@agentshouse/mdruntime-adapter 0.1.0-c8654c2657ee5 → 0.1.0-c86eddcb309ff

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/dist/read.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { BootstrapPage, RefreshResult, RoomAttachment } from '@agentshouse/mdruntime';
1
+ import type { BinaryFile, BootstrapPage, RefreshResult } from '@agentshouse/mdruntime';
2
2
  import type { TrackedAuthority } from './discovery.js';
3
3
  import type { HouseMode } from './transport.js';
4
4
  import { type LogPosition } from './version.js';
@@ -8,6 +8,7 @@ export type HouseManifestFile = {
8
8
  revision: string | undefined;
9
9
  version: string;
10
10
  head?: HeadChange;
11
+ binary?: BinaryFile;
11
12
  };
12
13
  export type HouseContent = {
13
14
  path: string;
@@ -17,10 +18,14 @@ export type HouseScope = LogPosition & {
17
18
  anchor: string;
18
19
  files: readonly HouseManifestFile[];
19
20
  contents: readonly HouseContent[];
20
- attachments?: readonly RoomAttachment[];
21
+ };
22
+ export type HouseCursor = {
23
+ room: string;
24
+ path: string | null;
21
25
  };
22
26
  export type HouseEnvelope = {
23
27
  scopes: readonly HouseScope[];
28
+ next?: HouseCursor;
24
29
  };
25
30
  export type HouseGrant = {
26
31
  method: 'GET';
@@ -41,14 +46,14 @@ export type HouseChange = {
41
46
  head?: HeadChange;
42
47
  } | {
43
48
  path: string;
44
- reference: {
45
- revision: string;
46
- };
49
+ binary: BinaryFile;
50
+ revision: string | undefined;
51
+ version: string;
52
+ head?: HeadChange;
47
53
  };
48
54
  export type HouseView = LogPosition & {
49
55
  authority: string;
50
56
  changes: readonly HouseChange[];
51
- attachments?: readonly RoomAttachment[];
52
57
  };
53
58
  export type HouseEnumeration = {
54
59
  authorities: readonly HouseView[];
@@ -61,7 +66,7 @@ export declare function headChange(held: {
61
66
  readonly author?: unknown;
62
67
  readonly created_at?: unknown;
63
68
  }): HeadChange | undefined | null;
64
- export declare function parseOriginals(value: unknown): readonly RoomAttachment[] | null;
69
+ export declare function binaryFileOf(held: Readonly<Record<string, unknown>>): BinaryFile | undefined | null;
65
70
  export declare function parseEnvelope(body: unknown): HouseEnvelope | null;
66
71
  export declare function parseSiteBootstrap(body: unknown): HouseScope | null;
67
72
  export declare function parseEnumeration(body: unknown, mode: HouseMode): HouseEnumeration | null;
@@ -71,6 +76,7 @@ export declare function bootstrapOf(scope: HouseScope): BootstrapPage;
71
76
  export type HouseSchema = {
72
77
  schema: string | null;
73
78
  version: string | null;
79
+ revision: string | null;
74
80
  };
75
81
  export declare function schemaOf(scope: HouseScope, schema: string): HouseSchema | null;
76
82
  export declare function viewOf(enumeration: HouseEnumeration, tracked: TrackedAuthority): HouseView | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../src/read.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../src/read.ts"],"names":[],"mappings":"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"}
package/dist/read.js CHANGED
@@ -51,32 +51,19 @@ export function headChange(held) {
51
51
  function headed(head) {
52
52
  return head === undefined ? {} : { head };
53
53
  }
54
- function parseOriginal(value) {
55
- if (typeof value !== 'object' || value === null)
56
- return null;
57
- const { attachment, name, bytes, media_type: mediaType } = value;
58
- if (typeof attachment !== 'string' || typeof name !== 'string')
59
- return null;
60
- if (typeof bytes !== 'number' || !Number.isSafeInteger(bytes) || bytes < 0)
61
- return null;
62
- if (mediaType !== null && typeof mediaType !== 'string')
54
+ export function binaryFileOf(held) {
55
+ if (held.file === undefined)
56
+ return undefined;
57
+ const { file, bytes, media_type: mediaType, sha256 } = held;
58
+ if (typeof file !== 'string' ||
59
+ typeof bytes !== 'number' ||
60
+ typeof mediaType !== 'string' ||
61
+ typeof sha256 !== 'string')
63
62
  return null;
64
- return { reference: attachment, name, byteLength: bytes, mediaType, entry: value };
63
+ return { fileRef: file, byteLength: bytes, mediaType, sha256 };
65
64
  }
66
- export function parseOriginals(value) {
67
- if (!Array.isArray(value))
68
- return null;
69
- const attachments = [];
70
- for (const entry of value) {
71
- const attachment = parseOriginal(entry);
72
- if (attachment === null)
73
- return null;
74
- attachments.push(attachment);
75
- }
76
- return attachments;
77
- }
78
- function declared(attachments) {
79
- return attachments === undefined ? {} : { attachments };
65
+ function binaried(binary) {
66
+ return binary === undefined ? {} : { binary };
80
67
  }
81
68
  function parseFile(value, mode) {
82
69
  if (typeof value !== 'object' || value === null)
@@ -85,16 +72,29 @@ function parseFile(value, mode) {
85
72
  if (typeof file.path !== 'string')
86
73
  return null;
87
74
  const head = headChange(file);
88
- if (head === null)
75
+ const binary = binaryFileOf(file);
76
+ if (head === null || binary === null)
89
77
  return null;
90
78
  if (mode === 'site') {
91
79
  if (typeof file.sha256 !== 'string')
92
80
  return null;
93
- return { path: file.path, revision: undefined, version: file.sha256, ...headed(head) };
81
+ return {
82
+ path: file.path,
83
+ revision: binary?.sha256,
84
+ version: file.sha256,
85
+ ...headed(head),
86
+ ...binaried(binary),
87
+ };
94
88
  }
95
89
  if (typeof file.revision !== 'string')
96
90
  return null;
97
- return { path: file.path, revision: file.revision, version: file.revision, ...headed(head) };
91
+ return {
92
+ path: file.path,
93
+ revision: file.revision,
94
+ version: file.revision,
95
+ ...headed(head),
96
+ ...binaried(binary),
97
+ };
98
98
  }
99
99
  function parseScope(value, mode) {
100
100
  if (typeof value !== 'object' || value === null)
@@ -130,12 +130,15 @@ function parseScope(value, mode) {
130
130
  return null;
131
131
  contents.push({ path: content.path, content: content.content });
132
132
  }
133
- if (mode === 'site')
134
- return { anchor: manifest.anchor, ...at, files, contents };
135
- const attachments = parseOriginals(held.originals);
136
- if (attachments === null)
133
+ return { anchor: manifest.anchor, ...at, files, contents };
134
+ }
135
+ function parseCursor(value) {
136
+ if (typeof value !== 'object' || value === null)
137
+ return null;
138
+ const { room, path } = value;
139
+ if (typeof room !== 'string' || (path !== null && typeof path !== 'string'))
137
140
  return null;
138
- return { anchor: manifest.anchor, ...at, files, contents, attachments };
141
+ return { room, path };
139
142
  }
140
143
  export function parseEnvelope(body) {
141
144
  if (typeof body !== 'object' || body === null)
@@ -149,7 +152,10 @@ export function parseEnvelope(body) {
149
152
  return null;
150
153
  scopes.push(scope);
151
154
  }
152
- return { scopes };
155
+ if (!('next' in body) || body.next === undefined)
156
+ return { scopes };
157
+ const next = parseCursor(body.next);
158
+ return next === null ? null : { scopes, next };
153
159
  }
154
160
  export function parseSiteBootstrap(body) {
155
161
  return parseScope(body, 'site');
@@ -163,8 +169,15 @@ function parseChange(value, mode) {
163
169
  if (held.removed === true)
164
170
  return { path: held.path, removed: true };
165
171
  const head = headChange(held);
166
- if (head === null)
172
+ const binary = binaryFileOf(held);
173
+ if (head === null || binary === null)
167
174
  return null;
175
+ if (binary !== undefined) {
176
+ if (mode === 'credential' && typeof held.revision !== 'string')
177
+ return null;
178
+ const revision = typeof held.revision === 'string' ? held.revision : binary.sha256;
179
+ return { path: held.path, binary, revision, version: revision, ...headed(head) };
180
+ }
168
181
  if (mode === 'site') {
169
182
  if (typeof held.content !== 'string' || typeof held.sha256 !== 'string')
170
183
  return null;
@@ -185,12 +198,6 @@ function parseChange(value, mode) {
185
198
  ...headed(head),
186
199
  };
187
200
  }
188
- if (typeof held.reference === 'object' && held.reference !== null) {
189
- const reference = held.reference;
190
- if (typeof reference.revision !== 'string')
191
- return null;
192
- return { path: held.path, reference: { revision: reference.revision } };
193
- }
194
201
  return null;
195
202
  }
196
203
  export function parseEnumeration(body, mode) {
@@ -215,14 +222,7 @@ export function parseEnumeration(body, mode) {
215
222
  return null;
216
223
  changes.push(mapped);
217
224
  }
218
- if (mode === 'site') {
219
- authorities.push({ authority: held.authority, ...at, changes });
220
- continue;
221
- }
222
- const attachments = parseOriginals(held.originals);
223
- if (attachments === null)
224
- return null;
225
- authorities.push({ authority: held.authority, ...at, changes, attachments });
225
+ authorities.push({ authority: held.authority, ...at, changes });
226
226
  }
227
227
  return { authorities };
228
228
  }
@@ -234,18 +234,15 @@ export function advancedScope(scope, view) {
234
234
  contents.delete(change.path);
235
235
  if ('removed' in change)
236
236
  continue;
237
- if ('content' in change) {
238
- files.set(change.path, {
239
- path: change.path,
240
- revision: change.revision,
241
- version: change.version,
242
- ...headed(change.head),
243
- });
237
+ files.set(change.path, {
238
+ path: change.path,
239
+ revision: change.revision,
240
+ version: change.version,
241
+ ...headed(change.head),
242
+ ...('binary' in change ? { binary: change.binary } : {}),
243
+ });
244
+ if ('content' in change)
244
245
  contents.set(change.path, change.content);
245
- continue;
246
- }
247
- const { revision } = change.reference;
248
- files.set(change.path, { path: change.path, revision, version: revision });
249
246
  }
250
247
  return {
251
248
  ...scope,
@@ -263,16 +260,16 @@ export function bootstrapOf(scope) {
263
260
  const documents = {};
264
261
  const revisions = {};
265
262
  const changes = {};
266
- const binaryTargets = [];
263
+ const binaryFiles = {};
267
264
  for (const file of scope.files) {
268
265
  if (file.revision !== undefined)
269
266
  revisions[file.path] = file.revision;
270
267
  if (file.head !== undefined)
271
268
  changes[file.path] = file.head;
272
269
  const content = contents.get(file.path);
273
- if (content === undefined)
274
- binaryTargets.push(file.path);
275
- else
270
+ if (file.binary !== undefined)
271
+ binaryFiles[file.path] = file.binary;
272
+ else if (content !== undefined)
276
273
  documents[file.path] = content;
277
274
  }
278
275
  return {
@@ -281,16 +278,17 @@ export function bootstrapOf(scope) {
281
278
  documents,
282
279
  revisions,
283
280
  changes,
284
- binaryTargets: binaryTargets.sort(),
285
- ...declared(scope.attachments),
281
+ binaryFiles,
286
282
  };
287
283
  }
288
284
  export function schemaOf(scope, schema) {
289
285
  const file = scope.files.find((entry) => entry.path === schema);
290
286
  if (file === undefined)
291
- return { schema: null, version: null };
287
+ return { schema: null, version: null, revision: null };
292
288
  const content = scope.contents.find((entry) => entry.path === schema);
293
- return content === undefined ? null : { schema: content.content, version: file.version };
289
+ return content === undefined
290
+ ? null
291
+ : { schema: content.content, version: file.version, revision: file.revision ?? null };
294
292
  }
295
293
  export function viewOf(enumeration, tracked) {
296
294
  return enumeration.authorities.find((entry) => entry.authority === tracked.authority);
@@ -301,23 +299,21 @@ export function refreshFrom(view, fromRoomVersion) {
301
299
  const documents = {};
302
300
  const revisions = {};
303
301
  const changes = {};
304
- const binaryTargets = [];
302
+ const binaryFiles = {};
305
303
  const removals = [];
306
304
  for (const change of view.changes) {
307
305
  if ('removed' in change) {
308
306
  removals.push(change.path);
309
307
  continue;
310
308
  }
311
- if ('content' in change) {
309
+ if ('content' in change)
312
310
  documents[change.path] = change.content;
313
- if (change.revision !== undefined)
314
- revisions[change.path] = change.revision;
315
- if (change.head !== undefined)
316
- changes[change.path] = change.head;
317
- continue;
318
- }
319
- binaryTargets.push(change.path);
320
- revisions[change.path] = change.reference.revision;
311
+ else
312
+ binaryFiles[change.path] = change.binary;
313
+ if (change.revision !== undefined)
314
+ revisions[change.path] = change.revision;
315
+ if (change.head !== undefined)
316
+ changes[change.path] = change.head;
321
317
  }
322
318
  return {
323
319
  kind: 'net-advancement',
@@ -325,8 +321,7 @@ export function refreshFrom(view, fromRoomVersion) {
325
321
  documents,
326
322
  revisions,
327
323
  changes,
328
- binaryTargets: binaryTargets.sort(),
324
+ binaryFiles,
329
325
  removals: removals.sort(),
330
- ...declared(view.attachments),
331
326
  };
332
327
  }
@@ -0,0 +1,7 @@
1
+ import type { TrackedAuthority } from './discovery.js';
2
+ export type HouseReferrer = {
3
+ locator: string;
4
+ referrer: Readonly<Record<string, string>>;
5
+ };
6
+ export declare function houseReferrer(referrer: unknown, tracked: ReadonlyMap<string, TrackedAuthority>): HouseReferrer | null;
7
+ //# sourceMappingURL=referrer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"referrer.d.ts","sourceRoot":"","sources":["../src/referrer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,MAAM,MAAM,aAAa,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,CAAC;AAgB5F,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC7C,aAAa,GAAG,IAAI,CAqBtB"}
@@ -0,0 +1,35 @@
1
+ function fields(value) {
2
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
3
+ ? value
4
+ : null;
5
+ }
6
+ function named(held, ...keys) {
7
+ const present = Object.keys(held);
8
+ return (present.length === keys.length &&
9
+ keys.every((key) => typeof held[key] === 'string' && held[key] !== ''));
10
+ }
11
+ export function houseReferrer(referrer, tracked) {
12
+ const held = fields(referrer);
13
+ if (held === null)
14
+ return null;
15
+ if (named(held, 'room', 'path')) {
16
+ const entry = tracked.get(held.room);
17
+ if (entry === undefined)
18
+ return null;
19
+ return {
20
+ locator: entry.locator,
21
+ referrer: { room_ref: entry.authority, path: held.path },
22
+ };
23
+ }
24
+ if (named(held, 'room_ref', 'record')) {
25
+ const roomRef = held.room_ref;
26
+ const entry = [...tracked.values()].find((candidate) => candidate.authority === roomRef);
27
+ return {
28
+ locator: entry?.locator ?? roomRef,
29
+ referrer: { room_ref: roomRef, record: held.record },
30
+ };
31
+ }
32
+ if (named(held, 'message'))
33
+ return { locator: '', referrer: { message: held.message } };
34
+ return null;
35
+ }
package/dist/refusal.d.ts CHANGED
@@ -1,9 +1,6 @@
1
1
  import type { AdapterFailure, DiscoverResult, ProviderRefusal, ScopedRefusal } from '@agentshouse/mdruntime';
2
- export type DoorRefusal = ProviderRefusal & {
3
- retryable: boolean;
4
- };
5
- export declare function doorRefusal(body: unknown): DoorRefusal | null;
6
- export declare function scopedRefusal(locator: string, scope: ScopedRefusal['scope'], refusal: DoorRefusal): ScopedRefusal;
2
+ export declare function doorRefusal(body: unknown): ProviderRefusal | null;
3
+ export declare function scopedRefusal(locator: string, scope: ScopedRefusal['scope'], refusal: ProviderRefusal): ScopedRefusal;
7
4
  export declare function classifyDoor(status: number, body: unknown, locator: string): AdapterFailure | null;
8
5
  export declare function classifyRead(status: number, body: unknown, locator: string): AdapterFailure | {
9
6
  kind: 'beyond-horizon';
@@ -1 +1 @@
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;AAEhC,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnE,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;AAmBD,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,GACd,cAAc,GAAG,IAAI,CAMvB;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,CAGpD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAYrF"}
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;AAEhC,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAOjE;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,EAC7B,OAAO,EAAE,eAAe,GACvB,aAAa,CAEf;AAmBD,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,GACd,cAAc,GAAG,IAAI,CAMvB;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,CAGpD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAQrF"}
package/dist/refusal.js CHANGED
@@ -6,11 +6,11 @@ export function doorRefusal(body) {
6
6
  const error = body.error;
7
7
  if (typeof error.code !== 'string')
8
8
  return null;
9
- const { code, ...fields } = error;
10
- return { code, fields, retryable: error.retryable === true };
9
+ const { code, retryable, ...fields } = error;
10
+ return { code, fields, retryable: retryable === true };
11
11
  }
12
12
  export function scopedRefusal(locator, scope, refusal) {
13
- return { kind: 'scoped-refusal', locator, scope, code: refusal.code, fields: refusal.fields };
13
+ return { kind: 'scoped-refusal', locator, scope, ...refusal };
14
14
  }
15
15
  function doorFailure(status, body) {
16
16
  if (status === 0)
@@ -50,11 +50,7 @@ export function discoveryFailure(status, body) {
50
50
  if (failure.kind === 'revoked-authorization')
51
51
  return failure;
52
52
  if (failure.kind === 'refused') {
53
- return {
54
- kind: 'contract-unavailable',
55
- code: failure.refusal.code,
56
- fields: failure.refusal.fields,
57
- };
53
+ return { kind: 'contract-unavailable', ...failure.refusal };
58
54
  }
59
55
  return { kind: 'transport-uncertainty' };
60
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAMR,MAAM,wBAAwB,CAAC;AAsBhC,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAgCxB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,GAAG,OAAO,CAiIxE"}
1
+ {"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAOR,MAAM,wBAAwB,CAAC;AAsBhC,OAAO,EAOL,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAiCxB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,GAAG,OAAO,CA8KxE"}
package/dist/site.js CHANGED
@@ -4,7 +4,8 @@ import { scopeModels, streamedModels, viewModels } from './model.js';
4
4
  import { advancedScope, bootstrapOf, parseEnumeration, parseSiteBootstrap, refreshFrom, viewOf, } from './read.js';
5
5
  import { classifyDoor, classifyRead, discoveryFailure } from './refusal.js';
6
6
  import { houseNotifications } from './stream.js';
7
- import { SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT, } from './transport.js';
7
+ import { SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT, SITE_FILE_RECORD, SITE_FILES, } from './transport.js';
8
+ import { houseReferrer } from './referrer.js';
8
9
  import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
9
10
  const UNCERTAIN = { kind: 'transport-uncertainty' };
10
11
  function siteRoom(tracked) {
@@ -24,6 +25,10 @@ function settled(refused) {
24
25
  export function createSiteAdapter(transport) {
25
26
  const notifications = houseNotifications(transport, 'site');
26
27
  const tracked = new Map();
28
+ function published(referrer) {
29
+ const named = houseReferrer(referrer, tracked);
30
+ return named === null || !tracked.has(named.locator) ? null : named;
31
+ }
27
32
  async function enumeration(entry, from) {
28
33
  const answer = await transport.door(SITE_DOOR_ENUMERATE, {
29
34
  positions: [presented(entry.authority, from)],
@@ -74,6 +79,7 @@ export function createSiteAdapter(transport) {
74
79
  return models === undefined ? answer : { ...answer, models };
75
80
  }
76
81
  return {
82
+ localSaves: true,
77
83
  async authorize() {
78
84
  return {};
79
85
  },
@@ -114,11 +120,37 @@ export function createSiteAdapter(transport) {
114
120
  return refreshed(entry, request.fromRoomVersion);
115
121
  },
116
122
  async mutate() {
117
- return { kind: 'rejected', affected: {}, code: 'write-grant', fields: {} };
123
+ return { kind: 'rejected', affected: {}, code: 'write-grant', fields: {}, retryable: false };
118
124
  },
119
125
  async history() {
120
126
  return { kind: 'no-history' };
121
127
  },
128
+ async binary(_authorization, request) {
129
+ const named = published(request.kind === 'path' ? { room: request.locator, path: request.path } : request.referrer);
130
+ if (named === null) {
131
+ return { kind: 'rejected', code: 'referrer_unknown', fields: {}, retryable: false };
132
+ }
133
+ if (request.fileRef === undefined) {
134
+ return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
135
+ }
136
+ const { room_ref, path, record } = named.referrer;
137
+ const read = await transport.download(`${SITE_FILES}${room_ref}/${encodeURIComponent(request.fileRef)}/${path === undefined
138
+ ? `${SITE_FILE_RECORD}/${encodeURIComponent(record)}`
139
+ : encodeURIComponent(path)}`);
140
+ if (read.status === 404) {
141
+ return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
142
+ }
143
+ return read.status === 200 && read.blob !== null
144
+ ? { kind: 'binary', blob: read.blob }
145
+ : UNCERTAIN;
146
+ },
147
+ referrerScope(referrer) {
148
+ const named = published(referrer);
149
+ if (named === null)
150
+ return null;
151
+ const { path } = named.referrer;
152
+ return { kind: 'room', locator: named.locator, ...(path === undefined ? {} : { path }) };
153
+ },
122
154
  reached(locator, version, target) {
123
155
  return reachedVersion(version, target, tracked.get(locator)?.logEpoch);
124
156
  },
@@ -127,7 +159,12 @@ export function createSiteAdapter(transport) {
127
159
  },
128
160
  async action(_authorization, request) {
129
161
  if (request.name !== 'submit') {
130
- return { kind: 'rejected', code: 'action-unimplemented', fields: { name: request.name } };
162
+ return {
163
+ kind: 'rejected',
164
+ code: 'action-unimplemented',
165
+ fields: { name: request.name },
166
+ retryable: false,
167
+ };
131
168
  }
132
169
  if (!transport.online())
133
170
  return UNCERTAIN;
@@ -144,6 +181,7 @@ export function createSiteAdapter(transport) {
144
181
  return [presented(entry.authority, at)];
145
182
  }));
146
183
  },
184
+ reopen: notifications.reopen,
147
185
  observe: notifications.observe,
148
186
  },
149
187
  serviceMode: notifications.serviceMode,
package/dist/stream.d.ts CHANGED
@@ -12,6 +12,7 @@ export type HouseNotifications = {
12
12
  runtime: string;
13
13
  observe(notify: (event: RoomStreamEvent) => void): () => void;
14
14
  send(rooms: readonly HouseHeldRoom[]): void;
15
+ reopen(): void;
15
16
  track(authorities: readonly TrackedAuthority[]): void;
16
17
  reach(authority: string, at: LogPosition): void;
17
18
  advance(tracked: TrackedAuthority, from: LogPosition, holds?: HeldRevision): StreamedAdvancement | null;
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,kBAAkB,EAElB,WAAW,EACX,eAAe,EAEf,iBAAiB,EAElB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EAEb,SAAS,EAET,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAgB7D,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;AAEvE,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACrC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC9D,IAAI,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACtD,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IAChD,OAAO,CACL,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,WAAW,EACjB,KAAK,CAAC,EAAE,YAAY,GACnB,mBAAmB,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,kBAAkB,CAAC;IAClC,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAuBF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,kBAAkB,CAoS5F"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,kBAAkB,EAElB,WAAW,EACX,eAAe,EAEf,iBAAiB,EAElB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EAEb,SAAS,EAET,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAgB7D,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;AAEvE,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACrC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC9D,IAAI,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAC;IAC5C,MAAM,IAAI,IAAI,CAAC;IACf,KAAK,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACtD,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IAChD,OAAO,CACL,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,WAAW,EACjB,KAAK,CAAC,EAAE,YAAY,GACnB,mBAAmB,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,kBAAkB,CAAC;IAClC,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAuBF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,kBAAkB,CA8S5F"}
package/dist/stream.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { acceptedMessage } from './actions.js';
2
- import { headChange } from './read.js';
2
+ import { binaryFileOf, headChange } from './read.js';
3
3
  import { roomVersion } from './version.js';
4
4
  const HELD_FRAMES_MAX = 256;
5
5
  function turnOperation(frame) {
@@ -222,6 +222,11 @@ export function houseNotifications(transport, mode) {
222
222
  opening = null;
223
223
  current?.hold(rooms, runtime);
224
224
  },
225
+ reopen() {
226
+ const current = opening;
227
+ opening = null;
228
+ current?.close();
229
+ },
225
230
  track(entries) {
226
231
  locators.clear();
227
232
  for (const entry of entries) {
@@ -260,6 +265,7 @@ export function houseNotifications(transport, mode) {
260
265
  const documents = {};
261
266
  const revisions = {};
262
267
  const changes = {};
268
+ const binaryFiles = {};
263
269
  const removals = [];
264
270
  const applied = [];
265
271
  const schemas = new Map();
@@ -267,6 +273,7 @@ export function houseNotifications(transport, mode) {
267
273
  delete documents[path];
268
274
  delete revisions[path];
269
275
  delete changes[path];
276
+ delete binaryFiles[path];
270
277
  const removed = removals.indexOf(path);
271
278
  if (removed !== -1)
272
279
  removals.splice(removed, 1);
@@ -287,7 +294,8 @@ export function houseNotifications(transport, mode) {
287
294
  removals.push(entry.path);
288
295
  continue;
289
296
  }
290
- if (entry.text === undefined)
297
+ const binary = binaryFileOf(entry);
298
+ if (binary === null || (binary === undefined && entry.text === undefined))
291
299
  return null;
292
300
  if (mode === 'credential' && entry.revision === undefined)
293
301
  return null;
@@ -295,9 +303,13 @@ export function houseNotifications(transport, mode) {
295
303
  if (head === null)
296
304
  return null;
297
305
  forget(entry.path);
298
- documents[entry.path] = entry.text;
299
- if (entry.revision !== undefined)
300
- revisions[entry.path] = entry.revision;
306
+ if (binary === undefined)
307
+ documents[entry.path] = entry.text;
308
+ else
309
+ binaryFiles[entry.path] = binary;
310
+ const revision = entry.revision ?? binary?.sha256;
311
+ if (revision !== undefined)
312
+ revisions[entry.path] = revision;
301
313
  if (head !== undefined)
302
314
  changes[entry.path] = head;
303
315
  }
@@ -311,7 +323,7 @@ export function houseNotifications(transport, mode) {
311
323
  documents,
312
324
  revisions,
313
325
  changes,
314
- binaryTargets: [],
326
+ binaryFiles,
315
327
  removals: removals.sort(),
316
328
  },
317
329
  entries: applied,