@agentshouse/mdruntime-adapter 0.1.0-cf22c8563f9f4 → 0.1.0-cf41d9210cb6b
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/README.md +2 -2
- package/dist/actions.d.ts +51 -2
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +123 -214
- package/dist/adapter.d.ts +1 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +336 -109
- package/dist/app-reference.d.ts +2 -0
- package/dist/app-reference.d.ts.map +1 -0
- package/dist/app-reference.js +2 -0
- package/dist/crockford.d.ts +4 -0
- package/dist/crockford.d.ts.map +1 -0
- package/dist/crockford.js +3 -0
- package/dist/discovery.d.ts +9 -11
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +55 -36
- package/dist/gather.d.ts +1 -1
- package/dist/gather.d.ts.map +1 -1
- package/dist/gather.js +15 -20
- package/dist/house-model.d.ts +2 -0
- package/dist/house-model.d.ts.map +1 -0
- package/dist/house-model.js +489 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/model.d.ts +6 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +32 -20
- package/dist/part.d.ts +14 -0
- package/dist/part.d.ts.map +1 -0
- package/dist/part.js +90 -0
- package/dist/read.d.ts +74 -20
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +353 -168
- package/dist/refusal.d.ts +2 -5
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +6 -9
- package/dist/room-stream.d.ts +19 -0
- package/dist/room-stream.d.ts.map +1 -0
- package/dist/room-stream.js +57 -0
- package/dist/room-types.d.ts +7 -0
- package/dist/room-types.d.ts.map +1 -0
- package/dist/room-types.js +125 -0
- package/dist/site.d.ts +1 -1
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +131 -62
- package/dist/stream.d.ts +6 -4
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +366 -44
- package/dist/transport.d.ts +76 -11
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +4 -0
- package/dist/upload.d.ts +12 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +63 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/write.d.ts +18 -9
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +164 -41
- package/package.json +9 -6
- package/AGENTS.md +0 -244
- package/dist/links.d.ts +0 -20
- package/dist/links.d.ts.map +0 -1
- package/dist/links.js +0 -104
package/dist/stream.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ROW_WEIGHT, } from '@agentshouse/mdruntime';
|
|
2
|
+
import { acceptedMessage, cursorPosition } from './actions.js';
|
|
3
|
+
import { sha256Hex } from './digest.js';
|
|
4
|
+
import { answered, answering, binaryFileOf, folded, forgotten, headChange, revised, } from './read.js';
|
|
3
5
|
import { roomVersion } from './version.js';
|
|
4
6
|
const HELD_FRAMES_MAX = 256;
|
|
5
7
|
function turnOperation(frame) {
|
|
@@ -14,6 +16,8 @@ function listedConversation(listed) {
|
|
|
14
16
|
created: listed.created_at,
|
|
15
17
|
finished: listed.finished_at,
|
|
16
18
|
outcome: listed.outcome,
|
|
19
|
+
waiting: listed.waiting,
|
|
20
|
+
newest: listed.newest === null ? null : cursorPosition(listed.newest),
|
|
17
21
|
};
|
|
18
22
|
}
|
|
19
23
|
function position(value) {
|
|
@@ -21,9 +25,78 @@ function position(value) {
|
|
|
21
25
|
return null;
|
|
22
26
|
return BigInt(value);
|
|
23
27
|
}
|
|
28
|
+
function assembled(entries) {
|
|
29
|
+
const whole = [];
|
|
30
|
+
let open = null;
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
if (entry.kind === 'piece') {
|
|
33
|
+
if (open === null || open.entry.path !== entry.path || entry.text === undefined)
|
|
34
|
+
return null;
|
|
35
|
+
open.texts.push(entry.text);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
if (open !== null)
|
|
39
|
+
return null;
|
|
40
|
+
if (entry.continued !== true) {
|
|
41
|
+
whole.push(entry);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (entry.text === undefined)
|
|
45
|
+
return null;
|
|
46
|
+
open = { entry, texts: [entry.text] };
|
|
47
|
+
}
|
|
48
|
+
if (entry.continued === true)
|
|
49
|
+
continue;
|
|
50
|
+
const { continued: _continued, ...head } = open.entry;
|
|
51
|
+
whole.push({ ...head, text: open.texts.join('') });
|
|
52
|
+
open = null;
|
|
53
|
+
}
|
|
54
|
+
return open === null ? whole : null;
|
|
55
|
+
}
|
|
56
|
+
async function verified(entries) {
|
|
57
|
+
try {
|
|
58
|
+
for (const entry of entries) {
|
|
59
|
+
if (entry.text === undefined || entry.sha256 === undefined)
|
|
60
|
+
continue;
|
|
61
|
+
if ((await sha256Hex(entry.text)) !== entry.sha256)
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function resumed(kept, frame) {
|
|
71
|
+
const last = frame.entries.at(-1);
|
|
72
|
+
const point = { parts: frame.index + 1, from: frame.from, target: frame.target };
|
|
73
|
+
if (last?.continued !== true)
|
|
74
|
+
return { ...point, handled: frame.handled, piece: null };
|
|
75
|
+
const text = last.text?.length ?? 0;
|
|
76
|
+
if (last.kind !== 'piece') {
|
|
77
|
+
return last.sha256 === undefined
|
|
78
|
+
? kept.resume
|
|
79
|
+
: { ...point, handled: frame.handled, piece: { sha256: last.sha256, offset: text } };
|
|
80
|
+
}
|
|
81
|
+
const piece = kept.resume?.piece ?? null;
|
|
82
|
+
if (piece === null)
|
|
83
|
+
return kept.resume;
|
|
84
|
+
const pieces = frame.entries.reduce((sum, entry) => sum + (entry.kind === 'piece' ? (entry.text?.length ?? 0) : 0), 0);
|
|
85
|
+
return {
|
|
86
|
+
...point,
|
|
87
|
+
handled: frame.handled,
|
|
88
|
+
piece: { sha256: piece.sha256, offset: piece.offset + pieces },
|
|
89
|
+
};
|
|
90
|
+
}
|
|
24
91
|
export function houseNotifications(transport, mode) {
|
|
25
92
|
const stream = transport.stream;
|
|
26
93
|
const lines = new Map();
|
|
94
|
+
const kept = new Map();
|
|
95
|
+
let receipts = null;
|
|
96
|
+
let loaded = Promise.resolve();
|
|
97
|
+
let acknowledging = null;
|
|
98
|
+
let receiving = Promise.resolve();
|
|
99
|
+
let verifying = 0;
|
|
27
100
|
const locators = new Map();
|
|
28
101
|
const observers = new Set();
|
|
29
102
|
const conversationObservers = new Set();
|
|
@@ -41,7 +114,10 @@ export function houseNotifications(transport, mode) {
|
|
|
41
114
|
event.kind === 'questions' ||
|
|
42
115
|
event.kind === 'process' ||
|
|
43
116
|
event.kind === 'commands' ||
|
|
44
|
-
event.kind === 'options'
|
|
117
|
+
event.kind === 'options' ||
|
|
118
|
+
event.kind === 'starting' ||
|
|
119
|
+
event.kind === 'link' ||
|
|
120
|
+
event.kind === 'deliveries') {
|
|
45
121
|
live.add(event.conversation);
|
|
46
122
|
}
|
|
47
123
|
for (const observer of conversationObservers)
|
|
@@ -49,6 +125,7 @@ export function houseNotifications(transport, mode) {
|
|
|
49
125
|
}
|
|
50
126
|
function reopened(next) {
|
|
51
127
|
opening = next;
|
|
128
|
+
acknowledging = next;
|
|
52
129
|
const gapped = new Set([...replicated, ...live]);
|
|
53
130
|
live.clear();
|
|
54
131
|
for (const conversation of gapped)
|
|
@@ -86,6 +163,18 @@ export function houseNotifications(transport, mode) {
|
|
|
86
163
|
emitConversation({ kind: 'options', conversation, options: structuredClone(frame.options) });
|
|
87
164
|
return;
|
|
88
165
|
}
|
|
166
|
+
if (frame.type === 'starting') {
|
|
167
|
+
emitConversation({ kind: 'starting', conversation, step: frame.step });
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (frame.type === 'link') {
|
|
171
|
+
emitConversation({ kind: 'link', conversation, connected: frame.connected });
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (frame.type === 'deliveries') {
|
|
175
|
+
emitConversation({ kind: 'deliveries', conversation, unknown: [...frame.unknown] });
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
89
178
|
if (frame.type === 'interactions') {
|
|
90
179
|
emitConversation({
|
|
91
180
|
kind: 'questions',
|
|
@@ -110,7 +199,162 @@ export function houseNotifications(transport, mode) {
|
|
|
110
199
|
if (line !== undefined)
|
|
111
200
|
lines.set(authority, { ...line, frames: [] });
|
|
112
201
|
}
|
|
113
|
-
function
|
|
202
|
+
async function forget(carries) {
|
|
203
|
+
const held = carries.filter((carry) => kept.delete(carry));
|
|
204
|
+
if (held.length > 0)
|
|
205
|
+
await receipts?.drop(held).catch(() => { });
|
|
206
|
+
}
|
|
207
|
+
async function lost(authority, carry) {
|
|
208
|
+
interrupt(authority);
|
|
209
|
+
await forget([carry]);
|
|
210
|
+
}
|
|
211
|
+
async function stage(frame, via) {
|
|
212
|
+
await loaded;
|
|
213
|
+
const port = receipts;
|
|
214
|
+
if (port === null)
|
|
215
|
+
return;
|
|
216
|
+
const held = kept.get(frame.carry);
|
|
217
|
+
if (held === undefined && frame.index !== 0) {
|
|
218
|
+
interrupt(frame.authority);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (held !== undefined &&
|
|
222
|
+
(held.fenced !== null || frame.index > held.parts || frame.index < (held.resume?.parts ?? 0))) {
|
|
223
|
+
await lost(frame.authority, frame.carry);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (held === undefined) {
|
|
227
|
+
await forget([...kept.values()]
|
|
228
|
+
.filter((other) => other.authority === frame.authority && other.fenced === null)
|
|
229
|
+
.map((other) => other.carry));
|
|
230
|
+
}
|
|
231
|
+
const start = held ?? {
|
|
232
|
+
authority: frame.authority,
|
|
233
|
+
carry: frame.carry,
|
|
234
|
+
logEpoch: lines.get(frame.authority)?.logEpoch ?? null,
|
|
235
|
+
after: frame.after,
|
|
236
|
+
parts: 0,
|
|
237
|
+
resume: null,
|
|
238
|
+
fenced: null,
|
|
239
|
+
};
|
|
240
|
+
const next = { ...start, parts: frame.index + 1, resume: resumed(start, frame) };
|
|
241
|
+
const part = { entries: frame.entries };
|
|
242
|
+
try {
|
|
243
|
+
await port.keep(frame.carry, next, { index: frame.index, value: part });
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
await lost(frame.authority, frame.carry);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
kept.set(frame.carry, next);
|
|
250
|
+
via?.received(frame.authority, frame.carry, frame.index);
|
|
251
|
+
}
|
|
252
|
+
async function keptEntries(carry, parts) {
|
|
253
|
+
if (parts === 0)
|
|
254
|
+
return [];
|
|
255
|
+
if (receipts === null)
|
|
256
|
+
return null;
|
|
257
|
+
const read = (await receipts.parts(carry, parts));
|
|
258
|
+
if (read.length !== parts)
|
|
259
|
+
return null;
|
|
260
|
+
const entries = assembled(read.flatMap((part) => part.entries));
|
|
261
|
+
return entries !== null && (await verified(entries)) ? entries : null;
|
|
262
|
+
}
|
|
263
|
+
async function carried(frame) {
|
|
264
|
+
await loaded;
|
|
265
|
+
const held = kept.get(frame.carry);
|
|
266
|
+
if (frame.parts > 0 && held?.parts !== frame.parts) {
|
|
267
|
+
await lost(frame.authority, frame.carry);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const entries = await keptEntries(frame.carry, frame.parts).catch(() => null);
|
|
271
|
+
if (entries === null) {
|
|
272
|
+
await lost(frame.authority, frame.carry);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const fenced = {
|
|
276
|
+
...(held ?? {
|
|
277
|
+
authority: frame.authority,
|
|
278
|
+
carry: frame.carry,
|
|
279
|
+
logEpoch: frame.log_epoch,
|
|
280
|
+
after: frame.after,
|
|
281
|
+
parts: 0,
|
|
282
|
+
resume: null,
|
|
283
|
+
}),
|
|
284
|
+
after: frame.after,
|
|
285
|
+
fenced: { position: frame.position, logEpoch: frame.log_epoch },
|
|
286
|
+
};
|
|
287
|
+
try {
|
|
288
|
+
await receipts?.keep(frame.carry, fenced);
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
await lost(frame.authority, frame.carry);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
kept.set(frame.carry, fenced);
|
|
295
|
+
publish(frame, entries);
|
|
296
|
+
}
|
|
297
|
+
async function load(port) {
|
|
298
|
+
try {
|
|
299
|
+
for (const { key, head } of await port.heads())
|
|
300
|
+
kept.set(key, head);
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
kept.clear();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
async function restored(room) {
|
|
307
|
+
const line = lines.get(room.authority);
|
|
308
|
+
let at = room.position;
|
|
309
|
+
const chain = [];
|
|
310
|
+
for (;;) {
|
|
311
|
+
const next = [...kept.values()].find((carry) => carry.authority === room.authority &&
|
|
312
|
+
carry.after === at &&
|
|
313
|
+
carry.fenced?.logEpoch === room.log_epoch);
|
|
314
|
+
if (next?.fenced == null)
|
|
315
|
+
break;
|
|
316
|
+
const entries = await keptEntries(next.carry, next.parts).catch(() => null);
|
|
317
|
+
if (entries === null)
|
|
318
|
+
break;
|
|
319
|
+
chain.push({ carry: next, entries });
|
|
320
|
+
at = next.fenced.position;
|
|
321
|
+
}
|
|
322
|
+
const partial = [...kept.values()].find((carry) => carry.authority === room.authority &&
|
|
323
|
+
carry.fenced === null &&
|
|
324
|
+
carry.logEpoch === room.log_epoch &&
|
|
325
|
+
carry.after === at &&
|
|
326
|
+
carry.resume !== null &&
|
|
327
|
+
carry.resume.parts > 0);
|
|
328
|
+
const stale = [...kept.values()].filter((carry) => carry.authority === room.authority &&
|
|
329
|
+
carry !== partial &&
|
|
330
|
+
!chain.some((link) => link.carry === carry));
|
|
331
|
+
await forget(stale.map((carry) => carry.carry));
|
|
332
|
+
if (line !== undefined && line.logEpoch === room.log_epoch && chain.length > 0) {
|
|
333
|
+
const frames = chain.map(({ carry, entries }) => ({
|
|
334
|
+
after: BigInt(carry.after),
|
|
335
|
+
position: BigInt(carry.fenced.position),
|
|
336
|
+
entries,
|
|
337
|
+
}));
|
|
338
|
+
lines.set(room.authority, { ...line, frames: [...line.frames, ...frames] });
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
...room,
|
|
342
|
+
position: at,
|
|
343
|
+
...(partial?.resume == null
|
|
344
|
+
? {}
|
|
345
|
+
: {
|
|
346
|
+
carry: {
|
|
347
|
+
id: partial.carry,
|
|
348
|
+
parts: partial.resume.parts,
|
|
349
|
+
from: partial.resume.from,
|
|
350
|
+
target: partial.resume.target,
|
|
351
|
+
handled: partial.resume.handled,
|
|
352
|
+
...(partial.resume.piece === null ? {} : { piece: partial.resume.piece }),
|
|
353
|
+
},
|
|
354
|
+
}),
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
function handle(frame, via) {
|
|
114
358
|
if (frame.type === 'signal') {
|
|
115
359
|
const mode = frame.service_mode;
|
|
116
360
|
if (mode !== 'open' && mode !== 'write-halted')
|
|
@@ -126,6 +370,10 @@ export function houseNotifications(transport, mode) {
|
|
|
126
370
|
});
|
|
127
371
|
return;
|
|
128
372
|
}
|
|
373
|
+
if (frame.type === 'authority_changed') {
|
|
374
|
+
emit({ kind: 'authority-changed', scope: { authorities: frame.rooms } });
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
129
377
|
if (frame.type === 'conversations') {
|
|
130
378
|
emitConversation({ kind: 'list', entries: frame.conversations.map(listedConversation) });
|
|
131
379
|
return;
|
|
@@ -142,13 +390,23 @@ export function houseNotifications(transport, mode) {
|
|
|
142
390
|
frame.type === 'process' ||
|
|
143
391
|
frame.type === 'commands' ||
|
|
144
392
|
frame.type === 'options' ||
|
|
393
|
+
frame.type === 'starting' ||
|
|
394
|
+
frame.type === 'link' ||
|
|
395
|
+
frame.type === 'deliveries' ||
|
|
145
396
|
frame.type === 'interactions' ||
|
|
146
397
|
frame.type === 'message') {
|
|
147
398
|
converse(frame);
|
|
148
399
|
return;
|
|
149
400
|
}
|
|
150
|
-
if (frame.type
|
|
151
|
-
return;
|
|
401
|
+
if (frame.type === 'part')
|
|
402
|
+
return ahead(() => stage(frame, via));
|
|
403
|
+
if (frame.type === 'carried')
|
|
404
|
+
return ahead(() => carried(frame));
|
|
405
|
+
}
|
|
406
|
+
function ahead(work) {
|
|
407
|
+
return receipts === null ? work() : receipts.ahead(work);
|
|
408
|
+
}
|
|
409
|
+
function publish(frame, entries) {
|
|
152
410
|
const at = position(frame.position);
|
|
153
411
|
const after = position(frame.after);
|
|
154
412
|
if (at === null || after === null || after >= at) {
|
|
@@ -162,7 +420,7 @@ export function houseNotifications(transport, mode) {
|
|
|
162
420
|
const last = line.frames.at(-1);
|
|
163
421
|
if (last !== undefined && at <= last.position)
|
|
164
422
|
return;
|
|
165
|
-
const held = { after, position: at, entries
|
|
423
|
+
const held = { after, position: at, entries };
|
|
166
424
|
const next = last !== undefined && after <= last.position ? [...line.frames, held] : [held];
|
|
167
425
|
lines.set(frame.authority, { ...line, frames: next.length > HELD_FRAMES_MAX ? [] : next });
|
|
168
426
|
}
|
|
@@ -171,11 +429,30 @@ export function houseNotifications(transport, mode) {
|
|
|
171
429
|
}
|
|
172
430
|
announce(frame.authority, { position: frame.position, logEpoch: frame.log_epoch });
|
|
173
431
|
}
|
|
174
|
-
stream.observe(
|
|
432
|
+
stream.observe((frame) => {
|
|
433
|
+
const via = acknowledging;
|
|
434
|
+
if (verifying === 0) {
|
|
435
|
+
const handled = handle(frame, via);
|
|
436
|
+
if (handled === undefined)
|
|
437
|
+
return;
|
|
438
|
+
verifying += 1;
|
|
439
|
+
receiving = handled.finally(() => {
|
|
440
|
+
verifying -= 1;
|
|
441
|
+
});
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
verifying += 1;
|
|
445
|
+
receiving = receiving
|
|
446
|
+
.then(() => handle(frame, via))
|
|
447
|
+
.finally(() => {
|
|
448
|
+
verifying -= 1;
|
|
449
|
+
});
|
|
450
|
+
});
|
|
175
451
|
stream.opened(reopened);
|
|
176
|
-
stream.closed((revoked) => {
|
|
452
|
+
stream.closed(({ revoked, lost }) => {
|
|
177
453
|
opening = null;
|
|
178
|
-
|
|
454
|
+
acknowledging = null;
|
|
455
|
+
emit({ kind: 'closed', revoked, lost });
|
|
179
456
|
});
|
|
180
457
|
return {
|
|
181
458
|
runtime,
|
|
@@ -198,8 +475,12 @@ export function houseNotifications(transport, mode) {
|
|
|
198
475
|
};
|
|
199
476
|
},
|
|
200
477
|
},
|
|
201
|
-
observe(notify) {
|
|
478
|
+
observe(notify, port) {
|
|
202
479
|
observers.add(notify);
|
|
480
|
+
if (receipts === null) {
|
|
481
|
+
receipts = port;
|
|
482
|
+
loaded = load(port);
|
|
483
|
+
}
|
|
203
484
|
if (opening !== null) {
|
|
204
485
|
queueMicrotask(() => {
|
|
205
486
|
if (observers.has(notify))
|
|
@@ -220,7 +501,35 @@ export function houseNotifications(transport, mode) {
|
|
|
220
501
|
}
|
|
221
502
|
const current = opening;
|
|
222
503
|
opening = null;
|
|
223
|
-
current
|
|
504
|
+
if (current === null)
|
|
505
|
+
return;
|
|
506
|
+
void loaded
|
|
507
|
+
.then(() => Promise.all(rooms.map(restored)))
|
|
508
|
+
.then((presented) => {
|
|
509
|
+
current.hold(presented, runtime);
|
|
510
|
+
for (const [index, room] of presented.entries()) {
|
|
511
|
+
if (room.position === rooms[index].position)
|
|
512
|
+
continue;
|
|
513
|
+
announce(room.authority, { position: room.position, logEpoch: room.log_epoch });
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
},
|
|
517
|
+
published(locator, at) {
|
|
518
|
+
const authority = [...locators].find(([, held]) => held.includes(locator))?.[0];
|
|
519
|
+
const reached = position(at.position);
|
|
520
|
+
if (authority === undefined || reached === null)
|
|
521
|
+
return;
|
|
522
|
+
void forget([...kept.values()]
|
|
523
|
+
.filter((carry) => carry.authority === authority &&
|
|
524
|
+
carry.fenced !== null &&
|
|
525
|
+
carry.fenced.logEpoch === at.logEpoch &&
|
|
526
|
+
BigInt(carry.fenced.position) <= reached)
|
|
527
|
+
.map((carry) => carry.carry));
|
|
528
|
+
},
|
|
529
|
+
reopen() {
|
|
530
|
+
const current = opening;
|
|
531
|
+
opening = null;
|
|
532
|
+
current?.close();
|
|
224
533
|
},
|
|
225
534
|
track(entries) {
|
|
226
535
|
locators.clear();
|
|
@@ -234,6 +543,9 @@ export function houseNotifications(transport, mode) {
|
|
|
234
543
|
if (!locators.has(authority))
|
|
235
544
|
lines.delete(authority);
|
|
236
545
|
}
|
|
546
|
+
void loaded.then(() => forget([...kept.values()]
|
|
547
|
+
.filter((carry) => !locators.has(carry.authority))
|
|
548
|
+
.map((carry) => carry.carry)));
|
|
237
549
|
},
|
|
238
550
|
reach(authority, at) {
|
|
239
551
|
const line = lines.get(authority);
|
|
@@ -248,7 +560,18 @@ export function houseNotifications(transport, mode) {
|
|
|
248
560
|
held,
|
|
249
561
|
});
|
|
250
562
|
},
|
|
251
|
-
|
|
563
|
+
edited(tracked, from) {
|
|
564
|
+
const line = lines.get(tracked.authority);
|
|
565
|
+
const start = position(from.position);
|
|
566
|
+
if (line === undefined || start === null || line.logEpoch !== from.logEpoch)
|
|
567
|
+
return [];
|
|
568
|
+
return [
|
|
569
|
+
...new Set(line.frames
|
|
570
|
+
.filter((frame) => frame.position > start)
|
|
571
|
+
.flatMap((frame) => frame.entries.flatMap((entry) => entry.kind === 'edited' && entry.revision !== undefined ? [entry.path] : []))),
|
|
572
|
+
];
|
|
573
|
+
},
|
|
574
|
+
*advance(tracked, from, holds) {
|
|
252
575
|
const line = lines.get(tracked.authority);
|
|
253
576
|
const start = position(from.position);
|
|
254
577
|
if (line === undefined || start === null || line.logEpoch !== from.logEpoch)
|
|
@@ -257,64 +580,63 @@ export function houseNotifications(transport, mode) {
|
|
|
257
580
|
const first = pending[0];
|
|
258
581
|
if (first === undefined || first.after > start)
|
|
259
582
|
return null;
|
|
260
|
-
const
|
|
261
|
-
const revisions = {};
|
|
262
|
-
const changes = {};
|
|
263
|
-
const removals = [];
|
|
264
|
-
const applied = [];
|
|
583
|
+
const answer = answering();
|
|
265
584
|
const schemas = new Map();
|
|
266
|
-
const forget = (path) => {
|
|
267
|
-
delete documents[path];
|
|
268
|
-
delete revisions[path];
|
|
269
|
-
delete changes[path];
|
|
270
|
-
const removed = removals.indexOf(path);
|
|
271
|
-
if (removed !== -1)
|
|
272
|
-
removals.splice(removed, 1);
|
|
273
|
-
};
|
|
274
585
|
for (const frame of pending) {
|
|
275
586
|
for (const entry of frame.entries) {
|
|
587
|
+
yield ROW_WEIGHT + (entry.text?.length ?? 0);
|
|
588
|
+
if (entry.kind === 'folder') {
|
|
589
|
+
folded(answer, entry.path, entry.removed === true);
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
276
592
|
if (entry.kind === 'edited' &&
|
|
277
593
|
entry.revision !== undefined &&
|
|
278
594
|
holds?.(entry.path, entry.revision) === true) {
|
|
279
|
-
|
|
595
|
+
forgotten(answer, entry.path);
|
|
280
596
|
continue;
|
|
281
597
|
}
|
|
282
|
-
|
|
283
|
-
if (tracked.schemas.includes(entry.path))
|
|
598
|
+
if (entry.path === tracked.schema)
|
|
284
599
|
schemas.set(entry.path, entry);
|
|
285
600
|
if (entry.kind === 'removed') {
|
|
286
|
-
|
|
287
|
-
removals.
|
|
601
|
+
forgotten(answer, entry.path);
|
|
602
|
+
answer.removals.add(entry.path);
|
|
288
603
|
continue;
|
|
289
604
|
}
|
|
290
|
-
|
|
605
|
+
const binary = binaryFileOf(entry);
|
|
606
|
+
if (binary === null || (binary === undefined && entry.text === undefined))
|
|
291
607
|
return null;
|
|
292
608
|
if (mode === 'credential' && entry.revision === undefined)
|
|
293
609
|
return null;
|
|
294
610
|
const head = headChange(entry);
|
|
295
611
|
if (head === null)
|
|
296
612
|
return null;
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
613
|
+
forgotten(answer, entry.path);
|
|
614
|
+
if (binary === undefined)
|
|
615
|
+
answer.documents.set(entry.path, entry.text);
|
|
616
|
+
else
|
|
617
|
+
answer.binaryFiles.set(entry.path, binary);
|
|
618
|
+
const revision = entry.revision ?? binary?.sha256;
|
|
619
|
+
if (revision !== undefined)
|
|
620
|
+
revised(answer, entry.path, revision);
|
|
301
621
|
if (head !== undefined)
|
|
302
|
-
changes
|
|
622
|
+
answer.changes.set(entry.path, head);
|
|
303
623
|
}
|
|
304
624
|
}
|
|
305
625
|
const last = pending.at(-1);
|
|
306
|
-
lines.
|
|
626
|
+
const current = lines.get(tracked.authority);
|
|
627
|
+
if (current?.logEpoch === line.logEpoch) {
|
|
628
|
+
lines.set(tracked.authority, {
|
|
629
|
+
...current,
|
|
630
|
+
frames: current.frames.filter((frame) => frame.position > start),
|
|
631
|
+
held: current.held !== null && current.held > last.position ? current.held : last.position,
|
|
632
|
+
});
|
|
633
|
+
}
|
|
307
634
|
return {
|
|
308
635
|
page: {
|
|
309
636
|
kind: 'net-advancement',
|
|
310
637
|
roomVersion: roomVersion({ position: last.position.toString(), logEpoch: line.logEpoch }),
|
|
311
|
-
|
|
312
|
-
revisions,
|
|
313
|
-
changes,
|
|
314
|
-
binaryTargets: [],
|
|
315
|
-
removals: removals.sort(),
|
|
638
|
+
...(yield* answered(answer)),
|
|
316
639
|
},
|
|
317
|
-
entries: applied,
|
|
318
640
|
schemas,
|
|
319
641
|
};
|
|
320
642
|
},
|