@agentshouse/mdruntime-adapter 0.1.0-ce5ef9afd7e9a → 0.1.0-ce752a56d9714
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 +4 -73
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +7 -316
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +148 -324
- package/dist/app-reference.d.ts +2 -0
- package/dist/app-reference.d.ts.map +1 -0
- package/dist/app-reference.js +2 -0
- package/dist/crockford.d.ts +4 -0
- package/dist/crockford.d.ts.map +1 -0
- package/dist/crockford.js +3 -0
- package/dist/discovery.d.ts +21 -12
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +73 -51
- 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 +911 -0
- package/dist/house-model.d.ts.map +1 -0
- package/dist/house-model.js +496 -0
- package/dist/index.d.ts +10 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -2
- package/dist/model.d.ts +5 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +10 -29
- package/dist/part.d.ts +12 -11
- package/dist/part.d.ts.map +1 -1
- package/dist/part.js +66 -56
- package/dist/read.d.ts +19 -56
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +140 -298
- package/dist/refusal.d.ts +0 -3
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +0 -5
- package/dist/room-stream.d.ts +20 -0
- package/dist/room-stream.d.ts.map +1 -0
- package/dist/room-stream.js +78 -0
- package/dist/room-types.d.ts +4 -3
- package/dist/room-types.d.ts.map +1 -1
- package/dist/room-types.js +66 -7
- package/dist/search.d.ts +5 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +47 -0
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +88 -176
- package/dist/stream.d.ts +13 -14
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +169 -426
- package/dist/transport.d.ts +48 -36
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +54 -12
- package/dist/upload.d.ts.map +1 -1
- package/dist/upload.js +26 -15
- package/dist/write.d.ts +6 -1
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +19 -32
- package/package.json +8 -4
- package/AGENTS.md +0 -312
- package/dist/gather.d.ts +0 -4
- package/dist/gather.d.ts.map +0 -1
- package/dist/gather.js +0 -35
- package/dist/referrer.d.ts +0 -9
- package/dist/referrer.d.ts.map +0 -1
- package/dist/referrer.js +0 -41
package/dist/adapter.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { stepped } from '@agentshouse/mdruntime';
|
|
2
|
-
import {
|
|
3
|
-
import { partModels, streamedModels, viewModels } from './model.js';
|
|
4
|
-
import { gathered, gatheredEach, selections } from './gather.js';
|
|
2
|
+
import { capabilities, discoveredRoom, mapDiscovery, parseAuthorityChange, parseDiscovery, trackedFrom, } from './discovery.js';
|
|
5
3
|
import { createSiteAdapter } from './site.js';
|
|
6
|
-
import { authorityRoot, bootstrapping,
|
|
7
|
-
import {
|
|
4
|
+
import { authorityRoot, bootstrapping, parseFileAddress, parseGrant, } from './read.js';
|
|
5
|
+
import { roomStreams } from './room-stream.js';
|
|
8
6
|
import { sha256Hex } from './digest.js';
|
|
9
7
|
import { finishedUpload, houseUpload } from './upload.js';
|
|
10
8
|
import { houseAction } from './actions.js';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
9
|
+
import { houseSearch } from './search.js';
|
|
10
|
+
import { classifyDoor, doorRefusal } from './refusal.js';
|
|
11
|
+
import { houseNotifications, } from './stream.js';
|
|
12
|
+
import { houseDoorRoute, } from './transport.js';
|
|
14
13
|
import { batchPaths, deltaBody, deltaBytes, deltaDigest, historyOutcome, houseChanges, houseMove, mutationOutcome, operationHead, rejectedMapping, revisionBody, uploadable, } from './write.js';
|
|
15
|
-
import {
|
|
16
|
-
import { HOUSE_ROOM_TYPES } from './room-types.js';
|
|
17
|
-
import { followsVersion, logPosition, presented, reachedVersion, roomVersion
|
|
14
|
+
import { HOUSE_TYPED_PATHS } from './house-model.js';
|
|
15
|
+
import { HOUSE_NAMEABLE_ROOM_TYPES, HOUSE_ROOM_TYPES } from './room-types.js';
|
|
16
|
+
import { followsVersion, logPosition, presented, reachedVersion, roomVersion } from './version.js';
|
|
18
17
|
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
19
18
|
const UNCERTAIN_READ = { kind: 'transport-uncertainty' };
|
|
19
|
+
const OCTET_STREAM = 'application/octet-stream';
|
|
20
20
|
const EXPIRED_ADDRESS = 403;
|
|
21
21
|
function lapsedGrant(outcome) {
|
|
22
22
|
return outcome.kind === 'rejected' && outcome.code === 'upload_unavailable';
|
|
@@ -30,7 +30,7 @@ async function heldFiles(authority, held, bound) {
|
|
|
30
30
|
async function reused(scope, held) {
|
|
31
31
|
const sent = new Set(scope.contents.map((entry) => entry.path));
|
|
32
32
|
const contents = [...scope.contents];
|
|
33
|
-
const asked = scope.files.filter((file) => file.binary === undefined && !sent.has(file.path));
|
|
33
|
+
const asked = scope.files.filter((file) => file.binary === undefined && file.outline === undefined && !sent.has(file.path));
|
|
34
34
|
if (asked.length === 0)
|
|
35
35
|
return scope;
|
|
36
36
|
if (held === undefined)
|
|
@@ -51,142 +51,91 @@ export function createAgentsHouseAdapter(options) {
|
|
|
51
51
|
if ('site' in options)
|
|
52
52
|
return createSiteAdapter(options.site, options.snapshot === true);
|
|
53
53
|
const transport = options.transport;
|
|
54
|
-
const notifications = houseNotifications(transport, 'credential'
|
|
54
|
+
const notifications = houseNotifications(transport, 'credential', {
|
|
55
|
+
opened: async (frame) => (frame === null ? null : opened(frame)),
|
|
56
|
+
changed,
|
|
57
|
+
});
|
|
55
58
|
const tracked = new Map();
|
|
56
|
-
const
|
|
57
|
-
|
|
59
|
+
const rooms = roomStreams('credential');
|
|
60
|
+
const unreused = new Set();
|
|
58
61
|
let bounds;
|
|
59
62
|
function declared() {
|
|
60
63
|
if (bounds === undefined)
|
|
61
64
|
throw new Error('no Discovery declared the bounds');
|
|
62
65
|
return bounds;
|
|
63
66
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
return unverifiedPart(entry.locator);
|
|
67
|
+
function opened(frame) {
|
|
68
|
+
const document = parseDiscovery(frame);
|
|
69
|
+
if (document === null)
|
|
70
|
+
return null;
|
|
71
|
+
bounds = document.bounds;
|
|
72
|
+
tracked.clear();
|
|
73
|
+
for (const entry of trackedFrom(document))
|
|
74
|
+
tracked.set(entry.locator, entry);
|
|
75
|
+
notifications.track([...tracked.values()]);
|
|
76
|
+
return {
|
|
77
|
+
...mapDiscovery(document, document.authorities.map((authority) => discoveredRoom(authority)), capabilities(document.actions)),
|
|
78
|
+
member: document.member,
|
|
79
|
+
};
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
function changed(frame) {
|
|
82
|
+
const change = parseAuthorityChange(frame);
|
|
83
|
+
if (change === null)
|
|
84
|
+
return null;
|
|
85
|
+
for (const locator of change.left)
|
|
86
|
+
tracked.delete(locator);
|
|
87
|
+
for (const entry of trackedFrom(change))
|
|
88
|
+
tracked.set(entry.locator, entry);
|
|
89
|
+
notifications.track([...tracked.values()]);
|
|
90
|
+
return {
|
|
91
|
+
kind: 'authority-changed',
|
|
92
|
+
rooms: change.authorities.map((authority) => discoveredRoom(authority)),
|
|
93
|
+
left: change.left,
|
|
94
|
+
member: change.member,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async function streamedPage(entry, token, held) {
|
|
98
|
+
const part = await rooms.part(entry, token);
|
|
99
|
+
if ('kind' in part)
|
|
100
|
+
return part;
|
|
101
|
+
const scope = await reused(part.scope, held);
|
|
89
102
|
if (scope === null) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
: bootstrapTogether({ entry, held: undefined });
|
|
103
|
+
unreused.add(entry.locator);
|
|
104
|
+
return UNCERTAIN_READ;
|
|
93
105
|
}
|
|
94
|
-
const next = continued.next + 1;
|
|
95
|
-
const more = next < continued.room.parts.length;
|
|
96
|
-
if (continued.next === 0 && !more)
|
|
97
|
-
handed.set(entry.locator, roomVersion(scope));
|
|
98
|
-
else
|
|
99
|
-
handed.delete(entry.locator);
|
|
100
|
-
notifications.reach(entry.authority, scope);
|
|
101
|
-
const seen = [
|
|
102
|
-
...continued.seen,
|
|
103
|
-
...entry.schemas.filter((schema) => scope.files.some((file) => file.path === schema)),
|
|
104
|
-
];
|
|
105
|
-
const models = await partModels(scope, entry, new Set(seen), !more);
|
|
106
106
|
return {
|
|
107
107
|
...(await stepped(bootstrapping(scope))),
|
|
108
|
-
...(models === undefined ? {} : { models }),
|
|
109
|
-
...(
|
|
108
|
+
...(part.models === undefined ? {} : { models: part.models }),
|
|
109
|
+
...(part.pageToken === undefined ? {} : { pageToken: part.pageToken }),
|
|
110
|
+
bytes: part.bytes,
|
|
110
111
|
};
|
|
111
112
|
}
|
|
112
|
-
async function
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
...presented(ask.entry.authority, { position: page.after, logEpoch: ask.from.logEpoch }),
|
|
118
|
-
page: { through: page.through, read: page.read },
|
|
119
|
-
},
|
|
120
|
-
],
|
|
121
|
-
});
|
|
122
|
-
const failure = classifyRead(answer.status, answer.body, ask.entry.locator);
|
|
123
|
-
if (failure !== null)
|
|
124
|
-
return failure;
|
|
125
|
-
const enumeration = parseEnumeration(answer.body, 'credential');
|
|
126
|
-
if (enumeration === null)
|
|
127
|
-
return UNCERTAIN_READ;
|
|
128
|
-
return (viewOf(enumeration, ask.entry) ?? { kind: 'room-not-readable', locator: ask.entry.locator });
|
|
113
|
+
async function namedDocument(entry, path, signal) {
|
|
114
|
+
const answered = await transport.streamed(houseDoorRoute('bootstrap'), { room_ref: entry.authority, prefixes: [`${authorityRoot(entry.handle)}/${path}`] }, signal ?? new AbortController().signal);
|
|
115
|
+
if (answered.room === null)
|
|
116
|
+
return classifyDoor(answered.status, answered.body, entry.locator) ?? UNCERTAIN_READ;
|
|
117
|
+
return rooms.named(entry, answered.room, signal);
|
|
129
118
|
}
|
|
130
|
-
async function
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
return models === undefined ? answer : { ...answer, models };
|
|
144
|
-
}
|
|
145
|
-
async function streamed(entry, request, from) {
|
|
146
|
-
if (handed.get(entry.locator) !== request.fromRoomVersion)
|
|
147
|
-
return null;
|
|
148
|
-
const asked = notifications.edited(entry, from);
|
|
149
|
-
const kept = asked.length === 0 || heldRevisions === undefined
|
|
150
|
-
? new Map()
|
|
151
|
-
: await heldRevisions(entry.locator, asked);
|
|
152
|
-
const advanced = await stepped(notifications.advance(entry, from, (path, revision) => kept.get(path) === revision));
|
|
153
|
-
if (advanced === null)
|
|
154
|
-
return null;
|
|
155
|
-
handed.set(entry.locator, advanced.page.roomVersion);
|
|
156
|
-
const models = await streamedModels(advanced.schemas, entry, 'credential');
|
|
157
|
-
return models === undefined ? advanced.page : { ...advanced.page, models };
|
|
119
|
+
async function openedRoom(entry, request) {
|
|
120
|
+
const reusing = unreused.delete(entry.locator) ? undefined : request.held;
|
|
121
|
+
const files = reusing === undefined
|
|
122
|
+
? null
|
|
123
|
+
: await heldFiles(entry.authority, reusing, declared().max_held_files);
|
|
124
|
+
const answered = await transport.streamed(houseDoorRoute('bootstrap'), {
|
|
125
|
+
room_ref: entry.authority,
|
|
126
|
+
prefixes: [authorityRoot(entry.handle)],
|
|
127
|
+
...(files === null ? {} : { held: [files] }),
|
|
128
|
+
}, request.signal ?? new AbortController().signal);
|
|
129
|
+
if (answered.room === null)
|
|
130
|
+
return classifyDoor(answered.status, answered.body, entry.locator) ?? UNCERTAIN_READ;
|
|
131
|
+
return rooms.head(entry, answered.room, request.arriving, request.signal);
|
|
158
132
|
}
|
|
159
133
|
function held(rooms) {
|
|
160
|
-
|
|
134
|
+
notifications.send(rooms.flatMap((room) => {
|
|
161
135
|
const entry = tracked.get(room.locator);
|
|
162
136
|
const at = logPosition(room.roomVersion);
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
handed.set(room.locator, room.roomVersion);
|
|
166
|
-
notifications.reach(entry.authority, at);
|
|
167
|
-
return [presented(entry.authority, at)];
|
|
168
|
-
});
|
|
169
|
-
notifications.send(kept);
|
|
170
|
-
}
|
|
171
|
-
async function adoptedMove(entry, into, outcome) {
|
|
172
|
-
if (outcome.kind === 'accepted' && outcome.destination !== undefined) {
|
|
173
|
-
await adopted(into, { kind: 'accepted', ...outcome.destination });
|
|
174
|
-
}
|
|
175
|
-
return adopted(entry, outcome);
|
|
176
|
-
}
|
|
177
|
-
async function adopted(entry, outcome) {
|
|
178
|
-
if (outcome.kind !== 'accepted')
|
|
179
|
-
return outcome;
|
|
180
|
-
const held = handed.get(entry.locator);
|
|
181
|
-
if (held === undefined)
|
|
182
|
-
return outcome;
|
|
183
|
-
const follows = followsVersion(held, outcome.roomVersion);
|
|
184
|
-
if (follows)
|
|
185
|
-
handed.set(entry.locator, outcome.roomVersion);
|
|
186
|
-
const at = logPosition(outcome.roomVersion);
|
|
187
|
-
if (follows && at !== null)
|
|
188
|
-
notifications.reach(entry.authority, at);
|
|
189
|
-
return outcome;
|
|
137
|
+
return entry === undefined || at === null ? [] : [presented(entry.authority, at)];
|
|
138
|
+
}));
|
|
190
139
|
}
|
|
191
140
|
function authorityFor(locator) {
|
|
192
141
|
return tracked.get(locator);
|
|
@@ -205,116 +154,18 @@ export function createAgentsHouseAdapter(options) {
|
|
|
205
154
|
return result;
|
|
206
155
|
return { ...result, at: { locator, roomVersion: roomVersion({ position, logEpoch }) } };
|
|
207
156
|
}
|
|
208
|
-
async function holding(asks) {
|
|
209
|
-
const bound = Math.floor(declared().max_held_files / Math.max(1, asks.filter((ask) => ask.held !== undefined).length));
|
|
210
|
-
const held = [];
|
|
211
|
-
for (const ask of asks) {
|
|
212
|
-
if (ask.held === undefined || bound === 0)
|
|
213
|
-
continue;
|
|
214
|
-
const files = await heldFiles(ask.entry.authority, ask.held, bound);
|
|
215
|
-
if (files !== null)
|
|
216
|
-
held.push(files);
|
|
217
|
-
}
|
|
218
|
-
return held;
|
|
219
|
-
}
|
|
220
|
-
async function bootstrapped(asks, answer) {
|
|
221
|
-
let open = asks.map((asked, ask) => ({ entry: asked.entry, asked, ask }));
|
|
222
|
-
while (open.length > 0) {
|
|
223
|
-
const unreached = [];
|
|
224
|
-
for (const part of selections(open, declared().max_prefixes)) {
|
|
225
|
-
const held = await holding(part.map(({ asked }) => asked));
|
|
226
|
-
const answered = await transport.door(DOOR_BOOTSTRAP, {
|
|
227
|
-
prefixes: part.map(({ entry }) => authorityRoot(entry.handle)),
|
|
228
|
-
...(held.length === 0 ? {} : { held }),
|
|
229
|
-
});
|
|
230
|
-
const classified = part.map(({ entry }) => classifyDoor(answered.status, answered.body, entry.locator));
|
|
231
|
-
const parted = classified[0] === null ? parseParted(answered.body) : null;
|
|
232
|
-
for (const [index, asked] of part.entries()) {
|
|
233
|
-
const failure = classified[index];
|
|
234
|
-
if (failure !== null && failure !== undefined) {
|
|
235
|
-
answer(asked.ask, failure);
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
if (parted === null) {
|
|
239
|
-
answer(asked.ask, UNCERTAIN_READ);
|
|
240
|
-
continue;
|
|
241
|
-
}
|
|
242
|
-
const room = parted.rooms.find((candidate) => candidate.anchor === asked.entry.authority);
|
|
243
|
-
if (room === undefined && parted.next !== undefined) {
|
|
244
|
-
unreached.push(asked);
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
if (room === undefined) {
|
|
248
|
-
answer(asked.ask, { kind: 'room-not-readable', locator: asked.entry.locator });
|
|
249
|
-
continue;
|
|
250
|
-
}
|
|
251
|
-
const kept = held.find((files) => files.room === asked.entry.authority);
|
|
252
|
-
answer(asked.ask, await partPage(asked.asked, {
|
|
253
|
-
room,
|
|
254
|
-
next: 0,
|
|
255
|
-
seen: [],
|
|
256
|
-
...(kept === undefined ? {} : { held: kept }),
|
|
257
|
-
}));
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
open = unreached;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
function layered(asks) {
|
|
264
|
-
const depths = new Map();
|
|
265
|
-
const layers = [];
|
|
266
|
-
for (const ask of asks) {
|
|
267
|
-
const depth = depths.get(ask.ask.entry.authority) ?? 0;
|
|
268
|
-
depths.set(ask.ask.entry.authority, depth + 1);
|
|
269
|
-
(layers[depth] ??= []).push(ask);
|
|
270
|
-
}
|
|
271
|
-
return layers;
|
|
272
|
-
}
|
|
273
|
-
async function enumerated(asks) {
|
|
274
|
-
const answers = [];
|
|
275
|
-
const parts = layered(asks.map((ask, index) => ({ ask, index }))).flatMap((layer) => selections(layer, declared().max_prefixes));
|
|
276
|
-
for (const part of parts) {
|
|
277
|
-
let open = [...part];
|
|
278
|
-
while (open.length > 0) {
|
|
279
|
-
const answer = await transport.door(DOOR_ENUMERATE, {
|
|
280
|
-
prefixes: open.map(({ ask }) => authorityRoot(ask.entry.handle)),
|
|
281
|
-
positions: open.map(({ ask }) => presented(ask.entry.authority, ask.from)),
|
|
282
|
-
});
|
|
283
|
-
const classified = open.map(({ ask }) => classifyRead(answer.status, answer.body, ask.entry.locator));
|
|
284
|
-
if (classified[0]?.kind === 'beyond-horizon') {
|
|
285
|
-
const named = doorRefusal(answer.body)?.fields.authority;
|
|
286
|
-
const expired = open.filter(({ ask }) => ask.entry.authority === named);
|
|
287
|
-
const answered = expired.length === 0 ? UNCERTAIN_READ : { kind: 'beyond-horizon' };
|
|
288
|
-
const gone = expired.length === 0 ? open : expired;
|
|
289
|
-
for (const ask of gone)
|
|
290
|
-
answers[ask.index] = answered;
|
|
291
|
-
open = open.filter((ask) => !gone.includes(ask));
|
|
292
|
-
continue;
|
|
293
|
-
}
|
|
294
|
-
const enumeration = classified[0] === null ? parseEnumeration(answer.body, 'credential') : null;
|
|
295
|
-
for (const [answerIndex, { ask, index }] of open.entries()) {
|
|
296
|
-
const failure = classified[answerIndex];
|
|
297
|
-
if (failure !== null && failure !== undefined) {
|
|
298
|
-
answers[index] = failure;
|
|
299
|
-
continue;
|
|
300
|
-
}
|
|
301
|
-
answers[index] =
|
|
302
|
-
enumeration === null ? UNCERTAIN_READ : await enumeratedRoom(enumeration, ask);
|
|
303
|
-
}
|
|
304
|
-
open = [];
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
return answers;
|
|
308
|
-
}
|
|
309
|
-
const bootstrapTogether = gatheredEach(bootstrapped);
|
|
310
|
-
const enumerateTogether = gathered(enumerated);
|
|
311
157
|
async function uploaded(head, changes, delta, bytes, entry, handed, keep) {
|
|
312
158
|
const paths = batchPaths(changes);
|
|
313
159
|
const sha256 = await deltaDigest(delta);
|
|
314
160
|
if (handed !== undefined && handed.sha256 === sha256) {
|
|
315
161
|
return { body: { ...head, paths, upload: handed, runtime: notifications.runtime } };
|
|
316
162
|
}
|
|
317
|
-
const minted = await transport.door(
|
|
163
|
+
const minted = await transport.door(houseDoorRoute('batch-upload'), {
|
|
164
|
+
...head,
|
|
165
|
+
paths,
|
|
166
|
+
bytes,
|
|
167
|
+
sha256,
|
|
168
|
+
});
|
|
318
169
|
if (minted.status !== 200) {
|
|
319
170
|
return {
|
|
320
171
|
outcome: await stepped(mutationOutcome(minted.status, minted.body, entry.locator, entry.handle)),
|
|
@@ -362,11 +213,11 @@ export function createAgentsHouseAdapter(options) {
|
|
|
362
213
|
: { body: inline };
|
|
363
214
|
if ('outcome' in prepared)
|
|
364
215
|
return prepared.outcome;
|
|
365
|
-
const answer = await transport.door(
|
|
216
|
+
const answer = await transport.door(houseDoorRoute('batch'), prepared.body);
|
|
366
217
|
const stagedFiles = await staged(answer, request);
|
|
367
218
|
if (stagedFiles === false)
|
|
368
219
|
return UNCERTAIN;
|
|
369
|
-
const settled = stagedFiles === null ? answer : await transport.door(
|
|
220
|
+
const settled = stagedFiles === null ? answer : await transport.door(houseDoorRoute('batch'), prepared.body);
|
|
370
221
|
if (stagedFiles === true && (await staged(settled, request)) !== null)
|
|
371
222
|
return UNCERTAIN;
|
|
372
223
|
return stepped(mutationOutcome(settled.status, settled.body, entry.locator, entry.handle, into === undefined
|
|
@@ -394,9 +245,22 @@ export function createAgentsHouseAdapter(options) {
|
|
|
394
245
|
function linked(answer, locator) {
|
|
395
246
|
const address = addressed(answer, locator);
|
|
396
247
|
return address.kind === 'address'
|
|
397
|
-
? { kind: 'link', url: address.url, name: address.name }
|
|
248
|
+
? { kind: 'link', url: address.url, name: address.name, mediaType: address.mediaType }
|
|
398
249
|
: address;
|
|
399
250
|
}
|
|
251
|
+
function refusedAttach(answer, locator) {
|
|
252
|
+
const failure = classifyDoor(answer.status, answer.body, locator);
|
|
253
|
+
if (failure === null)
|
|
254
|
+
return null;
|
|
255
|
+
return failure.kind === 'scoped-refusal'
|
|
256
|
+
? {
|
|
257
|
+
kind: 'rejected',
|
|
258
|
+
code: failure.code,
|
|
259
|
+
fields: failure.fields,
|
|
260
|
+
retryable: failure.retryable,
|
|
261
|
+
}
|
|
262
|
+
: failure;
|
|
263
|
+
}
|
|
400
264
|
async function downloaded(ask, locator) {
|
|
401
265
|
let address = addressed(await ask(), locator);
|
|
402
266
|
if (address.kind !== 'address')
|
|
@@ -421,7 +285,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
421
285
|
const entry = authorityFor(request.locator);
|
|
422
286
|
if (entry === undefined)
|
|
423
287
|
return null;
|
|
424
|
-
return () => transport.door(
|
|
288
|
+
return () => transport.door(houseDoorRoute('files/get'), {
|
|
425
289
|
room_ref: entry.authority,
|
|
426
290
|
path: request.path,
|
|
427
291
|
revision: request.revision,
|
|
@@ -429,72 +293,20 @@ export function createAgentsHouseAdapter(options) {
|
|
|
429
293
|
}
|
|
430
294
|
return {
|
|
431
295
|
roomTypes: HOUSE_ROOM_TYPES,
|
|
296
|
+
nameableRoomTypes: HOUSE_NAMEABLE_ROOM_TYPES,
|
|
297
|
+
typedPaths: HOUSE_TYPED_PATHS,
|
|
432
298
|
async authorize() {
|
|
433
299
|
return options.authorize();
|
|
434
300
|
},
|
|
435
|
-
async discover(_authorization, scope) {
|
|
436
|
-
const answer = await transport.door(DOOR_DISCOVER, {
|
|
437
|
-
prefixes: [...DISCOVER_PREFIXES],
|
|
438
|
-
...(scope === undefined ? {} : { rooms: scope.authorities }),
|
|
439
|
-
});
|
|
440
|
-
const failed = discoveryFailure(answer.status, answer.body);
|
|
441
|
-
if (failed !== null)
|
|
442
|
-
return failed;
|
|
443
|
-
const document = parseDiscovery(answer.body);
|
|
444
|
-
if (document === null)
|
|
445
|
-
return { kind: 'transport-uncertainty' };
|
|
446
|
-
bounds = document.bounds;
|
|
447
|
-
const entries = trackedFrom(document);
|
|
448
|
-
const covered = scope === undefined
|
|
449
|
-
? null
|
|
450
|
-
: [
|
|
451
|
-
...new Set([
|
|
452
|
-
...[...tracked.values()]
|
|
453
|
-
.filter((entry) => scope.authorities.includes(entry.authority))
|
|
454
|
-
.map((entry) => entry.locator),
|
|
455
|
-
...entries.map((entry) => entry.locator),
|
|
456
|
-
]),
|
|
457
|
-
];
|
|
458
|
-
if (covered === null)
|
|
459
|
-
tracked.clear();
|
|
460
|
-
else
|
|
461
|
-
for (const locator of covered)
|
|
462
|
-
tracked.delete(locator);
|
|
463
|
-
for (const entry of entries)
|
|
464
|
-
tracked.set(entry.locator, entry);
|
|
465
|
-
for (const locator of handed.keys())
|
|
466
|
-
if (!tracked.has(locator))
|
|
467
|
-
handed.delete(locator);
|
|
468
|
-
notifications.track([...tracked.values()]);
|
|
469
|
-
return {
|
|
470
|
-
...mapDiscovery(document, document.authorities.map((authority) => discoveredRoom(authority)), capabilities(document.actions, [...tracked.values()])),
|
|
471
|
-
member: document.member,
|
|
472
|
-
...(covered === null ? {} : { covered }),
|
|
473
|
-
};
|
|
474
|
-
},
|
|
475
301
|
async bootstrap(_authorization, request) {
|
|
476
302
|
const entry = authorityFor(request.locator);
|
|
477
303
|
if (entry === undefined)
|
|
478
304
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
},
|
|
485
|
-
async refresh(_authorization, request) {
|
|
486
|
-
const entry = authorityFor(request.locator);
|
|
487
|
-
if (entry === undefined)
|
|
488
|
-
return { kind: 'room-not-readable', locator: request.locator };
|
|
489
|
-
if (request.pageToken !== undefined)
|
|
490
|
-
return { kind: 'transport-uncertainty' };
|
|
491
|
-
const from = logPosition(request.fromRoomVersion);
|
|
492
|
-
if (from === null)
|
|
493
|
-
return { kind: 'beyond-horizon' };
|
|
494
|
-
const answered = await streamed(entry, request, from);
|
|
495
|
-
if (answered !== null)
|
|
496
|
-
return answered;
|
|
497
|
-
return enumerateTogether({ entry, from, fromRoomVersion: request.fromRoomVersion });
|
|
305
|
+
if (request.path !== undefined)
|
|
306
|
+
return namedDocument(entry, request.path, request.signal);
|
|
307
|
+
return request.pageToken === undefined
|
|
308
|
+
? openedRoom(entry, request)
|
|
309
|
+
: streamedPage(entry, request.pageToken, request.held);
|
|
498
310
|
},
|
|
499
311
|
async mutate(_authorization, request, keep) {
|
|
500
312
|
const entry = authorityFor(request.locator);
|
|
@@ -511,22 +323,21 @@ export function createAgentsHouseAdapter(options) {
|
|
|
511
323
|
: houseMove(batch, entry.handle, into.handle);
|
|
512
324
|
if (mapped.kind === 'unmapped')
|
|
513
325
|
return rejectedMapping(mapped);
|
|
514
|
-
const head = operationHead(batch);
|
|
326
|
+
const head = operationHead(batch, entry.authority);
|
|
515
327
|
const delta = deltaBody(mapped.changes);
|
|
516
328
|
const bytes = deltaBytes(delta);
|
|
517
329
|
const handed = request.upload;
|
|
518
330
|
const answer = (upload) => submit(request, head, mapped.changes, delta, bytes, entry, upload, keep, into);
|
|
519
|
-
const settle = (outcome) => into === undefined ? adopted(entry, outcome) : adoptedMove(entry, into, outcome);
|
|
520
331
|
const outcome = await answer(handed);
|
|
521
332
|
if (handed === undefined || !lapsedGrant(outcome))
|
|
522
|
-
return
|
|
523
|
-
return
|
|
333
|
+
return outcome;
|
|
334
|
+
return answer(undefined);
|
|
524
335
|
},
|
|
525
336
|
async history(_authorization, request) {
|
|
526
337
|
const entry = authorityFor(request.locator);
|
|
527
338
|
if (entry === undefined)
|
|
528
339
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
529
|
-
const answer = await transport.door(
|
|
340
|
+
const answer = await transport.door(houseDoorRoute('revisions'), revisionBody({
|
|
530
341
|
path: request.path,
|
|
531
342
|
handle: entry.handle,
|
|
532
343
|
...(request.revision === undefined ? {} : { revision: request.revision }),
|
|
@@ -538,17 +349,10 @@ export function createAgentsHouseAdapter(options) {
|
|
|
538
349
|
});
|
|
539
350
|
},
|
|
540
351
|
async binary(_authorization, request) {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
return downloaded(ask, request.locator);
|
|
546
|
-
}
|
|
547
|
-
const referrer = houseReferrer(request.referrer, tracked);
|
|
548
|
-
if (referrer === null) {
|
|
549
|
-
return { kind: 'rejected', code: 'referrer_unknown', fields: {}, retryable: false };
|
|
550
|
-
}
|
|
551
|
-
return downloaded(() => transport.door(DOOR_FILES_GET, { file: request.fileRef, referrer: referrer.referrer }), referrer.locator);
|
|
352
|
+
const ask = pathAddress(request);
|
|
353
|
+
if (ask === null)
|
|
354
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
355
|
+
return downloaded(ask, request.locator);
|
|
552
356
|
},
|
|
553
357
|
async link(_authorization, request) {
|
|
554
358
|
const ask = pathAddress(request);
|
|
@@ -556,8 +360,34 @@ export function createAgentsHouseAdapter(options) {
|
|
|
556
360
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
557
361
|
return linked(await ask(), request.locator);
|
|
558
362
|
},
|
|
559
|
-
|
|
560
|
-
|
|
363
|
+
async attach(_authorization, request) {
|
|
364
|
+
const entry = authorityFor(request.locator);
|
|
365
|
+
if (entry === undefined)
|
|
366
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
367
|
+
const declared = await transport.door(houseDoorRoute('files/attach'), {
|
|
368
|
+
room_ref: entry.authority,
|
|
369
|
+
name: request.name,
|
|
370
|
+
bytes: request.byteLength,
|
|
371
|
+
sha256: request.sha256,
|
|
372
|
+
media_type: request.mediaType.length > 0 ? request.mediaType : OCTET_STREAM,
|
|
373
|
+
});
|
|
374
|
+
const refused = refusedAttach(declared, request.locator);
|
|
375
|
+
if (refused !== null)
|
|
376
|
+
return refused;
|
|
377
|
+
const upload = houseUpload(declared.body?.upload);
|
|
378
|
+
if (upload === null)
|
|
379
|
+
return UNCERTAIN_READ;
|
|
380
|
+
const finished = await finishedUpload(transport, upload, request.blob);
|
|
381
|
+
if (finished === null)
|
|
382
|
+
return UNCERTAIN_READ;
|
|
383
|
+
const unfinished = refusedAttach(finished, request.locator);
|
|
384
|
+
if (unfinished !== null)
|
|
385
|
+
return unfinished;
|
|
386
|
+
const { path, revision } = (finished.body ?? {});
|
|
387
|
+
const root = `/rooms/${entry.handle}/`;
|
|
388
|
+
return typeof path === 'string' && path.startsWith(root) && typeof revision === 'string'
|
|
389
|
+
? { kind: 'attached', path: path.slice(root.length), revision }
|
|
390
|
+
: UNCERTAIN_READ;
|
|
561
391
|
},
|
|
562
392
|
reached(locator, version, target) {
|
|
563
393
|
return reachedVersion(version, target, authorityFor(locator)?.logEpoch);
|
|
@@ -568,18 +398,12 @@ export function createAgentsHouseAdapter(options) {
|
|
|
568
398
|
async action(_authorization, request) {
|
|
569
399
|
return withAt(await houseAction(transport, request));
|
|
570
400
|
},
|
|
401
|
+
search(_authorization, request) {
|
|
402
|
+
return houseSearch(transport, [...tracked.values()], request);
|
|
403
|
+
},
|
|
571
404
|
roomStream: {
|
|
572
405
|
hold: held,
|
|
573
|
-
|
|
574
|
-
observe(notify, receipts, revisions) {
|
|
575
|
-
heldRevisions = revisions;
|
|
576
|
-
return notifications.observe(notify, receipts);
|
|
577
|
-
},
|
|
578
|
-
published(locator, roomVersion) {
|
|
579
|
-
const at = logPosition(roomVersion);
|
|
580
|
-
if (at !== null)
|
|
581
|
-
notifications.published(locator, at);
|
|
582
|
-
},
|
|
406
|
+
observe: notifications.observe,
|
|
583
407
|
},
|
|
584
408
|
conversations: notifications.conversations,
|
|
585
409
|
serviceMode: notifications.serviceMode,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-reference.d.ts","sourceRoot":"","sources":["../src/app-reference.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,qBAAqB,QAEjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crockford.d.ts","sourceRoot":"","sources":["../src/crockford.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AAErE,eAAO,MAAM,mBAAmB,uCAA4B,CAAC;AAE7D,eAAO,MAAM,2BAA2B,QAAqC,CAAC"}
|