@superbee/core 0.2.0-pre.40 → 0.2.0-pre.42
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/README.md +96 -9
- package/dist/backend.d.ts +17 -1
- package/dist/backend.d.ts.map +1 -1
- package/dist/backend.js +41 -6
- package/dist/backend.js.map +1 -1
- package/dist/body-pages.d.ts +20 -0
- package/dist/body-pages.d.ts.map +1 -0
- package/dist/body-pages.js +56 -0
- package/dist/body-pages.js.map +1 -0
- package/dist/body-replace-guards.d.ts +29 -3
- package/dist/body-replace-guards.d.ts.map +1 -1
- package/dist/body-replace-guards.js +112 -19
- package/dist/body-replace-guards.js.map +1 -1
- package/dist/bounded-yaml.d.ts +28 -0
- package/dist/bounded-yaml.d.ts.map +1 -0
- package/dist/bounded-yaml.js +182 -0
- package/dist/bounded-yaml.js.map +1 -0
- package/dist/builtin-recipes/site.d.ts +5 -0
- package/dist/builtin-recipes/site.d.ts.map +1 -0
- package/dist/builtin-recipes/site.js +83 -0
- package/dist/builtin-recipes/site.js.map +1 -0
- package/dist/builtin-recipes.d.ts.map +1 -1
- package/dist/builtin-recipes.js +22 -0
- package/dist/builtin-recipes.js.map +1 -1
- package/dist/bundle-health/index.d.ts +2 -2
- package/dist/bundle-health/index.d.ts.map +1 -1
- package/dist/bundle-health/index.js +1 -1
- package/dist/bundle-health/index.js.map +1 -1
- package/dist/bundle-health/legacy-page.d.ts +8 -26
- package/dist/bundle-health/legacy-page.d.ts.map +1 -1
- package/dist/bundle-health/legacy-page.js +10 -35
- package/dist/bundle-health/legacy-page.js.map +1 -1
- package/dist/bundle-health/report.d.ts +0 -16
- package/dist/bundle-health/report.d.ts.map +1 -1
- package/dist/bundle-health/report.js +24 -54
- package/dist/bundle-health/report.js.map +1 -1
- package/dist/bundle-ops.d.ts +4 -1
- package/dist/bundle-ops.d.ts.map +1 -1
- package/dist/bundle-ops.js +6 -2
- package/dist/bundle-ops.js.map +1 -1
- package/dist/bundle.d.ts +1 -1
- package/dist/bundle.d.ts.map +1 -1
- package/dist/bundle.js +1 -1
- package/dist/bundle.js.map +1 -1
- package/dist/cross-bundle.d.ts +2 -2
- package/dist/cross-bundle.js +2 -2
- package/dist/document-codec.d.ts +3 -1
- package/dist/document-codec.d.ts.map +1 -1
- package/dist/document-codec.js +3 -1
- package/dist/document-codec.js.map +1 -1
- package/dist/document-mutation.d.ts +2 -0
- package/dist/document-mutation.d.ts.map +1 -1
- package/dist/document-mutation.js +44 -9
- package/dist/document-mutation.js.map +1 -1
- package/dist/document-scan.d.ts +23 -0
- package/dist/document-scan.d.ts.map +1 -0
- package/dist/document-scan.js +70 -0
- package/dist/document-scan.js.map +1 -0
- package/dist/document-transfer.d.ts +110 -4
- package/dist/document-transfer.d.ts.map +1 -1
- package/dist/document-transfer.js +490 -30
- package/dist/document-transfer.js.map +1 -1
- package/dist/engine.d.ts +4 -19
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +7 -47
- package/dist/engine.js.map +1 -1
- package/dist/errors.d.ts +37 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +75 -3
- package/dist/errors.js.map +1 -1
- package/dist/file-journaled-backend.d.ts.map +1 -1
- package/dist/file-journaled-backend.js +2 -2
- package/dist/file-journaled-backend.js.map +1 -1
- package/dist/filesystem-identity.d.ts +9 -0
- package/dist/filesystem-identity.d.ts.map +1 -1
- package/dist/filesystem-identity.js +186 -64
- package/dist/filesystem-identity.js.map +1 -1
- package/dist/filesystem-lock.d.ts +2 -2
- package/dist/filesystem-lock.d.ts.map +1 -1
- package/dist/filesystem-lock.js +81 -14
- package/dist/filesystem-lock.js.map +1 -1
- package/dist/filesystem-temp-name.d.ts +9 -0
- package/dist/filesystem-temp-name.d.ts.map +1 -0
- package/dist/filesystem-temp-name.js +20 -0
- package/dist/filesystem-temp-name.js.map +1 -0
- package/dist/filesystem.d.ts +6 -0
- package/dist/filesystem.d.ts.map +1 -1
- package/dist/filesystem.js +2 -1
- package/dist/filesystem.js.map +1 -1
- package/dist/frontmatter-contract.d.ts +14 -0
- package/dist/frontmatter-contract.d.ts.map +1 -1
- package/dist/frontmatter-contract.js +22 -0
- package/dist/frontmatter-contract.js.map +1 -1
- package/dist/frontmatter-splitter.d.ts +6 -0
- package/dist/frontmatter-splitter.d.ts.map +1 -1
- package/dist/frontmatter-splitter.js +8 -0
- package/dist/frontmatter-splitter.js.map +1 -1
- package/dist/frontmatter.d.ts +8 -1
- package/dist/frontmatter.d.ts.map +1 -1
- package/dist/frontmatter.js +43 -7
- package/dist/frontmatter.js.map +1 -1
- package/dist/hosted-client/client.d.ts +22 -5
- package/dist/hosted-client/client.d.ts.map +1 -1
- package/dist/hosted-client/client.js +57 -10
- package/dist/hosted-client/client.js.map +1 -1
- package/dist/hosted-client/index.d.ts +1 -0
- package/dist/hosted-client/index.d.ts.map +1 -1
- package/dist/hosted-client/index.js +1 -0
- package/dist/hosted-client/index.js.map +1 -1
- package/dist/hosted-client/view-content.d.ts +107 -0
- package/dist/hosted-client/view-content.d.ts.map +1 -0
- package/dist/hosted-client/view-content.js +155 -0
- package/dist/hosted-client/view-content.js.map +1 -0
- package/dist/hosted-transport/carrier.d.ts +1 -1
- package/dist/hosted-transport/carrier.d.ts.map +1 -1
- package/dist/hosted-transport/carrier.js +27 -18
- package/dist/hosted-transport/carrier.js.map +1 -1
- package/dist/hosted-transport/document-backend.d.ts +74 -0
- package/dist/hosted-transport/document-backend.d.ts.map +1 -0
- package/dist/hosted-transport/document-backend.js +160 -0
- package/dist/hosted-transport/document-backend.js.map +1 -0
- package/dist/hosted-transport/index.d.ts +1 -0
- package/dist/hosted-transport/index.d.ts.map +1 -1
- package/dist/hosted-transport/index.js +1 -0
- package/dist/hosted-transport/index.js.map +1 -1
- package/dist/hosted-transport/read-adapter.d.ts +1 -2
- package/dist/hosted-transport/read-adapter.d.ts.map +1 -1
- package/dist/hosted-transport/read-adapter.js.map +1 -1
- package/dist/identity-fold.d.ts +12 -14
- package/dist/identity-fold.d.ts.map +1 -1
- package/dist/identity-fold.js +17 -15
- package/dist/identity-fold.js.map +1 -1
- package/dist/index-projection.d.ts +2 -1
- package/dist/index-projection.d.ts.map +1 -1
- package/dist/index-projection.js +14 -5
- package/dist/index-projection.js.map +1 -1
- package/dist/index.d.ts +24 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -15
- package/dist/index.js.map +1 -1
- package/dist/indexeddb-backend.d.ts.map +1 -1
- package/dist/indexeddb-backend.js +2 -2
- package/dist/indexeddb-backend.js.map +1 -1
- package/dist/json-data.d.ts +3 -0
- package/dist/json-data.d.ts.map +1 -0
- package/dist/json-data.js +19 -0
- package/dist/json-data.js.map +1 -0
- package/dist/kind-authoring.d.ts +18 -0
- package/dist/kind-authoring.d.ts.map +1 -1
- package/dist/kind-authoring.js +54 -4
- package/dist/kind-authoring.js.map +1 -1
- package/dist/kind-coverage.d.ts +1 -0
- package/dist/kind-coverage.d.ts.map +1 -1
- package/dist/kind-coverage.js +4 -5
- package/dist/kind-coverage.js.map +1 -1
- package/dist/kind-undeclared-fields.d.ts +70 -0
- package/dist/kind-undeclared-fields.d.ts.map +1 -0
- package/dist/kind-undeclared-fields.js +120 -0
- package/dist/kind-undeclared-fields.js.map +1 -0
- package/dist/kinds-load.d.ts.map +1 -1
- package/dist/kinds-load.js +4 -1
- package/dist/kinds-load.js.map +1 -1
- package/dist/kinds.d.ts +9 -0
- package/dist/kinds.d.ts.map +1 -1
- package/dist/kinds.js +20 -0
- package/dist/kinds.js.map +1 -1
- package/dist/link-findings.d.ts +130 -0
- package/dist/link-findings.d.ts.map +1 -0
- package/dist/link-findings.js +272 -0
- package/dist/link-findings.js.map +1 -0
- package/dist/link-types.d.ts +7 -0
- package/dist/link-types.d.ts.map +1 -1
- package/dist/link-types.js +17 -2
- package/dist/link-types.js.map +1 -1
- package/dist/memory-backend.d.ts.map +1 -1
- package/dist/memory-backend.js +2 -2
- package/dist/memory-backend.js.map +1 -1
- package/dist/page.d.ts +3 -7
- package/dist/page.d.ts.map +1 -1
- package/dist/page.js +3 -7
- package/dist/page.js.map +1 -1
- package/dist/path-fold.d.ts +29 -16
- package/dist/path-fold.d.ts.map +1 -1
- package/dist/path-fold.js +30 -17
- package/dist/path-fold.js.map +1 -1
- package/dist/paths.d.ts +28 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +82 -1
- package/dist/paths.js.map +1 -1
- package/dist/platform.d.ts +9 -0
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js.map +1 -1
- package/dist/portable-frontmatter.d.ts +6 -0
- package/dist/portable-frontmatter.d.ts.map +1 -1
- package/dist/portable-frontmatter.js +26 -2
- package/dist/portable-frontmatter.js.map +1 -1
- package/dist/recipe-lifecycle/install.d.ts +4 -7
- package/dist/recipe-lifecycle/install.d.ts.map +1 -1
- package/dist/recipe-lifecycle/install.js +3 -20
- package/dist/recipe-lifecycle/install.js.map +1 -1
- package/dist/recipe-lifecycle/legacy-aliases.d.ts +1 -13
- package/dist/recipe-lifecycle/legacy-aliases.d.ts.map +1 -1
- package/dist/recipe-lifecycle/legacy-aliases.js +5 -34
- package/dist/recipe-lifecycle/legacy-aliases.js.map +1 -1
- package/dist/record-overlay/apply.d.ts.map +1 -1
- package/dist/record-overlay/apply.js +0 -4
- package/dist/record-overlay/apply.js.map +1 -1
- package/dist/record-overlay/findings.d.ts.map +1 -1
- package/dist/record-overlay/findings.js +4 -1
- package/dist/record-overlay/findings.js.map +1 -1
- package/dist/record-overlay/plan.js +3 -3
- package/dist/record-overlay/plan.js.map +1 -1
- package/dist/record-overlay/signal-text.d.ts +9 -2
- package/dist/record-overlay/signal-text.d.ts.map +1 -1
- package/dist/record-overlay/signal-text.js +21 -11
- package/dist/record-overlay/signal-text.js.map +1 -1
- package/dist/remote-backend.d.ts +9 -19
- package/dist/remote-backend.d.ts.map +1 -1
- package/dist/remote-backend.js +17 -5
- package/dist/remote-backend.js.map +1 -1
- package/dist/remote-operations.d.ts.map +1 -1
- package/dist/remote-operations.js +2 -0
- package/dist/remote-operations.js.map +1 -1
- package/dist/remote-parsers.d.ts +19 -0
- package/dist/remote-parsers.d.ts.map +1 -1
- package/dist/remote-parsers.js.map +1 -1
- package/dist/remote.d.ts +2 -4
- package/dist/remote.d.ts.map +1 -1
- package/dist/remote.js +2 -3
- package/dist/remote.js.map +1 -1
- package/dist/reserved-write.d.ts +9 -0
- package/dist/reserved-write.d.ts.map +1 -0
- package/dist/reserved-write.js +15 -0
- package/dist/reserved-write.js.map +1 -0
- package/dist/search/backend-source.d.ts +2 -2
- package/dist/search/backend-source.d.ts.map +1 -1
- package/dist/search/backend-source.js +30 -6
- package/dist/search/backend-source.js.map +1 -1
- package/dist/search/contract.d.ts +3 -0
- package/dist/search/contract.d.ts.map +1 -1
- package/dist/search/contract.js.map +1 -1
- package/dist/search/search.d.ts.map +1 -1
- package/dist/search/search.js +4 -1
- package/dist/search/search.js.map +1 -1
- package/dist/search/source.d.ts +3 -0
- package/dist/search/source.d.ts.map +1 -1
- package/dist/site-manifest.d.ts +49 -0
- package/dist/site-manifest.d.ts.map +1 -0
- package/dist/site-manifest.js +113 -0
- package/dist/site-manifest.js.map +1 -0
- package/dist/skip-reasons.d.ts +12 -0
- package/dist/skip-reasons.d.ts.map +1 -0
- package/dist/skip-reasons.js +15 -0
- package/dist/skip-reasons.js.map +1 -0
- package/dist/source-engine/driver.d.ts +4 -4
- package/dist/source-engine/driver.d.ts.map +1 -1
- package/dist/source-engine/driver.js +155 -34
- package/dist/source-engine/driver.js.map +1 -1
- package/dist/source-engine/index.d.ts +3 -1
- package/dist/source-engine/index.d.ts.map +1 -1
- package/dist/source-engine/index.js +1 -0
- package/dist/source-engine/index.js.map +1 -1
- package/dist/source-engine/machine-state.d.ts +19 -6
- package/dist/source-engine/machine-state.d.ts.map +1 -1
- package/dist/source-engine/machine-state.js +48 -2
- package/dist/source-engine/machine-state.js.map +1 -1
- package/dist/source-engine/observe.d.ts.map +1 -1
- package/dist/source-engine/observe.js +10 -4
- package/dist/source-engine/observe.js.map +1 -1
- package/dist/source-engine/snapshot.js +1 -1
- package/dist/source-engine/snapshot.js.map +1 -1
- package/dist/source-engine/target-consumer.d.ts +12 -0
- package/dist/source-engine/target-consumer.d.ts.map +1 -0
- package/dist/source-engine/target-consumer.js +15 -0
- package/dist/source-engine/target-consumer.js.map +1 -0
- package/dist/source-engine/target-descriptor.d.ts +3 -0
- package/dist/source-engine/target-descriptor.d.ts.map +1 -0
- package/dist/source-engine/target-descriptor.js +26 -0
- package/dist/source-engine/target-descriptor.js.map +1 -0
- package/dist/source-engine/target.d.ts +82 -0
- package/dist/source-engine/target.d.ts.map +1 -0
- package/dist/source-engine/target.js +213 -0
- package/dist/source-engine/target.js.map +1 -0
- package/dist/source-engine/types.d.ts +5 -1
- package/dist/source-engine/types.d.ts.map +1 -1
- package/dist/source-profiles/index.d.ts +1 -1
- package/dist/source-profiles/index.js +1 -1
- package/dist/string-identity-agreement.d.ts +1 -1
- package/dist/string-identity-agreement.d.ts.map +1 -1
- package/dist/string-identity-agreement.js +6 -0
- package/dist/string-identity-agreement.js.map +1 -1
- package/dist/system-documents.d.ts +13 -0
- package/dist/system-documents.d.ts.map +1 -0
- package/dist/system-documents.js +44 -0
- package/dist/system-documents.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/validation.d.ts +5 -0
- package/dist/validation.d.ts.map +1 -1
- package/package.json +19 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site-manifest.d.ts","sourceRoot":"","sources":["../src/site-manifest.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,SAAS,SAAS,CAAC;AAChC,eAAO,MAAM,YAAY,WAAW,CAAC;AACrC,iFAAiF;AACjF,eAAO,MAAM,UAAU,QAAmC,CAAC;AAC3D,eAAO,MAAM,WAAW,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MACwB,CAAC;AAC/E,eAAO,MAAM,kBAAkB,+HAAgI,CAAC;AAEhK,MAAM,MAAM,yBAAyB,GACjC;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC7E;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AACjE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,yBAAyB,CAAC;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;CACjF;AACD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,MAAM,uBAAuB,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,GACxF;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAAE,CAAC;AA8B1E;qGACqG;AACrG,wBAAgB,oBAAoB,CAAC,GAAG,EAAE;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CAAE,GAAG,uBAAuB,CA6CnJ"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/** Portable Site declaration grammar. Parsing grants no build, install or publication authority. */
|
|
2
|
+
import { assertSafeBlobKey, assertSafeConceptId, nonCanonicalDocumentId } from "./paths.js";
|
|
3
|
+
import { isJsonData } from "./json-data.js";
|
|
4
|
+
import { isOkfStandardField } from "./okf-standard-fields.js";
|
|
5
|
+
import { isManagedDocumentMetadataField } from "./managed-document-metadata.js";
|
|
6
|
+
export const SITE_TYPE = "Site";
|
|
7
|
+
export const SITES_PREFIX = "sites/";
|
|
8
|
+
/** One site label leaves room for its workspace label in a combined DNS name. */
|
|
9
|
+
export const SITE_LABEL = /^[a-z][a-z0-9-]{1,30}[a-z0-9]$/;
|
|
10
|
+
export const isSiteLabel = (value) => typeof value === "string" && SITE_LABEL.test(value) && !value.includes("--");
|
|
11
|
+
export const SITE_DOCUMENT_KEYS = ["type", "title", "description", "presentation", "landing", "views", "audience", "capabilities", "options", "brand"];
|
|
12
|
+
const record = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
13
|
+
const packageName = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
|
|
14
|
+
const exactVersion = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
|
|
15
|
+
const encoder = new TextEncoder();
|
|
16
|
+
function presentationReference(raw) {
|
|
17
|
+
if (typeof raw !== "string" || raw.length > 512)
|
|
18
|
+
return undefined;
|
|
19
|
+
if (raw.startsWith("repo:")) {
|
|
20
|
+
const repository = raw.slice(5);
|
|
21
|
+
return /^[A-Za-z0-9][A-Za-z0-9-]{0,38}\/[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/.test(repository) && !repository.endsWith(".git")
|
|
22
|
+
? { kind: "repository", repository } : undefined;
|
|
23
|
+
}
|
|
24
|
+
const at = raw.lastIndexOf("@");
|
|
25
|
+
if (at < 1)
|
|
26
|
+
return undefined;
|
|
27
|
+
const name = raw.slice(0, at), version = raw.slice(at + 1), match = exactVersion.exec(version);
|
|
28
|
+
if (name.length > 214 || !packageName.test(name) || !match ||
|
|
29
|
+
!match.slice(1, 4).every(part => Number.isSafeInteger(Number(part))) ||
|
|
30
|
+
match[4]?.split(".").some(part => /^\d+$/.test(part) && (part.length > 1 && part.startsWith("0") || !Number.isSafeInteger(Number(part)))))
|
|
31
|
+
return undefined;
|
|
32
|
+
return { kind: "package", name, version };
|
|
33
|
+
}
|
|
34
|
+
const concept = (raw) => {
|
|
35
|
+
if (typeof raw !== "string")
|
|
36
|
+
return false;
|
|
37
|
+
try {
|
|
38
|
+
assertSafeConceptId(raw);
|
|
39
|
+
return nonCanonicalDocumentId(raw) === null;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const blob = (raw) => {
|
|
46
|
+
if (typeof raw !== "string")
|
|
47
|
+
return false;
|
|
48
|
+
try {
|
|
49
|
+
assertSafeBlobKey(raw);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
/** Standard OKF and managed metadata survive on the document; only Site fields enter this value.
|
|
57
|
+
* Presentation owners validate option semantics. Builders separately admit trusted resolved code. */
|
|
58
|
+
export function parseSiteManifestDoc(doc) {
|
|
59
|
+
const errors = [];
|
|
60
|
+
const fail = (path, message) => { errors.push({ code: "SITE_MANIFEST_INVALID", path, message }); };
|
|
61
|
+
const fm = record(doc?.frontmatter) ? doc.frontmatter : {};
|
|
62
|
+
const site = typeof doc?.id === "string" && doc.id.startsWith(SITES_PREFIX) ? doc.id.slice(SITES_PREFIX.length) : "";
|
|
63
|
+
if (!isSiteLabel(site))
|
|
64
|
+
fail("/id", "a Site lives at sites/<site>, using one site label");
|
|
65
|
+
if (fm.type !== SITE_TYPE)
|
|
66
|
+
fail("/type", "type must be Site");
|
|
67
|
+
if (Object.keys(fm).some(key => !SITE_DOCUMENT_KEYS.includes(key) && !isOkfStandardField(key) && !isManagedDocumentMetadataField(key)))
|
|
68
|
+
fail("", "unrecognized Site fields");
|
|
69
|
+
if (typeof fm.title !== "string" || fm.title.trim() === "" || encoder.encode(fm.title).byteLength > 512)
|
|
70
|
+
fail("/title", "title must be a nonempty string of at most 512 bytes");
|
|
71
|
+
if (fm.description !== undefined && (typeof fm.description !== "string" || encoder.encode(fm.description).byteLength > 8192))
|
|
72
|
+
fail("/description", "description must be a string of at most 8192 bytes");
|
|
73
|
+
const presentation = presentationReference(fm.presentation);
|
|
74
|
+
if (!presentation)
|
|
75
|
+
fail("/presentation", "presentation must name an exact npm version or repo:owner/name");
|
|
76
|
+
if (fm.audience !== "restricted")
|
|
77
|
+
fail("/audience", "only the restricted audience is supported");
|
|
78
|
+
const list = (raw, path, maximum, valid) => {
|
|
79
|
+
if (!Array.isArray(raw) || raw.length > maximum || !raw.every(valid) || new Set(raw).size !== raw.length) {
|
|
80
|
+
fail(path, "expected a bounded list of unique valid references");
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
return [...raw];
|
|
84
|
+
};
|
|
85
|
+
const views = list(fm.views, "/views", 64, concept);
|
|
86
|
+
const capability = (v) => typeof v === "string" && /^[a-z][a-z0-9-]{0,63}$/.test(v);
|
|
87
|
+
const capabilities = list(fm.capabilities ?? [], "/capabilities", 16, capability);
|
|
88
|
+
if (fm.landing !== undefined && !concept(fm.landing))
|
|
89
|
+
fail("/landing", "landing must be a canonical document or View id");
|
|
90
|
+
const options = fm.options ?? {};
|
|
91
|
+
if (!record(options) || !isJsonData(options) || encoder.encode(JSON.stringify(options)).byteLength > 16384)
|
|
92
|
+
fail("/options", "options must be JSON data of at most 16384 bytes");
|
|
93
|
+
let brand;
|
|
94
|
+
if (fm.brand !== undefined) {
|
|
95
|
+
if (!record(fm.brand) || Object.keys(fm.brand).some(key => key !== "logo" && key !== "fonts"))
|
|
96
|
+
fail("/brand", "brand may only name a logo and fonts");
|
|
97
|
+
else {
|
|
98
|
+
if (fm.brand.logo !== undefined && !blob(fm.brand.logo))
|
|
99
|
+
fail("/brand/logo", "logo must be a bundle blob reference");
|
|
100
|
+
const fonts = fm.brand.fonts === undefined ? undefined : list(fm.brand.fonts, "/brand/fonts", 16, blob);
|
|
101
|
+
brand = { ...(typeof fm.brand.logo === "string" ? { logo: fm.brand.logo } : {}), ...(fonts ? { fonts } : {}) };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (errors.length)
|
|
105
|
+
return { ok: false, errors };
|
|
106
|
+
return { ok: true, manifest: {
|
|
107
|
+
id: doc.id, site, title: fm.title, presentation: presentation, audience: "restricted", views, capabilities,
|
|
108
|
+
options: JSON.parse(JSON.stringify(options)),
|
|
109
|
+
...(fm.description === undefined ? {} : { description: fm.description }),
|
|
110
|
+
...(fm.landing === undefined ? {} : { landing: fm.landing }), ...(brand ? { brand } : {}),
|
|
111
|
+
} };
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=site-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site-manifest.js","sourceRoot":"","sources":["../src/site-manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The skip reason a resilient scan gives a document the host refused to read, and the one test
|
|
3
|
+
* for it. Dependency-free so a browser bundle can tell a permission problem from a malformed
|
|
4
|
+
* document without loading the scan.
|
|
5
|
+
*/
|
|
6
|
+
/** The skip reason for a read refused with `code` (`EACCES` or `EPERM`); never the host path. */
|
|
7
|
+
export declare function permissionDeniedReason(code: "EACCES" | "EPERM"): string;
|
|
8
|
+
/** True when a scan skipped this document because the host refused to read it, not because it is malformed. */
|
|
9
|
+
export declare function isPermissionDeniedSkip(skip: {
|
|
10
|
+
reason: string;
|
|
11
|
+
}): boolean;
|
|
12
|
+
//# sourceMappingURL=skip-reasons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skip-reasons.d.ts","sourceRoot":"","sources":["../src/skip-reasons.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,iGAAiG;AACjG,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAEvE;AAED,+GAA+G;AAC/G,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAExE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The skip reason a resilient scan gives a document the host refused to read, and the one test
|
|
3
|
+
* for it. Dependency-free so a browser bundle can tell a permission problem from a malformed
|
|
4
|
+
* document without loading the scan.
|
|
5
|
+
*/
|
|
6
|
+
const PERMISSION_DENIED_PREFIX = "permission denied (";
|
|
7
|
+
/** The skip reason for a read refused with `code` (`EACCES` or `EPERM`); never the host path. */
|
|
8
|
+
export function permissionDeniedReason(code) {
|
|
9
|
+
return `${PERMISSION_DENIED_PREFIX}${code})`;
|
|
10
|
+
}
|
|
11
|
+
/** True when a scan skipped this document because the host refused to read it, not because it is malformed. */
|
|
12
|
+
export function isPermissionDeniedSkip(skip) {
|
|
13
|
+
return skip.reason.startsWith(PERMISSION_DENIED_PREFIX);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=skip-reasons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skip-reasons.js","sourceRoot":"","sources":["../src/skip-reasons.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAEvD,iGAAiG;AACjG,MAAM,UAAU,sBAAsB,CAAC,IAAwB;IAC7D,OAAO,GAAG,wBAAwB,GAAG,IAAI,GAAG,CAAC;AAC/C,CAAC;AAED,+GAA+G;AAC/G,MAAM,UAAU,sBAAsB,CAAC,IAAwB;IAC7D,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
export { isJsonData } from "../json-data.js";
|
|
1
2
|
/** Internal observation owner shared by network and finite acquisition wrappers. */
|
|
2
3
|
import { type BoundFeed } from "../connectors.js";
|
|
3
4
|
import type { Finding } from "../record-overlay/types.js";
|
|
5
|
+
import type { SourceCommitPreparation } from "./target.js";
|
|
4
6
|
import { type Stop } from "./guard.js";
|
|
5
|
-
import type
|
|
7
|
+
import { type MachineState, type SourceState } from "./machine-state.js";
|
|
6
8
|
import type { CommitResult, PageCommit, SourceRunReceipt } from "./types.js";
|
|
7
9
|
export declare const DEFAULT_MISSING_THRESHOLD = 2;
|
|
8
10
|
export declare const MAX_CURSOR_CHARS = 8192;
|
|
9
11
|
export declare const MAX_REPLAY_FAILURES = 5;
|
|
10
12
|
export declare const UNSUPPORTED_CONTENT = "SOURCE_UNSUPPORTED_CONTENT";
|
|
11
|
-
/** JSON data only: finite numbers, plain objects and arrays, no undefined members. */
|
|
12
|
-
export declare function isJsonData(value: unknown, depth?: number): boolean;
|
|
13
13
|
interface DriverOptions {
|
|
14
14
|
bound: BoundFeed;
|
|
15
15
|
state: MachineState;
|
|
@@ -33,8 +33,8 @@ interface DriverOptions {
|
|
|
33
33
|
lastUrl?(): string | undefined;
|
|
34
34
|
stop(stop: Stop, url?: string): void;
|
|
35
35
|
extraFindings: Finding[];
|
|
36
|
+
prepareCommit?(page: PageCommit): Promise<SourceCommitPreparation>;
|
|
36
37
|
commit(page: PageCommit): Promise<CommitResult | void>;
|
|
37
38
|
}
|
|
38
39
|
export declare function driveObservation(options: DriverOptions): Promise<void>;
|
|
39
|
-
export {};
|
|
40
40
|
//# sourceMappingURL=driver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/source-engine/driver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/source-engine/driver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,oFAAoF;AACpF,OAAO,EAA4B,KAAK,SAAS,EAA0B,MAAM,kBAAkB,CAAC;AAEpG,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,4BAA4B,CAAC;AAKxE,OAAO,KAAK,EAAE,uBAAuB,EAAuB,MAAM,aAAa,CAAC;AAChF,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAA4C,KAAK,YAAY,EAAwC,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACzJ,OAAO,KAAK,EAAE,YAAY,EAAe,UAAU,EAAqB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE7G,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAyGhE,UAAU,aAAa;IACrB,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,aAAa,GAAG,UAAU,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,2FAA2F;IAC3F,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,aAAa,GAAG,UAAU,CAAC;QAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/J,OAAO,CAAC,IAAI,IAAI,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,IAAI,MAAM,GAAG,SAAS,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,aAAa,EAAE,OAAO,EAAE,CAAC;IACzB,aAAa,CAAC,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACnE,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;CACxD;AACD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAsU5E"}
|
|
@@ -1,31 +1,23 @@
|
|
|
1
|
+
import { isJsonData } from "../json-data.js";
|
|
2
|
+
export { isJsonData } from "../json-data.js";
|
|
1
3
|
/** Internal observation owner shared by network and finite acquisition wrappers. */
|
|
2
4
|
import { changeBetween, mapRecord } from "../connectors.js";
|
|
3
5
|
import { overlayCanonicalJson } from "../record-overlay/canonical.js";
|
|
6
|
+
import { parseIsoInstant } from "../verification.js";
|
|
7
|
+
import { parseMarkdown } from "../document-codec.js";
|
|
8
|
+
import { discardSourceTargetConsumer, isSourceTargetConsumer } from "./target-consumer.js";
|
|
9
|
+
import { isSourceEstablishment } from "./target-descriptor.js";
|
|
4
10
|
import { SourceStop } from "./guard.js";
|
|
11
|
+
import { hasProtectedSourcePending, isSourceState } from "./machine-state.js";
|
|
5
12
|
export const DEFAULT_MISSING_THRESHOLD = 2;
|
|
6
13
|
export const MAX_CURSOR_CHARS = 8192;
|
|
7
14
|
export const MAX_REPLAY_FAILURES = 5;
|
|
8
15
|
export const UNSUPPORTED_CONTENT = "SOURCE_UNSUPPORTED_CONTENT";
|
|
9
16
|
const record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
10
17
|
const clip = (text, n) => (text.length > n ? text.slice(0, n - 1) + "…" : text);
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return false;
|
|
15
|
-
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
16
|
-
return true;
|
|
17
|
-
if (typeof value === "number")
|
|
18
|
-
return Number.isFinite(value);
|
|
19
|
-
if (Array.isArray(value))
|
|
20
|
-
return value.every((item) => isJsonData(item, depth + 1));
|
|
21
|
-
if (!record(value))
|
|
22
|
-
return false;
|
|
23
|
-
// A plain object from any realm: its prototype is null or a prototype that itself has none.
|
|
24
|
-
const proto = Object.getPrototypeOf(value);
|
|
25
|
-
if (proto !== null && Object.getPrototypeOf(proto) !== null)
|
|
26
|
-
return false;
|
|
27
|
-
return Object.values(value).every((item) => item !== undefined && isJsonData(item, depth + 1));
|
|
28
|
-
}
|
|
18
|
+
/** External identities are arbitrary strings, including Object.prototype member names. */
|
|
19
|
+
const idMap = (entries) => Object.assign(Object.create(null), entries);
|
|
20
|
+
const ownEntry = (entries, id) => Object.hasOwn(entries, id) ? entries[id] : undefined;
|
|
29
21
|
/** The page as the engine accepts it, or why not. */
|
|
30
22
|
function pageProblem(page) {
|
|
31
23
|
if (!record(page))
|
|
@@ -74,7 +66,7 @@ function diffPage(state, page, bound, observedAt) {
|
|
|
74
66
|
const changes = [];
|
|
75
67
|
const entries = new Map();
|
|
76
68
|
for (const [id, mapped] of last) {
|
|
77
|
-
const stored =
|
|
69
|
+
const stored = ownEntry(state.records, id);
|
|
78
70
|
if (mapped.kind === "refused") {
|
|
79
71
|
// Refused but present: still observed, so never missing; its accepted values stay.
|
|
80
72
|
if (stored)
|
|
@@ -126,6 +118,7 @@ function commitResult(result) {
|
|
|
126
118
|
export async function driveObservation(options) {
|
|
127
119
|
const { bound, receipt, observedAt, mode, resumed, signal, extraFindings } = options;
|
|
128
120
|
const key = bound.policy.feed;
|
|
121
|
+
const qualified = isSourceTargetConsumer(options.prepareCommit, options.commit);
|
|
129
122
|
let state = options.initial;
|
|
130
123
|
let version = options.version;
|
|
131
124
|
const baseline = version === null;
|
|
@@ -138,6 +131,12 @@ export async function driveObservation(options) {
|
|
|
138
131
|
/** Store `next` after a commit; false when the store refused it and the run has stopped. */
|
|
139
132
|
const store = async (next) => {
|
|
140
133
|
try {
|
|
134
|
+
if ((qualified || options.prepareCommit || hasProtectedSourcePending(state))
|
|
135
|
+
&& ((qualified ? Object.keys(next.pending ?? {}).length : Object.values(next.pending ?? {}).filter(p => p.establishment).length) > 100
|
|
136
|
+
|| new TextEncoder().encode(JSON.stringify(next)).length > 4194304))
|
|
137
|
+
throw new Error("source establishment state limit");
|
|
138
|
+
if (!isSourceState(next))
|
|
139
|
+
throw new Error("invalid source state");
|
|
141
140
|
version = await options.state.write(key, next, version);
|
|
142
141
|
state = next;
|
|
143
142
|
receipt.pending = Object.keys(next.pending ?? {}).length;
|
|
@@ -153,28 +152,92 @@ export async function driveObservation(options) {
|
|
|
153
152
|
// Changes an earlier commit asked to retry are planned again before anything is fetched. A
|
|
154
153
|
// record that has since disappeared has nothing left to write, unless the held change is the
|
|
155
154
|
// record coming back.
|
|
155
|
+
const retained = hasProtectedSourcePending(state);
|
|
156
|
+
if (retained && !qualified) {
|
|
157
|
+
stop = { outcome: "failed", reason: "establishment_consumer_required", retry: false };
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (retained && (Object.keys(state.pending ?? {}).length > 100 || new TextEncoder().encode(JSON.stringify(state)).length > 4194304)) {
|
|
161
|
+
stop = { outcome: "failed", reason: "establishment_state_limit", retry: false };
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (retained && !signal.aborted) {
|
|
165
|
+
const pending = state.pending;
|
|
166
|
+
const context = state.pending_commit;
|
|
167
|
+
// Old establishment checkpoints never recorded page order/flags. Retain their stable
|
|
168
|
+
// legacy order only when every entry belongs to one original group and observation.
|
|
169
|
+
const ids = context?.order ?? Object.keys(pending).sort();
|
|
170
|
+
const at = pending[ids[0]].held_at;
|
|
171
|
+
const first = pending[ids[0]].establishment;
|
|
172
|
+
if (!context && (!first || parseIsoInstant(at) === null || ids.some(id => {
|
|
173
|
+
const p = pending[id], e = p.establishment;
|
|
174
|
+
return !e || e.group !== first.group || e.generation !== first.generation || e.observed_at !== at || p.held_at !== at;
|
|
175
|
+
}))) {
|
|
176
|
+
stop = { outcome: "failed", reason: "establishment_scope_changed", retry: false };
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const records = idMap();
|
|
180
|
+
for (const id of ids)
|
|
181
|
+
records[id] = { fields: { ...(pending[id].change.after ?? pending[id].change.before ?? {}) } };
|
|
182
|
+
let result;
|
|
183
|
+
try {
|
|
184
|
+
const establishments = Object.fromEntries(ids.filter(id => pending[id].establishment !== undefined).map(id => [id, pending[id].establishment]));
|
|
185
|
+
result = commitResult(await options.commit(structuredClone({ feed: key, provider: bound.policy.provider,
|
|
186
|
+
observed_at: at, page: context?.page ?? 0, replay: true, changes: ids.map(id => pending[id].change), records,
|
|
187
|
+
baseline: context?.baseline ?? false, complete: context?.complete ?? false,
|
|
188
|
+
...(Object.keys(establishments).length ? { establishments } : {}) })));
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
receipt.held += ids.length;
|
|
192
|
+
stop = { outcome: "failed", reason: "establishment_pending", retry: true, detail: errorText(error) };
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (ids.some(id => result.hold.has(id) || result.retry.has(id))) {
|
|
196
|
+
receipt.held += ids.length;
|
|
197
|
+
stop = { outcome: "failed", reason: "establishment_pending", retry: true };
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const nextRecords = idMap(state.records);
|
|
201
|
+
for (const id of ids)
|
|
202
|
+
nextRecords[id] = entryJson(pending[id].entry);
|
|
203
|
+
const next = { ...state, records: nextRecords };
|
|
204
|
+
delete next.pending;
|
|
205
|
+
delete next.pending_commit;
|
|
206
|
+
// No next cursor/validators were stored in the supplying checkpoint. A successful
|
|
207
|
+
// recovery may rescan from the old cursor; it cannot claim the lost page completed.
|
|
208
|
+
if (!(await store(next)))
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
156
211
|
const pendingIds = signal.aborted ? [] : Object.keys(state.pending ?? {}).sort();
|
|
157
212
|
if (pendingIds.length) {
|
|
158
213
|
const pending = state.pending;
|
|
159
|
-
const live = pendingIds.filter((id) => !state.records
|
|
214
|
+
const live = pendingIds.filter((id) => pending[id].establishment !== undefined || !ownEntry(state.records, id)?.gone || pending[id].change.change_kind === "new");
|
|
215
|
+
const marked = live.filter(id => pending[id].establishment !== undefined);
|
|
216
|
+
const establishments = Object.fromEntries(marked.map(id => [id, pending[id].establishment]));
|
|
160
217
|
const changes = live.map((id) => pending[id].change);
|
|
161
|
-
const records =
|
|
218
|
+
const records = idMap();
|
|
162
219
|
for (const change of changes)
|
|
163
220
|
records[change.external_id] = { fields: { ...(change.after ?? change.before ?? {}) } };
|
|
164
221
|
let result;
|
|
165
222
|
let failure;
|
|
166
223
|
if (live.length) {
|
|
167
224
|
try {
|
|
168
|
-
result = commitResult(await options.commit({
|
|
225
|
+
result = commitResult(await options.commit(structuredClone({
|
|
169
226
|
feed: key, provider: bound.policy.provider, observed_at: observedAt, page: 0, replay: true, changes, records, baseline: false, complete: false,
|
|
170
|
-
|
|
227
|
+
...(marked.length ? { establishments } : {}),
|
|
228
|
+
})));
|
|
171
229
|
}
|
|
172
230
|
catch (error) {
|
|
173
231
|
failure = errorText(error);
|
|
174
232
|
}
|
|
175
233
|
}
|
|
176
|
-
|
|
177
|
-
|
|
234
|
+
if (marked.some(id => failure !== undefined || result.retry.has(id) || result.hold.has(id))) {
|
|
235
|
+
receipt.held += marked.length;
|
|
236
|
+
stop = { outcome: "failed", reason: "establishment_pending", retry: true, ...(failure ? { detail: failure } : {}) };
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const nextRecords = idMap(state.records);
|
|
240
|
+
const nextPending = idMap();
|
|
178
241
|
const dropped = [];
|
|
179
242
|
for (const id of live) {
|
|
180
243
|
const entry = pending[id];
|
|
@@ -193,7 +256,7 @@ export async function driveObservation(options) {
|
|
|
193
256
|
else if (!result.hold.has(id)) {
|
|
194
257
|
// The record's absence since the hold is newer than the change, so its count stays; a
|
|
195
258
|
// record that comes back starts afresh.
|
|
196
|
-
const current = state.records
|
|
259
|
+
const current = ownEntry(state.records, id);
|
|
197
260
|
nextRecords[id] = entryJson(current?.gone ? entry.entry : { ...entry.entry, missing: current?.missing ?? 0, first_missing_at: current?.first_missing_at });
|
|
198
261
|
}
|
|
199
262
|
}
|
|
@@ -224,6 +287,10 @@ export async function driveObservation(options) {
|
|
|
224
287
|
if (!(await store(next)))
|
|
225
288
|
return;
|
|
226
289
|
}
|
|
290
|
+
if (qualified && Object.keys(state.pending ?? {}).length) {
|
|
291
|
+
stop = { outcome: "failed", reason: "establishment_pending", retry: true };
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
227
294
|
if (signal.aborted) {
|
|
228
295
|
stop = { outcome: "deferred", reason: "deadline", retry: true };
|
|
229
296
|
return;
|
|
@@ -295,7 +362,7 @@ export async function driveObservation(options) {
|
|
|
295
362
|
seen.add(id);
|
|
296
363
|
const ended = !page.more;
|
|
297
364
|
const complete = ended && mode === "complete" && page.complete && sourceComplete;
|
|
298
|
-
const merged =
|
|
365
|
+
const merged = idMap(state.records);
|
|
299
366
|
for (const [id, entry] of diff.entries)
|
|
300
367
|
merged[id] = entry;
|
|
301
368
|
const missing = complete ? missingAfterComplete(merged, seen, threshold, observedAt) : { changes: [], entries: new Map() };
|
|
@@ -308,7 +375,7 @@ export async function driveObservation(options) {
|
|
|
308
375
|
const unlisted = complete ? Object.keys(state.pending ?? {}).filter((id) => !seen.has(id)) : [];
|
|
309
376
|
const superseded = [...new Set([...diff.seen, ...missing.entries.keys(), ...unlisted])].filter((id) => state.pending !== undefined && Object.hasOwn(state.pending, id));
|
|
310
377
|
if (superseded.length) {
|
|
311
|
-
const remaining =
|
|
378
|
+
const remaining = idMap(state.pending);
|
|
312
379
|
for (const id of superseded)
|
|
313
380
|
delete remaining[id];
|
|
314
381
|
const pre = { ...state };
|
|
@@ -319,15 +386,64 @@ export async function driveObservation(options) {
|
|
|
319
386
|
if (!(await store(pre)))
|
|
320
387
|
break;
|
|
321
388
|
}
|
|
322
|
-
const records =
|
|
389
|
+
const records = idMap();
|
|
323
390
|
for (const change of changes)
|
|
324
391
|
records[change.external_id] = { fields: { ...(change.after ?? change.before ?? {}) } };
|
|
325
392
|
let result;
|
|
326
393
|
try {
|
|
327
|
-
|
|
394
|
+
const commitPage = JSON.parse(JSON.stringify({
|
|
328
395
|
feed: key, provider: bound.policy.provider, observed_at: observedAt, page: receipt.pages + 1, replay: false,
|
|
329
396
|
changes, records, baseline, complete,
|
|
330
397
|
}));
|
|
398
|
+
if (options.prepareCommit) {
|
|
399
|
+
const prepared = await options.prepareCommit(structuredClone(commitPage));
|
|
400
|
+
if (!isJsonData(prepared) || !record(prepared.establishments))
|
|
401
|
+
throw new Error("invalid source preparation");
|
|
402
|
+
const descriptors = JSON.parse(JSON.stringify(prepared.establishments));
|
|
403
|
+
const ids = Object.keys(descriptors);
|
|
404
|
+
if (ids.length > 100)
|
|
405
|
+
throw new Error("source establishment page limit");
|
|
406
|
+
const pending = idMap(state.pending);
|
|
407
|
+
for (const id of ids) {
|
|
408
|
+
const change = byId.get(id), entry = diff.entries.get(id), e = descriptors[id];
|
|
409
|
+
if (!change?.after || !entry || !isSourceEstablishment(e) || e.observed_at !== observedAt)
|
|
410
|
+
throw new Error("invalid source establishment");
|
|
411
|
+
if (e.intent) {
|
|
412
|
+
const fm = parseMarkdown(e.intent.content, e.target).frontmatter;
|
|
413
|
+
if (fm.type !== bound.kind.governs || !Array.isArray(fm.sources) || fm.sources.length !== 1
|
|
414
|
+
|| fm.sources[0]?.resource !== bound.resource || fm.sources[0]?.id !== id)
|
|
415
|
+
throw new Error("invalid source establishment identity");
|
|
416
|
+
}
|
|
417
|
+
pending[id] = { change: structuredClone(change), entry: entryJson(structuredClone(entry)), held_at: observedAt, establishment: e };
|
|
418
|
+
}
|
|
419
|
+
if (qualified && changes.length) {
|
|
420
|
+
for (const change of changes) {
|
|
421
|
+
const id = change.external_id, entry = diff.entries.get(id) ?? missing.entries.get(id);
|
|
422
|
+
if (!entry)
|
|
423
|
+
throw new Error("source pending entry missing");
|
|
424
|
+
pending[id] = { change: structuredClone(change), entry: entryJson(structuredClone(entry)), held_at: observedAt,
|
|
425
|
+
...(Object.hasOwn(descriptors, id) ? { establishment: descriptors[id] } : {}) };
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
if ((qualified ? Object.keys(pending).length : Object.values(pending).filter(p => p.establishment).length) > 100)
|
|
429
|
+
throw new Error("source establishment pending limit");
|
|
430
|
+
if (ids.length || qualified && changes.length) {
|
|
431
|
+
const pre = { ...state, pending, ...(qualified ? { pending_commit: {
|
|
432
|
+
v: 1, order: changes.map(change => change.external_id), page: commitPage.page,
|
|
433
|
+
baseline: commitPage.baseline, complete: commitPage.complete,
|
|
434
|
+
} } : {}) };
|
|
435
|
+
if (new TextEncoder().encode(JSON.stringify(pre)).length > 4194304)
|
|
436
|
+
throw new Error("source establishment envelope limit");
|
|
437
|
+
if (!(await store(pre)))
|
|
438
|
+
return;
|
|
439
|
+
commitPage.establishments = structuredClone(descriptors);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
result = commitResult(await options.commit(commitPage));
|
|
443
|
+
if ((qualified ? changes.map(c => c.external_id) : Object.keys(commitPage.establishments ?? {})).some(id => result.hold.has(id) || result.retry.has(id))) {
|
|
444
|
+
stop = { outcome: "failed", reason: "establishment_pending", retry: true };
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
331
447
|
}
|
|
332
448
|
catch (error) {
|
|
333
449
|
stop = { outcome: "failed", reason: "commit_failed", retry: true, detail: errorText(error) };
|
|
@@ -335,13 +451,15 @@ export async function driveObservation(options) {
|
|
|
335
451
|
}
|
|
336
452
|
const notWritten = (id) => byId.has(id) && (result.hold.has(id) || result.retry.has(id));
|
|
337
453
|
// The page committed: now, and only now, its records and cursor are stored.
|
|
338
|
-
const nextRecords =
|
|
339
|
-
const nextPending =
|
|
454
|
+
const nextRecords = idMap(state.records);
|
|
455
|
+
const nextPending = idMap(state.pending);
|
|
340
456
|
for (const [id, entry] of [...diff.entries, ...missing.entries]) {
|
|
341
457
|
if (byId.has(id) && result.retry.has(id))
|
|
342
458
|
nextPending[id] = { change: byId.get(id), entry: entryJson(entry), held_at: observedAt };
|
|
343
|
-
else if (!notWritten(id))
|
|
459
|
+
else if (!notWritten(id)) {
|
|
344
460
|
nextRecords[id] = entryJson(entry);
|
|
461
|
+
delete nextPending[id];
|
|
462
|
+
}
|
|
345
463
|
}
|
|
346
464
|
const next = {
|
|
347
465
|
...state,
|
|
@@ -356,6 +474,7 @@ export async function driveObservation(options) {
|
|
|
356
474
|
next.pending = nextPending;
|
|
357
475
|
else
|
|
358
476
|
delete next.pending;
|
|
477
|
+
delete next.pending_commit;
|
|
359
478
|
if (!(await store(next)))
|
|
360
479
|
break;
|
|
361
480
|
receipt.pages += 1;
|
|
@@ -385,8 +504,10 @@ export async function driveObservation(options) {
|
|
|
385
504
|
return;
|
|
386
505
|
}
|
|
387
506
|
finally {
|
|
388
|
-
if (stop)
|
|
507
|
+
if (stop) {
|
|
508
|
+
discardSourceTargetConsumer(options.prepareCommit, options.commit);
|
|
389
509
|
options.stop(stop, stopUrl);
|
|
510
|
+
}
|
|
390
511
|
}
|
|
391
512
|
}
|
|
392
513
|
//# sourceMappingURL=driver.js.map
|