@agentshouse/mdruntime 0.1.0-c16fc8caac7ff → 0.1.0-c1c2b722d3dcd
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/README.md +8 -8
- package/dist/adapter.d.ts +51 -9
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attempt.d.ts.map +1 -1
- package/dist/attempt.js +14 -1
- package/dist/bootstrap.d.ts +3 -2
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +33 -7
- 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/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 +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/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 -1
- package/dist/chat/provider.d.ts.map +1 -1
- package/dist/chat/provider.js +62 -79
- 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 +4 -4
- package/dist/chat.d.ts +1 -1
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +1 -1
- package/dist/client.d.ts +17 -9
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +19 -6
- package/dist/collection.d.ts +20 -5
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +309 -33
- package/dist/connection.d.ts +31 -9
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +1573 -372
- package/dist/conversation.d.ts +20 -7
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +474 -163
- package/dist/durability.d.ts +7 -1
- package/dist/durability.d.ts.map +1 -1
- package/dist/entry.d.ts +17 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +157 -0
- 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 +14 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +91 -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 +10 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/memory.d.ts +8 -2
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +33 -6
- 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 +3 -0
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +114 -95
- 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 +30 -5
- package/dist/react.d.ts +8 -6
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +7 -17
- package/dist/read-side.d.ts +16 -7
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +484 -100
- 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 +18 -11
- package/dist/replica.d.ts +10 -5
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +95 -32
- package/dist/room-draft.d.ts +13 -1
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +11 -12
- 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 +9 -3
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +187 -92
- 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 +14 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +394 -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 +9 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +64 -0
- 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 +152 -32
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +52 -31
- package/package.json +6 -2
package/dist/store.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { sameBinary, sameChange } from './overlay.js';
|
|
2
|
+
import { differing } from './shared.js';
|
|
3
|
+
import { precedes } from './windows.js';
|
|
2
4
|
const DATABASE = 'mdruntime';
|
|
3
5
|
const AUTHORED = 'mdruntime-authored';
|
|
6
|
+
const FENCES = 'fences';
|
|
4
7
|
const ROOMS = 'rooms';
|
|
5
8
|
const DOCUMENTS = 'documents';
|
|
6
9
|
const BINARY_FILES = 'binaryFiles';
|
|
7
10
|
const TRANSFERS = 'transfers';
|
|
11
|
+
const RECEIVED = 'received';
|
|
12
|
+
const RECEIVED_PARTS = 'receivedParts';
|
|
8
13
|
const PENDING_CHANGES = 'pendingChanges';
|
|
9
14
|
const DECLARATIONS = 'declarations';
|
|
10
15
|
const ROOM_DRAFTS = 'roomDrafts';
|
|
@@ -12,22 +17,45 @@ const PRESENTATION = 'presentation';
|
|
|
12
17
|
const CONVERSATIONS = 'conversations';
|
|
13
18
|
const MESSAGES = 'messages';
|
|
14
19
|
const CHAT_DRAFTS = 'chatDrafts';
|
|
20
|
+
const CALLS = 'calls';
|
|
15
21
|
const QUEUES = 'queues';
|
|
16
22
|
const FACTS = 'facts';
|
|
17
23
|
const CURRENT = 'current';
|
|
18
24
|
const MEMBER = 'member';
|
|
25
|
+
const TARGETS = 'targets';
|
|
19
26
|
const GENERATION = 'generation';
|
|
20
27
|
const HOLDER = 'holder';
|
|
21
|
-
|
|
22
|
-
export const
|
|
28
|
+
const BINDING = 'binding';
|
|
29
|
+
export const STORE_SCHEMA = 25;
|
|
30
|
+
const REPLICA_SHAPE = 23;
|
|
31
|
+
export const AUTHORED_SCHEMA = 3;
|
|
23
32
|
const AUTHORED_STORES = [
|
|
24
33
|
[QUEUES, { keyPath: 'locator' }],
|
|
25
34
|
[PENDING_CHANGES, { keyPath: ['locator', 'id'] }],
|
|
26
35
|
[ROOM_DRAFTS, { keyPath: ['locator', 'path'] }],
|
|
27
36
|
[CHAT_DRAFTS, { keyPath: 'conversation' }],
|
|
37
|
+
[CALLS, { keyPath: 'operation' }],
|
|
28
38
|
[FACTS, undefined],
|
|
39
|
+
[FENCES, { keyPath: 'locator' }],
|
|
40
|
+
];
|
|
41
|
+
const REPLICA_STORES = [
|
|
42
|
+
[ROOMS, { keyPath: 'locator' }],
|
|
43
|
+
[DOCUMENTS, { keyPath: ['locator', 'transfer', 'path'] }],
|
|
44
|
+
[BINARY_FILES, { keyPath: ['locator', 'transfer', 'path'] }],
|
|
45
|
+
[TRANSFERS, { keyPath: 'locator' }],
|
|
46
|
+
[RECEIVED, { keyPath: 'key' }],
|
|
47
|
+
[RECEIVED_PARTS, { keyPath: ['key', 'index'] }],
|
|
48
|
+
[DECLARATIONS, undefined],
|
|
49
|
+
[PRESENTATION, { keyPath: 'app' }],
|
|
50
|
+
[CONVERSATIONS, { keyPath: 'conversation' }],
|
|
51
|
+
[MESSAGES, { keyPath: ['conversation', 'identity'] }],
|
|
29
52
|
];
|
|
30
53
|
const READ_BATCH = 256;
|
|
54
|
+
const MESSAGE_INDEXES = [
|
|
55
|
+
['conversation', 'conversation'],
|
|
56
|
+
['position', ['conversation', 'position']],
|
|
57
|
+
['turn', ['conversation', 'turn']],
|
|
58
|
+
];
|
|
31
59
|
function settled(request) {
|
|
32
60
|
return new Promise((resolve, reject) => {
|
|
33
61
|
request.onsuccess = () => resolve(request.result);
|
|
@@ -70,8 +98,11 @@ function amendPending(database, locator, id, amendment) {
|
|
|
70
98
|
};
|
|
71
99
|
return completed(transaction);
|
|
72
100
|
}
|
|
101
|
+
function accepted({ conversation: _held, ...message }) {
|
|
102
|
+
return message;
|
|
103
|
+
}
|
|
73
104
|
function roomRecord(record) {
|
|
74
|
-
const { documents, binaries, revisions, changes, written, ...room } = record;
|
|
105
|
+
const { documents, binaries, revisions, fileIds, changes, written, ...room } = record;
|
|
75
106
|
return room;
|
|
76
107
|
}
|
|
77
108
|
function chatDraftRecord(record) {
|
|
@@ -97,13 +128,15 @@ async function readTransfer(store, locator, transfer, receive) {
|
|
|
97
128
|
}
|
|
98
129
|
}
|
|
99
130
|
function emptyLayer() {
|
|
100
|
-
return { documents: {}, binaries: {}, revisions: {}, changes: {}, written: {} };
|
|
131
|
+
return { documents: {}, binaries: {}, revisions: {}, fileIds: {}, changes: {}, written: {} };
|
|
101
132
|
}
|
|
102
133
|
async function readLayer(transaction, locator, transfer) {
|
|
103
134
|
const layer = emptyLayer();
|
|
104
135
|
const head = (held) => {
|
|
105
136
|
if (held.revision !== null)
|
|
106
137
|
layer.revisions[held.path] = held.revision;
|
|
138
|
+
if (held.fileId !== null)
|
|
139
|
+
layer.fileIds[held.path] = held.fileId;
|
|
107
140
|
if (held.change !== null)
|
|
108
141
|
layer.changes[held.path] = held.change;
|
|
109
142
|
};
|
|
@@ -126,6 +159,7 @@ function documentRecord(locator, transfer, layer, path) {
|
|
|
126
159
|
path,
|
|
127
160
|
content: layer.documents[path],
|
|
128
161
|
revision: layer.revisions[path] ?? null,
|
|
162
|
+
fileId: layer.fileIds[path] ?? null,
|
|
129
163
|
change: layer.changes[path] ?? null,
|
|
130
164
|
written: layer.written[path] ?? null,
|
|
131
165
|
};
|
|
@@ -136,35 +170,37 @@ function binaryFileRecord(locator, transfer, layer, path) {
|
|
|
136
170
|
transfer,
|
|
137
171
|
path,
|
|
138
172
|
revision: layer.revisions[path] ?? null,
|
|
173
|
+
fileId: layer.fileIds[path] ?? null,
|
|
139
174
|
change: layer.changes[path] ?? null,
|
|
140
175
|
binary: layer.binaries[path],
|
|
141
176
|
};
|
|
142
177
|
}
|
|
143
178
|
function writeLayer(transaction, locator, transfer, next, base) {
|
|
144
179
|
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
180
|
const files = transaction.objectStore(BINARY_FILES);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
base
|
|
165
|
-
|
|
181
|
+
const paths = base === null
|
|
182
|
+
? new Set([...Object.keys(next.documents), ...Object.keys(next.binaries)])
|
|
183
|
+
: new Set([
|
|
184
|
+
...differing(base.documents, next.documents),
|
|
185
|
+
...differing(base.revisions, next.revisions),
|
|
186
|
+
...differing(base.fileIds, next.fileIds),
|
|
187
|
+
...differing(base.written, next.written),
|
|
188
|
+
...differing(base.changes, next.changes, sameChange),
|
|
189
|
+
...differing(base.binaries, next.binaries, sameBinary),
|
|
190
|
+
]);
|
|
191
|
+
for (const path of paths) {
|
|
192
|
+
if (next.documents[path] !== undefined) {
|
|
193
|
+
documents.put(documentRecord(locator, transfer, next, path));
|
|
194
|
+
}
|
|
195
|
+
else if (base?.documents[path] !== undefined) {
|
|
196
|
+
documents.delete([locator, transfer, path]);
|
|
197
|
+
}
|
|
198
|
+
if (next.binaries[path] !== undefined) {
|
|
166
199
|
files.put(binaryFileRecord(locator, transfer, next, path));
|
|
167
200
|
}
|
|
201
|
+
else if (base?.binaries[path] !== undefined) {
|
|
202
|
+
files.delete([locator, transfer, path]);
|
|
203
|
+
}
|
|
168
204
|
}
|
|
169
205
|
}
|
|
170
206
|
function removeRoomEntries(store, locator) {
|
|
@@ -215,6 +251,29 @@ export async function authoredBy(holder) {
|
|
|
215
251
|
authored.close();
|
|
216
252
|
}
|
|
217
253
|
}
|
|
254
|
+
export async function authoredBinding() {
|
|
255
|
+
const authored = await openAuthored();
|
|
256
|
+
try {
|
|
257
|
+
const transaction = authored.transaction(FACTS, 'readonly');
|
|
258
|
+
const held = transaction.objectStore(FACTS).get(BINDING);
|
|
259
|
+
await completed(transaction);
|
|
260
|
+
return typeof held.result === 'string' ? held.result : null;
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
authored.close();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
export async function bindAuthored(binding) {
|
|
267
|
+
const authored = await openAuthored();
|
|
268
|
+
try {
|
|
269
|
+
const transaction = authored.transaction(FACTS, 'readwrite');
|
|
270
|
+
transaction.objectStore(FACTS).put(binding, BINDING);
|
|
271
|
+
await completed(transaction);
|
|
272
|
+
}
|
|
273
|
+
finally {
|
|
274
|
+
authored.close();
|
|
275
|
+
}
|
|
276
|
+
}
|
|
218
277
|
export async function removeRuntimeStore(holder) {
|
|
219
278
|
await removeDatabase(DATABASE);
|
|
220
279
|
if (holder !== undefined && (await authoredBy(holder)))
|
|
@@ -222,38 +281,51 @@ export async function removeRuntimeStore(holder) {
|
|
|
222
281
|
await removeDatabase(AUTHORED);
|
|
223
282
|
return false;
|
|
224
283
|
}
|
|
284
|
+
export function openDatabase(name, version, upgrade) {
|
|
285
|
+
return new Promise((resolve, reject) => {
|
|
286
|
+
const opening = indexedDB.open(name, version);
|
|
287
|
+
opening.onupgradeneeded = (event) => upgrade(opening, event.oldVersion);
|
|
288
|
+
opening.onsuccess = () => resolve(opening.result);
|
|
289
|
+
opening.onerror = () => {
|
|
290
|
+
if (opening.error?.name !== 'VersionError') {
|
|
291
|
+
reject(opening.error);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
removeDatabase(name)
|
|
295
|
+
.then(() => openDatabase(name, version, upgrade))
|
|
296
|
+
.then(resolve, reject);
|
|
297
|
+
};
|
|
298
|
+
});
|
|
299
|
+
}
|
|
225
300
|
function openReplica() {
|
|
226
|
-
|
|
227
|
-
opening.onupgradeneeded = () => {
|
|
301
|
+
return openDatabase(DATABASE, STORE_SCHEMA, (opening, oldVersion) => {
|
|
228
302
|
const database = opening.result;
|
|
229
|
-
|
|
230
|
-
database.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const messages =
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
303
|
+
if (oldVersion < REPLICA_SHAPE) {
|
|
304
|
+
for (const name of [...database.objectStoreNames])
|
|
305
|
+
database.deleteObjectStore(name);
|
|
306
|
+
}
|
|
307
|
+
for (const [name, parameters] of REPLICA_STORES) {
|
|
308
|
+
if (database.objectStoreNames.contains(name))
|
|
309
|
+
continue;
|
|
310
|
+
database.createObjectStore(name, parameters);
|
|
311
|
+
}
|
|
312
|
+
const messages = opening.transaction.objectStore(MESSAGES);
|
|
313
|
+
for (const [name, keyPath] of MESSAGE_INDEXES) {
|
|
314
|
+
if (!messages.indexNames.contains(name))
|
|
315
|
+
messages.createIndex(name, keyPath);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
244
318
|
}
|
|
245
319
|
function openAuthored() {
|
|
246
|
-
|
|
247
|
-
opening.onupgradeneeded = () => {
|
|
320
|
+
return openDatabase(AUTHORED, AUTHORED_SCHEMA, (opening) => {
|
|
248
321
|
const database = opening.result;
|
|
249
322
|
for (const [name, parameters] of AUTHORED_STORES) {
|
|
250
323
|
if (!database.objectStoreNames.contains(name))
|
|
251
324
|
database.createObjectStore(name, parameters);
|
|
252
325
|
}
|
|
253
|
-
};
|
|
254
|
-
return settled(opening);
|
|
326
|
+
});
|
|
255
327
|
}
|
|
256
|
-
export async function openRuntimeStore() {
|
|
328
|
+
export async function openRuntimeStore(fenced) {
|
|
257
329
|
const authored = await openAuthored();
|
|
258
330
|
const database = await openReplica().catch((error) => {
|
|
259
331
|
authored.close();
|
|
@@ -264,12 +336,14 @@ export async function openRuntimeStore() {
|
|
|
264
336
|
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES], 'readonly');
|
|
265
337
|
const rooms = await settled(transaction.objectStore(ROOMS).getAll());
|
|
266
338
|
const records = [];
|
|
267
|
-
for (const room of rooms) {
|
|
339
|
+
for (const room of rooms.filter((held) => !fenced(held.locator))) {
|
|
268
340
|
records.push({ ...room, ...(await readLayer(transaction, room.locator, room.transfer)) });
|
|
269
341
|
}
|
|
270
342
|
return records;
|
|
271
343
|
},
|
|
272
|
-
async keepAuthored({ locator, queue, saved, roomDrafts, consumedRoomDrafts }) {
|
|
344
|
+
async keepAuthored({ locator, queue, founded, saved, roomDrafts, consumedRoomDrafts }) {
|
|
345
|
+
if (fenced(locator))
|
|
346
|
+
return;
|
|
273
347
|
const transaction = authored.transaction([QUEUES, PENDING_CHANGES, ROOM_DRAFTS], 'readwrite');
|
|
274
348
|
const order = transaction.objectStore(QUEUES);
|
|
275
349
|
const pending = transaction.objectStore(PENDING_CHANGES);
|
|
@@ -297,6 +371,16 @@ export async function openRuntimeStore() {
|
|
|
297
371
|
});
|
|
298
372
|
}
|
|
299
373
|
}
|
|
374
|
+
for (const batch of founded ?? []) {
|
|
375
|
+
if (!before.has(batch.id))
|
|
376
|
+
continue;
|
|
377
|
+
const stored = pending.get([locator, batch.id]);
|
|
378
|
+
stored.onsuccess = () => {
|
|
379
|
+
const record = stored.result;
|
|
380
|
+
if (record !== undefined)
|
|
381
|
+
pending.put({ ...record, batch });
|
|
382
|
+
};
|
|
383
|
+
}
|
|
300
384
|
};
|
|
301
385
|
const draftStore = transaction.objectStore(ROOM_DRAFTS);
|
|
302
386
|
for (const path of consumedRoomDrafts ?? [])
|
|
@@ -306,7 +390,7 @@ export async function openRuntimeStore() {
|
|
|
306
390
|
await completed(transaction);
|
|
307
391
|
},
|
|
308
392
|
async write({ next, previous, stored }) {
|
|
309
|
-
if (next === previous)
|
|
393
|
+
if (next === previous || fenced(next.locator))
|
|
310
394
|
return;
|
|
311
395
|
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES, TRANSFERS], 'readwrite');
|
|
312
396
|
transaction.objectStore(ROOMS).put(roomRecord(next));
|
|
@@ -326,6 +410,8 @@ export async function openRuntimeStore() {
|
|
|
326
410
|
const rooms = transaction.objectStore(ROOMS);
|
|
327
411
|
const revoked = { status: 'unavailable', reason: 'revoked' };
|
|
328
412
|
for (const record of records) {
|
|
413
|
+
if (fenced(record.locator))
|
|
414
|
+
continue;
|
|
329
415
|
rooms.put(roomRecord({ ...record, model: revoked, selectionModel: revoked }));
|
|
330
416
|
}
|
|
331
417
|
await completed(transaction);
|
|
@@ -359,6 +445,16 @@ export async function openRuntimeStore() {
|
|
|
359
445
|
transaction.objectStore(DECLARATIONS).put(member, MEMBER);
|
|
360
446
|
await completed(transaction);
|
|
361
447
|
},
|
|
448
|
+
async targets() {
|
|
449
|
+
const transaction = database.transaction(DECLARATIONS, 'readonly');
|
|
450
|
+
const held = await settled(transaction.objectStore(DECLARATIONS).get(TARGETS));
|
|
451
|
+
return held ?? {};
|
|
452
|
+
},
|
|
453
|
+
async keepTargets(targets) {
|
|
454
|
+
const transaction = database.transaction(DECLARATIONS, 'readwrite');
|
|
455
|
+
transaction.objectStore(DECLARATIONS).put(targets, TARGETS);
|
|
456
|
+
await completed(transaction);
|
|
457
|
+
},
|
|
362
458
|
async queues() {
|
|
363
459
|
const transaction = authored.transaction([QUEUES, PENDING_CHANGES], 'readonly');
|
|
364
460
|
const [queues, pending] = await Promise.all([
|
|
@@ -366,7 +462,9 @@ export async function openRuntimeStore() {
|
|
|
366
462
|
settled(transaction.objectStore(PENDING_CHANGES).getAll()),
|
|
367
463
|
]);
|
|
368
464
|
const byId = new Map(pending.map((record) => [`${record.locator}\0${record.id}`, record]));
|
|
369
|
-
return queues
|
|
465
|
+
return queues
|
|
466
|
+
.filter((queue) => !fenced(queue.locator))
|
|
467
|
+
.map((queue) => ({
|
|
370
468
|
locator: queue.locator,
|
|
371
469
|
pending: queue.order.map((id) => {
|
|
372
470
|
const record = byId.get(`${queue.locator}\0${id}`);
|
|
@@ -377,18 +475,22 @@ export async function openRuntimeStore() {
|
|
|
377
475
|
}),
|
|
378
476
|
}));
|
|
379
477
|
},
|
|
380
|
-
submit(locator, id, submission, lost) {
|
|
381
|
-
|
|
478
|
+
async submit(locator, id, submission, lost) {
|
|
479
|
+
if (!fenced(locator))
|
|
480
|
+
await amendPending(authored, locator, id, { submission, lost });
|
|
382
481
|
},
|
|
383
|
-
accept(locator, id, roomVersion) {
|
|
384
|
-
|
|
482
|
+
async accept(locator, id, roomVersion) {
|
|
483
|
+
if (!fenced(locator))
|
|
484
|
+
await amendPending(authored, locator, id, { accepted: roomVersion });
|
|
385
485
|
},
|
|
386
|
-
keepUpload(locator, id, upload) {
|
|
387
|
-
|
|
486
|
+
async keepUpload(locator, id, upload) {
|
|
487
|
+
if (!fenced(locator))
|
|
488
|
+
await amendPending(authored, locator, id, { upload });
|
|
388
489
|
},
|
|
389
490
|
async roomDrafts() {
|
|
390
491
|
const transaction = authored.transaction(ROOM_DRAFTS, 'readonly');
|
|
391
|
-
|
|
492
|
+
const held = await settled(transaction.objectStore(ROOM_DRAFTS).getAll());
|
|
493
|
+
return held.filter((record) => !fenced(record.locator));
|
|
392
494
|
},
|
|
393
495
|
async presentation() {
|
|
394
496
|
const transaction = database.transaction(PRESENTATION, 'readonly');
|
|
@@ -401,39 +503,98 @@ export async function openRuntimeStore() {
|
|
|
401
503
|
},
|
|
402
504
|
async conversations() {
|
|
403
505
|
const transaction = database.transaction([CONVERSATIONS, MESSAGES], 'readonly');
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
506
|
+
const records = await settled(transaction.objectStore(CONVERSATIONS).getAll());
|
|
507
|
+
const held = new Map(records.map(({ conversation, read, partial }) => [
|
|
508
|
+
conversation,
|
|
509
|
+
{ conversation, read, partial: partial === true },
|
|
510
|
+
]));
|
|
511
|
+
const keys = transaction.objectStore(MESSAGES).index('conversation');
|
|
512
|
+
await new Promise((resolve, reject) => {
|
|
513
|
+
const cursor = keys.openKeyCursor(null, 'nextunique');
|
|
514
|
+
cursor.onerror = () => reject(cursor.error);
|
|
515
|
+
cursor.onsuccess = () => {
|
|
516
|
+
const at = cursor.result;
|
|
517
|
+
if (at === null) {
|
|
518
|
+
resolve();
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
const conversation = at.key;
|
|
522
|
+
if (!held.has(conversation)) {
|
|
523
|
+
held.set(conversation, { conversation, read: undefined, partial: true });
|
|
524
|
+
}
|
|
525
|
+
at.continue();
|
|
526
|
+
};
|
|
527
|
+
});
|
|
417
528
|
return [...held.values()];
|
|
418
529
|
},
|
|
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
|
-
}
|
|
530
|
+
async keepMessages({ conversation, messages, read }) {
|
|
425
531
|
const transaction = database.transaction([CONVERSATIONS, MESSAGES], 'readwrite');
|
|
426
532
|
const stored = transaction.objectStore(MESSAGES);
|
|
427
533
|
for (const message of messages) {
|
|
428
534
|
stored.put({ ...message, conversation });
|
|
429
535
|
}
|
|
430
536
|
if (read !== undefined) {
|
|
431
|
-
transaction
|
|
432
|
-
|
|
433
|
-
.
|
|
537
|
+
transaction.objectStore(CONVERSATIONS).put({
|
|
538
|
+
conversation,
|
|
539
|
+
read: read.at,
|
|
540
|
+
...(read.partial ? { partial: true } : {}),
|
|
541
|
+
});
|
|
434
542
|
}
|
|
435
543
|
await completed(transaction);
|
|
436
544
|
},
|
|
545
|
+
async messageWindow(conversation, limit, before) {
|
|
546
|
+
const transaction = database.transaction(MESSAGES, 'readonly');
|
|
547
|
+
const index = transaction.objectStore(MESSAGES).index('position');
|
|
548
|
+
const range = IDBKeyRange.bound([conversation], [conversation, before?.[0] ?? []]);
|
|
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 (!precedes(record, before)) {
|
|
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,9 @@
|
|
|
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) => Later<R>): Later<R>;
|
|
5
|
+
export declare function inUnits<T>(items: Iterable<T>, each: (item: T) => number, ended?: () => void): Later<void>;
|
|
6
|
+
export declare function finished<R>(steps: Generator<number, R, void>): R;
|
|
7
|
+
export declare function stepped<R>(steps: Generator<number, R, void>): Later<R>;
|
|
8
|
+
export declare function inChunks<T>(items: readonly T[], weigh: (item: T) => number, each: (chunk: readonly T[]) => Later<void>): Promise<void>;
|
|
9
|
+
//# 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,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAEnF;AAmBD,wBAAgB,OAAO,CAAC,CAAC,EACvB,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAClB,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,EACzB,KAAK,GAAE,MAAM,IAAe,GAC3B,KAAK,CAAC,IAAI,CAAC,CAWb;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAIhE;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAStE;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,KAAK,CAAC,IAAI,CAAC,GACzC,OAAO,CAAC,IAAI,CAAC,CAUf"}
|