@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.
Files changed (510) hide show
  1. package/LICENSE.md +26 -0
  2. package/README.md +129 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs +11 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.mjs +10 -0
  5. package/dist/_virtual/rolldown_runtime.cjs +29 -0
  6. package/dist/afs-metadata-context.cjs +20 -0
  7. package/dist/afs-metadata-context.d.cts +21 -0
  8. package/dist/afs-metadata-context.d.cts.map +1 -0
  9. package/dist/afs-metadata-context.d.mts +21 -0
  10. package/dist/afs-metadata-context.d.mts.map +1 -0
  11. package/dist/afs-metadata-context.mjs +18 -0
  12. package/dist/afs-metadata-context.mjs.map +1 -0
  13. package/dist/blocklet-hook.cjs +180 -0
  14. package/dist/blocklet-hook.d.cts +29 -0
  15. package/dist/blocklet-hook.d.cts.map +1 -0
  16. package/dist/blocklet-hook.d.mts +29 -0
  17. package/dist/blocklet-hook.d.mts.map +1 -0
  18. package/dist/blocklet-hook.mjs +178 -0
  19. package/dist/blocklet-hook.mjs.map +1 -0
  20. package/dist/changelog-schema.cjs +603 -0
  21. package/dist/changelog-schema.d.cts +395 -0
  22. package/dist/changelog-schema.d.cts.map +1 -0
  23. package/dist/changelog-schema.d.mts +395 -0
  24. package/dist/changelog-schema.d.mts.map +1 -0
  25. package/dist/changelog-schema.mjs +570 -0
  26. package/dist/changelog-schema.mjs.map +1 -0
  27. package/dist/changelog-write.cjs +80 -0
  28. package/dist/changelog-write.d.cts +70 -0
  29. package/dist/changelog-write.d.cts.map +1 -0
  30. package/dist/changelog-write.d.mts +70 -0
  31. package/dist/changelog-write.d.mts.map +1 -0
  32. package/dist/changelog-write.mjs +77 -0
  33. package/dist/changelog-write.mjs.map +1 -0
  34. package/dist/cid-byte-cache.cjs +126 -0
  35. package/dist/cid-byte-cache.d.cts +46 -0
  36. package/dist/cid-byte-cache.d.cts.map +1 -0
  37. package/dist/cid-byte-cache.d.mts +47 -0
  38. package/dist/cid-byte-cache.d.mts.map +1 -0
  39. package/dist/cid-byte-cache.mjs +125 -0
  40. package/dist/cid-byte-cache.mjs.map +1 -0
  41. package/dist/cid.cjs +68 -0
  42. package/dist/cid.d.cts +22 -0
  43. package/dist/cid.d.cts.map +1 -0
  44. package/dist/cid.d.mts +22 -0
  45. package/dist/cid.d.mts.map +1 -0
  46. package/dist/cid.mjs +65 -0
  47. package/dist/cid.mjs.map +1 -0
  48. package/dist/client.cjs +221 -0
  49. package/dist/client.d.cts +72 -0
  50. package/dist/client.d.cts.map +1 -0
  51. package/dist/client.d.mts +72 -0
  52. package/dist/client.d.mts.map +1 -0
  53. package/dist/client.mjs +220 -0
  54. package/dist/client.mjs.map +1 -0
  55. package/dist/cloudflare.cjs +510 -0
  56. package/dist/cloudflare.d.cts +307 -0
  57. package/dist/cloudflare.d.cts.map +1 -0
  58. package/dist/cloudflare.d.mts +308 -0
  59. package/dist/cloudflare.d.mts.map +1 -0
  60. package/dist/cloudflare.mjs +507 -0
  61. package/dist/cloudflare.mjs.map +1 -0
  62. package/dist/ctime-backfill.cjs +272 -0
  63. package/dist/ctime-backfill.d.cts +169 -0
  64. package/dist/ctime-backfill.d.cts.map +1 -0
  65. package/dist/ctime-backfill.d.mts +169 -0
  66. package/dist/ctime-backfill.d.mts.map +1 -0
  67. package/dist/ctime-backfill.mjs +267 -0
  68. package/dist/ctime-backfill.mjs.map +1 -0
  69. package/dist/d1-gc-queue.cjs +80 -0
  70. package/dist/d1-gc-queue.d.cts +59 -0
  71. package/dist/d1-gc-queue.d.cts.map +1 -0
  72. package/dist/d1-gc-queue.d.mts +59 -0
  73. package/dist/d1-gc-queue.d.mts.map +1 -0
  74. package/dist/d1-gc-queue.mjs +81 -0
  75. package/dist/d1-gc-queue.mjs.map +1 -0
  76. package/dist/d1-resolve-store.cjs +189 -0
  77. package/dist/d1-resolve-store.d.cts +93 -0
  78. package/dist/d1-resolve-store.d.cts.map +1 -0
  79. package/dist/d1-resolve-store.d.mts +93 -0
  80. package/dist/d1-resolve-store.d.mts.map +1 -0
  81. package/dist/d1-resolve-store.mjs +190 -0
  82. package/dist/d1-resolve-store.mjs.map +1 -0
  83. package/dist/d1-schema.cjs +361 -0
  84. package/dist/d1-schema.d.cts +237 -0
  85. package/dist/d1-schema.d.cts.map +1 -0
  86. package/dist/d1-schema.d.mts +237 -0
  87. package/dist/d1-schema.d.mts.map +1 -0
  88. package/dist/d1-schema.mjs +341 -0
  89. package/dist/d1-schema.mjs.map +1 -0
  90. package/dist/d1-share-store.cjs +0 -0
  91. package/dist/d1-share-store.d.cts +53 -0
  92. package/dist/d1-share-store.d.cts.map +1 -0
  93. package/dist/d1-share-store.d.mts +53 -0
  94. package/dist/d1-share-store.d.mts.map +1 -0
  95. package/dist/d1-share-store.mjs +0 -0
  96. package/dist/d1-share-store.mjs.map +1 -0
  97. package/dist/d1-tree-index.cjs +1098 -0
  98. package/dist/d1-tree-index.d.cts +203 -0
  99. package/dist/d1-tree-index.d.cts.map +1 -0
  100. package/dist/d1-tree-index.d.mts +203 -0
  101. package/dist/d1-tree-index.d.mts.map +1 -0
  102. package/dist/d1-tree-index.mjs +1094 -0
  103. package/dist/d1-tree-index.mjs.map +1 -0
  104. package/dist/data-backend.cjs +147 -0
  105. package/dist/data-backend.d.cts +30 -0
  106. package/dist/data-backend.d.cts.map +1 -0
  107. package/dist/data-backend.d.mts +30 -0
  108. package/dist/data-backend.d.mts.map +1 -0
  109. package/dist/data-backend.mjs +148 -0
  110. package/dist/data-backend.mjs.map +1 -0
  111. package/dist/dedup-backfill.cjs +278 -0
  112. package/dist/dedup-backfill.d.cts +165 -0
  113. package/dist/dedup-backfill.d.cts.map +1 -0
  114. package/dist/dedup-backfill.d.mts +165 -0
  115. package/dist/dedup-backfill.d.mts.map +1 -0
  116. package/dist/dedup-backfill.mjs +273 -0
  117. package/dist/dedup-backfill.mjs.map +1 -0
  118. package/dist/did-space-like.d.cts +2 -0
  119. package/dist/did-space-like.d.mts +2 -0
  120. package/dist/did-utils.cjs +44 -0
  121. package/dist/did-utils.d.cts +25 -0
  122. package/dist/did-utils.d.cts.map +1 -0
  123. package/dist/did-utils.d.mts +25 -0
  124. package/dist/did-utils.d.mts.map +1 -0
  125. package/dist/did-utils.mjs +43 -0
  126. package/dist/did-utils.mjs.map +1 -0
  127. package/dist/dirty-path-queue.cjs +31 -0
  128. package/dist/dirty-path-queue.d.cts +104 -0
  129. package/dist/dirty-path-queue.d.cts.map +1 -0
  130. package/dist/dirty-path-queue.d.mts +104 -0
  131. package/dist/dirty-path-queue.d.mts.map +1 -0
  132. package/dist/dirty-path-queue.mjs +31 -0
  133. package/dist/dirty-path-queue.mjs.map +1 -0
  134. package/dist/dirty-path-schema.cjs +142 -0
  135. package/dist/dirty-path-schema.d.cts +90 -0
  136. package/dist/dirty-path-schema.d.cts.map +1 -0
  137. package/dist/dirty-path-schema.d.mts +90 -0
  138. package/dist/dirty-path-schema.d.mts.map +1 -0
  139. package/dist/dirty-path-schema.mjs +136 -0
  140. package/dist/dirty-path-schema.mjs.map +1 -0
  141. package/dist/download-actions.cjs +43 -0
  142. package/dist/download-actions.mjs +40 -0
  143. package/dist/download-actions.mjs.map +1 -0
  144. package/dist/fs-object-store.cjs +153 -0
  145. package/dist/fs-object-store.d.cts +21 -0
  146. package/dist/fs-object-store.d.cts.map +1 -0
  147. package/dist/fs-object-store.d.mts +22 -0
  148. package/dist/fs-object-store.d.mts.map +1 -0
  149. package/dist/fs-object-store.mjs +153 -0
  150. package/dist/fs-object-store.mjs.map +1 -0
  151. package/dist/gc-queue.d.cts +43 -0
  152. package/dist/gc-queue.d.cts.map +1 -0
  153. package/dist/gc-queue.d.mts +43 -0
  154. package/dist/gc-queue.d.mts.map +1 -0
  155. package/dist/index.cjs +2712 -0
  156. package/dist/index.d.cts +504 -0
  157. package/dist/index.d.cts.map +1 -0
  158. package/dist/index.d.mts +505 -0
  159. package/dist/index.d.mts.map +1 -0
  160. package/dist/index.mjs +2537 -0
  161. package/dist/index.mjs.map +1 -0
  162. package/dist/inline-content-migration.cjs +212 -0
  163. package/dist/inline-content-migration.d.cts +110 -0
  164. package/dist/inline-content-migration.d.cts.map +1 -0
  165. package/dist/inline-content-migration.d.mts +111 -0
  166. package/dist/inline-content-migration.d.mts.map +1 -0
  167. package/dist/inline-content-migration.mjs +207 -0
  168. package/dist/inline-content-migration.mjs.map +1 -0
  169. package/dist/inline-content.cjs +145 -0
  170. package/dist/inline-content.d.cts +98 -0
  171. package/dist/inline-content.d.cts.map +1 -0
  172. package/dist/inline-content.d.mts +98 -0
  173. package/dist/inline-content.d.mts.map +1 -0
  174. package/dist/inline-content.mjs +137 -0
  175. package/dist/inline-content.mjs.map +1 -0
  176. package/dist/local-changelog.cjs +241 -0
  177. package/dist/local-changelog.d.cts +119 -0
  178. package/dist/local-changelog.d.cts.map +1 -0
  179. package/dist/local-changelog.d.mts +119 -0
  180. package/dist/local-changelog.d.mts.map +1 -0
  181. package/dist/local-changelog.mjs +240 -0
  182. package/dist/local-changelog.mjs.map +1 -0
  183. package/dist/local.cjs +435 -0
  184. package/dist/local.d.cts +254 -0
  185. package/dist/local.d.cts.map +1 -0
  186. package/dist/local.d.mts +254 -0
  187. package/dist/local.d.mts.map +1 -0
  188. package/dist/local.mjs +427 -0
  189. package/dist/local.mjs.map +1 -0
  190. package/dist/memory-gc-queue.cjs +36 -0
  191. package/dist/memory-gc-queue.d.cts +22 -0
  192. package/dist/memory-gc-queue.d.cts.map +1 -0
  193. package/dist/memory-gc-queue.d.mts +22 -0
  194. package/dist/memory-gc-queue.d.mts.map +1 -0
  195. package/dist/memory-gc-queue.mjs +36 -0
  196. package/dist/memory-gc-queue.mjs.map +1 -0
  197. package/dist/memory-tree-index.cjs +734 -0
  198. package/dist/memory-tree-index.d.cts +159 -0
  199. package/dist/memory-tree-index.d.cts.map +1 -0
  200. package/dist/memory-tree-index.d.mts +159 -0
  201. package/dist/memory-tree-index.d.mts.map +1 -0
  202. package/dist/memory-tree-index.mjs +735 -0
  203. package/dist/memory-tree-index.mjs.map +1 -0
  204. package/dist/metadata-db.cjs +562 -0
  205. package/dist/metadata-db.d.cts +102 -0
  206. package/dist/metadata-db.d.cts.map +1 -0
  207. package/dist/metadata-db.d.mts +102 -0
  208. package/dist/metadata-db.d.mts.map +1 -0
  209. package/dist/metadata-db.mjs +562 -0
  210. package/dist/metadata-db.mjs.map +1 -0
  211. package/dist/mime-utils.cjs +2 -0
  212. package/dist/mime-utils.d.cts +2 -0
  213. package/dist/mime-utils.d.mts +2 -0
  214. package/dist/mime-utils.mjs +3 -0
  215. package/dist/object-key.cjs +41 -0
  216. package/dist/object-key.d.cts +25 -0
  217. package/dist/object-key.d.cts.map +1 -0
  218. package/dist/object-key.d.mts +25 -0
  219. package/dist/object-key.d.mts.map +1 -0
  220. package/dist/object-key.mjs +40 -0
  221. package/dist/object-key.mjs.map +1 -0
  222. package/dist/packages/session/dist/index.cjs +788 -0
  223. package/dist/packages/session/dist/index.mjs +782 -0
  224. package/dist/packages/session/dist/index.mjs.map +1 -0
  225. package/dist/platform/r2/dist/types.d.cts +49 -0
  226. package/dist/platform/r2/dist/types.d.cts.map +1 -0
  227. package/dist/prefix-range.cjs +33 -0
  228. package/dist/prefix-range.d.cts +29 -0
  229. package/dist/prefix-range.d.cts.map +1 -0
  230. package/dist/prefix-range.d.mts +29 -0
  231. package/dist/prefix-range.d.mts.map +1 -0
  232. package/dist/prefix-range.mjs +33 -0
  233. package/dist/prefix-range.mjs.map +1 -0
  234. package/dist/prefixed-tree-index.cjs +238 -0
  235. package/dist/prefixed-tree-index.d.cts +85 -0
  236. package/dist/prefixed-tree-index.d.cts.map +1 -0
  237. package/dist/prefixed-tree-index.d.mts +85 -0
  238. package/dist/prefixed-tree-index.d.mts.map +1 -0
  239. package/dist/prefixed-tree-index.mjs +239 -0
  240. package/dist/prefixed-tree-index.mjs.map +1 -0
  241. package/dist/presign-signer.cjs +7 -0
  242. package/dist/presign-signer.d.cts +99 -0
  243. package/dist/presign-signer.d.cts.map +1 -0
  244. package/dist/presign-signer.d.mts +99 -0
  245. package/dist/presign-signer.d.mts.map +1 -0
  246. package/dist/presign-signer.mjs +7 -0
  247. package/dist/presign-signer.mjs.map +1 -0
  248. package/dist/providers/platform/r2/dist/index.d.mts +3 -0
  249. package/dist/providers/platform/r2/dist/types.d.mts +49 -0
  250. package/dist/providers/platform/r2/dist/types.d.mts.map +1 -0
  251. package/dist/reconcile.cjs +184 -0
  252. package/dist/reconcile.d.cts +26 -0
  253. package/dist/reconcile.d.cts.map +1 -0
  254. package/dist/reconcile.d.mts +26 -0
  255. package/dist/reconcile.d.mts.map +1 -0
  256. package/dist/reconcile.mjs +184 -0
  257. package/dist/reconcile.mjs.map +1 -0
  258. package/dist/reference-check.cjs +49 -0
  259. package/dist/reference-check.d.cts +10 -0
  260. package/dist/reference-check.d.cts.map +1 -0
  261. package/dist/reference-check.d.mts +10 -0
  262. package/dist/reference-check.d.mts.map +1 -0
  263. package/dist/reference-check.mjs +48 -0
  264. package/dist/reference-check.mjs.map +1 -0
  265. package/dist/remote-afs.cjs +681 -0
  266. package/dist/remote-afs.d.cts +236 -0
  267. package/dist/remote-afs.d.cts.map +1 -0
  268. package/dist/remote-afs.d.mts +236 -0
  269. package/dist/remote-afs.d.mts.map +1 -0
  270. package/dist/remote-afs.mjs +676 -0
  271. package/dist/remote-afs.mjs.map +1 -0
  272. package/dist/rename-guard.cjs +18 -0
  273. package/dist/rename-guard.mjs +18 -0
  274. package/dist/rename-guard.mjs.map +1 -0
  275. package/dist/resolve.cjs +260 -0
  276. package/dist/resolve.d.cts +113 -0
  277. package/dist/resolve.d.cts.map +1 -0
  278. package/dist/resolve.d.mts +113 -0
  279. package/dist/resolve.d.mts.map +1 -0
  280. package/dist/resolve.mjs +260 -0
  281. package/dist/resolve.mjs.map +1 -0
  282. package/dist/rsync-content.cjs +33 -0
  283. package/dist/rsync-content.mjs +33 -0
  284. package/dist/rsync-content.mjs.map +1 -0
  285. package/dist/rsync.cjs +400 -0
  286. package/dist/rsync.d.cts +157 -0
  287. package/dist/rsync.d.cts.map +1 -0
  288. package/dist/rsync.d.mts +157 -0
  289. package/dist/rsync.d.mts.map +1 -0
  290. package/dist/rsync.mjs +397 -0
  291. package/dist/rsync.mjs.map +1 -0
  292. package/dist/run-gc.cjs +57 -0
  293. package/dist/run-gc.d.cts +40 -0
  294. package/dist/run-gc.d.cts.map +1 -0
  295. package/dist/run-gc.d.mts +41 -0
  296. package/dist/run-gc.d.mts.map +1 -0
  297. package/dist/run-gc.mjs +57 -0
  298. package/dist/run-gc.mjs.map +1 -0
  299. package/dist/scope-id.cjs +70 -0
  300. package/dist/scope-id.d.cts +35 -0
  301. package/dist/scope-id.d.cts.map +1 -0
  302. package/dist/scope-id.d.mts +35 -0
  303. package/dist/scope-id.d.mts.map +1 -0
  304. package/dist/scope-id.mjs +68 -0
  305. package/dist/scope-id.mjs.map +1 -0
  306. package/dist/scope-migration-node.cjs +172 -0
  307. package/dist/scope-migration-node.d.cts +44 -0
  308. package/dist/scope-migration-node.d.cts.map +1 -0
  309. package/dist/scope-migration-node.d.mts +44 -0
  310. package/dist/scope-migration-node.d.mts.map +1 -0
  311. package/dist/scope-migration-node.mjs +171 -0
  312. package/dist/scope-migration-node.mjs.map +1 -0
  313. package/dist/scope-migration.cjs +155 -0
  314. package/dist/scope-migration.d.cts +65 -0
  315. package/dist/scope-migration.d.cts.map +1 -0
  316. package/dist/scope-migration.d.mts +65 -0
  317. package/dist/scope-migration.d.mts.map +1 -0
  318. package/dist/scope-migration.mjs +154 -0
  319. package/dist/scope-migration.mjs.map +1 -0
  320. package/dist/share-declaration.cjs +225 -0
  321. package/dist/share-declaration.d.cts +30 -0
  322. package/dist/share-declaration.d.cts.map +1 -0
  323. package/dist/share-declaration.d.mts +32 -0
  324. package/dist/share-declaration.d.mts.map +1 -0
  325. package/dist/share-declaration.mjs +221 -0
  326. package/dist/share-declaration.mjs.map +1 -0
  327. package/dist/share-hook.cjs +63 -0
  328. package/dist/share-hook.mjs +62 -0
  329. package/dist/share-hook.mjs.map +1 -0
  330. package/dist/share-resolve.cjs +176 -0
  331. package/dist/share-resolve.d.cts +36 -0
  332. package/dist/share-resolve.d.cts.map +1 -0
  333. package/dist/share-resolve.d.mts +36 -0
  334. package/dist/share-resolve.d.mts.map +1 -0
  335. package/dist/share-resolve.mjs +177 -0
  336. package/dist/share-resolve.mjs.map +1 -0
  337. package/dist/share-serve.cjs +145 -0
  338. package/dist/share-serve.d.cts +30 -0
  339. package/dist/share-serve.d.cts.map +1 -0
  340. package/dist/share-serve.d.mts +30 -0
  341. package/dist/share-serve.d.mts.map +1 -0
  342. package/dist/share-serve.mjs +144 -0
  343. package/dist/share-serve.mjs.map +1 -0
  344. package/dist/share-store.cjs +25 -0
  345. package/dist/share-store.d.cts +65 -0
  346. package/dist/share-store.d.cts.map +1 -0
  347. package/dist/share-store.d.mts +65 -0
  348. package/dist/share-store.d.mts.map +1 -0
  349. package/dist/share-store.mjs +25 -0
  350. package/dist/share-store.mjs.map +1 -0
  351. package/dist/share-virtual-path.cjs +102 -0
  352. package/dist/share-virtual-path.mjs +101 -0
  353. package/dist/share-virtual-path.mjs.map +1 -0
  354. package/dist/space-resolver.cjs +54 -0
  355. package/dist/space-resolver.d.cts +34 -0
  356. package/dist/space-resolver.d.cts.map +1 -0
  357. package/dist/space-resolver.d.mts +34 -0
  358. package/dist/space-resolver.d.mts.map +1 -0
  359. package/dist/space-resolver.mjs +55 -0
  360. package/dist/space-resolver.mjs.map +1 -0
  361. package/dist/sqlite-gc-queue.cjs +51 -0
  362. package/dist/sqlite-gc-queue.d.cts +22 -0
  363. package/dist/sqlite-gc-queue.d.cts.map +1 -0
  364. package/dist/sqlite-gc-queue.d.mts +22 -0
  365. package/dist/sqlite-gc-queue.d.mts.map +1 -0
  366. package/dist/sqlite-gc-queue.mjs +52 -0
  367. package/dist/sqlite-gc-queue.mjs.map +1 -0
  368. package/dist/sqlite-resolve-store.cjs +163 -0
  369. package/dist/sqlite-resolve-store.d.cts +50 -0
  370. package/dist/sqlite-resolve-store.d.cts.map +1 -0
  371. package/dist/sqlite-resolve-store.d.mts +50 -0
  372. package/dist/sqlite-resolve-store.d.mts.map +1 -0
  373. package/dist/sqlite-resolve-store.mjs +164 -0
  374. package/dist/sqlite-resolve-store.mjs.map +1 -0
  375. package/dist/sqlite-share-store.cjs +157 -0
  376. package/dist/sqlite-share-store.d.cts +31 -0
  377. package/dist/sqlite-share-store.d.cts.map +1 -0
  378. package/dist/sqlite-share-store.d.mts +31 -0
  379. package/dist/sqlite-share-store.d.mts.map +1 -0
  380. package/dist/sqlite-share-store.mjs +157 -0
  381. package/dist/sqlite-share-store.mjs.map +1 -0
  382. package/dist/sqlite-tree-index.cjs +901 -0
  383. package/dist/sqlite-tree-index.d.cts +107 -0
  384. package/dist/sqlite-tree-index.d.cts.map +1 -0
  385. package/dist/sqlite-tree-index.d.mts +107 -0
  386. package/dist/sqlite-tree-index.d.mts.map +1 -0
  387. package/dist/sqlite-tree-index.mjs +902 -0
  388. package/dist/sqlite-tree-index.mjs.map +1 -0
  389. package/dist/sync-engine.cjs +1324 -0
  390. package/dist/sync-engine.d.cts +473 -0
  391. package/dist/sync-engine.d.cts.map +1 -0
  392. package/dist/sync-engine.d.mts +473 -0
  393. package/dist/sync-engine.d.mts.map +1 -0
  394. package/dist/sync-engine.mjs +1315 -0
  395. package/dist/sync-engine.mjs.map +1 -0
  396. package/dist/sync-state.cjs +303 -0
  397. package/dist/sync-state.d.cts +224 -0
  398. package/dist/sync-state.d.cts.map +1 -0
  399. package/dist/sync-state.d.mts +224 -0
  400. package/dist/sync-state.d.mts.map +1 -0
  401. package/dist/sync-state.mjs +297 -0
  402. package/dist/sync-state.mjs.map +1 -0
  403. package/dist/timestamp.cjs +92 -0
  404. package/dist/timestamp.mjs +91 -0
  405. package/dist/timestamp.mjs.map +1 -0
  406. package/dist/transports/http.cjs +54 -0
  407. package/dist/transports/http.d.cts +26 -0
  408. package/dist/transports/http.d.cts.map +1 -0
  409. package/dist/transports/http.d.mts +26 -0
  410. package/dist/transports/http.d.mts.map +1 -0
  411. package/dist/transports/http.mjs +54 -0
  412. package/dist/transports/http.mjs.map +1 -0
  413. package/dist/transports/static.cjs +55 -0
  414. package/dist/transports/static.d.cts +28 -0
  415. package/dist/transports/static.d.cts.map +1 -0
  416. package/dist/transports/static.d.mts +28 -0
  417. package/dist/transports/static.d.mts.map +1 -0
  418. package/dist/transports/static.mjs +55 -0
  419. package/dist/transports/static.mjs.map +1 -0
  420. package/dist/transports/types.cjs +13 -0
  421. package/dist/transports/types.d.cts +72 -0
  422. package/dist/transports/types.d.cts.map +1 -0
  423. package/dist/transports/types.d.mts +72 -0
  424. package/dist/transports/types.d.mts.map +1 -0
  425. package/dist/transports/types.mjs +13 -0
  426. package/dist/transports/types.mjs.map +1 -0
  427. package/dist/transports/ws.cjs +207 -0
  428. package/dist/transports/ws.d.cts +47 -0
  429. package/dist/transports/ws.d.cts.map +1 -0
  430. package/dist/transports/ws.d.mts +47 -0
  431. package/dist/transports/ws.d.mts.map +1 -0
  432. package/dist/transports/ws.mjs +206 -0
  433. package/dist/transports/ws.mjs.map +1 -0
  434. package/dist/tree-index.cjs +333 -0
  435. package/dist/tree-index.d.cts +524 -0
  436. package/dist/tree-index.d.cts.map +1 -0
  437. package/dist/tree-index.d.mts +524 -0
  438. package/dist/tree-index.d.mts.map +1 -0
  439. package/dist/tree-index.mjs +322 -0
  440. package/dist/tree-index.mjs.map +1 -0
  441. package/dist/tree-query.cjs +655 -0
  442. package/dist/tree-query.d.cts +70 -0
  443. package/dist/tree-query.d.cts.map +1 -0
  444. package/dist/tree-query.d.mts +70 -0
  445. package/dist/tree-query.d.mts.map +1 -0
  446. package/dist/tree-query.mjs +648 -0
  447. package/dist/tree-query.mjs.map +1 -0
  448. package/dist/upload-actions.cjs +97 -0
  449. package/dist/upload-actions.d.cts +19 -0
  450. package/dist/upload-actions.d.cts.map +1 -0
  451. package/dist/upload-actions.d.mts +21 -0
  452. package/dist/upload-actions.d.mts.map +1 -0
  453. package/dist/upload-actions.mjs +90 -0
  454. package/dist/upload-actions.mjs.map +1 -0
  455. package/dist/upload-session-store.cjs +185 -0
  456. package/dist/upload-session-store.d.cts +99 -0
  457. package/dist/upload-session-store.d.cts.map +1 -0
  458. package/dist/upload-session-store.d.mts +99 -0
  459. package/dist/upload-session-store.d.mts.map +1 -0
  460. package/dist/upload-session-store.mjs +184 -0
  461. package/dist/upload-session-store.mjs.map +1 -0
  462. package/dist/url-normalize.cjs +61 -0
  463. package/dist/url-normalize.d.cts +33 -0
  464. package/dist/url-normalize.d.cts.map +1 -0
  465. package/dist/url-normalize.d.mts +33 -0
  466. package/dist/url-normalize.d.mts.map +1 -0
  467. package/dist/url-normalize.mjs +61 -0
  468. package/dist/url-normalize.mjs.map +1 -0
  469. package/dist/versioned-content-backends.cjs +155 -0
  470. package/dist/versioned-content-backends.d.cts +49 -0
  471. package/dist/versioned-content-backends.d.cts.map +1 -0
  472. package/dist/versioned-content-backends.d.mts +49 -0
  473. package/dist/versioned-content-backends.d.mts.map +1 -0
  474. package/dist/versioned-content-backends.mjs +154 -0
  475. package/dist/versioned-content-backends.mjs.map +1 -0
  476. package/dist/versioned-content-index.cjs +102 -0
  477. package/dist/versioned-content-index.d.cts +46 -0
  478. package/dist/versioned-content-index.d.cts.map +1 -0
  479. package/dist/versioned-content-index.d.mts +46 -0
  480. package/dist/versioned-content-index.d.mts.map +1 -0
  481. package/dist/versioned-content-index.mjs +103 -0
  482. package/dist/versioned-content-index.mjs.map +1 -0
  483. package/dist/versioned-content-store.cjs +121 -0
  484. package/dist/versioned-content-store.d.cts +90 -0
  485. package/dist/versioned-content-store.d.cts.map +1 -0
  486. package/dist/versioned-content-store.d.mts +90 -0
  487. package/dist/versioned-content-store.d.mts.map +1 -0
  488. package/dist/versioned-content-store.mjs +122 -0
  489. package/dist/versioned-content-store.mjs.map +1 -0
  490. package/dist/versioned-scope.cjs +39 -0
  491. package/dist/versioned-scope.d.cts +57 -0
  492. package/dist/versioned-scope.d.cts.map +1 -0
  493. package/dist/versioned-scope.d.mts +57 -0
  494. package/dist/versioned-scope.d.mts.map +1 -0
  495. package/dist/versioned-scope.mjs +37 -0
  496. package/dist/versioned-scope.mjs.map +1 -0
  497. package/migrations/0001_tree_entries.sql +17 -0
  498. package/migrations/0002_resolve_entries.sql +7 -0
  499. package/migrations/0003_entries_v2.sql +38 -0
  500. package/migrations/0004_gc_queue.sql +5 -0
  501. package/migrations/0006_resolve_enhance.sql +14 -0
  502. package/migrations/0007_resolve_created_at.sql +10 -0
  503. package/migrations/0008_changelog.sql +34 -0
  504. package/migrations/0009_device_sync_state.sql +29 -0
  505. package/migrations/0010_scope_meta.sql +33 -0
  506. package/migrations/0011_shares.sql +25 -0
  507. package/migrations/0012_scope_meta_file_count.sql +41 -0
  508. package/migrations/0013_scope_meta_total_bytes.sql +47 -0
  509. package/migrations/0014_rename_tables.sql +62 -0
  510. package/package.json +102 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-tree-index.mjs","names":["result","hasMore","rows","countRes"],"sources":["../src/sqlite-tree-index.ts"],"sourcesContent":["/**\n * SQLiteTreeIndex — a `TreeIndex` over MetadataDB's libsql client.\n *\n * Implements the full `TreeIndex` contract on the SAME `entries` + `changelog`\n * tables D1TreeIndex uses (shared `changelog-schema.ts` DDL), so Node and\n * Cloudflare run identical sync semantics with only the storage primitive\n * swapped. Row-for-row aligned with `d1-tree-index.ts`; the only differences are\n * the libsql client API (`execute({sql,args})` / `batch(stmts,\"write\")`) vs the\n * D1 API (`prepare().bind().all()` / `batch([...])`).\n *\n * Why not delegate to `MetadataDB.upsertEntry`: that returns `void` and drops\n * the prior cid (`oldCid`) — the GC enqueue input. So `put`/`delete` here own\n * the atomic changelog batch + oldCid/ctime contract directly.\n */\n\nimport type { InValue, Client as LibsqlClient } from \"@libsql/client\";\nimport {\n PREFIX_WATERMARK_BUMP_SQL,\n PREFIX_WATERMARK_READ_SQL,\n watermarkPrefix,\n watermarkWritePrefix,\n} from \"./changelog-schema.js\";\nimport { validateDeviceId } from \"./changelog-write.js\";\nimport {\n ancestorDirs,\n buildDirChainStmt,\n MAX_ENTRIES_PER_SCOPE,\n nameOf,\n parentOf,\n prefixRange,\n} from \"./d1-tree-index.js\";\nimport type { DirtyPathRow, ListDirtyPathOptions } from \"./dirty-path-queue.js\";\nimport {\n DIRTY_PATH_ACK_SQL,\n DIRTY_PATH_LIST_SQL,\n DIRTY_PATH_MARK_ERROR_SQL,\n} from \"./dirty-path-schema.js\";\nimport {\n type InlineContentOptions,\n type ResolvedInlineConfig,\n resolveInlineConfig,\n resolveInlineContent,\n} from \"./inline-content.js\";\nimport type { MetadataDB } from \"./metadata-db.js\";\nimport { resolveParentDirStamp } from \"./timestamp.js\";\nimport {\n type BatchDeleteEntry,\n type BatchDeleteEntryResult,\n type BatchIndexContext,\n type BatchPutEntry,\n type BatchPutEntryResult,\n buildKeysetCursor,\n buildOrderedQueryParts,\n type ChangelogEntry,\n loopBatchDeleteEntries,\n loopBatchPutEntries,\n type PutOpts,\n parseTreeCursor,\n parseTreeEntryMetadata,\n serializeTreeEntryMetadata,\n storageQuotaError,\n type TreeEntry,\n type TreeIndex,\n type TreeIndexListEntriesResult,\n type TreeIndexListOptions,\n type TreeIndexListResult,\n treeEntryMetadataEqual,\n} from \"./tree-index.js\";\nimport {\n buildChildrenFrom,\n buildTreeQueryResultFromSql,\n buildTreeQueryStatements,\n mapAggregateRows,\n type TreeQueryResult,\n type TreeQuerySpec,\n} from \"./tree-query.js\";\n\n/**\n * `isReferencedMany` IN-shard size for libsql/SQLite (design §7.2). SQLite's\n * default bound-param cap is ~999; the three-way UNION binds each cid 3×, so\n * 300 cids ⇒ ≤ ~906 params — comfortably under the cap on both branches.\n */\nexport const SQLITE_MANY_SHARD_SIZE = 300;\n\nconst VALID_ORDER_BY: Record<string, string> = {\n path: \"path\",\n mtime: \"mtime\",\n size: \"size\",\n ctime: \"ctime\",\n mimeType: \"mime_type\",\n name: \"name\",\n};\n\n/** The only nullable sortable column — NULLs must sort last (see tree-index.ts). */\nconst NULLABLE_ORDER_COLUMNS = new Set([\"mime_type\"]);\n\n/** libsql returns INTEGER columns as number|bigint; coerce to a JS number. */\nfunction num(v: unknown): number {\n return typeof v === \"bigint\" ? Number(v) : ((v as number | null) ?? 0);\n}\n\n/** Raw sort-column value of a row for the keyset cursor (NULL stays null). */\nfunction sortValueOf(row: Record<string, unknown>, col: string): string | number | null {\n const v = row[col];\n if (v == null) return null;\n if (typeof v === \"bigint\") return Number(v);\n return v as string | number;\n}\n\nfunction mapChildRow(r: Record<string, unknown>): {\n path: string;\n cid: string;\n size: number;\n mtime: number;\n ctime: number;\n mimeType?: string;\n content?: string;\n} {\n const e: ReturnType<typeof mapChildRow> = {\n path: r.path as string,\n cid: (r.cid as string | null) ?? \"\",\n size: num(r.size),\n mtime: num(r.mtime),\n ctime: num(r.ctime),\n mimeType: (r.mime_type as string | null) ?? undefined,\n };\n // Present only when the SELECT projected it (includeContent) AND non-NULL.\n if (r.content != null) e.content = r.content as string;\n return e;\n}\n\nexport class SQLiteTreeIndex implements TreeIndex {\n private readonly client: LibsqlClient;\n private readonly maxEntriesPerScope: number;\n /** upload-limits Phase 5 byte quota (0 = disabled, the opt-in default). */\n private readonly maxBytesPerScope: number;\n private readonly inline: ResolvedInlineConfig;\n\n constructor(\n db: MetadataDB,\n private readonly scope: string,\n opts?: { maxEntriesPerScope?: number; maxBytesPerScope?: number } & InlineContentOptions,\n ) {\n this.client = db.rawClient;\n this.maxEntriesPerScope = opts?.maxEntriesPerScope ?? MAX_ENTRIES_PER_SCOPE;\n this.maxBytesPerScope =\n typeof opts?.maxBytesPerScope === \"number\" && opts.maxBytesPerScope > 0\n ? opts.maxBytesPerScope\n : 0;\n this.inline = resolveInlineConfig(opts);\n }\n\n /**\n * Current Σ size of this scope's file rows (upload-limits Phase 5 byte quota).\n * SQLite (local Node) has no D1 rows_read billing, so a direct `SUM(size)` is\n * fine here — same pattern as the file-count quota's `count(\"\")` scan (the\n * trigger-maintained `scope_meta.total_bytes` is a D1-only optimization).\n */\n private async scopeTotalBytes(): Promise<number> {\n const r = await this.client.execute({\n sql: \"SELECT COALESCE(SUM(size), 0) as total FROM ds_entries WHERE scope = ? AND kind = 'file'\",\n args: [this.scope],\n });\n return Number((r.rows[0] as { total?: number } | undefined)?.total ?? 0);\n }\n\n async get(path: string, opts?: { includeContent?: boolean }): Promise<TreeEntry | null> {\n // Content column projected ONLY for inline-enabled indexes — a default-off\n // index keeps issuing byte-identical legacy SQL (see d1-tree-index.ts).\n // `includeContent` (default true) lets metadata-only callers skip the\n // inline copy.\n const contentCol =\n (opts?.includeContent ?? true) && this.inline.inlineCache === \"on\" ? \", content\" : \"\";\n const result = await this.client.execute({\n sql: `SELECT cid, size, mtime, ctime, mime_type, metadata${contentCol} FROM ds_entries WHERE scope = ? AND path = ?`,\n args: [this.scope, path],\n });\n const row = result.rows[0];\n if (!row || row.cid == null) return null;\n const entry: TreeEntry = {\n cid: row.cid as string,\n size: num(row.size),\n mtime: num(row.mtime),\n ctime: num(row.ctime),\n mimeType: (row.mime_type as string | null) ?? undefined,\n };\n if (row.content != null) entry.content = row.content as string;\n const meta = parseTreeEntryMetadata(row.metadata);\n if (meta) entry.metadata = meta;\n return entry;\n }\n\n async getDirTimes(dirPath: string): Promise<{ ctime: number; mtime: number } | null> {\n // No `cid` filter (dir rows are cid-less, unlike get()); the trailing-slash\n // dirPath is the scaffolded directory row key (ancestorDirs form).\n const result = await this.client.execute({\n sql: \"SELECT ctime, mtime FROM ds_entries WHERE scope = ? AND path = ?\",\n args: [this.scope, dirPath],\n });\n const row = result.rows[0];\n return row ? { ctime: num(row.ctime), mtime: num(row.mtime) } : null;\n }\n\n async put(path: string, entry: TreeEntry, opts: PutOpts): Promise<{ oldCid?: string }> {\n validateDeviceId(opts.deviceId);\n\n const existing = await this.get(path);\n // Skip-if-unchanged: re-writing identical content at an existing path is a\n // no-op (cid IS the content hash + the optimistic-concurrency version).\n // Matching cid+mimeType ⇒ nothing changed, so skip the changelog row +\n // UPSERT. Same contract as D1TreeIndex.put / MemoryTreeIndex.put.\n //\n // EXCEPTION (inline write-through re-fill): when inline caching is on, the\n // skip MUST also confirm the inline `content` column already matches what\n // this write would store. A row whose cid matches but whose inline copy was\n // lost (legacy/unfilled row, or an externally voided copy) would otherwise\n // stay missing forever — the write-through never re-fills it. Recompute the\n // would-be inline content and skip only when the stored column already\n // equals it.\n if (\n existing &&\n existing.cid === entry.cid &&\n existing.mimeType === entry.mimeType &&\n treeEntryMetadataEqual(existing.metadata, entry.metadata)\n ) {\n // Metadata-aware skip (did-space-metadata G4): a metadata-only change\n // keeps the same cid — fall through to the UPSERT so it lands.\n if (this.inline.inlineCache !== \"on\") return { oldCid: existing.cid };\n const wouldBeInline = await resolveInlineContent(entry, this.inline);\n if ((existing.content ?? null) === wouldBeInline) return { oldCid: existing.cid };\n // Inline copy is out of sync with the desired state — fall through to the\n // UPSERT so the content column is re-filled (or cleared) to match the cid.\n }\n if (!existing) {\n const currentCount = await this.count(\"\");\n if (currentCount >= this.maxEntriesPerScope) {\n throw storageQuotaError(\n `Storage quota exceeded: scope \"${this.scope}\" has reached the ${this.maxEntriesPerScope} file limit`,\n );\n }\n }\n // upload-limits Phase 5 byte quota (opt-in; OFF when maxBytesPerScope===0).\n // Guard the NET byte delta (overwrite-aware) so a grow-past-quota overwrite\n // is also rejected. Direct SUM is fine on local SQLite (no D1 rows_read tax).\n if (this.maxBytesPerScope > 0) {\n const newBytes = entry.size - (existing?.size ?? 0);\n if (newBytes > 0) {\n const total = await this.scopeTotalBytes();\n if (total + newBytes > this.maxBytesPerScope) {\n throw storageQuotaError(\n `Storage quota exceeded: scope \"${this.scope}\" has reached the ${this.maxBytesPerScope}-byte limit`,\n );\n }\n }\n }\n\n const now = Date.now();\n const stmts: Array<{ sql: string; args: InValue[] }> = [];\n\n // Parent directory chain — preserves any existing dir row. Rule R2\n // (feed-sort §5.2): the DIRECT parent's ctime/mtime are stamped from this\n // write's application createdAt (when present); ancestors stay scaffold-\n // only INSERT OR IGNORE.\n const dirStamp = resolveParentDirStamp(entry.metadata);\n const directParent = parentOf(path);\n for (const dirPath of ancestorDirs(path)) {\n stmts.push(\n buildDirChainStmt(\n this.scope,\n dirPath,\n dirStamp && dirPath === directParent ? dirStamp : null,\n now,\n ),\n );\n }\n\n // Changelog row FIRST, with a correlated subquery for old_cid so the prior\n // cid is read INSIDE the atomic batch (before the UPSERT below overwrites\n // it). Same ordering invariant as D1TreeIndex.put.\n if (!opts.skipChangelog) {\n stmts.push({\n sql: CHANGELOG_INSERT_SQL_WITH_SUBQUERY,\n args: [\n this.scope,\n path,\n entry.cid,\n this.scope,\n path,\n entry.size,\n entry.mtime,\n opts.deviceId,\n ],\n });\n }\n\n // File UPSERT — ctime is set ONLY on first insert; ON CONFLICT preserves it.\n stmts.push(await this.buildFileUpsert(path, entry));\n\n // prefix_watermark bump (Live Update Resilience §11.4) — same atomic batch.\n if (!opts.skipChangelog) {\n const wmPrefix = watermarkWritePrefix(path);\n if (wmPrefix !== null) {\n stmts.push({ sql: PREFIX_WATERMARK_BUMP_SQL, args: [this.scope, wmPrefix] });\n }\n }\n\n await this.client.batch(stmts, \"write\");\n return { oldCid: existing?.cid };\n }\n\n /** Inline content this entry would store — drives loopBatchPutEntries' content-aware skip. */\n inlineForEntry(entry: TreeEntry): Promise<string | null> {\n return resolveInlineContent(entry, this.inline);\n }\n\n // ========== Dedup-on-write secondary index (#1159) ==========\n\n /** Point seek on the `(scope, dedup_scope, dedup_key)` partial UNIQUE index. */\n async findByDedupKey(\n dedupScope: string,\n dedupKey: string,\n ): Promise<({ path: string } & TreeEntry) | null> {\n const result = await this.client.execute({\n sql: `SELECT path, cid, size, mtime, ctime, mime_type, metadata\n FROM ds_entries WHERE scope = ? AND dedup_scope = ? AND dedup_key = ? LIMIT 1`,\n args: [this.scope, dedupScope, dedupKey],\n });\n const row = result.rows[0];\n if (!row || row.cid == null) return null;\n const entry: { path: string } & TreeEntry = {\n path: row.path as string,\n cid: row.cid as string,\n size: num(row.size),\n mtime: num(row.mtime),\n ctime: num(row.ctime),\n mimeType: (row.mime_type as string | null) ?? undefined,\n };\n const meta = parseTreeEntryMetadata(row.metadata);\n if (meta) entry.metadata = meta;\n return entry;\n }\n\n /** Index-only backfill: set the dedup columns without touching content/changelog. */\n async setDedupKey(\n path: string,\n dedupScope: string,\n dedupKey: string,\n opts: PutOpts,\n ): Promise<void> {\n validateDeviceId(opts.deviceId);\n await this.client.execute({\n sql: \"UPDATE ds_entries SET dedup_scope = ?, dedup_key = ? WHERE scope = ? AND path = ?\",\n args: [dedupScope, dedupKey, this.scope, path],\n });\n }\n\n async getPrefixWatermark(prefix: string): Promise<number | null> {\n const wmPrefix = watermarkPrefix(prefix);\n if (wmPrefix === null) return null;\n const result = await this.client.execute({\n sql: PREFIX_WATERMARK_READ_SQL,\n args: [this.scope, wmPrefix],\n });\n return num(result.rows[0]?.version);\n }\n\n /**\n * Build the file-row UPSERT. Inline-enabled indexes always write the\n * content column (inline copy or NULL — an overwrite without inline content\n * MUST clear any prior copy so the column never goes stale relative to the\n * new cid); default-off indexes keep the byte-identical legacy statement\n * (and never touch a not-yet-migrated database's missing column).\n */\n private async buildFileUpsert(\n path: string,\n entry: TreeEntry,\n ): Promise<{ sql: string; args: InValue[] }> {\n const base: InValue[] = [\n this.scope,\n path,\n parentOf(path),\n nameOf(path),\n entry.cid,\n entry.size,\n entry.mimeType ?? null,\n entry.ctime,\n entry.mtime,\n ];\n const metadataValue = serializeTreeEntryMetadata(entry.metadata);\n // Dedup-on-write columns (#1159). COALESCE on overwrite so a plain edit\n // (which carries no dedup fields) never drops a dedup row out of the index;\n // a dedup write / reindex supplies them and they win.\n const dedupScopeValue = entry.dedupScope ?? null;\n const dedupKeyValue = entry.dedupKey ?? null;\n if (this.inline.inlineCache !== \"on\") {\n return {\n sql: `INSERT INTO ds_entries (scope, path, parent, name, kind, cid, size, mime_type, ctime, mtime, metadata, dedup_scope, dedup_key)\n VALUES (?, ?, ?, ?, 'file', ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(scope, path) DO UPDATE SET\n cid = excluded.cid,\n size = excluded.size,\n mtime = excluded.mtime,\n mime_type = excluded.mime_type,\n metadata = excluded.metadata,\n dedup_scope = COALESCE(excluded.dedup_scope, ds_entries.dedup_scope),\n dedup_key = COALESCE(excluded.dedup_key, ds_entries.dedup_key)`,\n args: [...base, metadataValue, dedupScopeValue, dedupKeyValue],\n };\n }\n const inlineContent = await resolveInlineContent(entry, this.inline);\n return {\n sql: `INSERT INTO ds_entries (scope, path, parent, name, kind, cid, size, mime_type, ctime, mtime, content, metadata, dedup_scope, dedup_key)\n VALUES (?, ?, ?, ?, 'file', ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(scope, path) DO UPDATE SET\n cid = excluded.cid,\n size = excluded.size,\n mtime = excluded.mtime,\n mime_type = excluded.mime_type,\n content = excluded.content,\n metadata = excluded.metadata,\n dedup_scope = COALESCE(excluded.dedup_scope, ds_entries.dedup_scope),\n dedup_key = COALESCE(excluded.dedup_key, ds_entries.dedup_key)`,\n args: [...base, inlineContent, metadataValue, dedupScopeValue, dedupKeyValue],\n };\n }\n\n async delete(path: string, opts: PutOpts): Promise<void> {\n validateDeviceId(opts.deviceId);\n\n const stmts: Array<{ sql: string; args: InValue[] }> = [];\n if (!opts.skipChangelog) {\n // INSERT...SELECT logs the delete ONLY when a file row with a non-null cid\n // exists (no phantom delete rows for dirs or missing paths).\n stmts.push({\n sql: `INSERT INTO ds_changelog (scope, path, op, cid, old_cid, size, mtime, device_id)\n SELECT ?, ?, 'delete', NULL, cid, NULL, ?, ?\n FROM ds_entries WHERE scope = ? AND path = ? AND cid IS NOT NULL`,\n // T1.5: client mtime when supplied (echo prevention + LWW), else server clock.\n args: [this.scope, path, opts.mtime ?? Date.now(), opts.deviceId, this.scope, path],\n });\n }\n stmts.push({\n sql: \"DELETE FROM ds_entries WHERE scope = ? AND path = ?\",\n args: [this.scope, path],\n });\n if (!opts.skipChangelog) {\n const wmPrefix = watermarkWritePrefix(path);\n if (wmPrefix !== null) {\n stmts.push({ sql: PREFIX_WATERMARK_BUMP_SQL, args: [this.scope, wmPrefix] });\n }\n }\n await this.client.batch(stmts, \"write\");\n\n await this.cleanEmptyParents(path);\n }\n\n private async cleanEmptyParents(path: string): Promise<void> {\n for (const dirPath of ancestorDirs(path)) {\n const res = await this.client.execute({\n sql: \"SELECT 1 FROM ds_entries WHERE scope = ? AND parent = ? LIMIT 1\",\n args: [this.scope, dirPath],\n });\n if (res.rows.length > 0) break;\n await this.client.execute({\n sql: \"DELETE FROM ds_entries WHERE scope = ? AND path = ?\",\n args: [this.scope, dirPath],\n });\n }\n }\n\n async list(prefix: string, options?: TreeIndexListOptions): Promise<TreeIndexListResult> {\n const limit = options?.limit ?? 1000;\n const col = VALID_ORDER_BY[options?.orderBy ?? \"path\"];\n if (!col) throw new Error(`Invalid orderBy: ${options?.orderBy}`);\n const order = options?.order ?? \"asc\";\n if (limit === 0) return { entries: [], hasMore: false };\n\n const [lo, hi] = prefixRange(prefix);\n const args: InValue[] = [this.scope, lo, hi];\n let sql = `SELECT path, ${col} as _sort FROM ds_entries WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file'`;\n if (options?.cursor) {\n sql += ` AND ${col} ${order === \"asc\" ? \">\" : \"<\"} ?`;\n args.push(options.cursor);\n }\n sql += ` ORDER BY ${col} ${order} LIMIT ?`;\n args.push(limit + 1);\n\n const result = await this.client.execute({ sql, args });\n const hasMore = result.rows.length > limit;\n const rows = hasMore ? result.rows.slice(0, limit) : result.rows;\n return {\n entries: rows.map((r) => ({ path: r.path as string })),\n hasMore,\n cursor: hasMore && rows.length > 0 ? String(rows[rows.length - 1]!._sort) : undefined,\n };\n }\n\n async listEntries(\n prefix: string,\n options?: TreeIndexListOptions,\n ): Promise<TreeIndexListEntriesResult> {\n const limit = options?.limit ?? 1000;\n const hasOrderBy = options?.orderBy !== undefined;\n const col = VALID_ORDER_BY[options?.orderBy ?? \"path\"];\n if (!col) throw new Error(`Invalid orderBy: ${options?.orderBy}`);\n const order = options?.order === \"desc\" ? \"desc\" : \"asc\";\n if (limit === 0) return { entries: [], hasMore: false };\n\n const parsed = parseTreeCursor(options?.cursor, hasOrderBy);\n const [lo, hi] = prefixRange(prefix);\n const args: InValue[] = [this.scope, lo, hi];\n // includeContent is opt-in projection — the default SELECT never touches\n // the content column (zero-regression for every existing list path).\n const contentCol = options?.includeContent ? \", content\" : \"\";\n // Projecting non-indexed columns (cid/size/mtime/...) makes the planner\n // default to the PRIMARY KEY path-range scan instead of idx_entries_kind\n // (scope, kind, path) — reading every dir row in the range too (same\n // planner behavior confirmed on libsql as on D1, see d1-tree-index.ts).\n // Only force the hint when the sort column is `path` itself, matching the\n // index's own order — other orderBy columns still need a manual sort.\n const indexHint = col === \"path\" ? \" INDEXED BY idx_entries_kind\" : \"\";\n let sql = `SELECT path, cid, size, mtime, ctime, mime_type${contentCol} FROM ds_entries${indexHint} WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file'`;\n\n if (hasOrderBy) {\n // Keyset resume on (col, path) — path is the unique tiebreak. NULL\n // mime_type sorts last in both directions. See tree-index.ts helpers.\n const parts = buildOrderedQueryParts({\n col,\n nullable: NULLABLE_ORDER_COLUMNS.has(col),\n order,\n tieCol: \"path\",\n cursor: parsed.kind === \"v2\" ? parsed.cursor : undefined,\n });\n if (parts.cursorWhereSql) {\n sql += ` AND ${parts.cursorWhereSql}`;\n args.push(...parts.cursorArgs);\n }\n sql += ` ORDER BY ${parts.orderSql} LIMIT ?`;\n } else {\n // Legacy path — byte-identical to the pre-orderBy behavior.\n if (parsed.kind === \"legacy\") {\n sql += ` AND ${col} ${order === \"asc\" ? \">\" : \"<\"} ?`;\n args.push(parsed.value);\n }\n sql += ` ORDER BY ${col} ${order} LIMIT ?`;\n }\n args.push(limit + 1);\n\n const result = await this.client.execute({ sql, args });\n const hasMore = result.rows.length > limit;\n const rows = hasMore ? result.rows.slice(0, limit) : result.rows;\n const last = rows[rows.length - 1];\n const cursor =\n !hasMore || !last\n ? undefined\n : hasOrderBy\n ? buildKeysetCursor(sortValueOf(last, col), last.path as string)\n : String(last.path); // legacy default order is path — same value `_sort` held\n return {\n entries: rows.map((r) => {\n const e: { path: string } & TreeEntry = {\n path: r.path as string,\n cid: r.cid as string,\n size: num(r.size),\n mtime: num(r.mtime),\n ctime: num(r.ctime),\n mimeType: (r.mime_type as string | null) ?? undefined,\n };\n if (options?.includeContent && r.content != null) e.content = r.content as string;\n return e;\n }),\n hasMore,\n cursor,\n };\n }\n\n async hasChildren(prefix: string): Promise<boolean> {\n const [lo, hi] = prefixRange(prefix);\n const result = await this.client.execute({\n sql: \"SELECT 1 FROM ds_entries WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file' LIMIT 1\",\n args: [this.scope, lo, hi],\n });\n return result.rows.length > 0;\n }\n\n async count(prefix: string): Promise<number> {\n const [lo, hi] = prefixRange(prefix);\n const result = await this.client.execute({\n sql: \"SELECT COUNT(*) as cnt FROM ds_entries WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file'\",\n args: [this.scope, lo, hi],\n });\n return num(result.rows[0]?.cnt);\n }\n\n async deleteByPrefix(prefix: string, opts: PutOpts): Promise<number> {\n validateDeviceId(opts.deviceId);\n const [lo, hi] = prefixRange(prefix);\n\n const stmts: Array<{ sql: string; args: InValue[] }> = [];\n if (!opts.skipChangelog) {\n stmts.push({\n sql: `INSERT INTO ds_changelog (scope, path, op, cid, old_cid, size, mtime, device_id)\n SELECT ?, path, 'delete', NULL, cid, NULL, ?, ?\n FROM ds_entries INDEXED BY idx_entries_kind WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file' AND cid IS NOT NULL`,\n // T1.5: client mtime when supplied (echo prevention + LWW), else server clock.\n args: [this.scope, opts.mtime ?? Date.now(), opts.deviceId, this.scope, lo, hi],\n });\n }\n // Watermark bump BEFORE the DELETE so the DELETE stays the last statement\n // (rowsAffected read below). First segment of the prefix (subtree delete).\n if (!opts.skipChangelog) {\n const wmPrefix = watermarkPrefix(prefix);\n if (wmPrefix !== null) {\n stmts.push({ sql: PREFIX_WATERMARK_BUMP_SQL, args: [this.scope, wmPrefix] });\n }\n }\n stmts.push({\n sql: \"DELETE FROM ds_entries WHERE scope = ? AND path >= ? AND path < ?\",\n args: [this.scope, lo, hi],\n });\n\n const results = await this.client.batch(stmts, \"write\");\n // Last stmt is the DELETE; rowsAffected includes dir rows (matches D1).\n return num(results[results.length - 1]?.rowsAffected);\n }\n\n async listChildren(\n parent: string,\n options?: TreeIndexListOptions,\n ): Promise<TreeIndexListEntriesResult> {\n const limit = options?.limit ?? 1000;\n const order = options?.order === \"desc\" ? \"desc\" : \"asc\";\n if (limit === 0) return { entries: [], hasMore: false };\n\n const hasOrderBy = options?.orderBy !== undefined;\n const parsed = parseTreeCursor(options?.cursor, hasOrderBy);\n const includeContent = options?.includeContent === true;\n // Candidates FROM clause comes from the SHARED builder (tree-query.ts).\n // Dir-per-record joins moved to the query engine's doc form (T4.3) —\n // listChildren is always join-free now.\n const t = \"e.\";\n const from = buildChildrenFrom(undefined);\n const args: InValue[] = [...from.args, this.scope, parent];\n const contentCol = includeContent ? `, ${t}content` : \"\";\n let sql = `SELECT ${t}path, ${t}cid, ${t}size, ${t}mtime, ${t}ctime, ${t}mime_type, ${t}name${contentCol} ${from.sql} WHERE ${t}scope = ? AND ${t}parent = ?`;\n\n if (hasOrderBy) {\n const col = VALID_ORDER_BY[options!.orderBy!];\n if (!col) throw new Error(`Invalid orderBy: ${options?.orderBy}`);\n // Keyset resume on (col, name) — name is unique within a parent.\n const parts = buildOrderedQueryParts({\n col: `${t}${col}`,\n nullable: NULLABLE_ORDER_COLUMNS.has(col),\n order,\n tieCol: `${t}name`,\n cursor: parsed.kind === \"v2\" ? parsed.cursor : undefined,\n });\n if (parts.cursorWhereSql) {\n sql += ` AND ${parts.cursorWhereSql}`;\n args.push(...parts.cursorArgs);\n }\n sql += ` ORDER BY ${parts.orderSql} LIMIT ?`;\n args.push(limit + 1);\n\n const result = await this.client.execute({ sql, args });\n const hasMore = result.rows.length > limit;\n const rows = hasMore ? result.rows.slice(0, limit) : result.rows;\n const last = rows[rows.length - 1];\n return {\n entries: rows.map((r) => mapChildRow(r)),\n hasMore,\n cursor:\n hasMore && last\n ? buildKeysetCursor(sortValueOf(last, col), last.name as string)\n : undefined,\n };\n }\n\n // Legacy default path — byte-identical: ORDER BY name, plain name cursor.\n if (parsed.kind === \"legacy\") {\n sql += ` AND ${t}name ${order === \"asc\" ? \">\" : \"<\"} ?`;\n args.push(parsed.value);\n }\n sql += ` ORDER BY ${t}name ${order} LIMIT ?`;\n args.push(limit + 1);\n\n const result = await this.client.execute({ sql, args });\n const hasMore = result.rows.length > limit;\n const rows = hasMore ? result.rows.slice(0, limit) : result.rows;\n return {\n entries: rows.map((r) => mapChildRow(r)),\n hasMore,\n cursor: hasMore && rows.length > 0 ? String(rows[rows.length - 1]!.name) : undefined,\n };\n }\n\n async countChildren(parent: string): Promise<number> {\n const result = await this.client.execute({\n sql: \"SELECT COUNT(*) as cnt FROM ds_entries WHERE scope = ? AND parent = ?\",\n args: [this.scope, parent],\n });\n return num(result.rows[0]?.cnt);\n }\n\n /** Collection query (afs-collection-query Phase 1) — see tree-query.ts. */\n async query(parent: string, spec: TreeQuerySpec): Promise<TreeQueryResult> {\n const statements = buildTreeQueryStatements({ scope: this.scope, parent, spec });\n\n // Aggregate-mode (Phase 2 / G2.D): swaps the rows+count SQL for the\n // single aggregate SELECT + a group-cardinality counter.\n if (statements.aggregate) {\n const [aggRes, countRes] = await Promise.all([\n this.client.execute({\n sql: statements.aggregate.select.sql,\n args: statements.aggregate.select.args,\n }),\n this.client.execute({\n sql: statements.aggregate.countGroups.sql,\n args: statements.aggregate.countGroups.args,\n }),\n ]);\n // Zero-dim groupBy with empty input: SQL gives one row (because\n // `SELECT count(*)` always returns one) but the values are 0 — that\n // matches the reference behavior; no special handling needed.\n const aggregateGroups = mapAggregateRows(\n aggRes.rows as unknown as Array<Record<string, unknown>>,\n statements.aggregate.groupKeys,\n statements.aggregate.aggregations,\n );\n // total = number of distinct group rows; zero-dim path returns 1 (one\n // forced row, matching the reference's zero-dim exception).\n const total = statements.aggregate.groupKeys.length === 0 ? 1 : num(countRes.rows[0]?.cnt);\n return { rows: [], total, aggregateGroups };\n }\n\n const [rowsRes, countRes, groupsRes, seekRes] = await Promise.all([\n this.client.execute({ sql: statements.rows.sql, args: statements.rows.args }),\n // skipTotal: no count statement was built — skip the full-directory scan\n // and report total: -1 below.\n statements.count\n ? this.client.execute({ sql: statements.count.sql, args: statements.count.args })\n : Promise.resolve(undefined),\n statements.groups\n ? this.client.execute({ sql: statements.groups.sql, args: statements.groups.args })\n : Promise.resolve(undefined),\n statements.seek\n ? this.client.execute({ sql: statements.seek.sql, args: statements.seek.args })\n : Promise.resolve(undefined),\n ]);\n\n const seekOffset = statements.seek\n ? seekRes && seekRes.rows.length > 0\n ? num(seekRes.rows[0]?.rn)\n : -1\n : undefined;\n\n return buildTreeQueryResultFromSql({\n rawRows: rowsRes.rows as unknown as Array<Record<string, unknown>>,\n total: countRes ? num(countRes.rows[0]?.cnt) : -1,\n groupRows: groupsRes?.rows.map((r) => ({ t: r.t, v: r.v, cnt: r.cnt })),\n spec,\n orderField: statements.order.field,\n seekOffset,\n });\n }\n\n /** Page-bounded grouped child counts — see D1TreeIndex.countChildrenMany\n * (same ≤90-per-chunk shape kept for cross-backend statement parity). */\n async countChildrenMany(parents: string[]): Promise<Map<string, number>> {\n const map = new Map<string, number>();\n for (let offset = 0; offset < parents.length; offset += 90) {\n const chunk = parents.slice(offset, offset + 90);\n const result = await this.client.execute({\n sql: `SELECT parent, COUNT(*) as cnt FROM ds_entries WHERE scope = ? AND parent IN (${chunk.map(() => \"?\").join(\",\")}) GROUP BY parent`,\n args: [this.scope, ...chunk],\n });\n for (const r of result.rows) map.set(r.parent as string, num(r.cnt));\n }\n return map;\n }\n\n async aggregate(prefix: string): Promise<{ fileCount: number; totalSize: number }> {\n const [lo, hi] = prefixRange(prefix);\n const result = await this.client.execute({\n sql: `SELECT COUNT(*) as file_count, COALESCE(SUM(size), 0) as total_size\n FROM ds_entries INDEXED BY idx_entries_kind WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file'`,\n args: [this.scope, lo, hi],\n });\n const row = result.rows[0];\n return { fileCount: num(row?.file_count), totalSize: num(row?.total_size) };\n }\n\n /** Batch metadata read — loop over get (no IN-merge needed off-CF). */\n async getMany(paths: string[]): Promise<Map<string, TreeEntry | null>> {\n const map = new Map<string, TreeEntry | null>();\n for (const path of paths) map.set(path, await this.get(path));\n return map;\n }\n\n /** Batch sync fast path — loop reference semantics (conformance-pinned\n * equivalent of the merged D1 implementation). */\n async batchPutEntries(\n entries: BatchPutEntry[],\n ctx?: BatchIndexContext,\n ): Promise<BatchPutEntryResult[]> {\n return loopBatchPutEntries(this, entries, ctx);\n }\n\n /** Delete twin of {@link batchPutEntries} (loop reference semantics). */\n async batchDeleteEntries(\n entries: BatchDeleteEntry[],\n ctx?: BatchIndexContext,\n ): Promise<BatchDeleteEntryResult[]> {\n return loopBatchDeleteEntries(this, entries, ctx);\n }\n\n async putBatch(entries: Array<{ path: string; entry: TreeEntry }>, opts: PutOpts): Promise<void> {\n if (entries.length === 0) return;\n validateDeviceId(opts.deviceId);\n\n const now = Date.now();\n const stmts: Array<{ sql: string; args: InValue[] }> = [];\n\n // Rule R2 (feed-sort §5.2): stamp each direct parent of a createdAt-bearing\n // write (LWW by entry order); ancestors stay scaffold-only INSERT OR IGNORE.\n const dirStamps = new Map<string, { ctime: number; mtime: number }>();\n const allDirs = new Set<string>();\n for (const { path, entry } of entries) {\n const stamp = resolveParentDirStamp(entry.metadata);\n if (stamp) dirStamps.set(parentOf(path), stamp);\n for (const dirPath of ancestorDirs(path)) {\n if (allDirs.has(dirPath)) break;\n allDirs.add(dirPath);\n }\n }\n for (const dirPath of allDirs) {\n stmts.push(buildDirChainStmt(this.scope, dirPath, dirStamps.get(dirPath) ?? null, now));\n }\n\n for (const { path, entry } of entries) {\n if (!opts.skipChangelog) {\n stmts.push({\n sql: CHANGELOG_INSERT_SQL_WITH_SUBQUERY,\n args: [\n this.scope,\n path,\n entry.cid,\n this.scope,\n path,\n entry.size,\n entry.mtime,\n opts.deviceId,\n ],\n });\n }\n stmts.push(await this.buildFileUpsert(path, entry));\n }\n\n // One watermark bump per DISTINCT collection root touched (matches D1).\n if (!opts.skipChangelog) {\n const wmPrefixes = new Set<string>();\n for (const { path } of entries) {\n const wmPrefix = watermarkWritePrefix(path);\n if (wmPrefix !== null) wmPrefixes.add(wmPrefix);\n }\n for (const wmPrefix of wmPrefixes) {\n stmts.push({ sql: PREFIX_WATERMARK_BUMP_SQL, args: [this.scope, wmPrefix] });\n }\n }\n\n await this.client.batch(stmts, \"write\");\n }\n\n async listModifiedSince(\n prefix: string,\n since: number,\n options?: TreeIndexListOptions,\n ): Promise<TreeIndexListEntriesResult> {\n const limit = options?.limit ?? 1000;\n const order = options?.order ?? \"asc\";\n if (limit === 0) return { entries: [], hasMore: false };\n\n const [lo, hi] = prefixRange(prefix);\n const args: InValue[] = [this.scope, lo, hi, since];\n let sql = `SELECT path, cid, size, mtime, ctime, mime_type FROM ds_entries INDEXED BY idx_entries_kind\n WHERE scope = ? AND path >= ? AND path < ? AND mtime > ? AND kind = 'file'`;\n if (options?.cursor) {\n sql += ` AND path ${order === \"asc\" ? \">\" : \"<\"} ?`;\n args.push(options.cursor);\n }\n sql += ` ORDER BY path ${order} LIMIT ?`;\n args.push(limit + 1);\n\n const result = await this.client.execute({ sql, args });\n const hasMore = result.rows.length > limit;\n const rows = hasMore ? result.rows.slice(0, limit) : result.rows;\n return {\n entries: rows.map((r) => ({\n path: r.path as string,\n cid: r.cid as string,\n size: num(r.size),\n mtime: num(r.mtime),\n ctime: num(r.ctime),\n mimeType: (r.mime_type as string | null) ?? undefined,\n })),\n hasMore,\n cursor: hasMore && rows.length > 0 ? String(rows[rows.length - 1]!.path) : undefined,\n };\n }\n\n async getMaxSeq(): Promise<number> {\n const [result, compactedBelow] = await Promise.all([\n this.client.execute({\n sql: \"SELECT MAX(seq) as maxSeq FROM ds_changelog WHERE scope = ?\",\n args: [this.scope],\n }),\n this.getCompactedBelowSeq(),\n ]);\n return Math.max(num(result.rows[0]?.maxSeq), compactedBelow);\n }\n\n /**\n * Read-auth reference check (design §4.1) — three-way, scoped, optionally\n * prefix-local. See {@link TreeIndex.isReferenced}.\n */\n async isReferenced(cid: string, pathPrefix = \"\"): Promise<boolean> {\n if (!cid) return false;\n // Whole-scope (pathPrefix \"\") applies NO path filter — see the matching\n // comment in D1TreeIndex.isReferenced (the `prefixRange(\"\")` `\\xff` sentinel\n // mis-sorts multibyte UTF-8 paths).\n if (pathPrefix === \"\") {\n const result = await this.client.execute({\n sql: `SELECT 1 FROM (\n SELECT 1 FROM ds_entries WHERE scope = ? AND cid = ?\n UNION ALL\n SELECT 1 FROM ds_changelog WHERE scope = ? AND cid = ?\n UNION ALL\n SELECT 1 FROM ds_changelog WHERE scope = ? AND old_cid = ?\n ) LIMIT 1`,\n args: [this.scope, cid, this.scope, cid, this.scope, cid],\n });\n return result.rows.length > 0;\n }\n const [lo, hi] = prefixRange(pathPrefix);\n const result = await this.client.execute({\n sql: `SELECT 1 FROM (\n SELECT 1 FROM ds_entries WHERE scope = ? AND cid = ? AND path >= ? AND path < ?\n UNION ALL\n SELECT 1 FROM ds_changelog WHERE scope = ? AND cid = ? AND path >= ? AND path < ?\n UNION ALL\n SELECT 1 FROM ds_changelog WHERE scope = ? AND old_cid = ? AND path >= ? AND path < ?\n ) LIMIT 1`,\n args: [this.scope, cid, lo, hi, this.scope, cid, lo, hi, this.scope, cid, lo, hi],\n });\n return result.rows.length > 0;\n }\n\n /**\n * Batch read-auth (design §7.2 / §14) — three-way-equivalent to per-cid\n * {@link isReferenced}, sharded (see {@link SQLITE_MANY_SHARD_SIZE}). Returns\n * the referenced subset of `cids`.\n */\n async isReferencedMany(cids: string[], pathPrefix = \"\"): Promise<Set<string>> {\n const referenced = new Set<string>();\n const unique = [...new Set(cids.filter((c) => c))];\n if (unique.length === 0) return referenced;\n const usePrefix = pathPrefix !== \"\";\n const [lo, hi] = usePrefix ? prefixRange(pathPrefix) : [\"\", \"\"];\n for (let i = 0; i < unique.length; i += SQLITE_MANY_SHARD_SIZE) {\n const shard = unique.slice(i, i + SQLITE_MANY_SHARD_SIZE);\n const ph = shard.map(() => \"?\").join(\",\");\n const tail = usePrefix ? \"AND path >= ? AND path < ?\" : \"\";\n const sql = `SELECT cid AS c FROM ds_entries WHERE scope = ? AND cid IN (${ph}) ${tail}\n UNION\n SELECT cid AS c FROM ds_changelog WHERE scope = ? AND cid IN (${ph}) ${tail}\n UNION\n SELECT old_cid AS c FROM ds_changelog WHERE scope = ? AND old_cid IN (${ph}) ${tail}`;\n const args: InValue[] = [];\n for (let b = 0; b < 3; b++) {\n args.push(this.scope, ...shard);\n if (usePrefix) args.push(lo, hi);\n }\n const result = await this.client.execute({ sql, args });\n for (const row of result.rows) {\n const c = row.c as string | null;\n if (c) referenced.add(c);\n }\n }\n return referenced;\n }\n\n async getChangelogSince(\n sinceSeq: number,\n limit: number,\n ): Promise<{ entries: ChangelogEntry[]; hasMore: boolean; cursor: number }> {\n const safeLimit = limit > 0 ? limit : 0;\n if (safeLimit === 0) return { entries: [], hasMore: false, cursor: sinceSeq };\n\n const result = await this.client.execute({\n sql: `SELECT seq, scope, path, op, cid, old_cid, size, mtime, device_id\n FROM ds_changelog WHERE scope = ? AND seq > ? ORDER BY seq ASC LIMIT ?`,\n args: [this.scope, sinceSeq, safeLimit + 1],\n });\n const hasMore = result.rows.length > safeLimit;\n const rows = hasMore ? result.rows.slice(0, safeLimit) : result.rows;\n const entries: ChangelogEntry[] = rows.map((r) => ({\n seq: num(r.seq),\n scope: r.scope as string,\n path: r.path as string,\n op: r.op as \"put\" | \"delete\",\n cid: (r.cid as string | null) ?? null,\n old_cid: (r.old_cid as string | null) ?? null,\n size: r.size == null ? null : num(r.size),\n mtime: num(r.mtime),\n device_id: r.device_id as string,\n }));\n const cursor = entries.length > 0 ? entries[entries.length - 1]!.seq : sinceSeq;\n return { entries, hasMore, cursor };\n }\n\n async getCompactedBelowSeq(): Promise<number> {\n // Node/SQLite has no compaction job yet (Phase 2). Return 0 (permissive).\n return 0;\n }\n\n // ========== Source-side dirty queue (index-follower-dirty-path §7) ==========\n //\n // Row-for-row aligned with D1TreeIndex's queue methods; only the client API\n // differs (libsql `execute({sql,args})` + `rowsAffected` vs D1\n // `prepare().bind().run()` + `meta.changes`). The `ds_dirty_path` table +\n // trigger live in the same `_metadata.db` (created by MetadataDB.open), so\n // these operate on the SAME DB that holds `ds_changelog`.\n\n async listDirtyPaths(options: ListDirtyPathOptions): Promise<DirtyPathRow[]> {\n const now = options.now ?? Date.now();\n const limit = options.limit > 0 ? options.limit : 0;\n if (limit === 0) return [];\n const [lo, hi] = prefixRange(options.prefix);\n const { rows } = await this.client.execute({\n sql: DIRTY_PATH_LIST_SQL,\n args: [this.scope, lo, hi, now, limit],\n });\n return rows.map((r) => ({\n path: String(r.path),\n latestSeq: Number(r.latest_seq),\n op: String(r.op) as \"put\" | \"delete\",\n cid: r.cid == null ? null : String(r.cid),\n mtime: Number(r.mtime),\n attempts: Number(r.attempts),\n }));\n }\n\n async ackDirtyPath(path: string, latestSeq: number): Promise<boolean> {\n const res = await this.client.execute({\n sql: DIRTY_PATH_ACK_SQL,\n args: [this.scope, path, latestSeq],\n });\n return (res.rowsAffected ?? 0) > 0;\n }\n\n async markDirtyPathError(\n path: string,\n latestSeq: number,\n error: string,\n nextAttemptAt: number,\n ): Promise<boolean> {\n const res = await this.client.execute({\n sql: DIRTY_PATH_MARK_ERROR_SQL,\n args: [error, nextAttemptAt, this.scope, path, latestSeq],\n });\n return (res.rowsAffected ?? 0) > 0;\n }\n}\n\n/**\n * Put-path changelog INSERT with a correlated subquery reading the pre-write\n * cid as old_cid (mirrors D1TreeIndex). Distinct from the plain\n * `CHANGELOG_INSERT_SQL` in changelog-write.ts which takes old_cid as a bound\n * param (used by MetadataDB.upsertEntry, which pre-reads old_cid separately).\n */\nconst CHANGELOG_INSERT_SQL_WITH_SUBQUERY = `INSERT INTO ds_changelog (scope, path, op, cid, old_cid, size, mtime, device_id)\n VALUES (?, ?, 'put', ?, (SELECT cid FROM ds_entries WHERE scope = ? AND path = ?), ?, ?, ?)`;\n"],"mappings":"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"}