fundus 0.0.4 → 0.2.0

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 (224) hide show
  1. package/README.md +49 -8
  2. package/build/client/_app/immutable/assets/0.inkPq3ni.css +1 -0
  3. package/build/client/_app/immutable/assets/0.inkPq3ni.css.br +0 -0
  4. package/build/client/_app/immutable/assets/0.inkPq3ni.css.gz +0 -0
  5. package/build/client/_app/immutable/assets/3.ChSpCG-T.css +1 -0
  6. package/build/client/_app/immutable/assets/3.ChSpCG-T.css.br +0 -0
  7. package/build/client/_app/immutable/assets/3.ChSpCG-T.css.gz +0 -0
  8. package/build/client/_app/immutable/assets/{LibraryContextMenu.CMefGNE2.css → LibraryContextMenu.BYvU4SY7.css} +1 -1
  9. package/build/client/_app/immutable/assets/LibraryContextMenu.BYvU4SY7.css.br +0 -0
  10. package/build/client/_app/immutable/assets/LibraryContextMenu.BYvU4SY7.css.gz +0 -0
  11. package/build/client/_app/immutable/assets/ManifestSelector.Il8p28r8.css +1 -0
  12. package/build/client/_app/immutable/assets/ManifestSelector.Il8p28r8.css.br +0 -0
  13. package/build/client/_app/immutable/assets/ManifestSelector.Il8p28r8.css.gz +0 -0
  14. package/build/client/_app/immutable/chunks/BAEZPv6c.js +1 -0
  15. package/build/client/_app/immutable/chunks/BAEZPv6c.js.br +0 -0
  16. package/build/client/_app/immutable/chunks/BAEZPv6c.js.gz +0 -0
  17. package/build/client/_app/immutable/chunks/{DVEQFclp.js → ByVSyIj7.js} +1 -1
  18. package/build/client/_app/immutable/chunks/ByVSyIj7.js.br +1 -0
  19. package/build/client/_app/immutable/chunks/ByVSyIj7.js.gz +0 -0
  20. package/build/client/_app/immutable/chunks/C8W3KwDq.js +1 -0
  21. package/build/client/_app/immutable/chunks/C8W3KwDq.js.br +0 -0
  22. package/build/client/_app/immutable/chunks/C8W3KwDq.js.gz +0 -0
  23. package/build/client/_app/immutable/chunks/CP-bnOxU.js +1 -0
  24. package/build/client/_app/immutable/chunks/CP-bnOxU.js.br +0 -0
  25. package/build/client/_app/immutable/chunks/CP-bnOxU.js.gz +0 -0
  26. package/build/client/_app/immutable/chunks/{CNRz3sSw.js → D65cSBhe.js} +2 -2
  27. package/build/client/_app/immutable/chunks/D65cSBhe.js.br +0 -0
  28. package/build/client/_app/immutable/chunks/D65cSBhe.js.gz +0 -0
  29. package/build/client/_app/immutable/chunks/Db8LRH6X.js +108 -0
  30. package/build/client/_app/immutable/chunks/Db8LRH6X.js.br +0 -0
  31. package/build/client/_app/immutable/chunks/Db8LRH6X.js.gz +0 -0
  32. package/build/client/_app/immutable/chunks/TZFh8bT7.js +1 -0
  33. package/build/client/_app/immutable/chunks/TZFh8bT7.js.br +0 -0
  34. package/build/client/_app/immutable/chunks/TZFh8bT7.js.gz +0 -0
  35. package/build/client/_app/immutable/entry/app.nM6SgHKJ.js +2 -0
  36. package/build/client/_app/immutable/entry/app.nM6SgHKJ.js.br +0 -0
  37. package/build/client/_app/immutable/entry/app.nM6SgHKJ.js.gz +0 -0
  38. package/build/client/_app/immutable/entry/start.DNXvkhtP.js +1 -0
  39. package/build/client/_app/immutable/entry/start.DNXvkhtP.js.br +0 -0
  40. package/build/client/_app/immutable/entry/start.DNXvkhtP.js.gz +0 -0
  41. package/build/client/_app/immutable/nodes/0.QeXQNCp2.js +2 -0
  42. package/build/client/_app/immutable/nodes/0.QeXQNCp2.js.br +0 -0
  43. package/build/client/_app/immutable/nodes/0.QeXQNCp2.js.gz +0 -0
  44. package/build/client/_app/immutable/nodes/1.dMklHTc2.js +1 -0
  45. package/build/client/_app/immutable/nodes/1.dMklHTc2.js.br +0 -0
  46. package/build/client/_app/immutable/nodes/1.dMklHTc2.js.gz +0 -0
  47. package/build/client/_app/immutable/nodes/2.CW4VMcIP.js +3 -0
  48. package/build/client/_app/immutable/nodes/2.CW4VMcIP.js.br +0 -0
  49. package/build/client/_app/immutable/nodes/2.CW4VMcIP.js.gz +0 -0
  50. package/build/client/_app/immutable/nodes/3.CTiY_pbK.js +1 -0
  51. package/build/client/_app/immutable/nodes/3.CTiY_pbK.js.br +0 -0
  52. package/build/client/_app/immutable/nodes/3.CTiY_pbK.js.gz +0 -0
  53. package/build/client/_app/immutable/nodes/4.Dgxx52FJ.js +2 -0
  54. package/build/client/_app/immutable/nodes/4.Dgxx52FJ.js.br +0 -0
  55. package/build/client/_app/immutable/nodes/4.Dgxx52FJ.js.gz +0 -0
  56. package/build/client/_app/version.json +1 -1
  57. package/build/client/_app/version.json.br +0 -0
  58. package/build/client/_app/version.json.gz +0 -0
  59. package/build/client/favicon.svg +4 -0
  60. package/build/client/favicon.svg.br +0 -0
  61. package/build/client/favicon.svg.gz +0 -0
  62. package/build/handler.js +7 -7
  63. package/build/index.js +7 -7
  64. package/build/server/chunks/chunks/{context.js-BUZqFfWG.js → context.js-B77ZAVLi.js} +405 -31
  65. package/build/server/chunks/chunks/context.js-B77ZAVLi.js.map +1 -0
  66. package/build/server/chunks/chunks/{core.js-xfrkaQpS.js → core.js-EA_ysb1J.js} +130 -3
  67. package/build/server/chunks/chunks/core.js-EA_ysb1J.js.map +1 -0
  68. package/build/server/chunks/chunks/{exports.js-C0rwMMtk.js → exports.js-DvhE7Ffd.js} +2 -2
  69. package/build/server/chunks/chunks/{exports.js-C0rwMMtk.js.map → exports.js-DvhE7Ffd.js.map} +1 -1
  70. package/build/server/chunks/chunks/{http.js-DvopzwKh.js → http.js-DyoR9XRI.js} +5 -3
  71. package/build/server/chunks/chunks/http.js-DyoR9XRI.js.map +1 -0
  72. package/build/server/chunks/chunks/{internal.js-DGo2jPcg.js → internal.js-Dn37LrAW.js} +4 -4
  73. package/build/server/chunks/chunks/{internal.js-DGo2jPcg.js.map → internal.js-Dn37LrAW.js.map} +1 -1
  74. package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
  75. package/build/server/chunks/chunks/{library-store.js-ZLudCJlT.js → library-store.js-DJ-JRE-g.js} +388 -20
  76. package/build/server/chunks/chunks/library-store.js-DJ-JRE-g.js.map +1 -0
  77. package/build/server/chunks/chunks/{shared.js-B1gC9MiJ.js → shared.js-Dob0TlTu.js} +2 -2
  78. package/build/server/chunks/chunks/{shared.js-B1gC9MiJ.js.map → shared.js-Dob0TlTu.js.map} +1 -1
  79. package/build/server/chunks/chunks/{utils.js-DnEJ3UjO.js → utils.js-B4YimMxv.js} +3 -3
  80. package/build/server/chunks/chunks/{utils.js-DnEJ3UjO.js.map → utils.js-B4YimMxv.js.map} +1 -1
  81. package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-Cq5gXVQT.js → _server.ts.js-H4Pq1KAE.js} +4 -5
  82. package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-Cq5gXVQT.js.map → _server.ts.js-H4Pq1KAE.js.map} +1 -1
  83. package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-RXbedi8q.js → _server.ts.js-BI3KHSfE.js} +5 -6
  84. package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-RXbedi8q.js.map → _server.ts.js-BI3KHSfE.js.map} +1 -1
  85. package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/_server.ts.js-BlNYUbXX.js +34 -0
  86. package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/_server.ts.js-BlNYUbXX.js.map +1 -0
  87. package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-D7Qae9vU.js → _server.ts.js-j-_N540j.js} +9 -7
  88. package/build/server/chunks/entries/endpoints/api/assets/_server.ts.js-j-_N540j.js.map +1 -0
  89. package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-DtO20kgB.js → _server.ts.js-BHKobzAg.js} +5 -6
  90. package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-DtO20kgB.js.map → _server.ts.js-BHKobzAg.js.map} +1 -1
  91. package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-BUebPbd5.js → _server.ts.js-BFKjIOCv.js} +5 -6
  92. package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-BUebPbd5.js.map → _server.ts.js-BFKjIOCv.js.map} +1 -1
  93. package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-BjT2qPMT.js → _server.ts.js-BxZeVw8y.js} +5 -6
  94. package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-BjT2qPMT.js.map → _server.ts.js-BxZeVw8y.js.map} +1 -1
  95. package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-DYRLsoT7.js → _server.ts.js-CO36U_CT.js} +5 -6
  96. package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-DYRLsoT7.js.map → _server.ts.js-CO36U_CT.js.map} +1 -1
  97. package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-BbN2fGNN.js → _server.ts.js-CBlg1Bkl.js} +5 -6
  98. package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-BbN2fGNN.js.map → _server.ts.js-CBlg1Bkl.js.map} +1 -1
  99. package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-b_MKZ41b.js → _server.ts.js-DcGLCjIs.js} +5 -6
  100. package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-b_MKZ41b.js.map → _server.ts.js-DcGLCjIs.js.map} +1 -1
  101. package/build/server/chunks/entries/endpoints/api/raw/adopt/_server.ts.js-AqhtjOiL.js +32 -0
  102. package/build/server/chunks/entries/endpoints/api/raw/adopt/_server.ts.js-AqhtjOiL.js.map +1 -0
  103. package/build/server/chunks/entries/endpoints/api/raw/edited/accept/_server.ts.js-CSa6-DcU.js +30 -0
  104. package/build/server/chunks/entries/endpoints/api/raw/edited/accept/_server.ts.js-CSa6-DcU.js.map +1 -0
  105. package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/_server.ts.js-DnzZUoAo.js +30 -0
  106. package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/_server.ts.js-DnzZUoAo.js.map +1 -0
  107. package/build/server/chunks/entries/endpoints/api/reconcile/_server.ts.js-B0KMprKq.js +33 -0
  108. package/build/server/chunks/entries/endpoints/api/reconcile/_server.ts.js-B0KMprKq.js.map +1 -0
  109. package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-evEfMpvn.js → _server.ts.js-B1N9o1Ne.js} +5 -6
  110. package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-evEfMpvn.js.map → _server.ts.js-B1N9o1Ne.js.map} +1 -1
  111. package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-C04XE_1w.js → _server.ts.js-B6HbnRqq.js} +4 -5
  112. package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-C04XE_1w.js.map → _server.ts.js-B6HbnRqq.js.map} +1 -1
  113. package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-DB8TdoEv.js → _server.ts.js-7wzPyG9v.js} +5 -6
  114. package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-DB8TdoEv.js.map → _server.ts.js-7wzPyG9v.js.map} +1 -1
  115. package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-BrpaijZO.js → _server.ts.js-BWztxYge.js} +5 -6
  116. package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-BrpaijZO.js.map → _server.ts.js-BWztxYge.js.map} +1 -1
  117. package/build/server/chunks/entries/{hooks.server.js-BJJwZW_I.js → hooks.server.js-CVKLksJ1.js} +4 -5
  118. package/build/server/chunks/entries/{hooks.server.js-BJJwZW_I.js.map → hooks.server.js-CVKLksJ1.js.map} +1 -1
  119. package/build/server/chunks/{handler-DnbS2t1B.js → handler-DZ2Sps4a.js} +5 -5
  120. package/build/server/chunks/{handler-DnbS2t1B.js.map → handler-DZ2Sps4a.js.map} +1 -1
  121. package/build/server/chunks/{index.js-g77q3Boj.js → index.js-CdmTWQz8.js} +5 -5
  122. package/build/server/chunks/{index.js-g77q3Boj.js.map → index.js-CdmTWQz8.js.map} +1 -1
  123. package/build/server/chunks/{manifest.js-qmEXbstS.js → manifest.js-GhfNr35x.js} +57 -22
  124. package/build/server/chunks/manifest.js-GhfNr35x.js.map +1 -0
  125. package/build/server/chunks/nodes/0.js-DGT86_i-.js +11 -0
  126. package/build/server/chunks/nodes/0.js-DGT86_i-.js.map +1 -0
  127. package/build/server/chunks/nodes/1.js-DQgYreU0.js +7 -0
  128. package/build/server/chunks/nodes/{1.js-H-qwo4GJ.js.map → 1.js-DQgYreU0.js.map} +1 -1
  129. package/build/server/chunks/nodes/2.js-DItreSrX.js +7 -0
  130. package/build/server/chunks/nodes/2.js-DItreSrX.js.map +1 -0
  131. package/build/server/chunks/nodes/3.js-bE1dJ_6v.js +7 -0
  132. package/build/server/chunks/nodes/3.js-bE1dJ_6v.js.map +1 -0
  133. package/build/server/chunks/nodes/4.js-BebbMVXy.js +7 -0
  134. package/build/server/chunks/nodes/{4.js-BKL7LSSm.js.map → 4.js-BebbMVXy.js.map} +1 -1
  135. package/dist/cli.js +32 -9
  136. package/dist/core/api-types.d.ts +39 -1
  137. package/dist/core/index.d.ts +3 -2
  138. package/dist/core/index.js +2 -1
  139. package/dist/core/ingest.d.ts +2 -0
  140. package/dist/core/ingest.js +7 -0
  141. package/dist/core/raw-path.d.ts +8 -0
  142. package/dist/core/raw-path.js +63 -0
  143. package/dist/server/build.js +11 -2
  144. package/dist/server/check.d.ts +5 -1
  145. package/dist/server/check.js +80 -28
  146. package/dist/server/cli-commands.d.ts +3 -2
  147. package/dist/server/cli-commands.js +47 -4
  148. package/dist/server/cli-init.d.ts +1 -1
  149. package/dist/server/cli-init.js +38 -5
  150. package/dist/server/http.js +5 -1
  151. package/dist/server/index.d.ts +1 -1
  152. package/dist/server/library-store.d.ts +23 -0
  153. package/dist/server/library-store.js +82 -14
  154. package/dist/server/operations.d.ts +12 -2
  155. package/dist/server/operations.js +391 -31
  156. package/dist/server/processing/processor.js +3 -0
  157. package/dist/server/raw-reconciliation.d.ts +53 -0
  158. package/dist/server/raw-reconciliation.js +338 -0
  159. package/dist/server/raw-safety.d.ts +10 -0
  160. package/dist/server/raw-safety.js +73 -0
  161. package/dist/server/start.d.ts +4 -2
  162. package/dist/server/start.js +43 -11
  163. package/package.json +1 -1
  164. package/build/client/_app/immutable/assets/0.DLhIsYA_.css +0 -1
  165. package/build/client/_app/immutable/assets/0.DLhIsYA_.css.br +0 -0
  166. package/build/client/_app/immutable/assets/0.DLhIsYA_.css.gz +0 -0
  167. package/build/client/_app/immutable/assets/3.JwgtcTEd.css +0 -1
  168. package/build/client/_app/immutable/assets/3.JwgtcTEd.css.br +0 -0
  169. package/build/client/_app/immutable/assets/3.JwgtcTEd.css.gz +0 -0
  170. package/build/client/_app/immutable/assets/LibraryContextMenu.CMefGNE2.css.br +0 -0
  171. package/build/client/_app/immutable/assets/LibraryContextMenu.CMefGNE2.css.gz +0 -0
  172. package/build/client/_app/immutable/chunks/CNRz3sSw.js.br +0 -0
  173. package/build/client/_app/immutable/chunks/CNRz3sSw.js.gz +0 -0
  174. package/build/client/_app/immutable/chunks/CO4RBJfa.js +0 -1
  175. package/build/client/_app/immutable/chunks/CO4RBJfa.js.br +0 -0
  176. package/build/client/_app/immutable/chunks/CO4RBJfa.js.gz +0 -0
  177. package/build/client/_app/immutable/chunks/DOpBpjxS.js +0 -108
  178. package/build/client/_app/immutable/chunks/DOpBpjxS.js.br +0 -0
  179. package/build/client/_app/immutable/chunks/DOpBpjxS.js.gz +0 -0
  180. package/build/client/_app/immutable/chunks/DVEQFclp.js.br +0 -1
  181. package/build/client/_app/immutable/chunks/DVEQFclp.js.gz +0 -0
  182. package/build/client/_app/immutable/chunks/DiFoWL2c.js +0 -1
  183. package/build/client/_app/immutable/chunks/DiFoWL2c.js.br +0 -0
  184. package/build/client/_app/immutable/chunks/DiFoWL2c.js.gz +0 -0
  185. package/build/client/_app/immutable/chunks/DkADHpZF.js +0 -1
  186. package/build/client/_app/immutable/chunks/DkADHpZF.js.br +0 -0
  187. package/build/client/_app/immutable/chunks/DkADHpZF.js.gz +0 -0
  188. package/build/client/_app/immutable/entry/app.CKgtYXQb.js +0 -2
  189. package/build/client/_app/immutable/entry/app.CKgtYXQb.js.br +0 -0
  190. package/build/client/_app/immutable/entry/app.CKgtYXQb.js.gz +0 -0
  191. package/build/client/_app/immutable/entry/start.CYZu5qE1.js +0 -1
  192. package/build/client/_app/immutable/entry/start.CYZu5qE1.js.br +0 -0
  193. package/build/client/_app/immutable/entry/start.CYZu5qE1.js.gz +0 -0
  194. package/build/client/_app/immutable/nodes/0.I_1SApYQ.js +0 -2
  195. package/build/client/_app/immutable/nodes/0.I_1SApYQ.js.br +0 -0
  196. package/build/client/_app/immutable/nodes/0.I_1SApYQ.js.gz +0 -0
  197. package/build/client/_app/immutable/nodes/1.v6eUTnWq.js +0 -1
  198. package/build/client/_app/immutable/nodes/1.v6eUTnWq.js.br +0 -2
  199. package/build/client/_app/immutable/nodes/1.v6eUTnWq.js.gz +0 -0
  200. package/build/client/_app/immutable/nodes/2.DoA7Dfl-.js +0 -3
  201. package/build/client/_app/immutable/nodes/2.DoA7Dfl-.js.br +0 -0
  202. package/build/client/_app/immutable/nodes/2.DoA7Dfl-.js.gz +0 -0
  203. package/build/client/_app/immutable/nodes/3.C-DO70Bs.js +0 -1
  204. package/build/client/_app/immutable/nodes/3.C-DO70Bs.js.br +0 -0
  205. package/build/client/_app/immutable/nodes/3.C-DO70Bs.js.gz +0 -0
  206. package/build/client/_app/immutable/nodes/4.CALOuSyz.js +0 -2
  207. package/build/client/_app/immutable/nodes/4.CALOuSyz.js.br +0 -0
  208. package/build/client/_app/immutable/nodes/4.CALOuSyz.js.gz +0 -0
  209. package/build/server/chunks/chunks/context.js-BUZqFfWG.js.map +0 -1
  210. package/build/server/chunks/chunks/core.js-xfrkaQpS.js.map +0 -1
  211. package/build/server/chunks/chunks/folder-path.js-ytx9ucgg.js +0 -64
  212. package/build/server/chunks/chunks/folder-path.js-ytx9ucgg.js.map +0 -1
  213. package/build/server/chunks/chunks/http.js-DvopzwKh.js.map +0 -1
  214. package/build/server/chunks/chunks/library-store.js-ZLudCJlT.js.map +0 -1
  215. package/build/server/chunks/entries/endpoints/api/assets/_server.ts.js-D7Qae9vU.js.map +0 -1
  216. package/build/server/chunks/manifest.js-qmEXbstS.js.map +0 -1
  217. package/build/server/chunks/nodes/0.js-Bk6IZ-vD.js +0 -11
  218. package/build/server/chunks/nodes/0.js-Bk6IZ-vD.js.map +0 -1
  219. package/build/server/chunks/nodes/1.js-H-qwo4GJ.js +0 -7
  220. package/build/server/chunks/nodes/2.js-DRpXVLwp.js +0 -7
  221. package/build/server/chunks/nodes/2.js-DRpXVLwp.js.map +0 -1
  222. package/build/server/chunks/nodes/3.js-CDEzNFeU.js +0 -7
  223. package/build/server/chunks/nodes/3.js-CDEzNFeU.js.map +0 -1
  224. package/build/server/chunks/nodes/4.js-BKL7LSSm.js +0 -7
@@ -1 +1 @@
1
- {"version":3,"file":"internal2.js-BlXt2rfE.js","sources":["../../../../.svelte-kit/output/server/chunks/internal2.js"],"sourcesContent":["//#region node_modules/@sveltejs/kit/src/runtime/app/paths/internal/server.js\nvar base = \"\";\nvar assets = base;\nvar app_dir = \"_app\";\nvar initial = {\n\tbase,\n\tassets\n};\n/**\n* `base` could be overridden during rendering to be relative;\n* this one's the original non-relative base path\n*/\nvar initial_base = initial.base;\n/**\n* @param {{ base: string, assets: string }} paths\n*/\nfunction override(paths) {\n\tbase = paths.base;\n\tassets = paths.assets;\n}\nfunction reset() {\n\tbase = initial.base;\n\tassets = initial.assets;\n}\n/** @param {string} path */\nfunction set_assets(path) {\n\tassets = initial.assets = path;\n}\n//#endregion\n//#region node_modules/@sveltejs/kit/src/runtime/app/env/internal.js\nvar version = \"1783982340628\";\nvar prerendering = false;\nfunction set_building() {}\nfunction set_prerendering() {\n\tprerendering = true;\n}\n//#endregion\nexport { app_dir as a, initial_base as c, set_assets as d, version as i, override as l, set_building as n, assets as o, set_prerendering as r, base as s, prerendering as t, reset as u };\n"],"names":[],"mappings":"AAAA;AACG,IAAC,IAAI,GAAG;AACR,IAAC,MAAM,GAAG;AACV,IAAC,OAAO,GAAG;AACd,IAAI,OAAO,GAAG;AACd,CAAC,IAAI;AACL,CAAC;AACD,CAAC;AAMD;AACA;AACA;AACA,SAAS,QAAQ,CAAC,KAAK,EAAE;AACzB,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AAClB,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;AACtB;AACA,SAAS,KAAK,GAAG;AACjB,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI;AACpB,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM;AACxB;;;;"}
1
+ {"version":3,"file":"internal2.js-BlXt2rfE.js","sources":["../../../../.svelte-kit/output/server/chunks/internal2.js"],"sourcesContent":["//#region node_modules/@sveltejs/kit/src/runtime/app/paths/internal/server.js\nvar base = \"\";\nvar assets = base;\nvar app_dir = \"_app\";\nvar initial = {\n\tbase,\n\tassets\n};\n/**\n* `base` could be overridden during rendering to be relative;\n* this one's the original non-relative base path\n*/\nvar initial_base = initial.base;\n/**\n* @param {{ base: string, assets: string }} paths\n*/\nfunction override(paths) {\n\tbase = paths.base;\n\tassets = paths.assets;\n}\nfunction reset() {\n\tbase = initial.base;\n\tassets = initial.assets;\n}\n/** @param {string} path */\nfunction set_assets(path) {\n\tassets = initial.assets = path;\n}\n//#endregion\n//#region node_modules/@sveltejs/kit/src/runtime/app/env/internal.js\nvar version = \"1784103096725\";\nvar prerendering = false;\nfunction set_building() {}\nfunction set_prerendering() {\n\tprerendering = true;\n}\n//#endregion\nexport { app_dir as a, initial_base as c, set_assets as d, version as i, override as l, set_building as n, assets as o, set_prerendering as r, base as s, prerendering as t, reset as u };\n"],"names":[],"mappings":"AAAA;AACG,IAAC,IAAI,GAAG;AACR,IAAC,MAAM,GAAG;AACV,IAAC,OAAO,GAAG;AACd,IAAI,OAAO,GAAG;AACd,CAAC,IAAI;AACL,CAAC;AACD,CAAC;AAMD;AACA;AACA;AACA,SAAS,QAAQ,CAAC,KAAK,EAAE;AACzB,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AAClB,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;AACtB;AACA,SAAS,KAAK,GAAG;AACjB,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI;AACpB,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM;AACxB;;;;"}
@@ -1,9 +1,8 @@
1
- import { p as plugins, a as audioPlugin, c as chromaKeyVideoPlugin, v as videoPlugin, s as slicePlugin, i as imagePlugin, b as assetIdError, d as defaultInsetsForSize, m as manifestNameError, e as isAssetReference, f as validateVideoPreset, V as VIDEO_BUILT_IN_PRESETS, g as validateAudioPreset, A as AUDIO_BUILT_IN_PRESETS, h as validateImagePreset, I as IMAGE_BUILT_IN_PRESETS, S as SLICE_BUILT_IN_PRESETS } from './core.js-xfrkaQpS.js';
2
- import { n as normalizeFolderPath, f as folderOfRawPath, r as rawFileNameOfPath, a as folderPathError, p as parentFolderPath, b as folderNameError, j as joinFolderPath, c as folderNameOf, i as isFolderOrDescendant, d as replaceFolderPrefix, e as portableFolderPathKey, F as FOLDER_SENTINEL } from './folder-path.js-ytx9ucgg.js';
1
+ import { p as plugins, a as audioPlugin, c as chromaKeyVideoPlugin, v as videoPlugin, s as slicePlugin, i as imagePlugin, b as assetIdError, n as normalizeFolderPath, f as folderOfRawPath, r as rawFileNameOfPath, d as folderPathError, e as parentFolderPath, g as folderNameError, j as joinFolderPath, h as folderNameOf, k as isFolderOrDescendant, l as replaceFolderPrefix, m as portableFolderPathKey, o as defaultInsetsForSize, q as manifestNameError, F as FOLDER_SENTINEL, t as rawFilePathError, u as portableRawPathKey, w as isFundusTransactionName, x as isAssetReference, y as validateVideoPreset, V as VIDEO_BUILT_IN_PRESETS, z as validateAudioPreset, A as AUDIO_BUILT_IN_PRESETS, B as validateImagePreset, I as IMAGE_BUILT_IN_PRESETS, S as SLICE_BUILT_IN_PRESETS } from './core.js-EA_ysb1J.js';
3
2
  import { m as manifestColorError, a as manifestEmojiError } from './manifest-appearance.js-DTk355LQ.js';
4
3
  import { join, extname, dirname, basename, isAbsolute, resolve } from 'node:path';
5
- import { existsSync } from 'node:fs';
6
- import { readFile, mkdir, writeFile, rename, rm, unlink, stat, readdir } from 'node:fs/promises';
4
+ import { existsSync, constants } from 'node:fs';
5
+ import { readFile, mkdir, writeFile, rename, unlink, rm, stat, readdir, open, lstat } from 'node:fs/promises';
7
6
  import ffmpegStaticPath from 'ffmpeg-static';
8
7
  import { path } from 'ffprobe-static';
9
8
  import { execFile } from 'node:child_process';
@@ -1004,6 +1003,310 @@ function encodeRelativePathForUrl(path) {
1004
1003
  return path.split("/").map(encodeURIComponent).join("/");
1005
1004
  }
1006
1005
  //#endregion
1006
+ //#region src/lib/server/raw-reconciliation.ts
1007
+ function objectIdentity(value) {
1008
+ return `${value.dev}:${value.ino}:${value.mode}`;
1009
+ }
1010
+ function fileIdentity(value) {
1011
+ return `${objectIdentity(value)}:${value.size}:${value.mtimeNs}:${value.ctimeNs}`;
1012
+ }
1013
+ function pathMatchesHandle(pathStat, handleStat) {
1014
+ return pathStat.isFile() && objectIdentity(pathStat) === objectIdentity(handleStat);
1015
+ }
1016
+ /** Hash one regular file without following its final path component. */
1017
+ async function stableRawFileHash(path) {
1018
+ let lastProblem;
1019
+ for (let attempt = 0; attempt < 3; attempt++) try {
1020
+ const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
1021
+ try {
1022
+ const before = await handle.stat({ bigint: true });
1023
+ const pathBefore = await lstat(path, { bigint: true });
1024
+ if (!before.isFile() || !pathMatchesHandle(pathBefore, before)) throw new Error("path is not the opened regular file");
1025
+ const hash = createHash("sha256");
1026
+ for await (const chunk of handle.createReadStream({ autoClose: false })) hash.update(chunk);
1027
+ const after = await handle.stat({ bigint: true });
1028
+ const pathAfter = await lstat(path, { bigint: true });
1029
+ if (fileIdentity(before) === fileIdentity(after) && pathMatchesHandle(pathAfter, after)) return hash.digest("hex");
1030
+ lastProblem = /* @__PURE__ */ new Error("changed while it was being hashed");
1031
+ } finally {
1032
+ await handle.close().catch(() => {});
1033
+ }
1034
+ } catch (cause) {
1035
+ lastProblem = cause;
1036
+ }
1037
+ throw lastProblem instanceof Error ? lastProblem : new Error(String(lastProblem));
1038
+ }
1039
+ async function verifyStableRawFile(path, expectedHash) {
1040
+ const actualHash = await stableRawFileHash(path);
1041
+ if (actualHash !== expectedHash) throw new Error(`Raw source changed (expected ${expectedHash}, found ${actualHash}).`);
1042
+ }
1043
+ /** Enumerate without following symlinks and retain structural scan completeness. */
1044
+ async function scanRawDirectory(rawDir, includeFile = () => true) {
1045
+ const files = [];
1046
+ const blockers = [];
1047
+ const diagnostics = [];
1048
+ const occupiedPaths = /* @__PURE__ */ new Set();
1049
+ const entryKinds = /* @__PURE__ */ new Map();
1050
+ const ignoredRegularPaths = [];
1051
+ let complete = true;
1052
+ function markIncomplete(path, reason) {
1053
+ complete = false;
1054
+ diagnostics.push({
1055
+ path,
1056
+ reason
1057
+ });
1058
+ }
1059
+ async function visit(folder) {
1060
+ const absolutePath = join(rawDir, folder);
1061
+ let before;
1062
+ try {
1063
+ before = await lstat(absolutePath, { bigint: true });
1064
+ } catch (cause) {
1065
+ markIncomplete(folder, `${folder === "" ? "Raw directory" : `Directory "${folder}"`} cannot be read: ${cause instanceof Error ? cause.message : String(cause)}`);
1066
+ return;
1067
+ }
1068
+ if (!before.isDirectory() || before.isSymbolicLink()) {
1069
+ markIncomplete(folder, `${folder === "" ? "Raw directory" : `Directory "${folder}"`} is not a regular directory.`);
1070
+ return;
1071
+ }
1072
+ let entries;
1073
+ try {
1074
+ entries = await readdir(absolutePath, { withFileTypes: true });
1075
+ } catch (cause) {
1076
+ markIncomplete(folder, `${folder === "" ? "Raw directory" : `Directory "${folder}"`} cannot be traversed: ${cause instanceof Error ? cause.message : String(cause)}`);
1077
+ return;
1078
+ }
1079
+ for (const entry of entries.sort((a, b) => compareCodeUnits(a.name, b.name))) {
1080
+ const path = folder === "" ? entry.name : `${folder}/${entry.name}`;
1081
+ if (entry.name === ".gitkeep" || isFundusTransactionName(entry.name)) continue;
1082
+ if (entry.isDirectory()) {
1083
+ occupiedPaths.add(path);
1084
+ entryKinds.set(path, "directory");
1085
+ const problem = folderPathError(path);
1086
+ if (problem) blockers.push({
1087
+ path,
1088
+ reason: problem
1089
+ });
1090
+ else await visit(path);
1091
+ continue;
1092
+ }
1093
+ if (entry.isFile()) {
1094
+ if (!includeFile(path)) {
1095
+ ignoredRegularPaths.push(path);
1096
+ continue;
1097
+ }
1098
+ occupiedPaths.add(path);
1099
+ entryKinds.set(path, "file");
1100
+ const problem = rawFilePathError(path);
1101
+ if (problem) {
1102
+ blockers.push({
1103
+ path,
1104
+ reason: problem
1105
+ });
1106
+ continue;
1107
+ }
1108
+ try {
1109
+ files.push({
1110
+ path,
1111
+ hash: await stableRawFileHash(join(rawDir, path))
1112
+ });
1113
+ } catch (cause) {
1114
+ blockers.push({
1115
+ path,
1116
+ reason: `Could not obtain a stable file hash: ${cause instanceof Error ? cause.message : String(cause)}`
1117
+ });
1118
+ }
1119
+ continue;
1120
+ }
1121
+ const kind = entry.isSymbolicLink() ? "symlink" : "special";
1122
+ occupiedPaths.add(path);
1123
+ entryKinds.set(path, kind);
1124
+ blockers.push({
1125
+ path,
1126
+ reason: "Symlinks and special files are not supported."
1127
+ });
1128
+ }
1129
+ try {
1130
+ const after = await lstat(absolutePath, { bigint: true });
1131
+ if (!after.isDirectory() || objectIdentity(before) !== objectIdentity(after)) markIncomplete(folder, `${folder === "" ? "Raw directory" : `Directory "${folder}"`} changed during traversal.`);
1132
+ } catch (cause) {
1133
+ markIncomplete(folder, `${folder === "" ? "Raw directory" : `Directory "${folder}"`} changed during traversal: ${cause instanceof Error ? cause.message : String(cause)}`);
1134
+ }
1135
+ }
1136
+ await visit("");
1137
+ const collisions = /* @__PURE__ */ new Map();
1138
+ for (const path of [...occupiedPaths].sort(compareCodeUnits)) {
1139
+ const key = portableRawPathKey(path);
1140
+ const previous = collisions.get(key);
1141
+ if (previous !== void 0 && previous !== path) {
1142
+ const reason = `Raw paths "${previous}" and "${path}" collide portably.`;
1143
+ blockers.push({
1144
+ path: previous,
1145
+ reason
1146
+ });
1147
+ blockers.push({
1148
+ path,
1149
+ reason
1150
+ });
1151
+ } else collisions.set(key, path);
1152
+ }
1153
+ const blockersByPath = /* @__PURE__ */ new Map();
1154
+ for (const blocker of blockers) if (!blockersByPath.has(blocker.path)) blockersByPath.set(blocker.path, blocker);
1155
+ const sortedBlockers = [...blockersByPath.values()].sort((a, b) => compareCodeUnits(a.path, b.path));
1156
+ const blocked = new Set(sortedBlockers.map((entry) => entry.path));
1157
+ return {
1158
+ complete,
1159
+ diagnostics: diagnostics.sort((a, b) => compareCodeUnits(a.path, b.path)),
1160
+ files: files.filter((entry) => !blocked.has(entry.path)).sort((a, b) => compareCodeUnits(a.path, b.path)),
1161
+ blockers: sortedBlockers,
1162
+ occupiedPaths,
1163
+ entryKinds,
1164
+ ignoredRegularPaths: ignoredRegularPaths.sort(compareCodeUnits)
1165
+ };
1166
+ }
1167
+ /** Pure deterministic matching: exact path first, then only 1:1 hash groups. */
1168
+ function classifyRawFiles(library, scan) {
1169
+ const filesByPath = new Map(scan.files.map((file) => [file.path, file]));
1170
+ const remainingFiles = new Map(filesByPath);
1171
+ const remainingRecords = /* @__PURE__ */ new Map();
1172
+ const unchangedAssetIds = [];
1173
+ const edited = [];
1174
+ const blockers = [...scan.blockers];
1175
+ const excludedPrefixes = [];
1176
+ for (const assetId of Object.keys(library.assets).sort(compareCodeUnits)) {
1177
+ const record = library.assets[assetId];
1178
+ const kind = scan.entryKinds.get(record.raw);
1179
+ if (kind !== void 0 && kind !== "file") {
1180
+ const existing = blockers.find((blocker) => blocker.path === record.raw);
1181
+ if (existing) existing.assetId = assetId;
1182
+ else blockers.push({
1183
+ assetId,
1184
+ path: record.raw,
1185
+ reason: `Managed raw path is occupied by a ${kind}.`
1186
+ });
1187
+ excludedPrefixes.push(record.raw);
1188
+ continue;
1189
+ }
1190
+ const exact = filesByPath.get(record.raw);
1191
+ if (exact) {
1192
+ remainingFiles.delete(record.raw);
1193
+ if (exact.hash === record.rawHash) unchangedAssetIds.push(assetId);
1194
+ else edited.push({
1195
+ assetId,
1196
+ ...exact
1197
+ });
1198
+ } else if (scan.complete && !scan.occupiedPaths.has(record.raw) && !scan.blockers.some((blocker) => record.raw === blocker.path || record.raw.startsWith(`${blocker.path}/`))) remainingRecords.set(assetId, {
1199
+ path: record.raw,
1200
+ hash: record.rawHash
1201
+ });
1202
+ }
1203
+ for (const path of remainingFiles.keys()) if (excludedPrefixes.some((prefix) => path.startsWith(`${prefix}/`))) remainingFiles.delete(path);
1204
+ const recordsByHash = /* @__PURE__ */ new Map();
1205
+ for (const [assetId, record] of remainingRecords) recordsByHash.set(record.hash, [...recordsByHash.get(record.hash) ?? [], assetId]);
1206
+ const filesByHash = /* @__PURE__ */ new Map();
1207
+ for (const file of remainingFiles.values()) filesByHash.set(file.hash, [...filesByHash.get(file.hash) ?? [], file]);
1208
+ const moves = [];
1209
+ if (scan.complete) for (const [hash, assetIds] of recordsByHash) {
1210
+ const candidates = filesByHash.get(hash) ?? [];
1211
+ if (assetIds.length !== 1 || candidates.length !== 1) continue;
1212
+ const assetId = assetIds[0];
1213
+ const file = candidates[0];
1214
+ moves.push({
1215
+ assetId,
1216
+ from: remainingRecords.get(assetId)?.path ?? "",
1217
+ ...file
1218
+ });
1219
+ remainingRecords.delete(assetId);
1220
+ remainingFiles.delete(file.path);
1221
+ }
1222
+ const blockerKeys = /* @__PURE__ */ new Set();
1223
+ const uniqueBlockers = blockers.filter((blocker) => {
1224
+ const key = `${blocker.assetId ?? ""}|${blocker.path}`;
1225
+ if (blockerKeys.has(key)) return false;
1226
+ blockerKeys.add(key);
1227
+ return true;
1228
+ });
1229
+ return {
1230
+ complete: scan.complete,
1231
+ diagnostics: scan.diagnostics,
1232
+ unchangedAssetIds,
1233
+ edited: edited.sort((a, b) => compareCodeUnits(a.path, b.path)),
1234
+ moves: scan.complete ? moves.sort((a, b) => compareCodeUnits(a.path, b.path)) : [],
1235
+ deletions: scan.complete ? [...remainingRecords].map(([assetId, record]) => ({
1236
+ assetId,
1237
+ path: record.path
1238
+ })) : [],
1239
+ unmanaged: [...remainingFiles.values()].sort((a, b) => compareCodeUnits(a.path, b.path)),
1240
+ blockers: uniqueBlockers.sort((a, b) => compareCodeUnits(a.path, b.path))
1241
+ };
1242
+ }
1243
+ async function classifyRawDirectory(rawDir, library, includeExternalFile = () => true) {
1244
+ const managedPaths = new Set(Object.values(library.assets).map((record) => record.raw));
1245
+ const scan = await scanRawDirectory(rawDir, (path) => managedPaths.has(path) || includeExternalFile(path));
1246
+ const classification = classifyRawFiles(library, scan);
1247
+ if (!classification.complete || classification.deletions.length === 0) return classification;
1248
+ const ignoredByHash = /* @__PURE__ */ new Map();
1249
+ for (const path of scan.ignoredRegularPaths) try {
1250
+ const hash = await stableRawFileHash(join(rawDir, path));
1251
+ ignoredByHash.set(hash, [...ignoredByHash.get(hash) ?? [], path]);
1252
+ } catch (cause) {
1253
+ return {
1254
+ ...classification,
1255
+ complete: false,
1256
+ diagnostics: [...classification.diagnostics, {
1257
+ path,
1258
+ reason: `Could not safely check ignored raw file "${path}" while managed files were missing: ${cause instanceof Error ? cause.message : String(cause)}`
1259
+ }].sort((a, b) => compareCodeUnits(a.path, b.path)),
1260
+ moves: [],
1261
+ deletions: []
1262
+ };
1263
+ }
1264
+ const missingByHash = /* @__PURE__ */ new Map();
1265
+ for (const deletion of classification.deletions) {
1266
+ const hash = library.assets[deletion.assetId].rawHash;
1267
+ missingByHash.set(hash, [...missingByHash.get(hash) ?? [], deletion]);
1268
+ }
1269
+ const supportedByHash = /* @__PURE__ */ new Map();
1270
+ for (const file of classification.unmanaged) supportedByHash.set(file.hash, [...supportedByHash.get(file.hash) ?? [], file.path]);
1271
+ const protectedAssetIds = /* @__PURE__ */ new Set();
1272
+ const unsupportedBlockers = [];
1273
+ const ambiguityDiagnostics = [];
1274
+ for (const [hash, ignoredPaths] of ignoredByHash) {
1275
+ const missing = missingByHash.get(hash) ?? [];
1276
+ if (missing.length === 0) continue;
1277
+ const candidatePaths = [...supportedByHash.get(hash) ?? [], ...ignoredPaths].sort(compareCodeUnits);
1278
+ const sortedMissing = [...missing].sort((a, b) => compareCodeUnits(a.assetId, b.assetId));
1279
+ if (sortedMissing.length === 1 && ignoredPaths.length === 1 && candidatePaths.length === 1) {
1280
+ const [{ assetId, path: oldPath }] = sortedMissing;
1281
+ const [destination] = ignoredPaths;
1282
+ protectedAssetIds.add(assetId);
1283
+ unsupportedBlockers.push({
1284
+ assetId,
1285
+ path: destination,
1286
+ reason: `Asset "${assetId}" was moved from "${oldPath}" to unsupported path "${destination}". Rename it externally to a supported extension.`
1287
+ });
1288
+ continue;
1289
+ }
1290
+ ambiguityDiagnostics.push({
1291
+ path: candidatePaths[0] ?? "",
1292
+ reason: `Ignored raw files ambiguously match missing assets [${sortedMissing.map((entry) => entry.assetId).join(", ")}] and candidate paths [${candidatePaths.join(", ")}]. Restore or reduce the external files until the match is unique.`
1293
+ });
1294
+ }
1295
+ if (ambiguityDiagnostics.length > 0) return {
1296
+ ...classification,
1297
+ complete: false,
1298
+ diagnostics: [...classification.diagnostics, ...ambiguityDiagnostics].sort((a, b) => compareCodeUnits(`${a.path}|${a.reason}`, `${b.path}|${b.reason}`)),
1299
+ moves: [],
1300
+ deletions: [],
1301
+ blockers: [...classification.blockers, ...unsupportedBlockers].sort((a, b) => compareCodeUnits(a.path, b.path))
1302
+ };
1303
+ return {
1304
+ ...classification,
1305
+ deletions: classification.deletions.filter((deletion) => !protectedAssetIds.has(deletion.assetId)),
1306
+ blockers: [...classification.blockers, ...unsupportedBlockers].sort((a, b) => compareCodeUnits(a.path, b.path))
1307
+ };
1308
+ }
1309
+ //#endregion
1007
1310
  //#region src/lib/server/processing/processor.ts
1008
1311
  /**
1009
1312
  * The processing pipeline: every delivered asset gets exactly one
@@ -1094,6 +1397,7 @@ async function processAssetFile(record, rawPath, proxyPath, config, registry) {
1094
1397
  const stem = basename(proxyPath, extension);
1095
1398
  const temporaryPath = join(dirname(proxyPath), `.${stem}.${crypto.randomUUID()}.tmp${extension}`);
1096
1399
  try {
1400
+ await verifyStableRawFile(rawPath, record.rawHash);
1097
1401
  const output = await plugin.process({
1098
1402
  sourcePath: rawPath,
1099
1403
  targetPath: temporaryPath,
@@ -1101,6 +1405,7 @@ async function processAssetFile(record, rawPath, proxyPath, config, registry) {
1101
1405
  preset: plugin.resolvePreset(parameters, config),
1102
1406
  config
1103
1407
  });
1408
+ await verifyStableRawFile(rawPath, record.rawHash);
1104
1409
  await rename(temporaryPath, proxyPath);
1105
1410
  return output;
1106
1411
  } catch (cause) {
@@ -1165,22 +1470,10 @@ async function processAssets(config, library, registry = serverPluginsByType) {
1165
1470
  * is always the current truth. Proxy files are the pipeline's business — this
1166
1471
  * store only removes them on asset deletion (the pipeline also prunes orphans).
1167
1472
  */
1168
- /** A single path segment with no traversal — guards against `../` escapes. */
1169
- var SAFE_SEGMENT = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
1170
- function assertSafeFileName(fileName) {
1171
- if (!SAFE_SEGMENT.test(fileName) || fileName.includes("/") || fileName.includes("\\")) throw new Error(`Unsafe file name "${fileName}".`);
1172
- }
1173
1473
  /** Validate a persisted/served file path without allowing traversal outside its root. */
1174
1474
  function assertSafeRelativeFilePath(filePath) {
1175
- if (filePath.startsWith("/") || filePath.endsWith("/") || filePath.includes("\\")) throw new Error(`Unsafe file path "${filePath}".`);
1176
- const segments = filePath.split("/");
1177
- if (segments.length === 0) throw new Error(`Unsafe file path "${filePath}".`);
1178
- assertSafeFileName(segments.at(-1) ?? "");
1179
- const folder = segments.slice(0, -1).join("/");
1180
- if (folder !== "") {
1181
- const problem = folderPathError(folder);
1182
- if (problem) throw new Error(problem);
1183
- }
1475
+ const problem = rawFilePathError(filePath);
1476
+ if (problem) throw new Error(problem);
1184
1477
  }
1185
1478
  /**
1186
1479
  * Turn an arbitrary uploaded file name (spaces, umlauts, parentheses, nested
@@ -1232,6 +1525,30 @@ var LibraryStore = class {
1232
1525
  await rename(temporaryPath, this.#config.library);
1233
1526
  }
1234
1527
  /**
1528
+ * Candidate-first source transaction used for externally-owned raw files.
1529
+ * The callback runs after entering the store queue and may scan the raw tree;
1530
+ * Fundus writes only the library candidate and never touches external bytes.
1531
+ */
1532
+ async transactCandidate(change) {
1533
+ return this.#enqueue(async () => {
1534
+ const current = await this.read();
1535
+ const before = serializeLibrary(current);
1536
+ const candidate = structuredClone(current);
1537
+ const value = await change(candidate, current);
1538
+ const changed = serializeLibrary(candidate) !== before;
1539
+ if (changed) await this.write(candidate);
1540
+ return {
1541
+ library: candidate,
1542
+ value,
1543
+ changed
1544
+ };
1545
+ });
1546
+ }
1547
+ /** Remove derived proxies after a source record was externally deleted/moved. */
1548
+ async deleteProxiesOf(assetId) {
1549
+ await this.#deleteProxiesOf(assetId);
1550
+ }
1551
+ /**
1235
1552
  * Ingest a new asset: write the raw file into `rawDir` (under a sanitized,
1236
1553
  * non-colliding name), hash its content, and create the library record with
1237
1554
  * the owning plugin's default parameters. Returns the updated library.
@@ -1264,6 +1581,57 @@ var LibraryStore = class {
1264
1581
  await this.write(library);
1265
1582
  return library;
1266
1583
  }
1584
+ /**
1585
+ * Replace one asset's raw file while preserving its identity and authored
1586
+ * metadata. The replacement stays in the current folder, receives a safe
1587
+ * non-colliding name, and must be accepted by the asset's existing type.
1588
+ */
1589
+ async replaceRawFile(id, options) {
1590
+ return this.#enqueue(() => this.#replaceRawFile(id, options));
1591
+ }
1592
+ async #replaceRawFile(id, options) {
1593
+ const library = await this.read();
1594
+ const record = this.#requireAsset(library, id);
1595
+ const sanitizedName = sanitizeFileName(options.fileName);
1596
+ const extension = extname(sanitizedName).slice(1).toLowerCase();
1597
+ const plugin = serverPluginForType(record.type, this.#registry);
1598
+ if (!plugin.descriptor.accepts.includes(extension)) throw new Error(`The ${record.type} type does not accept ".${extension}" files (accepts: ${plugin.descriptor.accepts.join(", ")}).`);
1599
+ const previousRaw = record.raw;
1600
+ const previousHash = record.rawHash;
1601
+ const folder = folderOfRawPath(previousRaw);
1602
+ const previousName = rawFileNameOfPath(previousRaw);
1603
+ const storedName = sanitizedName === previousName ? previousName : this.#uniqueRawName(sanitizedName, folder);
1604
+ const nextRaw = folder === "" ? storedName : `${folder}/${storedName}`;
1605
+ const previousPath = join(this.#config.rawDir, previousRaw);
1606
+ const nextPath = join(this.#config.rawDir, nextRaw);
1607
+ const token = crypto.randomUUID();
1608
+ const temporaryPath = join(this.#config.rawDir, folder, `.fundus-replace-${token}.tmp`);
1609
+ const backupPath = `${previousPath}.fundus-replace-${token}`;
1610
+ let previousStaged = false;
1611
+ let replacementInstalled = false;
1612
+ await mkdir(dirname(temporaryPath), { recursive: true });
1613
+ try {
1614
+ await writeFile(temporaryPath, options.bytes);
1615
+ if (existsSync(previousPath)) {
1616
+ await rename(previousPath, backupPath);
1617
+ previousStaged = true;
1618
+ }
1619
+ await rename(temporaryPath, nextPath);
1620
+ replacementInstalled = true;
1621
+ record.raw = nextRaw;
1622
+ record.rawHash = sha256Hex(options.bytes);
1623
+ await this.write(library);
1624
+ } catch (cause) {
1625
+ record.raw = previousRaw;
1626
+ record.rawHash = previousHash;
1627
+ if (replacementInstalled) await unlink(nextPath).catch(() => {});
1628
+ if (previousStaged) await rename(backupPath, previousPath);
1629
+ await unlink(temporaryPath).catch(() => {});
1630
+ throw cause;
1631
+ }
1632
+ if (previousStaged) await unlink(backupPath).catch(() => {});
1633
+ return library;
1634
+ }
1267
1635
  /** Replace an asset's parameters (validated by the owning plugin). */
1268
1636
  async updateParameters(id, parameters) {
1269
1637
  return this.#enqueue(() => this.#updateParameters(id, parameters));
@@ -1764,5 +2132,5 @@ var LibraryStore = class {
1764
2132
  }
1765
2133
  };
1766
2134
 
1767
- export { LibraryStore as L, serverPluginForType as a, computeLibraryMembership as b, collectAllReferences as c, descriptorsByType as d, allDeliveredAssetIds as e, compareCodeUnits as f, generateManifestModules as g, encodeRelativePathForUrl as h, isRecord as i, assertSafeRelativeFilePath as j, processAssets as p, readCurrentProxy as r, serverPluginsByType as s };
1768
- //# sourceMappingURL=library-store.js-ZLudCJlT.js.map
2135
+ export { LibraryStore as L, serverPluginForType as a, computeLibraryMembership as b, collectAllReferences as c, descriptorsByType as d, allDeliveredAssetIds as e, compareCodeUnits as f, generateManifestModules as g, encodeRelativePathForUrl as h, isRecord as i, classifyRawDirectory as j, assertSafeRelativeFilePath as k, processAssets as p, readCurrentProxy as r, serverPluginsByType as s, verifyStableRawFile as v };
2136
+ //# sourceMappingURL=library-store.js-DJ-JRE-g.js.map