@zephyr3d/scene 0.9.0 → 0.9.2
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.
- package/dist/animation/animationset.js +135 -133
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/cloth/gpu_cloth_system.js +9 -1
- package/dist/animation/cloth/gpu_cloth_system.js.map +1 -1
- package/dist/animation/fixed_geometry_cache_track.js +5 -1
- package/dist/animation/fixed_geometry_cache_track.js.map +1 -1
- package/dist/animation/geometry_cache_utils.js +20 -4
- package/dist/animation/geometry_cache_utils.js.map +1 -1
- package/dist/animation/ik/ik_angle_constraint.js +2 -6
- package/dist/animation/ik/ik_angle_constraint.js.map +1 -1
- package/dist/animation/ik/two_bone_ik_solver.js +2 -6
- package/dist/animation/ik/two_bone_ik_solver.js.map +1 -1
- package/dist/animation/joint_dynamics/collision.js +60 -12
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/constraints.js +20 -4
- package/dist/animation/joint_dynamics/constraints.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +151 -103
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +21 -11
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js +15 -3
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/animation/pca_geometry_cache_track.js +5 -1
- package/dist/animation/pca_geometry_cache_track.js.map +1 -1
- package/dist/animation/skeleton.js +2 -2
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skeleton_modifier.js +2 -6
- package/dist/animation/skeleton_modifier.js.map +1 -1
- package/dist/animation/spring/spring_system.js +87 -114
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/app/app.js.map +1 -1
- package/dist/app/engine.js +1 -1
- package/dist/app/engine.js.map +1 -1
- package/dist/app/screen.js +4 -4
- package/dist/app/screen.js.map +1 -1
- package/dist/app/scriptingsystem.js +24 -1
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +165 -144
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +2 -2
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/model.js +3 -3
- package/dist/asset/model.js.map +1 -1
- package/dist/camera/camera.js +185 -185
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/orbit.js.map +1 -1
- package/dist/index.d.ts +794 -261
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/material/material.js +290 -288
- package/dist/material/material.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +13 -26
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/pbrmr.js +1 -11
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/sprite.js +6 -6
- package/dist/material/sprite.js.map +1 -1
- package/dist/material/terrain-cm.js +2 -2
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/posteffect/taa.js +31 -39
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/render/drawable.js +5 -1
- package/dist/render/drawable.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js +29 -3
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/executor.js +283 -33
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +338 -108
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/history_resource_manager.js +236 -156
- package/dist/render/rendergraph/history_resource_manager.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +10 -0
- package/dist/render/rendergraph/history_resources.js.map +1 -0
- package/dist/render/rendergraph/rendergraph.js +162 -35
- package/dist/render/rendergraph/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/types.js +36 -16
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/rendertarget.js +5 -1
- package/dist/render/rendertarget.js.map +1 -1
- package/dist/render/screenrendertarget.js +5 -1
- package/dist/render/screenrendertarget.js.map +1 -1
- package/dist/render/sky.js +4 -4
- package/dist/render/sky.js.map +1 -1
- package/dist/scene/basesprite.js +2 -2
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/graph_node.js +1 -1
- package/dist/scene/graph_node.js.map +1 -1
- package/dist/scene/mesh.js +4 -20
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/particlesys.js +1 -1
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene_node.js +2 -2
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/script_attachment.js +15 -3
- package/dist/scene/script_attachment.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +3 -3
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shapes/box.js +1 -1
- package/dist/shapes/box.js.map +1 -1
- package/dist/shapes/capsule.js +0 -3
- package/dist/shapes/capsule.js.map +1 -1
- package/dist/shapes/cylinder.js +0 -3
- package/dist/shapes/cylinder.js.map +1 -1
- package/dist/shapes/plane.js +0 -3
- package/dist/shapes/plane.js.map +1 -1
- package/dist/shapes/tetrahedron.js +3 -9
- package/dist/shapes/tetrahedron.js.map +1 -1
- package/dist/shapes/torus.js +4 -7
- package/dist/shapes/torus.js.map +1 -1
- package/dist/utility/blueprint/material/inputs.js +3 -3
- package/dist/utility/blueprint/material/inputs.js.map +1 -1
- package/dist/utility/blueprint/material/ir.js +493 -493
- package/dist/utility/blueprint/material/ir.js.map +1 -1
- package/dist/utility/serialization/manager.js +34 -3
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +45 -0
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +53 -0
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/common.js +10 -0
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +30 -0
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +63 -0
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +11 -0
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/misc.js +2 -0
- package/dist/utility/serialization/scene/misc.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +19 -0
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +22 -0
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +33 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +39 -0
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/script.js +2 -0
- package/dist/utility/serialization/scene/script.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +6 -0
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +9 -0
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +21 -0
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js +5 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/package.json +2 -2
|
@@ -2,69 +2,69 @@ import { textToBase64 } from '@zephyr3d/base';
|
|
|
2
2
|
import { init, parse } from '../node_modules/es-module-lexer/dist/lexer.js';
|
|
3
3
|
import { getApp } from './api.js';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Converts JavaScript source to a data URL tied to a logical module id.
|
|
7
|
-
*
|
|
8
|
-
* @param js - The JavaScript source code to embed.
|
|
9
|
-
* @param id - Logical module identifier (used only for sourceURL tagging).
|
|
10
|
-
* @returns A `data:text/javascript;base64,...` URL with an encoded `#id` suffix.
|
|
11
|
-
* @internal
|
|
5
|
+
/**
|
|
6
|
+
* Converts JavaScript source to a data URL tied to a logical module id.
|
|
7
|
+
*
|
|
8
|
+
* @param js - The JavaScript source code to embed.
|
|
9
|
+
* @param id - Logical module identifier (used only for sourceURL tagging).
|
|
10
|
+
* @returns A `data:text/javascript;base64,...` URL with an encoded `#id` suffix.
|
|
11
|
+
* @internal
|
|
12
12
|
*/ function toDataUrl(js, id) {
|
|
13
13
|
const b64 = textToBase64(js);
|
|
14
14
|
return `data:text/javascript;base64,${b64}#${encodeURIComponent(String(id))}`;
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Checks whether a specifier is an absolute HTTP(S) URL.
|
|
18
|
-
* @internal
|
|
16
|
+
/**
|
|
17
|
+
* Checks whether a specifier is an absolute HTTP(S) URL.
|
|
18
|
+
* @internal
|
|
19
19
|
*/ function isAbsoluteUrl(spec) {
|
|
20
20
|
return /^https?:\/\//i.test(spec);
|
|
21
21
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Checks whether a specifier is a special URL (data: or blob:).
|
|
24
|
-
* @internal
|
|
22
|
+
/**
|
|
23
|
+
* Checks whether a specifier is a special URL (data: or blob:).
|
|
24
|
+
* @internal
|
|
25
25
|
*/ function isSpecialUrl(spec) {
|
|
26
26
|
return /^(data|blob):/i.test(spec);
|
|
27
27
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Checks whether a specifier is a bare module (not starting with ./, ../, /, or #/).
|
|
30
|
-
* @internal
|
|
28
|
+
/**
|
|
29
|
+
* Checks whether a specifier is a bare module (not starting with ./, ../, /, or #/).
|
|
30
|
+
* @internal
|
|
31
31
|
*/ function isBareModule(spec) {
|
|
32
32
|
return !spec.startsWith('./') && !spec.startsWith('../') && !spec.startsWith('/') && !spec.startsWith('#/');
|
|
33
33
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Resolves, builds, and serves runtime modules using a VFS.
|
|
36
|
-
*
|
|
37
|
-
* Responsibilities:
|
|
38
|
-
* - Resolve logical module IDs to physical paths or URLs.
|
|
39
|
-
* - In editor mode, rewrite import specifiers and serve modules as data URLs after transpile.
|
|
40
|
-
* - Transpile TypeScript to JavaScript on the fly (requires `window.ts` TypeScript runtime).
|
|
41
|
-
* - Gather static and dynamic import dependencies for tooling.
|
|
42
|
-
*
|
|
43
|
-
* Modes:
|
|
44
|
-
* - Editor mode (`editorMode === true`): modules are rewritten to data URLs after transpile/build.
|
|
45
|
-
* - Runtime mode (`editorMode === false`): returns .js URLs directly (with .ts -\> .js mapping).
|
|
46
|
-
*
|
|
47
|
-
* Caching:
|
|
48
|
-
* - Built modules are memoized in `_built` map keyed by logical ID.
|
|
49
|
-
*
|
|
50
|
-
* @public
|
|
34
|
+
/**
|
|
35
|
+
* Resolves, builds, and serves runtime modules using a VFS.
|
|
36
|
+
*
|
|
37
|
+
* Responsibilities:
|
|
38
|
+
* - Resolve logical module IDs to physical paths or URLs.
|
|
39
|
+
* - In editor mode, rewrite import specifiers and serve modules as data URLs after transpile.
|
|
40
|
+
* - Transpile TypeScript to JavaScript on the fly (requires `window.ts` TypeScript runtime).
|
|
41
|
+
* - Gather static and dynamic import dependencies for tooling.
|
|
42
|
+
*
|
|
43
|
+
* Modes:
|
|
44
|
+
* - Editor mode (`editorMode === true`): modules are rewritten to data URLs after transpile/build.
|
|
45
|
+
* - Runtime mode (`editorMode === false`): returns .js URLs directly (with .ts -\> .js mapping).
|
|
46
|
+
*
|
|
47
|
+
* Caching:
|
|
48
|
+
* - Built modules are memoized in `_built` map keyed by logical ID.
|
|
49
|
+
*
|
|
50
|
+
* @public
|
|
51
51
|
*/ class ScriptRegistry {
|
|
52
52
|
_vfs;
|
|
53
53
|
_scriptsRoot;
|
|
54
54
|
_built;
|
|
55
|
-
/**
|
|
56
|
-
* @param vfs - The virtual file system for existence checks, reads, and path ops.
|
|
57
|
-
* @param scriptsRoot - Root directory for script resolution (used with `#/` specifiers).
|
|
58
|
-
* @param editorMode - Whether to build modules to data URLs and rewrite imports.
|
|
55
|
+
/**
|
|
56
|
+
* @param vfs - The virtual file system for existence checks, reads, and path ops.
|
|
57
|
+
* @param scriptsRoot - Root directory for script resolution (used with `#/` specifiers).
|
|
58
|
+
* @param editorMode - Whether to build modules to data URLs and rewrite imports.
|
|
59
59
|
*/ constructor(vfs, scriptsRoot){
|
|
60
60
|
this._vfs = vfs;
|
|
61
61
|
this._scriptsRoot = scriptsRoot;
|
|
62
62
|
this._built = new Map();
|
|
63
63
|
}
|
|
64
|
-
/**
|
|
65
|
-
* The active virtual file system.
|
|
66
|
-
*
|
|
67
|
-
* Assigning a new VFS clears the build cache.
|
|
64
|
+
/**
|
|
65
|
+
* The active virtual file system.
|
|
66
|
+
*
|
|
67
|
+
* Assigning a new VFS clears the build cache.
|
|
68
68
|
*/ get VFS() {
|
|
69
69
|
return this._vfs;
|
|
70
70
|
}
|
|
@@ -74,23 +74,44 @@ import { getApp } from './api.js';
|
|
|
74
74
|
this._built.clear();
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
-
/**
|
|
78
|
-
* The root path used by `#/` specifiers.
|
|
77
|
+
/**
|
|
78
|
+
* The root path used by `#/` specifiers.
|
|
79
79
|
*/ get scriptsRoot() {
|
|
80
80
|
return this._scriptsRoot;
|
|
81
81
|
}
|
|
82
82
|
set scriptsRoot(path) {
|
|
83
83
|
this._scriptsRoot = path;
|
|
84
84
|
}
|
|
85
|
-
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
|
|
93
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Invalidates cached built module output for one logical module id, or clears the full cache.
|
|
87
|
+
*
|
|
88
|
+
* Pass the same logical id shape that callers use with {@link ScriptRegistry.resolveRuntimeUrl},
|
|
89
|
+
* for example `/assets/scripts/foo.ts`, `/assets/scripts/foo.js`, or `/assets/scripts/foo`.
|
|
90
|
+
*
|
|
91
|
+
* @param moduleId - Optional logical module id to invalidate. Omit to clear the entire build cache.
|
|
92
|
+
*/ invalidate(moduleId) {
|
|
93
|
+
if (!moduleId) {
|
|
94
|
+
this._built.clear();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const normalized = String(moduleId);
|
|
98
|
+
this._built.delete(normalized);
|
|
99
|
+
if (normalized.endsWith('.ts') || normalized.endsWith('.js')) {
|
|
100
|
+
this._built.delete(normalized.slice(0, -3));
|
|
101
|
+
} else {
|
|
102
|
+
this._built.delete(`${normalized}.ts`);
|
|
103
|
+
this._built.delete(`${normalized}.js`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Fetches raw source for a logical module id by probing known extensions.
|
|
108
|
+
*
|
|
109
|
+
* Search order:
|
|
110
|
+
* - If `id` already ends with `.ts` or `.js` and is a file -\> return it.
|
|
111
|
+
* - Else try `.id.ts`, then `.id.js`.
|
|
112
|
+
*
|
|
113
|
+
* @param id - Logical module identifier (absolute or logical path-like).
|
|
114
|
+
* @returns Source code, resolved path, and type (`'js' | 'ts'`), or `undefined` if not found.
|
|
94
115
|
*/ async fetchSource(id) {
|
|
95
116
|
let type = null;
|
|
96
117
|
let pathWithExt = '';
|
|
@@ -139,18 +160,18 @@ import { getApp } from './api.js';
|
|
|
139
160
|
};
|
|
140
161
|
}
|
|
141
162
|
}
|
|
142
|
-
/**
|
|
143
|
-
* Resolves a module entry to a URL suitable for dynamic import.
|
|
144
|
-
*
|
|
145
|
-
* Behavior:
|
|
146
|
-
* - In editor mode, builds the module to a data URL.
|
|
147
|
-
* - Otherwise, returns `.js` URL directly:
|
|
148
|
-
* - If `id` ends with `.js`: return as-is.
|
|
149
|
-
* - If `id` ends with `.ts`: map to `.js` (assumes pre-built file exists).
|
|
150
|
-
* - Else: append `.js`.
|
|
151
|
-
*
|
|
152
|
-
* @param entryId - Entry module identifier (logical or path-like).
|
|
153
|
-
* @returns A URL string that can be used in `import(...)`.
|
|
163
|
+
/**
|
|
164
|
+
* Resolves a module entry to a URL suitable for dynamic import.
|
|
165
|
+
*
|
|
166
|
+
* Behavior:
|
|
167
|
+
* - In editor mode, builds the module to a data URL.
|
|
168
|
+
* - Otherwise, returns `.js` URL directly:
|
|
169
|
+
* - If `id` ends with `.js`: return as-is.
|
|
170
|
+
* - If `id` ends with `.ts`: map to `.js` (assumes pre-built file exists).
|
|
171
|
+
* - Else: append `.js`.
|
|
172
|
+
*
|
|
173
|
+
* @param entryId - Entry module identifier (logical or path-like).
|
|
174
|
+
* @returns A URL string that can be used in `import(...)`.
|
|
154
175
|
*/ async resolveRuntimeUrl(entryId) {
|
|
155
176
|
const id = await this.resolveLogicalId(entryId);
|
|
156
177
|
if (id.startsWith('/assets/@builtins/')) {
|
|
@@ -158,15 +179,15 @@ import { getApp } from './api.js';
|
|
|
158
179
|
}
|
|
159
180
|
return getApp().editorMode !== 'none' ? await this.build(String(id)) : id.endsWith('.js') ? id : id.endsWith('.ts') ? `${id.slice(0, -3)}.js` : `${id}.js`;
|
|
160
181
|
}
|
|
161
|
-
/**
|
|
162
|
-
* Recursively gathers direct static and dynamic import dependencies for a module.
|
|
163
|
-
*
|
|
164
|
-
* Only relative specifiers (`./` or `../`) are followed. Absolute, special, and bare
|
|
165
|
-
* module specifiers are ignored here.
|
|
166
|
-
*
|
|
167
|
-
* @param entryId - The starting (possibly relative) specifier from `fromId`.
|
|
168
|
-
* @param fromId - The logical id of the module containing `entryId`.
|
|
169
|
-
* @param dependencies - Output map of `resolvedSourcePath -\> file contents`.
|
|
182
|
+
/**
|
|
183
|
+
* Recursively gathers direct static and dynamic import dependencies for a module.
|
|
184
|
+
*
|
|
185
|
+
* Only relative specifiers (`./` or `../`) are followed. Absolute, special, and bare
|
|
186
|
+
* module specifiers are ignored here.
|
|
187
|
+
*
|
|
188
|
+
* @param entryId - The starting (possibly relative) specifier from `fromId`.
|
|
189
|
+
* @param fromId - The logical id of the module containing `entryId`.
|
|
190
|
+
* @param dependencies - Output map of `resolvedSourcePath -\> file contents`.
|
|
170
191
|
*/ async getDependencies(entryId, fromId, dependencies) {
|
|
171
192
|
const reStatic = /\b(?:import|export)\s+[^"']*?from\s+(['"])([^'"]+)\1/g;
|
|
172
193
|
const reDynamic = /\bimport\s*\(\s*(['"])([^'"]+)\1\s*\)/g;
|
|
@@ -194,18 +215,18 @@ import { getApp } from './api.js';
|
|
|
194
215
|
await gather(code, reStatic);
|
|
195
216
|
await gather(code, reDynamic);
|
|
196
217
|
}
|
|
197
|
-
/**
|
|
198
|
-
* Builds a logical module id into a data URL (editor mode pipeline).
|
|
199
|
-
*
|
|
200
|
-
* Steps:
|
|
201
|
-
* - Resolve source path (.ts/.js) via {@link ScriptRegistry.resolveSourcePath}.
|
|
202
|
-
* - Read source code.
|
|
203
|
-
* - Rewrite import specifiers via {@link ScriptRegistry.rewriteImports}.
|
|
204
|
-
* - Transpile TypeScript if needed via {@link ScriptRegistry.transpile}.
|
|
205
|
-
* - Convert to `data:` URL and memoize in `_built`.
|
|
206
|
-
*
|
|
207
|
-
* @param id - Logical module id to build.
|
|
208
|
-
* @returns Data URL string for dynamic import, or empty string if not found.
|
|
218
|
+
/**
|
|
219
|
+
* Builds a logical module id into a data URL (editor mode pipeline).
|
|
220
|
+
*
|
|
221
|
+
* Steps:
|
|
222
|
+
* - Resolve source path (.ts/.js) via {@link ScriptRegistry.resolveSourcePath}.
|
|
223
|
+
* - Read source code.
|
|
224
|
+
* - Rewrite import specifiers via {@link ScriptRegistry.rewriteImports}.
|
|
225
|
+
* - Transpile TypeScript if needed via {@link ScriptRegistry.transpile}.
|
|
226
|
+
* - Convert to `data:` URL and memoize in `_built`.
|
|
227
|
+
*
|
|
228
|
+
* @param id - Logical module id to build.
|
|
229
|
+
* @returns Data URL string for dynamic import, or empty string if not found.
|
|
209
230
|
*/ async build(id) {
|
|
210
231
|
const key = String(id);
|
|
211
232
|
const cached = this._built.get(key);
|
|
@@ -225,19 +246,19 @@ import { getApp } from './api.js';
|
|
|
225
246
|
this._built.set(key, url);
|
|
226
247
|
return url;
|
|
227
248
|
}
|
|
228
|
-
/**
|
|
229
|
-
* Transpiles code to JavaScript and appends sourceURL/sourceMap hints.
|
|
230
|
-
*
|
|
231
|
-
* Behavior:
|
|
232
|
-
* - For `'js'`, returns code with `//# sourceURL=logicalId`.
|
|
233
|
-
* - For `'ts'`, requires `window.ts` (TypeScript compiler) to be present and
|
|
234
|
-
* transpiles to ES2015/ESNext module with inline source maps.
|
|
235
|
-
*
|
|
236
|
-
* @param code - Source code to transpile.
|
|
237
|
-
* @param _id - Logical module id (used for fileName/sourceURL).
|
|
238
|
-
* @param type - Source type (`'js' | 'ts'`).
|
|
239
|
-
* @returns Transpiled JavaScript source.
|
|
240
|
-
* @throws If TypeScript runtime is not found for TS input.
|
|
249
|
+
/**
|
|
250
|
+
* Transpiles code to JavaScript and appends sourceURL/sourceMap hints.
|
|
251
|
+
*
|
|
252
|
+
* Behavior:
|
|
253
|
+
* - For `'js'`, returns code with `//# sourceURL=logicalId`.
|
|
254
|
+
* - For `'ts'`, requires `window.ts` (TypeScript compiler) to be present and
|
|
255
|
+
* transpiles to ES2015/ESNext module with inline source maps.
|
|
256
|
+
*
|
|
257
|
+
* @param code - Source code to transpile.
|
|
258
|
+
* @param _id - Logical module id (used for fileName/sourceURL).
|
|
259
|
+
* @param type - Source type (`'js' | 'ts'`).
|
|
260
|
+
* @returns Transpiled JavaScript source.
|
|
261
|
+
* @throws If TypeScript runtime is not found for TS input.
|
|
241
262
|
*/ async transpile(code, _id, type) {
|
|
242
263
|
const logicalId = String(_id);
|
|
243
264
|
if (type === 'js') {
|
|
@@ -266,26 +287,26 @@ import { getApp } from './api.js';
|
|
|
266
287
|
out += `\n//# sourceURL=${logicalId}`;
|
|
267
288
|
return out;
|
|
268
289
|
}
|
|
269
|
-
/**
|
|
270
|
-
* Rewrites ESM import specifiers in `code` into runtime-loadable URLs.
|
|
271
|
-
*
|
|
272
|
-
* Parsing:
|
|
273
|
-
* - Uses `es-module-lexer` to find import spans; sorts them ascending by start.
|
|
274
|
-
*
|
|
275
|
-
* Replacement rules:
|
|
276
|
-
* - Skip invalid spans or ones without quoted specifiers.
|
|
277
|
-
* - If spec is absolute URL, special URL (data:, blob:), or bare module:
|
|
278
|
-
* - If it starts with `@zephyr3d/`, keep as-is (external).
|
|
279
|
-
* - Otherwise resolve to a logical id and attempt to `build` it (if available).
|
|
280
|
-
* - Else (relative spec), resolve from `fromId` and `build` recursively.
|
|
281
|
-
*
|
|
282
|
-
* Output:
|
|
283
|
-
* - Directly writes the replacement specifier without re-adding quotes,
|
|
284
|
-
* so replacements must themselves be quoted or be valid URLs/data URLs.
|
|
285
|
-
*
|
|
286
|
-
* @param code - Module source code to transform.
|
|
287
|
-
* @param fromId - The logical id of the current module (resolution base for relatives).
|
|
288
|
-
* @returns Transformed source with rewritten import specifiers.
|
|
290
|
+
/**
|
|
291
|
+
* Rewrites ESM import specifiers in `code` into runtime-loadable URLs.
|
|
292
|
+
*
|
|
293
|
+
* Parsing:
|
|
294
|
+
* - Uses `es-module-lexer` to find import spans; sorts them ascending by start.
|
|
295
|
+
*
|
|
296
|
+
* Replacement rules:
|
|
297
|
+
* - Skip invalid spans or ones without quoted specifiers.
|
|
298
|
+
* - If spec is absolute URL, special URL (data:, blob:), or bare module:
|
|
299
|
+
* - If it starts with `@zephyr3d/`, keep as-is (external).
|
|
300
|
+
* - Otherwise resolve to a logical id and attempt to `build` it (if available).
|
|
301
|
+
* - Else (relative spec), resolve from `fromId` and `build` recursively.
|
|
302
|
+
*
|
|
303
|
+
* Output:
|
|
304
|
+
* - Directly writes the replacement specifier without re-adding quotes,
|
|
305
|
+
* so replacements must themselves be quoted or be valid URLs/data URLs.
|
|
306
|
+
*
|
|
307
|
+
* @param code - Module source code to transform.
|
|
308
|
+
* @param fromId - The logical id of the current module (resolution base for relatives).
|
|
309
|
+
* @returns Transformed source with rewritten import specifiers.
|
|
289
310
|
*/ async rewriteImports(code, fromId) {
|
|
290
311
|
await init;
|
|
291
312
|
const [imports] = parse(code);
|
|
@@ -325,27 +346,27 @@ import { getApp } from './api.js';
|
|
|
325
346
|
const depId = await this.resolveLogicalId(spec, String(fromId));
|
|
326
347
|
replacement = await this.build(depId); // recursively build as dataURL
|
|
327
348
|
}
|
|
328
|
-
out += replacement; //
|
|
349
|
+
out += replacement; // Do not wrap in quotes
|
|
329
350
|
last = im.e;
|
|
330
351
|
}
|
|
331
352
|
out += code.slice(last);
|
|
332
353
|
return out;
|
|
333
354
|
}
|
|
334
|
-
/**
|
|
335
|
-
* Resolves a specifier to a logical id suitable for further processing.
|
|
336
|
-
*
|
|
337
|
-
* Resolution rules:
|
|
338
|
-
* - `#/path`: resolved against `scriptsRoot` via VFS join/normalize.
|
|
339
|
-
* - `./` or `../`: resolved relative to `fromId` directory (requires `fromId`).
|
|
340
|
-
* - `/absolute`: treated as absolute from root (normalized).
|
|
341
|
-
* - Bare module in editor mode: if `/deps.lock.json` exists and contains an entry,
|
|
342
|
-
* map to the dependency's `entry` path; otherwise return as-is.
|
|
343
|
-
* - Else (non-editor bare module): return `spec` unchanged (external).
|
|
344
|
-
*
|
|
345
|
-
* @param spec - Import specifier string.
|
|
346
|
-
* @param fromId - Optional base logical id used for relative resolution.
|
|
347
|
-
* @returns A normalized logical id or an external specifier string.
|
|
348
|
-
* @throws If a relative import is provided without `fromId`.
|
|
355
|
+
/**
|
|
356
|
+
* Resolves a specifier to a logical id suitable for further processing.
|
|
357
|
+
*
|
|
358
|
+
* Resolution rules:
|
|
359
|
+
* - `#/path`: resolved against `scriptsRoot` via VFS join/normalize.
|
|
360
|
+
* - `./` or `../`: resolved relative to `fromId` directory (requires `fromId`).
|
|
361
|
+
* - `/absolute`: treated as absolute from root (normalized).
|
|
362
|
+
* - Bare module in editor mode: if `/deps.lock.json` exists and contains an entry,
|
|
363
|
+
* map to the dependency's `entry` path; otherwise return as-is.
|
|
364
|
+
* - Else (non-editor bare module): return `spec` unchanged (external).
|
|
365
|
+
*
|
|
366
|
+
* @param spec - Import specifier string.
|
|
367
|
+
* @param fromId - Optional base logical id used for relative resolution.
|
|
368
|
+
* @returns A normalized logical id or an external specifier string.
|
|
369
|
+
* @throws If a relative import is provided without `fromId`.
|
|
349
370
|
*/ async resolveLogicalId(spec, fromId) {
|
|
350
371
|
if (spec.startsWith('#/')) {
|
|
351
372
|
return this._vfs.normalizePath(this._vfs.join(this._scriptsRoot, spec.slice(2)));
|
|
@@ -373,16 +394,16 @@ import { getApp } from './api.js';
|
|
|
373
394
|
}
|
|
374
395
|
return spec;
|
|
375
396
|
}
|
|
376
|
-
/**
|
|
377
|
-
* Resolves a logical id to a concrete source path and type by probing extensions.
|
|
378
|
-
*
|
|
379
|
-
* Rules:
|
|
380
|
-
* - If `logicalId` ends with `.ts` or `.js`/`.mjs` and is a file, return it.
|
|
381
|
-
* - Else probe `logicalId.ts`, `logicalId.js`, `logicalId.mjs` in that order.
|
|
382
|
-
* - Maps `.mjs` to type `'js'`.
|
|
383
|
-
*
|
|
384
|
-
* @param logicalId - The normalized logical module id (path-like).
|
|
385
|
-
* @returns `{ type, path }` or `null` if not found.
|
|
397
|
+
/**
|
|
398
|
+
* Resolves a logical id to a concrete source path and type by probing extensions.
|
|
399
|
+
*
|
|
400
|
+
* Rules:
|
|
401
|
+
* - If `logicalId` ends with `.ts` or `.js`/`.mjs` and is a file, return it.
|
|
402
|
+
* - Else probe `logicalId.ts`, `logicalId.js`, `logicalId.mjs` in that order.
|
|
403
|
+
* - Maps `.mjs` to type `'js'`.
|
|
404
|
+
*
|
|
405
|
+
* @param logicalId - The normalized logical module id (path-like).
|
|
406
|
+
* @returns `{ type, path }` or `null` if not found.
|
|
386
407
|
*/ async resolveSourcePath(logicalId) {
|
|
387
408
|
let type = null;
|
|
388
409
|
let pathWithExt = '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scriptregistry.js","sources":["../../src/app/scriptregistry.ts"],"sourcesContent":["import type * as TS from 'typescript';\nimport type { Nullable, VFS } from '@zephyr3d/base';\nimport { textToBase64 } from '@zephyr3d/base';\nimport { init, parse } from 'es-module-lexer';\nimport { getApp } from './api';\n\n/**\n * Converts JavaScript source to a data URL tied to a logical module id.\n *\n * @param js - The JavaScript source code to embed.\n * @param id - Logical module identifier (used only for sourceURL tagging).\n * @returns A `data:text/javascript;base64,...` URL with an encoded `#id` suffix.\n * @internal\n */\nfunction toDataUrl(js: string, id: string) {\n const b64 = textToBase64(js);\n return `data:text/javascript;base64,${b64}#${encodeURIComponent(String(id))}`;\n}\n\n/**\n * Checks whether a specifier is an absolute HTTP(S) URL.\n * @internal\n */\nfunction isAbsoluteUrl(spec: string) {\n return /^https?:\\/\\//i.test(spec);\n}\n\n/**\n * Checks whether a specifier is a special URL (data: or blob:).\n * @internal\n */\nfunction isSpecialUrl(spec: string) {\n return /^(data|blob):/i.test(spec);\n}\n\n/**\n * Checks whether a specifier is a bare module (not starting with ./, ../, /, or #/).\n * @internal\n */\nfunction isBareModule(spec: string) {\n return !spec.startsWith('./') && !spec.startsWith('../') && !spec.startsWith('/') && !spec.startsWith('#/');\n}\n\n/**\n * Resolves, builds, and serves runtime modules using a VFS.\n *\n * Responsibilities:\n * - Resolve logical module IDs to physical paths or URLs.\n * - In editor mode, rewrite import specifiers and serve modules as data URLs after transpile.\n * - Transpile TypeScript to JavaScript on the fly (requires `window.ts` TypeScript runtime).\n * - Gather static and dynamic import dependencies for tooling.\n *\n * Modes:\n * - Editor mode (`editorMode === true`): modules are rewritten to data URLs after transpile/build.\n * - Runtime mode (`editorMode === false`): returns .js URLs directly (with .ts -\\> .js mapping).\n *\n * Caching:\n * - Built modules are memoized in `_built` map keyed by logical ID.\n *\n * @public\n */\nexport class ScriptRegistry {\n private _vfs: VFS;\n private _scriptsRoot: string;\n private _built: Map<string, string>; // logicalId -> dataURL\n\n /**\n * @param vfs - The virtual file system for existence checks, reads, and path ops.\n * @param scriptsRoot - Root directory for script resolution (used with `#/` specifiers).\n * @param editorMode - Whether to build modules to data URLs and rewrite imports.\n */\n constructor(vfs: VFS, scriptsRoot: string) {\n this._vfs = vfs;\n this._scriptsRoot = scriptsRoot;\n this._built = new Map();\n }\n\n /**\n * The active virtual file system.\n *\n * Assigning a new VFS clears the build cache.\n */\n get VFS() {\n return this._vfs;\n }\n set VFS(vfs: VFS) {\n if (vfs !== this._vfs) {\n this._vfs = vfs;\n this._built.clear();\n }\n }\n\n /**\n * The root path used by `#/` specifiers.\n */\n get scriptsRoot() {\n return this._scriptsRoot;\n }\n set scriptsRoot(path: string) {\n this._scriptsRoot = path;\n }\n\n /**\n * Fetches raw source for a logical module id by probing known extensions.\n *\n * Search order:\n * - If `id` already ends with `.ts` or `.js` and is a file -\\> return it.\n * - Else try `.id.ts`, then `.id.js`.\n *\n * @param id - Logical module identifier (absolute or logical path-like).\n * @returns Source code, resolved path, and type (`'js' | 'ts'`), or `undefined` if not found.\n */\n protected async fetchSource(id: string) {\n let type: Nullable<'js' | 'ts'> = null;\n let pathWithExt = '';\n if (id.endsWith('.ts')) {\n pathWithExt = id;\n type = 'ts';\n } else if (id.endsWith('.js')) {\n pathWithExt = id;\n type = 'js';\n }\n if (type) {\n const exists = await this._vfs.exists(pathWithExt);\n if (!exists) {\n type = null;\n }\n const stat = await this._vfs.stat(pathWithExt);\n if (stat.isDirectory) {\n type = null;\n }\n }\n const types = ['ts', 'js'] as const;\n if (!type) {\n for (const t of types) {\n pathWithExt = `${id}.${t}`;\n const exists = await this._vfs.exists(pathWithExt);\n if (exists) {\n const stats = await this._vfs.stat(pathWithExt);\n if (stats.isFile) {\n type = t;\n break;\n }\n }\n }\n }\n if (type) {\n const code = (await this._vfs.readFile(pathWithExt, { encoding: 'utf8' })) as string;\n return { code, type, path: pathWithExt };\n }\n }\n\n /**\n * Resolves a module entry to a URL suitable for dynamic import.\n *\n * Behavior:\n * - In editor mode, builds the module to a data URL.\n * - Otherwise, returns `.js` URL directly:\n * - If `id` ends with `.js`: return as-is.\n * - If `id` ends with `.ts`: map to `.js` (assumes pre-built file exists).\n * - Else: append `.js`.\n *\n * @param entryId - Entry module identifier (logical or path-like).\n * @returns A URL string that can be used in `import(...)`.\n */\n async resolveRuntimeUrl(entryId: string) {\n const id = await this.resolveLogicalId(entryId);\n if (id.startsWith('/assets/@builtins/')) {\n return await this.build(String(id));\n }\n return getApp().editorMode !== 'none'\n ? await this.build(String(id))\n : id.endsWith('.js')\n ? id\n : id.endsWith('.ts')\n ? `${id.slice(0, -3)}.js`\n : `${id}.js`;\n }\n\n /**\n * Recursively gathers direct static and dynamic import dependencies for a module.\n *\n * Only relative specifiers (`./` or `../`) are followed. Absolute, special, and bare\n * module specifiers are ignored here.\n *\n * @param entryId - The starting (possibly relative) specifier from `fromId`.\n * @param fromId - The logical id of the module containing `entryId`.\n * @param dependencies - Output map of `resolvedSourcePath -\\> file contents`.\n */\n async getDependencies(entryId: string, fromId: string, dependencies: Record<string, string>) {\n const reStatic = /\\b(?:import|export)\\s+[^\"']*?from\\s+(['\"])([^'\"]+)\\1/g;\n const reDynamic = /\\bimport\\s*\\(\\s*(['\"])([^'\"]+)\\1\\s*\\)/g;\n\n const normalizedId = await this.resolveLogicalId(entryId, fromId);\n const srcPath = await this.resolveSourcePath(normalizedId);\n if (!srcPath || dependencies[srcPath.path] !== undefined) {\n return;\n }\n const code = (await this._vfs.readFile(srcPath.path, { encoding: 'utf8' })) as string;\n dependencies[srcPath.path] = code;\n\n const gather = async (input: string, re: RegExp) => {\n for (;;) {\n const m = re.exec(input);\n if (!m) {\n break;\n }\n\n const spec = m[2];\n\n if (spec.startsWith('./') || spec.startsWith('../')) {\n await this.getDependencies(spec, normalizedId, dependencies);\n }\n }\n };\n\n await gather(code, reStatic);\n await gather(code, reDynamic);\n }\n\n /**\n * Builds a logical module id into a data URL (editor mode pipeline).\n *\n * Steps:\n * - Resolve source path (.ts/.js) via {@link ScriptRegistry.resolveSourcePath}.\n * - Read source code.\n * - Rewrite import specifiers via {@link ScriptRegistry.rewriteImports}.\n * - Transpile TypeScript if needed via {@link ScriptRegistry.transpile}.\n * - Convert to `data:` URL and memoize in `_built`.\n *\n * @param id - Logical module id to build.\n * @returns Data URL string for dynamic import, or empty string if not found.\n */\n private async build(id: string) {\n const key = String(id);\n const cached = this._built.get(key);\n if (cached) {\n return cached;\n }\n\n const srcPath = await this.resolveSourcePath(key);\n if (!srcPath) {\n return '';\n }\n const code = (await this._vfs.readFile(srcPath.path, { encoding: 'utf8' })) as string;\n\n const rewritten = await this.rewriteImports(code, key);\n const js = await this.transpile(rewritten, key, srcPath.type);\n const url = toDataUrl(js, key);\n this._built.set(key, url);\n return url;\n }\n\n /**\n * Transpiles code to JavaScript and appends sourceURL/sourceMap hints.\n *\n * Behavior:\n * - For `'js'`, returns code with `//# sourceURL=logicalId`.\n * - For `'ts'`, requires `window.ts` (TypeScript compiler) to be present and\n * transpiles to ES2015/ESNext module with inline source maps.\n *\n * @param code - Source code to transpile.\n * @param _id - Logical module id (used for fileName/sourceURL).\n * @param type - Source type (`'js' | 'ts'`).\n * @returns Transpiled JavaScript source.\n * @throws If TypeScript runtime is not found for TS input.\n */\n private async transpile(code: string, _id: string, type: 'js' | 'ts') {\n const logicalId = String(_id);\n\n if (type === 'js') {\n return `${code}\\n//# sourceURL=${logicalId}`;\n }\n\n const ts = (window as any).ts as typeof TS;\n if (!ts) {\n throw new Error('TypeScript runtime (window.ts) not found. Load typescript.js first.');\n }\n\n const res = ts.transpileModule(code, {\n compilerOptions: {\n target: ts.ScriptTarget.ES2015,\n module: ts.ModuleKind.ESNext,\n sourceMap: true,\n inlineSources: true,\n experimentalDecorators: true,\n useDefineForClassFields: false\n },\n fileName: logicalId\n });\n\n let out = res.outputText || '';\n if (res.sourceMapText) {\n const mapBase64 = btoa(unescape(encodeURIComponent(res.sourceMapText)));\n out += `\\n//# sourceMappingURL=data:application/json;base64,${mapBase64}`;\n }\n out += `\\n//# sourceURL=${logicalId}`;\n return out;\n }\n\n /**\n * Rewrites ESM import specifiers in `code` into runtime-loadable URLs.\n *\n * Parsing:\n * - Uses `es-module-lexer` to find import spans; sorts them ascending by start.\n *\n * Replacement rules:\n * - Skip invalid spans or ones without quoted specifiers.\n * - If spec is absolute URL, special URL (data:, blob:), or bare module:\n * - If it starts with `@zephyr3d/`, keep as-is (external).\n * - Otherwise resolve to a logical id and attempt to `build` it (if available).\n * - Else (relative spec), resolve from `fromId` and `build` recursively.\n *\n * Output:\n * - Directly writes the replacement specifier without re-adding quotes,\n * so replacements must themselves be quoted or be valid URLs/data URLs.\n *\n * @param code - Module source code to transform.\n * @param fromId - The logical id of the current module (resolution base for relatives).\n * @returns Transformed source with rewritten import specifiers.\n */\n private async rewriteImports(code: string, fromId: string) {\n await init;\n const [imports] = parse(code);\n const list = [...imports].sort((a, b) => (a.s || 0) - (b.s || 0));\n let out = '';\n let last = 0;\n\n for (const im of list) {\n // Skip import.meta entries reported by es-module-lexer.\n // Their \"specifier\" span points to the whole \"import.meta\" expression,\n // which must remain untouched.\n if (im.d === -2) {\n continue;\n }\n // must have quotes\n const hasQuote = im.ss != null && im.se != null;\n if (!hasQuote || im.se <= im.ss) {\n continue;\n }\n // must have contents\n if (im.e <= im.s) {\n continue;\n }\n // append [last, s)\n out += code.slice(last, im.s);\n\n const spec = code.slice(im.s, im.e); // original spec\n let replacement = spec;\n if (isAbsoluteUrl(spec) || isSpecialUrl(spec) || isBareModule(spec)) {\n if (spec.startsWith('@zephyr3d/')) {\n replacement = spec;\n } else {\n const depId = await this.resolveLogicalId(spec);\n replacement = await this.build(depId); // try build as dependence\n }\n } else {\n const depId = await this.resolveLogicalId(spec, String(fromId));\n replacement = await this.build(depId); // recursively build as dataURL\n }\n out += replacement; // 不加引号\n last = im.e;\n }\n out += code.slice(last);\n return out;\n }\n\n /**\n * Resolves a specifier to a logical id suitable for further processing.\n *\n * Resolution rules:\n * - `#/path`: resolved against `scriptsRoot` via VFS join/normalize.\n * - `./` or `../`: resolved relative to `fromId` directory (requires `fromId`).\n * - `/absolute`: treated as absolute from root (normalized).\n * - Bare module in editor mode: if `/deps.lock.json` exists and contains an entry,\n * map to the dependency's `entry` path; otherwise return as-is.\n * - Else (non-editor bare module): return `spec` unchanged (external).\n *\n * @param spec - Import specifier string.\n * @param fromId - Optional base logical id used for relative resolution.\n * @returns A normalized logical id or an external specifier string.\n * @throws If a relative import is provided without `fromId`.\n */\n async resolveLogicalId(spec: string, fromId?: string) {\n if (spec.startsWith('#/')) {\n return this._vfs.normalizePath(this._vfs.join(this._scriptsRoot, spec.slice(2)));\n } else if (spec.startsWith('./') || spec.startsWith('../')) {\n if (!fromId) {\n throw new Error(`Relative import \"${spec}\" requires fromId`);\n }\n return this._vfs.normalizePath(\n this._vfs.join(this._vfs.dirname(this._vfs.normalizePath(fromId)), spec)\n );\n } else if (spec.startsWith('/')) {\n return spec.replace(/^\\/+/, '/');\n } else if (getApp().editorMode !== 'none') {\n const libRoot = '/';\n // naked module, checking if it is a installed module in editor mode\n let depsLockPath = this._vfs.normalizePath(this._vfs.join(libRoot, 'libs/deps.lock.json'));\n let depsExists = await this._vfs.exists(depsLockPath);\n if (depsExists) {\n const content = (await this._vfs.readFile(depsLockPath, { encoding: 'utf8' })) as string;\n const depsInfo = JSON.parse(content) as { dependencies: Record<string, { entry: string }> };\n if (depsInfo?.dependencies[spec]) {\n return this._vfs.normalizePath(this._vfs.join(libRoot, depsInfo.dependencies[spec].entry));\n }\n }\n }\n return spec;\n }\n\n /**\n * Resolves a logical id to a concrete source path and type by probing extensions.\n *\n * Rules:\n * - If `logicalId` ends with `.ts` or `.js`/`.mjs` and is a file, return it.\n * - Else probe `logicalId.ts`, `logicalId.js`, `logicalId.mjs` in that order.\n * - Maps `.mjs` to type `'js'`.\n *\n * @param logicalId - The normalized logical module id (path-like).\n * @returns `{ type, path }` or `null` if not found.\n */\n async resolveSourcePath(logicalId: string) {\n let type: Nullable<'js' | 'ts'> = null;\n let pathWithExt = '';\n if (logicalId.endsWith('.ts')) {\n pathWithExt = logicalId;\n type = 'ts';\n } else if (logicalId.endsWith('.js') || logicalId.endsWith('.mjs')) {\n pathWithExt = logicalId;\n type = 'js';\n }\n if (type) {\n const exists = await this._vfs.exists(pathWithExt);\n if (!exists) {\n type = null;\n }\n const stat = await this._vfs.stat(pathWithExt);\n if (stat.isDirectory) {\n type = null;\n }\n }\n const types = ['ts', 'js', 'mjs'] as const;\n if (!type) {\n for (const t of types) {\n pathWithExt = `${logicalId}.${t}`;\n const exists = await this._vfs.exists(pathWithExt);\n if (exists) {\n const stats = await this._vfs.stat(pathWithExt);\n if (stats.isFile) {\n type = t === 'ts' ? 'ts' : 'js';\n break;\n }\n }\n }\n }\n return type ? { type, path: pathWithExt } : null;\n }\n}\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","build","getApp","editorMode","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","d","hasQuote","ss","se","e","replacement","depId","normalizePath","join","dirname","replace","libRoot","depsLockPath","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 * Invalidates cached built module output for one logical module id, or clears the full cache.\r\n *\r\n * Pass the same logical id shape that callers use with {@link ScriptRegistry.resolveRuntimeUrl},\r\n * for example `/assets/scripts/foo.ts`, `/assets/scripts/foo.js`, or `/assets/scripts/foo`.\r\n *\r\n * @param moduleId - Optional logical module id to invalidate. Omit to clear the entire build cache.\r\n */\r\n invalidate(moduleId?: string) {\r\n if (!moduleId) {\r\n this._built.clear();\r\n return;\r\n }\r\n const normalized = String(moduleId);\r\n this._built.delete(normalized);\r\n if (normalized.endsWith('.ts') || normalized.endsWith('.js')) {\r\n this._built.delete(normalized.slice(0, -3));\r\n } else {\r\n this._built.delete(`${normalized}.ts`);\r\n this._built.delete(`${normalized}.js`);\r\n }\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 if (id.startsWith('/assets/@builtins/')) {\r\n return await this.build(String(id));\r\n }\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 // Skip import.meta entries reported by es-module-lexer.\r\n // Their \"specifier\" span points to the whole \"import.meta\" expression,\r\n // which must remain untouched.\r\n if (im.d === -2) {\r\n continue;\r\n }\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; // Do not wrap in quotes\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 const libRoot = '/';\r\n // naked module, checking if it is a installed module in editor mode\r\n let depsLockPath = this._vfs.normalizePath(this._vfs.join(libRoot, 'libs/deps.lock.json'));\r\n let depsExists = await this._vfs.exists(depsLockPath);\r\n if (depsExists) {\r\n const content = (await this._vfs.readFile(depsLockPath, { 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(this._vfs.join(libRoot, 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","invalidate","moduleId","normalized","delete","endsWith","slice","fetchSource","type","pathWithExt","exists","stat","isDirectory","types","t","stats","isFile","code","readFile","encoding","resolveRuntimeUrl","entryId","resolveLogicalId","build","getApp","editorMode","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","d","hasQuote","ss","se","e","replacement","depId","normalizePath","join","dirname","replace","libRoot","depsLockPath","depsExists","content","depsInfo","JSON","entry"],"mappings":";;;;AAMA;;;;;;;AAOC,IACD,SAASA,SAAAA,CAAUC,EAAU,EAAEC,EAAU,EAAA;AACvC,IAAA,MAAMC,MAAMC,YAAaH,CAAAA,EAAAA,CAAAA;IACzB,OAAO,CAAC,4BAA4B,EAAEE,GAAAA,CAAI,CAAC,EAAEE,kBAAAA,CAAmBC,OAAOJ,EAAM,CAAA,CAAA,CAAA,CAAA;AAC/E;AAEA;;;IAIA,SAASK,cAAcC,IAAY,EAAA;IACjC,OAAO,eAAA,CAAgBC,IAAI,CAACD,IAAAA,CAAAA;AAC9B;AAEA;;;IAIA,SAASE,aAAaF,IAAY,EAAA;IAChC,OAAO,gBAAA,CAAiBC,IAAI,CAACD,IAAAA,CAAAA;AAC/B;AAEA;;;IAIA,SAASG,aAAaH,IAAY,EAAA;AAChC,IAAA,OAAO,CAACA,IAAKI,CAAAA,UAAU,CAAC,IAAS,CAAA,IAAA,CAACJ,KAAKI,UAAU,CAAC,KAAU,CAAA,IAAA,CAACJ,KAAKI,UAAU,CAAC,QAAQ,CAACJ,IAAAA,CAAKI,UAAU,CAAC,IAAA,CAAA;AACxG;AAEA;;;;;;;;;;;;;;;;;AAiBC,IACM,MAAMC,cAAAA,CAAAA;IACHC,IAAU;IACVC,YAAqB;IACrBC,MAA4B;AAEpC;;;;AAIC,MACD,WAAYC,CAAAA,GAAQ,EAAEC,WAAmB,CAAE;QACzC,IAAI,CAACJ,IAAI,GAAGG,GAAAA;QACZ,IAAI,CAACF,YAAY,GAAGG,WAAAA;QACpB,IAAI,CAACF,MAAM,GAAG,IAAIG,GAAAA,EAAAA;AACpB;AAEA;;;;AAIC,MACD,IAAIC,GAAM,GAAA;QACR,OAAO,IAAI,CAACN,IAAI;AAClB;IACA,IAAIM,GAAAA,CAAIH,GAAQ,EAAE;AAChB,QAAA,IAAIA,GAAQ,KAAA,IAAI,CAACH,IAAI,EAAE;YACrB,IAAI,CAACA,IAAI,GAAGG,GAAAA;YACZ,IAAI,CAACD,MAAM,CAACK,KAAK,EAAA;AACnB;AACF;AAEA;;AAEC,MACD,IAAIH,WAAc,GAAA;QAChB,OAAO,IAAI,CAACH,YAAY;AAC1B;IACA,IAAIG,WAAAA,CAAYI,IAAY,EAAE;QAC5B,IAAI,CAACP,YAAY,GAAGO,IAAAA;AACtB;AAEA;;;;;;;MAQAC,UAAAA,CAAWC,QAAiB,EAAE;AAC5B,QAAA,IAAI,CAACA,QAAU,EAAA;YACb,IAAI,CAACR,MAAM,CAACK,KAAK,EAAA;AACjB,YAAA;AACF;AACA,QAAA,MAAMI,aAAanB,MAAOkB,CAAAA,QAAAA,CAAAA;AAC1B,QAAA,IAAI,CAACR,MAAM,CAACU,MAAM,CAACD,UAAAA,CAAAA;AACnB,QAAA,IAAIA,WAAWE,QAAQ,CAAC,UAAUF,UAAWE,CAAAA,QAAQ,CAAC,KAAQ,CAAA,EAAA;YAC5D,IAAI,CAACX,MAAM,CAACU,MAAM,CAACD,UAAWG,CAAAA,KAAK,CAAC,CAAA,EAAG,EAAC,CAAA,CAAA;SACnC,MAAA;YACL,IAAI,CAACZ,MAAM,CAACU,MAAM,CAAC,CAAGD,EAAAA,UAAAA,CAAW,GAAG,CAAC,CAAA;YACrC,IAAI,CAACT,MAAM,CAACU,MAAM,CAAC,CAAGD,EAAAA,UAAAA,CAAW,GAAG,CAAC,CAAA;AACvC;AACF;AAEA;;;;;;;;;MAUA,MAAgBI,WAAY3B,CAAAA,EAAU,EAAE;AACtC,QAAA,IAAI4B,IAA8B,GAAA,IAAA;AAClC,QAAA,IAAIC,WAAc,GAAA,EAAA;QAClB,IAAI7B,EAAAA,CAAGyB,QAAQ,CAAC,KAAQ,CAAA,EAAA;YACtBI,WAAc7B,GAAAA,EAAAA;YACd4B,IAAO,GAAA,IAAA;AACT,SAAA,MAAO,IAAI5B,EAAAA,CAAGyB,QAAQ,CAAC,KAAQ,CAAA,EAAA;YAC7BI,WAAc7B,GAAAA,EAAAA;YACd4B,IAAO,GAAA,IAAA;AACT;AACA,QAAA,IAAIA,IAAM,EAAA;AACR,YAAA,MAAME,SAAS,MAAM,IAAI,CAAClB,IAAI,CAACkB,MAAM,CAACD,WAAAA,CAAAA;AACtC,YAAA,IAAI,CAACC,MAAQ,EAAA;gBACXF,IAAO,GAAA,IAAA;AACT;AACA,YAAA,MAAMG,OAAO,MAAM,IAAI,CAACnB,IAAI,CAACmB,IAAI,CAACF,WAAAA,CAAAA;YAClC,IAAIE,IAAAA,CAAKC,WAAW,EAAE;gBACpBJ,IAAO,GAAA,IAAA;AACT;AACF;AACA,QAAA,MAAMK,KAAQ,GAAA;AAAC,YAAA,IAAA;AAAM,YAAA;AAAK,SAAA;AAC1B,QAAA,IAAI,CAACL,IAAM,EAAA;YACT,KAAK,MAAMM,KAAKD,KAAO,CAAA;AACrBJ,gBAAAA,WAAAA,GAAc,CAAG7B,EAAAA,EAAAA,CAAG,CAAC,EAAEkC,CAAG,CAAA,CAAA;AAC1B,gBAAA,MAAMJ,SAAS,MAAM,IAAI,CAAClB,IAAI,CAACkB,MAAM,CAACD,WAAAA,CAAAA;AACtC,gBAAA,IAAIC,MAAQ,EAAA;AACV,oBAAA,MAAMK,QAAQ,MAAM,IAAI,CAACvB,IAAI,CAACmB,IAAI,CAACF,WAAAA,CAAAA;oBACnC,IAAIM,KAAAA,CAAMC,MAAM,EAAE;wBAChBR,IAAOM,GAAAA,CAAAA;AACP,wBAAA;AACF;AACF;AACF;AACF;AACA,QAAA,IAAIN,IAAM,EAAA;YACR,MAAMS,IAAAA,GAAQ,MAAM,IAAI,CAACzB,IAAI,CAAC0B,QAAQ,CAACT,WAAa,EAAA;gBAAEU,QAAU,EAAA;AAAO,aAAA,CAAA;YACvE,OAAO;AAAEF,gBAAAA,IAAAA;AAAMT,gBAAAA,IAAAA;gBAAMR,IAAMS,EAAAA;AAAY,aAAA;AACzC;AACF;AAEA;;;;;;;;;;;;MAaA,MAAMW,iBAAkBC,CAAAA,OAAe,EAAE;AACvC,QAAA,MAAMzC,EAAK,GAAA,MAAM,IAAI,CAAC0C,gBAAgB,CAACD,OAAAA,CAAAA;QACvC,IAAIzC,EAAAA,CAAGU,UAAU,CAAC,oBAAuB,CAAA,EAAA;AACvC,YAAA,OAAO,MAAM,IAAI,CAACiC,KAAK,CAACvC,MAAOJ,CAAAA,EAAAA,CAAAA,CAAAA;AACjC;AACA,QAAA,OAAO4C,MAASC,EAAAA,CAAAA,UAAU,KAAK,MAAA,GAC3B,MAAM,IAAI,CAACF,KAAK,CAACvC,MAAOJ,CAAAA,EAAAA,CAAAA,CAAAA,GACxBA,EAAGyB,CAAAA,QAAQ,CAAC,KACVzB,CAAAA,GAAAA,EAAAA,GACAA,EAAGyB,CAAAA,QAAQ,CAAC,KAAA,CAAA,GACV,CAAGzB,EAAAA,EAAAA,CAAG0B,KAAK,CAAC,CAAA,EAAG,EAAC,CAAA,CAAG,GAAG,CAAC,GACvB,CAAG1B,EAAAA,EAAAA,CAAG,GAAG,CAAC;AACpB;AAEA;;;;;;;;;AASC,MACD,MAAM8C,eAAgBL,CAAAA,OAAe,EAAEM,MAAc,EAAEC,YAAoC,EAAE;AAC3F,QAAA,MAAMC,QAAW,GAAA,uDAAA;AACjB,QAAA,MAAMC,SAAY,GAAA,wCAAA;AAElB,QAAA,MAAMC,eAAe,MAAM,IAAI,CAACT,gBAAgB,CAACD,OAASM,EAAAA,MAAAA,CAAAA;AAC1D,QAAA,MAAMK,OAAU,GAAA,MAAM,IAAI,CAACC,iBAAiB,CAACF,YAAAA,CAAAA;QAC7C,IAAI,CAACC,WAAWJ,YAAY,CAACI,QAAQhC,IAAI,CAAC,KAAKkC,SAAW,EAAA;AACxD,YAAA;AACF;QACA,MAAMjB,IAAAA,GAAQ,MAAM,IAAI,CAACzB,IAAI,CAAC0B,QAAQ,CAACc,OAAQhC,CAAAA,IAAI,EAAE;YAAEmB,QAAU,EAAA;AAAO,SAAA,CAAA;AACxES,QAAAA,YAAY,CAACI,OAAAA,CAAQhC,IAAI,CAAC,GAAGiB,IAAAA;QAE7B,MAAMkB,MAAAA,GAAS,OAAOC,KAAeC,EAAAA,EAAAA,GAAAA;YACnC,OAAS;gBACP,MAAMC,CAAAA,GAAID,EAAGE,CAAAA,IAAI,CAACH,KAAAA,CAAAA;AAClB,gBAAA,IAAI,CAACE,CAAG,EAAA;AACN,oBAAA;AACF;gBAEA,MAAMpD,IAAAA,GAAOoD,CAAC,CAAC,CAAE,CAAA;AAEjB,gBAAA,IAAIpD,KAAKI,UAAU,CAAC,SAASJ,IAAKI,CAAAA,UAAU,CAAC,KAAQ,CAAA,EAAA;AACnD,oBAAA,MAAM,IAAI,CAACoC,eAAe,CAACxC,MAAM6C,YAAcH,EAAAA,YAAAA,CAAAA;AACjD;AACF;AACF,SAAA;AAEA,QAAA,MAAMO,OAAOlB,IAAMY,EAAAA,QAAAA,CAAAA;AACnB,QAAA,MAAMM,OAAOlB,IAAMa,EAAAA,SAAAA,CAAAA;AACrB;AAEA;;;;;;;;;;;;MAaA,MAAcP,KAAM3C,CAAAA,EAAU,EAAE;AAC9B,QAAA,MAAM4D,MAAMxD,MAAOJ,CAAAA,EAAAA,CAAAA;AACnB,QAAA,MAAM6D,SAAS,IAAI,CAAC/C,MAAM,CAACgD,GAAG,CAACF,GAAAA,CAAAA;AAC/B,QAAA,IAAIC,MAAQ,EAAA;YACV,OAAOA,MAAAA;AACT;AAEA,QAAA,MAAMT,OAAU,GAAA,MAAM,IAAI,CAACC,iBAAiB,CAACO,GAAAA,CAAAA;AAC7C,QAAA,IAAI,CAACR,OAAS,EAAA;YACZ,OAAO,EAAA;AACT;QACA,MAAMf,IAAAA,GAAQ,MAAM,IAAI,CAACzB,IAAI,CAAC0B,QAAQ,CAACc,OAAQhC,CAAAA,IAAI,EAAE;YAAEmB,QAAU,EAAA;AAAO,SAAA,CAAA;AAExE,QAAA,MAAMwB,YAAY,MAAM,IAAI,CAACC,cAAc,CAAC3B,IAAMuB,EAAAA,GAAAA,CAAAA;QAClD,MAAM7D,EAAAA,GAAK,MAAM,IAAI,CAACkE,SAAS,CAACF,SAAAA,EAAWH,GAAKR,EAAAA,OAAAA,CAAQxB,IAAI,CAAA;QAC5D,MAAMsC,GAAAA,GAAMpE,UAAUC,EAAI6D,EAAAA,GAAAA,CAAAA;AAC1B,QAAA,IAAI,CAAC9C,MAAM,CAACqD,GAAG,CAACP,GAAKM,EAAAA,GAAAA,CAAAA;QACrB,OAAOA,GAAAA;AACT;AAEA;;;;;;;;;;;;;AAaC,MACD,MAAcD,SAAU5B,CAAAA,IAAY,EAAE+B,GAAW,EAAExC,IAAiB,EAAE;AACpE,QAAA,MAAMyC,YAAYjE,MAAOgE,CAAAA,GAAAA,CAAAA;AAEzB,QAAA,IAAIxC,SAAS,IAAM,EAAA;AACjB,YAAA,OAAO,CAAGS,EAAAA,IAAAA,CAAK,gBAAgB,EAAEgC,SAAW,CAAA,CAAA;AAC9C;QAEA,MAAMC,EAAAA,GAAK,MAACC,CAAeD,EAAE;AAC7B,QAAA,IAAI,CAACA,EAAI,EAAA;AACP,YAAA,MAAM,IAAIE,KAAM,CAAA,qEAAA,CAAA;AAClB;AAEA,QAAA,MAAMC,GAAMH,GAAAA,EAAAA,CAAGI,eAAe,CAACrC,IAAM,EAAA;YACnCsC,eAAiB,EAAA;gBACfC,MAAQN,EAAAA,EAAAA,CAAGO,YAAY,CAACC,MAAM;gBAC9BC,MAAQT,EAAAA,EAAAA,CAAGU,UAAU,CAACC,MAAM;gBAC5BC,SAAW,EAAA,IAAA;gBACXC,aAAe,EAAA,IAAA;gBACfC,sBAAwB,EAAA,IAAA;gBACxBC,uBAAyB,EAAA;AAC3B,aAAA;YACAC,QAAUjB,EAAAA;AACZ,SAAA,CAAA;QAEA,IAAIkB,GAAAA,GAAMd,GAAIe,CAAAA,UAAU,IAAI,EAAA;QAC5B,IAAIf,GAAAA,CAAIgB,aAAa,EAAE;AACrB,YAAA,MAAMC,SAAYC,GAAAA,IAAAA,CAAKC,QAASzF,CAAAA,kBAAAA,CAAmBsE,IAAIgB,aAAa,CAAA,CAAA,CAAA;YACpEF,GAAO,IAAA,CAAC,oDAAoD,EAAEG,SAAW,CAAA,CAAA;AAC3E;QACAH,GAAO,IAAA,CAAC,gBAAgB,EAAElB,SAAW,CAAA,CAAA;QACrC,OAAOkB,GAAAA;AACT;AAEA;;;;;;;;;;;;;;;;;;;;AAoBC,MACD,MAAcvB,cAAAA,CAAe3B,IAAY,EAAEU,MAAc,EAAE;QACzD,MAAM8C,IAAAA;QACN,MAAM,CAACC,OAAQ,CAAA,GAAGC,KAAM1D,CAAAA,IAAAA,CAAAA;AACxB,QAAA,MAAM2D,IAAO,GAAA;AAAIF,YAAAA,GAAAA;AAAQ,SAAA,CAACG,IAAI,CAAC,CAACC,CAAGC,EAAAA,CAAAA,GAAM,CAACD,CAAAA,CAAEE,CAAC,IAAI,CAAA,KAAMD,CAAEC,CAAAA,CAAC,IAAI,CAAA,CAAA,CAAA;AAC9D,QAAA,IAAIb,GAAM,GAAA,EAAA;AACV,QAAA,IAAIc,IAAO,GAAA,CAAA;QAEX,KAAK,MAAMC,MAAMN,IAAM,CAAA;;;;AAIrB,YAAA,IAAIM,EAAGC,CAAAA,CAAC,KAAK,EAAI,EAAA;AACf,gBAAA;AACF;;AAEA,YAAA,MAAMC,WAAWF,EAAGG,CAAAA,EAAE,IAAI,IAAQH,IAAAA,EAAAA,CAAGI,EAAE,IAAI,IAAA;AAC3C,YAAA,IAAI,CAACF,QAAYF,IAAAA,EAAAA,CAAGI,EAAE,IAAIJ,EAAAA,CAAGG,EAAE,EAAE;AAC/B,gBAAA;AACF;;AAEA,YAAA,IAAIH,EAAGK,CAAAA,CAAC,IAAIL,EAAAA,CAAGF,CAAC,EAAE;AAChB,gBAAA;AACF;;AAEAb,YAAAA,GAAAA,IAAOlD,IAAKX,CAAAA,KAAK,CAAC2E,IAAAA,EAAMC,GAAGF,CAAC,CAAA;YAE5B,MAAM9F,IAAAA,GAAO+B,IAAKX,CAAAA,KAAK,CAAC4E,EAAAA,CAAGF,CAAC,EAAEE,EAAAA,CAAGK,CAAC,CAAA,CAAA;AAClC,YAAA,IAAIC,WAActG,GAAAA,IAAAA;AAClB,YAAA,IAAID,aAAcC,CAAAA,IAAAA,CAAAA,IAASE,YAAaF,CAAAA,IAAAA,CAAAA,IAASG,aAAaH,IAAO,CAAA,EAAA;gBACnE,IAAIA,IAAAA,CAAKI,UAAU,CAAC,YAAe,CAAA,EAAA;oBACjCkG,WAActG,GAAAA,IAAAA;iBACT,MAAA;AACL,oBAAA,MAAMuG,KAAQ,GAAA,MAAM,IAAI,CAACnE,gBAAgB,CAACpC,IAAAA,CAAAA;AAC1CsG,oBAAAA,WAAAA,GAAc,MAAM,IAAI,CAACjE,KAAK,CAACkE;AACjC;aACK,MAAA;AACL,gBAAA,MAAMA,QAAQ,MAAM,IAAI,CAACnE,gBAAgB,CAACpC,MAAMF,MAAO2C,CAAAA,MAAAA,CAAAA,CAAAA;AACvD6D,gBAAAA,WAAAA,GAAc,MAAM,IAAI,CAACjE,KAAK,CAACkE;AACjC;AACAtB,YAAAA,GAAAA,IAAOqB;AACPP,YAAAA,IAAAA,GAAOC,GAAGK,CAAC;AACb;QACApB,GAAOlD,IAAAA,IAAAA,CAAKX,KAAK,CAAC2E,IAAAA,CAAAA;QAClB,OAAOd,GAAAA;AACT;AAEA;;;;;;;;;;;;;;;AAeC,MACD,MAAM7C,gBAAAA,CAAiBpC,IAAY,EAAEyC,MAAe,EAAE;QACpD,IAAIzC,IAAAA,CAAKI,UAAU,CAAC,IAAO,CAAA,EAAA;AACzB,YAAA,OAAO,IAAI,CAACE,IAAI,CAACkG,aAAa,CAAC,IAAI,CAAClG,IAAI,CAACmG,IAAI,CAAC,IAAI,CAAClG,YAAY,EAAEP,IAAAA,CAAKoB,KAAK,CAAC,CAAA,CAAA,CAAA,CAAA;SACvE,MAAA,IAAIpB,KAAKI,UAAU,CAAC,SAASJ,IAAKI,CAAAA,UAAU,CAAC,KAAQ,CAAA,EAAA;AAC1D,YAAA,IAAI,CAACqC,MAAQ,EAAA;AACX,gBAAA,MAAM,IAAIyB,KAAM,CAAA,CAAC,iBAAiB,EAAElE,IAAAA,CAAK,iBAAiB,CAAC,CAAA;AAC7D;YACA,OAAO,IAAI,CAACM,IAAI,CAACkG,aAAa,CAC5B,IAAI,CAAClG,IAAI,CAACmG,IAAI,CAAC,IAAI,CAACnG,IAAI,CAACoG,OAAO,CAAC,IAAI,CAACpG,IAAI,CAACkG,aAAa,CAAC/D,MAAUzC,CAAAA,CAAAA,EAAAA,IAAAA,CAAAA,CAAAA;AAEvE,SAAA,MAAO,IAAIA,IAAAA,CAAKI,UAAU,CAAC,GAAM,CAAA,EAAA;YAC/B,OAAOJ,IAAAA,CAAK2G,OAAO,CAAC,MAAQ,EAAA,GAAA,CAAA;AAC9B,SAAA,MAAO,IAAIrE,MAAAA,EAAAA,CAASC,UAAU,KAAK,MAAQ,EAAA;AACzC,YAAA,MAAMqE,OAAU,GAAA,GAAA;;AAEhB,YAAA,IAAIC,YAAe,GAAA,IAAI,CAACvG,IAAI,CAACkG,aAAa,CAAC,IAAI,CAAClG,IAAI,CAACmG,IAAI,CAACG,OAAS,EAAA,qBAAA,CAAA,CAAA;AACnE,YAAA,IAAIE,aAAa,MAAM,IAAI,CAACxG,IAAI,CAACkB,MAAM,CAACqF,YAAAA,CAAAA;AACxC,YAAA,IAAIC,UAAY,EAAA;gBACd,MAAMC,OAAAA,GAAW,MAAM,IAAI,CAACzG,IAAI,CAAC0B,QAAQ,CAAC6E,YAAc,EAAA;oBAAE5E,QAAU,EAAA;AAAO,iBAAA,CAAA;gBAC3E,MAAM+E,QAAAA,GAAWC,IAAKxB,CAAAA,KAAK,CAACsB,OAAAA,CAAAA;AAC5B,gBAAA,IAAIC,QAAUtE,EAAAA,YAAY,CAAC1C,IAAAA,CAAK,EAAE;AAChC,oBAAA,OAAO,IAAI,CAACM,IAAI,CAACkG,aAAa,CAAC,IAAI,CAAClG,IAAI,CAACmG,IAAI,CAACG,OAASI,EAAAA,QAAAA,CAAStE,YAAY,CAAC1C,IAAAA,CAAK,CAACkH,KAAK,CAAA,CAAA;AAC1F;AACF;AACF;QACA,OAAOlH,IAAAA;AACT;AAEA;;;;;;;;;;MAWA,MAAM+C,iBAAkBgB,CAAAA,SAAiB,EAAE;AACzC,QAAA,IAAIzC,IAA8B,GAAA,IAAA;AAClC,QAAA,IAAIC,WAAc,GAAA,EAAA;QAClB,IAAIwC,SAAAA,CAAU5C,QAAQ,CAAC,KAAQ,CAAA,EAAA;YAC7BI,WAAcwC,GAAAA,SAAAA;YACdzC,IAAO,GAAA,IAAA;SACF,MAAA,IAAIyC,UAAU5C,QAAQ,CAAC,UAAU4C,SAAU5C,CAAAA,QAAQ,CAAC,MAAS,CAAA,EAAA;YAClEI,WAAcwC,GAAAA,SAAAA;YACdzC,IAAO,GAAA,IAAA;AACT;AACA,QAAA,IAAIA,IAAM,EAAA;AACR,YAAA,MAAME,SAAS,MAAM,IAAI,CAAClB,IAAI,CAACkB,MAAM,CAACD,WAAAA,CAAAA;AACtC,YAAA,IAAI,CAACC,MAAQ,EAAA;gBACXF,IAAO,GAAA,IAAA;AACT;AACA,YAAA,MAAMG,OAAO,MAAM,IAAI,CAACnB,IAAI,CAACmB,IAAI,CAACF,WAAAA,CAAAA;YAClC,IAAIE,IAAAA,CAAKC,WAAW,EAAE;gBACpBJ,IAAO,GAAA,IAAA;AACT;AACF;AACA,QAAA,MAAMK,KAAQ,GAAA;AAAC,YAAA,IAAA;AAAM,YAAA,IAAA;AAAM,YAAA;AAAM,SAAA;AACjC,QAAA,IAAI,CAACL,IAAM,EAAA;YACT,KAAK,MAAMM,KAAKD,KAAO,CAAA;AACrBJ,gBAAAA,WAAAA,GAAc,CAAGwC,EAAAA,SAAAA,CAAU,CAAC,EAAEnC,CAAG,CAAA,CAAA;AACjC,gBAAA,MAAMJ,SAAS,MAAM,IAAI,CAAClB,IAAI,CAACkB,MAAM,CAACD,WAAAA,CAAAA;AACtC,gBAAA,IAAIC,MAAQ,EAAA;AACV,oBAAA,MAAMK,QAAQ,MAAM,IAAI,CAACvB,IAAI,CAACmB,IAAI,CAACF,WAAAA,CAAAA;oBACnC,IAAIM,KAAAA,CAAMC,MAAM,EAAE;wBAChBR,IAAOM,GAAAA,CAAAA,KAAM,OAAO,IAAO,GAAA,IAAA;AAC3B,wBAAA;AACF;AACF;AACF;AACF;AACA,QAAA,OAAON,IAAO,GAAA;AAAEA,YAAAA,IAAAA;YAAMR,IAAMS,EAAAA;SAAgB,GAAA,IAAA;AAC9C;AACF;;;;"}
|
|
@@ -609,7 +609,7 @@ import '../shaders/atmosphere.js';
|
|
|
609
609
|
const u = q.shift();
|
|
610
610
|
const ins = gs.incoming[u] || [];
|
|
611
611
|
for (const conn of ins){
|
|
612
|
-
const v = conn.targetNodeId; //
|
|
612
|
+
const v = conn.targetNodeId; // predecessor
|
|
613
613
|
if (!reachable.has(v)) {
|
|
614
614
|
reachable.add(v);
|
|
615
615
|
q.push(v);
|
|
@@ -649,7 +649,7 @@ import '../shaders/atmosphere.js';
|
|
|
649
649
|
for (const u of currentLevel){
|
|
650
650
|
const ins = gs.incoming[u] || [];
|
|
651
651
|
for (const conn of ins){
|
|
652
|
-
const v = conn.targetNodeId; //
|
|
652
|
+
const v = conn.targetNodeId; // predecessor
|
|
653
653
|
if (!sub.has(v)) {
|
|
654
654
|
continue;
|
|
655
655
|
}
|