@agentshouse/mdruntime-adapter 0.1.0-cfd03209dcd82 → 0.1.0-cfd2dc1938a2c
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 +6 -46
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +23 -342
- package/dist/adapter.d.ts +1 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +250 -278
- 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/authored-path.d.ts +11 -0
- package/dist/authored-path.d.ts.map +1 -0
- package/dist/authored-path.js +35 -0
- package/dist/chunks.d.ts +38 -0
- package/dist/chunks.d.ts.map +1 -0
- package/dist/chunks.js +247 -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 +23 -14
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +92 -54
- package/dist/history.d.ts +12 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +92 -0
- package/dist/house-model.d.ts +682 -0
- package/dist/house-model.d.ts.map +1 -0
- package/dist/house-model.js +397 -0
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/model.d.ts +5 -5
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +33 -43
- package/dist/read.d.ts +59 -44
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +158 -236
- package/dist/refusal.d.ts +1 -3
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +6 -6
- package/dist/room-types.d.ts +5 -0
- package/dist/room-types.d.ts.map +1 -0
- package/dist/room-types.js +120 -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 +1 -1
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +110 -131
- package/dist/space-schema.d.ts +7 -0
- package/dist/space-schema.d.ts.map +1 -0
- package/dist/space-schema.js +18 -0
- package/dist/stream.d.ts +15 -13
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +279 -159
- package/dist/transport.d.ts +81 -25
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +54 -11
- 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 -2
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +108 -76
- 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,47 +1,129 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { ROW_WEIGHT, stepped, } from '@agentshouse/mdruntime';
|
|
2
|
+
import { acceptedMessage, cursorPosition, houseHistory } from './history.js';
|
|
3
|
+
import { keptSpaceSchemas, streamedModels } from './model.js';
|
|
4
|
+
import { answered, answering, binaryFileOf, createdOf, folded, forgotten, headChange, revised, } from './read.js';
|
|
5
|
+
import { classifyDoor } from './refusal.js';
|
|
6
|
+
import { houseDoorRoute, } from './transport.js';
|
|
7
|
+
import { DECIMAL, logPosition, presented, roomVersion } from './version.js';
|
|
5
8
|
function turnOperation(frame) {
|
|
6
9
|
const { type: _type, conversation_id: _conversation, turn_id: _turn, ...operation } = frame;
|
|
7
10
|
return structuredClone(operation);
|
|
8
11
|
}
|
|
12
|
+
async function houseAgents(transport) {
|
|
13
|
+
const answer = await transport.door(houseDoorRoute('agents/list'), {});
|
|
14
|
+
if (classifyDoor(answer.status, answer.body, 'agents/list')?.kind === 'transport-uncertainty') {
|
|
15
|
+
throw new Error('agents/list reached no answer');
|
|
16
|
+
}
|
|
17
|
+
const agents = answer.status === 200 ? answer.body?.agents : null;
|
|
18
|
+
if (!Array.isArray(agents))
|
|
19
|
+
return null;
|
|
20
|
+
return agents.flatMap((one) => {
|
|
21
|
+
const { id, name, retired_at: retired } = (one ?? {});
|
|
22
|
+
return typeof id === 'string' && typeof name === 'string'
|
|
23
|
+
? [{ agent: id, name, retired: retired !== null && retired !== undefined }]
|
|
24
|
+
: [];
|
|
25
|
+
});
|
|
26
|
+
}
|
|
9
27
|
function listedConversation(listed) {
|
|
10
28
|
return {
|
|
11
29
|
conversation: listed.conversation_id,
|
|
12
30
|
agent: listed.agent_id,
|
|
31
|
+
agentName: listed.agent_name,
|
|
32
|
+
agentRetired: listed.agent_retired,
|
|
13
33
|
name: listed.name,
|
|
14
34
|
created: listed.created_at,
|
|
15
35
|
finished: listed.finished_at,
|
|
16
36
|
outcome: listed.outcome,
|
|
37
|
+
waiting: listed.waiting,
|
|
38
|
+
newest: listed.newest === null ? null : cursorPosition(listed.newest),
|
|
39
|
+
processEnded: listed.process_ended_at,
|
|
17
40
|
};
|
|
18
41
|
}
|
|
19
42
|
function position(value) {
|
|
20
|
-
if (
|
|
43
|
+
if (!DECIMAL.test(value))
|
|
21
44
|
return null;
|
|
22
45
|
return BigInt(value);
|
|
23
46
|
}
|
|
24
|
-
|
|
47
|
+
function* changed(tracked, entries, version, schemas) {
|
|
48
|
+
const answer = answering();
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
yield ROW_WEIGHT + (entry.text?.length ?? 0);
|
|
51
|
+
if (entry.kind === 'folder') {
|
|
52
|
+
folded(answer, entry.path, entry.removed === true);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (entry.path === tracked.schema)
|
|
56
|
+
schemas.set(entry.path, entry);
|
|
57
|
+
forgotten(answer, entry.path);
|
|
58
|
+
if (entry.space !== undefined) {
|
|
59
|
+
answer.removals.add(entry.path);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (entry.kind === 'removed') {
|
|
63
|
+
answer.removals.add(entry.path);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const binary = binaryFileOf(entry);
|
|
67
|
+
if (binary === undefined)
|
|
68
|
+
answer.documents.set(entry.path, entry.text ?? '');
|
|
69
|
+
else if (binary !== null)
|
|
70
|
+
answer.binaryFiles.set(entry.path, binary);
|
|
71
|
+
if (binary === undefined && entry.facts !== undefined)
|
|
72
|
+
answer.facts.set(entry.path, entry.facts);
|
|
73
|
+
const revision = entry.revision ?? binary?.sha256;
|
|
74
|
+
if (revision !== undefined)
|
|
75
|
+
revised(answer, entry.path, revision);
|
|
76
|
+
const head = headChange(entry);
|
|
77
|
+
if (head)
|
|
78
|
+
answer.changes.set(entry.path, head);
|
|
79
|
+
const created = createdOf(entry);
|
|
80
|
+
if (created)
|
|
81
|
+
answer.created.set(entry.path, created);
|
|
82
|
+
}
|
|
83
|
+
return { kind: 'net-advancement', roomVersion: version, ...(yield* answered(answer)) };
|
|
84
|
+
}
|
|
85
|
+
async function changePage(tracked, entries, version, mode, spaces, whole) {
|
|
86
|
+
const schemas = new Map();
|
|
87
|
+
const page = await stepped(changed(tracked, entries, version, schemas));
|
|
88
|
+
const models = await streamedModels(schemas, tracked, mode, spaces, whole);
|
|
89
|
+
return models === undefined ? page : { ...page, models };
|
|
90
|
+
}
|
|
91
|
+
export function houseNotifications(transport, mode, discovering, spaces) {
|
|
25
92
|
const stream = transport.stream;
|
|
26
|
-
const
|
|
27
|
-
|
|
93
|
+
const staged = new Map();
|
|
94
|
+
let socket = null;
|
|
95
|
+
const tracking = new Map();
|
|
28
96
|
const observers = new Set();
|
|
97
|
+
const replaying = new Map();
|
|
29
98
|
const conversationObservers = new Set();
|
|
30
99
|
const modeObservers = new Set();
|
|
31
100
|
let replicated = [];
|
|
101
|
+
let listedCursor = null;
|
|
102
|
+
const unanswered = [];
|
|
103
|
+
const heldAtZero = new Set();
|
|
32
104
|
const live = new Set();
|
|
33
105
|
let opening = null;
|
|
106
|
+
let announced = null;
|
|
34
107
|
const runtime = crypto.randomUUID();
|
|
35
108
|
function emit(event) {
|
|
36
|
-
for (const observer of observers)
|
|
37
|
-
observer
|
|
109
|
+
for (const observer of observers) {
|
|
110
|
+
const held = replaying.get(observer);
|
|
111
|
+
if (held === undefined)
|
|
112
|
+
observer(event);
|
|
113
|
+
else
|
|
114
|
+
held.push(event);
|
|
115
|
+
}
|
|
38
116
|
}
|
|
39
117
|
function emitConversation(event) {
|
|
40
118
|
if (event.kind === 'turn' ||
|
|
41
119
|
event.kind === 'questions' ||
|
|
42
120
|
event.kind === 'process' ||
|
|
43
121
|
event.kind === 'commands' ||
|
|
44
|
-
event.kind === 'options'
|
|
122
|
+
event.kind === 'options' ||
|
|
123
|
+
event.kind === 'starting' ||
|
|
124
|
+
event.kind === 'subagents' ||
|
|
125
|
+
event.kind === 'link' ||
|
|
126
|
+
event.kind === 'deliveries') {
|
|
45
127
|
live.add(event.conversation);
|
|
46
128
|
}
|
|
47
129
|
for (const observer of conversationObservers)
|
|
@@ -49,11 +131,33 @@ export function houseNotifications(transport, mode) {
|
|
|
49
131
|
}
|
|
50
132
|
function reopened(next) {
|
|
51
133
|
opening = next;
|
|
134
|
+
announced = null;
|
|
135
|
+
socket = next;
|
|
136
|
+
staged.clear();
|
|
137
|
+
unanswered.length = 0;
|
|
138
|
+
heldAtZero.clear();
|
|
52
139
|
const gapped = new Set([...replicated, ...live]);
|
|
53
140
|
live.clear();
|
|
54
141
|
for (const conversation of gapped)
|
|
55
142
|
emitConversation({ kind: 'gap', conversation });
|
|
56
143
|
emit({ kind: 'opened' });
|
|
144
|
+
if (mode === 'site')
|
|
145
|
+
announce(next, null);
|
|
146
|
+
}
|
|
147
|
+
function announce(via, frame) {
|
|
148
|
+
void discovering.opened(frame).then((discovery) => {
|
|
149
|
+
if (socket !== via)
|
|
150
|
+
return;
|
|
151
|
+
if (discovery === null) {
|
|
152
|
+
via.close();
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
announced = { kind: 'discovered', discovery };
|
|
156
|
+
emit(announced);
|
|
157
|
+
}, () => {
|
|
158
|
+
if (socket === via)
|
|
159
|
+
via.close();
|
|
160
|
+
});
|
|
57
161
|
}
|
|
58
162
|
function converse(frame) {
|
|
59
163
|
const conversation = frame.conversation_id;
|
|
@@ -72,6 +176,7 @@ export function houseNotifications(transport, mode) {
|
|
|
72
176
|
return;
|
|
73
177
|
emitConversation({ kind: 'commands', conversation, commands: [] });
|
|
74
178
|
emitConversation({ kind: 'options', conversation, options: [] });
|
|
179
|
+
emitConversation({ kind: 'subagents', conversation, subagents: [] });
|
|
75
180
|
return;
|
|
76
181
|
}
|
|
77
182
|
if (frame.type === 'commands') {
|
|
@@ -86,6 +191,26 @@ export function houseNotifications(transport, mode) {
|
|
|
86
191
|
emitConversation({ kind: 'options', conversation, options: structuredClone(frame.options) });
|
|
87
192
|
return;
|
|
88
193
|
}
|
|
194
|
+
if (frame.type === 'starting') {
|
|
195
|
+
emitConversation({ kind: 'starting', conversation, step: frame.step });
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (frame.type === 'subagents') {
|
|
199
|
+
emitConversation({
|
|
200
|
+
kind: 'subagents',
|
|
201
|
+
conversation,
|
|
202
|
+
subagents: structuredClone(frame.subagents),
|
|
203
|
+
});
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (frame.type === 'link') {
|
|
207
|
+
emitConversation({ kind: 'link', conversation, connected: frame.connected });
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (frame.type === 'deliveries') {
|
|
211
|
+
emitConversation({ kind: 'deliveries', conversation, unknown: [...frame.unknown] });
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
89
214
|
if (frame.type === 'interactions') {
|
|
90
215
|
emitConversation({
|
|
91
216
|
kind: 'questions',
|
|
@@ -99,18 +224,33 @@ export function houseNotifications(transport, mode) {
|
|
|
99
224
|
return;
|
|
100
225
|
emitConversation({ kind: 'accepted-message', conversation, message });
|
|
101
226
|
}
|
|
102
|
-
function
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
227
|
+
function stage(frame, via) {
|
|
228
|
+
const held = staged.get(frame.carry);
|
|
229
|
+
if (frame.index !== (held?.parts ?? 0)) {
|
|
230
|
+
staged.delete(frame.carry);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (held === undefined) {
|
|
234
|
+
for (const [carry, other] of staged) {
|
|
235
|
+
if (other.authority === frame.authority)
|
|
236
|
+
staged.delete(carry);
|
|
237
|
+
}
|
|
106
238
|
}
|
|
239
|
+
const next = held ?? { authority: frame.authority, parts: 0, entries: [] };
|
|
240
|
+
keptSpaceSchemas(frame.entries, spaces);
|
|
241
|
+
next.entries.push(...frame.entries);
|
|
242
|
+
next.parts += 1;
|
|
243
|
+
staged.set(frame.carry, next);
|
|
244
|
+
via?.received(frame.authority, frame.carry, frame.index);
|
|
107
245
|
}
|
|
108
|
-
function
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
246
|
+
function carried(frame) {
|
|
247
|
+
const held = staged.get(frame.carry);
|
|
248
|
+
staged.delete(frame.carry);
|
|
249
|
+
if ((held?.parts ?? 0) !== frame.parts)
|
|
250
|
+
return;
|
|
251
|
+
publish(frame, held?.entries ?? []);
|
|
112
252
|
}
|
|
113
|
-
function
|
|
253
|
+
function handle(frame, via) {
|
|
114
254
|
if (frame.type === 'signal') {
|
|
115
255
|
const mode = frame.service_mode;
|
|
116
256
|
if (mode !== 'open' && mode !== 'write-halted')
|
|
@@ -120,14 +260,35 @@ export function houseNotifications(transport, mode) {
|
|
|
120
260
|
return;
|
|
121
261
|
}
|
|
122
262
|
if (frame.type === 'opening') {
|
|
263
|
+
if (via !== null && mode === 'credential')
|
|
264
|
+
announce(via, frame);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (frame.type === 'caught_up') {
|
|
268
|
+
discovering.expired?.(frame.expired);
|
|
123
269
|
emit({
|
|
124
|
-
kind: '
|
|
125
|
-
expired:
|
|
270
|
+
kind: 'caught-up',
|
|
271
|
+
expired: [
|
|
272
|
+
...frame.expired.flatMap((authority) => (tracking.get(authority) ?? []).map((tracked) => tracked.locator)),
|
|
273
|
+
...(unanswered.shift() ?? []),
|
|
274
|
+
],
|
|
126
275
|
});
|
|
127
276
|
return;
|
|
128
277
|
}
|
|
278
|
+
if (frame.type === 'authority_changed') {
|
|
279
|
+
const change = discovering.changed(frame);
|
|
280
|
+
if (change !== null)
|
|
281
|
+
emit(change);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
129
284
|
if (frame.type === 'conversations') {
|
|
130
|
-
emitConversation({
|
|
285
|
+
emitConversation({
|
|
286
|
+
kind: 'list',
|
|
287
|
+
entries: frame.conversations.map(listedConversation),
|
|
288
|
+
whole: frame.whole,
|
|
289
|
+
more: frame.more,
|
|
290
|
+
cursor: frame.cursor,
|
|
291
|
+
});
|
|
131
292
|
return;
|
|
132
293
|
}
|
|
133
294
|
if (frame.type === 'conversation') {
|
|
@@ -142,40 +303,49 @@ export function houseNotifications(transport, mode) {
|
|
|
142
303
|
frame.type === 'process' ||
|
|
143
304
|
frame.type === 'commands' ||
|
|
144
305
|
frame.type === 'options' ||
|
|
306
|
+
frame.type === 'starting' ||
|
|
307
|
+
frame.type === 'subagents' ||
|
|
308
|
+
frame.type === 'link' ||
|
|
309
|
+
frame.type === 'deliveries' ||
|
|
145
310
|
frame.type === 'interactions' ||
|
|
146
311
|
frame.type === 'message') {
|
|
147
312
|
converse(frame);
|
|
148
313
|
return;
|
|
149
314
|
}
|
|
150
|
-
if (frame.type
|
|
151
|
-
|
|
315
|
+
if (frame.type === 'part')
|
|
316
|
+
stage(frame, via);
|
|
317
|
+
else if (frame.type === 'carried')
|
|
318
|
+
carried(frame);
|
|
319
|
+
}
|
|
320
|
+
function publish(frame, entries) {
|
|
152
321
|
const at = position(frame.position);
|
|
153
322
|
const after = position(frame.after);
|
|
154
|
-
if (at === null || after === null || after >= at)
|
|
155
|
-
interrupt(frame.authority);
|
|
323
|
+
if (at === null || after === null || after >= at)
|
|
156
324
|
return;
|
|
325
|
+
const from = after === 0n && !heldAtZero.has(frame.authority)
|
|
326
|
+
? null
|
|
327
|
+
: roomVersion({ position: frame.after, logEpoch: frame.log_epoch });
|
|
328
|
+
const version = roomVersion({ position: frame.position, logEpoch: frame.log_epoch });
|
|
329
|
+
for (const tracked of tracking.get(frame.authority) ?? []) {
|
|
330
|
+
emit({
|
|
331
|
+
kind: 'room-change',
|
|
332
|
+
locator: tracked.locator,
|
|
333
|
+
from,
|
|
334
|
+
roomVersion: version,
|
|
335
|
+
read: () => changePage(tracked, entries, version, mode, spaces, from === null),
|
|
336
|
+
});
|
|
157
337
|
}
|
|
158
|
-
const line = lines.get(frame.authority);
|
|
159
|
-
if (line?.logEpoch === frame.log_epoch) {
|
|
160
|
-
if (line.held !== null && at <= line.held)
|
|
161
|
-
return;
|
|
162
|
-
const last = line.frames.at(-1);
|
|
163
|
-
if (last !== undefined && at <= last.position)
|
|
164
|
-
return;
|
|
165
|
-
const held = { after, position: at, entries: frame.entries };
|
|
166
|
-
const next = last !== undefined && after <= last.position ? [...line.frames, held] : [held];
|
|
167
|
-
lines.set(frame.authority, { ...line, frames: next.length > HELD_FRAMES_MAX ? [] : next });
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
interrupt(frame.authority);
|
|
171
|
-
}
|
|
172
|
-
announce(frame.authority, { position: frame.position, logEpoch: frame.log_epoch });
|
|
173
338
|
}
|
|
174
|
-
stream.observe(
|
|
339
|
+
stream.observe((frame) => handle(frame, socket));
|
|
175
340
|
stream.opened(reopened);
|
|
176
|
-
stream.closed((revoked) => {
|
|
341
|
+
stream.closed(({ revoked, lost, authorityChanged }) => {
|
|
177
342
|
opening = null;
|
|
178
|
-
|
|
343
|
+
announced = null;
|
|
344
|
+
socket = null;
|
|
345
|
+
staged.clear();
|
|
346
|
+
unanswered.length = 0;
|
|
347
|
+
heldAtZero.clear();
|
|
348
|
+
emit({ kind: 'closed', revoked, lost, authorityChanged });
|
|
179
349
|
});
|
|
180
350
|
return {
|
|
181
351
|
runtime,
|
|
@@ -191,19 +361,34 @@ export function houseNotifications(transport, mode) {
|
|
|
191
361
|
replicate(next) {
|
|
192
362
|
replicated = [...next];
|
|
193
363
|
},
|
|
364
|
+
hold(cursor) {
|
|
365
|
+
listedCursor = cursor;
|
|
366
|
+
},
|
|
194
367
|
observe(notify) {
|
|
195
368
|
conversationObservers.add(notify);
|
|
196
369
|
return () => {
|
|
197
370
|
conversationObservers.delete(notify);
|
|
198
371
|
};
|
|
199
372
|
},
|
|
373
|
+
...(mode === 'credential'
|
|
374
|
+
? {
|
|
375
|
+
agents: () => houseAgents(transport),
|
|
376
|
+
history: (request) => houseHistory(transport, request),
|
|
377
|
+
}
|
|
378
|
+
: {}),
|
|
200
379
|
},
|
|
201
380
|
observe(notify) {
|
|
202
381
|
observers.add(notify);
|
|
203
382
|
if (opening !== null) {
|
|
383
|
+
const replayed = [{ kind: 'opened' }];
|
|
384
|
+
if (announced !== null)
|
|
385
|
+
replayed.push(announced);
|
|
386
|
+
replaying.set(notify, replayed);
|
|
204
387
|
queueMicrotask(() => {
|
|
205
|
-
|
|
206
|
-
|
|
388
|
+
replaying.delete(notify);
|
|
389
|
+
for (const event of replayed)
|
|
390
|
+
if (observers.has(notify))
|
|
391
|
+
notify(event);
|
|
207
392
|
});
|
|
208
393
|
}
|
|
209
394
|
return () => {
|
|
@@ -211,124 +396,59 @@ export function houseNotifications(transport, mode) {
|
|
|
211
396
|
};
|
|
212
397
|
},
|
|
213
398
|
send(rooms) {
|
|
214
|
-
for (const room of rooms) {
|
|
215
|
-
const line = lines.get(room.authority);
|
|
216
|
-
const held = position(room.position);
|
|
217
|
-
if (line === undefined || held === null || line.logEpoch !== room.log_epoch)
|
|
218
|
-
continue;
|
|
219
|
-
lines.set(room.authority, { ...line, frames: [], held });
|
|
220
|
-
}
|
|
221
|
-
const current = opening;
|
|
222
|
-
opening = null;
|
|
223
|
-
current?.hold(rooms, runtime);
|
|
224
|
-
},
|
|
225
|
-
reopen() {
|
|
226
|
-
const current = opening;
|
|
227
399
|
opening = null;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
track(entries) {
|
|
231
|
-
locators.clear();
|
|
232
|
-
for (const entry of entries) {
|
|
233
|
-
locators.set(entry.authority, [...(locators.get(entry.authority) ?? []), entry.locator]);
|
|
234
|
-
if (lines.get(entry.authority)?.logEpoch !== entry.logEpoch) {
|
|
235
|
-
lines.set(entry.authority, { logEpoch: entry.logEpoch, frames: [], held: null });
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
for (const authority of lines.keys()) {
|
|
239
|
-
if (!locators.has(authority))
|
|
240
|
-
lines.delete(authority);
|
|
241
|
-
}
|
|
242
|
-
},
|
|
243
|
-
reach(authority, at) {
|
|
244
|
-
const line = lines.get(authority);
|
|
245
|
-
const held = position(at.position);
|
|
246
|
-
if (line === undefined || held === null || line.logEpoch !== at.logEpoch)
|
|
400
|
+
announced = null;
|
|
401
|
+
if (socket === null)
|
|
247
402
|
return;
|
|
248
|
-
|
|
403
|
+
const entries = new Map([...tracking.values()].flat().map((tracked) => [tracked.locator, tracked]));
|
|
404
|
+
const named = rooms.flatMap((room) => {
|
|
405
|
+
const entry = entries.get(room.locator);
|
|
406
|
+
const at = room.roomVersion === null ? null : logPosition(room.roomVersion);
|
|
407
|
+
return entry === undefined || at === null ? [] : [{ entry, at }];
|
|
408
|
+
});
|
|
409
|
+
const unheld = rooms.flatMap((room) => {
|
|
410
|
+
const entry = entries.get(room.locator);
|
|
411
|
+
return entry === undefined || room.roomVersion !== null ? [] : [entry];
|
|
412
|
+
});
|
|
413
|
+
for (const { entry, at } of named) {
|
|
414
|
+
if (at.position === '0')
|
|
415
|
+
heldAtZero.add(entry.authority);
|
|
416
|
+
else
|
|
417
|
+
heldAtZero.delete(entry.authority);
|
|
418
|
+
}
|
|
419
|
+
for (const entry of unheld)
|
|
420
|
+
heldAtZero.delete(entry.authority);
|
|
421
|
+
const site = mode === 'site';
|
|
422
|
+
unanswered.push(site ? unheld.map((entry) => entry.locator) : []);
|
|
423
|
+
socket.hold([
|
|
424
|
+
...named.map(({ entry, at }) => presented(entry.authority, at)),
|
|
425
|
+
...(site ? [] : unheld).map((entry) => presented(entry.authority, { position: '0', logEpoch: entry.logEpoch })),
|
|
426
|
+
], runtime, listedCursor);
|
|
427
|
+
if (site)
|
|
249
428
|
return;
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
429
|
+
const made = unheld.filter((entry) => entry.position === '0');
|
|
430
|
+
queueMicrotask(() => {
|
|
431
|
+
for (const entry of made) {
|
|
432
|
+
const version = roomVersion(entry);
|
|
433
|
+
emit({
|
|
434
|
+
kind: 'room-change',
|
|
435
|
+
locator: entry.locator,
|
|
436
|
+
from: null,
|
|
437
|
+
roomVersion: version,
|
|
438
|
+
read: () => changePage(entry, [], version, mode, spaces, true),
|
|
439
|
+
});
|
|
440
|
+
}
|
|
254
441
|
});
|
|
255
442
|
},
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return null;
|
|
265
|
-
const documents = {};
|
|
266
|
-
const revisions = {};
|
|
267
|
-
const changes = {};
|
|
268
|
-
const binaryFiles = {};
|
|
269
|
-
const removals = [];
|
|
270
|
-
const applied = [];
|
|
271
|
-
const schemas = new Map();
|
|
272
|
-
const forget = (path) => {
|
|
273
|
-
delete documents[path];
|
|
274
|
-
delete revisions[path];
|
|
275
|
-
delete changes[path];
|
|
276
|
-
delete binaryFiles[path];
|
|
277
|
-
const removed = removals.indexOf(path);
|
|
278
|
-
if (removed !== -1)
|
|
279
|
-
removals.splice(removed, 1);
|
|
280
|
-
};
|
|
281
|
-
for (const frame of pending) {
|
|
282
|
-
for (const entry of frame.entries) {
|
|
283
|
-
if (entry.kind === 'edited' &&
|
|
284
|
-
entry.revision !== undefined &&
|
|
285
|
-
holds?.(entry.path, entry.revision) === true) {
|
|
286
|
-
forget(entry.path);
|
|
287
|
-
continue;
|
|
288
|
-
}
|
|
289
|
-
applied.push(entry);
|
|
290
|
-
if (tracked.schemas.includes(entry.path))
|
|
291
|
-
schemas.set(entry.path, entry);
|
|
292
|
-
if (entry.kind === 'removed') {
|
|
293
|
-
forget(entry.path);
|
|
294
|
-
removals.push(entry.path);
|
|
295
|
-
continue;
|
|
296
|
-
}
|
|
297
|
-
const binary = binaryFileOf(entry);
|
|
298
|
-
if (binary === null || (binary === undefined && entry.text === undefined))
|
|
299
|
-
return null;
|
|
300
|
-
if (mode === 'credential' && entry.revision === undefined)
|
|
301
|
-
return null;
|
|
302
|
-
const head = headChange(entry);
|
|
303
|
-
if (head === null)
|
|
304
|
-
return null;
|
|
305
|
-
forget(entry.path);
|
|
306
|
-
if (binary === undefined)
|
|
307
|
-
documents[entry.path] = entry.text;
|
|
308
|
-
else
|
|
309
|
-
binaryFiles[entry.path] = binary;
|
|
310
|
-
const revision = entry.revision ?? binary?.sha256;
|
|
311
|
-
if (revision !== undefined)
|
|
312
|
-
revisions[entry.path] = revision;
|
|
313
|
-
if (head !== undefined)
|
|
314
|
-
changes[entry.path] = head;
|
|
315
|
-
}
|
|
443
|
+
track(entries) {
|
|
444
|
+
tracking.clear();
|
|
445
|
+
for (const entry of entries) {
|
|
446
|
+
tracking.set(entry.authority, [...(tracking.get(entry.authority) ?? []), entry]);
|
|
447
|
+
}
|
|
448
|
+
for (const [carry, held] of staged) {
|
|
449
|
+
if (!tracking.has(held.authority))
|
|
450
|
+
staged.delete(carry);
|
|
316
451
|
}
|
|
317
|
-
const last = pending.at(-1);
|
|
318
|
-
lines.set(tracked.authority, { ...line, frames: pending, held: last.position });
|
|
319
|
-
return {
|
|
320
|
-
page: {
|
|
321
|
-
kind: 'net-advancement',
|
|
322
|
-
roomVersion: roomVersion({ position: last.position.toString(), logEpoch: line.logEpoch }),
|
|
323
|
-
documents,
|
|
324
|
-
revisions,
|
|
325
|
-
changes,
|
|
326
|
-
binaryFiles,
|
|
327
|
-
removals: removals.sort(),
|
|
328
|
-
},
|
|
329
|
-
entries: applied,
|
|
330
|
-
schemas,
|
|
331
|
-
};
|
|
332
452
|
},
|
|
333
453
|
};
|
|
334
454
|
}
|