@agentshouse/mdruntime 0.1.0-c5d3fa6fb67bc → 0.1.0-c6636685d0c4b
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 +205 -205
- package/README.md +8 -8
- package/dist/adapter.d.ts +36 -9
- package/dist/adapter.d.ts.map +1 -1
- package/dist/bootstrap.d.ts +2 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +1 -1
- package/dist/change-set.d.ts +5 -2
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +6 -1
- package/dist/chat/earlier.d.ts +10 -0
- package/dist/chat/earlier.d.ts.map +1 -0
- package/dist/chat/earlier.js +54 -0
- package/dist/chat/kit.js +1 -1
- package/dist/chat/list.d.ts +2 -1
- package/dist/chat/list.d.ts.map +1 -1
- package/dist/chat/list.js +45 -5
- package/dist/chat/markdown.d.ts +1 -0
- package/dist/chat/markdown.d.ts.map +1 -1
- package/dist/chat/markdown.js +78 -20
- package/dist/chat/message.d.ts +1 -0
- package/dist/chat/message.d.ts.map +1 -1
- package/dist/chat/message.js +12 -2
- package/dist/chat/messages.d.ts +2 -0
- package/dist/chat/messages.d.ts.map +1 -1
- package/dist/chat/messages.js +52 -20
- package/dist/chat/overlay.d.ts +1 -0
- package/dist/chat/overlay.d.ts.map +1 -1
- package/dist/chat/overlay.js +10 -0
- package/dist/chat/pieces.d.ts +62 -0
- package/dist/chat/pieces.d.ts.map +1 -0
- package/dist/chat/pieces.js +1110 -0
- package/dist/chat/provider.d.ts +1 -0
- package/dist/chat/provider.d.ts.map +1 -1
- package/dist/chat/provider.js +23 -14
- package/dist/chat/question.d.ts +1 -1
- package/dist/chat/question.d.ts.map +1 -1
- package/dist/chat/question.js +7 -18
- package/dist/chat/ready.d.ts +1 -1
- package/dist/chat/ready.d.ts.map +1 -1
- package/dist/chat/ready.js +1 -1
- package/dist/chat/steady.d.ts +3 -0
- package/dist/chat/steady.d.ts.map +1 -0
- package/dist/chat/steady.js +26 -0
- package/dist/chat/style.js +1 -1
- package/dist/chat.d.ts +2 -2
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +2 -2
- package/dist/client.d.ts +6 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +16 -5
- package/dist/collection.d.ts +4 -3
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +128 -63
- package/dist/connection.d.ts +12 -4
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +577 -217
- package/dist/conversation.d.ts +12 -0
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +196 -41
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +2 -1
- package/dist/host.d.ts +5 -4
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +45 -5
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/memory.d.ts +6 -3
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +17 -11
- package/dist/observation.d.ts +2 -0
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +9 -3
- package/dist/outcome.d.ts +14 -2
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +7 -0
- package/dist/overlay.d.ts +4 -4
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +181 -140
- package/dist/query.d.ts +26 -2
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +34 -6
- package/dist/reach.d.ts +4 -1
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +90 -21
- package/dist/react.d.ts +3 -3
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +7 -17
- package/dist/read-side.d.ts +3 -1
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +271 -82
- package/dist/reads.d.ts +11 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +98 -0
- package/dist/refresh.d.ts +4 -4
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +35 -16
- package/dist/replica.d.ts +11 -5
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +69 -40
- package/dist/room-draft.d.ts +12 -0
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +11 -12
- package/dist/rows.d.ts +1 -0
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +5 -0
- package/dist/save.d.ts +4 -2
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +195 -111
- package/dist/search.d.ts +17 -2
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +81 -7
- package/dist/seed.d.ts +16 -0
- package/dist/seed.d.ts.map +1 -0
- package/dist/seed.js +75 -0
- package/dist/shared.d.ts +4 -0
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +63 -33
- package/dist/store.d.ts +18 -2
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +398 -316
- package/dist/turn.d.ts +5 -3
- package/dist/turn.d.ts.map +1 -1
- package/dist/turn.js +26 -7
- package/dist/windows.d.ts +26 -0
- package/dist/windows.d.ts.map +1 -0
- package/dist/windows.js +93 -0
- package/dist/wire.d.ts +16 -0
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +4 -0
- package/package.json +2 -2
- package/dist/acquisition.d.ts +0 -14
- package/dist/acquisition.d.ts.map +0 -1
- package/dist/acquisition.js +0 -24
package/dist/store.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { sameBinary, sameChange } from './overlay.js';
|
|
2
|
-
import {
|
|
2
|
+
import { differences } from './shared.js';
|
|
3
|
+
import { inUnits, ROW_WEIGHT, stepped } from './turn.js';
|
|
4
|
+
import { precedes } from './windows.js';
|
|
3
5
|
const DATABASE = 'mdruntime';
|
|
4
6
|
const AUTHORED = 'mdruntime-authored';
|
|
5
7
|
const FENCES = 'fences';
|
|
@@ -16,6 +18,7 @@ const PRESENTATION = 'presentation';
|
|
|
16
18
|
const CONVERSATIONS = 'conversations';
|
|
17
19
|
const MESSAGES = 'messages';
|
|
18
20
|
const CHAT_DRAFTS = 'chatDrafts';
|
|
21
|
+
const CALLS = 'calls';
|
|
19
22
|
const QUEUES = 'queues';
|
|
20
23
|
const FACTS = 'facts';
|
|
21
24
|
const CURRENT = 'current';
|
|
@@ -26,12 +29,13 @@ const HOLDER = 'holder';
|
|
|
26
29
|
const BINDING = 'binding';
|
|
27
30
|
export const STORE_SCHEMA = 25;
|
|
28
31
|
const REPLICA_SHAPE = 23;
|
|
29
|
-
export const AUTHORED_SCHEMA =
|
|
32
|
+
export const AUTHORED_SCHEMA = 3;
|
|
30
33
|
const AUTHORED_STORES = [
|
|
31
34
|
[QUEUES, { keyPath: 'locator' }],
|
|
32
35
|
[PENDING_CHANGES, { keyPath: ['locator', 'id'] }],
|
|
33
36
|
[ROOM_DRAFTS, { keyPath: ['locator', 'path'] }],
|
|
34
37
|
[CHAT_DRAFTS, { keyPath: 'conversation' }],
|
|
38
|
+
[CALLS, { keyPath: 'operation' }],
|
|
35
39
|
[FACTS, undefined],
|
|
36
40
|
[FENCES, { keyPath: 'locator' }],
|
|
37
41
|
];
|
|
@@ -59,11 +63,52 @@ function settled(request) {
|
|
|
59
63
|
request.onerror = () => reject(request.error);
|
|
60
64
|
});
|
|
61
65
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
const turns = new Map();
|
|
67
|
+
function idle(database) {
|
|
68
|
+
return turns.get(database.name) ?? Promise.resolve();
|
|
69
|
+
}
|
|
70
|
+
export function transacted(database, stores, mode, work) {
|
|
71
|
+
let release = () => { };
|
|
72
|
+
const turn = new Promise((resolve) => {
|
|
73
|
+
release = resolve;
|
|
74
|
+
});
|
|
75
|
+
const before = idle(database);
|
|
76
|
+
const queued = before.then(() => turn);
|
|
77
|
+
turns.set(database.name, queued);
|
|
78
|
+
void queued.then(() => {
|
|
79
|
+
if (turns.get(database.name) === queued)
|
|
80
|
+
turns.delete(database.name);
|
|
81
|
+
});
|
|
82
|
+
return before.then(() => {
|
|
83
|
+
let transaction;
|
|
84
|
+
try {
|
|
85
|
+
transaction = database.transaction(stores, mode);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
release();
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
const committed = new Promise((resolve, reject) => {
|
|
92
|
+
transaction.oncomplete = () => {
|
|
93
|
+
release();
|
|
94
|
+
resolve();
|
|
95
|
+
};
|
|
96
|
+
transaction.onabort = () => {
|
|
97
|
+
release();
|
|
98
|
+
reject(transaction.error);
|
|
99
|
+
};
|
|
100
|
+
transaction.onerror = () => reject(transaction.error);
|
|
101
|
+
});
|
|
102
|
+
let value;
|
|
103
|
+
try {
|
|
104
|
+
value = work(transaction);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
void committed.catch(() => { });
|
|
108
|
+
transaction.abort();
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
return Promise.all([value, committed]).then(([held]) => held);
|
|
67
112
|
});
|
|
68
113
|
}
|
|
69
114
|
const EMPTY_DECLARATIONS = {
|
|
@@ -72,28 +117,27 @@ const EMPTY_DECLARATIONS = {
|
|
|
72
117
|
capabilities: [],
|
|
73
118
|
};
|
|
74
119
|
function declaration(database) {
|
|
75
|
-
|
|
76
|
-
return settled(transaction.objectStore(DECLARATIONS).get(CURRENT)).then((record) => record ?? EMPTY_DECLARATIONS);
|
|
120
|
+
return transacted(database, DECLARATIONS, 'readonly', (transaction) => settled(transaction.objectStore(DECLARATIONS).get(CURRENT))).then((record) => record ?? EMPTY_DECLARATIONS);
|
|
77
121
|
}
|
|
78
122
|
function updateDeclaration(database, update) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
123
|
+
return transacted(database, DECLARATIONS, 'readwrite', (transaction) => {
|
|
124
|
+
const store = transaction.objectStore(DECLARATIONS);
|
|
125
|
+
const prior = store.get(CURRENT);
|
|
126
|
+
prior.onsuccess = () => {
|
|
127
|
+
store.put(update(prior.result ?? EMPTY_DECLARATIONS), CURRENT);
|
|
128
|
+
};
|
|
129
|
+
});
|
|
86
130
|
}
|
|
87
131
|
function amendPending(database, locator, id, amendment) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
132
|
+
return transacted(database, PENDING_CHANGES, 'readwrite', (transaction) => {
|
|
133
|
+
const pending = transaction.objectStore(PENDING_CHANGES);
|
|
134
|
+
const request = pending.get([locator, id]);
|
|
135
|
+
request.onsuccess = () => {
|
|
136
|
+
const record = request.result;
|
|
137
|
+
if (record !== undefined)
|
|
138
|
+
pending.put({ ...record, ...amendment });
|
|
139
|
+
};
|
|
140
|
+
});
|
|
97
141
|
}
|
|
98
142
|
function accepted({ conversation: _held, ...message }) {
|
|
99
143
|
return message;
|
|
@@ -172,33 +216,44 @@ function binaryFileRecord(locator, transfer, layer, path) {
|
|
|
172
216
|
binary: layer.binaries[path],
|
|
173
217
|
};
|
|
174
218
|
}
|
|
175
|
-
function
|
|
219
|
+
function* changedIn(next, base) {
|
|
220
|
+
if (base === null)
|
|
221
|
+
return new Set([...Object.keys(next.documents), ...Object.keys(next.binaries)]);
|
|
222
|
+
return new Set([
|
|
223
|
+
...(yield* differences(base.documents, next.documents)),
|
|
224
|
+
...(yield* differences(base.revisions, next.revisions)),
|
|
225
|
+
...(yield* differences(base.fileIds, next.fileIds)),
|
|
226
|
+
...(yield* differences(base.written, next.written)),
|
|
227
|
+
...(yield* differences(base.changes, next.changes, sameChange)),
|
|
228
|
+
...(yield* differences(base.binaries, next.binaries, sameBinary)),
|
|
229
|
+
]);
|
|
230
|
+
}
|
|
231
|
+
function writeLayer(transaction, locator, transfer, layer) {
|
|
232
|
+
const { next, base, paths } = layer;
|
|
176
233
|
const documents = transaction.objectStore(DOCUMENTS);
|
|
177
234
|
const files = transaction.objectStore(BINARY_FILES);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
: new Set([
|
|
181
|
-
...differing(base.documents, next.documents),
|
|
182
|
-
...differing(base.revisions, next.revisions),
|
|
183
|
-
...differing(base.fileIds, next.fileIds),
|
|
184
|
-
...differing(base.written, next.written),
|
|
185
|
-
...differing(base.changes, next.changes, sameChange),
|
|
186
|
-
...differing(base.binaries, next.binaries, sameBinary),
|
|
187
|
-
]);
|
|
188
|
-
for (const path of paths) {
|
|
235
|
+
let last = null;
|
|
236
|
+
return inUnits(paths, (path) => {
|
|
189
237
|
if (next.documents[path] !== undefined) {
|
|
190
|
-
documents.put(documentRecord(locator, transfer, next, path));
|
|
238
|
+
last = documents.put(documentRecord(locator, transfer, next, path));
|
|
191
239
|
}
|
|
192
240
|
else if (base?.documents[path] !== undefined) {
|
|
193
|
-
documents.delete([locator, transfer, path]);
|
|
241
|
+
last = documents.delete([locator, transfer, path]);
|
|
194
242
|
}
|
|
195
243
|
if (next.binaries[path] !== undefined) {
|
|
196
|
-
files.put(binaryFileRecord(locator, transfer, next, path));
|
|
244
|
+
last = files.put(binaryFileRecord(locator, transfer, next, path));
|
|
197
245
|
}
|
|
198
246
|
else if (base?.binaries[path] !== undefined) {
|
|
199
|
-
files.delete([locator, transfer, path]);
|
|
247
|
+
last = files.delete([locator, transfer, path]);
|
|
200
248
|
}
|
|
201
|
-
|
|
249
|
+
return ROW_WEIGHT + (next.documents[path]?.length ?? 0);
|
|
250
|
+
}, () => { }, () => {
|
|
251
|
+
const request = last;
|
|
252
|
+
last = null;
|
|
253
|
+
return request === null
|
|
254
|
+
? Promise.resolve()
|
|
255
|
+
: new Promise((resolve) => request.addEventListener('success', () => resolve()));
|
|
256
|
+
});
|
|
202
257
|
}
|
|
203
258
|
function removeRoomEntries(store, locator) {
|
|
204
259
|
const keys = store.getAllKeys();
|
|
@@ -219,10 +274,8 @@ function removeDatabase(name) {
|
|
|
219
274
|
export async function authoredHolder() {
|
|
220
275
|
const authored = await openAuthored();
|
|
221
276
|
try {
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
await completed(transaction);
|
|
225
|
-
return typeof held.result === 'string' ? held.result : null;
|
|
277
|
+
const held = await transacted(authored, FACTS, 'readonly', (transaction) => settled(transaction.objectStore(FACTS).get(HOLDER)));
|
|
278
|
+
return typeof held === 'string' ? held : null;
|
|
226
279
|
}
|
|
227
280
|
finally {
|
|
228
281
|
authored.close();
|
|
@@ -231,17 +284,17 @@ export async function authoredHolder() {
|
|
|
231
284
|
export async function authoredBy(holder) {
|
|
232
285
|
const authored = await openAuthored();
|
|
233
286
|
try {
|
|
234
|
-
const transaction = authored.transaction(FACTS, 'readwrite');
|
|
235
|
-
const facts = transaction.objectStore(FACTS);
|
|
236
|
-
const held = facts.get(HOLDER);
|
|
237
287
|
let owned = true;
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
288
|
+
await transacted(authored, FACTS, 'readwrite', (transaction) => {
|
|
289
|
+
const facts = transaction.objectStore(FACTS);
|
|
290
|
+
const held = facts.get(HOLDER);
|
|
291
|
+
held.onsuccess = () => {
|
|
292
|
+
if (held.result === undefined)
|
|
293
|
+
facts.put(holder, HOLDER);
|
|
294
|
+
else
|
|
295
|
+
owned = held.result === holder;
|
|
296
|
+
};
|
|
297
|
+
});
|
|
245
298
|
return owned;
|
|
246
299
|
}
|
|
247
300
|
finally {
|
|
@@ -251,10 +304,8 @@ export async function authoredBy(holder) {
|
|
|
251
304
|
export async function authoredBinding() {
|
|
252
305
|
const authored = await openAuthored();
|
|
253
306
|
try {
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
await completed(transaction);
|
|
257
|
-
return typeof held.result === 'string' ? held.result : null;
|
|
307
|
+
const held = await transacted(authored, FACTS, 'readonly', (transaction) => settled(transaction.objectStore(FACTS).get(BINDING)));
|
|
308
|
+
return typeof held === 'string' ? held : null;
|
|
258
309
|
}
|
|
259
310
|
finally {
|
|
260
311
|
authored.close();
|
|
@@ -263,9 +314,9 @@ export async function authoredBinding() {
|
|
|
263
314
|
export async function bindAuthored(binding) {
|
|
264
315
|
const authored = await openAuthored();
|
|
265
316
|
try {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
317
|
+
await transacted(authored, FACTS, 'readwrite', (transaction) => {
|
|
318
|
+
transaction.objectStore(FACTS).put(binding, BINDING);
|
|
319
|
+
});
|
|
269
320
|
}
|
|
270
321
|
finally {
|
|
271
322
|
authored.close();
|
|
@@ -329,79 +380,97 @@ export async function openRuntimeStore(fenced) {
|
|
|
329
380
|
throw error;
|
|
330
381
|
});
|
|
331
382
|
return {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
383
|
+
all() {
|
|
384
|
+
return transacted(database, [ROOMS, DOCUMENTS, BINARY_FILES], 'readonly', async (transaction) => {
|
|
385
|
+
const rooms = await settled(transaction.objectStore(ROOMS).getAll());
|
|
386
|
+
const records = [];
|
|
387
|
+
for (const room of rooms.filter((held) => !fenced(held.locator))) {
|
|
388
|
+
records.push({
|
|
389
|
+
...room,
|
|
390
|
+
...(await readLayer(transaction, room.locator, room.transfer)),
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
return records;
|
|
394
|
+
});
|
|
340
395
|
},
|
|
341
|
-
async keepAuthored({ locator, queue, saved, roomDrafts, consumedRoomDrafts }) {
|
|
396
|
+
async keepAuthored({ locator, queue, founded, saved, roomDrafts, consumedRoomDrafts }) {
|
|
342
397
|
if (fenced(locator))
|
|
343
398
|
return;
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}
|
|
359
|
-
for (const batch of queue) {
|
|
360
|
-
if (!before.has(batch.id)) {
|
|
361
|
-
pending.put({
|
|
362
|
-
locator,
|
|
363
|
-
id: batch.id,
|
|
364
|
-
batch,
|
|
365
|
-
drafts: saved?.get(batch.id) ?? [],
|
|
366
|
-
submission: { state: 'waiting' },
|
|
367
|
-
lost: false,
|
|
368
|
-
});
|
|
399
|
+
await transacted(authored, [QUEUES, PENDING_CHANGES, ROOM_DRAFTS], 'readwrite', (transaction) => {
|
|
400
|
+
const order = transaction.objectStore(QUEUES);
|
|
401
|
+
const pending = transaction.objectStore(PENDING_CHANGES);
|
|
402
|
+
const held = order.get(locator);
|
|
403
|
+
held.onsuccess = () => {
|
|
404
|
+
const before = new Set(held.result?.order ?? []);
|
|
405
|
+
const after = new Set(queue.map((batch) => batch.id));
|
|
406
|
+
if (queue.length === 0)
|
|
407
|
+
order.delete(locator);
|
|
408
|
+
else
|
|
409
|
+
order.put({ locator, order: [...after] });
|
|
410
|
+
for (const id of before) {
|
|
411
|
+
if (!after.has(id))
|
|
412
|
+
pending.delete([locator, id]);
|
|
369
413
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
414
|
+
for (const batch of queue) {
|
|
415
|
+
if (!before.has(batch.id)) {
|
|
416
|
+
pending.put({
|
|
417
|
+
locator,
|
|
418
|
+
id: batch.id,
|
|
419
|
+
batch,
|
|
420
|
+
drafts: saved?.get(batch.id) ?? [],
|
|
421
|
+
submission: { state: 'waiting' },
|
|
422
|
+
lost: false,
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
for (const batch of founded ?? []) {
|
|
427
|
+
if (!before.has(batch.id))
|
|
428
|
+
continue;
|
|
429
|
+
const stored = pending.get([locator, batch.id]);
|
|
430
|
+
stored.onsuccess = () => {
|
|
431
|
+
const record = stored.result;
|
|
432
|
+
if (record !== undefined)
|
|
433
|
+
pending.put({ ...record, batch });
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
const draftStore = transaction.objectStore(ROOM_DRAFTS);
|
|
438
|
+
for (const path of consumedRoomDrafts ?? [])
|
|
439
|
+
draftStore.delete([locator, path]);
|
|
440
|
+
for (const record of roomDrafts ?? [])
|
|
441
|
+
draftStore.put(record);
|
|
442
|
+
});
|
|
378
443
|
},
|
|
379
444
|
async write({ next, previous, stored }) {
|
|
380
445
|
if (next === previous || fenced(next.locator))
|
|
381
446
|
return;
|
|
382
|
-
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES, TRANSFERS], 'readwrite');
|
|
383
|
-
transaction.objectStore(ROOMS).put(roomRecord(next));
|
|
384
447
|
const moved = previous?.transfer !== next.transfer;
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
448
|
+
const base = moved ? (stored ?? null) : previous;
|
|
449
|
+
const paths = await stepped(changedIn(next, base));
|
|
450
|
+
if (fenced(next.locator))
|
|
451
|
+
return;
|
|
452
|
+
await transacted(database, [ROOMS, DOCUMENTS, BINARY_FILES, TRANSFERS], 'readwrite', (transaction) => {
|
|
453
|
+
transaction.objectStore(ROOMS).put(roomRecord(next));
|
|
454
|
+
if (moved && previous !== null) {
|
|
455
|
+
const range = underTransfer(previous.locator, previous.transfer);
|
|
456
|
+
transaction.objectStore(DOCUMENTS).delete(range);
|
|
457
|
+
transaction.objectStore(BINARY_FILES).delete(range);
|
|
458
|
+
}
|
|
459
|
+
if (moved)
|
|
460
|
+
transaction.objectStore(TRANSFERS).delete(next.locator);
|
|
461
|
+
return writeLayer(transaction, next.locator, next.transfer, { next, base, paths });
|
|
462
|
+
});
|
|
394
463
|
},
|
|
395
464
|
async revokeModels(records) {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
465
|
+
await transacted(database, ROOMS, 'readwrite', (transaction) => {
|
|
466
|
+
const rooms = transaction.objectStore(ROOMS);
|
|
467
|
+
const revoked = { status: 'unavailable', reason: 'revoked' };
|
|
468
|
+
for (const record of records) {
|
|
469
|
+
if (fenced(record.locator))
|
|
470
|
+
continue;
|
|
471
|
+
rooms.put(roomRecord({ ...record, model: revoked, selectionModel: revoked }));
|
|
472
|
+
}
|
|
473
|
+
});
|
|
405
474
|
},
|
|
406
475
|
async lastCompleted() {
|
|
407
476
|
return (await declaration(database)).lastCompleted;
|
|
@@ -423,31 +492,28 @@ export async function openRuntimeStore(fenced) {
|
|
|
423
492
|
}));
|
|
424
493
|
},
|
|
425
494
|
async member() {
|
|
426
|
-
const
|
|
427
|
-
const held = await settled(transaction.objectStore(DECLARATIONS).get(MEMBER));
|
|
495
|
+
const held = await transacted(database, DECLARATIONS, 'readonly', (transaction) => settled(transaction.objectStore(DECLARATIONS).get(MEMBER)));
|
|
428
496
|
return held ?? null;
|
|
429
497
|
},
|
|
430
498
|
async keepMember(member) {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
499
|
+
await transacted(database, DECLARATIONS, 'readwrite', (transaction) => {
|
|
500
|
+
transaction.objectStore(DECLARATIONS).put(member, MEMBER);
|
|
501
|
+
});
|
|
434
502
|
},
|
|
435
503
|
async targets() {
|
|
436
|
-
const
|
|
437
|
-
const held = await settled(transaction.objectStore(DECLARATIONS).get(TARGETS));
|
|
504
|
+
const held = await transacted(database, DECLARATIONS, 'readonly', (transaction) => settled(transaction.objectStore(DECLARATIONS).get(TARGETS)));
|
|
438
505
|
return held ?? {};
|
|
439
506
|
},
|
|
440
507
|
async keepTargets(targets) {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
508
|
+
await transacted(database, DECLARATIONS, 'readwrite', (transaction) => {
|
|
509
|
+
transaction.objectStore(DECLARATIONS).put(targets, TARGETS);
|
|
510
|
+
});
|
|
444
511
|
},
|
|
445
512
|
async queues() {
|
|
446
|
-
const
|
|
447
|
-
const [queues, pending] = await Promise.all([
|
|
513
|
+
const [queues, pending] = await transacted(authored, [QUEUES, PENDING_CHANGES], 'readonly', (transaction) => Promise.all([
|
|
448
514
|
settled(transaction.objectStore(QUEUES).getAll()),
|
|
449
515
|
settled(transaction.objectStore(PENDING_CHANGES).getAll()),
|
|
450
|
-
]);
|
|
516
|
+
]));
|
|
451
517
|
const byId = new Map(pending.map((record) => [`${record.locator}\0${record.id}`, record]));
|
|
452
518
|
return queues
|
|
453
519
|
.filter((queue) => !fenced(queue.locator))
|
|
@@ -475,260 +541,276 @@ export async function openRuntimeStore(fenced) {
|
|
|
475
541
|
await amendPending(authored, locator, id, { upload });
|
|
476
542
|
},
|
|
477
543
|
async roomDrafts() {
|
|
478
|
-
const
|
|
479
|
-
const held = await settled(transaction.objectStore(ROOM_DRAFTS).getAll());
|
|
544
|
+
const held = await transacted(authored, ROOM_DRAFTS, 'readonly', (transaction) => settled(transaction.objectStore(ROOM_DRAFTS).getAll()));
|
|
480
545
|
return held.filter((record) => !fenced(record.locator));
|
|
481
546
|
},
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
return settled(transaction.objectStore(PRESENTATION).getAll());
|
|
547
|
+
presentation() {
|
|
548
|
+
return transacted(database, PRESENTATION, 'readonly', (transaction) => settled(transaction.objectStore(PRESENTATION).getAll()));
|
|
485
549
|
},
|
|
486
550
|
async present(record) {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
await completed(transaction);
|
|
490
|
-
},
|
|
491
|
-
async conversations() {
|
|
492
|
-
const transaction = database.transaction([CONVERSATIONS, MESSAGES], 'readonly');
|
|
493
|
-
const records = await settled(transaction.objectStore(CONVERSATIONS).getAll());
|
|
494
|
-
const held = new Map(records.map(({ conversation, read, partial }) => [
|
|
495
|
-
conversation,
|
|
496
|
-
{ conversation, read, partial: partial === true },
|
|
497
|
-
]));
|
|
498
|
-
const keys = transaction.objectStore(MESSAGES).index('conversation');
|
|
499
|
-
await new Promise((resolve, reject) => {
|
|
500
|
-
const cursor = keys.openKeyCursor(null, 'nextunique');
|
|
501
|
-
cursor.onerror = () => reject(cursor.error);
|
|
502
|
-
cursor.onsuccess = () => {
|
|
503
|
-
const at = cursor.result;
|
|
504
|
-
if (at === null) {
|
|
505
|
-
resolve();
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
|
-
const conversation = at.key;
|
|
509
|
-
if (!held.has(conversation)) {
|
|
510
|
-
held.set(conversation, { conversation, read: undefined, partial: true });
|
|
511
|
-
}
|
|
512
|
-
at.continue();
|
|
513
|
-
};
|
|
551
|
+
await transacted(database, PRESENTATION, 'readwrite', (transaction) => {
|
|
552
|
+
transaction.objectStore(PRESENTATION).put(record);
|
|
514
553
|
});
|
|
515
|
-
return [...held.values()];
|
|
516
554
|
},
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
stored.put({ ...message, conversation });
|
|
522
|
-
}
|
|
523
|
-
if (read !== undefined) {
|
|
524
|
-
transaction.objectStore(CONVERSATIONS).put({
|
|
555
|
+
conversations() {
|
|
556
|
+
return transacted(database, [CONVERSATIONS, MESSAGES], 'readonly', async (transaction) => {
|
|
557
|
+
const records = await settled(transaction.objectStore(CONVERSATIONS).getAll());
|
|
558
|
+
const held = new Map(records.map(({ conversation, read, partial }) => [
|
|
525
559
|
conversation,
|
|
526
|
-
read:
|
|
527
|
-
|
|
560
|
+
{ conversation, read, partial: partial === true },
|
|
561
|
+
]));
|
|
562
|
+
const keys = transaction.objectStore(MESSAGES).index('conversation');
|
|
563
|
+
await new Promise((resolve, reject) => {
|
|
564
|
+
const cursor = keys.openKeyCursor(null, 'nextunique');
|
|
565
|
+
cursor.onerror = () => reject(cursor.error);
|
|
566
|
+
cursor.onsuccess = () => {
|
|
567
|
+
const at = cursor.result;
|
|
568
|
+
if (at === null) {
|
|
569
|
+
resolve();
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
const conversation = at.key;
|
|
573
|
+
if (!held.has(conversation)) {
|
|
574
|
+
held.set(conversation, { conversation, read: undefined, partial: true });
|
|
575
|
+
}
|
|
576
|
+
at.continue();
|
|
577
|
+
};
|
|
528
578
|
});
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
},
|
|
532
|
-
async
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
579
|
+
return [...held.values()];
|
|
580
|
+
});
|
|
581
|
+
},
|
|
582
|
+
async keepMessages({ conversation, messages, read }) {
|
|
583
|
+
await transacted(database, [CONVERSATIONS, MESSAGES], 'readwrite', (transaction) => {
|
|
584
|
+
const stored = transaction.objectStore(MESSAGES);
|
|
585
|
+
for (const message of messages) {
|
|
586
|
+
stored.put({ ...message, conversation });
|
|
587
|
+
}
|
|
588
|
+
if (read !== undefined) {
|
|
589
|
+
transaction.objectStore(CONVERSATIONS).put({
|
|
590
|
+
conversation,
|
|
591
|
+
read: read.at,
|
|
592
|
+
...(read.partial ? { partial: true } : {}),
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
},
|
|
597
|
+
messageWindow(conversation, limit, before) {
|
|
598
|
+
return transacted(database, MESSAGES, 'readonly', async (transaction) => {
|
|
599
|
+
const index = transaction.objectStore(MESSAGES).index('position');
|
|
600
|
+
const range = IDBKeyRange.bound([conversation], [conversation, before?.[0] ?? []]);
|
|
601
|
+
const latest = [];
|
|
602
|
+
let more = false;
|
|
603
|
+
await new Promise((resolve, reject) => {
|
|
604
|
+
const cursor = index.openCursor(range, 'prev');
|
|
605
|
+
cursor.onerror = () => reject(cursor.error);
|
|
606
|
+
cursor.onsuccess = () => {
|
|
607
|
+
const at = cursor.result;
|
|
608
|
+
if (at === null) {
|
|
609
|
+
resolve();
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
const record = at.value;
|
|
613
|
+
if (!precedes(record, before)) {
|
|
614
|
+
at.continue();
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
if (latest.length === limit) {
|
|
618
|
+
more = true;
|
|
619
|
+
resolve();
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
latest.push(accepted(record));
|
|
555
623
|
at.continue();
|
|
556
|
-
|
|
624
|
+
};
|
|
625
|
+
});
|
|
626
|
+
return { messages: latest.reverse(), more };
|
|
557
627
|
});
|
|
558
|
-
|
|
628
|
+
},
|
|
629
|
+
messageCount(conversation) {
|
|
630
|
+
return transacted(database, MESSAGES, 'readonly', (transaction) => settled(transaction.objectStore(MESSAGES).index('conversation').count(conversation)));
|
|
559
631
|
},
|
|
560
632
|
async messagesAfter(conversation, identity) {
|
|
561
|
-
const transaction = database.transaction(MESSAGES, 'readonly');
|
|
562
633
|
const range = identity === null
|
|
563
634
|
? IDBKeyRange.bound([conversation], [conversation, []])
|
|
564
635
|
: IDBKeyRange.bound([conversation, identity], [conversation, []], true);
|
|
565
|
-
const held = await settled(transaction.objectStore(MESSAGES).getAll(range, READ_BATCH));
|
|
636
|
+
const held = await transacted(database, MESSAGES, 'readonly', (transaction) => settled(transaction.objectStore(MESSAGES).getAll(range, READ_BATCH)));
|
|
566
637
|
return held.map(accepted);
|
|
567
638
|
},
|
|
568
639
|
async messageIdentities(conversation) {
|
|
569
|
-
const
|
|
570
|
-
const keys = await settled(transaction.objectStore(MESSAGES).index('conversation').getAllKeys(conversation));
|
|
640
|
+
const keys = await transacted(database, MESSAGES, 'readonly', (transaction) => settled(transaction.objectStore(MESSAGES).index('conversation').getAllKeys(conversation)));
|
|
571
641
|
return keys.map((key) => key[1]);
|
|
572
642
|
},
|
|
573
643
|
async turnArrived(conversation, turn) {
|
|
574
|
-
const
|
|
575
|
-
const held = await settled(transaction.objectStore(MESSAGES).index('turn').count([conversation, turn]));
|
|
644
|
+
const held = await transacted(database, MESSAGES, 'readonly', (transaction) => settled(transaction.objectStore(MESSAGES).index('turn').count([conversation, turn])));
|
|
576
645
|
return held > 0;
|
|
577
646
|
},
|
|
578
647
|
async dropConversations(conversations) {
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
648
|
+
await transacted(authored, CHAT_DRAFTS, 'readwrite', (drafts) => {
|
|
649
|
+
for (const conversation of conversations)
|
|
650
|
+
drafts.objectStore(CHAT_DRAFTS).delete(conversation);
|
|
651
|
+
});
|
|
652
|
+
await transacted(database, [CONVERSATIONS, MESSAGES], 'readwrite', (transaction) => {
|
|
653
|
+
const messages = transaction.objectStore(MESSAGES);
|
|
654
|
+
for (const conversation of conversations) {
|
|
655
|
+
transaction.objectStore(CONVERSATIONS).delete(conversation);
|
|
656
|
+
const keys = messages.index('conversation').getAllKeys(conversation);
|
|
657
|
+
keys.onsuccess = () => {
|
|
658
|
+
for (const key of keys.result)
|
|
659
|
+
messages.delete(key);
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
});
|
|
594
663
|
},
|
|
595
664
|
async chatDrafts() {
|
|
596
|
-
const
|
|
597
|
-
const held = await settled(transaction.objectStore(CHAT_DRAFTS).getAll());
|
|
665
|
+
const held = await transacted(authored, CHAT_DRAFTS, 'readonly', (transaction) => settled(transaction.objectStore(CHAT_DRAFTS).getAll()));
|
|
598
666
|
return held.map(chatDraftRecord);
|
|
599
667
|
},
|
|
600
668
|
async keepChatDrafts(records) {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
669
|
+
await transacted(authored, CHAT_DRAFTS, 'readwrite', (transaction) => {
|
|
670
|
+
for (const record of records)
|
|
671
|
+
transaction.objectStore(CHAT_DRAFTS).put(record);
|
|
672
|
+
});
|
|
605
673
|
},
|
|
606
674
|
async dropChatDraft(conversation) {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
675
|
+
await transacted(authored, CHAT_DRAFTS, 'readwrite', (transaction) => {
|
|
676
|
+
transaction.objectStore(CHAT_DRAFTS).delete(conversation);
|
|
677
|
+
});
|
|
678
|
+
},
|
|
679
|
+
calls() {
|
|
680
|
+
return transacted(authored, CALLS, 'readonly', (transaction) => settled(transaction.objectStore(CALLS).getAll()));
|
|
681
|
+
},
|
|
682
|
+
async keepCall(record) {
|
|
683
|
+
await transacted(authored, CALLS, 'readwrite', (transaction) => {
|
|
684
|
+
transaction.objectStore(CALLS).put(record);
|
|
685
|
+
});
|
|
686
|
+
},
|
|
687
|
+
async dropCall(operation) {
|
|
688
|
+
await transacted(authored, CALLS, 'readwrite', (transaction) => {
|
|
689
|
+
transaction.objectStore(CALLS).delete(operation);
|
|
690
|
+
});
|
|
610
691
|
},
|
|
611
692
|
async keepRoomDraft(record) {
|
|
612
693
|
if (fenced(record.locator))
|
|
613
694
|
return;
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
695
|
+
await transacted(authored, ROOM_DRAFTS, 'readwrite', (transaction) => {
|
|
696
|
+
transaction.objectStore(ROOM_DRAFTS).put(record);
|
|
697
|
+
});
|
|
617
698
|
},
|
|
618
699
|
async discardRoomDraft(locator, path) {
|
|
619
700
|
if (fenced(locator))
|
|
620
701
|
return;
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
702
|
+
await transacted(authored, ROOM_DRAFTS, 'readwrite', (transaction) => {
|
|
703
|
+
transaction.objectStore(ROOM_DRAFTS).delete([locator, path]);
|
|
704
|
+
});
|
|
624
705
|
},
|
|
625
706
|
async fences() {
|
|
626
|
-
const
|
|
627
|
-
const held = await settled(transaction.objectStore(FENCES).getAll());
|
|
707
|
+
const held = await transacted(authored, FENCES, 'readonly', (transaction) => settled(transaction.objectStore(FENCES).getAll()));
|
|
628
708
|
return held.map((fence) => fence.locator);
|
|
629
709
|
},
|
|
630
710
|
async erase(locators) {
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
711
|
+
await transacted(authored, [FENCES, QUEUES, PENDING_CHANGES, ROOM_DRAFTS], 'readwrite', (work) => {
|
|
712
|
+
for (const locator of locators) {
|
|
713
|
+
work.objectStore(FENCES).put({ locator });
|
|
714
|
+
work.objectStore(QUEUES).delete(locator);
|
|
715
|
+
for (const name of [PENDING_CHANGES, ROOM_DRAFTS]) {
|
|
716
|
+
removeRoomEntries(work.objectStore(name), locator);
|
|
717
|
+
}
|
|
637
718
|
}
|
|
638
|
-
}
|
|
639
|
-
await
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
}
|
|
647
|
-
await
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
await completed(fences);
|
|
719
|
+
});
|
|
720
|
+
await transacted(database, [ROOMS, DOCUMENTS, BINARY_FILES, TRANSFERS], 'readwrite', (transaction) => {
|
|
721
|
+
for (const locator of locators) {
|
|
722
|
+
transaction.objectStore(ROOMS).delete(locator);
|
|
723
|
+
transaction.objectStore(TRANSFERS).delete(locator);
|
|
724
|
+
transaction.objectStore(DOCUMENTS).delete(underRoom(locator));
|
|
725
|
+
transaction.objectStore(BINARY_FILES).delete(underRoom(locator));
|
|
726
|
+
}
|
|
727
|
+
});
|
|
728
|
+
await transacted(authored, FENCES, 'readwrite', (fences) => {
|
|
729
|
+
for (const locator of locators)
|
|
730
|
+
fences.objectStore(FENCES).delete(locator);
|
|
731
|
+
});
|
|
652
732
|
},
|
|
653
733
|
async discard(locator) {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
734
|
+
await transacted(authored, [QUEUES, PENDING_CHANGES], 'readwrite', (transaction) => {
|
|
735
|
+
transaction.objectStore(QUEUES).delete(locator);
|
|
736
|
+
removeRoomEntries(transaction.objectStore(PENDING_CHANGES), locator);
|
|
737
|
+
});
|
|
658
738
|
},
|
|
659
739
|
async transfers() {
|
|
660
|
-
const
|
|
661
|
-
const held = await settled(transaction.objectStore(TRANSFERS).getAll());
|
|
740
|
+
const held = await transacted(database, TRANSFERS, 'readonly', (transaction) => settled(transaction.objectStore(TRANSFERS).getAll()));
|
|
662
741
|
return held.filter((record) => !fenced(record.locator));
|
|
663
742
|
},
|
|
664
743
|
staged(record) {
|
|
665
|
-
|
|
666
|
-
return readLayer(transaction, record.locator, record.transfer);
|
|
744
|
+
return transacted(database, [DOCUMENTS, BINARY_FILES], 'readonly', (transaction) => readLayer(transaction, record.locator, record.transfer));
|
|
667
745
|
},
|
|
668
746
|
async stage(record, page) {
|
|
669
747
|
if (fenced(record.locator))
|
|
670
748
|
return;
|
|
671
|
-
const
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
await
|
|
749
|
+
const paths = await stepped(changedIn(page, null));
|
|
750
|
+
if (fenced(record.locator))
|
|
751
|
+
return;
|
|
752
|
+
await transacted(database, [TRANSFERS, DOCUMENTS, BINARY_FILES], 'readwrite', (transaction) => {
|
|
753
|
+
transaction.objectStore(TRANSFERS).put(record);
|
|
754
|
+
return writeLayer(transaction, record.locator, record.transfer, {
|
|
755
|
+
next: page,
|
|
756
|
+
base: null,
|
|
757
|
+
paths,
|
|
758
|
+
});
|
|
759
|
+
});
|
|
675
760
|
},
|
|
676
761
|
async abandon(locator) {
|
|
677
762
|
if (fenced(locator))
|
|
678
763
|
return;
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
764
|
+
await transacted(database, [TRANSFERS, DOCUMENTS, BINARY_FILES], 'readwrite', (transaction) => {
|
|
765
|
+
const transfers = transaction.objectStore(TRANSFERS);
|
|
766
|
+
const held = transfers.get(locator);
|
|
767
|
+
held.onsuccess = () => {
|
|
768
|
+
const record = held.result;
|
|
769
|
+
if (record === undefined)
|
|
770
|
+
return;
|
|
771
|
+
transfers.delete(locator);
|
|
772
|
+
const range = underTransfer(locator, record.transfer);
|
|
773
|
+
transaction.objectStore(DOCUMENTS).delete(range);
|
|
774
|
+
transaction.objectStore(BINARY_FILES).delete(range);
|
|
775
|
+
};
|
|
776
|
+
});
|
|
692
777
|
},
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
return settled(transaction.objectStore(RECEIVED).getAll());
|
|
778
|
+
receivedHeads() {
|
|
779
|
+
return transacted(database, RECEIVED, 'readonly', (transaction) => settled(transaction.objectStore(RECEIVED).getAll()));
|
|
696
780
|
},
|
|
697
781
|
async receivedParts(key, count) {
|
|
698
|
-
const
|
|
699
|
-
const kept = await settled(transaction
|
|
782
|
+
const kept = await transacted(database, RECEIVED_PARTS, 'readonly', (transaction) => settled(transaction
|
|
700
783
|
.objectStore(RECEIVED_PARTS)
|
|
701
|
-
.getAll(IDBKeyRange.bound([key, 0], [key, count], false, true)));
|
|
784
|
+
.getAll(IDBKeyRange.bound([key, 0], [key, count], false, true))));
|
|
702
785
|
return kept.map((part) => part.value);
|
|
703
786
|
},
|
|
704
787
|
async keepReceived(key, head, part) {
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
788
|
+
await transacted(database, [RECEIVED, RECEIVED_PARTS], 'readwrite', (transaction) => {
|
|
789
|
+
transaction.objectStore(RECEIVED).put({ key, head });
|
|
790
|
+
if (part !== undefined)
|
|
791
|
+
transaction.objectStore(RECEIVED_PARTS).put({ key, ...part });
|
|
792
|
+
});
|
|
710
793
|
},
|
|
711
794
|
async dropReceived(keys) {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
795
|
+
await transacted(database, [RECEIVED, RECEIVED_PARTS], 'readwrite', (transaction) => {
|
|
796
|
+
for (const key of keys) {
|
|
797
|
+
transaction.objectStore(RECEIVED).delete(key);
|
|
798
|
+
transaction.objectStore(RECEIVED_PARTS).delete(IDBKeyRange.bound([key], [key, []]));
|
|
799
|
+
}
|
|
800
|
+
});
|
|
718
801
|
},
|
|
719
802
|
async generation() {
|
|
720
|
-
const
|
|
721
|
-
const held = await settled(transaction.objectStore(FACTS).get(GENERATION));
|
|
803
|
+
const held = await transacted(authored, FACTS, 'readonly', (transaction) => settled(transaction.objectStore(FACTS).get(GENERATION)));
|
|
722
804
|
return held ?? null;
|
|
723
805
|
},
|
|
724
806
|
async rememberGeneration(value) {
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
807
|
+
await transacted(authored, FACTS, 'readwrite', (transaction) => {
|
|
808
|
+
transaction.objectStore(FACTS).put(value, GENERATION);
|
|
809
|
+
});
|
|
728
810
|
},
|
|
729
811
|
close() {
|
|
730
|
-
authored
|
|
731
|
-
|
|
812
|
+
for (const held of [authored, database])
|
|
813
|
+
void idle(held).then(() => held.close());
|
|
732
814
|
},
|
|
733
815
|
};
|
|
734
816
|
}
|