@agentshouse/mdruntime 0.1.0-cd3ee807e46ae → 0.1.0-cd50a4607cb7d
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 +247 -269
- package/dist/adapter.d.ts +25 -2
- 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 +2 -2
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +28 -6
- package/dist/change-set.d.ts +2 -0
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +34 -9
- 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/list.d.ts +6 -0
- package/dist/chat/list.d.ts.map +1 -1
- package/dist/chat/list.js +6 -3
- 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/provider.d.ts.map +1 -1
- package/dist/chat/provider.js +25 -50
- package/dist/chat/ready.d.ts.map +1 -1
- package/dist/chat/ready.js +2 -2
- package/dist/chat/style.js +3 -3
- package/dist/client.d.ts +7 -7
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +1 -1
- 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 +8 -5
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +866 -301
- package/dist/conversation.d.ts +12 -7
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +258 -130
- package/dist/entry.d.ts +17 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +156 -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 +4 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +9 -5
- 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 +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/memory.d.ts +1 -0
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +10 -1
- package/dist/model.d.ts +1 -0
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +9 -0
- package/dist/observation.d.ts +5 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +22 -11
- package/dist/outcome.d.ts +4 -0
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +1 -0
- package/dist/overlay.d.ts +1 -0
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +33 -54
- package/dist/query.d.ts +28 -3
- package/dist/query.d.ts.map +1 -1
- package/dist/reach.js +3 -3
- package/dist/react.d.ts +3 -3
- package/dist/react.d.ts.map +1 -1
- package/dist/read-side.d.ts +13 -6
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +282 -83
- 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.map +1 -1
- package/dist/refresh.js +11 -10
- package/dist/replica.d.ts +1 -1
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +47 -19
- package/dist/rows.d.ts +4 -13
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +2 -12
- package/dist/save.d.ts +6 -2
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +42 -18
- package/dist/search.d.ts +28 -6
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +109 -44
- 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 +35 -10
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +275 -74
- package/dist/turn.d.ts +7 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +45 -0
- package/package.json +6 -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';
|
|
@@ -17,16 +21,37 @@ const FACTS = 'facts';
|
|
|
17
21
|
const CURRENT = 'current';
|
|
18
22
|
const MEMBER = 'member';
|
|
19
23
|
const GENERATION = 'generation';
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
const HOLDER = 'holder';
|
|
25
|
+
const BINDING = 'binding';
|
|
26
|
+
export const STORE_SCHEMA = 25;
|
|
27
|
+
const REPLICA_SHAPE = 23;
|
|
28
|
+
export const AUTHORED_SCHEMA = 2;
|
|
22
29
|
const AUTHORED_STORES = [
|
|
23
30
|
[QUEUES, { keyPath: 'locator' }],
|
|
24
31
|
[PENDING_CHANGES, { keyPath: ['locator', 'id'] }],
|
|
25
32
|
[ROOM_DRAFTS, { keyPath: ['locator', 'path'] }],
|
|
26
33
|
[CHAT_DRAFTS, { keyPath: 'conversation' }],
|
|
27
34
|
[FACTS, undefined],
|
|
35
|
+
[FENCES, { keyPath: 'locator' }],
|
|
36
|
+
];
|
|
37
|
+
const REPLICA_STORES = [
|
|
38
|
+
[ROOMS, { keyPath: 'locator' }],
|
|
39
|
+
[DOCUMENTS, { keyPath: ['locator', 'transfer', 'path'] }],
|
|
40
|
+
[BINARY_FILES, { keyPath: ['locator', 'transfer', 'path'] }],
|
|
41
|
+
[TRANSFERS, { keyPath: 'locator' }],
|
|
42
|
+
[RECEIVED, { keyPath: 'key' }],
|
|
43
|
+
[RECEIVED_PARTS, { keyPath: ['key', 'index'] }],
|
|
44
|
+
[DECLARATIONS, undefined],
|
|
45
|
+
[PRESENTATION, { keyPath: 'app' }],
|
|
46
|
+
[CONVERSATIONS, { keyPath: 'conversation' }],
|
|
47
|
+
[MESSAGES, { keyPath: ['conversation', 'identity'] }],
|
|
28
48
|
];
|
|
29
49
|
const READ_BATCH = 256;
|
|
50
|
+
const MESSAGE_INDEXES = [
|
|
51
|
+
['conversation', 'conversation'],
|
|
52
|
+
['position', ['conversation', 'position']],
|
|
53
|
+
['turn', ['conversation', 'turn']],
|
|
54
|
+
];
|
|
30
55
|
function settled(request) {
|
|
31
56
|
return new Promise((resolve, reject) => {
|
|
32
57
|
request.onsuccess = () => resolve(request.result);
|
|
@@ -69,6 +94,9 @@ function amendPending(database, locator, id, amendment) {
|
|
|
69
94
|
};
|
|
70
95
|
return completed(transaction);
|
|
71
96
|
}
|
|
97
|
+
function accepted({ conversation: _held, ...message }) {
|
|
98
|
+
return message;
|
|
99
|
+
}
|
|
72
100
|
function roomRecord(record) {
|
|
73
101
|
const { documents, binaries, revisions, changes, written, ...room } = record;
|
|
74
102
|
return room;
|
|
@@ -141,29 +169,29 @@ function binaryFileRecord(locator, transfer, layer, path) {
|
|
|
141
169
|
}
|
|
142
170
|
function writeLayer(transaction, locator, transfer, next, base) {
|
|
143
171
|
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
172
|
const files = transaction.objectStore(BINARY_FILES);
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
base
|
|
164
|
-
|
|
173
|
+
const paths = base === null
|
|
174
|
+
? new Set([...Object.keys(next.documents), ...Object.keys(next.binaries)])
|
|
175
|
+
: new Set([
|
|
176
|
+
...differing(base.documents, next.documents),
|
|
177
|
+
...differing(base.revisions, next.revisions),
|
|
178
|
+
...differing(base.written, next.written),
|
|
179
|
+
...differing(base.changes, next.changes, sameChange),
|
|
180
|
+
...differing(base.binaries, next.binaries, sameBinary),
|
|
181
|
+
]);
|
|
182
|
+
for (const path of paths) {
|
|
183
|
+
if (next.documents[path] !== undefined) {
|
|
184
|
+
documents.put(documentRecord(locator, transfer, next, path));
|
|
185
|
+
}
|
|
186
|
+
else if (base?.documents[path] !== undefined) {
|
|
187
|
+
documents.delete([locator, transfer, path]);
|
|
188
|
+
}
|
|
189
|
+
if (next.binaries[path] !== undefined) {
|
|
165
190
|
files.put(binaryFileRecord(locator, transfer, next, path));
|
|
166
191
|
}
|
|
192
|
+
else if (base?.binaries[path] !== undefined) {
|
|
193
|
+
files.delete([locator, transfer, path]);
|
|
194
|
+
}
|
|
167
195
|
}
|
|
168
196
|
}
|
|
169
197
|
function removeRoomEntries(store, locator) {
|
|
@@ -182,26 +210,86 @@ function removeDatabase(name) {
|
|
|
182
210
|
removal.onerror = () => reject(removal.error);
|
|
183
211
|
});
|
|
184
212
|
}
|
|
185
|
-
export async function
|
|
186
|
-
await
|
|
213
|
+
export async function authoredHolder() {
|
|
214
|
+
const authored = await openAuthored();
|
|
215
|
+
try {
|
|
216
|
+
const transaction = authored.transaction(FACTS, 'readonly');
|
|
217
|
+
const held = transaction.objectStore(FACTS).get(HOLDER);
|
|
218
|
+
await completed(transaction);
|
|
219
|
+
return typeof held.result === 'string' ? held.result : null;
|
|
220
|
+
}
|
|
221
|
+
finally {
|
|
222
|
+
authored.close();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
export async function authoredBy(holder) {
|
|
226
|
+
const authored = await openAuthored();
|
|
227
|
+
try {
|
|
228
|
+
const transaction = authored.transaction(FACTS, 'readwrite');
|
|
229
|
+
const facts = transaction.objectStore(FACTS);
|
|
230
|
+
const held = facts.get(HOLDER);
|
|
231
|
+
let owned = true;
|
|
232
|
+
held.onsuccess = () => {
|
|
233
|
+
if (held.result === undefined)
|
|
234
|
+
facts.put(holder, HOLDER);
|
|
235
|
+
else
|
|
236
|
+
owned = held.result === holder;
|
|
237
|
+
};
|
|
238
|
+
await completed(transaction);
|
|
239
|
+
return owned;
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
authored.close();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
export async function authoredBinding() {
|
|
246
|
+
const authored = await openAuthored();
|
|
247
|
+
try {
|
|
248
|
+
const transaction = authored.transaction(FACTS, 'readonly');
|
|
249
|
+
const held = transaction.objectStore(FACTS).get(BINDING);
|
|
250
|
+
await completed(transaction);
|
|
251
|
+
return typeof held.result === 'string' ? held.result : null;
|
|
252
|
+
}
|
|
253
|
+
finally {
|
|
254
|
+
authored.close();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
export async function bindAuthored(binding) {
|
|
258
|
+
const authored = await openAuthored();
|
|
259
|
+
try {
|
|
260
|
+
const transaction = authored.transaction(FACTS, 'readwrite');
|
|
261
|
+
transaction.objectStore(FACTS).put(binding, BINDING);
|
|
262
|
+
await completed(transaction);
|
|
263
|
+
}
|
|
264
|
+
finally {
|
|
265
|
+
authored.close();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
export async function removeRuntimeStore(holder) {
|
|
269
|
+
await removeDatabase(DATABASE);
|
|
270
|
+
if (holder !== undefined && (await authoredBy(holder)))
|
|
271
|
+
return true;
|
|
272
|
+
await removeDatabase(AUTHORED);
|
|
273
|
+
return false;
|
|
187
274
|
}
|
|
188
275
|
function openReplica() {
|
|
189
276
|
const opening = indexedDB.open(DATABASE, STORE_SCHEMA);
|
|
190
|
-
opening.onupgradeneeded = () => {
|
|
277
|
+
opening.onupgradeneeded = (event) => {
|
|
191
278
|
const database = opening.result;
|
|
192
|
-
|
|
193
|
-
database.
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const messages =
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
279
|
+
if (event.oldVersion < REPLICA_SHAPE) {
|
|
280
|
+
for (const name of [...database.objectStoreNames])
|
|
281
|
+
database.deleteObjectStore(name);
|
|
282
|
+
}
|
|
283
|
+
for (const [name, parameters] of REPLICA_STORES) {
|
|
284
|
+
if (database.objectStoreNames.contains(name))
|
|
285
|
+
continue;
|
|
286
|
+
database.createObjectStore(name, parameters);
|
|
287
|
+
}
|
|
288
|
+
const messages = opening.transaction.objectStore(MESSAGES);
|
|
289
|
+
for (const [name, keyPath] of MESSAGE_INDEXES) {
|
|
290
|
+
if (!messages.indexNames.contains(name))
|
|
291
|
+
messages.createIndex(name, keyPath);
|
|
292
|
+
}
|
|
205
293
|
};
|
|
206
294
|
return settled(opening);
|
|
207
295
|
}
|
|
@@ -216,7 +304,7 @@ function openAuthored() {
|
|
|
216
304
|
};
|
|
217
305
|
return settled(opening);
|
|
218
306
|
}
|
|
219
|
-
export async function openRuntimeStore() {
|
|
307
|
+
export async function openRuntimeStore(fenced) {
|
|
220
308
|
const authored = await openAuthored();
|
|
221
309
|
const database = await openReplica().catch((error) => {
|
|
222
310
|
authored.close();
|
|
@@ -227,12 +315,14 @@ export async function openRuntimeStore() {
|
|
|
227
315
|
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES], 'readonly');
|
|
228
316
|
const rooms = await settled(transaction.objectStore(ROOMS).getAll());
|
|
229
317
|
const records = [];
|
|
230
|
-
for (const room of rooms) {
|
|
318
|
+
for (const room of rooms.filter((held) => !fenced(held.locator))) {
|
|
231
319
|
records.push({ ...room, ...(await readLayer(transaction, room.locator, room.transfer)) });
|
|
232
320
|
}
|
|
233
321
|
return records;
|
|
234
322
|
},
|
|
235
323
|
async keepAuthored({ locator, queue, saved, roomDrafts, consumedRoomDrafts }) {
|
|
324
|
+
if (fenced(locator))
|
|
325
|
+
return;
|
|
236
326
|
const transaction = authored.transaction([QUEUES, PENDING_CHANGES, ROOM_DRAFTS], 'readwrite');
|
|
237
327
|
const order = transaction.objectStore(QUEUES);
|
|
238
328
|
const pending = transaction.objectStore(PENDING_CHANGES);
|
|
@@ -269,7 +359,7 @@ export async function openRuntimeStore() {
|
|
|
269
359
|
await completed(transaction);
|
|
270
360
|
},
|
|
271
361
|
async write({ next, previous, stored }) {
|
|
272
|
-
if (next === previous)
|
|
362
|
+
if (next === previous || fenced(next.locator))
|
|
273
363
|
return;
|
|
274
364
|
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES, TRANSFERS], 'readwrite');
|
|
275
365
|
transaction.objectStore(ROOMS).put(roomRecord(next));
|
|
@@ -289,6 +379,8 @@ export async function openRuntimeStore() {
|
|
|
289
379
|
const rooms = transaction.objectStore(ROOMS);
|
|
290
380
|
const revoked = { status: 'unavailable', reason: 'revoked' };
|
|
291
381
|
for (const record of records) {
|
|
382
|
+
if (fenced(record.locator))
|
|
383
|
+
continue;
|
|
292
384
|
rooms.put(roomRecord({ ...record, model: revoked, selectionModel: revoked }));
|
|
293
385
|
}
|
|
294
386
|
await completed(transaction);
|
|
@@ -329,7 +421,9 @@ export async function openRuntimeStore() {
|
|
|
329
421
|
settled(transaction.objectStore(PENDING_CHANGES).getAll()),
|
|
330
422
|
]);
|
|
331
423
|
const byId = new Map(pending.map((record) => [`${record.locator}\0${record.id}`, record]));
|
|
332
|
-
return queues
|
|
424
|
+
return queues
|
|
425
|
+
.filter((queue) => !fenced(queue.locator))
|
|
426
|
+
.map((queue) => ({
|
|
333
427
|
locator: queue.locator,
|
|
334
428
|
pending: queue.order.map((id) => {
|
|
335
429
|
const record = byId.get(`${queue.locator}\0${id}`);
|
|
@@ -340,18 +434,22 @@ export async function openRuntimeStore() {
|
|
|
340
434
|
}),
|
|
341
435
|
}));
|
|
342
436
|
},
|
|
343
|
-
submit(locator, id, submission, lost) {
|
|
344
|
-
|
|
437
|
+
async submit(locator, id, submission, lost) {
|
|
438
|
+
if (!fenced(locator))
|
|
439
|
+
await amendPending(authored, locator, id, { submission, lost });
|
|
345
440
|
},
|
|
346
|
-
accept(locator, id, roomVersion) {
|
|
347
|
-
|
|
441
|
+
async accept(locator, id, roomVersion) {
|
|
442
|
+
if (!fenced(locator))
|
|
443
|
+
await amendPending(authored, locator, id, { accepted: roomVersion });
|
|
348
444
|
},
|
|
349
|
-
keepUpload(locator, id, upload) {
|
|
350
|
-
|
|
445
|
+
async keepUpload(locator, id, upload) {
|
|
446
|
+
if (!fenced(locator))
|
|
447
|
+
await amendPending(authored, locator, id, { upload });
|
|
351
448
|
},
|
|
352
449
|
async roomDrafts() {
|
|
353
450
|
const transaction = authored.transaction(ROOM_DRAFTS, 'readonly');
|
|
354
|
-
|
|
451
|
+
const held = await settled(transaction.objectStore(ROOM_DRAFTS).getAll());
|
|
452
|
+
return held.filter((record) => !fenced(record.locator));
|
|
355
453
|
},
|
|
356
454
|
async presentation() {
|
|
357
455
|
const transaction = database.transaction(PRESENTATION, 'readonly');
|
|
@@ -364,39 +462,91 @@ export async function openRuntimeStore() {
|
|
|
364
462
|
},
|
|
365
463
|
async conversations() {
|
|
366
464
|
const transaction = database.transaction([CONVERSATIONS, MESSAGES], 'readonly');
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
465
|
+
const records = await settled(transaction.objectStore(CONVERSATIONS).getAll());
|
|
466
|
+
const held = new Map(records.map(({ conversation, read, partial }) => [
|
|
467
|
+
conversation,
|
|
468
|
+
{ conversation, read, partial: partial === true },
|
|
469
|
+
]));
|
|
470
|
+
const keys = transaction.objectStore(MESSAGES).index('conversation');
|
|
471
|
+
await new Promise((resolve, reject) => {
|
|
472
|
+
const cursor = keys.openKeyCursor(null, 'nextunique');
|
|
473
|
+
cursor.onerror = () => reject(cursor.error);
|
|
474
|
+
cursor.onsuccess = () => {
|
|
475
|
+
const at = cursor.result;
|
|
476
|
+
if (at === null) {
|
|
477
|
+
resolve();
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
const conversation = at.key;
|
|
481
|
+
if (!held.has(conversation)) {
|
|
482
|
+
held.set(conversation, { conversation, read: undefined, partial: true });
|
|
483
|
+
}
|
|
484
|
+
at.continue();
|
|
485
|
+
};
|
|
486
|
+
});
|
|
380
487
|
return [...held.values()];
|
|
381
488
|
},
|
|
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
|
-
}
|
|
489
|
+
async keepMessages({ conversation, messages, read }) {
|
|
388
490
|
const transaction = database.transaction([CONVERSATIONS, MESSAGES], 'readwrite');
|
|
389
491
|
const stored = transaction.objectStore(MESSAGES);
|
|
390
492
|
for (const message of messages) {
|
|
391
493
|
stored.put({ ...message, conversation });
|
|
392
494
|
}
|
|
393
495
|
if (read !== undefined) {
|
|
394
|
-
transaction
|
|
395
|
-
|
|
396
|
-
.
|
|
496
|
+
transaction.objectStore(CONVERSATIONS).put({
|
|
497
|
+
conversation,
|
|
498
|
+
read: read.at,
|
|
499
|
+
...(read.partial ? { partial: true } : {}),
|
|
500
|
+
});
|
|
397
501
|
}
|
|
398
502
|
await completed(transaction);
|
|
399
503
|
},
|
|
504
|
+
async messageWindow(conversation, limit) {
|
|
505
|
+
const transaction = database.transaction(MESSAGES, 'readonly');
|
|
506
|
+
const index = transaction.objectStore(MESSAGES).index('position');
|
|
507
|
+
const range = IDBKeyRange.bound([conversation], [conversation, []]);
|
|
508
|
+
if (limit === undefined) {
|
|
509
|
+
return (await settled(index.getAll(range))).map(accepted);
|
|
510
|
+
}
|
|
511
|
+
const latest = [];
|
|
512
|
+
if (limit === 0)
|
|
513
|
+
return latest;
|
|
514
|
+
await new Promise((resolve, reject) => {
|
|
515
|
+
const cursor = index.openCursor(range, 'prev');
|
|
516
|
+
cursor.onerror = () => reject(cursor.error);
|
|
517
|
+
cursor.onsuccess = () => {
|
|
518
|
+
const at = cursor.result;
|
|
519
|
+
if (at === null) {
|
|
520
|
+
resolve();
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
latest.push(accepted(at.value));
|
|
524
|
+
if (latest.length === limit)
|
|
525
|
+
resolve();
|
|
526
|
+
else
|
|
527
|
+
at.continue();
|
|
528
|
+
};
|
|
529
|
+
});
|
|
530
|
+
return latest.reverse();
|
|
531
|
+
},
|
|
532
|
+
async messagesAfter(conversation, identity) {
|
|
533
|
+
const transaction = database.transaction(MESSAGES, 'readonly');
|
|
534
|
+
const range = identity === null
|
|
535
|
+
? IDBKeyRange.bound([conversation], [conversation, []])
|
|
536
|
+
: IDBKeyRange.bound([conversation, identity], [conversation, []], true);
|
|
537
|
+
const held = await settled(transaction.objectStore(MESSAGES).getAll(range, READ_BATCH));
|
|
538
|
+
return held.map(accepted);
|
|
539
|
+
},
|
|
540
|
+
async messageIdentities(conversation) {
|
|
541
|
+
const transaction = database.transaction(MESSAGES, 'readonly');
|
|
542
|
+
const keys = await settled(transaction.objectStore(MESSAGES).index('conversation').getAllKeys(conversation));
|
|
543
|
+
return keys.map((key) => key[1]);
|
|
544
|
+
},
|
|
545
|
+
async turnArrived(conversation, turn) {
|
|
546
|
+
const transaction = database.transaction(MESSAGES, 'readonly');
|
|
547
|
+
const held = await settled(transaction.objectStore(MESSAGES).index('turn').count([conversation, turn]));
|
|
548
|
+
return held > 0;
|
|
549
|
+
},
|
|
400
550
|
async dropConversations(conversations) {
|
|
401
551
|
const drafts = authored.transaction(CHAT_DRAFTS, 'readwrite');
|
|
402
552
|
for (const conversation of conversations)
|
|
@@ -430,18 +580,28 @@ export async function openRuntimeStore() {
|
|
|
430
580
|
await completed(transaction);
|
|
431
581
|
},
|
|
432
582
|
async keepRoomDraft(record) {
|
|
583
|
+
if (fenced(record.locator))
|
|
584
|
+
return;
|
|
433
585
|
const transaction = authored.transaction(ROOM_DRAFTS, 'readwrite');
|
|
434
586
|
transaction.objectStore(ROOM_DRAFTS).put(record);
|
|
435
587
|
await completed(transaction);
|
|
436
588
|
},
|
|
437
589
|
async discardRoomDraft(locator, path) {
|
|
590
|
+
if (fenced(locator))
|
|
591
|
+
return;
|
|
438
592
|
const transaction = authored.transaction(ROOM_DRAFTS, 'readwrite');
|
|
439
593
|
transaction.objectStore(ROOM_DRAFTS).delete([locator, path]);
|
|
440
594
|
await completed(transaction);
|
|
441
595
|
},
|
|
442
|
-
async
|
|
443
|
-
const
|
|
596
|
+
async fences() {
|
|
597
|
+
const transaction = authored.transaction(FENCES, 'readonly');
|
|
598
|
+
const held = await settled(transaction.objectStore(FENCES).getAll());
|
|
599
|
+
return held.map((fence) => fence.locator);
|
|
600
|
+
},
|
|
601
|
+
async erase(locators) {
|
|
602
|
+
const work = authored.transaction([FENCES, QUEUES, PENDING_CHANGES, ROOM_DRAFTS], 'readwrite');
|
|
444
603
|
for (const locator of locators) {
|
|
604
|
+
work.objectStore(FENCES).put({ locator });
|
|
445
605
|
work.objectStore(QUEUES).delete(locator);
|
|
446
606
|
for (const name of [PENDING_CHANGES, ROOM_DRAFTS]) {
|
|
447
607
|
removeRoomEntries(work.objectStore(name), locator);
|
|
@@ -456,22 +616,37 @@ export async function openRuntimeStore() {
|
|
|
456
616
|
transaction.objectStore(BINARY_FILES).delete(underRoom(locator));
|
|
457
617
|
}
|
|
458
618
|
await completed(transaction);
|
|
619
|
+
const fences = authored.transaction(FENCES, 'readwrite');
|
|
620
|
+
for (const locator of locators)
|
|
621
|
+
fences.objectStore(FENCES).delete(locator);
|
|
622
|
+
await completed(fences);
|
|
623
|
+
},
|
|
624
|
+
async discard(locator) {
|
|
625
|
+
const transaction = authored.transaction([QUEUES, PENDING_CHANGES], 'readwrite');
|
|
626
|
+
transaction.objectStore(QUEUES).delete(locator);
|
|
627
|
+
removeRoomEntries(transaction.objectStore(PENDING_CHANGES), locator);
|
|
628
|
+
await completed(transaction);
|
|
459
629
|
},
|
|
460
630
|
async transfers() {
|
|
461
631
|
const transaction = database.transaction(TRANSFERS, 'readonly');
|
|
462
|
-
|
|
632
|
+
const held = await settled(transaction.objectStore(TRANSFERS).getAll());
|
|
633
|
+
return held.filter((record) => !fenced(record.locator));
|
|
463
634
|
},
|
|
464
635
|
staged(record) {
|
|
465
636
|
const transaction = database.transaction([DOCUMENTS, BINARY_FILES], 'readonly');
|
|
466
637
|
return readLayer(transaction, record.locator, record.transfer);
|
|
467
638
|
},
|
|
468
639
|
async stage(record, page) {
|
|
640
|
+
if (fenced(record.locator))
|
|
641
|
+
return;
|
|
469
642
|
const transaction = database.transaction([TRANSFERS, DOCUMENTS, BINARY_FILES], 'readwrite');
|
|
470
643
|
writeLayer(transaction, record.locator, record.transfer, page, null);
|
|
471
644
|
transaction.objectStore(TRANSFERS).put(record);
|
|
472
645
|
await completed(transaction);
|
|
473
646
|
},
|
|
474
647
|
async abandon(locator) {
|
|
648
|
+
if (fenced(locator))
|
|
649
|
+
return;
|
|
475
650
|
const transaction = database.transaction([TRANSFERS, DOCUMENTS, BINARY_FILES], 'readwrite');
|
|
476
651
|
const transfers = transaction.objectStore(TRANSFERS);
|
|
477
652
|
const held = transfers.get(locator);
|
|
@@ -486,6 +661,32 @@ export async function openRuntimeStore() {
|
|
|
486
661
|
};
|
|
487
662
|
await completed(transaction);
|
|
488
663
|
},
|
|
664
|
+
async receivedHeads() {
|
|
665
|
+
const transaction = database.transaction(RECEIVED, 'readonly');
|
|
666
|
+
return settled(transaction.objectStore(RECEIVED).getAll());
|
|
667
|
+
},
|
|
668
|
+
async receivedParts(key, count) {
|
|
669
|
+
const transaction = database.transaction(RECEIVED_PARTS, 'readonly');
|
|
670
|
+
const kept = await settled(transaction
|
|
671
|
+
.objectStore(RECEIVED_PARTS)
|
|
672
|
+
.getAll(IDBKeyRange.bound([key, 0], [key, count], false, true)));
|
|
673
|
+
return kept.map((part) => part.value);
|
|
674
|
+
},
|
|
675
|
+
async keepReceived(key, head, part) {
|
|
676
|
+
const transaction = database.transaction([RECEIVED, RECEIVED_PARTS], 'readwrite');
|
|
677
|
+
transaction.objectStore(RECEIVED).put({ key, head });
|
|
678
|
+
if (part !== undefined)
|
|
679
|
+
transaction.objectStore(RECEIVED_PARTS).put({ key, ...part });
|
|
680
|
+
await completed(transaction);
|
|
681
|
+
},
|
|
682
|
+
async dropReceived(keys) {
|
|
683
|
+
const transaction = database.transaction([RECEIVED, RECEIVED_PARTS], 'readwrite');
|
|
684
|
+
for (const key of keys) {
|
|
685
|
+
transaction.objectStore(RECEIVED).delete(key);
|
|
686
|
+
transaction.objectStore(RECEIVED_PARTS).delete(IDBKeyRange.bound([key], [key, []]));
|
|
687
|
+
}
|
|
688
|
+
await completed(transaction);
|
|
689
|
+
},
|
|
489
690
|
async generation() {
|
|
490
691
|
const transaction = authored.transaction(FACTS, 'readonly');
|
|
491
692
|
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"}
|
package/dist/turn.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export function yielded() {
|
|
2
|
+
return new Promise((resolve) => {
|
|
3
|
+
const channel = new MessageChannel();
|
|
4
|
+
channel.port1.onmessage = () => {
|
|
5
|
+
channel.port1.close();
|
|
6
|
+
resolve();
|
|
7
|
+
};
|
|
8
|
+
channel.port2.postMessage(null);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
const UNIT = 1 << 20;
|
|
12
|
+
export const ROW_WEIGHT = 256;
|
|
13
|
+
export function after(value, next) {
|
|
14
|
+
return value instanceof Promise ? value.then(next) : next(value);
|
|
15
|
+
}
|
|
16
|
+
async function resumed(iterator, each) {
|
|
17
|
+
let spent = UNIT;
|
|
18
|
+
for (let next = iterator.next(); next.done !== true; next = iterator.next()) {
|
|
19
|
+
if (spent >= UNIT) {
|
|
20
|
+
await yielded();
|
|
21
|
+
spent = 0;
|
|
22
|
+
}
|
|
23
|
+
spent += each(next.value);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function inUnits(items, each) {
|
|
27
|
+
const iterator = items[Symbol.iterator]();
|
|
28
|
+
let spent = 0;
|
|
29
|
+
for (let next = iterator.next(); next.done !== true; next = iterator.next()) {
|
|
30
|
+
spent += each(next.value);
|
|
31
|
+
if (spent >= UNIT)
|
|
32
|
+
return resumed(iterator, each);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export async function inChunks(items, weigh, each) {
|
|
36
|
+
for (let at = 0; at < items.length;) {
|
|
37
|
+
await yielded();
|
|
38
|
+
const chunk = [];
|
|
39
|
+
for (let spent = 0; at < items.length && spent < UNIT; at += 1) {
|
|
40
|
+
chunk.push(items[at]);
|
|
41
|
+
spent += weigh(items[at]);
|
|
42
|
+
}
|
|
43
|
+
each(chunk);
|
|
44
|
+
}
|
|
45
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentshouse/mdruntime",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-cd50a4607cb7d",
|
|
4
4
|
"description": "The headless core of MD App",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"types": "./dist/client.d.ts",
|
|
25
25
|
"default": "./dist/client.js"
|
|
26
26
|
},
|
|
27
|
+
"./entry": {
|
|
28
|
+
"types": "./dist/entry.d.ts",
|
|
29
|
+
"default": "./dist/entry.js"
|
|
30
|
+
},
|
|
27
31
|
"./memory": {
|
|
28
32
|
"types": "./dist/memory.d.ts",
|
|
29
33
|
"default": "./dist/memory.js"
|
|
@@ -45,7 +49,7 @@
|
|
|
45
49
|
"LICENSE"
|
|
46
50
|
],
|
|
47
51
|
"dependencies": {
|
|
48
|
-
"@agentshouse/mdmodel": "0.1.0-
|
|
52
|
+
"@agentshouse/mdmodel": "0.1.0-cad192ab63d5f",
|
|
49
53
|
"@assistant-ui/react-markdown": "0.14.20",
|
|
50
54
|
"@tanstack/db": "0.9.2",
|
|
51
55
|
"lucide-react": "1.47.0",
|