@agentshouse/mdruntime 0.1.0-c69ca0e865e0b → 0.1.0-c6fd2cbbff187
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 +275 -275
- package/dist/acquisition.d.ts +14 -0
- package/dist/acquisition.d.ts.map +1 -0
- package/dist/acquisition.js +24 -0
- package/dist/adapter.d.ts +50 -9
- package/dist/adapter.d.ts.map +1 -1
- package/dist/bootstrap.d.ts +3 -2
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +26 -4
- package/dist/change-set.d.ts +2 -0
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +36 -10
- package/dist/chat/acts.d.ts +3 -4
- package/dist/chat/acts.d.ts.map +1 -1
- package/dist/chat/acts.js +10 -10
- 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.d.ts +2 -1
- package/dist/chat/kit.d.ts.map +1 -1
- package/dist/chat/kit.js +3 -3
- package/dist/chat/list.d.ts +2 -1
- package/dist/chat/list.d.ts.map +1 -1
- package/dist/chat/list.js +42 -5
- package/dist/chat/message.d.ts.map +1 -1
- package/dist/chat/message.js +2 -2
- package/dist/chat/messages.d.ts +1 -0
- package/dist/chat/messages.d.ts.map +1 -1
- package/dist/chat/messages.js +4 -0
- package/dist/chat/provider.d.ts +1 -1
- package/dist/chat/provider.d.ts.map +1 -1
- package/dist/chat/provider.js +59 -69
- 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 -0
- package/dist/chat/ready.d.ts.map +1 -1
- package/dist/chat/ready.js +2 -2
- package/dist/chat/style.js +1 -1
- package/dist/client.d.ts +14 -8
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +17 -6
- package/dist/collection.d.ts +17 -3
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +230 -19
- package/dist/connection.d.ts +27 -8
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +1567 -362
- package/dist/conversation.d.ts +19 -7
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +438 -152
- package/dist/durability.d.ts +7 -1
- package/dist/durability.d.ts.map +1 -1
- package/dist/entry.d.ts +2 -2
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +3 -3
- package/dist/fence.d.ts +6 -0
- package/dist/fence.d.ts.map +1 -0
- package/dist/fence.js +10 -0
- package/dist/host.d.ts +17 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +90 -9
- package/dist/identity.d.ts +2 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +6 -0
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/memory.d.ts +9 -2
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +36 -7
- package/dist/model.d.ts +4 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +10 -1
- package/dist/observation.d.ts +7 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +29 -12
- package/dist/outcome.d.ts +12 -2
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +4 -0
- package/dist/overlay.d.ts +2 -0
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +58 -55
- package/dist/query.d.ts +56 -4
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +36 -7
- package/dist/reach.d.ts +6 -3
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +20 -5
- package/dist/react.d.ts +7 -4
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +6 -4
- package/dist/read-side.d.ts +13 -6
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +419 -92
- package/dist/readiness.d.ts +53 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +33 -0
- package/dist/reads.d.ts +11 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +98 -0
- package/dist/recovery.d.ts +25 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +197 -0
- package/dist/refresh.d.ts +4 -4
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +17 -10
- package/dist/replica.d.ts +6 -2
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +76 -23
- package/dist/room-draft.d.ts +13 -1
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +2 -2
- package/dist/rows.d.ts +6 -13
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +10 -13
- package/dist/save.d.ts +6 -0
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +53 -14
- package/dist/search.d.ts +49 -6
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +192 -47
- 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 +11 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +368 -0
- package/dist/status.d.ts +4 -0
- package/dist/status.d.ts.map +1 -1
- package/dist/store.d.ts +56 -11
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +311 -84
- package/dist/turn.d.ts +7 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +45 -0
- package/dist/windows.d.ts +19 -0
- package/dist/windows.d.ts.map +1 -0
- package/dist/windows.js +83 -0
- package/dist/wire.d.ts +144 -32
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +50 -31
- package/package.json +2 -2
package/dist/store.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { sameBinary, sameChange } from './overlay.js';
|
|
2
|
+
import { differing } from './shared.js';
|
|
2
3
|
const DATABASE = 'mdruntime';
|
|
3
4
|
const AUTHORED = 'mdruntime-authored';
|
|
5
|
+
const FENCES = 'fences';
|
|
4
6
|
const ROOMS = 'rooms';
|
|
5
7
|
const DOCUMENTS = 'documents';
|
|
6
8
|
const BINARY_FILES = 'binaryFiles';
|
|
7
9
|
const TRANSFERS = 'transfers';
|
|
10
|
+
const RECEIVED = 'received';
|
|
11
|
+
const RECEIVED_PARTS = 'receivedParts';
|
|
8
12
|
const PENDING_CHANGES = 'pendingChanges';
|
|
9
13
|
const DECLARATIONS = 'declarations';
|
|
10
14
|
const ROOM_DRAFTS = 'roomDrafts';
|
|
@@ -12,22 +16,45 @@ const PRESENTATION = 'presentation';
|
|
|
12
16
|
const CONVERSATIONS = 'conversations';
|
|
13
17
|
const MESSAGES = 'messages';
|
|
14
18
|
const CHAT_DRAFTS = 'chatDrafts';
|
|
19
|
+
const CALLS = 'calls';
|
|
15
20
|
const QUEUES = 'queues';
|
|
16
21
|
const FACTS = 'facts';
|
|
17
22
|
const CURRENT = 'current';
|
|
18
23
|
const MEMBER = 'member';
|
|
24
|
+
const TARGETS = 'targets';
|
|
19
25
|
const GENERATION = 'generation';
|
|
20
26
|
const HOLDER = 'holder';
|
|
21
|
-
|
|
22
|
-
export const
|
|
27
|
+
const BINDING = 'binding';
|
|
28
|
+
export const STORE_SCHEMA = 25;
|
|
29
|
+
const REPLICA_SHAPE = 23;
|
|
30
|
+
export const AUTHORED_SCHEMA = 3;
|
|
23
31
|
const AUTHORED_STORES = [
|
|
24
32
|
[QUEUES, { keyPath: 'locator' }],
|
|
25
33
|
[PENDING_CHANGES, { keyPath: ['locator', 'id'] }],
|
|
26
34
|
[ROOM_DRAFTS, { keyPath: ['locator', 'path'] }],
|
|
27
35
|
[CHAT_DRAFTS, { keyPath: 'conversation' }],
|
|
36
|
+
[CALLS, { keyPath: 'operation' }],
|
|
28
37
|
[FACTS, undefined],
|
|
38
|
+
[FENCES, { keyPath: 'locator' }],
|
|
39
|
+
];
|
|
40
|
+
const REPLICA_STORES = [
|
|
41
|
+
[ROOMS, { keyPath: 'locator' }],
|
|
42
|
+
[DOCUMENTS, { keyPath: ['locator', 'transfer', 'path'] }],
|
|
43
|
+
[BINARY_FILES, { keyPath: ['locator', 'transfer', 'path'] }],
|
|
44
|
+
[TRANSFERS, { keyPath: 'locator' }],
|
|
45
|
+
[RECEIVED, { keyPath: 'key' }],
|
|
46
|
+
[RECEIVED_PARTS, { keyPath: ['key', 'index'] }],
|
|
47
|
+
[DECLARATIONS, undefined],
|
|
48
|
+
[PRESENTATION, { keyPath: 'app' }],
|
|
49
|
+
[CONVERSATIONS, { keyPath: 'conversation' }],
|
|
50
|
+
[MESSAGES, { keyPath: ['conversation', 'identity'] }],
|
|
29
51
|
];
|
|
30
52
|
const READ_BATCH = 256;
|
|
53
|
+
const MESSAGE_INDEXES = [
|
|
54
|
+
['conversation', 'conversation'],
|
|
55
|
+
['position', ['conversation', 'position']],
|
|
56
|
+
['turn', ['conversation', 'turn']],
|
|
57
|
+
];
|
|
31
58
|
function settled(request) {
|
|
32
59
|
return new Promise((resolve, reject) => {
|
|
33
60
|
request.onsuccess = () => resolve(request.result);
|
|
@@ -70,8 +97,11 @@ function amendPending(database, locator, id, amendment) {
|
|
|
70
97
|
};
|
|
71
98
|
return completed(transaction);
|
|
72
99
|
}
|
|
100
|
+
function accepted({ conversation: _held, ...message }) {
|
|
101
|
+
return message;
|
|
102
|
+
}
|
|
73
103
|
function roomRecord(record) {
|
|
74
|
-
const { documents, binaries, revisions, changes, written, ...room } = record;
|
|
104
|
+
const { documents, binaries, revisions, fileIds, changes, written, ...room } = record;
|
|
75
105
|
return room;
|
|
76
106
|
}
|
|
77
107
|
function chatDraftRecord(record) {
|
|
@@ -97,13 +127,15 @@ async function readTransfer(store, locator, transfer, receive) {
|
|
|
97
127
|
}
|
|
98
128
|
}
|
|
99
129
|
function emptyLayer() {
|
|
100
|
-
return { documents: {}, binaries: {}, revisions: {}, changes: {}, written: {} };
|
|
130
|
+
return { documents: {}, binaries: {}, revisions: {}, fileIds: {}, changes: {}, written: {} };
|
|
101
131
|
}
|
|
102
132
|
async function readLayer(transaction, locator, transfer) {
|
|
103
133
|
const layer = emptyLayer();
|
|
104
134
|
const head = (held) => {
|
|
105
135
|
if (held.revision !== null)
|
|
106
136
|
layer.revisions[held.path] = held.revision;
|
|
137
|
+
if (held.fileId !== null)
|
|
138
|
+
layer.fileIds[held.path] = held.fileId;
|
|
107
139
|
if (held.change !== null)
|
|
108
140
|
layer.changes[held.path] = held.change;
|
|
109
141
|
};
|
|
@@ -126,6 +158,7 @@ function documentRecord(locator, transfer, layer, path) {
|
|
|
126
158
|
path,
|
|
127
159
|
content: layer.documents[path],
|
|
128
160
|
revision: layer.revisions[path] ?? null,
|
|
161
|
+
fileId: layer.fileIds[path] ?? null,
|
|
129
162
|
change: layer.changes[path] ?? null,
|
|
130
163
|
written: layer.written[path] ?? null,
|
|
131
164
|
};
|
|
@@ -136,35 +169,37 @@ function binaryFileRecord(locator, transfer, layer, path) {
|
|
|
136
169
|
transfer,
|
|
137
170
|
path,
|
|
138
171
|
revision: layer.revisions[path] ?? null,
|
|
172
|
+
fileId: layer.fileIds[path] ?? null,
|
|
139
173
|
change: layer.changes[path] ?? null,
|
|
140
174
|
binary: layer.binaries[path],
|
|
141
175
|
};
|
|
142
176
|
}
|
|
143
177
|
function writeLayer(transaction, locator, transfer, next, base) {
|
|
144
178
|
const documents = transaction.objectStore(DOCUMENTS);
|
|
145
|
-
for (const path of Object.keys(base?.documents ?? {})) {
|
|
146
|
-
if (next.documents[path] === undefined)
|
|
147
|
-
documents.delete([locator, transfer, path]);
|
|
148
|
-
}
|
|
149
|
-
for (const [path, content] of Object.entries(next.documents)) {
|
|
150
|
-
if (base?.documents[path] === content &&
|
|
151
|
-
base.revisions[path] === next.revisions[path] &&
|
|
152
|
-
base.written[path] === next.written[path] &&
|
|
153
|
-
sameChange(base.changes[path], next.changes[path]))
|
|
154
|
-
continue;
|
|
155
|
-
documents.put(documentRecord(locator, transfer, next, path));
|
|
156
|
-
}
|
|
157
179
|
const files = transaction.objectStore(BINARY_FILES);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
base
|
|
165
|
-
|
|
180
|
+
const paths = base === null
|
|
181
|
+
? new Set([...Object.keys(next.documents), ...Object.keys(next.binaries)])
|
|
182
|
+
: new Set([
|
|
183
|
+
...differing(base.documents, next.documents),
|
|
184
|
+
...differing(base.revisions, next.revisions),
|
|
185
|
+
...differing(base.fileIds, next.fileIds),
|
|
186
|
+
...differing(base.written, next.written),
|
|
187
|
+
...differing(base.changes, next.changes, sameChange),
|
|
188
|
+
...differing(base.binaries, next.binaries, sameBinary),
|
|
189
|
+
]);
|
|
190
|
+
for (const path of paths) {
|
|
191
|
+
if (next.documents[path] !== undefined) {
|
|
192
|
+
documents.put(documentRecord(locator, transfer, next, path));
|
|
193
|
+
}
|
|
194
|
+
else if (base?.documents[path] !== undefined) {
|
|
195
|
+
documents.delete([locator, transfer, path]);
|
|
196
|
+
}
|
|
197
|
+
if (next.binaries[path] !== undefined) {
|
|
166
198
|
files.put(binaryFileRecord(locator, transfer, next, path));
|
|
167
199
|
}
|
|
200
|
+
else if (base?.binaries[path] !== undefined) {
|
|
201
|
+
files.delete([locator, transfer, path]);
|
|
202
|
+
}
|
|
168
203
|
}
|
|
169
204
|
}
|
|
170
205
|
function removeRoomEntries(store, locator) {
|
|
@@ -215,6 +250,29 @@ export async function authoredBy(holder) {
|
|
|
215
250
|
authored.close();
|
|
216
251
|
}
|
|
217
252
|
}
|
|
253
|
+
export async function authoredBinding() {
|
|
254
|
+
const authored = await openAuthored();
|
|
255
|
+
try {
|
|
256
|
+
const transaction = authored.transaction(FACTS, 'readonly');
|
|
257
|
+
const held = transaction.objectStore(FACTS).get(BINDING);
|
|
258
|
+
await completed(transaction);
|
|
259
|
+
return typeof held.result === 'string' ? held.result : null;
|
|
260
|
+
}
|
|
261
|
+
finally {
|
|
262
|
+
authored.close();
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
export async function bindAuthored(binding) {
|
|
266
|
+
const authored = await openAuthored();
|
|
267
|
+
try {
|
|
268
|
+
const transaction = authored.transaction(FACTS, 'readwrite');
|
|
269
|
+
transaction.objectStore(FACTS).put(binding, BINDING);
|
|
270
|
+
await completed(transaction);
|
|
271
|
+
}
|
|
272
|
+
finally {
|
|
273
|
+
authored.close();
|
|
274
|
+
}
|
|
275
|
+
}
|
|
218
276
|
export async function removeRuntimeStore(holder) {
|
|
219
277
|
await removeDatabase(DATABASE);
|
|
220
278
|
if (holder !== undefined && (await authoredBy(holder)))
|
|
@@ -222,38 +280,51 @@ export async function removeRuntimeStore(holder) {
|
|
|
222
280
|
await removeDatabase(AUTHORED);
|
|
223
281
|
return false;
|
|
224
282
|
}
|
|
283
|
+
export function openDatabase(name, version, upgrade) {
|
|
284
|
+
return new Promise((resolve, reject) => {
|
|
285
|
+
const opening = indexedDB.open(name, version);
|
|
286
|
+
opening.onupgradeneeded = (event) => upgrade(opening, event.oldVersion);
|
|
287
|
+
opening.onsuccess = () => resolve(opening.result);
|
|
288
|
+
opening.onerror = () => {
|
|
289
|
+
if (opening.error?.name !== 'VersionError') {
|
|
290
|
+
reject(opening.error);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
removeDatabase(name)
|
|
294
|
+
.then(() => openDatabase(name, version, upgrade))
|
|
295
|
+
.then(resolve, reject);
|
|
296
|
+
};
|
|
297
|
+
});
|
|
298
|
+
}
|
|
225
299
|
function openReplica() {
|
|
226
|
-
|
|
227
|
-
opening.onupgradeneeded = () => {
|
|
300
|
+
return openDatabase(DATABASE, STORE_SCHEMA, (opening, oldVersion) => {
|
|
228
301
|
const database = opening.result;
|
|
229
|
-
|
|
230
|
-
database.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const messages =
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
302
|
+
if (oldVersion < REPLICA_SHAPE) {
|
|
303
|
+
for (const name of [...database.objectStoreNames])
|
|
304
|
+
database.deleteObjectStore(name);
|
|
305
|
+
}
|
|
306
|
+
for (const [name, parameters] of REPLICA_STORES) {
|
|
307
|
+
if (database.objectStoreNames.contains(name))
|
|
308
|
+
continue;
|
|
309
|
+
database.createObjectStore(name, parameters);
|
|
310
|
+
}
|
|
311
|
+
const messages = opening.transaction.objectStore(MESSAGES);
|
|
312
|
+
for (const [name, keyPath] of MESSAGE_INDEXES) {
|
|
313
|
+
if (!messages.indexNames.contains(name))
|
|
314
|
+
messages.createIndex(name, keyPath);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
244
317
|
}
|
|
245
318
|
function openAuthored() {
|
|
246
|
-
|
|
247
|
-
opening.onupgradeneeded = () => {
|
|
319
|
+
return openDatabase(AUTHORED, AUTHORED_SCHEMA, (opening) => {
|
|
248
320
|
const database = opening.result;
|
|
249
321
|
for (const [name, parameters] of AUTHORED_STORES) {
|
|
250
322
|
if (!database.objectStoreNames.contains(name))
|
|
251
323
|
database.createObjectStore(name, parameters);
|
|
252
324
|
}
|
|
253
|
-
};
|
|
254
|
-
return settled(opening);
|
|
325
|
+
});
|
|
255
326
|
}
|
|
256
|
-
export async function openRuntimeStore() {
|
|
327
|
+
export async function openRuntimeStore(fenced) {
|
|
257
328
|
const authored = await openAuthored();
|
|
258
329
|
const database = await openReplica().catch((error) => {
|
|
259
330
|
authored.close();
|
|
@@ -264,12 +335,14 @@ export async function openRuntimeStore() {
|
|
|
264
335
|
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES], 'readonly');
|
|
265
336
|
const rooms = await settled(transaction.objectStore(ROOMS).getAll());
|
|
266
337
|
const records = [];
|
|
267
|
-
for (const room of rooms) {
|
|
338
|
+
for (const room of rooms.filter((held) => !fenced(held.locator))) {
|
|
268
339
|
records.push({ ...room, ...(await readLayer(transaction, room.locator, room.transfer)) });
|
|
269
340
|
}
|
|
270
341
|
return records;
|
|
271
342
|
},
|
|
272
|
-
async keepAuthored({ locator, queue, saved, roomDrafts, consumedRoomDrafts }) {
|
|
343
|
+
async keepAuthored({ locator, queue, founded, saved, roomDrafts, consumedRoomDrafts }) {
|
|
344
|
+
if (fenced(locator))
|
|
345
|
+
return;
|
|
273
346
|
const transaction = authored.transaction([QUEUES, PENDING_CHANGES, ROOM_DRAFTS], 'readwrite');
|
|
274
347
|
const order = transaction.objectStore(QUEUES);
|
|
275
348
|
const pending = transaction.objectStore(PENDING_CHANGES);
|
|
@@ -297,6 +370,16 @@ export async function openRuntimeStore() {
|
|
|
297
370
|
});
|
|
298
371
|
}
|
|
299
372
|
}
|
|
373
|
+
for (const batch of founded ?? []) {
|
|
374
|
+
if (!before.has(batch.id))
|
|
375
|
+
continue;
|
|
376
|
+
const stored = pending.get([locator, batch.id]);
|
|
377
|
+
stored.onsuccess = () => {
|
|
378
|
+
const record = stored.result;
|
|
379
|
+
if (record !== undefined)
|
|
380
|
+
pending.put({ ...record, batch });
|
|
381
|
+
};
|
|
382
|
+
}
|
|
300
383
|
};
|
|
301
384
|
const draftStore = transaction.objectStore(ROOM_DRAFTS);
|
|
302
385
|
for (const path of consumedRoomDrafts ?? [])
|
|
@@ -306,7 +389,7 @@ export async function openRuntimeStore() {
|
|
|
306
389
|
await completed(transaction);
|
|
307
390
|
},
|
|
308
391
|
async write({ next, previous, stored }) {
|
|
309
|
-
if (next === previous)
|
|
392
|
+
if (next === previous || fenced(next.locator))
|
|
310
393
|
return;
|
|
311
394
|
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES, TRANSFERS], 'readwrite');
|
|
312
395
|
transaction.objectStore(ROOMS).put(roomRecord(next));
|
|
@@ -326,6 +409,8 @@ export async function openRuntimeStore() {
|
|
|
326
409
|
const rooms = transaction.objectStore(ROOMS);
|
|
327
410
|
const revoked = { status: 'unavailable', reason: 'revoked' };
|
|
328
411
|
for (const record of records) {
|
|
412
|
+
if (fenced(record.locator))
|
|
413
|
+
continue;
|
|
329
414
|
rooms.put(roomRecord({ ...record, model: revoked, selectionModel: revoked }));
|
|
330
415
|
}
|
|
331
416
|
await completed(transaction);
|
|
@@ -359,6 +444,16 @@ export async function openRuntimeStore() {
|
|
|
359
444
|
transaction.objectStore(DECLARATIONS).put(member, MEMBER);
|
|
360
445
|
await completed(transaction);
|
|
361
446
|
},
|
|
447
|
+
async targets() {
|
|
448
|
+
const transaction = database.transaction(DECLARATIONS, 'readonly');
|
|
449
|
+
const held = await settled(transaction.objectStore(DECLARATIONS).get(TARGETS));
|
|
450
|
+
return held ?? {};
|
|
451
|
+
},
|
|
452
|
+
async keepTargets(targets) {
|
|
453
|
+
const transaction = database.transaction(DECLARATIONS, 'readwrite');
|
|
454
|
+
transaction.objectStore(DECLARATIONS).put(targets, TARGETS);
|
|
455
|
+
await completed(transaction);
|
|
456
|
+
},
|
|
362
457
|
async queues() {
|
|
363
458
|
const transaction = authored.transaction([QUEUES, PENDING_CHANGES], 'readonly');
|
|
364
459
|
const [queues, pending] = await Promise.all([
|
|
@@ -366,7 +461,9 @@ export async function openRuntimeStore() {
|
|
|
366
461
|
settled(transaction.objectStore(PENDING_CHANGES).getAll()),
|
|
367
462
|
]);
|
|
368
463
|
const byId = new Map(pending.map((record) => [`${record.locator}\0${record.id}`, record]));
|
|
369
|
-
return queues
|
|
464
|
+
return queues
|
|
465
|
+
.filter((queue) => !fenced(queue.locator))
|
|
466
|
+
.map((queue) => ({
|
|
370
467
|
locator: queue.locator,
|
|
371
468
|
pending: queue.order.map((id) => {
|
|
372
469
|
const record = byId.get(`${queue.locator}\0${id}`);
|
|
@@ -377,18 +474,22 @@ export async function openRuntimeStore() {
|
|
|
377
474
|
}),
|
|
378
475
|
}));
|
|
379
476
|
},
|
|
380
|
-
submit(locator, id, submission, lost) {
|
|
381
|
-
|
|
477
|
+
async submit(locator, id, submission, lost) {
|
|
478
|
+
if (!fenced(locator))
|
|
479
|
+
await amendPending(authored, locator, id, { submission, lost });
|
|
382
480
|
},
|
|
383
|
-
accept(locator, id, roomVersion) {
|
|
384
|
-
|
|
481
|
+
async accept(locator, id, roomVersion) {
|
|
482
|
+
if (!fenced(locator))
|
|
483
|
+
await amendPending(authored, locator, id, { accepted: roomVersion });
|
|
385
484
|
},
|
|
386
|
-
keepUpload(locator, id, upload) {
|
|
387
|
-
|
|
485
|
+
async keepUpload(locator, id, upload) {
|
|
486
|
+
if (!fenced(locator))
|
|
487
|
+
await amendPending(authored, locator, id, { upload });
|
|
388
488
|
},
|
|
389
489
|
async roomDrafts() {
|
|
390
490
|
const transaction = authored.transaction(ROOM_DRAFTS, 'readonly');
|
|
391
|
-
|
|
491
|
+
const held = await settled(transaction.objectStore(ROOM_DRAFTS).getAll());
|
|
492
|
+
return held.filter((record) => !fenced(record.locator));
|
|
392
493
|
},
|
|
393
494
|
async presentation() {
|
|
394
495
|
const transaction = database.transaction(PRESENTATION, 'readonly');
|
|
@@ -401,39 +502,99 @@ export async function openRuntimeStore() {
|
|
|
401
502
|
},
|
|
402
503
|
async conversations() {
|
|
403
504
|
const transaction = database.transaction([CONVERSATIONS, MESSAGES], 'readonly');
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
505
|
+
const records = await settled(transaction.objectStore(CONVERSATIONS).getAll());
|
|
506
|
+
const held = new Map(records.map(({ conversation, read, partial }) => [
|
|
507
|
+
conversation,
|
|
508
|
+
{ conversation, read, partial: partial === true },
|
|
509
|
+
]));
|
|
510
|
+
const keys = transaction.objectStore(MESSAGES).index('conversation');
|
|
511
|
+
await new Promise((resolve, reject) => {
|
|
512
|
+
const cursor = keys.openKeyCursor(null, 'nextunique');
|
|
513
|
+
cursor.onerror = () => reject(cursor.error);
|
|
514
|
+
cursor.onsuccess = () => {
|
|
515
|
+
const at = cursor.result;
|
|
516
|
+
if (at === null) {
|
|
517
|
+
resolve();
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
const conversation = at.key;
|
|
521
|
+
if (!held.has(conversation)) {
|
|
522
|
+
held.set(conversation, { conversation, read: undefined, partial: true });
|
|
523
|
+
}
|
|
524
|
+
at.continue();
|
|
525
|
+
};
|
|
526
|
+
});
|
|
417
527
|
return [...held.values()];
|
|
418
528
|
},
|
|
419
|
-
async keepMessages({ conversation, messages, read
|
|
420
|
-
if (sealed === true) {
|
|
421
|
-
const sealing = authored.transaction(CHAT_DRAFTS, 'readwrite');
|
|
422
|
-
sealing.objectStore(CHAT_DRAFTS).delete(conversation);
|
|
423
|
-
await completed(sealing);
|
|
424
|
-
}
|
|
529
|
+
async keepMessages({ conversation, messages, read }) {
|
|
425
530
|
const transaction = database.transaction([CONVERSATIONS, MESSAGES], 'readwrite');
|
|
426
531
|
const stored = transaction.objectStore(MESSAGES);
|
|
427
532
|
for (const message of messages) {
|
|
428
533
|
stored.put({ ...message, conversation });
|
|
429
534
|
}
|
|
430
535
|
if (read !== undefined) {
|
|
431
|
-
transaction
|
|
432
|
-
|
|
433
|
-
.
|
|
536
|
+
transaction.objectStore(CONVERSATIONS).put({
|
|
537
|
+
conversation,
|
|
538
|
+
read: read.at,
|
|
539
|
+
...(read.partial ? { partial: true } : {}),
|
|
540
|
+
});
|
|
434
541
|
}
|
|
435
542
|
await completed(transaction);
|
|
436
543
|
},
|
|
544
|
+
async messageWindow(conversation, limit, before) {
|
|
545
|
+
const transaction = database.transaction(MESSAGES, 'readonly');
|
|
546
|
+
const index = transaction.objectStore(MESSAGES).index('position');
|
|
547
|
+
const range = IDBKeyRange.bound([conversation], [conversation, before?.[0] ?? []]);
|
|
548
|
+
const earlier = ({ position, identity }) => before === null || position < before[0] || (position === before[0] && identity < before[1]);
|
|
549
|
+
const latest = [];
|
|
550
|
+
let more = false;
|
|
551
|
+
await new Promise((resolve, reject) => {
|
|
552
|
+
const cursor = index.openCursor(range, 'prev');
|
|
553
|
+
cursor.onerror = () => reject(cursor.error);
|
|
554
|
+
cursor.onsuccess = () => {
|
|
555
|
+
const at = cursor.result;
|
|
556
|
+
if (at === null) {
|
|
557
|
+
resolve();
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
const record = at.value;
|
|
561
|
+
if (!earlier(record)) {
|
|
562
|
+
at.continue();
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
if (latest.length === limit) {
|
|
566
|
+
more = true;
|
|
567
|
+
resolve();
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
latest.push(accepted(record));
|
|
571
|
+
at.continue();
|
|
572
|
+
};
|
|
573
|
+
});
|
|
574
|
+
return { messages: latest.reverse(), more };
|
|
575
|
+
},
|
|
576
|
+
async messageCount(conversation) {
|
|
577
|
+
const transaction = database.transaction(MESSAGES, 'readonly');
|
|
578
|
+
return settled(transaction.objectStore(MESSAGES).index('conversation').count(conversation));
|
|
579
|
+
},
|
|
580
|
+
async messagesAfter(conversation, identity) {
|
|
581
|
+
const transaction = database.transaction(MESSAGES, 'readonly');
|
|
582
|
+
const range = identity === null
|
|
583
|
+
? IDBKeyRange.bound([conversation], [conversation, []])
|
|
584
|
+
: IDBKeyRange.bound([conversation, identity], [conversation, []], true);
|
|
585
|
+
const held = await settled(transaction.objectStore(MESSAGES).getAll(range, READ_BATCH));
|
|
586
|
+
return held.map(accepted);
|
|
587
|
+
},
|
|
588
|
+
async messageIdentities(conversation) {
|
|
589
|
+
const transaction = database.transaction(MESSAGES, 'readonly');
|
|
590
|
+
const keys = await settled(transaction.objectStore(MESSAGES).index('conversation').getAllKeys(conversation));
|
|
591
|
+
return keys.map((key) => key[1]);
|
|
592
|
+
},
|
|
593
|
+
async turnArrived(conversation, turn) {
|
|
594
|
+
const transaction = database.transaction(MESSAGES, 'readonly');
|
|
595
|
+
const held = await settled(transaction.objectStore(MESSAGES).index('turn').count([conversation, turn]));
|
|
596
|
+
return held > 0;
|
|
597
|
+
},
|
|
437
598
|
async dropConversations(conversations) {
|
|
438
599
|
const drafts = authored.transaction(CHAT_DRAFTS, 'readwrite');
|
|
439
600
|
for (const conversation of conversations)
|
|
@@ -456,9 +617,10 @@ export async function openRuntimeStore() {
|
|
|
456
617
|
const held = await settled(transaction.objectStore(CHAT_DRAFTS).getAll());
|
|
457
618
|
return held.map(chatDraftRecord);
|
|
458
619
|
},
|
|
459
|
-
async
|
|
620
|
+
async keepChatDrafts(records) {
|
|
460
621
|
const transaction = authored.transaction(CHAT_DRAFTS, 'readwrite');
|
|
461
|
-
|
|
622
|
+
for (const record of records)
|
|
623
|
+
transaction.objectStore(CHAT_DRAFTS).put(record);
|
|
462
624
|
await completed(transaction);
|
|
463
625
|
},
|
|
464
626
|
async dropChatDraft(conversation) {
|
|
@@ -466,19 +628,43 @@ export async function openRuntimeStore() {
|
|
|
466
628
|
transaction.objectStore(CHAT_DRAFTS).delete(conversation);
|
|
467
629
|
await completed(transaction);
|
|
468
630
|
},
|
|
631
|
+
async calls() {
|
|
632
|
+
const transaction = authored.transaction(CALLS, 'readonly');
|
|
633
|
+
return settled(transaction.objectStore(CALLS).getAll());
|
|
634
|
+
},
|
|
635
|
+
async keepCall(record) {
|
|
636
|
+
const transaction = authored.transaction(CALLS, 'readwrite');
|
|
637
|
+
transaction.objectStore(CALLS).put(record);
|
|
638
|
+
await completed(transaction);
|
|
639
|
+
},
|
|
640
|
+
async dropCall(operation) {
|
|
641
|
+
const transaction = authored.transaction(CALLS, 'readwrite');
|
|
642
|
+
transaction.objectStore(CALLS).delete(operation);
|
|
643
|
+
await completed(transaction);
|
|
644
|
+
},
|
|
469
645
|
async keepRoomDraft(record) {
|
|
646
|
+
if (fenced(record.locator))
|
|
647
|
+
return;
|
|
470
648
|
const transaction = authored.transaction(ROOM_DRAFTS, 'readwrite');
|
|
471
649
|
transaction.objectStore(ROOM_DRAFTS).put(record);
|
|
472
650
|
await completed(transaction);
|
|
473
651
|
},
|
|
474
652
|
async discardRoomDraft(locator, path) {
|
|
653
|
+
if (fenced(locator))
|
|
654
|
+
return;
|
|
475
655
|
const transaction = authored.transaction(ROOM_DRAFTS, 'readwrite');
|
|
476
656
|
transaction.objectStore(ROOM_DRAFTS).delete([locator, path]);
|
|
477
657
|
await completed(transaction);
|
|
478
658
|
},
|
|
479
|
-
async
|
|
480
|
-
const
|
|
659
|
+
async fences() {
|
|
660
|
+
const transaction = authored.transaction(FENCES, 'readonly');
|
|
661
|
+
const held = await settled(transaction.objectStore(FENCES).getAll());
|
|
662
|
+
return held.map((fence) => fence.locator);
|
|
663
|
+
},
|
|
664
|
+
async erase(locators) {
|
|
665
|
+
const work = authored.transaction([FENCES, QUEUES, PENDING_CHANGES, ROOM_DRAFTS], 'readwrite');
|
|
481
666
|
for (const locator of locators) {
|
|
667
|
+
work.objectStore(FENCES).put({ locator });
|
|
482
668
|
work.objectStore(QUEUES).delete(locator);
|
|
483
669
|
for (const name of [PENDING_CHANGES, ROOM_DRAFTS]) {
|
|
484
670
|
removeRoomEntries(work.objectStore(name), locator);
|
|
@@ -493,22 +679,37 @@ export async function openRuntimeStore() {
|
|
|
493
679
|
transaction.objectStore(BINARY_FILES).delete(underRoom(locator));
|
|
494
680
|
}
|
|
495
681
|
await completed(transaction);
|
|
682
|
+
const fences = authored.transaction(FENCES, 'readwrite');
|
|
683
|
+
for (const locator of locators)
|
|
684
|
+
fences.objectStore(FENCES).delete(locator);
|
|
685
|
+
await completed(fences);
|
|
686
|
+
},
|
|
687
|
+
async discard(locator) {
|
|
688
|
+
const transaction = authored.transaction([QUEUES, PENDING_CHANGES], 'readwrite');
|
|
689
|
+
transaction.objectStore(QUEUES).delete(locator);
|
|
690
|
+
removeRoomEntries(transaction.objectStore(PENDING_CHANGES), locator);
|
|
691
|
+
await completed(transaction);
|
|
496
692
|
},
|
|
497
693
|
async transfers() {
|
|
498
694
|
const transaction = database.transaction(TRANSFERS, 'readonly');
|
|
499
|
-
|
|
695
|
+
const held = await settled(transaction.objectStore(TRANSFERS).getAll());
|
|
696
|
+
return held.filter((record) => !fenced(record.locator));
|
|
500
697
|
},
|
|
501
698
|
staged(record) {
|
|
502
699
|
const transaction = database.transaction([DOCUMENTS, BINARY_FILES], 'readonly');
|
|
503
700
|
return readLayer(transaction, record.locator, record.transfer);
|
|
504
701
|
},
|
|
505
702
|
async stage(record, page) {
|
|
703
|
+
if (fenced(record.locator))
|
|
704
|
+
return;
|
|
506
705
|
const transaction = database.transaction([TRANSFERS, DOCUMENTS, BINARY_FILES], 'readwrite');
|
|
507
706
|
writeLayer(transaction, record.locator, record.transfer, page, null);
|
|
508
707
|
transaction.objectStore(TRANSFERS).put(record);
|
|
509
708
|
await completed(transaction);
|
|
510
709
|
},
|
|
511
710
|
async abandon(locator) {
|
|
711
|
+
if (fenced(locator))
|
|
712
|
+
return;
|
|
512
713
|
const transaction = database.transaction([TRANSFERS, DOCUMENTS, BINARY_FILES], 'readwrite');
|
|
513
714
|
const transfers = transaction.objectStore(TRANSFERS);
|
|
514
715
|
const held = transfers.get(locator);
|
|
@@ -523,6 +724,32 @@ export async function openRuntimeStore() {
|
|
|
523
724
|
};
|
|
524
725
|
await completed(transaction);
|
|
525
726
|
},
|
|
727
|
+
async receivedHeads() {
|
|
728
|
+
const transaction = database.transaction(RECEIVED, 'readonly');
|
|
729
|
+
return settled(transaction.objectStore(RECEIVED).getAll());
|
|
730
|
+
},
|
|
731
|
+
async receivedParts(key, count) {
|
|
732
|
+
const transaction = database.transaction(RECEIVED_PARTS, 'readonly');
|
|
733
|
+
const kept = await settled(transaction
|
|
734
|
+
.objectStore(RECEIVED_PARTS)
|
|
735
|
+
.getAll(IDBKeyRange.bound([key, 0], [key, count], false, true)));
|
|
736
|
+
return kept.map((part) => part.value);
|
|
737
|
+
},
|
|
738
|
+
async keepReceived(key, head, part) {
|
|
739
|
+
const transaction = database.transaction([RECEIVED, RECEIVED_PARTS], 'readwrite');
|
|
740
|
+
transaction.objectStore(RECEIVED).put({ key, head });
|
|
741
|
+
if (part !== undefined)
|
|
742
|
+
transaction.objectStore(RECEIVED_PARTS).put({ key, ...part });
|
|
743
|
+
await completed(transaction);
|
|
744
|
+
},
|
|
745
|
+
async dropReceived(keys) {
|
|
746
|
+
const transaction = database.transaction([RECEIVED, RECEIVED_PARTS], 'readwrite');
|
|
747
|
+
for (const key of keys) {
|
|
748
|
+
transaction.objectStore(RECEIVED).delete(key);
|
|
749
|
+
transaction.objectStore(RECEIVED_PARTS).delete(IDBKeyRange.bound([key], [key, []]));
|
|
750
|
+
}
|
|
751
|
+
await completed(transaction);
|
|
752
|
+
},
|
|
526
753
|
async generation() {
|
|
527
754
|
const transaction = authored.transaction(FACTS, 'readonly');
|
|
528
755
|
const held = await settled(transaction.objectStore(FACTS).get(GENERATION));
|
package/dist/turn.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function yielded(): Promise<void>;
|
|
2
|
+
export declare const ROW_WEIGHT = 256;
|
|
3
|
+
export type Later<T> = T | Promise<T>;
|
|
4
|
+
export declare function after<T, R>(value: Later<T>, next: (value: T) => R): Later<R>;
|
|
5
|
+
export declare function inUnits<T>(items: Iterable<T>, each: (item: T) => number): Later<void>;
|
|
6
|
+
export declare function inChunks<T>(items: readonly T[], weigh: (item: T) => number, each: (chunk: readonly T[]) => void): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=turn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn.d.ts","sourceRoot":"","sources":["../src/turn.ts"],"names":[],"mappings":"AAAA,wBAAgB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CASvC;AAID,eAAO,MAAM,UAAU,MAAM,CAAC;AAE9B,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEtC,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAE5E;AAaD,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAOrF;AAED,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,EAC1B,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,IAAI,GAClC,OAAO,CAAC,IAAI,CAAC,CAUf"}
|