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