@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,272 @@
1
+ const require_timestamp = require('./timestamp.cjs');
2
+ const require_tree_index = require('./tree-index.cjs');
3
+ const require_d1_tree_index = require('./d1-tree-index.cjs');
4
+
5
+ //#region src/ctime-backfill.ts
6
+ /**
7
+ * ctime-backfill — one-time backfill of `entries.ctime` from the application
8
+ * `createdAt` for data written BEFORE the feed-sort Rule R landed
9
+ * (planning/did-integration/feed-sort-createdat §7).
10
+ *
11
+ * Pre-fix, a FILE row's ctime was its insert time and its DIRECT-parent DIR row
12
+ * was created `INSERT OR IGNORE` with `ctime = Date.now()` and never updated.
13
+ * After Phase 3 switches the feed to `orderBy ctime`, those historical rows
14
+ * would sort by insert time. This sweep rewrites them to match what a fresh
15
+ * write would now stamp (R1 = file ctime, R2 = direct-parent DIR ctime/mtime).
16
+ *
17
+ * Design (mirrors inline-content-migration / scope-migration):
18
+ * - OFFLINE, code-driven. The core loop {@link backfillCtime} is backend-
19
+ * agnostic; the SQL lives in {@link CtimeBackfillBackend} adapters (D1 vs
20
+ * Node SQLite) so it is unit-testable against a mock D1.
21
+ * - **Host-language ISO parse** (`normalizeTs`) — NEVER SQLite `strftime`,
22
+ * which is unreliable for `Z`/offset/ms ISO-8601 (§7).
23
+ * - **WHERE pins `scope`** and binds scope/path as parameters — never a string
24
+ * interpolation; one scope is migrated at a time, never a cross-scope UPDATE.
25
+ * - **Deterministic `ORDER BY path ASC` keyset cursor** ⇒ for a degenerate
26
+ * DIR with several createdAt-bearing children, the LAST in path order wins
27
+ * (same LWW as the write path's R2 — NEVER MIN/MAX). Aside has exactly one
28
+ * createdAt child (`item.json`) per `{uuid}/`, so the result is deterministic.
29
+ * - **Idempotent**: each row is rewritten to `normalizeTs(createdAt)`, a fixed
30
+ * value, so a second pass writes the same value (0 effective change). The
31
+ * cursor advances past EVERY scanned row (including skips) so one invocation
32
+ * can't loop; a fresh invocation re-scans from the start.
33
+ * - **Only ctime/mtime change** — never cid/size/content/metadata. The FILE
34
+ * row's `mtime` (LWW arbiter) is NEVER touched; only its `ctime`. The DIR
35
+ * row gets both ctime+mtime (dir rows carry no LWW meaning, §1 fact 3).
36
+ * - **Batched / bounded** (`pageSize`, `maxPages`) to respect D1 write quota /
37
+ * avoid the O(N²) trap (cf. the D1 file_count burn-through lesson).
38
+ */
39
+ /** Run `fn` over `items` with at most `limit` in flight (single-threaded pool). */
40
+ async function mapPool(items, limit, fn) {
41
+ if (limit <= 1) {
42
+ for (const item of items) await fn(item);
43
+ return;
44
+ }
45
+ let i = 0;
46
+ const worker = async () => {
47
+ while (i < items.length) {
48
+ const item = items[i++];
49
+ if (item !== void 0) await fn(item);
50
+ }
51
+ };
52
+ await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));
53
+ }
54
+ /**
55
+ * Page over createdAt-bearing FILE rows in one scope and rewrite ctime (R1) +
56
+ * the direct-parent DIR stamp (R2). Returns stats; resumable across calls.
57
+ */
58
+ async function backfillCtime(backend, opts = {}) {
59
+ const pageSize = opts.pageSize ?? 200;
60
+ const maxPages = opts.maxPages ?? Number.POSITIVE_INFINITY;
61
+ const concurrency = Math.max(1, opts.concurrency ?? 1);
62
+ const dryRun = opts.dryRun ?? false;
63
+ const log = opts.log ?? (() => {});
64
+ const stats = {
65
+ scanned: 0,
66
+ stamped: 0,
67
+ alreadyCurrent: 0,
68
+ skippedNoCreatedAt: 0,
69
+ pages: 0,
70
+ lastCursor: "",
71
+ done: false
72
+ };
73
+ let cursor = "";
74
+ while (stats.pages < maxPages) {
75
+ const rows = await backend.selectCandidates(cursor, pageSize);
76
+ if (rows.length === 0) {
77
+ stats.done = true;
78
+ break;
79
+ }
80
+ stats.pages++;
81
+ const tasks = [];
82
+ for (const row of rows) {
83
+ stats.scanned++;
84
+ cursor = row.path;
85
+ const stamp = require_timestamp.resolveParentDirStamp(require_tree_index.parseTreeEntryMetadata(row.metadata));
86
+ if (!stamp) {
87
+ stats.skippedNoCreatedAt++;
88
+ continue;
89
+ }
90
+ tasks.push({
91
+ path: row.path,
92
+ ctime: stamp.ctime,
93
+ mtime: stamp.mtime
94
+ });
95
+ }
96
+ if (dryRun) stats.stamped += tasks.length;
97
+ else await mapPool(tasks, concurrency, async (t) => {
98
+ let changed = await backend.updateFileCtime(t.path, t.ctime);
99
+ const dir = require_d1_tree_index.parentOf(t.path);
100
+ if (dir) changed += await backend.updateDirStamp(dir, t.ctime, t.mtime);
101
+ if (changed > 0) stats.stamped++;
102
+ else stats.alreadyCurrent++;
103
+ });
104
+ stats.lastCursor = cursor;
105
+ log(`[ctime-backfill] page ${stats.pages}: scanned=${stats.scanned} stamped=${stats.stamped} cursor=${cursor}`);
106
+ }
107
+ return stats;
108
+ }
109
+ const SELECT_SQL = "SELECT path, metadata FROM ds_entries WHERE scope = ? AND kind = 'file' AND metadata IS NOT NULL AND path > ? ORDER BY path ASC LIMIT ?";
110
+ const UPDATE_FILE_SQL = "UPDATE ds_entries SET ctime = ? WHERE scope = ? AND path = ? AND kind = 'file' AND ctime != ?";
111
+ const UPDATE_DIR_SQL = "UPDATE ds_entries SET ctime = ?, mtime = ? WHERE scope = ? AND path = ? AND kind = 'dir' AND (ctime != ? OR mtime != ?)";
112
+ /** D1 (Cloudflare) backend adapter for one scope. */
113
+ function makeD1CtimeBackfillBackend(db, scope) {
114
+ return {
115
+ async selectCandidates(cursor, limit) {
116
+ return ((await db.prepare(SELECT_SQL).bind(scope, cursor, limit).all()).results ?? []).map((r) => ({
117
+ path: String(r.path),
118
+ metadata: r.metadata === null ? null : String(r.metadata)
119
+ }));
120
+ },
121
+ async updateFileCtime(path, ctime) {
122
+ return (await db.prepare(UPDATE_FILE_SQL).bind(ctime, scope, path, ctime).run()).meta?.changes ?? 0;
123
+ },
124
+ async updateDirStamp(dirPath, ctime, mtime) {
125
+ return (await db.prepare(UPDATE_DIR_SQL).bind(ctime, mtime, scope, dirPath, ctime, mtime).run()).meta?.changes ?? 0;
126
+ }
127
+ };
128
+ }
129
+ /** Node SQLite (libsql) backend adapter for one scope. */
130
+ function makeSqliteCtimeBackfillBackend(db, scope) {
131
+ return {
132
+ async selectCandidates(cursor, limit) {
133
+ return (await db.execute({
134
+ sql: SELECT_SQL,
135
+ args: [
136
+ scope,
137
+ cursor,
138
+ limit
139
+ ]
140
+ })).rows.map((r) => ({
141
+ path: String(r.path),
142
+ metadata: r.metadata === null ? null : String(r.metadata)
143
+ }));
144
+ },
145
+ async updateFileCtime(path, ctime) {
146
+ return (await db.execute({
147
+ sql: UPDATE_FILE_SQL,
148
+ args: [
149
+ ctime,
150
+ scope,
151
+ path,
152
+ ctime
153
+ ]
154
+ })).rowsAffected ?? 0;
155
+ },
156
+ async updateDirStamp(dirPath, ctime, mtime) {
157
+ return (await db.execute({
158
+ sql: UPDATE_DIR_SQL,
159
+ args: [
160
+ ctime,
161
+ mtime,
162
+ scope,
163
+ dirPath,
164
+ ctime,
165
+ mtime
166
+ ]
167
+ })).rowsAffected ?? 0;
168
+ }
169
+ };
170
+ }
171
+ const DISTINCT_SCOPES_SQL = "SELECT DISTINCT scope FROM ds_entries WHERE kind = 'file' AND metadata IS NOT NULL";
172
+ /** Enumerate scopes that have any createdAt-bearing file row (D1). */
173
+ async function distinctScopesWithMetadataD1(db) {
174
+ return ((await db.prepare(DISTINCT_SCOPES_SQL).bind().all()).results ?? []).map((r) => String(r.scope));
175
+ }
176
+ /** Enumerate scopes that have any createdAt-bearing file row (Node SQLite). */
177
+ async function distinctScopesWithMetadataSqlite(db) {
178
+ return (await db.execute({
179
+ sql: DISTINCT_SCOPES_SQL,
180
+ args: []
181
+ })).rows.map((r) => String(r.scope));
182
+ }
183
+ const defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
184
+ async function d1HttpQuery(cfg, sql, params) {
185
+ const f = cfg.fetchImpl ?? fetch;
186
+ const sleep = cfg.sleep ?? defaultSleep;
187
+ const maxRetries = cfg.maxRetries ?? 4;
188
+ const url = `https://api.cloudflare.com/client/v4/accounts/${cfg.accountId}/d1/database/${cfg.databaseId}/query`;
189
+ for (let attempt = 0;; attempt++) {
190
+ let status = 0;
191
+ let json;
192
+ let networkErr;
193
+ try {
194
+ const res = await f(url, {
195
+ method: "POST",
196
+ headers: {
197
+ authorization: `Bearer ${cfg.apiToken}`,
198
+ "content-type": "application/json"
199
+ },
200
+ body: JSON.stringify({
201
+ sql,
202
+ params
203
+ })
204
+ });
205
+ status = res.status;
206
+ json = await res.json();
207
+ } catch (e) {
208
+ networkErr = e;
209
+ }
210
+ if (!networkErr && status >= 200 && status < 300 && json?.success !== false) {
211
+ const r = json?.result?.[0];
212
+ return {
213
+ results: r?.results ?? [],
214
+ changes: r?.meta?.changes ?? 0
215
+ };
216
+ }
217
+ const transient = networkErr != null || status >= 500 || status === 429;
218
+ const msg = networkErr ? `D1 HTTP network error: ${String(networkErr).slice(0, 160)}` : `D1 HTTP ${status}: ${JSON.stringify(json?.errors ?? json).slice(0, 200)}`;
219
+ if (!transient || attempt >= maxRetries) throw new Error(msg);
220
+ await sleep(Math.min(2e3, 200 * 2 ** attempt));
221
+ }
222
+ }
223
+ /** CF D1 HTTP-API backend adapter for one scope (offline admin channel). */
224
+ function makeD1HttpCtimeBackfillBackend(cfg) {
225
+ return {
226
+ async selectCandidates(cursor, limit) {
227
+ const { results } = await d1HttpQuery(cfg, SELECT_SQL, [
228
+ cfg.scope,
229
+ cursor,
230
+ limit
231
+ ]);
232
+ return results.map((r) => ({
233
+ path: String(r.path),
234
+ metadata: r.metadata === null ? null : String(r.metadata)
235
+ }));
236
+ },
237
+ async updateFileCtime(path, ctime) {
238
+ const { changes } = await d1HttpQuery(cfg, UPDATE_FILE_SQL, [
239
+ ctime,
240
+ cfg.scope,
241
+ path,
242
+ ctime
243
+ ]);
244
+ return changes;
245
+ },
246
+ async updateDirStamp(dirPath, ctime, mtime) {
247
+ const { changes } = await d1HttpQuery(cfg, UPDATE_DIR_SQL, [
248
+ ctime,
249
+ mtime,
250
+ cfg.scope,
251
+ dirPath,
252
+ ctime,
253
+ mtime
254
+ ]);
255
+ return changes;
256
+ }
257
+ };
258
+ }
259
+ /** List distinct createdAt-bearing scopes on a CF D1 over HTTP (bulk sweep). */
260
+ async function distinctScopesWithMetadataD1Http(cfg) {
261
+ const { results } = await d1HttpQuery(cfg, DISTINCT_SCOPES_SQL, []);
262
+ return results.map((r) => String(r.scope));
263
+ }
264
+
265
+ //#endregion
266
+ exports.backfillCtime = backfillCtime;
267
+ exports.distinctScopesWithMetadataD1 = distinctScopesWithMetadataD1;
268
+ exports.distinctScopesWithMetadataD1Http = distinctScopesWithMetadataD1Http;
269
+ exports.distinctScopesWithMetadataSqlite = distinctScopesWithMetadataSqlite;
270
+ exports.makeD1CtimeBackfillBackend = makeD1CtimeBackfillBackend;
271
+ exports.makeD1HttpCtimeBackfillBackend = makeD1HttpCtimeBackfillBackend;
272
+ exports.makeSqliteCtimeBackfillBackend = makeSqliteCtimeBackfillBackend;
@@ -0,0 +1,169 @@
1
+ //#region src/ctime-backfill.d.ts
2
+ /**
3
+ * ctime-backfill — one-time backfill of `entries.ctime` from the application
4
+ * `createdAt` for data written BEFORE the feed-sort Rule R landed
5
+ * (planning/did-integration/feed-sort-createdat §7).
6
+ *
7
+ * Pre-fix, a FILE row's ctime was its insert time and its DIRECT-parent DIR row
8
+ * was created `INSERT OR IGNORE` with `ctime = Date.now()` and never updated.
9
+ * After Phase 3 switches the feed to `orderBy ctime`, those historical rows
10
+ * would sort by insert time. This sweep rewrites them to match what a fresh
11
+ * write would now stamp (R1 = file ctime, R2 = direct-parent DIR ctime/mtime).
12
+ *
13
+ * Design (mirrors inline-content-migration / scope-migration):
14
+ * - OFFLINE, code-driven. The core loop {@link backfillCtime} is backend-
15
+ * agnostic; the SQL lives in {@link CtimeBackfillBackend} adapters (D1 vs
16
+ * Node SQLite) so it is unit-testable against a mock D1.
17
+ * - **Host-language ISO parse** (`normalizeTs`) — NEVER SQLite `strftime`,
18
+ * which is unreliable for `Z`/offset/ms ISO-8601 (§7).
19
+ * - **WHERE pins `scope`** and binds scope/path as parameters — never a string
20
+ * interpolation; one scope is migrated at a time, never a cross-scope UPDATE.
21
+ * - **Deterministic `ORDER BY path ASC` keyset cursor** ⇒ for a degenerate
22
+ * DIR with several createdAt-bearing children, the LAST in path order wins
23
+ * (same LWW as the write path's R2 — NEVER MIN/MAX). Aside has exactly one
24
+ * createdAt child (`item.json`) per `{uuid}/`, so the result is deterministic.
25
+ * - **Idempotent**: each row is rewritten to `normalizeTs(createdAt)`, a fixed
26
+ * value, so a second pass writes the same value (0 effective change). The
27
+ * cursor advances past EVERY scanned row (including skips) so one invocation
28
+ * can't loop; a fresh invocation re-scans from the start.
29
+ * - **Only ctime/mtime change** — never cid/size/content/metadata. The FILE
30
+ * row's `mtime` (LWW arbiter) is NEVER touched; only its `ctime`. The DIR
31
+ * row gets both ctime+mtime (dir rows carry no LWW meaning, §1 fact 3).
32
+ * - **Batched / bounded** (`pageSize`, `maxPages`) to respect D1 write quota /
33
+ * avoid the O(N²) trap (cf. the D1 file_count burn-through lesson).
34
+ */
35
+ /** A FILE row with non-null metadata — a backfill candidate. */
36
+ interface CtimeBackfillCandidate {
37
+ path: string;
38
+ /** Raw `entries.metadata` JSON blob (host-parsed here, never in SQL). */
39
+ metadata: string | null;
40
+ }
41
+ /** Backend-specific SQL for the sweep (D1 vs Node SQLite). One scope each. */
42
+ interface CtimeBackfillBackend {
43
+ /**
44
+ * Select up to `limit` FILE rows with `metadata IS NOT NULL` and
45
+ * `path > cursor`, ordered `path ASC` (the keyset cursor). Empty ⇒ done.
46
+ */
47
+ selectCandidates(cursor: string, limit: number): Promise<CtimeBackfillCandidate[]>;
48
+ /**
49
+ * R1: set the FILE row's `ctime` (NEVER its mtime). The UPDATE is guarded
50
+ * `AND ctime != ?` so an already-migrated row is a 0-row no-op (re-runs burn
51
+ * no D1 write quota). Returns the number of rows actually changed (0 or 1).
52
+ */
53
+ updateFileCtime(path: string, ctime: number): Promise<number>;
54
+ /**
55
+ * R2: set the DIRECT-parent DIR row's `ctime` + `mtime`, guarded so an
56
+ * already-current dir is a no-op. Returns rows actually changed (0 or 1).
57
+ */
58
+ updateDirStamp(dirPath: string, ctime: number, mtime: number): Promise<number>;
59
+ }
60
+ interface CtimeBackfillOptions {
61
+ /** Rows per page (bounds the D1 write budget per invocation). Default 200. */
62
+ pageSize?: number;
63
+ /** Cap pages this invocation (cross-invocation paging). Default unbounded. */
64
+ maxPages?: number;
65
+ /**
66
+ * Max concurrent UPDATE round-trips WITHIN a page. Default 1 (serial — the
67
+ * deterministic reference behavior). >1 is a throughput win for the high-
68
+ * latency D1-HTTP channel (each row = 2 sequential UPDATEs otherwise).
69
+ *
70
+ * ⚠️ Concurrency > 1 makes the direct-parent DIR stamp NON-deterministic for
71
+ * a degenerate collection where MULTIPLE createdAt-bearing rows share one
72
+ * direct parent (the `ORDER BY path` last-writer-wins guarantee only holds
73
+ * serially). SAFE for dir-per-record collections (Aside: exactly one
74
+ * createdAt child — `item.json` — per `{uuid}/`, no shared parent). Use 1
75
+ * for strict determinism on degenerate shapes. Node SQLite (single
76
+ * connection) gains nothing — keep it 1 there.
77
+ */
78
+ concurrency?: number;
79
+ /**
80
+ * Preview only — scan + count candidates, run NO UPDATE. `stats.stamped`
81
+ * then reports rows that WOULD be stamped (an upper bound; the real run's
82
+ * `AND ctime != ?` guard skips already-current rows as 0-write). `scanned`
83
+ * and `skippedNoCreatedAt` are exact in both modes.
84
+ */
85
+ dryRun?: boolean;
86
+ log?: (msg: string) => void;
87
+ }
88
+ interface CtimeBackfillStats {
89
+ /** FILE rows examined (metadata IS NOT NULL). */
90
+ scanned: number;
91
+ /** Rows where a ctime/mtime value ACTUALLY changed (file and/or dir). */
92
+ stamped: number;
93
+ /**
94
+ * Rows that had a valid createdAt but were already at the target value — a
95
+ * 0-write no-op. On a clean second run this equals `scanned` and `stamped`
96
+ * is 0 (the spec's "第二趟 0 改动" idempotency contract).
97
+ */
98
+ alreadyCurrent: number;
99
+ /** Rows with metadata but no usable createdAt — left at insert time. */
100
+ skippedNoCreatedAt: number;
101
+ pages: number;
102
+ lastCursor: string;
103
+ /** True when a page came back empty (the sweep reached the end). */
104
+ done: boolean;
105
+ }
106
+ /**
107
+ * Page over createdAt-bearing FILE rows in one scope and rewrite ctime (R1) +
108
+ * the direct-parent DIR stamp (R2). Returns stats; resumable across calls.
109
+ */
110
+ declare function backfillCtime(backend: CtimeBackfillBackend, opts?: CtimeBackfillOptions): Promise<CtimeBackfillStats>;
111
+ /** Minimal D1 shape used by the sweep (subset of `D1Database`). */
112
+ interface D1Like {
113
+ prepare(sql: string): {
114
+ bind(...args: (string | number)[]): {
115
+ all(): Promise<{
116
+ results?: unknown[];
117
+ }>;
118
+ run(): Promise<{
119
+ meta?: {
120
+ changes?: number;
121
+ };
122
+ }>;
123
+ };
124
+ };
125
+ }
126
+ /** D1 (Cloudflare) backend adapter for one scope. */
127
+ declare function makeD1CtimeBackfillBackend(db: D1Like, scope: string): CtimeBackfillBackend;
128
+ /**
129
+ * Minimal libsql client shape (Node `_metadata.db`). `args` narrowed to the
130
+ * exact bound types so a real `@libsql/client` `Client` is assignable.
131
+ */
132
+ interface LibsqlLike {
133
+ execute(stmt: {
134
+ sql: string;
135
+ args: (string | number)[];
136
+ }): Promise<{
137
+ rows: Array<Record<string, unknown>>;
138
+ rowsAffected?: number;
139
+ }>;
140
+ }
141
+ /** Node SQLite (libsql) backend adapter for one scope. */
142
+ declare function makeSqliteCtimeBackfillBackend(db: LibsqlLike, scope: string): CtimeBackfillBackend;
143
+ /** Enumerate scopes that have any createdAt-bearing file row (D1). */
144
+ declare function distinctScopesWithMetadataD1(db: D1Like): Promise<string[]>;
145
+ /** Enumerate scopes that have any createdAt-bearing file row (Node SQLite). */
146
+ declare function distinctScopesWithMetadataSqlite(db: LibsqlLike): Promise<string[]>;
147
+ /**
148
+ * Config for the offline CF D1 HTTP backend: a local Node process holding a
149
+ * Cloudflare API token with D1-edit runs the SAME paged sweep SQL the worker
150
+ * would. No R2 involved — ctime backfill is pure index UPDATEs. `fetchImpl` /
151
+ * `sleep` are injectable for tests.
152
+ */
153
+ interface CtimeBackfillD1HttpConfig {
154
+ accountId: string;
155
+ databaseId: string;
156
+ apiToken: string;
157
+ scope: string;
158
+ fetchImpl?: typeof fetch;
159
+ /** Bounded retries for TRANSIENT failures (5xx / 429 / network). Default 4. */
160
+ maxRetries?: number;
161
+ sleep?: (ms: number) => Promise<void>;
162
+ }
163
+ /** CF D1 HTTP-API backend adapter for one scope (offline admin channel). */
164
+ declare function makeD1HttpCtimeBackfillBackend(cfg: CtimeBackfillD1HttpConfig): CtimeBackfillBackend;
165
+ /** List distinct createdAt-bearing scopes on a CF D1 over HTTP (bulk sweep). */
166
+ declare function distinctScopesWithMetadataD1Http(cfg: Omit<CtimeBackfillD1HttpConfig, "scope">): Promise<string[]>;
167
+ //#endregion
168
+ export { CtimeBackfillBackend, CtimeBackfillCandidate, CtimeBackfillD1HttpConfig, CtimeBackfillOptions, CtimeBackfillStats, D1Like, LibsqlLike, backfillCtime, distinctScopesWithMetadataD1, distinctScopesWithMetadataD1Http, distinctScopesWithMetadataSqlite, makeD1CtimeBackfillBackend, makeD1HttpCtimeBackfillBackend, makeSqliteCtimeBackfillBackend };
169
+ //# sourceMappingURL=ctime-backfill.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ctime-backfill.d.cts","names":[],"sources":["../src/ctime-backfill.ts"],"mappings":";;AAuCA;;;;;AAOA;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA;;;UA1BiB,sBAAA;EACf,IAAA;EA6BA;EA3BA,QAAA;AAAA;;UAIe,oBAAA;EA6CG;;AAGpB;;EA3CE,gBAAA,CAAiB,MAAA,UAAgB,KAAA,WAAgB,OAAA,CAAQ,sBAAA;EA2CxB;;;;;EArCjC,eAAA,CAAgB,IAAA,UAAc,KAAA,WAAgB,OAAA;EAmD9C;;;;EA9CA,cAAA,CAAe,OAAA,UAAiB,KAAA,UAAe,KAAA,WAAgB,OAAA;AAAA;AAAA,UAGhD,oBAAA;EAyEN;EAvET,QAAA;EAyES;EAvET,QAAA;EAuEQ;;;;;;;;;;AAiFV;;;EA1IE,WAAA;EA2IA;;;;;;EApIA,MAAA;EACA,GAAA,IAAO,GAAA;AAAA;AAAA,UAGQ,kBAAA;EAmIe;EAjI9B,OAAA;EAiIqC;EA/HrC,OAAA;EAqIwC;;;;;EA/HxC,cAAA;EA+HqE;EA7HrE,kBAAA;EACA,KAAA;EACA,UAAA;EAsJyB;EApJzB,IAAA;AAAA;;;;;iBA2BoB,aAAA,CACpB,OAAA,EAAS,oBAAA,EACT,IAAA,GAAM,oBAAA,GACL,OAAA,CAAQ,kBAAA;;UAiFM,MAAA;EACf,OAAA,CAAQ,GAAA;IACN,IAAA,IAAQ,IAAA;MACN,GAAA,IAAO,OAAA;QAAU,OAAA;MAAA;MACjB,GAAA,IAAO,OAAA;QAAU,IAAA;UAAS,OAAA;QAAA;MAAA;IAAA;EAAA;AAAA;;iBAMhB,0BAAA,CAA2B,EAAA,EAAI,MAAA,EAAQ,KAAA,WAAgB,oBAAA;;;;AAiEvE;UAtCiB,UAAA;EACf,OAAA,CAAQ,IAAA;IAAQ,GAAA;IAAa,IAAA;EAAA,IAA8B,OAAA;IACzD,IAAA,EAAM,KAAA,CAAM,MAAA;IACZ,YAAA;EAAA;AAAA;;iBAKY,8BAAA,CACd,EAAA,EAAI,UAAA,EACJ,KAAA,WACC,oBAAA;;iBA2BmB,4BAAA,CAA6B,EAAA,EAAI,MAAA,GAAS,OAAA;;iBAM1C,gCAAA,CAAiC,EAAA,EAAI,UAAA,GAAa,OAAA;;;AAYxE;;;;UAAiB,yBAAA;EACf,SAAA;EACA,UAAA;EACA,QAAA;EACA,KAAA;EACA,SAAA,UAAmB,KAAA;EAEnB;EAAA,UAAA;EACA,KAAA,IAAS,EAAA,aAAe,OAAA;AAAA;;iBAkDV,8BAAA,CACd,GAAA,EAAK,yBAAA,GACJ,oBAAA;AAFH;AAAA,iBA8BsB,gCAAA,CACpB,GAAA,EAAK,IAAA,CAAK,yBAAA,aACT,OAAA"}
@@ -0,0 +1,169 @@
1
+ //#region src/ctime-backfill.d.ts
2
+ /**
3
+ * ctime-backfill — one-time backfill of `entries.ctime` from the application
4
+ * `createdAt` for data written BEFORE the feed-sort Rule R landed
5
+ * (planning/did-integration/feed-sort-createdat §7).
6
+ *
7
+ * Pre-fix, a FILE row's ctime was its insert time and its DIRECT-parent DIR row
8
+ * was created `INSERT OR IGNORE` with `ctime = Date.now()` and never updated.
9
+ * After Phase 3 switches the feed to `orderBy ctime`, those historical rows
10
+ * would sort by insert time. This sweep rewrites them to match what a fresh
11
+ * write would now stamp (R1 = file ctime, R2 = direct-parent DIR ctime/mtime).
12
+ *
13
+ * Design (mirrors inline-content-migration / scope-migration):
14
+ * - OFFLINE, code-driven. The core loop {@link backfillCtime} is backend-
15
+ * agnostic; the SQL lives in {@link CtimeBackfillBackend} adapters (D1 vs
16
+ * Node SQLite) so it is unit-testable against a mock D1.
17
+ * - **Host-language ISO parse** (`normalizeTs`) — NEVER SQLite `strftime`,
18
+ * which is unreliable for `Z`/offset/ms ISO-8601 (§7).
19
+ * - **WHERE pins `scope`** and binds scope/path as parameters — never a string
20
+ * interpolation; one scope is migrated at a time, never a cross-scope UPDATE.
21
+ * - **Deterministic `ORDER BY path ASC` keyset cursor** ⇒ for a degenerate
22
+ * DIR with several createdAt-bearing children, the LAST in path order wins
23
+ * (same LWW as the write path's R2 — NEVER MIN/MAX). Aside has exactly one
24
+ * createdAt child (`item.json`) per `{uuid}/`, so the result is deterministic.
25
+ * - **Idempotent**: each row is rewritten to `normalizeTs(createdAt)`, a fixed
26
+ * value, so a second pass writes the same value (0 effective change). The
27
+ * cursor advances past EVERY scanned row (including skips) so one invocation
28
+ * can't loop; a fresh invocation re-scans from the start.
29
+ * - **Only ctime/mtime change** — never cid/size/content/metadata. The FILE
30
+ * row's `mtime` (LWW arbiter) is NEVER touched; only its `ctime`. The DIR
31
+ * row gets both ctime+mtime (dir rows carry no LWW meaning, §1 fact 3).
32
+ * - **Batched / bounded** (`pageSize`, `maxPages`) to respect D1 write quota /
33
+ * avoid the O(N²) trap (cf. the D1 file_count burn-through lesson).
34
+ */
35
+ /** A FILE row with non-null metadata — a backfill candidate. */
36
+ interface CtimeBackfillCandidate {
37
+ path: string;
38
+ /** Raw `entries.metadata` JSON blob (host-parsed here, never in SQL). */
39
+ metadata: string | null;
40
+ }
41
+ /** Backend-specific SQL for the sweep (D1 vs Node SQLite). One scope each. */
42
+ interface CtimeBackfillBackend {
43
+ /**
44
+ * Select up to `limit` FILE rows with `metadata IS NOT NULL` and
45
+ * `path > cursor`, ordered `path ASC` (the keyset cursor). Empty ⇒ done.
46
+ */
47
+ selectCandidates(cursor: string, limit: number): Promise<CtimeBackfillCandidate[]>;
48
+ /**
49
+ * R1: set the FILE row's `ctime` (NEVER its mtime). The UPDATE is guarded
50
+ * `AND ctime != ?` so an already-migrated row is a 0-row no-op (re-runs burn
51
+ * no D1 write quota). Returns the number of rows actually changed (0 or 1).
52
+ */
53
+ updateFileCtime(path: string, ctime: number): Promise<number>;
54
+ /**
55
+ * R2: set the DIRECT-parent DIR row's `ctime` + `mtime`, guarded so an
56
+ * already-current dir is a no-op. Returns rows actually changed (0 or 1).
57
+ */
58
+ updateDirStamp(dirPath: string, ctime: number, mtime: number): Promise<number>;
59
+ }
60
+ interface CtimeBackfillOptions {
61
+ /** Rows per page (bounds the D1 write budget per invocation). Default 200. */
62
+ pageSize?: number;
63
+ /** Cap pages this invocation (cross-invocation paging). Default unbounded. */
64
+ maxPages?: number;
65
+ /**
66
+ * Max concurrent UPDATE round-trips WITHIN a page. Default 1 (serial — the
67
+ * deterministic reference behavior). >1 is a throughput win for the high-
68
+ * latency D1-HTTP channel (each row = 2 sequential UPDATEs otherwise).
69
+ *
70
+ * ⚠️ Concurrency > 1 makes the direct-parent DIR stamp NON-deterministic for
71
+ * a degenerate collection where MULTIPLE createdAt-bearing rows share one
72
+ * direct parent (the `ORDER BY path` last-writer-wins guarantee only holds
73
+ * serially). SAFE for dir-per-record collections (Aside: exactly one
74
+ * createdAt child — `item.json` — per `{uuid}/`, no shared parent). Use 1
75
+ * for strict determinism on degenerate shapes. Node SQLite (single
76
+ * connection) gains nothing — keep it 1 there.
77
+ */
78
+ concurrency?: number;
79
+ /**
80
+ * Preview only — scan + count candidates, run NO UPDATE. `stats.stamped`
81
+ * then reports rows that WOULD be stamped (an upper bound; the real run's
82
+ * `AND ctime != ?` guard skips already-current rows as 0-write). `scanned`
83
+ * and `skippedNoCreatedAt` are exact in both modes.
84
+ */
85
+ dryRun?: boolean;
86
+ log?: (msg: string) => void;
87
+ }
88
+ interface CtimeBackfillStats {
89
+ /** FILE rows examined (metadata IS NOT NULL). */
90
+ scanned: number;
91
+ /** Rows where a ctime/mtime value ACTUALLY changed (file and/or dir). */
92
+ stamped: number;
93
+ /**
94
+ * Rows that had a valid createdAt but were already at the target value — a
95
+ * 0-write no-op. On a clean second run this equals `scanned` and `stamped`
96
+ * is 0 (the spec's "第二趟 0 改动" idempotency contract).
97
+ */
98
+ alreadyCurrent: number;
99
+ /** Rows with metadata but no usable createdAt — left at insert time. */
100
+ skippedNoCreatedAt: number;
101
+ pages: number;
102
+ lastCursor: string;
103
+ /** True when a page came back empty (the sweep reached the end). */
104
+ done: boolean;
105
+ }
106
+ /**
107
+ * Page over createdAt-bearing FILE rows in one scope and rewrite ctime (R1) +
108
+ * the direct-parent DIR stamp (R2). Returns stats; resumable across calls.
109
+ */
110
+ declare function backfillCtime(backend: CtimeBackfillBackend, opts?: CtimeBackfillOptions): Promise<CtimeBackfillStats>;
111
+ /** Minimal D1 shape used by the sweep (subset of `D1Database`). */
112
+ interface D1Like {
113
+ prepare(sql: string): {
114
+ bind(...args: (string | number)[]): {
115
+ all(): Promise<{
116
+ results?: unknown[];
117
+ }>;
118
+ run(): Promise<{
119
+ meta?: {
120
+ changes?: number;
121
+ };
122
+ }>;
123
+ };
124
+ };
125
+ }
126
+ /** D1 (Cloudflare) backend adapter for one scope. */
127
+ declare function makeD1CtimeBackfillBackend(db: D1Like, scope: string): CtimeBackfillBackend;
128
+ /**
129
+ * Minimal libsql client shape (Node `_metadata.db`). `args` narrowed to the
130
+ * exact bound types so a real `@libsql/client` `Client` is assignable.
131
+ */
132
+ interface LibsqlLike {
133
+ execute(stmt: {
134
+ sql: string;
135
+ args: (string | number)[];
136
+ }): Promise<{
137
+ rows: Array<Record<string, unknown>>;
138
+ rowsAffected?: number;
139
+ }>;
140
+ }
141
+ /** Node SQLite (libsql) backend adapter for one scope. */
142
+ declare function makeSqliteCtimeBackfillBackend(db: LibsqlLike, scope: string): CtimeBackfillBackend;
143
+ /** Enumerate scopes that have any createdAt-bearing file row (D1). */
144
+ declare function distinctScopesWithMetadataD1(db: D1Like): Promise<string[]>;
145
+ /** Enumerate scopes that have any createdAt-bearing file row (Node SQLite). */
146
+ declare function distinctScopesWithMetadataSqlite(db: LibsqlLike): Promise<string[]>;
147
+ /**
148
+ * Config for the offline CF D1 HTTP backend: a local Node process holding a
149
+ * Cloudflare API token with D1-edit runs the SAME paged sweep SQL the worker
150
+ * would. No R2 involved — ctime backfill is pure index UPDATEs. `fetchImpl` /
151
+ * `sleep` are injectable for tests.
152
+ */
153
+ interface CtimeBackfillD1HttpConfig {
154
+ accountId: string;
155
+ databaseId: string;
156
+ apiToken: string;
157
+ scope: string;
158
+ fetchImpl?: typeof fetch;
159
+ /** Bounded retries for TRANSIENT failures (5xx / 429 / network). Default 4. */
160
+ maxRetries?: number;
161
+ sleep?: (ms: number) => Promise<void>;
162
+ }
163
+ /** CF D1 HTTP-API backend adapter for one scope (offline admin channel). */
164
+ declare function makeD1HttpCtimeBackfillBackend(cfg: CtimeBackfillD1HttpConfig): CtimeBackfillBackend;
165
+ /** List distinct createdAt-bearing scopes on a CF D1 over HTTP (bulk sweep). */
166
+ declare function distinctScopesWithMetadataD1Http(cfg: Omit<CtimeBackfillD1HttpConfig, "scope">): Promise<string[]>;
167
+ //#endregion
168
+ export { CtimeBackfillBackend, CtimeBackfillCandidate, CtimeBackfillD1HttpConfig, CtimeBackfillOptions, CtimeBackfillStats, D1Like, LibsqlLike, backfillCtime, distinctScopesWithMetadataD1, distinctScopesWithMetadataD1Http, distinctScopesWithMetadataSqlite, makeD1CtimeBackfillBackend, makeD1HttpCtimeBackfillBackend, makeSqliteCtimeBackfillBackend };
169
+ //# sourceMappingURL=ctime-backfill.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ctime-backfill.d.mts","names":[],"sources":["../src/ctime-backfill.ts"],"mappings":";;AAuCA;;;;;AAOA;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA;;;UA1BiB,sBAAA;EACf,IAAA;EA6BA;EA3BA,QAAA;AAAA;;UAIe,oBAAA;EA6CG;;AAGpB;;EA3CE,gBAAA,CAAiB,MAAA,UAAgB,KAAA,WAAgB,OAAA,CAAQ,sBAAA;EA2CxB;;;;;EArCjC,eAAA,CAAgB,IAAA,UAAc,KAAA,WAAgB,OAAA;EAmD9C;;;;EA9CA,cAAA,CAAe,OAAA,UAAiB,KAAA,UAAe,KAAA,WAAgB,OAAA;AAAA;AAAA,UAGhD,oBAAA;EAyEN;EAvET,QAAA;EAyES;EAvET,QAAA;EAuEQ;;;;;;;;;;AAiFV;;;EA1IE,WAAA;EA2IA;;;;;;EApIA,MAAA;EACA,GAAA,IAAO,GAAA;AAAA;AAAA,UAGQ,kBAAA;EAmIe;EAjI9B,OAAA;EAiIqC;EA/HrC,OAAA;EAqIwC;;;;;EA/HxC,cAAA;EA+HqE;EA7HrE,kBAAA;EACA,KAAA;EACA,UAAA;EAsJyB;EApJzB,IAAA;AAAA;;;;;iBA2BoB,aAAA,CACpB,OAAA,EAAS,oBAAA,EACT,IAAA,GAAM,oBAAA,GACL,OAAA,CAAQ,kBAAA;;UAiFM,MAAA;EACf,OAAA,CAAQ,GAAA;IACN,IAAA,IAAQ,IAAA;MACN,GAAA,IAAO,OAAA;QAAU,OAAA;MAAA;MACjB,GAAA,IAAO,OAAA;QAAU,IAAA;UAAS,OAAA;QAAA;MAAA;IAAA;EAAA;AAAA;;iBAMhB,0BAAA,CAA2B,EAAA,EAAI,MAAA,EAAQ,KAAA,WAAgB,oBAAA;;;;AAiEvE;UAtCiB,UAAA;EACf,OAAA,CAAQ,IAAA;IAAQ,GAAA;IAAa,IAAA;EAAA,IAA8B,OAAA;IACzD,IAAA,EAAM,KAAA,CAAM,MAAA;IACZ,YAAA;EAAA;AAAA;;iBAKY,8BAAA,CACd,EAAA,EAAI,UAAA,EACJ,KAAA,WACC,oBAAA;;iBA2BmB,4BAAA,CAA6B,EAAA,EAAI,MAAA,GAAS,OAAA;;iBAM1C,gCAAA,CAAiC,EAAA,EAAI,UAAA,GAAa,OAAA;;;AAYxE;;;;UAAiB,yBAAA;EACf,SAAA;EACA,UAAA;EACA,QAAA;EACA,KAAA;EACA,SAAA,UAAmB,KAAA;EAEnB;EAAA,UAAA;EACA,KAAA,IAAS,EAAA,aAAe,OAAA;AAAA;;iBAkDV,8BAAA,CACd,GAAA,EAAK,yBAAA,GACJ,oBAAA;AAFH;AAAA,iBA8BsB,gCAAA,CACpB,GAAA,EAAK,IAAA,CAAK,yBAAA,aACT,OAAA"}