@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,221 @@
1
+ import { AFSAlreadyExistsError, AFSError, AFSForbiddenError, AFSValidationError } from "@aigne/afs";
2
+ import { load } from "js-yaml";
3
+
4
+ //#region src/share-declaration.ts
5
+ /**
6
+ * Phase 0.2 — ShareDeclaration: YAML schema parsing + path helpers.
7
+ *
8
+ * Exported functions used by Phase 0.3 (ShareResolver) and Phase 0.4 (writeHandler hook):
9
+ * - parseShareDeclaration
10
+ * - isShareDeclarationPath
11
+ * - isShareReservedPath
12
+ * - deriveSourcePath
13
+ * - mapShareErrorToAFSError
14
+ */
15
+ const KNOWN_FIELDS = new Set([
16
+ "slug",
17
+ "kind",
18
+ "status",
19
+ "expires_at",
20
+ "password",
21
+ "visibility",
22
+ "description",
23
+ "domain"
24
+ ]);
25
+ const SLUG_REGEX = /^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/;
26
+ const MAX_CONTENT_BYTES = 4096;
27
+ const MAX_DESCRIPTION_LENGTH = 200;
28
+ /**
29
+ * Parse and validate a `.share` file's content.
30
+ *
31
+ * Validation order (strict, per spec):
32
+ * 1. Size check (> 4096 bytes) — before YAML parse
33
+ * 2. Empty content (0 bytes) → { ok: true, data: {} }
34
+ * 3. UTF-8 decode (fatal mode)
35
+ * 4. YAML parse with maxAliasCount: 0
36
+ * 5. Unknown field detection
37
+ * 6. slug format
38
+ * 7. kind enum
39
+ * 8. status enum
40
+ * 9. description length
41
+ * 10. expires_at format
42
+ * 11. password structure
43
+ */
44
+ function parseShareDeclaration(content) {
45
+ if (content.byteLength > MAX_CONTENT_BYTES) return {
46
+ ok: false,
47
+ code: "share-content-too-large",
48
+ message: `Content size ${content.byteLength} bytes exceeds ${MAX_CONTENT_BYTES} byte limit`,
49
+ detail: {
50
+ sizeBytes: content.byteLength,
51
+ limit: MAX_CONTENT_BYTES
52
+ }
53
+ };
54
+ if (content.byteLength === 0) return {
55
+ ok: true,
56
+ data: {}
57
+ };
58
+ let text;
59
+ try {
60
+ text = new TextDecoder("utf-8", { fatal: true }).decode(content);
61
+ } catch {
62
+ return {
63
+ ok: false,
64
+ code: "share-yaml-parse-error",
65
+ message: "Content is not valid UTF-8"
66
+ };
67
+ }
68
+ let parsed;
69
+ try {
70
+ parsed = load(text);
71
+ } catch (err) {
72
+ return {
73
+ ok: false,
74
+ code: "share-yaml-parse-error",
75
+ message: err instanceof Error ? err.message : String(err),
76
+ detail: err
77
+ };
78
+ }
79
+ if (parsed == null) return {
80
+ ok: true,
81
+ data: {}
82
+ };
83
+ if (typeof parsed !== "object" || Array.isArray(parsed)) return {
84
+ ok: false,
85
+ code: "share-yaml-parse-error",
86
+ message: "Expected a YAML mapping (object), got a different type"
87
+ };
88
+ const obj = parsed;
89
+ for (const key of Object.keys(obj)) if (!KNOWN_FIELDS.has(key)) return {
90
+ ok: false,
91
+ code: "share-field-unknown",
92
+ message: `Unknown field: ${key}`,
93
+ detail: { field: key }
94
+ };
95
+ if (obj.slug !== void 0) {
96
+ if (typeof obj.slug !== "string" || !SLUG_REGEX.test(obj.slug)) return {
97
+ ok: false,
98
+ code: "share-slug-invalid",
99
+ message: `slug must match /^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/, got: ${JSON.stringify(obj.slug)}`,
100
+ detail: { slug: obj.slug }
101
+ };
102
+ }
103
+ if (obj.kind !== void 0) {
104
+ if (obj.kind !== "raw" && obj.kind !== "web") return {
105
+ ok: false,
106
+ code: "share-kind-invalid",
107
+ message: `kind must be "raw" or "web", got: ${JSON.stringify(obj.kind)}`,
108
+ detail: { kind: obj.kind }
109
+ };
110
+ }
111
+ if (obj.status !== void 0) {
112
+ if (obj.status !== "active" && obj.status !== "revoked") return {
113
+ ok: false,
114
+ code: "share-status-invalid",
115
+ message: `status must be "active" or "revoked", got: ${JSON.stringify(obj.status)}`,
116
+ detail: { status: obj.status }
117
+ };
118
+ }
119
+ if (obj.description !== void 0) {
120
+ if (typeof obj.description !== "string" || obj.description.length > MAX_DESCRIPTION_LENGTH) return {
121
+ ok: false,
122
+ code: "share-field-invalid",
123
+ message: `description must be a string with at most ${MAX_DESCRIPTION_LENGTH} characters`,
124
+ detail: { field: "description" }
125
+ };
126
+ }
127
+ if (obj.expires_at !== void 0) {
128
+ if (typeof obj.expires_at !== "string" || !isValidExpiresAt(obj.expires_at)) return {
129
+ ok: false,
130
+ code: "share-field-invalid",
131
+ message: `expires_at must be a valid ISO 8601 datetime or Unix milliseconds string`,
132
+ detail: { field: "expires_at" }
133
+ };
134
+ }
135
+ if (obj.password !== void 0) {
136
+ const pwd = obj.password;
137
+ if (typeof pwd !== "object" || pwd === null || Array.isArray(pwd) || pwd.algorithm !== "argon2id" || typeof pwd.hash !== "string") return {
138
+ ok: false,
139
+ code: "share-field-invalid",
140
+ message: "password must be {algorithm: \"argon2id\", hash: string}",
141
+ detail: { field: "password" }
142
+ };
143
+ }
144
+ return {
145
+ ok: true,
146
+ data: obj
147
+ };
148
+ }
149
+ function isValidExpiresAt(value) {
150
+ if (/^\d+$/.test(value)) return true;
151
+ const d = new Date(value);
152
+ return !Number.isNaN(d.getTime());
153
+ }
154
+ /**
155
+ * Returns true if `path` is a `.share` declaration file (in-tree or sidecar).
156
+ *
157
+ * Examples:
158
+ * `.share` → true (root in-tree)
159
+ * `/.share` → true (root in-tree with leading slash)
160
+ * `docs/.share` → true (subdirectory in-tree)
161
+ * `file.pdf.share` → true (sidecar)
162
+ * `.shares/foo` → false (reserved virtual view)
163
+ * `README.md` → false
164
+ */
165
+ function isShareDeclarationPath(path) {
166
+ return (path.startsWith("/") ? path.slice(1) : path).endsWith(".share");
167
+ }
168
+ /**
169
+ * Derives the source path from a declaration path.
170
+ *
171
+ * Examples:
172
+ * `.share` → `""` (root in-tree → source is root directory)
173
+ * `docs/.share` → `"docs"`
174
+ * `file.pdf.share` → `"file.pdf"`
175
+ */
176
+ function deriveSourcePath(declPath) {
177
+ const p = declPath.startsWith("/") ? declPath.slice(1) : declPath;
178
+ if (p.endsWith("/.share")) return p.slice(0, -7);
179
+ return p.slice(0, -6);
180
+ }
181
+ /**
182
+ * Returns true if `path` is a reserved share virtual path (read-only view, not writable).
183
+ *
184
+ * Reserved paths:
185
+ * `.shares` → the root virtual share listing
186
+ * `.shares/<anything>` → entries under the root listing
187
+ * `instances/<iid>/.shares` → per-instance listing
188
+ * `instances/<iid>/.shares/<…>` → per-instance listing entries
189
+ */
190
+ function isShareReservedPath(path) {
191
+ const norm = path.replace(/^\/+/, "");
192
+ if (norm === ".shares" || norm.startsWith(".shares/")) return true;
193
+ if (/^instances\/[^/]+\/\.shares(\/|$)/.test(norm)) return true;
194
+ return false;
195
+ }
196
+ /**
197
+ * Maps a ShareResolver / parser error code to the appropriate AFS error type
198
+ * so that writeHandler can throw with the correct HTTP status code.
199
+ */
200
+ function mapShareErrorToAFSError(code, message, path) {
201
+ switch (code) {
202
+ case "share-yaml-parse-error":
203
+ case "share-content-too-large":
204
+ case "share-field-unknown":
205
+ case "share-field-invalid":
206
+ case "share-slug-invalid":
207
+ case "share-kind-invalid":
208
+ case "share-status-invalid":
209
+ case "share-web-no-decl":
210
+ case "share-sidecar-target-missing":
211
+ case "share-nested": return new AFSValidationError(`[${path}] ${code}: ${message}`);
212
+ case "share-path-forbidden":
213
+ case "share-path-reserved": return new AFSForbiddenError(path, code);
214
+ case "share-slug-conflict": return new AFSAlreadyExistsError(path, message);
215
+ default: return new AFSError(`${code}: ${message}`, code);
216
+ }
217
+ }
218
+
219
+ //#endregion
220
+ export { deriveSourcePath, isShareDeclarationPath, isShareReservedPath, mapShareErrorToAFSError, parseShareDeclaration };
221
+ //# sourceMappingURL=share-declaration.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share-declaration.mjs","names":["yamlParse"],"sources":["../src/share-declaration.ts"],"sourcesContent":["/**\n * Phase 0.2 — ShareDeclaration: YAML schema parsing + path helpers.\n *\n * Exported functions used by Phase 0.3 (ShareResolver) and Phase 0.4 (writeHandler hook):\n * - parseShareDeclaration\n * - isShareDeclarationPath\n * - isShareReservedPath\n * - deriveSourcePath\n * - mapShareErrorToAFSError\n */\n\nimport { AFSAlreadyExistsError, AFSError, AFSForbiddenError, AFSValidationError } from \"@aigne/afs\";\nimport { load as yamlParse } from \"js-yaml\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/** All fields are optional; an empty file is equivalent to `{}`. */\nexport interface ShareDeclaration {\n slug?: string;\n kind?: \"raw\" | \"web\";\n status?: \"active\" | \"revoked\";\n expires_at?: string; // ISO 8601 or Unix ms string\n password?: { algorithm: \"argon2id\"; hash: string };\n visibility?: \"public\" | \"unlisted\";\n description?: string; // max 200 characters\n domain?: string; // Phase 2 only\n}\n\ntype ParseOk = { ok: true; data: ShareDeclaration };\ntype ParseFail = { ok: false; code: string; message: string; detail?: unknown };\nexport type ParseResult = ParseOk | ParseFail;\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst KNOWN_FIELDS = new Set([\n \"slug\",\n \"kind\",\n \"status\",\n \"expires_at\",\n \"password\",\n \"visibility\",\n \"description\",\n \"domain\",\n]);\n\nconst SLUG_REGEX = /^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/;\n\nconst MAX_CONTENT_BYTES = 4096;\nconst MAX_DESCRIPTION_LENGTH = 200;\n\n// ─── Parser ───────────────────────────────────────────────────────────────────\n\n/**\n * Parse and validate a `.share` file's content.\n *\n * Validation order (strict, per spec):\n * 1. Size check (> 4096 bytes) — before YAML parse\n * 2. Empty content (0 bytes) → { ok: true, data: {} }\n * 3. UTF-8 decode (fatal mode)\n * 4. YAML parse with maxAliasCount: 0\n * 5. Unknown field detection\n * 6. slug format\n * 7. kind enum\n * 8. status enum\n * 9. description length\n * 10. expires_at format\n * 11. password structure\n */\nexport function parseShareDeclaration(content: Uint8Array): ParseResult {\n // Step 1: size check — MUST happen before YAML parse\n if (content.byteLength > MAX_CONTENT_BYTES) {\n return {\n ok: false,\n code: \"share-content-too-large\",\n message: `Content size ${content.byteLength} bytes exceeds ${MAX_CONTENT_BYTES} byte limit`,\n detail: { sizeBytes: content.byteLength, limit: MAX_CONTENT_BYTES },\n };\n }\n\n // Step 2: empty content\n if (content.byteLength === 0) {\n return { ok: true, data: {} };\n }\n\n // Step 3: UTF-8 decode (fatal — reject non-UTF-8 bytes)\n let text: string;\n try {\n text = new TextDecoder(\"utf-8\", { fatal: true }).decode(content);\n } catch {\n return {\n ok: false,\n code: \"share-yaml-parse-error\",\n message: \"Content is not valid UTF-8\",\n };\n }\n\n // Step 4: YAML parse (content size already capped at 4096 bytes above)\n let parsed: unknown;\n try {\n parsed = yamlParse(text);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n ok: false,\n code: \"share-yaml-parse-error\",\n message: msg,\n detail: err,\n };\n }\n\n // null / undefined YAML (empty doc, comment-only, \"---\\n\") → empty declaration\n if (parsed == null) {\n return { ok: true, data: {} };\n }\n\n // Must be a plain object\n if (typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {\n ok: false,\n code: \"share-yaml-parse-error\",\n message: \"Expected a YAML mapping (object), got a different type\",\n };\n }\n\n const obj = parsed as Record<string, unknown>;\n\n // Step 5: unknown fields\n for (const key of Object.keys(obj)) {\n if (!KNOWN_FIELDS.has(key)) {\n return {\n ok: false,\n code: \"share-field-unknown\",\n message: `Unknown field: ${key}`,\n detail: { field: key },\n };\n }\n }\n\n // Step 6: slug format\n if (obj.slug !== undefined) {\n if (typeof obj.slug !== \"string\" || !SLUG_REGEX.test(obj.slug)) {\n return {\n ok: false,\n code: \"share-slug-invalid\",\n message: `slug must match /^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/, got: ${JSON.stringify(obj.slug)}`,\n detail: { slug: obj.slug },\n };\n }\n }\n\n // Step 7: kind enum\n if (obj.kind !== undefined) {\n if (obj.kind !== \"raw\" && obj.kind !== \"web\") {\n return {\n ok: false,\n code: \"share-kind-invalid\",\n message: `kind must be \"raw\" or \"web\", got: ${JSON.stringify(obj.kind)}`,\n detail: { kind: obj.kind },\n };\n }\n }\n\n // Step 8: status enum\n if (obj.status !== undefined) {\n if (obj.status !== \"active\" && obj.status !== \"revoked\") {\n return {\n ok: false,\n code: \"share-status-invalid\",\n message: `status must be \"active\" or \"revoked\", got: ${JSON.stringify(obj.status)}`,\n detail: { status: obj.status },\n };\n }\n }\n\n // Step 9: description length\n if (obj.description !== undefined) {\n if (typeof obj.description !== \"string\" || obj.description.length > MAX_DESCRIPTION_LENGTH) {\n return {\n ok: false,\n code: \"share-field-invalid\",\n message: `description must be a string with at most ${MAX_DESCRIPTION_LENGTH} characters`,\n detail: { field: \"description\" },\n };\n }\n }\n\n // Step 10: expires_at format\n if (obj.expires_at !== undefined) {\n if (typeof obj.expires_at !== \"string\" || !isValidExpiresAt(obj.expires_at)) {\n return {\n ok: false,\n code: \"share-field-invalid\",\n message: `expires_at must be a valid ISO 8601 datetime or Unix milliseconds string`,\n detail: { field: \"expires_at\" },\n };\n }\n }\n\n // Step 11: password structure\n if (obj.password !== undefined) {\n const pwd = obj.password as Record<string, unknown>;\n if (\n typeof pwd !== \"object\" ||\n pwd === null ||\n Array.isArray(pwd) ||\n pwd.algorithm !== \"argon2id\" ||\n typeof pwd.hash !== \"string\"\n ) {\n return {\n ok: false,\n code: \"share-field-invalid\",\n message: 'password must be {algorithm: \"argon2id\", hash: string}',\n detail: { field: \"password\" },\n };\n }\n }\n\n return { ok: true, data: obj as ShareDeclaration };\n}\n\nfunction isValidExpiresAt(value: string): boolean {\n // Accept Unix milliseconds (all-digit string)\n if (/^\\d+$/.test(value)) return true;\n // Accept ISO 8601 (anything Date can parse)\n const d = new Date(value);\n return !Number.isNaN(d.getTime());\n}\n\n// ─── Path helpers ─────────────────────────────────────────────────────────────\n\n/**\n * Returns true if `path` is a `.share` declaration file (in-tree or sidecar).\n *\n * Examples:\n * `.share` → true (root in-tree)\n * `/.share` → true (root in-tree with leading slash)\n * `docs/.share` → true (subdirectory in-tree)\n * `file.pdf.share` → true (sidecar)\n * `.shares/foo` → false (reserved virtual view)\n * `README.md` → false\n */\nexport function isShareDeclarationPath(path: string): boolean {\n const p = path.startsWith(\"/\") ? path.slice(1) : path;\n // All three cases (.share, dir/.share, file.pdf.share) end with \".share\"\n // Note: \".shares\" ends with \".shares\", not \".share\", so it correctly returns false\n return p.endsWith(\".share\");\n}\n\n/**\n * Derives the source path from a declaration path.\n *\n * Examples:\n * `.share` → `\"\"` (root in-tree → source is root directory)\n * `docs/.share` → `\"docs\"`\n * `file.pdf.share` → `\"file.pdf\"`\n */\nexport function deriveSourcePath(declPath: string): string {\n const p = declPath.startsWith(\"/\") ? declPath.slice(1) : declPath;\n if (p.endsWith(\"/.share\")) return p.slice(0, -\"/.share\".length);\n // Root in-tree (\".share\") → slice(0, -6) === \"\" ✓; sidecar (\"file.pdf.share\") → \"file.pdf\" ✓\n return p.slice(0, -\".share\".length);\n}\n\n/**\n * Returns true if `path` is a reserved share virtual path (read-only view, not writable).\n *\n * Reserved paths:\n * `.shares` → the root virtual share listing\n * `.shares/<anything>` → entries under the root listing\n * `instances/<iid>/.shares` → per-instance listing\n * `instances/<iid>/.shares/<…>` → per-instance listing entries\n */\nexport function isShareReservedPath(path: string): boolean {\n const norm = path.replace(/^\\/+/, \"\");\n if (norm === \".shares\" || norm.startsWith(\".shares/\")) return true;\n if (/^instances\\/[^/]+\\/\\.shares(\\/|$)/.test(norm)) return true;\n return false;\n}\n\n// ─── Error mapper ─────────────────────────────────────────────────────────────\n\n/**\n * Maps a ShareResolver / parser error code to the appropriate AFS error type\n * so that writeHandler can throw with the correct HTTP status code.\n */\nexport function mapShareErrorToAFSError(\n code: string,\n message: string,\n path: string,\n): AFSValidationError | AFSForbiddenError | AFSAlreadyExistsError | AFSError {\n switch (code) {\n // 400 Bad Request — validation\n case \"share-yaml-parse-error\":\n case \"share-content-too-large\":\n case \"share-field-unknown\":\n case \"share-field-invalid\":\n case \"share-slug-invalid\":\n case \"share-kind-invalid\":\n case \"share-status-invalid\":\n case \"share-web-no-decl\":\n case \"share-sidecar-target-missing\":\n case \"share-nested\":\n return new AFSValidationError(`[${path}] ${code}: ${message}`);\n // 403 Forbidden\n case \"share-path-forbidden\":\n case \"share-path-reserved\":\n return new AFSForbiddenError(path, code);\n // 409 Conflict — slug already used by a different decl_path\n case \"share-slug-conflict\":\n return new AFSAlreadyExistsError(path, message);\n // 500 fallback\n default:\n return new AFSError(`${code}: ${message}`, code);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
+ const require_share_declaration = require('./share-declaration.cjs');
3
+ let _aigne_afs = require("@aigne/afs");
4
+
5
+ //#region src/share-hook.ts
6
+ /**
7
+ * Phase 0.4 — Share write/delete hooks for all DID Space write paths.
8
+ *
9
+ * Provides applyShareWriteHook and applyShareDeleteHook, shared utilities
10
+ * called from all three write paths:
11
+ * - CloudflareDIDSpace.internalWrite (REST API)
12
+ * - DIDSpaceProvider.internalWrite (SyncEngine)
13
+ * - DIDSpaceProvider.writeHandler (AFS protocol)
14
+ *
15
+ * Separated from share-declaration.ts to avoid circular imports:
16
+ * share-hook.ts → share-resolve.ts + share-declaration.ts
17
+ * share-resolve.ts → share-declaration.ts
18
+ * share-declaration.ts → (no share deps)
19
+ */
20
+ /**
21
+ * applyShareWriteHook — called in any DID Space write path for .share files.
22
+ *
23
+ * phase="pre-io": validates BEFORE R2 PUT (dryRun=true).
24
+ * Validation failure → throws AFS error; R2/D1 not written.
25
+ *
26
+ * phase="post-io": reconciles AFTER R2 + tree_entries written (dryRun=false).
27
+ * Failure → throws AFSError (eventual consistency; R2 already written).
28
+ */
29
+ async function applyShareWriteHook(params) {
30
+ if (!params.resolver || !require_share_declaration.isShareDeclarationPath(params.afsPath)) return;
31
+ const { afsPath, treePath, bytes, cid, ownerDid, resolver, phase } = params;
32
+ if (phase === "pre-io") {
33
+ const validation = await resolver.reconcileFromDecl({
34
+ declPath: treePath,
35
+ declContent: bytes,
36
+ declCid: cid,
37
+ ownerDid,
38
+ dryRun: true
39
+ });
40
+ if (!validation.ok) throw require_share_declaration.mapShareErrorToAFSError(validation.code, validation.message, afsPath);
41
+ } else {
42
+ const result = await resolver.reconcileFromDecl({
43
+ declPath: treePath,
44
+ declContent: bytes,
45
+ declCid: cid,
46
+ ownerDid
47
+ });
48
+ if (!result.ok) throw new _aigne_afs.AFSError(`share-index-failed: ${result.code} — ${result.message}`, result.code);
49
+ }
50
+ }
51
+ /**
52
+ * applyShareDeleteHook — called in any DID Space delete path for .share files.
53
+ *
54
+ * Should be called AFTER tree_entries is deleted, to clean up shares index.
55
+ */
56
+ async function applyShareDeleteHook(params) {
57
+ if (!params.resolver || !require_share_declaration.isShareDeclarationPath(params.afsPath)) return;
58
+ await params.resolver.reconcileDelete(params.ownerDid, params.treePath);
59
+ }
60
+
61
+ //#endregion
62
+ exports.applyShareDeleteHook = applyShareDeleteHook;
63
+ exports.applyShareWriteHook = applyShareWriteHook;
@@ -0,0 +1,62 @@
1
+ import { isShareDeclarationPath, mapShareErrorToAFSError } from "./share-declaration.mjs";
2
+ import { AFSError } from "@aigne/afs";
3
+
4
+ //#region src/share-hook.ts
5
+ /**
6
+ * Phase 0.4 — Share write/delete hooks for all DID Space write paths.
7
+ *
8
+ * Provides applyShareWriteHook and applyShareDeleteHook, shared utilities
9
+ * called from all three write paths:
10
+ * - CloudflareDIDSpace.internalWrite (REST API)
11
+ * - DIDSpaceProvider.internalWrite (SyncEngine)
12
+ * - DIDSpaceProvider.writeHandler (AFS protocol)
13
+ *
14
+ * Separated from share-declaration.ts to avoid circular imports:
15
+ * share-hook.ts → share-resolve.ts + share-declaration.ts
16
+ * share-resolve.ts → share-declaration.ts
17
+ * share-declaration.ts → (no share deps)
18
+ */
19
+ /**
20
+ * applyShareWriteHook — called in any DID Space write path for .share files.
21
+ *
22
+ * phase="pre-io": validates BEFORE R2 PUT (dryRun=true).
23
+ * Validation failure → throws AFS error; R2/D1 not written.
24
+ *
25
+ * phase="post-io": reconciles AFTER R2 + tree_entries written (dryRun=false).
26
+ * Failure → throws AFSError (eventual consistency; R2 already written).
27
+ */
28
+ async function applyShareWriteHook(params) {
29
+ if (!params.resolver || !isShareDeclarationPath(params.afsPath)) return;
30
+ const { afsPath, treePath, bytes, cid, ownerDid, resolver, phase } = params;
31
+ if (phase === "pre-io") {
32
+ const validation = await resolver.reconcileFromDecl({
33
+ declPath: treePath,
34
+ declContent: bytes,
35
+ declCid: cid,
36
+ ownerDid,
37
+ dryRun: true
38
+ });
39
+ if (!validation.ok) throw mapShareErrorToAFSError(validation.code, validation.message, afsPath);
40
+ } else {
41
+ const result = await resolver.reconcileFromDecl({
42
+ declPath: treePath,
43
+ declContent: bytes,
44
+ declCid: cid,
45
+ ownerDid
46
+ });
47
+ if (!result.ok) throw new AFSError(`share-index-failed: ${result.code} — ${result.message}`, result.code);
48
+ }
49
+ }
50
+ /**
51
+ * applyShareDeleteHook — called in any DID Space delete path for .share files.
52
+ *
53
+ * Should be called AFTER tree_entries is deleted, to clean up shares index.
54
+ */
55
+ async function applyShareDeleteHook(params) {
56
+ if (!params.resolver || !isShareDeclarationPath(params.afsPath)) return;
57
+ await params.resolver.reconcileDelete(params.ownerDid, params.treePath);
58
+ }
59
+
60
+ //#endregion
61
+ export { applyShareDeleteHook, applyShareWriteHook };
62
+ //# sourceMappingURL=share-hook.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share-hook.mjs","names":[],"sources":["../src/share-hook.ts"],"sourcesContent":["/**\n * Phase 0.4 — Share write/delete hooks for all DID Space write paths.\n *\n * Provides applyShareWriteHook and applyShareDeleteHook, shared utilities\n * called from all three write paths:\n * - CloudflareDIDSpace.internalWrite (REST API)\n * - DIDSpaceProvider.internalWrite (SyncEngine)\n * - DIDSpaceProvider.writeHandler (AFS protocol)\n *\n * Separated from share-declaration.ts to avoid circular imports:\n * share-hook.ts → share-resolve.ts + share-declaration.ts\n * share-resolve.ts → share-declaration.ts\n * share-declaration.ts → (no share deps)\n */\n\nimport { AFSError } from \"@aigne/afs\";\nimport { isShareDeclarationPath, mapShareErrorToAFSError } from \"./share-declaration.js\";\nimport type { ShareResolver } from \"./share-resolve.js\";\n\n/**\n * applyShareWriteHook — called in any DID Space write path for .share files.\n *\n * phase=\"pre-io\": validates BEFORE R2 PUT (dryRun=true).\n * Validation failure → throws AFS error; R2/D1 not written.\n *\n * phase=\"post-io\": reconciles AFTER R2 + tree_entries written (dryRun=false).\n * Failure → throws AFSError (eventual consistency; R2 already written).\n */\nexport async function applyShareWriteHook(params: {\n afsPath: string;\n treePath: string;\n bytes: Uint8Array;\n cid: string;\n ownerDid: string;\n resolver: ShareResolver | undefined;\n phase: \"pre-io\" | \"post-io\";\n}): Promise<void> {\n if (!params.resolver || !isShareDeclarationPath(params.afsPath)) return;\n\n const { afsPath, treePath, bytes, cid, ownerDid, resolver, phase } = params;\n\n if (phase === \"pre-io\") {\n const validation = await resolver.reconcileFromDecl({\n declPath: treePath,\n declContent: bytes,\n declCid: cid,\n ownerDid,\n dryRun: true,\n });\n if (!validation.ok) {\n throw mapShareErrorToAFSError(validation.code, validation.message, afsPath);\n }\n } else {\n // post-io: R2 already written — best-effort D1 update\n const result = await resolver.reconcileFromDecl({\n declPath: treePath,\n declContent: bytes,\n declCid: cid,\n ownerDid,\n });\n if (!result.ok) {\n throw new AFSError(`share-index-failed: ${result.code} — ${result.message}`, result.code);\n }\n }\n}\n\n/**\n * applyShareDeleteHook — called in any DID Space delete path for .share files.\n *\n * Should be called AFTER tree_entries is deleted, to clean up shares index.\n */\nexport async function applyShareDeleteHook(params: {\n afsPath: string;\n treePath: string;\n ownerDid: string;\n resolver: ShareResolver | undefined;\n}): Promise<void> {\n if (!params.resolver || !isShareDeclarationPath(params.afsPath)) return;\n await params.resolver.reconcileDelete(params.ownerDid, params.treePath);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,eAAsB,oBAAoB,QAQxB;AAChB,KAAI,CAAC,OAAO,YAAY,CAAC,uBAAuB,OAAO,QAAQ,CAAE;CAEjE,MAAM,EAAE,SAAS,UAAU,OAAO,KAAK,UAAU,UAAU,UAAU;AAErE,KAAI,UAAU,UAAU;EACtB,MAAM,aAAa,MAAM,SAAS,kBAAkB;GAClD,UAAU;GACV,aAAa;GACb,SAAS;GACT;GACA,QAAQ;GACT,CAAC;AACF,MAAI,CAAC,WAAW,GACd,OAAM,wBAAwB,WAAW,MAAM,WAAW,SAAS,QAAQ;QAExE;EAEL,MAAM,SAAS,MAAM,SAAS,kBAAkB;GAC9C,UAAU;GACV,aAAa;GACb,SAAS;GACT;GACD,CAAC;AACF,MAAI,CAAC,OAAO,GACV,OAAM,IAAI,SAAS,uBAAuB,OAAO,KAAK,KAAK,OAAO,WAAW,OAAO,KAAK;;;;;;;;AAU/F,eAAsB,qBAAqB,QAKzB;AAChB,KAAI,CAAC,OAAO,YAAY,CAAC,uBAAuB,OAAO,QAAQ,CAAE;AACjE,OAAM,OAAO,SAAS,gBAAgB,OAAO,UAAU,OAAO,SAAS"}
@@ -0,0 +1,176 @@
1
+ const require_share_declaration = require('./share-declaration.cjs');
2
+
3
+ //#region src/share-resolve.ts
4
+ /**
5
+ * Phase 0.4 — ShareResolver: storage-agnostic share reconcile orchestrator.
6
+ *
7
+ * Holds the reconcile BUSINESS LOGIC (YAML parse + schema validation, reserved
8
+ * / forbidden / traversal path checks, sourcePath derivation, nested-share
9
+ * detection, kind auto-detection, slug determination + conflict check) and
10
+ * delegates ALL `shares` table access to an injected {@link ShareStore}. This
11
+ * mirrors the repo's `DIDSpaceResolver + KeyValueStore` precedent — one
12
+ * orchestrator, swappable backend (D1 / libsql), no adapter.
13
+ *
14
+ * Identity is owner-scoped: `(ownerDid, declPath)` is the composite key, so two
15
+ * owners that share one D1 / one daemon-global `_shares.db` never clobber each
16
+ * other (CRITICAL #1 fix). `slug` stays globally unique.
17
+ *
18
+ * Offline full rebuild (`reconcileAll`) is intentionally NOT here — see
19
+ * `D1ShareReconciler` in d1-share-store.ts (D1-only, needs an ObjectStore).
20
+ */
21
+ /** 21-character random ID using Web Crypto (base-36, no external deps). */
22
+ function generateId() {
23
+ return Array.from(crypto.getRandomValues(new Uint8Array(16)), (b) => b.toString(36).padStart(2, "0")).join("").slice(0, 21);
24
+ }
25
+ /** Paths under these prefixes are forbidden from having shares. */
26
+ const FORBIDDEN_PREFIXES = ["config/", "vault/"];
27
+ function isForbiddenPath(path) {
28
+ const p = path.startsWith("/") ? path.slice(1) : path;
29
+ return FORBIDDEN_PREFIXES.some((prefix) => p.startsWith(prefix));
30
+ }
31
+ function hasPathTraversal(path) {
32
+ return path.split("/").includes("..");
33
+ }
34
+ /** Returns true if the declPath is a sidecar (not root, not in-tree /.share). */
35
+ function isSidecarPath(declPath) {
36
+ const p = declPath.startsWith("/") ? declPath.slice(1) : declPath;
37
+ return p !== ".share" && !p.endsWith("/.share");
38
+ }
39
+ var ShareResolver = class {
40
+ constructor(store, treeIndex) {
41
+ this.store = store;
42
+ this.treeIndex = treeIndex;
43
+ }
44
+ resolveBySlug(slug) {
45
+ return this.store.resolveBySlug(slug);
46
+ }
47
+ listByOwner(ownerDid) {
48
+ return this.store.listByOwner(ownerDid);
49
+ }
50
+ listByInstance(ownerDid, instanceDid) {
51
+ return this.store.listByInstance(ownerDid, instanceDid);
52
+ }
53
+ readShare(ownerDid, slug) {
54
+ return this.store.readByOwnerAndSlug(ownerDid, slug);
55
+ }
56
+ findByOwnerAndDeclPath(ownerDid, declPath) {
57
+ return this.store.findByOwnerAndDeclPath(ownerDid, declPath);
58
+ }
59
+ async reconcileFromDecl(params) {
60
+ const { declPath, declContent, declCid, ownerDid, dryRun = false } = params;
61
+ const parsed = require_share_declaration.parseShareDeclaration(declContent);
62
+ if (!parsed.ok) return parsed;
63
+ if (require_share_declaration.isShareReservedPath(declPath)) return {
64
+ ok: false,
65
+ code: "share-path-reserved",
66
+ message: `Path is reserved and cannot have a share declaration: ${declPath}`
67
+ };
68
+ if (isForbiddenPath(declPath)) return {
69
+ ok: false,
70
+ code: "share-path-forbidden",
71
+ message: `Path prefix is forbidden for share declarations: ${declPath}`
72
+ };
73
+ if (hasPathTraversal(declPath)) return {
74
+ ok: false,
75
+ code: "share-path-forbidden",
76
+ message: `Path traversal detected in declaration path: ${declPath}`
77
+ };
78
+ const sourcePath = require_share_declaration.deriveSourcePath(declPath);
79
+ const isSidecar = isSidecarPath(declPath);
80
+ if (sourcePath !== "") {
81
+ const nested = await this.store.findNestedConflict(ownerDid, declPath, sourcePath);
82
+ if (nested) return {
83
+ ok: false,
84
+ code: "share-nested",
85
+ message: `Share declaration conflicts with ${nested}`
86
+ };
87
+ }
88
+ if (isSidecar && this.treeIndex && sourcePath) {
89
+ if (!await this.treeIndex.get(sourcePath, { includeContent: false })) return {
90
+ ok: false,
91
+ code: "share-sidecar-target-missing",
92
+ message: `Sidecar target file not found: ${sourcePath}`
93
+ };
94
+ }
95
+ let resolvedKind;
96
+ if (parsed.data.kind) {
97
+ resolvedKind = parsed.data.kind;
98
+ if (resolvedKind === "web" && this.treeIndex) {
99
+ const webPrefix = sourcePath ? `${sourcePath}/.web/` : ".web/";
100
+ const { entries } = await this.treeIndex.list(webPrefix, { limit: 1 });
101
+ if (entries.length === 0) return {
102
+ ok: false,
103
+ code: "share-web-no-decl",
104
+ message: `kind:web requires a .web/ directory at ${webPrefix}`
105
+ };
106
+ }
107
+ } else if (isSidecar) resolvedKind = "raw";
108
+ else if (this.treeIndex) {
109
+ const webPrefix = sourcePath ? `${sourcePath}/.web/` : ".web/";
110
+ const { entries } = await this.treeIndex.list(webPrefix, { limit: 1 });
111
+ resolvedKind = entries.length > 0 ? "web" : "raw";
112
+ } else resolvedKind = "raw";
113
+ const existing = await this.store.findByOwnerAndDeclPath(ownerDid, declPath);
114
+ let slug;
115
+ if (parsed.data.slug) slug = parsed.data.slug;
116
+ else if (existing) slug = existing.slug;
117
+ else slug = generateId();
118
+ if (!existing || existing.slug !== slug) {
119
+ const conflicting = await this.store.findSlugConflict(slug, ownerDid, declPath);
120
+ if (conflicting) return {
121
+ ok: false,
122
+ code: "share-slug-conflict",
123
+ message: `Slug "${slug}" is already claimed by ${conflicting}`
124
+ };
125
+ }
126
+ const now = Date.now();
127
+ const id = existing?.id ?? generateId();
128
+ const status = parsed.data.status ?? "active";
129
+ if (dryRun) return {
130
+ ok: true,
131
+ entry: {
132
+ id,
133
+ ownerDid,
134
+ sourcePath,
135
+ declPath,
136
+ slug,
137
+ kind: resolvedKind,
138
+ status,
139
+ declCid,
140
+ config: parsed.data,
141
+ createdAt: existing?.createdAt ?? now,
142
+ updatedAt: now
143
+ }
144
+ };
145
+ const row = {
146
+ id,
147
+ owner_did: ownerDid,
148
+ source_path: sourcePath,
149
+ decl_path: declPath,
150
+ slug,
151
+ kind: resolvedKind,
152
+ status,
153
+ decl_cid: declCid,
154
+ config_json: JSON.stringify(parsed.data),
155
+ created_at: existing?.createdAt ?? now,
156
+ updated_at: now
157
+ };
158
+ await this.store.upsert(row);
159
+ const final = await this.store.findByOwnerAndDeclPath(ownerDid, declPath);
160
+ if (!final) return {
161
+ ok: false,
162
+ code: "share-internal-error",
163
+ message: "Failed to read back the upserted share row"
164
+ };
165
+ return {
166
+ ok: true,
167
+ entry: final
168
+ };
169
+ }
170
+ reconcileDelete(ownerDid, declPath) {
171
+ return this.store.deleteByOwnerAndDeclPath(ownerDid, declPath);
172
+ }
173
+ };
174
+
175
+ //#endregion
176
+ exports.ShareResolver = ShareResolver;
@@ -0,0 +1,36 @@
1
+ import { ShareEntry, ShareStore } from "./share-store.cjs";
2
+ import { TreeIndex } from "./tree-index.cjs";
3
+
4
+ //#region src/share-resolve.d.ts
5
+ type ReconcileOk = {
6
+ ok: true;
7
+ entry: ShareEntry;
8
+ };
9
+ type ReconcileFail = {
10
+ ok: false;
11
+ code: string;
12
+ message: string;
13
+ detail?: unknown;
14
+ };
15
+ type ReconcileResult = ReconcileOk | ReconcileFail;
16
+ declare class ShareResolver {
17
+ private store;
18
+ private treeIndex?;
19
+ constructor(store: ShareStore, treeIndex?: TreeIndex | undefined);
20
+ resolveBySlug(slug: string): Promise<ShareEntry | null>;
21
+ listByOwner(ownerDid: string): Promise<ShareEntry[]>;
22
+ listByInstance(ownerDid: string, instanceDid: string): Promise<ShareEntry[]>;
23
+ readShare(ownerDid: string, slug: string): Promise<ShareEntry | null>;
24
+ findByOwnerAndDeclPath(ownerDid: string, declPath: string): Promise<ShareEntry | null>;
25
+ reconcileFromDecl(params: {
26
+ declPath: string;
27
+ declContent: Uint8Array;
28
+ declCid: string;
29
+ ownerDid: string;
30
+ dryRun?: boolean;
31
+ }): Promise<ReconcileResult>;
32
+ reconcileDelete(ownerDid: string, declPath: string): Promise<void>;
33
+ }
34
+ //#endregion
35
+ export { ShareResolver };
36
+ //# sourceMappingURL=share-resolve.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share-resolve.d.cts","names":[],"sources":["../src/share-resolve.ts"],"mappings":";;;;KAyDK,WAAA;EAAgB,EAAA;EAAU,KAAA,EAAO,UAAA;AAAA;AAAA,KACjC,aAAA;EAAkB,EAAA;EAAW,IAAA;EAAc,OAAA;EAAiB,MAAA;AAAA;AAAA,KAC5D,eAAA,GAAkB,WAAA,GAAc,aAAA;AAAA,cAIxB,aAAA;EAAA,QAED,KAAA;EAAA,QAMA,SAAA;cANA,KAAA,EAAO,UAAA,EAMP,SAAA,GAAY,SAAA;EAKtB,aAAA,CAAc,IAAA,WAAe,OAAA,CAAQ,UAAA;EAMrC,WAAA,CAAY,QAAA,WAAmB,OAAA,CAAQ,UAAA;EAIvC,cAAA,CAAe,QAAA,UAAkB,WAAA,WAAsB,OAAA,CAAQ,UAAA;EAI/D,SAAA,CAAU,QAAA,UAAkB,IAAA,WAAe,OAAA,CAAQ,UAAA;EAInD,sBAAA,CAAuB,QAAA,UAAkB,QAAA,WAAmB,OAAA,CAAQ,UAAA;EAM9D,iBAAA,CAAkB,MAAA;IACtB,QAAA;IACA,WAAA,EAAa,UAAA;IACb,OAAA;IACA,QAAA;IACA,MAAA;EAAA,IACE,OAAA,CAAQ,eAAA;EAyKZ,eAAA,CAAgB,QAAA,UAAkB,QAAA,WAAmB,OAAA;AAAA"}
@@ -0,0 +1,36 @@
1
+ import { ShareEntry, ShareStore } from "./share-store.mjs";
2
+ import { TreeIndex } from "./tree-index.mjs";
3
+
4
+ //#region src/share-resolve.d.ts
5
+ type ReconcileOk = {
6
+ ok: true;
7
+ entry: ShareEntry;
8
+ };
9
+ type ReconcileFail = {
10
+ ok: false;
11
+ code: string;
12
+ message: string;
13
+ detail?: unknown;
14
+ };
15
+ type ReconcileResult = ReconcileOk | ReconcileFail;
16
+ declare class ShareResolver {
17
+ private store;
18
+ private treeIndex?;
19
+ constructor(store: ShareStore, treeIndex?: TreeIndex | undefined);
20
+ resolveBySlug(slug: string): Promise<ShareEntry | null>;
21
+ listByOwner(ownerDid: string): Promise<ShareEntry[]>;
22
+ listByInstance(ownerDid: string, instanceDid: string): Promise<ShareEntry[]>;
23
+ readShare(ownerDid: string, slug: string): Promise<ShareEntry | null>;
24
+ findByOwnerAndDeclPath(ownerDid: string, declPath: string): Promise<ShareEntry | null>;
25
+ reconcileFromDecl(params: {
26
+ declPath: string;
27
+ declContent: Uint8Array;
28
+ declCid: string;
29
+ ownerDid: string;
30
+ dryRun?: boolean;
31
+ }): Promise<ReconcileResult>;
32
+ reconcileDelete(ownerDid: string, declPath: string): Promise<void>;
33
+ }
34
+ //#endregion
35
+ export { ShareResolver };
36
+ //# sourceMappingURL=share-resolve.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share-resolve.d.mts","names":[],"sources":["../src/share-resolve.ts"],"mappings":";;;;KAyDK,WAAA;EAAgB,EAAA;EAAU,KAAA,EAAO,UAAA;AAAA;AAAA,KACjC,aAAA;EAAkB,EAAA;EAAW,IAAA;EAAc,OAAA;EAAiB,MAAA;AAAA;AAAA,KAC5D,eAAA,GAAkB,WAAA,GAAc,aAAA;AAAA,cAIxB,aAAA;EAAA,QAED,KAAA;EAAA,QAMA,SAAA;cANA,KAAA,EAAO,UAAA,EAMP,SAAA,GAAY,SAAA;EAKtB,aAAA,CAAc,IAAA,WAAe,OAAA,CAAQ,UAAA;EAMrC,WAAA,CAAY,QAAA,WAAmB,OAAA,CAAQ,UAAA;EAIvC,cAAA,CAAe,QAAA,UAAkB,WAAA,WAAsB,OAAA,CAAQ,UAAA;EAI/D,SAAA,CAAU,QAAA,UAAkB,IAAA,WAAe,OAAA,CAAQ,UAAA;EAInD,sBAAA,CAAuB,QAAA,UAAkB,QAAA,WAAmB,OAAA,CAAQ,UAAA;EAM9D,iBAAA,CAAkB,MAAA;IACtB,QAAA;IACA,WAAA,EAAa,UAAA;IACb,OAAA;IACA,QAAA;IACA,MAAA;EAAA,IACE,OAAA,CAAQ,eAAA;EAyKZ,eAAA,CAAgB,QAAA,UAAkB,QAAA,WAAmB,OAAA;AAAA"}