@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,603 @@
1
+
2
+ //#region src/changelog-schema.ts
3
+ /**
4
+ * Changelog table schema — single source of truth for the four runtimes:
5
+ * - D1 (Cloudflare Worker) : migrations/0008_changelog.sql + d1-tree-index.ts
6
+ * - desktop SQLite (libsql) : metadata-db.ts ensureChangelogTable()
7
+ * - Swift SQLite (mobile) : SQLiteTreeIndex.swift migrate()
8
+ * - Kotlin SQLite (mobile) : SQLiteTreeIndex.kt migrate()
9
+ *
10
+ * The CI parity script (`scripts/check-changelog-ddl-parity.ts`) reads the
11
+ * DDL strings out of all four locations, normalises whitespace, lower-cases
12
+ * keywords/identifiers, and asserts byte equality.
13
+ *
14
+ * **Do not edit any of those four sources without updating the others.**
15
+ *
16
+ * Phase 2 Task 2.1 introduces the schema only — `put`/`delete` start writing
17
+ * changelog rows in Task 2.4. Until then the table sits empty.
18
+ */
19
+ /** CREATE TABLE statement. Idempotent (`IF NOT EXISTS`). */
20
+ const CHANGELOG_TABLE_SQL = `CREATE TABLE IF NOT EXISTS ds_changelog (
21
+ seq INTEGER PRIMARY KEY AUTOINCREMENT,
22
+ scope TEXT NOT NULL,
23
+ path TEXT NOT NULL,
24
+ op TEXT NOT NULL,
25
+ cid TEXT,
26
+ old_cid TEXT,
27
+ size INTEGER,
28
+ mtime INTEGER NOT NULL,
29
+ device_id TEXT NOT NULL,
30
+ CHECK (op IN ('put', 'delete'))
31
+ )`;
32
+ /**
33
+ * CREATE INDEX statements. Order matches migration file.
34
+ *
35
+ * The cid / old_cid indexes are **scope-composite** (`(scope, cid)` /
36
+ * `(scope, old_cid)`), NOT bare `(cid)` / `(old_cid)`: the only readers are
37
+ * `isReferenced` / `isReferencedMany`, which ALWAYS filter `scope = ?` (read-
38
+ * auth, design §7.2). A bare-cid index forces the `cid IN (…)` seek to fan out
39
+ * across every scope + the whole append-only history (Model B global object
40
+ * pool) and residual-filter scope afterwards — the 7180× rows_read blow-up on
41
+ * staging D1. Leading `scope` collapses the seek to one user's rows. No live
42
+ * SCOPE-BLIND reader exists (GC liveness uses entries-only `referencedAnywhere`;
43
+ * the scope-blind three-way `D1GCQueue.isReferenced` is retired), so these
44
+ * replace the old globals rather than adding to them — index count unchanged,
45
+ * no extra write-amplification on the hot append-only changelog.
46
+ */
47
+ const CHANGELOG_INDEX_SQL = [
48
+ "CREATE INDEX IF NOT EXISTS idx_changelog_scope_seq ON ds_changelog(scope, seq)",
49
+ "CREATE INDEX IF NOT EXISTS idx_changelog_scope_cid ON ds_changelog(scope, cid) WHERE cid IS NOT NULL",
50
+ "CREATE INDEX IF NOT EXISTS idx_changelog_scope_old_cid ON ds_changelog(scope, old_cid) WHERE old_cid IS NOT NULL"
51
+ ];
52
+ /**
53
+ * Migration 0110 — swap the legacy bare-cid changelog indexes for the
54
+ * scope-composite ones above. An explicit `DROP` is required: `CREATE INDEX
55
+ * IF NOT EXISTS idx_changelog_scope_cid …` lands the new index on fresh DBs,
56
+ * but an already-deployed DB carries the OLD `idx_changelog_cid` / `_old_cid`
57
+ * names — those must be dropped or they linger as orphan indexes, still
58
+ * maintained on every changelog insert. Fresh DBs apply the regenerated 0100
59
+ * (new names) THEN this (DROP no-ops on the absent old names, CREATE no-ops on
60
+ * the already-present new ones) → idempotent both ways. Sourced here so the
61
+ * migration and `ensureTable` share one definition. D1 + Node libsql only
62
+ * (mobile single-device runtimes have no scope selectivity to gain).
63
+ */
64
+ const CHANGELOG_SCOPE_CID_MIGRATION_SQL = [
65
+ "DROP INDEX IF EXISTS idx_changelog_cid",
66
+ "DROP INDEX IF EXISTS idx_changelog_old_cid",
67
+ "CREATE INDEX IF NOT EXISTS idx_changelog_scope_cid ON ds_changelog(scope, cid) WHERE cid IS NOT NULL",
68
+ "CREATE INDEX IF NOT EXISTS idx_changelog_scope_old_cid ON ds_changelog(scope, old_cid) WHERE old_cid IS NOT NULL"
69
+ ];
70
+ /**
71
+ * Combined DDL block (table + indices), separated by `;\n`.
72
+ *
73
+ * This is the canonical form against which Swift/Kotlin literals and the
74
+ * migration SQL file are compared. The parity script normalises whitespace
75
+ * and case before byte-comparing, so reformatting any one location is fine
76
+ * as long as the SQL semantics stay identical.
77
+ */
78
+ const CHANGELOG_DDL = [CHANGELOG_TABLE_SQL, ...CHANGELOG_INDEX_SQL].join(";\n");
79
+ /**
80
+ * Phase 2 Task 2.2 — `device_sync_state` table (D1 only).
81
+ *
82
+ * Worker-side per-device sync progress tracker. Unlike `changelog`, this
83
+ * table lives ONLY in Cloudflare D1; mobile runtimes do not mirror it.
84
+ * Each row records the highest changelog.seq a device has acknowledged
85
+ * plus heartbeat timestamps.
86
+ *
87
+ * Columns:
88
+ * - scope : DID Space scope (matches changelog.scope semantics)
89
+ * - device_id : opaque device identifier from request header
90
+ * - last_seq : highest changelog.seq this device has consumed
91
+ * - last_sync_at : unix millis of last successful advancement of last_seq
92
+ * - last_seen_at : unix millis of most recent heartbeat / HTTP touch
93
+ *
94
+ * Composite PRIMARY KEY `(scope, device_id)` means the table is a regular
95
+ * rowid table (no WITHOUT ROWID) so row updates stay cheap.
96
+ *
97
+ * NOT parity-checked by `scripts/check-changelog-ddl-parity.ts` — this DDL
98
+ * is D1-only. Kept here beside `CHANGELOG_*` so the full D1 schema sits in
99
+ * one file for future readers.
100
+ */
101
+ const DEVICE_SYNC_STATE_TABLE_SQL = `CREATE TABLE IF NOT EXISTS ds_device_sync_state (
102
+ scope TEXT NOT NULL,
103
+ device_id TEXT NOT NULL,
104
+ last_seq INTEGER NOT NULL DEFAULT 0,
105
+ last_sync_at INTEGER NOT NULL,
106
+ last_seen_at INTEGER NOT NULL,
107
+ PRIMARY KEY (scope, device_id)
108
+ )`;
109
+ /** CREATE INDEX statements for `device_sync_state`. Order matches migration. */
110
+ const DEVICE_SYNC_STATE_INDEX_SQL = ["CREATE INDEX IF NOT EXISTS idx_device_sync_state_scope_last_seen ON ds_device_sync_state(scope, last_seen_at)"];
111
+ /**
112
+ * Phase 2 Task 2.3 — `scope_meta` table (D1 only).
113
+ *
114
+ * Per-scope compaction metadata for the Cloudflare Worker. One row per
115
+ * DID Space scope. Written by G16 emergency compaction; read by the
116
+ * G5.a sync endpoint to decide whether to 409 incoming pulls whose
117
+ * `since` sits below the compaction watermark.
118
+ *
119
+ * Columns:
120
+ * - scope : DID Space scope (matches changelog.scope)
121
+ * - compacted_below_seq : highest seq that has been compacted away;
122
+ * incoming syncs with since < this value
123
+ * must receive a 409 requireFullResync.
124
+ * Monotonically non-decreasing.
125
+ * - last_compaction_at : unix millis of most recent compaction pass
126
+ * - total_changelog_writes : running counter of changelog rows ever
127
+ * written to this scope (deletes do NOT
128
+ * decrement); used by G16 to decide when to
129
+ * trigger emergency compaction
130
+ * - file_count : live count of `kind='file'` rows in `entries`
131
+ * for this scope. Maintained by the two
132
+ * `trg_entries_file_count_*` triggers below so
133
+ * the per-write capacity guard reads ONE row
134
+ * instead of a full-scope `COUNT(*)` scan (the
135
+ * O(N²) rows_read blow-up that exhausted the D1
136
+ * free tier during bulk sync). UNLIKE
137
+ * total_changelog_writes, deletes DO decrement it
138
+ * (floored at 0).
139
+ *
140
+ * Scopes are lazy-initialised: the row is NOT created on first changelog
141
+ * write. It's only materialised when compaction first runs for the
142
+ * scope. The `getCompactedBelowSeq` helper returns 0 for missing rows —
143
+ * the correct "nothing compacted yet" sentinel.
144
+ *
145
+ * PRIMARY KEY on `scope` makes this a regular rowid table; no secondary
146
+ * indices are needed since all lookups are by PK.
147
+ *
148
+ * NOT parity-checked by `scripts/check-changelog-ddl-parity.ts` — this
149
+ * DDL is D1-only (mobile runtimes do not mirror it). Kept here beside
150
+ * `CHANGELOG_*` and `DEVICE_SYNC_STATE_*` so the full D1 schema sits in
151
+ * one file for future readers.
152
+ */
153
+ const SCOPE_META_TABLE_SQL = `CREATE TABLE IF NOT EXISTS ds_scope_meta (
154
+ scope TEXT PRIMARY KEY,
155
+ compacted_below_seq INTEGER NOT NULL DEFAULT 0,
156
+ last_compaction_at INTEGER NOT NULL DEFAULT 0,
157
+ total_changelog_writes INTEGER NOT NULL DEFAULT 0,
158
+ file_count INTEGER NOT NULL DEFAULT 0
159
+ )`;
160
+ /**
161
+ * Additive ALTER for the `total_bytes` running-total (upload-limits Phase 5,
162
+ * byte-quota D3). total_bytes is added ONLY via this ALTER — NOT in the CREATE
163
+ * TABLE above — so the single migration that introduces it works on BOTH a
164
+ * fresh DB and an already-deployed scope_meta (an `ADD COLUMN` in the CREATE
165
+ * would collide with the migration's ALTER on a fresh DB; the runner is not
166
+ * idempotent on "duplicate column"). The runtime probe-then-ALTER in
167
+ * D1TreeIndex.ensureTable applies it to fresh test/dev DBs; production deploys
168
+ * apply the generated migration. Defaulted + NOT NULL → safe additive ALTER.
169
+ */
170
+ const SCOPE_META_TOTAL_BYTES_COLUMN_SQL = "ALTER TABLE ds_scope_meta ADD COLUMN total_bytes INTEGER NOT NULL DEFAULT 0";
171
+ /**
172
+ * Trigger that keeps `scope_meta.file_count` incrementing in lock-step with
173
+ * new `kind='file'` rows in `entries`. It exists so the capacity guard in
174
+ * `D1TreeIndex.put()` can read a single `scope_meta` row instead of issuing a
175
+ * full-scope `SELECT COUNT(*) FROM entries` on every new-file write — that
176
+ * scan read the WHOLE scope each time, turning a bulk sync of N files into
177
+ * ~N²/2 D1 `rows_read` and blowing past the free-tier 5M/day ceiling.
178
+ *
179
+ * INCREMENT via trigger; DECREMENT in app code — asymmetric on purpose.
180
+ * Cloudflare's D1 counts a statement's TRIGGER side-effects in `meta.changes`
181
+ * (verified on workerd: deleting 2 files + 1 dir with an AFTER-DELETE trigger
182
+ * reports 5, not 3). `deleteByPrefix` RETURNS `meta.changes`, so an
183
+ * AFTER-DELETE trigger would silently inflate that documented count. Inserts
184
+ * are safe — neither `put` nor `putBatch` reads `meta.changes` — so the
185
+ * increment stays a trigger (covering both paths for free), while
186
+ * `delete`/`deleteByPrefix` decrement `file_count` with their own batch
187
+ * statement, computed atomically from the pre-delete entries state. See
188
+ * `D1TreeIndex.delete` / `deleteByPrefix`.
189
+ *
190
+ * Trigger semantics:
191
+ * - INSERT of a `kind='file'` row → +1 (upsert creates the scope_meta row
192
+ * lazily on first file). Dir rows (`kind='dir'`) and `INSERT OR IGNORE`
193
+ * no-ops never fire. An overwrite (`ON CONFLICT DO UPDATE` on entries) is
194
+ * an UPDATE, not an INSERT, so it correctly leaves the count alone.
195
+ *
196
+ * D1-only (mobile runtimes don't mirror scope_meta). NOT parity-checked.
197
+ *
198
+ * NOTE: the body contains an inner `;` (required by SQLite trigger grammar).
199
+ * Any SQL splitter that feeds this to D1 one statement at a time MUST keep
200
+ * the `CREATE TRIGGER … BEGIN … END` block whole — see
201
+ * `runtimes/cloudflare/scripts/apply-d1-migrations.mjs` `splitSqlStatements`.
202
+ */
203
+ const SCOPE_META_FILE_COUNT_TRIGGER_SQL = [`CREATE TRIGGER IF NOT EXISTS trg_entries_file_count_insert
204
+ AFTER INSERT ON ds_entries WHEN NEW.kind = 'file'
205
+ BEGIN
206
+ INSERT INTO ds_scope_meta (scope, file_count) VALUES (NEW.scope, 1)
207
+ ON CONFLICT(scope) DO UPDATE SET file_count = file_count + 1;
208
+ END`];
209
+ /**
210
+ * Triggers that keep `scope_meta.total_bytes` (upload-limits Phase 5 byte-quota
211
+ * D3) in lock-step with the `size` of `kind='file'` rows — mirroring the
212
+ * file_count trigger so the byte quota reads ONE scope_meta row instead of a
213
+ * `SELECT SUM(size)` full-scope scan (the rejected O(N) rows_read anti-pattern
214
+ * that caused the 503, did-space-d1-filecount-fix).
215
+ *
216
+ * - INSERT of a new file → `+= NEW.size` (lazy upsert of the scope_meta row).
217
+ * - UPDATE (overwrite, same path, new content/size) → `+= NEW.size - OLD.size`.
218
+ * Safe as a trigger because put/putBatch do NOT read `meta.changes` — only
219
+ * `deleteByPrefix` does, so DELETE decrements in app code (below), exactly
220
+ * like file_count. Floored at 0 against drift.
221
+ *
222
+ * D1-only (mobile runtimes don't mirror scope_meta). NOT parity-checked. Each
223
+ * `CREATE TRIGGER … BEGIN … END` block has an inner `;` — keep it whole when
224
+ * splitting SQL (see apply-d1-migrations.mjs splitSqlStatements).
225
+ */
226
+ const SCOPE_META_TOTAL_BYTES_TRIGGER_SQL = [`CREATE TRIGGER IF NOT EXISTS trg_entries_total_bytes_insert
227
+ AFTER INSERT ON ds_entries WHEN NEW.kind = 'file'
228
+ BEGIN
229
+ INSERT INTO ds_scope_meta (scope, total_bytes) VALUES (NEW.scope, NEW.size)
230
+ ON CONFLICT(scope) DO UPDATE SET total_bytes = total_bytes + NEW.size;
231
+ END`, `CREATE TRIGGER IF NOT EXISTS trg_entries_total_bytes_update
232
+ AFTER UPDATE ON ds_entries WHEN NEW.kind = 'file' AND OLD.kind = 'file'
233
+ BEGIN
234
+ UPDATE ds_scope_meta SET total_bytes = MAX(0, total_bytes + NEW.size - OLD.size)
235
+ WHERE scope = NEW.scope;
236
+ END`];
237
+ /**
238
+ * Decrement `total_bytes` for `delete()`: subtract the file's size iff `path`
239
+ * is currently a file. Placed BEFORE the `DELETE FROM entries` so the subquery
240
+ * observes the pre-delete row. Floored at 0. Bind order: `(scope, path, scope)`
241
+ * — the subquery's `(scope, path)` first, then the outer `WHERE scope`.
242
+ */
243
+ const SCOPE_META_TOTAL_BYTES_DELETE_ONE_SQL = `UPDATE ds_scope_meta
244
+ SET total_bytes = MAX(0, total_bytes - COALESCE(
245
+ (SELECT size FROM ds_entries WHERE scope = ? AND path = ? AND kind = 'file'), 0
246
+ ))
247
+ WHERE scope = ?`;
248
+ /**
249
+ * Decrement `total_bytes` for `deleteByPrefix()`: subtract Σ size of the file
250
+ * rows in the range. Placed BEFORE the range `DELETE` so the SUM observes the
251
+ * pre-delete rows; scans only the deleted range. Floored at 0. Bind order:
252
+ * `(scope, lo, hi, scope)`.
253
+ */
254
+ const SCOPE_META_TOTAL_BYTES_DELETE_RANGE_SQL = `UPDATE ds_scope_meta
255
+ SET total_bytes = MAX(0, total_bytes - (
256
+ SELECT COALESCE(SUM(size), 0) FROM ds_entries INDEXED BY idx_entries_kind
257
+ WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file'
258
+ ))
259
+ WHERE scope = ?`;
260
+ /**
261
+ * One-time backfill: seed `total_bytes` from the current file rows for every
262
+ * scope. Absolute (`SET = excluded.total_bytes`) so it self-corrects against a
263
+ * concurrent write between trigger creation and this statement. Migration-only.
264
+ */
265
+ const SCOPE_META_TOTAL_BYTES_BACKFILL_SQL = `INSERT INTO ds_scope_meta (scope, total_bytes)
266
+ SELECT scope, COALESCE(SUM(size), 0) FROM ds_entries WHERE kind = 'file' GROUP BY scope
267
+ ON CONFLICT(scope) DO UPDATE SET total_bytes = excluded.total_bytes`;
268
+ /**
269
+ * Decrement statement for `delete()`: −1 iff `path` is currently a file.
270
+ * Placed in the delete batch BEFORE the `DELETE FROM entries` so the EXISTS
271
+ * subquery observes the pre-delete row. Floored at 0. Bind order:
272
+ * `(scope, scope, path)`.
273
+ */
274
+ const SCOPE_META_FILE_COUNT_DELETE_ONE_SQL = `UPDATE ds_scope_meta
275
+ SET file_count = MAX(0, file_count - 1)
276
+ WHERE scope = ? AND EXISTS (
277
+ SELECT 1 FROM ds_entries WHERE scope = ? AND path = ? AND kind = 'file'
278
+ )`;
279
+ /**
280
+ * Decrement statement for `deleteByPrefix()`: subtract the number of file rows
281
+ * in the prefix range. Placed in the batch BEFORE the range `DELETE` so the
282
+ * COUNT observes the pre-delete rows; the COUNT scans only the range being
283
+ * deleted (never the whole scope). Floored at 0. Bind order:
284
+ * `(scope, scope, lo, hi)`.
285
+ */
286
+ const SCOPE_META_FILE_COUNT_DELETE_RANGE_SQL = `UPDATE ds_scope_meta
287
+ SET file_count = MAX(0, file_count - (
288
+ SELECT COUNT(*) FROM ds_entries
289
+ WHERE scope = ? AND path >= ? AND path < ? AND kind = 'file'
290
+ ))
291
+ WHERE scope = ?`;
292
+ /**
293
+ * One-time backfill: seed `file_count` from the current `entries` rows for
294
+ * every scope that already has files. Absolute (`SET = excluded.file_count`,
295
+ * not `+=`) so it is self-correcting if a concurrent write fires a trigger
296
+ * between trigger creation and this statement. Migration-only — fresh DBs
297
+ * (tests / first deploy) start empty and need no backfill.
298
+ */
299
+ const SCOPE_META_FILE_COUNT_BACKFILL_SQL = `INSERT INTO ds_scope_meta (scope, file_count)
300
+ SELECT scope, COUNT(*) FROM ds_entries WHERE kind = 'file' GROUP BY scope
301
+ ON CONFLICT(scope) DO UPDATE SET file_count = excluded.file_count`;
302
+ /**
303
+ * CREATE INDEX statements for `scope_meta`. Empty by design — lookups are
304
+ * always by the PRIMARY KEY, so the autogenerated PK index is sufficient.
305
+ * Exported as an empty array for symmetry with `CHANGELOG_INDEX_SQL` and
306
+ * `DEVICE_SYNC_STATE_INDEX_SQL` so callers can loop uniformly.
307
+ */
308
+ const SCOPE_META_INDEX_SQL = [];
309
+ /**
310
+ * Live Update Resilience Phase 0 (DEC-7 / design §11.4) — `prefix_watermark`.
311
+ *
312
+ * Per-`(scope, prefix)` monotonic write counter. `prefix` is the FIRST path
313
+ * segment of a write path (the `/user` first-level collection root, e.g.
314
+ * `items`, `tags`). Every file write/delete INSIDE a collection (`depth >= 2`)
315
+ * bumps the matching row's `version` by 1, in the SAME D1 batch as the
316
+ * changelog INSERT (typical +1 row write-amplification).
317
+ *
318
+ * Web live-update reconcile reads ONE row (`SELECT version WHERE scope=? AND
319
+ * prefix=?`) to decide "did my list change?" — true O(1), independent of
320
+ * changelog history size or global write activity (the append-only changelog
321
+ * `drain` would be `O(global increment)` rows_read and hit the D1 cliff; see
322
+ * design §11.1-11.3 for the rejected alternatives B/D).
323
+ *
324
+ * `version` is prefix-LOCAL: it only counts writes to THIS collection root, so
325
+ * exposing it as the wire `liveSeq` never leaks another blocklet's timing
326
+ * (invariant I3). It is a plain monotonic counter, so `+1` gap detection works
327
+ * within a prefix (Phase 3 push self-check).
328
+ *
329
+ * NOT parity-checked by `scripts/check-changelog-ddl-parity.ts` — this table is
330
+ * D1-only (Cloudflare) + Node sqlite. Mobile (Swift/Kotlin) does NOT mirror it:
331
+ * mobile sync drains the changelog and never reads the watermark. Same handling
332
+ * as `scope_meta` / `device_sync_state` above.
333
+ */
334
+ const PREFIX_WATERMARK_TABLE_SQL = `CREATE TABLE IF NOT EXISTS ds_prefix_watermark (
335
+ scope TEXT NOT NULL,
336
+ prefix TEXT NOT NULL,
337
+ version INTEGER NOT NULL DEFAULT 0,
338
+ PRIMARY KEY (scope, prefix)
339
+ )`;
340
+ /**
341
+ * Upsert that bumps a prefix's watermark by 1 (lazily creating the row at
342
+ * version 1). Bind order: `(scope, prefix)`. Placed in the SAME batch as the
343
+ * changelog INSERT so a write and its watermark bump commit atomically.
344
+ */
345
+ const PREFIX_WATERMARK_BUMP_SQL = `INSERT INTO ds_prefix_watermark (scope, prefix, version)
346
+ VALUES (?, ?, 1)
347
+ ON CONFLICT(scope, prefix) DO UPDATE SET version = version + 1`;
348
+ /**
349
+ * Read the current watermark `version` for a `(scope, prefix)`. Bind order:
350
+ * `(scope, prefix)`. Missing row ⇒ no result ⇒ caller treats as version 0
351
+ * ("nothing written under this collection root yet").
352
+ */
353
+ const PREFIX_WATERMARK_READ_SQL = `SELECT version FROM ds_prefix_watermark
354
+ WHERE scope = ? AND prefix = ?`;
355
+ /**
356
+ * Instance-space layout marker. Both `CloudflareDIDSpace.getInstanceSpace`
357
+ * and the local backend mount blocklet fragments behind a `PrefixedTreeIndex`
358
+ * whose prefix is `blocklets/{instanceDid}/{role}/` — so the scope-relative
359
+ * paths this module sees for ALL instance-space traffic share the first
360
+ * segment `blocklets`. A first-segment watermark key would therefore collapse
361
+ * every collection of every blocklet (and every role) into ONE row per scope:
362
+ * a cross-blocklet timing leak (invariant I3) plus a false-trigger refetch of
363
+ * every open list on any write anywhere in the space (observed on staging CF
364
+ * 2026-06-10: `/user/items`, `/user/tags` and `/user/collections` all reported
365
+ * the same liveSeq). Under this layout the collection root is segment 4
366
+ * (`blocklets/{i}/{role}/items`), not segment 1.
367
+ */
368
+ const INSTANCE_LAYOUT_MARKER = "blocklets";
369
+ /** Segments forming the fragment root: `blocklets/{instanceDid}/{role}`. */
370
+ const INSTANCE_LAYOUT_ROOT_SEGMENTS = 3;
371
+ /**
372
+ * Extract the watermark prefix (the collection root) from a scope-relative
373
+ * tree path.
374
+ *
375
+ * Applied SYMMETRICALLY on the write side (which collection root does this
376
+ * write bump?) and the read side (which row does this list read?), so the two
377
+ * always agree regardless of how deeply the path nests — `items/X/y.json`,
378
+ * `items/X`, and `items` all map to `items`. Paths under the instance-space
379
+ * layout (`blocklets/{i}/{role}/...`) resolve to the per-fragment collection
380
+ * root `blocklets/{i}/{role}/<root>` — both sides of a `PrefixedTreeIndex`
381
+ * mount see the same prefixed path, so symmetry holds there too, now at the
382
+ * REAL collection-root granularity (prefix-local, I3).
383
+ *
384
+ * Returns `null` when the path has no collection root (`""`, `"foo.json"`,
385
+ * or a bare fragment root like `blocklets/i/user`) — such lists expose no
386
+ * `liveSeq` (consumer falls back to full re-list).
387
+ */
388
+ function watermarkPrefix(treePath) {
389
+ const segments = treePath.split("/").filter(Boolean);
390
+ if (segments[0] === INSTANCE_LAYOUT_MARKER) return segments.length >= INSTANCE_LAYOUT_ROOT_SEGMENTS + 1 ? segments.slice(0, INSTANCE_LAYOUT_ROOT_SEGMENTS + 1).join("/") : null;
391
+ return segments[0] ?? null;
392
+ }
393
+ /**
394
+ * Write-side gate: a write bumps a watermark only when it lands INSIDE a
395
+ * collection root. Generically that means `depth >= 2` (a root-level file
396
+ * `foo.json` is not a collection); under the instance-space layout the same
397
+ * rule applies relative to the fragment root — `blocklets/i/user/foo.json`
398
+ * (a file directly at the role root) is not inside a collection either.
399
+ * Returns the prefix to bump, or `null` to skip.
400
+ */
401
+ function watermarkWritePrefix(treePath) {
402
+ const segments = treePath.split("/").filter(Boolean);
403
+ if (segments[0] === INSTANCE_LAYOUT_MARKER) return segments.length >= INSTANCE_LAYOUT_ROOT_SEGMENTS + 2 ? segments.slice(0, INSTANCE_LAYOUT_ROOT_SEGMENTS + 1).join("/") : null;
404
+ if (segments.length < 2) return null;
405
+ return segments[0] ?? null;
406
+ }
407
+ /**
408
+ * Phase 3 Task 3.4 — `sync_state` local key-value table.
409
+ *
410
+ * Per-scope progress tracker for the local SyncEngine. Lives in the SAME
411
+ * SQLite DB as `changelog` on desktop (via MetadataDB) and mobile (via
412
+ * SQLiteTreeIndex). Byte-identical DDL across runtimes so the three-way
413
+ * parity script can treat it the same way as `changelog`.
414
+ *
415
+ * Schema (Task 3.4 minimum):
416
+ * key : `{scope}:local_seq` — max seq this device has pushed to cloud
417
+ * key : `{scope}:cloud_seq` — max seq pulled/applied from other devices
418
+ *
419
+ * Task 3.5 extends usage with more keys (device_id, last_sync_at, sync_status)
420
+ * backed by Keychain/Keystore on mobile. The table shape is unchanged — only
421
+ * the set of keys written to it grows.
422
+ *
423
+ * Values are always TEXT (SQLite's universal type). Integer keys like
424
+ * `local_seq` are stored as decimal strings and parsed at read time. This
425
+ * keeps the schema a single source of truth regardless of how many key types
426
+ * Task 3.5 adds later.
427
+ *
428
+ * Scope-prefixed keys let multiple DID Space scopes share the same SQLite DB
429
+ * without colliding — matching the existing scope isolation in the changelog
430
+ * table.
431
+ */
432
+ const SYNC_STATE_TABLE_SQL = `CREATE TABLE IF NOT EXISTS ds_sync_state (
433
+ key TEXT PRIMARY KEY,
434
+ value TEXT NOT NULL
435
+ )`;
436
+ /** CREATE INDEX statements for `sync_state`. Empty by design — lookups are by PK. */
437
+ const SYNC_STATE_INDEX_SQL = [];
438
+ /**
439
+ * Combined DDL for the sync_state table + indices. Exported for the same
440
+ * three-way parity reasons as `CHANGELOG_DDL` — Swift and Kotlin each embed
441
+ * a byte-identical literal that must match this string after normalisation.
442
+ */
443
+ const SYNC_STATE_DDL = [SYNC_STATE_TABLE_SQL, ...SYNC_STATE_INDEX_SQL].join(";\n");
444
+ /**
445
+ * Whitespace+case normaliser used by the parity script and tests.
446
+ *
447
+ * Strategy:
448
+ * 1. Strip SQL line comments (`-- ...` to end of line).
449
+ * 2. Strip C-style block comments (`/* ... *​/`) — defensive, none currently.
450
+ * 3. Lower-case everything (SQLite keywords + identifiers are case-insensitive).
451
+ * 4. Strip ALL `;` characters — different sources may add/omit a trailing
452
+ * semicolon on the last statement; semantically equivalent so we drop them.
453
+ * 5. Collapse any whitespace run (spaces, tabs, newlines) into a single space.
454
+ * 6. Trim leading/trailing whitespace.
455
+ * 7. Remove spaces immediately around `(`, `)`, `,` so that
456
+ * `changelog(scope, seq)` and `changelog ( scope , seq )` compare equal.
457
+ *
458
+ * Note: this is intentionally conservative — string literals like `'put'` and
459
+ * `'delete'` already happen to be lower-case, and SQLite treats string values
460
+ * as case-sensitive. If a future column ever needed mixed-case literals, we
461
+ * would have to mask string-literal regions before lower-casing.
462
+ */
463
+ function normalizeDdl(input) {
464
+ return input.replace(/--[^\n]*/g, " ").replace(/\/\*[\s\S]*?\*\//g, " ").toLowerCase().replace(/;/g, " ").replace(/\s+/g, " ").trim().replace(/\s*([(),])\s*/g, "$1");
465
+ }
466
+ /** `kind` discriminator for a changelog row entry on the sync wire. */
467
+ const CHANGELOG_ROW_KIND = "did-space:changelog-row";
468
+ /** `kind` discriminator for a manifest file entry on the sync wire. */
469
+ const MANIFEST_FILE_KIND = "did-space:file";
470
+ /**
471
+ * Field list for a changelog row's `meta.extra` (canonical sync wire).
472
+ * Order is documentary only — consumers read by key, never by position.
473
+ */
474
+ const CHANGELOG_WIRE_EXTRA_FIELDS = [
475
+ "seq",
476
+ "op",
477
+ "originalPath",
478
+ "cid",
479
+ "oldCid",
480
+ "size",
481
+ "mtime",
482
+ "deviceId"
483
+ ];
484
+ /** Field list for a manifest entry's `meta.extra` (canonical sync wire). */
485
+ const MANIFEST_WIRE_EXTRA_FIELDS = ["cid", "mtime"];
486
+ /**
487
+ * Serialize a changelog row to its canonical `meta.extra` payload. The provider
488
+ * wraps this as `meta: { kind: CHANGELOG_ROW_KIND, extra: serializeChangelogEntry(row) }`.
489
+ */
490
+ function serializeChangelogEntry(row) {
491
+ return {
492
+ seq: row.seq,
493
+ op: row.op,
494
+ originalPath: row.path,
495
+ cid: row.cid ?? null,
496
+ oldCid: row.old_cid ?? null,
497
+ size: row.size ?? null,
498
+ mtime: row.mtime,
499
+ deviceId: row.device_id
500
+ };
501
+ }
502
+ /**
503
+ * Serialize a manifest file entry to its canonical `meta`. `cid` is emitted at
504
+ * BOTH top-level and `extra.cid` (additive — see module header).
505
+ */
506
+ function serializeManifestEntry(row) {
507
+ const meta = {
508
+ kind: MANIFEST_FILE_KIND,
509
+ cid: row.cid,
510
+ size: row.size,
511
+ extra: {
512
+ cid: row.cid,
513
+ mtime: row.mtime
514
+ }
515
+ };
516
+ if (row.mimeType !== void 0) meta.mimeType = row.mimeType;
517
+ return meta;
518
+ }
519
+ /** Coerce an unknown into a finite number, or `fallback` when not coercible. */
520
+ function asNumber(value, fallback) {
521
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
522
+ }
523
+ /** Coerce an unknown into a non-empty string, or `null`. */
524
+ function asStringOrNull(value) {
525
+ return typeof value === "string" && value.length > 0 ? value : null;
526
+ }
527
+ /**
528
+ * Parse an untrusted changelog `meta.extra` bag into a typed {@link ChangelogWireExtra}.
529
+ * Returns `null` when required fields (`op`, `originalPath`) are missing/invalid —
530
+ * a malformed row is skipped, never crashes the parser. Numeric/optional fields
531
+ * degrade to safe defaults (`seq=0`, `cid=null`, …).
532
+ */
533
+ function parseChangelogEntry(extra) {
534
+ if (!extra || typeof extra !== "object") return null;
535
+ const e = extra;
536
+ const op = e.op;
537
+ if (op !== "put" && op !== "delete") return null;
538
+ const originalPath = typeof e.originalPath === "string" ? e.originalPath : null;
539
+ if (originalPath === null) return null;
540
+ const deviceId = typeof e.deviceId === "string" ? e.deviceId : "";
541
+ return {
542
+ seq: asNumber(e.seq, 0),
543
+ op,
544
+ originalPath,
545
+ cid: asStringOrNull(e.cid),
546
+ oldCid: asStringOrNull(e.oldCid),
547
+ size: typeof e.size === "number" && Number.isFinite(e.size) ? e.size : null,
548
+ mtime: asNumber(e.mtime, 0),
549
+ deviceId
550
+ };
551
+ }
552
+ /**
553
+ * Parse an untrusted manifest entry `meta` into its canonical `{ cid, mtime }`.
554
+ * Reads `extra.cid` FIRST (canonical, all-runtime), falling back to top-level
555
+ * `meta.cid` (additive). Returns `null` when no cid is resolvable.
556
+ */
557
+ function parseManifestEntry(meta) {
558
+ if (!meta || typeof meta !== "object") return null;
559
+ const m = meta;
560
+ const extra = m.extra ?? {};
561
+ const cid = typeof extra.cid === "string" && extra.cid.length > 0 ? extra.cid : typeof m.cid === "string" && m.cid.length > 0 ? m.cid : null;
562
+ if (cid === null) return null;
563
+ return {
564
+ cid,
565
+ mtime: asNumber(extra.mtime, 0)
566
+ };
567
+ }
568
+
569
+ //#endregion
570
+ exports.CHANGELOG_DDL = CHANGELOG_DDL;
571
+ exports.CHANGELOG_INDEX_SQL = CHANGELOG_INDEX_SQL;
572
+ exports.CHANGELOG_ROW_KIND = CHANGELOG_ROW_KIND;
573
+ exports.CHANGELOG_SCOPE_CID_MIGRATION_SQL = CHANGELOG_SCOPE_CID_MIGRATION_SQL;
574
+ exports.CHANGELOG_TABLE_SQL = CHANGELOG_TABLE_SQL;
575
+ exports.CHANGELOG_WIRE_EXTRA_FIELDS = CHANGELOG_WIRE_EXTRA_FIELDS;
576
+ exports.DEVICE_SYNC_STATE_INDEX_SQL = DEVICE_SYNC_STATE_INDEX_SQL;
577
+ exports.DEVICE_SYNC_STATE_TABLE_SQL = DEVICE_SYNC_STATE_TABLE_SQL;
578
+ exports.MANIFEST_FILE_KIND = MANIFEST_FILE_KIND;
579
+ exports.MANIFEST_WIRE_EXTRA_FIELDS = MANIFEST_WIRE_EXTRA_FIELDS;
580
+ exports.PREFIX_WATERMARK_BUMP_SQL = PREFIX_WATERMARK_BUMP_SQL;
581
+ exports.PREFIX_WATERMARK_READ_SQL = PREFIX_WATERMARK_READ_SQL;
582
+ exports.PREFIX_WATERMARK_TABLE_SQL = PREFIX_WATERMARK_TABLE_SQL;
583
+ exports.SCOPE_META_FILE_COUNT_BACKFILL_SQL = SCOPE_META_FILE_COUNT_BACKFILL_SQL;
584
+ exports.SCOPE_META_FILE_COUNT_DELETE_ONE_SQL = SCOPE_META_FILE_COUNT_DELETE_ONE_SQL;
585
+ exports.SCOPE_META_FILE_COUNT_DELETE_RANGE_SQL = SCOPE_META_FILE_COUNT_DELETE_RANGE_SQL;
586
+ exports.SCOPE_META_FILE_COUNT_TRIGGER_SQL = SCOPE_META_FILE_COUNT_TRIGGER_SQL;
587
+ exports.SCOPE_META_INDEX_SQL = SCOPE_META_INDEX_SQL;
588
+ exports.SCOPE_META_TABLE_SQL = SCOPE_META_TABLE_SQL;
589
+ exports.SCOPE_META_TOTAL_BYTES_BACKFILL_SQL = SCOPE_META_TOTAL_BYTES_BACKFILL_SQL;
590
+ exports.SCOPE_META_TOTAL_BYTES_COLUMN_SQL = SCOPE_META_TOTAL_BYTES_COLUMN_SQL;
591
+ exports.SCOPE_META_TOTAL_BYTES_DELETE_ONE_SQL = SCOPE_META_TOTAL_BYTES_DELETE_ONE_SQL;
592
+ exports.SCOPE_META_TOTAL_BYTES_DELETE_RANGE_SQL = SCOPE_META_TOTAL_BYTES_DELETE_RANGE_SQL;
593
+ exports.SCOPE_META_TOTAL_BYTES_TRIGGER_SQL = SCOPE_META_TOTAL_BYTES_TRIGGER_SQL;
594
+ exports.SYNC_STATE_DDL = SYNC_STATE_DDL;
595
+ exports.SYNC_STATE_INDEX_SQL = SYNC_STATE_INDEX_SQL;
596
+ exports.SYNC_STATE_TABLE_SQL = SYNC_STATE_TABLE_SQL;
597
+ exports.normalizeDdl = normalizeDdl;
598
+ exports.parseChangelogEntry = parseChangelogEntry;
599
+ exports.parseManifestEntry = parseManifestEntry;
600
+ exports.serializeChangelogEntry = serializeChangelogEntry;
601
+ exports.serializeManifestEntry = serializeManifestEntry;
602
+ exports.watermarkPrefix = watermarkPrefix;
603
+ exports.watermarkWritePrefix = watermarkWritePrefix;