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