@amalgm/shell 0.1.164-preview.36072132286 → 0.1.164-preview.36809057014
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/PURPOSE.md +642 -128
- package/README.md +10 -8
- package/dist/accepted-tail.d.ts +26 -0
- package/dist/accepted-tail.js +37 -0
- package/dist/accepted-tail.js.map +1 -0
- package/dist/agent-execution.d.ts +16 -1
- package/dist/agent-execution.js +13 -5
- package/dist/agent-execution.js.map +1 -1
- package/dist/apply-cleanup.d.ts +28 -0
- package/dist/apply-cleanup.js +166 -0
- package/dist/apply-cleanup.js.map +1 -0
- package/dist/apply-recovery.d.ts +47 -0
- package/dist/apply-recovery.js +99 -0
- package/dist/apply-recovery.js.map +1 -0
- package/dist/apply-rows.d.ts +72 -0
- package/dist/apply-rows.js +150 -0
- package/dist/apply-rows.js.map +1 -0
- package/dist/apply-saves.d.ts +85 -0
- package/dist/apply-saves.js +238 -0
- package/dist/apply-saves.js.map +1 -0
- package/dist/boot.js +2 -1
- package/dist/boot.js.map +1 -1
- package/dist/capture-work.d.ts +8 -0
- package/dist/capture-work.js +67 -0
- package/dist/capture-work.js.map +1 -0
- package/dist/cargo-group.d.ts +45 -0
- package/dist/cargo-group.js +88 -0
- package/dist/cargo-group.js.map +1 -0
- package/dist/channel-session.d.ts +4 -2
- package/dist/channel-session.js +4 -3
- package/dist/channel-session.js.map +1 -1
- package/dist/chat-composition.d.ts +2 -0
- package/dist/chat-composition.js +1 -0
- package/dist/chat-composition.js.map +1 -1
- package/dist/cli.js +20 -1
- package/dist/cli.js.map +1 -1
- package/dist/construct-apply-host.d.ts +4 -2
- package/dist/construct-apply-host.js +8 -3
- package/dist/construct-apply-host.js.map +1 -1
- package/dist/construct-door.js +1 -1
- package/dist/construct-door.js.map +1 -1
- package/dist/construct-ledger.d.ts +6 -1
- package/dist/construct-ledger.js +21 -33
- package/dist/construct-ledger.js.map +1 -1
- package/dist/content-cache-collection.d.ts +18 -0
- package/dist/content-cache-collection.js +99 -0
- package/dist/content-cache-collection.js.map +1 -0
- package/dist/content-cache-host.d.ts +83 -17
- package/dist/content-cache-host.js +335 -95
- package/dist/content-cache-host.js.map +1 -1
- package/dist/content-cache-namespace.d.ts +59 -0
- package/dist/content-cache-namespace.js +210 -0
- package/dist/content-cache-namespace.js.map +1 -0
- package/dist/content-cache-ownership.d.ts +13 -0
- package/dist/content-cache-ownership.js +75 -0
- package/dist/content-cache-ownership.js.map +1 -0
- package/dist/content-cache-retention.d.ts +23 -0
- package/dist/content-cache-retention.js +195 -0
- package/dist/content-cache-retention.js.map +1 -0
- package/dist/content-capture-pool.d.ts +287 -0
- package/dist/content-capture-pool.js +461 -0
- package/dist/content-capture-pool.js.map +1 -0
- package/dist/content-capture-worker.d.ts +8 -0
- package/dist/content-capture-worker.js +109 -0
- package/dist/content-capture-worker.js.map +1 -0
- package/dist/content-clock.d.ts +42 -0
- package/dist/content-clock.js +166 -0
- package/dist/content-clock.js.map +1 -0
- package/dist/content-direct.d.ts +2 -0
- package/dist/content-direct.js +12 -0
- package/dist/content-direct.js.map +1 -1
- package/dist/content-failure.d.ts +18 -0
- package/dist/content-failure.js +38 -0
- package/dist/content-failure.js.map +1 -0
- package/dist/content-stream-thread.d.ts +60 -0
- package/dist/content-stream-thread.js +95 -0
- package/dist/content-stream-thread.js.map +1 -0
- package/dist/content-stream-worker.d.ts +7 -0
- package/dist/content-stream-worker.js +52 -0
- package/dist/content-stream-worker.js.map +1 -0
- package/dist/declaration-absorption.d.ts +37 -0
- package/dist/declaration-absorption.js +119 -0
- package/dist/declaration-absorption.js.map +1 -0
- package/dist/declaration-chain.d.ts +36 -0
- package/dist/declaration-chain.js +96 -0
- package/dist/declaration-chain.js.map +1 -0
- package/dist/declaration-commit.d.ts +31 -0
- package/dist/declaration-commit.js +49 -0
- package/dist/declaration-commit.js.map +1 -0
- package/dist/declaration-hold.d.ts +22 -0
- package/dist/declaration-hold.js +24 -0
- package/dist/declaration-hold.js.map +1 -0
- package/dist/declaration-journal.d.ts +62 -0
- package/dist/declaration-journal.js +99 -0
- package/dist/declaration-journal.js.map +1 -0
- package/dist/declaration-save.d.ts +31 -0
- package/dist/declaration-save.js +134 -0
- package/dist/declaration-save.js.map +1 -0
- package/dist/detection/accepted-result.d.ts +19 -1
- package/dist/detection/accepted-result.js +36 -5
- package/dist/detection/accepted-result.js.map +1 -1
- package/dist/detection/admission-save.d.ts +55 -0
- package/dist/detection/admission-save.js +48 -0
- package/dist/detection/admission-save.js.map +1 -0
- package/dist/detection/admission-units.d.ts +66 -0
- package/dist/detection/admission-units.js +322 -0
- package/dist/detection/admission-units.js.map +1 -0
- package/dist/detection/alias-discovery.d.ts +12 -0
- package/dist/detection/alias-discovery.js +80 -0
- package/dist/detection/alias-discovery.js.map +1 -0
- package/dist/detection/alias-examination.d.ts +30 -0
- package/dist/detection/alias-examination.js +49 -0
- package/dist/detection/alias-examination.js.map +1 -0
- package/dist/detection/apply-ownership.d.ts +81 -0
- package/dist/detection/apply-ownership.js +232 -0
- package/dist/detection/apply-ownership.js.map +1 -0
- package/dist/detection/basis-advanced.d.ts +11 -0
- package/dist/detection/basis-advanced.js +26 -0
- package/dist/detection/basis-advanced.js.map +1 -0
- package/dist/detection/capture-outcome.d.ts +16 -0
- package/dist/detection/capture-outcome.js +92 -0
- package/dist/detection/capture-outcome.js.map +1 -0
- package/dist/detection/container-membership.d.ts +32 -0
- package/dist/detection/container-membership.js +49 -0
- package/dist/detection/container-membership.js.map +1 -0
- package/dist/detection/detect-cancelled.d.ts +6 -0
- package/dist/detection/detect-cancelled.js +10 -0
- package/dist/detection/detect-cancelled.js.map +1 -0
- package/dist/detection/directory-proof.d.ts +47 -0
- package/dist/detection/directory-proof.js +77 -0
- package/dist/detection/directory-proof.js.map +1 -0
- package/dist/detection/disposition-rows.d.ts +18 -0
- package/dist/detection/disposition-rows.js +29 -0
- package/dist/detection/disposition-rows.js.map +1 -0
- package/dist/detection/dispositions.d.ts +130 -0
- package/dist/detection/dispositions.js +248 -0
- package/dist/detection/dispositions.js.map +1 -0
- package/dist/detection/git-notice.d.ts +88 -0
- package/dist/detection/git-notice.js +444 -0
- package/dist/detection/git-notice.js.map +1 -0
- package/dist/detection/ground-proof.d.ts +130 -0
- package/dist/detection/ground-proof.js +274 -0
- package/dist/detection/ground-proof.js.map +1 -0
- package/dist/detection/ground-reader.d.ts +29 -0
- package/dist/detection/ground-reader.js +102 -0
- package/dist/detection/ground-reader.js.map +1 -0
- package/dist/detection/held-territory.d.ts +51 -0
- package/dist/detection/held-territory.js +205 -0
- package/dist/detection/held-territory.js.map +1 -0
- package/dist/detection/identity-discovery.d.ts +45 -0
- package/dist/detection/identity-discovery.js +287 -0
- package/dist/detection/identity-discovery.js.map +1 -0
- package/dist/detection/maintenance-sweep.d.ts +108 -0
- package/dist/detection/maintenance-sweep.js +325 -0
- package/dist/detection/maintenance-sweep.js.map +1 -0
- package/dist/detection/name-reach.d.ts +12 -0
- package/dist/detection/name-reach.js +28 -0
- package/dist/detection/name-reach.js.map +1 -0
- package/dist/detection/notebook-basis.d.ts +5 -7
- package/dist/detection/notebook-basis.js +6 -7
- package/dist/detection/notebook-basis.js.map +1 -1
- package/dist/detection/owed-selection.d.ts +51 -0
- package/dist/detection/owed-selection.js +169 -0
- package/dist/detection/owed-selection.js.map +1 -0
- package/dist/detection/portable.d.ts +34 -34
- package/dist/detection/portable.js +67 -93
- package/dist/detection/portable.js.map +1 -1
- package/dist/detection/reconciliation-coverage.d.ts +7 -0
- package/dist/detection/reconciliation-coverage.js +16 -0
- package/dist/detection/reconciliation-coverage.js.map +1 -0
- package/dist/detection/repository-publication.d.ts +20 -0
- package/dist/detection/repository-publication.js +79 -0
- package/dist/detection/repository-publication.js.map +1 -0
- package/dist/detection/repository-routes.d.ts +43 -0
- package/dist/detection/repository-routes.js +97 -0
- package/dist/detection/repository-routes.js.map +1 -0
- package/dist/detection/root-examination.d.ts +94 -0
- package/dist/detection/root-examination.js +523 -0
- package/dist/detection/root-examination.js.map +1 -0
- package/dist/detection/runtime.d.ts +131 -64
- package/dist/detection/runtime.js +808 -1103
- package/dist/detection/runtime.js.map +1 -1
- package/dist/detection/scoped-identity-port.d.ts +34 -0
- package/dist/detection/scoped-identity-port.js +81 -0
- package/dist/detection/scoped-identity-port.js.map +1 -0
- package/dist/detection/seal-law.d.ts +66 -0
- package/dist/detection/seal-law.js +116 -0
- package/dist/detection/seal-law.js.map +1 -0
- package/dist/detection/sharing-policy.d.ts +11 -0
- package/dist/detection/sharing-policy.js +32 -0
- package/dist/detection/sharing-policy.js.map +1 -0
- package/dist/detection/thread-database.d.ts +4 -0
- package/dist/detection/thread-database.js +30 -0
- package/dist/detection/thread-database.js.map +1 -0
- package/dist/detection/unreadable.d.ts +11 -0
- package/dist/detection/unreadable.js +9 -0
- package/dist/detection/unreadable.js.map +1 -0
- package/dist/detection/verified-content.d.ts +6 -0
- package/dist/detection/verified-content.js +12 -0
- package/dist/detection/verified-content.js.map +1 -0
- package/dist/detection/walk-law.d.ts +34 -0
- package/dist/detection/walk-law.js +55 -0
- package/dist/detection/walk-law.js.map +1 -0
- package/dist/development/fly-guest.js +2 -1
- package/dist/development/fly-guest.js.map +1 -1
- package/dist/entity-apply-host.d.ts +29 -13
- package/dist/entity-apply-host.js +1426 -461
- package/dist/entity-apply-host.js.map +1 -1
- package/dist/entity-apply-store.d.ts +77 -30
- package/dist/entity-apply-store.js +221 -516
- package/dist/entity-apply-store.js.map +1 -1
- package/dist/entity-record-observability.js +2 -0
- package/dist/entity-record-observability.js.map +1 -1
- package/dist/entity-record-saves.d.ts +20 -0
- package/dist/entity-record-saves.js +91 -0
- package/dist/entity-record-saves.js.map +1 -0
- package/dist/entity-record-store.d.ts +15 -7
- package/dist/entity-record-store.js +57 -117
- package/dist/entity-record-store.js.map +1 -1
- package/dist/files-register-host.d.ts +22 -3
- package/dist/files-register-host.js +70 -31
- package/dist/files-register-host.js.map +1 -1
- package/dist/filesystem.js +3 -2
- package/dist/filesystem.js.map +1 -1
- package/dist/git-binding.d.ts +65 -0
- package/dist/git-binding.js +220 -0
- package/dist/git-binding.js.map +1 -0
- package/dist/git-capture.d.ts +39 -0
- package/dist/git-capture.js +86 -0
- package/dist/git-capture.js.map +1 -0
- package/dist/git-card.d.ts +12 -0
- package/dist/git-card.js +123 -0
- package/dist/git-card.js.map +1 -0
- package/dist/git-checkpoint-construction.d.ts +41 -0
- package/dist/git-checkpoint-construction.js +96 -0
- package/dist/git-checkpoint-construction.js.map +1 -0
- package/dist/git-checkpoint-preparation.d.ts +37 -0
- package/dist/git-checkpoint-preparation.js +145 -0
- package/dist/git-checkpoint-preparation.js.map +1 -0
- package/dist/git-command.d.ts +61 -8
- package/dist/git-command.js +217 -63
- package/dist/git-command.js.map +1 -1
- package/dist/git-configuration.d.ts +40 -0
- package/dist/git-configuration.js +217 -0
- package/dist/git-configuration.js.map +1 -0
- package/dist/git-evidence.d.ts +61 -0
- package/dist/git-evidence.js +181 -0
- package/dist/git-evidence.js.map +1 -0
- package/dist/git-index-entries.d.ts +15 -0
- package/dist/git-index-entries.js +44 -0
- package/dist/git-index-entries.js.map +1 -0
- package/dist/git-index-format.d.ts +35 -0
- package/dist/git-index-format.js +293 -0
- package/dist/git-index-format.js.map +1 -0
- package/dist/git-index-witness.d.ts +33 -0
- package/dist/git-index-witness.js +69 -0
- package/dist/git-index-witness.js.map +1 -0
- package/dist/git-literal-host.d.ts +82 -0
- package/dist/git-literal-host.js +172 -0
- package/dist/git-literal-host.js.map +1 -0
- package/dist/git-literal-read.d.ts +88 -0
- package/dist/git-literal-read.js +170 -0
- package/dist/git-literal-read.js.map +1 -0
- package/dist/git-literal-replay.d.ts +33 -0
- package/dist/git-literal-replay.js +268 -0
- package/dist/git-literal-replay.js.map +1 -0
- package/dist/git-native-file.d.ts +42 -0
- package/dist/git-native-file.js +145 -0
- package/dist/git-native-file.js.map +1 -0
- package/dist/git-native-index.d.ts +21 -0
- package/dist/git-native-index.js +44 -0
- package/dist/git-native-index.js.map +1 -0
- package/dist/git-operation-host.d.ts +48 -0
- package/dist/git-operation-host.js +127 -0
- package/dist/git-operation-host.js.map +1 -0
- package/dist/git-private-index.d.ts +11 -0
- package/dist/git-private-index.js +42 -0
- package/dist/git-private-index.js.map +1 -0
- package/dist/git-private-repository.d.ts +4 -0
- package/dist/git-private-repository.js +69 -0
- package/dist/git-private-repository.js.map +1 -0
- package/dist/git-private-view.d.ts +39 -0
- package/dist/git-private-view.js +162 -0
- package/dist/git-private-view.js.map +1 -0
- package/dist/git-ref-store.d.ts +12 -0
- package/dist/git-ref-store.js +68 -0
- package/dist/git-ref-store.js.map +1 -0
- package/dist/git-registration-host.d.ts +20 -30
- package/dist/git-registration-host.js +86 -249
- package/dist/git-registration-host.js.map +1 -1
- package/dist/git-repository-host.d.ts +148 -22
- package/dist/git-repository-host.js +633 -650
- package/dist/git-repository-host.js.map +1 -1
- package/dist/git-worktree-host.d.ts +2 -0
- package/dist/git-worktree-host.js +16 -0
- package/dist/git-worktree-host.js.map +1 -0
- package/dist/graph-publication.d.ts +75 -0
- package/dist/graph-publication.js +203 -0
- package/dist/graph-publication.js.map +1 -0
- package/dist/ground-basis.d.ts +242 -0
- package/dist/ground-basis.js +1023 -0
- package/dist/ground-basis.js.map +1 -0
- package/dist/ground-checkpoint-worker.d.ts +1 -0
- package/dist/ground-checkpoint-worker.js +84 -0
- package/dist/ground-checkpoint-worker.js.map +1 -0
- package/dist/ground-checkpoints.d.ts +16 -0
- package/dist/ground-checkpoints.js +45 -0
- package/dist/ground-checkpoints.js.map +1 -0
- package/dist/ground-coordination.d.ts +107 -3
- package/dist/ground-coordination.js +249 -24
- package/dist/ground-coordination.js.map +1 -1
- package/dist/ground-database.d.ts +42 -0
- package/dist/ground-database.js +290 -0
- package/dist/ground-database.js.map +1 -0
- package/dist/ground-differences.d.ts +23 -0
- package/dist/ground-differences.js +47 -0
- package/dist/ground-differences.js.map +1 -0
- package/dist/ground-holders.d.ts +4 -0
- package/dist/ground-holders.js +15 -0
- package/dist/ground-holders.js.map +1 -0
- package/dist/ground-initialization-worker.d.ts +1 -0
- package/dist/ground-initialization-worker.js +20 -0
- package/dist/ground-initialization-worker.js.map +1 -0
- package/dist/ground-initialization.d.ts +35 -0
- package/dist/ground-initialization.js +102 -0
- package/dist/ground-initialization.js.map +1 -0
- package/dist/ground-install-saves.d.ts +63 -0
- package/dist/ground-install-saves.js +139 -0
- package/dist/ground-install-saves.js.map +1 -0
- package/dist/ground-inventory-schema.d.ts +18 -0
- package/dist/ground-inventory-schema.js +168 -0
- package/dist/ground-inventory-schema.js.map +1 -0
- package/dist/ground-profile.d.ts +7 -0
- package/dist/ground-profile.js +52 -0
- package/dist/ground-profile.js.map +1 -0
- package/dist/ground-root-index.d.ts +2 -1
- package/dist/ground-root-index.js +16 -14
- package/dist/ground-root-index.js.map +1 -1
- package/dist/ground-row.d.ts +62 -0
- package/dist/ground-row.js +70 -0
- package/dist/ground-row.js.map +1 -0
- package/dist/ground-save-ops.d.ts +44 -0
- package/dist/ground-save-ops.js +41 -0
- package/dist/ground-save-ops.js.map +1 -0
- package/dist/ground-saver-worker.d.ts +1 -0
- package/dist/ground-saver-worker.js +156 -0
- package/dist/ground-saver-worker.js.map +1 -0
- package/dist/ground-saver.d.ts +75 -0
- package/dist/ground-saver.js +216 -0
- package/dist/ground-saver.js.map +1 -0
- package/dist/ground-store.d.ts +84 -0
- package/dist/ground-store.js +473 -0
- package/dist/ground-store.js.map +1 -0
- package/dist/ground-territory.d.ts +130 -0
- package/dist/ground-territory.js +511 -0
- package/dist/ground-territory.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/installation/ownership.d.ts +0 -2
- package/dist/installation/ownership.js +3 -15
- package/dist/installation/ownership.js.map +1 -1
- package/dist/machine-host.d.ts +3 -2
- package/dist/machine-host.js +28 -16
- package/dist/machine-host.js.map +1 -1
- package/dist/materialized-graph.d.ts +7 -7
- package/dist/materialized-graph.js +11 -23
- package/dist/materialized-graph.js.map +1 -1
- package/dist/module-thread.d.ts +9 -0
- package/dist/module-thread.js +10 -0
- package/dist/module-thread.js.map +1 -0
- package/dist/native/fsevents-stream.node +0 -0
- package/dist/physical-path-witness.d.ts +64 -0
- package/dist/physical-path-witness.js +168 -0
- package/dist/physical-path-witness.js.map +1 -0
- package/dist/register-upload-fusion.d.ts +5 -4
- package/dist/register-upload-fusion.js +9 -6
- package/dist/register-upload-fusion.js.map +1 -1
- package/dist/registry-graph.d.ts +3 -2
- package/dist/registry-graph.js +9 -6
- package/dist/registry-graph.js.map +1 -1
- package/dist/registry-page-cache.d.ts +5 -2
- package/dist/registry-page-cache.js.map +1 -1
- package/dist/repository-identity-steps.d.ts +5 -0
- package/dist/repository-identity-steps.js +33 -0
- package/dist/repository-identity-steps.js.map +1 -0
- package/dist/runtime-node-flags.d.ts +10 -0
- package/dist/runtime-node-flags.js +11 -0
- package/dist/runtime-node-flags.js.map +1 -0
- package/dist/service/adapter.d.ts +1 -1
- package/dist/service/adapter.js +1 -1
- package/dist/service/adapter.js.map +1 -1
- package/dist/service/cli.js +16 -20
- package/dist/service/cli.js.map +1 -1
- package/dist/service/control.d.ts +2 -2
- package/dist/service/keepalive.d.ts +4 -11
- package/dist/service/keepalive.js +65 -118
- package/dist/service/keepalive.js.map +1 -1
- package/dist/service/policy.d.ts +36 -0
- package/dist/service/policy.js +25 -0
- package/dist/service/policy.js.map +1 -0
- package/dist/service/portable.d.ts +1 -1
- package/dist/service/portable.js +1 -1
- package/dist/service/portable.js.map +1 -1
- package/dist/service/recovery.d.ts +10 -9
- package/dist/service/recovery.js +29 -19
- package/dist/service/recovery.js.map +1 -1
- package/dist/service/windows-action.d.ts +5 -3
- package/dist/service/windows-action.js +6 -9
- package/dist/service/windows-action.js.map +1 -1
- package/dist/service/windows-task.js +5 -5
- package/dist/service/windows-task.js.map +1 -1
- package/dist/sharing-admission.d.ts +17 -0
- package/dist/sharing-admission.js +128 -0
- package/dist/sharing-admission.js.map +1 -0
- package/dist/snapshot-delivery-baseline.d.ts +12 -3
- package/dist/snapshot-delivery-baseline.js +41 -42
- package/dist/snapshot-delivery-baseline.js.map +1 -1
- package/dist/source-proof.d.ts +36 -0
- package/dist/source-proof.js +70 -0
- package/dist/source-proof.js.map +1 -0
- package/dist/source-signature.d.ts +56 -0
- package/dist/source-signature.js +56 -0
- package/dist/source-signature.js.map +1 -0
- package/dist/source-witness.d.ts +15 -0
- package/dist/source-witness.js +29 -0
- package/dist/source-witness.js.map +1 -0
- package/dist/sqlite-durability.d.ts +31 -0
- package/dist/sqlite-durability.js +28 -0
- package/dist/sqlite-durability.js.map +1 -0
- package/dist/sqlite.d.ts +8 -2
- package/dist/sqlite.js +27 -4
- package/dist/sqlite.js.map +1 -1
- package/dist/sync-address.d.ts +19 -0
- package/dist/sync-address.js +52 -0
- package/dist/sync-address.js.map +1 -0
- package/dist/sync-setting.d.ts +15 -0
- package/dist/sync-setting.js +13 -0
- package/dist/sync-setting.js.map +1 -1
- package/dist/turns.d.ts +42 -0
- package/dist/turns.js +112 -0
- package/dist/turns.js.map +1 -0
- package/dist/updates/bootstrap.d.ts +53 -7
- package/dist/updates/bootstrap.js +224 -137
- package/dist/updates/bootstrap.js.map +1 -1
- package/dist/updates/controller.d.ts +8 -0
- package/dist/updates/controller.js +27 -3
- package/dist/updates/controller.js.map +1 -1
- package/dist/updates/store.d.ts +3 -0
- package/dist/updates/store.js +12 -0
- package/dist/updates/store.js.map +1 -1
- package/dist/user-ground-host.d.ts +364 -69
- package/dist/user-ground-host.js +5231 -3366
- package/dist/user-ground-host.js.map +1 -1
- package/dist/watching/fsevents.d.ts +52 -1
- package/dist/watching/fsevents.js +60 -25
- package/dist/watching/fsevents.js.map +1 -1
- package/dist/watching/host.d.ts +129 -5
- package/dist/watching/host.js +433 -80
- package/dist/watching/host.js.map +1 -1
- package/dist/watching/index.d.ts +1 -1
- package/dist/wire-binary.d.ts +3 -2
- package/dist/wire-binary.js +10 -8
- package/dist/wire-binary.js.map +1 -1
- package/dist/wire-client.d.ts +3 -4
- package/dist/wire-client.js +18 -44
- package/dist/wire-client.js.map +1 -1
- package/dist/wire-outbox.d.ts +34 -0
- package/dist/wire-outbox.js +127 -0
- package/dist/wire-outbox.js.map +1 -0
- package/dist/workspace-host.d.ts +4 -0
- package/dist/workspace-host.js +12 -1
- package/dist/workspace-host.js.map +1 -1
- package/examinations/fixtures/private-wire-authority.js +133 -10
- package/npm-shrinkwrap.json +43 -56
- package/package.json +26 -13
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which names in the content cache directory are known durable.
|
|
3
|
+
*
|
|
4
|
+
* A cache name appears only over flushed bytes, but the directory entry
|
|
5
|
+
* itself survives a crash only once the directory is flushed. Flushing it
|
|
6
|
+
* before every Record costs one full barrier (F_FULLFSYNC on macOS) even
|
|
7
|
+
* when every name the Record needs was made durable long ago. The law here:
|
|
8
|
+
* once the required names are known durable, reusing them needs no flush.
|
|
9
|
+
*
|
|
10
|
+
* One main-thread coordinator per cache directory counts publications. A
|
|
11
|
+
* name gets a generation when it is published, or when a caller
|
|
12
|
+
* requires a name nobody reported (a name another writer published and has
|
|
13
|
+
* not reported yet is such a name, so it is conservatively flushed). A flush
|
|
14
|
+
* captures the latest generation just before it starts and credits exactly
|
|
15
|
+
* that much, only after it succeeds. A new directory incarnation forgets
|
|
16
|
+
* everything, and its first flush also makes the directory's own entry
|
|
17
|
+
* durable. Removal forgets the name, so recreating it is a new publication.
|
|
18
|
+
* Reporting a name reads nothing: the incarnation is observed off the event
|
|
19
|
+
* loop whenever durability is required, since the directory may be mid-flush,
|
|
20
|
+
* and a flush credits only the incarnation it flushed.
|
|
21
|
+
*
|
|
22
|
+
* Staged cargo becomes durable in groups, never one full flush per file. A
|
|
23
|
+
* full flush serializes at the drive (about 4 ms each on Apple SSDs), so a
|
|
24
|
+
* burst of a hundred small captures would otherwise wait for a hundred of
|
|
25
|
+
* them. A cargo writer stages its bytes written through to the device and
|
|
26
|
+
* asks for a barrier; every writer that staged before a barrier began is
|
|
27
|
+
* covered by it, and those arriving while one runs share the next. Only then
|
|
28
|
+
* does each staged file receive its name. On macOS the staged writes use
|
|
29
|
+
* O_DSYNC, so each is on the drive when it returns, and one F_FULLFSYNC of
|
|
30
|
+
* the cache directory flushes the drive's cache of them all. Elsewhere a
|
|
31
|
+
* written-through open is itself a flush per write, so each staged file is
|
|
32
|
+
* flushed through its own handle within the group barrier instead. A pass
|
|
33
|
+
* that captures a set asks for its barrier once the whole set has staged
|
|
34
|
+
* (cargo-group.ts), since a barrier stalls the staging still in flight.
|
|
35
|
+
*/
|
|
36
|
+
/** The extra open flag a staged cargo file is written with. */
|
|
37
|
+
export declare const STAGED_WRITE_THROUGH: number;
|
|
38
|
+
/** What a cache writer did to one name. */
|
|
39
|
+
export type CachePublication = "published" | "reused";
|
|
40
|
+
declare class CacheNamespace {
|
|
41
|
+
#private;
|
|
42
|
+
constructor(directory: string);
|
|
43
|
+
/** Names published since this process began: the cache's growth counter.
|
|
44
|
+
* One that replaced an equal copy counts too; only racing writers do so. */
|
|
45
|
+
get created(): number;
|
|
46
|
+
/** A published name needs a later flush; a reused one is adopted only
|
|
47
|
+
* when unknown. A late report never lowers a generation. */
|
|
48
|
+
report(name: string, publication: CachePublication): void;
|
|
49
|
+
/** Resolve once `staged` is durable, by a barrier that began after it was
|
|
50
|
+
* staged. A failed barrier rejects its whole group; nothing is named. */
|
|
51
|
+
stagedDurable(staged: string): Promise<void>;
|
|
52
|
+
forget(names: Iterable<string>): void;
|
|
53
|
+
/** Resolve once every name is durable, flushing only when some is not. A
|
|
54
|
+
* failed flush credits nothing and rejects, so dependent admission waits. */
|
|
55
|
+
require(names: readonly string[]): Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
/** The one coordinator for a cache directory in this process. */
|
|
58
|
+
export declare function cacheNamespace(directory: string): CacheNamespace;
|
|
59
|
+
export {};
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which names in the content cache directory are known durable.
|
|
3
|
+
*
|
|
4
|
+
* A cache name appears only over flushed bytes, but the directory entry
|
|
5
|
+
* itself survives a crash only once the directory is flushed. Flushing it
|
|
6
|
+
* before every Record costs one full barrier (F_FULLFSYNC on macOS) even
|
|
7
|
+
* when every name the Record needs was made durable long ago. The law here:
|
|
8
|
+
* once the required names are known durable, reusing them needs no flush.
|
|
9
|
+
*
|
|
10
|
+
* One main-thread coordinator per cache directory counts publications. A
|
|
11
|
+
* name gets a generation when it is published, or when a caller
|
|
12
|
+
* requires a name nobody reported (a name another writer published and has
|
|
13
|
+
* not reported yet is such a name, so it is conservatively flushed). A flush
|
|
14
|
+
* captures the latest generation just before it starts and credits exactly
|
|
15
|
+
* that much, only after it succeeds. A new directory incarnation forgets
|
|
16
|
+
* everything, and its first flush also makes the directory's own entry
|
|
17
|
+
* durable. Removal forgets the name, so recreating it is a new publication.
|
|
18
|
+
* Reporting a name reads nothing: the incarnation is observed off the event
|
|
19
|
+
* loop whenever durability is required, since the directory may be mid-flush,
|
|
20
|
+
* and a flush credits only the incarnation it flushed.
|
|
21
|
+
*
|
|
22
|
+
* Staged cargo becomes durable in groups, never one full flush per file. A
|
|
23
|
+
* full flush serializes at the drive (about 4 ms each on Apple SSDs), so a
|
|
24
|
+
* burst of a hundred small captures would otherwise wait for a hundred of
|
|
25
|
+
* them. A cargo writer stages its bytes written through to the device and
|
|
26
|
+
* asks for a barrier; every writer that staged before a barrier began is
|
|
27
|
+
* covered by it, and those arriving while one runs share the next. Only then
|
|
28
|
+
* does each staged file receive its name. On macOS the staged writes use
|
|
29
|
+
* O_DSYNC, so each is on the drive when it returns, and one F_FULLFSYNC of
|
|
30
|
+
* the cache directory flushes the drive's cache of them all. Elsewhere a
|
|
31
|
+
* written-through open is itself a flush per write, so each staged file is
|
|
32
|
+
* flushed through its own handle within the group barrier instead. A pass
|
|
33
|
+
* that captures a set asks for its barrier once the whole set has staged
|
|
34
|
+
* (cargo-group.ts), since a barrier stalls the staging still in flight.
|
|
35
|
+
*/
|
|
36
|
+
import { constants } from "node:fs";
|
|
37
|
+
import { lstat, open } from "node:fs/promises";
|
|
38
|
+
import { channel } from "node:diagnostics_channel";
|
|
39
|
+
import { dirname } from "node:path";
|
|
40
|
+
import { boundedForEach } from "./bounded-for-each.js";
|
|
41
|
+
/** The extra open flag a staged cargo file is written with. */
|
|
42
|
+
export const STAGED_WRITE_THROUGH = process.platform === "darwin" ? constants.O_DSYNC : 0;
|
|
43
|
+
/** Staged files one barrier flushes at once where each needs its own flush. */
|
|
44
|
+
const STAGED_FLUSH_CONCURRENCY = 16;
|
|
45
|
+
const flushes = channel("amalgm:content-namespace");
|
|
46
|
+
class CacheNamespace {
|
|
47
|
+
#directory;
|
|
48
|
+
#generations = new Map();
|
|
49
|
+
#incarnation = null;
|
|
50
|
+
#published = 0;
|
|
51
|
+
#durableThrough = 0;
|
|
52
|
+
#entryDurable = false;
|
|
53
|
+
#inFlight = null;
|
|
54
|
+
#created = 0;
|
|
55
|
+
/** The staged group the next barrier will cover, while it gathers. */
|
|
56
|
+
#gathering = null;
|
|
57
|
+
/** The latest staged barrier, settled either way. */
|
|
58
|
+
#staging = Promise.resolve();
|
|
59
|
+
constructor(directory) {
|
|
60
|
+
this.#directory = directory;
|
|
61
|
+
}
|
|
62
|
+
/** Names published since this process began: the cache's growth counter.
|
|
63
|
+
* One that replaced an equal copy counts too; only racing writers do so. */
|
|
64
|
+
get created() { return this.#created; }
|
|
65
|
+
/** A published name needs a later flush; a reused one is adopted only
|
|
66
|
+
* when unknown. A late report never lowers a generation. */
|
|
67
|
+
report(name, publication) {
|
|
68
|
+
if (publication === "published")
|
|
69
|
+
this.#created += 1;
|
|
70
|
+
if (publication === "reused")
|
|
71
|
+
this.#adopt(name);
|
|
72
|
+
else
|
|
73
|
+
this.#generations.set(name, ++this.#published);
|
|
74
|
+
}
|
|
75
|
+
/** Resolve once `staged` is durable, by a barrier that began after it was
|
|
76
|
+
* staged. A failed barrier rejects its whole group; nothing is named. */
|
|
77
|
+
stagedDurable(staged) {
|
|
78
|
+
if (!this.#gathering) {
|
|
79
|
+
const group = [];
|
|
80
|
+
const done = this.#staging.then(() => {
|
|
81
|
+
this.#gathering = null;
|
|
82
|
+
return flushStaged(this.#directory, group);
|
|
83
|
+
});
|
|
84
|
+
this.#staging = done.catch(() => undefined);
|
|
85
|
+
this.#gathering = { staged: group, done };
|
|
86
|
+
}
|
|
87
|
+
this.#gathering.staged.push(staged);
|
|
88
|
+
return this.#gathering.done;
|
|
89
|
+
}
|
|
90
|
+
forget(names) {
|
|
91
|
+
for (const name of names)
|
|
92
|
+
this.#generations.delete(name);
|
|
93
|
+
}
|
|
94
|
+
/** Resolve once every name is durable, flushing only when some is not. A
|
|
95
|
+
* failed flush credits nothing and rejects, so dependent admission waits. */
|
|
96
|
+
async require(names) {
|
|
97
|
+
const started = performance.now();
|
|
98
|
+
let flushed = 0;
|
|
99
|
+
let shared = 0;
|
|
100
|
+
for (;;) {
|
|
101
|
+
const incarnation = await this.#observeIncarnation();
|
|
102
|
+
if (!incarnation)
|
|
103
|
+
throw new Error(`content cache ${this.#directory} is unavailable`);
|
|
104
|
+
let need = 0;
|
|
105
|
+
for (const name of names)
|
|
106
|
+
need = Math.max(need, this.#adopt(name));
|
|
107
|
+
if (this.#durableThrough >= need)
|
|
108
|
+
break;
|
|
109
|
+
const flight = this.#inFlight;
|
|
110
|
+
if (flight && flight.target >= need) {
|
|
111
|
+
shared++;
|
|
112
|
+
await flight.done;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (flight) {
|
|
116
|
+
await flight.done.catch(() => undefined);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
flushed++;
|
|
120
|
+
await this.#flush(incarnation);
|
|
121
|
+
}
|
|
122
|
+
if (flushes.hasSubscribers) {
|
|
123
|
+
flushes.publish({ names: names.length, flushed, shared, ms: performance.now() - started });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
#adopt(name) {
|
|
127
|
+
const known = this.#generations.get(name);
|
|
128
|
+
if (known !== undefined)
|
|
129
|
+
return known;
|
|
130
|
+
const generation = ++this.#published;
|
|
131
|
+
this.#generations.set(name, generation);
|
|
132
|
+
return generation;
|
|
133
|
+
}
|
|
134
|
+
/** A replaced directory holds none of the old entries' durability, and an
|
|
135
|
+
* unavailable one holds none at all; null when it is unavailable. */
|
|
136
|
+
async #observeIncarnation() {
|
|
137
|
+
const stats = await lstat(this.#directory).catch(() => undefined);
|
|
138
|
+
const current = this.#incarnation;
|
|
139
|
+
if (stats && current && current.dev === stats.dev && current.ino === stats.ino)
|
|
140
|
+
return current;
|
|
141
|
+
this.#incarnation = stats ? { dev: stats.dev, ino: stats.ino } : null;
|
|
142
|
+
this.#generations.clear();
|
|
143
|
+
this.#entryDurable = false;
|
|
144
|
+
return this.#incarnation;
|
|
145
|
+
}
|
|
146
|
+
/** Flush the incarnation just observed; credit only while it is current. */
|
|
147
|
+
async #flush(incarnation) {
|
|
148
|
+
const target = this.#published;
|
|
149
|
+
const entry = !this.#entryDurable;
|
|
150
|
+
const done = (async () => {
|
|
151
|
+
const same = await syncDirectory(this.#directory, incarnation);
|
|
152
|
+
if (same && entry)
|
|
153
|
+
await syncDirectory(dirname(this.#directory), null);
|
|
154
|
+
if (same && this.#incarnation === incarnation) {
|
|
155
|
+
this.#durableThrough = Math.max(this.#durableThrough, target);
|
|
156
|
+
this.#entryDurable = true;
|
|
157
|
+
}
|
|
158
|
+
})();
|
|
159
|
+
this.#inFlight = { target, done };
|
|
160
|
+
try {
|
|
161
|
+
await done;
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
if (this.#inFlight?.done === done)
|
|
165
|
+
this.#inFlight = null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/** Make one group of staged files durable: one drive flush over their
|
|
170
|
+
* written-through bytes on macOS, their own flushes elsewhere. */
|
|
171
|
+
async function flushStaged(directory, staged) {
|
|
172
|
+
if (STAGED_WRITE_THROUGH !== 0) {
|
|
173
|
+
await syncDirectory(directory, null);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
await boundedForEach(staged, STAGED_FLUSH_CONCURRENCY, async (file) => {
|
|
177
|
+
const handle = await open(file, "r+");
|
|
178
|
+
try {
|
|
179
|
+
await handle.sync();
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
await handle.close();
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
/** Flush one directory; false when it is no longer the expected incarnation. */
|
|
187
|
+
async function syncDirectory(directory, expected) {
|
|
188
|
+
const handle = await open(directory, "r");
|
|
189
|
+
try {
|
|
190
|
+
if (expected) {
|
|
191
|
+
const stats = await handle.stat();
|
|
192
|
+
if (stats.dev !== expected.dev || stats.ino !== expected.ino)
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
await handle.sync();
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
await handle.close();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const namespaces = new Map();
|
|
203
|
+
/** The one coordinator for a cache directory in this process. */
|
|
204
|
+
export function cacheNamespace(directory) {
|
|
205
|
+
let namespace = namespaces.get(directory);
|
|
206
|
+
if (!namespace)
|
|
207
|
+
namespaces.set(directory, namespace = new CacheNamespace(directory));
|
|
208
|
+
return namespace;
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=content-cache-namespace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-cache-namespace.js","sourceRoot":"","sources":["../src/content-cache-namespace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function contentCacheOwnership(directory: string): ContentCacheOwnership;
|
|
2
|
+
export declare class ContentCacheOwnership {
|
|
3
|
+
#private;
|
|
4
|
+
get unused(): boolean;
|
|
5
|
+
onIdle(callback: (() => void) | null): void;
|
|
6
|
+
use(): () => void;
|
|
7
|
+
using<T>(work: () => Promise<T>): Promise<T>;
|
|
8
|
+
/** Hashing/dependency discovery may yield. A deletion step cannot: each runs
|
|
9
|
+
* synchronously while the original permission still holds, the turn yields
|
|
10
|
+
* between steps, and every new cache reader or reference writer invalidates
|
|
11
|
+
* the permission for the steps not yet run. */
|
|
12
|
+
maintain(prepare: (current: () => boolean) => Promise<readonly (() => void)[] | null>): Promise<"busy" | "deferred" | "invalidated" | "committed">;
|
|
13
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/** One-process cache lifetime fence. Ground cones still own filesystem effects.
|
|
2
|
+
* Users never wait for cleanup: a new user invalidates its pending deletion
|
|
3
|
+
* proof. Only a synchronous step under the original, unused fence may delete. */
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { awaitTurn } from "./turns.js";
|
|
6
|
+
const scopes = new Map();
|
|
7
|
+
export function contentCacheOwnership(directory) {
|
|
8
|
+
const key = resolve(directory);
|
|
9
|
+
let scope = scopes.get(key);
|
|
10
|
+
if (!scope) {
|
|
11
|
+
scope = new ContentCacheOwnership();
|
|
12
|
+
scopes.set(key, scope);
|
|
13
|
+
}
|
|
14
|
+
return scope;
|
|
15
|
+
}
|
|
16
|
+
export class ContentCacheOwnership {
|
|
17
|
+
#users = 0;
|
|
18
|
+
#revision = 0;
|
|
19
|
+
#maintaining = false;
|
|
20
|
+
#onIdle = null;
|
|
21
|
+
get unused() { return this.#users === 0; }
|
|
22
|
+
onIdle(callback) { this.#onIdle = callback; }
|
|
23
|
+
use() {
|
|
24
|
+
this.#revision += 1;
|
|
25
|
+
this.#users += 1;
|
|
26
|
+
let released = false;
|
|
27
|
+
return () => {
|
|
28
|
+
if (released)
|
|
29
|
+
return;
|
|
30
|
+
released = true;
|
|
31
|
+
this.#users -= 1;
|
|
32
|
+
if (this.#users === 0)
|
|
33
|
+
this.#onIdle?.();
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async using(work) {
|
|
37
|
+
const release = this.use();
|
|
38
|
+
try {
|
|
39
|
+
return await work();
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
release();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Hashing/dependency discovery may yield. A deletion step cannot: each runs
|
|
46
|
+
* synchronously while the original permission still holds, the turn yields
|
|
47
|
+
* between steps, and every new cache reader or reference writer invalidates
|
|
48
|
+
* the permission for the steps not yet run. */
|
|
49
|
+
async maintain(prepare) {
|
|
50
|
+
if (this.#users !== 0 || this.#maintaining)
|
|
51
|
+
return "busy";
|
|
52
|
+
this.#maintaining = true;
|
|
53
|
+
const revision = this.#revision;
|
|
54
|
+
const current = () => this.#users === 0 && this.#revision === revision;
|
|
55
|
+
try {
|
|
56
|
+
const steps = await prepare(current);
|
|
57
|
+
if (!current())
|
|
58
|
+
return "invalidated";
|
|
59
|
+
if (!steps)
|
|
60
|
+
return "deferred";
|
|
61
|
+
for (const [index, step] of steps.entries()) {
|
|
62
|
+
if (index > 0)
|
|
63
|
+
await awaitTurn();
|
|
64
|
+
if (!current())
|
|
65
|
+
return "invalidated";
|
|
66
|
+
step();
|
|
67
|
+
}
|
|
68
|
+
return "committed";
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
this.#maintaining = false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=content-cache-ownership.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-cache-ownership.js","sourceRoot":"","sources":["../src/content-cache-ownership.ts"],"names":[],"mappings":"AAAA;;iFAEiF;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAiC,CAAC;AACxD,MAAM,UAAU,qBAAqB,CAAC,SAAiB;IACrD,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/B,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;QAAC,KAAK,GAAG,IAAI,qBAAqB,EAAE,CAAC;QAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAAC,CAAC;IAC5E,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,OAAO,qBAAqB;IAChC,MAAM,GAAG,CAAC,CAAC;IACX,SAAS,GAAG,CAAC,CAAC;IACd,YAAY,GAAG,KAAK,CAAC;IACrB,OAAO,GAAwB,IAAI,CAAC;IAEpC,IAAI,MAAM,KAAc,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;IACnD,MAAM,CAAC,QAA6B,IAAU,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC;IAExE,GAAG;QACD,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;QACpB,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;QACjB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,OAAO,GAAG,EAAE;YACV,IAAI,QAAQ;gBAAE,OAAO;YACrB,QAAQ,GAAG,IAAI,CAAC;YAChB,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;YACjB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1C,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,KAAK,CAAI,IAAsB;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC;YAAC,OAAO,MAAM,IAAI,EAAE,CAAC;QAAC,CAAC;gBAAS,CAAC;YAAC,OAAO,EAAE,CAAC;QAAC,CAAC;IACrD,CAAC;IAED;;;mDAG+C;IAC/C,KAAK,CAAC,QAAQ,CAAC,OAA4E;QACzF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO,MAAM,CAAC;QAC1D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC;QACvE,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;YACrC,IAAI,CAAC,OAAO,EAAE;gBAAE,OAAO,aAAa,CAAC;YACrC,IAAI,CAAC,KAAK;gBAAE,OAAO,UAAU,CAAC;YAC9B,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC5C,IAAI,KAAK,GAAG,CAAC;oBAAE,MAAM,SAAS,EAAE,CAAC;gBACjC,IAAI,CAAC,OAAO,EAAE;oBAAE,OAAO,aAAa,CAAC;gBACrC,IAAI,EAAE,CAAC;YACT,CAAC;YACD,OAAO,WAAW,CAAC;QACrB,CAAC;gBAAS,CAAC;YAAC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAAC,CAAC;IAC1C,CAAC;CACF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
export interface CacheRoot {
|
|
3
|
+
readonly hash: string;
|
|
4
|
+
readonly repository: boolean;
|
|
5
|
+
readonly requiredLocal: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** One coherent answer for these cached objects: every owner that names one,
|
|
8
|
+
* plus the few record owners whose promises must hold whatever the cache
|
|
9
|
+
* holds. Recovery owners whose full dependency set cannot yet be enumerated
|
|
10
|
+
* refuse pruning (null) rather than borrowing current O. */
|
|
11
|
+
export declare function readCacheRoots(database: Database.Database, cached: readonly string[]): readonly CacheRoot[] | null;
|
|
12
|
+
/** Only dependency facts survive a visit. Verification streams pack bytes;
|
|
13
|
+
* metadata inspection never reconstructs an identity map or opens Git. */
|
|
14
|
+
export declare function retainCacheClosure(roots: readonly CacheRoot[], inspect: (hash: string, requiredLocal: boolean) => Promise<{
|
|
15
|
+
readonly parent: string | null;
|
|
16
|
+
} | null>, current?: () => boolean): Promise<ReadonlySet<string> | null>;
|
|
17
|
+
/** The cached objects no durable owner retains, proven in short chunks that
|
|
18
|
+
* yield between them. Null defers: a recovery owner exists or the fence moved.
|
|
19
|
+
* An object cached after the listing is never examined, so never deleted. */
|
|
20
|
+
export declare function unownedCache(database: Database.Database, cacheDir: string, current: () => boolean): Promise<{
|
|
21
|
+
readonly examined: number;
|
|
22
|
+
readonly unowned: readonly string[];
|
|
23
|
+
} | null>;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/** Durable owners of immutable Files cargo. No live path or O observation is
|
|
2
|
+
* a substitute for the exact bytes promised by B or an unresolved record.
|
|
3
|
+
*
|
|
4
|
+
* Retention is asked from the cache's side: for each object the cache holds,
|
|
5
|
+
* does a durable owner name it, directly or through a repository transport
|
|
6
|
+
* chain? Keep = cached ∩ retained; only cached ∖ retained is ever deleted. */
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { decodeAcceptedEntityRecord, decodeLocalEntityRecord } from "@amalgm/live";
|
|
10
|
+
import { hashContentFile, listCachedContent } from "./content-cache-host.js";
|
|
11
|
+
import { inspectRepositoryTransportFile } from "./git-repository-host.js";
|
|
12
|
+
import { awaitTurn } from "./turns.js";
|
|
13
|
+
/** Cached objects asked about in one short read transaction. */
|
|
14
|
+
const CHUNK = 256;
|
|
15
|
+
const PAYLOAD_TYPES = ["file.text", "file.binary", "link", "agent", "automation", "app", "tool"];
|
|
16
|
+
/** One owner more for a root: either role, once, is enough. */
|
|
17
|
+
const retain = (roots, hash, repository, requiredLocal) => {
|
|
18
|
+
const previous = roots.get(hash);
|
|
19
|
+
roots.set(hash, { hash, repository: repository || previous?.repository === true,
|
|
20
|
+
requiredLocal: requiredLocal || previous?.requiredLocal === true });
|
|
21
|
+
};
|
|
22
|
+
const prepared = new WeakMap();
|
|
23
|
+
const statements = (database) => {
|
|
24
|
+
let found = prepared.get(database);
|
|
25
|
+
if (!found)
|
|
26
|
+
prepared.set(database, found = {
|
|
27
|
+
recovery: database.prepare(`SELECT EXISTS(SELECT 1 FROM entity_apply_intents)
|
|
28
|
+
OR EXISTS(SELECT 1 FROM workspace_add_intents)
|
|
29
|
+
OR EXISTS(SELECT 1 FROM snapshot_publications WHERE status = 'pending') AS waiting`),
|
|
30
|
+
constructs: database.prepare("SELECT type, status, payload_version AS payloadVersion FROM constructs"),
|
|
31
|
+
pending: database.prepare("SELECT record_json AS recordJson FROM record_outbox WHERE status = 'pending'"),
|
|
32
|
+
unresolved: database.prepare("SELECT record_json AS recordJson FROM record_inbox WHERE resolved_at IS NULL"),
|
|
33
|
+
transport: database.prepare(`SELECT 1 FROM detection_notebook
|
|
34
|
+
WHERE transport_version = ? AND type = 'repo.git' AND status <> 'deleted' LIMIT 1`),
|
|
35
|
+
payload: database.prepare(`SELECT parent_uuid AS parentUUID FROM detection_notebook
|
|
36
|
+
WHERE payload_version = ? AND status <> 'deleted'
|
|
37
|
+
AND type IN (${PAYLOAD_TYPES.map(type => `'${type}'`).join(", ")})`),
|
|
38
|
+
parent: database.prepare("SELECT parent_uuid AS parentUUID, type FROM detection_notebook WHERE uuid = ?"),
|
|
39
|
+
});
|
|
40
|
+
return found;
|
|
41
|
+
};
|
|
42
|
+
/** One coherent answer for these cached objects: every owner that names one,
|
|
43
|
+
* plus the few record owners whose promises must hold whatever the cache
|
|
44
|
+
* holds. Recovery owners whose full dependency set cannot yet be enumerated
|
|
45
|
+
* refuse pruning (null) rather than borrowing current O. */
|
|
46
|
+
export function readCacheRoots(database, cached) {
|
|
47
|
+
const sql = statements(database);
|
|
48
|
+
return database.transaction(() => {
|
|
49
|
+
if (sql.recovery.get().waiting)
|
|
50
|
+
return null;
|
|
51
|
+
const roots = new Map();
|
|
52
|
+
const add = (hash, repository, requiredLocal) => {
|
|
53
|
+
if (!hash || hash.startsWith("git:"))
|
|
54
|
+
return; // a member object belongs to its repository parcel
|
|
55
|
+
if (!/^[0-9a-f]{64}$/.test(hash))
|
|
56
|
+
throw new Error("Cache owner has an invalid content head");
|
|
57
|
+
retain(roots, hash, repository, requiredLocal);
|
|
58
|
+
};
|
|
59
|
+
const record = (row, required) => {
|
|
60
|
+
if (row.status === "deleted")
|
|
61
|
+
return;
|
|
62
|
+
if (row.type === "repo.git")
|
|
63
|
+
add(row.transportVersion, true, required);
|
|
64
|
+
else if (PAYLOAD_TYPES.includes(row.type))
|
|
65
|
+
add(row.payloadVersion, false, required);
|
|
66
|
+
};
|
|
67
|
+
for (const row of sql.constructs.iterate()) {
|
|
68
|
+
record({ ...row, transportVersion: null }, false);
|
|
69
|
+
}
|
|
70
|
+
for (const row of sql.pending.iterate()) {
|
|
71
|
+
const pending = decodeLocalEntityRecord(row.recordJson);
|
|
72
|
+
record(pending.change.result, true);
|
|
73
|
+
for (const cargo of pending.change.cargo)
|
|
74
|
+
add(cargo.contentHash, cargo.kind === "git", true);
|
|
75
|
+
}
|
|
76
|
+
for (const row of sql.unresolved.iterate()) {
|
|
77
|
+
const accepted = decodeAcceptedEntityRecord(row.recordJson);
|
|
78
|
+
record(accepted.change.result, false);
|
|
79
|
+
for (const cargo of accepted.change.cargo)
|
|
80
|
+
add(cargo.contentHash, cargo.kind === "git", false);
|
|
81
|
+
}
|
|
82
|
+
// A durable baseline may have arrived through cold materialization,
|
|
83
|
+
// which does not promise a second local cache copy. Keep any cached
|
|
84
|
+
// copy; only unpublished Outbox cargo must already exist locally. A
|
|
85
|
+
// repository's transport is its own; a payload counts only outside every
|
|
86
|
+
// repository, whose parcel carries its members.
|
|
87
|
+
const territorial = repositoryTerritory(sql.parent);
|
|
88
|
+
for (const hash of cached) {
|
|
89
|
+
if (sql.transport.get(hash)) {
|
|
90
|
+
add(hash, true, false);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
for (const row of sql.payload.iterate(hash)) {
|
|
94
|
+
if (!territorial(row.parentUUID)) {
|
|
95
|
+
add(hash, false, false);
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return [...roots.values()];
|
|
101
|
+
})();
|
|
102
|
+
}
|
|
103
|
+
/** Whether a child of this node lies in repository territory: the node is a
|
|
104
|
+
* repository or lies in territory itself. A parent outside the notebook is the
|
|
105
|
+
* boundary. Answers are remembered for one read only. */
|
|
106
|
+
function repositoryTerritory(parent) {
|
|
107
|
+
const known = new Map();
|
|
108
|
+
return (start) => {
|
|
109
|
+
const path = new Set();
|
|
110
|
+
let answer = false;
|
|
111
|
+
for (let uuid = start; uuid !== null;) {
|
|
112
|
+
const remembered = known.get(uuid);
|
|
113
|
+
if (remembered !== undefined) {
|
|
114
|
+
answer = remembered;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
if (path.has(uuid))
|
|
118
|
+
throw new Error(`repository territory has a parent cycle at ${uuid}`);
|
|
119
|
+
const node = parent.get(uuid);
|
|
120
|
+
if (!node)
|
|
121
|
+
break;
|
|
122
|
+
path.add(uuid);
|
|
123
|
+
if (node.type === "repo.git") {
|
|
124
|
+
answer = true;
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
uuid = node.parentUUID;
|
|
128
|
+
}
|
|
129
|
+
for (const uuid of path)
|
|
130
|
+
known.set(uuid, answer);
|
|
131
|
+
return answer;
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/** Only dependency facts survive a visit. Verification streams pack bytes;
|
|
135
|
+
* metadata inspection never reconstructs an identity map or opens Git. */
|
|
136
|
+
export async function retainCacheClosure(roots, inspect, current = () => true) {
|
|
137
|
+
const retained = new Set(roots.map(root => root.hash));
|
|
138
|
+
const traversed = new Set();
|
|
139
|
+
for (const root of roots.filter(root => root.repository).sort((a, b) => Number(b.requiredLocal) - Number(a.requiredLocal))) {
|
|
140
|
+
const path = new Set();
|
|
141
|
+
let hash = root.hash;
|
|
142
|
+
while (hash !== null) {
|
|
143
|
+
if (!current())
|
|
144
|
+
return null;
|
|
145
|
+
if (path.has(hash))
|
|
146
|
+
throw new Error("Repository cache ownership has a transport cycle");
|
|
147
|
+
if (traversed.has(hash))
|
|
148
|
+
break;
|
|
149
|
+
path.add(hash);
|
|
150
|
+
retained.add(hash);
|
|
151
|
+
const metadata = await inspect(hash, root.requiredLocal);
|
|
152
|
+
if (!metadata)
|
|
153
|
+
break; // remote-only missing cargo is fetched by its eventual consumer
|
|
154
|
+
hash = metadata.parent;
|
|
155
|
+
}
|
|
156
|
+
for (const visited of path)
|
|
157
|
+
traversed.add(visited);
|
|
158
|
+
}
|
|
159
|
+
return current() ? retained : null;
|
|
160
|
+
}
|
|
161
|
+
/** The cached objects no durable owner retains, proven in short chunks that
|
|
162
|
+
* yield between them. Null defers: a recovery owner exists or the fence moved.
|
|
163
|
+
* An object cached after the listing is never examined, so never deleted. */
|
|
164
|
+
export async function unownedCache(database, cacheDir, current) {
|
|
165
|
+
const cached = [...await listCachedContent(cacheDir)];
|
|
166
|
+
const roots = new Map();
|
|
167
|
+
for (let start = 0; start === 0 || start < cached.length; start += CHUNK) {
|
|
168
|
+
if (start > 0)
|
|
169
|
+
await awaitTurn();
|
|
170
|
+
if (!current())
|
|
171
|
+
return null;
|
|
172
|
+
const found = readCacheRoots(database, cached.slice(start, start + CHUNK));
|
|
173
|
+
if (found === null)
|
|
174
|
+
return null;
|
|
175
|
+
for (const root of found)
|
|
176
|
+
retain(roots, root.hash, root.repository, root.requiredLocal);
|
|
177
|
+
}
|
|
178
|
+
for (const root of roots.values())
|
|
179
|
+
if (root.requiredLocal && !existsSync(join(cacheDir, `${root.hash}.bin`))) {
|
|
180
|
+
throw new Error(`Required local content ${root.hash} is absent; cache cleanup refused`);
|
|
181
|
+
}
|
|
182
|
+
const retained = await retainCacheClosure([...roots.values()], async (hash, required) => {
|
|
183
|
+
const file = join(cacheDir, `${hash}.bin`);
|
|
184
|
+
if (!existsSync(file)) {
|
|
185
|
+
if (required)
|
|
186
|
+
throw new Error(`Required local Git ancestor ${hash} is absent; cache cleanup refused`);
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
if (await hashContentFile(file) !== hash)
|
|
190
|
+
throw new Error("Unverified Git cache metadata cannot authorize cleanup");
|
|
191
|
+
return { parent: (await inspectRepositoryTransportFile(file)).parentTransportVersion };
|
|
192
|
+
}, current);
|
|
193
|
+
return retained === null ? null : { examined: cached.length, unowned: cached.filter(hash => !retained.has(hash)) };
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=content-cache-retention.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-cache-retention.js","sourceRoot":"","sources":["../src/content-cache-retention.ts"],"names":[],"mappings":"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"}
|