@agentshouse/mdruntime 0.1.0-c967d1ca66fee → 0.1.0-ca14c49c06d90
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 +142 -112
- package/README.md +11 -1
- package/dist/adapter.d.ts +59 -13
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attempt.d.ts +16 -0
- package/dist/attempt.d.ts.map +1 -0
- package/dist/attempt.js +70 -0
- package/dist/binary.d.ts +23 -0
- package/dist/binary.d.ts.map +1 -0
- package/dist/binary.js +8 -0
- package/dist/bootstrap.d.ts +2 -2
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +33 -14
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +8 -7
- package/dist/change.d.ts +11 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +26 -1
- package/dist/chat/acts.d.ts +33 -0
- package/dist/chat/acts.d.ts.map +1 -0
- package/dist/chat/acts.js +36 -0
- package/dist/chat/context.d.ts +3 -0
- package/dist/chat/context.d.ts.map +1 -0
- package/dist/chat/context.js +10 -0
- package/dist/chat/input.d.ts +9 -0
- package/dist/chat/input.d.ts.map +1 -0
- package/dist/chat/input.js +99 -0
- package/dist/chat/kit.d.ts +60 -0
- package/dist/chat/kit.d.ts.map +1 -0
- package/dist/chat/kit.js +123 -0
- package/dist/chat/lasting.d.ts +6 -0
- package/dist/chat/lasting.d.ts.map +1 -0
- package/dist/chat/lasting.js +19 -0
- package/dist/chat/list.d.ts +26 -0
- package/dist/chat/list.d.ts.map +1 -0
- package/dist/chat/list.js +62 -0
- package/dist/chat/markdown.d.ts +20 -0
- package/dist/chat/markdown.d.ts.map +1 -0
- package/dist/chat/markdown.js +188 -0
- package/dist/chat/message.d.ts +6 -0
- package/dist/chat/message.d.ts.map +1 -0
- package/dist/chat/message.js +192 -0
- package/dist/chat/messages.d.ts +21 -0
- package/dist/chat/messages.d.ts.map +1 -0
- package/dist/chat/messages.js +151 -0
- package/dist/chat/name.d.ts +6 -0
- package/dist/chat/name.d.ts.map +1 -0
- package/dist/chat/name.js +37 -0
- package/dist/chat/opened.d.ts +11 -0
- package/dist/chat/opened.d.ts.map +1 -0
- package/dist/chat/opened.js +17 -0
- package/dist/chat/overlay.d.ts +31 -0
- package/dist/chat/overlay.d.ts.map +1 -0
- package/dist/chat/overlay.js +97 -0
- package/dist/chat/parts.d.ts +57 -0
- package/dist/chat/parts.d.ts.map +1 -0
- package/dist/chat/parts.js +119 -0
- package/dist/chat/process.d.ts +20 -0
- package/dist/chat/process.d.ts.map +1 -0
- package/dist/chat/process.js +32 -0
- package/dist/chat/provider.d.ts +63 -0
- package/dist/chat/provider.d.ts.map +1 -0
- package/dist/chat/provider.js +620 -0
- package/dist/chat/question.d.ts +9 -0
- package/dist/chat/question.d.ts.map +1 -0
- package/dist/chat/question.js +80 -0
- package/dist/chat/questions.d.ts +31 -0
- package/dist/chat/questions.d.ts.map +1 -0
- package/dist/chat/questions.js +111 -0
- package/dist/chat/read.d.ts +5 -0
- package/dist/chat/read.d.ts.map +1 -0
- package/dist/chat/read.js +13 -0
- package/dist/chat/ready.d.ts +33 -0
- package/dist/chat/ready.d.ts.map +1 -0
- package/dist/chat/ready.js +91 -0
- package/dist/chat/style.d.ts +4 -0
- package/dist/chat/style.d.ts.map +1 -0
- package/dist/chat/style.js +302 -0
- package/dist/chat.d.ts +14 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +8 -0
- package/dist/client.d.ts +11 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +12 -2
- package/dist/connection.d.ts +13 -6
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +573 -193
- package/dist/conversation.d.ts +14 -4
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +188 -63
- package/dist/entry.d.ts +17 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +156 -0
- package/dist/expectation.d.ts +21 -0
- package/dist/expectation.d.ts.map +1 -0
- package/dist/expectation.js +70 -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 +3 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +13 -6
- package/dist/identity.d.ts +2 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +6 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/memory.d.ts +4 -3
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +40 -11
- package/dist/outcome.d.ts +11 -1
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +7 -0
- package/dist/overlay.d.ts +13 -2
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +64 -22
- package/dist/query.d.ts +2 -0
- package/dist/query.d.ts.map +1 -1
- package/dist/reach.d.ts +2 -0
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +26 -4
- package/dist/react.d.ts +2 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +9 -2
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +12 -17
- package/dist/replica.d.ts +5 -2
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +33 -28
- package/dist/room-draft.d.ts +19 -2
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +119 -1
- package/dist/rows.d.ts +3 -1
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +3 -1
- package/dist/save.d.ts +23 -0
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +309 -18
- package/dist/store.d.ts +36 -18
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +291 -172
- package/dist/wire.d.ts +3 -0
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +3 -0
- package/package.json +26 -14
- package/dist/attachment.d.ts +0 -3
- package/dist/attachment.d.ts.map +0 -1
- package/dist/attachment.js +0 -8
package/dist/store.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { sameChange } from './overlay.js';
|
|
1
|
+
import { sameBinary, sameChange } from './overlay.js';
|
|
3
2
|
const DATABASE = 'mdruntime';
|
|
3
|
+
const AUTHORED = 'mdruntime-authored';
|
|
4
|
+
const FENCES = 'fences';
|
|
4
5
|
const ROOMS = 'rooms';
|
|
5
6
|
const DOCUMENTS = 'documents';
|
|
6
|
-
const
|
|
7
|
-
const ATTACHMENTS = 'attachments';
|
|
7
|
+
const BINARY_FILES = 'binaryFiles';
|
|
8
8
|
const TRANSFERS = 'transfers';
|
|
9
|
+
const RECEIVED = 'received';
|
|
10
|
+
const RECEIVED_PARTS = 'receivedParts';
|
|
9
11
|
const PENDING_CHANGES = 'pendingChanges';
|
|
10
12
|
const DECLARATIONS = 'declarations';
|
|
11
13
|
const ROOM_DRAFTS = 'roomDrafts';
|
|
@@ -13,10 +15,36 @@ const PRESENTATION = 'presentation';
|
|
|
13
15
|
const CONVERSATIONS = 'conversations';
|
|
14
16
|
const MESSAGES = 'messages';
|
|
15
17
|
const CHAT_DRAFTS = 'chatDrafts';
|
|
18
|
+
const QUEUES = 'queues';
|
|
19
|
+
const FACTS = 'facts';
|
|
16
20
|
const CURRENT = 'current';
|
|
17
21
|
const MEMBER = 'member';
|
|
18
|
-
|
|
19
|
-
const
|
|
22
|
+
const GENERATION = 'generation';
|
|
23
|
+
const HOLDER = 'holder';
|
|
24
|
+
const BINDING = 'binding';
|
|
25
|
+
export const STORE_SCHEMA = 24;
|
|
26
|
+
const REPLICA_SHAPE = 23;
|
|
27
|
+
export const AUTHORED_SCHEMA = 2;
|
|
28
|
+
const AUTHORED_STORES = [
|
|
29
|
+
[QUEUES, { keyPath: 'locator' }],
|
|
30
|
+
[PENDING_CHANGES, { keyPath: ['locator', 'id'] }],
|
|
31
|
+
[ROOM_DRAFTS, { keyPath: ['locator', 'path'] }],
|
|
32
|
+
[CHAT_DRAFTS, { keyPath: 'conversation' }],
|
|
33
|
+
[FACTS, undefined],
|
|
34
|
+
[FENCES, { keyPath: 'locator' }],
|
|
35
|
+
];
|
|
36
|
+
const REPLICA_STORES = [
|
|
37
|
+
[ROOMS, { keyPath: 'locator' }],
|
|
38
|
+
[DOCUMENTS, { keyPath: ['locator', 'transfer', 'path'] }],
|
|
39
|
+
[BINARY_FILES, { keyPath: ['locator', 'transfer', 'path'] }],
|
|
40
|
+
[TRANSFERS, { keyPath: 'locator' }],
|
|
41
|
+
[RECEIVED, { keyPath: 'key' }],
|
|
42
|
+
[RECEIVED_PARTS, { keyPath: ['key', 'index'] }],
|
|
43
|
+
[DECLARATIONS, undefined],
|
|
44
|
+
[PRESENTATION, { keyPath: 'app' }],
|
|
45
|
+
[CONVERSATIONS, { keyPath: 'conversation' }],
|
|
46
|
+
[MESSAGES, { keyPath: ['conversation', 'identity'] }],
|
|
47
|
+
];
|
|
20
48
|
const READ_BATCH = 256;
|
|
21
49
|
function settled(request) {
|
|
22
50
|
return new Promise((resolve, reject) => {
|
|
@@ -33,7 +61,6 @@ function completed(transaction) {
|
|
|
33
61
|
}
|
|
34
62
|
const EMPTY_DECLARATIONS = {
|
|
35
63
|
lastCompleted: null,
|
|
36
|
-
generation: null,
|
|
37
64
|
providerLimits: [],
|
|
38
65
|
capabilities: [],
|
|
39
66
|
};
|
|
@@ -61,9 +88,12 @@ function amendPending(database, locator, id, amendment) {
|
|
|
61
88
|
};
|
|
62
89
|
return completed(transaction);
|
|
63
90
|
}
|
|
64
|
-
function roomRecord(record
|
|
65
|
-
const { documents,
|
|
66
|
-
return
|
|
91
|
+
function roomRecord(record) {
|
|
92
|
+
const { documents, binaries, revisions, changes, written, ...room } = record;
|
|
93
|
+
return room;
|
|
94
|
+
}
|
|
95
|
+
function chatDraftRecord(record) {
|
|
96
|
+
return { ...record, revision: record.revision ?? '' };
|
|
67
97
|
}
|
|
68
98
|
function underTransfer(locator, transfer, after) {
|
|
69
99
|
return after === undefined
|
|
@@ -85,7 +115,7 @@ async function readTransfer(store, locator, transfer, receive) {
|
|
|
85
115
|
}
|
|
86
116
|
}
|
|
87
117
|
function emptyLayer() {
|
|
88
|
-
return { documents: {},
|
|
118
|
+
return { documents: {}, binaries: {}, revisions: {}, changes: {}, written: {} };
|
|
89
119
|
}
|
|
90
120
|
async function readLayer(transaction, locator, transfer) {
|
|
91
121
|
const layer = emptyLayer();
|
|
@@ -101,9 +131,9 @@ async function readLayer(transaction, locator, transfer) {
|
|
|
101
131
|
layer.written[document.path] = document.written;
|
|
102
132
|
head(document);
|
|
103
133
|
});
|
|
104
|
-
await readTransfer(transaction.objectStore(
|
|
105
|
-
layer.
|
|
106
|
-
head(
|
|
134
|
+
await readTransfer(transaction.objectStore(BINARY_FILES), locator, transfer, (file) => {
|
|
135
|
+
layer.binaries[file.path] = file.binary;
|
|
136
|
+
head(file);
|
|
107
137
|
});
|
|
108
138
|
return layer;
|
|
109
139
|
}
|
|
@@ -118,13 +148,14 @@ function documentRecord(locator, transfer, layer, path) {
|
|
|
118
148
|
written: layer.written[path] ?? null,
|
|
119
149
|
};
|
|
120
150
|
}
|
|
121
|
-
function
|
|
151
|
+
function binaryFileRecord(locator, transfer, layer, path) {
|
|
122
152
|
return {
|
|
123
153
|
locator,
|
|
124
154
|
transfer,
|
|
125
155
|
path,
|
|
126
156
|
revision: layer.revisions[path] ?? null,
|
|
127
157
|
change: layer.changes[path] ?? null,
|
|
158
|
+
binary: layer.binaries[path],
|
|
128
159
|
};
|
|
129
160
|
}
|
|
130
161
|
function writeLayer(transaction, locator, transfer, next, base) {
|
|
@@ -141,18 +172,16 @@ function writeLayer(transaction, locator, transfer, next, base) {
|
|
|
141
172
|
continue;
|
|
142
173
|
documents.put(documentRecord(locator, transfer, next, path));
|
|
143
174
|
}
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (!afterTargets.has(path))
|
|
149
|
-
targets.delete([locator, transfer, path]);
|
|
175
|
+
const files = transaction.objectStore(BINARY_FILES);
|
|
176
|
+
for (const path of Object.keys(base?.binaries ?? {})) {
|
|
177
|
+
if (next.binaries[path] === undefined)
|
|
178
|
+
files.delete([locator, transfer, path]);
|
|
150
179
|
}
|
|
151
|
-
for (const path of
|
|
152
|
-
if (!
|
|
180
|
+
for (const path of Object.keys(next.binaries)) {
|
|
181
|
+
if (!sameBinary(base?.binaries[path], next.binaries[path]) ||
|
|
153
182
|
base?.revisions[path] !== next.revisions[path] ||
|
|
154
183
|
!sameChange(base?.changes[path], next.changes[path])) {
|
|
155
|
-
|
|
184
|
+
files.put(binaryFileRecord(locator, transfer, next, path));
|
|
156
185
|
}
|
|
157
186
|
}
|
|
158
187
|
}
|
|
@@ -165,155 +194,182 @@ function removeRoomEntries(store, locator) {
|
|
|
165
194
|
}
|
|
166
195
|
};
|
|
167
196
|
}
|
|
168
|
-
|
|
197
|
+
function removeDatabase(name) {
|
|
169
198
|
return new Promise((resolve, reject) => {
|
|
170
|
-
const removal = indexedDB.deleteDatabase(
|
|
199
|
+
const removal = indexedDB.deleteDatabase(name);
|
|
171
200
|
removal.onsuccess = () => resolve();
|
|
172
201
|
removal.onerror = () => reject(removal.error);
|
|
173
202
|
});
|
|
174
203
|
}
|
|
175
|
-
function
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
204
|
+
export async function authoredHolder() {
|
|
205
|
+
const authored = await openAuthored();
|
|
206
|
+
try {
|
|
207
|
+
const transaction = authored.transaction(FACTS, 'readonly');
|
|
208
|
+
const held = transaction.objectStore(FACTS).get(HOLDER);
|
|
209
|
+
await completed(transaction);
|
|
210
|
+
return typeof held.result === 'string' ? held.result : null;
|
|
211
|
+
}
|
|
212
|
+
finally {
|
|
213
|
+
authored.close();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
export async function authoredBy(holder) {
|
|
217
|
+
const authored = await openAuthored();
|
|
218
|
+
try {
|
|
219
|
+
const transaction = authored.transaction(FACTS, 'readwrite');
|
|
220
|
+
const facts = transaction.objectStore(FACTS);
|
|
221
|
+
const held = facts.get(HOLDER);
|
|
222
|
+
let owned = true;
|
|
223
|
+
held.onsuccess = () => {
|
|
224
|
+
if (held.result === undefined)
|
|
225
|
+
facts.put(holder, HOLDER);
|
|
226
|
+
else
|
|
227
|
+
owned = held.result === holder;
|
|
183
228
|
};
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
229
|
+
await completed(transaction);
|
|
230
|
+
return owned;
|
|
231
|
+
}
|
|
232
|
+
finally {
|
|
233
|
+
authored.close();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
export async function authoredBinding() {
|
|
237
|
+
const authored = await openAuthored();
|
|
238
|
+
try {
|
|
239
|
+
const transaction = authored.transaction(FACTS, 'readonly');
|
|
240
|
+
const held = transaction.objectStore(FACTS).get(BINDING);
|
|
241
|
+
await completed(transaction);
|
|
242
|
+
return typeof held.result === 'string' ? held.result : null;
|
|
243
|
+
}
|
|
244
|
+
finally {
|
|
245
|
+
authored.close();
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
export async function bindAuthored(binding) {
|
|
249
|
+
const authored = await openAuthored();
|
|
250
|
+
try {
|
|
251
|
+
const transaction = authored.transaction(FACTS, 'readwrite');
|
|
252
|
+
transaction.objectStore(FACTS).put(binding, BINDING);
|
|
253
|
+
await completed(transaction);
|
|
254
|
+
}
|
|
255
|
+
finally {
|
|
256
|
+
authored.close();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
export async function removeRuntimeStore(holder) {
|
|
260
|
+
await removeDatabase(DATABASE);
|
|
261
|
+
if (holder !== undefined && (await authoredBy(holder)))
|
|
262
|
+
return true;
|
|
263
|
+
await removeDatabase(AUTHORED);
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
function openReplica() {
|
|
267
|
+
const opening = indexedDB.open(DATABASE, STORE_SCHEMA);
|
|
268
|
+
opening.onupgradeneeded = (event) => {
|
|
269
|
+
const database = opening.result;
|
|
270
|
+
if (event.oldVersion < REPLICA_SHAPE) {
|
|
271
|
+
for (const name of [...database.objectStoreNames])
|
|
272
|
+
database.deleteObjectStore(name);
|
|
196
273
|
}
|
|
197
|
-
for (const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
const record = entry.value;
|
|
206
|
-
const transfer = transfers.get(record.locator);
|
|
207
|
-
if (transfer !== undefined)
|
|
208
|
-
to.put({ ...record, transfer });
|
|
209
|
-
entry.continue();
|
|
210
|
-
};
|
|
274
|
+
for (const [name, parameters] of REPLICA_STORES) {
|
|
275
|
+
if (database.objectStoreNames.contains(name))
|
|
276
|
+
continue;
|
|
277
|
+
const store = database.createObjectStore(name, parameters);
|
|
278
|
+
if (name === MESSAGES)
|
|
279
|
+
store.createIndex('conversation', 'conversation');
|
|
211
280
|
}
|
|
212
281
|
};
|
|
282
|
+
return settled(opening);
|
|
213
283
|
}
|
|
214
|
-
|
|
215
|
-
const opening = indexedDB.open(
|
|
216
|
-
opening.onupgradeneeded = (
|
|
284
|
+
function openAuthored() {
|
|
285
|
+
const opening = indexedDB.open(AUTHORED, AUTHORED_SCHEMA);
|
|
286
|
+
opening.onupgradeneeded = () => {
|
|
217
287
|
const database = opening.result;
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
288
|
+
for (const [name, parameters] of AUTHORED_STORES) {
|
|
289
|
+
if (!database.objectStoreNames.contains(name))
|
|
290
|
+
database.createObjectStore(name, parameters);
|
|
221
291
|
}
|
|
222
|
-
for (const name of [...database.objectStoreNames])
|
|
223
|
-
database.deleteObjectStore(name);
|
|
224
|
-
database.createObjectStore(ROOMS, { keyPath: 'locator' });
|
|
225
|
-
database.createObjectStore(DOCUMENTS, { keyPath: ['locator', 'transfer', 'path'] });
|
|
226
|
-
database.createObjectStore(BINARY_TARGETS, { keyPath: ['locator', 'transfer', 'path'] });
|
|
227
|
-
database.createObjectStore(TRANSFERS, { keyPath: 'locator' });
|
|
228
|
-
database.createObjectStore(ATTACHMENTS, { keyPath: ['locator', 'reference'] });
|
|
229
|
-
database.createObjectStore(PENDING_CHANGES, { keyPath: ['locator', 'id'] });
|
|
230
|
-
database.createObjectStore(DECLARATIONS);
|
|
231
|
-
database.createObjectStore(ROOM_DRAFTS, { keyPath: ['locator', 'path'] });
|
|
232
|
-
database.createObjectStore(PRESENTATION, { keyPath: 'app' });
|
|
233
|
-
database.createObjectStore(CONVERSATIONS, { keyPath: 'conversation' });
|
|
234
|
-
const messages = database.createObjectStore(MESSAGES, {
|
|
235
|
-
keyPath: ['conversation', 'identity'],
|
|
236
|
-
});
|
|
237
|
-
messages.createIndex('conversation', 'conversation');
|
|
238
|
-
database.createObjectStore(CHAT_DRAFTS, { keyPath: 'conversation' });
|
|
239
292
|
};
|
|
240
|
-
|
|
293
|
+
return settled(opening);
|
|
294
|
+
}
|
|
295
|
+
export async function openRuntimeStore(fenced) {
|
|
296
|
+
const authored = await openAuthored();
|
|
297
|
+
const database = await openReplica().catch((error) => {
|
|
298
|
+
authored.close();
|
|
299
|
+
throw error;
|
|
300
|
+
});
|
|
241
301
|
return {
|
|
242
302
|
async all() {
|
|
243
|
-
const transaction = database.transaction([ROOMS, DOCUMENTS,
|
|
244
|
-
const
|
|
245
|
-
settled(transaction.objectStore(ROOMS).getAll()),
|
|
246
|
-
settled(transaction.objectStore(ATTACHMENTS).getAll()),
|
|
247
|
-
]);
|
|
303
|
+
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES], 'readonly');
|
|
304
|
+
const rooms = await settled(transaction.objectStore(ROOMS).getAll());
|
|
248
305
|
const records = [];
|
|
249
|
-
for (const
|
|
250
|
-
|
|
251
|
-
records.push({
|
|
252
|
-
...room,
|
|
253
|
-
...layer,
|
|
254
|
-
attachments: attachments.flatMap(({ locator, ...attachment }) => locator === room.locator ? [attachment] : []),
|
|
255
|
-
});
|
|
306
|
+
for (const room of rooms.filter((held) => !fenced(held.locator))) {
|
|
307
|
+
records.push({ ...room, ...(await readLayer(transaction, room.locator, room.transfer)) });
|
|
256
308
|
}
|
|
257
309
|
return records;
|
|
258
310
|
},
|
|
259
|
-
async
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if (moved)
|
|
269
|
-
transaction.objectStore(TRANSFERS).delete(next.locator);
|
|
270
|
-
writeLayer(transaction, next.locator, next.transfer, next, moved ? (stored ?? null) : previous);
|
|
271
|
-
const attachments = transaction.objectStore(ATTACHMENTS);
|
|
272
|
-
const held = new Map((previous?.attachments ?? []).map((attachment) => [attachment.reference, attachment]));
|
|
273
|
-
const declared = new Set(next.attachments.map((attachment) => attachment.reference));
|
|
274
|
-
for (const reference of held.keys()) {
|
|
275
|
-
if (!declared.has(reference))
|
|
276
|
-
attachments.delete([next.locator, reference]);
|
|
277
|
-
}
|
|
278
|
-
for (const attachment of next.attachments) {
|
|
279
|
-
if (held.get(attachment.reference) === attachment)
|
|
280
|
-
continue;
|
|
281
|
-
attachments.put({ ...attachment, locator: next.locator });
|
|
282
|
-
}
|
|
283
|
-
if (previousQueue !== undefined) {
|
|
284
|
-
const pending = transaction.objectStore(PENDING_CHANGES);
|
|
285
|
-
const before = new Set(previousQueue.map((batch) => batch.id));
|
|
311
|
+
async keepAuthored({ locator, queue, saved, roomDrafts, consumedRoomDrafts }) {
|
|
312
|
+
if (fenced(locator))
|
|
313
|
+
return;
|
|
314
|
+
const transaction = authored.transaction([QUEUES, PENDING_CHANGES, ROOM_DRAFTS], 'readwrite');
|
|
315
|
+
const order = transaction.objectStore(QUEUES);
|
|
316
|
+
const pending = transaction.objectStore(PENDING_CHANGES);
|
|
317
|
+
const held = order.get(locator);
|
|
318
|
+
held.onsuccess = () => {
|
|
319
|
+
const before = new Set(held.result?.order ?? []);
|
|
286
320
|
const after = new Set(queue.map((batch) => batch.id));
|
|
321
|
+
if (queue.length === 0)
|
|
322
|
+
order.delete(locator);
|
|
323
|
+
else
|
|
324
|
+
order.put({ locator, order: [...after] });
|
|
287
325
|
for (const id of before) {
|
|
288
326
|
if (!after.has(id))
|
|
289
|
-
pending.delete([
|
|
327
|
+
pending.delete([locator, id]);
|
|
290
328
|
}
|
|
291
329
|
for (const batch of queue) {
|
|
292
330
|
if (!before.has(batch.id)) {
|
|
293
331
|
pending.put({
|
|
294
|
-
locator
|
|
332
|
+
locator,
|
|
295
333
|
id: batch.id,
|
|
296
334
|
batch,
|
|
297
|
-
drafts: saved ?? [],
|
|
335
|
+
drafts: saved?.get(batch.id) ?? [],
|
|
298
336
|
submission: { state: 'waiting' },
|
|
299
337
|
lost: false,
|
|
300
338
|
});
|
|
301
339
|
}
|
|
302
340
|
}
|
|
303
|
-
}
|
|
341
|
+
};
|
|
304
342
|
const draftStore = transaction.objectStore(ROOM_DRAFTS);
|
|
305
343
|
for (const path of consumedRoomDrafts ?? [])
|
|
306
|
-
draftStore.delete([
|
|
344
|
+
draftStore.delete([locator, path]);
|
|
307
345
|
for (const record of roomDrafts ?? [])
|
|
308
346
|
draftStore.put(record);
|
|
309
347
|
await completed(transaction);
|
|
310
348
|
},
|
|
349
|
+
async write({ next, previous, stored }) {
|
|
350
|
+
if (next === previous || fenced(next.locator))
|
|
351
|
+
return;
|
|
352
|
+
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES, TRANSFERS], 'readwrite');
|
|
353
|
+
transaction.objectStore(ROOMS).put(roomRecord(next));
|
|
354
|
+
const moved = previous?.transfer !== next.transfer;
|
|
355
|
+
if (moved && previous !== null) {
|
|
356
|
+
const range = underTransfer(previous.locator, previous.transfer);
|
|
357
|
+
transaction.objectStore(DOCUMENTS).delete(range);
|
|
358
|
+
transaction.objectStore(BINARY_FILES).delete(range);
|
|
359
|
+
}
|
|
360
|
+
if (moved)
|
|
361
|
+
transaction.objectStore(TRANSFERS).delete(next.locator);
|
|
362
|
+
writeLayer(transaction, next.locator, next.transfer, next, moved ? (stored ?? null) : previous);
|
|
363
|
+
await completed(transaction);
|
|
364
|
+
},
|
|
311
365
|
async revokeModels(records) {
|
|
312
366
|
const transaction = database.transaction(ROOMS, 'readwrite');
|
|
313
367
|
const rooms = transaction.objectStore(ROOMS);
|
|
314
368
|
const revoked = { status: 'unavailable', reason: 'revoked' };
|
|
315
|
-
for (const
|
|
316
|
-
|
|
369
|
+
for (const record of records) {
|
|
370
|
+
if (fenced(record.locator))
|
|
371
|
+
continue;
|
|
372
|
+
rooms.put(roomRecord({ ...record, model: revoked, selectionModel: revoked }));
|
|
317
373
|
}
|
|
318
374
|
await completed(transaction);
|
|
319
375
|
},
|
|
@@ -347,35 +403,41 @@ export async function openRuntimeStore() {
|
|
|
347
403
|
await completed(transaction);
|
|
348
404
|
},
|
|
349
405
|
async queues() {
|
|
350
|
-
const transaction =
|
|
351
|
-
const [
|
|
352
|
-
settled(transaction.objectStore(
|
|
406
|
+
const transaction = authored.transaction([QUEUES, PENDING_CHANGES], 'readonly');
|
|
407
|
+
const [queues, pending] = await Promise.all([
|
|
408
|
+
settled(transaction.objectStore(QUEUES).getAll()),
|
|
353
409
|
settled(transaction.objectStore(PENDING_CHANGES).getAll()),
|
|
354
410
|
]);
|
|
355
411
|
const byId = new Map(pending.map((record) => [`${record.locator}\0${record.id}`, record]));
|
|
356
|
-
return
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
412
|
+
return queues
|
|
413
|
+
.filter((queue) => !fenced(queue.locator))
|
|
414
|
+
.map((queue) => ({
|
|
415
|
+
locator: queue.locator,
|
|
416
|
+
pending: queue.order.map((id) => {
|
|
417
|
+
const record = byId.get(`${queue.locator}\0${id}`);
|
|
360
418
|
if (record === undefined)
|
|
361
|
-
throw new Error(`Missing Pending Change ${
|
|
419
|
+
throw new Error(`Missing Pending Change ${queue.locator}/${id}`);
|
|
362
420
|
const { batch, drafts, submission, lost, upload, accepted } = record;
|
|
363
421
|
return { batch, state: { drafts, submission, lost, upload, accepted } };
|
|
364
422
|
}),
|
|
365
423
|
}));
|
|
366
424
|
},
|
|
367
|
-
submit(locator, id, submission, lost) {
|
|
368
|
-
|
|
425
|
+
async submit(locator, id, submission, lost) {
|
|
426
|
+
if (!fenced(locator))
|
|
427
|
+
await amendPending(authored, locator, id, { submission, lost });
|
|
369
428
|
},
|
|
370
|
-
accept(locator, id, roomVersion) {
|
|
371
|
-
|
|
429
|
+
async accept(locator, id, roomVersion) {
|
|
430
|
+
if (!fenced(locator))
|
|
431
|
+
await amendPending(authored, locator, id, { accepted: roomVersion });
|
|
372
432
|
},
|
|
373
|
-
keepUpload(locator, id, upload) {
|
|
374
|
-
|
|
433
|
+
async keepUpload(locator, id, upload) {
|
|
434
|
+
if (!fenced(locator))
|
|
435
|
+
await amendPending(authored, locator, id, { upload });
|
|
375
436
|
},
|
|
376
437
|
async roomDrafts() {
|
|
377
|
-
const transaction =
|
|
378
|
-
|
|
438
|
+
const transaction = authored.transaction(ROOM_DRAFTS, 'readonly');
|
|
439
|
+
const held = await settled(transaction.objectStore(ROOM_DRAFTS).getAll());
|
|
440
|
+
return held.filter((record) => !fenced(record.locator));
|
|
379
441
|
},
|
|
380
442
|
async presentation() {
|
|
381
443
|
const transaction = database.transaction(PRESENTATION, 'readonly');
|
|
@@ -403,8 +465,8 @@ export async function openRuntimeStore() {
|
|
|
403
465
|
}
|
|
404
466
|
return [...held.values()];
|
|
405
467
|
},
|
|
406
|
-
async keepMessages({ conversation, messages, read
|
|
407
|
-
const transaction = database.transaction([CONVERSATIONS, MESSAGES
|
|
468
|
+
async keepMessages({ conversation, messages, read }) {
|
|
469
|
+
const transaction = database.transaction([CONVERSATIONS, MESSAGES], 'readwrite');
|
|
408
470
|
const stored = transaction.objectStore(MESSAGES);
|
|
409
471
|
for (const message of messages) {
|
|
410
472
|
stored.put({ ...message, conversation });
|
|
@@ -414,16 +476,17 @@ export async function openRuntimeStore() {
|
|
|
414
476
|
.objectStore(CONVERSATIONS)
|
|
415
477
|
.put({ conversation, read });
|
|
416
478
|
}
|
|
417
|
-
if (sealed === true)
|
|
418
|
-
transaction.objectStore(CHAT_DRAFTS).delete(conversation);
|
|
419
479
|
await completed(transaction);
|
|
420
480
|
},
|
|
421
481
|
async dropConversations(conversations) {
|
|
422
|
-
const
|
|
482
|
+
const drafts = authored.transaction(CHAT_DRAFTS, 'readwrite');
|
|
483
|
+
for (const conversation of conversations)
|
|
484
|
+
drafts.objectStore(CHAT_DRAFTS).delete(conversation);
|
|
485
|
+
await completed(drafts);
|
|
486
|
+
const transaction = database.transaction([CONVERSATIONS, MESSAGES], 'readwrite');
|
|
423
487
|
const messages = transaction.objectStore(MESSAGES);
|
|
424
488
|
for (const conversation of conversations) {
|
|
425
489
|
transaction.objectStore(CONVERSATIONS).delete(conversation);
|
|
426
|
-
transaction.objectStore(CHAT_DRAFTS).delete(conversation);
|
|
427
490
|
const keys = messages.index('conversation').getAllKeys(conversation);
|
|
428
491
|
keys.onsuccess = () => {
|
|
429
492
|
for (const key of keys.result)
|
|
@@ -433,58 +496,83 @@ export async function openRuntimeStore() {
|
|
|
433
496
|
await completed(transaction);
|
|
434
497
|
},
|
|
435
498
|
async chatDrafts() {
|
|
436
|
-
const transaction =
|
|
437
|
-
|
|
499
|
+
const transaction = authored.transaction(CHAT_DRAFTS, 'readonly');
|
|
500
|
+
const held = await settled(transaction.objectStore(CHAT_DRAFTS).getAll());
|
|
501
|
+
return held.map(chatDraftRecord);
|
|
438
502
|
},
|
|
439
503
|
async keepChatDraft(record) {
|
|
440
|
-
const transaction =
|
|
504
|
+
const transaction = authored.transaction(CHAT_DRAFTS, 'readwrite');
|
|
441
505
|
transaction.objectStore(CHAT_DRAFTS).put(record);
|
|
442
506
|
await completed(transaction);
|
|
443
507
|
},
|
|
444
508
|
async dropChatDraft(conversation) {
|
|
445
|
-
const transaction =
|
|
509
|
+
const transaction = authored.transaction(CHAT_DRAFTS, 'readwrite');
|
|
446
510
|
transaction.objectStore(CHAT_DRAFTS).delete(conversation);
|
|
447
511
|
await completed(transaction);
|
|
448
512
|
},
|
|
449
513
|
async keepRoomDraft(record) {
|
|
450
|
-
|
|
514
|
+
if (fenced(record.locator))
|
|
515
|
+
return;
|
|
516
|
+
const transaction = authored.transaction(ROOM_DRAFTS, 'readwrite');
|
|
451
517
|
transaction.objectStore(ROOM_DRAFTS).put(record);
|
|
452
518
|
await completed(transaction);
|
|
453
519
|
},
|
|
454
520
|
async discardRoomDraft(locator, path) {
|
|
455
|
-
|
|
521
|
+
if (fenced(locator))
|
|
522
|
+
return;
|
|
523
|
+
const transaction = authored.transaction(ROOM_DRAFTS, 'readwrite');
|
|
456
524
|
transaction.objectStore(ROOM_DRAFTS).delete([locator, path]);
|
|
457
525
|
await completed(transaction);
|
|
458
526
|
},
|
|
459
|
-
async
|
|
460
|
-
const transaction =
|
|
527
|
+
async fences() {
|
|
528
|
+
const transaction = authored.transaction(FENCES, 'readonly');
|
|
529
|
+
const held = await settled(transaction.objectStore(FENCES).getAll());
|
|
530
|
+
return held.map((fence) => fence.locator);
|
|
531
|
+
},
|
|
532
|
+
async erase(locators) {
|
|
533
|
+
const work = authored.transaction([FENCES, QUEUES, PENDING_CHANGES, ROOM_DRAFTS], 'readwrite');
|
|
534
|
+
for (const locator of locators) {
|
|
535
|
+
work.objectStore(FENCES).put({ locator });
|
|
536
|
+
work.objectStore(QUEUES).delete(locator);
|
|
537
|
+
for (const name of [PENDING_CHANGES, ROOM_DRAFTS]) {
|
|
538
|
+
removeRoomEntries(work.objectStore(name), locator);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
await completed(work);
|
|
542
|
+
const transaction = database.transaction([ROOMS, DOCUMENTS, BINARY_FILES, TRANSFERS], 'readwrite');
|
|
461
543
|
for (const locator of locators) {
|
|
462
544
|
transaction.objectStore(ROOMS).delete(locator);
|
|
463
545
|
transaction.objectStore(TRANSFERS).delete(locator);
|
|
464
546
|
transaction.objectStore(DOCUMENTS).delete(underRoom(locator));
|
|
465
|
-
transaction.objectStore(
|
|
466
|
-
for (const name of [ATTACHMENTS, PENDING_CHANGES, ROOM_DRAFTS]) {
|
|
467
|
-
removeRoomEntries(transaction.objectStore(name), locator);
|
|
468
|
-
}
|
|
547
|
+
transaction.objectStore(BINARY_FILES).delete(underRoom(locator));
|
|
469
548
|
}
|
|
470
549
|
await completed(transaction);
|
|
550
|
+
const fences = authored.transaction(FENCES, 'readwrite');
|
|
551
|
+
for (const locator of locators)
|
|
552
|
+
fences.objectStore(FENCES).delete(locator);
|
|
553
|
+
await completed(fences);
|
|
471
554
|
},
|
|
472
555
|
async transfers() {
|
|
473
556
|
const transaction = database.transaction(TRANSFERS, 'readonly');
|
|
474
|
-
|
|
557
|
+
const held = await settled(transaction.objectStore(TRANSFERS).getAll());
|
|
558
|
+
return held.filter((record) => !fenced(record.locator));
|
|
475
559
|
},
|
|
476
560
|
staged(record) {
|
|
477
|
-
const transaction = database.transaction([DOCUMENTS,
|
|
561
|
+
const transaction = database.transaction([DOCUMENTS, BINARY_FILES], 'readonly');
|
|
478
562
|
return readLayer(transaction, record.locator, record.transfer);
|
|
479
563
|
},
|
|
480
564
|
async stage(record, page) {
|
|
481
|
-
|
|
565
|
+
if (fenced(record.locator))
|
|
566
|
+
return;
|
|
567
|
+
const transaction = database.transaction([TRANSFERS, DOCUMENTS, BINARY_FILES], 'readwrite');
|
|
482
568
|
writeLayer(transaction, record.locator, record.transfer, page, null);
|
|
483
569
|
transaction.objectStore(TRANSFERS).put(record);
|
|
484
570
|
await completed(transaction);
|
|
485
571
|
},
|
|
486
572
|
async abandon(locator) {
|
|
487
|
-
|
|
573
|
+
if (fenced(locator))
|
|
574
|
+
return;
|
|
575
|
+
const transaction = database.transaction([TRANSFERS, DOCUMENTS, BINARY_FILES], 'readwrite');
|
|
488
576
|
const transfers = transaction.objectStore(TRANSFERS);
|
|
489
577
|
const held = transfers.get(locator);
|
|
490
578
|
held.onsuccess = () => {
|
|
@@ -494,17 +582,48 @@ export async function openRuntimeStore() {
|
|
|
494
582
|
transfers.delete(locator);
|
|
495
583
|
const range = underTransfer(locator, record.transfer);
|
|
496
584
|
transaction.objectStore(DOCUMENTS).delete(range);
|
|
497
|
-
transaction.objectStore(
|
|
585
|
+
transaction.objectStore(BINARY_FILES).delete(range);
|
|
498
586
|
};
|
|
499
587
|
await completed(transaction);
|
|
500
588
|
},
|
|
589
|
+
async receivedHeads() {
|
|
590
|
+
const transaction = database.transaction(RECEIVED, 'readonly');
|
|
591
|
+
return settled(transaction.objectStore(RECEIVED).getAll());
|
|
592
|
+
},
|
|
593
|
+
async receivedParts(key, count) {
|
|
594
|
+
const transaction = database.transaction(RECEIVED_PARTS, 'readonly');
|
|
595
|
+
const kept = await settled(transaction
|
|
596
|
+
.objectStore(RECEIVED_PARTS)
|
|
597
|
+
.getAll(IDBKeyRange.bound([key, 0], [key, count], false, true)));
|
|
598
|
+
return kept.map((part) => part.value);
|
|
599
|
+
},
|
|
600
|
+
async keepReceived(key, head, part) {
|
|
601
|
+
const transaction = database.transaction([RECEIVED, RECEIVED_PARTS], 'readwrite');
|
|
602
|
+
transaction.objectStore(RECEIVED).put({ key, head });
|
|
603
|
+
if (part !== undefined)
|
|
604
|
+
transaction.objectStore(RECEIVED_PARTS).put({ key, ...part });
|
|
605
|
+
await completed(transaction);
|
|
606
|
+
},
|
|
607
|
+
async dropReceived(keys) {
|
|
608
|
+
const transaction = database.transaction([RECEIVED, RECEIVED_PARTS], 'readwrite');
|
|
609
|
+
for (const key of keys) {
|
|
610
|
+
transaction.objectStore(RECEIVED).delete(key);
|
|
611
|
+
transaction.objectStore(RECEIVED_PARTS).delete(IDBKeyRange.bound([key], [key, []]));
|
|
612
|
+
}
|
|
613
|
+
await completed(transaction);
|
|
614
|
+
},
|
|
501
615
|
async generation() {
|
|
502
|
-
|
|
616
|
+
const transaction = authored.transaction(FACTS, 'readonly');
|
|
617
|
+
const held = await settled(transaction.objectStore(FACTS).get(GENERATION));
|
|
618
|
+
return held ?? null;
|
|
503
619
|
},
|
|
504
|
-
rememberGeneration(value) {
|
|
505
|
-
|
|
620
|
+
async rememberGeneration(value) {
|
|
621
|
+
const transaction = authored.transaction(FACTS, 'readwrite');
|
|
622
|
+
transaction.objectStore(FACTS).put(value, GENERATION);
|
|
623
|
+
await completed(transaction);
|
|
506
624
|
},
|
|
507
625
|
close() {
|
|
626
|
+
authored.close();
|
|
508
627
|
database.close();
|
|
509
628
|
},
|
|
510
629
|
};
|