@agentshouse/mdruntime 0.1.0-alpha.30 → 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.
- package/dist/bootstrap.d.ts +2 -6
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +1 -5
- package/dist/bootstrap.js.map +1 -1
- package/dist/collection.d.ts +8 -5
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +35 -11
- package/dist/collection.js.map +1 -1
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +126 -45
- package/dist/connection.js.map +1 -1
- package/dist/refresh.d.ts +2 -2
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +4 -4
- package/dist/refresh.js.map +1 -1
- package/dist/replica.d.ts +9 -3
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +90 -6
- package/dist/replica.js.map +1 -1
- package/dist/transfer.d.ts +5 -0
- package/dist/transfer.d.ts.map +1 -1
- package/dist/transfer.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.d.ts
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import type { ModelState } from './model.js';
|
|
2
2
|
import type { Adapter, AdapterFailure, Authorization, DiscoveredRoom } from './adapter.js';
|
|
3
|
-
import { type
|
|
4
|
-
|
|
5
|
-
export type BootstrapOutcome = {
|
|
6
|
-
kind: 'staged';
|
|
7
|
-
confirmed: ConfirmedLayer;
|
|
8
|
-
} | Unconfirmed | AdapterFailure;
|
|
3
|
+
import { type Staged } from './replica.js';
|
|
4
|
+
export type BootstrapOutcome = Staged | AdapterFailure;
|
|
9
5
|
export declare function bootstrapRoom(adapter: Adapter, authorization: Authorization, room: DiscoveredRoom, models: {
|
|
10
6
|
collection: ModelState;
|
|
11
7
|
selection: ModelState;
|
package/dist/bootstrap.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC3F,OAAO,EAAc,KAAK,
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC3F,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAGvD,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,cAAc,CAAC;AAEvD,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,UAAU,CAAA;CAAE,GACxD,OAAO,CAAC,gBAAgB,CAAC,CAwC3B"}
|
package/dist/bootstrap.js
CHANGED
|
@@ -28,7 +28,7 @@ export async function bootstrapRoom(adapter, authorization, room, models) {
|
|
|
28
28
|
for (const target of page.binaryTargets)binaryTargets.add(target);
|
|
29
29
|
pageToken = page.pageToken;
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
return readStaged({
|
|
32
32
|
locator: room.locator,
|
|
33
33
|
collectionRoot: room.collectionRoot,
|
|
34
34
|
name: room.name,
|
|
@@ -46,10 +46,6 @@ export async function bootstrapRoom(adapter, authorization, room, models) {
|
|
|
46
46
|
].sort(),
|
|
47
47
|
revisions
|
|
48
48
|
});
|
|
49
|
-
return confirmed === null ? unconfirmed : {
|
|
50
|
-
kind: 'staged',
|
|
51
|
-
confirmed
|
|
52
|
-
};
|
|
53
49
|
}
|
|
54
50
|
|
|
55
51
|
//# sourceMappingURL=bootstrap.js.map
|
package/dist/bootstrap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/workspace/packages/mdruntime/src/bootstrap.ts"],"sourcesContent":["import type { ModelState } from './model.js';\nimport type { Adapter, AdapterFailure, Authorization, DiscoveredRoom } from './adapter.js';\nimport { readStaged, type
|
|
1
|
+
{"version":3,"sources":["/workspace/packages/mdruntime/src/bootstrap.ts"],"sourcesContent":["import type { ModelState } from './model.js';\nimport type { Adapter, AdapterFailure, Authorization, DiscoveredRoom } from './adapter.js';\nimport { readStaged, type Staged } from './replica.js';\nimport { unconfirmed } from './transfer.js';\n\nexport type BootstrapOutcome = Staged | AdapterFailure;\n\nexport async function bootstrapRoom(\n adapter: Adapter,\n authorization: Authorization,\n room: DiscoveredRoom,\n models: { collection: ModelState; selection: ModelState },\n): Promise<BootstrapOutcome> {\n const first = await adapter.bootstrap(authorization, {\n locator: room.locator,\n selection: room.replica.selection,\n });\n if (first.kind !== 'bootstrap') return first;\n const roomVersion = first.roomVersion;\n const documents: Record<string, string> = { ...first.documents };\n const revisions: Record<string, string> = { ...first.revisions };\n const binaryTargets = new Set(first.binaryTargets);\n let pageToken = first.pageToken;\n while (pageToken !== undefined) {\n const page = await adapter.bootstrap(authorization, {\n locator: room.locator,\n selection: room.replica.selection,\n pageToken,\n });\n if (page.kind !== 'bootstrap') return page;\n if (page.roomVersion !== roomVersion) return unconfirmed;\n Object.assign(documents, page.documents);\n Object.assign(revisions, page.revisions);\n for (const target of page.binaryTargets) binaryTargets.add(target);\n pageToken = page.pageToken;\n }\n return readStaged({\n locator: room.locator,\n collectionRoot: room.collectionRoot,\n name: room.name,\n operations: room.operations,\n replica: room.replica,\n attachedModel: room.attachedModel,\n model: models.collection,\n typedSelection: room.typedSelection ?? null,\n selectionModel: models.selection,\n providerOwnedPaths: room.providerOwnedPaths,\n roomVersion,\n documents,\n binaryTargets: [...binaryTargets].sort(),\n revisions,\n });\n}\n"],"names":["readStaged","unconfirmed","bootstrapRoom","adapter","authorization","room","models","first","bootstrap","locator","selection","replica","kind","roomVersion","documents","revisions","binaryTargets","Set","pageToken","undefined","page","Object","assign","target","add","collectionRoot","name","operations","attachedModel","model","collection","typedSelection","selectionModel","providerOwnedPaths","sort"],"mappings":"AAEA,SAASA,UAAU,QAAqB,eAAe;AACvD,SAASC,WAAW,QAAQ,gBAAgB;AAI5C,OAAO,eAAeC,cACpBC,OAAgB,EAChBC,aAA4B,EAC5BC,IAAoB,EACpBC,MAAyD;IAEzD,MAAMC,QAAQ,MAAMJ,QAAQK,SAAS,CAACJ,eAAe;QACnDK,SAASJ,KAAKI,OAAO;QACrBC,WAAWL,KAAKM,OAAO,CAACD,SAAS;IACnC;IACA,IAAIH,MAAMK,IAAI,KAAK,aAAa,OAAOL;IACvC,MAAMM,cAAcN,MAAMM,WAAW;IACrC,MAAMC,YAAoC;QAAE,GAAGP,MAAMO,SAAS;IAAC;IAC/D,MAAMC,YAAoC;QAAE,GAAGR,MAAMQ,SAAS;IAAC;IAC/D,MAAMC,gBAAgB,IAAIC,IAAIV,MAAMS,aAAa;IACjD,IAAIE,YAAYX,MAAMW,SAAS;IAC/B,MAAOA,cAAcC,UAAW;QAC9B,MAAMC,OAAO,MAAMjB,QAAQK,SAAS,CAACJ,eAAe;YAClDK,SAASJ,KAAKI,OAAO;YACrBC,WAAWL,KAAKM,OAAO,CAACD,SAAS;YACjCQ;QACF;QACA,IAAIE,KAAKR,IAAI,KAAK,aAAa,OAAOQ;QACtC,IAAIA,KAAKP,WAAW,KAAKA,aAAa,OAAOZ;QAC7CoB,OAAOC,MAAM,CAACR,WAAWM,KAAKN,SAAS;QACvCO,OAAOC,MAAM,CAACP,WAAWK,KAAKL,SAAS;QACvC,KAAK,MAAMQ,UAAUH,KAAKJ,aAAa,CAAEA,cAAcQ,GAAG,CAACD;QAC3DL,YAAYE,KAAKF,SAAS;IAC5B;IACA,OAAOlB,WAAW;QAChBS,SAASJ,KAAKI,OAAO;QACrBgB,gBAAgBpB,KAAKoB,cAAc;QACnCC,MAAMrB,KAAKqB,IAAI;QACfC,YAAYtB,KAAKsB,UAAU;QAC3BhB,SAASN,KAAKM,OAAO;QACrBiB,eAAevB,KAAKuB,aAAa;QACjCC,OAAOvB,OAAOwB,UAAU;QACxBC,gBAAgB1B,KAAK0B,cAAc,IAAI;QACvCC,gBAAgB1B,OAAOI,SAAS;QAChCuB,oBAAoB5B,KAAK4B,kBAAkB;QAC3CpB;QACAC;QACAE,eAAe;eAAIA;SAAc,CAACkB,IAAI;QACtCnB;IACF;AACF"}
|
package/dist/collection.d.ts
CHANGED
|
@@ -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
|
-
|
|
19
|
+
type Previous = {
|
|
19
20
|
text: Readonly<Record<string, string>>;
|
|
20
21
|
collection: Collection;
|
|
21
|
-
}
|
|
22
|
-
export declare function
|
|
23
|
-
|
|
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
|
-
}
|
|
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
|
package/dist/collection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,QAAQ,
|
|
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"}
|
package/dist/collection.js
CHANGED
|
@@ -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
|
|
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
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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;
|
package/dist/collection.js.map
CHANGED
|
@@ -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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"}
|
package/dist/connection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,WAAW,EAEjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAIL,KAAK,OAAO,EAEZ,KAAK,aAAa,EAIlB,KAAK,aAAa,EAKlB,KAAK,eAAe,EAErB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAExB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,aAAa,CAAC;AAG1D,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAc,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE1F,OAAO,EAA8B,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
|
package/dist/connection.js
CHANGED
|
@@ -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';
|
|
@@ -66,6 +66,7 @@ export function composeRuntime(options) {
|
|
|
66
66
|
const discovered = new Map();
|
|
67
67
|
let roomsListed = false;
|
|
68
68
|
const scopedRefusals = new Map();
|
|
69
|
+
const sourceRefusals = new Map();
|
|
69
70
|
function modelKey(locator, attached) {
|
|
70
71
|
return `${attached} ${locator}`;
|
|
71
72
|
}
|
|
@@ -376,9 +377,9 @@ export function composeRuntime(options) {
|
|
|
376
377
|
model: revoked,
|
|
377
378
|
selectionModel: revoked
|
|
378
379
|
};
|
|
379
|
-
const
|
|
380
|
-
if (
|
|
381
|
-
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));
|
|
382
383
|
}
|
|
383
384
|
rooms.set(locator, {
|
|
384
385
|
...room,
|
|
@@ -423,7 +424,7 @@ export function composeRuntime(options) {
|
|
|
423
424
|
providerOwnedPaths: room.providerOwnedPaths,
|
|
424
425
|
roomVersion: replicas.get(room.locator)?.confirmed.record.roomVersion ?? null,
|
|
425
426
|
synchronizationAvailable,
|
|
426
|
-
refusal: scopedRefusals.get(room.locator) ?? null
|
|
427
|
+
refusal: scopedRefusals.get(room.locator) ?? sourceRefusals.get(room.locator) ?? null
|
|
427
428
|
});
|
|
428
429
|
}
|
|
429
430
|
async function applyDiscovery(listed, local) {
|
|
@@ -475,6 +476,7 @@ export function composeRuntime(options) {
|
|
|
475
476
|
roomDrafts.delete(locator);
|
|
476
477
|
unreadable.delete(locator);
|
|
477
478
|
scopedRefusals.delete(locator);
|
|
479
|
+
sourceRefusals.delete(locator);
|
|
478
480
|
for (const attached of [
|
|
479
481
|
'collection',
|
|
480
482
|
'typed-selection'
|
|
@@ -550,13 +552,13 @@ export function composeRuntime(options) {
|
|
|
550
552
|
const model = restored(modelKey(record.locator, 'collection'), record.model);
|
|
551
553
|
const selectionModel = restored(modelKey(record.locator, 'typed-selection'), record.selectionModel);
|
|
552
554
|
const prior = previousReplicas.get(record.locator);
|
|
553
|
-
const
|
|
555
|
+
const read = readConfirmed({
|
|
554
556
|
...record,
|
|
555
557
|
model,
|
|
556
558
|
selectionModel
|
|
557
559
|
}, prior?.confirmed);
|
|
558
|
-
if (
|
|
559
|
-
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));
|
|
560
562
|
const existing = rooms.get(record.locator);
|
|
561
563
|
if (existing === undefined) list(record, false);
|
|
562
564
|
else {
|
|
@@ -656,6 +658,7 @@ export function composeRuntime(options) {
|
|
|
656
658
|
];
|
|
657
659
|
const written = new Map();
|
|
658
660
|
for (const { batch, returned } of returning){
|
|
661
|
+
if (returned === null) continue;
|
|
659
662
|
for (const saved of pendings.get(batch.id)?.drafts ?? []){
|
|
660
663
|
const existing = written.get(saved.path) ?? roomDrafts.get(locator)?.get(saved.path);
|
|
661
664
|
written.set(saved.path, {
|
|
@@ -718,17 +721,15 @@ export function composeRuntime(options) {
|
|
|
718
721
|
model: modelOf(room.locator),
|
|
719
722
|
selectionModel: modelOf(room.locator, 'typed-selection')
|
|
720
723
|
}, prior?.confirmed);
|
|
721
|
-
if (retained
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
}));
|
|
726
|
-
return;
|
|
727
|
-
}
|
|
728
|
-
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)), {
|
|
729
728
|
room: true
|
|
730
729
|
});
|
|
730
|
+
for (const batch of accepted)pendings.delete(batch.id);
|
|
731
731
|
unreadable.delete(room.locator);
|
|
732
|
+
sourceRefusals.delete(room.locator);
|
|
732
733
|
list(room, true);
|
|
733
734
|
publishChangeSet(set);
|
|
734
735
|
moveTo({
|
|
@@ -984,6 +985,7 @@ export function composeRuntime(options) {
|
|
|
984
985
|
if (held !== undefined) {
|
|
985
986
|
const refreshed = await pullRefresh(authorized, held.confirmed);
|
|
986
987
|
if (refreshed.kind === 'still-current') {
|
|
988
|
+
if (sourceRefusals.has(room.locator)) return unconfirmed;
|
|
987
989
|
if (unreadable.delete(room.locator)) {
|
|
988
990
|
list(room, true);
|
|
989
991
|
emitRooms();
|
|
@@ -1013,12 +1015,33 @@ export function composeRuntime(options) {
|
|
|
1013
1015
|
unreadable.add(room.locator);
|
|
1014
1016
|
list(room, false);
|
|
1015
1017
|
emitRooms();
|
|
1018
|
+
} else if (withheld.kind === 'refused') {
|
|
1019
|
+
refusedSource(room, withheld);
|
|
1016
1020
|
} else if (withheld.kind === 'revoked-authorization') {
|
|
1017
1021
|
await refuse('revoked-authorization');
|
|
1018
1022
|
return 'stop';
|
|
1019
1023
|
}
|
|
1020
1024
|
return null;
|
|
1021
1025
|
}
|
|
1026
|
+
function refusedSource(room, { refusal }) {
|
|
1027
|
+
sourceRefusals.set(room.locator, {
|
|
1028
|
+
code: refusal.rule,
|
|
1029
|
+
fields: {
|
|
1030
|
+
file: refusal.file,
|
|
1031
|
+
...refusal.location === undefined ? {} : {
|
|
1032
|
+
location: refusal.location
|
|
1033
|
+
},
|
|
1034
|
+
version: refusal.version,
|
|
1035
|
+
...refusal.referrers === undefined ? {} : {
|
|
1036
|
+
referrers: refusal.referrers
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
});
|
|
1040
|
+
unreadable.add(room.locator);
|
|
1041
|
+
list(room, false);
|
|
1042
|
+
emitRooms();
|
|
1043
|
+
journal.record(`source refused ${room.locator} ${refusal.rule} ${refusal.file}`);
|
|
1044
|
+
}
|
|
1022
1045
|
function leaving(batch, result) {
|
|
1023
1046
|
if (result.kind === 'expired') {
|
|
1024
1047
|
return {
|
|
@@ -1065,10 +1088,50 @@ export function composeRuntime(options) {
|
|
|
1065
1088
|
}
|
|
1066
1089
|
};
|
|
1067
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
|
+
}
|
|
1068
1131
|
async function commitAccept(room, local, submitted, accepted, base, overlay) {
|
|
1069
1132
|
const current = replicas.get(room.locator);
|
|
1070
1133
|
if (current === undefined || !current.queue.some((batch)=>batch.id === submitted.id)) {
|
|
1071
|
-
return
|
|
1134
|
+
return null;
|
|
1072
1135
|
}
|
|
1073
1136
|
const remaining = current.queue.filter((batch)=>batch.id !== submitted.id);
|
|
1074
1137
|
const retainedBase = readConfirmed({
|
|
@@ -1076,41 +1139,41 @@ export function composeRuntime(options) {
|
|
|
1076
1139
|
model: modelOf(room.locator),
|
|
1077
1140
|
selectionModel: modelOf(room.locator, 'typed-selection')
|
|
1078
1141
|
}, base);
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
const acceptedOutcome = {
|
|
1083
|
-
kind: 'accepted',
|
|
1084
|
-
roomVersion: accepted.roomVersion,
|
|
1085
|
-
...accepted.author === undefined ? {} : {
|
|
1086
|
-
author: accepted.author
|
|
1087
|
-
},
|
|
1088
|
-
...accepted.time === undefined ? {} : {
|
|
1089
|
-
time: accepted.time
|
|
1090
|
-
}
|
|
1091
|
-
};
|
|
1092
|
-
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, {
|
|
1093
1145
|
accepted: {
|
|
1094
1146
|
id: submitted.id,
|
|
1095
|
-
outcome:
|
|
1147
|
+
outcome: acceptedOf(accepted)
|
|
1096
1148
|
},
|
|
1097
1149
|
room: true
|
|
1098
1150
|
});
|
|
1099
1151
|
unreadable.delete(room.locator);
|
|
1152
|
+
sourceRefusals.delete(room.locator);
|
|
1100
1153
|
list(room, true);
|
|
1101
1154
|
publishChangeSet(set);
|
|
1102
1155
|
moveTo({
|
|
1103
1156
|
...status,
|
|
1104
1157
|
...attention()
|
|
1105
1158
|
});
|
|
1106
|
-
|
|
1107
|
-
return
|
|
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;
|
|
1108
1167
|
}
|
|
1109
1168
|
async function submitRoom(room, local, authorized, progress) {
|
|
1110
1169
|
while(!closed && authorization !== undefined){
|
|
1111
1170
|
const replica = replicas.get(room.locator);
|
|
1112
1171
|
const head = replica?.queue[0];
|
|
1113
1172
|
if (replica === undefined || head === undefined) return null;
|
|
1173
|
+
if (outcomes.get(head.id)?.kind === 'accepted') {
|
|
1174
|
+
progress.complete = false;
|
|
1175
|
+
return null;
|
|
1176
|
+
}
|
|
1114
1177
|
const { submission, lost: earlier } = pendings.get(head.id) ?? {
|
|
1115
1178
|
submission: {
|
|
1116
1179
|
state: 'waiting'
|
|
@@ -1160,6 +1223,10 @@ export function composeRuntime(options) {
|
|
|
1160
1223
|
return null;
|
|
1161
1224
|
}
|
|
1162
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
|
+
}
|
|
1163
1230
|
journal.record(`outcome ${room.locator} ${head.id} ${result.kind}` + (result.kind === 'conflicted' && result.roomVersion !== undefined ? ` ${result.roomVersion}` : ''));
|
|
1164
1231
|
if (result.kind !== 'expired') journal.record(`refusal ${result.kind} ${result.code}`);
|
|
1165
1232
|
}
|
|
@@ -1182,7 +1249,10 @@ export function composeRuntime(options) {
|
|
|
1182
1249
|
return;
|
|
1183
1250
|
}
|
|
1184
1251
|
const set = await settle(local, room.locator, current, current.confirmed, current.queue.filter((batch)=>batch.id !== head.id), {
|
|
1185
|
-
leaving:
|
|
1252
|
+
leaving: result.kind === 'expired' && landed(head, current.confirmed) ? {
|
|
1253
|
+
...left,
|
|
1254
|
+
returned: null
|
|
1255
|
+
} : left
|
|
1186
1256
|
});
|
|
1187
1257
|
publishChangeSet(set);
|
|
1188
1258
|
moveTo({
|
|
@@ -1190,6 +1260,7 @@ export function composeRuntime(options) {
|
|
|
1190
1260
|
...attention()
|
|
1191
1261
|
});
|
|
1192
1262
|
});
|
|
1263
|
+
if (result.kind === 'expired') continue;
|
|
1193
1264
|
const withheld = await advance(room, local, authorized);
|
|
1194
1265
|
if (withheld !== null) return withhold(withheld, room, local, progress);
|
|
1195
1266
|
continue;
|
|
@@ -1207,8 +1278,7 @@ export function composeRuntime(options) {
|
|
|
1207
1278
|
return null;
|
|
1208
1279
|
}
|
|
1209
1280
|
if (pulled.kind === 'still-current') {
|
|
1210
|
-
|
|
1211
|
-
if (!committed) {
|
|
1281
|
+
if (!await committed(room, local, head, result, from, true)) {
|
|
1212
1282
|
progress.complete = false;
|
|
1213
1283
|
return null;
|
|
1214
1284
|
}
|
|
@@ -1216,8 +1286,7 @@ export function composeRuntime(options) {
|
|
|
1216
1286
|
}
|
|
1217
1287
|
if (pulled.kind === 'advanced') {
|
|
1218
1288
|
const overlay = pulled.confirmed.record.roomVersion === result.roomVersion;
|
|
1219
|
-
|
|
1220
|
-
if (!committed) {
|
|
1289
|
+
if (!await committed(room, local, head, result, pulled.confirmed, overlay)) {
|
|
1221
1290
|
progress.complete = false;
|
|
1222
1291
|
return null;
|
|
1223
1292
|
}
|
|
@@ -1236,8 +1305,7 @@ export function composeRuntime(options) {
|
|
|
1236
1305
|
}
|
|
1237
1306
|
if (bootstrapped.kind === 'staged') {
|
|
1238
1307
|
const overlay = bootstrapped.confirmed.record.roomVersion === result.roomVersion;
|
|
1239
|
-
|
|
1240
|
-
if (!committed) {
|
|
1308
|
+
if (!await committed(room, local, head, result, bootstrapped.confirmed, overlay)) {
|
|
1241
1309
|
progress.complete = false;
|
|
1242
1310
|
return null;
|
|
1243
1311
|
}
|
|
@@ -1250,6 +1318,8 @@ export function composeRuntime(options) {
|
|
|
1250
1318
|
unreadable.add(room.locator);
|
|
1251
1319
|
list(room, false);
|
|
1252
1320
|
emitRooms();
|
|
1321
|
+
} else if (bootstrapped.kind === 'refused') {
|
|
1322
|
+
await holdAccepted(room, local, head, result, bootstrapped);
|
|
1253
1323
|
}
|
|
1254
1324
|
return null;
|
|
1255
1325
|
}
|
|
@@ -1260,6 +1330,8 @@ export function composeRuntime(options) {
|
|
|
1260
1330
|
unreadable.add(room.locator);
|
|
1261
1331
|
list(room, false);
|
|
1262
1332
|
emitRooms();
|
|
1333
|
+
} else if (pulled.kind === 'refused') {
|
|
1334
|
+
await holdAccepted(room, local, head, result, pulled);
|
|
1263
1335
|
}
|
|
1264
1336
|
return null;
|
|
1265
1337
|
}
|
|
@@ -1297,9 +1369,9 @@ export function composeRuntime(options) {
|
|
|
1297
1369
|
previous: held.confirmed.record,
|
|
1298
1370
|
queue: held.queue
|
|
1299
1371
|
});
|
|
1300
|
-
const
|
|
1301
|
-
if (
|
|
1302
|
-
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));
|
|
1303
1375
|
}
|
|
1304
1376
|
}
|
|
1305
1377
|
models.set(key, next);
|
|
@@ -1704,10 +1776,19 @@ export function composeRuntime(options) {
|
|
|
1704
1776
|
if (handed?.includes(locator) !== true) continue;
|
|
1705
1777
|
const room = discovered.get(locator);
|
|
1706
1778
|
const held = replicas.get(locator);
|
|
1707
|
-
if (room === undefined
|
|
1779
|
+
if (room === undefined) continue;
|
|
1780
|
+
if (sourceRefusals.has(locator)) {
|
|
1781
|
+
void enqueue();
|
|
1782
|
+
continue;
|
|
1783
|
+
}
|
|
1784
|
+
if (held === undefined) continue;
|
|
1708
1785
|
if (held.confirmed.record.roomVersion === roomVersion) continue;
|
|
1709
1786
|
const withheld = await advance(room, local, authorization);
|
|
1710
1787
|
if (withheld === null) continue;
|
|
1788
|
+
if (withheld.kind === 'refused') {
|
|
1789
|
+
void enqueue();
|
|
1790
|
+
continue;
|
|
1791
|
+
}
|
|
1711
1792
|
if (withheld.kind === 'scoped-refusal') {
|
|
1712
1793
|
await scoped(withheld, room, local);
|
|
1713
1794
|
continue;
|