@aigne/afs-did-space 1.12.0-beta.5
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/LICENSE.md +26 -0
- package/README.md +129 -0
- package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs +11 -0
- package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.mjs +10 -0
- package/dist/_virtual/rolldown_runtime.cjs +29 -0
- package/dist/afs-metadata-context.cjs +20 -0
- package/dist/afs-metadata-context.d.cts +21 -0
- package/dist/afs-metadata-context.d.cts.map +1 -0
- package/dist/afs-metadata-context.d.mts +21 -0
- package/dist/afs-metadata-context.d.mts.map +1 -0
- package/dist/afs-metadata-context.mjs +18 -0
- package/dist/afs-metadata-context.mjs.map +1 -0
- package/dist/blocklet-hook.cjs +180 -0
- package/dist/blocklet-hook.d.cts +29 -0
- package/dist/blocklet-hook.d.cts.map +1 -0
- package/dist/blocklet-hook.d.mts +29 -0
- package/dist/blocklet-hook.d.mts.map +1 -0
- package/dist/blocklet-hook.mjs +178 -0
- package/dist/blocklet-hook.mjs.map +1 -0
- package/dist/changelog-schema.cjs +603 -0
- package/dist/changelog-schema.d.cts +395 -0
- package/dist/changelog-schema.d.cts.map +1 -0
- package/dist/changelog-schema.d.mts +395 -0
- package/dist/changelog-schema.d.mts.map +1 -0
- package/dist/changelog-schema.mjs +570 -0
- package/dist/changelog-schema.mjs.map +1 -0
- package/dist/changelog-write.cjs +80 -0
- package/dist/changelog-write.d.cts +70 -0
- package/dist/changelog-write.d.cts.map +1 -0
- package/dist/changelog-write.d.mts +70 -0
- package/dist/changelog-write.d.mts.map +1 -0
- package/dist/changelog-write.mjs +77 -0
- package/dist/changelog-write.mjs.map +1 -0
- package/dist/cid-byte-cache.cjs +126 -0
- package/dist/cid-byte-cache.d.cts +46 -0
- package/dist/cid-byte-cache.d.cts.map +1 -0
- package/dist/cid-byte-cache.d.mts +47 -0
- package/dist/cid-byte-cache.d.mts.map +1 -0
- package/dist/cid-byte-cache.mjs +125 -0
- package/dist/cid-byte-cache.mjs.map +1 -0
- package/dist/cid.cjs +68 -0
- package/dist/cid.d.cts +22 -0
- package/dist/cid.d.cts.map +1 -0
- package/dist/cid.d.mts +22 -0
- package/dist/cid.d.mts.map +1 -0
- package/dist/cid.mjs +65 -0
- package/dist/cid.mjs.map +1 -0
- package/dist/client.cjs +221 -0
- package/dist/client.d.cts +72 -0
- package/dist/client.d.cts.map +1 -0
- package/dist/client.d.mts +72 -0
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +220 -0
- package/dist/client.mjs.map +1 -0
- package/dist/cloudflare.cjs +510 -0
- package/dist/cloudflare.d.cts +307 -0
- package/dist/cloudflare.d.cts.map +1 -0
- package/dist/cloudflare.d.mts +308 -0
- package/dist/cloudflare.d.mts.map +1 -0
- package/dist/cloudflare.mjs +507 -0
- package/dist/cloudflare.mjs.map +1 -0
- package/dist/ctime-backfill.cjs +272 -0
- package/dist/ctime-backfill.d.cts +169 -0
- package/dist/ctime-backfill.d.cts.map +1 -0
- package/dist/ctime-backfill.d.mts +169 -0
- package/dist/ctime-backfill.d.mts.map +1 -0
- package/dist/ctime-backfill.mjs +267 -0
- package/dist/ctime-backfill.mjs.map +1 -0
- package/dist/d1-gc-queue.cjs +80 -0
- package/dist/d1-gc-queue.d.cts +59 -0
- package/dist/d1-gc-queue.d.cts.map +1 -0
- package/dist/d1-gc-queue.d.mts +59 -0
- package/dist/d1-gc-queue.d.mts.map +1 -0
- package/dist/d1-gc-queue.mjs +81 -0
- package/dist/d1-gc-queue.mjs.map +1 -0
- package/dist/d1-resolve-store.cjs +189 -0
- package/dist/d1-resolve-store.d.cts +93 -0
- package/dist/d1-resolve-store.d.cts.map +1 -0
- package/dist/d1-resolve-store.d.mts +93 -0
- package/dist/d1-resolve-store.d.mts.map +1 -0
- package/dist/d1-resolve-store.mjs +190 -0
- package/dist/d1-resolve-store.mjs.map +1 -0
- package/dist/d1-schema.cjs +361 -0
- package/dist/d1-schema.d.cts +237 -0
- package/dist/d1-schema.d.cts.map +1 -0
- package/dist/d1-schema.d.mts +237 -0
- package/dist/d1-schema.d.mts.map +1 -0
- package/dist/d1-schema.mjs +341 -0
- package/dist/d1-schema.mjs.map +1 -0
- package/dist/d1-share-store.cjs +0 -0
- package/dist/d1-share-store.d.cts +53 -0
- package/dist/d1-share-store.d.cts.map +1 -0
- package/dist/d1-share-store.d.mts +53 -0
- package/dist/d1-share-store.d.mts.map +1 -0
- package/dist/d1-share-store.mjs +0 -0
- package/dist/d1-share-store.mjs.map +1 -0
- package/dist/d1-tree-index.cjs +1098 -0
- package/dist/d1-tree-index.d.cts +203 -0
- package/dist/d1-tree-index.d.cts.map +1 -0
- package/dist/d1-tree-index.d.mts +203 -0
- package/dist/d1-tree-index.d.mts.map +1 -0
- package/dist/d1-tree-index.mjs +1094 -0
- package/dist/d1-tree-index.mjs.map +1 -0
- package/dist/data-backend.cjs +147 -0
- package/dist/data-backend.d.cts +30 -0
- package/dist/data-backend.d.cts.map +1 -0
- package/dist/data-backend.d.mts +30 -0
- package/dist/data-backend.d.mts.map +1 -0
- package/dist/data-backend.mjs +148 -0
- package/dist/data-backend.mjs.map +1 -0
- package/dist/dedup-backfill.cjs +278 -0
- package/dist/dedup-backfill.d.cts +165 -0
- package/dist/dedup-backfill.d.cts.map +1 -0
- package/dist/dedup-backfill.d.mts +165 -0
- package/dist/dedup-backfill.d.mts.map +1 -0
- package/dist/dedup-backfill.mjs +273 -0
- package/dist/dedup-backfill.mjs.map +1 -0
- package/dist/did-space-like.d.cts +2 -0
- package/dist/did-space-like.d.mts +2 -0
- package/dist/did-utils.cjs +44 -0
- package/dist/did-utils.d.cts +25 -0
- package/dist/did-utils.d.cts.map +1 -0
- package/dist/did-utils.d.mts +25 -0
- package/dist/did-utils.d.mts.map +1 -0
- package/dist/did-utils.mjs +43 -0
- package/dist/did-utils.mjs.map +1 -0
- package/dist/dirty-path-queue.cjs +31 -0
- package/dist/dirty-path-queue.d.cts +104 -0
- package/dist/dirty-path-queue.d.cts.map +1 -0
- package/dist/dirty-path-queue.d.mts +104 -0
- package/dist/dirty-path-queue.d.mts.map +1 -0
- package/dist/dirty-path-queue.mjs +31 -0
- package/dist/dirty-path-queue.mjs.map +1 -0
- package/dist/dirty-path-schema.cjs +142 -0
- package/dist/dirty-path-schema.d.cts +90 -0
- package/dist/dirty-path-schema.d.cts.map +1 -0
- package/dist/dirty-path-schema.d.mts +90 -0
- package/dist/dirty-path-schema.d.mts.map +1 -0
- package/dist/dirty-path-schema.mjs +136 -0
- package/dist/dirty-path-schema.mjs.map +1 -0
- package/dist/download-actions.cjs +43 -0
- package/dist/download-actions.mjs +40 -0
- package/dist/download-actions.mjs.map +1 -0
- package/dist/fs-object-store.cjs +153 -0
- package/dist/fs-object-store.d.cts +21 -0
- package/dist/fs-object-store.d.cts.map +1 -0
- package/dist/fs-object-store.d.mts +22 -0
- package/dist/fs-object-store.d.mts.map +1 -0
- package/dist/fs-object-store.mjs +153 -0
- package/dist/fs-object-store.mjs.map +1 -0
- package/dist/gc-queue.d.cts +43 -0
- package/dist/gc-queue.d.cts.map +1 -0
- package/dist/gc-queue.d.mts +43 -0
- package/dist/gc-queue.d.mts.map +1 -0
- package/dist/index.cjs +2712 -0
- package/dist/index.d.cts +504 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +505 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2537 -0
- package/dist/index.mjs.map +1 -0
- package/dist/inline-content-migration.cjs +212 -0
- package/dist/inline-content-migration.d.cts +110 -0
- package/dist/inline-content-migration.d.cts.map +1 -0
- package/dist/inline-content-migration.d.mts +111 -0
- package/dist/inline-content-migration.d.mts.map +1 -0
- package/dist/inline-content-migration.mjs +207 -0
- package/dist/inline-content-migration.mjs.map +1 -0
- package/dist/inline-content.cjs +145 -0
- package/dist/inline-content.d.cts +98 -0
- package/dist/inline-content.d.cts.map +1 -0
- package/dist/inline-content.d.mts +98 -0
- package/dist/inline-content.d.mts.map +1 -0
- package/dist/inline-content.mjs +137 -0
- package/dist/inline-content.mjs.map +1 -0
- package/dist/local-changelog.cjs +241 -0
- package/dist/local-changelog.d.cts +119 -0
- package/dist/local-changelog.d.cts.map +1 -0
- package/dist/local-changelog.d.mts +119 -0
- package/dist/local-changelog.d.mts.map +1 -0
- package/dist/local-changelog.mjs +240 -0
- package/dist/local-changelog.mjs.map +1 -0
- package/dist/local.cjs +435 -0
- package/dist/local.d.cts +254 -0
- package/dist/local.d.cts.map +1 -0
- package/dist/local.d.mts +254 -0
- package/dist/local.d.mts.map +1 -0
- package/dist/local.mjs +427 -0
- package/dist/local.mjs.map +1 -0
- package/dist/memory-gc-queue.cjs +36 -0
- package/dist/memory-gc-queue.d.cts +22 -0
- package/dist/memory-gc-queue.d.cts.map +1 -0
- package/dist/memory-gc-queue.d.mts +22 -0
- package/dist/memory-gc-queue.d.mts.map +1 -0
- package/dist/memory-gc-queue.mjs +36 -0
- package/dist/memory-gc-queue.mjs.map +1 -0
- package/dist/memory-tree-index.cjs +734 -0
- package/dist/memory-tree-index.d.cts +159 -0
- package/dist/memory-tree-index.d.cts.map +1 -0
- package/dist/memory-tree-index.d.mts +159 -0
- package/dist/memory-tree-index.d.mts.map +1 -0
- package/dist/memory-tree-index.mjs +735 -0
- package/dist/memory-tree-index.mjs.map +1 -0
- package/dist/metadata-db.cjs +562 -0
- package/dist/metadata-db.d.cts +102 -0
- package/dist/metadata-db.d.cts.map +1 -0
- package/dist/metadata-db.d.mts +102 -0
- package/dist/metadata-db.d.mts.map +1 -0
- package/dist/metadata-db.mjs +562 -0
- package/dist/metadata-db.mjs.map +1 -0
- package/dist/mime-utils.cjs +2 -0
- package/dist/mime-utils.d.cts +2 -0
- package/dist/mime-utils.d.mts +2 -0
- package/dist/mime-utils.mjs +3 -0
- package/dist/object-key.cjs +41 -0
- package/dist/object-key.d.cts +25 -0
- package/dist/object-key.d.cts.map +1 -0
- package/dist/object-key.d.mts +25 -0
- package/dist/object-key.d.mts.map +1 -0
- package/dist/object-key.mjs +40 -0
- package/dist/object-key.mjs.map +1 -0
- package/dist/packages/session/dist/index.cjs +788 -0
- package/dist/packages/session/dist/index.mjs +782 -0
- package/dist/packages/session/dist/index.mjs.map +1 -0
- package/dist/platform/r2/dist/types.d.cts +49 -0
- package/dist/platform/r2/dist/types.d.cts.map +1 -0
- package/dist/prefix-range.cjs +33 -0
- package/dist/prefix-range.d.cts +29 -0
- package/dist/prefix-range.d.cts.map +1 -0
- package/dist/prefix-range.d.mts +29 -0
- package/dist/prefix-range.d.mts.map +1 -0
- package/dist/prefix-range.mjs +33 -0
- package/dist/prefix-range.mjs.map +1 -0
- package/dist/prefixed-tree-index.cjs +238 -0
- package/dist/prefixed-tree-index.d.cts +85 -0
- package/dist/prefixed-tree-index.d.cts.map +1 -0
- package/dist/prefixed-tree-index.d.mts +85 -0
- package/dist/prefixed-tree-index.d.mts.map +1 -0
- package/dist/prefixed-tree-index.mjs +239 -0
- package/dist/prefixed-tree-index.mjs.map +1 -0
- package/dist/presign-signer.cjs +7 -0
- package/dist/presign-signer.d.cts +99 -0
- package/dist/presign-signer.d.cts.map +1 -0
- package/dist/presign-signer.d.mts +99 -0
- package/dist/presign-signer.d.mts.map +1 -0
- package/dist/presign-signer.mjs +7 -0
- package/dist/presign-signer.mjs.map +1 -0
- package/dist/providers/platform/r2/dist/index.d.mts +3 -0
- package/dist/providers/platform/r2/dist/types.d.mts +49 -0
- package/dist/providers/platform/r2/dist/types.d.mts.map +1 -0
- package/dist/reconcile.cjs +184 -0
- package/dist/reconcile.d.cts +26 -0
- package/dist/reconcile.d.cts.map +1 -0
- package/dist/reconcile.d.mts +26 -0
- package/dist/reconcile.d.mts.map +1 -0
- package/dist/reconcile.mjs +184 -0
- package/dist/reconcile.mjs.map +1 -0
- package/dist/reference-check.cjs +49 -0
- package/dist/reference-check.d.cts +10 -0
- package/dist/reference-check.d.cts.map +1 -0
- package/dist/reference-check.d.mts +10 -0
- package/dist/reference-check.d.mts.map +1 -0
- package/dist/reference-check.mjs +48 -0
- package/dist/reference-check.mjs.map +1 -0
- package/dist/remote-afs.cjs +681 -0
- package/dist/remote-afs.d.cts +236 -0
- package/dist/remote-afs.d.cts.map +1 -0
- package/dist/remote-afs.d.mts +236 -0
- package/dist/remote-afs.d.mts.map +1 -0
- package/dist/remote-afs.mjs +676 -0
- package/dist/remote-afs.mjs.map +1 -0
- package/dist/rename-guard.cjs +18 -0
- package/dist/rename-guard.mjs +18 -0
- package/dist/rename-guard.mjs.map +1 -0
- package/dist/resolve.cjs +260 -0
- package/dist/resolve.d.cts +113 -0
- package/dist/resolve.d.cts.map +1 -0
- package/dist/resolve.d.mts +113 -0
- package/dist/resolve.d.mts.map +1 -0
- package/dist/resolve.mjs +260 -0
- package/dist/resolve.mjs.map +1 -0
- package/dist/rsync-content.cjs +33 -0
- package/dist/rsync-content.mjs +33 -0
- package/dist/rsync-content.mjs.map +1 -0
- package/dist/rsync.cjs +400 -0
- package/dist/rsync.d.cts +157 -0
- package/dist/rsync.d.cts.map +1 -0
- package/dist/rsync.d.mts +157 -0
- package/dist/rsync.d.mts.map +1 -0
- package/dist/rsync.mjs +397 -0
- package/dist/rsync.mjs.map +1 -0
- package/dist/run-gc.cjs +57 -0
- package/dist/run-gc.d.cts +40 -0
- package/dist/run-gc.d.cts.map +1 -0
- package/dist/run-gc.d.mts +41 -0
- package/dist/run-gc.d.mts.map +1 -0
- package/dist/run-gc.mjs +57 -0
- package/dist/run-gc.mjs.map +1 -0
- package/dist/scope-id.cjs +70 -0
- package/dist/scope-id.d.cts +35 -0
- package/dist/scope-id.d.cts.map +1 -0
- package/dist/scope-id.d.mts +35 -0
- package/dist/scope-id.d.mts.map +1 -0
- package/dist/scope-id.mjs +68 -0
- package/dist/scope-id.mjs.map +1 -0
- package/dist/scope-migration-node.cjs +172 -0
- package/dist/scope-migration-node.d.cts +44 -0
- package/dist/scope-migration-node.d.cts.map +1 -0
- package/dist/scope-migration-node.d.mts +44 -0
- package/dist/scope-migration-node.d.mts.map +1 -0
- package/dist/scope-migration-node.mjs +171 -0
- package/dist/scope-migration-node.mjs.map +1 -0
- package/dist/scope-migration.cjs +155 -0
- package/dist/scope-migration.d.cts +65 -0
- package/dist/scope-migration.d.cts.map +1 -0
- package/dist/scope-migration.d.mts +65 -0
- package/dist/scope-migration.d.mts.map +1 -0
- package/dist/scope-migration.mjs +154 -0
- package/dist/scope-migration.mjs.map +1 -0
- package/dist/share-declaration.cjs +225 -0
- package/dist/share-declaration.d.cts +30 -0
- package/dist/share-declaration.d.cts.map +1 -0
- package/dist/share-declaration.d.mts +32 -0
- package/dist/share-declaration.d.mts.map +1 -0
- package/dist/share-declaration.mjs +221 -0
- package/dist/share-declaration.mjs.map +1 -0
- package/dist/share-hook.cjs +63 -0
- package/dist/share-hook.mjs +62 -0
- package/dist/share-hook.mjs.map +1 -0
- package/dist/share-resolve.cjs +176 -0
- package/dist/share-resolve.d.cts +36 -0
- package/dist/share-resolve.d.cts.map +1 -0
- package/dist/share-resolve.d.mts +36 -0
- package/dist/share-resolve.d.mts.map +1 -0
- package/dist/share-resolve.mjs +177 -0
- package/dist/share-resolve.mjs.map +1 -0
- package/dist/share-serve.cjs +145 -0
- package/dist/share-serve.d.cts +30 -0
- package/dist/share-serve.d.cts.map +1 -0
- package/dist/share-serve.d.mts +30 -0
- package/dist/share-serve.d.mts.map +1 -0
- package/dist/share-serve.mjs +144 -0
- package/dist/share-serve.mjs.map +1 -0
- package/dist/share-store.cjs +25 -0
- package/dist/share-store.d.cts +65 -0
- package/dist/share-store.d.cts.map +1 -0
- package/dist/share-store.d.mts +65 -0
- package/dist/share-store.d.mts.map +1 -0
- package/dist/share-store.mjs +25 -0
- package/dist/share-store.mjs.map +1 -0
- package/dist/share-virtual-path.cjs +102 -0
- package/dist/share-virtual-path.mjs +101 -0
- package/dist/share-virtual-path.mjs.map +1 -0
- package/dist/space-resolver.cjs +54 -0
- package/dist/space-resolver.d.cts +34 -0
- package/dist/space-resolver.d.cts.map +1 -0
- package/dist/space-resolver.d.mts +34 -0
- package/dist/space-resolver.d.mts.map +1 -0
- package/dist/space-resolver.mjs +55 -0
- package/dist/space-resolver.mjs.map +1 -0
- package/dist/sqlite-gc-queue.cjs +51 -0
- package/dist/sqlite-gc-queue.d.cts +22 -0
- package/dist/sqlite-gc-queue.d.cts.map +1 -0
- package/dist/sqlite-gc-queue.d.mts +22 -0
- package/dist/sqlite-gc-queue.d.mts.map +1 -0
- package/dist/sqlite-gc-queue.mjs +52 -0
- package/dist/sqlite-gc-queue.mjs.map +1 -0
- package/dist/sqlite-resolve-store.cjs +163 -0
- package/dist/sqlite-resolve-store.d.cts +50 -0
- package/dist/sqlite-resolve-store.d.cts.map +1 -0
- package/dist/sqlite-resolve-store.d.mts +50 -0
- package/dist/sqlite-resolve-store.d.mts.map +1 -0
- package/dist/sqlite-resolve-store.mjs +164 -0
- package/dist/sqlite-resolve-store.mjs.map +1 -0
- package/dist/sqlite-share-store.cjs +157 -0
- package/dist/sqlite-share-store.d.cts +31 -0
- package/dist/sqlite-share-store.d.cts.map +1 -0
- package/dist/sqlite-share-store.d.mts +31 -0
- package/dist/sqlite-share-store.d.mts.map +1 -0
- package/dist/sqlite-share-store.mjs +157 -0
- package/dist/sqlite-share-store.mjs.map +1 -0
- package/dist/sqlite-tree-index.cjs +901 -0
- package/dist/sqlite-tree-index.d.cts +107 -0
- package/dist/sqlite-tree-index.d.cts.map +1 -0
- package/dist/sqlite-tree-index.d.mts +107 -0
- package/dist/sqlite-tree-index.d.mts.map +1 -0
- package/dist/sqlite-tree-index.mjs +902 -0
- package/dist/sqlite-tree-index.mjs.map +1 -0
- package/dist/sync-engine.cjs +1324 -0
- package/dist/sync-engine.d.cts +473 -0
- package/dist/sync-engine.d.cts.map +1 -0
- package/dist/sync-engine.d.mts +473 -0
- package/dist/sync-engine.d.mts.map +1 -0
- package/dist/sync-engine.mjs +1315 -0
- package/dist/sync-engine.mjs.map +1 -0
- package/dist/sync-state.cjs +303 -0
- package/dist/sync-state.d.cts +224 -0
- package/dist/sync-state.d.cts.map +1 -0
- package/dist/sync-state.d.mts +224 -0
- package/dist/sync-state.d.mts.map +1 -0
- package/dist/sync-state.mjs +297 -0
- package/dist/sync-state.mjs.map +1 -0
- package/dist/timestamp.cjs +92 -0
- package/dist/timestamp.mjs +91 -0
- package/dist/timestamp.mjs.map +1 -0
- package/dist/transports/http.cjs +54 -0
- package/dist/transports/http.d.cts +26 -0
- package/dist/transports/http.d.cts.map +1 -0
- package/dist/transports/http.d.mts +26 -0
- package/dist/transports/http.d.mts.map +1 -0
- package/dist/transports/http.mjs +54 -0
- package/dist/transports/http.mjs.map +1 -0
- package/dist/transports/static.cjs +55 -0
- package/dist/transports/static.d.cts +28 -0
- package/dist/transports/static.d.cts.map +1 -0
- package/dist/transports/static.d.mts +28 -0
- package/dist/transports/static.d.mts.map +1 -0
- package/dist/transports/static.mjs +55 -0
- package/dist/transports/static.mjs.map +1 -0
- package/dist/transports/types.cjs +13 -0
- package/dist/transports/types.d.cts +72 -0
- package/dist/transports/types.d.cts.map +1 -0
- package/dist/transports/types.d.mts +72 -0
- package/dist/transports/types.d.mts.map +1 -0
- package/dist/transports/types.mjs +13 -0
- package/dist/transports/types.mjs.map +1 -0
- package/dist/transports/ws.cjs +207 -0
- package/dist/transports/ws.d.cts +47 -0
- package/dist/transports/ws.d.cts.map +1 -0
- package/dist/transports/ws.d.mts +47 -0
- package/dist/transports/ws.d.mts.map +1 -0
- package/dist/transports/ws.mjs +206 -0
- package/dist/transports/ws.mjs.map +1 -0
- package/dist/tree-index.cjs +333 -0
- package/dist/tree-index.d.cts +524 -0
- package/dist/tree-index.d.cts.map +1 -0
- package/dist/tree-index.d.mts +524 -0
- package/dist/tree-index.d.mts.map +1 -0
- package/dist/tree-index.mjs +322 -0
- package/dist/tree-index.mjs.map +1 -0
- package/dist/tree-query.cjs +655 -0
- package/dist/tree-query.d.cts +70 -0
- package/dist/tree-query.d.cts.map +1 -0
- package/dist/tree-query.d.mts +70 -0
- package/dist/tree-query.d.mts.map +1 -0
- package/dist/tree-query.mjs +648 -0
- package/dist/tree-query.mjs.map +1 -0
- package/dist/upload-actions.cjs +97 -0
- package/dist/upload-actions.d.cts +19 -0
- package/dist/upload-actions.d.cts.map +1 -0
- package/dist/upload-actions.d.mts +21 -0
- package/dist/upload-actions.d.mts.map +1 -0
- package/dist/upload-actions.mjs +90 -0
- package/dist/upload-actions.mjs.map +1 -0
- package/dist/upload-session-store.cjs +185 -0
- package/dist/upload-session-store.d.cts +99 -0
- package/dist/upload-session-store.d.cts.map +1 -0
- package/dist/upload-session-store.d.mts +99 -0
- package/dist/upload-session-store.d.mts.map +1 -0
- package/dist/upload-session-store.mjs +184 -0
- package/dist/upload-session-store.mjs.map +1 -0
- package/dist/url-normalize.cjs +61 -0
- package/dist/url-normalize.d.cts +33 -0
- package/dist/url-normalize.d.cts.map +1 -0
- package/dist/url-normalize.d.mts +33 -0
- package/dist/url-normalize.d.mts.map +1 -0
- package/dist/url-normalize.mjs +61 -0
- package/dist/url-normalize.mjs.map +1 -0
- package/dist/versioned-content-backends.cjs +155 -0
- package/dist/versioned-content-backends.d.cts +49 -0
- package/dist/versioned-content-backends.d.cts.map +1 -0
- package/dist/versioned-content-backends.d.mts +49 -0
- package/dist/versioned-content-backends.d.mts.map +1 -0
- package/dist/versioned-content-backends.mjs +154 -0
- package/dist/versioned-content-backends.mjs.map +1 -0
- package/dist/versioned-content-index.cjs +102 -0
- package/dist/versioned-content-index.d.cts +46 -0
- package/dist/versioned-content-index.d.cts.map +1 -0
- package/dist/versioned-content-index.d.mts +46 -0
- package/dist/versioned-content-index.d.mts.map +1 -0
- package/dist/versioned-content-index.mjs +103 -0
- package/dist/versioned-content-index.mjs.map +1 -0
- package/dist/versioned-content-store.cjs +121 -0
- package/dist/versioned-content-store.d.cts +90 -0
- package/dist/versioned-content-store.d.cts.map +1 -0
- package/dist/versioned-content-store.d.mts +90 -0
- package/dist/versioned-content-store.d.mts.map +1 -0
- package/dist/versioned-content-store.mjs +122 -0
- package/dist/versioned-content-store.mjs.map +1 -0
- package/dist/versioned-scope.cjs +39 -0
- package/dist/versioned-scope.d.cts +57 -0
- package/dist/versioned-scope.d.cts.map +1 -0
- package/dist/versioned-scope.d.mts +57 -0
- package/dist/versioned-scope.d.mts.map +1 -0
- package/dist/versioned-scope.mjs +37 -0
- package/dist/versioned-scope.mjs.map +1 -0
- package/migrations/0001_tree_entries.sql +17 -0
- package/migrations/0002_resolve_entries.sql +7 -0
- package/migrations/0003_entries_v2.sql +38 -0
- package/migrations/0004_gc_queue.sql +5 -0
- package/migrations/0006_resolve_enhance.sql +14 -0
- package/migrations/0007_resolve_created_at.sql +10 -0
- package/migrations/0008_changelog.sql +34 -0
- package/migrations/0009_device_sync_state.sql +29 -0
- package/migrations/0010_scope_meta.sql +33 -0
- package/migrations/0011_shares.sql +25 -0
- package/migrations/0012_scope_meta_file_count.sql +41 -0
- package/migrations/0013_scope_meta_total_bytes.sql +47 -0
- package/migrations/0014_rename_tables.sql +62 -0
- package/package.json +102 -0
|
@@ -0,0 +1,901 @@
|
|
|
1
|
+
const require_changelog_schema = require('./changelog-schema.cjs');
|
|
2
|
+
const require_inline_content = require('./inline-content.cjs');
|
|
3
|
+
const require_timestamp = require('./timestamp.cjs');
|
|
4
|
+
const require_tree_index = require('./tree-index.cjs');
|
|
5
|
+
const require_tree_query = require('./tree-query.cjs');
|
|
6
|
+
const require_changelog_write = require('./changelog-write.cjs');
|
|
7
|
+
const require_prefix_range = require('./prefix-range.cjs');
|
|
8
|
+
const require_dirty_path_schema = require('./dirty-path-schema.cjs');
|
|
9
|
+
const require_d1_tree_index = require('./d1-tree-index.cjs');
|
|
10
|
+
|
|
11
|
+
//#region src/sqlite-tree-index.ts
|
|
12
|
+
/**
|
|
13
|
+
* `isReferencedMany` IN-shard size for libsql/SQLite (design §7.2). SQLite's
|
|
14
|
+
* default bound-param cap is ~999; the three-way UNION binds each cid 3×, so
|
|
15
|
+
* 300 cids ⇒ ≤ ~906 params — comfortably under the cap on both branches.
|
|
16
|
+
*/
|
|
17
|
+
const SQLITE_MANY_SHARD_SIZE = 300;
|
|
18
|
+
const VALID_ORDER_BY = {
|
|
19
|
+
path: "path",
|
|
20
|
+
mtime: "mtime",
|
|
21
|
+
size: "size",
|
|
22
|
+
ctime: "ctime",
|
|
23
|
+
mimeType: "mime_type",
|
|
24
|
+
name: "name"
|
|
25
|
+
};
|
|
26
|
+
/** The only nullable sortable column — NULLs must sort last (see tree-index.ts). */
|
|
27
|
+
const NULLABLE_ORDER_COLUMNS = new Set(["mime_type"]);
|
|
28
|
+
/** libsql returns INTEGER columns as number|bigint; coerce to a JS number. */
|
|
29
|
+
function num(v) {
|
|
30
|
+
return typeof v === "bigint" ? Number(v) : v ?? 0;
|
|
31
|
+
}
|
|
32
|
+
/** Raw sort-column value of a row for the keyset cursor (NULL stays null). */
|
|
33
|
+
function sortValueOf(row, col) {
|
|
34
|
+
const v = row[col];
|
|
35
|
+
if (v == null) return null;
|
|
36
|
+
if (typeof v === "bigint") return Number(v);
|
|
37
|
+
return v;
|
|
38
|
+
}
|
|
39
|
+
function mapChildRow(r) {
|
|
40
|
+
const e = {
|
|
41
|
+
path: r.path,
|
|
42
|
+
cid: r.cid ?? "",
|
|
43
|
+
size: num(r.size),
|
|
44
|
+
mtime: num(r.mtime),
|
|
45
|
+
ctime: num(r.ctime),
|
|
46
|
+
mimeType: r.mime_type ?? void 0
|
|
47
|
+
};
|
|
48
|
+
if (r.content != null) e.content = r.content;
|
|
49
|
+
return e;
|
|
50
|
+
}
|
|
51
|
+
var SQLiteTreeIndex = class {
|
|
52
|
+
client;
|
|
53
|
+
maxEntriesPerScope;
|
|
54
|
+
/** upload-limits Phase 5 byte quota (0 = disabled, the opt-in default). */
|
|
55
|
+
maxBytesPerScope;
|
|
56
|
+
inline;
|
|
57
|
+
constructor(db, scope, opts) {
|
|
58
|
+
this.scope = scope;
|
|
59
|
+
this.client = db.rawClient;
|
|
60
|
+
this.maxEntriesPerScope = opts?.maxEntriesPerScope ?? require_d1_tree_index.MAX_ENTRIES_PER_SCOPE;
|
|
61
|
+
this.maxBytesPerScope = typeof opts?.maxBytesPerScope === "number" && opts.maxBytesPerScope > 0 ? opts.maxBytesPerScope : 0;
|
|
62
|
+
this.inline = require_inline_content.resolveInlineConfig(opts);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Current Σ size of this scope's file rows (upload-limits Phase 5 byte quota).
|
|
66
|
+
* SQLite (local Node) has no D1 rows_read billing, so a direct `SUM(size)` is
|
|
67
|
+
* fine here — same pattern as the file-count quota's `count("")` scan (the
|
|
68
|
+
* trigger-maintained `scope_meta.total_bytes` is a D1-only optimization).
|
|
69
|
+
*/
|
|
70
|
+
async scopeTotalBytes() {
|
|
71
|
+
const r = await this.client.execute({
|
|
72
|
+
sql: "SELECT COALESCE(SUM(size), 0) as total FROM ds_entries WHERE scope = ? AND kind = 'file'",
|
|
73
|
+
args: [this.scope]
|
|
74
|
+
});
|
|
75
|
+
return Number(r.rows[0]?.total ?? 0);
|
|
76
|
+
}
|
|
77
|
+
async get(path, opts) {
|
|
78
|
+
const contentCol = (opts?.includeContent ?? true) && this.inline.inlineCache === "on" ? ", content" : "";
|
|
79
|
+
const row = (await this.client.execute({
|
|
80
|
+
sql: `SELECT cid, size, mtime, ctime, mime_type, metadata${contentCol} FROM ds_entries WHERE scope = ? AND path = ?`,
|
|
81
|
+
args: [this.scope, path]
|
|
82
|
+
})).rows[0];
|
|
83
|
+
if (!row || row.cid == null) return null;
|
|
84
|
+
const entry = {
|
|
85
|
+
cid: row.cid,
|
|
86
|
+
size: num(row.size),
|
|
87
|
+
mtime: num(row.mtime),
|
|
88
|
+
ctime: num(row.ctime),
|
|
89
|
+
mimeType: row.mime_type ?? void 0
|
|
90
|
+
};
|
|
91
|
+
if (row.content != null) entry.content = row.content;
|
|
92
|
+
const meta = require_tree_index.parseTreeEntryMetadata(row.metadata);
|
|
93
|
+
if (meta) entry.metadata = meta;
|
|
94
|
+
return entry;
|
|
95
|
+
}
|
|
96
|
+
async getDirTimes(dirPath) {
|
|
97
|
+
const row = (await this.client.execute({
|
|
98
|
+
sql: "SELECT ctime, mtime FROM ds_entries WHERE scope = ? AND path = ?",
|
|
99
|
+
args: [this.scope, dirPath]
|
|
100
|
+
})).rows[0];
|
|
101
|
+
return row ? {
|
|
102
|
+
ctime: num(row.ctime),
|
|
103
|
+
mtime: num(row.mtime)
|
|
104
|
+
} : null;
|
|
105
|
+
}
|
|
106
|
+
async put(path, entry, opts) {
|
|
107
|
+
require_changelog_write.validateDeviceId(opts.deviceId);
|
|
108
|
+
const existing = await this.get(path);
|
|
109
|
+
if (existing && existing.cid === entry.cid && existing.mimeType === entry.mimeType && require_tree_index.treeEntryMetadataEqual(existing.metadata, entry.metadata)) {
|
|
110
|
+
if (this.inline.inlineCache !== "on") return { oldCid: existing.cid };
|
|
111
|
+
const wouldBeInline = await require_inline_content.resolveInlineContent(entry, this.inline);
|
|
112
|
+
if ((existing.content ?? null) === wouldBeInline) return { oldCid: existing.cid };
|
|
113
|
+
}
|
|
114
|
+
if (!existing) {
|
|
115
|
+
if (await this.count("") >= this.maxEntriesPerScope) throw require_tree_index.storageQuotaError(`Storage quota exceeded: scope "${this.scope}" has reached the ${this.maxEntriesPerScope} file limit`);
|
|
116
|
+
}
|
|
117
|
+
if (this.maxBytesPerScope > 0) {
|
|
118
|
+
const newBytes = entry.size - (existing?.size ?? 0);
|
|
119
|
+
if (newBytes > 0) {
|
|
120
|
+
if (await this.scopeTotalBytes() + newBytes > this.maxBytesPerScope) throw require_tree_index.storageQuotaError(`Storage quota exceeded: scope "${this.scope}" has reached the ${this.maxBytesPerScope}-byte limit`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const now = Date.now();
|
|
124
|
+
const stmts = [];
|
|
125
|
+
const dirStamp = require_timestamp.resolveParentDirStamp(entry.metadata);
|
|
126
|
+
const directParent = require_d1_tree_index.parentOf(path);
|
|
127
|
+
for (const dirPath of require_d1_tree_index.ancestorDirs(path)) stmts.push(require_d1_tree_index.buildDirChainStmt(this.scope, dirPath, dirStamp && dirPath === directParent ? dirStamp : null, now));
|
|
128
|
+
if (!opts.skipChangelog) stmts.push({
|
|
129
|
+
sql: CHANGELOG_INSERT_SQL_WITH_SUBQUERY,
|
|
130
|
+
args: [
|
|
131
|
+
this.scope,
|
|
132
|
+
path,
|
|
133
|
+
entry.cid,
|
|
134
|
+
this.scope,
|
|
135
|
+
path,
|
|
136
|
+
entry.size,
|
|
137
|
+
entry.mtime,
|
|
138
|
+
opts.deviceId
|
|
139
|
+
]
|
|
140
|
+
});
|
|
141
|
+
stmts.push(await this.buildFileUpsert(path, entry));
|
|
142
|
+
if (!opts.skipChangelog) {
|
|
143
|
+
const wmPrefix = require_changelog_schema.watermarkWritePrefix(path);
|
|
144
|
+
if (wmPrefix !== null) stmts.push({
|
|
145
|
+
sql: require_changelog_schema.PREFIX_WATERMARK_BUMP_SQL,
|
|
146
|
+
args: [this.scope, wmPrefix]
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
await this.client.batch(stmts, "write");
|
|
150
|
+
return { oldCid: existing?.cid };
|
|
151
|
+
}
|
|
152
|
+
/** Inline content this entry would store — drives loopBatchPutEntries' content-aware skip. */
|
|
153
|
+
inlineForEntry(entry) {
|
|
154
|
+
return require_inline_content.resolveInlineContent(entry, this.inline);
|
|
155
|
+
}
|
|
156
|
+
/** Point seek on the `(scope, dedup_scope, dedup_key)` partial UNIQUE index. */
|
|
157
|
+
async findByDedupKey(dedupScope, dedupKey) {
|
|
158
|
+
const row = (await this.client.execute({
|
|
159
|
+
sql: `SELECT path, cid, size, mtime, ctime, mime_type, metadata
|
|
160
|
+
FROM ds_entries WHERE scope = ? AND dedup_scope = ? AND dedup_key = ? LIMIT 1`,
|
|
161
|
+
args: [
|
|
162
|
+
this.scope,
|
|
163
|
+
dedupScope,
|
|
164
|
+
dedupKey
|
|
165
|
+
]
|
|
166
|
+
})).rows[0];
|
|
167
|
+
if (!row || row.cid == null) return null;
|
|
168
|
+
const entry = {
|
|
169
|
+
path: row.path,
|
|
170
|
+
cid: row.cid,
|
|
171
|
+
size: num(row.size),
|
|
172
|
+
mtime: num(row.mtime),
|
|
173
|
+
ctime: num(row.ctime),
|
|
174
|
+
mimeType: row.mime_type ?? void 0
|
|
175
|
+
};
|
|
176
|
+
const meta = require_tree_index.parseTreeEntryMetadata(row.metadata);
|
|
177
|
+
if (meta) entry.metadata = meta;
|
|
178
|
+
return entry;
|
|
179
|
+
}
|
|
180
|
+
/** Index-only backfill: set the dedup columns without touching content/changelog. */
|
|
181
|
+
async setDedupKey(path, dedupScope, dedupKey, opts) {
|
|
182
|
+
require_changelog_write.validateDeviceId(opts.deviceId);
|
|
183
|
+
await this.client.execute({
|
|
184
|
+
sql: "UPDATE ds_entries SET dedup_scope = ?, dedup_key = ? WHERE scope = ? AND path = ?",
|
|
185
|
+
args: [
|
|
186
|
+
dedupScope,
|
|
187
|
+
dedupKey,
|
|
188
|
+
this.scope,
|
|
189
|
+
path
|
|
190
|
+
]
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
async getPrefixWatermark(prefix) {
|
|
194
|
+
const wmPrefix = require_changelog_schema.watermarkPrefix(prefix);
|
|
195
|
+
if (wmPrefix === null) return null;
|
|
196
|
+
return num((await this.client.execute({
|
|
197
|
+
sql: require_changelog_schema.PREFIX_WATERMARK_READ_SQL,
|
|
198
|
+
args: [this.scope, wmPrefix]
|
|
199
|
+
})).rows[0]?.version);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Build the file-row UPSERT. Inline-enabled indexes always write the
|
|
203
|
+
* content column (inline copy or NULL — an overwrite without inline content
|
|
204
|
+
* MUST clear any prior copy so the column never goes stale relative to the
|
|
205
|
+
* new cid); default-off indexes keep the byte-identical legacy statement
|
|
206
|
+
* (and never touch a not-yet-migrated database's missing column).
|
|
207
|
+
*/
|
|
208
|
+
async buildFileUpsert(path, entry) {
|
|
209
|
+
const base = [
|
|
210
|
+
this.scope,
|
|
211
|
+
path,
|
|
212
|
+
require_d1_tree_index.parentOf(path),
|
|
213
|
+
require_d1_tree_index.nameOf(path),
|
|
214
|
+
entry.cid,
|
|
215
|
+
entry.size,
|
|
216
|
+
entry.mimeType ?? null,
|
|
217
|
+
entry.ctime,
|
|
218
|
+
entry.mtime
|
|
219
|
+
];
|
|
220
|
+
const metadataValue = require_tree_index.serializeTreeEntryMetadata(entry.metadata);
|
|
221
|
+
const dedupScopeValue = entry.dedupScope ?? null;
|
|
222
|
+
const dedupKeyValue = entry.dedupKey ?? null;
|
|
223
|
+
if (this.inline.inlineCache !== "on") return {
|
|
224
|
+
sql: `INSERT INTO ds_entries (scope, path, parent, name, kind, cid, size, mime_type, ctime, mtime, metadata, dedup_scope, dedup_key)
|
|
225
|
+
VALUES (?, ?, ?, ?, 'file', ?, ?, ?, ?, ?, ?, ?, ?)
|
|
226
|
+
ON CONFLICT(scope, path) DO UPDATE SET
|
|
227
|
+
cid = excluded.cid,
|
|
228
|
+
size = excluded.size,
|
|
229
|
+
mtime = excluded.mtime,
|
|
230
|
+
mime_type = excluded.mime_type,
|
|
231
|
+
metadata = excluded.metadata,
|
|
232
|
+
dedup_scope = COALESCE(excluded.dedup_scope, ds_entries.dedup_scope),
|
|
233
|
+
dedup_key = COALESCE(excluded.dedup_key, ds_entries.dedup_key)`,
|
|
234
|
+
args: [
|
|
235
|
+
...base,
|
|
236
|
+
metadataValue,
|
|
237
|
+
dedupScopeValue,
|
|
238
|
+
dedupKeyValue
|
|
239
|
+
]
|
|
240
|
+
};
|
|
241
|
+
const inlineContent = await require_inline_content.resolveInlineContent(entry, this.inline);
|
|
242
|
+
return {
|
|
243
|
+
sql: `INSERT INTO ds_entries (scope, path, parent, name, kind, cid, size, mime_type, ctime, mtime, content, metadata, dedup_scope, dedup_key)
|
|
244
|
+
VALUES (?, ?, ?, ?, 'file', ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
245
|
+
ON CONFLICT(scope, path) DO UPDATE SET
|
|
246
|
+
cid = excluded.cid,
|
|
247
|
+
size = excluded.size,
|
|
248
|
+
mtime = excluded.mtime,
|
|
249
|
+
mime_type = excluded.mime_type,
|
|
250
|
+
content = excluded.content,
|
|
251
|
+
metadata = excluded.metadata,
|
|
252
|
+
dedup_scope = COALESCE(excluded.dedup_scope, ds_entries.dedup_scope),
|
|
253
|
+
dedup_key = COALESCE(excluded.dedup_key, ds_entries.dedup_key)`,
|
|
254
|
+
args: [
|
|
255
|
+
...base,
|
|
256
|
+
inlineContent,
|
|
257
|
+
metadataValue,
|
|
258
|
+
dedupScopeValue,
|
|
259
|
+
dedupKeyValue
|
|
260
|
+
]
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
async delete(path, opts) {
|
|
264
|
+
require_changelog_write.validateDeviceId(opts.deviceId);
|
|
265
|
+
const stmts = [];
|
|
266
|
+
if (!opts.skipChangelog) stmts.push({
|
|
267
|
+
sql: `INSERT INTO ds_changelog (scope, path, op, cid, old_cid, size, mtime, device_id)
|
|
268
|
+
SELECT ?, ?, 'delete', NULL, cid, NULL, ?, ?
|
|
269
|
+
FROM ds_entries WHERE scope = ? AND path = ? AND cid IS NOT NULL`,
|
|
270
|
+
args: [
|
|
271
|
+
this.scope,
|
|
272
|
+
path,
|
|
273
|
+
opts.mtime ?? Date.now(),
|
|
274
|
+
opts.deviceId,
|
|
275
|
+
this.scope,
|
|
276
|
+
path
|
|
277
|
+
]
|
|
278
|
+
});
|
|
279
|
+
stmts.push({
|
|
280
|
+
sql: "DELETE FROM ds_entries WHERE scope = ? AND path = ?",
|
|
281
|
+
args: [this.scope, path]
|
|
282
|
+
});
|
|
283
|
+
if (!opts.skipChangelog) {
|
|
284
|
+
const wmPrefix = require_changelog_schema.watermarkWritePrefix(path);
|
|
285
|
+
if (wmPrefix !== null) stmts.push({
|
|
286
|
+
sql: require_changelog_schema.PREFIX_WATERMARK_BUMP_SQL,
|
|
287
|
+
args: [this.scope, wmPrefix]
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
await this.client.batch(stmts, "write");
|
|
291
|
+
await this.cleanEmptyParents(path);
|
|
292
|
+
}
|
|
293
|
+
async cleanEmptyParents(path) {
|
|
294
|
+
for (const dirPath of require_d1_tree_index.ancestorDirs(path)) {
|
|
295
|
+
if ((await this.client.execute({
|
|
296
|
+
sql: "SELECT 1 FROM ds_entries WHERE scope = ? AND parent = ? LIMIT 1",
|
|
297
|
+
args: [this.scope, dirPath]
|
|
298
|
+
})).rows.length > 0) break;
|
|
299
|
+
await this.client.execute({
|
|
300
|
+
sql: "DELETE FROM ds_entries WHERE scope = ? AND path = ?",
|
|
301
|
+
args: [this.scope, dirPath]
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
async list(prefix, options) {
|
|
306
|
+
const limit = options?.limit ?? 1e3;
|
|
307
|
+
const col = VALID_ORDER_BY[options?.orderBy ?? "path"];
|
|
308
|
+
if (!col) throw new Error(`Invalid orderBy: ${options?.orderBy}`);
|
|
309
|
+
const order = options?.order ?? "asc";
|
|
310
|
+
if (limit === 0) return {
|
|
311
|
+
entries: [],
|
|
312
|
+
hasMore: false
|
|
313
|
+
};
|
|
314
|
+
const [lo, hi] = require_prefix_range.prefixRange(prefix);
|
|
315
|
+
const args = [
|
|
316
|
+
this.scope,
|
|
317
|
+
lo,
|
|
318
|
+
hi
|
|
319
|
+
];
|
|
320
|
+
let sql = `SELECT path, ${col} as _sort FROM ds_entries WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file'`;
|
|
321
|
+
if (options?.cursor) {
|
|
322
|
+
sql += ` AND ${col} ${order === "asc" ? ">" : "<"} ?`;
|
|
323
|
+
args.push(options.cursor);
|
|
324
|
+
}
|
|
325
|
+
sql += ` ORDER BY ${col} ${order} LIMIT ?`;
|
|
326
|
+
args.push(limit + 1);
|
|
327
|
+
const result = await this.client.execute({
|
|
328
|
+
sql,
|
|
329
|
+
args
|
|
330
|
+
});
|
|
331
|
+
const hasMore = result.rows.length > limit;
|
|
332
|
+
const rows = hasMore ? result.rows.slice(0, limit) : result.rows;
|
|
333
|
+
return {
|
|
334
|
+
entries: rows.map((r) => ({ path: r.path })),
|
|
335
|
+
hasMore,
|
|
336
|
+
cursor: hasMore && rows.length > 0 ? String(rows[rows.length - 1]._sort) : void 0
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
async listEntries(prefix, options) {
|
|
340
|
+
const limit = options?.limit ?? 1e3;
|
|
341
|
+
const hasOrderBy = options?.orderBy !== void 0;
|
|
342
|
+
const col = VALID_ORDER_BY[options?.orderBy ?? "path"];
|
|
343
|
+
if (!col) throw new Error(`Invalid orderBy: ${options?.orderBy}`);
|
|
344
|
+
const order = options?.order === "desc" ? "desc" : "asc";
|
|
345
|
+
if (limit === 0) return {
|
|
346
|
+
entries: [],
|
|
347
|
+
hasMore: false
|
|
348
|
+
};
|
|
349
|
+
const parsed = require_tree_index.parseTreeCursor(options?.cursor, hasOrderBy);
|
|
350
|
+
const [lo, hi] = require_prefix_range.prefixRange(prefix);
|
|
351
|
+
const args = [
|
|
352
|
+
this.scope,
|
|
353
|
+
lo,
|
|
354
|
+
hi
|
|
355
|
+
];
|
|
356
|
+
let sql = `SELECT path, cid, size, mtime, ctime, mime_type${options?.includeContent ? ", content" : ""} FROM ds_entries${col === "path" ? " INDEXED BY idx_entries_kind" : ""} WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file'`;
|
|
357
|
+
if (hasOrderBy) {
|
|
358
|
+
const parts = require_tree_index.buildOrderedQueryParts({
|
|
359
|
+
col,
|
|
360
|
+
nullable: NULLABLE_ORDER_COLUMNS.has(col),
|
|
361
|
+
order,
|
|
362
|
+
tieCol: "path",
|
|
363
|
+
cursor: parsed.kind === "v2" ? parsed.cursor : void 0
|
|
364
|
+
});
|
|
365
|
+
if (parts.cursorWhereSql) {
|
|
366
|
+
sql += ` AND ${parts.cursorWhereSql}`;
|
|
367
|
+
args.push(...parts.cursorArgs);
|
|
368
|
+
}
|
|
369
|
+
sql += ` ORDER BY ${parts.orderSql} LIMIT ?`;
|
|
370
|
+
} else {
|
|
371
|
+
if (parsed.kind === "legacy") {
|
|
372
|
+
sql += ` AND ${col} ${order === "asc" ? ">" : "<"} ?`;
|
|
373
|
+
args.push(parsed.value);
|
|
374
|
+
}
|
|
375
|
+
sql += ` ORDER BY ${col} ${order} LIMIT ?`;
|
|
376
|
+
}
|
|
377
|
+
args.push(limit + 1);
|
|
378
|
+
const result = await this.client.execute({
|
|
379
|
+
sql,
|
|
380
|
+
args
|
|
381
|
+
});
|
|
382
|
+
const hasMore = result.rows.length > limit;
|
|
383
|
+
const rows = hasMore ? result.rows.slice(0, limit) : result.rows;
|
|
384
|
+
const last = rows[rows.length - 1];
|
|
385
|
+
const cursor = !hasMore || !last ? void 0 : hasOrderBy ? require_tree_index.buildKeysetCursor(sortValueOf(last, col), last.path) : String(last.path);
|
|
386
|
+
return {
|
|
387
|
+
entries: rows.map((r) => {
|
|
388
|
+
const e = {
|
|
389
|
+
path: r.path,
|
|
390
|
+
cid: r.cid,
|
|
391
|
+
size: num(r.size),
|
|
392
|
+
mtime: num(r.mtime),
|
|
393
|
+
ctime: num(r.ctime),
|
|
394
|
+
mimeType: r.mime_type ?? void 0
|
|
395
|
+
};
|
|
396
|
+
if (options?.includeContent && r.content != null) e.content = r.content;
|
|
397
|
+
return e;
|
|
398
|
+
}),
|
|
399
|
+
hasMore,
|
|
400
|
+
cursor
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
async hasChildren(prefix) {
|
|
404
|
+
const [lo, hi] = require_prefix_range.prefixRange(prefix);
|
|
405
|
+
return (await this.client.execute({
|
|
406
|
+
sql: "SELECT 1 FROM ds_entries WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file' LIMIT 1",
|
|
407
|
+
args: [
|
|
408
|
+
this.scope,
|
|
409
|
+
lo,
|
|
410
|
+
hi
|
|
411
|
+
]
|
|
412
|
+
})).rows.length > 0;
|
|
413
|
+
}
|
|
414
|
+
async count(prefix) {
|
|
415
|
+
const [lo, hi] = require_prefix_range.prefixRange(prefix);
|
|
416
|
+
return num((await this.client.execute({
|
|
417
|
+
sql: "SELECT COUNT(*) as cnt FROM ds_entries WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file'",
|
|
418
|
+
args: [
|
|
419
|
+
this.scope,
|
|
420
|
+
lo,
|
|
421
|
+
hi
|
|
422
|
+
]
|
|
423
|
+
})).rows[0]?.cnt);
|
|
424
|
+
}
|
|
425
|
+
async deleteByPrefix(prefix, opts) {
|
|
426
|
+
require_changelog_write.validateDeviceId(opts.deviceId);
|
|
427
|
+
const [lo, hi] = require_prefix_range.prefixRange(prefix);
|
|
428
|
+
const stmts = [];
|
|
429
|
+
if (!opts.skipChangelog) stmts.push({
|
|
430
|
+
sql: `INSERT INTO ds_changelog (scope, path, op, cid, old_cid, size, mtime, device_id)
|
|
431
|
+
SELECT ?, path, 'delete', NULL, cid, NULL, ?, ?
|
|
432
|
+
FROM ds_entries INDEXED BY idx_entries_kind WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file' AND cid IS NOT NULL`,
|
|
433
|
+
args: [
|
|
434
|
+
this.scope,
|
|
435
|
+
opts.mtime ?? Date.now(),
|
|
436
|
+
opts.deviceId,
|
|
437
|
+
this.scope,
|
|
438
|
+
lo,
|
|
439
|
+
hi
|
|
440
|
+
]
|
|
441
|
+
});
|
|
442
|
+
if (!opts.skipChangelog) {
|
|
443
|
+
const wmPrefix = require_changelog_schema.watermarkPrefix(prefix);
|
|
444
|
+
if (wmPrefix !== null) stmts.push({
|
|
445
|
+
sql: require_changelog_schema.PREFIX_WATERMARK_BUMP_SQL,
|
|
446
|
+
args: [this.scope, wmPrefix]
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
stmts.push({
|
|
450
|
+
sql: "DELETE FROM ds_entries WHERE scope = ? AND path >= ? AND path < ?",
|
|
451
|
+
args: [
|
|
452
|
+
this.scope,
|
|
453
|
+
lo,
|
|
454
|
+
hi
|
|
455
|
+
]
|
|
456
|
+
});
|
|
457
|
+
const results = await this.client.batch(stmts, "write");
|
|
458
|
+
return num(results[results.length - 1]?.rowsAffected);
|
|
459
|
+
}
|
|
460
|
+
async listChildren(parent, options) {
|
|
461
|
+
const limit = options?.limit ?? 1e3;
|
|
462
|
+
const order = options?.order === "desc" ? "desc" : "asc";
|
|
463
|
+
if (limit === 0) return {
|
|
464
|
+
entries: [],
|
|
465
|
+
hasMore: false
|
|
466
|
+
};
|
|
467
|
+
const hasOrderBy = options?.orderBy !== void 0;
|
|
468
|
+
const parsed = require_tree_index.parseTreeCursor(options?.cursor, hasOrderBy);
|
|
469
|
+
const includeContent = options?.includeContent === true;
|
|
470
|
+
const t = "e.";
|
|
471
|
+
const from = require_tree_query.buildChildrenFrom(void 0);
|
|
472
|
+
const args = [
|
|
473
|
+
...from.args,
|
|
474
|
+
this.scope,
|
|
475
|
+
parent
|
|
476
|
+
];
|
|
477
|
+
let sql = `SELECT ${t}path, ${t}cid, ${t}size, ${t}mtime, ${t}ctime, ${t}mime_type, ${t}name${includeContent ? `, ${t}content` : ""} ${from.sql} WHERE ${t}scope = ? AND ${t}parent = ?`;
|
|
478
|
+
if (hasOrderBy) {
|
|
479
|
+
const col = VALID_ORDER_BY[options.orderBy];
|
|
480
|
+
if (!col) throw new Error(`Invalid orderBy: ${options?.orderBy}`);
|
|
481
|
+
const parts = require_tree_index.buildOrderedQueryParts({
|
|
482
|
+
col: `${t}${col}`,
|
|
483
|
+
nullable: NULLABLE_ORDER_COLUMNS.has(col),
|
|
484
|
+
order,
|
|
485
|
+
tieCol: `${t}name`,
|
|
486
|
+
cursor: parsed.kind === "v2" ? parsed.cursor : void 0
|
|
487
|
+
});
|
|
488
|
+
if (parts.cursorWhereSql) {
|
|
489
|
+
sql += ` AND ${parts.cursorWhereSql}`;
|
|
490
|
+
args.push(...parts.cursorArgs);
|
|
491
|
+
}
|
|
492
|
+
sql += ` ORDER BY ${parts.orderSql} LIMIT ?`;
|
|
493
|
+
args.push(limit + 1);
|
|
494
|
+
const result$1 = await this.client.execute({
|
|
495
|
+
sql,
|
|
496
|
+
args
|
|
497
|
+
});
|
|
498
|
+
const hasMore$1 = result$1.rows.length > limit;
|
|
499
|
+
const rows$1 = hasMore$1 ? result$1.rows.slice(0, limit) : result$1.rows;
|
|
500
|
+
const last = rows$1[rows$1.length - 1];
|
|
501
|
+
return {
|
|
502
|
+
entries: rows$1.map((r) => mapChildRow(r)),
|
|
503
|
+
hasMore: hasMore$1,
|
|
504
|
+
cursor: hasMore$1 && last ? require_tree_index.buildKeysetCursor(sortValueOf(last, col), last.name) : void 0
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
if (parsed.kind === "legacy") {
|
|
508
|
+
sql += ` AND ${t}name ${order === "asc" ? ">" : "<"} ?`;
|
|
509
|
+
args.push(parsed.value);
|
|
510
|
+
}
|
|
511
|
+
sql += ` ORDER BY ${t}name ${order} LIMIT ?`;
|
|
512
|
+
args.push(limit + 1);
|
|
513
|
+
const result = await this.client.execute({
|
|
514
|
+
sql,
|
|
515
|
+
args
|
|
516
|
+
});
|
|
517
|
+
const hasMore = result.rows.length > limit;
|
|
518
|
+
const rows = hasMore ? result.rows.slice(0, limit) : result.rows;
|
|
519
|
+
return {
|
|
520
|
+
entries: rows.map((r) => mapChildRow(r)),
|
|
521
|
+
hasMore,
|
|
522
|
+
cursor: hasMore && rows.length > 0 ? String(rows[rows.length - 1].name) : void 0
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
async countChildren(parent) {
|
|
526
|
+
return num((await this.client.execute({
|
|
527
|
+
sql: "SELECT COUNT(*) as cnt FROM ds_entries WHERE scope = ? AND parent = ?",
|
|
528
|
+
args: [this.scope, parent]
|
|
529
|
+
})).rows[0]?.cnt);
|
|
530
|
+
}
|
|
531
|
+
/** Collection query (afs-collection-query Phase 1) — see tree-query.ts. */
|
|
532
|
+
async query(parent, spec) {
|
|
533
|
+
const statements = require_tree_query.buildTreeQueryStatements({
|
|
534
|
+
scope: this.scope,
|
|
535
|
+
parent,
|
|
536
|
+
spec
|
|
537
|
+
});
|
|
538
|
+
if (statements.aggregate) {
|
|
539
|
+
const [aggRes, countRes$1] = await Promise.all([this.client.execute({
|
|
540
|
+
sql: statements.aggregate.select.sql,
|
|
541
|
+
args: statements.aggregate.select.args
|
|
542
|
+
}), this.client.execute({
|
|
543
|
+
sql: statements.aggregate.countGroups.sql,
|
|
544
|
+
args: statements.aggregate.countGroups.args
|
|
545
|
+
})]);
|
|
546
|
+
const aggregateGroups = require_tree_query.mapAggregateRows(aggRes.rows, statements.aggregate.groupKeys, statements.aggregate.aggregations);
|
|
547
|
+
return {
|
|
548
|
+
rows: [],
|
|
549
|
+
total: statements.aggregate.groupKeys.length === 0 ? 1 : num(countRes$1.rows[0]?.cnt),
|
|
550
|
+
aggregateGroups
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
const [rowsRes, countRes, groupsRes, seekRes] = await Promise.all([
|
|
554
|
+
this.client.execute({
|
|
555
|
+
sql: statements.rows.sql,
|
|
556
|
+
args: statements.rows.args
|
|
557
|
+
}),
|
|
558
|
+
statements.count ? this.client.execute({
|
|
559
|
+
sql: statements.count.sql,
|
|
560
|
+
args: statements.count.args
|
|
561
|
+
}) : Promise.resolve(void 0),
|
|
562
|
+
statements.groups ? this.client.execute({
|
|
563
|
+
sql: statements.groups.sql,
|
|
564
|
+
args: statements.groups.args
|
|
565
|
+
}) : Promise.resolve(void 0),
|
|
566
|
+
statements.seek ? this.client.execute({
|
|
567
|
+
sql: statements.seek.sql,
|
|
568
|
+
args: statements.seek.args
|
|
569
|
+
}) : Promise.resolve(void 0)
|
|
570
|
+
]);
|
|
571
|
+
const seekOffset = statements.seek ? seekRes && seekRes.rows.length > 0 ? num(seekRes.rows[0]?.rn) : -1 : void 0;
|
|
572
|
+
return require_tree_query.buildTreeQueryResultFromSql({
|
|
573
|
+
rawRows: rowsRes.rows,
|
|
574
|
+
total: countRes ? num(countRes.rows[0]?.cnt) : -1,
|
|
575
|
+
groupRows: groupsRes?.rows.map((r) => ({
|
|
576
|
+
t: r.t,
|
|
577
|
+
v: r.v,
|
|
578
|
+
cnt: r.cnt
|
|
579
|
+
})),
|
|
580
|
+
spec,
|
|
581
|
+
orderField: statements.order.field,
|
|
582
|
+
seekOffset
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
/** Page-bounded grouped child counts — see D1TreeIndex.countChildrenMany
|
|
586
|
+
* (same ≤90-per-chunk shape kept for cross-backend statement parity). */
|
|
587
|
+
async countChildrenMany(parents) {
|
|
588
|
+
const map = /* @__PURE__ */ new Map();
|
|
589
|
+
for (let offset = 0; offset < parents.length; offset += 90) {
|
|
590
|
+
const chunk = parents.slice(offset, offset + 90);
|
|
591
|
+
const result = await this.client.execute({
|
|
592
|
+
sql: `SELECT parent, COUNT(*) as cnt FROM ds_entries WHERE scope = ? AND parent IN (${chunk.map(() => "?").join(",")}) GROUP BY parent`,
|
|
593
|
+
args: [this.scope, ...chunk]
|
|
594
|
+
});
|
|
595
|
+
for (const r of result.rows) map.set(r.parent, num(r.cnt));
|
|
596
|
+
}
|
|
597
|
+
return map;
|
|
598
|
+
}
|
|
599
|
+
async aggregate(prefix) {
|
|
600
|
+
const [lo, hi] = require_prefix_range.prefixRange(prefix);
|
|
601
|
+
const row = (await this.client.execute({
|
|
602
|
+
sql: `SELECT COUNT(*) as file_count, COALESCE(SUM(size), 0) as total_size
|
|
603
|
+
FROM ds_entries INDEXED BY idx_entries_kind WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file'`,
|
|
604
|
+
args: [
|
|
605
|
+
this.scope,
|
|
606
|
+
lo,
|
|
607
|
+
hi
|
|
608
|
+
]
|
|
609
|
+
})).rows[0];
|
|
610
|
+
return {
|
|
611
|
+
fileCount: num(row?.file_count),
|
|
612
|
+
totalSize: num(row?.total_size)
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
/** Batch metadata read — loop over get (no IN-merge needed off-CF). */
|
|
616
|
+
async getMany(paths) {
|
|
617
|
+
const map = /* @__PURE__ */ new Map();
|
|
618
|
+
for (const path of paths) map.set(path, await this.get(path));
|
|
619
|
+
return map;
|
|
620
|
+
}
|
|
621
|
+
/** Batch sync fast path — loop reference semantics (conformance-pinned
|
|
622
|
+
* equivalent of the merged D1 implementation). */
|
|
623
|
+
async batchPutEntries(entries, ctx) {
|
|
624
|
+
return require_tree_index.loopBatchPutEntries(this, entries, ctx);
|
|
625
|
+
}
|
|
626
|
+
/** Delete twin of {@link batchPutEntries} (loop reference semantics). */
|
|
627
|
+
async batchDeleteEntries(entries, ctx) {
|
|
628
|
+
return require_tree_index.loopBatchDeleteEntries(this, entries, ctx);
|
|
629
|
+
}
|
|
630
|
+
async putBatch(entries, opts) {
|
|
631
|
+
if (entries.length === 0) return;
|
|
632
|
+
require_changelog_write.validateDeviceId(opts.deviceId);
|
|
633
|
+
const now = Date.now();
|
|
634
|
+
const stmts = [];
|
|
635
|
+
const dirStamps = /* @__PURE__ */ new Map();
|
|
636
|
+
const allDirs = /* @__PURE__ */ new Set();
|
|
637
|
+
for (const { path, entry } of entries) {
|
|
638
|
+
const stamp = require_timestamp.resolveParentDirStamp(entry.metadata);
|
|
639
|
+
if (stamp) dirStamps.set(require_d1_tree_index.parentOf(path), stamp);
|
|
640
|
+
for (const dirPath of require_d1_tree_index.ancestorDirs(path)) {
|
|
641
|
+
if (allDirs.has(dirPath)) break;
|
|
642
|
+
allDirs.add(dirPath);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
for (const dirPath of allDirs) stmts.push(require_d1_tree_index.buildDirChainStmt(this.scope, dirPath, dirStamps.get(dirPath) ?? null, now));
|
|
646
|
+
for (const { path, entry } of entries) {
|
|
647
|
+
if (!opts.skipChangelog) stmts.push({
|
|
648
|
+
sql: CHANGELOG_INSERT_SQL_WITH_SUBQUERY,
|
|
649
|
+
args: [
|
|
650
|
+
this.scope,
|
|
651
|
+
path,
|
|
652
|
+
entry.cid,
|
|
653
|
+
this.scope,
|
|
654
|
+
path,
|
|
655
|
+
entry.size,
|
|
656
|
+
entry.mtime,
|
|
657
|
+
opts.deviceId
|
|
658
|
+
]
|
|
659
|
+
});
|
|
660
|
+
stmts.push(await this.buildFileUpsert(path, entry));
|
|
661
|
+
}
|
|
662
|
+
if (!opts.skipChangelog) {
|
|
663
|
+
const wmPrefixes = /* @__PURE__ */ new Set();
|
|
664
|
+
for (const { path } of entries) {
|
|
665
|
+
const wmPrefix = require_changelog_schema.watermarkWritePrefix(path);
|
|
666
|
+
if (wmPrefix !== null) wmPrefixes.add(wmPrefix);
|
|
667
|
+
}
|
|
668
|
+
for (const wmPrefix of wmPrefixes) stmts.push({
|
|
669
|
+
sql: require_changelog_schema.PREFIX_WATERMARK_BUMP_SQL,
|
|
670
|
+
args: [this.scope, wmPrefix]
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
await this.client.batch(stmts, "write");
|
|
674
|
+
}
|
|
675
|
+
async listModifiedSince(prefix, since, options) {
|
|
676
|
+
const limit = options?.limit ?? 1e3;
|
|
677
|
+
const order = options?.order ?? "asc";
|
|
678
|
+
if (limit === 0) return {
|
|
679
|
+
entries: [],
|
|
680
|
+
hasMore: false
|
|
681
|
+
};
|
|
682
|
+
const [lo, hi] = require_prefix_range.prefixRange(prefix);
|
|
683
|
+
const args = [
|
|
684
|
+
this.scope,
|
|
685
|
+
lo,
|
|
686
|
+
hi,
|
|
687
|
+
since
|
|
688
|
+
];
|
|
689
|
+
let sql = `SELECT path, cid, size, mtime, ctime, mime_type FROM ds_entries INDEXED BY idx_entries_kind
|
|
690
|
+
WHERE scope = ? AND path >= ? AND path < ? AND mtime > ? AND kind = 'file'`;
|
|
691
|
+
if (options?.cursor) {
|
|
692
|
+
sql += ` AND path ${order === "asc" ? ">" : "<"} ?`;
|
|
693
|
+
args.push(options.cursor);
|
|
694
|
+
}
|
|
695
|
+
sql += ` ORDER BY path ${order} LIMIT ?`;
|
|
696
|
+
args.push(limit + 1);
|
|
697
|
+
const result = await this.client.execute({
|
|
698
|
+
sql,
|
|
699
|
+
args
|
|
700
|
+
});
|
|
701
|
+
const hasMore = result.rows.length > limit;
|
|
702
|
+
const rows = hasMore ? result.rows.slice(0, limit) : result.rows;
|
|
703
|
+
return {
|
|
704
|
+
entries: rows.map((r) => ({
|
|
705
|
+
path: r.path,
|
|
706
|
+
cid: r.cid,
|
|
707
|
+
size: num(r.size),
|
|
708
|
+
mtime: num(r.mtime),
|
|
709
|
+
ctime: num(r.ctime),
|
|
710
|
+
mimeType: r.mime_type ?? void 0
|
|
711
|
+
})),
|
|
712
|
+
hasMore,
|
|
713
|
+
cursor: hasMore && rows.length > 0 ? String(rows[rows.length - 1].path) : void 0
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
async getMaxSeq() {
|
|
717
|
+
const [result, compactedBelow] = await Promise.all([this.client.execute({
|
|
718
|
+
sql: "SELECT MAX(seq) as maxSeq FROM ds_changelog WHERE scope = ?",
|
|
719
|
+
args: [this.scope]
|
|
720
|
+
}), this.getCompactedBelowSeq()]);
|
|
721
|
+
return Math.max(num(result.rows[0]?.maxSeq), compactedBelow);
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Read-auth reference check (design §4.1) — three-way, scoped, optionally
|
|
725
|
+
* prefix-local. See {@link TreeIndex.isReferenced}.
|
|
726
|
+
*/
|
|
727
|
+
async isReferenced(cid, pathPrefix = "") {
|
|
728
|
+
if (!cid) return false;
|
|
729
|
+
if (pathPrefix === "") return (await this.client.execute({
|
|
730
|
+
sql: `SELECT 1 FROM (
|
|
731
|
+
SELECT 1 FROM ds_entries WHERE scope = ? AND cid = ?
|
|
732
|
+
UNION ALL
|
|
733
|
+
SELECT 1 FROM ds_changelog WHERE scope = ? AND cid = ?
|
|
734
|
+
UNION ALL
|
|
735
|
+
SELECT 1 FROM ds_changelog WHERE scope = ? AND old_cid = ?
|
|
736
|
+
) LIMIT 1`,
|
|
737
|
+
args: [
|
|
738
|
+
this.scope,
|
|
739
|
+
cid,
|
|
740
|
+
this.scope,
|
|
741
|
+
cid,
|
|
742
|
+
this.scope,
|
|
743
|
+
cid
|
|
744
|
+
]
|
|
745
|
+
})).rows.length > 0;
|
|
746
|
+
const [lo, hi] = require_prefix_range.prefixRange(pathPrefix);
|
|
747
|
+
return (await this.client.execute({
|
|
748
|
+
sql: `SELECT 1 FROM (
|
|
749
|
+
SELECT 1 FROM ds_entries WHERE scope = ? AND cid = ? AND path >= ? AND path < ?
|
|
750
|
+
UNION ALL
|
|
751
|
+
SELECT 1 FROM ds_changelog WHERE scope = ? AND cid = ? AND path >= ? AND path < ?
|
|
752
|
+
UNION ALL
|
|
753
|
+
SELECT 1 FROM ds_changelog WHERE scope = ? AND old_cid = ? AND path >= ? AND path < ?
|
|
754
|
+
) LIMIT 1`,
|
|
755
|
+
args: [
|
|
756
|
+
this.scope,
|
|
757
|
+
cid,
|
|
758
|
+
lo,
|
|
759
|
+
hi,
|
|
760
|
+
this.scope,
|
|
761
|
+
cid,
|
|
762
|
+
lo,
|
|
763
|
+
hi,
|
|
764
|
+
this.scope,
|
|
765
|
+
cid,
|
|
766
|
+
lo,
|
|
767
|
+
hi
|
|
768
|
+
]
|
|
769
|
+
})).rows.length > 0;
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* Batch read-auth (design §7.2 / §14) — three-way-equivalent to per-cid
|
|
773
|
+
* {@link isReferenced}, sharded (see {@link SQLITE_MANY_SHARD_SIZE}). Returns
|
|
774
|
+
* the referenced subset of `cids`.
|
|
775
|
+
*/
|
|
776
|
+
async isReferencedMany(cids, pathPrefix = "") {
|
|
777
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
778
|
+
const unique = [...new Set(cids.filter((c) => c))];
|
|
779
|
+
if (unique.length === 0) return referenced;
|
|
780
|
+
const usePrefix = pathPrefix !== "";
|
|
781
|
+
const [lo, hi] = usePrefix ? require_prefix_range.prefixRange(pathPrefix) : ["", ""];
|
|
782
|
+
for (let i = 0; i < unique.length; i += SQLITE_MANY_SHARD_SIZE) {
|
|
783
|
+
const shard = unique.slice(i, i + SQLITE_MANY_SHARD_SIZE);
|
|
784
|
+
const ph = shard.map(() => "?").join(",");
|
|
785
|
+
const tail = usePrefix ? "AND path >= ? AND path < ?" : "";
|
|
786
|
+
const sql = `SELECT cid AS c FROM ds_entries WHERE scope = ? AND cid IN (${ph}) ${tail}
|
|
787
|
+
UNION
|
|
788
|
+
SELECT cid AS c FROM ds_changelog WHERE scope = ? AND cid IN (${ph}) ${tail}
|
|
789
|
+
UNION
|
|
790
|
+
SELECT old_cid AS c FROM ds_changelog WHERE scope = ? AND old_cid IN (${ph}) ${tail}`;
|
|
791
|
+
const args = [];
|
|
792
|
+
for (let b = 0; b < 3; b++) {
|
|
793
|
+
args.push(this.scope, ...shard);
|
|
794
|
+
if (usePrefix) args.push(lo, hi);
|
|
795
|
+
}
|
|
796
|
+
const result = await this.client.execute({
|
|
797
|
+
sql,
|
|
798
|
+
args
|
|
799
|
+
});
|
|
800
|
+
for (const row of result.rows) {
|
|
801
|
+
const c = row.c;
|
|
802
|
+
if (c) referenced.add(c);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return referenced;
|
|
806
|
+
}
|
|
807
|
+
async getChangelogSince(sinceSeq, limit) {
|
|
808
|
+
const safeLimit = limit > 0 ? limit : 0;
|
|
809
|
+
if (safeLimit === 0) return {
|
|
810
|
+
entries: [],
|
|
811
|
+
hasMore: false,
|
|
812
|
+
cursor: sinceSeq
|
|
813
|
+
};
|
|
814
|
+
const result = await this.client.execute({
|
|
815
|
+
sql: `SELECT seq, scope, path, op, cid, old_cid, size, mtime, device_id
|
|
816
|
+
FROM ds_changelog WHERE scope = ? AND seq > ? ORDER BY seq ASC LIMIT ?`,
|
|
817
|
+
args: [
|
|
818
|
+
this.scope,
|
|
819
|
+
sinceSeq,
|
|
820
|
+
safeLimit + 1
|
|
821
|
+
]
|
|
822
|
+
});
|
|
823
|
+
const hasMore = result.rows.length > safeLimit;
|
|
824
|
+
const entries = (hasMore ? result.rows.slice(0, safeLimit) : result.rows).map((r) => ({
|
|
825
|
+
seq: num(r.seq),
|
|
826
|
+
scope: r.scope,
|
|
827
|
+
path: r.path,
|
|
828
|
+
op: r.op,
|
|
829
|
+
cid: r.cid ?? null,
|
|
830
|
+
old_cid: r.old_cid ?? null,
|
|
831
|
+
size: r.size == null ? null : num(r.size),
|
|
832
|
+
mtime: num(r.mtime),
|
|
833
|
+
device_id: r.device_id
|
|
834
|
+
}));
|
|
835
|
+
return {
|
|
836
|
+
entries,
|
|
837
|
+
hasMore,
|
|
838
|
+
cursor: entries.length > 0 ? entries[entries.length - 1].seq : sinceSeq
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
async getCompactedBelowSeq() {
|
|
842
|
+
return 0;
|
|
843
|
+
}
|
|
844
|
+
async listDirtyPaths(options) {
|
|
845
|
+
const now = options.now ?? Date.now();
|
|
846
|
+
const limit = options.limit > 0 ? options.limit : 0;
|
|
847
|
+
if (limit === 0) return [];
|
|
848
|
+
const [lo, hi] = require_prefix_range.prefixRange(options.prefix);
|
|
849
|
+
const { rows } = await this.client.execute({
|
|
850
|
+
sql: require_dirty_path_schema.DIRTY_PATH_LIST_SQL,
|
|
851
|
+
args: [
|
|
852
|
+
this.scope,
|
|
853
|
+
lo,
|
|
854
|
+
hi,
|
|
855
|
+
now,
|
|
856
|
+
limit
|
|
857
|
+
]
|
|
858
|
+
});
|
|
859
|
+
return rows.map((r) => ({
|
|
860
|
+
path: String(r.path),
|
|
861
|
+
latestSeq: Number(r.latest_seq),
|
|
862
|
+
op: String(r.op),
|
|
863
|
+
cid: r.cid == null ? null : String(r.cid),
|
|
864
|
+
mtime: Number(r.mtime),
|
|
865
|
+
attempts: Number(r.attempts)
|
|
866
|
+
}));
|
|
867
|
+
}
|
|
868
|
+
async ackDirtyPath(path, latestSeq) {
|
|
869
|
+
return ((await this.client.execute({
|
|
870
|
+
sql: require_dirty_path_schema.DIRTY_PATH_ACK_SQL,
|
|
871
|
+
args: [
|
|
872
|
+
this.scope,
|
|
873
|
+
path,
|
|
874
|
+
latestSeq
|
|
875
|
+
]
|
|
876
|
+
})).rowsAffected ?? 0) > 0;
|
|
877
|
+
}
|
|
878
|
+
async markDirtyPathError(path, latestSeq, error, nextAttemptAt) {
|
|
879
|
+
return ((await this.client.execute({
|
|
880
|
+
sql: require_dirty_path_schema.DIRTY_PATH_MARK_ERROR_SQL,
|
|
881
|
+
args: [
|
|
882
|
+
error,
|
|
883
|
+
nextAttemptAt,
|
|
884
|
+
this.scope,
|
|
885
|
+
path,
|
|
886
|
+
latestSeq
|
|
887
|
+
]
|
|
888
|
+
})).rowsAffected ?? 0) > 0;
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
/**
|
|
892
|
+
* Put-path changelog INSERT with a correlated subquery reading the pre-write
|
|
893
|
+
* cid as old_cid (mirrors D1TreeIndex). Distinct from the plain
|
|
894
|
+
* `CHANGELOG_INSERT_SQL` in changelog-write.ts which takes old_cid as a bound
|
|
895
|
+
* param (used by MetadataDB.upsertEntry, which pre-reads old_cid separately).
|
|
896
|
+
*/
|
|
897
|
+
const CHANGELOG_INSERT_SQL_WITH_SUBQUERY = `INSERT INTO ds_changelog (scope, path, op, cid, old_cid, size, mtime, device_id)
|
|
898
|
+
VALUES (?, ?, 'put', ?, (SELECT cid FROM ds_entries WHERE scope = ? AND path = ?), ?, ?, ?)`;
|
|
899
|
+
|
|
900
|
+
//#endregion
|
|
901
|
+
exports.SQLiteTreeIndex = SQLiteTreeIndex;
|