statewire 0.16.0 → 0.17.1
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/README.md +12 -4
- package/dist/client/connection.d.ts +5 -1
- package/dist/client/connection.d.ts.map +1 -1
- package/dist/client/connection.js +22 -6
- package/dist/client/connection.js.map +1 -1
- package/dist/client/core.d.ts.map +1 -1
- package/dist/client/core.js +2 -0
- package/dist/client/core.js.map +1 -1
- package/dist/client/session.d.ts +15 -4
- package/dist/client/session.d.ts.map +1 -1
- package/dist/client/session.js +235 -52
- package/dist/client/session.js.map +1 -1
- package/dist/client/sessionStore.d.ts +5 -1
- package/dist/client/sessionStore.d.ts.map +1 -1
- package/dist/client/sessionStore.js +3 -1
- package/dist/client/sessionStore.js.map +1 -1
- package/dist/document.d.ts +25 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +88 -0
- package/dist/document.js.map +1 -0
- package/dist/host/draft.js +1 -1
- package/dist/host/host.d.ts +1 -0
- package/dist/host/host.d.ts.map +1 -1
- package/dist/host/host.js.map +1 -1
- package/dist/host/http.d.ts.map +1 -1
- package/dist/host/http.js +27 -9
- package/dist/host/http.js.map +1 -1
- package/dist/host/socket.d.ts +12 -5
- package/dist/host/socket.d.ts.map +1 -1
- package/dist/host/socket.js +107 -43
- package/dist/host/socket.js.map +1 -1
- package/dist/host-internal.d.ts +9 -1
- package/dist/host-internal.d.ts.map +1 -1
- package/dist/host-internal.js +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +2 -1
- package/dist/statewire.d.ts +33 -2
- package/dist/statewire.d.ts.map +1 -1
- package/dist/statewire.js +34 -3
- package/dist/statewire.js.map +1 -1
- package/dist/transports/fixtures.js +1 -0
- package/dist/transports/fixtures.js.map +1 -1
- package/dist/transports/remote.d.ts.map +1 -1
- package/dist/transports/remote.js +15 -8
- package/dist/transports/remote.js.map +1 -1
- package/dist/transports/sse.d.ts.map +1 -1
- package/dist/transports/sse.js +8 -8
- package/dist/transports/sse.js.map +1 -1
- package/dist/transports/testing.d.ts +1 -1
- package/dist/transports/testing.d.ts.map +1 -1
- package/dist/transports/testing.js +12 -4
- package/dist/transports/testing.js.map +1 -1
- package/dist/transports/ws.js +2 -2
- package/dist/transports/ws.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/wire/documents.d.ts +25 -2
- package/dist/wire/documents.d.ts.map +1 -1
- package/dist/wire/documents.js +28 -8
- package/dist/wire/documents.js.map +1 -1
- package/dist/wire/meta.d.ts +3 -18
- package/dist/wire/meta.d.ts.map +1 -1
- package/dist/wire/meta.js +8 -57
- package/dist/wire/meta.js.map +1 -1
- package/dist/wire/ops.js +1 -1
- package/dist/wire/protocol.d.ts +55 -0
- package/dist/wire/protocol.d.ts.map +1 -0
- package/dist/wire/protocol.js +221 -0
- package/dist/wire/protocol.js.map +1 -0
- package/dist/wire/version.d.ts +1 -3
- package/dist/wire/version.d.ts.map +1 -1
- package/dist/wire/version.js +1 -3
- package/dist/wire/version.js.map +1 -1
- package/package.json +1 -1
- package/src/client/connection.ts +43 -13
- package/src/client/core.ts +6 -0
- package/src/client/session.ts +340 -45
- package/src/client/sessionStore.ts +8 -0
- package/src/document.ts +185 -0
- package/src/host/host.ts +1 -0
- package/src/host/http.ts +36 -7
- package/src/host/socket.ts +149 -57
- package/src/host-internal.ts +12 -1
- package/src/index.ts +5 -0
- package/src/statewire.ts +109 -6
- package/src/transports/fixtures.ts +1 -1
- package/src/transports/remote.ts +16 -7
- package/src/transports/sse.ts +18 -8
- package/src/transports/testing.ts +10 -2
- package/src/transports/ws.ts +1 -1
- package/src/types.ts +11 -0
- package/src/wire/documents.ts +126 -8
- package/src/wire/meta.ts +11 -94
- package/src/wire/protocol.ts +327 -0
- package/src/wire/version.ts +0 -2
package/dist/host/socket.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { encodeDocument, reviveDocumentValue } from "../document.js";
|
|
2
|
+
import { DEFAULT_PROTOCOL, WIRE_VERSION, negotiateProtocols } from "../wire/protocol.js";
|
|
3
|
+
import { applyDocumentOps, mainDocument } from "../wire/documents.js";
|
|
1
4
|
import { StatewireSendError } from "../types.js";
|
|
2
5
|
import { getCommandsHost, getStateHost } from "./host.js";
|
|
3
|
-
import { encodeValue, reviveValue } from "../wire/meta.js";
|
|
4
6
|
import { COMMAND_CAPACITY_RETRY_MS, MAX_INFLIGHT_COMMANDS_PER_HOST } from "../wire/limits.js";
|
|
5
7
|
import { createMacrotaskPoster } from "../util/macrotask.js";
|
|
6
8
|
import { frames, stream } from "./http.js";
|
|
@@ -49,15 +51,6 @@ const parseLane = (value) => {
|
|
|
49
51
|
return statements;
|
|
50
52
|
};
|
|
51
53
|
const frameEncoder = new TextEncoder();
|
|
52
|
-
/** v1 ctx statements state the context whole: one root replace with an object value. */
|
|
53
|
-
const contextValue = (ops) => {
|
|
54
|
-
if (!Array.isArray(ops) || ops.length !== 1) throw new Error("context must be a single-op array");
|
|
55
|
-
const op = ops[0];
|
|
56
|
-
if (!isPlainObject(op) || op["op"] !== "replace" || !Array.isArray(op["path"]) || op["path"].length !== 0) throw new Error("context op must be a root replace");
|
|
57
|
-
const value = op["meta"] !== void 0 ? reviveValue(op["value"], op["meta"], { rejectUnknown: true }) : op["value"];
|
|
58
|
-
if (!isPlainObject(value)) throw new Error("context value must be an object");
|
|
59
|
-
return value;
|
|
60
|
-
};
|
|
61
54
|
const parseFrameValue = (frame) => {
|
|
62
55
|
if (!isPlainObject(frame)) return violation("malformed frame");
|
|
63
56
|
const keys = Object.keys(frame);
|
|
@@ -69,16 +62,12 @@ const parseFrameValue = (frame) => {
|
|
|
69
62
|
const lane = frame["ctx"];
|
|
70
63
|
if (Array.isArray(lane) && lane.length > 256) return violation("too many context statements");
|
|
71
64
|
for (const statement of parseLane(lane)) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
} catch {
|
|
76
|
-
return violation("invalid-context");
|
|
77
|
-
}
|
|
78
|
-
if (frameEncoder.encode(JSON.stringify(value)).byteLength > 65536) return violation("oversized-context");
|
|
65
|
+
const ops = statement["ops"];
|
|
66
|
+
if (!Array.isArray(ops) || !ops.length) return violation("invalid-context");
|
|
67
|
+
if (frameEncoder.encode(JSON.stringify(ops)).byteLength > 65536) return violation("oversized-context");
|
|
79
68
|
ctx.push({
|
|
80
69
|
seq: statement["seq"],
|
|
81
|
-
|
|
70
|
+
ops
|
|
82
71
|
});
|
|
83
72
|
}
|
|
84
73
|
}
|
|
@@ -88,8 +77,9 @@ const parseFrameValue = (frame) => {
|
|
|
88
77
|
if (Array.isArray(lane) && lane.length > 256) return violation("too many commands");
|
|
89
78
|
for (const statement of parseLane(lane)) {
|
|
90
79
|
const method = statement["method"];
|
|
91
|
-
if (typeof method !== "string" || !("params" in statement)) return violation("malformed statement");
|
|
80
|
+
if (typeof method !== "string" || typeof statement["protocol"] !== "string" || !("params" in statement)) return violation("malformed statement");
|
|
92
81
|
cmd.push({
|
|
82
|
+
protocol: statement["protocol"],
|
|
93
83
|
seq: statement["seq"],
|
|
94
84
|
method,
|
|
95
85
|
params: statement["params"],
|
|
@@ -114,7 +104,7 @@ const parseFrame = (raw) => {
|
|
|
114
104
|
const frameIsOversized = (raw) => raw.length > 8388608 || frameEncoder.encode(raw).byteLength > 8388608;
|
|
115
105
|
const encodePayload = (payload) => {
|
|
116
106
|
if (payload === void 0) return {};
|
|
117
|
-
const { value, meta } =
|
|
107
|
+
const { value, meta } = encodeDocument(payload);
|
|
118
108
|
return {
|
|
119
109
|
payload: value,
|
|
120
110
|
...meta !== void 0 && { meta }
|
|
@@ -186,7 +176,7 @@ const scheduleFlush = (h) => {
|
|
|
186
176
|
};
|
|
187
177
|
const recordOp = (h, op) => {
|
|
188
178
|
if (op.op === "replace" || op.op === "add") {
|
|
189
|
-
const { value, meta } =
|
|
179
|
+
const { value, meta } = encodeDocument(op.value);
|
|
190
180
|
h.pendingOps.push({
|
|
191
181
|
...op,
|
|
192
182
|
value,
|
|
@@ -277,13 +267,16 @@ const flush = (h, fin) => {
|
|
|
277
267
|
}));
|
|
278
268
|
if (ops.length > 0) {
|
|
279
269
|
const packet = {
|
|
280
|
-
ops,
|
|
270
|
+
ops: conn.selection.protocols.some((p) => p.name === h.protocol.name) ? ops : [],
|
|
281
271
|
...appliedEntries.length > 0 && { cmd: appliedEntries },
|
|
282
272
|
...edge && { idle: level }
|
|
283
273
|
};
|
|
284
274
|
sendTo(h, conn, JSON.stringify(packet));
|
|
285
275
|
} else if (appliedEntries.length > 0) sendTo(h, conn, JSON.stringify({ cmd: appliedEntries }));
|
|
286
|
-
const verdicts = cmds.get(conn.clientId) ?? []
|
|
276
|
+
const verdicts = (cmds.get(conn.clientId) ?? []).map((cmd) => conn.selection.protocols.some((p) => p.name === h.protocol.name) ? cmd : {
|
|
277
|
+
seq: cmd.seq,
|
|
278
|
+
...cmd.dur === void 0 ? {} : { dur: cmd.dur }
|
|
279
|
+
});
|
|
287
280
|
if (verdicts.length > 0) sendTo(h, conn, JSON.stringify({ cmd: verdicts }));
|
|
288
281
|
if (edge && ops.length === 0) sendTo(h, conn, JSON.stringify({ idle: level }));
|
|
289
282
|
if (fin !== void 0) {
|
|
@@ -311,6 +304,7 @@ const notifyClientRecords = (h) => {
|
|
|
311
304
|
ctxSeq: rec.ctxSeq,
|
|
312
305
|
touched: rec.touched,
|
|
313
306
|
context: rec.context,
|
|
307
|
+
contextDocuments: [...rec.contextDocuments.documents],
|
|
314
308
|
results: [...rec.results].map(([seq, entry]) => ({
|
|
315
309
|
seq,
|
|
316
310
|
ts: entry.ts,
|
|
@@ -380,7 +374,7 @@ const rejectStatement = (h, rec, adm, message) => settleCmd(h, rec, adm, {
|
|
|
380
374
|
code: "invalid-params",
|
|
381
375
|
message
|
|
382
376
|
});
|
|
383
|
-
const admitCmd = (h, rec, statement, auth) => {
|
|
377
|
+
const admitCmd = (h, rec, statement, auth, selection) => {
|
|
384
378
|
const adm = {
|
|
385
379
|
seq: statement.seq,
|
|
386
380
|
method: statement.method,
|
|
@@ -390,13 +384,22 @@ const admitCmd = (h, rec, statement, auth) => {
|
|
|
390
384
|
};
|
|
391
385
|
rec.inflight.set(statement.seq, adm);
|
|
392
386
|
notifyClientRecords(h);
|
|
387
|
+
if (statement.protocol !== h.protocol.name || !selection.protocols.some((p) => p.name === statement.protocol)) {
|
|
388
|
+
settleCmd(h, rec, adm, {
|
|
389
|
+
seq: adm.seq,
|
|
390
|
+
type: "rejected",
|
|
391
|
+
code: "unsupported-protocol",
|
|
392
|
+
message: "command protocol was not negotiated"
|
|
393
|
+
});
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
393
396
|
if (!Array.isArray(statement.params)) {
|
|
394
397
|
rejectStatement(h, rec, adm, "params must be an array");
|
|
395
398
|
return;
|
|
396
399
|
}
|
|
397
400
|
let params = statement.params;
|
|
398
401
|
if (statement.meta !== void 0) try {
|
|
399
|
-
params =
|
|
402
|
+
params = reviveDocumentValue(params, statement.meta, { rejectUnknown: true });
|
|
400
403
|
} catch (error) {
|
|
401
404
|
rejectStatement(h, rec, adm, `invalid params: ${error.message}`);
|
|
402
405
|
return;
|
|
@@ -434,7 +437,13 @@ const admitCmd = (h, rec, statement, auth) => {
|
|
|
434
437
|
});
|
|
435
438
|
});
|
|
436
439
|
};
|
|
437
|
-
const admitFrame = (h, rec, frame, auth
|
|
440
|
+
const admitFrame = (h, rec, frame, auth, selection = {
|
|
441
|
+
version: h.wireVersion.version,
|
|
442
|
+
protocols: [{
|
|
443
|
+
name: h.protocol.name,
|
|
444
|
+
version: h.protocol.version
|
|
445
|
+
}]
|
|
446
|
+
}) => {
|
|
438
447
|
rec.touched = Date.now();
|
|
439
448
|
const through = admittedThrough(rec);
|
|
440
449
|
for (const statement of frame.cmd) if (statement.seq <= through) reemit(h, rec, statement.seq);
|
|
@@ -476,11 +485,17 @@ const admitFrame = (h, rec, frame, auth) => {
|
|
|
476
485
|
};
|
|
477
486
|
}
|
|
478
487
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
488
|
+
let contextDocuments = rec.contextDocuments;
|
|
489
|
+
try {
|
|
490
|
+
for (const statement of ctxNew) contextDocuments = applyDocumentOps(contextDocuments, statement.ops, selection.protocols, true);
|
|
491
|
+
if (frameEncoder.encode(JSON.stringify([...contextDocuments.documents])).byteLength > 65536) return violation("oversized-context");
|
|
492
|
+
} catch {
|
|
493
|
+
return violation("invalid-context");
|
|
482
494
|
}
|
|
483
|
-
|
|
495
|
+
rec.contextDocuments = contextDocuments;
|
|
496
|
+
rec.context = mainDocument(contextDocuments, h.protocol.name)?.value ?? null;
|
|
497
|
+
if (ctxNew.length) rec.ctxSeq = ctxNew.at(-1).seq;
|
|
498
|
+
for (const statement of cmdNew) admitCmd(h, rec, statement, auth, selection);
|
|
484
499
|
if (cmdNew.length > 0) queueCmd(h, rec.id, {
|
|
485
500
|
seq: cmdNew.at(-1).seq,
|
|
486
501
|
dur: true
|
|
@@ -516,7 +531,19 @@ const message = (h, conn, data) => {
|
|
|
516
531
|
}
|
|
517
532
|
if (frame.ctx.length === 0 && frame.cmd.length === 0) return;
|
|
518
533
|
const rec = h.clients.get(conn.clientId);
|
|
519
|
-
|
|
534
|
+
let admission;
|
|
535
|
+
try {
|
|
536
|
+
admission = admitFrame(h, rec, frame, conn.auth, conn.selection);
|
|
537
|
+
} catch (error) {
|
|
538
|
+
const reason = violationReason(error);
|
|
539
|
+
if (reason === null) throw error;
|
|
540
|
+
sendTo(h, conn, JSON.stringify({ fin: {
|
|
541
|
+
reason: "protocol-error",
|
|
542
|
+
message: reason
|
|
543
|
+
} }));
|
|
544
|
+
closeConn(h, conn, 1008, reason);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
520
547
|
if (admission.type === "refused") sendTo(h, conn, JSON.stringify(admission.syn));
|
|
521
548
|
};
|
|
522
549
|
const closePending = (h, pending, code, reason) => {
|
|
@@ -573,7 +600,7 @@ const normalizedHeaders = (headers) => {
|
|
|
573
600
|
};
|
|
574
601
|
const connectAuthorized = (h, clientId, socket, options) => {
|
|
575
602
|
const authorize = h.authorize;
|
|
576
|
-
if (options.authorized === true) return register(h, clientId, socket, options.authorized === true, options.auth)?.connection ?? null;
|
|
603
|
+
if (options.authorized === true) return register(h, clientId, socket, options.authorized === true, options.auth, options.selection)?.connection ?? null;
|
|
577
604
|
const refuse = (code, reason) => {
|
|
578
605
|
try {
|
|
579
606
|
socket.close(code, reason);
|
|
@@ -640,7 +667,10 @@ const connectAuthorized = (h, clientId, socket, options) => {
|
|
|
640
667
|
const frame = initial.frame;
|
|
641
668
|
let headers;
|
|
642
669
|
try {
|
|
643
|
-
headers =
|
|
670
|
+
headers = {
|
|
671
|
+
...normalizedHeaders(initial.headers),
|
|
672
|
+
...normalizedHeaders(options.headers ?? {})
|
|
673
|
+
};
|
|
644
674
|
} catch {
|
|
645
675
|
sendPending(pending, JSON.stringify({ fin: {
|
|
646
676
|
reason: "protocol-error",
|
|
@@ -661,17 +691,23 @@ const connectAuthorized = (h, clientId, socket, options) => {
|
|
|
661
691
|
pending.authorizing = true;
|
|
662
692
|
Promise.resolve().then(() => authorize?.({ headers })).then((auth) => {
|
|
663
693
|
if (!pending.open || h.disposed || h.finished !== null) return;
|
|
664
|
-
|
|
694
|
+
const selection = negotiateProtocols(new Headers(headers), h.wireVersion, [h.protocol]);
|
|
695
|
+
if ("fin" in selection) {
|
|
696
|
+
sendPending(pending, JSON.stringify(selection));
|
|
697
|
+
closePending(h, pending, 1008, selection.fin.message);
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
options.onAuthorized?.(auth, selection);
|
|
665
701
|
pending.open = false;
|
|
666
702
|
h.pendingConns.delete(pending);
|
|
667
703
|
if (pending.timer !== null) clearTimeout(pending.timer);
|
|
668
|
-
const registration = register(h, clientId, socket, true, auth);
|
|
704
|
+
const registration = register(h, clientId, socket, true, auth, selection);
|
|
669
705
|
if (registration === null) return;
|
|
670
706
|
pending.connection = registration.connection;
|
|
671
|
-
if (frame.ctx.length || frame.cmd.length) {
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
}
|
|
707
|
+
if (frame.ctx.length || frame.cmd.length) message(h, registration.conn, JSON.stringify({
|
|
708
|
+
...frame.ctx.length ? { ctx: frame.ctx } : {},
|
|
709
|
+
...frame.cmd.length ? { cmd: frame.cmd } : {}
|
|
710
|
+
}));
|
|
675
711
|
for (const data of pending.queued.splice(0)) registration.connection.message(data);
|
|
676
712
|
}).catch((error) => {
|
|
677
713
|
if (pending.open) rejectPendingAuthorization(h, pending, error);
|
|
@@ -698,7 +734,13 @@ const gcClients = (h) => {
|
|
|
698
734
|
}
|
|
699
735
|
if (changed) notifyClientRecords(h);
|
|
700
736
|
};
|
|
701
|
-
const register = (h, clientId, socket, sawFrame = false, auth = void 0
|
|
737
|
+
const register = (h, clientId, socket, sawFrame = false, auth = void 0, selection = {
|
|
738
|
+
version: h.wireVersion.version,
|
|
739
|
+
protocols: [{
|
|
740
|
+
name: h.protocol.name,
|
|
741
|
+
version: h.protocol.version
|
|
742
|
+
}]
|
|
743
|
+
}) => {
|
|
702
744
|
const refuse = (code, reason) => {
|
|
703
745
|
try {
|
|
704
746
|
socket.close(code, reason);
|
|
@@ -734,6 +776,10 @@ const register = (h, clientId, socket, sawFrame = false, auth = void 0) => {
|
|
|
734
776
|
ctxSeq: 0,
|
|
735
777
|
touched: Date.now(),
|
|
736
778
|
context: null,
|
|
779
|
+
contextDocuments: {
|
|
780
|
+
mode: "mounted",
|
|
781
|
+
documents: /* @__PURE__ */ new Map()
|
|
782
|
+
},
|
|
737
783
|
results: /* @__PURE__ */ new Map(),
|
|
738
784
|
inflight: /* @__PURE__ */ new Map(),
|
|
739
785
|
principal: auth
|
|
@@ -743,6 +789,7 @@ const register = (h, clientId, socket, sawFrame = false, auth = void 0) => {
|
|
|
743
789
|
})();
|
|
744
790
|
rec.touched = Date.now();
|
|
745
791
|
const conn = {
|
|
792
|
+
selection,
|
|
746
793
|
clientId,
|
|
747
794
|
socket,
|
|
748
795
|
open: true,
|
|
@@ -755,20 +802,23 @@ const register = (h, clientId, socket, sawFrame = false, auth = void 0) => {
|
|
|
755
802
|
gcClients(h);
|
|
756
803
|
notifyClientRecords(h);
|
|
757
804
|
ensureHeartbeat(h);
|
|
758
|
-
const { value, meta } =
|
|
805
|
+
const { value, meta } = encodeDocument(h.stateHost.snapshot());
|
|
759
806
|
const hello = {
|
|
760
807
|
ops: [{
|
|
761
|
-
op: "
|
|
762
|
-
|
|
808
|
+
op: "mount",
|
|
809
|
+
protocol: h.protocol.name,
|
|
810
|
+
main: true,
|
|
763
811
|
value,
|
|
764
812
|
...meta !== void 0 && { meta }
|
|
765
813
|
}],
|
|
766
814
|
syn: {
|
|
815
|
+
...selection,
|
|
767
816
|
seq: admittedThrough(rec),
|
|
768
817
|
ctxSeq: rec.ctxSeq,
|
|
769
818
|
...h.idleWire && { idle: true }
|
|
770
819
|
}
|
|
771
820
|
};
|
|
821
|
+
if (!selection.protocols.some((p) => p.name === h.protocol.name)) hello.ops = [];
|
|
772
822
|
sendTo(h, conn, JSON.stringify(hello));
|
|
773
823
|
return {
|
|
774
824
|
rec,
|
|
@@ -808,6 +858,10 @@ const suspend = (h) => {
|
|
|
808
858
|
};
|
|
809
859
|
const restoreClientRecords = (records = []) => new Map(records.map((record) => [record.id, {
|
|
810
860
|
...record,
|
|
861
|
+
contextDocuments: {
|
|
862
|
+
mode: "mounted",
|
|
863
|
+
documents: new Map(record.contextDocuments ?? [])
|
|
864
|
+
},
|
|
811
865
|
results: new Map(record.results.map(({ seq, ts, cmd }) => [seq, {
|
|
812
866
|
ts,
|
|
813
867
|
cmd
|
|
@@ -817,6 +871,11 @@ const restoreClientRecords = (records = []) => new Map(records.map((record) => [
|
|
|
817
871
|
const useSocketHost = (transport, options, persistence) => {
|
|
818
872
|
const [h] = useState(() => {
|
|
819
873
|
const host = {
|
|
874
|
+
protocol: {
|
|
875
|
+
name: DEFAULT_PROTOCOL,
|
|
876
|
+
version: WIRE_VERSION
|
|
877
|
+
},
|
|
878
|
+
wireVersion: { version: WIRE_VERSION },
|
|
820
879
|
heartbeatMs: 15e3,
|
|
821
880
|
wsInitTimeoutMs: 5e3,
|
|
822
881
|
maxSubscribers: MAX_SUBSCRIBERS,
|
|
@@ -852,6 +911,11 @@ const useSocketHost = (transport, options, persistence) => {
|
|
|
852
911
|
};
|
|
853
912
|
return host;
|
|
854
913
|
});
|
|
914
|
+
h.protocol = options?.protocol ?? {
|
|
915
|
+
name: "default",
|
|
916
|
+
version: "2026-09-07"
|
|
917
|
+
};
|
|
918
|
+
h.wireVersion = options?.wireVersion ?? { version: "2026-09-07" };
|
|
855
919
|
setHeartbeatMs(h, options?.heartbeatIntervalMs ?? 15e3);
|
|
856
920
|
h.pushback = options?.pushback;
|
|
857
921
|
h.wsInitTimeoutMs = options?.wsInitTimeoutMs ?? 5e3;
|