@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,648 @@
|
|
|
1
|
+
import { buildKeysetCursor, buildOrderedQueryParts, compareTreeSortValues, keysetAfter, parseTreeCursor, parseTreeEntryMetadata } from "./tree-index.mjs";
|
|
2
|
+
import { AFSValidationError, TIME_BUCKET_KEY, aggregateGroupKeyNames, evaluateCollectionQuery, normalizeWhere, resolveFieldPath, whereMatchesItem } from "@aigne/afs";
|
|
3
|
+
|
|
4
|
+
//#region src/tree-query.ts
|
|
5
|
+
/**
|
|
6
|
+
* TreeQuery — the shared collection-query engine for the did-space TreeIndex
|
|
7
|
+
* family (afs-collection-query Phase 1, design §3.5).
|
|
8
|
+
*
|
|
9
|
+
* One compilation layer, three executors:
|
|
10
|
+
* - SQL builder (`buildTreeQueryStatements`) shared verbatim by
|
|
11
|
+
* SQLiteTreeIndex and (Phase 2) D1TreeIndex — identical dialect
|
|
12
|
+
* (json_extract / json_each / json_type all available on both).
|
|
13
|
+
* - JS executor (`runTreeQueryInMemory`) for MemoryTreeIndex, built on the
|
|
14
|
+
* SAME helpers the SQL path uses for ordering/keyset (`tree-index.ts`) and
|
|
15
|
+
* the canonical core `where` semantics (`whereMatches` from @aigne/afs) —
|
|
16
|
+
* conformance + the lockstep test pin all backends to one behavior.
|
|
17
|
+
*
|
|
18
|
+
* Semantics contract (must match `evaluateCollectionQuery` in @aigne/afs):
|
|
19
|
+
* - string comparisons fold case; numbers/booleans are type-strict
|
|
20
|
+
* - `notIn` includes records where the field is missing/null
|
|
21
|
+
* - `contains` requires an array field; missing/non-array never match
|
|
22
|
+
* - groupBy unnests arrays; missing/null/non-primitive group under `null`;
|
|
23
|
+
* string group keys are folded to lower case
|
|
24
|
+
* - keyset cursor: v2 format shared with list (`v2:<b64>:<b64>`), tie on the
|
|
25
|
+
* child's unique `name`; WHERE applies before pagination so total is the
|
|
26
|
+
* exact filtered count
|
|
27
|
+
*/
|
|
28
|
+
const ENGINE_ORDER_COLUMNS = {
|
|
29
|
+
name: "name",
|
|
30
|
+
path: "path",
|
|
31
|
+
size: "size",
|
|
32
|
+
ctime: "ctime",
|
|
33
|
+
mtime: "mtime",
|
|
34
|
+
mimeType: "mime_type"
|
|
35
|
+
};
|
|
36
|
+
const DEFAULT_QUERY_LIMIT = 1e3;
|
|
37
|
+
/**
|
|
38
|
+
* Provider-level constraints on the (already core-validated) spec that the
|
|
39
|
+
* tree engine enforces uniformly. Strict contract: reject, never ignore.
|
|
40
|
+
*
|
|
41
|
+
* Aggregate-mode orderBy is a totally different field set (group keys +
|
|
42
|
+
* `as` names) — those have already been validated by the core; nothing
|
|
43
|
+
* more for the engine to assert here.
|
|
44
|
+
*/
|
|
45
|
+
function assertTreeQuerySpec(spec) {
|
|
46
|
+
if (spec.text !== void 0) throw new AFSValidationError("Invalid query spec: text: not supported by this provider");
|
|
47
|
+
if (spec.aggregations) return;
|
|
48
|
+
if (spec.orderBy && spec.orderBy.length > 1) throw new AFSValidationError("Invalid query spec: orderBy: this provider supports a single sort key");
|
|
49
|
+
const field = spec.orderBy?.[0]?.[0];
|
|
50
|
+
if (field !== void 0 && !ENGINE_ORDER_COLUMNS[field] && !field.startsWith("meta.")) throw new AFSValidationError(`Invalid query spec: orderBy: unsupported field ${field}`);
|
|
51
|
+
}
|
|
52
|
+
/** Effective single sort key: requested tuple or the children default (name asc). */
|
|
53
|
+
function effectiveOrder(spec) {
|
|
54
|
+
const tuple = spec.orderBy?.[0];
|
|
55
|
+
return {
|
|
56
|
+
field: tuple?.[0] ?? "name",
|
|
57
|
+
order: tuple?.[1] ?? "asc"
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** Quoted JSON path for a core-validated dot-path (segments are [\w-]+). */
|
|
61
|
+
function jsonPathOf(field) {
|
|
62
|
+
return `$.${field.split(".").map((seg) => `"${seg}"`).join(".")}`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Resolve a where/orderBy field to its source JSON column expression and the
|
|
66
|
+
* `$.path` argument to `json_extract`. `meta.*` paths dispatch to the
|
|
67
|
+
* `entries.metadata` column (planning/agent-hub/metadata-foundation.md);
|
|
68
|
+
* everything else stays on the record (inline content JSON).
|
|
69
|
+
*
|
|
70
|
+
* `doc` (doc-mode = dir-per-record) decides where `meta.*` reads from:
|
|
71
|
+
* application metadata is persisted on the FILE row (`cf.metadata`), not on
|
|
72
|
+
* the parent dir row (`e.metadata`), so a doc-mode meta.* filter MUST read
|
|
73
|
+
* `cf` first and fall back to the dir row — the SAME precedence the orderBy
|
|
74
|
+
* path already uses (`COALESCE(cf.metadata, e.metadata)`). Without this a
|
|
75
|
+
* meta.* WHERE/groupBy/aggregate on a `{uuid}/item.json` collection reads the
|
|
76
|
+
* dir row's (always NULL) metadata and never matches. In file mode `e` IS the
|
|
77
|
+
* record file, so `e.metadata` is correct and `cf` doesn't exist in the FROM.
|
|
78
|
+
*/
|
|
79
|
+
function fieldSource(field, rec, doc) {
|
|
80
|
+
if (field.startsWith("meta.")) return {
|
|
81
|
+
src: doc ? "COALESCE(cf.metadata, e.metadata)" : "e.metadata",
|
|
82
|
+
path: jsonPathOf(field.slice(5))
|
|
83
|
+
};
|
|
84
|
+
return {
|
|
85
|
+
src: rec,
|
|
86
|
+
path: jsonPathOf(field)
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Compile one where leaf against the record expression. Type-strict by spec
|
|
91
|
+
* value type, case-folded for strings — mirrors `whereMatches`.
|
|
92
|
+
*/
|
|
93
|
+
function compileLeaf(rec, leaf, doc) {
|
|
94
|
+
const { src, path: p } = fieldSource(leaf.field, rec, doc);
|
|
95
|
+
const eqCond = (value) => {
|
|
96
|
+
if (typeof value === "boolean") return {
|
|
97
|
+
sql: `json_type(${src}, ?) = '${value ? "true" : "false"}'`,
|
|
98
|
+
args: [p]
|
|
99
|
+
};
|
|
100
|
+
if (typeof value === "number") return {
|
|
101
|
+
sql: `(json_type(${src}, ?) IN ('integer','real') AND json_extract(${src}, ?) = ?)`,
|
|
102
|
+
args: [
|
|
103
|
+
p,
|
|
104
|
+
p,
|
|
105
|
+
value
|
|
106
|
+
]
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
sql: `(json_type(${src}, ?) = 'text' AND lower(json_extract(${src}, ?)) = lower(?))`,
|
|
110
|
+
args: [
|
|
111
|
+
p,
|
|
112
|
+
p,
|
|
113
|
+
value
|
|
114
|
+
]
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
if ("eq" in leaf) return eqCond(leaf.eq);
|
|
118
|
+
if ("in" in leaf || "notIn" in leaf) {
|
|
119
|
+
const parts = (leaf.in ?? leaf.notIn).map((v) => eqCond(v));
|
|
120
|
+
const inSql = `(${parts.map((f) => f.sql).join(" OR ")})`;
|
|
121
|
+
const inArgs = parts.flatMap((f) => f.args);
|
|
122
|
+
if ("in" in leaf) return {
|
|
123
|
+
sql: inSql,
|
|
124
|
+
args: inArgs
|
|
125
|
+
};
|
|
126
|
+
return {
|
|
127
|
+
sql: `(json_type(${src}, ?) IS NULL OR json_type(${src}, ?) = 'null' OR NOT ${inSql})`,
|
|
128
|
+
args: [
|
|
129
|
+
p,
|
|
130
|
+
p,
|
|
131
|
+
...inArgs
|
|
132
|
+
]
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if ("contains" in leaf) {
|
|
136
|
+
const v = leaf.contains;
|
|
137
|
+
const member = typeof v === "number" ? {
|
|
138
|
+
sql: `(je.type IN ('integer','real') AND je.value = ?)`,
|
|
139
|
+
args: [v]
|
|
140
|
+
} : {
|
|
141
|
+
sql: `(je.type = 'text' AND lower(je.value) = lower(?))`,
|
|
142
|
+
args: [v]
|
|
143
|
+
};
|
|
144
|
+
return {
|
|
145
|
+
sql: `(json_type(${src}, ?) = 'array' AND EXISTS (SELECT 1 FROM json_each(json_extract(${src}, ?)) je WHERE ${member.sql}))`,
|
|
146
|
+
args: [
|
|
147
|
+
p,
|
|
148
|
+
p,
|
|
149
|
+
...member.args
|
|
150
|
+
]
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const op = "gte" in leaf ? ">=" : "<=";
|
|
154
|
+
const bound = "gte" in leaf ? leaf.gte : leaf.lte;
|
|
155
|
+
if (typeof bound === "number") return {
|
|
156
|
+
sql: `(json_type(${src}, ?) IN ('integer','real') AND json_extract(${src}, ?) ${op} ?)`,
|
|
157
|
+
args: [
|
|
158
|
+
p,
|
|
159
|
+
p,
|
|
160
|
+
bound
|
|
161
|
+
]
|
|
162
|
+
};
|
|
163
|
+
return {
|
|
164
|
+
sql: `(json_type(${src}, ?) = 'text' AND lower(json_extract(${src}, ?)) ${op} lower(?))`,
|
|
165
|
+
args: [
|
|
166
|
+
p,
|
|
167
|
+
p,
|
|
168
|
+
bound
|
|
169
|
+
]
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Build the three statements (page rows / exact count / optional groups) for
|
|
174
|
+
* a collection query over direct children of `parent` in `scope`.
|
|
175
|
+
*
|
|
176
|
+
* Candidate rows:
|
|
177
|
+
* - doc form: ALL direct children; record = LEFT-JOINed `<dir>/<doc>` inline
|
|
178
|
+
* content (file children have no record — `notIn` still matches them, the
|
|
179
|
+
* same as the reference evaluator's missing-field semantics).
|
|
180
|
+
* - file form: direct FILE children; record = the row's own inline content.
|
|
181
|
+
*
|
|
182
|
+
* Malformed/missing inline JSON collapses to NULL record (json_valid guard),
|
|
183
|
+
* never an engine error.
|
|
184
|
+
*/
|
|
185
|
+
/**
|
|
186
|
+
* THE single source of the children-candidates FROM clause — the doc
|
|
187
|
+
* sub-file LEFT JOIN used by the query engine (`listChildren` shares it in
|
|
188
|
+
* the join-free `buildChildrenFrom(undefined)` form post-T4.3), so the
|
|
189
|
+
* dir-per-record join condition can never drift. The `e.kind = 'dir'` join
|
|
190
|
+
* condition is
|
|
191
|
+
* load-bearing: without it a FILE row `items/foo` would join
|
|
192
|
+
* `items/fooitem.json` if such a path happened to exist.
|
|
193
|
+
*/
|
|
194
|
+
const CHILDREN_INDEX = "idx_entries_children";
|
|
195
|
+
/**
|
|
196
|
+
* Index that serves `ORDER BY <field>` NATIVELY for a `(scope, parent)`
|
|
197
|
+
* children query (E-S-R rule: equality columns then the sort column). ctime /
|
|
198
|
+
* mtime each have a matching `(scope, parent, <col>, name)` index so the sort
|
|
199
|
+
* is index-only and `LIMIT` terminates early instead of reading the whole
|
|
200
|
+
* directory into a temp b-tree. name / size / mimeType / meta.* have no such
|
|
201
|
+
* index → keep `idx_entries_children` (they still sort, but that is unchanged
|
|
202
|
+
* pre-existing behavior, not the aside feed's hot ctime path).
|
|
203
|
+
*
|
|
204
|
+
* Guard: `idx_entries_children` alone forces the (scope,parent,name) index,
|
|
205
|
+
* which cannot order by ctime — so it silently reintroduced the exact
|
|
206
|
+
* `USE TEMP B-TREE FOR ORDER BY` full-directory scan feed-sort-createdat
|
|
207
|
+
* removed (regression caught by e2e-driver-s3-orderby). This routes the ROWS
|
|
208
|
+
* query back onto the ordered index; the count/groups/aggregate FROM keeps the
|
|
209
|
+
* children index (no ORDER BY there — the children hint bounds correctly).
|
|
210
|
+
*/
|
|
211
|
+
function orderedChildrenIndex(orderField) {
|
|
212
|
+
if (orderField === "ctime") return "idx_entries_parent_ctime";
|
|
213
|
+
if (orderField === "mtime") return "idx_entries_parent_mtime";
|
|
214
|
+
return CHILDREN_INDEX;
|
|
215
|
+
}
|
|
216
|
+
function buildChildrenFrom(docFile, indexName = CHILDREN_INDEX) {
|
|
217
|
+
const hint = ` INDEXED BY ${indexName}`;
|
|
218
|
+
if (!docFile) return {
|
|
219
|
+
sql: `FROM ds_entries e${hint}`,
|
|
220
|
+
args: []
|
|
221
|
+
};
|
|
222
|
+
return {
|
|
223
|
+
sql: `FROM ds_entries e${hint} LEFT JOIN ds_entries cf ON e.kind = 'dir' AND cf.scope = e.scope AND cf.path = e.path || ?`,
|
|
224
|
+
args: [docFile]
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* SQL expression producing the canonical `time_bucket` string for a unix-ms
|
|
229
|
+
* source expression. Matches the JS `bucketizeTimestamp()` shape exactly so
|
|
230
|
+
* SQL ↔ memory backends stay byte-equal in the lockstep test:
|
|
231
|
+
*
|
|
232
|
+
* - `day` / `month` / `year` map to direct `strftime` formats.
|
|
233
|
+
* - `week` produces ISO 8601 `YYYY-Www` via a Thursday-anchor formula. SQLite
|
|
234
|
+
* has no `%V`, so we shift the date to its ISO Thursday with the
|
|
235
|
+
* `'-3 days', 'weekday 4'` modifier pair, then count weeks from Jan-4's
|
|
236
|
+
* Thursday of that ISO year (which is always in ISO week 1).
|
|
237
|
+
*
|
|
238
|
+
* `srcExpr` MUST be a SQL expression evaluating to a unix-ms integer (caller
|
|
239
|
+
* guarantees — we wrap with `cast(... as integer) / 1000` for the
|
|
240
|
+
* `'unixepoch'` modifier).
|
|
241
|
+
*/
|
|
242
|
+
function buildTimeBucketExpr(srcExpr, granularity) {
|
|
243
|
+
const unix = `(cast(${srcExpr} as integer) / 1000)`;
|
|
244
|
+
switch (granularity) {
|
|
245
|
+
case "day": return `strftime('%Y-%m-%d', ${unix}, 'unixepoch')`;
|
|
246
|
+
case "month": return `strftime('%Y-%m', ${unix}, 'unixepoch')`;
|
|
247
|
+
case "year": return `strftime('%Y', ${unix}, 'unixepoch')`;
|
|
248
|
+
case "week": {
|
|
249
|
+
const thu = `date(${unix}, 'unixepoch', '-3 days', 'weekday 4')`;
|
|
250
|
+
const isoYear = `strftime('%Y', ${thu})`;
|
|
251
|
+
return `(${isoYear} || '-W' || printf('%02d', ${`cast(((julianday(${thu}) - julianday(${`date(${isoYear} || '-01-04', '-3 days', 'weekday 4')`})) / 7) + 1 as integer)`}))`;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Resolve a group-key dimension name to a SQL expression. `time_bucket` is
|
|
257
|
+
* synthesized from `spec.timeBucketField` (default `meta.timestamp`).
|
|
258
|
+
* Everything else is a field dot-path that goes through `fieldSource()` so
|
|
259
|
+
* `meta.*` lands on `entries.metadata` and content paths stay on the
|
|
260
|
+
* record. Returns the column expression and (for `time_bucket`) any
|
|
261
|
+
* pre-extraction expression with the granularity baked in.
|
|
262
|
+
*/
|
|
263
|
+
function groupKeyExpr(name, spec, rec) {
|
|
264
|
+
const doc = !!spec.doc;
|
|
265
|
+
if (name === TIME_BUCKET_KEY) {
|
|
266
|
+
const { src: src$1, path: p$1 } = fieldSource(spec.timeBucketField ?? "meta.timestamp", rec, doc);
|
|
267
|
+
return buildTimeBucketExpr(`json_extract(${src$1}, '${p$1}')`, spec.timeGranularity);
|
|
268
|
+
}
|
|
269
|
+
const { src, path: p } = fieldSource(name, rec, doc);
|
|
270
|
+
return `json_extract(${src}, '${p}')`;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Compile one aggregation op to its SQL expression. Numeric ops cast to
|
|
274
|
+
* REAL to match the JS reference's `Number(v)` semantics — non-numeric
|
|
275
|
+
* strings/null collapse to 0, BigNumber.toString() roundtrips correctly.
|
|
276
|
+
* `count` is `COUNT(*)` (counts rows, including those with NULL fields).
|
|
277
|
+
*/
|
|
278
|
+
function aggregateOpExpr(op, rec, doc) {
|
|
279
|
+
if (op.op === "count") return "COUNT(*)";
|
|
280
|
+
const { src, path: p } = fieldSource(op.field, rec, doc);
|
|
281
|
+
const num = `CAST(json_extract(${src}, '${p}') AS REAL)`;
|
|
282
|
+
switch (op.op) {
|
|
283
|
+
case "sum": return `COALESCE(SUM(${num}), 0)`;
|
|
284
|
+
case "avg": return `AVG(${num})`;
|
|
285
|
+
case "max": return `MAX(${num})`;
|
|
286
|
+
case "min": return `MIN(${num})`;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function buildTreeQueryStatements(opts) {
|
|
290
|
+
const { scope, parent, spec } = opts;
|
|
291
|
+
const doc = spec.doc;
|
|
292
|
+
const { field, order } = effectiveOrder(spec);
|
|
293
|
+
const rawRec = doc ? "cf.content" : "e.content";
|
|
294
|
+
const rec = `(CASE WHEN ${rawRec} IS NOT NULL AND json_valid(${rawRec}) THEN ${rawRec} ELSE NULL END)`;
|
|
295
|
+
let col;
|
|
296
|
+
let colExpr;
|
|
297
|
+
let nullable;
|
|
298
|
+
if (field.startsWith("meta.")) {
|
|
299
|
+
const metaPath = jsonPathOf(field.slice(5));
|
|
300
|
+
colExpr = doc ? `COALESCE(json_extract(cf.metadata, '${metaPath}'), json_extract(e.metadata, '${metaPath}'))` : `json_extract(e.metadata, '${metaPath}')`;
|
|
301
|
+
col = colExpr;
|
|
302
|
+
nullable = true;
|
|
303
|
+
} else {
|
|
304
|
+
col = ENGINE_ORDER_COLUMNS[field];
|
|
305
|
+
colExpr = `e.${col}`;
|
|
306
|
+
nullable = col === "mime_type";
|
|
307
|
+
}
|
|
308
|
+
const from = buildChildrenFrom(doc);
|
|
309
|
+
const fromSql = from.sql;
|
|
310
|
+
const fromArgs = from.args;
|
|
311
|
+
const rowsFrom = buildChildrenFrom(doc, orderedChildrenIndex(field));
|
|
312
|
+
const baseWhere = ["e.scope = ?", "e.parent = ?"];
|
|
313
|
+
const baseArgs = [scope, parent];
|
|
314
|
+
if (!doc) baseWhere.push("e.kind = 'file'");
|
|
315
|
+
const whereLeaves = normalizeWhere(spec.where);
|
|
316
|
+
for (const leaf of whereLeaves) {
|
|
317
|
+
const frag = compileLeaf(rec, leaf, !!doc);
|
|
318
|
+
baseWhere.push(frag.sql);
|
|
319
|
+
baseArgs.push(...frag.args);
|
|
320
|
+
}
|
|
321
|
+
const whereSql = baseWhere.join(" AND ");
|
|
322
|
+
const parsed = parseTreeCursor(spec.cursor, true);
|
|
323
|
+
const parts = buildOrderedQueryParts({
|
|
324
|
+
col: colExpr,
|
|
325
|
+
nullable,
|
|
326
|
+
order,
|
|
327
|
+
tieCol: "e.name",
|
|
328
|
+
cursor: parsed.kind === "v2" ? parsed.cursor : void 0
|
|
329
|
+
});
|
|
330
|
+
const limit = spec.count ? 0 : spec.limit ?? DEFAULT_QUERY_LIMIT;
|
|
331
|
+
const offset = spec.offset ?? 0;
|
|
332
|
+
let rowsSql = `SELECT e.path, e.name, e.kind, e.cid, e.size, e.mtime, e.ctime, e.mime_type, e.metadata AS metadata${doc ? ", cf.content AS cf_content, cf.cid AS cf_cid, cf.metadata AS cf_metadata" : ", e.content AS content"} ${rowsFrom.sql} WHERE ${whereSql}`;
|
|
333
|
+
const rowsArgs = [...rowsFrom.args, ...baseArgs];
|
|
334
|
+
if (parts.cursorWhereSql) {
|
|
335
|
+
rowsSql += ` AND ${parts.cursorWhereSql}`;
|
|
336
|
+
rowsArgs.push(...parts.cursorArgs);
|
|
337
|
+
}
|
|
338
|
+
rowsSql += ` ORDER BY ${parts.orderSql} LIMIT ? OFFSET ?`;
|
|
339
|
+
rowsArgs.push(limit + 1, offset);
|
|
340
|
+
const countFrom = doc && whereLeaves.length === 0 ? buildChildrenFrom(void 0) : from;
|
|
341
|
+
const statements = {
|
|
342
|
+
rows: {
|
|
343
|
+
sql: rowsSql,
|
|
344
|
+
args: rowsArgs
|
|
345
|
+
},
|
|
346
|
+
count: spec.skipTotal ? void 0 : {
|
|
347
|
+
sql: `SELECT COUNT(*) AS cnt ${countFrom.sql} WHERE ${whereSql}`,
|
|
348
|
+
args: [...countFrom.args, ...baseArgs]
|
|
349
|
+
},
|
|
350
|
+
order: {
|
|
351
|
+
field,
|
|
352
|
+
order,
|
|
353
|
+
col
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
if (spec.aggregations) {
|
|
357
|
+
const groupKeys = aggregateGroupKeyNames(spec);
|
|
358
|
+
const keySelects = [];
|
|
359
|
+
for (let i = 0; i < groupKeys.length; i++) keySelects.push(`${groupKeyExpr(groupKeys[i], spec, rec)} AS k_${i}`);
|
|
360
|
+
const aggSelects = [];
|
|
361
|
+
for (const agg of spec.aggregations) aggSelects.push(`${aggregateOpExpr(agg, rec, !!doc)} AS ${agg.as}`);
|
|
362
|
+
const asSet = new Set(spec.aggregations.map((a) => a.as));
|
|
363
|
+
const groupSet = new Map(groupKeys.map((k, i) => [k, `k_${i}`]));
|
|
364
|
+
const orderParts = [];
|
|
365
|
+
for (const [orderField, dir] of spec.orderBy ?? []) {
|
|
366
|
+
const expr = groupSet.get(orderField) ?? (asSet.has(orderField) ? orderField : null);
|
|
367
|
+
if (expr) orderParts.push(`${expr} IS NULL ${dir === "asc" ? "ASC" : "DESC"}, ${expr} ${dir === "asc" ? "ASC" : "DESC"}`);
|
|
368
|
+
}
|
|
369
|
+
for (let i = 0; i < groupKeys.length; i++) orderParts.push(`k_${i} ASC`);
|
|
370
|
+
const orderSql = orderParts.length > 0 ? ` ORDER BY ${orderParts.join(", ")}` : "";
|
|
371
|
+
const groupBySql = groupKeys.length > 0 ? ` GROUP BY ${groupKeys.map((_, i) => `k_${i}`).join(", ")}` : "";
|
|
372
|
+
const aggLimit = spec.limit ?? DEFAULT_QUERY_LIMIT;
|
|
373
|
+
const aggOffset = spec.offset ?? 0;
|
|
374
|
+
const aggregateRowsSql = `SELECT ${[...keySelects, ...aggSelects].join(", ")} ${fromSql} WHERE ${whereSql}${groupBySql}${orderSql} LIMIT ? OFFSET ?`;
|
|
375
|
+
const countGroupsSql = groupKeys.length === 0 ? `SELECT 1 AS cnt ${fromSql} WHERE ${whereSql}` : `SELECT COUNT(*) AS cnt FROM (SELECT ${keySelects.join(", ")} ${fromSql} WHERE ${whereSql} GROUP BY ${groupKeys.map((_, i) => `k_${i}`).join(", ")})`;
|
|
376
|
+
statements.aggregate = {
|
|
377
|
+
select: {
|
|
378
|
+
sql: aggregateRowsSql,
|
|
379
|
+
args: [
|
|
380
|
+
...fromArgs,
|
|
381
|
+
...baseArgs,
|
|
382
|
+
aggLimit,
|
|
383
|
+
aggOffset
|
|
384
|
+
]
|
|
385
|
+
},
|
|
386
|
+
countGroups: {
|
|
387
|
+
sql: countGroupsSql,
|
|
388
|
+
args: groupKeys.length === 0 ? [...fromArgs, ...baseArgs] : [...fromArgs, ...baseArgs]
|
|
389
|
+
},
|
|
390
|
+
groupKeys,
|
|
391
|
+
aggregations: spec.aggregations
|
|
392
|
+
};
|
|
393
|
+
return statements;
|
|
394
|
+
}
|
|
395
|
+
if (typeof spec.groupBy === "string") {
|
|
396
|
+
const gp = jsonPathOf(spec.groupBy);
|
|
397
|
+
statements.groups = {
|
|
398
|
+
sql: `SELECT je.type AS t, CASE WHEN je.type = 'text' THEN lower(je.value) ELSE je.value END AS v, COUNT(*) AS cnt ${fromSql}, json_each(CASE json_type(${rec}, ?) WHEN 'array' THEN json_extract(${rec}, ?) WHEN 'true' THEN '[true]' WHEN 'false' THEN '[false]' ELSE json_array(json_extract(${rec}, ?)) END) je WHERE ${whereSql} GROUP BY t, v`,
|
|
399
|
+
args: [
|
|
400
|
+
...fromArgs,
|
|
401
|
+
gp,
|
|
402
|
+
gp,
|
|
403
|
+
gp,
|
|
404
|
+
...baseArgs
|
|
405
|
+
]
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
if (spec.seekId !== void 0) statements.seek = {
|
|
409
|
+
sql: `SELECT rn FROM (SELECT e.name AS nm, (ROW_NUMBER() OVER (ORDER BY ${parts.orderSql}) - 1) AS rn ${fromSql} WHERE ${whereSql}) AS _seek WHERE _seek.nm = ?`,
|
|
410
|
+
args: [
|
|
411
|
+
...fromArgs,
|
|
412
|
+
...baseArgs,
|
|
413
|
+
spec.seekId
|
|
414
|
+
]
|
|
415
|
+
};
|
|
416
|
+
return statements;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Assemble a TreeQueryResult from raw SQL rows — shared by SQLiteTreeIndex
|
|
420
|
+
* and D1TreeIndex so row mapping / hasMore slicing / keyset-cursor
|
|
421
|
+
* construction stay one implementation across SQL backends. `rawRows` is
|
|
422
|
+
* the (limit+1)-sized page from `TreeQueryStatements.rows`.
|
|
423
|
+
*/
|
|
424
|
+
function buildTreeQueryResultFromSql(opts) {
|
|
425
|
+
const { rawRows, total, groupRows, spec, orderField, seekOffset } = opts;
|
|
426
|
+
const limit = spec.count ? 0 : spec.limit ?? DEFAULT_QUERY_LIMIT;
|
|
427
|
+
const num = (v) => typeof v === "bigint" ? Number(v) : v ?? 0;
|
|
428
|
+
const hasMore = rawRows.length > limit;
|
|
429
|
+
const rows = (hasMore ? rawRows.slice(0, limit) : rawRows).map((r) => {
|
|
430
|
+
const row = {
|
|
431
|
+
path: r.path,
|
|
432
|
+
name: r.name,
|
|
433
|
+
kind: r.kind === "dir" ? "dir" : "file",
|
|
434
|
+
cid: r.cid ?? "",
|
|
435
|
+
size: num(r.size),
|
|
436
|
+
mtime: num(r.mtime),
|
|
437
|
+
ctime: num(r.ctime),
|
|
438
|
+
mimeType: r.mime_type ?? void 0
|
|
439
|
+
};
|
|
440
|
+
if (r.content != null) row.content = r.content;
|
|
441
|
+
if (r.cf_content != null) {
|
|
442
|
+
row.content = r.cf_content;
|
|
443
|
+
row.contentCid = r.cf_cid ?? void 0;
|
|
444
|
+
}
|
|
445
|
+
const meta = parseTreeEntryMetadata(r.cf_metadata ?? r.metadata);
|
|
446
|
+
if (meta !== void 0) row.metadata = meta;
|
|
447
|
+
return row;
|
|
448
|
+
});
|
|
449
|
+
const result = {
|
|
450
|
+
rows,
|
|
451
|
+
total
|
|
452
|
+
};
|
|
453
|
+
if (groupRows) result.groups = mapGroupRows(groupRows);
|
|
454
|
+
const last = rows[rows.length - 1];
|
|
455
|
+
if (hasMore && last && !spec.count) result.cursor = buildKeysetCursor(rowSortValue(last, orderField), last.name);
|
|
456
|
+
if (seekOffset !== void 0) result.seekOffset = seekOffset;
|
|
457
|
+
return result;
|
|
458
|
+
}
|
|
459
|
+
/** Sort-column value of a row (NULL mimeType stays null — sorts last). */
|
|
460
|
+
function rowSortValue(row, field) {
|
|
461
|
+
if (field.startsWith("meta.")) {
|
|
462
|
+
let cur = row.metadata;
|
|
463
|
+
for (const seg of field.slice(5).split(".")) {
|
|
464
|
+
if (cur == null || typeof cur !== "object" || Array.isArray(cur)) return null;
|
|
465
|
+
cur = cur[seg];
|
|
466
|
+
}
|
|
467
|
+
if (cur == null) return null;
|
|
468
|
+
if (typeof cur === "string" || typeof cur === "number") return cur;
|
|
469
|
+
return String(cur);
|
|
470
|
+
}
|
|
471
|
+
switch (field) {
|
|
472
|
+
case "name": return row.name;
|
|
473
|
+
case "path": return row.path;
|
|
474
|
+
case "mimeType": return row.mimeType ?? null;
|
|
475
|
+
case "size": return row.size;
|
|
476
|
+
case "ctime": return row.ctime;
|
|
477
|
+
case "mtime": return row.mtime;
|
|
478
|
+
default: return null;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
/** Canonical group ordering: count desc, then String(value) asc. */
|
|
482
|
+
function sortGroups(groups) {
|
|
483
|
+
return groups.sort((a, b) => b.count - a.count || String(a.value).localeCompare(String(b.value)));
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Map raw aggregate-mode SQL rows into the canonical `AFSAggregateGroup[]`.
|
|
487
|
+
* Each row has `k_0..k_N` for group dimensions (in `groupKeys` order) plus
|
|
488
|
+
* each aggregation alias. Numeric aggregates that come back as bigint are
|
|
489
|
+
* coerced to Number so callers don't have to worry about wire types.
|
|
490
|
+
*/
|
|
491
|
+
function mapAggregateRows(rows, groupKeys, aggregations) {
|
|
492
|
+
const coerce = (v) => {
|
|
493
|
+
if (typeof v === "bigint") return Number(v);
|
|
494
|
+
return v;
|
|
495
|
+
};
|
|
496
|
+
return rows.map((r) => {
|
|
497
|
+
const key = {};
|
|
498
|
+
for (let i = 0; i < groupKeys.length; i++) {
|
|
499
|
+
const v = coerce(r[`k_${i}`]);
|
|
500
|
+
key[groupKeys[i]] = v === null || v === void 0 ? null : typeof v === "string" || typeof v === "number" || typeof v === "boolean" ? v : String(v);
|
|
501
|
+
}
|
|
502
|
+
const out = { key };
|
|
503
|
+
for (const agg of aggregations) {
|
|
504
|
+
const raw = coerce(r[agg.as]);
|
|
505
|
+
if (agg.op === "count") out[agg.as] = typeof raw === "number" ? raw : 0;
|
|
506
|
+
else if (agg.op === "sum") out[agg.as] = typeof raw === "number" ? raw : 0;
|
|
507
|
+
else out[agg.as] = typeof raw === "number" ? raw : null;
|
|
508
|
+
}
|
|
509
|
+
return out;
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
/** Map raw group rows (t, v, cnt) into the canonical groups array. */
|
|
513
|
+
function mapGroupRows(rows) {
|
|
514
|
+
const merged = /* @__PURE__ */ new Map();
|
|
515
|
+
for (const r of rows) {
|
|
516
|
+
const t = String(r.t);
|
|
517
|
+
let value;
|
|
518
|
+
if (t === "text") value = String(r.v);
|
|
519
|
+
else if (t === "integer" || t === "real") value = Number(r.v);
|
|
520
|
+
else if (t === "true") value = true;
|
|
521
|
+
else if (t === "false") value = false;
|
|
522
|
+
else value = null;
|
|
523
|
+
const key = `${typeof value}:${String(value)}`;
|
|
524
|
+
const count = typeof r.cnt === "bigint" ? Number(r.cnt) : r.cnt;
|
|
525
|
+
const existing = merged.get(key);
|
|
526
|
+
if (existing) existing.count += count;
|
|
527
|
+
else merged.set(key, {
|
|
528
|
+
value,
|
|
529
|
+
count
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
return sortGroups([...merged.values()]);
|
|
533
|
+
}
|
|
534
|
+
/** Parse a record text into a JSON value; malformed → undefined (no record). */
|
|
535
|
+
function parseRecordText(text) {
|
|
536
|
+
if (text === void 0) return void 0;
|
|
537
|
+
try {
|
|
538
|
+
return JSON.parse(text);
|
|
539
|
+
} catch {
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
function foldPrimitive(value) {
|
|
544
|
+
if (typeof value === "string") return value.toLowerCase();
|
|
545
|
+
if (typeof value === "number" || typeof value === "boolean") return value;
|
|
546
|
+
return null;
|
|
547
|
+
}
|
|
548
|
+
/** Group-count with unnest semantics over parsed records (lockstep with SQL). */
|
|
549
|
+
function computeGroups(records, groupBy) {
|
|
550
|
+
const counts = /* @__PURE__ */ new Map();
|
|
551
|
+
const bump = (raw) => {
|
|
552
|
+
const value = foldPrimitive(raw);
|
|
553
|
+
const key = `${typeof value}:${String(value)}`;
|
|
554
|
+
const existing = counts.get(key);
|
|
555
|
+
if (existing) existing.count += 1;
|
|
556
|
+
else counts.set(key, {
|
|
557
|
+
value,
|
|
558
|
+
count: 1
|
|
559
|
+
});
|
|
560
|
+
};
|
|
561
|
+
for (const record of records) {
|
|
562
|
+
const value = resolveFieldPath(record, groupBy);
|
|
563
|
+
if (Array.isArray(value)) for (const member of value) bump(member);
|
|
564
|
+
else bump(value ?? null);
|
|
565
|
+
}
|
|
566
|
+
return sortGroups([...counts.values()]);
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Project `select` fields out of a parsed record (nested shape for
|
|
570
|
+
* dot-paths) — same projection rule as the core reference evaluator.
|
|
571
|
+
*/
|
|
572
|
+
function projectRecordFields(record, select) {
|
|
573
|
+
const out = {};
|
|
574
|
+
for (const field of select) {
|
|
575
|
+
const value = resolveFieldPath(record, field);
|
|
576
|
+
if (value === void 0) continue;
|
|
577
|
+
const segments = field.split(".");
|
|
578
|
+
let target = out;
|
|
579
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
580
|
+
const seg = segments[i];
|
|
581
|
+
if (typeof target[seg] !== "object" || target[seg] === null) target[seg] = {};
|
|
582
|
+
target = target[seg];
|
|
583
|
+
}
|
|
584
|
+
target[segments.at(-1)] = value;
|
|
585
|
+
}
|
|
586
|
+
return out;
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Execute a tree query over in-memory candidates — semantics locked to the
|
|
590
|
+
* SQL path by the lockstep test. `where` uses `whereMatchesItem` so that
|
|
591
|
+
* `meta.*` paths resolve against the candidate's `metadata` column the same
|
|
592
|
+
* way the SQL path reads `entries.metadata`.
|
|
593
|
+
*/
|
|
594
|
+
function runTreeQueryInMemory(candidates, spec) {
|
|
595
|
+
const filtered = spec.where ? candidates.filter((c) => whereMatchesItem({
|
|
596
|
+
entry: {
|
|
597
|
+
id: c.path,
|
|
598
|
+
path: c.path,
|
|
599
|
+
meta: c.metadata
|
|
600
|
+
},
|
|
601
|
+
record: c.record
|
|
602
|
+
}, spec.where)) : [...candidates];
|
|
603
|
+
if (spec.aggregations) {
|
|
604
|
+
const result$1 = evaluateCollectionQuery(filtered.map((c) => ({
|
|
605
|
+
entry: {
|
|
606
|
+
id: c.path,
|
|
607
|
+
path: c.path,
|
|
608
|
+
meta: c.metadata
|
|
609
|
+
},
|
|
610
|
+
record: c.record
|
|
611
|
+
})), spec);
|
|
612
|
+
return {
|
|
613
|
+
rows: [],
|
|
614
|
+
total: result$1.total,
|
|
615
|
+
aggregateGroups: result$1.aggregateGroups
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
const total = spec.skipTotal ? -1 : filtered.length;
|
|
619
|
+
const groups = typeof spec.groupBy === "string" ? computeGroups(filtered.map((c) => c.record), spec.groupBy) : void 0;
|
|
620
|
+
const { field, order } = effectiveOrder(spec);
|
|
621
|
+
filtered.sort((a, b) => {
|
|
622
|
+
const cmp = compareTreeSortValues(rowSortValue(a, field), rowSortValue(b, field), order);
|
|
623
|
+
if (cmp !== 0) return cmp;
|
|
624
|
+
const tie = a.name === b.name ? 0 : a.name < b.name ? -1 : 1;
|
|
625
|
+
return order === "desc" ? -tie : tie;
|
|
626
|
+
});
|
|
627
|
+
const parsed = parseTreeCursor(spec.cursor, true);
|
|
628
|
+
const afterCursor = parsed.kind === "v2" ? filtered.filter((row) => keysetAfter(rowSortValue(row, field), row.name, parsed.cursor, order)) : filtered;
|
|
629
|
+
let seekOffset;
|
|
630
|
+
if (spec.seekId !== void 0) seekOffset = filtered.findIndex((c) => c.name === spec.seekId);
|
|
631
|
+
const offset = spec.offset ?? 0;
|
|
632
|
+
const limit = spec.count ? 0 : spec.limit ?? DEFAULT_QUERY_LIMIT;
|
|
633
|
+
const page = afterCursor.slice(offset, offset + limit);
|
|
634
|
+
const hasMore = offset + limit < afterCursor.length;
|
|
635
|
+
const last = page[page.length - 1];
|
|
636
|
+
const result = {
|
|
637
|
+
rows: page.map(({ record: _record, ...row }) => row),
|
|
638
|
+
total
|
|
639
|
+
};
|
|
640
|
+
if (groups) result.groups = groups;
|
|
641
|
+
if (hasMore && last && !spec.count) result.cursor = buildKeysetCursor(rowSortValue(last, field), last.name);
|
|
642
|
+
if (seekOffset !== void 0) result.seekOffset = seekOffset;
|
|
643
|
+
return result;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
//#endregion
|
|
647
|
+
export { assertTreeQuerySpec, buildChildrenFrom, buildTreeQueryResultFromSql, buildTreeQueryStatements, mapAggregateRows, parseRecordText, projectRecordFields, runTreeQueryInMemory };
|
|
648
|
+
//# sourceMappingURL=tree-query.mjs.map
|