@brass-build/client 0.4.1 → 0.5.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 +124 -45
- package/CHANGELOG.md +80 -4
- package/README.md +666 -179
- package/dist/api-fetch.d.ts +8 -0
- package/dist/api-fetch.d.ts.map +1 -1
- package/dist/api-fetch.js +35 -8
- package/dist/api-fetch.js.map +1 -1
- package/dist/batched-get.d.ts +11 -0
- package/dist/batched-get.d.ts.map +1 -0
- package/dist/batched-get.js +92 -0
- package/dist/batched-get.js.map +1 -0
- package/dist/call-service.d.ts +4 -0
- package/dist/call-service.d.ts.map +1 -1
- package/dist/call-service.js +66 -3
- package/dist/call-service.js.map +1 -1
- package/dist/client.d.ts +48 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +918 -115
- package/dist/client.js.map +1 -1
- package/dist/document-checkpoints.d.ts +25 -2
- package/dist/document-checkpoints.d.ts.map +1 -1
- package/dist/document-checkpoints.js +258 -61
- package/dist/document-checkpoints.js.map +1 -1
- package/dist/document-commands.d.ts.map +1 -1
- package/dist/document-commands.js +5 -3
- package/dist/document-commands.js.map +1 -1
- package/dist/document-contents.d.ts +10 -0
- package/dist/document-contents.d.ts.map +1 -1
- package/dist/document-contents.js +23 -1
- package/dist/document-contents.js.map +1 -1
- package/dist/document-set-subscription.d.ts +56 -0
- package/dist/document-set-subscription.d.ts.map +1 -0
- package/dist/document-set-subscription.js +240 -0
- package/dist/document-set-subscription.js.map +1 -0
- package/dist/document-signals.d.ts +6 -0
- package/dist/document-signals.d.ts.map +1 -1
- package/dist/document-signals.js +31 -1
- package/dist/document-signals.js.map +1 -1
- package/dist/document-streams.d.ts +36 -2
- package/dist/document-streams.d.ts.map +1 -1
- package/dist/document-streams.js +69 -18
- package/dist/document-streams.js.map +1 -1
- package/dist/document-thumbnail-capture.d.ts +12 -2
- package/dist/document-thumbnail-capture.d.ts.map +1 -1
- package/dist/document-thumbnail-capture.js +103 -27
- package/dist/document-thumbnail-capture.js.map +1 -1
- package/dist/documents-namespace.d.ts +92 -10
- package/dist/documents-namespace.d.ts.map +1 -1
- package/dist/documents-namespace.js +285 -39
- package/dist/documents-namespace.js.map +1 -1
- package/dist/documents.d.ts +173 -8
- package/dist/documents.d.ts.map +1 -1
- package/dist/documents.js +1778 -310
- package/dist/documents.js.map +1 -1
- package/dist/errors.d.ts +3 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/fetch-retry.d.ts +1 -0
- package/dist/fetch-retry.d.ts.map +1 -1
- package/dist/fetch-retry.js +2 -0
- package/dist/fetch-retry.js.map +1 -1
- package/dist/file-choice.d.ts +2 -0
- package/dist/file-choice.d.ts.map +1 -0
- package/dist/file-choice.js +27 -0
- package/dist/file-choice.js.map +1 -0
- package/dist/guest-link.d.ts +18 -1
- package/dist/guest-link.d.ts.map +1 -1
- package/dist/guest-link.js +329 -1
- package/dist/guest-link.js.map +1 -1
- package/dist/handle-types.d.ts +67 -5
- package/dist/handle-types.d.ts.map +1 -1
- package/dist/handles.d.ts +15 -19
- package/dist/handles.d.ts.map +1 -1
- package/dist/handles.js +231 -76
- package/dist/handles.js.map +1 -1
- package/dist/hosted-ui.d.ts +61 -0
- package/dist/hosted-ui.d.ts.map +1 -1
- package/dist/hosted-ui.js +94 -42
- package/dist/hosted-ui.js.map +1 -1
- package/dist/import-contract.d.ts +74 -0
- package/dist/import-contract.d.ts.map +1 -0
- package/dist/import-contract.js +163 -0
- package/dist/import-contract.js.map +1 -0
- package/dist/import-guest.d.ts +9 -0
- package/dist/import-guest.d.ts.map +1 -0
- package/dist/import-guest.js +155 -0
- package/dist/import-guest.js.map +1 -0
- package/dist/import-report.d.ts +17 -0
- package/dist/import-report.d.ts.map +1 -0
- package/dist/import-report.js +7 -0
- package/dist/import-report.js.map +1 -0
- package/dist/importer-wait.d.ts +2 -0
- package/dist/importer-wait.d.ts.map +1 -0
- package/dist/importer-wait.js +5 -0
- package/dist/importer-wait.js.map +1 -0
- package/dist/importer.d.ts +18 -4
- package/dist/importer.d.ts.map +1 -1
- package/dist/importer.js +322 -105
- package/dist/importer.js.map +1 -1
- package/dist/in-development.d.ts +2 -0
- package/dist/in-development.d.ts.map +1 -0
- package/dist/in-development.js +10 -0
- package/dist/in-development.js.map +1 -0
- package/dist/index.d.ts +16 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -8
- package/dist/index.js.map +1 -1
- package/dist/init-keys.d.ts +1 -1
- package/dist/init-keys.d.ts.map +1 -1
- package/dist/init-keys.js +6 -1
- package/dist/init-keys.js.map +1 -1
- package/dist/input-documents.d.ts +67 -0
- package/dist/input-documents.d.ts.map +1 -0
- package/dist/input-documents.js +693 -0
- package/dist/input-documents.js.map +1 -0
- package/dist/inputs-status.d.ts +80 -0
- package/dist/inputs-status.d.ts.map +1 -0
- package/dist/inputs-status.js +460 -0
- package/dist/inputs-status.js.map +1 -0
- package/dist/inputs.d.ts +2 -0
- package/dist/inputs.d.ts.map +1 -0
- package/dist/inputs.js +793 -0
- package/dist/inputs.js.map +1 -0
- package/dist/internal.d.ts +6 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +4 -1
- package/dist/internal.js.map +1 -1
- package/dist/join-content.d.ts +33 -0
- package/dist/join-content.d.ts.map +1 -0
- package/dist/join-content.js +114 -0
- package/dist/join-content.js.map +1 -0
- package/dist/join-stamp.d.ts +3 -0
- package/dist/join-stamp.d.ts.map +1 -0
- package/dist/join-stamp.js +12 -0
- package/dist/join-stamp.js.map +1 -0
- package/dist/manifest-drift.d.ts +9 -0
- package/dist/manifest-drift.d.ts.map +1 -0
- package/dist/manifest-drift.js +46 -0
- package/dist/manifest-drift.js.map +1 -0
- package/dist/open-document.d.ts +109 -2
- package/dist/open-document.d.ts.map +1 -1
- package/dist/open-document.js +1822 -811
- package/dist/open-document.js.map +1 -1
- package/dist/page-restore.d.ts +12 -0
- package/dist/page-restore.d.ts.map +1 -0
- package/dist/page-restore.js +23 -0
- package/dist/page-restore.js.map +1 -0
- package/dist/placement.d.ts +13 -0
- package/dist/placement.d.ts.map +1 -0
- package/dist/placement.js +34 -0
- package/dist/placement.js.map +1 -0
- package/dist/presence.d.ts +1 -0
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js +16 -4
- package/dist/presence.js.map +1 -1
- package/dist/read-only-document.d.ts +87 -0
- package/dist/read-only-document.d.ts.map +1 -0
- package/dist/read-only-document.js +4 -0
- package/dist/read-only-document.js.map +1 -0
- package/dist/record-paging.d.ts +63 -6
- package/dist/record-paging.d.ts.map +1 -1
- package/dist/record-paging.js +122 -29
- package/dist/record-paging.js.map +1 -1
- package/dist/references.d.ts +40 -0
- package/dist/references.d.ts.map +1 -0
- package/dist/references.js +135 -0
- package/dist/references.js.map +1 -0
- package/dist/request-lane.d.ts +5 -0
- package/dist/request-lane.d.ts.map +1 -0
- package/dist/request-lane.js +48 -0
- package/dist/request-lane.js.map +1 -0
- package/dist/sealed-arrow.d.ts +170 -0
- package/dist/sealed-arrow.d.ts.map +1 -0
- package/dist/sealed-arrow.js +769 -0
- package/dist/sealed-arrow.js.map +1 -0
- package/dist/sealed-cache.d.ts +21 -0
- package/dist/sealed-cache.d.ts.map +1 -0
- package/dist/sealed-cache.js +247 -0
- package/dist/sealed-cache.js.map +1 -0
- package/dist/sealed-encode.d.ts +87 -0
- package/dist/sealed-encode.d.ts.map +1 -0
- package/dist/sealed-encode.js +876 -0
- package/dist/sealed-encode.js.map +1 -0
- package/dist/sealed-handles.d.ts +45 -0
- package/dist/sealed-handles.d.ts.map +1 -0
- package/dist/sealed-handles.js +408 -0
- package/dist/sealed-handles.js.map +1 -0
- package/dist/sealed-store.d.ts +242 -0
- package/dist/sealed-store.d.ts.map +1 -0
- package/dist/sealed-store.js +1155 -0
- package/dist/sealed-store.js.map +1 -0
- package/dist/serializer.d.ts +6 -15
- package/dist/serializer.d.ts.map +1 -1
- package/dist/session-toolbar.d.ts +20 -5
- package/dist/session-toolbar.d.ts.map +1 -1
- package/dist/session-toolbar.js +419 -67
- package/dist/session-toolbar.js.map +1 -1
- package/dist/session.d.ts +38 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +562 -79
- package/dist/session.js.map +1 -1
- package/dist/sha256.d.ts +3 -0
- package/dist/sha256.d.ts.map +1 -0
- package/dist/sha256.js +74 -0
- package/dist/sha256.js.map +1 -0
- package/dist/stable-handles.d.ts +19 -0
- package/dist/stable-handles.d.ts.map +1 -0
- package/dist/stable-handles.js +193 -0
- package/dist/stable-handles.js.map +1 -0
- package/dist/staged-seal.d.ts +2 -0
- package/dist/staged-seal.d.ts.map +1 -0
- package/dist/staged-seal.js +76 -0
- package/dist/staged-seal.js.map +1 -0
- package/dist/subscriber-delivery.d.ts +8 -0
- package/dist/subscriber-delivery.d.ts.map +1 -0
- package/dist/subscriber-delivery.js +31 -0
- package/dist/subscriber-delivery.js.map +1 -0
- package/dist/tail-op-import.d.ts +10 -0
- package/dist/tail-op-import.d.ts.map +1 -0
- package/dist/tail-op-import.js +33 -0
- package/dist/tail-op-import.js.map +1 -0
- package/dist/topic-lifecycle.d.ts +6 -0
- package/dist/topic-lifecycle.d.ts.map +1 -1
- package/dist/topic-lifecycle.js +32 -2
- package/dist/topic-lifecycle.js.map +1 -1
- package/dist/trial-replace-dialog.d.ts +10 -0
- package/dist/trial-replace-dialog.d.ts.map +1 -0
- package/dist/trial-replace-dialog.js +153 -0
- package/dist/trial-replace-dialog.js.map +1 -0
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/undo.d.ts +60 -5
- package/dist/undo.d.ts.map +1 -1
- package/dist/undo.js +344 -75
- package/dist/undo.js.map +1 -1
- package/dist/version-bar.d.ts +1 -0
- package/dist/version-bar.d.ts.map +1 -1
- package/dist/version-bar.js +2 -1
- package/dist/version-bar.js.map +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/dist/ws-client.d.ts +21 -0
- package/dist/ws-client.d.ts.map +1 -1
- package/dist/ws-client.js +192 -8
- package/dist/ws-client.js.map +1 -1
- package/dist/ws-frame-limit.d.ts +1 -0
- package/dist/ws-frame-limit.d.ts.map +1 -1
- package/dist/ws-frame-limit.js.map +1 -1
- package/docs/app-manifest.md +121 -17
- package/docs/custom-chrome.md +24 -16
- package/docs/hosted-ui-advanced.md +38 -6
- package/docs/imported-documents.md +104 -51
- package/docs/presence.md +16 -4
- package/docs/schemas.md +8 -5
- package/docs/services.md +6 -6
- package/docs/streams.md +139 -150
- package/docs/text-fields.md +26 -19
- package/package.json +5 -2
- package/src/api-fetch.ts +53 -3
- package/src/auth-flow.ts +1 -1
- package/src/batched-get.ts +117 -0
- package/src/call-service.ts +78 -3
- package/src/client.ts +1022 -112
- package/src/document-checkpoints.ts +307 -65
- package/src/document-commands.ts +5 -5
- package/src/document-contents.ts +27 -1
- package/src/document-set-subscription.ts +274 -0
- package/src/document-signals.ts +47 -5
- package/src/document-streams.ts +85 -16
- package/src/document-thumbnail-capture.ts +118 -32
- package/src/documents-namespace.ts +539 -84
- package/src/documents.ts +2017 -348
- package/src/errors.ts +17 -6
- package/src/fetch-retry.ts +5 -0
- package/src/file-choice.ts +26 -0
- package/src/guest-link.ts +362 -1
- package/src/handle-types.ts +73 -47
- package/src/handles.ts +253 -83
- package/src/hosted-ui.ts +211 -50
- package/src/import-contract.ts +227 -0
- package/src/import-guest.ts +193 -0
- package/src/import-report.ts +24 -0
- package/src/importer-wait.ts +4 -0
- package/src/importer.ts +386 -131
- package/src/in-development.ts +10 -0
- package/src/index.ts +76 -16
- package/src/init-keys.ts +6 -1
- package/src/input-documents.ts +819 -0
- package/src/inputs-status.ts +598 -0
- package/src/inputs.ts +1090 -0
- package/src/internal.ts +7 -0
- package/src/join-content.ts +135 -0
- package/src/join-stamp.ts +12 -0
- package/src/manifest-drift.ts +54 -0
- package/src/open-document.ts +2346 -930
- package/src/page-restore.ts +38 -0
- package/src/placement.ts +54 -0
- package/src/presence.ts +21 -5
- package/src/read-only-document.ts +133 -0
- package/src/record-paging.ts +147 -25
- package/src/references.ts +207 -0
- package/src/request-lane.ts +59 -0
- package/src/sealed-arrow.ts +843 -0
- package/src/sealed-cache.ts +267 -0
- package/src/sealed-encode.ts +1015 -0
- package/src/sealed-handles.ts +486 -0
- package/src/sealed-store.ts +1330 -0
- package/src/serializer.ts +8 -20
- package/src/session-toolbar.ts +463 -72
- package/src/session.ts +740 -99
- package/src/sha256.ts +65 -0
- package/src/stable-handles.ts +235 -0
- package/src/staged-seal.ts +90 -0
- package/src/subscriber-delivery.ts +37 -0
- package/src/tail-op-import.ts +30 -0
- package/src/topic-lifecycle.ts +38 -2
- package/src/trial-replace-dialog.ts +163 -0
- package/src/types.ts +6 -6
- package/src/undo.ts +386 -73
- package/src/version-bar.ts +5 -1
- package/src/version.ts +1 -1
- package/src/ws-client.ts +208 -16
- package/src/ws-frame-limit.ts +1 -0
package/dist/guest-link.js
CHANGED
|
@@ -5,9 +5,337 @@
|
|
|
5
5
|
//
|
|
6
6
|
// Pure + search-string-in so it stays testable, mirroring
|
|
7
7
|
// `isExportMode(search)`.
|
|
8
|
-
|
|
8
|
+
const GUEST_LINK_PARAM = 'brass_link';
|
|
9
9
|
export function readGuestLinkToken(search) {
|
|
10
10
|
const value = new URLSearchParams(search).get(GUEST_LINK_PARAM);
|
|
11
11
|
return value && value.trim() !== '' ? value : null;
|
|
12
12
|
}
|
|
13
|
+
// Pin the token into the page URL (`replaceState`, never a history entry):
|
|
14
|
+
// a document created while signed out is reached again only through its
|
|
15
|
+
// token, so a reload restores it from here, and `signIn()` carries this URL
|
|
16
|
+
// as its return address.
|
|
17
|
+
export function writeGuestLinkToken(token) {
|
|
18
|
+
if (typeof window === 'undefined')
|
|
19
|
+
return;
|
|
20
|
+
try {
|
|
21
|
+
const url = new URL(window.location.href);
|
|
22
|
+
url.searchParams.set(GUEST_LINK_PARAM, token);
|
|
23
|
+
const next = url.toString();
|
|
24
|
+
if (next === window.location.href)
|
|
25
|
+
return;
|
|
26
|
+
window.history.replaceState(window.history.state, '', next);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// History API unavailable or URL exotic: leave the URL alone.
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function clearGuestLinkToken() {
|
|
33
|
+
if (typeof window === 'undefined')
|
|
34
|
+
return;
|
|
35
|
+
try {
|
|
36
|
+
const url = new URL(window.location.href);
|
|
37
|
+
if (!url.searchParams.has(GUEST_LINK_PARAM))
|
|
38
|
+
return;
|
|
39
|
+
url.searchParams.delete(GUEST_LINK_PARAM);
|
|
40
|
+
window.history.replaceState(window.history.state, '', url.toString());
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// See `writeGuestLinkToken`.
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// The last document a visitor created without an account, per app. The URL
|
|
47
|
+
// is that document's only handle, so a visitor who closes the tab and comes
|
|
48
|
+
// back to the app's root would have no way back to it; the app's signed-out
|
|
49
|
+
// gate offers it from here. localStorage, since the return is in a new tab.
|
|
50
|
+
// The expiry is stored beside the token so the gate can say when the work
|
|
51
|
+
// is lost without a request, and an entry past it reads as absent.
|
|
52
|
+
//
|
|
53
|
+
// The token is a credential to an editable document, which is why the
|
|
54
|
+
// session hands an app the expiry alone and opens the document itself.
|
|
55
|
+
const UNSAVED_KEY_PREFIX = 'brass:unsaved:';
|
|
56
|
+
function unsavedStorage() {
|
|
57
|
+
if (typeof localStorage === 'undefined')
|
|
58
|
+
return null;
|
|
59
|
+
try {
|
|
60
|
+
return localStorage;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function unsavedKey(appId) {
|
|
67
|
+
return `${UNSAVED_KEY_PREFIX}${appId}`;
|
|
68
|
+
}
|
|
69
|
+
export function storeUnsavedWork(appId, token, expiresAt) {
|
|
70
|
+
const storage = unsavedStorage();
|
|
71
|
+
if (!storage)
|
|
72
|
+
return;
|
|
73
|
+
try {
|
|
74
|
+
storage.setItem(unsavedKey(appId), JSON.stringify({ token, expires_at: expiresAt.toISOString() }));
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Quota / disabled storage. The way back is a niceness; the open that
|
|
78
|
+
// just succeeded must not fail on it.
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export function readUnsavedWork(appId, now = Date.now()) {
|
|
82
|
+
const storage = unsavedStorage();
|
|
83
|
+
if (!storage)
|
|
84
|
+
return null;
|
|
85
|
+
let raw;
|
|
86
|
+
try {
|
|
87
|
+
raw = storage.getItem(unsavedKey(appId));
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
if (raw === null)
|
|
93
|
+
return null;
|
|
94
|
+
let parsed;
|
|
95
|
+
try {
|
|
96
|
+
parsed = JSON.parse(raw);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
const entry = parsed;
|
|
102
|
+
const expiresAt = typeof entry?.expires_at === 'string' ? new Date(entry.expires_at) : null;
|
|
103
|
+
if (typeof entry?.token !== 'string' ||
|
|
104
|
+
entry.token === '' ||
|
|
105
|
+
expiresAt === null ||
|
|
106
|
+
Number.isNaN(expiresAt.getTime())) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
// The platform removes the document at the expiry, so an entry past it
|
|
110
|
+
// names nothing and is dropped here rather than offered.
|
|
111
|
+
if (expiresAt.getTime() <= now) {
|
|
112
|
+
clearUnsavedWork(appId);
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
return { token: entry.token, expiresAt };
|
|
116
|
+
}
|
|
117
|
+
export function clearUnsavedWork(appId) {
|
|
118
|
+
const storage = unsavedStorage();
|
|
119
|
+
if (!storage)
|
|
120
|
+
return;
|
|
121
|
+
try {
|
|
122
|
+
storage.removeItem(unsavedKey(appId));
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// See `storeUnsavedWork`.
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Whether this browser has edited a document it made without an account. New
|
|
129
|
+
// and Upload ask before replacing one, so the marker outlives a reload; it
|
|
130
|
+
// carries the document's expiry so an entry past it is dropped on read.
|
|
131
|
+
const EDITED_KEY_PREFIX = 'brass:trial-edited:';
|
|
132
|
+
export function markTrialEdited(token, expiresAt) {
|
|
133
|
+
const storage = unsavedStorage();
|
|
134
|
+
if (!storage)
|
|
135
|
+
return;
|
|
136
|
+
try {
|
|
137
|
+
storage.setItem(`${EDITED_KEY_PREFIX}${token}`, expiresAt.toISOString());
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// See `storeUnsavedWork`.
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export function trialWasEdited(token, now = Date.now()) {
|
|
144
|
+
const storage = unsavedStorage();
|
|
145
|
+
if (!storage)
|
|
146
|
+
return false;
|
|
147
|
+
let raw;
|
|
148
|
+
try {
|
|
149
|
+
raw = storage.getItem(`${EDITED_KEY_PREFIX}${token}`);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
if (raw === null)
|
|
155
|
+
return false;
|
|
156
|
+
const expiresAt = Date.parse(raw);
|
|
157
|
+
if (Number.isNaN(expiresAt) || expiresAt <= now) {
|
|
158
|
+
try {
|
|
159
|
+
storage.removeItem(`${EDITED_KEY_PREFIX}${token}`);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// See `storeUnsavedWork`.
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
// The claim secret the mint handed this browser, one per document, keyed by
|
|
169
|
+
// the app and the document's link token. Only the browser that made the
|
|
170
|
+
// document has one, so a sign-in here keeps the document and a sign-in
|
|
171
|
+
// wherever its link was shared does not. Written at the mint alone, so opening
|
|
172
|
+
// a shared link leaves it alone. Every mint prunes the secrets whose document
|
|
173
|
+
// has expired, since nothing else removes the secret of a document nobody
|
|
174
|
+
// came back to.
|
|
175
|
+
const CLAIM_KEY_PREFIX = 'brass:claim:';
|
|
176
|
+
function claimKey(appId, token) {
|
|
177
|
+
return `${CLAIM_KEY_PREFIX}${appId}:${token}`;
|
|
178
|
+
}
|
|
179
|
+
// Collected before any removal, since removing a key renumbers the rest.
|
|
180
|
+
function claimKeys(storage, prefix) {
|
|
181
|
+
const keys = [];
|
|
182
|
+
try {
|
|
183
|
+
for (let i = 0; i < storage.length; i++) {
|
|
184
|
+
const key = storage.key(i);
|
|
185
|
+
if (key !== null && key.startsWith(prefix))
|
|
186
|
+
keys.push(key);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
// See `storeUnsavedWork`.
|
|
191
|
+
}
|
|
192
|
+
return keys;
|
|
193
|
+
}
|
|
194
|
+
function readClaimEntry(storage, key, now) {
|
|
195
|
+
let entry;
|
|
196
|
+
try {
|
|
197
|
+
entry = JSON.parse(storage.getItem(key) ?? 'null');
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
entry = null;
|
|
201
|
+
}
|
|
202
|
+
const expiresAt = typeof entry?.expires_at === 'string' ? Date.parse(entry.expires_at) : NaN;
|
|
203
|
+
if (typeof entry?.secret !== 'string' || Number.isNaN(expiresAt) || expiresAt <= now) {
|
|
204
|
+
try {
|
|
205
|
+
storage.removeItem(key);
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
// See `storeUnsavedWork`.
|
|
209
|
+
}
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
return entry.secret;
|
|
213
|
+
}
|
|
214
|
+
function pruneClaimSecrets(storage, now) {
|
|
215
|
+
for (const key of claimKeys(storage, CLAIM_KEY_PREFIX))
|
|
216
|
+
readClaimEntry(storage, key, now);
|
|
217
|
+
}
|
|
218
|
+
export function storeClaimSecret(appId, token, secret, expiresAt, now = Date.now()) {
|
|
219
|
+
const storage = unsavedStorage();
|
|
220
|
+
if (!storage)
|
|
221
|
+
return;
|
|
222
|
+
pruneClaimSecrets(storage, now);
|
|
223
|
+
try {
|
|
224
|
+
storage.setItem(claimKey(appId, token), JSON.stringify({ secret, expires_at: expiresAt.toISOString() }));
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// See `storeUnsavedWork`.
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
export function readClaimSecret(appId, token, now = Date.now()) {
|
|
231
|
+
const storage = unsavedStorage();
|
|
232
|
+
if (!storage)
|
|
233
|
+
return null;
|
|
234
|
+
return readClaimEntry(storage, claimKey(appId, token), now);
|
|
235
|
+
}
|
|
236
|
+
// One document's secret, or with no token every secret this browser holds
|
|
237
|
+
// for the app.
|
|
238
|
+
export function clearClaimSecret(appId, token) {
|
|
239
|
+
const storage = unsavedStorage();
|
|
240
|
+
if (!storage)
|
|
241
|
+
return;
|
|
242
|
+
const keys = token === undefined
|
|
243
|
+
? claimKeys(storage, `${CLAIM_KEY_PREFIX}${appId}:`)
|
|
244
|
+
: [claimKey(appId, token)];
|
|
245
|
+
for (const key of keys) {
|
|
246
|
+
try {
|
|
247
|
+
storage.removeItem(key);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// See `storeUnsavedWork`.
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// That this tab started a sign-in from a guest page, and on which token. Per
|
|
255
|
+
// tab (sessionStorage), written by `signIn()` and taken once on the return,
|
|
256
|
+
// so a URL carrying `brass_code` that this tab did not ask for claims nothing.
|
|
257
|
+
const SIGN_IN_INTENT_PREFIX = 'brass:claim-intent:';
|
|
258
|
+
function tabStorage() {
|
|
259
|
+
if (typeof sessionStorage === 'undefined')
|
|
260
|
+
return null;
|
|
261
|
+
try {
|
|
262
|
+
return sessionStorage;
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
export function markClaimIntent(appId, token) {
|
|
269
|
+
try {
|
|
270
|
+
tabStorage()?.setItem(`${SIGN_IN_INTENT_PREFIX}${appId}`, token);
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
// See `storeUnsavedWork`.
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
export function takeClaimIntent(appId) {
|
|
277
|
+
const storage = tabStorage();
|
|
278
|
+
if (!storage)
|
|
279
|
+
return null;
|
|
280
|
+
try {
|
|
281
|
+
const token = storage.getItem(`${SIGN_IN_INTENT_PREFIX}${appId}`);
|
|
282
|
+
storage.removeItem(`${SIGN_IN_INTENT_PREFIX}${appId}`);
|
|
283
|
+
return token;
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// The documents this browser claimed, per app, by the mint link each claim
|
|
290
|
+
// revoked. Reading that link again answers 410 for everyone, and a page that
|
|
291
|
+
// holds no session cannot ask the platform where it leads, so this is how a
|
|
292
|
+
// signed-out page on it knows to offer sign-in to the document instead. It
|
|
293
|
+
// confers no access (the open after sign-in is checked like any other), so a
|
|
294
|
+
// sign-out keeps it. Entries lapse after `CLAIMED_LINK_TTL_MS`.
|
|
295
|
+
const CLAIMED_KEY_PREFIX = 'brass:claimed:';
|
|
296
|
+
const CLAIMED_LINK_TTL_MS = 30 * 24 * 60 * 60 * 1000;
|
|
297
|
+
function claimedKey(appId, token) {
|
|
298
|
+
return `${CLAIMED_KEY_PREFIX}${appId}:${token}`;
|
|
299
|
+
}
|
|
300
|
+
function readClaimedEntry(storage, key, now) {
|
|
301
|
+
let entry;
|
|
302
|
+
try {
|
|
303
|
+
entry = JSON.parse(storage.getItem(key) ?? 'null');
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
entry = null;
|
|
307
|
+
}
|
|
308
|
+
const claimedAt = typeof entry?.claimed_at === 'number' ? entry.claimed_at : NaN;
|
|
309
|
+
if (typeof entry?.doc_id !== 'string' ||
|
|
310
|
+
Number.isNaN(claimedAt) ||
|
|
311
|
+
claimedAt + CLAIMED_LINK_TTL_MS <= now) {
|
|
312
|
+
try {
|
|
313
|
+
storage.removeItem(key);
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
// See `storeUnsavedWork`.
|
|
317
|
+
}
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
return entry.doc_id;
|
|
321
|
+
}
|
|
322
|
+
export function storeClaimedLink(appId, token, docId, now = Date.now()) {
|
|
323
|
+
const storage = unsavedStorage();
|
|
324
|
+
if (!storage)
|
|
325
|
+
return;
|
|
326
|
+
for (const key of claimKeys(storage, CLAIMED_KEY_PREFIX))
|
|
327
|
+
readClaimedEntry(storage, key, now);
|
|
328
|
+
try {
|
|
329
|
+
storage.setItem(claimedKey(appId, token), JSON.stringify({ doc_id: docId, claimed_at: now }));
|
|
330
|
+
}
|
|
331
|
+
catch {
|
|
332
|
+
// See `storeUnsavedWork`.
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
export function readClaimedLink(appId, token, now = Date.now()) {
|
|
336
|
+
const storage = unsavedStorage();
|
|
337
|
+
if (!storage)
|
|
338
|
+
return null;
|
|
339
|
+
return readClaimedEntry(storage, claimedKey(appId, token), now);
|
|
340
|
+
}
|
|
13
341
|
//# sourceMappingURL=guest-link.js.map
|
package/dist/guest-link.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guest-link.js","sourceRoot":"","sources":["../src/guest-link.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,yEAAyE;AACzE,mEAAmE;AACnE,2EAA2E;AAC3E,EAAE;AACF,0DAA0D;AAC1D,0BAA0B;AAE1B,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"guest-link.js","sourceRoot":"","sources":["../src/guest-link.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,yEAAyE;AACzE,mEAAmE;AACnE,2EAA2E;AAC3E,EAAE;AACF,0DAA0D;AAC1D,0BAA0B;AAE1B,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAEtC,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAChE,OAAO,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC;AAED,2EAA2E;AAC3E,wEAAwE;AACxE,4EAA4E;AAC5E,yBAAyB;AACzB,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO;IAC1C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC1C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC5B,IAAI,IAAI,KAAK,MAAM,CAAC,QAAQ,CAAC,IAAI;YAAE,OAAO;QAC1C,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,8DAA8D;IAChE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO;IAC1C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,CAAC;YAAE,OAAO;QACpD,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,6BAA6B;IAC/B,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,4EAA4E;AAC5E,4EAA4E;AAC5E,4EAA4E;AAC5E,0EAA0E;AAC1E,mEAAmE;AACnE,EAAE;AACF,sEAAsE;AACtE,uEAAuE;AACvE,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAO5C,SAAS,cAAc;IACrB,IAAI,OAAO,YAAY,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACrD,IAAI,CAAC;QACH,OAAO,YAAY,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,GAAG,kBAAkB,GAAG,KAAK,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,KAAa,EACb,KAAa,EACb,SAAe;IAEf,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,IAAI,CAAC;QACH,OAAO,CAAC,OAAO,CACb,UAAU,CAAC,KAAK,CAAC,EACjB,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC,CAC/D,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;QACtE,sCAAsC;IACxC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,MAAc,IAAI,CAAC,GAAG,EAAE;IAExB,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,GAAkB,CAAC;IACvB,IAAI,CAAC;QACH,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,MAA0D,CAAC;IACzE,MAAM,SAAS,GACb,OAAO,KAAK,EAAE,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5E,IACE,OAAO,KAAK,EAAE,KAAK,KAAK,QAAQ;QAChC,KAAK,CAAC,KAAK,KAAK,EAAE;QAClB,SAAS,KAAK,IAAI;QAClB,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,EACjC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,uEAAuE;IACvE,yDAAyD;IACzD,IAAI,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;QAC/B,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,IAAI,CAAC;QACH,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,2EAA2E;AAC3E,wEAAwE;AACxE,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAEhD,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,SAAe;IAC5D,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,IAAI,CAAC;QACH,OAAO,CAAC,OAAO,CAAC,GAAG,iBAAiB,GAAG,KAAK,EAAE,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,MAAc,IAAI,CAAC,GAAG,EAAE;IACpE,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,GAAkB,CAAC;IACvB,IAAI,CAAC;QACH,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,iBAAiB,GAAG,KAAK,EAAE,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;QAChD,IAAI,CAAC;YACH,OAAO,CAAC,UAAU,CAAC,GAAG,iBAAiB,GAAG,KAAK,EAAE,CAAC,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC;YACP,0BAA0B;QAC5B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,4EAA4E;AAC5E,wEAAwE;AACxE,uEAAuE;AACvE,+EAA+E;AAC/E,8EAA8E;AAC9E,0EAA0E;AAC1E,gBAAgB;AAChB,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAExC,SAAS,QAAQ,CAAC,KAAa,EAAE,KAAa;IAC5C,OAAO,GAAG,gBAAgB,GAAG,KAAK,IAAI,KAAK,EAAE,CAAC;AAChD,CAAC;AAED,yEAAyE;AACzE,SAAS,SAAS,CAAC,OAAgB,EAAE,MAAc;IACjD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,CAAC;QACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC3B,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CACrB,OAAgB,EAChB,GAAW,EACX,GAAW;IAEX,IAAI,KAAwD,CAAC;IAC7D,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,MAAM,CAAiB,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,GAAG,IAAI,CAAC;IACf,CAAC;IACD,MAAM,SAAS,GACb,OAAO,KAAK,EAAE,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC7E,IAAI,OAAO,KAAK,EAAE,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;QACrF,IAAI,CAAC;YACH,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,0BAA0B;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC;AACtB,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAgB,EAAE,GAAW;IACtD,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,OAAO,EAAE,gBAAgB,CAAC;QAAE,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAC5F,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,KAAa,EACb,KAAa,EACb,MAAc,EACd,SAAe,EACf,MAAc,IAAI,CAAC,GAAG,EAAE;IAExB,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,iBAAiB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAChC,IAAI,CAAC;QACH,OAAO,CAAC,OAAO,CACb,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,EACtB,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC,CAChE,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,KAAa,EACb,MAAc,IAAI,CAAC,GAAG,EAAE;IAExB,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED,0EAA0E;AAC1E,eAAe;AACf,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,KAAc;IAC5D,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,IAAI,GACR,KAAK,KAAK,SAAS;QACjB,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,gBAAgB,GAAG,KAAK,GAAG,CAAC;QACpD,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,0BAA0B;QAC5B,CAAC;IACH,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,4EAA4E;AAC5E,+EAA+E;AAC/E,MAAM,qBAAqB,GAAG,qBAAqB,CAAC;AAEpD,SAAS,UAAU;IACjB,IAAI,OAAO,cAAc,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,CAAC;QACH,OAAO,cAAc,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,KAAa;IAC1D,IAAI,CAAC;QACH,UAAU,EAAE,EAAE,OAAO,CAAC,GAAG,qBAAqB,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,qBAAqB,GAAG,KAAK,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,UAAU,CAAC,GAAG,qBAAqB,GAAG,KAAK,EAAE,CAAC,CAAC;QACvD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,6EAA6E;AAC7E,4EAA4E;AAC5E,2EAA2E;AAC3E,6EAA6E;AAC7E,gEAAgE;AAChE,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAC5C,MAAM,mBAAmB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAErD,SAAS,UAAU,CAAC,KAAa,EAAE,KAAa;IAC9C,OAAO,GAAG,kBAAkB,GAAG,KAAK,IAAI,KAAK,EAAE,CAAC;AAClD,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAgB,EAAE,GAAW,EAAE,GAAW;IAClE,IAAI,KAAwD,CAAC;IAC7D,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,MAAM,CAAiB,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,GAAG,IAAI,CAAC;IACf,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,KAAK,EAAE,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;IACjF,IACE,OAAO,KAAK,EAAE,MAAM,KAAK,QAAQ;QACjC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;QACvB,SAAS,GAAG,mBAAmB,IAAI,GAAG,EACtC,CAAC;QACD,IAAI,CAAC;YACH,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,0BAA0B;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,KAAa,EACb,KAAa,EACb,KAAa,EACb,MAAc,IAAI,CAAC,GAAG,EAAE;IAExB,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,OAAO,EAAE,kBAAkB,CAAC;QAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9F,IAAI,CAAC;QACH,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAChG,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,KAAa,EACb,MAAc,IAAI,CAAC,GAAG,EAAE;IAExB,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;AAClE,CAAC"}
|
package/dist/handle-types.d.ts
CHANGED
|
@@ -23,8 +23,9 @@ export interface Splice<E> {
|
|
|
23
23
|
readonly inserted: readonly E[];
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
* What changed in a list. Fires once on registration carrying the whole list
|
|
27
|
-
*
|
|
26
|
+
* What changed in a list. Fires once on registration carrying the whole list,
|
|
27
|
+
* then on every change carrying only what moved. No splice inserts more than
|
|
28
|
+
* 10,000 elements, so a spread apply stays inside the engine's argument limit.
|
|
28
29
|
*
|
|
29
30
|
* A registration fire and a resync are not special cases a subscriber has to
|
|
30
31
|
* recognise: both arrive as splices that replace what it was last told, so
|
|
@@ -41,13 +42,36 @@ export interface HandleOwner {
|
|
|
41
42
|
assertReadable(): void;
|
|
42
43
|
ensureLocalUpdatesSubscribed(): void;
|
|
43
44
|
commitMutate(): void;
|
|
45
|
+
runMutate(options: MutateOptions | undefined, fn: () => void): void;
|
|
44
46
|
originOf(event: unknown): ChangeSource;
|
|
47
|
+
reportSubscriberThrow(err: unknown): void;
|
|
48
|
+
}
|
|
49
|
+
/** Options every `mutate` takes. */
|
|
50
|
+
export interface MutateOptions {
|
|
51
|
+
/**
|
|
52
|
+
* `false` keeps the write off the reader's Undo stack, for a pass the app
|
|
53
|
+
* runs on its own rather than one the reader asked for. Defaults to true.
|
|
54
|
+
*/
|
|
55
|
+
undoable?: boolean;
|
|
45
56
|
}
|
|
46
57
|
export interface MapHandle<T = unknown> {
|
|
58
|
+
/** Per-entry read. Returns undefined when missing. */
|
|
47
59
|
get(entryKey: string): T | undefined;
|
|
60
|
+
/** Keys currently in the map. */
|
|
48
61
|
keys(): string[];
|
|
62
|
+
/** Whether an entry exists at `entryKey`. */
|
|
49
63
|
has(entryKey: string): boolean;
|
|
50
|
-
|
|
64
|
+
/** Every `[key, value]`, as a walk. Each step hands over one entry, so a
|
|
65
|
+
* caller that does not keep them never holds the whole map at once. */
|
|
66
|
+
entries(): IterableIterator<[string, T]>;
|
|
67
|
+
/** Mutate through a typed JS-proxy, scoped to this container; same
|
|
68
|
+
* ergonomics as `doc.mutate(d => { d.entities[id].field = ... })`. */
|
|
69
|
+
mutate(fn: (draft: Record<string, T>) => void, options?: MutateOptions): void;
|
|
70
|
+
/** ONE channel for every change whatever produced it (local / remote / undo
|
|
71
|
+
* / redo / checkout): the projection reconciles by value. The callback gets
|
|
72
|
+
* `change` and optional `origin` a render ignores. Fires once on
|
|
73
|
+
* registration with the whole map as `change.set`, then on every change
|
|
74
|
+
* (each later fire proportional to what that change wrote). */
|
|
51
75
|
subscribe(cb: MapSubscriber<T>): HandleUnsubscribe;
|
|
52
76
|
/**
|
|
53
77
|
* Report each time this container has been delivered whole: on
|
|
@@ -63,6 +87,10 @@ export interface MapHandle<T = unknown> {
|
|
|
63
87
|
* began, which is the only claim available: more always arrives afterwards.
|
|
64
88
|
*/
|
|
65
89
|
onSettled(cb: () => void): HandleUnsubscribe;
|
|
90
|
+
/** Child handle for `entries[entryKey]` when that entry is itself a map /
|
|
91
|
+
* list. Reads see empty until the container exists; the first mutate
|
|
92
|
+
* creates it, and a subscription taken before that delivers the container
|
|
93
|
+
* whole on whichever write creates it. */
|
|
66
94
|
map<U>(entryKey: string): MapHandle<U>;
|
|
67
95
|
list<U>(entryKey: string): ListHandle<U>;
|
|
68
96
|
}
|
|
@@ -84,7 +112,16 @@ export interface ListDraft<T> extends Array<T> {
|
|
|
84
112
|
}
|
|
85
113
|
export interface ListHandle<T = unknown> {
|
|
86
114
|
length(): number;
|
|
87
|
-
|
|
115
|
+
/** The element at `index`, or undefined outside the list. */
|
|
116
|
+
get(index: number): T | undefined;
|
|
117
|
+
/** Every element in order, as a walk. */
|
|
118
|
+
values(): IterableIterator<T>;
|
|
119
|
+
mutate(fn: (draft: ListDraft<T>) => void, options?: MutateOptions): void;
|
|
120
|
+
/** Fires once on registration carrying the whole list, then on
|
|
121
|
+
* every change carrying only what moved, so a subscriber applies splices to
|
|
122
|
+
* what it already holds and never re-reads. A keyed collection belongs in a
|
|
123
|
+
* map (or `orderedMap`), which reconciles by key; a list is for ordering
|
|
124
|
+
* keys and small positional data. */
|
|
88
125
|
subscribe(cb: ListSubscriber<T>): HandleUnsubscribe;
|
|
89
126
|
/**
|
|
90
127
|
* Report each time this container has been delivered whole: on
|
|
@@ -121,16 +158,41 @@ export type OrderedMapPosition = {
|
|
|
121
158
|
index: number;
|
|
122
159
|
};
|
|
123
160
|
export interface OrderedMapHandle<T = unknown> {
|
|
161
|
+
/** Per-entry read. Returns undefined when missing. */
|
|
124
162
|
get(entryKey: string): T | undefined;
|
|
163
|
+
/** Whether an entry exists in the map. */
|
|
125
164
|
has(entryKey: string): boolean;
|
|
165
|
+
/** Keys in order-list order, filtered to keys still present in the map. */
|
|
126
166
|
keys(): string[];
|
|
167
|
+
/** Every `[key, value]` in order, as a walk. */
|
|
168
|
+
entries(): IterableIterator<[string, T]>;
|
|
169
|
+
/** @deprecated Use `entries()`, which walks the same records in the same
|
|
170
|
+
* order without building the array. */
|
|
127
171
|
ordered(): {
|
|
128
172
|
key: string;
|
|
129
173
|
value: T;
|
|
130
174
|
}[];
|
|
131
|
-
|
|
175
|
+
/** Mutate the map; the sibling order list reconciles in the same commit
|
|
176
|
+
* (new keys appended in insertion order, deleted keys pruned). Drive it
|
|
177
|
+
* like `MapHandle.mutate`: `m[key] = record`, `delete m[key]`,
|
|
178
|
+
* `m[key].field = ...`. */
|
|
179
|
+
mutate(fn: (draft: Record<string, T>) => void, options?: MutateOptions): void;
|
|
180
|
+
/** Write `value` under `entryKey` and put that key at `at`, both in ONE
|
|
181
|
+
* commit (one undo step) like every other structural edit here. A key the
|
|
182
|
+
* map already holds is written and repositioned rather than named twice. */
|
|
132
183
|
insert(entryKey: string, value: T, at: OrderedMapPosition): void;
|
|
184
|
+
/** Reposition a key the map already holds, writing the order list alone. A
|
|
185
|
+
* key the map does not hold does nothing, so a reorder racing a peer's
|
|
186
|
+
* delete of the same key leaves the delete standing. */
|
|
133
187
|
move(entryKey: string, to: OrderedMapPosition): void;
|
|
188
|
+
/** Fires once on registration (the whole map as `change.set` in order),
|
|
189
|
+
* then on every change. A field edit carries only `set` / `deleted`; a
|
|
190
|
+
* change that moves the order also carries `change.order` (live keys in
|
|
191
|
+
* order) so the app re-sequences the views it holds. A move the map does
|
|
192
|
+
* not see (an edit of the sibling order list, a merge that resequences
|
|
193
|
+
* keys already present) arrives as an `order` of its own with an empty
|
|
194
|
+
* `set`. Content stays proportional to what the change wrote; re-sequencing
|
|
195
|
+
* happens only when the order moves, and at most once per change. */
|
|
134
196
|
subscribe(cb: MapSubscriber<T>): HandleUnsubscribe;
|
|
135
197
|
/**
|
|
136
198
|
* Report each time this container has been delivered whole: on
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle-types.d.ts","sourceRoot":"","sources":["../src/handle-types.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,MAAM,CAAC,CAAC,GAAG,OAAO;IAUjC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAErC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAKpC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAcD,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAChE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B;AAQD,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,OAAO,IAAI,CACvC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,MAAM,CAAC,EAAE,YAAY,KAClB,IAAI,CAAC;AAYV,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI,CACrC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,MAAM,EAAE,YAAY,GAAG,SAAS,EAChC,MAAM,EAAE,OAAO,KACZ,IAAI,CAAC;AAEV;;;;;;;GAOG;AACH,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,CAAC;CACjC;AAED
|
|
1
|
+
{"version":3,"file":"handle-types.d.ts","sourceRoot":"","sources":["../src/handle-types.ts"],"names":[],"mappings":"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"}
|
package/dist/handles.d.ts
CHANGED
|
@@ -1,24 +1,6 @@
|
|
|
1
1
|
import { LoroMovableList, LoroMap } from './wasm-runtime.js';
|
|
2
|
-
import { MutateBatcher } from './mutate-batching.js';
|
|
3
2
|
import type { Change, ChangeOrigin, ChangeSource, HandleOwner, HandleUnsubscribe, ListDraft, ListHandle, ListSubscriber, MapHandle, MapSubscriber, OrderedMapHandle, OrderedMapPosition } from './handle-types.js';
|
|
4
3
|
export type { Change, ChangeOrigin, ChangeSource, HandleOwner, ListDraft, HandleUnsubscribe, ListHandle, ListSubscriber, MapHandle, MapSubscriber, OrderedMapHandle, OrderedMapPosition, };
|
|
5
|
-
/**
|
|
6
|
-
* Where a root map's ADDITIONS go once the map has paged itself part-way
|
|
7
|
-
* through a mutation.
|
|
8
|
-
*
|
|
9
|
-
* A mutation large enough to need paging usually starts against a map that
|
|
10
|
-
* is not yet paged, so the decision cannot be made once at the top. The
|
|
11
|
-
* proxy consults this on every assignment; while it declines, the mutation
|
|
12
|
-
* runs exactly as an unpaged one does.
|
|
13
|
-
*/
|
|
14
|
-
interface WriteDivert {
|
|
15
|
-
take(key: string, value: unknown): boolean;
|
|
16
|
-
holds(key: string): boolean;
|
|
17
|
-
peek(key: string): unknown;
|
|
18
|
-
drop(key: string): void;
|
|
19
|
-
keys(): string[];
|
|
20
|
-
}
|
|
21
|
-
export declare function wrapLoroMapProxy(loroMap: LoroMap, batcher?: MutateBatcher, divert?: WriteDivert, guardKeys?: boolean): Record<string, unknown>;
|
|
22
4
|
/**
|
|
23
5
|
* What a ROOT map handle needs from its owning Document to present a paged
|
|
24
6
|
* store. Bundled rather than passed one by one: every member is read off the
|
|
@@ -46,7 +28,21 @@ export interface PagedRootHooks {
|
|
|
46
28
|
sessionToken(): string;
|
|
47
29
|
stateVersion(): StateVersion;
|
|
48
30
|
}
|
|
49
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Hide a handle's own fields from enumeration.
|
|
33
|
+
*
|
|
34
|
+
* A handle is a VIEW onto a container, not the container, so `Object.keys` on
|
|
35
|
+
* one is a natural thing to reach for and it type-checks. Enumerable, it
|
|
36
|
+
* answers with the handle's own fields, which look enough like record keys to
|
|
37
|
+
* pass and are the same handful whatever the document holds, so the mistake
|
|
38
|
+
* reads as a small document rather than as a mistake. Hidden, the answer is
|
|
39
|
+
* empty, and the reader goes looking for `keys()`.
|
|
40
|
+
*
|
|
41
|
+
* Every field is declared with an initialiser, so they all exist by the time
|
|
42
|
+
* this runs and a later assignment keeps the descriptor this sets.
|
|
43
|
+
*/
|
|
44
|
+
export declare function hideOwnFields(handle: object): void;
|
|
45
|
+
export declare function createRootMapHandle<T>(root: LoroMap, owner: HandleOwner, paging?: PagedRootHooks, rootKey?: string): MapHandle<T>;
|
|
50
46
|
export declare function createRootListHandle<T>(root: LoroMovableList, owner: HandleOwner): ListHandle<T>;
|
|
51
47
|
export declare function rebindRootMapAnchor(handle: MapHandle<unknown>, next: LoroMap): void;
|
|
52
48
|
export declare function rebindRootListAnchor(handle: ListHandle<unknown>, next: LoroMovableList): void;
|
package/dist/handles.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../src/handles.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,eAAe,EACf,OAAO,EAIR,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../src/handles.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,eAAe,EACf,OAAO,EAIR,MAAM,mBAAmB,CAAC;AAmC3B,OAAO,KAAK,EAGV,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,iBAAiB,EAGjB,SAAS,EACT,UAAU,EACV,cAAc,EACd,SAAS,EACT,aAAa,EAEb,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EACV,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,kBAAkB,GACnB,CAAC;AA8pFF;;;;;GAKG;AACH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC;AAYxE,MAAM,WAAW,cAAc;IAE7B,OAAO,IAAI,OAAO,CAAC;IAGnB,IAAI,IAAI,IAAI,CAAC;IAEb,YAAY,IAAI,MAAM,CAAC;IAEvB,YAAY,IAAI,YAAY,CAAC;CAC9B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAIlD;AAkoDD,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,WAAW,EAClB,MAAM,CAAC,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,MAAM,GACf,SAAS,CAAC,CAAC,CAAC,CAQd;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,WAAW,GACjB,UAAU,CAAC,CAAC,CAAC,CAEf;AAgBD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,EAC1B,IAAI,EAAE,OAAO,GACZ,IAAI,CAEN;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,EAC3B,IAAI,EAAE,eAAe,GACpB,IAAI,CAEN;AAcD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAEpE;AAMD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,GAC/C,IAAI,CAEN;AAOD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,GAC/C,IAAI,CAEN;AAKD,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,EACjB,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,EACzB,KAAK,EAAE,WAAW,GACjB,gBAAgB,CAAC,CAAC,CAAC,CAMrB"}
|