@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,240 @@
1
+ import { SYNC_STATE_INDEX_SQL, SYNC_STATE_TABLE_SQL } from "./changelog-schema.mjs";
2
+
3
+ //#region src/local-changelog.ts
4
+ /**
5
+ * LocalChangelog — Phase 3 Task 3.4 (G6)
6
+ *
7
+ * Read-side + GC companion to the `changelog` writes produced by
8
+ * MetadataDB / D1TreeIndex / SQLiteTreeIndex. Used exclusively by the
9
+ * local SyncEngine (desktop + mobile); has NO counterpart inside the
10
+ * CloudflareDIDSpace Worker — the server IS the cloud changelog, it has
11
+ * no notion of "unpushed local rows".
12
+ *
13
+ * Responsibilities:
14
+ *
15
+ * 1. `getUnpushed(sinceSeq, limit?)`
16
+ * Return changelog rows written by THIS device (`device_id == self`)
17
+ * whose `seq > sinceSeq`, ordered by seq ascending. SyncEngine pages
18
+ * through these on the push leg of each sync round.
19
+ *
20
+ * 2. `markPushed(upToSeq)`
21
+ * Advance `sync_state['{scope}:local_seq']` to record that all self-
22
+ * written rows up to `upToSeq` have been accepted by the server. Does
23
+ * NOT delete anything — row retention is owned by `gc()`. The watermark
24
+ * is strictly monotonic (setting a lower value is a no-op).
25
+ *
26
+ * 3. `gc()`
27
+ * Single atomic DELETE that removes:
28
+ * (a) rows from THIS device with seq ≤ local_seq (pushed, no longer
29
+ * needed for resume) AND
30
+ * (b) rows from OTHER devices with seq ≤ cloud_seq (pulled + applied,
31
+ * no longer needed for replay).
32
+ * Called by SyncEngine AFTER a successful sync round. The gc contract
33
+ * is called-by-engine — gc() itself makes no assumption about timing.
34
+ *
35
+ * 4. `getLocalSeq` / `getCloudSeq` / `setCloudSeq`
36
+ * Helpers for SyncEngine and tests. Task 3.5 introduces a richer
37
+ * `SyncStateStore` that owns these KV lookups with Keychain/Keystore
38
+ * backing; for Task 3.4 we keep the reads/writes inside LocalChangelog
39
+ * so the module is self-contained and pre-3.5 integration tests work.
40
+ *
41
+ * The `sync_state` KV table is created by `ensureTable()` — idempotent —
42
+ * and must be present before any of the methods above are called. The DDL
43
+ * lives in `changelog-schema.ts` and is byte-identical across TypeScript,
44
+ * Swift, and Kotlin (Task 3.5 will add a parity check once the schema
45
+ * extends with Keychain-backed keys).
46
+ *
47
+ * Scope isolation: every SQL statement inside LocalChangelog includes a
48
+ * `scope = ?` bind. Cross-scope leaks would regress Task 2.1's scope-
49
+ * scoped changelog design, so both gc() and getUnpushed() carry the scope
50
+ * through explicitly.
51
+ */
52
+ /** Default `limit` applied by `getUnpushed` when none is specified. */
53
+ const LOCAL_CHANGELOG_DEFAULT_LIMIT = 1e3;
54
+ /** Maximum `limit` accepted by `getUnpushed`; larger values are clamped. */
55
+ const LOCAL_CHANGELOG_MAX_LIMIT = 1e4;
56
+ function toChangelogEntry(row) {
57
+ const r = row;
58
+ return {
59
+ seq: Number(r.seq),
60
+ scope: r.scope,
61
+ path: r.path,
62
+ op: r.op,
63
+ cid: r.cid ?? null,
64
+ old_cid: r.old_cid ?? null,
65
+ size: r.size === null || r.size === void 0 ? null : Number(r.size),
66
+ mtime: Number(r.mtime),
67
+ device_id: r.device_id
68
+ };
69
+ }
70
+ var LocalChangelog = class {
71
+ client;
72
+ scope;
73
+ deviceId;
74
+ constructor(opts) {
75
+ if (typeof opts.scope !== "string" || opts.scope.length === 0) throw new Error("LocalChangelog: scope must be a non-empty string");
76
+ if (typeof opts.deviceId !== "string" || opts.deviceId.length === 0) throw new Error("LocalChangelog: deviceId must be a non-empty string");
77
+ this.client = opts.client;
78
+ this.scope = opts.scope;
79
+ this.deviceId = opts.deviceId;
80
+ }
81
+ /**
82
+ * Idempotently create the `sync_state` table (and any future indices).
83
+ *
84
+ * MetadataDB.open() calls this on desktop; mobile runtimes run the DDL
85
+ * inline from their own migrate(). Safe to call from tests that
86
+ * construct LocalChangelog directly on a raw libsql client.
87
+ */
88
+ static async ensureTable(client) {
89
+ await client.execute(SYNC_STATE_TABLE_SQL);
90
+ for (const sql of SYNC_STATE_INDEX_SQL) await client.execute(sql);
91
+ }
92
+ /**
93
+ * Read the `local_seq` watermark — highest changelog.seq that the current
94
+ * device has acknowledged as pushed. Returns 0 when the key is missing
95
+ * (nothing pushed yet).
96
+ */
97
+ async getLocalSeq() {
98
+ return this.readSeqKey(`${this.scope}:local_seq`);
99
+ }
100
+ /**
101
+ * Read the `cloud_seq` watermark — highest changelog.seq from OTHER
102
+ * devices that the current device has applied locally. Task 3.4 does
103
+ * not write this key itself; Task 3.5's SyncEngine will advance it as
104
+ * part of the pull leg. Returns 0 as the "nothing pulled yet" sentinel.
105
+ */
106
+ async getCloudSeq() {
107
+ return this.readSeqKey(`${this.scope}:cloud_seq`);
108
+ }
109
+ /**
110
+ * Test / SyncEngine helper to advance the cloud_seq watermark.
111
+ *
112
+ * Monotonic: a caller passing a lower value than the stored watermark
113
+ * is a no-op. This matches Task 3.5's eventual API contract and keeps
114
+ * LocalChangelog's GC branch for "other devices" safe under retries.
115
+ */
116
+ async setCloudSeq(seq) {
117
+ await this.writeSeqKeyMonotonic(`${this.scope}:cloud_seq`, seq);
118
+ }
119
+ /**
120
+ * Low-level SELECT for a `sync_state` integer key. Returns 0 when the
121
+ * key is missing. Throws on non-numeric values (corrupt state).
122
+ */
123
+ async readSeqKey(key) {
124
+ const result = await this.client.execute({
125
+ sql: "SELECT value FROM ds_sync_state WHERE key = ?",
126
+ args: [key]
127
+ });
128
+ if (result.rows.length === 0) return 0;
129
+ const raw = result.rows[0][0];
130
+ if (raw === null || raw === void 0) return 0;
131
+ const value = typeof raw === "string" ? raw : String(raw);
132
+ const parsed = Number(value);
133
+ if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) throw new Error(`LocalChangelog: corrupt sync_state value for key=${key}: ${value}`);
134
+ return parsed;
135
+ }
136
+ /**
137
+ * Monotonic INSERT-OR-REPLACE for a `sync_state` integer key. The CASE
138
+ * expression keeps the prior value when the incoming one is lower.
139
+ *
140
+ * Negative inputs are clamped to 0 so misbehaving callers cannot rewind
141
+ * the watermark below the "nothing synced yet" sentinel.
142
+ */
143
+ async writeSeqKeyMonotonic(key, seq) {
144
+ const safe = Math.max(0, Math.floor(Number.isFinite(seq) ? seq : 0));
145
+ await this.client.execute({
146
+ sql: `INSERT INTO ds_sync_state (key, value) VALUES (?, ?)
147
+ ON CONFLICT(key) DO UPDATE SET
148
+ value = CASE
149
+ WHEN CAST(excluded.value AS INTEGER) > CAST(ds_sync_state.value AS INTEGER)
150
+ THEN excluded.value
151
+ ELSE ds_sync_state.value
152
+ END`,
153
+ args: [key, String(safe)]
154
+ });
155
+ }
156
+ /**
157
+ * Return self-written changelog rows with seq > sinceSeq, ordered by seq
158
+ * ascending. Rows from other devices are excluded at the SQL layer
159
+ * (device_id filter) so this function is cheap even on multi-device
160
+ * spaces with heavy pull traffic.
161
+ *
162
+ * Clamping rules (matches G5.a Worker endpoint for consistency):
163
+ * - sinceSeq < 0 → clamped to 0 (not rejected; caller is internal)
164
+ * - limit undefined → LOCAL_CHANGELOG_DEFAULT_LIMIT (1000)
165
+ * - limit === 0 → returns [] without hitting SQLite
166
+ * - limit > LOCAL_CHANGELOG_MAX_LIMIT → clamped to 10000
167
+ */
168
+ async getUnpushed(sinceSeq, limit) {
169
+ const safeSince = Math.max(0, Math.floor(Number.isFinite(sinceSeq) ? sinceSeq : 0));
170
+ const requested = limit ?? LOCAL_CHANGELOG_DEFAULT_LIMIT;
171
+ if (requested === 0) return [];
172
+ const safeLimit = Math.min(LOCAL_CHANGELOG_MAX_LIMIT, Math.max(0, Math.floor(Number.isFinite(requested) ? requested : 0)));
173
+ if (safeLimit === 0) return [];
174
+ return (await this.client.execute({
175
+ sql: `SELECT seq, scope, path, op, cid, old_cid, size, mtime, device_id
176
+ FROM ds_changelog
177
+ WHERE scope = ? AND device_id = ? AND seq > ?
178
+ ORDER BY seq ASC
179
+ LIMIT ?`,
180
+ args: [
181
+ this.scope,
182
+ this.deviceId,
183
+ safeSince,
184
+ safeLimit
185
+ ]
186
+ })).rows.map(toChangelogEntry);
187
+ }
188
+ /**
189
+ * Advance the `local_seq` watermark to `upToSeq`. Does NOT delete rows;
190
+ * `gc()` is the only path that removes data.
191
+ *
192
+ * Monotonic: calls with `upToSeq` less than or equal to the stored
193
+ * watermark become no-ops. This keeps the invariant that SyncEngine can
194
+ * safely retry pushes without rewinding progress.
195
+ */
196
+ async markPushed(upToSeq) {
197
+ await this.writeSeqKeyMonotonic(`${this.scope}:local_seq`, upToSeq);
198
+ }
199
+ /**
200
+ * Atomically delete self-pushed rows (seq ≤ local_seq) AND other-device
201
+ * rows that have been applied locally (seq ≤ cloud_seq).
202
+ *
203
+ * Rows that do NOT match either branch — e.g. other-device rows above
204
+ * cloud_seq, or self rows above local_seq — remain untouched. This is
205
+ * the non-negotiable safety rule: GC must never remove a row whose
206
+ * application is still pending.
207
+ *
208
+ * Implementation note: we read local_seq + cloud_seq BEFORE issuing the
209
+ * DELETE and bake them into the WHERE clause. This keeps the DELETE a
210
+ * single statement (the spec mandates a single-shot DELETE, not a
211
+ * row-by-row loop) and makes the semantics easy to reason about under
212
+ * concurrent gc() invocations — each call operates on a point-in-time
213
+ * snapshot of the watermarks.
214
+ */
215
+ async gc() {
216
+ const localSeq = await this.getLocalSeq();
217
+ const cloudSeq = await this.getCloudSeq();
218
+ const result = await this.client.execute({
219
+ sql: `DELETE FROM ds_changelog
220
+ WHERE scope = ?
221
+ AND (
222
+ (device_id = ? AND seq <= ?)
223
+ OR
224
+ (device_id != ? AND seq <= ?)
225
+ )`,
226
+ args: [
227
+ this.scope,
228
+ this.deviceId,
229
+ localSeq,
230
+ this.deviceId,
231
+ cloudSeq
232
+ ]
233
+ });
234
+ return { deleted: Number(result.rowsAffected ?? 0) };
235
+ }
236
+ };
237
+
238
+ //#endregion
239
+ export { LOCAL_CHANGELOG_DEFAULT_LIMIT, LOCAL_CHANGELOG_MAX_LIMIT, LocalChangelog };
240
+ //# sourceMappingURL=local-changelog.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-changelog.mjs","names":[],"sources":["../src/local-changelog.ts"],"sourcesContent":["/**\n * LocalChangelog — Phase 3 Task 3.4 (G6)\n *\n * Read-side + GC companion to the `changelog` writes produced by\n * MetadataDB / D1TreeIndex / SQLiteTreeIndex. Used exclusively by the\n * local SyncEngine (desktop + mobile); has NO counterpart inside the\n * CloudflareDIDSpace Worker — the server IS the cloud changelog, it has\n * no notion of \"unpushed local rows\".\n *\n * Responsibilities:\n *\n * 1. `getUnpushed(sinceSeq, limit?)`\n * Return changelog rows written by THIS device (`device_id == self`)\n * whose `seq > sinceSeq`, ordered by seq ascending. SyncEngine pages\n * through these on the push leg of each sync round.\n *\n * 2. `markPushed(upToSeq)`\n * Advance `sync_state['{scope}:local_seq']` to record that all self-\n * written rows up to `upToSeq` have been accepted by the server. Does\n * NOT delete anything — row retention is owned by `gc()`. The watermark\n * is strictly monotonic (setting a lower value is a no-op).\n *\n * 3. `gc()`\n * Single atomic DELETE that removes:\n * (a) rows from THIS device with seq ≤ local_seq (pushed, no longer\n * needed for resume) AND\n * (b) rows from OTHER devices with seq ≤ cloud_seq (pulled + applied,\n * no longer needed for replay).\n * Called by SyncEngine AFTER a successful sync round. The gc contract\n * is called-by-engine — gc() itself makes no assumption about timing.\n *\n * 4. `getLocalSeq` / `getCloudSeq` / `setCloudSeq`\n * Helpers for SyncEngine and tests. Task 3.5 introduces a richer\n * `SyncStateStore` that owns these KV lookups with Keychain/Keystore\n * backing; for Task 3.4 we keep the reads/writes inside LocalChangelog\n * so the module is self-contained and pre-3.5 integration tests work.\n *\n * The `sync_state` KV table is created by `ensureTable()` — idempotent —\n * and must be present before any of the methods above are called. The DDL\n * lives in `changelog-schema.ts` and is byte-identical across TypeScript,\n * Swift, and Kotlin (Task 3.5 will add a parity check once the schema\n * extends with Keychain-backed keys).\n *\n * Scope isolation: every SQL statement inside LocalChangelog includes a\n * `scope = ?` bind. Cross-scope leaks would regress Task 2.1's scope-\n * scoped changelog design, so both gc() and getUnpushed() carry the scope\n * through explicitly.\n */\n\nimport { SYNC_STATE_INDEX_SQL, SYNC_STATE_TABLE_SQL } from \"./changelog-schema.js\";\nimport type { ChangelogEntry } from \"./tree-index.js\";\n\n/** Default `limit` applied by `getUnpushed` when none is specified. */\nexport const LOCAL_CHANGELOG_DEFAULT_LIMIT = 1000;\n\n/** Maximum `limit` accepted by `getUnpushed`; larger values are clamped. */\nexport const LOCAL_CHANGELOG_MAX_LIMIT = 10000;\n\nexport interface LocalChangelogOptions {\n /**\n * Already-opened libsql client sharing the same DB file as the TreeIndex.\n * LocalChangelog does NOT own the client lifecycle — callers (typically\n * `DIDSpaceProvider` construction) remain responsible for close().\n */\n client: import(\"@libsql/client\").Client;\n\n /** Scope string written into `changelog` and used to partition `sync_state` keys. */\n scope: string;\n\n /**\n * Device identifier of the current process. Used BOTH as the `self` filter\n * for `getUnpushed` AND as the branch discriminator in `gc()`.\n *\n * Task 3.4 takes this via constructor injection. Task 3.5 will wire the\n * argument to a Keychain/Keystore-backed SyncStateStore without changing\n * LocalChangelog's public surface.\n */\n deviceId: string;\n}\n\n/** Raw row shape returned by libsql SELECT against `changelog`. */\ninterface RawChangelogRow {\n seq: unknown;\n scope: unknown;\n path: unknown;\n op: unknown;\n cid: unknown;\n old_cid: unknown;\n size: unknown;\n mtime: unknown;\n device_id: unknown;\n}\n\nfunction toChangelogEntry(row: object): ChangelogEntry {\n const r = row as unknown as RawChangelogRow;\n return {\n seq: Number(r.seq),\n scope: r.scope as string,\n path: r.path as string,\n op: r.op as \"put\" | \"delete\",\n cid: (r.cid as string | null) ?? null,\n old_cid: (r.old_cid as string | null) ?? null,\n size: r.size === null || r.size === undefined ? null : Number(r.size),\n mtime: Number(r.mtime),\n device_id: r.device_id as string,\n };\n}\n\nexport class LocalChangelog {\n private readonly client: import(\"@libsql/client\").Client;\n private readonly scope: string;\n private readonly deviceId: string;\n\n constructor(opts: LocalChangelogOptions) {\n if (typeof opts.scope !== \"string\" || opts.scope.length === 0) {\n throw new Error(\"LocalChangelog: scope must be a non-empty string\");\n }\n if (typeof opts.deviceId !== \"string\" || opts.deviceId.length === 0) {\n throw new Error(\"LocalChangelog: deviceId must be a non-empty string\");\n }\n this.client = opts.client;\n this.scope = opts.scope;\n this.deviceId = opts.deviceId;\n }\n\n /**\n * Idempotently create the `sync_state` table (and any future indices).\n *\n * MetadataDB.open() calls this on desktop; mobile runtimes run the DDL\n * inline from their own migrate(). Safe to call from tests that\n * construct LocalChangelog directly on a raw libsql client.\n */\n static async ensureTable(client: import(\"@libsql/client\").Client): Promise<void> {\n await client.execute(SYNC_STATE_TABLE_SQL);\n for (const sql of SYNC_STATE_INDEX_SQL) {\n await client.execute(sql);\n }\n }\n\n // ── sync_state KV helpers ──────────────────────────────────────\n\n /**\n * Read the `local_seq` watermark — highest changelog.seq that the current\n * device has acknowledged as pushed. Returns 0 when the key is missing\n * (nothing pushed yet).\n */\n async getLocalSeq(): Promise<number> {\n return this.readSeqKey(`${this.scope}:local_seq`);\n }\n\n /**\n * Read the `cloud_seq` watermark — highest changelog.seq from OTHER\n * devices that the current device has applied locally. Task 3.4 does\n * not write this key itself; Task 3.5's SyncEngine will advance it as\n * part of the pull leg. Returns 0 as the \"nothing pulled yet\" sentinel.\n */\n async getCloudSeq(): Promise<number> {\n return this.readSeqKey(`${this.scope}:cloud_seq`);\n }\n\n /**\n * Test / SyncEngine helper to advance the cloud_seq watermark.\n *\n * Monotonic: a caller passing a lower value than the stored watermark\n * is a no-op. This matches Task 3.5's eventual API contract and keeps\n * LocalChangelog's GC branch for \"other devices\" safe under retries.\n */\n async setCloudSeq(seq: number): Promise<void> {\n await this.writeSeqKeyMonotonic(`${this.scope}:cloud_seq`, seq);\n }\n\n /**\n * Low-level SELECT for a `sync_state` integer key. Returns 0 when the\n * key is missing. Throws on non-numeric values (corrupt state).\n */\n private async readSeqKey(key: string): Promise<number> {\n const result = await this.client.execute({\n sql: \"SELECT value FROM ds_sync_state WHERE key = ?\",\n args: [key],\n });\n if (result.rows.length === 0) return 0;\n const raw = result.rows[0]![0];\n if (raw === null || raw === undefined) return 0;\n const value = typeof raw === \"string\" ? raw : String(raw);\n const parsed = Number(value);\n if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) {\n throw new Error(`LocalChangelog: corrupt sync_state value for key=${key}: ${value}`);\n }\n return parsed;\n }\n\n /**\n * Monotonic INSERT-OR-REPLACE for a `sync_state` integer key. The CASE\n * expression keeps the prior value when the incoming one is lower.\n *\n * Negative inputs are clamped to 0 so misbehaving callers cannot rewind\n * the watermark below the \"nothing synced yet\" sentinel.\n */\n private async writeSeqKeyMonotonic(key: string, seq: number): Promise<void> {\n const safe = Math.max(0, Math.floor(Number.isFinite(seq) ? seq : 0));\n await this.client.execute({\n sql: `INSERT INTO ds_sync_state (key, value) VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET\n value = CASE\n WHEN CAST(excluded.value AS INTEGER) > CAST(ds_sync_state.value AS INTEGER)\n THEN excluded.value\n ELSE ds_sync_state.value\n END`,\n args: [key, String(safe)],\n });\n }\n\n // ── public API ─────────────────────────────────────────────────\n\n /**\n * Return self-written changelog rows with seq > sinceSeq, ordered by seq\n * ascending. Rows from other devices are excluded at the SQL layer\n * (device_id filter) so this function is cheap even on multi-device\n * spaces with heavy pull traffic.\n *\n * Clamping rules (matches G5.a Worker endpoint for consistency):\n * - sinceSeq < 0 → clamped to 0 (not rejected; caller is internal)\n * - limit undefined → LOCAL_CHANGELOG_DEFAULT_LIMIT (1000)\n * - limit === 0 → returns [] without hitting SQLite\n * - limit > LOCAL_CHANGELOG_MAX_LIMIT → clamped to 10000\n */\n async getUnpushed(sinceSeq: number, limit?: number): Promise<ChangelogEntry[]> {\n const safeSince = Math.max(0, Math.floor(Number.isFinite(sinceSeq) ? sinceSeq : 0));\n const requested = limit ?? LOCAL_CHANGELOG_DEFAULT_LIMIT;\n if (requested === 0) return [];\n const safeLimit = Math.min(\n LOCAL_CHANGELOG_MAX_LIMIT,\n Math.max(0, Math.floor(Number.isFinite(requested) ? requested : 0)),\n );\n if (safeLimit === 0) return [];\n\n const result = await this.client.execute({\n sql: `SELECT seq, scope, path, op, cid, old_cid, size, mtime, device_id\n FROM ds_changelog\n WHERE scope = ? AND device_id = ? AND seq > ?\n ORDER BY seq ASC\n LIMIT ?`,\n args: [this.scope, this.deviceId, safeSince, safeLimit],\n });\n return result.rows.map(toChangelogEntry);\n }\n\n /**\n * Advance the `local_seq` watermark to `upToSeq`. Does NOT delete rows;\n * `gc()` is the only path that removes data.\n *\n * Monotonic: calls with `upToSeq` less than or equal to the stored\n * watermark become no-ops. This keeps the invariant that SyncEngine can\n * safely retry pushes without rewinding progress.\n */\n async markPushed(upToSeq: number): Promise<void> {\n await this.writeSeqKeyMonotonic(`${this.scope}:local_seq`, upToSeq);\n }\n\n /**\n * Atomically delete self-pushed rows (seq ≤ local_seq) AND other-device\n * rows that have been applied locally (seq ≤ cloud_seq).\n *\n * Rows that do NOT match either branch — e.g. other-device rows above\n * cloud_seq, or self rows above local_seq — remain untouched. This is\n * the non-negotiable safety rule: GC must never remove a row whose\n * application is still pending.\n *\n * Implementation note: we read local_seq + cloud_seq BEFORE issuing the\n * DELETE and bake them into the WHERE clause. This keeps the DELETE a\n * single statement (the spec mandates a single-shot DELETE, not a\n * row-by-row loop) and makes the semantics easy to reason about under\n * concurrent gc() invocations — each call operates on a point-in-time\n * snapshot of the watermarks.\n */\n async gc(): Promise<{ deleted: number }> {\n const localSeq = await this.getLocalSeq();\n const cloudSeq = await this.getCloudSeq();\n\n const result = await this.client.execute({\n sql: `DELETE FROM ds_changelog\n WHERE scope = ?\n AND (\n (device_id = ? AND seq <= ?)\n OR\n (device_id != ? AND seq <= ?)\n )`,\n args: [this.scope, this.deviceId, localSeq, this.deviceId, cloudSeq],\n });\n return { deleted: Number(result.rowsAffected ?? 0) };\n }\n}\n"],"mappings":"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"}