@mdbase-dev/sdk 0.1.0-beta.161 → 0.1.0-beta.163
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/app-grant/setup.js +25 -17
- package/dist/app-grant/setup.js.map +1 -1
- package/dist/app-host/local-facade.d.ts +1 -1
- package/dist/app-host/local-facade.js +1 -1
- package/dist/app-host/local-facade.js.map +1 -1
- package/dist/app-host/unsynced-collection.d.ts +99 -0
- package/dist/app-host/unsynced-collection.js +530 -0
- package/dist/app-host/unsynced-collection.js.map +1 -0
- package/dist/app-host/wasm-runtime.d.ts +12 -0
- package/dist/app-host/wasm-runtime.js +32 -0
- package/dist/app-host/wasm-runtime.js.map +1 -1
- package/dist/app-host/web-sign-in-session.d.ts +13 -0
- package/dist/app-host/web-sign-in-session.js.map +1 -1
- package/dist/application/asset-pins.json +4 -4
- package/dist/application/declaration.d.ts +2 -0
- package/dist/application/declaration.js +3 -3
- package/dist/application/declaration.js.map +1 -1
- package/dist/application/entry.d.ts +40 -0
- package/dist/application/entry.js +72 -2
- package/dist/application/entry.js.map +1 -1
- package/dist/application/front-door.d.ts +20 -1
- package/dist/application/front-door.js +22 -0
- package/dist/application/front-door.js.map +1 -1
- package/dist/application/native-assets.d.ts +13 -0
- package/dist/application/native-assets.js +6 -1
- package/dist/application/native-assets.js.map +1 -1
- package/dist/application/phase.d.ts +11 -1
- package/dist/application/phase.js +12 -0
- package/dist/application/phase.js.map +1 -1
- package/dist/application/runtime.d.ts +17 -0
- package/dist/application/runtime.js +102 -2
- package/dist/application/runtime.js.map +1 -1
- package/dist/application/setup.js +5 -0
- package/dist/application/setup.js.map +1 -1
- package/dist/application/unsynced-transfer.d.ts +111 -0
- package/dist/application/unsynced-transfer.js +194 -0
- package/dist/application/unsynced-transfer.js.map +1 -0
- package/dist/application/worker-client.js +3 -1
- package/dist/application/worker-client.js.map +1 -1
- package/dist/application/worker-host.d.ts +32 -0
- package/dist/application/worker-host.js +257 -16
- package/dist/application/worker-host.js.map +1 -1
- package/dist/application/worker-protocol.d.ts +1 -1
- package/dist/application/worker-protocol.js +7 -1
- package/dist/application/worker-protocol.js.map +1 -1
- package/dist/application/worker-session.d.ts +15 -0
- package/dist/application/worker-session.js +2 -1
- package/dist/application/worker-session.js.map +1 -1
- package/dist/application/worker.js +866 -144
- package/dist/browser/mdbase-sdk.js +7541 -6983
- package/dist/browser/mdbase-sdk.min.js +70 -70
- package/dist/client.d.ts +8 -1
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -1
- package/dist/describe-error.d.ts +1 -1
- package/dist/describe-error.js +1 -0
- package/dist/describe-error.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +11 -0
- package/dist/manifest.js +12 -0
- package/dist/manifest.js.map +1 -0
- package/dist/native/provenance.json +5 -5
- package/dist/native/runtime.wasm +0 -0
- package/dist/testing/application.d.ts +5 -1
- package/dist/testing/application.js +45 -1
- package/dist/testing/application.js.map +1 -1
- package/dist/thin-client.d.ts +1 -1
- package/dist/thin-client.js.map +1 -1
- package/dist/wire.d.ts +4 -1
- package/dist/wire.js +3 -1
- package/dist/wire.js.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
/** The app's unsynced collection: work before connecting (see
|
|
2
|
+
* docs/architecture/work-before-connecting.md). A local-only replica in this
|
|
3
|
+
* Worker, over the same SQL store, facade and setup journal as a synced
|
|
4
|
+
* collection. No account, sign-in, log, control plane or stored keys: its
|
|
5
|
+
* identifiers are random, kept in one IndexedDB row, and never leave this
|
|
6
|
+
* browser. One per app storage scope; it is never listed as a collection. */
|
|
7
|
+
import { appPoolNames } from "../app-storage/app-sqlite-index.js";
|
|
8
|
+
import { createAppCollectionSql } from "../app-storage/collection-sql.js";
|
|
9
|
+
import { AppCollectionSetupJournal } from "./collection-setup-journal.js";
|
|
10
|
+
import { attachAppCollectionControl } from "./collection-control.js";
|
|
11
|
+
import { attachAppLocalFacade } from "./local-facade.js";
|
|
12
|
+
import { acquireAppReplicaLease } from "./owner.js";
|
|
13
|
+
import { AppWasmRuntime } from "./wasm-runtime.js";
|
|
14
|
+
const STORE = "unsynced", KEY = "current", WORK = "work", RETIRED = "retired.", MOVED = "moved.";
|
|
15
|
+
const UUID = /^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/;
|
|
16
|
+
/** Tabs that may show the unsynced collection at once (as for a synced one). */
|
|
17
|
+
const MAX_TABS = 32;
|
|
18
|
+
export class AppUnsyncedCollectionError extends Error {
|
|
19
|
+
reason;
|
|
20
|
+
constructor(reason) {
|
|
21
|
+
super(`app unsynced collection: ${reason}`);
|
|
22
|
+
this.reason = reason;
|
|
23
|
+
this.name = "AppUnsyncedCollectionError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const fail = (reason = "unavailable") => new AppUnsyncedCollectionError(reason);
|
|
27
|
+
function identity(value) {
|
|
28
|
+
if (!value || typeof value !== "object" || Array.isArray(value) ||
|
|
29
|
+
Object.keys(value).sort().join() !== "account,collection,device,installation,replica,version")
|
|
30
|
+
throw fail();
|
|
31
|
+
const row = value;
|
|
32
|
+
const ids = [row.account, row.installation, row.collection, row.replica, row.device];
|
|
33
|
+
if (row.version !== 1 || ids.some(id => typeof id !== "string" || !UUID.test(id)) || new Set(ids).size !== ids.length)
|
|
34
|
+
throw fail();
|
|
35
|
+
return Object.freeze({ ...row });
|
|
36
|
+
}
|
|
37
|
+
function work(value) {
|
|
38
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).sort().join() !== "since,version")
|
|
39
|
+
throw fail();
|
|
40
|
+
const row = value;
|
|
41
|
+
if (row.version !== 1 || !Number.isSafeInteger(row.since) || row.since < 0)
|
|
42
|
+
throw fail();
|
|
43
|
+
return Object.freeze({ version: 1, since: row.since });
|
|
44
|
+
}
|
|
45
|
+
function retired(value) {
|
|
46
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).sort().join() !== "account,destination,identity,retiredAt,version")
|
|
47
|
+
throw fail();
|
|
48
|
+
const row = value;
|
|
49
|
+
if (row.version !== 1 || [row.destination, row.account].some(id => typeof id !== "string" || !UUID.test(id)) ||
|
|
50
|
+
!Number.isSafeInteger(row.retiredAt) || row.retiredAt < 0)
|
|
51
|
+
throw fail();
|
|
52
|
+
return Object.freeze({ version: 1, identity: identity(row.identity), destination: row.destination, account: row.account, retiredAt: row.retiredAt });
|
|
53
|
+
}
|
|
54
|
+
function database(name, signal) {
|
|
55
|
+
signal.throwIfAborted();
|
|
56
|
+
if (!globalThis.indexedDB)
|
|
57
|
+
throw fail();
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
const request = indexedDB.open(name, 1);
|
|
60
|
+
let abandoned = false;
|
|
61
|
+
const finish = () => signal.removeEventListener("abort", stop);
|
|
62
|
+
const stop = () => { abandoned = true; finish(); try {
|
|
63
|
+
request.transaction?.abort();
|
|
64
|
+
}
|
|
65
|
+
catch { /* already settled */ } reject(fail("fenced")); };
|
|
66
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
67
|
+
request.onblocked = request.onerror = stop;
|
|
68
|
+
request.onupgradeneeded = () => {
|
|
69
|
+
try {
|
|
70
|
+
if (abandoned || request.result.objectStoreNames.length)
|
|
71
|
+
throw fail();
|
|
72
|
+
request.result.createObjectStore(STORE);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
try {
|
|
76
|
+
request.transaction?.abort();
|
|
77
|
+
}
|
|
78
|
+
catch { /* preserve */ }
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
request.onsuccess = () => {
|
|
82
|
+
finish();
|
|
83
|
+
if (abandoned || request.result.objectStoreNames.length !== 1 || !request.result.objectStoreNames.contains(STORE)) {
|
|
84
|
+
request.result.close();
|
|
85
|
+
reject(fail());
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
resolve(request.result);
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** Read one row, adding `make()` first when it is absent and `make` is given
|
|
93
|
+
* (one transaction, so racing Workers agree on one value). */
|
|
94
|
+
async function row(databaseName, key, parse, make, signal) {
|
|
95
|
+
const db = await database(databaseName, signal);
|
|
96
|
+
try {
|
|
97
|
+
return await new Promise((resolve, reject) => {
|
|
98
|
+
const tx = db.transaction(STORE, make ? "readwrite" : "readonly", { durability: "strict" });
|
|
99
|
+
let result = null, problem = null;
|
|
100
|
+
tx.onabort = tx.onerror = () => reject(problem ?? fail());
|
|
101
|
+
tx.oncomplete = () => resolve(result);
|
|
102
|
+
const rows = tx.objectStore(STORE), read = rows.get(key);
|
|
103
|
+
read.onsuccess = () => {
|
|
104
|
+
try {
|
|
105
|
+
if (read.result !== undefined) {
|
|
106
|
+
result = parse(read.result);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (!make)
|
|
110
|
+
return;
|
|
111
|
+
const made = parse(make());
|
|
112
|
+
rows.add(made, key);
|
|
113
|
+
result = made;
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
problem = error;
|
|
117
|
+
tx.abort();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
db.close();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Read this scope's identity; with `create`, make it first. */
|
|
127
|
+
export function appUnsyncedIdentity(databaseName, create, signal) {
|
|
128
|
+
return row(databaseName, KEY, identity, create ? () => ({ version: 1, account: crypto.randomUUID(), installation: crypto.randomUUID(),
|
|
129
|
+
collection: crypto.randomUUID(), replica: crypto.randomUUID(), device: crypto.randomUUID() }) : null, signal);
|
|
130
|
+
}
|
|
131
|
+
/** Whether this scope's unsynced collection holds work, without opening it or
|
|
132
|
+
* creating its database. Null where the browser cannot list databases. */
|
|
133
|
+
export async function appUnsyncedWork(databaseName, signal) {
|
|
134
|
+
if (await exists(databaseName, signal) !== true)
|
|
135
|
+
return null;
|
|
136
|
+
return row(databaseName, WORK, work, null, signal);
|
|
137
|
+
}
|
|
138
|
+
/** Whether this scope's database exists, without creating it. Null where the
|
|
139
|
+
* browser cannot list databases. */
|
|
140
|
+
async function exists(databaseName, signal) {
|
|
141
|
+
const list = globalThis.indexedDB?.databases;
|
|
142
|
+
if (typeof list !== "function")
|
|
143
|
+
return null;
|
|
144
|
+
const names = await list.call(globalThis.indexedDB);
|
|
145
|
+
signal.throwIfAborted();
|
|
146
|
+
return names.some(entry => entry.name === databaseName);
|
|
147
|
+
}
|
|
148
|
+
/** One read-write transaction over the store; `work` queues its requests and
|
|
149
|
+
* returns the value to resolve with once the transaction commits. */
|
|
150
|
+
async function change(databaseName, signal, work) {
|
|
151
|
+
const db = await database(databaseName, signal);
|
|
152
|
+
try {
|
|
153
|
+
return await new Promise((resolve, reject) => {
|
|
154
|
+
const tx = db.transaction(STORE, "readwrite", { durability: "strict" });
|
|
155
|
+
let result, problem = null;
|
|
156
|
+
tx.onabort = tx.onerror = () => reject(problem ?? fail());
|
|
157
|
+
tx.oncomplete = () => resolve(result);
|
|
158
|
+
work(tx.objectStore(STORE), value => { result = value; }, error => { problem = error; tx.abort(); });
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
db.close();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/** After a transfer: move `source`'s identity to a retired row bound to
|
|
166
|
+
* `account`, and clear the work marker, so the next open starts a new
|
|
167
|
+
* collection. False when `source` is no longer this scope's collection. */
|
|
168
|
+
export function retireAppUnsynced(databaseName, source, destination, account, signal) {
|
|
169
|
+
return change(databaseName, signal, (rows, done, refuse) => {
|
|
170
|
+
const read = rows.get(KEY);
|
|
171
|
+
read.onsuccess = () => {
|
|
172
|
+
try {
|
|
173
|
+
if (read.result === undefined || identity(read.result).collection !== source) {
|
|
174
|
+
done(false);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const value = retired({ version: 1, identity: read.result, destination, account, retiredAt: Date.now() });
|
|
178
|
+
rows.put(value, RETIRED + source);
|
|
179
|
+
rows.delete(KEY);
|
|
180
|
+
rows.delete(WORK);
|
|
181
|
+
rows.delete(MOVED + source);
|
|
182
|
+
done(true);
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
refuse(error);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
/** Forget `source` (this scope's current collection): the next open starts a
|
|
191
|
+
* new one. Returns the identity whose storage the caller then erases. */
|
|
192
|
+
export function discardAppUnsynced(databaseName, source, signal) {
|
|
193
|
+
return change(databaseName, signal, (rows, done, refuse) => {
|
|
194
|
+
const read = rows.get(KEY);
|
|
195
|
+
read.onsuccess = () => {
|
|
196
|
+
try {
|
|
197
|
+
if (read.result === undefined) {
|
|
198
|
+
done(null);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const found = identity(read.result);
|
|
202
|
+
if (found.collection !== source) {
|
|
203
|
+
done(null);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
rows.delete(KEY);
|
|
207
|
+
rows.delete(WORK);
|
|
208
|
+
rows.delete(MOVED + source);
|
|
209
|
+
done(found);
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
refuse(error);
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
const REVISION = /^sha256:[0-9a-f]{64}$/;
|
|
218
|
+
/** The transfer ledger row: source record ID → the revision brought in. */
|
|
219
|
+
function moved(value) {
|
|
220
|
+
const row = value;
|
|
221
|
+
if (!row || row.version !== 1 || !row.revisions || typeof row.revisions !== "object" || Array.isArray(row.revisions))
|
|
222
|
+
throw fail();
|
|
223
|
+
const out = new Map();
|
|
224
|
+
for (const [id, revision] of Object.entries(row.revisions)) {
|
|
225
|
+
if (!UUID.test(id) || typeof revision !== "string" || !REVISION.test(revision))
|
|
226
|
+
throw fail();
|
|
227
|
+
out.set(id, revision);
|
|
228
|
+
}
|
|
229
|
+
return out;
|
|
230
|
+
}
|
|
231
|
+
/** Which revision of each of `source`'s records an unsynced transfer has
|
|
232
|
+
* brought in (empty before the first). */
|
|
233
|
+
export async function appUnsyncedMoved(databaseName, source, signal) {
|
|
234
|
+
if (!UUID.test(source))
|
|
235
|
+
throw fail("binding");
|
|
236
|
+
return await row(databaseName, MOVED + source, moved, null, signal) ?? new Map();
|
|
237
|
+
}
|
|
238
|
+
/** Add to `source`'s transfer ledger. Refused once `source` is no longer this
|
|
239
|
+
* scope's collection (retired or discarded): nothing more is transferred from it. */
|
|
240
|
+
export function noteAppUnsyncedMoved(databaseName, source, revisions, signal) {
|
|
241
|
+
for (const [id, revision] of revisions)
|
|
242
|
+
if (!UUID.test(id) || !REVISION.test(revision))
|
|
243
|
+
return Promise.reject(fail("binding"));
|
|
244
|
+
return change(databaseName, signal, (rows, done, refuse) => {
|
|
245
|
+
const current = rows.get(KEY), previous = rows.get(MOVED + source);
|
|
246
|
+
previous.onsuccess = () => {
|
|
247
|
+
try {
|
|
248
|
+
if (current.result === undefined || identity(current.result).collection !== source) {
|
|
249
|
+
refuse(fail());
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const next = previous.result === undefined ? new Map() : moved(previous.result);
|
|
253
|
+
for (const [id, revision] of revisions)
|
|
254
|
+
next.set(id, revision);
|
|
255
|
+
rows.put({ version: 1, revisions: Object.fromEntries(next) }, MOVED + source);
|
|
256
|
+
done();
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
refuse(error);
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
/** Retired copies in this scope, without creating its database. */
|
|
265
|
+
export async function appUnsyncedRetired(databaseName, signal) {
|
|
266
|
+
if (await exists(databaseName, signal) === false)
|
|
267
|
+
return [];
|
|
268
|
+
return change(databaseName, signal, (rows, done, refuse) => {
|
|
269
|
+
const read = rows.getAll(IDBKeyRange.bound(RETIRED, RETIRED + "\uffff"));
|
|
270
|
+
read.onsuccess = () => { try {
|
|
271
|
+
done(Object.freeze(read.result.map(retired)));
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
refuse(error);
|
|
275
|
+
} };
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
/** Remove a retired copy's row; its storage is erased by the caller first. */
|
|
279
|
+
export function forgetAppUnsyncedRetired(databaseName, collection, signal) {
|
|
280
|
+
return change(databaseName, signal, (rows, done) => { rows.delete(RETIRED + collection); done(); });
|
|
281
|
+
}
|
|
282
|
+
/** How long a retired copy is kept after its transfer: the destination's own
|
|
283
|
+
* replica holds every transferred record from the transfer on, so the copy is
|
|
284
|
+
* a recovery aid, not the only one. */
|
|
285
|
+
export const APP_UNSYNCED_RECOVERY_MS = 30 * 24 * 60 * 60 * 1000;
|
|
286
|
+
/** Erase every retired copy `drop` selects (storage first, then its row; a
|
|
287
|
+
* copy whose storage could not be erased keeps its row and is tried again).
|
|
288
|
+
* Never throws; returns how many were removed. */
|
|
289
|
+
export async function pruneAppUnsyncedRetired(databaseName, drop, signal) {
|
|
290
|
+
let removed = 0;
|
|
291
|
+
try {
|
|
292
|
+
for (const copy of await appUnsyncedRetired(databaseName, signal)) {
|
|
293
|
+
if (!drop(copy) || !await eraseAppUnsyncedStorage(copy.identity))
|
|
294
|
+
continue;
|
|
295
|
+
await forgetAppUnsyncedRetired(databaseName, copy.identity.collection, signal);
|
|
296
|
+
removed++;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
catch { /* tried again at the next start or sign-out */ }
|
|
300
|
+
return removed;
|
|
301
|
+
}
|
|
302
|
+
/** Erase an unsynced collection's replica storage (its OPFS pool). Call only
|
|
303
|
+
* once it is closed. True when nothing is left. */
|
|
304
|
+
export async function eraseAppUnsyncedStorage(id) {
|
|
305
|
+
const storage = globalThis.navigator?.storage;
|
|
306
|
+
if (typeof storage?.getDirectory !== "function")
|
|
307
|
+
return true;
|
|
308
|
+
try {
|
|
309
|
+
const root = await storage.getDirectory();
|
|
310
|
+
await root.removeEntry(appPoolNames({ account: id.account, installation: id.installation, collection: id.collection }).directory, { recursive: true });
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
return error instanceof DOMException && error.name === "NotFoundError";
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
/** Open (creating if needed) this scope's unsynced collection. Busy (another
|
|
318
|
+
* Worker holds it) rejects with the replica owner's `busy`. */
|
|
319
|
+
export async function openAppUnsyncedCollection(options, displayName, parent) {
|
|
320
|
+
if (typeof options.loadRuntime !== "function" || typeof displayName !== "string" || !displayName.trim())
|
|
321
|
+
throw fail("binding");
|
|
322
|
+
const openSql = createAppCollectionSql(options.sql);
|
|
323
|
+
const id = await appUnsyncedIdentity(options.databaseName, true, parent);
|
|
324
|
+
if (!id)
|
|
325
|
+
throw fail();
|
|
326
|
+
const scope = Object.freeze({ account: id.account, installation: id.installation, collection: id.collection });
|
|
327
|
+
const life = new AbortController(), signal = AbortSignal.any([parent, life.signal]);
|
|
328
|
+
let closed = false, closing = null, lease = null;
|
|
329
|
+
let runtime = null, sqlClose = null, fence = null;
|
|
330
|
+
let journal = null, ledger = null;
|
|
331
|
+
let assessment = "setup_required";
|
|
332
|
+
let saved = null, marking = false, writes = 0;
|
|
333
|
+
let mode = "approved-new";
|
|
334
|
+
const generation = crypto.randomUUID(), setupTurn = { owner: null };
|
|
335
|
+
const listeners = new Set();
|
|
336
|
+
const tabs = new Map();
|
|
337
|
+
const current = () => !closed && !signal.aborted;
|
|
338
|
+
const changed = () => { for (const listener of [...listeners])
|
|
339
|
+
try {
|
|
340
|
+
listener();
|
|
341
|
+
}
|
|
342
|
+
catch { /* observers do not own the replica */ } };
|
|
343
|
+
// Commits confirm locally on a tick; a write ticks at once instead of on the timer.
|
|
344
|
+
let ticking = false;
|
|
345
|
+
const tick = () => {
|
|
346
|
+
if (ticking || !current())
|
|
347
|
+
return;
|
|
348
|
+
ticking = true;
|
|
349
|
+
queueMicrotask(() => { ticking = false; try {
|
|
350
|
+
if (current())
|
|
351
|
+
runtime?.tick();
|
|
352
|
+
}
|
|
353
|
+
catch {
|
|
354
|
+
void close().catch(() => { });
|
|
355
|
+
} });
|
|
356
|
+
};
|
|
357
|
+
// The first submit marks the collection as holding work (once per scope).
|
|
358
|
+
const submitted = (method) => {
|
|
359
|
+
tick();
|
|
360
|
+
if (method === "submit")
|
|
361
|
+
writes++;
|
|
362
|
+
if (method !== "submit" || saved || marking || !current())
|
|
363
|
+
return;
|
|
364
|
+
marking = true;
|
|
365
|
+
void row(options.databaseName, WORK, work, () => ({ version: 1, since: Date.now() }), signal)
|
|
366
|
+
.then(value => { if (value && current()) {
|
|
367
|
+
saved = value;
|
|
368
|
+
changed();
|
|
369
|
+
} })
|
|
370
|
+
.catch(() => { })
|
|
371
|
+
.finally(() => { marking = false; });
|
|
372
|
+
};
|
|
373
|
+
const drop = (handoff) => {
|
|
374
|
+
const tab = tabs.get(handoff.dataPort);
|
|
375
|
+
if (!tab)
|
|
376
|
+
return;
|
|
377
|
+
tabs.delete(handoff.dataPort);
|
|
378
|
+
try {
|
|
379
|
+
tab.facade.close();
|
|
380
|
+
}
|
|
381
|
+
catch { /* closed with the runtime */ }
|
|
382
|
+
void tab.control.close().catch(() => { });
|
|
383
|
+
for (const port of [tab.data.port1, tab.command.port1])
|
|
384
|
+
try {
|
|
385
|
+
port.close();
|
|
386
|
+
}
|
|
387
|
+
catch { /* already closed */ }
|
|
388
|
+
};
|
|
389
|
+
const close = () => closing ??= (async () => {
|
|
390
|
+
closed = true;
|
|
391
|
+
life.abort();
|
|
392
|
+
changed();
|
|
393
|
+
let failed = false;
|
|
394
|
+
for (const tab of [...tabs.values()]) {
|
|
395
|
+
try {
|
|
396
|
+
await tab.control.close();
|
|
397
|
+
}
|
|
398
|
+
catch {
|
|
399
|
+
failed = true;
|
|
400
|
+
}
|
|
401
|
+
try {
|
|
402
|
+
tab.facade.close();
|
|
403
|
+
}
|
|
404
|
+
catch {
|
|
405
|
+
failed = true;
|
|
406
|
+
}
|
|
407
|
+
try {
|
|
408
|
+
tab.data.port1.postMessage([1, JSON.stringify([scope.account, scope.installation, scope.collection]), "close"]);
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
failed = true;
|
|
412
|
+
}
|
|
413
|
+
for (const port of [tab.data.port1, tab.data.port2, tab.command.port1, tab.command.port2])
|
|
414
|
+
try {
|
|
415
|
+
port.close();
|
|
416
|
+
}
|
|
417
|
+
catch {
|
|
418
|
+
failed = true;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
tabs.clear();
|
|
422
|
+
try {
|
|
423
|
+
journal?.close();
|
|
424
|
+
}
|
|
425
|
+
catch {
|
|
426
|
+
failed = true;
|
|
427
|
+
}
|
|
428
|
+
try {
|
|
429
|
+
const clean = await runtime?.close();
|
|
430
|
+
if (runtime && clean !== true)
|
|
431
|
+
fence?.();
|
|
432
|
+
}
|
|
433
|
+
catch {
|
|
434
|
+
failed = true;
|
|
435
|
+
fence?.();
|
|
436
|
+
}
|
|
437
|
+
try {
|
|
438
|
+
await sqlClose?.();
|
|
439
|
+
}
|
|
440
|
+
catch {
|
|
441
|
+
failed = true;
|
|
442
|
+
}
|
|
443
|
+
try {
|
|
444
|
+
await lease?.release();
|
|
445
|
+
}
|
|
446
|
+
catch {
|
|
447
|
+
failed = true;
|
|
448
|
+
}
|
|
449
|
+
listeners.clear();
|
|
450
|
+
if (failed)
|
|
451
|
+
throw fail();
|
|
452
|
+
})();
|
|
453
|
+
try {
|
|
454
|
+
lease = await acquireAppReplicaLease(options.locks, scope, signal);
|
|
455
|
+
journal = new AppCollectionSetupJournal({ ...options.setupJournal, scope, isCurrent: current });
|
|
456
|
+
const artifact = await options.loadRuntime({ signal });
|
|
457
|
+
if (!current())
|
|
458
|
+
throw fail("fenced");
|
|
459
|
+
const sql = await openSql({ scope, signal });
|
|
460
|
+
sqlClose = () => sql.close();
|
|
461
|
+
fence = () => sql.sql.fence();
|
|
462
|
+
ledger = sql.ledger ?? null;
|
|
463
|
+
if (!current())
|
|
464
|
+
throw fail("fenced");
|
|
465
|
+
runtime = await AppWasmRuntime.create(new Uint8Array(artifact), sql.sql);
|
|
466
|
+
if (!current())
|
|
467
|
+
throw fail("fenced");
|
|
468
|
+
runtime.openUnsyncedConsuming({ collection: id.collection, replicaId: id.replica, deviceId: id.device, opened: sql.opened, sqliteVersion: sql.sqliteVersion });
|
|
469
|
+
// As for a synced collection: an interrupted setup is reconciled, never redone.
|
|
470
|
+
const intent = await journal.load(signal);
|
|
471
|
+
if (!current())
|
|
472
|
+
throw fail("fenced");
|
|
473
|
+
saved = await row(options.databaseName, WORK, work, null, signal);
|
|
474
|
+
if (!current())
|
|
475
|
+
throw fail("fenced");
|
|
476
|
+
if (intent && intent.version !== 1 && (intent.phase === "attempted" || intent.phase === "confirmed"))
|
|
477
|
+
mode = "reconcile-original";
|
|
478
|
+
const native = runtime, local = Object.freeze({ ...scope, isCurrent: current });
|
|
479
|
+
const attach = () => {
|
|
480
|
+
if (!current() || tabs.size >= MAX_TABS)
|
|
481
|
+
return null;
|
|
482
|
+
const data = new MessageChannel(), command = new MessageChannel();
|
|
483
|
+
let control = null, facade = null;
|
|
484
|
+
try {
|
|
485
|
+
facade = attachAppLocalFacade(native, data.port1, local, submitted);
|
|
486
|
+
let value = null;
|
|
487
|
+
control = attachAppCollectionControl(command.port1, { scope, generation }, { journal: journal, resourceSetup: facade.resourceSetup, signal, isCurrent: current,
|
|
488
|
+
ledger: () => current() ? ledger : null, setupTurn,
|
|
489
|
+
assess(state) { if (!current())
|
|
490
|
+
return; if (assessment !== state) {
|
|
491
|
+
assessment = state;
|
|
492
|
+
changed();
|
|
493
|
+
} },
|
|
494
|
+
// Nothing syncs, so visibility changes nothing here.
|
|
495
|
+
foreground() { },
|
|
496
|
+
onProtocolFailure() { if (value)
|
|
497
|
+
drop(value); } });
|
|
498
|
+
// Configured from the declaration with nothing to review: the collection
|
|
499
|
+
// is this app's own and starts empty. Once configured, tabs only inspect.
|
|
500
|
+
value = Object.freeze({ schema: "mdbn-app-collection/1", scope, generation, displayName,
|
|
501
|
+
setupMode: mode === "reconcile-original" ? mode : assessment === "ready" ? "inspect" : "approved-new",
|
|
502
|
+
dataPort: data.port2, controlPort: command.port2, people: true });
|
|
503
|
+
tabs.set(data.port2, { data, command, facade, control });
|
|
504
|
+
return value;
|
|
505
|
+
}
|
|
506
|
+
catch {
|
|
507
|
+
try {
|
|
508
|
+
facade?.close();
|
|
509
|
+
}
|
|
510
|
+
catch { /* not attached */ }
|
|
511
|
+
void control?.close().catch(() => { });
|
|
512
|
+
for (const port of [data.port1, data.port2, command.port1, command.port2])
|
|
513
|
+
port.close();
|
|
514
|
+
return null;
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
return Object.freeze({ scope, generation, isCurrent: current, setForeground() { }, attach, detach: drop, close,
|
|
518
|
+
get state() { return current() ? assessment : "setup_required"; },
|
|
519
|
+
get work() { return saved; },
|
|
520
|
+
get writes() { return writes; },
|
|
521
|
+
subscribe(listener) { if (!current())
|
|
522
|
+
throw fail("fenced"); listeners.add(listener); return () => { listeners.delete(listener); }; },
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
catch (error) {
|
|
526
|
+
await close().catch(() => { });
|
|
527
|
+
throw error;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
//# sourceMappingURL=unsynced-collection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unsynced-collection.js","sourceRoot":"","sources":["../../src/app-host/unsynced-collection.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,6 +36,15 @@ export interface AppBootstrap {
|
|
|
36
36
|
opened: "fresh" | "existing" | "unclean";
|
|
37
37
|
sqliteVersion: number;
|
|
38
38
|
}
|
|
39
|
+
/** The app's unsynced collection: identifiers chosen and kept by this
|
|
40
|
+
* browser storage scope, never sent to the control plane. No secrets. */
|
|
41
|
+
export interface AppUnsyncedBootstrap {
|
|
42
|
+
collection: string;
|
|
43
|
+
replicaId: string;
|
|
44
|
+
deviceId: string;
|
|
45
|
+
opened: "fresh" | "existing" | "unclean";
|
|
46
|
+
sqliteVersion: number;
|
|
47
|
+
}
|
|
39
48
|
/** Trusted authenticated host bootstrap only, never a grant/app RPC. */
|
|
40
49
|
export interface AppCpConnectorPin {
|
|
41
50
|
readonly connectorId: string;
|
|
@@ -192,6 +201,9 @@ export declare class AppWasmRuntime extends WasmRuntime implements AppLogRuntime
|
|
|
192
201
|
private guard;
|
|
193
202
|
/** One attempt. The caller must unwrap keys before this SYNCHRONOUS operation. */
|
|
194
203
|
openAppConsuming(c: AppBootstrap): void;
|
|
204
|
+
/** One attempt: open this app's unsynced collection, a local-only replica
|
|
205
|
+
* with no log, no trust pins and no stored keys (`rt_app_open_local`). */
|
|
206
|
+
openUnsyncedConsuming(c: AppUnsyncedBootstrap): void;
|
|
195
207
|
tick(): void;
|
|
196
208
|
connect(options?: Parameters<WasmRuntime["connect"]>[0]): ReturnType<WasmRuntime["connect"]>;
|
|
197
209
|
/** Trusted host READ on its actual held port. Native admission/publication
|
|
@@ -167,6 +167,38 @@ export class AppWasmRuntime extends WasmRuntime {
|
|
|
167
167
|
c.kemSecretKey?.fill(0);
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
|
+
/** One attempt: open this app's unsynced collection, a local-only replica
|
|
171
|
+
* with no log, no trust pins and no stored keys (`rt_app_open_local`). */
|
|
172
|
+
openUnsyncedConsuming(c) {
|
|
173
|
+
let encoded = null;
|
|
174
|
+
try {
|
|
175
|
+
if (this.attempted || this.deviceAttempted || !this.sql || this.sql.needsRecovery || typeof this.app.rt_app_open_local !== "function")
|
|
176
|
+
throw bad();
|
|
177
|
+
this.attempted = true;
|
|
178
|
+
if (!Number.isSafeInteger(c.sqliteVersion) || c.sqliteVersion < 0 || c.sqliteVersion > 0xffff_ffff)
|
|
179
|
+
throw bad();
|
|
180
|
+
const opened = c.opened === "fresh" ? 0 : c.opened === "existing" ? 1 : c.opened === "unclean" ? 2 : -1;
|
|
181
|
+
if (opened < 0)
|
|
182
|
+
throw bad();
|
|
183
|
+
encoded = encodeSecret(new Map([
|
|
184
|
+
[0, 1], [1, uuidToBytes(c.collection)], [2, uuidToBytes(c.replicaId)], [3, uuidToBytes(c.deviceId)], [12, opened], [13, c.sqliteVersion],
|
|
185
|
+
]));
|
|
186
|
+
const error = this.guard(() => this.takeOut(this.app.rt_app_open_local(...this.put(encoded))));
|
|
187
|
+
if (error.length)
|
|
188
|
+
throw bad();
|
|
189
|
+
this.collection = c.collection;
|
|
190
|
+
this.deviceId = c.deviceId;
|
|
191
|
+
this.active = true;
|
|
192
|
+
this.markOpened();
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
this.fail();
|
|
196
|
+
throw bad();
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
encoded?.fill(0);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
170
202
|
tick() { if (this.active && !this.retired)
|
|
171
203
|
this.guard(() => super.tick()); }
|
|
172
204
|
connect(options = {}) {
|