statewire 0.18.0 → 0.18.2
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/client/session.d.ts +1 -1
- package/dist/client/session.d.ts.map +1 -1
- package/dist/client/session.js +49 -189
- package/dist/client/session.js.map +1 -1
- package/dist/host/http.d.ts.map +1 -1
- package/dist/host/http.js +2 -3
- package/dist/host/http.js.map +1 -1
- package/dist/host/socket.d.ts +4 -5
- package/dist/host/socket.d.ts.map +1 -1
- package/dist/host/socket.js +33 -44
- package/dist/host/socket.js.map +1 -1
- package/dist/host-internal.d.ts +0 -4
- package/dist/host-internal.d.ts.map +1 -1
- package/dist/host.d.ts +1 -1
- package/dist/statewire.d.ts +1 -11
- package/dist/statewire.d.ts.map +1 -1
- package/dist/statewire.js.map +1 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +6 -55
- package/dist/storage.js.map +1 -1
- package/dist/transports/sse.d.ts +1 -1
- package/dist/transports/sse.js.map +1 -1
- package/dist/transports/testing.js +2 -1
- package/dist/transports/testing.js.map +1 -1
- package/package.json +1 -1
- package/src/client/session.ts +68 -212
- package/src/host/http.ts +2 -9
- package/src/host/socket.ts +38 -46
- package/src/host-internal.ts +0 -4
- package/src/host.ts +1 -1
- package/src/statewire.ts +1 -8
- package/src/storage.ts +8 -92
- package/src/transports/sse.ts +1 -1
- package/src/transports/testing.ts +2 -1
package/dist/client/session.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ type Session = {
|
|
|
65
65
|
idle: boolean;
|
|
66
66
|
onSessionLost: StatewireClient.OnSessionLost | undefined;
|
|
67
67
|
onDone: (() => void) | undefined;
|
|
68
|
-
|
|
68
|
+
ctxNextSeq: number;
|
|
69
69
|
ctxPending: CtxPending[];
|
|
70
70
|
lanesOnAttach: boolean;
|
|
71
71
|
attachLaneSeqs: readonly [ReadonlySet<number>, ReadonlySet<number>];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","names":[],"sources":["../../src/client/session.ts"],"mappings":";;;;;;;;KA0CK;EACH;EACA,WAAW,YAAY,gBAAgB;EACvC;EACA;EACA;;KAGG;WACM;WACA,SAAS;WACT,KAAK;;EAEd;;EAEA;;EAEA;EACA,UAAU;EACV,SAAS;;KAGN;WACM;WACA;EACT;;KAeG;KAEO,0BAA0B,kBAAkB;EACtD,eAAe,gBAAgB;EAC/B,gBAAgB,gBAAgB;EAChC;;KAGG;EACH,KAAK;EACL,QAAQ,gBAAgB;EACxB;;KAGG;EACH,SAAS;EACT,WAAW,kBAAkB;EAC7B,kBAAkB,mBAAmB;EACrC,QAAQ,gBAAgB;EACxB,KAAK;EACL;EACA;EACA,OAAO;EACP;EACA,iBAAiB,gBAAgB;EACjC,OAAO,gBAAgB;EACvB,eAAe,mBAAmB;EAClC,QAAQ;EACR;;EAEA;EACA;EACA;EACA;EACA;EACA,eAAe,gBAAgB;EAC/B;EACA;EACA,YAAY;EACZ;EACA,0BAA0B,qBAAqB;EAC/C;EACA,SAAS;EACT;EACA,mBAAmB;EACnB,WAAW,mBAAmB;EAC9B;EACA,SAAS;EACT,QAAQ,UAAU;EAClB,QAAQ;EACR;EACA;EACA;EACA,WAAW;EACX;EACA,WAAW;EACX;EACA,UAAU,mBAAmB,sBAAsB;;
|
|
1
|
+
{"version":3,"file":"session.d.ts","names":[],"sources":["../../src/client/session.ts"],"mappings":";;;;;;;;KA0CK;EACH;EACA,WAAW,YAAY,gBAAgB;EACvC;EACA;EACA;;KAGG;WACM;WACA,SAAS;WACT,KAAK;;EAEd;;EAEA;;EAEA;EACA,UAAU;EACV,SAAS;;KAGN;WACM;WACA;EACT;;KAeG;KAEO,0BAA0B,kBAAkB;EACtD,eAAe,gBAAgB;EAC/B,gBAAgB,gBAAgB;EAChC;;KAGG;EACH,KAAK;EACL,QAAQ,gBAAgB;EACxB;;KAGG;EACH,SAAS;EACT,WAAW,kBAAkB;EAC7B,kBAAkB,mBAAmB;EACrC,QAAQ,gBAAgB;EACxB,KAAK;EACL;EACA;EACA,OAAO;EACP;EACA,iBAAiB,gBAAgB;EACjC,OAAO,gBAAgB;EACvB,eAAe,mBAAmB;EAClC,QAAQ;EACR;;EAEA;EACA;EACA;EACA;EACA;EACA,eAAe,gBAAgB;EAC/B;EACA;EACA,YAAY;EACZ;EACA,0BAA0B,qBAAqB;EAC/C;EACA,SAAS;EACT;EACA,mBAAmB;EACnB,WAAW,mBAAmB;EAC9B;EACA,SAAS;EACT,QAAQ,UAAU;EAClB,QAAQ;EACR;EACA;EACA;EACA,WAAW;EACX;EACA,WAAW;EACX;EACA,UAAU,mBAAmB,sBAAsB;;cAgJxC,iBACX,GAAG,qBACO,gBAAgB;cAqqBtB,eAAgB,GAAG,SAAS,WAAW;cAmLhC,gBACX,GAAG,SACH,OAAO,gBAAgB;cAYZ,cACX,GAAG,SACH,OAAO,gBAAgB,kBACtB;cA4GU,gBAAiB,GAAG,SAAS;cAGpC,aACJ,GAAG,SACH,OAAO,yBACP;cAuBW,iBAAkB,GAAG,YAAU,mBAAmB;cA+BlD,iBACX,GAAG,SACH,kBACA,gBACA,+BAA0B;cAsEf,sBACX,SAAS,4BACR"}
|
package/dist/client/session.js
CHANGED
|
@@ -93,21 +93,7 @@ const transact = (s, fn) => {
|
|
|
93
93
|
const result = shared.txq.then(() => s.store.lock(async () => {
|
|
94
94
|
const stored = s.store.load();
|
|
95
95
|
if (stored !== null && stored.clientId !== s.record.clientId) adoptReset(s, stored);
|
|
96
|
-
else if (stored !== null)
|
|
97
|
-
s.record = stored;
|
|
98
|
-
if (stored.context !== void 0) {
|
|
99
|
-
const posted = new Set(s.ctxPending.filter((p) => p.posted).map((p) => p.seq));
|
|
100
|
-
s.ctxOps = stored.context.ops;
|
|
101
|
-
s.contextDocuments = applyDocumentOps({
|
|
102
|
-
mode: "mounted",
|
|
103
|
-
documents: /* @__PURE__ */ new Map()
|
|
104
|
-
}, stored.context.ops);
|
|
105
|
-
s.ctxPending = stored.context.pending.map((p) => ({
|
|
106
|
-
...p,
|
|
107
|
-
posted: posted.has(p.seq)
|
|
108
|
-
}));
|
|
109
|
-
}
|
|
110
|
-
}
|
|
96
|
+
else if (stored !== null) s.record = stored;
|
|
111
97
|
fn();
|
|
112
98
|
const persistence = s.store.flush?.();
|
|
113
99
|
if (persistence) await persistence;
|
|
@@ -203,20 +189,6 @@ const settleAll = (s, detach) => {
|
|
|
203
189
|
});
|
|
204
190
|
}
|
|
205
191
|
};
|
|
206
|
-
const restateContext = (s) => {
|
|
207
|
-
s.ctxPending = [];
|
|
208
|
-
if (s.ctxOps === void 0) return;
|
|
209
|
-
const seq = s.record.ctxNextSeq;
|
|
210
|
-
setRecord(s, {
|
|
211
|
-
...s.record,
|
|
212
|
-
ctxNextSeq: seq + 1
|
|
213
|
-
});
|
|
214
|
-
s.ctxPending.push({
|
|
215
|
-
seq,
|
|
216
|
-
ops: s.ctxOps,
|
|
217
|
-
posted: false
|
|
218
|
-
});
|
|
219
|
-
};
|
|
220
192
|
const settleLost = (s, entries) => {
|
|
221
193
|
for (const entry of entries) {
|
|
222
194
|
s.lifecycle?.onCovered?.(entry.inv);
|
|
@@ -245,7 +217,6 @@ const rebaseRecord = (s, adopt) => {
|
|
|
245
217
|
s.lifecycle?.onCovered?.(old.inv);
|
|
246
218
|
enqueueInner(s, old.command, old.inv.params, old.resolve, old.reject);
|
|
247
219
|
}
|
|
248
|
-
restateContext(s);
|
|
249
220
|
publish(s);
|
|
250
221
|
wake(s);
|
|
251
222
|
pump(s);
|
|
@@ -253,7 +224,6 @@ const rebaseRecord = (s, adopt) => {
|
|
|
253
224
|
const resetRecord = (s, clientId) => rebaseRecord(s, () => setRecord(s, {
|
|
254
225
|
clientId,
|
|
255
226
|
nextSeq: 1,
|
|
256
|
-
ctxNextSeq: 1,
|
|
257
227
|
commands: []
|
|
258
228
|
}));
|
|
259
229
|
const adoptReset = (s, stored) => rebaseRecord(s, () => {
|
|
@@ -389,47 +359,7 @@ const publishIngested = (s) => {
|
|
|
389
359
|
for (const listener of s.documentListeners) listener();
|
|
390
360
|
wake(s);
|
|
391
361
|
};
|
|
392
|
-
const
|
|
393
|
-
if (s.record.context?.recover === "version-1") {
|
|
394
|
-
const document = s.contextDocuments.documents.get(0);
|
|
395
|
-
if (s.contextDocuments.documents.size !== 1 || !document?.main) throw new Error("statewire: version-1 context recovery requires one main document at doc 0");
|
|
396
|
-
const encoded = encodeDocument(document.value);
|
|
397
|
-
const ops = [{
|
|
398
|
-
...ctxWm === 0 ? {
|
|
399
|
-
op: "mount",
|
|
400
|
-
protocol: document.protocol,
|
|
401
|
-
main: true
|
|
402
|
-
} : {
|
|
403
|
-
op: "replace",
|
|
404
|
-
path: []
|
|
405
|
-
},
|
|
406
|
-
...encoded
|
|
407
|
-
}];
|
|
408
|
-
s.ctxPending = [{
|
|
409
|
-
seq: ctxWm + 1,
|
|
410
|
-
ops,
|
|
411
|
-
posted: false
|
|
412
|
-
}];
|
|
413
|
-
setRecord(s, {
|
|
414
|
-
...s.record,
|
|
415
|
-
ctxNextSeq: ctxWm + 2,
|
|
416
|
-
context: {
|
|
417
|
-
ops: contextSnapshot(s.contextDocuments),
|
|
418
|
-
pending: s.ctxPending
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
if (!(s.ctxPending.every((c, i) => c.seq === ctxWm + 1 + i) && s.record.ctxNextSeq === ctxWm + s.ctxPending.length + 1)) {
|
|
424
|
-
if (ctxWm > 0) throw new Error("statewire: context history is missing; use a new client id");
|
|
425
|
-
setRecord(s, {
|
|
426
|
-
...s.record,
|
|
427
|
-
ctxNextSeq: ctxWm + 1
|
|
428
|
-
});
|
|
429
|
-
restateContext(s);
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
const sessionLostInner = (s, seqWm, ctxWm) => {
|
|
362
|
+
const sessionLostInner = (s, seqWm) => {
|
|
433
363
|
const held = [...s.pending];
|
|
434
364
|
settleLost(s, held);
|
|
435
365
|
s.pending = [];
|
|
@@ -437,17 +367,16 @@ const sessionLostInner = (s, seqWm, ctxWm) => {
|
|
|
437
367
|
setRecord(s, {
|
|
438
368
|
clientId: s.record.clientId,
|
|
439
369
|
nextSeq: seqWm + 1,
|
|
440
|
-
ctxNextSeq: s.record.ctxNextSeq,
|
|
441
370
|
commands: [],
|
|
442
371
|
...s.record.failed !== void 0 && { failed: s.record.failed }
|
|
443
372
|
});
|
|
444
|
-
snapCtxClock(s, ctxWm);
|
|
445
373
|
if (held.length > 0 && s.onSessionLost?.(held.map((p) => p.inv)) === "requeue") for (const old of held) enqueueInner(s, old.command, old.inv.params, () => {}, () => {});
|
|
446
374
|
publish(s);
|
|
447
375
|
wake(s);
|
|
448
376
|
};
|
|
449
377
|
const handleHello = (s, { ops, syn }) => {
|
|
450
378
|
if (syn.record !== void 0 && syn.record !== "ephemeral") protocolError(`unknown record: ${String(syn.record)}`);
|
|
379
|
+
if (syn.ctxSeq !== void 0 && syn.ctxSeq !== 0) protocolError(`hello ctxSeq must be 0, got ${syn.ctxSeq}`);
|
|
451
380
|
s.selection = syn.version === void 0 || syn.protocols === void 0 ? void 0 : {
|
|
452
381
|
version: syn.version,
|
|
453
382
|
protocols: syn.protocols
|
|
@@ -469,11 +398,7 @@ const handleHello = (s, { ops, syn }) => {
|
|
|
469
398
|
if (s.shared) adoptStored(s);
|
|
470
399
|
s.durableSeq = syn.seq ?? 0;
|
|
471
400
|
for (const entry of s.pending) entry.posted = attachCmd.has(entry.seq);
|
|
472
|
-
const ctxWatermark = syn.ctxSeq ?? 0;
|
|
473
|
-
s.ctxPending = s.ctxPending.filter((c) => c.seq > ctxWatermark);
|
|
474
401
|
for (const c of s.ctxPending) c.posted = attachCtx.has(c.seq);
|
|
475
|
-
snapCtxClock(s, ctxWatermark);
|
|
476
|
-
if (s.ctxOps !== void 0) persistContext(s);
|
|
477
402
|
syncBacklogInner(s);
|
|
478
403
|
s.sessionKnown = true;
|
|
479
404
|
};
|
|
@@ -503,7 +428,8 @@ const handleRefusal = (s, syn) => {
|
|
|
503
428
|
if (typeof ctxSeq === "number") {
|
|
504
429
|
s.ctxPending = s.ctxPending.filter((c) => c.seq > ctxSeq);
|
|
505
430
|
for (const c of s.ctxPending) c.posted = false;
|
|
506
|
-
|
|
431
|
+
const firstCtx = s.ctxPending.find((c) => !c.posted);
|
|
432
|
+
if (firstCtx !== void 0 && firstCtx.seq > ctxSeq + 1) protocolError(`ctx gap on a live attach: seq ${firstCtx.seq} after watermark ${ctxSeq}`);
|
|
507
433
|
}
|
|
508
434
|
if (typeof syn.retry === "number") {
|
|
509
435
|
s.resumeAt = Date.now() + syn.retry;
|
|
@@ -512,14 +438,8 @@ const handleRefusal = (s, syn) => {
|
|
|
512
438
|
return;
|
|
513
439
|
}
|
|
514
440
|
const firstCmd = s.pending.find((p) => !p.posted);
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
const ctxGap = typeof ctxSeq === "number" && firstCtx !== void 0 && firstCtx.seq > ctxSeq + 1;
|
|
518
|
-
if (cmdGap || ctxGap) {
|
|
519
|
-
transactBackground(s, () => {
|
|
520
|
-
if (cmdGap) sessionLostInner(s, seq, ctxSeq ?? 0);
|
|
521
|
-
else snapCtxClock(s, ctxSeq);
|
|
522
|
-
}, () => {
|
|
441
|
+
if (typeof seq === "number" && firstCmd !== void 0 && firstCmd.seq > Math.max(seq, s.durableSeq) + 1) {
|
|
442
|
+
transactBackground(s, () => sessionLostInner(s, seq), () => {
|
|
523
443
|
wake(s);
|
|
524
444
|
pump(s);
|
|
525
445
|
});
|
|
@@ -541,19 +461,19 @@ const handleFinish = (s, { reason }) => {
|
|
|
541
461
|
wake(s);
|
|
542
462
|
};
|
|
543
463
|
const isFinished = (s) => s.attach === "finished";
|
|
544
|
-
const buildLanes = (s,
|
|
464
|
+
const buildLanes = (s, cmdGate = "all") => {
|
|
545
465
|
const ctxEntries = [];
|
|
546
466
|
for (const entry of s.ctxPending) {
|
|
547
467
|
if (entry.posted) continue;
|
|
548
|
-
if (persisted && (s.persistedRecord?.clientId !== s.record.clientId || entry.seq >= s.persistedRecord.ctxNextSeq)) break;
|
|
549
468
|
if (ctxEntries.length >= 256) break;
|
|
550
469
|
if (ctxEntries.length > 0 && entry.seq !== ctxEntries.at(-1).seq + 1) break;
|
|
551
470
|
ctxEntries.push(entry);
|
|
552
471
|
}
|
|
553
472
|
const cmdEntries = [];
|
|
554
473
|
for (const entry of s.pending) {
|
|
474
|
+
if (cmdGate === "none") break;
|
|
555
475
|
if (entry.posted) continue;
|
|
556
|
-
if (persisted && (s.persistedRecord?.clientId !== s.record.clientId || entry.seq >= s.persistedRecord.nextSeq)) break;
|
|
476
|
+
if (cmdGate === "persisted" && (s.persistedRecord?.clientId !== s.record.clientId || entry.seq >= s.persistedRecord.nextSeq)) break;
|
|
557
477
|
if (cmdEntries.length >= 256) break;
|
|
558
478
|
if (cmdEntries.length > 0 && entry.seq !== cmdEntries.at(-1).seq + 1) break;
|
|
559
479
|
cmdEntries.push(entry);
|
|
@@ -577,12 +497,21 @@ const buildLanes = (s, persisted = false) => {
|
|
|
577
497
|
ctxEntries
|
|
578
498
|
};
|
|
579
499
|
};
|
|
500
|
+
const resetContextLane = (s) => {
|
|
501
|
+
const ops = contextSnapshot(s.contextDocuments);
|
|
502
|
+
s.ctxPending = ops.length === 0 ? [] : [{
|
|
503
|
+
seq: 1,
|
|
504
|
+
ops,
|
|
505
|
+
posted: false
|
|
506
|
+
}];
|
|
507
|
+
s.ctxNextSeq = s.ctxPending.length + 1;
|
|
508
|
+
};
|
|
580
509
|
const takeAttachLanes = (s) => {
|
|
581
510
|
s.attachLaneSeqs = [/* @__PURE__ */ new Set(), /* @__PURE__ */ new Set()];
|
|
511
|
+
resetContextLane(s);
|
|
582
512
|
const wanted = s.lanesOnAttach;
|
|
583
513
|
s.lanesOnAttach = false;
|
|
584
|
-
|
|
585
|
-
const lanes = buildLanes(s, true);
|
|
514
|
+
const lanes = buildLanes(s, wanted && s.sessionKnown ? "persisted" : "none");
|
|
586
515
|
if (!lanes) return null;
|
|
587
516
|
s.attachLaneSeqs = [new Set(lanes.cmdEntries.map((p) => p.seq)), new Set(lanes.ctxEntries.map((c) => c.seq))];
|
|
588
517
|
for (const entry of lanes.cmdEntries) entry.attempted = true;
|
|
@@ -715,7 +644,7 @@ const setTransport = (s, transport) => {
|
|
|
715
644
|
wake(s);
|
|
716
645
|
};
|
|
717
646
|
const enqueueInner = (s, command, params, resolve, reject) => {
|
|
718
|
-
const seq = s.record.nextSeq;
|
|
647
|
+
const seq = Math.max(s.record.nextSeq, s.durableSeq + 1);
|
|
719
648
|
const entry = {
|
|
720
649
|
seq,
|
|
721
650
|
command,
|
|
@@ -925,67 +854,25 @@ const contextSnapshot = (documents) => [...documents.documents].map(([doc, d]) =
|
|
|
925
854
|
...encoded.meta === void 0 ? {} : { meta: encoded.meta }
|
|
926
855
|
};
|
|
927
856
|
});
|
|
928
|
-
const persistContext = (s) => {
|
|
929
|
-
const ops = contextSnapshot(s.contextDocuments);
|
|
930
|
-
s.ctxOps = ops;
|
|
931
|
-
setRecord(s, {
|
|
932
|
-
...s.record,
|
|
933
|
-
context: {
|
|
934
|
-
ops,
|
|
935
|
-
...s.record.context?.recover === void 0 ? {} : { recover: s.record.context.recover },
|
|
936
|
-
pending: s.ctxPending.map(({ seq, ops }) => ({
|
|
937
|
-
seq,
|
|
938
|
-
ops
|
|
939
|
-
}))
|
|
940
|
-
}
|
|
941
|
-
});
|
|
942
|
-
};
|
|
943
857
|
const changeContext = (s, build) => {
|
|
944
|
-
if (!s.hydrated) {
|
|
945
|
-
s.ready.then(() => changeContext(s, build)).catch((cause) => {
|
|
946
|
-
const error = wrapStorageError(cause);
|
|
947
|
-
s.storageError = error;
|
|
948
|
-
s.transport?.storageFailed(error);
|
|
949
|
-
});
|
|
950
|
-
return;
|
|
951
|
-
}
|
|
952
858
|
if (!s.running || isFinished(s)) return;
|
|
953
|
-
const
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
const { doc: _doc, ...rest } = value;
|
|
971
|
-
return rest;
|
|
972
|
-
}),
|
|
973
|
-
posted: false
|
|
974
|
-
}];
|
|
975
|
-
s.record = {
|
|
976
|
-
...s.record,
|
|
977
|
-
ctxNextSeq: seq + 1
|
|
978
|
-
};
|
|
979
|
-
persistContext(s);
|
|
980
|
-
};
|
|
981
|
-
if (!s.shared) {
|
|
982
|
-
submit();
|
|
983
|
-
wake(s);
|
|
984
|
-
pump(s);
|
|
985
|
-
} else transactBackground(s, submit, () => {
|
|
986
|
-
wake(s);
|
|
987
|
-
pump(s);
|
|
988
|
-
});
|
|
859
|
+
const operations = build(s.contextDocuments);
|
|
860
|
+
if (!operations.length) throw new Error("statewire: context operations must not be empty");
|
|
861
|
+
const offers = protocolOffers(s.options);
|
|
862
|
+
const protocols = s.selection?.protocols ?? (offers === "*" ? void 0 : offers);
|
|
863
|
+
s.contextDocuments = applyDocumentOps(s.contextDocuments, operations, protocols, true);
|
|
864
|
+
s.ctxPending = [...s.ctxPending, {
|
|
865
|
+
seq: s.ctxNextSeq++,
|
|
866
|
+
ops: operations.map((op) => {
|
|
867
|
+
const value = op;
|
|
868
|
+
if (value["doc"] !== 0) return value;
|
|
869
|
+
const { doc: _doc, ...rest } = value;
|
|
870
|
+
return rest;
|
|
871
|
+
}),
|
|
872
|
+
posted: false
|
|
873
|
+
}];
|
|
874
|
+
wake(s);
|
|
875
|
+
pump(s);
|
|
989
876
|
};
|
|
990
877
|
const updateContext = (s, operations) => changeContext(s, () => operations);
|
|
991
878
|
const setContext = (s, value, protocol = s.options.protocol ?? "default") => {
|
|
@@ -1061,14 +948,10 @@ const loadSessionRecord = (store, options) => {
|
|
|
1061
948
|
const record = stored ?? {
|
|
1062
949
|
clientId: randomId(),
|
|
1063
950
|
nextSeq: 1,
|
|
1064
|
-
ctxNextSeq: 1,
|
|
1065
951
|
commands: []
|
|
1066
952
|
};
|
|
1067
953
|
if (stored === null) store.save(record);
|
|
1068
|
-
return
|
|
1069
|
-
record,
|
|
1070
|
-
stored
|
|
1071
|
-
};
|
|
954
|
+
return record;
|
|
1072
955
|
};
|
|
1073
956
|
const useStatewireSession = (options) => {
|
|
1074
957
|
const [defaultStore] = useState(createMemorySessionStore);
|
|
@@ -1078,25 +961,18 @@ const useStatewireSession = (options) => {
|
|
|
1078
961
|
const store = options.sessionStore ?? mounted ?? defaultStore;
|
|
1079
962
|
if (store.lock === void 0 !== (store.subscribe === void 0)) throw new Error("statewire: session storage must provide lock and subscribe together");
|
|
1080
963
|
const [s] = useState(() => {
|
|
1081
|
-
const
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
ctxNextSeq: 1,
|
|
1086
|
-
commands: []
|
|
1087
|
-
},
|
|
1088
|
-
stored: null
|
|
964
|
+
const record = store.ready === void 0 ? loadSessionRecord(store, options) : {
|
|
965
|
+
clientId: randomId(),
|
|
966
|
+
nextSeq: 1,
|
|
967
|
+
commands: []
|
|
1089
968
|
};
|
|
1090
969
|
const session = {
|
|
1091
970
|
options,
|
|
1092
971
|
selection: void 0,
|
|
1093
|
-
contextDocuments:
|
|
972
|
+
contextDocuments: {
|
|
1094
973
|
mode: "mounted",
|
|
1095
974
|
documents: /* @__PURE__ */ new Map()
|
|
1096
|
-
}
|
|
1097
|
-
mode: "mounted",
|
|
1098
|
-
documents: /* @__PURE__ */ new Map()
|
|
1099
|
-
}, stored.context.ops),
|
|
975
|
+
},
|
|
1100
976
|
record,
|
|
1101
977
|
ctx: {
|
|
1102
978
|
beforeAttach: () => persistBeforeSend(session),
|
|
@@ -1132,11 +1008,8 @@ const useStatewireSession = (options) => {
|
|
|
1132
1008
|
idle: false,
|
|
1133
1009
|
onSessionLost: void 0,
|
|
1134
1010
|
onDone: void 0,
|
|
1135
|
-
|
|
1136
|
-
ctxPending:
|
|
1137
|
-
...p,
|
|
1138
|
-
posted: false
|
|
1139
|
-
})) ?? [],
|
|
1011
|
+
ctxNextSeq: 1,
|
|
1012
|
+
ctxPending: [],
|
|
1140
1013
|
lanesOnAttach: false,
|
|
1141
1014
|
attachLaneSeqs: [/* @__PURE__ */ new Set(), /* @__PURE__ */ new Set()],
|
|
1142
1015
|
frameFailures: 0,
|
|
@@ -1172,20 +1045,7 @@ const useStatewireSession = (options) => {
|
|
|
1172
1045
|
};
|
|
1173
1046
|
if (store.ready !== void 0) {
|
|
1174
1047
|
session.ready = store.ready.then(() => {
|
|
1175
|
-
|
|
1176
|
-
session.record = record_0;
|
|
1177
|
-
session.contextDocuments = record_0.context === void 0 ? {
|
|
1178
|
-
mode: "mounted",
|
|
1179
|
-
documents: /* @__PURE__ */ new Map()
|
|
1180
|
-
} : applyDocumentOps({
|
|
1181
|
-
mode: "mounted",
|
|
1182
|
-
documents: /* @__PURE__ */ new Map()
|
|
1183
|
-
}, record_0.context.ops);
|
|
1184
|
-
session.ctxOps = record_0.context?.ops;
|
|
1185
|
-
session.ctxPending = record_0.context?.pending.map((entry) => ({
|
|
1186
|
-
...entry,
|
|
1187
|
-
posted: false
|
|
1188
|
-
})) ?? [];
|
|
1048
|
+
session.record = loadSessionRecord(store, session.options);
|
|
1189
1049
|
session.recordPersisted = true;
|
|
1190
1050
|
session.hydrated = true;
|
|
1191
1051
|
if (session.running) session.notify();
|