@agentshouse/mdruntime-adapter 0.1.0-cd59fd8945dcb → 0.1.0-cd61dfca5d699
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/AGENTS.md +271 -262
- package/dist/actions.d.ts +23 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +68 -31
- package/dist/adapter.d.ts +1 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +261 -64
- package/dist/discovery.d.ts +2 -1
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +10 -6
- package/dist/handed.d.ts +15 -0
- package/dist/handed.d.ts.map +1 -0
- package/dist/handed.js +38 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/model.d.ts +0 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +0 -3
- package/dist/read.d.ts +29 -6
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +150 -52
- package/dist/referrer.d.ts +7 -0
- package/dist/referrer.d.ts.map +1 -0
- package/dist/referrer.js +35 -0
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +2 -1
- package/dist/site.d.ts +1 -1
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +174 -47
- package/dist/stream.d.ts +3 -2
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +326 -16
- package/dist/transport.d.ts +63 -6
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +3 -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 +2 -9
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +61 -8
- package/package.json +2 -3
- package/dist/links.d.ts +0 -20
- package/dist/links.d.ts.map +0 -1
- package/dist/links.js +0 -104
package/dist/adapter.js
CHANGED
|
@@ -2,22 +2,51 @@ import { DISCOVER_PREFIXES, capabilities, discoveredRoom, mapDiscovery, parseDis
|
|
|
2
2
|
import { partModels, streamedModels, viewModels } from './model.js';
|
|
3
3
|
import { gathered, gatheredEach, selections } from './gather.js';
|
|
4
4
|
import { createSiteAdapter } from './site.js';
|
|
5
|
-
import { bootstrapOf, contentPrefixes, matchesScope, parseEnumeration, parseEnvelope, parseGrant, refreshFrom, viewOf, } from './read.js';
|
|
6
|
-
import {
|
|
5
|
+
import { bootstrapOf, contentPrefixes, matchesScope, parseEnumeration, parseEnvelope, parseGrant, refreshFrom, viewOf, wholeView, } from './read.js';
|
|
6
|
+
import { sha256Hex } from './digest.js';
|
|
7
|
+
import { acceptedHanded, enumeratedHanded, heldHanded, scopeHanded, streamedHanded, } from './handed.js';
|
|
7
8
|
import { houseAction } from './actions.js';
|
|
8
9
|
import { classifyDoor, classifyRead, discoveryFailure, doorRefusal } from './refusal.js';
|
|
9
10
|
import { houseNotifications } from './stream.js';
|
|
10
|
-
import { DOOR_BATCH, DOOR_BATCH_UPLOAD, DOOR_BOOTSTRAP, DOOR_DISCOVER, DOOR_ENUMERATE, DOOR_REVISIONS, } from './transport.js';
|
|
11
|
+
import { DOOR_BATCH, DOOR_BATCH_UPLOAD, DOOR_BOOTSTRAP, DOOR_DISCOVER, DOOR_ENUMERATE, DOOR_FILES_GET, DOOR_REVISIONS, } from './transport.js';
|
|
11
12
|
import { batchPaths, deltaBody, deltaBytes, deltaDigest, historyOutcome, houseChanges, mutationOutcome, operationHead, rejectedMapping, revisionBody, uploadable, } from './write.js';
|
|
13
|
+
import { houseReferrer } from './referrer.js';
|
|
12
14
|
import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
|
|
13
15
|
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
14
16
|
const UNCERTAIN_READ = { kind: 'transport-uncertainty' };
|
|
15
17
|
function lapsedGrant(outcome) {
|
|
16
18
|
return outcome.kind === 'rejected' && outcome.code === 'upload_unavailable';
|
|
17
19
|
}
|
|
20
|
+
function heldFiles(authority, held, after, budget) {
|
|
21
|
+
if (held === undefined || budget === 0)
|
|
22
|
+
return null;
|
|
23
|
+
const paths = Object.keys(held.revisions)
|
|
24
|
+
.filter((path) => held.documents[path] !== undefined && (after === null || path > after))
|
|
25
|
+
.sort();
|
|
26
|
+
if (paths.length === 0)
|
|
27
|
+
return null;
|
|
28
|
+
const files = paths.slice(0, budget).map((path) => ({ path, revision: held.revisions[path] }));
|
|
29
|
+
return { room: authority, through: paths.length > budget ? files.at(-1).path : null, files };
|
|
30
|
+
}
|
|
31
|
+
async function reused(scope, held) {
|
|
32
|
+
const sent = new Set(scope.contents.map((entry) => entry.path));
|
|
33
|
+
const contents = [...scope.contents];
|
|
34
|
+
for (const file of scope.files) {
|
|
35
|
+
if (file.binary !== undefined || sent.has(file.path))
|
|
36
|
+
continue;
|
|
37
|
+
const content = held?.documents[file.path];
|
|
38
|
+
if (content === undefined ||
|
|
39
|
+
held?.revisions[file.path] !== file.revision ||
|
|
40
|
+
(await sha256Hex(content)) !== file.sha256) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
contents.push({ path: file.path, content });
|
|
44
|
+
}
|
|
45
|
+
return { ...scope, contents };
|
|
46
|
+
}
|
|
18
47
|
export function createAgentsHouseAdapter(options) {
|
|
19
48
|
if ('site' in options)
|
|
20
|
-
return createSiteAdapter(options.site);
|
|
49
|
+
return createSiteAdapter(options.site, options.snapshot === true);
|
|
21
50
|
const transport = options.transport;
|
|
22
51
|
const notifications = houseNotifications(transport, 'credential');
|
|
23
52
|
const tracked = new Map();
|
|
@@ -28,12 +57,22 @@ export function createAgentsHouseAdapter(options) {
|
|
|
28
57
|
throw new Error('no Discovery declared the bounds');
|
|
29
58
|
return bounds;
|
|
30
59
|
}
|
|
31
|
-
async function bootstrappedRoom(envelope,
|
|
32
|
-
|
|
60
|
+
async function bootstrappedRoom(envelope, sent, asked, continued) {
|
|
61
|
+
const { entry } = asked;
|
|
62
|
+
if (sent === undefined)
|
|
33
63
|
return { kind: 'room-not-readable', locator: entry.locator };
|
|
34
|
-
const
|
|
64
|
+
const scope = await reused(sent, asked.held);
|
|
65
|
+
if (scope === null) {
|
|
66
|
+
return asked.held === undefined
|
|
67
|
+
? UNCERTAIN_READ
|
|
68
|
+
: continued === null
|
|
69
|
+
? bootstrapTogether({ entry, held: undefined })
|
|
70
|
+
: continuedBootstrap({ entry, held: undefined }, continued);
|
|
71
|
+
}
|
|
72
|
+
const cursor = envelope.next?.room === entry.authority ? envelope.next : undefined;
|
|
73
|
+
const next = cursor?.path ?? null;
|
|
35
74
|
if (continued === null && next === null)
|
|
36
|
-
handed.set(entry.locator,
|
|
75
|
+
handed.set(entry.locator, scopeHanded(scope));
|
|
37
76
|
else
|
|
38
77
|
handed.delete(entry.locator);
|
|
39
78
|
notifications.reach(entry.authority, scope);
|
|
@@ -42,36 +81,56 @@ export function createAgentsHouseAdapter(options) {
|
|
|
42
81
|
...entry.schemas.filter((schema) => scope.files.some((file) => file.path === schema)),
|
|
43
82
|
];
|
|
44
83
|
const models = await partModels(scope, entry, new Set(seen), next === null);
|
|
45
|
-
const continuation = next === null
|
|
84
|
+
const continuation = next === null
|
|
85
|
+
? null
|
|
86
|
+
: { after: next, seen, ...(cursor?.cut === undefined ? {} : { cut: cursor.cut }) };
|
|
46
87
|
return {
|
|
47
88
|
...bootstrapOf(scope),
|
|
48
89
|
...(models === undefined ? {} : { models }),
|
|
49
90
|
...(continuation === null ? {} : { pageToken: JSON.stringify(continuation) }),
|
|
50
91
|
};
|
|
51
92
|
}
|
|
93
|
+
async function enumeratedPage(ask, page) {
|
|
94
|
+
const answer = await transport.door(DOOR_ENUMERATE, {
|
|
95
|
+
prefixes: contentPrefixes(ask.entry),
|
|
96
|
+
positions: [
|
|
97
|
+
{
|
|
98
|
+
...presented(ask.entry.authority, { position: page.after, logEpoch: ask.from.logEpoch }),
|
|
99
|
+
page: { through: page.through, read: page.read },
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
const failure = classifyRead(answer.status, answer.body, ask.entry.locator);
|
|
104
|
+
if (failure !== null)
|
|
105
|
+
return failure;
|
|
106
|
+
const enumeration = parseEnumeration(answer.body, 'credential');
|
|
107
|
+
if (enumeration === null)
|
|
108
|
+
return UNCERTAIN_READ;
|
|
109
|
+
return (viewOf(enumeration, ask.entry) ?? { kind: 'room-not-readable', locator: ask.entry.locator });
|
|
110
|
+
}
|
|
52
111
|
async function enumeratedRoom(enumeration, ask) {
|
|
53
|
-
const
|
|
54
|
-
if (
|
|
112
|
+
const first = viewOf(enumeration, ask.entry);
|
|
113
|
+
if (first === undefined)
|
|
55
114
|
return { kind: 'room-not-readable', locator: ask.entry.locator };
|
|
115
|
+
const view = await wholeView(first, (page) => enumeratedPage(ask, page));
|
|
116
|
+
if ('kind' in view)
|
|
117
|
+
return view;
|
|
56
118
|
notifications.reach(ask.entry.authority, view);
|
|
57
119
|
const answer = refreshFrom(view, ask.fromRoomVersion);
|
|
58
120
|
if (answer.kind !== 'net-advancement')
|
|
59
121
|
return answer;
|
|
60
|
-
handed.set(ask.entry.locator,
|
|
122
|
+
handed.set(ask.entry.locator, enumeratedHanded(view, handed.get(ask.entry.locator)));
|
|
61
123
|
const models = await viewModels(view, ask.entry);
|
|
62
124
|
return models === undefined ? answer : { ...answer, models };
|
|
63
125
|
}
|
|
64
126
|
async function streamed(entry, request, from) {
|
|
65
|
-
const
|
|
66
|
-
if (
|
|
127
|
+
const held = handed.get(entry.locator);
|
|
128
|
+
if (held?.roomVersion !== request.fromRoomVersion)
|
|
67
129
|
return null;
|
|
68
|
-
const advanced = notifications.advance(entry, from, (path, revision) =>
|
|
130
|
+
const advanced = notifications.advance(entry, from, (path, revision) => held.revisions.get(path) === revision);
|
|
69
131
|
if (advanced === null)
|
|
70
132
|
return null;
|
|
71
|
-
|
|
72
|
-
if (relinked === null)
|
|
73
|
-
return null;
|
|
74
|
-
handed.set(entry.locator, relinked);
|
|
133
|
+
handed.set(entry.locator, streamedHanded(held, advanced));
|
|
75
134
|
const models = await streamedModels(advanced.schemas, entry, 'credential');
|
|
76
135
|
return models === undefined ? advanced.page : { ...advanced.page, models };
|
|
77
136
|
}
|
|
@@ -81,7 +140,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
81
140
|
const at = logPosition(room.roomVersion);
|
|
82
141
|
if (entry === undefined || at === null)
|
|
83
142
|
return [];
|
|
84
|
-
handed.set(room.locator,
|
|
143
|
+
handed.set(room.locator, heldHanded(room));
|
|
85
144
|
notifications.reach(entry.authority, at);
|
|
86
145
|
return [presented(entry.authority, at)];
|
|
87
146
|
});
|
|
@@ -90,19 +149,15 @@ export function createAgentsHouseAdapter(options) {
|
|
|
90
149
|
function adopted(entry, outcome) {
|
|
91
150
|
if (outcome.kind !== 'accepted')
|
|
92
151
|
return outcome;
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
handed.set(entry.locator, relinked.links);
|
|
100
|
-
const at = logPosition(accepted.roomVersion);
|
|
152
|
+
const held = handed.get(entry.locator);
|
|
153
|
+
if (held === undefined)
|
|
154
|
+
return outcome;
|
|
155
|
+
const follows = followsVersion(held.roomVersion, outcome.roomVersion);
|
|
156
|
+
handed.set(entry.locator, acceptedHanded(held, outcome, follows ? outcome.roomVersion : held.roomVersion));
|
|
157
|
+
const at = logPosition(outcome.roomVersion);
|
|
101
158
|
if (follows && at !== null)
|
|
102
159
|
notifications.reach(entry.authority, at);
|
|
103
|
-
return
|
|
104
|
-
? accepted
|
|
105
|
-
: { ...accepted, attachments: relinked.attachments };
|
|
160
|
+
return outcome;
|
|
106
161
|
}
|
|
107
162
|
function authorityFor(locator) {
|
|
108
163
|
return tracked.get(locator);
|
|
@@ -124,13 +179,19 @@ export function createAgentsHouseAdapter(options) {
|
|
|
124
179
|
function weight(entry) {
|
|
125
180
|
return contentPrefixes(entry).length;
|
|
126
181
|
}
|
|
127
|
-
|
|
128
|
-
|
|
182
|
+
function holding(asks, after) {
|
|
183
|
+
const budget = Math.floor(declared().max_held_files / Math.max(1, asks.filter((ask) => ask.held !== undefined).length));
|
|
184
|
+
return asks.flatMap((ask) => heldFiles(ask.entry.authority, ask.held, after, budget) ?? []);
|
|
185
|
+
}
|
|
186
|
+
async function bootstrapped(asks, answer) {
|
|
187
|
+
let open = asks.map((asked, ask) => ({ entry: asked.entry, asked, ask }));
|
|
129
188
|
while (open.length > 0) {
|
|
130
189
|
const unreached = [];
|
|
131
190
|
for (const part of selections(open, ({ entry }) => weight(entry), declared().max_prefixes)) {
|
|
191
|
+
const held = holding(part.map(({ asked }) => asked), null);
|
|
132
192
|
const answered = await transport.door(DOOR_BOOTSTRAP, {
|
|
133
193
|
prefixes: part.flatMap(({ entry }) => contentPrefixes(entry)),
|
|
194
|
+
...(held.length === 0 ? {} : { held }),
|
|
134
195
|
});
|
|
135
196
|
const classified = part.map(({ entry }) => classifyDoor(answered.status, answered.body, entry.locator));
|
|
136
197
|
const envelope = classified[0] === null ? parseEnvelope(answered.body) : null;
|
|
@@ -149,71 +210,79 @@ export function createAgentsHouseAdapter(options) {
|
|
|
149
210
|
unreached.push(asked);
|
|
150
211
|
continue;
|
|
151
212
|
}
|
|
152
|
-
answer(asked.ask, await bootstrappedRoom(envelope, scope, asked.
|
|
213
|
+
answer(asked.ask, await bootstrappedRoom(envelope, scope, asked.asked, null));
|
|
153
214
|
}
|
|
154
215
|
}
|
|
155
216
|
open = unreached;
|
|
156
217
|
}
|
|
157
218
|
}
|
|
158
|
-
async function continuedBootstrap(
|
|
159
|
-
const
|
|
219
|
+
async function continuedBootstrap(asked, continued) {
|
|
220
|
+
const { entry } = asked;
|
|
221
|
+
const after = {
|
|
222
|
+
room: entry.authority,
|
|
223
|
+
path: continued.after,
|
|
224
|
+
...(continued.cut === undefined ? {} : { cut: continued.cut }),
|
|
225
|
+
};
|
|
226
|
+
const held = holding([asked], continued.after);
|
|
160
227
|
const answered = await transport.door(DOOR_BOOTSTRAP, {
|
|
161
228
|
prefixes: contentPrefixes(entry),
|
|
162
229
|
after,
|
|
230
|
+
...(held.length === 0 ? {} : { held }),
|
|
163
231
|
});
|
|
164
|
-
const failure =
|
|
232
|
+
const failure = classifyRead(answered.status, answered.body, entry.locator);
|
|
165
233
|
if (failure !== null)
|
|
166
234
|
return failure;
|
|
167
235
|
const envelope = parseEnvelope(answered.body);
|
|
168
236
|
if (envelope === null)
|
|
169
237
|
return UNCERTAIN_READ;
|
|
170
238
|
const scope = envelope.scopes.find((candidate) => matchesScope(candidate, entry));
|
|
171
|
-
return bootstrappedRoom(envelope, scope,
|
|
239
|
+
return bootstrappedRoom(envelope, scope, asked, continued);
|
|
172
240
|
}
|
|
173
241
|
function layered(asks) {
|
|
174
242
|
const depths = new Map();
|
|
175
243
|
const layers = [];
|
|
176
244
|
for (const ask of asks) {
|
|
177
|
-
const depth = depths.get(ask.entry.authority) ?? 0;
|
|
178
|
-
depths.set(ask.entry.authority, depth + 1);
|
|
245
|
+
const depth = depths.get(ask.ask.entry.authority) ?? 0;
|
|
246
|
+
depths.set(ask.ask.entry.authority, depth + 1);
|
|
179
247
|
(layers[depth] ??= []).push(ask);
|
|
180
248
|
}
|
|
181
249
|
return layers;
|
|
182
250
|
}
|
|
183
251
|
async function enumerated(asks) {
|
|
184
|
-
const answers =
|
|
185
|
-
const parts = layered(asks).flatMap((layer) => selections(layer, (ask) => weight(ask.entry), declared().max_prefixes));
|
|
252
|
+
const answers = [];
|
|
253
|
+
const parts = layered(asks.map((ask, index) => ({ ask, index }))).flatMap((layer) => selections(layer, ({ ask }) => weight(ask.entry), declared().max_prefixes));
|
|
186
254
|
for (const part of parts) {
|
|
187
255
|
let open = [...part];
|
|
188
256
|
while (open.length > 0) {
|
|
189
257
|
const answer = await transport.door(DOOR_ENUMERATE, {
|
|
190
|
-
prefixes: open.flatMap((ask) => contentPrefixes(ask.entry)),
|
|
191
|
-
positions: open.map((ask) => presented(ask.entry.authority, ask.from)),
|
|
258
|
+
prefixes: open.flatMap(({ ask }) => contentPrefixes(ask.entry)),
|
|
259
|
+
positions: open.map(({ ask }) => presented(ask.entry.authority, ask.from)),
|
|
192
260
|
});
|
|
193
|
-
const classified = open.map((ask) => classifyRead(answer.status, answer.body, ask.entry.locator));
|
|
261
|
+
const classified = open.map(({ ask }) => classifyRead(answer.status, answer.body, ask.entry.locator));
|
|
194
262
|
if (classified[0]?.kind === 'beyond-horizon') {
|
|
195
263
|
const named = doorRefusal(answer.body)?.fields.authority;
|
|
196
|
-
const expired = open.filter((ask) => ask.entry.authority === named);
|
|
264
|
+
const expired = open.filter(({ ask }) => ask.entry.authority === named);
|
|
197
265
|
const answered = expired.length === 0 ? UNCERTAIN_READ : { kind: 'beyond-horizon' };
|
|
198
266
|
const gone = expired.length === 0 ? open : expired;
|
|
199
267
|
for (const ask of gone)
|
|
200
|
-
answers.
|
|
268
|
+
answers[ask.index] = answered;
|
|
201
269
|
open = open.filter((ask) => !gone.includes(ask));
|
|
202
270
|
continue;
|
|
203
271
|
}
|
|
204
272
|
const enumeration = classified[0] === null ? parseEnumeration(answer.body, 'credential') : null;
|
|
205
|
-
for (const [
|
|
206
|
-
const failure = classified[
|
|
273
|
+
for (const [answerIndex, { ask, index }] of open.entries()) {
|
|
274
|
+
const failure = classified[answerIndex];
|
|
207
275
|
if (failure !== null && failure !== undefined) {
|
|
208
|
-
answers
|
|
276
|
+
answers[index] = failure;
|
|
209
277
|
continue;
|
|
210
278
|
}
|
|
211
|
-
answers
|
|
279
|
+
answers[index] =
|
|
280
|
+
enumeration === null ? UNCERTAIN_READ : await enumeratedRoom(enumeration, ask);
|
|
212
281
|
}
|
|
213
282
|
open = [];
|
|
214
283
|
}
|
|
215
284
|
}
|
|
216
|
-
return
|
|
285
|
+
return answers;
|
|
217
286
|
}
|
|
218
287
|
const bootstrapTogether = gatheredEach(bootstrapped);
|
|
219
288
|
const enumerateTogether = gathered(enumerated);
|
|
@@ -244,7 +313,30 @@ export function createAgentsHouseAdapter(options) {
|
|
|
244
313
|
await keep(upload);
|
|
245
314
|
return { body: { ...head, paths, upload, runtime: notifications.runtime } };
|
|
246
315
|
}
|
|
247
|
-
async function
|
|
316
|
+
async function staged(answer, batch) {
|
|
317
|
+
const refusal = doorRefusal(answer.body);
|
|
318
|
+
if (refusal?.code !== 'files_unstaged')
|
|
319
|
+
return null;
|
|
320
|
+
const grants = refusal.fields.upload;
|
|
321
|
+
if (!Array.isArray(grants))
|
|
322
|
+
return false;
|
|
323
|
+
for (const grant of grants) {
|
|
324
|
+
const { url, operation, sha256 } = grant;
|
|
325
|
+
const change = batch.changes.find((held) => held.kind === 'binary' && held.sha256 === sha256);
|
|
326
|
+
if (typeof url !== 'string' || typeof operation !== 'string' || change === undefined)
|
|
327
|
+
return false;
|
|
328
|
+
const delivered = await transport.transfer({
|
|
329
|
+
act: 'binary_stage',
|
|
330
|
+
url,
|
|
331
|
+
body: change.blob,
|
|
332
|
+
operation,
|
|
333
|
+
});
|
|
334
|
+
if (delivered.status !== 200)
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
return true;
|
|
338
|
+
}
|
|
339
|
+
async function submit(batch, head, changes, delta, bytes, entry, handed, keep) {
|
|
248
340
|
const inline = { ...head, changes, runtime: notifications.runtime };
|
|
249
341
|
const prepared = uploadable(inline, bytes, declared())
|
|
250
342
|
? await uploaded(head, changes, delta, bytes, entry, handed, keep)
|
|
@@ -252,14 +344,61 @@ export function createAgentsHouseAdapter(options) {
|
|
|
252
344
|
if ('outcome' in prepared)
|
|
253
345
|
return prepared.outcome;
|
|
254
346
|
const answer = await transport.door(DOOR_BATCH, prepared.body);
|
|
255
|
-
|
|
347
|
+
const stagedFiles = await staged(answer, batch);
|
|
348
|
+
if (stagedFiles === false)
|
|
349
|
+
return UNCERTAIN;
|
|
350
|
+
const settled = stagedFiles === null ? answer : await transport.door(DOOR_BATCH, prepared.body);
|
|
351
|
+
if (stagedFiles === true && (await staged(settled, batch)) !== null)
|
|
352
|
+
return UNCERTAIN;
|
|
353
|
+
return mutationOutcome(settled.status, settled.body, entry.locator, entry.handle);
|
|
354
|
+
}
|
|
355
|
+
function granted(answer, locator) {
|
|
356
|
+
const failure = classifyDoor(answer.status, answer.body, locator);
|
|
357
|
+
if (failure !== null) {
|
|
358
|
+
return failure.kind === 'scoped-refusal'
|
|
359
|
+
? {
|
|
360
|
+
kind: 'rejected',
|
|
361
|
+
code: failure.code,
|
|
362
|
+
fields: failure.fields,
|
|
363
|
+
retryable: failure.retryable,
|
|
364
|
+
}
|
|
365
|
+
: failure;
|
|
366
|
+
}
|
|
367
|
+
const grant = parseGrant(answer.body);
|
|
368
|
+
const name = answer.body.name;
|
|
369
|
+
if (grant === null || grant.method !== 'GET' || typeof name !== 'string') {
|
|
370
|
+
return UNCERTAIN_READ;
|
|
371
|
+
}
|
|
372
|
+
return { kind: 'link', url: grant.url, name };
|
|
373
|
+
}
|
|
374
|
+
async function downloaded(answer, locator) {
|
|
375
|
+
const link = granted(answer, locator);
|
|
376
|
+
if (link.kind !== 'link')
|
|
377
|
+
return link;
|
|
378
|
+
const read = await transport.download(link.url);
|
|
379
|
+
if (read.status !== 200 || read.blob === null)
|
|
380
|
+
return UNCERTAIN_READ;
|
|
381
|
+
return { kind: 'binary', blob: read.blob };
|
|
382
|
+
}
|
|
383
|
+
function pathGrant(request) {
|
|
384
|
+
const entry = authorityFor(request.locator);
|
|
385
|
+
if (entry === undefined)
|
|
386
|
+
return null;
|
|
387
|
+
return transport.door(DOOR_FILES_GET, {
|
|
388
|
+
room_ref: entry.authority,
|
|
389
|
+
path: request.path,
|
|
390
|
+
revision: request.revision,
|
|
391
|
+
});
|
|
256
392
|
}
|
|
257
393
|
return {
|
|
258
394
|
async authorize() {
|
|
259
395
|
return options.authorize();
|
|
260
396
|
},
|
|
261
|
-
async discover(_authorization) {
|
|
262
|
-
const answer = await transport.door(DOOR_DISCOVER, {
|
|
397
|
+
async discover(_authorization, scope) {
|
|
398
|
+
const answer = await transport.door(DOOR_DISCOVER, {
|
|
399
|
+
prefixes: [...DISCOVER_PREFIXES],
|
|
400
|
+
...(scope === undefined ? {} : { rooms: scope.authorities }),
|
|
401
|
+
});
|
|
263
402
|
const failed = discoveryFailure(answer.status, answer.body);
|
|
264
403
|
if (failed !== null)
|
|
265
404
|
return failed;
|
|
@@ -268,26 +407,42 @@ export function createAgentsHouseAdapter(options) {
|
|
|
268
407
|
return { kind: 'transport-uncertainty' };
|
|
269
408
|
bounds = document.bounds;
|
|
270
409
|
const entries = trackedFrom(document);
|
|
271
|
-
|
|
410
|
+
const covered = scope === undefined
|
|
411
|
+
? null
|
|
412
|
+
: [
|
|
413
|
+
...new Set([
|
|
414
|
+
...[...tracked.values()]
|
|
415
|
+
.filter((entry) => scope.authorities.includes(entry.authority))
|
|
416
|
+
.map((entry) => entry.locator),
|
|
417
|
+
...entries.map((entry) => entry.locator),
|
|
418
|
+
]),
|
|
419
|
+
];
|
|
420
|
+
if (covered === null)
|
|
421
|
+
tracked.clear();
|
|
422
|
+
else
|
|
423
|
+
for (const locator of covered)
|
|
424
|
+
tracked.delete(locator);
|
|
272
425
|
for (const entry of entries)
|
|
273
426
|
tracked.set(entry.locator, entry);
|
|
274
427
|
for (const locator of handed.keys())
|
|
275
428
|
if (!tracked.has(locator))
|
|
276
429
|
handed.delete(locator);
|
|
277
|
-
notifications.track(
|
|
430
|
+
notifications.track([...tracked.values()]);
|
|
278
431
|
return {
|
|
279
|
-
...mapDiscovery(document, document.authorities.map((authority) => discoveredRoom(authority)), capabilities(document)),
|
|
432
|
+
...mapDiscovery(document, document.authorities.map((authority) => discoveredRoom(authority)), capabilities(document.actions, [...tracked.values()])),
|
|
280
433
|
member: document.member,
|
|
434
|
+
...(covered === null ? {} : { covered }),
|
|
281
435
|
};
|
|
282
436
|
},
|
|
283
437
|
async bootstrap(_authorization, request) {
|
|
284
438
|
const entry = authorityFor(request.locator);
|
|
285
439
|
if (entry === undefined)
|
|
286
440
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
441
|
+
const asked = { entry, held: request.held };
|
|
287
442
|
if (request.pageToken !== undefined) {
|
|
288
|
-
return continuedBootstrap(
|
|
443
|
+
return continuedBootstrap(asked, JSON.parse(request.pageToken));
|
|
289
444
|
}
|
|
290
|
-
return bootstrapTogether(
|
|
445
|
+
return bootstrapTogether(asked);
|
|
291
446
|
},
|
|
292
447
|
async refresh(_authorization, request) {
|
|
293
448
|
const entry = authorityFor(request.locator);
|
|
@@ -314,10 +469,11 @@ export function createAgentsHouseAdapter(options) {
|
|
|
314
469
|
const delta = deltaBody(mapped.changes);
|
|
315
470
|
const bytes = deltaBytes(delta);
|
|
316
471
|
const handed = request.upload;
|
|
317
|
-
const
|
|
472
|
+
const batch = request.changeBatch;
|
|
473
|
+
const outcome = await submit(batch, head, mapped.changes, delta, bytes, entry, handed, keep);
|
|
318
474
|
if (handed === undefined || !lapsedGrant(outcome))
|
|
319
475
|
return adopted(entry, outcome);
|
|
320
|
-
return adopted(entry, await submit(head, mapped.changes, delta, bytes, entry, undefined, keep));
|
|
476
|
+
return adopted(entry, await submit(batch, head, mapped.changes, delta, bytes, entry, undefined, keep));
|
|
321
477
|
},
|
|
322
478
|
async history(_authorization, request) {
|
|
323
479
|
const entry = authorityFor(request.locator);
|
|
@@ -334,6 +490,38 @@ export function createAgentsHouseAdapter(options) {
|
|
|
334
490
|
...(request.revision === undefined ? {} : { revision: request.revision }),
|
|
335
491
|
});
|
|
336
492
|
},
|
|
493
|
+
async binary(_authorization, request) {
|
|
494
|
+
if (request.kind === 'path') {
|
|
495
|
+
const asked = pathGrant(request);
|
|
496
|
+
if (asked === null)
|
|
497
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
498
|
+
return downloaded(await asked, request.locator);
|
|
499
|
+
}
|
|
500
|
+
const referrer = houseReferrer(request.referrer, tracked);
|
|
501
|
+
if (referrer === null) {
|
|
502
|
+
return { kind: 'rejected', code: 'referrer_unknown', fields: {}, retryable: false };
|
|
503
|
+
}
|
|
504
|
+
const answer = await transport.door(DOOR_FILES_GET, {
|
|
505
|
+
file: request.fileRef,
|
|
506
|
+
referrer: referrer.referrer,
|
|
507
|
+
});
|
|
508
|
+
return downloaded(answer, referrer.locator);
|
|
509
|
+
},
|
|
510
|
+
async link(_authorization, request) {
|
|
511
|
+
const asked = pathGrant(request);
|
|
512
|
+
if (asked === null)
|
|
513
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
514
|
+
return granted(await asked, request.locator);
|
|
515
|
+
},
|
|
516
|
+
referrerScope(referrer) {
|
|
517
|
+
const held = houseReferrer(referrer, tracked);
|
|
518
|
+
if (held === null)
|
|
519
|
+
return null;
|
|
520
|
+
if (held.locator === '')
|
|
521
|
+
return { kind: 'conversations' };
|
|
522
|
+
const { path } = held.referrer;
|
|
523
|
+
return { kind: 'room', locator: held.locator, ...(path === undefined ? {} : { path }) };
|
|
524
|
+
},
|
|
337
525
|
reached(locator, version, target) {
|
|
338
526
|
return reachedVersion(version, target, authorityFor(locator)?.logEpoch);
|
|
339
527
|
},
|
|
@@ -343,7 +531,16 @@ export function createAgentsHouseAdapter(options) {
|
|
|
343
531
|
async action(_authorization, request) {
|
|
344
532
|
return withAt(await houseAction(transport, request));
|
|
345
533
|
},
|
|
346
|
-
roomStream: {
|
|
534
|
+
roomStream: {
|
|
535
|
+
hold: held,
|
|
536
|
+
reopen: notifications.reopen,
|
|
537
|
+
observe: notifications.observe,
|
|
538
|
+
published(locator, roomVersion) {
|
|
539
|
+
const at = logPosition(roomVersion);
|
|
540
|
+
if (at !== null)
|
|
541
|
+
notifications.published(locator, at);
|
|
542
|
+
},
|
|
543
|
+
},
|
|
347
544
|
conversations: notifications.conversations,
|
|
348
545
|
serviceMode: notifications.serviceMode,
|
|
349
546
|
};
|
package/dist/discovery.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export type HouseBounds = {
|
|
|
13
13
|
max_inline_body_bytes: number;
|
|
14
14
|
max_upload_bytes: number;
|
|
15
15
|
max_prefixes: number;
|
|
16
|
+
max_held_files: number;
|
|
16
17
|
change_retention_seconds: number;
|
|
17
18
|
operation_retention_seconds: number;
|
|
18
19
|
};
|
|
@@ -65,7 +66,7 @@ export declare function siteTracked(document: HouseSiteDiscovery): TrackedAuthor
|
|
|
65
66
|
export declare function trackedFrom(document: HouseDiscoveryDocument): TrackedAuthority[];
|
|
66
67
|
export declare function providerLimits(bounds: HouseBounds): readonly ProviderLimit[];
|
|
67
68
|
export declare function declaredRetention(bounds: HouseBounds): Retention;
|
|
68
|
-
export declare function capabilities(
|
|
69
|
+
export declare function capabilities(actions: HouseDiscoveryDocument['actions'], rooms: readonly Pick<TrackedAuthority, 'authority' | 'houseModel'>[]): readonly Capability[];
|
|
69
70
|
export declare function siteCapabilities(): readonly Capability[];
|
|
70
71
|
export declare function discoveredRoom(authority: HouseAuthority): DiscoveredRoom;
|
|
71
72
|
export declare function mapDiscovery(document: Pick<HouseDiscoveryDocument, 'bounds'>, rooms: readonly DiscoveredRoom[], declared: readonly Capability[]): Discovery;
|
package/dist/discovery.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,SAAS,EACT,MAAM,EACN,aAAa,EACb,SAAS,EACV,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAA6B,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3E,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAU,CAAC;AAE1D,MAAM,MAAM,WAAW,GAAG;IACxB,uBAAuB,EAAE,MAAM,CAAC;IAChC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,wBAAwB,EAAE,MAAM,CAAC;IACjC,2BAA2B,EAAE,MAAM,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,kBAAkB,EAAE,UAAU,GAAG,aAAa,CAAC;IAC/C,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,UAAU,EAAE,eAAe,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IACvC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAC5C,CAAC;
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,SAAS,EACT,MAAM,EACN,aAAa,EACb,SAAS,EACV,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAA6B,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3E,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAU,CAAC;AAE1D,MAAM,MAAM,WAAW,GAAG;IACxB,uBAAuB,EAAE,MAAM,CAAC;IAChC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB,EAAE,MAAM,CAAC;IACjC,2BAA2B,EAAE,MAAM,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,kBAAkB,EAAE,UAAU,GAAG,aAAa,CAAC;IAC/C,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,UAAU,EAAE,eAAe,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IACvC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAC5C,CAAC;AA+FF,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,sBAAsB,GAAG,IAAI,CAsB3E;AAmBD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI,CAa3E;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,kBAAkB,GAAG,gBAAgB,EAAE,CAW5E;AAQD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,sBAAsB,GAAG,gBAAgB,EAAE,CAWhF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,aAAa,EAAE,CAU5E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAMhE;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,sBAAsB,CAAC,SAAS,CAAC,EAC1C,KAAK,EAAE,SAAS,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,YAAY,CAAC,EAAE,GACnE,SAAS,UAAU,EAAE,CAWvB;AAED,wBAAgB,gBAAgB,IAAI,SAAS,UAAU,EAAE,CAOxD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,cAAc,GAAG,cAAc,CAmBxE;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,IAAI,CAAC,sBAAsB,EAAE,QAAQ,CAAC,EAChD,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,QAAQ,EAAE,SAAS,UAAU,EAAE,GAC9B,SAAS,CAQX"}
|
package/dist/discovery.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { declaredActions, houseConversationAgents } from './actions.js';
|
|
1
|
+
import { declaredActions, houseConversationAgents, SITE_SUBMIT } from './actions.js';
|
|
2
2
|
import { readPosition, roomVersion } from './version.js';
|
|
3
3
|
export const PROVIDER_ACTIONS = 'provider-actions';
|
|
4
4
|
export const DISCOVER_PREFIXES = ['/'];
|
|
@@ -13,6 +13,7 @@ const BOUND_KEYS = [
|
|
|
13
13
|
'max_inline_body_bytes',
|
|
14
14
|
'max_upload_bytes',
|
|
15
15
|
'max_prefixes',
|
|
16
|
+
'max_held_files',
|
|
16
17
|
'change_retention_seconds',
|
|
17
18
|
'operation_retention_seconds',
|
|
18
19
|
];
|
|
@@ -215,21 +216,24 @@ export function declaredRetention(bounds) {
|
|
|
215
216
|
refreshHorizon: bounds.change_retention_seconds,
|
|
216
217
|
};
|
|
217
218
|
}
|
|
218
|
-
export function capabilities(
|
|
219
|
-
const house =
|
|
219
|
+
export function capabilities(actions, rooms) {
|
|
220
|
+
const house = rooms.find((room) => room.houseModel !== null);
|
|
220
221
|
return [
|
|
221
222
|
{
|
|
222
223
|
name: PROVIDER_ACTIONS,
|
|
223
|
-
actions: declaredActions(
|
|
224
|
+
actions: declaredActions(actions),
|
|
224
225
|
...(house === undefined
|
|
225
226
|
? {}
|
|
226
|
-
: { conversationAgents: houseConversationAgents(house.
|
|
227
|
+
: { conversationAgents: houseConversationAgents(house.authority) }),
|
|
227
228
|
},
|
|
228
229
|
];
|
|
229
230
|
}
|
|
230
231
|
export function siteCapabilities() {
|
|
231
232
|
return [
|
|
232
|
-
{
|
|
233
|
+
{
|
|
234
|
+
name: PROVIDER_ACTIONS,
|
|
235
|
+
actions: [{ name: SITE_SUBMIT, inputShape: {}, resultKind: 'house' }],
|
|
236
|
+
},
|
|
233
237
|
];
|
|
234
238
|
}
|
|
235
239
|
export function discoveredRoom(authority) {
|
package/dist/handed.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { HeldRoom, MutationResult } from '@agentshouse/mdruntime';
|
|
2
|
+
import type { HouseScope, HouseView } from './read.js';
|
|
3
|
+
import type { StreamedAdvancement } from './stream.js';
|
|
4
|
+
export type HandedRoom = {
|
|
5
|
+
roomVersion: string;
|
|
6
|
+
revisions: ReadonlyMap<string, string>;
|
|
7
|
+
};
|
|
8
|
+
export declare function scopeHanded(scope: HouseScope): HandedRoom;
|
|
9
|
+
export declare function heldHanded(held: HeldRoom): HandedRoom;
|
|
10
|
+
export declare function acceptedHanded(held: HandedRoom, accepted: Extract<MutationResult, {
|
|
11
|
+
kind: 'accepted';
|
|
12
|
+
}>, roomVersion: string): HandedRoom;
|
|
13
|
+
export declare function enumeratedHanded(view: HouseView, earlier: HandedRoom | undefined): HandedRoom;
|
|
14
|
+
export declare function streamedHanded(held: HandedRoom, advanced: StreamedAdvancement): HandedRoom;
|
|
15
|
+
//# sourceMappingURL=handed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handed.d.ts","sourceRoot":"","sources":["../src/handed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,MAAM,MAAM,UAAU,GAAG;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC,CAAC;AAEF,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CASzD;AAOD,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAErD;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,EACvD,WAAW,EAAE,MAAM,GAClB,UAAU,CAKZ;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAM7F;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,mBAAmB,GAAG,UAAU,CAM1F"}
|
package/dist/handed.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { roomVersion } from './version.js';
|
|
2
|
+
export function scopeHanded(scope) {
|
|
3
|
+
return {
|
|
4
|
+
roomVersion: roomVersion(scope),
|
|
5
|
+
revisions: new Map(scope.files.flatMap(({ path, revision }) => revision === undefined ? [] : [[path, revision]])),
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
function revised(revisions, path, revision) {
|
|
9
|
+
if (revision === undefined)
|
|
10
|
+
revisions.delete(path);
|
|
11
|
+
else
|
|
12
|
+
revisions.set(path, revision);
|
|
13
|
+
}
|
|
14
|
+
export function heldHanded(held) {
|
|
15
|
+
return { roomVersion: held.roomVersion, revisions: new Map(Object.entries(held.revisions)) };
|
|
16
|
+
}
|
|
17
|
+
export function acceptedHanded(held, accepted, roomVersion) {
|
|
18
|
+
const revisions = new Map(held.revisions);
|
|
19
|
+
for (const [path, revision] of Object.entries(accepted.revisions))
|
|
20
|
+
revisions.set(path, revision);
|
|
21
|
+
for (const path of accepted.removals)
|
|
22
|
+
revisions.delete(path);
|
|
23
|
+
return { roomVersion, revisions };
|
|
24
|
+
}
|
|
25
|
+
export function enumeratedHanded(view, earlier) {
|
|
26
|
+
const revisions = new Map(earlier?.revisions);
|
|
27
|
+
for (const change of view.changes) {
|
|
28
|
+
revised(revisions, change.path, 'removed' in change ? undefined : change.revision);
|
|
29
|
+
}
|
|
30
|
+
return { roomVersion: roomVersion(view), revisions };
|
|
31
|
+
}
|
|
32
|
+
export function streamedHanded(held, advanced) {
|
|
33
|
+
const revisions = new Map(held.revisions);
|
|
34
|
+
for (const entry of advanced.entries) {
|
|
35
|
+
revised(revisions, entry.path, entry.kind === 'removed' ? undefined : entry.revision);
|
|
36
|
+
}
|
|
37
|
+
return { roomVersion: advanced.page.roomVersion, revisions };
|
|
38
|
+
}
|