@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.cjs +1625 -174
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +365 -31
- package/dist/index.d.ts +365 -31
- package/dist/index.js +1598 -172
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
|
457
|
+
const buffer = this._sendBuffer;
|
|
124
458
|
this._sendBuffer = [];
|
|
125
459
|
try {
|
|
126
|
-
this._ws.send(
|
|
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)
|
|
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
|
|
214
|
-
|
|
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
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
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
|
-
|
|
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)
|
|
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 (
|
|
413
|
-
const value = self._buffer
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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)
|
|
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++)
|
|
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
|
-
|
|
570
|
-
|
|
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.
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
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
|
-
|
|
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
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
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
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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 } :
|
|
696
|
-
this.peer.hub.systemCallSender.end(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
846
|
-
|
|
847
|
-
|
|
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.
|
|
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(
|
|
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(
|
|
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
|
|
884
|
-
this.
|
|
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)
|
|
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.
|
|
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(
|
|
914
|
-
|
|
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 ? {
|
|
942
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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.
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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), {
|
|
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)
|
|
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(
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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(
|
|
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 = {
|
|
2842
|
+
this._state = {
|
|
2843
|
+
kind: 3 /* JustConnected */,
|
|
2844
|
+
reconnectsIn: 0
|
|
2845
|
+
};
|
|
1472
2846
|
} else {
|
|
1473
2847
|
this._disconnectedAt = Date.now();
|
|
1474
|
-
this._state = {
|
|
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(
|
|
1480
|
-
|
|
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(
|
|
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 = {
|
|
2888
|
+
newState = {
|
|
2889
|
+
kind: 3 /* JustConnected */,
|
|
2890
|
+
reconnectsIn: 0
|
|
2891
|
+
};
|
|
1506
2892
|
this._scheduleRecompute(JustConnectedPeriodMs - connectedFor);
|
|
1507
2893
|
} else {
|
|
1508
|
-
newState = {
|
|
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 = {
|
|
1514
|
-
|
|
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 = {
|
|
2914
|
+
newState = {
|
|
2915
|
+
kind: 2 /* Disconnected */,
|
|
2916
|
+
lastError: this._lastError,
|
|
2917
|
+
reconnectsIn: 0
|
|
2918
|
+
};
|
|
1520
2919
|
} else {
|
|
1521
|
-
newState = {
|
|
1522
|
-
|
|
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
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
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
|