@agentshouse/mdruntime 0.1.0-c97456d63baba → 0.1.0-c9b1e59e5baeb
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 +221 -221
- package/README.md +8 -8
- package/dist/adapter.d.ts +35 -6
- 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 +5 -1
- package/dist/change-set.d.ts +5 -2
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +8 -2
- 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 +40 -4
- 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.map +1 -1
- package/dist/chat/message.js +9 -2
- package/dist/chat/messages.d.ts.map +1 -1
- package/dist/chat/messages.js +36 -16
- 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 +22 -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 +13 -5
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +506 -228
- package/dist/conversation.d.ts +11 -0
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +195 -41
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +3 -2
- package/dist/host.d.ts +9 -7
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +58 -9
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/memory.d.ts +7 -3
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +24 -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 +8 -2
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +3 -0
- package/dist/overlay.d.ts +5 -4
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +197 -132
- package/dist/query.d.ts +27 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +36 -7
- package/dist/reach.d.ts +1 -2
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +17 -4
- 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 +256 -69
- 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 +39 -14
- package/dist/replica.d.ts +11 -5
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +79 -41
- 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 +3 -1
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +8 -1
- 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 +27 -6
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +89 -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 +20 -4
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +404 -317
- 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,34 +117,33 @@ 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;
|
|
100
144
|
}
|
|
101
145
|
function roomRecord(record) {
|
|
102
|
-
const { documents, binaries, revisions, changes, written, ...room } = record;
|
|
146
|
+
const { documents, binaries, revisions, fileIds, changes, written, ...room } = record;
|
|
103
147
|
return room;
|
|
104
148
|
}
|
|
105
149
|
function chatDraftRecord(record) {
|
|
@@ -125,13 +169,15 @@ async function readTransfer(store, locator, transfer, receive) {
|
|
|
125
169
|
}
|
|
126
170
|
}
|
|
127
171
|
function emptyLayer() {
|
|
128
|
-
return { documents: {}, binaries: {}, revisions: {}, changes: {}, written: {} };
|
|
172
|
+
return { documents: {}, binaries: {}, revisions: {}, fileIds: {}, changes: {}, written: {} };
|
|
129
173
|
}
|
|
130
174
|
async function readLayer(transaction, locator, transfer) {
|
|
131
175
|
const layer = emptyLayer();
|
|
132
176
|
const head = (held) => {
|
|
133
177
|
if (held.revision !== null)
|
|
134
178
|
layer.revisions[held.path] = held.revision;
|
|
179
|
+
if (held.fileId !== null)
|
|
180
|
+
layer.fileIds[held.path] = held.fileId;
|
|
135
181
|
if (held.change !== null)
|
|
136
182
|
layer.changes[held.path] = held.change;
|
|
137
183
|
};
|
|
@@ -154,6 +200,7 @@ function documentRecord(locator, transfer, layer, path) {
|
|
|
154
200
|
path,
|
|
155
201
|
content: layer.documents[path],
|
|
156
202
|
revision: layer.revisions[path] ?? null,
|
|
203
|
+
fileId: layer.fileIds[path] ?? null,
|
|
157
204
|
change: layer.changes[path] ?? null,
|
|
158
205
|
written: layer.written[path] ?? null,
|
|
159
206
|
};
|
|
@@ -164,36 +211,49 @@ function binaryFileRecord(locator, transfer, layer, path) {
|
|
|
164
211
|
transfer,
|
|
165
212
|
path,
|
|
166
213
|
revision: layer.revisions[path] ?? null,
|
|
214
|
+
fileId: layer.fileIds[path] ?? null,
|
|
167
215
|
change: layer.changes[path] ?? null,
|
|
168
216
|
binary: layer.binaries[path],
|
|
169
217
|
};
|
|
170
218
|
}
|
|
171
|
-
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;
|
|
172
233
|
const documents = transaction.objectStore(DOCUMENTS);
|
|
173
234
|
const files = transaction.objectStore(BINARY_FILES);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
: new Set([
|
|
177
|
-
...differing(base.documents, next.documents),
|
|
178
|
-
...differing(base.revisions, next.revisions),
|
|
179
|
-
...differing(base.written, next.written),
|
|
180
|
-
...differing(base.changes, next.changes, sameChange),
|
|
181
|
-
...differing(base.binaries, next.binaries, sameBinary),
|
|
182
|
-
]);
|
|
183
|
-
for (const path of paths) {
|
|
235
|
+
let last = null;
|
|
236
|
+
return inUnits(paths, (path) => {
|
|
184
237
|
if (next.documents[path] !== undefined) {
|
|
185
|
-
documents.put(documentRecord(locator, transfer, next, path));
|
|
238
|
+
last = documents.put(documentRecord(locator, transfer, next, path));
|
|
186
239
|
}
|
|
187
240
|
else if (base?.documents[path] !== undefined) {
|
|
188
|
-
documents.delete([locator, transfer, path]);
|
|
241
|
+
last = documents.delete([locator, transfer, path]);
|
|
189
242
|
}
|
|
190
243
|
if (next.binaries[path] !== undefined) {
|
|
191
|
-
files.put(binaryFileRecord(locator, transfer, next, path));
|
|
244
|
+
last = files.put(binaryFileRecord(locator, transfer, next, path));
|
|
192
245
|
}
|
|
193
246
|
else if (base?.binaries[path] !== undefined) {
|
|
194
|
-
files.delete([locator, transfer, path]);
|
|
247
|
+
last = files.delete([locator, transfer, path]);
|
|
195
248
|
}
|
|
196
|
-
|
|
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
|
+
});
|
|
197
257
|
}
|
|
198
258
|
function removeRoomEntries(store, locator) {
|
|
199
259
|
const keys = store.getAllKeys();
|
|
@@ -214,10 +274,8 @@ function removeDatabase(name) {
|
|
|
214
274
|
export async function authoredHolder() {
|
|
215
275
|
const authored = await openAuthored();
|
|
216
276
|
try {
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
await completed(transaction);
|
|
220
|
-
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;
|
|
221
279
|
}
|
|
222
280
|
finally {
|
|
223
281
|
authored.close();
|
|
@@ -226,17 +284,17 @@ export async function authoredHolder() {
|
|
|
226
284
|
export async function authoredBy(holder) {
|
|
227
285
|
const authored = await openAuthored();
|
|
228
286
|
try {
|
|
229
|
-
const transaction = authored.transaction(FACTS, 'readwrite');
|
|
230
|
-
const facts = transaction.objectStore(FACTS);
|
|
231
|
-
const held = facts.get(HOLDER);
|
|
232
287
|
let owned = true;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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
|
+
});
|
|
240
298
|
return owned;
|
|
241
299
|
}
|
|
242
300
|
finally {
|
|
@@ -246,10 +304,8 @@ export async function authoredBy(holder) {
|
|
|
246
304
|
export async function authoredBinding() {
|
|
247
305
|
const authored = await openAuthored();
|
|
248
306
|
try {
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
await completed(transaction);
|
|
252
|
-
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;
|
|
253
309
|
}
|
|
254
310
|
finally {
|
|
255
311
|
authored.close();
|
|
@@ -258,9 +314,9 @@ export async function authoredBinding() {
|
|
|
258
314
|
export async function bindAuthored(binding) {
|
|
259
315
|
const authored = await openAuthored();
|
|
260
316
|
try {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
317
|
+
await transacted(authored, FACTS, 'readwrite', (transaction) => {
|
|
318
|
+
transaction.objectStore(FACTS).put(binding, BINDING);
|
|
319
|
+
});
|
|
264
320
|
}
|
|
265
321
|
finally {
|
|
266
322
|
authored.close();
|
|
@@ -324,79 +380,97 @@ export async function openRuntimeStore(fenced) {
|
|
|
324
380
|
throw error;
|
|
325
381
|
});
|
|
326
382
|
return {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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
|
+
});
|
|
335
395
|
},
|
|
336
|
-
async keepAuthored({ locator, queue, saved, roomDrafts, consumedRoomDrafts }) {
|
|
396
|
+
async keepAuthored({ locator, queue, founded, saved, roomDrafts, consumedRoomDrafts }) {
|
|
337
397
|
if (fenced(locator))
|
|
338
398
|
return;
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
}
|
|
354
|
-
for (const batch of queue) {
|
|
355
|
-
if (!before.has(batch.id)) {
|
|
356
|
-
pending.put({
|
|
357
|
-
locator,
|
|
358
|
-
id: batch.id,
|
|
359
|
-
batch,
|
|
360
|
-
drafts: saved?.get(batch.id) ?? [],
|
|
361
|
-
submission: { state: 'waiting' },
|
|
362
|
-
lost: false,
|
|
363
|
-
});
|
|
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]);
|
|
364
413
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
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
|
+
});
|
|
373
443
|
},
|
|
374
444
|
async write({ next, previous, stored }) {
|
|
375
445
|
if (next === previous || fenced(next.locator))
|
|
376
446
|
return;
|
|
377
|
-
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES, TRANSFERS], 'readwrite');
|
|
378
|
-
transaction.objectStore(ROOMS).put(roomRecord(next));
|
|
379
447
|
const moved = previous?.transfer !== next.transfer;
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
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
|
+
});
|
|
389
463
|
},
|
|
390
464
|
async revokeModels(records) {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
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
|
+
});
|
|
400
474
|
},
|
|
401
475
|
async lastCompleted() {
|
|
402
476
|
return (await declaration(database)).lastCompleted;
|
|
@@ -418,31 +492,28 @@ export async function openRuntimeStore(fenced) {
|
|
|
418
492
|
}));
|
|
419
493
|
},
|
|
420
494
|
async member() {
|
|
421
|
-
const
|
|
422
|
-
const held = await settled(transaction.objectStore(DECLARATIONS).get(MEMBER));
|
|
495
|
+
const held = await transacted(database, DECLARATIONS, 'readonly', (transaction) => settled(transaction.objectStore(DECLARATIONS).get(MEMBER)));
|
|
423
496
|
return held ?? null;
|
|
424
497
|
},
|
|
425
498
|
async keepMember(member) {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
499
|
+
await transacted(database, DECLARATIONS, 'readwrite', (transaction) => {
|
|
500
|
+
transaction.objectStore(DECLARATIONS).put(member, MEMBER);
|
|
501
|
+
});
|
|
429
502
|
},
|
|
430
503
|
async targets() {
|
|
431
|
-
const
|
|
432
|
-
const held = await settled(transaction.objectStore(DECLARATIONS).get(TARGETS));
|
|
504
|
+
const held = await transacted(database, DECLARATIONS, 'readonly', (transaction) => settled(transaction.objectStore(DECLARATIONS).get(TARGETS)));
|
|
433
505
|
return held ?? {};
|
|
434
506
|
},
|
|
435
507
|
async keepTargets(targets) {
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
508
|
+
await transacted(database, DECLARATIONS, 'readwrite', (transaction) => {
|
|
509
|
+
transaction.objectStore(DECLARATIONS).put(targets, TARGETS);
|
|
510
|
+
});
|
|
439
511
|
},
|
|
440
512
|
async queues() {
|
|
441
|
-
const
|
|
442
|
-
const [queues, pending] = await Promise.all([
|
|
513
|
+
const [queues, pending] = await transacted(authored, [QUEUES, PENDING_CHANGES], 'readonly', (transaction) => Promise.all([
|
|
443
514
|
settled(transaction.objectStore(QUEUES).getAll()),
|
|
444
515
|
settled(transaction.objectStore(PENDING_CHANGES).getAll()),
|
|
445
|
-
]);
|
|
516
|
+
]));
|
|
446
517
|
const byId = new Map(pending.map((record) => [`${record.locator}\0${record.id}`, record]));
|
|
447
518
|
return queues
|
|
448
519
|
.filter((queue) => !fenced(queue.locator))
|
|
@@ -470,260 +541,276 @@ export async function openRuntimeStore(fenced) {
|
|
|
470
541
|
await amendPending(authored, locator, id, { upload });
|
|
471
542
|
},
|
|
472
543
|
async roomDrafts() {
|
|
473
|
-
const
|
|
474
|
-
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()));
|
|
475
545
|
return held.filter((record) => !fenced(record.locator));
|
|
476
546
|
},
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
return settled(transaction.objectStore(PRESENTATION).getAll());
|
|
547
|
+
presentation() {
|
|
548
|
+
return transacted(database, PRESENTATION, 'readonly', (transaction) => settled(transaction.objectStore(PRESENTATION).getAll()));
|
|
480
549
|
},
|
|
481
550
|
async present(record) {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
await completed(transaction);
|
|
485
|
-
},
|
|
486
|
-
async conversations() {
|
|
487
|
-
const transaction = database.transaction([CONVERSATIONS, MESSAGES], 'readonly');
|
|
488
|
-
const records = await settled(transaction.objectStore(CONVERSATIONS).getAll());
|
|
489
|
-
const held = new Map(records.map(({ conversation, read, partial }) => [
|
|
490
|
-
conversation,
|
|
491
|
-
{ conversation, read, partial: partial === true },
|
|
492
|
-
]));
|
|
493
|
-
const keys = transaction.objectStore(MESSAGES).index('conversation');
|
|
494
|
-
await new Promise((resolve, reject) => {
|
|
495
|
-
const cursor = keys.openKeyCursor(null, 'nextunique');
|
|
496
|
-
cursor.onerror = () => reject(cursor.error);
|
|
497
|
-
cursor.onsuccess = () => {
|
|
498
|
-
const at = cursor.result;
|
|
499
|
-
if (at === null) {
|
|
500
|
-
resolve();
|
|
501
|
-
return;
|
|
502
|
-
}
|
|
503
|
-
const conversation = at.key;
|
|
504
|
-
if (!held.has(conversation)) {
|
|
505
|
-
held.set(conversation, { conversation, read: undefined, partial: true });
|
|
506
|
-
}
|
|
507
|
-
at.continue();
|
|
508
|
-
};
|
|
551
|
+
await transacted(database, PRESENTATION, 'readwrite', (transaction) => {
|
|
552
|
+
transaction.objectStore(PRESENTATION).put(record);
|
|
509
553
|
});
|
|
510
|
-
return [...held.values()];
|
|
511
554
|
},
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
stored.put({ ...message, conversation });
|
|
517
|
-
}
|
|
518
|
-
if (read !== undefined) {
|
|
519
|
-
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 }) => [
|
|
520
559
|
conversation,
|
|
521
|
-
read:
|
|
522
|
-
|
|
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
|
+
};
|
|
523
578
|
});
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
},
|
|
527
|
-
async
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
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));
|
|
550
623
|
at.continue();
|
|
551
|
-
|
|
624
|
+
};
|
|
625
|
+
});
|
|
626
|
+
return { messages: latest.reverse(), more };
|
|
552
627
|
});
|
|
553
|
-
|
|
628
|
+
},
|
|
629
|
+
messageCount(conversation) {
|
|
630
|
+
return transacted(database, MESSAGES, 'readonly', (transaction) => settled(transaction.objectStore(MESSAGES).index('conversation').count(conversation)));
|
|
554
631
|
},
|
|
555
632
|
async messagesAfter(conversation, identity) {
|
|
556
|
-
const transaction = database.transaction(MESSAGES, 'readonly');
|
|
557
633
|
const range = identity === null
|
|
558
634
|
? IDBKeyRange.bound([conversation], [conversation, []])
|
|
559
635
|
: IDBKeyRange.bound([conversation, identity], [conversation, []], true);
|
|
560
|
-
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)));
|
|
561
637
|
return held.map(accepted);
|
|
562
638
|
},
|
|
563
639
|
async messageIdentities(conversation) {
|
|
564
|
-
const
|
|
565
|
-
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)));
|
|
566
641
|
return keys.map((key) => key[1]);
|
|
567
642
|
},
|
|
568
643
|
async turnArrived(conversation, turn) {
|
|
569
|
-
const
|
|
570
|
-
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])));
|
|
571
645
|
return held > 0;
|
|
572
646
|
},
|
|
573
647
|
async dropConversations(conversations) {
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
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
|
+
});
|
|
589
663
|
},
|
|
590
664
|
async chatDrafts() {
|
|
591
|
-
const
|
|
592
|
-
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()));
|
|
593
666
|
return held.map(chatDraftRecord);
|
|
594
667
|
},
|
|
595
668
|
async keepChatDrafts(records) {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
669
|
+
await transacted(authored, CHAT_DRAFTS, 'readwrite', (transaction) => {
|
|
670
|
+
for (const record of records)
|
|
671
|
+
transaction.objectStore(CHAT_DRAFTS).put(record);
|
|
672
|
+
});
|
|
600
673
|
},
|
|
601
674
|
async dropChatDraft(conversation) {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
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
|
+
});
|
|
605
691
|
},
|
|
606
692
|
async keepRoomDraft(record) {
|
|
607
693
|
if (fenced(record.locator))
|
|
608
694
|
return;
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
695
|
+
await transacted(authored, ROOM_DRAFTS, 'readwrite', (transaction) => {
|
|
696
|
+
transaction.objectStore(ROOM_DRAFTS).put(record);
|
|
697
|
+
});
|
|
612
698
|
},
|
|
613
699
|
async discardRoomDraft(locator, path) {
|
|
614
700
|
if (fenced(locator))
|
|
615
701
|
return;
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
702
|
+
await transacted(authored, ROOM_DRAFTS, 'readwrite', (transaction) => {
|
|
703
|
+
transaction.objectStore(ROOM_DRAFTS).delete([locator, path]);
|
|
704
|
+
});
|
|
619
705
|
},
|
|
620
706
|
async fences() {
|
|
621
|
-
const
|
|
622
|
-
const held = await settled(transaction.objectStore(FENCES).getAll());
|
|
707
|
+
const held = await transacted(authored, FENCES, 'readonly', (transaction) => settled(transaction.objectStore(FENCES).getAll()));
|
|
623
708
|
return held.map((fence) => fence.locator);
|
|
624
709
|
},
|
|
625
710
|
async erase(locators) {
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
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
|
+
}
|
|
632
718
|
}
|
|
633
|
-
}
|
|
634
|
-
await
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
}
|
|
642
|
-
await
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
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
|
+
});
|
|
647
732
|
},
|
|
648
733
|
async discard(locator) {
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
734
|
+
await transacted(authored, [QUEUES, PENDING_CHANGES], 'readwrite', (transaction) => {
|
|
735
|
+
transaction.objectStore(QUEUES).delete(locator);
|
|
736
|
+
removeRoomEntries(transaction.objectStore(PENDING_CHANGES), locator);
|
|
737
|
+
});
|
|
653
738
|
},
|
|
654
739
|
async transfers() {
|
|
655
|
-
const
|
|
656
|
-
const held = await settled(transaction.objectStore(TRANSFERS).getAll());
|
|
740
|
+
const held = await transacted(database, TRANSFERS, 'readonly', (transaction) => settled(transaction.objectStore(TRANSFERS).getAll()));
|
|
657
741
|
return held.filter((record) => !fenced(record.locator));
|
|
658
742
|
},
|
|
659
743
|
staged(record) {
|
|
660
|
-
|
|
661
|
-
return readLayer(transaction, record.locator, record.transfer);
|
|
744
|
+
return transacted(database, [DOCUMENTS, BINARY_FILES], 'readonly', (transaction) => readLayer(transaction, record.locator, record.transfer));
|
|
662
745
|
},
|
|
663
746
|
async stage(record, page) {
|
|
664
747
|
if (fenced(record.locator))
|
|
665
748
|
return;
|
|
666
|
-
const
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
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
|
+
});
|
|
670
760
|
},
|
|
671
761
|
async abandon(locator) {
|
|
672
762
|
if (fenced(locator))
|
|
673
763
|
return;
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
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
|
+
});
|
|
687
777
|
},
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
return settled(transaction.objectStore(RECEIVED).getAll());
|
|
778
|
+
receivedHeads() {
|
|
779
|
+
return transacted(database, RECEIVED, 'readonly', (transaction) => settled(transaction.objectStore(RECEIVED).getAll()));
|
|
691
780
|
},
|
|
692
781
|
async receivedParts(key, count) {
|
|
693
|
-
const
|
|
694
|
-
const kept = await settled(transaction
|
|
782
|
+
const kept = await transacted(database, RECEIVED_PARTS, 'readonly', (transaction) => settled(transaction
|
|
695
783
|
.objectStore(RECEIVED_PARTS)
|
|
696
|
-
.getAll(IDBKeyRange.bound([key, 0], [key, count], false, true)));
|
|
784
|
+
.getAll(IDBKeyRange.bound([key, 0], [key, count], false, true))));
|
|
697
785
|
return kept.map((part) => part.value);
|
|
698
786
|
},
|
|
699
787
|
async keepReceived(key, head, part) {
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
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
|
+
});
|
|
705
793
|
},
|
|
706
794
|
async dropReceived(keys) {
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
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
|
+
});
|
|
713
801
|
},
|
|
714
802
|
async generation() {
|
|
715
|
-
const
|
|
716
|
-
const held = await settled(transaction.objectStore(FACTS).get(GENERATION));
|
|
803
|
+
const held = await transacted(authored, FACTS, 'readonly', (transaction) => settled(transaction.objectStore(FACTS).get(GENERATION)));
|
|
717
804
|
return held ?? null;
|
|
718
805
|
},
|
|
719
806
|
async rememberGeneration(value) {
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
807
|
+
await transacted(authored, FACTS, 'readwrite', (transaction) => {
|
|
808
|
+
transaction.objectStore(FACTS).put(value, GENERATION);
|
|
809
|
+
});
|
|
723
810
|
},
|
|
724
811
|
close() {
|
|
725
|
-
authored
|
|
726
|
-
|
|
812
|
+
for (const held of [authored, database])
|
|
813
|
+
void idle(held).then(() => held.close());
|
|
727
814
|
},
|
|
728
815
|
};
|
|
729
816
|
}
|