@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,189 @@
|
|
|
1
|
+
const require_d1_schema = require('./d1-schema.cjs');
|
|
2
|
+
const require_prefix_range = require('./prefix-range.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/d1-resolve-store.ts
|
|
5
|
+
/** Extract owner and kind from a JSON value string. Returns nulls on parse failure or missing fields. */
|
|
6
|
+
function extractIndexFields(value) {
|
|
7
|
+
try {
|
|
8
|
+
const parsed = JSON.parse(value);
|
|
9
|
+
return {
|
|
10
|
+
owner: typeof parsed.owner === "string" ? parsed.owner : null,
|
|
11
|
+
kind: typeof parsed.type === "string" ? parsed.type : null
|
|
12
|
+
};
|
|
13
|
+
} catch {
|
|
14
|
+
return {
|
|
15
|
+
owner: null,
|
|
16
|
+
kind: null
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
var D1ResolveStore = class {
|
|
21
|
+
conn;
|
|
22
|
+
constructor(db, opts) {
|
|
23
|
+
this.db = db;
|
|
24
|
+
this.conn = opts?.useReplica && typeof db.withSession === "function" ? db.withSession("first-unconstrained") : db;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create table with full schema including Phase R columns.
|
|
28
|
+
* Production: schema created by `wrangler d1 migrations apply`.
|
|
29
|
+
* Tests: call this in beforeEach with in-memory DB.
|
|
30
|
+
*/
|
|
31
|
+
async ensureTable() {
|
|
32
|
+
await this.db.prepare(require_d1_schema.RESOLVE_ENTRIES_TABLE_SQL).run();
|
|
33
|
+
for (const sql of require_d1_schema.RESOLVE_ENTRIES_INDEX_SQL) await this.db.prepare(sql).run();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Add Phase R columns to an existing resolve_entries table that was created before migration 0006.
|
|
37
|
+
* Safe to call on an already-migrated table (checks before ALTER TABLE).
|
|
38
|
+
* Also creates the indexes if they don't exist.
|
|
39
|
+
*/
|
|
40
|
+
async ensureColumns() {
|
|
41
|
+
const { results } = await this.db.prepare("SELECT name FROM pragma_table_info('ds_resolve_entries')").all();
|
|
42
|
+
const existing = new Set(results.map((r) => r.name));
|
|
43
|
+
if (!existing.has("owner")) await this.db.prepare("ALTER TABLE ds_resolve_entries ADD COLUMN owner TEXT").run();
|
|
44
|
+
if (!existing.has("kind")) await this.db.prepare("ALTER TABLE ds_resolve_entries ADD COLUMN kind TEXT").run();
|
|
45
|
+
if (!existing.has("updated_at")) await this.db.prepare("ALTER TABLE ds_resolve_entries ADD COLUMN updated_at INTEGER").run();
|
|
46
|
+
if (!existing.has("created_at")) await this.db.prepare("ALTER TABLE ds_resolve_entries ADD COLUMN created_at INTEGER").run();
|
|
47
|
+
await this.db.prepare("CREATE INDEX IF NOT EXISTS idx_resolve_owner ON ds_resolve_entries(owner)").run();
|
|
48
|
+
await this.db.prepare("CREATE INDEX IF NOT EXISTS idx_resolve_kind ON ds_resolve_entries(kind)").run();
|
|
49
|
+
await this.db.prepare("CREATE INDEX IF NOT EXISTS idx_resolve_updated ON ds_resolve_entries(updated_at)").run();
|
|
50
|
+
await this.db.prepare("CREATE INDEX IF NOT EXISTS idx_resolve_created ON ds_resolve_entries(created_at)").run();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Backfill owner/kind/updated_at for rows that were inserted before Phase R.
|
|
54
|
+
* Idempotent: only updates rows where at least one index column is NULL.
|
|
55
|
+
* Call once on startup after ensureColumns().
|
|
56
|
+
*/
|
|
57
|
+
async backfill() {
|
|
58
|
+
const { results } = await this.db.prepare("SELECT key, value FROM ds_resolve_entries WHERE owner IS NULL OR kind IS NULL OR updated_at IS NULL OR created_at IS NULL").all();
|
|
59
|
+
for (const row of results) {
|
|
60
|
+
const { owner, kind } = extractIndexFields(row.value);
|
|
61
|
+
const now = Date.now();
|
|
62
|
+
await this.db.prepare("UPDATE ds_resolve_entries SET owner = ?, kind = ?, updated_at = COALESCE(updated_at, ?), created_at = COALESCE(created_at, updated_at, ?) WHERE key = ? AND (owner IS NULL OR kind IS NULL OR updated_at IS NULL OR created_at IS NULL)").bind(owner, kind, now, now, row.key).run();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async get(key) {
|
|
66
|
+
return (await this.conn.prepare("SELECT value FROM ds_resolve_entries WHERE key = ?").bind(key).first())?.value ?? null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Batch get (issue #808): one `WHERE key IN (...)` round trip for several keys
|
|
70
|
+
* — collapses the serve path's sequential `resolve/blocklet/<host>` +
|
|
71
|
+
* `resolve/domain/<host>` lookups. Missing keys are simply absent from the map.
|
|
72
|
+
* Deduped so a repeated key doesn't widen the IN list.
|
|
73
|
+
*/
|
|
74
|
+
async getMany(keys) {
|
|
75
|
+
const out = /* @__PURE__ */ new Map();
|
|
76
|
+
const unique = [...new Set(keys)];
|
|
77
|
+
if (unique.length === 0) return out;
|
|
78
|
+
const placeholders = unique.map(() => "?").join(",");
|
|
79
|
+
const { results } = await this.conn.prepare(`SELECT key, value FROM ds_resolve_entries WHERE key IN (${placeholders})`).bind(...unique).all();
|
|
80
|
+
for (const row of results ?? []) out.set(row.key, row.value);
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
async put(key, value) {
|
|
84
|
+
const strValue = typeof value === "string" ? value : new TextDecoder().decode(value);
|
|
85
|
+
const { owner, kind } = extractIndexFields(strValue);
|
|
86
|
+
const now = Date.now();
|
|
87
|
+
await this.conn.prepare(`INSERT INTO ds_resolve_entries (key, value, owner, kind, updated_at, created_at) VALUES (?, ?, ?, ?, ?, ?)
|
|
88
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value, owner = excluded.owner, kind = excluded.kind, updated_at = excluded.updated_at`).bind(key, strValue, owner, kind, now, now).run();
|
|
89
|
+
}
|
|
90
|
+
async delete(key) {
|
|
91
|
+
await this.conn.prepare("DELETE FROM ds_resolve_entries WHERE key = ?").bind(key).run();
|
|
92
|
+
}
|
|
93
|
+
async list(options) {
|
|
94
|
+
const prefix = options?.prefix ?? "";
|
|
95
|
+
const limit = options?.limit ?? 1e3;
|
|
96
|
+
const cursor = options?.cursor;
|
|
97
|
+
const [lo, hi] = require_prefix_range.prefixRange(prefix);
|
|
98
|
+
const params = [lo, hi];
|
|
99
|
+
let sql = "SELECT key FROM ds_resolve_entries WHERE key >= ? AND key < ?";
|
|
100
|
+
if (cursor) {
|
|
101
|
+
sql += " AND key > ?";
|
|
102
|
+
params.push(cursor);
|
|
103
|
+
}
|
|
104
|
+
sql += " ORDER BY key LIMIT ?";
|
|
105
|
+
params.push(limit + 1);
|
|
106
|
+
const { results } = await this.conn.prepare(sql).bind(...params).all();
|
|
107
|
+
const hasMore = results.length > limit;
|
|
108
|
+
const selected = hasMore ? results.slice(0, limit) : results;
|
|
109
|
+
return {
|
|
110
|
+
keys: selected.map((r) => ({ name: r.key })),
|
|
111
|
+
list_complete: !hasMore,
|
|
112
|
+
cursor: hasMore && selected.length > 0 ? selected[selected.length - 1].key : void 0
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
async listWithValues(options) {
|
|
116
|
+
const prefix = options?.prefix ?? "";
|
|
117
|
+
const limit = options?.limit && options.limit > 0 ? options.limit : 1e3;
|
|
118
|
+
const cursor = options?.cursor;
|
|
119
|
+
const [lo, hi] = require_prefix_range.prefixRange(prefix);
|
|
120
|
+
const params = [lo, hi];
|
|
121
|
+
let sql = "SELECT key, value FROM ds_resolve_entries WHERE key >= ? AND key < ?";
|
|
122
|
+
if (cursor) {
|
|
123
|
+
sql += " AND key > ?";
|
|
124
|
+
params.push(cursor);
|
|
125
|
+
}
|
|
126
|
+
sql += " ORDER BY key LIMIT ?";
|
|
127
|
+
params.push(limit + 1);
|
|
128
|
+
const { results } = await this.conn.prepare(sql).bind(...params).all();
|
|
129
|
+
const hasMore = results.length > limit;
|
|
130
|
+
const selected = hasMore ? results.slice(0, limit) : results;
|
|
131
|
+
return {
|
|
132
|
+
entries: selected.map((r) => ({
|
|
133
|
+
key: r.key,
|
|
134
|
+
value: r.value
|
|
135
|
+
})),
|
|
136
|
+
list_complete: !hasMore,
|
|
137
|
+
cursor: hasMore && selected.length > 0 ? selected[selected.length - 1].key : void 0
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Like listWithValues but also returns created_at and updated_at columns.
|
|
142
|
+
* Used by DIDSpaceResolver to surface timestamps without a separate query.
|
|
143
|
+
*/
|
|
144
|
+
async listWithTimestamps(options) {
|
|
145
|
+
const prefix = options?.prefix ?? "";
|
|
146
|
+
const limit = options?.limit && options.limit > 0 ? options.limit : 1e3;
|
|
147
|
+
const cursor = options?.cursor;
|
|
148
|
+
const [lo, hi] = require_prefix_range.prefixRange(prefix);
|
|
149
|
+
const params = [lo, hi];
|
|
150
|
+
let sql = "SELECT key, value, created_at, updated_at FROM ds_resolve_entries WHERE key >= ? AND key < ?";
|
|
151
|
+
if (cursor) {
|
|
152
|
+
sql += " AND key > ?";
|
|
153
|
+
params.push(cursor);
|
|
154
|
+
}
|
|
155
|
+
sql += " ORDER BY key LIMIT ?";
|
|
156
|
+
params.push(limit + 1);
|
|
157
|
+
const { results } = await this.conn.prepare(sql).bind(...params).all();
|
|
158
|
+
const hasMore = results.length > limit;
|
|
159
|
+
const selected = hasMore ? results.slice(0, limit) : results;
|
|
160
|
+
return {
|
|
161
|
+
entries: selected.map((r) => ({
|
|
162
|
+
key: r.key,
|
|
163
|
+
value: r.value,
|
|
164
|
+
created_at: r.created_at,
|
|
165
|
+
updated_at: r.updated_at
|
|
166
|
+
})),
|
|
167
|
+
list_complete: !hasMore,
|
|
168
|
+
cursor: hasMore && selected.length > 0 ? selected[selected.length - 1].key : void 0
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* List all entries for a given owner. Uses idx_resolve_owner index.
|
|
173
|
+
* Returns key + value pairs for all rows where owner matches.
|
|
174
|
+
*/
|
|
175
|
+
async listByOwner(owner) {
|
|
176
|
+
const { results } = await this.conn.prepare("SELECT key, value FROM ds_resolve_entries WHERE owner = ?").bind(owner).all();
|
|
177
|
+
return results;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Read the index columns (owner, kind, updated_at) for a given key.
|
|
181
|
+
* Primarily used for testing and debugging — verifies Phase R columns are populated.
|
|
182
|
+
*/
|
|
183
|
+
async getIndexColumns(key) {
|
|
184
|
+
return this.conn.prepare("SELECT owner, kind, updated_at, created_at FROM ds_resolve_entries WHERE key = ?").bind(key).first();
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
//#endregion
|
|
189
|
+
exports.D1ResolveStore = D1ResolveStore;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { KeyValueStore, KeyValueStoreListWithValuesResult } from "@aigne/afs-kv";
|
|
2
|
+
|
|
3
|
+
//#region src/d1-resolve-store.d.ts
|
|
4
|
+
declare class D1ResolveStore implements KeyValueStore {
|
|
5
|
+
private db;
|
|
6
|
+
private readonly conn;
|
|
7
|
+
constructor(db: D1Database, opts?: {
|
|
8
|
+
useReplica?: boolean;
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* Create table with full schema including Phase R columns.
|
|
12
|
+
* Production: schema created by `wrangler d1 migrations apply`.
|
|
13
|
+
* Tests: call this in beforeEach with in-memory DB.
|
|
14
|
+
*/
|
|
15
|
+
ensureTable(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Add Phase R columns to an existing resolve_entries table that was created before migration 0006.
|
|
18
|
+
* Safe to call on an already-migrated table (checks before ALTER TABLE).
|
|
19
|
+
* Also creates the indexes if they don't exist.
|
|
20
|
+
*/
|
|
21
|
+
ensureColumns(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Backfill owner/kind/updated_at for rows that were inserted before Phase R.
|
|
24
|
+
* Idempotent: only updates rows where at least one index column is NULL.
|
|
25
|
+
* Call once on startup after ensureColumns().
|
|
26
|
+
*/
|
|
27
|
+
backfill(): Promise<void>;
|
|
28
|
+
get(key: string): Promise<string | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Batch get (issue #808): one `WHERE key IN (...)` round trip for several keys
|
|
31
|
+
* — collapses the serve path's sequential `resolve/blocklet/<host>` +
|
|
32
|
+
* `resolve/domain/<host>` lookups. Missing keys are simply absent from the map.
|
|
33
|
+
* Deduped so a repeated key doesn't widen the IN list.
|
|
34
|
+
*/
|
|
35
|
+
getMany(keys: string[]): Promise<Map<string, string | null>>;
|
|
36
|
+
put(key: string, value: string | ArrayBuffer): Promise<void>;
|
|
37
|
+
delete(key: string): Promise<void>;
|
|
38
|
+
list(options?: {
|
|
39
|
+
prefix?: string;
|
|
40
|
+
cursor?: string;
|
|
41
|
+
limit?: number;
|
|
42
|
+
}): Promise<{
|
|
43
|
+
keys: {
|
|
44
|
+
name: string;
|
|
45
|
+
}[];
|
|
46
|
+
list_complete: boolean;
|
|
47
|
+
cursor: string | undefined;
|
|
48
|
+
}>;
|
|
49
|
+
listWithValues(options?: {
|
|
50
|
+
prefix?: string;
|
|
51
|
+
cursor?: string;
|
|
52
|
+
limit?: number;
|
|
53
|
+
}): Promise<KeyValueStoreListWithValuesResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Like listWithValues but also returns created_at and updated_at columns.
|
|
56
|
+
* Used by DIDSpaceResolver to surface timestamps without a separate query.
|
|
57
|
+
*/
|
|
58
|
+
listWithTimestamps(options?: {
|
|
59
|
+
prefix?: string;
|
|
60
|
+
cursor?: string;
|
|
61
|
+
limit?: number;
|
|
62
|
+
}): Promise<{
|
|
63
|
+
entries: Array<{
|
|
64
|
+
key: string;
|
|
65
|
+
value: string;
|
|
66
|
+
created_at: number | null;
|
|
67
|
+
updated_at: number | null;
|
|
68
|
+
}>;
|
|
69
|
+
list_complete: boolean;
|
|
70
|
+
cursor?: string;
|
|
71
|
+
}>;
|
|
72
|
+
/**
|
|
73
|
+
* List all entries for a given owner. Uses idx_resolve_owner index.
|
|
74
|
+
* Returns key + value pairs for all rows where owner matches.
|
|
75
|
+
*/
|
|
76
|
+
listByOwner(owner: string): Promise<{
|
|
77
|
+
key: string;
|
|
78
|
+
value: string;
|
|
79
|
+
}[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Read the index columns (owner, kind, updated_at) for a given key.
|
|
82
|
+
* Primarily used for testing and debugging — verifies Phase R columns are populated.
|
|
83
|
+
*/
|
|
84
|
+
getIndexColumns(key: string): Promise<{
|
|
85
|
+
owner: string | null;
|
|
86
|
+
kind: string | null;
|
|
87
|
+
updated_at: number | null;
|
|
88
|
+
created_at: number | null;
|
|
89
|
+
} | null>;
|
|
90
|
+
}
|
|
91
|
+
//#endregion
|
|
92
|
+
export { D1ResolveStore };
|
|
93
|
+
//# sourceMappingURL=d1-resolve-store.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"d1-resolve-store.d.cts","names":[],"sources":["../src/d1-resolve-store.ts"],"mappings":";;;cA4Ba,cAAA,YAA0B,aAAA;EAAA,QAI3B,EAAA;EAAA,iBAHO,IAAA;cAGP,EAAA,EAAI,UAAA,EACZ,IAAA;IAAS,UAAA;EAAA;EAmKP;;;;;EAtJE,WAAA,CAAA,GAAe,OAAA;EAlB6B;;;;;EA+B5C,aAAA,CAAA,GAAiB,OAAA;EA3BT;;;;;EAiER,QAAA,CAAA,GAAY,OAAA;EAmBZ,GAAA,CAAI,GAAA,WAAc,OAAA;EAzDD;;;;;;EAuEjB,OAAA,CAAQ,IAAA,aAAiB,OAAA,CAAQ,GAAA;EAajC,GAAA,CAAI,GAAA,UAAa,KAAA,WAAgB,WAAA,GAAc,OAAA;EAa/C,MAAA,CAAO,GAAA,WAAc,OAAA;EAIrB,IAAA,CAAK,OAAA;IAAY,MAAA;IAAiB,MAAA;IAAiB,KAAA;EAAA,IAAgB,OAAA;;;;;;;EAgCnE,cAAA,CAAe,OAAA;IACnB,MAAA;IACA,MAAA;IACA,KAAA;EAAA,IACE,OAAA,CAAQ,iCAAA;;;;;EAoCN,kBAAA,CAAmB,OAAA;IACvB,MAAA;IACA,MAAA;IACA,KAAA;EAAA,IACE,OAAA;IACF,OAAA,EAAS,KAAA;MACP,GAAA;MACA,KAAA;MACA,UAAA;MACA,UAAA;IAAA;IAEF,aAAA;IACA,MAAA;EAAA;EANE;;;;EAiDE,WAAA,CAAY,KAAA,WAAgB,OAAA;IAAU,GAAA;IAAa,KAAA;EAAA;EAAvB;;;;EAY5B,eAAA,CAAgB,GAAA,WAAc,OAAA;IAClC,KAAA;IACA,IAAA;IACA,UAAA;IACA,UAAA;EAAA;AAAA"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { KeyValueStore, KeyValueStoreListWithValuesResult } from "@aigne/afs-kv";
|
|
2
|
+
|
|
3
|
+
//#region src/d1-resolve-store.d.ts
|
|
4
|
+
declare class D1ResolveStore implements KeyValueStore {
|
|
5
|
+
private db;
|
|
6
|
+
private readonly conn;
|
|
7
|
+
constructor(db: D1Database, opts?: {
|
|
8
|
+
useReplica?: boolean;
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* Create table with full schema including Phase R columns.
|
|
12
|
+
* Production: schema created by `wrangler d1 migrations apply`.
|
|
13
|
+
* Tests: call this in beforeEach with in-memory DB.
|
|
14
|
+
*/
|
|
15
|
+
ensureTable(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Add Phase R columns to an existing resolve_entries table that was created before migration 0006.
|
|
18
|
+
* Safe to call on an already-migrated table (checks before ALTER TABLE).
|
|
19
|
+
* Also creates the indexes if they don't exist.
|
|
20
|
+
*/
|
|
21
|
+
ensureColumns(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Backfill owner/kind/updated_at for rows that were inserted before Phase R.
|
|
24
|
+
* Idempotent: only updates rows where at least one index column is NULL.
|
|
25
|
+
* Call once on startup after ensureColumns().
|
|
26
|
+
*/
|
|
27
|
+
backfill(): Promise<void>;
|
|
28
|
+
get(key: string): Promise<string | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Batch get (issue #808): one `WHERE key IN (...)` round trip for several keys
|
|
31
|
+
* — collapses the serve path's sequential `resolve/blocklet/<host>` +
|
|
32
|
+
* `resolve/domain/<host>` lookups. Missing keys are simply absent from the map.
|
|
33
|
+
* Deduped so a repeated key doesn't widen the IN list.
|
|
34
|
+
*/
|
|
35
|
+
getMany(keys: string[]): Promise<Map<string, string | null>>;
|
|
36
|
+
put(key: string, value: string | ArrayBuffer): Promise<void>;
|
|
37
|
+
delete(key: string): Promise<void>;
|
|
38
|
+
list(options?: {
|
|
39
|
+
prefix?: string;
|
|
40
|
+
cursor?: string;
|
|
41
|
+
limit?: number;
|
|
42
|
+
}): Promise<{
|
|
43
|
+
keys: {
|
|
44
|
+
name: string;
|
|
45
|
+
}[];
|
|
46
|
+
list_complete: boolean;
|
|
47
|
+
cursor: string | undefined;
|
|
48
|
+
}>;
|
|
49
|
+
listWithValues(options?: {
|
|
50
|
+
prefix?: string;
|
|
51
|
+
cursor?: string;
|
|
52
|
+
limit?: number;
|
|
53
|
+
}): Promise<KeyValueStoreListWithValuesResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Like listWithValues but also returns created_at and updated_at columns.
|
|
56
|
+
* Used by DIDSpaceResolver to surface timestamps without a separate query.
|
|
57
|
+
*/
|
|
58
|
+
listWithTimestamps(options?: {
|
|
59
|
+
prefix?: string;
|
|
60
|
+
cursor?: string;
|
|
61
|
+
limit?: number;
|
|
62
|
+
}): Promise<{
|
|
63
|
+
entries: Array<{
|
|
64
|
+
key: string;
|
|
65
|
+
value: string;
|
|
66
|
+
created_at: number | null;
|
|
67
|
+
updated_at: number | null;
|
|
68
|
+
}>;
|
|
69
|
+
list_complete: boolean;
|
|
70
|
+
cursor?: string;
|
|
71
|
+
}>;
|
|
72
|
+
/**
|
|
73
|
+
* List all entries for a given owner. Uses idx_resolve_owner index.
|
|
74
|
+
* Returns key + value pairs for all rows where owner matches.
|
|
75
|
+
*/
|
|
76
|
+
listByOwner(owner: string): Promise<{
|
|
77
|
+
key: string;
|
|
78
|
+
value: string;
|
|
79
|
+
}[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Read the index columns (owner, kind, updated_at) for a given key.
|
|
82
|
+
* Primarily used for testing and debugging — verifies Phase R columns are populated.
|
|
83
|
+
*/
|
|
84
|
+
getIndexColumns(key: string): Promise<{
|
|
85
|
+
owner: string | null;
|
|
86
|
+
kind: string | null;
|
|
87
|
+
updated_at: number | null;
|
|
88
|
+
created_at: number | null;
|
|
89
|
+
} | null>;
|
|
90
|
+
}
|
|
91
|
+
//#endregion
|
|
92
|
+
export { D1ResolveStore };
|
|
93
|
+
//# sourceMappingURL=d1-resolve-store.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"d1-resolve-store.d.mts","names":[],"sources":["../src/d1-resolve-store.ts"],"mappings":";;;cA4Ba,cAAA,YAA0B,aAAA;EAAA,QAI3B,EAAA;EAAA,iBAHO,IAAA;cAGP,EAAA,EAAI,UAAA,EACZ,IAAA;IAAS,UAAA;EAAA;EAmKP;;;;;EAtJE,WAAA,CAAA,GAAe,OAAA;EAlB6B;;;;;EA+B5C,aAAA,CAAA,GAAiB,OAAA;EA3BT;;;;;EAiER,QAAA,CAAA,GAAY,OAAA;EAmBZ,GAAA,CAAI,GAAA,WAAc,OAAA;EAzDD;;;;;;EAuEjB,OAAA,CAAQ,IAAA,aAAiB,OAAA,CAAQ,GAAA;EAajC,GAAA,CAAI,GAAA,UAAa,KAAA,WAAgB,WAAA,GAAc,OAAA;EAa/C,MAAA,CAAO,GAAA,WAAc,OAAA;EAIrB,IAAA,CAAK,OAAA;IAAY,MAAA;IAAiB,MAAA;IAAiB,KAAA;EAAA,IAAgB,OAAA;;;;;;;EAgCnE,cAAA,CAAe,OAAA;IACnB,MAAA;IACA,MAAA;IACA,KAAA;EAAA,IACE,OAAA,CAAQ,iCAAA;;;;;EAoCN,kBAAA,CAAmB,OAAA;IACvB,MAAA;IACA,MAAA;IACA,KAAA;EAAA,IACE,OAAA;IACF,OAAA,EAAS,KAAA;MACP,GAAA;MACA,KAAA;MACA,UAAA;MACA,UAAA;IAAA;IAEF,aAAA;IACA,MAAA;EAAA;EANE;;;;EAiDE,WAAA,CAAY,KAAA,WAAgB,OAAA;IAAU,GAAA;IAAa,KAAA;EAAA;EAAvB;;;;EAY5B,eAAA,CAAgB,GAAA,WAAc,OAAA;IAClC,KAAA;IACA,IAAA;IACA,UAAA;IACA,UAAA;EAAA;AAAA"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { RESOLVE_ENTRIES_INDEX_SQL, RESOLVE_ENTRIES_TABLE_SQL } from "./d1-schema.mjs";
|
|
2
|
+
import { prefixRange } from "./prefix-range.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/d1-resolve-store.ts
|
|
5
|
+
/** Extract owner and kind from a JSON value string. Returns nulls on parse failure or missing fields. */
|
|
6
|
+
function extractIndexFields(value) {
|
|
7
|
+
try {
|
|
8
|
+
const parsed = JSON.parse(value);
|
|
9
|
+
return {
|
|
10
|
+
owner: typeof parsed.owner === "string" ? parsed.owner : null,
|
|
11
|
+
kind: typeof parsed.type === "string" ? parsed.type : null
|
|
12
|
+
};
|
|
13
|
+
} catch {
|
|
14
|
+
return {
|
|
15
|
+
owner: null,
|
|
16
|
+
kind: null
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
var D1ResolveStore = class {
|
|
21
|
+
conn;
|
|
22
|
+
constructor(db, opts) {
|
|
23
|
+
this.db = db;
|
|
24
|
+
this.conn = opts?.useReplica && typeof db.withSession === "function" ? db.withSession("first-unconstrained") : db;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create table with full schema including Phase R columns.
|
|
28
|
+
* Production: schema created by `wrangler d1 migrations apply`.
|
|
29
|
+
* Tests: call this in beforeEach with in-memory DB.
|
|
30
|
+
*/
|
|
31
|
+
async ensureTable() {
|
|
32
|
+
await this.db.prepare(RESOLVE_ENTRIES_TABLE_SQL).run();
|
|
33
|
+
for (const sql of RESOLVE_ENTRIES_INDEX_SQL) await this.db.prepare(sql).run();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Add Phase R columns to an existing resolve_entries table that was created before migration 0006.
|
|
37
|
+
* Safe to call on an already-migrated table (checks before ALTER TABLE).
|
|
38
|
+
* Also creates the indexes if they don't exist.
|
|
39
|
+
*/
|
|
40
|
+
async ensureColumns() {
|
|
41
|
+
const { results } = await this.db.prepare("SELECT name FROM pragma_table_info('ds_resolve_entries')").all();
|
|
42
|
+
const existing = new Set(results.map((r) => r.name));
|
|
43
|
+
if (!existing.has("owner")) await this.db.prepare("ALTER TABLE ds_resolve_entries ADD COLUMN owner TEXT").run();
|
|
44
|
+
if (!existing.has("kind")) await this.db.prepare("ALTER TABLE ds_resolve_entries ADD COLUMN kind TEXT").run();
|
|
45
|
+
if (!existing.has("updated_at")) await this.db.prepare("ALTER TABLE ds_resolve_entries ADD COLUMN updated_at INTEGER").run();
|
|
46
|
+
if (!existing.has("created_at")) await this.db.prepare("ALTER TABLE ds_resolve_entries ADD COLUMN created_at INTEGER").run();
|
|
47
|
+
await this.db.prepare("CREATE INDEX IF NOT EXISTS idx_resolve_owner ON ds_resolve_entries(owner)").run();
|
|
48
|
+
await this.db.prepare("CREATE INDEX IF NOT EXISTS idx_resolve_kind ON ds_resolve_entries(kind)").run();
|
|
49
|
+
await this.db.prepare("CREATE INDEX IF NOT EXISTS idx_resolve_updated ON ds_resolve_entries(updated_at)").run();
|
|
50
|
+
await this.db.prepare("CREATE INDEX IF NOT EXISTS idx_resolve_created ON ds_resolve_entries(created_at)").run();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Backfill owner/kind/updated_at for rows that were inserted before Phase R.
|
|
54
|
+
* Idempotent: only updates rows where at least one index column is NULL.
|
|
55
|
+
* Call once on startup after ensureColumns().
|
|
56
|
+
*/
|
|
57
|
+
async backfill() {
|
|
58
|
+
const { results } = await this.db.prepare("SELECT key, value FROM ds_resolve_entries WHERE owner IS NULL OR kind IS NULL OR updated_at IS NULL OR created_at IS NULL").all();
|
|
59
|
+
for (const row of results) {
|
|
60
|
+
const { owner, kind } = extractIndexFields(row.value);
|
|
61
|
+
const now = Date.now();
|
|
62
|
+
await this.db.prepare("UPDATE ds_resolve_entries SET owner = ?, kind = ?, updated_at = COALESCE(updated_at, ?), created_at = COALESCE(created_at, updated_at, ?) WHERE key = ? AND (owner IS NULL OR kind IS NULL OR updated_at IS NULL OR created_at IS NULL)").bind(owner, kind, now, now, row.key).run();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async get(key) {
|
|
66
|
+
return (await this.conn.prepare("SELECT value FROM ds_resolve_entries WHERE key = ?").bind(key).first())?.value ?? null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Batch get (issue #808): one `WHERE key IN (...)` round trip for several keys
|
|
70
|
+
* — collapses the serve path's sequential `resolve/blocklet/<host>` +
|
|
71
|
+
* `resolve/domain/<host>` lookups. Missing keys are simply absent from the map.
|
|
72
|
+
* Deduped so a repeated key doesn't widen the IN list.
|
|
73
|
+
*/
|
|
74
|
+
async getMany(keys) {
|
|
75
|
+
const out = /* @__PURE__ */ new Map();
|
|
76
|
+
const unique = [...new Set(keys)];
|
|
77
|
+
if (unique.length === 0) return out;
|
|
78
|
+
const placeholders = unique.map(() => "?").join(",");
|
|
79
|
+
const { results } = await this.conn.prepare(`SELECT key, value FROM ds_resolve_entries WHERE key IN (${placeholders})`).bind(...unique).all();
|
|
80
|
+
for (const row of results ?? []) out.set(row.key, row.value);
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
async put(key, value) {
|
|
84
|
+
const strValue = typeof value === "string" ? value : new TextDecoder().decode(value);
|
|
85
|
+
const { owner, kind } = extractIndexFields(strValue);
|
|
86
|
+
const now = Date.now();
|
|
87
|
+
await this.conn.prepare(`INSERT INTO ds_resolve_entries (key, value, owner, kind, updated_at, created_at) VALUES (?, ?, ?, ?, ?, ?)
|
|
88
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value, owner = excluded.owner, kind = excluded.kind, updated_at = excluded.updated_at`).bind(key, strValue, owner, kind, now, now).run();
|
|
89
|
+
}
|
|
90
|
+
async delete(key) {
|
|
91
|
+
await this.conn.prepare("DELETE FROM ds_resolve_entries WHERE key = ?").bind(key).run();
|
|
92
|
+
}
|
|
93
|
+
async list(options) {
|
|
94
|
+
const prefix = options?.prefix ?? "";
|
|
95
|
+
const limit = options?.limit ?? 1e3;
|
|
96
|
+
const cursor = options?.cursor;
|
|
97
|
+
const [lo, hi] = prefixRange(prefix);
|
|
98
|
+
const params = [lo, hi];
|
|
99
|
+
let sql = "SELECT key FROM ds_resolve_entries WHERE key >= ? AND key < ?";
|
|
100
|
+
if (cursor) {
|
|
101
|
+
sql += " AND key > ?";
|
|
102
|
+
params.push(cursor);
|
|
103
|
+
}
|
|
104
|
+
sql += " ORDER BY key LIMIT ?";
|
|
105
|
+
params.push(limit + 1);
|
|
106
|
+
const { results } = await this.conn.prepare(sql).bind(...params).all();
|
|
107
|
+
const hasMore = results.length > limit;
|
|
108
|
+
const selected = hasMore ? results.slice(0, limit) : results;
|
|
109
|
+
return {
|
|
110
|
+
keys: selected.map((r) => ({ name: r.key })),
|
|
111
|
+
list_complete: !hasMore,
|
|
112
|
+
cursor: hasMore && selected.length > 0 ? selected[selected.length - 1].key : void 0
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
async listWithValues(options) {
|
|
116
|
+
const prefix = options?.prefix ?? "";
|
|
117
|
+
const limit = options?.limit && options.limit > 0 ? options.limit : 1e3;
|
|
118
|
+
const cursor = options?.cursor;
|
|
119
|
+
const [lo, hi] = prefixRange(prefix);
|
|
120
|
+
const params = [lo, hi];
|
|
121
|
+
let sql = "SELECT key, value FROM ds_resolve_entries WHERE key >= ? AND key < ?";
|
|
122
|
+
if (cursor) {
|
|
123
|
+
sql += " AND key > ?";
|
|
124
|
+
params.push(cursor);
|
|
125
|
+
}
|
|
126
|
+
sql += " ORDER BY key LIMIT ?";
|
|
127
|
+
params.push(limit + 1);
|
|
128
|
+
const { results } = await this.conn.prepare(sql).bind(...params).all();
|
|
129
|
+
const hasMore = results.length > limit;
|
|
130
|
+
const selected = hasMore ? results.slice(0, limit) : results;
|
|
131
|
+
return {
|
|
132
|
+
entries: selected.map((r) => ({
|
|
133
|
+
key: r.key,
|
|
134
|
+
value: r.value
|
|
135
|
+
})),
|
|
136
|
+
list_complete: !hasMore,
|
|
137
|
+
cursor: hasMore && selected.length > 0 ? selected[selected.length - 1].key : void 0
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Like listWithValues but also returns created_at and updated_at columns.
|
|
142
|
+
* Used by DIDSpaceResolver to surface timestamps without a separate query.
|
|
143
|
+
*/
|
|
144
|
+
async listWithTimestamps(options) {
|
|
145
|
+
const prefix = options?.prefix ?? "";
|
|
146
|
+
const limit = options?.limit && options.limit > 0 ? options.limit : 1e3;
|
|
147
|
+
const cursor = options?.cursor;
|
|
148
|
+
const [lo, hi] = prefixRange(prefix);
|
|
149
|
+
const params = [lo, hi];
|
|
150
|
+
let sql = "SELECT key, value, created_at, updated_at FROM ds_resolve_entries WHERE key >= ? AND key < ?";
|
|
151
|
+
if (cursor) {
|
|
152
|
+
sql += " AND key > ?";
|
|
153
|
+
params.push(cursor);
|
|
154
|
+
}
|
|
155
|
+
sql += " ORDER BY key LIMIT ?";
|
|
156
|
+
params.push(limit + 1);
|
|
157
|
+
const { results } = await this.conn.prepare(sql).bind(...params).all();
|
|
158
|
+
const hasMore = results.length > limit;
|
|
159
|
+
const selected = hasMore ? results.slice(0, limit) : results;
|
|
160
|
+
return {
|
|
161
|
+
entries: selected.map((r) => ({
|
|
162
|
+
key: r.key,
|
|
163
|
+
value: r.value,
|
|
164
|
+
created_at: r.created_at,
|
|
165
|
+
updated_at: r.updated_at
|
|
166
|
+
})),
|
|
167
|
+
list_complete: !hasMore,
|
|
168
|
+
cursor: hasMore && selected.length > 0 ? selected[selected.length - 1].key : void 0
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* List all entries for a given owner. Uses idx_resolve_owner index.
|
|
173
|
+
* Returns key + value pairs for all rows where owner matches.
|
|
174
|
+
*/
|
|
175
|
+
async listByOwner(owner) {
|
|
176
|
+
const { results } = await this.conn.prepare("SELECT key, value FROM ds_resolve_entries WHERE owner = ?").bind(owner).all();
|
|
177
|
+
return results;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Read the index columns (owner, kind, updated_at) for a given key.
|
|
181
|
+
* Primarily used for testing and debugging — verifies Phase R columns are populated.
|
|
182
|
+
*/
|
|
183
|
+
async getIndexColumns(key) {
|
|
184
|
+
return this.conn.prepare("SELECT owner, kind, updated_at, created_at FROM ds_resolve_entries WHERE key = ?").bind(key).first();
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
//#endregion
|
|
189
|
+
export { D1ResolveStore };
|
|
190
|
+
//# sourceMappingURL=d1-resolve-store.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"d1-resolve-store.mjs","names":[],"sources":["../src/d1-resolve-store.ts"],"sourcesContent":["/**\n * D1ResolveStore — D1 implementation of KeyValueStore for DIDSpaceResolver.\n *\n * Flat key-value table: resolve_entries(key TEXT PK, value TEXT, owner TEXT, kind TEXT, updated_at INTEGER, created_at INTEGER).\n * When useReplica=true, all queries go through a D1 Session which routes\n * reads to the nearest replica and writes to the primary automatically.\n *\n * Phase R enhancement: owner/kind/updated_at index columns are maintained on every put().\n * Phase 7 enhancement: created_at is set once at insert time and never overwritten.\n * Call ensureColumns() + backfill() on startup to migrate existing rows.\n */\n\nimport type { KeyValueStore, KeyValueStoreListWithValuesResult } from \"@aigne/afs-kv\";\nimport { RESOLVE_ENTRIES_INDEX_SQL, RESOLVE_ENTRIES_TABLE_SQL } from \"./d1-schema.js\";\nimport { prefixRange } from \"./prefix-range.js\";\n\n/** Extract owner and kind from a JSON value string. Returns nulls on parse failure or missing fields. */\nfunction extractIndexFields(value: string): { owner: string | null; kind: string | null } {\n try {\n const parsed = JSON.parse(value);\n const owner = typeof parsed.owner === \"string\" ? parsed.owner : null;\n const kind = typeof parsed.type === \"string\" ? parsed.type : null;\n return { owner, kind };\n } catch {\n return { owner: null, kind: null };\n }\n}\n\nexport class D1ResolveStore implements KeyValueStore {\n private readonly conn: D1Database | D1DatabaseSession;\n\n constructor(\n private db: D1Database,\n opts?: { useReplica?: boolean },\n ) {\n this.conn =\n opts?.useReplica && typeof db.withSession === \"function\"\n ? db.withSession(\"first-unconstrained\")\n : db;\n }\n\n /**\n * Create table with full schema including Phase R columns.\n * Production: schema created by `wrangler d1 migrations apply`.\n * Tests: call this in beforeEach with in-memory DB.\n */\n async ensureTable(): Promise<void> {\n await this.db.prepare(RESOLVE_ENTRIES_TABLE_SQL).run();\n // Ensure indexes exist (idempotent)\n for (const sql of RESOLVE_ENTRIES_INDEX_SQL) {\n await this.db.prepare(sql).run();\n }\n }\n\n /**\n * Add Phase R columns to an existing resolve_entries table that was created before migration 0006.\n * Safe to call on an already-migrated table (checks before ALTER TABLE).\n * Also creates the indexes if they don't exist.\n */\n async ensureColumns(): Promise<void> {\n const { results } = await this.db\n .prepare(\"SELECT name FROM pragma_table_info('ds_resolve_entries')\")\n .all<{ name: string }>();\n const existing = new Set(results.map((r) => r.name));\n\n if (!existing.has(\"owner\")) {\n await this.db.prepare(\"ALTER TABLE ds_resolve_entries ADD COLUMN owner TEXT\").run();\n }\n if (!existing.has(\"kind\")) {\n await this.db.prepare(\"ALTER TABLE ds_resolve_entries ADD COLUMN kind TEXT\").run();\n }\n if (!existing.has(\"updated_at\")) {\n await this.db.prepare(\"ALTER TABLE ds_resolve_entries ADD COLUMN updated_at INTEGER\").run();\n }\n if (!existing.has(\"created_at\")) {\n await this.db.prepare(\"ALTER TABLE ds_resolve_entries ADD COLUMN created_at INTEGER\").run();\n }\n\n await this.db\n .prepare(\"CREATE INDEX IF NOT EXISTS idx_resolve_owner ON ds_resolve_entries(owner)\")\n .run();\n await this.db\n .prepare(\"CREATE INDEX IF NOT EXISTS idx_resolve_kind ON ds_resolve_entries(kind)\")\n .run();\n await this.db\n .prepare(\"CREATE INDEX IF NOT EXISTS idx_resolve_updated ON ds_resolve_entries(updated_at)\")\n .run();\n await this.db\n .prepare(\"CREATE INDEX IF NOT EXISTS idx_resolve_created ON ds_resolve_entries(created_at)\")\n .run();\n }\n\n /**\n * Backfill owner/kind/updated_at for rows that were inserted before Phase R.\n * Idempotent: only updates rows where at least one index column is NULL.\n * Call once on startup after ensureColumns().\n */\n async backfill(): Promise<void> {\n const { results } = await this.db\n .prepare(\n \"SELECT key, value FROM ds_resolve_entries WHERE owner IS NULL OR kind IS NULL OR updated_at IS NULL OR created_at IS NULL\",\n )\n .all<{ key: string; value: string }>();\n\n for (const row of results) {\n const { owner, kind } = extractIndexFields(row.value);\n const now = Date.now();\n await this.db\n .prepare(\n \"UPDATE ds_resolve_entries SET owner = ?, kind = ?, updated_at = COALESCE(updated_at, ?), created_at = COALESCE(created_at, updated_at, ?) WHERE key = ? AND (owner IS NULL OR kind IS NULL OR updated_at IS NULL OR created_at IS NULL)\",\n )\n .bind(owner, kind, now, now, row.key)\n .run();\n }\n }\n\n async get(key: string): Promise<string | null> {\n const row = await this.conn\n .prepare(\"SELECT value FROM ds_resolve_entries WHERE key = ?\")\n .bind(key)\n .first<{ value: string }>();\n return row?.value ?? null;\n }\n\n /**\n * Batch get (issue #808): one `WHERE key IN (...)` round trip for several keys\n * — collapses the serve path's sequential `resolve/blocklet/<host>` +\n * `resolve/domain/<host>` lookups. Missing keys are simply absent from the map.\n * Deduped so a repeated key doesn't widen the IN list.\n */\n async getMany(keys: string[]): Promise<Map<string, string | null>> {\n const out = new Map<string, string | null>();\n const unique = [...new Set(keys)];\n if (unique.length === 0) return out;\n const placeholders = unique.map(() => \"?\").join(\",\");\n const { results } = await this.conn\n .prepare(`SELECT key, value FROM ds_resolve_entries WHERE key IN (${placeholders})`)\n .bind(...unique)\n .all<{ key: string; value: string }>();\n for (const row of results ?? []) out.set(row.key, row.value);\n return out;\n }\n\n async put(key: string, value: string | ArrayBuffer): Promise<void> {\n const strValue = typeof value === \"string\" ? value : new TextDecoder().decode(value);\n const { owner, kind } = extractIndexFields(strValue);\n const now = Date.now();\n await this.conn\n .prepare(\n `INSERT INTO ds_resolve_entries (key, value, owner, kind, updated_at, created_at) VALUES (?, ?, ?, ?, ?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value, owner = excluded.owner, kind = excluded.kind, updated_at = excluded.updated_at`,\n )\n .bind(key, strValue, owner, kind, now, now)\n .run();\n }\n\n async delete(key: string): Promise<void> {\n await this.conn.prepare(\"DELETE FROM ds_resolve_entries WHERE key = ?\").bind(key).run();\n }\n\n async list(options?: { prefix?: string; cursor?: string; limit?: number }) {\n const prefix = options?.prefix ?? \"\";\n const limit = options?.limit ?? 1000;\n const cursor = options?.cursor;\n\n const [lo, hi] = prefixRange(prefix);\n const params: unknown[] = [lo, hi];\n\n let sql = \"SELECT key FROM ds_resolve_entries WHERE key >= ? AND key < ?\";\n\n if (cursor) {\n sql += \" AND key > ?\";\n params.push(cursor);\n }\n\n sql += \" ORDER BY key LIMIT ?\";\n params.push(limit + 1);\n\n const { results } = await this.conn\n .prepare(sql)\n .bind(...params)\n .all<{ key: string }>();\n const hasMore = results.length > limit;\n const selected = hasMore ? results.slice(0, limit) : results;\n\n return {\n keys: selected.map((r) => ({ name: r.key })),\n list_complete: !hasMore,\n cursor: hasMore && selected.length > 0 ? selected[selected.length - 1]!.key : undefined,\n };\n }\n\n async listWithValues(options?: {\n prefix?: string;\n cursor?: string;\n limit?: number;\n }): Promise<KeyValueStoreListWithValuesResult> {\n const prefix = options?.prefix ?? \"\";\n const limit = options?.limit && options.limit > 0 ? options.limit : 1000;\n const cursor = options?.cursor;\n\n const [lo, hi] = prefixRange(prefix);\n const params: unknown[] = [lo, hi];\n\n let sql = \"SELECT key, value FROM ds_resolve_entries WHERE key >= ? AND key < ?\";\n\n if (cursor) {\n sql += \" AND key > ?\";\n params.push(cursor);\n }\n\n sql += \" ORDER BY key LIMIT ?\";\n params.push(limit + 1);\n\n const { results } = await this.conn\n .prepare(sql)\n .bind(...params)\n .all<{ key: string; value: string }>();\n const hasMore = results.length > limit;\n const selected = hasMore ? results.slice(0, limit) : results;\n\n return {\n entries: selected.map((r) => ({ key: r.key, value: r.value })),\n list_complete: !hasMore,\n cursor: hasMore && selected.length > 0 ? selected[selected.length - 1]!.key : undefined,\n };\n }\n\n /**\n * Like listWithValues but also returns created_at and updated_at columns.\n * Used by DIDSpaceResolver to surface timestamps without a separate query.\n */\n async listWithTimestamps(options?: {\n prefix?: string;\n cursor?: string;\n limit?: number;\n }): Promise<{\n entries: Array<{\n key: string;\n value: string;\n created_at: number | null;\n updated_at: number | null;\n }>;\n list_complete: boolean;\n cursor?: string;\n }> {\n const prefix = options?.prefix ?? \"\";\n const limit = options?.limit && options.limit > 0 ? options.limit : 1000;\n const cursor = options?.cursor;\n\n const [lo, hi] = prefixRange(prefix);\n const params: unknown[] = [lo, hi];\n\n let sql =\n \"SELECT key, value, created_at, updated_at FROM ds_resolve_entries WHERE key >= ? AND key < ?\";\n\n if (cursor) {\n sql += \" AND key > ?\";\n params.push(cursor);\n }\n\n sql += \" ORDER BY key LIMIT ?\";\n params.push(limit + 1);\n\n const { results } = await this.conn\n .prepare(sql)\n .bind(...params)\n .all<{ key: string; value: string; created_at: number | null; updated_at: number | null }>();\n const hasMore = results.length > limit;\n const selected = hasMore ? results.slice(0, limit) : results;\n\n return {\n entries: selected.map((r) => ({\n key: r.key,\n value: r.value,\n created_at: r.created_at,\n updated_at: r.updated_at,\n })),\n list_complete: !hasMore,\n cursor: hasMore && selected.length > 0 ? selected[selected.length - 1]!.key : undefined,\n };\n }\n\n /**\n * List all entries for a given owner. Uses idx_resolve_owner index.\n * Returns key + value pairs for all rows where owner matches.\n */\n async listByOwner(owner: string): Promise<{ key: string; value: string }[]> {\n const { results } = await this.conn\n .prepare(\"SELECT key, value FROM ds_resolve_entries WHERE owner = ?\")\n .bind(owner)\n .all<{ key: string; value: string }>();\n return results;\n }\n\n /**\n * Read the index columns (owner, kind, updated_at) for a given key.\n * Primarily used for testing and debugging — verifies Phase R columns are populated.\n */\n async getIndexColumns(key: string): Promise<{\n owner: string | null;\n kind: string | null;\n updated_at: number | null;\n created_at: number | null;\n } | null> {\n return this.conn\n .prepare(\"SELECT owner, kind, updated_at, created_at FROM ds_resolve_entries WHERE key = ?\")\n .bind(key)\n .first<{\n owner: string | null;\n kind: string | null;\n updated_at: number | null;\n created_at: number | null;\n }>();\n }\n}\n"],"mappings":"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"}
|