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":"1783982340628"}
1
+ {"version":"1784103096725"}
Binary file
Binary file
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
2
+ <rect width="64" height="64" rx="14" fill="#1e1e1e" />
3
+ <path d="M32 7 57 32 32 57 7 32Z" fill="#0d99ff" />
4
+ </svg>
Binary file
Binary file
package/build/handler.js CHANGED
@@ -2,9 +2,9 @@ import './shims.js';
2
2
  import 'node:fs';
3
3
  import 'node:path';
4
4
  import 'node:process';
5
- export { h as handler } from './server/chunks/handler-DnbS2t1B.js';
6
- import './server/chunks/index.js-g77q3Boj.js';
7
- import './server/chunks/manifest.js-qmEXbstS.js';
5
+ export { h as handler } from './server/chunks/handler-DZ2Sps4a.js';
6
+ import './server/chunks/index.js-CdmTWQz8.js';
7
+ import './server/chunks/manifest.js-GhfNr35x.js';
8
8
  import './env.js';
9
9
  import 'node:buffer';
10
10
  import 'node:crypto';
@@ -12,11 +12,11 @@ import 'node:http';
12
12
  import 'node:timers';
13
13
  import 'node:querystring';
14
14
  import 'node:stream';
15
- import './server/chunks/chunks/shared.js-B1gC9MiJ.js';
16
- import './server/chunks/chunks/internal.js-DGo2jPcg.js';
17
- import './server/chunks/chunks/utils.js-DnEJ3UjO.js';
15
+ import './server/chunks/chunks/shared.js-Dob0TlTu.js';
16
+ import './server/chunks/chunks/internal.js-Dn37LrAW.js';
17
+ import './server/chunks/chunks/utils.js-B4YimMxv.js';
18
18
  import 'node:url';
19
19
  import './server/chunks/chunks/internal2.js-BlXt2rfE.js';
20
- import './server/chunks/chunks/exports.js-C0rwMMtk.js';
20
+ import './server/chunks/chunks/exports.js-DvhE7Ffd.js';
21
21
  import './server/chunks/chunks/routing.js-y-tryuip.js';
22
22
  //# sourceMappingURL=handler.js.map
package/build/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import http from 'node:http';
2
2
  import fs__default from 'node:fs';
3
3
  import process from 'node:process';
4
- import { p as polka, h as handler, f as format_listening_address } from './server/chunks/handler-DnbS2t1B.js';
4
+ import { p as polka, h as handler, f as format_listening_address } from './server/chunks/handler-DZ2Sps4a.js';
5
5
  import { env, timeout_env } from './env.js';
6
6
  import { rm } from 'node:fs/promises';
7
7
  import './shims.js';
@@ -11,14 +11,14 @@ import 'node:path';
11
11
  import 'node:timers';
12
12
  import 'node:querystring';
13
13
  import 'node:stream';
14
- import './server/chunks/chunks/shared.js-B1gC9MiJ.js';
15
- import './server/chunks/chunks/internal.js-DGo2jPcg.js';
16
- import './server/chunks/chunks/utils.js-DnEJ3UjO.js';
17
- import './server/chunks/index.js-g77q3Boj.js';
14
+ import './server/chunks/chunks/shared.js-Dob0TlTu.js';
15
+ import './server/chunks/chunks/internal.js-Dn37LrAW.js';
16
+ import './server/chunks/chunks/utils.js-B4YimMxv.js';
17
+ import './server/chunks/index.js-CdmTWQz8.js';
18
18
  import './server/chunks/chunks/internal2.js-BlXt2rfE.js';
19
- import './server/chunks/chunks/exports.js-C0rwMMtk.js';
19
+ import './server/chunks/chunks/exports.js-DvhE7Ffd.js';
20
20
  import './server/chunks/chunks/routing.js-y-tryuip.js';
21
- import './server/chunks/manifest.js-qmEXbstS.js';
21
+ import './server/chunks/manifest.js-GhfNr35x.js';
22
22
  import 'node:url';
23
23
 
24
24
  const path = env('SOCKET_PATH', false);
@@ -1,6 +1,5 @@
1
- import './core.js-xfrkaQpS.js';
2
- import { r as rawFileNameOfPath, f as folderOfRawPath } from './folder-path.js-ytx9ucgg.js';
3
- import { s as serverPluginsByType, i as isRecord, L as LibraryStore, a as serverPluginForType, p as processAssets, g as generateManifestModules, c as collectAllReferences, d as descriptorsByType, b as computeLibraryMembership, e as allDeliveredAssetIds, f as compareCodeUnits, r as readCurrentProxy, h as encodeRelativePathForUrl } from './library-store.js-ZLudCJlT.js';
1
+ import { f as folderOfRawPath, r as rawFileNameOfPath, C as typesForFileName, D as proposeAssetId, e as parentFolderPath, m as portableFolderPathKey, b as assetIdError } from './core.js-EA_ysb1J.js';
2
+ import { s as serverPluginsByType, i as isRecord, L as LibraryStore, a as serverPluginForType, v as verifyStableRawFile, p as processAssets, g as generateManifestModules, c as collectAllReferences, d as descriptorsByType, b as computeLibraryMembership, e as allDeliveredAssetIds, f as compareCodeUnits, r as readCurrentProxy, h as encodeRelativePathForUrl, j as classifyRawDirectory } from './library-store.js-DJ-JRE-g.js';
4
3
  import { isAbsolute, resolve, join } from 'node:path';
5
4
  import { existsSync } from 'node:fs';
6
5
  import { createJiti } from 'jiti';
@@ -63,6 +62,60 @@ async function loadConfig(projectRoot) {
63
62
  return resolveConfig(root, isRecord(module) && "default" in module ? module.default : module);
64
63
  }
65
64
  //#endregion
65
+ //#region src/lib/server/raw-safety.ts
66
+ function rawSafetyIssueKey(issue) {
67
+ return `${issue.kind}|${issue.assetId ?? ""}|${issue.path}`;
68
+ }
69
+ /** Managed-source safety gate shared by editor operations and `fundus build`. */
70
+ function rawSafetyIssues(library, classification, compatibleTypes) {
71
+ const issues = [];
72
+ if (!classification.complete) for (const diagnostic of classification.diagnostics) issues.push({
73
+ kind: "incomplete",
74
+ path: diagnostic.path,
75
+ message: diagnostic.reason
76
+ });
77
+ for (const blocker of classification.blockers) {
78
+ const affected = blocker.assetId ? [blocker.assetId] : Object.entries(library.assets).filter(([, record]) => record.raw === blocker.path || record.raw.startsWith(`${blocker.path}/`)).map(([assetId]) => assetId);
79
+ for (const assetId of affected) issues.push({
80
+ kind: "blocker",
81
+ path: blocker.path,
82
+ assetId,
83
+ message: `Raw source "${blocker.path}" is unsafe: ${blocker.reason}`
84
+ });
85
+ }
86
+ for (const missing of classification.deletions) issues.push({
87
+ kind: "missing",
88
+ path: missing.path,
89
+ assetId: missing.assetId,
90
+ message: `Raw file "${missing.path}" is missing from the raw directory.`
91
+ });
92
+ for (const move of classification.moves) issues.push({
93
+ kind: "missing",
94
+ path: move.from,
95
+ assetId: move.assetId,
96
+ message: `Raw file "${move.from}" is missing from the raw directory.`
97
+ });
98
+ for (const edited of classification.edited) issues.push({
99
+ kind: "edited",
100
+ path: edited.path,
101
+ assetId: edited.assetId,
102
+ message: `Raw file "${edited.path}" changed outside Fundus.`
103
+ });
104
+ for (const [assetId, record] of Object.entries(library.assets)) if (!compatibleTypes(record.raw).includes(record.type)) issues.push({
105
+ kind: "type-incompatible",
106
+ path: record.raw,
107
+ assetId,
108
+ message: `Raw file "${record.raw}" is not compatible with its current ${record.type} type.`
109
+ });
110
+ const seen = /* @__PURE__ */ new Set();
111
+ return issues.filter((issue) => {
112
+ const key = rawSafetyIssueKey(issue);
113
+ if (seen.has(key)) return false;
114
+ seen.add(key);
115
+ return true;
116
+ });
117
+ }
118
+ //#endregion
66
119
  //#region src/lib/server/operations.ts
67
120
  /**
68
121
  * The one operations layer: builds the state payload and runs
@@ -89,6 +142,8 @@ var FundusOperations = class {
89
142
  #config;
90
143
  #registry;
91
144
  #store;
145
+ #operationQueue = Promise.resolve();
146
+ #pipelineQueue = Promise.resolve();
92
147
  constructor(config, registry = serverPluginsByType) {
93
148
  this.#config = config;
94
149
  this.#registry = registry;
@@ -100,9 +155,146 @@ var FundusOperations = class {
100
155
  get store() {
101
156
  return this.#store;
102
157
  }
103
- /** Read-only state snapshot (no processing). */
104
- async state() {
105
- return this.#buildState(await this.#store.read(), []);
158
+ #enqueueOperation(operation) {
159
+ const run = this.#operationQueue.then(operation, operation);
160
+ this.#operationQueue = run.then(() => {}, () => {});
161
+ return run;
162
+ }
163
+ /** Read-only state snapshot, serialized with mutations but never processing or writing. */
164
+ state() {
165
+ return this.#enqueueOperation(() => this.#state());
166
+ }
167
+ async #state() {
168
+ await this.#pipelineQueue;
169
+ const library = await this.#store.read();
170
+ const classification = await this.#classifyRawDirectory(library);
171
+ return this.#snapshotState(library, classification);
172
+ }
173
+ /** Reconcile only changes that are safe without a user decision: unique moves and deletions. */
174
+ reconcileRawState() {
175
+ return this.#enqueueOperation(async () => {
176
+ let library = await this.#store.read();
177
+ let classification = await this.#classifyRawDirectory(library);
178
+ if (!this.#canAutoReconcile(classification)) return this.#snapshotState(library, classification);
179
+ for (let pass = 0; pass < 2; pass++) {
180
+ const result = await this.#store.transactCandidate(async (candidate, current) => {
181
+ const fresh = await this.#classifyRawDirectory(current);
182
+ const affectedIds = [];
183
+ if (!this.#canAutoReconcile(fresh)) return {
184
+ classification: fresh,
185
+ affectedIds
186
+ };
187
+ for (const move of fresh.moves) {
188
+ candidate.assets[move.assetId].raw = move.path;
189
+ this.#registerFolderAncestors(candidate, folderOfRawPath(move.path));
190
+ affectedIds.push(move.assetId);
191
+ }
192
+ for (const deletion of fresh.deletions) {
193
+ delete candidate.assets[deletion.assetId];
194
+ affectedIds.push(deletion.assetId);
195
+ }
196
+ return {
197
+ classification: fresh,
198
+ affectedIds
199
+ };
200
+ });
201
+ library = result.library;
202
+ classification = result.value.classification;
203
+ if (!result.changed) return this.#snapshotState(library, classification);
204
+ await this.#store.syncFolders(library);
205
+ for (const id of result.value.affectedIds) await this.#store.deleteProxiesOf(id);
206
+ const snapshot = await this.#afterMutationSnapshot(library);
207
+ library = snapshot.library;
208
+ classification = snapshot.classification;
209
+ if (classification.moves.length === 0 && classification.deletions.length === 0) return snapshot.state;
210
+ if (!this.#canAutoReconcile(classification, true)) return snapshot.state;
211
+ }
212
+ return this.#snapshotState(library, classification, [{ message: "Raw directory kept changing during reconciliation; refresh again after external file operations settle." }]);
213
+ });
214
+ }
215
+ /** Adopt an already-existing raw file without copying, renaming, or deleting it. */
216
+ adoptRawFile(token, id, type, manifests = []) {
217
+ return this.#enqueueOperation(async () => {
218
+ const result = await this.#store.transactCandidate(async (candidate, current) => {
219
+ const file = (await this.#classifyRawDirectory(current)).unmanaged.find((entry) => this.#newToken(entry.path, entry.hash) === token);
220
+ if (!file) throw new Error("This ingestion item is stale; refresh the editor and try again.");
221
+ const idProblem = assetIdError(id);
222
+ if (idProblem) throw new Error(idProblem);
223
+ if (Object.hasOwn(candidate.assets, id)) throw new Error(`An asset with id "${id}" already exists.`);
224
+ if (!this.#compatibleTypes(file.path).includes(type)) throw new Error(`The ${type} type does not accept "${file.path}".`);
225
+ const uniqueManifests = [...new Set(manifests)];
226
+ for (const name of uniqueManifests) if (!Object.hasOwn(candidate.manifests, name)) throw new Error(`Unknown manifest "${name}".`);
227
+ const plugin = serverPluginForType(type, this.#registry);
228
+ let parameters = plugin.descriptor.defaultParameters(plugin.pluginConfig(this.#config));
229
+ parameters = plugin.descriptor.validateParameters(parameters);
230
+ if (plugin.seedIngestParameters) {
231
+ const seeded = await plugin.seedIngestParameters({
232
+ rawPath: join(this.#config.rawDir, file.path),
233
+ rawFileName: rawFileNameOfPath(file.path),
234
+ parameters,
235
+ config: this.#config
236
+ });
237
+ if (seeded !== void 0) parameters = plugin.descriptor.validateParameters(seeded);
238
+ }
239
+ await verifyStableRawFile(join(this.#config.rawDir, file.path), file.hash);
240
+ this.#registerFolderAncestors(candidate, folderOfRawPath(file.path));
241
+ candidate.assets[id] = {
242
+ type,
243
+ raw: file.path,
244
+ rawHash: file.hash,
245
+ parameters,
246
+ manifests: uniqueManifests.sort()
247
+ };
248
+ });
249
+ await this.#store.syncFolders(result.library);
250
+ return this.#afterMutation(result.library);
251
+ });
252
+ }
253
+ /** Reset/reseed edited bytes, optionally changing to another compatible type. */
254
+ acceptEditedRawFile(token, type) {
255
+ return this.#enqueueOperation(async () => {
256
+ const result = await this.#store.transactCandidate(async (candidate, current) => {
257
+ const classification = await this.#classifyRawDirectory(current);
258
+ const edited = this.#editedRawFiles(classification, current).find((entry) => this.#editedToken(entry.assetId, entry.path, entry.hash) === token);
259
+ if (!edited) throw new Error("This edited item is stale; refresh the editor and try again.");
260
+ if (!this.#compatibleTypes(edited.path).includes(type)) throw new Error(`The ${type} type does not accept "${edited.path}".`);
261
+ const plugin = serverPluginForType(type, this.#registry);
262
+ let parameters = plugin.descriptor.validateParameters(plugin.descriptor.defaultParameters(plugin.pluginConfig(this.#config)));
263
+ if (plugin.seedIngestParameters) {
264
+ const seeded = await plugin.seedIngestParameters({
265
+ rawPath: join(this.#config.rawDir, edited.path),
266
+ rawFileName: rawFileNameOfPath(edited.path),
267
+ parameters,
268
+ config: this.#config
269
+ });
270
+ if (seeded !== void 0) parameters = plugin.descriptor.validateParameters(seeded);
271
+ }
272
+ await verifyStableRawFile(join(this.#config.rawDir, edited.path), edited.hash);
273
+ const record = candidate.assets[edited.assetId];
274
+ record.type = type;
275
+ record.rawHash = edited.hash;
276
+ record.parameters = parameters;
277
+ return edited.assetId;
278
+ });
279
+ await this.#store.deleteProxiesOf(result.value);
280
+ return this.#afterMutation(result.library);
281
+ });
282
+ }
283
+ /** Accept edited bytes while preserving type, parameters, path and memberships. */
284
+ dismissEditedRawFile(token) {
285
+ return this.#enqueueOperation(async () => {
286
+ const result = await this.#store.transactCandidate(async (candidate, current) => {
287
+ const classification = await this.#classifyRawDirectory(current);
288
+ const edited = this.#editedRawFiles(classification, current).find((entry) => this.#editedToken(entry.assetId, entry.path, entry.hash) === token);
289
+ if (!edited) throw new Error("This edited item is stale; refresh the editor and try again.");
290
+ const record = current.assets[edited.assetId];
291
+ if (!this.#compatibleTypes(edited.path).includes(record.type)) throw new Error(`The moved file "${edited.path}" is not compatible with its current ${record.type} type; choose a compatible type and process it.`);
292
+ candidate.assets[edited.assetId].rawHash = edited.hash;
293
+ return edited.assetId;
294
+ });
295
+ await this.#store.deleteProxiesOf(result.value);
296
+ return this.#afterMutation(result.library);
297
+ });
106
298
  }
107
299
  /**
108
300
  * Ingest an upload: store the raw file + record, then let the owning
@@ -113,7 +305,10 @@ var FundusOperations = class {
113
305
  * explicit membership set in the same operation; a failing application
114
306
  * rolls the whole ingest back, so a failed ingest leaves nothing behind.
115
307
  */
116
- async ingest(options) {
308
+ ingest(options) {
309
+ return this.#enqueueOperation(() => this.#ingest(options));
310
+ }
311
+ async #ingest(options) {
117
312
  let library = await this.#store.ingest(options);
118
313
  try {
119
314
  const plugin = serverPluginForType(options.type, this.#registry);
@@ -138,7 +333,10 @@ var FundusOperations = class {
138
333
  return this.#afterMutation(library);
139
334
  }
140
335
  /** Apply a PATCH body: parameters and/or manifests and/or a rename — in that order. */
141
- async patchAsset(id, body) {
336
+ patchAsset(id, body) {
337
+ return this.#enqueueOperation(() => this.#patchAsset(id, body));
338
+ }
339
+ async #patchAsset(id, body) {
142
340
  let library = await this.#store.read();
143
341
  this.#requireAsset(library, id);
144
342
  if (body.parameters !== void 0) library = await this.#store.updateParameters(id, body.parameters);
@@ -156,11 +354,24 @@ var FundusOperations = class {
156
354
  }
157
355
  return this.#afterMutation(library);
158
356
  }
159
- async moveAsset(id, folder) {
357
+ moveAsset(id, folder) {
358
+ return this.#enqueueOperation(() => this.#moveAsset(id, folder));
359
+ }
360
+ async #moveAsset(id, folder) {
160
361
  return this.#afterMutation(await this.#store.moveAsset(id, folder));
161
362
  }
363
+ /** Replace the raw bytes/name and run the normal processing + codegen tail. */
364
+ replaceRawFile(id, options) {
365
+ return this.#enqueueOperation(() => this.#replaceRawFile(id, options));
366
+ }
367
+ async #replaceRawFile(id, options) {
368
+ return this.#afterMutation(await this.#store.replaceRawFile(id, options));
369
+ }
162
370
  /** Move a selected asset set as one editor action and roll back on any failure. */
163
- async moveAssets(assetIds, folder) {
371
+ moveAssets(assetIds, folder) {
372
+ return this.#enqueueOperation(() => this.#moveAssets(assetIds, folder));
373
+ }
374
+ async #moveAssets(assetIds, folder) {
164
375
  const uniqueIds = [...new Set(assetIds)];
165
376
  if (uniqueIds.length === 0) throw new Error("At least one asset id is required.");
166
377
  const originalFolders = /* @__PURE__ */ new Map();
@@ -183,16 +394,28 @@ var FundusOperations = class {
183
394
  throw cause;
184
395
  }
185
396
  }
186
- async createFolder(path) {
397
+ createFolder(path) {
398
+ return this.#enqueueOperation(() => this.#createFolder(path));
399
+ }
400
+ async #createFolder(path) {
187
401
  return this.#afterMutation(await this.#store.createFolder(path));
188
402
  }
189
- async renameFolder(path, newName) {
403
+ renameFolder(path, newName) {
404
+ return this.#enqueueOperation(() => this.#renameFolder(path, newName));
405
+ }
406
+ async #renameFolder(path, newName) {
190
407
  return this.#afterMutation(await this.#store.renameFolder(path, newName));
191
408
  }
192
- async moveFolder(path, parent) {
409
+ moveFolder(path, parent) {
410
+ return this.#enqueueOperation(() => this.#moveFolder(path, parent));
411
+ }
412
+ async #moveFolder(path, parent) {
193
413
  return this.#afterMutation(await this.#store.moveFolder(path, parent));
194
414
  }
195
- async deleteFolder(path) {
415
+ deleteFolder(path) {
416
+ return this.#enqueueOperation(() => this.#deleteFolder(path));
417
+ }
418
+ async #deleteFolder(path) {
196
419
  const result = await this.#store.deleteFolder(path);
197
420
  return this.#afterMutation(result.library);
198
421
  }
@@ -204,7 +427,10 @@ var FundusOperations = class {
204
427
  * rejected with nothing written. The REST `patchAsset` keeps the editor's
205
428
  * lenient replace semantics.
206
429
  */
207
- async setAsset(id, changes) {
430
+ setAsset(id, changes) {
431
+ return this.#enqueueOperation(() => this.#setAsset(id, changes));
432
+ }
433
+ async #setAsset(id, changes) {
208
434
  const library = await this.#store.read();
209
435
  this.#requireAsset(library, id);
210
436
  return this.#afterMutation(await this.#applyAssetChanges(library, id, changes));
@@ -214,7 +440,10 @@ var FundusOperations = class {
214
440
  * a referrer keeps pointing at the old id, so renaming a referenced asset
215
441
  * introduces dangling-reference errors. Update the referrers first.
216
442
  */
217
- async renameAsset(id, newId) {
443
+ renameAsset(id, newId) {
444
+ return this.#enqueueOperation(() => this.#renameAsset(id, newId));
445
+ }
446
+ async #renameAsset(id, newId) {
218
447
  const library = await this.#store.read();
219
448
  this.#requireAsset(library, id);
220
449
  if (newId !== id && !Object.hasOwn(library.assets, newId)) {
@@ -231,7 +460,10 @@ var FundusOperations = class {
231
460
  * (the asset is a reference target) is rejected before anything —
232
461
  * including the raw file — is removed; the REST route stays lenient.
233
462
  */
234
- async deleteAsset(id, options) {
463
+ deleteAsset(id, options) {
464
+ return this.#enqueueOperation(() => this.#deleteAsset(id, options));
465
+ }
466
+ async #deleteAsset(id, options) {
235
467
  if (options?.failOnIntroducedIssues) {
236
468
  const library = await this.#store.read();
237
469
  this.#requireAsset(library, id);
@@ -242,19 +474,31 @@ var FundusOperations = class {
242
474
  return this.#afterMutation(await this.#store.deleteAsset(id));
243
475
  }
244
476
  /** Delete a selected asset set as one lenient editor mutation. */
245
- async deleteAssets(assetIds) {
477
+ deleteAssets(assetIds) {
478
+ return this.#enqueueOperation(() => this.#deleteAssets(assetIds));
479
+ }
480
+ async #deleteAssets(assetIds) {
246
481
  const uniqueIds = [...new Set(assetIds)];
247
482
  if (uniqueIds.length === 0) throw new Error("At least one asset id is required.");
248
483
  return this.#afterMutation(await this.#store.deleteAssets(uniqueIds));
249
484
  }
250
- async createManifest(name) {
485
+ createManifest(name) {
486
+ return this.#enqueueOperation(() => this.#createManifest(name));
487
+ }
488
+ async #createManifest(name) {
251
489
  return this.#afterMutation(await this.#store.createManifest(name));
252
490
  }
253
- async setManifestAppearance(name, appearance) {
491
+ setManifestAppearance(name, appearance) {
492
+ return this.#enqueueOperation(() => this.#setManifestAppearance(name, appearance));
493
+ }
494
+ async #setManifestAppearance(name, appearance) {
254
495
  return this.#afterMutation(await this.#store.setManifestAppearance(name, appearance));
255
496
  }
256
497
  /** Apply a PATCH body: appearance fields and/or a rename — in that order. */
257
- async patchManifest(name, body) {
498
+ patchManifest(name, body) {
499
+ return this.#enqueueOperation(() => this.#patchManifest(name, body));
500
+ }
501
+ async #patchManifest(name, body) {
258
502
  let library = await this.#store.setManifestAppearance(name, {
259
503
  color: body.color,
260
504
  emoji: body.emoji
@@ -271,26 +515,47 @@ var FundusOperations = class {
271
515
  * the module must be updated by hand — both the file name and the exported
272
516
  * const change with the manifest name.
273
517
  */
274
- async renameManifest(name, newName) {
518
+ renameManifest(name, newName) {
519
+ return this.#enqueueOperation(() => this.#renameManifest(name, newName));
520
+ }
521
+ async #renameManifest(name, newName) {
275
522
  return this.#afterMutation(await this.#store.renameManifest(name, newName));
276
523
  }
277
- async deleteManifest(name) {
524
+ deleteManifest(name) {
525
+ return this.#enqueueOperation(() => this.#deleteManifest(name));
526
+ }
527
+ async #deleteManifest(name) {
278
528
  return this.#afterMutation(await this.#store.deleteManifest(name));
279
529
  }
280
530
  /** The autosave chain tail: process + regenerate, then report fresh state. */
281
531
  async #afterMutation(library) {
532
+ return (await this.#afterMutationSnapshot(library)).state;
533
+ }
534
+ async #afterMutationSnapshot(library) {
535
+ const run = this.#pipelineQueue.then(() => this.#runAfterMutation(library), () => this.#runAfterMutation(library));
536
+ this.#pipelineQueue = run.then(() => {}, () => {});
537
+ return run;
538
+ }
539
+ async #runAfterMutation(library) {
282
540
  const pipelineIssues = [];
283
- const issues = await this.#store.validate(library);
284
- if (issues.length === 0) try {
541
+ const classification = await this.#classifyRawDirectory(library);
542
+ const ordinaryIssues = await this.#store.validate(library);
543
+ const safetyIssues = this.#rawSafetyIssues(library, classification);
544
+ if (ordinaryIssues.length === 0 && safetyIssues.length === 0) try {
285
545
  const report = await processAssets(this.#config, library, this.#registry);
286
546
  await generateManifestModules(this.#config, library, report.proxies, this.#registry);
287
547
  } catch (cause) {
288
548
  pipelineIssues.push({ message: `Processing failed: ${cause instanceof Error ? cause.message : String(cause)}` });
289
549
  }
290
- return this.#buildState(library, pipelineIssues, issues);
550
+ const latestLibrary = await this.#store.read();
551
+ const latestClassification = await this.#classifyRawDirectory(latestLibrary);
552
+ return {
553
+ library: latestLibrary,
554
+ classification: latestClassification,
555
+ state: await this.#snapshotState(latestLibrary, latestClassification, pipelineIssues)
556
+ };
291
557
  }
292
- async #buildState(library, extraIssues, precomputedIssues) {
293
- const issues = [...precomputedIssues ?? await this.#store.validate(library), ...extraIssues];
558
+ async #buildState(library, issues, classification) {
294
559
  const referencesByAsset = collectAllReferences(library, descriptorsByType(this.#registry));
295
560
  const membershipByManifest = computeLibraryMembership(library, referencesByAsset);
296
561
  const delivered = allDeliveredAssetIds(membershipByManifest);
@@ -335,7 +600,7 @@ var FundusOperations = class {
335
600
  type: record.type,
336
601
  raw: record.raw,
337
602
  folder: folderOfRawPath(record.raw),
338
- rawUrl: `/files/raw/${encodeRelativePathForUrl(record.raw)}`,
603
+ rawUrl: `/files/raw/${encodeRelativePathForUrl(record.raw)}?v=${record.rawHash.slice(0, 12)}`,
339
604
  rawHash: record.rawHash,
340
605
  parameters: record.parameters,
341
606
  manifests: record.manifests,
@@ -372,9 +637,118 @@ var FundusOperations = class {
372
637
  issues,
373
638
  presetNames,
374
639
  manifestMemberships,
375
- manifestDeliveredBytes
640
+ manifestDeliveredBytes,
641
+ rawIngestionQueue: this.#buildRawIngestionQueue(library, classification)
376
642
  };
377
643
  }
644
+ #compatibleTypes(path) {
645
+ return typesForFileName(path, Object.values(this.#registry).map((plugin) => plugin.descriptor)).sort(compareCodeUnits);
646
+ }
647
+ #classifyRawDirectory(library) {
648
+ return classifyRawDirectory(this.#config.rawDir, library, (path) => this.#compatibleTypes(path).length > 0);
649
+ }
650
+ #rawSafetyIssues(library, classification) {
651
+ return rawSafetyIssues(library, classification, (path) => this.#compatibleTypes(path));
652
+ }
653
+ async #snapshotState(library, classification, extraIssues = []) {
654
+ const issues = [
655
+ ...await this.#store.validate(library),
656
+ ...this.#rawSafetyIssues(library, classification),
657
+ ...extraIssues
658
+ ];
659
+ const seen = /* @__PURE__ */ new Set();
660
+ const uniqueIssues = issues.filter((issue) => {
661
+ const key = `${issue.assetId ?? ""}|${issue.message}`;
662
+ if (seen.has(key)) return false;
663
+ seen.add(key);
664
+ return true;
665
+ });
666
+ return this.#buildState(library, uniqueIssues, classification);
667
+ }
668
+ #canAutoReconcile(classification, retry = false) {
669
+ return classification.complete && classification.blockers.length === 0 && classification.moves.length + classification.deletions.length > 0 && (!retry || classification.edited.length === 0 && classification.unmanaged.length === 0);
670
+ }
671
+ #newToken(path, hash) {
672
+ return `new:${path}:${hash}`;
673
+ }
674
+ #editedToken(assetId, path, hash) {
675
+ return `edited:${assetId}:${path}:${hash}`;
676
+ }
677
+ #proposedId(path, reservedIds) {
678
+ const base = proposeAssetId(rawFileNameOfPath(path));
679
+ if (!reservedIds.has(base)) return base;
680
+ for (let index = 2;; index++) {
681
+ const candidate = `${base}${index}`;
682
+ if (!reservedIds.has(candidate)) return candidate;
683
+ }
684
+ }
685
+ #buildRawIngestionQueue(library, classification) {
686
+ const queue = [];
687
+ const reservedIds = new Set(Object.keys(library.assets));
688
+ for (const file of classification.unmanaged) {
689
+ const compatibleTypes = this.#compatibleTypes(file.path);
690
+ const proposedId = this.#proposedId(file.path, reservedIds);
691
+ reservedIds.add(proposedId);
692
+ queue.push({
693
+ kind: "new",
694
+ token: this.#newToken(file.path, file.hash),
695
+ path: file.path,
696
+ hash: file.hash,
697
+ compatibleTypes,
698
+ proposedId
699
+ });
700
+ }
701
+ for (const edited of this.#editedRawFiles(classification, library)) {
702
+ const currentType = library.assets[edited.assetId].type;
703
+ queue.push({
704
+ kind: "edited",
705
+ token: this.#editedToken(edited.assetId, edited.path, edited.hash),
706
+ path: edited.path,
707
+ hash: edited.hash,
708
+ assetId: edited.assetId,
709
+ currentType,
710
+ compatibleTypes: this.#compatibleTypes(edited.path)
711
+ });
712
+ }
713
+ for (const blocker of classification.blockers) queue.push({
714
+ kind: "unsupported",
715
+ token: `unsupported:${blocker.path}:${blocker.reason}`,
716
+ path: blocker.path,
717
+ reason: blocker.reason
718
+ });
719
+ for (const diagnostic of classification.diagnostics) queue.push({
720
+ kind: "unsupported",
721
+ token: `unsupported:raw-directory:${diagnostic.reason}`,
722
+ path: diagnostic.path || "Raw directory",
723
+ reason: diagnostic.reason
724
+ });
725
+ return queue.sort((a, b) => compareCodeUnits(a.path, b.path));
726
+ }
727
+ #editedRawFiles(classification, library) {
728
+ const edited = new Map(classification.edited.map((entry) => [entry.assetId, entry]));
729
+ for (const assetId of classification.unchangedAssetIds) {
730
+ const record = library.assets[assetId];
731
+ if (!this.#compatibleTypes(record.raw).includes(record.type)) edited.set(assetId, {
732
+ assetId,
733
+ path: record.raw,
734
+ hash: record.rawHash
735
+ });
736
+ }
737
+ return [...edited.values()].sort((a, b) => compareCodeUnits(a.path, b.path));
738
+ }
739
+ #registerFolderAncestors(library, folder) {
740
+ if (folder === "") return;
741
+ const missing = [];
742
+ for (let current = folder; current !== ""; current = parentFolderPath(current)) if (!library.folders.includes(current)) missing.push(current);
743
+ const keys = new Map(library.folders.map((path) => [portableFolderPathKey(path), path]));
744
+ for (const path of missing.reverse()) {
745
+ const collision = keys.get(portableFolderPathKey(path));
746
+ if (collision !== void 0 && collision !== path) throw new Error(`Folder "${path}" collides with existing folder "${collision}".`);
747
+ library.folders.push(path);
748
+ keys.set(portableFolderPathKey(path), path);
749
+ }
750
+ library.folders.sort(compareCodeUnits);
751
+ }
378
752
  #requireAsset(library, id) {
379
753
  if (!Object.hasOwn(library.assets, id)) throw new Error(`Unknown asset "${id}".`);
380
754
  }
@@ -426,4 +800,4 @@ async function createFundusContext() {
426
800
  }
427
801
 
428
802
  export { getFundusContext as g, initializeFundusContext as i };
429
- //# sourceMappingURL=context.js-BUZqFfWG.js.map
803
+ //# sourceMappingURL=context.js-B77ZAVLi.js.map