diff --git a/dist/index.cjs b/dist/index.cjs index d680598..6af063a 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -1,2 +1,2 @@ -class TinybufError extends Error{}function $hashCode(t){let r=5381;for(let e=0;ethis.on(t,(()=>{})))),this}clear(){this.t.clear(),this.o.clear()}}const t=Math.floor,r=Math.ceil,$clamp=(t,r,e)=>t>e?e:te<0?r(e):t(e),$roundAwayFromZero=e=>e<0?t(e):r(e);function $touscal8(t){return $clamp(127+$roundTowardZero(254*t-127),0,254)}function $toscal8(t){return $clamp($roundTowardZero(127*t),-127,127)+127}function $fromuscal8(t){return $clamp(.01*($roundAwayFromZero(.3937007874015748*(t-127))+50),0,1)}function $fromscal8(t){return $clamp(.01*$roundAwayFromZero(.787401574803149*(t-127)),-1,1)}const e={UInt:"uint",UInt8:"u8",UInt16:"u16",UInt32:"u32",Int:"int",Int8:"i8",Int16:"i16",Int32:"i32",Float64:"f64",Float32:"f32",Float16:"f16",BFloat16:"b16",Scalar8:"sc",UScalar8:"usc",Bool:"bl",Bools:"bls",Buffer:"buf",String:"str",JSON:"jsn",RegExp:"re",Date:"dt"},i=Object.values(e);class MaybeType{constructor(t){this.type=t}}const mask=(t,r=1)=>t.reduce(((t,r)=>t<<1|r),r),unmask=(t,r)=>{const e=void 0===r?31-Math.clz32(t):Array.isArray(r)?r.length:r,i=Array.isArray(r)&&r.length===e?r:new Array(e);for(let r=0;rt.encode(r)}(),s=function(){const t=new TextDecoder("utf-8");return r=>t.decode(r)}();const o=function(){const t=new Float32Array(1),r=new Int32Array(t.buffer);return function(e){t[0]=e;let i=r[0],n=i>>16&32768,s=4096+(2147483647&i)|0;return s>=1199570944?(2147483647&i)<1199570944?31743|n:s<2139095040?31744|n:31744|n|(8388607&i)>>13:s>=947912704?n|s-939524096>>13:s<855638016?n:(s=(2147483647&i)>>23,n|(8388607&i|8388608)+(8388608>>>s-102)>>126-s)}}(),a=function(){const t=Math.pow(2,-24),r=new Float32Array(1056);for(let t=0;t<32;t++)r[t]=Math.pow(2,t-15);for(let t=0;t<1024;t++)r[t+32]=1+t/1024;return function(e){const i=32768&~e?1:-1,n=31744&e,s=1023&e;return 0===n?0===s?0*i:i*t:31744===n?0===s?i*(1/0):NaN:r[n>>10]*r[s+32]*i}}(),h=new Uint32Array(1),f=new Float32Array(h.buffer);const u=536870912,c=268435456,d=4294967296,$={h:(r,e)=>{"number"!=typeof r&&(r=Number(r)),r<0&&(r=0),r<128?e.u(r):r<16384?e.$(r+32768):r=u?(e.l(t(r/d)+3758096384),e.l(r>>>0)):e.u(!0===r?1:0)},p:t=>{const r=t.m();return 128&r?64&r?32&r?(t.B()-3758096384)*d+t.B():t.B()-3221225472:t.F()-32768:(t.v(),r)}},l={h:(t,r)=>r.u(t),p:t=>t.A()},w={h:(t,r)=>r.$(t),p:t=>t.F()},y={h:(t,r)=>r.l(t),p:t=>t.B()},p={h:(r,e)=>{"number"!=typeof r&&(r=Number(r)),r>=-64&&r<64?e.u(127&r):r>=-8192&&r<8192?e.$(32768+(16383&r)):r>=-268435456&&r=c?(e.l(3758096384+(536870911&t(r/d))),e.l(r>>>0)):e.u(!0===r?127:0)},p:t=>{let r,e=t.m();return 128&e?64&e?32&e?(r=t.B()-3758096384,r=268435456&r?3758096384|r:r,r*d+t.B()):(r=t.B()-3221225472,268435456&r?3758096384|r:r):(r=t.F()-32768,8192&r?4294950912|r:r):(t.v(),64&e?4294967168|e:e)}},b={h:(t,r)=>r.T(t),p:t=>t.U()},m={h:(t,r)=>r.I(t),p:t=>t.S()},B={h:(t,r)=>r.M(t),p:t=>t.j()},F={h:(t,r)=>r.$(function $tobf16(t){return f[0]=t,h[0]>>>16}(t)),p:t=>function $frombf16(t){return h[0]=t<<16,f[0]}(t.F())},v={h:(t,r)=>r.$(o(t)),p:t=>a(t.F())},A={h:(t,r)=>r.H(t),p:t=>t._()},T={h:(t,r)=>r.k(t),p:t=>t.O()},x={h:(t,r)=>r.u($touscal8(t)),p:t=>$fromuscal8(t.A())},E={h:(t,r)=>r.u($toscal8(t)),p:t=>$fromscal8(t.A())},g={h:(t,r)=>p.h(t.getTime(),r),p:t=>new Date(p.p(t))},U={h:(t,r)=>{$.h(t.byteLength,r),r.C(t)},p:t=>t.D($.p(t))},I={h:(t,r)=>U.h(n(t),r),p:t=>s(U.p(t))},S={h:(t,r)=>r.u(t?1:0),p:t=>0!==t.A()},M={h:(t,r)=>{t.length>28&&(t=t.slice(0,28)),$.h(mask(t),r)},p:(t,r)=>unmask($.p(t),r)},j={h:(t,r)=>I.h(JSON.stringify(t),r),p:t=>JSON.parse(I.p(t))},H={h:(t,r)=>{r.u(mask([t.global,t.ignoreCase,t.multiline])),I.h(t.source,r)},p:t=>{const[r,e,i]=unmask(t.A());return new RegExp(I.p(t),(r?"g":"")+(e?"i":"")+(i?"m":""))}},_={[e.UInt]:$.h,[e.UInt8]:l.h,[e.UInt16]:w.h,[e.UInt32]:y.h,[e.Int]:p.h,[e.Int8]:b.h,[e.Int16]:m.h,[e.Int32]:B.h,[e.Float64]:T.h,[e.Float32]:A.h,[e.Float16]:v.h,[e.BFloat16]:F.h,[e.Scalar8]:E.h,[e.UScalar8]:x.h,[e.Bool]:S.h,[e.Bools]:M.h,[e.Buffer]:U.h,[e.String]:I.h,[e.JSON]:j.h,[e.RegExp]:H.h,[e.Date]:g.h},k={[e.UInt]:$.p,[e.UInt8]:l.p,[e.UInt16]:w.p,[e.UInt32]:y.p,[e.Int]:p.p,[e.Int8]:b.p,[e.Int16]:m.p,[e.Int32]:B.p,[e.Float64]:T.p,[e.Float32]:A.p,[e.Float16]:v.p,[e.BFloat16]:F.p,[e.Scalar8]:E.p,[e.UScalar8]:x.p,[e.Bool]:S.p,[e.Bools]:M.p,[e.Buffer]:U.p,[e.String]:I.p,[e.JSON]:j.p,[e.RegExp]:H.p,[e.Date]:g.p};let O={safe:!1,useGlobalEncodingBuffer:!0,encodingBufferMaxSize:1500,encodingBufferInitialSize:256,encodingBufferIncrement:256};class BufferWriter{constructor(t){this.i=0,this.N=new DataView(new ArrayBuffer(t))}V(){return new Uint8Array(this.N.buffer,this.N.byteOffset,this.i)}R(){return new Uint8Array(this.N.buffer.slice(0,this.i))}T(t){this.N.setInt8(this.J(1),t)}I(t){this.N.setInt16(this.J(2),t,!0)}M(t){this.N.setInt32(this.J(4),t,!0)}u(t){this.N.setUint8(this.J(1),t)}$(t){this.N.setUint16(this.J(2),t,!1)}l(t){this.N.setUint32(this.J(4),t,!1)}H(t){this.N.setFloat32(this.J(4),t,!0)}k(t){this.N.setFloat64(this.J(8),t,!0)}C(t){const r=this.J(t.byteLength);let e=ArrayBuffer.isView(t)?t instanceof Uint8Array?t:new Uint8Array(t.buffer,t.byteOffset,t.byteLength):new Uint8Array(t);new Uint8Array(this.N.buffer,this.N.byteOffset+r,t.byteLength).set(e)}J(t){if(this.i+t>this.N.byteLength){const r=this.i+t-this.N.byteLength,e=Math.ceil(r/O.encodingBufferIncrement)*O.encodingBufferIncrement;this.W(this.N.byteLength+e)}const r=this.i;return this.i+=t,r}W(t){if(t>O.encodingBufferMaxSize)throw new TinybufError(`exceeded encodingBufferMaxSize: ${O.encodingBufferMaxSize}`);const r=new ArrayBuffer(t),e=new Uint8Array(this.N.buffer,this.N.byteOffset,this.N.byteLength);new Uint8Array(r).set(e),this.N=new DataView(r)}}class BufferReader{constructor(t,r){this.N=ArrayBuffer.isView(t)?new DataView(t.buffer,t.byteOffset,t.byteLength):new DataView(t),this.i=null!=r?r:0}m(){return this.N.getUint8(this.i)}v(){this.i++}A(){return this.N.getUint8(this.i++)}F(){const t=this.N.getUint16(this.i);return this.i+=2,t}B(){const t=this.N.getUint32(this.i);return this.i+=4,t}U(){return this.N.getInt8(this.i++)}S(){const t=this.N.getInt16(this.i,!0);return this.i+=2,t}j(){const t=this.N.getInt32(this.i,!0);return this.i+=4,t}_(){const t=this.N.getFloat32(this.i,!0);return this.i+=4,t}O(){const t=this.N.getFloat64(this.i,!0);return this.i+=8,t}D(t){if(this.N.byteOffset+this.i+t>this.N.byteLength)throw new RangeError("exceeded bytes");const r=new Uint8Array(this.N.buffer,this.N.byteOffset+this.i,t);return this.i+=t,r}}class BufferFormat{get encodingBuffer(){var t;return null===(t=this.P)||void 0===t?void 0:t.N}constructor(t,r){if(this.q=!1,"string"==typeof t&&i.includes(t))this.G=t;else{if(t instanceof MaybeType)throw new TypeError("Format cannot be optional");if(!(t instanceof Object))throw new TypeError(`Format must be object or Type: ${JSON.stringify(t)} ${typeof t} ${i[t]}`);if(this.G=void 0,this.K=new Map,this.L=Object.keys(t).map((r=>{const e=new Field(r,t[r]);return this.K.set(r,e),e})),void 0===r)this.header=$hashCode(this.f),this.X=this.header;else if(null===r)this.header=void 0,this.X=void 0;else{if(!function isValidHeader(t){return"number"==typeof t?Number.isInteger(t)&&t>=0&&t<=65535:"string"==typeof t&&2===(new TextEncoder).encode(t).byteLength}(r))throw new TypeError(`Header must be uint16, 2 byte string, or null. Received: ${r}`);this.header=r,this.X="number"==typeof r?r:$strToHashCode(r)}}}get f(){return void 0===this.Y&&(this.Y=void 0!==this.L?`{${this.L.map((t=>t.f)).join(",")}}`:`${this.G}`),this.Y}static Z(){return O.useGlobalEncodingBuffer?(BufferFormat.tt||(this.tt=new BufferWriter(O.encodingBufferInitialSize)),this.tt):new BufferWriter(O.encodingBufferInitialSize)}encode(t,r){return this.P||(this.P=BufferFormat.Z()),this.P.i=0,this.q&&(t=this.rt(t)),this.et(t,this.P),(null!=r?r:O.safe)?this.P.R():this.P.V()}decode(t,r){return this.it(new BufferReader(t,void 0===this.header?0:2),r)}setTransforms(t){if(this.q=!0,"function"==typeof t||Array.isArray(t)&&"function"==typeof t[0])this.nt=t;else for(const r of Object.keys(t)){const e=this.K.get(r);if(!e)throw new TypeError(`Failed to set transforms for field '${r}'`);e.st.setTransforms(t[r])}return this}setValidation(t){if(this.q=!0,"function"==typeof t)this.ot=t;else for(const r of Object.keys(t)){const e=this.K.get(r);if(!e)throw new TypeError(`Failed to set validation function for field '${r}'`);e.st.setValidation(t[r])}return this}et(t,r){if(void 0!==this.X&&r.$(this.X),void 0!==this.G){const e=this.ot||this.nt?this.rt(t):t;return _[this.G](e,r)}if("object"!=typeof t||!t)throw new TypeError("expected object type");for(const e of this.L){const i=t[e.ht];if(e.ft){if(null==i){S.h(!1,r);continue}S.h(!0,r)}else if(null==i)throw new Error(`missing required value: ${e.ht}`);e.ut?this.ct(i,r,e.st):e.st.et(i,r)}}rt(t){return this.ot&&this.dt(t),"function"==typeof this.nt?this.nt(t):Array.isArray(this.nt)&&"function"==typeof this.nt[0]?this.nt[0](t):t}$t(t){return Array.isArray(this.nt)&&"function"==typeof this.nt[1]&&(t=this.nt[1](t)),this.ot&&this.dt(t),t}dt(t){if(!this.ot)return;const r=this.ot(t);if(r instanceof Error)throw r;if(!1===r)throw new Error("failed validation")}it(t,r){return this.it=this.lt(),this.it(t,r)}wt(){const t=this.L.map((({ht:t},r)=>`v.${t}=this.${this.yt.name}(${r},s,v.${t})`)).join(";");return`let v=o??{};${t};return v;`}yt(t,r,e){const i=this.L[t];if(!i.ft||S.p(r))return i.ut?this.bt(i.st,r,e):i.st.it(r,e)}lt(){return void 0!==this.G?this.q?t=>this.$t(k[this.G](t)):k[this.G]:new Function("s","o",this.wt())}ct(t,r,e){if(!Array.isArray(t))throw new TypeError(`expected array, instead got: ${t}`);$.h(t.length,r);for(let i=0;inew BufferParser,exports.defineFormat=function defineFormat(t,r){return null!==t&&"object"==typeof t?new BufferFormat(t):new BufferFormat(r,t)},exports.f16round=function f16round(t){return a(o(t))},exports.mask=mask,exports.optional=function optional(t){return new MaybeType(t)},exports.peekHeader=peekHeader,exports.peekHeaderStr=peekHeaderStr,exports.scalround=function scalround(t){return $fromscal8($toscal8(t))},exports.setTinybufConfig=t=>{O=Object.assign(Object.assign({},O),t)},exports.unmask=unmask,exports.uscalround=function uscalround(t){return $fromuscal8($touscal8(t))}; +class TinybufError extends Error{}function $hashCode(t){let r=5381;for(let e=0;ethis.on(t,(()=>{})))),this}clear(){this.t.clear(),this.o.clear()}}const t=Math.floor,r=Math.ceil,$clamp=(t,r,e)=>t>e?e:te<0?r(e):t(e),$roundAwayFromZero=e=>e<0?t(e):r(e);function $touscal8(t){return $clamp(127+$roundTowardZero(254*t-127),0,254)}function $toscal8(t){return $clamp($roundTowardZero(127*t),-127,127)+127}function $fromuscal8(t){return $clamp(.01*($roundAwayFromZero(.3937007874015748*(t-127))+50),0,1)}function $fromscal8(t){return $clamp(.01*$roundAwayFromZero(.787401574803149*(t-127)),-1,1)}const e={UInt:"uint",UInt8:"u8",UInt16:"u16",UInt32:"u32",Int:"int",Int8:"i8",Int16:"i16",Int32:"i32",Float64:"f64",Float32:"f32",Float16:"f16",BFloat16:"b16",Scalar8:"sc",UScalar8:"usc",Bool:"bl",Bools:"bls",Buffer:"buf",String:"str",JSON:"jsn",RegExp:"re",Date:"dt"},i=Object.values(e);class MaybeType{constructor(t){this.type=t}}const mask=(t,r=1)=>t.reduce(((t,r)=>t<<1|r),r),unmask=(t,r)=>{const e=void 0===r?31-Math.clz32(t):Array.isArray(r)?r.length:r,i=Array.isArray(r)&&r.length===e?r:new Array(e);for(let r=0;rt.encode(r)}(),s=function(){const t=new TextDecoder("utf-8");return r=>t.decode(r)}();const o=function(){const t=new Float32Array(1),r=new Int32Array(t.buffer);return function(e){t[0]=e;let i=r[0],n=i>>16&32768,s=4096+(2147483647&i)|0;return s>=1199570944?(2147483647&i)<1199570944?31743|n:s<2139095040?31744|n:31744|n|(8388607&i)>>13:s>=947912704?n|s-939524096>>13:s<855638016?n:(s=(2147483647&i)>>23,n|(8388607&i|8388608)+(8388608>>>s-102)>>126-s)}}(),h=function(){const t=Math.pow(2,-24),r=new Float32Array(1056);for(let t=0;t<32;t++)r[t]=Math.pow(2,t-15);for(let t=0;t<1024;t++)r[t+32]=1+t/1024;return function(e){const i=32768&~e?1:-1,n=31744&e,s=1023&e;return 0===n?0===s?0*i:i*t:31744===n?0===s?i*(1/0):NaN:r[n>>10]*r[s+32]*i}}(),a=new Uint32Array(1),f=new Float32Array(a.buffer);const u=536870912,c=268435456,d=4294967296,$={h:(r,e)=>{"number"!=typeof r&&(r=Number(r)),r<0&&(r=0),r<128?e.u(r):r<16384?e.$(r+32768):r=u?(e.l(t(r/d)+3758096384),e.l(r>>>0)):e.u(!0===r?1:0)},p:t=>{const r=t.m();return 128&r?64&r?32&r?(t.B()-3758096384)*d+t.B():t.B()-3221225472:t.F()-32768:(t.A(),r)}},l={h:(t,r)=>r.u(t),p:t=>t.T()},w={h:(t,r)=>r.$(t),p:t=>t.F()},y={h:(t,r)=>r.l(t),p:t=>t.B()},p={h:(r,e)=>{"number"!=typeof r&&(r=Number(r)),r>=-64&&r<64?e.u(127&r):r>=-8192&&r<8192?e.$(32768+(16383&r)):r>=-268435456&&r=c?(e.l(3758096384+(536870911&t(r/d))),e.l(r>>>0)):e.u(!0===r?127:0)},p:t=>{let r,e=t.m();return 128&e?64&e?32&e?(r=t.B()-3758096384,r=268435456&r?3758096384|r:r,r*d+t.B()):(r=t.B()-3221225472,268435456&r?3758096384|r:r):(r=t.F()-32768,8192&r?4294950912|r:r):(t.A(),64&e?4294967168|e:e)}},b={h:(t,r)=>r.v(t),p:t=>t.U()},m={h:(t,r)=>r.I(t),p:t=>t.M()},B={h:(t,r)=>r.S(t),p:t=>t.j()},F={h:(t,r)=>r.$(function $tobf16(t){return f[0]=t,a[0]>>>16}(t)),p:t=>function $frombf16(t){return a[0]=t<<16,f[0]}(t.F())},A={h:(t,r)=>r.$(o(t)),p:t=>h(t.F())},T={h:(t,r)=>r.H(t),p:t=>t._()},v={h:(t,r)=>r.k(t),p:t=>t.O()},x={h:(t,r)=>r.u($touscal8(t)),p:t=>$fromuscal8(t.T())},E={h:(t,r)=>r.u($toscal8(t)),p:t=>$fromscal8(t.T())},g={h:(t,r)=>p.h(t.getTime(),r),p:t=>new Date(p.p(t))},U={h:(t,r)=>{$.h(t.byteLength,r),r.C(t)},p:t=>t.D($.p(t))},I={h:(t,r)=>U.h(n(t),r),p:t=>s(U.p(t))},M={h:(t,r)=>r.u(t?1:0),p:t=>0!==t.T()},S={h:(t,r)=>{t.length>28&&(t=t.slice(0,28)),$.h(mask(t),r)},p:(t,r)=>unmask($.p(t),r)},j={h:(t,r)=>I.h(JSON.stringify(t),r),p:t=>JSON.parse(I.p(t))},H={h:(t,r)=>{r.u(mask([t.global,t.ignoreCase,t.multiline])),I.h(t.source,r)},p:t=>{const[r,e,i]=unmask(t.T());return new RegExp(I.p(t),(r?"g":"")+(e?"i":"")+(i?"m":""))}},_={[e.UInt]:$.h,[e.UInt8]:l.h,[e.UInt16]:w.h,[e.UInt32]:y.h,[e.Int]:p.h,[e.Int8]:b.h,[e.Int16]:m.h,[e.Int32]:B.h,[e.Float64]:v.h,[e.Float32]:T.h,[e.Float16]:A.h,[e.BFloat16]:F.h,[e.Scalar8]:E.h,[e.UScalar8]:x.h,[e.Bool]:M.h,[e.Bools]:S.h,[e.Buffer]:U.h,[e.String]:I.h,[e.JSON]:j.h,[e.RegExp]:H.h,[e.Date]:g.h},k={[e.UInt]:$.p,[e.UInt8]:l.p,[e.UInt16]:w.p,[e.UInt32]:y.p,[e.Int]:p.p,[e.Int8]:b.p,[e.Int16]:m.p,[e.Int32]:B.p,[e.Float64]:v.p,[e.Float32]:T.p,[e.Float16]:A.p,[e.BFloat16]:F.p,[e.Scalar8]:E.p,[e.UScalar8]:x.p,[e.Bool]:M.p,[e.Bools]:S.p,[e.Buffer]:U.p,[e.String]:I.p,[e.JSON]:j.p,[e.RegExp]:H.p,[e.Date]:g.p};let O={safe:!1,useGlobalEncodingBuffer:!0,encodingBufferMaxSize:1500,encodingBufferInitialSize:256,encodingBufferIncrement:256};class BufferWriter{constructor(t){this.V=0,this.N=0,this.R=new DataView(new ArrayBuffer(t))}W(){return new Uint8Array(this.R.buffer,this.R.byteOffset,this.V)}J(){return new Uint8Array(this.R.buffer.slice(0,this.V))}v(t){this.P(1).setInt8(this.N,t)}I(t){this.P(2).setInt16(this.N,t,!0)}S(t){this.P(4).setInt32(this.N,t,!0)}u(t){this.P(1).setUint8(this.N,t)}$(t){this.P(2).setUint16(this.N,t,!1)}l(t){this.P(4).setUint32(this.N,t,!1)}H(t){this.P(4).setFloat32(this.N,t,!0)}k(t){this.P(8).setFloat64(this.N,t,!0)}C(t){this.P(t.byteLength);let r=ArrayBuffer.isView(t)?t instanceof Uint8Array?t:new Uint8Array(t.buffer,t.byteOffset,t.byteLength):new Uint8Array(t);new Uint8Array(this.R.buffer,this.R.byteOffset+this.N,t.byteLength).set(r)}P(t){if(this.V+t>this.R.byteLength){const r=this.V+t-this.R.byteLength,e=Math.ceil(r/O.encodingBufferIncrement)*O.encodingBufferIncrement;this.q(this.R.byteLength+e)}return this.N=this.V,this.V+=t,this.R}q(t){if(t>O.encodingBufferMaxSize)throw new TinybufError(`exceeded encodingBufferMaxSize: ${O.encodingBufferMaxSize}`);const r=new ArrayBuffer(t),e=new Uint8Array(this.R.buffer,this.R.byteOffset,this.R.byteLength);new Uint8Array(r).set(e),this.R=new DataView(r)}}class BufferReader{constructor(t,r){this.R=ArrayBuffer.isView(t)?new DataView(t.buffer,t.byteOffset,t.byteLength):new DataView(t),this.i=null!=r?r:0}m(){return this.R.getUint8(this.i)}A(){this.i++}T(){return this.R.getUint8(this.i++)}F(){const t=this.R.getUint16(this.i);return this.i+=2,t}B(){const t=this.R.getUint32(this.i);return this.i+=4,t}U(){return this.R.getInt8(this.i++)}M(){const t=this.R.getInt16(this.i,!0);return this.i+=2,t}j(){const t=this.R.getInt32(this.i,!0);return this.i+=4,t}_(){const t=this.R.getFloat32(this.i,!0);return this.i+=4,t}O(){const t=this.R.getFloat64(this.i,!0);return this.i+=8,t}D(t){if(this.R.byteOffset+this.i+t>this.R.byteLength)throw new RangeError("exceeded bytes");const r=new Uint8Array(this.R.buffer,this.R.byteOffset+this.i,t);return this.i+=t,r}}class BufferFormat{get encodingBuffer(){var t;return null===(t=this.G)||void 0===t?void 0:t.R}constructor(t,r){if(this.K=!1,"string"==typeof t&&i.includes(t))this.L=t;else{if(t instanceof MaybeType)throw new TypeError("Format cannot be optional");if(!(t instanceof Object))throw new TypeError("Format must be object or Type");if(this.L=void 0,this.X=new Map,this.Y=Object.keys(t).map((r=>{const e=new Field(r,t[r]);return this.X.set(r,e),e})),void 0===r)this.header=$hashCode(this.f),this.Z=this.header;else if(null===r)this.header=void 0,this.Z=void 0;else{if(!function isValidHeader(t){return"number"==typeof t?Number.isInteger(t)&&t>=0&&t<=65535:"string"==typeof t&&2===(new TextEncoder).encode(t).byteLength}(r))throw new TypeError("Header must be 2-byte string, uint16, or null.");this.header=r,this.Z="number"==typeof r?r:$strToHashCode(r)}}}get f(){return void 0===this.tt&&(this.tt=void 0!==this.Y?`{${this.Y.map((t=>t.f)).join(",")}}`:`${this.L}`),this.tt}static rt(){return O.useGlobalEncodingBuffer?(BufferFormat.et||(this.et=new BufferWriter(O.encodingBufferInitialSize)),this.et):new BufferWriter(O.encodingBufferInitialSize)}encode(t,r){return this.G||(this.G=BufferFormat.rt()),this.G.V=0,this.K&&(t=this.it(t)),this.nt(t,this.G),(null!=r?r:O.safe)?this.G.J():this.G.W()}decode(t,r){return this.st(new BufferReader(t,void 0===this.header?0:2),r)}setTransforms(t){if(this.K=!0,"function"==typeof t||Array.isArray(t)&&"function"==typeof t[0])this.ot=t;else for(const r of Object.keys(t)){const e=this.X.get(r);if(!e)throw new TypeError(`Failed to set transforms for field '${r}'`);e.ht.setTransforms(t[r])}return this}setValidation(t){if(this.K=!0,"function"==typeof t)this.ft=t;else for(const r of Object.keys(t)){const e=this.X.get(r);if(!e)throw new TypeError(`Failed to set validation function for field '${r}'`);e.ht.setValidation(t[r])}return this}nt(t,r){if(void 0!==this.Z&&r.$(this.Z),void 0!==this.L){const e=this.ft||this.ot?this.it(t):t;return _[this.L](e,r)}if("object"!=typeof t||!t)throw new TypeError("expected object type");for(const e of this.Y){const i=t[e.ut];if(e.ct){if(null==i){M.h(!1,r);continue}M.h(!0,r)}else if(null==i)throw new Error(`missing required value: ${e.ut}`);e.dt?this.$t(i,r,e.ht):e.ht.nt(i,r)}}it(t){return this.ft&&this.lt(t),"function"==typeof this.ot?this.ot(t):Array.isArray(this.ot)&&"function"==typeof this.ot[0]?this.ot[0](t):t}wt(t){return Array.isArray(this.ot)&&"function"==typeof this.ot[1]&&(t=this.ot[1](t)),this.ft&&this.lt(t),t}lt(t){if(!this.ft)return;const r=this.ft(t);if(r instanceof Error)throw r;if(!1===r)throw new Error("failed validation")}st(t,r){return this.st=this.yt(),this.st(t,r)}bt(){const t=this.Y.map((({ut:t},r)=>`v.${t}=this.${this.Bt.name}(${r},s,v.${t})`)).join(";");return`let v=o??{};${t};return v;`}Bt(t,r,e){const i=this.Y[t];if(!i.ct||M.p(r))return i.dt?this.Ft(i.ht,r,e):i.ht.st(r,e)}yt(){return void 0!==this.L?this.K?t=>this.wt(k[this.L](t)):k[this.L]:new Function("s","o",this.bt())}$t(t,r,e){if(!Array.isArray(t))throw new TypeError(`expected array, instead got: ${t}`);$.h(t.length,r);for(let i=0;inew BufferParser,exports.defineFormat=function defineFormat(t,r){return null!==t&&"object"==typeof t?new BufferFormat(t):new BufferFormat(r,t)},exports.f16round=function f16round(t){return h(o(t))},exports.mask=mask,exports.optional=function optional(t){return new MaybeType(t)},exports.peekHeader=peekHeader,exports.peekHeaderStr=peekHeaderStr,exports.scalround=function scalround(t){return $fromscal8($toscal8(t))},exports.setTinybufConfig=t=>{O=Object.assign(Object.assign({},O),t)},exports.unmask=unmask,exports.uscalround=function uscalround(t){return $fromuscal8($touscal8(t))}; //# sourceMappingURL=index.cjs.map diff --git a/dist/index.cjs.map b/dist/index.cjs.map index f6be9e4..ed713f1 100644 --- a/dist/index.cjs.map +++ b/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.cjs","sources":["../src/core/lib/errors.ts","../src/core/lib/hashCode.ts","../src/core/lib/peek.ts","../src/core/BufferParser.ts","../src/core/lib/math.ts","../src/core/lib/scalar.ts","../src/core/Type.ts","../src/core/lib/bitmask.ts","../src/core/lib/utf8.ts","../src/core/lib/float16.ts","../src/core/lib/bfloat16.ts","../src/core/lib/coders.ts","../src/core/config.ts","../src/core/lib/BufferWriter.ts","../src/core/lib/BufferReader.ts","../src/core/BufferFormat.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unified-signatures */\n\nexport class TinybufError extends Error {}\n","/**\n * DJB2 hash algorithm (modified for 16-bit uints).\n *\n * DJB2 is a simple and widely used non-cryptographic\n * hash function created by Daniel J. Bernstein.\n *\n * @returns 16-bit unsigned integer\n */\nexport function $hashCode(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash * 33) ^ str.charCodeAt(i);\n }\n return hash & 0xFFFF; // Ensure the result is a Uint16\n}\n\n/**\n * Returns an unsigned 16-bit integer hashcode for some string.\n * Prefers 2 character string.\n *\n * @returns A UInt16 between 0 and 65535 (inclusive).\n */\nexport function $strToHashCode(str: string): number {\n if (str.length !== 2) return $hashCode(str);\n return str.charCodeAt(0) * 256 + str.charCodeAt(1);\n}\n\n/**\n * Convert a UInt16 hashcode to a 2-byte string.\n */\nexport function $hashCodeToStr(hashCode: number): string {\n return String.fromCharCode(Math.floor(hashCode / 256)) + String.fromCharCode(hashCode % 256);\n}\n","import { $hashCodeToStr } from \"./hashCode\";\n\n\n/**\n * Read the header bytes of a buffer as a number.\n *\n * @throws {RangeError} if buffer size < 2\n */\nexport function peekHeader(b: ArrayBuffer | ArrayBufferView): number {\n return (ArrayBuffer.isView(b) ? new DataView(b.buffer, b.byteOffset, 2) : new DataView(b, 0, 2)).getUint16(0, false);\n}\n\n/**\n * Read the header bytes of a buffer as a string.\n *\n * @throws {RangeError} if buffer length < 2\n */\nexport function peekHeaderStr(b: ArrayBuffer | ArrayBufferView): string {\n return $hashCodeToStr(peekHeader(b));\n}\n","import { BufferFormat } from \"./BufferFormat\";\nimport { EncoderDefinition, InferredDecodedType } from \"./Type\";\nimport { TinybufError } from \"./lib/errors\";\nimport { $hashCodeToStr, $strToHashCode } from \"./lib/hashCode\";\nimport { peekHeader } from \"./lib/peek\";\n\ntype AnyFormat = BufferFormat;\ntype Uint16FormatHeader = number;\n\n/**\n * Small utility for registering and processing format handlers.\n *\n * @example\n * const myHandler = bufferParser()\n * .on(FormatA, aData => {})\n * .on(FormatB, bData => {});\n *\n * myHandler.processBuffer(bytes);\n */\nexport const bufferParser = (): BufferParser => new BufferParser();\n\nexport class BufferParser {\n /** @internal */\n private _$formats = new Map any, decodeInPlace: boolean]>();\n private _$data = new Map(); // used when decoding in-place\n\n /**\n * Decode an array buffer and trigger the relevant data handler.\n *\n * When passed an ArrayBufferView, accesses the underlying 'buffer' instance directly.\n *\n * @throws {TinybufError} if fails to decode, or no handler is registered\n */\n public processBuffer(b: ArrayBuffer | ArrayBufferView): void {\n let f: any, data: any, cb: (data: any) => any, r: boolean;\n\n try {\n const header = peekHeader(b);\n\n if (!this._$formats.has(header)) {\n throw new TinybufError(`Unknown format: ${header} '${$hashCodeToStr(header)}')`);\n }\n\n [f, cb, r] = this._$formats.get(header);\n if (r) data = this._$data.get(header) ?? {};\n data = f.decode(b, data);\n if (r) this._$data.set(header, data);\n }\n catch (e) {\n const err = new TinybufError(`Failed to decode: ${e}`);\n err.stack = e.stack;\n\n throw err;\n }\n\n cb(data);\n }\n\n /**\n * Register a format handler.\n */\n public on>(\n format: BufferFormat,\n callback: (data: DecodedType) => any,\n {\n decodeInPlace = false,\n } = {},\n ): this {\n if (format.header == null) {\n throw new TinybufError(\"Format requires header\");\n }\n\n const header = typeof format.header === \"string\" ? $strToHashCode(format.header) : format.header;\n\n if (this._$formats.has(header) && this._$formats.get(header)?.[0] !== format) {\n throw new TinybufError(`Format header collision: ${format.header}`);\n }\n\n this._$formats.set(header, [format, callback, decodeInPlace]);\n\n return this;\n }\n\n /** Register a format (or formats) that are recognized. */\n public ignore(...format: AnyFormat[]): this {\n format.forEach(f => this.on(f, () => {}));\n return this;\n }\n\n /** Clears all registered formats and handlers. */\n public clear(): void {\n this._$formats.clear();\n this._$data.clear();\n }\n}\n","export const $floor = Math.floor,\n $ceil = Math.ceil;\n\n/** Clamp a number to a range. */\nexport const $clamp = (value: number, min: number, max: number): number =>\n value > max ? max : value < min ? min : value;\n\n/** Round toward zero */\nexport const $roundTowardZero = (x: number): number => x < 0 ? $ceil(x) : $floor(x);\n\n/** Round away zero */\nexport const $roundAwayFromZero = (x: number): number =>\n x < 0 ? $floor(x) : $ceil(x);\n","import { $clamp, $roundTowardZero, $roundAwayFromZero } from \"./math\";\n\n/**\n * Quantize a number to an 8-bit scalar between 0.0 and 1.0.\n *\n * @returns A number (double) in its closest signed scalar representation.\n */\nexport function uscalround(x: number): number {\n return $fromuscal8($touscal8(x));\n}\n\n/**\n * Quantize a number to an 8-bit signed scalar between -1.0 and 1.0.\n *\n * @returns A number (double) in its closest signed scalar representation.\n */\nexport function scalround(x: number): number {\n return $fromscal8($toscal8(x));\n}\n\n/** @returns A UInt8 bitmask representation. */\nexport function $touscal8(x: number): number {\n return $clamp(127 + $roundTowardZero(x * 254 - 127), 0, 254);\n}\n\n/** @returns A UInt8 bitmask representation. */\nexport function $toscal8(x: number): number {\n return $clamp($roundTowardZero(x * 127), -127, 127) + 127;\n}\n\n/** @returns An unsigned scalar between 0.0 and 1.0. */\nexport function $fromuscal8(x: number): number {\n // Make symmetric: (0.5 + round((uint8 - 127) / 254 * 100)) / 100\n return $clamp(($roundAwayFromZero((x - 127) * 0.3937007874015748) + 50) * 0.01, 0, 1);\n}\n\n/** @returns A signed scalar between -1.0 and 1.0. */\nexport function $fromscal8(x: number): number {\n // Make symmetric: round((uint8 - 127) / 127 * 100) / 100\n return $clamp($roundAwayFromZero((x - 127) * 0.787401574803149) * 0.01, -1, 1);\n}\n","/**\n * Field types for defining encoding formats.\n *\n * @see [Types](https://github.com/reececomo/tinybuf/blob/main/docs/types.md)\n */\nexport const Type = {\n /**\n * Unsigned integer (1 - 8 bytes).\n * - 0 → 127 = 1 byte\n * - 128 → 16,384 = 2 bytes\n * - 16,385 → 536,870,911 = 4 bytes\n * - 536,870,912 → `Number.MAX_SAFE_INTEGER` = 8 bytes\n */\n UInt: \"uint\",\n\n /** Unsigned 8-bit integer (between 0 and 255, 1 byte). */\n UInt8: \"u8\",\n\n /** Unsigned 16-bit integer (between 0 and 65,535, 2 bytes). */\n UInt16: \"u16\",\n\n /** Unsigned 32-bit integer (between 0 and 4,294,967,295, 4 bytes). */\n UInt32: \"u32\",\n\n /**\n * Signed integer (1 - 8 bytes).\n * - 0 → ±64 = 1 byte\n * - ±65 → ±8,192 = 2 bytes\n * - ±8,193 → ±268,435,456 = 4 bytes\n * - ±268,435,457 → ±`Number.MAX_SAFE_INTEGER` = 8 bytes\n */\n Int: \"int\",\n\n /** Signed 1 byte integer (between -127 and 127). */\n Int8: \"i8\",\n\n /** Signed 2 byte integer (between -32,767 and 32,767). */\n Int16: \"i16\",\n\n /** Signed 4 byte integer (between -2,147,483,647 and 2,147,483,647). */\n Int32: \"i32\",\n\n /** Default JavaScript `number` type. Floating-point number (64-bit, double precision, 8 bytes). */\n Float64: \"f64\",\n\n /** Floating-point number (32-bit, single precision, 4 bytes). */\n Float32: \"f32\",\n\n /**\n * Floating-point number (16-bit in FP16 format, half precision, 2 bytes).\n *\n * **Warning:** Low precision; maximum range: ±65,504.\n */\n Float16: \"f16\",\n\n /**\n * Floating-point number (16-bit in BF16 format, half precision, 2 bytes).\n *\n * **Warning:** Low precision.\n */\n BFloat16: \"b16\",\n\n /** A signed 2-decimal scalar between -1.00 and 1.00 (1 byte). */\n Scalar8: \"sc\",\n\n /** An unsigned 2-decimal scalar between 0.00 and 1.00 (1 byte). */\n UScalar8: \"usc\",\n\n /**\n * Boolean value (1 byte).\n * @see {Bools} for packing multiple booleans into a single byte.\n */\n Bool: \"bl\",\n\n /** Any array of booleans (1 bit overhead, encoded as UInt). */\n Bools: \"bls\",\n\n /** Any ArrayBuffer or ArrayBufferView (e.g. Uint8Array) value (encoded as 1 x UInt for byte length + buffer bytes). */\n Buffer: \"buf\",\n\n /** A UTF-8 string (encoded as 1 x UInt for UTF-8 byte length + UTF-8 bytes). */\n String: \"str\",\n\n /** Any JSON data (encodes as UTF-8). */\n JSON: \"jsn\",\n\n /** JavaScript RegExp object. */\n RegExp: \"re\",\n\n /**\n * JavaScript Date object.\n *\n * Encoded as an 8 byte (64-bit) integer UTC timestamp from as the number\n * of milliseconds since the Unix Epoch (January 1, 1970, 00:00:00 UTC).\n *\n * @see {Date}\n */\n Date: \"dt\",\n} as const;\n\nexport type TypeLiteral = typeof Type[keyof typeof Type];\nexport const ValidTypes = Object.values(Type);\n\n/**\n * Mappings for the value types.\n */\nexport type ValueTypes = {\n [Type.Int]: number;\n [Type.Int8]: number;\n [Type.Int16]: number;\n [Type.Int32]: number;\n [Type.UInt]: number;\n [Type.UInt8]: number;\n [Type.UInt16]: number;\n [Type.UInt32]: number;\n [Type.Float64]: number;\n [Type.Float32]: number;\n [Type.Float16]: number;\n [Type.BFloat16]: number;\n [Type.Scalar8]: number;\n [Type.UScalar8]: number;\n [Type.Bool]: boolean;\n [Type.Bools]: boolean[];\n [Type.Buffer]: Uint8Array | ArrayBuffer | ArrayBufferView;\n [Type.String]: string;\n [Type.JSON]: any;\n [Type.RegExp]: RegExp;\n [Type.Date]: Date;\n};\n\n/** @throws any error too */\nexport type ValidationFn = (x: T) => undefined | boolean | Error;\nexport type TransformFn = (x: T) => T;\nexport type Transforms = TransformFn | [preEncode: TransformFn] | [preEncode: TransformFn | undefined, postDecode: TransformFn | undefined];\n\n/**\n * A wrapper around any Type definition that declares it as optional.\n */\nexport class MaybeType {\n public constructor(public type: T) {}\n}\n\n/**\n * Wrap any definition as optional.\n */\nexport function optional(t: T): MaybeType {\n return new MaybeType(t);\n}\n\n/**\n * A definition for an object binary encoder.\n */\nexport type EncoderDefinition = {\n [key: string]: FieldDefinition | MaybeType;\n};\n\n/**\n * Definition for an object-field binary encoder.\n */\nexport type FieldDefinition = keyof ValueTypes | [keyof ValueTypes] | EncoderDefinition | [EncoderDefinition] | MaybeType;\n\n/**\n * The resulting type of the decoded data, based on the encoder definition.\n */\nexport type InferredDecodedType = {\n [EKey in keyof EncoderType as EncoderType[EKey] extends MaybeType ? never : EKey]: EncoderType[EKey] extends keyof ValueTypes\n ? ValueTypes[EncoderType[EKey]]\n : EncoderType[EKey] extends [keyof ValueTypes]\n ? Array\n : EncoderType[EKey] extends EncoderDefinition\n ? InferredDecodedType\n : EncoderType[EKey] extends [EncoderDefinition]\n ? Array>\n : never;\n} & {\n [EKey in keyof EncoderType as EncoderType[EKey] extends MaybeType ? EKey : never]?: EncoderType[EKey] extends MaybeType\n ? ValueTypes[OptionalValue] | undefined\n : EncoderType[EKey] extends MaybeType\n ? Array | undefined\n : EncoderType[EKey] extends MaybeType\n ? InferredDecodedType | undefined\n : never;\n};\n\nexport type InferredTransformConfig = {\n [EKey in keyof EncoderType]?: EncoderType[EKey] extends keyof ValueTypes\n ? Transforms\n : EncoderType[EKey] extends [keyof ValueTypes]\n ? Transforms\n : EncoderType[EKey] extends EncoderDefinition\n ? InferredTransformConfig\n : EncoderType[EKey] extends [EncoderDefinition]\n ? InferredTransformConfig\n : EncoderType[EKey] extends MaybeType\n ? Transforms\n : EncoderType[EKey] extends MaybeType\n ? Transforms\n : EncoderType[EKey] extends MaybeType\n ? InferredTransformConfig | undefined\n : never;\n};\n\nexport type InferredValidationConfig = {\n [EKey in keyof EncoderType]?: EncoderType[EKey] extends keyof ValueTypes\n ? ValidationFn\n : EncoderType[EKey] extends [keyof ValueTypes]\n ? ValidationFn\n : EncoderType[EKey] extends EncoderDefinition\n ? InferredValidationConfig\n : EncoderType[EKey] extends [EncoderDefinition]\n ? InferredValidationConfig\n : EncoderType[EKey] extends MaybeType\n ? ValidationFn\n : EncoderType[EKey] extends MaybeType\n ? ValidationFn\n : EncoderType[EKey] extends MaybeType\n ? InferredValidationConfig | undefined\n : never;\n};\n","/**\n * Mask booleans to a uint32.\n *\n * @param x - A boolean array.\n * @param padBit - A bit to pad the mask (for variable length data).\n */\nexport const mask = (x: boolean[], padBit: 0 | 1 = 0b1): number => {\n return x.reduce((n, b: any) => (n << 1) | b, padBit);\n};\n\n/**\n * Unmask booleans from a uint32.\n *\n * @param x - A uint32 number.\n * @param l - number of booleans to expect (default: infer lenth from x where x is encoded with a pad bit)\n * or pass an existing boolean array to decode in-place.\n */\nexport const unmask = (x: number, l?: number | boolean[]): boolean[] => {\n const len = l === undefined ? 31 - Math.clz32(x) : Array.isArray(l) ? l.length : l;\n const val = Array.isArray(l) && l.length === len ? l : new Array(len);\n for (let i = 0; i < len; i++) val[i] = !!(x & (1 << (len - 1 - i)));\n return val;\n};\n","export const $utf8encode = (function () {\n const encoder = new TextEncoder();\n return (x?: string): Uint8Array => encoder.encode(x);\n})();\n\nexport const $utf8decode = (function () {\n const decoder = new TextDecoder(\"utf-8\");\n return (y: Uint8Array): string => decoder.decode(y);\n})();\n","/**\n * Returns the nearest half precision float representation of a number.\n * @param x A numeric expression.\n */\nexport function f16round(x: number): number {\n return $fromf16($tof16(x));\n}\n\n/**\n * Returns the nearest half precision float representation of a number as a 16-bit bitmask.\n */\nexport const $tof16 = (function() {\n const x = new Float32Array(1);\n const y = new Int32Array(x.buffer);\n\n return function (f: number) {\n x[0] = f;\n let i = y[0]; // 32-bit int\n let s = (i >> 16) & 0X8000; // sign\n let z = (i & 0X7FFFFFFF) + 0X1000 | 0;\n\n if (z >= 0X47800000) {\n if ((i & 0X7FFFFFFF) < 0X47800000) return s | 0X7BFF;\n if (z < 0X7F800000) return s | 0X7C00;\n return s | 0X7C00 | (i & 0X007FFFFF) >> 13;\n }\n if (z >= 0X38800000) return s | z - 0X38000000 >> 13;\n else if (z < 0X33000000) return s;\n z = (i & 0X7FFFFFFF) >> 23;\n return s | ((i & 0X7FFFFF | 0X800000)\n + (0X800000 >>> z - 102)\n >> 126 - z);\n };\n}());\n\n/**\n * Returns the nearest half precision float value for a 16-bit bitmask.\n */\nexport const $fromf16 = (function() {\n const z = Math.pow(2, -24); // subnormal constant\n const d = new Float32Array(32 + 1024);\n for (let e = 0; e < 32; e++) d[e] = Math.pow(2, e - 15); // biased exponents\n for (let m = 0; m < 1024; m++) d[m + 0x20] = 1 + m / 1024; // normalized offset mantissas\n\n return function (b: number): number {\n const s = (b & 32768) === 32768 ? -1 : 1; // sign: 1 bit\n const e = b & 31744; // exponent: 5 bits\n const m = b & 1023; // mantissa: 10 bits\n\n if (e === 0) return m === 0 ? s * 0 : s * z;\n if (e === 31744) return m === 0 ? s * Infinity : NaN;\n return d[e >> 10] * d[m + 0x20] * s;\n };\n}());\n","const i = new Uint32Array(1);\nconst f = new Float32Array(i.buffer);\n\n/**\n * Returns the nearest bfloat16 representation of a number.\n * @param x A numeric expression.\n */\nexport function bf16round(x: number): number {\n f[0] = x;\n i[0] = i[0] & 0xFFFF0000;\n return f[0];\n}\n\n/** Returns a 16-bit bfloat16 bitmask for a given float. */\nexport function $tobf16(x: number): number {\n f[0] = x;\n return i[0] >>> 16;\n}\n\n/** Returns the nearest value from a 16-bit bfloat16 bitmask. */\nexport function $frombf16(x: number): number {\n i[0] = x << 16;\n return f[0];\n}\n","import { BufferWriter } from \"./BufferWriter\";\nimport { BufferReader } from \"./BufferReader\";\nimport {\n $fromuscal8,\n $fromscal8,\n $touscal8,\n $toscal8\n} from \"./scalar\";\nimport { TypeLiteral, Type } from \"../Type\";\nimport { mask, unmask } from \"./bitmask\";\nimport { $utf8decode, $utf8encode } from \"./utf8\";\nimport { $floor } from \"./math\";\nimport { $fromf16, $tof16 } from \"./float16\";\nimport { $frombf16, $tobf16 } from \"./bfloat16\";\n\n// Pre-calculated constants\nconst MAX_VARUINT8 = 128,\n MAX_VARUINT16 = 16_384,\n MAX_VARUINT32 = 536_870_912,\n MAX_VARINT8 = 64,\n MAX_VARINT16 = 8_192,\n MAX_VARINT32 = 268_435_456,\n POW_32 = 0x100000000;\n\ntype WriterFn = (value: W, writer: BufferWriter) => void;\ntype ReaderFn = (reader: BufferReader, overwrite?: Partial) => R;\n\nexport interface BinaryTypeCoder {\n $write: WriterFn;\n $read: ReaderFn;\n}\n\n/**\n * Format (big-endian):\n * 7b 0xxxxxxx\n * 14b 10xxxxxx xxxxxxxx\n * 29b 110xxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n * 61b 111xxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n */\nexport const uintCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n if (typeof value !== \"number\") value = Number(value);\n if (value < 0) value = 0;\n if (value < MAX_VARUINT8) writer.$writeUint8(value);\n else if (value < MAX_VARUINT16) writer.$writeUint16(value + 0x8000);\n else if (value < MAX_VARUINT32) writer.$writeUint32(value + 0xc0000000);\n else if (value >= MAX_VARUINT32) {\n writer.$writeUint32($floor(value / POW_32) + 0xe0000000);\n writer.$writeUint32(value >>> 0);\n }\n else {\n // coercion case\n writer.$writeUint8(value as any === true ? 1 : 0);\n }\n },\n $read: (reader) => {\n const firstByte = reader.$peek();\n\n if (!(firstByte & 0x80)) {\n reader.$skip();\n return firstByte;\n }\n else if (!(firstByte & 0x40)) {\n return reader.$readUint16() - 0x8000;\n }\n else if (!(firstByte & 0x20)) {\n return reader.$readUint32() - 0xc0000000;\n }\n\n return (reader.$readUint32() - 0xe0000000) * POW_32\n + reader.$readUint32();\n }\n};\n\nexport const uint8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8(value),\n $read: (reader) => reader.$readUint8(),\n};\n\nexport const uint16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint16(value),\n $read: (reader) => reader.$readUint16(),\n};\n\nexport const uint32Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint32(value),\n $read: (reader) => reader.$readUint32(),\n};\n\n/**\n * Format (big-endian):\n * 7b 0xxxxxxx\n * 14b 10xxxxxx xxxxxxxx\n * 29b 110xxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n * 61b 111xxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n */\nexport const intCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n if (typeof value !== \"number\") value = Number(value);\n if (value >= -MAX_VARINT8 && value < MAX_VARINT8) writer.$writeUint8(value & 0x7f);\n else if (value >= -MAX_VARINT16 && value < MAX_VARINT16) writer.$writeUint16((value & 0x3fff) + 0x8000);\n else if (value >= -MAX_VARINT32 && value < MAX_VARINT32) writer.$writeUint32((value & 0x1fffffff) + 0xc0000000);\n else if (value < -MAX_VARINT32 || value >= MAX_VARINT32) {\n // Split in two 32b uints\n writer.$writeUint32(($floor(value / POW_32) & 0x1fffffff) + 0xe0000000);\n writer.$writeUint32(value >>> 0);\n }\n else {\n // coercion case\n writer.$writeUint8(value as any === true ? 0x7f : 0);\n }\n },\n $read: (reader) => {\n let firstByte = reader.$peek(), i: number;\n\n if (!(firstByte & 0x80)) {\n reader.$skip();\n return (firstByte & 0x40) ? (firstByte | 0xffffff80) : firstByte;\n }\n else if (!(firstByte & 0x40)) {\n i = reader.$readUint16() - 0x8000;\n return (i & 0x2000) ? (i | 0xffffc000) : i;\n }\n else if (!(firstByte & 0x20)) {\n i = reader.$readUint32() - 0xc0000000;\n return (i & 0x10000000) ? (i | 0xe0000000) : i;\n }\n else {\n i = reader.$readUint32() - 0xe0000000;\n i = (i & 0x10000000) ? (i | 0xe0000000) : i;\n return i * POW_32 + reader.$readUint32();\n }\n }\n};\n\nexport const int8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeInt8(value),\n $read: (reader) => reader.$readInt8(),\n};\n\nexport const int16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeInt16(value),\n $read: (reader) => reader.$readInt16(),\n};\n\nexport const int32Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeInt32(value),\n $read: (reader) => reader.$readInt32(),\n};\n\nexport const bfloat16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint16($tobf16(value)),\n $read: (reader) => $frombf16(reader.$readUint16()),\n};\n\nexport const float16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint16($tof16(value)),\n $read: (reader) => $fromf16(reader.$readUint16()),\n};\n\nexport const float32Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeFloat32(value),\n $read: (reader) => reader.$readFloat32(),\n};\n\nexport const float64Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeFloat64(value),\n $read: (reader) => reader.$readFloat64(),\n};\n\nexport const uscalar8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8($touscal8(value)),\n $read: (reader) => $fromuscal8(reader.$readUint8()),\n};\n\nexport const scalar8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8($toscal8(value)),\n $read: (reader) => $fromscal8(reader.$readUint8()),\n};\n\nexport const dateCoder: BinaryTypeCoder = {\n $write: (value, writer) => intCoder.$write(value.getTime(), writer),\n $read: (reader) => new Date(intCoder.$read(reader)),\n};\n\nexport const bufferCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n uintCoder.$write(value.byteLength, writer); // prefix length\n writer.$writeBytes(value);\n },\n $read: (reader) => reader.$readBytes(uintCoder.$read(reader)),\n};\n\nexport const stringCoder: BinaryTypeCoder = {\n $write: (value, writer) => bufferCoder.$write($utf8encode(value), writer),\n $read: (reader) => $utf8decode(bufferCoder.$read(reader)),\n};\n\nexport const boolCoder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8(value ? 1 : 0),\n $read: (reader) => reader.$readUint8() !== 0,\n};\n\nexport const boolsCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n if (value.length > 28) value = value.slice(0, 28); // drop additional\n uintCoder.$write(mask(value), writer);\n },\n $read: (reader, p) => unmask(uintCoder.$read(reader), p),\n};\n\nexport const jsonCoder: BinaryTypeCoder = {\n $write: (value, writer) => stringCoder.$write(JSON.stringify(value), writer),\n $read: (reader) => JSON.parse(stringCoder.$read(reader)),\n};\n\nexport const regexCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n writer.$writeUint8(mask([value.global, value.ignoreCase, value.multiline]));\n stringCoder.$write(value.source, writer);\n },\n $read: (reader) => {\n const [g, i, m] = unmask(reader.$readUint8());\n return new RegExp(stringCoder.$read(reader), (g ? \"g\" : \"\") + (i ? \"i\" : \"\") + (m ? \"m\" : \"\"));\n }\n};\n\nexport const writers: Record> = {\n [Type.UInt]: uintCoder.$write,\n [Type.UInt8]: uint8Coder.$write,\n [Type.UInt16]: uint16Coder.$write,\n [Type.UInt32]: uint32Coder.$write,\n [Type.Int]: intCoder.$write,\n [Type.Int8]: int8Coder.$write,\n [Type.Int16]: int16Coder.$write,\n [Type.Int32]: int32Coder.$write,\n [Type.Float64]: float64Coder.$write,\n [Type.Float32]: float32Coder.$write,\n [Type.Float16]: float16Coder.$write,\n [Type.BFloat16]: bfloat16Coder.$write,\n [Type.Scalar8]: scalar8Coder.$write,\n [Type.UScalar8]: uscalar8Coder.$write,\n [Type.Bool]: boolCoder.$write,\n [Type.Bools]: boolsCoder.$write,\n [Type.Buffer]: bufferCoder.$write,\n [Type.String]: stringCoder.$write,\n [Type.JSON]: jsonCoder.$write,\n [Type.RegExp]: regexCoder.$write,\n [Type.Date]: dateCoder.$write,\n};\n\nexport const readers: Record> = {\n [Type.UInt]: uintCoder.$read,\n [Type.UInt8]: uint8Coder.$read,\n [Type.UInt16]: uint16Coder.$read,\n [Type.UInt32]: uint32Coder.$read,\n [Type.Int]: intCoder.$read,\n [Type.Int8]: int8Coder.$read,\n [Type.Int16]: int16Coder.$read,\n [Type.Int32]: int32Coder.$read,\n [Type.Float64]: float64Coder.$read,\n [Type.Float32]: float32Coder.$read,\n [Type.Float16]: float16Coder.$read,\n [Type.BFloat16]: bfloat16Coder.$read,\n [Type.Scalar8]: scalar8Coder.$read,\n [Type.UScalar8]: uscalar8Coder.$read,\n [Type.Bool]: boolCoder.$read,\n [Type.Bools]: boolsCoder.$read,\n [Type.Buffer]: bufferCoder.$read,\n [Type.String]: stringCoder.$read,\n [Type.JSON]: jsonCoder.$read,\n [Type.RegExp]: regexCoder.$read,\n [Type.Date]: dateCoder.$read,\n};\n","/** Default maximum transmission unit in networking */\nconst MTU = 1500;\n\n/** Set Tinybuf global config */\nexport const setTinybufConfig = (c: Partial): void => {\n cfg = { ...cfg, ...c };\n};\n\nexport type TinybufConfig = {\n /**\n * (default: false)\n *\n * This sets the default value for `preserveBytes` on\n * `encode(data, preserveBytes?)`.\n *\n * By default, `encode()` returns its encoded bytes as a `Uint8Array`\n * view of the bytes in the shared encoding buffer.\n *\n * This is suitable for synchronous use (e.g. high-performance applications)\n * as it avoids slow and expensive memory allocation and fragmentation on\n * each call to `encode()`.\n *\n * However, susbsequent calls are destructive to the underlying bytes, so\n * for asynchronous uses (e.g. Promises, Workers, long-lived storage), set\n * `preserveBytes` to `true`.\n */\n safe: boolean,\n\n /**\n * (default: true)\n * By default, format encoders share a global encoding buffer for performance\n * and memory management reasons.\n *\n * When set to false, each format is allocated an individual encoding buffer.\n *\n * Enable to maximise performance and memory re-use, just be cautious of\n * possible race conditions.\n */\n useGlobalEncodingBuffer: boolean,\n\n /**\n * (default: 1500)\n * The maximum bytes that can be allocated to an encoding buffer.\n *\n * Default is 1500 bytes, the standard \"Maximum Transmission Unit\".\n */\n encodingBufferMaxSize: number,\n\n /**\n * (default: 256)\n * Initial bytes to allocate for an encoding buffer.\n */\n encodingBufferInitialSize: number,\n\n /**\n * (default: 256)\n * Additional bytes to allocated when dynamically increasing the size of an encoding buffer.\n */\n encodingBufferIncrement: number,\n};\n\n/** @internal */\nexport let cfg: TinybufConfig = {\n safe: false,\n useGlobalEncodingBuffer: true,\n encodingBufferMaxSize: MTU,\n encodingBufferInitialSize: 256,\n encodingBufferIncrement: 256,\n};\n","import { cfg } from \"../config\";\nimport { TinybufError } from \"./errors\";\n\n/**\n * Wraps a buffer with a write head pointer.\n *\n * @internal\n */\nexport class BufferWriter {\n public i: number = 0;\n public _$dataView: DataView;\n\n public constructor(initialSize: number) {\n this._$dataView = new DataView(new ArrayBuffer(initialSize));\n }\n\n public $viewBytes(): Uint8Array {\n return new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset, this.i);\n }\n\n public $copyBytes(): Uint8Array {\n return new Uint8Array(this._$dataView.buffer.slice(0, this.i));\n }\n\n // ----- Writers: -----\n\n public $writeInt8(value: number): void {\n this._$dataView.setInt8(this._$alloc(1), value);\n }\n\n public $writeInt16(value: number): void {\n this._$dataView.setInt16(this._$alloc(2), value, true);\n }\n\n public $writeInt32(value: number): void {\n this._$dataView.setInt32(this._$alloc(4), value, true);\n }\n\n public $writeUint8(value: number): void {\n this._$dataView.setUint8(this._$alloc(1), value);\n }\n\n public $writeUint16(value: number): void {\n this._$dataView.setUint16(this._$alloc(2), value, false); // big-endian for varint\n }\n\n public $writeUint32(value: number): void {\n this._$dataView.setUint32(this._$alloc(4), value, false); // big-endian for varint\n }\n\n public $writeFloat32(value: number): void {\n this._$dataView.setFloat32(this._$alloc(4), value, true);\n }\n\n public $writeFloat64(value: number): void {\n this._$dataView.setFloat64(this._$alloc(8), value, true);\n }\n\n public $writeBytes(b: Uint8Array | ArrayBuffer | ArrayBufferView): void {\n // allocate bytes first\n const j = this._$alloc(b.byteLength);\n\n let bBytes: Uint8Array = ArrayBuffer.isView(b)\n ? b instanceof Uint8Array ? b : new Uint8Array(b.buffer, b.byteOffset, b.byteLength)\n : new Uint8Array(b);\n\n // copy bytes\n new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset + j, b.byteLength).set(bBytes);\n }\n\n // ----- Private methods: -----\n\n /** @returns writer head (byteOffset) */\n private _$alloc(bytes: number): number {\n if (this.i + bytes > this._$dataView.byteLength) {\n const minBytesNeeded = this.i + bytes - this._$dataView.byteLength;\n const requestedNewBytes = Math.ceil(minBytesNeeded / cfg.encodingBufferIncrement) * cfg.encodingBufferIncrement;\n this._$resizeBuffer(this._$dataView.byteLength + requestedNewBytes);\n }\n\n const j = this.i;\n this.i += bytes;\n\n return j;\n }\n\n private _$resizeBuffer(newSize: number): void {\n if (newSize > cfg.encodingBufferMaxSize) {\n // safety check\n throw new TinybufError(`exceeded encodingBufferMaxSize: ${cfg.encodingBufferMaxSize}`);\n }\n\n const newBuf = new ArrayBuffer(newSize);\n\n // copy bytes\n const oldView = new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset, this._$dataView.byteLength);\n new Uint8Array(newBuf).set(oldView);\n\n // update ref\n this._$dataView = new DataView(newBuf);\n }\n}\n","/**\n * Wraps a buffer with a read head pointer.\n *\n * @internal\n */\nexport class BufferReader {\n public i: number;\n private _$dataView: DataView;\n\n public constructor(b: Uint8Array | ArrayBufferView | ArrayBuffer, headerBytes?: number) {\n this._$dataView = ArrayBuffer.isView(b)\n ? new DataView(b.buffer, b.byteOffset, b.byteLength)\n : new DataView(b);\n\n this.i = headerBytes ?? 0; // internal offset (header)\n }\n\n /** Read the next byte, without moving the read head pointer. */\n public $peek(): number {\n return this._$dataView.getUint8(this.i);\n }\n\n /** Skip the next byte without reading it. */\n public $skip(): void {\n this.i++;\n }\n\n // ----- Readers: -----\n\n public $readUint8(): number {\n return this._$dataView.getUint8(this.i++);\n }\n\n public $readUint16(): number {\n const r = this._$dataView.getUint16(this.i); // big-endian\n this.i += 2;\n return r;\n }\n\n public $readUint32(): number {\n const r = this._$dataView.getUint32(this.i); // big-endian\n this.i += 4;\n return r;\n }\n\n public $readInt8(): number {\n return this._$dataView.getInt8(this.i++);\n }\n\n public $readInt16(): number {\n const r = this._$dataView.getInt16(this.i, true); // little-endian\n this.i += 2;\n return r;\n }\n\n public $readInt32(): number {\n const r = this._$dataView.getInt32(this.i, true); // little-endian\n this.i += 4;\n return r;\n }\n\n public $readFloat32(): number {\n const r = this._$dataView.getFloat32(this.i, true); // little-endian\n this.i += 4;\n return r;\n }\n\n public $readFloat64(): number {\n const r = this._$dataView.getFloat64(this.i, true); // little-endian\n this.i += 8;\n return r;\n }\n\n /** @throws RangeError if exceeds length */\n public $readBytes(bytes: number): Uint8Array {\n if (this._$dataView.byteOffset + this.i + bytes > this._$dataView.byteLength) {\n throw new RangeError(\"exceeded bytes\");\n }\n\n const view = new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset + this.i, bytes);\n this.i += bytes;\n\n return view;\n }\n}\n","import { writers, readers } from \"./lib/coders\";\nimport * as coders from \"./lib/coders\";\nimport { $hashCode, $strToHashCode } from \"./lib/hashCode\";\nimport { peekHeader, peekHeaderStr } from \"./lib/peek\";\nimport { BufferWriter } from \"./lib/BufferWriter\";\nimport { BufferReader } from \"./lib/BufferReader\";\nimport {\n InferredDecodedType,\n EncoderDefinition,\n MaybeType,\n InferredTransformConfig,\n InferredValidationConfig,\n ValidationFn,\n Transforms,\n FieldDefinition,\n TypeLiteral,\n ValidTypes\n} from \"./Type\";\nimport { cfg } from \"./config\";\n\nexport type FormatHeader = string | number;\n\n/**\n * Decoded object types for a given binary format.\n * @example let onData = (data: Decoded) => {...};\n */\nexport type Decoded = FromBufferFormat extends BufferFormat ? InferredDecodedType : never;\n\n/**\n * Defines a format for encoding/decoding binary buffers.\n *\n * Optionally customize the identifier, either as a 2-byte string, an unsigned integer (0 -> 65,535), or as `null` to disable entirely.\n *\n * @example\n * const MyFormat = defineFormat({ ... });\n * const MyFormat = defineFormat('ab', { ... });\n * const MyFormat = defineFormat(1234, { ... });\n * const MyFormat = defineFormat(null, { ... });\n */\nexport function defineFormat(def: T): BufferFormat;\n/**\n * Defines a format for encoding/decoding binary buffers.\n *\n * Optionally customize the identifier, either as a 2-byte string, an unsigned integer (0 -> 65,535), or as `null` to disable entirely.\n *\n * @example\n * const MyFormat = defineFormat({ ... });\n * const MyFormat = defineFormat('ab', { ... });\n * const MyFormat = defineFormat(1234, { ... });\n * const MyFormat = defineFormat(null, { ... });\n */\nexport function defineFormat(h: HeaderType | null, def: T): BufferFormat;\nexport function defineFormat(a?: HeaderType | T, b?: T): BufferFormat {\n return a !== null && typeof a === \"object\"\n ? new BufferFormat(a as T)\n : new BufferFormat(b as T, a as HeaderType);\n}\n\nfunction isValidHeader(h: FormatHeader): boolean {\n if (typeof h === \"number\") return Number.isInteger(h) && h >= 0 && h <= 65_535;\n if (typeof h === \"string\") return new TextEncoder().encode(h).byteLength === 2;\n return false;\n}\n\n/**\n * BufferFormat is a utility class for encoding and decoding binary data based\n * on a provided encoding format.\n *\n * @see {header}\n * @see {encode(data)}\n * @see {decode(binary)}\n */\nexport class BufferFormat {\n /** @internal */\n private static _$globalWriter?: BufferWriter;\n\n /**\n * A unique identifier encoded as the first 2 bytes (or `undefined` if headerless).\n *\n * @see {peekHeader(...)}\n * @see {peekHeaderStr(...)}\n */\n public header!: HeaderType;\n\n /** @internal */\n private _$header!: number; // always uint16 vesion\n /** @internal */\n private _$type!: TypeLiteral;\n /** @internal */\n private _$fields!: Field[];\n /** @internal */\n private _$fieldsMap!: Map;\n\n /** @internal */\n private _$format?: string;\n /** @internal */\n private _$transforms?: Transforms | undefined;\n /** @internal */\n private _$validate?: ValidationFn | undefined;\n /** @internal */\n private _$hasValidationOrTransforms = false;\n /** @internal */\n private _$writer?: BufferWriter;\n\n public get encodingBuffer(): DataView | undefined {\n return this._$writer?._$dataView;\n }\n\n public constructor(\n def: EncoderType,\n header?: HeaderType | null,\n ) {\n // set definition\n if (typeof def === \"string\" && ValidTypes.includes(def)) {\n this._$type = def;\n }\n else if (def instanceof MaybeType) {\n throw new TypeError(\"Format cannot be optional\");\n }\n else if (def instanceof Object) {\n this._$type = undefined; // object\n this._$fieldsMap = new Map();\n this._$fields = Object.keys(def).map((name) => {\n const f = new Field(name, def[name]);\n this._$fieldsMap.set(name, f); // also set map entry\n return f;\n });\n\n // set headers\n if (header === undefined) {\n this.header = $hashCode(this.f) as HeaderType; // automatic\n this._$header = this.header as number;\n }\n else if (header === null) {\n this.header = undefined; // headerless\n this._$header = undefined;\n }\n else if (isValidHeader(header)) {\n this.header = header; // manual\n this._$header = typeof header === \"number\" ? header : $strToHashCode(header);\n }\n else {\n throw new TypeError(`Header must be uint16, 2 byte string, or null. Received: ${header}`);\n }\n }\n else {\n throw new TypeError(`Format must be object or Type: ${JSON.stringify(def)} ${typeof def} ${ValidTypes[def]}`);\n }\n }\n\n // ----- Static methods: -----\n\n /**\n * Read the header of a buffer as a number.\n *\n * @see {header}\n * @throws {RangeError} if buffer size < 2\n */\n public static peekHeader = peekHeader;\n\n /**\n * Read the header of a buffer as a string.\n *\n * @see {header}\n * @throws {RangeError} if buffer size < 2\n */\n public static peekHeaderStr = peekHeaderStr;\n\n // ----- Accessors: -----\n\n /**\n * @example \"{uint8,str[]?}\"\n * @internal\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private get f(): string {\n if (this._$format === undefined) {\n this._$format = this._$fields !== undefined\n ? `{${this._$fields.map(v => v.f).join(\",\")}}`\n : `${this._$type}`;\n }\n\n return this._$format;\n }\n\n /** @internal */\n private static _$initWriter(): BufferWriter {\n if (cfg.useGlobalEncodingBuffer) {\n if (!BufferFormat._$globalWriter) {\n // lazy init: global encoding buffer created at max size\n this._$globalWriter = new BufferWriter(cfg.encodingBufferInitialSize);\n }\n\n return this._$globalWriter;\n }\n\n return new BufferWriter(cfg.encodingBufferInitialSize);\n }\n\n /**\n * Encode an object to bytes.\n *\n * **Warning:** Returns an unsafe view into the encoding buffer. Pass this reference to preserve\n * performance, and to minimize memory allocation and fragmentation.\n *\n * @param data - data to encode\n * @param preserveBytes - (default: `setTinybufConfig().safe`) When set to true, copies encoded\n * bytes to a new buffer. When set to false, returns an unsafe view of bytes but prevents\n * unnnecessary memory allocation and fragmentation.\n *\n * @returns a copy of encoded bytes\n * @throws if fails to encode value to schema\n */\n public encode>(\n data: DecodedType,\n preserveBytes?: boolean,\n ): Uint8Array {\n if (!this._$writer) {\n // lazy init\n this._$writer = BufferFormat._$initWriter();\n }\n\n // reset\n this._$writer.i = 0;\n\n if (this._$hasValidationOrTransforms) {\n data = this._$preprocess(data);\n }\n\n this._$write(data, this._$writer);\n\n return (preserveBytes ?? cfg.safe)\n ? this._$writer.$copyBytes()\n : this._$writer.$viewBytes();\n }\n\n /**\n * Decode binary data to an object.\n * @throws if fails to decode bytes to schema.\n */\n public decode>(\n bytes: Uint8Array | ArrayBufferView | ArrayBuffer,\n decodeInto?: Partial,\n ): DecodedType {\n return this._$read(new BufferReader(bytes, this.header === undefined ? 0 : 2), decodeInto);\n }\n\n /**\n * Set additional transform functions to apply before encoding and after decoding.\n */\n public setTransforms(transforms: InferredTransformConfig | Transforms): this {\n this._$hasValidationOrTransforms = true;\n\n if (typeof transforms === \"function\" || (Array.isArray(transforms) && typeof transforms[0] === \"function\")) {\n this._$transforms = transforms;\n }\n else {\n for (const name of Object.keys(transforms)) {\n const field = this._$fieldsMap.get(name);\n if (!field) {\n throw new TypeError(`Failed to set transforms for field '${name}'`);\n }\n\n // Set validation for object.\n field.$coder.setTransforms(transforms[name]);\n }\n }\n\n return this;\n }\n\n /**\n * Set additional validation rules which are applied on encode() and decode().\n *\n * - Validation functions should throw an error, return an error, or return boolean false.\n * - Anything else is treated as successfully passing validation.\n */\n public setValidation(validations: InferredValidationConfig | ValidationFn): this {\n this._$hasValidationOrTransforms = true;\n\n if (typeof validations === \"function\") {\n this._$validate = validations;\n }\n else {\n for (const name of Object.keys(validations)) {\n const field = this._$fieldsMap.get(name);\n if (!field) {\n throw new TypeError(`Failed to set validation function for field '${name}'`);\n }\n\n field.$coder.setValidation(validations[name]);\n }\n }\n\n return this;\n }\n\n // ----- Implementation: -----\n\n /**\n * @param value\n * @param bw\n * @throws if the value is invalid\n *\n * @internal\n */\n private _$write(value: any, bw: BufferWriter): void {\n // write header\n if (this._$header !== undefined) bw.$writeUint16(this._$header);\n\n // write scalar\n if (this._$type !== undefined) {\n const safeValue = (this._$validate || this._$transforms) ? this._$preprocess(value) : value;\n\n return writers[this._$type](safeValue, bw);\n }\n\n // check for object type\n if (typeof value !== \"object\" || !value) {\n throw new TypeError(\"expected object type\");\n }\n\n // write each field\n for (const field of this._$fields) {\n const subValue = value[field.$name];\n\n if (field.$isOptional) {\n if (subValue === undefined || subValue === null) {\n coders.boolCoder.$write(false, bw);\n continue; // skip\n }\n else {\n coders.boolCoder.$write(true, bw);\n }\n }\n else if (subValue == null) {\n throw new Error(`missing required value: ${field.$name}`);\n }\n\n if (field.$isArray) {\n // array\n this._$writeArray(subValue, bw, field.$coder);\n continue;\n }\n\n // scalar/object field\n field.$coder._$write(subValue, bw);\n }\n }\n\n /**\n * pre-process: validation and/or transforms\n * @internal\n */\n private _$preprocess>(data: T): T {\n if (this._$validate) this._$processValidation(data);\n\n if (typeof this._$transforms === \"function\") {\n return this._$transforms(data);\n }\n else if (Array.isArray(this._$transforms) && typeof this._$transforms[0] === \"function\") {\n return this._$transforms[0](data);\n }\n\n return data;\n }\n\n /**\n * post-process: validation and/or transforms\n * @internal\n */\n private _$postprocess>(data: T): T {\n if (Array.isArray(this._$transforms) && typeof this._$transforms[1] === \"function\") {\n data = this._$transforms[1](data);\n }\n\n if (this._$validate) this._$processValidation(data);\n\n return data;\n }\n\n private _$processValidation(data: any): void {\n if (!this._$validate) return;\n const res = this._$validate(data);\n if (res instanceof Error) throw res;\n if (res === false) throw new Error(\"failed validation\");\n }\n\n /**\n * This function will be executed only the first time\n * After that, we'll compile the read routine and add it directly to the instance\n * @param state\n * @returns\n * @throws if fails\n *\n * @internal\n */\n private _$read>(state: BufferReader, obj?: Partial): DecodedType {\n // This function will be executed only the first time to compile the read routine.\n // After that, we'll compile the read routine and add it directly to the instance\n\n // Update the read method implementation.\n this._$read = this._$compileFormatReadFn();\n\n return this._$read(state, obj);\n }\n\n /**\n * Generate read function code for this coder.\n *\n * @example\n * let v=o??{};\n * v.prop1=this._$readField(0,s,o);\n * v.prop2=this._$readField(1,s,o);\n * return v\n *\n * @internal\n */\n private _$makeObjectReadFnBody(): string {\n const fieldsStr: string = this._$fields\n .map(({ $name: n }, i) => `v.${n}=this.${this._$readField.name}(${i},s,v.${n})`)\n .join(\";\");\n\n return `let v=o??{};${fieldsStr};return v;`;\n }\n\n /**\n * Read an individual field.\n * @internal\n */\n private _$readField(fieldIndex: number, state: BufferReader, obj?: any): any {\n const field = this._$fields[fieldIndex];\n\n if (field.$isOptional && !coders.boolCoder.$read(state)) {\n return undefined;\n }\n\n if (field.$isArray) {\n return this._$readArray(field.$coder, state, obj);\n }\n\n return field.$coder._$read(state, obj);\n }\n\n /**\n * Compile the decode() method for this object.\n *\n * @internal\n */\n private _$compileFormatReadFn>(): (state: BufferReader, obj: Partial | undefined) => DecodedType {\n if (this._$type !== undefined) {\n // scalar type\n return this._$hasValidationOrTransforms\n ? (s) => this._$postprocess(readers[this._$type](s))\n : readers[this._$type];\n }\n\n // object type\n return new Function(\"s\", \"o\", this._$makeObjectReadFnBody()) as any;\n }\n\n /**\n * @internal\n */\n private _$writeArray(value: any[], bw: BufferWriter, type: BufferFormat): void {\n if (!Array.isArray(value)) {\n throw new TypeError(`expected array, instead got: ${value}`);\n }\n\n coders.uintCoder.$write(value.length, bw);\n for (let i = 0; i < value.length; i++) {\n type._$write(value[i], bw);\n }\n }\n\n /**\n * @throws if invalid data\n * @internal\n */\n private _$readArray(type: BufferFormat, state: any, obj?: Array): Array {\n const len = coders.uintCoder.$read(state);\n const arr = obj?.length === len ? obj : new Array(len);\n for (let j = 0; j < arr.length; j++) {\n arr[j] = type._$read(state, obj?.[j]);\n }\n return arr;\n }\n}\n\n/**\n * Parses and represents an object field.\n *\n * @internal\n */\nclass Field {\n public $name: string;\n public $coder: BufferFormat;\n public $isOptional: boolean;\n public $isArray: boolean;\n\n private _$formatString?: string;\n\n public constructor(name: string, rawType: FieldDefinition) {\n this.$isOptional = rawType instanceof MaybeType;\n let type = rawType instanceof MaybeType ? rawType.type : rawType;\n\n this.$name = name;\n\n if (Array.isArray(type)) {\n if (type.length !== 1) {\n throw new TypeError(\"Array type must contain exactly one format\");\n }\n\n type = type[0];\n this.$isArray = true;\n }\n else {\n this.$isArray = false;\n }\n\n this.$coder = new BufferFormat(type, null);\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public get f(): string {\n if (this._$formatString === undefined) {\n this._$formatString = `${(this.$coder as any).f}${this.$isArray ? \"[]\" : \"\"}${this.$isOptional ? \"?\" : \"\"}`;\n }\n\n return this._$formatString;\n }\n}\n"],"names":["TinybufError","Error","$hashCode","str","hash","i","length","charCodeAt","$strToHashCode","$hashCodeToStr","hashCode","String","fromCharCode","Math","floor","peekHeader","b","ArrayBuffer","isView","DataView","buffer","byteOffset","getUint16","peekHeaderStr","BufferParser","constructor","this","_$formats","Map","_$data","processBuffer","f","data","cb","r","header","has","get","_a","decode","set","e","err","stack","on","format","callback","decodeInPlace","ignore","forEach","clear","$floor","$ceil","ceil","$clamp","value","min","max","$roundTowardZero","x","$roundAwayFromZero","$touscal8","$toscal8","$fromuscal8","$fromscal8","Type","UInt","UInt8","UInt16","UInt32","Int","Int8","Int16","Int32","Float64","Float32","Float16","BFloat16","Scalar8","UScalar8","Bool","Bools","Buffer","JSON","RegExp","Date","ValidTypes","Object","values","MaybeType","type","mask","padBit","reduce","n","unmask","l","len","undefined","clz32","Array","isArray","val","$utf8encode","encoder","TextEncoder","encode","$utf8decode","decoder","TextDecoder","y","$tof16","Float32Array","Int32Array","s","z","$fromf16","pow","d","m","Infinity","NaN","Uint32Array","MAX_VARUINT32","MAX_VARINT32","POW_32","uintCoder","$write","writer","Number","$writeUint8","$writeUint16","$writeUint32","$read","reader","firstByte","$peek","$readUint32","$readUint16","$skip","uint8Coder","$readUint8","uint16Coder","uint32Coder","intCoder","int8Coder","$writeInt8","$readInt8","int16Coder","$writeInt16","$readInt16","int32Coder","$writeInt32","$readInt32","bfloat16Coder","$tobf16","$frombf16","float16Coder","float32Coder","$writeFloat32","$readFloat32","float64Coder","$writeFloat64","$readFloat64","uscalar8Coder","scalar8Coder","dateCoder","getTime","bufferCoder","byteLength","$writeBytes","$readBytes","stringCoder","boolCoder","boolsCoder","slice","p","jsonCoder","stringify","parse","regexCoder","global","ignoreCase","multiline","source","g","writers","readers","cfg","safe","useGlobalEncodingBuffer","encodingBufferMaxSize","encodingBufferInitialSize","encodingBufferIncrement","BufferWriter","initialSize","_$dataView","$viewBytes","Uint8Array","$copyBytes","setInt8","_$alloc","setInt16","setInt32","setUint8","setUint16","setUint32","setFloat32","setFloat64","j","bBytes","bytes","minBytesNeeded","requestedNewBytes","_$resizeBuffer","newSize","newBuf","oldView","BufferReader","headerBytes","getUint8","getUint32","getInt8","getInt16","getInt32","getFloat32","getFloat64","RangeError","view","BufferFormat","encodingBuffer","_$writer","def","_$hasValidationOrTransforms","includes","_$type","TypeError","_$fieldsMap","_$fields","keys","map","name","Field","_$header","isValidHeader","h","isInteger","_$format","v","join","_$initWriter","_$globalWriter","preserveBytes","_$preprocess","_$write","decodeInto","_$read","setTransforms","transforms","_$transforms","field","$coder","setValidation","validations","_$validate","bw","safeValue","subValue","$name","$isOptional","coders.boolCoder","$isArray","_$writeArray","_$processValidation","_$postprocess","res","state","obj","_$compileFormatReadFn","_$makeObjectReadFnBody","fieldsStr","_$readField","fieldIndex","_$readArray","Function","coders.uintCoder","arr","rawType","_$formatString","bf16round","defineFormat","a","f16round","optional","t","scalround","c","assign","uscalround"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.cjs","sources":["../src/core/lib/errors.ts","../src/core/lib/hashCode.ts","../src/core/lib/peek.ts","../src/core/BufferParser.ts","../src/core/lib/math.ts","../src/core/lib/scalar.ts","../src/core/Type.ts","../src/core/lib/bitmask.ts","../src/core/lib/utf8.ts","../src/core/lib/float16.ts","../src/core/lib/bfloat16.ts","../src/core/lib/coders.ts","../src/core/config.ts","../src/core/lib/BufferWriter.ts","../src/core/lib/BufferReader.ts","../src/core/BufferFormat.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unified-signatures */\n\nexport class TinybufError extends Error {}\n","/**\n * DJB2 hash algorithm (modified for 16-bit uints).\n *\n * DJB2 is a simple and widely used non-cryptographic\n * hash function created by Daniel J. Bernstein.\n *\n * @returns 16-bit unsigned integer\n */\nexport function $hashCode(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash * 33) ^ str.charCodeAt(i);\n }\n return hash & 0xFFFF; // Ensure the result is a Uint16\n}\n\n/**\n * Returns an unsigned 16-bit integer hashcode for some string.\n * Prefers 2 character string.\n *\n * @returns A UInt16 between 0 and 65535 (inclusive).\n */\nexport function $strToHashCode(str: string): number {\n if (str.length !== 2) return $hashCode(str);\n return str.charCodeAt(0) * 256 + str.charCodeAt(1);\n}\n\n/**\n * Convert a UInt16 hashcode to a 2-byte string.\n */\nexport function $hashCodeToStr(hashCode: number): string {\n return String.fromCharCode(Math.floor(hashCode / 256)) + String.fromCharCode(hashCode % 256);\n}\n","import { $hashCodeToStr } from \"./hashCode\";\n\n\n/**\n * Read the header bytes of a buffer as a number.\n *\n * @throws {RangeError} if buffer size < 2\n */\nexport function peekHeader(b: ArrayBuffer | ArrayBufferView): number {\n return (ArrayBuffer.isView(b) ? new DataView(b.buffer, b.byteOffset, 2) : new DataView(b, 0, 2)).getUint16(0, false);\n}\n\n/**\n * Read the header bytes of a buffer as a string.\n *\n * @throws {RangeError} if buffer length < 2\n */\nexport function peekHeaderStr(b: ArrayBuffer | ArrayBufferView): string {\n return $hashCodeToStr(peekHeader(b));\n}\n","import { BufferFormat } from \"./BufferFormat\";\nimport { EncoderDefinition, DecodedType } from \"./Type\";\nimport { TinybufError } from \"./lib/errors\";\nimport { $hashCodeToStr, $strToHashCode } from \"./lib/hashCode\";\nimport { peekHeader } from \"./lib/peek\";\n\ntype AnyFormat = BufferFormat;\ntype Uint16FormatHeader = number;\n\n/**\n * Small utility for registering and processing format handlers.\n *\n * @example\n * const myHandler = bufferParser()\n * .on(FormatA, aData => {})\n * .on(FormatB, bData => {});\n *\n * myHandler.processBuffer(bytes);\n */\nexport const bufferParser = (): BufferParser => new BufferParser();\n\nexport class BufferParser {\n /** @internal */\n private _$formats = new Map any, decodeInPlace: boolean]>();\n private _$data = new Map(); // used when decoding in-place\n\n /**\n * Decode an array buffer and trigger the relevant data handler.\n *\n * When passed an ArrayBufferView, accesses the underlying 'buffer' instance directly.\n *\n * @throws {TinybufError} if fails to decode, or no handler is registered\n */\n public processBuffer(b: ArrayBuffer | ArrayBufferView): void {\n let f: any, data: any, cb: (data: any) => any, r: boolean;\n\n try {\n const header = peekHeader(b);\n\n if (!this._$formats.has(header)) {\n throw new TinybufError(`Unknown format: ${header} '${$hashCodeToStr(header)}')`);\n }\n\n [f, cb, r] = this._$formats.get(header);\n if (r) data = this._$data.get(header) ?? {};\n data = f.decode(b, data);\n if (r) this._$data.set(header, data);\n }\n catch (e) {\n const err = new TinybufError(`Failed to decode: ${e}`);\n err.stack = e.stack;\n\n throw err;\n }\n\n cb(data);\n }\n\n /**\n * Register a format handler.\n */\n public on>(\n format: BufferFormat,\n callback: (data: TDecodedType) => any,\n {\n decodeInPlace = false,\n } = {},\n ): this {\n if (format.header == null) {\n throw new TinybufError(\"Format requires header\");\n }\n\n const header = typeof format.header === \"string\" ? $strToHashCode(format.header) : format.header;\n\n if (this._$formats.has(header) && this._$formats.get(header)?.[0] !== format) {\n throw new TinybufError(`Format header collision: ${format.header}`);\n }\n\n this._$formats.set(header, [format, callback, decodeInPlace]);\n\n return this;\n }\n\n /** Register a format (or formats) that are recognized. */\n public ignore(...format: AnyFormat[]): this {\n format.forEach(f => this.on(f, () => {}));\n return this;\n }\n\n /** Clears all registered formats and handlers. */\n public clear(): void {\n this._$formats.clear();\n this._$data.clear();\n }\n}\n","export const $floor = Math.floor,\n $ceil = Math.ceil;\n\n/** Clamp a number to a range. */\nexport const $clamp = (value: number, min: number, max: number): number =>\n value > max ? max : value < min ? min : value;\n\n/** Round toward zero */\nexport const $roundTowardZero = (x: number): number => x < 0 ? $ceil(x) : $floor(x);\n\n/** Round away zero */\nexport const $roundAwayFromZero = (x: number): number =>\n x < 0 ? $floor(x) : $ceil(x);\n","import { $clamp, $roundTowardZero, $roundAwayFromZero } from \"./math\";\n\n/**\n * Quantize a number to an 8-bit scalar between 0.0 and 1.0.\n *\n * @returns A number (double) in its closest signed scalar representation.\n */\nexport function uscalround(x: number): number {\n return $fromuscal8($touscal8(x));\n}\n\n/**\n * Quantize a number to an 8-bit signed scalar between -1.0 and 1.0.\n *\n * @returns A number (double) in its closest signed scalar representation.\n */\nexport function scalround(x: number): number {\n return $fromscal8($toscal8(x));\n}\n\n/** @returns A UInt8 bitmask representation. */\nexport function $touscal8(x: number): number {\n return $clamp(127 + $roundTowardZero(x * 254 - 127), 0, 254);\n}\n\n/** @returns A UInt8 bitmask representation. */\nexport function $toscal8(x: number): number {\n return $clamp($roundTowardZero(x * 127), -127, 127) + 127;\n}\n\n/** @returns An unsigned scalar between 0.0 and 1.0. */\nexport function $fromuscal8(x: number): number {\n // Make symmetric: (0.5 + round((uint8 - 127) / 254 * 100)) / 100\n return $clamp(($roundAwayFromZero((x - 127) * 0.3937007874015748) + 50) * 0.01, 0, 1);\n}\n\n/** @returns A signed scalar between -1.0 and 1.0. */\nexport function $fromscal8(x: number): number {\n // Make symmetric: round((uint8 - 127) / 127 * 100) / 100\n return $clamp($roundAwayFromZero((x - 127) * 0.787401574803149) * 0.01, -1, 1);\n}\n","/**\n * Field types for defining encoding formats.\n *\n * @see [Types](https://github.com/reececomo/tinybuf/blob/main/docs/types.md)\n */\nexport const Type = {\n /**\n * Unsigned integer (1 - 8 bytes).\n * - 0 → 127 = 1 byte\n * - 128 → 16,384 = 2 bytes\n * - 16,385 → 536,870,911 = 4 bytes\n * - 536,870,912 → `Number.MAX_SAFE_INTEGER` = 8 bytes\n */\n UInt: \"uint\",\n\n /** Unsigned 8-bit integer (between 0 and 255, 1 byte). */\n UInt8: \"u8\",\n\n /** Unsigned 16-bit integer (between 0 and 65,535, 2 bytes). */\n UInt16: \"u16\",\n\n /** Unsigned 32-bit integer (between 0 and 4,294,967,295, 4 bytes). */\n UInt32: \"u32\",\n\n /**\n * Signed integer (1 - 8 bytes).\n * - 0 → ±64 = 1 byte\n * - ±65 → ±8,192 = 2 bytes\n * - ±8,193 → ±268,435,456 = 4 bytes\n * - ±268,435,457 → ±`Number.MAX_SAFE_INTEGER` = 8 bytes\n */\n Int: \"int\",\n\n /** Signed 1 byte integer (between -127 and 127). */\n Int8: \"i8\",\n\n /** Signed 2 byte integer (between -32,767 and 32,767). */\n Int16: \"i16\",\n\n /** Signed 4 byte integer (between -2,147,483,647 and 2,147,483,647). */\n Int32: \"i32\",\n\n /** Default JavaScript `number` type. Floating-point number (64-bit, double precision, 8 bytes). */\n Float64: \"f64\",\n\n /** Floating-point number (32-bit, single precision, 4 bytes). */\n Float32: \"f32\",\n\n /**\n * Floating-point number (16-bit in FP16 format, half precision, 2 bytes).\n *\n * **Warning:** Low precision; maximum range: ±65,504.\n */\n Float16: \"f16\",\n\n /**\n * Floating-point number (16-bit in BF16 format, half precision, 2 bytes).\n *\n * **Warning:** Low precision.\n */\n BFloat16: \"b16\",\n\n /** A signed 2-decimal scalar between -1.00 and 1.00 (1 byte). */\n Scalar8: \"sc\",\n\n /** An unsigned 2-decimal scalar between 0.00 and 1.00 (1 byte). */\n UScalar8: \"usc\",\n\n /**\n * Boolean value (1 byte).\n * @see {Bools} for packing multiple booleans into a single byte.\n */\n Bool: \"bl\",\n\n /** Any array of booleans (1 bit overhead, encoded as UInt). */\n Bools: \"bls\",\n\n /** Any ArrayBuffer or ArrayBufferView (e.g. Uint8Array) value (encoded as 1 x UInt for byte length + buffer bytes). */\n Buffer: \"buf\",\n\n /** A UTF-8 string (encoded as 1 x UInt for UTF-8 byte length + UTF-8 bytes). */\n String: \"str\",\n\n /** Any JSON data (encodes as UTF-8). */\n JSON: \"jsn\",\n\n /** JavaScript RegExp object. */\n RegExp: \"re\",\n\n /**\n * JavaScript Date object.\n *\n * Encoded as an 8 byte (64-bit) integer UTC timestamp from as the number\n * of milliseconds since the Unix Epoch (January 1, 1970, 00:00:00 UTC).\n *\n * @see {Date}\n */\n Date: \"dt\",\n} as const;\n\nexport type TypeLiteral = typeof Type[keyof typeof Type];\nexport const ValidTypes = Object.values(Type);\n\n/**\n * Mappings for the value types.\n */\nexport type ValueTypes = {\n [Type.Int]: number;\n [Type.Int8]: number;\n [Type.Int16]: number;\n [Type.Int32]: number;\n [Type.UInt]: number;\n [Type.UInt8]: number;\n [Type.UInt16]: number;\n [Type.UInt32]: number;\n [Type.Float64]: number;\n [Type.Float32]: number;\n [Type.Float16]: number;\n [Type.BFloat16]: number;\n [Type.Scalar8]: number;\n [Type.UScalar8]: number;\n [Type.Bool]: boolean;\n [Type.Bools]: boolean[];\n [Type.Buffer]: Uint8Array | ArrayBuffer | ArrayBufferView;\n [Type.String]: string;\n [Type.JSON]: any;\n [Type.RegExp]: RegExp;\n [Type.Date]: Date;\n};\n\n/** https://www.totaltypescript.com/concepts/the-prettify-helper */\ntype Pretty = T extends ArrayBuffer | ArrayBufferView | Date | RegExp | Uint8Array ? T\n : T extends Array ? Array>\n : T extends object ? {[K in keyof T]: Pretty} & unknown : T;\n\n/** @throws any error too */\nexport type ValidationFn = (x: T) => undefined | boolean | Error;\nexport type TransformFn = (x: T) => T;\nexport type Transforms = TransformFn | [preEncode: TransformFn] | [preEncode: TransformFn | undefined, postDecode: TransformFn | undefined];\n\n/**\n * A wrapper around any Type definition that declares it as optional.\n */\nexport class MaybeType {\n public constructor(public type: T) {}\n}\n\n/**\n * Wrap any definition as optional.\n */\nexport function optional(t: T): MaybeType {\n return new MaybeType(t);\n}\n\n/**\n * A definition for an object binary encoder.\n */\nexport type EncoderDefinition = {\n [key: string]: FieldDefinition | MaybeType;\n};\n\n/**\n * Definition for an object-field binary encoder.\n */\nexport type FieldDefinition = keyof ValueTypes | [keyof ValueTypes] | EncoderDefinition | [EncoderDefinition] | MaybeType;\n\n/**\n * The resulting type of the decoded data, based on the encoder definition.\n */\ntype RawDecodedType = {\n [EKey in keyof EncoderType as EncoderType[EKey] extends MaybeType ? never : EKey]: EncoderType[EKey] extends keyof ValueTypes\n ? ValueTypes[EncoderType[EKey]]\n : EncoderType[EKey] extends [keyof ValueTypes]\n ? Array\n : EncoderType[EKey] extends EncoderDefinition\n ? RawDecodedType\n : EncoderType[EKey] extends [EncoderDefinition]\n ? Array>\n : never;\n} & {\n [EKey in keyof EncoderType as EncoderType[EKey] extends MaybeType ? EKey : never]?: EncoderType[EKey] extends MaybeType\n ? ValueTypes[OptionalValue] | undefined\n : EncoderType[EKey] extends MaybeType\n ? Array | undefined\n : EncoderType[EKey] extends MaybeType\n ? RawDecodedType | undefined\n : never;\n};\n\nexport type DecodedType = Pretty>;\n\nexport type TransformConfig = {\n [EKey in keyof EncoderType]?: EncoderType[EKey] extends keyof ValueTypes\n ? Transforms\n : EncoderType[EKey] extends [keyof ValueTypes]\n ? Transforms\n : EncoderType[EKey] extends EncoderDefinition\n ? TransformConfig\n : EncoderType[EKey] extends [EncoderDefinition]\n ? TransformConfig\n : EncoderType[EKey] extends MaybeType\n ? Transforms\n : EncoderType[EKey] extends MaybeType\n ? Transforms\n : EncoderType[EKey] extends MaybeType\n ? TransformConfig | undefined\n : never;\n};\n\nexport type ValidationConfig = {\n [EKey in keyof EncoderType]?: EncoderType[EKey] extends keyof ValueTypes\n ? ValidationFn\n : EncoderType[EKey] extends [keyof ValueTypes]\n ? ValidationFn\n : EncoderType[EKey] extends EncoderDefinition\n ? ValidationConfig\n : EncoderType[EKey] extends [EncoderDefinition]\n ? ValidationConfig\n : EncoderType[EKey] extends MaybeType\n ? ValidationFn\n : EncoderType[EKey] extends MaybeType\n ? ValidationFn\n : EncoderType[EKey] extends MaybeType\n ? ValidationConfig | undefined\n : never;\n};\n","/**\n * Mask booleans to a uint32.\n *\n * @param x - A boolean array.\n * @param padBit - A bit to pad the mask (for variable length data).\n */\nexport const mask = (x: boolean[], padBit: 0 | 1 = 0b1): number => {\n return x.reduce((n, b: any) => (n << 1) | b, padBit);\n};\n\n/**\n * Unmask booleans from a uint32.\n *\n * @param x - A uint32 number.\n * @param l - number of booleans to expect (default: infer lenth from x where x is encoded with a pad bit)\n * or pass an existing boolean array to decode in-place.\n */\nexport const unmask = (x: number, l?: number | boolean[]): boolean[] => {\n const len = l === undefined ? 31 - Math.clz32(x) : Array.isArray(l) ? l.length : l;\n const val = Array.isArray(l) && l.length === len ? l : new Array(len);\n for (let i = 0; i < len; i++) val[i] = !!(x & (1 << (len - 1 - i)));\n return val;\n};\n","export const $utf8encode = (function () {\n const encoder = new TextEncoder();\n return (x?: string): Uint8Array => encoder.encode(x);\n})();\n\nexport const $utf8decode = (function () {\n const decoder = new TextDecoder(\"utf-8\");\n return (y: Uint8Array): string => decoder.decode(y);\n})();\n","/**\n * Returns the nearest half precision float representation of a number.\n * @param x A numeric expression.\n */\nexport function f16round(x: number): number {\n return $fromf16($tof16(x));\n}\n\n/**\n * Returns the nearest half precision float representation of a number as a 16-bit bitmask.\n */\nexport const $tof16 = (function() {\n const x = new Float32Array(1);\n const y = new Int32Array(x.buffer);\n\n return function (f: number) {\n x[0] = f;\n let i = y[0]; // 32-bit int\n let s = (i >> 16) & 0X8000; // sign\n let z = (i & 0X7FFFFFFF) + 0X1000 | 0;\n\n if (z >= 0X47800000) {\n if ((i & 0X7FFFFFFF) < 0X47800000) return s | 0X7BFF;\n if (z < 0X7F800000) return s | 0X7C00;\n return s | 0X7C00 | (i & 0X007FFFFF) >> 13;\n }\n if (z >= 0X38800000) return s | z - 0X38000000 >> 13;\n else if (z < 0X33000000) return s;\n z = (i & 0X7FFFFFFF) >> 23;\n return s | ((i & 0X7FFFFF | 0X800000)\n + (0X800000 >>> z - 102)\n >> 126 - z);\n };\n}());\n\n/**\n * Returns the nearest half precision float value for a 16-bit bitmask.\n */\nexport const $fromf16 = (function() {\n const z = Math.pow(2, -24); // subnormal constant\n const d = new Float32Array(32 + 1024);\n for (let e = 0; e < 32; e++) d[e] = Math.pow(2, e - 15); // biased exponents\n for (let m = 0; m < 1024; m++) d[m + 0x20] = 1 + m / 1024; // normalized offset mantissas\n\n return function (b: number): number {\n const s = (b & 32768) === 32768 ? -1 : 1; // sign: 1 bit\n const e = b & 31744; // exponent: 5 bits\n const m = b & 1023; // mantissa: 10 bits\n\n if (e === 0) return m === 0 ? s * 0 : s * z;\n if (e === 31744) return m === 0 ? s * Infinity : NaN;\n return d[e >> 10] * d[m + 0x20] * s;\n };\n}());\n","const i = new Uint32Array(1);\nconst f = new Float32Array(i.buffer);\n\n/**\n * Returns the nearest bfloat16 representation of a number.\n * @param x A numeric expression.\n */\nexport function bf16round(x: number): number {\n f[0] = x;\n i[0] = i[0] & 0xFFFF0000;\n return f[0];\n}\n\n/** Returns a 16-bit bfloat16 bitmask for a given float. */\nexport function $tobf16(x: number): number {\n f[0] = x;\n return i[0] >>> 16;\n}\n\n/** Returns the nearest value from a 16-bit bfloat16 bitmask. */\nexport function $frombf16(x: number): number {\n i[0] = x << 16;\n return f[0];\n}\n","import { BufferWriter } from \"./BufferWriter\";\nimport { BufferReader } from \"./BufferReader\";\nimport {\n $fromuscal8,\n $fromscal8,\n $touscal8,\n $toscal8\n} from \"./scalar\";\nimport { TypeLiteral, Type } from \"../Type\";\nimport { mask, unmask } from \"./bitmask\";\nimport { $utf8decode, $utf8encode } from \"./utf8\";\nimport { $floor } from \"./math\";\nimport { $fromf16, $tof16 } from \"./float16\";\nimport { $frombf16, $tobf16 } from \"./bfloat16\";\n\n// Pre-calculated constants\nconst MAX_VARUINT8 = 128,\n MAX_VARUINT16 = 16_384,\n MAX_VARUINT32 = 536_870_912,\n MAX_VARINT8 = 64,\n MAX_VARINT16 = 8_192,\n MAX_VARINT32 = 268_435_456,\n POW_32 = 0x100000000;\n\ntype WriterFn = (value: W, writer: BufferWriter) => void;\ntype ReaderFn = (reader: BufferReader, overwrite?: Partial) => R;\n\nexport interface BinaryTypeCoder {\n $write: WriterFn;\n $read: ReaderFn;\n}\n\n/**\n * Format (big-endian):\n * 7b 0xxxxxxx\n * 14b 10xxxxxx xxxxxxxx\n * 29b 110xxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n * 61b 111xxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n */\nexport const uintCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n if (typeof value !== \"number\") value = Number(value);\n if (value < 0) value = 0;\n if (value < MAX_VARUINT8) writer.$writeUint8(value);\n else if (value < MAX_VARUINT16) writer.$writeUint16(value + 0x8000);\n else if (value < MAX_VARUINT32) writer.$writeUint32(value + 0xc0000000);\n else if (value >= MAX_VARUINT32) {\n writer.$writeUint32($floor(value / POW_32) + 0xe0000000);\n writer.$writeUint32(value >>> 0);\n }\n else {\n // coercion case\n writer.$writeUint8(value as any === true ? 1 : 0);\n }\n },\n $read: (reader) => {\n const firstByte = reader.$peek();\n\n if (!(firstByte & 0x80)) {\n reader.$skip();\n return firstByte;\n }\n else if (!(firstByte & 0x40)) {\n return reader.$readUint16() - 0x8000;\n }\n else if (!(firstByte & 0x20)) {\n return reader.$readUint32() - 0xc0000000;\n }\n\n return (reader.$readUint32() - 0xe0000000) * POW_32\n + reader.$readUint32();\n }\n};\n\nexport const uint8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8(value),\n $read: (reader) => reader.$readUint8(),\n};\n\nexport const uint16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint16(value),\n $read: (reader) => reader.$readUint16(),\n};\n\nexport const uint32Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint32(value),\n $read: (reader) => reader.$readUint32(),\n};\n\n/**\n * Format (big-endian):\n * 7b 0xxxxxxx\n * 14b 10xxxxxx xxxxxxxx\n * 29b 110xxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n * 61b 111xxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n */\nexport const intCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n if (typeof value !== \"number\") value = Number(value);\n if (value >= -MAX_VARINT8 && value < MAX_VARINT8) writer.$writeUint8(value & 0x7f);\n else if (value >= -MAX_VARINT16 && value < MAX_VARINT16) writer.$writeUint16((value & 0x3fff) + 0x8000);\n else if (value >= -MAX_VARINT32 && value < MAX_VARINT32) writer.$writeUint32((value & 0x1fffffff) + 0xc0000000);\n else if (value < -MAX_VARINT32 || value >= MAX_VARINT32) {\n // Split in two 32b uints\n writer.$writeUint32(($floor(value / POW_32) & 0x1fffffff) + 0xe0000000);\n writer.$writeUint32(value >>> 0);\n }\n else {\n // coercion case\n writer.$writeUint8(value as any === true ? 0x7f : 0);\n }\n },\n $read: (reader) => {\n let firstByte = reader.$peek(), i: number;\n\n if (!(firstByte & 0x80)) {\n reader.$skip();\n return (firstByte & 0x40) ? (firstByte | 0xffffff80) : firstByte;\n }\n else if (!(firstByte & 0x40)) {\n i = reader.$readUint16() - 0x8000;\n return (i & 0x2000) ? (i | 0xffffc000) : i;\n }\n else if (!(firstByte & 0x20)) {\n i = reader.$readUint32() - 0xc0000000;\n return (i & 0x10000000) ? (i | 0xe0000000) : i;\n }\n else {\n i = reader.$readUint32() - 0xe0000000;\n i = (i & 0x10000000) ? (i | 0xe0000000) : i;\n return i * POW_32 + reader.$readUint32();\n }\n }\n};\n\nexport const int8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeInt8(value),\n $read: (reader) => reader.$readInt8(),\n};\n\nexport const int16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeInt16(value),\n $read: (reader) => reader.$readInt16(),\n};\n\nexport const int32Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeInt32(value),\n $read: (reader) => reader.$readInt32(),\n};\n\nexport const bfloat16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint16($tobf16(value)),\n $read: (reader) => $frombf16(reader.$readUint16()),\n};\n\nexport const float16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint16($tof16(value)),\n $read: (reader) => $fromf16(reader.$readUint16()),\n};\n\nexport const float32Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeFloat32(value),\n $read: (reader) => reader.$readFloat32(),\n};\n\nexport const float64Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeFloat64(value),\n $read: (reader) => reader.$readFloat64(),\n};\n\nexport const uscalar8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8($touscal8(value)),\n $read: (reader) => $fromuscal8(reader.$readUint8()),\n};\n\nexport const scalar8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8($toscal8(value)),\n $read: (reader) => $fromscal8(reader.$readUint8()),\n};\n\nexport const dateCoder: BinaryTypeCoder = {\n $write: (value, writer) => intCoder.$write(value.getTime(), writer),\n $read: (reader) => new Date(intCoder.$read(reader)),\n};\n\nexport const bufferCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n uintCoder.$write(value.byteLength, writer); // prefix length\n writer.$writeBytes(value);\n },\n $read: (reader) => reader.$readBytes(uintCoder.$read(reader)),\n};\n\nexport const stringCoder: BinaryTypeCoder = {\n $write: (value, writer) => bufferCoder.$write($utf8encode(value), writer),\n $read: (reader) => $utf8decode(bufferCoder.$read(reader)),\n};\n\nexport const boolCoder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8(value ? 1 : 0),\n $read: (reader) => reader.$readUint8() !== 0,\n};\n\nexport const boolsCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n if (value.length > 28) value = value.slice(0, 28); // drop additional\n uintCoder.$write(mask(value), writer);\n },\n $read: (reader, p) => unmask(uintCoder.$read(reader), p),\n};\n\nexport const jsonCoder: BinaryTypeCoder = {\n $write: (value, writer) => stringCoder.$write(JSON.stringify(value), writer),\n $read: (reader) => JSON.parse(stringCoder.$read(reader)),\n};\n\nexport const regexCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n writer.$writeUint8(mask([value.global, value.ignoreCase, value.multiline]));\n stringCoder.$write(value.source, writer);\n },\n $read: (reader) => {\n const [g, i, m] = unmask(reader.$readUint8());\n return new RegExp(stringCoder.$read(reader), (g ? \"g\" : \"\") + (i ? \"i\" : \"\") + (m ? \"m\" : \"\"));\n }\n};\n\nexport const writers: Record> = {\n [Type.UInt]: uintCoder.$write,\n [Type.UInt8]: uint8Coder.$write,\n [Type.UInt16]: uint16Coder.$write,\n [Type.UInt32]: uint32Coder.$write,\n [Type.Int]: intCoder.$write,\n [Type.Int8]: int8Coder.$write,\n [Type.Int16]: int16Coder.$write,\n [Type.Int32]: int32Coder.$write,\n [Type.Float64]: float64Coder.$write,\n [Type.Float32]: float32Coder.$write,\n [Type.Float16]: float16Coder.$write,\n [Type.BFloat16]: bfloat16Coder.$write,\n [Type.Scalar8]: scalar8Coder.$write,\n [Type.UScalar8]: uscalar8Coder.$write,\n [Type.Bool]: boolCoder.$write,\n [Type.Bools]: boolsCoder.$write,\n [Type.Buffer]: bufferCoder.$write,\n [Type.String]: stringCoder.$write,\n [Type.JSON]: jsonCoder.$write,\n [Type.RegExp]: regexCoder.$write,\n [Type.Date]: dateCoder.$write,\n};\n\nexport const readers: Record> = {\n [Type.UInt]: uintCoder.$read,\n [Type.UInt8]: uint8Coder.$read,\n [Type.UInt16]: uint16Coder.$read,\n [Type.UInt32]: uint32Coder.$read,\n [Type.Int]: intCoder.$read,\n [Type.Int8]: int8Coder.$read,\n [Type.Int16]: int16Coder.$read,\n [Type.Int32]: int32Coder.$read,\n [Type.Float64]: float64Coder.$read,\n [Type.Float32]: float32Coder.$read,\n [Type.Float16]: float16Coder.$read,\n [Type.BFloat16]: bfloat16Coder.$read,\n [Type.Scalar8]: scalar8Coder.$read,\n [Type.UScalar8]: uscalar8Coder.$read,\n [Type.Bool]: boolCoder.$read,\n [Type.Bools]: boolsCoder.$read,\n [Type.Buffer]: bufferCoder.$read,\n [Type.String]: stringCoder.$read,\n [Type.JSON]: jsonCoder.$read,\n [Type.RegExp]: regexCoder.$read,\n [Type.Date]: dateCoder.$read,\n};\n","/** Default maximum transmission unit in networking */\nconst MTU = 1500;\n\n/** Set Tinybuf global config */\nexport const setTinybufConfig = (c: Partial): void => {\n cfg = { ...cfg, ...c };\n};\n\nexport type TinybufConfig = {\n /**\n * (default: false)\n *\n * This sets the default value for `preserveBytes` on\n * `encode(data, preserveBytes?)`.\n *\n * By default, `encode()` returns its encoded bytes as a `Uint8Array`\n * view of the bytes in the shared encoding buffer.\n *\n * This is suitable for synchronous use (e.g. high-performance applications)\n * as it avoids slow and expensive memory allocation and fragmentation on\n * each call to `encode()`.\n *\n * However, susbsequent calls are destructive to the underlying bytes, so\n * for asynchronous uses (e.g. Promises, Workers, long-lived storage), set\n * `preserveBytes` to `true`.\n */\n safe: boolean,\n\n /**\n * (default: true)\n * By default, format encoders share a global encoding buffer for performance\n * and memory management reasons.\n *\n * When set to false, each format is allocated an individual encoding buffer.\n *\n * Enable to maximise performance and memory re-use, just be cautious of\n * possible race conditions.\n */\n useGlobalEncodingBuffer: boolean,\n\n /**\n * (default: 1500)\n * The maximum bytes that can be allocated to an encoding buffer.\n *\n * Default is 1500 bytes, the standard \"Maximum Transmission Unit\".\n */\n encodingBufferMaxSize: number,\n\n /**\n * (default: 256)\n * Initial bytes to allocate for an encoding buffer.\n */\n encodingBufferInitialSize: number,\n\n /**\n * (default: 256)\n * Additional bytes to allocated when dynamically increasing the size of an encoding buffer.\n */\n encodingBufferIncrement: number,\n};\n\n/** @internal */\nexport let cfg: TinybufConfig = {\n safe: false,\n useGlobalEncodingBuffer: true,\n encodingBufferMaxSize: MTU,\n encodingBufferInitialSize: 256,\n encodingBufferIncrement: 256,\n};\n","import { cfg } from \"../config\";\nimport { TinybufError } from \"./errors\";\n\n/**\n * Wraps a buffer with a write head pointer.\n *\n * @internal\n */\nexport class BufferWriter {\n public $byteLength: number = 0;\n public _$dataView: DataView;\n private _$writeHead: number = 0;\n\n public constructor(initialSize: number) {\n this._$dataView = new DataView(new ArrayBuffer(initialSize));\n }\n\n public $viewBytes(): Uint8Array {\n return new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset, this.$byteLength);\n }\n\n public $copyBytes(): Uint8Array {\n return new Uint8Array(this._$dataView.buffer.slice(0, this.$byteLength));\n }\n\n // ----- Writers: -----\n\n public $writeInt8(value: number): void {\n this._$alloc(1).setInt8(this._$writeHead, value);\n }\n\n public $writeInt16(value: number): void {\n this._$alloc(2).setInt16(this._$writeHead, value, true);\n }\n\n public $writeInt32(value: number): void {\n this._$alloc(4).setInt32(this._$writeHead, value, true);\n }\n\n public $writeUint8(value: number): void {\n this._$alloc(1).setUint8(this._$writeHead, value);\n }\n\n public $writeUint16(value: number): void {\n this._$alloc(2).setUint16(this._$writeHead, value, false); // big-endian for varint\n }\n\n public $writeUint32(value: number): void {\n this._$alloc(4).setUint32(this._$writeHead, value, false); // big-endian for varint\n }\n\n public $writeFloat32(value: number): void {\n this._$alloc(4).setFloat32(this._$writeHead, value, true);\n }\n\n public $writeFloat64(value: number): void {\n this._$alloc(8).setFloat64(this._$writeHead, value, true);\n }\n\n public $writeBytes(b: Uint8Array | ArrayBuffer | ArrayBufferView): void {\n // allocate bytes first\n this._$alloc(b.byteLength);\n\n let bBytes: Uint8Array = ArrayBuffer.isView(b)\n ? b instanceof Uint8Array\n ? b\n : new Uint8Array(b.buffer, b.byteOffset, b.byteLength)\n : new Uint8Array(b);\n\n // copy bytes\n new Uint8Array(\n this._$dataView.buffer,\n this._$dataView.byteOffset + this._$writeHead,\n b.byteLength\n ).set(bBytes);\n }\n\n // ----- Private methods: -----\n\n private _$alloc(bytes: number): DataView {\n if (this.$byteLength + bytes > this._$dataView.byteLength) {\n const minBytesNeeded = this.$byteLength + bytes - this._$dataView.byteLength;\n const requestedNewBytes = Math.ceil(minBytesNeeded / cfg.encodingBufferIncrement) * cfg.encodingBufferIncrement;\n this._$resizeBuffer(this._$dataView.byteLength + requestedNewBytes);\n }\n\n this._$writeHead = this.$byteLength;\n this.$byteLength += bytes;\n\n return this._$dataView;\n }\n\n private _$resizeBuffer(newSize: number): void {\n if (newSize > cfg.encodingBufferMaxSize) {\n // safety check\n throw new TinybufError(`exceeded encodingBufferMaxSize: ${cfg.encodingBufferMaxSize}`);\n }\n\n const newBuf = new ArrayBuffer(newSize);\n\n // copy bytes\n const oldView = new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset, this._$dataView.byteLength);\n new Uint8Array(newBuf).set(oldView);\n\n // update ref\n this._$dataView = new DataView(newBuf);\n }\n}\n","/**\n * Wraps a buffer with a read head pointer.\n *\n * @internal\n */\nexport class BufferReader {\n public i: number;\n private _$dataView: DataView;\n\n public constructor(b: Uint8Array | ArrayBufferView | ArrayBuffer, headerBytes?: number) {\n this._$dataView = ArrayBuffer.isView(b)\n ? new DataView(b.buffer, b.byteOffset, b.byteLength)\n : new DataView(b);\n\n this.i = headerBytes ?? 0; // internal offset (header)\n }\n\n /** Read the next byte, without moving the read head pointer. */\n public $peek(): number {\n return this._$dataView.getUint8(this.i);\n }\n\n /** Skip the next byte without reading it. */\n public $skip(): void {\n this.i++;\n }\n\n // ----- Readers: -----\n\n public $readUint8(): number {\n return this._$dataView.getUint8(this.i++);\n }\n\n public $readUint16(): number {\n const r = this._$dataView.getUint16(this.i); // big-endian\n this.i += 2;\n return r;\n }\n\n public $readUint32(): number {\n const r = this._$dataView.getUint32(this.i); // big-endian\n this.i += 4;\n return r;\n }\n\n public $readInt8(): number {\n return this._$dataView.getInt8(this.i++);\n }\n\n public $readInt16(): number {\n const r = this._$dataView.getInt16(this.i, true); // little-endian\n this.i += 2;\n return r;\n }\n\n public $readInt32(): number {\n const r = this._$dataView.getInt32(this.i, true); // little-endian\n this.i += 4;\n return r;\n }\n\n public $readFloat32(): number {\n const r = this._$dataView.getFloat32(this.i, true); // little-endian\n this.i += 4;\n return r;\n }\n\n public $readFloat64(): number {\n const r = this._$dataView.getFloat64(this.i, true); // little-endian\n this.i += 8;\n return r;\n }\n\n /** @throws RangeError if exceeds length */\n public $readBytes(bytes: number): Uint8Array {\n if (this._$dataView.byteOffset + this.i + bytes > this._$dataView.byteLength) {\n throw new RangeError(\"exceeded bytes\");\n }\n\n const view = new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset + this.i, bytes);\n this.i += bytes;\n\n return view;\n }\n}\n","import { writers, readers } from \"./lib/coders\";\nimport * as coders from \"./lib/coders\";\nimport { $hashCode, $strToHashCode } from \"./lib/hashCode\";\nimport { peekHeader, peekHeaderStr } from \"./lib/peek\";\nimport { BufferWriter } from \"./lib/BufferWriter\";\nimport { BufferReader } from \"./lib/BufferReader\";\nimport {\n DecodedType,\n EncoderDefinition,\n FieldDefinition,\n TransformConfig,\n ValidationConfig,\n MaybeType,\n Transforms,\n TypeLiteral,\n ValidationFn,\n ValidTypes,\n} from \"./Type\";\nimport { cfg } from \"./config\";\n\nexport type FormatHeader = string | number;\n\n/**\n * Utility to get the decoded type of a buffer format\n * @example type Format = Decoded\n */\nexport type Decoded = TBufferFormat extends BufferFormat\n ? DecodedType\n : never;\n\n/**\n * Defines a format for encoding/decoding binary buffers.\n *\n * Optionally customize the identifier, either as a 2-byte string, an unsigned integer (0 -> 65,535), or as `null` to disable entirely.\n *\n * @example\n * const MyFormat = defineFormat({ ... });\n * const MyFormat = defineFormat('ab', { ... });\n * const MyFormat = defineFormat(1234, { ... });\n * const MyFormat = defineFormat(null, { ... });\n */\nexport function defineFormat(def: T): BufferFormat;\n/**\n * Defines a format for encoding/decoding binary buffers.\n *\n * Optionally customize the identifier, either as a 2-byte string, an unsigned integer (0 -> 65,535), or as `null` to disable entirely.\n *\n * @example\n * const MyFormat = defineFormat({ ... });\n * const MyFormat = defineFormat('ab', { ... });\n * const MyFormat = defineFormat(1234, { ... });\n * const MyFormat = defineFormat(null, { ... });\n */\nexport function defineFormat(h: HeaderType | null, def: T): BufferFormat;\nexport function defineFormat(a?: HeaderType | T, b?: T): BufferFormat {\n return a !== null && typeof a === \"object\"\n ? new BufferFormat(a as T)\n : new BufferFormat(b as T, a as HeaderType);\n}\n\nfunction isValidHeader(h: FormatHeader): boolean {\n if (typeof h === \"number\") return Number.isInteger(h) && h >= 0 && h <= 65_535;\n if (typeof h === \"string\") return new TextEncoder().encode(h).byteLength === 2;\n return false;\n}\n\n/**\n * BufferFormat is a utility class for encoding and decoding binary data based\n * on a provided encoding format.\n *\n * @see {header}\n * @see {encode(data)}\n * @see {decode(binary)}\n */\nexport class BufferFormat {\n /** @internal */\n private static _$globalWriter?: BufferWriter;\n\n /**\n * A unique identifier encoded as the first 2 bytes (or `undefined` if headerless).\n *\n * @see {peekHeader(...)}\n * @see {peekHeaderStr(...)}\n */\n public header!: HeaderType;\n\n /** @internal */\n private _$header!: number; // always uint16 vesion\n /** @internal */\n private _$type!: TypeLiteral;\n /** @internal */\n private _$fields!: Field[];\n /** @internal */\n private _$fieldsMap!: Map;\n\n /** @internal */\n private _$format?: string;\n /** @internal */\n private _$transforms?: Transforms | undefined;\n /** @internal */\n private _$validate?: ValidationFn | undefined;\n /** @internal */\n private _$hasValidationOrTransforms = false;\n /** @internal */\n private _$writer?: BufferWriter;\n\n public get encodingBuffer(): DataView | undefined {\n return this._$writer?._$dataView;\n }\n\n public constructor(\n def: EncoderType,\n header?: HeaderType | null,\n ) {\n // set definition\n if (typeof def === \"string\" && ValidTypes.includes(def)) {\n this._$type = def;\n }\n else if (def instanceof MaybeType) {\n throw new TypeError(\"Format cannot be optional\");\n }\n else if (def instanceof Object) {\n this._$type = undefined; // object\n this._$fieldsMap = new Map();\n this._$fields = Object.keys(def).map((name) => {\n const f = new Field(name, def[name]);\n this._$fieldsMap.set(name, f); // also set map entry\n return f;\n });\n\n // set headers\n if (header === undefined) {\n this.header = $hashCode(this.f) as HeaderType; // automatic\n this._$header = this.header as number;\n }\n else if (header === null) {\n this.header = undefined; // headerless\n this._$header = undefined;\n }\n else if (isValidHeader(header)) {\n this.header = header; // manual\n this._$header = typeof header === \"number\" ? header : $strToHashCode(header);\n }\n else {\n throw new TypeError(\"Header must be 2-byte string, uint16, or null.\");\n }\n }\n else {\n throw new TypeError(\"Format must be object or Type\");\n }\n }\n\n // ----- Static methods: -----\n\n /**\n * Read the header of a buffer as a number.\n *\n * @see {header}\n * @throws {RangeError} if buffer size < 2\n */\n public static peekHeader = peekHeader;\n\n /**\n * Read the header of a buffer as a string.\n *\n * @see {header}\n * @throws {RangeError} if buffer size < 2\n */\n public static peekHeaderStr = peekHeaderStr;\n\n // ----- Accessors: -----\n\n /**\n * @example \"{uint8,str[]?}\"\n * @internal\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private get f(): string {\n if (this._$format === undefined) {\n this._$format = this._$fields !== undefined\n ? `{${this._$fields.map(v => v.f).join(\",\")}}`\n : `${this._$type}`;\n }\n\n return this._$format;\n }\n\n /** @internal */\n private static _$initWriter(): BufferWriter {\n if (cfg.useGlobalEncodingBuffer) {\n if (!BufferFormat._$globalWriter) {\n // lazy init: global encoding buffer created at max size\n this._$globalWriter = new BufferWriter(cfg.encodingBufferInitialSize);\n }\n\n return this._$globalWriter;\n }\n\n return new BufferWriter(cfg.encodingBufferInitialSize);\n }\n\n /**\n * Encode an object to bytes.\n *\n * **Warning:** Returns an unsafe view into the encoding buffer. Pass this reference to preserve\n * performance, and to minimize memory allocation and fragmentation.\n *\n * @param data - data to encode\n * @param preserveBytes - (default: `setTinybufConfig().safe`) When set to true, copies encoded\n * bytes to a new buffer. When set to false, returns an unsafe view of bytes but prevents\n * unnnecessary memory allocation and fragmentation.\n *\n * @returns a copy of encoded bytes\n * @throws if fails to encode value to schema\n */\n public encode>(\n data: TDecodedType,\n preserveBytes?: boolean,\n ): Uint8Array {\n if (!this._$writer) {\n // lazy init\n this._$writer = BufferFormat._$initWriter();\n }\n\n // reset\n this._$writer.$byteLength = 0;\n\n if (this._$hasValidationOrTransforms) {\n data = this._$preprocess(data);\n }\n\n this._$write(data, this._$writer);\n\n return (preserveBytes ?? cfg.safe)\n ? this._$writer.$copyBytes()\n : this._$writer.$viewBytes();\n }\n\n /**\n * Decode binary data to an object.\n * @throws if fails to decode bytes to schema.\n */\n public decode>(\n bytes: Uint8Array | ArrayBufferView | ArrayBuffer,\n decodeInto?: Partial,\n ): TDecodedType {\n return this._$read(new BufferReader(bytes, this.header === undefined ? 0 : 2), decodeInto);\n }\n\n /**\n * Set additional transform functions to apply before encoding and after decoding.\n */\n public setTransforms(transforms: TransformConfig | Transforms): this {\n this._$hasValidationOrTransforms = true;\n\n if (typeof transforms === \"function\" || (Array.isArray(transforms) && typeof transforms[0] === \"function\")) {\n this._$transforms = transforms;\n }\n else {\n for (const name of Object.keys(transforms)) {\n const field = this._$fieldsMap.get(name);\n if (!field) {\n throw new TypeError(`Failed to set transforms for field '${name}'`);\n }\n\n // Set validation for object.\n field.$coder.setTransforms(transforms[name]);\n }\n }\n\n return this;\n }\n\n /**\n * Set additional validation rules which are applied on encode() and decode().\n *\n * - Validation functions should throw an error, return an error, or return boolean false.\n * - Anything else is treated as successfully passing validation.\n */\n public setValidation(validations: ValidationConfig | ValidationFn): this {\n this._$hasValidationOrTransforms = true;\n\n if (typeof validations === \"function\") {\n this._$validate = validations;\n }\n else {\n for (const name of Object.keys(validations)) {\n const field = this._$fieldsMap.get(name);\n if (!field) {\n throw new TypeError(`Failed to set validation function for field '${name}'`);\n }\n\n field.$coder.setValidation(validations[name]);\n }\n }\n\n return this;\n }\n\n // ----- Implementation: -----\n\n /**\n * @param value\n * @param bw\n * @throws if the value is invalid\n *\n * @internal\n */\n private _$write(value: any, bw: BufferWriter): void {\n // write header\n if (this._$header !== undefined) bw.$writeUint16(this._$header);\n\n // write scalar\n if (this._$type !== undefined) {\n const safeValue = (this._$validate || this._$transforms) ? this._$preprocess(value) : value;\n\n return writers[this._$type](safeValue, bw);\n }\n\n // check for object type\n if (typeof value !== \"object\" || !value) {\n throw new TypeError(\"expected object type\");\n }\n\n // write each field\n for (const field of this._$fields) {\n const subValue = value[field.$name];\n\n if (field.$isOptional) {\n if (subValue === undefined || subValue === null) {\n coders.boolCoder.$write(false, bw);\n continue; // skip\n }\n else {\n coders.boolCoder.$write(true, bw);\n }\n }\n else if (subValue == null) {\n throw new Error(`missing required value: ${field.$name}`);\n }\n\n if (field.$isArray) {\n // array\n this._$writeArray(subValue, bw, field.$coder);\n continue;\n }\n\n // scalar/object field\n field.$coder._$write(subValue, bw);\n }\n }\n\n /**\n * pre-process: validation and/or transforms\n * @internal\n */\n private _$preprocess>(data: T): T {\n if (this._$validate) this._$processValidation(data);\n\n if (typeof this._$transforms === \"function\") {\n return this._$transforms(data);\n }\n else if (Array.isArray(this._$transforms) && typeof this._$transforms[0] === \"function\") {\n return this._$transforms[0](data);\n }\n\n return data;\n }\n\n /**\n * post-process: validation and/or transforms\n * @internal\n */\n private _$postprocess>(data: T): T {\n if (Array.isArray(this._$transforms) && typeof this._$transforms[1] === \"function\") {\n data = this._$transforms[1](data);\n }\n\n if (this._$validate) this._$processValidation(data);\n\n return data;\n }\n\n private _$processValidation(data: any): void {\n if (!this._$validate) return;\n const res = this._$validate(data);\n if (res instanceof Error) throw res;\n if (res === false) throw new Error(\"failed validation\");\n }\n\n /**\n * This function will be executed only the first time\n * After that, we'll compile the read routine and add it directly to the instance\n * @param state\n * @returns\n * @throws if fails\n *\n * @internal\n */\n private _$read>(state: BufferReader, obj?: Partial): TDecodedType {\n // This function will be executed only the first time to compile the read routine.\n // After that, we'll compile the read routine and add it directly to the instance\n\n // Update the read method implementation.\n this._$read = this._$compileFormatReadFn();\n\n return this._$read(state, obj);\n }\n\n /**\n * Generate read function code for this coder.\n *\n * @example\n * let v=o??{};\n * v.prop1=this._$readField(0,s,o);\n * v.prop2=this._$readField(1,s,o);\n * return v\n *\n * @internal\n */\n private _$makeObjectReadFnBody(): string {\n const fieldsStr: string = this._$fields\n .map(({ $name: n }, i) => `v.${n}=this.${this._$readField.name}(${i},s,v.${n})`)\n .join(\";\");\n\n return `let v=o??{};${fieldsStr};return v;`;\n }\n\n /**\n * Read an individual field.\n * @internal\n */\n private _$readField(fieldIndex: number, state: BufferReader, obj?: any): any {\n const field = this._$fields[fieldIndex];\n\n if (field.$isOptional && !coders.boolCoder.$read(state)) {\n return undefined;\n }\n\n if (field.$isArray) {\n return this._$readArray(field.$coder, state, obj);\n }\n\n return field.$coder._$read(state, obj);\n }\n\n /**\n * Compile the decode() method for this object.\n *\n * @internal\n */\n private _$compileFormatReadFn>(): (state: BufferReader, obj: Partial | undefined) => TDecodedType {\n if (this._$type !== undefined) {\n // scalar type\n return this._$hasValidationOrTransforms\n ? (s) => this._$postprocess(readers[this._$type](s))\n : readers[this._$type];\n }\n\n // object type\n return new Function(\"s\", \"o\", this._$makeObjectReadFnBody()) as any;\n }\n\n /**\n * @internal\n */\n private _$writeArray(value: any[], bw: BufferWriter, type: BufferFormat): void {\n if (!Array.isArray(value)) {\n throw new TypeError(`expected array, instead got: ${value}`);\n }\n\n coders.uintCoder.$write(value.length, bw);\n for (let i = 0; i < value.length; i++) {\n type._$write(value[i], bw);\n }\n }\n\n /**\n * @throws if invalid data\n * @internal\n */\n private _$readArray(type: BufferFormat, state: any, obj?: Array): Array {\n const len = coders.uintCoder.$read(state);\n const arr = obj?.length === len ? obj : new Array(len);\n for (let j = 0; j < arr.length; j++) {\n arr[j] = type._$read(state, obj?.[j]);\n }\n return arr;\n }\n}\n\n/**\n * Parses and represents an object field.\n *\n * @internal\n */\nclass Field {\n public $name: string;\n public $coder: BufferFormat;\n public $isOptional: boolean;\n public $isArray: boolean;\n\n private _$formatString?: string;\n\n public constructor(name: string, rawType: FieldDefinition) {\n this.$isOptional = rawType instanceof MaybeType;\n let type = rawType instanceof MaybeType ? rawType.type : rawType;\n\n this.$name = name;\n\n if (Array.isArray(type)) {\n if (type.length !== 1) {\n throw new TypeError(\"Array type must contain exactly one format\");\n }\n\n type = type[0];\n this.$isArray = true;\n }\n else {\n this.$isArray = false;\n }\n\n this.$coder = new BufferFormat(type, null);\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public get f(): string {\n if (this._$formatString === undefined) {\n this._$formatString = `${(this.$coder as any).f}${this.$isArray ? \"[]\" : \"\"}${this.$isOptional ? \"?\" : \"\"}`;\n }\n\n return this._$formatString;\n }\n}\n"],"names":["TinybufError","Error","$hashCode","str","hash","i","length","charCodeAt","$strToHashCode","$hashCodeToStr","hashCode","String","fromCharCode","Math","floor","peekHeader","b","ArrayBuffer","isView","DataView","buffer","byteOffset","getUint16","peekHeaderStr","BufferParser","constructor","this","_$formats","Map","_$data","processBuffer","f","data","cb","r","header","has","get","_a","decode","set","e","err","stack","on","format","callback","decodeInPlace","ignore","forEach","clear","$floor","$ceil","ceil","$clamp","value","min","max","$roundTowardZero","x","$roundAwayFromZero","$touscal8","$toscal8","$fromuscal8","$fromscal8","Type","UInt","UInt8","UInt16","UInt32","Int","Int8","Int16","Int32","Float64","Float32","Float16","BFloat16","Scalar8","UScalar8","Bool","Bools","Buffer","JSON","RegExp","Date","ValidTypes","Object","values","MaybeType","type","mask","padBit","reduce","n","unmask","l","len","undefined","clz32","Array","isArray","val","$utf8encode","encoder","TextEncoder","encode","$utf8decode","decoder","TextDecoder","y","$tof16","Float32Array","Int32Array","s","z","$fromf16","pow","d","m","Infinity","NaN","Uint32Array","MAX_VARUINT32","MAX_VARINT32","POW_32","uintCoder","$write","writer","Number","$writeUint8","$writeUint16","$writeUint32","$read","reader","firstByte","$peek","$readUint32","$readUint16","$skip","uint8Coder","$readUint8","uint16Coder","uint32Coder","intCoder","int8Coder","$writeInt8","$readInt8","int16Coder","$writeInt16","$readInt16","int32Coder","$writeInt32","$readInt32","bfloat16Coder","$tobf16","$frombf16","float16Coder","float32Coder","$writeFloat32","$readFloat32","float64Coder","$writeFloat64","$readFloat64","uscalar8Coder","scalar8Coder","dateCoder","getTime","bufferCoder","byteLength","$writeBytes","$readBytes","stringCoder","boolCoder","boolsCoder","slice","p","jsonCoder","stringify","parse","regexCoder","global","ignoreCase","multiline","source","g","writers","readers","cfg","safe","useGlobalEncodingBuffer","encodingBufferMaxSize","encodingBufferInitialSize","encodingBufferIncrement","BufferWriter","initialSize","$byteLength","_$writeHead","_$dataView","$viewBytes","Uint8Array","$copyBytes","_$alloc","setInt8","setInt16","setInt32","setUint8","setUint16","setUint32","setFloat32","setFloat64","bBytes","bytes","minBytesNeeded","requestedNewBytes","_$resizeBuffer","newSize","newBuf","oldView","BufferReader","headerBytes","getUint8","getUint32","getInt8","getInt16","getInt32","getFloat32","getFloat64","RangeError","view","BufferFormat","encodingBuffer","_$writer","def","_$hasValidationOrTransforms","includes","_$type","TypeError","_$fieldsMap","_$fields","keys","map","name","Field","_$header","isValidHeader","h","isInteger","_$format","v","join","_$initWriter","_$globalWriter","preserveBytes","_$preprocess","_$write","decodeInto","_$read","setTransforms","transforms","_$transforms","field","$coder","setValidation","validations","_$validate","bw","safeValue","subValue","$name","$isOptional","coders.boolCoder","$isArray","_$writeArray","_$processValidation","_$postprocess","res","state","obj","_$compileFormatReadFn","_$makeObjectReadFnBody","fieldsStr","_$readField","fieldIndex","_$readArray","Function","coders.uintCoder","arr","j","rawType","_$formatString","bf16round","defineFormat","a","f16round","optional","t","scalround","c","assign","uscalround"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index 3514729..5f04703 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -115,6 +115,10 @@ export type ValueTypes = { [Type.RegExp]: RegExp; [Type.Date]: Date; }; +/** https://www.totaltypescript.com/concepts/the-prettify-helper */ +export type Pretty = T extends ArrayBuffer | ArrayBufferView | Date | RegExp | Uint8Array ? T : T extends Array ? Array> : T extends object ? { + [K in keyof T]: Pretty; +} & unknown : T; /** @throws any error too */ export type ValidationFn = (x: T) => undefined | boolean | Error; export type TransformFn = (x: T) => T; @@ -152,41 +156,42 @@ export type FieldDefinition = keyof ValueTypes | [ /** * The resulting type of the decoded data, based on the encoder definition. */ -export type InferredDecodedType = { +export type RawDecodedType = { [EKey in keyof EncoderType as EncoderType[EKey] extends MaybeType ? never : EKey]: EncoderType[EKey] extends keyof ValueTypes ? ValueTypes[EncoderType[EKey]] : EncoderType[EKey] extends [ keyof ValueTypes - ] ? Array : EncoderType[EKey] extends EncoderDefinition ? InferredDecodedType : EncoderType[EKey] extends [ + ] ? Array : EncoderType[EKey] extends EncoderDefinition ? RawDecodedType : EncoderType[EKey] extends [ EncoderDefinition - ] ? Array> : never; + ] ? Array> : never; } & { [EKey in keyof EncoderType as EncoderType[EKey] extends MaybeType ? EKey : never]?: EncoderType[EKey] extends MaybeType ? ValueTypes[OptionalValue] | undefined : EncoderType[EKey] extends MaybeType ? Array | undefined : EncoderType[EKey] extends MaybeType ? InferredDecodedType | undefined : never; + ]> ? Array | undefined : EncoderType[EKey] extends MaybeType ? RawDecodedType | undefined : never; }; -export type InferredTransformConfig = { +export type DecodedType = Pretty>; +export type TransformConfig = { [EKey in keyof EncoderType]?: EncoderType[EKey] extends keyof ValueTypes ? Transforms : EncoderType[EKey] extends [ keyof ValueTypes - ] ? Transforms : EncoderType[EKey] extends EncoderDefinition ? InferredTransformConfig : EncoderType[EKey] extends [ + ] ? Transforms : EncoderType[EKey] extends EncoderDefinition ? TransformConfig : EncoderType[EKey] extends [ EncoderDefinition - ] ? InferredTransformConfig : EncoderType[EKey] extends MaybeType ? Transforms : EncoderType[EKey] extends MaybeType : EncoderType[EKey] extends MaybeType ? Transforms : EncoderType[EKey] extends MaybeType ? Transforms : EncoderType[EKey] extends MaybeType ? InferredTransformConfig | undefined : never; + ]> ? Transforms : EncoderType[EKey] extends MaybeType ? TransformConfig | undefined : never; }; -export type InferredValidationConfig = { +export type ValidationConfig = { [EKey in keyof EncoderType]?: EncoderType[EKey] extends keyof ValueTypes ? ValidationFn : EncoderType[EKey] extends [ keyof ValueTypes - ] ? ValidationFn : EncoderType[EKey] extends EncoderDefinition ? InferredValidationConfig : EncoderType[EKey] extends [ + ] ? ValidationFn : EncoderType[EKey] extends EncoderDefinition ? ValidationConfig : EncoderType[EKey] extends [ EncoderDefinition - ] ? InferredValidationConfig : EncoderType[EKey] extends MaybeType ? ValidationFn : EncoderType[EKey] extends MaybeType : EncoderType[EKey] extends MaybeType ? ValidationFn : EncoderType[EKey] extends MaybeType ? ValidationFn : EncoderType[EKey] extends MaybeType ? InferredValidationConfig | undefined : never; + ]> ? ValidationFn : EncoderType[EKey] extends MaybeType ? ValidationConfig | undefined : never; }; export type FormatHeader = string | number; /** - * Decoded object types for a given binary format. - * @example let onData = (data: Decoded) => {...}; + * Utility to get the decoded type of a buffer format + * @example type Format = Decoded */ -export type Decoded = FromBufferFormat extends BufferFormat ? InferredDecodedType : never; +export type Decoded = TBufferFormat extends BufferFormat ? DecodedType : never; /** * Defines a format for encoding/decoding binary buffers. * @@ -198,7 +203,7 @@ export type Decoded = FromBufferFormat extends BufferFormat(def: T): BufferFormat; +export declare function defineFormat(def: T): BufferFormat; /** * Defines a format for encoding/decoding binary buffers. * @@ -210,7 +215,7 @@ export declare function defineFormat(h: HeaderType | null, def: T): BufferFormat; +export declare function defineFormat(h: HeaderType | null, def: T): BufferFormat; /** * BufferFormat is a utility class for encoding and decoding binary data based * on a provided encoding format. @@ -257,23 +262,23 @@ export declare class BufferFormat>(data: DecodedType, preserveBytes?: boolean): Uint8Array; + encode>(data: TDecodedType, preserveBytes?: boolean): Uint8Array; /** * Decode binary data to an object. * @throws if fails to decode bytes to schema. */ - decode>(bytes: Uint8Array | ArrayBufferView | ArrayBuffer, decodeInto?: Partial): DecodedType; + decode>(bytes: Uint8Array | ArrayBufferView | ArrayBuffer, decodeInto?: Partial): TDecodedType; /** * Set additional transform functions to apply before encoding and after decoding. */ - setTransforms(transforms: InferredTransformConfig | Transforms): this; + setTransforms(transforms: TransformConfig | Transforms): this; /** * Set additional validation rules which are applied on encode() and decode(). * * - Validation functions should throw an error, return an error, or return boolean false. * - Anything else is treated as successfully passing validation. */ - setValidation(validations: InferredValidationConfig | ValidationFn): this; + setValidation(validations: ValidationConfig | ValidationFn): this; private _$processValidation; } export type AnyFormat = BufferFormat; @@ -301,7 +306,7 @@ export declare class BufferParser { /** * Register a format handler. */ - on>(format: BufferFormat, callback: (data: DecodedType) => any, { decodeInPlace, }?: { + on>(format: BufferFormat, callback: (data: TDecodedType) => any, { decodeInPlace, }?: { decodeInPlace?: boolean; }): this; /** Register a format (or formats) that are recognized. */ diff --git a/dist/index.mjs b/dist/index.mjs index 677ecf5..377d3a8 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -1,2 +1,2 @@ -class TinybufError extends Error{}function $hashCode(t){let r=5381;for(let e=0;enew BufferParser;class BufferParser{constructor(){this.t=new Map,this.o=new Map}processBuffer(t){var r;let e,i,n,s;try{const o=peekHeader(t);if(!this.t.has(o))throw new TinybufError(`Unknown format: ${o} '${$hashCodeToStr(o)}')`);[e,n,s]=this.t.get(o),s&&(i=null!==(r=this.o.get(o))&&void 0!==r?r:{}),i=e.decode(t,i),s&&this.o.set(o,i)}catch(t){const r=new TinybufError(`Failed to decode: ${t}`);throw r.stack=t.stack,r}n(i)}on(t,r,{decodeInPlace:e=!1}={}){var i;if(null==t.header)throw new TinybufError("Format requires header");const n="string"==typeof t.header?$strToHashCode(t.header):t.header;if(this.t.has(n)&&(null===(i=this.t.get(n))||void 0===i?void 0:i[0])!==t)throw new TinybufError(`Format header collision: ${t.header}`);return this.t.set(n,[t,r,e]),this}ignore(...t){return t.forEach((t=>this.on(t,(()=>{})))),this}clear(){this.t.clear(),this.o.clear()}}const t=Math.floor,r=Math.ceil,$clamp=(t,r,e)=>t>e?e:te<0?r(e):t(e),$roundAwayFromZero=e=>e<0?t(e):r(e);function uscalround(t){return $fromuscal8($touscal8(t))}function scalround(t){return $fromscal8($toscal8(t))}function $touscal8(t){return $clamp(127+$roundTowardZero(254*t-127),0,254)}function $toscal8(t){return $clamp($roundTowardZero(127*t),-127,127)+127}function $fromuscal8(t){return $clamp(.01*($roundAwayFromZero(.3937007874015748*(t-127))+50),0,1)}function $fromscal8(t){return $clamp(.01*$roundAwayFromZero(.787401574803149*(t-127)),-1,1)}const e={UInt:"uint",UInt8:"u8",UInt16:"u16",UInt32:"u32",Int:"int",Int8:"i8",Int16:"i16",Int32:"i32",Float64:"f64",Float32:"f32",Float16:"f16",BFloat16:"b16",Scalar8:"sc",UScalar8:"usc",Bool:"bl",Bools:"bls",Buffer:"buf",String:"str",JSON:"jsn",RegExp:"re",Date:"dt"},i=Object.values(e);class MaybeType{constructor(t){this.type=t}}function optional(t){return new MaybeType(t)}const mask=(t,r=1)=>t.reduce(((t,r)=>t<<1|r),r),unmask=(t,r)=>{const e=void 0===r?31-Math.clz32(t):Array.isArray(r)?r.length:r,i=Array.isArray(r)&&r.length===e?r:new Array(e);for(let r=0;rt.encode(r)}(),s=function(){const t=new TextDecoder("utf-8");return r=>t.decode(r)}();function f16round(t){return a(o(t))}const o=function(){const t=new Float32Array(1),r=new Int32Array(t.buffer);return function(e){t[0]=e;let i=r[0],n=i>>16&32768,s=4096+(2147483647&i)|0;return s>=1199570944?(2147483647&i)<1199570944?31743|n:s<2139095040?31744|n:31744|n|(8388607&i)>>13:s>=947912704?n|s-939524096>>13:s<855638016?n:(s=(2147483647&i)>>23,n|(8388607&i|8388608)+(8388608>>>s-102)>>126-s)}}(),a=function(){const t=Math.pow(2,-24),r=new Float32Array(1056);for(let t=0;t<32;t++)r[t]=Math.pow(2,t-15);for(let t=0;t<1024;t++)r[t+32]=1+t/1024;return function(e){const i=32768&~e?1:-1,n=31744&e,s=1023&e;return 0===n?0===s?0*i:i*t:31744===n?0===s?i*(1/0):NaN:r[n>>10]*r[s+32]*i}}(),h=new Uint32Array(1),f=new Float32Array(h.buffer);function bf16round(t){return f[0]=t,h[0]=4294901760&h[0],f[0]}const u=536870912,c=268435456,d=4294967296,$={h:(r,e)=>{"number"!=typeof r&&(r=Number(r)),r<0&&(r=0),r<128?e.u(r):r<16384?e.$(r+32768):r=u?(e.l(t(r/d)+3758096384),e.l(r>>>0)):e.u(!0===r?1:0)},p:t=>{const r=t.m();return 128&r?64&r?32&r?(t.B()-3758096384)*d+t.B():t.B()-3221225472:t.F()-32768:(t.v(),r)}},l={h:(t,r)=>r.u(t),p:t=>t.A()},w={h:(t,r)=>r.$(t),p:t=>t.F()},y={h:(t,r)=>r.l(t),p:t=>t.B()},p={h:(r,e)=>{"number"!=typeof r&&(r=Number(r)),r>=-64&&r<64?e.u(127&r):r>=-8192&&r<8192?e.$(32768+(16383&r)):r>=-268435456&&r=c?(e.l(3758096384+(536870911&t(r/d))),e.l(r>>>0)):e.u(!0===r?127:0)},p:t=>{let r,e=t.m();return 128&e?64&e?32&e?(r=t.B()-3758096384,r=268435456&r?3758096384|r:r,r*d+t.B()):(r=t.B()-3221225472,268435456&r?3758096384|r:r):(r=t.F()-32768,8192&r?4294950912|r:r):(t.v(),64&e?4294967168|e:e)}},b={h:(t,r)=>r.T(t),p:t=>t.U()},m={h:(t,r)=>r.I(t),p:t=>t.S()},B={h:(t,r)=>r.M(t),p:t=>t.j()},F={h:(t,r)=>r.$(function $tobf16(t){return f[0]=t,h[0]>>>16}(t)),p:t=>function $frombf16(t){return h[0]=t<<16,f[0]}(t.F())},v={h:(t,r)=>r.$(o(t)),p:t=>a(t.F())},A={h:(t,r)=>r.H(t),p:t=>t._()},T={h:(t,r)=>r.k(t),p:t=>t.O()},E={h:(t,r)=>r.u($touscal8(t)),p:t=>$fromuscal8(t.A())},g={h:(t,r)=>r.u($toscal8(t)),p:t=>$fromscal8(t.A())},U={h:(t,r)=>p.h(t.getTime(),r),p:t=>new Date(p.p(t))},I={h:(t,r)=>{$.h(t.byteLength,r),r.C(t)},p:t=>t.D($.p(t))},S={h:(t,r)=>I.h(n(t),r),p:t=>s(I.p(t))},M={h:(t,r)=>r.u(t?1:0),p:t=>0!==t.A()},x={h:(t,r)=>{t.length>28&&(t=t.slice(0,28)),$.h(mask(t),r)},p:(t,r)=>unmask($.p(t),r)},j={h:(t,r)=>S.h(JSON.stringify(t),r),p:t=>JSON.parse(S.p(t))},H={h:(t,r)=>{r.u(mask([t.global,t.ignoreCase,t.multiline])),S.h(t.source,r)},p:t=>{const[r,e,i]=unmask(t.A());return new RegExp(S.p(t),(r?"g":"")+(e?"i":"")+(i?"m":""))}},_={[e.UInt]:$.h,[e.UInt8]:l.h,[e.UInt16]:w.h,[e.UInt32]:y.h,[e.Int]:p.h,[e.Int8]:b.h,[e.Int16]:m.h,[e.Int32]:B.h,[e.Float64]:T.h,[e.Float32]:A.h,[e.Float16]:v.h,[e.BFloat16]:F.h,[e.Scalar8]:g.h,[e.UScalar8]:E.h,[e.Bool]:M.h,[e.Bools]:x.h,[e.Buffer]:I.h,[e.String]:S.h,[e.JSON]:j.h,[e.RegExp]:H.h,[e.Date]:U.h},k={[e.UInt]:$.p,[e.UInt8]:l.p,[e.UInt16]:w.p,[e.UInt32]:y.p,[e.Int]:p.p,[e.Int8]:b.p,[e.Int16]:m.p,[e.Int32]:B.p,[e.Float64]:T.p,[e.Float32]:A.p,[e.Float16]:v.p,[e.BFloat16]:F.p,[e.Scalar8]:g.p,[e.UScalar8]:E.p,[e.Bool]:M.p,[e.Bools]:x.p,[e.Buffer]:I.p,[e.String]:S.p,[e.JSON]:j.p,[e.RegExp]:H.p,[e.Date]:U.p},setTinybufConfig=t=>{O=Object.assign(Object.assign({},O),t)};let O={safe:!1,useGlobalEncodingBuffer:!0,encodingBufferMaxSize:1500,encodingBufferInitialSize:256,encodingBufferIncrement:256};class BufferWriter{constructor(t){this.i=0,this.N=new DataView(new ArrayBuffer(t))}V(){return new Uint8Array(this.N.buffer,this.N.byteOffset,this.i)}R(){return new Uint8Array(this.N.buffer.slice(0,this.i))}T(t){this.N.setInt8(this.J(1),t)}I(t){this.N.setInt16(this.J(2),t,!0)}M(t){this.N.setInt32(this.J(4),t,!0)}u(t){this.N.setUint8(this.J(1),t)}$(t){this.N.setUint16(this.J(2),t,!1)}l(t){this.N.setUint32(this.J(4),t,!1)}H(t){this.N.setFloat32(this.J(4),t,!0)}k(t){this.N.setFloat64(this.J(8),t,!0)}C(t){const r=this.J(t.byteLength);let e=ArrayBuffer.isView(t)?t instanceof Uint8Array?t:new Uint8Array(t.buffer,t.byteOffset,t.byteLength):new Uint8Array(t);new Uint8Array(this.N.buffer,this.N.byteOffset+r,t.byteLength).set(e)}J(t){if(this.i+t>this.N.byteLength){const r=this.i+t-this.N.byteLength,e=Math.ceil(r/O.encodingBufferIncrement)*O.encodingBufferIncrement;this.W(this.N.byteLength+e)}const r=this.i;return this.i+=t,r}W(t){if(t>O.encodingBufferMaxSize)throw new TinybufError(`exceeded encodingBufferMaxSize: ${O.encodingBufferMaxSize}`);const r=new ArrayBuffer(t),e=new Uint8Array(this.N.buffer,this.N.byteOffset,this.N.byteLength);new Uint8Array(r).set(e),this.N=new DataView(r)}}class BufferReader{constructor(t,r){this.N=ArrayBuffer.isView(t)?new DataView(t.buffer,t.byteOffset,t.byteLength):new DataView(t),this.i=null!=r?r:0}m(){return this.N.getUint8(this.i)}v(){this.i++}A(){return this.N.getUint8(this.i++)}F(){const t=this.N.getUint16(this.i);return this.i+=2,t}B(){const t=this.N.getUint32(this.i);return this.i+=4,t}U(){return this.N.getInt8(this.i++)}S(){const t=this.N.getInt16(this.i,!0);return this.i+=2,t}j(){const t=this.N.getInt32(this.i,!0);return this.i+=4,t}_(){const t=this.N.getFloat32(this.i,!0);return this.i+=4,t}O(){const t=this.N.getFloat64(this.i,!0);return this.i+=8,t}D(t){if(this.N.byteOffset+this.i+t>this.N.byteLength)throw new RangeError("exceeded bytes");const r=new Uint8Array(this.N.buffer,this.N.byteOffset+this.i,t);return this.i+=t,r}}function defineFormat(t,r){return null!==t&&"object"==typeof t?new BufferFormat(t):new BufferFormat(r,t)}class BufferFormat{get encodingBuffer(){var t;return null===(t=this.P)||void 0===t?void 0:t.N}constructor(t,r){if(this.q=!1,"string"==typeof t&&i.includes(t))this.G=t;else{if(t instanceof MaybeType)throw new TypeError("Format cannot be optional");if(!(t instanceof Object))throw new TypeError(`Format must be object or Type: ${JSON.stringify(t)} ${typeof t} ${i[t]}`);if(this.G=void 0,this.K=new Map,this.L=Object.keys(t).map((r=>{const e=new Field(r,t[r]);return this.K.set(r,e),e})),void 0===r)this.header=$hashCode(this.f),this.X=this.header;else if(null===r)this.header=void 0,this.X=void 0;else{if(!function isValidHeader(t){return"number"==typeof t?Number.isInteger(t)&&t>=0&&t<=65535:"string"==typeof t&&2===(new TextEncoder).encode(t).byteLength}(r))throw new TypeError(`Header must be uint16, 2 byte string, or null. Received: ${r}`);this.header=r,this.X="number"==typeof r?r:$strToHashCode(r)}}}get f(){return void 0===this.Y&&(this.Y=void 0!==this.L?`{${this.L.map((t=>t.f)).join(",")}}`:`${this.G}`),this.Y}static Z(){return O.useGlobalEncodingBuffer?(BufferFormat.tt||(this.tt=new BufferWriter(O.encodingBufferInitialSize)),this.tt):new BufferWriter(O.encodingBufferInitialSize)}encode(t,r){return this.P||(this.P=BufferFormat.Z()),this.P.i=0,this.q&&(t=this.rt(t)),this.et(t,this.P),(null!=r?r:O.safe)?this.P.R():this.P.V()}decode(t,r){return this.it(new BufferReader(t,void 0===this.header?0:2),r)}setTransforms(t){if(this.q=!0,"function"==typeof t||Array.isArray(t)&&"function"==typeof t[0])this.nt=t;else for(const r of Object.keys(t)){const e=this.K.get(r);if(!e)throw new TypeError(`Failed to set transforms for field '${r}'`);e.st.setTransforms(t[r])}return this}setValidation(t){if(this.q=!0,"function"==typeof t)this.ot=t;else for(const r of Object.keys(t)){const e=this.K.get(r);if(!e)throw new TypeError(`Failed to set validation function for field '${r}'`);e.st.setValidation(t[r])}return this}et(t,r){if(void 0!==this.X&&r.$(this.X),void 0!==this.G){const e=this.ot||this.nt?this.rt(t):t;return _[this.G](e,r)}if("object"!=typeof t||!t)throw new TypeError("expected object type");for(const e of this.L){const i=t[e.ht];if(e.ft){if(null==i){M.h(!1,r);continue}M.h(!0,r)}else if(null==i)throw new Error(`missing required value: ${e.ht}`);e.ut?this.ct(i,r,e.st):e.st.et(i,r)}}rt(t){return this.ot&&this.dt(t),"function"==typeof this.nt?this.nt(t):Array.isArray(this.nt)&&"function"==typeof this.nt[0]?this.nt[0](t):t}$t(t){return Array.isArray(this.nt)&&"function"==typeof this.nt[1]&&(t=this.nt[1](t)),this.ot&&this.dt(t),t}dt(t){if(!this.ot)return;const r=this.ot(t);if(r instanceof Error)throw r;if(!1===r)throw new Error("failed validation")}it(t,r){return this.it=this.lt(),this.it(t,r)}wt(){const t=this.L.map((({ht:t},r)=>`v.${t}=this.${this.yt.name}(${r},s,v.${t})`)).join(";");return`let v=o??{};${t};return v;`}yt(t,r,e){const i=this.L[t];if(!i.ft||M.p(r))return i.ut?this.bt(i.st,r,e):i.st.it(r,e)}lt(){return void 0!==this.G?this.q?t=>this.$t(k[this.G](t)):k[this.G]:new Function("s","o",this.wt())}ct(t,r,e){if(!Array.isArray(t))throw new TypeError(`expected array, instead got: ${t}`);$.h(t.length,r);for(let i=0;inew BufferParser;class BufferParser{constructor(){this.t=new Map,this.o=new Map}processBuffer(t){var r;let e,i,n,s;try{const o=peekHeader(t);if(!this.t.has(o))throw new TinybufError(`Unknown format: ${o} '${$hashCodeToStr(o)}')`);[e,n,s]=this.t.get(o),s&&(i=null!==(r=this.o.get(o))&&void 0!==r?r:{}),i=e.decode(t,i),s&&this.o.set(o,i)}catch(t){const r=new TinybufError(`Failed to decode: ${t}`);throw r.stack=t.stack,r}n(i)}on(t,r,{decodeInPlace:e=!1}={}){var i;if(null==t.header)throw new TinybufError("Format requires header");const n="string"==typeof t.header?$strToHashCode(t.header):t.header;if(this.t.has(n)&&(null===(i=this.t.get(n))||void 0===i?void 0:i[0])!==t)throw new TinybufError(`Format header collision: ${t.header}`);return this.t.set(n,[t,r,e]),this}ignore(...t){return t.forEach((t=>this.on(t,(()=>{})))),this}clear(){this.t.clear(),this.o.clear()}}const t=Math.floor,r=Math.ceil,$clamp=(t,r,e)=>t>e?e:te<0?r(e):t(e),$roundAwayFromZero=e=>e<0?t(e):r(e);function uscalround(t){return $fromuscal8($touscal8(t))}function scalround(t){return $fromscal8($toscal8(t))}function $touscal8(t){return $clamp(127+$roundTowardZero(254*t-127),0,254)}function $toscal8(t){return $clamp($roundTowardZero(127*t),-127,127)+127}function $fromuscal8(t){return $clamp(.01*($roundAwayFromZero(.3937007874015748*(t-127))+50),0,1)}function $fromscal8(t){return $clamp(.01*$roundAwayFromZero(.787401574803149*(t-127)),-1,1)}const e={UInt:"uint",UInt8:"u8",UInt16:"u16",UInt32:"u32",Int:"int",Int8:"i8",Int16:"i16",Int32:"i32",Float64:"f64",Float32:"f32",Float16:"f16",BFloat16:"b16",Scalar8:"sc",UScalar8:"usc",Bool:"bl",Bools:"bls",Buffer:"buf",String:"str",JSON:"jsn",RegExp:"re",Date:"dt"},i=Object.values(e);class MaybeType{constructor(t){this.type=t}}function optional(t){return new MaybeType(t)}const mask=(t,r=1)=>t.reduce(((t,r)=>t<<1|r),r),unmask=(t,r)=>{const e=void 0===r?31-Math.clz32(t):Array.isArray(r)?r.length:r,i=Array.isArray(r)&&r.length===e?r:new Array(e);for(let r=0;rt.encode(r)}(),s=function(){const t=new TextDecoder("utf-8");return r=>t.decode(r)}();function f16round(t){return a(o(t))}const o=function(){const t=new Float32Array(1),r=new Int32Array(t.buffer);return function(e){t[0]=e;let i=r[0],n=i>>16&32768,s=4096+(2147483647&i)|0;return s>=1199570944?(2147483647&i)<1199570944?31743|n:s<2139095040?31744|n:31744|n|(8388607&i)>>13:s>=947912704?n|s-939524096>>13:s<855638016?n:(s=(2147483647&i)>>23,n|(8388607&i|8388608)+(8388608>>>s-102)>>126-s)}}(),a=function(){const t=Math.pow(2,-24),r=new Float32Array(1056);for(let t=0;t<32;t++)r[t]=Math.pow(2,t-15);for(let t=0;t<1024;t++)r[t+32]=1+t/1024;return function(e){const i=32768&~e?1:-1,n=31744&e,s=1023&e;return 0===n?0===s?0*i:i*t:31744===n?0===s?i*(1/0):NaN:r[n>>10]*r[s+32]*i}}(),h=new Uint32Array(1),f=new Float32Array(h.buffer);function bf16round(t){return f[0]=t,h[0]=4294901760&h[0],f[0]}const u=536870912,c=268435456,d=4294967296,$={h:(r,e)=>{"number"!=typeof r&&(r=Number(r)),r<0&&(r=0),r<128?e.u(r):r<16384?e.$(r+32768):r=u?(e.l(t(r/d)+3758096384),e.l(r>>>0)):e.u(!0===r?1:0)},p:t=>{const r=t.m();return 128&r?64&r?32&r?(t.B()-3758096384)*d+t.B():t.B()-3221225472:t.F()-32768:(t.A(),r)}},l={h:(t,r)=>r.u(t),p:t=>t.T()},w={h:(t,r)=>r.$(t),p:t=>t.F()},y={h:(t,r)=>r.l(t),p:t=>t.B()},p={h:(r,e)=>{"number"!=typeof r&&(r=Number(r)),r>=-64&&r<64?e.u(127&r):r>=-8192&&r<8192?e.$(32768+(16383&r)):r>=-268435456&&r=c?(e.l(3758096384+(536870911&t(r/d))),e.l(r>>>0)):e.u(!0===r?127:0)},p:t=>{let r,e=t.m();return 128&e?64&e?32&e?(r=t.B()-3758096384,r=268435456&r?3758096384|r:r,r*d+t.B()):(r=t.B()-3221225472,268435456&r?3758096384|r:r):(r=t.F()-32768,8192&r?4294950912|r:r):(t.A(),64&e?4294967168|e:e)}},b={h:(t,r)=>r.v(t),p:t=>t.U()},m={h:(t,r)=>r.I(t),p:t=>t.M()},B={h:(t,r)=>r.S(t),p:t=>t.j()},F={h:(t,r)=>r.$(function $tobf16(t){return f[0]=t,h[0]>>>16}(t)),p:t=>function $frombf16(t){return h[0]=t<<16,f[0]}(t.F())},A={h:(t,r)=>r.$(o(t)),p:t=>a(t.F())},T={h:(t,r)=>r.H(t),p:t=>t._()},v={h:(t,r)=>r.k(t),p:t=>t.O()},E={h:(t,r)=>r.u($touscal8(t)),p:t=>$fromuscal8(t.T())},g={h:(t,r)=>r.u($toscal8(t)),p:t=>$fromscal8(t.T())},U={h:(t,r)=>p.h(t.getTime(),r),p:t=>new Date(p.p(t))},I={h:(t,r)=>{$.h(t.byteLength,r),r.C(t)},p:t=>t.D($.p(t))},M={h:(t,r)=>I.h(n(t),r),p:t=>s(I.p(t))},S={h:(t,r)=>r.u(t?1:0),p:t=>0!==t.T()},x={h:(t,r)=>{t.length>28&&(t=t.slice(0,28)),$.h(mask(t),r)},p:(t,r)=>unmask($.p(t),r)},j={h:(t,r)=>M.h(JSON.stringify(t),r),p:t=>JSON.parse(M.p(t))},H={h:(t,r)=>{r.u(mask([t.global,t.ignoreCase,t.multiline])),M.h(t.source,r)},p:t=>{const[r,e,i]=unmask(t.T());return new RegExp(M.p(t),(r?"g":"")+(e?"i":"")+(i?"m":""))}},_={[e.UInt]:$.h,[e.UInt8]:l.h,[e.UInt16]:w.h,[e.UInt32]:y.h,[e.Int]:p.h,[e.Int8]:b.h,[e.Int16]:m.h,[e.Int32]:B.h,[e.Float64]:v.h,[e.Float32]:T.h,[e.Float16]:A.h,[e.BFloat16]:F.h,[e.Scalar8]:g.h,[e.UScalar8]:E.h,[e.Bool]:S.h,[e.Bools]:x.h,[e.Buffer]:I.h,[e.String]:M.h,[e.JSON]:j.h,[e.RegExp]:H.h,[e.Date]:U.h},k={[e.UInt]:$.p,[e.UInt8]:l.p,[e.UInt16]:w.p,[e.UInt32]:y.p,[e.Int]:p.p,[e.Int8]:b.p,[e.Int16]:m.p,[e.Int32]:B.p,[e.Float64]:v.p,[e.Float32]:T.p,[e.Float16]:A.p,[e.BFloat16]:F.p,[e.Scalar8]:g.p,[e.UScalar8]:E.p,[e.Bool]:S.p,[e.Bools]:x.p,[e.Buffer]:I.p,[e.String]:M.p,[e.JSON]:j.p,[e.RegExp]:H.p,[e.Date]:U.p},setTinybufConfig=t=>{O=Object.assign(Object.assign({},O),t)};let O={safe:!1,useGlobalEncodingBuffer:!0,encodingBufferMaxSize:1500,encodingBufferInitialSize:256,encodingBufferIncrement:256};class BufferWriter{constructor(t){this.V=0,this.N=0,this.R=new DataView(new ArrayBuffer(t))}W(){return new Uint8Array(this.R.buffer,this.R.byteOffset,this.V)}J(){return new Uint8Array(this.R.buffer.slice(0,this.V))}v(t){this.P(1).setInt8(this.N,t)}I(t){this.P(2).setInt16(this.N,t,!0)}S(t){this.P(4).setInt32(this.N,t,!0)}u(t){this.P(1).setUint8(this.N,t)}$(t){this.P(2).setUint16(this.N,t,!1)}l(t){this.P(4).setUint32(this.N,t,!1)}H(t){this.P(4).setFloat32(this.N,t,!0)}k(t){this.P(8).setFloat64(this.N,t,!0)}C(t){this.P(t.byteLength);let r=ArrayBuffer.isView(t)?t instanceof Uint8Array?t:new Uint8Array(t.buffer,t.byteOffset,t.byteLength):new Uint8Array(t);new Uint8Array(this.R.buffer,this.R.byteOffset+this.N,t.byteLength).set(r)}P(t){if(this.V+t>this.R.byteLength){const r=this.V+t-this.R.byteLength,e=Math.ceil(r/O.encodingBufferIncrement)*O.encodingBufferIncrement;this.q(this.R.byteLength+e)}return this.N=this.V,this.V+=t,this.R}q(t){if(t>O.encodingBufferMaxSize)throw new TinybufError(`exceeded encodingBufferMaxSize: ${O.encodingBufferMaxSize}`);const r=new ArrayBuffer(t),e=new Uint8Array(this.R.buffer,this.R.byteOffset,this.R.byteLength);new Uint8Array(r).set(e),this.R=new DataView(r)}}class BufferReader{constructor(t,r){this.R=ArrayBuffer.isView(t)?new DataView(t.buffer,t.byteOffset,t.byteLength):new DataView(t),this.i=null!=r?r:0}m(){return this.R.getUint8(this.i)}A(){this.i++}T(){return this.R.getUint8(this.i++)}F(){const t=this.R.getUint16(this.i);return this.i+=2,t}B(){const t=this.R.getUint32(this.i);return this.i+=4,t}U(){return this.R.getInt8(this.i++)}M(){const t=this.R.getInt16(this.i,!0);return this.i+=2,t}j(){const t=this.R.getInt32(this.i,!0);return this.i+=4,t}_(){const t=this.R.getFloat32(this.i,!0);return this.i+=4,t}O(){const t=this.R.getFloat64(this.i,!0);return this.i+=8,t}D(t){if(this.R.byteOffset+this.i+t>this.R.byteLength)throw new RangeError("exceeded bytes");const r=new Uint8Array(this.R.buffer,this.R.byteOffset+this.i,t);return this.i+=t,r}}function defineFormat(t,r){return null!==t&&"object"==typeof t?new BufferFormat(t):new BufferFormat(r,t)}class BufferFormat{get encodingBuffer(){var t;return null===(t=this.G)||void 0===t?void 0:t.R}constructor(t,r){if(this.K=!1,"string"==typeof t&&i.includes(t))this.L=t;else{if(t instanceof MaybeType)throw new TypeError("Format cannot be optional");if(!(t instanceof Object))throw new TypeError("Format must be object or Type");if(this.L=void 0,this.X=new Map,this.Y=Object.keys(t).map((r=>{const e=new Field(r,t[r]);return this.X.set(r,e),e})),void 0===r)this.header=$hashCode(this.f),this.Z=this.header;else if(null===r)this.header=void 0,this.Z=void 0;else{if(!function isValidHeader(t){return"number"==typeof t?Number.isInteger(t)&&t>=0&&t<=65535:"string"==typeof t&&2===(new TextEncoder).encode(t).byteLength}(r))throw new TypeError("Header must be 2-byte string, uint16, or null.");this.header=r,this.Z="number"==typeof r?r:$strToHashCode(r)}}}get f(){return void 0===this.tt&&(this.tt=void 0!==this.Y?`{${this.Y.map((t=>t.f)).join(",")}}`:`${this.L}`),this.tt}static rt(){return O.useGlobalEncodingBuffer?(BufferFormat.et||(this.et=new BufferWriter(O.encodingBufferInitialSize)),this.et):new BufferWriter(O.encodingBufferInitialSize)}encode(t,r){return this.G||(this.G=BufferFormat.rt()),this.G.V=0,this.K&&(t=this.it(t)),this.nt(t,this.G),(null!=r?r:O.safe)?this.G.J():this.G.W()}decode(t,r){return this.st(new BufferReader(t,void 0===this.header?0:2),r)}setTransforms(t){if(this.K=!0,"function"==typeof t||Array.isArray(t)&&"function"==typeof t[0])this.ot=t;else for(const r of Object.keys(t)){const e=this.X.get(r);if(!e)throw new TypeError(`Failed to set transforms for field '${r}'`);e.ht.setTransforms(t[r])}return this}setValidation(t){if(this.K=!0,"function"==typeof t)this.ft=t;else for(const r of Object.keys(t)){const e=this.X.get(r);if(!e)throw new TypeError(`Failed to set validation function for field '${r}'`);e.ht.setValidation(t[r])}return this}nt(t,r){if(void 0!==this.Z&&r.$(this.Z),void 0!==this.L){const e=this.ft||this.ot?this.it(t):t;return _[this.L](e,r)}if("object"!=typeof t||!t)throw new TypeError("expected object type");for(const e of this.Y){const i=t[e.ut];if(e.ct){if(null==i){S.h(!1,r);continue}S.h(!0,r)}else if(null==i)throw new Error(`missing required value: ${e.ut}`);e.dt?this.$t(i,r,e.ht):e.ht.nt(i,r)}}it(t){return this.ft&&this.lt(t),"function"==typeof this.ot?this.ot(t):Array.isArray(this.ot)&&"function"==typeof this.ot[0]?this.ot[0](t):t}wt(t){return Array.isArray(this.ot)&&"function"==typeof this.ot[1]&&(t=this.ot[1](t)),this.ft&&this.lt(t),t}lt(t){if(!this.ft)return;const r=this.ft(t);if(r instanceof Error)throw r;if(!1===r)throw new Error("failed validation")}st(t,r){return this.st=this.yt(),this.st(t,r)}bt(){const t=this.Y.map((({ut:t},r)=>`v.${t}=this.${this.Bt.name}(${r},s,v.${t})`)).join(";");return`let v=o??{};${t};return v;`}Bt(t,r,e){const i=this.Y[t];if(!i.ct||S.p(r))return i.dt?this.Ft(i.ht,r,e):i.ht.st(r,e)}yt(){return void 0!==this.L?this.K?t=>this.wt(k[this.L](t)):k[this.L]:new Function("s","o",this.bt())}$t(t,r,e){if(!Array.isArray(t))throw new TypeError(`expected array, instead got: ${t}`);$.h(t.length,r);for(let i=0;i;\ntype Uint16FormatHeader = number;\n\n/**\n * Small utility for registering and processing format handlers.\n *\n * @example\n * const myHandler = bufferParser()\n * .on(FormatA, aData => {})\n * .on(FormatB, bData => {});\n *\n * myHandler.processBuffer(bytes);\n */\nexport const bufferParser = (): BufferParser => new BufferParser();\n\nexport class BufferParser {\n /** @internal */\n private _$formats = new Map any, decodeInPlace: boolean]>();\n private _$data = new Map(); // used when decoding in-place\n\n /**\n * Decode an array buffer and trigger the relevant data handler.\n *\n * When passed an ArrayBufferView, accesses the underlying 'buffer' instance directly.\n *\n * @throws {TinybufError} if fails to decode, or no handler is registered\n */\n public processBuffer(b: ArrayBuffer | ArrayBufferView): void {\n let f: any, data: any, cb: (data: any) => any, r: boolean;\n\n try {\n const header = peekHeader(b);\n\n if (!this._$formats.has(header)) {\n throw new TinybufError(`Unknown format: ${header} '${$hashCodeToStr(header)}')`);\n }\n\n [f, cb, r] = this._$formats.get(header);\n if (r) data = this._$data.get(header) ?? {};\n data = f.decode(b, data);\n if (r) this._$data.set(header, data);\n }\n catch (e) {\n const err = new TinybufError(`Failed to decode: ${e}`);\n err.stack = e.stack;\n\n throw err;\n }\n\n cb(data);\n }\n\n /**\n * Register a format handler.\n */\n public on>(\n format: BufferFormat,\n callback: (data: DecodedType) => any,\n {\n decodeInPlace = false,\n } = {},\n ): this {\n if (format.header == null) {\n throw new TinybufError(\"Format requires header\");\n }\n\n const header = typeof format.header === \"string\" ? $strToHashCode(format.header) : format.header;\n\n if (this._$formats.has(header) && this._$formats.get(header)?.[0] !== format) {\n throw new TinybufError(`Format header collision: ${format.header}`);\n }\n\n this._$formats.set(header, [format, callback, decodeInPlace]);\n\n return this;\n }\n\n /** Register a format (or formats) that are recognized. */\n public ignore(...format: AnyFormat[]): this {\n format.forEach(f => this.on(f, () => {}));\n return this;\n }\n\n /** Clears all registered formats and handlers. */\n public clear(): void {\n this._$formats.clear();\n this._$data.clear();\n }\n}\n","export const $floor = Math.floor,\n $ceil = Math.ceil;\n\n/** Clamp a number to a range. */\nexport const $clamp = (value: number, min: number, max: number): number =>\n value > max ? max : value < min ? min : value;\n\n/** Round toward zero */\nexport const $roundTowardZero = (x: number): number => x < 0 ? $ceil(x) : $floor(x);\n\n/** Round away zero */\nexport const $roundAwayFromZero = (x: number): number =>\n x < 0 ? $floor(x) : $ceil(x);\n","import { $clamp, $roundTowardZero, $roundAwayFromZero } from \"./math\";\n\n/**\n * Quantize a number to an 8-bit scalar between 0.0 and 1.0.\n *\n * @returns A number (double) in its closest signed scalar representation.\n */\nexport function uscalround(x: number): number {\n return $fromuscal8($touscal8(x));\n}\n\n/**\n * Quantize a number to an 8-bit signed scalar between -1.0 and 1.0.\n *\n * @returns A number (double) in its closest signed scalar representation.\n */\nexport function scalround(x: number): number {\n return $fromscal8($toscal8(x));\n}\n\n/** @returns A UInt8 bitmask representation. */\nexport function $touscal8(x: number): number {\n return $clamp(127 + $roundTowardZero(x * 254 - 127), 0, 254);\n}\n\n/** @returns A UInt8 bitmask representation. */\nexport function $toscal8(x: number): number {\n return $clamp($roundTowardZero(x * 127), -127, 127) + 127;\n}\n\n/** @returns An unsigned scalar between 0.0 and 1.0. */\nexport function $fromuscal8(x: number): number {\n // Make symmetric: (0.5 + round((uint8 - 127) / 254 * 100)) / 100\n return $clamp(($roundAwayFromZero((x - 127) * 0.3937007874015748) + 50) * 0.01, 0, 1);\n}\n\n/** @returns A signed scalar between -1.0 and 1.0. */\nexport function $fromscal8(x: number): number {\n // Make symmetric: round((uint8 - 127) / 127 * 100) / 100\n return $clamp($roundAwayFromZero((x - 127) * 0.787401574803149) * 0.01, -1, 1);\n}\n","/**\n * Field types for defining encoding formats.\n *\n * @see [Types](https://github.com/reececomo/tinybuf/blob/main/docs/types.md)\n */\nexport const Type = {\n /**\n * Unsigned integer (1 - 8 bytes).\n * - 0 → 127 = 1 byte\n * - 128 → 16,384 = 2 bytes\n * - 16,385 → 536,870,911 = 4 bytes\n * - 536,870,912 → `Number.MAX_SAFE_INTEGER` = 8 bytes\n */\n UInt: \"uint\",\n\n /** Unsigned 8-bit integer (between 0 and 255, 1 byte). */\n UInt8: \"u8\",\n\n /** Unsigned 16-bit integer (between 0 and 65,535, 2 bytes). */\n UInt16: \"u16\",\n\n /** Unsigned 32-bit integer (between 0 and 4,294,967,295, 4 bytes). */\n UInt32: \"u32\",\n\n /**\n * Signed integer (1 - 8 bytes).\n * - 0 → ±64 = 1 byte\n * - ±65 → ±8,192 = 2 bytes\n * - ±8,193 → ±268,435,456 = 4 bytes\n * - ±268,435,457 → ±`Number.MAX_SAFE_INTEGER` = 8 bytes\n */\n Int: \"int\",\n\n /** Signed 1 byte integer (between -127 and 127). */\n Int8: \"i8\",\n\n /** Signed 2 byte integer (between -32,767 and 32,767). */\n Int16: \"i16\",\n\n /** Signed 4 byte integer (between -2,147,483,647 and 2,147,483,647). */\n Int32: \"i32\",\n\n /** Default JavaScript `number` type. Floating-point number (64-bit, double precision, 8 bytes). */\n Float64: \"f64\",\n\n /** Floating-point number (32-bit, single precision, 4 bytes). */\n Float32: \"f32\",\n\n /**\n * Floating-point number (16-bit in FP16 format, half precision, 2 bytes).\n *\n * **Warning:** Low precision; maximum range: ±65,504.\n */\n Float16: \"f16\",\n\n /**\n * Floating-point number (16-bit in BF16 format, half precision, 2 bytes).\n *\n * **Warning:** Low precision.\n */\n BFloat16: \"b16\",\n\n /** A signed 2-decimal scalar between -1.00 and 1.00 (1 byte). */\n Scalar8: \"sc\",\n\n /** An unsigned 2-decimal scalar between 0.00 and 1.00 (1 byte). */\n UScalar8: \"usc\",\n\n /**\n * Boolean value (1 byte).\n * @see {Bools} for packing multiple booleans into a single byte.\n */\n Bool: \"bl\",\n\n /** Any array of booleans (1 bit overhead, encoded as UInt). */\n Bools: \"bls\",\n\n /** Any ArrayBuffer or ArrayBufferView (e.g. Uint8Array) value (encoded as 1 x UInt for byte length + buffer bytes). */\n Buffer: \"buf\",\n\n /** A UTF-8 string (encoded as 1 x UInt for UTF-8 byte length + UTF-8 bytes). */\n String: \"str\",\n\n /** Any JSON data (encodes as UTF-8). */\n JSON: \"jsn\",\n\n /** JavaScript RegExp object. */\n RegExp: \"re\",\n\n /**\n * JavaScript Date object.\n *\n * Encoded as an 8 byte (64-bit) integer UTC timestamp from as the number\n * of milliseconds since the Unix Epoch (January 1, 1970, 00:00:00 UTC).\n *\n * @see {Date}\n */\n Date: \"dt\",\n} as const;\n\nexport type TypeLiteral = typeof Type[keyof typeof Type];\nexport const ValidTypes = Object.values(Type);\n\n/**\n * Mappings for the value types.\n */\nexport type ValueTypes = {\n [Type.Int]: number;\n [Type.Int8]: number;\n [Type.Int16]: number;\n [Type.Int32]: number;\n [Type.UInt]: number;\n [Type.UInt8]: number;\n [Type.UInt16]: number;\n [Type.UInt32]: number;\n [Type.Float64]: number;\n [Type.Float32]: number;\n [Type.Float16]: number;\n [Type.BFloat16]: number;\n [Type.Scalar8]: number;\n [Type.UScalar8]: number;\n [Type.Bool]: boolean;\n [Type.Bools]: boolean[];\n [Type.Buffer]: Uint8Array | ArrayBuffer | ArrayBufferView;\n [Type.String]: string;\n [Type.JSON]: any;\n [Type.RegExp]: RegExp;\n [Type.Date]: Date;\n};\n\n/** @throws any error too */\nexport type ValidationFn = (x: T) => undefined | boolean | Error;\nexport type TransformFn = (x: T) => T;\nexport type Transforms = TransformFn | [preEncode: TransformFn] | [preEncode: TransformFn | undefined, postDecode: TransformFn | undefined];\n\n/**\n * A wrapper around any Type definition that declares it as optional.\n */\nexport class MaybeType {\n public constructor(public type: T) {}\n}\n\n/**\n * Wrap any definition as optional.\n */\nexport function optional(t: T): MaybeType {\n return new MaybeType(t);\n}\n\n/**\n * A definition for an object binary encoder.\n */\nexport type EncoderDefinition = {\n [key: string]: FieldDefinition | MaybeType;\n};\n\n/**\n * Definition for an object-field binary encoder.\n */\nexport type FieldDefinition = keyof ValueTypes | [keyof ValueTypes] | EncoderDefinition | [EncoderDefinition] | MaybeType;\n\n/**\n * The resulting type of the decoded data, based on the encoder definition.\n */\nexport type InferredDecodedType = {\n [EKey in keyof EncoderType as EncoderType[EKey] extends MaybeType ? never : EKey]: EncoderType[EKey] extends keyof ValueTypes\n ? ValueTypes[EncoderType[EKey]]\n : EncoderType[EKey] extends [keyof ValueTypes]\n ? Array\n : EncoderType[EKey] extends EncoderDefinition\n ? InferredDecodedType\n : EncoderType[EKey] extends [EncoderDefinition]\n ? Array>\n : never;\n} & {\n [EKey in keyof EncoderType as EncoderType[EKey] extends MaybeType ? EKey : never]?: EncoderType[EKey] extends MaybeType\n ? ValueTypes[OptionalValue] | undefined\n : EncoderType[EKey] extends MaybeType\n ? Array | undefined\n : EncoderType[EKey] extends MaybeType\n ? InferredDecodedType | undefined\n : never;\n};\n\nexport type InferredTransformConfig = {\n [EKey in keyof EncoderType]?: EncoderType[EKey] extends keyof ValueTypes\n ? Transforms\n : EncoderType[EKey] extends [keyof ValueTypes]\n ? Transforms\n : EncoderType[EKey] extends EncoderDefinition\n ? InferredTransformConfig\n : EncoderType[EKey] extends [EncoderDefinition]\n ? InferredTransformConfig\n : EncoderType[EKey] extends MaybeType\n ? Transforms\n : EncoderType[EKey] extends MaybeType\n ? Transforms\n : EncoderType[EKey] extends MaybeType\n ? InferredTransformConfig | undefined\n : never;\n};\n\nexport type InferredValidationConfig = {\n [EKey in keyof EncoderType]?: EncoderType[EKey] extends keyof ValueTypes\n ? ValidationFn\n : EncoderType[EKey] extends [keyof ValueTypes]\n ? ValidationFn\n : EncoderType[EKey] extends EncoderDefinition\n ? InferredValidationConfig\n : EncoderType[EKey] extends [EncoderDefinition]\n ? InferredValidationConfig\n : EncoderType[EKey] extends MaybeType\n ? ValidationFn\n : EncoderType[EKey] extends MaybeType\n ? ValidationFn\n : EncoderType[EKey] extends MaybeType\n ? InferredValidationConfig | undefined\n : never;\n};\n","/**\n * Mask booleans to a uint32.\n *\n * @param x - A boolean array.\n * @param padBit - A bit to pad the mask (for variable length data).\n */\nexport const mask = (x: boolean[], padBit: 0 | 1 = 0b1): number => {\n return x.reduce((n, b: any) => (n << 1) | b, padBit);\n};\n\n/**\n * Unmask booleans from a uint32.\n *\n * @param x - A uint32 number.\n * @param l - number of booleans to expect (default: infer lenth from x where x is encoded with a pad bit)\n * or pass an existing boolean array to decode in-place.\n */\nexport const unmask = (x: number, l?: number | boolean[]): boolean[] => {\n const len = l === undefined ? 31 - Math.clz32(x) : Array.isArray(l) ? l.length : l;\n const val = Array.isArray(l) && l.length === len ? l : new Array(len);\n for (let i = 0; i < len; i++) val[i] = !!(x & (1 << (len - 1 - i)));\n return val;\n};\n","export const $utf8encode = (function () {\n const encoder = new TextEncoder();\n return (x?: string): Uint8Array => encoder.encode(x);\n})();\n\nexport const $utf8decode = (function () {\n const decoder = new TextDecoder(\"utf-8\");\n return (y: Uint8Array): string => decoder.decode(y);\n})();\n","/**\n * Returns the nearest half precision float representation of a number.\n * @param x A numeric expression.\n */\nexport function f16round(x: number): number {\n return $fromf16($tof16(x));\n}\n\n/**\n * Returns the nearest half precision float representation of a number as a 16-bit bitmask.\n */\nexport const $tof16 = (function() {\n const x = new Float32Array(1);\n const y = new Int32Array(x.buffer);\n\n return function (f: number) {\n x[0] = f;\n let i = y[0]; // 32-bit int\n let s = (i >> 16) & 0X8000; // sign\n let z = (i & 0X7FFFFFFF) + 0X1000 | 0;\n\n if (z >= 0X47800000) {\n if ((i & 0X7FFFFFFF) < 0X47800000) return s | 0X7BFF;\n if (z < 0X7F800000) return s | 0X7C00;\n return s | 0X7C00 | (i & 0X007FFFFF) >> 13;\n }\n if (z >= 0X38800000) return s | z - 0X38000000 >> 13;\n else if (z < 0X33000000) return s;\n z = (i & 0X7FFFFFFF) >> 23;\n return s | ((i & 0X7FFFFF | 0X800000)\n + (0X800000 >>> z - 102)\n >> 126 - z);\n };\n}());\n\n/**\n * Returns the nearest half precision float value for a 16-bit bitmask.\n */\nexport const $fromf16 = (function() {\n const z = Math.pow(2, -24); // subnormal constant\n const d = new Float32Array(32 + 1024);\n for (let e = 0; e < 32; e++) d[e] = Math.pow(2, e - 15); // biased exponents\n for (let m = 0; m < 1024; m++) d[m + 0x20] = 1 + m / 1024; // normalized offset mantissas\n\n return function (b: number): number {\n const s = (b & 32768) === 32768 ? -1 : 1; // sign: 1 bit\n const e = b & 31744; // exponent: 5 bits\n const m = b & 1023; // mantissa: 10 bits\n\n if (e === 0) return m === 0 ? s * 0 : s * z;\n if (e === 31744) return m === 0 ? s * Infinity : NaN;\n return d[e >> 10] * d[m + 0x20] * s;\n };\n}());\n","const i = new Uint32Array(1);\nconst f = new Float32Array(i.buffer);\n\n/**\n * Returns the nearest bfloat16 representation of a number.\n * @param x A numeric expression.\n */\nexport function bf16round(x: number): number {\n f[0] = x;\n i[0] = i[0] & 0xFFFF0000;\n return f[0];\n}\n\n/** Returns a 16-bit bfloat16 bitmask for a given float. */\nexport function $tobf16(x: number): number {\n f[0] = x;\n return i[0] >>> 16;\n}\n\n/** Returns the nearest value from a 16-bit bfloat16 bitmask. */\nexport function $frombf16(x: number): number {\n i[0] = x << 16;\n return f[0];\n}\n","import { BufferWriter } from \"./BufferWriter\";\nimport { BufferReader } from \"./BufferReader\";\nimport {\n $fromuscal8,\n $fromscal8,\n $touscal8,\n $toscal8\n} from \"./scalar\";\nimport { TypeLiteral, Type } from \"../Type\";\nimport { mask, unmask } from \"./bitmask\";\nimport { $utf8decode, $utf8encode } from \"./utf8\";\nimport { $floor } from \"./math\";\nimport { $fromf16, $tof16 } from \"./float16\";\nimport { $frombf16, $tobf16 } from \"./bfloat16\";\n\n// Pre-calculated constants\nconst MAX_VARUINT8 = 128,\n MAX_VARUINT16 = 16_384,\n MAX_VARUINT32 = 536_870_912,\n MAX_VARINT8 = 64,\n MAX_VARINT16 = 8_192,\n MAX_VARINT32 = 268_435_456,\n POW_32 = 0x100000000;\n\ntype WriterFn = (value: W, writer: BufferWriter) => void;\ntype ReaderFn = (reader: BufferReader, overwrite?: Partial) => R;\n\nexport interface BinaryTypeCoder {\n $write: WriterFn;\n $read: ReaderFn;\n}\n\n/**\n * Format (big-endian):\n * 7b 0xxxxxxx\n * 14b 10xxxxxx xxxxxxxx\n * 29b 110xxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n * 61b 111xxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n */\nexport const uintCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n if (typeof value !== \"number\") value = Number(value);\n if (value < 0) value = 0;\n if (value < MAX_VARUINT8) writer.$writeUint8(value);\n else if (value < MAX_VARUINT16) writer.$writeUint16(value + 0x8000);\n else if (value < MAX_VARUINT32) writer.$writeUint32(value + 0xc0000000);\n else if (value >= MAX_VARUINT32) {\n writer.$writeUint32($floor(value / POW_32) + 0xe0000000);\n writer.$writeUint32(value >>> 0);\n }\n else {\n // coercion case\n writer.$writeUint8(value as any === true ? 1 : 0);\n }\n },\n $read: (reader) => {\n const firstByte = reader.$peek();\n\n if (!(firstByte & 0x80)) {\n reader.$skip();\n return firstByte;\n }\n else if (!(firstByte & 0x40)) {\n return reader.$readUint16() - 0x8000;\n }\n else if (!(firstByte & 0x20)) {\n return reader.$readUint32() - 0xc0000000;\n }\n\n return (reader.$readUint32() - 0xe0000000) * POW_32\n + reader.$readUint32();\n }\n};\n\nexport const uint8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8(value),\n $read: (reader) => reader.$readUint8(),\n};\n\nexport const uint16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint16(value),\n $read: (reader) => reader.$readUint16(),\n};\n\nexport const uint32Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint32(value),\n $read: (reader) => reader.$readUint32(),\n};\n\n/**\n * Format (big-endian):\n * 7b 0xxxxxxx\n * 14b 10xxxxxx xxxxxxxx\n * 29b 110xxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n * 61b 111xxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n */\nexport const intCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n if (typeof value !== \"number\") value = Number(value);\n if (value >= -MAX_VARINT8 && value < MAX_VARINT8) writer.$writeUint8(value & 0x7f);\n else if (value >= -MAX_VARINT16 && value < MAX_VARINT16) writer.$writeUint16((value & 0x3fff) + 0x8000);\n else if (value >= -MAX_VARINT32 && value < MAX_VARINT32) writer.$writeUint32((value & 0x1fffffff) + 0xc0000000);\n else if (value < -MAX_VARINT32 || value >= MAX_VARINT32) {\n // Split in two 32b uints\n writer.$writeUint32(($floor(value / POW_32) & 0x1fffffff) + 0xe0000000);\n writer.$writeUint32(value >>> 0);\n }\n else {\n // coercion case\n writer.$writeUint8(value as any === true ? 0x7f : 0);\n }\n },\n $read: (reader) => {\n let firstByte = reader.$peek(), i: number;\n\n if (!(firstByte & 0x80)) {\n reader.$skip();\n return (firstByte & 0x40) ? (firstByte | 0xffffff80) : firstByte;\n }\n else if (!(firstByte & 0x40)) {\n i = reader.$readUint16() - 0x8000;\n return (i & 0x2000) ? (i | 0xffffc000) : i;\n }\n else if (!(firstByte & 0x20)) {\n i = reader.$readUint32() - 0xc0000000;\n return (i & 0x10000000) ? (i | 0xe0000000) : i;\n }\n else {\n i = reader.$readUint32() - 0xe0000000;\n i = (i & 0x10000000) ? (i | 0xe0000000) : i;\n return i * POW_32 + reader.$readUint32();\n }\n }\n};\n\nexport const int8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeInt8(value),\n $read: (reader) => reader.$readInt8(),\n};\n\nexport const int16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeInt16(value),\n $read: (reader) => reader.$readInt16(),\n};\n\nexport const int32Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeInt32(value),\n $read: (reader) => reader.$readInt32(),\n};\n\nexport const bfloat16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint16($tobf16(value)),\n $read: (reader) => $frombf16(reader.$readUint16()),\n};\n\nexport const float16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint16($tof16(value)),\n $read: (reader) => $fromf16(reader.$readUint16()),\n};\n\nexport const float32Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeFloat32(value),\n $read: (reader) => reader.$readFloat32(),\n};\n\nexport const float64Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeFloat64(value),\n $read: (reader) => reader.$readFloat64(),\n};\n\nexport const uscalar8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8($touscal8(value)),\n $read: (reader) => $fromuscal8(reader.$readUint8()),\n};\n\nexport const scalar8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8($toscal8(value)),\n $read: (reader) => $fromscal8(reader.$readUint8()),\n};\n\nexport const dateCoder: BinaryTypeCoder = {\n $write: (value, writer) => intCoder.$write(value.getTime(), writer),\n $read: (reader) => new Date(intCoder.$read(reader)),\n};\n\nexport const bufferCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n uintCoder.$write(value.byteLength, writer); // prefix length\n writer.$writeBytes(value);\n },\n $read: (reader) => reader.$readBytes(uintCoder.$read(reader)),\n};\n\nexport const stringCoder: BinaryTypeCoder = {\n $write: (value, writer) => bufferCoder.$write($utf8encode(value), writer),\n $read: (reader) => $utf8decode(bufferCoder.$read(reader)),\n};\n\nexport const boolCoder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8(value ? 1 : 0),\n $read: (reader) => reader.$readUint8() !== 0,\n};\n\nexport const boolsCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n if (value.length > 28) value = value.slice(0, 28); // drop additional\n uintCoder.$write(mask(value), writer);\n },\n $read: (reader, p) => unmask(uintCoder.$read(reader), p),\n};\n\nexport const jsonCoder: BinaryTypeCoder = {\n $write: (value, writer) => stringCoder.$write(JSON.stringify(value), writer),\n $read: (reader) => JSON.parse(stringCoder.$read(reader)),\n};\n\nexport const regexCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n writer.$writeUint8(mask([value.global, value.ignoreCase, value.multiline]));\n stringCoder.$write(value.source, writer);\n },\n $read: (reader) => {\n const [g, i, m] = unmask(reader.$readUint8());\n return new RegExp(stringCoder.$read(reader), (g ? \"g\" : \"\") + (i ? \"i\" : \"\") + (m ? \"m\" : \"\"));\n }\n};\n\nexport const writers: Record> = {\n [Type.UInt]: uintCoder.$write,\n [Type.UInt8]: uint8Coder.$write,\n [Type.UInt16]: uint16Coder.$write,\n [Type.UInt32]: uint32Coder.$write,\n [Type.Int]: intCoder.$write,\n [Type.Int8]: int8Coder.$write,\n [Type.Int16]: int16Coder.$write,\n [Type.Int32]: int32Coder.$write,\n [Type.Float64]: float64Coder.$write,\n [Type.Float32]: float32Coder.$write,\n [Type.Float16]: float16Coder.$write,\n [Type.BFloat16]: bfloat16Coder.$write,\n [Type.Scalar8]: scalar8Coder.$write,\n [Type.UScalar8]: uscalar8Coder.$write,\n [Type.Bool]: boolCoder.$write,\n [Type.Bools]: boolsCoder.$write,\n [Type.Buffer]: bufferCoder.$write,\n [Type.String]: stringCoder.$write,\n [Type.JSON]: jsonCoder.$write,\n [Type.RegExp]: regexCoder.$write,\n [Type.Date]: dateCoder.$write,\n};\n\nexport const readers: Record> = {\n [Type.UInt]: uintCoder.$read,\n [Type.UInt8]: uint8Coder.$read,\n [Type.UInt16]: uint16Coder.$read,\n [Type.UInt32]: uint32Coder.$read,\n [Type.Int]: intCoder.$read,\n [Type.Int8]: int8Coder.$read,\n [Type.Int16]: int16Coder.$read,\n [Type.Int32]: int32Coder.$read,\n [Type.Float64]: float64Coder.$read,\n [Type.Float32]: float32Coder.$read,\n [Type.Float16]: float16Coder.$read,\n [Type.BFloat16]: bfloat16Coder.$read,\n [Type.Scalar8]: scalar8Coder.$read,\n [Type.UScalar8]: uscalar8Coder.$read,\n [Type.Bool]: boolCoder.$read,\n [Type.Bools]: boolsCoder.$read,\n [Type.Buffer]: bufferCoder.$read,\n [Type.String]: stringCoder.$read,\n [Type.JSON]: jsonCoder.$read,\n [Type.RegExp]: regexCoder.$read,\n [Type.Date]: dateCoder.$read,\n};\n","/** Default maximum transmission unit in networking */\nconst MTU = 1500;\n\n/** Set Tinybuf global config */\nexport const setTinybufConfig = (c: Partial): void => {\n cfg = { ...cfg, ...c };\n};\n\nexport type TinybufConfig = {\n /**\n * (default: false)\n *\n * This sets the default value for `preserveBytes` on\n * `encode(data, preserveBytes?)`.\n *\n * By default, `encode()` returns its encoded bytes as a `Uint8Array`\n * view of the bytes in the shared encoding buffer.\n *\n * This is suitable for synchronous use (e.g. high-performance applications)\n * as it avoids slow and expensive memory allocation and fragmentation on\n * each call to `encode()`.\n *\n * However, susbsequent calls are destructive to the underlying bytes, so\n * for asynchronous uses (e.g. Promises, Workers, long-lived storage), set\n * `preserveBytes` to `true`.\n */\n safe: boolean,\n\n /**\n * (default: true)\n * By default, format encoders share a global encoding buffer for performance\n * and memory management reasons.\n *\n * When set to false, each format is allocated an individual encoding buffer.\n *\n * Enable to maximise performance and memory re-use, just be cautious of\n * possible race conditions.\n */\n useGlobalEncodingBuffer: boolean,\n\n /**\n * (default: 1500)\n * The maximum bytes that can be allocated to an encoding buffer.\n *\n * Default is 1500 bytes, the standard \"Maximum Transmission Unit\".\n */\n encodingBufferMaxSize: number,\n\n /**\n * (default: 256)\n * Initial bytes to allocate for an encoding buffer.\n */\n encodingBufferInitialSize: number,\n\n /**\n * (default: 256)\n * Additional bytes to allocated when dynamically increasing the size of an encoding buffer.\n */\n encodingBufferIncrement: number,\n};\n\n/** @internal */\nexport let cfg: TinybufConfig = {\n safe: false,\n useGlobalEncodingBuffer: true,\n encodingBufferMaxSize: MTU,\n encodingBufferInitialSize: 256,\n encodingBufferIncrement: 256,\n};\n","import { cfg } from \"../config\";\nimport { TinybufError } from \"./errors\";\n\n/**\n * Wraps a buffer with a write head pointer.\n *\n * @internal\n */\nexport class BufferWriter {\n public i: number = 0;\n public _$dataView: DataView;\n\n public constructor(initialSize: number) {\n this._$dataView = new DataView(new ArrayBuffer(initialSize));\n }\n\n public $viewBytes(): Uint8Array {\n return new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset, this.i);\n }\n\n public $copyBytes(): Uint8Array {\n return new Uint8Array(this._$dataView.buffer.slice(0, this.i));\n }\n\n // ----- Writers: -----\n\n public $writeInt8(value: number): void {\n this._$dataView.setInt8(this._$alloc(1), value);\n }\n\n public $writeInt16(value: number): void {\n this._$dataView.setInt16(this._$alloc(2), value, true);\n }\n\n public $writeInt32(value: number): void {\n this._$dataView.setInt32(this._$alloc(4), value, true);\n }\n\n public $writeUint8(value: number): void {\n this._$dataView.setUint8(this._$alloc(1), value);\n }\n\n public $writeUint16(value: number): void {\n this._$dataView.setUint16(this._$alloc(2), value, false); // big-endian for varint\n }\n\n public $writeUint32(value: number): void {\n this._$dataView.setUint32(this._$alloc(4), value, false); // big-endian for varint\n }\n\n public $writeFloat32(value: number): void {\n this._$dataView.setFloat32(this._$alloc(4), value, true);\n }\n\n public $writeFloat64(value: number): void {\n this._$dataView.setFloat64(this._$alloc(8), value, true);\n }\n\n public $writeBytes(b: Uint8Array | ArrayBuffer | ArrayBufferView): void {\n // allocate bytes first\n const j = this._$alloc(b.byteLength);\n\n let bBytes: Uint8Array = ArrayBuffer.isView(b)\n ? b instanceof Uint8Array ? b : new Uint8Array(b.buffer, b.byteOffset, b.byteLength)\n : new Uint8Array(b);\n\n // copy bytes\n new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset + j, b.byteLength).set(bBytes);\n }\n\n // ----- Private methods: -----\n\n /** @returns writer head (byteOffset) */\n private _$alloc(bytes: number): number {\n if (this.i + bytes > this._$dataView.byteLength) {\n const minBytesNeeded = this.i + bytes - this._$dataView.byteLength;\n const requestedNewBytes = Math.ceil(minBytesNeeded / cfg.encodingBufferIncrement) * cfg.encodingBufferIncrement;\n this._$resizeBuffer(this._$dataView.byteLength + requestedNewBytes);\n }\n\n const j = this.i;\n this.i += bytes;\n\n return j;\n }\n\n private _$resizeBuffer(newSize: number): void {\n if (newSize > cfg.encodingBufferMaxSize) {\n // safety check\n throw new TinybufError(`exceeded encodingBufferMaxSize: ${cfg.encodingBufferMaxSize}`);\n }\n\n const newBuf = new ArrayBuffer(newSize);\n\n // copy bytes\n const oldView = new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset, this._$dataView.byteLength);\n new Uint8Array(newBuf).set(oldView);\n\n // update ref\n this._$dataView = new DataView(newBuf);\n }\n}\n","/**\n * Wraps a buffer with a read head pointer.\n *\n * @internal\n */\nexport class BufferReader {\n public i: number;\n private _$dataView: DataView;\n\n public constructor(b: Uint8Array | ArrayBufferView | ArrayBuffer, headerBytes?: number) {\n this._$dataView = ArrayBuffer.isView(b)\n ? new DataView(b.buffer, b.byteOffset, b.byteLength)\n : new DataView(b);\n\n this.i = headerBytes ?? 0; // internal offset (header)\n }\n\n /** Read the next byte, without moving the read head pointer. */\n public $peek(): number {\n return this._$dataView.getUint8(this.i);\n }\n\n /** Skip the next byte without reading it. */\n public $skip(): void {\n this.i++;\n }\n\n // ----- Readers: -----\n\n public $readUint8(): number {\n return this._$dataView.getUint8(this.i++);\n }\n\n public $readUint16(): number {\n const r = this._$dataView.getUint16(this.i); // big-endian\n this.i += 2;\n return r;\n }\n\n public $readUint32(): number {\n const r = this._$dataView.getUint32(this.i); // big-endian\n this.i += 4;\n return r;\n }\n\n public $readInt8(): number {\n return this._$dataView.getInt8(this.i++);\n }\n\n public $readInt16(): number {\n const r = this._$dataView.getInt16(this.i, true); // little-endian\n this.i += 2;\n return r;\n }\n\n public $readInt32(): number {\n const r = this._$dataView.getInt32(this.i, true); // little-endian\n this.i += 4;\n return r;\n }\n\n public $readFloat32(): number {\n const r = this._$dataView.getFloat32(this.i, true); // little-endian\n this.i += 4;\n return r;\n }\n\n public $readFloat64(): number {\n const r = this._$dataView.getFloat64(this.i, true); // little-endian\n this.i += 8;\n return r;\n }\n\n /** @throws RangeError if exceeds length */\n public $readBytes(bytes: number): Uint8Array {\n if (this._$dataView.byteOffset + this.i + bytes > this._$dataView.byteLength) {\n throw new RangeError(\"exceeded bytes\");\n }\n\n const view = new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset + this.i, bytes);\n this.i += bytes;\n\n return view;\n }\n}\n","import { writers, readers } from \"./lib/coders\";\nimport * as coders from \"./lib/coders\";\nimport { $hashCode, $strToHashCode } from \"./lib/hashCode\";\nimport { peekHeader, peekHeaderStr } from \"./lib/peek\";\nimport { BufferWriter } from \"./lib/BufferWriter\";\nimport { BufferReader } from \"./lib/BufferReader\";\nimport {\n InferredDecodedType,\n EncoderDefinition,\n MaybeType,\n InferredTransformConfig,\n InferredValidationConfig,\n ValidationFn,\n Transforms,\n FieldDefinition,\n TypeLiteral,\n ValidTypes\n} from \"./Type\";\nimport { cfg } from \"./config\";\n\nexport type FormatHeader = string | number;\n\n/**\n * Decoded object types for a given binary format.\n * @example let onData = (data: Decoded) => {...};\n */\nexport type Decoded = FromBufferFormat extends BufferFormat ? InferredDecodedType : never;\n\n/**\n * Defines a format for encoding/decoding binary buffers.\n *\n * Optionally customize the identifier, either as a 2-byte string, an unsigned integer (0 -> 65,535), or as `null` to disable entirely.\n *\n * @example\n * const MyFormat = defineFormat({ ... });\n * const MyFormat = defineFormat('ab', { ... });\n * const MyFormat = defineFormat(1234, { ... });\n * const MyFormat = defineFormat(null, { ... });\n */\nexport function defineFormat(def: T): BufferFormat;\n/**\n * Defines a format for encoding/decoding binary buffers.\n *\n * Optionally customize the identifier, either as a 2-byte string, an unsigned integer (0 -> 65,535), or as `null` to disable entirely.\n *\n * @example\n * const MyFormat = defineFormat({ ... });\n * const MyFormat = defineFormat('ab', { ... });\n * const MyFormat = defineFormat(1234, { ... });\n * const MyFormat = defineFormat(null, { ... });\n */\nexport function defineFormat(h: HeaderType | null, def: T): BufferFormat;\nexport function defineFormat(a?: HeaderType | T, b?: T): BufferFormat {\n return a !== null && typeof a === \"object\"\n ? new BufferFormat(a as T)\n : new BufferFormat(b as T, a as HeaderType);\n}\n\nfunction isValidHeader(h: FormatHeader): boolean {\n if (typeof h === \"number\") return Number.isInteger(h) && h >= 0 && h <= 65_535;\n if (typeof h === \"string\") return new TextEncoder().encode(h).byteLength === 2;\n return false;\n}\n\n/**\n * BufferFormat is a utility class for encoding and decoding binary data based\n * on a provided encoding format.\n *\n * @see {header}\n * @see {encode(data)}\n * @see {decode(binary)}\n */\nexport class BufferFormat {\n /** @internal */\n private static _$globalWriter?: BufferWriter;\n\n /**\n * A unique identifier encoded as the first 2 bytes (or `undefined` if headerless).\n *\n * @see {peekHeader(...)}\n * @see {peekHeaderStr(...)}\n */\n public header!: HeaderType;\n\n /** @internal */\n private _$header!: number; // always uint16 vesion\n /** @internal */\n private _$type!: TypeLiteral;\n /** @internal */\n private _$fields!: Field[];\n /** @internal */\n private _$fieldsMap!: Map;\n\n /** @internal */\n private _$format?: string;\n /** @internal */\n private _$transforms?: Transforms | undefined;\n /** @internal */\n private _$validate?: ValidationFn | undefined;\n /** @internal */\n private _$hasValidationOrTransforms = false;\n /** @internal */\n private _$writer?: BufferWriter;\n\n public get encodingBuffer(): DataView | undefined {\n return this._$writer?._$dataView;\n }\n\n public constructor(\n def: EncoderType,\n header?: HeaderType | null,\n ) {\n // set definition\n if (typeof def === \"string\" && ValidTypes.includes(def)) {\n this._$type = def;\n }\n else if (def instanceof MaybeType) {\n throw new TypeError(\"Format cannot be optional\");\n }\n else if (def instanceof Object) {\n this._$type = undefined; // object\n this._$fieldsMap = new Map();\n this._$fields = Object.keys(def).map((name) => {\n const f = new Field(name, def[name]);\n this._$fieldsMap.set(name, f); // also set map entry\n return f;\n });\n\n // set headers\n if (header === undefined) {\n this.header = $hashCode(this.f) as HeaderType; // automatic\n this._$header = this.header as number;\n }\n else if (header === null) {\n this.header = undefined; // headerless\n this._$header = undefined;\n }\n else if (isValidHeader(header)) {\n this.header = header; // manual\n this._$header = typeof header === \"number\" ? header : $strToHashCode(header);\n }\n else {\n throw new TypeError(`Header must be uint16, 2 byte string, or null. Received: ${header}`);\n }\n }\n else {\n throw new TypeError(`Format must be object or Type: ${JSON.stringify(def)} ${typeof def} ${ValidTypes[def]}`);\n }\n }\n\n // ----- Static methods: -----\n\n /**\n * Read the header of a buffer as a number.\n *\n * @see {header}\n * @throws {RangeError} if buffer size < 2\n */\n public static peekHeader = peekHeader;\n\n /**\n * Read the header of a buffer as a string.\n *\n * @see {header}\n * @throws {RangeError} if buffer size < 2\n */\n public static peekHeaderStr = peekHeaderStr;\n\n // ----- Accessors: -----\n\n /**\n * @example \"{uint8,str[]?}\"\n * @internal\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private get f(): string {\n if (this._$format === undefined) {\n this._$format = this._$fields !== undefined\n ? `{${this._$fields.map(v => v.f).join(\",\")}}`\n : `${this._$type}`;\n }\n\n return this._$format;\n }\n\n /** @internal */\n private static _$initWriter(): BufferWriter {\n if (cfg.useGlobalEncodingBuffer) {\n if (!BufferFormat._$globalWriter) {\n // lazy init: global encoding buffer created at max size\n this._$globalWriter = new BufferWriter(cfg.encodingBufferInitialSize);\n }\n\n return this._$globalWriter;\n }\n\n return new BufferWriter(cfg.encodingBufferInitialSize);\n }\n\n /**\n * Encode an object to bytes.\n *\n * **Warning:** Returns an unsafe view into the encoding buffer. Pass this reference to preserve\n * performance, and to minimize memory allocation and fragmentation.\n *\n * @param data - data to encode\n * @param preserveBytes - (default: `setTinybufConfig().safe`) When set to true, copies encoded\n * bytes to a new buffer. When set to false, returns an unsafe view of bytes but prevents\n * unnnecessary memory allocation and fragmentation.\n *\n * @returns a copy of encoded bytes\n * @throws if fails to encode value to schema\n */\n public encode>(\n data: DecodedType,\n preserveBytes?: boolean,\n ): Uint8Array {\n if (!this._$writer) {\n // lazy init\n this._$writer = BufferFormat._$initWriter();\n }\n\n // reset\n this._$writer.i = 0;\n\n if (this._$hasValidationOrTransforms) {\n data = this._$preprocess(data);\n }\n\n this._$write(data, this._$writer);\n\n return (preserveBytes ?? cfg.safe)\n ? this._$writer.$copyBytes()\n : this._$writer.$viewBytes();\n }\n\n /**\n * Decode binary data to an object.\n * @throws if fails to decode bytes to schema.\n */\n public decode>(\n bytes: Uint8Array | ArrayBufferView | ArrayBuffer,\n decodeInto?: Partial,\n ): DecodedType {\n return this._$read(new BufferReader(bytes, this.header === undefined ? 0 : 2), decodeInto);\n }\n\n /**\n * Set additional transform functions to apply before encoding and after decoding.\n */\n public setTransforms(transforms: InferredTransformConfig | Transforms): this {\n this._$hasValidationOrTransforms = true;\n\n if (typeof transforms === \"function\" || (Array.isArray(transforms) && typeof transforms[0] === \"function\")) {\n this._$transforms = transforms;\n }\n else {\n for (const name of Object.keys(transforms)) {\n const field = this._$fieldsMap.get(name);\n if (!field) {\n throw new TypeError(`Failed to set transforms for field '${name}'`);\n }\n\n // Set validation for object.\n field.$coder.setTransforms(transforms[name]);\n }\n }\n\n return this;\n }\n\n /**\n * Set additional validation rules which are applied on encode() and decode().\n *\n * - Validation functions should throw an error, return an error, or return boolean false.\n * - Anything else is treated as successfully passing validation.\n */\n public setValidation(validations: InferredValidationConfig | ValidationFn): this {\n this._$hasValidationOrTransforms = true;\n\n if (typeof validations === \"function\") {\n this._$validate = validations;\n }\n else {\n for (const name of Object.keys(validations)) {\n const field = this._$fieldsMap.get(name);\n if (!field) {\n throw new TypeError(`Failed to set validation function for field '${name}'`);\n }\n\n field.$coder.setValidation(validations[name]);\n }\n }\n\n return this;\n }\n\n // ----- Implementation: -----\n\n /**\n * @param value\n * @param bw\n * @throws if the value is invalid\n *\n * @internal\n */\n private _$write(value: any, bw: BufferWriter): void {\n // write header\n if (this._$header !== undefined) bw.$writeUint16(this._$header);\n\n // write scalar\n if (this._$type !== undefined) {\n const safeValue = (this._$validate || this._$transforms) ? this._$preprocess(value) : value;\n\n return writers[this._$type](safeValue, bw);\n }\n\n // check for object type\n if (typeof value !== \"object\" || !value) {\n throw new TypeError(\"expected object type\");\n }\n\n // write each field\n for (const field of this._$fields) {\n const subValue = value[field.$name];\n\n if (field.$isOptional) {\n if (subValue === undefined || subValue === null) {\n coders.boolCoder.$write(false, bw);\n continue; // skip\n }\n else {\n coders.boolCoder.$write(true, bw);\n }\n }\n else if (subValue == null) {\n throw new Error(`missing required value: ${field.$name}`);\n }\n\n if (field.$isArray) {\n // array\n this._$writeArray(subValue, bw, field.$coder);\n continue;\n }\n\n // scalar/object field\n field.$coder._$write(subValue, bw);\n }\n }\n\n /**\n * pre-process: validation and/or transforms\n * @internal\n */\n private _$preprocess>(data: T): T {\n if (this._$validate) this._$processValidation(data);\n\n if (typeof this._$transforms === \"function\") {\n return this._$transforms(data);\n }\n else if (Array.isArray(this._$transforms) && typeof this._$transforms[0] === \"function\") {\n return this._$transforms[0](data);\n }\n\n return data;\n }\n\n /**\n * post-process: validation and/or transforms\n * @internal\n */\n private _$postprocess>(data: T): T {\n if (Array.isArray(this._$transforms) && typeof this._$transforms[1] === \"function\") {\n data = this._$transforms[1](data);\n }\n\n if (this._$validate) this._$processValidation(data);\n\n return data;\n }\n\n private _$processValidation(data: any): void {\n if (!this._$validate) return;\n const res = this._$validate(data);\n if (res instanceof Error) throw res;\n if (res === false) throw new Error(\"failed validation\");\n }\n\n /**\n * This function will be executed only the first time\n * After that, we'll compile the read routine and add it directly to the instance\n * @param state\n * @returns\n * @throws if fails\n *\n * @internal\n */\n private _$read>(state: BufferReader, obj?: Partial): DecodedType {\n // This function will be executed only the first time to compile the read routine.\n // After that, we'll compile the read routine and add it directly to the instance\n\n // Update the read method implementation.\n this._$read = this._$compileFormatReadFn();\n\n return this._$read(state, obj);\n }\n\n /**\n * Generate read function code for this coder.\n *\n * @example\n * let v=o??{};\n * v.prop1=this._$readField(0,s,o);\n * v.prop2=this._$readField(1,s,o);\n * return v\n *\n * @internal\n */\n private _$makeObjectReadFnBody(): string {\n const fieldsStr: string = this._$fields\n .map(({ $name: n }, i) => `v.${n}=this.${this._$readField.name}(${i},s,v.${n})`)\n .join(\";\");\n\n return `let v=o??{};${fieldsStr};return v;`;\n }\n\n /**\n * Read an individual field.\n * @internal\n */\n private _$readField(fieldIndex: number, state: BufferReader, obj?: any): any {\n const field = this._$fields[fieldIndex];\n\n if (field.$isOptional && !coders.boolCoder.$read(state)) {\n return undefined;\n }\n\n if (field.$isArray) {\n return this._$readArray(field.$coder, state, obj);\n }\n\n return field.$coder._$read(state, obj);\n }\n\n /**\n * Compile the decode() method for this object.\n *\n * @internal\n */\n private _$compileFormatReadFn>(): (state: BufferReader, obj: Partial | undefined) => DecodedType {\n if (this._$type !== undefined) {\n // scalar type\n return this._$hasValidationOrTransforms\n ? (s) => this._$postprocess(readers[this._$type](s))\n : readers[this._$type];\n }\n\n // object type\n return new Function(\"s\", \"o\", this._$makeObjectReadFnBody()) as any;\n }\n\n /**\n * @internal\n */\n private _$writeArray(value: any[], bw: BufferWriter, type: BufferFormat): void {\n if (!Array.isArray(value)) {\n throw new TypeError(`expected array, instead got: ${value}`);\n }\n\n coders.uintCoder.$write(value.length, bw);\n for (let i = 0; i < value.length; i++) {\n type._$write(value[i], bw);\n }\n }\n\n /**\n * @throws if invalid data\n * @internal\n */\n private _$readArray(type: BufferFormat, state: any, obj?: Array): Array {\n const len = coders.uintCoder.$read(state);\n const arr = obj?.length === len ? obj : new Array(len);\n for (let j = 0; j < arr.length; j++) {\n arr[j] = type._$read(state, obj?.[j]);\n }\n return arr;\n }\n}\n\n/**\n * Parses and represents an object field.\n *\n * @internal\n */\nclass Field {\n public $name: string;\n public $coder: BufferFormat;\n public $isOptional: boolean;\n public $isArray: boolean;\n\n private _$formatString?: string;\n\n public constructor(name: string, rawType: FieldDefinition) {\n this.$isOptional = rawType instanceof MaybeType;\n let type = rawType instanceof MaybeType ? rawType.type : rawType;\n\n this.$name = name;\n\n if (Array.isArray(type)) {\n if (type.length !== 1) {\n throw new TypeError(\"Array type must contain exactly one format\");\n }\n\n type = type[0];\n this.$isArray = true;\n }\n else {\n this.$isArray = false;\n }\n\n this.$coder = new BufferFormat(type, null);\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public get f(): string {\n if (this._$formatString === undefined) {\n this._$formatString = `${(this.$coder as any).f}${this.$isArray ? \"[]\" : \"\"}${this.$isOptional ? \"?\" : \"\"}`;\n }\n\n return this._$formatString;\n }\n}\n"],"names":["TinybufError","Error","$hashCode","str","hash","i","length","charCodeAt","$strToHashCode","$hashCodeToStr","hashCode","String","fromCharCode","Math","floor","peekHeader","b","ArrayBuffer","isView","DataView","buffer","byteOffset","getUint16","peekHeaderStr","bufferParser","BufferParser","constructor","this","_$formats","Map","_$data","processBuffer","f","data","cb","r","header","has","get","_a","decode","set","e","err","stack","on","format","callback","decodeInPlace","ignore","forEach","clear","$floor","$ceil","ceil","$clamp","value","min","max","$roundTowardZero","x","$roundAwayFromZero","uscalround","$fromuscal8","$touscal8","scalround","$fromscal8","$toscal8","Type","UInt","UInt8","UInt16","UInt32","Int","Int8","Int16","Int32","Float64","Float32","Float16","BFloat16","Scalar8","UScalar8","Bool","Bools","Buffer","JSON","RegExp","Date","ValidTypes","Object","values","MaybeType","type","optional","t","mask","padBit","reduce","n","unmask","l","len","undefined","clz32","Array","isArray","val","$utf8encode","encoder","TextEncoder","encode","$utf8decode","decoder","TextDecoder","y","f16round","$fromf16","$tof16","Float32Array","Int32Array","s","z","pow","d","m","Infinity","NaN","Uint32Array","bf16round","MAX_VARUINT32","MAX_VARINT32","POW_32","uintCoder","$write","writer","Number","$writeUint8","$writeUint16","$writeUint32","$read","reader","firstByte","$peek","$readUint32","$readUint16","$skip","uint8Coder","$readUint8","uint16Coder","uint32Coder","intCoder","int8Coder","$writeInt8","$readInt8","int16Coder","$writeInt16","$readInt16","int32Coder","$writeInt32","$readInt32","bfloat16Coder","$tobf16","$frombf16","float16Coder","float32Coder","$writeFloat32","$readFloat32","float64Coder","$writeFloat64","$readFloat64","uscalar8Coder","scalar8Coder","dateCoder","getTime","bufferCoder","byteLength","$writeBytes","$readBytes","stringCoder","boolCoder","boolsCoder","slice","p","jsonCoder","stringify","parse","regexCoder","global","ignoreCase","multiline","source","g","writers","readers","setTinybufConfig","c","cfg","assign","safe","useGlobalEncodingBuffer","encodingBufferMaxSize","encodingBufferInitialSize","encodingBufferIncrement","BufferWriter","initialSize","_$dataView","$viewBytes","Uint8Array","$copyBytes","setInt8","_$alloc","setInt16","setInt32","setUint8","setUint16","setUint32","setFloat32","setFloat64","j","bBytes","bytes","minBytesNeeded","requestedNewBytes","_$resizeBuffer","newSize","newBuf","oldView","BufferReader","headerBytes","getUint8","getUint32","getInt8","getInt16","getInt32","getFloat32","getFloat64","RangeError","view","defineFormat","a","BufferFormat","encodingBuffer","_$writer","def","_$hasValidationOrTransforms","includes","_$type","TypeError","_$fieldsMap","_$fields","keys","map","name","Field","_$header","isValidHeader","h","isInteger","_$format","v","join","_$initWriter","_$globalWriter","preserveBytes","_$preprocess","_$write","decodeInto","_$read","setTransforms","transforms","_$transforms","field","$coder","setValidation","validations","_$validate","bw","safeValue","subValue","$name","$isOptional","coders.boolCoder","$isArray","_$writeArray","_$processValidation","_$postprocess","res","state","obj","_$compileFormatReadFn","_$makeObjectReadFnBody","fieldsStr","_$readField","fieldIndex","_$readArray","Function","coders.uintCoder","arr","rawType","_$formatString"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.mjs","sources":["../src/core/lib/errors.ts","../src/core/lib/hashCode.ts","../src/core/lib/peek.ts","../src/core/BufferParser.ts","../src/core/lib/math.ts","../src/core/lib/scalar.ts","../src/core/Type.ts","../src/core/lib/bitmask.ts","../src/core/lib/utf8.ts","../src/core/lib/float16.ts","../src/core/lib/bfloat16.ts","../src/core/lib/coders.ts","../src/core/config.ts","../src/core/lib/BufferWriter.ts","../src/core/lib/BufferReader.ts","../src/core/BufferFormat.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unified-signatures */\n\nexport class TinybufError extends Error {}\n","/**\n * DJB2 hash algorithm (modified for 16-bit uints).\n *\n * DJB2 is a simple and widely used non-cryptographic\n * hash function created by Daniel J. Bernstein.\n *\n * @returns 16-bit unsigned integer\n */\nexport function $hashCode(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash * 33) ^ str.charCodeAt(i);\n }\n return hash & 0xFFFF; // Ensure the result is a Uint16\n}\n\n/**\n * Returns an unsigned 16-bit integer hashcode for some string.\n * Prefers 2 character string.\n *\n * @returns A UInt16 between 0 and 65535 (inclusive).\n */\nexport function $strToHashCode(str: string): number {\n if (str.length !== 2) return $hashCode(str);\n return str.charCodeAt(0) * 256 + str.charCodeAt(1);\n}\n\n/**\n * Convert a UInt16 hashcode to a 2-byte string.\n */\nexport function $hashCodeToStr(hashCode: number): string {\n return String.fromCharCode(Math.floor(hashCode / 256)) + String.fromCharCode(hashCode % 256);\n}\n","import { $hashCodeToStr } from \"./hashCode\";\n\n\n/**\n * Read the header bytes of a buffer as a number.\n *\n * @throws {RangeError} if buffer size < 2\n */\nexport function peekHeader(b: ArrayBuffer | ArrayBufferView): number {\n return (ArrayBuffer.isView(b) ? new DataView(b.buffer, b.byteOffset, 2) : new DataView(b, 0, 2)).getUint16(0, false);\n}\n\n/**\n * Read the header bytes of a buffer as a string.\n *\n * @throws {RangeError} if buffer length < 2\n */\nexport function peekHeaderStr(b: ArrayBuffer | ArrayBufferView): string {\n return $hashCodeToStr(peekHeader(b));\n}\n","import { BufferFormat } from \"./BufferFormat\";\nimport { EncoderDefinition, DecodedType } from \"./Type\";\nimport { TinybufError } from \"./lib/errors\";\nimport { $hashCodeToStr, $strToHashCode } from \"./lib/hashCode\";\nimport { peekHeader } from \"./lib/peek\";\n\ntype AnyFormat = BufferFormat;\ntype Uint16FormatHeader = number;\n\n/**\n * Small utility for registering and processing format handlers.\n *\n * @example\n * const myHandler = bufferParser()\n * .on(FormatA, aData => {})\n * .on(FormatB, bData => {});\n *\n * myHandler.processBuffer(bytes);\n */\nexport const bufferParser = (): BufferParser => new BufferParser();\n\nexport class BufferParser {\n /** @internal */\n private _$formats = new Map any, decodeInPlace: boolean]>();\n private _$data = new Map(); // used when decoding in-place\n\n /**\n * Decode an array buffer and trigger the relevant data handler.\n *\n * When passed an ArrayBufferView, accesses the underlying 'buffer' instance directly.\n *\n * @throws {TinybufError} if fails to decode, or no handler is registered\n */\n public processBuffer(b: ArrayBuffer | ArrayBufferView): void {\n let f: any, data: any, cb: (data: any) => any, r: boolean;\n\n try {\n const header = peekHeader(b);\n\n if (!this._$formats.has(header)) {\n throw new TinybufError(`Unknown format: ${header} '${$hashCodeToStr(header)}')`);\n }\n\n [f, cb, r] = this._$formats.get(header);\n if (r) data = this._$data.get(header) ?? {};\n data = f.decode(b, data);\n if (r) this._$data.set(header, data);\n }\n catch (e) {\n const err = new TinybufError(`Failed to decode: ${e}`);\n err.stack = e.stack;\n\n throw err;\n }\n\n cb(data);\n }\n\n /**\n * Register a format handler.\n */\n public on>(\n format: BufferFormat,\n callback: (data: TDecodedType) => any,\n {\n decodeInPlace = false,\n } = {},\n ): this {\n if (format.header == null) {\n throw new TinybufError(\"Format requires header\");\n }\n\n const header = typeof format.header === \"string\" ? $strToHashCode(format.header) : format.header;\n\n if (this._$formats.has(header) && this._$formats.get(header)?.[0] !== format) {\n throw new TinybufError(`Format header collision: ${format.header}`);\n }\n\n this._$formats.set(header, [format, callback, decodeInPlace]);\n\n return this;\n }\n\n /** Register a format (or formats) that are recognized. */\n public ignore(...format: AnyFormat[]): this {\n format.forEach(f => this.on(f, () => {}));\n return this;\n }\n\n /** Clears all registered formats and handlers. */\n public clear(): void {\n this._$formats.clear();\n this._$data.clear();\n }\n}\n","export const $floor = Math.floor,\n $ceil = Math.ceil;\n\n/** Clamp a number to a range. */\nexport const $clamp = (value: number, min: number, max: number): number =>\n value > max ? max : value < min ? min : value;\n\n/** Round toward zero */\nexport const $roundTowardZero = (x: number): number => x < 0 ? $ceil(x) : $floor(x);\n\n/** Round away zero */\nexport const $roundAwayFromZero = (x: number): number =>\n x < 0 ? $floor(x) : $ceil(x);\n","import { $clamp, $roundTowardZero, $roundAwayFromZero } from \"./math\";\n\n/**\n * Quantize a number to an 8-bit scalar between 0.0 and 1.0.\n *\n * @returns A number (double) in its closest signed scalar representation.\n */\nexport function uscalround(x: number): number {\n return $fromuscal8($touscal8(x));\n}\n\n/**\n * Quantize a number to an 8-bit signed scalar between -1.0 and 1.0.\n *\n * @returns A number (double) in its closest signed scalar representation.\n */\nexport function scalround(x: number): number {\n return $fromscal8($toscal8(x));\n}\n\n/** @returns A UInt8 bitmask representation. */\nexport function $touscal8(x: number): number {\n return $clamp(127 + $roundTowardZero(x * 254 - 127), 0, 254);\n}\n\n/** @returns A UInt8 bitmask representation. */\nexport function $toscal8(x: number): number {\n return $clamp($roundTowardZero(x * 127), -127, 127) + 127;\n}\n\n/** @returns An unsigned scalar between 0.0 and 1.0. */\nexport function $fromuscal8(x: number): number {\n // Make symmetric: (0.5 + round((uint8 - 127) / 254 * 100)) / 100\n return $clamp(($roundAwayFromZero((x - 127) * 0.3937007874015748) + 50) * 0.01, 0, 1);\n}\n\n/** @returns A signed scalar between -1.0 and 1.0. */\nexport function $fromscal8(x: number): number {\n // Make symmetric: round((uint8 - 127) / 127 * 100) / 100\n return $clamp($roundAwayFromZero((x - 127) * 0.787401574803149) * 0.01, -1, 1);\n}\n","/**\n * Field types for defining encoding formats.\n *\n * @see [Types](https://github.com/reececomo/tinybuf/blob/main/docs/types.md)\n */\nexport const Type = {\n /**\n * Unsigned integer (1 - 8 bytes).\n * - 0 → 127 = 1 byte\n * - 128 → 16,384 = 2 bytes\n * - 16,385 → 536,870,911 = 4 bytes\n * - 536,870,912 → `Number.MAX_SAFE_INTEGER` = 8 bytes\n */\n UInt: \"uint\",\n\n /** Unsigned 8-bit integer (between 0 and 255, 1 byte). */\n UInt8: \"u8\",\n\n /** Unsigned 16-bit integer (between 0 and 65,535, 2 bytes). */\n UInt16: \"u16\",\n\n /** Unsigned 32-bit integer (between 0 and 4,294,967,295, 4 bytes). */\n UInt32: \"u32\",\n\n /**\n * Signed integer (1 - 8 bytes).\n * - 0 → ±64 = 1 byte\n * - ±65 → ±8,192 = 2 bytes\n * - ±8,193 → ±268,435,456 = 4 bytes\n * - ±268,435,457 → ±`Number.MAX_SAFE_INTEGER` = 8 bytes\n */\n Int: \"int\",\n\n /** Signed 1 byte integer (between -127 and 127). */\n Int8: \"i8\",\n\n /** Signed 2 byte integer (between -32,767 and 32,767). */\n Int16: \"i16\",\n\n /** Signed 4 byte integer (between -2,147,483,647 and 2,147,483,647). */\n Int32: \"i32\",\n\n /** Default JavaScript `number` type. Floating-point number (64-bit, double precision, 8 bytes). */\n Float64: \"f64\",\n\n /** Floating-point number (32-bit, single precision, 4 bytes). */\n Float32: \"f32\",\n\n /**\n * Floating-point number (16-bit in FP16 format, half precision, 2 bytes).\n *\n * **Warning:** Low precision; maximum range: ±65,504.\n */\n Float16: \"f16\",\n\n /**\n * Floating-point number (16-bit in BF16 format, half precision, 2 bytes).\n *\n * **Warning:** Low precision.\n */\n BFloat16: \"b16\",\n\n /** A signed 2-decimal scalar between -1.00 and 1.00 (1 byte). */\n Scalar8: \"sc\",\n\n /** An unsigned 2-decimal scalar between 0.00 and 1.00 (1 byte). */\n UScalar8: \"usc\",\n\n /**\n * Boolean value (1 byte).\n * @see {Bools} for packing multiple booleans into a single byte.\n */\n Bool: \"bl\",\n\n /** Any array of booleans (1 bit overhead, encoded as UInt). */\n Bools: \"bls\",\n\n /** Any ArrayBuffer or ArrayBufferView (e.g. Uint8Array) value (encoded as 1 x UInt for byte length + buffer bytes). */\n Buffer: \"buf\",\n\n /** A UTF-8 string (encoded as 1 x UInt for UTF-8 byte length + UTF-8 bytes). */\n String: \"str\",\n\n /** Any JSON data (encodes as UTF-8). */\n JSON: \"jsn\",\n\n /** JavaScript RegExp object. */\n RegExp: \"re\",\n\n /**\n * JavaScript Date object.\n *\n * Encoded as an 8 byte (64-bit) integer UTC timestamp from as the number\n * of milliseconds since the Unix Epoch (January 1, 1970, 00:00:00 UTC).\n *\n * @see {Date}\n */\n Date: \"dt\",\n} as const;\n\nexport type TypeLiteral = typeof Type[keyof typeof Type];\nexport const ValidTypes = Object.values(Type);\n\n/**\n * Mappings for the value types.\n */\nexport type ValueTypes = {\n [Type.Int]: number;\n [Type.Int8]: number;\n [Type.Int16]: number;\n [Type.Int32]: number;\n [Type.UInt]: number;\n [Type.UInt8]: number;\n [Type.UInt16]: number;\n [Type.UInt32]: number;\n [Type.Float64]: number;\n [Type.Float32]: number;\n [Type.Float16]: number;\n [Type.BFloat16]: number;\n [Type.Scalar8]: number;\n [Type.UScalar8]: number;\n [Type.Bool]: boolean;\n [Type.Bools]: boolean[];\n [Type.Buffer]: Uint8Array | ArrayBuffer | ArrayBufferView;\n [Type.String]: string;\n [Type.JSON]: any;\n [Type.RegExp]: RegExp;\n [Type.Date]: Date;\n};\n\n/** https://www.totaltypescript.com/concepts/the-prettify-helper */\ntype Pretty = T extends ArrayBuffer | ArrayBufferView | Date | RegExp | Uint8Array ? T\n : T extends Array ? Array>\n : T extends object ? {[K in keyof T]: Pretty} & unknown : T;\n\n/** @throws any error too */\nexport type ValidationFn = (x: T) => undefined | boolean | Error;\nexport type TransformFn = (x: T) => T;\nexport type Transforms = TransformFn | [preEncode: TransformFn] | [preEncode: TransformFn | undefined, postDecode: TransformFn | undefined];\n\n/**\n * A wrapper around any Type definition that declares it as optional.\n */\nexport class MaybeType {\n public constructor(public type: T) {}\n}\n\n/**\n * Wrap any definition as optional.\n */\nexport function optional(t: T): MaybeType {\n return new MaybeType(t);\n}\n\n/**\n * A definition for an object binary encoder.\n */\nexport type EncoderDefinition = {\n [key: string]: FieldDefinition | MaybeType;\n};\n\n/**\n * Definition for an object-field binary encoder.\n */\nexport type FieldDefinition = keyof ValueTypes | [keyof ValueTypes] | EncoderDefinition | [EncoderDefinition] | MaybeType;\n\n/**\n * The resulting type of the decoded data, based on the encoder definition.\n */\ntype RawDecodedType = {\n [EKey in keyof EncoderType as EncoderType[EKey] extends MaybeType ? never : EKey]: EncoderType[EKey] extends keyof ValueTypes\n ? ValueTypes[EncoderType[EKey]]\n : EncoderType[EKey] extends [keyof ValueTypes]\n ? Array\n : EncoderType[EKey] extends EncoderDefinition\n ? RawDecodedType\n : EncoderType[EKey] extends [EncoderDefinition]\n ? Array>\n : never;\n} & {\n [EKey in keyof EncoderType as EncoderType[EKey] extends MaybeType ? EKey : never]?: EncoderType[EKey] extends MaybeType\n ? ValueTypes[OptionalValue] | undefined\n : EncoderType[EKey] extends MaybeType\n ? Array | undefined\n : EncoderType[EKey] extends MaybeType\n ? RawDecodedType | undefined\n : never;\n};\n\nexport type DecodedType = Pretty>;\n\nexport type TransformConfig = {\n [EKey in keyof EncoderType]?: EncoderType[EKey] extends keyof ValueTypes\n ? Transforms\n : EncoderType[EKey] extends [keyof ValueTypes]\n ? Transforms\n : EncoderType[EKey] extends EncoderDefinition\n ? TransformConfig\n : EncoderType[EKey] extends [EncoderDefinition]\n ? TransformConfig\n : EncoderType[EKey] extends MaybeType\n ? Transforms\n : EncoderType[EKey] extends MaybeType\n ? Transforms\n : EncoderType[EKey] extends MaybeType\n ? TransformConfig | undefined\n : never;\n};\n\nexport type ValidationConfig = {\n [EKey in keyof EncoderType]?: EncoderType[EKey] extends keyof ValueTypes\n ? ValidationFn\n : EncoderType[EKey] extends [keyof ValueTypes]\n ? ValidationFn\n : EncoderType[EKey] extends EncoderDefinition\n ? ValidationConfig\n : EncoderType[EKey] extends [EncoderDefinition]\n ? ValidationConfig\n : EncoderType[EKey] extends MaybeType\n ? ValidationFn\n : EncoderType[EKey] extends MaybeType\n ? ValidationFn\n : EncoderType[EKey] extends MaybeType\n ? ValidationConfig | undefined\n : never;\n};\n","/**\n * Mask booleans to a uint32.\n *\n * @param x - A boolean array.\n * @param padBit - A bit to pad the mask (for variable length data).\n */\nexport const mask = (x: boolean[], padBit: 0 | 1 = 0b1): number => {\n return x.reduce((n, b: any) => (n << 1) | b, padBit);\n};\n\n/**\n * Unmask booleans from a uint32.\n *\n * @param x - A uint32 number.\n * @param l - number of booleans to expect (default: infer lenth from x where x is encoded with a pad bit)\n * or pass an existing boolean array to decode in-place.\n */\nexport const unmask = (x: number, l?: number | boolean[]): boolean[] => {\n const len = l === undefined ? 31 - Math.clz32(x) : Array.isArray(l) ? l.length : l;\n const val = Array.isArray(l) && l.length === len ? l : new Array(len);\n for (let i = 0; i < len; i++) val[i] = !!(x & (1 << (len - 1 - i)));\n return val;\n};\n","export const $utf8encode = (function () {\n const encoder = new TextEncoder();\n return (x?: string): Uint8Array => encoder.encode(x);\n})();\n\nexport const $utf8decode = (function () {\n const decoder = new TextDecoder(\"utf-8\");\n return (y: Uint8Array): string => decoder.decode(y);\n})();\n","/**\n * Returns the nearest half precision float representation of a number.\n * @param x A numeric expression.\n */\nexport function f16round(x: number): number {\n return $fromf16($tof16(x));\n}\n\n/**\n * Returns the nearest half precision float representation of a number as a 16-bit bitmask.\n */\nexport const $tof16 = (function() {\n const x = new Float32Array(1);\n const y = new Int32Array(x.buffer);\n\n return function (f: number) {\n x[0] = f;\n let i = y[0]; // 32-bit int\n let s = (i >> 16) & 0X8000; // sign\n let z = (i & 0X7FFFFFFF) + 0X1000 | 0;\n\n if (z >= 0X47800000) {\n if ((i & 0X7FFFFFFF) < 0X47800000) return s | 0X7BFF;\n if (z < 0X7F800000) return s | 0X7C00;\n return s | 0X7C00 | (i & 0X007FFFFF) >> 13;\n }\n if (z >= 0X38800000) return s | z - 0X38000000 >> 13;\n else if (z < 0X33000000) return s;\n z = (i & 0X7FFFFFFF) >> 23;\n return s | ((i & 0X7FFFFF | 0X800000)\n + (0X800000 >>> z - 102)\n >> 126 - z);\n };\n}());\n\n/**\n * Returns the nearest half precision float value for a 16-bit bitmask.\n */\nexport const $fromf16 = (function() {\n const z = Math.pow(2, -24); // subnormal constant\n const d = new Float32Array(32 + 1024);\n for (let e = 0; e < 32; e++) d[e] = Math.pow(2, e - 15); // biased exponents\n for (let m = 0; m < 1024; m++) d[m + 0x20] = 1 + m / 1024; // normalized offset mantissas\n\n return function (b: number): number {\n const s = (b & 32768) === 32768 ? -1 : 1; // sign: 1 bit\n const e = b & 31744; // exponent: 5 bits\n const m = b & 1023; // mantissa: 10 bits\n\n if (e === 0) return m === 0 ? s * 0 : s * z;\n if (e === 31744) return m === 0 ? s * Infinity : NaN;\n return d[e >> 10] * d[m + 0x20] * s;\n };\n}());\n","const i = new Uint32Array(1);\nconst f = new Float32Array(i.buffer);\n\n/**\n * Returns the nearest bfloat16 representation of a number.\n * @param x A numeric expression.\n */\nexport function bf16round(x: number): number {\n f[0] = x;\n i[0] = i[0] & 0xFFFF0000;\n return f[0];\n}\n\n/** Returns a 16-bit bfloat16 bitmask for a given float. */\nexport function $tobf16(x: number): number {\n f[0] = x;\n return i[0] >>> 16;\n}\n\n/** Returns the nearest value from a 16-bit bfloat16 bitmask. */\nexport function $frombf16(x: number): number {\n i[0] = x << 16;\n return f[0];\n}\n","import { BufferWriter } from \"./BufferWriter\";\nimport { BufferReader } from \"./BufferReader\";\nimport {\n $fromuscal8,\n $fromscal8,\n $touscal8,\n $toscal8\n} from \"./scalar\";\nimport { TypeLiteral, Type } from \"../Type\";\nimport { mask, unmask } from \"./bitmask\";\nimport { $utf8decode, $utf8encode } from \"./utf8\";\nimport { $floor } from \"./math\";\nimport { $fromf16, $tof16 } from \"./float16\";\nimport { $frombf16, $tobf16 } from \"./bfloat16\";\n\n// Pre-calculated constants\nconst MAX_VARUINT8 = 128,\n MAX_VARUINT16 = 16_384,\n MAX_VARUINT32 = 536_870_912,\n MAX_VARINT8 = 64,\n MAX_VARINT16 = 8_192,\n MAX_VARINT32 = 268_435_456,\n POW_32 = 0x100000000;\n\ntype WriterFn = (value: W, writer: BufferWriter) => void;\ntype ReaderFn = (reader: BufferReader, overwrite?: Partial) => R;\n\nexport interface BinaryTypeCoder {\n $write: WriterFn;\n $read: ReaderFn;\n}\n\n/**\n * Format (big-endian):\n * 7b 0xxxxxxx\n * 14b 10xxxxxx xxxxxxxx\n * 29b 110xxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n * 61b 111xxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n */\nexport const uintCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n if (typeof value !== \"number\") value = Number(value);\n if (value < 0) value = 0;\n if (value < MAX_VARUINT8) writer.$writeUint8(value);\n else if (value < MAX_VARUINT16) writer.$writeUint16(value + 0x8000);\n else if (value < MAX_VARUINT32) writer.$writeUint32(value + 0xc0000000);\n else if (value >= MAX_VARUINT32) {\n writer.$writeUint32($floor(value / POW_32) + 0xe0000000);\n writer.$writeUint32(value >>> 0);\n }\n else {\n // coercion case\n writer.$writeUint8(value as any === true ? 1 : 0);\n }\n },\n $read: (reader) => {\n const firstByte = reader.$peek();\n\n if (!(firstByte & 0x80)) {\n reader.$skip();\n return firstByte;\n }\n else if (!(firstByte & 0x40)) {\n return reader.$readUint16() - 0x8000;\n }\n else if (!(firstByte & 0x20)) {\n return reader.$readUint32() - 0xc0000000;\n }\n\n return (reader.$readUint32() - 0xe0000000) * POW_32\n + reader.$readUint32();\n }\n};\n\nexport const uint8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8(value),\n $read: (reader) => reader.$readUint8(),\n};\n\nexport const uint16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint16(value),\n $read: (reader) => reader.$readUint16(),\n};\n\nexport const uint32Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint32(value),\n $read: (reader) => reader.$readUint32(),\n};\n\n/**\n * Format (big-endian):\n * 7b 0xxxxxxx\n * 14b 10xxxxxx xxxxxxxx\n * 29b 110xxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n * 61b 111xxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx\n */\nexport const intCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n if (typeof value !== \"number\") value = Number(value);\n if (value >= -MAX_VARINT8 && value < MAX_VARINT8) writer.$writeUint8(value & 0x7f);\n else if (value >= -MAX_VARINT16 && value < MAX_VARINT16) writer.$writeUint16((value & 0x3fff) + 0x8000);\n else if (value >= -MAX_VARINT32 && value < MAX_VARINT32) writer.$writeUint32((value & 0x1fffffff) + 0xc0000000);\n else if (value < -MAX_VARINT32 || value >= MAX_VARINT32) {\n // Split in two 32b uints\n writer.$writeUint32(($floor(value / POW_32) & 0x1fffffff) + 0xe0000000);\n writer.$writeUint32(value >>> 0);\n }\n else {\n // coercion case\n writer.$writeUint8(value as any === true ? 0x7f : 0);\n }\n },\n $read: (reader) => {\n let firstByte = reader.$peek(), i: number;\n\n if (!(firstByte & 0x80)) {\n reader.$skip();\n return (firstByte & 0x40) ? (firstByte | 0xffffff80) : firstByte;\n }\n else if (!(firstByte & 0x40)) {\n i = reader.$readUint16() - 0x8000;\n return (i & 0x2000) ? (i | 0xffffc000) : i;\n }\n else if (!(firstByte & 0x20)) {\n i = reader.$readUint32() - 0xc0000000;\n return (i & 0x10000000) ? (i | 0xe0000000) : i;\n }\n else {\n i = reader.$readUint32() - 0xe0000000;\n i = (i & 0x10000000) ? (i | 0xe0000000) : i;\n return i * POW_32 + reader.$readUint32();\n }\n }\n};\n\nexport const int8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeInt8(value),\n $read: (reader) => reader.$readInt8(),\n};\n\nexport const int16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeInt16(value),\n $read: (reader) => reader.$readInt16(),\n};\n\nexport const int32Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeInt32(value),\n $read: (reader) => reader.$readInt32(),\n};\n\nexport const bfloat16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint16($tobf16(value)),\n $read: (reader) => $frombf16(reader.$readUint16()),\n};\n\nexport const float16Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint16($tof16(value)),\n $read: (reader) => $fromf16(reader.$readUint16()),\n};\n\nexport const float32Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeFloat32(value),\n $read: (reader) => reader.$readFloat32(),\n};\n\nexport const float64Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeFloat64(value),\n $read: (reader) => reader.$readFloat64(),\n};\n\nexport const uscalar8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8($touscal8(value)),\n $read: (reader) => $fromuscal8(reader.$readUint8()),\n};\n\nexport const scalar8Coder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8($toscal8(value)),\n $read: (reader) => $fromscal8(reader.$readUint8()),\n};\n\nexport const dateCoder: BinaryTypeCoder = {\n $write: (value, writer) => intCoder.$write(value.getTime(), writer),\n $read: (reader) => new Date(intCoder.$read(reader)),\n};\n\nexport const bufferCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n uintCoder.$write(value.byteLength, writer); // prefix length\n writer.$writeBytes(value);\n },\n $read: (reader) => reader.$readBytes(uintCoder.$read(reader)),\n};\n\nexport const stringCoder: BinaryTypeCoder = {\n $write: (value, writer) => bufferCoder.$write($utf8encode(value), writer),\n $read: (reader) => $utf8decode(bufferCoder.$read(reader)),\n};\n\nexport const boolCoder: BinaryTypeCoder = {\n $write: (value, writer) => writer.$writeUint8(value ? 1 : 0),\n $read: (reader) => reader.$readUint8() !== 0,\n};\n\nexport const boolsCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n if (value.length > 28) value = value.slice(0, 28); // drop additional\n uintCoder.$write(mask(value), writer);\n },\n $read: (reader, p) => unmask(uintCoder.$read(reader), p),\n};\n\nexport const jsonCoder: BinaryTypeCoder = {\n $write: (value, writer) => stringCoder.$write(JSON.stringify(value), writer),\n $read: (reader) => JSON.parse(stringCoder.$read(reader)),\n};\n\nexport const regexCoder: BinaryTypeCoder = {\n $write: (value, writer) => {\n writer.$writeUint8(mask([value.global, value.ignoreCase, value.multiline]));\n stringCoder.$write(value.source, writer);\n },\n $read: (reader) => {\n const [g, i, m] = unmask(reader.$readUint8());\n return new RegExp(stringCoder.$read(reader), (g ? \"g\" : \"\") + (i ? \"i\" : \"\") + (m ? \"m\" : \"\"));\n }\n};\n\nexport const writers: Record> = {\n [Type.UInt]: uintCoder.$write,\n [Type.UInt8]: uint8Coder.$write,\n [Type.UInt16]: uint16Coder.$write,\n [Type.UInt32]: uint32Coder.$write,\n [Type.Int]: intCoder.$write,\n [Type.Int8]: int8Coder.$write,\n [Type.Int16]: int16Coder.$write,\n [Type.Int32]: int32Coder.$write,\n [Type.Float64]: float64Coder.$write,\n [Type.Float32]: float32Coder.$write,\n [Type.Float16]: float16Coder.$write,\n [Type.BFloat16]: bfloat16Coder.$write,\n [Type.Scalar8]: scalar8Coder.$write,\n [Type.UScalar8]: uscalar8Coder.$write,\n [Type.Bool]: boolCoder.$write,\n [Type.Bools]: boolsCoder.$write,\n [Type.Buffer]: bufferCoder.$write,\n [Type.String]: stringCoder.$write,\n [Type.JSON]: jsonCoder.$write,\n [Type.RegExp]: regexCoder.$write,\n [Type.Date]: dateCoder.$write,\n};\n\nexport const readers: Record> = {\n [Type.UInt]: uintCoder.$read,\n [Type.UInt8]: uint8Coder.$read,\n [Type.UInt16]: uint16Coder.$read,\n [Type.UInt32]: uint32Coder.$read,\n [Type.Int]: intCoder.$read,\n [Type.Int8]: int8Coder.$read,\n [Type.Int16]: int16Coder.$read,\n [Type.Int32]: int32Coder.$read,\n [Type.Float64]: float64Coder.$read,\n [Type.Float32]: float32Coder.$read,\n [Type.Float16]: float16Coder.$read,\n [Type.BFloat16]: bfloat16Coder.$read,\n [Type.Scalar8]: scalar8Coder.$read,\n [Type.UScalar8]: uscalar8Coder.$read,\n [Type.Bool]: boolCoder.$read,\n [Type.Bools]: boolsCoder.$read,\n [Type.Buffer]: bufferCoder.$read,\n [Type.String]: stringCoder.$read,\n [Type.JSON]: jsonCoder.$read,\n [Type.RegExp]: regexCoder.$read,\n [Type.Date]: dateCoder.$read,\n};\n","/** Default maximum transmission unit in networking */\nconst MTU = 1500;\n\n/** Set Tinybuf global config */\nexport const setTinybufConfig = (c: Partial): void => {\n cfg = { ...cfg, ...c };\n};\n\nexport type TinybufConfig = {\n /**\n * (default: false)\n *\n * This sets the default value for `preserveBytes` on\n * `encode(data, preserveBytes?)`.\n *\n * By default, `encode()` returns its encoded bytes as a `Uint8Array`\n * view of the bytes in the shared encoding buffer.\n *\n * This is suitable for synchronous use (e.g. high-performance applications)\n * as it avoids slow and expensive memory allocation and fragmentation on\n * each call to `encode()`.\n *\n * However, susbsequent calls are destructive to the underlying bytes, so\n * for asynchronous uses (e.g. Promises, Workers, long-lived storage), set\n * `preserveBytes` to `true`.\n */\n safe: boolean,\n\n /**\n * (default: true)\n * By default, format encoders share a global encoding buffer for performance\n * and memory management reasons.\n *\n * When set to false, each format is allocated an individual encoding buffer.\n *\n * Enable to maximise performance and memory re-use, just be cautious of\n * possible race conditions.\n */\n useGlobalEncodingBuffer: boolean,\n\n /**\n * (default: 1500)\n * The maximum bytes that can be allocated to an encoding buffer.\n *\n * Default is 1500 bytes, the standard \"Maximum Transmission Unit\".\n */\n encodingBufferMaxSize: number,\n\n /**\n * (default: 256)\n * Initial bytes to allocate for an encoding buffer.\n */\n encodingBufferInitialSize: number,\n\n /**\n * (default: 256)\n * Additional bytes to allocated when dynamically increasing the size of an encoding buffer.\n */\n encodingBufferIncrement: number,\n};\n\n/** @internal */\nexport let cfg: TinybufConfig = {\n safe: false,\n useGlobalEncodingBuffer: true,\n encodingBufferMaxSize: MTU,\n encodingBufferInitialSize: 256,\n encodingBufferIncrement: 256,\n};\n","import { cfg } from \"../config\";\nimport { TinybufError } from \"./errors\";\n\n/**\n * Wraps a buffer with a write head pointer.\n *\n * @internal\n */\nexport class BufferWriter {\n public $byteLength: number = 0;\n public _$dataView: DataView;\n private _$writeHead: number = 0;\n\n public constructor(initialSize: number) {\n this._$dataView = new DataView(new ArrayBuffer(initialSize));\n }\n\n public $viewBytes(): Uint8Array {\n return new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset, this.$byteLength);\n }\n\n public $copyBytes(): Uint8Array {\n return new Uint8Array(this._$dataView.buffer.slice(0, this.$byteLength));\n }\n\n // ----- Writers: -----\n\n public $writeInt8(value: number): void {\n this._$alloc(1).setInt8(this._$writeHead, value);\n }\n\n public $writeInt16(value: number): void {\n this._$alloc(2).setInt16(this._$writeHead, value, true);\n }\n\n public $writeInt32(value: number): void {\n this._$alloc(4).setInt32(this._$writeHead, value, true);\n }\n\n public $writeUint8(value: number): void {\n this._$alloc(1).setUint8(this._$writeHead, value);\n }\n\n public $writeUint16(value: number): void {\n this._$alloc(2).setUint16(this._$writeHead, value, false); // big-endian for varint\n }\n\n public $writeUint32(value: number): void {\n this._$alloc(4).setUint32(this._$writeHead, value, false); // big-endian for varint\n }\n\n public $writeFloat32(value: number): void {\n this._$alloc(4).setFloat32(this._$writeHead, value, true);\n }\n\n public $writeFloat64(value: number): void {\n this._$alloc(8).setFloat64(this._$writeHead, value, true);\n }\n\n public $writeBytes(b: Uint8Array | ArrayBuffer | ArrayBufferView): void {\n // allocate bytes first\n this._$alloc(b.byteLength);\n\n let bBytes: Uint8Array = ArrayBuffer.isView(b)\n ? b instanceof Uint8Array\n ? b\n : new Uint8Array(b.buffer, b.byteOffset, b.byteLength)\n : new Uint8Array(b);\n\n // copy bytes\n new Uint8Array(\n this._$dataView.buffer,\n this._$dataView.byteOffset + this._$writeHead,\n b.byteLength\n ).set(bBytes);\n }\n\n // ----- Private methods: -----\n\n private _$alloc(bytes: number): DataView {\n if (this.$byteLength + bytes > this._$dataView.byteLength) {\n const minBytesNeeded = this.$byteLength + bytes - this._$dataView.byteLength;\n const requestedNewBytes = Math.ceil(minBytesNeeded / cfg.encodingBufferIncrement) * cfg.encodingBufferIncrement;\n this._$resizeBuffer(this._$dataView.byteLength + requestedNewBytes);\n }\n\n this._$writeHead = this.$byteLength;\n this.$byteLength += bytes;\n\n return this._$dataView;\n }\n\n private _$resizeBuffer(newSize: number): void {\n if (newSize > cfg.encodingBufferMaxSize) {\n // safety check\n throw new TinybufError(`exceeded encodingBufferMaxSize: ${cfg.encodingBufferMaxSize}`);\n }\n\n const newBuf = new ArrayBuffer(newSize);\n\n // copy bytes\n const oldView = new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset, this._$dataView.byteLength);\n new Uint8Array(newBuf).set(oldView);\n\n // update ref\n this._$dataView = new DataView(newBuf);\n }\n}\n","/**\n * Wraps a buffer with a read head pointer.\n *\n * @internal\n */\nexport class BufferReader {\n public i: number;\n private _$dataView: DataView;\n\n public constructor(b: Uint8Array | ArrayBufferView | ArrayBuffer, headerBytes?: number) {\n this._$dataView = ArrayBuffer.isView(b)\n ? new DataView(b.buffer, b.byteOffset, b.byteLength)\n : new DataView(b);\n\n this.i = headerBytes ?? 0; // internal offset (header)\n }\n\n /** Read the next byte, without moving the read head pointer. */\n public $peek(): number {\n return this._$dataView.getUint8(this.i);\n }\n\n /** Skip the next byte without reading it. */\n public $skip(): void {\n this.i++;\n }\n\n // ----- Readers: -----\n\n public $readUint8(): number {\n return this._$dataView.getUint8(this.i++);\n }\n\n public $readUint16(): number {\n const r = this._$dataView.getUint16(this.i); // big-endian\n this.i += 2;\n return r;\n }\n\n public $readUint32(): number {\n const r = this._$dataView.getUint32(this.i); // big-endian\n this.i += 4;\n return r;\n }\n\n public $readInt8(): number {\n return this._$dataView.getInt8(this.i++);\n }\n\n public $readInt16(): number {\n const r = this._$dataView.getInt16(this.i, true); // little-endian\n this.i += 2;\n return r;\n }\n\n public $readInt32(): number {\n const r = this._$dataView.getInt32(this.i, true); // little-endian\n this.i += 4;\n return r;\n }\n\n public $readFloat32(): number {\n const r = this._$dataView.getFloat32(this.i, true); // little-endian\n this.i += 4;\n return r;\n }\n\n public $readFloat64(): number {\n const r = this._$dataView.getFloat64(this.i, true); // little-endian\n this.i += 8;\n return r;\n }\n\n /** @throws RangeError if exceeds length */\n public $readBytes(bytes: number): Uint8Array {\n if (this._$dataView.byteOffset + this.i + bytes > this._$dataView.byteLength) {\n throw new RangeError(\"exceeded bytes\");\n }\n\n const view = new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset + this.i, bytes);\n this.i += bytes;\n\n return view;\n }\n}\n","import { writers, readers } from \"./lib/coders\";\nimport * as coders from \"./lib/coders\";\nimport { $hashCode, $strToHashCode } from \"./lib/hashCode\";\nimport { peekHeader, peekHeaderStr } from \"./lib/peek\";\nimport { BufferWriter } from \"./lib/BufferWriter\";\nimport { BufferReader } from \"./lib/BufferReader\";\nimport {\n DecodedType,\n EncoderDefinition,\n FieldDefinition,\n TransformConfig,\n ValidationConfig,\n MaybeType,\n Transforms,\n TypeLiteral,\n ValidationFn,\n ValidTypes,\n} from \"./Type\";\nimport { cfg } from \"./config\";\n\nexport type FormatHeader = string | number;\n\n/**\n * Utility to get the decoded type of a buffer format\n * @example type Format = Decoded\n */\nexport type Decoded = TBufferFormat extends BufferFormat\n ? DecodedType\n : never;\n\n/**\n * Defines a format for encoding/decoding binary buffers.\n *\n * Optionally customize the identifier, either as a 2-byte string, an unsigned integer (0 -> 65,535), or as `null` to disable entirely.\n *\n * @example\n * const MyFormat = defineFormat({ ... });\n * const MyFormat = defineFormat('ab', { ... });\n * const MyFormat = defineFormat(1234, { ... });\n * const MyFormat = defineFormat(null, { ... });\n */\nexport function defineFormat(def: T): BufferFormat;\n/**\n * Defines a format for encoding/decoding binary buffers.\n *\n * Optionally customize the identifier, either as a 2-byte string, an unsigned integer (0 -> 65,535), or as `null` to disable entirely.\n *\n * @example\n * const MyFormat = defineFormat({ ... });\n * const MyFormat = defineFormat('ab', { ... });\n * const MyFormat = defineFormat(1234, { ... });\n * const MyFormat = defineFormat(null, { ... });\n */\nexport function defineFormat(h: HeaderType | null, def: T): BufferFormat;\nexport function defineFormat(a?: HeaderType | T, b?: T): BufferFormat {\n return a !== null && typeof a === \"object\"\n ? new BufferFormat(a as T)\n : new BufferFormat(b as T, a as HeaderType);\n}\n\nfunction isValidHeader(h: FormatHeader): boolean {\n if (typeof h === \"number\") return Number.isInteger(h) && h >= 0 && h <= 65_535;\n if (typeof h === \"string\") return new TextEncoder().encode(h).byteLength === 2;\n return false;\n}\n\n/**\n * BufferFormat is a utility class for encoding and decoding binary data based\n * on a provided encoding format.\n *\n * @see {header}\n * @see {encode(data)}\n * @see {decode(binary)}\n */\nexport class BufferFormat {\n /** @internal */\n private static _$globalWriter?: BufferWriter;\n\n /**\n * A unique identifier encoded as the first 2 bytes (or `undefined` if headerless).\n *\n * @see {peekHeader(...)}\n * @see {peekHeaderStr(...)}\n */\n public header!: HeaderType;\n\n /** @internal */\n private _$header!: number; // always uint16 vesion\n /** @internal */\n private _$type!: TypeLiteral;\n /** @internal */\n private _$fields!: Field[];\n /** @internal */\n private _$fieldsMap!: Map;\n\n /** @internal */\n private _$format?: string;\n /** @internal */\n private _$transforms?: Transforms | undefined;\n /** @internal */\n private _$validate?: ValidationFn | undefined;\n /** @internal */\n private _$hasValidationOrTransforms = false;\n /** @internal */\n private _$writer?: BufferWriter;\n\n public get encodingBuffer(): DataView | undefined {\n return this._$writer?._$dataView;\n }\n\n public constructor(\n def: EncoderType,\n header?: HeaderType | null,\n ) {\n // set definition\n if (typeof def === \"string\" && ValidTypes.includes(def)) {\n this._$type = def;\n }\n else if (def instanceof MaybeType) {\n throw new TypeError(\"Format cannot be optional\");\n }\n else if (def instanceof Object) {\n this._$type = undefined; // object\n this._$fieldsMap = new Map();\n this._$fields = Object.keys(def).map((name) => {\n const f = new Field(name, def[name]);\n this._$fieldsMap.set(name, f); // also set map entry\n return f;\n });\n\n // set headers\n if (header === undefined) {\n this.header = $hashCode(this.f) as HeaderType; // automatic\n this._$header = this.header as number;\n }\n else if (header === null) {\n this.header = undefined; // headerless\n this._$header = undefined;\n }\n else if (isValidHeader(header)) {\n this.header = header; // manual\n this._$header = typeof header === \"number\" ? header : $strToHashCode(header);\n }\n else {\n throw new TypeError(\"Header must be 2-byte string, uint16, or null.\");\n }\n }\n else {\n throw new TypeError(\"Format must be object or Type\");\n }\n }\n\n // ----- Static methods: -----\n\n /**\n * Read the header of a buffer as a number.\n *\n * @see {header}\n * @throws {RangeError} if buffer size < 2\n */\n public static peekHeader = peekHeader;\n\n /**\n * Read the header of a buffer as a string.\n *\n * @see {header}\n * @throws {RangeError} if buffer size < 2\n */\n public static peekHeaderStr = peekHeaderStr;\n\n // ----- Accessors: -----\n\n /**\n * @example \"{uint8,str[]?}\"\n * @internal\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private get f(): string {\n if (this._$format === undefined) {\n this._$format = this._$fields !== undefined\n ? `{${this._$fields.map(v => v.f).join(\",\")}}`\n : `${this._$type}`;\n }\n\n return this._$format;\n }\n\n /** @internal */\n private static _$initWriter(): BufferWriter {\n if (cfg.useGlobalEncodingBuffer) {\n if (!BufferFormat._$globalWriter) {\n // lazy init: global encoding buffer created at max size\n this._$globalWriter = new BufferWriter(cfg.encodingBufferInitialSize);\n }\n\n return this._$globalWriter;\n }\n\n return new BufferWriter(cfg.encodingBufferInitialSize);\n }\n\n /**\n * Encode an object to bytes.\n *\n * **Warning:** Returns an unsafe view into the encoding buffer. Pass this reference to preserve\n * performance, and to minimize memory allocation and fragmentation.\n *\n * @param data - data to encode\n * @param preserveBytes - (default: `setTinybufConfig().safe`) When set to true, copies encoded\n * bytes to a new buffer. When set to false, returns an unsafe view of bytes but prevents\n * unnnecessary memory allocation and fragmentation.\n *\n * @returns a copy of encoded bytes\n * @throws if fails to encode value to schema\n */\n public encode>(\n data: TDecodedType,\n preserveBytes?: boolean,\n ): Uint8Array {\n if (!this._$writer) {\n // lazy init\n this._$writer = BufferFormat._$initWriter();\n }\n\n // reset\n this._$writer.$byteLength = 0;\n\n if (this._$hasValidationOrTransforms) {\n data = this._$preprocess(data);\n }\n\n this._$write(data, this._$writer);\n\n return (preserveBytes ?? cfg.safe)\n ? this._$writer.$copyBytes()\n : this._$writer.$viewBytes();\n }\n\n /**\n * Decode binary data to an object.\n * @throws if fails to decode bytes to schema.\n */\n public decode>(\n bytes: Uint8Array | ArrayBufferView | ArrayBuffer,\n decodeInto?: Partial,\n ): TDecodedType {\n return this._$read(new BufferReader(bytes, this.header === undefined ? 0 : 2), decodeInto);\n }\n\n /**\n * Set additional transform functions to apply before encoding and after decoding.\n */\n public setTransforms(transforms: TransformConfig | Transforms): this {\n this._$hasValidationOrTransforms = true;\n\n if (typeof transforms === \"function\" || (Array.isArray(transforms) && typeof transforms[0] === \"function\")) {\n this._$transforms = transforms;\n }\n else {\n for (const name of Object.keys(transforms)) {\n const field = this._$fieldsMap.get(name);\n if (!field) {\n throw new TypeError(`Failed to set transforms for field '${name}'`);\n }\n\n // Set validation for object.\n field.$coder.setTransforms(transforms[name]);\n }\n }\n\n return this;\n }\n\n /**\n * Set additional validation rules which are applied on encode() and decode().\n *\n * - Validation functions should throw an error, return an error, or return boolean false.\n * - Anything else is treated as successfully passing validation.\n */\n public setValidation(validations: ValidationConfig | ValidationFn): this {\n this._$hasValidationOrTransforms = true;\n\n if (typeof validations === \"function\") {\n this._$validate = validations;\n }\n else {\n for (const name of Object.keys(validations)) {\n const field = this._$fieldsMap.get(name);\n if (!field) {\n throw new TypeError(`Failed to set validation function for field '${name}'`);\n }\n\n field.$coder.setValidation(validations[name]);\n }\n }\n\n return this;\n }\n\n // ----- Implementation: -----\n\n /**\n * @param value\n * @param bw\n * @throws if the value is invalid\n *\n * @internal\n */\n private _$write(value: any, bw: BufferWriter): void {\n // write header\n if (this._$header !== undefined) bw.$writeUint16(this._$header);\n\n // write scalar\n if (this._$type !== undefined) {\n const safeValue = (this._$validate || this._$transforms) ? this._$preprocess(value) : value;\n\n return writers[this._$type](safeValue, bw);\n }\n\n // check for object type\n if (typeof value !== \"object\" || !value) {\n throw new TypeError(\"expected object type\");\n }\n\n // write each field\n for (const field of this._$fields) {\n const subValue = value[field.$name];\n\n if (field.$isOptional) {\n if (subValue === undefined || subValue === null) {\n coders.boolCoder.$write(false, bw);\n continue; // skip\n }\n else {\n coders.boolCoder.$write(true, bw);\n }\n }\n else if (subValue == null) {\n throw new Error(`missing required value: ${field.$name}`);\n }\n\n if (field.$isArray) {\n // array\n this._$writeArray(subValue, bw, field.$coder);\n continue;\n }\n\n // scalar/object field\n field.$coder._$write(subValue, bw);\n }\n }\n\n /**\n * pre-process: validation and/or transforms\n * @internal\n */\n private _$preprocess>(data: T): T {\n if (this._$validate) this._$processValidation(data);\n\n if (typeof this._$transforms === \"function\") {\n return this._$transforms(data);\n }\n else if (Array.isArray(this._$transforms) && typeof this._$transforms[0] === \"function\") {\n return this._$transforms[0](data);\n }\n\n return data;\n }\n\n /**\n * post-process: validation and/or transforms\n * @internal\n */\n private _$postprocess>(data: T): T {\n if (Array.isArray(this._$transforms) && typeof this._$transforms[1] === \"function\") {\n data = this._$transforms[1](data);\n }\n\n if (this._$validate) this._$processValidation(data);\n\n return data;\n }\n\n private _$processValidation(data: any): void {\n if (!this._$validate) return;\n const res = this._$validate(data);\n if (res instanceof Error) throw res;\n if (res === false) throw new Error(\"failed validation\");\n }\n\n /**\n * This function will be executed only the first time\n * After that, we'll compile the read routine and add it directly to the instance\n * @param state\n * @returns\n * @throws if fails\n *\n * @internal\n */\n private _$read>(state: BufferReader, obj?: Partial): TDecodedType {\n // This function will be executed only the first time to compile the read routine.\n // After that, we'll compile the read routine and add it directly to the instance\n\n // Update the read method implementation.\n this._$read = this._$compileFormatReadFn();\n\n return this._$read(state, obj);\n }\n\n /**\n * Generate read function code for this coder.\n *\n * @example\n * let v=o??{};\n * v.prop1=this._$readField(0,s,o);\n * v.prop2=this._$readField(1,s,o);\n * return v\n *\n * @internal\n */\n private _$makeObjectReadFnBody(): string {\n const fieldsStr: string = this._$fields\n .map(({ $name: n }, i) => `v.${n}=this.${this._$readField.name}(${i},s,v.${n})`)\n .join(\";\");\n\n return `let v=o??{};${fieldsStr};return v;`;\n }\n\n /**\n * Read an individual field.\n * @internal\n */\n private _$readField(fieldIndex: number, state: BufferReader, obj?: any): any {\n const field = this._$fields[fieldIndex];\n\n if (field.$isOptional && !coders.boolCoder.$read(state)) {\n return undefined;\n }\n\n if (field.$isArray) {\n return this._$readArray(field.$coder, state, obj);\n }\n\n return field.$coder._$read(state, obj);\n }\n\n /**\n * Compile the decode() method for this object.\n *\n * @internal\n */\n private _$compileFormatReadFn>(): (state: BufferReader, obj: Partial | undefined) => TDecodedType {\n if (this._$type !== undefined) {\n // scalar type\n return this._$hasValidationOrTransforms\n ? (s) => this._$postprocess(readers[this._$type](s))\n : readers[this._$type];\n }\n\n // object type\n return new Function(\"s\", \"o\", this._$makeObjectReadFnBody()) as any;\n }\n\n /**\n * @internal\n */\n private _$writeArray(value: any[], bw: BufferWriter, type: BufferFormat): void {\n if (!Array.isArray(value)) {\n throw new TypeError(`expected array, instead got: ${value}`);\n }\n\n coders.uintCoder.$write(value.length, bw);\n for (let i = 0; i < value.length; i++) {\n type._$write(value[i], bw);\n }\n }\n\n /**\n * @throws if invalid data\n * @internal\n */\n private _$readArray(type: BufferFormat, state: any, obj?: Array): Array {\n const len = coders.uintCoder.$read(state);\n const arr = obj?.length === len ? obj : new Array(len);\n for (let j = 0; j < arr.length; j++) {\n arr[j] = type._$read(state, obj?.[j]);\n }\n return arr;\n }\n}\n\n/**\n * Parses and represents an object field.\n *\n * @internal\n */\nclass Field {\n public $name: string;\n public $coder: BufferFormat;\n public $isOptional: boolean;\n public $isArray: boolean;\n\n private _$formatString?: string;\n\n public constructor(name: string, rawType: FieldDefinition) {\n this.$isOptional = rawType instanceof MaybeType;\n let type = rawType instanceof MaybeType ? rawType.type : rawType;\n\n this.$name = name;\n\n if (Array.isArray(type)) {\n if (type.length !== 1) {\n throw new TypeError(\"Array type must contain exactly one format\");\n }\n\n type = type[0];\n this.$isArray = true;\n }\n else {\n this.$isArray = false;\n }\n\n this.$coder = new BufferFormat(type, null);\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public get f(): string {\n if (this._$formatString === undefined) {\n this._$formatString = `${(this.$coder as any).f}${this.$isArray ? \"[]\" : \"\"}${this.$isOptional ? \"?\" : \"\"}`;\n }\n\n return this._$formatString;\n }\n}\n"],"names":["TinybufError","Error","$hashCode","str","hash","i","length","charCodeAt","$strToHashCode","$hashCodeToStr","hashCode","String","fromCharCode","Math","floor","peekHeader","b","ArrayBuffer","isView","DataView","buffer","byteOffset","getUint16","peekHeaderStr","bufferParser","BufferParser","constructor","this","_$formats","Map","_$data","processBuffer","f","data","cb","r","header","has","get","_a","decode","set","e","err","stack","on","format","callback","decodeInPlace","ignore","forEach","clear","$floor","$ceil","ceil","$clamp","value","min","max","$roundTowardZero","x","$roundAwayFromZero","uscalround","$fromuscal8","$touscal8","scalround","$fromscal8","$toscal8","Type","UInt","UInt8","UInt16","UInt32","Int","Int8","Int16","Int32","Float64","Float32","Float16","BFloat16","Scalar8","UScalar8","Bool","Bools","Buffer","JSON","RegExp","Date","ValidTypes","Object","values","MaybeType","type","optional","t","mask","padBit","reduce","n","unmask","l","len","undefined","clz32","Array","isArray","val","$utf8encode","encoder","TextEncoder","encode","$utf8decode","decoder","TextDecoder","y","f16round","$fromf16","$tof16","Float32Array","Int32Array","s","z","pow","d","m","Infinity","NaN","Uint32Array","bf16round","MAX_VARUINT32","MAX_VARINT32","POW_32","uintCoder","$write","writer","Number","$writeUint8","$writeUint16","$writeUint32","$read","reader","firstByte","$peek","$readUint32","$readUint16","$skip","uint8Coder","$readUint8","uint16Coder","uint32Coder","intCoder","int8Coder","$writeInt8","$readInt8","int16Coder","$writeInt16","$readInt16","int32Coder","$writeInt32","$readInt32","bfloat16Coder","$tobf16","$frombf16","float16Coder","float32Coder","$writeFloat32","$readFloat32","float64Coder","$writeFloat64","$readFloat64","uscalar8Coder","scalar8Coder","dateCoder","getTime","bufferCoder","byteLength","$writeBytes","$readBytes","stringCoder","boolCoder","boolsCoder","slice","p","jsonCoder","stringify","parse","regexCoder","global","ignoreCase","multiline","source","g","writers","readers","setTinybufConfig","c","cfg","assign","safe","useGlobalEncodingBuffer","encodingBufferMaxSize","encodingBufferInitialSize","encodingBufferIncrement","BufferWriter","initialSize","$byteLength","_$writeHead","_$dataView","$viewBytes","Uint8Array","$copyBytes","_$alloc","setInt8","setInt16","setInt32","setUint8","setUint16","setUint32","setFloat32","setFloat64","bBytes","bytes","minBytesNeeded","requestedNewBytes","_$resizeBuffer","newSize","newBuf","oldView","BufferReader","headerBytes","getUint8","getUint32","getInt8","getInt16","getInt32","getFloat32","getFloat64","RangeError","view","defineFormat","a","BufferFormat","encodingBuffer","_$writer","def","_$hasValidationOrTransforms","includes","_$type","TypeError","_$fieldsMap","_$fields","keys","map","name","Field","_$header","isValidHeader","h","isInteger","_$format","v","join","_$initWriter","_$globalWriter","preserveBytes","_$preprocess","_$write","decodeInto","_$read","setTransforms","transforms","_$transforms","field","$coder","setValidation","validations","_$validate","bw","safeValue","subValue","$name","$isOptional","coders.boolCoder","$isArray","_$writeArray","_$processValidation","_$postprocess","res","state","obj","_$compileFormatReadFn","_$makeObjectReadFnBody","fieldsStr","_$readField","fieldIndex","_$readArray","Function","coders.uintCoder","arr","j","rawType","_$formatString"],"mappings":"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"} \ No newline at end of file diff --git a/src/core/BufferFormat.ts b/src/core/BufferFormat.ts index f09ad21..a37905a 100644 --- a/src/core/BufferFormat.ts +++ b/src/core/BufferFormat.ts @@ -5,26 +5,28 @@ import { peekHeader, peekHeaderStr } from "./lib/peek"; import { BufferWriter } from "./lib/BufferWriter"; import { BufferReader } from "./lib/BufferReader"; import { - InferredDecodedType, + DecodedType, EncoderDefinition, + FieldDefinition, + TransformConfig, + ValidationConfig, MaybeType, - InferredTransformConfig, - InferredValidationConfig, - ValidationFn, Transforms, - FieldDefinition, TypeLiteral, - ValidTypes + ValidationFn, + ValidTypes, } from "./Type"; import { cfg } from "./config"; export type FormatHeader = string | number; /** - * Decoded object types for a given binary format. - * @example let onData = (data: Decoded) => {...}; + * Utility to get the decoded type of a buffer format + * @example type Format = Decoded */ -export type Decoded = FromBufferFormat extends BufferFormat ? InferredDecodedType : never; +export type Decoded = TBufferFormat extends BufferFormat + ? DecodedType + : never; /** * Defines a format for encoding/decoding binary buffers. @@ -37,7 +39,7 @@ export type Decoded = FromBufferFormat extends BufferFormat(def: T): BufferFormat; +export function defineFormat(def: T): BufferFormat; /** * Defines a format for encoding/decoding binary buffers. * @@ -49,8 +51,8 @@ export function defineFormat(h: HeaderType | null, def: T): BufferFormat; -export function defineFormat(a?: HeaderType | T, b?: T): BufferFormat { +export function defineFormat(h: HeaderType | null, def: T): BufferFormat; +export function defineFormat(a?: HeaderType | T, b?: T): BufferFormat { return a !== null && typeof a === "object" ? new BufferFormat(a as T) : new BufferFormat(b as T, a as HeaderType); @@ -140,11 +142,11 @@ export class BufferFormat>( - data: DecodedType, + public encode>( + data: TDecodedType, preserveBytes?: boolean, ): Uint8Array { if (!this._$writer) { @@ -221,7 +223,7 @@ export class BufferFormat>( + public decode>( bytes: Uint8Array | ArrayBufferView | ArrayBuffer, - decodeInto?: Partial, - ): DecodedType { + decodeInto?: Partial, + ): TDecodedType { return this._$read(new BufferReader(bytes, this.header === undefined ? 0 : 2), decodeInto); } /** * Set additional transform functions to apply before encoding and after decoding. */ - public setTransforms(transforms: InferredTransformConfig | Transforms): this { + public setTransforms(transforms: TransformConfig | Transforms): this { this._$hasValidationOrTransforms = true; if (typeof transforms === "function" || (Array.isArray(transforms) && typeof transforms[0] === "function")) { @@ -275,7 +277,7 @@ export class BufferFormat | ValidationFn): this { + public setValidation(validations: ValidationConfig | ValidationFn): this { this._$hasValidationOrTransforms = true; if (typeof validations === "function") { @@ -395,7 +397,7 @@ export class BufferFormat>(state: BufferReader, obj?: Partial): DecodedType { + private _$read>(state: BufferReader, obj?: Partial): TDecodedType { // This function will be executed only the first time to compile the read routine. // After that, we'll compile the read routine and add it directly to the instance @@ -447,7 +449,7 @@ export class BufferFormat>(): (state: BufferReader, obj: Partial | undefined) => DecodedType { + private _$compileFormatReadFn>(): (state: BufferReader, obj: Partial | undefined) => TDecodedType { if (this._$type !== undefined) { // scalar type return this._$hasValidationOrTransforms diff --git a/src/core/BufferParser.ts b/src/core/BufferParser.ts index fd9b003..fae870a 100644 --- a/src/core/BufferParser.ts +++ b/src/core/BufferParser.ts @@ -1,5 +1,5 @@ import { BufferFormat } from "./BufferFormat"; -import { EncoderDefinition, InferredDecodedType } from "./Type"; +import { EncoderDefinition, DecodedType } from "./Type"; import { TinybufError } from "./lib/errors"; import { $hashCodeToStr, $strToHashCode } from "./lib/hashCode"; import { peekHeader } from "./lib/peek"; @@ -59,9 +59,9 @@ export class BufferParser { /** * Register a format handler. */ - public on>( + public on>( format: BufferFormat, - callback: (data: DecodedType) => any, + callback: (data: TDecodedType) => any, { decodeInPlace = false, } = {}, diff --git a/src/core/Type.ts b/src/core/Type.ts index 8dd908e..15cda67 100644 --- a/src/core/Type.ts +++ b/src/core/Type.ts @@ -128,6 +128,11 @@ export type ValueTypes = { [Type.Date]: Date; }; +/** https://www.totaltypescript.com/concepts/the-prettify-helper */ +type Pretty = T extends ArrayBuffer | ArrayBufferView | Date | RegExp | Uint8Array ? T + : T extends Array ? Array> + : T extends object ? {[K in keyof T]: Pretty} & unknown : T; + /** @throws any error too */ export type ValidationFn = (x: T) => undefined | boolean | Error; export type TransformFn = (x: T) => T; @@ -162,15 +167,15 @@ export type FieldDefinition = keyof ValueTypes | [keyof ValueTypes] | EncoderDef /** * The resulting type of the decoded data, based on the encoder definition. */ -export type InferredDecodedType = { +type RawDecodedType = { [EKey in keyof EncoderType as EncoderType[EKey] extends MaybeType ? never : EKey]: EncoderType[EKey] extends keyof ValueTypes ? ValueTypes[EncoderType[EKey]] : EncoderType[EKey] extends [keyof ValueTypes] ? Array : EncoderType[EKey] extends EncoderDefinition - ? InferredDecodedType + ? RawDecodedType : EncoderType[EKey] extends [EncoderDefinition] - ? Array> + ? Array> : never; } & { [EKey in keyof EncoderType as EncoderType[EKey] extends MaybeType ? EKey : never]?: EncoderType[EKey] extends MaybeType @@ -178,42 +183,44 @@ export type InferredDecodedType = { : EncoderType[EKey] extends MaybeType ? Array | undefined : EncoderType[EKey] extends MaybeType - ? InferredDecodedType | undefined + ? RawDecodedType | undefined : never; }; -export type InferredTransformConfig = { +export type DecodedType = Pretty>; + +export type TransformConfig = { [EKey in keyof EncoderType]?: EncoderType[EKey] extends keyof ValueTypes ? Transforms : EncoderType[EKey] extends [keyof ValueTypes] ? Transforms : EncoderType[EKey] extends EncoderDefinition - ? InferredTransformConfig + ? TransformConfig : EncoderType[EKey] extends [EncoderDefinition] - ? InferredTransformConfig + ? TransformConfig : EncoderType[EKey] extends MaybeType ? Transforms : EncoderType[EKey] extends MaybeType ? Transforms : EncoderType[EKey] extends MaybeType - ? InferredTransformConfig | undefined + ? TransformConfig | undefined : never; }; -export type InferredValidationConfig = { +export type ValidationConfig = { [EKey in keyof EncoderType]?: EncoderType[EKey] extends keyof ValueTypes ? ValidationFn : EncoderType[EKey] extends [keyof ValueTypes] ? ValidationFn : EncoderType[EKey] extends EncoderDefinition - ? InferredValidationConfig + ? ValidationConfig : EncoderType[EKey] extends [EncoderDefinition] - ? InferredValidationConfig + ? ValidationConfig : EncoderType[EKey] extends MaybeType ? ValidationFn : EncoderType[EKey] extends MaybeType ? ValidationFn : EncoderType[EKey] extends MaybeType - ? InferredValidationConfig | undefined + ? ValidationConfig | undefined : never; }; diff --git a/src/core/lib/BufferWriter.ts b/src/core/lib/BufferWriter.ts index 1e3bc63..cc0eb90 100644 --- a/src/core/lib/BufferWriter.ts +++ b/src/core/lib/BufferWriter.ts @@ -7,81 +7,87 @@ import { TinybufError } from "./errors"; * @internal */ export class BufferWriter { - public i: number = 0; + public $byteLength: number = 0; public _$dataView: DataView; + private _$writeHead: number = 0; public constructor(initialSize: number) { this._$dataView = new DataView(new ArrayBuffer(initialSize)); } public $viewBytes(): Uint8Array { - return new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset, this.i); + return new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset, this.$byteLength); } public $copyBytes(): Uint8Array { - return new Uint8Array(this._$dataView.buffer.slice(0, this.i)); + return new Uint8Array(this._$dataView.buffer.slice(0, this.$byteLength)); } // ----- Writers: ----- public $writeInt8(value: number): void { - this._$dataView.setInt8(this._$alloc(1), value); + this._$alloc(1).setInt8(this._$writeHead, value); } public $writeInt16(value: number): void { - this._$dataView.setInt16(this._$alloc(2), value, true); + this._$alloc(2).setInt16(this._$writeHead, value, true); } public $writeInt32(value: number): void { - this._$dataView.setInt32(this._$alloc(4), value, true); + this._$alloc(4).setInt32(this._$writeHead, value, true); } public $writeUint8(value: number): void { - this._$dataView.setUint8(this._$alloc(1), value); + this._$alloc(1).setUint8(this._$writeHead, value); } public $writeUint16(value: number): void { - this._$dataView.setUint16(this._$alloc(2), value, false); // big-endian for varint + this._$alloc(2).setUint16(this._$writeHead, value, false); // big-endian for varint } public $writeUint32(value: number): void { - this._$dataView.setUint32(this._$alloc(4), value, false); // big-endian for varint + this._$alloc(4).setUint32(this._$writeHead, value, false); // big-endian for varint } public $writeFloat32(value: number): void { - this._$dataView.setFloat32(this._$alloc(4), value, true); + this._$alloc(4).setFloat32(this._$writeHead, value, true); } public $writeFloat64(value: number): void { - this._$dataView.setFloat64(this._$alloc(8), value, true); + this._$alloc(8).setFloat64(this._$writeHead, value, true); } public $writeBytes(b: Uint8Array | ArrayBuffer | ArrayBufferView): void { // allocate bytes first - const j = this._$alloc(b.byteLength); + this._$alloc(b.byteLength); let bBytes: Uint8Array = ArrayBuffer.isView(b) - ? b instanceof Uint8Array ? b : new Uint8Array(b.buffer, b.byteOffset, b.byteLength) + ? b instanceof Uint8Array + ? b + : new Uint8Array(b.buffer, b.byteOffset, b.byteLength) : new Uint8Array(b); // copy bytes - new Uint8Array(this._$dataView.buffer, this._$dataView.byteOffset + j, b.byteLength).set(bBytes); + new Uint8Array( + this._$dataView.buffer, + this._$dataView.byteOffset + this._$writeHead, + b.byteLength + ).set(bBytes); } // ----- Private methods: ----- - /** @returns writer head (byteOffset) */ - private _$alloc(bytes: number): number { - if (this.i + bytes > this._$dataView.byteLength) { - const minBytesNeeded = this.i + bytes - this._$dataView.byteLength; + private _$alloc(bytes: number): DataView { + if (this.$byteLength + bytes > this._$dataView.byteLength) { + const minBytesNeeded = this.$byteLength + bytes - this._$dataView.byteLength; const requestedNewBytes = Math.ceil(minBytesNeeded / cfg.encodingBufferIncrement) * cfg.encodingBufferIncrement; this._$resizeBuffer(this._$dataView.byteLength + requestedNewBytes); } - const j = this.i; - this.i += bytes; + this._$writeHead = this.$byteLength; + this.$byteLength += bytes; - return j; + return this._$dataView; } private _$resizeBuffer(newSize: number): void {