rollback-netcode 0.0.4

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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +140 -0
  3. package/dist/debug.d.ts +29 -0
  4. package/dist/debug.d.ts.map +1 -0
  5. package/dist/debug.js +56 -0
  6. package/dist/debug.js.map +1 -0
  7. package/dist/index.d.ts +62 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +57 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/protocol/encoding.d.ts +80 -0
  12. package/dist/protocol/encoding.d.ts.map +1 -0
  13. package/dist/protocol/encoding.js +992 -0
  14. package/dist/protocol/encoding.js.map +1 -0
  15. package/dist/protocol/messages.d.ts +271 -0
  16. package/dist/protocol/messages.d.ts.map +1 -0
  17. package/dist/protocol/messages.js +114 -0
  18. package/dist/protocol/messages.js.map +1 -0
  19. package/dist/rollback/engine.d.ts +261 -0
  20. package/dist/rollback/engine.d.ts.map +1 -0
  21. package/dist/rollback/engine.js +543 -0
  22. package/dist/rollback/engine.js.map +1 -0
  23. package/dist/rollback/input-buffer.d.ts +225 -0
  24. package/dist/rollback/input-buffer.d.ts.map +1 -0
  25. package/dist/rollback/input-buffer.js +483 -0
  26. package/dist/rollback/input-buffer.js.map +1 -0
  27. package/dist/rollback/snapshot-buffer.d.ts +119 -0
  28. package/dist/rollback/snapshot-buffer.d.ts.map +1 -0
  29. package/dist/rollback/snapshot-buffer.js +256 -0
  30. package/dist/rollback/snapshot-buffer.js.map +1 -0
  31. package/dist/session/desync-manager.d.ts +106 -0
  32. package/dist/session/desync-manager.d.ts.map +1 -0
  33. package/dist/session/desync-manager.js +136 -0
  34. package/dist/session/desync-manager.js.map +1 -0
  35. package/dist/session/lag-monitor.d.ts +69 -0
  36. package/dist/session/lag-monitor.d.ts.map +1 -0
  37. package/dist/session/lag-monitor.js +74 -0
  38. package/dist/session/lag-monitor.js.map +1 -0
  39. package/dist/session/message-builders.d.ts +86 -0
  40. package/dist/session/message-builders.d.ts.map +1 -0
  41. package/dist/session/message-builders.js +199 -0
  42. package/dist/session/message-builders.js.map +1 -0
  43. package/dist/session/message-router.d.ts +61 -0
  44. package/dist/session/message-router.d.ts.map +1 -0
  45. package/dist/session/message-router.js +105 -0
  46. package/dist/session/message-router.js.map +1 -0
  47. package/dist/session/player-manager.d.ts +100 -0
  48. package/dist/session/player-manager.d.ts.map +1 -0
  49. package/dist/session/player-manager.js +160 -0
  50. package/dist/session/player-manager.js.map +1 -0
  51. package/dist/session/session.d.ts +379 -0
  52. package/dist/session/session.d.ts.map +1 -0
  53. package/dist/session/session.js +1294 -0
  54. package/dist/session/session.js.map +1 -0
  55. package/dist/session/topology.d.ts +66 -0
  56. package/dist/session/topology.d.ts.map +1 -0
  57. package/dist/session/topology.js +72 -0
  58. package/dist/session/topology.js.map +1 -0
  59. package/dist/transport/adapter.d.ts +99 -0
  60. package/dist/transport/adapter.d.ts.map +1 -0
  61. package/dist/transport/adapter.js +8 -0
  62. package/dist/transport/adapter.js.map +1 -0
  63. package/dist/transport/local.d.ts +192 -0
  64. package/dist/transport/local.d.ts.map +1 -0
  65. package/dist/transport/local.js +435 -0
  66. package/dist/transport/local.js.map +1 -0
  67. package/dist/transport/transforming.d.ts +177 -0
  68. package/dist/transport/transforming.d.ts.map +1 -0
  69. package/dist/transport/transforming.js +407 -0
  70. package/dist/transport/transforming.js.map +1 -0
  71. package/dist/transport/webrtc.d.ts +285 -0
  72. package/dist/transport/webrtc.d.ts.map +1 -0
  73. package/dist/transport/webrtc.js +734 -0
  74. package/dist/transport/webrtc.js.map +1 -0
  75. package/dist/types.d.ts +394 -0
  76. package/dist/types.d.ts.map +1 -0
  77. package/dist/types.js +256 -0
  78. package/dist/types.js.map +1 -0
  79. package/dist/utils/rate-limiter.d.ts +59 -0
  80. package/dist/utils/rate-limiter.d.ts.map +1 -0
  81. package/dist/utils/rate-limiter.js +93 -0
  82. package/dist/utils/rate-limiter.js.map +1 -0
  83. package/package.json +61 -0
@@ -0,0 +1,435 @@
1
+ /**
2
+ * Local/in-memory transport for testing.
3
+ *
4
+ * Allows connecting multiple LocalTransport instances together
5
+ * with simulated network conditions (latency, jitter, packet loss).
6
+ */
7
+ /**
8
+ * Min-heap implementation for efficient message queue ordering.
9
+ * Uses deliverAt time as the priority.
10
+ */
11
+ class MessageHeap {
12
+ heap = [];
13
+ /**
14
+ * Get the number of messages in the heap.
15
+ */
16
+ get length() {
17
+ return this.heap.length;
18
+ }
19
+ /**
20
+ * Insert a message into the heap. O(log n)
21
+ */
22
+ push(message) {
23
+ this.heap.push(message);
24
+ this.bubbleUp(this.heap.length - 1);
25
+ }
26
+ /**
27
+ * Remove and return the message with the earliest delivery time. O(log n)
28
+ */
29
+ pop() {
30
+ if (this.heap.length === 0) {
31
+ return undefined;
32
+ }
33
+ const min = this.heap[0];
34
+ const last = this.heap.pop();
35
+ if (this.heap.length > 0 && last !== undefined) {
36
+ this.heap[0] = last;
37
+ this.bubbleDown(0);
38
+ }
39
+ return min;
40
+ }
41
+ /**
42
+ * Peek at the message with the earliest delivery time without removing it.
43
+ */
44
+ peek() {
45
+ return this.heap[0];
46
+ }
47
+ /**
48
+ * Clear all messages from the heap.
49
+ */
50
+ clear() {
51
+ this.heap.length = 0;
52
+ }
53
+ /**
54
+ * Move a node up the heap to maintain heap property.
55
+ */
56
+ bubbleUp(startIndex) {
57
+ let idx = startIndex;
58
+ while (idx > 0) {
59
+ const parentIndex = Math.floor((idx - 1) / 2);
60
+ const parent = this.heap[parentIndex];
61
+ const current = this.heap[idx];
62
+ if (parent === undefined || current === undefined)
63
+ break;
64
+ if (parent.deliverAt <= current.deliverAt)
65
+ break;
66
+ // Swap with parent
67
+ this.heap[parentIndex] = current;
68
+ this.heap[idx] = parent;
69
+ idx = parentIndex;
70
+ }
71
+ }
72
+ /**
73
+ * Move a node down the heap to maintain heap property.
74
+ */
75
+ bubbleDown(startIndex) {
76
+ const length = this.heap.length;
77
+ let idx = startIndex;
78
+ while (true) {
79
+ const leftIndex = 2 * idx + 1;
80
+ const rightIndex = 2 * idx + 2;
81
+ let smallest = idx;
82
+ const current = this.heap[idx];
83
+ const left = this.heap[leftIndex];
84
+ const right = this.heap[rightIndex];
85
+ if (current === undefined)
86
+ break;
87
+ if (leftIndex < length &&
88
+ left !== undefined &&
89
+ left.deliverAt < current.deliverAt) {
90
+ smallest = leftIndex;
91
+ }
92
+ const smallestItem = this.heap[smallest];
93
+ if (rightIndex < length &&
94
+ right !== undefined &&
95
+ smallestItem !== undefined &&
96
+ right.deliverAt < smallestItem.deliverAt) {
97
+ smallest = rightIndex;
98
+ }
99
+ if (smallest === idx)
100
+ break;
101
+ // Swap with smallest child
102
+ const swap = this.heap[smallest];
103
+ if (swap !== undefined) {
104
+ this.heap[smallest] = current;
105
+ this.heap[idx] = swap;
106
+ }
107
+ idx = smallest;
108
+ }
109
+ }
110
+ }
111
+ /**
112
+ * Simple seeded random number generator for deterministic testing.
113
+ */
114
+ class SeededRandom {
115
+ seed;
116
+ constructor(seed) {
117
+ this.seed = seed;
118
+ }
119
+ /**
120
+ * Returns a random number between 0 and 1.
121
+ */
122
+ next() {
123
+ // Simple LCG
124
+ this.seed = (this.seed * 1664525 + 1013904223) >>> 0;
125
+ return this.seed / 0xffffffff;
126
+ }
127
+ }
128
+ /**
129
+ * In-memory transport for testing.
130
+ *
131
+ * Features:
132
+ * - Connect multiple LocalTransport instances together
133
+ * - Simulated network conditions (latency, jitter, packet loss)
134
+ * - Deterministic mode for reproducible tests
135
+ * - Manual time control via tick() method
136
+ */
137
+ export class LocalTransport {
138
+ localPeerId;
139
+ onMessage = null;
140
+ onConnect = null;
141
+ onDisconnect = null;
142
+ onError = null;
143
+ /** Callback for keepalive ping - set by Session to send Ping messages */
144
+ onKeepalivePing = null;
145
+ _connectedPeers = new Set();
146
+ linkedTransports = new Map();
147
+ pendingMessages = new MessageHeap();
148
+ packetLoss;
149
+ random;
150
+ currentTime = 0;
151
+ /** Simulated one-way latency in milliseconds */
152
+ _latency = 0;
153
+ /** Simulated jitter (latency variation) in milliseconds */
154
+ _jitter = 0;
155
+ /**
156
+ * Create a new LocalTransport.
157
+ *
158
+ * @param localPeerId - Unique ID for this transport
159
+ * @param config - Network simulation configuration
160
+ */
161
+ constructor(localPeerId, config) {
162
+ this.localPeerId = localPeerId;
163
+ this.latency = config?.latency ?? 0;
164
+ this.jitter = config?.jitter ?? 0;
165
+ this.packetLoss = config?.packetLoss ?? 0;
166
+ const deterministic = config?.deterministic ?? false;
167
+ const seed = config?.seed ?? 12345;
168
+ this.random = deterministic ? new SeededRandom(seed) : null;
169
+ }
170
+ /**
171
+ * Get the set of connected peer IDs.
172
+ */
173
+ get connectedPeers() {
174
+ return this._connectedPeers;
175
+ }
176
+ /**
177
+ * Link two LocalTransport instances together.
178
+ * Creates a bidirectional connection.
179
+ *
180
+ * @param a - First transport
181
+ * @param b - Second transport
182
+ */
183
+ static link(a, b) {
184
+ a.linkedTransports.set(b.localPeerId, b);
185
+ b.linkedTransports.set(a.localPeerId, a);
186
+ }
187
+ /**
188
+ * Unlink two LocalTransport instances.
189
+ *
190
+ * @param a - First transport
191
+ * @param b - Second transport
192
+ */
193
+ static unlink(a, b) {
194
+ a.linkedTransports.delete(b.localPeerId);
195
+ b.linkedTransports.delete(a.localPeerId);
196
+ }
197
+ /**
198
+ * Connect to a peer.
199
+ * The peer must be linked via LocalTransport.link().
200
+ */
201
+ async connect(peerId) {
202
+ const peer = this.linkedTransports.get(peerId);
203
+ if (!peer) {
204
+ throw new Error(`Peer ${peerId} is not linked`);
205
+ }
206
+ if (this._connectedPeers.has(peerId)) {
207
+ return; // Already connected
208
+ }
209
+ // Add to connected peers on both sides
210
+ this._connectedPeers.add(peerId);
211
+ peer._connectedPeers.add(this.localPeerId);
212
+ // Notify both sides
213
+ this.onConnect?.(peerId);
214
+ peer.onConnect?.(this.localPeerId);
215
+ }
216
+ /**
217
+ * Disconnect from a peer.
218
+ */
219
+ disconnect(peerId) {
220
+ if (!this._connectedPeers.has(peerId)) {
221
+ return;
222
+ }
223
+ const peer = this.linkedTransports.get(peerId);
224
+ // Remove from connected peers on both sides
225
+ this._connectedPeers.delete(peerId);
226
+ if (peer) {
227
+ peer._connectedPeers.delete(this.localPeerId);
228
+ peer.onDisconnect?.(this.localPeerId);
229
+ }
230
+ this.onDisconnect?.(peerId);
231
+ }
232
+ /**
233
+ * Disconnect from all peers.
234
+ */
235
+ disconnectAll() {
236
+ const peers = Array.from(this._connectedPeers);
237
+ for (const peerId of peers) {
238
+ this.disconnect(peerId);
239
+ }
240
+ }
241
+ /**
242
+ * Send a message to a specific peer.
243
+ * Uses a min-heap for O(log n) insertion instead of O(n log n) sort.
244
+ */
245
+ send(peerId, message, reliable) {
246
+ if (!this._connectedPeers.has(peerId)) {
247
+ return; // Not connected, silently drop
248
+ }
249
+ // Check for packet loss (unreliable only)
250
+ if (!reliable && this.shouldDropPacket()) {
251
+ return;
252
+ }
253
+ // Calculate delivery time with latency and jitter
254
+ const deliverAt = this.currentTime + this.calculateDelay();
255
+ // Copy message to prevent external mutation
256
+ const messageCopy = new Uint8Array(message.length);
257
+ messageCopy.set(message);
258
+ // Push to heap - O(log n) instead of O(n log n) for sort
259
+ this.pendingMessages.push({
260
+ targetPeerId: peerId,
261
+ message: messageCopy,
262
+ deliverAt,
263
+ reliable,
264
+ });
265
+ }
266
+ /**
267
+ * Broadcast a message to all connected peers.
268
+ */
269
+ broadcast(message, reliable) {
270
+ for (const peerId of this._connectedPeers) {
271
+ this.send(peerId, message, reliable);
272
+ }
273
+ }
274
+ /**
275
+ * Process all pending messages immediately, ignoring simulated delay.
276
+ * Useful for synchronous tests.
277
+ */
278
+ flush() {
279
+ while (this.pendingMessages.length > 0) {
280
+ const pending = this.pendingMessages.pop();
281
+ if (pending !== undefined) {
282
+ this.deliverMessage(pending);
283
+ }
284
+ }
285
+ }
286
+ /**
287
+ * Advance simulated time and deliver any messages due.
288
+ *
289
+ * @param deltaMs - Time to advance in milliseconds
290
+ */
291
+ tick(deltaMs) {
292
+ this.currentTime += deltaMs;
293
+ this.deliverDueMessages();
294
+ }
295
+ /**
296
+ * Get the current simulated time.
297
+ */
298
+ getCurrentTime() {
299
+ return this.currentTime;
300
+ }
301
+ /**
302
+ * Set the current simulated time.
303
+ */
304
+ setCurrentTime(time) {
305
+ this.currentTime = time;
306
+ this.deliverDueMessages();
307
+ }
308
+ /**
309
+ * Get the number of pending messages.
310
+ */
311
+ getPendingMessageCount() {
312
+ return this.pendingMessages.length;
313
+ }
314
+ /**
315
+ * Deliver all messages that are due based on current time.
316
+ * Uses O(k log n) where k is the number of messages delivered.
317
+ */
318
+ deliverDueMessages() {
319
+ while (this.pendingMessages.length > 0) {
320
+ const first = this.pendingMessages.peek();
321
+ if (first === undefined || first.deliverAt > this.currentTime) {
322
+ break;
323
+ }
324
+ this.pendingMessages.pop();
325
+ this.deliverMessage(first);
326
+ }
327
+ }
328
+ /**
329
+ * Deliver a single message to its target peer.
330
+ * Messages are delivered regardless of current connection state, simulating
331
+ * real networks where messages in flight can arrive after disconnect.
332
+ */
333
+ deliverMessage(pending) {
334
+ const peer = this.linkedTransports.get(pending.targetPeerId);
335
+ if (peer) {
336
+ peer.onMessage?.(this.localPeerId, pending.message);
337
+ }
338
+ }
339
+ /**
340
+ * Calculate delay for a message based on latency and jitter.
341
+ */
342
+ calculateDelay() {
343
+ let delay = this._latency;
344
+ if (this._jitter > 0) {
345
+ const jitterAmount = this.getRandomValue() * this._jitter * 2;
346
+ delay += jitterAmount - this._jitter;
347
+ }
348
+ return Math.max(0, delay);
349
+ }
350
+ /**
351
+ * Determine if a packet should be dropped.
352
+ */
353
+ shouldDropPacket() {
354
+ if (this.packetLoss <= 0) {
355
+ return false;
356
+ }
357
+ return this.getRandomValue() < this.packetLoss;
358
+ }
359
+ /**
360
+ * Get a random value between 0 and 1.
361
+ */
362
+ getRandomValue() {
363
+ if (this.random) {
364
+ return this.random.next();
365
+ }
366
+ return Math.random();
367
+ }
368
+ /**
369
+ * Get the current simulated latency in milliseconds.
370
+ */
371
+ get latency() {
372
+ return this._latency;
373
+ }
374
+ /**
375
+ * Set the simulated latency in milliseconds.
376
+ * Can be changed at any time; affects only new messages.
377
+ */
378
+ set latency(value) {
379
+ this._latency = Math.max(0, value);
380
+ }
381
+ /**
382
+ * Get the current simulated jitter in milliseconds.
383
+ */
384
+ get jitter() {
385
+ return this._jitter;
386
+ }
387
+ /**
388
+ * Set the simulated jitter in milliseconds.
389
+ * Can be changed at any time; affects only new messages.
390
+ */
391
+ set jitter(value) {
392
+ this._jitter = Math.max(0, value);
393
+ }
394
+ /**
395
+ * Trigger keepalive pings for all connected peers.
396
+ * Call this periodically to trigger RTT measurement.
397
+ * The Session will handle the actual Ping/Pong and RTT calculation.
398
+ */
399
+ triggerKeepalive() {
400
+ if (!this.onKeepalivePing)
401
+ return;
402
+ for (const peerId of this._connectedPeers) {
403
+ this.onKeepalivePing(peerId);
404
+ }
405
+ }
406
+ }
407
+ /**
408
+ * Create a group of linked LocalTransport instances.
409
+ *
410
+ * @param peerIds - Array of peer IDs to create
411
+ * @param config - Optional shared configuration
412
+ * @returns Map of peer ID to LocalTransport
413
+ */
414
+ export function createLocalTransportGroup(peerIds, config) {
415
+ const transports = new Map();
416
+ // Create all transports
417
+ for (const peerId of peerIds) {
418
+ transports.set(peerId, new LocalTransport(peerId, config));
419
+ }
420
+ // Link all transports together (full mesh)
421
+ const transportArray = Array.from(transports.values());
422
+ for (let i = 0; i < transportArray.length; i++) {
423
+ const transportI = transportArray[i];
424
+ if (!transportI)
425
+ continue;
426
+ for (let j = i + 1; j < transportArray.length; j++) {
427
+ const transportJ = transportArray[j];
428
+ if (!transportJ)
429
+ continue;
430
+ LocalTransport.link(transportI, transportJ);
431
+ }
432
+ }
433
+ return transports;
434
+ }
435
+ //# sourceMappingURL=local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/transport/local.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * TransformingTransport - Wraps a transport with compression and segmentation.
3
+ *
4
+ * Provides transparent compression (using pako/gzip) and segmentation for large
5
+ * messages that exceed WebRTC DataChannel limits (~16KB).
6
+ */
7
+ import type { ConnectionMetrics, TransportAdapter } from "./adapter.js";
8
+ /**
9
+ * Configuration for TransformingTransport.
10
+ */
11
+ export interface TransformingTransportConfig {
12
+ /**
13
+ * Compression mode:
14
+ * - 'auto': Compress if result is smaller than original (default)
15
+ * - 'always': Always compress
16
+ * - 'never': Never compress
17
+ * @default 'auto'
18
+ */
19
+ compression: "auto" | "always" | "never";
20
+ /**
21
+ * Minimum message size in bytes before compression is attempted.
22
+ * Messages smaller than this are sent raw.
23
+ * @default 128
24
+ */
25
+ compressionThreshold: number;
26
+ /**
27
+ * Whether to segment large messages.
28
+ * @default true
29
+ */
30
+ segmentation: boolean;
31
+ /**
32
+ * Maximum size of each segment in bytes (including headers).
33
+ * WebRTC DataChannels typically have ~16KB limit.
34
+ * @default 16000
35
+ */
36
+ maxSegmentSize: number;
37
+ /**
38
+ * Timeout in milliseconds for reassembling segmented messages.
39
+ * Incomplete messages are discarded after this timeout.
40
+ * @default 5000
41
+ */
42
+ reassemblyTimeout: number;
43
+ }
44
+ /**
45
+ * Default configuration for TransformingTransport.
46
+ */
47
+ export declare const DEFAULT_TRANSFORMING_TRANSPORT_CONFIG: TransformingTransportConfig;
48
+ /**
49
+ * Wraps a transport with transparent compression and segmentation.
50
+ *
51
+ * Send path: compress -> segment -> send via inner transport
52
+ * Receive path: reassemble -> decompress -> deliver to callback
53
+ */
54
+ export declare class TransformingTransport implements TransportAdapter {
55
+ onMessage: ((peerId: string, message: Uint8Array) => void) | null;
56
+ onConnect: ((peerId: string) => void) | null;
57
+ onDisconnect: ((peerId: string) => void) | null;
58
+ onError: ((peerId: string | null, error: Error, context: string) => void) | null;
59
+ private readonly inner;
60
+ private readonly config;
61
+ /** Per-peer message ID counters for outgoing messages */
62
+ private readonly messageIdCounters;
63
+ /** Per-peer reassembly buffers for incoming messages */
64
+ private readonly reassemblyBuffers;
65
+ /** Timer ID for periodic cleanup */
66
+ private cleanupTimerId;
67
+ /**
68
+ * Create a new TransformingTransport.
69
+ *
70
+ * @param inner - The underlying transport to wrap
71
+ * @param config - Optional configuration (uses defaults for missing values)
72
+ */
73
+ constructor(inner: TransportAdapter, config?: Partial<TransformingTransportConfig>);
74
+ /**
75
+ * Get the set of connected peer IDs.
76
+ */
77
+ get connectedPeers(): ReadonlySet<string>;
78
+ /**
79
+ * Get the local peer's ID.
80
+ */
81
+ get localPeerId(): string;
82
+ /**
83
+ * Connect to a peer.
84
+ */
85
+ connect(peerId: string): Promise<void>;
86
+ /**
87
+ * Disconnect from a peer.
88
+ */
89
+ disconnect(peerId: string): void;
90
+ /**
91
+ * Disconnect from all peers.
92
+ */
93
+ disconnectAll(): void;
94
+ /**
95
+ * Send a message to a specific peer.
96
+ * Applies compression and segmentation as configured.
97
+ */
98
+ send(peerId: string, message: Uint8Array, reliable: boolean): void;
99
+ /**
100
+ * Broadcast a message to all connected peers.
101
+ * Each peer receives independently segmented messages with unique message IDs.
102
+ */
103
+ broadcast(message: Uint8Array, reliable: boolean): void;
104
+ /**
105
+ * Get connection quality metrics for a peer.
106
+ */
107
+ getConnectionMetrics?(peerId: string): ConnectionMetrics | null;
108
+ /**
109
+ * Stop the cleanup timer and dispose of the inner transport.
110
+ * Call this when disposing of the transport.
111
+ */
112
+ dispose(): void;
113
+ /**
114
+ * Apply compression to outgoing message data.
115
+ * Returns data with a 1-byte compression header.
116
+ */
117
+ private transformOutgoing;
118
+ /**
119
+ * Add compression header to message data.
120
+ */
121
+ private addCompressionHeader;
122
+ /**
123
+ * Segment a transformed message for sending.
124
+ * Returns an array of segments, each with an 8-byte header.
125
+ */
126
+ private segmentMessage;
127
+ /**
128
+ * Create a segment with auto-generated message ID.
129
+ */
130
+ private createSegment;
131
+ /**
132
+ * Create a segment with a specific message ID.
133
+ */
134
+ private createSegmentWithId;
135
+ /**
136
+ * Get the next message ID for a peer.
137
+ *
138
+ * Note: Wraps at 2^32 (~4 billion). Collisions after wrap-around are handled by:
139
+ * 1. The total-mismatch check in bufferSegment() (rejects segments with wrong total)
140
+ * 2. The reassembly timeout cleanup (removes stale entries after 5s)
141
+ * 3. Practical impossibility: at 60 msg/sec, wrap-around takes ~2.2 years
142
+ */
143
+ private getNextMessageId;
144
+ /**
145
+ * Handle an incoming message from the inner transport.
146
+ */
147
+ private handleIncomingMessage;
148
+ /**
149
+ * Buffer a segment and attempt reassembly.
150
+ */
151
+ private bufferSegment;
152
+ /**
153
+ * Reassemble a complete message from segments.
154
+ */
155
+ private reassembleMessage;
156
+ /**
157
+ * Decompress and deliver a reassembled message.
158
+ */
159
+ private deliverMessage;
160
+ /**
161
+ * Clean up state for a disconnected peer.
162
+ */
163
+ private cleanupPeerState;
164
+ /**
165
+ * Start the periodic cleanup timer.
166
+ */
167
+ private startCleanupTimer;
168
+ /**
169
+ * Stop the cleanup timer.
170
+ */
171
+ private stopCleanupTimer;
172
+ /**
173
+ * Remove incomplete messages that have timed out.
174
+ */
175
+ private cleanupTimedOutMessages;
176
+ }
177
+ //# sourceMappingURL=transforming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transforming.d.ts","sourceRoot":"","sources":["../../src/transport/transforming.ts"],"names":[],"mappings":"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"}