@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
package/dist/run-gc.cjs
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const require_object_key = require('./object-key.cjs');
|
|
2
|
+
|
|
3
|
+
//#region src/run-gc.ts
|
|
4
|
+
/** 7 days — the sole protection for behind/offline devices (design §0.2, §7). */
|
|
5
|
+
const DEFAULT_GC_GRACE_MS = 10080 * 60 * 1e3;
|
|
6
|
+
const DEFAULT_GC_LIMIT = 500;
|
|
7
|
+
async function runGc(o) {
|
|
8
|
+
const limit = o.limit ?? DEFAULT_GC_LIMIT;
|
|
9
|
+
const graceMs = o.graceMs ?? DEFAULT_GC_GRACE_MS;
|
|
10
|
+
const nowMs = Date.now();
|
|
11
|
+
const candidates = await o.queue.fetchCandidates(limit, graceMs);
|
|
12
|
+
const stats = {
|
|
13
|
+
candidates: candidates.length,
|
|
14
|
+
deleted: [],
|
|
15
|
+
skipped: [],
|
|
16
|
+
errors: []
|
|
17
|
+
};
|
|
18
|
+
for (const { cid } of candidates) {
|
|
19
|
+
try {
|
|
20
|
+
require_object_key.assertValidCid(cid);
|
|
21
|
+
} catch (err) {
|
|
22
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
23
|
+
stats.errors.push({
|
|
24
|
+
cid,
|
|
25
|
+
error: msg
|
|
26
|
+
});
|
|
27
|
+
o.log?.(`[gc] skip invalid cid: ${msg}`);
|
|
28
|
+
try {
|
|
29
|
+
await o.queue.remove(cid);
|
|
30
|
+
} catch {}
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
if (await o.referencedAnywhere(cid, nowMs)) {
|
|
35
|
+
await o.queue.remove(cid);
|
|
36
|
+
stats.skipped.push(cid);
|
|
37
|
+
} else {
|
|
38
|
+
await o.objectStore.delete(require_object_key.objectKeyForCid(cid));
|
|
39
|
+
await o.queue.remove(cid);
|
|
40
|
+
stats.deleted.push(cid);
|
|
41
|
+
}
|
|
42
|
+
} catch (err) {
|
|
43
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
44
|
+
stats.errors.push({
|
|
45
|
+
cid,
|
|
46
|
+
error: msg
|
|
47
|
+
});
|
|
48
|
+
o.log?.(`[gc] error on cid ${cid}: ${msg}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
o.log?.(JSON.stringify(stats));
|
|
52
|
+
return stats;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
exports.DEFAULT_GC_GRACE_MS = DEFAULT_GC_GRACE_MS;
|
|
57
|
+
exports.runGc = runGc;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ObjectStore } from "./platform/r2/dist/types.cjs";
|
|
2
|
+
import { GcQueue } from "./gc-queue.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/run-gc.d.ts
|
|
5
|
+
/** 7 days — the sole protection for behind/offline devices (design §0.2, §7). */
|
|
6
|
+
declare const DEFAULT_GC_GRACE_MS: number;
|
|
7
|
+
interface RunGcOptions {
|
|
8
|
+
queue: GcQueue;
|
|
9
|
+
/**
|
|
10
|
+
* scope-blind liveness — entries ∪ non-expired prepared upload sessions
|
|
11
|
+
* (reference-check.ts). `nowMs` is the sweep-start time, passed so the whole
|
|
12
|
+
* sweep judges prepared-session expiry against ONE consistent clock (design
|
|
13
|
+
* §9). Ad-hoc callers may omit it (the impls default to Date.now()).
|
|
14
|
+
*/
|
|
15
|
+
referencedAnywhere(cid: string, nowMs: number): Promise<boolean>;
|
|
16
|
+
objectStore: ObjectStore;
|
|
17
|
+
/** max candidates per sweep (default 500). */
|
|
18
|
+
limit?: number;
|
|
19
|
+
/** grace window (default 7d). `runGc` owns the canonical value and passes it
|
|
20
|
+
* explicitly to `fetchCandidates`, so a queue impl's own default is never relied upon. */
|
|
21
|
+
graceMs?: number;
|
|
22
|
+
log?: (line: string) => void;
|
|
23
|
+
}
|
|
24
|
+
interface GcStats {
|
|
25
|
+
/** number of candidates fetched this sweep. */
|
|
26
|
+
candidates: number;
|
|
27
|
+
/** cids whose object was deleted. */
|
|
28
|
+
deleted: string[];
|
|
29
|
+
/** cids kept because still referenced (object NOT deleted). */
|
|
30
|
+
skipped: string[];
|
|
31
|
+
/** cids that errored (invalid cid, or delete/remove threw). */
|
|
32
|
+
errors: Array<{
|
|
33
|
+
cid: string;
|
|
34
|
+
error: string;
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
declare function runGc(o: RunGcOptions): Promise<GcStats>;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { DEFAULT_GC_GRACE_MS, GcStats, RunGcOptions, runGc };
|
|
40
|
+
//# sourceMappingURL=run-gc.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-gc.d.cts","names":[],"sources":["../src/run-gc.ts"],"mappings":";;;;;cA+Ba,mBAAA;AAAA,UAGI,YAAA;EACf,KAAA,EAAO,OAAA;EAiBQ;;;;;;EAVf,kBAAA,CAAmB,GAAA,UAAa,KAAA,WAAgB,OAAA;EAChD,WAAA,EAAa,WAAA;EAiBL;EAfR,KAAA;EAe6B;;EAZ7B,OAAA;EACA,GAAA,IAAO,IAAA;AAAA;AAAA,UAGQ,OAAA;EAWc;EAT7B,UAAA;EAS4C;EAP5C,OAAA;EAOmD;EALnD,OAAA;EAK0B;EAH1B,MAAA,EAAQ,KAAA;IAAQ,GAAA;IAAa,KAAA;EAAA;AAAA;AAAA,iBAGT,KAAA,CAAM,CAAA,EAAG,YAAA,GAAe,OAAA,CAAQ,OAAA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ObjectStore } from "./providers/platform/r2/dist/types.mjs";
|
|
2
|
+
import "./providers/platform/r2/dist/index.mjs";
|
|
3
|
+
import { GcQueue } from "./gc-queue.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/run-gc.d.ts
|
|
6
|
+
/** 7 days — the sole protection for behind/offline devices (design §0.2, §7). */
|
|
7
|
+
declare const DEFAULT_GC_GRACE_MS: number;
|
|
8
|
+
interface RunGcOptions {
|
|
9
|
+
queue: GcQueue;
|
|
10
|
+
/**
|
|
11
|
+
* scope-blind liveness — entries ∪ non-expired prepared upload sessions
|
|
12
|
+
* (reference-check.ts). `nowMs` is the sweep-start time, passed so the whole
|
|
13
|
+
* sweep judges prepared-session expiry against ONE consistent clock (design
|
|
14
|
+
* §9). Ad-hoc callers may omit it (the impls default to Date.now()).
|
|
15
|
+
*/
|
|
16
|
+
referencedAnywhere(cid: string, nowMs: number): Promise<boolean>;
|
|
17
|
+
objectStore: ObjectStore;
|
|
18
|
+
/** max candidates per sweep (default 500). */
|
|
19
|
+
limit?: number;
|
|
20
|
+
/** grace window (default 7d). `runGc` owns the canonical value and passes it
|
|
21
|
+
* explicitly to `fetchCandidates`, so a queue impl's own default is never relied upon. */
|
|
22
|
+
graceMs?: number;
|
|
23
|
+
log?: (line: string) => void;
|
|
24
|
+
}
|
|
25
|
+
interface GcStats {
|
|
26
|
+
/** number of candidates fetched this sweep. */
|
|
27
|
+
candidates: number;
|
|
28
|
+
/** cids whose object was deleted. */
|
|
29
|
+
deleted: string[];
|
|
30
|
+
/** cids kept because still referenced (object NOT deleted). */
|
|
31
|
+
skipped: string[];
|
|
32
|
+
/** cids that errored (invalid cid, or delete/remove threw). */
|
|
33
|
+
errors: Array<{
|
|
34
|
+
cid: string;
|
|
35
|
+
error: string;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
declare function runGc(o: RunGcOptions): Promise<GcStats>;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { DEFAULT_GC_GRACE_MS, GcStats, RunGcOptions, runGc };
|
|
41
|
+
//# sourceMappingURL=run-gc.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-gc.d.mts","names":[],"sources":["../src/run-gc.ts"],"mappings":";;;;;;cA+Ba,mBAAA;AAAA,UAGI,YAAA;EACf,KAAA,EAAO,OAAA;EAcY;AAGrB;;;;;EAVE,kBAAA,CAAmB,GAAA,UAAa,KAAA,WAAgB,OAAA;EAChD,WAAA,EAAa,WAAA;EAiBb;EAfA,KAAA;EAegB;;EAZhB,OAAA;EACA,GAAA,IAAO,IAAA;AAAA;AAAA,UAGQ,OAAA;;EAEf,UAAA;EASoD;EAPpD,OAAA;EAOmD;EALnD,OAAA;EAK6B;EAH7B,MAAA,EAAQ,KAAA;IAAQ,GAAA;IAAa,KAAA;EAAA;AAAA;AAAA,iBAGT,KAAA,CAAM,CAAA,EAAG,YAAA,GAAe,OAAA,CAAQ,OAAA"}
|
package/dist/run-gc.mjs
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { assertValidCid, objectKeyForCid } from "./object-key.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/run-gc.ts
|
|
4
|
+
/** 7 days — the sole protection for behind/offline devices (design §0.2, §7). */
|
|
5
|
+
const DEFAULT_GC_GRACE_MS = 10080 * 60 * 1e3;
|
|
6
|
+
const DEFAULT_GC_LIMIT = 500;
|
|
7
|
+
async function runGc(o) {
|
|
8
|
+
const limit = o.limit ?? DEFAULT_GC_LIMIT;
|
|
9
|
+
const graceMs = o.graceMs ?? DEFAULT_GC_GRACE_MS;
|
|
10
|
+
const nowMs = Date.now();
|
|
11
|
+
const candidates = await o.queue.fetchCandidates(limit, graceMs);
|
|
12
|
+
const stats = {
|
|
13
|
+
candidates: candidates.length,
|
|
14
|
+
deleted: [],
|
|
15
|
+
skipped: [],
|
|
16
|
+
errors: []
|
|
17
|
+
};
|
|
18
|
+
for (const { cid } of candidates) {
|
|
19
|
+
try {
|
|
20
|
+
assertValidCid(cid);
|
|
21
|
+
} catch (err) {
|
|
22
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
23
|
+
stats.errors.push({
|
|
24
|
+
cid,
|
|
25
|
+
error: msg
|
|
26
|
+
});
|
|
27
|
+
o.log?.(`[gc] skip invalid cid: ${msg}`);
|
|
28
|
+
try {
|
|
29
|
+
await o.queue.remove(cid);
|
|
30
|
+
} catch {}
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
if (await o.referencedAnywhere(cid, nowMs)) {
|
|
35
|
+
await o.queue.remove(cid);
|
|
36
|
+
stats.skipped.push(cid);
|
|
37
|
+
} else {
|
|
38
|
+
await o.objectStore.delete(objectKeyForCid(cid));
|
|
39
|
+
await o.queue.remove(cid);
|
|
40
|
+
stats.deleted.push(cid);
|
|
41
|
+
}
|
|
42
|
+
} catch (err) {
|
|
43
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
44
|
+
stats.errors.push({
|
|
45
|
+
cid,
|
|
46
|
+
error: msg
|
|
47
|
+
});
|
|
48
|
+
o.log?.(`[gc] error on cid ${cid}: ${msg}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
o.log?.(JSON.stringify(stats));
|
|
52
|
+
return stats;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
export { DEFAULT_GC_GRACE_MS, runGc };
|
|
57
|
+
//# sourceMappingURL=run-gc.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-gc.mjs","names":[],"sources":["../src/run-gc.ts"],"sourcesContent":["/**\n * runGc — the shared, runtime-agnostic object-GC sweeper (design §4.5).\n *\n * Storage-agnostic: it takes a `GcQueue` (where candidates live), a\n * `referencedAnywhere` callback (scope-blind, entries-only liveness — §4.4b),\n * and an `ObjectStore`. Node passes `SqliteGcQueue` + `referencedAnywhereLibsql`\n * + `FsObjectStore`; Cloudflare passes `D1GCQueue` + `referencedAnywhereD1` +\n * raw R2. Both call the SAME sweeper.\n *\n * Per candidate:\n * 1. `assertValidCid(cid)` — a poisoned queue row (`\"../_metadata.db\"`) is\n * logged + recorded as an error and the row is dropped; the object store is\n * NEVER asked to delete a traversal key (§4.5 P0-safety).\n * 2. re-check `referencedAnywhere(cid)` FRESH, immediately before delete (never\n * snapshotted at fetch) — together with the §4.7 write-dequeue this shrinks\n * the re-reference race window to sub-ms.\n * 3. referenced ⇒ keep the object, drop the queue row (`skipped`).\n * unreferenced ⇒ `objectStore.delete(objectKeyForCid(cid))` then drop the\n * row (`deleted`).\n *\n * Per-item try/catch: one bad cid never aborts the batch. On an operational\n * error (delete/remove threw) the row is LEFT for the next run — delete is\n * idempotent, so a crash between delete and remove is retried safely and never\n * loses a live object.\n */\n\nimport type { ObjectStore } from \"@aigne/afs-r2\";\nimport type { GcQueue } from \"./gc-queue.js\";\nimport { assertValidCid, objectKeyForCid } from \"./object-key.js\";\n\n/** 7 days — the sole protection for behind/offline devices (design §0.2, §7). */\nexport const DEFAULT_GC_GRACE_MS = 7 * 24 * 60 * 60 * 1000;\nconst DEFAULT_GC_LIMIT = 500;\n\nexport interface RunGcOptions {\n queue: GcQueue;\n /**\n * scope-blind liveness — entries ∪ non-expired prepared upload sessions\n * (reference-check.ts). `nowMs` is the sweep-start time, passed so the whole\n * sweep judges prepared-session expiry against ONE consistent clock (design\n * §9). Ad-hoc callers may omit it (the impls default to Date.now()).\n */\n referencedAnywhere(cid: string, nowMs: number): Promise<boolean>;\n objectStore: ObjectStore;\n /** max candidates per sweep (default 500). */\n limit?: number;\n /** grace window (default 7d). `runGc` owns the canonical value and passes it\n * explicitly to `fetchCandidates`, so a queue impl's own default is never relied upon. */\n graceMs?: number;\n log?: (line: string) => void;\n}\n\nexport interface GcStats {\n /** number of candidates fetched this sweep. */\n candidates: number;\n /** cids whose object was deleted. */\n deleted: string[];\n /** cids kept because still referenced (object NOT deleted). */\n skipped: string[];\n /** cids that errored (invalid cid, or delete/remove threw). */\n errors: Array<{ cid: string; error: string }>;\n}\n\nexport async function runGc(o: RunGcOptions): Promise<GcStats> {\n const limit = o.limit ?? DEFAULT_GC_LIMIT;\n const graceMs = o.graceMs ?? DEFAULT_GC_GRACE_MS;\n // ONE sweep-start clock, threaded into every liveness check so prepared-session\n // expiry is judged uniformly across the whole sweep (design §9).\n const nowMs = Date.now();\n const candidates = await o.queue.fetchCandidates(limit, graceMs);\n\n const stats: GcStats = { candidates: candidates.length, deleted: [], skipped: [], errors: [] };\n\n for (const { cid } of candidates) {\n // (1) Validate FIRST — a poisoned row must never reach objectStore.delete\n // with a traversal key. Drop the garbage row (it can never be a valid object\n // or reference) and record it; keep sweeping.\n try {\n assertValidCid(cid);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n stats.errors.push({ cid, error: msg });\n o.log?.(`[gc] skip invalid cid: ${msg}`);\n try {\n await o.queue.remove(cid);\n } catch {\n // leave the poison row if even removal fails; it stays visible next run.\n }\n continue;\n }\n\n try {\n // (2) FRESH liveness re-check at delete time (never snapshotted).\n if (await o.referencedAnywhere(cid, nowMs)) {\n // (3a) still referenced — keep the object, drop the queue row.\n await o.queue.remove(cid);\n stats.skipped.push(cid);\n } else {\n // (3b) orphan — delete the object, then drop the row. Idempotent: a\n // crash before `remove` is retried and the already-gone delete no-ops.\n await o.objectStore.delete(objectKeyForCid(cid));\n await o.queue.remove(cid);\n stats.deleted.push(cid);\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n stats.errors.push({ cid, error: msg });\n o.log?.(`[gc] error on cid ${cid}: ${msg}`);\n // leave the row for the next run (delete is idempotent; no live object lost).\n }\n }\n\n o.log?.(JSON.stringify(stats));\n return stats;\n}\n"],"mappings":";;;;AA+BA,MAAa,sBAAsB,QAAc,KAAK;AACtD,MAAM,mBAAmB;AA+BzB,eAAsB,MAAM,GAAmC;CAC7D,MAAM,QAAQ,EAAE,SAAS;CACzB,MAAM,UAAU,EAAE,WAAW;CAG7B,MAAM,QAAQ,KAAK,KAAK;CACxB,MAAM,aAAa,MAAM,EAAE,MAAM,gBAAgB,OAAO,QAAQ;CAEhE,MAAM,QAAiB;EAAE,YAAY,WAAW;EAAQ,SAAS,EAAE;EAAE,SAAS,EAAE;EAAE,QAAQ,EAAE;EAAE;AAE9F,MAAK,MAAM,EAAE,SAAS,YAAY;AAIhC,MAAI;AACF,kBAAe,IAAI;WACZ,KAAK;GACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,SAAM,OAAO,KAAK;IAAE;IAAK,OAAO;IAAK,CAAC;AACtC,KAAE,MAAM,0BAA0B,MAAM;AACxC,OAAI;AACF,UAAM,EAAE,MAAM,OAAO,IAAI;WACnB;AAGR;;AAGF,MAAI;AAEF,OAAI,MAAM,EAAE,mBAAmB,KAAK,MAAM,EAAE;AAE1C,UAAM,EAAE,MAAM,OAAO,IAAI;AACzB,UAAM,QAAQ,KAAK,IAAI;UAClB;AAGL,UAAM,EAAE,YAAY,OAAO,gBAAgB,IAAI,CAAC;AAChD,UAAM,EAAE,MAAM,OAAO,IAAI;AACzB,UAAM,QAAQ,KAAK,IAAI;;WAElB,KAAK;GACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,SAAM,OAAO,KAAK;IAAE;IAAK,OAAO;IAAK,CAAC;AACtC,KAAE,MAAM,qBAAqB,IAAI,IAAI,MAAM;;;AAK/C,GAAE,MAAM,KAAK,UAAU,MAAM,CAAC;AAC9B,QAAO"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
let _arcblock_did = require("@arcblock/did");
|
|
3
|
+
let _noble_hashes_hmac_js = require("@noble/hashes/hmac.js");
|
|
4
|
+
let _noble_hashes_sha2_js = require("@noble/hashes/sha2.js");
|
|
5
|
+
let _noble_hashes_utils_js = require("@noble/hashes/utils.js");
|
|
6
|
+
let multiformats_bases_base32 = require("multiformats/bases/base32");
|
|
7
|
+
|
|
8
|
+
//#region src/scope-id.ts
|
|
9
|
+
/**
|
|
10
|
+
* scope-id — scope de-identification primitives (README §4.2 / §4.4 / §4.5).
|
|
11
|
+
*
|
|
12
|
+
* The DID Space "storage scope" is normally the plaintext `normalizeId(DID)`.
|
|
13
|
+
* When a deployment opts into de-identification (by providing a per-deployment
|
|
14
|
+
* HMAC secret), the storage scope becomes an opaque HMAC of the DID, so a D1
|
|
15
|
+
* dump / R2 replica leak cannot be attributed back to a specific user.
|
|
16
|
+
*
|
|
17
|
+
* These are PURE functions, shared verbatim by CF + Node runtimes AND by the
|
|
18
|
+
* offline migration scripts. The runtime and the migration script MUST derive
|
|
19
|
+
* scopes with the SAME `decodeScopeHmacSecret` + `deriveScope` to stay
|
|
20
|
+
* addressable — see README §4.4 "编码定死".
|
|
21
|
+
*
|
|
22
|
+
* - HMAC must be SYNCHRONOUS (tree-index constructors run synchronously in the
|
|
23
|
+
* request path). WebCrypto `subtle.sign` is async; `node:crypto` is absent on
|
|
24
|
+
* CF Workers. `@noble/hashes` is the only synchronous, cross-runtime option.
|
|
25
|
+
* - base32 reuses did-space's existing `multiformats` dependency.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Derive an opaque storage scope from a normalized DID + HMAC secret.
|
|
29
|
+
*
|
|
30
|
+
* HMAC-SHA256(key, utf8(normalizedDid)) → first 20 bytes → base32 lower, no pad,
|
|
31
|
+
* no prefix → 32 chars (20 × 8 / 5 = 32, naturally unpadded). The result is the
|
|
32
|
+
* final scope; nothing is prefixed. 32 chars fits `entries.scope CHECK(LENGTH<=128)`.
|
|
33
|
+
*
|
|
34
|
+
* Empty key throws (fail-closed): a de-id-disabled caller must not reach here.
|
|
35
|
+
*/
|
|
36
|
+
function deriveScope(normalizedDid, key) {
|
|
37
|
+
if (!key?.length) throw new Error("scopeHmacSecret missing — refusing to derive (fail-closed)");
|
|
38
|
+
const mac = (0, _noble_hashes_hmac_js.hmac)(_noble_hashes_sha2_js.sha256, key, (0, _noble_hashes_utils_js.utf8ToBytes)(normalizedDid));
|
|
39
|
+
return multiformats_bases_base32.base32.baseEncode(mac.subarray(0, 20));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Decode the deployment HMAC secret from its env/config string.
|
|
43
|
+
*
|
|
44
|
+
* Encoding is fixed (README §4.4): hex(32 bytes) → 64 hex chars. Any other
|
|
45
|
+
* decoded length throws — runtime and migration MUST agree byte-for-byte.
|
|
46
|
+
*/
|
|
47
|
+
function decodeScopeHmacSecret(envStr) {
|
|
48
|
+
const bytes = (0, _noble_hashes_utils_js.hexToBytes)(envStr);
|
|
49
|
+
if (bytes.length !== 32) throw new Error(`scopeHmacSecret must decode to 32 bytes, got ${bytes.length}`);
|
|
50
|
+
return bytes;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Is this scope a plaintext DID (i.e. still pending de-id migration)?
|
|
54
|
+
*
|
|
55
|
+
* Uses the authoritative DID validator (`@arcblock/did#isValid`) — never a
|
|
56
|
+
* hand-rolled regex, never the lenient `validateId`. `isValid` accepts the bare
|
|
57
|
+
* normalizeId form (it strips any prefix internally via `toAddress`), so the
|
|
58
|
+
* normalized scope can be checked directly without re-prefixing.
|
|
59
|
+
*
|
|
60
|
+
* Returns false for: versioned content scopes (`schema:pkg:1.2.3`), already
|
|
61
|
+
* derived base32 hashes, bare names (`persona`), `did:web:*`, random strings.
|
|
62
|
+
* This is what makes migration idempotent: a re-run sees derived hashes as
|
|
63
|
+
* non-DID and skips them (README §4.5).
|
|
64
|
+
*/
|
|
65
|
+
const isPlainDidScope = (scope) => (0, _arcblock_did.isValid)(scope);
|
|
66
|
+
|
|
67
|
+
//#endregion
|
|
68
|
+
exports.decodeScopeHmacSecret = decodeScopeHmacSecret;
|
|
69
|
+
exports.deriveScope = deriveScope;
|
|
70
|
+
exports.isPlainDidScope = isPlainDidScope;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/scope-id.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Derive an opaque storage scope from a normalized DID + HMAC secret.
|
|
4
|
+
*
|
|
5
|
+
* HMAC-SHA256(key, utf8(normalizedDid)) → first 20 bytes → base32 lower, no pad,
|
|
6
|
+
* no prefix → 32 chars (20 × 8 / 5 = 32, naturally unpadded). The result is the
|
|
7
|
+
* final scope; nothing is prefixed. 32 chars fits `entries.scope CHECK(LENGTH<=128)`.
|
|
8
|
+
*
|
|
9
|
+
* Empty key throws (fail-closed): a de-id-disabled caller must not reach here.
|
|
10
|
+
*/
|
|
11
|
+
declare function deriveScope(normalizedDid: string, key: Uint8Array): string;
|
|
12
|
+
/**
|
|
13
|
+
* Decode the deployment HMAC secret from its env/config string.
|
|
14
|
+
*
|
|
15
|
+
* Encoding is fixed (README §4.4): hex(32 bytes) → 64 hex chars. Any other
|
|
16
|
+
* decoded length throws — runtime and migration MUST agree byte-for-byte.
|
|
17
|
+
*/
|
|
18
|
+
declare function decodeScopeHmacSecret(envStr: string): Uint8Array;
|
|
19
|
+
/**
|
|
20
|
+
* Is this scope a plaintext DID (i.e. still pending de-id migration)?
|
|
21
|
+
*
|
|
22
|
+
* Uses the authoritative DID validator (`@arcblock/did#isValid`) — never a
|
|
23
|
+
* hand-rolled regex, never the lenient `validateId`. `isValid` accepts the bare
|
|
24
|
+
* normalizeId form (it strips any prefix internally via `toAddress`), so the
|
|
25
|
+
* normalized scope can be checked directly without re-prefixing.
|
|
26
|
+
*
|
|
27
|
+
* Returns false for: versioned content scopes (`schema:pkg:1.2.3`), already
|
|
28
|
+
* derived base32 hashes, bare names (`persona`), `did:web:*`, random strings.
|
|
29
|
+
* This is what makes migration idempotent: a re-run sees derived hashes as
|
|
30
|
+
* non-DID and skips them (README §4.5).
|
|
31
|
+
*/
|
|
32
|
+
declare const isPlainDidScope: (scope: string) => boolean;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { decodeScopeHmacSecret, deriveScope, isPlainDidScope };
|
|
35
|
+
//# sourceMappingURL=scope-id.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-id.d.cts","names":[],"sources":["../src/scope-id.ts"],"mappings":";;AAiCA;;;;;;;;iBAAgB,WAAA,CAAY,aAAA,UAAuB,GAAA,EAAK,UAAA;AAexD;;;;;AAqBA;AArBA,iBAAgB,qBAAA,CAAsB,MAAA,WAAiB,UAAA;;;;;;;;;;;;;;cAqB1C,eAAA,GAAmB,KAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/scope-id.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Derive an opaque storage scope from a normalized DID + HMAC secret.
|
|
4
|
+
*
|
|
5
|
+
* HMAC-SHA256(key, utf8(normalizedDid)) → first 20 bytes → base32 lower, no pad,
|
|
6
|
+
* no prefix → 32 chars (20 × 8 / 5 = 32, naturally unpadded). The result is the
|
|
7
|
+
* final scope; nothing is prefixed. 32 chars fits `entries.scope CHECK(LENGTH<=128)`.
|
|
8
|
+
*
|
|
9
|
+
* Empty key throws (fail-closed): a de-id-disabled caller must not reach here.
|
|
10
|
+
*/
|
|
11
|
+
declare function deriveScope(normalizedDid: string, key: Uint8Array): string;
|
|
12
|
+
/**
|
|
13
|
+
* Decode the deployment HMAC secret from its env/config string.
|
|
14
|
+
*
|
|
15
|
+
* Encoding is fixed (README §4.4): hex(32 bytes) → 64 hex chars. Any other
|
|
16
|
+
* decoded length throws — runtime and migration MUST agree byte-for-byte.
|
|
17
|
+
*/
|
|
18
|
+
declare function decodeScopeHmacSecret(envStr: string): Uint8Array;
|
|
19
|
+
/**
|
|
20
|
+
* Is this scope a plaintext DID (i.e. still pending de-id migration)?
|
|
21
|
+
*
|
|
22
|
+
* Uses the authoritative DID validator (`@arcblock/did#isValid`) — never a
|
|
23
|
+
* hand-rolled regex, never the lenient `validateId`. `isValid` accepts the bare
|
|
24
|
+
* normalizeId form (it strips any prefix internally via `toAddress`), so the
|
|
25
|
+
* normalized scope can be checked directly without re-prefixing.
|
|
26
|
+
*
|
|
27
|
+
* Returns false for: versioned content scopes (`schema:pkg:1.2.3`), already
|
|
28
|
+
* derived base32 hashes, bare names (`persona`), `did:web:*`, random strings.
|
|
29
|
+
* This is what makes migration idempotent: a re-run sees derived hashes as
|
|
30
|
+
* non-DID and skips them (README §4.5).
|
|
31
|
+
*/
|
|
32
|
+
declare const isPlainDidScope: (scope: string) => boolean;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { decodeScopeHmacSecret, deriveScope, isPlainDidScope };
|
|
35
|
+
//# sourceMappingURL=scope-id.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-id.d.mts","names":[],"sources":["../src/scope-id.ts"],"mappings":";;AAiCA;;;;;;;;iBAAgB,WAAA,CAAY,aAAA,UAAuB,GAAA,EAAK,UAAA;AAexD;;;;;AAqBA;AArBA,iBAAgB,qBAAA,CAAsB,MAAA,WAAiB,UAAA;;;;;;;;;;;;;;cAqB1C,eAAA,GAAmB,KAAA"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { isValid } from "@arcblock/did";
|
|
2
|
+
import { hmac } from "@noble/hashes/hmac.js";
|
|
3
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
4
|
+
import { hexToBytes, utf8ToBytes } from "@noble/hashes/utils.js";
|
|
5
|
+
import { base32 } from "multiformats/bases/base32";
|
|
6
|
+
|
|
7
|
+
//#region src/scope-id.ts
|
|
8
|
+
/**
|
|
9
|
+
* scope-id — scope de-identification primitives (README §4.2 / §4.4 / §4.5).
|
|
10
|
+
*
|
|
11
|
+
* The DID Space "storage scope" is normally the plaintext `normalizeId(DID)`.
|
|
12
|
+
* When a deployment opts into de-identification (by providing a per-deployment
|
|
13
|
+
* HMAC secret), the storage scope becomes an opaque HMAC of the DID, so a D1
|
|
14
|
+
* dump / R2 replica leak cannot be attributed back to a specific user.
|
|
15
|
+
*
|
|
16
|
+
* These are PURE functions, shared verbatim by CF + Node runtimes AND by the
|
|
17
|
+
* offline migration scripts. The runtime and the migration script MUST derive
|
|
18
|
+
* scopes with the SAME `decodeScopeHmacSecret` + `deriveScope` to stay
|
|
19
|
+
* addressable — see README §4.4 "编码定死".
|
|
20
|
+
*
|
|
21
|
+
* - HMAC must be SYNCHRONOUS (tree-index constructors run synchronously in the
|
|
22
|
+
* request path). WebCrypto `subtle.sign` is async; `node:crypto` is absent on
|
|
23
|
+
* CF Workers. `@noble/hashes` is the only synchronous, cross-runtime option.
|
|
24
|
+
* - base32 reuses did-space's existing `multiformats` dependency.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Derive an opaque storage scope from a normalized DID + HMAC secret.
|
|
28
|
+
*
|
|
29
|
+
* HMAC-SHA256(key, utf8(normalizedDid)) → first 20 bytes → base32 lower, no pad,
|
|
30
|
+
* no prefix → 32 chars (20 × 8 / 5 = 32, naturally unpadded). The result is the
|
|
31
|
+
* final scope; nothing is prefixed. 32 chars fits `entries.scope CHECK(LENGTH<=128)`.
|
|
32
|
+
*
|
|
33
|
+
* Empty key throws (fail-closed): a de-id-disabled caller must not reach here.
|
|
34
|
+
*/
|
|
35
|
+
function deriveScope(normalizedDid, key) {
|
|
36
|
+
if (!key?.length) throw new Error("scopeHmacSecret missing — refusing to derive (fail-closed)");
|
|
37
|
+
const mac = hmac(sha256, key, utf8ToBytes(normalizedDid));
|
|
38
|
+
return base32.baseEncode(mac.subarray(0, 20));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Decode the deployment HMAC secret from its env/config string.
|
|
42
|
+
*
|
|
43
|
+
* Encoding is fixed (README §4.4): hex(32 bytes) → 64 hex chars. Any other
|
|
44
|
+
* decoded length throws — runtime and migration MUST agree byte-for-byte.
|
|
45
|
+
*/
|
|
46
|
+
function decodeScopeHmacSecret(envStr) {
|
|
47
|
+
const bytes = hexToBytes(envStr);
|
|
48
|
+
if (bytes.length !== 32) throw new Error(`scopeHmacSecret must decode to 32 bytes, got ${bytes.length}`);
|
|
49
|
+
return bytes;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Is this scope a plaintext DID (i.e. still pending de-id migration)?
|
|
53
|
+
*
|
|
54
|
+
* Uses the authoritative DID validator (`@arcblock/did#isValid`) — never a
|
|
55
|
+
* hand-rolled regex, never the lenient `validateId`. `isValid` accepts the bare
|
|
56
|
+
* normalizeId form (it strips any prefix internally via `toAddress`), so the
|
|
57
|
+
* normalized scope can be checked directly without re-prefixing.
|
|
58
|
+
*
|
|
59
|
+
* Returns false for: versioned content scopes (`schema:pkg:1.2.3`), already
|
|
60
|
+
* derived base32 hashes, bare names (`persona`), `did:web:*`, random strings.
|
|
61
|
+
* This is what makes migration idempotent: a re-run sees derived hashes as
|
|
62
|
+
* non-DID and skips them (README §4.5).
|
|
63
|
+
*/
|
|
64
|
+
const isPlainDidScope = (scope) => isValid(scope);
|
|
65
|
+
|
|
66
|
+
//#endregion
|
|
67
|
+
export { decodeScopeHmacSecret, deriveScope, isPlainDidScope };
|
|
68
|
+
//# sourceMappingURL=scope-id.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-id.mjs","names":[],"sources":["../src/scope-id.ts"],"sourcesContent":["/**\n * scope-id — scope de-identification primitives (README §4.2 / §4.4 / §4.5).\n *\n * The DID Space \"storage scope\" is normally the plaintext `normalizeId(DID)`.\n * When a deployment opts into de-identification (by providing a per-deployment\n * HMAC secret), the storage scope becomes an opaque HMAC of the DID, so a D1\n * dump / R2 replica leak cannot be attributed back to a specific user.\n *\n * These are PURE functions, shared verbatim by CF + Node runtimes AND by the\n * offline migration scripts. The runtime and the migration script MUST derive\n * scopes with the SAME `decodeScopeHmacSecret` + `deriveScope` to stay\n * addressable — see README §4.4 \"编码定死\".\n *\n * - HMAC must be SYNCHRONOUS (tree-index constructors run synchronously in the\n * request path). WebCrypto `subtle.sign` is async; `node:crypto` is absent on\n * CF Workers. `@noble/hashes` is the only synchronous, cross-runtime option.\n * - base32 reuses did-space's existing `multiformats` dependency.\n */\nimport { isValid } from \"@arcblock/did\";\nimport { hmac } from \"@noble/hashes/hmac.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { hexToBytes, utf8ToBytes } from \"@noble/hashes/utils.js\";\nimport { base32 } from \"multiformats/bases/base32\";\n\n/**\n * Derive an opaque storage scope from a normalized DID + HMAC secret.\n *\n * HMAC-SHA256(key, utf8(normalizedDid)) → first 20 bytes → base32 lower, no pad,\n * no prefix → 32 chars (20 × 8 / 5 = 32, naturally unpadded). The result is the\n * final scope; nothing is prefixed. 32 chars fits `entries.scope CHECK(LENGTH<=128)`.\n *\n * Empty key throws (fail-closed): a de-id-disabled caller must not reach here.\n */\nexport function deriveScope(normalizedDid: string, key: Uint8Array): string {\n if (!key?.length) {\n throw new Error(\"scopeHmacSecret missing — refusing to derive (fail-closed)\");\n }\n const mac = hmac(sha256, key, utf8ToBytes(normalizedDid)); // 32 bytes\n // `baseEncode` yields the raw base32 alphabet with no multibase prefix.\n return base32.baseEncode(mac.subarray(0, 20)); // 32 chars\n}\n\n/**\n * Decode the deployment HMAC secret from its env/config string.\n *\n * Encoding is fixed (README §4.4): hex(32 bytes) → 64 hex chars. Any other\n * decoded length throws — runtime and migration MUST agree byte-for-byte.\n */\nexport function decodeScopeHmacSecret(envStr: string): Uint8Array {\n const bytes = hexToBytes(envStr);\n if (bytes.length !== 32) {\n throw new Error(`scopeHmacSecret must decode to 32 bytes, got ${bytes.length}`);\n }\n return bytes;\n}\n\n/**\n * Is this scope a plaintext DID (i.e. still pending de-id migration)?\n *\n * Uses the authoritative DID validator (`@arcblock/did#isValid`) — never a\n * hand-rolled regex, never the lenient `validateId`. `isValid` accepts the bare\n * normalizeId form (it strips any prefix internally via `toAddress`), so the\n * normalized scope can be checked directly without re-prefixing.\n *\n * Returns false for: versioned content scopes (`schema:pkg:1.2.3`), already\n * derived base32 hashes, bare names (`persona`), `did:web:*`, random strings.\n * This is what makes migration idempotent: a re-run sees derived hashes as\n * non-DID and skips them (README §4.5).\n */\nexport const isPlainDidScope = (scope: string): boolean => isValid(scope);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,YAAY,eAAuB,KAAyB;AAC1E,KAAI,CAAC,KAAK,OACR,OAAM,IAAI,MAAM,6DAA6D;CAE/E,MAAM,MAAM,KAAK,QAAQ,KAAK,YAAY,cAAc,CAAC;AAEzD,QAAO,OAAO,WAAW,IAAI,SAAS,GAAG,GAAG,CAAC;;;;;;;;AAS/C,SAAgB,sBAAsB,QAA4B;CAChE,MAAM,QAAQ,WAAW,OAAO;AAChC,KAAI,MAAM,WAAW,GACnB,OAAM,IAAI,MAAM,gDAAgD,MAAM,SAAS;AAEjF,QAAO;;;;;;;;;;;;;;;AAgBT,MAAa,mBAAmB,UAA2B,QAAQ,MAAM"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_scope_id = require('./scope-id.cjs');
|
|
3
|
+
let node_fs = require("node:fs");
|
|
4
|
+
let node_path = require("node:path");
|
|
5
|
+
let _libsql_client = require("@libsql/client");
|
|
6
|
+
|
|
7
|
+
//#region src/scope-migration-node.ts
|
|
8
|
+
/**
|
|
9
|
+
* scope-migration-node — offline Node scope de-identification migration (README §5.4).
|
|
10
|
+
*
|
|
11
|
+
* Migrates the existing PLAINTEXT DID-scoped per-user spaces on a local disk to
|
|
12
|
+
* derived HMAC scopes. Unlike the CF migration (one shared D1), Node stores each
|
|
13
|
+
* user under `{rootPath}/{scope}/_metadata.db` + a daemon-global
|
|
14
|
+
* `{rootPath}/_shares.db`, so this is a per-DIRECTORY rename plus a per-db
|
|
15
|
+
* rewrite. OFFLINE tool: the daemon MUST be stopped first (README §5.4).
|
|
16
|
+
*
|
|
17
|
+
* Per directory `{rootPath}/{s}` whose basename `s` is a plaintext DID:
|
|
18
|
+
* 1. Rewrite `_metadata.db` scope columns (entries / changelog /
|
|
19
|
+
* prefix_watermark) where `scope = s` → `deriveScope(s)`, rewrite the
|
|
20
|
+
* `sync_state` `{s}:` key prefix (INSERT+DELETE — can't UPDATE a PK; the
|
|
21
|
+
* bare `device_id` key has no `{s}:` prefix so it is preserved), and clear
|
|
22
|
+
* `cid_cache` (no scope column, rebuildable). `sync_checkpoint` (transient)
|
|
23
|
+
* and `gc_queue` (cid-keyed) are untouched. ALL in one atomic batch.
|
|
24
|
+
* 2. `fs.rename` the directory to `{rootPath}/{deriveScope(s)}` — done LAST so
|
|
25
|
+
* the directory name is the idempotency marker: an interrupted run leaves a
|
|
26
|
+
* plaintext dir (re-run completes it), and a finished dir is a hash
|
|
27
|
+
* (`isPlainDidScope` false → skipped). The per-db batch is itself
|
|
28
|
+
* idempotent (keyed on the old plaintext `s`, a no-op once moved).
|
|
29
|
+
*
|
|
30
|
+
* Then the daemon-global `_shares.db.owner_did` is migrated once (same DID
|
|
31
|
+
* classification). Strict: only true DIDs migrate; versioned / already-derived /
|
|
32
|
+
* junk are skipped + reported, never silently HMAC'd.
|
|
33
|
+
*/
|
|
34
|
+
/** Which of `names` exist as tables in this db. */
|
|
35
|
+
async function existingTables(client, names) {
|
|
36
|
+
const placeholders = names.map(() => "?").join(", ");
|
|
37
|
+
const res = await client.execute({
|
|
38
|
+
sql: `SELECT name FROM sqlite_master WHERE type = 'table' AND name IN (${placeholders})`,
|
|
39
|
+
args: names
|
|
40
|
+
});
|
|
41
|
+
return new Set((res.rows ?? []).map((r) => r.name));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Rewrite a single per-user `_metadata.db` for the DID scope `s` → derived.
|
|
45
|
+
* Atomic (one write batch). The caller MUST close the client before renaming
|
|
46
|
+
* the directory.
|
|
47
|
+
*
|
|
48
|
+
* Probes table existence first: older `_metadata.db` files predate
|
|
49
|
+
* `prefix_watermark` / `sync_state` / `cid_cache` (added by later phases), so
|
|
50
|
+
* each statement is included ONLY when its table exists — otherwise libsql
|
|
51
|
+
* throws "no such table" and the whole batch aborts. `entries` / `changelog`
|
|
52
|
+
* are the core tables (always present in a real space db).
|
|
53
|
+
*/
|
|
54
|
+
async function migrateNodeMetadataDb(client, s, key) {
|
|
55
|
+
const h = require_scope_id.deriveScope(s, key);
|
|
56
|
+
const scopedPrefix = `${s}:`;
|
|
57
|
+
const derivedPrefix = `${h}:`;
|
|
58
|
+
const likeOld = `${s}:%`;
|
|
59
|
+
const present = await existingTables(client, [
|
|
60
|
+
"ds_entries",
|
|
61
|
+
"ds_changelog",
|
|
62
|
+
"ds_prefix_watermark",
|
|
63
|
+
"ds_dirty_path",
|
|
64
|
+
"ds_sync_state",
|
|
65
|
+
"cid_cache"
|
|
66
|
+
]);
|
|
67
|
+
const stmts = [];
|
|
68
|
+
if (present.has("ds_entries")) stmts.push({
|
|
69
|
+
sql: "UPDATE ds_entries SET scope = ? WHERE scope = ?",
|
|
70
|
+
args: [h, s]
|
|
71
|
+
});
|
|
72
|
+
if (present.has("ds_changelog")) stmts.push({
|
|
73
|
+
sql: "UPDATE ds_changelog SET scope = ? WHERE scope = ?",
|
|
74
|
+
args: [h, s]
|
|
75
|
+
});
|
|
76
|
+
if (present.has("ds_prefix_watermark")) stmts.push({
|
|
77
|
+
sql: "UPDATE ds_prefix_watermark SET scope = ? WHERE scope = ?",
|
|
78
|
+
args: [h, s]
|
|
79
|
+
});
|
|
80
|
+
if (present.has("ds_dirty_path")) stmts.push({
|
|
81
|
+
sql: "UPDATE ds_dirty_path SET scope = ? WHERE scope = ?",
|
|
82
|
+
args: [h, s]
|
|
83
|
+
});
|
|
84
|
+
if (present.has("ds_sync_state")) {
|
|
85
|
+
stmts.push({
|
|
86
|
+
sql: "INSERT OR IGNORE INTO ds_sync_state(key, value) SELECT replace(key, ?, ?), value FROM ds_sync_state WHERE key LIKE ?",
|
|
87
|
+
args: [
|
|
88
|
+
scopedPrefix,
|
|
89
|
+
derivedPrefix,
|
|
90
|
+
likeOld
|
|
91
|
+
]
|
|
92
|
+
});
|
|
93
|
+
stmts.push({
|
|
94
|
+
sql: "DELETE FROM ds_sync_state WHERE key LIKE ?",
|
|
95
|
+
args: [likeOld]
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (present.has("cid_cache")) stmts.push({
|
|
99
|
+
sql: "DELETE FROM cid_cache",
|
|
100
|
+
args: []
|
|
101
|
+
});
|
|
102
|
+
if (stmts.length > 0) await client.batch(stmts, "write");
|
|
103
|
+
}
|
|
104
|
+
/** Migrate `_shares.db.owner_did` for every plaintext-DID owner (one batch). */
|
|
105
|
+
async function migrateNodeShares(sharesPath, key, dryRun) {
|
|
106
|
+
const client = (0, _libsql_client.createClient)({ url: `file:${sharesPath}` });
|
|
107
|
+
try {
|
|
108
|
+
const owners = ((await client.execute("SELECT DISTINCT owner_did AS v FROM ds_shares")).rows ?? []).map((r) => r.v).filter((v) => v != null);
|
|
109
|
+
const migrate = owners.filter((o) => require_scope_id.isPlainDidScope(o));
|
|
110
|
+
const skipped = owners.length - migrate.length;
|
|
111
|
+
if (dryRun || migrate.length === 0) return {
|
|
112
|
+
migrated: 0,
|
|
113
|
+
skipped
|
|
114
|
+
};
|
|
115
|
+
await client.batch(migrate.map((o) => ({
|
|
116
|
+
sql: "UPDATE ds_shares SET owner_did = ? WHERE owner_did = ?",
|
|
117
|
+
args: [require_scope_id.deriveScope(o, key), o]
|
|
118
|
+
})), "write");
|
|
119
|
+
return {
|
|
120
|
+
migrated: migrate.length,
|
|
121
|
+
skipped
|
|
122
|
+
};
|
|
123
|
+
} finally {
|
|
124
|
+
client.close();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Migrate (or, with `dryRun`, classify) every plaintext-DID space under
|
|
129
|
+
* `rootPath`, plus the daemon-global `_shares.db`.
|
|
130
|
+
*/
|
|
131
|
+
async function migrateNodeSpaces(opts) {
|
|
132
|
+
const { rootPath, key, dryRun = false } = opts;
|
|
133
|
+
const migrate = [];
|
|
134
|
+
const skip = [];
|
|
135
|
+
const entries = (0, node_fs.existsSync)(rootPath) ? (0, node_fs.readdirSync)(rootPath, { withFileTypes: true }) : [];
|
|
136
|
+
for (const entry of entries) {
|
|
137
|
+
if (!entry.isDirectory()) continue;
|
|
138
|
+
(require_scope_id.isPlainDidScope(entry.name) ? migrate : skip).push(entry.name);
|
|
139
|
+
}
|
|
140
|
+
migrate.sort();
|
|
141
|
+
skip.sort();
|
|
142
|
+
let renamed = 0;
|
|
143
|
+
if (!dryRun) for (const s of migrate) {
|
|
144
|
+
const dir = (0, node_path.join)(rootPath, s);
|
|
145
|
+
const dbPath = (0, node_path.join)(dir, "_metadata.db");
|
|
146
|
+
if ((0, node_fs.existsSync)(dbPath)) {
|
|
147
|
+
const client = (0, _libsql_client.createClient)({ url: `file:${dbPath}` });
|
|
148
|
+
try {
|
|
149
|
+
await migrateNodeMetadataDb(client, s, key);
|
|
150
|
+
} finally {
|
|
151
|
+
client.close();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
(0, node_fs.renameSync)(dir, (0, node_path.join)(rootPath, require_scope_id.deriveScope(s, key)));
|
|
155
|
+
renamed++;
|
|
156
|
+
}
|
|
157
|
+
const sharesPath = (0, node_path.join)(rootPath, "_shares.db");
|
|
158
|
+
const shares = (0, node_fs.existsSync)(sharesPath) ? await migrateNodeShares(sharesPath, key, dryRun) : {
|
|
159
|
+
migrated: 0,
|
|
160
|
+
skipped: 0
|
|
161
|
+
};
|
|
162
|
+
return {
|
|
163
|
+
migrate,
|
|
164
|
+
skip,
|
|
165
|
+
renamed,
|
|
166
|
+
shares
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
//#endregion
|
|
171
|
+
exports.migrateNodeMetadataDb = migrateNodeMetadataDb;
|
|
172
|
+
exports.migrateNodeSpaces = migrateNodeSpaces;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Client } from "@libsql/client";
|
|
2
|
+
|
|
3
|
+
//#region src/scope-migration-node.d.ts
|
|
4
|
+
interface NodeScopeMigrationOptions {
|
|
5
|
+
/** Classify only — list migrate/skip, rewrite + rename nothing. */
|
|
6
|
+
dryRun?: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface NodeScopeMigrationReport {
|
|
9
|
+
/** Plaintext DID directory names that WILL be / WERE migrated (sorted). */
|
|
10
|
+
migrate: string[];
|
|
11
|
+
/** Non-DID directory names skipped: already-derived hash / versioned / junk (sorted). */
|
|
12
|
+
skip: string[];
|
|
13
|
+
/** Count of directories actually renamed (0 when dryRun). */
|
|
14
|
+
renamed: number;
|
|
15
|
+
/** `_shares.db` owner_did migration outcome. */
|
|
16
|
+
shares: {
|
|
17
|
+
migrated: number;
|
|
18
|
+
skipped: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Rewrite a single per-user `_metadata.db` for the DID scope `s` → derived.
|
|
23
|
+
* Atomic (one write batch). The caller MUST close the client before renaming
|
|
24
|
+
* the directory.
|
|
25
|
+
*
|
|
26
|
+
* Probes table existence first: older `_metadata.db` files predate
|
|
27
|
+
* `prefix_watermark` / `sync_state` / `cid_cache` (added by later phases), so
|
|
28
|
+
* each statement is included ONLY when its table exists — otherwise libsql
|
|
29
|
+
* throws "no such table" and the whole batch aborts. `entries` / `changelog`
|
|
30
|
+
* are the core tables (always present in a real space db).
|
|
31
|
+
*/
|
|
32
|
+
declare function migrateNodeMetadataDb(client: Client, s: string, key: Uint8Array): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Migrate (or, with `dryRun`, classify) every plaintext-DID space under
|
|
35
|
+
* `rootPath`, plus the daemon-global `_shares.db`.
|
|
36
|
+
*/
|
|
37
|
+
declare function migrateNodeSpaces(opts: {
|
|
38
|
+
rootPath: string;
|
|
39
|
+
key: Uint8Array;
|
|
40
|
+
dryRun?: boolean;
|
|
41
|
+
}): Promise<NodeScopeMigrationReport>;
|
|
42
|
+
//#endregion
|
|
43
|
+
export { NodeScopeMigrationOptions, NodeScopeMigrationReport, migrateNodeMetadataDb, migrateNodeSpaces };
|
|
44
|
+
//# sourceMappingURL=scope-migration-node.d.cts.map
|