fundus 0.28.1 → 0.29.1

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 (190) hide show
  1. package/README.md +41 -33
  2. package/build/client/_app/immutable/chunks/{apKHI4vq.js → C0uU_Rhe.js} +2 -2
  3. package/build/client/_app/immutable/chunks/C0uU_Rhe.js.br +0 -0
  4. package/build/client/_app/immutable/chunks/C0uU_Rhe.js.gz +0 -0
  5. package/build/client/_app/immutable/chunks/{Bsj1ssvc.js → CE3cWlK6.js} +1 -1
  6. package/build/client/_app/immutable/chunks/CE3cWlK6.js.br +0 -0
  7. package/build/client/_app/immutable/chunks/CE3cWlK6.js.gz +0 -0
  8. package/build/client/_app/immutable/chunks/{g2rma9Ym.js → CMJ10zbJ.js} +1 -1
  9. package/build/client/_app/immutable/chunks/CMJ10zbJ.js.br +0 -0
  10. package/build/client/_app/immutable/chunks/CMJ10zbJ.js.gz +0 -0
  11. package/build/client/_app/immutable/chunks/{QlQ-jeIO.js → Cq3PJxJG.js} +1 -1
  12. package/build/client/_app/immutable/chunks/Cq3PJxJG.js.br +2 -0
  13. package/build/client/_app/immutable/chunks/Cq3PJxJG.js.gz +0 -0
  14. package/build/client/_app/immutable/chunks/{OL1Dh1oP.js → Wk7WcyQU.js} +1 -1
  15. package/build/client/_app/immutable/chunks/Wk7WcyQU.js.br +0 -0
  16. package/build/client/_app/immutable/chunks/Wk7WcyQU.js.gz +0 -0
  17. package/build/client/_app/immutable/entry/{app.DpZM49_s.js → app.Dit62aNJ.js} +2 -2
  18. package/build/client/_app/immutable/entry/app.Dit62aNJ.js.br +0 -0
  19. package/build/client/_app/immutable/entry/app.Dit62aNJ.js.gz +0 -0
  20. package/build/client/_app/immutable/entry/start.CCBu6ABN.js +1 -0
  21. package/build/client/_app/immutable/entry/start.CCBu6ABN.js.br +0 -0
  22. package/build/client/_app/immutable/entry/start.CCBu6ABN.js.gz +0 -0
  23. package/build/client/_app/immutable/nodes/{0.Wqvn8XD-.js → 0.DnyKXqLr.js} +1 -1
  24. package/build/client/_app/immutable/nodes/0.DnyKXqLr.js.br +0 -0
  25. package/build/client/_app/immutable/nodes/0.DnyKXqLr.js.gz +0 -0
  26. package/build/client/_app/immutable/nodes/{1.Z-UvvLkP.js → 1.Cz-4S6LF.js} +1 -1
  27. package/build/client/_app/immutable/nodes/1.Cz-4S6LF.js.br +0 -0
  28. package/build/client/_app/immutable/nodes/1.Cz-4S6LF.js.gz +0 -0
  29. package/build/client/_app/immutable/nodes/{2.lu89W_qJ.js → 2.C75-hsCY.js} +1 -1
  30. package/build/client/_app/immutable/nodes/2.C75-hsCY.js.br +0 -0
  31. package/build/client/_app/immutable/nodes/2.C75-hsCY.js.gz +0 -0
  32. package/build/client/_app/immutable/nodes/{3.Dt32EAoq.js → 3.4pSddugU.js} +1 -1
  33. package/build/client/_app/immutable/nodes/3.4pSddugU.js.br +0 -0
  34. package/build/client/_app/immutable/nodes/3.4pSddugU.js.gz +0 -0
  35. package/build/client/_app/immutable/nodes/{4.WipzcX8_.js → 4.KoQxJEWQ.js} +1 -1
  36. package/build/client/_app/immutable/nodes/4.KoQxJEWQ.js.br +0 -0
  37. package/build/client/_app/immutable/nodes/4.KoQxJEWQ.js.gz +0 -0
  38. package/build/client/_app/version.json +1 -1
  39. package/build/client/_app/version.json.br +0 -0
  40. package/build/client/_app/version.json.gz +0 -0
  41. package/build/handler.js +7 -7
  42. package/build/index.js +7 -7
  43. package/build/server/chunks/chunks/{context.js-BZSZNuAd.js → context.js-BR2IRl9z.js} +205 -115
  44. package/build/server/chunks/chunks/context.js-BR2IRl9z.js.map +1 -0
  45. package/build/server/chunks/chunks/{contract.js-B4JdXFgm.js → contract.js-DHeIVVv8.js} +46 -12
  46. package/build/server/chunks/chunks/contract.js-DHeIVVv8.js.map +1 -0
  47. package/build/server/chunks/chunks/{core.js-BHxa3VBo.js → core.js-AGKlECJ0.js} +32 -32
  48. package/build/server/chunks/chunks/core.js-AGKlECJ0.js.map +1 -0
  49. package/build/server/chunks/chunks/{exports.js-D0dALD2Q.js → exports.js-CNZgoxR0.js} +2 -2
  50. package/build/server/chunks/chunks/{exports.js-D0dALD2Q.js.map → exports.js-CNZgoxR0.js.map} +1 -1
  51. package/build/server/chunks/chunks/{http.js-DYYKvppy.js → http.js-dk5jbOFm.js} +2 -2
  52. package/build/server/chunks/chunks/{http.js-DYYKvppy.js.map → http.js-dk5jbOFm.js.map} +1 -1
  53. package/build/server/chunks/chunks/{internal.js-CJkB_gzV.js → internal.js-DlRiYJji.js} +3 -3
  54. package/build/server/chunks/chunks/{internal.js-CJkB_gzV.js.map → internal.js-DlRiYJji.js.map} +1 -1
  55. package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
  56. package/build/server/chunks/chunks/{manifest-membership.js-BkrPsM_r.js → manifest-membership.js-DkHaPk2F.js} +2 -2
  57. package/build/server/chunks/chunks/{manifest-membership.js-BkrPsM_r.js.map → manifest-membership.js-DkHaPk2F.js.map} +1 -1
  58. package/build/server/chunks/chunks/{raw-reconciliation2.js-DKOpJ8if.js → raw-reconciliation.js-Cco4r8lr.js} +52 -18
  59. package/build/server/chunks/chunks/raw-reconciliation.js-Cco4r8lr.js.map +1 -0
  60. package/build/server/chunks/chunks/raw-reconciliation2.js-CuYSsYTP.js +11 -0
  61. package/build/server/chunks/chunks/raw-reconciliation2.js-CuYSsYTP.js.map +1 -0
  62. package/build/server/chunks/chunks/{shared.js-D3ZDVUlh.js → shared.js-C6qC0jnA.js} +2 -2
  63. package/build/server/chunks/chunks/{shared.js-D3ZDVUlh.js.map → shared.js-C6qC0jnA.js.map} +1 -1
  64. package/build/server/chunks/chunks/{utils.js-CqWW_v-5.js → utils.js-BZ32hXFI.js} +3 -3
  65. package/build/server/chunks/chunks/{utils.js-CqWW_v-5.js.map → utils.js-BZ32hXFI.js.map} +1 -1
  66. package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-Dw2MW5Tm.js → _server.ts.js-8jGLP2Aj.js} +6 -6
  67. package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-Dw2MW5Tm.js.map → _server.ts.js-8jGLP2Aj.js.map} +1 -1
  68. package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-GQDuJGug.js → _server.ts.js-BOW9Ejim.js} +7 -7
  69. package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-GQDuJGug.js.map → _server.ts.js-BOW9Ejim.js.map} +1 -1
  70. package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-JbLSv7Xx.js → _server.ts.js-Clac8atJ.js} +7 -7
  71. package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-JbLSv7Xx.js.map → _server.ts.js-Clac8atJ.js.map} +1 -1
  72. package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-BPae-BYF.js → _server.ts.js-EdHTA-SO.js} +7 -7
  73. package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-BPae-BYF.js.map → _server.ts.js-EdHTA-SO.js.map} +1 -1
  74. package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/{_server.ts.js-BafrrUxu.js → _server.ts.js-ZBCRgRYi.js} +7 -7
  75. package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/{_server.ts.js-BafrrUxu.js.map → _server.ts.js-ZBCRgRYi.js.map} +1 -1
  76. package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-UOlSNEi9.js → _server.ts.js-DY_e5K6d.js} +7 -7
  77. package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-UOlSNEi9.js.map → _server.ts.js-DY_e5K6d.js.map} +1 -1
  78. package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-QE1vUuAx.js → _server.ts.js-Cl2jxJNi.js} +7 -7
  79. package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-QE1vUuAx.js.map → _server.ts.js-Cl2jxJNi.js.map} +1 -1
  80. package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DIVfppGt.js → _server.ts.js-DrrZWUbd.js} +7 -7
  81. package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DIVfppGt.js.map → _server.ts.js-DrrZWUbd.js.map} +1 -1
  82. package/build/server/chunks/entries/endpoints/api/events/{_server.ts.js-B6R_kqP8.js → _server.ts.js-Bnw0HbEk.js} +7 -7
  83. package/build/server/chunks/entries/endpoints/api/events/{_server.ts.js-B6R_kqP8.js.map → _server.ts.js-Bnw0HbEk.js.map} +1 -1
  84. package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-CertbDsH.js → _server.ts.js-NeVn2ap9.js} +7 -7
  85. package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-CertbDsH.js.map → _server.ts.js-NeVn2ap9.js.map} +1 -1
  86. package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-DEIF3Hu2.js → _server.ts.js-ENGDgoLy.js} +7 -7
  87. package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-DEIF3Hu2.js.map → _server.ts.js-ENGDgoLy.js.map} +1 -1
  88. package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-DNFsNGr4.js → _server.ts.js-BQVGCzBR.js} +7 -7
  89. package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-DNFsNGr4.js.map → _server.ts.js-BQVGCzBR.js.map} +1 -1
  90. package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-DDW8XRPe.js → _server.ts.js-Pxver0Y-.js} +7 -7
  91. package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-DDW8XRPe.js.map → _server.ts.js-Pxver0Y-.js.map} +1 -1
  92. package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-C222-xli.js → _server.ts.js-DYtiqzJq.js} +7 -7
  93. package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-C222-xli.js.map → _server.ts.js-DYtiqzJq.js.map} +1 -1
  94. package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-CI1P1uyd.js → _server.ts.js-lBgmEZHV.js} +7 -7
  95. package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-CI1P1uyd.js.map → _server.ts.js-lBgmEZHV.js.map} +1 -1
  96. package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-DpiUwaSh.js → _server.ts.js-BJHyONFH.js} +7 -7
  97. package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-DpiUwaSh.js.map → _server.ts.js-BJHyONFH.js.map} +1 -1
  98. package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-DT0VPqPT.js → _server.ts.js-Bm5XO80W.js} +7 -7
  99. package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-DT0VPqPT.js.map → _server.ts.js-Bm5XO80W.js.map} +1 -1
  100. package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-DBpHM42g.js → _server.ts.js-B7Z20kYf.js} +7 -7
  101. package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-DBpHM42g.js.map → _server.ts.js-B7Z20kYf.js.map} +1 -1
  102. package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-Cxu5b6Au.js → _server.ts.js-Cg-f37jc.js} +7 -7
  103. package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-Cxu5b6Au.js.map → _server.ts.js-Cg-f37jc.js.map} +1 -1
  104. package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-W4dhMo8Y.js → _server.ts.js-dIXZiq5l.js} +7 -7
  105. package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-W4dhMo8Y.js.map → _server.ts.js-dIXZiq5l.js.map} +1 -1
  106. package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-DJ_adxbT.js → _server.ts.js-CnTrS5pT.js} +7 -7
  107. package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-DJ_adxbT.js.map → _server.ts.js-CnTrS5pT.js.map} +1 -1
  108. package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-BisoHihD.js → _server.ts.js-B7TcFRuL.js} +6 -6
  109. package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-BisoHihD.js.map → _server.ts.js-B7TcFRuL.js.map} +1 -1
  110. package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-D4jLLuko.js → _server.ts.js-BkUQInqW.js} +7 -7
  111. package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-D4jLLuko.js.map → _server.ts.js-BkUQInqW.js.map} +1 -1
  112. package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-Dfv2ItjT.js → _server.ts.js-CshyvqOq.js} +7 -7
  113. package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-Dfv2ItjT.js.map → _server.ts.js-CshyvqOq.js.map} +1 -1
  114. package/build/server/chunks/entries/{hooks.server.js-oHJX5INm.js → hooks.server.js-D4DECjz_.js} +8 -7
  115. package/build/server/chunks/entries/hooks.server.js-D4DECjz_.js.map +1 -0
  116. package/build/server/chunks/{handler-BAe0c9yw.js → handler-Cna54zf6.js} +5 -5
  117. package/build/server/chunks/{handler-BAe0c9yw.js.map → handler-Cna54zf6.js.map} +1 -1
  118. package/build/server/chunks/{index.js-DUYD4JB0.js → index.js-BnpHWDec.js} +5 -5
  119. package/build/server/chunks/{index.js-DUYD4JB0.js.map → index.js-BnpHWDec.js.map} +1 -1
  120. package/build/server/chunks/{manifest.js-zwun-T7O.js → manifest.js-9WMEOpxH.js} +31 -31
  121. package/build/server/chunks/{manifest.js-zwun-T7O.js.map → manifest.js-9WMEOpxH.js.map} +1 -1
  122. package/build/server/chunks/nodes/{0.js-BmkXwDRY.js → 0.js-C2b1a672.js} +2 -2
  123. package/build/server/chunks/nodes/{0.js-BmkXwDRY.js.map → 0.js-C2b1a672.js.map} +1 -1
  124. package/build/server/chunks/nodes/1.js-P3Ai28oj.js +7 -0
  125. package/build/server/chunks/nodes/{1.js-xbOwEHCW.js.map → 1.js-P3Ai28oj.js.map} +1 -1
  126. package/build/server/chunks/nodes/{2.js-BuNw1vTZ.js → 2.js-sM3j5BqB.js} +2 -2
  127. package/build/server/chunks/nodes/{2.js-BuNw1vTZ.js.map → 2.js-sM3j5BqB.js.map} +1 -1
  128. package/build/server/chunks/nodes/3.js-G0jV-ymM.js +7 -0
  129. package/build/server/chunks/nodes/{3.js-Dpr_DvNU.js.map → 3.js-G0jV-ymM.js.map} +1 -1
  130. package/build/server/chunks/nodes/4.js-BUTPrI45.js +7 -0
  131. package/build/server/chunks/nodes/{4.js-14Lypd4o.js.map → 4.js-BUTPrI45.js.map} +1 -1
  132. package/dist/cli.js +3 -4
  133. package/dist/core/figma-tag-links.d.ts +66 -0
  134. package/dist/core/figma-tag-links.js +97 -0
  135. package/dist/core/index.d.ts +2 -2
  136. package/dist/core/index.js +1 -1
  137. package/dist/server/cli-commands.d.ts +1 -1
  138. package/dist/server/cli-commands.js +1 -1
  139. package/dist/server/cli-figma-tags.d.ts +1 -1
  140. package/dist/server/cli-figma-tags.js +149 -88
  141. package/dist/server/concurrency.d.ts +12 -0
  142. package/dist/server/concurrency.js +23 -0
  143. package/dist/server/figma-tags.d.ts +72 -24
  144. package/dist/server/figma-tags.js +130 -79
  145. package/dist/server/image-duplicates.js +6 -4
  146. package/dist/server/importers/figma.d.ts +20 -15
  147. package/dist/server/importers/figma.js +172 -92
  148. package/dist/server/operations.d.ts +7 -0
  149. package/dist/server/operations.js +53 -26
  150. package/dist/server/processing/processor.d.ts +29 -1
  151. package/dist/server/processing/processor.js +42 -5
  152. package/dist/server/raw-reconciliation.js +26 -10
  153. package/package.json +1 -1
  154. package/build/client/_app/immutable/chunks/Bsj1ssvc.js.br +0 -0
  155. package/build/client/_app/immutable/chunks/Bsj1ssvc.js.gz +0 -0
  156. package/build/client/_app/immutable/chunks/OL1Dh1oP.js.br +0 -0
  157. package/build/client/_app/immutable/chunks/OL1Dh1oP.js.gz +0 -0
  158. package/build/client/_app/immutable/chunks/QlQ-jeIO.js.br +0 -2
  159. package/build/client/_app/immutable/chunks/QlQ-jeIO.js.gz +0 -0
  160. package/build/client/_app/immutable/chunks/apKHI4vq.js.br +0 -0
  161. package/build/client/_app/immutable/chunks/apKHI4vq.js.gz +0 -0
  162. package/build/client/_app/immutable/chunks/g2rma9Ym.js.br +0 -0
  163. package/build/client/_app/immutable/chunks/g2rma9Ym.js.gz +0 -0
  164. package/build/client/_app/immutable/entry/app.DpZM49_s.js.br +0 -0
  165. package/build/client/_app/immutable/entry/app.DpZM49_s.js.gz +0 -0
  166. package/build/client/_app/immutable/entry/start.B3EMVPEN.js +0 -1
  167. package/build/client/_app/immutable/entry/start.B3EMVPEN.js.br +0 -0
  168. package/build/client/_app/immutable/entry/start.B3EMVPEN.js.gz +0 -0
  169. package/build/client/_app/immutable/nodes/0.Wqvn8XD-.js.br +0 -0
  170. package/build/client/_app/immutable/nodes/0.Wqvn8XD-.js.gz +0 -0
  171. package/build/client/_app/immutable/nodes/1.Z-UvvLkP.js.br +0 -0
  172. package/build/client/_app/immutable/nodes/1.Z-UvvLkP.js.gz +0 -0
  173. package/build/client/_app/immutable/nodes/2.lu89W_qJ.js.br +0 -0
  174. package/build/client/_app/immutable/nodes/2.lu89W_qJ.js.gz +0 -0
  175. package/build/client/_app/immutable/nodes/3.Dt32EAoq.js.br +0 -0
  176. package/build/client/_app/immutable/nodes/3.Dt32EAoq.js.gz +0 -0
  177. package/build/client/_app/immutable/nodes/4.WipzcX8_.js.br +0 -0
  178. package/build/client/_app/immutable/nodes/4.WipzcX8_.js.gz +0 -0
  179. package/build/server/chunks/chunks/context.js-BZSZNuAd.js.map +0 -1
  180. package/build/server/chunks/chunks/contract.js-B4JdXFgm.js.map +0 -1
  181. package/build/server/chunks/chunks/core.js-BHxa3VBo.js.map +0 -1
  182. package/build/server/chunks/chunks/raw-reconciliation.js-DPnNXe0b.js +0 -11
  183. package/build/server/chunks/chunks/raw-reconciliation.js-DPnNXe0b.js.map +0 -1
  184. package/build/server/chunks/chunks/raw-reconciliation2.js-DKOpJ8if.js.map +0 -1
  185. package/build/server/chunks/entries/hooks.server.js-oHJX5INm.js.map +0 -1
  186. package/build/server/chunks/nodes/1.js-xbOwEHCW.js +0 -7
  187. package/build/server/chunks/nodes/3.js-Dpr_DvNU.js +0 -7
  188. package/build/server/chunks/nodes/4.js-14Lypd4o.js +0 -7
  189. package/dist/core/figma-tag-script.d.ts +0 -154
  190. package/dist/core/figma-tag-script.js +0 -248
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-BAe0c9yw.js';
4
+ import { p as polka, h as handler, f as format_listening_address } from './server/chunks/handler-Cna54zf6.js';
5
5
  import { env, timeout_env } from './env.js';
6
6
  import { rm } from 'node:fs/promises';
7
7
  import './shims.js';
@@ -11,15 +11,15 @@ 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-D3ZDVUlh.js';
15
- import './server/chunks/chunks/internal.js-CJkB_gzV.js';
14
+ import './server/chunks/chunks/shared.js-C6qC0jnA.js';
15
+ import './server/chunks/chunks/internal.js-DlRiYJji.js';
16
16
  import 'node:module';
17
- import './server/chunks/chunks/utils.js-CqWW_v-5.js';
18
- import './server/chunks/index.js-DUYD4JB0.js';
17
+ import './server/chunks/chunks/utils.js-BZ32hXFI.js';
18
+ import './server/chunks/index.js-BnpHWDec.js';
19
19
  import './server/chunks/chunks/internal2.js-BlXt2rfE.js';
20
- import './server/chunks/chunks/exports.js-D0dALD2Q.js';
20
+ import './server/chunks/chunks/exports.js-CNZgoxR0.js';
21
21
  import './server/chunks/chunks/routing.js-y-tryuip.js';
22
- import './server/chunks/manifest.js-zwun-T7O.js';
22
+ import './server/chunks/manifest.js-9WMEOpxH.js';
23
23
  import 'node:url';
24
24
 
25
25
  const path = env('SOCKET_PATH', false);
@@ -1,8 +1,8 @@
1
- import { c as compareCodeUnits, h as folderOfRawPath, j as rawFileNameOfPath, g as canonicalizeParameters, n as normalizeFolderPath, J as typesForFileName, k as parentFolderPath, u as portableFolderPathKey } from './core.js-BHxa3VBo.js';
2
- import { i as isRecord, s as serverPluginsByType, L as LibraryStore, d as descriptorsByType, m as manifestModuleFileName, l as locateGeneratedAssetDeclaration, a as serializeLibrary, b as serverPluginForType, S as SourceImportError, p as processAssets, g as generateManifestModules, r as readCurrentProxy, e as encodeRelativePathForUrl, c as invalidInput, f as parseLibrary } from './contract.js-B4JdXFgm.js';
3
- import { c as collectAllReferences, a as assetIdError, b as computeLibraryMembership, d as allDeliveredAssetIds, i as isValidAssetId } from './manifest-membership.js-BkrPsM_r.js';
1
+ import { c as compareCodeUnits, h as folderOfRawPath, j as rawFileNameOfPath, g as canonicalizeParameters, n as normalizeFolderPath, J as typesForFileName, k as parentFolderPath, u as portableFolderPathKey } from './core.js-AGKlECJ0.js';
2
+ import { i as isRecord, s as serverPluginsByType, P as ProxyInfoCache, L as LibraryStore, d as descriptorsByType, m as manifestModuleFileName, l as locateGeneratedAssetDeclaration, a as serializeLibrary, b as serverPluginForType, S as SourceImportError, p as processAssets, g as generateManifestModules, r as readCurrentProxy, e as encodeRelativePathForUrl, c as invalidInput, f as parseLibrary } from './contract.js-DHeIVVv8.js';
3
+ import { c as collectAllReferences, d as allDeliveredAssetIds, b as computeLibraryMembership, a as assetIdError, i as isValidAssetId } from './manifest-membership.js-DkHaPk2F.js';
4
4
  import { v as validateDependencyList, f as formatRequiredBy } from './dependencies.js-pUkjICr5.js';
5
- import { v as verifyStableRawFile, c as classifyRawDirectory } from './raw-reconciliation2.js-DKOpJ8if.js';
5
+ import { m as mapConcurrent, v as verifyStableRawFile, c as classifyRawDirectory } from './raw-reconciliation.js-Cco4r8lr.js';
6
6
  import { createRequire } from 'node:module';
7
7
  import { isAbsolute, resolve, basename, dirname, join, extname, relative, sep } from 'node:path';
8
8
  import { existsSync, watch, readFileSync } from 'node:fs';
@@ -16,14 +16,59 @@ import { lookup } from 'node:dns/promises';
16
16
  import { isIP } from 'node:net';
17
17
  import { request } from 'node:https';
18
18
 
19
- //#region src/lib/core/figma-tag-script.ts
20
19
  /**
21
- * Whether the id names a node inside an instance (`I<instance>;<source>`).
22
- * Such nodes inherit the shared plugin data of the main component's node, so
23
- * they report its tag without being a separate taggable node.
20
+ * The tag a link URL names, or `null`. An exact string match (no URL parsing)
21
+ * makes any path segment, query, fragment or percent-escape fail the tag grammar.
24
22
  */
25
- function isInstanceSublayerId(id) {
26
- return id.startsWith("I");
23
+ function parseFundusTagLink(url) {
24
+ if (!url.startsWith("https://fundus.invalid/asset/")) return null;
25
+ const tag = url.slice(29);
26
+ return isValidAssetId(tag) ? tag : null;
27
+ }
28
+ var TAGGABLE_NODE_ID = /^\d+:\d+$/;
29
+ /**
30
+ * The Fundus tags carried by own links on plain scene-node ids; inherited,
31
+ * sublayer, foreign and unparsable links are dropped. One entry per link, so
32
+ * several tags on one node stay several entries. Sorted by tag, then node id.
33
+ */
34
+ function figmaTagEntries(links) {
35
+ const entries = [];
36
+ for (const link of links) {
37
+ if (link.inherited || !TAGGABLE_NODE_ID.test(link.nodeId)) continue;
38
+ const tag = parseFundusTagLink(link.url);
39
+ if (tag === null) continue;
40
+ entries.push(link.linkId === void 0 ? {
41
+ tag,
42
+ nodeId: link.nodeId
43
+ } : {
44
+ tag,
45
+ nodeId: link.nodeId,
46
+ linkId: link.linkId
47
+ });
48
+ }
49
+ return entries.sort((left, right) => compareCodeUnits(left.tag, right.tag) || compareCodeUnits(left.nodeId, right.nodeId));
50
+ }
51
+ /**
52
+ * The links in a REST `GET /v1/files/:key/dev_resources` body, or `null` when
53
+ * `dev_resources` is not an array. Entries without string `id`/`url`/`node_id`
54
+ * are skipped.
55
+ */
56
+ function figmaLinksFromRest(body) {
57
+ const resources = typeof body === "object" && body !== null ? body.dev_resources : void 0;
58
+ if (!Array.isArray(resources)) return null;
59
+ const links = [];
60
+ for (const resource of resources) {
61
+ if (typeof resource !== "object" || resource === null) continue;
62
+ const { id, url, node_id: nodeId } = resource;
63
+ if (typeof id !== "string" || typeof url !== "string" || typeof nodeId !== "string") continue;
64
+ links.push({
65
+ nodeId,
66
+ url,
67
+ inherited: false,
68
+ linkId: id
69
+ });
70
+ }
71
+ return links;
27
72
  }
28
73
  //#endregion
29
74
  //#region src/lib/core/propose-asset-id.ts
@@ -427,6 +472,9 @@ var PNG_SIGNATURE = Uint8Array.from([
427
472
  26,
428
473
  10
429
474
  ]);
475
+ /** Worst case per API call: 3 attempts × 30 s timeout + 2 waits × 10 s = 110 s. */
476
+ var FIGMA_RATE_LIMIT_ATTEMPTS = 3;
477
+ var FIGMA_RATE_LIMIT_MAX_WAIT_SECONDS = 10;
430
478
  function record(value) {
431
479
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
432
480
  }
@@ -506,12 +554,12 @@ function retryAfter(response) {
506
554
  const seconds = Number(raw);
507
555
  return Number.isSafeInteger(seconds) ? seconds : void 0;
508
556
  }
509
- function upstreamStatusError(response) {
557
+ function upstreamStatusError(response, scope) {
510
558
  if (response.status === 401) return new SourceImportError("unauthorized", "Figma authentication failed.");
511
- if (response.status === 403) return new SourceImportError("forbidden", "Figma authentication or access failed. The token may be invalid or expired, or it may not have access to this file.");
559
+ if (response.status === 403) return new SourceImportError("forbidden", scope ? `Figma authentication or access failed. The token may be invalid or expired, may lack the ${scope} scope, or may not have access to this file.` : "Figma authentication or access failed. The token may be invalid or expired, or it may not have access to this file.");
512
560
  if (response.status === 404) return new SourceImportError("not-found", "The Figma file or node was not found.");
513
561
  if (response.status === 429) return new SourceImportError("rate-limited", "Figma rate-limited this request.", retryAfter(response));
514
- return new SourceImportError("upstream-failed", `Figma export failed with status ${response.status}.`);
562
+ return new SourceImportError("upstream-failed", `Figma request failed with status ${response.status}.`);
515
563
  }
516
564
  function isForbiddenIpv4(address) {
517
565
  const parts = address.split(".").map(Number);
@@ -570,7 +618,7 @@ async function resolveSafeDownloadTarget(value) {
570
618
  addresses
571
619
  };
572
620
  }
573
- async function fetchWithDeadline(fetcher, url, init, consume) {
621
+ async function fetchWithDeadline(fetcher, url, init, scope) {
574
622
  const controller = new AbortController();
575
623
  const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
576
624
  try {
@@ -578,12 +626,12 @@ async function fetchWithDeadline(fetcher, url, init, consume) {
578
626
  ...init,
579
627
  signal: controller.signal
580
628
  });
581
- if (!response.ok) throw upstreamStatusError(response);
582
- return await consume(response);
629
+ if (!response.ok) throw upstreamStatusError(response, scope);
630
+ return new Uint8Array(await response.arrayBuffer());
583
631
  } catch (cause) {
584
- if (controller.signal.aborted || cause instanceof Error && cause.name === "AbortError") throw new SourceImportError("download-timeout", "Figma export timed out.");
632
+ if (controller.signal.aborted || cause instanceof Error && cause.name === "AbortError") throw new SourceImportError("download-timeout", "Figma request timed out.");
585
633
  if (cause instanceof SourceImportError) throw cause;
586
- throw new SourceImportError("upstream-failed", "Figma export request failed.");
634
+ throw new SourceImportError("upstream-failed", "Figma request failed.");
587
635
  } finally {
588
636
  clearTimeout(timeout);
589
637
  }
@@ -684,44 +732,28 @@ async function validatePng(bytes) {
684
732
  if (!metadata.width || !metadata.height) throw new SourceImportError("invalid-response", "Figma export has invalid dimensions.");
685
733
  if (metadata.width * metadata.height > MAX_PIXELS) throw new SourceImportError("image-too-large", "Figma export exceeds the 32 megapixel limit.");
686
734
  }
687
- /**
688
- * Every taggable node in a REST document tree (`plugin_data=shared`), in
689
- * document order. Nodes inside instances are skipped: they echo the main
690
- * component node's tag, and Fundus imports only plain `12:34` node ids.
691
- */
692
- function figmaDocumentNodes(document) {
693
- const nodes = [];
694
- const visit = (value, page) => {
695
- const current = record(value);
696
- if (!current) return;
697
- const name = typeof current.name === "string" ? current.name : "";
698
- const pageName = current.type === "CANVAS" ? name : page;
699
- if (typeof current.id === "string" && current.type !== "DOCUMENT" && current.type !== "CANVAS" && !isInstanceSublayerId(current.id)) {
700
- const shared = record(current.sharedPluginData);
701
- const fundus = shared ? record(shared.fundus) : null;
702
- const tag = fundus && typeof fundus.assetId === "string" ? fundus.assetId : "";
703
- nodes.push({
704
- nodeId: current.id,
705
- nodeName: name,
706
- page: pageName,
707
- tag: tag === "" ? null : tag
708
- });
709
- }
710
- if (Array.isArray(current.children)) for (const child of current.children) visit(child, pageName);
711
- };
712
- visit(record(document), "");
713
- return nodes;
735
+ async function fetchFigmaApiBytes(endpoint, init, scope, context) {
736
+ for (let attempt = 1;; attempt++) try {
737
+ return await fetchWithDeadline(context.fetch, endpoint, init, scope);
738
+ } catch (cause) {
739
+ const wait = cause instanceof SourceImportError && cause.code === "rate-limited" ? cause.retryAfterSeconds : void 0;
740
+ if (wait === void 0 || wait > FIGMA_RATE_LIMIT_MAX_WAIT_SECONDS || attempt >= FIGMA_RATE_LIMIT_ATTEMPTS) throw cause;
741
+ await new Promise((resolve) => setTimeout(resolve, wait * 1e3));
742
+ }
714
743
  }
715
- /** The whole document tree of a Figma file, including every node's shared plugin data. */
716
- async function fetchFigmaDocument(fileKey, context) {
744
+ async function requestFigmaApi(endpoint, context, request) {
717
745
  const token = context.config.import.figma.token;
718
746
  if (!token) throw new SourceImportError("not-configured", "Figma access is not configured.");
719
- const endpoint = new URL(`https://api.figma.com/v1/files/${encodeURIComponent(fileKey)}`);
720
- endpoint.searchParams.set("plugin_data", "shared");
721
- const jsonBytes = await fetchWithDeadline(context.fetch, endpoint, {
747
+ const jsonBytes = await fetchFigmaApiBytes(endpoint, {
748
+ method: request.method ?? "GET",
722
749
  redirect: "error",
723
- headers: { "X-Figma-Token": token }
724
- }, async (response) => new Uint8Array(await response.arrayBuffer()));
750
+ headers: {
751
+ "X-Figma-Token": token,
752
+ ...request.body !== void 0 ? { "Content-Type": "application/json" } : {}
753
+ },
754
+ ...request.body !== void 0 ? { body: JSON.stringify(request.body) } : {}
755
+ }, request.scope, context);
756
+ if (jsonBytes.byteLength === 0) return {};
725
757
  let payload;
726
758
  try {
727
759
  payload = JSON.parse(new TextDecoder().decode(jsonBytes));
@@ -729,38 +761,64 @@ async function fetchFigmaDocument(fileKey, context) {
729
761
  throw new SourceImportError("invalid-response", "Figma returned an invalid response.");
730
762
  }
731
763
  const body = record(payload);
732
- if (!body || body.err || typeof body.status === "number" && body.status >= 400) throw new SourceImportError("invalid-response", "Figma returned an invalid response.");
733
- return body.document;
764
+ if (!body || body.err || body.error === true || typeof body.status === "number" && body.status >= 400) throw new SourceImportError("invalid-response", request.errorMessage);
765
+ if (Array.isArray(body.errors) && body.errors.length > 0) throw new SourceImportError("upstream-failed", `Figma rejected the request: ${body.errors.map((entry) => {
766
+ const reason = record(entry)?.error;
767
+ return typeof reason === "string" ? reason : "unknown error";
768
+ }).join("; ")}`);
769
+ return body;
770
+ }
771
+ function figmaFileEndpoint(fileKey, path) {
772
+ return new URL(`https://api.figma.com/v1/files/${encodeURIComponent(fileKey)}${path}`);
773
+ }
774
+ /** Every Fundus tag link in the file (orphaned ones included); each entry has its `linkId`. */
775
+ async function listFigmaTagEntries(fileKey, context) {
776
+ const links = figmaLinksFromRest(await requestFigmaApi(figmaFileEndpoint(fileKey, "/dev_resources"), context, {
777
+ scope: "file_dev_resources:read",
778
+ errorMessage: "Figma returned an invalid response."
779
+ }));
780
+ if (!links) throw new SourceImportError("invalid-response", "Figma returned an invalid Dev Resources list.");
781
+ return figmaTagEntries(links).filter((entry) => entry.linkId !== void 0);
782
+ }
783
+ /** Export URLs for the nodes in one `/images` call; `null` for a node Figma cannot render. */
784
+ async function exportImageUrls(fileKey, nodeIds, scale, context) {
785
+ const endpoint = new URL(`https://api.figma.com/v1/images/${encodeURIComponent(fileKey)}`);
786
+ endpoint.searchParams.set("ids", nodeIds.join(","));
787
+ endpoint.searchParams.set("format", "png");
788
+ endpoint.searchParams.set("scale", String(scale));
789
+ const images = record((await requestFigmaApi(endpoint, context, {
790
+ scope: "file_content:read",
791
+ errorMessage: "Figma could not render this node."
792
+ })).images);
793
+ const urls = {};
794
+ for (const nodeId of nodeIds) {
795
+ if (!images || !Object.hasOwn(images, nodeId)) throw new SourceImportError("invalid-response", "Figma did not return the requested node.");
796
+ const imageUrl = images[nodeId];
797
+ urls[nodeId] = typeof imageUrl === "string" && imageUrl.length > 0 ? imageUrl : null;
798
+ }
799
+ return urls;
734
800
  }
735
- async function resolveTagToNode(fileKey, tag, context) {
736
- const matches = figmaDocumentNodes(await fetchFigmaDocument(fileKey, context)).filter((node) => node.tag === tag);
737
- if (matches.length === 0) throw new SourceImportError("not-found", `No Figma node is tagged "${tag}" in this file.`);
738
- if (matches.length > 1) throw new SourceImportError("ambiguous-tag", `More than one Figma node is tagged "${tag}" in this file.`);
739
- return matches[0].nodeId;
801
+ /**
802
+ * The one renderable node carrying `tag`. All candidates go into a single
803
+ * `/images` call, which answers deleted nodes with `null`; a live but
804
+ * unrenderable second candidate therefore goes unnoticed.
805
+ */
806
+ async function resolveTaggedNode(fileKey, tag, scale, context) {
807
+ const candidates = [...new Set((await listFigmaTagEntries(fileKey, context)).filter((entry) => entry.tag === tag).map((entry) => entry.nodeId))];
808
+ if (candidates.length === 0) throw new SourceImportError("not-found", `No Figma node is tagged "${tag}" in this file.`);
809
+ const urls = await exportImageUrls(fileKey, candidates, scale, context);
810
+ const live = candidates.flatMap((nodeId) => {
811
+ const imageUrl = urls[nodeId];
812
+ return imageUrl ? [{
813
+ nodeId,
814
+ imageUrl
815
+ }] : [];
816
+ });
817
+ if (live.length === 0) throw new SourceImportError("not-found", `Every Figma node tagged "${tag}" (${candidates.join(", ")}) is deleted or cannot be rendered.`);
818
+ if (live.length > 1) throw new SourceImportError("ambiguous-tag", `More than one Figma node is tagged "${tag}" in this file (${live.map((node) => node.nodeId).join(", ")}).`);
819
+ return live[0];
740
820
  }
741
- async function materialize(source, context) {
742
- const token = context.config.import.figma.token;
743
- if (!token) throw new SourceImportError("not-configured", "Figma access is not configured.");
744
- const endpoint = new URL(`https://api.figma.com/v1/images/${encodeURIComponent(source.fileKey)}`);
745
- endpoint.searchParams.set("ids", source.nodeId);
746
- endpoint.searchParams.set("format", source.format);
747
- endpoint.searchParams.set("scale", String(source.scale));
748
- const jsonBytes = await fetchWithDeadline(context.fetch, endpoint, {
749
- redirect: "error",
750
- headers: { "X-Figma-Token": token }
751
- }, async (response) => new Uint8Array(await response.arrayBuffer()));
752
- let payload;
753
- try {
754
- payload = JSON.parse(new TextDecoder().decode(jsonBytes));
755
- } catch {
756
- throw new SourceImportError("invalid-response", "Figma returned an invalid response.");
757
- }
758
- const body = record(payload);
759
- if (!body || body.err || typeof body.status === "number" && body.status >= 400) throw new SourceImportError("invalid-response", "Figma could not render this node.");
760
- const images = record(body.images);
761
- if (!images || !Object.hasOwn(images, source.nodeId)) throw new SourceImportError("invalid-response", "Figma did not return the requested node.");
762
- const imageUrl = images[source.nodeId];
763
- if (typeof imageUrl !== "string" || imageUrl.length === 0) throw new SourceImportError("invalid-response", "Figma could not render the requested node.");
821
+ async function downloadRaw(source, imageUrl, context) {
764
822
  const bytes = await downloadExport(context.httpsTransport ?? requestPinnedHttps, imageUrl);
765
823
  await validatePng(bytes);
766
824
  return {
@@ -772,6 +830,18 @@ async function materialize(source, context) {
772
830
  }
773
831
  };
774
832
  }
833
+ async function importNode(source, context) {
834
+ const imageUrl = (await exportImageUrls(source.fileKey, [source.nodeId], source.scale, context))[source.nodeId];
835
+ if (!imageUrl) throw new SourceImportError("invalid-response", "Figma could not render the requested node.");
836
+ return downloadRaw(source, imageUrl, context);
837
+ }
838
+ async function importTag(source, context) {
839
+ const { nodeId, imageUrl } = await resolveTaggedNode(source.fileKey, source.fundusTag, source.scale, context);
840
+ return downloadRaw({
841
+ ...source,
842
+ nodeId
843
+ }, imageUrl, context);
844
+ }
775
845
  var figmaSourceImporter = {
776
846
  kind: "figma",
777
847
  label: "Figma",
@@ -780,18 +850,16 @@ var figmaSourceImporter = {
780
850
  if (input.mode === "tag") {
781
851
  const fileKey = input.fileKey ?? context.config.import.figma.defaultFileKey;
782
852
  if (!fileKey) throw new SourceImportError("not-configured", "Figma tag import needs a fileKey or import.figma.defaultFileKey in fundus.config.");
783
- const nodeId = await resolveTagToNode(fileKey, input.tag, context);
784
- return materialize({
853
+ return importTag({
785
854
  mode: "tag",
786
855
  fileKey,
787
856
  fundusTag: input.tag,
788
- nodeId,
789
857
  format: "png",
790
858
  scale: input.scale ?? context.config.import.figma.defaults.scale
791
859
  }, context);
792
860
  }
793
861
  const parsed = parseFigmaSelectionUrl(input.url);
794
- return materialize({
862
+ return importNode({
795
863
  fileKey: parsed.fileKey,
796
864
  nodeId: parsed.nodeId,
797
865
  format: "png",
@@ -800,14 +868,8 @@ var figmaSourceImporter = {
800
868
  },
801
869
  validateSourceParameters: validateFigmaSourceParameters,
802
870
  async reimportRaw(source, context) {
803
- if (source.mode === "tag") {
804
- const nodeId = await resolveTagToNode(source.fileKey, source.fundusTag, context);
805
- return materialize({
806
- ...source,
807
- nodeId
808
- }, context);
809
- }
810
- return materialize(source, context);
871
+ if (source.mode === "tag") return importTag(source, context);
872
+ return importNode(source, context);
811
873
  }
812
874
  };
813
875
  //#endregion
@@ -1451,22 +1513,22 @@ var ImageDuplicateDetector = class {
1451
1513
  const images = Object.entries(library.assets).filter(([, record]) => record.type === "image").sort(([left], [right]) => compareCodeUnits(left, right));
1452
1514
  const activeHashes = new Set(images.map(([, record]) => record.rawHash));
1453
1515
  for (const hash of this.#fingerprints.keys()) if (!activeHashes.has(hash)) this.#fingerprints.delete(hash);
1454
- const readable = [];
1455
- for (const [id, record] of images) {
1516
+ const readable = (await mapConcurrent(images, 8, async ([id, record]) => {
1456
1517
  let fingerprint = this.#fingerprints.get(record.rawHash);
1457
1518
  if (!fingerprint) {
1458
1519
  fingerprint = imageFingerprint(join(rawDir, record.raw), 8);
1459
1520
  this.#fingerprints.set(record.rawHash, fingerprint);
1460
1521
  }
1461
1522
  try {
1462
- readable.push({
1523
+ return {
1463
1524
  id,
1464
1525
  fingerprint: await fingerprint
1465
- });
1526
+ };
1466
1527
  } catch {
1467
1528
  this.#fingerprints.delete(record.rawHash);
1529
+ return null;
1468
1530
  }
1469
- }
1531
+ })).filter((entry) => entry !== null);
1470
1532
  const duplicates = /* @__PURE__ */ new Map();
1471
1533
  for (let leftIndex = 0; leftIndex < readable.length; leftIndex++) for (let rightIndex = leftIndex + 1; rightIndex < readable.length; rightIndex++) {
1472
1534
  const left = readable[leftIndex];
@@ -1527,6 +1589,7 @@ var FundusOperations = class {
1527
1589
  #importers;
1528
1590
  #usageAnalyzer;
1529
1591
  #duplicateDetector = new ImageDuplicateDetector();
1592
+ #proxyInfoCache = new ProxyInfoCache();
1530
1593
  #operationQueue = Promise.resolve();
1531
1594
  #pipelineQueue = Promise.resolve();
1532
1595
  constructor(config, registry = serverPluginsByType, importerRegistry = serverImporters) {
@@ -1622,6 +1685,17 @@ var FundusOperations = class {
1622
1685
  const classification = await this.#classifyRawDirectory(library);
1623
1686
  return this.#snapshotState(library, classification);
1624
1687
  }
1688
+ /**
1689
+ * Fill the image-fingerprint and proxy-probe caches without scanning raws or
1690
+ * joining the operation queue, so an early editor reconcile shares this
1691
+ * in-flight work instead of waiting behind it. Both caches are keyed by
1692
+ * content, so a concurrent mutation can only make an entry unused.
1693
+ */
1694
+ async warmCaches() {
1695
+ const library = await this.#store.read();
1696
+ const delivered = allDeliveredAssetIds(computeLibraryMembership(library, collectAllReferences(library, descriptorsByType(this.#registry))));
1697
+ await Promise.all([this.#duplicateDetector.find(library, this.#config.rawDir), mapConcurrent([...delivered].sort(compareCodeUnits), 8, (assetId) => this.#proxyState(assetId, library.assets[assetId], delivered))]);
1698
+ }
1625
1699
  /** Reconcile only changes that are safe without a user decision: unique moves and deletions. */
1626
1700
  reconcileRawState() {
1627
1701
  return this.#enqueueOperation(async () => {
@@ -2245,12 +2319,38 @@ var FundusOperations = class {
2245
2319
  state: await this.#snapshotState(latestLibrary, latestClassification, pipelineIssues)
2246
2320
  };
2247
2321
  }
2322
+ async #proxyState(assetId, record, delivered) {
2323
+ if (!delivered.has(assetId)) return { proxy: null };
2324
+ try {
2325
+ const currentProxy = await readCurrentProxy(assetId, record, this.#config, this.#registry, this.#proxyInfoCache);
2326
+ if (!currentProxy) return {
2327
+ proxy: null,
2328
+ warning: "Proxy is stale or missing — it will be (re)processed on the next save."
2329
+ };
2330
+ return { proxy: {
2331
+ url: `/files/proxy/${encodeRelativePathForUrl(currentProxy.relativePath)}`,
2332
+ upToDate: true,
2333
+ ...currentProxy
2334
+ } };
2335
+ } catch (cause) {
2336
+ return {
2337
+ proxy: null,
2338
+ warning: cause instanceof Error ? cause.message : String(cause)
2339
+ };
2340
+ }
2341
+ }
2248
2342
  async #buildState(library, issues, classification) {
2249
- const [gitBranch, changedGitAssets] = await Promise.all([currentGitBranch(this.#config.projectRoot), gitAssetChanges(this.#config.projectRoot, this.#config.library, library)]);
2250
2343
  const referencesByAsset = collectAllReferences(library, descriptorsByType(this.#registry));
2251
- const duplicatesByAsset = await this.#duplicateDetector.find(library, this.#config.rawDir);
2252
2344
  const membershipByManifest = computeLibraryMembership(library, referencesByAsset);
2253
2345
  const delivered = allDeliveredAssetIds(membershipByManifest);
2346
+ const assetIds = Object.keys(library.assets).sort(compareCodeUnits);
2347
+ const [gitBranch, changedGitAssets, duplicatesByAsset, proxies] = await Promise.all([
2348
+ currentGitBranch(this.#config.projectRoot),
2349
+ gitAssetChanges(this.#config.projectRoot, this.#config.library, library),
2350
+ this.#duplicateDetector.find(library, this.#config.rawDir),
2351
+ mapConcurrent(assetIds, 8, (assetId) => this.#proxyState(assetId, library.assets[assetId], delivered))
2352
+ ]);
2353
+ this.#proxyInfoCache.retain(delivered);
2254
2354
  const passiveManifestsByAsset = /* @__PURE__ */ new Map();
2255
2355
  for (const manifestName of Object.keys(library.manifests).sort(compareCodeUnits)) for (const passiveMember of membershipByManifest[manifestName].passiveMembers) {
2256
2356
  const passiveManifests = passiveManifestsByAsset.get(passiveMember.assetId) ?? [];
@@ -2272,24 +2372,14 @@ var FundusOperations = class {
2272
2372
  const requiredByAsset = /* @__PURE__ */ new Map();
2273
2373
  for (const dependency of this.#config.dependencies) requiredByAsset.set(dependency.id, [...dependency.sources]);
2274
2374
  const assets = [];
2275
- for (const assetId of Object.keys(library.assets).sort(compareCodeUnits)) {
2375
+ for (const [index, assetId] of assetIds.entries()) {
2276
2376
  const record = library.assets[assetId];
2277
2377
  const warnings = [];
2278
2378
  for (const issue of issues) if (issue.assetId === assetId) warnings.push(issue.message);
2279
2379
  if (record.manifests.length === 0 && !delivered.has(assetId)) warnings.push("In no manifest and not referenced by any delivered asset — nothing is processed or generated for it.");
2280
2380
  if (record.importSource && !this.#importers.has(record.importSource.importer)) warnings.push(`Importer "${record.importSource.importer}" is unavailable; the local raw file remains usable.`);
2281
- let proxy = null;
2282
- if (delivered.has(assetId)) try {
2283
- const currentProxy = await readCurrentProxy(assetId, record, this.#config, this.#registry);
2284
- if (currentProxy) proxy = {
2285
- url: `/files/proxy/${encodeRelativePathForUrl(currentProxy.relativePath)}`,
2286
- upToDate: true,
2287
- ...currentProxy
2288
- };
2289
- else warnings.push("Proxy is stale or missing — it will be (re)processed on the next save.");
2290
- } catch (cause) {
2291
- warnings.push(cause instanceof Error ? cause.message : String(cause));
2292
- }
2381
+ const { proxy, warning: proxyWarning } = proxies[index];
2382
+ if (proxyWarning) warnings.push(proxyWarning);
2293
2383
  assets.push({
2294
2384
  id: assetId,
2295
2385
  type: record.type,
@@ -2514,4 +2604,4 @@ async function createFundusContext() {
2514
2604
  }
2515
2605
 
2516
2606
  export { getFundusContext as g, initializeFundusContext as i };
2517
- //# sourceMappingURL=context.js-BZSZNuAd.js.map
2607
+ //# sourceMappingURL=context.js-BR2IRl9z.js.map