@actuallab/rpc 12.1.115 → 12.2.23

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/dist/index.js CHANGED
@@ -22,6 +22,10 @@ var ARG_DELIMITER = "";
22
22
  var FRAME_DELIMITER = "\n";
23
23
 
24
24
  // src/rpc-serialization.ts
25
+ import {
26
+ Encoder,
27
+ Decoder
28
+ } from "@msgpack/msgpack";
25
29
  function serializeMessage(message, args) {
26
30
  const envelope = JSON.stringify(message);
27
31
  if (args === void 0 || args.length === 0) {
@@ -51,13 +55,263 @@ function deserializeMessage(raw) {
51
55
  try {
52
56
  return JSON.parse(s);
53
57
  } catch {
58
+ console.warn(
59
+ `[RpcSerialization] failed to parse arg as JSON: ${s.substring(0, 100)}`
60
+ );
54
61
  return s;
55
62
  }
56
63
  });
57
64
  return { message, args };
58
65
  }
66
+ var textEncoder = new TextEncoder();
67
+ var textDecoder = new TextDecoder();
68
+ var INITIAL_ENCODER_BUFFER_SIZE = 32 * 1024;
69
+ var defaultBinaryEncoder = new Encoder(
70
+ void 0,
71
+ void 0,
72
+ void 0,
73
+ INITIAL_ENCODER_BUFFER_SIZE
74
+ );
75
+ var defaultBinaryDecoder = new Decoder();
76
+ function createBinaryEncoder() {
77
+ return new Encoder(
78
+ void 0,
79
+ void 0,
80
+ void 0,
81
+ INITIAL_ENCODER_BUFFER_SIZE
82
+ );
83
+ }
84
+ function varUintByteLen(value) {
85
+ if (value < 0) value = 0;
86
+ let n = 0;
87
+ do {
88
+ n++;
89
+ value >>>= 7;
90
+ } while (value > 0);
91
+ return n;
92
+ }
93
+ function writeVarUintInto(out, pos, value) {
94
+ if (value < 0) value = 0;
95
+ do {
96
+ let byte = value & 127;
97
+ value >>>= 7;
98
+ if (value > 0) byte |= 128;
99
+ out[pos++] = byte;
100
+ } while (value > 0);
101
+ return pos;
102
+ }
103
+ function readVarUint(data, offset) {
104
+ let value = 0, shift = 0, bytesRead = 0;
105
+ do {
106
+ if (offset + bytesRead >= data.length) break;
107
+ const byte = data[offset + bytesRead];
108
+ value |= (byte & 127) << shift;
109
+ bytesRead++;
110
+ if ((byte & 128) === 0) break;
111
+ shift += 7;
112
+ } while (shift < 35);
113
+ return { value: value >>> 0, bytesRead };
114
+ }
115
+ function concatUint8Arrays(arrays) {
116
+ let totalLength = 0;
117
+ for (const arr of arrays) totalLength += arr.length;
118
+ const result = new Uint8Array(totalLength);
119
+ let offset = 0;
120
+ for (const arr of arrays) {
121
+ result.set(arr, offset);
122
+ offset += arr.length;
123
+ }
124
+ return result;
125
+ }
126
+ function serializeBinaryMessage(message, args, encoder = defaultBinaryEncoder) {
127
+ let argsDataLen = 0;
128
+ let argBufs = null;
129
+ if (args && args.length > 0) {
130
+ argBufs = new Array(args.length);
131
+ for (let i = 0; i < args.length; i++) {
132
+ const buf = encoder.encode(args[i]);
133
+ argBufs[i] = buf;
134
+ argsDataLen += buf.length;
135
+ }
136
+ }
137
+ const callType = message.CallType ?? 0;
138
+ const relatedId = message.RelatedId ?? 0;
139
+ const methodBytes = textEncoder.encode(message.Method ?? "");
140
+ const relatedIdLen = varUintByteLen(relatedId);
141
+ const methodLenVarintLen = varUintByteLen(methodBytes.length);
142
+ const headerSize = 1 + relatedIdLen + methodLenVarintLen + methodBytes.length;
143
+ const totalSize = headerSize + 4 + argsDataLen;
144
+ const out = new Uint8Array(totalSize);
145
+ let pos = 0;
146
+ out[pos++] = callType << 5 & 224;
147
+ pos = writeVarUintInto(out, pos, relatedId);
148
+ pos = writeVarUintInto(out, pos, methodBytes.length);
149
+ out.set(methodBytes, pos);
150
+ pos += methodBytes.length;
151
+ out[pos++] = argsDataLen & 255;
152
+ out[pos++] = argsDataLen >>> 8 & 255;
153
+ out[pos++] = argsDataLen >>> 16 & 255;
154
+ out[pos++] = argsDataLen >>> 24 & 255;
155
+ if (argBufs !== null) {
156
+ for (const buf of argBufs) {
157
+ out.set(buf, pos);
158
+ pos += buf.length;
159
+ }
160
+ }
161
+ return out;
162
+ }
163
+ function deserializeBinaryMessage(data, offset, decoder = defaultBinaryDecoder) {
164
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
165
+ let pos = offset;
166
+ const byte0 = data[pos++];
167
+ const callTypeId = byte0 >> 5 & 7;
168
+ const headerCount = byte0 & 31;
169
+ const relId = readVarUint(data, pos);
170
+ pos += relId.bytesRead;
171
+ const methodLen = readVarUint(data, pos);
172
+ pos += methodLen.bytesRead;
173
+ const methodBytes = data.subarray(pos, pos + methodLen.value);
174
+ const method = textDecoder.decode(methodBytes);
175
+ pos += methodLen.value;
176
+ const argDataLen = view.getInt32(pos, true);
177
+ pos += 4;
178
+ if (headerCount > 0) {
179
+ for (let h = 0; h < headerCount; h++) {
180
+ const keyLen = data[pos++];
181
+ pos += keyLen;
182
+ const valLen = readVarUint(data, pos);
183
+ pos += valLen.bytesRead + valLen.value;
184
+ }
185
+ }
186
+ const args = [];
187
+ const argEnd = pos + argDataLen;
188
+ if (argDataLen > 0) {
189
+ const argSlice = data.subarray(pos, argEnd);
190
+ for (const decoded of decoder.decodeMulti(argSlice)) {
191
+ args.push(decoded);
192
+ }
193
+ pos = argEnd;
194
+ }
195
+ const message = {
196
+ Method: method,
197
+ RelatedId: relId.value,
198
+ CallType: callTypeId
199
+ };
200
+ return { message, args, bytesRead: pos - offset };
201
+ }
202
+ function splitBinaryFrame(frame, decoder = defaultBinaryDecoder) {
203
+ const results = [];
204
+ let offset = 0;
205
+ while (offset < frame.length) {
206
+ const { message, args, bytesRead } = deserializeBinaryMessage(
207
+ frame,
208
+ offset,
209
+ decoder
210
+ );
211
+ if (bytesRead <= 0) break;
212
+ results.push({ message, args });
213
+ offset += bytesRead;
214
+ }
215
+ return results;
216
+ }
217
+ function serializeBinaryFrame(messages) {
218
+ return concatUint8Arrays(messages);
219
+ }
220
+ function serializeCompactBinaryMessage(message, args, registry, encoder = defaultBinaryEncoder) {
221
+ let argsDataLen = 0;
222
+ let argBufs = null;
223
+ if (args && args.length > 0) {
224
+ argBufs = new Array(args.length);
225
+ for (let i = 0; i < args.length; i++) {
226
+ const buf = encoder.encode(args[i]);
227
+ argBufs[i] = buf;
228
+ argsDataLen += buf.length;
229
+ }
230
+ }
231
+ const methodName = message.Method ?? "";
232
+ const methodHash = registry?.requireHash(methodName) ?? 0;
233
+ const callType = message.CallType ?? 0;
234
+ const relatedId = message.RelatedId ?? 0;
235
+ const relatedIdLen = varUintByteLen(relatedId);
236
+ const headerSize = 1 + relatedIdLen + 4;
237
+ const totalSize = headerSize + 4 + argsDataLen;
238
+ const out = new Uint8Array(totalSize);
239
+ let pos = 0;
240
+ out[pos++] = callType << 5 & 224;
241
+ pos = writeVarUintInto(out, pos, relatedId);
242
+ const hashU32 = methodHash >>> 0;
243
+ out[pos++] = hashU32 & 255;
244
+ out[pos++] = hashU32 >>> 8 & 255;
245
+ out[pos++] = hashU32 >>> 16 & 255;
246
+ out[pos++] = hashU32 >>> 24 & 255;
247
+ out[pos++] = argsDataLen & 255;
248
+ out[pos++] = argsDataLen >>> 8 & 255;
249
+ out[pos++] = argsDataLen >>> 16 & 255;
250
+ out[pos++] = argsDataLen >>> 24 & 255;
251
+ if (argBufs !== null) {
252
+ for (const buf of argBufs) {
253
+ out.set(buf, pos);
254
+ pos += buf.length;
255
+ }
256
+ }
257
+ return out;
258
+ }
259
+ function deserializeCompactBinaryMessage(data, offset, registry, decoder = defaultBinaryDecoder) {
260
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
261
+ let pos = offset;
262
+ const byte0 = data[pos++];
263
+ const callTypeId = byte0 >> 5 & 7;
264
+ const headerCount = byte0 & 31;
265
+ const relId = readVarUint(data, pos);
266
+ pos += relId.bytesRead;
267
+ const methodHash = view.getUint32(pos, true);
268
+ pos += 4;
269
+ const method = registry?.getName(methodHash | 0) ?? `<hash:0x${methodHash.toString(16).padStart(8, "0")}>`;
270
+ const argDataLen = view.getInt32(pos, true);
271
+ pos += 4;
272
+ if (headerCount > 0) {
273
+ for (let h = 0; h < headerCount; h++) {
274
+ const keyLen = data[pos++];
275
+ pos += keyLen;
276
+ const valLen = readVarUint(data, pos);
277
+ pos += valLen.bytesRead + valLen.value;
278
+ }
279
+ }
280
+ const args = [];
281
+ const argEnd = pos + argDataLen;
282
+ if (argDataLen > 0) {
283
+ const argSlice = data.subarray(pos, argEnd);
284
+ for (const decoded of decoder.decodeMulti(argSlice)) {
285
+ args.push(decoded);
286
+ }
287
+ pos = argEnd;
288
+ }
289
+ const message = {
290
+ Method: method,
291
+ RelatedId: relId.value,
292
+ CallType: callTypeId
293
+ };
294
+ return { message, args, bytesRead: pos - offset };
295
+ }
296
+ function splitCompactBinaryFrame(frame, registry, decoder = defaultBinaryDecoder) {
297
+ const results = [];
298
+ let offset = 0;
299
+ while (offset < frame.length) {
300
+ const { message, args, bytesRead } = deserializeCompactBinaryMessage(
301
+ frame,
302
+ offset,
303
+ registry,
304
+ decoder
305
+ );
306
+ if (bytesRead <= 0) break;
307
+ results.push({ message, args });
308
+ offset += bytesRead;
309
+ }
310
+ return results;
311
+ }
59
312
 
60
313
  // src/rpc-connection.ts
314
+ import { Decoder as Decoder2 } from "@msgpack/msgpack";
61
315
  import { PromiseSource, EventHandlerSet } from "@actuallab/core";
62
316
  var WebSocketState = {
63
317
  CONNECTING: 0,
@@ -69,11 +323,36 @@ var RpcWebSocketConnection = class {
69
323
  _ws;
70
324
  _sendBuffer = [];
71
325
  _connected = new PromiseSource();
326
+ /** Per-connection msgpack encoder — reused across outbound messages to
327
+ * amortise construction cost and to keep the internal write buffer at
328
+ * its largest observed size (avoids repeated `resizeBuffer` growth on
329
+ * large video frames). See serializeBinaryMessage() for details. */
330
+ _encoder = createBinaryEncoder();
331
+ /** Per-connection msgpack decoder — reused across inbound messages
332
+ * rather than reconstructing one for every `decodeMulti` call. */
333
+ _decoder = new Decoder2();
334
+ /** Exposed for callers who need to encode outbound binary messages
335
+ * through this connection (e.g. `serializeBinaryMessage`). Safe to
336
+ * pass to synchronous encode calls on the same event-loop turn. */
337
+ get encoder() {
338
+ return this._encoder;
339
+ }
340
+ get decoder() {
341
+ return this._decoder;
342
+ }
343
+ _format;
344
+ _methodRegistry;
345
+ binaryMode;
72
346
  messageReceived = new EventHandlerSet();
73
347
  closed = new EventHandlerSet();
74
348
  error = new EventHandlerSet();
75
- constructor(ws) {
349
+ constructor(ws, binaryMode = false, format, methodRegistry) {
76
350
  this._ws = ws;
351
+ this.binaryMode = binaryMode;
352
+ this._format = format;
353
+ this._methodRegistry = methodRegistry;
354
+ if (binaryMode && ws.binaryType !== void 0)
355
+ ws.binaryType = "arraybuffer";
77
356
  if (ws.readyState === WebSocketState.OPEN) {
78
357
  this._connected.resolve();
79
358
  this._flush();
@@ -83,10 +362,46 @@ var RpcWebSocketConnection = class {
83
362
  this._flush();
84
363
  };
85
364
  ws.onmessage = (ev) => {
86
- const data = typeof ev.data === "string" ? ev.data : String(ev.data);
87
- const messages = splitFrame(data);
88
- for (const msg of messages) {
89
- if (msg.length > 0) this.messageReceived.trigger(msg);
365
+ if (ev.data instanceof Uint8Array || ev.data instanceof ArrayBuffer) {
366
+ const frame = ev.data instanceof Uint8Array ? ev.data : new Uint8Array(ev.data);
367
+ try {
368
+ const messages = this._splitBinary(frame);
369
+ for (const { message, args } of messages) {
370
+ this.messageReceived.trigger({
371
+ kind: "binary",
372
+ message,
373
+ args
374
+ });
375
+ }
376
+ } catch (e) {
377
+ this.error.trigger(e);
378
+ }
379
+ } else if (typeof Blob !== "undefined" && ev.data instanceof Blob && this.binaryMode) {
380
+ void ev.data.arrayBuffer().then((ab) => {
381
+ const frame = new Uint8Array(ab);
382
+ try {
383
+ const messages = this._splitBinary(frame);
384
+ for (const { message, args } of messages) {
385
+ this.messageReceived.trigger({
386
+ kind: "binary",
387
+ message,
388
+ args
389
+ });
390
+ }
391
+ } catch (e) {
392
+ this.error.trigger(e);
393
+ }
394
+ });
395
+ } else {
396
+ const data = typeof ev.data === "string" ? ev.data : String(ev.data);
397
+ const messages = splitFrame(data);
398
+ for (const msg of messages) {
399
+ if (msg.length > 0)
400
+ this.messageReceived.trigger({
401
+ kind: "text",
402
+ raw: msg
403
+ });
404
+ }
90
405
  }
91
406
  };
92
407
  ws.onclose = (ev) => {
@@ -103,27 +418,46 @@ var RpcWebSocketConnection = class {
103
418
  return this._connected.promise;
104
419
  }
105
420
  send(serializedMessage) {
106
- try {
107
- if (this._ws.readyState === WebSocketState.OPEN)
108
- this._ws.send(serializedMessage);
109
- else if (this._ws.readyState === WebSocketState.CONNECTING)
110
- this._sendBuffer.push(serializedMessage);
111
- } catch {
112
- }
421
+ this._sendRaw(serializedMessage);
422
+ }
423
+ sendBinary(data) {
424
+ this._sendRaw(data);
425
+ }
426
+ sendTextBatch(messages) {
427
+ this._sendRaw(serializeFrame(messages));
113
428
  }
114
- sendBatch(messages) {
115
- const frame = serializeFrame(messages);
116
- this.send(frame);
429
+ sendBinaryBatch(messages) {
430
+ this._sendRaw(serializeBinaryFrame(messages));
431
+ }
432
+ /** Split a binary frame using the format (compact-aware) or default splitter. */
433
+ _splitBinary(frame) {
434
+ if (this._format) {
435
+ return this._format.splitBinaryFrame(
436
+ frame,
437
+ this._decoder,
438
+ this._methodRegistry
439
+ );
440
+ }
441
+ return splitBinaryFrame(frame, this._decoder);
117
442
  }
118
443
  close(code, reason) {
119
444
  this._ws.close(code, reason);
120
445
  }
446
+ _sendRaw(data) {
447
+ try {
448
+ if (this._ws.readyState === WebSocketState.OPEN) {
449
+ this._ws.send(data);
450
+ } else if (this._ws.readyState === WebSocketState.CONNECTING)
451
+ this._sendBuffer.push(data);
452
+ } catch {
453
+ }
454
+ }
121
455
  _flush() {
122
456
  if (this._sendBuffer.length === 0) return;
123
- const frame = serializeFrame(this._sendBuffer);
457
+ const buffer = this._sendBuffer;
124
458
  this._sendBuffer = [];
125
459
  try {
126
- this._ws.send(frame);
460
+ for (const item of buffer) this._ws.send(item);
127
461
  } catch {
128
462
  }
129
463
  }
@@ -134,6 +468,7 @@ import { EventHandlerSet as EventHandlerSet2 } from "@actuallab/core";
134
468
  var RpcMessageChannelConnection = class {
135
469
  _port;
136
470
  _open = true;
471
+ binaryMode = false;
137
472
  messageReceived = new EventHandlerSet2();
138
473
  closed = new EventHandlerSet2();
139
474
  whenConnected = Promise.resolve();
@@ -143,7 +478,8 @@ var RpcMessageChannelConnection = class {
143
478
  port.onmessage = (ev) => {
144
479
  const data = typeof ev.data === "string" ? ev.data : String(ev.data);
145
480
  for (const msg of splitFrame(data))
146
- if (msg.length > 0) this.messageReceived.trigger(msg);
481
+ if (msg.length > 0)
482
+ this.messageReceived.trigger({ kind: "text", raw: msg });
147
483
  };
148
484
  }
149
485
  get isOpen() {
@@ -156,6 +492,13 @@ var RpcMessageChannelConnection = class {
156
492
  } catch {
157
493
  }
158
494
  }
495
+ sendBinary(data) {
496
+ if (!this._open) return;
497
+ try {
498
+ this._port.postMessage(data, [data.buffer]);
499
+ } catch {
500
+ }
501
+ }
159
502
  close(code, reason) {
160
503
  if (!this._open) return;
161
504
  this._open = false;
@@ -210,8 +553,8 @@ var RpcOutboundCall = class {
210
553
  /** Whether to remove this call from the tracker on $sys.Ok. Default: true.
211
554
  * Subclasses (e.g. compute calls) override to false to stay in tracker for invalidation. */
212
555
  removeOnOk = true;
213
- /** The serialized wire message — stored for re-sending on reconnect. */
214
- serializedMessage = "";
556
+ /** The serialized wire data — stored for re-sending on reconnect. */
557
+ serializedWireData = "";
215
558
  constructor(callId, method) {
216
559
  this.callId = callId;
217
560
  this.method = method;
@@ -301,6 +644,7 @@ var RpcInboundCallTracker = class {
301
644
  };
302
645
 
303
646
  // src/rpc-stream.ts
647
+ import Denque from "denque";
304
648
  import { PromiseSource as PromiseSource3 } from "@actuallab/core";
305
649
 
306
650
  // src/rpc-object.ts
@@ -308,25 +652,49 @@ var RpcObjectKind = { Local: 0, Remote: 1 };
308
652
 
309
653
  // src/rpc-stream.ts
310
654
  function parseStreamRef(value) {
311
- if (typeof value !== "string") return null;
312
- const parts = value.split(",");
313
- if (parts.length < 4 || parts.length > 5) return null;
314
- const hostId = parts[0];
315
- const localId = parseInt(parts[1], 10);
316
- const ackPeriod = parseInt(parts[2], 10);
317
- const ackAdvance = parseInt(parts[3], 10);
318
- if (isNaN(localId) || isNaN(ackPeriod) || isNaN(ackAdvance)) return null;
319
- const allowReconnect = parts.length < 5 || parts[4] !== "0";
320
- return { hostId, localId, ackPeriod, ackAdvance, allowReconnect };
655
+ if (typeof value === "string") {
656
+ const parts = value.split(",");
657
+ if (parts.length < 4 || parts.length > 6) return null;
658
+ const hostId = parts[0];
659
+ const localId = parseInt(parts[1], 10);
660
+ const ackPeriod = parseInt(parts[2], 10);
661
+ const ackAdvance = parseInt(parts[3], 10);
662
+ if (isNaN(localId) || isNaN(ackPeriod) || isNaN(ackAdvance))
663
+ return null;
664
+ const allowReconnect = parts.length < 5 || parts[4] !== "0";
665
+ const isRealTime = parts.length >= 6 && parts[5] === "1";
666
+ return { hostId, localId, ackPeriod, ackAdvance, allowReconnect, isRealTime };
667
+ }
668
+ if (typeof value === "object" && value !== null) {
669
+ const obj = value;
670
+ const serializedId = obj.SerializedId;
671
+ if (!Array.isArray(serializedId) || serializedId.length < 2)
672
+ return null;
673
+ const rawHostId = serializedId[0];
674
+ const hostId = String(rawHostId);
675
+ const localId = Number(serializedId[1]);
676
+ const ackPeriod = Number(obj.AckPeriod ?? 256);
677
+ const ackAdvance = Number(obj.AckAdvance ?? 128);
678
+ const allowReconnect = obj.AllowReconnect !== false;
679
+ const isRealTime = obj.IsRealTime === true;
680
+ return { hostId, localId, ackPeriod, ackAdvance, allowReconnect, isRealTime };
681
+ }
682
+ return null;
321
683
  }
322
- var RpcStream = class {
684
+ var RpcStream = class _RpcStream {
323
685
  id;
324
686
  kind = RpcObjectKind.Remote;
325
687
  allowReconnect;
326
688
  peer;
327
689
  ackPeriod;
328
690
  ackAdvance;
329
- _buffer = [];
691
+ // Double-ended queue so consumption via `shift()` is O(1) and the
692
+ // backing store frees memory as items are drained. The previous
693
+ // `T[]` buffer kept every item for the life of the stream because
694
+ // the iterator tracked a read index instead of shifting — fine for
695
+ // short runs but a slow leak in the browser where a video call can
696
+ // last an hour.
697
+ _buffer = new Denque();
330
698
  _nextExpectedIndex = 0;
331
699
  _consumerWaiting = null;
332
700
  _completed = false;
@@ -346,6 +714,17 @@ var RpcStream = class {
346
714
  onItem(index, item) {
347
715
  if (this._disposed || this._completed) return;
348
716
  if (index > this._nextExpectedIndex) {
717
+ console.warn(
718
+ `[RpcStream] item index gap: localId=${this.id.localId}, expected=${this._nextExpectedIndex}, received=${index}`
719
+ );
720
+ if (!this.allowReconnect) {
721
+ this._completed = true;
722
+ this._completionError = new Error(
723
+ `Stream gap at index ${index} (expected ${this._nextExpectedIndex}); reconnect not allowed`
724
+ );
725
+ this._notifyConsumer();
726
+ return;
727
+ }
349
728
  this._sendAck(this._nextExpectedIndex, true);
350
729
  return;
351
730
  }
@@ -362,6 +741,17 @@ var RpcStream = class {
362
741
  onBatch(index, items) {
363
742
  if (this._disposed || this._completed) return;
364
743
  if (index > this._nextExpectedIndex) {
744
+ console.warn(
745
+ `[RpcStream] batch index gap: localId=${this.id.localId}, expected=${this._nextExpectedIndex}, received=${index}`
746
+ );
747
+ if (!this.allowReconnect) {
748
+ this._completed = true;
749
+ this._completionError = new Error(
750
+ `Stream gap at index ${index} (expected ${this._nextExpectedIndex}); reconnect not allowed`
751
+ );
752
+ this._notifyConsumer();
753
+ return;
754
+ }
365
755
  this._sendAck(this._nextExpectedIndex, true);
366
756
  return;
367
757
  }
@@ -397,10 +787,9 @@ var RpcStream = class {
397
787
  }
398
788
  // -- AsyncIterable --
399
789
  [Symbol.asyncIterator]() {
400
- if (this._iterating) throw new Error("RpcStream can only be iterated once.");
790
+ if (this._iterating)
791
+ throw new Error("RpcStream can only be iterated once.");
401
792
  this._iterating = true;
402
- let bufferIndex = 0;
403
- let consumedIndex = 0;
404
793
  const self = this;
405
794
  return {
406
795
  async next() {
@@ -409,10 +798,8 @@ var RpcStream = class {
409
798
  self._sendAck(0, true);
410
799
  }
411
800
  while (true) {
412
- if (bufferIndex < self._buffer.length) {
413
- const value = self._buffer[bufferIndex];
414
- bufferIndex++;
415
- consumedIndex++;
801
+ if (!self._buffer.isEmpty()) {
802
+ const value = self._buffer.shift();
416
803
  return { value, done: false };
417
804
  }
418
805
  if (self._completed) {
@@ -451,17 +838,30 @@ var RpcStream = class {
451
838
  this._sendAck(nextIndex, false);
452
839
  }
453
840
  }
454
- _sendAck(nextIndex, _mustReset) {
841
+ static _emptyGuid = "00000000-0000-0000-0000-000000000000";
842
+ _sendAck(nextIndex, mustReset) {
455
843
  this._ackSentUpTo = nextIndex;
456
844
  const conn = this.peer.connection;
457
845
  if (conn) {
458
- this.peer.hub.systemCallSender.ack(conn, this.id.localId, nextIndex, this.id.hostId);
846
+ const hostId = mustReset ? this.id.hostId : _RpcStream._emptyGuid;
847
+ this.peer.hub.systemCallSender.ack(
848
+ conn,
849
+ this.peer.format,
850
+ this.id.localId,
851
+ nextIndex,
852
+ hostId
853
+ );
459
854
  }
460
855
  }
461
856
  _sendAckEnd() {
462
857
  const conn = this.peer.connection;
463
858
  if (conn) {
464
- this.peer.hub.systemCallSender.ackEnd(conn, this.id.localId, this.id.hostId);
859
+ this.peer.hub.systemCallSender.ackEnd(
860
+ conn,
861
+ this.peer.format,
862
+ this.id.localId,
863
+ this.id.hostId
864
+ );
465
865
  }
466
866
  }
467
867
  };
@@ -483,6 +883,8 @@ function resolveStreamRefs(value, peer) {
483
883
  return value;
484
884
  }
485
885
  if (typeof value === "object") {
886
+ if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer)
887
+ return value;
486
888
  for (const key of Object.keys(value)) {
487
889
  value[key] = resolveStreamRefs(
488
890
  value[key],
@@ -528,21 +930,39 @@ var RpcSystemCallHandler = class {
528
930
  }
529
931
  case RpcSystemCalls.item: {
530
932
  const stream = peer.remoteObjects.get(relatedId);
531
- if (stream) stream.onItem(args[0], resolveStreamRefs(args[1], peer));
933
+ if (!stream) {
934
+ console.warn(
935
+ `[RpcSysHandler] $sys.I: no stream for relatedId=${relatedId}`
936
+ );
937
+ } else {
938
+ stream.onItem(
939
+ args[0],
940
+ resolveStreamRefs(args[1], peer)
941
+ );
942
+ }
532
943
  break;
533
944
  }
534
945
  case RpcSystemCalls.batch: {
535
946
  const stream = peer.remoteObjects.get(relatedId);
536
- if (stream) {
947
+ if (!stream) {
948
+ console.warn(
949
+ `[RpcSysHandler] $sys.B: no stream for relatedId=${relatedId}`
950
+ );
951
+ } else if (Array.isArray(args[1])) {
537
952
  const items = args[1];
538
- for (let i = 0; i < items.length; i++) items[i] = resolveStreamRefs(items[i], peer);
953
+ for (let i = 0; i < items.length; i++)
954
+ items[i] = resolveStreamRefs(items[i], peer);
539
955
  stream.onBatch(args[0], items);
540
956
  }
541
957
  break;
542
958
  }
543
959
  case RpcSystemCalls.end: {
544
960
  const stream = peer.remoteObjects.get(relatedId);
545
- if (stream) {
961
+ if (!stream) {
962
+ console.warn(
963
+ `[RpcSysHandler] $sys.End: no stream for relatedId=${relatedId}`
964
+ );
965
+ } else {
546
966
  const errorInfo = args[1];
547
967
  const msg = errorInfo?.Message ?? errorInfo?.message;
548
968
  const error = msg ? new Error(msg) : null;
@@ -560,76 +980,142 @@ var RpcSystemCallHandler = class {
560
980
  sender?.onAckEnd(args[0]);
561
981
  break;
562
982
  }
983
+ default: {
984
+ if (method === "$sys.Disconnect" || method?.startsWith("$sys.Disconnect")) {
985
+ const ids = args[0];
986
+ if (Array.isArray(ids)) {
987
+ for (const id of ids) {
988
+ const remoteObj = peer.remoteObjects.get(id);
989
+ if (remoteObj && typeof remoteObj.disconnect === "function") {
990
+ remoteObj.disconnect();
991
+ }
992
+ const sharedObj = peer.sharedObjects.get(id);
993
+ if (sharedObj && typeof sharedObj.disconnect === "function") {
994
+ sharedObj.disconnect();
995
+ }
996
+ }
997
+ }
998
+ }
999
+ break;
1000
+ }
563
1001
  }
564
1002
  }
565
1003
  };
566
1004
 
567
1005
  // src/rpc-system-call-sender.ts
568
- var RpcSystemCallSender = class {
569
- handshake(conn, peerId, hubId, index) {
570
- const msg = serializeMessage({ Method: RpcSystemCalls.handshake }, [{
1006
+ var RpcSystemCallSender = class _RpcSystemCallSender {
1007
+ // Reusable envelopes — one per hot-path method.
1008
+ _itemEnv = {
1009
+ Method: RpcSystemCalls.item,
1010
+ RelatedId: 0
1011
+ };
1012
+ _batchEnv = {
1013
+ Method: RpcSystemCalls.batch,
1014
+ RelatedId: 0
1015
+ };
1016
+ _endEnv = {
1017
+ Method: RpcSystemCalls.end,
1018
+ RelatedId: 0
1019
+ };
1020
+ _ackEnv = {
1021
+ Method: RpcSystemCalls.ack,
1022
+ RelatedId: 0
1023
+ };
1024
+ _ackEndEnv = {
1025
+ Method: RpcSystemCalls.ackEnd,
1026
+ RelatedId: 0
1027
+ };
1028
+ // Reusable arg arrays.
1029
+ _itemArgs = [0, null];
1030
+ _batchArgs = [0, null];
1031
+ _endArgs = [0, { TypeRef: "", Message: "" }];
1032
+ _ackArgs = [0, ""];
1033
+ _ackEndArgs = [""];
1034
+ static NO_ERROR = Object.freeze({ TypeRef: "", Message: "" });
1035
+ registry;
1036
+ _send(conn, format, envelope, args) {
1037
+ const wireData = format.serializeMessage(
1038
+ envelope,
1039
+ args,
1040
+ conn.encoder,
1041
+ this.registry
1042
+ );
1043
+ if (typeof wireData === "string") {
1044
+ conn.send(wireData);
1045
+ } else {
1046
+ conn.sendBinary(wireData);
1047
+ }
1048
+ }
1049
+ handshake(conn, format, peerId, hubId, index) {
1050
+ const handshakeArg = format.isBinary ? [peerId, null, hubId, 2, index] : {
571
1051
  RemotePeerId: peerId,
572
1052
  RemoteApiVersionSet: null,
573
1053
  RemoteHubId: hubId,
574
1054
  ProtocolVersion: 2,
575
1055
  Index: index
576
- }]);
577
- conn.send(msg);
578
- }
579
- ok(conn, relatedId, result) {
580
- const msg = serializeMessage({ Method: RpcSystemCalls.ok, RelatedId: relatedId }, [result]);
581
- conn.send(msg);
1056
+ };
1057
+ this._send(conn, format, { Method: RpcSystemCalls.handshake }, [
1058
+ handshakeArg
1059
+ ]);
1060
+ }
1061
+ ok(conn, format, relatedId, result) {
1062
+ this._send(
1063
+ conn,
1064
+ format,
1065
+ { Method: RpcSystemCalls.ok, RelatedId: relatedId },
1066
+ [result]
1067
+ );
582
1068
  }
583
- error(conn, relatedId, error) {
1069
+ error(conn, format, relatedId, error) {
584
1070
  const message = error instanceof Error ? error.message : String(error);
585
- const msg = serializeMessage(
1071
+ this._send(
1072
+ conn,
1073
+ format,
586
1074
  { Method: RpcSystemCalls.error, RelatedId: relatedId },
587
1075
  [{ Message: message }]
588
1076
  );
589
- conn.send(msg);
590
- }
591
- cancel(conn, relatedId) {
592
- const msg = serializeMessage({ Method: RpcSystemCalls.cancel, RelatedId: relatedId });
593
- conn.send(msg);
594
- }
595
- keepAlive(conn, activeCallIds) {
596
- const msg = serializeMessage({ Method: RpcSystemCalls.keepAlive }, [activeCallIds]);
597
- conn.send(msg);
598
- }
599
- item(conn, localId, index, item) {
600
- const msg = serializeMessage(
601
- { Method: RpcSystemCalls.item, RelatedId: localId },
602
- [index, item]
603
- );
604
- conn.send(msg);
605
1077
  }
606
- batch(conn, localId, index, items) {
607
- const msg = serializeMessage(
608
- { Method: RpcSystemCalls.batch, RelatedId: localId },
609
- [index, items]
610
- );
611
- conn.send(msg);
612
- }
613
- end(conn, localId, index, error = null) {
614
- const msg = serializeMessage(
615
- { Method: RpcSystemCalls.end, RelatedId: localId },
616
- [index, error]
617
- );
618
- conn.send(msg);
619
- }
620
- ack(conn, localId, nextIndex, hostId) {
621
- const msg = serializeMessage(
622
- { Method: RpcSystemCalls.ack, RelatedId: localId },
623
- [nextIndex, hostId]
624
- );
625
- conn.send(msg);
1078
+ cancel(conn, format, relatedId) {
1079
+ this._send(conn, format, {
1080
+ Method: RpcSystemCalls.cancel,
1081
+ RelatedId: relatedId
1082
+ });
626
1083
  }
627
- ackEnd(conn, localId, hostId) {
628
- const msg = serializeMessage(
629
- { Method: RpcSystemCalls.ackEnd, RelatedId: localId },
630
- [hostId]
631
- );
632
- conn.send(msg);
1084
+ keepAlive(conn, format, activeCallIds) {
1085
+ this._send(conn, format, { Method: RpcSystemCalls.keepAlive }, [
1086
+ activeCallIds
1087
+ ]);
1088
+ }
1089
+ item(conn, format, localId, index, item) {
1090
+ this._itemEnv.RelatedId = localId;
1091
+ this._itemArgs[0] = index;
1092
+ this._itemArgs[1] = item;
1093
+ this._send(conn, format, this._itemEnv, this._itemArgs);
1094
+ this._itemArgs[1] = null;
1095
+ }
1096
+ batch(conn, format, localId, index, items) {
1097
+ this._batchEnv.RelatedId = localId;
1098
+ this._batchArgs[0] = index;
1099
+ this._batchArgs[1] = items;
1100
+ this._send(conn, format, this._batchEnv, this._batchArgs);
1101
+ this._batchArgs[1] = null;
1102
+ }
1103
+ end(conn, format, localId, index, error = _RpcSystemCallSender.NO_ERROR) {
1104
+ this._endEnv.RelatedId = localId;
1105
+ this._endArgs[0] = index;
1106
+ this._endArgs[1] = error;
1107
+ this._send(conn, format, this._endEnv, this._endArgs);
1108
+ }
1109
+ ack(conn, format, localId, nextIndex, hostId) {
1110
+ this._ackEnv.RelatedId = localId;
1111
+ this._ackArgs[0] = nextIndex;
1112
+ this._ackArgs[1] = hostId;
1113
+ this._send(conn, format, this._ackEnv, this._ackArgs);
1114
+ }
1115
+ ackEnd(conn, format, localId, hostId) {
1116
+ this._ackEndEnv.RelatedId = localId;
1117
+ this._ackEndArgs[0] = hostId;
1118
+ this._send(conn, format, this._ackEndEnv, this._ackEndArgs);
633
1119
  }
634
1120
  };
635
1121
 
@@ -641,29 +1127,42 @@ var RpcStreamSender = class {
641
1127
  id;
642
1128
  kind = RpcObjectKind.Local;
643
1129
  allowReconnect;
1130
+ isRealTime;
1131
+ canSkipTo;
644
1132
  peer;
645
1133
  ackPeriod;
646
1134
  ackAdvance;
647
1135
  _nextIndex = 0;
648
1136
  _ended = false;
649
1137
  _started = new PromiseSource4();
650
- constructor(peer, ackPeriod = DEFAULT_ACK_PERIOD, ackAdvance = DEFAULT_ACK_ADVANCE, allowReconnect = true) {
1138
+ _lastAckedIndex = 0;
1139
+ _ackWaiting = null;
1140
+ constructor(peer, ackPeriod = DEFAULT_ACK_PERIOD, ackAdvance = DEFAULT_ACK_ADVANCE, allowReconnect = true, isRealTime = false, canSkipTo = () => true) {
651
1141
  const localId = peer.sharedObjects.nextId();
652
1142
  this.id = { hostId: peer.hub.hubId, localId };
653
1143
  this.allowReconnect = allowReconnect;
1144
+ this.isRealTime = isRealTime;
1145
+ this.canSkipTo = canSkipTo;
654
1146
  this.peer = peer;
655
1147
  this.ackPeriod = ackPeriod;
656
1148
  this.ackAdvance = ackAdvance;
657
1149
  }
658
1150
  /** Returns the stream reference string for the $sys.Ok response. */
659
1151
  toRef() {
660
- return `${this.id.hostId},${this.id.localId},${this.ackPeriod},${this.ackAdvance},${this.allowReconnect ? "1" : "0"}`;
1152
+ return `${this.id.hostId},${this.id.localId},${this.ackPeriod},${this.ackAdvance},${this.allowReconnect ? "1" : "0"},${this.isRealTime ? "1" : "0"}`;
661
1153
  }
662
1154
  /** Called by system call handler when $sys.Ack is received from the client. */
663
- onAck(_nextIndex, _hostId) {
1155
+ onAck(nextIndex, _hostId) {
664
1156
  if (!this._started.isCompleted) {
665
1157
  this._started.resolve();
666
1158
  }
1159
+ if (nextIndex > this._lastAckedIndex) {
1160
+ this._lastAckedIndex = nextIndex;
1161
+ }
1162
+ if (this._ackWaiting) {
1163
+ this._ackWaiting.resolve();
1164
+ this._ackWaiting = null;
1165
+ }
667
1166
  }
668
1167
  /** Called by system call handler when $sys.AckEnd is received from the client. */
669
1168
  onAckEnd(_hostId) {
@@ -675,7 +1174,13 @@ var RpcStreamSender = class {
675
1174
  if (this._ended) return;
676
1175
  const conn = this.peer.connection;
677
1176
  if (!conn) return;
678
- this.peer.hub.systemCallSender.item(conn, this.id.localId, this._nextIndex, item);
1177
+ this.peer.hub.systemCallSender.item(
1178
+ conn,
1179
+ this.peer.format,
1180
+ this.id.localId,
1181
+ this._nextIndex,
1182
+ item
1183
+ );
679
1184
  this._nextIndex++;
680
1185
  }
681
1186
  /** Send a batch of items to the client. */
@@ -683,7 +1188,13 @@ var RpcStreamSender = class {
683
1188
  if (this._ended || items.length === 0) return;
684
1189
  const conn = this.peer.connection;
685
1190
  if (!conn) return;
686
- this.peer.hub.systemCallSender.batch(conn, this.id.localId, this._nextIndex, items);
1191
+ this.peer.hub.systemCallSender.batch(
1192
+ conn,
1193
+ this.peer.format,
1194
+ this.id.localId,
1195
+ this._nextIndex,
1196
+ items
1197
+ );
687
1198
  this._nextIndex += items.length;
688
1199
  }
689
1200
  /** Signal stream completion to the client. */
@@ -692,19 +1203,63 @@ var RpcStreamSender = class {
692
1203
  this._ended = true;
693
1204
  const conn = this.peer.connection;
694
1205
  if (!conn) return;
695
- const errorInfo = error ? { Message: error.message } : null;
696
- this.peer.hub.systemCallSender.end(conn, this.id.localId, this._nextIndex, errorInfo);
1206
+ const errorInfo = error ? { TypeRef: "System.Exception", Message: error.message } : { TypeRef: "", Message: "" };
1207
+ this.peer.hub.systemCallSender.end(
1208
+ conn,
1209
+ this.peer.format,
1210
+ this.id.localId,
1211
+ this._nextIndex,
1212
+ errorInfo
1213
+ );
697
1214
  }
698
1215
  /**
699
1216
  * Consume an AsyncIterable and send all items to the client.
700
1217
  * Waits for the client's initial Ack before starting to pump items.
1218
+ *
1219
+ * When `isRealTime` is true, applies flow control based on `ackAdvance`:
1220
+ * if the sender is `ackAdvance` items ahead of the last ACK, it enters
1221
+ * skip mode — draining the source and discarding items until it finds
1222
+ * one where `canSkipTo` returns true.
701
1223
  */
702
1224
  async writeFrom(source) {
703
1225
  await this._started.promise;
1226
+ const iterator = source[Symbol.asyncIterator]();
704
1227
  try {
705
- for await (const item of source) {
1228
+ while (true) {
1229
+ const next = await iterator.next();
1230
+ if (next.done || this._ended) break;
1231
+ const item = next.value;
1232
+ if (this._nextIndex < this._lastAckedIndex + this.ackAdvance) {
1233
+ this.sendItem(item);
1234
+ continue;
1235
+ }
1236
+ if (!this.isRealTime) {
1237
+ await this._waitForAckBudget();
1238
+ if (this._ended) return;
1239
+ this.sendItem(item);
1240
+ continue;
1241
+ }
1242
+ let latestSkipTarget = this.canSkipTo(item) ? item : void 0;
1243
+ let sourceExhausted = false;
1244
+ while (this._nextIndex >= this._lastAckedIndex + this.ackAdvance) {
1245
+ if (this._ended) return;
1246
+ const n = await iterator.next();
1247
+ if (n.done) {
1248
+ sourceExhausted = true;
1249
+ break;
1250
+ }
1251
+ if (this.canSkipTo(n.value)) {
1252
+ latestSkipTarget = n.value;
1253
+ }
1254
+ }
706
1255
  if (this._ended) return;
707
- this.sendItem(item);
1256
+ if (latestSkipTarget !== void 0) {
1257
+ this.sendItem(latestSkipTarget);
1258
+ }
1259
+ if (sourceExhausted) {
1260
+ if (!this._ended) this.sendEnd();
1261
+ return;
1262
+ }
708
1263
  }
709
1264
  if (!this._ended) {
710
1265
  this.sendEnd();
@@ -715,6 +1270,14 @@ var RpcStreamSender = class {
715
1270
  }
716
1271
  }
717
1272
  }
1273
+ /** Wait until _nextIndex < _lastAckedIndex + ackAdvance. */
1274
+ async _waitForAckBudget() {
1275
+ while (this._nextIndex >= this._lastAckedIndex + this.ackAdvance) {
1276
+ if (this._ended) return;
1277
+ this._ackWaiting = new PromiseSource4();
1278
+ await this._ackWaiting.promise;
1279
+ }
1280
+ }
718
1281
  // -- IRpcObject --
719
1282
  reconnect() {
720
1283
  }
@@ -736,6 +1299,9 @@ var RpcRemoteObjectTracker = class {
736
1299
  get(localId) {
737
1300
  return this._objects.get(localId);
738
1301
  }
1302
+ keys() {
1303
+ return this._objects.keys();
1304
+ }
739
1305
  unregister(obj) {
740
1306
  this._objects.delete(obj.id.localId);
741
1307
  }
@@ -747,10 +1313,8 @@ var RpcRemoteObjectTracker = class {
747
1313
  }
748
1314
  reconnectAll() {
749
1315
  for (const obj of this._objects.values()) {
750
- if (obj.allowReconnect)
751
- obj.reconnect();
752
- else
753
- obj.disconnect();
1316
+ if (obj.allowReconnect) obj.reconnect();
1317
+ else obj.disconnect();
754
1318
  }
755
1319
  }
756
1320
  };
@@ -768,6 +1332,9 @@ var RpcSharedObjectTracker = class {
768
1332
  get(localId) {
769
1333
  return this._objects.get(localId);
770
1334
  }
1335
+ keys() {
1336
+ return this._objects.keys();
1337
+ }
771
1338
  unregister(obj) {
772
1339
  this._objects.delete(obj.id.localId);
773
1340
  }
@@ -791,8 +1358,164 @@ var RpcClientPeerReconnectDelayer = class extends RetryDelayer {
791
1358
  }
792
1359
  };
793
1360
 
1361
+ // src/rpc-serialization-format.ts
1362
+ import { Decoder as Decoder3 } from "@msgpack/msgpack";
1363
+ var RpcSerializationFormat = class {
1364
+ /** Create a reusable binary encoder for this format. Returns undefined for text formats. */
1365
+ createEncoder() {
1366
+ return void 0;
1367
+ }
1368
+ /** Create a reusable binary decoder for this format. Returns undefined for text formats. */
1369
+ createDecoder() {
1370
+ return void 0;
1371
+ }
1372
+ // Named format instances — initialized in initFormats() below (after subclasses are defined)
1373
+ static SystemJsonV5;
1374
+ static SystemJsonV5NP;
1375
+ static NewtonsoftJsonV5;
1376
+ static NewtonsoftJsonV5NP;
1377
+ static MessagePackV6;
1378
+ static MemoryPackV6;
1379
+ static MessagePackV6C;
1380
+ static MemoryPackV6C;
1381
+ static All;
1382
+ /** Convenience shortcut for RpcSerializationFormatResolver.Default.get(key). */
1383
+ static get(key) {
1384
+ return RpcSerializationFormatResolver.Default.get(key);
1385
+ }
1386
+ /** Convenience shortcut for RpcSerializationFormatResolver.Default.tryGet(key). */
1387
+ static tryGet(key) {
1388
+ return RpcSerializationFormatResolver.Default.tryGet(key);
1389
+ }
1390
+ };
1391
+ var RpcJsonSerializationFormat = class extends RpcSerializationFormat {
1392
+ key;
1393
+ isBinary = false;
1394
+ isCompact = false;
1395
+ constructor(key) {
1396
+ super();
1397
+ this.key = key;
1398
+ }
1399
+ serializeMessage(message, args) {
1400
+ return serializeMessage(message, args);
1401
+ }
1402
+ deserializeTextMessage(raw) {
1403
+ return deserializeMessage(raw);
1404
+ }
1405
+ splitBinaryFrame() {
1406
+ throw new Error("Text format does not support binary frames");
1407
+ }
1408
+ serializeBinaryFrame() {
1409
+ throw new Error("Text format does not support binary frames");
1410
+ }
1411
+ };
1412
+ var RpcMessagePackSerializationFormat = class extends RpcSerializationFormat {
1413
+ key;
1414
+ isBinary = true;
1415
+ isCompact = false;
1416
+ constructor(key) {
1417
+ super();
1418
+ this.key = key;
1419
+ }
1420
+ serializeMessage(message, args, encoder) {
1421
+ return serializeBinaryMessage(message, args, encoder);
1422
+ }
1423
+ deserializeTextMessage(raw) {
1424
+ return deserializeMessage(raw);
1425
+ }
1426
+ splitBinaryFrame(frame, decoder) {
1427
+ return splitBinaryFrame(frame, decoder);
1428
+ }
1429
+ serializeBinaryFrame(messages) {
1430
+ return serializeBinaryFrame(messages);
1431
+ }
1432
+ createEncoder() {
1433
+ return createBinaryEncoder();
1434
+ }
1435
+ createDecoder() {
1436
+ return new Decoder3();
1437
+ }
1438
+ };
1439
+ var RpcMessagePackCompactSerializationFormat = class extends RpcSerializationFormat {
1440
+ key;
1441
+ isBinary = true;
1442
+ isCompact = true;
1443
+ constructor(key) {
1444
+ super();
1445
+ this.key = key;
1446
+ }
1447
+ serializeMessage(message, args, encoder, registry) {
1448
+ return serializeCompactBinaryMessage(
1449
+ message,
1450
+ args,
1451
+ registry,
1452
+ encoder
1453
+ );
1454
+ }
1455
+ deserializeTextMessage(raw) {
1456
+ return deserializeMessage(raw);
1457
+ }
1458
+ splitBinaryFrame(frame, decoder, registry) {
1459
+ return splitCompactBinaryFrame(frame, registry, decoder);
1460
+ }
1461
+ serializeBinaryFrame(messages) {
1462
+ return serializeBinaryFrame(messages);
1463
+ }
1464
+ createEncoder() {
1465
+ return createBinaryEncoder();
1466
+ }
1467
+ createDecoder() {
1468
+ return new Decoder3();
1469
+ }
1470
+ };
1471
+ RpcSerializationFormat.SystemJsonV5 = new RpcJsonSerializationFormat("json5");
1472
+ RpcSerializationFormat.SystemJsonV5NP = new RpcJsonSerializationFormat("json5np");
1473
+ RpcSerializationFormat.NewtonsoftJsonV5 = new RpcJsonSerializationFormat("njson5");
1474
+ RpcSerializationFormat.NewtonsoftJsonV5NP = new RpcJsonSerializationFormat("njson5np");
1475
+ RpcSerializationFormat.MessagePackV6 = new RpcMessagePackSerializationFormat("msgpack6");
1476
+ RpcSerializationFormat.MemoryPackV6 = new RpcMessagePackSerializationFormat("mempack6");
1477
+ RpcSerializationFormat.MessagePackV6C = new RpcMessagePackCompactSerializationFormat("msgpack6c");
1478
+ RpcSerializationFormat.MemoryPackV6C = new RpcMessagePackCompactSerializationFormat("mempack6c");
1479
+ RpcSerializationFormat.All = [
1480
+ RpcSerializationFormat.SystemJsonV5,
1481
+ RpcSerializationFormat.SystemJsonV5NP,
1482
+ RpcSerializationFormat.NewtonsoftJsonV5,
1483
+ RpcSerializationFormat.NewtonsoftJsonV5NP,
1484
+ RpcSerializationFormat.MessagePackV6,
1485
+ RpcSerializationFormat.MemoryPackV6,
1486
+ RpcSerializationFormat.MessagePackV6C,
1487
+ RpcSerializationFormat.MemoryPackV6C
1488
+ ];
1489
+ var RpcSerializationFormatResolver = class _RpcSerializationFormatResolver {
1490
+ static DefaultFormats = RpcSerializationFormat.All;
1491
+ static Default = new _RpcSerializationFormatResolver("json5np");
1492
+ defaultFormatKey;
1493
+ formats;
1494
+ get defaultFormat() {
1495
+ return this.get(this.defaultFormatKey);
1496
+ }
1497
+ constructor(defaultFormatKey, formats) {
1498
+ const map = /* @__PURE__ */ new Map();
1499
+ for (const f of formats ?? _RpcSerializationFormatResolver.DefaultFormats)
1500
+ map.set(f.key, f);
1501
+ if (!map.has(defaultFormatKey))
1502
+ throw new Error(`No format with key '${defaultFormatKey}'.`);
1503
+ this.defaultFormatKey = defaultFormatKey;
1504
+ this.formats = map;
1505
+ }
1506
+ get(key) {
1507
+ const format = this.tryGet(key);
1508
+ if (!format)
1509
+ throw new Error(`No format with key '${key}'.`);
1510
+ return format;
1511
+ }
1512
+ tryGet(key) {
1513
+ if (!key) key = this.defaultFormatKey;
1514
+ return this.formats.get(key);
1515
+ }
1516
+ };
1517
+
794
1518
  // src/rpc-peer.ts
795
- var DEFAULT_SERIALIZATION_FORMAT = "json5np";
796
1519
  var RPC_CLOSE_CODE_UNSUPPORTED_FORMAT = 4001;
797
1520
  var defaultConnectionUrlResolver = (peer) => {
798
1521
  const sep = peer.ref.includes("?") ? "&" : "?";
@@ -839,17 +1562,27 @@ var RpcPeer = class {
839
1562
  this._startKeepAlive();
840
1563
  });
841
1564
  }
1565
+ /** The serialization format used by this peer. Override in subclasses. */
1566
+ get format() {
1567
+ return RpcSerializationFormatResolver.Default.defaultFormat;
1568
+ }
842
1569
  call(method, args, options) {
843
1570
  const callId = this.outbound.nextId();
844
1571
  const outboundCall = options?.outboundCallFactory ? options.outboundCallFactory(callId, method) : new RpcOutboundCall(callId, method);
845
- const msg = serializeMessage(
846
- { Method: method, RelatedId: callId, CallType: options?.callTypeId ?? 0 },
847
- args
1572
+ const envelope = {
1573
+ Method: method,
1574
+ RelatedId: callId,
1575
+ CallType: options?.callTypeId ?? 0
1576
+ };
1577
+ outboundCall.serializedWireData = this.format.serializeMessage(
1578
+ envelope,
1579
+ args,
1580
+ this._connection?.encoder,
1581
+ this._hub.registry
848
1582
  );
849
- outboundCall.serializedMessage = msg;
850
1583
  if (this._connection !== void 0) {
851
1584
  this.outbound.register(outboundCall);
852
- this._connection.send(msg);
1585
+ this._sendWireData(outboundCall.serializedWireData);
853
1586
  } else {
854
1587
  this._pendingSends.push(outboundCall);
855
1588
  }
@@ -863,12 +1596,16 @@ var RpcPeer = class {
863
1596
  outboundCall.result.reject(new Error("Call cancelled."));
864
1597
  outboundCall.onDisconnect();
865
1598
  if (peer._connection !== void 0)
866
- hub.systemCallSender.cancel(peer._connection, callId);
1599
+ hub.systemCallSender.cancel(peer._connection, peer.format, callId);
867
1600
  } else {
868
- const idx = peer._pendingSends.findIndex((c) => c.callId === callId);
1601
+ const idx = peer._pendingSends.findIndex(
1602
+ (c) => c.callId === callId
1603
+ );
869
1604
  if (idx !== -1) {
870
1605
  peer._pendingSends.splice(idx, 1);
871
- outboundCall.result.reject(new Error("Call cancelled."));
1606
+ outboundCall.result.reject(
1607
+ new Error("Call cancelled.")
1608
+ );
872
1609
  outboundCall.onDisconnect();
873
1610
  }
874
1611
  }
@@ -880,8 +1617,14 @@ var RpcPeer = class {
880
1617
  }
881
1618
  callNoWait(method, args) {
882
1619
  if (this._connection === void 0) return;
883
- const msg = serializeMessage({ Method: method, RelatedId: 0 }, args);
884
- this._connection.send(msg);
1620
+ const envelope = { Method: method, RelatedId: 0 };
1621
+ const wireData = this.format.serializeMessage(
1622
+ envelope,
1623
+ args,
1624
+ this._connection.encoder,
1625
+ this._hub.registry
1626
+ );
1627
+ this._sendWireData(wireData);
885
1628
  }
886
1629
  close() {
887
1630
  this._stopKeepAlive();
@@ -900,23 +1643,41 @@ var RpcPeer = class {
900
1643
  }
901
1644
  /** Send any messages buffered while disconnected. Call after connection + handshake are ready. */
902
1645
  _flushPendingSends() {
903
- if (this._pendingSends.length === 0 || this._connection === void 0) return;
1646
+ if (this._pendingSends.length === 0 || this._connection === void 0)
1647
+ return;
904
1648
  for (const call of this._pendingSends) {
905
1649
  this.outbound.register(call);
906
- this._connection.send(call.serializedMessage);
1650
+ this._sendWireData(call.serializedWireData);
907
1651
  }
908
1652
  this._pendingSends.length = 0;
909
1653
  }
1654
+ /** Send pre-serialized wire data through the current connection. */
1655
+ _sendWireData(data) {
1656
+ if (this._connection === void 0) return;
1657
+ if (typeof data === "string") {
1658
+ this._connection.send(data);
1659
+ } else {
1660
+ this._connection.sendBinary(data);
1661
+ }
1662
+ }
910
1663
  /** Override in subclasses to handle the remote peer's handshake response. */
911
1664
  _onHandshakeReceived(_handshake) {
912
1665
  }
913
- _handleMessage(raw) {
914
- const { message, args } = deserializeMessage(raw);
1666
+ _handleMessage(received) {
1667
+ let message;
1668
+ let args;
1669
+ if (received.kind === "binary") {
1670
+ message = received.message;
1671
+ args = received.args;
1672
+ } else {
1673
+ const parsed = deserializeMessage(received.raw);
1674
+ message = parsed.message;
1675
+ args = parsed.args;
1676
+ }
915
1677
  const method = message.Method ?? "";
916
1678
  if (method === RpcSystemCalls.handshake) {
917
1679
  const handshake = args[0];
918
- if (handshake !== void 0)
919
- this._onHandshakeReceived(handshake);
1680
+ if (handshake !== void 0) this._onHandshakeReceived(handshake);
920
1681
  return;
921
1682
  }
922
1683
  if (method.startsWith("$sys")) {
@@ -938,19 +1699,42 @@ var RpcPeer = class {
938
1699
  if (serviceHost !== void 0) {
939
1700
  void (async () => {
940
1701
  try {
941
- const context = this._connection !== void 0 ? { __rpcDispatch: true, callId: relatedId, connection: this._connection } : void 0;
942
- const result = await serviceHost.dispatch(method, args, context);
1702
+ const context = this._connection !== void 0 ? {
1703
+ __rpcDispatch: true,
1704
+ callId: relatedId,
1705
+ connection: this._connection
1706
+ } : void 0;
1707
+ const result = await serviceHost.dispatch(
1708
+ method,
1709
+ args,
1710
+ context
1711
+ );
943
1712
  if (methodDef?.stream === true && this._connection !== void 0) {
944
1713
  const sender = new RpcStreamSender(this);
945
1714
  this.sharedObjects.register(sender);
946
- this._hub.systemCallSender.ok(this._connection, relatedId, sender.toRef());
1715
+ this._hub.systemCallSender.ok(
1716
+ this._connection,
1717
+ this.format,
1718
+ relatedId,
1719
+ sender.toRef()
1720
+ );
947
1721
  void sender.writeFrom(result);
948
1722
  } else if (!isNoWait && this._connection !== void 0) {
949
- this._hub.systemCallSender.ok(this._connection, relatedId, result);
1723
+ this._hub.systemCallSender.ok(
1724
+ this._connection,
1725
+ this.format,
1726
+ relatedId,
1727
+ result
1728
+ );
950
1729
  }
951
1730
  } catch (e) {
952
1731
  if (!isNoWait && this._connection !== void 0) {
953
- this._hub.systemCallSender.error(this._connection, relatedId, e);
1732
+ this._hub.systemCallSender.error(
1733
+ this._connection,
1734
+ this.format,
1735
+ relatedId,
1736
+ e
1737
+ );
954
1738
  }
955
1739
  } finally {
956
1740
  if (!isNoWait) {
@@ -963,7 +1747,9 @@ var RpcPeer = class {
963
1747
  _startKeepAlive() {
964
1748
  this._keepAliveTimer = setInterval(() => {
965
1749
  if (this._connection !== void 0) {
966
- this._hub.systemCallSender.keepAlive(this._connection, this.outbound.activeCallIds());
1750
+ this._hub.systemCallSender.keepAlive(this._connection, this.format, [
1751
+ ...this.remoteObjects.keys()
1752
+ ]);
967
1753
  }
968
1754
  }, 15e3);
969
1755
  }
@@ -1011,10 +1797,16 @@ var RpcClientPeer = class extends RpcPeer {
1011
1797
  this._reconnectsAt = value;
1012
1798
  this.reconnectsAtChanged.trigger();
1013
1799
  }
1800
+ _format;
1014
1801
  constructor(hub, url, serializationFormat) {
1015
1802
  super(url, hub);
1016
1803
  this.clientId = guidToBase64Url(this.id);
1017
- this.serializationFormat = serializationFormat ?? DEFAULT_SERIALIZATION_FORMAT;
1804
+ const resolver = RpcSerializationFormatResolver.Default;
1805
+ this.serializationFormat = serializationFormat ?? resolver.defaultFormatKey;
1806
+ this._format = resolver.get(this.serializationFormat);
1807
+ }
1808
+ get format() {
1809
+ return this._format;
1018
1810
  }
1019
1811
  get connectionKind() {
1020
1812
  return this._connectionKind;
@@ -1032,7 +1824,12 @@ var RpcClientPeer = class extends RpcPeer {
1032
1824
  let lastCloseReason = "";
1033
1825
  try {
1034
1826
  const ws = wsFactory?.(connUrl) ?? new WebSocket(connUrl);
1035
- const conn = new RpcWebSocketConnection(ws);
1827
+ const conn = new RpcWebSocketConnection(
1828
+ ws,
1829
+ this.format.isBinary,
1830
+ this.format,
1831
+ this._hub.registry
1832
+ );
1036
1833
  this._connectionKind = 1 /* Connecting */;
1037
1834
  conn.closed.add((ev) => {
1038
1835
  lastCloseCode = ev.code;
@@ -1041,11 +1838,21 @@ var RpcClientPeer = class extends RpcPeer {
1041
1838
  this._pendingHandshake = new PromiseSource5();
1042
1839
  this.setupConnection(conn);
1043
1840
  this._connection = void 0;
1044
- const closedRejection = new Promise((_, reject) => conn.closed.add(() => reject(new Error("Connection failed"))));
1841
+ const closedRejection = new Promise(
1842
+ (_, reject) => conn.closed.add(
1843
+ () => reject(new Error("Connection failed"))
1844
+ )
1845
+ );
1045
1846
  closedRejection.catch(() => {
1046
1847
  });
1047
1848
  await Promise.race([conn.whenConnected, closedRejection]);
1048
- this._hub.systemCallSender.handshake(conn, this.id, this._hub.hubId, ++this._handshakeIndex);
1849
+ this._hub.systemCallSender.handshake(
1850
+ conn,
1851
+ this.format,
1852
+ this.id,
1853
+ this._hub.hubId,
1854
+ ++this._handshakeIndex
1855
+ );
1049
1856
  const remoteHandshake = await Promise.race([
1050
1857
  this._pendingHandshake.promise,
1051
1858
  closedRejection
@@ -1098,7 +1905,6 @@ var RpcClientPeer = class extends RpcPeer {
1098
1905
  * Regular in-flight calls are re-sent transparently. */
1099
1906
  _reconnect(_isPeerChanged) {
1100
1907
  if (this._connection === void 0) return;
1101
- const conn = this._connection;
1102
1908
  if (_isPeerChanged) {
1103
1909
  this.remoteObjects.disconnectAll();
1104
1910
  } else {
@@ -1110,7 +1916,7 @@ var RpcClientPeer = class extends RpcPeer {
1110
1916
  call.onDisconnect();
1111
1917
  this.outbound.remove(call.callId);
1112
1918
  } else {
1113
- conn.send(call.serializedMessage);
1919
+ this._sendWireData(call.serializedWireData);
1114
1920
  }
1115
1921
  }
1116
1922
  this._flushPendingSends();
@@ -1133,7 +1939,13 @@ var RpcServerPeer = class extends RpcPeer {
1133
1939
  }
1134
1940
  _onHandshakeReceived(_handshake) {
1135
1941
  if (this._connection !== void 0) {
1136
- this._hub.systemCallSender.handshake(this._connection, this.id, this._hub.hubId, 0);
1942
+ this._hub.systemCallSender.handshake(
1943
+ this._connection,
1944
+ this.format,
1945
+ this.id,
1946
+ this._hub.hubId,
1947
+ 0
1948
+ );
1137
1949
  }
1138
1950
  }
1139
1951
  };
@@ -1161,12 +1973,16 @@ var RpcServiceHost = class {
1161
1973
  for (const methodDef of def.methods.values()) {
1162
1974
  const fn = impl[methodDef.name];
1163
1975
  if (!fn) continue;
1164
- this._methods.set(wireMethodName(methodDef), { def: methodDef, fn });
1976
+ this._methods.set(wireMethodName(methodDef), {
1977
+ def: methodDef,
1978
+ fn
1979
+ });
1165
1980
  }
1166
1981
  }
1167
1982
  async dispatch(wireMethod, args, context) {
1168
1983
  const entry = this._methods.get(wireMethod);
1169
- if (entry === void 0) throw new Error(`Method not found: ${wireMethod}`);
1984
+ if (entry === void 0)
1985
+ throw new Error(`Method not found: ${wireMethod}`);
1170
1986
  if (context !== void 0 && entry.def.callTypeId !== 0) {
1171
1987
  return await entry.fn(...args, context);
1172
1988
  }
@@ -1205,6 +2021,539 @@ function rpcMethod(options) {
1205
2021
  };
1206
2022
  }
1207
2023
 
2024
+ // src/rpc-xxhash3.ts
2025
+ var U64_MASK = 0xffffffffffffffffn;
2026
+ var U32_MASK = 0xffffffffn;
2027
+ var PRIME32_1 = 2654435761;
2028
+ var PRIME32_2 = 2246822519;
2029
+ var PRIME32_3 = 3266489917;
2030
+ var PRIME64_1 = 0x9e3779b185ebca87n;
2031
+ var PRIME64_2 = 0xc2b2ae3d27d4eb4fn;
2032
+ var PRIME64_3 = 0x165667b19e3779f9n;
2033
+ var PRIME64_4 = 0x85ebca77c2b2ae63n;
2034
+ var PRIME64_5 = 0x27d4eb2f165667c5n;
2035
+ var XXH3_SECRET_SIZE_MIN = 136;
2036
+ var XXH_SECRET_DEFAULT_SIZE = 192;
2037
+ var STRIPE_LEN = 64;
2038
+ var XXH_SECRET_CONSUME_RATE = 8;
2039
+ var ACC_NB = STRIPE_LEN / 8;
2040
+ var XXH3_MIDSIZE_MAX = 240;
2041
+ var XXH3_MIDSIZE_STARTOFFSET = 3;
2042
+ var XXH3_MIDSIZE_LASTOFFSET = 17;
2043
+ var XXH_SECRET_LASTACC_START = 7;
2044
+ var XXH_SECRET_MERGEACCS_START = 11;
2045
+ var RRMXMX = 0x9fb21c651e98df25n;
2046
+ var DEFAULT_SECRET = new Uint8Array([
2047
+ 184,
2048
+ 254,
2049
+ 108,
2050
+ 57,
2051
+ 35,
2052
+ 164,
2053
+ 75,
2054
+ 190,
2055
+ 124,
2056
+ 1,
2057
+ 129,
2058
+ 44,
2059
+ 247,
2060
+ 33,
2061
+ 173,
2062
+ 28,
2063
+ 222,
2064
+ 212,
2065
+ 109,
2066
+ 233,
2067
+ 131,
2068
+ 144,
2069
+ 151,
2070
+ 219,
2071
+ 114,
2072
+ 64,
2073
+ 164,
2074
+ 164,
2075
+ 183,
2076
+ 179,
2077
+ 103,
2078
+ 31,
2079
+ 203,
2080
+ 121,
2081
+ 230,
2082
+ 78,
2083
+ 204,
2084
+ 192,
2085
+ 229,
2086
+ 120,
2087
+ 130,
2088
+ 90,
2089
+ 208,
2090
+ 125,
2091
+ 204,
2092
+ 255,
2093
+ 114,
2094
+ 33,
2095
+ 184,
2096
+ 8,
2097
+ 70,
2098
+ 116,
2099
+ 247,
2100
+ 67,
2101
+ 36,
2102
+ 142,
2103
+ 224,
2104
+ 53,
2105
+ 144,
2106
+ 230,
2107
+ 129,
2108
+ 58,
2109
+ 38,
2110
+ 76,
2111
+ 60,
2112
+ 40,
2113
+ 82,
2114
+ 187,
2115
+ 145,
2116
+ 195,
2117
+ 0,
2118
+ 203,
2119
+ 136,
2120
+ 208,
2121
+ 101,
2122
+ 139,
2123
+ 27,
2124
+ 83,
2125
+ 46,
2126
+ 163,
2127
+ 113,
2128
+ 100,
2129
+ 72,
2130
+ 151,
2131
+ 162,
2132
+ 13,
2133
+ 249,
2134
+ 78,
2135
+ 56,
2136
+ 25,
2137
+ 239,
2138
+ 70,
2139
+ 169,
2140
+ 222,
2141
+ 172,
2142
+ 216,
2143
+ 168,
2144
+ 250,
2145
+ 118,
2146
+ 63,
2147
+ 227,
2148
+ 156,
2149
+ 52,
2150
+ 63,
2151
+ 249,
2152
+ 220,
2153
+ 187,
2154
+ 199,
2155
+ 199,
2156
+ 11,
2157
+ 79,
2158
+ 29,
2159
+ 138,
2160
+ 81,
2161
+ 224,
2162
+ 75,
2163
+ 205,
2164
+ 180,
2165
+ 89,
2166
+ 49,
2167
+ 200,
2168
+ 159,
2169
+ 126,
2170
+ 201,
2171
+ 217,
2172
+ 120,
2173
+ 115,
2174
+ 100,
2175
+ 234,
2176
+ 197,
2177
+ 172,
2178
+ 131,
2179
+ 52,
2180
+ 211,
2181
+ 235,
2182
+ 195,
2183
+ 197,
2184
+ 129,
2185
+ 160,
2186
+ 255,
2187
+ 250,
2188
+ 19,
2189
+ 99,
2190
+ 235,
2191
+ 23,
2192
+ 13,
2193
+ 221,
2194
+ 81,
2195
+ 183,
2196
+ 240,
2197
+ 218,
2198
+ 73,
2199
+ 211,
2200
+ 22,
2201
+ 85,
2202
+ 38,
2203
+ 41,
2204
+ 212,
2205
+ 104,
2206
+ 158,
2207
+ 43,
2208
+ 22,
2209
+ 190,
2210
+ 88,
2211
+ 125,
2212
+ 71,
2213
+ 161,
2214
+ 252,
2215
+ 143,
2216
+ 248,
2217
+ 184,
2218
+ 209,
2219
+ 122,
2220
+ 208,
2221
+ 49,
2222
+ 206,
2223
+ 69,
2224
+ 203,
2225
+ 58,
2226
+ 143,
2227
+ 149,
2228
+ 22,
2229
+ 4,
2230
+ 40,
2231
+ 175,
2232
+ 215,
2233
+ 251,
2234
+ 202,
2235
+ 187,
2236
+ 75,
2237
+ 64,
2238
+ 126
2239
+ ]);
2240
+ function u64(x) {
2241
+ return x & U64_MASK;
2242
+ }
2243
+ function read32LE(buf, off) {
2244
+ return (buf[off] | buf[off + 1] << 8 | buf[off + 2] << 16 | buf[off + 3] << 24) >>> 0;
2245
+ }
2246
+ function read64LE(buf, off) {
2247
+ return BigInt(buf[off]) | BigInt(buf[off + 1]) << 8n | BigInt(buf[off + 2]) << 16n | BigInt(buf[off + 3]) << 24n | BigInt(buf[off + 4]) << 32n | BigInt(buf[off + 5]) << 40n | BigInt(buf[off + 6]) << 48n | BigInt(buf[off + 7]) << 56n;
2248
+ }
2249
+ function write64LE(buf, off, value) {
2250
+ let x = u64(value);
2251
+ for (let i = 0; i < 8; i++) {
2252
+ buf[off + i] = Number(x & 0xffn);
2253
+ x >>= 8n;
2254
+ }
2255
+ }
2256
+ function swap32(x) {
2257
+ return (x << 24 & 4278190080 | x << 8 & 16711680 | x >>> 8 & 65280 | x >>> 24 & 255) >>> 0;
2258
+ }
2259
+ function swap64(x) {
2260
+ x = u64(x);
2261
+ return x << 56n & 0xff00000000000000n | x << 40n & 0x00ff000000000000n | x << 24n & 0x0000ff0000000000n | x << 8n & 0x000000ff00000000n | x >> 8n & 0x00000000ff000000n | x >> 24n & 0x0000000000ff0000n | x >> 40n & 0x000000000000ff00n | x >> 56n & 0x00000000000000ffn;
2262
+ }
2263
+ function rotl64(x, amount) {
2264
+ const r = BigInt(amount & 63);
2265
+ return u64(x << r | x >> 64n - r);
2266
+ }
2267
+ function mul128Fold64(lhs, rhs) {
2268
+ const product = u64(lhs) * u64(rhs);
2269
+ return u64(product) ^ u64(product >> 64n);
2270
+ }
2271
+ function xxh64Avalanche(hash) {
2272
+ let h = u64(hash);
2273
+ h ^= h >> 33n;
2274
+ h = u64(h * PRIME64_2);
2275
+ h ^= h >> 29n;
2276
+ h = u64(h * PRIME64_3);
2277
+ h ^= h >> 32n;
2278
+ return u64(h);
2279
+ }
2280
+ function xxh3Avalanche(hash) {
2281
+ let h = u64(hash);
2282
+ h ^= h >> 37n;
2283
+ h = u64(h * 0x165667919e3779f9n);
2284
+ h ^= h >> 32n;
2285
+ return u64(h);
2286
+ }
2287
+ function len0(secret, seed) {
2288
+ const acc = u64(seed ^ read64LE(secret, 56) ^ read64LE(secret, 64));
2289
+ return xxh64Avalanche(acc);
2290
+ }
2291
+ function len1to3(input, length, secret, seed) {
2292
+ const byte1 = input[0];
2293
+ const byte2 = length > 1 ? input[1] : input[0];
2294
+ const byte3 = input[length - 1];
2295
+ const combined = (byte1 << 16 | byte2 << 24 | byte3 | length << 8) >>> 0;
2296
+ const bitflip = u64(
2297
+ BigInt((read32LE(secret, 0) ^ read32LE(secret, 4)) >>> 0) + seed
2298
+ );
2299
+ const value64 = u64(BigInt(combined) ^ bitflip);
2300
+ return xxh64Avalanche(value64);
2301
+ }
2302
+ function len4to8(input, length, secret, seed) {
2303
+ const inputHi = read32LE(input, 0);
2304
+ const inputLo = read32LE(input, length - 4);
2305
+ const input64 = BigInt(inputLo) | BigInt(inputHi) << 32n;
2306
+ let acc = read64LE(secret, 8) ^ read64LE(secret, 16);
2307
+ seed ^= BigInt(swap32(Number(seed & U32_MASK))) << 32n;
2308
+ acc = u64(acc - seed);
2309
+ acc ^= input64;
2310
+ acc ^= rotl64(acc, 49) ^ rotl64(acc, 24);
2311
+ acc = u64(acc * RRMXMX);
2312
+ acc ^= (acc >> 35n) + BigInt(length);
2313
+ acc = u64(acc * RRMXMX);
2314
+ acc ^= acc >> 28n;
2315
+ return u64(acc);
2316
+ }
2317
+ function len9to16(input, length, secret, seed) {
2318
+ let inputLo = read64LE(secret, 24) ^ read64LE(secret, 32);
2319
+ let inputHi = read64LE(secret, 40) ^ read64LE(secret, 48);
2320
+ let acc = BigInt(length);
2321
+ inputLo = u64(inputLo + seed);
2322
+ inputHi = u64(inputHi - seed);
2323
+ inputLo ^= read64LE(input, 0);
2324
+ inputHi ^= read64LE(input, length - 8);
2325
+ acc = u64(acc + swap64(inputLo));
2326
+ acc = u64(acc + inputHi);
2327
+ acc = u64(acc + mul128Fold64(inputLo, inputHi));
2328
+ return xxh3Avalanche(acc);
2329
+ }
2330
+ function mix16B(input, inputOff, secret, secretOff, seed) {
2331
+ let lhs = seed;
2332
+ let rhs = u64(0n - seed);
2333
+ lhs = u64(lhs + read64LE(secret, secretOff));
2334
+ rhs = u64(rhs + read64LE(secret, secretOff + 8));
2335
+ lhs ^= read64LE(input, inputOff);
2336
+ rhs ^= read64LE(input, inputOff + 8);
2337
+ return mul128Fold64(lhs, rhs);
2338
+ }
2339
+ function len17to128(input, length, secret, seed) {
2340
+ let i = Math.floor((length - 1) / 32);
2341
+ let acc = u64(BigInt(length) * PRIME64_1);
2342
+ for (; i >= 0; i--) {
2343
+ acc = u64(acc + mix16B(input, 16 * i, secret, 32 * i, seed));
2344
+ acc = u64(
2345
+ acc + mix16B(
2346
+ input,
2347
+ length - 16 * (i + 1),
2348
+ secret,
2349
+ 32 * i + 16,
2350
+ seed
2351
+ )
2352
+ );
2353
+ }
2354
+ return xxh3Avalanche(acc);
2355
+ }
2356
+ function len129to240(input, length, secret, seed) {
2357
+ let acc = u64(BigInt(length) * PRIME64_1);
2358
+ const nbRounds = Math.floor(length / 16);
2359
+ for (let i = 0; i < 8; i++) {
2360
+ acc = u64(acc + mix16B(input, 16 * i, secret, 16 * i, seed));
2361
+ }
2362
+ acc = xxh3Avalanche(acc);
2363
+ for (let i = 8; i < nbRounds; i++) {
2364
+ acc = u64(
2365
+ acc + mix16B(
2366
+ input,
2367
+ 16 * i,
2368
+ secret,
2369
+ 16 * (i - 8) + XXH3_MIDSIZE_STARTOFFSET,
2370
+ seed
2371
+ )
2372
+ );
2373
+ }
2374
+ acc = u64(
2375
+ acc + mix16B(
2376
+ input,
2377
+ length - 16,
2378
+ secret,
2379
+ XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET,
2380
+ seed
2381
+ )
2382
+ );
2383
+ return xxh3Avalanche(acc);
2384
+ }
2385
+ function hashShort(input, length, secret, seed) {
2386
+ if (length <= 16) {
2387
+ if (length > 8) return len9to16(input, length, secret, seed);
2388
+ if (length >= 4) return len4to8(input, length, secret, seed);
2389
+ if (length !== 0) return len1to3(input, length, secret, seed);
2390
+ return len0(secret, seed);
2391
+ }
2392
+ if (length <= 128) return len17to128(input, length, secret, seed);
2393
+ return len129to240(input, length, secret, seed);
2394
+ }
2395
+ function accumulate512(acc, input, inputOff, secret, secretOff) {
2396
+ for (let i = 0; i < ACC_NB; i++) {
2397
+ const dataVal = read64LE(input, inputOff + 8 * i);
2398
+ const dataKey = dataVal ^ read64LE(secret, secretOff + 8 * i);
2399
+ acc[i ^ 1] = u64(acc[i ^ 1] + dataVal);
2400
+ const low32 = dataKey & U32_MASK;
2401
+ const high32 = dataKey >> 32n;
2402
+ acc[i] = u64(acc[i] + low32 * high32);
2403
+ }
2404
+ }
2405
+ function scrambleAcc(acc, secret, secretOff) {
2406
+ for (let i = 0; i < ACC_NB; i++) {
2407
+ let x = acc[i];
2408
+ x ^= x >> 47n;
2409
+ x ^= read64LE(secret, secretOff + 8 * i);
2410
+ x = u64(x * BigInt(PRIME32_1));
2411
+ acc[i] = x;
2412
+ }
2413
+ }
2414
+ function accumulateLoop(acc, input, inputOff, secret, secretOff, nbStripes) {
2415
+ for (let n = 0; n < nbStripes; n++) {
2416
+ accumulate512(
2417
+ acc,
2418
+ input,
2419
+ inputOff + n * STRIPE_LEN,
2420
+ secret,
2421
+ secretOff + 8 * n
2422
+ );
2423
+ }
2424
+ }
2425
+ function mix2Accs(acc, accOff, secret, secretOff) {
2426
+ return mul128Fold64(
2427
+ acc[accOff] ^ read64LE(secret, secretOff),
2428
+ acc[accOff + 1] ^ read64LE(secret, secretOff + 8)
2429
+ );
2430
+ }
2431
+ function mergeAccs(acc, key, keyOff, start) {
2432
+ let result = start;
2433
+ for (let i = 0; i < 4; i++) {
2434
+ result = u64(result + mix2Accs(acc, 2 * i, key, keyOff + 16 * i));
2435
+ }
2436
+ return xxh3Avalanche(result);
2437
+ }
2438
+ function hashLong(input, length, secret, secretSize) {
2439
+ const nbRounds = Math.floor(
2440
+ (secretSize - STRIPE_LEN) / XXH_SECRET_CONSUME_RATE
2441
+ );
2442
+ const blockLen = STRIPE_LEN * nbRounds;
2443
+ const nbBlocks = Math.floor((length - 1) / blockLen);
2444
+ const nbStripes = Math.floor(
2445
+ (length - 1 - blockLen * nbBlocks) / STRIPE_LEN
2446
+ );
2447
+ const acc = [
2448
+ BigInt(PRIME32_3),
2449
+ PRIME64_1,
2450
+ PRIME64_2,
2451
+ PRIME64_3,
2452
+ PRIME64_4,
2453
+ BigInt(PRIME32_2),
2454
+ PRIME64_5,
2455
+ BigInt(PRIME32_1)
2456
+ ];
2457
+ for (let n = 0; n < nbBlocks; n++) {
2458
+ accumulateLoop(acc, input, n * blockLen, secret, 0, nbRounds);
2459
+ scrambleAcc(acc, secret, secretSize - STRIPE_LEN);
2460
+ }
2461
+ accumulateLoop(acc, input, nbBlocks * blockLen, secret, 0, nbStripes);
2462
+ accumulate512(
2463
+ acc,
2464
+ input,
2465
+ length - STRIPE_LEN,
2466
+ secret,
2467
+ secretSize - STRIPE_LEN - XXH_SECRET_LASTACC_START
2468
+ );
2469
+ return mergeAccs(
2470
+ acc,
2471
+ secret,
2472
+ XXH_SECRET_MERGEACCS_START,
2473
+ u64(BigInt(length) * PRIME64_1)
2474
+ );
2475
+ }
2476
+ function hashLongWithSeed(input, length, seed) {
2477
+ const secret = new Uint8Array(XXH_SECRET_DEFAULT_SIZE);
2478
+ for (let i = 0; i < XXH_SECRET_DEFAULT_SIZE / 16; i++) {
2479
+ const off = 16 * i;
2480
+ write64LE(secret, off, u64(read64LE(DEFAULT_SECRET, off) + seed));
2481
+ write64LE(
2482
+ secret,
2483
+ off + 8,
2484
+ u64(read64LE(DEFAULT_SECRET, off + 8) - seed)
2485
+ );
2486
+ }
2487
+ return hashLong(input, length, secret, secret.length);
2488
+ }
2489
+ var textEncoder2 = new TextEncoder();
2490
+ function xxh3_64(input, seed = 0n) {
2491
+ const len = input.length;
2492
+ if (len <= XXH3_MIDSIZE_MAX) {
2493
+ return hashShort(input, len, DEFAULT_SECRET, u64(seed));
2494
+ }
2495
+ return hashLongWithSeed(input, len, u64(seed));
2496
+ }
2497
+ function xxh3_64str(input, seed = 0n) {
2498
+ return xxh3_64(textEncoder2.encode(input), seed);
2499
+ }
2500
+ function computeMethodHash(methodName) {
2501
+ const utf8 = textEncoder2.encode(methodName);
2502
+ const prefixValue = Math.imul(67211, utf8.length) >>> 0;
2503
+ const prefixed = new Uint8Array(4 + utf8.length);
2504
+ prefixed[0] = prefixValue & 255;
2505
+ prefixed[1] = prefixValue >>> 8 & 255;
2506
+ prefixed[2] = prefixValue >>> 16 & 255;
2507
+ prefixed[3] = prefixValue >>> 24 & 255;
2508
+ prefixed.set(utf8, 4);
2509
+ const hash64 = xxh3_64(prefixed);
2510
+ return Number(hash64 & 0xffffffffn) | 0;
2511
+ }
2512
+
2513
+ // src/rpc-method-registry.ts
2514
+ var RpcMethodRegistry = class {
2515
+ _nameToHash = /* @__PURE__ */ new Map();
2516
+ _hashToName = /* @__PURE__ */ new Map();
2517
+ /** Register a method name and compute its hash. */
2518
+ register(methodName) {
2519
+ if (this._nameToHash.has(methodName)) return;
2520
+ const hash = computeMethodHash(methodName);
2521
+ const existing = this._hashToName.get(hash);
2522
+ if (existing !== void 0 && existing !== methodName) {
2523
+ console.warn(
2524
+ `[RpcMethodRegistry] hash collision: "${methodName}" and "${existing}" both hash to ${hash}`
2525
+ );
2526
+ return;
2527
+ }
2528
+ this._nameToHash.set(methodName, hash);
2529
+ this._hashToName.set(hash, methodName);
2530
+ }
2531
+ /** Register all wire method names from a service definition. */
2532
+ registerService(serviceName, methods) {
2533
+ for (const [, def] of methods) {
2534
+ const wireName = `${serviceName}.${def.name}:${def.wireArgCount}`;
2535
+ this.register(wireName);
2536
+ }
2537
+ }
2538
+ /** Get the hash for a method name. Computes on demand if not registered. */
2539
+ getHash(methodName) {
2540
+ let hash = this._nameToHash.get(methodName);
2541
+ if (hash === void 0) {
2542
+ this.register(methodName);
2543
+ hash = this._nameToHash.get(methodName);
2544
+ }
2545
+ return hash;
2546
+ }
2547
+ /** Get the method name for a hash. Returns undefined if not registered. */
2548
+ getName(hash) {
2549
+ return this._hashToName.get(hash);
2550
+ }
2551
+ /** Get the hash for a method name, throwing if not registered. */
2552
+ requireHash(methodName) {
2553
+ return this.getHash(methodName);
2554
+ }
2555
+ };
2556
+
1208
2557
  // src/rpc-hub.ts
1209
2558
  var RpcHub = class {
1210
2559
  hubId;
@@ -1212,9 +2561,16 @@ var RpcHub = class {
1212
2561
  serviceHost;
1213
2562
  systemCallSender = new RpcSystemCallSender();
1214
2563
  systemCallHandler = new RpcSystemCallHandler();
2564
+ /** Method registry for compact format hash ↔ name resolution.
2565
+ * Created lazily, populated by addService/addClient. */
2566
+ registry = new RpcMethodRegistry();
1215
2567
  constructor(hubId) {
1216
2568
  this.hubId = hubId ?? crypto.randomUUID();
1217
2569
  this.serviceHost = new RpcServiceHost();
2570
+ this.systemCallSender.registry = this.registry;
2571
+ for (const methodName of Object.values(RpcSystemCalls)) {
2572
+ this.registry.register(methodName);
2573
+ }
1218
2574
  }
1219
2575
  addPeer(peer) {
1220
2576
  this.peers.set(peer.ref, peer);
@@ -1252,10 +2608,12 @@ var RpcHub = class {
1252
2608
  wrappedImpl[methodDef.name] = methodDef.callTypeId !== 0 ? this._wrapServerMethod(methodDef, fn, impl) : fn;
1253
2609
  }
1254
2610
  this.serviceHost.register(def, wrappedImpl);
2611
+ this.registry.registerService(def.name, def.methods);
1255
2612
  }
1256
2613
  /** Create a typed client proxy for a service on a remote peer. */
1257
2614
  addClient(peer, defOrContract) {
1258
2615
  const def = this._resolveServiceDef(defOrContract);
2616
+ this.registry.registerService(def.name, def.methods);
1259
2617
  const overloads = /* @__PURE__ */ new Map();
1260
2618
  for (const methodDef of def.methods.values()) {
1261
2619
  let byArgCount = overloads.get(methodDef.name);
@@ -1263,7 +2621,10 @@ var RpcHub = class {
1263
2621
  byArgCount = /* @__PURE__ */ new Map();
1264
2622
  overloads.set(methodDef.name, byArgCount);
1265
2623
  }
1266
- byArgCount.set(methodDef.argCount, this._createClientMethod(peer, methodDef));
2624
+ byArgCount.set(
2625
+ methodDef.argCount,
2626
+ this._createClientMethod(peer, methodDef)
2627
+ );
1267
2628
  }
1268
2629
  const methods = /* @__PURE__ */ new Map();
1269
2630
  for (const [name, byArgCount] of overloads) {
@@ -1272,7 +2633,10 @@ var RpcHub = class {
1272
2633
  } else {
1273
2634
  methods.set(name, (...args) => {
1274
2635
  const fn = byArgCount.get(args.length);
1275
- if (!fn) throw new Error(`No overload of ${name} accepts ${args.length} arguments`);
2636
+ if (!fn)
2637
+ throw new Error(
2638
+ `No overload of ${name} accepts ${args.length} arguments`
2639
+ );
1276
2640
  return fn(...args);
1277
2641
  });
1278
2642
  }
@@ -1288,7 +2652,8 @@ var RpcHub = class {
1288
2652
  /** Build an RpcServiceDef from decorator metadata on a contract class. Override in FusionHub for compute support. */
1289
2653
  _buildServiceDef(cls) {
1290
2654
  const svcMeta = getServiceMeta(cls);
1291
- if (svcMeta === void 0) throw new Error("Contract class missing @rpcService metadata");
2655
+ if (svcMeta === void 0)
2656
+ throw new Error("Contract class missing @rpcService metadata");
1292
2657
  const methodsMeta = getMethodsMeta(cls) ?? {};
1293
2658
  const methods = /* @__PURE__ */ new Map();
1294
2659
  for (const [name, meta] of Object.entries(methodsMeta)) {
@@ -1331,7 +2696,10 @@ var RpcHub = class {
1331
2696
  const outboundCall = peer.call(wireName, callArgs);
1332
2697
  const result = await outboundCall.result.promise;
1333
2698
  const ref = parseStreamRef(result);
1334
- if (!ref) throw new Error(`Expected stream reference, got: ${JSON.stringify(result)}`);
2699
+ if (!ref)
2700
+ throw new Error(
2701
+ `Expected stream reference, got: ${JSON.stringify(result)}`
2702
+ );
1335
2703
  const stream = new RpcStream(ref, peer);
1336
2704
  peer.remoteObjects.register(stream);
1337
2705
  return stream;
@@ -1370,7 +2738,10 @@ function createRpcClient(peer, serviceDef) {
1370
2738
  }
1371
2739
  methods.set(name, (...args) => {
1372
2740
  const fn = fns.get(args.length);
1373
- if (!fn) throw new Error(`No overload of ${name} accepts ${args.length} arguments`);
2741
+ if (!fn)
2742
+ throw new Error(
2743
+ `No overload of ${name} accepts ${args.length} arguments`
2744
+ );
1374
2745
  return fn(...args);
1375
2746
  });
1376
2747
  }
@@ -1415,12 +2786,10 @@ function getStateDescription(state, useLastError = false) {
1415
2786
  case 1 /* JustDisconnected */:
1416
2787
  return "Just disconnected, reconnecting...";
1417
2788
  case 2 /* Disconnected */:
1418
- if (state.reconnectsIn > 0)
1419
- break;
2789
+ if (state.reconnectsIn > 0) break;
1420
2790
  return "Reconnecting...";
1421
2791
  }
1422
- if (state.lastError == null || !useLastError)
1423
- return "Disconnected.";
2792
+ if (state.lastError == null || !useLastError) return "Disconnected.";
1424
2793
  let message = state.lastError.message.trim();
1425
2794
  if (!(message.endsWith(".") || message.endsWith("!") || message.endsWith("?")))
1426
2795
  message += ".";
@@ -1451,7 +2820,9 @@ var RpcPeerStateMonitor = class {
1451
2820
  _onDisconnected = (ev) => {
1452
2821
  const wasConnected = this._rawConnected;
1453
2822
  this._rawConnected = false;
1454
- this._lastError = new Error(`Connection closed: ${ev.reason} (code ${ev.code})`);
2823
+ this._lastError = new Error(
2824
+ `Connection closed: ${ev.reason} (code ${ev.code})`
2825
+ );
1455
2826
  if (wasConnected) {
1456
2827
  this._disconnectedAt = Date.now();
1457
2828
  }
@@ -1468,16 +2839,26 @@ var RpcPeerStateMonitor = class {
1468
2839
  this._rawConnected = peer.isConnected;
1469
2840
  if (this._rawConnected) {
1470
2841
  this._connectedAt = Date.now();
1471
- this._state = { kind: 3 /* JustConnected */, reconnectsIn: 0 };
2842
+ this._state = {
2843
+ kind: 3 /* JustConnected */,
2844
+ reconnectsIn: 0
2845
+ };
1472
2846
  } else {
1473
2847
  this._disconnectedAt = Date.now();
1474
- this._state = { kind: 1 /* JustDisconnected */, reconnectsIn: 0 };
2848
+ this._state = {
2849
+ kind: 1 /* JustDisconnected */,
2850
+ reconnectsIn: 0
2851
+ };
1475
2852
  }
1476
2853
  peer.connected.add(this._onConnected);
1477
2854
  peer.disconnected.add(this._onDisconnected);
1478
2855
  peer.reconnectsAtChanged.add(this._onReconnectsAtChanged);
1479
- peer.reconnectDelayer.cancelDelaysChanged.add(this._onCancelDelaysChanged);
1480
- this._scheduleRecompute(this._rawConnected ? JustConnectedPeriodMs : JustDisconnectedPeriodMs);
2856
+ peer.reconnectDelayer.cancelDelaysChanged.add(
2857
+ this._onCancelDelaysChanged
2858
+ );
2859
+ this._scheduleRecompute(
2860
+ this._rawConnected ? JustConnectedPeriodMs : JustDisconnectedPeriodMs
2861
+ );
1481
2862
  }
1482
2863
  get state() {
1483
2864
  return this._state;
@@ -1490,7 +2871,9 @@ var RpcPeerStateMonitor = class {
1490
2871
  this.peer.connected.remove(this._onConnected);
1491
2872
  this.peer.disconnected.remove(this._onDisconnected);
1492
2873
  this.peer.reconnectsAtChanged.remove(this._onReconnectsAtChanged);
1493
- this.peer.reconnectDelayer.cancelDelaysChanged.remove(this._onCancelDelaysChanged);
2874
+ this.peer.reconnectDelayer.cancelDelaysChanged.remove(
2875
+ this._onCancelDelaysChanged
2876
+ );
1494
2877
  }
1495
2878
  _recompute() {
1496
2879
  if (this._timer !== void 0) {
@@ -1502,24 +2885,46 @@ var RpcPeerStateMonitor = class {
1502
2885
  if (this._rawConnected) {
1503
2886
  const connectedFor = now - this._connectedAt;
1504
2887
  if (connectedFor < JustConnectedPeriodMs) {
1505
- newState = { kind: 3 /* JustConnected */, reconnectsIn: 0 };
2888
+ newState = {
2889
+ kind: 3 /* JustConnected */,
2890
+ reconnectsIn: 0
2891
+ };
1506
2892
  this._scheduleRecompute(JustConnectedPeriodMs - connectedFor);
1507
2893
  } else {
1508
- newState = { kind: 0 /* Connected */, reconnectsIn: 0 };
2894
+ newState = {
2895
+ kind: 0 /* Connected */,
2896
+ reconnectsIn: 0
2897
+ };
1509
2898
  }
1510
2899
  } else {
1511
2900
  const disconnectedFor = now - this._disconnectedAt;
1512
2901
  if (disconnectedFor < JustDisconnectedPeriodMs) {
1513
- newState = { kind: 1 /* JustDisconnected */, lastError: this._lastError, reconnectsIn: 0 };
1514
- this._scheduleRecompute(JustDisconnectedPeriodMs - disconnectedFor);
2902
+ newState = {
2903
+ kind: 1 /* JustDisconnected */,
2904
+ lastError: this._lastError,
2905
+ reconnectsIn: 0
2906
+ };
2907
+ this._scheduleRecompute(
2908
+ JustDisconnectedPeriodMs - disconnectedFor
2909
+ );
1515
2910
  } else {
1516
2911
  const reconnectsAt = this.peer.reconnectsAt;
1517
2912
  const reconnectsIn = reconnectsAt > 0 ? Math.max(0, reconnectsAt - now) : 0;
1518
2913
  if (reconnectsIn < MinReconnectsInMs) {
1519
- newState = { kind: 2 /* Disconnected */, lastError: this._lastError, reconnectsIn: 0 };
2914
+ newState = {
2915
+ kind: 2 /* Disconnected */,
2916
+ lastError: this._lastError,
2917
+ reconnectsIn: 0
2918
+ };
1520
2919
  } else {
1521
- newState = { kind: 2 /* Disconnected */, lastError: this._lastError, reconnectsIn };
1522
- this._scheduleRecompute(Math.min(1e3, reconnectsIn - MinReconnectsInMs));
2920
+ newState = {
2921
+ kind: 2 /* Disconnected */,
2922
+ lastError: this._lastError,
2923
+ reconnectsIn
2924
+ };
2925
+ this._scheduleRecompute(
2926
+ Math.min(1e3, reconnectsIn - MinReconnectsInMs)
2927
+ );
1523
2928
  }
1524
2929
  }
1525
2930
  }
@@ -1534,15 +2939,17 @@ var RpcPeerStateMonitor = class {
1534
2939
  }
1535
2940
  _scheduleRecompute(delayMs) {
1536
2941
  if (this._timer !== void 0) clearTimeout(this._timer);
1537
- this._timer = setTimeout(() => {
1538
- this._timer = void 0;
1539
- this._recompute();
1540
- }, Math.max(0, delayMs));
2942
+ this._timer = setTimeout(
2943
+ () => {
2944
+ this._timer = void 0;
2945
+ this._recompute();
2946
+ },
2947
+ Math.max(0, delayMs)
2948
+ );
1541
2949
  }
1542
2950
  };
1543
2951
  export {
1544
2952
  ARG_DELIMITER,
1545
- DEFAULT_SERIALIZATION_FORMAT,
1546
2953
  ENVELOPE_DELIMITER,
1547
2954
  FRAME_DELIMITER,
1548
2955
  RPC_CLOSE_CODE_UNSUPPORTED_FORMAT,
@@ -1552,7 +2959,11 @@ export {
1552
2959
  RpcHub,
1553
2960
  RpcInboundCall,
1554
2961
  RpcInboundCallTracker,
2962
+ RpcJsonSerializationFormat,
1555
2963
  RpcMessageChannelConnection,
2964
+ RpcMessagePackCompactSerializationFormat,
2965
+ RpcMessagePackSerializationFormat,
2966
+ RpcMethodRegistry,
1556
2967
  RpcObjectKind,
1557
2968
  RpcOutboundCall,
1558
2969
  RpcOutboundCallTracker,
@@ -1561,6 +2972,8 @@ export {
1561
2972
  RpcPeerStateKind,
1562
2973
  RpcPeerStateMonitor,
1563
2974
  RpcRemoteObjectTracker,
2975
+ RpcSerializationFormat,
2976
+ RpcSerializationFormatResolver,
1564
2977
  RpcServerPeer,
1565
2978
  RpcServiceHost,
1566
2979
  RpcSharedObjectTracker,
@@ -1572,10 +2985,16 @@ export {
1572
2985
  RpcType,
1573
2986
  RpcWebSocketConnection,
1574
2987
  WebSocketState,
2988
+ computeMethodHash,
2989
+ createBinaryEncoder,
1575
2990
  createMessageChannelPair,
1576
2991
  createRpcClient,
2992
+ defaultBinaryDecoder,
2993
+ defaultBinaryEncoder,
1577
2994
  defaultConnectionUrlResolver,
1578
2995
  defineRpcService,
2996
+ deserializeBinaryMessage,
2997
+ deserializeCompactBinaryMessage,
1579
2998
  deserializeMessage,
1580
2999
  getMethodsMeta,
1581
3000
  getServiceMeta,
@@ -1586,9 +3005,16 @@ export {
1586
3005
  resolveStreamRefs,
1587
3006
  rpcMethod,
1588
3007
  rpcService,
3008
+ serializeBinaryFrame,
3009
+ serializeBinaryMessage,
3010
+ serializeCompactBinaryMessage,
1589
3011
  serializeFrame,
1590
3012
  serializeMessage,
3013
+ splitBinaryFrame,
3014
+ splitCompactBinaryFrame,
1591
3015
  splitFrame,
1592
- wireMethodName
3016
+ wireMethodName,
3017
+ xxh3_64,
3018
+ xxh3_64str
1593
3019
  };
1594
3020
  //# sourceMappingURL=index.js.map