sonic-ws 1.3.2 → 2.0.0-fix

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.
Files changed (75) hide show
  1. package/LICENSE +56 -196
  2. package/README.md +88 -17
  3. package/bundled/bundle.js +6 -0
  4. package/bundled/bundle.wasm +0 -0
  5. package/dist/{index.d.ts → ts/index.d.ts} +9 -2
  6. package/dist/{index.js → ts/index.js} +10 -11
  7. package/dist/ts/native/wrapper.d.ts +64 -0
  8. package/dist/ts/native/wrapper.js +7 -0
  9. package/dist/ts/version.d.ts +16 -0
  10. package/dist/ts/version.js +7 -0
  11. package/dist/{ws → ts/ws}/Connection.d.ts +8 -2
  12. package/dist/{ws → ts/ws}/Connection.js +3 -2
  13. package/dist/{ws → ts/ws}/PacketProcessor.d.ts +8 -2
  14. package/dist/{ws → ts/ws}/PacketProcessor.js +4 -3
  15. package/dist/{ws → ts/ws}/client/core/ClientCore.d.ts +8 -2
  16. package/dist/ts/ws/client/core/ClientCore.js +7 -0
  17. package/dist/{ws → ts/ws}/client/node/ClientNode.d.ts +8 -2
  18. package/dist/ts/ws/client/node/ClientNode.js +7 -0
  19. package/dist/ts/ws/debug/DebugServer.d.ts +17 -0
  20. package/dist/ts/ws/debug/DebugServer.js +7 -0
  21. package/dist/{ws → ts/ws}/packets/PacketType.d.ts +9 -3
  22. package/dist/{ws → ts/ws}/packets/PacketType.js +3 -2
  23. package/dist/{ws → ts/ws}/packets/Packets.d.ts +8 -5
  24. package/dist/ts/ws/packets/Packets.js +7 -0
  25. package/dist/{ws → ts/ws}/server/SonicWSConnection.d.ts +8 -2
  26. package/dist/ts/ws/server/SonicWSConnection.js +7 -0
  27. package/dist/{ws → ts/ws}/server/SonicWSServer.d.ts +12 -3
  28. package/dist/ts/ws/server/SonicWSServer.js +7 -0
  29. package/dist/{ws → ts/ws}/util/BufferUtil.d.ts +8 -2
  30. package/dist/{ws → ts/ws}/util/BufferUtil.js +3 -2
  31. package/dist/ts/ws/util/StringUtil.d.ts +13 -0
  32. package/dist/ts/ws/util/StringUtil.js +7 -0
  33. package/dist/{ws → ts/ws}/util/enums/EnumHandler.d.ts +8 -2
  34. package/dist/{ws → ts/ws}/util/enums/EnumHandler.js +3 -2
  35. package/dist/ts/ws/util/enums/EnumType.d.ts +12 -0
  36. package/dist/{ws → ts/ws}/util/enums/EnumType.js +4 -3
  37. package/dist/ts/ws/util/packets/BatchHelper.d.ts +11 -0
  38. package/dist/ts/ws/util/packets/BatchHelper.js +7 -0
  39. package/dist/ts/ws/util/packets/CompressionUtil.d.ts +18 -0
  40. package/dist/ts/ws/util/packets/CompressionUtil.js +7 -0
  41. package/dist/ts/ws/util/packets/HashUtil.d.ts +12 -0
  42. package/dist/{ws → ts/ws}/util/packets/HashUtil.js +3 -2
  43. package/dist/ts/ws/util/packets/JSONUtil.d.ts +12 -0
  44. package/dist/ts/ws/util/packets/JSONUtil.js +7 -0
  45. package/dist/ts/ws/util/packets/PacketHolder.d.ts +11 -0
  46. package/dist/{ws → ts/ws}/util/packets/PacketHolder.js +4 -3
  47. package/dist/{ws → ts/ws}/util/packets/PacketUtils.d.ts +8 -2
  48. package/dist/ts/ws/util/packets/PacketUtils.js +7 -0
  49. package/dist/ts/ws/util/packets/RateHandler.d.ts +11 -0
  50. package/dist/{ws → ts/ws}/util/packets/RateHandler.js +3 -2
  51. package/package.json +14 -10
  52. package/dist/version.d.ts +0 -10
  53. package/dist/version.js +0 -6
  54. package/dist/ws/client/core/ClientCore.js +0 -6
  55. package/dist/ws/client/node/ClientNode.js +0 -6
  56. package/dist/ws/debug/DebugServer.d.ts +0 -11
  57. package/dist/ws/debug/DebugServer.js +0 -6
  58. package/dist/ws/packets/PacketProcessors.d.ts +0 -17
  59. package/dist/ws/packets/PacketProcessors.js +0 -6
  60. package/dist/ws/packets/Packets.js +0 -6
  61. package/dist/ws/server/SonicWSConnection.js +0 -6
  62. package/dist/ws/server/SonicWSServer.js +0 -6
  63. package/dist/ws/util/StringUtil.d.ts +0 -9
  64. package/dist/ws/util/StringUtil.js +0 -6
  65. package/dist/ws/util/enums/EnumType.d.ts +0 -6
  66. package/dist/ws/util/packets/BatchHelper.d.ts +0 -5
  67. package/dist/ws/util/packets/BatchHelper.js +0 -6
  68. package/dist/ws/util/packets/CompressionUtil.d.ts +0 -39
  69. package/dist/ws/util/packets/CompressionUtil.js +0 -6
  70. package/dist/ws/util/packets/HashUtil.d.ts +0 -6
  71. package/dist/ws/util/packets/JSONUtil.d.ts +0 -6
  72. package/dist/ws/util/packets/JSONUtil.js +0 -6
  73. package/dist/ws/util/packets/PacketHolder.d.ts +0 -5
  74. package/dist/ws/util/packets/PacketUtils.js +0 -6
  75. package/dist/ws/util/packets/RateHandler.d.ts +0 -5
@@ -0,0 +1,18 @@
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
+ * Copyright (c) 2026 Lily (liwybloc)
8
+ * License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
9
+ * See LICENSE for personal, non-commercial license terms.
10
+ */
11
+ /** Utilities still required by schema serialization and the connection handshake. */
12
+ export declare const MAX_BYTE = 255;
13
+ export declare const MAX_UVARINT: number;
14
+ export declare const EMPTY_UINT8: Uint8Array<ArrayBuffer>;
15
+ export declare const compressBools: (values: boolean[]) => number;
16
+ export declare const decompressBools: (byte: number) => boolean[];
17
+ export declare function convertVarInt(value: number): number[];
18
+ export declare function readVarInt(data: ArrayLike<number>, offset: number): [number, 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_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_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,12 @@
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
+ * Copyright (c) 2026 Lily (liwybloc)
8
+ * License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
9
+ * See LICENSE for personal, non-commercial license terms.
10
+ */
11
+ export declare function setHashFunc(use64Bit: boolean): void;
12
+ export declare function hashValue(value: any): bigint | number;
@@ -1,6 +1,7 @@
1
1
  /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
2
+ * Copyright (c) 2026 Lily (liwybloc)
3
+ * License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
4
+ * See LICENSE for personal, non-commercial license terms.
4
5
  */
5
6
 
6
7
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.setHashFunc=function(e){o=e?n:r},exports.hashValue=function(e){return o(e)};const e=1099511628211n,t=(1n<<64n)-1n,n=n=>{let r=14695981039346656037n;const o=n=>{if(null===n)return r^=0n,void(r=r*e&t);const l=typeof n;if("number"===l)return r^=BigInt(Math.trunc(n)),void(r=r*e&t);if("string"!==l){if("boolean"===l)return r^=n?1n:0n,void(r=r*e&t);if(Array.isArray(n))for(let e=0;e<n.length;e++)o(n[e]);else if("object"===l){const l=Object.keys(n).sort();for(let s=0;s<l.length;s++){const i=l[s];for(let n=0;n<i.length;n++)r^=BigInt(i.charCodeAt(n)),r=r*e&t;o(n[i])}}}else for(let o=0;o<n.length;o++)r^=BigInt(n.charCodeAt(o)),r=r*e&t};return o(n),r},r=e=>{let t=2166136261;const n=e=>{if(null===e)return void(t^=0);const r=typeof e;if("number"===r)return t^=0|e,void(t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24));if("string"!==r)if("boolean"!==r){if(Array.isArray(e))for(let t=0;t<e.length;t++)n(e[t]);else if("object"===r){const r=Object.keys(e).sort();for(let o=0;o<r.length;o++){const l=r[o];for(let e=0;e<l.length;e++)t^=l.charCodeAt(e),t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24);n(e[l])}}}else t^=e?1:0;else for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24)};return n(e),t>>>0};let o=n;
@@ -0,0 +1,12 @@
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
+ * Copyright (c) 2026 Lily (liwybloc)
8
+ * License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
9
+ * See LICENSE for personal, non-commercial license terms.
10
+ */
11
+ export declare const compressJSON: (value: any) => Uint8Array<ArrayBuffer>;
12
+ export declare const decompressJSON: (bytes: Uint8Array) => any;
@@ -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.decompressJSON=exports.compressJSON=void 0;const r=require("../BufferUtil"),e=r=>Array.from({length:8},(e,t)=>!!(r&1<<7-t));function t(r){if(!Number.isInteger(r)||r<0)throw new Error(`Invalid JSON variable integer: ${r}`);const e=[];do{let t=127&r;(r>>>=7)>0&&(t|=128),e.push(t)}while(r>0);return e}function n(r,e){let t=0,n=0;for(;;){if(e>=r.length||n>28)throw new Error("Invalid JSON variable integer");const s=r[e++];if(t+=(127&s)<<n,!(128&s))return[e,t];n+=7}}var s;!function(r){r[r.NULL=0]="NULL",r[r.BOOL=1]="BOOL",r[r.INT=2]="INT",r[r.FLOAT=3]="FLOAT",r[r.STRING=4]="STRING",r[r.ARRAY=5]="ARRAY",r[r.OBJECT=6]="OBJECT"}(s||(s={}));const o=r=>{const e=(new TextEncoder).encode(r);return[...t(e.length),...e]},a=(r,e)=>{const[t,s]=n(r,e);return{value:(new TextDecoder).decode(r.subarray(t,t+s)),length:t+s-e}};exports.compressJSON=e=>{const n=[],a=[],u=[],c=r=>{switch(null===r?"null":Array.isArray(r)?"array":typeof r){case"null":u.push(s.NULL);break;case"boolean":u.push(s.BOOL),n.push(r);break;case"number":Number.isInteger(r)?(u.push(s.INT),a.push(...t((r=>r<<1^r>>31)(r)))):(u.push(s.FLOAT),a.push(...function(r){if(Number.isNaN(r))return[127,128,0,1];const e=r<0?1:0;if(0===(r=Math.abs(r)))return[0,0,0,0];const t=Math.floor(Math.log2(r));if(!Number.isFinite(r)||t>127||t<-126)return[e?255:127,128,0,0];const n=(e<<31|t+127<<23|8388607&Math.round((r/2**t-1)*2**23))>>>0;return[n>>>24,n>>>16&255,n>>>8&255,255&n]}(r)));break;case"string":u.push(s.STRING),a.push(...o(r));break;case"array":u.push(s.ARRAY),a.push(...t(r.length));for(const e of r)c(e);break;case"object":{u.push(s.OBJECT);const e=Object.keys(r);a.push(...t(e.length));for(const t of e)a.push(...o(t)),c(r[t]);break}default:throw new Error("Unsupported type")}};c(e);const l=n.length?(0,r.splitArray)(n,8).map(r=>r.reduce((r,e,t)=>r|Number(e)<<7-t,0)):[],h=(r=>{let e="";for(const t of r)e+=t.toString(2).padStart(3,"0");return(r=>new Uint8Array(r.match(/.{1,8}/g)?.map(r=>parseInt(r.padEnd(8,"0"),2))??[]))(e)})(u),p=[...t(l.length),...t(h.length)];return Uint8Array.from([...p,...l.flat(),...h,...a])},exports.decompressJSON=r=>{let t=0;const[o,u]=n(r,t);t=o;const[c,l]=n(r,t);t=c;const h=[];for(let n=0;n<u;n++)h.push(...e(r[t++]));let p=0;const i=r.subarray(t,t+l);t+=l;const f=((r,e)=>{const t=(r=>Array.from(r,r=>r.toString(2).padStart(8,"0")).join(""))(r),n=[];for(let r=0;r<e;r++)n.push(parseInt(t.slice(3*r,3*r+3),2));return n})(i,8*i.length/3);let N=0;const O=e=>{if(e>500)throw new Error("JSON array too deep.");const o=f[N++];switch(o){case s.NULL:return null;case s.BOOL:return h[p++];case s.INT:{const[e,s]=n(r,t);return t=e,(u=s)>>>1^-(1&u)}case s.FLOAT:{const e=function(r){const e=(r[0]<<24|r[1]<<16|r[2]<<8|r[3])>>>0,t=e>>>23&255,n=(0===t?0:1)+(8388607&e)/2**23,s=255===t?0===n?1/0:NaN:n*2**(0===t?-126:t-127);return e>>>31?-s:s}(Array.from(r.subarray(t,t+4)));return t+=4,e}case s.STRING:{const{value:e,length:n}=a(r,t);return t+=n,e}case s.ARRAY:{const[s,o]=n(r,t);t=s;const a=[];for(let r=0;r<o;r++)a.push(O(e+1));return a}case s.OBJECT:{const[s,o]=n(r,t);t=s;const u={};for(let n=0;n<o;n++){const{value:n,length:s}=a(r,t);t+=s,u[n]=O(e+1)}return u}default:throw new Error(`Unknown type ${o}`)}var u};return O(0)};
@@ -0,0 +1,11 @@
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
+ * Copyright (c) 2026 Lily (liwybloc)
8
+ * License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
9
+ * See LICENSE for personal, non-commercial license terms.
10
+ */
11
+ export {};
@@ -1,6 +1,7 @@
1
1
  /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
2
+ * Copyright (c) 2026 Lily (liwybloc)
3
+ * License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
4
+ * See LICENSE for personal, non-commercial license terms.
4
5
  */
5
6
 
6
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.PacketHolder=void 0;exports.PacketHolder=class{key;keys;tags;packetMap;packets;constructor(t){this.key=1,this.keys={},this.tags={},this.packetMap={},t&&this.holdPackets(t)}createKey(t){this.keys[t]=this.key,this.tags[this.key]=t,this.key++}holdPackets(t){this.packets=t;for(const e of t)this.createKey(e.tag),this.packetMap[e.tag]=e}getKey(t){if(!(t 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 in this.packetMap))throw new Error("Unknown packet tag: "+t);return this.packetMap[t]}hasKey(t){return t in this.tags}hasTag(t){return t in this.keys}getKeys(){return this.keys}getTagMap(){return this.tags}getTags(){return Object.values(this.tags)}getPackets(){return this.packets}serialize(){return this.packets.map(t=>t.serialize()).flat()}};
7
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.PacketHolder=void 0,exports.PacketHolder=class{key;keys;tags;packetMap;packets;constructor(t){this.key=1,this.keys={},this.tags={},this.packetMap={},t&&this.holdPackets(t)}createKey(t){this.keys[t]=this.key,this.tags[this.key]=t,this.key++}holdPackets(t){this.packets=t;for(const e of t)this.createKey(e.tag),this.packetMap[e.tag]=e}getKey(t){if(!(t 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 in this.packetMap))throw new Error("Unknown packet tag: "+t);return this.packetMap[t]}hasKey(t){return t in this.tags}hasTag(t){return t in this.keys}getKeys(){return this.keys}getTagMap(){return this.tags}getTags(){return Object.values(this.tags)}getPackets(){return this.packets}serialize(){return this.packets.map(t=>t.serialize()).flat()}};
@@ -1,6 +1,12 @@
1
1
  /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
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
+ * Copyright (c) 2026 Lily (liwybloc)
8
+ * License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
9
+ * See LICENSE for personal, non-commercial license terms.
4
10
  */
5
11
  import { ConvertType, Packet, ValidatorFunction } from "../../packets/Packets";
6
12
  import { PacketType } from "../../packets/PacketType";
@@ -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=async function e(a,o,i,s,c,l=!1){const f=a.getKey(o),p=a.getPacket(o);return async function(t,a,n,r,o,i,s){if(t[0]&&!i)return new Promise(e=>t[1].push([e,r,o]));t[0]=!0;const c=await s();if(t[1].length>0){const[r,o,i]=t[1].shift();queueMicrotask(async()=>{r(await e(a,o,i,t,n,!0))})}else t[0]=!1;return c}(s,a,c,o,i,l,async()=>{if(p.rereference){if(-1===c)throw new Error("Cannot send a re-referenced packet from the server-wide sender!");const e=(0,r.hashValue)(i);if(p.lastSent[c]===e)return[f,n.EMPTY_UINT8,p];p.lastSent[c]=e}if(p.autoFlatten)i=u(i[0]);else{if(i.length>p.maxSize)throw new Error(`Packet "${o}" only allows ${p.maxSize} values!`);if(i.length<p.minSize)throw new Error(`Packet "${o}" requires at least ${p.minSize} values!`)}if(p.object){if(i=i.map(e=>Array.isArray(e)?e:[e]),!p.autoFlatten){const e=p.dataMin,t=p.dataMax;for(let a=0;a<e.length;a++){if(i[a].length<e[a])throw new Error(`Section ${a+1} of packet "${o}" requires at least ${e[a]} values!`);if(i[a].length>t[a])throw new Error(`Section ${a+1} of packet "${o}" only allows ${t[a]} values!`)}}}else if(p.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 p.processSend(i):n.EMPTY_UINT8;return[f,e,p]})},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=l,exports.CreateObjPacket=function(a){let{tag:n,types:r=[],dataMaxes:l,dataMins:u,noDataRange:f=!1,dontSpread:p=!1,autoFlatten:h=!1,validator:y=null,dataBatching:m=0,maxBatchSize:d=10,rateLimit:w=0,enabled:g=!0,async:k=!1,gzipCompression:P=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");for(const e of r)if(o(e))throw new Error(`Invalid packet type in "${n}" packet: ${e}`);f?(l=Array.from({length:r.length}).map(()=>i),u=Array.from({length:r.length}).map(()=>0)):(null==l?l=Array.from({length:r.length}).map(()=>1):Array.isArray(l)||(l=Array.from({length:r.length}).map(()=>l)),null==u?u=Array.from({length:r.length}).map((e,t)=>l[t]):Array.isArray(u)||(u=Array.from({length:r.length}).map(()=>u)));const E=l.map(s),S=u.map((e,a)=>r[a]==t.PacketType.NONE?0:c(e,E[a])),x=new e.PacketSchema(!0,r,k,S,E,w,p,h,!1,m,d,P);return new e.Packet(n,x,y,g,!1)},exports.CreateEnumPacket=function(e){const{tag:t,enumData:a,dataMax:n=1,dataMin:r=0,noDataRange:o=!1,dontSpread:i=!1,validator:s=null,dataBatching:c=0,maxBatchSize:u=10,rateLimit:f=0,enabled:p=!0,async:h=!1}=e;return l({tag:t,type:a,dataMax:n,dataMin:r,noDataRange:o,dontSpread:i,validator:s,dataBatching:c,maxBatchSize:u,rateLimit:f,enabled:p,async:h})},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=u,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");function o(e){return!(("number"==typeof e&&e in t.PacketType||e instanceof a.EnumPackage)&&e!=t.PacketType.KEY_EFFECTIVE)}const i=2048383;function s(e){return e<0?(console.warn("Having a data maximum below 0 does not do anything!"),0):e>i?(console.warn(`Only ${i} values can be sent on a type! Uhh make an issue if you want to send more.`),i):e}function c(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 l(a){let{tag:n,type:r=t.PacketType.NONE,dataMax:l=1,dataMin:u=1,noDataRange:f=!1,dontSpread:p=!1,validator:h=null,dataBatching:y=0,maxBatchSize:m=10,rateLimit:d=0,enabled:w=!0,async:g=!1,gzipCompression:k=r==t.PacketType.JSON,rereference:P=!1}=a;if(!n)throw new Error("Tag not selected!");if(f?(u=P?1:0,l=i):null==u&&(u=r==t.PacketType.NONE?0:l),P&&0==u)throw new Error("Rereference cannot be true if the dataMin is 0");if(o(r))throw new Error(`Invalid packet type: ${r}`);const E=new e.PacketSchema(!1,r,g,c(u,l),s(l),d,p,!1,P,y,m,k);return new e.Packet(n,E,h,w,!1)}function u(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]))??[]}
@@ -0,0 +1,11 @@
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
+ * Copyright (c) 2026 Lily (liwybloc)
8
+ * License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
9
+ * See LICENSE for personal, non-commercial license terms.
10
+ */
11
+ export {};
@@ -1,6 +1,7 @@
1
1
  /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
2
+ * Copyright (c) 2026 Lily (liwybloc)
3
+ * License-Identifier: LicenseRef-Lily-Personal-NonCommercial-2026
4
+ * See LICENSE for personal, non-commercial license terms.
4
5
  */
5
6
 
6
7
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.RateHandler=void 0;const t=require("../../Connection");exports.RateHandler=class{rates={};limits={};setInterval;socket;constructor(t){this.setInterval=t.setInterval,this.socket=t.socket}start(){0!=Object.keys(this.rates).length&&this.setInterval(()=>{for(const t in this.rates)this.rates[t]=0},1e3)}registerRate(t,e){0!=e&&(this.rates[t]=0,this.limits[t]=e)}registerAll(t,e){const s=t.getPackets();for(const r of s)this.registerRate(e+t.getKey(r.tag),r.rateLimit)}trigger(e){return e in this.rates&&++this.rates[e]>this.limits[e]&&(this.socket.close(t.CloseCodes.RATELIMIT),!0)}subtract(t){t in this.rates&&this.rates[t]--}};
package/package.json CHANGED
@@ -1,17 +1,20 @@
1
1
  {
2
2
  "name": "sonic-ws",
3
- "version": "1.3.2",
3
+ "version": "2.0.0-fix",
4
4
  "description": "Ultra-lightweight, high-performance, and bandwidth efficient websocket library",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
5
+ "main": "dist/ts/index.js",
6
+ "types": "dist/ts/index.d.ts",
7
7
  "scripts": {
8
8
  "webpack": "webpack --mode production",
9
- "build_web": "rimraf ./html && tsc --moduleResolution nodenext --module nodenext --outDir ./html src/ws/client/browser/ClientBrowser.ts && npm run webpack",
10
- "build_node": "rimraf ./dist && tsc -d",
11
- "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",
12
- "test_web": "npm run build && node test-site/server.mjs",
13
- "test_node": "npm run build_node && node test.mjs",
14
- "publish": "npm run build && cp ./bundled/SonicWS_bundle.js ./release/SonicWS_bundle.js"
9
+ "build_wasm_browser": "wasm-pack build --release --target bundler --out-dir ../ts/native/wasm/pkg --out-name sonic_ws_core ./src/core --features wasm --no-default-features",
10
+ "build_wasm_node": "wasm-pack build --release --target nodejs --out-dir ../ts/native/wasm/node --out-name sonic_ws_core ./src/core --features wasm --no-default-features",
11
+ "build_wasm": "npm run build_wasm_browser && npm run build_wasm_node",
12
+ "build_web": "npm run build_wasm_browser && tsc --moduleResolution nodenext --module nodenext --outDir ./dist/ts src/ts/ws/client/browser/ClientBrowser.ts && cpy \"src/ts/native/wasm/pkg/*\" dist/ts/native/wasm/pkg --flat && npm run webpack",
13
+ "build_node": "npm run build_wasm && rimraf ./dist/ts && tsc -d && cpy \"src/ts/native/wasm/node/*\" dist/ts/native/wasm/node --flat",
14
+ "build": "npm run build_node && npm run build_web && rimraf ./dist/ts/ws/client/browser && rimraf ./dist/ts/ws/debug/DebugClient.d.ts && rimraf ./dist/ts/ws/debug/DebugClient.js && node minify",
15
+ "test_web": "npm run build && node tests/test_web.mjs",
16
+ "test_node": "npm --prefix src/core/tests/typescript run build:native && npm run build_node && node tests/test_node.mjs",
17
+ "publish": "npm run build && node minify && rimraf ./release/SonicWS_bundle.js ./release/SonicWS_core.wasm && cp ./bundled/bundle.js ./release/bundle.js && cp ./bundled/bundle.wasm ./release/bundle.wasm && sleep 1"
15
18
  },
16
19
  "repository": {
17
20
  "type": "git",
@@ -22,7 +25,7 @@
22
25
  },
23
26
  "homepage": "https://github.com/liwybloc/sonic-ws#readme",
24
27
  "author": "lily",
25
- "license": "Apache-2.0",
28
+ "license": "LicenseRef-Lily-Personal-NonCommercial-2026",
26
29
  "dependencies": {
27
30
  "open": "^11.0.0",
28
31
  "ws": "^8.18.2"
@@ -33,6 +36,7 @@
33
36
  "cpy-cli": "^5.0.0",
34
37
  "esbuild-loader": "^4.4.2",
35
38
  "form-data": "^4.0.4",
39
+ "playwright": "^1.61.1",
36
40
  "rimraf": "^6.0.1",
37
41
  "terser": "^5.46.0",
38
42
  "ts-loader": "^9.5.2",
package/dist/version.d.ts DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
- /** Current protocol version */
6
- export declare const VERSION = 20;
7
- /** Server data suffix */
8
- export declare const SERVER_SUFFIX = "SWS";
9
- /** Server data suffix in array */
10
- export declare const SERVER_SUFFIX_NUMS: number[];
package/dist/version.js DELETED
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- 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=20,exports.SERVER_SUFFIX="SWS",exports.SERVER_SUFFIX_NUMS=(0,e.processCharCodes)(exports.SERVER_SUFFIX);
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.SonicWSCore=void 0;const e=require("../../util/packets/PacketHolder"),t=require("../../util/packets/CompressionUtil"),s=require("../../util/packets/PacketUtils"),i=require("../../../version"),a=require("../../packets/Packets"),r=require("../../util/packets/BatchHelper"),n=require("../../util/BufferUtil"),c=require("../../Connection"),o=require("../../util/StringUtil");class h extends c.Connection{preListen;clientPackets=new e.PacketHolder;serverPackets=new e.PacketHolder;pastKeys=!1;readyListeners=[];bufferHandler;_timers={};asyncData={};asyncMap={};constructor(e,t,s,i){super(e,-1,"LocalSocket",s,i),this.socket=e,this.preListen={},this.invalidPacket=this.invalidPacket.bind(this),this.serverKeyHandler=this.serverKeyHandler.bind(this),this.messageHandler=this.messageHandler.bind(this),this._on("message",this.serverKeyHandler),this._on("close",()=>{this.callMiddleware("onStatusChange",WebSocket.CLOSED);for(const[e,t,s]of Object.values(this._timers))this.clearTimeout(e),s&&t(!0);for(const e of this.clientPackets.getPackets())delete e.lastSent[0];for(const e of this.serverPackets.getPackets())delete e.lastReceived[0]}),this.bufferHandler=t}reading=!1;readQueue=[];async serverKeyHandler(e){if(this.reading)return this.readQueue.push(e);this.reading=!0;const s=await this.bufferHandler(e);if(s.length<3||(0,o.as8String)(s.slice(0,3))!=i.SERVER_SUFFIX)throw this.close(1e3),new Error("The server requested is not a Sonic WS server.");const r=s[3];if(r!=i.VERSION)throw this.close(1e3),new Error(`Version mismatch: ${r>i.VERSION?"client":"server"} is outdated (server: ${r}, client: ${i.VERSION})`);const n=await(0,t.decompressGzip)(s.subarray(4,s.length)),[c,h]=(0,t.readVarInt)(n,0);this.id=h;const[l,d]=(0,t.readVarInt)(n,c),u=n.subarray(l,l+d);this.clientPackets.holdPackets(a.Packet.deserializeAll(u,!0));const k=n.subarray(l+d,n.length);this.serverPackets.holdPackets(a.Packet.deserializeAll(k,!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,i,a){const r=this.listeners[t];if(!r)return console.warn("Warn: No listener for packet "+t);await this.enqueuePacket(e,r,s,i,a),await this.callMiddleware("onReceive_post",t,"string"==typeof e?[e]:e[0])}isAsync(e){return this.asyncMap[e]}async enqueuePacket(e,t,i,a,r){await(0,s.listenPacket)(e,t,this.invalidPacket),await this.triggerNextPacket(i,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,n,c;if(i?(c=this.asyncData[t],a=c[0],n=c[1]):(a=this.listenLock,n=this.packetQueue),a)return void n.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,n,i,c);if(0==h.dataBatching){const e=h.lastReceived[0]=await h.listen(s,null);return void this.listenPacket(e,o,n,i,c)}const l=await r.BatchHelper.unravelBatch(h,s,null);if("string"==typeof l)return this.invalidPacket(l);l.forEach(e=>this.listenPacket(e,o,n,i,c))}async messageHandler(e){const t=await this.bufferHandler(e);t.length<1||await this.dataHandler(t)}listen(e,t){this.serverPackets.hasTag(e)?(this.listeners[e]??=[]).push(t):console.log("Tag is not available on server: "+e)}raw_onsend(e){this.listeners.send.push(e)}sendQueue=[!1,[],void 0];async send(e,...t){if(await this.callMiddleware("onSend_pre",e,t,Date.now(),performance.now()))return;const[i,a,r]=await(0,s.processPacket)(this.clientPackets,e,t,this.sendQueue,0);0==r.dataBatching?this.raw_send((0,n.toPacketBuffer)(i,a)):this.batcher.batchPacket(i,a),await this.callMiddleware("onSend_post",e,a,a.length)}on_ready(e){this.pastKeys?e():this.readyListeners.push(e)}on_close(e){this._on("close",e)}on(e,t){if(this.socket.readyState!==WebSocket.OPEN)return this.preListen[e]||(this.preListen[e]=[]),void this.preListen[e].push(t);this.listen(e,t)}}exports.SonicWSCore=h;
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- var e=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SonicWS=void 0;const r=e(require("ws")),o=require("../core/ClientCore");class t extends o.SonicWSCore{constructor(e,o){const t=new r.default.WebSocket(e,o);super(t,e=>Promise.resolve(new Uint8Array(e)),t.on.bind(t),t.removeEventListener.bind(t))}}exports.SonicWS=t;
@@ -1,11 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
- import { SonicWSServer } from "../server/SonicWSServer";
6
- export declare class DebugServer {
7
- constructor(host: SonicWSServer, data: {
8
- port?: number;
9
- password?: string;
10
- });
11
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- var e=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.DebugServer=void 0;const t=require("../Connection"),o=require("../packets/PacketType"),s=require("../server/SonicWSServer"),n=require("../util/packets/PacketUtils"),a=e(require("http")),c=e(require("open")),d=require("../util/enums/EnumHandler");exports.DebugServer=class{constructor(e,i){if(i.port??=0,i.password??="",i.port<0||i.port>=65536)throw new Error("Port out of range!");const l=a.default.createServer((e,t)=>{t.writeHead(200,{"Content-Type":"text/html"}),t.end('<!doctypehtml><meta charset=UTF-8><script src=https://cdn.jsdelivr.net/gh/liwybloc/sonic-ws/bundled/SonicWS_bundle.js><\/script><title>SonicWS Debug Menu</title><style>body{margin:0;font-family:Inter,Arial,sans-serif;background:#0f1115;color:#e6e6e6;height:100vh;display:flex}#sidebar{width:260px;background:#141821;border-right:1px solid #1f2533;display:flex;flex-direction:column}#sidebar-header{padding:16px;font-weight:600;font-size:18px;border-bottom:1px solid #1f2533;cursor:pointer;transition:color .2s}#sidebar-header:hover{color:#ddd}#socket-list{flex:1;overflow-y:auto}.socket-item{padding:10px 14px;cursor:pointer;border-bottom:1px solid #1f2533}.socket-item:hover{background:#1b2030}.socket-item.active{background:#22294a}.socket-id{font-size:12px;opacity:.7}#main{flex:1;display:flex;flex-direction:column}#main-header{padding:17px;border-bottom:1px solid #1f2533;display:flex;justify-content:space-between;align-items:center}#stats{display:flex;gap:20px;font-size:13px}#packets{flex:1;overflow-y:auto;padding:12px}.packet{background:#1a1f2e;border-radius:6px;padding:6px 8px;margin-bottom:4px;font-size:12px;cursor:pointer}.packet.sent{border-left:3px solid #3cff7a}.packet.recv{border-left:3px solid #ff5a5a}.packet-details{display:none;margin-top:4px;opacity:.75;font-size:11px}.packet.expanded .packet-details{display:block}button{background:0 0}</style><div id=sidebar><div id=sidebar-header>Sonic WS Debug Menu</div><div id=socket-list></div></div><div id=main><div id=main-header><button id=close-socket style=display:none>❌</button><div id=socket-title>Server Home</div><div id=stats></div></div><div id=home style=display:block;padding:16px><h2>Server Dashboard</h2><div id=global-stats style=margin-bottom:16px></div><h3>Connection Logs</h3><ul id=connection-logs style=max-height:200px;overflow-y:auto;padding-left:16px></ul><div style=margin-top:16px><table style=width:100%;border-collapse:collapse><thead><tr><th style="border-bottom:1px solid #444;text-align:left">Socket ID<th style="border-bottom:1px solid #444;text-align:left">Name<th style="border-bottom:1px solid #444;text-align:left">Status<tbody id=connection-table></table></div></div><div id=packets></div></div><script>const socketList=document.getElementById("socket-list"),packetsDiv=document.getElementById("packets"),socketTitle=document.getElementById("socket-title"),debugTitle=document.getElementById("sidebar-header"),statsDiv=document.getElementById("stats"),home=document.getElementById("home"),closeSocketBtn=document.getElementById("close-socket");debugTitle.onclick=()=>{null!==activeId&&(activeId=null,packetsDiv.style.display="none",home.style.display="block",closeSocketBtn.style.display="none",renderGlobalStats())};const globalStats={totalSockets:0,totalSent:0,totalRecv:0,totalSentBytes:0,totalRecvBytes:0,totalSaved:0,startTime:0};function formatMilliseconds(e){if(e<1)return"0.0s";const t=[{label:"week",value:6048e5},{label:"day",value:864e5},{label:"hour",value:36e5},{label:"minute",value:6e4}],s=[];for(const{label:o,value:n}of t){const t=Math.floor(e/n);t>0&&(s.push(t+" "+o+(1!==t?"s":"")),e-=t*n)}if(e>0||0===s.length){const t=(e/1e3).toFixed(1);s.push(t+"s")}if(1===s.length)return s[0];const o=s.pop();return s.join(", ")+" and "+o}const globalStatsDiv=document.getElementById("global-stats");function renderGlobalStats(){const e=globalStats,t=formatMilliseconds(Date.now()-e.startTime);globalStatsDiv.innerHTML="<div><strong>Total Sockets:</strong> "+e.totalSockets+"</div><div><strong>Total Sent Packets:</strong> "+e.totalSent+"</div><div><strong>Total Received Packets:</strong> "+e.totalRecv+"</div><div><strong>Total Sent Bytes:</strong> "+e.totalSentBytes+" B</div><div><strong>Total Received Bytes:</strong> "+e.totalRecvBytes+" B</div><div><strong>Total Bandwidth Saved:</strong> "+e.totalSaved+" B</div><div><strong>Uptime:</strong> "+t+"</div>"}function updateConnectionTable(){const e=document.getElementById("connection-table");e.innerHTML="",sockets.forEach((t=>{const s=document.createElement("tr");s.innerHTML="<td>"+t.id+"</td><td>"+t.name+\'</td><td style="color:\'+(t.el.style.color||"#0f0")+\'">\'+("#f00"===t.el.style.color?"Disconnected":"Connected")+"</td>",e.appendChild(s)}))}setInterval(renderGlobalStats,50),setInterval(updateConnectionTable,1e3);const sockets=new Map;let activeId=null;function selectSocket(e){activeId=e,[...socketList.children].forEach((t=>t.classList.toggle("active",t.dataset.id==e)));const t=sockets.get(e);socketTitle.textContent=t.name,packetsDiv.innerHTML="",t.packets.forEach((e=>packetsDiv.appendChild(e.el))),renderStats(t),home.style.display="none",packetsDiv.style.display="block",closeSocketBtn.style.display="block"}function renderStats(e){statsDiv.innerHTML="<div>Sent: "+e.sent+"</div><div>Recv: "+e.recv+"</div><div>Sent bytes: "+e.sentBytes+"</div><div>Recv bytes: "+e.recvBytes+"</div><div>Saved: "+e.saved+"</div>"}function addSocket(e,t){const s=document.createElement("div");s.className="socket-item",s.dataset.id=e,s.innerHTML="<div>"+t+\'</div><div class="socket-id">#\'+e+"</div>",s.onclick=()=>selectSocket(e),socketList.appendChild(s),sockets.set(e,{id:e,name:t,el:s,packets:[],sent:0,recv:0,sentBytes:0,recvBytes:0,saved:0})}function removeSocket(e,t,s,o){const n=sockets.get(e);if(!n)return console.error("Unknown socket!!",e);n.el.dataset.id=e+"-closed",n.el.onclick=()=>selectSocket(e+"-closed"),sockets.set(e+"-closed",n),sockets.delete(e),activeId==e&&(activeId=e+"-closed");const c=n.el.childNodes[0];c.style.color="#f00";let l=document.createElement("span");l.style.display="inline-block",l.style.width="10px",l.style.height="10px",l.style.borderRadius="50%",l.style.background="#ff5a5a",l.style.marginLeft="8px",c.appendChild(l);const a=document.createElement("li");a.textContent="Socket #"+e+" disconnected — Code: "+t+", Reason: "+s+", Closure Cause: "+o,document.getElementById("connection-logs").appendChild(a),requestAnimationFrame((()=>l.style.width="100%")),setTimeout((()=>{l.remove(),n.el.remove(),activeId==e+"-closed"&&(packetsDiv.style.display="none",home.style.display="block",closeSocketBtn.style.display="none")}),3e4)}function addPacket(e,t,s,o,n,c,l,a){const d=sockets.get(e);if(!d)return console.error("Unknown socket!!",e);const i=document.createElement("div");i.className="packet "+("sent"===t?"sent":"recv"),i.innerHTML="<div>"+s+("undefined"!==c?" — "+c:"")+\'</div><div class="packet-details">Raw Bytes: \'+o+"b (saved: ~"+n+"b)<br>Processed At: "+new Date(l).toISOString()+"<br>Processing Time: "+a.toFixed(2)+"ms</div>",i.onclick=()=>i.classList.toggle("expanded"),d.packets.push({el:i}),"sent"===t?(d.sent++,d.sentBytes+=o):(d.recv++,d.recvBytes+=o),d.saved+=n,activeId===e&&(packetsDiv.appendChild(i),renderStats(d))}function setStat(e,t){globalStats[Object.keys(globalStats)[e]]=t,null===activeId&&renderGlobalStats()}closeSocketBtn.onclick=()=>{null!==activeId&&ws.send("close",Number(activeId))};const ws=new SonicWS("ws://"+location.host);ws.on("connection",(e=>addSocket(e,"Socket "+e))),ws.on("disconnection",(([e,t],[s,o])=>removeSocket(e,t,s,o))),ws.on("nameChange",(([e],[t])=>{const s=sockets.get(e);if(!s)return console.error("Unknown socket!!",e);s.name=t,s.el.firstChild.textContent=t,activeId===e&&(socketTitle.textContent=t)})),ws.on("packet",(([e,t,s],[o],[n],[c],[l,a])=>{console.log("Received packet",{id:e,size:t,saved:s,dir:o,tag:n,values:c,time:l,processTime:a}),addPacket(e,o,n,t,s,c,l,a)})),ws.on("stats",(e=>{console.log("Received stats",e),e.forEach(((e,t)=>setStat(t,e)))})),ws.on("stat",((e,t)=>setStat(e,t)));const lastKnownPassword=localStorage.getItem("password"),empty=!localStorage.getItem("req");let usedPass="";ws.on_ready((()=>{empty?ws.send("password",""):ws.send("password",usedPass=lastKnownPassword??prompt("Please enter password"))})),ws.on_close((()=>{window.location.reload()})),ws.on("authenticated",(e=>{e?(localStorage.setItem("req",usedPass.length>0),localStorage.setItem("password",usedPass)):(localStorage.setItem("req",!0),localStorage.removeItem("password"),window.location.reload())}));<\/script>')}),r=(0,d.DefineEnum)("type",["sent","recv"]),p=new s.SonicWSServer({clientPackets:[(0,n.CreatePacket)({tag:"password",type:o.PacketType.STRINGS_UTF16}),(0,n.CreatePacket)({tag:"close",type:o.PacketType.UVARINT})],serverPackets:[(0,n.CreatePacket)({tag:"authenticated",type:o.PacketType.BOOLEANS}),(0,n.CreatePacket)({tag:"connection",type:o.PacketType.UVARINT}),(0,n.CreateObjPacket)({tag:"disconnection",types:[o.PacketType.UVARINT,o.PacketType.STRINGS],noDataRange:!0}),(0,n.CreateObjPacket)({tag:"nameChange",types:[o.PacketType.UVARINT,o.PacketType.STRINGS_UTF16],noDataRange:!0}),(0,n.CreateObjPacket)({tag:"packet",types:[o.PacketType.VARINT,r,o.PacketType.STRINGS_UTF16,o.PacketType.STRINGS_UTF16,o.PacketType.FLOATS],noDataRange:!0,dataBatching:50,maxBatchSize:0}),(0,n.CreatePacket)({tag:"stats",type:o.PacketType.UVARINT,noDataRange:!0,dontSpread:!0}),(0,n.CreatePacket)({tag:"stat",type:o.PacketType.UVARINT,dataMax:2})],websocketOptions:{server:l}}),v=new Proxy({totalSockets:0,totalSent:0,totalRecv:0,totalSentBytes:0,totalRecvBytes:0,totalSaved:0,startTime:Date.now()},{set(e,t,o){const s=String(t);return e[s]!==o&&(e[s]=o,p.broadcast("stat",Object.keys(v).indexOf(s),o)),!0}}),k={};p.on_connect(o=>{let s=!1;const n=o.send.bind(o);let a=[];o.send=async(e,...t)=>{console.log(s,e,t),s?n(e,...t):a.push([e,t])},o.send("stats",...Object.values(v)),e.connections.forEach(e=>{o.send("connection",e.id),o.send("nameChange",e.id,e.getName()),k[e.id]?.forEach(e=>{o.send("packet",...e)})}),o.on("password",e=>{i.password!=e?(n("authenticated",!1),setTimeout(()=>o.close(1008),1e3)):(s=!0,o.send("authenticated",!0),a.forEach(([e,t])=>n(e,...t)))}),o.on("close",o=>{s&&e.connectionMap[o]?.close(t.CloseCodes.MANUAL_SHUTDOWN)})});const u=[],g={},y=new TextEncoder,m=e=>y.encode(JSON.stringify(e)??"[]").length;e.addMiddleware(new class{onClientConnect(e){v.totalSockets++,k[e.id]=[],u.push(e),p.broadcast("connection",e.id);const t={},o={};e.addMiddleware(new class{onNameChange(t){p.broadcast("nameChange",e.id,t)}onSend_pre(e,o,s,n){t[e]??=[],t[e].push([o,n,s])}onSend_post(o,s,n){v.totalSentBytes+=n,v.totalSent++;const[a,c,d]=t[o].shift(),i=m(a)-n;v.totalSaved+=i;const l=[[e.id,n+1,i],r.wrap("sent"),o,JSON.stringify(a),[d,performance.now()-c]];k[e.id].push(l),p.broadcast("packet",...l)}onReceive_pre(e,t,s){v.totalRecvBytes+=s,v.totalRecv++,o[e]??=[],o[e].push([t,performance.now(),Date.now()])}onReceive_post(t,s){const[n,a,c]=o[t].shift(),d=m(s)-n.length;v.totalSaved+=d;const i=[[e.id,n.length+1,d],r.wrap("recv"),t,JSON.stringify(s),[c,performance.now()-a]];k[e.id].push(i),p.broadcast("packet",...i)}})}onClientDisconnect(e,o,s){v.totalSockets--,p.broadcast("disconnection",[e.id,o],[s?.toString()??"UNKNOWN",(0,t.getClosureCause)(o)]),delete k[e.id],u.splice(u.indexOf(e),1)}onPacketBroadcast_pre(e,t,...o){g[e]??=[],g[e].push([o,performance.now(),Date.now()])}onPacketBroadcast_post(e,t,o,s){const[n,a,c]=g[e].shift();t.recipients.forEach(t=>{u.includes(t)&&(t.callMiddleware("onSend_pre",e,n,c,a),t.callMiddleware("onSend_post",e,o,s))})}}),l.listen(i.port,()=>{const e=l.address();console.log(`SWS Debug server running at http://localhost:${e.port}`),(0,c.default)(`http://localhost:${e.port}`)})}};
@@ -1,17 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
- import { EnumPackage } from "../util/enums/EnumType";
6
- import { Packet } from "./Packets";
7
- import { PacketType } from "./PacketType";
8
- export type PacketTypeValidator = (data: Uint8Array, index: number) => Promise<[Uint8Array, false | any]>;
9
- export type PacketReceiveProcessor = (data: Uint8Array, validationResult: any, index: number) => any;
10
- export type PacketSendProcessor = (ident: string, ...data: any[]) => Promise<Uint8Array>;
11
- export declare function createValidator<T extends PacketType>(type: T, dataCap: number, dataMin: number, packet: Packet<T> | Packet<T[]>, gzipCompression: boolean): PacketTypeValidator;
12
- export declare function createReceiveProcessor(type: PacketType, enumData: EnumPackage[], cap: number): PacketReceiveProcessor;
13
- /** Creates a function that processes a packet type */
14
- export declare function createSendProcessor(type: PacketType, gzipCompression: boolean, batchedData: boolean): PacketSendProcessor;
15
- export declare function createObjSendProcessor(packet: Packet<PacketType[]>): PacketSendProcessor;
16
- export declare function createObjReceiveProcessor(packet: Packet<PacketType[]>): PacketReceiveProcessor;
17
- export declare function createObjValidator(packet: Packet<PacketType[]>): PacketTypeValidator;
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.createValidator=p,exports.createReceiveProcessor=l,exports.createSendProcessor=T,exports.createObjSendProcessor=function(e){const r=e.type.length,a=e.type.map(e=>T(e,!1,!1));return async(e,n)=>{let c=[];for(let s=0;s<r;s++){const r=n[s],o=await a[s](e,Array.isArray(r)?r:[r]);if(o.length>t.MAX_UVARINT)throw new Error(`Cannot send ${o.length}/${t.MAX_UVARINT} bytes of data!`);c.push(...(0,t.convertVarInt)(o.length)),o.forEach(e=>c.push(e))}return new Uint8Array(c)}},exports.createObjReceiveProcessor=function(e){const a=e.type.map((t,r)=>l(t,e.enumData,e.dataMax[r]));return(n,c)=>{let s=0,o=0,u=[];for(;s<n.length;){const[p,l]=(0,t.readVarInt)(n,s);s=p;const T=n.subarray(s,s+=l);u.push(a[u.length](T,c[u.length],e.type[u.length]==r.PacketType.ENUMS?o++:0))}return u}},exports.createObjValidator=function(e){const a=e.type.map((t,r)=>p(t,e.dataMax[r],e.dataMin[r],e,!1));return async n=>{let c=0,s=0,o=[];for(;c<n.length;){if(o.length>e.type.length)return[n,!1];const[u,p]=(0,t.readVarInt)(n,c);if(c=u,p+c>n.length)return[n,!1];const l=n.subarray(c,c+=p),[,T]=await a[o.length](l,e.type[o.length]==r.PacketType.ENUMS?s++:0);if(!1===T)return[n,!1];o.push(T)}return[n,o]}};const e=require("../util/BufferUtil"),t=require("../util/packets/CompressionUtil"),r=require("./PacketType"),a=require("../util/BufferUtil"),n=require("../util/StringUtil"),c=require("../util/packets/JSONUtil");function s(e,t){return r=>r.length>=t&&r.length<=e}function o(e,t){return t*=2,e*=2,r=>r.length>=t&&r.length<=e&&r.length%2==0}function u(e,r){return a=>{if(0==a.length)return r<=0&&[];let n=0,c=0,s=[];for(;c<a.length;){const[r,o]=(0,t.readVarInt)(a,c);if(c=r,s.push(o),++n>e)return!1}return!(n<r)&&s}}function p(e,a,n,p,l){const T=function(){switch(e){case r.PacketType.NONE:return e=>0==e.length;case r.PacketType.RAW:return()=>{};case r.PacketType.ENUMS:return(e,t)=>{if(e.length<n||e.length>a||t>=p.enumData.length)return!1;const r=p.enumData[t];for(let t=0;t<e.length;t++)if(r.values.length<=e[t])return!1};case r.PacketType.BYTES:case r.PacketType.UBYTES:case r.PacketType.HEX:return s(a,n);case r.PacketType.SHORTS:case r.PacketType.USHORTS:return o(a,n);case r.PacketType.VARINT:case r.PacketType.UVARINT:case r.PacketType.DELTAS:return u(a,n);case r.PacketType.FLOATS:return e=>{if(e.length%4!=0)return!1;const r=e.length*t.ONE_FOURTH;return!(r>a||r<n)&&void 0};case r.PacketType.DOUBLES:return e=>{if(e.length%8!=0)return!1;const r=e.length*t.ONE_EIGHT;return!(r>a||r<n)&&void 0};case r.PacketType.BOOLEANS:{const e=Math.ceil(n*t.ONE_EIGHT),r=Math.ceil(a*t.ONE_EIGHT);return t=>t.length>=e&&t.length<=r}case r.PacketType.STRINGS_ASCII:return e=>{let r=0;const[c,s]=(0,t.readVarInt)(e,r);if(r=c,s<n||s>a)return!1;const o=[];let u=0;for(let a=0;a<s;a++){const[a,n]=(0,t.readVarInt)(e,r);r=a,o.push(n),u+=n}return!(r+Math.ceil(u/8)>e.length)&&[s,o,r]};case r.PacketType.STRINGS_UTF16:return e=>{let r=0,c=0,s=[];for(;c<e.length;){if(r++,r>a)return!1;const[n,o]=(0,t.readVarInt)(e,c);c=n;let u=[];for(let r=0;r<o;r++){const[r,a]=(0,t.readVarInt)(e,c);if(c=r,c>e.length)return!1;u.push(a)}s.push(u)}return!(r<n)&&s};case r.PacketType.JSON:return e=>{try{return(0,c.decompressJSON)(e)}catch{return!1}};default:throw new Error("Unknown type: "+e)}}();return l&&0==p.dataBatching?async(e,r)=>{try{const a=await(0,t.decompressGzip)(e);return[a,T(a,r)]}catch{return[e,!1]}}:async(e,t)=>[e,T(e,t)]}function l(e,c,s){switch(e){case r.PacketType.NONE:return()=>{};case r.PacketType.RAW:return e=>e;case r.PacketType.BYTES:return e=>Array.from(e).map(t.demapZigZag);case r.PacketType.UBYTES:return e=>Array.from(e);case r.PacketType.HEX:return e=>(0,t.bytesToHex)(e);case r.PacketType.SHORTS:return e=>(0,a.splitBuffer)(e,2).map(e=>(0,t.demapShort_ZZ)(e));case r.PacketType.USHORTS:return e=>(0,a.splitBuffer)(e,2).map(e=>(0,t.fromShort)(e));case r.PacketType.VARINT:return(e,r)=>r.map(t.demapZigZag);case r.PacketType.UVARINT:return(e,t)=>t;case r.PacketType.DELTAS:return(e,r)=>r.map((e,a)=>r[a]=(r[a-1]||0)+(0,t.demapZigZag)(e));case r.PacketType.FLOATS:return e=>(0,a.splitBuffer)(e,4).map(t.deconvertFloat);case r.PacketType.DOUBLES:return e=>(0,a.splitBuffer)(e,8).map(t.deconvertDouble);case r.PacketType.BOOLEANS:return e=>Array.from(e).map(e=>(0,t.decompressBools)(e)).flat().splice(0,s);case r.PacketType.ENUMS:return(e,t,r)=>{const a=c[r];return Array.from(e).map(e=>a.values[e])};case r.PacketType.STRINGS_ASCII:return(e,r)=>{const[a,c,s]=r,o=(0,t.bytesToBits)(e.subarray(s)),u=(0,n.decodeHuffman)(o);if(!u)return[];const p=[];let l=0;for(let e=0;e<a;e++)p.push(u.slice(l,l+c[e])),l+=c[e];return p};case r.PacketType.STRINGS_UTF16:return(e,t)=>t.map(e=>String.fromCodePoint(...e));case r.PacketType.JSON:return(e,t)=>t;default:throw new Error("Unknown type: "+e)}}function T(a,s,o){const u=function(){switch(a){case r.PacketType.NONE:return()=>[];case r.PacketType.RAW:return e=>Array.from(e);case r.PacketType.ENUMS:return e=>e;case r.PacketType.BYTES:return e=>e.map(t.mapZigZag);case r.PacketType.UBYTES:return e=>e.map(t.toByte);case r.PacketType.HEX:return e=>{if("string"!=typeof e){if(e instanceof Array&&1==e.length)return(0,t.hexToBytes)(e[0]);throw new Error("Cannot send more than 1 hex string; this packet is equivalent to UBYTES: "+JSON.stringify(e))}return(0,t.hexToBytes)(e)};case r.PacketType.SHORTS:return e=>e.map(t.mapShort_ZZ).flat();case r.PacketType.USHORTS:return e=>e.map(t.toShort).flat();case r.PacketType.VARINT:return e=>e.map(e=>(0,t.convertVarInt)((0,t.mapZigZag)(e))).flat();case r.PacketType.UVARINT:return e=>e.map(t.convertVarInt).flat();case r.PacketType.DELTAS:return e=>e.map((r,a)=>(0,t.convertVarInt)((0,t.mapZigZag)(r-(e[a-1]||0)))).flat();case r.PacketType.FLOATS:return e=>e.map(t.convertFloat).flat();case r.PacketType.DOUBLES:return e=>e.map(t.convertDouble).flat();case r.PacketType.BOOLEANS:return r=>(0,e.splitArray)(r,8).map(e=>(0,t.compressBools)(e)).flat();case r.PacketType.STRINGS_ASCII:return e=>[...(0,t.convertVarInt)(e.length),...e.map(e=>(0,t.convertVarInt)(e.length)).flat(),...(0,n.encodeHuffman)(e.reduce((e,t)=>e+String(t),""))];case r.PacketType.STRINGS_UTF16:return e=>{const r=[];for(const a of e){const e=String(a),c=(0,n.processCharCodes)(e),s=c.length;r.push(...(0,t.convertVarInt)(s)),r.push(...c.map(t.convertVarInt).flat())}return r};case r.PacketType.JSON:return e=>Array.from((0,c.compressJSON)(e));default:throw new Error("Unknown type: "+a)}}();return!s||o?async(e,t)=>new Uint8Array(u(t)):async(e,r)=>(0,t.compressGzip)(new Uint8Array(u(r)),e)}
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.PacketSchema=exports.Packet=void 0;const t=require("../util/enums/EnumHandler"),e=require("../util/enums/EnumType"),a=require("../util/packets/CompressionUtil"),s=require("../util/packets/PacketUtils"),i=require("./PacketProcessors"),r=require("./PacketType"),n=require("../util/StringUtil");class o{defaultEnabled;tag;maxSize;minSize;type;enumData;dataMax;dataMin;dataBatching;maxBatchSize;dontSpread;autoFlatten;rateLimit;async;rereference;gzipCompression;object;client;receiveProcessor;sendProcessor;validator;processReceive;processSend;validate;customValidator;lastReceived={};lastSent={};constructor(t,e,a,s,n){if(this.tag=t,this.defaultEnabled=s,this.client=n,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=n?1/0:e.maxBatchSize,this.gzipCompression=e.gzipCompression,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]==r.PacketType.NONE&&(this.dataMax[t]=this.dataMin[t]=0);this.receiveProcessor=(0,i.createObjReceiveProcessor)(this),this.sendProcessor=(0,i.createObjSendProcessor)(this),this.validator=(0,i.createObjValidator)(this)}else this.maxSize=this.dataMax,this.minSize=this.dataMin,this.type==r.PacketType.NONE&&(this.dataMax=this.dataMin=0),this.receiveProcessor=(0,i.createReceiveProcessor)(this.type,this.enumData,this.dataMax),this.sendProcessor=(0,i.createSendProcessor)(this.type,this.gzipCompression,0!=this.dataBatching),this.validator=(0,i.createValidator)(this.type,this.dataMax,this.dataMin,this,this.gzipCompression);this.processReceive=(t,e)=>this.receiveProcessor(t,e,0),this.processSend=async e=>new Uint8Array(await this.sendProcessor(t,e)),this.validate=t=>this.validator(t,0),this.customValidator=a}async listen(t,e){try{const[a,i]=await this.validate(t);if(!this.client&&!1===i)return"Invalid packet";const r=this.processReceive(a,i),n=this.autoFlatten?(0,s.UnFlattenData)(r):r;if(null!=this.customValidator)if(this.dontSpread){if(!this.customValidator(e,n))return"Didn't pass custom validator"}else if(!this.customValidator(e,...n))return"Didn't pass custom validator";return[n,!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=[this.tag.length,...(0,n.processCharCodes)(this.tag),(0,a.compressBools)([this.dontSpread,this.async,this.object,this.autoFlatten,this.gzipCompression,this.rereference]),this.dataBatching,this.enumData.length,...this.enumData.map(t=>t.serialize()).flat()];return this.object?[...t,this.maxSize,...this.dataMax.map(a.convertVarInt).flat(),...this.dataMin.map(a.convertVarInt).flat(),...this.type]:[...t,...(0,a.convertVarInt)(this.dataMax),...(0,a.convertVarInt)(this.dataMin),this.type]}static readVarInts(t,e,s){const i=[];for(let r=0;r<s;r++){const[s,r]=(0,a.readVarInt)(t,e);e=s,i.push(r)}return[i,e]}static deserialize(s,i,c){const d=i,l=s[i++],p=(0,n.as8String)(s.slice(i,i+=l)),[u,m,y,S,g,P]=(0,a.decompressBools)(s[i++]),f=s[i++],M=s[i++],v=[];for(let a=0;a<M;a++){const a=s[i++],r=(0,n.as8String)(s.slice(i,i+=a)),o=s[i++],c=[];for(let t=0;t<o;t++){const t=s[i++],a=s[i++],r=(0,n.as8String)(s.slice(i,i+=t));c.push(e.TYPE_CONVERSION_MAP[a](r))}v.push((0,t.DefineEnum)(r,c))}if(y){const t=s[i++],[e,a]=this.readVarInts(s,i,t);i=a;const[n,l]=this.readVarInts(s,i,t);i=l;const y=Array.from(s.slice(i,i+=t));let P=0;const M=y.map(t=>t==r.PacketType.ENUMS?v[P++]:t),x=new h(!0,M,m,n,e,-1,u,S,!1,f,-1,g);return[new o(p,x,null,!1,c),i-d]}const[x,z]=(0,a.readVarInt)(s,i);i=x;const[b,V]=(0,a.readVarInt)(s,i);i=b;const k=s[i++],j=k==r.PacketType.ENUMS?v[0]:k,B=new h(!1,j,m,V,z,-1,u,!1,P,f,-1,g);return[new o(p,B,null,!1,c),i-d]}static deserializeAll(t,e){const a=[];let s=0;for(;s<t.length;){const[i,r]=this.deserialize(t,s,e);a.push(i),s+=r}return a}}exports.Packet=o;const c=(t,a)=>t instanceof e.EnumPackage?(a.push(t),r.PacketType.ENUMS):t;class h{type;enumData=[];dataMax;dataMin;dataBatching;maxBatchSize;rateLimit;dontSpread=!1;autoFlatten=!1;async=!1;rereference=!1;gzipCompression=!1;object;constructor(t,e,a,s,i,r,n,o,h,d,l,p){this.object=t,this.async=a,this.dataMin=s,this.dataMax=i,this.rateLimit=r,this.dontSpread=n,this.autoFlatten=o,this.rereference=h,this.dataBatching=d,this.maxBatchSize=l,this.gzipCompression=p,this.type=t?e.map(t=>c(t,this.enumData)):c(e,this.enumData)}testObject(t){return this.object}}exports.PacketSchema=h;
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- 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.on,e.removeEventListener),this.host=t,this.handshakePacket=i;for(const e of t.clientPackets.getPackets()){const t=e.tag;this.listeners[t]=[],e.lastReceived[this.id]=void 0,this.enabledPackets[t]=e.defaultEnabled,this.asyncMap[t]=e.async,e.async&&(this.asyncData[t]=[!1,[]])}this.setInterval=this.setInterval.bind(this),this.batcher.registerSendPackets(this.host.serverPackets,this),this.invalidPacket=this.invalidPacket.bind(this),this.rater=new s.RateHandler(this),this.rater.registerRate("C",n),this.rater.registerRate("S",r),this.rater.registerAll(t.clientPackets,"client"),this.rater.registerAll(t.serverPackets,"server"),this.rater.start(),null==this.handshakePacket?this.socket.addEventListener("message",this.messageLambda):(this.handshakeLambda=e=>this.handshakeHandler(e),this.socket.addEventListener("message",this.handshakeLambda)),this.socket.on("close",()=>{for(const e of t.clientPackets.getPackets())delete e.lastReceived[this.id];for(const e of t.serverPackets.getPackets())delete e.lastSent[this.id]})}parseData(e){if(this.rater.trigger("C"))return null;if(!(e.data instanceof Buffer))return null;const t=new Uint8Array(e.data);if(this.print&&console.log(`⬇ (${this.id},${t.byteLength})`,t.length>0&&this.host.clientPackets.getTag(t[0])||"<INVALID>",(0,a.stringifyBuffer)(t)),t.byteLength<1)return this.socket.close(i.CloseCodes.SMALL),null;const s=t[0],n=t.slice(1);if(!this.host.clientPackets.hasKey(s))return this.socket.close(i.CloseCodes.INVALID_KEY),null;const r=this.host.clientPackets.getTag(s);return this.enabledPackets[r]?this.rater.trigger("client"+s)?null:[r,n]:(this.socket.close(i.CloseCodes.DISABLED_PACKET),null)}handshakeHandler(e){const t=this.parseData(e);if(null==t)return this.socket.close(i.CloseCodes.INVALID_DATA);t[0]==this.handshakePacket?(this.messageHandler(t),this.socket.removeEventListener("message",this.handshakeLambda),this.socket.addEventListener("message",this.handshakedMessageLambda),this.handshakeComplete=!0):this.socket.close(i.CloseCodes.INVALID_DATA)}invalidPacket(e){console.log("Closure cause",e),this.socket.close(i.CloseCodes.INVALID_PACKET,e)}isAsync(e){return this.asyncMap[e]}listenLock=!1;packetQueue=[];async listenPacket(t,s,a,i,n){this.closed||(await(0,e.listenPacket)(t,this.listeners[s],this.invalidPacket),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!`);this.listeners[e]??=[],this.listeners[e].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)}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(`⬆ (${this.id},${e.byteLength})`,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;
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- var e,t=this&&this.__createBinding||(Object.create?function(e,t,s,n){void 0===n&&(n=s);var i=Object.getOwnPropertyDescriptor(t,s);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[s]}}),Object.defineProperty(e,n,i)}: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 i={};if(null!=n)for(var a=e(n),r=0;r<a.length;r++)"default"!==a[r]&&t(i,n,a[r]);return s(i,n),i});Object.defineProperty(exports,"__esModule",{value:!0}),exports.SonicWSServer=void 0;const i=n(require("ws")),a=require("./SonicWSConnection"),r=require("../util/packets/PacketHolder"),c=require("../util/packets/CompressionUtil"),o=require("../../version"),l=require("../util/packets/PacketUtils"),h=require("../PacketProcessor"),d=require("../util/packets/HashUtil"),u=require("../Connection"),g=require("../debug/DebugServer");class p extends h.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];constructor(e){super();const{clientPackets:t=[],serverPackets:s=[],websocketOptions:n={}}=e;this.wss=new i.WebSocketServer(n),this.clientPackets=new r.PacketHolder(t),this.serverPackets=new r.PacketHolder(s);const l=this.clientPackets.serialize(),h=this.serverPackets.serialize(),g=[...o.SERVER_SUFFIX_NUMS,o.VERSION],p=[...(0,c.convertVarInt)(l.length),...l,...h];(0,d.setHashFunc)(e.sonicServerSettings?.bit64Hash??!0),this.wss.on("connection",async e=>{const t=new a.SonicWSConnection(e,this,this.generateSocketID(),this.handshakePacket,this.clientRateLimit,this.serverRateLimit);if(await this.callMiddleware("onClientConnect",t))return t.close(u.CloseCodes.MIDDLEWARE,"Connection blocked by middleware."),this.callMiddleware("onClientDisconnect",t,u.CloseCodes.MIDDLEWARE,Buffer.from("Connection blocked by middleware.")),void this.availableIds.push(t.id);const s=new Uint8Array([...(0,c.convertVarInt)(t.id),...p]);e.send([...g,...await(0,c.compressGzip)(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)>o.VERSION&&console.warn(`SonicWS is currently running outdated! (current: ${o.VERSION}, latest: ${e}) Update with "npm update sonic-ws"`)}).catch(e=>{console.error(e),console.warn("Could not check SonicWS version.")})}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){e>c.MAX_BYTE&&(e=0,console.warn(`A rate limit above ${c.MAX_BYTE} is considered infinite.`)),this.clientRateLimit=e}setServerRateLimit(e){e>c.MAX_BYTE&&(e=0,console.warn(`A rate limit above ${c.MAX_BYTE} is considered infinite.`)),this.serverRateLimit=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[i,a,r]=await(0,l.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(i,a,r))}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)}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 g.DebugServer(this,e)}}exports.SonicWSServer=p;
@@ -1,9 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
- export declare function processCharCodes(text: string): number[];
6
- export declare function convertCharCodes(codes: number[]): string;
7
- export declare function encodeHuffman(text: string): Uint8Array;
8
- export declare function decodeHuffman(bits: string): string;
9
- export declare function as8String(data: Uint8Array): string;
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.processCharCodes=function(e){return Array.from(e,e=>e.codePointAt(0))},exports.convertCharCodes=r,exports.encodeHuffman=function(r){return(0,e.bitsToBytes)(Array.from(r).map(e=>t[e]).join(""))},exports.decodeHuffman=function(e){let r="",t="";for(const n of e)t+=n,o[t]&&(r+=o[t],t="");return r},exports.as8String=function(e){return r(Array.from(e))};const e=require("./packets/CompressionUtil");function r(e){return String.fromCodePoint(...e)}const o={1000001:"w",1000010:"m",1000100:"u",1000101:"c",1000110:"l",1000111:"d",1001001:"r",1001010:"h",1001100:"s",1001101:"n",1001110:"i",1001111:"o",1010001:"a",1010010:"t",1010100:"e",1010101:"",1e7:"ˆ",10000001:"‡",10000111:"†",1001e4:"…",10010001:"„",10010111:"ƒ",101e5:"‚",10100001:"",10100111:"€",10101100:"",10101101:"~",10101111:"}",1011e4:"|",10110001:"{",10110011:"`",10110100:"_",10110101:"^",10110111:"]",10111e3:"",10111001:"[",10111011:"@",10111100:"?",10111101:">",10111111:"=",11e6:"<",11000001:";",11000011:":",11000100:"9",11000101:"8",11000111:"7",11001e3:"6",11001001:"5",11001011:"4",11001100:"3",11001101:"2",11001111:"1",1101e4:"0",11010001:"/",11010011:".",11010100:"-",11010101:",",11010111:"+",11011e3:"*",11011001:")",11011011:"(",11011100:"'",11011101:"&",11011111:"$",11100001:"#",11100010:'"',11100100:"!",11100101:"",11100110:"",11100111:"",11101001:"",11101010:"",11101100:"",11101101:"",11101110:"",11101111:"",11110001:"",11110010:"",11110100:"",11110101:"",11110110:"",11110111:"",11111001:"",11111010:"",11111100:"",11111101:"",11111110:"",11111111:"",100001100:"Ã",100101100:"Â",100101101:"Á",101001100:"À",101011100:"¿",101011101:"¾",101100100:"½",101101100:"¼",101101101:"»",101110100:"º",101111100:"¹",101111101:"¸",110000100:"·",110001100:"¶",110001101:"µ",110010100:"´",110011100:"³",110011101:"²",110100100:"±",110101100:"°",110101101:"¯",110110100:"®",110111100:"­",110111101:"%",111e6:"¬",111000001:"«",111000111:"ª",11101e4:"©",111010001:"¨",111010111:"§",1111e5:"¦",111100001:"¥",111100111:"¤",11111e4:"£",111110001:"¢",111110111:"¡",1000011010:"á",1010011010:"à",1010011011:"ß",1011001010:"Þ",1011101010:"Ý",1011101011:"Ü",1100001010:"Û",1100101010:"Ú",1100101011:"Ù",1101001010:"Ø",1101101010:"×",1101101011:"Ö",1110001100:"Õ",1110101100:"Ô",1110101101:"Ó",1111001100:"Ò",1111101100:"Ñ",1111101101:"Ð","00000000":" ","00000001":"Ÿ","0000001":"\n","0000010":"","000001100":"Ï","0000011010":"ç","00000110110":"ó","000001101110":"ù","0000011011110":"ü","00000110111110":"þ","00000110111111":"ý","00000111":"ž","0000100":"\b","0000101":"","0000110":"","0000111":"","00010000":"","00010001":"œ","0001001":"","0001010":"","000101100":"Î","000101101":"Í","00010111":"›","0001100":"","0001101":"","0001110":"","0001111":"Z","00100000":"š","00100001":"™","0010001":"Q","0010010":"X","001001100":"Ì","0010011010":"æ","0010011011":"å","00100111":"˜","0010100":"J","0010101":"K","0010110":"V","0010111":"B","00110000":"—","00110001":"–","0011001":"P","0011010":"Y","001101100":"Ë","001101101":"Ê","00110111":"•","0011100":"G","0011101":"F","0011110":"W","0011111":"M","01000000":"”","01000001":"“","0100001":"U","0100010":"C","010001100":"É","0100011010":"ä","01000110110":"ò","01000110111":"ñ","01000111":"’","0100100":"L","0100101":"D","0100110":"R","0100111":"H","01010000":"‘","01010001":"","0101001":"S","0101010":"N","010101100":"È","010101101":"Ç","01010111":"","0101100":"I","0101101":"O","0101110":"A","0101111":"T","01100000":"Ž","01100001":"","0110001":"E","0110010":"z","011001100":"Æ","0110011010":"ã","0110011011":"â","01100111":"Œ","0110100":"q","0110101":"x","0110110":"j","0110111":"k","01110000":"‹","01110001":"Š","0111001":"v","0111010":"b","011101100":"Å","011101101":"Ä","01110111":"‰","0111100":"p","0111101":"y","0111110":"g","0111111":"f",10000110110:"ð",100001101110:"ø",100001101111:"÷",10110010110:"ï",10110010111:"î",11000010110:"í",110000101110:"ö",1100001011110:"û",1100001011111:"ú",11010010110:"ì",11010010111:"ë",11100011010:"ê",111000110110:"õ",111000110111:"ô",11110011010:"é",11110011011:"è"},t=Object.fromEntries(Object.entries(o).map(([e,r])=>[r,e]));
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
- export declare const TYPE_CONVERSION_MAP: Record<number, (data: string) => string | number | boolean | undefined | null>;
6
- export type EnumValue = string | number | boolean | undefined | null;
@@ -1,5 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
- export {};
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.BatchHelper=void 0;const t=require("../BufferUtil"),e=require("./CompressionUtil");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 s=t.getKey(e);this.initiateBatch(s,a.dataBatching,a.gzipCompression)})}initiateBatch(t,e,a){this.batchedData[t]=[],this.batchInfo[t]=[e,a]}startBatch(a){const[s,c]=this.batchInfo[a];this.batchTimeouts[a]=this.conn.setInterval(async()=>{if(0==this.batchedData[a].length)return;const s=new Uint8Array(this.batchedData[a]);this.conn.raw_send((0,t.toPacketBuffer)(a,c?await(0,e.compressGzip)(s):s)),this.batchedData[a]=[],delete this.batchTimeouts[a]},s)}batchPacket(t,a){const s=this.batchedData[t];s.push(...(0,e.convertVarInt)(a.length)),a.forEach(t=>s.push(t)),this.batchTimeouts[t]||this.startBatch(t)}static async unravelBatch(t,a,s){const c=t.gzipCompression?await(0,e.decompressGzip)(a):a,i=[];for(let a=0;a<c.length;){if(t.maxBatchSize>0&&i.length>t.maxBatchSize)return"Too big of batch";const[h,n]=(0,e.readVarInt)(c,a);if(a=h,a+n>c.length)return"Tampered batch length";const r=c.slice(a,a+=n),o=await t.listen(r,s);if("string"==typeof o)return"Batched packet: "+o;i.push([o[0],!t.dontSpread])}return i}};
@@ -1,39 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
- export declare const MAX_BYTE = 255;
6
- export declare const NEGATIVE_BYTE = 127;
7
- export declare const MAX_SHORT = 65535;
8
- export declare const SHORT_CC_OVERFLOW: number;
9
- export declare const UVARINT_OVERFLOW: number, VARINT_CHAIN_FLAG = 128,
10
- NEGATIVE_VARINT: number,
11
- VARINT_OVERFLOW: number,
12
- MAX_VSECT_SIZE = 7,
13
- MAX_UVARINT: number,
14
- MAX_VARINT: number;
15
- export declare const ONE_EIGHT: number, ONE_FOURTH: number;
16
- export declare const EMPTY_UINT8: Uint8Array<ArrayBuffer>;
17
- export type SHORT_BITS = [high: number, low: number];
18
- export declare function fromShort(short: SHORT_BITS): number;
19
- export declare function toShort(n: number): SHORT_BITS;
20
- export declare function toByte(n: number): number;
21
- export declare const compressBools: (array: boolean[]) => number;
22
- export declare const decompressBools: (byte: number) => boolean[];
23
- export declare function convertFloat(flt: number): number[];
24
- export declare function deconvertFloat(bytes: number[]): number;
25
- export declare function convertDouble(double: number): number[];
26
- export declare function deconvertDouble(bytes: number[]): number;
27
- export declare function mapZigZag(n: number): number;
28
- export declare function demapZigZag(n: number): number;
29
- export declare function demapShort_ZZ(short: SHORT_BITS): number;
30
- export declare function mapShort_ZZ(short: number): SHORT_BITS;
31
- export declare function convertVarInt(num: number): number[];
32
- export declare function readVarInt(arr: number[] | Uint8Array, off: number): [number, number];
33
- export declare function deconvertVarInts(arr: Uint8Array | number[]): number[];
34
- export declare const bytesToBits: (bytes: ArrayLike<number>) => string;
35
- export declare const bitsToBytes: (bits: string) => Uint8Array<ArrayBuffer>;
36
- export declare function compressGzip(data: Uint8Array<ArrayBuffer>, ident?: string): Promise<Uint8Array>;
37
- export declare function decompressGzip(data: Uint8Array): Promise<Uint8Array>;
38
- export declare function bytesToHex(bytes: Uint8Array): string;
39
- export declare function hexToBytes(hex: string): Uint8Array<ArrayBuffer>;
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.bitsToBytes=exports.bytesToBits=exports.decompressBools=exports.compressBools=exports.EMPTY_UINT8=exports.ONE_FOURTH=exports.ONE_EIGHT=exports.MAX_VARINT=exports.MAX_UVARINT=exports.MAX_VSECT_SIZE=exports.VARINT_OVERFLOW=exports.NEGATIVE_VARINT=exports.VARINT_CHAIN_FLAG=exports.UVARINT_OVERFLOW=exports.SHORT_CC_OVERFLOW=exports.MAX_SHORT=exports.NEGATIVE_BYTE=exports.MAX_BYTE=void 0,exports.fromShort=o,exports.toShort=n,exports.toByte=function(t){if(!isFinite(t))throw new Error("Can only use real numbers in bytes: "+t);if(t>exports.MAX_BYTE||t<-exports.MAX_BYTE-1)throw new Error(`Byte Numbers must be within range -${exports.MAX_BYTE+1} and ${exports.MAX_BYTE}: ${t}`);return t},exports.convertFloat=function(t){if(isNaN(t))return T(0,A,1);const r=t<0?1:0;if(0==(t=Math.abs(t)))return T(r,0,0);const o=Math.floor(Math.log(t)/Math.LN2);if(o>127||o<-126)return T(r,255,0);const n=t/e(o),s=Math.round((n-1)*e(23));return T(r,o+127,8388607&s)},exports.deconvertFloat=function(t){const r=t.map(t=>t.toString(2).padStart(8,"0")).join(""),o=p(r[0]),n=p(r.slice(1,9)),i=0==n?-126:n-127,a=function(t,r){const o=p(t);let n=0;for(let t=0;t<s;t++)o&1<<s-t-1&&(n+=e(-(t+1)));return(r?1:0)+n}(r.slice(9,32),0!=n);let u;u=n==A?0==a?1/0:NaN:a*e(i);return 1==o?-u:u},exports.convertDouble=function(t){if(isNaN(t))return _(0,c,1);const r=t<0?1:0;if(!isFinite(t))return _(r,c,0);let o,n;0==(t=Math.abs(t))?(o=0,n=0):(o=Math.floor(Math.log2(t))-51,n=Math.floor(t/e(o)));return _(r,o+1023,n)},exports.deconvertDouble=function(t){const r=t.map(t=>t.toString(2).padStart(8,"0")).join(""),o=p(r[0]),n=p(r.slice(1,12)),s=0==n?-1022:n-1023,i=p(r.slice(12,64));let a;a=n==c?0==i?1/0:NaN:i*e(s);return 1==o?-a:a},exports.mapZigZag=E,exports.demapZigZag=l,exports.demapShort_ZZ=function(t){return l(o(t))},exports.mapShort_ZZ=function(t){return n(E(t))},exports.convertVarInt=function(t){if(t>exports.MAX_UVARINT||t<0)throw new Error(`Variable Ints must be within range 0 and ${exports.MAX_VARINT}: ${t}`);if(0===t)return[0];const r=[];for(;t>0;){let e=127&t;(t>>>=7)>0&&(e|=exports.VARINT_CHAIN_FLAG),r.push(e)}return r},exports.readVarInt=N,exports.deconvertVarInts=function(t){let r=[],e=0;for(;e<t.length;){const[o,n]=N(t,e);r.push(n),e=o}return r},exports.compressGzip=async function(t,r=""){if("undefined"==typeof CompressionStream)throw"undefined"!=typeof window&&window.alert(I),new Error(I);const e=new Blob([t]).stream().pipeThrough(new CompressionStream("deflate-raw")),o=await new Response(e).arrayBuffer();t.length<=o.byteLength&&""!=r&&console.warn("WARN: Packet '"+r+"' is small, and compressing it makes the size bigger!");return new Uint8Array(o)},exports.decompressGzip=async function(t){if("undefined"==typeof DecompressionStream)throw"undefined"!=typeof window&&window.alert(I),new Error(I);const r=new Blob([t]).stream().pipeThrough(new DecompressionStream("deflate-raw")),e=await new Response(r).arrayBuffer();return new Uint8Array(e)},exports.bytesToHex=function(t){return Array.from(t,t=>t.toString(16).padStart(2,"0")).join("")},exports.hexToBytes=function(t){const r=new Uint8Array(t.length/2);for(let e=0;e<t.length;e+=2)r[e/2]=parseInt(t.substring(e,e+2),16);return r};const t=require("../BufferUtil");exports.MAX_BYTE=255,exports.NEGATIVE_BYTE=127,exports.MAX_SHORT=65535,exports.SHORT_CC_OVERFLOW=exports.MAX_BYTE+1,exports.UVARINT_OVERFLOW=exports.NEGATIVE_BYTE+1,exports.VARINT_CHAIN_FLAG=128,exports.NEGATIVE_VARINT=Math.floor(exports.NEGATIVE_BYTE/2),exports.VARINT_OVERFLOW=exports.NEGATIVE_VARINT+1,exports.MAX_VSECT_SIZE=7,exports.MAX_UVARINT=exports.UVARINT_OVERFLOW**exports.MAX_VSECT_SIZE-1,exports.MAX_VARINT=Math.floor(exports.MAX_UVARINT/2),exports.ONE_EIGHT=1/8,exports.ONE_FOURTH=1/4,exports.EMPTY_UINT8=new Uint8Array([]);const r=[],e=t=>r[t]??=Math.pow(2,t);function o(t){return t[0]*exports.SHORT_CC_OVERFLOW+t[1]}function n(t){if(!isFinite(t))throw new Error("Can only use real numbers in shorts: "+t);if(t>exports.MAX_SHORT||t<0)throw new Error(`Short Numbers must be within range 0 and ${exports.MAX_SHORT}`);return[Math.floor(t/exports.SHORT_CC_OVERFLOW),t%exports.SHORT_CC_OVERFLOW]}exports.compressBools=t=>t.reduce((t,r,e)=>t|r<<7-e,0);exports.decompressBools=t=>[...Array(8)].map((r,e)=>!!(t&1<<7-e));const s=23;function p(t){return parseInt(t,2)}const i=8,a=23,u=11,x=52,A=255,c=2047;function f(r,e,o,n,s){const i=o.toString(2)+n.toString(2).padStart(r,"0")+s.toString(2).padStart(e,"0");return(0,t.splitArray)(Array.from(i),8).map(t=>p(t.join("")))}function T(t,r,e){return f(i,a,t,r,e)}function _(t,r,e){return f(u,x,t,r,e)}function E(t){return t<<1^t>>31}function l(t){return t>>>1^-(1&t)}function N(t,r){let e,o=0,n=0;do{e=t[r++],o+=(e&~exports.VARINT_CHAIN_FLAG)<<n,n+=7}while(0!==(e&exports.VARINT_CHAIN_FLAG));return[r,o]}exports.bytesToBits=t=>Array.from(t).map(t=>t.toString(2).padStart(8,"0")).join("");exports.bitsToBytes=t=>new Uint8Array(t.match(/.{1,8}/g)?.map(t=>parseInt(t.padEnd(8,"0"),2))??[]);const I="Your browser is too old to support compression. Please update!";
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
- export declare function setHashFunc(use64Bit: boolean): void;
6
- export declare function hashValue(value: any): bigint | number;
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
- export declare const compressJSON: (value: any) => Uint8Array<ArrayBuffer>;
6
- export declare const decompressJSON: (bytes: Uint8Array) => any;
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.decompressJSON=exports.compressJSON=void 0;const e=require("../BufferUtil"),r=require("./CompressionUtil");var t;!function(e){e[e.NULL=0]="NULL",e[e.BOOL=1]="BOOL",e[e.INT=2]="INT",e[e.FLOAT=3]="FLOAT",e[e.STRING=4]="STRING",e[e.ARRAY=5]="ARRAY",e[e.OBJECT=6]="OBJECT"}(t||(t={}));const s=e=>{const t=(new TextEncoder).encode(e);return[...(0,r.convertVarInt)(t.length),...t]},n=(e,t)=>{const[s,n]=(0,r.readVarInt)(e,t);return{value:(new TextDecoder).decode(e.subarray(s,s+n)),length:s+n-t}};exports.compressJSON=n=>{const o=[],c=[],a=[],u=e=>{if(null===e)a.push(t.NULL);else if("boolean"==typeof e)a.push(t.BOOL),o.push(e);else if(Number.isInteger(e))a.push(t.INT),c.push(...(0,r.convertVarInt)((0,r.mapZigZag)(e)));else if("number"==typeof e)a.push(t.FLOAT),c.push(...(0,r.convertFloat)(e));else if("string"==typeof e)a.push(t.STRING),c.push(...s(e));else if(Array.isArray(e)){a.push(t.ARRAY),c.push(...(0,r.convertVarInt)(e.length));for(const r of e)u(r)}else{if("object"!=typeof e)throw new Error("Unsupported type");{a.push(t.OBJECT);const n=Object.keys(e);c.push(...(0,r.convertVarInt)(n.length));for(const r of n)c.push(...s(r)),u(e[r])}}};u(n);const p=o.length?(0,e.splitArray)(o,8).map(e=>(0,r.compressBools)(e)):[],l=(e=>{let t="";for(const r of e)t+=r.toString(2).padStart(3,"0");return(0,r.bitsToBytes)(t)})(a),h=[...(0,r.convertVarInt)(p.length),...(0,r.convertVarInt)(l.length)];return Uint8Array.from([...h,...p.flat(),...l,...c])};exports.decompressJSON=e=>{let s=0;const[o,c]=(0,r.readVarInt)(e,s);s=o;const[a,u]=(0,r.readVarInt)(e,s);s=a;const p=[];for(let t=0;t<c;t++)p.push(...(0,r.decompressBools)(e[s++]));let l=0;const h=e.subarray(s,s+u);s+=u;const f=((e,t)=>{const s=(0,r.bytesToBits)(e),n=[];for(let e=0;e<t;e++)n.push(parseInt(s.slice(3*e,3*e+3),2));return n})(h,8*h.length/3);let i=0;const d=o=>{if(o>500)throw new Error("JSON array too deep.");const c=f[i++];switch(c){case t.NULL:return null;case t.BOOL:return p[l++];case t.INT:{const[t,n]=(0,r.readVarInt)(e,s);return s=t,(0,r.demapZigZag)(n)}case t.FLOAT:{const t=(0,r.deconvertFloat)(Array.from(e.subarray(s,s+4)));return s+=4,t}case t.STRING:{const{value:r,length:t}=n(e,s);return s+=t,r}case t.ARRAY:{const[t,n]=(0,r.readVarInt)(e,s);s=t;const c=[];for(let e=0;e<n;e++)c.push(d(o+1));return c}case t.OBJECT:{const[t,c]=(0,r.readVarInt)(e,s);s=t;const a={};for(let r=0;r<c;r++){const{value:r,length:t}=n(e,s);s+=t,a[r]=d(o+1)}return a}default:throw new Error(`Unknown type ${c}`)}};return d(0)};
@@ -1,5 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
- export {};
@@ -1,6 +0,0 @@
1
- /**
2
- * Copyright 2026 Lily (liwybloc)
3
- * Licensed under the Apache License, Version 2.0.
4
- */
5
-
6
- 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=u,exports.CreateObjPacket=function(a){let{tag:n,types:r=[],dataMaxes:o,dataMins:u,noDataRange:f=!1,dontSpread:p=!1,autoFlatten:h=!1,validator:y=null,dataBatching:m=0,maxBatchSize:d=10,rateLimit:w=0,enabled:g=!0,async:k=!1,gzipCompression:P=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");for(const e of r)if(i(e))throw new Error(`Invalid packet type in "${n}" packet: ${e}`);f?(o=Array.from({length:r.length}).map(()=>s),u=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==u?u=Array.from({length:r.length}).map((e,t)=>o[t]):Array.isArray(u)||(u=Array.from({length:r.length}).map(()=>u)));const E=o.map(c),S=u.map((e,a)=>r[a]==t.PacketType.NONE?0:l(e,E[a])),x=new e.PacketSchema(!0,r,k,S,E,w,p,h,!1,m,d,P);return new e.Packet(n,x,y,g,!1)},exports.CreateEnumPacket=function(e){const{tag:t,enumData:a,dataMax:n=1,dataMin:r=0,noDataRange:o=!1,dontSpread:i=!1,validator:s=null,dataBatching:c=0,maxBatchSize:l=10,rateLimit:f=0,enabled:p=!0,async:h=!1}=e;return u({tag:t,type:a,dataMax:n,dataMin:r,noDataRange:o,dontSpread:i,validator:s,dataBatching:c,maxBatchSize:l,rateLimit:f,enabled:p,async:h})},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=f,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,s,c,l=!1){const u=e.getKey(a),p=e.getPacket(a);return async function(e,t,a,n,r,i,s){if(e[0]&&!i)return new Promise(t=>e[1].push([t,n,r]));e[0]=!0;const c=await s();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 c}(s,e,c,a,i,l,async()=>{if(p.rereference){if(-1===c)throw new Error("Cannot send a re-referenced packet from the server-wide sender!");const e=(0,r.hashValue)(i);if(p.lastSent[c]===e)return[u,n.EMPTY_UINT8,p];p.lastSent[c]=e}if(p.autoFlatten)i=f(i[0]);else{if(i.length>p.maxSize)throw new Error(`Packet "${a}" only allows ${p.maxSize} values!`);if(i.length<p.minSize)throw new Error(`Packet "${a}" requires at least ${p.minSize} values!`)}if(p.object){if(i=i.map(e=>Array.isArray(e)?e:[e]),!p.autoFlatten){const e=p.dataMin,t=p.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(p.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 p.processSend(i):n.EMPTY_UINT8;return[u,e,p]})}function i(e){return!(("number"==typeof e&&e in t.PacketType||e instanceof a.EnumPackage)&&e!=t.PacketType.KEY_EFFECTIVE)}const s=2048383;function c(e){return e<0?(console.warn("Having a data maximum below 0 does not do anything!"),0):e>s?(console.warn(`Only ${s} values can be sent on a type! Uhh make an issue if you want to send more.`),s):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(a){let{tag:n,type:r=t.PacketType.NONE,dataMax:o=1,dataMin:u=1,noDataRange:f=!1,dontSpread:p=!1,validator:h=null,dataBatching:y=0,maxBatchSize:m=10,rateLimit:d=0,enabled:w=!0,async:g=!1,gzipCompression:k=r==t.PacketType.JSON,rereference:P=!1}=a;if(!n)throw new Error("Tag not selected!");if(f?(u=P?1:0,o=s):null==u&&(u=r==t.PacketType.NONE?0:o),P&&0==u)throw new Error("Rereference cannot be true if the dataMin is 0");if(i(r))throw new Error(`Invalid packet type: ${r}`);const E=new e.PacketSchema(!1,r,g,l(u,o),c(o),d,p,!1,P,y,m,k);return new e.Packet(n,E,h,w,!1)}function f(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]))??[]}