@indigoai-us/hq-cloud 6.18.44-alpha.8 → 6.18.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/sync-runner-planning.d.ts +12 -0
- package/dist/bin/sync-runner-planning.d.ts.map +1 -1
- package/dist/bin/sync-runner-planning.js +18 -0
- package/dist/bin/sync-runner-planning.js.map +1 -1
- package/dist/bin/sync-runner-watch-loop.d.ts +18 -0
- package/dist/bin/sync-runner-watch-loop.d.ts.map +1 -1
- package/dist/bin/sync-runner-watch-loop.js +75 -6
- package/dist/bin/sync-runner-watch-loop.js.map +1 -1
- package/dist/bin/sync-runner.d.ts +22 -1
- package/dist/bin/sync-runner.d.ts.map +1 -1
- package/dist/bin/sync-runner.js +33 -4
- package/dist/bin/sync-runner.js.map +1 -1
- package/dist/cli/conflict.d.ts.map +1 -1
- package/dist/cli/conflict.js +2 -1
- package/dist/cli/conflict.js.map +1 -1
- package/dist/cli/rescue-core.d.ts +6 -0
- package/dist/cli/rescue-core.d.ts.map +1 -1
- package/dist/cli/rescue-core.js +10 -1
- package/dist/cli/rescue-core.js.map +1 -1
- package/dist/cli/rescue-windows-test-harness.d.ts +19 -0
- package/dist/cli/rescue-windows-test-harness.d.ts.map +1 -0
- package/dist/cli/rescue-windows-test-harness.js +443 -0
- package/dist/cli/rescue-windows-test-harness.js.map +1 -0
- package/dist/company-resolver.d.ts +22 -0
- package/dist/company-resolver.d.ts.map +1 -1
- package/dist/company-resolver.js +1 -1
- package/dist/company-resolver.js.map +1 -1
- package/dist/ignore.d.ts +4 -1
- package/dist/ignore.d.ts.map +1 -1
- package/dist/ignore.js +10 -12
- package/dist/ignore.js.map +1 -1
- package/dist/journal-snapshot-decoder.js +15 -2
- package/dist/journal-snapshot-decoder.js.map +1 -1
- package/dist/sync/durable-apply.d.ts +2 -0
- package/dist/sync/durable-apply.d.ts.map +1 -1
- package/dist/sync/durable-apply.js +9 -12
- package/dist/sync/durable-apply.js.map +1 -1
- package/dist/sync/fsync-compat.d.ts +13 -0
- package/dist/sync/fsync-compat.d.ts.map +1 -0
- package/dist/sync/fsync-compat.js +33 -0
- package/dist/sync/fsync-compat.js.map +1 -0
- package/dist/sync/multipart-uploader.d.ts.map +1 -1
- package/dist/sync/multipart-uploader.js +2 -1
- package/dist/sync/multipart-uploader.js.map +1 -1
- package/dist/sync/scope-inventory-client.d.ts.map +1 -1
- package/dist/sync/scope-inventory-client.js +7 -2
- package/dist/sync/scope-inventory-client.js.map +1 -1
- package/dist/telemetry.d.ts +31 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +177 -17
- package/dist/telemetry.js.map +1 -1
- package/dist/usage-company-fallback.d.ts +104 -0
- package/dist/usage-company-fallback.d.ts.map +1 -0
- package/dist/usage-company-fallback.js +599 -0
- package/dist/usage-company-fallback.js.map +1 -0
- package/dist/watch-owner-lease.d.ts +3 -0
- package/dist/watch-owner-lease.d.ts.map +1 -1
- package/dist/watch-owner-lease.js +14 -3
- package/dist/watch-owner-lease.js.map +1 -1
- package/package.json +2 -2
- package/dist/active-company.test.d.ts +0 -2
- package/dist/active-company.test.d.ts.map +0 -1
- package/dist/active-company.test.js +0 -149
- package/dist/active-company.test.js.map +0 -1
- package/dist/agent-codex-instructions.test.d.ts +0 -2
- package/dist/agent-codex-instructions.test.d.ts.map +0 -1
- package/dist/agent-codex-instructions.test.js +0 -271
- package/dist/agent-codex-instructions.test.js.map +0 -1
- package/dist/backup-prune.test.d.ts +0 -2
- package/dist/backup-prune.test.d.ts.map +0 -1
- package/dist/backup-prune.test.js +0 -154
- package/dist/backup-prune.test.js.map +0 -1
- package/dist/bandwidth.test.d.ts +0 -2
- package/dist/bandwidth.test.d.ts.map +0 -1
- package/dist/bandwidth.test.js +0 -342
- package/dist/bandwidth.test.js.map +0 -1
- package/dist/best-effort-error.test.d.ts +0 -2
- package/dist/best-effort-error.test.d.ts.map +0 -1
- package/dist/best-effort-error.test.js +0 -54
- package/dist/best-effort-error.test.js.map +0 -1
- package/dist/bin/area-ledger-migration.test.d.ts +0 -2
- package/dist/bin/area-ledger-migration.test.d.ts.map +0 -1
- package/dist/bin/area-ledger-migration.test.js +0 -410
- package/dist/bin/area-ledger-migration.test.js.map +0 -1
- package/dist/bin/backup-prune-runner.test.d.ts +0 -2
- package/dist/bin/backup-prune-runner.test.d.ts.map +0 -1
- package/dist/bin/backup-prune-runner.test.js +0 -22
- package/dist/bin/backup-prune-runner.test.js.map +0 -1
- package/dist/bin/journal-repair.test.d.ts +0 -2
- package/dist/bin/journal-repair.test.d.ts.map +0 -1
- package/dist/bin/journal-repair.test.js +0 -53
- package/dist/bin/journal-repair.test.js.map +0 -1
- package/dist/bin/layout-compatibility.test.d.ts +0 -2
- package/dist/bin/layout-compatibility.test.d.ts.map +0 -1
- package/dist/bin/layout-compatibility.test.js +0 -87
- package/dist/bin/layout-compatibility.test.js.map +0 -1
- package/dist/bin/outpost-heartbeat.test.d.ts +0 -7
- package/dist/bin/outpost-heartbeat.test.d.ts.map +0 -1
- package/dist/bin/outpost-heartbeat.test.js +0 -84
- package/dist/bin/outpost-heartbeat.test.js.map +0 -1
- package/dist/bin/outpost-session-host.test.d.ts +0 -7
- package/dist/bin/outpost-session-host.test.d.ts.map +0 -1
- package/dist/bin/outpost-session-host.test.js +0 -52
- package/dist/bin/outpost-session-host.test.js.map +0 -1
- package/dist/bin/sync-mutation.test.d.ts +0 -2
- package/dist/bin/sync-mutation.test.d.ts.map +0 -1
- package/dist/bin/sync-mutation.test.js +0 -64
- package/dist/bin/sync-mutation.test.js.map +0 -1
- package/dist/bin/sync-runner-args.test.d.ts +0 -2
- package/dist/bin/sync-runner-args.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-args.test.js +0 -82
- package/dist/bin/sync-runner-args.test.js.map +0 -1
- package/dist/bin/sync-runner-auth-wait.test.d.ts +0 -2
- package/dist/bin/sync-runner-auth-wait.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-auth-wait.test.js +0 -406
- package/dist/bin/sync-runner-auth-wait.test.js.map +0 -1
- package/dist/bin/sync-runner-backoff.regression.test.d.ts +0 -29
- package/dist/bin/sync-runner-backoff.regression.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-backoff.regression.test.js +0 -224
- package/dist/bin/sync-runner-backoff.regression.test.js.map +0 -1
- package/dist/bin/sync-runner-company.test.d.ts +0 -2
- package/dist/bin/sync-runner-company.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-company.test.js +0 -2439
- package/dist/bin/sync-runner-company.test.js.map +0 -1
- package/dist/bin/sync-runner-delete-snapshot-mixed.bench.test.d.ts +0 -2
- package/dist/bin/sync-runner-delete-snapshot-mixed.bench.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-delete-snapshot-mixed.bench.test.js +0 -648
- package/dist/bin/sync-runner-delete-snapshot-mixed.bench.test.js.map +0 -1
- package/dist/bin/sync-runner-delete-snapshot.bench.test.d.ts +0 -2
- package/dist/bin/sync-runner-delete-snapshot.bench.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-delete-snapshot.bench.test.js +0 -329
- package/dist/bin/sync-runner-delete-snapshot.bench.test.js.map +0 -1
- package/dist/bin/sync-runner-events.test.d.ts +0 -2
- package/dist/bin/sync-runner-events.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-events.test.js +0 -364
- package/dist/bin/sync-runner-events.test.js.map +0 -1
- package/dist/bin/sync-runner-heap-telemetry.test.d.ts +0 -2
- package/dist/bin/sync-runner-heap-telemetry.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-heap-telemetry.test.js +0 -1966
- package/dist/bin/sync-runner-heap-telemetry.test.js.map +0 -1
- package/dist/bin/sync-runner-manifest.test.d.ts +0 -12
- package/dist/bin/sync-runner-manifest.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-manifest.test.js +0 -921
- package/dist/bin/sync-runner-manifest.test.js.map +0 -1
- package/dist/bin/sync-runner-planning.test.d.ts +0 -2
- package/dist/bin/sync-runner-planning.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-planning.test.js +0 -448
- package/dist/bin/sync-runner-planning.test.js.map +0 -1
- package/dist/bin/sync-runner-post-sync-flags.test.d.ts +0 -2
- package/dist/bin/sync-runner-post-sync-flags.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-post-sync-flags.test.js +0 -64
- package/dist/bin/sync-runner-post-sync-flags.test.js.map +0 -1
- package/dist/bin/sync-runner-publish-expansion.test.d.ts +0 -2
- package/dist/bin/sync-runner-publish-expansion.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-publish-expansion.test.js +0 -54
- package/dist/bin/sync-runner-publish-expansion.test.js.map +0 -1
- package/dist/bin/sync-runner-receiver-unresolved-company.test.d.ts +0 -2
- package/dist/bin/sync-runner-receiver-unresolved-company.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-receiver-unresolved-company.test.js +0 -379
- package/dist/bin/sync-runner-receiver-unresolved-company.test.js.map +0 -1
- package/dist/bin/sync-runner-rollup.test.d.ts +0 -2
- package/dist/bin/sync-runner-rollup.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-rollup.test.js +0 -24
- package/dist/bin/sync-runner-rollup.test.js.map +0 -1
- package/dist/bin/sync-runner-watch-loop.test.d.ts +0 -2
- package/dist/bin/sync-runner-watch-loop.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-watch-loop.test.js +0 -734
- package/dist/bin/sync-runner-watch-loop.test.js.map +0 -1
- package/dist/bin/sync-runner-watch-routes.test.d.ts +0 -2
- package/dist/bin/sync-runner-watch-routes.test.d.ts.map +0 -1
- package/dist/bin/sync-runner-watch-routes.test.js +0 -181
- package/dist/bin/sync-runner-watch-routes.test.js.map +0 -1
- package/dist/bin/sync-runner.test.d.ts +0 -10
- package/dist/bin/sync-runner.test.d.ts.map +0 -1
- package/dist/bin/sync-runner.test.js +0 -18984
- package/dist/bin/sync-runner.test.js.map +0 -1
- package/dist/cli/case-alias.test.d.ts +0 -2
- package/dist/cli/case-alias.test.d.ts.map +0 -1
- package/dist/cli/case-alias.test.js +0 -96
- package/dist/cli/case-alias.test.js.map +0 -1
- package/dist/cli/conflict-recovery.test.d.ts +0 -2
- package/dist/cli/conflict-recovery.test.d.ts.map +0 -1
- package/dist/cli/conflict-recovery.test.js +0 -201
- package/dist/cli/conflict-recovery.test.js.map +0 -1
- package/dist/cli/conflict-winner.test.d.ts +0 -7
- package/dist/cli/conflict-winner.test.d.ts.map +0 -1
- package/dist/cli/conflict-winner.test.js +0 -98
- package/dist/cli/conflict-winner.test.js.map +0 -1
- package/dist/cli/doctor.test.d.ts +0 -13
- package/dist/cli/doctor.test.d.ts.map +0 -1
- package/dist/cli/doctor.test.js +0 -607
- package/dist/cli/doctor.test.js.map +0 -1
- package/dist/cli/invite.test.d.ts +0 -5
- package/dist/cli/invite.test.d.ts.map +0 -1
- package/dist/cli/invite.test.js +0 -178
- package/dist/cli/invite.test.js.map +0 -1
- package/dist/cli/onepass-pull-planner-regressions.test.d.ts +0 -2
- package/dist/cli/onepass-pull-planner-regressions.test.d.ts.map +0 -1
- package/dist/cli/onepass-pull-planner-regressions.test.js +0 -300
- package/dist/cli/onepass-pull-planner-regressions.test.js.map +0 -1
- package/dist/cli/onepass-pull-planner.test.d.ts +0 -2
- package/dist/cli/onepass-pull-planner.test.d.ts.map +0 -1
- package/dist/cli/onepass-pull-planner.test.js +0 -266
- package/dist/cli/onepass-pull-planner.test.js.map +0 -1
- package/dist/cli/push-scan-exclusions.test.d.ts +0 -2
- package/dist/cli/push-scan-exclusions.test.d.ts.map +0 -1
- package/dist/cli/push-scan-exclusions.test.js +0 -99
- package/dist/cli/push-scan-exclusions.test.js.map +0 -1
- package/dist/cli/reindex-knowledge.test.d.ts +0 -12
- package/dist/cli/reindex-knowledge.test.d.ts.map +0 -1
- package/dist/cli/reindex-knowledge.test.js +0 -260
- package/dist/cli/reindex-knowledge.test.js.map +0 -1
- package/dist/cli/reindex.test.d.ts +0 -11
- package/dist/cli/reindex.test.d.ts.map +0 -1
- package/dist/cli/reindex.test.js +0 -811
- package/dist/cli/reindex.test.js.map +0 -1
- package/dist/cli/rescue-breaker.test.d.ts +0 -2
- package/dist/cli/rescue-breaker.test.d.ts.map +0 -1
- package/dist/cli/rescue-breaker.test.js +0 -812
- package/dist/cli/rescue-breaker.test.js.map +0 -1
- package/dist/cli/rescue-classify-ordering.test.d.ts +0 -2
- package/dist/cli/rescue-classify-ordering.test.d.ts.map +0 -1
- package/dist/cli/rescue-classify-ordering.test.js +0 -500
- package/dist/cli/rescue-classify-ordering.test.js.map +0 -1
- package/dist/cli/rescue-clone-diagnostics.test.d.ts +0 -2
- package/dist/cli/rescue-clone-diagnostics.test.d.ts.map +0 -1
- package/dist/cli/rescue-clone-diagnostics.test.js +0 -101
- package/dist/cli/rescue-clone-diagnostics.test.js.map +0 -1
- package/dist/cli/rescue-clone-network-retry.test.d.ts +0 -2
- package/dist/cli/rescue-clone-network-retry.test.d.ts.map +0 -1
- package/dist/cli/rescue-clone-network-retry.test.js +0 -415
- package/dist/cli/rescue-clone-network-retry.test.js.map +0 -1
- package/dist/cli/rescue-core-stamp.test.d.ts +0 -2
- package/dist/cli/rescue-core-stamp.test.d.ts.map +0 -1
- package/dist/cli/rescue-core-stamp.test.js +0 -364
- package/dist/cli/rescue-core-stamp.test.js.map +0 -1
- package/dist/cli/rescue-drift-reconcile.test.d.ts +0 -2
- package/dist/cli/rescue-drift-reconcile.test.d.ts.map +0 -1
- package/dist/cli/rescue-drift-reconcile.test.js +0 -162
- package/dist/cli/rescue-drift-reconcile.test.js.map +0 -1
- package/dist/cli/rescue-drop-dir-symlink.test.d.ts +0 -2
- package/dist/cli/rescue-drop-dir-symlink.test.d.ts.map +0 -1
- package/dist/cli/rescue-drop-dir-symlink.test.js +0 -255
- package/dist/cli/rescue-drop-dir-symlink.test.js.map +0 -1
- package/dist/cli/rescue-exec-bit-preserve.test.d.ts +0 -2
- package/dist/cli/rescue-exec-bit-preserve.test.d.ts.map +0 -1
- package/dist/cli/rescue-exec-bit-preserve.test.js +0 -177
- package/dist/cli/rescue-exec-bit-preserve.test.js.map +0 -1
- package/dist/cli/rescue-hq-root-guard.test.d.ts +0 -2
- package/dist/cli/rescue-hq-root-guard.test.d.ts.map +0 -1
- package/dist/cli/rescue-hq-root-guard.test.js +0 -210
- package/dist/cli/rescue-hq-root-guard.test.js.map +0 -1
- package/dist/cli/rescue-journal-reconcile.test.d.ts +0 -2
- package/dist/cli/rescue-journal-reconcile.test.d.ts.map +0 -1
- package/dist/cli/rescue-journal-reconcile.test.js +0 -186
- package/dist/cli/rescue-journal-reconcile.test.js.map +0 -1
- package/dist/cli/rescue-keep-local-ignore.test.d.ts +0 -2
- package/dist/cli/rescue-keep-local-ignore.test.d.ts.map +0 -1
- package/dist/cli/rescue-keep-local-ignore.test.js +0 -315
- package/dist/cli/rescue-keep-local-ignore.test.js.map +0 -1
- package/dist/cli/rescue-move.test.d.ts +0 -2
- package/dist/cli/rescue-move.test.d.ts.map +0 -1
- package/dist/cli/rescue-move.test.js +0 -166
- package/dist/cli/rescue-move.test.js.map +0 -1
- package/dist/cli/rescue-mtime-preserve.test.d.ts +0 -2
- package/dist/cli/rescue-mtime-preserve.test.d.ts.map +0 -1
- package/dist/cli/rescue-mtime-preserve.test.js +0 -186
- package/dist/cli/rescue-mtime-preserve.test.js.map +0 -1
- package/dist/cli/rescue-preserve-copy-symlink.test.d.ts +0 -2
- package/dist/cli/rescue-preserve-copy-symlink.test.d.ts.map +0 -1
- package/dist/cli/rescue-preserve-copy-symlink.test.js +0 -483
- package/dist/cli/rescue-preserve-copy-symlink.test.js.map +0 -1
- package/dist/cli/rescue-realpath.test.d.ts +0 -2
- package/dist/cli/rescue-realpath.test.d.ts.map +0 -1
- package/dist/cli/rescue-realpath.test.js +0 -109
- package/dist/cli/rescue-realpath.test.js.map +0 -1
- package/dist/cli/rescue-restore-flag.test.d.ts +0 -2
- package/dist/cli/rescue-restore-flag.test.d.ts.map +0 -1
- package/dist/cli/rescue-restore-flag.test.js +0 -82
- package/dist/cli/rescue-restore-flag.test.js.map +0 -1
- package/dist/cli/rescue-rsync-preflight.test.d.ts +0 -2
- package/dist/cli/rescue-rsync-preflight.test.d.ts.map +0 -1
- package/dist/cli/rescue-rsync-preflight.test.js +0 -579
- package/dist/cli/rescue-rsync-preflight.test.js.map +0 -1
- package/dist/cli/rescue-rsync-status.test.d.ts +0 -2
- package/dist/cli/rescue-rsync-status.test.d.ts.map +0 -1
- package/dist/cli/rescue-rsync-status.test.js +0 -406
- package/dist/cli/rescue-rsync-status.test.js.map +0 -1
- package/dist/cli/rescue-settings-reconcile.test.d.ts +0 -2
- package/dist/cli/rescue-settings-reconcile.test.d.ts.map +0 -1
- package/dist/cli/rescue-settings-reconcile.test.js +0 -610
- package/dist/cli/rescue-settings-reconcile.test.js.map +0 -1
- package/dist/cli/rescue-snapshot-copy.test.d.ts +0 -2
- package/dist/cli/rescue-snapshot-copy.test.d.ts.map +0 -1
- package/dist/cli/rescue-snapshot-copy.test.js +0 -790
- package/dist/cli/rescue-snapshot-copy.test.js.map +0 -1
- package/dist/cli/rescue-snapshot-recovery.test.d.ts +0 -2
- package/dist/cli/rescue-snapshot-recovery.test.d.ts.map +0 -1
- package/dist/cli/rescue-snapshot-recovery.test.js +0 -265
- package/dist/cli/rescue-snapshot-recovery.test.js.map +0 -1
- package/dist/cli/rescue-snapshot.test.d.ts +0 -2
- package/dist/cli/rescue-snapshot.test.d.ts.map +0 -1
- package/dist/cli/rescue-snapshot.test.js +0 -46
- package/dist/cli/rescue-snapshot.test.js.map +0 -1
- package/dist/cli/rescue-source-switch-floor.test.d.ts +0 -2
- package/dist/cli/rescue-source-switch-floor.test.d.ts.map +0 -1
- package/dist/cli/rescue-source-switch-floor.test.js +0 -247
- package/dist/cli/rescue-source-switch-floor.test.js.map +0 -1
- package/dist/cli/rescue-unchanged-delete.test.d.ts +0 -2
- package/dist/cli/rescue-unchanged-delete.test.d.ts.map +0 -1
- package/dist/cli/rescue-unchanged-delete.test.js +0 -305
- package/dist/cli/rescue-unchanged-delete.test.js.map +0 -1
- package/dist/cli/rescue.reindex.test.d.ts +0 -2
- package/dist/cli/rescue.reindex.test.d.ts.map +0 -1
- package/dist/cli/rescue.reindex.test.js +0 -72
- package/dist/cli/rescue.reindex.test.js.map +0 -1
- package/dist/cli/rescue.test.d.ts +0 -2
- package/dist/cli/rescue.test.d.ts.map +0 -1
- package/dist/cli/rescue.test.js +0 -127
- package/dist/cli/rescue.test.js.map +0 -1
- package/dist/cli/share-plan-limit-presign.test.d.ts +0 -2
- package/dist/cli/share-plan-limit-presign.test.d.ts.map +0 -1
- package/dist/cli/share-plan-limit-presign.test.js +0 -271
- package/dist/cli/share-plan-limit-presign.test.js.map +0 -1
- package/dist/cli/share-presign-transport.test.d.ts +0 -22
- package/dist/cli/share-presign-transport.test.d.ts.map +0 -1
- package/dist/cli/share-presign-transport.test.js +0 -388
- package/dist/cli/share-presign-transport.test.js.map +0 -1
- package/dist/cli/share.test.d.ts +0 -5
- package/dist/cli/share.test.d.ts.map +0 -1
- package/dist/cli/share.test.js +0 -12335
- package/dist/cli/share.test.js.map +0 -1
- package/dist/cli/streaming-pull-planner.bench.test.d.ts +0 -15
- package/dist/cli/streaming-pull-planner.bench.test.d.ts.map +0 -1
- package/dist/cli/streaming-pull-planner.bench.test.js +0 -273
- package/dist/cli/streaming-pull-planner.bench.test.js.map +0 -1
- package/dist/cli/sync-scope.test.d.ts +0 -22
- package/dist/cli/sync-scope.test.d.ts.map +0 -1
- package/dist/cli/sync-scope.test.js +0 -903
- package/dist/cli/sync-scope.test.js.map +0 -1
- package/dist/cli/sync.test.d.ts +0 -5
- package/dist/cli/sync.test.d.ts.map +0 -1
- package/dist/cli/sync.test.js +0 -9028
- package/dist/cli/sync.test.js.map +0 -1
- package/dist/cli/tombstones.test.d.ts +0 -2
- package/dist/cli/tombstones.test.d.ts.map +0 -1
- package/dist/cli/tombstones.test.js +0 -120
- package/dist/cli/tombstones.test.js.map +0 -1
- package/dist/cli/watch-event-push-conflict.test.d.ts +0 -25
- package/dist/cli/watch-event-push-conflict.test.d.ts.map +0 -1
- package/dist/cli/watch-event-push-conflict.test.js +0 -230
- package/dist/cli/watch-event-push-conflict.test.js.map +0 -1
- package/dist/client-info.test.d.ts +0 -11
- package/dist/client-info.test.d.ts.map +0 -1
- package/dist/client-info.test.js +0 -168
- package/dist/client-info.test.js.map +0 -1
- package/dist/cognito-auth-lock-no-hard-links.test.d.ts +0 -11
- package/dist/cognito-auth-lock-no-hard-links.test.d.ts.map +0 -1
- package/dist/cognito-auth-lock-no-hard-links.test.js +0 -76
- package/dist/cognito-auth-lock-no-hard-links.test.js.map +0 -1
- package/dist/cognito-auth.test.d.ts +0 -9
- package/dist/cognito-auth.test.d.ts.map +0 -1
- package/dist/cognito-auth.test.js +0 -745
- package/dist/cognito-auth.test.js.map +0 -1
- package/dist/company-resolver.test.d.ts +0 -7
- package/dist/company-resolver.test.d.ts.map +0 -1
- package/dist/company-resolver.test.js +0 -533
- package/dist/company-resolver.test.js.map +0 -1
- package/dist/company-slug.test.d.ts +0 -7
- package/dist/company-slug.test.d.ts.map +0 -1
- package/dist/company-slug.test.js +0 -43
- package/dist/company-slug.test.js.map +0 -1
- package/dist/company-vault-transport.test.d.ts +0 -12
- package/dist/company-vault-transport.test.d.ts.map +0 -1
- package/dist/company-vault-transport.test.js +0 -97
- package/dist/company-vault-transport.test.js.map +0 -1
- package/dist/context.test.d.ts +0 -7
- package/dist/context.test.d.ts.map +0 -1
- package/dist/context.test.js +0 -646
- package/dist/context.test.js.map +0 -1
- package/dist/entity-resolver.test.d.ts +0 -10
- package/dist/entity-resolver.test.d.ts.map +0 -1
- package/dist/entity-resolver.test.js +0 -244
- package/dist/entity-resolver.test.js.map +0 -1
- package/dist/getindigo-dead-refs-contract.test.d.ts +0 -2
- package/dist/getindigo-dead-refs-contract.test.d.ts.map +0 -1
- package/dist/getindigo-dead-refs-contract.test.js +0 -58
- package/dist/getindigo-dead-refs-contract.test.js.map +0 -1
- package/dist/hermetic-test-env.test.d.ts +0 -2
- package/dist/hermetic-test-env.test.d.ts.map +0 -1
- package/dist/hermetic-test-env.test.js +0 -61
- package/dist/hermetic-test-env.test.js.map +0 -1
- package/dist/hq-root-recovery.test.d.ts +0 -2
- package/dist/hq-root-recovery.test.d.ts.map +0 -1
- package/dist/hq-root-recovery.test.js +0 -65
- package/dist/hq-root-recovery.test.js.map +0 -1
- package/dist/ignore.test.d.ts +0 -10
- package/dist/ignore.test.d.ts.map +0 -1
- package/dist/ignore.test.js +0 -926
- package/dist/ignore.test.js.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/dist/index.test.js +0 -26
- package/dist/index.test.js.map +0 -1
- package/dist/journal-area-ledger-read-boundary.test.d.ts +0 -2
- package/dist/journal-area-ledger-read-boundary.test.d.ts.map +0 -1
- package/dist/journal-area-ledger-read-boundary.test.js +0 -420
- package/dist/journal-area-ledger-read-boundary.test.js.map +0 -1
- package/dist/journal-baseline.test.d.ts +0 -2
- package/dist/journal-baseline.test.d.ts.map +0 -1
- package/dist/journal-baseline.test.js +0 -218
- package/dist/journal-baseline.test.js.map +0 -1
- package/dist/journal-decode-window.test.d.ts +0 -2
- package/dist/journal-decode-window.test.d.ts.map +0 -1
- package/dist/journal-decode-window.test.js +0 -99
- package/dist/journal-decode-window.test.js.map +0 -1
- package/dist/journal-delta-writes.test.d.ts +0 -2
- package/dist/journal-delta-writes.test.d.ts.map +0 -1
- package/dist/journal-delta-writes.test.js +0 -159
- package/dist/journal-delta-writes.test.js.map +0 -1
- package/dist/journal-ledger-index.test.d.ts +0 -15
- package/dist/journal-ledger-index.test.d.ts.map +0 -1
- package/dist/journal-ledger-index.test.js +0 -269
- package/dist/journal-ledger-index.test.js.map +0 -1
- package/dist/journal-public-boundary.test.d.ts +0 -2
- package/dist/journal-public-boundary.test.d.ts.map +0 -1
- package/dist/journal-public-boundary.test.js +0 -216
- package/dist/journal-public-boundary.test.js.map +0 -1
- package/dist/journal-row-store.test.d.ts +0 -2
- package/dist/journal-row-store.test.d.ts.map +0 -1
- package/dist/journal-row-store.test.js +0 -729
- package/dist/journal-row-store.test.js.map +0 -1
- package/dist/journal-snapshot-memory-helpers.d.ts +0 -33
- package/dist/journal-snapshot-memory-helpers.d.ts.map +0 -1
- package/dist/journal-snapshot-memory-helpers.js +0 -212
- package/dist/journal-snapshot-memory-helpers.js.map +0 -1
- package/dist/journal-snapshot-memory.test.d.ts +0 -2
- package/dist/journal-snapshot-memory.test.d.ts.map +0 -1
- package/dist/journal-snapshot-memory.test.js +0 -47
- package/dist/journal-snapshot-memory.test.js.map +0 -1
- package/dist/journal-snapshot-v4-memory.test.d.ts +0 -2
- package/dist/journal-snapshot-v4-memory.test.d.ts.map +0 -1
- package/dist/journal-snapshot-v4-memory.test.js +0 -24
- package/dist/journal-snapshot-v4-memory.test.js.map +0 -1
- package/dist/journal-snapshot-v4-writer-memory.test.d.ts +0 -2
- package/dist/journal-snapshot-v4-writer-memory.test.d.ts.map +0 -1
- package/dist/journal-snapshot-v4-writer-memory.test.js +0 -76
- package/dist/journal-snapshot-v4-writer-memory.test.js.map +0 -1
- package/dist/journal-snapshot-v4-writer.test.d.ts +0 -2
- package/dist/journal-snapshot-v4-writer.test.d.ts.map +0 -1
- package/dist/journal-snapshot-v4-writer.test.js +0 -282
- package/dist/journal-snapshot-v4-writer.test.js.map +0 -1
- package/dist/journal-snapshot-v4.test.d.ts +0 -2
- package/dist/journal-snapshot-v4.test.d.ts.map +0 -1
- package/dist/journal-snapshot-v4.test.js +0 -281
- package/dist/journal-snapshot-v4.test.js.map +0 -1
- package/dist/journal-store.test.d.ts +0 -2
- package/dist/journal-store.test.d.ts.map +0 -1
- package/dist/journal-store.test.js +0 -1227
- package/dist/journal-store.test.js.map +0 -1
- package/dist/journal-streaming.heap.test.d.ts +0 -2
- package/dist/journal-streaming.heap.test.d.ts.map +0 -1
- package/dist/journal-streaming.heap.test.js +0 -190
- package/dist/journal-streaming.heap.test.js.map +0 -1
- package/dist/journal.test.d.ts +0 -9
- package/dist/journal.test.d.ts.map +0 -1
- package/dist/journal.test.js +0 -1074
- package/dist/journal.test.js.map +0 -1
- package/dist/kms10-etag-safe-pull.test.d.ts +0 -2
- package/dist/kms10-etag-safe-pull.test.d.ts.map +0 -1
- package/dist/kms10-etag-safe-pull.test.js +0 -53
- package/dist/kms10-etag-safe-pull.test.js.map +0 -1
- package/dist/lib/cloud-authoritative.test.d.ts +0 -2
- package/dist/lib/cloud-authoritative.test.d.ts.map +0 -1
- package/dist/lib/cloud-authoritative.test.js +0 -42
- package/dist/lib/cloud-authoritative.test.js.map +0 -1
- package/dist/lib/conflict-reconcile.test.d.ts +0 -7
- package/dist/lib/conflict-reconcile.test.d.ts.map +0 -1
- package/dist/lib/conflict-reconcile.test.js +0 -246
- package/dist/lib/conflict-reconcile.test.js.map +0 -1
- package/dist/lib/conflict.test.d.ts +0 -9
- package/dist/lib/conflict.test.d.ts.map +0 -1
- package/dist/lib/conflict.test.js +0 -340
- package/dist/lib/conflict.test.js.map +0 -1
- package/dist/lib/describe-error.test.d.ts +0 -2
- package/dist/lib/describe-error.test.d.ts.map +0 -1
- package/dist/lib/describe-error.test.js +0 -148
- package/dist/lib/describe-error.test.js.map +0 -1
- package/dist/lib/machine-id.test.d.ts +0 -8
- package/dist/lib/machine-id.test.d.ts.map +0 -1
- package/dist/lib/machine-id.test.js +0 -228
- package/dist/lib/machine-id.test.js.map +0 -1
- package/dist/lib/net-errors.test.d.ts +0 -2
- package/dist/lib/net-errors.test.d.ts.map +0 -1
- package/dist/lib/net-errors.test.js +0 -111
- package/dist/lib/net-errors.test.js.map +0 -1
- package/dist/lib/ontology-entity-meta.test.d.ts +0 -2
- package/dist/lib/ontology-entity-meta.test.d.ts.map +0 -1
- package/dist/lib/ontology-entity-meta.test.js +0 -79
- package/dist/lib/ontology-entity-meta.test.js.map +0 -1
- package/dist/lib/ontology-entity-push.test.d.ts +0 -2
- package/dist/lib/ontology-entity-push.test.d.ts.map +0 -1
- package/dist/lib/ontology-entity-push.test.js +0 -156
- package/dist/lib/ontology-entity-push.test.js.map +0 -1
- package/dist/lib/personal-connector-settings-sync.test.d.ts +0 -2
- package/dist/lib/personal-connector-settings-sync.test.d.ts.map +0 -1
- package/dist/lib/personal-connector-settings-sync.test.js +0 -34
- package/dist/lib/personal-connector-settings-sync.test.js.map +0 -1
- package/dist/lib/readlink-safe.test.d.ts +0 -2
- package/dist/lib/readlink-safe.test.d.ts.map +0 -1
- package/dist/lib/readlink-safe.test.js +0 -34
- package/dist/lib/readlink-safe.test.js.map +0 -1
- package/dist/lib/s3-content-checksum.test.d.ts +0 -2
- package/dist/lib/s3-content-checksum.test.d.ts.map +0 -1
- package/dist/lib/s3-content-checksum.test.js +0 -26
- package/dist/lib/s3-content-checksum.test.js.map +0 -1
- package/dist/lib/skill-register-landed-bytes.test.d.ts +0 -2
- package/dist/lib/skill-register-landed-bytes.test.d.ts.map +0 -1
- package/dist/lib/skill-register-landed-bytes.test.js +0 -83
- package/dist/lib/skill-register-landed-bytes.test.js.map +0 -1
- package/dist/local-path-codec.test.d.ts +0 -14
- package/dist/local-path-codec.test.d.ts.map +0 -1
- package/dist/local-path-codec.test.js +0 -122
- package/dist/local-path-codec.test.js.map +0 -1
- package/dist/machine-auth.test.d.ts +0 -14
- package/dist/machine-auth.test.d.ts.map +0 -1
- package/dist/machine-auth.test.js +0 -1482
- package/dist/machine-auth.test.js.map +0 -1
- package/dist/machine-token-cache-isolation.test.d.ts +0 -24
- package/dist/machine-token-cache-isolation.test.d.ts.map +0 -1
- package/dist/machine-token-cache-isolation.test.js +0 -284
- package/dist/machine-token-cache-isolation.test.js.map +0 -1
- package/dist/manifest/US-002.acceptance.test.d.ts +0 -11
- package/dist/manifest/US-002.acceptance.test.d.ts.map +0 -1
- package/dist/manifest/US-002.acceptance.test.js +0 -160
- package/dist/manifest/US-002.acceptance.test.js.map +0 -1
- package/dist/manifest/US-004.acceptance.test.d.ts +0 -12
- package/dist/manifest/US-004.acceptance.test.d.ts.map +0 -1
- package/dist/manifest/US-004.acceptance.test.js +0 -173
- package/dist/manifest/US-004.acceptance.test.js.map +0 -1
- package/dist/manifest/build-manifest-resident-parity.test.d.ts +0 -2
- package/dist/manifest/build-manifest-resident-parity.test.d.ts.map +0 -1
- package/dist/manifest/build-manifest-resident-parity.test.js +0 -69
- package/dist/manifest/build-manifest-resident-parity.test.js.map +0 -1
- package/dist/manifest/build-manifest.bench.test.d.ts +0 -22
- package/dist/manifest/build-manifest.bench.test.d.ts.map +0 -1
- package/dist/manifest/build-manifest.bench.test.js +0 -930
- package/dist/manifest/build-manifest.bench.test.js.map +0 -1
- package/dist/manifest/build-manifest.test.d.ts +0 -10
- package/dist/manifest/build-manifest.test.d.ts.map +0 -1
- package/dist/manifest/build-manifest.test.js +0 -1217
- package/dist/manifest/build-manifest.test.js.map +0 -1
- package/dist/manifest/contract.test.d.ts +0 -17
- package/dist/manifest/contract.test.d.ts.map +0 -1
- package/dist/manifest/contract.test.js +0 -346
- package/dist/manifest/contract.test.js.map +0 -1
- package/dist/manifest/import-graph.test.d.ts +0 -25
- package/dist/manifest/import-graph.test.d.ts.map +0 -1
- package/dist/manifest/import-graph.test.js +0 -120
- package/dist/manifest/import-graph.test.js.map +0 -1
- package/dist/manifest/ledger-shard-isolation.test.d.ts +0 -18
- package/dist/manifest/ledger-shard-isolation.test.d.ts.map +0 -1
- package/dist/manifest/ledger-shard-isolation.test.js +0 -153
- package/dist/manifest/ledger-shard-isolation.test.js.map +0 -1
- package/dist/manifest/snapshot-store.test.d.ts +0 -11
- package/dist/manifest/snapshot-store.test.d.ts.map +0 -1
- package/dist/manifest/snapshot-store.test.js +0 -206
- package/dist/manifest/snapshot-store.test.js.map +0 -1
- package/dist/manifest/upload-manifest.test.d.ts +0 -10
- package/dist/manifest/upload-manifest.test.d.ts.map +0 -1
- package/dist/manifest/upload-manifest.test.js +0 -1335
- package/dist/manifest/upload-manifest.test.js.map +0 -1
- package/dist/manifest-reconcile.test.d.ts +0 -2
- package/dist/manifest-reconcile.test.d.ts.map +0 -1
- package/dist/manifest-reconcile.test.js +0 -1029
- package/dist/manifest-reconcile.test.js.map +0 -1
- package/dist/object-io.test.d.ts +0 -11
- package/dist/object-io.test.d.ts.map +0 -1
- package/dist/object-io.test.js +0 -2376
- package/dist/object-io.test.js.map +0 -1
- package/dist/operation-lock.test.d.ts +0 -5
- package/dist/operation-lock.test.d.ts.map +0 -1
- package/dist/operation-lock.test.js +0 -796
- package/dist/operation-lock.test.js.map +0 -1
- package/dist/outcome-telemetry.test.d.ts +0 -9
- package/dist/outcome-telemetry.test.d.ts.map +0 -1
- package/dist/outcome-telemetry.test.js +0 -663
- package/dist/outcome-telemetry.test.js.map +0 -1
- package/dist/outposts/client.test.d.ts +0 -9
- package/dist/outposts/client.test.d.ts.map +0 -1
- package/dist/outposts/client.test.js +0 -415
- package/dist/outposts/client.test.js.map +0 -1
- package/dist/outposts/command.test.d.ts +0 -18
- package/dist/outposts/command.test.d.ts.map +0 -1
- package/dist/outposts/command.test.js +0 -1230
- package/dist/outposts/command.test.js.map +0 -1
- package/dist/outposts/replica-sync.test.d.ts +0 -2
- package/dist/outposts/replica-sync.test.d.ts.map +0 -1
- package/dist/outposts/replica-sync.test.js +0 -224
- package/dist/outposts/replica-sync.test.js.map +0 -1
- package/dist/outposts/self-deploy.test.d.ts +0 -2
- package/dist/outposts/self-deploy.test.d.ts.map +0 -1
- package/dist/outposts/self-deploy.test.js +0 -218
- package/dist/outposts/self-deploy.test.js.map +0 -1
- package/dist/outposts/session-heartbeat-bounds.test.d.ts +0 -25
- package/dist/outposts/session-heartbeat-bounds.test.d.ts.map +0 -1
- package/dist/outposts/session-heartbeat-bounds.test.js +0 -156
- package/dist/outposts/session-heartbeat-bounds.test.js.map +0 -1
- package/dist/outposts/session-heartbeat-guard.test.d.ts +0 -16
- package/dist/outposts/session-heartbeat-guard.test.d.ts.map +0 -1
- package/dist/outposts/session-heartbeat-guard.test.js +0 -88
- package/dist/outposts/session-heartbeat-guard.test.js.map +0 -1
- package/dist/outposts/session-heartbeat-publisher.test.d.ts +0 -10
- package/dist/outposts/session-heartbeat-publisher.test.d.ts.map +0 -1
- package/dist/outposts/session-heartbeat-publisher.test.js +0 -153
- package/dist/outposts/session-heartbeat-publisher.test.js.map +0 -1
- package/dist/outposts/session-heartbeat-retain-guard.test.d.ts +0 -18
- package/dist/outposts/session-heartbeat-retain-guard.test.d.ts.map +0 -1
- package/dist/outposts/session-heartbeat-retain-guard.test.js +0 -106
- package/dist/outposts/session-heartbeat-retain-guard.test.js.map +0 -1
- package/dist/outposts/session-heartbeat-scan.test.d.ts +0 -20
- package/dist/outposts/session-heartbeat-scan.test.d.ts.map +0 -1
- package/dist/outposts/session-heartbeat-scan.test.js +0 -241
- package/dist/outposts/session-heartbeat-scan.test.js.map +0 -1
- package/dist/outposts/session-heartbeat.test.d.ts +0 -11
- package/dist/outposts/session-heartbeat.test.d.ts.map +0 -1
- package/dist/outposts/session-heartbeat.test.js +0 -370
- package/dist/outposts/session-heartbeat.test.js.map +0 -1
- package/dist/outposts/session-host-auth.test.d.ts +0 -16
- package/dist/outposts/session-host-auth.test.d.ts.map +0 -1
- package/dist/outposts/session-host-auth.test.js +0 -284
- package/dist/outposts/session-host-auth.test.js.map +0 -1
- package/dist/outposts/session-host-command.test.d.ts +0 -10
- package/dist/outposts/session-host-command.test.d.ts.map +0 -1
- package/dist/outposts/session-host-command.test.js +0 -180
- package/dist/outposts/session-host-command.test.js.map +0 -1
- package/dist/outposts/session-host-connection.test.d.ts +0 -18
- package/dist/outposts/session-host-connection.test.d.ts.map +0 -1
- package/dist/outposts/session-host-connection.test.js +0 -392
- package/dist/outposts/session-host-connection.test.js.map +0 -1
- package/dist/outposts/session-host-fakes.d.ts +0 -61
- package/dist/outposts/session-host-fakes.d.ts.map +0 -1
- package/dist/outposts/session-host-fakes.js +0 -115
- package/dist/outposts/session-host-fakes.js.map +0 -1
- package/dist/outposts/session-host-ndjson.test.d.ts +0 -11
- package/dist/outposts/session-host-ndjson.test.d.ts.map +0 -1
- package/dist/outposts/session-host-ndjson.test.js +0 -73
- package/dist/outposts/session-host-ndjson.test.js.map +0 -1
- package/dist/outposts/session-host-protocol.test.d.ts +0 -15
- package/dist/outposts/session-host-protocol.test.d.ts.map +0 -1
- package/dist/outposts/session-host-protocol.test.js +0 -0
- package/dist/outposts/session-host-protocol.test.js.map +0 -1
- package/dist/outposts/session-host-server.test.d.ts +0 -10
- package/dist/outposts/session-host-server.test.d.ts.map +0 -1
- package/dist/outposts/session-host-server.test.js +0 -118
- package/dist/outposts/session-host-server.test.js.map +0 -1
- package/dist/outposts/session-host-sessions.test.d.ts +0 -18
- package/dist/outposts/session-host-sessions.test.d.ts.map +0 -1
- package/dist/outposts/session-host-sessions.test.js +0 -439
- package/dist/outposts/session-host-sessions.test.js.map +0 -1
- package/dist/outposts/terminal.test.d.ts +0 -2
- package/dist/outposts/terminal.test.d.ts.map +0 -1
- package/dist/outposts/terminal.test.js +0 -146
- package/dist/outposts/terminal.test.js.map +0 -1
- package/dist/outposts/transport.test.d.ts +0 -10
- package/dist/outposts/transport.test.d.ts.map +0 -1
- package/dist/outposts/transport.test.js +0 -205
- package/dist/outposts/transport.test.js.map +0 -1
- package/dist/packed-journal-phase2.test.d.ts +0 -2
- package/dist/packed-journal-phase2.test.d.ts.map +0 -1
- package/dist/packed-journal-phase2.test.js +0 -273
- package/dist/packed-journal-phase2.test.js.map +0 -1
- package/dist/path-ancestors.test.d.ts +0 -2
- package/dist/path-ancestors.test.d.ts.map +0 -1
- package/dist/path-ancestors.test.js +0 -21
- package/dist/path-ancestors.test.js.map +0 -1
- package/dist/personal-vault-exclusions.test.d.ts +0 -22
- package/dist/personal-vault-exclusions.test.d.ts.map +0 -1
- package/dist/personal-vault-exclusions.test.js +0 -294
- package/dist/personal-vault-exclusions.test.js.map +0 -1
- package/dist/personal-vault.test.d.ts +0 -18
- package/dist/personal-vault.test.d.ts.map +0 -1
- package/dist/personal-vault.test.js +0 -1099
- package/dist/personal-vault.test.js.map +0 -1
- package/dist/plan-limit-pause.test.d.ts +0 -2
- package/dist/plan-limit-pause.test.d.ts.map +0 -1
- package/dist/plan-limit-pause.test.js +0 -150
- package/dist/plan-limit-pause.test.js.map +0 -1
- package/dist/plan-limit.fixtures.d.ts +0 -34
- package/dist/plan-limit.fixtures.d.ts.map +0 -1
- package/dist/plan-limit.fixtures.js +0 -96
- package/dist/plan-limit.fixtures.js.map +0 -1
- package/dist/plan-limit.test.d.ts +0 -2
- package/dist/plan-limit.test.d.ts.map +0 -1
- package/dist/plan-limit.test.js +0 -132
- package/dist/plan-limit.test.js.map +0 -1
- package/dist/prefix-coalesce.test.d.ts +0 -2
- package/dist/prefix-coalesce.test.d.ts.map +0 -1
- package/dist/prefix-coalesce.test.js +0 -260
- package/dist/prefix-coalesce.test.js.map +0 -1
- package/dist/private-folder-transport.test.d.ts +0 -2
- package/dist/private-folder-transport.test.d.ts.map +0 -1
- package/dist/private-folder-transport.test.js +0 -33
- package/dist/private-folder-transport.test.js.map +0 -1
- package/dist/public-surface.test.d.ts +0 -15
- package/dist/public-surface.test.d.ts.map +0 -1
- package/dist/public-surface.test.js +0 -110
- package/dist/public-surface.test.js.map +0 -1
- package/dist/qmd-reindex.test.d.ts +0 -14
- package/dist/qmd-reindex.test.d.ts.map +0 -1
- package/dist/qmd-reindex.test.js +0 -899
- package/dist/qmd-reindex.test.js.map +0 -1
- package/dist/read-only-state-dir.test.d.ts +0 -27
- package/dist/read-only-state-dir.test.d.ts.map +0 -1
- package/dist/read-only-state-dir.test.js +0 -167
- package/dist/read-only-state-dir.test.js.map +0 -1
- package/dist/remote-pull.test.d.ts +0 -2
- package/dist/remote-pull.test.d.ts.map +0 -1
- package/dist/remote-pull.test.js +0 -1147
- package/dist/remote-pull.test.js.map +0 -1
- package/dist/s3-download-stream-hash.test.d.ts +0 -2
- package/dist/s3-download-stream-hash.test.d.ts.map +0 -1
- package/dist/s3-download-stream-hash.test.js +0 -70
- package/dist/s3-download-stream-hash.test.js.map +0 -1
- package/dist/s3.list-cost.test.d.ts +0 -2
- package/dist/s3.list-cost.test.d.ts.map +0 -1
- package/dist/s3.list-cost.test.js +0 -51
- package/dist/s3.list-cost.test.js.map +0 -1
- package/dist/s3.rename-retry.test.d.ts +0 -2
- package/dist/s3.rename-retry.test.d.ts.map +0 -1
- package/dist/s3.rename-retry.test.js +0 -217
- package/dist/s3.rename-retry.test.js.map +0 -1
- package/dist/s3.symlink-materialize.test.d.ts +0 -18
- package/dist/s3.symlink-materialize.test.d.ts.map +0 -1
- package/dist/s3.symlink-materialize.test.js +0 -579
- package/dist/s3.symlink-materialize.test.js.map +0 -1
- package/dist/s3.test.d.ts +0 -9
- package/dist/s3.test.d.ts.map +0 -1
- package/dist/s3.test.js +0 -2047
- package/dist/s3.test.js.map +0 -1
- package/dist/s3.windows-portability.test.d.ts +0 -12
- package/dist/s3.windows-portability.test.d.ts.map +0 -1
- package/dist/s3.windows-portability.test.js +0 -223
- package/dist/s3.windows-portability.test.js.map +0 -1
- package/dist/schemas/signal-types.test.d.ts +0 -2
- package/dist/schemas/signal-types.test.d.ts.map +0 -1
- package/dist/schemas/signal-types.test.js +0 -65
- package/dist/schemas/signal-types.test.js.map +0 -1
- package/dist/schemas/source-channels.test.d.ts +0 -2
- package/dist/schemas/source-channels.test.d.ts.map +0 -1
- package/dist/schemas/source-channels.test.js +0 -65
- package/dist/schemas/source-channels.test.js.map +0 -1
- package/dist/scope-shrink.test.d.ts +0 -13
- package/dist/scope-shrink.test.d.ts.map +0 -1
- package/dist/scope-shrink.test.js +0 -558
- package/dist/scope-shrink.test.js.map +0 -1
- package/dist/session-log-capture.test.d.ts +0 -2
- package/dist/session-log-capture.test.d.ts.map +0 -1
- package/dist/session-log-capture.test.js +0 -533
- package/dist/session-log-capture.test.js.map +0 -1
- package/dist/session-log-retention.test.d.ts +0 -2
- package/dist/session-log-retention.test.d.ts.map +0 -1
- package/dist/session-log-retention.test.js +0 -383
- package/dist/session-log-retention.test.js.map +0 -1
- package/dist/signals/get.test.d.ts +0 -5
- package/dist/signals/get.test.d.ts.map +0 -1
- package/dist/signals/get.test.js +0 -254
- package/dist/signals/get.test.js.map +0 -1
- package/dist/signals/list.test.d.ts +0 -9
- package/dist/signals/list.test.d.ts.map +0 -1
- package/dist/signals/list.test.js +0 -330
- package/dist/signals/list.test.js.map +0 -1
- package/dist/skill-telemetry.test.d.ts +0 -2
- package/dist/skill-telemetry.test.d.ts.map +0 -1
- package/dist/skill-telemetry.test.js +0 -1484
- package/dist/skill-telemetry.test.js.map +0 -1
- package/dist/sources/get.test.d.ts +0 -5
- package/dist/sources/get.test.d.ts.map +0 -1
- package/dist/sources/get.test.js +0 -236
- package/dist/sources/get.test.js.map +0 -1
- package/dist/sources/list.test.d.ts +0 -8
- package/dist/sources/list.test.d.ts.map +0 -1
- package/dist/sources/list.test.js +0 -318
- package/dist/sources/list.test.js.map +0 -1
- package/dist/sts-credential-refresh.test.d.ts +0 -2
- package/dist/sts-credential-refresh.test.d.ts.map +0 -1
- package/dist/sts-credential-refresh.test.js +0 -181
- package/dist/sts-credential-refresh.test.js.map +0 -1
- package/dist/swallowed-error-sites.test.d.ts +0 -2
- package/dist/swallowed-error-sites.test.d.ts.map +0 -1
- package/dist/swallowed-error-sites.test.js +0 -199
- package/dist/swallowed-error-sites.test.js.map +0 -1
- package/dist/swallowed-error-w32.test.d.ts +0 -2
- package/dist/swallowed-error-w32.test.d.ts.map +0 -1
- package/dist/swallowed-error-w32.test.js +0 -171
- package/dist/swallowed-error-w32.test.js.map +0 -1
- package/dist/swallowed-error-w33.test.d.ts +0 -2
- package/dist/swallowed-error-w33.test.d.ts.map +0 -1
- package/dist/swallowed-error-w33.test.js +0 -125
- package/dist/swallowed-error-w33.test.js.map +0 -1
- package/dist/swallowed-error-w34.test.d.ts +0 -2
- package/dist/swallowed-error-w34.test.d.ts.map +0 -1
- package/dist/swallowed-error-w34.test.js +0 -110
- package/dist/swallowed-error-w34.test.js.map +0 -1
- package/dist/swallowed-error-w35.test.d.ts +0 -2
- package/dist/swallowed-error-w35.test.d.ts.map +0 -1
- package/dist/swallowed-error-w35.test.js +0 -223
- package/dist/swallowed-error-w35.test.js.map +0 -1
- package/dist/sync/area-ledger-auto-migration.test.d.ts +0 -2
- package/dist/sync/area-ledger-auto-migration.test.d.ts.map +0 -1
- package/dist/sync/area-ledger-auto-migration.test.js +0 -291
- package/dist/sync/area-ledger-auto-migration.test.js.map +0 -1
- package/dist/sync/area-ledger-migration.test.d.ts +0 -2
- package/dist/sync/area-ledger-migration.test.d.ts.map +0 -1
- package/dist/sync/area-ledger-migration.test.js +0 -554
- package/dist/sync/area-ledger-migration.test.js.map +0 -1
- package/dist/sync/area-ledger-recovery.bench.test.d.ts +0 -2
- package/dist/sync/area-ledger-recovery.bench.test.d.ts.map +0 -1
- package/dist/sync/area-ledger-recovery.bench.test.js +0 -60
- package/dist/sync/area-ledger-recovery.bench.test.js.map +0 -1
- package/dist/sync/area-ledger-writer-lock.bench.test.d.ts +0 -2
- package/dist/sync/area-ledger-writer-lock.bench.test.d.ts.map +0 -1
- package/dist/sync/area-ledger-writer-lock.bench.test.js +0 -57
- package/dist/sync/area-ledger-writer-lock.bench.test.js.map +0 -1
- package/dist/sync/area-ledger.test.d.ts +0 -2
- package/dist/sync/area-ledger.test.d.ts.map +0 -1
- package/dist/sync/area-ledger.test.js +0 -1401
- package/dist/sync/area-ledger.test.js.map +0 -1
- package/dist/sync/area-resolver.test.d.ts +0 -2
- package/dist/sync/area-resolver.test.d.ts.map +0 -1
- package/dist/sync/area-resolver.test.js +0 -234
- package/dist/sync/area-resolver.test.js.map +0 -1
- package/dist/sync/base-version-resolver.test.d.ts +0 -2
- package/dist/sync/base-version-resolver.test.d.ts.map +0 -1
- package/dist/sync/base-version-resolver.test.js +0 -24
- package/dist/sync/base-version-resolver.test.js.map +0 -1
- package/dist/sync/candidate-uploader.test.d.ts +0 -2
- package/dist/sync/candidate-uploader.test.d.ts.map +0 -1
- package/dist/sync/candidate-uploader.test.js +0 -132
- package/dist/sync/candidate-uploader.test.js.map +0 -1
- package/dist/sync/child-process-sync-worker-env.test.d.ts +0 -2
- package/dist/sync/child-process-sync-worker-env.test.d.ts.map +0 -1
- package/dist/sync/child-process-sync-worker-env.test.js +0 -38
- package/dist/sync/child-process-sync-worker-env.test.js.map +0 -1
- package/dist/sync/child-process-sync-worker-errors.test.d.ts +0 -2
- package/dist/sync/child-process-sync-worker-errors.test.d.ts.map +0 -1
- package/dist/sync/child-process-sync-worker-errors.test.js +0 -121
- package/dist/sync/child-process-sync-worker-errors.test.js.map +0 -1
- package/dist/sync/child-process-sync-worker.test.d.ts +0 -2
- package/dist/sync/child-process-sync-worker.test.d.ts.map +0 -1
- package/dist/sync/child-process-sync-worker.test.js +0 -262
- package/dist/sync/child-process-sync-worker.test.js.map +0 -1
- package/dist/sync/content-hash.test.d.ts +0 -2
- package/dist/sync/content-hash.test.d.ts.map +0 -1
- package/dist/sync/content-hash.test.js +0 -16
- package/dist/sync/content-hash.test.js.map +0 -1
- package/dist/sync/delta-client.test.d.ts +0 -2
- package/dist/sync/delta-client.test.d.ts.map +0 -1
- package/dist/sync/delta-client.test.js +0 -97
- package/dist/sync/delta-client.test.js.map +0 -1
- package/dist/sync/durable-apply.test.d.ts +0 -2
- package/dist/sync/durable-apply.test.d.ts.map +0 -1
- package/dist/sync/durable-apply.test.js +0 -180
- package/dist/sync/durable-apply.test.js.map +0 -1
- package/dist/sync/event-sync.test.d.ts +0 -14
- package/dist/sync/event-sync.test.d.ts.map +0 -1
- package/dist/sync/event-sync.test.js +0 -1714
- package/dist/sync/event-sync.test.js.map +0 -1
- package/dist/sync/feature-flags.test.d.ts +0 -24
- package/dist/sync/feature-flags.test.d.ts.map +0 -1
- package/dist/sync/feature-flags.test.js +0 -594
- package/dist/sync/feature-flags.test.js.map +0 -1
- package/dist/sync/full-pass-cap-governor.bench.test.d.ts +0 -2
- package/dist/sync/full-pass-cap-governor.bench.test.d.ts.map +0 -1
- package/dist/sync/full-pass-cap-governor.bench.test.js +0 -179
- package/dist/sync/full-pass-cap-governor.bench.test.js.map +0 -1
- package/dist/sync/full-pass-caps.test.d.ts +0 -2
- package/dist/sync/full-pass-caps.test.d.ts.map +0 -1
- package/dist/sync/full-pass-caps.test.js +0 -550
- package/dist/sync/full-pass-caps.test.js.map +0 -1
- package/dist/sync/idle-full-reconcile.test.d.ts +0 -2
- package/dist/sync/idle-full-reconcile.test.d.ts.map +0 -1
- package/dist/sync/idle-full-reconcile.test.js +0 -62
- package/dist/sync/idle-full-reconcile.test.js.map +0 -1
- package/dist/sync/inbound-event-admission.test.d.ts +0 -2
- package/dist/sync/inbound-event-admission.test.d.ts.map +0 -1
- package/dist/sync/inbound-event-admission.test.js +0 -125
- package/dist/sync/inbound-event-admission.test.js.map +0 -1
- package/dist/sync/journal-ledger-stream.test.d.ts +0 -12
- package/dist/sync/journal-ledger-stream.test.d.ts.map +0 -1
- package/dist/sync/journal-ledger-stream.test.js +0 -134
- package/dist/sync/journal-ledger-stream.test.js.map +0 -1
- package/dist/sync/lease-client.test.d.ts +0 -2
- package/dist/sync/lease-client.test.d.ts.map +0 -1
- package/dist/sync/lease-client.test.js +0 -119
- package/dist/sync/lease-client.test.js.map +0 -1
- package/dist/sync/logger.test.d.ts +0 -19
- package/dist/sync/logger.test.d.ts.map +0 -1
- package/dist/sync/logger.test.js +0 -204
- package/dist/sync/logger.test.js.map +0 -1
- package/dist/sync/metrics.test.d.ts +0 -19
- package/dist/sync/metrics.test.d.ts.map +0 -1
- package/dist/sync/metrics.test.js +0 -357
- package/dist/sync/metrics.test.js.map +0 -1
- package/dist/sync/multipart-uploader.test.d.ts +0 -2
- package/dist/sync/multipart-uploader.test.d.ts.map +0 -1
- package/dist/sync/multipart-uploader.test.js +0 -135
- package/dist/sync/multipart-uploader.test.js.map +0 -1
- package/dist/sync/mutation-client.test.d.ts +0 -2
- package/dist/sync/mutation-client.test.d.ts.map +0 -1
- package/dist/sync/mutation-client.test.js +0 -100
- package/dist/sync/mutation-client.test.js.map +0 -1
- package/dist/sync/mutation-session.test.d.ts +0 -2
- package/dist/sync/mutation-session.test.d.ts.map +0 -1
- package/dist/sync/mutation-session.test.js +0 -190
- package/dist/sync/mutation-session.test.js.map +0 -1
- package/dist/sync/parallel-sync-coordinator.test.d.ts +0 -2
- package/dist/sync/parallel-sync-coordinator.test.d.ts.map +0 -1
- package/dist/sync/parallel-sync-coordinator.test.js +0 -564
- package/dist/sync/parallel-sync-coordinator.test.js.map +0 -1
- package/dist/sync/path-leases.test.d.ts +0 -2
- package/dist/sync/path-leases.test.d.ts.map +0 -1
- package/dist/sync/path-leases.test.js +0 -51
- package/dist/sync/path-leases.test.js.map +0 -1
- package/dist/sync/per-area-maintenance.test.d.ts +0 -2
- package/dist/sync/per-area-maintenance.test.d.ts.map +0 -1
- package/dist/sync/per-area-maintenance.test.js +0 -100
- package/dist/sync/per-area-maintenance.test.js.map +0 -1
- package/dist/sync/push-event.test.d.ts +0 -15
- package/dist/sync/push-event.test.d.ts.map +0 -1
- package/dist/sync/push-event.test.js +0 -282
- package/dist/sync/push-event.test.js.map +0 -1
- package/dist/sync/push-receiver.test.d.ts +0 -25
- package/dist/sync/push-receiver.test.d.ts.map +0 -1
- package/dist/sync/push-receiver.test.js +0 -2851
- package/dist/sync/push-receiver.test.js.map +0 -1
- package/dist/sync/push-transport.test.d.ts +0 -2
- package/dist/sync/push-transport.test.d.ts.map +0 -1
- package/dist/sync/push-transport.test.js +0 -70
- package/dist/sync/push-transport.test.js.map +0 -1
- package/dist/sync/push-walk-matchers.bench.test.d.ts +0 -2
- package/dist/sync/push-walk-matchers.bench.test.d.ts.map +0 -1
- package/dist/sync/push-walk-matchers.bench.test.js +0 -230
- package/dist/sync/push-walk-matchers.bench.test.js.map +0 -1
- package/dist/sync/realtime-network-integration.test.d.ts +0 -2
- package/dist/sync/realtime-network-integration.test.d.ts.map +0 -1
- package/dist/sync/realtime-network-integration.test.js +0 -83
- package/dist/sync/realtime-network-integration.test.js.map +0 -1
- package/dist/sync/realtime-rollout.test.d.ts +0 -2
- package/dist/sync/realtime-rollout.test.d.ts.map +0 -1
- package/dist/sync/realtime-rollout.test.js +0 -94
- package/dist/sync/realtime-rollout.test.js.map +0 -1
- package/dist/sync/realtime-telemetry.test.d.ts +0 -2
- package/dist/sync/realtime-telemetry.test.d.ts.map +0 -1
- package/dist/sync/realtime-telemetry.test.js +0 -300
- package/dist/sync/realtime-telemetry.test.js.map +0 -1
- package/dist/sync/receiver-origin-config.test.d.ts +0 -2
- package/dist/sync/receiver-origin-config.test.d.ts.map +0 -1
- package/dist/sync/receiver-origin-config.test.js +0 -39
- package/dist/sync/receiver-origin-config.test.js.map +0 -1
- package/dist/sync/reconcile-cursor.test.d.ts +0 -2
- package/dist/sync/reconcile-cursor.test.d.ts.map +0 -1
- package/dist/sync/reconcile-cursor.test.js +0 -139
- package/dist/sync/reconcile-cursor.test.js.map +0 -1
- package/dist/sync/remote-file-spool.test.d.ts +0 -2
- package/dist/sync/remote-file-spool.test.d.ts.map +0 -1
- package/dist/sync/remote-file-spool.test.js +0 -77
- package/dist/sync/remote-file-spool.test.js.map +0 -1
- package/dist/sync/scope-inventory-client.test.d.ts +0 -2
- package/dist/sync/scope-inventory-client.test.d.ts.map +0 -1
- package/dist/sync/scope-inventory-client.test.js +0 -103
- package/dist/sync/scope-inventory-client.test.js.map +0 -1
- package/dist/sync/secret-path-policy.test.d.ts +0 -2
- package/dist/sync/secret-path-policy.test.d.ts.map +0 -1
- package/dist/sync/secret-path-policy.test.js +0 -183
- package/dist/sync/secret-path-policy.test.js.map +0 -1
- package/dist/sync/snapshot-client.test.d.ts +0 -2
- package/dist/sync/snapshot-client.test.d.ts.map +0 -1
- package/dist/sync/snapshot-client.test.js +0 -169
- package/dist/sync/snapshot-client.test.js.map +0 -1
- package/dist/sync/state-store.test.d.ts +0 -2
- package/dist/sync/state-store.test.d.ts.map +0 -1
- package/dist/sync/state-store.test.js +0 -1556
- package/dist/sync/state-store.test.js.map +0 -1
- package/dist/sync/sync-contract.test.d.ts +0 -2
- package/dist/sync/sync-contract.test.d.ts.map +0 -1
- package/dist/sync/sync-contract.test.js +0 -141
- package/dist/sync/sync-contract.test.js.map +0 -1
- package/dist/sync/targeted-pull-prefixes.test.d.ts +0 -2
- package/dist/sync/targeted-pull-prefixes.test.d.ts.map +0 -1
- package/dist/sync/targeted-pull-prefixes.test.js +0 -33
- package/dist/sync/targeted-pull-prefixes.test.js.map +0 -1
- package/dist/sync/targeted-upsert-exact-list.test.d.ts +0 -2
- package/dist/sync/targeted-upsert-exact-list.test.d.ts.map +0 -1
- package/dist/sync/targeted-upsert-exact-list.test.js +0 -247
- package/dist/sync/targeted-upsert-exact-list.test.js.map +0 -1
- package/dist/sync/unchanged-push-events.test.d.ts +0 -2
- package/dist/sync/unchanged-push-events.test.d.ts.map +0 -1
- package/dist/sync/unchanged-push-events.test.js +0 -76
- package/dist/sync/unchanged-push-events.test.js.map +0 -1
- package/dist/sync/uploader-finalization.test.d.ts +0 -2
- package/dist/sync/uploader-finalization.test.d.ts.map +0 -1
- package/dist/sync/uploader-finalization.test.js +0 -107
- package/dist/sync/uploader-finalization.test.js.map +0 -1
- package/dist/sync-core.test.d.ts +0 -2
- package/dist/sync-core.test.d.ts.map +0 -1
- package/dist/sync-core.test.js +0 -189
- package/dist/sync-core.test.js.map +0 -1
- package/dist/sync-progress.test.d.ts +0 -2
- package/dist/sync-progress.test.d.ts.map +0 -1
- package/dist/sync-progress.test.js +0 -277
- package/dist/sync-progress.test.js.map +0 -1
- package/dist/telemetry-events.test.d.ts +0 -2
- package/dist/telemetry-events.test.d.ts.map +0 -1
- package/dist/telemetry-events.test.js +0 -113
- package/dist/telemetry-events.test.js.map +0 -1
- package/dist/telemetry.test.d.ts +0 -11
- package/dist/telemetry.test.d.ts.map +0 -1
- package/dist/telemetry.test.js +0 -1603
- package/dist/telemetry.test.js.map +0 -1
- package/dist/vault-client.test.d.ts +0 -7
- package/dist/vault-client.test.d.ts.map +0 -1
- package/dist/vault-client.test.js +0 -1334
- package/dist/vault-client.test.js.map +0 -1
- package/dist/watch-coverage.test.d.ts +0 -2
- package/dist/watch-coverage.test.d.ts.map +0 -1
- package/dist/watch-coverage.test.js +0 -56
- package/dist/watch-coverage.test.js.map +0 -1
- package/dist/watch-owner-lease.test.d.ts +0 -2
- package/dist/watch-owner-lease.test.d.ts.map +0 -1
- package/dist/watch-owner-lease.test.js +0 -353
- package/dist/watch-owner-lease.test.js.map +0 -1
- package/dist/watch-parent.test.d.ts +0 -2
- package/dist/watch-parent.test.d.ts.map +0 -1
- package/dist/watch-parent.test.js +0 -131
- package/dist/watch-parent.test.js.map +0 -1
- package/dist/watch-roots.test.d.ts +0 -18
- package/dist/watch-roots.test.d.ts.map +0 -1
- package/dist/watch-roots.test.js +0 -395
- package/dist/watch-roots.test.js.map +0 -1
- package/dist/watcher-continuity-hot-path.test.d.ts +0 -2
- package/dist/watcher-continuity-hot-path.test.d.ts.map +0 -1
- package/dist/watcher-continuity-hot-path.test.js +0 -40
- package/dist/watcher-continuity-hot-path.test.js.map +0 -1
- package/dist/watcher-event-gate.test.d.ts +0 -16
- package/dist/watcher-event-gate.test.d.ts.map +0 -1
- package/dist/watcher-event-gate.test.js +0 -191
- package/dist/watcher-event-gate.test.js.map +0 -1
- package/dist/watcher-replan-sweep.test.d.ts +0 -2
- package/dist/watcher-replan-sweep.test.d.ts.map +0 -1
- package/dist/watcher-replan-sweep.test.js +0 -245
- package/dist/watcher-replan-sweep.test.js.map +0 -1
- package/dist/watcher-stdout.test.d.ts +0 -2
- package/dist/watcher-stdout.test.d.ts.map +0 -1
- package/dist/watcher-stdout.test.js +0 -86
- package/dist/watcher-stdout.test.js.map +0 -1
- package/dist/watcher.test.d.ts +0 -2
- package/dist/watcher.test.d.ts.map +0 -1
- package/dist/watcher.test.js +0 -4301
- package/dist/watcher.test.js.map +0 -1
- package/dist/watcher.warmup-cancel.test.d.ts +0 -2
- package/dist/watcher.warmup-cancel.test.d.ts.map +0 -1
- package/dist/watcher.warmup-cancel.test.js +0 -59
- package/dist/watcher.warmup-cancel.test.js.map +0 -1
- package/dist/watcher.warmup-responsive.test.d.ts +0 -2
- package/dist/watcher.warmup-responsive.test.d.ts.map +0 -1
- package/dist/watcher.warmup-responsive.test.js +0 -62
- package/dist/watcher.warmup-responsive.test.js.map +0 -1
|
@@ -1,1401 +0,0 @@
|
|
|
1
|
-
import * as fs from "node:fs";
|
|
2
|
-
import * as os from "node:os";
|
|
3
|
-
import * as path from "node:path";
|
|
4
|
-
import { spawn } from "node:child_process";
|
|
5
|
-
import { once } from "node:events";
|
|
6
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
7
|
-
import { MAX_PULLS_PER_COMPANY } from "../journal.js";
|
|
8
|
-
import { AreaLedger, UNROUTED_AREA_ID, setAreaLedgerTestHooksForTest } from "./area-ledger.js";
|
|
9
|
-
import { StateStore, setStateStoreWalRecordReadHookForTest } from "./state-store.js";
|
|
10
|
-
import { JournalRowOverlay, JournalRowStore } from "../journal-row-store.js";
|
|
11
|
-
import { forgetSharedAreaJournalRows } from "../journal-snapshot-rows.js";
|
|
12
|
-
const roots = [];
|
|
13
|
-
afterEach(() => {
|
|
14
|
-
setAreaLedgerTestHooksForTest(undefined);
|
|
15
|
-
setStateStoreWalRecordReadHookForTest(undefined);
|
|
16
|
-
// Vitest 4 returns an existing mock when a later case spies on the same
|
|
17
|
-
// method. Restore every case's prototype spies so their call history cannot
|
|
18
|
-
// cross the cache-performance assertions below.
|
|
19
|
-
vi.restoreAllMocks();
|
|
20
|
-
for (const root of roots.splice(0))
|
|
21
|
-
fs.rmSync(root, { recursive: true, force: true });
|
|
22
|
-
});
|
|
23
|
-
function entry(size) {
|
|
24
|
-
return {
|
|
25
|
-
hash: `${size}`.repeat(64),
|
|
26
|
-
size,
|
|
27
|
-
syncedAt: "2026-08-27T00:00:00.000Z",
|
|
28
|
-
direction: "up",
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
function pullRecord(index) {
|
|
32
|
-
const completedAt = new Date(Date.UTC(2026, 4, 20, 0, 0, 0, index)).toISOString();
|
|
33
|
-
return {
|
|
34
|
-
pullId: `pull-${String(index).padStart(3, "0")}`,
|
|
35
|
-
companyUid: "cmp_indigo",
|
|
36
|
-
startedAt: completedAt,
|
|
37
|
-
completedAt,
|
|
38
|
-
syncMode: "all",
|
|
39
|
-
prefixSet: [],
|
|
40
|
-
scopeChangeDetected: false,
|
|
41
|
-
orphansRemoved: 0,
|
|
42
|
-
orphansBlocked: 0,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
function makeRoot() {
|
|
46
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "hq-area-ledger-test-"));
|
|
47
|
-
roots.push(root);
|
|
48
|
-
return root;
|
|
49
|
-
}
|
|
50
|
-
function open(root, initialJournal) {
|
|
51
|
-
return AreaLedger.open({
|
|
52
|
-
rootDir: root,
|
|
53
|
-
journalSlug: "personal-vault",
|
|
54
|
-
layoutEpoch: 1,
|
|
55
|
-
areaIds: ["root:alpha", "root:beta"],
|
|
56
|
-
resolveArea: (key) => key.startsWith("alpha/") ? "root:alpha" : key.startsWith("beta/") ? "root:beta" : undefined,
|
|
57
|
-
initialJournal,
|
|
58
|
-
maxRecordsBeforeCompaction: 2,
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
function openMany(root, count) {
|
|
62
|
-
const areaIds = Array.from({ length: count }, (_, index) => `root:area-${index}`);
|
|
63
|
-
return AreaLedger.open({
|
|
64
|
-
rootDir: root,
|
|
65
|
-
journalSlug: "personal-vault",
|
|
66
|
-
layoutEpoch: 1,
|
|
67
|
-
areaIds,
|
|
68
|
-
resolveArea: (key) => {
|
|
69
|
-
const index = Number(/^area-(\d+)\//.exec(key)?.[1]);
|
|
70
|
-
return Number.isSafeInteger(index) && areaIds[index] !== undefined ? areaIds[index] : undefined;
|
|
71
|
-
},
|
|
72
|
-
maxRecordsBeforeCompaction: 8,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
async function exitCode(child) {
|
|
76
|
-
const [code, signal] = await once(child, "exit");
|
|
77
|
-
if (code !== 0)
|
|
78
|
-
throw new Error(`area-ledger child failed with ${String(code)} / ${String(signal)}`);
|
|
79
|
-
return code;
|
|
80
|
-
}
|
|
81
|
-
if (process.env.AREA_LEDGER_CHILD_ROOT) {
|
|
82
|
-
describe("AreaLedger child append", () => {
|
|
83
|
-
it("appends its assigned independent area", () => {
|
|
84
|
-
const ledger = open(process.env.AREA_LEDGER_CHILD_ROOT);
|
|
85
|
-
ledger.append({ upserts: { "beta/from-child.md": entry(2) } });
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
describe("AreaLedger — a key with no area must not wedge the whole vault", () => {
|
|
91
|
-
// THE PERMANENT-WEDGE BUG.
|
|
92
|
-
//
|
|
93
|
-
// The area layout is committed exactly once, at the legacy -> area
|
|
94
|
-
// cutover (`cutOver()` mints activeLayoutEpoch and nothing ever re-mints
|
|
95
|
-
// it). The resolver is then loaded from that frozen `area-resolver.json`
|
|
96
|
-
// — "an authority decision, not a hint" — so it knows only the top-level
|
|
97
|
-
// directories that existed on cutover day.
|
|
98
|
-
//
|
|
99
|
-
// Create ANY new top-level directory in the HQ root afterwards and every
|
|
100
|
-
// key beneath it resolves to nothing. `partition()` then throws out of
|
|
101
|
-
// `append()`, which aborts the ENTIRE personal-vault checkpoint — not just
|
|
102
|
-
// the unroutable key. Every unrelated change in the same transaction is
|
|
103
|
-
// lost with it, and because the layout is never rebuilt the next sync
|
|
104
|
-
// fails identically. On this fleet two machines stayed wedged for days;
|
|
105
|
-
// the only recovery was deleting the directory by hand.
|
|
106
|
-
//
|
|
107
|
-
// A new top-level directory is an ordinary thing for a user to make. It
|
|
108
|
-
// must never be able to stop their vault syncing.
|
|
109
|
-
function openWithUnroutable(root) {
|
|
110
|
-
return AreaLedger.open({
|
|
111
|
-
rootDir: root,
|
|
112
|
-
journalSlug: "personal-vault",
|
|
113
|
-
layoutEpoch: 1,
|
|
114
|
-
// A layout frozen before `gamma/` existed.
|
|
115
|
-
areaIds: ["root:alpha", "root:beta"],
|
|
116
|
-
resolveArea: (key) => key.startsWith("alpha/")
|
|
117
|
-
? "root:alpha"
|
|
118
|
-
: key.startsWith("beta/")
|
|
119
|
-
? "root:beta"
|
|
120
|
-
: undefined,
|
|
121
|
-
maxRecordsBeforeCompaction: 2,
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
it("accepts an append containing a key the frozen layout cannot route", () => {
|
|
125
|
-
const root = makeRoot();
|
|
126
|
-
const ledger = openWithUnroutable(root);
|
|
127
|
-
expect(() => ledger.append({ upserts: { "gamma/new-top-level.md": entry(1) } })).not.toThrow();
|
|
128
|
-
});
|
|
129
|
-
it("does not discard the routable changes travelling with it", () => {
|
|
130
|
-
// The damage was never limited to the unroutable path: one unknown key
|
|
131
|
-
// took the whole transaction down with it.
|
|
132
|
-
const root = makeRoot();
|
|
133
|
-
const ledger = openWithUnroutable(root);
|
|
134
|
-
ledger.append({
|
|
135
|
-
upserts: {
|
|
136
|
-
"alpha/keep-me.md": entry(1),
|
|
137
|
-
"beta/keep-me-too.md": entry(2),
|
|
138
|
-
"gamma/new-top-level.md": entry(3),
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
const files = openWithUnroutable(root).read().files;
|
|
142
|
-
expect(files["alpha/keep-me.md"]).toMatchObject({ size: 1 });
|
|
143
|
-
expect(files["beta/keep-me-too.md"]).toMatchObject({ size: 2 });
|
|
144
|
-
});
|
|
145
|
-
it("still journals the unroutable key so it is not silently forgotten", () => {
|
|
146
|
-
// Dropping the row would be its own bug: the file would then look
|
|
147
|
-
// untracked forever and never reconcile.
|
|
148
|
-
const root = makeRoot();
|
|
149
|
-
const ledger = openWithUnroutable(root);
|
|
150
|
-
ledger.append({ upserts: { "gamma/new-top-level.md": entry(7) } });
|
|
151
|
-
expect(openWithUnroutable(root).read().files["gamma/new-top-level.md"])
|
|
152
|
-
.toMatchObject({ size: 7 });
|
|
153
|
-
});
|
|
154
|
-
it("survives a second sync, the way the wedged machines never did", () => {
|
|
155
|
-
const root = makeRoot();
|
|
156
|
-
openWithUnroutable(root).append({
|
|
157
|
-
upserts: { "gamma/new-top-level.md": entry(1) },
|
|
158
|
-
});
|
|
159
|
-
expect(() => openWithUnroutable(root).append({
|
|
160
|
-
upserts: { "gamma/another.md": entry(2), "alpha/ok.md": entry(3) },
|
|
161
|
-
})).not.toThrow();
|
|
162
|
-
expect(openWithUnroutable(root).read().files["alpha/ok.md"])
|
|
163
|
-
.toMatchObject({ size: 3 });
|
|
164
|
-
});
|
|
165
|
-
it("routes a deletion of an unroutable key without throwing", () => {
|
|
166
|
-
const root = makeRoot();
|
|
167
|
-
const ledger = openWithUnroutable(root);
|
|
168
|
-
ledger.append({ upserts: { "gamma/gone.md": entry(1) } });
|
|
169
|
-
expect(() => openWithUnroutable(root).append({ deletes: ["gamma/gone.md"] })).not.toThrow();
|
|
170
|
-
expect(openWithUnroutable(root).read().files["gamma/gone.md"]).toBeUndefined();
|
|
171
|
-
});
|
|
172
|
-
/** Every byte an area holds on disk — the ground truth for placement. */
|
|
173
|
-
function storedText(dir) {
|
|
174
|
-
const walk = (at) => fs.readdirSync(at, { withFileTypes: true }).flatMap((item) => {
|
|
175
|
-
const full = path.join(at, item.name);
|
|
176
|
-
return item.isDirectory() ? walk(full) : [fs.readFileSync(full, "utf8")];
|
|
177
|
-
});
|
|
178
|
-
return fs.existsSync(dir) ? walk(dir).join("\n") : "";
|
|
179
|
-
}
|
|
180
|
-
it("keeps a routable key in ITS OWN area, not the overflow", () => {
|
|
181
|
-
// Negative control. A fix that simply swept every key into one overflow
|
|
182
|
-
// area would pass every test above while destroying the per-area
|
|
183
|
-
// partitioning the whole design exists for — and with it the per-area
|
|
184
|
-
// append locks two processes rely on. Placement is read off disk because
|
|
185
|
-
// an append opens every configured area whatever it writes, so the
|
|
186
|
-
// opened-area list cannot say where a row actually landed.
|
|
187
|
-
const root = makeRoot();
|
|
188
|
-
const ledger = openWithUnroutable(root);
|
|
189
|
-
ledger.append({
|
|
190
|
-
upserts: { "alpha/a.md": entry(1), "gamma/g.md": entry(2) },
|
|
191
|
-
});
|
|
192
|
-
const directories = ledger.stateDirectoriesForTest();
|
|
193
|
-
const alpha = storedText(directories.get("root:alpha"));
|
|
194
|
-
const overflow = storedText(directories.get(UNROUTED_AREA_ID));
|
|
195
|
-
expect(alpha).toContain("alpha/a.md");
|
|
196
|
-
expect(alpha).not.toContain("gamma/g.md");
|
|
197
|
-
expect(overflow).toContain("gamma/g.md");
|
|
198
|
-
expect(overflow).not.toContain("alpha/a.md");
|
|
199
|
-
// ...and the sibling area nobody wrote to holds neither of them.
|
|
200
|
-
expect(storedText(directories.get("root:beta"))).not.toContain("alpha/a.md");
|
|
201
|
-
});
|
|
202
|
-
it("routes every unroutable key to the SAME overflow area", () => {
|
|
203
|
-
// Otherwise a machine that grows many new top-level directories would
|
|
204
|
-
// grow an unbounded number of area state stores.
|
|
205
|
-
const root = makeRoot();
|
|
206
|
-
const ledger = openWithUnroutable(root);
|
|
207
|
-
ledger.append({
|
|
208
|
-
upserts: { "gamma/one.md": entry(1), "delta/two.md": entry(2) },
|
|
209
|
-
});
|
|
210
|
-
const directories = ledger.stateDirectoriesForTest();
|
|
211
|
-
expect([...directories.keys()].sort()).toEqual(["@meta", UNROUTED_AREA_ID, "root:alpha", "root:beta"].sort());
|
|
212
|
-
const overflow = storedText(directories.get(UNROUTED_AREA_ID));
|
|
213
|
-
expect(overflow).toContain("gamma/one.md");
|
|
214
|
-
expect(overflow).toContain("delta/two.md");
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
describe("AreaLedger — the overflow area must never collide with a real one", () => {
|
|
218
|
-
// The 2026-09-07 regression, reproduced end to end.
|
|
219
|
-
//
|
|
220
|
-
// hq-cloud 6.16.24 did two things in one release: it added the overflow
|
|
221
|
-
// area (so an unroutable key stops aborting the checkpoint) and it added
|
|
222
|
-
// the top-level lockfiles to the personal vault's exclusions. Together
|
|
223
|
-
// those turned a key that had a live entry in a REAL area into a key that
|
|
224
|
-
// no longer routes — so the next delta touching it took the overflow route
|
|
225
|
-
// and the SAME key was suddenly journaled in two areas at once.
|
|
226
|
-
//
|
|
227
|
-
// `combine` treated that as corruption and threw. It runs inside
|
|
228
|
-
// `primeAggregateCache`, which is on the JournalStore OPEN path, so it
|
|
229
|
-
// fired on every open: the watcher crash-looped, and unlike the
|
|
230
|
-
// append-time failure the overflow area was introduced to remove, there
|
|
231
|
-
// was nothing the user could do to recover. Both HQ outposts hit it within
|
|
232
|
-
// hours of upgrading — `pnpm-lock.yaml` on one, `package-lock.json` on the
|
|
233
|
-
// other.
|
|
234
|
-
//
|
|
235
|
-
// Two halves are tested here: the read path HEALS a ledger that already
|
|
236
|
-
// holds the duplicate, and the write path stops a new one being made.
|
|
237
|
-
/** A ledger whose layout knows `root:gamma`. */
|
|
238
|
-
function openWide(root) {
|
|
239
|
-
return AreaLedger.open({
|
|
240
|
-
rootDir: root,
|
|
241
|
-
journalSlug: "personal-vault",
|
|
242
|
-
layoutEpoch: 1,
|
|
243
|
-
areaIds: ["root:alpha", "root:gamma"],
|
|
244
|
-
resolveArea: (key) => key.startsWith("alpha/") ? "root:alpha" : key.startsWith("gamma/") ? "root:gamma" : undefined,
|
|
245
|
-
maxRecordsBeforeCompaction: 2,
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* The same root seen by a build whose layout does NOT know `root:gamma` —
|
|
250
|
-
* which is how 6.16.24 behaved for a key it had just excluded. This is the
|
|
251
|
-
* writer that creates the duplicate, standing in for the released build
|
|
252
|
-
* that had no prevention in it.
|
|
253
|
-
*/
|
|
254
|
-
function openNarrow(root) {
|
|
255
|
-
return AreaLedger.open({
|
|
256
|
-
rootDir: root,
|
|
257
|
-
journalSlug: "personal-vault",
|
|
258
|
-
layoutEpoch: 1,
|
|
259
|
-
areaIds: ["root:alpha"],
|
|
260
|
-
resolveArea: (key) => (key.startsWith("alpha/") ? "root:alpha" : undefined),
|
|
261
|
-
maxRecordsBeforeCompaction: 2,
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* The production shape of the regression: the area list is frozen, so
|
|
266
|
-
* `root:gamma` is still configured, but the key no longer routes to it.
|
|
267
|
-
*/
|
|
268
|
-
function openStranded(root) {
|
|
269
|
-
return AreaLedger.open({
|
|
270
|
-
rootDir: root,
|
|
271
|
-
journalSlug: "personal-vault",
|
|
272
|
-
layoutEpoch: 1,
|
|
273
|
-
areaIds: ["root:alpha", "root:gamma"],
|
|
274
|
-
resolveArea: (key) => (key.startsWith("alpha/") ? "root:alpha" : undefined),
|
|
275
|
-
maxRecordsBeforeCompaction: 2,
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
/** Put `gamma/g.md` in BOTH `root:gamma` and the overflow area. */
|
|
279
|
-
function seedDuplicate(root) {
|
|
280
|
-
openWide(root).append({ upserts: { "gamma/g.md": entry(1) } });
|
|
281
|
-
openNarrow(root).append({ upserts: { "gamma/g.md": entry(2) } });
|
|
282
|
-
}
|
|
283
|
-
it("reproduces the duplicate: the same key lands in a real area AND the overflow", () => {
|
|
284
|
-
// Negative control for the two tests below. If this ever stops producing
|
|
285
|
-
// a duplicate, they would both pass without exercising anything.
|
|
286
|
-
const root = makeRoot();
|
|
287
|
-
seedDuplicate(root);
|
|
288
|
-
const directories = openWide(root).stateDirectoriesForTest();
|
|
289
|
-
const walk = (at) => fs.readdirSync(at, { withFileTypes: true }).flatMap((item) => {
|
|
290
|
-
const full = path.join(at, item.name);
|
|
291
|
-
return item.isDirectory() ? walk(full) : [fs.readFileSync(full, "utf8")];
|
|
292
|
-
});
|
|
293
|
-
const text = (dir) => (fs.existsSync(dir) ? walk(dir).join("\n") : "");
|
|
294
|
-
expect(text(directories.get("root:gamma"))).toContain("gamma/g.md");
|
|
295
|
-
expect(text(directories.get(UNROUTED_AREA_ID))).toContain("gamma/g.md");
|
|
296
|
-
});
|
|
297
|
-
it("reads a ledger that already holds the duplicate instead of throwing", () => {
|
|
298
|
-
const root = makeRoot();
|
|
299
|
-
seedDuplicate(root);
|
|
300
|
-
expect(() => openWide(root).read()).not.toThrow();
|
|
301
|
-
});
|
|
302
|
-
it("resolves the duplicate to the REAL area's entry, not the overflow copy", () => {
|
|
303
|
-
// Direction matters. The overflow area is the fallback for keys the
|
|
304
|
-
// layout cannot place, so a key it CAN place is governed by its placed
|
|
305
|
-
// entry; the overflow copy is stale by construction. Sizes 1 and 2 are
|
|
306
|
-
// what tell the two apart.
|
|
307
|
-
const root = makeRoot();
|
|
308
|
-
seedDuplicate(root);
|
|
309
|
-
expect(openWide(root).read().files["gamma/g.md"]?.size).toBe(1);
|
|
310
|
-
});
|
|
311
|
-
it("still throws when one key is present in two REAL areas", () => {
|
|
312
|
-
// The invariant this fix must NOT weaken. A routable key has exactly one
|
|
313
|
-
// home, so two real areas holding it means the on-disk state disagrees
|
|
314
|
-
// with itself, and silently picking a winner would hide that.
|
|
315
|
-
//
|
|
316
|
-
// Each writer below is given a layout containing only its OWN area, so
|
|
317
|
-
// neither can see — and therefore evict — the other's copy. That is what
|
|
318
|
-
// it now takes to build this state at all: through a layout that knows
|
|
319
|
-
// both areas, the eviction in `partition` converges it away instead (see
|
|
320
|
-
// the re-route test below).
|
|
321
|
-
const root = makeRoot();
|
|
322
|
-
const single = (areaId) => AreaLedger.open({
|
|
323
|
-
rootDir: root,
|
|
324
|
-
journalSlug: "personal-vault",
|
|
325
|
-
layoutEpoch: 1,
|
|
326
|
-
areaIds: [areaId],
|
|
327
|
-
resolveArea: () => areaId,
|
|
328
|
-
maxRecordsBeforeCompaction: 2,
|
|
329
|
-
});
|
|
330
|
-
single("root:alpha").append({ upserts: { "shared.md": entry(1) } });
|
|
331
|
-
single("root:beta").append({ upserts: { "shared.md": entry(2) } });
|
|
332
|
-
expect(() => AreaLedger.open({
|
|
333
|
-
rootDir: root,
|
|
334
|
-
journalSlug: "personal-vault",
|
|
335
|
-
layoutEpoch: 1,
|
|
336
|
-
areaIds: ["root:alpha", "root:beta"],
|
|
337
|
-
resolveArea: () => "root:alpha",
|
|
338
|
-
maxRecordsBeforeCompaction: 2,
|
|
339
|
-
}).read()).toThrow(/present in multiple areas/);
|
|
340
|
-
});
|
|
341
|
-
it("does not create a duplicate when a key stops routing but its area still holds it", () => {
|
|
342
|
-
// The prevention half. `root:gamma` is still a configured area holding
|
|
343
|
-
// the row; the key no longer resolves to it. The append must go to the
|
|
344
|
-
// area that already owns the row, NOT to the overflow.
|
|
345
|
-
const root = makeRoot();
|
|
346
|
-
openWide(root).append({ upserts: { "gamma/g.md": entry(1) } });
|
|
347
|
-
const stranded = AreaLedger.open({
|
|
348
|
-
rootDir: root,
|
|
349
|
-
journalSlug: "personal-vault",
|
|
350
|
-
layoutEpoch: 1,
|
|
351
|
-
areaIds: ["root:alpha", "root:gamma"],
|
|
352
|
-
// `gamma/` was excluded, so it routes nowhere now.
|
|
353
|
-
resolveArea: (key) => (key.startsWith("alpha/") ? "root:alpha" : undefined),
|
|
354
|
-
maxRecordsBeforeCompaction: 2,
|
|
355
|
-
});
|
|
356
|
-
stranded.append({ upserts: { "gamma/g.md": entry(3) } });
|
|
357
|
-
const directories = stranded.stateDirectoriesForTest();
|
|
358
|
-
const walk = (at) => fs.readdirSync(at, { withFileTypes: true }).flatMap((item) => {
|
|
359
|
-
const full = path.join(at, item.name);
|
|
360
|
-
return item.isDirectory() ? walk(full) : [fs.readFileSync(full, "utf8")];
|
|
361
|
-
});
|
|
362
|
-
const text = (dir) => (fs.existsSync(dir) ? walk(dir).join("\n") : "");
|
|
363
|
-
expect(text(UNROUTED_AREA_ID in Object.fromEntries(directories) ? directories.get(UNROUTED_AREA_ID) : "")).not.toContain("gamma/g.md");
|
|
364
|
-
expect(stranded.read().files["gamma/g.md"]?.size).toBe(3);
|
|
365
|
-
});
|
|
366
|
-
it("still routes a genuinely new unplaceable key to the overflow area", () => {
|
|
367
|
-
// The prevention must not swallow the case the overflow area exists for:
|
|
368
|
-
// a key no area has ever held still belongs in the overflow.
|
|
369
|
-
const root = makeRoot();
|
|
370
|
-
const ledger = openNarrow(root);
|
|
371
|
-
ledger.append({ upserts: { "delta/new.md": entry(1) } });
|
|
372
|
-
const directories = ledger.stateDirectoriesForTest();
|
|
373
|
-
const walk = (at) => fs.readdirSync(at, { withFileTypes: true }).flatMap((item) => {
|
|
374
|
-
const full = path.join(at, item.name);
|
|
375
|
-
return item.isDirectory() ? walk(full) : [fs.readFileSync(full, "utf8")];
|
|
376
|
-
});
|
|
377
|
-
expect(walk(directories.get(UNROUTED_AREA_ID)).join("\n")).toContain("delta/new.md");
|
|
378
|
-
});
|
|
379
|
-
it("reads a stranded row back through readRows right after an append", () => {
|
|
380
|
-
// Codex P1 on #502. `append()` clears the aggregate cache, and the
|
|
381
|
-
// area-authoritative migration path calls `verifyDeltaParity` -> `readRows`
|
|
382
|
-
// immediately afterwards. With a cold cache the row lookup used to have
|
|
383
|
-
// no opinion, so a key the layout can no longer route was read from the
|
|
384
|
-
// overflow area rather than from the real area the append had just
|
|
385
|
-
// written it to — returning undefined (or the stale overflow copy) and
|
|
386
|
-
// failing parity on every mutation of that key.
|
|
387
|
-
const root = makeRoot();
|
|
388
|
-
openWide(root).append({ upserts: { "gamma/g.md": entry(1) } });
|
|
389
|
-
const stranded = AreaLedger.open({
|
|
390
|
-
rootDir: root,
|
|
391
|
-
journalSlug: "personal-vault",
|
|
392
|
-
layoutEpoch: 1,
|
|
393
|
-
areaIds: ["root:alpha", "root:gamma"],
|
|
394
|
-
resolveArea: (key) => (key.startsWith("alpha/") ? "root:alpha" : undefined),
|
|
395
|
-
maxRecordsBeforeCompaction: 2,
|
|
396
|
-
});
|
|
397
|
-
stranded.append({ upserts: { "gamma/g.md": entry(7) } });
|
|
398
|
-
expect(stranded.readRows(["gamma/g.md"])["gamma/g.md"]).toMatchObject({ size: 7 });
|
|
399
|
-
expect(stranded.readScoped(["gamma/g.md"]).files["gamma/g.md"]).toMatchObject({ size: 7 });
|
|
400
|
-
});
|
|
401
|
-
it("keeps the real area's value when only the overflow area is refreshed", () => {
|
|
402
|
-
// Codex P1 on #502. The incremental refresh removes every key the
|
|
403
|
-
// refreshed area used to hold before reinstalling. For a duplicated key
|
|
404
|
-
// that removal also dropped the REAL area's winning value, so the
|
|
405
|
-
// collision guard never fired and the stale overflow entry was installed
|
|
406
|
-
// as the aggregate value — or the key vanished entirely when the overflow
|
|
407
|
-
// copy had been removed.
|
|
408
|
-
const root = makeRoot();
|
|
409
|
-
seedDuplicate(root);
|
|
410
|
-
const reader = openWide(root);
|
|
411
|
-
expect(reader.read().files["gamma/g.md"]?.size).toBe(1);
|
|
412
|
-
// Another process changes ONLY the overflow area.
|
|
413
|
-
openNarrow(root).append({ upserts: { "delta/other.md": entry(9) } });
|
|
414
|
-
expect(reader.read().files["gamma/g.md"]?.size).toBe(1);
|
|
415
|
-
// ...and again when the overflow copy is removed outright.
|
|
416
|
-
openNarrow(root).append({ deletes: ["gamma/g.md"] });
|
|
417
|
-
expect(reader.read().files["gamma/g.md"]?.size).toBe(1);
|
|
418
|
-
});
|
|
419
|
-
it("lets a delete reach the row after the duplicate has been healed", () => {
|
|
420
|
-
// The user-visible symptom was that deletes never stuck. Healing the read
|
|
421
|
-
// is not enough on its own — the row must still be removable.
|
|
422
|
-
const root = makeRoot();
|
|
423
|
-
seedDuplicate(root);
|
|
424
|
-
const ledger = openWide(root);
|
|
425
|
-
// Read first, which is the order the sync runner uses: opening the
|
|
426
|
-
// journal store primes the aggregate cache before anything is written.
|
|
427
|
-
// That read is what notices the duplicate, and the append that follows
|
|
428
|
-
// is what drops the stale overflow copy.
|
|
429
|
-
ledger.read();
|
|
430
|
-
expect(() => ledger.append({ deletes: ["gamma/g.md"] })).not.toThrow();
|
|
431
|
-
expect(openWide(root).read().files["gamma/g.md"]).toBeUndefined();
|
|
432
|
-
});
|
|
433
|
-
it("lets a delete reach the row when nothing read the aggregate first", () => {
|
|
434
|
-
// Convergence must not be conditional on a prior aggregate read. An
|
|
435
|
-
// area-authoritative scoped pass never calls the aggregate path, so a
|
|
436
|
-
// ledger whose duplicate has never been observed still has to drop the
|
|
437
|
-
// overflow copy on the delete that removes the real one — otherwise the
|
|
438
|
-
// stale copy resurfaces and the row is undeletable, which is the
|
|
439
|
-
// production symptom this whole fix exists to remove.
|
|
440
|
-
const root = makeRoot();
|
|
441
|
-
seedDuplicate(root);
|
|
442
|
-
openWide(root).append({ deletes: ["gamma/g.md"] });
|
|
443
|
-
expect(openWide(root).read().files["gamma/g.md"]).toBeUndefined();
|
|
444
|
-
});
|
|
445
|
-
it("reads the live value after another process moves a stranded key to the overflow", () => {
|
|
446
|
-
// A warm cache records where a stranded key lived when it was primed.
|
|
447
|
-
// If another process then removes it from that real area and recreates
|
|
448
|
-
// it in the overflow, the cached owner is stale: refreshing only the now
|
|
449
|
-
// empty real area reports the key as missing even though its current
|
|
450
|
-
// value is on disk.
|
|
451
|
-
const root = makeRoot();
|
|
452
|
-
openWide(root).append({ upserts: { "gamma/g.md": entry(1) } });
|
|
453
|
-
const reader = openStranded(root);
|
|
454
|
-
expect(reader.read().files["gamma/g.md"]?.size).toBe(1);
|
|
455
|
-
// Another process empties the real area, then writes the key afresh.
|
|
456
|
-
// With `root:gamma` no longer holding it, that write takes the overflow.
|
|
457
|
-
openWide(root).append({ deletes: ["gamma/g.md"] });
|
|
458
|
-
openStranded(root).append({ upserts: { "gamma/g.md": entry(2) } });
|
|
459
|
-
expect(reader.read().files["gamma/g.md"]?.size).toBe(2);
|
|
460
|
-
expect(reader.readRows(["gamma/g.md"])["gamma/g.md"]?.size).toBe(2);
|
|
461
|
-
expect(reader.readScoped(["gamma/g.md"]).files["gamma/g.md"]?.size).toBe(2);
|
|
462
|
-
});
|
|
463
|
-
it("evicts an overflow copy that only became visible when its watermark landed", () => {
|
|
464
|
-
// The convergence probe memoizes what the overflow area holds, keyed on
|
|
465
|
-
// that area's on-disk generation. A row the overflow has PREPARED becomes
|
|
466
|
-
// visible when its watermark is published, and that write lands in meta —
|
|
467
|
-
// the overflow area's own generation never moves. A memo built in that
|
|
468
|
-
// window keeps answering "no row here", so the delete of the real copy
|
|
469
|
-
// skips the eviction and the row resurfaces.
|
|
470
|
-
//
|
|
471
|
-
// The window only exists INSIDE another writer's transaction, which is
|
|
472
|
-
// why this interleaves rather than crashing and recovering: a prepare
|
|
473
|
-
// abandoned before its watermark is discarded by recovery, never
|
|
474
|
-
// published, so it cannot produce this state.
|
|
475
|
-
const root = makeRoot();
|
|
476
|
-
openWide(root).append({ upserts: { "gamma/g.md": entry(1) } });
|
|
477
|
-
const ledger = openWide(root);
|
|
478
|
-
setAreaLedgerTestHooksForTest({
|
|
479
|
-
// Mid-transaction, after the overflow prepare is on disk and before its
|
|
480
|
-
// watermark: the long-lived instance builds its memo here, and sees no
|
|
481
|
-
// overflow row because the transaction is not yet visible.
|
|
482
|
-
afterDataBeforeWatermark: () => {
|
|
483
|
-
ledger.append({ upserts: { "gamma/other.md": entry(3) } });
|
|
484
|
-
},
|
|
485
|
-
afterWatermarkBeforeFinalize: () => {
|
|
486
|
-
throw new Error("simulated crash after watermark");
|
|
487
|
-
},
|
|
488
|
-
});
|
|
489
|
-
// A build that cannot see `root:gamma` writes the same key to the
|
|
490
|
-
// overflow, spanning the overflow and `root:alpha`.
|
|
491
|
-
expect(() => openNarrow(root).append({ upserts: { "gamma/g.md": entry(2), "alpha/a.md": entry(9) } })).toThrow("simulated crash after watermark");
|
|
492
|
-
setAreaLedgerTestHooksForTest(undefined);
|
|
493
|
-
ledger.append({ deletes: ["gamma/g.md"] });
|
|
494
|
-
expect(openWide(root).read().files["gamma/g.md"]).toBeUndefined();
|
|
495
|
-
});
|
|
496
|
-
it("sees a published cross-area row when probing for a stranded key's owner", () => {
|
|
497
|
-
// Visibility is per-area: whether a transaction counts as committed is
|
|
498
|
-
// computed from the areas that transaction NAMES. Probing candidate areas
|
|
499
|
-
// one at a time therefore has to recompute it per probe. Carrying the
|
|
500
|
-
// first candidate's answer forward hides a row that was published but not
|
|
501
|
-
// yet finalized, the probe reports the real owner as empty, and the key
|
|
502
|
-
// is treated as unplaceable — so its next delete or update goes to the
|
|
503
|
-
// overflow while the original row stays put.
|
|
504
|
-
const root = makeRoot();
|
|
505
|
-
const areaIds = ["root:alpha", "root:beta", "root:gamma"];
|
|
506
|
-
const writer = AreaLedger.open({
|
|
507
|
-
rootDir: root,
|
|
508
|
-
journalSlug: "personal-vault",
|
|
509
|
-
layoutEpoch: 1,
|
|
510
|
-
areaIds,
|
|
511
|
-
resolveArea: (key) => `root:${key.split("/")[0]}`,
|
|
512
|
-
maxRecordsBeforeCompaction: 2,
|
|
513
|
-
});
|
|
514
|
-
// Publish a transaction naming beta and gamma, then crash before it is
|
|
515
|
-
// finalized. `root:alpha` — the first candidate probed — does not name it.
|
|
516
|
-
setAreaLedgerTestHooksForTest({
|
|
517
|
-
afterWatermarkBeforeFinalize: () => {
|
|
518
|
-
throw new Error("simulated crash after watermark");
|
|
519
|
-
},
|
|
520
|
-
});
|
|
521
|
-
expect(() => writer.append({ upserts: { "beta/b.md": entry(1), "gamma/g.md": entry(2) } })).toThrow("simulated crash after watermark");
|
|
522
|
-
setAreaLedgerTestHooksForTest(undefined);
|
|
523
|
-
const stranded = AreaLedger.open({
|
|
524
|
-
rootDir: root,
|
|
525
|
-
journalSlug: "personal-vault",
|
|
526
|
-
layoutEpoch: 1,
|
|
527
|
-
areaIds,
|
|
528
|
-
resolveArea: (key) => (key.startsWith("alpha/") ? "root:alpha" : undefined),
|
|
529
|
-
maxRecordsBeforeCompaction: 2,
|
|
530
|
-
});
|
|
531
|
-
expect(stranded.readRows(["gamma/g.md"])["gamma/g.md"]?.size).toBe(2);
|
|
532
|
-
});
|
|
533
|
-
it("reads the live value after another process moves a stranded key into a real area", () => {
|
|
534
|
-
// The mirror of the move-to-overflow case. A warm cache can record that
|
|
535
|
-
// NO real area holds a stranded key, so it resolves to the overflow; if
|
|
536
|
-
// another process — one whose layout still routes the key — then writes
|
|
537
|
-
// it into a real area, the cached answer sends the read to the overflow
|
|
538
|
-
// and returns the stale value or nothing at all.
|
|
539
|
-
const root = makeRoot();
|
|
540
|
-
openNarrow(root).append({ upserts: { "gamma/g.md": entry(2) } });
|
|
541
|
-
const reader = openStranded(root);
|
|
542
|
-
expect(reader.read().files["gamma/g.md"]?.size).toBe(2);
|
|
543
|
-
// A build that CAN route the key writes it to `root:gamma`, and converges
|
|
544
|
-
// the overflow copy away in the same append.
|
|
545
|
-
openWide(root).append({ upserts: { "gamma/g.md": entry(1) } });
|
|
546
|
-
expect(reader.readRows(["gamma/g.md"])["gamma/g.md"]?.size).toBe(1);
|
|
547
|
-
expect(reader.readScoped(["gamma/g.md"]).files["gamma/g.md"]?.size).toBe(1);
|
|
548
|
-
});
|
|
549
|
-
it("still throws when an incremental refresh is what reveals two REAL areas", () => {
|
|
550
|
-
// The real-vs-real invariant has to hold on the incremental path too. A
|
|
551
|
-
// full rebuild rejects this state; an incremental refresh that only looks
|
|
552
|
-
// at the one changed area must not quietly install whichever copy was
|
|
553
|
-
// written last.
|
|
554
|
-
const root = makeRoot();
|
|
555
|
-
const reader = openWide(root);
|
|
556
|
-
reader.append({ upserts: { "gamma/g.md": entry(1) } });
|
|
557
|
-
expect(reader.read().files["gamma/g.md"]?.size).toBe(1);
|
|
558
|
-
// An external writer with a different layout puts the SAME key into
|
|
559
|
-
// `root:alpha`, which no overflow copy is involved in.
|
|
560
|
-
AreaLedger.open({
|
|
561
|
-
rootDir: root,
|
|
562
|
-
journalSlug: "personal-vault",
|
|
563
|
-
layoutEpoch: 1,
|
|
564
|
-
areaIds: ["root:alpha"],
|
|
565
|
-
resolveArea: () => "root:alpha",
|
|
566
|
-
maxRecordsBeforeCompaction: 2,
|
|
567
|
-
}).append({ upserts: { "gamma/g.md": entry(2) } });
|
|
568
|
-
expect(() => reader.read()).toThrow(/present in multiple areas/);
|
|
569
|
-
});
|
|
570
|
-
});
|
|
571
|
-
describe("AreaLedger", () => {
|
|
572
|
-
const makeEventReplayFixture = () => {
|
|
573
|
-
const root = makeRoot();
|
|
574
|
-
const keys = Array.from({ length: 24 }, (_, index) => `alpha/random-${String(index).padStart(2, "0")}.md`);
|
|
575
|
-
const initialFiles = Object.fromEntries(keys.map((key, index) => [key, entry(index)]));
|
|
576
|
-
let routeKnown = true;
|
|
577
|
-
const ledger = AreaLedger.open({
|
|
578
|
-
rootDir: root,
|
|
579
|
-
journalSlug: "personal-vault",
|
|
580
|
-
layoutEpoch: 1,
|
|
581
|
-
areaIds: ["root:alpha"],
|
|
582
|
-
resolveArea: (key) => routeKnown && key.startsWith("alpha/") ? "root:alpha" : undefined,
|
|
583
|
-
initialJournal: { version: "2", lastSync: "", files: initialFiles, pulls: [] },
|
|
584
|
-
maxRecordsBeforeCompaction: 10_000,
|
|
585
|
-
maxWalBytesBeforeCompaction: 128 * 1024 * 1024,
|
|
586
|
-
});
|
|
587
|
-
const deltas = [];
|
|
588
|
-
const append = (delta) => {
|
|
589
|
-
deltas.push(delta);
|
|
590
|
-
ledger.append(delta);
|
|
591
|
-
};
|
|
592
|
-
const preparedDelta = { deletes: [keys[3]], upserts: { [keys[4]]: entry(1_004) } };
|
|
593
|
-
deltas.push(preparedDelta);
|
|
594
|
-
setAreaLedgerTestHooksForTest({
|
|
595
|
-
afterWatermarkBeforeFinalize: () => { throw new Error("leave committed prepare visible"); },
|
|
596
|
-
});
|
|
597
|
-
expect(() => ledger.append({
|
|
598
|
-
...preparedDelta,
|
|
599
|
-
metadata: { lastSync: "prepared", pulls: [] },
|
|
600
|
-
})).toThrow("leave committed prepare visible");
|
|
601
|
-
setAreaLedgerTestHooksForTest(undefined);
|
|
602
|
-
append({ deletes: [keys[0]], upserts: {} });
|
|
603
|
-
append({ deletes: [], upserts: { [keys[0]]: entry(2_001) } });
|
|
604
|
-
append({ deletes: [], upserts: { [keys[1]]: entry(3_001) } });
|
|
605
|
-
append({ deletes: [keys[1]], upserts: {} });
|
|
606
|
-
append({ deletes: [keys[2]], upserts: { [keys[2]]: entry(5_001) } });
|
|
607
|
-
let randomState = 0x6d2b79f5;
|
|
608
|
-
const random = () => {
|
|
609
|
-
randomState = (Math.imul(randomState, 1_664_525) + 1_013_904_223) >>> 0;
|
|
610
|
-
return randomState / 0x1_0000_0000;
|
|
611
|
-
};
|
|
612
|
-
for (let eventIndex = 0; eventIndex < 32; eventIndex += 1) {
|
|
613
|
-
const deletes = new Set();
|
|
614
|
-
const upserts = {};
|
|
615
|
-
const deleteCount = 1 + Math.floor(random() * 4);
|
|
616
|
-
const upsertCount = 1 + Math.floor(random() * 4);
|
|
617
|
-
for (let index = 0; index < deleteCount; index += 1) {
|
|
618
|
-
deletes.add(keys[Math.floor(random() * keys.length)]);
|
|
619
|
-
}
|
|
620
|
-
for (let index = 0; index < upsertCount; index += 1) {
|
|
621
|
-
const key = keys[Math.floor(random() * keys.length)];
|
|
622
|
-
upserts[key] = entry(10_000 + eventIndex * 10 + index);
|
|
623
|
-
}
|
|
624
|
-
append({ deletes: [...deletes], upserts });
|
|
625
|
-
}
|
|
626
|
-
const oldPerKeyMaterialization = (key) => {
|
|
627
|
-
let row = initialFiles[key];
|
|
628
|
-
for (const delta of deltas) {
|
|
629
|
-
if (delta.deletes.includes(key))
|
|
630
|
-
row = undefined;
|
|
631
|
-
if (delta.upserts[key] !== undefined)
|
|
632
|
-
row = delta.upserts[key];
|
|
633
|
-
}
|
|
634
|
-
return row;
|
|
635
|
-
};
|
|
636
|
-
return {
|
|
637
|
-
ledger,
|
|
638
|
-
keys,
|
|
639
|
-
oldPerKeyMaterialization,
|
|
640
|
-
eventCount: deltas.length,
|
|
641
|
-
setRouteKnown: (value) => { routeKnown = value; },
|
|
642
|
-
};
|
|
643
|
-
};
|
|
644
|
-
it("matches the old per-key fold while visiting direct events once in readRows", () => {
|
|
645
|
-
const { ledger, keys, oldPerKeyMaterialization, eventCount } = makeEventReplayFixture();
|
|
646
|
-
const expected = {};
|
|
647
|
-
for (const key of keys)
|
|
648
|
-
expected[key] = oldPerKeyMaterialization(key);
|
|
649
|
-
let eventVisits = 0;
|
|
650
|
-
setAreaLedgerTestHooksForTest({ onMaterializeEvent: () => { eventVisits += 1; } });
|
|
651
|
-
expect(ledger.readRows(keys)).toEqual(expected);
|
|
652
|
-
expect(eventVisits).toBe(eventCount);
|
|
653
|
-
});
|
|
654
|
-
it("folds a stranded-row probe tail once per area before reading requested rows", () => {
|
|
655
|
-
const { ledger, keys, oldPerKeyMaterialization, eventCount, setRouteKnown } = makeEventReplayFixture();
|
|
656
|
-
setRouteKnown(false);
|
|
657
|
-
const expected = {};
|
|
658
|
-
for (const key of keys)
|
|
659
|
-
expected[key] = oldPerKeyMaterialization(key);
|
|
660
|
-
let eventVisits = 0;
|
|
661
|
-
setAreaLedgerTestHooksForTest({ onMaterializeEvent: () => { eventVisits += 1; } });
|
|
662
|
-
expect(ledger.readRows(keys)).toEqual(expected);
|
|
663
|
-
// One event fold establishes presence for stranded-key placement; the
|
|
664
|
-
// second materializes the requested values. Work remains independent of
|
|
665
|
-
// the number of probes rather than replaying the tail per key.
|
|
666
|
-
expect(eventVisits).toBe(eventCount * 2);
|
|
667
|
-
});
|
|
668
|
-
it("folds readRowsUnder descendants in one pass over the direct events", () => {
|
|
669
|
-
const { ledger, keys, oldPerKeyMaterialization, eventCount } = makeEventReplayFixture();
|
|
670
|
-
const expected = {};
|
|
671
|
-
for (const key of keys) {
|
|
672
|
-
const row = oldPerKeyMaterialization(key);
|
|
673
|
-
if (row !== undefined)
|
|
674
|
-
expected[key] = row;
|
|
675
|
-
}
|
|
676
|
-
let eventVisits = 0;
|
|
677
|
-
setAreaLedgerTestHooksForTest({ onMaterializeEvent: () => { eventVisits += 1; } });
|
|
678
|
-
expect(ledger.readRowsUnder(["alpha"], ["root:alpha"])).toEqual(expected);
|
|
679
|
-
expect(eventVisits).toBe(eventCount);
|
|
680
|
-
});
|
|
681
|
-
it("allows two processes to append independent areas through distinct append locks", async () => {
|
|
682
|
-
const root = makeRoot();
|
|
683
|
-
const child = spawn(process.execPath, [path.join(process.cwd(), "node_modules/vitest/vitest.mjs"), "run", "src/sync/area-ledger.test.ts", "--no-file-parallelism"], {
|
|
684
|
-
cwd: process.cwd(),
|
|
685
|
-
env: { ...process.env, AREA_LEDGER_CHILD_ROOT: root },
|
|
686
|
-
stdio: "pipe",
|
|
687
|
-
});
|
|
688
|
-
const parent = open(root);
|
|
689
|
-
parent.append({ upserts: { "alpha/from-parent.md": entry(1) } });
|
|
690
|
-
await exitCode(child);
|
|
691
|
-
const reopened = open(root);
|
|
692
|
-
expect(reopened.read().files).toMatchObject({
|
|
693
|
-
"alpha/from-parent.md": { size: 1 },
|
|
694
|
-
"beta/from-child.md": { size: 2 },
|
|
695
|
-
});
|
|
696
|
-
const directories = reopened.stateDirectoriesForTest();
|
|
697
|
-
const alphaLock = path.join(directories.get("root:alpha"), "append.lock");
|
|
698
|
-
const betaLock = path.join(directories.get("root:beta"), "append.lock");
|
|
699
|
-
expect(alphaLock).not.toBe(betaLock);
|
|
700
|
-
expect(fs.existsSync(alphaLock)).toBe(false);
|
|
701
|
-
expect(fs.existsSync(betaLock)).toBe(false);
|
|
702
|
-
}, 30_000);
|
|
703
|
-
it("preserves same-area append ordering and durability", () => {
|
|
704
|
-
const root = makeRoot();
|
|
705
|
-
const first = open(root);
|
|
706
|
-
const second = open(root);
|
|
707
|
-
first.append({ upserts: { "alpha/one.md": entry(1) } });
|
|
708
|
-
second.append({ upserts: { "alpha/two.md": entry(2) } });
|
|
709
|
-
expect(open(root).readScoped(["alpha/one.md", "alpha/two.md"]).files).toMatchObject({
|
|
710
|
-
"alpha/one.md": { size: 1 },
|
|
711
|
-
"alpha/two.md": { size: 2 },
|
|
712
|
-
});
|
|
713
|
-
});
|
|
714
|
-
it("opens only the routed data area for a scoped read", () => {
|
|
715
|
-
const root = makeRoot();
|
|
716
|
-
const ledger = open(root);
|
|
717
|
-
ledger.append({ upserts: { "alpha/one.md": entry(1) } });
|
|
718
|
-
ledger.append({ upserts: { "beta/two.md": entry(2) } });
|
|
719
|
-
const scoped = open(root);
|
|
720
|
-
expect(scoped.readScoped(["alpha/one.md"])).toMatchObject({ files: { "alpha/one.md": { size: 1 } } });
|
|
721
|
-
// Scoped reads refresh @meta so they can include a committed prepare.
|
|
722
|
-
// No unrelated beta data store is needed when no watermark names it.
|
|
723
|
-
expect(scoped.openedAreasForTest()).toEqual(["@meta", "root:alpha"]);
|
|
724
|
-
});
|
|
725
|
-
it("materializes scoped delete roots only by exact key or matching descendant", () => {
|
|
726
|
-
const root = makeRoot();
|
|
727
|
-
const files = Object.fromEntries(Array.from({ length: 1_000 }, (_, index) => [`alpha/unrelated/${index}.md`, entry(index)]));
|
|
728
|
-
Object.assign(files, {
|
|
729
|
-
"alpha/removed-dir/one.md": entry(1_001),
|
|
730
|
-
"alpha/removed-dir/two.md": entry(1_002),
|
|
731
|
-
});
|
|
732
|
-
const writer = open(root, { version: "2", lastSync: "", files, pulls: [] });
|
|
733
|
-
writer.append({
|
|
734
|
-
upserts: {
|
|
735
|
-
"alpha/removed-file.md": entry(1_003),
|
|
736
|
-
"alpha/removed-dir/from-visible-delta.md": entry(1_004),
|
|
737
|
-
},
|
|
738
|
-
});
|
|
739
|
-
const reader = open(root);
|
|
740
|
-
const materialized = [];
|
|
741
|
-
setAreaLedgerTestHooksForTest({ onMaterializeRow: (key) => materialized.push(key) });
|
|
742
|
-
expect(reader.readRowsUnder(["alpha/removed-file.md"], ["root:alpha"])).toMatchObject({
|
|
743
|
-
"alpha/removed-file.md": { size: 1_003 },
|
|
744
|
-
});
|
|
745
|
-
expect(materialized).toEqual(["alpha/removed-file.md"]);
|
|
746
|
-
materialized.length = 0;
|
|
747
|
-
const directoryRows = reader.readRowsUnder(["alpha/removed-dir"], ["root:alpha"]);
|
|
748
|
-
expect(directoryRows).toMatchObject({
|
|
749
|
-
"alpha/removed-dir/one.md": { size: 1_001 },
|
|
750
|
-
"alpha/removed-dir/two.md": { size: 1_002 },
|
|
751
|
-
"alpha/removed-dir/from-visible-delta.md": { size: 1_004 },
|
|
752
|
-
});
|
|
753
|
-
// The missing exact root is probed once; only matching descendants are
|
|
754
|
-
// materialized, never the thousand unrelated rows in this area.
|
|
755
|
-
expect(materialized).toHaveLength(Object.keys(directoryRows).length + 1);
|
|
756
|
-
});
|
|
757
|
-
it("keeps empty roots, exact rows, and path-segment matching equivalent", () => {
|
|
758
|
-
const root = makeRoot();
|
|
759
|
-
const writer = open(root, {
|
|
760
|
-
version: "2",
|
|
761
|
-
lastSync: "",
|
|
762
|
-
files: {
|
|
763
|
-
"alpha/a/b/file.md": entry(1),
|
|
764
|
-
"alpha/a/bc/file.md": entry(2),
|
|
765
|
-
"alpha/exact.md": entry(3),
|
|
766
|
-
},
|
|
767
|
-
pulls: [],
|
|
768
|
-
});
|
|
769
|
-
const exact = writer.readRowsUnder(["alpha/exact.md"], ["root:alpha"]);
|
|
770
|
-
expect(Object.keys(exact)).toEqual(["alpha/exact.md"]);
|
|
771
|
-
const directory = writer.readRowsUnder(["alpha/a/b"], ["root:alpha"]);
|
|
772
|
-
expect(Object.keys(directory)).toEqual(["alpha/a/b/file.md"]);
|
|
773
|
-
const all = writer.readRowsUnder([""], ["root:alpha"]);
|
|
774
|
-
expect(Object.keys(all).sort()).toEqual([
|
|
775
|
-
"alpha/a/b/file.md",
|
|
776
|
-
"alpha/a/bc/file.md",
|
|
777
|
-
"alpha/exact.md",
|
|
778
|
-
]);
|
|
779
|
-
});
|
|
780
|
-
it("orders a prepared update before later direct updates and deletes", () => {
|
|
781
|
-
const root = makeRoot();
|
|
782
|
-
const ledger = open(root);
|
|
783
|
-
ledger.append({ upserts: { "alpha/x.md": entry(1) }, metadata: { lastSync: "prepared", pulls: [] } });
|
|
784
|
-
ledger.append({ upserts: { "alpha/x.md": entry(2) } });
|
|
785
|
-
expect(ledger.read().files["alpha/x.md"]).toMatchObject({ size: 2 });
|
|
786
|
-
ledger.append({ upserts: { "alpha/x.md": entry(3) }, metadata: { lastSync: "prepared-again", pulls: [] } });
|
|
787
|
-
ledger.append({ deletes: ["alpha/x.md"] });
|
|
788
|
-
expect(ledger.read().files["alpha/x.md"]).toBeUndefined();
|
|
789
|
-
});
|
|
790
|
-
it("includes committed multi-area prepares in scoped reads and refreshes cached stores", () => {
|
|
791
|
-
const root = makeRoot();
|
|
792
|
-
const reader = open(root);
|
|
793
|
-
expect(reader.readScoped(["alpha/one.md"]).files).toEqual({});
|
|
794
|
-
const writer = open(root);
|
|
795
|
-
writer.append({
|
|
796
|
-
upserts: { "alpha/one.md": entry(1), "beta/two.md": entry(2) },
|
|
797
|
-
metadata: { lastSync: "visible", pulls: [] },
|
|
798
|
-
});
|
|
799
|
-
expect(reader.readScoped(["alpha/one.md"])).toMatchObject({
|
|
800
|
-
lastSync: "visible",
|
|
801
|
-
files: { "alpha/one.md": { size: 1 } },
|
|
802
|
-
});
|
|
803
|
-
});
|
|
804
|
-
it("keeps a warm aggregate connected after a scoped read", () => {
|
|
805
|
-
const root = makeRoot();
|
|
806
|
-
const writer = open(root);
|
|
807
|
-
writer.append({ upserts: { "alpha/one.md": entry(1) } });
|
|
808
|
-
const reader = open(root);
|
|
809
|
-
expect(reader.read().files["alpha/one.md"]?.size).toBe(1);
|
|
810
|
-
expect(reader.readScoped(["alpha/one.md"]).files["alpha/one.md"]?.size).toBe(1);
|
|
811
|
-
writer.append({ upserts: { "alpha/one.md": entry(2) } });
|
|
812
|
-
expect(reader.read().files["alpha/one.md"]?.size).toBe(2);
|
|
813
|
-
});
|
|
814
|
-
it("applies committed WAL records to a warm aggregate without replaying its growing tail", () => {
|
|
815
|
-
// The area writer now defers a snapshot until a bounded WAL threshold.
|
|
816
|
-
// A warm aggregate must apply each known durable delta directly: replaying
|
|
817
|
-
// all prior commits into an overlay after every append turns N small
|
|
818
|
-
// commits into O(N²) overlay work (and into a full-area CPU stall at
|
|
819
|
-
// production scale).
|
|
820
|
-
const root = makeRoot();
|
|
821
|
-
const ledger = AreaLedger.open({
|
|
822
|
-
rootDir: root,
|
|
823
|
-
journalSlug: "personal-vault",
|
|
824
|
-
layoutEpoch: 1,
|
|
825
|
-
areaIds: ["root:alpha", "root:beta"],
|
|
826
|
-
resolveArea: (key) => key.startsWith("alpha/") ? "root:alpha" : "root:beta",
|
|
827
|
-
maxRecordsBeforeCompaction: 128,
|
|
828
|
-
});
|
|
829
|
-
ledger.readCached();
|
|
830
|
-
const replay = vi.spyOn(JournalRowOverlay.prototype, "dirtyLogSnapshot");
|
|
831
|
-
for (let index = 0; index < 32; index += 1) {
|
|
832
|
-
ledger.append({
|
|
833
|
-
upserts: { [`alpha/watch/${index}.md`]: entry(index) },
|
|
834
|
-
metadata: { lastSync: `tail-${index}`, pulls: [] },
|
|
835
|
-
});
|
|
836
|
-
}
|
|
837
|
-
const aggregate = ledger.readCached().journal;
|
|
838
|
-
expect(aggregate.files["alpha/watch/31.md"]?.size).toBe(31);
|
|
839
|
-
expect(aggregate.lastSync).toBe("tail-31");
|
|
840
|
-
expect(replay).not.toHaveBeenCalled();
|
|
841
|
-
});
|
|
842
|
-
it("bounds a fresh area-ledger open to one committed WAL tail per changed store", () => {
|
|
843
|
-
// A cache miss may replay a WAL, but it must replay one bounded tail,
|
|
844
|
-
// not re-open/replay it for every scoped call. Thirty-two published
|
|
845
|
-
// alpha transactions leave 32 alpha records and 32 @meta records; beta
|
|
846
|
-
// and overflow have only headers. The opener therefore has exactly 64
|
|
847
|
-
// durable records to apply.
|
|
848
|
-
const root = makeRoot();
|
|
849
|
-
const writer = AreaLedger.open({
|
|
850
|
-
rootDir: root,
|
|
851
|
-
journalSlug: "personal-vault",
|
|
852
|
-
layoutEpoch: 1,
|
|
853
|
-
areaIds: ["root:alpha", "root:beta"],
|
|
854
|
-
resolveArea: (key) => key.startsWith("alpha/") ? "root:alpha" : "root:beta",
|
|
855
|
-
maxRecordsBeforeCompaction: 128,
|
|
856
|
-
});
|
|
857
|
-
for (let index = 0; index < 32; index += 1) {
|
|
858
|
-
writer.append({
|
|
859
|
-
upserts: { [`alpha/cold/${index}.md`]: entry(index) },
|
|
860
|
-
metadata: { lastSync: `cold-${index}`, pulls: [] },
|
|
861
|
-
});
|
|
862
|
-
}
|
|
863
|
-
let replayedRecords = 0;
|
|
864
|
-
setStateStoreWalRecordReadHookForTest(() => { replayedRecords += 1; });
|
|
865
|
-
const reader = AreaLedger.open({
|
|
866
|
-
rootDir: root,
|
|
867
|
-
journalSlug: "personal-vault",
|
|
868
|
-
layoutEpoch: 1,
|
|
869
|
-
areaIds: ["root:alpha", "root:beta"],
|
|
870
|
-
resolveArea: (key) => key.startsWith("alpha/") ? "root:alpha" : "root:beta",
|
|
871
|
-
maxRecordsBeforeCompaction: 128,
|
|
872
|
-
});
|
|
873
|
-
expect(reader.readCached().journal.files["alpha/cold/31.md"]?.size).toBe(31);
|
|
874
|
-
expect(replayedRecords).toBe(64);
|
|
875
|
-
expect(replayedRecords).toBeLessThan(128);
|
|
876
|
-
});
|
|
877
|
-
it("reconciles an unrelated area refreshed during a metadata publish", () => {
|
|
878
|
-
const root = makeRoot();
|
|
879
|
-
const ledger = open(root);
|
|
880
|
-
// Prime the long-lived packed aggregate before a separate writer begins
|
|
881
|
-
// a metadata-bearing transaction.
|
|
882
|
-
expect(ledger.read().files).toEqual({});
|
|
883
|
-
setAreaLedgerTestHooksForTest({
|
|
884
|
-
// The watermark is durable but the writer has not finalized its own
|
|
885
|
-
// area yet. A peer advances beta in this exact window, so the writer's
|
|
886
|
-
// all-area refresh must reconcile beta before it records new cache
|
|
887
|
-
// identities or the warm aggregate will stay stale forever.
|
|
888
|
-
afterWatermarkBeforeFinalize: () => {
|
|
889
|
-
const peer = open(root);
|
|
890
|
-
peer.append({ upserts: { "beta/concurrent.md": entry(2) } });
|
|
891
|
-
// A second append forces the tiny test store through its generation
|
|
892
|
-
// replacement path rather than exercising only a WAL tail.
|
|
893
|
-
peer.append({ upserts: { "beta/concurrent.md": entry(3) } });
|
|
894
|
-
},
|
|
895
|
-
});
|
|
896
|
-
ledger.append({
|
|
897
|
-
upserts: { "alpha/published.md": entry(1) },
|
|
898
|
-
metadata: { lastSync: "published", pulls: [] },
|
|
899
|
-
});
|
|
900
|
-
expect(ledger.read().files["alpha/published.md"]?.size).toBe(1);
|
|
901
|
-
expect(ledger.read().files["beta/concurrent.md"]?.size).toBe(3);
|
|
902
|
-
});
|
|
903
|
-
it("hides a watermark when independent recovery lost one named area prepare", () => {
|
|
904
|
-
const root = makeRoot();
|
|
905
|
-
const ledger = open(root);
|
|
906
|
-
setAreaLedgerTestHooksForTest({
|
|
907
|
-
afterWatermarkBeforeFinalize: () => { throw new Error("simulated crash after watermark"); },
|
|
908
|
-
});
|
|
909
|
-
expect(() => ledger.append({
|
|
910
|
-
upserts: { "alpha/one.md": entry(1), "beta/two.md": entry(2) },
|
|
911
|
-
metadata: { lastSync: "must-be-atomic", pulls: [] },
|
|
912
|
-
})).toThrow("simulated crash after watermark");
|
|
913
|
-
setAreaLedgerTestHooksForTest(undefined);
|
|
914
|
-
const betaDir = ledger.stateDirectoriesForTest().get("root:beta");
|
|
915
|
-
fs.rmSync(betaDir, { recursive: true, force: true });
|
|
916
|
-
expect(open(root).read().files).toEqual({});
|
|
917
|
-
});
|
|
918
|
-
it("retires published prepares and watermarks at the area WAL fold threshold", () => {
|
|
919
|
-
const root = makeRoot();
|
|
920
|
-
const ledger = open(root);
|
|
921
|
-
ledger.append({
|
|
922
|
-
upserts: { "alpha/one.md": entry(1), "beta/two.md": entry(2) },
|
|
923
|
-
metadata: { lastSync: "fold", pulls: [] },
|
|
924
|
-
});
|
|
925
|
-
// The first published transaction remains replayable in the WAL. This
|
|
926
|
-
// is the no-full-snapshot-per-scoped-commit contract; it is still fully
|
|
927
|
-
// visible to readers before a later bounded fold retires it.
|
|
928
|
-
expect(ledger.transactionCountsForTest()).toEqual({ prepared: 2, watermarks: 1, finalized: 0 });
|
|
929
|
-
expect(ledger.read().files).toMatchObject({ "alpha/one.md": { size: 1 }, "beta/two.md": { size: 2 } });
|
|
930
|
-
// `open()` sets a two-record test threshold. The second transaction
|
|
931
|
-
// reaches it and must fold both committed transactions atomically.
|
|
932
|
-
ledger.append({
|
|
933
|
-
upserts: { "alpha/three.md": entry(3), "beta/four.md": entry(4) },
|
|
934
|
-
metadata: { lastSync: "folded", pulls: [] },
|
|
935
|
-
});
|
|
936
|
-
expect(ledger.transactionCountsForTest()).toEqual({ prepared: 0, watermarks: 0, finalized: 0 });
|
|
937
|
-
expect(ledger.read().files).toMatchObject({
|
|
938
|
-
"alpha/one.md": { size: 1 },
|
|
939
|
-
"beta/two.md": { size: 2 },
|
|
940
|
-
"alpha/three.md": { size: 3 },
|
|
941
|
-
"beta/four.md": { size: 4 },
|
|
942
|
-
});
|
|
943
|
-
expect(ledger.transactionCountsForTest()).toEqual({ prepared: 0, watermarks: 0, finalized: 0 });
|
|
944
|
-
expect(open(root).read().files).toMatchObject({
|
|
945
|
-
"alpha/one.md": { size: 1 },
|
|
946
|
-
"beta/two.md": { size: 2 },
|
|
947
|
-
"alpha/three.md": { size: 3 },
|
|
948
|
-
"beta/four.md": { size: 4 },
|
|
949
|
-
});
|
|
950
|
-
});
|
|
951
|
-
it("returns the cached aggregate without refreshes, locks, appends, or recombination", () => {
|
|
952
|
-
const root = makeRoot();
|
|
953
|
-
const ledger = open(root);
|
|
954
|
-
ledger.append({ upserts: { "alpha/one.md": entry(1), "beta/two.md": entry(2) } });
|
|
955
|
-
expect(ledger.read().files).toMatchObject({ "alpha/one.md": { size: 1 }, "beta/two.md": { size: 2 } });
|
|
956
|
-
const refresh = vi.spyOn(StateStore.prototype, "refresh");
|
|
957
|
-
const append = vi.spyOn(StateStore.prototype, "append");
|
|
958
|
-
const replace = vi.spyOn(StateStore.prototype, "replaceStateWith");
|
|
959
|
-
const combine = vi.spyOn(ledger, "combine");
|
|
960
|
-
const cached = ledger.read();
|
|
961
|
-
expect(cached.files).toMatchObject({ "alpha/one.md": { size: 1 }, "beta/two.md": { size: 2 } });
|
|
962
|
-
expect(refresh).not.toHaveBeenCalled();
|
|
963
|
-
expect(append).not.toHaveBeenCalled();
|
|
964
|
-
expect(replace).not.toHaveBeenCalled();
|
|
965
|
-
expect(combine).not.toHaveBeenCalled();
|
|
966
|
-
cached.files["alpha/mutated.md"] = entry(3);
|
|
967
|
-
expect(ledger.read().files["alpha/mutated.md"]).toBeUndefined();
|
|
968
|
-
});
|
|
969
|
-
it("refreshes and re-materializes only changed stores in a 50-area cached ledger", () => {
|
|
970
|
-
const root = makeRoot();
|
|
971
|
-
const writer = openMany(root, 50);
|
|
972
|
-
for (let index = 0; index < 50; index++) {
|
|
973
|
-
writer.append({ upserts: { [`area-${index}/seed.md`]: entry(index) } });
|
|
974
|
-
}
|
|
975
|
-
const reader = openMany(root, 50);
|
|
976
|
-
expect(Object.keys(reader.read().files)).toHaveLength(50);
|
|
977
|
-
const refresh = vi.spyOn(StateStore.prototype, "refresh");
|
|
978
|
-
const combine = vi.spyOn(reader, "combine");
|
|
979
|
-
reader.read();
|
|
980
|
-
reader.read();
|
|
981
|
-
expect(refresh).not.toHaveBeenCalled();
|
|
982
|
-
expect(combine).not.toHaveBeenCalled();
|
|
983
|
-
writer.append({ upserts: { "area-17/changed.md": entry(99) } });
|
|
984
|
-
expect(reader.read().files["area-17/changed.md"]).toMatchObject({ size: 99 });
|
|
985
|
-
expect(refresh).toHaveBeenCalledTimes(1);
|
|
986
|
-
expect(combine).not.toHaveBeenCalled();
|
|
987
|
-
});
|
|
988
|
-
it("does not re-resolve every packed row for every area while rebuilding a phase-two aggregate", () => {
|
|
989
|
-
const root = makeRoot();
|
|
990
|
-
const areaCount = 50;
|
|
991
|
-
const rows = 2_000;
|
|
992
|
-
const areaIds = Array.from({ length: areaCount }, (_, index) => `root:area-${index}`);
|
|
993
|
-
let resolveCalls = 0;
|
|
994
|
-
const ledger = AreaLedger.open({
|
|
995
|
-
rootDir: root,
|
|
996
|
-
journalSlug: "personal-vault",
|
|
997
|
-
layoutEpoch: 1,
|
|
998
|
-
areaIds,
|
|
999
|
-
resolveArea: (key) => {
|
|
1000
|
-
resolveCalls += 1;
|
|
1001
|
-
const index = Number(/^area-(\d+)\//.exec(key)?.[1]);
|
|
1002
|
-
return Number.isSafeInteger(index) && areaIds[index] !== undefined ? areaIds[index] : undefined;
|
|
1003
|
-
},
|
|
1004
|
-
});
|
|
1005
|
-
const upserts = {};
|
|
1006
|
-
for (let index = 0; index < rows; index += 1) {
|
|
1007
|
-
upserts[`area-${index % areaCount}/nested/entry-${index}.md`] = entry(index);
|
|
1008
|
-
}
|
|
1009
|
-
ledger.append({ upserts });
|
|
1010
|
-
// The first build gives every area its packed facade. Rebuild from those
|
|
1011
|
-
// facades to exercise the pass-open path that wedged phase two.
|
|
1012
|
-
ledger.readCached();
|
|
1013
|
-
resolveCalls = 0;
|
|
1014
|
-
ledger.invalidateAggregateCache();
|
|
1015
|
-
const aggregate = ledger.readCached().journal;
|
|
1016
|
-
expect(Object.keys(aggregate.files)).toHaveLength(rows);
|
|
1017
|
-
expect(resolveCalls).toBeLessThanOrEqual(rows + areaCount);
|
|
1018
|
-
expect(resolveCalls).toBe(rows);
|
|
1019
|
-
});
|
|
1020
|
-
it("recovers a fully prepared cross-area transaction by writing the watermark last", () => {
|
|
1021
|
-
const root = makeRoot();
|
|
1022
|
-
const ledger = open(root);
|
|
1023
|
-
setAreaLedgerTestHooksForTest({
|
|
1024
|
-
afterDataBeforeWatermark: () => { throw new Error("simulated process crash"); },
|
|
1025
|
-
});
|
|
1026
|
-
expect(() => ledger.append({
|
|
1027
|
-
upserts: { "alpha/one.md": entry(1), "beta/two.md": entry(2) },
|
|
1028
|
-
metadata: { lastSync: "watermark", pulls: [] },
|
|
1029
|
-
})).toThrow("simulated process crash");
|
|
1030
|
-
setAreaLedgerTestHooksForTest(undefined);
|
|
1031
|
-
expect(open(root).read()).toMatchObject({
|
|
1032
|
-
lastSync: "watermark",
|
|
1033
|
-
files: { "alpha/one.md": { size: 1 }, "beta/two.md": { size: 2 } },
|
|
1034
|
-
});
|
|
1035
|
-
});
|
|
1036
|
-
it("keeps appenders correct while one area compacts off-lock", () => {
|
|
1037
|
-
const root = makeRoot();
|
|
1038
|
-
const ledger = open(root);
|
|
1039
|
-
ledger.append({ upserts: { "alpha/one.md": entry(1) } });
|
|
1040
|
-
ledger.append({ upserts: { "alpha/two.md": entry(2) } });
|
|
1041
|
-
ledger.append({ upserts: { "beta/other.md": entry(3) } });
|
|
1042
|
-
expect(open(root).read().files).toMatchObject({
|
|
1043
|
-
"alpha/one.md": { size: 1 },
|
|
1044
|
-
"alpha/two.md": { size: 2 },
|
|
1045
|
-
"beta/other.md": { size: 3 },
|
|
1046
|
-
});
|
|
1047
|
-
});
|
|
1048
|
-
it("matches the legacy aggregate journal fixture while keeping the legacy adapter opt-in default", () => {
|
|
1049
|
-
const root = makeRoot();
|
|
1050
|
-
const legacy = {
|
|
1051
|
-
version: "2",
|
|
1052
|
-
lastSync: "before",
|
|
1053
|
-
files: { "alpha/one.md": entry(1), "beta/two.md": entry(2) },
|
|
1054
|
-
pulls: [],
|
|
1055
|
-
};
|
|
1056
|
-
const ledger = open(root, legacy);
|
|
1057
|
-
expect(ledger.read()).toEqual(legacy);
|
|
1058
|
-
legacy.files["alpha/three.md"] = entry(3);
|
|
1059
|
-
delete legacy.files["beta/two.md"];
|
|
1060
|
-
legacy.lastSync = "after";
|
|
1061
|
-
ledger.append({
|
|
1062
|
-
upserts: { "alpha/three.md": entry(3) },
|
|
1063
|
-
deletes: ["beta/two.md"],
|
|
1064
|
-
metadata: { lastSync: "after", pulls: [] },
|
|
1065
|
-
});
|
|
1066
|
-
expect(ledger.read()).toEqual(legacy);
|
|
1067
|
-
});
|
|
1068
|
-
it("keeps @meta on ordinary rotation thresholds when the areas are given migration limits", () => {
|
|
1069
|
-
const stateRoot = makeRoot();
|
|
1070
|
-
// Exactly the thresholds AreaLedgerMigration holds while it projects a
|
|
1071
|
-
// vault into areas. They are meant to keep a bulk area copy out of a
|
|
1072
|
-
// compaction loop; @meta is transaction bookkeeping and must not inherit
|
|
1073
|
-
// them, or its WAL grows for the life of the store. A controller reached
|
|
1074
|
-
// 224 MB / 47,291 records this way, and every process that opened the
|
|
1075
|
-
// vault replayed all of it before doing any work.
|
|
1076
|
-
const ledger = AreaLedger.open({
|
|
1077
|
-
rootDir: stateRoot,
|
|
1078
|
-
journalSlug: "personal-vault",
|
|
1079
|
-
layoutEpoch: 1,
|
|
1080
|
-
areaIds: ["root:alpha"],
|
|
1081
|
-
resolveArea: (key) => (key.startsWith("alpha/") ? "root:alpha" : undefined),
|
|
1082
|
-
maxRecordsBeforeCompaction: 1_000_000,
|
|
1083
|
-
maxWalBytesBeforeCompaction: 256 * 1024 * 1024,
|
|
1084
|
-
});
|
|
1085
|
-
// Every real sync transaction carries metadata, and metadata is what puts
|
|
1086
|
-
// a watermark/finalize pair into @meta. 150 transactions is 300 meta
|
|
1087
|
-
// records, past StateStore's ordinary 256-record threshold.
|
|
1088
|
-
for (let index = 1; index <= 150; index++) {
|
|
1089
|
-
ledger.append({
|
|
1090
|
-
upserts: { [`alpha/${index}`]: entry(index) },
|
|
1091
|
-
metadata: { lastSync: `2026-08-27T00:00:${String(index % 60).padStart(2, "0")}.000Z` },
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
1094
|
-
const metaDir = ledger.stateDirectoriesForTest().get("@meta");
|
|
1095
|
-
expect(metaDir).toBeDefined();
|
|
1096
|
-
const generationOf = (dir) => Math.max(...fs.readdirSync(dir)
|
|
1097
|
-
.filter((name) => /^snapshot-\d+\.bin$/.test(name))
|
|
1098
|
-
.map((name) => Number(/\d+/.exec(name)[0])));
|
|
1099
|
-
const generation = generationOf(metaDir);
|
|
1100
|
-
expect(generation).toBeGreaterThan(1);
|
|
1101
|
-
// The live WAL holds only what accumulated since the last fold, not all
|
|
1102
|
-
// 300 records.
|
|
1103
|
-
expect(fs.statSync(path.join(metaDir, `wal-${generation}.bin`)).size).toBeLessThan(128 * 1024);
|
|
1104
|
-
}, 120_000);
|
|
1105
|
-
it("caps @meta pull history at MAX_PULLS_PER_COMPANY and keeps the most recent records", () => {
|
|
1106
|
-
const root = makeRoot();
|
|
1107
|
-
const ledger = open(root);
|
|
1108
|
-
const pulls = [];
|
|
1109
|
-
for (let index = 0; index < MAX_PULLS_PER_COMPANY + 10; index++) {
|
|
1110
|
-
pulls.push(pullRecord(index));
|
|
1111
|
-
ledger.append({ metadata: { lastSync: `t${index}`, pulls: [...pulls] } });
|
|
1112
|
-
}
|
|
1113
|
-
const stored = open(root).read().pulls ?? [];
|
|
1114
|
-
expect(stored).toHaveLength(MAX_PULLS_PER_COMPANY);
|
|
1115
|
-
expect(stored.map((record) => record.pullId)).toEqual(Array.from({ length: MAX_PULLS_PER_COMPANY }, (_, offset) => pullRecord(offset + 10).pullId));
|
|
1116
|
-
});
|
|
1117
|
-
it("trims an already-oversized @meta pulls array down to the cap on the next write", () => {
|
|
1118
|
-
const root = makeRoot();
|
|
1119
|
-
const oversized = Array.from({ length: MAX_PULLS_PER_COMPANY + 10 }, (_, index) => pullRecord(index));
|
|
1120
|
-
const seeded = open(root, {
|
|
1121
|
-
version: "2",
|
|
1122
|
-
lastSync: "seeded",
|
|
1123
|
-
files: {},
|
|
1124
|
-
pulls: oversized,
|
|
1125
|
-
});
|
|
1126
|
-
expect(seeded.read().pulls).toHaveLength(MAX_PULLS_PER_COMPANY + 10);
|
|
1127
|
-
seeded.append({ metadata: { lastSync: "healed", pulls: oversized } });
|
|
1128
|
-
const stored = open(root).read().pulls ?? [];
|
|
1129
|
-
expect(stored).toHaveLength(MAX_PULLS_PER_COMPANY);
|
|
1130
|
-
expect(stored[0]?.pullId).toBe(pullRecord(10).pullId);
|
|
1131
|
-
expect(stored.at(-1)?.pullId).toBe(pullRecord(MAX_PULLS_PER_COMPANY + 9).pullId);
|
|
1132
|
-
});
|
|
1133
|
-
});
|
|
1134
|
-
describe("AreaLedger — one packed aggregate view, however many readers hold it", () => {
|
|
1135
|
-
// THE MEMORY-CEILING BUG.
|
|
1136
|
-
//
|
|
1137
|
-
// A personal vault on this fleet has ~690k journal rows. The ledger used to
|
|
1138
|
-
// deep-copy every one of them into each projection it built: the raw area
|
|
1139
|
-
// state, the materialized per-area journal, and the combined aggregate —
|
|
1140
|
-
// and every JournalStore session opened on top copied them all again. With
|
|
1141
|
-
// the runner's cached targeted-pull session, the watcher's session and a
|
|
1142
|
-
// pass-local session open at once, an outpost held five or six full copies,
|
|
1143
|
-
// 4.2 GB live against Node's 4.3 GB default ceiling, and recycled or hard
|
|
1144
|
-
// crashed every ~15 minutes.
|
|
1145
|
-
//
|
|
1146
|
-
// Area rows remain immutable and shared by their local projections. The
|
|
1147
|
-
// aggregate owns the one packed representation; its record facade
|
|
1148
|
-
// materializes frozen rows only at the caller's requested path.
|
|
1149
|
-
function seed(root, rows) {
|
|
1150
|
-
const ledger = open(root);
|
|
1151
|
-
const upserts = {};
|
|
1152
|
-
for (let index = 0; index < rows; index += 1)
|
|
1153
|
-
upserts[`alpha/file-${index}.md`] = entry(index + 1);
|
|
1154
|
-
ledger.append({ upserts });
|
|
1155
|
-
return ledger;
|
|
1156
|
-
}
|
|
1157
|
-
it("builds the shared aggregate store directly instead of repacking a record", () => {
|
|
1158
|
-
const root = makeRoot();
|
|
1159
|
-
const ledger = AreaLedger.open({
|
|
1160
|
-
rootDir: root,
|
|
1161
|
-
journalSlug: "personal-vault",
|
|
1162
|
-
layoutEpoch: 1,
|
|
1163
|
-
areaIds: ["root:alpha", "root:beta"],
|
|
1164
|
-
resolveArea: (key) => key.startsWith("alpha/") ? "root:alpha" : "root:beta",
|
|
1165
|
-
sharedJournalRowsCacheKey: `area-ledger-direct-packed-aggregate-${root}`,
|
|
1166
|
-
});
|
|
1167
|
-
ledger.append({ upserts: { "alpha/one.md": entry(1), "beta/two.md": entry(2) } });
|
|
1168
|
-
const repack = vi.spyOn(JournalRowStore.prototype, "replaceFromRecord");
|
|
1169
|
-
try {
|
|
1170
|
-
const aggregate = ledger.readCached().journal;
|
|
1171
|
-
expect(aggregate.files["alpha/one.md"]).toMatchObject({ size: 1 });
|
|
1172
|
-
expect(aggregate.files["beta/two.md"]).toMatchObject({ size: 2 });
|
|
1173
|
-
expect(repack).not.toHaveBeenCalled();
|
|
1174
|
-
}
|
|
1175
|
-
finally {
|
|
1176
|
-
repack.mockRestore();
|
|
1177
|
-
}
|
|
1178
|
-
});
|
|
1179
|
-
it("reattaches cached area journals when adopting another bridge's shared rows", () => {
|
|
1180
|
-
const root = makeRoot();
|
|
1181
|
-
const sharedJournalRowsCacheKey = `area-ledger-shared-rows-${root}`;
|
|
1182
|
-
const options = {
|
|
1183
|
-
rootDir: root,
|
|
1184
|
-
journalSlug: "personal-vault",
|
|
1185
|
-
layoutEpoch: 1,
|
|
1186
|
-
areaIds: ["root:alpha", "root:beta"],
|
|
1187
|
-
resolveArea: (key) => key.startsWith("alpha/") ? "root:alpha" : "root:beta",
|
|
1188
|
-
sharedJournalRowsCacheKey,
|
|
1189
|
-
};
|
|
1190
|
-
const idleTargetedBridge = AreaLedger.open(options);
|
|
1191
|
-
idleTargetedBridge.append({ upserts: { "alpha/changed.md": entry(1) } });
|
|
1192
|
-
idleTargetedBridge.readCached();
|
|
1193
|
-
// A released cached full-pass bridge drops its shared-store registration
|
|
1194
|
-
// while this targeted bridge remains open with its original facade.
|
|
1195
|
-
forgetSharedAreaJournalRows(sharedJournalRowsCacheKey);
|
|
1196
|
-
const fullPassBridge = AreaLedger.open(options);
|
|
1197
|
-
fullPassBridge.readCached();
|
|
1198
|
-
// The targeted bridge adopts the new shared rows. Its per-area facades
|
|
1199
|
-
// must move too, otherwise this direct append writes to its retired rows
|
|
1200
|
-
// and the identity-preserving refresh leaves the new aggregate stale.
|
|
1201
|
-
idleTargetedBridge.readCached();
|
|
1202
|
-
idleTargetedBridge.append({ upserts: { "alpha/changed.md": entry(2) } });
|
|
1203
|
-
expect(idleTargetedBridge.readCached().journal.files["alpha/changed.md"]).toMatchObject({ size: 2 });
|
|
1204
|
-
expect(fullPassBridge.readCached().journal.files["alpha/changed.md"]).toMatchObject({ size: 2 });
|
|
1205
|
-
});
|
|
1206
|
-
it("does not materialize inherited initial journal rows", () => {
|
|
1207
|
-
const files = Object.create({ "alpha/inherited.md": entry(99) });
|
|
1208
|
-
files["alpha/owned.md"] = entry(1);
|
|
1209
|
-
const ledger = open(makeRoot(), { version: "2", lastSync: "", files, pulls: [] });
|
|
1210
|
-
expect(ledger.read().files).toEqual({ "alpha/owned.md": entry(1) });
|
|
1211
|
-
});
|
|
1212
|
-
it("materializes aggregate rows from the packed store instead of retaining area rows", () => {
|
|
1213
|
-
const ledger = seed(makeRoot(), 50);
|
|
1214
|
-
const aggregate = ledger.readCached().journal;
|
|
1215
|
-
const raw = ledger.readRows(["alpha/file-7.md"])["alpha/file-7.md"];
|
|
1216
|
-
expect(raw).toBeDefined();
|
|
1217
|
-
expect(aggregate.files["alpha/file-7.md"]).toEqual(raw);
|
|
1218
|
-
expect(aggregate.files["alpha/file-7.md"]).not.toBe(raw);
|
|
1219
|
-
});
|
|
1220
|
-
it("primes the aggregate without cloning rows", () => {
|
|
1221
|
-
const ledger = seed(makeRoot(), 2_000);
|
|
1222
|
-
const clone = vi.spyOn(globalThis, "structuredClone");
|
|
1223
|
-
try {
|
|
1224
|
-
const { journal } = ledger.readCached();
|
|
1225
|
-
expect(Object.keys(journal.files)).toHaveLength(2_000);
|
|
1226
|
-
// Metadata (pulls) may still be copied; rows must not be.
|
|
1227
|
-
expect(clone.mock.calls.length).toBeLessThan(20);
|
|
1228
|
-
}
|
|
1229
|
-
finally {
|
|
1230
|
-
clone.mockRestore();
|
|
1231
|
-
}
|
|
1232
|
-
});
|
|
1233
|
-
it("updates packed aggregate rows on the incremental refresh path after another process appends", () => {
|
|
1234
|
-
const root = makeRoot();
|
|
1235
|
-
const ledger = seed(root, 20);
|
|
1236
|
-
ledger.readCached();
|
|
1237
|
-
open(root).append({ upserts: { "alpha/file-3.md": entry(300), "alpha/new.md": entry(301) } });
|
|
1238
|
-
const clone = vi.spyOn(globalThis, "structuredClone");
|
|
1239
|
-
let aggregate;
|
|
1240
|
-
try {
|
|
1241
|
-
aggregate = ledger.readCached().journal;
|
|
1242
|
-
expect(clone.mock.calls.length).toBeLessThan(20);
|
|
1243
|
-
}
|
|
1244
|
-
finally {
|
|
1245
|
-
clone.mockRestore();
|
|
1246
|
-
}
|
|
1247
|
-
expect(aggregate.files["alpha/file-3.md"]).toMatchObject({ size: 300 });
|
|
1248
|
-
expect(aggregate.files["alpha/new.md"]).toEqual(ledger.readRows(["alpha/new.md"])["alpha/new.md"]);
|
|
1249
|
-
});
|
|
1250
|
-
it("collapses finalized overlays before a later direct append refreshes the shared aggregate", () => {
|
|
1251
|
-
// A metadata-bearing write folds through a JournalRowOverlay. The next
|
|
1252
|
-
// direct write from another process must reach the warm packed aggregate,
|
|
1253
|
-
// not mutate that overlay behind an identity-preserving cache entry.
|
|
1254
|
-
const root = makeRoot();
|
|
1255
|
-
const reader = open(root);
|
|
1256
|
-
reader.readCached();
|
|
1257
|
-
const writer = open(root);
|
|
1258
|
-
writer.append({
|
|
1259
|
-
upserts: { "alpha/changed.md": entry(1) },
|
|
1260
|
-
metadata: { lastSync: "folded", pulls: [] },
|
|
1261
|
-
});
|
|
1262
|
-
expect(reader.readCached().journal.files["alpha/changed.md"]).toMatchObject({ size: 1 });
|
|
1263
|
-
writer.append({ upserts: { "alpha/changed.md": entry(2) } });
|
|
1264
|
-
expect(reader.readCached().journal.files["alpha/changed.md"]).toMatchObject({ size: 2 });
|
|
1265
|
-
});
|
|
1266
|
-
it("freezes every shared row so an in-place mutation fails loudly", () => {
|
|
1267
|
-
const ledger = seed(makeRoot(), 5);
|
|
1268
|
-
const row = ledger.readCached().journal.files["alpha/file-1.md"];
|
|
1269
|
-
expect(Object.isFrozen(row)).toBe(true);
|
|
1270
|
-
expect(() => { row.size = 999; }).toThrow(TypeError);
|
|
1271
|
-
expect(ledger.readRows(["alpha/file-1.md"])["alpha/file-1.md"]).toMatchObject({ size: 2 });
|
|
1272
|
-
});
|
|
1273
|
-
it("freezes nested row values too, so a delete intent cannot be rewritten in place", () => {
|
|
1274
|
-
const root = makeRoot();
|
|
1275
|
-
const ledger = seed(root, 2);
|
|
1276
|
-
const intent = { version: 1, remoteEtag: "etag-1", localHash: "a".repeat(64), localKind: "file" };
|
|
1277
|
-
ledger.append({ upserts: { "alpha/file-1.md": { ...entry(7), localDeleteIntent: intent } } });
|
|
1278
|
-
const row = ledger.readCached().journal.files["alpha/file-1.md"];
|
|
1279
|
-
expect(Object.isFrozen(row.localDeleteIntent)).toBe(true);
|
|
1280
|
-
expect(() => { row.localDeleteIntent.remoteEtag = "changed"; }).toThrow(TypeError);
|
|
1281
|
-
expect(ledger.readRows(["alpha/file-1.md"])["alpha/file-1.md"].localDeleteIntent).toEqual(intent);
|
|
1282
|
-
// A fresh handle after the store is reopened is the same guarantee, not a
|
|
1283
|
-
// one-off from the first materialization.
|
|
1284
|
-
const reopened = open(root).readCached().journal.files["alpha/file-1.md"];
|
|
1285
|
-
expect(Object.isFrozen(reopened.localDeleteIntent)).toBe(true);
|
|
1286
|
-
});
|
|
1287
|
-
it("keeps public overlay replacements and deletes detached from shared rows", () => {
|
|
1288
|
-
const ledger = seed(makeRoot(), 5);
|
|
1289
|
-
const snapshot = ledger.read();
|
|
1290
|
-
snapshot.files["alpha/file-1.md"] = { ...snapshot.files["alpha/file-1.md"], size: 999 };
|
|
1291
|
-
delete snapshot.files["alpha/file-2.md"];
|
|
1292
|
-
expect(snapshot.files["alpha/file-1.md"]).toMatchObject({ size: 999 });
|
|
1293
|
-
expect(snapshot.files["alpha/file-2.md"]).toBeUndefined();
|
|
1294
|
-
expect(ledger.readCached().journal.files["alpha/file-1.md"]).toMatchObject({ size: 2 });
|
|
1295
|
-
expect(ledger.readCached().journal.files["alpha/file-2.md"]).toMatchObject({ size: 3 });
|
|
1296
|
-
});
|
|
1297
|
-
});
|
|
1298
|
-
}
|
|
1299
|
-
if (!process.env.AREA_LEDGER_CHILD_ROOT) {
|
|
1300
|
-
/**
|
|
1301
|
-
* `append()` brings the warm aggregate current before its own delta, but the
|
|
1302
|
-
* durable append that follows takes the area's lock and refreshes INSIDE it.
|
|
1303
|
-
* A peer that committed in that window is folded into the area StateStore, yet
|
|
1304
|
-
* the warm packed aggregate only ever receives this process's own partitioned
|
|
1305
|
-
* delta. Recording the post-append identity on top of that made the peer's row
|
|
1306
|
-
* permanently invisible: `hasChangedOnDisk` reports no change, so no later
|
|
1307
|
-
* `readCached()` ever reconciles it.
|
|
1308
|
-
*/
|
|
1309
|
-
describe("AreaLedger — a peer write inside the append window", () => {
|
|
1310
|
-
function openStable(root) {
|
|
1311
|
-
return AreaLedger.open({
|
|
1312
|
-
rootDir: root,
|
|
1313
|
-
journalSlug: "personal-vault",
|
|
1314
|
-
layoutEpoch: 1,
|
|
1315
|
-
areaIds: ["root:alpha", "root:beta"],
|
|
1316
|
-
resolveArea: (key) => key.startsWith("alpha/") ? "root:alpha" : key.startsWith("beta/") ? "root:beta" : undefined,
|
|
1317
|
-
// Low enough that the peer's own append publishes a new generation.
|
|
1318
|
-
// That is the shape that actually loses the row: this process's durable
|
|
1319
|
-
// append then refreshes by RECOVERY, which hands its area state a fresh
|
|
1320
|
-
// row map detached from the warm packed aggregate, so the peer's record
|
|
1321
|
-
// never writes through into it.
|
|
1322
|
-
maxRecordsBeforeCompaction: 2,
|
|
1323
|
-
});
|
|
1324
|
-
}
|
|
1325
|
-
/**
|
|
1326
|
-
* Commit `peerDelta` from another ledger inside this process's own durable
|
|
1327
|
-
* append — after `append()` has brought its warm aggregate current, before
|
|
1328
|
-
* the area lock is taken. Both durable entry points are intercepted: a
|
|
1329
|
-
* single-area delta appends directly, a metadata-bearing one batches.
|
|
1330
|
-
*/
|
|
1331
|
-
function appendWithPeerWriteInFlight(ledger, peer, peerDelta, ownDelta) {
|
|
1332
|
-
const originalAppend = StateStore.prototype.append;
|
|
1333
|
-
const originalBatch = StateStore.appendBatch;
|
|
1334
|
-
let injected = false;
|
|
1335
|
-
const injectOnce = () => {
|
|
1336
|
-
if (injected)
|
|
1337
|
-
return;
|
|
1338
|
-
injected = true;
|
|
1339
|
-
peer.append(peerDelta);
|
|
1340
|
-
};
|
|
1341
|
-
const appendSpy = vi.spyOn(StateStore.prototype, "append");
|
|
1342
|
-
appendSpy.mockImplementation(function (type, payload, flags) {
|
|
1343
|
-
injectOnce();
|
|
1344
|
-
return originalAppend.call(this, type, payload, flags);
|
|
1345
|
-
});
|
|
1346
|
-
const batchSpy = vi.spyOn(StateStore, "appendBatch");
|
|
1347
|
-
batchSpy.mockImplementation(((entries) => {
|
|
1348
|
-
injectOnce();
|
|
1349
|
-
return originalBatch.call(StateStore, entries);
|
|
1350
|
-
}));
|
|
1351
|
-
try {
|
|
1352
|
-
ledger.append(ownDelta);
|
|
1353
|
-
}
|
|
1354
|
-
finally {
|
|
1355
|
-
appendSpy.mockRestore();
|
|
1356
|
-
batchSpy.mockRestore();
|
|
1357
|
-
}
|
|
1358
|
-
expect(injected).toBe(true);
|
|
1359
|
-
}
|
|
1360
|
-
it("keeps the peer's row in the same area visible to later reads", () => {
|
|
1361
|
-
const root = makeRoot();
|
|
1362
|
-
const ledger = openStable(root);
|
|
1363
|
-
const peer = openStable(root);
|
|
1364
|
-
ledger.append({ upserts: { "alpha/seed.md": entry(1) } });
|
|
1365
|
-
// Warm the aggregate cache: the shortcut being tested only runs with one.
|
|
1366
|
-
expect(ledger.read().files["alpha/seed.md"]).toMatchObject({ size: 1 });
|
|
1367
|
-
appendWithPeerWriteInFlight(ledger, peer, { upserts: { "alpha/from-peer.md": entry(2) } }, { upserts: { "alpha/mine.md": entry(3) } });
|
|
1368
|
-
const files = ledger.read().files;
|
|
1369
|
-
expect(files["alpha/mine.md"]).toMatchObject({ size: 3 });
|
|
1370
|
-
expect(files["alpha/from-peer.md"]).toMatchObject({ size: 2 });
|
|
1371
|
-
// Another read must not need a second chance to see it.
|
|
1372
|
-
expect(ledger.read().files["alpha/from-peer.md"]).toMatchObject({ size: 2 });
|
|
1373
|
-
// And the peer row is genuinely durable, not a cache artefact.
|
|
1374
|
-
expect(openStable(root).read().files["alpha/from-peer.md"]).toMatchObject({ size: 2 });
|
|
1375
|
-
});
|
|
1376
|
-
it("keeps a peer's delete of a row this process is not touching", () => {
|
|
1377
|
-
const root = makeRoot();
|
|
1378
|
-
const ledger = openStable(root);
|
|
1379
|
-
const peer = openStable(root);
|
|
1380
|
-
ledger.append({ upserts: { "alpha/seed.md": entry(1), "alpha/doomed.md": entry(4) } });
|
|
1381
|
-
expect(ledger.read().files["alpha/doomed.md"]).toMatchObject({ size: 4 });
|
|
1382
|
-
appendWithPeerWriteInFlight(ledger, peer, { deletes: ["alpha/doomed.md"] }, { upserts: { "alpha/mine.md": entry(3) } });
|
|
1383
|
-
const files = ledger.read().files;
|
|
1384
|
-
expect(files["alpha/mine.md"]).toMatchObject({ size: 3 });
|
|
1385
|
-
expect(files["alpha/doomed.md"]).toBeUndefined();
|
|
1386
|
-
});
|
|
1387
|
-
it("keeps a peer's row when this process commits a metadata-bearing transaction", () => {
|
|
1388
|
-
const root = makeRoot();
|
|
1389
|
-
const ledger = openStable(root);
|
|
1390
|
-
const peer = openStable(root);
|
|
1391
|
-
ledger.append({ upserts: { "alpha/seed.md": entry(1) } });
|
|
1392
|
-
expect(ledger.read().files["alpha/seed.md"]).toMatchObject({ size: 1 });
|
|
1393
|
-
appendWithPeerWriteInFlight(ledger, peer, { upserts: { "alpha/from-peer-tx.md": entry(5) } }, { upserts: { "alpha/mine.md": entry(3) }, metadata: { lastSync: "t1" } });
|
|
1394
|
-
const journal = ledger.read();
|
|
1395
|
-
expect(journal.lastSync).toBe("t1");
|
|
1396
|
-
expect(journal.files["alpha/mine.md"]).toMatchObject({ size: 3 });
|
|
1397
|
-
expect(journal.files["alpha/from-peer-tx.md"]).toMatchObject({ size: 5 });
|
|
1398
|
-
});
|
|
1399
|
-
});
|
|
1400
|
-
}
|
|
1401
|
-
//# sourceMappingURL=area-ledger.test.js.map
|