twinwire 0.0.0-stage → 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.
Files changed (95) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/LICENSE +21 -0
  3. package/README.md +128 -2
  4. package/dist/browser/twinwire.js +2075 -0
  5. package/dist/browser/twinwire.js.map +7 -0
  6. package/dist/browser/twinwire.min.js +1 -0
  7. package/dist/browser/twinwire.mjs +2052 -0
  8. package/dist/browser/twinwire.mjs.map +7 -0
  9. package/dist/browser.d.ts +5 -0
  10. package/dist/browser.js +6 -0
  11. package/dist/browser.js.map +1 -0
  12. package/dist/client/client.d.ts +128 -0
  13. package/dist/client/client.js +470 -0
  14. package/dist/client/client.js.map +1 -0
  15. package/dist/client/index.d.ts +3 -0
  16. package/dist/client/index.js +4 -0
  17. package/dist/client/index.js.map +1 -0
  18. package/dist/client/lobby.d.ts +40 -0
  19. package/dist/client/lobby.js +122 -0
  20. package/dist/client/lobby.js.map +1 -0
  21. package/dist/client/rtc.d.ts +17 -0
  22. package/dist/client/rtc.js +102 -0
  23. package/dist/client/rtc.js.map +1 -0
  24. package/dist/core/budget.d.ts +27 -0
  25. package/dist/core/budget.js +39 -0
  26. package/dist/core/budget.js.map +1 -0
  27. package/dist/core/endpoint.d.ts +144 -0
  28. package/dist/core/endpoint.js +501 -0
  29. package/dist/core/endpoint.js.map +1 -0
  30. package/dist/core/lobby.d.ts +59 -0
  31. package/dist/core/lobby.js +53 -0
  32. package/dist/core/lobby.js.map +1 -0
  33. package/dist/core/protocol.d.ts +52 -0
  34. package/dist/core/protocol.js +100 -0
  35. package/dist/core/protocol.js.map +1 -0
  36. package/dist/core/reliable.d.ts +52 -0
  37. package/dist/core/reliable.js +116 -0
  38. package/dist/core/reliable.js.map +1 -0
  39. package/dist/core/rtc.d.ts +28 -0
  40. package/dist/core/rtc.js +21 -0
  41. package/dist/core/rtc.js.map +1 -0
  42. package/dist/index.d.ts +6 -0
  43. package/dist/index.js +7 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/netcode/clock.d.ts +15 -0
  46. package/dist/netcode/clock.js +37 -0
  47. package/dist/netcode/clock.js.map +1 -0
  48. package/dist/netcode/codec.d.ts +10 -0
  49. package/dist/netcode/codec.js +95 -0
  50. package/dist/netcode/codec.js.map +1 -0
  51. package/dist/netcode/index.d.ts +9 -0
  52. package/dist/netcode/index.js +10 -0
  53. package/dist/netcode/index.js.map +1 -0
  54. package/dist/netcode/inputs.d.ts +7 -0
  55. package/dist/netcode/inputs.js +43 -0
  56. package/dist/netcode/inputs.js.map +1 -0
  57. package/dist/netcode/interpolation.d.ts +44 -0
  58. package/dist/netcode/interpolation.js +101 -0
  59. package/dist/netcode/interpolation.js.map +1 -0
  60. package/dist/netcode/prediction.d.ts +40 -0
  61. package/dist/netcode/prediction.js +97 -0
  62. package/dist/netcode/prediction.js.map +1 -0
  63. package/dist/netcode/replication.d.ts +36 -0
  64. package/dist/netcode/replication.js +90 -0
  65. package/dist/netcode/replication.js.map +1 -0
  66. package/dist/netcode/snapshots.d.ts +29 -0
  67. package/dist/netcode/snapshots.js +78 -0
  68. package/dist/netcode/snapshots.js.map +1 -0
  69. package/dist/netcode/spatial.d.ts +16 -0
  70. package/dist/netcode/spatial.js +63 -0
  71. package/dist/netcode/spatial.js.map +1 -0
  72. package/dist/netcode/timing.d.ts +37 -0
  73. package/dist/netcode/timing.js +41 -0
  74. package/dist/netcode/timing.js.map +1 -0
  75. package/dist/server/index.d.ts +4 -0
  76. package/dist/server/index.js +5 -0
  77. package/dist/server/index.js.map +1 -0
  78. package/dist/server/lobby.d.ts +134 -0
  79. package/dist/server/lobby.js +462 -0
  80. package/dist/server/lobby.js.map +1 -0
  81. package/dist/server/rtc.d.ts +38 -0
  82. package/dist/server/rtc.js +102 -0
  83. package/dist/server/rtc.js.map +1 -0
  84. package/dist/server/server.d.ts +145 -0
  85. package/dist/server/server.js +457 -0
  86. package/dist/server/server.js.map +1 -0
  87. package/dist/server/turn.d.ts +22 -0
  88. package/dist/server/turn.js +52 -0
  89. package/dist/server/turn.js.map +1 -0
  90. package/docs/ADOPTING.md +64 -0
  91. package/docs/API.md +181 -0
  92. package/docs/ARCHITECTURE.md +101 -0
  93. package/docs/OPERATIONS.md +93 -0
  94. package/docs/RELEASE-CHECKLIST.md +25 -0
  95. package/package.json +100 -4
@@ -0,0 +1,501 @@
1
+ import { TokenBucket } from './budget.js';
2
+ import { ReliableEvents } from './reliable.js';
3
+ import { decodeFrame, encodeFrame, FrameKind, DEFAULT_STATE_BYTES, HEADER_BYTES, MAX_STATE_BYTES, MTU_STATE_BYTES, newer, stringify, isUint, utf8, fromUtf8, utf8Length, } from './protocol.js';
4
+ const DATAGRAM_EVENT_BYTES = 960;
5
+ export class Endpoint {
6
+ events;
7
+ stats = { bytesSent: 0, bytesReceived: 0, statesSent: 0, statesReceived: 0,
8
+ stale: 0, expired: 0, coalesced: 0, congested: 0, invalid: 0, fastTransitions: 0, datagramRttMs: 0,
9
+ eventsViaDatagram: 0, datagramEventFrames: 0, stateAcksSent: 0, stateAcksReceived: 0, impairedDrops: 0 };
10
+ onState = () => { };
11
+ onEvent = () => { };
12
+ onFastDown = () => { };
13
+ onFastChange = () => { };
14
+ onEventAck = () => { };
15
+ /** The peer has seen state `seq` on `stream` (only for states sent with `ack: true`). */
16
+ onStateAck = () => { };
17
+ reliable;
18
+ datagram;
19
+ epoch = 0;
20
+ sequence = new Map();
21
+ received = new Map();
22
+ queued = new Map();
23
+ acksOut = new Map();
24
+ acksIn = new Map();
25
+ lastAckSentAt = -Infinity;
26
+ lastEventSent = 0;
27
+ datagramAcked = 0;
28
+ ackDue = false;
29
+ lastProbe = -Infinity;
30
+ proofAt = -Infinity;
31
+ attachedAt = 0;
32
+ probes = new Map();
33
+ probeSeq = 0;
34
+ fast = false;
35
+ now;
36
+ budget;
37
+ highWater;
38
+ maxStreams;
39
+ probeInterval;
40
+ probeTimeout;
41
+ maxStateBytes;
42
+ datagramStateBytes;
43
+ datagramEvents;
44
+ stateAckInterval;
45
+ impairment;
46
+ constructor(o = {}) {
47
+ this.now = o.now ?? (() => performance.now());
48
+ const rate = o.bytesPerSecond ?? 32 * 1024;
49
+ this.budget = new TokenBucket(rate, o.burstBytes ?? Math.max(rate / 2, 16 * 1024), this.now());
50
+ this.highWater = o.maxBufferedBytes ?? 64 * 1024;
51
+ this.maxStreams = o.maxStreams ?? 1024;
52
+ this.probeInterval = o.probeIntervalMs ?? 250;
53
+ this.probeTimeout = o.probeTimeoutMs ?? 1500;
54
+ this.maxStateBytes = o.maxStateBytes ?? DEFAULT_STATE_BYTES;
55
+ this.datagramStateBytes = o.datagramStateBytes ?? 8 * 1024;
56
+ this.datagramEvents = o.datagramEvents ?? true;
57
+ this.stateAckInterval = o.stateAckIntervalMs ?? 50;
58
+ this.events = new ReliableEvents(o.events);
59
+ if (!(this.highWater > 0) || !isUint(this.maxStreams, 65536) || this.maxStreams < 1 ||
60
+ !(this.probeInterval >= 10) || !(this.probeTimeout >= this.probeInterval * 2) ||
61
+ !isUint(this.maxStateBytes, MAX_STATE_BYTES) || this.maxStateBytes < 1 ||
62
+ !(this.datagramStateBytes >= MTU_STATE_BYTES) || !(this.stateAckInterval >= 0))
63
+ throw new RangeError('Invalid endpoint limits');
64
+ if (o.impair)
65
+ this.setImpairment(o.impair);
66
+ }
67
+ get active() { return !!this.reliable?.open; }
68
+ get fastActive() { return this.fast && !!this.datagram?.open && this.now() - this.proofAt <= this.probeTimeout; }
69
+ get pendingStates() { return this.queued.size; }
70
+ get connectionEpoch() { return this.epoch; }
71
+ get maxFrameBytes() { return this.maxStateBytes + HEADER_BYTES; }
72
+ /** Newest seq the peer reported for an acknowledged stream in this connection epoch. */
73
+ stateAck(stream) { return this.acksIn.get(stream); }
74
+ setImpairment(i) {
75
+ if (!i) {
76
+ this.impairment = undefined;
77
+ return;
78
+ }
79
+ const { lagMs = 0, jitterMs = 0, loss = 0, duplicate = 0 } = i;
80
+ if (![lagMs, jitterMs].every(v => Number.isFinite(v) && v >= 0 && v <= 10000) ||
81
+ ![loss, duplicate].every(v => Number.isFinite(v) && v >= 0 && v <= 1))
82
+ throw new RangeError('Invalid impairment');
83
+ this.impairment = lagMs || jitterMs || loss || duplicate ? { lagMs, jitterMs, loss, duplicate } : undefined;
84
+ }
85
+ get impaired() { return this.impairment && { ...this.impairment }; }
86
+ attach(epoch, reliable) {
87
+ if (!isUint(epoch) || !epoch)
88
+ throw new Error('Invalid epoch');
89
+ this.detach();
90
+ this.epoch = epoch;
91
+ this.reliable = this.impairReliable(reliable);
92
+ this.ackDue = this.events.received > 0;
93
+ this.lastEventSent = this.events.acknowledged;
94
+ this.datagramAcked = 0;
95
+ this.sequence.clear();
96
+ this.received.clear();
97
+ this.acksOut.clear();
98
+ this.acksIn.clear();
99
+ for (const e of this.events.entries()) {
100
+ e.datagramAt = -Infinity;
101
+ e.datagramTries = 0;
102
+ }
103
+ }
104
+ detach() {
105
+ this.dropDatagram(false);
106
+ this.reliable = undefined;
107
+ this.queued.clear();
108
+ }
109
+ attachDatagram(link) {
110
+ this.dropDatagram(false);
111
+ this.datagram = this.impairDatagram(link);
112
+ this.attachedAt = this.now();
113
+ this.lastProbe = -Infinity;
114
+ this.proofAt = -Infinity;
115
+ this.probes.clear();
116
+ }
117
+ dropDatagram(notify = true) {
118
+ const d = this.datagram;
119
+ this.datagram = undefined;
120
+ this.proofAt = -Infinity;
121
+ this.probes.clear();
122
+ this.setFast(false);
123
+ try {
124
+ d?.close();
125
+ }
126
+ catch { /* already closed */ }
127
+ if (d && notify)
128
+ this.onFastDown();
129
+ }
130
+ setFast(next) {
131
+ if (next !== this.fast) {
132
+ this.fast = next;
133
+ this.stats.fastTransitions++;
134
+ this.onFastChange(next);
135
+ }
136
+ }
137
+ sendControl(m) {
138
+ const data = stringify(m), ws = this.reliable;
139
+ if (!ws?.open || ws.bufferedAmount > this.highWater)
140
+ return false;
141
+ try {
142
+ if (!ws.send(data))
143
+ return false;
144
+ }
145
+ catch {
146
+ return false;
147
+ }
148
+ this.stats.bytesSent += utf8Length(data);
149
+ return true;
150
+ }
151
+ sendEvent(data) { const seq = this.events.push(data); this.flush(); return seq; }
152
+ /** Retains only the newest unsent payload per stream. Returns the state's seq (0 when offline).
153
+ * An accepted enqueue is not a delivery guarantee; use `ack: true` and onStateAck to learn what arrived. */
154
+ sendState(stream, data, time, o = {}) {
155
+ if (!this.active)
156
+ return 0;
157
+ if (!isUint(stream, 65535) || !Number.isFinite(time) || data.length > this.maxStateBytes ||
158
+ !(o.ttlMs === undefined || Number.isFinite(o.ttlMs) && o.ttlMs > 0) ||
159
+ !(o.priority === undefined || Number.isFinite(o.priority) && o.priority >= 0))
160
+ throw new RangeError('Invalid state');
161
+ if (!this.sequence.has(stream) && this.sequence.size >= this.maxStreams)
162
+ throw new Error('State stream limit');
163
+ const seq = ((this.sequence.get(stream) ?? 0) + 1) >>> 0 || 1;
164
+ this.sequence.set(stream, seq);
165
+ const old = this.queued.get(stream);
166
+ if (old)
167
+ this.stats.coalesced++;
168
+ const now = this.now();
169
+ this.queued.set(stream, { frame: { kind: o.ack ? FrameKind.stateAcked : FrameKind.state, epoch: this.epoch, stream, seq, time, payload: data.slice() },
170
+ first: old?.first ?? now, deadline: now + (o.ttlMs ?? 100), priority: o.priority ?? 1 });
171
+ return seq;
172
+ }
173
+ receiveControl(m) {
174
+ if (m.e !== this.epoch || !this.active)
175
+ return false;
176
+ if (m.t === 'event') {
177
+ if (typeof m.s !== 'number' || !('d' in m))
178
+ throw new Error('Invalid event');
179
+ this.events.receive(m.s, m.d, this.onEvent);
180
+ this.ackDue = !this.sendControl({ t: 'ack', e: this.epoch, s: this.events.received });
181
+ return true;
182
+ }
183
+ if (m.t === 'ack') {
184
+ if (typeof m.s !== 'number')
185
+ throw new Error('Invalid acknowledgement');
186
+ if (this.events.ack(m.s))
187
+ this.onEventAck(m.s);
188
+ return true;
189
+ }
190
+ return false;
191
+ }
192
+ receiveBinary(bytes, via) {
193
+ this.stats.bytesReceived += bytes.length;
194
+ if (!this.active)
195
+ return;
196
+ const f = decodeFrame(bytes, this.maxFrameBytes);
197
+ if (!f) {
198
+ this.stats.invalid++;
199
+ return;
200
+ }
201
+ if (f.epoch !== this.epoch || (via === 'rtc' && !this.datagram)) {
202
+ this.stats.stale++;
203
+ return;
204
+ }
205
+ switch (f.kind) {
206
+ case FrameKind.probe:
207
+ if (via === 'rtc')
208
+ this.sendFast(encodeFrame({ ...f, kind: FrameKind.reply }));
209
+ return;
210
+ case FrameKind.reply: {
211
+ if (via !== 'rtc')
212
+ return;
213
+ const sent = this.probes.get(f.seq);
214
+ if (sent === undefined || sent !== f.time)
215
+ return;
216
+ this.probes.delete(f.seq);
217
+ const rtt = this.now() - sent;
218
+ if (rtt < 0 || rtt > this.probeTimeout)
219
+ return;
220
+ this.proofAt = this.now();
221
+ this.stats.datagramRttMs = rtt;
222
+ this.setFast(true);
223
+ return;
224
+ }
225
+ case FrameKind.events: return this.receiveDatagramEvents(f);
226
+ case FrameKind.sack: return this.receiveStateAcks(f);
227
+ }
228
+ const prior = this.received.get(f.stream);
229
+ if (prior !== undefined && !newer(f.seq, prior)) {
230
+ this.stats.stale++;
231
+ return;
232
+ }
233
+ if (prior === undefined && this.received.size >= this.maxStreams) {
234
+ this.stats.invalid++;
235
+ return;
236
+ }
237
+ this.received.set(f.stream, f.seq);
238
+ this.stats.statesReceived++;
239
+ if (f.kind === FrameKind.stateAcked)
240
+ this.acksOut.set(f.stream, f.seq);
241
+ this.onState({ stream: f.stream, seq: f.seq, time: f.time, data: f.payload, via });
242
+ }
243
+ receiveDatagramEvents(f) {
244
+ if (f.seq <= this.events.sentThrough && this.events.ack(f.seq))
245
+ this.onEventAck(f.seq);
246
+ if (!f.payload.length)
247
+ return;
248
+ let list;
249
+ try {
250
+ list = JSON.parse(fromUtf8(f.payload));
251
+ }
252
+ catch {
253
+ this.stats.invalid++;
254
+ return;
255
+ }
256
+ if (!Array.isArray(list) || list.length > 64) {
257
+ this.stats.invalid++;
258
+ return;
259
+ }
260
+ let delivered = 0;
261
+ for (const item of list) {
262
+ if (!Array.isArray(item) || item.length !== 2 || !Number.isSafeInteger(item[0])) {
263
+ this.stats.invalid++;
264
+ return;
265
+ }
266
+ try {
267
+ delivered += this.events.receive(item[0], item[1], this.onEvent);
268
+ }
269
+ catch {
270
+ this.stats.invalid++;
271
+ return;
272
+ }
273
+ }
274
+ if (delivered) {
275
+ this.stats.eventsViaDatagram += delivered;
276
+ this.ackDue = true;
277
+ }
278
+ }
279
+ receiveStateAcks(f) {
280
+ const p = f.payload;
281
+ if (p.length % 6) {
282
+ this.stats.invalid++;
283
+ return;
284
+ }
285
+ const v = new DataView(p.buffer, p.byteOffset, p.byteLength);
286
+ for (let at = 0; at < p.length; at += 6) {
287
+ const stream = v.getUint16(at, true), seq = v.getUint32(at + 2, true), sent = this.sequence.get(stream);
288
+ if (sent === undefined || newer(seq, sent))
289
+ continue;
290
+ const prior = this.acksIn.get(stream);
291
+ if (prior !== undefined && !newer(seq, prior))
292
+ continue;
293
+ this.acksIn.set(stream, seq);
294
+ this.stats.stateAcksReceived++;
295
+ this.onStateAck(stream, seq);
296
+ }
297
+ }
298
+ sendFast(b) {
299
+ const d = this.datagram;
300
+ if (!d?.open || d.bufferedAmount > this.highWater)
301
+ return false;
302
+ try {
303
+ if (!d.send(b))
304
+ return false;
305
+ }
306
+ catch {
307
+ return false;
308
+ }
309
+ this.stats.bytesSent += b.length;
310
+ return true;
311
+ }
312
+ /** Binary on the datagram path when it is proven, else the WebSocket. */
313
+ sendBinary(b, preferFast) {
314
+ const ws = this.reliable;
315
+ if (preferFast && this.fastActive && this.datagram && this.datagram.bufferedAmount <= this.highWater)
316
+ return this.sendFast(b);
317
+ if (!ws?.open || ws.bufferedAmount > this.highWater)
318
+ return false;
319
+ try {
320
+ if (!ws.send(b))
321
+ return false;
322
+ }
323
+ catch {
324
+ return false;
325
+ }
326
+ this.stats.bytesSent += b.length;
327
+ return true;
328
+ }
329
+ pump() {
330
+ const now = this.now(), d = this.datagram;
331
+ if (d) {
332
+ if ((!d.open && now - this.attachedAt > this.probeTimeout) ||
333
+ (this.fast && now - this.proofAt > this.probeTimeout) ||
334
+ (!this.fast && now - this.attachedAt > this.probeTimeout * 2))
335
+ this.dropDatagram();
336
+ else if (d.open && now - this.lastProbe >= this.probeInterval) {
337
+ this.lastProbe = now;
338
+ const seq = this.probeSeq = (this.probeSeq + 1) >>> 0;
339
+ this.probes.set(seq, now);
340
+ for (const [s, at] of this.probes)
341
+ if (now - at > this.probeTimeout)
342
+ this.probes.delete(s);
343
+ this.sendFast(encodeFrame({ kind: FrameKind.probe, epoch: this.epoch, stream: 0, seq, time: now, payload: new Uint8Array() }));
344
+ }
345
+ }
346
+ this.flush();
347
+ }
348
+ flush(maxPackets = 8) {
349
+ const ws = this.reliable, now = this.now();
350
+ if (!ws?.open)
351
+ return;
352
+ if (this.ackDue)
353
+ this.ackDue = !this.sendControl({ t: 'ack', e: this.epoch, s: this.events.received });
354
+ for (const e of this.events.entries()) {
355
+ if (e.seq <= this.lastEventSent)
356
+ continue;
357
+ const encoded = `{"t":"event","e":${this.epoch},"s":${e.seq},"d":${e.text}}`;
358
+ const size = utf8Length(encoded);
359
+ if (ws.bufferedAmount > this.highWater || !this.budget.take(size, now))
360
+ break;
361
+ try {
362
+ if (!ws.send(encoded))
363
+ break;
364
+ }
365
+ catch {
366
+ break;
367
+ }
368
+ this.events.sent(e.seq);
369
+ this.lastEventSent = e.seq;
370
+ this.stats.bytesSent += size;
371
+ }
372
+ if (this.fastActive)
373
+ this.flushDatagramEvents(now);
374
+ if (this.acksOut.size && now - this.lastAckSentAt >= this.stateAckInterval)
375
+ this.flushStateAcks(now);
376
+ for (const [id, q] of this.queued)
377
+ if (q.deadline <= now) {
378
+ this.queued.delete(id);
379
+ this.stats.expired++;
380
+ }
381
+ if (!this.queued.size)
382
+ return;
383
+ const queue = [...this.queued.values()].sort((a, b) => (b.priority + (now - b.first) / 100) - (a.priority + (now - a.first) / 100));
384
+ let count = 0;
385
+ for (const q of queue) {
386
+ if (count++ >= maxPackets)
387
+ break;
388
+ const b = encodeFrame(q.frame);
389
+ if (!this.budget.take(b.length, now))
390
+ break;
391
+ if (!this.sendBinary(b, q.frame.payload.length <= this.datagramStateBytes)) {
392
+ this.stats.congested++;
393
+ break;
394
+ }
395
+ this.stats.statesSent++;
396
+ this.queued.delete(q.frame.stream);
397
+ }
398
+ }
399
+ /** Copies of WebSocket-sent, unacknowledged events, retried on the datagram path for UDP-like latency. */
400
+ flushDatagramEvents(now) {
401
+ const retry = Math.max(40, Math.min(200, this.stats.datagramRttMs * 1.5 + 10));
402
+ const items = [];
403
+ let bytes = 2;
404
+ if (this.datagramEvents)
405
+ for (const e of this.events.entries()) {
406
+ if (e.seq > this.lastEventSent)
407
+ break;
408
+ if (e.datagramTries >= 6 || now - e.datagramAt < retry || e.bytes - 64 > DATAGRAM_EVENT_BYTES)
409
+ continue;
410
+ const item = `[${e.seq},${e.text}]`, size = utf8Length(item) + 1;
411
+ if (bytes + size > DATAGRAM_EVENT_BYTES || items.length >= 64)
412
+ break;
413
+ items.push(item);
414
+ bytes += size;
415
+ e.datagramAt = now;
416
+ e.datagramTries++;
417
+ }
418
+ const ackChanged = this.events.received !== this.datagramAcked;
419
+ if (!items.length && !ackChanged)
420
+ return;
421
+ const payload = utf8('[' + items.join(',') + ']');
422
+ if (this.sendFast(encodeFrame({ kind: FrameKind.events, epoch: this.epoch, stream: 0, seq: this.events.received >>> 0, time: now, payload }))) {
423
+ this.datagramAcked = this.events.received;
424
+ this.stats.datagramEventFrames++;
425
+ }
426
+ }
427
+ flushStateAcks(now) {
428
+ const pairs = [...this.acksOut].slice(0, 150), p = new Uint8Array(pairs.length * 6), v = new DataView(p.buffer);
429
+ pairs.forEach(([stream, seq], i) => { v.setUint16(i * 6, stream, true); v.setUint32(i * 6 + 2, seq, true); });
430
+ if (this.sendBinary(encodeFrame({ kind: FrameKind.sack, epoch: this.epoch, stream: 0, seq: 0, time: now, payload: p }), true)) {
431
+ for (const [stream, seq] of pairs)
432
+ if (this.acksOut.get(stream) === seq)
433
+ this.acksOut.delete(stream);
434
+ this.lastAckSentAt = now;
435
+ this.stats.stateAcksSent++;
436
+ }
437
+ }
438
+ /** Delays a stream-like link without ever reordering it: one queue, one timer. */
439
+ impairReliable(link) {
440
+ let tail = 0, timer;
441
+ const queue = [];
442
+ const drain = () => {
443
+ timer = undefined;
444
+ const t = performance.now();
445
+ while (queue.length && queue[0].at <= t + 1) {
446
+ const { data } = queue.shift();
447
+ if (link.open)
448
+ try {
449
+ link.send(data);
450
+ }
451
+ catch { /* reconnect owns recovery */ }
452
+ }
453
+ if (queue.length)
454
+ timer = setTimeout(drain, queue[0].at - t);
455
+ };
456
+ const self = this;
457
+ return {
458
+ get open() { return link.open; }, get bufferedAmount() { return link.bufferedAmount; },
459
+ close: () => { queue.length = 0; clearTimeout(timer); timer = undefined; link.close(); },
460
+ send(data) {
461
+ const i = self.impairment;
462
+ if (!i && !queue.length)
463
+ return link.send(data);
464
+ if (!link.open)
465
+ return false;
466
+ const t = performance.now(), at = Math.max(tail, t + (i?.lagMs ?? 0) + Math.random() * (i?.jitterMs ?? 0));
467
+ tail = at;
468
+ queue.push({ at, data: typeof data === 'string' ? data : data.slice() });
469
+ if (!timer)
470
+ timer = setTimeout(drain, at - t);
471
+ return true;
472
+ },
473
+ };
474
+ }
475
+ impairDatagram(link) {
476
+ const self = this;
477
+ return {
478
+ get open() { return link.open; }, get bufferedAmount() { return link.bufferedAmount; }, close: () => link.close(),
479
+ send(data) {
480
+ const i = self.impairment;
481
+ if (!i)
482
+ return link.send(data);
483
+ if (!link.open)
484
+ return false;
485
+ const copies = Math.random() < i.loss ? 0 : Math.random() < i.duplicate ? 2 : 1;
486
+ if (!copies)
487
+ self.stats.impairedDrops++;
488
+ for (let n = 0; n < copies; n++) {
489
+ const copy = data.slice();
490
+ setTimeout(() => { if (link.open)
491
+ try {
492
+ link.send(copy);
493
+ }
494
+ catch { /* dropped */ } }, i.lagMs + Math.random() * i.jitterMs);
495
+ }
496
+ return true;
497
+ },
498
+ };
499
+ }
500
+ }
501
+ //# sourceMappingURL=endpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../../src/core/endpoint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import type { Json } from './protocol.js';
2
+ /** Lobby messages ride on reliable events under this key; the application's own events never use it. */
3
+ export declare const LOBBY_KEY = "$lobby";
4
+ export type Visibility = 'public' | 'private';
5
+ export interface MemberView {
6
+ seat: number;
7
+ name: string;
8
+ ready: boolean;
9
+ connected: boolean;
10
+ host: boolean;
11
+ meta: Record<string, Json>;
12
+ }
13
+ export interface RoomView {
14
+ code: string;
15
+ mode: string;
16
+ visibility: Visibility;
17
+ phase: string;
18
+ maxMembers: number;
19
+ meta: Record<string, Json>;
20
+ /** The viewer's own seat. */
21
+ you: number;
22
+ members: MemberView[];
23
+ /** Server clock (ms) when the ready countdown ends, or null. Compare with client.clock.serverTime(). */
24
+ countdownEndsAt: number | null;
25
+ }
26
+ export interface CreateRequest {
27
+ mode?: string;
28
+ visibility?: Visibility;
29
+ maxMembers?: number;
30
+ meta?: Record<string, Json>;
31
+ name?: string;
32
+ memberMeta?: Record<string, Json>;
33
+ /** Anything the game needs to set the room up (a save, a course). Goes to onCreate; never shown to other members. */
34
+ init?: Json;
35
+ }
36
+ export interface JoinRequest {
37
+ code: string;
38
+ name?: string;
39
+ memberMeta?: Record<string, Json>;
40
+ }
41
+ export interface QuickPlayRequest {
42
+ mode?: string;
43
+ /** Only rooms whose meta has these exact values (a build id, a region). */
44
+ match?: Record<string, Json>;
45
+ name?: string;
46
+ memberMeta?: Record<string, Json>;
47
+ /** Used when no room fits and a new public one is made. */
48
+ create?: Omit<CreateRequest, 'visibility' | 'mode' | 'name' | 'memberMeta'>;
49
+ }
50
+ /** Readable room codes: no I/O (they look like 1/0). */
51
+ export declare const CODE_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZ";
52
+ export declare function normalizeCode(code: unknown): string | null;
53
+ export declare function cleanName(name: unknown, max?: number): string;
54
+ /** Small flat JSON maps (meta) only: bounded keys, scalar values or short arrays. */
55
+ export declare function cleanMeta(v: unknown, maxBytes?: number): Record<string, Json> | null;
56
+ export declare function metaMatches(meta: Record<string, Json>, match: Record<string, Json> | undefined): boolean;
57
+ export declare function isLobbyMessage(d: Json): d is {
58
+ [LOBBY_KEY]: string;
59
+ } & Record<string, Json>;
@@ -0,0 +1,53 @@
1
+ /** Lobby messages ride on reliable events under this key; the application's own events never use it. */
2
+ export const LOBBY_KEY = '$lobby';
3
+ /** Readable room codes: no I/O (they look like 1/0). */
4
+ export const CODE_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
5
+ export function normalizeCode(code) {
6
+ if (typeof code !== 'string')
7
+ return null;
8
+ const c = code.trim().toUpperCase();
9
+ return /^[A-Z0-9]{3,12}$/.test(c) ? c : null;
10
+ }
11
+ const range = (a, b) => String.fromCharCode(a) + '-' + String.fromCharCode(b);
12
+ /** Control, zero-width and bidi-override characters: never allowed in a shown name. */
13
+ const INVISIBLE = new RegExp('[' + [range(0, 31), range(127, 159), range(0x200b, 0x200f), range(0x2028, 0x202e), range(0x2066, 0x2069)].join('') + ']', 'g');
14
+ export function cleanName(name, max = 16) {
15
+ if (typeof name !== 'string')
16
+ return '';
17
+ return name.replace(/\s+/g, ' ').replace(INVISIBLE, '').replace(/ +/g, ' ').trim().slice(0, max);
18
+ }
19
+ /** Small flat JSON maps (meta) only: bounded keys, scalar values or short arrays. */
20
+ export function cleanMeta(v, maxBytes = 1024) {
21
+ if (v === undefined || v === null)
22
+ return {};
23
+ if (typeof v !== 'object' || Array.isArray(v))
24
+ return null;
25
+ let text;
26
+ try {
27
+ text = JSON.stringify(v);
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ if (text.length > maxBytes)
33
+ return null;
34
+ const out = {};
35
+ for (const [k, x] of Object.entries(v)) {
36
+ if (!/^[\w.-]{1,32}$/.test(k) || ['__proto__', 'constructor', 'prototype'].includes(k))
37
+ return null;
38
+ out[k] = JSON.parse(JSON.stringify(x ?? null));
39
+ }
40
+ return out;
41
+ }
42
+ export function metaMatches(meta, match) {
43
+ if (!match)
44
+ return true;
45
+ for (const k of Object.keys(match))
46
+ if (JSON.stringify(meta[k] ?? null) !== JSON.stringify(match[k] ?? null))
47
+ return false;
48
+ return true;
49
+ }
50
+ export function isLobbyMessage(d) {
51
+ return !!d && typeof d === 'object' && !Array.isArray(d) && typeof d[LOBBY_KEY] === 'string';
52
+ }
53
+ //# sourceMappingURL=lobby.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lobby.js","sourceRoot":"","sources":["../../src/core/lobby.ts"],"names":[],"mappings":"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"}