@superbee/core 0.2.0-pre.2 → 0.2.0-pre.20
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 +1000 -0
- package/dist/artifact-contract.d.ts +90 -0
- package/dist/artifact-contract.d.ts.map +1 -0
- package/dist/artifact-contract.js +205 -0
- package/dist/artifact-contract.js.map +1 -0
- package/dist/backend.d.ts +19 -1
- package/dist/backend.d.ts.map +1 -1
- package/dist/backend.js +83 -36
- package/dist/backend.js.map +1 -1
- package/dist/blob-contract.d.ts +80 -0
- package/dist/blob-contract.d.ts.map +1 -0
- package/dist/blob-contract.js +131 -0
- package/dist/blob-contract.js.map +1 -0
- package/dist/blob-journal.d.ts +302 -0
- package/dist/blob-journal.d.ts.map +1 -0
- package/dist/blob-journal.js +540 -0
- package/dist/blob-journal.js.map +1 -0
- package/dist/body-replace-guards.d.ts +50 -0
- package/dist/body-replace-guards.d.ts.map +1 -0
- package/dist/body-replace-guards.js +158 -0
- package/dist/body-replace-guards.js.map +1 -0
- package/dist/builtin-recipes/content.d.ts +93 -0
- package/dist/builtin-recipes/content.d.ts.map +1 -0
- package/dist/builtin-recipes/content.js +288 -0
- package/dist/builtin-recipes/content.js.map +1 -0
- package/dist/builtin-recipes.d.ts +10 -0
- package/dist/builtin-recipes.d.ts.map +1 -0
- package/dist/builtin-recipes.js +97 -0
- package/dist/builtin-recipes.js.map +1 -0
- package/dist/bundle-health/index.d.ts +14 -0
- package/dist/bundle-health/index.d.ts.map +1 -0
- package/dist/bundle-health/index.js +12 -0
- package/dist/bundle-health/index.js.map +1 -0
- package/dist/bundle-health/kind-findings.d.ts +44 -0
- package/dist/bundle-health/kind-findings.d.ts.map +1 -0
- package/dist/bundle-health/kind-findings.js +68 -0
- package/dist/bundle-health/kind-findings.js.map +1 -0
- package/dist/bundle-health/legacy-page.d.ts +39 -0
- package/dist/bundle-health/legacy-page.d.ts.map +1 -0
- package/dist/bundle-health/legacy-page.js +50 -0
- package/dist/bundle-health/legacy-page.js.map +1 -0
- package/dist/bundle-health/report.d.ts +202 -0
- package/dist/bundle-health/report.d.ts.map +1 -0
- package/dist/bundle-health/report.js +438 -0
- package/dist/bundle-health/report.js.map +1 -0
- package/dist/bundle-ops.d.ts +1 -1
- package/dist/bundle-ops.d.ts.map +1 -1
- package/dist/bundle-ops.js +2 -2
- package/dist/bundle-ops.js.map +1 -1
- package/dist/bundle.d.ts +2 -1
- package/dist/bundle.d.ts.map +1 -1
- package/dist/bundle.js +3 -3
- package/dist/bundle.js.map +1 -1
- package/dist/code-point-order.d.ts +8 -0
- package/dist/code-point-order.d.ts.map +1 -0
- package/dist/code-point-order.js +20 -0
- package/dist/code-point-order.js.map +1 -0
- package/dist/connectors.d.ts +230 -0
- package/dist/connectors.d.ts.map +1 -0
- package/dist/connectors.js +1150 -0
- package/dist/connectors.js.map +1 -0
- package/dist/cross-bundle.d.ts +135 -0
- package/dist/cross-bundle.d.ts.map +1 -0
- package/dist/cross-bundle.js +186 -0
- package/dist/cross-bundle.js.map +1 -0
- package/dist/dependencies.d.ts +94 -0
- package/dist/dependencies.d.ts.map +1 -0
- package/dist/dependencies.js +180 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/document-codec.d.ts +6 -1
- package/dist/document-codec.d.ts.map +1 -1
- package/dist/document-codec.js +8 -4
- package/dist/document-codec.js.map +1 -1
- package/dist/document-field-actions.d.ts +31 -1
- package/dist/document-field-actions.d.ts.map +1 -1
- package/dist/document-field-actions.js +137 -34
- package/dist/document-field-actions.js.map +1 -1
- package/dist/document-mutation.d.ts +22 -10
- package/dist/document-mutation.d.ts.map +1 -1
- package/dist/document-mutation.js +58 -27
- package/dist/document-mutation.js.map +1 -1
- package/dist/document-write-policy.d.ts.map +1 -1
- package/dist/document-write-policy.js +4 -2
- package/dist/document-write-policy.js.map +1 -1
- package/dist/engine.d.ts +9 -2
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +11 -4
- package/dist/engine.js.map +1 -1
- package/dist/file-journaled-backend-internal.d.ts +21 -0
- package/dist/file-journaled-backend-internal.d.ts.map +1 -0
- package/dist/file-journaled-backend-internal.js +12 -0
- package/dist/file-journaled-backend-internal.js.map +1 -0
- package/dist/file-journaled-backend.d.ts +200 -0
- package/dist/file-journaled-backend.d.ts.map +1 -0
- package/dist/file-journaled-backend.js +1334 -0
- package/dist/file-journaled-backend.js.map +1 -0
- package/dist/filesystem-host.d.ts +15 -0
- package/dist/filesystem-host.d.ts.map +1 -0
- package/dist/filesystem-host.js +20 -0
- package/dist/filesystem-host.js.map +1 -0
- package/dist/filesystem-identity.d.ts +86 -4
- package/dist/filesystem-identity.d.ts.map +1 -1
- package/dist/filesystem-identity.js +338 -102
- package/dist/filesystem-identity.js.map +1 -1
- package/dist/filesystem-lock.d.ts +16 -3
- package/dist/filesystem-lock.d.ts.map +1 -1
- package/dist/filesystem-lock.js +323 -77
- package/dist/filesystem-lock.js.map +1 -1
- package/dist/filesystem-push-role.d.ts +77 -0
- package/dist/filesystem-push-role.d.ts.map +1 -0
- package/dist/filesystem-push-role.js +165 -0
- package/dist/filesystem-push-role.js.map +1 -0
- package/dist/filesystem.d.ts +17 -0
- package/dist/filesystem.d.ts.map +1 -0
- package/dist/filesystem.js +18 -0
- package/dist/filesystem.js.map +1 -0
- package/dist/frontmatter.d.ts +8 -0
- package/dist/frontmatter.d.ts.map +1 -1
- package/dist/frontmatter.js +14 -4
- package/dist/frontmatter.js.map +1 -1
- package/dist/governed-body-write.d.ts +106 -0
- package/dist/governed-body-write.d.ts.map +1 -0
- package/dist/governed-body-write.js +251 -0
- package/dist/governed-body-write.js.map +1 -0
- package/dist/host-policy-snapshot.d.ts +9 -0
- package/dist/host-policy-snapshot.d.ts.map +1 -0
- package/dist/host-policy-snapshot.js +33 -0
- package/dist/host-policy-snapshot.js.map +1 -0
- package/dist/host-text.d.ts +31 -0
- package/dist/host-text.d.ts.map +1 -0
- package/dist/host-text.js +77 -0
- package/dist/host-text.js.map +1 -0
- package/dist/hosted-client/binding.d.ts +7 -0
- package/dist/hosted-client/binding.d.ts.map +1 -0
- package/dist/hosted-client/binding.js +10 -0
- package/dist/hosted-client/binding.js.map +1 -0
- package/dist/hosted-client/blob-delivery.d.ts +67 -0
- package/dist/hosted-client/blob-delivery.d.ts.map +1 -0
- package/dist/hosted-client/blob-delivery.js +169 -0
- package/dist/hosted-client/blob-delivery.js.map +1 -0
- package/dist/hosted-client/blob-write.d.ts +386 -0
- package/dist/hosted-client/blob-write.d.ts.map +1 -0
- package/dist/hosted-client/blob-write.js +770 -0
- package/dist/hosted-client/blob-write.js.map +1 -0
- package/dist/hosted-client/bundle-listing.d.ts +46 -0
- package/dist/hosted-client/bundle-listing.d.ts.map +1 -0
- package/dist/hosted-client/bundle-listing.js +36 -0
- package/dist/hosted-client/bundle-listing.js.map +1 -0
- package/dist/hosted-client/client.d.ts +219 -0
- package/dist/hosted-client/client.d.ts.map +1 -0
- package/dist/hosted-client/client.js +309 -0
- package/dist/hosted-client/client.js.map +1 -0
- package/dist/hosted-client/directory.d.ts +46 -0
- package/dist/hosted-client/directory.d.ts.map +1 -0
- package/dist/hosted-client/directory.js +74 -0
- package/dist/hosted-client/directory.js.map +1 -0
- package/dist/hosted-client/errors.d.ts +26 -0
- package/dist/hosted-client/errors.d.ts.map +1 -0
- package/dist/hosted-client/errors.js +35 -0
- package/dist/hosted-client/errors.js.map +1 -0
- package/dist/hosted-client/inbox.d.ts +320 -0
- package/dist/hosted-client/inbox.d.ts.map +1 -0
- package/dist/hosted-client/inbox.js +379 -0
- package/dist/hosted-client/inbox.js.map +1 -0
- package/dist/hosted-client/index.d.ts +30 -0
- package/dist/hosted-client/index.d.ts.map +1 -0
- package/dist/hosted-client/index.js +32 -0
- package/dist/hosted-client/index.js.map +1 -0
- package/dist/hosted-client/journal.d.ts +103 -0
- package/dist/hosted-client/journal.d.ts.map +1 -0
- package/dist/hosted-client/journal.js +464 -0
- package/dist/hosted-client/journal.js.map +1 -0
- package/dist/hosted-client/node.d.ts +74 -0
- package/dist/hosted-client/node.d.ts.map +1 -0
- package/dist/hosted-client/node.js +219 -0
- package/dist/hosted-client/node.js.map +1 -0
- package/dist/hosted-client/reference.d.ts +12 -0
- package/dist/hosted-client/reference.d.ts.map +1 -0
- package/dist/hosted-client/reference.js +29 -0
- package/dist/hosted-client/reference.js.map +1 -0
- package/dist/hosted-client/write.d.ts +217 -0
- package/dist/hosted-client/write.d.ts.map +1 -0
- package/dist/hosted-client/write.js +418 -0
- package/dist/hosted-client/write.js.map +1 -0
- package/dist/hosted-transport/answer-rows.d.ts +243 -0
- package/dist/hosted-transport/answer-rows.d.ts.map +1 -0
- package/dist/hosted-transport/answer-rows.js +454 -0
- package/dist/hosted-transport/answer-rows.js.map +1 -0
- package/dist/hosted-transport/blob-reads.d.ts +35 -0
- package/dist/hosted-transport/blob-reads.d.ts.map +1 -0
- package/dist/hosted-transport/blob-reads.js +179 -0
- package/dist/hosted-transport/blob-reads.js.map +1 -0
- package/dist/hosted-transport/blob-write.d.ts +34 -0
- package/dist/hosted-transport/blob-write.d.ts.map +1 -0
- package/dist/hosted-transport/blob-write.js +115 -0
- package/dist/hosted-transport/blob-write.js.map +1 -0
- package/dist/hosted-transport/carrier.d.ts +151 -0
- package/dist/hosted-transport/carrier.d.ts.map +1 -0
- package/dist/hosted-transport/carrier.js +260 -0
- package/dist/hosted-transport/carrier.js.map +1 -0
- package/dist/hosted-transport/history-pages.d.ts +55 -0
- package/dist/hosted-transport/history-pages.d.ts.map +1 -0
- package/dist/hosted-transport/history-pages.js +69 -0
- package/dist/hosted-transport/history-pages.js.map +1 -0
- package/dist/hosted-transport/index.d.ts +18 -0
- package/dist/hosted-transport/index.d.ts.map +1 -0
- package/dist/hosted-transport/index.js +18 -0
- package/dist/hosted-transport/index.js.map +1 -0
- package/dist/hosted-transport/operations.d.ts +85 -0
- package/dist/hosted-transport/operations.d.ts.map +1 -0
- package/dist/hosted-transport/operations.js +128 -0
- package/dist/hosted-transport/operations.js.map +1 -0
- package/dist/hosted-transport/paged-reads.d.ts +87 -0
- package/dist/hosted-transport/paged-reads.d.ts.map +1 -0
- package/dist/hosted-transport/paged-reads.js +238 -0
- package/dist/hosted-transport/paged-reads.js.map +1 -0
- package/dist/hosted-transport/read-adapter.d.ts +256 -0
- package/dist/hosted-transport/read-adapter.d.ts.map +1 -0
- package/dist/hosted-transport/read-adapter.js +568 -0
- package/dist/hosted-transport/read-adapter.js.map +1 -0
- package/dist/hosted-transport/root-write.d.ts +114 -0
- package/dist/hosted-transport/root-write.d.ts.map +1 -0
- package/dist/hosted-transport/root-write.js +171 -0
- package/dist/hosted-transport/root-write.js.map +1 -0
- package/dist/hosted-transport/whole-document-transport.d.ts +204 -0
- package/dist/hosted-transport/whole-document-transport.d.ts.map +1 -0
- package/dist/hosted-transport/whole-document-transport.js +447 -0
- package/dist/hosted-transport/whole-document-transport.js.map +1 -0
- package/dist/index.d.ts +34 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -8
- package/dist/index.js.map +1 -1
- package/dist/indexeddb-backend.d.ts +28 -6
- package/dist/indexeddb-backend.d.ts.map +1 -1
- package/dist/indexeddb-backend.js +471 -92
- package/dist/indexeddb-backend.js.map +1 -1
- package/dist/journaled-backend.d.ts +247 -10
- package/dist/journaled-backend.d.ts.map +1 -1
- package/dist/journaled-backend.js +302 -1
- package/dist/journaled-backend.js.map +1 -1
- package/dist/kind-authoring.d.ts +170 -0
- package/dist/kind-authoring.d.ts.map +1 -0
- package/dist/kind-authoring.js +451 -0
- package/dist/kind-authoring.js.map +1 -0
- package/dist/kind-conformance-error.d.ts +15 -0
- package/dist/kind-conformance-error.d.ts.map +1 -0
- package/dist/kind-conformance-error.js +20 -0
- package/dist/kind-conformance-error.js.map +1 -0
- package/dist/kind-coverage.d.ts +99 -0
- package/dist/kind-coverage.d.ts.map +1 -0
- package/dist/kind-coverage.js +186 -0
- package/dist/kind-coverage.js.map +1 -0
- package/dist/kind-field-mutation.d.ts +4 -0
- package/dist/kind-field-mutation.d.ts.map +1 -1
- package/dist/kind-field-mutation.js +28 -3
- package/dist/kind-field-mutation.js.map +1 -1
- package/dist/kinds-load.js +4 -4
- package/dist/kinds-load.js.map +1 -1
- package/dist/kinds.d.ts +65 -2
- package/dist/kinds.d.ts.map +1 -1
- package/dist/kinds.js +341 -21
- package/dist/kinds.js.map +1 -1
- package/dist/link-types.d.ts +26 -0
- package/dist/link-types.d.ts.map +1 -0
- package/dist/link-types.js +57 -0
- package/dist/link-types.js.map +1 -0
- package/dist/links.d.ts +21 -3
- package/dist/links.d.ts.map +1 -1
- package/dist/links.js +213 -14
- package/dist/links.js.map +1 -1
- package/dist/managed-document-metadata.d.ts +2 -0
- package/dist/managed-document-metadata.d.ts.map +1 -0
- package/dist/managed-document-metadata.js +9 -0
- package/dist/managed-document-metadata.js.map +1 -0
- package/dist/memory-backend.d.ts +2 -2
- package/dist/memory-backend.d.ts.map +1 -1
- package/dist/memory-backend.js +26 -11
- package/dist/memory-backend.js.map +1 -1
- package/dist/paths.d.ts +16 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +25 -0
- package/dist/paths.js.map +1 -1
- package/dist/platform.d.ts +13 -2
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +16 -0
- package/dist/platform.js.map +1 -1
- package/dist/portable-export.d.ts +119 -0
- package/dist/portable-export.d.ts.map +1 -0
- package/dist/portable-export.js +501 -0
- package/dist/portable-export.js.map +1 -0
- package/dist/publication-filesystem.d.ts +1 -1
- package/dist/publication-filesystem.d.ts.map +1 -1
- package/dist/publication-filesystem.js +1 -1
- package/dist/publication-filesystem.js.map +1 -1
- package/dist/qualified-links.d.ts +67 -0
- package/dist/qualified-links.d.ts.map +1 -0
- package/dist/qualified-links.js +117 -0
- package/dist/qualified-links.js.map +1 -0
- package/dist/query-filter.d.ts +16 -2
- package/dist/query-filter.d.ts.map +1 -1
- package/dist/query-filter.js +40 -1
- package/dist/query-filter.js.map +1 -1
- package/dist/query-order.d.ts +22 -0
- package/dist/query-order.d.ts.map +1 -0
- package/dist/query-order.js +42 -0
- package/dist/query-order.js.map +1 -0
- package/dist/recipe-lifecycle/errors.d.ts +94 -0
- package/dist/recipe-lifecycle/errors.d.ts.map +1 -0
- package/dist/recipe-lifecycle/errors.js +122 -0
- package/dist/recipe-lifecycle/errors.js.map +1 -0
- package/dist/recipe-lifecycle/evolution.d.ts +75 -0
- package/dist/recipe-lifecycle/evolution.d.ts.map +1 -0
- package/dist/recipe-lifecycle/evolution.js +789 -0
- package/dist/recipe-lifecycle/evolution.js.map +1 -0
- package/dist/recipe-lifecycle/index.d.ts +24 -0
- package/dist/recipe-lifecycle/index.d.ts.map +1 -0
- package/dist/recipe-lifecycle/index.js +20 -0
- package/dist/recipe-lifecycle/index.js.map +1 -0
- package/dist/recipe-lifecycle/install.d.ts +126 -0
- package/dist/recipe-lifecycle/install.d.ts.map +1 -0
- package/dist/recipe-lifecycle/install.js +511 -0
- package/dist/recipe-lifecycle/install.js.map +1 -0
- package/dist/recipe-lifecycle/legacy-aliases.d.ts +16 -0
- package/dist/recipe-lifecycle/legacy-aliases.d.ts.map +1 -0
- package/dist/recipe-lifecycle/legacy-aliases.js +51 -0
- package/dist/recipe-lifecycle/legacy-aliases.js.map +1 -0
- package/dist/recipe-lifecycle/stamp.d.ts +136 -0
- package/dist/recipe-lifecycle/stamp.d.ts.map +1 -0
- package/dist/recipe-lifecycle/stamp.js +326 -0
- package/dist/recipe-lifecycle/stamp.js.map +1 -0
- package/dist/recipes.d.ts +29 -1
- package/dist/recipes.d.ts.map +1 -1
- package/dist/recipes.js +137 -1
- package/dist/recipes.js.map +1 -1
- package/dist/record-overlay/apply.d.ts +43 -0
- package/dist/record-overlay/apply.d.ts.map +1 -0
- package/dist/record-overlay/apply.js +527 -0
- package/dist/record-overlay/apply.js.map +1 -0
- package/dist/record-overlay/canonical.d.ts +22 -0
- package/dist/record-overlay/canonical.d.ts.map +1 -0
- package/dist/record-overlay/canonical.js +47 -0
- package/dist/record-overlay/canonical.js.map +1 -0
- package/dist/record-overlay/digest.d.ts +4 -0
- package/dist/record-overlay/digest.d.ts.map +1 -0
- package/dist/record-overlay/digest.js +11 -0
- package/dist/record-overlay/digest.js.map +1 -0
- package/dist/record-overlay/errors.d.ts +44 -0
- package/dist/record-overlay/errors.d.ts.map +1 -0
- package/dist/record-overlay/errors.js +55 -0
- package/dist/record-overlay/errors.js.map +1 -0
- package/dist/record-overlay/findings.d.ts +5 -0
- package/dist/record-overlay/findings.d.ts.map +1 -0
- package/dist/record-overlay/findings.js +83 -0
- package/dist/record-overlay/findings.js.map +1 -0
- package/dist/record-overlay/index.d.ts +23 -0
- package/dist/record-overlay/index.d.ts.map +1 -0
- package/dist/record-overlay/index.js +21 -0
- package/dist/record-overlay/index.js.map +1 -0
- package/dist/record-overlay/plan.d.ts +12 -0
- package/dist/record-overlay/plan.d.ts.map +1 -0
- package/dist/record-overlay/plan.js +285 -0
- package/dist/record-overlay/plan.js.map +1 -0
- package/dist/record-overlay/policy.d.ts +69 -0
- package/dist/record-overlay/policy.d.ts.map +1 -0
- package/dist/record-overlay/policy.js +228 -0
- package/dist/record-overlay/policy.js.map +1 -0
- package/dist/record-overlay/redact.d.ts +3 -0
- package/dist/record-overlay/redact.d.ts.map +1 -0
- package/dist/record-overlay/redact.js +27 -0
- package/dist/record-overlay/redact.js.map +1 -0
- package/dist/record-overlay/signal-kind.d.ts +30 -0
- package/dist/record-overlay/signal-kind.d.ts.map +1 -0
- package/dist/record-overlay/signal-kind.js +38 -0
- package/dist/record-overlay/signal-kind.js.map +1 -0
- package/dist/record-overlay/signal-text.d.ts +45 -0
- package/dist/record-overlay/signal-text.d.ts.map +1 -0
- package/dist/record-overlay/signal-text.js +116 -0
- package/dist/record-overlay/signal-text.js.map +1 -0
- package/dist/record-overlay/source-index.d.ts +19 -0
- package/dist/record-overlay/source-index.d.ts.map +1 -0
- package/dist/record-overlay/source-index.js +102 -0
- package/dist/record-overlay/source-index.js.map +1 -0
- package/dist/record-overlay/types.d.ts +291 -0
- package/dist/record-overlay/types.d.ts.map +1 -0
- package/dist/record-overlay/types.js +2 -0
- package/dist/record-overlay/types.js.map +1 -0
- package/dist/remote-backend.d.ts +67 -67
- package/dist/remote-backend.d.ts.map +1 -1
- package/dist/remote-backend.js +169 -201
- package/dist/remote-backend.js.map +1 -1
- package/dist/remote-document-codec.d.ts +15 -0
- package/dist/remote-document-codec.d.ts.map +1 -0
- package/dist/remote-document-codec.js +103 -0
- package/dist/remote-document-codec.js.map +1 -0
- package/dist/remote-error.d.ts +38 -0
- package/dist/remote-error.d.ts.map +1 -0
- package/dist/remote-error.js +59 -0
- package/dist/remote-error.js.map +1 -0
- package/dist/remote-operations.d.ts +6 -3
- package/dist/remote-operations.d.ts.map +1 -1
- package/dist/remote-operations.js +23 -5
- package/dist/remote-operations.js.map +1 -1
- package/dist/remote-parsers.d.ts +86 -0
- package/dist/remote-parsers.d.ts.map +1 -0
- package/dist/remote-parsers.js +181 -0
- package/dist/remote-parsers.js.map +1 -0
- package/dist/remote.d.ts +5 -2
- package/dist/remote.d.ts.map +1 -1
- package/dist/remote.js +5 -1
- package/dist/remote.js.map +1 -1
- package/dist/search/backend-source.d.ts +6 -0
- package/dist/search/backend-source.d.ts.map +1 -0
- package/dist/search/backend-source.js +33 -0
- package/dist/search/backend-source.js.map +1 -0
- package/dist/search/contract.d.ts +151 -0
- package/dist/search/contract.d.ts.map +1 -0
- package/dist/search/contract.js +78 -0
- package/dist/search/contract.js.map +1 -0
- package/dist/search/errors.d.ts +30 -0
- package/dist/search/errors.d.ts.map +1 -0
- package/dist/search/errors.js +50 -0
- package/dist/search/errors.js.map +1 -0
- package/dist/search/identity.d.ts +12 -0
- package/dist/search/identity.d.ts.map +1 -0
- package/dist/search/identity.js +90 -0
- package/dist/search/identity.js.map +1 -0
- package/dist/search/index.d.ts +16 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +15 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/memory-source.d.ts +36 -0
- package/dist/search/memory-source.d.ts.map +1 -0
- package/dist/search/memory-source.js +235 -0
- package/dist/search/memory-source.js.map +1 -0
- package/dist/search/rank.d.ts +34 -0
- package/dist/search/rank.d.ts.map +1 -0
- package/dist/search/rank.js +129 -0
- package/dist/search/rank.js.map +1 -0
- package/dist/search/row-text.d.ts +38 -0
- package/dist/search/row-text.d.ts.map +1 -0
- package/dist/search/row-text.js +88 -0
- package/dist/search/row-text.js.map +1 -0
- package/dist/search/search.d.ts +28 -0
- package/dist/search/search.d.ts.map +1 -0
- package/dist/search/search.js +257 -0
- package/dist/search/search.js.map +1 -0
- package/dist/search/source.d.ts +67 -0
- package/dist/search/source.d.ts.map +1 -0
- package/dist/search/source.js +2 -0
- package/dist/search/source.js.map +1 -0
- package/dist/search/text.d.ts +47 -0
- package/dist/search/text.d.ts.map +1 -0
- package/dist/search/text.js +148 -0
- package/dist/search/text.js.map +1 -0
- package/dist/site-capabilities.d.ts +339 -0
- package/dist/site-capabilities.d.ts.map +1 -0
- package/dist/site-capabilities.js +717 -0
- package/dist/site-capabilities.js.map +1 -0
- package/dist/source-engine/guard.d.ts +82 -0
- package/dist/source-engine/guard.d.ts.map +1 -0
- package/dist/source-engine/guard.js +396 -0
- package/dist/source-engine/guard.js.map +1 -0
- package/dist/source-engine/index.d.ts +24 -0
- package/dist/source-engine/index.d.ts.map +1 -0
- package/dist/source-engine/index.js +20 -0
- package/dist/source-engine/index.js.map +1 -0
- package/dist/source-engine/machine-state.d.ts +74 -0
- package/dist/source-engine/machine-state.d.ts.map +1 -0
- package/dist/source-engine/machine-state.js +48 -0
- package/dist/source-engine/machine-state.js.map +1 -0
- package/dist/source-engine/observe.d.ts +18 -0
- package/dist/source-engine/observe.d.ts.map +1 -0
- package/dist/source-engine/observe.js +598 -0
- package/dist/source-engine/observe.js.map +1 -0
- package/dist/source-engine/robots.d.ts +53 -0
- package/dist/source-engine/robots.d.ts.map +1 -0
- package/dist/source-engine/robots.js +158 -0
- package/dist/source-engine/robots.js.map +1 -0
- package/dist/source-engine/types.d.ts +285 -0
- package/dist/source-engine/types.d.ts.map +1 -0
- package/dist/source-engine/types.js +2 -0
- package/dist/source-engine/types.js.map +1 -0
- package/dist/source-harness/conformance.d.ts +16 -0
- package/dist/source-harness/conformance.d.ts.map +1 -0
- package/dist/source-harness/conformance.js +265 -0
- package/dist/source-harness/conformance.js.map +1 -0
- package/dist/source-harness/fixture.d.ts +95 -0
- package/dist/source-harness/fixture.d.ts.map +1 -0
- package/dist/source-harness/fixture.js +261 -0
- package/dist/source-harness/fixture.js.map +1 -0
- package/dist/source-harness/index.d.ts +22 -0
- package/dist/source-harness/index.d.ts.map +1 -0
- package/dist/source-harness/index.js +19 -0
- package/dist/source-harness/index.js.map +1 -0
- package/dist/source-harness/peer.d.ts +74 -0
- package/dist/source-harness/peer.d.ts.map +1 -0
- package/dist/source-harness/peer.js +106 -0
- package/dist/source-harness/peer.js.map +1 -0
- package/dist/storage.d.ts +6 -2
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +4 -1
- package/dist/storage.js.map +1 -1
- package/dist/types.d.ts +33 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/uncertain-write.d.ts +156 -19
- package/dist/uncertain-write.d.ts.map +1 -1
- package/dist/uncertain-write.js +90 -31
- package/dist/uncertain-write.js.map +1 -1
- package/dist/versioning.d.ts +9 -4
- package/dist/versioning.d.ts.map +1 -1
- package/dist/versioning.js +9 -4
- package/dist/versioning.js.map +1 -1
- package/dist/write-identity.d.ts +5 -0
- package/dist/write-identity.d.ts.map +1 -0
- package/dist/write-identity.js +9 -0
- package/dist/write-identity.js.map +1 -0
- package/package.json +94 -2
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
import { resolveContentType } from "./content-type.js";
|
|
33
33
|
import { MalformedDocumentError, parseMarkdown, stringifyDoc } from "./frontmatter.js";
|
|
34
34
|
import { mutationActorFromFrontmatter } from "./mutation-attribution.js";
|
|
35
|
-
import { IntentHoldConflict, IntentStateConflict, } from "./journaled-backend.js";
|
|
35
|
+
import { assertDeletionIntent, deletionIntentRecord, JournalSnapshotConflict, assertJournalGuard, assertJournalIntentChanges, assertJournalMetaChanges, assertMetaWrite, captureJournalGuardOption, captureJournalDeleteOptions, captureJournalWriteOptions, captureIntentUpdate, captureMetaWrite, captureJournalValue, captureRetireAcknowledged, JournalGuardConflict, assertJournalResolutionOptions, assertJournalSnapshot, IntentHoldConflict, IntentStateConflict, } from "./journaled-backend.js";
|
|
36
36
|
import { assertSafeBlobKey, assertSafeConceptId, assertSafeReservedDir, assertSafeReservedFilename, compareStorageKeys, pathFromConceptId } from "./paths.js";
|
|
37
37
|
import { parseLeadingFrontmatter } from "./portable-frontmatter.js";
|
|
38
38
|
import { blobVersion, defaultActor, VersionConflict, versionOfBytes } from "./versioning.js";
|
|
@@ -105,12 +105,31 @@ function editionOf(index) {
|
|
|
105
105
|
throw error;
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* One listing row from a stored record: the frontmatter is what `readWithJournal` parses for
|
|
110
|
+
* the record under `edition` (the split takes the body as a substring it never parses), or
|
|
111
|
+
* `null` with the parser's error when the leading block does not parse.
|
|
112
|
+
*/
|
|
113
|
+
function headOf(record, intents, meta, edition) {
|
|
114
|
+
const head = { id: record.id, version: record.version, updatedBy: record.updatedBy, updatedAt: record.updatedAt, raw: record.raw, intents, meta };
|
|
115
|
+
let frontmatter;
|
|
116
|
+
try {
|
|
117
|
+
frontmatter = parseMarkdown(record.raw, pathFromConceptId(record.id), { okfVersion: edition }).frontmatter;
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
if (!(error instanceof MalformedDocumentError))
|
|
121
|
+
throw error;
|
|
122
|
+
return { ...head, frontmatter: null, malformed: error };
|
|
123
|
+
}
|
|
124
|
+
return { ...head, frontmatter };
|
|
125
|
+
}
|
|
108
126
|
/**
|
|
109
127
|
* A persistent browser-local OKF store implementing the {@link JournaledBackend} contract over
|
|
110
128
|
* IndexedDB. One instance per bundle per JavaScript realm; several instances over the same
|
|
111
129
|
* database name are peers whose conditional writes are serialized by the database.
|
|
112
130
|
*/
|
|
113
131
|
export class IndexedDbBackend {
|
|
132
|
+
journalSnapshotCas = true;
|
|
114
133
|
/**
|
|
115
134
|
* What a resolved write promises: the IndexedDB transaction reported `complete`. Whether the
|
|
116
135
|
* committed pages survive power loss is the browser's and the operating system's decision.
|
|
@@ -251,9 +270,47 @@ export class IndexedDbBackend {
|
|
|
251
270
|
* report the transaction's AbortError and the cause would be lost.
|
|
252
271
|
*/
|
|
253
272
|
async #transact(stores, mode, body) {
|
|
254
|
-
|
|
273
|
+
// Starting a transaction throws synchronously on a handle closed between the open resolving
|
|
274
|
+
// and this line, which is what a `close()` issued in the same turn as an in-flight call
|
|
275
|
+
// produces. `close()` promises that the next operation reopens lazily, and the cold path gets
|
|
276
|
+
// that for free by joining the next open; this is the warm equivalent. Retrying is safe here
|
|
277
|
+
// and only here: the throw means no transaction exists, so nothing was attempted and the
|
|
278
|
+
// retry cannot repeat work. A second failure is the host's own answer and propagates, which
|
|
279
|
+
// is also what a genuinely bad store name does after one wasted reopen.
|
|
280
|
+
let db = await this.#open();
|
|
281
|
+
let transaction;
|
|
282
|
+
try {
|
|
283
|
+
transaction = db.transaction(stores, mode);
|
|
284
|
+
}
|
|
285
|
+
catch (firstFailure) {
|
|
286
|
+
if (this.#db === db)
|
|
287
|
+
this.close();
|
|
288
|
+
db = await this.#open();
|
|
289
|
+
try {
|
|
290
|
+
transaction = db.transaction(stores, mode);
|
|
291
|
+
}
|
|
292
|
+
catch (retryFailure) {
|
|
293
|
+
// The retry's failure is what the caller acts on. When the two differ the first one was
|
|
294
|
+
// never about a closed handle, so it is the more informative of the pair and is kept as
|
|
295
|
+
// the cause rather than discarded.
|
|
296
|
+
const failure = asError(retryFailure);
|
|
297
|
+
if (failure !== firstFailure && failure.cause == null) {
|
|
298
|
+
// Attaching a cause is a convenience and is never worth replacing the host's own error.
|
|
299
|
+
// This error belongs to the host, which may hand back a frozen one or one whose `cause`
|
|
300
|
+
// is a getter; assigning to either throws in strict mode, and that TypeError would reach
|
|
301
|
+
// the caller in place of the real failure.
|
|
302
|
+
try {
|
|
303
|
+
failure.cause = firstFailure;
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
// Surface the host's error exactly as it came.
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
throw failure;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
255
312
|
return new Promise((resolve, reject) => {
|
|
256
|
-
const tx =
|
|
313
|
+
const tx = transaction;
|
|
257
314
|
let result = null;
|
|
258
315
|
let failure = null;
|
|
259
316
|
tx.oncomplete = () => {
|
|
@@ -481,6 +538,54 @@ export class IndexedDbBackend {
|
|
|
481
538
|
// pending-change record and no record exists for an edit that never committed. Settling an
|
|
482
539
|
// intent is a compare-and-swap on the intent's own `state`, so a stale realm cannot settle
|
|
483
540
|
// an intent another realm already settled.
|
|
541
|
+
/**
|
|
542
|
+
* Remove acknowledged intents of one target and named meta rows in one transaction, after
|
|
543
|
+
* comparing the target's full guard in that same transaction.
|
|
544
|
+
*/
|
|
545
|
+
async retireAcknowledged(target, options) {
|
|
546
|
+
assertSafeConceptId(target);
|
|
547
|
+
const { guard: expected, requestIds, removeMeta } = captureRetireAcknowledged(target, options);
|
|
548
|
+
await this.#transact([DOCUMENTS, INTENTS, META], "readwrite", (tx, done, fail, guard) => {
|
|
549
|
+
this.#checkJournalGuard(tx, expected, () => {
|
|
550
|
+
for (const requestId of requestIds) {
|
|
551
|
+
const removal = tx.objectStore(INTENTS).delete(requestId);
|
|
552
|
+
removal.onerror = () => fail(requestError(removal, `IndexedDB intent retirement failed for '${requestId}'`));
|
|
553
|
+
}
|
|
554
|
+
for (const key of removeMeta ?? []) {
|
|
555
|
+
const removal = tx.objectStore(META).delete(key);
|
|
556
|
+
removal.onerror = () => fail(requestError(removal, `IndexedDB meta delete failed for '${key}'`));
|
|
557
|
+
}
|
|
558
|
+
done(undefined);
|
|
559
|
+
}, fail, guard);
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
/** Read and compare a complete guard inside its caller's still-active transaction. */
|
|
563
|
+
#checkJournalGuard(tx, expected, next, fail, guard) {
|
|
564
|
+
if (expected === undefined) {
|
|
565
|
+
next();
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
const current = { target: expected.target, document: null, intents: [], meta: [] };
|
|
569
|
+
let pending = 2 + expected.meta.length;
|
|
570
|
+
const finish = () => { if (--pending === 0) {
|
|
571
|
+
assertJournalGuard(expected, current);
|
|
572
|
+
next();
|
|
573
|
+
} };
|
|
574
|
+
const read = (request, accept) => {
|
|
575
|
+
request.onerror = () => fail(requestError(request, "IndexedDB journal guard read failed"));
|
|
576
|
+
request.onsuccess = guard(() => { accept(request.result); finish(); });
|
|
577
|
+
};
|
|
578
|
+
read(tx.objectStore(DOCUMENTS).get(expected.target), value => {
|
|
579
|
+
const row = value;
|
|
580
|
+
current.document = row ? { version: row.version, raw: row.raw } : null;
|
|
581
|
+
});
|
|
582
|
+
read(tx.objectStore(INTENTS).getAll(), value => { current.intents = value.filter(row => row.target === expected.target); });
|
|
583
|
+
for (const entry of expected.meta)
|
|
584
|
+
read(tx.objectStore(META).get(entry.key), value => {
|
|
585
|
+
const row = value;
|
|
586
|
+
current.meta.push({ key: entry.key, expected: row === undefined ? { present: false } : { present: true, value: row.value } });
|
|
587
|
+
});
|
|
588
|
+
}
|
|
484
589
|
/**
|
|
485
590
|
* One transaction over documents, intents, and meta: the document compare-and-swap of
|
|
486
591
|
* {@link write}, plus (optionally) deleting a superseded intent, recording a new intent for
|
|
@@ -491,14 +596,25 @@ export class IndexedDbBackend {
|
|
|
491
596
|
* {@link IntentHoldConflict} before the document is touched.
|
|
492
597
|
*/
|
|
493
598
|
async writeJournaled(id, doc, options = {}) {
|
|
599
|
+
const snapshotGuard = captureJournalGuardOption(options, id);
|
|
600
|
+
if (snapshotGuard !== undefined) {
|
|
601
|
+
options = captureJournalWriteOptions(options);
|
|
602
|
+
doc = captureJournalValue(doc);
|
|
603
|
+
}
|
|
494
604
|
assertSafeConceptId(id);
|
|
605
|
+
assertJournalResolutionOptions(id, options);
|
|
495
606
|
const raw = stringifyDoc(doc.frontmatter, doc.body ?? "");
|
|
496
607
|
const version = versionOfBytes(raw);
|
|
608
|
+
if (snapshotGuard && (doc.id !== id || (options.intent && options.intent.target !== id)))
|
|
609
|
+
throw new JournalGuardConflict(id);
|
|
610
|
+
const suppliedMeta = typeof options.meta === "function" ? options.meta({ version, raw }) : options.meta;
|
|
611
|
+
assertJournalMetaChanges(snapshotGuard, suppliedMeta ?? [], options.removeMeta);
|
|
612
|
+
options = structuredClone({ ...options, meta: suppliedMeta, ...(snapshotGuard ? { guard: snapshotGuard } : {}) });
|
|
497
613
|
const updatedBy = options.actor?.trim() || defaultActor();
|
|
498
614
|
const now = new Date().toISOString();
|
|
499
615
|
const expected = options.expectedVersion;
|
|
500
616
|
const { intent, supersede, requireSettled } = options;
|
|
501
|
-
const meta =
|
|
617
|
+
const meta = options.meta;
|
|
502
618
|
return this.#transact([DOCUMENTS, INTENTS, META], "readwrite", (tx, done, fail, guard) => {
|
|
503
619
|
const documents = tx.objectStore(DOCUMENTS);
|
|
504
620
|
const intents = tx.objectStore(INTENTS);
|
|
@@ -512,6 +628,10 @@ export class IndexedDbBackend {
|
|
|
512
628
|
const put = metaStore.put(row);
|
|
513
629
|
put.onerror = () => fail(requestError(put, `IndexedDB meta write failed for '${row.key}'`));
|
|
514
630
|
}
|
|
631
|
+
for (const key of options.removeMeta ?? []) {
|
|
632
|
+
const remove = metaStore.delete(key);
|
|
633
|
+
remove.onerror = () => fail(requestError(remove, `IndexedDB meta delete failed for '${key}'`));
|
|
634
|
+
}
|
|
515
635
|
};
|
|
516
636
|
const recordIntent = () => {
|
|
517
637
|
if (!intent) {
|
|
@@ -568,20 +688,55 @@ export class IndexedDbBackend {
|
|
|
568
688
|
removeSuperseded();
|
|
569
689
|
});
|
|
570
690
|
};
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
691
|
+
const apply = () => {
|
|
692
|
+
if (options.resolveIntents) {
|
|
693
|
+
request(intents.getAll(), "resolution snapshot", (rows) => {
|
|
694
|
+
assertJournalSnapshot(id, options.resolveIntents.expected, rows, intent?.requestId);
|
|
695
|
+
for (const row of options.resolveIntents.expected) {
|
|
696
|
+
const removal = intents.delete(row.requestId);
|
|
697
|
+
removal.onerror = () => fail(requestError(removal, "IndexedDB resolution delete failed"));
|
|
698
|
+
}
|
|
699
|
+
writeDocument();
|
|
700
|
+
});
|
|
581
701
|
return;
|
|
582
702
|
}
|
|
583
|
-
|
|
584
|
-
|
|
703
|
+
if (!requireSettled) {
|
|
704
|
+
writeDocument();
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
// The journal has no target index; this scan shares the write's transaction.
|
|
708
|
+
request(intents.getAll(), "intent scan", (rows) => {
|
|
709
|
+
const holder = rows.find((row) => row.target === id && row.state !== "acknowledged");
|
|
710
|
+
if (holder) {
|
|
711
|
+
fail(new IntentHoldConflict(id, holder.requestId, holder.state));
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
writeDocument();
|
|
715
|
+
});
|
|
716
|
+
};
|
|
717
|
+
const checkIdentities = () => {
|
|
718
|
+
if (!snapshotGuard) {
|
|
719
|
+
apply();
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
const checkSuperseded = (existingIdentity) => {
|
|
723
|
+
if (!supersede) {
|
|
724
|
+
assertJournalIntentChanges(snapshotGuard, existingIdentity, undefined);
|
|
725
|
+
apply();
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
request(intents.get(supersede.requestId), "superseded identity read", row => {
|
|
729
|
+
assertJournalIntentChanges(snapshotGuard, existingIdentity, row);
|
|
730
|
+
apply();
|
|
731
|
+
});
|
|
732
|
+
};
|
|
733
|
+
if (!intent) {
|
|
734
|
+
checkSuperseded(undefined);
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
request(intents.get(intent.requestId), "new identity read", row => checkSuperseded(row));
|
|
738
|
+
};
|
|
739
|
+
this.#checkJournalGuard(tx, snapshotGuard, checkIdentities, fail, guard);
|
|
585
740
|
});
|
|
586
741
|
}
|
|
587
742
|
/**
|
|
@@ -594,69 +749,138 @@ export class IndexedDbBackend {
|
|
|
594
749
|
* with `false` even under a compare-and-swap.
|
|
595
750
|
*/
|
|
596
751
|
async deleteJournaled(id, options = {}) {
|
|
752
|
+
options = captureJournalDeleteOptions(id, options);
|
|
597
753
|
assertSafeConceptId(id);
|
|
754
|
+
assertJournalResolutionOptions(id, options);
|
|
755
|
+
assertDeletionIntent(id, options);
|
|
598
756
|
const expected = options.expectedVersion;
|
|
599
757
|
const { requireSettled, onHeld } = options;
|
|
600
758
|
const puts = options.meta ?? [];
|
|
601
759
|
const removals = options.removeMeta ?? [];
|
|
760
|
+
const intent = options.intent ? structuredClone(options.intent) : undefined;
|
|
761
|
+
const supersede = options.supersede ? { ...options.supersede } : undefined;
|
|
762
|
+
const now = new Date().toISOString();
|
|
602
763
|
return this.#transact([DOCUMENTS, INTENTS, META], "readwrite", (tx, done, fail, guard) => {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
const
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
};
|
|
616
|
-
const applyMeta = () => {
|
|
617
|
-
putMeta(puts);
|
|
618
|
-
for (const key of removals) {
|
|
619
|
-
const removal = metaStore.delete(key);
|
|
620
|
-
removal.onerror = () => fail(requestError(removal, `IndexedDB meta delete failed for '${key}'`));
|
|
621
|
-
}
|
|
622
|
-
};
|
|
623
|
-
const deleteDocument = () => {
|
|
624
|
-
request(documents.get(id), "read", (current) => {
|
|
625
|
-
const record = current;
|
|
626
|
-
if (!record) {
|
|
627
|
-
applyMeta();
|
|
628
|
-
done({ outcome: "absent" });
|
|
629
|
-
return;
|
|
764
|
+
this.#checkJournalGuard(tx, options.guard, () => {
|
|
765
|
+
const documents = tx.objectStore(DOCUMENTS);
|
|
766
|
+
const intents = tx.objectStore(INTENTS);
|
|
767
|
+
const metaStore = tx.objectStore(META);
|
|
768
|
+
const request = (req, label, next) => {
|
|
769
|
+
req.onerror = () => fail(requestError(req, `IndexedDB ${label} failed for '${id}'`));
|
|
770
|
+
req.onsuccess = guard(() => next(req.result));
|
|
771
|
+
};
|
|
772
|
+
const putMeta = (rows) => {
|
|
773
|
+
for (const row of rows) {
|
|
774
|
+
const put = metaStore.put(row);
|
|
775
|
+
put.onerror = () => fail(requestError(put, `IndexedDB meta write failed for '${row.key}'`));
|
|
630
776
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
777
|
+
};
|
|
778
|
+
const applyMeta = () => {
|
|
779
|
+
putMeta(puts);
|
|
780
|
+
for (const key of removals) {
|
|
781
|
+
const removal = metaStore.delete(key);
|
|
782
|
+
removal.onerror = () => fail(requestError(removal, `IndexedDB meta delete failed for '${key}'`));
|
|
634
783
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
784
|
+
};
|
|
785
|
+
// The superseded intent and the recorded deletion intent, in the same transaction as the
|
|
786
|
+
// deletion and its meta rows, as `writeJournaled` records a write's.
|
|
787
|
+
const journal = (outcome) => {
|
|
788
|
+
const record = (sequence) => {
|
|
789
|
+
if (!intent) {
|
|
790
|
+
applyMeta();
|
|
791
|
+
done({ outcome });
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
const row = deletionIntentRecord(intent, sequence, now);
|
|
795
|
+
const counter = metaStore.put({ key: INTENT_SEQUENCE_KEY, value: sequence });
|
|
796
|
+
counter.onerror = () => fail(requestError(counter, "IndexedDB sequence write failed"));
|
|
797
|
+
const put = intents.put(row);
|
|
798
|
+
put.onerror = () => fail(requestError(put, `IndexedDB intent write failed for '${row.requestId}'`));
|
|
799
|
+
applyMeta();
|
|
800
|
+
done({ outcome, intent: row });
|
|
801
|
+
};
|
|
802
|
+
const next = () => {
|
|
803
|
+
if (!intent) {
|
|
804
|
+
record(0);
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
request(intents.get(intent.requestId), "intent read", (taken) => {
|
|
808
|
+
if (taken !== undefined) {
|
|
809
|
+
fail(new JournalSnapshotConflict(id));
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
request(metaStore.get(INTENT_SEQUENCE_KEY), "sequence read", (current) => {
|
|
813
|
+
const previous = current?.value;
|
|
814
|
+
record((typeof previous === "number" ? previous : 0) + 1);
|
|
815
|
+
});
|
|
816
|
+
});
|
|
817
|
+
};
|
|
818
|
+
if (!supersede) {
|
|
819
|
+
next();
|
|
652
820
|
return;
|
|
653
821
|
}
|
|
654
|
-
|
|
655
|
-
|
|
822
|
+
request(intents.get(supersede.requestId), "intent read", (current) => {
|
|
823
|
+
const existing = current;
|
|
824
|
+
if (!existing || existing.target !== id || existing.state !== supersede.expectedState || existing.attempts !== supersede.expectedAttempts) {
|
|
825
|
+
fail(new IntentStateConflict(supersede.requestId, supersede.expectedState, existing?.state ?? null));
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
const removal = intents.delete(supersede.requestId);
|
|
829
|
+
removal.onerror = () => fail(requestError(removal, `IndexedDB intent delete failed for '${supersede.requestId}'`));
|
|
830
|
+
next();
|
|
831
|
+
});
|
|
832
|
+
};
|
|
833
|
+
const deleteDocument = () => {
|
|
834
|
+
request(documents.get(id), "read", (current) => {
|
|
835
|
+
const record = current;
|
|
836
|
+
if (options.resolveIntents && expected !== (record?.version ?? null)) {
|
|
837
|
+
fail(new VersionConflict(id, expected, record?.version ?? null));
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
if (!record) {
|
|
841
|
+
journal("absent");
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
if (expected !== undefined && expected !== record.version) {
|
|
845
|
+
fail(new VersionConflict(id, expected, record.version));
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
const removal = documents.delete(id);
|
|
849
|
+
removal.onerror = () => fail(requestError(removal, `IndexedDB delete failed for '${id}'`));
|
|
850
|
+
journal("deleted");
|
|
851
|
+
});
|
|
852
|
+
};
|
|
853
|
+
if (options.resolveIntents) {
|
|
854
|
+
request(intents.getAll(), "resolution snapshot", (rows) => {
|
|
855
|
+
assertJournalSnapshot(id, options.resolveIntents.expected, rows, intent?.requestId);
|
|
856
|
+
for (const row of options.resolveIntents.expected) {
|
|
857
|
+
const removal = intents.delete(row.requestId);
|
|
858
|
+
removal.onerror = () => fail(requestError(removal, "IndexedDB resolution delete failed"));
|
|
859
|
+
}
|
|
860
|
+
deleteDocument();
|
|
861
|
+
});
|
|
656
862
|
return;
|
|
657
863
|
}
|
|
658
|
-
|
|
659
|
-
|
|
864
|
+
if (!requireSettled) {
|
|
865
|
+
deleteDocument();
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
// The same in-transaction hold scan as `writeJournaled`: the answer holds for the deletion
|
|
869
|
+
// that follows, and for the `onHeld` rows put in its place.
|
|
870
|
+
request(intents.getAll(), "intent scan", (rows) => {
|
|
871
|
+
const holder = rows.find((row) => row.target === id && row.state !== "acknowledged");
|
|
872
|
+
if (holder) {
|
|
873
|
+
if (!onHeld) {
|
|
874
|
+
fail(new IntentHoldConflict(id, holder.requestId, holder.state));
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
putMeta(onHeld.meta);
|
|
878
|
+
done({ outcome: "held", requestId: holder.requestId, state: holder.state });
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
deleteDocument();
|
|
882
|
+
});
|
|
883
|
+
}, fail, guard);
|
|
660
884
|
});
|
|
661
885
|
}
|
|
662
886
|
/**
|
|
@@ -712,6 +936,132 @@ export class IndexedDbBackend {
|
|
|
712
936
|
const { frontmatter, body } = parseMarkdown(record.raw, pathFromConceptId(id), { okfVersion: editionOf(index) });
|
|
713
937
|
return { document: { doc: { id, frontmatter, body }, version: record.version }, raw: record.raw, intents: rows, meta };
|
|
714
938
|
}
|
|
939
|
+
/**
|
|
940
|
+
* Every document's head with its intents and the meta rows named for it, from ONE readonly
|
|
941
|
+
* transaction over documents, reserved, intents, and meta: {@link readWithJournal} over the
|
|
942
|
+
* whole store. The root index, the journal (grouped by target, since it has no index by
|
|
943
|
+
* target) and the `shared` keys are read once, then the documents are walked by cursor, each
|
|
944
|
+
* row's own keys read with it, so a caller's `project` sees one record at a time and the
|
|
945
|
+
* listing holds only what it keeps plus the journal it read up front, intents' content
|
|
946
|
+
* included. The frontmatter is the one `readWithJournal` would parse
|
|
947
|
+
* for the record, under the edition the root index declared at this moment; the body is
|
|
948
|
+
* never parsed. Rows come back in `list` order.
|
|
949
|
+
*/
|
|
950
|
+
async readHeads(options = {}) {
|
|
951
|
+
const keysOf = options.meta ?? (() => []);
|
|
952
|
+
const sharedKeys = [...new Set(options.shared ?? [])];
|
|
953
|
+
const project = options.project ?? ((head) => head);
|
|
954
|
+
const rows = await this.#transact([DOCUMENTS, RESERVED, INTENTS, META], "readonly", (tx, done, fail, guard) => {
|
|
955
|
+
const out = [];
|
|
956
|
+
let edition;
|
|
957
|
+
const byTarget = new Map();
|
|
958
|
+
const shared = new Map();
|
|
959
|
+
// Rows still being assembled, plus one for the cursor walk itself; the listing is done
|
|
960
|
+
// when the walk has ended and every row's meta reads have landed.
|
|
961
|
+
let outstanding = 1;
|
|
962
|
+
const finish = () => {
|
|
963
|
+
if (--outstanding === 0)
|
|
964
|
+
done(out);
|
|
965
|
+
};
|
|
966
|
+
// A parse or projection failure aborts the transaction through `fail`; after it no
|
|
967
|
+
// request is placed and no request's own error is reported, so the caller's error is
|
|
968
|
+
// the rejection, not the aborted transaction's refusal of the requests still in flight.
|
|
969
|
+
let stopped = false;
|
|
970
|
+
const stop = (error) => {
|
|
971
|
+
if (stopped)
|
|
972
|
+
return;
|
|
973
|
+
stopped = true;
|
|
974
|
+
fail(error);
|
|
975
|
+
};
|
|
976
|
+
const metaStore = tx.objectStore(META);
|
|
977
|
+
const readMeta = (key, into, then) => {
|
|
978
|
+
const request = metaStore.get(key);
|
|
979
|
+
request.onerror = () => stop(requestError(request, `IndexedDB meta read failed for '${key}'`));
|
|
980
|
+
request.onsuccess = guard(() => {
|
|
981
|
+
const row = request.result;
|
|
982
|
+
if (row !== undefined)
|
|
983
|
+
into.set(key, row.value);
|
|
984
|
+
then();
|
|
985
|
+
});
|
|
986
|
+
};
|
|
987
|
+
const walk = () => {
|
|
988
|
+
const cursor = tx.objectStore(DOCUMENTS).openCursor();
|
|
989
|
+
cursor.onerror = () => stop(requestError(cursor, "IndexedDB document scan failed"));
|
|
990
|
+
cursor.onsuccess = guard(() => {
|
|
991
|
+
const current = cursor.result;
|
|
992
|
+
if (!current) {
|
|
993
|
+
finish();
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
996
|
+
const record = current.value;
|
|
997
|
+
const intents = byTarget.get(record.id) ?? [];
|
|
998
|
+
const keys = [...new Set(keysOf(record.id, intents))].filter((key) => !shared.has(key) && !sharedKeys.includes(key));
|
|
999
|
+
const meta = new Map(shared);
|
|
1000
|
+
let pending = keys.length;
|
|
1001
|
+
outstanding += 1;
|
|
1002
|
+
const complete = () => {
|
|
1003
|
+
try {
|
|
1004
|
+
out.push({ id: record.id, row: project(headOf(record, intents, meta, edition)) });
|
|
1005
|
+
}
|
|
1006
|
+
catch (error) {
|
|
1007
|
+
stop(asError(error));
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
1010
|
+
finish();
|
|
1011
|
+
};
|
|
1012
|
+
if (pending === 0)
|
|
1013
|
+
complete();
|
|
1014
|
+
else {
|
|
1015
|
+
for (const key of keys) {
|
|
1016
|
+
readMeta(key, meta, () => {
|
|
1017
|
+
if (--pending === 0)
|
|
1018
|
+
complete();
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
if (!stopped)
|
|
1023
|
+
current.continue();
|
|
1024
|
+
});
|
|
1025
|
+
};
|
|
1026
|
+
const readShared = () => {
|
|
1027
|
+
let pending = sharedKeys.length;
|
|
1028
|
+
if (pending === 0) {
|
|
1029
|
+
walk();
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
for (const key of sharedKeys) {
|
|
1033
|
+
readMeta(key, shared, () => {
|
|
1034
|
+
if (--pending === 0)
|
|
1035
|
+
walk();
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
};
|
|
1039
|
+
// The index, the journal and the shared rows land before the walk starts, so every row
|
|
1040
|
+
// is built under one edition and sees its whole journal, whatever order the host
|
|
1041
|
+
// answers requests in.
|
|
1042
|
+
const rootIndex = tx.objectStore(RESERVED).get(reservedKey("", "index.md"));
|
|
1043
|
+
rootIndex.onerror = () => stop(requestError(rootIndex, "IndexedDB root index read failed"));
|
|
1044
|
+
rootIndex.onsuccess = guard(() => {
|
|
1045
|
+
edition = editionOf(rootIndex.result);
|
|
1046
|
+
const scan = tx.objectStore(INTENTS).getAll();
|
|
1047
|
+
scan.onerror = () => stop(requestError(scan, "IndexedDB journal scan failed"));
|
|
1048
|
+
scan.onsuccess = guard(() => {
|
|
1049
|
+
for (const row of scan.result) {
|
|
1050
|
+
const list = byTarget.get(row.target);
|
|
1051
|
+
if (list)
|
|
1052
|
+
list.push(row);
|
|
1053
|
+
else
|
|
1054
|
+
byTarget.set(row.target, [row]);
|
|
1055
|
+
}
|
|
1056
|
+
for (const list of byTarget.values())
|
|
1057
|
+
list.sort((a, b) => a.sequence - b.sequence);
|
|
1058
|
+
readShared();
|
|
1059
|
+
});
|
|
1060
|
+
});
|
|
1061
|
+
});
|
|
1062
|
+
rows.sort((a, b) => compareStorageKeys(a.id, b.id));
|
|
1063
|
+
return rows.map((entry) => entry.row);
|
|
1064
|
+
}
|
|
715
1065
|
/** Intents in local commit order, optionally restricted to one or more states. */
|
|
716
1066
|
async listIntents(state) {
|
|
717
1067
|
const wanted = state === undefined ? null : new Set(typeof state === "string" ? [state] : state);
|
|
@@ -732,38 +1082,67 @@ export class IndexedDbBackend {
|
|
|
732
1082
|
* missing record rejects with {@link IntentStateConflict} and writes nothing.
|
|
733
1083
|
*/
|
|
734
1084
|
async updateIntent(requestId, expectedState, patch, options = {}) {
|
|
1085
|
+
({ patch, options } = captureIntentUpdate(patch, options));
|
|
735
1086
|
const now = new Date().toISOString();
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
const
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
const
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
1087
|
+
const raw = options.document ? stringifyDoc(options.document.frontmatter, options.document.body ?? "") : undefined;
|
|
1088
|
+
const replacement = raw === undefined ? undefined : { id: options.document.id, raw, version: versionOfBytes(raw), updatedBy: defaultActor(), updatedAt: now };
|
|
1089
|
+
return this.#transact([DOCUMENTS, INTENTS, META], "readwrite", (tx, done, fail, guard) => {
|
|
1090
|
+
this.#checkJournalGuard(tx, options.guard, () => {
|
|
1091
|
+
const intents = tx.objectStore(INTENTS);
|
|
1092
|
+
const read = intents.get(requestId);
|
|
1093
|
+
read.onerror = () => fail(requestError(read, `IndexedDB intent read failed for '${requestId}'`));
|
|
1094
|
+
read.onsuccess = guard(() => {
|
|
1095
|
+
const current = read.result;
|
|
1096
|
+
if (!current || current.state !== expectedState) {
|
|
1097
|
+
fail(new IntentStateConflict(requestId, expectedState, current?.state ?? null));
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
if (options.guard && current.target !== options.guard.target)
|
|
1101
|
+
throw new JournalGuardConflict(current.target);
|
|
1102
|
+
const next = { ...current, ...patch, requestId, sequence: current.sequence, updatedAt: now };
|
|
1103
|
+
if (replacement) {
|
|
1104
|
+
const write = tx.objectStore(DOCUMENTS).put(replacement);
|
|
1105
|
+
write.onerror = () => fail(requestError(write, "IndexedDB replacement write failed"));
|
|
1106
|
+
}
|
|
1107
|
+
const put = intents.put(next);
|
|
1108
|
+
put.onerror = () => fail(requestError(put, `IndexedDB intent write failed for '${requestId}'`));
|
|
1109
|
+
const metaStore = tx.objectStore(META);
|
|
1110
|
+
for (const row of options.meta ?? []) {
|
|
1111
|
+
const metaPut = metaStore.put(row);
|
|
1112
|
+
metaPut.onerror = () => fail(requestError(metaPut, `IndexedDB meta write failed for '${row.key}'`));
|
|
1113
|
+
}
|
|
1114
|
+
done(next);
|
|
1115
|
+
});
|
|
1116
|
+
}, fail, guard);
|
|
756
1117
|
});
|
|
757
1118
|
}
|
|
758
1119
|
async readMeta(key) {
|
|
759
1120
|
const row = await this.#getOne(META, key);
|
|
760
1121
|
return row === undefined ? undefined : row.value;
|
|
761
1122
|
}
|
|
762
|
-
async writeMeta(key, value) {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
1123
|
+
async writeMeta(key, value, options = {}) {
|
|
1124
|
+
options = captureMetaWrite(options);
|
|
1125
|
+
value = options.expected !== undefined || options.requireEmptyJournal ? captureJournalValue(value) : structuredClone(value);
|
|
1126
|
+
await this.#transact([INTENTS, META], "readwrite", (tx, done, fail, guard) => {
|
|
1127
|
+
const meta = tx.objectStore(META);
|
|
1128
|
+
const read = meta.get(key);
|
|
1129
|
+
read.onerror = () => fail(requestError(read, "IndexedDB admission read failed"));
|
|
1130
|
+
read.onsuccess = guard(() => {
|
|
1131
|
+
const row = read.result;
|
|
1132
|
+
const finish = (intents) => {
|
|
1133
|
+
assertMetaWrite(key, options, row === undefined ? { present: false } : { present: true, value: row.value }, intents);
|
|
1134
|
+
const put = meta.put({ key, value });
|
|
1135
|
+
put.onerror = () => fail(requestError(put, `IndexedDB meta write failed for '${key}'`));
|
|
1136
|
+
done(undefined);
|
|
1137
|
+
};
|
|
1138
|
+
if (!options.requireEmptyJournal) {
|
|
1139
|
+
finish([]);
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
const scan = tx.objectStore(INTENTS).getAll();
|
|
1143
|
+
scan.onerror = () => fail(requestError(scan, "IndexedDB admission journal scan failed"));
|
|
1144
|
+
scan.onsuccess = guard(() => finish(scan.result));
|
|
1145
|
+
});
|
|
767
1146
|
});
|
|
768
1147
|
}
|
|
769
1148
|
// ── blobs ──────────────────────────────────────────────────────────────────────────────
|