@zephyr3d/scene 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/dist/animation/animation.js +4 -15
  2. package/dist/animation/animation.js.map +1 -1
  3. package/dist/animation/animationset.js +22 -9
  4. package/dist/animation/animationset.js.map +1 -1
  5. package/dist/animation/animationtrack.js +1 -0
  6. package/dist/animation/animationtrack.js.map +1 -1
  7. package/dist/animation/eulerrotationtrack.js +0 -1
  8. package/dist/animation/eulerrotationtrack.js.map +1 -1
  9. package/dist/animation/morphtarget.js +7 -1
  10. package/dist/animation/morphtarget.js.map +1 -1
  11. package/dist/animation/morphtrack.js +3 -3
  12. package/dist/animation/morphtrack.js.map +1 -1
  13. package/dist/animation/proptrack.js +37 -41
  14. package/dist/animation/proptrack.js.map +1 -1
  15. package/dist/animation/rotationtrack.js +0 -1
  16. package/dist/animation/rotationtrack.js.map +1 -1
  17. package/dist/animation/scaletrack.js +0 -1
  18. package/dist/animation/scaletrack.js.map +1 -1
  19. package/dist/animation/skeleton.js +7 -14
  20. package/dist/animation/skeleton.js.map +1 -1
  21. package/dist/animation/translationtrack.js +0 -1
  22. package/dist/animation/translationtrack.js.map +1 -1
  23. package/dist/app/api.js +13 -4
  24. package/dist/app/api.js.map +1 -1
  25. package/dist/app/app.js +13 -1
  26. package/dist/app/app.js.map +1 -1
  27. package/dist/app/engine.js +33 -45
  28. package/dist/app/engine.js.map +1 -1
  29. package/dist/app/inputmgr.js.map +1 -1
  30. package/dist/app/runtimescript.js.map +1 -1
  31. package/dist/app/screen.js +318 -0
  32. package/dist/app/screen.js.map +1 -0
  33. package/dist/app/scriptingsystem.js +10 -6
  34. package/dist/app/scriptingsystem.js.map +1 -1
  35. package/dist/app/scriptregistry.js +11 -22
  36. package/dist/app/scriptregistry.js.map +1 -1
  37. package/dist/asset/assetmanager.js +79 -58
  38. package/dist/asset/assetmanager.js.map +1 -1
  39. package/dist/asset/builtin.js +5 -5
  40. package/dist/asset/builtin.js.map +1 -1
  41. package/dist/asset/loaders/dds/dds.js +6 -2
  42. package/dist/asset/loaders/dds/dds.js.map +1 -1
  43. package/dist/asset/loaders/dds/dds_loader.js +1 -1
  44. package/dist/asset/loaders/dds/dds_loader.js.map +1 -1
  45. package/dist/asset/loaders/gltf/gltf_loader.js +14 -6
  46. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  47. package/dist/asset/loaders/gltf/helpers.js +6 -2
  48. package/dist/asset/loaders/gltf/helpers.js.map +1 -1
  49. package/dist/asset/loaders/hdr/hdr.js +22 -15
  50. package/dist/asset/loaders/hdr/hdr.js.map +1 -1
  51. package/dist/asset/loaders/image/tga_Loader.js +2 -1
  52. package/dist/asset/loaders/image/tga_Loader.js.map +1 -1
  53. package/dist/asset/loaders/image/webimage_loader.js.map +1 -1
  54. package/dist/asset/loaders/loader.js +2 -2
  55. package/dist/asset/loaders/loader.js.map +1 -1
  56. package/dist/asset/model.js +2 -2
  57. package/dist/asset/model.js.map +1 -1
  58. package/dist/blitter/bilateralblur.js.map +1 -1
  59. package/dist/blitter/blitter.js +9 -11
  60. package/dist/blitter/blitter.js.map +1 -1
  61. package/dist/blitter/box.js +0 -1
  62. package/dist/blitter/box.js.map +1 -1
  63. package/dist/blitter/copy.js.map +1 -1
  64. package/dist/blitter/gaussianblur.js.map +1 -1
  65. package/dist/camera/base.js +1 -3
  66. package/dist/camera/base.js.map +1 -1
  67. package/dist/camera/camera.js +121 -37
  68. package/dist/camera/camera.js.map +1 -1
  69. package/dist/camera/fps.js +19 -17
  70. package/dist/camera/fps.js.map +1 -1
  71. package/dist/camera/orbit.js +45 -43
  72. package/dist/camera/orbit.js.map +1 -1
  73. package/dist/camera/orthocamera.js +27 -21
  74. package/dist/camera/orthocamera.js.map +1 -1
  75. package/dist/camera/perspectivecamera.js +26 -17
  76. package/dist/camera/perspectivecamera.js.map +1 -1
  77. package/dist/index.d.ts +14453 -15609
  78. package/dist/index.js +17 -11
  79. package/dist/index.js.map +1 -1
  80. package/dist/material/blinn.js.map +1 -1
  81. package/dist/material/grassmaterial.js.map +1 -1
  82. package/dist/material/lambert.js.map +1 -1
  83. package/dist/material/material.js +11 -5
  84. package/dist/material/material.js.map +1 -1
  85. package/dist/material/meshmaterial.js +10 -9
  86. package/dist/material/meshmaterial.js.map +1 -1
  87. package/dist/material/mixins/albedocolor.js.map +1 -1
  88. package/dist/material/mixins/foliage.js.map +1 -1
  89. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  90. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  91. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +7 -0
  92. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  93. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  94. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  95. package/dist/material/mixins/lit.js +3 -3
  96. package/dist/material/mixins/lit.js.map +1 -1
  97. package/dist/material/mixins/pbr/brdf.js.map +1 -1
  98. package/dist/material/mixins/pbr/common.js.map +1 -1
  99. package/dist/material/mixins/texture.js +3 -0
  100. package/dist/material/mixins/texture.js.map +1 -1
  101. package/dist/material/mixins/vertexcolor.js.map +1 -1
  102. package/dist/material/particle.js.map +1 -1
  103. package/dist/material/pbrblueprint.js +180 -22
  104. package/dist/material/pbrblueprint.js.map +1 -1
  105. package/dist/material/pbrmr.js.map +1 -1
  106. package/dist/material/pbrsg.js.map +1 -1
  107. package/dist/material/shader/helper.js +36 -53
  108. package/dist/material/shader/helper.js.map +1 -1
  109. package/dist/material/sprite.js +301 -0
  110. package/dist/material/sprite.js.map +1 -0
  111. package/dist/material/sprite3d.js +301 -0
  112. package/dist/material/sprite3d.js.map +1 -0
  113. package/dist/material/sprite3d_std.js +116 -0
  114. package/dist/material/sprite3d_std.js.map +1 -0
  115. package/dist/material/sprite3dblueprint.js +235 -0
  116. package/dist/material/sprite3dblueprint.js.map +1 -0
  117. package/dist/material/sprite_std.js +116 -0
  118. package/dist/material/sprite_std.js.map +1 -0
  119. package/dist/material/spriteblueprint.js +235 -0
  120. package/dist/material/spriteblueprint.js.map +1 -0
  121. package/dist/material/terrain-cm.js +0 -1
  122. package/dist/material/terrain-cm.js.map +1 -1
  123. package/dist/material/unlit.js.map +1 -1
  124. package/dist/material/water.js.map +1 -1
  125. package/dist/posteffect/bloom.js.map +1 -1
  126. package/dist/posteffect/compositor.js.map +1 -1
  127. package/dist/posteffect/fxaa.js.map +1 -1
  128. package/dist/posteffect/grayscale.js.map +1 -1
  129. package/dist/posteffect/motionblur.js.map +1 -1
  130. package/dist/posteffect/posteffect.js.map +1 -1
  131. package/dist/posteffect/sao.js.map +1 -1
  132. package/dist/posteffect/ssr.js +7 -5
  133. package/dist/posteffect/ssr.js.map +1 -1
  134. package/dist/posteffect/taa.js.map +1 -1
  135. package/dist/posteffect/tonemap.js.map +1 -1
  136. package/dist/render/abuffer_oit.js +8 -6
  137. package/dist/render/abuffer_oit.js.map +1 -1
  138. package/dist/render/clipmap.js +0 -10
  139. package/dist/render/clipmap.js.map +1 -1
  140. package/dist/render/cluster_light.js +4 -4
  141. package/dist/render/cluster_light.js.map +1 -1
  142. package/dist/render/cull_visitor.js +15 -17
  143. package/dist/render/cull_visitor.js.map +1 -1
  144. package/dist/render/depthpass.js +3 -4
  145. package/dist/render/depthpass.js.map +1 -1
  146. package/dist/render/drawable.js +15 -0
  147. package/dist/render/drawable.js.map +1 -0
  148. package/dist/render/drawable_mixin.js +8 -4
  149. package/dist/render/drawable_mixin.js.map +1 -1
  150. package/dist/render/envlight.js.map +1 -1
  151. package/dist/render/fbm_wavegenerator.js +3 -1
  152. package/dist/render/fbm_wavegenerator.js.map +1 -1
  153. package/dist/render/fft_wavegenerator.js +67 -64
  154. package/dist/render/fft_wavegenerator.js.map +1 -1
  155. package/dist/render/fullscreenquad.js.map +1 -1
  156. package/dist/render/gerstner_wavegenerator.js +3 -1
  157. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  158. package/dist/render/globalbindgroup_allocator.js +3 -1
  159. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  160. package/dist/render/hzb.js +1 -2
  161. package/dist/render/hzb.js.map +1 -1
  162. package/dist/render/lightpass.js +13 -13
  163. package/dist/render/lightpass.js.map +1 -1
  164. package/dist/render/objectcolorpass.js +4 -7
  165. package/dist/render/objectcolorpass.js.map +1 -1
  166. package/dist/render/primitive.js +4 -5
  167. package/dist/render/primitive.js.map +1 -1
  168. package/dist/render/render_queue.js +10 -5
  169. package/dist/render/render_queue.js.map +1 -1
  170. package/dist/render/renderer.js +16 -22
  171. package/dist/render/renderer.js.map +1 -1
  172. package/dist/render/renderpass.js +27 -52
  173. package/dist/render/renderpass.js.map +1 -1
  174. package/dist/render/rendertarget.js +5 -0
  175. package/dist/render/rendertarget.js.map +1 -0
  176. package/dist/render/screenrendertarget.js +56 -0
  177. package/dist/render/screenrendertarget.js.map +1 -0
  178. package/dist/render/shadowmap_pass.js +4 -5
  179. package/dist/render/shadowmap_pass.js.map +1 -1
  180. package/dist/render/sky.js +16 -14
  181. package/dist/render/sky.js.map +1 -1
  182. package/dist/render/weightedblended_oit.js.map +1 -1
  183. package/dist/scene/basesprite.js +296 -0
  184. package/dist/scene/basesprite.js.map +1 -0
  185. package/dist/scene/batchgroup.js +4 -2
  186. package/dist/scene/batchgroup.js.map +1 -1
  187. package/dist/scene/environment.js +9 -10
  188. package/dist/scene/environment.js.map +1 -1
  189. package/dist/scene/graph_node.js.map +1 -1
  190. package/dist/scene/light.js +22 -4
  191. package/dist/scene/light.js.map +1 -1
  192. package/dist/scene/mesh.js +93 -15
  193. package/dist/scene/mesh.js.map +1 -1
  194. package/dist/scene/octree.js.map +1 -1
  195. package/dist/scene/particlesys.js +25 -22
  196. package/dist/scene/particlesys.js.map +1 -1
  197. package/dist/scene/raycast_visitor.js +0 -16
  198. package/dist/scene/raycast_visitor.js.map +1 -1
  199. package/dist/scene/scene.js +7 -4
  200. package/dist/scene/scene.js.map +1 -1
  201. package/dist/scene/scene_node.js +20 -35
  202. package/dist/scene/scene_node.js.map +1 -1
  203. package/dist/scene/sprite.js +18 -0
  204. package/dist/scene/sprite.js.map +1 -0
  205. package/dist/scene/sprite3d.js +18 -0
  206. package/dist/scene/sprite3d.js.map +1 -0
  207. package/dist/scene/terrain-cm/grass.js +5 -4
  208. package/dist/scene/terrain-cm/grass.js.map +1 -1
  209. package/dist/scene/terrain-cm/grassmaterial.js +3 -1
  210. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  211. package/dist/scene/terrain-cm/terrain-cm.js +65 -48
  212. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  213. package/dist/scene/water.js +35 -30
  214. package/dist/scene/water.js.map +1 -1
  215. package/dist/shaders/atmosphere.js +17 -29
  216. package/dist/shaders/atmosphere.js.map +1 -1
  217. package/dist/shaders/fog.js.map +1 -1
  218. package/dist/shaders/misc.js.map +1 -1
  219. package/dist/shaders/noise.js.map +1 -1
  220. package/dist/shaders/pbr.js.map +1 -1
  221. package/dist/shaders/shadow.js.map +1 -1
  222. package/dist/shaders/ssr.js.map +1 -1
  223. package/dist/shaders/temporal.js.map +1 -1
  224. package/dist/shaders/water.js.map +1 -1
  225. package/dist/shadow/esm.js +1 -1
  226. package/dist/shadow/esm.js.map +1 -1
  227. package/dist/shadow/pcf_opt.js.map +1 -1
  228. package/dist/shadow/pcf_pd.js.map +1 -1
  229. package/dist/shadow/shader.js +3 -1
  230. package/dist/shadow/shader.js.map +1 -1
  231. package/dist/shadow/shadow_impl.js.map +1 -1
  232. package/dist/shadow/shadowmapper.js +6 -18
  233. package/dist/shadow/shadowmapper.js.map +1 -1
  234. package/dist/shadow/ssm.js.map +1 -1
  235. package/dist/shadow/vsm.js.map +1 -1
  236. package/dist/shapes/box.js +9 -3
  237. package/dist/shapes/box.js.map +1 -1
  238. package/dist/shapes/cylinder.js +2 -2
  239. package/dist/shapes/cylinder.js.map +1 -1
  240. package/dist/shapes/plane.js +2 -2
  241. package/dist/shapes/plane.js.map +1 -1
  242. package/dist/shapes/shape.js +2 -1
  243. package/dist/shapes/shape.js.map +1 -1
  244. package/dist/shapes/sphere.js +2 -2
  245. package/dist/shapes/sphere.js.map +1 -1
  246. package/dist/shapes/tetrahedron.js +5 -6
  247. package/dist/shapes/tetrahedron.js.map +1 -1
  248. package/dist/shapes/torus.js +2 -2
  249. package/dist/shapes/torus.js.map +1 -1
  250. package/dist/utility/aabbtree.js +1 -1
  251. package/dist/utility/aabbtree.js.map +1 -1
  252. package/dist/utility/blueprint/common/constants.js +578 -104
  253. package/dist/utility/blueprint/common/constants.js.map +1 -1
  254. package/dist/utility/blueprint/common/math.js +471 -9
  255. package/dist/utility/blueprint/common/math.js.map +1 -1
  256. package/dist/utility/blueprint/common.js +1 -1
  257. package/dist/utility/blueprint/common.js.map +1 -1
  258. package/dist/utility/blueprint/material/func.js +9 -5
  259. package/dist/utility/blueprint/material/func.js.map +1 -1
  260. package/dist/utility/blueprint/material/inputs.js.map +1 -1
  261. package/dist/utility/blueprint/material/ir.js +288 -80
  262. package/dist/utility/blueprint/material/ir.js.map +1 -1
  263. package/dist/utility/blueprint/material/pbr.js +92 -4
  264. package/dist/utility/blueprint/material/pbr.js.map +1 -1
  265. package/dist/utility/blueprint/material/texture.js +62 -45
  266. package/dist/utility/blueprint/material/texture.js.map +1 -1
  267. package/dist/utility/blueprint/node.js +28 -1
  268. package/dist/utility/blueprint/node.js.map +1 -1
  269. package/dist/utility/bounding_volume.js.map +1 -1
  270. package/dist/utility/debug.js.map +1 -1
  271. package/dist/utility/draco/decoder.js.map +1 -1
  272. package/dist/utility/misc.js +1 -1
  273. package/dist/utility/misc.js.map +1 -1
  274. package/dist/utility/panorama.js.map +1 -1
  275. package/dist/utility/pmrem.js.map +1 -1
  276. package/dist/utility/rendermipmap.js.map +1 -1
  277. package/dist/utility/serialization/json.js +19 -15
  278. package/dist/utility/serialization/json.js.map +1 -1
  279. package/dist/utility/serialization/manager.js +89 -22
  280. package/dist/utility/serialization/manager.js.map +1 -1
  281. package/dist/utility/serialization/scene/animation.js +23 -21
  282. package/dist/utility/serialization/scene/animation.js.map +1 -1
  283. package/dist/utility/serialization/scene/batch.js +4 -3
  284. package/dist/utility/serialization/scene/batch.js.map +1 -1
  285. package/dist/utility/serialization/scene/camera.js +97 -9
  286. package/dist/utility/serialization/scene/camera.js.map +1 -1
  287. package/dist/utility/serialization/scene/common.js +102 -28
  288. package/dist/utility/serialization/scene/common.js.map +1 -1
  289. package/dist/utility/serialization/scene/light.js +14 -12
  290. package/dist/utility/serialization/scene/light.js.map +1 -1
  291. package/dist/utility/serialization/scene/material.js +154 -26
  292. package/dist/utility/serialization/scene/material.js.map +1 -1
  293. package/dist/utility/serialization/scene/mesh.js +71 -100
  294. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  295. package/dist/utility/serialization/scene/misc.js +3 -2
  296. package/dist/utility/serialization/scene/misc.js.map +1 -1
  297. package/dist/utility/serialization/scene/node.js +42 -9
  298. package/dist/utility/serialization/scene/node.js.map +1 -1
  299. package/dist/utility/serialization/scene/particle.js +7 -5
  300. package/dist/utility/serialization/scene/particle.js.map +1 -1
  301. package/dist/utility/serialization/scene/primitive.js +18 -15
  302. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  303. package/dist/utility/serialization/scene/scene.js +3 -2
  304. package/dist/utility/serialization/scene/scene.js.map +1 -1
  305. package/dist/utility/serialization/scene/sprite.js +164 -0
  306. package/dist/utility/serialization/scene/sprite.js.map +1 -0
  307. package/dist/utility/serialization/scene/terrain.js +8 -6
  308. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  309. package/dist/utility/serialization/scene/water.js +11 -9
  310. package/dist/utility/serialization/scene/water.js.map +1 -1
  311. package/dist/utility/serialization/types.js +6 -0
  312. package/dist/utility/serialization/types.js.map +1 -0
  313. package/dist/utility/shprojector.js.map +1 -1
  314. package/dist/utility/textures/ggxlut.js.map +1 -1
  315. package/dist/utility/textures/gradientnoise.js.map +1 -1
  316. package/dist/utility/textures/randomnoise.js.map +1 -1
  317. package/dist/values.js +14 -14
  318. package/dist/values.js.map +1 -1
  319. package/package.json +80 -80
@@ -1 +1 @@
1
- {"version":3,"file":"scriptregistry.js","sources":["../../src/app/scriptregistry.ts"],"sourcesContent":["import type * as TS from 'typescript';\r\nimport type { VFS } from '@zephyr3d/base';\r\nimport { textToBase64 } from '@zephyr3d/base';\r\nimport { init, parse } from 'es-module-lexer';\r\n\r\n/**\r\n * Converts JavaScript source to a data URL tied to a logical module id.\r\n *\r\n * @param js - The JavaScript source code to embed.\r\n * @param id - Logical module identifier (used only for sourceURL tagging).\r\n * @returns A `data:text/javascript;base64,...` URL with an encoded `#id` suffix.\r\n * @internal\r\n */\r\nfunction toDataUrl(js: string, id: string): string {\r\n const b64 = textToBase64(js);\r\n return `data:text/javascript;base64,${b64}#${encodeURIComponent(String(id))}`;\r\n}\r\n\r\n/**\r\n * Checks whether a specifier is an absolute HTTP(S) URL.\r\n * @internal\r\n */\r\nfunction isAbsoluteUrl(spec: string): boolean {\r\n return /^https?:\\/\\//i.test(spec);\r\n}\r\n\r\n/**\r\n * Checks whether a specifier is a special URL (data: or blob:).\r\n * @internal\r\n */\r\nfunction isSpecialUrl(spec: string): boolean {\r\n return /^(data|blob):/i.test(spec);\r\n}\r\n\r\n/**\r\n * Checks whether a specifier is a bare module (not starting with ./, ../, /, or #/).\r\n * @internal\r\n */\r\nfunction isBareModule(spec: string): boolean {\r\n return !spec.startsWith('./') && !spec.startsWith('../') && !spec.startsWith('/') && !spec.startsWith('#/');\r\n}\r\n\r\n/**\r\n * Resolves, builds, and serves runtime modules using a VFS.\r\n *\r\n * Responsibilities:\r\n * - Resolve logical module IDs to physical paths or URLs.\r\n * - In editor mode, rewrite import specifiers and serve modules as data URLs after transpile.\r\n * - Transpile TypeScript to JavaScript on the fly (requires `window.ts` TypeScript runtime).\r\n * - Gather static and dynamic import dependencies for tooling.\r\n *\r\n * Modes:\r\n * - Editor mode (`editorMode === true`): modules are rewritten to data URLs after transpile/build.\r\n * - Runtime mode (`editorMode === false`): returns .js URLs directly (with .ts -\\> .js mapping).\r\n *\r\n * Caching:\r\n * - Built modules are memoized in `_built` map keyed by logical ID.\r\n *\r\n * @public\r\n */\r\nexport class ScriptRegistry {\r\n private _vfs: VFS;\r\n private _scriptsRoot: string;\r\n private _built = new Map<string, string>(); // logicalId -> dataURL\r\n private _editorMode = false;\r\n\r\n /**\r\n * @param vfs - The virtual file system for existence checks, reads, and path ops.\r\n * @param scriptsRoot - Root directory for script resolution (used with `#/` specifiers).\r\n * @param editorMode - Whether to build modules to data URLs and rewrite imports.\r\n */\r\n constructor(vfs: VFS, scriptsRoot: string, editorMode: boolean) {\r\n this._vfs = vfs;\r\n this._scriptsRoot = scriptsRoot;\r\n this._editorMode = editorMode;\r\n }\r\n\r\n /**\r\n * The active virtual file system.\r\n *\r\n * Assigning a new VFS clears the build cache.\r\n */\r\n get VFS() {\r\n return this._vfs;\r\n }\r\n set VFS(vfs: VFS) {\r\n if (vfs !== this._vfs) {\r\n this._vfs = vfs;\r\n this._built.clear();\r\n }\r\n }\r\n\r\n /**\r\n * Whether the registry operates in editor mode (rewrite/build to data URLs).\r\n */\r\n get editorMode() {\r\n return this._editorMode;\r\n }\r\n set editorMode(val: boolean) {\r\n this._editorMode = val;\r\n }\r\n\r\n /**\r\n * The root path used by `#/` specifiers.\r\n */\r\n get scriptsRoot() {\r\n return this._scriptsRoot;\r\n }\r\n set scriptsRoot(path: string) {\r\n this._scriptsRoot = path;\r\n }\r\n\r\n /**\r\n * Fetches raw source for a logical module id by probing known extensions.\r\n *\r\n * Search order:\r\n * - If `id` already ends with `.ts` or `.js` and is a file -\\> return it.\r\n * - Else try `.id.ts`, then `.id.js`.\r\n *\r\n * @param id - Logical module identifier (absolute or logical path-like).\r\n * @returns Source code, resolved path, and type (`'js' | 'ts'`), or `undefined` if not found.\r\n */\r\n protected async fetchSource(\r\n id: string\r\n ): Promise<{ code: string; path: string; type: 'js' | 'ts'; sourceMap?: string } | undefined> {\r\n let type: 'js' | 'ts' = null;\r\n let pathWithExt = '';\r\n if (id.endsWith('.ts')) {\r\n pathWithExt = id;\r\n type = 'ts';\r\n } else if (id.endsWith('.js')) {\r\n pathWithExt = id;\r\n type = 'js';\r\n }\r\n if (type) {\r\n const exists = await this._vfs.exists(pathWithExt);\r\n if (!exists) {\r\n type = null;\r\n }\r\n const stat = await this._vfs.stat(pathWithExt);\r\n if (stat.isDirectory) {\r\n type = null;\r\n }\r\n }\r\n const types = ['ts', 'js'] as const;\r\n if (!type) {\r\n for (const t of types) {\r\n pathWithExt = `${id}.${t}`;\r\n const exists = await this._vfs.exists(pathWithExt);\r\n if (exists) {\r\n const stats = await this._vfs.stat(pathWithExt);\r\n if (stats.isFile) {\r\n type = t;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n if (type) {\r\n const code = (await this._vfs.readFile(pathWithExt, { encoding: 'utf8' })) as string;\r\n return { code, type, path: pathWithExt };\r\n }\r\n }\r\n\r\n /**\r\n * Resolves a module entry to a URL suitable for dynamic import.\r\n *\r\n * Behavior:\r\n * - In editor mode, builds the module to a data URL.\r\n * - Otherwise, returns `.js` URL directly:\r\n * - If `id` ends with `.js`: return as-is.\r\n * - If `id` ends with `.ts`: map to `.js` (assumes pre-built file exists).\r\n * - Else: append `.js`.\r\n *\r\n * @param entryId - Entry module identifier (logical or path-like).\r\n * @returns A URL string that can be used in `import(...)`.\r\n */\r\n async resolveRuntimeUrl(entryId: string): Promise<string> {\r\n const id = await this.resolveLogicalId(entryId);\r\n return this._editorMode\r\n ? await this.build(String(id))\r\n : id.endsWith('.js')\r\n ? id\r\n : id.endsWith('.ts')\r\n ? `${id.slice(0, -3)}.js`\r\n : `${id}.js`;\r\n }\r\n\r\n /**\r\n * Recursively gathers direct static and dynamic import dependencies for a module.\r\n *\r\n * Only relative specifiers (`./` or `../`) are followed. Absolute, special, and bare\r\n * module specifiers are ignored here.\r\n *\r\n * @param entryId - The starting (possibly relative) specifier from `fromId`.\r\n * @param fromId - The logical id of the module containing `entryId`.\r\n * @param dependencies - Output map of `resolvedSourcePath -\\> file contents`.\r\n */\r\n async getDependencies(\r\n entryId: string,\r\n fromId: string,\r\n dependencies: Record<string, string>\r\n ): Promise<void> {\r\n const reStatic = /\\b(?:import|export)\\s+[^\"']*?from\\s+(['\"])([^'\"]+)\\1/g;\r\n const reDynamic = /\\bimport\\s*\\(\\s*(['\"])([^'\"]+)\\1\\s*\\)/g;\r\n\r\n const normalizedId = await this.resolveLogicalId(entryId, fromId);\r\n const srcPath = await this.resolveSourcePath(normalizedId);\r\n if (!srcPath || dependencies[srcPath.path] !== undefined) {\r\n return;\r\n }\r\n const code = (await this._vfs.readFile(srcPath.path, { encoding: 'utf8' })) as string;\r\n dependencies[srcPath.path] = code;\r\n\r\n const gather = async (input: string, re: RegExp) => {\r\n for (;;) {\r\n const m = re.exec(input);\r\n if (!m) {\r\n break;\r\n }\r\n\r\n const spec = m[2];\r\n\r\n if (spec.startsWith('./') || spec.startsWith('../')) {\r\n await this.getDependencies(spec, normalizedId, dependencies);\r\n }\r\n }\r\n };\r\n\r\n await gather(code, reStatic);\r\n await gather(code, reDynamic);\r\n }\r\n\r\n /**\r\n * Builds a logical module id into a data URL (editor mode pipeline).\r\n *\r\n * Steps:\r\n * - Resolve source path (.ts/.js) via {@link ScriptRegistry.resolveSourcePath}.\r\n * - Read source code.\r\n * - Rewrite import specifiers via {@link ScriptRegistry.rewriteImports}.\r\n * - Transpile TypeScript if needed via {@link ScriptRegistry.transpile}.\r\n * - Convert to `data:` URL and memoize in `_built`.\r\n *\r\n * @param id - Logical module id to build.\r\n * @returns Data URL string for dynamic import, or empty string if not found.\r\n */\r\n private async build(id: string): Promise<string> {\r\n const key = String(id);\r\n const cached = this._built.get(key);\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const srcPath = await this.resolveSourcePath(key);\r\n if (!srcPath) {\r\n return '';\r\n }\r\n const code = (await this._vfs.readFile(srcPath.path, { encoding: 'utf8' })) as string;\r\n\r\n const rewritten = await this.rewriteImports(code, key);\r\n const js = await this.transpile(rewritten, key, srcPath.type);\r\n const url = toDataUrl(js, key);\r\n this._built.set(key, url);\r\n return url;\r\n }\r\n\r\n /**\r\n * Transpiles code to JavaScript and appends sourceURL/sourceMap hints.\r\n *\r\n * Behavior:\r\n * - For `'js'`, returns code with `//# sourceURL=logicalId`.\r\n * - For `'ts'`, requires `window.ts` (TypeScript compiler) to be present and\r\n * transpiles to ES2015/ESNext module with inline source maps.\r\n *\r\n * @param code - Source code to transpile.\r\n * @param _id - Logical module id (used for fileName/sourceURL).\r\n * @param type - Source type (`'js' | 'ts'`).\r\n * @returns Transpiled JavaScript source.\r\n * @throws If TypeScript runtime is not found for TS input.\r\n */\r\n private async transpile(code: string, _id: string, type: 'js' | 'ts'): Promise<string> {\r\n const logicalId = String(_id);\r\n\r\n if (type === 'js') {\r\n return `${code}\\n//# sourceURL=${logicalId}`;\r\n }\r\n\r\n const ts = (window as any).ts as typeof TS;\r\n if (!ts) {\r\n throw new Error('TypeScript runtime (window.ts) not found. Load typescript.js first.');\r\n }\r\n\r\n const res = ts.transpileModule(code, {\r\n compilerOptions: {\r\n target: ts.ScriptTarget.ES2015,\r\n module: ts.ModuleKind.ESNext,\r\n sourceMap: true,\r\n inlineSources: true,\r\n experimentalDecorators: true,\r\n useDefineForClassFields: false\r\n },\r\n fileName: logicalId\r\n });\r\n\r\n let out = res.outputText || '';\r\n if (res.sourceMapText) {\r\n const mapBase64 = btoa(unescape(encodeURIComponent(res.sourceMapText)));\r\n out += `\\n//# sourceMappingURL=data:application/json;base64,${mapBase64}`;\r\n }\r\n out += `\\n//# sourceURL=${logicalId}`;\r\n return out;\r\n }\r\n\r\n /**\r\n * Rewrites ESM import specifiers in `code` into runtime-loadable URLs.\r\n *\r\n * Parsing:\r\n * - Uses `es-module-lexer` to find import spans; sorts them ascending by start.\r\n *\r\n * Replacement rules:\r\n * - Skip invalid spans or ones without quoted specifiers.\r\n * - If spec is absolute URL, special URL (data:, blob:), or bare module:\r\n * - If it starts with `@zephyr3d/`, keep as-is (external).\r\n * - Otherwise resolve to a logical id and attempt to `build` it (if available).\r\n * - Else (relative spec), resolve from `fromId` and `build` recursively.\r\n *\r\n * Output:\r\n * - Directly writes the replacement specifier without re-adding quotes,\r\n * so replacements must themselves be quoted or be valid URLs/data URLs.\r\n *\r\n * @param code - Module source code to transform.\r\n * @param fromId - The logical id of the current module (resolution base for relatives).\r\n * @returns Transformed source with rewritten import specifiers.\r\n */\r\n private async rewriteImports(code: string, fromId: string): Promise<string> {\r\n await init;\r\n const [imports] = parse(code);\r\n const list = [...imports].sort((a, b) => (a.s || 0) - (b.s || 0));\r\n let out = '';\r\n let last = 0;\r\n\r\n for (const im of list) {\r\n // must have quotes\r\n const hasQuote = im.ss != null && im.se != null;\r\n if (!hasQuote || im.se <= im.ss) {\r\n continue;\r\n }\r\n // must have contents\r\n if (im.e <= im.s) {\r\n continue;\r\n }\r\n // append [last, s)\r\n out += code.slice(last, im.s);\r\n\r\n const spec = code.slice(im.s, im.e); // original spec\r\n let replacement = spec;\r\n if (isAbsoluteUrl(spec) || isSpecialUrl(spec) || isBareModule(spec)) {\r\n if (spec.startsWith('@zephyr3d/')) {\r\n replacement = spec;\r\n } else {\r\n const depId = await this.resolveLogicalId(spec);\r\n replacement = await this.build(depId); // try build as dependence\r\n }\r\n } else {\r\n const depId = await this.resolveLogicalId(spec, String(fromId));\r\n replacement = await this.build(depId); // recursively build as dataURL\r\n }\r\n out += replacement; // 不加引号\r\n last = im.e;\r\n }\r\n out += code.slice(last);\r\n return out;\r\n }\r\n\r\n /**\r\n * Resolves a specifier to a logical id suitable for further processing.\r\n *\r\n * Resolution rules:\r\n * - `#/path`: resolved against `scriptsRoot` via VFS join/normalize.\r\n * - `./` or `../`: resolved relative to `fromId` directory (requires `fromId`).\r\n * - `/absolute`: treated as absolute from root (normalized).\r\n * - Bare module in editor mode: if `/deps.lock.json` exists and contains an entry,\r\n * map to the dependency's `entry` path; otherwise return as-is.\r\n * - Else (non-editor bare module): return `spec` unchanged (external).\r\n *\r\n * @param spec - Import specifier string.\r\n * @param fromId - Optional base logical id used for relative resolution.\r\n * @returns A normalized logical id or an external specifier string.\r\n * @throws If a relative import is provided without `fromId`.\r\n */\r\n async resolveLogicalId(spec: string, fromId?: string): Promise<string> {\r\n let path: string;\r\n\r\n if (spec.startsWith('#/')) {\r\n path = this._vfs.normalizePath(this._vfs.join(this._scriptsRoot, spec.slice(2)));\r\n } else if (spec.startsWith('./') || spec.startsWith('../')) {\r\n if (!fromId) {\r\n throw new Error(`Relative import \"${spec}\" requires fromId`);\r\n }\r\n path = this._vfs.normalizePath(\r\n this._vfs.join(this._vfs.dirname(this._vfs.normalizePath(fromId)), spec)\r\n );\r\n } else if (spec.startsWith('/')) {\r\n path = spec.replace(/^\\/+/, '/');\r\n } else if (this._editorMode) {\r\n // naked module, checking if it is a installed module in editor mode\r\n const depsExists = await this._vfs.exists('/libs/deps.lock.json');\r\n if (depsExists) {\r\n const content = (await this._vfs.readFile('/libs/deps.lock.json', { encoding: 'utf8' })) as string;\r\n const depsInfo = JSON.parse(content) as { dependencies: Record<string, { entry: string }> };\r\n if (depsInfo?.dependencies[spec]) {\r\n path = this._vfs.normalizePath(depsInfo.dependencies[spec].entry);\r\n }\r\n }\r\n } else {\r\n return spec;\r\n }\r\n return path;\r\n }\r\n\r\n /**\r\n * Resolves a logical id to a concrete source path and type by probing extensions.\r\n *\r\n * Rules:\r\n * - If `logicalId` ends with `.ts` or `.js`/`.mjs` and is a file, return it.\r\n * - Else probe `logicalId.ts`, `logicalId.js`, `logicalId.mjs` in that order.\r\n * - Maps `.mjs` to type `'js'`.\r\n *\r\n * @param logicalId - The normalized logical module id (path-like).\r\n * @returns `{ type, path }` or `null` if not found.\r\n */\r\n async resolveSourcePath(logicalId: string) {\r\n let type: 'js' | 'ts' = null;\r\n let pathWithExt = '';\r\n if (logicalId.endsWith('.ts')) {\r\n pathWithExt = logicalId;\r\n type = 'ts';\r\n } else if (logicalId.endsWith('.js') || logicalId.endsWith('.mjs')) {\r\n pathWithExt = logicalId;\r\n type = 'js';\r\n }\r\n if (type) {\r\n const exists = await this._vfs.exists(pathWithExt);\r\n if (!exists) {\r\n type = null;\r\n }\r\n const stat = await this._vfs.stat(pathWithExt);\r\n if (stat.isDirectory) {\r\n type = null;\r\n }\r\n }\r\n const types = ['ts', 'js', 'mjs'] as const;\r\n if (!type) {\r\n for (const t of types) {\r\n pathWithExt = `${logicalId}.${t}`;\r\n const exists = await this._vfs.exists(pathWithExt);\r\n if (exists) {\r\n const stats = await this._vfs.stat(pathWithExt);\r\n if (stats.isFile) {\r\n type = t === 'ts' ? 'ts' : 'js';\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n return type ? { type, path: pathWithExt } : null;\r\n }\r\n}\r\n"],"names":["toDataUrl","js","id","b64","textToBase64","encodeURIComponent","String","isAbsoluteUrl","spec","test","isSpecialUrl","isBareModule","startsWith","ScriptRegistry","_vfs","_scriptsRoot","_built","Map","_editorMode","vfs","scriptsRoot","editorMode","VFS","clear","val","path","fetchSource","type","pathWithExt","endsWith","exists","stat","isDirectory","types","t","stats","isFile","code","readFile","encoding","resolveRuntimeUrl","entryId","resolveLogicalId","build","slice","getDependencies","fromId","dependencies","reStatic","reDynamic","normalizedId","srcPath","resolveSourcePath","undefined","gather","input","re","m","exec","key","cached","get","rewritten","rewriteImports","transpile","url","set","_id","logicalId","ts","window","Error","res","transpileModule","compilerOptions","target","ScriptTarget","ES2015","module","ModuleKind","ESNext","sourceMap","inlineSources","experimentalDecorators","useDefineForClassFields","fileName","out","outputText","sourceMapText","mapBase64","btoa","unescape","init","imports","parse","list","sort","a","b","s","last","im","hasQuote","ss","se","e","replacement","depId","normalizePath","join","dirname","replace","depsExists","content","depsInfo","JSON","entry"],"mappings":"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"}
1
+ {"version":3,"file":"scriptregistry.js","sources":["../../src/app/scriptregistry.ts"],"sourcesContent":["import type * as TS from 'typescript';\r\nimport type { Nullable, VFS } from '@zephyr3d/base';\r\nimport { textToBase64 } from '@zephyr3d/base';\r\nimport { init, parse } from 'es-module-lexer';\r\nimport { getApp } from './api';\r\n\r\n/**\r\n * Converts JavaScript source to a data URL tied to a logical module id.\r\n *\r\n * @param js - The JavaScript source code to embed.\r\n * @param id - Logical module identifier (used only for sourceURL tagging).\r\n * @returns A `data:text/javascript;base64,...` URL with an encoded `#id` suffix.\r\n * @internal\r\n */\r\nfunction toDataUrl(js: string, id: string) {\r\n const b64 = textToBase64(js);\r\n return `data:text/javascript;base64,${b64}#${encodeURIComponent(String(id))}`;\r\n}\r\n\r\n/**\r\n * Checks whether a specifier is an absolute HTTP(S) URL.\r\n * @internal\r\n */\r\nfunction isAbsoluteUrl(spec: string) {\r\n return /^https?:\\/\\//i.test(spec);\r\n}\r\n\r\n/**\r\n * Checks whether a specifier is a special URL (data: or blob:).\r\n * @internal\r\n */\r\nfunction isSpecialUrl(spec: string) {\r\n return /^(data|blob):/i.test(spec);\r\n}\r\n\r\n/**\r\n * Checks whether a specifier is a bare module (not starting with ./, ../, /, or #/).\r\n * @internal\r\n */\r\nfunction isBareModule(spec: string) {\r\n return !spec.startsWith('./') && !spec.startsWith('../') && !spec.startsWith('/') && !spec.startsWith('#/');\r\n}\r\n\r\n/**\r\n * Resolves, builds, and serves runtime modules using a VFS.\r\n *\r\n * Responsibilities:\r\n * - Resolve logical module IDs to physical paths or URLs.\r\n * - In editor mode, rewrite import specifiers and serve modules as data URLs after transpile.\r\n * - Transpile TypeScript to JavaScript on the fly (requires `window.ts` TypeScript runtime).\r\n * - Gather static and dynamic import dependencies for tooling.\r\n *\r\n * Modes:\r\n * - Editor mode (`editorMode === true`): modules are rewritten to data URLs after transpile/build.\r\n * - Runtime mode (`editorMode === false`): returns .js URLs directly (with .ts -\\> .js mapping).\r\n *\r\n * Caching:\r\n * - Built modules are memoized in `_built` map keyed by logical ID.\r\n *\r\n * @public\r\n */\r\nexport class ScriptRegistry {\r\n private _vfs: VFS;\r\n private _scriptsRoot: string;\r\n private _built: Map<string, string>; // logicalId -> dataURL\r\n\r\n /**\r\n * @param vfs - The virtual file system for existence checks, reads, and path ops.\r\n * @param scriptsRoot - Root directory for script resolution (used with `#/` specifiers).\r\n * @param editorMode - Whether to build modules to data URLs and rewrite imports.\r\n */\r\n constructor(vfs: VFS, scriptsRoot: string) {\r\n this._vfs = vfs;\r\n this._scriptsRoot = scriptsRoot;\r\n this._built = new Map();\r\n }\r\n\r\n /**\r\n * The active virtual file system.\r\n *\r\n * Assigning a new VFS clears the build cache.\r\n */\r\n get VFS() {\r\n return this._vfs;\r\n }\r\n set VFS(vfs: VFS) {\r\n if (vfs !== this._vfs) {\r\n this._vfs = vfs;\r\n this._built.clear();\r\n }\r\n }\r\n\r\n /**\r\n * The root path used by `#/` specifiers.\r\n */\r\n get scriptsRoot() {\r\n return this._scriptsRoot;\r\n }\r\n set scriptsRoot(path: string) {\r\n this._scriptsRoot = path;\r\n }\r\n\r\n /**\r\n * Fetches raw source for a logical module id by probing known extensions.\r\n *\r\n * Search order:\r\n * - If `id` already ends with `.ts` or `.js` and is a file -\\> return it.\r\n * - Else try `.id.ts`, then `.id.js`.\r\n *\r\n * @param id - Logical module identifier (absolute or logical path-like).\r\n * @returns Source code, resolved path, and type (`'js' | 'ts'`), or `undefined` if not found.\r\n */\r\n protected async fetchSource(id: string) {\r\n let type: Nullable<'js' | 'ts'> = null;\r\n let pathWithExt = '';\r\n if (id.endsWith('.ts')) {\r\n pathWithExt = id;\r\n type = 'ts';\r\n } else if (id.endsWith('.js')) {\r\n pathWithExt = id;\r\n type = 'js';\r\n }\r\n if (type) {\r\n const exists = await this._vfs.exists(pathWithExt);\r\n if (!exists) {\r\n type = null;\r\n }\r\n const stat = await this._vfs.stat(pathWithExt);\r\n if (stat.isDirectory) {\r\n type = null;\r\n }\r\n }\r\n const types = ['ts', 'js'] as const;\r\n if (!type) {\r\n for (const t of types) {\r\n pathWithExt = `${id}.${t}`;\r\n const exists = await this._vfs.exists(pathWithExt);\r\n if (exists) {\r\n const stats = await this._vfs.stat(pathWithExt);\r\n if (stats.isFile) {\r\n type = t;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n if (type) {\r\n const code = (await this._vfs.readFile(pathWithExt, { encoding: 'utf8' })) as string;\r\n return { code, type, path: pathWithExt };\r\n }\r\n }\r\n\r\n /**\r\n * Resolves a module entry to a URL suitable for dynamic import.\r\n *\r\n * Behavior:\r\n * - In editor mode, builds the module to a data URL.\r\n * - Otherwise, returns `.js` URL directly:\r\n * - If `id` ends with `.js`: return as-is.\r\n * - If `id` ends with `.ts`: map to `.js` (assumes pre-built file exists).\r\n * - Else: append `.js`.\r\n *\r\n * @param entryId - Entry module identifier (logical or path-like).\r\n * @returns A URL string that can be used in `import(...)`.\r\n */\r\n async resolveRuntimeUrl(entryId: string) {\r\n const id = await this.resolveLogicalId(entryId);\r\n return getApp().editorMode !== 'none'\r\n ? await this.build(String(id))\r\n : id.endsWith('.js')\r\n ? id\r\n : id.endsWith('.ts')\r\n ? `${id.slice(0, -3)}.js`\r\n : `${id}.js`;\r\n }\r\n\r\n /**\r\n * Recursively gathers direct static and dynamic import dependencies for a module.\r\n *\r\n * Only relative specifiers (`./` or `../`) are followed. Absolute, special, and bare\r\n * module specifiers are ignored here.\r\n *\r\n * @param entryId - The starting (possibly relative) specifier from `fromId`.\r\n * @param fromId - The logical id of the module containing `entryId`.\r\n * @param dependencies - Output map of `resolvedSourcePath -\\> file contents`.\r\n */\r\n async getDependencies(entryId: string, fromId: string, dependencies: Record<string, string>) {\r\n const reStatic = /\\b(?:import|export)\\s+[^\"']*?from\\s+(['\"])([^'\"]+)\\1/g;\r\n const reDynamic = /\\bimport\\s*\\(\\s*(['\"])([^'\"]+)\\1\\s*\\)/g;\r\n\r\n const normalizedId = await this.resolveLogicalId(entryId, fromId);\r\n const srcPath = await this.resolveSourcePath(normalizedId);\r\n if (!srcPath || dependencies[srcPath.path] !== undefined) {\r\n return;\r\n }\r\n const code = (await this._vfs.readFile(srcPath.path, { encoding: 'utf8' })) as string;\r\n dependencies[srcPath.path] = code;\r\n\r\n const gather = async (input: string, re: RegExp) => {\r\n for (;;) {\r\n const m = re.exec(input);\r\n if (!m) {\r\n break;\r\n }\r\n\r\n const spec = m[2];\r\n\r\n if (spec.startsWith('./') || spec.startsWith('../')) {\r\n await this.getDependencies(spec, normalizedId, dependencies);\r\n }\r\n }\r\n };\r\n\r\n await gather(code, reStatic);\r\n await gather(code, reDynamic);\r\n }\r\n\r\n /**\r\n * Builds a logical module id into a data URL (editor mode pipeline).\r\n *\r\n * Steps:\r\n * - Resolve source path (.ts/.js) via {@link ScriptRegistry.resolveSourcePath}.\r\n * - Read source code.\r\n * - Rewrite import specifiers via {@link ScriptRegistry.rewriteImports}.\r\n * - Transpile TypeScript if needed via {@link ScriptRegistry.transpile}.\r\n * - Convert to `data:` URL and memoize in `_built`.\r\n *\r\n * @param id - Logical module id to build.\r\n * @returns Data URL string for dynamic import, or empty string if not found.\r\n */\r\n private async build(id: string) {\r\n const key = String(id);\r\n const cached = this._built.get(key);\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const srcPath = await this.resolveSourcePath(key);\r\n if (!srcPath) {\r\n return '';\r\n }\r\n const code = (await this._vfs.readFile(srcPath.path, { encoding: 'utf8' })) as string;\r\n\r\n const rewritten = await this.rewriteImports(code, key);\r\n const js = await this.transpile(rewritten, key, srcPath.type);\r\n const url = toDataUrl(js, key);\r\n this._built.set(key, url);\r\n return url;\r\n }\r\n\r\n /**\r\n * Transpiles code to JavaScript and appends sourceURL/sourceMap hints.\r\n *\r\n * Behavior:\r\n * - For `'js'`, returns code with `//# sourceURL=logicalId`.\r\n * - For `'ts'`, requires `window.ts` (TypeScript compiler) to be present and\r\n * transpiles to ES2015/ESNext module with inline source maps.\r\n *\r\n * @param code - Source code to transpile.\r\n * @param _id - Logical module id (used for fileName/sourceURL).\r\n * @param type - Source type (`'js' | 'ts'`).\r\n * @returns Transpiled JavaScript source.\r\n * @throws If TypeScript runtime is not found for TS input.\r\n */\r\n private async transpile(code: string, _id: string, type: 'js' | 'ts') {\r\n const logicalId = String(_id);\r\n\r\n if (type === 'js') {\r\n return `${code}\\n//# sourceURL=${logicalId}`;\r\n }\r\n\r\n const ts = (window as any).ts as typeof TS;\r\n if (!ts) {\r\n throw new Error('TypeScript runtime (window.ts) not found. Load typescript.js first.');\r\n }\r\n\r\n const res = ts.transpileModule(code, {\r\n compilerOptions: {\r\n target: ts.ScriptTarget.ES2015,\r\n module: ts.ModuleKind.ESNext,\r\n sourceMap: true,\r\n inlineSources: true,\r\n experimentalDecorators: true,\r\n useDefineForClassFields: false\r\n },\r\n fileName: logicalId\r\n });\r\n\r\n let out = res.outputText || '';\r\n if (res.sourceMapText) {\r\n const mapBase64 = btoa(unescape(encodeURIComponent(res.sourceMapText)));\r\n out += `\\n//# sourceMappingURL=data:application/json;base64,${mapBase64}`;\r\n }\r\n out += `\\n//# sourceURL=${logicalId}`;\r\n return out;\r\n }\r\n\r\n /**\r\n * Rewrites ESM import specifiers in `code` into runtime-loadable URLs.\r\n *\r\n * Parsing:\r\n * - Uses `es-module-lexer` to find import spans; sorts them ascending by start.\r\n *\r\n * Replacement rules:\r\n * - Skip invalid spans or ones without quoted specifiers.\r\n * - If spec is absolute URL, special URL (data:, blob:), or bare module:\r\n * - If it starts with `@zephyr3d/`, keep as-is (external).\r\n * - Otherwise resolve to a logical id and attempt to `build` it (if available).\r\n * - Else (relative spec), resolve from `fromId` and `build` recursively.\r\n *\r\n * Output:\r\n * - Directly writes the replacement specifier without re-adding quotes,\r\n * so replacements must themselves be quoted or be valid URLs/data URLs.\r\n *\r\n * @param code - Module source code to transform.\r\n * @param fromId - The logical id of the current module (resolution base for relatives).\r\n * @returns Transformed source with rewritten import specifiers.\r\n */\r\n private async rewriteImports(code: string, fromId: string) {\r\n await init;\r\n const [imports] = parse(code);\r\n const list = [...imports].sort((a, b) => (a.s || 0) - (b.s || 0));\r\n let out = '';\r\n let last = 0;\r\n\r\n for (const im of list) {\r\n // must have quotes\r\n const hasQuote = im.ss != null && im.se != null;\r\n if (!hasQuote || im.se <= im.ss) {\r\n continue;\r\n }\r\n // must have contents\r\n if (im.e <= im.s) {\r\n continue;\r\n }\r\n // append [last, s)\r\n out += code.slice(last, im.s);\r\n\r\n const spec = code.slice(im.s, im.e); // original spec\r\n let replacement = spec;\r\n if (isAbsoluteUrl(spec) || isSpecialUrl(spec) || isBareModule(spec)) {\r\n if (spec.startsWith('@zephyr3d/')) {\r\n replacement = spec;\r\n } else {\r\n const depId = await this.resolveLogicalId(spec);\r\n replacement = await this.build(depId); // try build as dependence\r\n }\r\n } else {\r\n const depId = await this.resolveLogicalId(spec, String(fromId));\r\n replacement = await this.build(depId); // recursively build as dataURL\r\n }\r\n out += replacement; // 不加引号\r\n last = im.e;\r\n }\r\n out += code.slice(last);\r\n return out;\r\n }\r\n\r\n /**\r\n * Resolves a specifier to a logical id suitable for further processing.\r\n *\r\n * Resolution rules:\r\n * - `#/path`: resolved against `scriptsRoot` via VFS join/normalize.\r\n * - `./` or `../`: resolved relative to `fromId` directory (requires `fromId`).\r\n * - `/absolute`: treated as absolute from root (normalized).\r\n * - Bare module in editor mode: if `/deps.lock.json` exists and contains an entry,\r\n * map to the dependency's `entry` path; otherwise return as-is.\r\n * - Else (non-editor bare module): return `spec` unchanged (external).\r\n *\r\n * @param spec - Import specifier string.\r\n * @param fromId - Optional base logical id used for relative resolution.\r\n * @returns A normalized logical id or an external specifier string.\r\n * @throws If a relative import is provided without `fromId`.\r\n */\r\n async resolveLogicalId(spec: string, fromId?: string) {\r\n if (spec.startsWith('#/')) {\r\n return this._vfs.normalizePath(this._vfs.join(this._scriptsRoot, spec.slice(2)));\r\n } else if (spec.startsWith('./') || spec.startsWith('../')) {\r\n if (!fromId) {\r\n throw new Error(`Relative import \"${spec}\" requires fromId`);\r\n }\r\n return this._vfs.normalizePath(\r\n this._vfs.join(this._vfs.dirname(this._vfs.normalizePath(fromId)), spec)\r\n );\r\n } else if (spec.startsWith('/')) {\r\n return spec.replace(/^\\/+/, '/');\r\n } else if (getApp().editorMode !== 'none') {\r\n // naked module, checking if it is a installed module in editor mode\r\n const depsExists = await this._vfs.exists('/libs/deps.lock.json');\r\n if (depsExists) {\r\n const content = (await this._vfs.readFile('/libs/deps.lock.json', { encoding: 'utf8' })) as string;\r\n const depsInfo = JSON.parse(content) as { dependencies: Record<string, { entry: string }> };\r\n if (depsInfo?.dependencies[spec]) {\r\n return this._vfs.normalizePath(depsInfo.dependencies[spec].entry);\r\n }\r\n }\r\n }\r\n return spec;\r\n }\r\n\r\n /**\r\n * Resolves a logical id to a concrete source path and type by probing extensions.\r\n *\r\n * Rules:\r\n * - If `logicalId` ends with `.ts` or `.js`/`.mjs` and is a file, return it.\r\n * - Else probe `logicalId.ts`, `logicalId.js`, `logicalId.mjs` in that order.\r\n * - Maps `.mjs` to type `'js'`.\r\n *\r\n * @param logicalId - The normalized logical module id (path-like).\r\n * @returns `{ type, path }` or `null` if not found.\r\n */\r\n async resolveSourcePath(logicalId: string) {\r\n let type: Nullable<'js' | 'ts'> = null;\r\n let pathWithExt = '';\r\n if (logicalId.endsWith('.ts')) {\r\n pathWithExt = logicalId;\r\n type = 'ts';\r\n } else if (logicalId.endsWith('.js') || logicalId.endsWith('.mjs')) {\r\n pathWithExt = logicalId;\r\n type = 'js';\r\n }\r\n if (type) {\r\n const exists = await this._vfs.exists(pathWithExt);\r\n if (!exists) {\r\n type = null;\r\n }\r\n const stat = await this._vfs.stat(pathWithExt);\r\n if (stat.isDirectory) {\r\n type = null;\r\n }\r\n }\r\n const types = ['ts', 'js', 'mjs'] as const;\r\n if (!type) {\r\n for (const t of types) {\r\n pathWithExt = `${logicalId}.${t}`;\r\n const exists = await this._vfs.exists(pathWithExt);\r\n if (exists) {\r\n const stats = await this._vfs.stat(pathWithExt);\r\n if (stats.isFile) {\r\n type = t === 'ts' ? 'ts' : 'js';\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n return type ? { type, path: pathWithExt } : null;\r\n }\r\n}\r\n"],"names":["toDataUrl","js","id","b64","textToBase64","encodeURIComponent","String","isAbsoluteUrl","spec","test","isSpecialUrl","isBareModule","startsWith","ScriptRegistry","_vfs","_scriptsRoot","_built","vfs","scriptsRoot","Map","VFS","clear","path","fetchSource","type","pathWithExt","endsWith","exists","stat","isDirectory","types","t","stats","isFile","code","readFile","encoding","resolveRuntimeUrl","entryId","resolveLogicalId","getApp","editorMode","build","slice","getDependencies","fromId","dependencies","reStatic","reDynamic","normalizedId","srcPath","resolveSourcePath","undefined","gather","input","re","m","exec","key","cached","get","rewritten","rewriteImports","transpile","url","set","_id","logicalId","ts","window","Error","res","transpileModule","compilerOptions","target","ScriptTarget","ES2015","module","ModuleKind","ESNext","sourceMap","inlineSources","experimentalDecorators","useDefineForClassFields","fileName","out","outputText","sourceMapText","mapBase64","btoa","unescape","init","imports","parse","list","sort","a","b","s","last","im","hasQuote","ss","se","e","replacement","depId","normalizePath","join","dirname","replace","depsExists","content","depsInfo","JSON","entry"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { DWeakRef, ASSERT, base64ToUint8Array, Vector3, DRef, Vector4, isPowerOf2, nextPowerOf2, VFSError } from '@zephyr3d/base';
1
+ import { DWeakRef, ASSERT, base64ToUint8Array, Vector3, DRef, Vector4, VFSError, isPowerOf2, nextPowerOf2 } from '@zephyr3d/base';
2
2
  import { GLTFLoader } from './loaders/gltf/gltf_loader.js';
3
3
  import { WebImageLoader } from './loaders/image/webimage_loader.js';
4
4
  import { DDSLoader } from './loaders/dds/dds_loader.js';
@@ -18,11 +18,13 @@ import '../material/particle.js';
18
18
  import { Material } from '../material/material.js';
19
19
  import '../material/meshmaterial.js';
20
20
  import '../material/grassmaterial.js';
21
- import '../material/terrainmaterial.js';
22
21
  import '../material/terrain-cm.js';
23
22
  import '../material/pbrmr.js';
24
23
  import '../material/pbrsg.js';
25
24
  import { PBRBluePrintMaterial } from '../material/pbrblueprint.js';
25
+ import '../material/sprite.js';
26
+ import '../material/sprite_std.js';
27
+ import { SpriteBlueprintMaterial } from '../material/spriteblueprint.js';
26
28
  import { BoundingBox } from '../utility/bounding_volume.js';
27
29
  import { MaterialBlueprintIR } from '../utility/blueprint/material/ir.js';
28
30
  import '../render/renderer.js';
@@ -76,6 +78,7 @@ import '../shaders/atmosphere.js';
76
78
  this._models = {};
77
79
  this._materials = {};
78
80
  this._primitives = {};
81
+ this._skeletons = {};
79
82
  this._bluePrints = {};
80
83
  this._binaryDatas = {};
81
84
  this._textDatas = {};
@@ -467,27 +470,35 @@ import '../shaders/atmosphere.js';
467
470
  const m = materials[i];
468
471
  if (m instanceof PBRBluePrintMaterial && (!filter || filter(m))) {
469
472
  const data = await this.loadBluePrintMaterialData(paths[i], true);
470
- m.fragmentIR = data.irFragment;
471
- m.vertexIR = data.irVertex;
472
- m.uniformValues = data.uniformValues;
473
- m.uniformTextures = data.uniformTextures;
473
+ if (data) {
474
+ m.fragmentIR = data.irFragment;
475
+ m.vertexIR = data.irVertex;
476
+ m.uniformValues = data.uniformValues;
477
+ m.uniformTextures = data.uniformTextures;
478
+ }
474
479
  }
475
480
  }
476
481
  }
477
482
  async loadBluePrintMaterialData(url, reload, VFSs) {
478
483
  try {
479
- const data = await this.readFileFromVFSs(url, {
480
- encoding: 'utf8'
481
- }, VFSs);
482
- const content = JSON.parse(data);
483
- ASSERT(content.type === 'PBRBluePrintMaterial', `Unsupported material type: ${content.type}`);
484
- const ir = reload ? await this.loadBluePrint(content.data.IR, VFSs) : await this.fetchBluePrint(content.data.IR, VFSs);
485
- const uniformValues = content.data.uniformValues.map((v)=>({
484
+ let irData;
485
+ if (typeof url === 'string') {
486
+ const data = await this.readFileFromVFSs(url, {
487
+ encoding: 'utf8'
488
+ }, VFSs);
489
+ const content = JSON.parse(data);
490
+ ASSERT(content.type === 'PBRBluePrintMaterial' || content.type === 'SpriteBluePrintMaterial', `Unsupported material type: ${content.type}`);
491
+ irData = content.data;
492
+ } else {
493
+ irData = url;
494
+ }
495
+ const ir = reload ? await this.loadBluePrint(irData.IR, VFSs) : await this.fetchBluePrint(irData.IR, VFSs);
496
+ const uniformValues = irData.uniformValues.map((v)=>({
486
497
  ...v,
487
498
  finalValue: v.value.length === 1 ? v.value[0] : new Float32Array(v.value)
488
499
  }));
489
500
  const uniformTextures = [];
490
- const textures = content.data.uniformTextures;
501
+ const textures = irData.uniformTextures;
491
502
  for (const v of textures){
492
503
  const tex = await this.fetchTexture(v.texture, {
493
504
  linearColorSpace: !v.sRGB
@@ -506,8 +517,8 @@ import '../shaders/atmosphere.js';
506
517
  });
507
518
  }
508
519
  return {
509
- irFragment: ir['fragment'],
510
- irVertex: ir['vertex'],
520
+ irFragment: ir?.['fragment'] ?? null,
521
+ irVertex: ir?.['vertex'] ?? null,
511
522
  uniformValues,
512
523
  uniformTextures
513
524
  };
@@ -530,10 +541,14 @@ import '../shaders/atmosphere.js';
530
541
  encoding: 'utf8'
531
542
  }, VFSs);
532
543
  const content = JSON.parse(data);
533
- ASSERT(content.type === 'PBRBluePrintMaterial' || content.type === 'Default', `Unsupported material type: ${content.type}`);
544
+ ASSERT(content.type === 'PBRBluePrintMaterial' || content.type === 'SpriteBluePrintMaterial' || content.type === 'Default', `Unsupported material type: ${content.type}`);
545
+ let mat;
534
546
  if (content.type === 'PBRBluePrintMaterial') {
535
- const data = await this.loadBluePrintMaterialData(url, reload, VFSs);
536
- return new PBRBluePrintMaterial(data.irFragment, data.irVertex, data.uniformValues, data.uniformTextures);
547
+ const data = await this.loadBluePrintMaterialData(content.data, reload, VFSs);
548
+ mat = new PBRBluePrintMaterial(data.irFragment, data.irVertex, data.uniformValues, data.uniformTextures);
549
+ } else if (content.type === 'SpriteBluePrintMaterial') {
550
+ const data = await this.loadBluePrintMaterialData(content.data, reload, VFSs);
551
+ mat = new SpriteBlueprintMaterial(data.irFragment, data.uniformValues, data.uniformTextures);
537
552
  } else {
538
553
  const obj = await this._resourceManager.deserializeObject(null, content.data);
539
554
  if (!(obj instanceof Material)) {
@@ -544,6 +559,10 @@ import '../shaders/atmosphere.js';
544
559
  }
545
560
  return obj;
546
561
  }
562
+ if (mat && content.props) {
563
+ await this._resourceManager.deserializeObjectProps(mat, content.props);
564
+ }
565
+ return mat;
547
566
  } catch (err) {
548
567
  console.error(`Load material failed: ${err}`);
549
568
  return null;
@@ -668,13 +687,16 @@ import '../shaders/atmosphere.js';
668
687
  order: this.getReverseTopologicalOrderFromRoots(gs, nodeMap, roots).order.reverse()
669
688
  };
670
689
  }
690
+ invalidateBluePrint(path) {
691
+ delete this._bluePrints[path];
692
+ }
671
693
  async loadBluePrint(path, VFSs) {
672
694
  try {
673
695
  const content = await this.readFileFromVFSs(path, {
674
696
  encoding: 'utf8'
675
697
  }, VFSs);
676
698
  const bp = JSON.parse(content);
677
- ASSERT(bp.type === 'PBRMaterial' || bp.type === 'MaterialFunction', `Unsupported blueprint type: ${bp.type}`);
699
+ ASSERT(bp.type === 'PBRMaterial' || bp.type === 'SpriteMaterial' || bp.type === 'MaterialFunction', `Unsupported blueprint type: ${bp.type}`);
678
700
  const states = bp.state;
679
701
  const result = {};
680
702
  for (const k of Object.keys(states)){
@@ -689,7 +711,7 @@ import '../shaders/atmosphere.js';
689
711
  }
690
712
  }
691
713
  const dag = await this.createBluePrintDAG(nodeMap, roots, state.links);
692
- result[k] = new MaterialBlueprintIR(dag, path);
714
+ result[k] = new MaterialBlueprintIR(dag, path, state);
693
715
  }
694
716
  return result;
695
717
  } catch (err) {
@@ -745,7 +767,9 @@ import '../shaders/atmosphere.js';
745
767
  continue;
746
768
  }
747
769
  const tex = await this.doLoadTexture(loader, mimeType, data, !!srgb, samplerOptions, texture);
748
- tex.name = this.vfs.basename(url);
770
+ if (tex) {
771
+ tex.name = this.vfs.basename(url);
772
+ }
749
773
  return tex;
750
774
  }
751
775
  throw new Error(`Can not find loader for asset ${url}`);
@@ -768,28 +792,9 @@ import '../shaders/atmosphere.js';
768
792
  return await loader.load(mimeType, data, srgb, samplerOptions, texture);
769
793
  } else {
770
794
  let tex = await loader.load(mimeType, data, srgb, samplerOptions);
771
- if (texture) {
772
- const magFilter = tex.width !== texture.width || tex.height !== texture.height ? 'linear' : 'nearest';
773
- const minFilter = magFilter;
774
- const mipFilter = 'none';
775
- const sampler = device.createSampler({
776
- addressU: 'clamp',
777
- addressV: 'clamp',
778
- magFilter,
779
- minFilter,
780
- mipFilter
781
- });
782
- const blitter = new CopyBlitter();
783
- blitter.blit(tex, texture, sampler);
784
- tex = texture;
785
- } else {
786
- const po2_w = isPowerOf2(tex.width);
787
- const po2_h = isPowerOf2(tex.height);
788
- const srgb = tex.isSRGBFormat();
789
- if (srgb || !po2_w || !po2_h) {
790
- const newWidth = po2_w ? tex.width : nextPowerOf2(tex.width);
791
- const newHeight = po2_h ? tex.height : nextPowerOf2(tex.height);
792
- const magFilter = newWidth !== tex.width || newHeight !== tex.height ? 'linear' : 'nearest';
795
+ if (tex) {
796
+ if (texture) {
797
+ const magFilter = tex.width !== texture.width || tex.height !== texture.height ? 'linear' : 'nearest';
793
798
  const minFilter = magFilter;
794
799
  const mipFilter = 'none';
795
800
  const sampler = device.createSampler({
@@ -799,12 +804,33 @@ import '../shaders/atmosphere.js';
799
804
  minFilter,
800
805
  mipFilter
801
806
  });
802
- const destFormat = srgb ? 'rgba8unorm' : tex.format;
803
807
  const blitter = new CopyBlitter();
804
- const newTexture = tex.isTexture2D() ? device.createTexture2D(destFormat, newWidth, newHeight) : device.createCubeTexture(destFormat, newWidth);
805
- blitter.blit(tex, newTexture, sampler);
806
- tex.dispose();
807
- tex = newTexture;
808
+ blitter.blit(tex, texture, sampler);
809
+ tex = texture;
810
+ } else {
811
+ const po2_w = isPowerOf2(tex.width);
812
+ const po2_h = isPowerOf2(tex.height);
813
+ const srgb = tex.isSRGBFormat();
814
+ if (srgb || !po2_w || !po2_h) {
815
+ const newWidth = po2_w ? tex.width : nextPowerOf2(tex.width);
816
+ const newHeight = po2_h ? tex.height : nextPowerOf2(tex.height);
817
+ const magFilter = newWidth !== tex.width || newHeight !== tex.height ? 'linear' : 'nearest';
818
+ const minFilter = magFilter;
819
+ const mipFilter = 'none';
820
+ const sampler = device.createSampler({
821
+ addressU: 'clamp',
822
+ addressV: 'clamp',
823
+ magFilter,
824
+ minFilter,
825
+ mipFilter
826
+ });
827
+ const destFormat = srgb ? 'rgba8unorm' : tex.format;
828
+ const blitter = new CopyBlitter();
829
+ const newTexture = tex.isTexture2D() ? device.createTexture2D(destFormat, newWidth, newHeight) : device.createCubeTexture(destFormat, newWidth);
830
+ blitter.blit(tex, newTexture, sampler);
831
+ tex.dispose();
832
+ tex = newTexture;
833
+ }
808
834
  }
809
835
  }
810
836
  return tex;
@@ -894,7 +920,7 @@ import '../shaders/atmosphere.js';
894
920
  if (loader) {
895
921
  this._builtinTextureLoaders[name] = loader;
896
922
  } else {
897
- this._builtinTextureLoaders[name] = undefined;
923
+ delete this._builtinTextureLoaders[name];
898
924
  }
899
925
  }
900
926
  /**
@@ -925,14 +951,9 @@ import '../shaders/atmosphere.js';
925
951
  this.vfs
926
952
  ];
927
953
  for (const vfs of vfsList){
928
- if (!await vfs.exists(path)) {
929
- continue;
930
- }
931
- const stat = await vfs.stat(path);
932
- if (!stat || !stat.isFile) {
933
- continue;
934
- }
935
- return await vfs.readFile(path, options);
954
+ try {
955
+ return await vfs.readFile(path, options);
956
+ } catch {}
936
957
  }
937
958
  throw new VFSError(`File does not exist: ${path}`, 'ENOENT', path);
938
959
  }