@brass-build/client 0.1.0 → 0.3.0
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/AGENTS.md +72 -63
- package/CHANGELOG.md +97 -0
- package/README.md +325 -235
- package/dist/auth-flow.d.ts +10 -1
- package/dist/auth-flow.d.ts.map +1 -1
- package/dist/auth-flow.js +64 -20
- package/dist/auth-flow.js.map +1 -1
- package/dist/client.d.ts +4 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +245 -76
- package/dist/client.js.map +1 -1
- package/dist/document-checkpoints.d.ts +1 -0
- package/dist/document-checkpoints.d.ts.map +1 -1
- package/dist/document-checkpoints.js +27 -0
- package/dist/document-checkpoints.js.map +1 -1
- package/dist/document-engine.d.ts +4 -0
- package/dist/document-engine.d.ts.map +1 -0
- package/dist/document-engine.js +9 -0
- package/dist/document-engine.js.map +1 -0
- package/dist/document-signals.d.ts +31 -1
- package/dist/document-signals.d.ts.map +1 -1
- package/dist/document-signals.js +59 -0
- package/dist/document-signals.js.map +1 -1
- package/dist/document-streams.d.ts +8 -1
- package/dist/document-streams.d.ts.map +1 -1
- package/dist/document-streams.js +79 -8
- package/dist/document-streams.js.map +1 -1
- package/dist/document-thumbnail-capture.d.ts +20 -0
- package/dist/document-thumbnail-capture.d.ts.map +1 -1
- package/dist/document-thumbnail-capture.js +247 -9
- package/dist/document-thumbnail-capture.js.map +1 -1
- package/dist/documents-namespace.d.ts.map +1 -1
- package/dist/documents-namespace.js +22 -3
- package/dist/documents-namespace.js.map +1 -1
- package/dist/documents.d.ts +49 -16
- package/dist/documents.d.ts.map +1 -1
- package/dist/documents.js +981 -237
- package/dist/documents.js.map +1 -1
- package/dist/embed-protocol.d.ts +3 -0
- package/dist/embed-protocol.d.ts.map +1 -0
- package/dist/embed-protocol.js +26 -0
- package/dist/embed-protocol.js.map +1 -0
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +8 -1
- package/dist/emitter.js.map +1 -1
- package/dist/export-guest.d.ts.map +1 -1
- package/dist/export-guest.js +14 -6
- package/dist/export-guest.js.map +1 -1
- package/dist/fetch-deadline.d.ts +22 -0
- package/dist/fetch-deadline.d.ts.map +1 -0
- package/dist/fetch-deadline.js +96 -0
- package/dist/fetch-deadline.js.map +1 -0
- package/dist/fetch-retry.d.ts +1 -0
- package/dist/fetch-retry.d.ts.map +1 -1
- package/dist/fetch-retry.js +12 -5
- package/dist/fetch-retry.js.map +1 -1
- package/dist/handle-types.d.ts +150 -0
- package/dist/handle-types.d.ts.map +1 -0
- package/dist/handle-types.js +8 -0
- package/dist/handle-types.js.map +1 -0
- package/dist/handles.d.ts +48 -48
- package/dist/handles.d.ts.map +1 -1
- package/dist/handles.js +3122 -501
- package/dist/handles.js.map +1 -1
- package/dist/hosted-runtime.d.ts.map +1 -1
- package/dist/hosted-runtime.js +8 -12
- package/dist/hosted-runtime.js.map +1 -1
- package/dist/hosted-ui.d.ts +0 -1
- package/dist/hosted-ui.d.ts.map +1 -1
- package/dist/hosted-ui.js +29 -24
- package/dist/hosted-ui.js.map +1 -1
- package/dist/importer.d.ts.map +1 -1
- package/dist/importer.js +204 -8
- package/dist/importer.js.map +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +2 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -1
- package/dist/join-coverage.d.ts +12 -0
- package/dist/join-coverage.d.ts.map +1 -0
- package/dist/join-coverage.js +37 -0
- package/dist/join-coverage.js.map +1 -0
- package/dist/jwt.d.ts.map +1 -1
- package/dist/jwt.js +5 -1
- package/dist/jwt.js.map +1 -1
- package/dist/launch-context.js +2 -2
- package/dist/launch-context.js.map +1 -1
- package/dist/mutate-batching.d.ts +25 -2
- package/dist/mutate-batching.d.ts.map +1 -1
- package/dist/mutate-batching.js +57 -10
- package/dist/mutate-batching.js.map +1 -1
- package/dist/open-document.d.ts +30 -1
- package/dist/open-document.d.ts.map +1 -1
- package/dist/open-document.js +1905 -322
- package/dist/open-document.js.map +1 -1
- package/dist/presence.d.ts +28 -0
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js +149 -7
- package/dist/presence.js.map +1 -1
- package/dist/record-paging.d.ts +335 -71
- package/dist/record-paging.d.ts.map +1 -1
- package/dist/record-paging.js +590 -127
- package/dist/record-paging.js.map +1 -1
- package/dist/selection-persistence.d.ts.map +1 -1
- package/dist/selection-persistence.js +11 -1
- package/dist/selection-persistence.js.map +1 -1
- package/dist/serializer.d.ts +30 -1
- package/dist/serializer.d.ts.map +1 -1
- package/dist/session-persistence.d.ts.map +1 -1
- package/dist/session-persistence.js +9 -8
- package/dist/session-persistence.js.map +1 -1
- package/dist/session-toolbar.d.ts +0 -1
- package/dist/session-toolbar.d.ts.map +1 -1
- package/dist/session-toolbar.js +356 -83
- package/dist/session-toolbar.js.map +1 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +87 -18
- package/dist/session.js.map +1 -1
- package/dist/tail-ops.d.ts +14 -4
- package/dist/tail-ops.d.ts.map +1 -1
- package/dist/tail-ops.js +75 -15
- package/dist/tail-ops.js.map +1 -1
- package/dist/topic-lifecycle.d.ts +4 -0
- package/dist/topic-lifecycle.d.ts.map +1 -1
- package/dist/topic-lifecycle.js +25 -1
- package/dist/topic-lifecycle.js.map +1 -1
- package/dist/types.d.ts +47 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/undo.d.ts +2 -3
- package/dist/undo.d.ts.map +1 -1
- package/dist/undo.js +11 -0
- package/dist/undo.js.map +1 -1
- package/dist/unload-guard.d.ts +5 -0
- package/dist/unload-guard.d.ts.map +1 -0
- package/dist/unload-guard.js +88 -0
- package/dist/unload-guard.js.map +1 -0
- package/dist/version-bar.d.ts +4 -3
- package/dist/version-bar.d.ts.map +1 -1
- package/dist/version-bar.js +162 -20
- package/dist/version-bar.js.map +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/dist/vite.d.ts +18 -2
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +133 -8
- package/dist/vite.js.map +1 -1
- package/dist/when-saved.d.ts +2 -0
- package/dist/when-saved.d.ts.map +1 -0
- package/dist/when-saved.js +70 -0
- package/dist/when-saved.js.map +1 -0
- package/dist/ws-client.d.ts +27 -3
- package/dist/ws-client.d.ts.map +1 -1
- package/dist/ws-client.js +408 -89
- package/dist/ws-client.js.map +1 -1
- package/dist/ws-frame-limit.d.ts.map +1 -1
- package/dist/ws-frame-limit.js +23 -17
- package/dist/ws-frame-limit.js.map +1 -1
- package/docs/app-manifest.md +7 -8
- package/docs/custom-chrome.md +21 -22
- package/docs/hosted-ui-advanced.md +14 -17
- package/docs/imported-documents.md +53 -197
- package/docs/presence.md +45 -21
- package/docs/schemas.md +12 -17
- package/docs/streams.md +55 -57
- package/package.json +4 -3
- package/src/auth-flow.ts +90 -23
- package/src/client.ts +262 -80
- package/src/document-checkpoints.ts +30 -0
- package/src/document-engine.ts +15 -0
- package/src/document-signals.ts +120 -8
- package/src/document-streams.ts +95 -9
- package/src/document-thumbnail-capture.ts +253 -9
- package/src/documents-namespace.ts +38 -13
- package/src/documents.ts +1103 -290
- package/src/embed-protocol.ts +25 -0
- package/src/emitter.ts +8 -1
- package/src/export-guest.ts +15 -9
- package/src/fetch-deadline.ts +119 -0
- package/src/fetch-retry.ts +14 -5
- package/src/handle-types.ts +303 -0
- package/src/handles.ts +3407 -683
- package/src/hosted-runtime.ts +8 -12
- package/src/hosted-ui.ts +28 -32
- package/src/importer.ts +216 -8
- package/src/index.ts +29 -18
- package/src/internal.ts +7 -0
- package/src/join-coverage.ts +42 -0
- package/src/jwt.ts +8 -1
- package/src/launch-context.ts +2 -2
- package/src/mutate-batching.ts +60 -11
- package/src/open-document.ts +2441 -502
- package/src/presence.ts +210 -11
- package/src/record-paging.ts +686 -137
- package/src/selection-persistence.ts +10 -1
- package/src/serializer.ts +33 -1
- package/src/session-persistence.ts +9 -8
- package/src/session-toolbar.ts +387 -89
- package/src/session.ts +91 -17
- package/src/tail-ops.ts +76 -10
- package/src/topic-lifecycle.ts +31 -1
- package/src/types.ts +56 -4
- package/src/undo.ts +13 -5
- package/src/unload-guard.ts +91 -0
- package/src/version-bar.ts +183 -26
- package/src/version.ts +1 -1
- package/src/vite.ts +175 -10
- package/src/when-saved.ts +66 -0
- package/src/ws-client.ts +461 -92
- package/src/ws-frame-limit.ts +23 -17
package/dist/tail-ops.js
CHANGED
|
@@ -14,33 +14,93 @@ import { BrassError } from './errors.js';
|
|
|
14
14
|
function isUrlOp(op) {
|
|
15
15
|
return typeof op.op_blob_url === 'string';
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* What the spilled entries in this tail say they will cost to fetch.
|
|
19
|
+
*
|
|
20
|
+
* Read before any of them is fetched, so a load can state the whole of what it
|
|
21
|
+
* is about to download rather than discovering it. An entry naming no size
|
|
22
|
+
* counts zero, which understates the total: a bar that finishes early is a
|
|
23
|
+
* worse answer than one that never moves, and a much better one than a bar
|
|
24
|
+
* that goes backwards when the rest arrives.
|
|
25
|
+
*/
|
|
26
|
+
export function declaredTailBytes(tailOps) {
|
|
27
|
+
let total = 0;
|
|
28
|
+
for (const op of tailOps) {
|
|
29
|
+
if (!isUrlOp(op))
|
|
30
|
+
continue;
|
|
31
|
+
const declared = op.op_blob_bytes;
|
|
32
|
+
if (typeof declared === 'number' && declared > 0)
|
|
33
|
+
total += declared;
|
|
34
|
+
}
|
|
35
|
+
return total;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* How many spilled ops a join fetches at once.
|
|
39
|
+
*
|
|
40
|
+
* A browser refuses to open an unbounded number of sockets: past a few
|
|
41
|
+
* hundred in flight it fails the rest of them outright with
|
|
42
|
+
* `ERR_INSUFFICIENT_RESOURCES`, which arrives as a rejected fetch and
|
|
43
|
+
* fails the whole join. Chrome's own per-host cap is 6, so a higher bound
|
|
44
|
+
* here only queues inside the browser; this is low enough to stay clear of
|
|
45
|
+
* the failure and high enough that the queue drains at the connection
|
|
46
|
+
* limit rather than the loop's.
|
|
47
|
+
*/
|
|
48
|
+
const TAIL_FETCH_CONCURRENCY = 8;
|
|
17
49
|
/**
|
|
18
50
|
* Fetch any tail op whose bytes live behind a signed URL, leaving inline
|
|
19
51
|
* ops untouched, and return the tail in its original order.
|
|
20
52
|
*
|
|
21
|
-
* Ordering matters and concurrency does not disturb it:
|
|
22
|
-
*
|
|
23
|
-
* still applies ops in ascending seq.
|
|
53
|
+
* Ordering matters and concurrency does not disturb it: each result lands
|
|
54
|
+
* back at its own index, so the caller still applies ops in ascending seq.
|
|
24
55
|
*
|
|
25
56
|
* A failed fetch throws rather than dropping the op. Skipping one would
|
|
26
57
|
* leave the reader a document missing an edit it will never be sent
|
|
27
58
|
* again, which reads as data loss; failing the join sends it back through
|
|
28
59
|
* a path that can succeed.
|
|
29
60
|
*/
|
|
30
|
-
export async function resolveTailOps(tailOps, fetchImpl = fetch
|
|
31
|
-
|
|
61
|
+
export async function resolveTailOps(tailOps, fetchImpl = fetch,
|
|
62
|
+
// Told how many BYTES of the spilled ops are in hand, as each lands. A
|
|
63
|
+
// document whose tail spilled fetches hundreds of objects here, eight at a
|
|
64
|
+
// time, inside the join and before anything else reports: without this the
|
|
65
|
+
// whole stretch is silent, and a load that is working looks exactly like one
|
|
66
|
+
// that has hung.
|
|
67
|
+
//
|
|
68
|
+
// Bytes rather than objects because this is half of one download, not a
|
|
69
|
+
// stage of its own. The snapshot that follows is measured in bytes, and a
|
|
70
|
+
// reader watching a load has no use for the distinction between an op that
|
|
71
|
+
// spilled and the snapshot it will be folded into.
|
|
72
|
+
onProgress) {
|
|
73
|
+
const spilled = tailOps.filter(isUrlOp).length;
|
|
74
|
+
if (spilled === 0) {
|
|
32
75
|
return tailOps;
|
|
33
76
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
77
|
+
const out = Array.from({ length: tailOps.length });
|
|
78
|
+
let loadedBytes = 0;
|
|
79
|
+
onProgress?.(0);
|
|
80
|
+
let next = 0;
|
|
81
|
+
const worker = async () => {
|
|
82
|
+
for (;;) {
|
|
83
|
+
const i = next++;
|
|
84
|
+
if (i >= tailOps.length)
|
|
85
|
+
return;
|
|
86
|
+
const op = tailOps[i];
|
|
87
|
+
if (!isUrlOp(op)) {
|
|
88
|
+
out[i] = op;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
// The URL is pre-signed, so it carries no Brass headers: adding one
|
|
92
|
+
// would fall outside the signature and be refused.
|
|
93
|
+
const response = await fetchImpl(op.op_blob_url, { method: 'GET' });
|
|
94
|
+
if (!response.ok) {
|
|
95
|
+
throw new BrassError('Tail op fetch failed', { status: response.status });
|
|
96
|
+
}
|
|
97
|
+
const body = await response.text();
|
|
98
|
+
out[i] = { seq: op.seq, op_blob_b64: body };
|
|
99
|
+
loadedBytes += body.length;
|
|
100
|
+
onProgress?.(loadedBytes);
|
|
42
101
|
}
|
|
43
|
-
|
|
44
|
-
}));
|
|
102
|
+
};
|
|
103
|
+
await Promise.all(Array.from({ length: Math.min(TAIL_FETCH_CONCURRENCY, tailOps.length) }, () => worker()));
|
|
104
|
+
return out;
|
|
45
105
|
}
|
|
46
106
|
//# sourceMappingURL=tail-ops.js.map
|
package/dist/tail-ops.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tail-ops.js","sourceRoot":"","sources":["../src/tail-ops.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,oEAAoE;AACpE,yEAAyE;AACzE,sEAAsE;AACtE,sEAAsE;AACtE,uBAAuB;AACvB,EAAE;AACF,qEAAqE;AACrE,wEAAwE;AACxE,uEAAuE;AACvE,yCAAyC;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"tail-ops.js","sourceRoot":"","sources":["../src/tail-ops.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,oEAAoE;AACpE,yEAAyE;AACzE,sEAAsE;AACtE,sEAAsE;AACtE,uBAAuB;AACvB,EAAE;AACF,qEAAqE;AACrE,wEAAwE;AACxE,uEAAuE;AACvE,yCAAyC;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAiBzC,SAAS,OAAO,CAAC,EAAc;IAC7B,OAAO,OAAQ,EAAgC,CAAC,WAAW,KAAK,QAAQ,CAAC;AAC3E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAA8B;IAC9D,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAAE,SAAS;QAC3B,MAAM,QAAQ,GAAI,EAAkC,CAAC,aAAa,CAAC;QACnE,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,GAAG,CAAC;YAAE,KAAK,IAAI,QAAQ,CAAC;IACtE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAEjC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAA8B,EAC9B,YAA0B,KAAK;AAC/B,uEAAuE;AACvE,2EAA2E;AAC3E,2EAA2E;AAC3E,6EAA6E;AAC7E,iBAAiB;AACjB,EAAE;AACF,wEAAwE;AACxE,0EAA0E;AAC1E,2EAA2E;AAC3E,mDAAmD;AACnD,UAA0C;IAE1C,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAC/C,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,OAAO,OAA2B,CAAC;IACrC,CAAC;IACD,MAAM,GAAG,GAAqB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACrE,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;IAChB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,MAAM,MAAM,GAAG,KAAK,IAAmB,EAAE;QACvC,SAAS,CAAC;YACR,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;YACjB,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM;gBAAE,OAAO;YAChC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;YACvB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;gBACjB,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;gBACZ,SAAS;YACX,CAAC;YACD,oEAAoE;YACpE,mDAAmD;YACnD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,UAAU,CAAC,sBAAsB,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5E,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;YAC5C,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC;YAC3B,UAAU,EAAE,CAAC,WAAW,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CAAC;IACF,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,CAC5E,MAAM,EAAE,CACT,CACF,CAAC;IACF,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -28,6 +28,9 @@ export type TopicEffect = {
|
|
|
28
28
|
kind: 'drop_held';
|
|
29
29
|
} | {
|
|
30
30
|
kind: 'drop_listeners';
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'deliver_error';
|
|
33
|
+
reason: string;
|
|
31
34
|
} | {
|
|
32
35
|
kind: 'fire_error';
|
|
33
36
|
reason: string;
|
|
@@ -37,5 +40,6 @@ export interface StepResult {
|
|
|
37
40
|
effects: TopicEffect[];
|
|
38
41
|
}
|
|
39
42
|
export declare function holdsFrames(state: TopicState): boolean;
|
|
43
|
+
export declare function isFrameScopedReason(reason: string): boolean;
|
|
40
44
|
export declare function step(state: TopicState, event: TopicEvent): StepResult;
|
|
41
45
|
//# sourceMappingURL=topic-lifecycle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topic-lifecycle.d.ts","sourceRoot":"","sources":["../src/topic-lifecycle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"topic-lifecycle.d.ts","sourceRoot":"","sources":["../src/topic-lifecycle.ts"],"names":[],"mappings":"AA6BA,MAAM,MAAM,UAAU,GAClB,MAAM,GACN,aAAa,GACb,aAAa,GACb,UAAU,GACV,UAAU,CAAC;AAEf,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,CAAC;IAGlB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,UAAU,EAAE,UAAiD,CAAC;AAE3E,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,GAE5B;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GAGrB;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAI1B;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3C,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAKD,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAEtD;AAMD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE3D;AAyCD,wBAAgB,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,UAAU,CAuHrE"}
|
package/dist/topic-lifecycle.js
CHANGED
|
@@ -17,20 +17,35 @@
|
|
|
17
17
|
// `retrySpent` survives into a same-connection re-subscribe so the
|
|
18
18
|
// retry stays one-per-topic-per-connection.
|
|
19
19
|
//
|
|
20
|
+
// A frame-scoped reason (`isFrameScopedReason`) is the exception to all of
|
|
21
|
+
// that: it describes the frame the server could not process, not the
|
|
22
|
+
// subscription it arrived on, so every live phase keeps its state and hands
|
|
23
|
+
// the error to the topic's callbacks, which hold the frame that drew it.
|
|
24
|
+
//
|
|
20
25
|
// Invariant: every transition into `tornDown` emits `send_unsubscribe`,
|
|
21
26
|
// so no server-side subscription row can outlive the client-side state
|
|
22
27
|
// (an orphan row would have its `last_seen` kept fresh by the heartbeat,
|
|
23
28
|
// making it immune to the server's stale reaper).
|
|
24
29
|
export const IDLE_TOPIC = { phase: 'idle', retrySpent: false };
|
|
25
30
|
// True while topic-scoped frames must be held back: sending before the
|
|
26
|
-
// `subscribed` ack races the server's
|
|
31
|
+
// `subscribed` ack races the server's subscription record write and draws a spurious
|
|
27
32
|
// `forbidden`.
|
|
28
33
|
export function holdsFrames(state) {
|
|
29
34
|
return state.phase === 'subscribing' || state.phase === 'retrying';
|
|
30
35
|
}
|
|
36
|
+
// True for a reason that judges one frame rather than the subscription.
|
|
37
|
+
// `unavailable` answers a durable op write the server was authorised to
|
|
38
|
+
// take and could not store right now, so the topic stays up and the writer
|
|
39
|
+
// re-sends the op.
|
|
40
|
+
export function isFrameScopedReason(reason) {
|
|
41
|
+
return reason === 'unavailable';
|
|
42
|
+
}
|
|
31
43
|
const SEND_SUBSCRIBE = { kind: 'send_subscribe' };
|
|
32
44
|
const FLUSH_HELD = { kind: 'flush_held' };
|
|
33
45
|
const DROP_HELD = { kind: 'drop_held' };
|
|
46
|
+
function deliverError(state, reason) {
|
|
47
|
+
return { state, effects: [{ kind: 'deliver_error', reason }] };
|
|
48
|
+
}
|
|
34
49
|
// Rejection / spent-retry teardown. `send_unsubscribe` releases any
|
|
35
50
|
// server-side row a completed retry may have re-created (the invariant in
|
|
36
51
|
// the header); `unsubscribe` is idempotent server-side, so sending it when
|
|
@@ -77,6 +92,9 @@ export function step(state, event) {
|
|
|
77
92
|
effects: [FLUSH_HELD],
|
|
78
93
|
};
|
|
79
94
|
case 'error':
|
|
95
|
+
if (isFrameScopedReason(event.reason)) {
|
|
96
|
+
return deliverError(state, event.reason);
|
|
97
|
+
}
|
|
80
98
|
// Never established on this connection: the rejection is final.
|
|
81
99
|
return tearDown(state, event.reason);
|
|
82
100
|
case 'socket_open':
|
|
@@ -92,6 +110,9 @@ export function step(state, event) {
|
|
|
92
110
|
case 'established':
|
|
93
111
|
switch (event.type) {
|
|
94
112
|
case 'error':
|
|
113
|
+
if (isFrameScopedReason(event.reason)) {
|
|
114
|
+
return deliverError(state, event.reason);
|
|
115
|
+
}
|
|
95
116
|
// A mid-stream `not_subscribed` is an eviction (the server
|
|
96
117
|
// dropped the subscription row while this client stayed alive,
|
|
97
118
|
// e.g. a presence reap that raced a live-but-quiet connection),
|
|
@@ -121,6 +142,9 @@ export function step(state, event) {
|
|
|
121
142
|
case 'retrying':
|
|
122
143
|
switch (event.type) {
|
|
123
144
|
case 'error':
|
|
145
|
+
if (isFrameScopedReason(event.reason)) {
|
|
146
|
+
return deliverError(state, event.reason);
|
|
147
|
+
}
|
|
124
148
|
// An eviction draws errors for EVERY frame in flight against the
|
|
125
149
|
// reaped row; the trailing ones land while the retry's subscribe
|
|
126
150
|
// is unacked and describe frames that predate it, so the retry
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topic-lifecycle.js","sourceRoot":"","sources":["../src/topic-lifecycle.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,oEAAoE;AACpE,0EAA0E;AAC1E,kEAAkE;AAClE,EAAE;AACF,UAAU;AACV,8DAA8D;AAC9D,wEAAwE;AACxE,yEAAyE;AACzE,yCAAyC;AACzC,2EAA2E;AAC3E,mEAAmE;AACnE,yEAAyE;AACzE,oEAAoE;AACpE,2EAA2E;AAC3E,wEAAwE;AACxE,uEAAuE;AACvE,gDAAgD;AAChD,EAAE;AACF,wEAAwE;AACxE,uEAAuE;AACvE,yEAAyE;AACzE,kDAAkD;AAgBlD,MAAM,CAAC,MAAM,UAAU,GAAe,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"topic-lifecycle.js","sourceRoot":"","sources":["../src/topic-lifecycle.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { HostedUiTheme } from './hosted-ui.js';
|
|
1
2
|
export interface BrassUser {
|
|
2
3
|
sub: string;
|
|
3
4
|
email?: string;
|
|
@@ -9,7 +10,7 @@ export interface BrassInitOptions {
|
|
|
9
10
|
apiBaseUrl?: string;
|
|
10
11
|
wsBaseUrl?: string;
|
|
11
12
|
dashboardBaseUrl?: string;
|
|
12
|
-
hostedUiTheme?:
|
|
13
|
+
hostedUiTheme?: HostedUiTheme;
|
|
13
14
|
openIncompatibleDocuments?: boolean;
|
|
14
15
|
syncDocToUrl?: boolean;
|
|
15
16
|
docUrlParam?: string;
|
|
@@ -19,4 +20,49 @@ export interface BrassInitOptions {
|
|
|
19
20
|
export type AuthStatus = 'unknown' | 'signed-in' | 'signed-out' | 'guest';
|
|
20
21
|
export type UserChangeListener = (user: BrassUser | null) => void;
|
|
21
22
|
export type ErrorListener = (error: Error) => void;
|
|
23
|
+
export interface UndoControllerOptions {
|
|
24
|
+
maxUndoSteps?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A document's own view of how its sync is going, as the client sees it.
|
|
28
|
+
*
|
|
29
|
+
* The server records what reached it, so the facts that separate a write
|
|
30
|
+
* that was lost from a client that is merely slow live only here. Read it
|
|
31
|
+
* when a save is taking longer than it should; `Brass.onError` reports
|
|
32
|
+
* failures, and this reports the state a failure has not yet been declared
|
|
33
|
+
* for.
|
|
34
|
+
*/
|
|
35
|
+
export interface DocSyncDiagnostics {
|
|
36
|
+
/** Ops committed locally that the server has not acknowledged. */
|
|
37
|
+
unackedOps: number;
|
|
38
|
+
/** How long the oldest of them has been waiting, in ms. 0 when none. */
|
|
39
|
+
oldestUnackedMs: number;
|
|
40
|
+
/**
|
|
41
|
+
* The oldest unacked op's correlator. The same id rides the op to the
|
|
42
|
+
* server, so it is what an operator matches a stuck save against the
|
|
43
|
+
* server's record of the write.
|
|
44
|
+
*/
|
|
45
|
+
oldestClientOpId: string | null;
|
|
46
|
+
/**
|
|
47
|
+
* Sockets the SDK has opened since it was constructed, past the first.
|
|
48
|
+
* Every open document shares one socket, so this is a fact about the
|
|
49
|
+
* client rather than about this document, and it counts a deliberate
|
|
50
|
+
* close and re-open alongside a drop.
|
|
51
|
+
*/
|
|
52
|
+
reconnects: number;
|
|
53
|
+
/**
|
|
54
|
+
* Since any acknowledgement landed on this socket, in ms, or null when
|
|
55
|
+
* none ever has. A connection answering nothing and one merely behind
|
|
56
|
+
* look the same from a single op's age; this is what tells them apart.
|
|
57
|
+
*/
|
|
58
|
+
lastAckAgeMs: number | null;
|
|
59
|
+
/** Bytes on the socket against the transport's in-flight budget. */
|
|
60
|
+
inFlightBytes: number;
|
|
61
|
+
/** Ops too large for the socket, travelling over HTTP right now. */
|
|
62
|
+
httpOpsInFlight: number;
|
|
63
|
+
/** Rounds the durability handshake has spent reconciling. */
|
|
64
|
+
healRounds: number;
|
|
65
|
+
/** Whether the page is hidden, which throttles the client's timers. */
|
|
66
|
+
hidden: boolean;
|
|
67
|
+
}
|
|
22
68
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAI/B,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,UAAU,CAAC,EAAE,MAAM,CAAC;IAOpB,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAK1B,aAAa,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAI/B,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,UAAU,CAAC,EAAE,MAAM,CAAC;IAOpB,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAK1B,aAAa,CAAC,EAAE,aAAa,CAAC;IAM9B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAQpC,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,cAAc,CAAC,EAAE,MAAM,CAAC;IAOxB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAWD,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,CAAC;AAE1E,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;AAKlE,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAEnD,MAAM,WAAW,qBAAqB;IAGpC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,eAAe,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,MAAM,EAAE,OAAO,CAAC;CACjB"}
|
package/dist/undo.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type LoroDoc } from 'loro-crdt';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
2
|
+
import type { UndoControllerOptions } from './types.js';
|
|
3
|
+
export declare const PAGING_COMMIT_ORIGIN = "brass.paging";
|
|
5
4
|
export declare class UndoController {
|
|
6
5
|
private readonly _mgr;
|
|
7
6
|
private _groupOpen;
|
package/dist/undo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"undo.d.ts","sourceRoot":"","sources":["../src/undo.ts"],"names":[],"mappings":"AAIA,OAAO,EAAe,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"undo.d.ts","sourceRoot":"","sources":["../src/undo.ts"],"names":[],"mappings":"AAIA,OAAO,EAAe,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA2BxD,eAAO,MAAM,oBAAoB,iBAAiB,CAAC;AAInD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAc;IAOnC,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,qBAAqB;IAiB7D,IAAI,IAAI,OAAO;IAIf,IAAI,IAAI,OAAO;IAIf,OAAO,CAAC,YAAY;IAapB,OAAO,IAAI,OAAO;IAIlB,OAAO,IAAI,OAAO;IASlB,QAAQ,IAAI,IAAI;IAWhB,KAAK,IAAI,IAAI;IAYb,IAAI,IAAI,IAAI;CAWb"}
|
package/dist/undo.js
CHANGED
|
@@ -17,6 +17,16 @@ const UNDO_MERGE_INTERVAL_MS = 0;
|
|
|
17
17
|
// Cap on retained undo steps (Loro's default is 100). 200 at typical AEC
|
|
18
18
|
// entity sizes is a few hundred KB, well below anything that matters.
|
|
19
19
|
const DEFAULT_MAX_UNDO_STEPS = 200;
|
|
20
|
+
// Commit origin the paged marker (`meta.paged:<root>`) is stamped with, and
|
|
21
|
+
// the one origin the undo stack ignores.
|
|
22
|
+
//
|
|
23
|
+
// The marker says which shape a root's records are stored in, so it is a fact
|
|
24
|
+
// about the store rather than a step the reader took: undoing it leaves the
|
|
25
|
+
// pages the crossing mutation sealed behind a marker that says unpaged, which
|
|
26
|
+
// every reader answers by handing back the page entries themselves. The write
|
|
27
|
+
// that carries it therefore commits alone, so nothing an app authored is
|
|
28
|
+
// excluded alongside it.
|
|
29
|
+
export const PAGING_COMMIT_ORIGIN = 'brass.paging';
|
|
20
30
|
// Thin wrapper around Loro's UndoManager exposing only what the Document
|
|
21
31
|
// needs. Owned by the Document; not part of the public SDK surface.
|
|
22
32
|
export class UndoController {
|
|
@@ -32,6 +42,7 @@ export class UndoController {
|
|
|
32
42
|
this._mgr = new UndoManager(loroDoc, {
|
|
33
43
|
mergeInterval: UNDO_MERGE_INTERVAL_MS,
|
|
34
44
|
maxUndoSteps: options?.maxUndoSteps ?? DEFAULT_MAX_UNDO_STEPS,
|
|
45
|
+
excludeOriginPrefixes: [PAGING_COMMIT_ORIGIN],
|
|
35
46
|
});
|
|
36
47
|
// Open the implicit group so commits before the first `createCheckpoint`
|
|
37
48
|
// still bracket as one undo step.
|
package/dist/undo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"undo.js","sourceRoot":"","sources":["../src/undo.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,+EAA+E;AAC/E,4EAA4E;AAC5E,+CAA+C;AAC/C,OAAO,EAAE,WAAW,EAAgB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"undo.js","sourceRoot":"","sources":["../src/undo.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,+EAA+E;AAC/E,4EAA4E;AAC5E,+CAA+C;AAC/C,OAAO,EAAE,WAAW,EAAgB,MAAM,WAAW,CAAC;AAItD,6EAA6E;AAC7E,6EAA6E;AAC7E,0EAA0E;AAC1E,4EAA4E;AAC5E,sEAAsE;AACtE,6EAA6E;AAC7E,6EAA6E;AAC7E,4EAA4E;AAC5E,oEAAoE;AACpE,wEAAwE;AACxE,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAEjC,yEAAyE;AACzE,sEAAsE;AACtE,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC,4EAA4E;AAC5E,yCAAyC;AACzC,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,yEAAyE;AACzE,yBAAyB;AACzB,MAAM,CAAC,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAEnD,yEAAyE;AACzE,oEAAoE;AACpE,MAAM,OAAO,cAAc;IACR,IAAI,CAAc;IACnC,yEAAyE;IACzE,uEAAuE;IACvE,yEAAyE;IACzE,wEAAwE;IACxE,yEAAyE;IACzE,2DAA2D;IACnD,UAAU,GAAG,KAAK,CAAC;IAE3B,YAAY,OAAgB,EAAE,OAA+B;QAC3D,IAAI,CAAC,IAAI,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE;YACnC,aAAa,EAAE,sBAAsB;YACrC,YAAY,EAAE,OAAO,EAAE,YAAY,IAAI,sBAAsB;YAC7D,qBAAqB,EAAE,CAAC,oBAAoB,CAAC;SAC9C,CAAC,CAAC;QACH,yEAAyE;QACzE,kCAAkC;QAClC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,6EAA6E;IAC7E,6EAA6E;IAC7E,2EAA2E;IAC3E,0EAA0E;IAC1E,gEAAgE;IAChE,IAAI;QACF,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IAEO,YAAY,CAAC,EAAiB;QACpC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC;YACH,OAAO,EAAE,EAAE,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,0EAA0E;IAC1E,+DAA+D;IAC/D,0EAA0E;IAC1E,qEAAqE;IACrE,+DAA+D;IAC/D,QAAQ;QACN,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,8EAA8E;IAC9E,qCAAqC;IACrC,KAAK;QACH,yEAAyE;QACzE,gDAAgD;QAChD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC;gBACP,wDAAwD;YAC1D,CAAC;YACD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unload-guard.d.ts","sourceRoot":"","sources":["../src/unload-guard.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,YAAY;IAC3B,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3E,mBAAmB,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;CAC/E"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Native "leave site?" confirmation while a document holds ops the server
|
|
2
|
+
// has not acked. Reloading or navigating away drops those ops with the tab,
|
|
3
|
+
// so the browser's own prompt is the last point at which the writer can
|
|
4
|
+
// choose to stay.
|
|
5
|
+
//
|
|
6
|
+
// One registry rather than a listener per document: several documents can be
|
|
7
|
+
// open at once (and one the app has closed can still be parked in the SDK's
|
|
8
|
+
// cache with ops in flight), while the prompt is a property of the page. The
|
|
9
|
+
// registry keys on the owning Document so a count only ever leaves when that
|
|
10
|
+
// document acks its ops or closes, and the listener is attached only while
|
|
11
|
+
// the total is above zero. A permanently attached listener prompts on every
|
|
12
|
+
// navigation, which teaches readers to dismiss it.
|
|
13
|
+
const outstandingByOwner = new Map();
|
|
14
|
+
let handler = null;
|
|
15
|
+
// The target the handler is attached to, so a detach cannot go to a
|
|
16
|
+
// different one than the attach did.
|
|
17
|
+
let attachedTo = null;
|
|
18
|
+
// `undefined` means "resolve from the environment"; a test overrides it with
|
|
19
|
+
// a fake target, or with `null` to stand in for a non-browser host.
|
|
20
|
+
let targetOverride;
|
|
21
|
+
function resolveTarget() {
|
|
22
|
+
if (targetOverride !== undefined)
|
|
23
|
+
return targetOverride;
|
|
24
|
+
const candidate = globalThis.window;
|
|
25
|
+
if (typeof candidate !== 'object' || candidate === null)
|
|
26
|
+
return null;
|
|
27
|
+
const target = candidate;
|
|
28
|
+
if (typeof target.addEventListener !== 'function')
|
|
29
|
+
return null;
|
|
30
|
+
if (typeof target.removeEventListener !== 'function')
|
|
31
|
+
return null;
|
|
32
|
+
return target;
|
|
33
|
+
}
|
|
34
|
+
function sync() {
|
|
35
|
+
let total = 0;
|
|
36
|
+
for (const count of outstandingByOwner.values())
|
|
37
|
+
total += count;
|
|
38
|
+
if (total === 0) {
|
|
39
|
+
if (handler && attachedTo) {
|
|
40
|
+
attachedTo.removeEventListener('beforeunload', handler);
|
|
41
|
+
}
|
|
42
|
+
handler = null;
|
|
43
|
+
attachedTo = null;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (handler)
|
|
47
|
+
return;
|
|
48
|
+
const target = resolveTarget();
|
|
49
|
+
if (!target)
|
|
50
|
+
return;
|
|
51
|
+
handler = (e) => {
|
|
52
|
+
// `preventDefault` is the whole signal. Browsers show their own wording
|
|
53
|
+
// and ignore anything the handler returns or assigns.
|
|
54
|
+
e.preventDefault();
|
|
55
|
+
};
|
|
56
|
+
attachedTo = target;
|
|
57
|
+
target.addEventListener('beforeunload', handler);
|
|
58
|
+
}
|
|
59
|
+
// Report how many un-acked ops `owner` holds. Zero forgets it.
|
|
60
|
+
/** @internal */
|
|
61
|
+
export function trackUnsavedWork(owner, count) {
|
|
62
|
+
if (count > 0)
|
|
63
|
+
outstandingByOwner.set(owner, count);
|
|
64
|
+
else
|
|
65
|
+
outstandingByOwner.delete(owner);
|
|
66
|
+
sync();
|
|
67
|
+
}
|
|
68
|
+
// Forget `owner` entirely, whatever it last reported. Called from
|
|
69
|
+
// `Document.close()`, where the ops go away with the document.
|
|
70
|
+
/** @internal */
|
|
71
|
+
export function releaseUnsavedWork(owner) {
|
|
72
|
+
if (!outstandingByOwner.delete(owner))
|
|
73
|
+
return;
|
|
74
|
+
sync();
|
|
75
|
+
}
|
|
76
|
+
// Point the guard at a fake target and drop every tracked owner, so one
|
|
77
|
+
// test's documents cannot hold the listener open across the next.
|
|
78
|
+
/** @internal */
|
|
79
|
+
export function _setUnloadTargetForTesting(target) {
|
|
80
|
+
if (handler && attachedTo) {
|
|
81
|
+
attachedTo.removeEventListener('beforeunload', handler);
|
|
82
|
+
}
|
|
83
|
+
handler = null;
|
|
84
|
+
attachedTo = null;
|
|
85
|
+
outstandingByOwner.clear();
|
|
86
|
+
targetOverride = target;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=unload-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unload-guard.js","sourceRoot":"","sources":["../src/unload-guard.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,4EAA4E;AAC5E,wEAAwE;AACxE,kBAAkB;AAClB,EAAE;AACF,6EAA6E;AAC7E,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,2EAA2E;AAC3E,4EAA4E;AAC5E,mDAAmD;AAOnD,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAC;AACrD,IAAI,OAAO,GAAgC,IAAI,CAAC;AAChD,oEAAoE;AACpE,qCAAqC;AACrC,IAAI,UAAU,GAAwB,IAAI,CAAC;AAC3C,6EAA6E;AAC7E,oEAAoE;AACpE,IAAI,cAA+C,CAAC;AAEpD,SAAS,aAAa;IACpB,IAAI,cAAc,KAAK,SAAS;QAAE,OAAO,cAAc,CAAC;IACxD,MAAM,SAAS,GAAI,UAAmC,CAAC,MAAM,CAAC;IAC9D,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACrE,MAAM,MAAM,GAAG,SAAkC,CAAC;IAClD,IAAI,OAAO,MAAM,CAAC,gBAAgB,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAC/D,IAAI,OAAO,MAAM,CAAC,mBAAmB,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAClE,OAAO,MAAsB,CAAC;AAChC,CAAC;AAED,SAAS,IAAI;IACX,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,kBAAkB,CAAC,MAAM,EAAE;QAAE,KAAK,IAAI,KAAK,CAAC;IAEhE,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;YAC1B,UAAU,CAAC,mBAAmB,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;QACf,UAAU,GAAG,IAAI,CAAC;QAClB,OAAO;IACT,CAAC;IACD,IAAI,OAAO;QAAE,OAAO;IACpB,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,OAAO,GAAG,CAAC,CAAQ,EAAQ,EAAE;QAC3B,wEAAwE;QACxE,sDAAsD;QACtD,CAAC,CAAC,cAAc,EAAE,CAAC;IACrB,CAAC,CAAC;IACF,UAAU,GAAG,MAAM,CAAC;IACpB,MAAM,CAAC,gBAAgB,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC;AAED,+DAA+D;AAC/D,gBAAgB;AAChB,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,KAAa;IAC3D,IAAI,KAAK,GAAG,CAAC;QAAE,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;;QAC/C,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,EAAE,CAAC;AACT,CAAC;AAED,kEAAkE;AAClE,+DAA+D;AAC/D,gBAAgB;AAChB,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC;QAAE,OAAO;IAC9C,IAAI,EAAE,CAAC;AACT,CAAC;AAED,wEAAwE;AACxE,kEAAkE;AAClE,gBAAgB;AAChB,MAAM,UAAU,0BAA0B,CACxC,MAAuC;IAEvC,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;QAC1B,UAAU,CAAC,mBAAmB,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,GAAG,IAAI,CAAC;IACf,UAAU,GAAG,IAAI,CAAC;IAClB,kBAAkB,CAAC,KAAK,EAAE,CAAC;IAC3B,cAAc,GAAG,MAAM,CAAC;AAC1B,CAAC"}
|
package/dist/version-bar.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export interface VersionBarDeps {
|
|
2
2
|
dashboardBaseUrl: string;
|
|
3
3
|
theme?: 'light' | 'dark' | 'auto';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
returnToHead: () => void;
|
|
4
|
+
checkoutVersion: (version: number) => Promise<void>;
|
|
5
|
+
returnToHead: () => Promise<void>;
|
|
7
6
|
fork: (fromVersion: number, name?: string) => void;
|
|
8
7
|
browse: () => void;
|
|
8
|
+
currentVersion: () => number | null;
|
|
9
9
|
close: () => void;
|
|
10
10
|
}
|
|
11
11
|
export interface VersionBarContext {
|
|
@@ -13,6 +13,7 @@ export interface VersionBarContext {
|
|
|
13
13
|
branch: string | undefined;
|
|
14
14
|
version: number | null;
|
|
15
15
|
branchName?: string | undefined;
|
|
16
|
+
pinned?: boolean;
|
|
16
17
|
}
|
|
17
18
|
export interface VersionBarFrame {
|
|
18
19
|
update(ctx: VersionBarContext): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-bar.d.ts","sourceRoot":"","sources":["../src/version-bar.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"version-bar.d.ts","sourceRoot":"","sources":["../src/version-bar.ts"],"names":[],"mappings":"AAmCA,MAAM,WAAW,cAAc;IAG7B,gBAAgB,EAAE,MAAM,CAAC;IAEzB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAIlC,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,MAAM,EAAE,MAAM,IAAI,CAAC;IAInB,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAIpC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAG3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAGvB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAIhC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAI9B,MAAM,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACrC,OAAO,IAAI,IAAI,CAAC;CACjB;AAWD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE,cAAc,GACnB,eAAe,CA4RjB"}
|