@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 @@
|
|
|
1
|
+
{"version":3,"file":"prefixed-tree-index.mjs","names":["map"],"sources":["../src/prefixed-tree-index.ts"],"sourcesContent":["/**\n * PrefixedTreeIndex — wraps a TreeIndex, prepending a prefix to all paths.\n *\n * Used by CloudflareDIDSpace to store per-app data under a shared user scope:\n * scope = \"z1user\", prefix = \"z1appA/\" → path \"file.txt\" stored as \"z1appA/file.txt\"\n */\n\nimport type { DirtyPathRow, ListDirtyPathOptions } from \"./dirty-path-queue.js\";\nimport {\n type BatchDeleteEntry,\n type BatchDeleteEntryResult,\n type BatchIndexContext,\n type BatchPutEntry,\n type BatchPutEntryResult,\n type ChangelogEntry,\n loopBatchDeleteEntries,\n loopBatchPutEntries,\n type PutOpts,\n type TreeEntry,\n type TreeIndex,\n type TreeIndexListEntriesResult,\n type TreeIndexListOptions,\n type TreeIndexListResult,\n} from \"./tree-index.js\";\n\nexport class PrefixedTreeIndex implements TreeIndex {\n constructor(\n private inner: TreeIndex,\n private prefix: string,\n ) {}\n\n async get(path: string, opts?: { includeContent?: boolean }): Promise<TreeEntry | null> {\n return this.inner.get(this.prefix + path, opts);\n }\n\n async getDirTimes(dirPath: string): Promise<{ ctime: number; mtime: number } | null> {\n return (await this.inner.getDirTimes?.(this.prefix + dirPath)) ?? null;\n }\n\n async put(path: string, entry: TreeEntry, opts: PutOpts): Promise<{ oldCid?: string }> {\n // Dedup scope is a collection path in the SAME namespace as `path`, so it\n // must carry the fragment prefix too — otherwise app A and app B under one\n // user scope would share a dedup identity (#1159 app-isolation, mirrors the\n // prefix-local read-auth in isReferenced).\n const prefixed =\n entry.dedupScope != null ? { ...entry, dedupScope: this.prefix + entry.dedupScope } : entry;\n return this.inner.put(this.prefix + path, prefixed, opts);\n }\n\n async delete(path: string, opts: PutOpts): Promise<void> {\n return this.inner.delete(this.prefix + path, opts);\n }\n\n /** Dedup lookup (#1159) — prefix the scope in, strip the prefix off the result path. */\n async findByDedupKey(\n dedupScope: string,\n dedupKey: string,\n ): Promise<({ path: string } & TreeEntry) | null> {\n const r = await this.inner.findByDedupKey?.(this.prefix + dedupScope, dedupKey);\n if (!r) return null;\n return { ...r, path: r.path.slice(this.prefix.length) };\n }\n\n /** Dedup reindex seam (#1159) — prefix both the path and the dedup scope. */\n async setDedupKey(\n path: string,\n dedupScope: string,\n dedupKey: string,\n opts: PutOpts,\n ): Promise<void> {\n await this.inner.setDedupKey?.(this.prefix + path, this.prefix + dedupScope, dedupKey, opts);\n }\n\n async list(listPrefix: string, options?: TreeIndexListOptions): Promise<TreeIndexListResult> {\n const result = await this.inner.list(this.prefix + listPrefix, options);\n // Strip prefix from returned paths\n return {\n entries: result.entries.map((e) => ({\n path: e.path.slice(this.prefix.length),\n })),\n hasMore: result.hasMore,\n cursor: result.cursor,\n };\n }\n\n async listEntries(\n listPrefix: string,\n options?: TreeIndexListOptions,\n ): Promise<TreeIndexListEntriesResult> {\n const result = await this.inner.listEntries(this.prefix + listPrefix, options);\n return {\n entries: result.entries.map((e) => ({\n ...e,\n path: e.path.slice(this.prefix.length),\n })),\n hasMore: result.hasMore,\n cursor: result.cursor,\n };\n }\n\n async hasChildren(listPrefix: string): Promise<boolean> {\n return this.inner.hasChildren(this.prefix + listPrefix);\n }\n\n async getAndHasChildren(\n filePath: string,\n dirPrefix: string,\n ): Promise<[TreeEntry | null, boolean]> {\n if (this.inner.getAndHasChildren) {\n return this.inner.getAndHasChildren(this.prefix + filePath, this.prefix + dirPrefix);\n }\n const [entry, hasChildren] = await Promise.all([\n this.inner.get(this.prefix + filePath),\n this.inner.hasChildren(this.prefix + dirPrefix),\n ]);\n return [entry, hasChildren];\n }\n\n async count(listPrefix: string): Promise<number> {\n return this.inner.count(this.prefix + listPrefix);\n }\n\n async deleteByPrefix(listPrefix: string, opts: PutOpts): Promise<number> {\n return this.inner.deleteByPrefix(this.prefix + listPrefix, opts);\n }\n\n // ========== v2 methods ==========\n\n async listChildren(\n parent: string,\n options?: TreeIndexListOptions,\n ): Promise<TreeIndexListEntriesResult> {\n const result = await this.inner.listChildren(this.prefix + parent, options);\n return {\n entries: result.entries.map((e) => ({\n ...e,\n path: e.path.slice(this.prefix.length),\n })),\n hasMore: result.hasMore,\n cursor: result.cursor,\n };\n }\n\n async countChildren(parent: string): Promise<number> {\n return this.inner.countChildren(this.prefix + parent);\n }\n\n /**\n * Collection query — delegate with the fragment prefix prepended, strip it\n * off result row paths. The prefix is the blocklet-isolation boundary: a\n * fragment can only ever query its own sub-tree.\n */\n async query(\n parent: string,\n spec: import(\"./tree-query.js\").TreeQuerySpec,\n ): Promise<import(\"./tree-query.js\").TreeQueryResult> {\n if (!this.inner.query) {\n throw new Error(\"Collection query is not supported by the underlying index\");\n }\n const result = await this.inner.query(this.prefix + parent, spec);\n return {\n ...result,\n rows: result.rows.map((r) => ({ ...r, path: r.path.slice(this.prefix.length) })),\n };\n }\n\n async countChildrenMany(parents: string[]): Promise<Map<string, number>> {\n // Delegate with the prefix prepended, then strip it back off the parent\n // keys so the returned paths match what `listChildren` yields here. An\n // inner index without the method falls back to per-path countChildren —\n // page-bounded by contract, so the loop is ≤ one page of parents. Zero\n // counts stay omitted in both branches (contract: `map.get(p) ?? 0`).\n const out = new Map<string, number>();\n if (!this.inner.countChildrenMany) {\n for (const p of parents) {\n const cnt = await this.inner.countChildren(this.prefix + p);\n if (cnt > 0) out.set(p, cnt);\n }\n return out;\n }\n const inner = await this.inner.countChildrenMany(parents.map((p) => this.prefix + p));\n for (const [parent, cnt] of inner) out.set(parent.slice(this.prefix.length), cnt);\n return out;\n }\n\n async aggregate(prefix: string): Promise<{ fileCount: number; totalSize: number }> {\n return this.inner.aggregate(this.prefix + prefix);\n }\n\n async putBatch(entries: Array<{ path: string; entry: TreeEntry }>, opts: PutOpts): Promise<void> {\n return this.inner.putBatch(\n entries.map((e) => ({ path: this.prefix + e.path, entry: e.entry })),\n opts,\n );\n }\n\n // ── batch sync fast path (afs-rpc-batch P3) — prefix in, strip out ──\n // Forwards to the inner index's merged implementation when present; falls\n // back to the loop reference semantics over THIS wrapper otherwise.\n\n private mapPrereadIn(ctx: BatchIndexContext | undefined): BatchIndexContext | undefined {\n if (!ctx?.preread) return ctx;\n const inner = new Map<string, TreeEntry | null>();\n for (const [k, v] of ctx.preread) inner.set(this.prefix + k, v);\n return { ...ctx, preread: inner };\n }\n\n async getMany(paths: string[]): Promise<Map<string, TreeEntry | null>> {\n if (!this.inner.getMany) {\n const map = new Map<string, TreeEntry | null>();\n for (const p of paths) map.set(p, await this.get(p));\n return map;\n }\n const innerMap = await this.inner.getMany(paths.map((p) => this.prefix + p));\n const map = new Map<string, TreeEntry | null>();\n for (const p of paths) map.set(p, innerMap.get(this.prefix + p) ?? null);\n return map;\n }\n\n /** Inline policy is path-independent — delegate straight to the inner index.\n * An inner without inline support resolves to NULL (loop keeps the legacy skip). */\n inlineForEntry(entry: TreeEntry): Promise<string | null> {\n return this.inner.inlineForEntry?.(entry) ?? Promise.resolve(null);\n }\n\n async batchPutEntries(\n entries: BatchPutEntry[],\n ctx?: BatchIndexContext,\n ): Promise<BatchPutEntryResult[]> {\n if (!this.inner.batchPutEntries) return loopBatchPutEntries(this, entries, ctx);\n const results = await this.inner.batchPutEntries(\n entries.map((e) => ({ ...e, path: this.prefix + e.path })),\n this.mapPrereadIn(ctx),\n );\n return results.map((r) => ({ ...r, path: r.path.slice(this.prefix.length) }));\n }\n\n async batchDeleteEntries(\n entries: BatchDeleteEntry[],\n ctx?: BatchIndexContext,\n ): Promise<BatchDeleteEntryResult[]> {\n if (!this.inner.batchDeleteEntries) return loopBatchDeleteEntries(this, entries, ctx);\n const results = await this.inner.batchDeleteEntries(\n entries.map((e) => ({ ...e, path: this.prefix + e.path })),\n this.mapPrereadIn(ctx),\n );\n return results.map((r) => ({ ...r, path: r.path.slice(this.prefix.length) }));\n }\n\n async listModifiedSince(\n prefix: string,\n since: number,\n options?: TreeIndexListOptions,\n ): Promise<TreeIndexListEntriesResult> {\n const result = await this.inner.listModifiedSince(this.prefix + prefix, since, options);\n return {\n entries: result.entries.map((e) => ({\n ...e,\n path: e.path.slice(this.prefix.length),\n })),\n hasMore: result.hasMore,\n cursor: result.cursor,\n };\n }\n\n async getMaxSeq(): Promise<number> {\n // The changelog is shared across the entire scope; delegate to the\n // underlying index so the waterline reflects the scope's latest write.\n return this.inner.getMaxSeq();\n }\n\n async getPrefixWatermark(prefix: string): Promise<number | null> {\n // Prepend the fragment prefix so the inner index reduces `prefix + path`\n // to the same watermark key on read as it did on write. For the\n // instance-space layout (`blocklets/{i}/{role}/`) `watermarkPrefix`\n // resolves the key at the per-fragment collection root\n // (`blocklets/{i}/{role}/items`), keeping rows prefix-local (I3) instead\n // of collapsing the whole scope onto one first-segment row. If the inner\n // index lacks the method (rollout), there is no watermark → null.\n if (!this.inner.getPrefixWatermark) return null;\n return this.inner.getPrefixWatermark(this.prefix + prefix);\n }\n\n async getChangelogSince(\n sinceSeq: number,\n limit: number,\n ): Promise<{ entries: ChangelogEntry[]; hasMore: boolean; cursor: number }> {\n // The inner changelog is space-wide (scope = userDid). Filter to rows whose\n // path falls under this fragment's prefix and strip it, so callers only see\n // their own app's changes — never another app's rows under the same scope.\n //\n // `cursor` and `hasMore` come STRAIGHT from inner: cursor = max inner seq on\n // this page (NOT the last surviving entry's seq), hasMore = inner pagination.\n // This guarantees the cursor advances even when the prefix filter empties a\n // page — the caller keeps pulling by cursor until the inner scan is drained,\n // with no infinite loop and no skipped rows.\n const inner = await this.inner.getChangelogSince(sinceSeq, limit);\n const entries = inner.entries\n .filter((r) => r.path.startsWith(this.prefix))\n .map((r) => ({ ...r, path: r.path.slice(this.prefix.length) }));\n return { entries, hasMore: inner.hasMore, cursor: inner.cursor };\n }\n\n async getCompactedBelowSeq(): Promise<number> {\n return (await this.inner.getCompactedBelowSeq?.()) ?? 0;\n }\n\n /**\n * PREFIX-LOCAL read-auth (design §4.1, P0#2): authorize a cid ONLY when this\n * fragment's own sub-tree references it. Delegates with the fragment prefix\n * prepended, so app A can never read app B's object under the same user by\n * knowing the cid. The unprefixed space-root provider stays whole-scope.\n */\n async isReferenced(cid: string, pathPrefix = \"\"): Promise<boolean> {\n return this.inner.isReferenced(cid, this.prefix + pathPrefix);\n }\n\n /**\n * PREFIX-LOCAL batch read-auth (design §7.2): authorize ONLY cids this\n * fragment's own sub-tree references. Same prefix-prepend delegation as the\n * single-cid {@link isReferenced}.\n */\n async isReferencedMany(cids: string[], pathPrefix = \"\"): Promise<Set<string>> {\n return this.inner.isReferencedMany(cids, this.prefix + pathPrefix);\n }\n\n // ── Source-side dirty queue (index-follower-dirty-path §7) ──\n //\n // The blocklet-isolation boundary for dirty rows: prepend this fragment's\n // prefix on the way IN (so the inner range scan is confined to\n // `blocklets/{instanceDid}/{role}/…`, never another blocklet's rows) and\n // strip it OFF the returned `path` so the follower sees the stripped\n // `originalPath` (e.g. `items/x.json`). ack/fail re-add the full path. A\n // caller can only ever list/ack/fail dirty rows inside its own sub-tree — a\n // manual `../` or foreign full path lands OUTSIDE `[prefix, prefix+succ)` and\n // matches nothing.\n\n async listDirtyPaths(options: ListDirtyPathOptions): Promise<DirtyPathRow[]> {\n if (!this.inner.listDirtyPaths) return [];\n const rows = await this.inner.listDirtyPaths({\n ...options,\n prefix: this.prefix + options.prefix,\n });\n return rows.map((r) => ({ ...r, path: r.path.slice(this.prefix.length) }));\n }\n\n async ackDirtyPath(path: string, latestSeq: number): Promise<boolean> {\n if (!this.inner.ackDirtyPath) return false;\n return this.inner.ackDirtyPath(this.prefix + path, latestSeq);\n }\n\n async markDirtyPathError(\n path: string,\n latestSeq: number,\n error: string,\n nextAttemptAt: number,\n ): Promise<boolean> {\n if (!this.inner.markDirtyPathError) return false;\n return this.inner.markDirtyPathError(this.prefix + path, latestSeq, error, nextAttemptAt);\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
//#region src/presign-signer.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* presign-signer.ts — the object-store signing capability contract (design §7.1).
|
|
4
|
+
*
|
|
5
|
+
* A `PresignSigner` mints a single, exact-key, checksum-pinned upload grant for
|
|
6
|
+
* the object-store layer. It is an **injected dependency** (like `ObjectStore`):
|
|
7
|
+
* the provider itself never holds R2 credentials — the runtime constructs a
|
|
8
|
+
* concrete signer (CF: `R2PresignSigner` over `aws4fetch`, §15 decision 7) and
|
|
9
|
+
* injects it, or injects nothing (Node `DIDSpace` = fallback-only, §15 decision 8,
|
|
10
|
+
* so `signer === null` is a legitimate, stable state).
|
|
11
|
+
*
|
|
12
|
+
* The grant authorizes EXACTLY one object key + one `PutObject`, and pins the
|
|
13
|
+
* full-object SHA-256 checksum into the signature so a malicious client can
|
|
14
|
+
* neither change the key nor the bytes (the global CAS pool's only cross-user
|
|
15
|
+
* integrity defense — design §7.1 / §10, P0-verified in p0-measurements.md).
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* A minted presigned PUT grant. The client uploads bytes out-of-band:
|
|
19
|
+
* `fetch(url, { method, headers: signedHeaders, body })`.
|
|
20
|
+
*
|
|
21
|
+
* `signedHeaders` are the headers the client MUST resend verbatim for the
|
|
22
|
+
* signature to validate (with aws4fetch's `signQuery`, the checksum header's
|
|
23
|
+
* NAME is in `X-Amz-SignedHeaders` but its VALUE is not in the query — so the
|
|
24
|
+
* client has to send the header itself; tampering → `403`, see §8).
|
|
25
|
+
*/
|
|
26
|
+
interface PresignedPut {
|
|
27
|
+
url: string;
|
|
28
|
+
method: "PUT";
|
|
29
|
+
signedHeaders: Record<string, string>;
|
|
30
|
+
/** ISO-8601 expiry — when the presigned URL stops being accepted by R2. */
|
|
31
|
+
expiresAt: string;
|
|
32
|
+
}
|
|
33
|
+
interface PresignPutInput {
|
|
34
|
+
/** Exact object-store key, e.g. `objects/bafk...`. Pinned into the signature. */
|
|
35
|
+
objectKey: string;
|
|
36
|
+
/** base64 of the 32-byte SHA-256 digest (= the CID's multihash digest). */
|
|
37
|
+
checksumSha256: string;
|
|
38
|
+
/** URL validity in seconds (0 < n ≤ 604800; S3/R2 hard cap is 7 days). */
|
|
39
|
+
expiresInSec: number;
|
|
40
|
+
/** Optional content type to pin (currently advisory; not signed in v1). */
|
|
41
|
+
contentType?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Declared byte length (upload-limits Phase 4, anti-lie D2 = §9.2(ii)). When
|
|
44
|
+
* set, the signer pins `Content-Length` INTO the signature so R2 rejects a PUT
|
|
45
|
+
* whose body size differs (`403 SignatureDoesNotMatch`) — a client cannot
|
|
46
|
+
* declare a small size to pass the ingest-prepare cap then PUT a larger object
|
|
47
|
+
* (PRE-2 spike PASS, real R2). Omitted → no size pin (back-compat; Node has no
|
|
48
|
+
* signer so this is moot there). aws4fetch lists `content-length` as
|
|
49
|
+
* UNSIGNABLE, so the signer must opt into `allHeaders` to sign it.
|
|
50
|
+
*/
|
|
51
|
+
contentLength?: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A minted presigned GET grant (download plane, design §7.1). The client reads
|
|
55
|
+
* bytes out-of-band: `fetch(url, { method, headers: signedHeaders })`.
|
|
56
|
+
*
|
|
57
|
+
* Symmetric to {@link PresignedPut} but READ-ONLY: GET-only, exact-key, short
|
|
58
|
+
* TTL, and — unlike PUT — NO checksum is pinned. Integrity is the client's
|
|
59
|
+
* `computeCID(bytes)` self-check (design §8.1), not an R2-enforced precondition,
|
|
60
|
+
* so `signedHeaders` is normally `{}` (the host header is injected by `fetch`).
|
|
61
|
+
*/
|
|
62
|
+
interface PresignedGet {
|
|
63
|
+
url: string;
|
|
64
|
+
method: "GET";
|
|
65
|
+
signedHeaders: Record<string, string>;
|
|
66
|
+
/** ISO-8601 expiry — when the presigned URL stops being accepted by R2. */
|
|
67
|
+
expiresAt: string;
|
|
68
|
+
}
|
|
69
|
+
interface PresignGetInput {
|
|
70
|
+
/** Exact object-store key, e.g. `objects/bafk...`. Pinned into the signature. */
|
|
71
|
+
objectKey: string;
|
|
72
|
+
/** URL validity in seconds (0 < n ≤ 604800; S3/R2 hard cap is 7 days). */
|
|
73
|
+
expiresInSec: number;
|
|
74
|
+
/**
|
|
75
|
+
* Optional Content-Type to bake into the signed URL via the S3
|
|
76
|
+
* `response-content-type` query override (preview-r2-direct §3 / Review-1).
|
|
77
|
+
* Objects are stored content-addressed with NO httpMetadata, so R2 would
|
|
78
|
+
* otherwise serve them as `application/octet-stream` (a `<video>`/`<audio>`
|
|
79
|
+
* element then won't play). Set, the signer adds `response-content-type=<mime>`
|
|
80
|
+
* (+ defensive `response-content-disposition=inline`) BEFORE signing so R2
|
|
81
|
+
* honors it. OMITTED → the URL is byte-identical to the no-override form
|
|
82
|
+
* (native-sync `prepare-download` omits it → back-compatible).
|
|
83
|
+
*/
|
|
84
|
+
responseContentType?: string;
|
|
85
|
+
}
|
|
86
|
+
interface PresignSigner {
|
|
87
|
+
presignPut(input: PresignPutInput): Promise<PresignedPut>;
|
|
88
|
+
/**
|
|
89
|
+
* Mint an exact-key, short-TTL presigned GET (download plane, design §7.1).
|
|
90
|
+
* Required on every signer — its presence IS the `downloadGrantCapability`
|
|
91
|
+
* flag's `typeof signer.presignGet === "function"` basis (design §7.3).
|
|
92
|
+
*/
|
|
93
|
+
presignGet(input: PresignGetInput): Promise<PresignedGet>;
|
|
94
|
+
}
|
|
95
|
+
/** S3/R2 presigned-URL max validity (7 days, in seconds). */
|
|
96
|
+
declare const PRESIGN_MAX_EXPIRES_SEC: number;
|
|
97
|
+
//#endregion
|
|
98
|
+
export { PRESIGN_MAX_EXPIRES_SEC, PresignGetInput, PresignPutInput, PresignSigner, PresignedGet, PresignedPut };
|
|
99
|
+
//# sourceMappingURL=presign-signer.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presign-signer.d.cts","names":[],"sources":["../src/presign-signer.ts"],"mappings":";;AAyBA;;;;;;;;;;;AAQA;;;;;;;;;;;AA8BA;UAtCiB,YAAA;EACf,GAAA;EACA,MAAA;EACA,aAAA,EAAe,MAAA;EAqCf;EAnCA,SAAA;AAAA;AAAA,UAGe,eAAA;EAmCN;EAjCT,SAAA;EAoCe;EAlCf,cAAA;;EAEA,YAAA;EAkCA;EAhCA,WAAA;EA+CA;;;AAGF;;;;;;EAxCE,aAAA;AAAA;;;;;;;;;;UAYe,YAAA;EACf,GAAA;EACA,MAAA;EACA,aAAA,EAAe,MAAA;EAgCyC;EA9BxD,SAAA;AAAA;AAAA,UAGe,eAAA;;EAEf,SAAA;EA6BqD;EA3BrD,YAAA;;;;;;;;;;;EAaA,mBAAA;AAAA;AAAA,UAGe,aAAA;EACf,UAAA,CAAW,KAAA,EAAO,eAAA,GAAkB,OAAA,CAAQ,YAAA;;;;;;EAM5C,UAAA,CAAW,KAAA,EAAO,eAAA,GAAkB,OAAA,CAAQ,YAAA;AAAA;;cAIjC,uBAAA"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
//#region src/presign-signer.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* presign-signer.ts — the object-store signing capability contract (design §7.1).
|
|
4
|
+
*
|
|
5
|
+
* A `PresignSigner` mints a single, exact-key, checksum-pinned upload grant for
|
|
6
|
+
* the object-store layer. It is an **injected dependency** (like `ObjectStore`):
|
|
7
|
+
* the provider itself never holds R2 credentials — the runtime constructs a
|
|
8
|
+
* concrete signer (CF: `R2PresignSigner` over `aws4fetch`, §15 decision 7) and
|
|
9
|
+
* injects it, or injects nothing (Node `DIDSpace` = fallback-only, §15 decision 8,
|
|
10
|
+
* so `signer === null` is a legitimate, stable state).
|
|
11
|
+
*
|
|
12
|
+
* The grant authorizes EXACTLY one object key + one `PutObject`, and pins the
|
|
13
|
+
* full-object SHA-256 checksum into the signature so a malicious client can
|
|
14
|
+
* neither change the key nor the bytes (the global CAS pool's only cross-user
|
|
15
|
+
* integrity defense — design §7.1 / §10, P0-verified in p0-measurements.md).
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* A minted presigned PUT grant. The client uploads bytes out-of-band:
|
|
19
|
+
* `fetch(url, { method, headers: signedHeaders, body })`.
|
|
20
|
+
*
|
|
21
|
+
* `signedHeaders` are the headers the client MUST resend verbatim for the
|
|
22
|
+
* signature to validate (with aws4fetch's `signQuery`, the checksum header's
|
|
23
|
+
* NAME is in `X-Amz-SignedHeaders` but its VALUE is not in the query — so the
|
|
24
|
+
* client has to send the header itself; tampering → `403`, see §8).
|
|
25
|
+
*/
|
|
26
|
+
interface PresignedPut {
|
|
27
|
+
url: string;
|
|
28
|
+
method: "PUT";
|
|
29
|
+
signedHeaders: Record<string, string>;
|
|
30
|
+
/** ISO-8601 expiry — when the presigned URL stops being accepted by R2. */
|
|
31
|
+
expiresAt: string;
|
|
32
|
+
}
|
|
33
|
+
interface PresignPutInput {
|
|
34
|
+
/** Exact object-store key, e.g. `objects/bafk...`. Pinned into the signature. */
|
|
35
|
+
objectKey: string;
|
|
36
|
+
/** base64 of the 32-byte SHA-256 digest (= the CID's multihash digest). */
|
|
37
|
+
checksumSha256: string;
|
|
38
|
+
/** URL validity in seconds (0 < n ≤ 604800; S3/R2 hard cap is 7 days). */
|
|
39
|
+
expiresInSec: number;
|
|
40
|
+
/** Optional content type to pin (currently advisory; not signed in v1). */
|
|
41
|
+
contentType?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Declared byte length (upload-limits Phase 4, anti-lie D2 = §9.2(ii)). When
|
|
44
|
+
* set, the signer pins `Content-Length` INTO the signature so R2 rejects a PUT
|
|
45
|
+
* whose body size differs (`403 SignatureDoesNotMatch`) — a client cannot
|
|
46
|
+
* declare a small size to pass the ingest-prepare cap then PUT a larger object
|
|
47
|
+
* (PRE-2 spike PASS, real R2). Omitted → no size pin (back-compat; Node has no
|
|
48
|
+
* signer so this is moot there). aws4fetch lists `content-length` as
|
|
49
|
+
* UNSIGNABLE, so the signer must opt into `allHeaders` to sign it.
|
|
50
|
+
*/
|
|
51
|
+
contentLength?: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A minted presigned GET grant (download plane, design §7.1). The client reads
|
|
55
|
+
* bytes out-of-band: `fetch(url, { method, headers: signedHeaders })`.
|
|
56
|
+
*
|
|
57
|
+
* Symmetric to {@link PresignedPut} but READ-ONLY: GET-only, exact-key, short
|
|
58
|
+
* TTL, and — unlike PUT — NO checksum is pinned. Integrity is the client's
|
|
59
|
+
* `computeCID(bytes)` self-check (design §8.1), not an R2-enforced precondition,
|
|
60
|
+
* so `signedHeaders` is normally `{}` (the host header is injected by `fetch`).
|
|
61
|
+
*/
|
|
62
|
+
interface PresignedGet {
|
|
63
|
+
url: string;
|
|
64
|
+
method: "GET";
|
|
65
|
+
signedHeaders: Record<string, string>;
|
|
66
|
+
/** ISO-8601 expiry — when the presigned URL stops being accepted by R2. */
|
|
67
|
+
expiresAt: string;
|
|
68
|
+
}
|
|
69
|
+
interface PresignGetInput {
|
|
70
|
+
/** Exact object-store key, e.g. `objects/bafk...`. Pinned into the signature. */
|
|
71
|
+
objectKey: string;
|
|
72
|
+
/** URL validity in seconds (0 < n ≤ 604800; S3/R2 hard cap is 7 days). */
|
|
73
|
+
expiresInSec: number;
|
|
74
|
+
/**
|
|
75
|
+
* Optional Content-Type to bake into the signed URL via the S3
|
|
76
|
+
* `response-content-type` query override (preview-r2-direct §3 / Review-1).
|
|
77
|
+
* Objects are stored content-addressed with NO httpMetadata, so R2 would
|
|
78
|
+
* otherwise serve them as `application/octet-stream` (a `<video>`/`<audio>`
|
|
79
|
+
* element then won't play). Set, the signer adds `response-content-type=<mime>`
|
|
80
|
+
* (+ defensive `response-content-disposition=inline`) BEFORE signing so R2
|
|
81
|
+
* honors it. OMITTED → the URL is byte-identical to the no-override form
|
|
82
|
+
* (native-sync `prepare-download` omits it → back-compatible).
|
|
83
|
+
*/
|
|
84
|
+
responseContentType?: string;
|
|
85
|
+
}
|
|
86
|
+
interface PresignSigner {
|
|
87
|
+
presignPut(input: PresignPutInput): Promise<PresignedPut>;
|
|
88
|
+
/**
|
|
89
|
+
* Mint an exact-key, short-TTL presigned GET (download plane, design §7.1).
|
|
90
|
+
* Required on every signer — its presence IS the `downloadGrantCapability`
|
|
91
|
+
* flag's `typeof signer.presignGet === "function"` basis (design §7.3).
|
|
92
|
+
*/
|
|
93
|
+
presignGet(input: PresignGetInput): Promise<PresignedGet>;
|
|
94
|
+
}
|
|
95
|
+
/** S3/R2 presigned-URL max validity (7 days, in seconds). */
|
|
96
|
+
declare const PRESIGN_MAX_EXPIRES_SEC: number;
|
|
97
|
+
//#endregion
|
|
98
|
+
export { PRESIGN_MAX_EXPIRES_SEC, PresignGetInput, PresignPutInput, PresignSigner, PresignedGet, PresignedPut };
|
|
99
|
+
//# sourceMappingURL=presign-signer.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presign-signer.d.mts","names":[],"sources":["../src/presign-signer.ts"],"mappings":";;AAyBA;;;;;;;;;;;AAQA;;;;;;;;;;;AA8BA;UAtCiB,YAAA;EACf,GAAA;EACA,MAAA;EACA,aAAA,EAAe,MAAA;EAqCf;EAnCA,SAAA;AAAA;AAAA,UAGe,eAAA;EAmCN;EAjCT,SAAA;EAoCe;EAlCf,cAAA;;EAEA,YAAA;EAkCA;EAhCA,WAAA;EA+CA;;;AAGF;;;;;;EAxCE,aAAA;AAAA;;;;;;;;;;UAYe,YAAA;EACf,GAAA;EACA,MAAA;EACA,aAAA,EAAe,MAAA;EAgCyC;EA9BxD,SAAA;AAAA;AAAA,UAGe,eAAA;;EAEf,SAAA;EA6BqD;EA3BrD,YAAA;;;;;;;;;;;EAaA,mBAAA;AAAA;AAAA,UAGe,aAAA;EACf,UAAA,CAAW,KAAA,EAAO,eAAA,GAAkB,OAAA,CAAQ,YAAA;;;;;;EAM5C,UAAA,CAAW,KAAA,EAAO,eAAA,GAAkB,OAAA,CAAQ,YAAA;AAAA;;cAIjC,uBAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presign-signer.mjs","names":[],"sources":["../src/presign-signer.ts"],"sourcesContent":["/**\n * presign-signer.ts — the object-store signing capability contract (design §7.1).\n *\n * A `PresignSigner` mints a single, exact-key, checksum-pinned upload grant for\n * the object-store layer. It is an **injected dependency** (like `ObjectStore`):\n * the provider itself never holds R2 credentials — the runtime constructs a\n * concrete signer (CF: `R2PresignSigner` over `aws4fetch`, §15 decision 7) and\n * injects it, or injects nothing (Node `DIDSpace` = fallback-only, §15 decision 8,\n * so `signer === null` is a legitimate, stable state).\n *\n * The grant authorizes EXACTLY one object key + one `PutObject`, and pins the\n * full-object SHA-256 checksum into the signature so a malicious client can\n * neither change the key nor the bytes (the global CAS pool's only cross-user\n * integrity defense — design §7.1 / §10, P0-verified in p0-measurements.md).\n */\n\n/**\n * A minted presigned PUT grant. The client uploads bytes out-of-band:\n * `fetch(url, { method, headers: signedHeaders, body })`.\n *\n * `signedHeaders` are the headers the client MUST resend verbatim for the\n * signature to validate (with aws4fetch's `signQuery`, the checksum header's\n * NAME is in `X-Amz-SignedHeaders` but its VALUE is not in the query — so the\n * client has to send the header itself; tampering → `403`, see §8).\n */\nexport interface PresignedPut {\n url: string;\n method: \"PUT\";\n signedHeaders: Record<string, string>;\n /** ISO-8601 expiry — when the presigned URL stops being accepted by R2. */\n expiresAt: string;\n}\n\nexport interface PresignPutInput {\n /** Exact object-store key, e.g. `objects/bafk...`. Pinned into the signature. */\n objectKey: string;\n /** base64 of the 32-byte SHA-256 digest (= the CID's multihash digest). */\n checksumSha256: string;\n /** URL validity in seconds (0 < n ≤ 604800; S3/R2 hard cap is 7 days). */\n expiresInSec: number;\n /** Optional content type to pin (currently advisory; not signed in v1). */\n contentType?: string;\n /**\n * Declared byte length (upload-limits Phase 4, anti-lie D2 = §9.2(ii)). When\n * set, the signer pins `Content-Length` INTO the signature so R2 rejects a PUT\n * whose body size differs (`403 SignatureDoesNotMatch`) — a client cannot\n * declare a small size to pass the ingest-prepare cap then PUT a larger object\n * (PRE-2 spike PASS, real R2). Omitted → no size pin (back-compat; Node has no\n * signer so this is moot there). aws4fetch lists `content-length` as\n * UNSIGNABLE, so the signer must opt into `allHeaders` to sign it.\n */\n contentLength?: number;\n}\n\n/**\n * A minted presigned GET grant (download plane, design §7.1). The client reads\n * bytes out-of-band: `fetch(url, { method, headers: signedHeaders })`.\n *\n * Symmetric to {@link PresignedPut} but READ-ONLY: GET-only, exact-key, short\n * TTL, and — unlike PUT — NO checksum is pinned. Integrity is the client's\n * `computeCID(bytes)` self-check (design §8.1), not an R2-enforced precondition,\n * so `signedHeaders` is normally `{}` (the host header is injected by `fetch`).\n */\nexport interface PresignedGet {\n url: string;\n method: \"GET\";\n signedHeaders: Record<string, string>;\n /** ISO-8601 expiry — when the presigned URL stops being accepted by R2. */\n expiresAt: string;\n}\n\nexport interface PresignGetInput {\n /** Exact object-store key, e.g. `objects/bafk...`. Pinned into the signature. */\n objectKey: string;\n /** URL validity in seconds (0 < n ≤ 604800; S3/R2 hard cap is 7 days). */\n expiresInSec: number;\n // GET pins no checksum: integrity is verified by the client's computeCID\n // (design §8.1), not enforced by R2 — the dual of presignPut's checksum pin.\n /**\n * Optional Content-Type to bake into the signed URL via the S3\n * `response-content-type` query override (preview-r2-direct §3 / Review-1).\n * Objects are stored content-addressed with NO httpMetadata, so R2 would\n * otherwise serve them as `application/octet-stream` (a `<video>`/`<audio>`\n * element then won't play). Set, the signer adds `response-content-type=<mime>`\n * (+ defensive `response-content-disposition=inline`) BEFORE signing so R2\n * honors it. OMITTED → the URL is byte-identical to the no-override form\n * (native-sync `prepare-download` omits it → back-compatible).\n */\n responseContentType?: string;\n}\n\nexport interface PresignSigner {\n presignPut(input: PresignPutInput): Promise<PresignedPut>;\n /**\n * Mint an exact-key, short-TTL presigned GET (download plane, design §7.1).\n * Required on every signer — its presence IS the `downloadGrantCapability`\n * flag's `typeof signer.presignGet === \"function\"` basis (design §7.3).\n */\n presignGet(input: PresignGetInput): Promise<PresignedGet>;\n}\n\n/** S3/R2 presigned-URL max validity (7 days, in seconds). */\nexport const PRESIGN_MAX_EXPIRES_SEC = 7 * 24 * 60 * 60;\n"],"mappings":";;AAsGA,MAAa,0BAA0B,QAAc"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { ObjectStore, ObjectStoreHeadResult, ObjectStoreListOptions, ObjectStoreListResult, ObjectStoreObject } from "./types.mjs";
|
|
2
|
+
import { AFSAccessMode, AFSEntry, AFSExplainResult, AFSListResult, AFSSearchOptions, AFSStatResult, AFSWriteEntryPayload, CapabilitiesManifest, ProviderManifest, ProviderTreeSchema } from "@aigne/afs";
|
|
3
|
+
import { AFSBaseProvider, RouteContext } from "@aigne/afs/provider";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//#region ../../platform/r2/dist/types.d.cts
|
|
2
|
+
//#region src/types.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* ObjectStore — platform-agnostic interface for R2-compatible object storage.
|
|
5
|
+
*
|
|
6
|
+
* R2Bucket satisfies this interface natively.
|
|
7
|
+
* For Node.js testing, use MemoryObjectStore or miniflare.
|
|
8
|
+
*/
|
|
9
|
+
interface ObjectStoreObject {
|
|
10
|
+
readonly key: string;
|
|
11
|
+
readonly size: number;
|
|
12
|
+
readonly uploaded: Date;
|
|
13
|
+
/** Custom metadata (R2 httpMetadata or custom) */
|
|
14
|
+
readonly customMetadata?: Record<string, string>;
|
|
15
|
+
text(): Promise<string>;
|
|
16
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
17
|
+
}
|
|
18
|
+
interface ObjectStoreHeadResult {
|
|
19
|
+
readonly key: string;
|
|
20
|
+
readonly size: number;
|
|
21
|
+
readonly uploaded: Date;
|
|
22
|
+
readonly customMetadata?: Record<string, string>;
|
|
23
|
+
}
|
|
24
|
+
interface ObjectStoreListResult {
|
|
25
|
+
readonly objects: ReadonlyArray<{
|
|
26
|
+
readonly key: string;
|
|
27
|
+
readonly size: number;
|
|
28
|
+
readonly uploaded: Date;
|
|
29
|
+
readonly customMetadata?: Record<string, string>;
|
|
30
|
+
}>;
|
|
31
|
+
readonly truncated: boolean;
|
|
32
|
+
readonly cursor?: string;
|
|
33
|
+
}
|
|
34
|
+
interface ObjectStoreListOptions {
|
|
35
|
+
prefix?: string;
|
|
36
|
+
cursor?: string;
|
|
37
|
+
limit?: number;
|
|
38
|
+
delimiter?: string;
|
|
39
|
+
}
|
|
40
|
+
interface ObjectStore {
|
|
41
|
+
get(key: string): Promise<ObjectStoreObject | null>;
|
|
42
|
+
put(key: string, value: string | ArrayBuffer | ReadableStream): Promise<void>;
|
|
43
|
+
list(options?: ObjectStoreListOptions): Promise<ObjectStoreListResult>;
|
|
44
|
+
head(key: string): Promise<ObjectStoreHeadResult | null>;
|
|
45
|
+
delete(key: string): Promise<void>;
|
|
46
|
+
} //#endregion
|
|
47
|
+
//#endregion
|
|
48
|
+
export { ObjectStore, ObjectStoreHeadResult, ObjectStoreListOptions, ObjectStoreListResult, ObjectStoreObject };
|
|
49
|
+
//# sourceMappingURL=types.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":["ObjectStoreObject","Date","Record","Promise","ArrayBuffer","key","size","uploaded","customMetadata","text","arrayBuffer","ObjectStoreHeadResult","ObjectStoreListResult","ReadonlyArray","objects","truncated","cursor","ObjectStoreListOptions","prefix","limit","delimiter","ObjectStore","ReadableStream","get","put","value","list","options","head","delete"],"sources":["../../../../../../../platform/r2/dist/types.d.cts"],"mappings":";;;;;;;;UAOUA,iBAAAA;EAAAA,SACCK,GAAAA;EAAAA,SACAC,IAAAA;EAAAA,SACAC,QAAAA,EAAUN,IAAAA;EAFVI;EAAAA,SAIAG,cAAAA,GAAiBN,MAAAA;EAC1BO,IAAAA,IAAQN,OAAAA;EACRO,WAAAA,IAAeP,OAAAA,CAAQC,WAAAA;AAAAA;AAAAA,UAEfO,qBAAAA;EAAAA,SACCN,GAAAA;EAAAA,SACAC,IAAAA;EAAAA,SACAC,QAAAA,EAAUN,IAAAA;EAAAA,SACVO,cAAAA,GAAiBN,MAAAA;AAAAA;AAAAA,UAElBU,qBAAAA;EAAAA,SACCE,OAAAA,EAASD,aAAAA;IAAAA,SACPR,GAAAA;IAAAA,SACAC,IAAAA;IAAAA,SACAC,QAAAA,EAAUN,IAAAA;IAAAA,SACVO,cAAAA,GAAiBN,MAAAA;EAAAA;EAAAA,SAEnBa,SAAAA;EAAAA,SACAC,MAAAA;AAAAA;AAAAA,UAEDC,sBAAAA;EACRC,MAAAA;EACAF,MAAAA;EACAG,KAAAA;EACAC,SAAAA;AAAAA;AAAAA,UAEQC,WAAAA;EACRE,GAAAA,CAAIlB,GAAAA,WAAcF,OAAAA,CAAQH,iBAAAA;EAC1BwB,GAAAA,CAAInB,GAAAA,UAAaoB,KAAAA,WAAgBrB,WAAAA,GAAckB,cAAAA,GAAiBnB,OAAAA;EAChEuB,IAAAA,CAAKC,OAAAA,GAAUV,sBAAAA,GAAyBd,OAAAA,CAAQS,qBAAAA;EAChDgB,IAAAA,CAAKvB,GAAAA,WAAcF,OAAAA,CAAQQ,qBAAAA;EAC3BkB,MAAAA,CAAOxB,GAAAA,WAAcF,OAAAA;AAAAA"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_cid = require('./cid.cjs');
|
|
3
|
+
let node_fs = require("node:fs");
|
|
4
|
+
let node_path = require("node:path");
|
|
5
|
+
|
|
6
|
+
//#region src/reconcile.ts
|
|
7
|
+
/**
|
|
8
|
+
* DIDSpace reconcile engine — Phase 2 (Task 2.2)
|
|
9
|
+
*
|
|
10
|
+
* Compares the local filesystem against _metadata.db and brings the index
|
|
11
|
+
* up to date without reading file content unless necessary.
|
|
12
|
+
*
|
|
13
|
+
* Algorithm (scalability-design §七):
|
|
14
|
+
* 1. Walk filesystem (stat only) — O(n) syscalls, no file reads
|
|
15
|
+
* 2. Read index from _metadata.db — single SQL query
|
|
16
|
+
* 3. Three-way compare per file:
|
|
17
|
+
* - NEW: in FS, not in DB → read file, computeCID, INSERT
|
|
18
|
+
* - MODIFIED: in both, mtime or size differ → re-read, computeCID, UPDATE
|
|
19
|
+
* - UNCHANGED: in both, mtime+size same → skip (CID cache hit)
|
|
20
|
+
* - DELETED: in DB, not in FS → DELETE from entries
|
|
21
|
+
* 4. Batch-update entries + cid_cache
|
|
22
|
+
*/
|
|
23
|
+
/** File names/patterns to exclude from reconcile */
|
|
24
|
+
const EXCLUDED_NAMES = new Set([
|
|
25
|
+
"_metadata.db",
|
|
26
|
+
"_metadata.db-wal",
|
|
27
|
+
"_metadata.db-shm"
|
|
28
|
+
]);
|
|
29
|
+
/** Directory names to skip entirely (they contain sensitive/internal data) */
|
|
30
|
+
const EXCLUDED_DIRS = new Set(["vault", "config"]);
|
|
31
|
+
function isExcluded(name) {
|
|
32
|
+
if (EXCLUDED_NAMES.has(name)) return true;
|
|
33
|
+
if (name.startsWith("data.db")) return true;
|
|
34
|
+
if (name.endsWith("-wal") || name.endsWith("-shm") || name.endsWith("-journal")) return true;
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
/** Convert an absolute filesystem path to a relative AFS-style path (no leading slash). */
|
|
38
|
+
function fsPathToRelative(rootPath, absPath) {
|
|
39
|
+
const rel = (0, node_path.relative)(rootPath, absPath);
|
|
40
|
+
return node_path.sep === "\\" ? rel.replace(/\\/g, "/") : rel;
|
|
41
|
+
}
|
|
42
|
+
function walkFs(rootPath, dir, depth) {
|
|
43
|
+
const results = [];
|
|
44
|
+
let entries;
|
|
45
|
+
try {
|
|
46
|
+
entries = (0, node_fs.readdirSync)(dir, { withFileTypes: true });
|
|
47
|
+
} catch {
|
|
48
|
+
return results;
|
|
49
|
+
}
|
|
50
|
+
for (const entry of entries) {
|
|
51
|
+
if (entry.name.startsWith(".")) continue;
|
|
52
|
+
if (isExcluded(entry.name)) continue;
|
|
53
|
+
const absPath = (0, node_path.join)(dir, entry.name);
|
|
54
|
+
if (entry.isSymbolicLink()) continue;
|
|
55
|
+
if (entry.isDirectory()) {
|
|
56
|
+
if (EXCLUDED_DIRS.has(entry.name)) continue;
|
|
57
|
+
results.push(...walkFs(rootPath, absPath, depth + 1));
|
|
58
|
+
} else if (entry.isFile()) {
|
|
59
|
+
if (depth === 0) continue;
|
|
60
|
+
let st;
|
|
61
|
+
try {
|
|
62
|
+
st = (0, node_fs.statSync)(absPath);
|
|
63
|
+
} catch {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
results.push({
|
|
67
|
+
absPath,
|
|
68
|
+
relPath: fsPathToRelative(rootPath, absPath),
|
|
69
|
+
size: st.size,
|
|
70
|
+
mtimeMs: Math.floor(st.mtimeMs)
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return results;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Derive the `parent` path for a given file/dir path (no leading slash convention).
|
|
78
|
+
*
|
|
79
|
+
* Examples:
|
|
80
|
+
* "appA/files/hello.txt" → "appA/files/"
|
|
81
|
+
* "appA/files/" → "appA/"
|
|
82
|
+
* "appA/" → ""
|
|
83
|
+
*/
|
|
84
|
+
function parentOf(path) {
|
|
85
|
+
const p = path.endsWith("/") ? path.slice(0, -1) : path;
|
|
86
|
+
const idx = p.lastIndexOf("/");
|
|
87
|
+
if (idx < 0) return "";
|
|
88
|
+
return p.slice(0, idx + 1);
|
|
89
|
+
}
|
|
90
|
+
/** Derive the basename (name) from a path (no leading slash convention). */
|
|
91
|
+
function nameOf(path) {
|
|
92
|
+
const p = path.endsWith("/") ? path.slice(0, -1) : path;
|
|
93
|
+
const idx = p.lastIndexOf("/");
|
|
94
|
+
return idx < 0 ? p : p.slice(idx + 1);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Reconcile the local filesystem against _metadata.db.
|
|
98
|
+
* Returns stats about the reconcile operation.
|
|
99
|
+
*/
|
|
100
|
+
async function reconcile(options) {
|
|
101
|
+
const { rootPath, scope, metadataDb } = options;
|
|
102
|
+
const start = Date.now();
|
|
103
|
+
const fsFiles = walkFs(rootPath, rootPath, 0);
|
|
104
|
+
const fsMap = /* @__PURE__ */ new Map();
|
|
105
|
+
for (const f of fsFiles) fsMap.set(f.relPath, {
|
|
106
|
+
size: f.size,
|
|
107
|
+
mtimeMs: f.mtimeMs,
|
|
108
|
+
absPath: f.absPath
|
|
109
|
+
});
|
|
110
|
+
const dbFiles = await metadataDb.getFiles(scope);
|
|
111
|
+
const dbMap = /* @__PURE__ */ new Map();
|
|
112
|
+
for (const row of dbFiles) dbMap.set(row.path, row);
|
|
113
|
+
const toUpsert = [];
|
|
114
|
+
const toDelete = [];
|
|
115
|
+
const now = Date.now();
|
|
116
|
+
let added = 0;
|
|
117
|
+
let modified = 0;
|
|
118
|
+
let unchanged = 0;
|
|
119
|
+
for (const [relPath, fsInfo] of fsMap) {
|
|
120
|
+
const dbEntry = dbMap.get(relPath);
|
|
121
|
+
if (!dbEntry) {
|
|
122
|
+
const cid = await computeCidWithCache(metadataDb, fsInfo.absPath, fsInfo.size, fsInfo.mtimeMs);
|
|
123
|
+
toUpsert.push({
|
|
124
|
+
scope,
|
|
125
|
+
path: relPath,
|
|
126
|
+
parent: parentOf(relPath),
|
|
127
|
+
name: nameOf(relPath),
|
|
128
|
+
kind: "file",
|
|
129
|
+
cid,
|
|
130
|
+
size: fsInfo.size,
|
|
131
|
+
mime_type: null,
|
|
132
|
+
ctime: now,
|
|
133
|
+
mtime: fsInfo.mtimeMs
|
|
134
|
+
});
|
|
135
|
+
added++;
|
|
136
|
+
} else if (fsInfo.size !== dbEntry.size || fsInfo.mtimeMs !== dbEntry.mtime) {
|
|
137
|
+
const cid = await computeCidWithCache(metadataDb, fsInfo.absPath, fsInfo.size, fsInfo.mtimeMs);
|
|
138
|
+
toUpsert.push({
|
|
139
|
+
...dbEntry,
|
|
140
|
+
cid,
|
|
141
|
+
size: fsInfo.size,
|
|
142
|
+
mtime: fsInfo.mtimeMs
|
|
143
|
+
});
|
|
144
|
+
modified++;
|
|
145
|
+
} else unchanged++;
|
|
146
|
+
}
|
|
147
|
+
for (const [dbPath] of dbMap) if (!fsMap.has(dbPath)) toDelete.push(dbPath);
|
|
148
|
+
const reconcileOpts = { deviceId: "desktop:default" };
|
|
149
|
+
if (toUpsert.length > 0) for (let i = 0; i < toUpsert.length; i += 500) await metadataDb.upsertEntries(toUpsert.slice(i, i + 500), reconcileOpts);
|
|
150
|
+
for (const path of toDelete) await metadataDb.deleteEntry(scope, path, reconcileOpts);
|
|
151
|
+
return {
|
|
152
|
+
added,
|
|
153
|
+
modified,
|
|
154
|
+
unchanged,
|
|
155
|
+
deleted: toDelete.length,
|
|
156
|
+
elapsed: Date.now() - start
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get CID for a file — use cid_cache if mtime+size match, else compute and cache.
|
|
161
|
+
*/
|
|
162
|
+
async function computeCidWithCache(metadataDb, absPath, size, mtimeMs) {
|
|
163
|
+
const cached = await metadataDb.getCidCache(absPath);
|
|
164
|
+
if (cached && cached.mtime_ms === mtimeMs && cached.size === size) return cached.cid;
|
|
165
|
+
let content;
|
|
166
|
+
try {
|
|
167
|
+
const buf = (0, node_fs.readFileSync)(absPath);
|
|
168
|
+
content = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
169
|
+
} catch {
|
|
170
|
+
content = new Uint8Array(0);
|
|
171
|
+
}
|
|
172
|
+
const cid = await require_cid.computeCID(content);
|
|
173
|
+
await metadataDb.setCidCache({
|
|
174
|
+
path: absPath,
|
|
175
|
+
cid,
|
|
176
|
+
size,
|
|
177
|
+
mtime_ms: mtimeMs,
|
|
178
|
+
computed_at: Date.now()
|
|
179
|
+
});
|
|
180
|
+
return cid;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
//#endregion
|
|
184
|
+
exports.reconcile = reconcile;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { MetadataDB } from "./metadata-db.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/reconcile.d.ts
|
|
4
|
+
interface ReconcileOptions {
|
|
5
|
+
/** Root directory of the user's DID space (e.g. ~/.afs/spaces/{userDid}/) */
|
|
6
|
+
rootPath: string;
|
|
7
|
+
/** userDid used as scope in the entries table */
|
|
8
|
+
scope: string;
|
|
9
|
+
/** MetadataDB instance (already opened) */
|
|
10
|
+
metadataDb: MetadataDB;
|
|
11
|
+
}
|
|
12
|
+
interface ReconcileStats {
|
|
13
|
+
added: number;
|
|
14
|
+
modified: number;
|
|
15
|
+
unchanged: number;
|
|
16
|
+
deleted: number;
|
|
17
|
+
elapsed: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Reconcile the local filesystem against _metadata.db.
|
|
21
|
+
* Returns stats about the reconcile operation.
|
|
22
|
+
*/
|
|
23
|
+
declare function reconcile(options: ReconcileOptions): Promise<ReconcileStats>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { ReconcileOptions, ReconcileStats, reconcile };
|
|
26
|
+
//# sourceMappingURL=reconcile.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.d.cts","names":[],"sources":["../src/reconcile.ts"],"mappings":";;;UAwBiB,gBAAA;EAWf;EATA,QAAA;EAWA;EATA,KAAA;EAUO;EARP,UAAA,EAAY,UAAA;AAAA;AAAA,UAGG,cAAA;EACf,KAAA;EACA,QAAA;EACA,SAAA;EACA,OAAA;EACA,OAAA;AAAA;;;;;iBAiHoB,SAAA,CAAU,OAAA,EAAS,gBAAA,GAAmB,OAAA,CAAQ,cAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { MetadataDB } from "./metadata-db.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/reconcile.d.ts
|
|
4
|
+
interface ReconcileOptions {
|
|
5
|
+
/** Root directory of the user's DID space (e.g. ~/.afs/spaces/{userDid}/) */
|
|
6
|
+
rootPath: string;
|
|
7
|
+
/** userDid used as scope in the entries table */
|
|
8
|
+
scope: string;
|
|
9
|
+
/** MetadataDB instance (already opened) */
|
|
10
|
+
metadataDb: MetadataDB;
|
|
11
|
+
}
|
|
12
|
+
interface ReconcileStats {
|
|
13
|
+
added: number;
|
|
14
|
+
modified: number;
|
|
15
|
+
unchanged: number;
|
|
16
|
+
deleted: number;
|
|
17
|
+
elapsed: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Reconcile the local filesystem against _metadata.db.
|
|
21
|
+
* Returns stats about the reconcile operation.
|
|
22
|
+
*/
|
|
23
|
+
declare function reconcile(options: ReconcileOptions): Promise<ReconcileStats>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { ReconcileOptions, ReconcileStats, reconcile };
|
|
26
|
+
//# sourceMappingURL=reconcile.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.d.mts","names":[],"sources":["../src/reconcile.ts"],"mappings":";;;UAwBiB,gBAAA;EAWf;EATA,QAAA;EAWA;EATA,KAAA;EAUO;EARP,UAAA,EAAY,UAAA;AAAA;AAAA,UAGG,cAAA;EACf,KAAA;EACA,QAAA;EACA,SAAA;EACA,OAAA;EACA,OAAA;AAAA;;;;;iBAiHoB,SAAA,CAAU,OAAA,EAAS,gBAAA,GAAmB,OAAA,CAAQ,cAAA"}
|