@colyseus/sdk 0.17.41 → 0.17.42
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/build/3rd_party/discord.cjs +1 -1
- package/build/3rd_party/discord.mjs +1 -1
- package/build/Auth.cjs +1 -1
- package/build/Auth.mjs +1 -1
- package/build/Client.cjs +1 -1
- package/build/Client.mjs +1 -1
- package/build/Connection.cjs +1 -1
- package/build/Connection.mjs +1 -1
- package/build/HTTP.cjs +1 -1
- package/build/HTTP.mjs +1 -1
- package/build/Room.cjs +1 -1
- package/build/Room.mjs +1 -1
- package/build/Storage.cjs +1 -1
- package/build/Storage.mjs +1 -1
- package/build/core/nanoevents.cjs +1 -1
- package/build/core/nanoevents.mjs +1 -1
- package/build/core/signal.cjs +1 -1
- package/build/core/signal.mjs +1 -1
- package/build/core/utils.cjs +1 -1
- package/build/core/utils.mjs +1 -1
- package/build/debug.cjs +1 -1
- package/build/debug.mjs +1 -1
- package/build/errors/Errors.cjs +1 -1
- package/build/errors/Errors.mjs +1 -1
- package/build/fetchXHR.cjs +1 -1
- package/build/fetchXHR.mjs +1 -1
- package/build/index.cjs +1 -1
- package/build/index.mjs +1 -1
- package/build/legacy.cjs +1 -1
- package/build/legacy.mjs +1 -1
- package/build/serializer/NoneSerializer.cjs +1 -1
- package/build/serializer/NoneSerializer.mjs +1 -1
- package/build/serializer/SchemaSerializer.cjs +1 -1
- package/build/serializer/SchemaSerializer.mjs +1 -1
- package/build/serializer/Serializer.cjs +1 -1
- package/build/serializer/Serializer.mjs +1 -1
- package/build/transport/H3Transport.cjs +70 -21
- package/build/transport/H3Transport.cjs.map +1 -1
- package/build/transport/H3Transport.d.ts +16 -0
- package/build/transport/H3Transport.mjs +69 -23
- package/build/transport/H3Transport.mjs.map +1 -1
- package/build/transport/WebSocketTransport.cjs +1 -1
- package/build/transport/WebSocketTransport.mjs +1 -1
- package/dist/colyseus.js +69 -21
- package/dist/colyseus.js.map +1 -1
- package/dist/debug.js +1 -1
- package/package.json +2 -2
- package/src/transport/H3Transport.ts +74 -24
package/dist/debug.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colyseus/sdk",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.42",
|
|
4
4
|
"description": "Colyseus Multiplayer SDK for JavaScript/TypeScript",
|
|
5
5
|
"author": "Endel Dreyer",
|
|
6
6
|
"license": "MIT",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"typescript": "^5.9.3",
|
|
83
83
|
"vite": "^5.0.11",
|
|
84
84
|
"vitest": "^2.1.1",
|
|
85
|
-
"@colyseus/core": "^0.17.
|
|
85
|
+
"@colyseus/core": "^0.17.42"
|
|
86
86
|
},
|
|
87
87
|
"peerDependencies": {
|
|
88
88
|
"@colyseus/core": "0.17.x"
|
|
@@ -1,6 +1,69 @@
|
|
|
1
1
|
import { encode, decode, type Iterator } from '@colyseus/schema';
|
|
2
2
|
import type { ITransport, ITransportEventMap } from "./ITransport.ts";
|
|
3
3
|
|
|
4
|
+
// 9 bytes is the maximum length of a variable-length integer prefix
|
|
5
|
+
const MAX_LENGTH_PREFIX_BYTES = 9;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Reassembles length-prefixed frames from arbitrary byte chunks.
|
|
9
|
+
*
|
|
10
|
+
* A single WebTransport `reader.read()` may:
|
|
11
|
+
* - deliver multiple whole frames in one chunk
|
|
12
|
+
* - split a frame (or its length prefix) across multiple chunks
|
|
13
|
+
*
|
|
14
|
+
* This reassembler buffers partial data across reads so each dispatched
|
|
15
|
+
* frame is exactly one complete message.
|
|
16
|
+
*/
|
|
17
|
+
export class FrameReassembler {
|
|
18
|
+
private pending: Uint8Array = new Uint8Array(0);
|
|
19
|
+
|
|
20
|
+
push(chunk: Uint8Array | undefined): Uint8Array[] {
|
|
21
|
+
if (!chunk || chunk.byteLength === 0) { return []; }
|
|
22
|
+
|
|
23
|
+
const bytes = (this.pending.byteLength === 0)
|
|
24
|
+
? chunk
|
|
25
|
+
: concatBytes(this.pending, chunk);
|
|
26
|
+
|
|
27
|
+
const frames: Uint8Array[] = [];
|
|
28
|
+
let offset = 0;
|
|
29
|
+
|
|
30
|
+
while (offset < bytes.byteLength) {
|
|
31
|
+
const it: Iterator = { offset };
|
|
32
|
+
let length: number;
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
length = decode.number(bytes as any, it);
|
|
36
|
+
} catch (e) {
|
|
37
|
+
// length prefix is incomplete — wait for more bytes
|
|
38
|
+
if (bytes.byteLength - offset <= MAX_LENGTH_PREFIX_BYTES) { break; }
|
|
39
|
+
throw e;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const frameEnd = it.offset + length;
|
|
43
|
+
if (frameEnd > bytes.byteLength) {
|
|
44
|
+
// payload is incomplete — wait for more bytes
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
frames.push(bytes.subarray(it.offset, frameEnd));
|
|
49
|
+
offset = frameEnd;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
this.pending = (offset < bytes.byteLength)
|
|
53
|
+
? bytes.slice(offset)
|
|
54
|
+
: new Uint8Array(0);
|
|
55
|
+
|
|
56
|
+
return frames;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function concatBytes(a: Uint8Array, b: Uint8Array): Uint8Array {
|
|
61
|
+
const out = new Uint8Array(a.byteLength + b.byteLength);
|
|
62
|
+
out.set(a, 0);
|
|
63
|
+
out.set(b, a.byteLength);
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
|
|
4
67
|
export class H3TransportTransport implements ITransport {
|
|
5
68
|
wt: WebTransport;
|
|
6
69
|
isOpen: boolean = false;
|
|
@@ -14,6 +77,9 @@ export class H3TransportTransport implements ITransport {
|
|
|
14
77
|
|
|
15
78
|
private lengthPrefixBuffer = new Uint8Array(9); // 9 bytes is the maximum length of a length prefix
|
|
16
79
|
|
|
80
|
+
private reliableReassembler = new FrameReassembler();
|
|
81
|
+
private unreliableReassembler = new FrameReassembler();
|
|
82
|
+
|
|
17
83
|
constructor(events: ITransportEventMap) {
|
|
18
84
|
this.events = events;
|
|
19
85
|
}
|
|
@@ -110,19 +176,11 @@ export class H3TransportTransport implements ITransport {
|
|
|
110
176
|
//
|
|
111
177
|
// a single read may contain multiple messages
|
|
112
178
|
// each message is prefixed with its length
|
|
179
|
+
// a read may also deliver a partial frame; buffer across reads
|
|
113
180
|
//
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
do {
|
|
118
|
-
//
|
|
119
|
-
// QUESTION: should we buffer the message in case it's not fully read?
|
|
120
|
-
//
|
|
121
|
-
|
|
122
|
-
const length = decode.number(messages as any, it);
|
|
123
|
-
this.events.onmessage({ data: messages.subarray(it.offset, it.offset + length) });
|
|
124
|
-
it.offset += length;
|
|
125
|
-
} while (it.offset < messages.length);
|
|
181
|
+
for (const frame of this.reliableReassembler.push(result.value)) {
|
|
182
|
+
this.events.onmessage({ data: frame });
|
|
183
|
+
}
|
|
126
184
|
|
|
127
185
|
} catch (e) {
|
|
128
186
|
if (e.message.indexOf("session is closed") === -1) {
|
|
@@ -147,19 +205,11 @@ export class H3TransportTransport implements ITransport {
|
|
|
147
205
|
//
|
|
148
206
|
// a single read may contain multiple messages
|
|
149
207
|
// each message is prefixed with its length
|
|
208
|
+
// a read may also deliver a partial frame; buffer across reads
|
|
150
209
|
//
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
do {
|
|
155
|
-
//
|
|
156
|
-
// QUESTION: should we buffer the message in case it's not fully read?
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
const length = decode.number(messages as any, it);
|
|
160
|
-
this.events.onmessage({ data: messages.subarray(it.offset, it.offset + length) });
|
|
161
|
-
it.offset += length;
|
|
162
|
-
} while (it.offset < messages.length);
|
|
210
|
+
for (const frame of this.unreliableReassembler.push(result.value)) {
|
|
211
|
+
this.events.onmessage({ data: frame });
|
|
212
|
+
}
|
|
163
213
|
|
|
164
214
|
} catch (e) {
|
|
165
215
|
if (e.message.indexOf("session is closed") === -1) {
|