@agentshouse/mdruntime-adapter 0.1.0-ce3fe65a95f49 → 0.1.0-ce5ef9afd7e9a

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 (50) hide show
  1. package/AGENTS.md +289 -279
  2. package/dist/actions.d.ts +13 -5
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +85 -115
  5. package/dist/adapter.d.ts +1 -0
  6. package/dist/adapter.d.ts.map +1 -1
  7. package/dist/adapter.js +292 -130
  8. package/dist/discovery.d.ts +5 -3
  9. package/dist/discovery.d.ts.map +1 -1
  10. package/dist/discovery.js +29 -10
  11. package/dist/gather.d.ts +1 -1
  12. package/dist/gather.d.ts.map +1 -1
  13. package/dist/gather.js +4 -14
  14. package/dist/index.d.ts +3 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -0
  17. package/dist/part.d.ts +13 -0
  18. package/dist/part.d.ts.map +1 -0
  19. package/dist/part.js +80 -0
  20. package/dist/read.d.ts +64 -20
  21. package/dist/read.d.ts.map +1 -1
  22. package/dist/read.js +296 -105
  23. package/dist/referrer.d.ts +2 -0
  24. package/dist/referrer.d.ts.map +1 -1
  25. package/dist/referrer.js +8 -2
  26. package/dist/room-types.d.ts +6 -0
  27. package/dist/room-types.d.ts.map +1 -0
  28. package/dist/room-types.js +66 -0
  29. package/dist/site.d.ts +1 -1
  30. package/dist/site.d.ts.map +1 -1
  31. package/dist/site.js +143 -118
  32. package/dist/stream.d.ts +5 -4
  33. package/dist/stream.d.ts.map +1 -1
  34. package/dist/stream.js +275 -77
  35. package/dist/transport.d.ts +46 -7
  36. package/dist/transport.d.ts.map +1 -1
  37. package/dist/transport.js +1 -0
  38. package/dist/upload.d.ts +12 -0
  39. package/dist/upload.d.ts.map +1 -0
  40. package/dist/upload.js +52 -0
  41. package/dist/version.d.ts +1 -0
  42. package/dist/version.d.ts.map +1 -1
  43. package/dist/version.js +1 -1
  44. package/dist/write.d.ts +12 -1
  45. package/dist/write.d.ts.map +1 -1
  46. package/dist/write.js +96 -44
  47. package/package.json +2 -2
  48. package/dist/handed.d.ts +0 -15
  49. package/dist/handed.d.ts.map +0 -1
  50. package/dist/handed.js +0 -38
@@ -0,0 +1,12 @@
1
+ import { type HouseDoorAnswer, type HouseTransport } from './transport.js';
2
+ export type HouseUpload = {
3
+ readonly id: string;
4
+ readonly partBytes: number;
5
+ readonly parts: readonly {
6
+ readonly part: number;
7
+ readonly url: string;
8
+ }[];
9
+ };
10
+ export declare function houseUpload(value: unknown): HouseUpload | null;
11
+ export declare function finishedUpload(transport: HouseTransport, first: HouseUpload, blob: Blob): Promise<HouseDoorAnswer | null>;
12
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE9F,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC5E,CAAC;AAkBF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAQ9D;AAWD,wBAAsB,cAAc,CAClC,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAgBjC"}
package/dist/upload.js ADDED
@@ -0,0 +1,52 @@
1
+ import { DOOR_FILES_FINISH } from './transport.js';
2
+ // A finishing call that finds House still reading the stored bytes back answers checking; the runtime asks again after five seconds, as the Kit does.
3
+ const CHECKING_WAIT_MS = 5_000;
4
+ const FINISHING_ROUNDS = 24;
5
+ function record(value) {
6
+ return value !== null && typeof value === 'object' ? value : {};
7
+ }
8
+ function part(value) {
9
+ const { part: number, url } = record(value);
10
+ return Number.isSafeInteger(number) && number > 0 && typeof url === 'string'
11
+ ? { part: number, url }
12
+ : null;
13
+ }
14
+ export function houseUpload(value) {
15
+ const { id, part_bytes: partBytes, parts } = record(value);
16
+ if (typeof id !== 'string' || !Number.isSafeInteger(partBytes) || partBytes <= 0)
17
+ return null;
18
+ if (!Array.isArray(parts))
19
+ return null;
20
+ const named = parts.map(part);
21
+ if (named.some((one) => one === null))
22
+ return null;
23
+ return { id, partBytes: partBytes, parts: named };
24
+ }
25
+ async function sent(transport, upload, blob) {
26
+ for (const { part: number, url } of upload.parts) {
27
+ const start = (number - 1) * upload.partBytes;
28
+ if ((await transport.put(url, blob.slice(start, start + upload.partBytes))) !== 200)
29
+ return false;
30
+ }
31
+ return true;
32
+ }
33
+ export async function finishedUpload(transport, first, blob) {
34
+ let upload = first;
35
+ for (let round = 0; round < FINISHING_ROUNDS; round += 1) {
36
+ if (!(await sent(transport, upload, blob)))
37
+ return null;
38
+ const answer = await transport.door(DOOR_FILES_FINISH, { upload: upload.id });
39
+ if (answer.status !== 200)
40
+ return answer;
41
+ const missing = houseUpload(record(answer.body).upload);
42
+ if (missing !== null) {
43
+ upload = missing;
44
+ continue;
45
+ }
46
+ if (record(answer.body).checking !== true)
47
+ return answer;
48
+ upload = { ...upload, parts: [] };
49
+ await new Promise((resolve) => setTimeout(resolve, CHECKING_WAIT_MS));
50
+ }
51
+ return null;
52
+ }
package/dist/version.d.ts CHANGED
@@ -11,6 +11,7 @@ export declare function roomVersion(at: LogPosition): string;
11
11
  export declare function logPosition(version: string): LogPosition | null;
12
12
  export declare function readPosition(held: Readonly<Record<string, unknown>>): LogPosition | null;
13
13
  export declare function presented(authority: string, at: LogPosition): PresentedPosition;
14
+ export declare const DECIMAL: RegExp;
14
15
  export declare function reachedVersion(roomVersion: string, target: string, currentEpoch: string | undefined): boolean;
15
16
  export declare function followsVersion(roomVersion: string, next: string): boolean;
16
17
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAEnD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAI/D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,WAAW,GAAG,IAAI,CAKxF;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,iBAAiB,CAE/E;AAID,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,OAAO,CAQT;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAMzE"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAEnD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAI/D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,WAAW,GAAG,IAAI,CAKxF;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,iBAAiB,CAE/E;AAED,eAAO,MAAM,OAAO,QAAwB,CAAC;AAE7C,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,OAAO,CAQT;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAMzE"}
package/dist/version.js CHANGED
@@ -18,7 +18,7 @@ export function readPosition(held) {
18
18
  export function presented(authority, at) {
19
19
  return { authority, position: at.position, log_epoch: at.logEpoch };
20
20
  }
21
- const DECIMAL = /^(?:0|[1-9][0-9]*)$/;
21
+ export const DECIMAL = /^(?:0|[1-9][0-9]*)$/;
22
22
  export function reachedVersion(roomVersion, target, currentEpoch) {
23
23
  if (roomVersion === target)
24
24
  return true;
package/dist/write.d.ts CHANGED
@@ -10,6 +10,7 @@ export type ChangeMapping = {
10
10
  rule: string;
11
11
  };
12
12
  export declare function houseChanges(batch: ChangeBatch, handle: string): ChangeMapping;
13
+ export declare function houseMove(batch: ChangeBatch, source: string, destination: string): ChangeMapping;
13
14
  export type OperationHead = {
14
15
  readonly operation_id: string;
15
16
  readonly app_ref?: string;
@@ -21,7 +22,17 @@ export declare function deltaBody(changes: readonly HouseOperation[]): string;
21
22
  export declare function deltaBytes(delta: string): number;
22
23
  export declare function uploadable(inline: Readonly<Record<string, unknown>>, bytes: number, bounds: Pick<HouseBounds, 'max_inline_body_bytes' | 'max_upload_bytes'>): boolean;
23
24
  export declare function deltaDigest(delta: string): Promise<string>;
24
- export declare function mutationOutcome(status: number, body: unknown, locator: string, handle: string): MutationResult;
25
+ export type MoveAuthorities = {
26
+ readonly source: {
27
+ readonly authority: string;
28
+ readonly handle: string;
29
+ };
30
+ readonly destination: {
31
+ readonly authority: string;
32
+ readonly handle: string;
33
+ };
34
+ };
35
+ export declare function mutationOutcome(status: number, body: unknown, locator: string, handle: string, move?: MoveAuthorities): Generator<number, MutationResult, void>;
25
36
  export declare function rejectedMapping(mapping: Extract<ChangeMapping, {
26
37
  kind: 'unmapped';
27
38
  }>): {
@@ -1 +1 @@
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,CA8EhB;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"}
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../src/write.ts"],"names":[],"mappings":"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"}
package/dist/write.js CHANGED
@@ -1,5 +1,5 @@
1
- import { departure, } from '@agentshouse/mdruntime';
2
- import { binaryFileOf, headChange } from './read.js';
1
+ import { departure, ROW_WEIGHT, } from '@agentshouse/mdruntime';
2
+ import { answered, answering, binaryFileOf, headChange, revised } from './read.js';
3
3
  import { sha256Hex, textBytes } from './digest.js';
4
4
  import { nativePath, roomLocalPath } from './map.js';
5
5
  import { classifyDoor, doorRefusal, scopedRefusal } from './refusal.js';
@@ -120,6 +120,24 @@ export function houseChanges(batch, handle) {
120
120
  }
121
121
  return { kind: 'changes', changes };
122
122
  }
123
+ export function houseMove(batch, source, destination) {
124
+ const changes = [];
125
+ for (const { path, to } of batch.between?.moves ?? []) {
126
+ const existence = priorExistence(batch, path);
127
+ if (existence === undefined)
128
+ return { kind: 'unmapped', path, rule: 'precondition-missing' };
129
+ if (!('base' in existence)) {
130
+ return { kind: 'unmapped', path, rule: 'presence-base-unrepresentable' };
131
+ }
132
+ changes.push({
133
+ op: 'rename',
134
+ path: nativePath(path, source),
135
+ to: nativePath(to, destination),
136
+ base: existence.base,
137
+ });
138
+ }
139
+ return { kind: 'changes', changes };
140
+ }
123
141
  export function operationHead(batch) {
124
142
  const writer = batch.writtenBy;
125
143
  return writer === undefined
@@ -129,7 +147,7 @@ export function operationHead(batch) {
129
147
  export function batchPaths(changes) {
130
148
  return [
131
149
  ...new Set(changes.flatMap((change) => change.op === 'rename' ? [String(change.path), String(change.to)] : [String(change.path)])),
132
- ].sort();
150
+ ];
133
151
  }
134
152
  export function deltaBody(changes) {
135
153
  return JSON.stringify({ changes });
@@ -144,16 +162,19 @@ export function uploadable(inline, bytes, bounds) {
144
162
  export function deltaDigest(delta) {
145
163
  return sha256Hex(delta);
146
164
  }
147
- function material(value, handle) {
165
+ function* material(value, handle, within = () => true) {
148
166
  if (!Array.isArray(value))
149
167
  return null;
150
168
  const held = [];
151
169
  for (const entry of value) {
170
+ yield ROW_WEIGHT;
152
171
  if (typeof entry !== 'object' || entry === null)
153
172
  return null;
154
173
  const file = entry;
155
174
  if (typeof file.path !== 'string')
156
175
  return null;
176
+ if (!within(file.path))
177
+ continue;
157
178
  if (file.content !== null && typeof file.content !== 'string')
158
179
  return null;
159
180
  if (file.revision !== null && file.revision !== undefined && typeof file.revision !== 'string')
@@ -181,27 +202,74 @@ function material(value, handle) {
181
202
  }
182
203
  return held;
183
204
  }
184
- function affectedOf(held) {
205
+ function* affectedOf(held) {
185
206
  const affected = {};
186
207
  for (const entry of held) {
187
208
  if (entry.content !== null)
188
209
  affected[entry.path] = entry.content;
210
+ yield ROW_WEIGHT;
189
211
  }
190
212
  return affected;
191
213
  }
192
- export function mutationOutcome(status, body, locator, handle) {
214
+ function* acceptedOf(at, contents) {
215
+ const answer = answering();
216
+ for (const entry of contents) {
217
+ yield ROW_WEIGHT + (entry.content?.length ?? 0);
218
+ if (entry.revision === null) {
219
+ answer.removals.add(entry.path);
220
+ continue;
221
+ }
222
+ if (entry.content !== null)
223
+ answer.documents.set(entry.path, entry.content);
224
+ if (entry.binary !== undefined)
225
+ answer.binaryFiles.set(entry.path, entry.binary);
226
+ revised(answer, entry.path, entry.revision);
227
+ if (entry.head !== undefined)
228
+ answer.changes.set(entry.path, entry.head);
229
+ }
230
+ const unbinaried = answer.binaryFiles.size === 0;
231
+ const { binaryFiles, ...room } = yield* answered(answer);
232
+ return { roomVersion: roomVersion(at), ...room, ...(unbinaried ? {} : { binaryFiles }) };
233
+ }
234
+ function* movedOutcome(held, move) {
235
+ const authorities = Array.isArray(held.authorities) ? held.authorities : [];
236
+ const at = (authority) => {
237
+ const entry = authorities.find((one) => typeof one === 'object' &&
238
+ one !== null &&
239
+ one.authority === authority);
240
+ return entry === undefined ? null : readPosition(entry);
241
+ };
242
+ const left = at(move.source.authority);
243
+ const arrived = at(move.destination.authority);
244
+ if (left === null || arrived === null)
245
+ return { kind: 'transport-uncertainty' };
246
+ const under = (handle) => (path) => path.startsWith(`/rooms/${handle}/`);
247
+ const leaving = yield* material(held.contents, move.source.handle, under(move.source.handle));
248
+ const arriving = yield* material(held.contents, move.destination.handle, under(move.destination.handle));
249
+ if (leaving === null || arriving === null)
250
+ return { kind: 'transport-uncertainty' };
251
+ return {
252
+ kind: 'accepted',
253
+ ...(yield* acceptedOf(left, leaving)),
254
+ destination: yield* acceptedOf(arrived, arriving),
255
+ };
256
+ }
257
+ export function* mutationOutcome(status, body, locator, handle, move) {
193
258
  const refusal = doorRefusal(body);
194
259
  if (refusal !== null && refusal.code === 'service_mode_write_halted') {
195
260
  return { kind: 'write-halted' };
196
261
  }
197
- if (refusal !== null && refusal.code === 'expired')
198
- return { kind: 'expired' };
262
+ if (refusal !== null && refusal.code === 'expired') {
263
+ return refusal.fields.restored === true
264
+ ? { kind: 'expired', restored: true }
265
+ : { kind: 'expired' };
266
+ }
199
267
  if (refusal !== null && refusal.code === 'edit_conflict') {
200
268
  const { current, ...fields } = refusal.fields;
201
- const held = material(current, handle) ?? [];
269
+ const held = (yield* material(current, handle)) ?? [];
202
270
  return {
203
271
  kind: 'conflicted',
204
- affected: affectedOf(held),
272
+ affected: yield* affectedOf(held),
205
273
  code: refusal.code,
206
274
  fields,
207
275
  retryable: refusal.retryable,
@@ -225,8 +293,9 @@ export function mutationOutcome(status, body, locator, handle) {
225
293
  }
226
294
  if (classified !== null && classified.kind !== 'scoped-refusal')
227
295
  return classified;
228
- if (classified !== null && status === 403)
296
+ if (classified !== null && status === 403 && refusal?.code === 'operation_denied') {
229
297
  return classified;
298
+ }
230
299
  if (refusal !== null && status >= 400) {
231
300
  return {
232
301
  kind: 'rejected',
@@ -240,39 +309,15 @@ export function mutationOutcome(status, body, locator, handle) {
240
309
  return { kind: 'transport-uncertainty' };
241
310
  }
242
311
  const held = body;
312
+ if (move !== undefined)
313
+ return yield* movedOutcome(held, move);
243
314
  const at = readPosition(held);
244
315
  if (at === null)
245
316
  return { kind: 'transport-uncertainty' };
246
- const contents = material(held.contents, handle);
317
+ const contents = yield* material(held.contents, handle);
247
318
  if (contents === null)
248
319
  return { kind: 'transport-uncertainty' };
249
- const documents = {};
250
- const revisions = {};
251
- const changes = {};
252
- const binaryFiles = {};
253
- const removals = [];
254
- for (const entry of contents) {
255
- if (entry.revision === null) {
256
- removals.push(entry.path);
257
- continue;
258
- }
259
- if (entry.content !== null)
260
- documents[entry.path] = entry.content;
261
- if (entry.binary !== undefined)
262
- binaryFiles[entry.path] = entry.binary;
263
- revisions[entry.path] = entry.revision;
264
- if (entry.head !== undefined)
265
- changes[entry.path] = entry.head;
266
- }
267
- return {
268
- kind: 'accepted',
269
- roomVersion: roomVersion(at),
270
- documents,
271
- revisions,
272
- changes,
273
- removals: removals.sort(),
274
- ...(Object.keys(binaryFiles).length === 0 ? {} : { binaryFiles }),
275
- };
320
+ return { kind: 'accepted', ...(yield* acceptedOf(at, contents)) };
276
321
  }
277
322
  export function rejectedMapping(mapping) {
278
323
  return {
@@ -293,12 +338,19 @@ export function revisionBody(input) {
293
338
  function revisionAuthor(entry) {
294
339
  const user = entry.author_user;
295
340
  const site = entry.author_site;
296
- const name = entry.author_site_name;
297
- if (typeof user === 'string' && site === undefined && name === undefined) {
341
+ const siteName = entry.author_site_name;
342
+ const inbox = entry.author_inbox;
343
+ const inboxName = entry.author_inbox_name;
344
+ const named = [site, siteName, inbox, inboxName].filter((held) => held !== undefined);
345
+ if (typeof user === 'string' && named.length === 0)
298
346
  return { kind: 'user', id: user };
347
+ if (user !== null || named.length !== 2)
348
+ return null;
349
+ if (typeof site === 'string' && typeof siteName === 'string') {
350
+ return { kind: 'site', id: site, name: siteName };
299
351
  }
300
- if (user === null && typeof site === 'string' && typeof name === 'string') {
301
- return { kind: 'site', id: site, name };
352
+ if (typeof inbox === 'string' && typeof inboxName === 'string') {
353
+ return { kind: 'inbox', id: inbox, name: inboxName };
302
354
  }
303
355
  return null;
304
356
  }
@@ -337,7 +389,7 @@ export function historyOutcome(status, body, locator, request) {
337
389
  return {
338
390
  kind: 'scoped-refusal',
339
391
  locator,
340
- scope: 'content',
392
+ scope: 'operation',
341
393
  code: 'retained_history_unavailable',
342
394
  fields: { path: request.path, revision: request.revision },
343
395
  retryable: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentshouse/mdruntime-adapter",
3
- "version": "0.1.0-ce3fe65a95f49",
3
+ "version": "0.1.0-ce5ef9afd7e9a",
4
4
  "description": "Agents House Adapter for the MD Runtime",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,6 +25,6 @@
25
25
  "LICENSE"
26
26
  ],
27
27
  "dependencies": {
28
- "@agentshouse/mdruntime": "0.1.0-c56daf494ecb4"
28
+ "@agentshouse/mdruntime": "0.1.0-c03e7b79830dd"
29
29
  }
30
30
  }
package/dist/handed.d.ts DELETED
@@ -1,15 +0,0 @@
1
- import type { HeldRoom, MutationResult } from '@agentshouse/mdruntime';
2
- import type { HouseScope, HouseView } from './read.js';
3
- import type { StreamedAdvancement } from './stream.js';
4
- export type HandedRoom = {
5
- roomVersion: string;
6
- revisions: ReadonlyMap<string, string>;
7
- };
8
- export declare function scopeHanded(scope: HouseScope): HandedRoom;
9
- export declare function heldHanded(held: HeldRoom): HandedRoom;
10
- export declare function acceptedHanded(held: HandedRoom, accepted: Extract<MutationResult, {
11
- kind: 'accepted';
12
- }>, roomVersion: string): HandedRoom;
13
- export declare function enumeratedHanded(view: HouseView, earlier: HandedRoom | undefined): HandedRoom;
14
- export declare function streamedHanded(held: HandedRoom, advanced: StreamedAdvancement): HandedRoom;
15
- //# sourceMappingURL=handed.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handed.d.ts","sourceRoot":"","sources":["../src/handed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,MAAM,MAAM,UAAU,GAAG;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC,CAAC;AAEF,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CASzD;AAOD,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAErD;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,EACvD,WAAW,EAAE,MAAM,GAClB,UAAU,CAKZ;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAM7F;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,mBAAmB,GAAG,UAAU,CAM1F"}
package/dist/handed.js DELETED
@@ -1,38 +0,0 @@
1
- import { roomVersion } from './version.js';
2
- export function scopeHanded(scope) {
3
- return {
4
- roomVersion: roomVersion(scope),
5
- revisions: new Map(scope.files.flatMap(({ path, revision }) => revision === undefined ? [] : [[path, revision]])),
6
- };
7
- }
8
- function revised(revisions, path, revision) {
9
- if (revision === undefined)
10
- revisions.delete(path);
11
- else
12
- revisions.set(path, revision);
13
- }
14
- export function heldHanded(held) {
15
- return { roomVersion: held.roomVersion, revisions: new Map(Object.entries(held.revisions)) };
16
- }
17
- export function acceptedHanded(held, accepted, roomVersion) {
18
- const revisions = new Map(held.revisions);
19
- for (const [path, revision] of Object.entries(accepted.revisions))
20
- revisions.set(path, revision);
21
- for (const path of accepted.removals)
22
- revisions.delete(path);
23
- return { roomVersion, revisions };
24
- }
25
- export function enumeratedHanded(view, earlier) {
26
- const revisions = new Map(earlier?.revisions);
27
- for (const change of view.changes) {
28
- revised(revisions, change.path, 'removed' in change ? undefined : change.revision);
29
- }
30
- return { roomVersion: roomVersion(view), revisions };
31
- }
32
- export function streamedHanded(held, advanced) {
33
- const revisions = new Map(held.revisions);
34
- for (const entry of advanced.entries) {
35
- revised(revisions, entry.path, entry.kind === 'removed' ? undefined : entry.revision);
36
- }
37
- return { roomVersion: advanced.page.roomVersion, revisions };
38
- }