@agentshouse/mdruntime-adapter 0.1.0-cd59fd8945dcb → 0.1.0-cda5b3be3317e

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.
Files changed (46) hide show
  1. package/AGENTS.md +271 -262
  2. package/dist/actions.d.ts +23 -0
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +68 -31
  5. package/dist/adapter.d.ts +1 -0
  6. package/dist/adapter.d.ts.map +1 -1
  7. package/dist/adapter.js +261 -64
  8. package/dist/discovery.d.ts +2 -1
  9. package/dist/discovery.d.ts.map +1 -1
  10. package/dist/discovery.js +10 -6
  11. package/dist/handed.d.ts +15 -0
  12. package/dist/handed.d.ts.map +1 -0
  13. package/dist/handed.js +38 -0
  14. package/dist/index.d.ts +2 -2
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +1 -1
  17. package/dist/model.d.ts +0 -1
  18. package/dist/model.d.ts.map +1 -1
  19. package/dist/model.js +0 -3
  20. package/dist/read.d.ts +29 -6
  21. package/dist/read.d.ts.map +1 -1
  22. package/dist/read.js +150 -52
  23. package/dist/referrer.d.ts +7 -0
  24. package/dist/referrer.d.ts.map +1 -0
  25. package/dist/referrer.js +35 -0
  26. package/dist/refusal.d.ts.map +1 -1
  27. package/dist/refusal.js +2 -1
  28. package/dist/site.d.ts +1 -1
  29. package/dist/site.d.ts.map +1 -1
  30. package/dist/site.js +174 -47
  31. package/dist/stream.d.ts +3 -2
  32. package/dist/stream.d.ts.map +1 -1
  33. package/dist/stream.js +325 -16
  34. package/dist/transport.d.ts +62 -6
  35. package/dist/transport.d.ts.map +1 -1
  36. package/dist/transport.js +3 -0
  37. package/dist/version.d.ts +1 -0
  38. package/dist/version.d.ts.map +1 -1
  39. package/dist/version.js +1 -1
  40. package/dist/write.d.ts +2 -9
  41. package/dist/write.d.ts.map +1 -1
  42. package/dist/write.js +61 -8
  43. package/package.json +2 -3
  44. package/dist/links.d.ts +0 -20
  45. package/dist/links.d.ts.map +0 -1
  46. package/dist/links.js +0 -104
package/dist/write.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ChangeBatch, HistoryResult, MutationResult, RoomAttachment } from '@agentshouse/mdruntime';
1
+ import { type ChangeBatch, type HistoryResult, type MutationResult } from '@agentshouse/mdruntime';
2
2
  import type { HouseBounds } from './discovery.js';
3
3
  export type HouseOperation = Readonly<Record<string, unknown>>;
4
4
  export type ChangeMapping = {
@@ -21,14 +21,7 @@ export declare function deltaBody(changes: readonly HouseOperation[]): string;
21
21
  export declare function deltaBytes(delta: string): number;
22
22
  export declare function uploadable(inline: Readonly<Record<string, unknown>>, bytes: number, bounds: Pick<HouseBounds, 'max_inline_body_bytes' | 'max_upload_bytes'>): boolean;
23
23
  export declare function deltaDigest(delta: string): Promise<string>;
24
- export type SubmittedOutcome = Exclude<MutationResult, {
25
- kind: 'accepted';
26
- }> | (Extract<MutationResult, {
27
- kind: 'accepted';
28
- }> & {
29
- originals: readonly RoomAttachment[];
30
- });
31
- export declare function mutationOutcome(status: number, body: unknown, locator: string, handle: string): SubmittedOutcome;
24
+ export declare function mutationOutcome(status: number, body: unknown, locator: string, handle: string): MutationResult;
32
25
  export declare function rejectedMapping(mapping: Extract<ChangeMapping, {
33
26
  kind: 'unmapped';
34
27
  }>): {
@@ -1 +1 @@
1
- {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../src/write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,WAAW,EAEX,aAAa,EAEb,cAAc,EAEd,cAAc,EACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAOlD,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE/D,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAuGrD,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAQ9E;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CAK/D;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,MAAM,EAAE,CAQhF;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,CAEpE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,uBAAuB,GAAG,kBAAkB,CAAC,GACtE,OAAO,CAKT;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE1D;AA6CD,MAAM,MAAM,gBAAgB,GACxB,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,GAC7C,CAAC,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,GAAG;IAAE,SAAS,EAAE,SAAS,cAAc,EAAE,CAAA;CAAE,CAAC,CAAC;AAE/F,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,gBAAgB,CA4ElB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;IAEjF,IAAI,EAAE,UAAU;IAChB,QAAQ;IACR,IAAI;IACJ,MAAM;QAAI,IAAI;;IACd,SAAS;EAEZ;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAM1B;AAeD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3C,aAAa,CAiDf"}
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../src/write.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EAEhB,KAAK,aAAa,EAElB,KAAK,cAAc,EAEpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAOlD,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE/D,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAwHrD,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAQ9E;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CAK/D;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,MAAM,EAAE,CAQhF;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,CAEpE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,uBAAuB,GAAG,kBAAkB,CAAC,GACtE,OAAO,CAKT;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE1D;AAiDD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,cAAc,CAmFhB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;IAEjF,IAAI,EAAE,UAAU;IAChB,QAAQ;IACR,IAAI;IACJ,MAAM;QAAI,IAAI;;IACd,SAAS;EAEZ;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAM1B;AA4BD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3C,aAAa,CAyDf"}
package/dist/write.js CHANGED
@@ -1,4 +1,5 @@
1
- import { headChange } from './read.js';
1
+ import { departure, } from '@agentshouse/mdruntime';
2
+ import { binaryFileOf, headChange, identities } from './read.js';
2
3
  import { sha256Hex, textBytes } from './digest.js';
3
4
  import { nativePath, roomLocalPath } from './map.js';
4
5
  import { classifyDoor, doorRefusal, scopedRefusal } from './refusal.js';
@@ -73,6 +74,25 @@ function operationOf(batch, change, handle) {
73
74
  const operation = created(change, path);
74
75
  return operation === null ? { rule: 'type-missing' } : { operation };
75
76
  }
77
+ if (change.kind === 'binary') {
78
+ const written = {
79
+ op: 'upload',
80
+ path,
81
+ local_id: change.localId,
82
+ bytes: change.byteLength,
83
+ sha256: change.sha256,
84
+ media_type: change.mediaType,
85
+ };
86
+ const from = departure(batch.changes, batch.changes.indexOf(change));
87
+ if (from === change.path && priorAbsence(batch, change.path) !== undefined)
88
+ return { operation: written };
89
+ const replaced = priorExistence(batch, from);
90
+ if (replaced === undefined)
91
+ return { rule: 'precondition-missing' };
92
+ if (!('base' in replaced))
93
+ return { rule: 'presence-base-unrepresentable' };
94
+ return { operation: { ...written, base: replaced.base } };
95
+ }
76
96
  const existence = priorExistence(batch, change.path);
77
97
  if (existence === undefined)
78
98
  return { rule: 'precondition-missing' };
@@ -138,6 +158,9 @@ function material(value, handle) {
138
158
  return null;
139
159
  if (file.revision !== null && file.revision !== undefined && typeof file.revision !== 'string')
140
160
  return null;
161
+ const binary = binaryFileOf(file);
162
+ if (binary === null)
163
+ return null;
141
164
  const head = headChange(file);
142
165
  if (head === null)
143
166
  return null;
@@ -152,6 +175,7 @@ function material(value, handle) {
152
175
  path,
153
176
  content: file.content,
154
177
  revision: typeof file.revision === 'string' ? file.revision : null,
178
+ ...(binary === undefined ? {} : { binary }),
155
179
  ...(head === undefined ? {} : { head }),
156
180
  });
157
181
  }
@@ -170,8 +194,11 @@ export function mutationOutcome(status, body, locator, handle) {
170
194
  if (refusal !== null && refusal.code === 'service_mode_write_halted') {
171
195
  return { kind: 'write-halted' };
172
196
  }
173
- if (refusal !== null && refusal.code === 'expired')
174
- return { kind: 'expired' };
197
+ if (refusal !== null && refusal.code === 'expired') {
198
+ return refusal.fields.restored === true
199
+ ? { kind: 'expired', restored: true }
200
+ : { kind: 'expired' };
201
+ }
175
202
  if (refusal !== null && refusal.code === 'edit_conflict') {
176
203
  const { current, ...fields } = refusal.fields;
177
204
  const held = material(current, handle) ?? [];
@@ -225,13 +252,17 @@ export function mutationOutcome(status, body, locator, handle) {
225
252
  const documents = {};
226
253
  const revisions = {};
227
254
  const changes = {};
255
+ const binaryFiles = {};
228
256
  const removals = [];
229
257
  for (const entry of contents) {
230
- if (entry.content === null || entry.revision === null) {
258
+ if (entry.revision === null) {
231
259
  removals.push(entry.path);
232
260
  continue;
233
261
  }
234
- documents[entry.path] = entry.content;
262
+ if (entry.content !== null)
263
+ documents[entry.path] = entry.content;
264
+ if (entry.binary !== undefined)
265
+ binaryFiles[entry.path] = entry.binary;
235
266
  revisions[entry.path] = entry.revision;
236
267
  if (entry.head !== undefined)
237
268
  changes[entry.path] = entry.head;
@@ -241,9 +272,10 @@ export function mutationOutcome(status, body, locator, handle) {
241
272
  roomVersion: roomVersion(at),
242
273
  documents,
243
274
  revisions,
275
+ ...identities(revisions),
244
276
  changes,
245
277
  removals: removals.sort(),
246
- originals: [],
278
+ ...(Object.keys(binaryFiles).length === 0 ? {} : { binaryFiles }),
247
279
  };
248
280
  }
249
281
  export function rejectedMapping(mapping) {
@@ -274,6 +306,17 @@ function revisionAuthor(entry) {
274
306
  }
275
307
  return null;
276
308
  }
309
+ function historyBinary(entry) {
310
+ if (entry.file === undefined)
311
+ return undefined;
312
+ const { file, bytes, media_type: mediaType, sha256 } = entry;
313
+ if (typeof file !== 'string' ||
314
+ typeof bytes !== 'number' ||
315
+ typeof mediaType !== 'string' ||
316
+ typeof sha256 !== 'string')
317
+ return null;
318
+ return { fileRef: file, byteLength: bytes, mediaType, sha256 };
319
+ }
277
320
  export function historyOutcome(status, body, locator, request) {
278
321
  const classified = classifyDoor(status, body, locator);
279
322
  if (classified !== null)
@@ -298,12 +341,14 @@ export function historyOutcome(status, body, locator, request) {
298
341
  return {
299
342
  kind: 'scoped-refusal',
300
343
  locator,
301
- scope: 'content',
344
+ scope: 'operation',
302
345
  code: 'retained_history_unavailable',
303
346
  fields: { path: request.path, revision: request.revision },
304
347
  retryable: false,
305
348
  };
306
349
  }
350
+ if (typeof named.file === 'string')
351
+ return { kind: 'no-history' };
307
352
  if (typeof named.content !== 'string')
308
353
  return { kind: 'transport-uncertainty' };
309
354
  return { kind: 'revision', content: named.content };
@@ -318,7 +363,15 @@ export function historyOutcome(status, body, locator, request) {
318
363
  typeof entry.created_at !== 'string') {
319
364
  return { kind: 'transport-uncertainty' };
320
365
  }
321
- revisions.push({ revision: entry.revision, author, time: entry.created_at });
366
+ const binaryFile = historyBinary(entry);
367
+ if (binaryFile === null)
368
+ return { kind: 'transport-uncertainty' };
369
+ revisions.push({
370
+ revision: entry.revision,
371
+ author,
372
+ time: entry.created_at,
373
+ ...(binaryFile === undefined ? {} : { binaryFile }),
374
+ });
322
375
  }
323
376
  const next = held.next_before;
324
377
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentshouse/mdruntime-adapter",
3
- "version": "0.1.0-cd59fd8945dcb",
3
+ "version": "0.1.0-cda5b3be3317e",
4
4
  "description": "Agents House Adapter for the MD Runtime",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,7 +25,6 @@
25
25
  "LICENSE"
26
26
  ],
27
27
  "dependencies": {
28
- "@agentshouse/mdmodel": "0.1.0-cc9fa0498a7f7",
29
- "@agentshouse/mdruntime": "0.1.0-cd3486bd400ed"
28
+ "@agentshouse/mdruntime": "0.1.0-ce9f29a01a271"
30
29
  }
31
30
  }
package/dist/links.d.ts DELETED
@@ -1,20 +0,0 @@
1
- import type { HeldRoom, MutationResult, RoomAttachment } from '@agentshouse/mdruntime';
2
- import type { HouseScope, HouseView } from './read.js';
3
- import type { StreamedAdvancement } from './stream.js';
4
- export type RoomLinks = {
5
- roomVersion: string;
6
- handed: ReadonlyMap<string, RoomAttachment>;
7
- paths: ReadonlyMap<string, ReadonlySet<string>>;
8
- revisions: ReadonlyMap<string, string>;
9
- };
10
- export declare function scopeLinks(scope: HouseScope): RoomLinks;
11
- export declare function heldLinks(held: HeldRoom): RoomLinks;
12
- export declare function acceptedLinks(held: RoomLinks, accepted: Extract<MutationResult, {
13
- kind: 'accepted';
14
- }>, roomVersion: string, originals: readonly RoomAttachment[]): {
15
- links: RoomLinks;
16
- attachments?: readonly RoomAttachment[];
17
- };
18
- export declare function enumeratedLinks(view: HouseView, earlier: RoomLinks | undefined): RoomLinks;
19
- export declare function streamedLinks(held: RoomLinks, advanced: StreamedAdvancement): RoomLinks | null;
20
- //# sourceMappingURL=links.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../src/links.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACvF,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAOvD,MAAM,MAAM,SAAS,GAAG;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC5C,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAChD,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC,CAAC;AAcF,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,CAWvD;AAOD,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAOnD;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,EACvD,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,SAAS,cAAc,EAAE,GACnC;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,WAAW,CAAC,EAAE,SAAS,cAAc,EAAE,CAAA;CAAE,CA2B/D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAgB1F;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,mBAAmB,GAAG,SAAS,GAAG,IAAI,CAoB9F"}
package/dist/links.js DELETED
@@ -1,104 +0,0 @@
1
- import { roomVersion } from './version.js';
2
- const ATTACHMENT_REFERENCE = /at_[1-9a-hjkmnp-tv-z][0-9a-hjkmnp-tv-z]*\.[0-9a-hjkmnp-tv-z]/g;
3
- const NONE = new Set();
4
- function linkedBy(text) {
5
- if (text === null)
6
- return NONE;
7
- const references = new Set(Array.from(text.matchAll(ATTACHMENT_REFERENCE), ([found]) => found));
8
- return references.size === 0 ? NONE : references;
9
- }
10
- function handedOf(attachments) {
11
- return new Map((attachments ?? []).map((attachment) => [attachment.reference, attachment]));
12
- }
13
- export function scopeLinks(scope) {
14
- return {
15
- roomVersion: roomVersion(scope),
16
- handed: handedOf(scope.attachments),
17
- paths: new Map(scope.contents.map(({ path, content }) => [path, linkedBy(content)])),
18
- revisions: new Map(scope.files.flatMap(({ path, revision }) => revision === undefined ? [] : [[path, revision]])),
19
- };
20
- }
21
- function revised(revisions, path, revision) {
22
- if (revision === undefined)
23
- revisions.delete(path);
24
- else
25
- revisions.set(path, revision);
26
- }
27
- export function heldLinks(held) {
28
- return {
29
- roomVersion: held.roomVersion,
30
- handed: handedOf(held.attachments),
31
- paths: new Map(Object.entries(held.documents).map(([path, text]) => [path, linkedBy(text)])),
32
- revisions: new Map(Object.entries(held.revisions)),
33
- };
34
- }
35
- export function acceptedLinks(held, accepted, roomVersion, originals) {
36
- const paths = new Map(held.paths);
37
- const revisions = new Map(held.revisions);
38
- const handed = new Map(held.handed);
39
- const answered = handedOf(originals);
40
- for (const [path, text] of Object.entries(accepted.documents)) {
41
- const linked = linkedBy(text);
42
- for (const reference of linked) {
43
- const original = answered.get(reference);
44
- if (!handed.has(reference) && original !== undefined)
45
- handed.set(reference, original);
46
- }
47
- paths.set(path, linked);
48
- }
49
- for (const [path, revision] of Object.entries(accepted.revisions))
50
- revisions.set(path, revision);
51
- for (const path of accepted.removals) {
52
- paths.delete(path);
53
- revisions.delete(path);
54
- }
55
- const linked = new Set([...paths.values()].flatMap((references) => [...references]));
56
- for (const reference of held.handed.keys()) {
57
- const before = [...held.paths.values()].some((references) => references.has(reference));
58
- if (before && !linked.has(reference))
59
- handed.delete(reference);
60
- }
61
- const links = { roomVersion, handed, paths, revisions };
62
- const changed = handed.size !== held.handed.size || [...handed.keys()].some((key) => !held.handed.has(key));
63
- return changed ? { links, attachments: [...handed.values()] } : { links };
64
- }
65
- export function enumeratedLinks(view, earlier) {
66
- const paths = new Map(earlier?.paths);
67
- const revisions = new Map(earlier?.revisions);
68
- for (const change of view.changes) {
69
- paths.set(change.path, linkedBy('content' in change ? change.content : null));
70
- revised(revisions, change.path, 'removed' in change
71
- ? undefined
72
- : 'reference' in change
73
- ? change.reference.revision
74
- : change.revision);
75
- }
76
- return { roomVersion: roomVersion(view), handed: handedOf(view.attachments), paths, revisions };
77
- }
78
- export function streamedLinks(held, advanced) {
79
- const paths = new Map(held.paths);
80
- const revisions = new Map(held.revisions);
81
- const dropped = new Set();
82
- for (const entry of advanced.entries) {
83
- revised(revisions, entry.path, entry.kind === 'removed' ? undefined : entry.revision);
84
- const text = entry.kind === 'removed' ? null : entry.text;
85
- if (text === undefined)
86
- return null;
87
- const linked = linkedBy(text);
88
- for (const reference of linked)
89
- if (!held.handed.has(reference))
90
- return null;
91
- for (const reference of paths.get(entry.path) ?? held.handed.keys()) {
92
- if (held.handed.has(reference) && !linked.has(reference))
93
- dropped.add(reference);
94
- }
95
- paths.set(entry.path, linked);
96
- }
97
- for (const references of paths.values()) {
98
- for (const reference of references)
99
- dropped.delete(reference);
100
- }
101
- if (dropped.size > 0)
102
- return null;
103
- return { roomVersion: advanced.page.roomVersion, handed: held.handed, paths, revisions };
104
- }