@osmo.inc/cli 0.1.18-preview.2 → 0.1.19

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 (943) hide show
  1. package/DEPLOY.md +62 -16
  2. package/README.md +31 -17
  3. package/SETUP.md +19 -7
  4. package/THIRD_PARTY_NOTICES.md +5 -16
  5. package/bin/osmo.mjs +12 -0
  6. package/dist/osmo.js +2500 -8905
  7. package/package.json +14 -27
  8. package/release.json +49 -84
  9. package/third-party/inventory.json +0 -3601
  10. package/node_modules/@esbuild/darwin-arm64/README.md +0 -3
  11. package/node_modules/@esbuild/darwin-arm64/bin/esbuild +0 -0
  12. package/node_modules/@esbuild/darwin-arm64/package.json +0 -20
  13. package/node_modules/esbuild/LICENSE.md +0 -21
  14. package/node_modules/esbuild/README.md +0 -3
  15. package/node_modules/esbuild/bin/esbuild +0 -223
  16. package/node_modules/esbuild/install.js +0 -289
  17. package/node_modules/esbuild/lib/main.d.ts +0 -716
  18. package/node_modules/esbuild/lib/main.js +0 -2532
  19. package/node_modules/esbuild/package.json +0 -49
  20. package/node_modules/typescript/LICENSE.txt +0 -55
  21. package/node_modules/typescript/ThirdPartyNoticeText.txt +0 -193
  22. package/node_modules/typescript/lib/lib.d.ts +0 -22
  23. package/node_modules/typescript/lib/lib.decorators.d.ts +0 -384
  24. package/node_modules/typescript/lib/lib.decorators.legacy.d.ts +0 -22
  25. package/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +0 -41
  26. package/node_modules/typescript/lib/lib.dom.d.ts +0 -39429
  27. package/node_modules/typescript/lib/lib.dom.iterable.d.ts +0 -571
  28. package/node_modules/typescript/lib/lib.es2015.collection.d.ts +0 -147
  29. package/node_modules/typescript/lib/lib.es2015.core.d.ts +0 -597
  30. package/node_modules/typescript/lib/lib.es2015.d.ts +0 -28
  31. package/node_modules/typescript/lib/lib.es2015.generator.d.ts +0 -77
  32. package/node_modules/typescript/lib/lib.es2015.iterable.d.ts +0 -605
  33. package/node_modules/typescript/lib/lib.es2015.promise.d.ts +0 -81
  34. package/node_modules/typescript/lib/lib.es2015.proxy.d.ts +0 -128
  35. package/node_modules/typescript/lib/lib.es2015.reflect.d.ts +0 -144
  36. package/node_modules/typescript/lib/lib.es2015.symbol.d.ts +0 -46
  37. package/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +0 -326
  38. package/node_modules/typescript/lib/lib.es2016.array.include.d.ts +0 -116
  39. package/node_modules/typescript/lib/lib.es2016.d.ts +0 -21
  40. package/node_modules/typescript/lib/lib.es2016.full.d.ts +0 -23
  41. package/node_modules/typescript/lib/lib.es2016.intl.d.ts +0 -31
  42. package/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +0 -21
  43. package/node_modules/typescript/lib/lib.es2017.d.ts +0 -26
  44. package/node_modules/typescript/lib/lib.es2017.date.d.ts +0 -31
  45. package/node_modules/typescript/lib/lib.es2017.full.d.ts +0 -23
  46. package/node_modules/typescript/lib/lib.es2017.intl.d.ts +0 -44
  47. package/node_modules/typescript/lib/lib.es2017.object.d.ts +0 -49
  48. package/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +0 -135
  49. package/node_modules/typescript/lib/lib.es2017.string.d.ts +0 -45
  50. package/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +0 -53
  51. package/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +0 -77
  52. package/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +0 -53
  53. package/node_modules/typescript/lib/lib.es2018.d.ts +0 -24
  54. package/node_modules/typescript/lib/lib.es2018.full.d.ts +0 -24
  55. package/node_modules/typescript/lib/lib.es2018.intl.d.ts +0 -83
  56. package/node_modules/typescript/lib/lib.es2018.promise.d.ts +0 -30
  57. package/node_modules/typescript/lib/lib.es2018.regexp.d.ts +0 -37
  58. package/node_modules/typescript/lib/lib.es2019.array.d.ts +0 -79
  59. package/node_modules/typescript/lib/lib.es2019.d.ts +0 -24
  60. package/node_modules/typescript/lib/lib.es2019.full.d.ts +0 -24
  61. package/node_modules/typescript/lib/lib.es2019.intl.d.ts +0 -23
  62. package/node_modules/typescript/lib/lib.es2019.object.d.ts +0 -33
  63. package/node_modules/typescript/lib/lib.es2019.string.d.ts +0 -37
  64. package/node_modules/typescript/lib/lib.es2019.symbol.d.ts +0 -24
  65. package/node_modules/typescript/lib/lib.es2020.bigint.d.ts +0 -765
  66. package/node_modules/typescript/lib/lib.es2020.d.ts +0 -27
  67. package/node_modules/typescript/lib/lib.es2020.date.d.ts +0 -42
  68. package/node_modules/typescript/lib/lib.es2020.full.d.ts +0 -24
  69. package/node_modules/typescript/lib/lib.es2020.intl.d.ts +0 -474
  70. package/node_modules/typescript/lib/lib.es2020.number.d.ts +0 -28
  71. package/node_modules/typescript/lib/lib.es2020.promise.d.ts +0 -47
  72. package/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +0 -99
  73. package/node_modules/typescript/lib/lib.es2020.string.d.ts +0 -44
  74. package/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +0 -41
  75. package/node_modules/typescript/lib/lib.es2021.d.ts +0 -23
  76. package/node_modules/typescript/lib/lib.es2021.full.d.ts +0 -24
  77. package/node_modules/typescript/lib/lib.es2021.intl.d.ts +0 -166
  78. package/node_modules/typescript/lib/lib.es2021.promise.d.ts +0 -48
  79. package/node_modules/typescript/lib/lib.es2021.string.d.ts +0 -33
  80. package/node_modules/typescript/lib/lib.es2021.weakref.d.ts +0 -78
  81. package/node_modules/typescript/lib/lib.es2022.array.d.ts +0 -121
  82. package/node_modules/typescript/lib/lib.es2022.d.ts +0 -25
  83. package/node_modules/typescript/lib/lib.es2022.error.d.ts +0 -75
  84. package/node_modules/typescript/lib/lib.es2022.full.d.ts +0 -24
  85. package/node_modules/typescript/lib/lib.es2022.intl.d.ts +0 -145
  86. package/node_modules/typescript/lib/lib.es2022.object.d.ts +0 -26
  87. package/node_modules/typescript/lib/lib.es2022.regexp.d.ts +0 -39
  88. package/node_modules/typescript/lib/lib.es2022.string.d.ts +0 -25
  89. package/node_modules/typescript/lib/lib.es2023.array.d.ts +0 -924
  90. package/node_modules/typescript/lib/lib.es2023.collection.d.ts +0 -21
  91. package/node_modules/typescript/lib/lib.es2023.d.ts +0 -22
  92. package/node_modules/typescript/lib/lib.es2023.full.d.ts +0 -24
  93. package/node_modules/typescript/lib/lib.es2023.intl.d.ts +0 -56
  94. package/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +0 -65
  95. package/node_modules/typescript/lib/lib.es2024.collection.d.ts +0 -29
  96. package/node_modules/typescript/lib/lib.es2024.d.ts +0 -26
  97. package/node_modules/typescript/lib/lib.es2024.full.d.ts +0 -24
  98. package/node_modules/typescript/lib/lib.es2024.object.d.ts +0 -29
  99. package/node_modules/typescript/lib/lib.es2024.promise.d.ts +0 -35
  100. package/node_modules/typescript/lib/lib.es2024.regexp.d.ts +0 -25
  101. package/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +0 -68
  102. package/node_modules/typescript/lib/lib.es2024.string.d.ts +0 -29
  103. package/node_modules/typescript/lib/lib.es5.d.ts +0 -4601
  104. package/node_modules/typescript/lib/lib.es6.d.ts +0 -23
  105. package/node_modules/typescript/lib/lib.esnext.array.d.ts +0 -35
  106. package/node_modules/typescript/lib/lib.esnext.collection.d.ts +0 -96
  107. package/node_modules/typescript/lib/lib.esnext.d.ts +0 -29
  108. package/node_modules/typescript/lib/lib.esnext.decorators.d.ts +0 -28
  109. package/node_modules/typescript/lib/lib.esnext.disposable.d.ts +0 -193
  110. package/node_modules/typescript/lib/lib.esnext.error.d.ts +0 -24
  111. package/node_modules/typescript/lib/lib.esnext.float16.d.ts +0 -445
  112. package/node_modules/typescript/lib/lib.esnext.full.d.ts +0 -24
  113. package/node_modules/typescript/lib/lib.esnext.intl.d.ts +0 -21
  114. package/node_modules/typescript/lib/lib.esnext.iterator.d.ts +0 -148
  115. package/node_modules/typescript/lib/lib.esnext.promise.d.ts +0 -34
  116. package/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +0 -25
  117. package/node_modules/typescript/lib/lib.scripthost.d.ts +0 -322
  118. package/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +0 -41
  119. package/node_modules/typescript/lib/lib.webworker.d.ts +0 -13150
  120. package/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +0 -23
  121. package/node_modules/typescript/lib/lib.webworker.iterable.d.ts +0 -340
  122. package/node_modules/typescript/lib/typescript.js +0 -382
  123. package/node_modules/typescript/package.json +0 -57
  124. package/runtime/apps/native/tools/compile.mjs +0 -217
  125. package/runtime/packages/scene/scripts/validate-strict.mjs +0 -246
  126. package/runtime/packages/scene/src/clip.d.mts +0 -14
  127. package/runtime/packages/scene/src/clip.mjs +0 -15
  128. package/runtime/packages/scene/src/color-value.d.mts +0 -5
  129. package/runtime/packages/scene/src/color-value.mjs +0 -19
  130. package/runtime/packages/scene/src/color.ts +0 -1
  131. package/runtime/packages/scene/src/effects.ts +0 -213
  132. package/runtime/packages/scene/src/elements.ts +0 -491
  133. package/runtime/packages/scene/src/evaluate.ts +0 -919
  134. package/runtime/packages/scene/src/index.ts +0 -69
  135. package/runtime/packages/scene/src/jsx-runtime.ts +0 -73
  136. package/runtime/packages/scene/src/knob-schema.ts +0 -115
  137. package/runtime/packages/scene/src/knobs.ts +0 -118
  138. package/runtime/packages/scene/src/mask.d.mts +0 -6
  139. package/runtime/packages/scene/src/mask.mjs +0 -17
  140. package/runtime/packages/scene/src/metadata.d.mts +0 -23
  141. package/runtime/packages/scene/src/metadata.mjs +0 -44
  142. package/runtime/packages/scene/src/motion-sampling.d.mts +0 -2
  143. package/runtime/packages/scene/src/motion-sampling.mjs +0 -50
  144. package/runtime/packages/scene/src/motion.ts +0 -121
  145. package/runtime/packages/scene/src/shader.ts +0 -57
  146. package/src/resource-examples/example-image/landscape.svg +0 -7
  147. package/src/resource-examples/example-image/resource.json +0 -8
  148. package/src/resource-examples/example-model/gem.glb +0 -0
  149. package/src/resource-examples/example-model/preview.svg +0 -1
  150. package/src/resource-examples/example-model/resource.json +0 -7
  151. package/src/resource-examples/example-scene/resource.json +0 -1
  152. package/src/resource-examples/example-scene/scene.tsx +0 -8
  153. package/src/resource-examples/example-shader/effect.wgsl +0 -7
  154. package/src/resource-examples/example-shader/preview.svg +0 -1
  155. package/src/resource-examples/example-shader/resource.json +0 -27
  156. package/src/resource-examples/example-shader/tint.wgsl +0 -7
  157. package/src/resource-examples/example-video/ambient.mp4 +0 -0
  158. package/src/resource-examples/example-video/resource.json +0 -9
  159. package/src/starter/scene.tsx +0 -20
  160. package/studio/index.html +0 -2
  161. package/studio/public/check-circle-filled.svg +0 -3
  162. package/studio/public/comment-cursor/active-outer.svg +0 -3
  163. package/studio/public/comment-cursor/default.svg +0 -6
  164. package/studio/public/osmo-studio-logo.svg +0 -12
  165. package/studio/public/pencil-simple.svg +0 -5
  166. package/studio/src/active-outer-TVYUEURE.svg +0 -3
  167. package/studio/src/app.css +0 -4
  168. package/studio/src/app.js +0 -714
  169. package/studio/src/default-6CTRH4V5.svg +0 -6
  170. package/studio/src/engine_bg.wasm +0 -0
  171. package/studio/src/inter-cyrillic-ext-wght-normal-IYF56FF6.woff2 +0 -0
  172. package/studio/src/inter-cyrillic-wght-normal-JEOLYBOO.woff2 +0 -0
  173. package/studio/src/inter-greek-ext-wght-normal-EOVOK2B5.woff2 +0 -0
  174. package/studio/src/inter-greek-wght-normal-IRE366VL.woff2 +0 -0
  175. package/studio/src/inter-latin-ext-wght-normal-HA22NDSG.woff2 +0 -0
  176. package/studio/src/inter-latin-wght-normal-NRMW37G5.woff2 +0 -0
  177. package/studio/src/inter-vietnamese-wght-normal-CE5GGD3W.woff2 +0 -0
  178. package/studio/src/osmo-studio-logo-D5R2V77B.svg +0 -12
  179. package/third-party/cargo/adler2@2.0.1/Cargo.toml +0 -91
  180. package/third-party/cargo/adler2@2.0.1/LICENSE-0BSD +0 -12
  181. package/third-party/cargo/adler2@2.0.1/LICENSE-APACHE +0 -201
  182. package/third-party/cargo/adler2@2.0.1/LICENSE-MIT +0 -23
  183. package/third-party/cargo/allocator-api2@0.2.21/Cargo.toml +0 -48
  184. package/third-party/cargo/allocator-api2@0.2.21/LICENSE-APACHE +0 -176
  185. package/third-party/cargo/allocator-api2@0.2.21/LICENSE-MIT +0 -23
  186. package/third-party/cargo/arrayref@0.3.9/Cargo.toml +0 -23
  187. package/third-party/cargo/arrayref@0.3.9/LICENSE +0 -26
  188. package/third-party/cargo/arrayvec@0.7.8/Cargo.toml +0 -112
  189. package/third-party/cargo/arrayvec@0.7.8/LICENSE-APACHE +0 -201
  190. package/third-party/cargo/arrayvec@0.7.8/LICENSE-MIT +0 -25
  191. package/third-party/cargo/ascii@1.1.0/Cargo.toml +0 -41
  192. package/third-party/cargo/ascii@1.1.0/LICENSE-APACHE +0 -201
  193. package/third-party/cargo/ascii@1.1.0/LICENSE-MIT +0 -22
  194. package/third-party/cargo/ash@0.38.0+1.3.281/Cargo.toml +0 -66
  195. package/third-party/cargo/ash@0.38.0+1.3.281/LICENSE-APACHE +0 -67
  196. package/third-party/cargo/ash@0.38.0+1.3.281/LICENSE-MIT +0 -25
  197. package/third-party/cargo/autocfg@1.5.1/Cargo.toml +0 -75
  198. package/third-party/cargo/autocfg@1.5.1/LICENSE-APACHE +0 -201
  199. package/third-party/cargo/autocfg@1.5.1/LICENSE-MIT +0 -25
  200. package/third-party/cargo/base64@0.13.1/Cargo.toml +0 -53
  201. package/third-party/cargo/base64@0.13.1/LICENSE-APACHE +0 -201
  202. package/third-party/cargo/base64@0.13.1/LICENSE-MIT +0 -21
  203. package/third-party/cargo/base64@0.22.1/Cargo.toml +0 -85
  204. package/third-party/cargo/base64@0.22.1/LICENSE-APACHE +0 -201
  205. package/third-party/cargo/base64@0.22.1/LICENSE-MIT +0 -21
  206. package/third-party/cargo/bit-set@0.10.0/Cargo.toml +0 -108
  207. package/third-party/cargo/bit-set@0.10.0/LICENSE-APACHE +0 -201
  208. package/third-party/cargo/bit-set@0.10.0/LICENSE-MIT +0 -25
  209. package/third-party/cargo/bit-vec@0.9.1/Cargo.toml +0 -94
  210. package/third-party/cargo/bit-vec@0.9.1/LICENSE-APACHE +0 -201
  211. package/third-party/cargo/bit-vec@0.9.1/LICENSE-MIT +0 -25
  212. package/third-party/cargo/bitflags@2.13.0/Cargo.toml +0 -120
  213. package/third-party/cargo/bitflags@2.13.0/LICENSE-APACHE +0 -201
  214. package/third-party/cargo/bitflags@2.13.0/LICENSE-MIT +0 -25
  215. package/third-party/cargo/block2@0.6.2/Cargo.toml +0 -115
  216. package/third-party/cargo/block2@0.6.2/MIT-terms.txt +0 -22
  217. package/third-party/cargo/block2@0.6.2/madsmtm-objc2-b4167b582b2f-LICENSE.md +0 -34
  218. package/third-party/cargo/bumpalo@3.20.3/Cargo.toml +0 -99
  219. package/third-party/cargo/bumpalo@3.20.3/LICENSE-APACHE +0 -201
  220. package/third-party/cargo/bumpalo@3.20.3/LICENSE-MIT +0 -25
  221. package/third-party/cargo/bytemuck@1.25.1/Cargo.toml +0 -153
  222. package/third-party/cargo/bytemuck@1.25.1/LICENSE-APACHE +0 -61
  223. package/third-party/cargo/bytemuck@1.25.1/LICENSE-MIT +0 -9
  224. package/third-party/cargo/bytemuck@1.25.1/LICENSE-ZLIB +0 -11
  225. package/third-party/cargo/bytemuck_derive@1.11.0/Cargo.toml +0 -60
  226. package/third-party/cargo/bytemuck_derive@1.11.0/LICENSE-APACHE +0 -61
  227. package/third-party/cargo/bytemuck_derive@1.11.0/LICENSE-MIT +0 -9
  228. package/third-party/cargo/bytemuck_derive@1.11.0/LICENSE-ZLIB +0 -11
  229. package/third-party/cargo/byteorder-lite@0.1.0/Cargo.toml +0 -57
  230. package/third-party/cargo/byteorder-lite@0.1.0/LICENSE-MIT +0 -21
  231. package/third-party/cargo/byteorder-lite@0.1.0/UNLICENSE +0 -24
  232. package/third-party/cargo/byteorder@1.5.0/COPYING +0 -3
  233. package/third-party/cargo/byteorder@1.5.0/Cargo.toml +0 -54
  234. package/third-party/cargo/byteorder@1.5.0/LICENSE-MIT +0 -21
  235. package/third-party/cargo/byteorder@1.5.0/UNLICENSE +0 -24
  236. package/third-party/cargo/cfg-if@1.0.4/Cargo.toml +0 -47
  237. package/third-party/cargo/cfg-if@1.0.4/LICENSE-APACHE +0 -201
  238. package/third-party/cargo/cfg-if@1.0.4/LICENSE-MIT +0 -25
  239. package/third-party/cargo/cfg_aliases@0.2.1/Cargo.toml +0 -43
  240. package/third-party/cargo/cfg_aliases@0.2.1/LICENSE +0 -9
  241. package/third-party/cargo/chunked_transfer@1.5.0/Cargo.toml +0 -27
  242. package/third-party/cargo/chunked_transfer@1.5.0/LICENSE-APACHE +0 -201
  243. package/third-party/cargo/chunked_transfer@1.5.0/LICENSE-MIT +0 -22
  244. package/third-party/cargo/codespan-reporting@0.13.1/Cargo.toml +0 -115
  245. package/third-party/cargo/codespan-reporting@0.13.1/LICENSE +0 -201
  246. package/third-party/cargo/color_quant@1.1.0/Cargo.toml +0 -20
  247. package/third-party/cargo/color_quant@1.1.0/LICENSE +0 -21
  248. package/third-party/cargo/console_error_panic_hook@0.1.7/Cargo.toml +0 -27
  249. package/third-party/cargo/console_error_panic_hook@0.1.7/LICENSE-APACHE +0 -201
  250. package/third-party/cargo/console_error_panic_hook@0.1.7/LICENSE-MIT +0 -25
  251. package/third-party/cargo/core_maths@0.1.1/Cargo.toml +0 -37
  252. package/third-party/cargo/core_maths@0.1.1/LICENSE +0 -21
  253. package/third-party/cargo/cosmic-text@0.19.0/Cargo.toml +0 -214
  254. package/third-party/cargo/cosmic-text@0.19.0/LICENSE-APACHE +0 -201
  255. package/third-party/cargo/cosmic-text@0.19.0/LICENSE-MIT +0 -21
  256. package/third-party/cargo/crc32fast@1.5.0/Cargo.toml +0 -68
  257. package/third-party/cargo/crc32fast@1.5.0/LICENSE-APACHE +0 -202
  258. package/third-party/cargo/crc32fast@1.5.0/LICENSE-MIT +0 -21
  259. package/third-party/cargo/data-url@0.3.2/Cargo.toml +0 -63
  260. package/third-party/cargo/data-url@0.3.2/LICENSE-APACHE +0 -201
  261. package/third-party/cargo/data-url@0.3.2/LICENSE-MIT +0 -25
  262. package/third-party/cargo/dispatch2@0.3.1/Cargo.toml +0 -122
  263. package/third-party/cargo/dispatch2@0.3.1/MIT-terms.txt +0 -22
  264. package/third-party/cargo/dispatch2@0.3.1/madsmtm-objc2-8852b424193c-LICENSE.md +0 -34
  265. package/third-party/cargo/dlib@0.5.3/Cargo.toml +0 -43
  266. package/third-party/cargo/dlib@0.5.3/LICENSE.txt +0 -19
  267. package/third-party/cargo/document-features@0.2.12/Cargo.toml +0 -51
  268. package/third-party/cargo/document-features@0.2.12/LICENSE-APACHE +0 -73
  269. package/third-party/cargo/document-features@0.2.12/LICENSE-MIT +0 -19
  270. package/third-party/cargo/equivalent@1.0.2/Cargo.toml +0 -37
  271. package/third-party/cargo/equivalent@1.0.2/LICENSE-APACHE +0 -201
  272. package/third-party/cargo/equivalent@1.0.2/LICENSE-MIT +0 -25
  273. package/third-party/cargo/errno@0.3.14/Cargo.toml +0 -67
  274. package/third-party/cargo/errno@0.3.14/LICENSE-APACHE +0 -201
  275. package/third-party/cargo/errno@0.3.14/LICENSE-MIT +0 -25
  276. package/third-party/cargo/etagere@0.3.0/Cargo.toml +0 -57
  277. package/third-party/cargo/etagere@0.3.0/LICENSE-APACHE +0 -13
  278. package/third-party/cargo/etagere@0.3.0/LICENSE-MIT +0 -20
  279. package/third-party/cargo/euclid@0.22.14/COPYRIGHT +0 -5
  280. package/third-party/cargo/euclid@0.22.14/Cargo.toml +0 -66
  281. package/third-party/cargo/euclid@0.22.14/LICENSE-APACHE +0 -201
  282. package/third-party/cargo/euclid@0.22.14/LICENSE-MIT +0 -25
  283. package/third-party/cargo/fastrand@2.5.0/Cargo.toml +0 -89
  284. package/third-party/cargo/fastrand@2.5.0/LICENSE-APACHE +0 -201
  285. package/third-party/cargo/fastrand@2.5.0/LICENSE-MIT +0 -23
  286. package/third-party/cargo/fdeflate@0.3.7/Cargo.toml +0 -55
  287. package/third-party/cargo/fdeflate@0.3.7/LICENSE-APACHE +0 -177
  288. package/third-party/cargo/fdeflate@0.3.7/LICENSE-MIT +0 -25
  289. package/third-party/cargo/flate2@1.1.9/Cargo.toml +0 -274
  290. package/third-party/cargo/flate2@1.1.9/LICENSE-APACHE +0 -201
  291. package/third-party/cargo/flate2@1.1.9/LICENSE-MIT +0 -25
  292. package/third-party/cargo/float-cmp@0.9.0/Cargo.toml +0 -39
  293. package/third-party/cargo/float-cmp@0.9.0/LICENSE +0 -19
  294. package/third-party/cargo/float_next_after@1.0.0/Cargo.toml +0 -43
  295. package/third-party/cargo/float_next_after@1.0.0/LICENSE +0 -23
  296. package/third-party/cargo/foldhash@0.2.0/Cargo.toml +0 -80
  297. package/third-party/cargo/foldhash@0.2.0/LICENSE +0 -19
  298. package/third-party/cargo/font-types@0.11.3/Cargo.toml +0 -55
  299. package/third-party/cargo/font-types@0.11.3/LICENSE-APACHE +0 -67
  300. package/third-party/cargo/font-types@0.11.3/LICENSE-MIT +0 -25
  301. package/third-party/cargo/fontdb@0.23.0/Cargo.toml +0 -83
  302. package/third-party/cargo/fontdb@0.23.0/LICENSE +0 -21
  303. package/third-party/cargo/futures-core@0.3.32/Cargo.toml +0 -66
  304. package/third-party/cargo/futures-core@0.3.32/LICENSE-APACHE +0 -202
  305. package/third-party/cargo/futures-core@0.3.32/LICENSE-MIT +0 -26
  306. package/third-party/cargo/futures-task@0.3.32/Cargo.toml +0 -58
  307. package/third-party/cargo/futures-task@0.3.32/LICENSE-APACHE +0 -202
  308. package/third-party/cargo/futures-task@0.3.32/LICENSE-MIT +0 -26
  309. package/third-party/cargo/futures-util@0.3.32/Cargo.toml +0 -181
  310. package/third-party/cargo/futures-util@0.3.32/LICENSE-APACHE +0 -202
  311. package/third-party/cargo/futures-util@0.3.32/LICENSE-MIT +0 -26
  312. package/third-party/cargo/getrandom@0.4.3/Cargo.toml +0 -165
  313. package/third-party/cargo/getrandom@0.4.3/LICENSE-APACHE +0 -201
  314. package/third-party/cargo/getrandom@0.4.3/LICENSE-MIT +0 -26
  315. package/third-party/cargo/gif@0.14.2/Cargo.toml +0 -84
  316. package/third-party/cargo/gif@0.14.2/LICENSE-APACHE +0 -201
  317. package/third-party/cargo/gif@0.14.2/LICENSE-MIT +0 -21
  318. package/third-party/cargo/glam@0.33.2/Cargo.toml +0 -354
  319. package/third-party/cargo/glam@0.33.2/LICENSE-APACHE +0 -201
  320. package/third-party/cargo/glam@0.33.2/LICENSE-MIT +0 -23
  321. package/third-party/cargo/glow@0.17.0/Cargo.toml +0 -122
  322. package/third-party/cargo/glow@0.17.0/LICENSE-APACHE +0 -201
  323. package/third-party/cargo/glow@0.17.0/LICENSE-MIT +0 -23
  324. package/third-party/cargo/glow@0.17.0/LICENSE-ZLIB +0 -15
  325. package/third-party/cargo/gltf-derive@1.4.1/Cargo.toml +0 -34
  326. package/third-party/cargo/gltf-derive@1.4.1/LICENSE-APACHE +0 -202
  327. package/third-party/cargo/gltf-derive@1.4.1/LICENSE-MIT +0 -26
  328. package/third-party/cargo/gltf-json@1.4.1/Cargo.toml +0 -50
  329. package/third-party/cargo/gltf-json@1.4.1/LICENSE-APACHE +0 -202
  330. package/third-party/cargo/gltf-json@1.4.1/LICENSE-MIT +0 -26
  331. package/third-party/cargo/gltf@1.4.1/Cargo.toml +0 -122
  332. package/third-party/cargo/gltf@1.4.1/LICENSE-APACHE +0 -202
  333. package/third-party/cargo/gltf@1.4.1/LICENSE-MIT +0 -26
  334. package/third-party/cargo/glyphon@0.12.0/Cargo.toml +0 -35
  335. package/third-party/cargo/glyphon@0.12.0/LICENSE-APACHE +0 -201
  336. package/third-party/cargo/glyphon@0.12.0/LICENSE-MIT +0 -23
  337. package/third-party/cargo/glyphon@0.12.0/LICENSE-ZLIB +0 -15
  338. package/third-party/cargo/gpu-allocator@0.28.0/Cargo.toml +0 -180
  339. package/third-party/cargo/gpu-allocator@0.28.0/LICENSE-APACHE +0 -201
  340. package/third-party/cargo/gpu-allocator@0.28.0/LICENSE-MIT +0 -7
  341. package/third-party/cargo/grid@1.0.1/Cargo.toml +0 -77
  342. package/third-party/cargo/grid@1.0.1/LICENSE +0 -21
  343. package/third-party/cargo/half@2.7.1/Cargo.toml +0 -137
  344. package/third-party/cargo/half@2.7.1/LICENSE-APACHE +0 -176
  345. package/third-party/cargo/half@2.7.1/LICENSE-MIT +0 -19
  346. package/third-party/cargo/harfrust@0.5.2/Cargo.toml +0 -115
  347. package/third-party/cargo/harfrust@0.5.2/harfbuzz-harfrust-efdae3142ab7-LICENSE +0 -22
  348. package/third-party/cargo/hashbrown@0.16.1/Cargo.toml +0 -180
  349. package/third-party/cargo/hashbrown@0.16.1/LICENSE-APACHE +0 -201
  350. package/third-party/cargo/hashbrown@0.16.1/LICENSE-MIT +0 -25
  351. package/third-party/cargo/hashbrown@0.17.1/Cargo.toml +0 -201
  352. package/third-party/cargo/hashbrown@0.17.1/LICENSE-APACHE +0 -201
  353. package/third-party/cargo/hashbrown@0.17.1/LICENSE-MIT +0 -25
  354. package/third-party/cargo/httpdate@1.0.3/Cargo.toml +0 -35
  355. package/third-party/cargo/httpdate@1.0.3/LICENSE-APACHE +0 -201
  356. package/third-party/cargo/httpdate@1.0.3/LICENSE-MIT +0 -19
  357. package/third-party/cargo/image-webp@0.2.4/Cargo.toml +0 -63
  358. package/third-party/cargo/image-webp@0.2.4/LICENSE-APACHE +0 -177
  359. package/third-party/cargo/image-webp@0.2.4/LICENSE-MIT +0 -25
  360. package/third-party/cargo/image@0.25.10/Cargo.toml +0 -248
  361. package/third-party/cargo/image@0.25.10/LICENSE-APACHE +0 -177
  362. package/third-party/cargo/image@0.25.10/LICENSE-MIT +0 -25
  363. package/third-party/cargo/imagesize@0.14.0/Cargo.toml +0 -104
  364. package/third-party/cargo/imagesize@0.14.0/LICENSE +0 -21
  365. package/third-party/cargo/indexmap@2.14.0/Cargo.toml +0 -167
  366. package/third-party/cargo/indexmap@2.14.0/LICENSE-APACHE +0 -201
  367. package/third-party/cargo/indexmap@2.14.0/LICENSE-MIT +0 -25
  368. package/third-party/cargo/inflections@1.1.1/Cargo.toml +0 -21
  369. package/third-party/cargo/inflections@1.1.1/LICENSE +0 -20
  370. package/third-party/cargo/itoa@1.0.18/Cargo.toml +0 -66
  371. package/third-party/cargo/itoa@1.0.18/LICENSE-APACHE +0 -176
  372. package/third-party/cargo/itoa@1.0.18/LICENSE-MIT +0 -23
  373. package/third-party/cargo/js-sys@0.3.103/Cargo.toml +0 -98
  374. package/third-party/cargo/js-sys@0.3.103/LICENSE-APACHE +0 -201
  375. package/third-party/cargo/js-sys@0.3.103/LICENSE-MIT +0 -25
  376. package/third-party/cargo/khronos-egl@6.0.0/Cargo.toml +0 -82
  377. package/third-party/cargo/khronos-egl@6.0.0/LICENSE-APACHE +0 -201
  378. package/third-party/cargo/khronos-egl@6.0.0/LICENSE-MIT +0 -23
  379. package/third-party/cargo/kurbo@0.13.1/Cargo.toml +0 -230
  380. package/third-party/cargo/kurbo@0.13.1/LICENSE-APACHE +0 -202
  381. package/third-party/cargo/kurbo@0.13.1/LICENSE-MIT +0 -25
  382. package/third-party/cargo/lazy_static@1.5.0/Cargo.toml +0 -46
  383. package/third-party/cargo/lazy_static@1.5.0/LICENSE-APACHE +0 -201
  384. package/third-party/cargo/lazy_static@1.5.0/LICENSE-MIT +0 -25
  385. package/third-party/cargo/libc@0.2.186/Cargo.toml +0 -229
  386. package/third-party/cargo/libc@0.2.186/LICENSE-APACHE +0 -176
  387. package/third-party/cargo/libc@0.2.186/LICENSE-MIT +0 -25
  388. package/third-party/cargo/libloading@0.8.9/Cargo.toml +0 -90
  389. package/third-party/cargo/libloading@0.8.9/LICENSE +0 -12
  390. package/third-party/cargo/libm@0.2.16/Cargo.toml +0 -61
  391. package/third-party/cargo/libm@0.2.16/LICENSE.txt +0 -258
  392. package/third-party/cargo/linebender_resource_handle@0.1.1/Cargo.toml +0 -107
  393. package/third-party/cargo/linebender_resource_handle@0.1.1/LICENSE-APACHE +0 -176
  394. package/third-party/cargo/linebender_resource_handle@0.1.1/LICENSE-MIT +0 -19
  395. package/third-party/cargo/litrs@1.0.0/Cargo.toml +0 -63
  396. package/third-party/cargo/litrs@1.0.0/LICENSE-APACHE +0 -176
  397. package/third-party/cargo/litrs@1.0.0/LICENSE-MIT +0 -25
  398. package/third-party/cargo/lock_api@0.4.14/Cargo.toml +0 -68
  399. package/third-party/cargo/lock_api@0.4.14/LICENSE-APACHE +0 -201
  400. package/third-party/cargo/lock_api@0.4.14/LICENSE-MIT +0 -25
  401. package/third-party/cargo/log@0.4.33/Cargo.toml +0 -152
  402. package/third-party/cargo/log@0.4.33/LICENSE-APACHE +0 -201
  403. package/third-party/cargo/log@0.4.33/LICENSE-MIT +0 -25
  404. package/third-party/cargo/lru@0.16.4/Cargo.toml +0 -47
  405. package/third-party/cargo/lru@0.16.4/LICENSE +0 -21
  406. package/third-party/cargo/lyon_geom@1.0.19/Cargo.toml +0 -69
  407. package/third-party/cargo/lyon_geom@1.0.19/nical-lyon-56219c95c658-LICENSE-APACHE +0 -13
  408. package/third-party/cargo/lyon_geom@1.0.19/nical-lyon-56219c95c658-LICENSE-MIT +0 -20
  409. package/third-party/cargo/lyon_path@1.0.19/Cargo.toml +0 -58
  410. package/third-party/cargo/lyon_path@1.0.19/nical-lyon-56219c95c658-LICENSE-APACHE +0 -13
  411. package/third-party/cargo/lyon_path@1.0.19/nical-lyon-56219c95c658-LICENSE-MIT +0 -20
  412. package/third-party/cargo/lyon_tessellation@1.0.20/Cargo.toml +0 -71
  413. package/third-party/cargo/lyon_tessellation@1.0.20/nical-lyon-7fa75ea8eea3-LICENSE-APACHE +0 -13
  414. package/third-party/cargo/lyon_tessellation@1.0.20/nical-lyon-7fa75ea8eea3-LICENSE-MIT +0 -20
  415. package/third-party/cargo/memchr@2.8.3/COPYING +0 -3
  416. package/third-party/cargo/memchr@2.8.3/Cargo.toml +0 -89
  417. package/third-party/cargo/memchr@2.8.3/LICENSE-MIT +0 -21
  418. package/third-party/cargo/memchr@2.8.3/UNLICENSE +0 -24
  419. package/third-party/cargo/memmap2@0.9.11/Cargo.toml +0 -59
  420. package/third-party/cargo/memmap2@0.9.11/LICENSE-APACHE +0 -201
  421. package/third-party/cargo/memmap2@0.9.11/LICENSE-MIT +0 -26
  422. package/third-party/cargo/miniz_oxide@0.8.9/Cargo.toml +0 -91
  423. package/third-party/cargo/miniz_oxide@0.8.9/LICENSE +0 -25
  424. package/third-party/cargo/miniz_oxide@0.8.9/LICENSE-APACHE.md +0 -177
  425. package/third-party/cargo/miniz_oxide@0.8.9/LICENSE-MIT.md +0 -24
  426. package/third-party/cargo/miniz_oxide@0.8.9/LICENSE-ZLIB.md +0 -14
  427. package/third-party/cargo/moxcms@0.8.1/Cargo.toml +0 -113
  428. package/third-party/cargo/moxcms@0.8.1/LICENSE-APACHE.md +0 -201
  429. package/third-party/cargo/moxcms@0.8.1/LICENSE.md +0 -26
  430. package/third-party/cargo/naga-types@30.0.0/Cargo.toml +0 -94
  431. package/third-party/cargo/naga-types@30.0.0/LICENSE.APACHE +0 -176
  432. package/third-party/cargo/naga-types@30.0.0/LICENSE.MIT +0 -21
  433. package/third-party/cargo/naga@30.0.0/Cargo.toml +0 -246
  434. package/third-party/cargo/naga@30.0.0/LICENSE.APACHE +0 -176
  435. package/third-party/cargo/naga@30.0.0/LICENSE.MIT +0 -21
  436. package/third-party/cargo/num-traits@0.2.19/Cargo.toml +0 -54
  437. package/third-party/cargo/num-traits@0.2.19/LICENSE-APACHE +0 -201
  438. package/third-party/cargo/num-traits@0.2.19/LICENSE-MIT +0 -25
  439. package/third-party/cargo/objc2-core-foundation@0.3.2/Cargo.toml +0 -221
  440. package/third-party/cargo/objc2-core-foundation@0.3.2/MIT-terms.txt +0 -22
  441. package/third-party/cargo/objc2-core-foundation@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +0 -34
  442. package/third-party/cargo/objc2-core-graphics@0.3.2/Cargo.toml +0 -331
  443. package/third-party/cargo/objc2-core-graphics@0.3.2/MIT-terms.txt +0 -22
  444. package/third-party/cargo/objc2-core-graphics@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +0 -34
  445. package/third-party/cargo/objc2-encode@4.1.0/Cargo.toml +0 -81
  446. package/third-party/cargo/objc2-encode@4.1.0/MIT-terms.txt +0 -22
  447. package/third-party/cargo/objc2-encode@4.1.0/madsmtm-objc2-8d214f547736-LICENSE.md +0 -34
  448. package/third-party/cargo/objc2-foundation@0.3.2/Cargo.toml +0 -529
  449. package/third-party/cargo/objc2-foundation@0.3.2/MIT-terms.txt +0 -22
  450. package/third-party/cargo/objc2-foundation@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +0 -34
  451. package/third-party/cargo/objc2-io-surface@0.3.2/Cargo.toml +0 -139
  452. package/third-party/cargo/objc2-io-surface@0.3.2/MIT-terms.txt +0 -22
  453. package/third-party/cargo/objc2-io-surface@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +0 -34
  454. package/third-party/cargo/objc2-metal@0.3.2/Cargo.toml +0 -601
  455. package/third-party/cargo/objc2-metal@0.3.2/MIT-terms.txt +0 -22
  456. package/third-party/cargo/objc2-metal@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +0 -34
  457. package/third-party/cargo/objc2-quartz-core@0.3.2/Cargo.toml +0 -302
  458. package/third-party/cargo/objc2-quartz-core@0.3.2/MIT-terms.txt +0 -22
  459. package/third-party/cargo/objc2-quartz-core@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +0 -34
  460. package/third-party/cargo/objc2@0.6.4/Cargo.toml +0 -232
  461. package/third-party/cargo/objc2@0.6.4/MIT-terms.txt +0 -22
  462. package/third-party/cargo/objc2@0.6.4/madsmtm-objc2-8852b424193c-LICENSE.md +0 -34
  463. package/third-party/cargo/once_cell@1.21.4/Cargo.toml +0 -119
  464. package/third-party/cargo/once_cell@1.21.4/LICENSE-APACHE +0 -201
  465. package/third-party/cargo/once_cell@1.21.4/LICENSE-MIT +0 -23
  466. package/third-party/cargo/ordered-float@5.3.0/Cargo.toml +0 -162
  467. package/third-party/cargo/ordered-float@5.3.0/LICENSE-MIT +0 -25
  468. package/third-party/cargo/parking_lot@0.12.5/Cargo.toml +0 -87
  469. package/third-party/cargo/parking_lot@0.12.5/LICENSE-APACHE +0 -201
  470. package/third-party/cargo/parking_lot@0.12.5/LICENSE-MIT +0 -25
  471. package/third-party/cargo/parking_lot_core@0.9.12/Cargo.toml +0 -72
  472. package/third-party/cargo/parking_lot_core@0.9.12/LICENSE-APACHE +0 -201
  473. package/third-party/cargo/parking_lot_core@0.9.12/LICENSE-MIT +0 -25
  474. package/third-party/cargo/pico-args@0.5.0/Cargo.toml +0 -32
  475. package/third-party/cargo/pico-args@0.5.0/LICENSE +0 -20
  476. package/third-party/cargo/pin-project-lite@0.2.17/Cargo.toml +0 -198
  477. package/third-party/cargo/pin-project-lite@0.2.17/LICENSE-APACHE +0 -177
  478. package/third-party/cargo/pin-project-lite@0.2.17/LICENSE-MIT +0 -23
  479. package/third-party/cargo/pkg-config@0.3.33/Cargo.toml +0 -43
  480. package/third-party/cargo/pkg-config@0.3.33/LICENSE-APACHE +0 -201
  481. package/third-party/cargo/pkg-config@0.3.33/LICENSE-MIT +0 -25
  482. package/third-party/cargo/png@0.18.1/Cargo.toml +0 -130
  483. package/third-party/cargo/png@0.18.1/LICENSE-APACHE +0 -201
  484. package/third-party/cargo/png@0.18.1/LICENSE-MIT +0 -25
  485. package/third-party/cargo/pollster@0.4.0/Cargo.toml +0 -53
  486. package/third-party/cargo/pollster@0.4.0/LICENSE-APACHE +0 -201
  487. package/third-party/cargo/pollster@0.4.0/LICENSE-MIT +0 -25
  488. package/third-party/cargo/polycool@0.4.0/Cargo.toml +0 -83
  489. package/third-party/cargo/polycool@0.4.0/LICENSE-APACHE +0 -202
  490. package/third-party/cargo/polycool@0.4.0/LICENSE-MIT +0 -25
  491. package/third-party/cargo/pp-rs@0.2.1/Cargo.toml +0 -23
  492. package/third-party/cargo/pp-rs@0.2.1/LICENSE +0 -29
  493. package/third-party/cargo/presser@0.3.1/Cargo.toml +0 -58
  494. package/third-party/cargo/presser@0.3.1/LICENSE-APACHE +0 -201
  495. package/third-party/cargo/presser@0.3.1/LICENSE-MIT +0 -25
  496. package/third-party/cargo/proc-macro2@1.0.106/Cargo.toml +0 -105
  497. package/third-party/cargo/proc-macro2@1.0.106/LICENSE-APACHE +0 -176
  498. package/third-party/cargo/proc-macro2@1.0.106/LICENSE-MIT +0 -23
  499. package/third-party/cargo/profiling@1.0.18/Cargo.toml +0 -96
  500. package/third-party/cargo/profiling@1.0.18/aclysma-profiling-8271551172eb-LICENSE-APACHE +0 -201
  501. package/third-party/cargo/profiling@1.0.18/aclysma-profiling-8271551172eb-LICENSE-MIT +0 -21
  502. package/third-party/cargo/pxfm@0.1.30/Cargo.toml +0 -53
  503. package/third-party/cargo/pxfm@0.1.30/LICENSE-APACHE.md +0 -201
  504. package/third-party/cargo/pxfm@0.1.30/LICENSE.md +0 -26
  505. package/third-party/cargo/quick-error@2.0.1/Cargo.toml +0 -24
  506. package/third-party/cargo/quick-error@2.0.1/LICENSE-APACHE +0 -202
  507. package/third-party/cargo/quick-error@2.0.1/LICENSE-MIT +0 -19
  508. package/third-party/cargo/quote@1.0.46/Cargo.toml +0 -70
  509. package/third-party/cargo/quote@1.0.46/LICENSE-APACHE +0 -176
  510. package/third-party/cargo/quote@1.0.46/LICENSE-MIT +0 -23
  511. package/third-party/cargo/rangemap@1.7.1/Cargo.toml +0 -91
  512. package/third-party/cargo/rangemap@1.7.1/LICENSE-APACHE +0 -191
  513. package/third-party/cargo/rangemap@1.7.1/LICENSE-MIT +0 -7
  514. package/third-party/cargo/raw-window-handle@0.6.2/Cargo.toml +0 -56
  515. package/third-party/cargo/raw-window-handle@0.6.2/LICENSE-APACHE.md +0 -177
  516. package/third-party/cargo/raw-window-handle@0.6.2/LICENSE-MIT.md +0 -21
  517. package/third-party/cargo/raw-window-handle@0.6.2/LICENSE-ZLIB.md +0 -11
  518. package/third-party/cargo/raw-window-metal@1.1.0/Cargo.toml +0 -111
  519. package/third-party/cargo/raw-window-metal@1.1.0/LICENSE-APACHE +0 -202
  520. package/third-party/cargo/raw-window-metal@1.1.0/LICENSE-MIT +0 -17
  521. package/third-party/cargo/read-fonts@0.37.0/Cargo.toml +0 -95
  522. package/third-party/cargo/read-fonts@0.37.0/LICENSE-APACHE +0 -67
  523. package/third-party/cargo/read-fonts@0.37.0/LICENSE-MIT +0 -25
  524. package/third-party/cargo/read-fonts@0.39.2/Cargo.toml +0 -96
  525. package/third-party/cargo/read-fonts@0.39.2/LICENSE-APACHE +0 -67
  526. package/third-party/cargo/read-fonts@0.39.2/LICENSE-MIT +0 -25
  527. package/third-party/cargo/renderdoc-sys@1.1.0/Cargo.toml +0 -39
  528. package/third-party/cargo/renderdoc-sys@1.1.0/LICENSE-APACHE +0 -201
  529. package/third-party/cargo/renderdoc-sys@1.1.0/LICENSE-MIT +0 -25
  530. package/third-party/cargo/resvg@0.47.0/Cargo.toml +0 -112
  531. package/third-party/cargo/resvg@0.47.0/LICENSE-APACHE +0 -176
  532. package/third-party/cargo/resvg@0.47.0/LICENSE-MIT +0 -25
  533. package/third-party/cargo/rgb@0.8.53/Cargo.toml +0 -110
  534. package/third-party/cargo/rgb@0.8.53/LICENSE +0 -21
  535. package/third-party/cargo/roxmltree@0.21.1/Cargo.toml +0 -75
  536. package/third-party/cargo/roxmltree@0.21.1/LICENSE-APACHE +0 -201
  537. package/third-party/cargo/roxmltree@0.21.1/LICENSE-MIT +0 -21
  538. package/third-party/cargo/rustc-hash@1.1.0/Cargo.toml +0 -25
  539. package/third-party/cargo/rustc-hash@1.1.0/LICENSE-APACHE +0 -201
  540. package/third-party/cargo/rustc-hash@1.1.0/LICENSE-MIT +0 -23
  541. package/third-party/cargo/rustc-hash@2.1.3/Cargo.toml +0 -50
  542. package/third-party/cargo/rustc-hash@2.1.3/LICENSE-APACHE +0 -176
  543. package/third-party/cargo/rustc-hash@2.1.3/LICENSE-MIT +0 -23
  544. package/third-party/cargo/rustix@1.1.4/COPYRIGHT +0 -29
  545. package/third-party/cargo/rustix@1.1.4/Cargo.toml +0 -292
  546. package/third-party/cargo/rustix@1.1.4/LICENSE-APACHE +0 -201
  547. package/third-party/cargo/rustix@1.1.4/LICENSE-Apache-2.0_WITH_LLVM-exception +0 -220
  548. package/third-party/cargo/rustix@1.1.4/LICENSE-MIT +0 -23
  549. package/third-party/cargo/rustversion@1.0.23/Cargo.toml +0 -69
  550. package/third-party/cargo/rustversion@1.0.23/LICENSE-APACHE +0 -176
  551. package/third-party/cargo/rustversion@1.0.23/LICENSE-MIT +0 -23
  552. package/third-party/cargo/rustybuzz@0.20.1/Cargo.toml +0 -110
  553. package/third-party/cargo/rustybuzz@0.20.1/LICENSE +0 -22
  554. package/third-party/cargo/scopeguard@1.2.0/Cargo.toml +0 -43
  555. package/third-party/cargo/scopeguard@1.2.0/LICENSE-APACHE +0 -201
  556. package/third-party/cargo/scopeguard@1.2.0/LICENSE-MIT +0 -25
  557. package/third-party/cargo/self_cell@1.2.2/Cargo.toml +0 -33
  558. package/third-party/cargo/self_cell@1.2.2/LICENSE-APACHE +0 -201
  559. package/third-party/cargo/self_cell@1.2.2/LICENSE-GPLv2 +0 -339
  560. package/third-party/cargo/self_cell@1.3.0/Cargo.toml +0 -33
  561. package/third-party/cargo/self_cell@1.3.0/LICENSE-APACHE +0 -201
  562. package/third-party/cargo/self_cell@1.3.0/LICENSE-GPLv2 +0 -339
  563. package/third-party/cargo/serde@1.0.228/Cargo.toml +0 -84
  564. package/third-party/cargo/serde@1.0.228/LICENSE-APACHE +0 -176
  565. package/third-party/cargo/serde@1.0.228/LICENSE-MIT +0 -23
  566. package/third-party/cargo/serde_core@1.0.228/Cargo.toml +0 -87
  567. package/third-party/cargo/serde_core@1.0.228/LICENSE-APACHE +0 -176
  568. package/third-party/cargo/serde_core@1.0.228/LICENSE-MIT +0 -23
  569. package/third-party/cargo/serde_derive@1.0.228/Cargo.toml +0 -87
  570. package/third-party/cargo/serde_derive@1.0.228/LICENSE-APACHE +0 -176
  571. package/third-party/cargo/serde_derive@1.0.228/LICENSE-MIT +0 -23
  572. package/third-party/cargo/serde_json@1.0.150/Cargo.toml +0 -162
  573. package/third-party/cargo/serde_json@1.0.150/LICENSE-APACHE +0 -176
  574. package/third-party/cargo/serde_json@1.0.150/LICENSE-MIT +0 -23
  575. package/third-party/cargo/simd-adler32@0.3.10/Cargo.toml +0 -68
  576. package/third-party/cargo/simd-adler32@0.3.10/LICENSE.md +0 -21
  577. package/third-party/cargo/simplecss@0.2.2/Cargo.toml +0 -146
  578. package/third-party/cargo/simplecss@0.2.2/LICENSE-APACHE +0 -201
  579. package/third-party/cargo/simplecss@0.2.2/LICENSE-MIT +0 -21
  580. package/third-party/cargo/siphasher@1.0.3/COPYING +0 -7
  581. package/third-party/cargo/siphasher@1.0.3/Cargo.toml +0 -64
  582. package/third-party/cargo/skrifa@0.40.0/Cargo.toml +0 -86
  583. package/third-party/cargo/skrifa@0.40.0/LICENSE-APACHE +0 -67
  584. package/third-party/cargo/skrifa@0.40.0/LICENSE-MIT +0 -25
  585. package/third-party/cargo/skrifa@0.42.1/Cargo.toml +0 -86
  586. package/third-party/cargo/skrifa@0.42.1/LICENSE-APACHE +0 -67
  587. package/third-party/cargo/skrifa@0.42.1/LICENSE-MIT +0 -25
  588. package/third-party/cargo/slab@0.4.12/Cargo.toml +0 -67
  589. package/third-party/cargo/slab@0.4.12/LICENSE +0 -25
  590. package/third-party/cargo/slotmap@1.1.1/Cargo.toml +0 -83
  591. package/third-party/cargo/slotmap@1.1.1/LICENSE +0 -19
  592. package/third-party/cargo/smallvec@1.15.2/Cargo.toml +0 -103
  593. package/third-party/cargo/smallvec@1.15.2/LICENSE-APACHE +0 -201
  594. package/third-party/cargo/smallvec@1.15.2/LICENSE-MIT +0 -25
  595. package/third-party/cargo/smol_str@0.3.6/Cargo.toml +0 -155
  596. package/third-party/cargo/smol_str@0.3.6/LICENSE-APACHE +0 -201
  597. package/third-party/cargo/smol_str@0.3.6/LICENSE-MIT +0 -23
  598. package/third-party/cargo/spirv@0.4.0+sdk-1.4.341.0/Cargo.toml +0 -56
  599. package/third-party/cargo/spirv@0.4.0+sdk-1.4.341.0/gfx-rs-rspirv-8afc3d0ac8e1-LICENSE +0 -202
  600. package/third-party/cargo/static_assertions@1.1.0/Cargo.toml +0 -39
  601. package/third-party/cargo/static_assertions@1.1.0/LICENSE-APACHE +0 -202
  602. package/third-party/cargo/static_assertions@1.1.0/LICENSE-MIT +0 -21
  603. package/third-party/cargo/strict-num@0.1.1/Cargo.toml +0 -35
  604. package/third-party/cargo/strict-num@0.1.1/LICENSE +0 -19
  605. package/third-party/cargo/svgtypes@0.16.1/Cargo.toml +0 -57
  606. package/third-party/cargo/svgtypes@0.16.1/LICENSE-APACHE +0 -201
  607. package/third-party/cargo/svgtypes@0.16.1/LICENSE-MIT +0 -20
  608. package/third-party/cargo/swash@0.2.9/Cargo.toml +0 -93
  609. package/third-party/cargo/swash@0.2.9/LICENSE-APACHE +0 -201
  610. package/third-party/cargo/swash@0.2.9/LICENSE-MIT +0 -25
  611. package/third-party/cargo/syn@2.0.118/Cargo.toml +0 -272
  612. package/third-party/cargo/syn@2.0.118/LICENSE-APACHE +0 -176
  613. package/third-party/cargo/syn@2.0.118/LICENSE-MIT +0 -23
  614. package/third-party/cargo/sys-locale@0.3.2/Cargo.toml +0 -73
  615. package/third-party/cargo/sys-locale@0.3.2/LICENSE-APACHE +0 -201
  616. package/third-party/cargo/sys-locale@0.3.2/LICENSE-MIT +0 -21
  617. package/third-party/cargo/taffy@0.12.1/Cargo.toml +0 -171
  618. package/third-party/cargo/taffy@0.12.1/DioxusLabs-taffy-1c9e37a0a1cf-LICENSE.md +0 -25
  619. package/third-party/cargo/tempfile@3.27.0/Cargo.toml +0 -105
  620. package/third-party/cargo/tempfile@3.27.0/LICENSE-APACHE +0 -201
  621. package/third-party/cargo/tempfile@3.27.0/LICENSE-MIT +0 -25
  622. package/third-party/cargo/termcolor@1.4.1/COPYING +0 -3
  623. package/third-party/cargo/termcolor@1.4.1/Cargo.toml +0 -40
  624. package/third-party/cargo/termcolor@1.4.1/LICENSE-MIT +0 -21
  625. package/third-party/cargo/termcolor@1.4.1/UNLICENSE +0 -24
  626. package/third-party/cargo/thiserror-impl@2.0.18/Cargo.toml +0 -52
  627. package/third-party/cargo/thiserror-impl@2.0.18/LICENSE-APACHE +0 -176
  628. package/third-party/cargo/thiserror-impl@2.0.18/LICENSE-MIT +0 -23
  629. package/third-party/cargo/thiserror@2.0.18/Cargo.toml +0 -119
  630. package/third-party/cargo/thiserror@2.0.18/LICENSE-APACHE +0 -176
  631. package/third-party/cargo/thiserror@2.0.18/LICENSE-MIT +0 -23
  632. package/third-party/cargo/tiny-skia-path@0.12.0/Cargo.toml +0 -58
  633. package/third-party/cargo/tiny-skia-path@0.12.0/LICENSE +0 -30
  634. package/third-party/cargo/tiny-skia@0.12.0/Cargo.toml +0 -116
  635. package/third-party/cargo/tiny-skia@0.12.0/LICENSE +0 -30
  636. package/third-party/cargo/tiny_http@0.12.0/Cargo.toml +0 -82
  637. package/third-party/cargo/tiny_http@0.12.0/LICENSE-APACHE +0 -201
  638. package/third-party/cargo/tiny_http@0.12.0/LICENSE-MIT +0 -25
  639. package/third-party/cargo/tinyvec@1.12.0/Cargo.toml +0 -184
  640. package/third-party/cargo/tinyvec@1.12.0/LICENSE-APACHE.md +0 -202
  641. package/third-party/cargo/tinyvec@1.12.0/LICENSE-MIT.md +0 -5
  642. package/third-party/cargo/tinyvec@1.12.0/LICENSE-ZLIB.md +0 -11
  643. package/third-party/cargo/tinyvec_macros@0.1.1/Cargo.toml +0 -19
  644. package/third-party/cargo/tinyvec_macros@0.1.1/LICENSE-APACHE.md +0 -202
  645. package/third-party/cargo/tinyvec_macros@0.1.1/LICENSE-MIT.md +0 -21
  646. package/third-party/cargo/tinyvec_macros@0.1.1/LICENSE-ZLIB.md +0 -20
  647. package/third-party/cargo/ttf-parser@0.25.1/Cargo.toml +0 -101
  648. package/third-party/cargo/ttf-parser@0.25.1/LICENSE-APACHE +0 -201
  649. package/third-party/cargo/ttf-parser@0.25.1/LICENSE-MIT +0 -20
  650. package/third-party/cargo/unicode-bidi-mirroring@0.4.0/Cargo.toml +0 -22
  651. package/third-party/cargo/unicode-bidi-mirroring@0.4.0/LICENSE-APACHE +0 -201
  652. package/third-party/cargo/unicode-bidi-mirroring@0.4.0/LICENSE-MIT +0 -21
  653. package/third-party/cargo/unicode-bidi@0.3.18/COPYRIGHT +0 -8
  654. package/third-party/cargo/unicode-bidi@0.3.18/Cargo.toml +0 -90
  655. package/third-party/cargo/unicode-bidi@0.3.18/LICENSE-APACHE +0 -201
  656. package/third-party/cargo/unicode-bidi@0.3.18/LICENSE-MIT +0 -25
  657. package/third-party/cargo/unicode-ccc@0.4.0/Cargo.toml +0 -22
  658. package/third-party/cargo/unicode-ccc@0.4.0/LICENSE-APACHE +0 -201
  659. package/third-party/cargo/unicode-ccc@0.4.0/LICENSE-MIT +0 -21
  660. package/third-party/cargo/unicode-ident@1.0.24/Cargo.toml +0 -84
  661. package/third-party/cargo/unicode-ident@1.0.24/LICENSE-APACHE +0 -176
  662. package/third-party/cargo/unicode-ident@1.0.24/LICENSE-MIT +0 -23
  663. package/third-party/cargo/unicode-ident@1.0.24/LICENSE-UNICODE +0 -39
  664. package/third-party/cargo/unicode-linebreak@0.1.5/Cargo.toml +0 -32
  665. package/third-party/cargo/unicode-linebreak@0.1.5/LICENSE +0 -201
  666. package/third-party/cargo/unicode-properties@0.1.4/COPYRIGHT +0 -7
  667. package/third-party/cargo/unicode-properties@0.1.4/Cargo.toml +0 -65
  668. package/third-party/cargo/unicode-properties@0.1.4/LICENSE-APACHE +0 -201
  669. package/third-party/cargo/unicode-properties@0.1.4/LICENSE-MIT +0 -25
  670. package/third-party/cargo/unicode-script@0.5.8/Cargo.toml +0 -63
  671. package/third-party/cargo/unicode-script@0.5.8/LICENSE-APACHE +0 -201
  672. package/third-party/cargo/unicode-script@0.5.8/LICENSE-MIT +0 -27
  673. package/third-party/cargo/unicode-segmentation@1.13.3/COPYRIGHT +0 -7
  674. package/third-party/cargo/unicode-segmentation@1.13.3/Cargo.toml +0 -91
  675. package/third-party/cargo/unicode-segmentation@1.13.3/LICENSE-APACHE +0 -201
  676. package/third-party/cargo/unicode-segmentation@1.13.3/LICENSE-MIT +0 -25
  677. package/third-party/cargo/unicode-vo@0.1.0/Cargo.toml +0 -22
  678. package/third-party/cargo/unicode-vo@0.1.0/LICENSE-APACHE +0 -201
  679. package/third-party/cargo/unicode-vo@0.1.0/LICENSE-MIT +0 -21
  680. package/third-party/cargo/unicode-width@0.2.2/COPYRIGHT +0 -7
  681. package/third-party/cargo/unicode-width@0.2.2/Cargo.toml +0 -77
  682. package/third-party/cargo/unicode-width@0.2.2/LICENSE-APACHE +0 -201
  683. package/third-party/cargo/unicode-width@0.2.2/LICENSE-MIT +0 -25
  684. package/third-party/cargo/unicode-xid@0.2.6/COPYRIGHT +0 -7
  685. package/third-party/cargo/unicode-xid@0.2.6/Cargo.toml +0 -65
  686. package/third-party/cargo/unicode-xid@0.2.6/LICENSE-APACHE +0 -201
  687. package/third-party/cargo/unicode-xid@0.2.6/LICENSE-MIT +0 -25
  688. package/third-party/cargo/urlencoding@2.1.3/Cargo.toml +0 -41
  689. package/third-party/cargo/urlencoding@2.1.3/LICENSE +0 -20
  690. package/third-party/cargo/usvg@0.47.0/Cargo.toml +0 -138
  691. package/third-party/cargo/usvg@0.47.0/LICENSE-APACHE +0 -176
  692. package/third-party/cargo/usvg@0.47.0/LICENSE-MIT +0 -25
  693. package/third-party/cargo/version_check@0.9.5/Cargo.toml +0 -38
  694. package/third-party/cargo/version_check@0.9.5/LICENSE-APACHE +0 -201
  695. package/third-party/cargo/version_check@0.9.5/LICENSE-MIT +0 -19
  696. package/third-party/cargo/wasm-bindgen-futures@0.4.76/Cargo.toml +0 -88
  697. package/third-party/cargo/wasm-bindgen-futures@0.4.76/LICENSE-APACHE +0 -201
  698. package/third-party/cargo/wasm-bindgen-futures@0.4.76/LICENSE-MIT +0 -25
  699. package/third-party/cargo/wasm-bindgen-macro-support@0.2.126/Cargo.toml +0 -83
  700. package/third-party/cargo/wasm-bindgen-macro-support@0.2.126/LICENSE-APACHE +0 -201
  701. package/third-party/cargo/wasm-bindgen-macro-support@0.2.126/LICENSE-MIT +0 -25
  702. package/third-party/cargo/wasm-bindgen-macro@0.2.126/Cargo.toml +0 -73
  703. package/third-party/cargo/wasm-bindgen-macro@0.2.126/LICENSE-APACHE +0 -201
  704. package/third-party/cargo/wasm-bindgen-macro@0.2.126/LICENSE-MIT +0 -25
  705. package/third-party/cargo/wasm-bindgen-shared@0.2.126/Cargo.toml +0 -66
  706. package/third-party/cargo/wasm-bindgen-shared@0.2.126/LICENSE-APACHE +0 -201
  707. package/third-party/cargo/wasm-bindgen-shared@0.2.126/LICENSE-MIT +0 -25
  708. package/third-party/cargo/wasm-bindgen@0.2.126/Cargo.toml +0 -122
  709. package/third-party/cargo/wasm-bindgen@0.2.126/LICENSE-APACHE +0 -201
  710. package/third-party/cargo/wasm-bindgen@0.2.126/LICENSE-MIT +0 -25
  711. package/third-party/cargo/wayland-sys@0.31.11/Cargo.toml +0 -81
  712. package/third-party/cargo/wayland-sys@0.31.11/LICENSE.txt +0 -19
  713. package/third-party/cargo/web-sys@0.3.103/Cargo.toml +0 -2823
  714. package/third-party/cargo/web-sys@0.3.103/LICENSE-APACHE +0 -201
  715. package/third-party/cargo/web-sys@0.3.103/LICENSE-MIT +0 -25
  716. package/third-party/cargo/weezl@0.1.12/Cargo.toml +0 -120
  717. package/third-party/cargo/weezl@0.1.12/LICENSE-APACHE +0 -201
  718. package/third-party/cargo/weezl@0.1.12/LICENSE-MIT +0 -22
  719. package/third-party/cargo/wgpu-core-deps-apple@30.0.0/Cargo.toml +0 -53
  720. package/third-party/cargo/wgpu-core-deps-apple@30.0.0/LICENSE.APACHE +0 -176
  721. package/third-party/cargo/wgpu-core-deps-apple@30.0.0/LICENSE.MIT +0 -21
  722. package/third-party/cargo/wgpu-core@30.0.0/Cargo.toml +0 -237
  723. package/third-party/cargo/wgpu-core@30.0.0/LICENSE.APACHE +0 -176
  724. package/third-party/cargo/wgpu-core@30.0.0/LICENSE.MIT +0 -21
  725. package/third-party/cargo/wgpu-hal@30.0.0/Cargo.toml +0 -541
  726. package/third-party/cargo/wgpu-hal@30.0.0/LICENSE.APACHE +0 -176
  727. package/third-party/cargo/wgpu-hal@30.0.0/LICENSE.MIT +0 -21
  728. package/third-party/cargo/wgpu-naga-bridge@30.0.0/Cargo.toml +0 -46
  729. package/third-party/cargo/wgpu-naga-bridge@30.0.0/LICENSE.APACHE +0 -176
  730. package/third-party/cargo/wgpu-naga-bridge@30.0.0/LICENSE.MIT +0 -21
  731. package/third-party/cargo/wgpu-types@30.0.0/Cargo.toml +0 -161
  732. package/third-party/cargo/wgpu-types@30.0.0/LICENSE.APACHE +0 -176
  733. package/third-party/cargo/wgpu-types@30.0.0/LICENSE.MIT +0 -21
  734. package/third-party/cargo/wgpu@30.0.0/Cargo.toml +0 -278
  735. package/third-party/cargo/wgpu@30.0.0/LICENSE.APACHE +0 -176
  736. package/third-party/cargo/wgpu@30.0.0/LICENSE.MIT +0 -21
  737. package/third-party/cargo/xmlwriter@0.1.0/Cargo.toml +0 -23
  738. package/third-party/cargo/xmlwriter@0.1.0/LICENSE +0 -21
  739. package/third-party/cargo/yazi@0.2.1/Cargo.toml +0 -45
  740. package/third-party/cargo/yazi@0.2.1/LICENSE-APACHE +0 -201
  741. package/third-party/cargo/yazi@0.2.1/LICENSE-MIT +0 -19
  742. package/third-party/cargo/zeno@0.3.3/Cargo.toml +0 -65
  743. package/third-party/cargo/zeno@0.3.3/LICENSE-APACHE +0 -201
  744. package/third-party/cargo/zeno@0.3.3/LICENSE-MIT +0 -25
  745. package/third-party/cargo/zerocopy-derive@0.8.54/Cargo.toml +0 -209
  746. package/third-party/cargo/zerocopy-derive@0.8.54/LICENSE-APACHE +0 -202
  747. package/third-party/cargo/zerocopy-derive@0.8.54/LICENSE-BSD +0 -24
  748. package/third-party/cargo/zerocopy-derive@0.8.54/LICENSE-MIT +0 -26
  749. package/third-party/cargo/zerocopy@0.8.54/Cargo.toml +0 -419
  750. package/third-party/cargo/zerocopy@0.8.54/LICENSE-APACHE +0 -202
  751. package/third-party/cargo/zerocopy@0.8.54/LICENSE-BSD +0 -24
  752. package/third-party/cargo/zerocopy@0.8.54/LICENSE-MIT +0 -26
  753. package/third-party/cargo/zmij@1.0.23/Cargo.toml +0 -90
  754. package/third-party/cargo/zmij@1.0.23/LICENSE-MIT +0 -23
  755. package/third-party/cargo/zune-core@0.5.1/Cargo.toml +0 -47
  756. package/third-party/cargo/zune-core@0.5.1/LICENSE-APACHE +0 -201
  757. package/third-party/cargo/zune-core@0.5.1/LICENSE-MIT +0 -21
  758. package/third-party/cargo/zune-core@0.5.1/LICENSE-ZLIB +0 -19
  759. package/third-party/cargo/zune-jpeg@0.5.15/Cargo.toml +0 -67
  760. package/third-party/cargo/zune-jpeg@0.5.15/LICENSE-APACHE +0 -201
  761. package/third-party/cargo/zune-jpeg@0.5.15/LICENSE-MIT +0 -21
  762. package/third-party/cargo/zune-jpeg@0.5.15/LICENSE-ZLIB +0 -19
  763. package/third-party/npm/@esbuild__darwin-arm64@0.27.4/esbuild-0.27.4-LICENSE.md +0 -21
  764. package/third-party/npm/@esbuild__darwin-arm64@0.27.4/go-LICENSE +0 -27
  765. package/third-party/npm/@esbuild__darwin-arm64@0.27.4/golang-x-sys-c0bba94af5f8-LICENSE +0 -27
  766. package/third-party/npm/@esbuild__darwin-arm64@0.27.4/package.json +0 -20
  767. package/third-party/npm/@floating-ui__core@1.7.5/LICENSE +0 -20
  768. package/third-party/npm/@floating-ui__core@1.7.5/package.json +0 -63
  769. package/third-party/npm/@floating-ui__dom@1.7.6/LICENSE +0 -20
  770. package/third-party/npm/@floating-ui__dom@1.7.6/package.json +0 -71
  771. package/third-party/npm/@floating-ui__react-dom@2.1.8/LICENSE +0 -20
  772. package/third-party/npm/@floating-ui__react-dom@2.1.8/package.json +0 -76
  773. package/third-party/npm/@floating-ui__utils@0.2.11/LICENSE +0 -20
  774. package/third-party/npm/@floating-ui__utils@0.2.11/package.json +0 -70
  775. package/third-party/npm/@radix-ui__primitive@1.1.7/LICENSE +0 -21
  776. package/third-party/npm/@radix-ui__primitive@1.1.7/package.json +0 -79
  777. package/third-party/npm/@radix-ui__react-arrow@1.1.15/LICENSE +0 -21
  778. package/third-party/npm/@radix-ui__react-arrow@1.1.15/package.json +0 -68
  779. package/third-party/npm/@radix-ui__react-collection@1.1.15/LICENSE +0 -21
  780. package/third-party/npm/@radix-ui__react-collection@1.1.15/package.json +0 -71
  781. package/third-party/npm/@radix-ui__react-compose-refs@1.1.5/LICENSE +0 -21
  782. package/third-party/npm/@radix-ui__react-compose-refs@1.1.5/package.json +0 -60
  783. package/third-party/npm/@radix-ui__react-context-menu@2.3.7/LICENSE +0 -21
  784. package/third-party/npm/@radix-ui__react-context-menu@2.3.7/package.json +0 -73
  785. package/third-party/npm/@radix-ui__react-context@1.2.2/LICENSE +0 -21
  786. package/third-party/npm/@radix-ui__react-context@1.2.2/package.json +0 -60
  787. package/third-party/npm/@radix-ui__react-direction@1.1.4/LICENSE +0 -21
  788. package/third-party/npm/@radix-ui__react-direction@1.1.4/package.json +0 -60
  789. package/third-party/npm/@radix-ui__react-dismissable-layer@1.1.19/LICENSE +0 -21
  790. package/third-party/npm/@radix-ui__react-dismissable-layer@1.1.19/package.json +0 -74
  791. package/third-party/npm/@radix-ui__react-focus-guards@1.1.6/LICENSE +0 -21
  792. package/third-party/npm/@radix-ui__react-focus-guards@1.1.6/package.json +0 -60
  793. package/third-party/npm/@radix-ui__react-focus-scope@1.1.16/LICENSE +0 -21
  794. package/third-party/npm/@radix-ui__react-focus-scope@1.1.16/package.json +0 -71
  795. package/third-party/npm/@radix-ui__react-id@1.1.4/LICENSE +0 -21
  796. package/third-party/npm/@radix-ui__react-id@1.1.4/package.json +0 -63
  797. package/third-party/npm/@radix-ui__react-menu@2.1.24/LICENSE +0 -21
  798. package/third-party/npm/@radix-ui__react-menu@2.1.24/package.json +0 -86
  799. package/third-party/npm/@radix-ui__react-popper@1.3.7/LICENSE +0 -21
  800. package/third-party/npm/@radix-ui__react-popper@1.3.7/package.json +0 -78
  801. package/third-party/npm/@radix-ui__react-portal@1.1.17/LICENSE +0 -21
  802. package/third-party/npm/@radix-ui__react-portal@1.1.17/package.json +0 -69
  803. package/third-party/npm/@radix-ui__react-presence@1.1.10/LICENSE +0 -21
  804. package/third-party/npm/@radix-ui__react-presence@1.1.10/package.json +0 -68
  805. package/third-party/npm/@radix-ui__react-primitive@2.1.10/LICENSE +0 -21
  806. package/third-party/npm/@radix-ui__react-primitive@2.1.10/package.json +0 -68
  807. package/third-party/npm/@radix-ui__react-roving-focus@1.1.19/LICENSE +0 -21
  808. package/third-party/npm/@radix-ui__react-roving-focus@1.1.19/package.json +0 -78
  809. package/third-party/npm/@radix-ui__react-slot@1.3.3/LICENSE +0 -21
  810. package/third-party/npm/@radix-ui__react-slot@1.3.3/package.json +0 -63
  811. package/third-party/npm/@radix-ui__react-use-callback-ref@1.1.4/LICENSE +0 -21
  812. package/third-party/npm/@radix-ui__react-use-callback-ref@1.1.4/package.json +0 -60
  813. package/third-party/npm/@radix-ui__react-use-controllable-state@1.2.6/LICENSE +0 -21
  814. package/third-party/npm/@radix-ui__react-use-controllable-state@1.2.6/package.json +0 -65
  815. package/third-party/npm/@radix-ui__react-use-effect-event@0.0.5/LICENSE +0 -21
  816. package/third-party/npm/@radix-ui__react-use-effect-event@0.0.5/package.json +0 -65
  817. package/third-party/npm/@radix-ui__react-use-is-hydrated@0.1.3/LICENSE +0 -21
  818. package/third-party/npm/@radix-ui__react-use-is-hydrated@0.1.3/package.json +0 -61
  819. package/third-party/npm/@radix-ui__react-use-layout-effect@1.1.4/LICENSE +0 -21
  820. package/third-party/npm/@radix-ui__react-use-layout-effect@1.1.4/package.json +0 -60
  821. package/third-party/npm/@radix-ui__react-use-size@1.1.4/LICENSE +0 -21
  822. package/third-party/npm/@radix-ui__react-use-size@1.1.4/package.json +0 -63
  823. package/third-party/npm/aria-hidden@1.2.6/LICENSE +0 -21
  824. package/third-party/npm/aria-hidden@1.2.6/package.json +0 -71
  825. package/third-party/npm/detect-node-es@1.1.0/LICENSE +0 -21
  826. package/third-party/npm/detect-node-es@1.1.0/package.json +0 -29
  827. package/third-party/npm/esbuild@0.27.4/LICENSE.md +0 -21
  828. package/third-party/npm/esbuild@0.27.4/package.json +0 -49
  829. package/third-party/npm/get-nonce@1.0.1/LICENSE +0 -21
  830. package/third-party/npm/get-nonce@1.0.1/package.json +0 -68
  831. package/third-party/npm/mediabunny@1.52.2/LICENSE +0 -373
  832. package/third-party/npm/mediabunny@1.52.2/package.json +0 -136
  833. package/third-party/npm/mediabunny@1.52.2/source/LICENSE +0 -373
  834. package/third-party/npm/mediabunny@1.52.2/source/package.json +0 -136
  835. package/third-party/npm/mediabunny@1.52.2/source/src/adts/adts-demuxer.ts +0 -400
  836. package/third-party/npm/mediabunny@1.52.2/source/src/adts/adts-muxer.ts +0 -124
  837. package/third-party/npm/mediabunny@1.52.2/source/src/adts/adts-reader.ts +0 -85
  838. package/third-party/npm/mediabunny@1.52.2/source/src/aes.ts +0 -307
  839. package/third-party/npm/mediabunny@1.52.2/source/src/codec-data.ts +0 -3178
  840. package/third-party/npm/mediabunny@1.52.2/source/src/codec.ts +0 -1154
  841. package/third-party/npm/mediabunny@1.52.2/source/src/conversion.ts +0 -2042
  842. package/third-party/npm/mediabunny@1.52.2/source/src/custom-coder.ts +0 -212
  843. package/third-party/npm/mediabunny@1.52.2/source/src/decode.ts +0 -263
  844. package/third-party/npm/mediabunny@1.52.2/source/src/demuxer.ts +0 -43
  845. package/third-party/npm/mediabunny@1.52.2/source/src/encode.ts +0 -1412
  846. package/third-party/npm/mediabunny@1.52.2/source/src/flac/flac-demuxer.ts +0 -813
  847. package/third-party/npm/mediabunny@1.52.2/source/src/flac/flac-misc.ts +0 -165
  848. package/third-party/npm/mediabunny@1.52.2/source/src/flac/flac-muxer.ts +0 -350
  849. package/third-party/npm/mediabunny@1.52.2/source/src/hls/hls-demuxer.ts +0 -995
  850. package/third-party/npm/mediabunny@1.52.2/source/src/hls/hls-misc.ts +0 -81
  851. package/third-party/npm/mediabunny@1.52.2/source/src/hls/hls-muxer.ts +0 -1529
  852. package/third-party/npm/mediabunny@1.52.2/source/src/hls/hls-segmented-input.ts +0 -772
  853. package/third-party/npm/mediabunny@1.52.2/source/src/id3.ts +0 -972
  854. package/third-party/npm/mediabunny@1.52.2/source/src/index.ts +0 -319
  855. package/third-party/npm/mediabunny@1.52.2/source/src/input-format.ts +0 -819
  856. package/third-party/npm/mediabunny@1.52.2/source/src/input-track.ts +0 -1141
  857. package/third-party/npm/mediabunny@1.52.2/source/src/input.ts +0 -571
  858. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-boxes.ts +0 -1911
  859. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-demuxer.ts +0 -3953
  860. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-misc.ts +0 -90
  861. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-muxer.ts +0 -1595
  862. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-reader.ts +0 -91
  863. package/third-party/npm/mediabunny@1.52.2/source/src/logging.ts +0 -120
  864. package/third-party/npm/mediabunny@1.52.2/source/src/matroska/ebml.ts +0 -770
  865. package/third-party/npm/mediabunny@1.52.2/source/src/matroska/matroska-demuxer.ts +0 -2598
  866. package/third-party/npm/mediabunny@1.52.2/source/src/matroska/matroska-misc.ts +0 -29
  867. package/third-party/npm/mediabunny@1.52.2/source/src/matroska/matroska-muxer.ts +0 -1360
  868. package/third-party/npm/mediabunny@1.52.2/source/src/media-sink.ts +0 -2589
  869. package/third-party/npm/mediabunny@1.52.2/source/src/media-source.ts +0 -3041
  870. package/third-party/npm/mediabunny@1.52.2/source/src/metadata.ts +0 -335
  871. package/third-party/npm/mediabunny@1.52.2/source/src/misc.ts +0 -1336
  872. package/third-party/npm/mediabunny@1.52.2/source/src/mp3/mp3-demuxer.ts +0 -469
  873. package/third-party/npm/mediabunny@1.52.2/source/src/mp3/mp3-muxer.ts +0 -169
  874. package/third-party/npm/mediabunny@1.52.2/source/src/mp3/mp3-reader.ts +0 -61
  875. package/third-party/npm/mediabunny@1.52.2/source/src/mp3/mp3-writer.ts +0 -121
  876. package/third-party/npm/mediabunny@1.52.2/source/src/mpeg-ts/mpeg-ts-demuxer.ts +0 -2519
  877. package/third-party/npm/mediabunny@1.52.2/source/src/mpeg-ts/mpeg-ts-misc.ts +0 -32
  878. package/third-party/npm/mediabunny@1.52.2/source/src/mpeg-ts/mpeg-ts-muxer.ts +0 -842
  879. package/third-party/npm/mediabunny@1.52.2/source/src/muxer.ts +0 -80
  880. package/third-party/npm/mediabunny@1.52.2/source/src/node.ts +0 -11
  881. package/third-party/npm/mediabunny@1.52.2/source/src/ogg/ogg-demuxer.ts +0 -1087
  882. package/third-party/npm/mediabunny@1.52.2/source/src/ogg/ogg-misc.ts +0 -116
  883. package/third-party/npm/mediabunny@1.52.2/source/src/ogg/ogg-muxer.ts +0 -527
  884. package/third-party/npm/mediabunny@1.52.2/source/src/ogg/ogg-reader.ts +0 -93
  885. package/third-party/npm/mediabunny@1.52.2/source/src/output-format.ts +0 -1425
  886. package/third-party/npm/mediabunny@1.52.2/source/src/output.ts +0 -940
  887. package/third-party/npm/mediabunny@1.52.2/source/src/packet.ts +0 -287
  888. package/third-party/npm/mediabunny@1.52.2/source/src/pcm.ts +0 -112
  889. package/third-party/npm/mediabunny@1.52.2/source/src/reader.ts +0 -391
  890. package/third-party/npm/mediabunny@1.52.2/source/src/resample.ts +0 -287
  891. package/third-party/npm/mediabunny@1.52.2/source/src/sample.ts +0 -3231
  892. package/third-party/npm/mediabunny@1.52.2/source/src/segmented-input.ts +0 -575
  893. package/third-party/npm/mediabunny@1.52.2/source/src/source.ts +0 -2588
  894. package/third-party/npm/mediabunny@1.52.2/source/src/subtitles.ts +0 -131
  895. package/third-party/npm/mediabunny@1.52.2/source/src/target.ts +0 -871
  896. package/third-party/npm/mediabunny@1.52.2/source/src/tsconfig.json +0 -16
  897. package/third-party/npm/mediabunny@1.52.2/source/src/wave/riff-writer.ts +0 -36
  898. package/third-party/npm/mediabunny@1.52.2/source/src/wave/wave-demuxer.ts +0 -583
  899. package/third-party/npm/mediabunny@1.52.2/source/src/wave/wave-muxer.ts +0 -375
  900. package/third-party/npm/mediabunny@1.52.2/source/src/writer.ts +0 -128
  901. package/third-party/npm/react-dom@19.3.0/LICENSE +0 -21
  902. package/third-party/npm/react-dom@19.3.0/package.json +0 -117
  903. package/third-party/npm/react-remove-scroll-bar@2.3.8/package.json +0 -85
  904. package/third-party/npm/react-remove-scroll-bar@2.3.8/react-remove-scroll-bar-LICENSE +0 -21
  905. package/third-party/npm/react-remove-scroll@2.7.2/LICENSE +0 -21
  906. package/third-party/npm/react-remove-scroll@2.7.2/package.json +0 -98
  907. package/third-party/npm/react-style-singleton@2.2.3/LICENSE +0 -21
  908. package/third-party/npm/react-style-singleton@2.2.3/package.json +0 -90
  909. package/third-party/npm/react@19.3.0/LICENSE +0 -21
  910. package/third-party/npm/react@19.3.0/package.json +0 -51
  911. package/third-party/npm/scheduler@0.28.0/LICENSE +0 -21
  912. package/third-party/npm/scheduler@0.28.0/package.json +0 -27
  913. package/third-party/npm/tslib@2.8.1/LICENSE.txt +0 -12
  914. package/third-party/npm/tslib@2.8.1/package.json +0 -47
  915. package/third-party/npm/typescript@5.9.3/LICENSE.txt +0 -55
  916. package/third-party/npm/typescript@5.9.3/ThirdPartyNoticeText.txt +0 -193
  917. package/third-party/npm/typescript@5.9.3/package.json +0 -120
  918. package/third-party/npm/use-callback-ref@1.3.3/LICENSE +0 -21
  919. package/third-party/npm/use-callback-ref@1.3.3/package.json +0 -85
  920. package/third-party/npm/use-sidecar@1.1.3/LICENSE +0 -21
  921. package/third-party/npm/use-sidecar@1.1.3/package.json +0 -93
  922. package/third-party/packages/render-engine/assets/OFL.txt +0 -93
  923. package/third-party/packages/studio/public/fonts/OFL.txt +0 -93
  924. package/third-party/packages/studio/vendor/osmo-icons/LICENSE +0 -21
  925. package/third-party/packages/studio/vendor/shadcn/LICENSE +0 -21
  926. package/third-party/repository-notices.md +0 -41
  927. package/third-party/rust-standard-library/COPYRIGHT-library.html +0 -5556
  928. package/third-party/rust-standard-library/licenses/Apache-2.0.txt +0 -73
  929. package/third-party/rust-standard-library/licenses/BSD-2-Clause.txt +0 -9
  930. package/third-party/rust-standard-library/licenses/CC-BY-SA-4.0.txt +0 -427
  931. package/third-party/rust-standard-library/licenses/GCC-exception-3.1.txt +0 -30
  932. package/third-party/rust-standard-library/licenses/GPL-2.0-only.txt +0 -133
  933. package/third-party/rust-standard-library/licenses/GPL-3.0-or-later.txt +0 -202
  934. package/third-party/rust-standard-library/licenses/ISC.txt +0 -7
  935. package/third-party/rust-standard-library/licenses/LLVM-exception.txt +0 -15
  936. package/third-party/rust-standard-library/licenses/MIT.txt +0 -9
  937. package/third-party/rust-standard-library/licenses/NCSA.txt +0 -29
  938. package/third-party/rust-standard-library/licenses/OFL-1.1.txt +0 -43
  939. package/third-party/rust-standard-library/licenses/Unicode-3.0.txt +0 -39
  940. package/third-party/rust-standard-library/version.txt +0 -1
  941. package/vendor/osmo-lite +0 -0
  942. package/vendor/osmo-scene-0.1.0.tgz +0 -0
  943. package/vendor/platform.json +0 -1
@@ -1,2588 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026-present, Vanilagy and contributors
3
- *
4
- * This Source Code Form is subject to the terms of the Mozilla Public
5
- * License, v. 2.0. If a copy of the MPL was not distributed with this
6
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
- */
8
-
9
- import type { FileHandle } from 'node:fs/promises';
10
- import {
11
- assert,
12
- binarySearchLessOrEqual,
13
- clamp,
14
- closedIntervalsOverlap,
15
- FilePath,
16
- isNumber,
17
- isWebKit,
18
- MaybePromise,
19
- mergeRequestInit,
20
- normalizeHeaders,
21
- polyfillSymbolDispose,
22
- promiseWithResolvers,
23
- retriedFetch,
24
- toDataView,
25
- toUint8Array,
26
- wait,
27
- EventEmitter,
28
- } from './misc';
29
- import * as nodeAlias from './node';
30
- import { InputDisposedError } from './input';
31
- import { Logging } from './logging';
32
-
33
- polyfillSymbolDispose();
34
-
35
- const node = typeof nodeAlias !== 'undefined'
36
- ? nodeAlias // Aliasing it prevents some bundler warnings
37
- : undefined!;
38
-
39
- export type ReadResult = {
40
- bytes: Uint8Array;
41
- view: DataView;
42
- /** The offset of the bytes in the file. */
43
- offset: number;
44
- };
45
-
46
- export const DEFAULT_MIN_READ_POSITION = 0;
47
- export const DEFAULT_MAX_READ_POSITION = Infinity;
48
-
49
- /**
50
- * The events emitted by a {@link Source}, with each key being an event name and its value being the event data.
51
- * @group Input sources
52
- * @public
53
- */
54
- export type SourceEvents = {
55
- /** Emitted each time data is retrieved from the source. */
56
- read: {
57
- /** The start of the retrieved range, inclusive. */
58
- start: number;
59
- /** The end of the retrieved range, exclusive. */
60
- end: number;
61
- };
62
- };
63
-
64
- let sourceFinalizationRegistry: FinalizationRegistry<() => unknown> | null = null;
65
- if (typeof FinalizationRegistry !== 'undefined') {
66
- sourceFinalizationRegistry = new FinalizationRegistry((cleanup) => {
67
- cleanup();
68
- });
69
- }
70
-
71
- /**
72
- * The source base class, representing a resource from which bytes can be read.
73
- * @group Input sources
74
- * @public
75
- */
76
- export abstract class Source extends EventEmitter<SourceEvents> {
77
- /** @internal */
78
- abstract _getFileSize(): number | null | undefined;
79
- /** @internal */
80
- abstract _read(
81
- start: number,
82
- end: number,
83
- minReadPosition: number,
84
- maxReadPosition: number,
85
- ): MaybePromise<ReadResult | null>;
86
- /** @internal */
87
- abstract _dispose(): void;
88
- /** @internal */
89
- _disposed = false;
90
- /** @internal */
91
- _refCount = 0;
92
- /**
93
- * Used internally to mark if a source stems from an HLS reading operation. Used to suppress certain warnings.
94
- * @internal
95
- */
96
- _usedForHls = false;
97
- /**
98
- * FinalizationRegistry for rogue refs to this source that didn't get freed. It lives on the Source itself so that
99
- * in case the Source transitively points back to itself and forms a cycle (for example through a custom
100
- * CustomSource callback) that we're not leaking memory.
101
- * @internal
102
- */
103
- _refFinalizationRegistry: FinalizationRegistry<Source> | null = null;
104
-
105
- /** @internal */
106
- private _sizePromise: Promise<number | null> | null = null;
107
-
108
- constructor() {
109
- super();
110
-
111
- if (typeof FinalizationRegistry !== 'undefined') {
112
- this._refFinalizationRegistry = new FinalizationRegistry((source) => {
113
- source._decrementRefCount();
114
- });
115
- }
116
- }
117
-
118
- /**
119
- * Resolves with the total size of the file in bytes. This function is memoized, meaning only the first call
120
- * will retrieve the size.
121
- *
122
- * Returns null if the source is unsized.
123
- */
124
- async getSizeOrNull() {
125
- if (this._disposed) {
126
- throw new InputDisposedError();
127
- }
128
-
129
- return this._sizePromise ??= (async () => {
130
- let size = this._getFileSize();
131
- if (size !== undefined) {
132
- return size;
133
- }
134
-
135
- await this._read(0, 1, DEFAULT_MIN_READ_POSITION, DEFAULT_MAX_READ_POSITION);
136
- size = this._getFileSize();
137
- assert(size !== undefined);
138
-
139
- return size;
140
- })();
141
- }
142
-
143
- /**
144
- * Resolves with the total size of the file in bytes. This function is memoized, meaning only the first call
145
- * will retrieve the size.
146
- *
147
- * Throws an error if the source is unsized.
148
- */
149
- async getSize() {
150
- if (this._disposed) {
151
- throw new InputDisposedError();
152
- }
153
-
154
- const result = await this.getSizeOrNull();
155
- if (result === null) {
156
- throw new Error('Cannot determine the size of an unsized source.');
157
- }
158
-
159
- return result;
160
- }
161
-
162
- /**
163
- * Returns a new {@link RangedSource} that maps data onto this source using the given offset and length. If a length
164
- * is not provided, the ranged source spans until the end of this source's data.
165
- *
166
- * Useful for reading files that are embedded within larger files.
167
- */
168
- slice(offset: number, length?: number) {
169
- if (!Number.isInteger(offset) || offset < 0) {
170
- throw new TypeError('offset must be a non-negative integer.');
171
- }
172
- if (length !== undefined && (!Number.isInteger(length) || length < 0)) {
173
- throw new TypeError('length, when provided, must be a non-negative integer.');
174
- }
175
-
176
- return new RangedSource(this, offset, length);
177
- }
178
-
179
- /**
180
- * Called each time data is retrieved from the source. Will be called with the retrieved range (end exclusive).
181
- *
182
- * @deprecated Use `source.on('read', ({ start, end }) => ...)` instead.
183
- */
184
- onread: ((start: number, end: number) => unknown) | null = null;
185
-
186
- /** @internal */
187
- _dispatchRead(start: number, end: number) {
188
- // eslint-disable-next-line @typescript-eslint/no-deprecated
189
- this.onread?.(start, end);
190
- this._emit('read', { start, end });
191
- }
192
-
193
- /**
194
- * Creates a new `SourceRef` pointing to this source. You are expected to call `.free()` on said `SourceRef` when
195
- * you're done with it.
196
- */
197
- ref() {
198
- return new SourceRef(this);
199
- }
200
-
201
- /** @internal */
202
- _incrementRefCount() {
203
- this._refCount++;
204
- }
205
-
206
- /** @internal */
207
- _decrementRefCount() {
208
- this._refCount--;
209
-
210
- if (this._refCount === 0) {
211
- this._dispose();
212
- this._disposed = true;
213
- }
214
- }
215
- }
216
-
217
- /**
218
- * A reference to a {@link Source}, used to manage a source's lifecycle. Creating a `SourceRef` via {@link Source.ref}
219
- * increases that source's internal reference count. As long as a source has a non-zero reference count, it is assumed
220
- * to still be in use. Once all references are freed via {@link SourceRef.free}, the source gets disposed.
221
- *
222
- * @group Input sources
223
- * @public
224
- */
225
- export class SourceRef<S extends Source = Source> implements Disposable {
226
- /** @internal */
227
- private _source: S | null;
228
- /** @internal */
229
- private _freed = false;
230
-
231
- /** @internal */
232
- constructor(source: S) {
233
- if (source._disposed) {
234
- throw new Error('Cannot ref a disposed source.');
235
- }
236
-
237
- source._incrementRefCount();
238
- source._refFinalizationRegistry?.register(this, source, this);
239
-
240
- this._source = source;
241
- }
242
-
243
- /** The {@link Source} this ref references. Accessing this field throws an error after having freed the ref. */
244
- get source() {
245
- if (!this._source) {
246
- throw new Error('Can\'t get source; ref has already been freed.');
247
- }
248
-
249
- return this._source;
250
- }
251
-
252
- /** Whether or not this reference has been freed via {@link SourceRef.free}. */
253
- get freed() {
254
- return this._freed;
255
- }
256
-
257
- /**
258
- * Frees the ref, decrementing the source's internal reference count. If the source's internal reference count
259
- * reaches zero, it gets disposed. To catch bugs, this method throws if the ref is already freed.
260
- */
261
- free() {
262
- if (this._freed) {
263
- throw new Error('Illegal operation: double free on SourceRef.');
264
- }
265
-
266
- const source = this.source;
267
- assert(source._refCount > 0);
268
-
269
- source._decrementRefCount();
270
- source._refFinalizationRegistry?.unregister(this);
271
-
272
- this._freed = true;
273
- this._source = null;
274
- }
275
-
276
- /**
277
- * Calls {@link SourceRef.free}.
278
- */
279
- [Symbol.dispose]() {
280
- if (!this.freed) {
281
- this.free();
282
- }
283
- }
284
- }
285
-
286
- /**
287
- * A source which can create new sources from file paths. Required for multi-file inputs such as HLS playlists.
288
- * @public
289
- * @group Input sources
290
- */
291
- export abstract class PathedSource extends Source {
292
- constructor(
293
- /**
294
- * The path that points to the root file; the entry file of the media.
295
- *
296
- * This path may be modified by the source to indicate a redirect: an updated path to perform new requests
297
- * relative to.
298
- */
299
- public rootPath: FilePath,
300
- /** The callback that is called for each requested file; must return a {@link Source} or {@link SourceRef}. */
301
- public readonly requestHandler: (request: SourceRequest) => MaybePromise<Source | SourceRef>,
302
- ) {
303
- if (typeof rootPath !== 'string') {
304
- throw new TypeError('rootPath must be a string.');
305
- }
306
- if (typeof requestHandler !== 'function') {
307
- throw new TypeError('requestHandler must be a function.');
308
- }
309
-
310
- super();
311
- }
312
-
313
- /** @internal */
314
- _resolveRequest(request: SourceRequest): MaybePromise<SourceRef> {
315
- const result = this.requestHandler(request);
316
-
317
- const handle = (result: Source | SourceRef) => {
318
- if (!(result instanceof Source || result instanceof SourceRef)) {
319
- throw new TypeError('requestHandler must return or resolve to a Source or SourceRef.');
320
- }
321
-
322
- const ref = result instanceof Source
323
- ? result.ref()
324
- : result;
325
-
326
- ref.source._usedForHls ||= this._usedForHls;
327
-
328
- return ref;
329
- };
330
-
331
- if (result instanceof Promise) {
332
- return result.then(handle);
333
- } else {
334
- return handle(result);
335
- }
336
- }
337
- }
338
-
339
- /**
340
- * A request for a {@link Source} at the given path.
341
- * @group Input sources
342
- * @public
343
- */
344
- export type SourceRequest = {
345
- /** The requested file path. */
346
- path: FilePath;
347
- /** Whether the requested file is the root file. */
348
- isRoot: boolean;
349
- };
350
-
351
- export const sourceRequestsAreEqual = (a: SourceRequest, b: SourceRequest) => {
352
- return a.path === b.path;
353
- };
354
-
355
- /**
356
- * A custom multi-file source where each file is uniquely identified by a {@link FilePath} and can be resolved to
357
- * an arbitrary {@link Source}.
358
- *
359
- * @public
360
- * @group Input sources
361
- */
362
- export class CustomPathedSource extends PathedSource {
363
- /** @internal */
364
- _root: SourceRef | null = null;
365
- /** @internal */
366
- _rootRequest: Promise<SourceRef> | null = null;
367
-
368
- /** @internal */
369
- override _read(
370
- start: number,
371
- end: number,
372
- minReadPosition: number,
373
- maxReadPosition: number,
374
- ): MaybePromise<ReadResult | null> {
375
- if (!this._root) {
376
- if (!this._rootRequest) {
377
- const result = this._resolveRequest({ path: this.rootPath, isRoot: true });
378
-
379
- const handle = (result: Source | SourceRef) => {
380
- const ref = result instanceof Source
381
- ? result.ref()
382
- : result;
383
-
384
- this._root = ref;
385
- this._rootRequest = null;
386
-
387
- return ref;
388
- };
389
-
390
- if (result instanceof Promise) {
391
- this._rootRequest = result.then(handle);
392
- } else {
393
- handle(result);
394
- assert(this._root);
395
- }
396
- }
397
-
398
- if (this._rootRequest) {
399
- return this._rootRequest.then(ref => ref.source._read(start, end, minReadPosition, maxReadPosition));
400
- }
401
- }
402
-
403
- return this._root!.source._read(start, end, minReadPosition, maxReadPosition);
404
- }
405
-
406
- /** @internal */
407
- override _getFileSize(): number | null | undefined {
408
- if (this._root) {
409
- return this._root.source._getFileSize();
410
- }
411
-
412
- return undefined;
413
- }
414
-
415
- /** @internal */
416
- override _dispose(): void {
417
- if (this._root) {
418
- this._root.free();
419
- } else if (this._rootRequest) {
420
- void this._rootRequest
421
- .then(ref => ref.free());
422
- }
423
- }
424
- }
425
-
426
- /**
427
- * A source backed by an ArrayBuffer or ArrayBufferView, with the entire file held in memory.
428
- * @group Input sources
429
- * @public
430
- */
431
- export class BufferSource extends Source {
432
- /** @internal */
433
- _bytes: Uint8Array;
434
- /** @internal */
435
- _view: DataView;
436
- /** @internal */
437
- _onreadCalled = false;
438
-
439
- /**
440
- * Creates a new {@link BufferSource} backed by the specified `ArrayBuffer`, `SharedArrayBuffer`,
441
- * or `ArrayBufferView`.
442
- */
443
- constructor(buffer: AllowSharedBufferSource) {
444
- if (
445
- !(buffer instanceof ArrayBuffer)
446
- && !(typeof SharedArrayBuffer !== 'undefined' && buffer instanceof SharedArrayBuffer)
447
- && !ArrayBuffer.isView(buffer)
448
- ) {
449
- throw new TypeError('buffer must be an ArrayBuffer, SharedArrayBuffer, or ArrayBufferView.');
450
- }
451
-
452
- super();
453
-
454
- this._bytes = toUint8Array(buffer);
455
- this._view = toDataView(buffer);
456
- }
457
-
458
- /** @internal */
459
- _getFileSize(): number {
460
- return this._bytes.byteLength;
461
- }
462
-
463
- /** @internal */
464
- _read(): ReadResult {
465
- if (!this._onreadCalled) {
466
- // We just say the first read retrieves all bytes from the source (which, I mean, it does)
467
- this._dispatchRead(0, this._bytes.byteLength);
468
- this._onreadCalled = true;
469
- }
470
-
471
- return {
472
- bytes: this._bytes,
473
- view: this._view,
474
- offset: 0,
475
- };
476
- }
477
-
478
- /** @internal */
479
- _dispose() {}
480
- }
481
-
482
- /**
483
- * Options for {@link BlobSource}.
484
- * @group Input sources
485
- * @public
486
- */
487
- export type BlobSourceOptions = {
488
- /** The maximum number of bytes the cache is allowed to hold in memory. Defaults to 8 MiB. */
489
- maxCacheSize?: number;
490
- /**
491
- * Defaults to `true`. When `true`, Mediabunny will acquire a `ReadableStream` reader internally to efficiently read
492
- * data from the blob. Since this can lead to errors in some (very) rare cases due to browser bugs, you can set this
493
- * field to `false` to try a slower but more stable reading method.
494
- */
495
- useStreamReader?: boolean;
496
- };
497
-
498
- /**
499
- * A source backed by a [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob). Since a
500
- * [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) is also a `Blob`, this is the source to use when
501
- * reading files off the disk.
502
- * @group Input sources
503
- * @public
504
- */
505
- export class BlobSource extends Source {
506
- /** @internal */
507
- _blob: Blob;
508
- /** @internal */
509
- _options: BlobSourceOptions;
510
- /** @internal */
511
- _orchestrator: ReadOrchestrator;
512
-
513
- /**
514
- * Creates a new {@link BlobSource} backed by the specified
515
- * [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).
516
- */
517
- constructor(blob: Blob, options: BlobSourceOptions = {}) {
518
- if (!(blob instanceof Blob)) {
519
- throw new TypeError('blob must be a Blob.');
520
- }
521
- if (!options || typeof options !== 'object') {
522
- throw new TypeError('options must be an object.');
523
- }
524
- if (
525
- options.maxCacheSize !== undefined
526
- && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)
527
- ) {
528
- throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');
529
- }
530
- if (options.useStreamReader !== undefined && typeof options.useStreamReader !== 'boolean') {
531
- throw new TypeError('options.useStreamReader, when provided, must be a boolean.');
532
- }
533
-
534
- super();
535
-
536
- this._blob = blob;
537
- this._options = options;
538
-
539
- this._orchestrator = new ReadOrchestrator({
540
- maxCacheSize: options.maxCacheSize ?? (8 * 2 ** 20 /* 8 MiB */),
541
- maxWorkerCount: 4,
542
- runWorker: this._runWorker.bind(this),
543
- prefetchProfile: PREFETCH_PROFILES.fileSystem,
544
- });
545
-
546
- this._orchestrator.fileSize = blob.size;
547
- }
548
-
549
- /** @internal */
550
- _getFileSize(): number {
551
- return this._orchestrator.fileSize!; // Faster than blob.size
552
- }
553
-
554
- /** @internal */
555
- _read(
556
- start: number,
557
- end: number,
558
- minReadPosition: number,
559
- maxReadPosition: number,
560
- ): MaybePromise<ReadResult | null> {
561
- return this._orchestrator.read(start, end, minReadPosition, maxReadPosition);
562
- }
563
-
564
- /** @internal */
565
- _readers = new WeakMap<ReadWorker, ReadableStreamDefaultReader<Uint8Array> | null>();
566
-
567
- /** @internal */
568
- private async _runWorker(worker: ReadWorker) {
569
- assert(worker.strictTarget);
570
-
571
- let reader = this._readers.get(worker);
572
- if (reader === undefined) {
573
- // https://github.com/Vanilagy/mediabunny/issues/184
574
- // WebKit has critical bugs with blob.stream():
575
- // - WebKitBlobResource error 1 when streaming large files
576
- // - Memory buildup and reload loops on iOS (network process crashes)
577
- // - ReadableStream stalls under backpressure (especially video)
578
- // Affects Safari and all iOS browsers (Chrome, Firefox, etc.).
579
- // Use arrayBuffer() fallback for WebKit browsers.
580
- if ('stream' in this._blob && !isWebKit() && this._options.useStreamReader !== false) {
581
- // Get a reader of the blob starting at the required offset, and then keep it around
582
- const slice = this._blob.slice(worker.currentPos);
583
- reader = slice.stream().getReader();
584
- } else {
585
- // We'll need to use more primitive ways
586
- reader = null;
587
- }
588
-
589
- this._readers.set(worker, reader);
590
- }
591
-
592
- while (worker.currentPos < worker.targetPos && !worker.aborted) {
593
- if (reader) {
594
- const { done, value } = await reader.read();
595
- if (done) {
596
- this._orchestrator.onWorkerFinished(worker);
597
- throw new Error('Blob reader stopped unexpectedly before all requested data was read.');
598
- }
599
-
600
- if (worker.aborted) {
601
- break;
602
- }
603
-
604
- this._dispatchRead(worker.currentPos, worker.currentPos + value.length);
605
- this._orchestrator.supplyWorkerData(worker, value);
606
- } else {
607
- const data = await this._blob.slice(worker.currentPos, worker.targetPos).arrayBuffer();
608
-
609
- if (worker.aborted) {
610
- break;
611
- }
612
-
613
- this._dispatchRead(worker.currentPos, worker.currentPos + data.byteLength);
614
- this._orchestrator.supplyWorkerData(worker, new Uint8Array(data));
615
- }
616
- }
617
-
618
- this._orchestrator.signalWorkerStoppedRunning(worker);
619
-
620
- if (worker.aborted) {
621
- // MDN: "Calling this method signals a loss of interest in the stream by a consumer."
622
- await reader?.cancel();
623
- }
624
- }
625
-
626
- /** @internal */
627
- _dispose() {
628
- this._orchestrator.dispose();
629
- }
630
- }
631
-
632
- const URL_SOURCE_MIN_LOAD_AMOUNT = 0.5 * 2 ** 20; // 0.5 MiB
633
- const DEFAULT_RETRY_DELAY
634
- = ((previousAttempts, error, src) => {
635
- // Check if this could be a CORS error. If so, we cannot recover from it and
636
- // should not attempt to retry.
637
- // CORS errors are intentionally not opaque, so we need to rely on heuristics.
638
- const couldBeCorsError = error instanceof Error
639
- && (
640
- error.message.includes('Failed to fetch') // Chrome
641
- || error.message.includes('Load failed') // Safari
642
- || error.message.includes('NetworkError when attempting to fetch resource') // Firefox
643
- )
644
- && typeof window !== 'undefined'; // CORS only happens in browser environments
645
-
646
- if (couldBeCorsError) {
647
- let originOfSrc: string | null = null;
648
- // Checking if the origin is different, because only then a CORS error could originate
649
- try {
650
- if (typeof window !== 'undefined' && typeof window.location !== 'undefined') {
651
- originOfSrc = new URL(src instanceof Request ? src.url : src, window.location.href).origin;
652
- }
653
- } catch {
654
- // URL parse failed
655
- }
656
-
657
- // If user is offline, it is probably not a CORS error.
658
- const isOnline
659
- = typeof navigator !== 'undefined' && typeof navigator.onLine === 'boolean' ? navigator.onLine : true;
660
-
661
- if (isOnline && originOfSrc !== null && originOfSrc !== window.location.origin) {
662
- Logging._warn(
663
- `Request will not be retried because a CORS error was suspected due to different origins. You can`
664
- + ` modify this behavior by providing your own function for the 'getRetryDelay' option.`,
665
- );
666
- return null;
667
- }
668
- }
669
-
670
- return Math.min(2 ** (previousAttempts - 2), 16);
671
- }) satisfies UrlSourceOptions['getRetryDelay'];
672
-
673
- const warnedOrigins = new Set<string>();
674
-
675
- /**
676
- * Options for {@link UrlSource}.
677
- * @group Input sources
678
- * @public
679
- */
680
- export type UrlSourceOptions = {
681
- /**
682
- * The [`RequestInit`](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit) used by the Fetch API. Can be
683
- * used to further control the requests, such as setting custom headers.
684
- *
685
- * The `signal` field is not available, as Mediabunny controls request cancellation internally. If you want to
686
- * cancel ongoing requests, use {@link Input.dispose}.
687
- */
688
- requestInit?: Omit<RequestInit, 'signal'>;
689
-
690
- /**
691
- * A function that returns the delay (in seconds) before retrying a failed request. The function is called
692
- * with the number of previous, unsuccessful attempts, as well as with the error with which the previous request
693
- * failed. If the function returns `null`, no more retries will be made.
694
- *
695
- * By default, it uses an exponential backoff algorithm that never gives up unless
696
- * a CORS error is suspected (`fetch()` did reject, `navigator.onLine` is true and origin is different).
697
- */
698
- getRetryDelay?: (previousAttempts: number, error: unknown, url: string | URL | Request) => number | null;
699
-
700
- /** The maximum number of bytes the cache is allowed to hold in memory. Defaults to 64 MiB. */
701
- maxCacheSize?: number;
702
-
703
- /** The maximum number of parallel requests to use for fetching. Defaults to 2. */
704
- parallelism?: number;
705
-
706
- /**
707
- * A WHATWG-compatible fetch function. You can use this field to polyfill the `fetch` function, add missing
708
- * features, or use a custom implementation.
709
- */
710
- fetchFn?: typeof fetch;
711
- };
712
-
713
- /**
714
- * A source backed by a URL. This is useful for reading data from the network. Requests will be made using an optimized
715
- * reading and prefetching pattern to minimize request count and latency.
716
- * @group Input sources
717
- * @public
718
- */
719
- export class UrlSource extends PathedSource {
720
- /** @internal */
721
- _url: string | URL | Request;
722
- /** @internal */
723
- _getRetryDelay: (previousAttempts: number, error: unknown, url: string | URL | Request) => number | null;
724
- /** @internal */
725
- _options: UrlSourceOptions;
726
- /** @internal */
727
- _requestInit: RequestInit;
728
- /** @internal */
729
- _offset = 0;
730
- /** @internal */
731
- _length: number | null = null;
732
- /** @internal */
733
- _orchestrator: ReadOrchestrator;
734
- /**
735
- * Note that this value being true does NOT mean the file size can't change anymore; it just signals that we have at
736
- * least checked if we know the file size or not.
737
- * @internal
738
- */
739
- _fileSizeDetermined = false;
740
-
741
- /**
742
- * Creates a new {@link UrlSource} backed by the resource at the specified URL.
743
- *
744
- * When passing a `Request` instance, note that its `signal` will be overridden by Mediabunny; if you want to cancel
745
- * ongoing requests, use {@link Input.dispose}.
746
- */
747
- constructor(
748
- url: string | URL | Request,
749
- options: UrlSourceOptions = {},
750
- ) {
751
- if (
752
- typeof url !== 'string'
753
- && !(url instanceof URL)
754
- && !(typeof Request !== 'undefined' && url instanceof Request)
755
- ) {
756
- throw new TypeError('url must be a string, URL or Request.');
757
- }
758
- if (!options || typeof options !== 'object') {
759
- throw new TypeError('options must be an object.');
760
- }
761
- if (options.requestInit !== undefined && (!options.requestInit || typeof options.requestInit !== 'object')) {
762
- throw new TypeError('options.requestInit, when provided, must be an object.');
763
- }
764
- if (options.getRetryDelay !== undefined && typeof options.getRetryDelay !== 'function') {
765
- throw new TypeError('options.getRetryDelay, when provided, must be a function.');
766
- }
767
- if (
768
- options.maxCacheSize !== undefined
769
- && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)
770
- ) {
771
- throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');
772
- }
773
- if (options.parallelism !== undefined && (!Number.isInteger(options.parallelism) || options.parallelism < 1)) {
774
- throw new TypeError('options.parallelism, when provided, must be a positive number.');
775
- }
776
- if (options.fetchFn !== undefined && typeof options.fetchFn !== 'function') {
777
- throw new TypeError('options.fetchFn, when provided, must be a function.');
778
- // Won't bother validating this function beyond this
779
- }
780
-
781
- const urlString = url instanceof Request
782
- ? url.url
783
- : url instanceof URL
784
- ? url.href
785
- : url;
786
-
787
- super(
788
- urlString,
789
- request => new UrlSource(request.path, this._options),
790
- );
791
-
792
- this._url = url;
793
- this._options = options;
794
- this._getRetryDelay = options.getRetryDelay ?? DEFAULT_RETRY_DELAY;
795
-
796
- // A user-supplied Range header is interpreted as a byte offset (and optional length) into the resource. We
797
- // pull it out of the request and remember it for subsequent requests.
798
- this._requestInit = { ...options.requestInit };
799
-
800
- let rangeHeaderValue: string | null = null;
801
-
802
- if (options.requestInit?.headers) {
803
- const headers = { ...normalizeHeaders(options.requestInit.headers) };
804
- const rangeKey = Object.keys(headers).find(key => key.toLowerCase() === 'range');
805
- if (rangeKey !== undefined) {
806
- rangeHeaderValue = headers[rangeKey]!;
807
- delete headers[rangeKey];
808
- this._requestInit.headers = headers;
809
- }
810
- }
811
-
812
- if (url instanceof Request) {
813
- const requestRange = url.headers.get('Range');
814
- if (requestRange !== null) {
815
- rangeHeaderValue ??= requestRange;
816
-
817
- // Clone the request so we don't mutate the user's object, then strip the Range header
818
- const strippedRequest = new Request(url);
819
- strippedRequest.headers.delete('Range');
820
- this._url = strippedRequest;
821
- }
822
- }
823
-
824
- if (rangeHeaderValue !== null) {
825
- const parsed = parseByteRangeHeader(rangeHeaderValue);
826
- if (parsed) {
827
- this._offset = parsed.offset;
828
- this._length = parsed.length;
829
- }
830
- }
831
-
832
- // Most files in the real-world have a single sequential access pattern, but having two in parallel can
833
- // also happen
834
- const DEFAULT_PARALLELISM = 2;
835
-
836
- this._orchestrator = new ReadOrchestrator({
837
- maxCacheSize: options.maxCacheSize ?? (64 * 2 ** 20 /* 64 MiB */),
838
- maxWorkerCount: options.parallelism ?? DEFAULT_PARALLELISM,
839
- runWorker: this._runWorker.bind(this),
840
- prefetchProfile: PREFETCH_PROFILES.network,
841
- });
842
- }
843
-
844
- /** @internal */
845
- _getFileSize(): number | null | undefined {
846
- if (!this._fileSizeDetermined) {
847
- return this._length !== null ? this._length : undefined;
848
- }
849
-
850
- const baseSize = this._orchestrator.fileSize;
851
- if (baseSize === null) {
852
- return this._length !== null ? this._length : null;
853
- }
854
-
855
- return clamp(baseSize - this._offset, 0, this._length ?? Infinity);
856
- }
857
-
858
- /** @internal */
859
- _read(
860
- start: number,
861
- end: number,
862
- minReadPosition: number,
863
- maxReadPosition: number,
864
- ): MaybePromise<ReadResult | null> {
865
- if (this._length !== null && end > this._length) {
866
- return null;
867
- }
868
-
869
- const offset = this._offset;
870
- const result = this._orchestrator.read(
871
- offset + start,
872
- offset + end,
873
- Math.max(offset + minReadPosition, offset),
874
- offset + Math.min(maxReadPosition, this._length ?? Infinity),
875
- );
876
-
877
- const processResult = (result: ReadResult | null) => {
878
- if (!result) {
879
- return null;
880
- }
881
-
882
- result.offset -= this._offset;
883
- return result;
884
- };
885
-
886
- if (result instanceof Promise) {
887
- return result.then(processResult);
888
- } else {
889
- return processResult(result);
890
- }
891
- }
892
-
893
- /** @internal */
894
- private async _runWorker(worker: ReadWorker) {
895
- // The outer loop is for resuming a request if it dies mid-response
896
- while (true) {
897
- const abortController = new AbortController();
898
- const response = await retriedFetch(
899
- this._options.fetchFn ?? fetch,
900
- this._url,
901
- mergeRequestInit(this._requestInit, {
902
- headers: {
903
- // Always sending a range request is a good way to probe if the server supports them
904
- Range: `bytes=${worker.currentPos}-`,
905
- },
906
- signal: abortController.signal,
907
- }),
908
- this._getRetryDelay,
909
- () => this._disposed,
910
- );
911
-
912
- if (!response.ok) {
913
- // eslint-disable-next-line @typescript-eslint/no-base-to-string
914
- throw new Error(`Error fetching ${String(this._url)}: ${response.status} ${response.statusText}`);
915
- }
916
-
917
- if (response.redirected) {
918
- // Modify our own root path so that future subrequests get made relative to the redirected URL
919
- this.rootPath = response.url;
920
- }
921
-
922
- outer:
923
- if (this._orchestrator.fileSize === null) {
924
- // See if we can deduce the file size from the response
925
-
926
- const contentRange = response.headers.get('Content-Range');
927
- if (contentRange) {
928
- const match = /\/(\d+)/.exec(contentRange);
929
- if (match) {
930
- this._orchestrator.supplyFileSize(Number(match[1]));
931
- break outer;
932
- }
933
- }
934
-
935
- const contentLength = response.headers.get('Content-Length');
936
- if (contentLength) {
937
- // Note: For range requests, this is _technically_ not correct, as the range response could contain
938
- // less data than was requested. In practice, it seems most servers don't do this though, and the
939
- // Content-Length header actually contains the length until the end of the file.
940
- this._orchestrator.supplyFileSize(worker.currentPos + Number(contentLength));
941
- }
942
- }
943
-
944
- this._fileSizeDetermined = true; // Yes, this is correct even if file size is still null
945
-
946
- if (response.status !== 206) {
947
- if (!this._usedForHls) {
948
- const url = new URL(
949
- this._url instanceof Request ? this._url.url : this._url,
950
- typeof window !== 'undefined' ? window.location.href : undefined,
951
- );
952
-
953
- if (
954
- url.origin !== 'null'
955
- // Don't show the warning for M3U8 playlist files, it's irrelevant for those
956
- && !(url.pathname.endsWith('.m3u8') || url.pathname.endsWith('.m3u'))
957
- ) {
958
- if (!warnedOrigins.has(url.origin)) {
959
- Logging._warn(
960
- `HTTP server (origin ${url.origin}) did not respond to a range request with 206 Partial`
961
- + ' Content, meaning the entire resource will now be downloaded. To enable efficient'
962
- + ' media file streaming across a network, please make sure your server supports'
963
- + ' range requests.',
964
- );
965
- warnedOrigins.add(url.origin);
966
- }
967
- }
968
- }
969
-
970
- worker.currentPos = 0;
971
- this._orchestrator.options.maxCacheSize = Infinity; // 🤷
972
-
973
- if (this._orchestrator.fileSize !== null) {
974
- worker.targetPos = this._orchestrator.fileSize;
975
- } else {
976
- // The server is dumb, doesn't even surface the content length, but we'll work with it.
977
- worker.targetPos = Infinity;
978
- worker.strictTarget = false;
979
- }
980
-
981
- this._orchestrator.consolidateEverythingIntoOneWorker(worker);
982
- }
983
-
984
- if (!response.body) {
985
- throw new Error(
986
- 'Missing HTTP response body stream. The used fetch function must provide the response body as a'
987
- + ' ReadableStream.',
988
- );
989
- }
990
-
991
- const reader = response.body.getReader();
992
-
993
- while (true) {
994
- if (worker.currentPos >= worker.targetPos || worker.aborted) {
995
- abortController.abort();
996
- this._orchestrator.signalWorkerStoppedRunning(worker);
997
-
998
- return;
999
- }
1000
-
1001
- let readResult: ReadableStreamReadResult<Uint8Array>;
1002
-
1003
- try {
1004
- readResult = await reader.read();
1005
- } catch (error) {
1006
- if (this._disposed) {
1007
- // No need to try to retry
1008
- throw error;
1009
- }
1010
-
1011
- const retryDelayInSeconds = this._getRetryDelay(1, error, this._url);
1012
- if (retryDelayInSeconds !== null) {
1013
- Logging._error('Error while reading response stream. Attempting to resume.', error);
1014
- await wait(1000 * retryDelayInSeconds);
1015
-
1016
- break;
1017
- } else {
1018
- throw error;
1019
- }
1020
- }
1021
-
1022
- if (worker.aborted) {
1023
- continue; // Cleanup happens in next iteration
1024
- }
1025
-
1026
- const { done, value } = readResult;
1027
-
1028
- if (done) {
1029
- if (worker.currentPos >= worker.targetPos) {
1030
- // All data was delivered, we're good
1031
- this._orchestrator.onWorkerFinished(worker);
1032
- return;
1033
- }
1034
-
1035
- if (worker.strictTarget) {
1036
- // The response stopped early, before the target. This can happen if server decides to cap range
1037
- // requests arbitrarily, even if the request had an uncapped end. In this case, let's fetch the
1038
- // rest of the data using a new request.
1039
- break;
1040
- } else {
1041
- // Assume we have simply reached the end of the resource
1042
- this._orchestrator.onWorkerFinished(worker);
1043
- return;
1044
- }
1045
- }
1046
-
1047
- this._dispatchRead(worker.currentPos, worker.currentPos + value.length);
1048
- this._orchestrator.supplyWorkerData(worker, value);
1049
- }
1050
- }
1051
-
1052
- // The previous UrlSource had logic for circumventing https://issues.chromium.org/issues/436025873; I haven't
1053
- // been able to observe this bug with the new UrlSource (maybe because we're using response streaming), so the
1054
- // logic for that has vanished for now. Leaving a comment here if this becomes relevant again.
1055
- }
1056
-
1057
- /** @internal */
1058
- _dispose() {
1059
- this._orchestrator.dispose();
1060
- }
1061
- }
1062
-
1063
- const BYTE_RANGE_REGEX = /^bytes=(\d+)-(\d*)$/;
1064
- const parseByteRangeHeader = (value: string) => {
1065
- const match = BYTE_RANGE_REGEX.exec(value.trim());
1066
- if (!match) {
1067
- return null;
1068
- }
1069
-
1070
- const offset = Number(match[1]);
1071
- const end = match[2] === '' ? null : Number(match[2]);
1072
-
1073
- if (end !== null && end < offset) {
1074
- return null;
1075
- }
1076
-
1077
- return {
1078
- offset,
1079
- length: end !== null ? end - offset + 1 : null,
1080
- };
1081
- };
1082
-
1083
- /**
1084
- * Options for {@link FilePathSource}.
1085
- * @group Input sources
1086
- * @public
1087
- */
1088
- export type FilePathSourceOptions = {
1089
- /** The maximum number of bytes the cache is allowed to hold in memory. Defaults to 8 MiB. */
1090
- maxCacheSize?: number;
1091
- };
1092
-
1093
- /**
1094
- * A source backed by a path to a file. Intended for server-side usage in Node, Bun, or Deno.
1095
- *
1096
- * Make sure to call `.dispose()` on the corresponding {@link Input} when done to explicitly free the internal file
1097
- * handle acquired by this source.
1098
- * @group Input sources
1099
- * @public
1100
- */
1101
- export class FilePathSource extends PathedSource {
1102
- /** @internal */
1103
- _customSource: CustomSource;
1104
- /** @internal */
1105
- _fileHandle: FileHandle | null = null;
1106
-
1107
- /** Creates a new {@link FilePathSource} backed by the file at the specified file path. */
1108
- constructor(filePath: string, options: FilePathSourceOptions = {}) {
1109
- if (typeof filePath !== 'string') {
1110
- throw new TypeError('filePath must be a string.');
1111
- }
1112
- if (!options || typeof options !== 'object') {
1113
- throw new TypeError('options must be an object.');
1114
- }
1115
- if (
1116
- options.maxCacheSize !== undefined
1117
- && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)
1118
- ) {
1119
- throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');
1120
- }
1121
-
1122
- if (!node.fs) {
1123
- throw new Error(
1124
- 'FilePathSource is only available in server-side environments (Node.js, Bun, Deno).',
1125
- );
1126
- }
1127
-
1128
- super(filePath, request => new FilePathSource(request.path, options));
1129
-
1130
- // Let's back this source with a CustomSource, makes the implementation very simple
1131
- this._customSource = new CustomSource({
1132
- getSize: async () => {
1133
- const fileHandle = await node.fs.open(filePath, 'r');
1134
- this._fileHandle = fileHandle;
1135
-
1136
- sourceFinalizationRegistry?.register(this, () => {
1137
- // If it's not closed, Node prints annoying warnings
1138
- void fileHandle.close();
1139
- }, this);
1140
-
1141
- const stats = await fileHandle.stat();
1142
- return stats.size;
1143
- },
1144
- read: async (start, end) => {
1145
- assert(this._fileHandle);
1146
-
1147
- const buffer = new Uint8Array(end - start);
1148
- await this._fileHandle.read(buffer, 0, end - start, start);
1149
-
1150
- return buffer;
1151
- },
1152
- maxCacheSize: options.maxCacheSize,
1153
- prefetchProfile: 'fileSystem',
1154
- });
1155
- }
1156
-
1157
- /** @internal */
1158
- _read(
1159
- start: number,
1160
- end: number,
1161
- minReadPosition: number,
1162
- maxReadPosition: number,
1163
- ): MaybePromise<ReadResult | null> {
1164
- return this._customSource._read(start, end, minReadPosition, maxReadPosition);
1165
- }
1166
-
1167
- /** @internal */
1168
- _getFileSize(): number | null | undefined {
1169
- return this._customSource._getFileSize();
1170
- }
1171
-
1172
- /** @internal */
1173
- _dispose() {
1174
- this._customSource._dispose();
1175
-
1176
- if (this._fileHandle) {
1177
- void this._fileHandle.close();
1178
- this._fileHandle = null;
1179
- sourceFinalizationRegistry?.unregister(this);
1180
- }
1181
- }
1182
- }
1183
-
1184
- /**
1185
- * Options for defining a {@link CustomSource}.
1186
- * @group Input sources
1187
- * @public
1188
- */
1189
- export type CustomSourceOptions = {
1190
- /**
1191
- * Called when the size of the entire file is requested. Must return or resolve to the size in bytes. This function
1192
- * is guaranteed to be called before `read`.
1193
- */
1194
- getSize: () => MaybePromise<number>;
1195
-
1196
- /**
1197
- * Called when data is requested. Must return or resolve to the bytes from the specified byte range, or a stream
1198
- * that yields these bytes.
1199
- *
1200
- * You are guaranteed that `0 <= start < end < fileSize`.
1201
- */
1202
- read: (start: number, end: number) => MaybePromise<Uint8Array | ReadableStream<Uint8Array>>;
1203
-
1204
- /**
1205
- * Called when the {@link Input} driven by this source is disposed.
1206
- */
1207
- dispose?: () => unknown;
1208
-
1209
- /** The maximum number of bytes the cache is allowed to hold in memory. Defaults to 8 MiB. */
1210
- maxCacheSize?: number;
1211
-
1212
- /**
1213
- * Specifies the prefetch profile that the reader should use with this source. A prefetch profile specifies the
1214
- * pattern with which bytes outside of the requested range are preloaded to reduce latency for future reads.
1215
- *
1216
- * - `'none'` (default): No prefetching; only the data needed in the moment is requested.
1217
- * - `'fileSystem'`: File system-optimized prefetching: a small amount of data is prefetched bidirectionally,
1218
- * aligned with page boundaries.
1219
- * - `'network'`: Network-optimized prefetching, or more generally, prefetching optimized for any high-latency
1220
- * environment: tries to minimize the amount of read calls and aggressively prefetches data when sequential access
1221
- * patterns are detected.
1222
- */
1223
- prefetchProfile?: 'none' | 'fileSystem' | 'network';
1224
- };
1225
-
1226
- /**
1227
- * A general-purpose, callback-driven source that can get its data from anywhere. Use this source to implement your own
1228
- * custom source if the other sources don't cover your case.
1229
- * @group Input sources
1230
- * @public
1231
- */
1232
- export class CustomSource extends Source {
1233
- /** @internal */
1234
- _options: CustomSourceOptions;
1235
- /** @internal */
1236
- _orchestrator: ReadOrchestrator;
1237
-
1238
- /** Creates a new {@link CustomSource} whose behavior is specified by `options`. */
1239
- constructor(options: CustomSourceOptions) {
1240
- if (!options || typeof options !== 'object') {
1241
- throw new TypeError('options must be an object.');
1242
- }
1243
- if (typeof options.getSize !== 'function') {
1244
- throw new TypeError('options.getSize must be a function.');
1245
- }
1246
- if (typeof options.read !== 'function') {
1247
- throw new TypeError('options.read must be a function.');
1248
- }
1249
- if (options.dispose !== undefined && typeof options.dispose !== 'function') {
1250
- throw new TypeError('options.dispose, when provided, must be a function.');
1251
- }
1252
- if (
1253
- options.maxCacheSize !== undefined
1254
- && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)
1255
- ) {
1256
- throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');
1257
- }
1258
- if (options.prefetchProfile && !['none', 'fileSystem', 'network'].includes(options.prefetchProfile)) {
1259
- throw new TypeError(
1260
- 'options.prefetchProfile, when provided, must be one of \'none\', \'fileSystem\' or \'network\'.',
1261
- );
1262
- }
1263
-
1264
- super();
1265
-
1266
- this._options = options;
1267
-
1268
- this._orchestrator = new ReadOrchestrator({
1269
- maxCacheSize: options.maxCacheSize ?? (8 * 2 ** 20 /* 8 MiB */),
1270
- maxWorkerCount: 2, // Fixed for now, *should* be fine
1271
- prefetchProfile: PREFETCH_PROFILES[options.prefetchProfile ?? 'none'],
1272
- runWorker: this._runWorker.bind(this),
1273
- });
1274
- }
1275
-
1276
- /** @internal */
1277
- _getFileSize(): number | null | undefined {
1278
- return this._orchestrator.fileSize ?? undefined;
1279
- }
1280
-
1281
- /** @internal */
1282
- _read(
1283
- start: number,
1284
- end: number,
1285
- minReadPosition: number,
1286
- maxReadPosition: number,
1287
- ): MaybePromise<ReadResult | null> {
1288
- if (this._orchestrator.fileSize !== null) {
1289
- return this._orchestrator.read(start, end, minReadPosition, maxReadPosition);
1290
- }
1291
-
1292
- const result = this._options.getSize();
1293
-
1294
- if (result instanceof Promise) {
1295
- return result.then((size) => {
1296
- if (!Number.isInteger(size) || size < 0) {
1297
- throw new TypeError('options.getSize must return or resolve to a non-negative integer.');
1298
- }
1299
-
1300
- this._orchestrator.fileSize = size;
1301
- return this._orchestrator.read(start, end, minReadPosition, maxReadPosition);
1302
- });
1303
- } else {
1304
- if (!Number.isInteger(result) || result < 0) {
1305
- throw new TypeError('options.getSize must return or resolve to a non-negative integer.');
1306
- }
1307
-
1308
- this._orchestrator.fileSize = result;
1309
- return this._orchestrator.read(start, end, minReadPosition, maxReadPosition);
1310
- }
1311
- }
1312
-
1313
- /** @internal */
1314
- private async _runWorker(worker: ReadWorker) {
1315
- while (worker.currentPos < worker.targetPos && !worker.aborted) {
1316
- const originalCurrentPos = worker.currentPos;
1317
- const originalTargetPos = worker.targetPos;
1318
-
1319
- let data = this._options.read(worker.currentPos, originalTargetPos);
1320
- if (data instanceof Promise) data = await data;
1321
-
1322
- if (worker.aborted) {
1323
- break;
1324
- }
1325
-
1326
- if (data instanceof Uint8Array) {
1327
- data = toUint8Array(data); // Normalize things like Node.js Buffer to Uint8Array
1328
-
1329
- if (data.length !== originalTargetPos - worker.currentPos) {
1330
- // Yes, we're that strict
1331
- throw new Error(
1332
- `options.read returned a Uint8Array with unexpected length: Requested ${
1333
- originalTargetPos - worker.currentPos
1334
- } bytes, but got ${data.length}.`,
1335
- );
1336
- }
1337
-
1338
- this._dispatchRead(worker.currentPos, worker.currentPos + data.length);
1339
- this._orchestrator.supplyWorkerData(worker, data);
1340
- } else if (data instanceof ReadableStream) {
1341
- const reader = data.getReader();
1342
-
1343
- while (worker.currentPos < originalTargetPos && !worker.aborted) {
1344
- const { done, value } = await reader.read();
1345
- if (done) {
1346
- if (worker.currentPos < originalTargetPos) {
1347
- // Yes, we're *that* strict
1348
- throw new Error(
1349
- `ReadableStream returned by options.read ended before supplying enough data.`
1350
- + ` Requested ${originalTargetPos - originalCurrentPos} bytes, but got ${
1351
- worker.currentPos - originalCurrentPos
1352
- }`,
1353
- );
1354
- }
1355
-
1356
- break;
1357
- }
1358
-
1359
- if (!(value instanceof Uint8Array)) {
1360
- throw new TypeError('ReadableStream returned by options.read must yield Uint8Array chunks.');
1361
- }
1362
-
1363
- if (worker.aborted) {
1364
- break;
1365
- }
1366
-
1367
- const data = toUint8Array(value); // Normalize things like Node.js Buffer to Uint8Array
1368
-
1369
- this._dispatchRead(worker.currentPos, worker.currentPos + data.length);
1370
- this._orchestrator.supplyWorkerData(worker, data);
1371
- }
1372
- } else {
1373
- throw new TypeError('options.read must return or resolve to a Uint8Array or a ReadableStream.');
1374
- }
1375
- }
1376
-
1377
- this._orchestrator.signalWorkerStoppedRunning(worker);
1378
- }
1379
-
1380
- /** @internal */
1381
- _dispose() {
1382
- this._orchestrator.dispose();
1383
- this._options.dispose?.();
1384
- }
1385
- }
1386
-
1387
- /**
1388
- * An alias for {@link CustomSource}.
1389
- * @deprecated This name is misleading and will be removed in a future release. Please use {@link CustomSource} instead.
1390
- *
1391
- * @group Input sources
1392
- * @public
1393
- */
1394
- export const StreamSource = CustomSource;
1395
-
1396
- /**
1397
- * An alias for {@link CustomSourceOptions}.
1398
- * @deprecated This name is misleading and will be removed in a future release. Please use
1399
- * {@link CustomSourceOptions} instead.
1400
- *
1401
- * @group Input sources
1402
- * @public
1403
- */
1404
- export type StreamSourceOptions = CustomSourceOptions;
1405
-
1406
- type ReadableStreamSourcePendingSlice = {
1407
- start: number;
1408
- end: number;
1409
- bytes: Uint8Array;
1410
- resolve: (bytes: ReadResult | null) => void;
1411
- reject: (error: unknown) => void;
1412
- };
1413
-
1414
- /**
1415
- * Options for {@link ReadableStreamSource}.
1416
- * @group Input sources
1417
- * @public
1418
- */
1419
- export type ReadableStreamSourceOptions = {
1420
- /** The maximum number of bytes the cache is allowed to hold in memory. Defaults to 32 MiB. */
1421
- maxCacheSize?: number;
1422
- };
1423
-
1424
- /**
1425
- * A source backed by a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) of
1426
- * `Uint8Array`, representing an append-only byte stream of unknown length. This is the source to use for incrementally
1427
- * streaming in input files that are still being constructed and whose size we don't yet know, like for example the
1428
- * output chunks of [MediaRecorder](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder).
1429
- *
1430
- * This source is *unsized*, meaning calls to `.getSize()` will throw and readers are more limited due to the
1431
- * lack of random file access. You should only use this source with sequential access patterns, such as reading all
1432
- * packets from start to end. This source does not work well with random access patterns unless you increase its
1433
- * max cache size.
1434
- *
1435
- * @group Input sources
1436
- * @public
1437
- */
1438
- export class ReadableStreamSource extends Source {
1439
- /** @internal */
1440
- _stream: ReadableStream<Uint8Array>;
1441
- /** @internal */
1442
- _reader: ReadableStreamDefaultReader<Uint8Array> | null = null;
1443
- /** @internal */
1444
- _cache: CacheEntry[] = [];
1445
- /** @internal */
1446
- _maxCacheSize: number;
1447
- /** @internal */
1448
- _pendingSlices: ReadableStreamSourcePendingSlice[] = [];
1449
- /** @internal */
1450
- _currentIndex = 0;
1451
- /** @internal */
1452
- _targetIndex = 0;
1453
- /** @internal */
1454
- _maxRequestedIndex = 0;
1455
- /** @internal */
1456
- _endIndex: number | null = null;
1457
- /** @internal */
1458
- _pulling = false;
1459
-
1460
- /** Creates a new {@link ReadableStreamSource} backed by the specified `ReadableStream<Uint8Array>`. */
1461
- constructor(stream: ReadableStream<Uint8Array>, options: ReadableStreamSourceOptions = {}) {
1462
- if (!(stream instanceof ReadableStream)) {
1463
- throw new TypeError('stream must be a ReadableStream.');
1464
- }
1465
- if (!options || typeof options !== 'object') {
1466
- throw new TypeError('options must be an object.');
1467
- }
1468
- if (
1469
- options.maxCacheSize !== undefined
1470
- && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)
1471
- ) {
1472
- throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');
1473
- }
1474
-
1475
- super();
1476
-
1477
- this._stream = stream;
1478
- this._maxCacheSize = options.maxCacheSize ?? (32 * 2 ** 20 /* 32 MiB */);
1479
- }
1480
-
1481
- /** @internal */
1482
- _getFileSize(): number | null {
1483
- return this._endIndex; // Starts out as null, meaning this source is unsized
1484
- }
1485
-
1486
- /** @internal */
1487
- _read(start: number, end: number): MaybePromise<ReadResult | null> {
1488
- if (this._endIndex !== null && end > this._endIndex) {
1489
- return null;
1490
- }
1491
-
1492
- this._maxRequestedIndex = Math.max(this._maxRequestedIndex, end);
1493
-
1494
- const cacheStartIndex = binarySearchLessOrEqual(this._cache, start, x => x.start);
1495
- const cacheStartEntry = cacheStartIndex !== -1 ? this._cache[cacheStartIndex]! : null;
1496
-
1497
- if (cacheStartEntry && cacheStartEntry.start <= start && end <= cacheStartEntry.end) {
1498
- // The request can be satisfied with a single cache entry
1499
- return {
1500
- bytes: cacheStartEntry.bytes,
1501
- view: cacheStartEntry.view,
1502
- offset: cacheStartEntry.start,
1503
- };
1504
- }
1505
-
1506
- let lastEnd = start;
1507
- const bytes = new Uint8Array(end - start);
1508
-
1509
- if (cacheStartIndex !== -1) {
1510
- // Walk over the cache to see if we can satisfy the request using multiple cache entries
1511
- for (let i = cacheStartIndex; i < this._cache.length; i++) {
1512
- const cacheEntry = this._cache[i]!;
1513
- if (cacheEntry.start >= end) {
1514
- break;
1515
- }
1516
-
1517
- const cappedStart = Math.max(start, cacheEntry.start);
1518
- if (cappedStart > lastEnd) {
1519
- // We're too far behind
1520
- this._throwDueToCacheMiss();
1521
- }
1522
-
1523
- const cappedEnd = Math.min(end, cacheEntry.end);
1524
-
1525
- if (cappedStart < cappedEnd) {
1526
- bytes.set(
1527
- cacheEntry.bytes.subarray(cappedStart - cacheEntry.start, cappedEnd - cacheEntry.start),
1528
- cappedStart - start,
1529
- );
1530
-
1531
- lastEnd = cappedEnd;
1532
- }
1533
- }
1534
- }
1535
-
1536
- if (lastEnd === end) {
1537
- return {
1538
- bytes,
1539
- view: toDataView(bytes),
1540
- offset: start,
1541
- };
1542
- }
1543
-
1544
- // We need to pull more data
1545
-
1546
- if (this._currentIndex > lastEnd) {
1547
- // We're too far behind
1548
- this._throwDueToCacheMiss();
1549
- }
1550
-
1551
- const { promise, resolve, reject } = promiseWithResolvers<ReadResult | null>();
1552
-
1553
- this._pendingSlices.push({
1554
- start,
1555
- end,
1556
- bytes,
1557
- resolve,
1558
- reject,
1559
- });
1560
-
1561
- this._targetIndex = Math.max(this._targetIndex, end);
1562
-
1563
- // Start pulling from the stream if we're not already doing it
1564
- if (!this._pulling) {
1565
- this._pulling = true;
1566
- void this._pull()
1567
- .catch((error) => {
1568
- this._pulling = false;
1569
-
1570
- if (this._pendingSlices.length > 0) {
1571
- this._pendingSlices.forEach(x => x.reject(error)); // Make sure to propagate any errors
1572
- this._pendingSlices.length = 0;
1573
- } else {
1574
- throw error; // So it doesn't get swallowed
1575
- }
1576
- });
1577
- }
1578
-
1579
- return promise;
1580
- }
1581
-
1582
- /** @internal */
1583
- _throwDueToCacheMiss() {
1584
- throw new Error(
1585
- 'Read is before the cached region. With ReadableStreamSource, you must access the data more'
1586
- + ' sequentially or increase the size of its cache.',
1587
- );
1588
- }
1589
-
1590
- /** @internal */
1591
- async _pull() {
1592
- this._reader ??= this._stream.getReader();
1593
-
1594
- // This is the loop that keeps pulling data from the stream until a target index is reached, filling requests
1595
- // in the process
1596
- while (this._currentIndex < this._targetIndex && !this._disposed) {
1597
- const { done, value } = await this._reader.read();
1598
- if (done) {
1599
- for (const pendingSlice of this._pendingSlices) {
1600
- pendingSlice.resolve(null);
1601
- }
1602
- this._pendingSlices.length = 0;
1603
- this._endIndex = this._currentIndex; // We know how long the file is now!
1604
-
1605
- break;
1606
- }
1607
-
1608
- const startIndex = this._currentIndex;
1609
- const endIndex = this._currentIndex + value.byteLength;
1610
-
1611
- this._dispatchRead(startIndex, endIndex);
1612
-
1613
- // Fill the pending slices with the data
1614
- for (let i = 0; i < this._pendingSlices.length; i++) {
1615
- const pendingSlice = this._pendingSlices[i]!;
1616
-
1617
- const cappedStart = Math.max(startIndex, pendingSlice.start);
1618
- const cappedEnd = Math.min(endIndex, pendingSlice.end);
1619
-
1620
- if (cappedStart < cappedEnd) {
1621
- pendingSlice.bytes.set(
1622
- value.subarray(cappedStart - startIndex, cappedEnd - startIndex),
1623
- cappedStart - pendingSlice.start,
1624
- );
1625
- if (cappedEnd === pendingSlice.end) {
1626
- // Pending slice fully filled
1627
- pendingSlice.resolve({
1628
- bytes: pendingSlice.bytes,
1629
- view: toDataView(pendingSlice.bytes),
1630
- offset: pendingSlice.start,
1631
- });
1632
- this._pendingSlices.splice(i, 1);
1633
- i--;
1634
- }
1635
- }
1636
- }
1637
-
1638
- this._cache.push({
1639
- start: startIndex,
1640
- end: endIndex,
1641
- bytes: value,
1642
- view: toDataView(value),
1643
- age: 0, // Unused
1644
- });
1645
-
1646
- // Do cache eviction, based on the distance from the last-requested index. It's important that we do it like
1647
- // this and not based on where the reader is at, because if the reader is fast, we'll unnecessarily evict
1648
- // data that we still might need.
1649
- while (this._cache.length > 0) {
1650
- const firstEntry = this._cache[0]!;
1651
- const distance = this._maxRequestedIndex - firstEntry.end;
1652
-
1653
- if (distance <= this._maxCacheSize) {
1654
- break;
1655
- }
1656
-
1657
- this._cache.shift();
1658
- }
1659
-
1660
- this._currentIndex += value.byteLength;
1661
- }
1662
-
1663
- this._pulling = false;
1664
- }
1665
-
1666
- /** @internal */
1667
- _dispose() {
1668
- for (const pendingSlice of this._pendingSlices) {
1669
- pendingSlice.reject(new InputDisposedError());
1670
- }
1671
-
1672
- this._pendingSlices.length = 0;
1673
- this._cache.length = 0;
1674
- void this._reader?.cancel();
1675
- }
1676
- }
1677
-
1678
- type PrefetchProfile = (start: number, end: number, workers: ReadWorker[]) => {
1679
- start: number;
1680
- end: number;
1681
- };
1682
-
1683
- const PREFETCH_PROFILES = {
1684
- none: (start, end) => ({ start, end }),
1685
- fileSystem: (start, end) => {
1686
- const padding = 2 ** 16;
1687
-
1688
- start = Math.floor((start - padding) / padding) * padding;
1689
- end = Math.ceil((end + padding) / padding) * padding;
1690
-
1691
- return { start, end };
1692
- },
1693
- network: (start, end, workers) => {
1694
- // Add a slight bit of start padding because backwards reading is painful
1695
- const paddingStart = 2 ** 16;
1696
- start = Math.max(0, Math.floor((start - paddingStart) / paddingStart) * paddingStart);
1697
-
1698
- // Remote resources have extreme latency (relatively speaking), so the benefit from intelligent
1699
- // prefetching is great. The network prefetch strategy is as follows: When we notice
1700
- // successive reads to a worker's read region, we prefetch more data at the end of that region,
1701
- // growing exponentially (up to a cap). This performs well for real-world use cases: Either we read a
1702
- // small part of the file once and then never need it again, in which case the requested about of data
1703
- // is small. Or, we're repeatedly doing a sequential access pattern (common in media files), in which
1704
- // case we can become more and more confident to prefetch more and more data.
1705
- for (const worker of workers) {
1706
- const maxExtensionAmount = 8 * 2 ** 20; // 8 MiB
1707
-
1708
- // When the read region cross the threshold point, we trigger a prefetch. This point is typically
1709
- // in the middle of the worker's read region, or a fixed offset from the end if the region has grown
1710
- // really large.
1711
- const thresholdPoint = Math.max(
1712
- (worker.startPos + worker.targetPos) / 2,
1713
- worker.targetPos - maxExtensionAmount,
1714
- );
1715
-
1716
- if (closedIntervalsOverlap(
1717
- start, end,
1718
- thresholdPoint, worker.targetPos,
1719
- )) {
1720
- const size = worker.targetPos - worker.startPos;
1721
-
1722
- // If we extend by maxExtensionAmount
1723
- const a = Math.ceil((size + 1) / maxExtensionAmount) * maxExtensionAmount;
1724
- // If we extend to the next power of 2
1725
- const b = 2 ** Math.ceil(Math.log2(size + 1));
1726
-
1727
- const extent = Math.min(b, a);
1728
- end = Math.max(end, worker.startPos + extent);
1729
- }
1730
- }
1731
-
1732
- end = Math.max(end, start + URL_SOURCE_MIN_LOAD_AMOUNT);
1733
-
1734
- return {
1735
- start,
1736
- end,
1737
- };
1738
- },
1739
- } satisfies Record<string, PrefetchProfile>;
1740
-
1741
- type PendingSlice = {
1742
- start: number;
1743
- bytes: Uint8Array;
1744
- holes: Hole[];
1745
- resolve: (bytes: Uint8Array | null) => void;
1746
- reject: (error: unknown) => void;
1747
- };
1748
-
1749
- type Hole = {
1750
- start: number;
1751
- end: number;
1752
- };
1753
-
1754
- type CacheEntry = {
1755
- start: number;
1756
- end: number;
1757
- bytes: Uint8Array;
1758
- view: DataView;
1759
- age: number;
1760
- };
1761
-
1762
- type ReadWorker = {
1763
- startPos: number;
1764
- currentPos: number;
1765
- targetPos: number;
1766
- /** The target is considered _strict_ when it is an error for the worker to terminate before reaching the target. */
1767
- strictTarget: boolean;
1768
- running: boolean;
1769
- aborted: boolean;
1770
- pendingSlices: PendingSlice[];
1771
- age: number;
1772
- };
1773
-
1774
- /**
1775
- * Godclass for orchestrating complex, cached read operations. The reading model is as follows: Any reading task is
1776
- * delegated to a *worker*, which is a sequential reader positioned somewhere along the file. All workers run in
1777
- * parallel and can be stopped and resumed in their forward movement. When read requests come in, this orchestrator will
1778
- * first try to satisfy the request with only the cached data. If this isn't possible, workers are spun up for all
1779
- * missing parts (or existing workers are repurposed), and these workers will then fill the holes in the data as they
1780
- * march along the file.
1781
- */
1782
- class ReadOrchestrator {
1783
- fileSize: number | null = null;
1784
- nextAge = 0; // Used for multiple things
1785
- workers: ReadWorker[] = [];
1786
- cache: CacheEntry[] = [];
1787
- currentCacheSize = 0;
1788
- disposed = false;
1789
- queuedReads: {
1790
- hole: Hole;
1791
- strictTarget: boolean;
1792
- pendingSlices: PendingSlice[];
1793
- age: number;
1794
- }[] = [];
1795
-
1796
- constructor(public options: {
1797
- maxCacheSize: number;
1798
- runWorker: (worker: ReadWorker) => Promise<void>;
1799
- prefetchProfile: PrefetchProfile;
1800
- maxWorkerCount: number;
1801
- }) {}
1802
-
1803
- read(
1804
- innerStart: number,
1805
- innerEnd: number,
1806
- minReadPosition: number,
1807
- maxReadPosition: number,
1808
- ): MaybePromise<ReadResult | null> {
1809
- assert(!this.disposed);
1810
-
1811
- const prefetchRange = this.options.prefetchProfile(innerStart, innerEnd, this.workers);
1812
- const outerStart = Math.max(prefetchRange.start, minReadPosition);
1813
- const outerEnd = Math.min(prefetchRange.end, this.fileSize ?? Infinity, maxReadPosition);
1814
- assert(outerStart <= innerStart && innerEnd <= outerEnd);
1815
-
1816
- let result: MaybePromise<ReadResult | null> | null = null;
1817
-
1818
- const innerCacheStartIndex = binarySearchLessOrEqual(this.cache, innerStart, x => x.start);
1819
- const innerStartEntry = innerCacheStartIndex !== -1 ? this.cache[innerCacheStartIndex] : null;
1820
-
1821
- // See if the read request can be satisfied by a single cache entry
1822
- if (innerStartEntry && innerStartEntry.start <= innerStart && innerEnd <= innerStartEntry.end) {
1823
- innerStartEntry.age = this.nextAge++;
1824
-
1825
- result = {
1826
- bytes: innerStartEntry.bytes,
1827
- view: innerStartEntry.view,
1828
- offset: innerStartEntry.start,
1829
- };
1830
- // Can't return yet though, still need to check if the prefetch range might lie outside the cached area
1831
- }
1832
-
1833
- const outerCacheStartIndex = binarySearchLessOrEqual(this.cache, outerStart, x => x.start);
1834
-
1835
- const bytes = result ? null : new Uint8Array(innerEnd - innerStart);
1836
- let contiguousBytesWriteEnd = 0; // Used to track if the cache is able to completely cover the bytes
1837
-
1838
- let lastEnd = outerStart;
1839
- // The "holes" in the cache (the parts we need to load)
1840
- const outerHoles: Hole[] = [];
1841
-
1842
- // Loop over the cache and build up the list of holes
1843
- if (outerCacheStartIndex !== -1) {
1844
- for (let i = outerCacheStartIndex; i < this.cache.length; i++) {
1845
- const entry = this.cache[i]!;
1846
- if (entry.start >= outerEnd) {
1847
- break;
1848
- }
1849
- if (entry.end <= outerStart) {
1850
- continue;
1851
- }
1852
-
1853
- const cappedOuterStart = Math.max(outerStart, entry.start);
1854
- const cappedOuterEnd = Math.min(outerEnd, entry.end);
1855
- assert(cappedOuterStart <= cappedOuterEnd);
1856
-
1857
- if (lastEnd < cappedOuterStart) {
1858
- outerHoles.push({ start: lastEnd, end: cappedOuterStart });
1859
- }
1860
- lastEnd = cappedOuterEnd;
1861
-
1862
- if (bytes) {
1863
- const cappedInnerStart = Math.max(innerStart, entry.start);
1864
- const cappedInnerEnd = Math.min(innerEnd, entry.end);
1865
-
1866
- if (cappedInnerStart < cappedInnerEnd) {
1867
- const relativeOffset = cappedInnerStart - innerStart;
1868
-
1869
- // Fill the relevant section of the bytes with the cached data
1870
- bytes.set(
1871
- entry.bytes.subarray(cappedInnerStart - entry.start, cappedInnerEnd - entry.start),
1872
- relativeOffset,
1873
- );
1874
-
1875
- if (relativeOffset === contiguousBytesWriteEnd) {
1876
- contiguousBytesWriteEnd = cappedInnerEnd - innerStart;
1877
- }
1878
- }
1879
- }
1880
- entry.age = this.nextAge++;
1881
- }
1882
-
1883
- if (lastEnd < outerEnd) {
1884
- outerHoles.push({ start: lastEnd, end: outerEnd });
1885
- }
1886
- } else {
1887
- outerHoles.push({ start: outerStart, end: outerEnd });
1888
- }
1889
-
1890
- if (bytes && contiguousBytesWriteEnd >= bytes.length) {
1891
- // Multiple cache entries were able to completely cover the requested bytes!
1892
- result = {
1893
- bytes,
1894
- view: toDataView(bytes),
1895
- offset: innerStart,
1896
- };
1897
- }
1898
-
1899
- if (outerHoles.length === 0) {
1900
- assert(result);
1901
- return result;
1902
- }
1903
-
1904
- // We need to read more data, so now we're in async land
1905
- const { promise, resolve, reject } = promiseWithResolvers<Uint8Array | null>();
1906
-
1907
- const innerHoles: typeof outerHoles = [];
1908
- for (const outerHole of outerHoles) {
1909
- const cappedStart = Math.max(innerStart, outerHole.start);
1910
- const cappedEnd = Math.min(innerEnd, outerHole.end);
1911
-
1912
- if (cappedStart === outerHole.start && cappedEnd === outerHole.end) {
1913
- innerHoles.push(outerHole); // Can reuse without allocating a new object
1914
- } else if (cappedStart < cappedEnd) {
1915
- innerHoles.push({ start: cappedStart, end: cappedEnd });
1916
- }
1917
- }
1918
-
1919
- const pendingSlice: PendingSlice | null = bytes && {
1920
- start: innerStart,
1921
- bytes,
1922
- holes: innerHoles,
1923
- resolve,
1924
- reject,
1925
- };
1926
-
1927
- // Fire off workers to take care of patching the holes
1928
- outer:
1929
- for (const outerHole of outerHoles) {
1930
- for (const worker of this.workers) {
1931
- const addedToWorker = this.checkHoleAgainstWorker(
1932
- worker,
1933
- outerHole,
1934
- pendingSlice ? [pendingSlice] : [],
1935
- );
1936
-
1937
- if (addedToWorker) {
1938
- this.checkQueuedReadsAgainstWorker(worker);
1939
- continue outer;
1940
- }
1941
- }
1942
-
1943
- // We need to spawn a new worker
1944
- const strictTarget = outerHole.end < outerEnd || this.fileSize !== null;
1945
- const newWorker = this.createWorker(outerHole.start, outerHole.end, strictTarget);
1946
-
1947
- if (newWorker) {
1948
- if (pendingSlice) {
1949
- newWorker.pendingSlices = [pendingSlice];
1950
- }
1951
-
1952
- this.runWorker(newWorker);
1953
- } else {
1954
- // Max worker count has been reached, let's queue a read for later
1955
-
1956
- let index = binarySearchLessOrEqual(this.queuedReads, outerHole.start, x => x.hole.start);
1957
- let entry = index !== -1
1958
- ? this.queuedReads[index]!
1959
- : null;
1960
-
1961
- if (entry && outerHole.start <= entry.hole.end) {
1962
- entry.hole.end = Math.max(entry.hole.end, outerHole.end);
1963
- entry.strictTarget &&= strictTarget;
1964
-
1965
- if (pendingSlice) {
1966
- entry.pendingSlices.push(pendingSlice);
1967
- }
1968
- } else {
1969
- index++;
1970
- entry = {
1971
- hole: {
1972
- // Clone the hole because it might be mutated later
1973
- start: outerHole.start,
1974
- end: outerHole.end,
1975
- },
1976
- strictTarget,
1977
- pendingSlices: pendingSlice ? [pendingSlice] : [],
1978
- age: this.nextAge++,
1979
- };
1980
- this.queuedReads.splice(index, 0, entry);
1981
- }
1982
-
1983
- // Merge with any subsequent entries that overlap
1984
- while (index + 1 < this.queuedReads.length) {
1985
- const nextEntry = this.queuedReads[index + 1]!;
1986
- if (nextEntry.hole.start > entry.hole.end) {
1987
- break;
1988
- }
1989
-
1990
- entry.hole.end = Math.max(entry.hole.end, nextEntry.hole.end);
1991
- entry.pendingSlices.push(...nextEntry.pendingSlices);
1992
- entry.strictTarget &&= nextEntry.strictTarget;
1993
- entry.age = Math.min(entry.age, nextEntry.age);
1994
- this.queuedReads.splice(index + 1, 1);
1995
- }
1996
- }
1997
- }
1998
-
1999
- if (!result) {
2000
- assert(bytes);
2001
-
2002
- result = promise.then(bytes => bytes && ({
2003
- bytes,
2004
- view: toDataView(bytes),
2005
- offset: innerStart,
2006
- } satisfies ReadResult));
2007
- } else {
2008
- // The requested region was satisfied by the cache, but the entire prefetch region was not
2009
- promise.catch((error) => {
2010
- if (this.disposed) {
2011
- return; // Swallow the error
2012
- }
2013
-
2014
- // Nobody's awaiting this result but an errored read is still notable
2015
- throw error;
2016
- });
2017
- }
2018
-
2019
- return result;
2020
- }
2021
-
2022
- checkHoleAgainstWorker(worker: ReadWorker, hole: Hole, pendingSlices: PendingSlice[]) {
2023
- // A small tolerance in the case that the requested region is *just* after the target position of an
2024
- // existing worker. In that case, it's probably more efficient to repurpose that worker than to spawn
2025
- // another one so close to it
2026
- const gapTolerance = 2 ** 17;
2027
-
2028
- // This check also implies worker.currentPos <= hole.start, a critical condition
2029
- if (closedIntervalsOverlap(
2030
- hole.start - gapTolerance, hole.start,
2031
- worker.currentPos, worker.targetPos,
2032
- )) {
2033
- worker.targetPos = Math.max(worker.targetPos, hole.end); // Update the worker's target position
2034
-
2035
- for (let i = 0; i < pendingSlices.length; i++) {
2036
- const pendingSlice = pendingSlices[i]!;
2037
- if (!worker.pendingSlices.includes(pendingSlice)) {
2038
- worker.pendingSlices.push(pendingSlice);
2039
- }
2040
- }
2041
-
2042
- if (!worker.running) {
2043
- // Kick it off if it's idle
2044
- this.runWorker(worker);
2045
- }
2046
-
2047
- return true;
2048
- }
2049
-
2050
- return false;
2051
- }
2052
-
2053
- checkQueuedReadsAgainstWorker(worker: ReadWorker) {
2054
- let wasTrueOnce = false;
2055
-
2056
- for (let i = 0; i < this.queuedReads.length; i++) {
2057
- const queuedRead = this.queuedReads[i]!;
2058
- const result = this.checkHoleAgainstWorker(worker, queuedRead.hole, queuedRead.pendingSlices);
2059
-
2060
- if (result) {
2061
- this.queuedReads.splice(i, 1);
2062
- i--;
2063
- wasTrueOnce = true;
2064
- } else if (wasTrueOnce) {
2065
- // We can stop since the holes are sorted
2066
- break;
2067
- }
2068
- }
2069
- }
2070
-
2071
- createWorker(startPos: number, targetPos: number, strictTarget: boolean) {
2072
- if (this.workers.length >= this.options.maxWorkerCount) {
2073
- let oldestWorker: ReadWorker | null = null;
2074
- let oldestIndex: number | null = null;
2075
-
2076
- for (let i = 0; i < this.workers.length; i++) {
2077
- const worker = this.workers[i]!;
2078
-
2079
- if (
2080
- !worker.running
2081
- && worker.pendingSlices.length === 0
2082
- && (!oldestWorker || worker.age < oldestWorker.age)
2083
- ) {
2084
- oldestIndex = i;
2085
- oldestWorker = worker;
2086
- }
2087
- }
2088
-
2089
- if (oldestWorker) {
2090
- // LRU eviction
2091
- assert(oldestIndex !== null);
2092
- assert(oldestWorker.pendingSlices.length === 0);
2093
- this.workers.splice(oldestIndex, 1);
2094
- } else {
2095
- return null; // All workers are still running, we can't create a new one
2096
- }
2097
- }
2098
-
2099
- const worker: ReadWorker = {
2100
- startPos,
2101
- currentPos: startPos,
2102
- targetPos,
2103
- strictTarget,
2104
- running: false,
2105
- // Due to async shenanigans, it can happen that workers are started after disposal. In this case, instead of
2106
- // simply not creating the worker, we allow it to run but immediately label it as aborted, so it can then
2107
- // shut itself down.
2108
- aborted: this.disposed,
2109
- pendingSlices: [],
2110
- age: this.nextAge++,
2111
- };
2112
- this.workers.push(worker);
2113
-
2114
- return worker;
2115
- }
2116
-
2117
- runWorker(worker: ReadWorker) {
2118
- assert(!worker.running);
2119
- assert(worker.currentPos < worker.targetPos);
2120
-
2121
- worker.running = true;
2122
- worker.age = this.nextAge++;
2123
-
2124
- void this.options.runWorker(worker)
2125
- .catch((error) => {
2126
- worker.running = false;
2127
-
2128
- if (worker.pendingSlices.length > 0) {
2129
- worker.pendingSlices.forEach(x => x.reject(error)); // Make sure to propagate any errors
2130
- worker.pendingSlices.length = 0;
2131
- } else if (!worker.aborted && !this.disposed) {
2132
- throw error; // So it doesn't get swallowed
2133
- }
2134
- })
2135
- .finally(() => {
2136
- if (worker.running) {
2137
- // Rare, but can happen with multiple concurrent reads. In this case, don't do anything.
2138
- return;
2139
- }
2140
-
2141
- if (this.queuedReads.length > 0) {
2142
- let oldestIndex = 0;
2143
- for (let i = 1; i < this.queuedReads.length; i++) {
2144
- const queuedRead = this.queuedReads[i]!;
2145
- if (queuedRead.age < this.queuedReads[oldestIndex]!.age) {
2146
- oldestIndex = i;
2147
- }
2148
- }
2149
-
2150
- const queuedRead = this.queuedReads[oldestIndex]!;
2151
-
2152
- const newWorker = this.createWorker(
2153
- queuedRead.hole.start,
2154
- queuedRead.hole.end,
2155
- queuedRead.strictTarget,
2156
- );
2157
- if (!newWorker) {
2158
- // In high-contention cases, it could be that we've already reached max worker count, so in this
2159
- // case we don't do anything.
2160
- return;
2161
- }
2162
-
2163
- this.queuedReads.splice(oldestIndex, 1);
2164
- newWorker.pendingSlices = queuedRead.pendingSlices;
2165
- this.runWorker(newWorker);
2166
- }
2167
- });
2168
- }
2169
-
2170
- consolidateEverythingIntoOneWorker(worker: ReadWorker) {
2171
- // Here we merge everything into one "megaworker" that spans the entire file. We assume the passed-in worker
2172
- // is already configured to be a megaworker.
2173
-
2174
- const uniqueSlices = new Set(worker.pendingSlices);
2175
-
2176
- for (let i = 0; i < this.workers.length; i++) {
2177
- const otherWorker = this.workers[i]!;
2178
- if (otherWorker === worker) {
2179
- continue;
2180
- }
2181
-
2182
- for (const slice of otherWorker.pendingSlices) {
2183
- uniqueSlices.add(slice);
2184
- }
2185
-
2186
- otherWorker.aborted = true;
2187
- otherWorker.pendingSlices.length = 0;
2188
- this.workers.splice(i, 1);
2189
- i--;
2190
- }
2191
-
2192
- for (let i = 0; i < this.queuedReads.length; i++) {
2193
- const queuedRead = this.queuedReads[i]!;
2194
-
2195
- for (const slice of queuedRead.pendingSlices) {
2196
- uniqueSlices.add(slice);
2197
- }
2198
- }
2199
-
2200
- worker.pendingSlices = [...uniqueSlices];
2201
- this.queuedReads.length = 0;
2202
- }
2203
-
2204
- /** Called by a worker when it has read some data. */
2205
- supplyWorkerData(worker: ReadWorker, bytes: Uint8Array) {
2206
- assert(!worker.aborted);
2207
-
2208
- const start = worker.currentPos;
2209
- const end = start + bytes.length;
2210
-
2211
- this.insertIntoCache({
2212
- start,
2213
- end,
2214
- bytes,
2215
- view: toDataView(bytes),
2216
- age: this.nextAge++,
2217
- });
2218
- worker.currentPos += bytes.length;
2219
-
2220
- if (worker.currentPos > worker.targetPos) {
2221
- // In case it overshoots
2222
- worker.targetPos = worker.currentPos;
2223
- this.checkQueuedReadsAgainstWorker(worker);
2224
- }
2225
-
2226
- // Now, let's see if we can use the read bytes to fill any pending slice
2227
- for (let i = 0; i < worker.pendingSlices.length; i++) {
2228
- const pendingSlice = worker.pendingSlices[i]!;
2229
-
2230
- const clampedStart = Math.max(start, pendingSlice.start);
2231
- const clampedEnd = Math.min(end, pendingSlice.start + pendingSlice.bytes.length);
2232
-
2233
- if (clampedStart < clampedEnd) {
2234
- pendingSlice.bytes.set(
2235
- bytes.subarray(clampedStart - start, clampedEnd - start),
2236
- clampedStart - pendingSlice.start,
2237
- );
2238
- }
2239
-
2240
- for (let j = 0; j < pendingSlice.holes.length; j++) {
2241
- // The hole is intentionally not modified here if the read section starts somewhere in the middle of
2242
- // the hole. We don't need to do "hole splitting", since the workers are spawned *by* the holes,
2243
- // meaning there's always a worker which will consume the hole left to right.
2244
- const hole = pendingSlice.holes[j]!;
2245
- if (start <= hole.start && end > hole.start) {
2246
- hole.start = end;
2247
- }
2248
-
2249
- if (hole.end <= hole.start) {
2250
- pendingSlice.holes.splice(j, 1);
2251
- j--;
2252
- }
2253
- }
2254
-
2255
- if (pendingSlice.holes.length === 0) {
2256
- // The slice has been fulfilled, everything has been read. Let's resolve the promise
2257
- pendingSlice.resolve(pendingSlice.bytes);
2258
- worker.pendingSlices.splice(i, 1);
2259
- i--;
2260
- }
2261
- }
2262
-
2263
- // Remove other idle workers if we "ate" into their territory
2264
- for (let i = 0; i < this.workers.length; i++) {
2265
- const otherWorker = this.workers[i]!;
2266
- if (worker === otherWorker || otherWorker.running) {
2267
- continue;
2268
- }
2269
-
2270
- if (closedIntervalsOverlap(
2271
- start, end,
2272
- otherWorker.currentPos, otherWorker.targetPos, // These should typically be equal when the worker's idle
2273
- )) {
2274
- this.workers.splice(i, 1);
2275
- i--;
2276
- }
2277
- }
2278
- }
2279
-
2280
- supplyFileSize(size: number) {
2281
- assert(this.fileSize === null);
2282
-
2283
- this.fileSize = size;
2284
-
2285
- // Trim the workers with this new information
2286
- for (const worker of this.workers) {
2287
- worker.targetPos = Math.min(worker.targetPos, size);
2288
- worker.strictTarget = true;
2289
-
2290
- for (let i = 0; i < worker.pendingSlices.length; i++) {
2291
- const pendingSlice = worker.pendingSlices[i]!;
2292
-
2293
- for (const hole of pendingSlice.holes) {
2294
- if (hole.end > size) {
2295
- // Can't satisfy this slice anymore
2296
- pendingSlice.resolve(null);
2297
- worker.pendingSlices.splice(i, 1);
2298
- i--;
2299
-
2300
- break;
2301
- }
2302
- }
2303
- }
2304
- }
2305
-
2306
- // Trim the queued reads as well
2307
- for (let i = 0; i < this.queuedReads.length; i++) {
2308
- const queuedRead = this.queuedReads[i]!;
2309
- if (queuedRead.hole.start >= size) {
2310
- // Entirely out of bounds
2311
- for (const slice of queuedRead.pendingSlices) slice.resolve(null);
2312
- this.queuedReads.splice(i, 1);
2313
- i--;
2314
- } else if (queuedRead.hole.end > size) {
2315
- // Partially out of bounds
2316
- queuedRead.hole.end = size;
2317
- queuedRead.strictTarget = true;
2318
-
2319
- for (let j = 0; j < queuedRead.pendingSlices.length; j++) {
2320
- const slice = queuedRead.pendingSlices[j]!;
2321
- // If the slice itself is out of bounds, resolve it
2322
- if (slice.start >= size) {
2323
- slice.resolve(null);
2324
- queuedRead.pendingSlices.splice(j, 1);
2325
- j--;
2326
- }
2327
- }
2328
- }
2329
- }
2330
- }
2331
-
2332
- signalWorkerStoppedRunning(worker: ReadWorker) {
2333
- worker.running = false;
2334
-
2335
- if (!worker.aborted) {
2336
- // When a worker stops running, that means it has hit its targetPos. It might still have pendingSlices
2337
- // assigned, but this is because those pending slices cover data that other workers are assigned to fill.
2338
- // Since targetPos has been reached, we can confidently say that this worker has completed its share of work
2339
- // on the pending slices and must no longer care about them.
2340
- worker.pendingSlices.length = 0;
2341
- }
2342
- }
2343
-
2344
- /** Called when a worker reaches the end of the underlying data and must be cleaned up. */
2345
- onWorkerFinished(worker: ReadWorker) {
2346
- const index = this.workers.indexOf(worker);
2347
- assert(index !== -1);
2348
-
2349
- worker.running = false;
2350
- this.workers.splice(index, 1);
2351
-
2352
- if (this.fileSize === null) {
2353
- // We can now deduce the file size!
2354
- this.supplyFileSize(worker.currentPos);
2355
- }
2356
-
2357
- for (const pendingSlice of worker.pendingSlices) {
2358
- pendingSlice.resolve(null);
2359
- }
2360
- }
2361
-
2362
- insertIntoCache(entry: CacheEntry) {
2363
- if (this.options.maxCacheSize === 0) {
2364
- return; // No caching
2365
- }
2366
-
2367
- let insertionIndex = binarySearchLessOrEqual(this.cache, entry.start, x => x.start) + 1;
2368
-
2369
- if (insertionIndex > 0) {
2370
- const previous = this.cache[insertionIndex - 1]!;
2371
- if (previous.end >= entry.end) {
2372
- // Previous entry swallows the one to be inserted; we don't need to do anything
2373
- return;
2374
- }
2375
-
2376
- if (previous.end > entry.start) {
2377
- // Partial overlap with the previous entry, let's join
2378
- const joined = new Uint8Array(entry.end - previous.start);
2379
- joined.set(previous.bytes, 0);
2380
- joined.set(entry.bytes, entry.start - previous.start);
2381
-
2382
- this.currentCacheSize += entry.end - previous.end;
2383
-
2384
- previous.bytes = joined;
2385
- previous.view = toDataView(joined);
2386
- previous.end = entry.end;
2387
-
2388
- // Do the rest of the logic with the previous entry instead
2389
- insertionIndex--;
2390
- entry = previous;
2391
- } else {
2392
- this.cache.splice(insertionIndex, 0, entry);
2393
- this.currentCacheSize += entry.bytes.length;
2394
- }
2395
- } else {
2396
- this.cache.splice(insertionIndex, 0, entry);
2397
- this.currentCacheSize += entry.bytes.length;
2398
- }
2399
-
2400
- for (let i = insertionIndex + 1; i < this.cache.length; i++) {
2401
- const next = this.cache[i]!;
2402
- if (entry.end <= next.start) {
2403
- // Even if they touch, we don't wanna merge them, no need
2404
- break;
2405
- }
2406
-
2407
- if (entry.end >= next.end) {
2408
- // The inserted entry completely swallows the next entry
2409
- this.cache.splice(i, 1);
2410
- this.currentCacheSize -= next.bytes.length;
2411
- i--;
2412
- continue;
2413
- }
2414
-
2415
- // Partial overlap, let's join
2416
- const joined = new Uint8Array(next.end - entry.start);
2417
- joined.set(entry.bytes, 0);
2418
- joined.set(next.bytes, next.start - entry.start);
2419
-
2420
- this.currentCacheSize -= entry.end - next.start; // Subtract the overlap
2421
-
2422
- entry.bytes = joined;
2423
- entry.view = toDataView(joined);
2424
- entry.end = next.end;
2425
- this.cache.splice(i, 1);
2426
-
2427
- break; // After the join case, we're done: the next entry cannot possibly overlap with the inserted one.
2428
- }
2429
-
2430
- // LRU eviction of cache entries
2431
- while (this.currentCacheSize > this.options.maxCacheSize) {
2432
- let oldestIndex = 0;
2433
- let oldestEntry = this.cache[0]!;
2434
-
2435
- for (let i = 1; i < this.cache.length; i++) {
2436
- const entry = this.cache[i]!;
2437
-
2438
- if (entry.age < oldestEntry.age) {
2439
- oldestIndex = i;
2440
- oldestEntry = entry;
2441
- }
2442
- }
2443
-
2444
- if (this.currentCacheSize - oldestEntry.bytes.length <= this.options.maxCacheSize) {
2445
- // Don't evict if it would shrink the cache below the max size
2446
- break;
2447
- }
2448
-
2449
- this.cache.splice(oldestIndex, 1);
2450
- this.currentCacheSize -= oldestEntry.bytes.length;
2451
- }
2452
- }
2453
-
2454
- dispose() {
2455
- for (const worker of this.workers) {
2456
- for (const slice of worker.pendingSlices) {
2457
- slice.reject(new InputDisposedError());
2458
- }
2459
-
2460
- worker.pendingSlices.length = 0;
2461
- worker.aborted = true;
2462
- }
2463
-
2464
- for (const queuedRead of this.queuedReads) {
2465
- for (const slice of queuedRead.pendingSlices) {
2466
- slice.reject(new InputDisposedError());
2467
- }
2468
- }
2469
-
2470
- this.workers.length = 0;
2471
- this.cache.length = 0;
2472
- this.queuedReads.length = 0;
2473
- this.disposed = true;
2474
- }
2475
- }
2476
-
2477
- /**
2478
- * A dummy source from which no data can be read. Can be used in conjunction with input formats that get their data
2479
- * from another source.
2480
- */
2481
- export class NullSource extends Source {
2482
- override _getFileSize(): number | null {
2483
- return null;
2484
- }
2485
-
2486
- override _read(): MaybePromise<ReadResult | null> {
2487
- return null;
2488
- }
2489
-
2490
- override _dispose(): void {
2491
- // Do nothing
2492
- }
2493
- }
2494
-
2495
- /**
2496
- * A source that covers a range (offset + length) of another source. Useful for reading files that are embedded within
2497
- * larger files.
2498
- *
2499
- * @group Input sources
2500
- * @public
2501
- */
2502
- export class RangedSource extends Source {
2503
- /** @internal */
2504
- _baseSource: Source;
2505
- /** @internal */
2506
- _ref: SourceRef | null = null;
2507
- /** @internal */
2508
- _offset: number;
2509
- /** @internal */
2510
- _length: number | null;
2511
-
2512
- /** @internal */
2513
- constructor(baseSource: Source, offset: number, length?: number) {
2514
- super();
2515
-
2516
- if (baseSource._disposed) {
2517
- throw new Error('Cannot create a slice of a disposed source.');
2518
- }
2519
-
2520
- this._baseSource = baseSource;
2521
- this._offset = offset;
2522
- this._length = length ?? null;
2523
- }
2524
-
2525
- /** @internal */
2526
- override _getFileSize(): number | null | undefined {
2527
- const baseSize = this._baseSource._getFileSize();
2528
- if (baseSize === undefined) {
2529
- return this._length !== null
2530
- ? this._length
2531
- : undefined;
2532
- }
2533
-
2534
- if (baseSize === null) {
2535
- if (this._length !== null) {
2536
- return this._length;
2537
- } else {
2538
- return null;
2539
- }
2540
- }
2541
-
2542
- return clamp(baseSize - this._offset, 0, this._length ?? Infinity);
2543
- }
2544
-
2545
- /** @internal */
2546
- override _read(
2547
- start: number,
2548
- end: number,
2549
- minReadPosition: number,
2550
- maxReadPosition: number,
2551
- ): MaybePromise<ReadResult | null> {
2552
- if (this._length !== null && end > this._length) {
2553
- return null;
2554
- }
2555
-
2556
- const result = this._baseSource._read(
2557
- this._offset + start,
2558
- this._offset + end,
2559
- this._offset + minReadPosition,
2560
- this._offset + maxReadPosition,
2561
- );
2562
-
2563
- const processResult = (result: ReadResult | null) => {
2564
- if (!result) {
2565
- return null;
2566
- }
2567
-
2568
- result.offset -= this._offset;
2569
- return result;
2570
- };
2571
-
2572
- if (result instanceof Promise) {
2573
- return result.then(processResult);
2574
- } else {
2575
- return processResult(result);
2576
- }
2577
- }
2578
-
2579
- /** @internal */
2580
- override _dispose(): void {
2581
- this._ref?.free();
2582
- }
2583
-
2584
- override ref() {
2585
- this._ref ??= this._baseSource.ref();
2586
- return super.ref();
2587
- }
2588
- }