@agentshouse/mdruntime 0.1.0-alpha.31 → 0.1.0-alpha.32

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.
@@ -1,6 +1,7 @@
1
1
  import { type Document, type Validation } from '@agentshouse/mdmodel';
2
2
  import type { ModelState } from './model.js';
3
3
  import type { MdModelIdentity } from './adapter.js';
4
+ import { type Refused, type Unconfirmed } from './transfer.js';
4
5
  export declare const MD_MODEL: MdModelIdentity;
5
6
  export type Collection = {
6
7
  documents: Readonly<Record<string, Document>>;
@@ -15,14 +16,16 @@ export type Composition = {
15
16
  } | null;
16
17
  };
17
18
  export declare function governing(composition: Composition, path: string): ModelState;
18
- export declare function parseCollection(text: Readonly<Record<string, string>>, composition: Composition, previous?: {
19
+ type Previous = {
19
20
  text: Readonly<Record<string, string>>;
20
21
  collection: Collection;
21
- }): Collection;
22
- export declare function readCollection(text: Readonly<Record<string, string>>, composition: Composition, previous?: {
23
- text: Readonly<Record<string, string>>;
22
+ };
23
+ export declare function parseCollection(text: Readonly<Record<string, string>>, composition: Composition, previous?: Previous): Collection;
24
+ export declare function readCollection(text: Readonly<Record<string, string>>, composition: Composition, previous?: Previous): {
25
+ kind: 'read';
24
26
  collection: Collection;
25
- }): Collection | null;
27
+ } | Refused | Unconfirmed;
26
28
  export declare function validRoot(root: unknown): root is string;
27
29
  export declare function validateCollection(text: Readonly<Record<string, string>>, binaryTargets: readonly string[], composition: Composition): Validation;
30
+ export {};
28
31
  //# sourceMappingURL=collection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,QAAQ,EACb,KAAK,UAAU,EAEhB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,eAAO,MAAM,QAAQ,EAAE,eAAwE,CAAC;AAIhG,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9C,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE;QAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;CACnE,CAAC;AASF,wBAAgB,SAAS,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAI5E;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACtC,WAAW,EAAE,WAAW,EACxB,QAAQ,CAAC,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,GAC5E,UAAU,CAYZ;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACtC,WAAW,EAAE,WAAW,EACxB,QAAQ,CAAC,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,GAC5E,UAAU,GAAG,IAAI,CAenB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,MAAM,CAEvD;AA0CD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACtC,aAAa,EAAE,SAAS,MAAM,EAAE,EAChC,WAAW,EAAE,WAAW,GACvB,UAAU,CA0CZ"}
1
+ {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,QAAQ,EAEb,KAAK,UAAU,EAEhB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAe,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5E,eAAO,MAAM,QAAQ,EAAE,eAAwE,CAAC;AAIhG,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9C,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE;QAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;CACnE,CAAC;AASF,wBAAgB,SAAS,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAI5E;AAED,KAAK,QAAQ,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAAC;AAanF,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACtC,WAAW,EAAE,WAAW,EACxB,QAAQ,CAAC,EAAE,QAAQ,GAClB,UAAU,CAOZ;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACtC,WAAW,EAAE,WAAW,EACxB,QAAQ,CAAC,EAAE,QAAQ,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,GAAG,OAAO,GAAG,WAAW,CAoBlE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,MAAM,CAEvD;AA0CD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACtC,aAAa,EAAE,SAAS,MAAM,EAAE,EAChC,WAAW,EAAE,WAAW,GACvB,UAAU,CA0CZ"}
@@ -1,5 +1,6 @@
1
1
  import { parse, validate, VERSION } from '@agentshouse/mdmodel';
2
2
  import { beneath, normalize } from './paths.js';
3
+ import { unconfirmed } from './transfer.js';
3
4
  export const MD_MODEL = {
4
5
  identity: '@agentshouse/mdmodel',
5
6
  version: VERSION
@@ -13,15 +14,17 @@ function selected(composition, path) {
13
14
  export function governing(composition, path) {
14
15
  return composition.selection !== null && selected(composition, path) ? composition.selection.model : composition.model;
15
16
  }
17
+ function parsedAt(text, path, previous) {
18
+ const retained = previous?.collection.documents[path];
19
+ return retained !== undefined && previous?.text[path] === text[path] ? {
20
+ ok: true,
21
+ document: retained
22
+ } : parse(text[path], path);
23
+ }
16
24
  export function parseCollection(text, composition, previous) {
17
25
  const documents = {};
18
26
  for (const path of Object.keys(text).sort()){
19
- const retained = previous?.collection.documents[path];
20
- if (retained !== undefined && previous?.text[path] === text[path]) {
21
- documents[path] = retained;
22
- continue;
23
- }
24
- const parsed = parse(text[path], path);
27
+ const parsed = parsedAt(text, path, previous);
25
28
  if (parsed.ok) documents[path] = parsed.document;
26
29
  }
27
30
  return {
@@ -30,11 +33,32 @@ export function parseCollection(text, composition, previous) {
30
33
  };
31
34
  }
32
35
  export function readCollection(text, composition, previous) {
33
- if (!validRoot(composition.collectionRoot)) return null;
34
- const collection = parseCollection(text, composition, previous);
35
- if (Object.keys(collection.documents).length !== Object.keys(text).length) return null;
36
- if (Object.entries(collection.documents).some(([path, document])=>!member(path, composition.collectionRoot) && !selected(composition, path) && document.type !== undefined && document.type !== 'any')) return null;
37
- return collection;
36
+ if (!validRoot(composition.collectionRoot)) return unconfirmed;
37
+ const documents = {};
38
+ for (const path of Object.keys(text).sort()){
39
+ const parsed = parsedAt(text, path, previous);
40
+ if (!parsed.ok) return {
41
+ kind: 'refused',
42
+ refusal: parsed.refusal
43
+ };
44
+ const { type } = parsed.document;
45
+ if (!member(path, composition.collectionRoot) && !selected(composition, path) && type !== undefined && type !== 'any') return {
46
+ kind: 'refused',
47
+ refusal: {
48
+ rule: 'outside-collection-type',
49
+ file: path,
50
+ version: VERSION
51
+ }
52
+ };
53
+ documents[path] = parsed.document;
54
+ }
55
+ return {
56
+ kind: 'read',
57
+ collection: {
58
+ documents,
59
+ composition
60
+ }
61
+ };
38
62
  }
39
63
  export function validRoot(root) {
40
64
  return typeof root === 'string' && normalize(root) === root;
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/collection.ts"],"sourcesContent":["import {\n parse,\n validate,\n VERSION,\n type Document,\n type Validation,\n type VerifiedModel,\n} from '@agentshouse/mdmodel';\nimport { beneath, normalize } from './paths.js';\nimport type { ModelState } from './model.js';\nimport type { MdModelIdentity } from './adapter.js';\n\nexport const MD_MODEL: MdModelIdentity = { identity: '@agentshouse/mdmodel', version: VERSION };\n\nconst NO_TYPES: VerifiedModel = { types: {} };\n\nexport type Collection = {\n documents: Readonly<Record<string, Document>>;\n composition: Composition;\n};\n\nexport type Composition = {\n collectionRoot: string;\n model: ModelState;\n selection: { roots: readonly string[]; model: ModelState } | null;\n};\n\nfunction selected(composition: Composition, path: string): boolean {\n return (\n composition.selection !== null &&\n composition.selection.roots.some((root) => beneath(root, path))\n );\n}\n\nexport function governing(composition: Composition, path: string): ModelState {\n return composition.selection !== null && selected(composition, path)\n ? composition.selection.model\n : composition.model;\n}\n\nexport function parseCollection(\n text: Readonly<Record<string, string>>,\n composition: Composition,\n previous?: { text: Readonly<Record<string, string>>; collection: Collection },\n): Collection {\n const documents: Record<string, Document> = {};\n for (const path of Object.keys(text).sort()) {\n const retained = previous?.collection.documents[path];\n if (retained !== undefined && previous?.text[path] === text[path]) {\n documents[path] = retained;\n continue;\n }\n const parsed = parse(text[path], path);\n if (parsed.ok) documents[path] = parsed.document;\n }\n return { documents, composition };\n}\n\nexport function readCollection(\n text: Readonly<Record<string, string>>,\n composition: Composition,\n previous?: { text: Readonly<Record<string, string>>; collection: Collection },\n): Collection | null {\n if (!validRoot(composition.collectionRoot)) return null;\n const collection = parseCollection(text, composition, previous);\n if (Object.keys(collection.documents).length !== Object.keys(text).length) return null;\n if (\n Object.entries(collection.documents).some(\n ([path, document]) =>\n !member(path, composition.collectionRoot) &&\n !selected(composition, path) &&\n document.type !== undefined &&\n document.type !== 'any',\n )\n )\n return null;\n return collection;\n}\n\nexport function validRoot(root: unknown): root is string {\n return typeof root === 'string' && normalize(root) === root;\n}\n\nfunction member(path: string, root: string): boolean {\n return root === '' || path.startsWith(`${root}/`);\n}\n\ntype Refusal = Extract<Validation, { verdict: 'refuse' }>;\n\nfunction validateAgainst(\n documents: Readonly<Record<string, string>>,\n binaryTargets: readonly string[],\n prefix: string,\n model: ModelState,\n): Validation {\n if (model.status === 'unavailable') {\n const typed = Object.entries(documents).find(([, content]) => {\n const parsed = parse(content);\n return parsed.ok && parsed.document.type !== undefined && parsed.document.type !== 'any';\n });\n if (typed !== undefined)\n return {\n verdict: 'refuse',\n rule: 'model-unavailable',\n file: `${prefix}${typed[0]}`,\n version: VERSION,\n };\n }\n const verdict = validate(\n documents,\n { binaryTargets },\n model.status === 'unavailable' ? NO_TYPES : { types: model.types },\n );\n if (verdict.verdict === 'accept') return verdict;\n return {\n ...verdict,\n file: `${prefix}${verdict.file}`,\n ...(verdict.referrers === undefined\n ? {}\n : { referrers: verdict.referrers.map((path) => `${prefix}${path}`) }),\n };\n}\n\nexport function validateCollection(\n text: Readonly<Record<string, string>>,\n binaryTargets: readonly string[],\n composition: Composition,\n): Validation {\n const prefix = composition.collectionRoot === '' ? '' : `${composition.collectionRoot}/`;\n const collection: Record<string, string> = {};\n const selection: Record<string, string> = {};\n for (const [path, content] of Object.entries(text)) {\n if (member(path, composition.collectionRoot)) {\n collection[path.slice(prefix.length)] = content;\n continue;\n }\n if (selected(composition, path)) {\n selection[path] = content;\n continue;\n }\n const parsed = parse(content, path);\n if (!parsed.ok) return { verdict: 'refuse', ...parsed.refusal };\n if (Object.hasOwn(parsed.document.fields, 'type') && parsed.document.fields.type !== 'any') {\n return { verdict: 'refuse', rule: 'outside-collection-type', file: path, version: VERSION };\n }\n }\n const verdicts = [\n validateAgainst(\n collection,\n binaryTargets\n .filter((path) => member(path, composition.collectionRoot))\n .map((path) => path.slice(prefix.length)),\n prefix,\n composition.model,\n ),\n ];\n if (composition.selection !== null) {\n verdicts.push(\n validateAgainst(\n selection,\n binaryTargets.filter((path) => selected(composition, path)),\n '',\n composition.selection.model,\n ),\n );\n }\n const refusals = verdicts.filter((verdict): verdict is Refusal => verdict.verdict === 'refuse');\n if (refusals.length === 0) return verdicts[0];\n return refusals.find((refusal) => refusal.rule !== 'model-unavailable') ?? refusals[0];\n}\n"],"names":["parse","validate","VERSION","beneath","normalize","MD_MODEL","identity","version","NO_TYPES","types","selected","composition","path","selection","roots","some","root","governing","model","parseCollection","text","previous","documents","Object","keys","sort","retained","collection","undefined","parsed","ok","document","readCollection","validRoot","collectionRoot","length","entries","member","type","startsWith","validateAgainst","binaryTargets","prefix","status","typed","find","content","verdict","rule","file","referrers","map","validateCollection","slice","refusal","hasOwn","fields","verdicts","filter","push","refusals"],"mappings":"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"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/collection.ts"],"sourcesContent":["import {\n parse,\n validate,\n VERSION,\n type Document,\n type ParseResult,\n type Validation,\n type VerifiedModel,\n} from '@agentshouse/mdmodel';\nimport { beneath, normalize } from './paths.js';\nimport type { ModelState } from './model.js';\nimport type { MdModelIdentity } from './adapter.js';\nimport { unconfirmed, type Refused, type Unconfirmed } from './transfer.js';\n\nexport const MD_MODEL: MdModelIdentity = { identity: '@agentshouse/mdmodel', version: VERSION };\n\nconst NO_TYPES: VerifiedModel = { types: {} };\n\nexport type Collection = {\n documents: Readonly<Record<string, Document>>;\n composition: Composition;\n};\n\nexport type Composition = {\n collectionRoot: string;\n model: ModelState;\n selection: { roots: readonly string[]; model: ModelState } | null;\n};\n\nfunction selected(composition: Composition, path: string): boolean {\n return (\n composition.selection !== null &&\n composition.selection.roots.some((root) => beneath(root, path))\n );\n}\n\nexport function governing(composition: Composition, path: string): ModelState {\n return composition.selection !== null && selected(composition, path)\n ? composition.selection.model\n : composition.model;\n}\n\ntype Previous = { text: Readonly<Record<string, string>>; collection: Collection };\n\nfunction parsedAt(\n text: Readonly<Record<string, string>>,\n path: string,\n previous: Previous | undefined,\n): ParseResult {\n const retained = previous?.collection.documents[path];\n return retained !== undefined && previous?.text[path] === text[path]\n ? { ok: true, document: retained }\n : parse(text[path], path);\n}\n\nexport function parseCollection(\n text: Readonly<Record<string, string>>,\n composition: Composition,\n previous?: Previous,\n): Collection {\n const documents: Record<string, Document> = {};\n for (const path of Object.keys(text).sort()) {\n const parsed = parsedAt(text, path, previous);\n if (parsed.ok) documents[path] = parsed.document;\n }\n return { documents, composition };\n}\n\nexport function readCollection(\n text: Readonly<Record<string, string>>,\n composition: Composition,\n previous?: Previous,\n): { kind: 'read'; collection: Collection } | Refused | Unconfirmed {\n if (!validRoot(composition.collectionRoot)) return unconfirmed;\n const documents: Record<string, Document> = {};\n for (const path of Object.keys(text).sort()) {\n const parsed = parsedAt(text, path, previous);\n if (!parsed.ok) return { kind: 'refused', refusal: parsed.refusal };\n const { type } = parsed.document;\n if (\n !member(path, composition.collectionRoot) &&\n !selected(composition, path) &&\n type !== undefined &&\n type !== 'any'\n )\n return {\n kind: 'refused',\n refusal: { rule: 'outside-collection-type', file: path, version: VERSION },\n };\n documents[path] = parsed.document;\n }\n return { kind: 'read', collection: { documents, composition } };\n}\n\nexport function validRoot(root: unknown): root is string {\n return typeof root === 'string' && normalize(root) === root;\n}\n\nfunction member(path: string, root: string): boolean {\n return root === '' || path.startsWith(`${root}/`);\n}\n\ntype Refusal = Extract<Validation, { verdict: 'refuse' }>;\n\nfunction validateAgainst(\n documents: Readonly<Record<string, string>>,\n binaryTargets: readonly string[],\n prefix: string,\n model: ModelState,\n): Validation {\n if (model.status === 'unavailable') {\n const typed = Object.entries(documents).find(([, content]) => {\n const parsed = parse(content);\n return parsed.ok && parsed.document.type !== undefined && parsed.document.type !== 'any';\n });\n if (typed !== undefined)\n return {\n verdict: 'refuse',\n rule: 'model-unavailable',\n file: `${prefix}${typed[0]}`,\n version: VERSION,\n };\n }\n const verdict = validate(\n documents,\n { binaryTargets },\n model.status === 'unavailable' ? NO_TYPES : { types: model.types },\n );\n if (verdict.verdict === 'accept') return verdict;\n return {\n ...verdict,\n file: `${prefix}${verdict.file}`,\n ...(verdict.referrers === undefined\n ? {}\n : { referrers: verdict.referrers.map((path) => `${prefix}${path}`) }),\n };\n}\n\nexport function validateCollection(\n text: Readonly<Record<string, string>>,\n binaryTargets: readonly string[],\n composition: Composition,\n): Validation {\n const prefix = composition.collectionRoot === '' ? '' : `${composition.collectionRoot}/`;\n const collection: Record<string, string> = {};\n const selection: Record<string, string> = {};\n for (const [path, content] of Object.entries(text)) {\n if (member(path, composition.collectionRoot)) {\n collection[path.slice(prefix.length)] = content;\n continue;\n }\n if (selected(composition, path)) {\n selection[path] = content;\n continue;\n }\n const parsed = parse(content, path);\n if (!parsed.ok) return { verdict: 'refuse', ...parsed.refusal };\n if (Object.hasOwn(parsed.document.fields, 'type') && parsed.document.fields.type !== 'any') {\n return { verdict: 'refuse', rule: 'outside-collection-type', file: path, version: VERSION };\n }\n }\n const verdicts = [\n validateAgainst(\n collection,\n binaryTargets\n .filter((path) => member(path, composition.collectionRoot))\n .map((path) => path.slice(prefix.length)),\n prefix,\n composition.model,\n ),\n ];\n if (composition.selection !== null) {\n verdicts.push(\n validateAgainst(\n selection,\n binaryTargets.filter((path) => selected(composition, path)),\n '',\n composition.selection.model,\n ),\n );\n }\n const refusals = verdicts.filter((verdict): verdict is Refusal => verdict.verdict === 'refuse');\n if (refusals.length === 0) return verdicts[0];\n return refusals.find((refusal) => refusal.rule !== 'model-unavailable') ?? refusals[0];\n}\n"],"names":["parse","validate","VERSION","beneath","normalize","unconfirmed","MD_MODEL","identity","version","NO_TYPES","types","selected","composition","path","selection","roots","some","root","governing","model","parsedAt","text","previous","retained","collection","documents","undefined","ok","document","parseCollection","Object","keys","sort","parsed","readCollection","validRoot","collectionRoot","kind","refusal","type","member","rule","file","startsWith","validateAgainst","binaryTargets","prefix","status","typed","entries","find","content","verdict","referrers","map","validateCollection","slice","length","hasOwn","fields","verdicts","filter","push","refusals"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@ import { MD_MODEL, validRoot } from './collection.js';
12
12
  import { createLog } from './log.js';
13
13
  import { refreshRoom } from './refresh.js';
14
14
  import { buildBatch } from './save.js';
15
- import { applyReturned, compositionOf, readConfirmed, replicaOf, withdrawals } from './replica.js';
15
+ import { applyReturned, compositionOf, landed, readConfirmed, replicaOf, withdrawals } from './replica.js';
16
16
  import { changedParts, changesOf, held, readParts, returnedInto, underneath } from './room-draft.js';
17
17
  import { settled, same, saving, STARTING, transferring } from './status.js';
18
18
  import { detectStorageLoss, nextGeneration } from './durability.js';
@@ -377,9 +377,9 @@ export function composeRuntime(options) {
377
377
  model: revoked,
378
378
  selectionModel: revoked
379
379
  };
380
- const confirmed = readConfirmed(record, before.confirmed);
381
- if (confirmed === null) throw new Error(`Cannot retype revoked Room ${locator}`);
382
- replicas.set(locator, replicaOf(confirmed, before.queue, rewriting(), before));
380
+ const read = readConfirmed(record, before.confirmed);
381
+ if (read.kind !== 'staged') throw new Error(`Cannot retype revoked Room ${locator}`);
382
+ replicas.set(locator, replicaOf(read.confirmed, before.queue, rewriting(), before));
383
383
  }
384
384
  rooms.set(locator, {
385
385
  ...room,
@@ -552,13 +552,13 @@ export function composeRuntime(options) {
552
552
  const model = restored(modelKey(record.locator, 'collection'), record.model);
553
553
  const selectionModel = restored(modelKey(record.locator, 'typed-selection'), record.selectionModel);
554
554
  const prior = previousReplicas.get(record.locator);
555
- const confirmed = readConfirmed({
555
+ const read = readConfirmed({
556
556
  ...record,
557
557
  model,
558
558
  selectionModel
559
559
  }, prior?.confirmed);
560
- if (confirmed === null) continue;
561
- replicas.set(record.locator, replicaOf(confirmed, queuedBatches.get(record.locator) ?? [], rewriting(), prior));
560
+ if (read.kind !== 'staged') continue;
561
+ replicas.set(record.locator, replicaOf(read.confirmed, queuedBatches.get(record.locator) ?? [], rewriting(), prior));
562
562
  const existing = rooms.get(record.locator);
563
563
  if (existing === undefined) list(record, false);
564
564
  else {
@@ -658,6 +658,7 @@ export function composeRuntime(options) {
658
658
  ];
659
659
  const written = new Map();
660
660
  for (const { batch, returned } of returning){
661
+ if (returned === null) continue;
661
662
  for (const saved of pendings.get(batch.id)?.drafts ?? []){
662
663
  const existing = written.get(saved.path) ?? roomDrafts.get(locator)?.get(saved.path);
663
664
  written.set(saved.path, {
@@ -720,16 +721,13 @@ export function composeRuntime(options) {
720
721
  model: modelOf(room.locator),
721
722
  selectionModel: modelOf(room.locator, 'typed-selection')
722
723
  }, prior?.confirmed);
723
- if (retained === null) {
724
- list(room, true);
725
- publishChangeSet(changeSet(room.locator, prior ?? null, prior ?? null, {
726
- room: true
727
- }));
728
- return;
729
- }
730
- const set = await settle(local, room.locator, prior, retained, prior?.queue ?? [], {
724
+ if (retained.kind !== 'staged') throw new Error(`Cannot retype staged Room ${room.locator}`);
725
+ const queue = prior?.queue ?? [];
726
+ const accepted = queue.filter((batch)=>outcomes.get(batch.id)?.kind === 'accepted');
727
+ const set = await settle(local, room.locator, prior, retained.confirmed, queue.filter((batch)=>!accepted.includes(batch)), {
731
728
  room: true
732
729
  });
730
+ for (const batch of accepted)pendings.delete(batch.id);
733
731
  unreadable.delete(room.locator);
734
732
  sourceRefusals.delete(room.locator);
735
733
  list(room, true);
@@ -987,7 +985,7 @@ export function composeRuntime(options) {
987
985
  if (held !== undefined) {
988
986
  const refreshed = await pullRefresh(authorized, held.confirmed);
989
987
  if (refreshed.kind === 'still-current') {
990
- sourceRefusals.delete(room.locator);
988
+ if (sourceRefusals.has(room.locator)) return unconfirmed;
991
989
  if (unreadable.delete(room.locator)) {
992
990
  list(room, true);
993
991
  emitRooms();
@@ -1090,10 +1088,50 @@ export function composeRuntime(options) {
1090
1088
  }
1091
1089
  };
1092
1090
  }
1091
+ function acceptedOf(accepted) {
1092
+ return {
1093
+ kind: 'accepted',
1094
+ roomVersion: accepted.roomVersion,
1095
+ ...accepted.author === undefined ? {} : {
1096
+ author: accepted.author
1097
+ },
1098
+ ...accepted.time === undefined ? {} : {
1099
+ time: accepted.time
1100
+ }
1101
+ };
1102
+ }
1103
+ function logAccepted(locator, submitted, accepted) {
1104
+ journal.record(`outcome ${locator} ${submitted.id} accepted ${accepted.roomVersion}` + (accepted.author === undefined ? '' : ` author ${accepted.author}`) + (accepted.time === undefined ? '' : ` time ${accepted.time}`));
1105
+ }
1106
+ async function holdAccepted(room, local, submitted, accepted, refused) {
1107
+ await exclusive(async ()=>{
1108
+ const current = replicas.get(room.locator);
1109
+ if (current === undefined || !current.queue.some((batch)=>batch.id === submitted.id)) {
1110
+ return;
1111
+ }
1112
+ const outcome = acceptedOf(accepted);
1113
+ await local.write({
1114
+ next: current.confirmed.record,
1115
+ previous: current.confirmed.record,
1116
+ queue: current.queue,
1117
+ previousQueue: current.queue,
1118
+ outcomes: [
1119
+ {
1120
+ id: submitted.id,
1121
+ outcome
1122
+ }
1123
+ ]
1124
+ });
1125
+ outcomes.set(submitted.id, outcome);
1126
+ outcomeRooms.set(submitted.id, room.locator);
1127
+ logAccepted(room.locator, submitted, accepted);
1128
+ });
1129
+ if (refused !== null) refusedSource(room, refused);
1130
+ }
1093
1131
  async function commitAccept(room, local, submitted, accepted, base, overlay) {
1094
1132
  const current = replicas.get(room.locator);
1095
1133
  if (current === undefined || !current.queue.some((batch)=>batch.id === submitted.id)) {
1096
- return true;
1134
+ return null;
1097
1135
  }
1098
1136
  const remaining = current.queue.filter((batch)=>batch.id !== submitted.id);
1099
1137
  const retainedBase = readConfirmed({
@@ -1101,28 +1139,12 @@ export function composeRuntime(options) {
1101
1139
  model: modelOf(room.locator),
1102
1140
  selectionModel: modelOf(room.locator, 'typed-selection')
1103
1141
  }, base);
1104
- if (retainedBase === null) return false;
1105
- let applied = retainedBase;
1106
- if (overlay) {
1107
- const returned = applyReturned(retainedBase, accepted.documents, accepted.revisions, accepted.removals, accepted.roomVersion);
1108
- if (returned.kind === 'refused') refusedSource(room, returned);
1109
- if (returned.kind !== 'staged') return false;
1110
- applied = returned.confirmed;
1111
- }
1112
- const acceptedOutcome = {
1113
- kind: 'accepted',
1114
- roomVersion: accepted.roomVersion,
1115
- ...accepted.author === undefined ? {} : {
1116
- author: accepted.author
1117
- },
1118
- ...accepted.time === undefined ? {} : {
1119
- time: accepted.time
1120
- }
1121
- };
1122
- const set = await settle(local, room.locator, current, applied, remaining, {
1142
+ const applied = overlay && retainedBase.kind === 'staged' ? applyReturned(retainedBase.confirmed, accepted.documents, accepted.revisions, accepted.removals, accepted.roomVersion) : retainedBase;
1143
+ if (applied.kind !== 'staged') return applied;
1144
+ const set = await settle(local, room.locator, current, applied.confirmed, remaining, {
1123
1145
  accepted: {
1124
1146
  id: submitted.id,
1125
- outcome: acceptedOutcome
1147
+ outcome: acceptedOf(accepted)
1126
1148
  },
1127
1149
  room: true
1128
1150
  });
@@ -1134,14 +1156,24 @@ export function composeRuntime(options) {
1134
1156
  ...status,
1135
1157
  ...attention()
1136
1158
  });
1137
- journal.record(`outcome ${room.locator} ${submitted.id} accepted ${accepted.roomVersion}` + (accepted.author === undefined ? '' : ` author ${accepted.author}`) + (accepted.time === undefined ? '' : ` time ${accepted.time}`));
1138
- return true;
1159
+ logAccepted(room.locator, submitted, accepted);
1160
+ return null;
1161
+ }
1162
+ async function committed(room, local, submitted, accepted, base, overlay) {
1163
+ const failed = await exclusive(()=>commitAccept(room, local, submitted, accepted, base, overlay));
1164
+ if (failed === null) return true;
1165
+ await holdAccepted(room, local, submitted, accepted, failed.kind === 'refused' ? failed : null);
1166
+ return false;
1139
1167
  }
1140
1168
  async function submitRoom(room, local, authorized, progress) {
1141
1169
  while(!closed && authorization !== undefined){
1142
1170
  const replica = replicas.get(room.locator);
1143
1171
  const head = replica?.queue[0];
1144
1172
  if (replica === undefined || head === undefined) return null;
1173
+ if (outcomes.get(head.id)?.kind === 'accepted') {
1174
+ progress.complete = false;
1175
+ return null;
1176
+ }
1145
1177
  const { submission, lost: earlier } = pendings.get(head.id) ?? {
1146
1178
  submission: {
1147
1179
  state: 'waiting'
@@ -1191,6 +1223,10 @@ export function composeRuntime(options) {
1191
1223
  return null;
1192
1224
  }
1193
1225
  if (result.kind === 'conflicted' || result.kind === 'rejected' || result.kind === 'expired' || result.kind === 'retryable-refusal') {
1226
+ if (result.kind === 'expired') {
1227
+ const withheld = await advance(room, local, authorized);
1228
+ if (withheld !== null) return withhold(withheld, room, local, progress);
1229
+ }
1194
1230
  journal.record(`outcome ${room.locator} ${head.id} ${result.kind}` + (result.kind === 'conflicted' && result.roomVersion !== undefined ? ` ${result.roomVersion}` : ''));
1195
1231
  if (result.kind !== 'expired') journal.record(`refusal ${result.kind} ${result.code}`);
1196
1232
  }
@@ -1213,7 +1249,10 @@ export function composeRuntime(options) {
1213
1249
  return;
1214
1250
  }
1215
1251
  const set = await settle(local, room.locator, current, current.confirmed, current.queue.filter((batch)=>batch.id !== head.id), {
1216
- leaving: left
1252
+ leaving: result.kind === 'expired' && landed(head, current.confirmed) ? {
1253
+ ...left,
1254
+ returned: null
1255
+ } : left
1217
1256
  });
1218
1257
  publishChangeSet(set);
1219
1258
  moveTo({
@@ -1221,6 +1260,7 @@ export function composeRuntime(options) {
1221
1260
  ...attention()
1222
1261
  });
1223
1262
  });
1263
+ if (result.kind === 'expired') continue;
1224
1264
  const withheld = await advance(room, local, authorized);
1225
1265
  if (withheld !== null) return withhold(withheld, room, local, progress);
1226
1266
  continue;
@@ -1238,8 +1278,7 @@ export function composeRuntime(options) {
1238
1278
  return null;
1239
1279
  }
1240
1280
  if (pulled.kind === 'still-current') {
1241
- const committed = await exclusive(()=>commitAccept(room, local, head, result, from, true));
1242
- if (!committed) {
1281
+ if (!await committed(room, local, head, result, from, true)) {
1243
1282
  progress.complete = false;
1244
1283
  return null;
1245
1284
  }
@@ -1247,8 +1286,7 @@ export function composeRuntime(options) {
1247
1286
  }
1248
1287
  if (pulled.kind === 'advanced') {
1249
1288
  const overlay = pulled.confirmed.record.roomVersion === result.roomVersion;
1250
- const committed = await exclusive(()=>commitAccept(room, local, head, result, pulled.confirmed, overlay));
1251
- if (!committed) {
1289
+ if (!await committed(room, local, head, result, pulled.confirmed, overlay)) {
1252
1290
  progress.complete = false;
1253
1291
  return null;
1254
1292
  }
@@ -1267,8 +1305,7 @@ export function composeRuntime(options) {
1267
1305
  }
1268
1306
  if (bootstrapped.kind === 'staged') {
1269
1307
  const overlay = bootstrapped.confirmed.record.roomVersion === result.roomVersion;
1270
- const committed = await exclusive(()=>commitAccept(room, local, head, result, bootstrapped.confirmed, overlay));
1271
- if (!committed) {
1308
+ if (!await committed(room, local, head, result, bootstrapped.confirmed, overlay)) {
1272
1309
  progress.complete = false;
1273
1310
  return null;
1274
1311
  }
@@ -1282,7 +1319,7 @@ export function composeRuntime(options) {
1282
1319
  list(room, false);
1283
1320
  emitRooms();
1284
1321
  } else if (bootstrapped.kind === 'refused') {
1285
- refusedSource(room, bootstrapped);
1322
+ await holdAccepted(room, local, head, result, bootstrapped);
1286
1323
  }
1287
1324
  return null;
1288
1325
  }
@@ -1294,7 +1331,7 @@ export function composeRuntime(options) {
1294
1331
  list(room, false);
1295
1332
  emitRooms();
1296
1333
  } else if (pulled.kind === 'refused') {
1297
- refusedSource(room, pulled);
1334
+ await holdAccepted(room, local, head, result, pulled);
1298
1335
  }
1299
1336
  return null;
1300
1337
  }
@@ -1332,9 +1369,9 @@ export function composeRuntime(options) {
1332
1369
  previous: held.confirmed.record,
1333
1370
  queue: held.queue
1334
1371
  });
1335
- const confirmed = readConfirmed(record, held.confirmed);
1336
- if (confirmed !== null) {
1337
- replicas.set(room.locator, replicaOf(confirmed, held.queue, rewriting(), held));
1372
+ const read = readConfirmed(record, held.confirmed);
1373
+ if (read.kind === 'staged') {
1374
+ replicas.set(room.locator, replicaOf(read.confirmed, held.queue, rewriting(), held));
1338
1375
  }
1339
1376
  }
1340
1377
  models.set(key, next);