@agentshouse/mdruntime-adapter 0.1.0-cb6436097e8a2 → 0.1.0-cb8fc491b1a92
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 +122 -23
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +27 -141
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +220 -337
- 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 +6 -10
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +36 -40
- package/dist/house-model.d.ts +2983 -0
- package/dist/house-model.d.ts.map +1 -0
- package/dist/house-model.js +1643 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/model.d.ts +5 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +10 -29
- 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 +46 -63
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +216 -283
- package/dist/refusal.d.ts +0 -3
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +0 -5
- 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 +126 -0
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +80 -179
- package/dist/stream.d.ts +4 -14
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +125 -413
- package/dist/transport.d.ts +53 -43
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +49 -11
- package/dist/upload.d.ts +12 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +63 -0
- package/dist/write.d.ts +16 -1
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +101 -56
- package/package.json +8 -4
- package/AGENTS.md +0 -299
- package/dist/gather.d.ts +0 -4
- package/dist/gather.d.ts.map +0 -1
- package/dist/gather.js +0 -45
- package/dist/handed.d.ts +0 -15
- package/dist/handed.d.ts.map +0 -1
- package/dist/handed.js +0 -38
- package/dist/referrer.d.ts +0 -7
- package/dist/referrer.d.ts.map +0 -1
- package/dist/referrer.js +0 -35
package/dist/stream.js
CHANGED
|
@@ -1,100 +1,84 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { ROW_WEIGHT, stepped, } from '@agentshouse/mdruntime';
|
|
2
|
+
import { acceptedMessage, cursorPosition } from './actions.js';
|
|
3
|
+
import { streamedModels } from './model.js';
|
|
4
|
+
import { answered, answering, binaryFileOf, folded, forgotten, headChange, revised, } from './read.js';
|
|
5
|
+
import { houseDoorRoute, } from './transport.js';
|
|
6
|
+
import { DECIMAL, roomVersion } from './version.js';
|
|
6
7
|
function turnOperation(frame) {
|
|
7
8
|
const { type: _type, conversation_id: _conversation, turn_id: _turn, ...operation } = frame;
|
|
8
9
|
return structuredClone(operation);
|
|
9
10
|
}
|
|
11
|
+
async function houseAgents(transport) {
|
|
12
|
+
const answer = await transport.door(houseDoorRoute('agents/read'), {});
|
|
13
|
+
const agents = answer.status === 200 ? answer.body?.agents : null;
|
|
14
|
+
if (!Array.isArray(agents))
|
|
15
|
+
return null;
|
|
16
|
+
return agents.flatMap((one) => {
|
|
17
|
+
const { id, name, retired_at: retired } = (one ?? {});
|
|
18
|
+
return typeof id === 'string' && typeof name === 'string'
|
|
19
|
+
? [{ agent: id, name, retired: retired !== null && retired !== undefined }]
|
|
20
|
+
: [];
|
|
21
|
+
});
|
|
22
|
+
}
|
|
10
23
|
function listedConversation(listed) {
|
|
11
24
|
return {
|
|
12
25
|
conversation: listed.conversation_id,
|
|
13
26
|
agent: listed.agent_id,
|
|
27
|
+
agentName: listed.agent_name,
|
|
28
|
+
agentRetired: listed.agent_retired,
|
|
14
29
|
name: listed.name,
|
|
15
30
|
created: listed.created_at,
|
|
16
31
|
finished: listed.finished_at,
|
|
17
32
|
outcome: listed.outcome,
|
|
33
|
+
waiting: listed.waiting,
|
|
34
|
+
newest: listed.newest === null ? null : cursorPosition(listed.newest),
|
|
18
35
|
};
|
|
19
36
|
}
|
|
20
37
|
function position(value) {
|
|
21
|
-
if (
|
|
38
|
+
if (!DECIMAL.test(value))
|
|
22
39
|
return null;
|
|
23
40
|
return BigInt(value);
|
|
24
41
|
}
|
|
25
|
-
function
|
|
26
|
-
const
|
|
27
|
-
let open = null;
|
|
42
|
+
function* changed(tracked, entries, version, schemas) {
|
|
43
|
+
const answer = answering();
|
|
28
44
|
for (const entry of entries) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
if (open !== null)
|
|
36
|
-
return null;
|
|
37
|
-
if (entry.continued !== true) {
|
|
38
|
-
whole.push(entry);
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
if (entry.text === undefined)
|
|
42
|
-
return null;
|
|
43
|
-
open = { entry, texts: [entry.text] };
|
|
45
|
+
yield ROW_WEIGHT + (entry.text?.length ?? 0);
|
|
46
|
+
if (entry.kind === 'folder') {
|
|
47
|
+
folded(answer, entry.path, entry.removed === true);
|
|
48
|
+
continue;
|
|
44
49
|
}
|
|
45
|
-
if (entry.
|
|
50
|
+
if (entry.path === tracked.schema)
|
|
51
|
+
schemas.set(entry.path, entry);
|
|
52
|
+
forgotten(answer, entry.path);
|
|
53
|
+
if (entry.kind === 'removed') {
|
|
54
|
+
answer.removals.add(entry.path);
|
|
46
55
|
continue;
|
|
47
|
-
const { continued: _continued, ...head } = open.entry;
|
|
48
|
-
whole.push({ ...head, text: open.texts.join('') });
|
|
49
|
-
open = null;
|
|
50
|
-
}
|
|
51
|
-
return open === null ? whole : null;
|
|
52
|
-
}
|
|
53
|
-
async function verified(entries) {
|
|
54
|
-
try {
|
|
55
|
-
for (const entry of entries) {
|
|
56
|
-
if (entry.text === undefined || entry.sha256 === undefined)
|
|
57
|
-
continue;
|
|
58
|
-
if ((await sha256Hex(entry.text)) !== entry.sha256)
|
|
59
|
-
return false;
|
|
60
56
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
const binary = binaryFileOf(entry);
|
|
58
|
+
if (binary === undefined)
|
|
59
|
+
answer.documents.set(entry.path, entry.text ?? '');
|
|
60
|
+
else if (binary !== null)
|
|
61
|
+
answer.binaryFiles.set(entry.path, binary);
|
|
62
|
+
const revision = entry.revision ?? binary?.sha256;
|
|
63
|
+
if (revision !== undefined)
|
|
64
|
+
revised(answer, entry.path, revision);
|
|
65
|
+
const head = headChange(entry);
|
|
66
|
+
if (head)
|
|
67
|
+
answer.changes.set(entry.path, head);
|
|
65
68
|
}
|
|
69
|
+
return { kind: 'net-advancement', roomVersion: version, ...(yield* answered(answer)) };
|
|
66
70
|
}
|
|
67
|
-
function
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const text = last.text?.length ?? 0;
|
|
73
|
-
if (last.kind !== 'piece') {
|
|
74
|
-
return last.sha256 === undefined
|
|
75
|
-
? kept.resume
|
|
76
|
-
: { ...point, handled: frame.handled, piece: { sha256: last.sha256, offset: text } };
|
|
77
|
-
}
|
|
78
|
-
const piece = kept.resume?.piece ?? null;
|
|
79
|
-
if (piece === null)
|
|
80
|
-
return kept.resume;
|
|
81
|
-
const pieces = frame.entries.reduce((sum, entry) => sum + (entry.kind === 'piece' ? (entry.text?.length ?? 0) : 0), 0);
|
|
82
|
-
return {
|
|
83
|
-
...point,
|
|
84
|
-
handled: frame.handled,
|
|
85
|
-
piece: { sha256: piece.sha256, offset: piece.offset + pieces },
|
|
86
|
-
};
|
|
71
|
+
async function changePage(tracked, entries, version, mode) {
|
|
72
|
+
const schemas = new Map();
|
|
73
|
+
const page = await stepped(changed(tracked, entries, version, schemas));
|
|
74
|
+
const models = await streamedModels(schemas, tracked, mode);
|
|
75
|
+
return models === undefined ? page : { ...page, models };
|
|
87
76
|
}
|
|
88
77
|
export function houseNotifications(transport, mode) {
|
|
89
78
|
const stream = transport.stream;
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
let loaded = Promise.resolve();
|
|
94
|
-
let acknowledging = null;
|
|
95
|
-
let receiving = Promise.resolve();
|
|
96
|
-
let verifying = 0;
|
|
97
|
-
const locators = new Map();
|
|
79
|
+
const staged = new Map();
|
|
80
|
+
let socket = null;
|
|
81
|
+
const tracking = new Map();
|
|
98
82
|
const observers = new Set();
|
|
99
83
|
const conversationObservers = new Set();
|
|
100
84
|
const modeObservers = new Set();
|
|
@@ -111,7 +95,10 @@ export function houseNotifications(transport, mode) {
|
|
|
111
95
|
event.kind === 'questions' ||
|
|
112
96
|
event.kind === 'process' ||
|
|
113
97
|
event.kind === 'commands' ||
|
|
114
|
-
event.kind === 'options'
|
|
98
|
+
event.kind === 'options' ||
|
|
99
|
+
event.kind === 'starting' ||
|
|
100
|
+
event.kind === 'link' ||
|
|
101
|
+
event.kind === 'deliveries') {
|
|
115
102
|
live.add(event.conversation);
|
|
116
103
|
}
|
|
117
104
|
for (const observer of conversationObservers)
|
|
@@ -119,7 +106,8 @@ export function houseNotifications(transport, mode) {
|
|
|
119
106
|
}
|
|
120
107
|
function reopened(next) {
|
|
121
108
|
opening = next;
|
|
122
|
-
|
|
109
|
+
socket = next;
|
|
110
|
+
staged.clear();
|
|
123
111
|
const gapped = new Set([...replicated, ...live]);
|
|
124
112
|
live.clear();
|
|
125
113
|
for (const conversation of gapped)
|
|
@@ -157,6 +145,18 @@ export function houseNotifications(transport, mode) {
|
|
|
157
145
|
emitConversation({ kind: 'options', conversation, options: structuredClone(frame.options) });
|
|
158
146
|
return;
|
|
159
147
|
}
|
|
148
|
+
if (frame.type === 'starting') {
|
|
149
|
+
emitConversation({ kind: 'starting', conversation, step: frame.step });
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (frame.type === 'link') {
|
|
153
|
+
emitConversation({ kind: 'link', conversation, connected: frame.connected });
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (frame.type === 'deliveries') {
|
|
157
|
+
emitConversation({ kind: 'deliveries', conversation, unknown: [...frame.unknown] });
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
160
|
if (frame.type === 'interactions') {
|
|
161
161
|
emitConversation({
|
|
162
162
|
kind: 'questions',
|
|
@@ -170,171 +170,30 @@ export function houseNotifications(transport, mode) {
|
|
|
170
170
|
return;
|
|
171
171
|
emitConversation({ kind: 'accepted-message', conversation, message });
|
|
172
172
|
}
|
|
173
|
-
function
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
function interrupt(authority) {
|
|
180
|
-
const line = lines.get(authority);
|
|
181
|
-
if (line !== undefined)
|
|
182
|
-
lines.set(authority, { ...line, frames: [] });
|
|
183
|
-
}
|
|
184
|
-
async function forget(carries) {
|
|
185
|
-
const held = carries.filter((carry) => kept.delete(carry));
|
|
186
|
-
if (held.length > 0)
|
|
187
|
-
await receipts?.drop(held).catch(() => { });
|
|
188
|
-
}
|
|
189
|
-
async function lost(authority, carry) {
|
|
190
|
-
interrupt(authority);
|
|
191
|
-
await forget([carry]);
|
|
192
|
-
}
|
|
193
|
-
async function stage(frame, via) {
|
|
194
|
-
await loaded;
|
|
195
|
-
const port = receipts;
|
|
196
|
-
if (port === null)
|
|
197
|
-
return;
|
|
198
|
-
const held = kept.get(frame.carry);
|
|
199
|
-
if (held === undefined && frame.index !== 0) {
|
|
200
|
-
interrupt(frame.authority);
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
if (held !== undefined &&
|
|
204
|
-
(held.fenced !== null || frame.index > held.parts || frame.index < (held.resume?.parts ?? 0))) {
|
|
205
|
-
await lost(frame.authority, frame.carry);
|
|
173
|
+
function stage(frame, via) {
|
|
174
|
+
const held = staged.get(frame.carry);
|
|
175
|
+
if (frame.index !== (held?.parts ?? 0)) {
|
|
176
|
+
staged.delete(frame.carry);
|
|
206
177
|
return;
|
|
207
178
|
}
|
|
208
179
|
if (held === undefined) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
const start = held ?? {
|
|
214
|
-
authority: frame.authority,
|
|
215
|
-
carry: frame.carry,
|
|
216
|
-
logEpoch: lines.get(frame.authority)?.logEpoch ?? null,
|
|
217
|
-
after: frame.after,
|
|
218
|
-
parts: 0,
|
|
219
|
-
resume: null,
|
|
220
|
-
fenced: null,
|
|
221
|
-
};
|
|
222
|
-
const next = { ...start, parts: frame.index + 1, resume: resumed(start, frame) };
|
|
223
|
-
const part = { entries: frame.entries };
|
|
224
|
-
try {
|
|
225
|
-
await port.keep(frame.carry, next, { index: frame.index, value: part });
|
|
226
|
-
}
|
|
227
|
-
catch {
|
|
228
|
-
await lost(frame.authority, frame.carry);
|
|
229
|
-
return;
|
|
180
|
+
for (const [carry, other] of staged) {
|
|
181
|
+
if (other.authority === frame.authority)
|
|
182
|
+
staged.delete(carry);
|
|
183
|
+
}
|
|
230
184
|
}
|
|
231
|
-
|
|
185
|
+
const next = held ?? { authority: frame.authority, parts: 0, entries: [] };
|
|
186
|
+
next.entries.push(...frame.entries);
|
|
187
|
+
next.parts += 1;
|
|
188
|
+
staged.set(frame.carry, next);
|
|
232
189
|
via?.received(frame.authority, frame.carry, frame.index);
|
|
233
190
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if (
|
|
238
|
-
return null;
|
|
239
|
-
const read = (await receipts.parts(carry, parts));
|
|
240
|
-
if (read.length !== parts)
|
|
241
|
-
return null;
|
|
242
|
-
const entries = assembled(read.flatMap((part) => part.entries));
|
|
243
|
-
return entries !== null && (await verified(entries)) ? entries : null;
|
|
244
|
-
}
|
|
245
|
-
async function carried(frame) {
|
|
246
|
-
await loaded;
|
|
247
|
-
const held = kept.get(frame.carry);
|
|
248
|
-
if (frame.parts > 0 && held?.parts !== frame.parts) {
|
|
249
|
-
await lost(frame.authority, frame.carry);
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
const entries = await keptEntries(frame.carry, frame.parts).catch(() => null);
|
|
253
|
-
if (entries === null) {
|
|
254
|
-
await lost(frame.authority, frame.carry);
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
const fenced = {
|
|
258
|
-
...(held ?? {
|
|
259
|
-
authority: frame.authority,
|
|
260
|
-
carry: frame.carry,
|
|
261
|
-
logEpoch: frame.log_epoch,
|
|
262
|
-
after: frame.after,
|
|
263
|
-
parts: 0,
|
|
264
|
-
resume: null,
|
|
265
|
-
}),
|
|
266
|
-
after: frame.after,
|
|
267
|
-
fenced: { position: frame.position, logEpoch: frame.log_epoch },
|
|
268
|
-
};
|
|
269
|
-
try {
|
|
270
|
-
await receipts?.keep(frame.carry, fenced);
|
|
271
|
-
}
|
|
272
|
-
catch {
|
|
273
|
-
await lost(frame.authority, frame.carry);
|
|
191
|
+
function carried(frame) {
|
|
192
|
+
const held = staged.get(frame.carry);
|
|
193
|
+
staged.delete(frame.carry);
|
|
194
|
+
if ((held?.parts ?? 0) !== frame.parts)
|
|
274
195
|
return;
|
|
275
|
-
|
|
276
|
-
kept.set(frame.carry, fenced);
|
|
277
|
-
publish(frame, entries);
|
|
278
|
-
}
|
|
279
|
-
async function load(port) {
|
|
280
|
-
try {
|
|
281
|
-
for (const { key, head } of await port.heads())
|
|
282
|
-
kept.set(key, head);
|
|
283
|
-
}
|
|
284
|
-
catch {
|
|
285
|
-
kept.clear();
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
async function restored(room) {
|
|
289
|
-
const line = lines.get(room.authority);
|
|
290
|
-
let at = room.position;
|
|
291
|
-
const chain = [];
|
|
292
|
-
for (;;) {
|
|
293
|
-
const next = [...kept.values()].find((carry) => carry.authority === room.authority &&
|
|
294
|
-
carry.after === at &&
|
|
295
|
-
carry.fenced?.logEpoch === room.log_epoch);
|
|
296
|
-
if (next?.fenced == null)
|
|
297
|
-
break;
|
|
298
|
-
const entries = await keptEntries(next.carry, next.parts).catch(() => null);
|
|
299
|
-
if (entries === null)
|
|
300
|
-
break;
|
|
301
|
-
chain.push({ carry: next, entries });
|
|
302
|
-
at = next.fenced.position;
|
|
303
|
-
}
|
|
304
|
-
const partial = [...kept.values()].find((carry) => carry.authority === room.authority &&
|
|
305
|
-
carry.fenced === null &&
|
|
306
|
-
carry.logEpoch === room.log_epoch &&
|
|
307
|
-
carry.after === at &&
|
|
308
|
-
carry.resume !== null &&
|
|
309
|
-
carry.resume.parts > 0);
|
|
310
|
-
const stale = [...kept.values()].filter((carry) => carry.authority === room.authority &&
|
|
311
|
-
carry !== partial &&
|
|
312
|
-
!chain.some((link) => link.carry === carry));
|
|
313
|
-
await forget(stale.map((carry) => carry.carry));
|
|
314
|
-
if (line !== undefined && line.logEpoch === room.log_epoch && chain.length > 0) {
|
|
315
|
-
const frames = chain.map(({ carry, entries }) => ({
|
|
316
|
-
after: BigInt(carry.after),
|
|
317
|
-
position: BigInt(carry.fenced.position),
|
|
318
|
-
entries,
|
|
319
|
-
}));
|
|
320
|
-
lines.set(room.authority, { ...line, frames: [...line.frames, ...frames] });
|
|
321
|
-
}
|
|
322
|
-
return {
|
|
323
|
-
...room,
|
|
324
|
-
position: at,
|
|
325
|
-
...(partial?.resume == null
|
|
326
|
-
? {}
|
|
327
|
-
: {
|
|
328
|
-
carry: {
|
|
329
|
-
id: partial.carry,
|
|
330
|
-
parts: partial.resume.parts,
|
|
331
|
-
from: partial.resume.from,
|
|
332
|
-
target: partial.resume.target,
|
|
333
|
-
handled: partial.resume.handled,
|
|
334
|
-
...(partial.resume.piece === null ? {} : { piece: partial.resume.piece }),
|
|
335
|
-
},
|
|
336
|
-
}),
|
|
337
|
-
};
|
|
196
|
+
publish(frame, held?.entries ?? []);
|
|
338
197
|
}
|
|
339
198
|
function handle(frame, via) {
|
|
340
199
|
if (frame.type === 'signal') {
|
|
@@ -348,10 +207,14 @@ export function houseNotifications(transport, mode) {
|
|
|
348
207
|
if (frame.type === 'opening') {
|
|
349
208
|
emit({
|
|
350
209
|
kind: 'opening',
|
|
351
|
-
expired: frame.expired.flatMap((authority) =>
|
|
210
|
+
expired: frame.expired.flatMap((authority) => (tracking.get(authority) ?? []).map((tracked) => tracked.locator)),
|
|
352
211
|
});
|
|
353
212
|
return;
|
|
354
213
|
}
|
|
214
|
+
if (frame.type === 'authority_changed') {
|
|
215
|
+
emit({ kind: 'authority-changed', scope: { authorities: frame.rooms } });
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
355
218
|
if (frame.type === 'conversations') {
|
|
356
219
|
emitConversation({ kind: 'list', entries: frame.conversations.map(listedConversation) });
|
|
357
220
|
return;
|
|
@@ -368,63 +231,43 @@ export function houseNotifications(transport, mode) {
|
|
|
368
231
|
frame.type === 'process' ||
|
|
369
232
|
frame.type === 'commands' ||
|
|
370
233
|
frame.type === 'options' ||
|
|
234
|
+
frame.type === 'starting' ||
|
|
235
|
+
frame.type === 'link' ||
|
|
236
|
+
frame.type === 'deliveries' ||
|
|
371
237
|
frame.type === 'interactions' ||
|
|
372
238
|
frame.type === 'message') {
|
|
373
239
|
converse(frame);
|
|
374
240
|
return;
|
|
375
241
|
}
|
|
376
242
|
if (frame.type === 'part')
|
|
377
|
-
|
|
378
|
-
if (frame.type === 'carried')
|
|
379
|
-
|
|
243
|
+
stage(frame, via);
|
|
244
|
+
else if (frame.type === 'carried')
|
|
245
|
+
carried(frame);
|
|
380
246
|
}
|
|
381
247
|
function publish(frame, entries) {
|
|
382
248
|
const at = position(frame.position);
|
|
383
249
|
const after = position(frame.after);
|
|
384
|
-
if (at === null || after === null || after >= at)
|
|
385
|
-
interrupt(frame.authority);
|
|
250
|
+
if (at === null || after === null || after >= at)
|
|
386
251
|
return;
|
|
387
|
-
}
|
|
388
|
-
const
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
const next = last !== undefined && after <= last.position ? [...line.frames, held] : [held];
|
|
397
|
-
lines.set(frame.authority, { ...line, frames: next.length > HELD_FRAMES_MAX ? [] : next });
|
|
398
|
-
}
|
|
399
|
-
else {
|
|
400
|
-
interrupt(frame.authority);
|
|
401
|
-
}
|
|
402
|
-
announce(frame.authority, { position: frame.position, logEpoch: frame.log_epoch });
|
|
403
|
-
}
|
|
404
|
-
stream.observe((frame) => {
|
|
405
|
-
const via = acknowledging;
|
|
406
|
-
if (verifying === 0) {
|
|
407
|
-
const handled = handle(frame, via);
|
|
408
|
-
if (handled === undefined)
|
|
409
|
-
return;
|
|
410
|
-
verifying += 1;
|
|
411
|
-
receiving = handled.finally(() => {
|
|
412
|
-
verifying -= 1;
|
|
252
|
+
const from = roomVersion({ position: frame.after, logEpoch: frame.log_epoch });
|
|
253
|
+
const version = roomVersion({ position: frame.position, logEpoch: frame.log_epoch });
|
|
254
|
+
for (const tracked of tracking.get(frame.authority) ?? []) {
|
|
255
|
+
emit({
|
|
256
|
+
kind: 'room-change',
|
|
257
|
+
locator: tracked.locator,
|
|
258
|
+
from,
|
|
259
|
+
roomVersion: version,
|
|
260
|
+
read: () => changePage(tracked, entries, version, mode),
|
|
413
261
|
});
|
|
414
|
-
return;
|
|
415
262
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
.then(() => handle(frame, via))
|
|
419
|
-
.finally(() => {
|
|
420
|
-
verifying -= 1;
|
|
421
|
-
});
|
|
422
|
-
});
|
|
263
|
+
}
|
|
264
|
+
stream.observe((frame) => handle(frame, socket));
|
|
423
265
|
stream.opened(reopened);
|
|
424
|
-
stream.closed((revoked) => {
|
|
266
|
+
stream.closed(({ revoked, lost }) => {
|
|
425
267
|
opening = null;
|
|
426
|
-
|
|
427
|
-
|
|
268
|
+
socket = null;
|
|
269
|
+
staged.clear();
|
|
270
|
+
emit({ kind: 'closed', revoked, lost });
|
|
428
271
|
});
|
|
429
272
|
return {
|
|
430
273
|
runtime,
|
|
@@ -446,13 +289,10 @@ export function houseNotifications(transport, mode) {
|
|
|
446
289
|
conversationObservers.delete(notify);
|
|
447
290
|
};
|
|
448
291
|
},
|
|
292
|
+
...(mode === 'credential' ? { agents: () => houseAgents(transport) } : {}),
|
|
449
293
|
},
|
|
450
|
-
observe(notify
|
|
294
|
+
observe(notify) {
|
|
451
295
|
observers.add(notify);
|
|
452
|
-
if (receipts === null) {
|
|
453
|
-
receipts = port;
|
|
454
|
-
loaded = load(port);
|
|
455
|
-
}
|
|
456
296
|
if (opening !== null) {
|
|
457
297
|
queueMicrotask(() => {
|
|
458
298
|
if (observers.has(notify))
|
|
@@ -463,40 +303,9 @@ export function houseNotifications(transport, mode) {
|
|
|
463
303
|
observers.delete(notify);
|
|
464
304
|
};
|
|
465
305
|
},
|
|
466
|
-
send(rooms
|
|
467
|
-
for (const room of rooms) {
|
|
468
|
-
const line = lines.get(room.authority);
|
|
469
|
-
const held = position(room.position);
|
|
470
|
-
if (line === undefined || held === null || line.logEpoch !== room.log_epoch)
|
|
471
|
-
continue;
|
|
472
|
-
lines.set(room.authority, { ...line, frames: [], held });
|
|
473
|
-
}
|
|
474
|
-
const current = opening;
|
|
306
|
+
send(rooms) {
|
|
475
307
|
opening = null;
|
|
476
|
-
|
|
477
|
-
return;
|
|
478
|
-
void loaded
|
|
479
|
-
.then(() => Promise.all(rooms.map(restored)))
|
|
480
|
-
.then((presented) => {
|
|
481
|
-
current.hold(presented, runtime, demand);
|
|
482
|
-
for (const [index, room] of presented.entries()) {
|
|
483
|
-
if (room.position === rooms[index].position)
|
|
484
|
-
continue;
|
|
485
|
-
announce(room.authority, { position: room.position, logEpoch: room.log_epoch });
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
},
|
|
489
|
-
published(locator, at) {
|
|
490
|
-
const authority = [...locators].find(([, held]) => held.includes(locator))?.[0];
|
|
491
|
-
const reached = position(at.position);
|
|
492
|
-
if (authority === undefined || reached === null)
|
|
493
|
-
return;
|
|
494
|
-
void forget([...kept.values()]
|
|
495
|
-
.filter((carry) => carry.authority === authority &&
|
|
496
|
-
carry.fenced !== null &&
|
|
497
|
-
carry.fenced.logEpoch === at.logEpoch &&
|
|
498
|
-
BigInt(carry.fenced.position) <= reached)
|
|
499
|
-
.map((carry) => carry.carry));
|
|
308
|
+
socket?.hold(rooms, runtime);
|
|
500
309
|
},
|
|
501
310
|
reopen() {
|
|
502
311
|
const current = opening;
|
|
@@ -504,111 +313,14 @@ export function houseNotifications(transport, mode) {
|
|
|
504
313
|
current?.close();
|
|
505
314
|
},
|
|
506
315
|
track(entries) {
|
|
507
|
-
|
|
316
|
+
tracking.clear();
|
|
508
317
|
for (const entry of entries) {
|
|
509
|
-
|
|
510
|
-
if (lines.get(entry.authority)?.logEpoch !== entry.logEpoch) {
|
|
511
|
-
lines.set(entry.authority, { logEpoch: entry.logEpoch, frames: [], held: null });
|
|
512
|
-
}
|
|
318
|
+
tracking.set(entry.authority, [...(tracking.get(entry.authority) ?? []), entry]);
|
|
513
319
|
}
|
|
514
|
-
for (const
|
|
515
|
-
if (!
|
|
516
|
-
|
|
320
|
+
for (const [carry, held] of staged) {
|
|
321
|
+
if (!tracking.has(held.authority))
|
|
322
|
+
staged.delete(carry);
|
|
517
323
|
}
|
|
518
|
-
void loaded.then(() => forget([...kept.values()]
|
|
519
|
-
.filter((carry) => !locators.has(carry.authority))
|
|
520
|
-
.map((carry) => carry.carry)));
|
|
521
|
-
},
|
|
522
|
-
reach(authority, at) {
|
|
523
|
-
const line = lines.get(authority);
|
|
524
|
-
const held = position(at.position);
|
|
525
|
-
if (line === undefined || held === null || line.logEpoch !== at.logEpoch)
|
|
526
|
-
return;
|
|
527
|
-
if (line.held !== null && held <= line.held)
|
|
528
|
-
return;
|
|
529
|
-
lines.set(authority, {
|
|
530
|
-
...line,
|
|
531
|
-
frames: line.frames.filter((frame) => frame.position > held),
|
|
532
|
-
held,
|
|
533
|
-
});
|
|
534
|
-
},
|
|
535
|
-
advance(tracked, from, holds) {
|
|
536
|
-
const line = lines.get(tracked.authority);
|
|
537
|
-
const start = position(from.position);
|
|
538
|
-
if (line === undefined || start === null || line.logEpoch !== from.logEpoch)
|
|
539
|
-
return null;
|
|
540
|
-
const pending = line.frames.filter((frame) => frame.position > start);
|
|
541
|
-
const first = pending[0];
|
|
542
|
-
if (first === undefined || first.after > start)
|
|
543
|
-
return null;
|
|
544
|
-
const documents = {};
|
|
545
|
-
const revisions = {};
|
|
546
|
-
const changes = {};
|
|
547
|
-
const binaryFiles = {};
|
|
548
|
-
const removals = [];
|
|
549
|
-
const applied = [];
|
|
550
|
-
const schemas = new Map();
|
|
551
|
-
const forget = (path) => {
|
|
552
|
-
delete documents[path];
|
|
553
|
-
delete revisions[path];
|
|
554
|
-
delete changes[path];
|
|
555
|
-
delete binaryFiles[path];
|
|
556
|
-
const removed = removals.indexOf(path);
|
|
557
|
-
if (removed !== -1)
|
|
558
|
-
removals.splice(removed, 1);
|
|
559
|
-
};
|
|
560
|
-
for (const frame of pending) {
|
|
561
|
-
for (const entry of frame.entries) {
|
|
562
|
-
if (entry.kind === 'edited' &&
|
|
563
|
-
entry.revision !== undefined &&
|
|
564
|
-
holds?.(entry.path, entry.revision) === true) {
|
|
565
|
-
forget(entry.path);
|
|
566
|
-
continue;
|
|
567
|
-
}
|
|
568
|
-
applied.push(entry);
|
|
569
|
-
if (tracked.schemas.includes(entry.path))
|
|
570
|
-
schemas.set(entry.path, entry);
|
|
571
|
-
if (entry.kind === 'removed') {
|
|
572
|
-
forget(entry.path);
|
|
573
|
-
removals.push(entry.path);
|
|
574
|
-
continue;
|
|
575
|
-
}
|
|
576
|
-
const binary = binaryFileOf(entry);
|
|
577
|
-
if (binary === null || (binary === undefined && entry.text === undefined))
|
|
578
|
-
return null;
|
|
579
|
-
if (mode === 'credential' && entry.revision === undefined)
|
|
580
|
-
return null;
|
|
581
|
-
const head = headChange(entry);
|
|
582
|
-
if (head === null)
|
|
583
|
-
return null;
|
|
584
|
-
forget(entry.path);
|
|
585
|
-
if (binary === undefined)
|
|
586
|
-
documents[entry.path] = entry.text;
|
|
587
|
-
else
|
|
588
|
-
binaryFiles[entry.path] = binary;
|
|
589
|
-
const revision = entry.revision ?? binary?.sha256;
|
|
590
|
-
if (revision !== undefined)
|
|
591
|
-
revisions[entry.path] = revision;
|
|
592
|
-
if (head !== undefined)
|
|
593
|
-
changes[entry.path] = head;
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
const last = pending.at(-1);
|
|
597
|
-
lines.set(tracked.authority, { ...line, frames: pending, held: last.position });
|
|
598
|
-
return {
|
|
599
|
-
page: {
|
|
600
|
-
kind: 'net-advancement',
|
|
601
|
-
roomVersion: roomVersion({ position: last.position.toString(), logEpoch: line.logEpoch }),
|
|
602
|
-
documents,
|
|
603
|
-
revisions,
|
|
604
|
-
...identities(revisions),
|
|
605
|
-
changes,
|
|
606
|
-
binaryFiles,
|
|
607
|
-
removals: removals.sort(),
|
|
608
|
-
},
|
|
609
|
-
entries: applied,
|
|
610
|
-
schemas,
|
|
611
|
-
};
|
|
612
324
|
},
|
|
613
325
|
};
|
|
614
326
|
}
|