@agentshouse/mdruntime 0.1.0-cdf82f77fae68 → 0.1.0-ce131cb435f8b
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 +271 -290
- 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 +8 -1
- package/dist/chat/list.d.ts.map +1 -1
- package/dist/chat/list.js +48 -8
- package/dist/chat/markdown.d.ts +2 -1
- package/dist/chat/markdown.d.ts.map +1 -1
- package/dist/chat/markdown.js +7 -6
- 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 +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 +4 -4
- package/dist/chat/style.js +4 -4
- 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 +15 -3
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +94 -12
- 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 +62 -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 +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 +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 +9 -3
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +68 -22
- 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 +59 -12
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +350 -86
- 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 +12 -8
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,21 +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
|
-
|
|
21
|
-
|
|
27
|
+
const HOLDER = 'holder';
|
|
28
|
+
const BINDING = 'binding';
|
|
29
|
+
export const STORE_SCHEMA = 25;
|
|
30
|
+
const REPLICA_SHAPE = 23;
|
|
31
|
+
export const AUTHORED_SCHEMA = 3;
|
|
22
32
|
const AUTHORED_STORES = [
|
|
23
33
|
[QUEUES, { keyPath: 'locator' }],
|
|
24
34
|
[PENDING_CHANGES, { keyPath: ['locator', 'id'] }],
|
|
25
35
|
[ROOM_DRAFTS, { keyPath: ['locator', 'path'] }],
|
|
26
36
|
[CHAT_DRAFTS, { keyPath: 'conversation' }],
|
|
37
|
+
[CALLS, { keyPath: 'operation' }],
|
|
27
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'] }],
|
|
28
52
|
];
|
|
29
53
|
const READ_BATCH = 256;
|
|
54
|
+
const MESSAGE_INDEXES = [
|
|
55
|
+
['conversation', 'conversation'],
|
|
56
|
+
['position', ['conversation', 'position']],
|
|
57
|
+
['turn', ['conversation', 'turn']],
|
|
58
|
+
];
|
|
30
59
|
function settled(request) {
|
|
31
60
|
return new Promise((resolve, reject) => {
|
|
32
61
|
request.onsuccess = () => resolve(request.result);
|
|
@@ -69,8 +98,11 @@ function amendPending(database, locator, id, amendment) {
|
|
|
69
98
|
};
|
|
70
99
|
return completed(transaction);
|
|
71
100
|
}
|
|
101
|
+
function accepted({ conversation: _held, ...message }) {
|
|
102
|
+
return message;
|
|
103
|
+
}
|
|
72
104
|
function roomRecord(record) {
|
|
73
|
-
const { documents, binaries, revisions, changes, written, ...room } = record;
|
|
105
|
+
const { documents, binaries, revisions, fileIds, changes, written, ...room } = record;
|
|
74
106
|
return room;
|
|
75
107
|
}
|
|
76
108
|
function chatDraftRecord(record) {
|
|
@@ -96,13 +128,15 @@ async function readTransfer(store, locator, transfer, receive) {
|
|
|
96
128
|
}
|
|
97
129
|
}
|
|
98
130
|
function emptyLayer() {
|
|
99
|
-
return { documents: {}, binaries: {}, revisions: {}, changes: {}, written: {} };
|
|
131
|
+
return { documents: {}, binaries: {}, revisions: {}, fileIds: {}, changes: {}, written: {} };
|
|
100
132
|
}
|
|
101
133
|
async function readLayer(transaction, locator, transfer) {
|
|
102
134
|
const layer = emptyLayer();
|
|
103
135
|
const head = (held) => {
|
|
104
136
|
if (held.revision !== null)
|
|
105
137
|
layer.revisions[held.path] = held.revision;
|
|
138
|
+
if (held.fileId !== null)
|
|
139
|
+
layer.fileIds[held.path] = held.fileId;
|
|
106
140
|
if (held.change !== null)
|
|
107
141
|
layer.changes[held.path] = held.change;
|
|
108
142
|
};
|
|
@@ -125,6 +159,7 @@ function documentRecord(locator, transfer, layer, path) {
|
|
|
125
159
|
path,
|
|
126
160
|
content: layer.documents[path],
|
|
127
161
|
revision: layer.revisions[path] ?? null,
|
|
162
|
+
fileId: layer.fileIds[path] ?? null,
|
|
128
163
|
change: layer.changes[path] ?? null,
|
|
129
164
|
written: layer.written[path] ?? null,
|
|
130
165
|
};
|
|
@@ -135,35 +170,37 @@ function binaryFileRecord(locator, transfer, layer, path) {
|
|
|
135
170
|
transfer,
|
|
136
171
|
path,
|
|
137
172
|
revision: layer.revisions[path] ?? null,
|
|
173
|
+
fileId: layer.fileIds[path] ?? null,
|
|
138
174
|
change: layer.changes[path] ?? null,
|
|
139
175
|
binary: layer.binaries[path],
|
|
140
176
|
};
|
|
141
177
|
}
|
|
142
178
|
function writeLayer(transaction, locator, transfer, next, base) {
|
|
143
179
|
const documents = transaction.objectStore(DOCUMENTS);
|
|
144
|
-
for (const path of Object.keys(base?.documents ?? {})) {
|
|
145
|
-
if (next.documents[path] === undefined)
|
|
146
|
-
documents.delete([locator, transfer, path]);
|
|
147
|
-
}
|
|
148
|
-
for (const [path, content] of Object.entries(next.documents)) {
|
|
149
|
-
if (base?.documents[path] === content &&
|
|
150
|
-
base.revisions[path] === next.revisions[path] &&
|
|
151
|
-
base.written[path] === next.written[path] &&
|
|
152
|
-
sameChange(base.changes[path], next.changes[path]))
|
|
153
|
-
continue;
|
|
154
|
-
documents.put(documentRecord(locator, transfer, next, path));
|
|
155
|
-
}
|
|
156
180
|
const files = transaction.objectStore(BINARY_FILES);
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
base
|
|
164
|
-
|
|
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) {
|
|
165
199
|
files.put(binaryFileRecord(locator, transfer, next, path));
|
|
166
200
|
}
|
|
201
|
+
else if (base?.binaries[path] !== undefined) {
|
|
202
|
+
files.delete([locator, transfer, path]);
|
|
203
|
+
}
|
|
167
204
|
}
|
|
168
205
|
}
|
|
169
206
|
function removeRoomEntries(store, locator) {
|
|
@@ -182,41 +219,113 @@ function removeDatabase(name) {
|
|
|
182
219
|
removal.onerror = () => reject(removal.error);
|
|
183
220
|
});
|
|
184
221
|
}
|
|
185
|
-
export async function
|
|
186
|
-
await
|
|
222
|
+
export async function authoredHolder() {
|
|
223
|
+
const authored = await openAuthored();
|
|
224
|
+
try {
|
|
225
|
+
const transaction = authored.transaction(FACTS, 'readonly');
|
|
226
|
+
const held = transaction.objectStore(FACTS).get(HOLDER);
|
|
227
|
+
await completed(transaction);
|
|
228
|
+
return typeof held.result === 'string' ? held.result : null;
|
|
229
|
+
}
|
|
230
|
+
finally {
|
|
231
|
+
authored.close();
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
export async function authoredBy(holder) {
|
|
235
|
+
const authored = await openAuthored();
|
|
236
|
+
try {
|
|
237
|
+
const transaction = authored.transaction(FACTS, 'readwrite');
|
|
238
|
+
const facts = transaction.objectStore(FACTS);
|
|
239
|
+
const held = facts.get(HOLDER);
|
|
240
|
+
let owned = true;
|
|
241
|
+
held.onsuccess = () => {
|
|
242
|
+
if (held.result === undefined)
|
|
243
|
+
facts.put(holder, HOLDER);
|
|
244
|
+
else
|
|
245
|
+
owned = held.result === holder;
|
|
246
|
+
};
|
|
247
|
+
await completed(transaction);
|
|
248
|
+
return owned;
|
|
249
|
+
}
|
|
250
|
+
finally {
|
|
251
|
+
authored.close();
|
|
252
|
+
}
|
|
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
|
+
}
|
|
277
|
+
export async function removeRuntimeStore(holder) {
|
|
278
|
+
await removeDatabase(DATABASE);
|
|
279
|
+
if (holder !== undefined && (await authoredBy(holder)))
|
|
280
|
+
return true;
|
|
281
|
+
await removeDatabase(AUTHORED);
|
|
282
|
+
return false;
|
|
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
|
+
});
|
|
187
299
|
}
|
|
188
300
|
function openReplica() {
|
|
189
|
-
|
|
190
|
-
opening.onupgradeneeded = () => {
|
|
301
|
+
return openDatabase(DATABASE, STORE_SCHEMA, (opening, oldVersion) => {
|
|
191
302
|
const database = opening.result;
|
|
192
|
-
|
|
193
|
-
database.
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const messages =
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
+
});
|
|
207
318
|
}
|
|
208
319
|
function openAuthored() {
|
|
209
|
-
|
|
210
|
-
opening.onupgradeneeded = () => {
|
|
320
|
+
return openDatabase(AUTHORED, AUTHORED_SCHEMA, (opening) => {
|
|
211
321
|
const database = opening.result;
|
|
212
322
|
for (const [name, parameters] of AUTHORED_STORES) {
|
|
213
323
|
if (!database.objectStoreNames.contains(name))
|
|
214
324
|
database.createObjectStore(name, parameters);
|
|
215
325
|
}
|
|
216
|
-
};
|
|
217
|
-
return settled(opening);
|
|
326
|
+
});
|
|
218
327
|
}
|
|
219
|
-
export async function openRuntimeStore() {
|
|
328
|
+
export async function openRuntimeStore(fenced) {
|
|
220
329
|
const authored = await openAuthored();
|
|
221
330
|
const database = await openReplica().catch((error) => {
|
|
222
331
|
authored.close();
|
|
@@ -227,12 +336,14 @@ export async function openRuntimeStore() {
|
|
|
227
336
|
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES], 'readonly');
|
|
228
337
|
const rooms = await settled(transaction.objectStore(ROOMS).getAll());
|
|
229
338
|
const records = [];
|
|
230
|
-
for (const room of rooms) {
|
|
339
|
+
for (const room of rooms.filter((held) => !fenced(held.locator))) {
|
|
231
340
|
records.push({ ...room, ...(await readLayer(transaction, room.locator, room.transfer)) });
|
|
232
341
|
}
|
|
233
342
|
return records;
|
|
234
343
|
},
|
|
235
|
-
async keepAuthored({ locator, queue, saved, roomDrafts, consumedRoomDrafts }) {
|
|
344
|
+
async keepAuthored({ locator, queue, founded, saved, roomDrafts, consumedRoomDrafts }) {
|
|
345
|
+
if (fenced(locator))
|
|
346
|
+
return;
|
|
236
347
|
const transaction = authored.transaction([QUEUES, PENDING_CHANGES, ROOM_DRAFTS], 'readwrite');
|
|
237
348
|
const order = transaction.objectStore(QUEUES);
|
|
238
349
|
const pending = transaction.objectStore(PENDING_CHANGES);
|
|
@@ -260,6 +371,16 @@ export async function openRuntimeStore() {
|
|
|
260
371
|
});
|
|
261
372
|
}
|
|
262
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
|
+
}
|
|
263
384
|
};
|
|
264
385
|
const draftStore = transaction.objectStore(ROOM_DRAFTS);
|
|
265
386
|
for (const path of consumedRoomDrafts ?? [])
|
|
@@ -269,7 +390,7 @@ export async function openRuntimeStore() {
|
|
|
269
390
|
await completed(transaction);
|
|
270
391
|
},
|
|
271
392
|
async write({ next, previous, stored }) {
|
|
272
|
-
if (next === previous)
|
|
393
|
+
if (next === previous || fenced(next.locator))
|
|
273
394
|
return;
|
|
274
395
|
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES, TRANSFERS], 'readwrite');
|
|
275
396
|
transaction.objectStore(ROOMS).put(roomRecord(next));
|
|
@@ -289,6 +410,8 @@ export async function openRuntimeStore() {
|
|
|
289
410
|
const rooms = transaction.objectStore(ROOMS);
|
|
290
411
|
const revoked = { status: 'unavailable', reason: 'revoked' };
|
|
291
412
|
for (const record of records) {
|
|
413
|
+
if (fenced(record.locator))
|
|
414
|
+
continue;
|
|
292
415
|
rooms.put(roomRecord({ ...record, model: revoked, selectionModel: revoked }));
|
|
293
416
|
}
|
|
294
417
|
await completed(transaction);
|
|
@@ -322,6 +445,16 @@ export async function openRuntimeStore() {
|
|
|
322
445
|
transaction.objectStore(DECLARATIONS).put(member, MEMBER);
|
|
323
446
|
await completed(transaction);
|
|
324
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
|
+
},
|
|
325
458
|
async queues() {
|
|
326
459
|
const transaction = authored.transaction([QUEUES, PENDING_CHANGES], 'readonly');
|
|
327
460
|
const [queues, pending] = await Promise.all([
|
|
@@ -329,7 +462,9 @@ export async function openRuntimeStore() {
|
|
|
329
462
|
settled(transaction.objectStore(PENDING_CHANGES).getAll()),
|
|
330
463
|
]);
|
|
331
464
|
const byId = new Map(pending.map((record) => [`${record.locator}\0${record.id}`, record]));
|
|
332
|
-
return queues
|
|
465
|
+
return queues
|
|
466
|
+
.filter((queue) => !fenced(queue.locator))
|
|
467
|
+
.map((queue) => ({
|
|
333
468
|
locator: queue.locator,
|
|
334
469
|
pending: queue.order.map((id) => {
|
|
335
470
|
const record = byId.get(`${queue.locator}\0${id}`);
|
|
@@ -340,18 +475,22 @@ export async function openRuntimeStore() {
|
|
|
340
475
|
}),
|
|
341
476
|
}));
|
|
342
477
|
},
|
|
343
|
-
submit(locator, id, submission, lost) {
|
|
344
|
-
|
|
478
|
+
async submit(locator, id, submission, lost) {
|
|
479
|
+
if (!fenced(locator))
|
|
480
|
+
await amendPending(authored, locator, id, { submission, lost });
|
|
345
481
|
},
|
|
346
|
-
accept(locator, id, roomVersion) {
|
|
347
|
-
|
|
482
|
+
async accept(locator, id, roomVersion) {
|
|
483
|
+
if (!fenced(locator))
|
|
484
|
+
await amendPending(authored, locator, id, { accepted: roomVersion });
|
|
348
485
|
},
|
|
349
|
-
keepUpload(locator, id, upload) {
|
|
350
|
-
|
|
486
|
+
async keepUpload(locator, id, upload) {
|
|
487
|
+
if (!fenced(locator))
|
|
488
|
+
await amendPending(authored, locator, id, { upload });
|
|
351
489
|
},
|
|
352
490
|
async roomDrafts() {
|
|
353
491
|
const transaction = authored.transaction(ROOM_DRAFTS, 'readonly');
|
|
354
|
-
|
|
492
|
+
const held = await settled(transaction.objectStore(ROOM_DRAFTS).getAll());
|
|
493
|
+
return held.filter((record) => !fenced(record.locator));
|
|
355
494
|
},
|
|
356
495
|
async presentation() {
|
|
357
496
|
const transaction = database.transaction(PRESENTATION, 'readonly');
|
|
@@ -364,39 +503,98 @@ export async function openRuntimeStore() {
|
|
|
364
503
|
},
|
|
365
504
|
async conversations() {
|
|
366
505
|
const transaction = database.transaction([CONVERSATIONS, MESSAGES], 'readonly');
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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
|
+
});
|
|
380
528
|
return [...held.values()];
|
|
381
529
|
},
|
|
382
|
-
async keepMessages({ conversation, messages, read
|
|
383
|
-
if (sealed === true) {
|
|
384
|
-
const sealing = authored.transaction(CHAT_DRAFTS, 'readwrite');
|
|
385
|
-
sealing.objectStore(CHAT_DRAFTS).delete(conversation);
|
|
386
|
-
await completed(sealing);
|
|
387
|
-
}
|
|
530
|
+
async keepMessages({ conversation, messages, read }) {
|
|
388
531
|
const transaction = database.transaction([CONVERSATIONS, MESSAGES], 'readwrite');
|
|
389
532
|
const stored = transaction.objectStore(MESSAGES);
|
|
390
533
|
for (const message of messages) {
|
|
391
534
|
stored.put({ ...message, conversation });
|
|
392
535
|
}
|
|
393
536
|
if (read !== undefined) {
|
|
394
|
-
transaction
|
|
395
|
-
|
|
396
|
-
.
|
|
537
|
+
transaction.objectStore(CONVERSATIONS).put({
|
|
538
|
+
conversation,
|
|
539
|
+
read: read.at,
|
|
540
|
+
...(read.partial ? { partial: true } : {}),
|
|
541
|
+
});
|
|
397
542
|
}
|
|
398
543
|
await completed(transaction);
|
|
399
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
|
+
},
|
|
400
598
|
async dropConversations(conversations) {
|
|
401
599
|
const drafts = authored.transaction(CHAT_DRAFTS, 'readwrite');
|
|
402
600
|
for (const conversation of conversations)
|
|
@@ -419,9 +617,10 @@ export async function openRuntimeStore() {
|
|
|
419
617
|
const held = await settled(transaction.objectStore(CHAT_DRAFTS).getAll());
|
|
420
618
|
return held.map(chatDraftRecord);
|
|
421
619
|
},
|
|
422
|
-
async
|
|
620
|
+
async keepChatDrafts(records) {
|
|
423
621
|
const transaction = authored.transaction(CHAT_DRAFTS, 'readwrite');
|
|
424
|
-
|
|
622
|
+
for (const record of records)
|
|
623
|
+
transaction.objectStore(CHAT_DRAFTS).put(record);
|
|
425
624
|
await completed(transaction);
|
|
426
625
|
},
|
|
427
626
|
async dropChatDraft(conversation) {
|
|
@@ -429,19 +628,43 @@ export async function openRuntimeStore() {
|
|
|
429
628
|
transaction.objectStore(CHAT_DRAFTS).delete(conversation);
|
|
430
629
|
await completed(transaction);
|
|
431
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
|
+
},
|
|
432
645
|
async keepRoomDraft(record) {
|
|
646
|
+
if (fenced(record.locator))
|
|
647
|
+
return;
|
|
433
648
|
const transaction = authored.transaction(ROOM_DRAFTS, 'readwrite');
|
|
434
649
|
transaction.objectStore(ROOM_DRAFTS).put(record);
|
|
435
650
|
await completed(transaction);
|
|
436
651
|
},
|
|
437
652
|
async discardRoomDraft(locator, path) {
|
|
653
|
+
if (fenced(locator))
|
|
654
|
+
return;
|
|
438
655
|
const transaction = authored.transaction(ROOM_DRAFTS, 'readwrite');
|
|
439
656
|
transaction.objectStore(ROOM_DRAFTS).delete([locator, path]);
|
|
440
657
|
await completed(transaction);
|
|
441
658
|
},
|
|
442
|
-
async
|
|
443
|
-
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');
|
|
444
666
|
for (const locator of locators) {
|
|
667
|
+
work.objectStore(FENCES).put({ locator });
|
|
445
668
|
work.objectStore(QUEUES).delete(locator);
|
|
446
669
|
for (const name of [PENDING_CHANGES, ROOM_DRAFTS]) {
|
|
447
670
|
removeRoomEntries(work.objectStore(name), locator);
|
|
@@ -456,22 +679,37 @@ export async function openRuntimeStore() {
|
|
|
456
679
|
transaction.objectStore(BINARY_FILES).delete(underRoom(locator));
|
|
457
680
|
}
|
|
458
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);
|
|
459
692
|
},
|
|
460
693
|
async transfers() {
|
|
461
694
|
const transaction = database.transaction(TRANSFERS, 'readonly');
|
|
462
|
-
|
|
695
|
+
const held = await settled(transaction.objectStore(TRANSFERS).getAll());
|
|
696
|
+
return held.filter((record) => !fenced(record.locator));
|
|
463
697
|
},
|
|
464
698
|
staged(record) {
|
|
465
699
|
const transaction = database.transaction([DOCUMENTS, BINARY_FILES], 'readonly');
|
|
466
700
|
return readLayer(transaction, record.locator, record.transfer);
|
|
467
701
|
},
|
|
468
702
|
async stage(record, page) {
|
|
703
|
+
if (fenced(record.locator))
|
|
704
|
+
return;
|
|
469
705
|
const transaction = database.transaction([TRANSFERS, DOCUMENTS, BINARY_FILES], 'readwrite');
|
|
470
706
|
writeLayer(transaction, record.locator, record.transfer, page, null);
|
|
471
707
|
transaction.objectStore(TRANSFERS).put(record);
|
|
472
708
|
await completed(transaction);
|
|
473
709
|
},
|
|
474
710
|
async abandon(locator) {
|
|
711
|
+
if (fenced(locator))
|
|
712
|
+
return;
|
|
475
713
|
const transaction = database.transaction([TRANSFERS, DOCUMENTS, BINARY_FILES], 'readwrite');
|
|
476
714
|
const transfers = transaction.objectStore(TRANSFERS);
|
|
477
715
|
const held = transfers.get(locator);
|
|
@@ -486,6 +724,32 @@ export async function openRuntimeStore() {
|
|
|
486
724
|
};
|
|
487
725
|
await completed(transaction);
|
|
488
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
|
+
},
|
|
489
753
|
async generation() {
|
|
490
754
|
const transaction = authored.transaction(FACTS, 'readonly');
|
|
491
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"}
|