sonic-ws 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/bundled/bundle.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/ws/Connection.d.ts +2 -0
- package/dist/ws/Connection.js +1 -1
- package/dist/ws/client/core/ClientCore.d.ts +2 -0
- package/dist/ws/client/core/ClientCore.js +1 -1
- package/dist/ws/packets/Packets.d.ts +29 -1
- package/dist/ws/packets/Packets.js +1 -1
- package/dist/ws/server/SonicWSConnection.d.ts +2 -0
- package/dist/ws/server/SonicWSConnection.js +1 -1
- package/dist/ws/server/SonicWSServer.d.ts +13 -0
- package/dist/ws/server/SonicWSServer.js +1 -1
- package/dist/ws/util/packets/BatchHelper.js +1 -1
- package/dist/ws/util/packets/PacketHolder.js +1 -1
- package/dist/ws/util/packets/PacketUtils.d.ts +23 -0
- package/dist/ws/util/packets/PacketUtils.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ The TypeScript/python layer handles connections, packet definitions, middleware,
|
|
|
78
78
|
- Object framing, batching, and raw DEFLATE compression
|
|
79
79
|
- TypeScript/Python-side JSON conversion transported through reserved wire type 16 as raw bytes
|
|
80
80
|
|
|
81
|
-
The same Rust implementation is exposed through N-API for native Node use and through WASM for browsers and the portable Node fallback. Protocol behavior therefore does not depend on which runtime is connected.
|
|
81
|
+
The same Rust implementation is exposed through N-API for native Node use and through WASM for browsers, Python, and the portable Node fallback. Python loads its packaged WASM core through `wasmtime`, so the Python package does not need separate SonicWS DLL, dylib, or shared-object releases. Protocol behavior therefore does not depend on which runtime is connected.
|
|
82
82
|
|
|
83
83
|
Automatic browser-file serving at `/SonicWS/bundle.js` and
|
|
84
84
|
`/SonicWS/bundle.wasm` is supported only by the Node.js server, where it can be
|
|
@@ -148,6 +148,21 @@ Full API documentation:
|
|
|
148
148
|
- [TypeScript / Node / browser](docs/ts/README.md)
|
|
149
149
|
- [Python](docs/py/README.md)
|
|
150
150
|
|
|
151
|
+
Packet schemas can now map the existing single-type wire format directly to application objects:
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
const entitySnapshot = CreatePacket({
|
|
155
|
+
tag: "entitySnapshot",
|
|
156
|
+
type: PacketType.VARINT,
|
|
157
|
+
schema: ["id", "type", "x", "y", "z", "pitch", "yaw"],
|
|
158
|
+
autoFlatten: true,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
await ws.send("entitySnapshot", [...entities.values()]);
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
This remains a homogeneous `VARINT` packet. Schema mapping, row-major `autoFlatten`, object-packet `autoTranspose`, quantization, bounds, and packet groups are application-layer conveniences and do not turn the codec into a mixed-type serializer. See the packet documentation above for TypeScript and Python examples.
|
|
165
|
+
|
|
151
166
|
## KNOWN ISSUES
|
|
152
167
|
|
|
153
168
|
- `KEY_EFFECTIVE` is reserved but still a work in progress.
|
package/bundled/bundle.js
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
4
|
* See LICENSE for personal, non-commercial license terms.
|
|
5
5
|
*/
|
|
6
|
-
(()=>{"use strict";var __webpack_modules__={8(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.BatchHelper=void 0;const a=n(950),r=n(351);t.BatchHelper=class{batchInfo={};batchTimeouts={};batchedData={};conn;registerSendPackets(e,t){this.conn=t,e.getTags().forEach(t=>{const n=e.getPacket(t);if(0==n.dataBatching)return;const a=e.getKey(t);this.initiateBatch(a,n.dataBatching,n.gzipCompression)})}initiateBatch(e,t,n){this.batchedData[e]=[],this.batchInfo[e]=[t,n]}startBatch(e){const[t,n]=this.batchInfo[e];this.batchTimeouts[e]=this.conn.setInterval(()=>{if(0==this.batchedData[e].length)return;const t=(0,r.encodeNativeBatch)(this.batchedData[e],n);this.conn.raw_send((0,a.toPacketBuffer)(e,t)),this.batchedData[e]=[],delete this.batchTimeouts[e]},t)}batchPacket(e,t){this.batchedData[e].push(t),this.batchTimeouts[e]||this.startBatch(e)}static async unravelBatch(e,t,n){let a;try{a=(0,r.decodeNativeBatch)(t,e.gzipCompression,e.maxBatchSize)}catch(e){return"Invalid batch: "+e}const s=[];for(const t of a){const a=await e.listen(t,n);if("string"==typeof a)return"Batched packet: "+a;s.push([a[0],!e.dontSpread])}return s}}},30(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.decompressBools=t.compressBools=t.EMPTY_UINT8=t.MAX_UVARINT=t.MAX_USHORT=t.MAX_BYTE=void 0,t.convertVarInt=function(e){if(!Number.isSafeInteger(e)||e<0||e>t.MAX_UVARINT)throw new Error(`Variable Ints must be within range 0 and ${t.MAX_UVARINT}: ${e}`);const n=[];do{let t=e%128;(e=Math.floor(e/128))>0&&(t|=128),n.push(t)}while(e>0);return n},t.readVarInt=function(e,t){let n=0,a=1;for(let r=0;r<8;r++){if(t>=e.length)throw new Error("Truncated variable integer");const r=e[t++];if(n+=(127&r)*a,!(128&r))return[t,n];a*=128}throw new Error("Variable integer is too long")},t.MAX_BYTE=255,t.MAX_USHORT=65535,t.MAX_UVARINT=128**7-1,t.EMPTY_UINT8=new Uint8Array([]);t.compressBools=e=>e.reduce((e,t,n)=>e|Number(t)<<7-n,0);t.decompressBools=e=>Array.from({length:8},(t,n)=>!!(e&1<<7-n))},72(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.decompressJSON=t.compressJSON=void 0;const a=n(950),r=e=>Array.from({length:8},(t,n)=>!!(e&1<<7-n));function s(e){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid JSON variable integer: ${e}`);const t=[];do{let n=127&e;(e>>>=7)>0&&(n|=128),t.push(n)}while(e>0);return t}function i(e,t){let n=0,a=0;for(;;){if(t>=e.length||a>28)throw new Error("Invalid JSON variable integer");const r=e[t++];if(n+=(127&r)<<a,!(128&r))return[t,n];a+=7}}var o;!function(e){e[e.NULL=0]="NULL",e[e.BOOL=1]="BOOL",e[e.INT=2]="INT",e[e.FLOAT=3]="FLOAT",e[e.STRING=4]="STRING",e[e.ARRAY=5]="ARRAY",e[e.OBJECT=6]="OBJECT"}(o||(o={}));const c=e=>{const t=(new TextEncoder).encode(e);return[...s(t.length),...t]},d=(e,t)=>{const[n,a]=i(e,t);return{value:(new TextDecoder).decode(e.subarray(n,n+a)),length:n+a-t}},l=e=>{let t="";for(const n of e)t+=n.toString(2).padStart(3,"0");return(e=>new Uint8Array(e.match(/.{1,8}/g)?.map(e=>parseInt(e.padEnd(8,"0"),2))??[]))(t)},u=(e,t)=>{const n=(e=>Array.from(e,e=>e.toString(2).padStart(8,"0")).join(""))(e),a=[];for(let e=0;e<t;e++)a.push(parseInt(n.slice(3*e,3*e+3),2));return a};t.compressJSON=e=>{const t=[],n=[],r=[],i=e=>{switch(null===e?"null":Array.isArray(e)?"array":typeof e){case"null":r.push(o.NULL);break;case"boolean":r.push(o.BOOL),t.push(e);break;case"number":Number.isInteger(e)?(r.push(o.INT),n.push(...s((e=>e<<1^e>>31)(e)))):(r.push(o.FLOAT),n.push(...function(e){if(Number.isNaN(e))return[127,128,0,1];const t=e<0?1:0;if(0===(e=Math.abs(e)))return[0,0,0,0];const n=Math.floor(Math.log2(e));if(!Number.isFinite(e)||n>127||n<-126)return[t?255:127,128,0,0];const a=(t<<31|n+127<<23|8388607&Math.round((e/2**n-1)*2**23))>>>0;return[a>>>24,a>>>16&255,a>>>8&255,255&a]}(e)));break;case"string":r.push(o.STRING),n.push(...c(e));break;case"array":r.push(o.ARRAY),n.push(...s(e.length));for(const t of e)i(t);break;case"object":{r.push(o.OBJECT);const t=Object.keys(e);n.push(...s(t.length));for(const a of t)n.push(...c(a)),i(e[a]);break}default:throw new Error("Unsupported type")}};i(e);const d=t.length?(0,a.splitArray)(t,8).map(e=>e.reduce((e,t,n)=>e|Number(t)<<7-n,0)):[],u=l(r),h=[...s(d.length),...s(u.length)];return Uint8Array.from([...h,...d.flat(),...u,...n])};t.decompressJSON=e=>{let t=0;const[n,a]=i(e,t);t=n;const[s,c]=i(e,t);t=s;const l=[];for(let n=0;n<a;n++)l.push(...r(e[t++]));let h=0;const p=e.subarray(t,t+c);t+=c;const f=u(p,8*p.length/3);let w=0;const _=n=>{if(n>500)throw new Error("JSON array too deep.");const a=f[w++];switch(a){case o.NULL:return null;case o.BOOL:return l[h++];case o.INT:{const[n,a]=i(e,t);return t=n,(r=a)>>>1^-(1&r)}case o.FLOAT:{const n=function(e){const t=(e[0]<<24|e[1]<<16|e[2]<<8|e[3])>>>0,n=t>>>23&255,a=(0===n?0:1)+(8388607&t)/2**23,r=255===n?0===a?1/0:NaN:a*2**(0===n?-126:n-127);return t>>>31?-r:r}(Array.from(e.subarray(t,t+4)));return t+=4,n}case o.STRING:{const{value:n,length:a}=d(e,t);return t+=a,n}case o.ARRAY:{const[a,r]=i(e,t);t=a;const s=[];for(let e=0;e<r;e++)s.push(_(n+1));return s}case o.OBJECT:{const[a,r]=i(e,t);t=a;const s={};for(let a=0;a<r;a++){const{value:a,length:r}=d(e,t);t+=r,s[a]=_(n+1)}return s}default:throw new Error(`Unknown type ${a}`)}var r};return _(0)}},98(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.EnumPackage=t.TYPE_CONVERSION_MAP=void 0;const a=n(157),r=n(388),s={string:0,number:1,boolean:2,undefined:3,object:4};function i(e){const t=typeof e;if(!(t in s)&&null!=e)throw new Error(`Cannot serialize type "${t}" in an enum!`);return s[t]}t.TYPE_CONVERSION_MAP={0:e=>e,1:e=>parseFloat(e),2:e=>"true"==e,3:()=>{},4:()=>null};t.EnumPackage=class{tag;values;constructor(e,t){this.tag=e,this.values=t,this.wrap=this.wrap.bind(this)}serialize(){const e=(0,a.processCharCodes)(this.tag);return[this.tag.length,...e,this.values.length,...this.values.map(e=>[String(e).length,i(e),...(0,a.processCharCodes)(String(e))]).flat()]}wrap(e){return(0,r.WrapEnum)(this.tag,e)}}},102(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.PacketSchema=t.Packet=void 0;const a=n(388),r=n(98),s=n(30),i=n(433),o=n(619),c=n(157),d=n(351),l=n(72);class u{defaultEnabled;tag;maxSize;minSize;type;enumData;dataMax;dataMin;dataBatching;maxBatchSize;dontSpread;autoFlatten;rateLimit;async;rereference;gzipCompression;object;client;processReceive;processSend;validate;customValidator;lastReceived={};lastSent={};constructor(e,t,n,a,r){if(this.tag=e,this.defaultEnabled=a,this.client=r,this.async=t.async,this.enumData=t.enumData,this.rateLimit=t.rateLimit,this.dontSpread=t.dontSpread,this.autoFlatten=t.autoFlatten,this.rereference=t.rereference,this.dataBatching=t.dataBatching,this.maxBatchSize=r?1/0:t.maxBatchSize,this.gzipCompression=t.gzipCompression,this.object=t.object,this.type=t.type,this.dataMax=t.dataMax,this.dataMin=t.dataMin,t.testObject(this)){this.maxSize=this.minSize=this.type.length;for(let e=0;e<this.type.length;e++)this.type[e]==o.PacketType.NONE&&(this.dataMax[e]=this.dataMin[e]=0);const e={types:this.type,dataMins:this.dataMin,dataMaxes:this.dataMax,enumData:this.enumData};this.processReceive=t=>(0,d.decodeNativeObject)(e,t).map((e,t)=>this.type[t]===o.PacketType.JSON?(0,l.decompressJSON)(e):e),this.processSend=async t=>{let n=0;const a=t.map((e,t)=>{if(this.type[t]===o.PacketType.JSON)return(0,l.compressJSON)(e);if(this.type[t]!==o.PacketType.ENUMS)return e;const a=this.enumData[n++];return(Array.isArray(e)?e:[e]).map(e=>{if(!Number.isInteger(e)||e<0||e>=a.values.length)throw new Error(`Invalid wrapped enum index: ${e}`);return a.values[e]})});return(0,d.encodeNativeObject)(e,a)},this.validate=async t=>{(0,d.validateNativeObject)(e,t);return(0,d.decodeNativeObject)(e,t).forEach((e,t)=>{if(this.type[t]!==o.PacketType.JSON)return;const n=(0,l.decompressJSON)(e),a=Array.isArray(n)?n.length:1;if(a<this.dataMin[t]||a>this.dataMax[t])throw new Error("JSON value count is outside schema limits")}),[t,!0]}}else{{this.maxSize=this.dataMax,this.minSize=this.dataMin,this.type==o.PacketType.NONE&&(this.dataMax=this.dataMin=0);const e=this.enumData[0];this.processReceive=t=>this.type===o.PacketType.JSON?(0,l.decompressJSON)(t):(0,d.decodeNative)(this.type,t,this.dataMax,e),this.processSend=async t=>{let n;if(this.type===o.PacketType.JSON)n=(0,l.compressJSON)(t);else if(this.type===o.PacketType.ENUMS)n=Uint8Array.from(t);else{const a=this.type===o.PacketType.RAW&&1===t.length&&t[0]instanceof Uint8Array?t[0]:t;n=(0,d.encodeNative)(this.type,a,e)}return this.gzipCompression&&0===this.dataBatching?(0,d.deflateNative)(n):n},this.validate=async t=>{const n=this.gzipCompression&&0===this.dataBatching?(0,d.inflateNative)(t):t;if(this.type===o.PacketType.JSON){const e=(0,l.decompressJSON)(n),t=Array.isArray(e)?e.length:1;if(t<this.dataMin||t>this.dataMax)throw new Error("JSON value count is outside schema limits")}else(0,d.validateNative)(this.type,n,this.dataMin,this.dataMax,{enumData:e});return[n,!0]}}}this.customValidator=n}async listen(e,t){try{const[n,a]=await this.validate(e);if(!this.client&&!1===a)return"Invalid packet";const r=this.processReceive(n,a),s=this.autoFlatten?(0,i.UnFlattenData)(r):r;if(null!=this.customValidator)if(this.dontSpread){if(!this.customValidator(t,s))return"Didn't pass custom validator"}else if(!this.customValidator(t,...s))return"Didn't pass custom validator";return[s,!this.dontSpread]}catch(e){return console.error("There was an error processing the packet! This is probably my fault... report at https://github.com/liwybloc/sonic-ws",e),"Error: "+e}}serialize(){const e=[this.tag.length,...(0,c.processCharCodes)(this.tag),(0,s.compressBools)([this.dontSpread,this.async,this.object,this.autoFlatten,this.gzipCompression,this.rereference]),this.dataBatching,this.enumData.length,...this.enumData.map(e=>e.serialize()).flat()];return this.object?[...e,this.maxSize,...this.dataMax.map(s.convertVarInt).flat(),...this.dataMin.map(s.convertVarInt).flat(),...this.type]:[...e,...(0,s.convertVarInt)(this.dataMax),...(0,s.convertVarInt)(this.dataMin),this.type]}static readVarInts(e,t,n){const a=[];for(let r=0;r<n;r++){const[n,r]=(0,s.readVarInt)(e,t);t=n,a.push(r)}return[a,t]}static deserialize(e,t,n){const i=t,d=e[t++],l=(0,c.as8String)(e.slice(t,t+=d)),[h,f,w,_,y,m]=(0,s.decompressBools)(e[t++]),g=e[t++],b=e[t++],v=[];for(let n=0;n<b;n++){const n=e[t++],s=(0,c.as8String)(e.slice(t,t+=n)),i=e[t++],o=[];for(let n=0;n<i;n++){const n=e[t++],a=e[t++],s=(0,c.as8String)(e.slice(t,t+=n));o.push(r.TYPE_CONVERSION_MAP[a](s))}v.push((0,a.DefineEnum)(s,o))}if(w){const a=e[t++],[r,s]=this.readVarInts(e,t,a);t=s;const[c,d]=this.readVarInts(e,t,a);t=d;const w=Array.from(e.slice(t,t+=a));let m=0;const b=w.map(e=>e==o.PacketType.ENUMS?v[m++]:e),S=new p(!0,b,f,c,r,-1,h,_,!1,g,-1,y);return[new u(l,S,null,!1,n),t-i]}const[S,k]=(0,s.readVarInt)(e,t);t=S;const[E,T]=(0,s.readVarInt)(e,t);t=E;const N=e[t++],P=N==o.PacketType.ENUMS?v[0]:N,A=new p(!1,P,f,T,k,-1,h,!1,m,g,-1,y);return[new u(l,A,null,!1,n),t-i]}static deserializeAll(e,t){const n=[];let a=0;for(;a<e.length;){const[r,s]=this.deserialize(e,a,t);n.push(r),a+=s}return n}}t.Packet=u;const h=(e,t)=>e instanceof r.EnumPackage?(t.push(e),o.PacketType.ENUMS):e;class p{type;enumData=[];dataMax;dataMin;dataBatching;maxBatchSize;rateLimit;dontSpread=!1;autoFlatten=!1;async=!1;rereference=!1;gzipCompression=!1;object;constructor(e,t,n,a,r,s,i,o,c,d,l,u){this.object=e,this.async=n,this.dataMin=a,this.dataMax=r,this.rateLimit=s,this.dontSpread=i,this.autoFlatten=o,this.rereference=c,this.dataBatching=d,this.maxBatchSize=l,this.gzipCompression=u,this.type=e?t.map(e=>h(e,this.enumData)):h(t,this.enumData)}testObject(e){return this.object}}t.PacketSchema=p},157(e,t){function n(e){return String.fromCodePoint(...e)}Object.defineProperty(t,"__esModule",{value:!0}),t.processCharCodes=function(e){return Array.from(e,e=>e.codePointAt(0))},t.convertCharCodes=n,t.as8String=function(e){return n(Array.from(e))}},234(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.SERVER_SUFFIX_NUMS=t.SERVER_SUFFIX=t.VERSION=void 0;const a=n(157);t.VERSION=22,t.SERVER_SUFFIX="SWS",t.SERVER_SUFFIX_NUMS=(0,a.processCharCodes)(t.SERVER_SUFFIX)},351(__unused_webpack_module,exports,__webpack_require__){var __webpack_dirname__="/";Object.defineProperty(exports,"__esModule",{value:!0}),exports.setNativeCore=setNativeCore,exports.initializeWasmCore=initializeWasmCore,exports.loadNativeCore=loadNativeCore,exports.encodeNative=encodeNative,exports.decodeNative=decodeNative,exports.validateNative=validateNative,exports.encodeNativeObject=encodeNativeObject,exports.decodeNativeObject=decodeNativeObject,exports.validateNativeObject=validateNativeObject,exports.encodeNativeBatch=encodeNativeBatch,exports.decodeNativeBatch=decodeNativeBatch,exports.deflateNative=deflateNative,exports.inflateNative=inflateNative;const PacketType_1=__webpack_require__(619),version_1=__webpack_require__(234),CDN_RELEASE="https://cdn.jsdelivr.net/gh/liwybloc/sonic-ws/release",CDN_WASM=`${CDN_RELEASE}/bundle.wasm`,CDN_VERSION=`${CDN_RELEASE}/version`;let loadedCore,wasmInitialization;function buffer(e){return"undefined"!=typeof Buffer?Buffer.from(e.buffer,e.byteOffset,e.byteLength):new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}function values(e){return Array.isArray(e)?[...e]:[e]}function assertNativeCore(e){const t=["encodeSigned","decodeSigned","encodeUnsigned","decodeUnsigned","encodeFloats","decodeFloats","encodeStrings","decodeStrings","encodeBooleans","decodeBooleans","decodeRaw","encodeHex","decodeHex","frameObject","unframeObject","encodeBatch","decodeBatch","deflateRaw","inflateRaw","validateEncoded","validateEnum","validateObject"].filter(t=>"function"!=typeof e[t]);if(t.length>0)throw new Error(`Invalid SonicWS native addon; missing: ${t.join(", ")}`)}function setNativeCore(e){assertNativeCore(e),loadedCore=e}function fetchUrl(e){return"string"==typeof e?e:e instanceof URL?e.href:e.url}async function isWasm(e){if(!e.ok)return!1;const t=new Uint8Array(await e.clone().arrayBuffer());return t.length>=4&&0===t[0]&&97===t[1]&&115===t[2]&&109===t[3]}async function fetchCdnWasm(e){const t=await e(CDN_VERSION,{cache:"no-store"});if(!t.ok)throw new Error(`Unable to verify SonicWS CDN protocol version (${t.status})`);const n=Number((await t.text()).trim());if(!Number.isInteger(n)||n!==version_1.VERSION)throw new Error(`SonicWS CDN protocol mismatch: expected ${version_1.VERSION}, received ${String(n)}`);const a=await e(CDN_WASM);if(!await isWasm(a))throw new Error("SonicWS CDN returned an invalid WASM module");return a}async function initializeBrowserWasm(){const e=window.fetch.bind(window);window.fetch=async(t,n)=>{const a=fetchUrl(t);if(a===CDN_WASM||!new URL(a,window.location.href).pathname.endsWith("/bundle.wasm"))return e(t,n);try{const a=await e(t,n);if(await isWasm(a))return a}catch{}return fetchCdnWasm(e)};try{return setNativeCore(await Promise.resolve().then(__webpack_require__.bind(__webpack_require__,880))),loadedCore}finally{window.fetch=e}}function initializeWasmCore(){return loadedCore?Promise.resolve(loadedCore):wasmInitialization||(wasmInitialization=(async()=>{if("undefined"!=typeof window)return initializeBrowserWasm();const wasm=eval("require")("./wasm/node/sonic_ws_core.js");return setNativeCore(wasm),loadedCore})().finally(()=>{wasmInitialization=void 0}),wasmInitialization)}function loadNativeCore(addonPath){if(loadedCore&&!addonPath)return loadedCore;const candidates=addonPath?[addonPath]:["undefined"!=typeof process?process.env.SONIC_WS_CORE_PATH:void 0,`${__webpack_dirname__}/sonic_ws_core.node`,`${__webpack_dirname__}/../../../native/sonic_ws_core.node`].filter(e=>Boolean(e)),failures=[],nodeRequire="undefined"==typeof window?eval("require"):void 0;for(const e of candidates)try{const t=nodeRequire(e);return assertNativeCore(t),addonPath||(loadedCore=t),t}catch(t){failures.push(`${e}: ${t instanceof Error?t.message:String(t)}`)}if("undefined"==typeof window)try{const e=nodeRequire("./wasm/node/sonic_ws_core.js");return assertNativeCore(e),loadedCore=e,e}catch(e){failures.push(`Node WASM fallback: ${e instanceof Error?e.message:String(e)}`)}throw new Error(`SonicWS codec is not initialized. In Node, set SONIC_WS_CORE_PATH; in browsers, await initializeWasmCore().\n${failures.join("\n")}`)}function enumIndex(e,t){const n=e.values.findIndex(e=>e===t||"number"==typeof e&&"number"==typeof t&&Number.isNaN(e)&&Number.isNaN(t));if(n<0)throw new Error(`Value ${String(t)} does not exist in enum ${e.tag}`);return n}function encodeNative(e,t,n,a=loadNativeCore()){switch(e){case PacketType_1.PacketType.NONE:if(null!=t&&(!Array.isArray(t)||0!==t.length))throw new TypeError("NONE only accepts null, undefined, or an empty array");return new Uint8Array(0);case PacketType_1.PacketType.RAW:case PacketType_1.PacketType.JSON:if(!(t instanceof Uint8Array||Array.isArray(t)))throw new TypeError((e===PacketType_1.PacketType.JSON?"JSON wire data":"RAW")+" requires a Uint8Array or number array");return t instanceof Uint8Array?buffer(t):Uint8Array.from(t);case PacketType_1.PacketType.BYTES:case PacketType_1.PacketType.SHORTS:case PacketType_1.PacketType.VARINT:case PacketType_1.PacketType.DELTAS:return a.encodeSigned(e,values(t));case PacketType_1.PacketType.UBYTES:case PacketType_1.PacketType.USHORTS:case PacketType_1.PacketType.UVARINT:return a.encodeUnsigned(e,values(t));case PacketType_1.PacketType.FLOATS:case PacketType_1.PacketType.DOUBLES:return a.encodeFloats(e,values(t));case PacketType_1.PacketType.STRINGS_ASCII:case PacketType_1.PacketType.STRINGS_UTF16:return a.encodeStrings(e,values(t));case PacketType_1.PacketType.BOOLEANS:return a.encodeBooleans(values(t));case PacketType_1.PacketType.HEX:{const e=Array.isArray(t)?t[0]:t;if("string"!=typeof e)throw new TypeError("HEX requires one string");return a.encodeHex(e)}case PacketType_1.PacketType.ENUMS:if(!n)throw new Error("ENUMS requires an EnumPackage");return Uint8Array.from(values(t).map(e=>enumIndex(n,e)));case PacketType_1.PacketType.KEY_EFFECTIVE:throw new Error("KEY_EFFECTIVE is not implemented");default:throw new Error(`Unknown packet type: ${e}`)}}function decodeNative(e,t,n=4294967295,a,r=loadNativeCore()){const s=buffer(t);switch(e){case PacketType_1.PacketType.NONE:if(0!==t.byteLength)throw new Error("NONE packet contains data");return;case PacketType_1.PacketType.RAW:case PacketType_1.PacketType.JSON:return r.decodeRaw(s);case PacketType_1.PacketType.BYTES:case PacketType_1.PacketType.SHORTS:case PacketType_1.PacketType.VARINT:case PacketType_1.PacketType.DELTAS:return r.decodeSigned(e,s);case PacketType_1.PacketType.UBYTES:case PacketType_1.PacketType.USHORTS:case PacketType_1.PacketType.UVARINT:return r.decodeUnsigned(e,s);case PacketType_1.PacketType.FLOATS:case PacketType_1.PacketType.DOUBLES:return r.decodeFloats(e,s);case PacketType_1.PacketType.STRINGS_ASCII:case PacketType_1.PacketType.STRINGS_UTF16:return r.decodeStrings(e,s);case PacketType_1.PacketType.BOOLEANS:return r.decodeBooleans(s,n);case PacketType_1.PacketType.HEX:return r.decodeHex(s);case PacketType_1.PacketType.ENUMS:if(!a)throw new Error("ENUMS requires an EnumPackage");return[...t].map(e=>{if(e>=a.values.length)throw new Error(`Enum index ${e} is out of range`);return a.values[e]});case PacketType_1.PacketType.KEY_EFFECTIVE:throw new Error("KEY_EFFECTIVE is not implemented");default:throw new Error(`Unknown packet type: ${e}`)}}function validateNative(e,t,n,a,r={},s=loadNativeCore()){if(e!==PacketType_1.PacketType.ENUMS)s.validateEncoded(e,buffer(t),n,a,r.compressed??!1,r.batched??!1,r.maxBatchSize);else{if(!r.enumData)throw new Error("ENUMS requires an EnumPackage");s.validateEnum(buffer(t),r.enumData.values.length,n,a)}}function encodeNativeObject(e,t,n=loadNativeCore()){if(t.length!==e.types.length)throw new Error("Object field count does not match schema");let a=0;const r=e.types.map((r,s)=>encodeNative(r,t[s],r===PacketType_1.PacketType.ENUMS?e.enumData?.[a++]:void 0,n));return n.frameObject(r)}function decodeNativeObject(e,t,n=loadNativeCore()){const a=n.unframeObject(buffer(t),e.types.length);let r=0;return a.map((t,a)=>decodeNative(e.types[a],t,e.dataMaxes[a],e.types[a]===PacketType_1.PacketType.ENUMS?e.enumData?.[r++]:void 0,n))}function validateNativeObject(e,t,n=loadNativeCore()){n.validateObject(buffer(t),[...e.types],[...e.dataMins],[...e.dataMaxes],(e.enumData??[]).map(e=>e.values.length))}function encodeNativeBatch(e,t,n=loadNativeCore()){return n.encodeBatch(e.map(buffer),t)}function decodeNativeBatch(e,t,n=0,a,r=loadNativeCore()){const s=Number.isFinite(n)&&n>0?n:0;return r.decodeBatch(buffer(e),t,s,a)}function deflateNative(e,t=loadNativeCore()){return t.deflateRaw(buffer(e))}function inflateNative(e,t,n=loadNativeCore()){return n.inflateRaw(buffer(e),t)}},388(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.SET_PACKAGES=t.ENUM_KEY_TO_TAG=t.ENUM_TAG_TO_KEY=t.MAX_ENUM_SIZE=void 0,t.DefineEnum=function(e,n){const a=t.SET_PACKAGES[e];if(a){if(a.values.find((e,t)=>n[t]!=e))throw new Error(`Pre-existing enum package of tag '${e}' is set and different!`);return a}if(n.length>t.MAX_ENUM_SIZE)throw new Error(`An enum can only hold ${t.MAX_ENUM_SIZE} possible values.`);return t.ENUM_TAG_TO_KEY[e]=Object.fromEntries(n.map((e,t)=>[e,t])),t.ENUM_KEY_TO_TAG[e]=Object.fromEntries(n.map((e,t)=>[t,e])),t.SET_PACKAGES[e]=new r.EnumPackage(e,n)},t.WrapEnum=function(e,n){if(!(n in t.ENUM_TAG_TO_KEY[e]))throw new Error(`Value "${n}" does not exist in enum "${e}"`);return t.ENUM_TAG_TO_KEY[e][n]},t.DeWrapEnum=function(e,n){return t.ENUM_KEY_TO_TAG[e][n]};const a=n(30),r=n(98);t.MAX_ENUM_SIZE=a.MAX_BYTE,t.ENUM_TAG_TO_KEY={},t.ENUM_KEY_TO_TAG={},t.SET_PACKAGES={}},404(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.PacketHolder=void 0;t.PacketHolder=class{key;keys;tags;packetMap;packets;constructor(e){this.key=1,this.keys={},this.tags={},this.packetMap={},e&&this.holdPackets(e)}createKey(e){this.keys[e]=this.key,this.tags[this.key]=e,this.key++}holdPackets(e){this.packets=e;for(const t of e)this.createKey(t.tag),this.packetMap[t.tag]=t}getKey(e){if(!(e in this.keys))throw new Error(`Not a valid tag: ${e}`);return this.keys[e]}getTag(e){if(e in this.tags)return this.tags[e]}getPacket(e){if(!(e in this.packetMap))throw new Error("Unknown packet tag: "+e);return this.packetMap[e]}hasKey(e){return e in this.tags}hasTag(e){return e in this.keys}getKeys(){return this.keys}getTagMap(){return this.tags}getTags(){return Object.values(this.tags)}getPackets(){return this.packets}serialize(){return this.packets.map(e=>e.serialize()).flat()}}},410(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.setHashFunc=function(e){i=e?r:s},t.hashValue=function(e){return i(e)};const n=1099511628211n,a=(1n<<64n)-1n,r=e=>{let t=14695981039346656037n;const r=e=>{if(null===e)return t^=0n,void(t=t*n&a);const s=typeof e;if("number"===s)return t^=BigInt(Math.trunc(e)),void(t=t*n&a);if("string"!==s){if("boolean"===s)return t^=e?1n:0n,void(t=t*n&a);if(Array.isArray(e))for(let t=0;t<e.length;t++)r(e[t]);else if("object"===s){const s=Object.keys(e).sort();for(let i=0;i<s.length;i++){const o=s[i];for(let e=0;e<o.length;e++)t^=BigInt(o.charCodeAt(e)),t=t*n&a;r(e[o])}}}else for(let r=0;r<e.length;r++)t^=BigInt(e.charCodeAt(r)),t=t*n&a};return r(e),t},s=e=>{let t=2166136261;const n=e=>{if(null===e)return void(t^=0);const a=typeof e;if("number"===a)return t^=0|e,void(t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24));if("string"!==a)if("boolean"!==a){if(Array.isArray(e))for(let t=0;t<e.length;t++)n(e[t]);else if("object"===a){const a=Object.keys(e).sort();for(let r=0;r<a.length;r++){const s=a[r];for(let e=0;e<s.length;e++)t^=s.charCodeAt(e),t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24);n(e[s])}}}else t^=e?1:0;else for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24)};return n(e),t>>>0};let i=r},433(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.processPacket=c,t.listenPacket=async function(e,t,n){if("string"==typeof e)return n(e);const[a,r]=e;try{if(r&&Array.isArray(a))for(const e of t)await e(...a);else for(const e of t)await e(a)}catch(e){console.error(e),n(e)}},t.CreatePacket=f,t.CreateObjPacket=function(e){let{tag:t,types:n=[],dataMaxes:s,dataMins:i,noDataRange:o=!1,dontSpread:c=!1,autoFlatten:f=!1,validator:w=null,dataBatching:_=0,maxBatchSize:y=10,rateLimit:m=0,enabled:g=!0,async:b=!1,gzipCompression:v=n&&n.includes(r.PacketType.JSON)}=e;if(!t)throw new Error("Tag not selected!");if(!n||0==n.length)throw new Error("Types is set to 0 length");for(const e of n)if(d(e))throw new Error(`Invalid packet type in "${t}" packet: ${e}`);o?(s=Array.from({length:n.length}).map(()=>l),i=Array.from({length:n.length}).map(()=>0)):(null==s?s=Array.from({length:n.length}).map(()=>1):Array.isArray(s)||(s=Array.from({length:n.length}).map(()=>s)),null==i?i=Array.from({length:n.length}).map((e,t)=>s[t]):Array.isArray(i)||(i=Array.from({length:n.length}).map(()=>i)));const S=s.map(u),k=i.map((e,t)=>n[t]==r.PacketType.NONE?0:h(e,S[t])),E=new a.PacketSchema(!0,n,b,k,S,p(m),c,f,!1,_,y,v);return new a.Packet(t,E,w,g,!1)},t.CreateEnumPacket=function(e){const{tag:t,enumData:n,dataMax:a=1,dataMin:r=0,noDataRange:s=!1,dontSpread:i=!1,validator:o=null,dataBatching:c=0,maxBatchSize:d=10,rateLimit:l=0,enabled:u=!0,async:h=!1}=e;return f({tag:t,type:n,dataMax:a,dataMin:r,noDataRange:s,dontSpread:i,validator:o,dataBatching:c,maxBatchSize:d,rateLimit:l,enabled:u,async:h})},t.CreateKeyEffective=function(e){const{tag:t,count:n=2,validator:a=null,async:r=!1}=e;if(!t)throw new Error("Tag not selected!");if(n<2)throw new Error("Must have at least 2 key consumptions on key effective packet!");throw new Error("Currently W.I.P.")},t.FlattenData=w,t.UnFlattenData=function(e){return e[0]?.map((t,n)=>e.map(e=>e[n]))??[]};const a=n(102),r=n(619),s=n(98),i=n(30),o=n(410);async function c(e,t,n,a,s,d=!1){const l=e.getKey(t),u=e.getPacket(t);return async function(e,t,n,a,r,s,i){if(e[0]&&!s)return new Promise(t=>e[1].push([t,a,r]));e[0]=!0;const o=await i();if(e[1].length>0){const[a,r,s]=e[1].shift();queueMicrotask(async()=>{a(await c(t,r,s,e,n,!0))})}else e[0]=!1;return o}(a,e,s,t,n,d,async()=>{if(u.rereference){if(-1===s)throw new Error("Cannot send a re-referenced packet from the server-wide sender!");const e=(0,o.hashValue)(n);if(u.lastSent[s]===e)return[l,i.EMPTY_UINT8,u];u.lastSent[s]=e}if(u.autoFlatten)n=w(n[0]);else{if(n.length>u.maxSize)throw new Error(`Packet "${t}" only allows ${u.maxSize} values!`);if(n.length<u.minSize)throw new Error(`Packet "${t}" requires at least ${u.minSize} values!`)}if(u.object){if(n=n.map(e=>Array.isArray(e)?e:[e]),!u.autoFlatten){const e=u.dataMin,a=u.dataMax;for(let r=0;r<e.length;r++){if(n[r].length<e[r])throw new Error(`Section ${r+1} of packet "${t}" requires at least ${e[r]} values!`);if(n[r].length>a[r])throw new Error(`Section ${r+1} of packet "${t}" only allows ${a[r]} values!`)}}}else if(u.type!==r.PacketType.JSON){const e=n.find(e=>"object"==typeof e&&null!=e);e&&console.warn(`Passing an array will result in undefined behavior (${JSON.stringify(e)}). Spread the array with ...arr`)}const e=n.length>0?await u.processSend(n):i.EMPTY_UINT8;return[l,e,u]})}function d(e){return!(("number"==typeof e&&e in r.PacketType||e instanceof s.EnumPackage)&&e!=r.PacketType.KEY_EFFECTIVE)}const l=2048383;function u(e){return e<0?(console.warn("Having a data maximum below 0 does not do anything!"),0):e>l?(console.warn("Only 2048383 values can be sent on a type! Uhh make an issue if you want to send more."),l):e}function h(e,t){return e<0?(console.warn("Having a data minimum below 0 does not do anything!"),0):e>t?(console.warn("Data minimum can not be higher than the data maximum!"),t):e}function p(e){if(!Number.isFinite(e)||e<0)throw new Error("Rate limit must be a non-negative finite number");return(e=Math.floor(e))>i.MAX_USHORT?(console.warn(`A rate limit above ${i.MAX_USHORT} is considered infinite.`),0):e}function f(e){let{tag:t,type:n=r.PacketType.NONE,dataMax:s=1,dataMin:i=1,noDataRange:o=!1,dontSpread:c=!1,validator:f=null,dataBatching:w=0,maxBatchSize:_=10,rateLimit:y=0,enabled:m=!0,async:g=!1,gzipCompression:b=n==r.PacketType.JSON,rereference:v=!1}=e;if(!t)throw new Error("Tag not selected!");if(o?(i=v?1:0,s=l):null==i&&(i=n==r.PacketType.NONE?0:s),v&&0==i)throw new Error("Rereference cannot be true if the dataMin is 0");if(d(n))throw new Error(`Invalid packet type: ${n}`);const S=new a.PacketSchema(!1,n,g,h(i,s),u(s),p(y),c,!1,v,w,_,b);return new a.Packet(t,S,f,m,!1)}function w(e){if(null==e)return[];const t=e[0];if(null==t)return[];if(!Array.isArray(t))throw new Error(`Cannot flatten array: ${e}`);return t.map((t,n)=>e.map(e=>e[n]))??[]}},605(e,t,n){var a=n(804);e.exports=n.v(t,e.id,"a8f247f5205d0c667c14",{"./sonic_ws_core_bg.js":{__wbg_get_unchecked_6e0ad6d2a41b06f6:a.ss,__wbg_length_370319915dc99107:a.Sg,__wbg_push_d2ae3af0c1217ae6:a.Tb,__wbg_new_32b398fb48b6d94a:a.gV,__wbg_new_cd45aabdf6073e84:a.EW,__wbg_length_1f0964f4a5e2c6d8:a.Pt,__wbg_prototypesetcall_4770620bbe4688a0:a.pe,__wbg_new_from_slice_77cdfb7977362f3c:a.BV,__wbg___wbindgen_string_get_b0ca35b86a603356:a.oF,__wbg___wbindgen_number_get_394265ed1e1b84ee:a.JV,__wbg___wbindgen_throw_344f42d3211c4765:a.F6,__wbg___wbindgen_boolean_get_fa956cfa2d1bd751:a.sL,__wbindgen_init_externref_table:a.bL,__wbindgen_cast_0000000000000001:a.NR,__wbindgen_cast_0000000000000002:a.U_}})},619(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.PacketType=void 0,function(e){e[e.NONE=0]="NONE",e[e.RAW=1]="RAW",e[e.STRINGS_ASCII=2]="STRINGS_ASCII",e[e.STRINGS_UTF16=3]="STRINGS_UTF16",e[e.STRINGS=2]="STRINGS",e[e.ENUMS=4]="ENUMS",e[e.BYTES=5]="BYTES",e[e.UBYTES=6]="UBYTES",e[e.SHORTS=7]="SHORTS",e[e.USHORTS=8]="USHORTS",e[e.VARINT=9]="VARINT",e[e.UVARINT=10]="UVARINT",e[e.DELTAS=11]="DELTAS",e[e.FLOATS=12]="FLOATS",e[e.DOUBLES=13]="DOUBLES",e[e.BOOLEANS=14]="BOOLEANS",e[e.KEY_EFFECTIVE=15]="KEY_EFFECTIVE",e[e.JSON=16]="JSON",e[e.HEX=17]="HEX"}(n||(t.PacketType=n={}))},804(e,t,n){function a(e,t,n,a){const r=Z.decodeBatch(e,t,n,K(a)?Number.MAX_SAFE_INTEGER:a>>>0);if(r[2])throw Y(r[1]);return Y(r[0])}function r(e,t){const n=Z.decodeBooleans(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function s(e,t){const n=Z.decodeFloats(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function i(e){let t,n;try{const s=Z.decodeHex(e);var a=s[0],r=s[1];if(s[3])throw a=0,r=0,Y(s[2]);return t=a,n=r,V(a,r)}finally{Z.__wbindgen_free(t,n,1)}}function o(e){const t=Z.decodeRaw(e);if(t[2])throw Y(t[1]);return Y(t[0])}function c(e,t){const n=Z.decodeSigned(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function d(e,t){const n=Z.decodeStrings(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function l(e,t){const n=Z.decodeUnsigned(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function u(e){const t=Z.deflateRaw(e);if(t[2])throw Y(t[1]);return Y(t[0])}function h(e,t){const n=Z.encodeBatch(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function p(e){const t=Z.encodeBooleans(e);if(t[2])throw Y(t[1]);return Y(t[0])}function f(e,t){const n=Z.encodeFloats(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function w(e){const t=q(e,Z.__wbindgen_malloc,Z.__wbindgen_realloc),n=ee,a=Z.encodeHex(t,n);if(a[2])throw Y(a[1]);return Y(a[0])}function _(e,t){const n=Z.encodeSigned(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function y(e,t){const n=Z.encodeStrings(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function m(e,t){const n=Z.encodeUnsigned(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function g(e){const t=Z.frameObject(e);if(t[2])throw Y(t[1]);return Y(t[0])}function b(e,t){const n=Z.inflateRaw(e,K(t)?Number.MAX_SAFE_INTEGER:t>>>0);if(n[2])throw Y(n[1]);return Y(n[0])}function v(e,t){const n=Z.unframeObject(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function S(e,t,n,a,r,s,i){const o=Z.validateEncoded(e,t,n,a,r,s,K(i)?Number.MAX_SAFE_INTEGER:i>>>0);if(o[1])throw Y(o[0])}function k(e,t,n,a){const r=Z.validateEnum(e,t,n,a);if(r[1])throw Y(r[0])}function E(e,t,n,a,r){const s=Z.validateObject(e,t,n,a,r);if(s[1])throw Y(s[0])}function T(e){const t="boolean"==typeof e?e:void 0;return K(t)?16777215:t?1:0}function N(e,t){const n="number"==typeof t?t:void 0;W().setFloat64(e+8,K(n)?0:n,!0),W().setInt32(e+0,!K(n),!0)}function P(e,t){const n="string"==typeof t?t:void 0;var a=K(n)?0:q(n,Z.__wbindgen_malloc,Z.__wbindgen_realloc),r=ee;W().setInt32(e+4,r,!0),W().setInt32(e+0,a,!0)}function A(e,t){throw new Error(V(e,t))}function O(e,t){return e[t>>>0]}function x(e){return e.length}function M(e){return e.length}function C(){return new Array}function I(e){return new Uint8Array(e)}function R(e,t){return new Uint8Array(F(e,t))}function B(e,t,n){Uint8Array.prototype.set.call(F(e,t),n)}function U(e,t){return e.push(t)}function D(e){return e}function L(e,t){return V(e,t)}function j(){const e=Z.__wbindgen_externrefs,t=e.grow(4);e.set(0,void 0),e.set(t+0,void 0),e.set(t+1,null),e.set(t+2,!0),e.set(t+3,!1)}function F(e,t){return e>>>=0,$().subarray(e/1,e/1+t)}n.d(t,{B4:()=>h,BV:()=>R,Dq:()=>o,EF:()=>i,EW:()=>I,F6:()=>A,JV:()=>N,NR:()=>D,Pt:()=>x,Q5:()=>E,Sg:()=>M,Tb:()=>U,Ts:()=>_,U_:()=>L,XC:()=>y,_s:()=>f,at:()=>u,bL:()=>j,cv:()=>v,gV:()=>C,hD:()=>S,i1:()=>k,i4:()=>s,iT:()=>p,iX:()=>r,jN:()=>a,lI:()=>te,mU:()=>w,mk:()=>l,nt:()=>g,oF:()=>P,pe:()=>B,qO:()=>m,sL:()=>T,ss:()=>O,tD:()=>c,wS:()=>b,zC:()=>d});let z=null;function W(){return(null===z||!0===z.buffer.detached||void 0===z.buffer.detached&&z.buffer!==Z.memory.buffer)&&(z=new DataView(Z.memory.buffer)),z}function V(e,t){return function(e,t){G+=t,G>=X&&(J=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0}),J.decode(),G=t);return J.decode($().subarray(e,e+t))}(e>>>0,t)}let H=null;function $(){return null!==H&&0!==H.byteLength||(H=new Uint8Array(Z.memory.buffer)),H}function K(e){return null==e}function q(e,t,n){if(void 0===n){const n=Q.encode(e),a=t(n.length,1)>>>0;return $().subarray(a,a+n.length).set(n),ee=n.length,a}let a=e.length,r=t(a,1)>>>0;const s=$();let i=0;for(;i<a;i++){const t=e.charCodeAt(i);if(t>127)break;s[r+i]=t}if(i!==a){0!==i&&(e=e.slice(i)),r=n(r,a,a=i+3*e.length,1)>>>0;const t=$().subarray(r+i,r+a);i+=Q.encodeInto(e,t).written,r=n(r,a,i,1)>>>0}return ee=i,r}function Y(e){const t=Z.__wbindgen_externrefs.get(e);return Z.__externref_table_dealloc(e),t}let J=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0});J.decode();const X=2146435072;let G=0;const Q=new TextEncoder;"encodeInto"in Q||(Q.encodeInto=function(e,t){const n=Q.encode(e);return t.set(n),{read:e.length,written:n.length}});let Z,ee=0;function te(e){Z=e}},853(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.DebugClient=void 0;t.DebugClient=class{host;constructor(e){this.host=e;const t=document.createElement("sonicws");t.innerHTML="<style>sws-h3{margin:0;color:#fff;font-size:16px;font-weight:600}#sonicws-container{display:flex;flex-direction:column;position:absolute;top:50px;left:50px;width:75vw;min-width:33vw;min-height:25vh;max-height:75vh;max-width:75vw;font-family:Arial,sans-serif;background-color:#2c2c2c;border-radius:10px;box-shadow:0 8px 20px rgba(0,0,0,.4);overflow:hidden;user-select:none;transition:box-shadow .2s ease;z-index:2147483647}#sonicws-container:hover{box-shadow:0 12px 28px rgba(0,0,0,.6)}#sonicws-header{display:flex;justify-content:space-between;align-items:center;cursor:move;background:linear-gradient(90deg,#4a90e2,#357ab7);padding:10px 12px;border-top-left-radius:10px;border-top-right-radius:10px}#sonicws-toggle{font-size:18px;font-weight:700;cursor:pointer;color:#fff;user-select:none}#sonicws-body{flex:1;display:flex;padding:12px;color:#e0e0e0;font-size:14px;min-height:0}#sonicws-stats{display:flex;flex-direction:column;min-width:140px}#sonicws-stats sws-p{margin:4px 0}#sonicws-packets{min-height:0;display:flex;flex-direction:column;flex:1;margin-left:10px;background-color:#1e1e1e;padding:8px;border-radius:8px;overflow-y:scroll}sws-div.packet{background-color:#2a2a2a;border-radius:6px;padding:3px 5px;margin-bottom:2px;cursor:pointer;transition:background .2s ease,transform .1s ease;display:flex;flex-direction:column}sws-div.packet:hover{background-color:#3a3a3a;transform:translateY(-1px)}sws-div.packet-header{display:flex;align-items:flex-start;flex-wrap:wrap;font-size:11px;white-space:normal;word-break:break-word}sws-span.packet-arrow{font-weight:700;margin-right:6px}sws-div.packet-details{margin-top:6px;font-size:10px;color:#aaa;display:none;flex-direction:column}sws-div.packet.expanded sws-div.packet-details{display:flex}#sonicws-resizer{width:12px;height:12px;background:#666;position:absolute;right:0;bottom:0;cursor:se-resize;border-bottom-right-radius:10px;transition:background .2s ease}#sonicws-resizer:hover{background:#888}#sonicws-container.minimized{width:auto!important;height:auto!important;min-width:unset;min-height:unset}#sonicws-container.minimized #sonicws-body,#sonicws-container.minimized #sonicws-resizer{display:none}#sonicws-container.minimized #sonicws-header{padding:8px 12px}#sonicws-container.minimized #sonicws-title{font-size:14px}</style><sws-div id=sonicws-container><sws-div id=sonicws-header><sws-h3 id=sonicws-title>SonicWS Debug Menu</sws-h3><sws-span id=sonicws-toggle>−</sws-span></sws-div><sws-div id=sonicws-body><sws-div id=sonicws-stats><sws-p>Status:<sws-span id=sonicws-status>Connecting</sws-span></sws-p><sws-p>Sent Packets:<sws-span id=sonicws-sent>0</sws-span></sws-p><sws-p>Received Packets:<sws-span id=sonicws-received>0</sws-span></sws-p><sws-p>Total Bytes Sent:<sws-span id=sonicws-sentbytes>0</sws-span></sws-p><sws-p>Total Bytes Received:<sws-span id=sonicws-receivedbytes>0</sws-span></sws-p><sws-p>Total Bytes Saved:<sws-span id=sonicws-savedbytes>0</sws-span></sws-p></sws-div><sws-div id=sonicws-packets></sws-div></sws-div><sws-div id=sonicws-resizer></sws-div></sws-div>",document.body?(document.body.appendChild(t),this._loadDebugScript()):document.addEventListener("DOMContentLoaded",()=>{document.body.appendChild(t),this._loadDebugScript()})}_evalInScope(e){const t=this.host;return new Function("send","WrapEnum","DeWrapEnum","FlattenData","UnFlattenData",`"use strict"; return (${e});`)(t.send.bind(t),t.WrapEnum.bind(t),t.DeWrapEnum.bind(t),t.FlattenData.bind(t),t.UnFlattenData.bind(t))}_loadDebugScript(){const e={},t={},n=this.host;this.host.addMiddleware(new class{onReceive_pre(e,n){t[e]??=[],t[e].push([n,performance.now()])}onReceive_post(e,a){const[r,s]=t[e].shift();T("received",`${e} (0x${n.serverPackets.getKey(e).toString(16).toUpperCase()})`,r,JSON.stringify(a),performance.now()-s)}onSend_pre(t,n){e[t]??=[],e[t].push([n,performance.now()])}onSend_post(t,a){const[r,s]=e[t].shift();T("sent",`${t} (0x${n.clientPackets.getKey(t).toString(16).toUpperCase()})`,a,JSON.stringify(r),performance.now()-s)}onStatusChange(e){k(e)}});const a=e=>document.getElementById(e),r=a("sonicws-container"),s=a("sonicws-header"),i=a("sonicws-resizer"),o=a("sonicws-status"),c=a("sonicws-packets"),d=a("sonicws-sent"),l=a("sonicws-received"),u=a("sonicws-sentbytes"),h=a("sonicws-receivedbytes"),p=a("sonicws-savedbytes"),f=document.getElementById("sonicws-toggle"),w=document.getElementById("sonicws-title");let _=!1;const y=document.createElement("input");y.type="text",y.placeholder='send("tag", 5)',y.style.marginTop="8px",y.style.width="100%",y.style.boxSizing="border-box";const m=document.createElement("button");function g(){const e=r.getBoundingClientRect(),t=window.innerWidth-e.width,n=window.innerHeight-e.height,a=Math.min(Math.max(0,e.left),Math.max(0,t)),s=Math.min(Math.max(0,e.top),Math.max(0,n));r.style.left=a+"px",r.style.top=s+"px"}m.innerText="Run",m.style.marginTop="4px",m.style.width="100%",a("sonicws-stats").appendChild(y),a("sonicws-stats").appendChild(m),m.addEventListener("click",()=>{try{this._evalInScope(y.value)}catch(e){console.error(e)}}),f.addEventListener("click",e=>{e.stopPropagation(),_=!_,_?(r.classList.add("minimized"),w.innerText="SWS",f.innerText="+",r.style.width="",r.style.height=""):(r.classList.remove("minimized"),w.innerText="SonicWS Debug Menu",f.innerText="−"),g()});const b={sentPackets:0,receivedPackets:0,totalBytesSent:0,totalBytesReceived:0,totalBytesSaved:0},v=new Proxy(b,{get(e,t){switch(t){case"sonicws-sent":return b.sentPackets;case"sonicws-received":return b.receivedPackets;case"sonicws-sentbytes":return b.totalBytesSent;case"sonicws-receivedbytes":return b.totalBytesReceived;case"sonicws-savedbytes":return b.totalBytesSaved;default:return}},set(e,t,n){switch(t){case"sonicws-sent":return b.sentPackets=n,d.innerText=n.toLocaleString(),!0;case"sonicws-received":return b.receivedPackets=n,l.innerText=n.toLocaleString(),!0;case"sonicws-sentbytes":{b.totalBytesSent=n;const{amt:e,unit:t}=S(n);return u.innerText=e+t,!0}case"sonicws-receivedbytes":{b.totalBytesReceived=n;const{amt:e,unit:t}=S(n);return h.innerText=e+t,!0}case"sonicws-savedbytes":{b.totalBytesSaved=n;const{amt:e,unit:t}=S(n);return p.innerText=e+t,!0}default:return!1}}}),S=e=>{if(!Number.isFinite(e)||e<0)return{amt:0,unit:"B"};const t=["B","KB","MB","GB","TB"];let n=e,a=0;for(;n>=1024&&a<t.length-1;)n/=1024,a++;return{amt:0==a?n.toString():n.toFixed(2),unit:t[a]}};function k(e){switch(e){case WebSocket.CLOSED:o.innerText="Closed",o.style.color="#f00";break;case WebSocket.CLOSING:o.innerText="Closing",o.style.color="#fa0";break;case WebSocket.OPEN:o.innerText="Open",o.style.color="#0f0";break;case WebSocket.CONNECTING:o.innerText="Connecting",o.style.color="#ff0";break;default:o.innerText="Unknown",o.style.color="#777"}}k(WebSocket.CONNECTING);const E=new TextEncoder;function T(e,t,n,a,r){const s=new Date,i=n.length+("sent"==e?1:0),o=E.encode(a).length-i+1,d=document.createElement("sws-div");d.classList.add("packet");const l=document.createElement("sws-div");l.classList.add("packet-header");const u=document.createElement("sws-span");u.classList.add("packet-arrow"),u.innerText="sent"===e?"⬆":"⬇",u.style.color="sent"===e?"#0f0":"#f00";const h=document.createElement("sws-span");h.innerText=t+": "+a,l.appendChild(u),l.appendChild(h);const p=document.createElement("sws-div");p.classList.add("packet-details"),p.innerHTML=`\n <sws-p> Raw Bytes: ${i}b (saved ~${o}b)</sws-p>\n <sws-p> Processed At: ${s.toISOString()} </sws-p>\n <sws-p> Processing Time: <sws-span class="processing-time" > ${r.toFixed(1)} </sws-span> ms</sws-p>\n `,d.appendChild(l),d.appendChild(p),c.append(d),l.addEventListener("click",()=>d.classList.toggle("expanded")),"sent"===e?(v["sonicws-sent"]++,v["sonicws-sentbytes"]+=i):(v["sonicws-received"]++,v["sonicws-receivedbytes"]+=i),v["sonicws-savedbytes"]+=o}let N=!1,P=0,A=0,O=0,x=0,M=!1,C=0,I=0,R=0,B=0;s.addEventListener("mousedown",e=>{N=!0,P=e.clientX,A=e.clientY;const t=r.getBoundingClientRect();O=t.left,x=t.top,e.preventDefault()}),i.addEventListener("mousedown",e=>{M=!0,C=e.clientX,I=e.clientY;const t=r.getBoundingClientRect();R=t.width,B=t.height,e.preventDefault()}),document.addEventListener("mousemove",e=>{N&&(r.style.left=O+e.clientX-P+"px",r.style.top=x+e.clientY-A+"px",g()),M&&!_&&(r.style.width=R+e.clientX-C+"px",r.style.height=B+e.clientY-I+"px",g())}),document.addEventListener("mouseup",()=>{N=!1,M=!1}),g(),window.addEventListener("resize",g)}}},880(e,t,n){n.a(e,async(e,a)=>{try{n.r(t),n.d(t,{decodeBatch:()=>s.jN,decodeBooleans:()=>s.iX,decodeFloats:()=>s.i4,decodeHex:()=>s.EF,decodeRaw:()=>s.Dq,decodeSigned:()=>s.tD,decodeStrings:()=>s.zC,decodeUnsigned:()=>s.mk,deflateRaw:()=>s.at,encodeBatch:()=>s.B4,encodeBooleans:()=>s.iT,encodeFloats:()=>s._s,encodeHex:()=>s.mU,encodeSigned:()=>s.Ts,encodeStrings:()=>s.XC,encodeUnsigned:()=>s.qO,frameObject:()=>s.nt,inflateRaw:()=>s.wS,unframeObject:()=>s.cv,validateEncoded:()=>s.hD,validateEnum:()=>s.i1,validateObject:()=>s.Q5});var r=n(605),s=n(804),i=e([r]);r=(i.then?(await i)():i)[0],(0,s.lI)(r),r.__wbindgen_start(),a()}catch(e){a(e)}})},913(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.CloseCodes=t.Connection=void 0,t.getClosureCause=function(e){if(e>=4e3)return i[e]??"UNKNOWN";switch(e){case 1e3:return"NORMAL_CLOSURE";case 1001:return"GOING_AWAY";case 1002:return"PROTOCOL_ERROR";case 1003:return"UNSUPPORTED_DATA";case 1006:return"ABNORMAL_CLOSURE";default:return"UNKNOWN"}};const a=n(985),r=n(8);class s extends a.MiddlewareHolder{listeners;rawSendListeners=[];name;closed=!1;socket;_timers={};batcher;_on;_off;id;constructor(e,t,n,a,s){super(),this.id=t,this.listeners={},this.name=n,this.socket=e,this.batcher=new r.BatchHelper,this._on=a,this._off=s,this._on("close",()=>{this.callMiddleware("onStatusChange",WebSocket.CLOSED),this.closed=!0;for(const[e,t,n]of Object.values(this._timers))this.clearTimeout(e),n&&t(!0)}),this._on("open",()=>this.callMiddleware("onStatusChange",WebSocket.OPEN))}setTimeout(e,t,n=!1){const a=setTimeout(()=>{e(),this.clearTimeout(a)},t);return this._timers[a]=[a,e,n],a}setInterval(e,t,n=!1){const a=setInterval(e,t);return this._timers[a]=[a,e,n],a}clearTimeout(e){clearTimeout(e),delete this._timers[e]}clearInterval(e){this.clearTimeout(e)}raw_send(e){this.socket.send(e);for(const t of this.rawSendListeners)t(e)}raw_onmessage(e){this._on("message",e)}raw_onsend(e){this.rawSendListeners.push(e)}close(e=1e3,t){this.closed=!0,this.socket.close(e,t?.toString())}isClosed(){return this.closed||this.socket.readyState==WebSocket.CLOSED}async setName(e){await this.callMiddleware("onNameChange",e)||(this.name=e)}getName(){return this.name}}var i;t.Connection=s,function(e){e[e.RATELIMIT=4e3]="RATELIMIT",e[e.SMALL=4001]="SMALL",e[e.INVALID_KEY=4002]="INVALID_KEY",e[e.INVALID_PACKET=4003]="INVALID_PACKET",e[e.INVALID_DATA=4004]="INVALID_DATA",e[e.REPEATED_HANDSHAKE=4005]="REPEATED_HANDSHAKE",e[e.DISABLED_PACKET=4006]="DISABLED_PACKET",e[e.MIDDLEWARE=4007]="MIDDLEWARE",e[e.MANUAL_SHUTDOWN=4008]="MANUAL_SHUTDOWN"}(i||(t.CloseCodes=i={}))},937(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.SonicWSCore=void 0;const a=n(404),r=n(30),s=n(351),i=n(433),o=n(234),c=n(102),d=n(8),l=n(950),u=n(913),h=n(157);class p extends u.Connection{preListen;clientPackets=new a.PacketHolder;serverPackets=new a.PacketHolder;pastKeys=!1;readyListeners=[];bufferHandler;_timers={};asyncData={};asyncMap={};constructor(e,t,n,a){super(e,-1,"LocalSocket",n,a),this.socket=e,this.preListen={},this.invalidPacket=this.invalidPacket.bind(this),this.serverKeyHandler=this.serverKeyHandler.bind(this),this.messageHandler=this.messageHandler.bind(this),this._on("message",this.serverKeyHandler),this._on("close",()=>{this.callMiddleware("onStatusChange",WebSocket.CLOSED);for(const[e,t,n]of Object.values(this._timers))this.clearTimeout(e),n&&t(!0);for(const e of this.clientPackets.getPackets())delete e.lastSent[0];for(const e of this.serverPackets.getPackets())delete e.lastReceived[0]}),this.bufferHandler=t}reading=!1;readQueue=[];async serverKeyHandler(e){if(this.reading)return this.readQueue.push(e);this.reading=!0;const t=await this.bufferHandler(e);if(t.length<3||(0,h.as8String)(t.slice(0,3))!=o.SERVER_SUFFIX)throw this.close(1e3),new Error("The server requested is not a Sonic WS server.");const n=t[3];if(n!=o.VERSION)throw this.close(1e3),new Error(`Version mismatch: ${n>o.VERSION?"client":"server"} is outdated (server: ${n}, client: ${o.VERSION})`);const a=(0,s.inflateNative)(t.subarray(4,t.length)),[i,d]=(0,r.readVarInt)(a,0);this.id=d;const[l,u]=(0,r.readVarInt)(a,i),p=a.subarray(l,l+u);this.clientPackets.holdPackets(c.Packet.deserializeAll(p,!0));const f=a.subarray(l+u,a.length);this.serverPackets.holdPackets(c.Packet.deserializeAll(f,!0)),this.batcher.registerSendPackets(this.clientPackets,this);for(const e of this.serverPackets.getPackets()){const t=this.serverPackets.getKey(e.tag);this.asyncMap[t]=e.async,e.async&&(this.asyncData[t]=[!1,[]])}Object.keys(this.preListen).forEach(e=>this.preListen[e].forEach(t=>{if(!this.serverPackets.hasTag(e))return console.error(new Error(`The server does not send the packet with tag "${e}"!`));this.listen(e,t)})),this.preListen=null,this.pastKeys=!0,this.readyListeners.forEach(e=>e()),this.readyListeners=null,this._off("message",this.serverKeyHandler),this._on("message",this.messageHandler),this.readQueue.forEach(e=>this.messageHandler(e)),this.readQueue=[]}invalidPacket(e){throw console.error(e),new Error("An error occured with data from the server!! This is probably my fault.. make an issue at https://github.com/liwybloc/sonic-ws")}listenLock=!1;packetQueue=[];async listenPacket(e,t,n,a,r){const s=this.listeners[t];if(!s)return console.warn("Warn: No listener for packet "+t);await this.enqueuePacket(e,s,n,a,r),await this.callMiddleware("onReceive_post",t,"string"==typeof e?[e]:e[0])}isAsync(e){return this.asyncMap[e]}async enqueuePacket(e,t,n,a,r){await(0,i.listenPacket)(e,t,this.invalidPacket),await this.triggerNextPacket(n,a,r)}async triggerNextPacket(e,t,n){t?n[0]=!1:this.listenLock=!1,e.length>0&&this.dataHandler(e.shift())}async dataHandler(e){const t=e[0],n=e.slice(1),a=this.isAsync(t);let r,s,i;if(a?(i=this.asyncData[t],r=i[0],s=i[1]):(r=this.listenLock,s=this.packetQueue),r)return void s.push(e);a?i[0]=!0:this.listenLock=!0;const o=this.serverPackets.getTag(t),c=this.serverPackets.getPacket(o);if(await this.callMiddleware("onReceive_pre",c.tag,e,e.length))return;if(c.rereference&&0==n.length)return void 0===c.lastReceived[0]?this.invalidPacket("No previous value to rereference"):void this.listenPacket(c.lastReceived[0],o,s,a,i);if(0==c.dataBatching){const e=c.lastReceived[0]=await c.listen(n,null);return void this.listenPacket(e,o,s,a,i)}const l=await d.BatchHelper.unravelBatch(c,n,null);if("string"==typeof l)return this.invalidPacket(l);l.forEach(e=>this.listenPacket(e,o,s,a,i))}async messageHandler(e){const t=await this.bufferHandler(e);t.length<1||await this.dataHandler(t)}listen(e,t){this.serverPackets.hasTag(e)?(this.listeners[e]??=[]).push(t):console.log("Tag is not available on server: "+e)}sendQueue=[!1,[],void 0];async send(e,...t){if(await this.callMiddleware("onSend_pre",e,t,Date.now(),performance.now()))return;const[n,a,r]=await(0,i.processPacket)(this.clientPackets,e,t,this.sendQueue,0);0==r.dataBatching?this.raw_send((0,l.toPacketBuffer)(n,a)):this.batcher.batchPacket(n,a),await this.callMiddleware("onSend_post",e,a,a.length)}on_ready(e){this.pastKeys?e():this.readyListeners.push(e)}on_close(e){this._on("close",e)}on(e,t){if(this.socket.readyState!==WebSocket.OPEN)return this.preListen[e]||(this.preListen[e]=[]),void this.preListen[e].push(t);this.listen(e,t)}}t.SonicWSCore=p},950(e,t){function n(e,t){const n=[];for(let a=0;a<e.length;a+=t){const r=e.slice(a,a+t);n.push(r)}return n}Object.defineProperty(t,"__esModule",{value:!0}),t.splitArray=n,t.toPacketBuffer=function(e,t){const n=new Uint8Array(1+t.length);return n[0]=e,n.set(t,1),n},t.splitBuffer=function(e,t){return n(Array.from(e),t)},t.stringifyBuffer=function(e){return`<Buffer ${Array.from(e).map(e=>e.toString(16).padStart(2,"0")).join(" ")}>`}},985(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.MiddlewareHolder=void 0;t.MiddlewareHolder=class{middlewares=[];addMiddleware(e){this.middlewares.push(e);const t=e;try{"function"==typeof t.init&&t.init(this)}catch(e){console.warn("Middleware init threw an error:",e)}}async callMiddleware(e,...t){let n=!1;for(const a of this.middlewares){const r=a[e];if(r)try{await r(...t)&&(n=!0)}catch(t){console.warn(`Middleware ${String(e)} threw an error:`,t)}}return n}}}},__webpack_module_cache__={},hasSymbol,webpackQueues,webpackExports,webpackError,resolveQueue;function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,exports:{}};return __webpack_modules__[e](n,n.exports,__webpack_require__),n.exports}hasSymbol="function"==typeof Symbol,webpackQueues=hasSymbol?Symbol("webpack queues"):"__webpack_queues__",webpackExports=hasSymbol?Symbol("webpack exports"):"__webpack_exports__",webpackError=hasSymbol?Symbol("webpack error"):"__webpack_error__",resolveQueue=e=>{e&&e.d<1&&(e.d=1,e.forEach(e=>e.r--),e.forEach(e=>e.r--?e.r++:e()))},__webpack_require__.a=(e,t,n)=>{var a;n&&((a=[]).d=-1);var r,s,i,o=new Set,c=e.exports,d=new Promise((e,t)=>{i=t,s=e});d[webpackExports]=c,d[webpackQueues]=e=>(a&&e(a),o.forEach(e),d.catch(e=>{})),e.exports=d,t(e=>{var t;r=(e=>e.map(e=>{if(null!==e&&"object"==typeof e){if(e[webpackQueues])return e;if(e.then){var t=[];t.d=0,e.then(e=>{n[webpackExports]=e,resolveQueue(t)},e=>{n[webpackError]=e,resolveQueue(t)});var n={};return n[webpackQueues]=e=>e(t),n}}var a={};return a[webpackQueues]=e=>{},a[webpackExports]=e,a}))(e);var n=()=>r.map(e=>{if(e[webpackError])throw e[webpackError];return e[webpackExports]}),s=new Promise(e=>{(t=()=>e(n)).r=0;var s=e=>e!==a&&!o.has(e)&&(o.add(e),e&&!e.d&&(t.r++,e.push(t)));r.map(e=>e[webpackQueues](s))});return t.r?s:n()},e=>(e?i(d[webpackError]=e):s(c),resolveQueue(a))),a&&a.d<0&&(a.d=0)},__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.v=(e,t,n,a)=>{var r=fetch(__webpack_require__.p+"bundle.wasm"),s=()=>r.then(e=>e.arrayBuffer()).then(e=>WebAssembly.instantiate(e,a)).then(t=>Object.assign(e,t.instance.exports));return r.then(t=>"function"==typeof WebAssembly.instantiateStreaming?WebAssembly.instantiateStreaming(t,a).then(t=>Object.assign(e,t.instance.exports),e=>{if("application/wasm"!==t.headers.get("Content-Type"))return console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",e),s();throw e}):s())},(()=>{var e;__webpack_require__.g.importScripts&&(e=__webpack_require__.g.location+"");var t=__webpack_require__.g.document;if(!e&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){var n=t.getElementsByTagName("script");if(n.length)for(var a=n.length-1;a>-1&&(!e||!/^http(s?):/.test(e));)e=n[a--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),__webpack_require__.p=e})();var __webpack_exports__={};(()=>{const e=__webpack_require__(853),t=__webpack_require__(388),n=__webpack_require__(433),a=__webpack_require__(937),r=__webpack_require__(351);class s extends a.SonicWSCore{static initialize(){return(0,r.initializeWasmCore)()}antiTamperCall=()=>{};constructor(e,t,n=!1){const a=new WebSocket(e,t);if(super(a,async e=>new Uint8Array(await e.data.arrayBuffer()),a.addEventListener.bind(a),a.removeEventListener.bind(a)),n){const e=this,t=a.send.bind(a),n=this.send.bind(this);let r;this.send=async(t,...a)=>(r=e.clientPackets.getKey(t),await n(t,...a)),a.send=n=>n instanceof Uint8Array&&r==n[0]?t(n):(e.antiTamperCall(),void e.close())}}on_tamper(e){this.antiTamperCall=e}WrapEnum(e,n){return(0,t.WrapEnum)(e,n)}DeWrapEnum(e,n){return(0,t.DeWrapEnum)(e,n)}FlattenData(e){return(0,n.FlattenData)(e)}UnFlattenData(e){return(0,n.UnFlattenData)(e)}debugClient=null;OpenDebug(){if(null!=this.debugClient)throw new Error("Debug client has already been opened!");this.debugClient=new e.DebugClient(this)}}window.SonicWS=s})()})();
|
|
6
|
+
(()=>{"use strict";var __webpack_modules__={8(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.BatchHelper=void 0;const a=n(950),r=n(351);t.BatchHelper=class{batchInfo={};batchTimeouts={};batchedData={};conn;registerSendPackets(e,t){this.conn=t,e.getTags().forEach(t=>{const n=e.getPacket(t);if(0==n.dataBatching)return;const a=e.getKey(t);this.initiateBatch(a,n.dataBatching,n.gzipCompression)})}initiateBatch(e,t,n){this.batchedData[e]=[],this.batchInfo[e]=[t,n]}startBatch(e){const[t,n]=this.batchInfo[e];this.batchTimeouts[e]=this.conn.setInterval(()=>{if(0==this.batchedData[e].length)return;const t=(0,r.encodeNativeBatch)(this.batchedData[e],n);this.conn.raw_send((0,a.toPacketBuffer)(e,t)),this.batchedData[e]=[],delete this.batchTimeouts[e]},t)}batchPacket(e,t){this.batchedData[e].push(t),this.batchTimeouts[e]||this.startBatch(e)}static async unravelBatch(e,t,n){let a;try{a=(0,r.decodeNativeBatch)(t,e.gzipCompression,e.maxBatchSize)}catch(e){return"Invalid batch: "+e}const s=[];for(const t of a){const a=await e.listen(t,n);if("string"==typeof a)return"Batched packet: "+a;s.push(a)}return s}}},30(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.decompressBools=t.compressBools=t.EMPTY_UINT8=t.MAX_UVARINT=t.MAX_USHORT=t.MAX_BYTE=void 0,t.convertVarInt=function(e){if(!Number.isSafeInteger(e)||e<0||e>t.MAX_UVARINT)throw new Error(`Variable Ints must be within range 0 and ${t.MAX_UVARINT}: ${e}`);const n=[];do{let t=e%128;(e=Math.floor(e/128))>0&&(t|=128),n.push(t)}while(e>0);return n},t.readVarInt=function(e,t){let n=0,a=1;for(let r=0;r<8;r++){if(t>=e.length)throw new Error("Truncated variable integer");const r=e[t++];if(n+=(127&r)*a,!(128&r))return[t,n];a*=128}throw new Error("Variable integer is too long")},t.MAX_BYTE=255,t.MAX_USHORT=65535,t.MAX_UVARINT=128**7-1,t.EMPTY_UINT8=new Uint8Array([]);t.compressBools=e=>e.reduce((e,t,n)=>e|Number(t)<<7-n,0);t.decompressBools=e=>Array.from({length:8},(t,n)=>!!(e&1<<7-n))},72(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.decompressJSON=t.compressJSON=void 0;const a=n(950),r=e=>Array.from({length:8},(t,n)=>!!(e&1<<7-n));function s(e){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid JSON variable integer: ${e}`);const t=[];do{let n=127&e;(e>>>=7)>0&&(n|=128),t.push(n)}while(e>0);return t}function i(e,t){let n=0,a=0;for(;;){if(t>=e.length||a>28)throw new Error("Invalid JSON variable integer");const r=e[t++];if(n+=(127&r)<<a,!(128&r))return[t,n];a+=7}}var o;!function(e){e[e.NULL=0]="NULL",e[e.BOOL=1]="BOOL",e[e.INT=2]="INT",e[e.FLOAT=3]="FLOAT",e[e.STRING=4]="STRING",e[e.ARRAY=5]="ARRAY",e[e.OBJECT=6]="OBJECT"}(o||(o={}));const c=e=>{const t=(new TextEncoder).encode(e);return[...s(t.length),...t]},d=(e,t)=>{const[n,a]=i(e,t);return{value:(new TextDecoder).decode(e.subarray(n,n+a)),length:n+a-t}},l=e=>{let t="";for(const n of e)t+=n.toString(2).padStart(3,"0");return(e=>new Uint8Array(e.match(/.{1,8}/g)?.map(e=>parseInt(e.padEnd(8,"0"),2))??[]))(t)},u=(e,t)=>{const n=(e=>Array.from(e,e=>e.toString(2).padStart(8,"0")).join(""))(e),a=[];for(let e=0;e<t;e++)a.push(parseInt(n.slice(3*e,3*e+3),2));return a};t.compressJSON=e=>{const t=[],n=[],r=[],i=e=>{switch(null===e?"null":Array.isArray(e)?"array":typeof e){case"null":r.push(o.NULL);break;case"boolean":r.push(o.BOOL),t.push(e);break;case"number":Number.isInteger(e)?(r.push(o.INT),n.push(...s((e=>e<<1^e>>31)(e)))):(r.push(o.FLOAT),n.push(...function(e){if(Number.isNaN(e))return[127,128,0,1];const t=e<0?1:0;if(0===(e=Math.abs(e)))return[0,0,0,0];const n=Math.floor(Math.log2(e));if(!Number.isFinite(e)||n>127||n<-126)return[t?255:127,128,0,0];const a=(t<<31|n+127<<23|8388607&Math.round((e/2**n-1)*2**23))>>>0;return[a>>>24,a>>>16&255,a>>>8&255,255&a]}(e)));break;case"string":r.push(o.STRING),n.push(...c(e));break;case"array":r.push(o.ARRAY),n.push(...s(e.length));for(const t of e)i(t);break;case"object":{r.push(o.OBJECT);const t=Object.keys(e);n.push(...s(t.length));for(const a of t)n.push(...c(a)),i(e[a]);break}default:throw new Error("Unsupported type")}};i(e);const d=t.length?(0,a.splitArray)(t,8).map(e=>e.reduce((e,t,n)=>e|Number(t)<<7-n,0)):[],u=l(r),h=[...s(d.length),...s(u.length)];return Uint8Array.from([...h,...d.flat(),...u,...n])};t.decompressJSON=e=>{let t=0;const[n,a]=i(e,t);t=n;const[s,c]=i(e,t);t=s;const l=[];for(let n=0;n<a;n++)l.push(...r(e[t++]));let h=0;const p=e.subarray(t,t+c);t+=c;const f=u(p,8*p.length/3);let w=0;const y=n=>{if(n>500)throw new Error("JSON array too deep.");const a=f[w++];switch(a){case o.NULL:return null;case o.BOOL:return l[h++];case o.INT:{const[n,a]=i(e,t);return t=n,(r=a)>>>1^-(1&r)}case o.FLOAT:{const n=function(e){const t=(e[0]<<24|e[1]<<16|e[2]<<8|e[3])>>>0,n=t>>>23&255,a=(0===n?0:1)+(8388607&t)/2**23,r=255===n?0===a?1/0:NaN:a*2**(0===n?-126:n-127);return t>>>31?-r:r}(Array.from(e.subarray(t,t+4)));return t+=4,n}case o.STRING:{const{value:n,length:a}=d(e,t);return t+=a,n}case o.ARRAY:{const[a,r]=i(e,t);t=a;const s=[];for(let e=0;e<r;e++)s.push(y(n+1));return s}case o.OBJECT:{const[a,r]=i(e,t);t=a;const s={};for(let a=0;a<r;a++){const{value:a,length:r}=d(e,t);t+=r,s[a]=y(n+1)}return s}default:throw new Error(`Unknown type ${a}`)}var r};return y(0)}},98(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.EnumPackage=t.TYPE_CONVERSION_MAP=void 0;const a=n(157),r=n(388),s={string:0,number:1,boolean:2,undefined:3,object:4};function i(e){const t=typeof e;if(!(t in s)&&null!=e)throw new Error(`Cannot serialize type "${t}" in an enum!`);return s[t]}t.TYPE_CONVERSION_MAP={0:e=>e,1:e=>parseFloat(e),2:e=>"true"==e,3:()=>{},4:()=>null};t.EnumPackage=class{tag;values;constructor(e,t){this.tag=e,this.values=t,this.wrap=this.wrap.bind(this)}serialize(){const e=(0,a.processCharCodes)(this.tag);return[this.tag.length,...e,this.values.length,...this.values.map(e=>[String(e).length,i(e),...(0,a.processCharCodes)(String(e))]).flat()]}wrap(e){return(0,r.WrapEnum)(this.tag,e)}}},102(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.PacketSchema=t.Packet=void 0;const a=n(388),r=n(98),s=n(30),i=n(433),o=n(619),c=n(157),d=n(351),l=n(72);class u{defaultEnabled;tag;maxSize;minSize;type;enumData;dataMax;dataMin;dataBatching;maxBatchSize;dontSpread;autoFlatten;fields;quantized;valueMin;valueMax;parent;variant;rateLimit;async;rereference;gzipCompression;object;client;processReceive;processSend;validate;customValidator;lastReceived={};lastSent={};quantizationErrors={};constructor(e,t,n,a,r){this.tag=e,this.defaultEnabled=a,this.client=r,this.async=t.async,this.enumData=t.enumData,this.rateLimit=t.rateLimit,this.dontSpread=t.dontSpread,this.autoFlatten=t.autoFlatten,this.rereference=t.rereference,this.dataBatching=t.dataBatching,this.maxBatchSize=r?1/0:t.maxBatchSize,this.gzipCompression=t.gzipCompression,this.fields=t.fields,this.quantized=t.quantized?{...t.quantized,trackError:t.quantized.trackError??!0}:void 0,this.valueMin=t.valueMin,this.valueMax=t.valueMax;const s=/^__(.+)\$([^$]+)$/.exec(e);if(this.parent=s?.[1],this.variant=s?.[2],this.object=t.object,this.type=t.type,this.dataMax=t.dataMax,this.dataMin=t.dataMin,t.testObject(this)){this.maxSize=this.minSize=this.type.length;for(let e=0;e<this.type.length;e++)this.type[e]==o.PacketType.NONE&&(this.dataMax[e]=this.dataMin[e]=0);const e={types:this.type,dataMins:this.dataMin,dataMaxes:this.dataMax,enumData:this.enumData};this.processReceive=t=>(0,d.decodeNativeObject)(e,t).map((e,t)=>this.type[t]===o.PacketType.JSON?(0,l.decompressJSON)(e):e),this.processSend=async t=>{let n=0;const a=t.map((e,t)=>{if(this.type[t]===o.PacketType.JSON)return(0,l.compressJSON)(e);if(this.type[t]!==o.PacketType.ENUMS)return e;const a=this.enumData[n++];return(Array.isArray(e)?e:[e]).map(e=>{if(!Number.isInteger(e)||e<0||e>=a.values.length)throw new Error(`Invalid wrapped enum index: ${e}`);return a.values[e]})});return(0,d.encodeNativeObject)(e,a)},this.validate=async t=>{(0,d.validateNativeObject)(e,t);return(0,d.decodeNativeObject)(e,t).forEach((e,t)=>{if(this.type[t]!==o.PacketType.JSON)return;const n=(0,l.decompressJSON)(e),a=Array.isArray(n)?n.length:1;if(a<this.dataMin[t]||a>this.dataMax[t])throw new Error("JSON value count is outside schema limits")}),[t,!0]}}else{{this.maxSize=this.dataMax,this.minSize=this.dataMin,this.type==o.PacketType.NONE&&(this.dataMax=this.dataMin=0);const e=this.enumData[0];this.processReceive=t=>this.type===o.PacketType.JSON?(0,l.decompressJSON)(t):(0,d.decodeNative)(this.type,t,this.dataMax,e),this.processSend=async t=>{let n;if(this.type===o.PacketType.JSON)n=(0,l.compressJSON)(t);else if(this.type===o.PacketType.ENUMS)n=Uint8Array.from(t);else{const a=this.type===o.PacketType.RAW&&1===t.length&&t[0]instanceof Uint8Array?t[0]:t;n=(0,d.encodeNative)(this.type,a,e)}return this.gzipCompression&&0===this.dataBatching?(0,d.deflateNative)(n):n},this.validate=async t=>{const n=this.gzipCompression&&0===this.dataBatching?(0,d.inflateNative)(t):t;if(this.type===o.PacketType.JSON){const e=(0,l.decompressJSON)(n),t=Array.isArray(e)?e.length:1;if(t<this.dataMin||t>this.dataMax)throw new Error("JSON value count is outside schema limits")}else(0,d.validateNative)(this.type,n,this.dataMin,this.dataMax,{enumData:e});return[n,!0]}}}this.customValidator=n}assertRecord(e,t){if(!this.fields)throw new Error(`Packet "${this.tag}" ${t} requires schema`);if(null===e||"object"!=typeof e||Array.isArray(e))throw new Error(`Packet "${this.tag}" ${t} requires an object record`);const n=this.fields.filter(t=>!Object.prototype.hasOwnProperty.call(e,t));if(n.length)throw new Error(`Packet "${this.tag}" is missing schema field(s): ${n.join(", ")}`);const a=Object.keys(e).filter(e=>!this.fields.includes(e));if(a.length)throw new Error(`Packet "${this.tag}" has unknown schema field(s): ${a.join(", ")}`);return this.fields.map(t=>e[t])}logical(e,t,n=-1){const a=this.quantized?.scale;return e.map(e=>{if("number"!=typeof e||!Number.isFinite(e))throw new Error(`Packet "${this.tag}" ${t} value must be a finite number`);const r="receive"===t&&a?e/a:e;if(void 0!==this.valueMin&&r<this.valueMin)throw new Error(`Packet "${this.tag}" value ${r} is below minimum ${this.valueMin}`);if(void 0!==this.valueMax&&r>this.valueMax)throw new Error(`Packet "${this.tag}" value ${r} exceeds maximum ${this.valueMax}`);if("send"===t&&a){const e=r*a+(this.quantized?.trackError?this.quantizationErrors[n]??0:0),t=Math.round(e);return this.quantized?.trackError&&(this.quantizationErrors[n]=e-t),t}return r})}prepareSend(e,t=-1){if(this.object){if(this.autoFlatten&&this.fields){if(1!==e.length||!Array.isArray(e[0]))throw new Error(`Packet "${this.tag}" autoTranspose requires one array of records`);const t=e[0].map(e=>this.assertRecord(e,"autoTranspose"));return this.fields.map((e,n)=>t.map(e=>e[n]))}return e}let n=e;if(this.autoFlatten){if(1!==e.length||!Array.isArray(e[0]))throw new Error(`Packet "${this.tag}" autoFlatten requires one array of records`);if(n=e[0].flatMap(e=>this.assertRecord(e,"autoFlatten")),this.fields&&n.length%this.fields.length!==0)throw new Error(`Packet "${this.tag}" flat value count must be divisible by schema length ${this.fields.length}`)}else this.fields&&1===e.length&&null!==e[0]&&"object"==typeof e[0]&&!Array.isArray(e[0])&&(n=this.assertRecord(e[0],"schema mapping"));return this.quantized||void 0!==this.valueMin||void 0!==this.valueMax?this.logical(n,"send",t):n}clearQuantizationState(e){delete this.quantizationErrors[e]}finishReceive(e){if(this.object){if(this.autoFlatten&&this.fields){const t=e,n=t[0]?.length??0;if(t.some(e=>e.length!==n))throw new Error(`Packet "${this.tag}" autoTranspose columns have different lengths`);return Array.from({length:n},(e,n)=>Object.fromEntries(this.fields.map((e,a)=>[e,t[a][n]])))}return this.autoFlatten?(0,i.UnFlattenData)(e):e}let t=Array.isArray(e)?e:[e];if((this.quantized||void 0!==this.valueMin||void 0!==this.valueMax)&&(t=this.logical(t,"receive")),this.autoFlatten){const e=this.fields.length;if(t.length%e!==0)throw new Error(`Packet "${this.tag}" flat value count ${t.length} is not divisible by schema length ${e}`);return Array.from({length:t.length/e},(n,a)=>Object.fromEntries(this.fields.map((n,r)=>[n,t[a*e+r]])))}return this.fields?Object.fromEntries(this.fields.map((e,n)=>[e,t[n]])):e}async listen(e,t){try{const[n,a]=await this.validate(e);if(!this.client&&!1===a)return"Invalid packet";const r=this.processReceive(n,a),s=this.finishReceive(r);if(null!=this.customValidator)if(this.dontSpread||this.fields){if(!this.customValidator(t,s))return"Didn't pass custom validator"}else if(!this.customValidator(t,...s))return"Didn't pass custom validator";return[s,!this.fields&&!this.dontSpread]}catch(e){return console.error("There was an error processing the packet! This is probably my fault... report at https://github.com/liwybloc/sonic-ws",e),"Error: "+e}}serialize(){const e=(new TextEncoder).encode(JSON.stringify({schema:this.fields,quantized:this.quantized,min:this.valueMin,max:this.valueMax})),t=[this.tag.length,...(0,c.processCharCodes)(this.tag),(0,s.compressBools)([this.dontSpread,this.async,this.object,this.autoFlatten,this.gzipCompression,this.rereference]),...(0,s.convertVarInt)(e.length),...e,this.dataBatching,this.enumData.length,...this.enumData.map(e=>e.serialize()).flat()];return this.object?[...t,this.maxSize,...this.dataMax.map(s.convertVarInt).flat(),...this.dataMin.map(s.convertVarInt).flat(),...this.type]:[...t,...(0,s.convertVarInt)(this.dataMax),...(0,s.convertVarInt)(this.dataMin),this.type]}static readVarInts(e,t,n){const a=[];for(let r=0;r<n;r++){const[n,r]=(0,s.readVarInt)(e,t);t=n,a.push(r)}return[a,t]}static deserialize(e,t,n){const i=t,d=e[t++],l=(0,c.as8String)(e.slice(t,t+=d)),[h,f,w,y,m,_]=(0,s.decompressBools)(e[t++]),[g,b]=(0,s.readVarInt)(e,t);t=g;const v=JSON.parse((new TextDecoder).decode(e.slice(t,t+=b))),k=e[t++],E=e[t++],S=[];for(let n=0;n<E;n++){const n=e[t++],s=(0,c.as8String)(e.slice(t,t+=n)),i=e[t++],o=[];for(let n=0;n<i;n++){const n=e[t++],a=e[t++],s=(0,c.as8String)(e.slice(t,t+=n));o.push(r.TYPE_CONVERSION_MAP[a](s))}S.push((0,a.DefineEnum)(s,o))}if(w){const a=e[t++],[r,s]=this.readVarInts(e,t,a);t=s;const[c,d]=this.readVarInts(e,t,a);t=d;const w=Array.from(e.slice(t,t+=a));let _=0;const g=w.map(e=>e==o.PacketType.ENUMS?S[_++]:e),b=new p(!0,g,f,c,r,-1,h,y,!1,k,-1,m,v.schema);return[new u(l,b,null,!1,n),t-i]}const[T,P]=(0,s.readVarInt)(e,t);t=T;const[N,A]=(0,s.readVarInt)(e,t);t=N;const x=e[t++],O=x==o.PacketType.ENUMS?S[0]:x,M=new p(!1,O,f,A,P,-1,h,y,_,k,-1,m,v.schema,v.quantized,v.min,v.max);return[new u(l,M,null,!1,n),t-i]}static deserializeAll(e,t){const n=[];let a=0;for(;a<e.length;){const[r,s]=this.deserialize(e,a,t);n.push(r),a+=s}return n}}t.Packet=u;const h=(e,t)=>e instanceof r.EnumPackage?(t.push(e),o.PacketType.ENUMS):e;class p{type;enumData=[];dataMax;dataMin;dataBatching;maxBatchSize;rateLimit;dontSpread=!1;autoFlatten=!1;async=!1;rereference=!1;gzipCompression=!1;object;fields;quantized;valueMin;valueMax;constructor(e,t,n,a,r,s,i,o,c,d,l,u,p,f,w,y){this.object=e,this.async=n,this.dataMin=a,this.dataMax=r,this.rateLimit=s,this.dontSpread=i,this.autoFlatten=o,this.rereference=c,this.dataBatching=d,this.maxBatchSize=l,this.gzipCompression=u,this.fields=p?[...p]:void 0,this.quantized=f?{...f}:void 0,this.valueMin=w,this.valueMax=y,this.type=e?t.map(e=>h(e,this.enumData)):h(t,this.enumData)}testObject(e){return this.object}}t.PacketSchema=p},157(e,t){function n(e){return String.fromCodePoint(...e)}Object.defineProperty(t,"__esModule",{value:!0}),t.processCharCodes=function(e){return Array.from(e,e=>e.codePointAt(0))},t.convertCharCodes=n,t.as8String=function(e){return n(Array.from(e))}},234(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.SERVER_SUFFIX_NUMS=t.SERVER_SUFFIX=t.VERSION=void 0;const a=n(157);t.VERSION=23,t.SERVER_SUFFIX="SWS",t.SERVER_SUFFIX_NUMS=(0,a.processCharCodes)(t.SERVER_SUFFIX)},351(__unused_webpack_module,exports,__webpack_require__){var __webpack_dirname__="/";Object.defineProperty(exports,"__esModule",{value:!0}),exports.setNativeCore=setNativeCore,exports.initializeWasmCore=initializeWasmCore,exports.loadNativeCore=loadNativeCore,exports.encodeNative=encodeNative,exports.decodeNative=decodeNative,exports.validateNative=validateNative,exports.encodeNativeObject=encodeNativeObject,exports.decodeNativeObject=decodeNativeObject,exports.validateNativeObject=validateNativeObject,exports.encodeNativeBatch=encodeNativeBatch,exports.decodeNativeBatch=decodeNativeBatch,exports.deflateNative=deflateNative,exports.inflateNative=inflateNative;const PacketType_1=__webpack_require__(619),version_1=__webpack_require__(234),CDN_RELEASE="https://cdn.jsdelivr.net/gh/liwybloc/sonic-ws/release",CDN_WASM=`${CDN_RELEASE}/bundle.wasm`,CDN_VERSION=`${CDN_RELEASE}/version`;let loadedCore,wasmInitialization;function buffer(e){return"undefined"!=typeof Buffer?Buffer.from(e.buffer,e.byteOffset,e.byteLength):new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}function values(e){return Array.isArray(e)?[...e]:[e]}function assertNativeCore(e){const t=["encodeSigned","decodeSigned","encodeUnsigned","decodeUnsigned","encodeFloats","decodeFloats","encodeStrings","decodeStrings","encodeBooleans","decodeBooleans","decodeRaw","encodeHex","decodeHex","frameObject","unframeObject","encodeBatch","decodeBatch","deflateRaw","inflateRaw","validateEncoded","validateEnum","validateObject"].filter(t=>"function"!=typeof e[t]);if(t.length>0)throw new Error(`Invalid SonicWS native addon; missing: ${t.join(", ")}`)}function setNativeCore(e){assertNativeCore(e),loadedCore=e}function fetchUrl(e){return"string"==typeof e?e:e instanceof URL?e.href:e.url}async function isWasm(e){if(!e.ok)return!1;const t=new Uint8Array(await e.clone().arrayBuffer());return t.length>=4&&0===t[0]&&97===t[1]&&115===t[2]&&109===t[3]}async function fetchCdnWasm(e){const t=await e(CDN_VERSION,{cache:"no-store"});if(!t.ok)throw new Error(`Unable to verify SonicWS CDN protocol version (${t.status})`);const n=Number((await t.text()).trim());if(!Number.isInteger(n)||n!==version_1.VERSION)throw new Error(`SonicWS CDN protocol mismatch: expected ${version_1.VERSION}, received ${String(n)}`);const a=await e(CDN_WASM);if(!await isWasm(a))throw new Error("SonicWS CDN returned an invalid WASM module");return a}async function initializeBrowserWasm(){const e=window.fetch.bind(window);window.fetch=async(t,n)=>{const a=fetchUrl(t);if(a===CDN_WASM||!new URL(a,window.location.href).pathname.endsWith("/bundle.wasm"))return e(t,n);try{const a=await e(t,n);if(await isWasm(a))return a}catch{}return fetchCdnWasm(e)};try{return setNativeCore(await Promise.resolve().then(__webpack_require__.bind(__webpack_require__,880))),loadedCore}finally{window.fetch=e}}function initializeWasmCore(){return loadedCore?Promise.resolve(loadedCore):wasmInitialization||(wasmInitialization=(async()=>{if("undefined"!=typeof window)return initializeBrowserWasm();const wasm=eval("require")("./wasm/node/sonic_ws_core.js");return setNativeCore(wasm),loadedCore})().finally(()=>{wasmInitialization=void 0}),wasmInitialization)}function loadNativeCore(addonPath){if(loadedCore&&!addonPath)return loadedCore;const candidates=addonPath?[addonPath]:["undefined"!=typeof process?process.env.SONIC_WS_CORE_PATH:void 0,`${__webpack_dirname__}/sonic_ws_core.node`,`${__webpack_dirname__}/../../../native/sonic_ws_core.node`].filter(e=>Boolean(e)),failures=[],nodeRequire="undefined"==typeof window?eval("require"):void 0;for(const e of candidates)try{const t=nodeRequire(e);return assertNativeCore(t),addonPath||(loadedCore=t),t}catch(t){failures.push(`${e}: ${t instanceof Error?t.message:String(t)}`)}if("undefined"==typeof window)try{const e=nodeRequire("./wasm/node/sonic_ws_core.js");return assertNativeCore(e),loadedCore=e,e}catch(e){failures.push(`Node WASM fallback: ${e instanceof Error?e.message:String(e)}`)}throw new Error(`SonicWS codec is not initialized. In Node, set SONIC_WS_CORE_PATH; in browsers, await initializeWasmCore().\n${failures.join("\n")}`)}function enumIndex(e,t){const n=e.values.findIndex(e=>e===t||"number"==typeof e&&"number"==typeof t&&Number.isNaN(e)&&Number.isNaN(t));if(n<0)throw new Error(`Value ${String(t)} does not exist in enum ${e.tag}`);return n}function encodeNative(e,t,n,a=loadNativeCore()){switch(e){case PacketType_1.PacketType.NONE:if(null!=t&&(!Array.isArray(t)||0!==t.length))throw new TypeError("NONE only accepts null, undefined, or an empty array");return new Uint8Array(0);case PacketType_1.PacketType.RAW:case PacketType_1.PacketType.JSON:if(!(t instanceof Uint8Array||Array.isArray(t)))throw new TypeError((e===PacketType_1.PacketType.JSON?"JSON wire data":"RAW")+" requires a Uint8Array or number array");return t instanceof Uint8Array?buffer(t):Uint8Array.from(t);case PacketType_1.PacketType.BYTES:case PacketType_1.PacketType.SHORTS:case PacketType_1.PacketType.VARINT:case PacketType_1.PacketType.DELTAS:return a.encodeSigned(e,values(t));case PacketType_1.PacketType.UBYTES:case PacketType_1.PacketType.USHORTS:case PacketType_1.PacketType.UVARINT:return a.encodeUnsigned(e,values(t));case PacketType_1.PacketType.FLOATS:case PacketType_1.PacketType.DOUBLES:return a.encodeFloats(e,values(t));case PacketType_1.PacketType.STRINGS_ASCII:case PacketType_1.PacketType.STRINGS_UTF16:return a.encodeStrings(e,values(t));case PacketType_1.PacketType.BOOLEANS:return a.encodeBooleans(values(t));case PacketType_1.PacketType.HEX:{const e=Array.isArray(t)?t[0]:t;if("string"!=typeof e)throw new TypeError("HEX requires one string");return a.encodeHex(e)}case PacketType_1.PacketType.ENUMS:if(!n)throw new Error("ENUMS requires an EnumPackage");return Uint8Array.from(values(t).map(e=>enumIndex(n,e)));case PacketType_1.PacketType.KEY_EFFECTIVE:throw new Error("KEY_EFFECTIVE is not implemented");default:throw new Error(`Unknown packet type: ${e}`)}}function decodeNative(e,t,n=4294967295,a,r=loadNativeCore()){const s=buffer(t);switch(e){case PacketType_1.PacketType.NONE:if(0!==t.byteLength)throw new Error("NONE packet contains data");return;case PacketType_1.PacketType.RAW:case PacketType_1.PacketType.JSON:return r.decodeRaw(s);case PacketType_1.PacketType.BYTES:case PacketType_1.PacketType.SHORTS:case PacketType_1.PacketType.VARINT:case PacketType_1.PacketType.DELTAS:return r.decodeSigned(e,s);case PacketType_1.PacketType.UBYTES:case PacketType_1.PacketType.USHORTS:case PacketType_1.PacketType.UVARINT:return r.decodeUnsigned(e,s);case PacketType_1.PacketType.FLOATS:case PacketType_1.PacketType.DOUBLES:return r.decodeFloats(e,s);case PacketType_1.PacketType.STRINGS_ASCII:case PacketType_1.PacketType.STRINGS_UTF16:return r.decodeStrings(e,s);case PacketType_1.PacketType.BOOLEANS:return r.decodeBooleans(s,n);case PacketType_1.PacketType.HEX:return r.decodeHex(s);case PacketType_1.PacketType.ENUMS:if(!a)throw new Error("ENUMS requires an EnumPackage");return[...t].map(e=>{if(e>=a.values.length)throw new Error(`Enum index ${e} is out of range`);return a.values[e]});case PacketType_1.PacketType.KEY_EFFECTIVE:throw new Error("KEY_EFFECTIVE is not implemented");default:throw new Error(`Unknown packet type: ${e}`)}}function validateNative(e,t,n,a,r={},s=loadNativeCore()){if(e!==PacketType_1.PacketType.ENUMS)s.validateEncoded(e,buffer(t),n,a,r.compressed??!1,r.batched??!1,r.maxBatchSize);else{if(!r.enumData)throw new Error("ENUMS requires an EnumPackage");s.validateEnum(buffer(t),r.enumData.values.length,n,a)}}function encodeNativeObject(e,t,n=loadNativeCore()){if(t.length!==e.types.length)throw new Error("Object field count does not match schema");let a=0;const r=e.types.map((r,s)=>encodeNative(r,t[s],r===PacketType_1.PacketType.ENUMS?e.enumData?.[a++]:void 0,n));return n.frameObject(r)}function decodeNativeObject(e,t,n=loadNativeCore()){const a=n.unframeObject(buffer(t),e.types.length);let r=0;return a.map((t,a)=>decodeNative(e.types[a],t,e.dataMaxes[a],e.types[a]===PacketType_1.PacketType.ENUMS?e.enumData?.[r++]:void 0,n))}function validateNativeObject(e,t,n=loadNativeCore()){n.validateObject(buffer(t),[...e.types],[...e.dataMins],[...e.dataMaxes],(e.enumData??[]).map(e=>e.values.length))}function encodeNativeBatch(e,t,n=loadNativeCore()){return n.encodeBatch(e.map(buffer),t)}function decodeNativeBatch(e,t,n=0,a,r=loadNativeCore()){const s=Number.isFinite(n)&&n>0?n:0;return r.decodeBatch(buffer(e),t,s,a)}function deflateNative(e,t=loadNativeCore()){return t.deflateRaw(buffer(e))}function inflateNative(e,t,n=loadNativeCore()){return n.inflateRaw(buffer(e),t)}},388(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.SET_PACKAGES=t.ENUM_KEY_TO_TAG=t.ENUM_TAG_TO_KEY=t.MAX_ENUM_SIZE=void 0,t.DefineEnum=function(e,n){const a=t.SET_PACKAGES[e];if(a){if(a.values.find((e,t)=>n[t]!=e))throw new Error(`Pre-existing enum package of tag '${e}' is set and different!`);return a}if(n.length>t.MAX_ENUM_SIZE)throw new Error(`An enum can only hold ${t.MAX_ENUM_SIZE} possible values.`);return t.ENUM_TAG_TO_KEY[e]=Object.fromEntries(n.map((e,t)=>[e,t])),t.ENUM_KEY_TO_TAG[e]=Object.fromEntries(n.map((e,t)=>[t,e])),t.SET_PACKAGES[e]=new r.EnumPackage(e,n)},t.WrapEnum=function(e,n){if(!(n in t.ENUM_TAG_TO_KEY[e]))throw new Error(`Value "${n}" does not exist in enum "${e}"`);return t.ENUM_TAG_TO_KEY[e][n]},t.DeWrapEnum=function(e,n){return t.ENUM_KEY_TO_TAG[e][n]};const a=n(30),r=n(98);t.MAX_ENUM_SIZE=a.MAX_BYTE,t.ENUM_TAG_TO_KEY={},t.ENUM_KEY_TO_TAG={},t.SET_PACKAGES={}},404(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.PacketHolder=void 0;t.PacketHolder=class{key;keys;tags;packetMap;packets;variants={};parents=new Set;constructor(e){this.key=1,this.keys={},this.tags={},this.packetMap={},e&&this.holdPackets(e)}createKey(e){this.keys[e]=this.key,this.tags[this.key]=e,this.key++}holdPackets(e){this.packets=e;for(const t of e)this.createKey(t.tag),this.packetMap[t.tag]=t,t.parent&&t.variant&&(this.variants[`${t.parent}.${t.variant}`]=t.tag,this.parents.add(t.parent))}getKey(e){if(!((e=this.resolveTag(e))in this.keys))throw new Error(`Not a valid tag: ${e}`);return this.keys[e]}getTag(e){if(e in this.tags)return this.tags[e]}getPacket(e){if(!((e=this.resolveTag(e))in this.packetMap))throw new Error("Unknown packet tag: "+e);return this.packetMap[e]}hasKey(e){return e in this.tags}hasTag(e){return this.resolveTag(e)in this.keys||this.parents.has(e)}resolveTag(e){return this.variants[e]??e}getVariantTag(e,t){const n=this.variants[`${e}.${t}`];if(!n)throw new Error(`Unknown packet variant: ${e}.${t}`);return n}getKeys(){return this.keys}getTagMap(){return this.tags}getTags(){return Object.values(this.tags)}getPackets(){return this.packets}serialize(){return this.packets.map(e=>e.serialize()).flat()}}},410(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.setHashFunc=function(e){i=e?r:s},t.hashValue=function(e){return i(e)};const n=1099511628211n,a=(1n<<64n)-1n,r=e=>{let t=14695981039346656037n;const r=e=>{if(null===e)return t^=0n,void(t=t*n&a);const s=typeof e;if("number"===s)return t^=BigInt(Math.trunc(e)),void(t=t*n&a);if("string"!==s){if("boolean"===s)return t^=e?1n:0n,void(t=t*n&a);if(Array.isArray(e))for(let t=0;t<e.length;t++)r(e[t]);else if("object"===s){const s=Object.keys(e).sort();for(let i=0;i<s.length;i++){const o=s[i];for(let e=0;e<o.length;e++)t^=BigInt(o.charCodeAt(e)),t=t*n&a;r(e[o])}}}else for(let r=0;r<e.length;r++)t^=BigInt(e.charCodeAt(r)),t=t*n&a};return r(e),t},s=e=>{let t=2166136261;const n=e=>{if(null===e)return void(t^=0);const a=typeof e;if("number"===a)return t^=0|e,void(t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24));if("string"!==a)if("boolean"!==a){if(Array.isArray(e))for(let t=0;t<e.length;t++)n(e[t]);else if("object"===a){const a=Object.keys(e).sort();for(let r=0;r<a.length;r++){const s=a[r];for(let e=0;e<s.length;e++)t^=s.charCodeAt(e),t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24);n(e[s])}}}else t^=e?1:0;else for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24)};return n(e),t>>>0};let i=r},433(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.processPacket=c,t.listenPacket=async function(e,t,n){if("string"==typeof e)return n(e);const[a,r]=e;try{if(r&&Array.isArray(a))for(const e of t)await e(...a);else for(const e of t)await e(a)}catch(e){console.error(e),n(e)}},t.CreatePacket=f,t.CreateObjPacket=function(e){let{tag:t,types:n=[],dataMaxes:s,dataMins:i,noDataRange:o=!1,dontSpread:c=!1,autoFlatten:f=!1,autoTranspose:y,schema:m,validator:_=null,dataBatching:g=0,maxBatchSize:b=10,rateLimit:v=0,enabled:k=!0,async:E=!1,gzipCompression:S=n&&n.includes(r.PacketType.JSON)}=e;if(!t)throw new Error("Tag not selected!");if(!n||0==n.length)throw new Error("Types is set to 0 length");if(w(m,t),m&&m.length!==n.length)throw new Error(`Packet "${t}" schema length must match types length`);if(void 0!==y&&f&&y!==f)throw new Error(`Packet "${t}" has conflicting autoFlatten and autoTranspose options`);const T=y??f;for(const e of n)if(d(e))throw new Error(`Invalid packet type in "${t}" packet: ${e}`);o?(s=Array.from({length:n.length}).map(()=>l),i=Array.from({length:n.length}).map(()=>0)):(null==s?s=Array.from({length:n.length}).map(()=>1):Array.isArray(s)||(s=Array.from({length:n.length}).map(()=>s)),null==i?i=Array.from({length:n.length}).map((e,t)=>s[t]):Array.isArray(i)||(i=Array.from({length:n.length}).map(()=>i)));const P=s.map(u),N=i.map((e,t)=>n[t]==r.PacketType.NONE?0:h(e,P[t])),A=new a.PacketSchema(!0,n,E,N,P,p(v),c,T,!1,g,b,S,m);return new a.Packet(t,A,_,k,!1)},t.CreatePacketGroup=function(e){if(!e.tag||e.tag.includes("$"))throw new Error("Packet group tag is required and cannot contain '$'");const t=Object.entries(e.variants);if(!t.length)throw new Error(`Packet group "${e.tag}" requires at least one variant`);return t.map(([t,n])=>{if(!t||t.includes("$"))throw new Error("Packet variant names cannot be empty or contain '$'");return f({...n,tag:`__${e.tag}$${t}`})})},t.CreateEnumPacket=function(e){const{tag:t,enumData:n,dataMax:a=1,dataMin:r=0,noDataRange:s=!1,dontSpread:i=!1,validator:o=null,dataBatching:c=0,maxBatchSize:d=10,rateLimit:l=0,enabled:u=!0,async:h=!1}=e;return f({tag:t,type:n,dataMax:a,dataMin:r,noDataRange:s,dontSpread:i,validator:o,dataBatching:c,maxBatchSize:d,rateLimit:l,enabled:u,async:h})},t.CreateKeyEffective=function(e){const{tag:t,count:n=2,validator:a=null,async:r=!1}=e;if(!t)throw new Error("Tag not selected!");if(n<2)throw new Error("Must have at least 2 key consumptions on key effective packet!");throw new Error("Currently W.I.P.")},t.FlattenData=m,t.UnFlattenData=function(e){return e[0]?.map((t,n)=>e.map(e=>e[n]))??[]};const a=n(102),r=n(619),s=n(98),i=n(30),o=n(410);async function c(e,t,n,a,s,d=!1){const l=e.getKey(t),u=e.getPacket(t);return async function(e,t,n,a,r,s,i){if(e[0]&&!s)return new Promise(t=>e[1].push([t,a,r]));e[0]=!0;const o=await i();if(e[1].length>0){const[a,r,s]=e[1].shift();queueMicrotask(async()=>{a(await c(t,r,s,e,n,!0))})}else e[0]=!1;return o}(a,e,s,t,n,d,async()=>{if(u.rereference){if(-1===s)throw new Error("Cannot send a re-referenced packet from the server-wide sender!");const e=(0,o.hashValue)(n);if(u.lastSent[s]===e)return[l,i.EMPTY_UINT8,u];u.lastSent[s]=e}if(n=u.prepareSend(n,s),u.autoFlatten&&u.object&&!u.fields)n=m(n[0]);else{if(n.length>u.maxSize)throw new Error(`Packet "${t}" only allows ${u.maxSize} values!`);if(n.length<u.minSize)throw new Error(`Packet "${t}" requires at least ${u.minSize} values!`)}if(u.object){if(n=n.map(e=>Array.isArray(e)?e:[e]),!u.autoFlatten){const e=u.dataMin,a=u.dataMax;for(let r=0;r<e.length;r++){if(n[r].length<e[r])throw new Error(`Section ${r+1} of packet "${t}" requires at least ${e[r]} values!`);if(n[r].length>a[r])throw new Error(`Section ${r+1} of packet "${t}" only allows ${a[r]} values!`)}}}else if(u.type!==r.PacketType.JSON){const e=n.find(e=>"object"==typeof e&&null!=e);e&&console.warn(`Passing an array will result in undefined behavior (${JSON.stringify(e)}). Spread the array with ...arr`)}const e=n.length>0?await u.processSend(n):i.EMPTY_UINT8;return[l,e,u]})}function d(e){return!(("number"==typeof e&&e in r.PacketType||e instanceof s.EnumPackage)&&e!=r.PacketType.KEY_EFFECTIVE)}const l=2048383;function u(e){return e<0?(console.warn("Having a data maximum below 0 does not do anything!"),0):e>l?(console.warn("Only 2048383 values can be sent on a type! Uhh make an issue if you want to send more."),l):e}function h(e,t){return e<0?(console.warn("Having a data minimum below 0 does not do anything!"),0):e>t?(console.warn("Data minimum can not be higher than the data maximum!"),t):e}function p(e){if(!Number.isFinite(e)||e<0)throw new Error("Rate limit must be a non-negative finite number");return(e=Math.floor(e))>i.MAX_USHORT?(console.warn(`A rate limit above ${i.MAX_USHORT} is considered infinite.`),0):e}function f(e){const t=!0===e.autoFlatten&&void 0===e.dataMax&&void 0===e.dataMin;let{tag:n,type:s=r.PacketType.NONE,dataMax:i=1,dataMin:o,noDataRange:c=!1,dontSpread:f=!1,validator:m=null,dataBatching:_=0,maxBatchSize:g=10,rateLimit:b=0,enabled:v=!0,async:k=!1,gzipCompression:E=s==r.PacketType.JSON,rereference:S=!1,schema:T,autoFlatten:P=!1,quantized:N,min:A,max:x}=e;if(!n)throw new Error("Tag not selected!");if(c||t?(o=S?1:0,i=l):null==o&&(o=s==r.PacketType.NONE?0:i),S&&0==o)throw new Error("Rereference cannot be true if the dataMin is 0");if(d(s))throw new Error(`Invalid packet type: ${s}`);if(w(T,n),P&&(!T||0===T.length))throw new Error(`Packet "${n}" autoFlatten requires schema`);if(T&&!P&&o===i&&T.length!==i)throw new Error(`Packet "${n}" schema length must match its fixed value count (${i})`);!function(e,t,n,a,r){if(void 0!==n&&void 0!==a&&n>a)throw new Error(`Packet "${r}" min cannot exceed max`);if((t||void 0!==n||void 0!==a)&&!y.has(e))throw new Error(`Packet "${r}" numeric options require a numeric packet type`);if(t&&(!Number.isFinite(t.scale)||t.scale<=0))throw new Error(`Packet "${r}" quantization scale must be positive and finite`)}(s,N,A,x,n);const O=new a.PacketSchema(!1,s,k,h(o,i),u(i),p(b),f,P,S,_,g,E,T,N,A,x);return new a.Packet(n,O,m,v,!1)}function w(e,t){if(e){if(!e.length||e.some(e=>"string"!=typeof e||!e))throw new Error(`Packet "${t}" schema must contain non-empty field names`);if(new Set(e).size!==e.length)throw new Error(`Packet "${t}" schema fields must be unique`)}}const y=new Set([r.PacketType.BYTES,r.PacketType.UBYTES,r.PacketType.SHORTS,r.PacketType.USHORTS,r.PacketType.VARINT,r.PacketType.UVARINT,r.PacketType.DELTAS,r.PacketType.FLOATS,r.PacketType.DOUBLES]);function m(e){if(null==e)return[];const t=e[0];if(null==t)return[];if(!Array.isArray(t))throw new Error(`Cannot flatten array: ${e}`);return t.map((t,n)=>e.map(e=>e[n]))??[]}},605(e,t,n){var a=n(804);e.exports=n.v(t,e.id,"a8f247f5205d0c667c14",{"./sonic_ws_core_bg.js":{__wbg_get_unchecked_6e0ad6d2a41b06f6:a.ss,__wbg_length_370319915dc99107:a.Sg,__wbg_push_d2ae3af0c1217ae6:a.Tb,__wbg_new_32b398fb48b6d94a:a.gV,__wbg_new_cd45aabdf6073e84:a.EW,__wbg_length_1f0964f4a5e2c6d8:a.Pt,__wbg_prototypesetcall_4770620bbe4688a0:a.pe,__wbg_new_from_slice_77cdfb7977362f3c:a.BV,__wbg___wbindgen_string_get_b0ca35b86a603356:a.oF,__wbg___wbindgen_number_get_394265ed1e1b84ee:a.JV,__wbg___wbindgen_throw_344f42d3211c4765:a.F6,__wbg___wbindgen_boolean_get_fa956cfa2d1bd751:a.sL,__wbindgen_init_externref_table:a.bL,__wbindgen_cast_0000000000000001:a.NR,__wbindgen_cast_0000000000000002:a.U_}})},619(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.PacketType=void 0,function(e){e[e.NONE=0]="NONE",e[e.RAW=1]="RAW",e[e.STRINGS_ASCII=2]="STRINGS_ASCII",e[e.STRINGS_UTF16=3]="STRINGS_UTF16",e[e.STRINGS=2]="STRINGS",e[e.ENUMS=4]="ENUMS",e[e.BYTES=5]="BYTES",e[e.UBYTES=6]="UBYTES",e[e.SHORTS=7]="SHORTS",e[e.USHORTS=8]="USHORTS",e[e.VARINT=9]="VARINT",e[e.UVARINT=10]="UVARINT",e[e.DELTAS=11]="DELTAS",e[e.FLOATS=12]="FLOATS",e[e.DOUBLES=13]="DOUBLES",e[e.BOOLEANS=14]="BOOLEANS",e[e.KEY_EFFECTIVE=15]="KEY_EFFECTIVE",e[e.JSON=16]="JSON",e[e.HEX=17]="HEX"}(n||(t.PacketType=n={}))},804(e,t,n){function a(e,t,n,a){const r=Z.decodeBatch(e,t,n,H(a)?Number.MAX_SAFE_INTEGER:a>>>0);if(r[2])throw Y(r[1]);return Y(r[0])}function r(e,t){const n=Z.decodeBooleans(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function s(e,t){const n=Z.decodeFloats(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function i(e){let t,n;try{const s=Z.decodeHex(e);var a=s[0],r=s[1];if(s[3])throw a=0,r=0,Y(s[2]);return t=a,n=r,V(a,r)}finally{Z.__wbindgen_free(t,n,1)}}function o(e){const t=Z.decodeRaw(e);if(t[2])throw Y(t[1]);return Y(t[0])}function c(e,t){const n=Z.decodeSigned(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function d(e,t){const n=Z.decodeStrings(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function l(e,t){const n=Z.decodeUnsigned(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function u(e){const t=Z.deflateRaw(e);if(t[2])throw Y(t[1]);return Y(t[0])}function h(e,t){const n=Z.encodeBatch(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function p(e){const t=Z.encodeBooleans(e);if(t[2])throw Y(t[1]);return Y(t[0])}function f(e,t){const n=Z.encodeFloats(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function w(e){const t=K(e,Z.__wbindgen_malloc,Z.__wbindgen_realloc),n=ee,a=Z.encodeHex(t,n);if(a[2])throw Y(a[1]);return Y(a[0])}function y(e,t){const n=Z.encodeSigned(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function m(e,t){const n=Z.encodeStrings(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function _(e,t){const n=Z.encodeUnsigned(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function g(e){const t=Z.frameObject(e);if(t[2])throw Y(t[1]);return Y(t[0])}function b(e,t){const n=Z.inflateRaw(e,H(t)?Number.MAX_SAFE_INTEGER:t>>>0);if(n[2])throw Y(n[1]);return Y(n[0])}function v(e,t){const n=Z.unframeObject(e,t);if(n[2])throw Y(n[1]);return Y(n[0])}function k(e,t,n,a,r,s,i){const o=Z.validateEncoded(e,t,n,a,r,s,H(i)?Number.MAX_SAFE_INTEGER:i>>>0);if(o[1])throw Y(o[0])}function E(e,t,n,a){const r=Z.validateEnum(e,t,n,a);if(r[1])throw Y(r[0])}function S(e,t,n,a,r){const s=Z.validateObject(e,t,n,a,r);if(s[1])throw Y(s[0])}function T(e){const t="boolean"==typeof e?e:void 0;return H(t)?16777215:t?1:0}function P(e,t){const n="number"==typeof t?t:void 0;F().setFloat64(e+8,H(n)?0:n,!0),F().setInt32(e+0,!H(n),!0)}function N(e,t){const n="string"==typeof t?t:void 0;var a=H(n)?0:K(n,Z.__wbindgen_malloc,Z.__wbindgen_realloc),r=ee;F().setInt32(e+4,r,!0),F().setInt32(e+0,a,!0)}function A(e,t){throw new Error(V(e,t))}function x(e,t){return e[t>>>0]}function O(e){return e.length}function M(e){return e.length}function C(){return new Array}function I(e){return new Uint8Array(e)}function R(e,t){return new Uint8Array(z(e,t))}function B(e,t,n){Uint8Array.prototype.set.call(z(e,t),n)}function U(e,t){return e.push(t)}function D(e){return e}function L(e,t){return V(e,t)}function $(){const e=Z.__wbindgen_externrefs,t=e.grow(4);e.set(0,void 0),e.set(t+0,void 0),e.set(t+1,null),e.set(t+2,!0),e.set(t+3,!1)}function z(e,t){return e>>>=0,q().subarray(e/1,e/1+t)}n.d(t,{B4:()=>h,BV:()=>R,Dq:()=>o,EF:()=>i,EW:()=>I,F6:()=>A,JV:()=>P,NR:()=>D,Pt:()=>O,Q5:()=>S,Sg:()=>M,Tb:()=>U,Ts:()=>y,U_:()=>L,XC:()=>m,_s:()=>f,at:()=>u,bL:()=>$,cv:()=>v,gV:()=>C,hD:()=>k,i1:()=>E,i4:()=>s,iT:()=>p,iX:()=>r,jN:()=>a,lI:()=>te,mU:()=>w,mk:()=>l,nt:()=>g,oF:()=>N,pe:()=>B,qO:()=>_,sL:()=>T,ss:()=>x,tD:()=>c,wS:()=>b,zC:()=>d});let j=null;function F(){return(null===j||!0===j.buffer.detached||void 0===j.buffer.detached&&j.buffer!==Z.memory.buffer)&&(j=new DataView(Z.memory.buffer)),j}function V(e,t){return function(e,t){X+=t,X>=G&&(J=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0}),J.decode(),X=t);return J.decode(q().subarray(e,e+t))}(e>>>0,t)}let W=null;function q(){return null!==W&&0!==W.byteLength||(W=new Uint8Array(Z.memory.buffer)),W}function H(e){return null==e}function K(e,t,n){if(void 0===n){const n=Q.encode(e),a=t(n.length,1)>>>0;return q().subarray(a,a+n.length).set(n),ee=n.length,a}let a=e.length,r=t(a,1)>>>0;const s=q();let i=0;for(;i<a;i++){const t=e.charCodeAt(i);if(t>127)break;s[r+i]=t}if(i!==a){0!==i&&(e=e.slice(i)),r=n(r,a,a=i+3*e.length,1)>>>0;const t=q().subarray(r+i,r+a);i+=Q.encodeInto(e,t).written,r=n(r,a,i,1)>>>0}return ee=i,r}function Y(e){const t=Z.__wbindgen_externrefs.get(e);return Z.__externref_table_dealloc(e),t}let J=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0});J.decode();const G=2146435072;let X=0;const Q=new TextEncoder;"encodeInto"in Q||(Q.encodeInto=function(e,t){const n=Q.encode(e);return t.set(n),{read:e.length,written:n.length}});let Z,ee=0;function te(e){Z=e}},853(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.DebugClient=void 0;t.DebugClient=class{host;constructor(e){this.host=e;const t=document.createElement("sonicws");t.innerHTML="<style>sws-h3{margin:0;color:#fff;font-size:16px;font-weight:600}#sonicws-container{display:flex;flex-direction:column;position:absolute;top:50px;left:50px;width:75vw;min-width:33vw;min-height:25vh;max-height:75vh;max-width:75vw;font-family:Arial,sans-serif;background-color:#2c2c2c;border-radius:10px;box-shadow:0 8px 20px rgba(0,0,0,.4);overflow:hidden;user-select:none;transition:box-shadow .2s ease;z-index:2147483647}#sonicws-container:hover{box-shadow:0 12px 28px rgba(0,0,0,.6)}#sonicws-header{display:flex;justify-content:space-between;align-items:center;cursor:move;background:linear-gradient(90deg,#4a90e2,#357ab7);padding:10px 12px;border-top-left-radius:10px;border-top-right-radius:10px}#sonicws-toggle{font-size:18px;font-weight:700;cursor:pointer;color:#fff;user-select:none}#sonicws-body{flex:1;display:flex;padding:12px;color:#e0e0e0;font-size:14px;min-height:0}#sonicws-stats{display:flex;flex-direction:column;min-width:140px}#sonicws-stats sws-p{margin:4px 0}#sonicws-packets{min-height:0;display:flex;flex-direction:column;flex:1;margin-left:10px;background-color:#1e1e1e;padding:8px;border-radius:8px;overflow-y:scroll}sws-div.packet{background-color:#2a2a2a;border-radius:6px;padding:3px 5px;margin-bottom:2px;cursor:pointer;transition:background .2s ease,transform .1s ease;display:flex;flex-direction:column}sws-div.packet:hover{background-color:#3a3a3a;transform:translateY(-1px)}sws-div.packet-header{display:flex;align-items:flex-start;flex-wrap:wrap;font-size:11px;white-space:normal;word-break:break-word}sws-span.packet-arrow{font-weight:700;margin-right:6px}sws-div.packet-details{margin-top:6px;font-size:10px;color:#aaa;display:none;flex-direction:column}sws-div.packet.expanded sws-div.packet-details{display:flex}#sonicws-resizer{width:12px;height:12px;background:#666;position:absolute;right:0;bottom:0;cursor:se-resize;border-bottom-right-radius:10px;transition:background .2s ease}#sonicws-resizer:hover{background:#888}#sonicws-container.minimized{width:auto!important;height:auto!important;min-width:unset;min-height:unset}#sonicws-container.minimized #sonicws-body,#sonicws-container.minimized #sonicws-resizer{display:none}#sonicws-container.minimized #sonicws-header{padding:8px 12px}#sonicws-container.minimized #sonicws-title{font-size:14px}</style><sws-div id=sonicws-container><sws-div id=sonicws-header><sws-h3 id=sonicws-title>SonicWS Debug Menu</sws-h3><sws-span id=sonicws-toggle>−</sws-span></sws-div><sws-div id=sonicws-body><sws-div id=sonicws-stats><sws-p>Status:<sws-span id=sonicws-status>Connecting</sws-span></sws-p><sws-p>Sent Packets:<sws-span id=sonicws-sent>0</sws-span></sws-p><sws-p>Received Packets:<sws-span id=sonicws-received>0</sws-span></sws-p><sws-p>Total Bytes Sent:<sws-span id=sonicws-sentbytes>0</sws-span></sws-p><sws-p>Total Bytes Received:<sws-span id=sonicws-receivedbytes>0</sws-span></sws-p><sws-p>Total Bytes Saved:<sws-span id=sonicws-savedbytes>0</sws-span></sws-p></sws-div><sws-div id=sonicws-packets></sws-div></sws-div><sws-div id=sonicws-resizer></sws-div></sws-div>",document.body?(document.body.appendChild(t),this._loadDebugScript()):document.addEventListener("DOMContentLoaded",()=>{document.body.appendChild(t),this._loadDebugScript()})}_evalInScope(e){const t=this.host;return new Function("send","WrapEnum","DeWrapEnum","FlattenData","UnFlattenData",`"use strict"; return (${e});`)(t.send.bind(t),t.WrapEnum.bind(t),t.DeWrapEnum.bind(t),t.FlattenData.bind(t),t.UnFlattenData.bind(t))}_loadDebugScript(){const e={},t={},n=this.host;this.host.addMiddleware(new class{onReceive_pre(e,n){t[e]??=[],t[e].push([n,performance.now()])}onReceive_post(e,a){const[r,s]=t[e].shift();T("received",`${e} (0x${n.serverPackets.getKey(e).toString(16).toUpperCase()})`,r,JSON.stringify(a),performance.now()-s)}onSend_pre(t,n){e[t]??=[],e[t].push([n,performance.now()])}onSend_post(t,a){const[r,s]=e[t].shift();T("sent",`${t} (0x${n.clientPackets.getKey(t).toString(16).toUpperCase()})`,a,JSON.stringify(r),performance.now()-s)}onStatusChange(e){E(e)}});const a=e=>document.getElementById(e),r=a("sonicws-container"),s=a("sonicws-header"),i=a("sonicws-resizer"),o=a("sonicws-status"),c=a("sonicws-packets"),d=a("sonicws-sent"),l=a("sonicws-received"),u=a("sonicws-sentbytes"),h=a("sonicws-receivedbytes"),p=a("sonicws-savedbytes"),f=document.getElementById("sonicws-toggle"),w=document.getElementById("sonicws-title");let y=!1;const m=document.createElement("input");m.type="text",m.placeholder='send("tag", 5)',m.style.marginTop="8px",m.style.width="100%",m.style.boxSizing="border-box";const _=document.createElement("button");function g(){const e=r.getBoundingClientRect(),t=window.innerWidth-e.width,n=window.innerHeight-e.height,a=Math.min(Math.max(0,e.left),Math.max(0,t)),s=Math.min(Math.max(0,e.top),Math.max(0,n));r.style.left=a+"px",r.style.top=s+"px"}_.innerText="Run",_.style.marginTop="4px",_.style.width="100%",a("sonicws-stats").appendChild(m),a("sonicws-stats").appendChild(_),_.addEventListener("click",()=>{try{this._evalInScope(m.value)}catch(e){console.error(e)}}),f.addEventListener("click",e=>{e.stopPropagation(),y=!y,y?(r.classList.add("minimized"),w.innerText="SWS",f.innerText="+",r.style.width="",r.style.height=""):(r.classList.remove("minimized"),w.innerText="SonicWS Debug Menu",f.innerText="−"),g()});const b={sentPackets:0,receivedPackets:0,totalBytesSent:0,totalBytesReceived:0,totalBytesSaved:0},v=new Proxy(b,{get(e,t){switch(t){case"sonicws-sent":return b.sentPackets;case"sonicws-received":return b.receivedPackets;case"sonicws-sentbytes":return b.totalBytesSent;case"sonicws-receivedbytes":return b.totalBytesReceived;case"sonicws-savedbytes":return b.totalBytesSaved;default:return}},set(e,t,n){switch(t){case"sonicws-sent":return b.sentPackets=n,d.innerText=n.toLocaleString(),!0;case"sonicws-received":return b.receivedPackets=n,l.innerText=n.toLocaleString(),!0;case"sonicws-sentbytes":{b.totalBytesSent=n;const{amt:e,unit:t}=k(n);return u.innerText=e+t,!0}case"sonicws-receivedbytes":{b.totalBytesReceived=n;const{amt:e,unit:t}=k(n);return h.innerText=e+t,!0}case"sonicws-savedbytes":{b.totalBytesSaved=n;const{amt:e,unit:t}=k(n);return p.innerText=e+t,!0}default:return!1}}}),k=e=>{if(!Number.isFinite(e)||e<0)return{amt:0,unit:"B"};const t=["B","KB","MB","GB","TB"];let n=e,a=0;for(;n>=1024&&a<t.length-1;)n/=1024,a++;return{amt:0==a?n.toString():n.toFixed(2),unit:t[a]}};function E(e){switch(e){case WebSocket.CLOSED:o.innerText="Closed",o.style.color="#f00";break;case WebSocket.CLOSING:o.innerText="Closing",o.style.color="#fa0";break;case WebSocket.OPEN:o.innerText="Open",o.style.color="#0f0";break;case WebSocket.CONNECTING:o.innerText="Connecting",o.style.color="#ff0";break;default:o.innerText="Unknown",o.style.color="#777"}}E(WebSocket.CONNECTING);const S=new TextEncoder;function T(e,t,n,a,r){const s=new Date,i=n.length+("sent"==e?1:0),o=S.encode(a).length-i+1,d=document.createElement("sws-div");d.classList.add("packet");const l=document.createElement("sws-div");l.classList.add("packet-header");const u=document.createElement("sws-span");u.classList.add("packet-arrow"),u.innerText="sent"===e?"⬆":"⬇",u.style.color="sent"===e?"#0f0":"#f00";const h=document.createElement("sws-span");h.innerText=t+": "+a,l.appendChild(u),l.appendChild(h);const p=document.createElement("sws-div");p.classList.add("packet-details"),p.innerHTML=`\n <sws-p> Raw Bytes: ${i}b (saved ~${o}b)</sws-p>\n <sws-p> Processed At: ${s.toISOString()} </sws-p>\n <sws-p> Processing Time: <sws-span class="processing-time" > ${r.toFixed(1)} </sws-span> ms</sws-p>\n `,d.appendChild(l),d.appendChild(p),c.append(d),l.addEventListener("click",()=>d.classList.toggle("expanded")),"sent"===e?(v["sonicws-sent"]++,v["sonicws-sentbytes"]+=i):(v["sonicws-received"]++,v["sonicws-receivedbytes"]+=i),v["sonicws-savedbytes"]+=o}let P=!1,N=0,A=0,x=0,O=0,M=!1,C=0,I=0,R=0,B=0;s.addEventListener("mousedown",e=>{P=!0,N=e.clientX,A=e.clientY;const t=r.getBoundingClientRect();x=t.left,O=t.top,e.preventDefault()}),i.addEventListener("mousedown",e=>{M=!0,C=e.clientX,I=e.clientY;const t=r.getBoundingClientRect();R=t.width,B=t.height,e.preventDefault()}),document.addEventListener("mousemove",e=>{P&&(r.style.left=x+e.clientX-N+"px",r.style.top=O+e.clientY-A+"px",g()),M&&!y&&(r.style.width=R+e.clientX-C+"px",r.style.height=B+e.clientY-I+"px",g())}),document.addEventListener("mouseup",()=>{P=!1,M=!1}),g(),window.addEventListener("resize",g)}}},880(e,t,n){n.a(e,async(e,a)=>{try{n.r(t),n.d(t,{decodeBatch:()=>s.jN,decodeBooleans:()=>s.iX,decodeFloats:()=>s.i4,decodeHex:()=>s.EF,decodeRaw:()=>s.Dq,decodeSigned:()=>s.tD,decodeStrings:()=>s.zC,decodeUnsigned:()=>s.mk,deflateRaw:()=>s.at,encodeBatch:()=>s.B4,encodeBooleans:()=>s.iT,encodeFloats:()=>s._s,encodeHex:()=>s.mU,encodeSigned:()=>s.Ts,encodeStrings:()=>s.XC,encodeUnsigned:()=>s.qO,frameObject:()=>s.nt,inflateRaw:()=>s.wS,unframeObject:()=>s.cv,validateEncoded:()=>s.hD,validateEnum:()=>s.i1,validateObject:()=>s.Q5});var r=n(605),s=n(804),i=e([r]);r=(i.then?(await i)():i)[0],(0,s.lI)(r),r.__wbindgen_start(),a()}catch(e){a(e)}})},913(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.CloseCodes=t.Connection=void 0,t.getClosureCause=function(e){if(e>=4e3)return i[e]??"UNKNOWN";switch(e){case 1e3:return"NORMAL_CLOSURE";case 1001:return"GOING_AWAY";case 1002:return"PROTOCOL_ERROR";case 1003:return"UNSUPPORTED_DATA";case 1006:return"ABNORMAL_CLOSURE";default:return"UNKNOWN"}};const a=n(985),r=n(8);class s extends a.MiddlewareHolder{listeners;rawSendListeners=[];name;closed=!1;socket;_timers={};batcher;_on;_off;id;state={};constructor(e,t,n,a,s){super(),this.id=t,this.listeners={},this.name=n,this.socket=e,this.batcher=new r.BatchHelper,this._on=a,this._off=s,this._on("close",()=>{this.callMiddleware("onStatusChange",WebSocket.CLOSED),this.closed=!0;for(const[e,t,n]of Object.values(this._timers))this.clearTimeout(e),n&&t(!0)}),this._on("open",()=>this.callMiddleware("onStatusChange",WebSocket.OPEN))}setTimeout(e,t,n=!1){const a=setTimeout(()=>{e(),this.clearTimeout(a)},t);return this._timers[a]=[a,e,n],a}setInterval(e,t,n=!1){const a=setInterval(e,t);return this._timers[a]=[a,e,n],a}clearTimeout(e){clearTimeout(e),delete this._timers[e]}clearInterval(e){this.clearTimeout(e)}raw_send(e){this.socket.send(e);for(const t of this.rawSendListeners)t(e)}raw_onmessage(e){this._on("message",e)}raw_onsend(e){this.rawSendListeners.push(e)}close(e=1e3,t){this.closed=!0,this.socket.close(e,t?.toString())}isClosed(){return this.closed||this.socket.readyState==WebSocket.CLOSED}async setName(e){await this.callMiddleware("onNameChange",e)||(this.name=e)}getName(){return this.name}}var i;t.Connection=s,function(e){e[e.RATELIMIT=4e3]="RATELIMIT",e[e.SMALL=4001]="SMALL",e[e.INVALID_KEY=4002]="INVALID_KEY",e[e.INVALID_PACKET=4003]="INVALID_PACKET",e[e.INVALID_DATA=4004]="INVALID_DATA",e[e.REPEATED_HANDSHAKE=4005]="REPEATED_HANDSHAKE",e[e.DISABLED_PACKET=4006]="DISABLED_PACKET",e[e.MIDDLEWARE=4007]="MIDDLEWARE",e[e.MANUAL_SHUTDOWN=4008]="MANUAL_SHUTDOWN"}(i||(t.CloseCodes=i={}))},937(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.SonicWSCore=void 0;const a=n(404),r=n(30),s=n(351),i=n(433),o=n(234),c=n(102),d=n(8),l=n(950),u=n(913),h=n(157);class p extends u.Connection{preListen;clientPackets=new a.PacketHolder;serverPackets=new a.PacketHolder;pastKeys=!1;readyListeners=[];bufferHandler;_timers={};asyncData={};asyncMap={};constructor(e,t,n,a){super(e,-1,"LocalSocket",n,a),this.socket=e,this.preListen={},this.invalidPacket=this.invalidPacket.bind(this),this.serverKeyHandler=this.serverKeyHandler.bind(this),this.messageHandler=this.messageHandler.bind(this),this._on("message",this.serverKeyHandler),this._on("close",()=>{this.callMiddleware("onStatusChange",WebSocket.CLOSED);for(const[e,t,n]of Object.values(this._timers))this.clearTimeout(e),n&&t(!0);for(const e of this.clientPackets.getPackets())delete e.lastSent[0],e.clearQuantizationState(0);for(const e of this.serverPackets.getPackets())delete e.lastReceived[0]}),this.bufferHandler=t}reading=!1;readQueue=[];async serverKeyHandler(e){if(this.reading)return this.readQueue.push(e);this.reading=!0;const t=await this.bufferHandler(e);if(t.length<3||(0,h.as8String)(t.slice(0,3))!=o.SERVER_SUFFIX)throw this.close(1e3),new Error("The server requested is not a Sonic WS server.");const n=t[3];if(n!=o.VERSION)throw this.close(1e3),new Error(`Version mismatch: ${n>o.VERSION?"client":"server"} is outdated (server: ${n}, client: ${o.VERSION})`);const a=(0,s.inflateNative)(t.subarray(4,t.length)),[i,d]=(0,r.readVarInt)(a,0);this.id=d;const[l,u]=(0,r.readVarInt)(a,i),p=a.subarray(l,l+u);this.clientPackets.holdPackets(c.Packet.deserializeAll(p,!0));const f=a.subarray(l+u,a.length);this.serverPackets.holdPackets(c.Packet.deserializeAll(f,!0)),this.batcher.registerSendPackets(this.clientPackets,this);for(const e of this.serverPackets.getPackets()){const t=this.serverPackets.getKey(e.tag);this.asyncMap[t]=e.async,e.async&&(this.asyncData[t]=[!1,[]])}Object.keys(this.preListen).forEach(e=>this.preListen[e].forEach(t=>{if(!this.serverPackets.hasTag(e))return console.error(new Error(`The server does not send the packet with tag "${e}"!`));this.listen(e,t)})),this.preListen=null,this.pastKeys=!0,this.readyListeners.forEach(e=>e()),this.readyListeners=null,this._off("message",this.serverKeyHandler),this._on("message",this.messageHandler),this.readQueue.forEach(e=>this.messageHandler(e)),this.readQueue=[]}invalidPacket(e){throw console.error(e),new Error("An error occured with data from the server!! This is probably my fault.. make an issue at https://github.com/liwybloc/sonic-ws")}listenLock=!1;packetQueue=[];async listenPacket(e,t,n,a,r){const s=this.listeners[t],o=this.serverPackets.getPacket(t),c=o.parent?this.listeners[o.parent]:void 0;if(!s&&!c)return console.warn("Warn: No listener for packet "+t),void await this.triggerNextPacket(n,a,r);if(s&&await(0,i.listenPacket)(e,s,this.invalidPacket),"string"!=typeof e&&o.parent&&o.variant)for(const t of c??[])await t({variant:o.variant,payload:e[0]});await this.triggerNextPacket(n,a,r),await this.callMiddleware("onReceive_post",t,"string"==typeof e?[e]:e[0])}isAsync(e){return this.asyncMap[e]}async enqueuePacket(e,t,n,a,r){await(0,i.listenPacket)(e,t,this.invalidPacket),await this.triggerNextPacket(n,a,r)}async triggerNextPacket(e,t,n){t?n[0]=!1:this.listenLock=!1,e.length>0&&this.dataHandler(e.shift())}async dataHandler(e){const t=e[0],n=e.slice(1),a=this.isAsync(t);let r,s,i;if(a?(i=this.asyncData[t],r=i[0],s=i[1]):(r=this.listenLock,s=this.packetQueue),r)return void s.push(e);a?i[0]=!0:this.listenLock=!0;const o=this.serverPackets.getTag(t),c=this.serverPackets.getPacket(o);if(await this.callMiddleware("onReceive_pre",c.tag,e,e.length))return;if(c.rereference&&0==n.length)return void 0===c.lastReceived[0]?this.invalidPacket("No previous value to rereference"):void this.listenPacket(c.lastReceived[0],o,s,a,i);if(0==c.dataBatching){const e=c.lastReceived[0]=await c.listen(n,null);return void this.listenPacket(e,o,s,a,i)}const l=await d.BatchHelper.unravelBatch(c,n,null);if("string"==typeof l)return this.invalidPacket(l);l.forEach(e=>this.listenPacket(e,o,s,a,i))}async messageHandler(e){const t=await this.bufferHandler(e);t.length<1||await this.dataHandler(t)}listen(e,t){if(!this.serverPackets.hasTag(e))return void console.log("Tag is not available on server: "+e);const n=this.serverPackets.resolveTag(e);(this.listeners[n]??=[]).push(t)}sendQueue=[!1,[],void 0];async send(e,...t){if(await this.callMiddleware("onSend_pre",e,t,Date.now(),performance.now()))return;const[n,a,r]=await(0,i.processPacket)(this.clientPackets,e,t,this.sendQueue,0);0==r.dataBatching?this.raw_send((0,l.toPacketBuffer)(n,a)):this.batcher.batchPacket(n,a),await this.callMiddleware("onSend_post",e,a,a.length)}sendVariant(e,t,...n){return this.send(this.clientPackets.getVariantTag(e,t),...n)}async sendSafe(e,...t){try{return await this.send(e,...t),!0}catch(t){return console.error(`Failed to send packet "${e}"`,t),!1}}on_ready(e){this.pastKeys?e():this.readyListeners.push(e)}on_close(e){this._on("close",e)}on(e,t){if(this.socket.readyState!==WebSocket.OPEN)return this.preListen[e]||(this.preListen[e]=[]),void this.preListen[e].push(t);this.listen(e,t)}}t.SonicWSCore=p},950(e,t){function n(e,t){const n=[];for(let a=0;a<e.length;a+=t){const r=e.slice(a,a+t);n.push(r)}return n}Object.defineProperty(t,"__esModule",{value:!0}),t.splitArray=n,t.toPacketBuffer=function(e,t){const n=new Uint8Array(1+t.length);return n[0]=e,n.set(t,1),n},t.splitBuffer=function(e,t){return n(Array.from(e),t)},t.stringifyBuffer=function(e){return`<Buffer ${Array.from(e).map(e=>e.toString(16).padStart(2,"0")).join(" ")}>`}},985(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.MiddlewareHolder=void 0;t.MiddlewareHolder=class{middlewares=[];addMiddleware(e){this.middlewares.push(e);const t=e;try{"function"==typeof t.init&&t.init(this)}catch(e){console.warn("Middleware init threw an error:",e)}}async callMiddleware(e,...t){let n=!1;for(const a of this.middlewares){const r=a[e];if(r)try{await r(...t)&&(n=!0)}catch(t){console.warn(`Middleware ${String(e)} threw an error:`,t)}}return n}}}},__webpack_module_cache__={},hasSymbol,webpackQueues,webpackExports,webpackError,resolveQueue;function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,exports:{}};return __webpack_modules__[e](n,n.exports,__webpack_require__),n.exports}hasSymbol="function"==typeof Symbol,webpackQueues=hasSymbol?Symbol("webpack queues"):"__webpack_queues__",webpackExports=hasSymbol?Symbol("webpack exports"):"__webpack_exports__",webpackError=hasSymbol?Symbol("webpack error"):"__webpack_error__",resolveQueue=e=>{e&&e.d<1&&(e.d=1,e.forEach(e=>e.r--),e.forEach(e=>e.r--?e.r++:e()))},__webpack_require__.a=(e,t,n)=>{var a;n&&((a=[]).d=-1);var r,s,i,o=new Set,c=e.exports,d=new Promise((e,t)=>{i=t,s=e});d[webpackExports]=c,d[webpackQueues]=e=>(a&&e(a),o.forEach(e),d.catch(e=>{})),e.exports=d,t(e=>{var t;r=(e=>e.map(e=>{if(null!==e&&"object"==typeof e){if(e[webpackQueues])return e;if(e.then){var t=[];t.d=0,e.then(e=>{n[webpackExports]=e,resolveQueue(t)},e=>{n[webpackError]=e,resolveQueue(t)});var n={};return n[webpackQueues]=e=>e(t),n}}var a={};return a[webpackQueues]=e=>{},a[webpackExports]=e,a}))(e);var n=()=>r.map(e=>{if(e[webpackError])throw e[webpackError];return e[webpackExports]}),s=new Promise(e=>{(t=()=>e(n)).r=0;var s=e=>e!==a&&!o.has(e)&&(o.add(e),e&&!e.d&&(t.r++,e.push(t)));r.map(e=>e[webpackQueues](s))});return t.r?s:n()},e=>(e?i(d[webpackError]=e):s(c),resolveQueue(a))),a&&a.d<0&&(a.d=0)},__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.v=(e,t,n,a)=>{var r=fetch(__webpack_require__.p+"bundle.wasm"),s=()=>r.then(e=>e.arrayBuffer()).then(e=>WebAssembly.instantiate(e,a)).then(t=>Object.assign(e,t.instance.exports));return r.then(t=>"function"==typeof WebAssembly.instantiateStreaming?WebAssembly.instantiateStreaming(t,a).then(t=>Object.assign(e,t.instance.exports),e=>{if("application/wasm"!==t.headers.get("Content-Type"))return console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",e),s();throw e}):s())},(()=>{var e;__webpack_require__.g.importScripts&&(e=__webpack_require__.g.location+"");var t=__webpack_require__.g.document;if(!e&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){var n=t.getElementsByTagName("script");if(n.length)for(var a=n.length-1;a>-1&&(!e||!/^http(s?):/.test(e));)e=n[a--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),__webpack_require__.p=e})();var __webpack_exports__={};(()=>{const e=__webpack_require__(853),t=__webpack_require__(388),n=__webpack_require__(433),a=__webpack_require__(937),r=__webpack_require__(351);class s extends a.SonicWSCore{static initialize(){return(0,r.initializeWasmCore)()}antiTamperCall=()=>{};constructor(e,t,n=!1){const a=new WebSocket(e,t);if(super(a,async e=>new Uint8Array(await e.data.arrayBuffer()),a.addEventListener.bind(a),a.removeEventListener.bind(a)),n){const e=this,t=a.send.bind(a),n=this.send.bind(this);let r;this.send=async(t,...a)=>(r=e.clientPackets.getKey(t),await n(t,...a)),a.send=n=>n instanceof Uint8Array&&r==n[0]?t(n):(e.antiTamperCall(),void e.close())}}on_tamper(e){this.antiTamperCall=e}WrapEnum(e,n){return(0,t.WrapEnum)(e,n)}DeWrapEnum(e,n){return(0,t.DeWrapEnum)(e,n)}FlattenData(e){return(0,n.FlattenData)(e)}UnFlattenData(e){return(0,n.UnFlattenData)(e)}debugClient=null;OpenDebug(){if(null!=this.debugClient)throw new Error("Debug client has already been opened!");this.debugClient=new e.DebugClient(this)}}window.SonicWS=s})()})();
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export { SonicWSConnection } from './ws/server/SonicWSConnection';
|
|
|
8
8
|
export { SonicWSServer } from './ws/server/SonicWSServer';
|
|
9
9
|
export { PacketType } from './ws/packets/PacketType';
|
|
10
10
|
export { BasicMiddleware, ConnectionMiddleware, ServerMiddleware, BCInfo } from './ws/PacketProcessor';
|
|
11
|
-
export { CreatePacket, CreateObjPacket, CreateEnumPacket, FlattenData, UnFlattenData } from './ws/util/packets/PacketUtils';
|
|
11
|
+
export { CreatePacket, CreateObjPacket, CreateEnumPacket, CreatePacketGroup, FlattenData, UnFlattenData } from './ws/util/packets/PacketUtils';
|
|
12
12
|
export { DefineEnum, WrapEnum } from './ws/util/enums/EnumHandler';
|
|
13
13
|
export { initializeWasmCore } from './native/wrapper';
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
13
13
|
*/
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.initializeWasmCore = exports.WrapEnum = exports.DefineEnum = exports.UnFlattenData = exports.FlattenData = exports.CreateEnumPacket = exports.CreateObjPacket = exports.CreatePacket = exports.PacketType = exports.SonicWSServer = exports.SonicWSConnection = exports.SonicWS = void 0;
|
|
15
|
+
exports.initializeWasmCore = exports.WrapEnum = exports.DefineEnum = exports.UnFlattenData = exports.FlattenData = exports.CreatePacketGroup = exports.CreateEnumPacket = exports.CreateObjPacket = exports.CreatePacket = exports.PacketType = exports.SonicWSServer = exports.SonicWSConnection = exports.SonicWS = void 0;
|
|
16
16
|
var ClientNode_1 = require("./ws/client/node/ClientNode");
|
|
17
17
|
Object.defineProperty(exports, "SonicWS", { enumerable: true, get: function () { return ClientNode_1.SonicWS; } });
|
|
18
18
|
var SonicWSConnection_1 = require("./ws/server/SonicWSConnection");
|
|
@@ -25,6 +25,7 @@ var PacketUtils_1 = require("./ws/util/packets/PacketUtils");
|
|
|
25
25
|
Object.defineProperty(exports, "CreatePacket", { enumerable: true, get: function () { return PacketUtils_1.CreatePacket; } });
|
|
26
26
|
Object.defineProperty(exports, "CreateObjPacket", { enumerable: true, get: function () { return PacketUtils_1.CreateObjPacket; } });
|
|
27
27
|
Object.defineProperty(exports, "CreateEnumPacket", { enumerable: true, get: function () { return PacketUtils_1.CreateEnumPacket; } });
|
|
28
|
+
Object.defineProperty(exports, "CreatePacketGroup", { enumerable: true, get: function () { return PacketUtils_1.CreatePacketGroup; } });
|
|
28
29
|
Object.defineProperty(exports, "FlattenData", { enumerable: true, get: function () { return PacketUtils_1.FlattenData; } });
|
|
29
30
|
Object.defineProperty(exports, "UnFlattenData", { enumerable: true, get: function () { return PacketUtils_1.UnFlattenData; } });
|
|
30
31
|
var EnumHandler_1 = require("./ws/util/enums/EnumHandler");
|
package/dist/version.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* See LICENSE for personal, non-commercial license terms.
|
|
5
5
|
*/
|
|
6
6
|
/** Current protocol version */
|
|
7
|
-
export declare const VERSION =
|
|
7
|
+
export declare const VERSION = 23;
|
|
8
8
|
/** Server data suffix */
|
|
9
9
|
export declare const SERVER_SUFFIX = "SWS";
|
|
10
10
|
/** Server data suffix in array */
|
package/dist/version.js
CHANGED
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* See LICENSE for personal, non-commercial license terms.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.SERVER_SUFFIX_NUMS=exports.SERVER_SUFFIX=exports.VERSION=void 0;const e=require("./ws/util/StringUtil");exports.VERSION=
|
|
7
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.SERVER_SUFFIX_NUMS=exports.SERVER_SUFFIX=exports.VERSION=void 0;const e=require("./ws/util/StringUtil");exports.VERSION=23,exports.SERVER_SUFFIX="SWS",exports.SERVER_SUFFIX_NUMS=(0,e.processCharCodes)(exports.SERVER_SUFFIX);
|
package/dist/ws/Connection.d.ts
CHANGED
|
@@ -86,6 +86,8 @@ export declare abstract class Connection<T extends {
|
|
|
86
86
|
_off: Function;
|
|
87
87
|
/** The index of the connection; unique for all connected, not unique after disconnection. */
|
|
88
88
|
id: number;
|
|
89
|
+
/** Mutable application-owned state scoped to this connection. */
|
|
90
|
+
state: Record<string, unknown>;
|
|
89
91
|
constructor(socket: T, id: number, name: string, addListener: Function, removeListener: Function);
|
|
90
92
|
setTimeout(call: () => void, time: number, callOnClose?: boolean): number;
|
|
91
93
|
setInterval(call: () => void, time: number, callOnClose?: boolean): number;
|
package/dist/ws/Connection.js
CHANGED
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* See LICENSE for personal, non-commercial license terms.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.CloseCodes=exports.Connection=void 0,exports.getClosureCause=function(e){if(e>=4e3)return r[e]??"UNKNOWN";switch(e){case 1e3:return"NORMAL_CLOSURE";case 1001:return"GOING_AWAY";case 1002:return"PROTOCOL_ERROR";case 1003:return"UNSUPPORTED_DATA";case 1006:return"ABNORMAL_CLOSURE";default:return"UNKNOWN"}};const e=require("./PacketProcessor"),t=require("./util/packets/BatchHelper");class s extends e.MiddlewareHolder{listeners;rawSendListeners=[];name;closed=!1;socket;_timers={};batcher;_on;_off;id;constructor(e,s,r,o,i){super(),this.id=s,this.listeners={},this.name=r,this.socket=e,this.batcher=new t.BatchHelper,this._on=o,this._off=i,this._on("close",()=>{this.callMiddleware("onStatusChange",WebSocket.CLOSED),this.closed=!0;for(const[e,t,s]of Object.values(this._timers))this.clearTimeout(e),s&&t(!0)}),this._on("open",()=>this.callMiddleware("onStatusChange",WebSocket.OPEN))}setTimeout(e,t,s=!1){const r=setTimeout(()=>{e(),this.clearTimeout(r)},t);return this._timers[r]=[r,e,s],r}setInterval(e,t,s=!1){const r=setInterval(e,t);return this._timers[r]=[r,e,s],r}clearTimeout(e){clearTimeout(e),delete this._timers[e]}clearInterval(e){this.clearTimeout(e)}raw_send(e){this.socket.send(e);for(const t of this.rawSendListeners)t(e)}raw_onmessage(e){this._on("message",e)}raw_onsend(e){this.rawSendListeners.push(e)}close(e=1e3,t){this.closed=!0,this.socket.close(e,t?.toString())}isClosed(){return this.closed||this.socket.readyState==WebSocket.CLOSED}async setName(e){await this.callMiddleware("onNameChange",e)||(this.name=e)}getName(){return this.name}}var r;exports.Connection=s,function(e){e[e.RATELIMIT=4e3]="RATELIMIT",e[e.SMALL=4001]="SMALL",e[e.INVALID_KEY=4002]="INVALID_KEY",e[e.INVALID_PACKET=4003]="INVALID_PACKET",e[e.INVALID_DATA=4004]="INVALID_DATA",e[e.REPEATED_HANDSHAKE=4005]="REPEATED_HANDSHAKE",e[e.DISABLED_PACKET=4006]="DISABLED_PACKET",e[e.MIDDLEWARE=4007]="MIDDLEWARE",e[e.MANUAL_SHUTDOWN=4008]="MANUAL_SHUTDOWN"}(r||(exports.CloseCodes=r={}));
|
|
7
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.CloseCodes=exports.Connection=void 0,exports.getClosureCause=function(e){if(e>=4e3)return r[e]??"UNKNOWN";switch(e){case 1e3:return"NORMAL_CLOSURE";case 1001:return"GOING_AWAY";case 1002:return"PROTOCOL_ERROR";case 1003:return"UNSUPPORTED_DATA";case 1006:return"ABNORMAL_CLOSURE";default:return"UNKNOWN"}};const e=require("./PacketProcessor"),t=require("./util/packets/BatchHelper");class s extends e.MiddlewareHolder{listeners;rawSendListeners=[];name;closed=!1;socket;_timers={};batcher;_on;_off;id;state={};constructor(e,s,r,o,i){super(),this.id=s,this.listeners={},this.name=r,this.socket=e,this.batcher=new t.BatchHelper,this._on=o,this._off=i,this._on("close",()=>{this.callMiddleware("onStatusChange",WebSocket.CLOSED),this.closed=!0;for(const[e,t,s]of Object.values(this._timers))this.clearTimeout(e),s&&t(!0)}),this._on("open",()=>this.callMiddleware("onStatusChange",WebSocket.OPEN))}setTimeout(e,t,s=!1){const r=setTimeout(()=>{e(),this.clearTimeout(r)},t);return this._timers[r]=[r,e,s],r}setInterval(e,t,s=!1){const r=setInterval(e,t);return this._timers[r]=[r,e,s],r}clearTimeout(e){clearTimeout(e),delete this._timers[e]}clearInterval(e){this.clearTimeout(e)}raw_send(e){this.socket.send(e);for(const t of this.rawSendListeners)t(e)}raw_onmessage(e){this._on("message",e)}raw_onsend(e){this.rawSendListeners.push(e)}close(e=1e3,t){this.closed=!0,this.socket.close(e,t?.toString())}isClosed(){return this.closed||this.socket.readyState==WebSocket.CLOSED}async setName(e){await this.callMiddleware("onNameChange",e)||(this.name=e)}getName(){return this.name}}var r;exports.Connection=s,function(e){e[e.RATELIMIT=4e3]="RATELIMIT",e[e.SMALL=4001]="SMALL",e[e.INVALID_KEY=4002]="INVALID_KEY",e[e.INVALID_PACKET=4003]="INVALID_PACKET",e[e.INVALID_DATA=4004]="INVALID_DATA",e[e.REPEATED_HANDSHAKE=4005]="REPEATED_HANDSHAKE",e[e.DISABLED_PACKET=4006]="DISABLED_PACKET",e[e.MIDDLEWARE=4007]="MIDDLEWARE",e[e.MANUAL_SHUTDOWN=4008]="MANUAL_SHUTDOWN"}(r||(exports.CloseCodes=r={}));
|
|
@@ -43,6 +43,8 @@ export declare abstract class SonicWSCore<T extends {
|
|
|
43
43
|
* @param values The values to send
|
|
44
44
|
*/
|
|
45
45
|
send(tag: string, ...values: any[]): Promise<void>;
|
|
46
|
+
sendVariant(parent: string, variant: string, ...values: any[]): Promise<void>;
|
|
47
|
+
sendSafe(tag: string, ...values: any[]): Promise<boolean>;
|
|
46
48
|
/**
|
|
47
49
|
* Listens for when the client connects
|
|
48
50
|
* @param listener Callback on connection
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* See LICENSE for personal, non-commercial license terms.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.SonicWSCore=void 0;const e=require("../../util/packets/PacketHolder"),t=require("../../util/packets/CompressionUtil"),s=require("../../../native/wrapper"),i=require("../../util/packets/PacketUtils"),a=require("../../../version"),r=require("../../packets/Packets"),n=require("../../util/packets/BatchHelper"),c=require("../../util/BufferUtil"),o=require("../../Connection"),h=require("../../util/StringUtil");class l extends o.Connection{preListen;clientPackets=new e.PacketHolder;serverPackets=new e.PacketHolder;pastKeys=!1;readyListeners=[];bufferHandler;_timers={};asyncData={};asyncMap={};constructor(e,t,s,i){super(e,-1,"LocalSocket",s,i),this.socket=e,this.preListen={},this.invalidPacket=this.invalidPacket.bind(this),this.serverKeyHandler=this.serverKeyHandler.bind(this),this.messageHandler=this.messageHandler.bind(this),this._on("message",this.serverKeyHandler),this._on("close",()=>{this.callMiddleware("onStatusChange",WebSocket.CLOSED);for(const[e,t,s]of Object.values(this._timers))this.clearTimeout(e),s&&t(!0);for(const e of this.clientPackets.getPackets())delete e.lastSent[0];for(const e of this.serverPackets.getPackets())delete e.lastReceived[0]}),this.bufferHandler=t}reading=!1;readQueue=[];async serverKeyHandler(e){if(this.reading)return this.readQueue.push(e);this.reading=!0;const i=await this.bufferHandler(e);if(i.length<3||(0,h.as8String)(i.slice(0,3))!=a.SERVER_SUFFIX)throw this.close(1e3),new Error("The server requested is not a Sonic WS server.");const n=i[3];if(n!=a.VERSION)throw this.close(1e3),new Error(`Version mismatch: ${n>a.VERSION?"client":"server"} is outdated (server: ${n}, client: ${a.VERSION})`);const c=(0,s.inflateNative)(i.subarray(4,i.length)),[o,l]=(0,t.readVarInt)(c,0);this.id=l;const[d,u]=(0,t.readVarInt)(c,o),k=c.subarray(d,d+u);this.clientPackets.holdPackets(r.Packet.deserializeAll(k,!0));const
|
|
7
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.SonicWSCore=void 0;const e=require("../../util/packets/PacketHolder"),t=require("../../util/packets/CompressionUtil"),s=require("../../../native/wrapper"),i=require("../../util/packets/PacketUtils"),a=require("../../../version"),r=require("../../packets/Packets"),n=require("../../util/packets/BatchHelper"),c=require("../../util/BufferUtil"),o=require("../../Connection"),h=require("../../util/StringUtil");class l extends o.Connection{preListen;clientPackets=new e.PacketHolder;serverPackets=new e.PacketHolder;pastKeys=!1;readyListeners=[];bufferHandler;_timers={};asyncData={};asyncMap={};constructor(e,t,s,i){super(e,-1,"LocalSocket",s,i),this.socket=e,this.preListen={},this.invalidPacket=this.invalidPacket.bind(this),this.serverKeyHandler=this.serverKeyHandler.bind(this),this.messageHandler=this.messageHandler.bind(this),this._on("message",this.serverKeyHandler),this._on("close",()=>{this.callMiddleware("onStatusChange",WebSocket.CLOSED);for(const[e,t,s]of Object.values(this._timers))this.clearTimeout(e),s&&t(!0);for(const e of this.clientPackets.getPackets())delete e.lastSent[0],e.clearQuantizationState(0);for(const e of this.serverPackets.getPackets())delete e.lastReceived[0]}),this.bufferHandler=t}reading=!1;readQueue=[];async serverKeyHandler(e){if(this.reading)return this.readQueue.push(e);this.reading=!0;const i=await this.bufferHandler(e);if(i.length<3||(0,h.as8String)(i.slice(0,3))!=a.SERVER_SUFFIX)throw this.close(1e3),new Error("The server requested is not a Sonic WS server.");const n=i[3];if(n!=a.VERSION)throw this.close(1e3),new Error(`Version mismatch: ${n>a.VERSION?"client":"server"} is outdated (server: ${n}, client: ${a.VERSION})`);const c=(0,s.inflateNative)(i.subarray(4,i.length)),[o,l]=(0,t.readVarInt)(c,0);this.id=l;const[d,u]=(0,t.readVarInt)(c,o),k=c.subarray(d,d+u);this.clientPackets.holdPackets(r.Packet.deserializeAll(k,!0));const v=c.subarray(d+u,c.length);this.serverPackets.holdPackets(r.Packet.deserializeAll(v,!0)),this.batcher.registerSendPackets(this.clientPackets,this);for(const e of this.serverPackets.getPackets()){const t=this.serverPackets.getKey(e.tag);this.asyncMap[t]=e.async,e.async&&(this.asyncData[t]=[!1,[]])}Object.keys(this.preListen).forEach(e=>this.preListen[e].forEach(t=>{if(!this.serverPackets.hasTag(e))return console.error(new Error(`The server does not send the packet with tag "${e}"!`));this.listen(e,t)})),this.preListen=null,this.pastKeys=!0,this.readyListeners.forEach(e=>e()),this.readyListeners=null,this._off("message",this.serverKeyHandler),this._on("message",this.messageHandler),this.readQueue.forEach(e=>this.messageHandler(e)),this.readQueue=[]}invalidPacket(e){throw console.error(e),new Error("An error occured with data from the server!! This is probably my fault.. make an issue at https://github.com/liwybloc/sonic-ws")}listenLock=!1;packetQueue=[];async listenPacket(e,t,s,a,r){const n=this.listeners[t],c=this.serverPackets.getPacket(t),o=c.parent?this.listeners[c.parent]:void 0;if(!n&&!o)return console.warn("Warn: No listener for packet "+t),void await this.triggerNextPacket(s,a,r);if(n&&await(0,i.listenPacket)(e,n,this.invalidPacket),"string"!=typeof e&&c.parent&&c.variant)for(const t of o??[])await t({variant:c.variant,payload:e[0]});await this.triggerNextPacket(s,a,r),await this.callMiddleware("onReceive_post",t,"string"==typeof e?[e]:e[0])}isAsync(e){return this.asyncMap[e]}async enqueuePacket(e,t,s,a,r){await(0,i.listenPacket)(e,t,this.invalidPacket),await this.triggerNextPacket(s,a,r)}async triggerNextPacket(e,t,s){t?s[0]=!1:this.listenLock=!1,e.length>0&&this.dataHandler(e.shift())}async dataHandler(e){const t=e[0],s=e.slice(1),i=this.isAsync(t);let a,r,c;if(i?(c=this.asyncData[t],a=c[0],r=c[1]):(a=this.listenLock,r=this.packetQueue),a)return void r.push(e);i?c[0]=!0:this.listenLock=!0;const o=this.serverPackets.getTag(t),h=this.serverPackets.getPacket(o);if(await this.callMiddleware("onReceive_pre",h.tag,e,e.length))return;if(h.rereference&&0==s.length)return void 0===h.lastReceived[0]?this.invalidPacket("No previous value to rereference"):void this.listenPacket(h.lastReceived[0],o,r,i,c);if(0==h.dataBatching){const e=h.lastReceived[0]=await h.listen(s,null);return void this.listenPacket(e,o,r,i,c)}const l=await n.BatchHelper.unravelBatch(h,s,null);if("string"==typeof l)return this.invalidPacket(l);l.forEach(e=>this.listenPacket(e,o,r,i,c))}async messageHandler(e){const t=await this.bufferHandler(e);t.length<1||await this.dataHandler(t)}listen(e,t){if(!this.serverPackets.hasTag(e))return void console.log("Tag is not available on server: "+e);const s=this.serverPackets.resolveTag(e);(this.listeners[s]??=[]).push(t)}sendQueue=[!1,[],void 0];async send(e,...t){if(await this.callMiddleware("onSend_pre",e,t,Date.now(),performance.now()))return;const[s,a,r]=await(0,i.processPacket)(this.clientPackets,e,t,this.sendQueue,0);0==r.dataBatching?this.raw_send((0,c.toPacketBuffer)(s,a)):this.batcher.batchPacket(s,a),await this.callMiddleware("onSend_post",e,a,a.length)}sendVariant(e,t,...s){return this.send(this.clientPackets.getVariantTag(e,t),...s)}async sendSafe(e,...t){try{return await this.send(e,...t),!0}catch(t){return console.error(`Failed to send packet "${e}"`,t),!1}}on_ready(e){this.pastKeys?e():this.readyListeners.push(e)}on_close(e){this._on("close",e)}on(e,t){if(this.socket.readyState!==WebSocket.OPEN)return this.preListen[e]||(this.preListen[e]=[]),void this.preListen[e].push(t);this.listen(e,t)}}exports.SonicWSCore=l;
|
|
@@ -23,6 +23,15 @@ export declare class Packet<T extends (PacketType | readonly PacketType[])> {
|
|
|
23
23
|
readonly maxBatchSize: number;
|
|
24
24
|
readonly dontSpread: boolean;
|
|
25
25
|
readonly autoFlatten: boolean;
|
|
26
|
+
readonly fields?: readonly string[];
|
|
27
|
+
readonly quantized?: {
|
|
28
|
+
scale: number;
|
|
29
|
+
trackError?: boolean;
|
|
30
|
+
};
|
|
31
|
+
readonly valueMin?: number;
|
|
32
|
+
readonly valueMax?: number;
|
|
33
|
+
readonly parent?: string;
|
|
34
|
+
readonly variant?: string;
|
|
26
35
|
readonly rateLimit: number;
|
|
27
36
|
readonly async: boolean;
|
|
28
37
|
readonly rereference: boolean;
|
|
@@ -35,7 +44,16 @@ export declare class Packet<T extends (PacketType | readonly PacketType[])> {
|
|
|
35
44
|
customValidator: ((socket: SonicWSConnection, ...values: any[]) => boolean) | null;
|
|
36
45
|
lastReceived: Record<number, any>;
|
|
37
46
|
lastSent: Record<number, number | bigint>;
|
|
47
|
+
private quantizationErrors;
|
|
38
48
|
constructor(tag: string, schema: PacketSchema<T>, customValidator: ValidatorFunction, enabled: boolean, client: boolean);
|
|
49
|
+
private assertRecord;
|
|
50
|
+
private logical;
|
|
51
|
+
/** Converts ergonomic application values into the existing positional wire model. */
|
|
52
|
+
prepareSend(values: any[], stateKey?: number): any[];
|
|
53
|
+
/** Clears error-feedback state for a disconnected sender. */
|
|
54
|
+
clearQuantizationState(stateKey: number): void;
|
|
55
|
+
/** Converts decoded positional data into schema objects and application-level numbers. */
|
|
56
|
+
finishReceive(decoded: any): any;
|
|
39
57
|
listen(value: Uint8Array, socket: SonicWSConnection | null): Promise<[processed: any, flatten: boolean] | string>;
|
|
40
58
|
serialize(): number[];
|
|
41
59
|
private static readVarInts;
|
|
@@ -56,7 +74,17 @@ export declare class PacketSchema<T extends (PacketType | readonly PacketType[])
|
|
|
56
74
|
rereference: boolean;
|
|
57
75
|
gzipCompression: boolean;
|
|
58
76
|
object: boolean;
|
|
59
|
-
|
|
77
|
+
fields?: readonly string[];
|
|
78
|
+
quantized?: {
|
|
79
|
+
scale: number;
|
|
80
|
+
trackError?: boolean;
|
|
81
|
+
};
|
|
82
|
+
valueMin?: number;
|
|
83
|
+
valueMax?: number;
|
|
84
|
+
constructor(object: boolean, type: ImpactType<T, ArguableType>, async: boolean, dataMin: ImpactType<T, number>, dataMax: ImpactType<T, number>, rateLimit: number, dontSpread: boolean, autoFlatten: boolean, rereference: boolean, dataBatching: number, maxBatchSize: number, gzipCompression: boolean, fields?: readonly string[], quantized?: {
|
|
85
|
+
scale: number;
|
|
86
|
+
trackError?: boolean;
|
|
87
|
+
}, valueMin?: number, valueMax?: number);
|
|
60
88
|
testObject(packet: Packet<PacketType | readonly PacketType[]>): packet is Packet<PacketType[]>;
|
|
61
89
|
}
|
|
62
90
|
export {};
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* See LICENSE for personal, non-commercial license terms.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.PacketSchema=exports.Packet=void 0;const t=require("../util/enums/EnumHandler"),e=require("../util/enums/EnumType"),
|
|
7
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.PacketSchema=exports.Packet=void 0;const t=require("../util/enums/EnumHandler"),e=require("../util/enums/EnumType"),i=require("../util/packets/CompressionUtil"),a=require("../util/packets/PacketUtils"),s=require("./PacketType"),r=require("../util/StringUtil"),n=require("../../native/wrapper"),h=require("../util/packets/JSONUtil");class o{defaultEnabled;tag;maxSize;minSize;type;enumData;dataMax;dataMin;dataBatching;maxBatchSize;dontSpread;autoFlatten;fields;quantized;valueMin;valueMax;parent;variant;rateLimit;async;rereference;gzipCompression;object;client;processReceive;processSend;validate;customValidator;lastReceived={};lastSent={};quantizationErrors={};constructor(t,e,i,a,r){this.tag=t,this.defaultEnabled=a,this.client=r,this.async=e.async,this.enumData=e.enumData,this.rateLimit=e.rateLimit,this.dontSpread=e.dontSpread,this.autoFlatten=e.autoFlatten,this.rereference=e.rereference,this.dataBatching=e.dataBatching,this.maxBatchSize=r?1/0:e.maxBatchSize,this.gzipCompression=e.gzipCompression,this.fields=e.fields,this.quantized=e.quantized?{...e.quantized,trackError:e.quantized.trackError??!0}:void 0,this.valueMin=e.valueMin,this.valueMax=e.valueMax;const o=/^__(.+)\$([^$]+)$/.exec(t);if(this.parent=o?.[1],this.variant=o?.[2],this.object=e.object,this.type=e.type,this.dataMax=e.dataMax,this.dataMin=e.dataMin,e.testObject(this)){this.maxSize=this.minSize=this.type.length;for(let t=0;t<this.type.length;t++)this.type[t]==s.PacketType.NONE&&(this.dataMax[t]=this.dataMin[t]=0);const t={types:this.type,dataMins:this.dataMin,dataMaxes:this.dataMax,enumData:this.enumData};this.processReceive=e=>(0,n.decodeNativeObject)(t,e).map((t,e)=>this.type[e]===s.PacketType.JSON?(0,h.decompressJSON)(t):t),this.processSend=async e=>{let i=0;const a=e.map((t,e)=>{if(this.type[e]===s.PacketType.JSON)return(0,h.compressJSON)(t);if(this.type[e]!==s.PacketType.ENUMS)return t;const a=this.enumData[i++];return(Array.isArray(t)?t:[t]).map(t=>{if(!Number.isInteger(t)||t<0||t>=a.values.length)throw new Error(`Invalid wrapped enum index: ${t}`);return a.values[t]})});return(0,n.encodeNativeObject)(t,a)},this.validate=async e=>{(0,n.validateNativeObject)(t,e);return(0,n.decodeNativeObject)(t,e).forEach((t,e)=>{if(this.type[e]!==s.PacketType.JSON)return;const i=(0,h.decompressJSON)(t),a=Array.isArray(i)?i.length:1;if(a<this.dataMin[e]||a>this.dataMax[e])throw new Error("JSON value count is outside schema limits")}),[e,!0]}}else{{this.maxSize=this.dataMax,this.minSize=this.dataMin,this.type==s.PacketType.NONE&&(this.dataMax=this.dataMin=0);const t=this.enumData[0];this.processReceive=e=>this.type===s.PacketType.JSON?(0,h.decompressJSON)(e):(0,n.decodeNative)(this.type,e,this.dataMax,t),this.processSend=async e=>{let i;if(this.type===s.PacketType.JSON)i=(0,h.compressJSON)(e);else if(this.type===s.PacketType.ENUMS)i=Uint8Array.from(e);else{const a=this.type===s.PacketType.RAW&&1===e.length&&e[0]instanceof Uint8Array?e[0]:e;i=(0,n.encodeNative)(this.type,a,t)}return this.gzipCompression&&0===this.dataBatching?(0,n.deflateNative)(i):i},this.validate=async e=>{const i=this.gzipCompression&&0===this.dataBatching?(0,n.inflateNative)(e):e;if(this.type===s.PacketType.JSON){const t=(0,h.decompressJSON)(i),e=Array.isArray(t)?t.length:1;if(e<this.dataMin||e>this.dataMax)throw new Error("JSON value count is outside schema limits")}else(0,n.validateNative)(this.type,i,this.dataMin,this.dataMax,{enumData:t});return[i,!0]}}}this.customValidator=i}assertRecord(t,e){if(!this.fields)throw new Error(`Packet "${this.tag}" ${e} requires schema`);if(null===t||"object"!=typeof t||Array.isArray(t))throw new Error(`Packet "${this.tag}" ${e} requires an object record`);const i=this.fields.filter(e=>!Object.prototype.hasOwnProperty.call(t,e));if(i.length)throw new Error(`Packet "${this.tag}" is missing schema field(s): ${i.join(", ")}`);const a=Object.keys(t).filter(t=>!this.fields.includes(t));if(a.length)throw new Error(`Packet "${this.tag}" has unknown schema field(s): ${a.join(", ")}`);return this.fields.map(e=>t[e])}logical(t,e,i=-1){const a=this.quantized?.scale;return t.map(t=>{if("number"!=typeof t||!Number.isFinite(t))throw new Error(`Packet "${this.tag}" ${e} value must be a finite number`);const s="receive"===e&&a?t/a:t;if(void 0!==this.valueMin&&s<this.valueMin)throw new Error(`Packet "${this.tag}" value ${s} is below minimum ${this.valueMin}`);if(void 0!==this.valueMax&&s>this.valueMax)throw new Error(`Packet "${this.tag}" value ${s} exceeds maximum ${this.valueMax}`);if("send"===e&&a){const t=s*a+(this.quantized?.trackError?this.quantizationErrors[i]??0:0),e=Math.round(t);return this.quantized?.trackError&&(this.quantizationErrors[i]=t-e),e}return s})}prepareSend(t,e=-1){if(this.object){if(this.autoFlatten&&this.fields){if(1!==t.length||!Array.isArray(t[0]))throw new Error(`Packet "${this.tag}" autoTranspose requires one array of records`);const e=t[0].map(t=>this.assertRecord(t,"autoTranspose"));return this.fields.map((t,i)=>e.map(t=>t[i]))}return t}let i=t;if(this.autoFlatten){if(1!==t.length||!Array.isArray(t[0]))throw new Error(`Packet "${this.tag}" autoFlatten requires one array of records`);if(i=t[0].flatMap(t=>this.assertRecord(t,"autoFlatten")),this.fields&&i.length%this.fields.length!==0)throw new Error(`Packet "${this.tag}" flat value count must be divisible by schema length ${this.fields.length}`)}else this.fields&&1===t.length&&null!==t[0]&&"object"==typeof t[0]&&!Array.isArray(t[0])&&(i=this.assertRecord(t[0],"schema mapping"));return this.quantized||void 0!==this.valueMin||void 0!==this.valueMax?this.logical(i,"send",e):i}clearQuantizationState(t){delete this.quantizationErrors[t]}finishReceive(t){if(this.object){if(this.autoFlatten&&this.fields){const e=t,i=e[0]?.length??0;if(e.some(t=>t.length!==i))throw new Error(`Packet "${this.tag}" autoTranspose columns have different lengths`);return Array.from({length:i},(t,i)=>Object.fromEntries(this.fields.map((t,a)=>[t,e[a][i]])))}return this.autoFlatten?(0,a.UnFlattenData)(t):t}let e=Array.isArray(t)?t:[t];if((this.quantized||void 0!==this.valueMin||void 0!==this.valueMax)&&(e=this.logical(e,"receive")),this.autoFlatten){const t=this.fields.length;if(e.length%t!==0)throw new Error(`Packet "${this.tag}" flat value count ${e.length} is not divisible by schema length ${t}`);return Array.from({length:e.length/t},(i,a)=>Object.fromEntries(this.fields.map((i,s)=>[i,e[a*t+s]])))}return this.fields?Object.fromEntries(this.fields.map((t,i)=>[t,e[i]])):t}async listen(t,e){try{const[i,a]=await this.validate(t);if(!this.client&&!1===a)return"Invalid packet";const s=this.processReceive(i,a),r=this.finishReceive(s);if(null!=this.customValidator)if(this.dontSpread||this.fields){if(!this.customValidator(e,r))return"Didn't pass custom validator"}else if(!this.customValidator(e,...r))return"Didn't pass custom validator";return[r,!this.fields&&!this.dontSpread]}catch(t){return console.error("There was an error processing the packet! This is probably my fault... report at https://github.com/liwybloc/sonic-ws",t),"Error: "+t}}serialize(){const t=(new TextEncoder).encode(JSON.stringify({schema:this.fields,quantized:this.quantized,min:this.valueMin,max:this.valueMax})),e=[this.tag.length,...(0,r.processCharCodes)(this.tag),(0,i.compressBools)([this.dontSpread,this.async,this.object,this.autoFlatten,this.gzipCompression,this.rereference]),...(0,i.convertVarInt)(t.length),...t,this.dataBatching,this.enumData.length,...this.enumData.map(t=>t.serialize()).flat()];return this.object?[...e,this.maxSize,...this.dataMax.map(i.convertVarInt).flat(),...this.dataMin.map(i.convertVarInt).flat(),...this.type]:[...e,...(0,i.convertVarInt)(this.dataMax),...(0,i.convertVarInt)(this.dataMin),this.type]}static readVarInts(t,e,a){const s=[];for(let r=0;r<a;r++){const[a,r]=(0,i.readVarInt)(t,e);e=a,s.push(r)}return[s,e]}static deserialize(a,n,h){const c=n,d=a[n++],u=(0,r.as8String)(a.slice(n,n+=d)),[p,m,f,y,v,g]=(0,i.decompressBools)(a[n++]),[M,S]=(0,i.readVarInt)(a,n);n=M;const x=JSON.parse((new TextDecoder).decode(a.slice(n,n+=S))),w=a[n++],z=a[n++],k=[];for(let i=0;i<z;i++){const i=a[n++],s=(0,r.as8String)(a.slice(n,n+=i)),h=a[n++],o=[];for(let t=0;t<h;t++){const t=a[n++],i=a[n++],s=(0,r.as8String)(a.slice(n,n+=t));o.push(e.TYPE_CONVERSION_MAP[i](s))}k.push((0,t.DefineEnum)(s,o))}if(f){const t=a[n++],[e,i]=this.readVarInts(a,n,t);n=i;const[r,d]=this.readVarInts(a,n,t);n=d;const f=Array.from(a.slice(n,n+=t));let g=0;const M=f.map(t=>t==s.PacketType.ENUMS?k[g++]:t),S=new l(!0,M,m,r,e,-1,p,y,!1,w,-1,v,x.schema);return[new o(u,S,null,!1,h),n-c]}const[E,b]=(0,i.readVarInt)(a,n);n=E;const[N,P]=(0,i.readVarInt)(a,n);n=N;const O=a[n++],q=O==s.PacketType.ENUMS?k[0]:O,$=new l(!1,q,m,P,b,-1,p,y,g,w,-1,v,x.schema,x.quantized,x.min,x.max);return[new o(u,$,null,!1,h),n-c]}static deserializeAll(t,e){const i=[];let a=0;for(;a<t.length;){const[s,r]=this.deserialize(t,a,e);i.push(s),a+=r}return i}}exports.Packet=o;const c=(t,i)=>t instanceof e.EnumPackage?(i.push(t),s.PacketType.ENUMS):t;class l{type;enumData=[];dataMax;dataMin;dataBatching;maxBatchSize;rateLimit;dontSpread=!1;autoFlatten=!1;async=!1;rereference=!1;gzipCompression=!1;object;fields;quantized;valueMin;valueMax;constructor(t,e,i,a,s,r,n,h,o,l,d,u,p,m,f,y){this.object=t,this.async=i,this.dataMin=a,this.dataMax=s,this.rateLimit=r,this.dontSpread=n,this.autoFlatten=h,this.rereference=o,this.dataBatching=l,this.maxBatchSize=d,this.gzipCompression=u,this.fields=p?[...p]:void 0,this.quantized=m?{...m}:void 0,this.valueMin=f,this.valueMax=y,this.type=t?e.map(t=>c(t,this.enumData)):c(e,this.enumData)}testObject(t){return this.object}}exports.PacketSchema=l;
|
|
@@ -61,6 +61,8 @@ export declare class SonicWSConnection extends Connection<WS.WebSocket, Buffer>
|
|
|
61
61
|
* @param values The values to send
|
|
62
62
|
*/
|
|
63
63
|
send(tag: string, ...values: any[]): Promise<void>;
|
|
64
|
+
sendVariant(parent: string, variant: string, ...values: any[]): Promise<void>;
|
|
65
|
+
sendSafe(tag: string, ...values: any[]): Promise<boolean>;
|
|
64
66
|
/**
|
|
65
67
|
* Broadcasts a packet to all other users connected
|
|
66
68
|
* @param tag The tag to send
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* See LICENSE for personal, non-commercial license terms.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.SonicWSConnection=void 0;const e=require("../util/packets/PacketUtils"),t=require("../util/packets/BatchHelper"),s=require("../util/packets/RateHandler"),a=require("../util/BufferUtil"),i=require("../Connection");class n extends i.Connection{host;print=!1;handshakePacket;handshakeLambda;messageLambda=e=>this.messageHandler(this.parseData(e));handshakedMessageLambda=e=>{const t=this.parseData(e);return null==t?this.socket.close(i.CloseCodes.INVALID_DATA):t[0]==this.handshakePacket?this.socket.close(i.CloseCodes.REPEATED_HANDSHAKE):void this.messageHandler(t)};rater;enabledPackets={};handshakeComplete=!1;asyncMap={};asyncData={};constructor(e,t,a,i,n,r){super(e,a,"Socket "+a,e.addEventListener.bind(e),e.removeEventListener.bind(e)),this.host=t,this.handshakePacket=i;for(const e of t.clientPackets.getPackets()){const t=e.tag;this.listeners[t]=[],e.lastReceived[this.id]=void 0,this.enabledPackets[t]=e.defaultEnabled,this.asyncMap[t]=e.async,e.async&&(this.asyncData[t]=[!1,[]])}this.setInterval=this.setInterval.bind(this),this.batcher.registerSendPackets(this.host.serverPackets,this),this.invalidPacket=this.invalidPacket.bind(this),this.rater=new s.RateHandler(this),this.rater.registerRate("C",n),this.rater.registerRate("S",r),this.rater.registerAll(t.clientPackets,"client"),this.rater.registerAll(t.serverPackets,"server"),this.rater.start(),null==this.handshakePacket?this.socket.addEventListener("message",this.messageLambda):(this.handshakeLambda=e=>this.handshakeHandler(e),this.socket.addEventListener("message",this.handshakeLambda)),this.socket.on("close",()=>{for(const e of t.clientPackets.getPackets())delete e.lastReceived[this.id];for(const e of t.serverPackets.getPackets())delete e.lastSent[this.id]})}parseData(e){if(this.rater.trigger("C"))return null;if(!(e.data instanceof Buffer))return null;const t=new Uint8Array(e.data);if(this.print&&console.log(`[31m⬇ [38;5;245m(${this.id},${t.byteLength})[0m`,t.length>0&&this.host.clientPackets.getTag(t[0])||"<INVALID>",(0,a.stringifyBuffer)(t)),t.byteLength<1)return this.socket.close(i.CloseCodes.SMALL),null;const s=t[0],n=t.slice(1);if(!this.host.clientPackets.hasKey(s))return this.socket.close(i.CloseCodes.INVALID_KEY),null;const r=this.host.clientPackets.getTag(s);return this.enabledPackets[r]?this.rater.trigger("client"+s)?null:[r,n]:(this.socket.close(i.CloseCodes.DISABLED_PACKET),null)}handshakeHandler(e){const t=this.parseData(e);if(null==t)return this.socket.close(i.CloseCodes.INVALID_DATA);t[0]==this.handshakePacket?(this.messageHandler(t),this.socket.removeEventListener("message",this.handshakeLambda),this.socket.addEventListener("message",this.handshakedMessageLambda),this.handshakeComplete=!0):this.socket.close(i.CloseCodes.INVALID_DATA)}invalidPacket(e){console.log("Closure cause",e),this.socket.close(i.CloseCodes.INVALID_PACKET,e)}isAsync(e){return this.asyncMap[e]}listenLock=!1;packetQueue=[];async listenPacket(t,s,a,i,n){this.closed
|
|
7
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.SonicWSConnection=void 0;const e=require("../util/packets/PacketUtils"),t=require("../util/packets/BatchHelper"),s=require("../util/packets/RateHandler"),a=require("../util/BufferUtil"),i=require("../Connection");class n extends i.Connection{host;print=!1;handshakePacket;handshakeLambda;messageLambda=e=>this.messageHandler(this.parseData(e));handshakedMessageLambda=e=>{const t=this.parseData(e);return null==t?this.socket.close(i.CloseCodes.INVALID_DATA):t[0]==this.handshakePacket?this.socket.close(i.CloseCodes.REPEATED_HANDSHAKE):void this.messageHandler(t)};rater;enabledPackets={};handshakeComplete=!1;asyncMap={};asyncData={};constructor(e,t,a,i,n,r){super(e,a,"Socket "+a,e.addEventListener.bind(e),e.removeEventListener.bind(e)),this.host=t,this.handshakePacket=i;for(const e of t.clientPackets.getPackets()){const t=e.tag;this.listeners[t]=[],e.lastReceived[this.id]=void 0,this.enabledPackets[t]=e.defaultEnabled,this.asyncMap[t]=e.async,e.async&&(this.asyncData[t]=[!1,[]])}this.setInterval=this.setInterval.bind(this),this.batcher.registerSendPackets(this.host.serverPackets,this),this.invalidPacket=this.invalidPacket.bind(this),this.rater=new s.RateHandler(this),this.rater.registerRate("C",n),this.rater.registerRate("S",r),this.rater.registerAll(t.clientPackets,"client"),this.rater.registerAll(t.serverPackets,"server"),this.rater.start(),null==this.handshakePacket?this.socket.addEventListener("message",this.messageLambda):(this.handshakeLambda=e=>this.handshakeHandler(e),this.socket.addEventListener("message",this.handshakeLambda)),this.socket.on("close",()=>{for(const e of t.clientPackets.getPackets())delete e.lastReceived[this.id];for(const e of t.serverPackets.getPackets())delete e.lastSent[this.id],e.clearQuantizationState(this.id)})}parseData(e){if(this.rater.trigger("C"))return null;if(!(e.data instanceof Buffer))return null;const t=new Uint8Array(e.data);if(this.print&&console.log(`[31m⬇ [38;5;245m(${this.id},${t.byteLength})[0m`,t.length>0&&this.host.clientPackets.getTag(t[0])||"<INVALID>",(0,a.stringifyBuffer)(t)),t.byteLength<1)return this.socket.close(i.CloseCodes.SMALL),null;const s=t[0],n=t.slice(1);if(!this.host.clientPackets.hasKey(s))return this.socket.close(i.CloseCodes.INVALID_KEY),null;const r=this.host.clientPackets.getTag(s);return this.enabledPackets[r]?this.rater.trigger("client"+s)?null:[r,n]:(this.socket.close(i.CloseCodes.DISABLED_PACKET),null)}handshakeHandler(e){const t=this.parseData(e);if(null==t)return this.socket.close(i.CloseCodes.INVALID_DATA);t[0]==this.handshakePacket?(this.messageHandler(t),this.socket.removeEventListener("message",this.handshakeLambda),this.socket.addEventListener("message",this.handshakedMessageLambda),this.handshakeComplete=!0):this.socket.close(i.CloseCodes.INVALID_DATA)}invalidPacket(e){console.log("Closure cause",e),this.socket.close(i.CloseCodes.INVALID_PACKET,e)}isAsync(e){return this.asyncMap[e]}listenLock=!1;packetQueue=[];async listenPacket(t,s,a,i,n){if(this.closed)return;await(0,e.listenPacket)(t,this.listeners[s],this.invalidPacket);const r=this.host.clientPackets.getPacket(s);if("string"!=typeof t&&r.parent&&r.variant)for(const e of this.listeners[r.parent]??[])await e({variant:r.variant,payload:t[0]});await this.callMiddleware("onReceive_post",s,"string"==typeof t?[t]:t[0]),i?n[0]=!1:this.listenLock=!1,0==a.length||this.messageHandler(a.shift())}async messageHandler(e,s=!1){if(null==e)return;const[a,i]=e,n=this.isAsync(a);let r,h,c;if(n?(c=this.asyncData[a],r=c[0],h=c[1]):(r=this.listenLock,h=this.packetQueue),r)return void h.push(e);n?c[0]=!0:this.listenLock=!0;const o=this.host.clientPackets.getPacket(a);if(!s&&await this.callMiddleware("onReceive_pre",o.tag,i,i.length))return;if(o.rereference&&0==i.length){const e=o.lastReceived[this.id];return void 0===e?this.invalidPacket("No previous value to rereference"):void await this.listenPacket(e,a,h,n,c)}if(0==o.dataBatching){const e=await o.listen(i,this);return o.lastReceived[this.id]=e,void await this.listenPacket(e,a,h,n,c)}const l=await t.BatchHelper.unravelBatch(o,i,this);if("string"==typeof l)return this.invalidPacket(l);for(const e of l)n?c[0]=!0:this.listenLock=!0,await this.listenPacket(e,a,h,n,c)}enablePacket(e){this.enabledPackets[e]=!0}disablePacket(e){this.enabledPackets[e]=!1}on_close(e){this.socket.on("close",(t,s)=>e(t,String(s)))}on(e,t){if(!this.host.clientPackets.hasTag(e))throw new Error(`Tag "${String(e)}" has not been created!`);const s=this.host.clientPackets.resolveTag(e);this.listeners[s]??=[],this.listeners[s].push(t)}send_processed(e,t,s){this.rater.trigger("server"+e)||(0==s.dataBatching?this.raw_send((0,a.toPacketBuffer)(e,t)):this.batcher.batchPacket(e,t))}sendQueue=[!1,[],void 0];async send(t,...s){if(await this.callMiddleware("onSend_pre",t,s,Date.now(),performance.now()))return;const[a,i,n]=await(0,e.processPacket)(this.host.serverPackets,t,s,this.sendQueue,this.id);await this.callMiddleware("onSend_post",t,i,i.length)||this.send_processed(a,i,n)}sendVariant(e,t,...s){return this.send(this.host.serverPackets.getVariantTag(e,t),...s)}async sendSafe(e,...t){try{return await this.send(e,...t),!0}catch(t){return this.host.handleSendError(t,{packetTag:e,connection:this}),!1}}broadcastFiltered(e,t,...s){this.host.broadcastFiltered(e,e=>e!=this&&t(e),...s)}broadcast(e,...t){this.broadcastFiltered(e,()=>!0,...t)}togglePrint(){this.print=!this.print}raw_send(e){this.isClosed()?console.warn("WARN! Connection already closed when trying to send message!",this.id,(0,a.stringifyBuffer)(e)):this.rater.trigger("S")||(this.print&&console.log(`[32m⬆ [38;5;245m(${this.id},${e.byteLength})[0m`,e.length>0&&this.host.serverPackets.getTag(e[0])||"<INVALID>",(0,a.stringifyBuffer)(e)),super.raw_send(e))}tag(e,t=!0){this.host.tag(this,e,t)}}exports.SonicWSConnection=n;
|
|
@@ -28,6 +28,11 @@ export type SonicServerOptions = {
|
|
|
28
28
|
/** Default WS Options */
|
|
29
29
|
readonly websocketOptions?: WS.ServerOptions;
|
|
30
30
|
readonly sonicServerSettings?: SonicServerSettings;
|
|
31
|
+
readonly onSendError?: (error: unknown, context: {
|
|
32
|
+
packetTag: string;
|
|
33
|
+
connection?: SonicWSConnection;
|
|
34
|
+
operation?: "broadcast";
|
|
35
|
+
}) => void;
|
|
31
36
|
};
|
|
32
37
|
export type PacketTypings = readonly Packet<PacketType | readonly PacketType[]>[];
|
|
33
38
|
export declare class SonicWSServer extends MiddlewareHolder<ServerMiddleware> {
|
|
@@ -45,6 +50,7 @@ export declare class SonicWSServer extends MiddlewareHolder<ServerMiddleware> {
|
|
|
45
50
|
tags: Map<SonicWSConnection, Set<String>>;
|
|
46
51
|
tagsInv: Map<String, Set<SonicWSConnection>>;
|
|
47
52
|
private serverwideSendQueue;
|
|
53
|
+
private readonly sendErrorHandler?;
|
|
48
54
|
/**
|
|
49
55
|
* Initializes and hosts a websocket with sonic protocol
|
|
50
56
|
* Rate limits can be set with wss.setClientRateLimit(x) and wss.setServerRateLimit(x); it is defaulted at 500/second per both
|
|
@@ -113,6 +119,13 @@ export declare class SonicWSServer extends MiddlewareHolder<ServerMiddleware> {
|
|
|
113
119
|
broadcastTagged(tag: string, packetTag: string, ...values: any): Promise<void>;
|
|
114
120
|
broadcastFiltered(tag: string, filter: (socket: SonicWSConnection) => boolean, ...values: any): Promise<void>;
|
|
115
121
|
broadcast(tag: string, ...values: any): Promise<void>;
|
|
122
|
+
broadcastSafe(tag: string, ...values: any[]): Promise<boolean>;
|
|
123
|
+
broadcastVariant(parent: string, variant: string, ...values: any[]): Promise<void>;
|
|
124
|
+
handleSendError(error: unknown, context: {
|
|
125
|
+
packetTag: string;
|
|
126
|
+
connection?: SonicWSConnection;
|
|
127
|
+
operation?: "broadcast";
|
|
128
|
+
}): void;
|
|
116
129
|
/**
|
|
117
130
|
* @returns All users connected to the socket
|
|
118
131
|
*/
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* See LICENSE for personal, non-commercial license terms.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
var e,t=this&&this.__createBinding||(Object.create?function(e,t,s,n){void 0===n&&(n=s);var
|
|
7
|
+
var e,t=this&&this.__createBinding||(Object.create?function(e,t,s,n){void 0===n&&(n=s);var r=Object.getOwnPropertyDescriptor(t,s);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[s]}}),Object.defineProperty(e,n,r)}:function(e,t,s,n){void 0===n&&(n=s),e[n]=t[s]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var s in e)Object.prototype.hasOwnProperty.call(e,s)&&(t[t.length]=s);return t},e(t)},function(n){if(n&&n.__esModule)return n;var r={};if(null!=n)for(var a=e(n),i=0;i<a.length;i++)"default"!==a[i]&&t(r,n,a[i]);return s(r,n),r});Object.defineProperty(exports,"__esModule",{value:!0}),exports.SonicWSServer=void 0;const r=n(require("ws")),a=require("node:fs/promises"),i=require("node:path"),o=require("./SonicWSConnection"),c=require("../util/packets/PacketHolder"),l=require("../util/packets/CompressionUtil"),d=require("../../native/wrapper"),h=require("../../version"),u=require("../util/packets/PacketUtils"),g=require("../PacketProcessor"),p=require("../util/packets/HashUtil"),b=require("../Connection"),w=require("../debug/DebugServer"),v=e=>{if(!Number.isFinite(e)||e<0)throw new Error("Rate limit must be a non-negative finite number.");return(e=Math.floor(e))>l.MAX_USHORT?(console.warn(`A rate limit above ${l.MAX_USHORT} is considered infinite.`),0):e};class f extends g.MiddlewareHolder{wss;availableIds=[];lastId=0;connectListeners=[];clientPackets;serverPackets;connections=[];connectionMap={};clientRateLimit=500;serverRateLimit=500;handshakePacket=null;tags=new Map;tagsInv=new Map;serverwideSendQueue=[!1,[],void 0];sendErrorHandler;constructor(e){super();const{clientPackets:t=[],serverPackets:s=[],websocketOptions:n={}}=e;if(this.sendErrorHandler=e.onSendError,this.wss=new r.WebSocketServer(n),e.sonicServerSettings?.serveBrowserClient??1){const e=n.server??this.wss._server;e&&this.installBrowserAssetRoutes(e)}this.clientPackets=new c.PacketHolder(t),this.serverPackets=new c.PacketHolder(s);const a=this.clientPackets.serialize(),i=this.serverPackets.serialize(),u=[...h.SERVER_SUFFIX_NUMS,h.VERSION],g=[...(0,l.convertVarInt)(a.length),...a,...i];(0,p.setHashFunc)(e.sonicServerSettings?.bit64Hash??!0),this.wss.on("connection",async e=>{const t=new o.SonicWSConnection(e,this,this.generateSocketID(),this.handshakePacket,this.clientRateLimit,this.serverRateLimit);if(await this.callMiddleware("onClientConnect",t))return t.close(b.CloseCodes.MIDDLEWARE,"Connection blocked by middleware."),this.callMiddleware("onClientDisconnect",t,b.CloseCodes.MIDDLEWARE,Buffer.from("Connection blocked by middleware.")),void this.availableIds.push(t.id);const s=new Uint8Array([...(0,l.convertVarInt)(t.id),...g]);e.send([...u,...(0,d.deflateNative)(s)]),this.connections.push(t),this.connectionMap[t.id]=t,this.connectListeners.forEach(e=>e(t)),e.on("close",(e,s)=>{if(this.connections.splice(this.connections.indexOf(t),1),delete this.connectionMap[t.id],this.availableIds.push(t.id),this.tags.has(t)){for(const e of this.tags.get(t))this.tagsInv.get(e)?.delete(t);this.tags.delete(t)}this.callMiddleware("onClientDisconnect",t,e,s)})}),(e.sonicServerSettings?.checkForUpdates??1)&&fetch("https://raw.githubusercontent.com/liwybloc/sonic-ws/refs/heads/main/release/version").then(e=>e.text()).then(e=>{parseInt(e)>h.VERSION&&console.warn(`SonicWS is currently running outdated! (current: ${h.VERSION}, latest: ${e}) Update with "npm update sonic-ws"`)}).catch(e=>{console.error(e),console.warn("Could not check SonicWS version.")})}installBrowserAssetRoutes(e){const t=e.listeners("request");e.removeAllListeners("request"),e.on("request",(s,n)=>{const r=new URL(s.url??"/","http://localhost").pathname,o="/SonicWS/bundle.js"===r?["bundle.js","text/javascript; charset=utf-8"]:"/SonicWS/bundle.wasm"===r?["bundle.wasm","application/wasm"]:void 0;if(!o){for(const r of t)Reflect.apply(r,e,[s,n]);return}const c=(0,i.resolve)(__dirname,"../../../bundled",o[0]);(0,a.readFile)(c).then(e=>{n.writeHead(200,{"content-type":o[1],"content-length":e.byteLength,"cache-control":"public, max-age=3600"}),n.end(e)}).catch(e=>{n.writeHead(500,{"content-type":"text/plain; charset=utf-8"}),n.end(`Unable to load SonicWS browser asset: ${e instanceof Error?e.message:String(e)}`)})})}generateSocketID(){return 0==this.availableIds.length&&this.availableIds.push(this.lastId+1),this.lastId=this.availableIds.shift(),this.lastId}requireHandshake(e){if(!this.clientPackets.hasTag(e))throw new Error(`The client does not send "${e}" and so it cannot use it as a handshake!`);if(0!=this.clientPackets.getPacket(e).dataBatching)throw new Error(`The packet "${e}" is a batched packet, and cannot be used as a handshake!`);this.handshakePacket=e}setClientRateLimit(e){this.clientRateLimit=v(e)}setServerRateLimit(e){this.serverRateLimit=v(e)}enablePacket(e){this.clientPackets.getPacket(e).defaultEnabled=!0,this.connections.forEach(t=>t.enablePacket(e))}disablePacket(e){this.clientPackets.getPacket(e).defaultEnabled=!1,this.connections.forEach(t=>t.disablePacket(e))}on_connect(e){this.connectListeners.push(e)}on_ready(e){this.wss.on("listening",e)}shutdown(e){this.wss.close(e)}async broadcastInternal(e,t,s){let n;if("all"===t.type)n=this.connections;else if("tagged"===t.type){if(!this.tagsInv.has(t.tag))return;n=Array.from(this.tagsInv.get(t.tag))}else n=this.connections.filter(t.filter);if(await this.callMiddleware("onPacketBroadcast_pre",e,{recipients:n,...t},s))return;if(0===n.length)return;const[r,a,i]=await(0,u.processPacket)(this.serverPackets,e,s,this.serverwideSendQueue,-1);await this.callMiddleware("onPacketBroadcast_post",e,{recipients:n,...t},a,a.length)||n.forEach(e=>e.send_processed(r,a,i))}async broadcastTagged(e,t,...s){await this.broadcastInternal(t,{type:"tagged",tag:e},s)}async broadcastFiltered(e,t,...s){await this.broadcastInternal(e,{type:"filter",filter:t},s)}async broadcast(e,...t){await this.broadcastInternal(e,{type:"all"},t)}async broadcastSafe(e,...t){try{return await this.broadcast(e,...t),!0}catch(t){return this.handleSendError(t,{packetTag:e,operation:"broadcast"}),!1}}broadcastVariant(e,t,...s){return this.broadcast(this.serverPackets.getVariantTag(e,t),...s)}handleSendError(e,t){this.sendErrorHandler?this.sendErrorHandler(e,t):console.error(`Failed to send packet "${t.packetTag}"`,e)}getConnected(){return this.connections}getSocket(e){return this.connectionMap[e]}closeSocket(e,t=1e3,s){this.getSocket(e).close(t,s)}tag(e,t,s=!0){this.tags.get(e)||this.tags.set(e,new Set),this.tagsInv.get(t)||this.tagsInv.set(t,new Set),s&&this.tags.get(e).forEach(t=>this.tagsInv.get(t)?.delete(e)),this.tags.get(e).add(t),this.tagsInv.get(t).add(e)}debugServer=null;OpenDebug(e={}){if(null!=this.debugServer)throw new Error("Attempted to open a debug server when one has already been opened.");this.debugServer=new w.DebugServer(this,e)}}exports.SonicWSServer=f;
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* See LICENSE for personal, non-commercial license terms.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.BatchHelper=void 0;const t=require("../BufferUtil"),e=require("../../../native/wrapper");exports.BatchHelper=class{batchInfo={};batchTimeouts={};batchedData={};conn;registerSendPackets(t,e){this.conn=e,t.getTags().forEach(e=>{const a=t.getPacket(e);if(0==a.dataBatching)return;const c=t.getKey(e);this.initiateBatch(c,a.dataBatching,a.gzipCompression)})}initiateBatch(t,e,a){this.batchedData[t]=[],this.batchInfo[t]=[e,a]}startBatch(a){const[c,s]=this.batchInfo[a];this.batchTimeouts[a]=this.conn.setInterval(()=>{if(0==this.batchedData[a].length)return;const c=(0,e.encodeNativeBatch)(this.batchedData[a],s);this.conn.raw_send((0,t.toPacketBuffer)(a,c)),this.batchedData[a]=[],delete this.batchTimeouts[a]},c)}batchPacket(t,e){this.batchedData[t].push(e),this.batchTimeouts[t]||this.startBatch(t)}static async unravelBatch(t,a,c){let s;try{s=(0,e.decodeNativeBatch)(a,t.gzipCompression,t.maxBatchSize)}catch(t){return"Invalid batch: "+t}const i=[];for(const e of s){const a=await t.listen(e,c);if("string"==typeof a)return"Batched packet: "+a;i.push(
|
|
7
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.BatchHelper=void 0;const t=require("../BufferUtil"),e=require("../../../native/wrapper");exports.BatchHelper=class{batchInfo={};batchTimeouts={};batchedData={};conn;registerSendPackets(t,e){this.conn=e,t.getTags().forEach(e=>{const a=t.getPacket(e);if(0==a.dataBatching)return;const c=t.getKey(e);this.initiateBatch(c,a.dataBatching,a.gzipCompression)})}initiateBatch(t,e,a){this.batchedData[t]=[],this.batchInfo[t]=[e,a]}startBatch(a){const[c,s]=this.batchInfo[a];this.batchTimeouts[a]=this.conn.setInterval(()=>{if(0==this.batchedData[a].length)return;const c=(0,e.encodeNativeBatch)(this.batchedData[a],s);this.conn.raw_send((0,t.toPacketBuffer)(a,c)),this.batchedData[a]=[],delete this.batchTimeouts[a]},c)}batchPacket(t,e){this.batchedData[t].push(e),this.batchTimeouts[t]||this.startBatch(t)}static async unravelBatch(t,a,c){let s;try{s=(0,e.decodeNativeBatch)(a,t.gzipCompression,t.maxBatchSize)}catch(t){return"Invalid batch: "+t}const i=[];for(const e of s){const a=await t.listen(e,c);if("string"==typeof a)return"Batched packet: "+a;i.push(a)}return i}};
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* See LICENSE for personal, non-commercial license terms.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.PacketHolder=void 0;exports.PacketHolder=class{key;keys;tags;packetMap;packets;constructor(t){this.key=1,this.keys={},this.tags={},this.packetMap={},t&&this.holdPackets(t)}createKey(t){this.keys[t]=this.key,this.tags[this.key]=t,this.key++}holdPackets(t){this.packets=t;for(const e of t)this.createKey(e.tag),this.packetMap[e.tag]=e}getKey(t){if(!(t
|
|
7
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.PacketHolder=void 0;exports.PacketHolder=class{key;keys;tags;packetMap;packets;variants={};parents=new Set;constructor(t){this.key=1,this.keys={},this.tags={},this.packetMap={},t&&this.holdPackets(t)}createKey(t){this.keys[t]=this.key,this.tags[this.key]=t,this.key++}holdPackets(t){this.packets=t;for(const e of t)this.createKey(e.tag),this.packetMap[e.tag]=e,e.parent&&e.variant&&(this.variants[`${e.parent}.${e.variant}`]=e.tag,this.parents.add(e.parent))}getKey(t){if(!((t=this.resolveTag(t))in this.keys))throw new Error(`Not a valid tag: ${t}`);return this.keys[t]}getTag(t){if(t in this.tags)return this.tags[t]}getPacket(t){if(!((t=this.resolveTag(t))in this.packetMap))throw new Error("Unknown packet tag: "+t);return this.packetMap[t]}hasKey(t){return t in this.tags}hasTag(t){return this.resolveTag(t)in this.keys||this.parents.has(t)}resolveTag(t){return this.variants[t]??t}getVariantTag(t,e){const s=this.variants[`${t}.${e}`];if(!s)throw new Error(`Unknown packet variant: ${t}.${e}`);return s}getKeys(){return this.keys}getTagMap(){return this.tags}getTags(){return Object.values(this.tags)}getPackets(){return this.packets}serialize(){return this.packets.map(t=>t.serialize()).flat()}};
|
|
@@ -52,6 +52,19 @@ export type SinglePacketSettings = SharedPacketSettings & {
|
|
|
52
52
|
dataMin?: number;
|
|
53
53
|
/** If this is true, it will save the last received of this value, and if no data is sent, it'll re-use the previous value. This is not compatible with dataMin: 0. Defaults to false. */
|
|
54
54
|
rereference?: boolean;
|
|
55
|
+
/** Field names used to map positional values to and from an object. */
|
|
56
|
+
schema?: readonly string[];
|
|
57
|
+
/** Treat one array of records as fixed-width row-major data. Requires schema. */
|
|
58
|
+
autoFlatten?: boolean;
|
|
59
|
+
/** Packet-level numeric quantization. trackError defaults to true and enables per-connection error feedback. */
|
|
60
|
+
quantized?: {
|
|
61
|
+
scale: number;
|
|
62
|
+
trackError?: boolean;
|
|
63
|
+
};
|
|
64
|
+
/** Inclusive application-level numeric minimum. */
|
|
65
|
+
min?: number;
|
|
66
|
+
/** Inclusive application-level numeric maximum. */
|
|
67
|
+
max?: number;
|
|
55
68
|
};
|
|
56
69
|
/** Settings for multi-typed packets */
|
|
57
70
|
export type MultiPacketSettings = SharedPacketSettings & {
|
|
@@ -63,6 +76,14 @@ export type MultiPacketSettings = SharedPacketSettings & {
|
|
|
63
76
|
dataMins?: number[] | number;
|
|
64
77
|
/** Will automatically run FlattenData() and UnFlattenData() on values; this will optimize [[x,y,z],[x,y,z]...] for wire transfer */
|
|
65
78
|
autoFlatten?: boolean;
|
|
79
|
+
/** Field names for records transposed into object-packet columns. */
|
|
80
|
+
schema?: readonly string[];
|
|
81
|
+
/** Column-major repeated-record mapping. autoFlatten remains a deprecated alias. */
|
|
82
|
+
autoTranspose?: boolean;
|
|
83
|
+
};
|
|
84
|
+
export type PacketGroupSettings = {
|
|
85
|
+
tag: string;
|
|
86
|
+
variants: Record<string, Omit<SinglePacketSettings, "tag">>;
|
|
66
87
|
};
|
|
67
88
|
/** Settings for single-typed enum packets */
|
|
68
89
|
export type EnumPacketSettings = SharedPacketSettings & {
|
|
@@ -99,6 +120,8 @@ export declare function CreateObjPacket<T extends readonly ArguableType[], V ext
|
|
|
99
120
|
}>(settings: MultiPacketSettings & {
|
|
100
121
|
readonly types: T;
|
|
101
122
|
}): Packet<V>;
|
|
123
|
+
/** Creates normal child packets for a tagged variant group. Spread the result into a packet list. */
|
|
124
|
+
export declare function CreatePacketGroup(settings: PacketGroupSettings): Packet<any>[];
|
|
102
125
|
/**
|
|
103
126
|
* Creates and defines an enum packet. This can be used to create an enum-based packet
|
|
104
127
|
* with a specific tag and possible values.
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* See LICENSE for personal, non-commercial license terms.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.processPacket=o,exports.listenPacket=async function(e,t,a){if("string"==typeof e)return a(e);const[n,r]=e;try{if(r&&Array.isArray(n))for(const e of t)await e(...n);else for(const e of t)await e(n)}catch(e){console.error(e),a(e)}},exports.CreatePacket=f,exports.CreateObjPacket=function(a){let{tag:n,types:r=[],dataMaxes:o,dataMins:f,noDataRange:
|
|
7
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.processPacket=o,exports.listenPacket=async function(e,t,a){if("string"==typeof e)return a(e);const[n,r]=e;try{if(r&&Array.isArray(n))for(const e of t)await e(...n);else for(const e of t)await e(n)}catch(e){console.error(e),a(e)}},exports.CreatePacket=f,exports.CreateObjPacket=function(a){let{tag:n,types:r=[],dataMaxes:o,dataMins:f,noDataRange:p=!1,dontSpread:m=!1,autoFlatten:w=!1,autoTranspose:d,schema:y,validator:g=null,dataBatching:k=0,maxBatchSize:P=10,rateLimit:E=0,enabled:T=!0,async:S=!1,gzipCompression:$=r&&r.includes(t.PacketType.JSON)}=a;if(!n)throw new Error("Tag not selected!");if(!r||0==r.length)throw new Error("Types is set to 0 length");if(h(y,n),y&&y.length!==r.length)throw new Error(`Packet "${n}" schema length must match types length`);if(void 0!==d&&w&&d!==w)throw new Error(`Packet "${n}" has conflicting autoFlatten and autoTranspose options`);const v=d??w;for(const e of r)if(i(e))throw new Error(`Invalid packet type in "${n}" packet: ${e}`);p?(o=Array.from({length:r.length}).map(()=>c),f=Array.from({length:r.length}).map(()=>0)):(null==o?o=Array.from({length:r.length}).map(()=>1):Array.isArray(o)||(o=Array.from({length:r.length}).map(()=>o)),null==f?f=Array.from({length:r.length}).map((e,t)=>o[t]):Array.isArray(f)||(f=Array.from({length:r.length}).map(()=>f)));const x=o.map(s),b=f.map((e,a)=>r[a]==t.PacketType.NONE?0:l(e,x[a])),A=new e.PacketSchema(!0,r,S,b,x,u(E),m,v,!1,k,P,$,y);return new e.Packet(n,A,g,T,!1)},exports.CreatePacketGroup=function(e){if(!e.tag||e.tag.includes("$"))throw new Error("Packet group tag is required and cannot contain '$'");const t=Object.entries(e.variants);if(!t.length)throw new Error(`Packet group "${e.tag}" requires at least one variant`);return t.map(([t,a])=>{if(!t||t.includes("$"))throw new Error("Packet variant names cannot be empty or contain '$'");return f({...a,tag:`__${e.tag}$${t}`})})},exports.CreateEnumPacket=function(e){const{tag:t,enumData:a,dataMax:n=1,dataMin:r=0,noDataRange:o=!1,dontSpread:i=!1,validator:c=null,dataBatching:s=0,maxBatchSize:l=10,rateLimit:u=0,enabled:h=!0,async:p=!1}=e;return f({tag:t,type:a,dataMax:n,dataMin:r,noDataRange:o,dontSpread:i,validator:c,dataBatching:s,maxBatchSize:l,rateLimit:u,enabled:h,async:p})},exports.CreateKeyEffective=function(e){const{tag:t,count:a=2,validator:n=null,async:r=!1}=e;if(!t)throw new Error("Tag not selected!");if(a<2)throw new Error("Must have at least 2 key consumptions on key effective packet!");throw new Error("Currently W.I.P.")},exports.FlattenData=m,exports.UnFlattenData=function(e){return e[0]?.map((t,a)=>e.map(e=>e[a]))??[]};const e=require("../../packets/Packets"),t=require("../../packets/PacketType"),a=require("../enums/EnumType"),n=require("./CompressionUtil"),r=require("./HashUtil");async function o(e,a,i,c,s,l=!1){const u=e.getKey(a),f=e.getPacket(a);return async function(e,t,a,n,r,i,c){if(e[0]&&!i)return new Promise(t=>e[1].push([t,n,r]));e[0]=!0;const s=await c();if(e[1].length>0){const[n,r,i]=e[1].shift();queueMicrotask(async()=>{n(await o(t,r,i,e,a,!0))})}else e[0]=!1;return s}(c,e,s,a,i,l,async()=>{if(f.rereference){if(-1===s)throw new Error("Cannot send a re-referenced packet from the server-wide sender!");const e=(0,r.hashValue)(i);if(f.lastSent[s]===e)return[u,n.EMPTY_UINT8,f];f.lastSent[s]=e}if(i=f.prepareSend(i,s),f.autoFlatten&&f.object&&!f.fields)i=m(i[0]);else{if(i.length>f.maxSize)throw new Error(`Packet "${a}" only allows ${f.maxSize} values!`);if(i.length<f.minSize)throw new Error(`Packet "${a}" requires at least ${f.minSize} values!`)}if(f.object){if(i=i.map(e=>Array.isArray(e)?e:[e]),!f.autoFlatten){const e=f.dataMin,t=f.dataMax;for(let n=0;n<e.length;n++){if(i[n].length<e[n])throw new Error(`Section ${n+1} of packet "${a}" requires at least ${e[n]} values!`);if(i[n].length>t[n])throw new Error(`Section ${n+1} of packet "${a}" only allows ${t[n]} values!`)}}}else if(f.type!==t.PacketType.JSON){const e=i.find(e=>"object"==typeof e&&null!=e);e&&console.warn(`Passing an array will result in undefined behavior (${JSON.stringify(e)}). Spread the array with ...arr`)}const e=i.length>0?await f.processSend(i):n.EMPTY_UINT8;return[u,e,f]})}function i(e){return!(("number"==typeof e&&e in t.PacketType||e instanceof a.EnumPackage)&&e!=t.PacketType.KEY_EFFECTIVE)}const c=2048383;function s(e){return e<0?(console.warn("Having a data maximum below 0 does not do anything!"),0):e>c?(console.warn(`Only ${c} values can be sent on a type! Uhh make an issue if you want to send more.`),c):e}function l(e,t){return e<0?(console.warn("Having a data minimum below 0 does not do anything!"),0):e>t?(console.warn("Data minimum can not be higher than the data maximum!"),t):e}function u(e){if(!Number.isFinite(e)||e<0)throw new Error("Rate limit must be a non-negative finite number");return(e=Math.floor(e))>n.MAX_USHORT?(console.warn(`A rate limit above ${n.MAX_USHORT} is considered infinite.`),0):e}function f(a){const n=!0===a.autoFlatten&&void 0===a.dataMax&&void 0===a.dataMin;let{tag:r,type:o=t.PacketType.NONE,dataMax:f=1,dataMin:m,noDataRange:w=!1,dontSpread:d=!1,validator:y=null,dataBatching:g=0,maxBatchSize:k=10,rateLimit:P=0,enabled:E=!0,async:T=!1,gzipCompression:S=o==t.PacketType.JSON,rereference:$=!1,schema:v,autoFlatten:x=!1,quantized:b,min:A,max:M}=a;if(!r)throw new Error("Tag not selected!");if(w||n?(m=$?1:0,f=c):null==m&&(m=o==t.PacketType.NONE?0:f),$&&0==m)throw new Error("Rereference cannot be true if the dataMin is 0");if(i(o))throw new Error(`Invalid packet type: ${o}`);if(h(v,r),x&&(!v||0===v.length))throw new Error(`Packet "${r}" autoFlatten requires schema`);if(v&&!x&&m===f&&v.length!==f)throw new Error(`Packet "${r}" schema length must match its fixed value count (${f})`);!function(e,t,a,n,r){if(void 0!==a&&void 0!==n&&a>n)throw new Error(`Packet "${r}" min cannot exceed max`);if((t||void 0!==a||void 0!==n)&&!p.has(e))throw new Error(`Packet "${r}" numeric options require a numeric packet type`);if(t&&(!Number.isFinite(t.scale)||t.scale<=0))throw new Error(`Packet "${r}" quantization scale must be positive and finite`)}(o,b,A,M,r);const O=new e.PacketSchema(!1,o,T,l(m,f),s(f),u(P),d,x,$,g,k,S,v,b,A,M);return new e.Packet(r,O,y,E,!1)}function h(e,t){if(e){if(!e.length||e.some(e=>"string"!=typeof e||!e))throw new Error(`Packet "${t}" schema must contain non-empty field names`);if(new Set(e).size!==e.length)throw new Error(`Packet "${t}" schema fields must be unique`)}}const p=new Set([t.PacketType.BYTES,t.PacketType.UBYTES,t.PacketType.SHORTS,t.PacketType.USHORTS,t.PacketType.VARINT,t.PacketType.UVARINT,t.PacketType.DELTAS,t.PacketType.FLOATS,t.PacketType.DOUBLES]);function m(e){if(null==e)return[];const t=e[0];if(null==t)return[];if(!Array.isArray(t))throw new Error(`Cannot flatten array: ${e}`);return t.map((t,a)=>e.map(e=>e[a]))??[]}
|