fundus 0.0.2 → 0.0.4

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 (303) hide show
  1. package/README.md +73 -0
  2. package/build/client/_app/immutable/assets/0.DLhIsYA_.css.br +0 -0
  3. package/build/client/_app/immutable/assets/0.DLhIsYA_.css.gz +0 -0
  4. package/build/client/_app/immutable/assets/2.ohi-TClG.css +1 -0
  5. package/build/client/_app/immutable/assets/2.ohi-TClG.css.br +0 -0
  6. package/build/client/_app/immutable/assets/2.ohi-TClG.css.gz +0 -0
  7. package/build/client/_app/immutable/assets/3.JwgtcTEd.css +1 -0
  8. package/build/client/_app/immutable/assets/3.JwgtcTEd.css.br +0 -0
  9. package/build/client/_app/immutable/assets/3.JwgtcTEd.css.gz +0 -0
  10. package/build/client/_app/immutable/assets/4.p004hmEN.css +1 -0
  11. package/build/client/_app/immutable/assets/4.p004hmEN.css.br +0 -0
  12. package/build/client/_app/immutable/assets/4.p004hmEN.css.gz +0 -0
  13. package/build/client/_app/immutable/assets/ConfirmDialog.BdKlitwi.css +1 -0
  14. package/build/client/_app/immutable/assets/ConfirmDialog.BdKlitwi.css.br +0 -0
  15. package/build/client/_app/immutable/assets/ConfirmDialog.BdKlitwi.css.gz +0 -0
  16. package/build/client/_app/immutable/assets/LibraryContextMenu.CMefGNE2.css +1 -0
  17. package/build/client/_app/immutable/assets/LibraryContextMenu.CMefGNE2.css.br +0 -0
  18. package/build/client/_app/immutable/assets/LibraryContextMenu.CMefGNE2.css.gz +0 -0
  19. package/build/client/_app/immutable/chunks/Bjy-W4x2.js.br +0 -0
  20. package/build/client/_app/immutable/chunks/Bjy-W4x2.js.gz +0 -0
  21. package/build/client/_app/immutable/chunks/CNRz3sSw.js.br +0 -0
  22. package/build/client/_app/immutable/chunks/CNRz3sSw.js.gz +0 -0
  23. package/build/client/_app/immutable/chunks/CO4RBJfa.js.br +0 -0
  24. package/build/client/_app/immutable/chunks/CO4RBJfa.js.gz +0 -0
  25. package/build/client/_app/immutable/chunks/DOpBpjxS.js +108 -0
  26. package/build/client/_app/immutable/chunks/DOpBpjxS.js.br +0 -0
  27. package/build/client/_app/immutable/chunks/DOpBpjxS.js.gz +0 -0
  28. package/{dist/editor/_app/immutable/chunks/BfPE5wdt.js → build/client/_app/immutable/chunks/DVEQFclp.js} +1 -1
  29. package/build/client/_app/immutable/chunks/DVEQFclp.js.br +1 -0
  30. package/build/client/_app/immutable/chunks/DVEQFclp.js.gz +0 -0
  31. package/{dist/editor/_app/immutable/chunks/DjvOiDmq.js → build/client/_app/immutable/chunks/DiFoWL2c.js} +1 -1
  32. package/build/client/_app/immutable/chunks/DiFoWL2c.js.br +0 -0
  33. package/build/client/_app/immutable/chunks/DiFoWL2c.js.gz +0 -0
  34. package/build/client/_app/immutable/chunks/DkADHpZF.js +1 -0
  35. package/build/client/_app/immutable/chunks/DkADHpZF.js.br +0 -0
  36. package/build/client/_app/immutable/chunks/DkADHpZF.js.gz +0 -0
  37. package/build/client/_app/immutable/chunks/xihTtKlq.js.br +1 -0
  38. package/build/client/_app/immutable/chunks/xihTtKlq.js.gz +0 -0
  39. package/{dist/editor/_app/immutable/entry/app.BkqbfI8n.js → build/client/_app/immutable/entry/app.CKgtYXQb.js} +2 -2
  40. package/build/client/_app/immutable/entry/app.CKgtYXQb.js.br +0 -0
  41. package/build/client/_app/immutable/entry/app.CKgtYXQb.js.gz +0 -0
  42. package/build/client/_app/immutable/entry/start.CYZu5qE1.js +1 -0
  43. package/build/client/_app/immutable/entry/start.CYZu5qE1.js.br +0 -0
  44. package/build/client/_app/immutable/entry/start.CYZu5qE1.js.gz +0 -0
  45. package/{dist/editor/_app/immutable/nodes/0.xdMI5GEU.js → build/client/_app/immutable/nodes/0.I_1SApYQ.js} +1 -1
  46. package/build/client/_app/immutable/nodes/0.I_1SApYQ.js.br +0 -0
  47. package/build/client/_app/immutable/nodes/0.I_1SApYQ.js.gz +0 -0
  48. package/{dist/editor/_app/immutable/nodes/1.D9p2tfoJ.js → build/client/_app/immutable/nodes/1.v6eUTnWq.js} +1 -1
  49. package/build/client/_app/immutable/nodes/1.v6eUTnWq.js.br +2 -0
  50. package/build/client/_app/immutable/nodes/1.v6eUTnWq.js.gz +0 -0
  51. package/build/client/_app/immutable/nodes/2.DoA7Dfl-.js +3 -0
  52. package/build/client/_app/immutable/nodes/2.DoA7Dfl-.js.br +0 -0
  53. package/build/client/_app/immutable/nodes/2.DoA7Dfl-.js.gz +0 -0
  54. package/build/client/_app/immutable/nodes/3.C-DO70Bs.js +1 -0
  55. package/build/client/_app/immutable/nodes/3.C-DO70Bs.js.br +0 -0
  56. package/build/client/_app/immutable/nodes/3.C-DO70Bs.js.gz +0 -0
  57. package/build/client/_app/immutable/nodes/4.CALOuSyz.js +2 -0
  58. package/build/client/_app/immutable/nodes/4.CALOuSyz.js.br +0 -0
  59. package/build/client/_app/immutable/nodes/4.CALOuSyz.js.gz +0 -0
  60. package/build/client/_app/version.json +1 -0
  61. package/build/client/_app/version.json.br +0 -0
  62. package/build/client/_app/version.json.gz +0 -0
  63. package/build/env.js +100 -0
  64. package/build/env.js.map +1 -0
  65. package/build/handler.js +22 -0
  66. package/build/handler.js.map +1 -0
  67. package/build/index.js +145 -0
  68. package/build/index.js.map +1 -0
  69. package/build/server/chunks/chunks/context.js-BUZqFfWG.js +429 -0
  70. package/build/server/chunks/chunks/context.js-BUZqFfWG.js.map +1 -0
  71. package/build/server/chunks/chunks/core.js-xfrkaQpS.js +458 -0
  72. package/build/server/chunks/chunks/core.js-xfrkaQpS.js.map +1 -0
  73. package/build/server/chunks/chunks/env.js-l0sNRNKZ.js +2 -0
  74. package/build/server/chunks/chunks/env.js-l0sNRNKZ.js.map +1 -0
  75. package/build/server/chunks/chunks/exports.js-C0rwMMtk.js +152 -0
  76. package/build/server/chunks/chunks/exports.js-C0rwMMtk.js.map +1 -0
  77. package/build/server/chunks/chunks/folder-path.js-ytx9ucgg.js +64 -0
  78. package/build/server/chunks/chunks/folder-path.js-ytx9ucgg.js.map +1 -0
  79. package/build/server/chunks/chunks/http.js-DvopzwKh.js +100 -0
  80. package/build/server/chunks/chunks/http.js-DvopzwKh.js.map +1 -0
  81. package/build/server/chunks/chunks/internal.js-DGo2jPcg.js +5753 -0
  82. package/build/server/chunks/chunks/internal.js-DGo2jPcg.js.map +1 -0
  83. package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js +22 -0
  84. package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -0
  85. package/{dist/operations-DYM-5KVl.js → build/server/chunks/chunks/library-store.js-ZLudCJlT.js} +463 -492
  86. package/build/server/chunks/chunks/library-store.js-ZLudCJlT.js.map +1 -0
  87. package/build/server/chunks/chunks/manifest-appearance.js-DTk355LQ.js +146 -0
  88. package/build/server/chunks/chunks/manifest-appearance.js-DTk355LQ.js.map +1 -0
  89. package/build/server/chunks/chunks/routing.js-y-tryuip.js +213 -0
  90. package/build/server/chunks/chunks/routing.js-y-tryuip.js.map +1 -0
  91. package/build/server/chunks/chunks/shared.js-B1gC9MiJ.js +255 -0
  92. package/build/server/chunks/chunks/shared.js-B1gC9MiJ.js.map +1 -0
  93. package/build/server/chunks/chunks/utils.js-DnEJ3UjO.js +1048 -0
  94. package/build/server/chunks/chunks/utils.js-DnEJ3UjO.js.map +1 -0
  95. package/build/server/chunks/entries/endpoints/api/_...path_/_server.ts.js-Cq5gXVQT.js +27 -0
  96. package/build/server/chunks/entries/endpoints/api/_...path_/_server.ts.js-Cq5gXVQT.js.map +1 -0
  97. package/build/server/chunks/entries/endpoints/api/assets/_id_/_server.ts.js-RXbedi8q.js +24 -0
  98. package/build/server/chunks/entries/endpoints/api/assets/_id_/_server.ts.js-RXbedi8q.js.map +1 -0
  99. package/build/server/chunks/entries/endpoints/api/assets/_server.ts.js-D7Qae9vU.js +45 -0
  100. package/build/server/chunks/entries/endpoints/api/assets/_server.ts.js-D7Qae9vU.js.map +1 -0
  101. package/build/server/chunks/entries/endpoints/api/assets/delete/_server.ts.js-DtO20kgB.js +31 -0
  102. package/build/server/chunks/entries/endpoints/api/assets/delete/_server.ts.js-DtO20kgB.js.map +1 -0
  103. package/build/server/chunks/entries/endpoints/api/assets/move/_server.ts.js-BUebPbd5.js +31 -0
  104. package/build/server/chunks/entries/endpoints/api/assets/move/_server.ts.js-BUebPbd5.js.map +1 -0
  105. package/build/server/chunks/entries/endpoints/api/folders/_path_/_server.ts.js-BjT2qPMT.js +38 -0
  106. package/build/server/chunks/entries/endpoints/api/folders/_path_/_server.ts.js-BjT2qPMT.js.map +1 -0
  107. package/build/server/chunks/entries/endpoints/api/folders/_server.ts.js-DYRLsoT7.js +31 -0
  108. package/build/server/chunks/entries/endpoints/api/folders/_server.ts.js-DYRLsoT7.js.map +1 -0
  109. package/build/server/chunks/entries/endpoints/api/manifests/_name_/_server.ts.js-BbN2fGNN.js +24 -0
  110. package/build/server/chunks/entries/endpoints/api/manifests/_name_/_server.ts.js-BbN2fGNN.js.map +1 -0
  111. package/build/server/chunks/entries/endpoints/api/manifests/_server.ts.js-b_MKZ41b.js +31 -0
  112. package/build/server/chunks/entries/endpoints/api/manifests/_server.ts.js-b_MKZ41b.js.map +1 -0
  113. package/build/server/chunks/entries/endpoints/api/state/_server.ts.js-evEfMpvn.js +24 -0
  114. package/build/server/chunks/entries/endpoints/api/state/_server.ts.js-evEfMpvn.js.map +1 -0
  115. package/build/server/chunks/entries/endpoints/files/_...path_/_server.ts.js-C04XE_1w.js +27 -0
  116. package/build/server/chunks/entries/endpoints/files/_...path_/_server.ts.js-C04XE_1w.js.map +1 -0
  117. package/build/server/chunks/entries/endpoints/files/proxy/_...path_/_server.ts.js-DB8TdoEv.js +24 -0
  118. package/build/server/chunks/entries/endpoints/files/proxy/_...path_/_server.ts.js-DB8TdoEv.js.map +1 -0
  119. package/build/server/chunks/entries/endpoints/files/raw/_...path_/_server.ts.js-BrpaijZO.js +24 -0
  120. package/build/server/chunks/entries/endpoints/files/raw/_...path_/_server.ts.js-BrpaijZO.js.map +1 -0
  121. package/build/server/chunks/entries/hooks.server.js-BJJwZW_I.js +23 -0
  122. package/build/server/chunks/entries/hooks.server.js-BJJwZW_I.js.map +1 -0
  123. package/build/server/chunks/handler-DnbS2t1B.js +1475 -0
  124. package/build/server/chunks/handler-DnbS2t1B.js.map +1 -0
  125. package/build/server/chunks/index.js-g77q3Boj.js +3789 -0
  126. package/build/server/chunks/index.js-g77q3Boj.js.map +1 -0
  127. package/build/server/chunks/manifest.js-qmEXbstS.js +149 -0
  128. package/build/server/chunks/manifest.js-qmEXbstS.js.map +1 -0
  129. package/build/server/chunks/nodes/0.js-Bk6IZ-vD.js +11 -0
  130. package/build/server/chunks/nodes/0.js-Bk6IZ-vD.js.map +1 -0
  131. package/build/server/chunks/nodes/1.js-H-qwo4GJ.js +7 -0
  132. package/build/server/chunks/nodes/1.js-H-qwo4GJ.js.map +1 -0
  133. package/build/server/chunks/nodes/2.js-DRpXVLwp.js +7 -0
  134. package/build/server/chunks/nodes/2.js-DRpXVLwp.js.map +1 -0
  135. package/build/server/chunks/nodes/3.js-CDEzNFeU.js +7 -0
  136. package/build/server/chunks/nodes/3.js-CDEzNFeU.js.map +1 -0
  137. package/build/server/chunks/nodes/4.js-BKL7LSSm.js +7 -0
  138. package/build/server/chunks/nodes/4.js-BKL7LSSm.js.map +1 -0
  139. package/build/shims.js +33 -0
  140. package/build/shims.js.map +1 -0
  141. package/dist/cli.d.ts +2 -1
  142. package/dist/cli.js +116 -1336
  143. package/dist/config.d.ts +3 -2
  144. package/dist/config.js +2 -2
  145. package/dist/core/api-types.d.ts +141 -0
  146. package/dist/core/api-types.js +1 -0
  147. package/dist/core/asset-id.d.ts +28 -0
  148. package/dist/core/asset-id.js +59 -0
  149. package/dist/core/asset-reference.d.ts +23 -0
  150. package/dist/core/asset-reference.js +15 -0
  151. package/dist/core/canonicalize.d.ts +9 -0
  152. package/dist/core/canonicalize.js +36 -0
  153. package/dist/core/chroma-key.d.ts +30 -0
  154. package/dist/core/chroma-key.js +55 -0
  155. package/dist/core/config.d.ts +35 -0
  156. package/dist/core/config.js +4 -0
  157. package/dist/core/folder-path.d.ts +19 -0
  158. package/dist/core/folder-path.js +86 -0
  159. package/dist/core/index.d.ts +33 -499
  160. package/dist/core/index.js +17 -962
  161. package/dist/core/ingest.d.ts +24 -0
  162. package/dist/core/ingest.js +42 -0
  163. package/dist/core/library.d.ts +54 -0
  164. package/dist/core/library.js +138 -0
  165. package/dist/core/manifest-appearance.d.ts +35 -0
  166. package/dist/core/manifest-appearance.js +123 -0
  167. package/dist/core/manifest-entry.d.ts +104 -0
  168. package/dist/core/manifest-entry.js +1 -0
  169. package/dist/core/manifest-membership.d.ts +56 -0
  170. package/dist/core/manifest-membership.js +54 -0
  171. package/dist/core/plugins/audio.d.ts +26 -0
  172. package/dist/core/plugins/audio.js +44 -0
  173. package/dist/core/plugins/chroma-key-video.d.ts +29 -0
  174. package/dist/core/plugins/chroma-key-video.js +69 -0
  175. package/dist/core/plugins/contract.d.ts +35 -0
  176. package/dist/core/plugins/contract.js +1 -0
  177. package/dist/core/plugins/image.d.ts +30 -0
  178. package/dist/core/plugins/image.js +45 -0
  179. package/dist/core/plugins/registry.d.ts +16 -0
  180. package/dist/core/plugins/registry.js +52 -0
  181. package/dist/core/plugins/slice.d.ts +22 -0
  182. package/dist/core/plugins/slice.js +60 -0
  183. package/dist/core/plugins/video.d.ts +45 -0
  184. package/dist/core/plugins/video.js +77 -0
  185. package/dist/core/reference-graph.d.ts +41 -0
  186. package/dist/core/reference-graph.js +138 -0
  187. package/dist/core/slice-data.d.ts +61 -0
  188. package/dist/core/slice-data.js +49 -0
  189. package/dist/runtime/chroma-key-gl.d.ts +40 -22
  190. package/dist/runtime/chroma-key-gl.js +189 -183
  191. package/dist/runtime/components/ChromaKeyVideo.svelte +3 -3
  192. package/dist/runtime/components/ChromaKeyVideo.svelte.d.ts +21 -0
  193. package/dist/runtime/components/Image.svelte +1 -1
  194. package/dist/runtime/components/Image.svelte.d.ts +9 -0
  195. package/dist/runtime/components/Slice.svelte +1 -1
  196. package/dist/runtime/components/Slice.svelte.d.ts +19 -0
  197. package/dist/runtime/components/SliceCanvas.svelte +3 -3
  198. package/dist/runtime/components/SliceCanvas.svelte.d.ts +10 -0
  199. package/dist/runtime/components/SliceDom.svelte +3 -3
  200. package/dist/runtime/components/SliceDom.svelte.d.ts +10 -0
  201. package/dist/runtime/components/Video.svelte +2 -2
  202. package/dist/runtime/components/Video.svelte.d.ts +18 -0
  203. package/dist/runtime/geometry.d.ts +55 -35
  204. package/dist/runtime/geometry.js +186 -191
  205. package/dist/runtime/index.d.ts +9 -9
  206. package/dist/runtime/index.js +9 -9
  207. package/dist/runtime/kind-handlers.d.ts +33 -30
  208. package/dist/runtime/kind-handlers.js +85 -67
  209. package/dist/runtime/manifest.d.ts +53 -47
  210. package/dist/runtime/manifest.js +133 -113
  211. package/dist/runtime/observe-border-box-size.d.ts +1 -4
  212. package/dist/runtime/observe-border-box-size.js +9 -10
  213. package/dist/runtime/preload-registry.d.ts +22 -8
  214. package/dist/runtime/preload-registry.js +65 -62
  215. package/dist/server/build.d.ts +8 -0
  216. package/dist/server/build.js +25 -0
  217. package/dist/server/check.d.ts +24 -0
  218. package/dist/server/check.js +199 -0
  219. package/dist/server/cli-commands.d.ts +25 -0
  220. package/dist/server/cli-commands.js +1178 -0
  221. package/dist/server/cli-init.d.ts +3 -0
  222. package/dist/server/cli-init.js +53 -0
  223. package/dist/server/cli-io.d.ts +46 -0
  224. package/dist/server/cli-io.js +105 -0
  225. package/dist/server/codegen.d.ts +58 -0
  226. package/dist/server/codegen.js +185 -0
  227. package/dist/server/config-loader.d.ts +35 -0
  228. package/dist/server/config-loader.js +79 -0
  229. package/dist/server/context.d.ts +8 -0
  230. package/dist/server/context.js +19 -0
  231. package/dist/server/folder-filesystem.d.ts +7 -0
  232. package/dist/server/folder-filesystem.js +39 -0
  233. package/dist/server/http.d.ts +12 -0
  234. package/dist/server/http.js +100 -0
  235. package/dist/server/index.d.ts +17 -0
  236. package/dist/server/index.js +9 -0
  237. package/dist/server/job-hash.d.ts +10 -0
  238. package/dist/server/job-hash.js +23 -0
  239. package/dist/server/library-store.d.ts +82 -0
  240. package/dist/server/library-store.js +763 -0
  241. package/dist/server/operations.d.ts +87 -0
  242. package/dist/server/operations.js +427 -0
  243. package/dist/server/plugins/audio.d.ts +8 -0
  244. package/dist/server/plugins/audio.js +41 -0
  245. package/dist/server/plugins/chroma-key-video.d.ts +9 -0
  246. package/dist/server/plugins/chroma-key-video.js +40 -0
  247. package/dist/server/plugins/config.d.ts +13 -0
  248. package/dist/server/plugins/config.js +32 -0
  249. package/dist/server/plugins/contract.d.ts +114 -0
  250. package/dist/server/plugins/contract.js +16 -0
  251. package/dist/server/plugins/image.d.ts +9 -0
  252. package/dist/server/plugins/image.js +43 -0
  253. package/dist/server/plugins/slice.d.ts +15 -0
  254. package/dist/server/plugins/slice.js +76 -0
  255. package/dist/server/plugins/video.d.ts +7 -0
  256. package/dist/server/plugins/video.js +54 -0
  257. package/dist/server/plugins.d.ts +23 -0
  258. package/dist/server/plugins.js +35 -0
  259. package/dist/server/processing/audio-processing.d.ts +17 -0
  260. package/dist/server/processing/audio-processing.js +46 -0
  261. package/dist/server/processing/ffmpeg.d.ts +9 -0
  262. package/dist/server/processing/ffmpeg.js +50 -0
  263. package/dist/server/processing/image-processing.d.ts +16 -0
  264. package/dist/server/processing/image-processing.js +26 -0
  265. package/dist/server/processing/media-probe.d.ts +15 -0
  266. package/dist/server/processing/media-probe.js +27 -0
  267. package/dist/server/processing/processor.d.ts +50 -0
  268. package/dist/server/processing/processor.js +158 -0
  269. package/dist/server/processing/video-processing.d.ts +35 -0
  270. package/dist/server/processing/video-processing.js +87 -0
  271. package/dist/server/server.d.ts +13 -0
  272. package/dist/server/server.js +57 -0
  273. package/dist/server/start.d.ts +13 -0
  274. package/dist/server/start.js +80 -0
  275. package/package.json +31 -16
  276. package/dist/build-CZYFLLvl.js +0 -191
  277. package/dist/core/image-Dqmz8FXS.js +0 -54
  278. package/dist/core/reference-graph-CjuHbLDw.d.ts +0 -280
  279. package/dist/core/testing.d.ts +0 -27
  280. package/dist/core/testing.js +0 -80
  281. package/dist/editor/200.html +0 -37
  282. package/dist/editor/_app/immutable/assets/2.DIbbW7U1.css +0 -1
  283. package/dist/editor/_app/immutable/assets/3.C-9vFQ9A.css +0 -1
  284. package/dist/editor/_app/immutable/assets/4.BS8ElpOV.css +0 -1
  285. package/dist/editor/_app/immutable/assets/ConfirmDialog.CHEISE-L.css +0 -1
  286. package/dist/editor/_app/immutable/assets/LibraryContextMenu.CDjCmdV-.css +0 -1
  287. package/dist/editor/_app/immutable/chunks/Cx6qtxJg.js +0 -1
  288. package/dist/editor/_app/immutable/chunks/DjdrdRzT.js +0 -1
  289. package/dist/editor/_app/immutable/chunks/n7mvYc42.js +0 -5
  290. package/dist/editor/_app/immutable/entry/start.C8HHOLly.js +0 -1
  291. package/dist/editor/_app/immutable/nodes/2.BrA0Hyzu.js +0 -3
  292. package/dist/editor/_app/immutable/nodes/3.WO7tZH_d.js +0 -104
  293. package/dist/editor/_app/immutable/nodes/4.DQtx17aW.js +0 -2
  294. package/dist/editor/_app/version.json +0 -1
  295. package/dist/index.d.ts +0 -370
  296. package/dist/index.js +0 -4
  297. package/dist/start-Bhnqt9Dc.js +0 -279
  298. package/dist/start-D2IXOrni.js +0 -2
  299. /package/{dist/editor → build/client}/_app/immutable/assets/0.DLhIsYA_.css +0 -0
  300. /package/{dist/editor → build/client}/_app/immutable/chunks/Bjy-W4x2.js +0 -0
  301. /package/{dist/editor → build/client}/_app/immutable/chunks/CNRz3sSw.js +0 -0
  302. /package/{dist/editor → build/client}/_app/immutable/chunks/CO4RBJfa.js +0 -0
  303. /package/{dist/editor → build/client}/_app/immutable/chunks/xihTtKlq.js +0 -0
@@ -1,46 +1,49 @@
1
- import { AudioManifestEntry, PreloadOptions } from "#fundus/core";
2
-
3
- //#region src/kind-handlers.d.ts
1
+ /**
2
+ * The runtime part of the type-plugin contract: per-kind preload
3
+ * strategy and its inverse release strategy. Each first-party kind registers
4
+ * a handler that knows how its delivered file is loaded — image-backed kinds
5
+ * fetch + optionally decode, media kinds (video/audio) fetch fully and mint
6
+ * an object URL — and how what it loaded is disposed (revoke the object URL;
7
+ * image-backed kinds have nothing to dispose). An unknown kind falls back to
8
+ * a plain full fetch: no decode, no retention.
9
+ *
10
+ * Handlers are pure strategy: refcounting, cross-manifest dedup, and
11
+ * in-flight bookkeeping live in the module-wide registry
12
+ * (preload-registry.ts); kind-agnostic orchestration lives in `Manifest`.
13
+ */
14
+ import type { AudioManifestEntry, PreloadOptions } from '../core/index.js';
4
15
  /** The playable URL hosts feed to their own audio engine. */
5
- declare function audioSourceOf(entry: AudioManifestEntry): string;
16
+ export declare function audioSourceOf(entry: AudioManifestEntry): string;
6
17
  /**
7
18
  * What a handler's `preload` acquired and its `release` must dispose. For
8
19
  * retained media kinds this is the minted object URL; cache-backed kinds
9
20
  * (image, slice, unknown) hold no disposable resources.
10
21
  */
11
- interface KindHandlerResources {
12
- /** Object URL minted over the fully fetched file (retained media kinds). */
13
- objectUrl?: string;
22
+ export interface KindHandlerResources {
23
+ /** Object URL minted over the fully fetched file (retained media kinds). */
24
+ objectUrl?: string;
14
25
  }
15
26
  /** How one asset kind preloads — and releases — its delivered file. */
16
- interface KindRuntimeHandler {
17
- /**
18
- * Fully load one source of this kind — the promise resolves only once the
19
- * file is completely transferred (plus the kind's strategy: decoded /
20
- * retained as an object URL) — and return the resources `release` disposes.
21
- */
22
- preload(url: string, options: PreloadOptions): Promise<KindHandlerResources>;
23
- /**
24
- * The inverse of `preload`: dispose the resources it returned (revoke the
25
- * object URL). Omitted = the kind acquires nothing disposable.
26
- */
27
- release?(resources: KindHandlerResources): void;
27
+ export interface KindRuntimeHandler {
28
+ /**
29
+ * Fully load one source of this kind — the promise resolves only once the
30
+ * file is completely transferred (plus the kind's strategy: decoded /
31
+ * retained as an object URL) — and return the resources `release` disposes.
32
+ */
33
+ preload(url: string, options: PreloadOptions): Promise<KindHandlerResources>;
34
+ /**
35
+ * The inverse of `preload`: dispose the resources it returned (revoke the
36
+ * object URL). Omitted = the kind acquires nothing disposable.
37
+ */
38
+ release?(resources: KindHandlerResources): void;
28
39
  }
29
- /**
30
- * Entry kinds whose delivered file is retained as an object URL by
31
- * `preload()` while held. A chroma-key-video's own `src` is a video file, so
32
- * it retains too; its inlined mask/fallback entries are `image` kind and
33
- * follow the image handler via the source walk.
34
- */
35
- declare const RETAINED_KINDS: ReadonlySet<string>;
40
+ export declare const RETAINED_KINDS: ReadonlySet<string>;
36
41
  /**
37
42
  * Whether a source of `kind` decodes under the given per-kind preload options
38
43
  * (options are namespaced per plugin type, like `plugins.<type>` in
39
44
  * the config). Image-backed kinds decode by default; each kind opts out
40
45
  * independently (`{ image: { decode: false } }` leaves slices decoding).
41
46
  */
42
- declare function shouldDecode(kind: string, options: PreloadOptions): boolean;
47
+ export declare function shouldDecode(kind: string, options: PreloadOptions): boolean;
43
48
  /** The runtime handler owning `kind`'s preload/release strategy (fallback for unknown kinds). */
44
- declare function runtimeHandlerFor(kind: string): KindRuntimeHandler;
45
- //#endregion
46
- export { KindHandlerResources, KindRuntimeHandler, RETAINED_KINDS, audioSourceOf, runtimeHandlerFor, shouldDecode };
49
+ export declare function runtimeHandlerFor(kind: string): KindRuntimeHandler;
@@ -1,86 +1,104 @@
1
- import { resolveRetainedSource } from "./preload-registry.js";
2
- //#region src/kind-handlers.ts
1
+ import { plugins } from '../core/plugins/registry.js';
2
+ import { resolveRetainedSource } from './preload-registry.js';
3
3
  /** The playable URL hosts feed to their own audio engine. */
4
- function audioSourceOf(entry) {
5
- return resolveRetainedSource(entry.src);
4
+ export function audioSourceOf(entry) {
5
+ return resolveRetainedSource(entry.src);
6
6
  }
7
7
  /** Entry kinds whose delivered file is an image the browser can pre-decode. */
8
- const IMAGE_BACKED_KINDS = new Set(["image", "slice"]);
8
+ const IMAGE_BACKED_KINDS = new Set(['image', 'slice']);
9
9
  /**
10
- * Entry kinds whose delivered file is retained as an object URL by
11
- * `preload()` while held. A chroma-key-video's own `src` is a video file, so
12
- * it retains too; its inlined mask/fallback entries are `image` kind and
13
- * follow the image handler via the source walk.
14
- */
15
- const RETAINED_KINDS = new Set([
16
- "video",
17
- "chroma-key-video",
18
- "audio"
10
+ * Entry kinds whose delivered file is retained as an object URL by
11
+ * `preload()` while held. A chroma-key-video's own `src` is a video file, so
12
+ * it retains too; its inlined mask/fallback entries are `image` kind and
13
+ * follow the image handler via the source walk.
14
+ */
15
+ const RETAINED_KIND_CATALOGUE = new Set([
16
+ 'video',
17
+ 'chroma-key-video',
18
+ 'audio'
19
19
  ]);
20
+ export const RETAINED_KINDS = new Set([...RETAINED_KIND_CATALOGUE].filter((kind) => plugins.has(kind)));
20
21
  /**
21
- * Whether a source of `kind` decodes under the given per-kind preload options
22
- * (options are namespaced per plugin type, like `plugins.<type>` in
23
- * the config). Image-backed kinds decode by default; each kind opts out
24
- * independently (`{ image: { decode: false } }` leaves slices decoding).
25
- */
26
- function shouldDecode(kind, options) {
27
- if (!IMAGE_BACKED_KINDS.has(kind)) return false;
28
- return options[kind]?.decode ?? true;
22
+ * Whether a source of `kind` decodes under the given per-kind preload options
23
+ * (options are namespaced per plugin type, like `plugins.<type>` in
24
+ * the config). Image-backed kinds decode by default; each kind opts out
25
+ * independently (`{ image: { decode: false } }` leaves slices decoding).
26
+ */
27
+ export function shouldDecode(kind, options) {
28
+ if (!IMAGE_BACKED_KINDS.has(kind))
29
+ return false;
30
+ // The image-backed check above narrows the kind — only these carry `decode`.
31
+ const kindOptions = options[kind];
32
+ return kindOptions?.decode ?? true;
29
33
  }
30
34
  /** Fetch a source, throwing a uniform error on a non-OK response. */
31
35
  async function fetchCompletely(url) {
32
- const response = await fetch(url);
33
- if (!response.ok) throw new Error(`Preloading "${url}" failed: ${response.status} ${response.statusText}.`);
34
- return response;
36
+ const response = await fetch(url);
37
+ if (!response.ok) {
38
+ throw new Error(`Preloading "${url}" failed: ${response.status} ${response.statusText}.`);
39
+ }
40
+ return response;
35
41
  }
36
42
  /**
37
- * The image-backed strategy (image, slice): fetch the full file, then decode
38
- * by default. Decoding goes via an HTMLImageElement where a DOM exists (the
39
- * browser serves the bytes from cache); headless environments (Node tests,
40
- * SSR) skip decoding. Nothing to release — the browser cache owns the bytes.
41
- */
43
+ * The image-backed strategy (image, slice): fetch the full file, then decode
44
+ * by default. Decoding goes via an HTMLImageElement where a DOM exists (the
45
+ * browser serves the bytes from cache); headless environments (Node tests,
46
+ * SSR) skip decoding. Nothing to release — the browser cache owns the bytes.
47
+ */
42
48
  function imageBackedHandler(kind) {
43
- return { async preload(url, options) {
44
- await (await fetchCompletely(url)).arrayBuffer();
45
- if (shouldDecode(kind, options) && typeof globalThis.Image === "function") {
46
- const image = new globalThis.Image();
47
- image.src = url;
48
- await image.decode();
49
- }
50
- return {};
51
- } };
49
+ return {
50
+ async preload(url, options) {
51
+ const response = await fetchCompletely(url);
52
+ // Read the body fully so the file is actually transferred (and
53
+ // cached), not just the response headers.
54
+ await response.arrayBuffer();
55
+ if (shouldDecode(kind, options) && typeof globalThis.Image === 'function') {
56
+ const image = new globalThis.Image();
57
+ image.src = url;
58
+ await image.decode();
59
+ }
60
+ return {};
61
+ }
62
+ };
52
63
  }
53
64
  /**
54
- * The retained-media strategy (video, chroma-key-video, audio): fetch the
55
- * full file and retain it as an object URL so later playback does not touch
56
- * the network. Release revokes the URL, freeing the
57
- * retained memory. Environments without object URLs (SSR) still fetch fully
58
- * but retain nothing.
59
- */
65
+ * The retained-media strategy (video, chroma-key-video, audio): fetch the
66
+ * full file and retain it as an object URL so later playback does not touch
67
+ * the network. Release revokes the URL, freeing the
68
+ * retained memory. Environments without object URLs (SSR) still fetch fully
69
+ * but retain nothing.
70
+ */
60
71
  const retainedMediaHandler = {
61
- async preload(url) {
62
- const blob = await (await fetchCompletely(url)).blob();
63
- if (typeof URL.createObjectURL !== "function") return {};
64
- return { objectUrl: URL.createObjectURL(blob) };
65
- },
66
- release(resources) {
67
- if (resources.objectUrl !== void 0 && typeof URL.revokeObjectURL === "function") URL.revokeObjectURL(resources.objectUrl);
68
- }
72
+ async preload(url) {
73
+ const response = await fetchCompletely(url);
74
+ const blob = await response.blob();
75
+ if (typeof URL.createObjectURL !== 'function')
76
+ return {};
77
+ return { objectUrl: URL.createObjectURL(blob) };
78
+ },
79
+ release(resources) {
80
+ if (resources.objectUrl !== undefined && typeof URL.revokeObjectURL === 'function') {
81
+ URL.revokeObjectURL(resources.objectUrl);
82
+ }
83
+ }
69
84
  };
70
85
  /** Fallback for kinds without a registered handler: plain full fetch. */
71
- const unknownKindHandler = { async preload(url) {
72
- await (await fetchCompletely(url)).arrayBuffer();
73
- return {};
74
- } };
75
- /** The statically registered first-party handlers. */
76
- const handlerByKind = new Map([
77
- ["image", imageBackedHandler("image")],
78
- ["slice", imageBackedHandler("slice")],
79
- ...[...RETAINED_KINDS].map((kind) => [kind, retainedMediaHandler])
80
- ]);
86
+ const unknownKindHandler = {
87
+ async preload(url) {
88
+ await (await fetchCompletely(url)).arrayBuffer();
89
+ return {};
90
+ }
91
+ };
92
+ const runtimeHandlerCatalogue = {
93
+ image: imageBackedHandler('image'),
94
+ slice: imageBackedHandler('slice'),
95
+ video: retainedMediaHandler,
96
+ 'chroma-key-video': retainedMediaHandler,
97
+ audio: retainedMediaHandler
98
+ };
99
+ /** The runtime facets of the centrally registered plugins. */
100
+ const handlerByKind = new Map(Object.entries(plugins.project(runtimeHandlerCatalogue, 'runtime handler')));
81
101
  /** The runtime handler owning `kind`'s preload/release strategy (fallback for unknown kinds). */
82
- function runtimeHandlerFor(kind) {
83
- return handlerByKind.get(kind) ?? unknownKindHandler;
102
+ export function runtimeHandlerFor(kind) {
103
+ return handlerByKind.get(kind) ?? unknownKindHandler;
84
104
  }
85
- //#endregion
86
- export { RETAINED_KINDS, audioSourceOf, runtimeHandlerFor, shouldDecode };
@@ -1,10 +1,18 @@
1
- import { ManifestEntry, PreloadOptions } from "#fundus/core";
2
-
3
- //#region src/manifest.d.ts
1
+ /**
2
+ * The runtime manifest: generated modules call `createManifest` with data-only
3
+ * entries, and the entries become direct, typed, readonly properties
4
+ * — no global registry, no string keys, a removed asset is a compile error.
5
+ *
6
+ * `Manifest` owns only kind-agnostic orchestration — entry-source collection
7
+ * (including inlined reference entries), URL dedup, in-flight/idempotency.
8
+ * How each kind actually loads (decode, retention) is the per-kind runtime
9
+ * handler's strategy — see kind-handlers.ts.
10
+ */
11
+ import type { ManifestEntry, PreloadOptions } from '../core/index.js';
4
12
  /** One deliverable file of an entry: its URL and the owning entry's kind. */
5
- interface EntrySource {
6
- url: string;
7
- kind: string;
13
+ export interface EntrySource {
14
+ url: string;
15
+ kind: string;
8
16
  }
9
17
  /**
10
18
  * Collect every deliverable URL of an entry, including the entries codegen
@@ -12,49 +20,47 @@ interface EntrySource {
12
20
  * a string `kind` is an entry, and its `src` (when present) is a source.
13
21
  * Generic by design: adding a kind does not change preload orchestration.
14
22
  */
15
- declare function collectEntrySources(entry: ManifestEntry): EntrySource[];
16
- declare class Manifest {
17
- #private;
18
- constructor(entries: Record<string, ManifestEntry>);
19
- /**
20
- * Fetch every deliverable file of this manifest up front — including the
21
- * reference closure, which codegen inlined into the entries — and decode
22
- * image-backed entries. Options are namespaced per asset kind, mirroring
23
- * `plugins.<type>` in the config: `{ image: { decode: false } }`
24
- * skips decoding for image entries only; slices keep decoding unless
25
- * `slice: { decode: false }` is passed too. An option applies to every
26
- * entry of its kind, inlined reference entries included.
27
- *
28
- * Idempotent and concurrent-safe: one in-flight promise per manifest; a
29
- * second call joins it (or resolves immediately once done), and URLs shared
30
- * by several entries are fetched once. Sharing goes further than this
31
- * manifest: every URL is acquired through the module-wide refcounted
32
- * registry, so a URL another manifest already preloaded (or is preloading)
33
- * is never fetched again — this manifest just takes a hold on it. A failed
34
- * preload rolls back this manifest's holds and clears the in-flight state
35
- * so it can be retried. A joined call's options are ignored: options apply
36
- * per preload run (the first call after construction or `release()`).
37
- */
38
- preload(options?: PreloadOptions): Promise<void>;
39
- /**
40
- * Drop this manifest's holds on everything it preloaded. Assets shared
41
- * with another preloaded manifest stay fully alive for that holder; assets
42
- * nobody holds anymore are disposed via their kind's release strategy
43
- * (retained media object URLs are revoked, freeing the memory). Consumers
44
- * of a fully released source fall back to its network URL.
45
- *
46
- * Safe in every state: before or without `preload()` it is a no-op, and
47
- * calling it while a `preload()` is still in flight drops the holds
48
- * without cancelling — when the in-flight load completes unheld, the
49
- * registry disposes it immediately (no leak). Afterwards the manifest's
50
- * preload state is reset, so a later `preload()` re-acquires from scratch.
51
- */
52
- release(): void;
23
+ export declare function collectEntrySources(entry: ManifestEntry): EntrySource[];
24
+ export declare class Manifest {
25
+ #private;
26
+ constructor(entries: Record<string, ManifestEntry>);
27
+ /**
28
+ * Fetch every deliverable file of this manifest up front — including the
29
+ * reference closure, which codegen inlined into the entries — and decode
30
+ * image-backed entries. Options are namespaced per asset kind, mirroring
31
+ * `plugins.<type>` in the config: `{ image: { decode: false } }`
32
+ * skips decoding for image entries only; slices keep decoding unless
33
+ * `slice: { decode: false }` is passed too. An option applies to every
34
+ * entry of its kind, inlined reference entries included.
35
+ *
36
+ * Idempotent and concurrent-safe: one in-flight promise per manifest; a
37
+ * second call joins it (or resolves immediately once done), and URLs shared
38
+ * by several entries are fetched once. Sharing goes further than this
39
+ * manifest: every URL is acquired through the module-wide refcounted
40
+ * registry, so a URL another manifest already preloaded (or is preloading)
41
+ * is never fetched again — this manifest just takes a hold on it. A failed
42
+ * preload rolls back this manifest's holds and clears the in-flight state
43
+ * so it can be retried. A joined call's options are ignored: options apply
44
+ * per preload run (the first call after construction or `release()`).
45
+ */
46
+ preload(options?: PreloadOptions): Promise<void>;
47
+ /**
48
+ * Drop this manifest's holds on everything it preloaded. Assets shared
49
+ * with another preloaded manifest stay fully alive for that holder; assets
50
+ * nobody holds anymore are disposed via their kind's release strategy
51
+ * (retained media object URLs are revoked, freeing the memory). Consumers
52
+ * of a fully released source fall back to its network URL.
53
+ *
54
+ * Safe in every state: before or without `preload()` it is a no-op, and
55
+ * calling it while a `preload()` is still in flight drops the holds
56
+ * without cancelling — when the in-flight load completes unheld, the
57
+ * registry disposes it immediately (no leak). Afterwards the manifest's
58
+ * preload state is reset, so a later `preload()` re-acquires from scratch.
59
+ */
60
+ release(): void;
53
61
  }
54
62
  /**
55
63
  * Construct a manifest whose entries are direct readonly properties:
56
64
  * `mainCatalog.navigationPanel` is fully typed, and a typo is a compile error.
57
65
  */
58
- declare function createManifest<T extends Record<string, ManifestEntry>>(entries: T): Manifest & Readonly<T>;
59
- //#endregion
60
- export { EntrySource, Manifest, collectEntrySources, createManifest };
66
+ export declare function createManifest<T extends Record<string, ManifestEntry>>(entries: T): Manifest & Readonly<T>;
@@ -1,117 +1,137 @@
1
- import { acquireSource, releaseSource } from "./preload-registry.js";
2
- //#region src/manifest.ts
1
+ import { acquireSource, releaseSource } from './preload-registry.js';
3
2
  /**
4
- * Collect every deliverable URL of an entry, including the entries codegen
5
- * inlined in place of asset references: any nested object carrying
6
- * a string `kind` is an entry, and its `src` (when present) is a source.
7
- * Generic by design: adding a kind does not change preload orchestration.
8
- */
9
- function collectEntrySources(entry) {
10
- const sources = [];
11
- visit(entry);
12
- return sources;
13
- function visit(value) {
14
- if (Array.isArray(value)) {
15
- for (const element of value) visit(element);
16
- return;
17
- }
18
- if (typeof value !== "object" || value === null) return;
19
- const record = value;
20
- if (typeof record.kind === "string" && typeof record.src === "string") sources.push({
21
- url: record.src,
22
- kind: record.kind
23
- });
24
- for (const nested of Object.values(record)) visit(nested);
25
- }
3
+ * Collect every deliverable URL of an entry, including the entries codegen
4
+ * inlined in place of asset references: any nested object carrying
5
+ * a string `kind` is an entry, and its `src` (when present) is a source.
6
+ * Generic by design: adding a kind does not change preload orchestration.
7
+ */
8
+ export function collectEntrySources(entry) {
9
+ const sources = [];
10
+ visit(entry);
11
+ return sources;
12
+ function visit(value) {
13
+ if (Array.isArray(value)) {
14
+ for (const element of value)
15
+ visit(element);
16
+ return;
17
+ }
18
+ if (typeof value !== 'object' || value === null)
19
+ return;
20
+ const record = value;
21
+ if (typeof record.kind === 'string' && typeof record.src === 'string') {
22
+ sources.push({ url: record.src, kind: record.kind });
23
+ }
24
+ for (const nested of Object.values(record))
25
+ visit(nested);
26
+ }
27
+ }
28
+ export class Manifest {
29
+ #entries;
30
+ #preloading = null;
31
+ /**
32
+ * URLs this manifest currently holds in the module-wide registry (each
33
+ * held at most once — the registry's reference count counts holding
34
+ * manifests, not preload calls). Replaced wholesale by `release()`: an
35
+ * in-flight preload run keeps operating on the set object it captured, so
36
+ * a release during the run (which drains that set) turns the run's own
37
+ * failure rollback into a no-op instead of a double release.
38
+ */
39
+ #heldUrls = new Set();
40
+ constructor(entries) {
41
+ for (const key of Object.keys(entries)) {
42
+ // Belt-and-braces with core's reserved-id check: codegen validates ids, but a
43
+ // hand-written call must not silently shadow a class member either.
44
+ if (key in this) {
45
+ throw new Error(`Manifest entry id "${key}" collides with a Manifest member.`);
46
+ }
47
+ }
48
+ Object.assign(this, entries);
49
+ this.#entries = entries;
50
+ }
51
+ /**
52
+ * Fetch every deliverable file of this manifest up front — including the
53
+ * reference closure, which codegen inlined into the entries — and decode
54
+ * image-backed entries. Options are namespaced per asset kind, mirroring
55
+ * `plugins.<type>` in the config: `{ image: { decode: false } }`
56
+ * skips decoding for image entries only; slices keep decoding unless
57
+ * `slice: { decode: false }` is passed too. An option applies to every
58
+ * entry of its kind, inlined reference entries included.
59
+ *
60
+ * Idempotent and concurrent-safe: one in-flight promise per manifest; a
61
+ * second call joins it (or resolves immediately once done), and URLs shared
62
+ * by several entries are fetched once. Sharing goes further than this
63
+ * manifest: every URL is acquired through the module-wide refcounted
64
+ * registry, so a URL another manifest already preloaded (or is preloading)
65
+ * is never fetched again — this manifest just takes a hold on it. A failed
66
+ * preload rolls back this manifest's holds and clears the in-flight state
67
+ * so it can be retried. A joined call's options are ignored: options apply
68
+ * per preload run (the first call after construction or `release()`).
69
+ */
70
+ preload(options = {}) {
71
+ if (!this.#preloading) {
72
+ const tracked = this.#preloadAll(options, this.#heldUrls).catch((cause) => {
73
+ // Reset for retry — unless release() or a follow-up preload()
74
+ // already superseded this run while it was in flight.
75
+ if (this.#preloading === tracked)
76
+ this.#preloading = null;
77
+ throw cause;
78
+ });
79
+ this.#preloading = tracked;
80
+ }
81
+ return this.#preloading;
82
+ }
83
+ /**
84
+ * Drop this manifest's holds on everything it preloaded. Assets shared
85
+ * with another preloaded manifest stay fully alive for that holder; assets
86
+ * nobody holds anymore are disposed via their kind's release strategy
87
+ * (retained media object URLs are revoked, freeing the memory). Consumers
88
+ * of a fully released source fall back to its network URL.
89
+ *
90
+ * Safe in every state: before or without `preload()` it is a no-op, and
91
+ * calling it while a `preload()` is still in flight drops the holds
92
+ * without cancelling — when the in-flight load completes unheld, the
93
+ * registry disposes it immediately (no leak). Afterwards the manifest's
94
+ * preload state is reset, so a later `preload()` re-acquires from scratch.
95
+ */
96
+ release() {
97
+ const held = this.#heldUrls;
98
+ this.#heldUrls = new Set();
99
+ this.#preloading = null;
100
+ for (const url of held)
101
+ releaseSource(url);
102
+ // Drain the old set so an in-flight run's failure rollback (which
103
+ // captured it) finds nothing left to release.
104
+ held.clear();
105
+ }
106
+ async #preloadAll(options, held) {
107
+ const kindByUrl = new Map();
108
+ for (const entry of Object.values(this.#entries)) {
109
+ for (const source of collectEntrySources(entry)) {
110
+ if (!kindByUrl.has(source.url))
111
+ kindByUrl.set(source.url, source.kind);
112
+ }
113
+ }
114
+ const acquisitions = [];
115
+ for (const [url, kind] of kindByUrl) {
116
+ held.add(url);
117
+ acquisitions.push(acquireSource(url, kind, options));
118
+ }
119
+ const outcomes = await Promise.allSettled(acquisitions);
120
+ const failure = outcomes.find((outcome) => outcome.status === 'rejected');
121
+ if (failure) {
122
+ // Roll back every hold of this run — unless release() already
123
+ // dropped them mid-flight (it drains the captured set).
124
+ for (const url of held)
125
+ releaseSource(url);
126
+ held.clear();
127
+ throw failure.reason;
128
+ }
129
+ }
26
130
  }
27
- var Manifest = class {
28
- #entries;
29
- #preloading = null;
30
- /**
31
- * URLs this manifest currently holds in the module-wide registry (each
32
- * held at most once — the registry's reference count counts holding
33
- * manifests, not preload calls). Replaced wholesale by `release()`: an
34
- * in-flight preload run keeps operating on the set object it captured, so
35
- * a release during the run (which drains that set) turns the run's own
36
- * failure rollback into a no-op instead of a double release.
37
- */
38
- #heldUrls = /* @__PURE__ */ new Set();
39
- constructor(entries) {
40
- for (const key of Object.keys(entries)) if (key in this) throw new Error(`Manifest entry id "${key}" collides with a Manifest member.`);
41
- Object.assign(this, entries);
42
- this.#entries = entries;
43
- }
44
- /**
45
- * Fetch every deliverable file of this manifest up front — including the
46
- * reference closure, which codegen inlined into the entries — and decode
47
- * image-backed entries. Options are namespaced per asset kind, mirroring
48
- * `plugins.<type>` in the config: `{ image: { decode: false } }`
49
- * skips decoding for image entries only; slices keep decoding unless
50
- * `slice: { decode: false }` is passed too. An option applies to every
51
- * entry of its kind, inlined reference entries included.
52
- *
53
- * Idempotent and concurrent-safe: one in-flight promise per manifest; a
54
- * second call joins it (or resolves immediately once done), and URLs shared
55
- * by several entries are fetched once. Sharing goes further than this
56
- * manifest: every URL is acquired through the module-wide refcounted
57
- * registry, so a URL another manifest already preloaded (or is preloading)
58
- * is never fetched again — this manifest just takes a hold on it. A failed
59
- * preload rolls back this manifest's holds and clears the in-flight state
60
- * so it can be retried. A joined call's options are ignored: options apply
61
- * per preload run (the first call after construction or `release()`).
62
- */
63
- preload(options = {}) {
64
- if (!this.#preloading) {
65
- const tracked = this.#preloadAll(options, this.#heldUrls).catch((cause) => {
66
- if (this.#preloading === tracked) this.#preloading = null;
67
- throw cause;
68
- });
69
- this.#preloading = tracked;
70
- }
71
- return this.#preloading;
72
- }
73
- /**
74
- * Drop this manifest's holds on everything it preloaded. Assets shared
75
- * with another preloaded manifest stay fully alive for that holder; assets
76
- * nobody holds anymore are disposed via their kind's release strategy
77
- * (retained media object URLs are revoked, freeing the memory). Consumers
78
- * of a fully released source fall back to its network URL.
79
- *
80
- * Safe in every state: before or without `preload()` it is a no-op, and
81
- * calling it while a `preload()` is still in flight drops the holds
82
- * without cancelling — when the in-flight load completes unheld, the
83
- * registry disposes it immediately (no leak). Afterwards the manifest's
84
- * preload state is reset, so a later `preload()` re-acquires from scratch.
85
- */
86
- release() {
87
- const held = this.#heldUrls;
88
- this.#heldUrls = /* @__PURE__ */ new Set();
89
- this.#preloading = null;
90
- for (const url of held) releaseSource(url);
91
- held.clear();
92
- }
93
- async #preloadAll(options, held) {
94
- const kindByUrl = /* @__PURE__ */ new Map();
95
- for (const entry of Object.values(this.#entries)) for (const source of collectEntrySources(entry)) if (!kindByUrl.has(source.url)) kindByUrl.set(source.url, source.kind);
96
- const acquisitions = [];
97
- for (const [url, kind] of kindByUrl) {
98
- held.add(url);
99
- acquisitions.push(acquireSource(url, kind, options));
100
- }
101
- const failure = (await Promise.allSettled(acquisitions)).find((outcome) => outcome.status === "rejected");
102
- if (failure) {
103
- for (const url of held) releaseSource(url);
104
- held.clear();
105
- throw failure.reason;
106
- }
107
- }
108
- };
109
131
  /**
110
- * Construct a manifest whose entries are direct readonly properties:
111
- * `mainCatalog.navigationPanel` is fully typed, and a typo is a compile error.
112
- */
113
- function createManifest(entries) {
114
- return new Manifest(entries);
132
+ * Construct a manifest whose entries are direct readonly properties:
133
+ * `mainCatalog.navigationPanel` is fully typed, and a typo is a compile error.
134
+ */
135
+ export function createManifest(entries) {
136
+ return new Manifest(entries);
115
137
  }
116
- //#endregion
117
- export { Manifest, collectEntrySources, createManifest };
@@ -1,5 +1,2 @@
1
- //#region src/observe-border-box-size.d.ts
2
1
  /** Observe an element's layout border-box size in whole CSS pixels. */
3
- declare function observeBorderBoxSize(element: HTMLElement, onSize: (width: number, height: number) => void): () => void;
4
- //#endregion
5
- export { observeBorderBoxSize };
2
+ export declare function observeBorderBoxSize(element: HTMLElement, onSize: (width: number, height: number) => void): () => void;
@@ -1,12 +1,11 @@
1
- //#region src/observe-border-box-size.ts
2
1
  /** Observe an element's layout border-box size in whole CSS pixels. */
3
- function observeBorderBoxSize(element, onSize) {
4
- const observer = new ResizeObserver((entries) => {
5
- const size = entries[0]?.borderBoxSize?.[0];
6
- onSize(Math.round(size?.inlineSize ?? element.offsetWidth), Math.round(size?.blockSize ?? element.offsetHeight));
7
- });
8
- observer.observe(element);
9
- return () => observer.disconnect();
2
+ export function observeBorderBoxSize(element, onSize) {
3
+ const observer = new ResizeObserver((entries) => {
4
+ // Measure layout, not getBoundingClientRect(): transforms must not freeze
5
+ // render geometry after an animation because they do not retrigger resize.
6
+ const size = entries[0]?.borderBoxSize?.[0];
7
+ onSize(Math.round(size?.inlineSize ?? element.offsetWidth), Math.round(size?.blockSize ?? element.offsetHeight));
8
+ });
9
+ observer.observe(element);
10
+ return () => observer.disconnect();
10
11
  }
11
- //#endregion
12
- export { observeBorderBoxSize };