@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
|
@@ -15,6 +15,15 @@
|
|
|
15
15
|
* entirely between two probes of one observation can be traversed by the operating system
|
|
16
16
|
* during a listing or open, but its bytes can never be returned as EXACT, because the leaf
|
|
17
17
|
* witness at the post-walk must match the entry the requested path reaches.
|
|
18
|
+
* - A bulk read runs its observations inside one {@link ObservationPass}: the same protocol per
|
|
19
|
+
* path, but a directory's listing is taken once and reused while the directory's change
|
|
20
|
+
* witness proves its entry set unchanged, and every EXACT verdict that used a reused listing has
|
|
21
|
+
* its post-walk repeated at the end of the pass without trusting timestamps. Listing the parent
|
|
22
|
+
* per observation would make a pass over a directory of N documents read O(N²) directory
|
|
23
|
+
* entries. The speedup assumes local disks, whose directory times advance on every entry change;
|
|
24
|
+
* on Linux any other filesystem type lists per use, and elsewhere a mount whose times can lie
|
|
25
|
+
* (network or FUSE attribute caches, settable Windows directory times) is covered by the
|
|
26
|
+
* end-of-pass re-verification, short of an inode number reused within the pass.
|
|
18
27
|
* - Mutations hold one cross-process lock keyed by a pure fold of the root and `rel`, decide
|
|
19
28
|
* inside it, create directories one segment at a time with a spelling check, and publish a
|
|
20
29
|
* first-created leaf with `link` so the host's own equivalence refuses a second spelling the
|
|
@@ -37,8 +46,8 @@
|
|
|
37
46
|
* and the root's spelling is folded into the lock key rather than verified.
|
|
38
47
|
*
|
|
39
48
|
* Every filesystem call goes through a {@link FilesystemIdentityPort} passed to the protocol
|
|
40
|
-
* functions. Production
|
|
41
|
-
*
|
|
49
|
+
* functions. Production constructs a Node binding with the backend's captured host policy;
|
|
50
|
+
* the policy supplies classifications, never a replacement identity protocol. Normalizing stores that rewrite names on
|
|
42
51
|
* write (legacy HFS+) are unsupported: an id whose NFD form differs from its own form is written
|
|
43
52
|
* and then refused as an alias on every later observation, never silently aliased.
|
|
44
53
|
*/
|
|
@@ -47,12 +56,12 @@ import path from "node:path";
|
|
|
47
56
|
import { createHash, randomUUID } from "node:crypto";
|
|
48
57
|
import { ConcurrentReplacementError, FilesystemIdentityAliasError, InvalidInputError } from "./errors.js";
|
|
49
58
|
import { acquireFilesystemIdentityLock } from "./filesystem-lock.js";
|
|
50
|
-
|
|
59
|
+
import { captureFilesystemHostPolicy } from "./filesystem-host.js";
|
|
51
60
|
/**
|
|
52
|
-
*
|
|
61
|
+
* A host can transiently deny replacement while another process is closing a read handle or a
|
|
53
62
|
* scanner holds the destination. An in-place rename retry cannot remain bound to the complete
|
|
54
63
|
* parent-and-leaf observation: either can change after any final check. Abort this attempt instead,
|
|
55
|
-
* mapping only
|
|
64
|
+
* mapping only a host-classified replacement conflict to the typed
|
|
56
65
|
* contention signal owned by the higher-level fresh read/decide/CAS loop. Every other platform and
|
|
57
66
|
* errno remains the original immediate failure.
|
|
58
67
|
*/
|
|
@@ -61,8 +70,7 @@ async function replaceExistingLeaf(port, tmp, target, rel) {
|
|
|
61
70
|
await port.rename(tmp, target);
|
|
62
71
|
}
|
|
63
72
|
catch (err) {
|
|
64
|
-
|
|
65
|
-
if ((port.platform ?? process.platform) === "win32" && WINDOWS_REPLACE_CONFLICT_CODES.has(code)) {
|
|
73
|
+
if (port.isReplacementConflict?.(err)) {
|
|
66
74
|
throw new ConcurrentReplacementError(rel, 1, 10);
|
|
67
75
|
}
|
|
68
76
|
throw err;
|
|
@@ -219,6 +227,13 @@ async function probeSegment(port, candidate, rel, segment) {
|
|
|
219
227
|
function hasExact(listing, segment) {
|
|
220
228
|
return listing.some((entry) => entry.name === segment);
|
|
221
229
|
}
|
|
230
|
+
/** One fresh `entries` call per use: the single-read protocol. */
|
|
231
|
+
function freshListings(port) {
|
|
232
|
+
return async (dir) => {
|
|
233
|
+
const listing = await port.entries(dir);
|
|
234
|
+
return listing === null ? null : { has: (name) => hasExact(listing, name) };
|
|
235
|
+
};
|
|
236
|
+
}
|
|
222
237
|
/**
|
|
223
238
|
* M-REALIZE: per segment, root to leaf, it must exist and the parent listing must carry its exact
|
|
224
239
|
* spelling. A listing-only alias decision is sound here because the identity lock is held: no
|
|
@@ -277,15 +292,15 @@ async function recordWalk(port, rootResolved, segments, rel) {
|
|
|
277
292
|
* (`handle` given) applies that leaf table against the handle's inode, probing the leaf
|
|
278
293
|
* unconditionally.
|
|
279
294
|
*/
|
|
280
|
-
async function confirmedWalk(port, rootResolved, segments, rel, recorded, handle) {
|
|
295
|
+
async function confirmedWalk(port, rootResolved, segments, rel, recorded, handle, listings = freshListings(port)) {
|
|
281
296
|
let parent = rootResolved;
|
|
282
297
|
for (let index = 0; index < segments.length; index++) {
|
|
283
298
|
const segment = segments[index];
|
|
284
299
|
const candidate = path.join(parent, segment);
|
|
285
|
-
const listing = await
|
|
300
|
+
const listing = await listings(parent);
|
|
286
301
|
if (listing === null)
|
|
287
302
|
return "absent";
|
|
288
|
-
const listed =
|
|
303
|
+
const listed = listing.has(segment);
|
|
289
304
|
if (handle !== null && index === segments.length - 1) {
|
|
290
305
|
const verdict = classifyLeaf({ listed, probe: await probeSegment(port, candidate, rel, segment), handle });
|
|
291
306
|
if (verdict === "aliased")
|
|
@@ -316,14 +331,17 @@ function countRestart(restarts, rel) {
|
|
|
316
331
|
* from O-PROBE, bounded; the handle is closed before any restart opens another.
|
|
317
332
|
*/
|
|
318
333
|
export async function observeExact(port, root, rel, read) {
|
|
334
|
+
return observeWith(port, path.resolve(root), rel, read, freshListings(port));
|
|
335
|
+
}
|
|
336
|
+
/** The observation protocol of {@link observeExact}, with the parent listings drawn from `listings`. */
|
|
337
|
+
async function observeWith(port, rootResolved, rel, read, listings, onExact) {
|
|
319
338
|
const segments = relSegments(rel);
|
|
320
|
-
const rootResolved = path.resolve(root);
|
|
321
339
|
const target = path.join(rootResolved, ...segments);
|
|
322
340
|
for (let restarts = 0;;) {
|
|
323
341
|
const recorded = await recordWalk(port, rootResolved, segments, rel);
|
|
324
342
|
if (recorded === null)
|
|
325
343
|
return { state: "absent" };
|
|
326
|
-
const verified = await confirmedWalk(port, rootResolved, segments, rel, recorded, null);
|
|
344
|
+
const verified = await confirmedWalk(port, rootResolved, segments, rel, recorded, null, listings);
|
|
327
345
|
if (verified === "absent")
|
|
328
346
|
return { state: "absent" };
|
|
329
347
|
if (verified === "restart") {
|
|
@@ -337,10 +355,9 @@ export async function observeExact(port, root, rel, read) {
|
|
|
337
355
|
catch (err) {
|
|
338
356
|
if (isAbsentPathError(err))
|
|
339
357
|
return { state: "absent" };
|
|
340
|
-
//
|
|
341
|
-
// an uncertain generation, not a durable permission verdict; re-run the witnessed walk and
|
|
358
|
+
// A host-classified transient open failure reports an uncertain generation; re-run the witnessed walk and
|
|
342
359
|
// let the existing bound turn persistent contention into ConcurrentReplacementError.
|
|
343
|
-
if (
|
|
360
|
+
if (port.isTransientOpenError?.(err)) {
|
|
344
361
|
restarts = countRestart(restarts, rel);
|
|
345
362
|
continue;
|
|
346
363
|
}
|
|
@@ -352,13 +369,15 @@ export async function observeExact(port, root, rel, read) {
|
|
|
352
369
|
value = await read(opened.handle, target);
|
|
353
370
|
if (value === null)
|
|
354
371
|
return { state: "absent" };
|
|
355
|
-
verdict = await confirmedWalk(port, rootResolved, segments, rel, recorded, opened);
|
|
372
|
+
verdict = await confirmedWalk(port, rootResolved, segments, rel, recorded, opened, listings);
|
|
356
373
|
}
|
|
357
374
|
finally {
|
|
358
375
|
await port.close(opened.handle);
|
|
359
376
|
}
|
|
360
|
-
if (verdict === "exact")
|
|
377
|
+
if (verdict === "exact") {
|
|
378
|
+
onExact?.(recorded, { dev: opened.dev, ino: opened.ino });
|
|
361
379
|
return { state: "exact", value };
|
|
380
|
+
}
|
|
362
381
|
if (verdict === "absent")
|
|
363
382
|
return { state: "absent" };
|
|
364
383
|
restarts = countRestart(restarts, rel);
|
|
@@ -385,6 +404,154 @@ export async function probeExact(port, root, rel) {
|
|
|
385
404
|
restarts = countRestart(restarts, rel);
|
|
386
405
|
}
|
|
387
406
|
}
|
|
407
|
+
// ── observation pass ──────────────────────────────────────────────────────────
|
|
408
|
+
/**
|
|
409
|
+
* How long a directory's modification and status-change times must have been still before a
|
|
410
|
+
* listing of it may be reused. A change that lands in the same timestamp tick as the directory's
|
|
411
|
+
* previous change leaves both times unchanged, so a witness is only a change detector once the
|
|
412
|
+
* clock has moved past that tick. Three seconds covers the coarsest supported granularity (FAT's
|
|
413
|
+
* two-second mtime) plus margin; finer clocks (APFS, ext4, NTFS) are covered with room to spare.
|
|
414
|
+
* A time in the future (clock skew) is never settled.
|
|
415
|
+
*/
|
|
416
|
+
const SETTLED_AFTER_NS = 3000000000n;
|
|
417
|
+
function witnessKey(witness) {
|
|
418
|
+
return `${witness.dev}:${witness.ino}:${witness.mtimeNs}:${witness.ctimeNs}`;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Open an {@link ObservationPass} over `(port, root)`.
|
|
422
|
+
*
|
|
423
|
+
* Every observation runs the exact single-read protocol of {@link observeExact} — recorded walk,
|
|
424
|
+
* confirmed pre-walk, open, read, confirmed post-walk with the handle still open, bounded
|
|
425
|
+
* restarts — and differs only in where a walk's parent listing comes from. The first time a
|
|
426
|
+
* directory is needed the pass takes `witness, entries, witness`; when the two witnesses agree and
|
|
427
|
+
* the directory's times have settled, that listing is kept. Each later use re-takes the witness
|
|
428
|
+
* (one `stat`, constant cost) and reuses the kept listing only if the witness is unchanged;
|
|
429
|
+
* otherwise it lists afresh exactly as a single read would.
|
|
430
|
+
*
|
|
431
|
+
* Two independent arguments make a reused listing safe:
|
|
432
|
+
*
|
|
433
|
+
* 1. Timestamps (the fast path is right in the moment). Where a directory's times advance on every
|
|
434
|
+
* entry change — local APFS, HFS+, ext4, XFS, btrfs, NTFS, FAT — an unchanged settled witness
|
|
435
|
+
* means the entry set is the kept listing at the moment of use, so every verdict is the one a
|
|
436
|
+
* single read reaches against the same state.
|
|
437
|
+
* 2. Re-verification (no timestamps trusted). Where the witness can lie — attribute caches on
|
|
438
|
+
* network and FUSE mounts, settable directory times on Windows, a clock stepped backwards — an
|
|
439
|
+
* observation that used a reused listing may be wrong in the moment, so its verdict is not
|
|
440
|
+
* trusted: a refusal or absence reached through a reused listing is re-taken at once by
|
|
441
|
+
* {@link observeExact}, and `finish` repeats the post-walk of every EXACT verdict that used one
|
|
442
|
+
* against fresh listings (one per directory) and fresh probes. Each segment must still be
|
|
443
|
+
* listed under its exact spelling and reach the inode recorded for it, the leaf the inode the
|
|
444
|
+
* bytes were read from; anything else is returned for a fresh single read. Since published
|
|
445
|
+
* bytes are immutable per inode, a verdict that passes is a state of this identity at `finish`.
|
|
446
|
+
* What this cannot see is the read file being deleted and its inode NUMBER reused by a new file
|
|
447
|
+
* under the same spelling within the pass, because the handle is closed by then.
|
|
448
|
+
*
|
|
449
|
+
* On Linux, a mount whose filesystem type is not a known local one (NFS, SMB, FUSE, 9p, ...) gets
|
|
450
|
+
* no directory witness at all, so it lists exactly as single reads do.
|
|
451
|
+
*/
|
|
452
|
+
export function openObservationPass(port, root, now = Date.now) {
|
|
453
|
+
const rootResolved = path.resolve(root);
|
|
454
|
+
const kept = new Map();
|
|
455
|
+
const reusedVerdicts = [];
|
|
456
|
+
const fresh = freshListings(port);
|
|
457
|
+
const witnessOf = port.directoryWitness?.bind(port);
|
|
458
|
+
const settled = (witness) => {
|
|
459
|
+
const nowNs = BigInt(Math.floor(now())) * 1000000n;
|
|
460
|
+
const latest = witness.mtimeNs > witness.ctimeNs ? witness.mtimeNs : witness.ctimeNs;
|
|
461
|
+
return nowNs - latest >= SETTLED_AFTER_NS;
|
|
462
|
+
};
|
|
463
|
+
/** Listings for one observation; `reused()` says whether any came from the kept set. */
|
|
464
|
+
const listingsFor = () => {
|
|
465
|
+
let reused = false;
|
|
466
|
+
if (witnessOf === undefined)
|
|
467
|
+
return { source: fresh, reused: () => false };
|
|
468
|
+
const source = async (dir) => {
|
|
469
|
+
const keep = kept.get(dir);
|
|
470
|
+
if (keep !== undefined) {
|
|
471
|
+
const current = await witnessOf(dir);
|
|
472
|
+
if (current !== null && witnessKey(current) === keep.witness) {
|
|
473
|
+
reused = true;
|
|
474
|
+
return keep.names;
|
|
475
|
+
}
|
|
476
|
+
kept.delete(dir);
|
|
477
|
+
}
|
|
478
|
+
const before = await witnessOf(dir);
|
|
479
|
+
const listing = await port.entries(dir);
|
|
480
|
+
if (listing === null)
|
|
481
|
+
return null;
|
|
482
|
+
const names = new Set(listing.map((entry) => entry.name));
|
|
483
|
+
const after = await witnessOf(dir);
|
|
484
|
+
if (before !== null && after !== null && witnessKey(before) === witnessKey(after) && settled(after)) {
|
|
485
|
+
kept.set(dir, { witness: witnessKey(after), names });
|
|
486
|
+
}
|
|
487
|
+
return names;
|
|
488
|
+
};
|
|
489
|
+
return { source, reused: () => reused };
|
|
490
|
+
};
|
|
491
|
+
return {
|
|
492
|
+
async observe(rel, read) {
|
|
493
|
+
const listings = listingsFor();
|
|
494
|
+
let exact;
|
|
495
|
+
let observed;
|
|
496
|
+
try {
|
|
497
|
+
observed = await observeWith(port, rootResolved, rel, read, listings.source, (recorded, handle) => {
|
|
498
|
+
exact = { rel, segments: relSegments(rel), recorded, handle };
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
catch (error) {
|
|
502
|
+
if (!listings.reused())
|
|
503
|
+
throw error;
|
|
504
|
+
return observeExact(port, rootResolved, rel, read);
|
|
505
|
+
}
|
|
506
|
+
if (!listings.reused())
|
|
507
|
+
return observed;
|
|
508
|
+
if (observed.state === "absent")
|
|
509
|
+
return observeExact(port, rootResolved, rel, read);
|
|
510
|
+
if (exact !== undefined)
|
|
511
|
+
reusedVerdicts.push(exact);
|
|
512
|
+
return observed;
|
|
513
|
+
},
|
|
514
|
+
async finish() {
|
|
515
|
+
const retry = new Set();
|
|
516
|
+
const endListings = new Map();
|
|
517
|
+
const listedAtEnd = async (dir) => {
|
|
518
|
+
if (!endListings.has(dir)) {
|
|
519
|
+
const listing = await port.entries(dir);
|
|
520
|
+
endListings.set(dir, listing === null ? null : new Set(listing.map((entry) => entry.name)));
|
|
521
|
+
}
|
|
522
|
+
return endListings.get(dir);
|
|
523
|
+
};
|
|
524
|
+
try {
|
|
525
|
+
for (const verdict of reusedVerdicts) {
|
|
526
|
+
if (!(await holdsAtEnd(port, rootResolved, verdict, listedAtEnd)))
|
|
527
|
+
retry.add(verdict.rel);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
finally {
|
|
531
|
+
kept.clear();
|
|
532
|
+
reusedVerdicts.length = 0;
|
|
533
|
+
}
|
|
534
|
+
return [...retry];
|
|
535
|
+
},
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
/** The post-walk of one EXACT verdict, repeated against end-of-pass listings and fresh probes. */
|
|
539
|
+
async function holdsAtEnd(port, rootResolved, verdict, listedAtEnd) {
|
|
540
|
+
let parent = rootResolved;
|
|
541
|
+
for (let index = 0; index < verdict.segments.length; index++) {
|
|
542
|
+
const segment = verdict.segments[index];
|
|
543
|
+
const listing = await listedAtEnd(parent);
|
|
544
|
+
if (listing === null || !listing.has(segment))
|
|
545
|
+
return false;
|
|
546
|
+
const candidate = path.join(parent, segment);
|
|
547
|
+
const probed = await port.probe(candidate);
|
|
548
|
+
const expected = index === verdict.segments.length - 1 ? verdict.handle : verdict.recorded[index];
|
|
549
|
+
if (probed === null || probed.kind === "symlink" || !sameWitness(probed, expected))
|
|
550
|
+
return false;
|
|
551
|
+
parent = candidate;
|
|
552
|
+
}
|
|
553
|
+
return true;
|
|
554
|
+
}
|
|
388
555
|
// ── mutation ──────────────────────────────────────────────────────────────────
|
|
389
556
|
/**
|
|
390
557
|
* Roots (resolved) whose filesystem refused a hard link. Learned lazily on the first creation
|
|
@@ -394,7 +561,15 @@ export async function probeExact(port, root, rel) {
|
|
|
394
561
|
* first-creation writers of a host-equated pair the fold misses are not excluded" applies there
|
|
395
562
|
* and only there.
|
|
396
563
|
*/
|
|
397
|
-
const linkUnsupportedRoots = new
|
|
564
|
+
const linkUnsupportedRoots = new WeakMap();
|
|
565
|
+
function unsupportedLinkRoots(port) {
|
|
566
|
+
let roots = linkUnsupportedRoots.get(port);
|
|
567
|
+
if (!roots) {
|
|
568
|
+
roots = new Set();
|
|
569
|
+
linkUnsupportedRoots.set(port, roots);
|
|
570
|
+
}
|
|
571
|
+
return roots;
|
|
572
|
+
}
|
|
398
573
|
/**
|
|
399
574
|
* Process-local queue per identity key, shared by every `FilesystemBackend` instance: the
|
|
400
575
|
* engine constructs a fresh adapter per bundle operation, so an instance-level map would
|
|
@@ -508,7 +683,7 @@ async function createExactLeaf(port, tmp, target, rel, leaf, rootResolved) {
|
|
|
508
683
|
return;
|
|
509
684
|
}
|
|
510
685
|
if (outcome === "unsupported") {
|
|
511
|
-
|
|
686
|
+
unsupportedLinkRoots(port).add(rootResolved);
|
|
512
687
|
await port.rename(tmp, target);
|
|
513
688
|
return;
|
|
514
689
|
}
|
|
@@ -556,7 +731,7 @@ export async function mutateExact(port, root, rel, body) {
|
|
|
556
731
|
await replaceExistingLeaf(port, tmp, target, rel);
|
|
557
732
|
return;
|
|
558
733
|
}
|
|
559
|
-
if (
|
|
734
|
+
if (unsupportedLinkRoots(port).has(rootResolved)) {
|
|
560
735
|
await port.rename(tmp, target);
|
|
561
736
|
return;
|
|
562
737
|
}
|
|
@@ -588,88 +763,149 @@ function kindOf(stats) {
|
|
|
588
763
|
return "file";
|
|
589
764
|
return "other";
|
|
590
765
|
}
|
|
591
|
-
/**
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
766
|
+
/**
|
|
767
|
+
* Linux filesystem types (`statfs` magic numbers) whose directory times are kept by the local
|
|
768
|
+
* kernel and advance on every entry change. Anything else on Linux — NFS, SMB/CIFS, FUSE, 9p,
|
|
769
|
+
* Ceph, and every type not named here — gets no directory witness, so an observation pass lists it
|
|
770
|
+
* exactly as single reads do. Other platforms expose no stable type through Node, so their
|
|
771
|
+
* witnesses are offered and the pass's end-of-pass re-verification is what covers a remote mount.
|
|
772
|
+
*/
|
|
773
|
+
const LOCAL_LINUX_FILESYSTEMS = new Set([
|
|
774
|
+
0xef53, // ext2/3/4
|
|
775
|
+
0x58465342, // xfs
|
|
776
|
+
0x9123683e, // btrfs
|
|
777
|
+
0x01021994, // tmpfs
|
|
778
|
+
0x858458f6, // ramfs
|
|
779
|
+
0x794c7630, // overlayfs
|
|
780
|
+
0x2fc12fc1, // zfs
|
|
781
|
+
0xf2f52010, // f2fs
|
|
782
|
+
0xca451a4e, // bcachefs
|
|
783
|
+
0x4d44, // vfat
|
|
784
|
+
0x2011bab0, // exfat
|
|
785
|
+
0x7366746e, // ntfs3
|
|
786
|
+
0x482b, // hfsplus
|
|
787
|
+
]);
|
|
788
|
+
/** Whether a directory witness may be offered on `platform` for a filesystem of `filesystemType`. */
|
|
789
|
+
export function directoryWitnessTrusted(platform, filesystemType) {
|
|
790
|
+
if (platform !== "linux")
|
|
791
|
+
return true;
|
|
792
|
+
return filesystemType !== null && LOCAL_LINUX_FILESYSTEMS.has(filesystemType);
|
|
793
|
+
}
|
|
794
|
+
/** Whether `dir`'s filesystem may offer directory witnesses, asked once per device per port. */
|
|
795
|
+
function witnessTrust() {
|
|
796
|
+
const devices = new Map();
|
|
797
|
+
return (dev, dir) => {
|
|
798
|
+
if (process.platform !== "linux")
|
|
799
|
+
return Promise.resolve(true);
|
|
800
|
+
let trusted = devices.get(dev);
|
|
801
|
+
if (trusted === undefined) {
|
|
802
|
+
trusted = fs.statfs(dir).then((info) => directoryWitnessTrusted("linux", Number(info.type)), () => false);
|
|
803
|
+
devices.set(dev, trusted);
|
|
610
804
|
}
|
|
611
|
-
|
|
612
|
-
|
|
805
|
+
return trusted;
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
/** The one production binding: `node:fs`, the temp-file convention, and the identity lock. */
|
|
809
|
+
export function createNodeFilesystemIdentityPort(hostPolicy) {
|
|
810
|
+
const policy = captureFilesystemHostPolicy(hostPolicy);
|
|
811
|
+
const witnessTrustedOn = witnessTrust();
|
|
812
|
+
return Object.freeze({
|
|
813
|
+
isTransientOpenError: policy.isTransientOpenError,
|
|
814
|
+
isReplacementConflict: policy.isReplacementConflict,
|
|
815
|
+
async probe(target) {
|
|
816
|
+
let lstats;
|
|
817
|
+
try {
|
|
818
|
+
lstats = await fs.lstat(target);
|
|
819
|
+
}
|
|
820
|
+
catch (err) {
|
|
821
|
+
if (isAbsentPathError(err))
|
|
822
|
+
return null;
|
|
823
|
+
throw err;
|
|
824
|
+
}
|
|
825
|
+
return { kind: kindOf(lstats), dev: lstats.dev, ino: lstats.ino };
|
|
826
|
+
},
|
|
827
|
+
async entries(dir) {
|
|
828
|
+
try {
|
|
829
|
+
const dirents = await fs.readdir(dir, { withFileTypes: true });
|
|
830
|
+
return dirents.map((dirent) => ({ name: dirent.name, kind: kindOf(dirent) }));
|
|
831
|
+
}
|
|
832
|
+
catch (err) {
|
|
833
|
+
if (isAbsentPathError(err))
|
|
834
|
+
return null;
|
|
835
|
+
throw err;
|
|
836
|
+
}
|
|
837
|
+
},
|
|
838
|
+
async directoryWitness(dir) {
|
|
839
|
+
let stats;
|
|
840
|
+
try {
|
|
841
|
+
stats = await fs.stat(dir, { bigint: true });
|
|
842
|
+
}
|
|
843
|
+
catch (err) {
|
|
844
|
+
if (isAbsentPathError(err))
|
|
845
|
+
return null;
|
|
846
|
+
throw err;
|
|
847
|
+
}
|
|
848
|
+
if (!(await witnessTrustedOn(stats.dev, dir)))
|
|
613
849
|
return null;
|
|
614
|
-
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
}
|
|
674
|
-
}
|
|
850
|
+
return { dev: stats.dev, ino: stats.ino, mtimeNs: stats.mtimeNs, ctimeNs: stats.ctimeNs };
|
|
851
|
+
},
|
|
852
|
+
async open(target) {
|
|
853
|
+
const handle = await fs.open(target, "r");
|
|
854
|
+
try {
|
|
855
|
+
const stats = await handle.stat();
|
|
856
|
+
return { handle, dev: stats.dev, ino: stats.ino };
|
|
857
|
+
}
|
|
858
|
+
catch (err) {
|
|
859
|
+
await handle.close().catch(() => { });
|
|
860
|
+
throw err;
|
|
861
|
+
}
|
|
862
|
+
},
|
|
863
|
+
readAll(handle) {
|
|
864
|
+
return handle.readFile();
|
|
865
|
+
},
|
|
866
|
+
close(handle) {
|
|
867
|
+
return handle.close();
|
|
868
|
+
},
|
|
869
|
+
async stat(target) {
|
|
870
|
+
return { mtime: (await fs.stat(target)).mtime };
|
|
871
|
+
},
|
|
872
|
+
async mkdir(dir) {
|
|
873
|
+
try {
|
|
874
|
+
await fs.mkdir(dir);
|
|
875
|
+
return "created";
|
|
876
|
+
}
|
|
877
|
+
catch (err) {
|
|
878
|
+
if (err.code === "EEXIST")
|
|
879
|
+
return "exists";
|
|
880
|
+
throw err;
|
|
881
|
+
}
|
|
882
|
+
},
|
|
883
|
+
async writeTemp(dir, name, bytes) {
|
|
884
|
+
await fs.writeFile(path.join(dir, name), bytes);
|
|
885
|
+
},
|
|
886
|
+
async link(from, to) {
|
|
887
|
+
try {
|
|
888
|
+
await fs.link(from, to);
|
|
889
|
+
return "linked";
|
|
890
|
+
}
|
|
891
|
+
catch (err) {
|
|
892
|
+
const code = err.code;
|
|
893
|
+
if (code === "EEXIST")
|
|
894
|
+
return "exists";
|
|
895
|
+
if (code === "EPERM" || code === "ENOTSUP" || code === "EOPNOTSUPP" || code === "EXDEV")
|
|
896
|
+
return "unsupported";
|
|
897
|
+
throw err;
|
|
898
|
+
}
|
|
899
|
+
},
|
|
900
|
+
async rename(from, to) {
|
|
901
|
+
await fs.rename(from, to);
|
|
902
|
+
},
|
|
903
|
+
async unlink(target) {
|
|
904
|
+
await fs.unlink(target);
|
|
905
|
+
},
|
|
906
|
+
claim(key, identity) {
|
|
907
|
+
return acquireFilesystemIdentityLock(key, `${identity.root}:${identity.rel}`, { portableRoot: identity.root, hostPolicy: policy });
|
|
908
|
+
},
|
|
909
|
+
});
|
|
910
|
+
}
|
|
675
911
|
//# sourceMappingURL=filesystem-identity.js.map
|