@agentshouse/mdruntime-adapter 0.1.0-alpha.2 → 0.1.0-alpha.21
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 +120 -22
- package/dist/actions.d.ts +3 -11
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +118 -223
- package/dist/actions.js.map +1 -1
- package/dist/adapter.d.ts +3 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +45 -101
- package/dist/adapter.js.map +1 -1
- package/dist/discovery.d.ts +34 -7
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +132 -29
- package/dist/discovery.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/model.d.ts +19 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +64 -0
- package/dist/model.js.map +1 -0
- package/dist/read.d.ts +16 -12
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +109 -30
- package/dist/read.js.map +1 -1
- package/dist/refusal.d.ts +4 -1
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +13 -0
- package/dist/refusal.js.map +1 -1
- package/dist/site.d.ts +4 -0
- package/dist/site.d.ts.map +1 -0
- package/dist/site.js +205 -0
- package/dist/site.js.map +1 -0
- package/dist/stream.d.ts +7 -5
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +117 -82
- package/dist/stream.js.map +1 -1
- package/dist/transport.d.ts +16 -5
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +5 -1
- package/dist/transport.js.map +1 -1
- package/dist/version.d.ts +14 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +29 -0
- package/dist/version.js.map +1 -0
- package/dist/write.d.ts +6 -0
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +24 -7
- package/dist/write.js.map +1 -1
- package/package.json +3 -3
package/dist/read.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PROVIDER_SELECTION_ROOTS } from './discovery.js';
|
|
2
|
+
import { readPosition, roomVersion } from './version.js';
|
|
2
3
|
export function authorityRoot(handle) {
|
|
3
4
|
return handle === undefined ? '/private' : `/rooms/${handle}`;
|
|
4
5
|
}
|
|
@@ -36,24 +37,41 @@ export function parseGrant(body) {
|
|
|
36
37
|
url: transfer.url
|
|
37
38
|
};
|
|
38
39
|
}
|
|
39
|
-
function
|
|
40
|
+
function parseFile(value, mode) {
|
|
41
|
+
if (typeof value !== 'object' || value === null) return null;
|
|
42
|
+
const file = value;
|
|
43
|
+
if (typeof file.path !== 'string') return null;
|
|
44
|
+
if (mode === 'site') {
|
|
45
|
+
if (typeof file.sha256 !== 'string') return null;
|
|
46
|
+
return {
|
|
47
|
+
path: file.path,
|
|
48
|
+
revision: undefined,
|
|
49
|
+
version: file.sha256
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (typeof file.revision !== 'string') return null;
|
|
53
|
+
return {
|
|
54
|
+
path: file.path,
|
|
55
|
+
revision: file.revision,
|
|
56
|
+
version: file.revision
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function parseScope(value, mode) {
|
|
40
60
|
if (typeof value !== 'object' || value === null) return null;
|
|
41
61
|
const held = value;
|
|
42
62
|
if (typeof held.manifest !== 'object' || held.manifest === null) return null;
|
|
43
63
|
if (!Array.isArray(held.contents)) return null;
|
|
44
64
|
const manifest = held.manifest;
|
|
45
|
-
if (manifest.scope !== 'room'
|
|
46
|
-
|
|
65
|
+
if (manifest.scope !== 'room') return null;
|
|
66
|
+
const at = readPosition(manifest);
|
|
67
|
+
if (typeof manifest.anchor !== 'string' || manifest.anchor.length === 0 || at === null) return null;
|
|
68
|
+
if (manifest.room_handle !== null && (typeof manifest.room_handle !== 'string' || manifest.room_handle.length === 0)) return null;
|
|
47
69
|
if (!Array.isArray(manifest.files)) return null;
|
|
48
70
|
const files = [];
|
|
49
71
|
for (const entry of manifest.files){
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
files.push({
|
|
54
|
-
path: file.path,
|
|
55
|
-
revision: file.revision
|
|
56
|
-
});
|
|
72
|
+
const file = parseFile(entry, mode);
|
|
73
|
+
if (file === null) return null;
|
|
74
|
+
files.push(file);
|
|
57
75
|
}
|
|
58
76
|
const contents = [];
|
|
59
77
|
for (const entry of held.contents){
|
|
@@ -66,10 +84,8 @@ function parseScope(value) {
|
|
|
66
84
|
});
|
|
67
85
|
}
|
|
68
86
|
return {
|
|
69
|
-
scope: manifest.scope,
|
|
70
87
|
anchor: manifest.anchor,
|
|
71
|
-
|
|
72
|
-
position: manifest.position,
|
|
88
|
+
...at,
|
|
73
89
|
files,
|
|
74
90
|
contents
|
|
75
91
|
};
|
|
@@ -79,7 +95,7 @@ export function parseEnvelope(body) {
|
|
|
79
95
|
if (!('scopes' in body) || !Array.isArray(body.scopes)) return null;
|
|
80
96
|
const scopes = [];
|
|
81
97
|
for (const entry of body.scopes){
|
|
82
|
-
const scope = parseScope(entry);
|
|
98
|
+
const scope = parseScope(entry, 'credential');
|
|
83
99
|
if (scope === null) return null;
|
|
84
100
|
scopes.push(scope);
|
|
85
101
|
}
|
|
@@ -87,7 +103,10 @@ export function parseEnvelope(body) {
|
|
|
87
103
|
scopes
|
|
88
104
|
};
|
|
89
105
|
}
|
|
90
|
-
function
|
|
106
|
+
export function parseSiteBootstrap(body) {
|
|
107
|
+
return parseScope(body, 'site');
|
|
108
|
+
}
|
|
109
|
+
function parseChange(value, mode) {
|
|
91
110
|
if (typeof value !== 'object' || value === null) return null;
|
|
92
111
|
const held = value;
|
|
93
112
|
if (typeof held.path !== 'string') return null;
|
|
@@ -95,11 +114,21 @@ function parseChange(value) {
|
|
|
95
114
|
path: held.path,
|
|
96
115
|
removed: true
|
|
97
116
|
};
|
|
117
|
+
if (mode === 'site') {
|
|
118
|
+
if (typeof held.content !== 'string' || typeof held.sha256 !== 'string') return null;
|
|
119
|
+
return {
|
|
120
|
+
path: held.path,
|
|
121
|
+
content: held.content,
|
|
122
|
+
revision: undefined,
|
|
123
|
+
version: held.sha256
|
|
124
|
+
};
|
|
125
|
+
}
|
|
98
126
|
if (typeof held.content === 'string' && typeof held.revision === 'string') {
|
|
99
127
|
return {
|
|
100
128
|
path: held.path,
|
|
101
129
|
content: held.content,
|
|
102
|
-
revision: held.revision
|
|
130
|
+
revision: held.revision,
|
|
131
|
+
version: held.revision
|
|
103
132
|
};
|
|
104
133
|
}
|
|
105
134
|
if (typeof held.reference === 'object' && held.reference !== null) {
|
|
@@ -114,24 +143,25 @@ function parseChange(value) {
|
|
|
114
143
|
}
|
|
115
144
|
return null;
|
|
116
145
|
}
|
|
117
|
-
export function parseEnumeration(body) {
|
|
146
|
+
export function parseEnumeration(body, mode) {
|
|
118
147
|
if (typeof body !== 'object' || body === null) return null;
|
|
119
148
|
if (!('authorities' in body) || !Array.isArray(body.authorities)) return null;
|
|
120
149
|
const authorities = [];
|
|
121
150
|
for (const entry of body.authorities){
|
|
122
151
|
if (typeof entry !== 'object' || entry === null) return null;
|
|
123
152
|
const held = entry;
|
|
124
|
-
|
|
153
|
+
const at = readPosition(held);
|
|
154
|
+
if (typeof held.authority !== 'string' || at === null) return null;
|
|
125
155
|
if (!Array.isArray(held.changes)) return null;
|
|
126
156
|
const changes = [];
|
|
127
157
|
for (const change of held.changes){
|
|
128
|
-
const mapped = parseChange(change);
|
|
158
|
+
const mapped = parseChange(change, mode);
|
|
129
159
|
if (mapped === null) return null;
|
|
130
160
|
changes.push(mapped);
|
|
131
161
|
}
|
|
132
162
|
authorities.push({
|
|
133
163
|
authority: held.authority,
|
|
134
|
-
|
|
164
|
+
...at,
|
|
135
165
|
changes
|
|
136
166
|
});
|
|
137
167
|
}
|
|
@@ -139,9 +169,52 @@ export function parseEnumeration(body) {
|
|
|
139
169
|
authorities
|
|
140
170
|
};
|
|
141
171
|
}
|
|
172
|
+
export function advancedScope(scope, view) {
|
|
173
|
+
const files = new Map(scope.files.map((file)=>[
|
|
174
|
+
file.path,
|
|
175
|
+
file
|
|
176
|
+
]));
|
|
177
|
+
const contents = new Map(scope.contents.map((entry)=>[
|
|
178
|
+
entry.path,
|
|
179
|
+
entry.content
|
|
180
|
+
]));
|
|
181
|
+
for (const change of view.changes){
|
|
182
|
+
files.delete(change.path);
|
|
183
|
+
contents.delete(change.path);
|
|
184
|
+
if ('removed' in change) continue;
|
|
185
|
+
if ('content' in change) {
|
|
186
|
+
files.set(change.path, {
|
|
187
|
+
path: change.path,
|
|
188
|
+
revision: change.revision,
|
|
189
|
+
version: change.version
|
|
190
|
+
});
|
|
191
|
+
contents.set(change.path, change.content);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
const { revision } = change.reference;
|
|
195
|
+
files.set(change.path, {
|
|
196
|
+
path: change.path,
|
|
197
|
+
revision,
|
|
198
|
+
version: revision
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
...scope,
|
|
203
|
+
position: view.position,
|
|
204
|
+
logEpoch: view.logEpoch,
|
|
205
|
+
files: [
|
|
206
|
+
...files.values()
|
|
207
|
+
],
|
|
208
|
+
contents: [
|
|
209
|
+
...contents
|
|
210
|
+
].map(([path, content])=>({
|
|
211
|
+
path,
|
|
212
|
+
content
|
|
213
|
+
}))
|
|
214
|
+
};
|
|
215
|
+
}
|
|
142
216
|
export function matchesScope(scope, tracked) {
|
|
143
|
-
|
|
144
|
-
return scope.roomHandle === tracked.handle || scope.anchor === tracked.authority;
|
|
217
|
+
return scope.anchor === tracked.authority;
|
|
145
218
|
}
|
|
146
219
|
export function withinRoot(path, root) {
|
|
147
220
|
return path === root || path.startsWith(`${root}/`);
|
|
@@ -156,6 +229,9 @@ export function bootstrapFrom(envelope, tracked) {
|
|
|
156
229
|
kind: 'room-not-readable',
|
|
157
230
|
locator: tracked.locator
|
|
158
231
|
};
|
|
232
|
+
return bootstrapOf(scope, tracked);
|
|
233
|
+
}
|
|
234
|
+
export function bootstrapOf(scope, tracked) {
|
|
159
235
|
const contents = new Map(scope.contents.map((entry)=>[
|
|
160
236
|
entry.path,
|
|
161
237
|
entry.content
|
|
@@ -165,14 +241,14 @@ export function bootstrapFrom(envelope, tracked) {
|
|
|
165
241
|
const binaryTargets = [];
|
|
166
242
|
for (const file of scope.files){
|
|
167
243
|
if (!selects(tracked, file.path)) continue;
|
|
168
|
-
revisions[file.path] = file.revision;
|
|
244
|
+
if (file.revision !== undefined) revisions[file.path] = file.revision;
|
|
169
245
|
const content = contents.get(file.path);
|
|
170
246
|
if (content === undefined) binaryTargets.push(file.path);
|
|
171
247
|
else documents[file.path] = content;
|
|
172
248
|
}
|
|
173
249
|
return {
|
|
174
250
|
kind: 'bootstrap',
|
|
175
|
-
roomVersion: scope
|
|
251
|
+
roomVersion: roomVersion(scope),
|
|
176
252
|
documents,
|
|
177
253
|
revisions,
|
|
178
254
|
binaryTargets: binaryTargets.sort()
|
|
@@ -185,23 +261,26 @@ export function definitionAddress(path) {
|
|
|
185
261
|
export function definitionsFrom(envelope, tracked, modelRoot) {
|
|
186
262
|
const scope = envelope.scopes.find((entry)=>matchesScope(entry, tracked));
|
|
187
263
|
if (scope === undefined) return null;
|
|
264
|
+
return definitionsOf(scope, modelRoot);
|
|
265
|
+
}
|
|
266
|
+
export function definitionsOf(scope, modelRoot) {
|
|
188
267
|
const contents = new Map(scope.contents.map((entry)=>[
|
|
189
268
|
entry.path,
|
|
190
269
|
entry.content
|
|
191
270
|
]));
|
|
192
271
|
const definitions = {};
|
|
193
|
-
const
|
|
272
|
+
const versions = [];
|
|
194
273
|
for (const file of scope.files){
|
|
195
274
|
if (!withinRoot(file.path, modelRoot)) continue;
|
|
196
275
|
const content = contents.get(file.path);
|
|
197
276
|
const address = definitionAddress(file.path);
|
|
198
277
|
if (content === undefined || Object.hasOwn(definitions, address)) return null;
|
|
199
278
|
definitions[address] = content;
|
|
200
|
-
|
|
279
|
+
versions.push(`${file.path} ${file.version}`);
|
|
201
280
|
}
|
|
202
281
|
return {
|
|
203
282
|
definitions,
|
|
204
|
-
|
|
283
|
+
versions: versions.sort()
|
|
205
284
|
};
|
|
206
285
|
}
|
|
207
286
|
export function refreshFrom(enumeration, tracked, fromRoomVersion) {
|
|
@@ -210,7 +289,7 @@ export function refreshFrom(enumeration, tracked, fromRoomVersion) {
|
|
|
210
289
|
kind: 'room-not-readable',
|
|
211
290
|
locator: tracked.locator
|
|
212
291
|
};
|
|
213
|
-
if (view
|
|
292
|
+
if (roomVersion(view) === fromRoomVersion) return {
|
|
214
293
|
kind: 'still-current'
|
|
215
294
|
};
|
|
216
295
|
const documents = {};
|
|
@@ -225,7 +304,7 @@ export function refreshFrom(enumeration, tracked, fromRoomVersion) {
|
|
|
225
304
|
}
|
|
226
305
|
if ('content' in change) {
|
|
227
306
|
documents[change.path] = change.content;
|
|
228
|
-
revisions[change.path] = change.revision;
|
|
307
|
+
if (change.revision !== undefined) revisions[change.path] = change.revision;
|
|
229
308
|
continue;
|
|
230
309
|
}
|
|
231
310
|
binaryTargets.push(change.path);
|
|
@@ -233,7 +312,7 @@ export function refreshFrom(enumeration, tracked, fromRoomVersion) {
|
|
|
233
312
|
}
|
|
234
313
|
return {
|
|
235
314
|
kind: 'net-advancement',
|
|
236
|
-
roomVersion: view
|
|
315
|
+
roomVersion: roomVersion(view),
|
|
237
316
|
documents,
|
|
238
317
|
revisions,
|
|
239
318
|
binaryTargets: binaryTargets.sort(),
|
package/dist/read.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/workspace/packages/mdruntime-adapter/src/read.ts"],"sourcesContent":["import type { BootstrapResult, RefreshResult } from '@agentshouse/mdruntime';\nimport { PROVIDER_SELECTION_ROOTS, type TrackedAuthority } from './discovery.js';\n\nexport type HouseManifestFile = {\n path: string;\n revision: string;\n};\n\nexport type HouseContent = {\n path: string;\n content: string;\n};\n\nexport type HouseScope = {\n scope: 'room' | 'private';\n anchor: string;\n roomHandle: string | undefined;\n position: string;\n files: readonly HouseManifestFile[];\n contents: readonly HouseContent[];\n};\n\nexport type HouseEnvelope = {\n scopes: readonly HouseScope[];\n};\n\nexport type HouseGrant = {\n method: 'GET' | 'POST';\n operation: string;\n url: string;\n};\n\nexport type HouseChange =\n | { path: string; removed: true }\n | { path: string; content: string; revision: string }\n | { path: string; reference: { revision: string } };\n\nexport type HouseEnumeration = {\n authorities: readonly {\n authority: string;\n position: string;\n changes: readonly HouseChange[];\n }[];\n};\n\nexport function authorityRoot(handle: string | undefined): string {\n return handle === undefined ? '/private' : `/rooms/${handle}`;\n}\n\nexport const ROOM_README = 'ROOM.md';\n\nexport function selectionRoots(tracked: TrackedAuthority): readonly string[] {\n if (tracked.handle === undefined) {\n return [tracked.collectionRoot, ...PROVIDER_SELECTION_ROOTS];\n }\n return [ROOM_README, tracked.collectionRoot];\n}\n\nexport function contentPrefixes(tracked: TrackedAuthority): readonly string[] {\n const root = authorityRoot(tracked.handle);\n return selectionRoots(tracked)\n .filter((entry) => entry !== ROOM_README)\n .map((entry) => `${root}/${entry}`);\n}\n\nexport function modelPrefix(tracked: TrackedAuthority, modelRoot: string): string {\n return `${authorityRoot(tracked.handle)}/${modelRoot}`;\n}\n\nexport function parseGrant(body: unknown): HouseGrant | null {\n if (typeof body !== 'object' || body === null) return null;\n if (!('transfer' in body) || typeof body.transfer !== 'object' || body.transfer === null) {\n return null;\n }\n const transfer = body.transfer as Record<string, unknown>;\n if (transfer.method !== 'GET' && transfer.method !== 'POST') return null;\n if (typeof transfer.operation !== 'string' || typeof transfer.url !== 'string') return null;\n return { method: transfer.method, operation: transfer.operation, url: transfer.url };\n}\n\nfunction parseScope(value: unknown): HouseScope | null {\n if (typeof value !== 'object' || value === null) return null;\n const held = value as Record<string, unknown>;\n if (typeof held.manifest !== 'object' || held.manifest === null) return null;\n if (!Array.isArray(held.contents)) return null;\n const manifest = held.manifest as Record<string, unknown>;\n if (manifest.scope !== 'room' && manifest.scope !== 'private') return null;\n if (typeof manifest.anchor !== 'string' || typeof manifest.position !== 'string') return null;\n if (!Array.isArray(manifest.files)) return null;\n const files: HouseManifestFile[] = [];\n for (const entry of manifest.files) {\n if (typeof entry !== 'object' || entry === null) return null;\n const file = entry as Record<string, unknown>;\n if (typeof file.path !== 'string' || typeof file.revision !== 'string') return null;\n files.push({ path: file.path, revision: file.revision });\n }\n const contents: HouseContent[] = [];\n for (const entry of held.contents) {\n if (typeof entry !== 'object' || entry === null) return null;\n const content = entry as Record<string, unknown>;\n if (typeof content.path !== 'string' || typeof content.content !== 'string') return null;\n contents.push({ path: content.path, content: content.content });\n }\n return {\n scope: manifest.scope,\n anchor: manifest.anchor,\n roomHandle: typeof manifest.room_handle === 'string' ? manifest.room_handle : undefined,\n position: manifest.position,\n files,\n contents,\n };\n}\n\nexport function parseEnvelope(body: unknown): HouseEnvelope | null {\n if (typeof body !== 'object' || body === null) return null;\n if (!('scopes' in body) || !Array.isArray(body.scopes)) return null;\n const scopes: HouseScope[] = [];\n for (const entry of body.scopes) {\n const scope = parseScope(entry);\n if (scope === null) return null;\n scopes.push(scope);\n }\n return { scopes };\n}\n\nfunction parseChange(value: unknown): HouseChange | null {\n if (typeof value !== 'object' || value === null) return null;\n const held = value as Record<string, unknown>;\n if (typeof held.path !== 'string') return null;\n if (held.removed === true) return { path: held.path, removed: true };\n if (typeof held.content === 'string' && typeof held.revision === 'string') {\n return { path: held.path, content: held.content, revision: held.revision };\n }\n if (typeof held.reference === 'object' && held.reference !== null) {\n const reference = held.reference as Record<string, unknown>;\n if (typeof reference.revision !== 'string') return null;\n return { path: held.path, reference: { revision: reference.revision } };\n }\n return null;\n}\n\nexport function parseEnumeration(body: unknown): HouseEnumeration | null {\n if (typeof body !== 'object' || body === null) return null;\n if (!('authorities' in body) || !Array.isArray(body.authorities)) return null;\n const authorities: HouseEnumeration['authorities'][number][] = [];\n for (const entry of body.authorities) {\n if (typeof entry !== 'object' || entry === null) return null;\n const held = entry as Record<string, unknown>;\n if (typeof held.authority !== 'string' || typeof held.position !== 'string') return null;\n if (!Array.isArray(held.changes)) return null;\n const changes: HouseChange[] = [];\n for (const change of held.changes) {\n const mapped = parseChange(change);\n if (mapped === null) return null;\n changes.push(mapped);\n }\n authorities.push({ authority: held.authority, position: held.position, changes });\n }\n return { authorities };\n}\n\nexport function matchesScope(scope: HouseScope, tracked: TrackedAuthority): boolean {\n if (tracked.handle === undefined) return scope.scope === 'private';\n return scope.roomHandle === tracked.handle || scope.anchor === tracked.authority;\n}\n\nexport function withinRoot(path: string, root: string): boolean {\n return path === root || path.startsWith(`${root}/`);\n}\n\nexport function selects(tracked: TrackedAuthority, path: string): boolean {\n if (tracked.modelRoots.some((root) => withinRoot(path, root))) return false;\n return selectionRoots(tracked).some((root) => withinRoot(path, root));\n}\n\nexport function bootstrapFrom(envelope: HouseEnvelope, tracked: TrackedAuthority): BootstrapResult {\n const scope = envelope.scopes.find((entry) => matchesScope(entry, tracked));\n if (scope === undefined) return { kind: 'room-not-readable', locator: tracked.locator };\n const contents = new Map(scope.contents.map((entry) => [entry.path, entry.content]));\n const documents: Record<string, string> = {};\n const revisions: Record<string, string> = {};\n const binaryTargets: string[] = [];\n for (const file of scope.files) {\n if (!selects(tracked, file.path)) continue;\n revisions[file.path] = file.revision;\n const content = contents.get(file.path);\n if (content === undefined) binaryTargets.push(file.path);\n else documents[file.path] = content;\n }\n return {\n kind: 'bootstrap',\n roomVersion: scope.position,\n documents,\n revisions,\n binaryTargets: binaryTargets.sort(),\n };\n}\n\nexport type HouseDefinitions = {\n definitions: Readonly<Record<string, string>>;\n revisions: readonly string[];\n};\n\nexport const MODEL_DEFINITION_ADDRESS = 'types';\n\nexport function definitionAddress(path: string): string {\n return `${MODEL_DEFINITION_ADDRESS}/${path.slice(path.lastIndexOf('/') + 1)}`;\n}\n\nexport function definitionsFrom(\n envelope: HouseEnvelope,\n tracked: TrackedAuthority,\n modelRoot: string,\n): HouseDefinitions | null {\n const scope = envelope.scopes.find((entry) => matchesScope(entry, tracked));\n if (scope === undefined) return null;\n const contents = new Map(scope.contents.map((entry) => [entry.path, entry.content]));\n const definitions: Record<string, string> = {};\n const revisions: string[] = [];\n for (const file of scope.files) {\n if (!withinRoot(file.path, modelRoot)) continue;\n const content = contents.get(file.path);\n const address = definitionAddress(file.path);\n if (content === undefined || Object.hasOwn(definitions, address)) return null;\n definitions[address] = content;\n revisions.push(`${file.path} ${file.revision}`);\n }\n return { definitions, revisions: revisions.sort() };\n}\n\nexport function refreshFrom(\n enumeration: HouseEnumeration,\n tracked: TrackedAuthority,\n fromRoomVersion: string,\n): RefreshResult {\n const view = enumeration.authorities.find((entry) => entry.authority === tracked.authority);\n if (view === undefined) return { kind: 'room-not-readable', locator: tracked.locator };\n if (view.position === fromRoomVersion) return { kind: 'still-current' };\n const documents: Record<string, string> = {};\n const revisions: Record<string, string> = {};\n const binaryTargets: string[] = [];\n const removals: string[] = [];\n for (const change of view.changes) {\n if (!selects(tracked, change.path)) continue;\n if ('removed' in change) {\n removals.push(change.path);\n continue;\n }\n if ('content' in change) {\n documents[change.path] = change.content;\n revisions[change.path] = change.revision;\n continue;\n }\n binaryTargets.push(change.path);\n revisions[change.path] = change.reference.revision;\n }\n return {\n kind: 'net-advancement',\n roomVersion: view.position,\n documents,\n revisions,\n binaryTargets: binaryTargets.sort(),\n removals: removals.sort(),\n };\n}\n"],"names":["PROVIDER_SELECTION_ROOTS","authorityRoot","handle","undefined","ROOM_README","selectionRoots","tracked","collectionRoot","contentPrefixes","root","filter","entry","map","modelPrefix","modelRoot","parseGrant","body","transfer","method","operation","url","parseScope","value","held","manifest","Array","isArray","contents","scope","anchor","position","files","file","path","revision","push","content","roomHandle","room_handle","parseEnvelope","scopes","parseChange","removed","reference","parseEnumeration","authorities","authority","changes","change","mapped","matchesScope","withinRoot","startsWith","selects","modelRoots","some","bootstrapFrom","envelope","find","kind","locator","Map","documents","revisions","binaryTargets","get","roomVersion","sort","MODEL_DEFINITION_ADDRESS","definitionAddress","slice","lastIndexOf","definitionsFrom","definitions","address","Object","hasOwn","refreshFrom","enumeration","fromRoomVersion","view","removals"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/workspace/packages/mdruntime-adapter/src/read.ts"],"sourcesContent":["import type { BootstrapPage, BootstrapResult, RefreshResult } from '@agentshouse/mdruntime';\nimport { PROVIDER_SELECTION_ROOTS, type TrackedAuthority } from './discovery.js';\nimport type { HouseMode } from './transport.js';\nimport { readPosition, roomVersion, type LogPosition } from './version.js';\n\nexport type HouseManifestFile = {\n path: string;\n revision: string | undefined;\n version: string;\n};\n\nexport type HouseContent = {\n path: string;\n content: string;\n};\n\nexport type HouseScope = LogPosition & {\n anchor: string;\n files: readonly HouseManifestFile[];\n contents: readonly HouseContent[];\n};\n\nexport type HouseEnvelope = {\n scopes: readonly HouseScope[];\n};\n\nexport type HouseGrant = {\n method: 'GET' | 'POST';\n operation: string;\n url: string;\n};\n\nexport type HouseChange =\n | { path: string; removed: true }\n | { path: string; content: string; revision: string | undefined; version: string }\n | { path: string; reference: { revision: string } };\n\nexport type HouseEnumeration = {\n authorities: readonly (LogPosition & {\n authority: string;\n changes: readonly HouseChange[];\n })[];\n};\n\nexport function authorityRoot(handle: string | undefined): string {\n return handle === undefined ? '/private' : `/rooms/${handle}`;\n}\n\nexport const ROOM_README = 'ROOM.md';\n\nexport function selectionRoots(tracked: TrackedAuthority): readonly string[] {\n if (tracked.handle === undefined) {\n return [tracked.collectionRoot, ...PROVIDER_SELECTION_ROOTS];\n }\n return [ROOM_README, tracked.collectionRoot];\n}\n\nexport function contentPrefixes(tracked: TrackedAuthority): readonly string[] {\n const root = authorityRoot(tracked.handle);\n return selectionRoots(tracked)\n .filter((entry) => entry !== ROOM_README)\n .map((entry) => `${root}/${entry}`);\n}\n\nexport function modelPrefix(tracked: TrackedAuthority, modelRoot: string): string {\n return `${authorityRoot(tracked.handle)}/${modelRoot}`;\n}\n\nexport function parseGrant(body: unknown): HouseGrant | null {\n if (typeof body !== 'object' || body === null) return null;\n if (!('transfer' in body) || typeof body.transfer !== 'object' || body.transfer === null) {\n return null;\n }\n const transfer = body.transfer as Record<string, unknown>;\n if (transfer.method !== 'GET' && transfer.method !== 'POST') return null;\n if (typeof transfer.operation !== 'string' || typeof transfer.url !== 'string') return null;\n return { method: transfer.method, operation: transfer.operation, url: transfer.url };\n}\n\nfunction parseFile(value: unknown, mode: HouseMode): HouseManifestFile | null {\n if (typeof value !== 'object' || value === null) return null;\n const file = value as Record<string, unknown>;\n if (typeof file.path !== 'string') return null;\n if (mode === 'site') {\n if (typeof file.sha256 !== 'string') return null;\n return { path: file.path, revision: undefined, version: file.sha256 };\n }\n if (typeof file.revision !== 'string') return null;\n return { path: file.path, revision: file.revision, version: file.revision };\n}\n\nfunction parseScope(value: unknown, mode: HouseMode): HouseScope | null {\n if (typeof value !== 'object' || value === null) return null;\n const held = value as Record<string, unknown>;\n if (typeof held.manifest !== 'object' || held.manifest === null) return null;\n if (!Array.isArray(held.contents)) return null;\n const manifest = held.manifest as Record<string, unknown>;\n if (manifest.scope !== 'room') return null;\n const at = readPosition(manifest);\n if (typeof manifest.anchor !== 'string' || manifest.anchor.length === 0 || at === null)\n return null;\n if (\n manifest.room_handle !== null &&\n (typeof manifest.room_handle !== 'string' || manifest.room_handle.length === 0)\n )\n return null;\n if (!Array.isArray(manifest.files)) return null;\n const files: HouseManifestFile[] = [];\n for (const entry of manifest.files) {\n const file = parseFile(entry, mode);\n if (file === null) return null;\n files.push(file);\n }\n const contents: HouseContent[] = [];\n for (const entry of held.contents) {\n if (typeof entry !== 'object' || entry === null) return null;\n const content = entry as Record<string, unknown>;\n if (typeof content.path !== 'string' || typeof content.content !== 'string') return null;\n contents.push({ path: content.path, content: content.content });\n }\n return {\n anchor: manifest.anchor,\n ...at,\n files,\n contents,\n };\n}\n\nexport function parseEnvelope(body: unknown): HouseEnvelope | null {\n if (typeof body !== 'object' || body === null) return null;\n if (!('scopes' in body) || !Array.isArray(body.scopes)) return null;\n const scopes: HouseScope[] = [];\n for (const entry of body.scopes) {\n const scope = parseScope(entry, 'credential');\n if (scope === null) return null;\n scopes.push(scope);\n }\n return { scopes };\n}\n\nexport function parseSiteBootstrap(body: unknown): HouseScope | null {\n return parseScope(body, 'site');\n}\n\nfunction parseChange(value: unknown, mode: HouseMode): HouseChange | null {\n if (typeof value !== 'object' || value === null) return null;\n const held = value as Record<string, unknown>;\n if (typeof held.path !== 'string') return null;\n if (held.removed === true) return { path: held.path, removed: true };\n if (mode === 'site') {\n if (typeof held.content !== 'string' || typeof held.sha256 !== 'string') return null;\n return { path: held.path, content: held.content, revision: undefined, version: held.sha256 };\n }\n if (typeof held.content === 'string' && typeof held.revision === 'string') {\n return {\n path: held.path,\n content: held.content,\n revision: held.revision,\n version: held.revision,\n };\n }\n if (typeof held.reference === 'object' && held.reference !== null) {\n const reference = held.reference as Record<string, unknown>;\n if (typeof reference.revision !== 'string') return null;\n return { path: held.path, reference: { revision: reference.revision } };\n }\n return null;\n}\n\nexport function parseEnumeration(body: unknown, mode: HouseMode): HouseEnumeration | null {\n if (typeof body !== 'object' || body === null) return null;\n if (!('authorities' in body) || !Array.isArray(body.authorities)) return null;\n const authorities: HouseEnumeration['authorities'][number][] = [];\n for (const entry of body.authorities) {\n if (typeof entry !== 'object' || entry === null) return null;\n const held = entry as Record<string, unknown>;\n const at = readPosition(held);\n if (typeof held.authority !== 'string' || at === null) return null;\n if (!Array.isArray(held.changes)) return null;\n const changes: HouseChange[] = [];\n for (const change of held.changes) {\n const mapped = parseChange(change, mode);\n if (mapped === null) return null;\n changes.push(mapped);\n }\n authorities.push({ authority: held.authority, ...at, changes });\n }\n return { authorities };\n}\n\nexport function advancedScope(\n scope: HouseScope,\n view: HouseEnumeration['authorities'][number],\n): HouseScope {\n const files = new Map(scope.files.map((file) => [file.path, file]));\n const contents = new Map(scope.contents.map((entry) => [entry.path, entry.content]));\n for (const change of view.changes) {\n files.delete(change.path);\n contents.delete(change.path);\n if ('removed' in change) continue;\n if ('content' in change) {\n files.set(change.path, {\n path: change.path,\n revision: change.revision,\n version: change.version,\n });\n contents.set(change.path, change.content);\n continue;\n }\n const { revision } = change.reference;\n files.set(change.path, { path: change.path, revision, version: revision });\n }\n return {\n ...scope,\n position: view.position,\n logEpoch: view.logEpoch,\n files: [...files.values()],\n contents: [...contents].map(([path, content]) => ({ path, content })),\n };\n}\n\nexport function matchesScope(scope: HouseScope, tracked: TrackedAuthority): boolean {\n return scope.anchor === tracked.authority;\n}\n\nexport function withinRoot(path: string, root: string): boolean {\n return path === root || path.startsWith(`${root}/`);\n}\n\nexport function selects(tracked: TrackedAuthority, path: string): boolean {\n if (tracked.modelRoots.some((root) => withinRoot(path, root))) return false;\n return selectionRoots(tracked).some((root) => withinRoot(path, root));\n}\n\nexport function bootstrapFrom(envelope: HouseEnvelope, tracked: TrackedAuthority): BootstrapResult {\n const scope = envelope.scopes.find((entry) => matchesScope(entry, tracked));\n if (scope === undefined) return { kind: 'room-not-readable', locator: tracked.locator };\n return bootstrapOf(scope, tracked);\n}\n\nexport function bootstrapOf(scope: HouseScope, tracked: TrackedAuthority): BootstrapPage {\n const contents = new Map(scope.contents.map((entry) => [entry.path, entry.content]));\n const documents: Record<string, string> = {};\n const revisions: Record<string, string> = {};\n const binaryTargets: string[] = [];\n for (const file of scope.files) {\n if (!selects(tracked, file.path)) continue;\n if (file.revision !== undefined) revisions[file.path] = file.revision;\n const content = contents.get(file.path);\n if (content === undefined) binaryTargets.push(file.path);\n else documents[file.path] = content;\n }\n return {\n kind: 'bootstrap',\n roomVersion: roomVersion(scope),\n documents,\n revisions,\n binaryTargets: binaryTargets.sort(),\n };\n}\n\nexport type HouseDefinitions = {\n definitions: Readonly<Record<string, string>>;\n versions: readonly string[];\n};\n\nexport const MODEL_DEFINITION_ADDRESS = 'types';\n\nexport function definitionAddress(path: string): string {\n return `${MODEL_DEFINITION_ADDRESS}/${path.slice(path.lastIndexOf('/') + 1)}`;\n}\n\nexport function definitionsFrom(\n envelope: HouseEnvelope,\n tracked: TrackedAuthority,\n modelRoot: string,\n): HouseDefinitions | null {\n const scope = envelope.scopes.find((entry) => matchesScope(entry, tracked));\n if (scope === undefined) return null;\n return definitionsOf(scope, modelRoot);\n}\n\nexport function definitionsOf(scope: HouseScope, modelRoot: string): HouseDefinitions | null {\n const contents = new Map(scope.contents.map((entry) => [entry.path, entry.content]));\n const definitions: Record<string, string> = {};\n const versions: string[] = [];\n for (const file of scope.files) {\n if (!withinRoot(file.path, modelRoot)) continue;\n const content = contents.get(file.path);\n const address = definitionAddress(file.path);\n if (content === undefined || Object.hasOwn(definitions, address)) return null;\n definitions[address] = content;\n versions.push(`${file.path} ${file.version}`);\n }\n return { definitions, versions: versions.sort() };\n}\n\nexport function refreshFrom(\n enumeration: HouseEnumeration,\n tracked: TrackedAuthority,\n fromRoomVersion: string,\n): RefreshResult {\n const view = enumeration.authorities.find((entry) => entry.authority === tracked.authority);\n if (view === undefined) return { kind: 'room-not-readable', locator: tracked.locator };\n if (roomVersion(view) === fromRoomVersion) return { kind: 'still-current' };\n const documents: Record<string, string> = {};\n const revisions: Record<string, string> = {};\n const binaryTargets: string[] = [];\n const removals: string[] = [];\n for (const change of view.changes) {\n if (!selects(tracked, change.path)) continue;\n if ('removed' in change) {\n removals.push(change.path);\n continue;\n }\n if ('content' in change) {\n documents[change.path] = change.content;\n if (change.revision !== undefined) revisions[change.path] = change.revision;\n continue;\n }\n binaryTargets.push(change.path);\n revisions[change.path] = change.reference.revision;\n }\n return {\n kind: 'net-advancement',\n roomVersion: roomVersion(view),\n documents,\n revisions,\n binaryTargets: binaryTargets.sort(),\n removals: removals.sort(),\n };\n}\n"],"names":["PROVIDER_SELECTION_ROOTS","readPosition","roomVersion","authorityRoot","handle","undefined","ROOM_README","selectionRoots","tracked","collectionRoot","contentPrefixes","root","filter","entry","map","modelPrefix","modelRoot","parseGrant","body","transfer","method","operation","url","parseFile","value","mode","file","path","sha256","revision","version","parseScope","held","manifest","Array","isArray","contents","scope","at","anchor","length","room_handle","files","push","content","parseEnvelope","scopes","parseSiteBootstrap","parseChange","removed","reference","parseEnumeration","authorities","authority","changes","change","mapped","advancedScope","view","Map","delete","set","position","logEpoch","values","matchesScope","withinRoot","startsWith","selects","modelRoots","some","bootstrapFrom","envelope","find","kind","locator","bootstrapOf","documents","revisions","binaryTargets","get","sort","MODEL_DEFINITION_ADDRESS","definitionAddress","slice","lastIndexOf","definitionsFrom","definitionsOf","definitions","versions","address","Object","hasOwn","refreshFrom","enumeration","fromRoomVersion","removals"],"mappings":"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"}
|
package/dist/refusal.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import type { AdapterFailure, ProviderRefusal, ScopedRefusal } from '@agentshouse/mdruntime';
|
|
1
|
+
import type { AdapterFailure, DiscoverResult, ProviderRefusal, ScopedRefusal } from '@agentshouse/mdruntime';
|
|
2
2
|
export type DoorRefusal = ProviderRefusal;
|
|
3
3
|
export declare function doorRefusal(body: unknown): DoorRefusal | null;
|
|
4
4
|
export declare function scopedRefusal(locator: string, scope: ScopedRefusal['scope'], refusal: DoorRefusal): ScopedRefusal;
|
|
5
5
|
export declare function classifyDoor(status: number, body: unknown, locator: string): AdapterFailure | {
|
|
6
6
|
kind: 'beyond-horizon';
|
|
7
7
|
} | null;
|
|
8
|
+
export declare function discoveryFailure(classified: AdapterFailure | {
|
|
9
|
+
kind: 'beyond-horizon';
|
|
10
|
+
}): DiscoverResult;
|
|
8
11
|
//# sourceMappingURL=refusal.d.ts.map
|
package/dist/refusal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refusal.d.ts","sourceRoot":"","sources":["../src/refusal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"refusal.d.ts","sourceRoot":"","sources":["../src/refusal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,eAAe,EACf,aAAa,EACd,MAAM,wBAAwB,CAAC;AAgBhC,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC;AAE1C,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAO7D;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,EAC7B,OAAO,EAAE,WAAW,GACnB,aAAa,CAEf;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,GACd,cAAc,GAAG;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAAG,IAAI,CAepD;AAED,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,cAAc,GAAG;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GACtD,cAAc,CAMhB"}
|
package/dist/refusal.js
CHANGED
|
@@ -61,5 +61,18 @@ export function classifyDoor(status, body, locator) {
|
|
|
61
61
|
if (status === 403) return scopedRefusal(locator, 'operation', refusal);
|
|
62
62
|
return scopedRefusal(locator, 'undisclosed', refusal);
|
|
63
63
|
}
|
|
64
|
+
export function discoveryFailure(classified) {
|
|
65
|
+
if (classified.kind === 'revoked-authorization') return classified;
|
|
66
|
+
if (classified.kind === 'scoped-refusal') {
|
|
67
|
+
return {
|
|
68
|
+
kind: 'contract-unavailable',
|
|
69
|
+
code: classified.code,
|
|
70
|
+
fields: classified.fields
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
kind: 'transport-uncertainty'
|
|
75
|
+
};
|
|
76
|
+
}
|
|
64
77
|
|
|
65
78
|
//# sourceMappingURL=refusal.js.map
|
package/dist/refusal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/workspace/packages/mdruntime-adapter/src/refusal.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"sources":["/workspace/packages/mdruntime-adapter/src/refusal.ts"],"sourcesContent":["import type {\n AdapterFailure,\n DiscoverResult,\n ProviderRefusal,\n ScopedRefusal,\n} from '@agentshouse/mdruntime';\n\nconst RETRYABLE_CODES = new Set([\n 'auth_unavailable',\n 'replica_behind',\n 'read_replica_unavailable',\n 'read_replica_lagging',\n 'read_pool_acquisition_timed_out',\n 'sync_unavailable',\n 'sync_failed',\n 'rate_limited',\n 'operation_contended',\n 'service_mode_write_halted',\n 'transaction_budget_exceeded',\n]);\n\nexport type DoorRefusal = ProviderRefusal;\n\nexport function doorRefusal(body: unknown): DoorRefusal | null {\n if (typeof body !== 'object' || body === null) return null;\n if (!('error' in body) || typeof body.error !== 'object' || body.error === null) return null;\n const error = body.error as Record<string, unknown>;\n if (typeof error.code !== 'string') return null;\n const { code, ...fields } = error;\n return { code, fields };\n}\n\nexport function scopedRefusal(\n locator: string,\n scope: ScopedRefusal['scope'],\n refusal: DoorRefusal,\n): ScopedRefusal {\n return { kind: 'scoped-refusal', locator, scope, code: refusal.code, fields: refusal.fields };\n}\n\nexport function classifyDoor(\n status: number,\n body: unknown,\n locator: string,\n): AdapterFailure | { kind: 'beyond-horizon' } | null {\n if (status === 0) return { kind: 'transport-uncertainty' };\n const refusal = doorRefusal(body);\n if (status === 401) return { kind: 'revoked-authorization' };\n if (refusal !== null && RETRYABLE_CODES.has(refusal.code))\n return { kind: 'transport-uncertainty' };\n if (refusal !== null && refusal.code === 'position_expired') return { kind: 'beyond-horizon' };\n if (status === 404 || refusal?.code === 'room_not_found') {\n return { kind: 'room-not-readable', locator };\n }\n if (status >= 500) return { kind: 'transport-uncertainty' };\n if (status < 400) return null;\n if (refusal === null) return { kind: 'transport-uncertainty' };\n if (status === 403) return scopedRefusal(locator, 'operation', refusal);\n return scopedRefusal(locator, 'undisclosed', refusal);\n}\n\nexport function discoveryFailure(\n classified: AdapterFailure | { kind: 'beyond-horizon' },\n): DiscoverResult {\n if (classified.kind === 'revoked-authorization') return classified;\n if (classified.kind === 'scoped-refusal') {\n return { kind: 'contract-unavailable', code: classified.code, fields: classified.fields };\n }\n return { kind: 'transport-uncertainty' };\n}\n"],"names":["RETRYABLE_CODES","Set","doorRefusal","body","error","code","fields","scopedRefusal","locator","scope","refusal","kind","classifyDoor","status","has","discoveryFailure","classified"],"mappings":"AAOA,MAAMA,kBAAkB,IAAIC,IAAI;IAC9B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAID,OAAO,SAASC,YAAYC,IAAa;IACvC,IAAI,OAAOA,SAAS,YAAYA,SAAS,MAAM,OAAO;IACtD,IAAI,CAAE,CAAA,WAAWA,IAAG,KAAM,OAAOA,KAAKC,KAAK,KAAK,YAAYD,KAAKC,KAAK,KAAK,MAAM,OAAO;IACxF,MAAMA,QAAQD,KAAKC,KAAK;IACxB,IAAI,OAAOA,MAAMC,IAAI,KAAK,UAAU,OAAO;IAC3C,MAAM,EAAEA,IAAI,EAAE,GAAGC,QAAQ,GAAGF;IAC5B,OAAO;QAAEC;QAAMC;IAAO;AACxB;AAEA,OAAO,SAASC,cACdC,OAAe,EACfC,KAA6B,EAC7BC,OAAoB;IAEpB,OAAO;QAAEC,MAAM;QAAkBH;QAASC;QAAOJ,MAAMK,QAAQL,IAAI;QAAEC,QAAQI,QAAQJ,MAAM;IAAC;AAC9F;AAEA,OAAO,SAASM,aACdC,MAAc,EACdV,IAAa,EACbK,OAAe;IAEf,IAAIK,WAAW,GAAG,OAAO;QAAEF,MAAM;IAAwB;IACzD,MAAMD,UAAUR,YAAYC;IAC5B,IAAIU,WAAW,KAAK,OAAO;QAAEF,MAAM;IAAwB;IAC3D,IAAID,YAAY,QAAQV,gBAAgBc,GAAG,CAACJ,QAAQL,IAAI,GACtD,OAAO;QAAEM,MAAM;IAAwB;IACzC,IAAID,YAAY,QAAQA,QAAQL,IAAI,KAAK,oBAAoB,OAAO;QAAEM,MAAM;IAAiB;IAC7F,IAAIE,WAAW,OAAOH,SAASL,SAAS,kBAAkB;QACxD,OAAO;YAAEM,MAAM;YAAqBH;QAAQ;IAC9C;IACA,IAAIK,UAAU,KAAK,OAAO;QAAEF,MAAM;IAAwB;IAC1D,IAAIE,SAAS,KAAK,OAAO;IACzB,IAAIH,YAAY,MAAM,OAAO;QAAEC,MAAM;IAAwB;IAC7D,IAAIE,WAAW,KAAK,OAAON,cAAcC,SAAS,aAAaE;IAC/D,OAAOH,cAAcC,SAAS,eAAeE;AAC/C;AAEA,OAAO,SAASK,iBACdC,UAAuD;IAEvD,IAAIA,WAAWL,IAAI,KAAK,yBAAyB,OAAOK;IACxD,IAAIA,WAAWL,IAAI,KAAK,kBAAkB;QACxC,OAAO;YAAEA,MAAM;YAAwBN,MAAMW,WAAWX,IAAI;YAAEC,QAAQU,WAAWV,MAAM;QAAC;IAC1F;IACA,OAAO;QAAEK,MAAM;IAAwB;AACzC"}
|
package/dist/site.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAOR,MAAM,wBAAwB,CAAC;AAgChC,OAAO,EAML,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAgCxB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,GAAG,OAAO,CA0IxE"}
|
package/dist/site.js
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { actionOutcome } from './actions.js';
|
|
2
|
+
import { mapDiscovery, parseSiteDiscovery, siteCapabilities, siteSlots, siteTracked } from './discovery.js';
|
|
3
|
+
import { MODEL_ABSENT, failedModel, heldModel, modelKey, modelShelf } from './model.js';
|
|
4
|
+
import { advancedScope, authorityRoot, bootstrapOf, definitionsOf, parseEnumeration, parseSiteBootstrap, refreshFrom, selectionRoots } from './read.js';
|
|
5
|
+
import { classifyDoor, discoveryFailure } from './refusal.js';
|
|
6
|
+
import { houseNotifications } from './stream.js';
|
|
7
|
+
import { PRIVATE_LOCATOR, SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT } from './transport.js';
|
|
8
|
+
import { logPosition, presented, roomVersion } from './version.js';
|
|
9
|
+
const UNCERTAIN = {
|
|
10
|
+
kind: 'transport-uncertainty'
|
|
11
|
+
};
|
|
12
|
+
function siteRoom(tracked, attachedModel) {
|
|
13
|
+
const read = selectionRoots(tracked);
|
|
14
|
+
return {
|
|
15
|
+
name: tracked.handle,
|
|
16
|
+
locator: tracked.locator,
|
|
17
|
+
collectionRoot: tracked.collectionRoot,
|
|
18
|
+
roomVersion: roomVersion(tracked),
|
|
19
|
+
operations: {
|
|
20
|
+
read: [
|
|
21
|
+
...read
|
|
22
|
+
],
|
|
23
|
+
sync: [
|
|
24
|
+
...read
|
|
25
|
+
],
|
|
26
|
+
write: [],
|
|
27
|
+
delete: []
|
|
28
|
+
},
|
|
29
|
+
replica: {
|
|
30
|
+
selection: tracked.locator,
|
|
31
|
+
admission: 'admitted'
|
|
32
|
+
},
|
|
33
|
+
attachedModel,
|
|
34
|
+
providerOwnedPaths: []
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function settled(refused) {
|
|
38
|
+
return refused.kind === 'beyond-horizon' ? UNCERTAIN : refused;
|
|
39
|
+
}
|
|
40
|
+
export function createSiteAdapter(transport) {
|
|
41
|
+
const notifications = houseNotifications(transport, 'site');
|
|
42
|
+
const tracked = new Map();
|
|
43
|
+
const models = modelShelf();
|
|
44
|
+
const acquired = new Map();
|
|
45
|
+
let caught = new Map();
|
|
46
|
+
async function enumeration(entry, from) {
|
|
47
|
+
const answer = await transport.door(SITE_DOOR_ENUMERATE, {
|
|
48
|
+
positions: [
|
|
49
|
+
presented(entry.authority, from)
|
|
50
|
+
]
|
|
51
|
+
});
|
|
52
|
+
const classified = classifyDoor(answer.status, answer.body, entry.locator);
|
|
53
|
+
if (classified !== null) return classified;
|
|
54
|
+
return parseEnumeration(answer.body, 'site') ?? UNCERTAIN;
|
|
55
|
+
}
|
|
56
|
+
async function caughtUp(entry) {
|
|
57
|
+
const answer = await transport.read(`${SITE_DOOR_BOOTSTRAP}${entry.authority}`);
|
|
58
|
+
const classified = classifyDoor(answer.status, answer.body, entry.locator);
|
|
59
|
+
if (classified !== null) return {
|
|
60
|
+
failure: settled(classified)
|
|
61
|
+
};
|
|
62
|
+
const scope = parseSiteBootstrap(answer.body);
|
|
63
|
+
if (scope === null) return {
|
|
64
|
+
failure: UNCERTAIN
|
|
65
|
+
};
|
|
66
|
+
if (roomVersion(scope) === roomVersion(entry)) return {
|
|
67
|
+
scope
|
|
68
|
+
};
|
|
69
|
+
const found = await enumeration(entry, scope);
|
|
70
|
+
if ('kind' in found) return {
|
|
71
|
+
failure: settled(found)
|
|
72
|
+
};
|
|
73
|
+
const view = found.authorities.find((held)=>held.authority === entry.authority);
|
|
74
|
+
if (view === undefined) return {
|
|
75
|
+
failure: {
|
|
76
|
+
kind: 'room-not-readable',
|
|
77
|
+
locator: entry.locator
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
return {
|
|
81
|
+
scope: advancedScope(scope, view)
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
async function refreshed(entry, fromRoomVersion) {
|
|
85
|
+
const from = logPosition(fromRoomVersion);
|
|
86
|
+
if (from === null) return {
|
|
87
|
+
kind: 'beyond-horizon'
|
|
88
|
+
};
|
|
89
|
+
const streamed = notifications.advance(entry, from);
|
|
90
|
+
if (streamed !== null) return streamed;
|
|
91
|
+
const found = await enumeration(entry, from);
|
|
92
|
+
if ('kind' in found) return found;
|
|
93
|
+
return refreshFrom(found, entry, fromRoomVersion);
|
|
94
|
+
}
|
|
95
|
+
async function acquire(entry, held) {
|
|
96
|
+
if ('failure' in held) return {
|
|
97
|
+
snapshot: failedModel(held.failure),
|
|
98
|
+
identity: null
|
|
99
|
+
};
|
|
100
|
+
const model = await heldModel(definitionsOf(held.scope, entry.modelRoot), `${authorityRoot(entry.handle)}/${entry.modelRoot}`, MODEL_ABSENT);
|
|
101
|
+
acquired.set(entry.authority, {
|
|
102
|
+
roomVersion: roomVersion(held.scope),
|
|
103
|
+
model
|
|
104
|
+
});
|
|
105
|
+
return model;
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
async authorize () {
|
|
109
|
+
return {};
|
|
110
|
+
},
|
|
111
|
+
async model (_authorization, request) {
|
|
112
|
+
return models.answer(request);
|
|
113
|
+
},
|
|
114
|
+
async discover () {
|
|
115
|
+
const answer = await transport.door(SITE_DOOR_DISCOVER, {});
|
|
116
|
+
const classified = classifyDoor(answer.status, answer.body, PRIVATE_LOCATOR);
|
|
117
|
+
if (classified !== null) return discoveryFailure(classified);
|
|
118
|
+
const document = parseSiteDiscovery(answer.body);
|
|
119
|
+
if (document === null) return UNCERTAIN;
|
|
120
|
+
const entries = siteTracked(document);
|
|
121
|
+
tracked.clear();
|
|
122
|
+
for (const entry of entries)tracked.set(entry.locator, entry);
|
|
123
|
+
notifications.track(entries);
|
|
124
|
+
const published = new Set(entries.map((entry)=>entry.authority));
|
|
125
|
+
for (const authority of [
|
|
126
|
+
...acquired.keys()
|
|
127
|
+
]){
|
|
128
|
+
if (!published.has(authority)) acquired.delete(authority);
|
|
129
|
+
}
|
|
130
|
+
const fresh = new Map();
|
|
131
|
+
const current = new Map();
|
|
132
|
+
for (const entry of entries){
|
|
133
|
+
const kept = acquired.get(entry.authority);
|
|
134
|
+
if (kept !== undefined && kept.roomVersion === roomVersion(entry)) {
|
|
135
|
+
current.set(entry.authority, kept.model);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const held = await caughtUp(entry);
|
|
139
|
+
fresh.set(entry.authority, held);
|
|
140
|
+
current.set(entry.authority, await acquire(entry, held));
|
|
141
|
+
}
|
|
142
|
+
caught = fresh;
|
|
143
|
+
const rooms = entries.map((entry)=>{
|
|
144
|
+
const shelved = models.retain(modelKey(entry.locator, 'collection'), current.get(entry.authority));
|
|
145
|
+
return siteRoom(entry, shelved?.identity ?? null);
|
|
146
|
+
});
|
|
147
|
+
models.keep(entries.map((entry)=>entry.locator));
|
|
148
|
+
return {
|
|
149
|
+
...mapDiscovery(document, rooms, siteCapabilities()),
|
|
150
|
+
slots: siteSlots(document)
|
|
151
|
+
};
|
|
152
|
+
},
|
|
153
|
+
async bootstrap (_authorization, request) {
|
|
154
|
+
const entry = tracked.get(request.locator);
|
|
155
|
+
if (entry === undefined) return {
|
|
156
|
+
kind: 'room-not-readable',
|
|
157
|
+
locator: request.locator
|
|
158
|
+
};
|
|
159
|
+
if (request.pageToken !== undefined) return UNCERTAIN;
|
|
160
|
+
const held = caught.get(entry.authority) ?? await caughtUp(entry);
|
|
161
|
+
if ('failure' in held) return held.failure;
|
|
162
|
+
return bootstrapOf(held.scope, entry);
|
|
163
|
+
},
|
|
164
|
+
async refresh (_authorization, request) {
|
|
165
|
+
const entry = tracked.get(request.locator);
|
|
166
|
+
if (entry === undefined) return {
|
|
167
|
+
kind: 'room-not-readable',
|
|
168
|
+
locator: request.locator
|
|
169
|
+
};
|
|
170
|
+
if (request.pageToken !== undefined) return UNCERTAIN;
|
|
171
|
+
const result = await refreshed(entry, request.fromRoomVersion);
|
|
172
|
+
if (result.kind === 'beyond-horizon') caught.delete(entry.authority);
|
|
173
|
+
return result;
|
|
174
|
+
},
|
|
175
|
+
async mutate () {
|
|
176
|
+
return {
|
|
177
|
+
kind: 'rejected',
|
|
178
|
+
affected: {},
|
|
179
|
+
code: 'write-grant',
|
|
180
|
+
fields: {}
|
|
181
|
+
};
|
|
182
|
+
},
|
|
183
|
+
async history () {
|
|
184
|
+
return {
|
|
185
|
+
kind: 'no-history'
|
|
186
|
+
};
|
|
187
|
+
},
|
|
188
|
+
async action (_authorization, request) {
|
|
189
|
+
if (request.name !== 'submit') {
|
|
190
|
+
return {
|
|
191
|
+
kind: 'rejected',
|
|
192
|
+
code: 'action-unimplemented',
|
|
193
|
+
fields: {
|
|
194
|
+
name: request.name
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
if (!transport.online()) return UNCERTAIN;
|
|
199
|
+
return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input), 'submit');
|
|
200
|
+
},
|
|
201
|
+
roomVersions: notifications
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
//# sourceMappingURL=site.js.map
|