sonic-ws 2.0.1 → 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 +64 -84
- package/bundled/bundle.js +1 -1
- package/bundled/bundle.wasm +0 -0
- package/dist/{ts/index.d.ts → index.d.ts} +1 -1
- package/dist/{ts/index.js → index.js} +2 -1
- package/dist/{ts/native → native}/wasm/node/package.json +1 -1
- package/dist/{ts/native → native}/wasm/node/sonic_ws_core.d.ts +0 -2
- package/dist/native/wasm/node/sonic_ws_core.js +7 -0
- package/dist/{ts/native → native}/wasm/node/sonic_ws_core_bg.wasm +0 -0
- package/dist/{ts/native/wasm/pkg → native/wasm/node}/sonic_ws_core_bg.wasm.d.ts +0 -1
- package/dist/{ts/native → native}/wasm/pkg/package.json +1 -1
- package/dist/{ts/native → native}/wasm/pkg/sonic_ws_core.d.ts +0 -2
- package/dist/{ts/native → native}/wasm/pkg/sonic_ws_core.js +1 -1
- package/dist/native/wasm/pkg/sonic_ws_core_bg.js +7 -0
- package/dist/{ts/native → native}/wasm/pkg/sonic_ws_core_bg.wasm +0 -0
- package/dist/{ts/native/wasm/node → native/wasm/pkg}/sonic_ws_core_bg.wasm.d.ts +0 -1
- package/dist/{ts/native → native}/wrapper.d.ts +0 -1
- package/dist/native/wrapper.js +7 -0
- package/dist/{ts/version.d.ts → version.d.ts} +1 -1
- package/dist/{ts/version.js → version.js} +1 -1
- package/dist/{ts/ws → ws}/Connection.d.ts +6 -0
- package/dist/ws/Connection.js +7 -0
- package/dist/{ts/ws → ws}/client/core/ClientCore.d.ts +2 -5
- package/dist/ws/client/core/ClientCore.js +7 -0
- package/dist/{ts/ws → ws}/packets/Packets.d.ts +29 -1
- package/dist/ws/packets/Packets.js +7 -0
- package/dist/{ts/ws → ws}/server/SonicWSConnection.d.ts +2 -0
- package/dist/ws/server/SonicWSConnection.js +7 -0
- package/dist/{ts/ws → ws}/server/SonicWSServer.d.ts +13 -0
- package/dist/ws/server/SonicWSServer.js +7 -0
- package/dist/{ts/ws → ws}/util/packets/BatchHelper.js +1 -1
- package/dist/{ts/ws → ws}/util/packets/CompressionUtil.d.ts +1 -0
- package/dist/ws/util/packets/CompressionUtil.js +7 -0
- package/dist/ws/util/packets/PacketHolder.js +7 -0
- package/dist/{ts/ws → ws}/util/packets/PacketUtils.d.ts +23 -0
- package/dist/ws/util/packets/PacketUtils.js +7 -0
- package/package.json +15 -11
- package/dist/ts/native/wasm/node/sonic_ws_core.js +0 -7
- package/dist/ts/native/wasm/pkg/sonic_ws_core_bg.js +0 -7
- package/dist/ts/native/wrapper.js +0 -7
- package/dist/ts/ws/Connection.js +0 -7
- package/dist/ts/ws/client/core/ClientCore.js +0 -7
- package/dist/ts/ws/packets/Packets.js +0 -7
- package/dist/ts/ws/server/SonicWSConnection.js +0 -7
- package/dist/ts/ws/server/SonicWSServer.js +0 -7
- package/dist/ts/ws/util/packets/CompressionUtil.js +0 -7
- package/dist/ts/ws/util/packets/PacketHolder.js +0 -7
- package/dist/ts/ws/util/packets/PacketUtils.js +0 -7
- /package/dist/{ts/native → native}/wasm/node/README.md +0 -0
- /package/dist/{ts/native → native}/wasm/pkg/README.md +0 -0
- /package/dist/{ts/ws → ws}/PacketProcessor.d.ts +0 -0
- /package/dist/{ts/ws → ws}/PacketProcessor.js +0 -0
- /package/dist/{ts/ws → ws}/client/node/ClientNode.d.ts +0 -0
- /package/dist/{ts/ws → ws}/client/node/ClientNode.js +0 -0
- /package/dist/{ts/ws → ws}/debug/DebugServer.d.ts +0 -0
- /package/dist/{ts/ws → ws}/debug/DebugServer.js +0 -0
- /package/dist/{ts/ws → ws}/packets/PacketType.d.ts +0 -0
- /package/dist/{ts/ws → ws}/packets/PacketType.js +0 -0
- /package/dist/{ts/ws → ws}/util/BufferUtil.d.ts +0 -0
- /package/dist/{ts/ws → ws}/util/BufferUtil.js +0 -0
- /package/dist/{ts/ws → ws}/util/StringUtil.d.ts +0 -0
- /package/dist/{ts/ws → ws}/util/StringUtil.js +0 -0
- /package/dist/{ts/ws → ws}/util/enums/EnumHandler.d.ts +0 -0
- /package/dist/{ts/ws → ws}/util/enums/EnumHandler.js +0 -0
- /package/dist/{ts/ws → ws}/util/enums/EnumType.d.ts +0 -0
- /package/dist/{ts/ws → ws}/util/enums/EnumType.js +0 -0
- /package/dist/{ts/ws → ws}/util/packets/BatchHelper.d.ts +0 -0
- /package/dist/{ts/ws → ws}/util/packets/HashUtil.d.ts +0 -0
- /package/dist/{ts/ws → ws}/util/packets/HashUtil.js +0 -0
- /package/dist/{ts/ws → ws}/util/packets/JSONUtil.d.ts +0 -0
- /package/dist/{ts/ws → ws}/util/packets/JSONUtil.js +0 -0
- /package/dist/{ts/ws → ws}/util/packets/PacketHolder.d.ts +0 -0
- /package/dist/{ts/ws → ws}/util/packets/RateHandler.d.ts +0 -0
- /package/dist/{ts/ws → ws}/util/packets/RateHandler.js +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
+
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
+
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export function decodeBatch(e,n,t,o){const r=l.decodeBatch(e,n,t,i(o)?Number.MAX_SAFE_INTEGER:o>>>0);if(r[2])throw f(r[1]);return f(r[0])}export function decodeBooleans(e,n){const t=l.decodeBooleans(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function decodeFloats(e,n){const t=l.decodeFloats(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function decodeHex(e){let n,t;try{const i=l.decodeHex(e);var r=i[0],c=i[1];if(i[3])throw r=0,c=0,f(i[2]);return n=r,t=c,o(r,c)}finally{l.__wbindgen_free(n,t,1)}}export function decodeRaw(e){const n=l.decodeRaw(e);if(n[2])throw f(n[1]);return f(n[0])}export function decodeSigned(e,n){const t=l.decodeSigned(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function decodeStrings(e,n){const t=l.decodeStrings(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function decodeUnsigned(e,n){const t=l.decodeUnsigned(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function deflateRaw(e){const n=l.deflateRaw(e);if(n[2])throw f(n[1]);return f(n[0])}export function encodeBatch(e,n){const t=l.encodeBatch(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function encodeBooleans(e){const n=l.encodeBooleans(e);if(n[2])throw f(n[1]);return f(n[0])}export function encodeFloats(e,n){const t=l.encodeFloats(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function encodeHex(e){const n=d(e,l.__wbindgen_malloc,l.__wbindgen_realloc),t=w,o=l.encodeHex(n,t);if(o[2])throw f(o[1]);return f(o[0])}export function encodeSigned(e,n){const t=l.encodeSigned(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function encodeStrings(e,n){const t=l.encodeStrings(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function encodeUnsigned(e,n){const t=l.encodeUnsigned(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function frameObject(e){const n=l.frameObject(e);if(n[2])throw f(n[1]);return f(n[0])}export function inflateRaw(e,n){const t=l.inflateRaw(e,i(n)?Number.MAX_SAFE_INTEGER:n>>>0);if(t[2])throw f(t[1]);return f(t[0])}export function unframeObject(e,n){const t=l.unframeObject(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function validateEncoded(e,n,t,o,r,c,d){const u=l.validateEncoded(e,n,t,o,r,c,i(d)?Number.MAX_SAFE_INTEGER:d>>>0);if(u[1])throw f(u[0])}export function validateEnum(e,n,t,o){const r=l.validateEnum(e,n,t,o);if(r[1])throw f(r[0])}export function validateObject(e,n,t,o,r){const c=l.validateObject(e,n,t,o,r);if(c[1])throw f(c[0])}export function __wbg___wbindgen_boolean_get_fa956cfa2d1bd751(e){const n="boolean"==typeof e?e:void 0;return i(n)?16777215:n?1:0}export function __wbg___wbindgen_number_get_394265ed1e1b84ee(e,n){const o="number"==typeof n?n:void 0;t().setFloat64(e+8,i(o)?0:o,!0),t().setInt32(e+0,!i(o),!0)}export function __wbg___wbindgen_string_get_b0ca35b86a603356(e,n){const o="string"==typeof n?n:void 0;var r=i(o)?0:d(o,l.__wbindgen_malloc,l.__wbindgen_realloc),c=w;t().setInt32(e+4,c,!0),t().setInt32(e+0,r,!0)}export function __wbg___wbindgen_throw_344f42d3211c4765(e,n){throw new Error(o(e,n))}export function __wbg_get_unchecked_6e0ad6d2a41b06f6(e,n){return e[n>>>0]}export function __wbg_length_1f0964f4a5e2c6d8(e){return e.length}export function __wbg_length_370319915dc99107(e){return e.length}export function __wbg_new_32b398fb48b6d94a(){return new Array}export function __wbg_new_cd45aabdf6073e84(e){return new Uint8Array(e)}export function __wbg_new_from_slice_77cdfb7977362f3c(n,t){return new Uint8Array(e(n,t))}export function __wbg_prototypesetcall_4770620bbe4688a0(n,t,o){Uint8Array.prototype.set.call(e(n,t),o)}export function __wbg_push_d2ae3af0c1217ae6(e,n){return e.push(n)}export function __wbindgen_cast_0000000000000001(e){return e}export function __wbindgen_cast_0000000000000002(e,n){return o(e,n)}export function __wbindgen_init_externref_table(){const e=l.__wbindgen_externrefs,n=e.grow(4);e.set(0,void 0),e.set(n+0,void 0),e.set(n+1,null),e.set(n+2,!0),e.set(n+3,!1)}function e(e,n){return e>>>=0,c().subarray(e/1,e/1+n)}let n=null;function t(){return(null===n||!0===n.buffer.detached||void 0===n.buffer.detached&&n.buffer!==l.memory.buffer)&&(n=new DataView(l.memory.buffer)),n}function o(e,n){return function(e,n){a+=n,a>=_&&(u=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0}),u.decode(),a=n);return u.decode(c().subarray(e,e+n))}(e>>>0,n)}let r=null;function c(){return null!==r&&0!==r.byteLength||(r=new Uint8Array(l.memory.buffer)),r}function i(e){return null==e}function d(e,n,t){if(void 0===t){const t=s.encode(e),o=n(t.length,1)>>>0;return c().subarray(o,o+t.length).set(t),w=t.length,o}let o=e.length,r=n(o,1)>>>0;const i=c();let d=0;for(;d<o;d++){const n=e.charCodeAt(d);if(n>127)break;i[r+d]=n}if(d!==o){0!==d&&(e=e.slice(d)),r=t(r,o,o=d+3*e.length,1)>>>0;const n=c().subarray(r+d,r+o);d+=s.encodeInto(e,n).written,r=t(r,o,d,1)>>>0}return w=d,r}function f(e){const n=l.__wbindgen_externrefs.get(e);return l.__externref_table_dealloc(e),n}let u=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0});u.decode();const _=2146435072;let a=0;const s=new TextEncoder;"encodeInto"in s||(s.encodeInto=function(e,n){const t=s.encode(e);return n.set(t),{read:e.length,written:t.length}});let l,w=0;export function __wbg_set_wasm(e){l=e}
|
|
Binary file
|
|
@@ -19,7 +19,6 @@ export const encodeBatch: (a: any, b: number) => [number, number, number];
|
|
|
19
19
|
export const encodeBooleans: (a: any) => [number, number, number];
|
|
20
20
|
export const encodeFloats: (a: number, b: any) => [number, number, number];
|
|
21
21
|
export const encodeHex: (a: number, b: number) => [number, number, number];
|
|
22
|
-
export const encodeRaw: (a: any) => [number, number, number];
|
|
23
22
|
export const encodeSigned: (a: number, b: any) => [number, number, number];
|
|
24
23
|
export const encodeStrings: (a: number, b: any) => [number, number, number];
|
|
25
24
|
export const encodeUnsigned: (a: number, b: any) => [number, number, number];
|
|
@@ -16,7 +16,6 @@ export interface SonicNativeCore {
|
|
|
16
16
|
decodeStrings(kind: number, data: Uint8Array): string[];
|
|
17
17
|
encodeBooleans(values: boolean[]): Uint8Array;
|
|
18
18
|
decodeBooleans(data: Uint8Array, count: number): boolean[];
|
|
19
|
-
encodeRaw(data: Uint8Array): Uint8Array;
|
|
20
19
|
decodeRaw(data: Uint8Array): Uint8Array;
|
|
21
20
|
encodeHex(value: string): Uint8Array;
|
|
22
21
|
decodeHex(data: Uint8Array): string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
+
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
+
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
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=require("../ws/packets/PacketType"),version_1=require("../version"),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 a=Number((await t.text()).trim());if(!Number.isInteger(a)||a!==version_1.VERSION)throw new Error(`SonicWS CDN protocol mismatch: expected ${version_1.VERSION}, received ${String(a)}`);const n=await e(CDN_WASM);if(!await isWasm(n))throw new Error("SonicWS CDN returned an invalid WASM module");return n}async function initializeBrowserWasm(){const e=window.fetch.bind(window);window.fetch=async(t,a)=>{const n=fetchUrl(t);if(n===CDN_WASM||!new URL(n,window.location.href).pathname.endsWith("/bundle.wasm"))return e(t,a);try{const n=await e(t,a);if(await isWasm(n))return n}catch{}return fetchCdnWasm(e)};try{return setNativeCore(await import("./wasm/pkg/sonic_ws_core.js")),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,"undefined"!=typeof __dirname?`${__dirname}/sonic_ws_core.node`:void 0,"undefined"!=typeof __dirname?`${__dirname}/../../../native/sonic_ws_core.node`:void 0].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 a=e.values.findIndex(e=>e===t||"number"==typeof e&&"number"==typeof t&&Number.isNaN(e)&&Number.isNaN(t));if(a<0)throw new Error(`Value ${String(t)} does not exist in enum ${e.tag}`);return a}function encodeNative(e,t,a,n=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 n.encodeSigned(e,values(t));case PacketType_1.PacketType.UBYTES:case PacketType_1.PacketType.USHORTS:case PacketType_1.PacketType.UVARINT:return n.encodeUnsigned(e,values(t));case PacketType_1.PacketType.FLOATS:case PacketType_1.PacketType.DOUBLES:return n.encodeFloats(e,values(t));case PacketType_1.PacketType.STRINGS_ASCII:case PacketType_1.PacketType.STRINGS_UTF16:return n.encodeStrings(e,values(t));case PacketType_1.PacketType.BOOLEANS:return n.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 n.encodeHex(e)}case PacketType_1.PacketType.ENUMS:if(!a)throw new Error("ENUMS requires an EnumPackage");return Uint8Array.from(values(t).map(e=>enumIndex(a,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,a=4294967295,n,r=loadNativeCore()){const o=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(o);case PacketType_1.PacketType.BYTES:case PacketType_1.PacketType.SHORTS:case PacketType_1.PacketType.VARINT:case PacketType_1.PacketType.DELTAS:return r.decodeSigned(e,o);case PacketType_1.PacketType.UBYTES:case PacketType_1.PacketType.USHORTS:case PacketType_1.PacketType.UVARINT:return r.decodeUnsigned(e,o);case PacketType_1.PacketType.FLOATS:case PacketType_1.PacketType.DOUBLES:return r.decodeFloats(e,o);case PacketType_1.PacketType.STRINGS_ASCII:case PacketType_1.PacketType.STRINGS_UTF16:return r.decodeStrings(e,o);case PacketType_1.PacketType.BOOLEANS:return r.decodeBooleans(o,a);case PacketType_1.PacketType.HEX:return r.decodeHex(o);case PacketType_1.PacketType.ENUMS:if(!n)throw new Error("ENUMS requires an EnumPackage");return[...t].map(e=>{if(e>=n.values.length)throw new Error(`Enum index ${e} is out of range`);return n.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,a,n,r={},o=loadNativeCore()){if(e!==PacketType_1.PacketType.ENUMS)o.validateEncoded(e,buffer(t),a,n,r.compressed??!1,r.batched??!1,r.maxBatchSize);else{if(!r.enumData)throw new Error("ENUMS requires an EnumPackage");o.validateEnum(buffer(t),r.enumData.values.length,a,n)}}function encodeNativeObject(e,t,a=loadNativeCore()){if(t.length!==e.types.length)throw new Error("Object field count does not match schema");let n=0;const r=e.types.map((r,o)=>encodeNative(r,t[o],r===PacketType_1.PacketType.ENUMS?e.enumData?.[n++]:void 0,a));return a.frameObject(r)}function decodeNativeObject(e,t,a=loadNativeCore()){const n=a.unframeObject(buffer(t),e.types.length);let r=0;return n.map((t,n)=>decodeNative(e.types[n],t,e.dataMaxes[n],e.types[n]===PacketType_1.PacketType.ENUMS?e.enumData?.[r++]:void 0,a))}function validateNativeObject(e,t,a=loadNativeCore()){a.validateObject(buffer(t),[...e.types],[...e.dataMins],[...e.dataMaxes],(e.enumData??[]).map(e=>e.values.length))}function encodeNativeBatch(e,t,a=loadNativeCore()){return a.encodeBatch(e.map(buffer),t)}function decodeNativeBatch(e,t,a=0,n,r=loadNativeCore()){const o=Number.isFinite(a)&&a>0?a:0;return r.decodeBatch(buffer(e),t,o,n)}function deflateNative(e,t=loadNativeCore()){return t.deflateRaw(buffer(e))}function inflateNative(e,t,a=loadNativeCore()){return a.inflateRaw(buffer(e),t)}
|
|
@@ -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 */
|
|
@@ -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);
|
|
@@ -50,6 +50,8 @@ export interface IConnection<T> extends IMiddlewareHolder<ConnectionMiddleware>
|
|
|
50
50
|
* @param listener Callback for when data is received
|
|
51
51
|
*/
|
|
52
52
|
raw_onmessage(listener: (data: T) => void): void;
|
|
53
|
+
/** Listens for all raw outgoing messages. */
|
|
54
|
+
raw_onsend(listener: (data: Uint8Array) => void): void;
|
|
53
55
|
/**
|
|
54
56
|
* Closes the connection
|
|
55
57
|
*/
|
|
@@ -74,6 +76,7 @@ export declare abstract class Connection<T extends {
|
|
|
74
76
|
close: (c: number, d: string | undefined) => void;
|
|
75
77
|
}, K> extends MiddlewareHolder<ConnectionMiddleware> implements IConnection<K> {
|
|
76
78
|
protected listeners: Record<string, Array<(...data: any[]) => void>>;
|
|
79
|
+
private rawSendListeners;
|
|
77
80
|
private name;
|
|
78
81
|
protected closed: boolean;
|
|
79
82
|
socket: T;
|
|
@@ -83,6 +86,8 @@ export declare abstract class Connection<T extends {
|
|
|
83
86
|
_off: Function;
|
|
84
87
|
/** The index of the connection; unique for all connected, not unique after disconnection. */
|
|
85
88
|
id: number;
|
|
89
|
+
/** Mutable application-owned state scoped to this connection. */
|
|
90
|
+
state: Record<string, unknown>;
|
|
86
91
|
constructor(socket: T, id: number, name: string, addListener: Function, removeListener: Function);
|
|
87
92
|
setTimeout(call: () => void, time: number, callOnClose?: boolean): number;
|
|
88
93
|
setInterval(call: () => void, time: number, callOnClose?: boolean): number;
|
|
@@ -90,6 +95,7 @@ export declare abstract class Connection<T extends {
|
|
|
90
95
|
clearInterval(id: number): void;
|
|
91
96
|
raw_send(data: Uint8Array): void;
|
|
92
97
|
raw_onmessage(listener: (data: K) => void): void;
|
|
98
|
+
raw_onsend(listener: (data: Uint8Array) => void): void;
|
|
93
99
|
close(code?: number, reason?: string | Buffer): void;
|
|
94
100
|
isClosed(): boolean;
|
|
95
101
|
setName(name: string): Promise<void>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
+
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
+
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
+
*/
|
|
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;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={}));
|
|
@@ -36,11 +36,6 @@ export declare abstract class SonicWSCore<T extends {
|
|
|
36
36
|
private dataHandler;
|
|
37
37
|
private messageHandler;
|
|
38
38
|
protected listen(tag: string, listener: (data: any[]) => void): void;
|
|
39
|
-
/**
|
|
40
|
-
* Listens for all sent messages rawly
|
|
41
|
-
* @param listener Callback for when data is received
|
|
42
|
-
*/
|
|
43
|
-
raw_onsend(listener: (data: Uint8Array) => void): void;
|
|
44
39
|
private sendQueue;
|
|
45
40
|
/**
|
|
46
41
|
* Sends a packet to the server
|
|
@@ -48,6 +43,8 @@ export declare abstract class SonicWSCore<T extends {
|
|
|
48
43
|
* @param values The values to send
|
|
49
44
|
*/
|
|
50
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>;
|
|
51
48
|
/**
|
|
52
49
|
* Listens for when the client connects
|
|
53
50
|
* @param listener Callback on connection
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
+
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
+
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
+
*/
|
|
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],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 {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
+
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
+
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
+
*/
|
|
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"),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
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
+
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
+
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
+
*/
|
|
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],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
|
*/
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
+
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
+
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
+
*/
|
|
6
|
+
|
|
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}};
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
/** Utilities still required by schema serialization and the connection handshake. */
|
|
7
7
|
export declare const MAX_BYTE = 255;
|
|
8
|
+
export declare const MAX_USHORT = 65535;
|
|
8
9
|
export declare const MAX_UVARINT: number;
|
|
9
10
|
export declare const EMPTY_UINT8: Uint8Array<ArrayBuffer>;
|
|
10
11
|
export declare const compressBools: (values: boolean[]) => number;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
+
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
+
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.decompressBools=exports.compressBools=exports.EMPTY_UINT8=exports.MAX_UVARINT=exports.MAX_USHORT=exports.MAX_BYTE=void 0,exports.convertVarInt=function(e){if(!Number.isSafeInteger(e)||e<0||e>exports.MAX_UVARINT)throw new Error(`Variable Ints must be within range 0 and ${exports.MAX_UVARINT}: ${e}`);const r=[];do{let o=e%128;(e=Math.floor(e/128))>0&&(o|=128),r.push(o)}while(e>0);return r},exports.readVarInt=function(e,r){let o=0,t=1;for(let s=0;s<8;s++){if(r>=e.length)throw new Error("Truncated variable integer");const s=e[r++];if(o+=(127&s)*t,!(128&s))return[r,o];t*=128}throw new Error("Variable integer is too long")},exports.MAX_BYTE=255,exports.MAX_USHORT=65535,exports.MAX_UVARINT=128**7-1,exports.EMPTY_UINT8=new Uint8Array([]);exports.compressBools=e=>e.reduce((e,r,o)=>e|Number(r)<<7-o,0);exports.decompressBools=e=>Array.from({length:8},(r,o)=>!!(e&1<<7-o));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
+
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
+
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
+
*/
|
|
6
|
+
|
|
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.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
+
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
+
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
+
*/
|
|
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: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]))??[]}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sonic-ws",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Ultra-lightweight, high-performance, and bandwidth efficient websocket library",
|
|
5
|
-
"main": "dist/
|
|
6
|
-
"types": "dist/
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
|
-
"dist
|
|
8
|
+
"dist/**/*",
|
|
9
9
|
"bundled/bundle.js",
|
|
10
10
|
"bundled/bundle.wasm",
|
|
11
11
|
"README.md",
|
|
@@ -13,16 +13,20 @@
|
|
|
13
13
|
],
|
|
14
14
|
"scripts": {
|
|
15
15
|
"webpack": "webpack --mode production",
|
|
16
|
-
|
|
17
|
-
"
|
|
16
|
+
|
|
17
|
+
"build_wasm_browser": "wasm-pack build --release --target bundler --out-dir ../ts/src/native/wasm/pkg --out-name sonic_ws_core ../core --features wasm --no-default-features",
|
|
18
|
+
"build_wasm_node": "wasm-pack build --release --target nodejs --out-dir ../ts/src/native/wasm/node --out-name sonic_ws_core ../core --features wasm --no-default-features",
|
|
18
19
|
"build_wasm": "npm run build_wasm_browser && npm run build_wasm_node",
|
|
19
|
-
"build_web": "npm run build_wasm_browser && tsc --moduleResolution nodenext --module nodenext --outDir ./dist
|
|
20
|
-
"build_node": "npm run build_wasm && rimraf ./dist
|
|
21
|
-
"build": "npm run build_node && npm run build_web && rimraf ./dist/
|
|
20
|
+
"build_web": "npm run build_wasm_browser && tsc --moduleResolution nodenext --module nodenext --outDir ./dist src/ws/client/browser/ClientBrowser.ts && cpy \"src/native/wasm/pkg/*\" dist/native/wasm/pkg --flat && rimraf ./dist/native/wasm/pkg/.gitignore && npm run webpack && node package-files.mjs",
|
|
21
|
+
"build_node": "npm run build_wasm && rimraf ./dist && tsc -d && cpy \"src/native/wasm/node/*\" dist/native/wasm/node --flat && rimraf ./dist/native/wasm/node/.gitignore",
|
|
22
|
+
"build": "npm run build_node && npm run build_web && rimraf ./dist/ws/client/browser && rimraf ./dist/ws/debug/DebugClient.d.ts && rimraf ./dist/ws/debug/DebugClient.js && node minify.mjs && node package-files.mjs",
|
|
23
|
+
|
|
22
24
|
"test_web": "npm run build && node tests/test_web.mjs",
|
|
23
|
-
"test_node": "npm --prefix
|
|
25
|
+
"test_node": "npm --prefix ../core/tests/typescript run build:native && npm run build_node && node tests/test_node.mjs",
|
|
24
26
|
"prepack": "npm run build",
|
|
25
|
-
|
|
27
|
+
|
|
28
|
+
"stage_package": "node package-files.mjs",
|
|
29
|
+
"publish:assets": "rimraf ../../release/SonicWS_bundle.js ../../release/SonicWS_core.wasm && cp ../../bundled/bundle.js ../../release/bundle.js && cp ../../bundled/bundle.wasm ../../release/bundle.wasm"
|
|
26
30
|
},
|
|
27
31
|
"repository": {
|
|
28
32
|
"type": "git",
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
-
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
-
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
function e(e,n){return e>>>=0,c().subarray(e/1,e/1+n)}exports.decodeBatch=function(e,n,t,o){const r=b.decodeBatch(e,n,t,i(o)?Number.MAX_SAFE_INTEGER:o>>>0);if(r[2])throw d(r[1]);return d(r[0])},exports.decodeBooleans=function(e,n){const t=b.decodeBooleans(e,n);if(t[2])throw d(t[1]);return d(t[0])},exports.decodeFloats=function(e,n){const t=b.decodeFloats(e,n);if(t[2])throw d(t[1]);return d(t[0])},exports.decodeHex=function(e){let n,t;try{const i=b.decodeHex(e);var r=i[0],c=i[1];if(i[3])throw r=0,c=0,d(i[2]);return n=r,t=c,o(r,c)}finally{b.__wbindgen_free(n,t,1)}},exports.decodeRaw=function(e){const n=b.decodeRaw(e);if(n[2])throw d(n[1]);return d(n[0])},exports.decodeSigned=function(e,n){const t=b.decodeSigned(e,n);if(t[2])throw d(t[1]);return d(t[0])},exports.decodeStrings=function(e,n){const t=b.decodeStrings(e,n);if(t[2])throw d(t[1]);return d(t[0])},exports.decodeUnsigned=function(e,n){const t=b.decodeUnsigned(e,n);if(t[2])throw d(t[1]);return d(t[0])},exports.deflateRaw=function(e){const n=b.deflateRaw(e);if(n[2])throw d(n[1]);return d(n[0])},exports.encodeBatch=function(e,n){const t=b.encodeBatch(e,n);if(t[2])throw d(t[1]);return d(t[0])},exports.encodeBooleans=function(e){const n=b.encodeBooleans(e);if(n[2])throw d(n[1]);return d(n[0])},exports.encodeFloats=function(e,n){const t=b.encodeFloats(e,n);if(t[2])throw d(t[1]);return d(t[0])},exports.encodeHex=function(e){const n=_(e,b.__wbindgen_malloc,b.__wbindgen_realloc),t=s,o=b.encodeHex(n,t);if(o[2])throw d(o[1]);return d(o[0])},exports.encodeRaw=function(e){const n=b.encodeRaw(e);if(n[2])throw d(n[1]);return d(n[0])},exports.encodeSigned=function(e,n){const t=b.encodeSigned(e,n);if(t[2])throw d(t[1]);return d(t[0])},exports.encodeStrings=function(e,n){const t=b.encodeStrings(e,n);if(t[2])throw d(t[1]);return d(t[0])},exports.encodeUnsigned=function(e,n){const t=b.encodeUnsigned(e,n);if(t[2])throw d(t[1]);return d(t[0])},exports.frameObject=function(e){const n=b.frameObject(e);if(n[2])throw d(n[1]);return d(n[0])},exports.inflateRaw=function(e,n){const t=b.inflateRaw(e,i(n)?Number.MAX_SAFE_INTEGER:n>>>0);if(t[2])throw d(t[1]);return d(t[0])},exports.unframeObject=function(e,n){const t=b.unframeObject(e,n);if(t[2])throw d(t[1]);return d(t[0])},exports.validateEncoded=function(e,n,t,o,r,c,_){const u=b.validateEncoded(e,n,t,o,r,c,i(_)?Number.MAX_SAFE_INTEGER:_>>>0);if(u[1])throw d(u[0])},exports.validateEnum=function(e,n,t,o){const r=b.validateEnum(e,n,t,o);if(r[1])throw d(r[0])},exports.validateObject=function(e,n,t,o,r){const c=b.validateObject(e,n,t,o,r);if(c[1])throw d(c[0])};let n=null;function t(){return(null===n||!0===n.buffer.detached||void 0===n.buffer.detached&&n.buffer!==b.memory.buffer)&&(n=new DataView(b.memory.buffer)),n}function o(e,n){return function(e,n){return u.decode(c().subarray(e,e+n))}(e>>>0,n)}let r=null;function c(){return null!==r&&0!==r.byteLength||(r=new Uint8Array(b.memory.buffer)),r}function i(e){return null==e}function _(e,n,t){if(void 0===t){const t=f.encode(e),o=n(t.length,1)>>>0;return c().subarray(o,o+t.length).set(t),s=t.length,o}let o=e.length,r=n(o,1)>>>0;const i=c();let _=0;for(;_<o;_++){const n=e.charCodeAt(_);if(n>127)break;i[r+_]=n}if(_!==o){0!==_&&(e=e.slice(_)),r=t(r,o,o=_+3*e.length,1)>>>0;const n=c().subarray(r+_,r+o);_+=f.encodeInto(e,n).written,r=t(r,o,_,1)>>>0}return s=_,r}function d(e){const n=b.__wbindgen_externrefs.get(e);return b.__externref_table_dealloc(e),n}let u=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0});u.decode();const f=new TextEncoder;"encodeInto"in f||(f.encodeInto=function(e,n){const t=f.encode(e);return n.set(t),{read:e.length,written:t.length}});let s=0;const a=`${__dirname}/sonic_ws_core_bg.wasm`,l=require("fs").readFileSync(a),w=new WebAssembly.Module(l);let b=new WebAssembly.Instance(w,{__proto__:null,"./sonic_ws_core_bg.js":{__proto__:null,__wbg___wbindgen_boolean_get_fa956cfa2d1bd751:function(e){const n="boolean"==typeof e?e:void 0;return i(n)?16777215:n?1:0},__wbg___wbindgen_number_get_394265ed1e1b84ee:function(e,n){const o="number"==typeof n?n:void 0;t().setFloat64(e+8,i(o)?0:o,!0),t().setInt32(e+0,!i(o),!0)},__wbg___wbindgen_string_get_b0ca35b86a603356:function(e,n){const o="string"==typeof n?n:void 0;var r=i(o)?0:_(o,b.__wbindgen_malloc,b.__wbindgen_realloc),c=s;t().setInt32(e+4,c,!0),t().setInt32(e+0,r,!0)},__wbg___wbindgen_throw_344f42d3211c4765:function(e,n){throw new Error(o(e,n))},__wbg_get_unchecked_6e0ad6d2a41b06f6:function(e,n){return e[n>>>0]},__wbg_length_1f0964f4a5e2c6d8:function(e){return e.length},__wbg_length_370319915dc99107:function(e){return e.length},__wbg_new_32b398fb48b6d94a:function(){return new Array},__wbg_new_cd45aabdf6073e84:function(e){return new Uint8Array(e)},__wbg_new_from_slice_77cdfb7977362f3c:function(n,t){return new Uint8Array(e(n,t))},__wbg_prototypesetcall_4770620bbe4688a0:function(n,t,o){Uint8Array.prototype.set.call(e(n,t),o)},__wbg_push_d2ae3af0c1217ae6:function(e,n){return e.push(n)},__wbindgen_cast_0000000000000001:function(e){return e},__wbindgen_cast_0000000000000002:function(e,n){return o(e,n)},__wbindgen_init_externref_table:function(){const e=b.__wbindgen_externrefs,n=e.grow(4);e.set(0,void 0),e.set(n+0,void 0),e.set(n+1,null),e.set(n+2,!0),e.set(n+3,!1)}}}).exports;b.__wbindgen_start();
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
-
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
-
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
export function decodeBatch(e,n,t,o){const r=w.decodeBatch(e,n,t,i(o)?Number.MAX_SAFE_INTEGER:o>>>0);if(r[2])throw f(r[1]);return f(r[0])}export function decodeBooleans(e,n){const t=w.decodeBooleans(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function decodeFloats(e,n){const t=w.decodeFloats(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function decodeHex(e){let n,t;try{const i=w.decodeHex(e);var r=i[0],c=i[1];if(i[3])throw r=0,c=0,f(i[2]);return n=r,t=c,o(r,c)}finally{w.__wbindgen_free(n,t,1)}}export function decodeRaw(e){const n=w.decodeRaw(e);if(n[2])throw f(n[1]);return f(n[0])}export function decodeSigned(e,n){const t=w.decodeSigned(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function decodeStrings(e,n){const t=w.decodeStrings(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function decodeUnsigned(e,n){const t=w.decodeUnsigned(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function deflateRaw(e){const n=w.deflateRaw(e);if(n[2])throw f(n[1]);return f(n[0])}export function encodeBatch(e,n){const t=w.encodeBatch(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function encodeBooleans(e){const n=w.encodeBooleans(e);if(n[2])throw f(n[1]);return f(n[0])}export function encodeFloats(e,n){const t=w.encodeFloats(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function encodeHex(e){const n=d(e,w.__wbindgen_malloc,w.__wbindgen_realloc),t=l,o=w.encodeHex(n,t);if(o[2])throw f(o[1]);return f(o[0])}export function encodeRaw(e){const n=w.encodeRaw(e);if(n[2])throw f(n[1]);return f(n[0])}export function encodeSigned(e,n){const t=w.encodeSigned(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function encodeStrings(e,n){const t=w.encodeStrings(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function encodeUnsigned(e,n){const t=w.encodeUnsigned(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function frameObject(e){const n=w.frameObject(e);if(n[2])throw f(n[1]);return f(n[0])}export function inflateRaw(e,n){const t=w.inflateRaw(e,i(n)?Number.MAX_SAFE_INTEGER:n>>>0);if(t[2])throw f(t[1]);return f(t[0])}export function unframeObject(e,n){const t=w.unframeObject(e,n);if(t[2])throw f(t[1]);return f(t[0])}export function validateEncoded(e,n,t,o,r,c,d){const u=w.validateEncoded(e,n,t,o,r,c,i(d)?Number.MAX_SAFE_INTEGER:d>>>0);if(u[1])throw f(u[0])}export function validateEnum(e,n,t,o){const r=w.validateEnum(e,n,t,o);if(r[1])throw f(r[0])}export function validateObject(e,n,t,o,r){const c=w.validateObject(e,n,t,o,r);if(c[1])throw f(c[0])}export function __wbg___wbindgen_boolean_get_fa956cfa2d1bd751(e){const n="boolean"==typeof e?e:void 0;return i(n)?16777215:n?1:0}export function __wbg___wbindgen_number_get_394265ed1e1b84ee(e,n){const o="number"==typeof n?n:void 0;t().setFloat64(e+8,i(o)?0:o,!0),t().setInt32(e+0,!i(o),!0)}export function __wbg___wbindgen_string_get_b0ca35b86a603356(e,n){const o="string"==typeof n?n:void 0;var r=i(o)?0:d(o,w.__wbindgen_malloc,w.__wbindgen_realloc),c=l;t().setInt32(e+4,c,!0),t().setInt32(e+0,r,!0)}export function __wbg___wbindgen_throw_344f42d3211c4765(e,n){throw new Error(o(e,n))}export function __wbg_get_unchecked_6e0ad6d2a41b06f6(e,n){return e[n>>>0]}export function __wbg_length_1f0964f4a5e2c6d8(e){return e.length}export function __wbg_length_370319915dc99107(e){return e.length}export function __wbg_new_32b398fb48b6d94a(){return new Array}export function __wbg_new_cd45aabdf6073e84(e){return new Uint8Array(e)}export function __wbg_new_from_slice_77cdfb7977362f3c(n,t){return new Uint8Array(e(n,t))}export function __wbg_prototypesetcall_4770620bbe4688a0(n,t,o){Uint8Array.prototype.set.call(e(n,t),o)}export function __wbg_push_d2ae3af0c1217ae6(e,n){return e.push(n)}export function __wbindgen_cast_0000000000000001(e){return e}export function __wbindgen_cast_0000000000000002(e,n){return o(e,n)}export function __wbindgen_init_externref_table(){const e=w.__wbindgen_externrefs,n=e.grow(4);e.set(0,void 0),e.set(n+0,void 0),e.set(n+1,null),e.set(n+2,!0),e.set(n+3,!1)}function e(e,n){return e>>>=0,c().subarray(e/1,e/1+n)}let n=null;function t(){return(null===n||!0===n.buffer.detached||void 0===n.buffer.detached&&n.buffer!==w.memory.buffer)&&(n=new DataView(w.memory.buffer)),n}function o(e,n){return function(e,n){a+=n,a>=_&&(u=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0}),u.decode(),a=n);return u.decode(c().subarray(e,e+n))}(e>>>0,n)}let r=null;function c(){return null!==r&&0!==r.byteLength||(r=new Uint8Array(w.memory.buffer)),r}function i(e){return null==e}function d(e,n,t){if(void 0===t){const t=s.encode(e),o=n(t.length,1)>>>0;return c().subarray(o,o+t.length).set(t),l=t.length,o}let o=e.length,r=n(o,1)>>>0;const i=c();let d=0;for(;d<o;d++){const n=e.charCodeAt(d);if(n>127)break;i[r+d]=n}if(d!==o){0!==d&&(e=e.slice(d)),r=t(r,o,o=d+3*e.length,1)>>>0;const n=c().subarray(r+d,r+o);d+=s.encodeInto(e,n).written,r=t(r,o,d,1)>>>0}return l=d,r}function f(e){const n=w.__wbindgen_externrefs.get(e);return w.__externref_table_dealloc(e),n}let u=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0});u.decode();const _=2146435072;let a=0;const s=new TextEncoder;"encodeInto"in s||(s.encodeInto=function(e,n){const t=s.encode(e);return n.set(t),{read:e.length,written:t.length}});let w,l=0;export function __wbg_set_wasm(e){w=e}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
-
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
-
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
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=require("../ws/packets/PacketType");let loadedCore;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","encodeRaw","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}async function initializeWasmCore(){const wasm="undefined"==typeof window?eval("require")("./wasm/node/sonic_ws_core.js"):await import("./wasm/pkg/sonic_ws_core.js");return setNativeCore(wasm),loadedCore}function loadNativeCore(addonPath){if(loadedCore&&!addonPath)return loadedCore;const candidates=addonPath?[addonPath]:["undefined"!=typeof process?process.env.SONIC_WS_CORE_PATH:void 0,"undefined"!=typeof __dirname?`${__dirname}/sonic_ws_core.node`:void 0,"undefined"!=typeof __dirname?`${__dirname}/../../../native/sonic_ws_core.node`:void 0].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 a=e.values.findIndex(e=>e===t||"number"==typeof e&&"number"==typeof t&&Number.isNaN(e)&&Number.isNaN(t));if(a<0)throw new Error(`Value ${String(t)} does not exist in enum ${e.tag}`);return a}function encodeNative(e,t,a,r=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 r.encodeRaw(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 r.encodeSigned(e,values(t));case PacketType_1.PacketType.UBYTES:case PacketType_1.PacketType.USHORTS:case PacketType_1.PacketType.UVARINT:return r.encodeUnsigned(e,values(t));case PacketType_1.PacketType.FLOATS:case PacketType_1.PacketType.DOUBLES:return r.encodeFloats(e,values(t));case PacketType_1.PacketType.STRINGS_ASCII:case PacketType_1.PacketType.STRINGS_UTF16:return r.encodeStrings(e,values(t));case PacketType_1.PacketType.BOOLEANS:return r.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 r.encodeHex(e)}case PacketType_1.PacketType.ENUMS:if(!a)throw new Error("ENUMS requires an EnumPackage");return Uint8Array.from(values(t).map(e=>enumIndex(a,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,a=4294967295,r,n=loadNativeCore()){const o=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 n.decodeRaw(o);case PacketType_1.PacketType.BYTES:case PacketType_1.PacketType.SHORTS:case PacketType_1.PacketType.VARINT:case PacketType_1.PacketType.DELTAS:return n.decodeSigned(e,o);case PacketType_1.PacketType.UBYTES:case PacketType_1.PacketType.USHORTS:case PacketType_1.PacketType.UVARINT:return n.decodeUnsigned(e,o);case PacketType_1.PacketType.FLOATS:case PacketType_1.PacketType.DOUBLES:return n.decodeFloats(e,o);case PacketType_1.PacketType.STRINGS_ASCII:case PacketType_1.PacketType.STRINGS_UTF16:return n.decodeStrings(e,o);case PacketType_1.PacketType.BOOLEANS:return n.decodeBooleans(o,a);case PacketType_1.PacketType.HEX:return n.decodeHex(o);case PacketType_1.PacketType.ENUMS:if(!r)throw new Error("ENUMS requires an EnumPackage");return[...t].map(e=>{if(e>=r.values.length)throw new Error(`Enum index ${e} is out of range`);return r.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,a,r,n={},o=loadNativeCore()){if(e!==PacketType_1.PacketType.ENUMS)o.validateEncoded(e,buffer(t),a,r,n.compressed??!1,n.batched??!1,n.maxBatchSize);else{if(!n.enumData)throw new Error("ENUMS requires an EnumPackage");o.validateEnum(buffer(t),n.enumData.values.length,a,r)}}function encodeNativeObject(e,t,a=loadNativeCore()){if(t.length!==e.types.length)throw new Error("Object field count does not match schema");let r=0;const n=e.types.map((n,o)=>encodeNative(n,t[o],n===PacketType_1.PacketType.ENUMS?e.enumData?.[r++]:void 0,a));return a.frameObject(n)}function decodeNativeObject(e,t,a=loadNativeCore()){const r=a.unframeObject(buffer(t),e.types.length);let n=0;return r.map((t,r)=>decodeNative(e.types[r],t,e.dataMaxes[r],e.types[r]===PacketType_1.PacketType.ENUMS?e.enumData?.[n++]:void 0,a))}function validateNativeObject(e,t,a=loadNativeCore()){a.validateObject(buffer(t),[...e.types],[...e.dataMins],[...e.dataMaxes],(e.enumData??[]).map(e=>e.values.length))}function encodeNativeBatch(e,t,a=loadNativeCore()){return a.encodeBatch(e.map(buffer),t)}function decodeNativeBatch(e,t,a=0,r,n=loadNativeCore()){const o=Number.isFinite(a)&&a>0?a:0;return n.decodeBatch(buffer(e),t,o,r)}function deflateNative(e,t=loadNativeCore()){return t.deflateRaw(buffer(e))}function inflateNative(e,t,a=loadNativeCore()){return a.inflateRaw(buffer(e),t)}
|
package/dist/ts/ws/Connection.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2026 Lily (liwybloc)
|
|
3
|
-
* License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
|
|
4
|
-
* See LICENSE for personal, non-commercial license terms.
|
|
5
|
-
*/
|
|
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;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)}raw_onmessage(e){this._on("message",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={}));
|