@agentshouse/mdruntime-adapter 0.1.0-alpha.9 → 0.1.0-c506c7d6e6199
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 +156 -27
- package/README.md +32 -0
- package/dist/actions.d.ts +4 -12
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +239 -332
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +271 -197
- package/dist/digest.js +1 -5
- package/dist/discovery.d.ts +22 -26
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +154 -223
- package/dist/gather.d.ts +3 -0
- package/dist/gather.d.ts.map +1 -0
- package/dist/gather.js +40 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/links.d.ts +12 -0
- package/dist/links.d.ts.map +1 -0
- package/dist/links.js +66 -0
- package/dist/map.d.ts +2 -2
- package/dist/map.d.ts.map +1 -1
- package/dist/map.js +6 -7
- package/dist/model.d.ts +2 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +21 -39
- package/dist/read.d.ts +31 -26
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +208 -199
- package/dist/refusal.d.ts +3 -1
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +27 -62
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +110 -124
- package/dist/stream.d.ts +11 -5
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +209 -213
- package/dist/transport.d.ts +45 -28
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +2 -3
- package/dist/version.d.ts +1 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +23 -18
- package/dist/write.d.ts +5 -7
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +127 -215
- package/package.json +4 -12
- package/dist/actions.js.map +0 -1
- package/dist/adapter.js.map +0 -1
- package/dist/digest.js.map +0 -1
- package/dist/discovery.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/map.js.map +0 -1
- package/dist/model.js.map +0 -1
- package/dist/read.js.map +0 -1
- package/dist/refusal.js.map +0 -1
- package/dist/site.js.map +0 -1
- package/dist/stream.js.map +0 -1
- package/dist/transport.js.map +0 -1
- package/dist/version.js.map +0 -1
- package/dist/write.js.map +0 -1
package/dist/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,OAAO,EACP,aAAa,EAad,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,OAAO,EACP,aAAa,EAad,MAAM,wBAAwB,CAAC;AAyChC,OAAO,EAQL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AAuBxB,MAAM,MAAM,yBAAyB,GACjC;IACE,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;CACrC,GACD;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAiCjC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CA2ZpF"}
|
package/dist/adapter.js
CHANGED
|
@@ -1,61 +1,96 @@
|
|
|
1
|
-
import { DISCOVER_PREFIXES,
|
|
2
|
-
import { MODEL_ABSENT, failedModel, heldModel, modelKey, modelShelf } from './model.js';
|
|
1
|
+
import { DISCOVER_PREFIXES, capabilities, discoveredRoom, locatorOf, mapDiscovery, parseDiscovery, trackedFrom, } from './discovery.js';
|
|
2
|
+
import { MODEL_ABSENT, failedModel, heldModel, modelKey, modelShelf, } from './model.js';
|
|
3
|
+
import { gathered, selections } from './gather.js';
|
|
3
4
|
import { createSiteAdapter } from './site.js';
|
|
4
|
-
import {
|
|
5
|
+
import { bootstrapOf, contentPrefixes, matchesScope, parseEnumeration, parseEnvelope, parseGrant, refreshFrom, schemaFrom, schemaPath, viewOf, } from './read.js';
|
|
6
|
+
import { enumeratedLinks, scopeLinks, streamedLinks } from './links.js';
|
|
5
7
|
import { houseAction } from './actions.js';
|
|
6
|
-
import { classifyDoor, discoveryFailure } from './refusal.js';
|
|
8
|
+
import { classifyDoor, discoveryFailure, doorRefusal } from './refusal.js';
|
|
7
9
|
import { houseNotifications } from './stream.js';
|
|
8
|
-
import { DOOR_BATCH, DOOR_BATCH_UPLOAD, DOOR_BOOTSTRAP, DOOR_DISCOVER, DOOR_ENUMERATE, DOOR_REVISIONS,
|
|
9
|
-
import { batchPaths, deltaBody, deltaBytes, deltaDigest, historyOutcome, houseChanges, mutationOutcome, operationHead, rejectedMapping, revisionBody, uploadable } from './write.js';
|
|
10
|
-
import { logPosition, presented } from './version.js';
|
|
11
|
-
const UNCERTAIN = {
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
const RESOLVED_OUTCOMES = new Set([
|
|
15
|
-
'accepted',
|
|
16
|
-
'conflicted',
|
|
17
|
-
'rejected',
|
|
18
|
-
'expired'
|
|
19
|
-
]);
|
|
10
|
+
import { DOOR_BATCH, DOOR_BATCH_UPLOAD, DOOR_BOOTSTRAP, DOOR_DISCOVER, DOOR_ENUMERATE, DOOR_REVISIONS, PRIVATE_LOCATOR, } from './transport.js';
|
|
11
|
+
import { batchPaths, deltaBody, deltaBytes, deltaDigest, historyOutcome, houseChanges, mutationOutcome, operationHead, rejectedMapping, revisionBody, uploadable, } from './write.js';
|
|
12
|
+
import { logPosition, presented, reachedVersion, roomVersion, } from './version.js';
|
|
13
|
+
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
14
|
+
const UNCERTAIN_READ = { kind: 'transport-uncertainty' };
|
|
20
15
|
function lapsedGrant(outcome) {
|
|
21
16
|
return outcome.kind === 'rejected' && outcome.code === 'upload_unavailable';
|
|
22
17
|
}
|
|
23
18
|
function modelFailure(classified, envelope) {
|
|
24
19
|
if (classified === null) {
|
|
25
|
-
return envelope === null ? {
|
|
26
|
-
kind: 'transport-uncertainty'
|
|
27
|
-
} : MODEL_ABSENT;
|
|
20
|
+
return envelope === null ? { kind: 'transport-uncertainty' } : MODEL_ABSENT;
|
|
28
21
|
}
|
|
29
22
|
return failedModel(classified);
|
|
30
23
|
}
|
|
31
24
|
export function createAgentsHouseAdapter(options) {
|
|
32
|
-
if ('site' in options)
|
|
25
|
+
if ('site' in options)
|
|
26
|
+
return createSiteAdapter(options.site);
|
|
33
27
|
const transport = options.transport;
|
|
34
28
|
const notifications = houseNotifications(transport, 'credential');
|
|
35
29
|
const tracked = new Map();
|
|
30
|
+
const handed = new Map();
|
|
36
31
|
const models = modelShelf();
|
|
37
|
-
|
|
38
|
-
function
|
|
39
|
-
|
|
32
|
+
let bounds;
|
|
33
|
+
function declared() {
|
|
34
|
+
if (bounds === undefined)
|
|
35
|
+
throw new Error('no Discovery declared the bounds');
|
|
36
|
+
return bounds;
|
|
37
|
+
}
|
|
38
|
+
function bootstrappedRoom(envelope, entry) {
|
|
39
|
+
const scope = envelope.scopes.find((candidate) => matchesScope(candidate, entry));
|
|
40
|
+
if (scope === undefined)
|
|
41
|
+
return { kind: 'room-not-readable', locator: entry.locator };
|
|
42
|
+
handed.set(entry.locator, scopeLinks(scope));
|
|
43
|
+
notifications.hold(entry.authority, scope);
|
|
44
|
+
return bootstrapOf(scope);
|
|
45
|
+
}
|
|
46
|
+
function enumeratedRoom(enumeration, ask) {
|
|
47
|
+
const view = viewOf(enumeration, ask.entry);
|
|
48
|
+
if (view === undefined)
|
|
49
|
+
return { kind: 'room-not-readable', locator: ask.entry.locator };
|
|
50
|
+
notifications.hold(ask.entry.authority, view);
|
|
51
|
+
const answer = refreshFrom(view, ask.fromRoomVersion);
|
|
52
|
+
if (answer.kind === 'net-advancement') {
|
|
53
|
+
handed.set(ask.entry.locator, enumeratedLinks(view, handed.get(ask.entry.locator)));
|
|
54
|
+
}
|
|
55
|
+
return answer;
|
|
56
|
+
}
|
|
57
|
+
function streamed(entry, request, from) {
|
|
58
|
+
const links = handed.get(entry.locator);
|
|
59
|
+
if (links?.roomVersion !== request.fromRoomVersion)
|
|
60
|
+
return null;
|
|
61
|
+
const advanced = notifications.advance(entry, from, (path, revision) => links.revisions.get(path) === revision);
|
|
62
|
+
if (advanced === null)
|
|
63
|
+
return null;
|
|
64
|
+
if (request.minPosition !== undefined &&
|
|
65
|
+
!reachedVersion(advanced.page.roomVersion, request.minPosition, entry.logEpoch))
|
|
66
|
+
return null;
|
|
67
|
+
const relinked = streamedLinks(links, advanced);
|
|
68
|
+
if (relinked === null)
|
|
69
|
+
return null;
|
|
70
|
+
handed.set(entry.locator, relinked);
|
|
71
|
+
return advanced.page;
|
|
72
|
+
}
|
|
73
|
+
function held(envelope, entry, schema, failure) {
|
|
74
|
+
return heldModel(envelope === null ? null : schemaFrom(envelope, entry, schema), schemaPath(entry.handle, schema), failure);
|
|
75
|
+
}
|
|
76
|
+
function modelPrefixes(entry) {
|
|
77
|
+
return entry.schemas.map((schema) => schemaPath(entry.handle, schema));
|
|
40
78
|
}
|
|
41
79
|
async function acquireModels(entries) {
|
|
42
80
|
const acquired = new Map();
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
if (privateEntry !== undefined) {
|
|
58
|
-
acquired.set(modelKey(privateEntry.locator, 'typed-selection'), await held(envelope, privateEntry, PROVIDER_SELECTION_MODEL_ROOT, `${authorityRoot(undefined)}/${PROVIDER_SELECTION_MODEL_ROOT}`, failure));
|
|
81
|
+
for (const part of selections(entries, (entry) => modelPrefixes(entry).length, declared().max_prefixes)) {
|
|
82
|
+
const answer = await transport.door(DOOR_BOOTSTRAP, {
|
|
83
|
+
prefixes: part.flatMap((entry) => modelPrefixes(entry)),
|
|
84
|
+
});
|
|
85
|
+
const classified = classifyDoor(answer.status, answer.body, PRIVATE_LOCATOR);
|
|
86
|
+
const envelope = classified === null ? parseEnvelope(await bundled(answer.body)) : null;
|
|
87
|
+
const failure = modelFailure(classified, envelope);
|
|
88
|
+
for (const entry of part) {
|
|
89
|
+
acquired.set(modelKey(entry.locator, 'collection'), await held(envelope, entry, entry.schema, failure));
|
|
90
|
+
if (entry.houseModel === null)
|
|
91
|
+
continue;
|
|
92
|
+
acquired.set(modelKey(entry.locator, 'typed-selection'), await held(envelope, entry, entry.houseModel.root, failure));
|
|
93
|
+
}
|
|
59
94
|
}
|
|
60
95
|
return acquired;
|
|
61
96
|
}
|
|
@@ -63,223 +98,262 @@ export function createAgentsHouseAdapter(options) {
|
|
|
63
98
|
const locator = locatorOf(authority);
|
|
64
99
|
const key = modelKey(locator, 'collection');
|
|
65
100
|
const collection = models.retain(key, acquired.get(key));
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return discoveredRoom(authority, collection?.identity ?? null, providerSelection(selection?.identity ?? null));
|
|
101
|
+
const selection = authority.houseModel === null
|
|
102
|
+
? undefined
|
|
103
|
+
: models.retain(modelKey(locator, 'typed-selection'), acquired.get(modelKey(locator, 'typed-selection')));
|
|
104
|
+
return discoveredRoom(authority, collection?.identity ?? null, selection?.identity ?? null);
|
|
71
105
|
}
|
|
72
106
|
function authorityFor(locator) {
|
|
73
107
|
return tracked.get(locator);
|
|
74
108
|
}
|
|
109
|
+
function withAt(result) {
|
|
110
|
+
if (result.kind !== 'action')
|
|
111
|
+
return result;
|
|
112
|
+
const body = result.result;
|
|
113
|
+
if (typeof body !== 'object' || body === null)
|
|
114
|
+
return result;
|
|
115
|
+
const { authority, position, log_epoch: logEpoch } = body;
|
|
116
|
+
if (typeof position !== 'string' || typeof logEpoch !== 'string')
|
|
117
|
+
return result;
|
|
118
|
+
const locator = authority === undefined
|
|
119
|
+
? PRIVATE_LOCATOR
|
|
120
|
+
: [...tracked.values()].find((entry) => entry.authority === authority)?.locator;
|
|
121
|
+
if (locator === undefined)
|
|
122
|
+
return result;
|
|
123
|
+
return { ...result, at: { locator, roomVersion: roomVersion({ position, logEpoch }) } };
|
|
124
|
+
}
|
|
75
125
|
async function bundled(body) {
|
|
76
126
|
const grant = parseGrant(body);
|
|
77
|
-
if (grant === null)
|
|
78
|
-
|
|
127
|
+
if (grant === null)
|
|
128
|
+
return body;
|
|
129
|
+
if (grant.method !== 'GET')
|
|
130
|
+
return null;
|
|
79
131
|
const answer = await transport.transfer({
|
|
80
|
-
act: '
|
|
132
|
+
act: 'local_copy_bundle',
|
|
81
133
|
method: 'GET',
|
|
82
|
-
url: grant.url
|
|
134
|
+
url: grant.url,
|
|
135
|
+
answer: 'json',
|
|
83
136
|
});
|
|
84
137
|
return answer.status === 200 ? answer.body : null;
|
|
85
138
|
}
|
|
86
|
-
|
|
139
|
+
function weight(entry) {
|
|
140
|
+
return contentPrefixes(entry).length;
|
|
141
|
+
}
|
|
142
|
+
async function bootstrapped(entries) {
|
|
143
|
+
const answers = [];
|
|
144
|
+
for (const part of selections(entries, weight, declared().max_prefixes)) {
|
|
145
|
+
const answer = await transport.door(DOOR_BOOTSTRAP, {
|
|
146
|
+
prefixes: part.flatMap((entry) => contentPrefixes(entry)),
|
|
147
|
+
});
|
|
148
|
+
const classified = part.map((entry) => classifyDoor(answer.status, answer.body, entry.locator));
|
|
149
|
+
const envelope = classified[0] === null ? parseEnvelope(await bundled(answer.body)) : null;
|
|
150
|
+
part.forEach((entry, index) => {
|
|
151
|
+
const failure = classified[index];
|
|
152
|
+
if (failure === null || failure === undefined) {
|
|
153
|
+
answers.push(envelope === null ? UNCERTAIN_READ : bootstrappedRoom(envelope, entry));
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
answers.push(failure.kind === 'beyond-horizon' ? UNCERTAIN_READ : failure);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return answers;
|
|
160
|
+
}
|
|
161
|
+
function layered(asks) {
|
|
162
|
+
const depths = new Map();
|
|
163
|
+
const layers = [];
|
|
164
|
+
for (const ask of asks) {
|
|
165
|
+
const depth = depths.get(ask.entry.authority) ?? 0;
|
|
166
|
+
depths.set(ask.entry.authority, depth + 1);
|
|
167
|
+
(layers[depth] ??= []).push(ask);
|
|
168
|
+
}
|
|
169
|
+
return layers;
|
|
170
|
+
}
|
|
171
|
+
async function enumerated(asks) {
|
|
172
|
+
const answers = new Map();
|
|
173
|
+
const parts = layered(asks).flatMap((layer) => selections(layer, (ask) => weight(ask.entry), declared().max_prefixes));
|
|
174
|
+
for (const part of parts) {
|
|
175
|
+
let open = [...part];
|
|
176
|
+
while (open.length > 0) {
|
|
177
|
+
const answer = await transport.door(DOOR_ENUMERATE, {
|
|
178
|
+
prefixes: open.flatMap((ask) => contentPrefixes(ask.entry)),
|
|
179
|
+
positions: open.map((ask) => ({
|
|
180
|
+
...presented(ask.entry.authority, ask.from),
|
|
181
|
+
...(ask.minPosition === undefined ? {} : { min_position: ask.minPosition }),
|
|
182
|
+
})),
|
|
183
|
+
});
|
|
184
|
+
const refusal = doorRefusal(answer.body);
|
|
185
|
+
if (refusal?.code === 'replica_behind') {
|
|
186
|
+
const named = open.filter((ask) => ask.entry.authority === refusal.fields.authority);
|
|
187
|
+
const behind = named.length === 0 ? open : named;
|
|
188
|
+
for (const ask of behind) {
|
|
189
|
+
answers.set(ask, refusal.retryable
|
|
190
|
+
? { kind: 'retryable-refusal', code: refusal.code, fields: refusal.fields }
|
|
191
|
+
: (classifyDoor(answer.status, answer.body, ask.entry.locator) ?? UNCERTAIN_READ));
|
|
192
|
+
}
|
|
193
|
+
open = open.filter((ask) => !behind.includes(ask));
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
const classified = open.map((ask) => classifyDoor(answer.status, answer.body, ask.entry.locator));
|
|
197
|
+
if (classified[0]?.kind === 'beyond-horizon') {
|
|
198
|
+
const named = doorRefusal(answer.body)?.fields.authority;
|
|
199
|
+
const expired = open.filter((ask) => ask.entry.authority === named);
|
|
200
|
+
const answered = expired.length === 0 ? UNCERTAIN_READ : { kind: 'beyond-horizon' };
|
|
201
|
+
const gone = expired.length === 0 ? open : expired;
|
|
202
|
+
for (const ask of gone)
|
|
203
|
+
answers.set(ask, answered);
|
|
204
|
+
open = open.filter((ask) => !gone.includes(ask));
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const enumeration = classified[0] === null ? parseEnumeration(answer.body, 'credential') : null;
|
|
208
|
+
open.forEach((ask, index) => {
|
|
209
|
+
const failure = classified[index];
|
|
210
|
+
if (failure !== null && failure !== undefined) {
|
|
211
|
+
answers.set(ask, failure);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
answers.set(ask, enumeration === null ? UNCERTAIN_READ : enumeratedRoom(enumeration, ask));
|
|
215
|
+
});
|
|
216
|
+
open = [];
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return asks.map((ask) => answers.get(ask) ?? UNCERTAIN_READ);
|
|
220
|
+
}
|
|
221
|
+
const bootstrapTogether = gathered(bootstrapped);
|
|
222
|
+
const enumerateTogether = gathered(enumerated);
|
|
223
|
+
async function uploaded(head, changes, delta, bytes, entry, handed, keep) {
|
|
87
224
|
const paths = batchPaths(changes);
|
|
88
225
|
const sha256 = await deltaDigest(delta);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
};
|
|
93
|
-
const minted = await transport.door(DOOR_BATCH_UPLOAD, {
|
|
94
|
-
...head,
|
|
95
|
-
paths,
|
|
96
|
-
bytes,
|
|
97
|
-
sha256
|
|
98
|
-
});
|
|
226
|
+
if (handed !== undefined && handed.sha256 === sha256) {
|
|
227
|
+
return { body: { ...head, paths, upload: handed } };
|
|
228
|
+
}
|
|
229
|
+
const minted = await transport.door(DOOR_BATCH_UPLOAD, { ...head, paths, bytes, sha256 });
|
|
99
230
|
if (minted.status !== 200) {
|
|
100
|
-
return {
|
|
101
|
-
outcome: mutationOutcome(minted.status, minted.body, entry.locator, entry.handle)
|
|
102
|
-
};
|
|
231
|
+
return { outcome: mutationOutcome(minted.status, minted.body, entry.locator, entry.handle) };
|
|
103
232
|
}
|
|
104
233
|
const grant = parseGrant(minted.body);
|
|
105
|
-
if (grant === null || grant.method !== 'POST')
|
|
106
|
-
outcome: UNCERTAIN
|
|
107
|
-
};
|
|
234
|
+
if (grant === null || grant.method !== 'POST')
|
|
235
|
+
return { outcome: UNCERTAIN };
|
|
108
236
|
const delivered = await transport.transfer({
|
|
109
237
|
act: 'authored_batch_upload',
|
|
110
238
|
method: 'POST',
|
|
111
239
|
url: grant.url,
|
|
112
|
-
|
|
240
|
+
answer: 'json',
|
|
241
|
+
body: `${grant.operation}\n${delta}`,
|
|
113
242
|
});
|
|
114
|
-
if (delivered.status !== 200)
|
|
115
|
-
outcome: UNCERTAIN
|
|
116
|
-
};
|
|
243
|
+
if (delivered.status !== 200)
|
|
244
|
+
return { outcome: UNCERTAIN };
|
|
117
245
|
const holding = parseGrant(delivered.body);
|
|
118
|
-
if (holding === null
|
|
119
|
-
outcome: UNCERTAIN
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
paths,
|
|
124
|
-
upload: {
|
|
125
|
-
url: holding.url,
|
|
126
|
-
operation: holding.operation,
|
|
127
|
-
bytes,
|
|
128
|
-
sha256
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
submissions.set(head.operation_id, {
|
|
132
|
-
sha256,
|
|
133
|
-
body
|
|
134
|
-
});
|
|
135
|
-
return {
|
|
136
|
-
body
|
|
137
|
-
};
|
|
246
|
+
if (holding === null || holding.method !== 'POST')
|
|
247
|
+
return { outcome: UNCERTAIN };
|
|
248
|
+
const upload = { url: holding.url, operation: holding.operation, bytes, sha256 };
|
|
249
|
+
await keep(upload);
|
|
250
|
+
return { body: { ...head, paths, upload } };
|
|
138
251
|
}
|
|
139
|
-
async function submit(head, changes, delta, bytes, entry) {
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if ('outcome' in prepared) return prepared.outcome;
|
|
252
|
+
async function submit(head, changes, delta, bytes, entry, handed, keep) {
|
|
253
|
+
const inline = { ...head, changes };
|
|
254
|
+
const prepared = uploadable(inline, bytes, declared())
|
|
255
|
+
? await uploaded(head, changes, delta, bytes, entry, handed, keep)
|
|
256
|
+
: { body: inline };
|
|
257
|
+
if ('outcome' in prepared)
|
|
258
|
+
return prepared.outcome;
|
|
147
259
|
const answer = await transport.door(DOOR_BATCH, prepared.body);
|
|
148
260
|
return mutationOutcome(answer.status, answer.body, entry.locator, entry.handle);
|
|
149
261
|
}
|
|
150
262
|
return {
|
|
151
|
-
async authorize
|
|
263
|
+
async authorize() {
|
|
152
264
|
return options.authorize();
|
|
153
265
|
},
|
|
154
|
-
async model
|
|
266
|
+
async model(_authorization, request) {
|
|
155
267
|
return models.answer(request);
|
|
156
268
|
},
|
|
157
|
-
async discover
|
|
158
|
-
const answer = await transport.door(DOOR_DISCOVER, {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
});
|
|
163
|
-
const classified = classifyDoor(answer.status, answer.body, PRIVATE_AUTHORITY);
|
|
164
|
-
if (classified !== null) return discoveryFailure(classified);
|
|
269
|
+
async discover(_authorization) {
|
|
270
|
+
const answer = await transport.door(DOOR_DISCOVER, { prefixes: [...DISCOVER_PREFIXES] });
|
|
271
|
+
const classified = classifyDoor(answer.status, answer.body, PRIVATE_LOCATOR);
|
|
272
|
+
if (classified !== null)
|
|
273
|
+
return discoveryFailure(classified);
|
|
165
274
|
const document = parseDiscovery(answer.body);
|
|
166
|
-
if (document === null)
|
|
167
|
-
kind: 'transport-uncertainty'
|
|
168
|
-
|
|
275
|
+
if (document === null)
|
|
276
|
+
return { kind: 'transport-uncertainty' };
|
|
277
|
+
bounds = document.bounds;
|
|
169
278
|
const entries = trackedFrom(document);
|
|
170
279
|
tracked.clear();
|
|
171
|
-
for (const entry of entries)
|
|
280
|
+
for (const entry of entries)
|
|
281
|
+
tracked.set(entry.locator, entry);
|
|
282
|
+
for (const locator of handed.keys())
|
|
283
|
+
if (!tracked.has(locator))
|
|
284
|
+
handed.delete(locator);
|
|
172
285
|
notifications.track(entries);
|
|
173
286
|
const acquired = await acquireModels(entries);
|
|
174
|
-
models.keep(entries.map((entry)=>entry.locator));
|
|
175
|
-
return mapDiscovery(document, document.authorities.map((authority)=>roomOf(authority, acquired)), capabilities());
|
|
287
|
+
models.keep(entries.map((entry) => entry.locator));
|
|
288
|
+
return mapDiscovery(document, document.authorities.map((authority) => roomOf(authority, acquired)), capabilities(document.actions));
|
|
176
289
|
},
|
|
177
|
-
async bootstrap
|
|
290
|
+
async bootstrap(_authorization, request) {
|
|
178
291
|
const entry = authorityFor(request.locator);
|
|
179
|
-
if (entry === undefined)
|
|
180
|
-
kind: 'room-not-readable',
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
kind: 'transport-uncertainty'
|
|
185
|
-
};
|
|
186
|
-
const answer = await transport.door(DOOR_BOOTSTRAP, {
|
|
187
|
-
prefixes: [
|
|
188
|
-
...contentPrefixes(entry)
|
|
189
|
-
]
|
|
190
|
-
});
|
|
191
|
-
const classified = classifyDoor(answer.status, answer.body, entry.locator);
|
|
192
|
-
if (classified !== null) {
|
|
193
|
-
return classified.kind === 'beyond-horizon' ? {
|
|
194
|
-
kind: 'transport-uncertainty'
|
|
195
|
-
} : classified;
|
|
196
|
-
}
|
|
197
|
-
const envelope = parseEnvelope(await bundled(answer.body));
|
|
198
|
-
if (envelope === null) return {
|
|
199
|
-
kind: 'transport-uncertainty'
|
|
200
|
-
};
|
|
201
|
-
return bootstrapFrom(envelope, entry);
|
|
292
|
+
if (entry === undefined)
|
|
293
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
294
|
+
if (request.pageToken !== undefined)
|
|
295
|
+
return { kind: 'transport-uncertainty' };
|
|
296
|
+
return bootstrapTogether(entry);
|
|
202
297
|
},
|
|
203
|
-
async refresh
|
|
298
|
+
async refresh(_authorization, request) {
|
|
204
299
|
const entry = authorityFor(request.locator);
|
|
205
|
-
if (entry === undefined)
|
|
206
|
-
kind: 'room-not-readable',
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (request.pageToken !== undefined) return {
|
|
210
|
-
kind: 'transport-uncertainty'
|
|
211
|
-
};
|
|
300
|
+
if (entry === undefined)
|
|
301
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
302
|
+
if (request.pageToken !== undefined)
|
|
303
|
+
return { kind: 'transport-uncertainty' };
|
|
212
304
|
const from = logPosition(request.fromRoomVersion);
|
|
213
|
-
if (from === null)
|
|
214
|
-
kind: 'beyond-horizon'
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
]
|
|
305
|
+
if (from === null)
|
|
306
|
+
return { kind: 'beyond-horizon' };
|
|
307
|
+
const answered = streamed(entry, request, from);
|
|
308
|
+
if (answered !== null)
|
|
309
|
+
return answered;
|
|
310
|
+
const minPosition = request.minPosition === undefined ? null : logPosition(request.minPosition);
|
|
311
|
+
return enumerateTogether({
|
|
312
|
+
entry,
|
|
313
|
+
from,
|
|
314
|
+
fromRoomVersion: request.fromRoomVersion,
|
|
315
|
+
...(minPosition?.logEpoch === from.logEpoch ? { minPosition: minPosition.position } : {}),
|
|
225
316
|
});
|
|
226
|
-
const classified = classifyDoor(answer.status, answer.body, entry.locator);
|
|
227
|
-
if (classified !== null) return classified;
|
|
228
|
-
const enumeration = parseEnumeration(answer.body, 'credential');
|
|
229
|
-
if (enumeration === null) return {
|
|
230
|
-
kind: 'transport-uncertainty'
|
|
231
|
-
};
|
|
232
|
-
return refreshFrom(enumeration, entry, request.fromRoomVersion);
|
|
233
317
|
},
|
|
234
|
-
async mutate
|
|
318
|
+
async mutate(_authorization, request, keep) {
|
|
235
319
|
const entry = authorityFor(request.locator);
|
|
236
|
-
if (entry === undefined)
|
|
237
|
-
kind: 'room-not-readable',
|
|
238
|
-
locator: request.locator
|
|
239
|
-
};
|
|
320
|
+
if (entry === undefined)
|
|
321
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
240
322
|
const mapped = houseChanges(request.changeBatch, entry.handle);
|
|
241
|
-
if (mapped.kind === 'unmapped')
|
|
323
|
+
if (mapped.kind === 'unmapped')
|
|
324
|
+
return rejectedMapping(mapped);
|
|
242
325
|
const head = operationHead(request.changeBatch);
|
|
243
326
|
const delta = deltaBody(mapped.changes);
|
|
244
327
|
const bytes = deltaBytes(delta);
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
if (
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
if (RESOLVED_OUTCOMES.has(outcome.kind)) submissions.delete(head.operation_id);
|
|
252
|
-
return outcome;
|
|
328
|
+
const handed = request.upload;
|
|
329
|
+
const outcome = await submit(head, mapped.changes, delta, bytes, entry, handed, keep);
|
|
330
|
+
if (handed === undefined || !lapsedGrant(outcome))
|
|
331
|
+
return outcome;
|
|
332
|
+
return submit(head, mapped.changes, delta, bytes, entry, undefined, keep);
|
|
253
333
|
},
|
|
254
|
-
async history
|
|
334
|
+
async history(_authorization, request) {
|
|
255
335
|
const entry = authorityFor(request.locator);
|
|
256
|
-
if (entry === undefined)
|
|
257
|
-
kind: 'room-not-readable',
|
|
258
|
-
locator: request.locator
|
|
259
|
-
};
|
|
336
|
+
if (entry === undefined)
|
|
337
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
260
338
|
const answer = await transport.door(DOOR_REVISIONS, revisionBody({
|
|
261
339
|
path: request.path,
|
|
262
340
|
handle: entry.handle,
|
|
263
|
-
...request.revision === undefined ? {} : {
|
|
264
|
-
|
|
265
|
-
},
|
|
266
|
-
...request.pageToken === undefined ? {} : {
|
|
267
|
-
pageToken: request.pageToken
|
|
268
|
-
}
|
|
341
|
+
...(request.revision === undefined ? {} : { revision: request.revision }),
|
|
342
|
+
...(request.pageToken === undefined ? {} : { pageToken: request.pageToken }),
|
|
269
343
|
}));
|
|
270
344
|
return historyOutcome(answer.status, answer.body, entry.locator, {
|
|
271
345
|
path: request.path,
|
|
272
|
-
...request.revision === undefined ? {} : {
|
|
273
|
-
revision: request.revision
|
|
274
|
-
}
|
|
346
|
+
...(request.revision === undefined ? {} : { revision: request.revision }),
|
|
275
347
|
});
|
|
276
348
|
},
|
|
277
|
-
|
|
278
|
-
return
|
|
349
|
+
reached(locator, version, target) {
|
|
350
|
+
return reachedVersion(version, target, authorityFor(locator)?.logEpoch);
|
|
351
|
+
},
|
|
352
|
+
async action(_authorization, request) {
|
|
353
|
+
return withAt(await houseAction(transport, request));
|
|
279
354
|
},
|
|
280
355
|
roomVersions: notifications,
|
|
281
|
-
conversations: notifications.conversations
|
|
356
|
+
conversations: notifications.conversations,
|
|
357
|
+
serviceMode: notifications.serviceMode,
|
|
282
358
|
};
|
|
283
359
|
}
|
|
284
|
-
|
|
285
|
-
//# sourceMappingURL=adapter.js.map
|
package/dist/digest.js
CHANGED
|
@@ -3,9 +3,5 @@ export function textBytes(value) {
|
|
|
3
3
|
}
|
|
4
4
|
export async function sha256Hex(value) {
|
|
5
5
|
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(value));
|
|
6
|
-
return [
|
|
7
|
-
...new Uint8Array(digest)
|
|
8
|
-
].map((byte)=>byte.toString(16).padStart(2, '0')).join('');
|
|
6
|
+
return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, '0')).join('');
|
|
9
7
|
}
|
|
10
|
-
|
|
11
|
-
//# sourceMappingURL=digest.js.map
|