@agentshouse/mdruntime-adapter 0.1.0-ccd2ccb1f7214 → 0.1.0-ccda1a2da11c3
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 +50 -40
- package/dist/actions.d.ts +11 -5
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +77 -97
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +183 -139
- package/dist/discovery.d.ts +3 -2
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +24 -6
- package/dist/gather.d.ts +1 -1
- package/dist/gather.d.ts.map +1 -1
- package/dist/gather.js +4 -14
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/part.d.ts +13 -0
- package/dist/part.d.ts.map +1 -0
- package/dist/part.js +80 -0
- package/dist/read.d.ts +51 -27
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +241 -124
- package/dist/referrer.d.ts +2 -0
- package/dist/referrer.d.ts.map +1 -1
- package/dist/referrer.js +8 -2
- package/dist/room-types.d.ts +6 -0
- package/dist/room-types.d.ts.map +1 -0
- package/dist/room-types.js +66 -0
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +63 -76
- package/dist/stream.d.ts +3 -3
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +38 -34
- package/dist/transport.d.ts +6 -3
- package/dist/transport.d.ts.map +1 -1
- package/dist/write.d.ts +12 -1
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +90 -42
- package/package.json +2 -2
- package/dist/handed.d.ts +0 -15
- package/dist/handed.d.ts.map +0 -1
- package/dist/handed.js +0 -38
package/dist/adapter.js
CHANGED
|
@@ -1,46 +1,48 @@
|
|
|
1
|
+
import { stepped } from '@agentshouse/mdruntime';
|
|
1
2
|
import { DISCOVER_PREFIXES, capabilities, discoveredRoom, mapDiscovery, parseDiscovery, trackedFrom, } from './discovery.js';
|
|
2
3
|
import { partModels, streamedModels, viewModels } from './model.js';
|
|
3
4
|
import { gathered, gatheredEach, selections } from './gather.js';
|
|
4
5
|
import { createSiteAdapter } from './site.js';
|
|
5
|
-
import {
|
|
6
|
+
import { authorityRoot, bootstrapping, emptyScope, housePart, parseEnumeration, parseFileAddress, parseGrant, parseParted, refreshFrom, viewOf, wholeView, } from './read.js';
|
|
7
|
+
import { PART_ATTEMPTS, unverifiedPart } from './part.js';
|
|
6
8
|
import { sha256Hex } from './digest.js';
|
|
7
|
-
import { acceptedHanded, enumeratedHanded, heldHanded, scopeHanded, streamedHanded, } from './handed.js';
|
|
8
9
|
import { houseAction } from './actions.js';
|
|
9
10
|
import { classifyDoor, classifyRead, discoveryFailure, doorRefusal } from './refusal.js';
|
|
10
11
|
import { houseNotifications } from './stream.js';
|
|
11
12
|
import { DOOR_BATCH, DOOR_BATCH_UPLOAD, DOOR_BOOTSTRAP, DOOR_DISCOVER, DOOR_ENUMERATE, DOOR_FILES_GET, DOOR_REVISIONS, } from './transport.js';
|
|
12
|
-
import { batchPaths, deltaBody, deltaBytes, deltaDigest, historyOutcome, houseChanges, mutationOutcome, operationHead, rejectedMapping, revisionBody, uploadable, } from './write.js';
|
|
13
|
-
import { houseReferrer } from './referrer.js';
|
|
13
|
+
import { batchPaths, deltaBody, deltaBytes, deltaDigest, historyOutcome, houseChanges, houseMove, mutationOutcome, operationHead, rejectedMapping, revisionBody, uploadable, } from './write.js';
|
|
14
|
+
import { houseReferrer, houseReferrerScope } from './referrer.js';
|
|
15
|
+
import { HOUSE_ROOM_TYPES } from './room-types.js';
|
|
14
16
|
import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
|
|
15
17
|
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
16
18
|
const UNCERTAIN_READ = { kind: 'transport-uncertainty' };
|
|
19
|
+
const EXPIRED_ADDRESS = 403;
|
|
17
20
|
function lapsedGrant(outcome) {
|
|
18
21
|
return outcome.kind === 'rejected' && outcome.code === 'upload_unavailable';
|
|
19
22
|
}
|
|
20
|
-
function heldFiles(authority, held,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
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 };
|
|
23
|
+
async function heldFiles(authority, held, bound) {
|
|
24
|
+
const listed = await held.files(null, bound + 1);
|
|
25
|
+
const files = listed.slice(0, bound);
|
|
26
|
+
const through = listed.length > bound ? (files.at(-1)?.path ?? null) : null;
|
|
27
|
+
return files.length === 0 ? null : { room: authority, through, files };
|
|
30
28
|
}
|
|
31
29
|
async function reused(scope, held) {
|
|
32
30
|
const sent = new Set(scope.contents.map((entry) => entry.path));
|
|
33
31
|
const contents = [...scope.contents];
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
const asked = scope.files.filter((file) => file.binary === undefined && !sent.has(file.path));
|
|
33
|
+
if (asked.length === 0)
|
|
34
|
+
return scope;
|
|
35
|
+
if (held === undefined)
|
|
36
|
+
return null;
|
|
37
|
+
const kept = await held.contents(asked.map(({ path }) => path));
|
|
38
|
+
for (const file of asked) {
|
|
39
|
+
const found = kept.get(file.path);
|
|
40
|
+
if (found === undefined ||
|
|
41
|
+
found.revision !== file.revision ||
|
|
42
|
+
(await sha256Hex(found.content)) !== file.sha256) {
|
|
41
43
|
return null;
|
|
42
44
|
}
|
|
43
|
-
contents.push({ path: file.path, content });
|
|
45
|
+
contents.push({ path: file.path, content: found.content });
|
|
44
46
|
}
|
|
45
47
|
return { ...scope, contents };
|
|
46
48
|
}
|
|
@@ -51,48 +53,64 @@ export function createAgentsHouseAdapter(options) {
|
|
|
51
53
|
const notifications = houseNotifications(transport, 'credential');
|
|
52
54
|
const tracked = new Map();
|
|
53
55
|
const handed = new Map();
|
|
56
|
+
let heldRevisions;
|
|
54
57
|
let bounds;
|
|
55
58
|
function declared() {
|
|
56
59
|
if (bounds === undefined)
|
|
57
60
|
throw new Error('no Discovery declared the bounds');
|
|
58
61
|
return bounds;
|
|
59
62
|
}
|
|
60
|
-
async function
|
|
63
|
+
async function fetchedPart(entry, continued, listed) {
|
|
64
|
+
for (let attempt = 0; attempt < PART_ATTEMPTS; attempt += 1) {
|
|
65
|
+
const answered = await transport.door(DOOR_BOOTSTRAP, {
|
|
66
|
+
prefixes: [authorityRoot(entry.handle)],
|
|
67
|
+
part: listed.part,
|
|
68
|
+
...(continued.held === undefined ? {} : { held: [continued.held] }),
|
|
69
|
+
});
|
|
70
|
+
const failure = classifyRead(answered.status, answered.body, entry.locator);
|
|
71
|
+
if (failure !== null)
|
|
72
|
+
return failure;
|
|
73
|
+
const scope = await housePart(continued.room, answered.body, listed, 'credential');
|
|
74
|
+
if (scope !== null)
|
|
75
|
+
return scope;
|
|
76
|
+
}
|
|
77
|
+
return unverifiedPart(entry.locator);
|
|
78
|
+
}
|
|
79
|
+
async function partPage(asked, continued) {
|
|
61
80
|
const { entry } = asked;
|
|
62
|
-
|
|
63
|
-
|
|
81
|
+
const listed = continued.room.parts[continued.next];
|
|
82
|
+
const sent = listed === undefined
|
|
83
|
+
? emptyScope(continued.room)
|
|
84
|
+
: await fetchedPart(entry, continued, listed);
|
|
85
|
+
if ('kind' in sent)
|
|
86
|
+
return sent;
|
|
64
87
|
const scope = await reused(sent, asked.held);
|
|
65
88
|
if (scope === null) {
|
|
66
89
|
return asked.held === undefined
|
|
67
90
|
? UNCERTAIN_READ
|
|
68
|
-
:
|
|
69
|
-
? bootstrapTogether({ entry, held: undefined })
|
|
70
|
-
: continuedBootstrap({ entry, held: undefined }, continued);
|
|
91
|
+
: bootstrapTogether({ entry, held: undefined });
|
|
71
92
|
}
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
if (continued ===
|
|
75
|
-
handed.set(entry.locator,
|
|
93
|
+
const next = continued.next + 1;
|
|
94
|
+
const more = next < continued.room.parts.length;
|
|
95
|
+
if (continued.next === 0 && !more)
|
|
96
|
+
handed.set(entry.locator, roomVersion(scope));
|
|
76
97
|
else
|
|
77
98
|
handed.delete(entry.locator);
|
|
78
99
|
notifications.reach(entry.authority, scope);
|
|
79
100
|
const seen = [
|
|
80
|
-
...
|
|
101
|
+
...continued.seen,
|
|
81
102
|
...entry.schemas.filter((schema) => scope.files.some((file) => file.path === schema)),
|
|
82
103
|
];
|
|
83
|
-
const models = await partModels(scope, entry, new Set(seen),
|
|
84
|
-
const continuation = next === null
|
|
85
|
-
? null
|
|
86
|
-
: { after: next, seen, ...(cursor?.cut === undefined ? {} : { cut: cursor.cut }) };
|
|
104
|
+
const models = await partModels(scope, entry, new Set(seen), !more);
|
|
87
105
|
return {
|
|
88
|
-
...
|
|
106
|
+
...(await stepped(bootstrapping(scope))),
|
|
89
107
|
...(models === undefined ? {} : { models }),
|
|
90
|
-
...(
|
|
108
|
+
...(more ? { pageToken: JSON.stringify({ ...continued, next, seen }) } : {}),
|
|
91
109
|
};
|
|
92
110
|
}
|
|
93
111
|
async function enumeratedPage(ask, page) {
|
|
94
112
|
const answer = await transport.door(DOOR_ENUMERATE, {
|
|
95
|
-
prefixes:
|
|
113
|
+
prefixes: [authorityRoot(ask.entry.handle)],
|
|
96
114
|
positions: [
|
|
97
115
|
{
|
|
98
116
|
...presented(ask.entry.authority, { position: page.after, logEpoch: ask.from.logEpoch }),
|
|
@@ -116,21 +134,24 @@ export function createAgentsHouseAdapter(options) {
|
|
|
116
134
|
if ('kind' in view)
|
|
117
135
|
return view;
|
|
118
136
|
notifications.reach(ask.entry.authority, view);
|
|
119
|
-
const answer = refreshFrom(view, ask.fromRoomVersion);
|
|
137
|
+
const answer = await refreshFrom(view, ask.fromRoomVersion);
|
|
120
138
|
if (answer.kind !== 'net-advancement')
|
|
121
139
|
return answer;
|
|
122
|
-
handed.set(ask.entry.locator,
|
|
140
|
+
handed.set(ask.entry.locator, roomVersion(view));
|
|
123
141
|
const models = await viewModels(view, ask.entry);
|
|
124
142
|
return models === undefined ? answer : { ...answer, models };
|
|
125
143
|
}
|
|
126
144
|
async function streamed(entry, request, from) {
|
|
127
|
-
|
|
128
|
-
if (held?.roomVersion !== request.fromRoomVersion)
|
|
145
|
+
if (handed.get(entry.locator) !== request.fromRoomVersion)
|
|
129
146
|
return null;
|
|
130
|
-
const
|
|
147
|
+
const asked = notifications.edited(entry, from);
|
|
148
|
+
const kept = asked.length === 0 || heldRevisions === undefined
|
|
149
|
+
? new Map()
|
|
150
|
+
: await heldRevisions(entry.locator, asked);
|
|
151
|
+
const advanced = await stepped(notifications.advance(entry, from, (path, revision) => kept.get(path) === revision));
|
|
131
152
|
if (advanced === null)
|
|
132
153
|
return null;
|
|
133
|
-
handed.set(entry.locator,
|
|
154
|
+
handed.set(entry.locator, advanced.page.roomVersion);
|
|
134
155
|
const models = await streamedModels(advanced.schemas, entry, 'credential');
|
|
135
156
|
return models === undefined ? advanced.page : { ...advanced.page, models };
|
|
136
157
|
}
|
|
@@ -140,20 +161,27 @@ export function createAgentsHouseAdapter(options) {
|
|
|
140
161
|
const at = logPosition(room.roomVersion);
|
|
141
162
|
if (entry === undefined || at === null)
|
|
142
163
|
return [];
|
|
143
|
-
handed.set(room.locator,
|
|
164
|
+
handed.set(room.locator, room.roomVersion);
|
|
144
165
|
notifications.reach(entry.authority, at);
|
|
145
166
|
return [presented(entry.authority, at)];
|
|
146
167
|
});
|
|
147
168
|
notifications.send(kept);
|
|
148
169
|
}
|
|
149
|
-
function
|
|
170
|
+
async function adoptedMove(entry, into, outcome) {
|
|
171
|
+
if (outcome.kind === 'accepted' && outcome.destination !== undefined) {
|
|
172
|
+
await adopted(into, { kind: 'accepted', ...outcome.destination });
|
|
173
|
+
}
|
|
174
|
+
return adopted(entry, outcome);
|
|
175
|
+
}
|
|
176
|
+
async function adopted(entry, outcome) {
|
|
150
177
|
if (outcome.kind !== 'accepted')
|
|
151
178
|
return outcome;
|
|
152
179
|
const held = handed.get(entry.locator);
|
|
153
180
|
if (held === undefined)
|
|
154
181
|
return outcome;
|
|
155
|
-
const follows = followsVersion(held
|
|
156
|
-
|
|
182
|
+
const follows = followsVersion(held, outcome.roomVersion);
|
|
183
|
+
if (follows)
|
|
184
|
+
handed.set(entry.locator, outcome.roomVersion);
|
|
157
185
|
const at = logPosition(outcome.roomVersion);
|
|
158
186
|
if (follows && at !== null)
|
|
159
187
|
notifications.reach(entry.authority, at);
|
|
@@ -176,68 +204,61 @@ export function createAgentsHouseAdapter(options) {
|
|
|
176
204
|
return result;
|
|
177
205
|
return { ...result, at: { locator, roomVersion: roomVersion({ position, logEpoch }) } };
|
|
178
206
|
}
|
|
179
|
-
function
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
207
|
+
async function holding(asks) {
|
|
208
|
+
const bound = Math.floor(declared().max_held_files / Math.max(1, asks.filter((ask) => ask.held !== undefined).length));
|
|
209
|
+
const held = [];
|
|
210
|
+
for (const ask of asks) {
|
|
211
|
+
if (ask.held === undefined || bound === 0)
|
|
212
|
+
continue;
|
|
213
|
+
const files = await heldFiles(ask.entry.authority, ask.held, bound);
|
|
214
|
+
if (files !== null)
|
|
215
|
+
held.push(files);
|
|
216
|
+
}
|
|
217
|
+
return held;
|
|
185
218
|
}
|
|
186
219
|
async function bootstrapped(asks, answer) {
|
|
187
220
|
let open = asks.map((asked, ask) => ({ entry: asked.entry, asked, ask }));
|
|
188
221
|
while (open.length > 0) {
|
|
189
222
|
const unreached = [];
|
|
190
|
-
for (const part of selections(open,
|
|
191
|
-
const held = holding(part.map(({ asked }) => asked)
|
|
223
|
+
for (const part of selections(open, declared().max_prefixes)) {
|
|
224
|
+
const held = await holding(part.map(({ asked }) => asked));
|
|
192
225
|
const answered = await transport.door(DOOR_BOOTSTRAP, {
|
|
193
|
-
prefixes: part.
|
|
226
|
+
prefixes: part.map(({ entry }) => authorityRoot(entry.handle)),
|
|
194
227
|
...(held.length === 0 ? {} : { held }),
|
|
195
228
|
});
|
|
196
229
|
const classified = part.map(({ entry }) => classifyDoor(answered.status, answered.body, entry.locator));
|
|
197
|
-
const
|
|
230
|
+
const parted = classified[0] === null ? parseParted(answered.body) : null;
|
|
198
231
|
for (const [index, asked] of part.entries()) {
|
|
199
232
|
const failure = classified[index];
|
|
200
233
|
if (failure !== null && failure !== undefined) {
|
|
201
234
|
answer(asked.ask, failure);
|
|
202
235
|
continue;
|
|
203
236
|
}
|
|
204
|
-
if (
|
|
237
|
+
if (parted === null) {
|
|
205
238
|
answer(asked.ask, UNCERTAIN_READ);
|
|
206
239
|
continue;
|
|
207
240
|
}
|
|
208
|
-
const
|
|
209
|
-
if (
|
|
241
|
+
const room = parted.rooms.find((candidate) => candidate.anchor === asked.entry.authority);
|
|
242
|
+
if (room === undefined && parted.next !== undefined) {
|
|
210
243
|
unreached.push(asked);
|
|
211
244
|
continue;
|
|
212
245
|
}
|
|
213
|
-
|
|
246
|
+
if (room === undefined) {
|
|
247
|
+
answer(asked.ask, { kind: 'room-not-readable', locator: asked.entry.locator });
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
const kept = held.find((files) => files.room === asked.entry.authority);
|
|
251
|
+
answer(asked.ask, await partPage(asked.asked, {
|
|
252
|
+
room,
|
|
253
|
+
next: 0,
|
|
254
|
+
seen: [],
|
|
255
|
+
...(kept === undefined ? {} : { held: kept }),
|
|
256
|
+
}));
|
|
214
257
|
}
|
|
215
258
|
}
|
|
216
259
|
open = unreached;
|
|
217
260
|
}
|
|
218
261
|
}
|
|
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);
|
|
227
|
-
const answered = await transport.door(DOOR_BOOTSTRAP, {
|
|
228
|
-
prefixes: contentPrefixes(entry),
|
|
229
|
-
after,
|
|
230
|
-
...(held.length === 0 ? {} : { held }),
|
|
231
|
-
});
|
|
232
|
-
const failure = classifyRead(answered.status, answered.body, entry.locator);
|
|
233
|
-
if (failure !== null)
|
|
234
|
-
return failure;
|
|
235
|
-
const envelope = parseEnvelope(answered.body);
|
|
236
|
-
if (envelope === null)
|
|
237
|
-
return UNCERTAIN_READ;
|
|
238
|
-
const scope = envelope.scopes.find((candidate) => matchesScope(candidate, entry));
|
|
239
|
-
return bootstrappedRoom(envelope, scope, asked, continued);
|
|
240
|
-
}
|
|
241
262
|
function layered(asks) {
|
|
242
263
|
const depths = new Map();
|
|
243
264
|
const layers = [];
|
|
@@ -250,12 +271,12 @@ export function createAgentsHouseAdapter(options) {
|
|
|
250
271
|
}
|
|
251
272
|
async function enumerated(asks) {
|
|
252
273
|
const answers = [];
|
|
253
|
-
const parts = layered(asks.map((ask, index) => ({ ask, index }))).flatMap((layer) => selections(layer,
|
|
274
|
+
const parts = layered(asks.map((ask, index) => ({ ask, index }))).flatMap((layer) => selections(layer, declared().max_prefixes));
|
|
254
275
|
for (const part of parts) {
|
|
255
276
|
let open = [...part];
|
|
256
277
|
while (open.length > 0) {
|
|
257
278
|
const answer = await transport.door(DOOR_ENUMERATE, {
|
|
258
|
-
prefixes: open.
|
|
279
|
+
prefixes: open.map(({ ask }) => authorityRoot(ask.entry.handle)),
|
|
259
280
|
positions: open.map(({ ask }) => presented(ask.entry.authority, ask.from)),
|
|
260
281
|
});
|
|
261
282
|
const classified = open.map(({ ask }) => classifyRead(answer.status, answer.body, ask.entry.locator));
|
|
@@ -294,10 +315,12 @@ export function createAgentsHouseAdapter(options) {
|
|
|
294
315
|
}
|
|
295
316
|
const minted = await transport.door(DOOR_BATCH_UPLOAD, { ...head, paths, bytes, sha256 });
|
|
296
317
|
if (minted.status !== 200) {
|
|
297
|
-
return {
|
|
318
|
+
return {
|
|
319
|
+
outcome: await stepped(mutationOutcome(minted.status, minted.body, entry.locator, entry.handle)),
|
|
320
|
+
};
|
|
298
321
|
}
|
|
299
322
|
const grant = parseGrant(minted.body);
|
|
300
|
-
if (grant === null
|
|
323
|
+
if (grant === null)
|
|
301
324
|
return { outcome: UNCERTAIN };
|
|
302
325
|
const delivered = await transport.transfer({
|
|
303
326
|
act: 'authored_batch_upload',
|
|
@@ -307,13 +330,13 @@ export function createAgentsHouseAdapter(options) {
|
|
|
307
330
|
if (delivered.status !== 200)
|
|
308
331
|
return { outcome: UNCERTAIN };
|
|
309
332
|
const holding = parseGrant(delivered.body);
|
|
310
|
-
if (holding === null
|
|
333
|
+
if (holding === null)
|
|
311
334
|
return { outcome: UNCERTAIN };
|
|
312
335
|
const upload = { url: holding.url, operation: holding.operation, bytes, sha256 };
|
|
313
336
|
await keep(upload);
|
|
314
337
|
return { body: { ...head, paths, upload, runtime: notifications.runtime } };
|
|
315
338
|
}
|
|
316
|
-
async function staged(answer, batch) {
|
|
339
|
+
async function staged(answer, { changeBatch: batch, file }) {
|
|
317
340
|
const refusal = doorRefusal(answer.body);
|
|
318
341
|
if (refusal?.code !== 'files_unstaged')
|
|
319
342
|
return null;
|
|
@@ -328,7 +351,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
328
351
|
const delivered = await transport.transfer({
|
|
329
352
|
act: 'binary_stage',
|
|
330
353
|
url,
|
|
331
|
-
body: change.
|
|
354
|
+
body: await file(change.localId),
|
|
332
355
|
operation,
|
|
333
356
|
});
|
|
334
357
|
if (delivered.status !== 200)
|
|
@@ -336,7 +359,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
336
359
|
}
|
|
337
360
|
return true;
|
|
338
361
|
}
|
|
339
|
-
async function submit(
|
|
362
|
+
async function submit(request, head, changes, delta, bytes, entry, handed, keep, into) {
|
|
340
363
|
const inline = { ...head, changes, runtime: notifications.runtime };
|
|
341
364
|
const prepared = uploadable(inline, bytes, declared())
|
|
342
365
|
? await uploaded(head, changes, delta, bytes, entry, handed, keep)
|
|
@@ -344,15 +367,20 @@ export function createAgentsHouseAdapter(options) {
|
|
|
344
367
|
if ('outcome' in prepared)
|
|
345
368
|
return prepared.outcome;
|
|
346
369
|
const answer = await transport.door(DOOR_BATCH, prepared.body);
|
|
347
|
-
const stagedFiles = await staged(answer,
|
|
370
|
+
const stagedFiles = await staged(answer, request);
|
|
348
371
|
if (stagedFiles === false)
|
|
349
372
|
return UNCERTAIN;
|
|
350
373
|
const settled = stagedFiles === null ? answer : await transport.door(DOOR_BATCH, prepared.body);
|
|
351
|
-
if (stagedFiles === true && (await staged(settled,
|
|
374
|
+
if (stagedFiles === true && (await staged(settled, request)) !== null)
|
|
352
375
|
return UNCERTAIN;
|
|
353
|
-
return mutationOutcome(settled.status, settled.body, entry.locator, entry.handle
|
|
376
|
+
return stepped(mutationOutcome(settled.status, settled.body, entry.locator, entry.handle, into === undefined
|
|
377
|
+
? undefined
|
|
378
|
+
: {
|
|
379
|
+
source: { authority: entry.authority, handle: entry.handle },
|
|
380
|
+
destination: { authority: into.authority, handle: into.handle },
|
|
381
|
+
}));
|
|
354
382
|
}
|
|
355
|
-
function
|
|
383
|
+
function addressed(answer, locator) {
|
|
356
384
|
const failure = classifyDoor(answer.status, answer.body, locator);
|
|
357
385
|
if (failure !== null) {
|
|
358
386
|
return failure.kind === 'scoped-refusal'
|
|
@@ -364,33 +392,47 @@ export function createAgentsHouseAdapter(options) {
|
|
|
364
392
|
}
|
|
365
393
|
: failure;
|
|
366
394
|
}
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
return
|
|
395
|
+
const address = parseFileAddress(answer.body);
|
|
396
|
+
return address === null ? UNCERTAIN_READ : { kind: 'address', ...address };
|
|
397
|
+
}
|
|
398
|
+
function linked(answer, locator) {
|
|
399
|
+
const address = addressed(answer, locator);
|
|
400
|
+
return address.kind === 'address'
|
|
401
|
+
? { kind: 'link', url: address.url, name: address.name }
|
|
402
|
+
: address;
|
|
373
403
|
}
|
|
374
|
-
async function downloaded(
|
|
375
|
-
|
|
376
|
-
if (
|
|
377
|
-
return
|
|
378
|
-
|
|
379
|
-
if (read.status
|
|
404
|
+
async function downloaded(ask, locator) {
|
|
405
|
+
let address = addressed(await ask(), locator);
|
|
406
|
+
if (address.kind !== 'address')
|
|
407
|
+
return address;
|
|
408
|
+
let read = await transport.download(address.url);
|
|
409
|
+
if (read.status === EXPIRED_ADDRESS) {
|
|
410
|
+
address = addressed(await ask(), locator);
|
|
411
|
+
if (address.kind !== 'address')
|
|
412
|
+
return address;
|
|
413
|
+
read = await transport.download(address.url);
|
|
414
|
+
}
|
|
415
|
+
if (read.status !== 200 || read.body === null)
|
|
380
416
|
return UNCERTAIN_READ;
|
|
381
|
-
return {
|
|
417
|
+
return {
|
|
418
|
+
kind: 'binary',
|
|
419
|
+
body: read.body,
|
|
420
|
+
mediaType: address.mediaType,
|
|
421
|
+
sha256: address.sha256,
|
|
422
|
+
};
|
|
382
423
|
}
|
|
383
|
-
function
|
|
424
|
+
function pathAddress(request) {
|
|
384
425
|
const entry = authorityFor(request.locator);
|
|
385
426
|
if (entry === undefined)
|
|
386
427
|
return null;
|
|
387
|
-
return transport.door(DOOR_FILES_GET, {
|
|
428
|
+
return () => transport.door(DOOR_FILES_GET, {
|
|
388
429
|
room_ref: entry.authority,
|
|
389
430
|
path: request.path,
|
|
390
431
|
revision: request.revision,
|
|
391
432
|
});
|
|
392
433
|
}
|
|
393
434
|
return {
|
|
435
|
+
roomTypes: HOUSE_ROOM_TYPES,
|
|
394
436
|
async authorize() {
|
|
395
437
|
return options.authorize();
|
|
396
438
|
},
|
|
@@ -440,7 +482,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
440
482
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
441
483
|
const asked = { entry, held: request.held };
|
|
442
484
|
if (request.pageToken !== undefined) {
|
|
443
|
-
return
|
|
485
|
+
return partPage(asked, JSON.parse(request.pageToken));
|
|
444
486
|
}
|
|
445
487
|
return bootstrapTogether(asked);
|
|
446
488
|
},
|
|
@@ -462,18 +504,27 @@ export function createAgentsHouseAdapter(options) {
|
|
|
462
504
|
const entry = authorityFor(request.locator);
|
|
463
505
|
if (entry === undefined)
|
|
464
506
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
465
|
-
const
|
|
507
|
+
const batch = request.changeBatch;
|
|
508
|
+
const destination = batch.between?.destination.room;
|
|
509
|
+
const into = destination === undefined ? undefined : authorityFor(destination);
|
|
510
|
+
if (destination !== undefined && into === undefined) {
|
|
511
|
+
return { kind: 'room-not-readable', locator: destination };
|
|
512
|
+
}
|
|
513
|
+
const mapped = into === undefined
|
|
514
|
+
? houseChanges(batch, entry.handle)
|
|
515
|
+
: houseMove(batch, entry.handle, into.handle);
|
|
466
516
|
if (mapped.kind === 'unmapped')
|
|
467
517
|
return rejectedMapping(mapped);
|
|
468
|
-
const head = operationHead(
|
|
518
|
+
const head = operationHead(batch);
|
|
469
519
|
const delta = deltaBody(mapped.changes);
|
|
470
520
|
const bytes = deltaBytes(delta);
|
|
471
521
|
const handed = request.upload;
|
|
472
|
-
const
|
|
473
|
-
const
|
|
522
|
+
const answer = (upload) => submit(request, head, mapped.changes, delta, bytes, entry, upload, keep, into);
|
|
523
|
+
const settle = (outcome) => into === undefined ? adopted(entry, outcome) : adoptedMove(entry, into, outcome);
|
|
524
|
+
const outcome = await answer(handed);
|
|
474
525
|
if (handed === undefined || !lapsedGrant(outcome))
|
|
475
|
-
return
|
|
476
|
-
return
|
|
526
|
+
return settle(outcome);
|
|
527
|
+
return settle(await answer(undefined));
|
|
477
528
|
},
|
|
478
529
|
async history(_authorization, request) {
|
|
479
530
|
const entry = authorityFor(request.locator);
|
|
@@ -492,35 +543,25 @@ export function createAgentsHouseAdapter(options) {
|
|
|
492
543
|
},
|
|
493
544
|
async binary(_authorization, request) {
|
|
494
545
|
if (request.kind === 'path') {
|
|
495
|
-
const
|
|
496
|
-
if (
|
|
546
|
+
const ask = pathAddress(request);
|
|
547
|
+
if (ask === null)
|
|
497
548
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
498
|
-
return downloaded(
|
|
549
|
+
return downloaded(ask, request.locator);
|
|
499
550
|
}
|
|
500
551
|
const referrer = houseReferrer(request.referrer, tracked);
|
|
501
552
|
if (referrer === null) {
|
|
502
553
|
return { kind: 'rejected', code: 'referrer_unknown', fields: {}, retryable: false };
|
|
503
554
|
}
|
|
504
|
-
|
|
505
|
-
file: request.fileRef,
|
|
506
|
-
referrer: referrer.referrer,
|
|
507
|
-
});
|
|
508
|
-
return downloaded(answer, referrer.locator);
|
|
555
|
+
return downloaded(() => transport.door(DOOR_FILES_GET, { file: request.fileRef, referrer: referrer.referrer }), referrer.locator);
|
|
509
556
|
},
|
|
510
557
|
async link(_authorization, request) {
|
|
511
|
-
const
|
|
512
|
-
if (
|
|
558
|
+
const ask = pathAddress(request);
|
|
559
|
+
if (ask === null)
|
|
513
560
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
514
|
-
return
|
|
561
|
+
return linked(await ask(), request.locator);
|
|
515
562
|
},
|
|
516
563
|
referrerScope(referrer) {
|
|
517
|
-
|
|
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 }) };
|
|
564
|
+
return houseReferrerScope(referrer, tracked);
|
|
524
565
|
},
|
|
525
566
|
reached(locator, version, target) {
|
|
526
567
|
return reachedVersion(version, target, authorityFor(locator)?.logEpoch);
|
|
@@ -534,7 +575,10 @@ export function createAgentsHouseAdapter(options) {
|
|
|
534
575
|
roomStream: {
|
|
535
576
|
hold: held,
|
|
536
577
|
reopen: notifications.reopen,
|
|
537
|
-
observe
|
|
578
|
+
observe(notify, receipts, revisions) {
|
|
579
|
+
heldRevisions = revisions;
|
|
580
|
+
return notifications.observe(notify, receipts);
|
|
581
|
+
},
|
|
538
582
|
published(locator, roomVersion) {
|
|
539
583
|
const at = logPosition(roomVersion);
|
|
540
584
|
if (at !== null)
|
package/dist/discovery.d.ts
CHANGED
|
@@ -16,13 +16,13 @@ export type HouseBounds = {
|
|
|
16
16
|
max_held_files: number;
|
|
17
17
|
change_retention_seconds: number;
|
|
18
18
|
operation_retention_seconds: number;
|
|
19
|
+
max_move_documents?: number;
|
|
19
20
|
};
|
|
20
21
|
export type HouseOperations = {
|
|
21
|
-
read: readonly string[];
|
|
22
|
-
sync: readonly string[];
|
|
23
22
|
write: readonly string[];
|
|
24
23
|
delete: readonly string[];
|
|
25
24
|
};
|
|
25
|
+
export type HouseReadLevel = 'mcp' | 'online' | 'local';
|
|
26
26
|
export type HouseModel = {
|
|
27
27
|
root: string;
|
|
28
28
|
paths: readonly string[];
|
|
@@ -35,6 +35,7 @@ export type HouseAuthority = LogPosition & {
|
|
|
35
35
|
houseModel: HouseModel | null;
|
|
36
36
|
managedReplication: 'admitted' | 'unavailable';
|
|
37
37
|
protectedPaths: readonly string[];
|
|
38
|
+
read: HouseReadLevel;
|
|
38
39
|
operations: HouseOperations;
|
|
39
40
|
};
|
|
40
41
|
export type HouseDiscoveryDocument = {
|
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,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB,EAAE,MAAM,CAAC;IACjC,2BAA2B,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|