sonic-ws 1.0.0-rc.7 → 1.0.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 +19 -11
- package/dist/index.js +1 -1
- package/dist/version.d.ts +5 -3
- package/dist/version.js +8 -5
- package/dist/ws/Connection.d.ts +19 -0
- package/dist/ws/Connection.js +17 -0
- package/dist/ws/client/core/ClientCore.d.ts +27 -9
- package/dist/ws/client/core/ClientCore.js +162 -64
- package/dist/ws/client/node/ClientNode.js +2 -2
- package/dist/ws/packets/PacketProcessors.d.ts +11 -6
- package/dist/ws/packets/PacketProcessors.js +233 -175
- package/dist/ws/packets/PacketType.d.ts +30 -16
- package/dist/ws/packets/PacketType.js +31 -17
- package/dist/ws/packets/Packets.d.ts +15 -14
- package/dist/ws/packets/Packets.js +117 -99
- package/dist/ws/server/SonicWSConnection.d.ts +30 -8
- package/dist/ws/server/SonicWSConnection.js +67 -25
- package/dist/ws/server/SonicWSServer.d.ts +22 -0
- package/dist/ws/server/SonicWSServer.js +50 -8
- package/dist/ws/util/ArrayUtil.js +1 -1
- package/dist/ws/util/BufferUtil.d.ts +4 -0
- package/dist/ws/util/BufferUtil.js +40 -0
- package/dist/ws/util/StringUtil.d.ts +6 -0
- package/dist/ws/util/StringUtil.js +66 -0
- package/dist/ws/util/enums/EnumHandler.d.ts +2 -3
- package/dist/ws/util/enums/EnumHandler.js +4 -7
- package/dist/ws/util/enums/EnumType.d.ts +3 -2
- package/dist/ws/util/enums/EnumType.js +21 -10
- package/dist/ws/util/packets/BatchHelper.d.ts +10 -6
- package/dist/ws/util/packets/BatchHelper.js +28 -16
- package/dist/ws/util/packets/CompressionUtil.d.ts +44 -0
- package/dist/ws/util/packets/CompressionUtil.js +321 -0
- package/dist/ws/util/packets/PacketHolder.d.ts +5 -10
- package/dist/ws/util/packets/PacketHolder.js +25 -13
- package/dist/ws/util/packets/PacketUtils.d.ts +11 -8
- package/dist/ws/util/packets/PacketUtils.js +31 -26
- package/dist/ws/util/packets/RateHandler.js +16 -1
- package/package.json +2 -2
- package/dist/ws/util/packets/CodePointUtil.d.ts +0 -22
- package/dist/ws/util/packets/CodePointUtil.js +0 -220
package/README.md
CHANGED
|
@@ -7,17 +7,19 @@ SonicWS is an ultra-lightweight, high-performance WebSocket library focused on m
|
|
|
7
7
|
Compression:
|
|
8
8
|
- Lossless compression up to 70% or more (for example, 38kb -> 14kb)
|
|
9
9
|
- Optimized bandwidth for many different types to fit special constraints
|
|
10
|
-
- Automatic helpers to flatten nested arrays for maximum wire efficiency
|
|
10
|
+
- Automatic helpers to flatten typed nested arrays for maximum wire efficiency (for example, [[1,2,3],[4,5,6]] to [[1,4],[2,5],[3,6]])
|
|
11
|
+
- Uses raw binary bytes to transmit data as efficiently as possible while still using high level readable code
|
|
11
12
|
|
|
12
13
|
Developer Friendly:
|
|
13
14
|
- Predefined data types of various sized integers, decimals, strings, enums, etc. and RAW for any special cases
|
|
14
|
-
- Keys are automatically indexed before transfer, improving readability (for example, send("pixel") and send("p")
|
|
15
|
+
- Keys are automatically indexed before transfer, improving readability and efficiency (for example, send("pixel") and send("p") use the same bandwidth)
|
|
15
16
|
- Data is validated and supports custom validation, ensuring only valid, safe, and untampered packets ever call your listeners
|
|
16
17
|
|
|
17
18
|
Security:
|
|
18
|
-
- Tamper-proof; any invalid packet instantly causes closure, and tampering
|
|
19
|
-
- Built-in ability for handshake packets, preventing
|
|
19
|
+
- Tamper-proof; any invalid packet instantly causes closure, and tampering becomes incredibly difficult
|
|
20
|
+
- Built-in ability for handshake packets, preventing repetitive initiation checks in listeners (for example, removes if(!init) everywhere)
|
|
20
21
|
- Built-in rate limiting for packets; ability for global send & receive, alongside per-packet rate limiting
|
|
22
|
+
- Built-in disabling & enabling of packets to prevent abuse
|
|
21
23
|
|
|
22
24
|
Performance & Scaling:
|
|
23
25
|
- Can handle very large packets in microseconds
|
|
@@ -27,9 +29,11 @@ Performance & Scaling:
|
|
|
27
29
|
|
|
28
30
|
Developer Experience:
|
|
29
31
|
- Minimal boilerplate code due to listeners only receiving valid data
|
|
30
|
-
- Enums can map to any primitive value
|
|
32
|
+
- Enums can map to any primitive value (e.g. number, string, boolean, null) and transmits in 1 byte
|
|
31
33
|
- Timers and intervals for sockets that automatically clear upon closure
|
|
34
|
+
- Many data types to maximize speed, clarity, bandwidth, and security
|
|
32
35
|
- Debug tools for socket ids, byte size, data logging, etc. for troubleshooting
|
|
36
|
+
- Very minimal learning curve, easy to work in
|
|
33
37
|
- JSDoc's for understanding
|
|
34
38
|
|
|
35
39
|
Whether you're making a real-time game, a dashboard, a distributed system, or anything else, SonicWS gets you safe, structured packets, fast.
|
|
@@ -51,11 +55,11 @@ Browser (Client):
|
|
|
51
55
|
```js
|
|
52
56
|
const wss = new SonicWSServer({
|
|
53
57
|
clientPackets: [
|
|
54
|
-
CreatePacket({tag: "pong", type: PacketType.
|
|
58
|
+
CreatePacket({tag: "pong", type: PacketType.VARINT, dataMax: 1})
|
|
55
59
|
],
|
|
56
60
|
serverPackets: [
|
|
57
|
-
CreatePacket({tag: "ping", type: PacketType.
|
|
58
|
-
CreateObjPacket({tag: "data", types: [PacketType.
|
|
61
|
+
CreatePacket({tag: "ping", type: PacketType.VARINT, dataMax: 1}),
|
|
62
|
+
CreateObjPacket({tag: "data", types: [PacketType.BYTES, PacketTypes.STRINGS], dataMaxes: [2, 3]})
|
|
59
63
|
],
|
|
60
64
|
websocketOptions: { port: 1234 }
|
|
61
65
|
});
|
|
@@ -66,10 +70,10 @@ wss.on_connect((socket) => {
|
|
|
66
70
|
|
|
67
71
|
socket.on("pong", (num) => {
|
|
68
72
|
console.log("Ponged!", num);
|
|
69
|
-
socket.send("data", [Math.floor(Math.random() *
|
|
73
|
+
socket.send("data", [Math.floor(Math.random() * 26), Math.floor(Math.random() * 256)], ["hello", "from", "server"]);
|
|
70
74
|
});
|
|
71
75
|
|
|
72
|
-
setInterval(() => {
|
|
76
|
+
socket.setInterval(() => {
|
|
73
77
|
socket.send("ping", Date.now());
|
|
74
78
|
}, 10000);
|
|
75
79
|
|
|
@@ -106,6 +110,10 @@ ws.on_close((event) => {
|
|
|
106
110
|
|
|
107
111
|
Batch rate limit is off by 1
|
|
108
112
|
|
|
113
|
+
Varint max is off by a bit
|
|
114
|
+
|
|
109
115
|
## PLANNED FEATURES
|
|
110
116
|
|
|
111
|
-
More data checking and better error handling
|
|
117
|
+
More data checking and better error handling
|
|
118
|
+
|
|
119
|
+
Implement a better system for data min/max
|
package/dist/index.js
CHANGED
package/dist/version.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/** Current protocol version */
|
|
2
|
-
export declare const VERSION =
|
|
3
|
-
/**
|
|
4
|
-
export declare const
|
|
2
|
+
export declare const VERSION = 9;
|
|
3
|
+
/** Server data suffix */
|
|
4
|
+
export declare const SERVER_SUFFIX = "SWS";
|
|
5
|
+
/** Server data suffix in array */
|
|
6
|
+
export declare const SERVER_SUFFIX_NUMS: number[];
|
package/dist/version.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
* Copyright 2025 Lily (
|
|
3
|
+
* Copyright 2025 Lily (liwybloc)
|
|
4
4
|
*
|
|
5
5
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
* you may not use this file except in compliance with the License.
|
|
@@ -15,8 +15,11 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.
|
|
18
|
+
exports.SERVER_SUFFIX_NUMS = exports.SERVER_SUFFIX = exports.VERSION = void 0;
|
|
19
|
+
var StringUtil_1 = require("./ws/util/StringUtil");
|
|
19
20
|
/** Current protocol version */
|
|
20
|
-
exports.VERSION =
|
|
21
|
-
/**
|
|
22
|
-
exports.
|
|
21
|
+
exports.VERSION = 9;
|
|
22
|
+
/** Server data suffix */
|
|
23
|
+
exports.SERVER_SUFFIX = "SWS";
|
|
24
|
+
/** Server data suffix in array */
|
|
25
|
+
exports.SERVER_SUFFIX_NUMS = (0, StringUtil_1.processCharCodes)(exports.SERVER_SUFFIX);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface Connection {
|
|
2
|
+
timers: Record<number, number>;
|
|
3
|
+
/** Sets an auto closing timer on the connection. Use connection.clearTimeout to prevent memory waste. */
|
|
4
|
+
setTimeout(call: () => void, time: number): number;
|
|
5
|
+
/** Sets an auto closing interval on the connection. Use connection.clearInterval to prevent memory waste. */
|
|
6
|
+
setInterval(call: () => void, time: number): number;
|
|
7
|
+
/** Safely clears a timer */
|
|
8
|
+
clearTimeout(index: number): void;
|
|
9
|
+
/** Safely clears an interval */
|
|
10
|
+
clearInterval(index: number): void;
|
|
11
|
+
/**
|
|
12
|
+
* Sends the uint8array through the connection
|
|
13
|
+
*/
|
|
14
|
+
raw_send(data: Uint8Array): void;
|
|
15
|
+
/**
|
|
16
|
+
* Closes the connection
|
|
17
|
+
*/
|
|
18
|
+
close(code?: number, reason?: string): void;
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2025 Lily (liwybloc)
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { PacketHolder } from '../../util/packets/PacketHolder';
|
|
2
|
-
|
|
2
|
+
import { Connection } from '../../Connection';
|
|
3
|
+
export declare abstract class SonicWSCore implements Connection {
|
|
3
4
|
/** Raw 'ws' library connection / webjs WebSocket class */
|
|
4
5
|
socket: WebSocket;
|
|
5
6
|
protected listeners: {
|
|
6
|
-
message: Array<(data:
|
|
7
|
+
message: Array<(data: Uint8Array) => void>;
|
|
7
8
|
close: Array<(event: CloseEvent) => void>;
|
|
8
9
|
event: {
|
|
9
|
-
[key:
|
|
10
|
+
[key: number]: Array<(...data: any[]) => void>;
|
|
10
11
|
};
|
|
11
12
|
};
|
|
12
13
|
protected preListen: {
|
|
@@ -16,12 +17,12 @@ export declare abstract class SonicWSCore {
|
|
|
16
17
|
protected serverPackets: PacketHolder;
|
|
17
18
|
private pastKeys;
|
|
18
19
|
private readyListeners;
|
|
19
|
-
private keyHandler;
|
|
20
|
-
private sendQueue;
|
|
21
|
-
private timers;
|
|
22
20
|
private batcher;
|
|
21
|
+
private bufferHandler;
|
|
23
22
|
id: number;
|
|
24
|
-
|
|
23
|
+
timers: Record<number, number>;
|
|
24
|
+
constructor(ws: WebSocket, bufferHandler: (val: MessageEvent) => Promise<Uint8Array>);
|
|
25
|
+
private reading;
|
|
25
26
|
private serverKeyHandler;
|
|
26
27
|
private invalidPacket;
|
|
27
28
|
private listenPacket;
|
|
@@ -31,11 +32,11 @@ export declare abstract class SonicWSCore {
|
|
|
31
32
|
* Listens for all messages rawly
|
|
32
33
|
* @param listener Callback for when data is received
|
|
33
34
|
*/
|
|
34
|
-
raw_onmessage(listener: (data:
|
|
35
|
+
raw_onmessage(listener: (data: Uint8Array) => void): void;
|
|
35
36
|
/**
|
|
36
37
|
* Sends raw data
|
|
37
38
|
*/
|
|
38
|
-
raw_send(data:
|
|
39
|
+
raw_send(data: Uint8Array): void;
|
|
39
40
|
/**
|
|
40
41
|
* Sends a packet to the server
|
|
41
42
|
* @param tag The tag of the packet
|
|
@@ -58,16 +59,33 @@ export declare abstract class SonicWSCore {
|
|
|
58
59
|
* @param listener The callback with the values
|
|
59
60
|
*/
|
|
60
61
|
on(tag: string, listener: (value: any[]) => void): void;
|
|
62
|
+
private setTimer;
|
|
61
63
|
/**
|
|
62
64
|
* Sets a timeout that will automatically end when the socket closes
|
|
63
65
|
* @param call The function to call
|
|
64
66
|
* @param time The time between now and the call (ms)
|
|
67
|
+
* @returns The timeout id to be used with socket.clearInterval(id)
|
|
65
68
|
*/
|
|
66
69
|
setTimeout(call: () => void, time: number): number;
|
|
67
70
|
/**
|
|
68
71
|
* Sets an interval that will automatically end when the socket closes
|
|
69
72
|
* @param call The function to call
|
|
70
73
|
* @param time The time between calls (ms)
|
|
74
|
+
* @returns The interval id to be used with socket.clearInterval(id)
|
|
71
75
|
*/
|
|
72
76
|
setInterval(call: () => void, time: number): number;
|
|
77
|
+
/**
|
|
78
|
+
* Clears a timeout
|
|
79
|
+
* @param id The timeout id
|
|
80
|
+
*/
|
|
81
|
+
clearTimeout(id: number): void;
|
|
82
|
+
/**
|
|
83
|
+
* Clears an interval
|
|
84
|
+
* @param id The interval id
|
|
85
|
+
*/
|
|
86
|
+
clearInterval(id: number): void;
|
|
87
|
+
/**
|
|
88
|
+
* Closes the connection
|
|
89
|
+
*/
|
|
90
|
+
close(code?: number, reason?: string): void;
|
|
73
91
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
* Copyright 2025 Lily (
|
|
3
|
+
* Copyright 2025 Lily (liwybloc)
|
|
4
4
|
*
|
|
5
5
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
* you may not use this file except in compliance with the License.
|
|
@@ -14,26 +14,61 @@
|
|
|
14
14
|
* See the License for the specific language governing permissions and
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
20
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
21
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
22
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
23
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
27
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
28
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
29
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
30
|
+
function step(op) {
|
|
31
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
32
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
33
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
34
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
35
|
+
switch (op[0]) {
|
|
36
|
+
case 0: case 1: t = op; break;
|
|
37
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
38
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
39
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
40
|
+
default:
|
|
41
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
42
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
43
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
44
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
45
|
+
if (t[2]) _.ops.pop();
|
|
46
|
+
_.trys.pop(); continue;
|
|
47
|
+
}
|
|
48
|
+
op = body.call(thisArg, _);
|
|
49
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
50
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
51
|
+
}
|
|
52
|
+
};
|
|
17
53
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
54
|
exports.SonicWSCore = void 0;
|
|
19
55
|
var PacketHolder_1 = require("../../util/packets/PacketHolder");
|
|
20
|
-
var
|
|
56
|
+
var CompressionUtil_1 = require("../../util/packets/CompressionUtil");
|
|
21
57
|
var PacketUtils_1 = require("../../util/packets/PacketUtils");
|
|
22
58
|
var version_1 = require("../../../version");
|
|
23
59
|
var Packets_1 = require("../../packets/Packets");
|
|
24
60
|
var BatchHelper_1 = require("../../util/packets/BatchHelper");
|
|
25
|
-
|
|
26
|
-
var THRESHOLD_MULT = 0.90;
|
|
61
|
+
var BufferUtil_1 = require("../../util/BufferUtil");
|
|
27
62
|
var SonicWSCore = /** @class */ (function () {
|
|
28
|
-
function SonicWSCore(ws) {
|
|
63
|
+
function SonicWSCore(ws, bufferHandler) {
|
|
29
64
|
var _this = this;
|
|
30
65
|
this.clientPackets = new PacketHolder_1.PacketHolder();
|
|
31
66
|
this.serverPackets = new PacketHolder_1.PacketHolder();
|
|
32
67
|
this.pastKeys = false;
|
|
33
68
|
this.readyListeners = [];
|
|
34
|
-
this.sendQueue = [];
|
|
35
|
-
this.timers = [];
|
|
36
69
|
this.id = -1;
|
|
70
|
+
this.timers = {};
|
|
71
|
+
this.reading = false;
|
|
37
72
|
this.socket = ws;
|
|
38
73
|
this.listeners = {
|
|
39
74
|
message: [],
|
|
@@ -43,74 +78,107 @@ var SonicWSCore = /** @class */ (function () {
|
|
|
43
78
|
this.preListen = {};
|
|
44
79
|
this.batcher = new BatchHelper_1.BatchHelper();
|
|
45
80
|
this.invalidPacket = this.invalidPacket.bind(this);
|
|
46
|
-
this.
|
|
47
|
-
this.
|
|
81
|
+
this.serverKeyHandler = this.serverKeyHandler.bind(this);
|
|
82
|
+
this.messageHandler = this.messageHandler.bind(this);
|
|
83
|
+
this.socket.addEventListener('message', this.serverKeyHandler);
|
|
48
84
|
this.socket.addEventListener('close', function (event) {
|
|
49
85
|
_this.listeners.close.forEach(function (listener) { return listener(event); });
|
|
50
|
-
_this.timers.forEach(clearTimeout);
|
|
86
|
+
Object.values(_this.timers).forEach(clearTimeout);
|
|
51
87
|
});
|
|
88
|
+
this.bufferHandler = bufferHandler;
|
|
52
89
|
}
|
|
53
90
|
SonicWSCore.prototype.serverKeyHandler = function (event) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
91
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
92
|
+
var data, version, _a, off, ckLength, ckData, skData;
|
|
93
|
+
var _this = this;
|
|
94
|
+
return __generator(this, function (_b) {
|
|
95
|
+
switch (_b.label) {
|
|
96
|
+
case 0:
|
|
97
|
+
// stupid asynchronous bullshit
|
|
98
|
+
if (this.reading)
|
|
99
|
+
return [2 /*return*/, this.messageHandler(event)];
|
|
100
|
+
this.reading = true;
|
|
101
|
+
return [4 /*yield*/, this.bufferHandler(event)];
|
|
102
|
+
case 1:
|
|
103
|
+
data = _b.sent();
|
|
104
|
+
if (data.length < 3 || (0, BufferUtil_1.as8String)(data.slice(0, 3)) != version_1.SERVER_SUFFIX) {
|
|
105
|
+
this.socket.close(1000);
|
|
106
|
+
throw new Error("The server requested is not a Sonic WS server.");
|
|
107
|
+
}
|
|
108
|
+
if (data.length == 3) {
|
|
109
|
+
// todo: queue
|
|
110
|
+
return [2 /*return*/];
|
|
111
|
+
}
|
|
112
|
+
version = data[3];
|
|
113
|
+
if (version != version_1.VERSION) {
|
|
114
|
+
this.socket.close(1000);
|
|
115
|
+
throw new Error("Version mismatch: ".concat(version > version_1.VERSION ? "client" : "server", " is outdated (server: ").concat(version, ", client: ").concat(version_1.VERSION, ")"));
|
|
116
|
+
}
|
|
117
|
+
_a = (0, CompressionUtil_1.readVarInt)(data, 4, false), off = _a[0], ckLength = _a[1];
|
|
118
|
+
ckData = data.slice(off, off + ckLength);
|
|
119
|
+
this.clientPackets.holdPackets(Packets_1.Packet.deserializeAll(ckData, true));
|
|
120
|
+
skData = data.slice(off + ckLength, data.length - 1);
|
|
121
|
+
this.serverPackets.holdPackets(Packets_1.Packet.deserializeAll(skData, true));
|
|
122
|
+
this.id = data[data.length - 1];
|
|
123
|
+
this.batcher.registerSendPackets(this.clientPackets, this);
|
|
124
|
+
Object.keys(this.preListen).forEach(function (tag) { return _this.preListen[tag].forEach(function (listener) {
|
|
125
|
+
var key = _this.serverPackets.getKey(tag);
|
|
126
|
+
// print the error to console without halting execution
|
|
127
|
+
if (key == null)
|
|
128
|
+
return console.error(new Error("The server does not send the packet with tag \"".concat(tag, "\"!")));
|
|
129
|
+
_this.listen(tag, listener);
|
|
130
|
+
}); });
|
|
131
|
+
this.preListen = null; // clear
|
|
132
|
+
this.pastKeys = true;
|
|
133
|
+
this.readyListeners.forEach(function (l) { return l(); });
|
|
134
|
+
this.readyListeners = null; // clear
|
|
135
|
+
this.socket.removeEventListener('message', this.serverKeyHandler);
|
|
136
|
+
this.socket.addEventListener('message', this.messageHandler);
|
|
137
|
+
return [2 /*return*/];
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
});
|
|
83
141
|
};
|
|
84
142
|
SonicWSCore.prototype.invalidPacket = function (listened) {
|
|
85
143
|
console.log(listened);
|
|
86
144
|
throw new Error("An error occured with data from the server!! This is probably my fault.. make an issue at https://github.com/cutelittlelily/sonic-ws");
|
|
87
145
|
};
|
|
88
146
|
SonicWSCore.prototype.listenPacket = function (data, code) {
|
|
89
|
-
|
|
147
|
+
var listeners = this.listeners.event[code];
|
|
148
|
+
if (!listeners)
|
|
149
|
+
return console.warn("Warn: No listener for packet " + this.serverPackets.getTag(code));
|
|
150
|
+
(0, PacketUtils_1.listenPacket)(data, listeners, this.invalidPacket);
|
|
90
151
|
};
|
|
91
152
|
SonicWSCore.prototype.messageHandler = function (event) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
153
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
154
|
+
var data, key, value, packet, batchData;
|
|
155
|
+
var _this = this;
|
|
156
|
+
return __generator(this, function (_a) {
|
|
157
|
+
switch (_a.label) {
|
|
158
|
+
case 0: return [4 /*yield*/, this.bufferHandler(event)];
|
|
159
|
+
case 1:
|
|
160
|
+
data = _a.sent();
|
|
161
|
+
this.listeners.message.forEach(function (listener) { return listener(data); });
|
|
162
|
+
if (data.length < 1)
|
|
163
|
+
return [2 /*return*/];
|
|
164
|
+
key = data[0];
|
|
165
|
+
value = data.slice(1);
|
|
166
|
+
packet = this.serverPackets.getPacket(this.serverPackets.getTag(key));
|
|
167
|
+
if (packet.dataBatching == 0) {
|
|
168
|
+
this.listenPacket(packet.listen(value, null), key);
|
|
169
|
+
return [2 /*return*/];
|
|
170
|
+
}
|
|
171
|
+
batchData = BatchHelper_1.BatchHelper.unravelBatch(packet, value, null);
|
|
172
|
+
if (typeof batchData == 'string')
|
|
173
|
+
return [2 /*return*/, this.invalidPacket(batchData)];
|
|
174
|
+
batchData.forEach(function (data) { return _this.listenPacket(data, key); });
|
|
175
|
+
return [2 /*return*/];
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
});
|
|
111
179
|
};
|
|
112
180
|
SonicWSCore.prototype.listen = function (key, listener) {
|
|
113
|
-
var skey = this.serverPackets.
|
|
181
|
+
var skey = this.serverPackets.getKey(key);
|
|
114
182
|
if (!skey) {
|
|
115
183
|
console.log("Key is not available on server: " + key);
|
|
116
184
|
return;
|
|
@@ -144,7 +212,7 @@ var SonicWSCore = /** @class */ (function () {
|
|
|
144
212
|
}
|
|
145
213
|
var _a = (0, PacketUtils_1.processPacket)(this.clientPackets, tag, values), code = _a[0], data = _a[1], packet = _a[2];
|
|
146
214
|
if (packet.dataBatching == 0)
|
|
147
|
-
this.raw_send(code
|
|
215
|
+
this.raw_send((0, BufferUtil_1.toPacketBuffer)(code, data));
|
|
148
216
|
else
|
|
149
217
|
this.batcher.batchPacket(code, data);
|
|
150
218
|
};
|
|
@@ -179,26 +247,56 @@ var SonicWSCore = /** @class */ (function () {
|
|
|
179
247
|
}
|
|
180
248
|
this.listen(tag, listener);
|
|
181
249
|
};
|
|
250
|
+
SonicWSCore.prototype.setTimer = function (id) {
|
|
251
|
+
this.timers[id] = id;
|
|
252
|
+
};
|
|
182
253
|
/**
|
|
183
254
|
* Sets a timeout that will automatically end when the socket closes
|
|
184
255
|
* @param call The function to call
|
|
185
256
|
* @param time The time between now and the call (ms)
|
|
257
|
+
* @returns The timeout id to be used with socket.clearInterval(id)
|
|
186
258
|
*/
|
|
187
259
|
SonicWSCore.prototype.setTimeout = function (call, time) {
|
|
188
|
-
var
|
|
189
|
-
|
|
260
|
+
var _this = this;
|
|
261
|
+
var timeout = setTimeout(function () {
|
|
262
|
+
call();
|
|
263
|
+
_this.clearTimeout(timeout);
|
|
264
|
+
}, time);
|
|
265
|
+
this.setTimer(timeout);
|
|
190
266
|
return timeout;
|
|
191
267
|
};
|
|
192
268
|
/**
|
|
193
269
|
* Sets an interval that will automatically end when the socket closes
|
|
194
270
|
* @param call The function to call
|
|
195
271
|
* @param time The time between calls (ms)
|
|
272
|
+
* @returns The interval id to be used with socket.clearInterval(id)
|
|
196
273
|
*/
|
|
197
274
|
SonicWSCore.prototype.setInterval = function (call, time) {
|
|
198
275
|
var interval = setInterval(call, time);
|
|
199
|
-
this.
|
|
276
|
+
this.setTimer(interval);
|
|
200
277
|
return interval;
|
|
201
278
|
};
|
|
279
|
+
/**
|
|
280
|
+
* Clears a timeout
|
|
281
|
+
* @param id The timeout id
|
|
282
|
+
*/
|
|
283
|
+
SonicWSCore.prototype.clearTimeout = function (id) {
|
|
284
|
+
clearTimeout(id);
|
|
285
|
+
delete this.timers[id];
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* Clears an interval
|
|
289
|
+
* @param id The interval id
|
|
290
|
+
*/
|
|
291
|
+
SonicWSCore.prototype.clearInterval = function (id) {
|
|
292
|
+
this.clearTimeout(id);
|
|
293
|
+
};
|
|
294
|
+
/**
|
|
295
|
+
* Closes the connection
|
|
296
|
+
*/
|
|
297
|
+
SonicWSCore.prototype.close = function (code, reason) {
|
|
298
|
+
this.socket.close(code, reason);
|
|
299
|
+
};
|
|
202
300
|
return SonicWSCore;
|
|
203
301
|
}());
|
|
204
302
|
exports.SonicWSCore = SonicWSCore;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
* Copyright 2025 Lily (
|
|
3
|
+
* Copyright 2025 Lily (liwybloc)
|
|
4
4
|
*
|
|
5
5
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
* you may not use this file except in compliance with the License.
|
|
@@ -46,7 +46,7 @@ var SonicWS = /** @class */ (function (_super) {
|
|
|
46
46
|
*/
|
|
47
47
|
function SonicWS(url, options) {
|
|
48
48
|
var ws = new ws_1.default.WebSocket(url, options);
|
|
49
|
-
return _super.call(this, ws) || this;
|
|
49
|
+
return _super.call(this, ws, function (val) { return Promise.resolve(new Uint8Array(val.data)); }) || this;
|
|
50
50
|
}
|
|
51
51
|
return SonicWS;
|
|
52
52
|
}(ClientCore_1.SonicWSCore));
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import { EnumPackage } from "../util/enums/EnumType";
|
|
1
2
|
import { Packet } from "./Packets";
|
|
2
3
|
import { PacketType } from "./PacketType";
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export declare function
|
|
7
|
-
export declare function
|
|
8
|
-
|
|
4
|
+
export type PacketTypeValidator = (data: Uint8Array, index: number) => false | any;
|
|
5
|
+
export type PacketReceiveProcessor = (data: Uint8Array, validationResult: any, index: number) => any;
|
|
6
|
+
export type PacketSendProcessor = (...data: any) => number[];
|
|
7
|
+
export declare function createValidator(type: PacketType, dataCap: number, dataMin: number, enumData: EnumPackage[]): PacketTypeValidator;
|
|
8
|
+
export declare function createReceiveProcessor(type: PacketType, enumData: EnumPackage[], cap: number): PacketReceiveProcessor;
|
|
9
|
+
/** Creates a function that processes a packet type */
|
|
10
|
+
export declare function createSendProcessor(type: PacketType): PacketSendProcessor;
|
|
11
|
+
export declare function createObjSendProcessor(packet: Packet): PacketSendProcessor;
|
|
12
|
+
export declare function createObjReceiveProcessor(packet: Packet): PacketReceiveProcessor;
|
|
13
|
+
export declare function createObjValidator(packet: Packet): PacketTypeValidator;
|