@needle-tools/engine 5.1.0-canary.e9062c0 → 5.1.0-canary.f57972c
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/CHANGELOG.md +120 -0
- package/SKILL.md +4 -1
- package/components.needle.json +1 -1
- package/dist/{needle-engine.bundle-CDKcuALa.js → needle-engine.bundle-CAIG39cL.js} +13605 -12680
- package/dist/needle-engine.bundle-CFh_isu6.umd.cjs +1734 -0
- package/dist/needle-engine.bundle-CtadUKoi.min.js +1734 -0
- package/dist/needle-engine.d.ts +1579 -394
- package/dist/needle-engine.js +542 -538
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/three.js +1 -0
- package/dist/three.min.js +21 -21
- package/dist/three.umd.cjs +16 -16
- package/lib/engine/api.d.ts +8 -1
- package/lib/engine/api.js +7 -1
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/codegen/register_types.js +10 -18
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/debug/debug_spatial_console.d.ts +2 -0
- package/lib/engine/debug/debug_spatial_console.js +10 -7
- package/lib/engine/debug/debug_spatial_console.js.map +1 -1
- package/lib/engine/engine_addressables.d.ts +2 -0
- package/lib/engine/engine_addressables.js +6 -3
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_audio.d.ts +68 -0
- package/lib/engine/engine_audio.js +172 -0
- package/lib/engine/engine_audio.js.map +1 -1
- package/lib/engine/engine_camera.fit.js +16 -4
- package/lib/engine/engine_camera.fit.js.map +1 -1
- package/lib/engine/engine_components.js +1 -1
- package/lib/engine/engine_components.js.map +1 -1
- package/lib/engine/engine_context.d.ts +37 -27
- package/lib/engine/engine_context.js +51 -31
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_context_eventbus.d.ts +47 -0
- package/lib/engine/engine_context_eventbus.js +47 -0
- package/lib/engine/engine_context_eventbus.js.map +1 -0
- package/lib/engine/engine_disposable.d.ts +172 -0
- package/lib/engine/engine_disposable.js +136 -0
- package/lib/engine/engine_disposable.js.map +1 -0
- package/lib/engine/engine_gameobject.d.ts +1 -10
- package/lib/engine/engine_gameobject.js +22 -120
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_gltf_builtin_components.js +7 -69
- package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
- package/lib/engine/engine_init.js +14 -4
- package/lib/engine/engine_init.js.map +1 -1
- package/lib/engine/engine_input.d.ts +24 -5
- package/lib/engine/engine_input.js +3 -2
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_instantiate_resolve.d.ts +42 -0
- package/lib/engine/engine_instantiate_resolve.js +372 -0
- package/lib/engine/engine_instantiate_resolve.js.map +1 -0
- package/lib/engine/engine_license.d.ts +7 -7
- package/lib/engine/engine_license.js +186 -58
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_mainloop_utils.js +7 -4
- package/lib/engine/engine_mainloop_utils.js.map +1 -1
- package/lib/engine/engine_networking.d.ts +51 -37
- package/lib/engine/engine_networking.js +132 -82
- package/lib/engine/engine_networking.js.map +1 -1
- package/lib/engine/engine_networking.transport.websocket.d.ts +15 -0
- package/lib/engine/engine_networking.transport.websocket.js +38 -0
- package/lib/engine/engine_networking.transport.websocket.js.map +1 -0
- package/lib/engine/engine_networking_blob.js +4 -4
- package/lib/engine/engine_networking_blob.js.map +1 -1
- package/lib/engine/engine_networking_instantiate.js +2 -2
- package/lib/engine/engine_networking_instantiate.js.map +1 -1
- package/lib/engine/engine_networking_types.d.ts +39 -1
- package/lib/engine/engine_networking_types.js +7 -0
- package/lib/engine/engine_networking_types.js.map +1 -1
- package/lib/engine/engine_physics_rapier.d.ts +21 -3
- package/lib/engine/engine_physics_rapier.js +94 -25
- package/lib/engine/engine_physics_rapier.js.map +1 -1
- package/lib/engine/engine_scenedata.d.ts +5 -7
- package/lib/engine/engine_scenedata.js +16 -13
- package/lib/engine/engine_scenedata.js.map +1 -1
- package/lib/engine/engine_serialization_builtin_serializer.d.ts +10 -16
- package/lib/engine/engine_serialization_builtin_serializer.js +56 -46
- package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
- package/lib/engine/engine_serialization_core.d.ts +1 -0
- package/lib/engine/engine_serialization_core.js +7 -0
- package/lib/engine/engine_serialization_core.js.map +1 -1
- package/lib/engine/engine_types.d.ts +29 -11
- package/lib/engine/engine_types.js +1 -1
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/engine_util_decorator.js +7 -2
- package/lib/engine/engine_util_decorator.js.map +1 -1
- package/lib/engine/engine_utils.d.ts +1 -1
- package/lib/engine/engine_utils.js +19 -5
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/engine_utils_qrcode.js +2 -2
- package/lib/engine/engine_utils_qrcode.js.map +1 -1
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js.map +1 -1
- package/lib/engine/webcomponents/jsx.d.ts +9 -2
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +2 -2
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js +6 -6
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +10 -4
- package/lib/engine/webcomponents/needle-engine.js +3 -3
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.loading.js +2 -2
- package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
- package/lib/engine/xr/NeedleXRSession.d.ts +3 -2
- package/lib/engine/xr/NeedleXRSession.js +50 -14
- package/lib/engine/xr/NeedleXRSession.js.map +1 -1
- package/lib/engine/xr/TempXRContext.js +2 -2
- package/lib/engine/xr/TempXRContext.js.map +1 -1
- package/lib/engine/xr/events.d.ts +1 -1
- package/lib/engine/xr/events.js.map +1 -1
- package/lib/engine-components/Animation.js +17 -16
- package/lib/engine-components/Animation.js.map +1 -1
- package/lib/engine-components/AnimationBuilder.d.ts +158 -0
- package/lib/engine-components/AnimationBuilder.js +305 -0
- package/lib/engine-components/AnimationBuilder.js.map +1 -0
- package/lib/engine-components/Animator.d.ts +6 -0
- package/lib/engine-components/Animator.js +23 -13
- package/lib/engine-components/Animator.js.map +1 -1
- package/lib/engine-components/AnimatorController.builder.d.ts +191 -0
- package/lib/engine-components/AnimatorController.builder.js +263 -0
- package/lib/engine-components/AnimatorController.builder.js.map +1 -0
- package/lib/engine-components/AnimatorController.d.ts +4 -119
- package/lib/engine-components/AnimatorController.js +37 -233
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/AudioSource.d.ts +19 -3
- package/lib/engine-components/AudioSource.js +121 -68
- package/lib/engine-components/AudioSource.js.map +1 -1
- package/lib/engine-components/Collider.d.ts +18 -9
- package/lib/engine-components/Collider.js +61 -14
- package/lib/engine-components/Collider.js.map +1 -1
- package/lib/engine-components/Component.d.ts +72 -9
- package/lib/engine-components/Component.js +114 -10
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/ContactShadows.d.ts +1 -0
- package/lib/engine-components/ContactShadows.js +14 -1
- package/lib/engine-components/ContactShadows.js.map +1 -1
- package/lib/engine-components/DragControls.d.ts +7 -0
- package/lib/engine-components/DragControls.js +19 -7
- package/lib/engine-components/DragControls.js.map +1 -1
- package/lib/engine-components/DropListener.js +3 -0
- package/lib/engine-components/DropListener.js.map +1 -1
- package/lib/engine-components/EventList.d.ts +31 -9
- package/lib/engine-components/EventList.js +37 -76
- package/lib/engine-components/EventList.js.map +1 -1
- package/lib/engine-components/Joints.d.ts +4 -2
- package/lib/engine-components/Joints.js +19 -3
- package/lib/engine-components/Joints.js.map +1 -1
- package/lib/engine-components/Light.js +13 -3
- package/lib/engine-components/Light.js.map +1 -1
- package/lib/engine-components/Networking.d.ts +1 -1
- package/lib/engine-components/Networking.js +1 -1
- package/lib/engine-components/OrbitControls.d.ts +0 -2
- package/lib/engine-components/OrbitControls.js +30 -12
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/ReflectionProbe.js +2 -0
- package/lib/engine-components/ReflectionProbe.js.map +1 -1
- package/lib/engine-components/RigidBody.d.ts +12 -4
- package/lib/engine-components/RigidBody.js +18 -4
- package/lib/engine-components/RigidBody.js.map +1 -1
- package/lib/engine-components/SceneSwitcher.js +3 -0
- package/lib/engine-components/SceneSwitcher.js.map +1 -1
- package/lib/engine-components/SeeThrough.js +2 -2
- package/lib/engine-components/SeeThrough.js.map +1 -1
- package/lib/engine-components/api.d.ts +2 -1
- package/lib/engine-components/api.js +2 -1
- package/lib/engine-components/api.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +7 -13
- package/lib/engine-components/codegen/components.js +7 -13
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/export/usdz/USDZExporter.js +4 -4
- package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
- package/lib/engine-components/postprocessing/VolumeParameter.d.ts +2 -0
- package/lib/engine-components/postprocessing/VolumeParameter.js +4 -1
- package/lib/engine-components/postprocessing/VolumeParameter.js.map +1 -1
- package/lib/engine-components/timeline/PlayableDirector.d.ts +21 -11
- package/lib/engine-components/timeline/PlayableDirector.js +75 -67
- package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
- package/lib/engine-components/timeline/SignalAsset.d.ts +3 -1
- package/lib/engine-components/timeline/SignalAsset.js +1 -0
- package/lib/engine-components/timeline/SignalAsset.js.map +1 -1
- package/lib/engine-components/timeline/TimelineBuilder.d.ts +413 -0
- package/lib/engine-components/timeline/TimelineBuilder.js +506 -0
- package/lib/engine-components/timeline/TimelineBuilder.js.map +1 -0
- package/lib/engine-components/timeline/TimelineModels.d.ts +2 -1
- package/lib/engine-components/timeline/TimelineModels.js +3 -0
- package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
- package/lib/engine-components/timeline/TimelineTracks.d.ts +37 -6
- package/lib/engine-components/timeline/TimelineTracks.js +92 -26
- package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
- package/lib/engine-components/timeline/index.d.ts +2 -1
- package/lib/engine-components/timeline/index.js +2 -0
- package/lib/engine-components/timeline/index.js.map +1 -1
- package/lib/engine-components/ui/Canvas.d.ts +1 -1
- package/lib/engine-components/ui/Canvas.js +2 -8
- package/lib/engine-components/ui/Canvas.js.map +1 -1
- package/lib/engine-components/ui/Text.d.ts +1 -0
- package/lib/engine-components/ui/Text.js +10 -7
- package/lib/engine-components/ui/Text.js.map +1 -1
- package/lib/engine-components/web/CursorFollow.d.ts +0 -1
- package/lib/engine-components/web/CursorFollow.js +21 -13
- package/lib/engine-components/web/CursorFollow.js.map +1 -1
- package/lib/engine-components/webxr/WebXRImageTracking.d.ts +62 -1
- package/lib/engine-components/webxr/WebXRImageTracking.js +59 -2
- package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
- package/package.json +2 -83
- package/plugins/common/cloud.js +6 -1
- package/plugins/common/license.js +31 -10
- package/plugins/common/worker.js +9 -4
- package/plugins/vite/asap.js +17 -8
- package/plugins/vite/dependencies.js +29 -10
- package/plugins/vite/dependency-watcher.js +2 -2
- package/plugins/vite/editor-connection.js +3 -3
- package/plugins/vite/license.js +42 -7
- package/plugins/vite/local-files-core.js +3 -3
- package/plugins/vite/local-files-utils.d.ts +3 -1
- package/plugins/vite/local-files-utils.js +29 -5
- package/plugins/vite/reload.js +19 -18
- package/plugins/vite/server.js +2 -1
- package/src/engine/api.ts +11 -1
- package/src/engine/codegen/register_types.ts +10 -18
- package/src/engine/debug/debug_spatial_console.ts +10 -7
- package/src/engine/engine_addressables.ts +6 -3
- package/src/engine/engine_audio.ts +184 -0
- package/src/engine/engine_camera.fit.ts +15 -4
- package/src/engine/engine_components.ts +1 -1
- package/src/engine/engine_context.ts +63 -39
- package/src/engine/engine_context_eventbus.ts +73 -0
- package/src/engine/engine_disposable.ts +214 -0
- package/src/engine/engine_gameobject.ts +54 -159
- package/src/engine/engine_gltf_builtin_components.ts +7 -76
- package/src/engine/engine_init.ts +14 -4
- package/src/engine/engine_input.ts +28 -7
- package/src/engine/engine_instantiate_resolve.ts +407 -0
- package/src/engine/engine_license.ts +202 -56
- package/src/engine/engine_mainloop_utils.ts +7 -4
- package/src/engine/engine_networking.transport.websocket.ts +45 -0
- package/src/engine/engine_networking.ts +161 -137
- package/src/engine/engine_networking_blob.ts +4 -4
- package/src/engine/engine_networking_instantiate.ts +2 -2
- package/src/engine/engine_networking_types.ts +41 -1
- package/src/engine/engine_physics_rapier.ts +102 -33
- package/src/engine/engine_scenedata.ts +16 -13
- package/src/engine/engine_serialization_builtin_serializer.ts +64 -52
- package/src/engine/engine_serialization_core.ts +9 -0
- package/src/engine/engine_types.ts +46 -27
- package/src/engine/engine_util_decorator.ts +7 -2
- package/src/engine/engine_utils.ts +16 -5
- package/src/engine/engine_utils_qrcode.ts +2 -2
- package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
- package/src/engine/webcomponents/jsx.d.ts +9 -2
- package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +2 -2
- package/src/engine/webcomponents/needle menu/needle-menu.ts +6 -6
- package/src/engine/webcomponents/needle-engine.loading.ts +6 -6
- package/src/engine/webcomponents/needle-engine.ts +12 -6
- package/src/engine/xr/NeedleXRSession.ts +48 -13
- package/src/engine/xr/TempXRContext.ts +2 -2
- package/src/engine/xr/events.ts +1 -1
- package/src/engine-components/Animation.ts +19 -16
- package/src/engine-components/AnimationBuilder.ts +472 -0
- package/src/engine-components/Animator.ts +24 -12
- package/src/engine-components/AnimatorController.builder.ts +387 -0
- package/src/engine-components/AnimatorController.ts +24 -292
- package/src/engine-components/AudioSource.ts +130 -79
- package/src/engine-components/Collider.ts +66 -18
- package/src/engine-components/Component.ts +118 -20
- package/src/engine-components/ContactShadows.ts +15 -1
- package/src/engine-components/DragControls.ts +18 -11
- package/src/engine-components/DropListener.ts +3 -0
- package/src/engine-components/EventList.ts +45 -83
- package/src/engine-components/Joints.ts +20 -4
- package/src/engine-components/Light.ts +13 -4
- package/src/engine-components/Networking.ts +1 -1
- package/src/engine-components/OrbitControls.ts +34 -14
- package/src/engine-components/ReflectionProbe.ts +2 -0
- package/src/engine-components/RigidBody.ts +18 -4
- package/src/engine-components/SceneSwitcher.ts +3 -0
- package/src/engine-components/SeeThrough.ts +2 -2
- package/src/engine-components/api.ts +2 -1
- package/src/engine-components/codegen/components.ts +7 -13
- package/src/engine-components/export/usdz/USDZExporter.ts +4 -4
- package/src/engine-components/postprocessing/VolumeParameter.ts +4 -1
- package/src/engine-components/timeline/PlayableDirector.ts +83 -81
- package/src/engine-components/timeline/SignalAsset.ts +4 -1
- package/src/engine-components/timeline/TimelineBuilder.ts +824 -0
- package/src/engine-components/timeline/TimelineModels.ts +5 -1
- package/src/engine-components/timeline/TimelineTracks.ts +96 -27
- package/src/engine-components/timeline/index.ts +2 -1
- package/src/engine-components/ui/Canvas.ts +2 -8
- package/src/engine-components/ui/Text.ts +12 -8
- package/src/engine-components/web/CursorFollow.ts +21 -14
- package/src/engine-components/webxr/WebXRImageTracking.ts +79 -7
- package/dist/needle-engine.bundle--q_w7iXI.umd.cjs +0 -1732
- package/dist/needle-engine.bundle-w22UkaT_.min.js +0 -1732
- package/lib/engine-components/AvatarLoader.d.ts +0 -80
- package/lib/engine-components/AvatarLoader.js +0 -232
- package/lib/engine-components/AvatarLoader.js.map +0 -1
- package/lib/engine-components/avatar/AvatarBlink_Simple.d.ts +0 -11
- package/lib/engine-components/avatar/AvatarBlink_Simple.js +0 -77
- package/lib/engine-components/avatar/AvatarBlink_Simple.js.map +0 -1
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.d.ts +0 -14
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js +0 -69
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js.map +0 -1
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.d.ts +0 -29
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.js +0 -122
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.js.map +0 -1
- package/lib/engine-components/avatar/Avatar_MouthShapes.d.ts +0 -15
- package/lib/engine-components/avatar/Avatar_MouthShapes.js +0 -80
- package/lib/engine-components/avatar/Avatar_MouthShapes.js.map +0 -1
- package/lib/engine-components/avatar/Avatar_MustacheShake.d.ts +0 -9
- package/lib/engine-components/avatar/Avatar_MustacheShake.js +0 -30
- package/lib/engine-components/avatar/Avatar_MustacheShake.js.map +0 -1
- package/src/engine-components/AvatarLoader.ts +0 -264
- package/src/engine-components/avatar/AvatarBlink_Simple.ts +0 -70
- package/src/engine-components/avatar/AvatarEyeLook_Rotation.ts +0 -64
- package/src/engine-components/avatar/Avatar_Brain_LookAt.ts +0 -140
- package/src/engine-components/avatar/Avatar_MouthShapes.ts +0 -84
- package/src/engine-components/avatar/Avatar_MustacheShake.ts +0 -32
- package/src/vite-env.d.ts +0 -16
|
@@ -86,24 +86,38 @@ async function requestNeedleCloud(path, options) {
|
|
|
86
86
|
|
|
87
87
|
/** @typedef {{ ok: boolean, status: number, statusText: string, text: string }} NeedleCloudHttpResponse */
|
|
88
88
|
|
|
89
|
+
/** @typedef {{ type: string, jwt: string | null }} LicenseResult */
|
|
90
|
+
|
|
89
91
|
/**
|
|
90
92
|
* Replace license string - used for webpack
|
|
91
93
|
* @param {string} code
|
|
92
94
|
* @param {DefaultOptions & {accessToken?:string, team:string|undefined}} opts
|
|
93
95
|
*/
|
|
94
96
|
export async function replaceLicense(code, opts) {
|
|
95
|
-
const index = code?.indexOf("
|
|
97
|
+
const index = code?.indexOf("_EubmJj");
|
|
96
98
|
if (index >= 0) {
|
|
97
|
-
const
|
|
98
|
-
if (!
|
|
99
|
+
const licenseResult = await resolveLicense(opts);
|
|
100
|
+
if (!licenseResult) {
|
|
99
101
|
return code;
|
|
100
102
|
}
|
|
101
103
|
const end = code.indexOf(";", index);
|
|
102
104
|
if (end >= 0) {
|
|
103
105
|
const line = code.substring(index, end);
|
|
104
|
-
const replaced = "
|
|
106
|
+
const replaced = "_EubmJj = \"" + licenseResult.type + "\"";
|
|
105
107
|
code = code.replace(line, replaced);
|
|
106
|
-
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Also inject JWT if available
|
|
111
|
+
if (licenseResult.jwt) {
|
|
112
|
+
const jwtIndex = code.indexOf("__OXddGMYg");
|
|
113
|
+
if (jwtIndex >= 0) {
|
|
114
|
+
const jwtEnd = code.indexOf(";", jwtIndex);
|
|
115
|
+
if (jwtEnd >= 0) {
|
|
116
|
+
const jwtLine = code.substring(jwtIndex, jwtEnd);
|
|
117
|
+
const jwtReplaced = "__OXddGMYg = \"" + licenseResult.jwt + "\"";
|
|
118
|
+
code = code.replace(jwtLine, jwtReplaced);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
107
121
|
}
|
|
108
122
|
}
|
|
109
123
|
return code;
|
|
@@ -112,7 +126,7 @@ export async function replaceLicense(code, opts) {
|
|
|
112
126
|
/**
|
|
113
127
|
* Resolve the license using the needle engine licensing server
|
|
114
128
|
* @param {DefaultOptions & {accessToken?:string, team?:string} | null} args
|
|
115
|
-
* @returns {Promise<
|
|
129
|
+
* @returns {Promise<LicenseResult | null>}
|
|
116
130
|
*/
|
|
117
131
|
export async function resolveLicense(args = null) {
|
|
118
132
|
let accessToken = args?.accessToken;
|
|
@@ -210,7 +224,7 @@ export async function resolveLicense(args = null) {
|
|
|
210
224
|
return null;
|
|
211
225
|
}
|
|
212
226
|
else if (!licenseResponse.ok) {
|
|
213
|
-
if (licenseResponse.status
|
|
227
|
+
if (licenseResponse.status >= 500)
|
|
214
228
|
logLicense(`ERROR: Failed to fetch license (${licenseResponse.status})`, "error");
|
|
215
229
|
else
|
|
216
230
|
logLicense(`No license found (${licenseResponse.status})`);
|
|
@@ -226,10 +240,11 @@ export async function resolveLicense(args = null) {
|
|
|
226
240
|
/**
|
|
227
241
|
* @param {string} str License string
|
|
228
242
|
* @param {{includeFetchLine?: boolean}} [options]
|
|
243
|
+
* @returns {LicenseResult | null}
|
|
229
244
|
*/
|
|
230
245
|
function tryParseLicense(str, options = undefined) {
|
|
231
246
|
try {
|
|
232
|
-
/** @type {{needle_engine_license:string}} */
|
|
247
|
+
/** @type {{needle_engine_license:string, needle_license_jwt?:string}} */
|
|
233
248
|
const licenseJson = JSON.parse(str);
|
|
234
249
|
if (licenseJson.needle_engine_license) {
|
|
235
250
|
const success = `INFO: Successfully received \"${licenseJson.needle_engine_license?.toUpperCase()}\" license`;
|
|
@@ -239,7 +254,10 @@ function tryParseLicense(str, options = undefined) {
|
|
|
239
254
|
else {
|
|
240
255
|
logLicense(success);
|
|
241
256
|
}
|
|
242
|
-
return
|
|
257
|
+
return {
|
|
258
|
+
type: licenseJson.needle_engine_license,
|
|
259
|
+
jwt: licenseJson.needle_license_jwt || null,
|
|
260
|
+
};
|
|
243
261
|
}
|
|
244
262
|
if ("error" in licenseJson) {
|
|
245
263
|
logLicense(`ERROR in license check: \"${licenseJson.error}\"`, "error");
|
|
@@ -361,7 +379,10 @@ export async function getPublicIdentifier(project_id, opts = undefined) {
|
|
|
361
379
|
return null;
|
|
362
380
|
}
|
|
363
381
|
else if (!res.ok) {
|
|
364
|
-
|
|
382
|
+
if (res.status >= 500)
|
|
383
|
+
logIdentifier(`Failed to fetch project identifier (${res.status})`, "error");
|
|
384
|
+
else
|
|
385
|
+
logIdentifier(`No project identifier found (${res.status})`);
|
|
365
386
|
await releaseResponse(res);
|
|
366
387
|
return null;
|
|
367
388
|
}
|
package/plugins/common/worker.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from 'path';
|
|
1
2
|
import { needleLog } from '../vite/logging.js';
|
|
2
3
|
|
|
3
4
|
|
|
@@ -53,13 +54,17 @@ export function rollupFixWorkerImport(opts = { logFail: true }) {
|
|
|
53
54
|
// console.log("WORKER?", url)
|
|
54
55
|
if (url?.startsWith("/")) {
|
|
55
56
|
needleLog("rollup", `Rewrite worker import in ${chunk.fileName}`, "log", { leadingNewline: true, dimBody: false });
|
|
56
|
-
//
|
|
57
|
-
|
|
57
|
+
// Compute the relative path from the chunk's directory to the worker file.
|
|
58
|
+
// url is absolute from build root (e.g. "/assets/worker.js") and the chunk
|
|
59
|
+
// may itself be inside assets/ — using path.posix.relative avoids producing
|
|
60
|
+
// a double "assets/assets/" path.
|
|
61
|
+
const workerPath = url.replace(/^\//, "");
|
|
62
|
+
const chunkDir = path.posix.dirname(chunk.fileName);
|
|
63
|
+
const relativeUrl = path.posix.relative(chunkDir, workerPath) || workerPath;
|
|
58
64
|
// For CORS issues we need to use importScripts: https://linear.app/needle/issue/NE-6572#comment-ea5dc65e
|
|
59
|
-
const output = `/* new-worker */ new Worker(URL.createObjectURL(new Blob(["import '" + \`\${new URL('./${
|
|
65
|
+
const output = `/* new-worker */ new Worker(URL.createObjectURL(new Blob(["import '" + \`\${new URL('./${relativeUrl}', import.meta.url).toString()}\` + "';"], { type: 'text/javascript' }))`;
|
|
60
66
|
needleLog("rollup", "Did rewrite worker output to: " + output, "log", { leadingNewline: true });
|
|
61
67
|
return output;
|
|
62
|
-
// return `new Worker(new URL("./${newUrl}", import.meta.url)`;
|
|
63
68
|
}
|
|
64
69
|
return match;
|
|
65
70
|
});
|
package/plugins/vite/asap.js
CHANGED
|
@@ -50,7 +50,7 @@ export async function needleAsap(command, config, userSettings) {
|
|
|
50
50
|
const tags = [];
|
|
51
51
|
|
|
52
52
|
try {
|
|
53
|
-
generateGltfPreloadLinks(config, html, tags);
|
|
53
|
+
generateGltfPreloadLinks(config, html, tags, viteConfig?.base);
|
|
54
54
|
}
|
|
55
55
|
catch (err) {
|
|
56
56
|
console.error("Error generating gltf preload links", err);
|
|
@@ -173,18 +173,21 @@ function fixMainTs() {
|
|
|
173
173
|
* @param {import('vite').ResolvedConfig} _config
|
|
174
174
|
* @param {import('vite').HtmlTagDescriptor[]} tags
|
|
175
175
|
*/
|
|
176
|
-
function generateScriptPreloadLinks(
|
|
176
|
+
function generateScriptPreloadLinks(config, tags) {
|
|
177
177
|
try {
|
|
178
|
+
const base = config.base || '/';
|
|
178
179
|
const chunks = preloadScriptPaths;
|
|
179
180
|
// console.log("ASAP", chunks)
|
|
180
181
|
if (chunks.length > 0) {
|
|
181
182
|
for (const chunk of chunks) {
|
|
183
|
+
// Apply base path so preload hrefs resolve correctly under SPA routing
|
|
184
|
+
const href = chunk.startsWith('./') ? base + chunk.slice(2) : chunk;
|
|
182
185
|
tags.push({
|
|
183
186
|
tag: 'link',
|
|
184
187
|
attrs: {
|
|
185
188
|
rel: "modulepreload",
|
|
186
189
|
as: "script",
|
|
187
|
-
href:
|
|
190
|
+
href: href,
|
|
188
191
|
}
|
|
189
192
|
});
|
|
190
193
|
}
|
|
@@ -203,15 +206,16 @@ const codegenRegex = /\"(?<gltf>.+(.glb|.gltf)(\?.*)?)\"/gm;
|
|
|
203
206
|
/**
|
|
204
207
|
* @param {import('../types').needleConfig} config
|
|
205
208
|
* @param {string} html
|
|
206
|
-
* @param {import('vite').HtmlTagDescriptor[]} tags
|
|
209
|
+
* @param {import('vite').HtmlTagDescriptor[]} tags
|
|
210
|
+
* @param {string} [base]
|
|
207
211
|
**/
|
|
208
|
-
function generateGltfPreloadLinks(config, html, tags) {
|
|
212
|
+
function generateGltfPreloadLinks(config, html, tags, base) {
|
|
209
213
|
|
|
210
214
|
// TODO: try to get the <needle-engine src> element src attribute and preload that
|
|
211
215
|
const needleEngineMatches = tryParseNeedleEngineSrcAttributeFromHtml(html);
|
|
212
216
|
if (needleEngineMatches?.length) {
|
|
213
217
|
for (const item of needleEngineMatches) {
|
|
214
|
-
insertPreloadLink(tags, item, "model/gltf+json");
|
|
218
|
+
insertPreloadLink(tags, item, "model/gltf+json", base);
|
|
215
219
|
}
|
|
216
220
|
}
|
|
217
221
|
|
|
@@ -246,7 +250,7 @@ function generateGltfPreloadLinks(config, html, tags) {
|
|
|
246
250
|
}
|
|
247
251
|
}
|
|
248
252
|
needleLog("needle:asap", `Insert glTF preload link: ${value}`);
|
|
249
|
-
insertPreloadLink(tags, value, "model/gltf+json");
|
|
253
|
+
insertPreloadLink(tags, value, "model/gltf+json", base);
|
|
250
254
|
}
|
|
251
255
|
}
|
|
252
256
|
}
|
|
@@ -258,9 +262,14 @@ function generateGltfPreloadLinks(config, html, tags) {
|
|
|
258
262
|
* @param {import('vite').HtmlTagDescriptor[]} tags
|
|
259
263
|
* @param {string} href
|
|
260
264
|
* @param {string} type
|
|
265
|
+
* @param {string} [base]
|
|
261
266
|
*/
|
|
262
|
-
function insertPreloadLink(tags, href, type) {
|
|
267
|
+
function insertPreloadLink(tags, href, type, base) {
|
|
263
268
|
if (!href) return;
|
|
269
|
+
// Apply base path so preload hrefs resolve correctly under SPA routing
|
|
270
|
+
if (base && !href.startsWith('http') && !href.startsWith('/')) {
|
|
271
|
+
href = base + (href.startsWith('./') ? href.slice(2) : href);
|
|
272
|
+
}
|
|
264
273
|
tags.push({
|
|
265
274
|
tag: 'link',
|
|
266
275
|
attrs: {
|
|
@@ -61,6 +61,35 @@ export function needleDependencies(command, config, userSettings) {
|
|
|
61
61
|
}
|
|
62
62
|
},
|
|
63
63
|
},
|
|
64
|
+
// Vite 8's optimizer rebases `new URL(specifier, import.meta.url)` paths
|
|
65
|
+
// inside pre-bundled dependencies (PR #21434), but only handles truly relative
|
|
66
|
+
// paths (./ ../). Bare-specifier paths like `three-mesh-bvh/src/workers/...`
|
|
67
|
+
// are treated as relative to the *source file* that contained the `new URL()`
|
|
68
|
+
// call, producing a wrong URL such as:
|
|
69
|
+
// /node_modules/@needle-tools/engine/.../three-mesh-bvh/src/workers/generateMeshBVH.worker.js
|
|
70
|
+
// This middleware rewrites those broken URLs so the dev server finds the file at
|
|
71
|
+
// its real location in node_modules.
|
|
72
|
+
{
|
|
73
|
+
name: 'needle:worker-url-rewrite',
|
|
74
|
+
configureServer(server) {
|
|
75
|
+
const rewritePackages = ['three-mesh-bvh'];
|
|
76
|
+
server.middlewares.use((req, _res, next) => {
|
|
77
|
+
if (req.url) {
|
|
78
|
+
for (const pkg of rewritePackages) {
|
|
79
|
+
const marker = `/${pkg}/`;
|
|
80
|
+
if (req.url.includes(marker) && !req.url.startsWith(`/node_modules/${pkg}/`) && !req.url.startsWith('/@fs/')) {
|
|
81
|
+
const idx = req.url.indexOf(marker);
|
|
82
|
+
const rewritten = '/node_modules' + req.url.slice(idx);
|
|
83
|
+
needleLog('needle-dependencies', `Rewriting worker URL → ${rewritten}`);
|
|
84
|
+
req.url = rewritten;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
next();
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
},
|
|
64
93
|
]
|
|
65
94
|
}
|
|
66
95
|
|
|
@@ -158,16 +187,6 @@ function handleOptimizeDeps(config) {
|
|
|
158
187
|
config.optimizeDeps.exclude.push('@needle-tools/engine');
|
|
159
188
|
needleLog("needle-dependencies", 'Detected local @needle-tools/engine package → will exclude it from optimization');
|
|
160
189
|
}
|
|
161
|
-
// When engine is excluded from optimizeDeps, three-mesh-bvh must also be excluded.
|
|
162
|
-
// The BVH worker (generateMeshBVH.worker.js) uses bare imports like `import 'three'`
|
|
163
|
-
// which only resolve correctly when served through Vite's dev server module system.
|
|
164
|
-
// If three-mesh-bvh is pre-bundled, the worker URL points into the cache and bare
|
|
165
|
-
// imports fail at runtime → "Unknown error. Please check the server console."
|
|
166
|
-
if (!config.optimizeDeps.include?.includes('three-mesh-bvh') &&
|
|
167
|
-
!config.optimizeDeps.exclude.includes('three-mesh-bvh')) {
|
|
168
|
-
config.optimizeDeps.exclude.push('three-mesh-bvh');
|
|
169
|
-
needleLog("needle-dependencies", 'Detected local @needle-tools/engine package → will also exclude three-mesh-bvh from optimization');
|
|
170
|
-
}
|
|
171
190
|
}
|
|
172
191
|
}
|
|
173
192
|
|
|
@@ -98,7 +98,7 @@ function watchPackageJson(server, projectDir, packageJsonPath, cachePath) {
|
|
|
98
98
|
|
|
99
99
|
setTimeout(() => {
|
|
100
100
|
requireInstall = testIfInstallIsRequired(projectDir, packageJson);
|
|
101
|
-
}, 1000);
|
|
101
|
+
}, 1000).unref();
|
|
102
102
|
|
|
103
103
|
setInterval(() => {
|
|
104
104
|
if (!packageJson || lastEditTime === undefined) return;
|
|
@@ -149,7 +149,7 @@ function watchPackageJson(server, projectDir, packageJsonPath, cachePath) {
|
|
|
149
149
|
restart(server, projectDir, cachePath);
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
|
-
}, 2000);
|
|
152
|
+
}, 2000).unref();
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
/** @param {string} projectDir @param {PackageJson | undefined} packageJson @returns {boolean} */
|
|
@@ -27,7 +27,7 @@ export async function editorConnection(command, config, userSettings, pluginsArr
|
|
|
27
27
|
if (typeof config.generator === "string" && !config.generator.includes("Unity")) return;
|
|
28
28
|
|
|
29
29
|
if (!config) {
|
|
30
|
-
setTimeout(() => needleLog("needle-editor-sync", "Needle Editor Sync can not be installed automatically to vite: missing config", "warn"), 1000);
|
|
30
|
+
setTimeout(() => needleLog("needle-editor-sync", "Needle Editor Sync can not be installed automatically to vite: missing config", "warn"), 1000).unref();
|
|
31
31
|
return createPlugin(false);
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -42,14 +42,14 @@ export async function editorConnection(command, config, userSettings, pluginsArr
|
|
|
42
42
|
// }
|
|
43
43
|
// }
|
|
44
44
|
if (needleEditorSettings && needleEditorSettings.enabled === false) {
|
|
45
|
-
setTimeout(() => needleLog("needle-editor-sync", "Needle Editor Sync is not enabled. Add a 'Needle Editor Sync' component to your scene to enable", "warn"), 1000);
|
|
45
|
+
setTimeout(() => needleLog("needle-editor-sync", "Needle Editor Sync is not enabled. Add a 'Needle Editor Sync' component to your scene to enable", "warn"), 1000).unref();
|
|
46
46
|
return createPlugin(false);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
// Check if the editor package is installed
|
|
50
50
|
let path = root + `/node_modules/${editorSyncPackageName}/plugins/index.js`;
|
|
51
51
|
if (existsSync(path) === false) {
|
|
52
|
-
setTimeout(() => needleLog("needle-editor-sync", `${editorSyncPackageName} is not installed: Add the "Needle Editor Sync" component to your scene if you want to send changes directly from the Unity Editor to web app`, "warn"), 1000);
|
|
52
|
+
setTimeout(() => needleLog("needle-editor-sync", `${editorSyncPackageName} is not installed: Add the "Needle Editor Sync" component to your scene if you want to send changes directly from the Unity Editor to web app`, "warn"), 1000).unref();
|
|
53
53
|
return createPlugin(false);
|
|
54
54
|
}
|
|
55
55
|
|
package/plugins/vite/license.js
CHANGED
|
@@ -8,7 +8,9 @@ import { loadConfig } from './config.js';
|
|
|
8
8
|
* @returns {import('vite').Plugin}
|
|
9
9
|
*/
|
|
10
10
|
export function needleLicense(command, config, userSettings) {
|
|
11
|
-
|
|
11
|
+
/** @type {import('../common/license.js').LicenseResult | null | undefined} */
|
|
12
|
+
let licenseResult = undefined;
|
|
13
|
+
let appliedLicense = false;
|
|
12
14
|
|
|
13
15
|
return {
|
|
14
16
|
name: "needle:license",
|
|
@@ -23,7 +25,7 @@ export function needleLicense(command, config, userSettings) {
|
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
licenseResult = await resolveLicense({
|
|
27
29
|
team: team,
|
|
28
30
|
accessToken: userSettings?.license?.accessToken,
|
|
29
31
|
loglevel: userSettings?.debugLicense === true ? "verbose" : undefined
|
|
@@ -31,25 +33,58 @@ export function needleLicense(command, config, userSettings) {
|
|
|
31
33
|
|
|
32
34
|
},
|
|
33
35
|
async transform(src, id) {
|
|
34
|
-
|
|
36
|
+
// Vite 4 and 8 handling:
|
|
37
|
+
const isNeedleEngineFile = id.includes("engine/engine_license")
|
|
38
|
+
|| id.includes("needle-tools_engine")
|
|
39
|
+
|| id.includes("@needle-tools")
|
|
40
|
+
|| id.includes("needle-engine");
|
|
35
41
|
// sometimes the actual license parameter is in a unnamed chunk file
|
|
36
42
|
const isViteChunkFile = id.includes("chunk") && id.includes(".vite");
|
|
37
43
|
if (isNeedleEngineFile || isViteChunkFile) {
|
|
38
44
|
|
|
39
|
-
if (!
|
|
45
|
+
if (!licenseResult) {
|
|
40
46
|
return;
|
|
41
47
|
}
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
let modified = false;
|
|
50
|
+
|
|
51
|
+
// Replace license type
|
|
52
|
+
const index = src.indexOf("_EubmJj");
|
|
44
53
|
if (index >= 0) {
|
|
45
54
|
const end = src.indexOf(";", index);
|
|
46
55
|
if (end >= 0) {
|
|
47
56
|
const line = src.substring(index, end);
|
|
48
|
-
const replaced = "
|
|
57
|
+
const replaced = "_EubmJj = \"" + licenseResult.type + "\"";
|
|
49
58
|
src = src.replace(line, replaced);
|
|
50
|
-
|
|
59
|
+
modified = true;
|
|
51
60
|
}
|
|
52
61
|
}
|
|
62
|
+
|
|
63
|
+
// Replace license JWT (same pattern)
|
|
64
|
+
if (licenseResult.jwt) {
|
|
65
|
+
const jwtIndex = src.indexOf("__OXddGMYg");
|
|
66
|
+
if (jwtIndex >= 0) {
|
|
67
|
+
const jwtEnd = src.indexOf(";", jwtIndex);
|
|
68
|
+
if (jwtEnd >= 0) {
|
|
69
|
+
const jwtLine = src.substring(jwtIndex, jwtEnd);
|
|
70
|
+
const jwtReplaced = "__OXddGMYg = \"" + licenseResult.jwt + "\"";
|
|
71
|
+
src = src.replace(jwtLine, jwtReplaced);
|
|
72
|
+
modified = true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (modified) {
|
|
78
|
+
appliedLicense = true;
|
|
79
|
+
return { code: src, map: null }
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
buildEnd() {
|
|
84
|
+
if (!appliedLicense) {
|
|
85
|
+
if (process.env.NEEDLE_TEST_ENV) {
|
|
86
|
+
console.error("ERR: License was not applied!");
|
|
87
|
+
}
|
|
53
88
|
}
|
|
54
89
|
}
|
|
55
90
|
}
|
|
@@ -291,7 +291,7 @@ export function needleMakeFilesLocal(command, _config, userSettings) {
|
|
|
291
291
|
failedDownloads,
|
|
292
292
|
localizationStats,
|
|
293
293
|
}, activeHandlers);
|
|
294
|
-
src = fixRelativeNewURL(src);
|
|
294
|
+
src = fixRelativeNewURL(src, viteConfig?.base);
|
|
295
295
|
}
|
|
296
296
|
catch (err) {
|
|
297
297
|
needleLog("needle:local-files", "Error in transform: " + getErrMessage(err), "error");
|
|
@@ -303,7 +303,7 @@ export function needleMakeFilesLocal(command, _config, userSettings) {
|
|
|
303
303
|
},
|
|
304
304
|
renderChunk(code, chunk) {
|
|
305
305
|
if (!chunk.fileName?.endsWith(".js")) return null;
|
|
306
|
-
const fixed = fixRelativeNewURL(code);
|
|
306
|
+
const fixed = fixRelativeNewURL(code, viteConfig?.base);
|
|
307
307
|
if (fixed === code) return null;
|
|
308
308
|
return {
|
|
309
309
|
code: fixed,
|
|
@@ -314,7 +314,7 @@ export function needleMakeFilesLocal(command, _config, userSettings) {
|
|
|
314
314
|
for (const output of Object.values(bundle)) {
|
|
315
315
|
if (output.type !== "chunk") continue;
|
|
316
316
|
if (!output.fileName?.endsWith(".js")) continue;
|
|
317
|
-
const fixed = fixRelativeNewURL(output.code);
|
|
317
|
+
const fixed = fixRelativeNewURL(output.code, viteConfig?.base);
|
|
318
318
|
if (fixed !== output.code) output.code = fixed;
|
|
319
319
|
}
|
|
320
320
|
},
|
|
@@ -24,9 +24,11 @@ export function normalizeWebPath(path: string): string;
|
|
|
24
24
|
export function ensureTrailingSlash(path: string): string;
|
|
25
25
|
/**
|
|
26
26
|
* @param {string} src
|
|
27
|
+
* @param {string} [base] - Vite base path (e.g. "/" or "/app/"). When provided,
|
|
28
|
+
* ext/ paths are made absolute so they resolve correctly under SPA routing.
|
|
27
29
|
* @returns {string}
|
|
28
30
|
*/
|
|
29
|
-
export function fixRelativeNewURL(src: string): string;
|
|
31
|
+
export function fixRelativeNewURL(src: string, base?: string): string;
|
|
30
32
|
/**
|
|
31
33
|
* @param {string} src
|
|
32
34
|
* @returns {string}
|
|
@@ -113,25 +113,49 @@ export function ensureTrailingSlash(path) {
|
|
|
113
113
|
|
|
114
114
|
/**
|
|
115
115
|
* @param {string} src
|
|
116
|
+
* @param {string} [base] - Vite base path (e.g. "/" or "/app/"). When provided,
|
|
117
|
+
* ext/ paths are made absolute so they resolve correctly under SPA routing.
|
|
116
118
|
* @returns {string}
|
|
117
119
|
*/
|
|
118
|
-
export function fixRelativeNewURL(src) {
|
|
120
|
+
export function fixRelativeNewURL(src, base) {
|
|
121
|
+
/** @param {string} path */
|
|
122
|
+
function makeAbsolute(path) {
|
|
123
|
+
// Strip any leading ./ ../ or / prefix to get the clean ext/... path
|
|
124
|
+
const clean = path.replace(/^(?:\.\.?\/)+/, '').replace(/^\//, '');
|
|
125
|
+
if (base) return base.replace(/\/+$/, '') + '/' + clean;
|
|
126
|
+
return clean;
|
|
127
|
+
}
|
|
128
|
+
|
|
119
129
|
src = src.replace(
|
|
120
130
|
/(?<==\s*)(["'])((?:(?:\.{1,2}\/)|\/)?ext\/[^"']*\/)\1/g,
|
|
121
131
|
(/** @type {string} */ _match, /** @type {string} */ quote, /** @type {string} */ path) => {
|
|
122
|
-
const
|
|
123
|
-
return `new URL(${quote}${
|
|
132
|
+
const resolved = makeAbsolute(path);
|
|
133
|
+
return `new URL(${quote}${resolved}${quote}, self.location?.href || ${quote}${quote}).href`;
|
|
124
134
|
}
|
|
125
135
|
);
|
|
126
136
|
|
|
127
137
|
src = src.replace(
|
|
128
138
|
/new\s+URL\s*\(\s*(["'`])((?:(?:\.{1,2}\/)|\/)?ext\/[^"'`]+)\1\s*\)/g,
|
|
129
139
|
(/** @type {string} */ _match, /** @type {string} */ quote, /** @type {string} */ path) => {
|
|
130
|
-
const
|
|
131
|
-
return `new URL(${quote}${
|
|
140
|
+
const resolved = makeAbsolute(path);
|
|
141
|
+
return `new URL(${quote}${resolved}${quote}, self.location?.href)`;
|
|
132
142
|
}
|
|
133
143
|
);
|
|
134
144
|
|
|
145
|
+
// Make remaining ext/ string literals absolute (e.g. font paths passed as
|
|
146
|
+
// function arguments like addVariant("normal","normal","ext/fonts/...")).
|
|
147
|
+
// The regexes above already consumed paths inside new URL() calls and
|
|
148
|
+
// assignment-based patterns, so this only catches leftover bare strings.
|
|
149
|
+
if (base) {
|
|
150
|
+
src = src.replace(
|
|
151
|
+
/(["'`])((?:\.{1,2}\/)?ext\/[^"'`]+)\1/g,
|
|
152
|
+
(/** @type {string} */ _match, /** @type {string} */ quote, /** @type {string} */ path) => {
|
|
153
|
+
const resolved = makeAbsolute(path);
|
|
154
|
+
return `${quote}${resolved}${quote}`;
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
135
159
|
return src;
|
|
136
160
|
}
|
|
137
161
|
|
package/plugins/vite/reload.js
CHANGED
|
@@ -7,6 +7,7 @@ import { existsSync, readFileSync, statSync } from 'fs';
|
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
8
|
import { needleLog } from './logging.js';
|
|
9
9
|
|
|
10
|
+
const pluginName = "needle-reload";
|
|
10
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
12
|
const __dirname = path.dirname(__filename);
|
|
12
13
|
|
|
@@ -39,7 +40,7 @@ export function needleReload(_command, config, userSettings) {
|
|
|
39
40
|
const buildDirectory = projectConfig?.buildDirectory?.length ? process.cwd().replaceAll("\\", "/") + "/" + projectConfig?.buildDirectory : "";
|
|
40
41
|
if (buildDirectory?.length) {
|
|
41
42
|
const relativeBuildDirectory = path.relative(process.cwd(), buildDirectory).replaceAll("\\", "/") || ".";
|
|
42
|
-
setTimeout(() => needleLog(
|
|
43
|
+
setTimeout(() => needleLog(pluginName, "Build directory: " + relativeBuildDirectory), 100);
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
// These ignore patterns will be injected into user config to better control vite reloading
|
|
@@ -59,7 +60,7 @@ export function needleReload(_command, config, userSettings) {
|
|
|
59
60
|
// @ts-ignore - watch.ignored is guaranteed to be string[] by the guards above
|
|
60
61
|
config.server.watch.ignored.push(pattern);
|
|
61
62
|
if (userSettings?.debug === true)
|
|
62
|
-
setTimeout(() => needleLog(
|
|
63
|
+
setTimeout(() => needleLog(pluginName, "Updated server ignore patterns: " + JSON.stringify(config.server?.watch?.ignored)), 100);
|
|
63
64
|
},
|
|
64
65
|
/** @param {import('vite').HmrContext & {buildDirectory?: string}} args */
|
|
65
66
|
handleHotUpdate(args) {
|
|
@@ -118,7 +119,7 @@ function getHot(server) {
|
|
|
118
119
|
|
|
119
120
|
/** @param {import('vite').ViteDevServer} server @param {string} [file] */
|
|
120
121
|
function notifyClientWillReload(server, file) {
|
|
121
|
-
|
|
122
|
+
needleLog(pluginName, "Send reload notification");
|
|
122
123
|
getHot(server).send('needle:reload', { type: 'will-reload', file: file });
|
|
123
124
|
}
|
|
124
125
|
|
|
@@ -134,7 +135,7 @@ async function handleReload({ file, server, modules: _modules, read, buildDirect
|
|
|
134
135
|
|
|
135
136
|
// Dont reload the whole server when a file that is using hot reload changes
|
|
136
137
|
if (filesUsingHotReload.has(file)) {
|
|
137
|
-
|
|
138
|
+
needleLog(pluginName, "File is using hot reload: " + file);
|
|
138
139
|
return null;
|
|
139
140
|
}
|
|
140
141
|
|
|
@@ -153,7 +154,7 @@ async function handleReload({ file, server, modules: _modules, read, buildDirect
|
|
|
153
154
|
// instead of relying on the vite server watch ignore array
|
|
154
155
|
// we could here also match paths that we know we dont want to track
|
|
155
156
|
if (ignorePatterns.length > 0 && ignoreRegex.test(file)) {
|
|
156
|
-
|
|
157
|
+
needleLog(pluginName, "Ignore change in file: " + getFileNameLog(file));
|
|
157
158
|
return [];
|
|
158
159
|
}
|
|
159
160
|
|
|
@@ -163,7 +164,7 @@ async function handleReload({ file, server, modules: _modules, read, buildDirect
|
|
|
163
164
|
if (buildDirectory?.length) {
|
|
164
165
|
const dir = path.dirname(file).replaceAll("\\", "/");
|
|
165
166
|
if (dir.startsWith(buildDirectory)) {
|
|
166
|
-
|
|
167
|
+
needleLog(pluginName, "Ignore change in build directory: " + getFileNameLog(file));
|
|
167
168
|
return [];
|
|
168
169
|
}
|
|
169
170
|
}
|
|
@@ -178,13 +179,13 @@ async function handleReload({ file, server, modules: _modules, read, buildDirect
|
|
|
178
179
|
return [];
|
|
179
180
|
}
|
|
180
181
|
if (await testIfFileContentChanged(file, read) === false) {
|
|
181
|
-
|
|
182
|
+
needleLog(pluginName, "File content didnt change: " + getFileNameLog(file));
|
|
182
183
|
return [];
|
|
183
184
|
}
|
|
184
185
|
}
|
|
185
186
|
|
|
186
187
|
// these are known file types we export from integrations
|
|
187
|
-
const knownExportFileTypes = [
|
|
188
|
+
const knownExportFileTypes = [".glb", ".gltf", ".bin", "exr", ".ktx2", ".mp3", ".ogg", ".mp4", ".webm"];
|
|
188
189
|
if (!knownExportFileTypes.some((type) => file.endsWith(type)))
|
|
189
190
|
return null;
|
|
190
191
|
|
|
@@ -208,7 +209,7 @@ async function handleReload({ file, server, modules: _modules, read, buildDirect
|
|
|
208
209
|
}
|
|
209
210
|
}
|
|
210
211
|
|
|
211
|
-
|
|
212
|
+
needleLog(pluginName, "> Detected file change: " + getFileNameLog(file) + " (" + ((fileSize / (1024 * 1024)).toFixed(1)) + " MB)");
|
|
212
213
|
notifyClientWillReload(server);
|
|
213
214
|
scheduleReload(server);
|
|
214
215
|
return [];
|
|
@@ -223,8 +224,8 @@ async function scheduleReload(server, level = 0) {
|
|
|
223
224
|
const lockFile = path.join(process.cwd(), lockFileName);
|
|
224
225
|
if (existsSync(lockFile)) {
|
|
225
226
|
if (level === 0)
|
|
226
|
-
|
|
227
|
-
setTimeout(() => scheduleReload(server, level += 1), 300);
|
|
227
|
+
needleLog(pluginName, "Lock file exists, waiting for export to finish...");
|
|
228
|
+
setTimeout(() => scheduleReload(server, level += 1), 300).unref();
|
|
228
229
|
return;
|
|
229
230
|
}
|
|
230
231
|
|
|
@@ -234,13 +235,13 @@ async function scheduleReload(server, level = 0) {
|
|
|
234
235
|
if (timeDiff < 1000) {
|
|
235
236
|
// Sometimes file changes happen immediately after triggering a reload
|
|
236
237
|
// we dont want to reload again in that case
|
|
237
|
-
|
|
238
|
+
needleLog(pluginName, "Ignoring reload, last reload was too recent" + timeDiff + "ms ago");
|
|
238
239
|
return;
|
|
239
240
|
}
|
|
240
241
|
|
|
241
242
|
lastReloadTime = Date.now();
|
|
242
243
|
const readableTime = new Date(lastReloadTime).toLocaleTimeString();
|
|
243
|
-
|
|
244
|
+
needleLog(pluginName, "< Reloading... " + readableTime);
|
|
244
245
|
getHot(server).send({
|
|
245
246
|
type: 'full-reload',
|
|
246
247
|
path: '*'
|
|
@@ -299,10 +300,10 @@ function removeVersionQueryArgument(content) {
|
|
|
299
300
|
function insertScriptRegisterHotReloadCode(src, filePath) {
|
|
300
301
|
|
|
301
302
|
// We only want to inject the hot reload code in the needle-engine root file
|
|
302
|
-
if(!filePath.includes("/src/needle-engine.ts")) {
|
|
303
|
+
if (!filePath.includes("/src/needle-engine.ts")) {
|
|
303
304
|
return src;
|
|
304
305
|
}
|
|
305
|
-
|
|
306
|
+
needleLog(pluginName, "[Needle HMR] Hot reload is enabled");
|
|
306
307
|
// this code let's the engine know that we are in hot reload mode
|
|
307
308
|
const code = `
|
|
308
309
|
globalThis.NEEDLE_HOT_RELOAD_ENABLED = true;
|
|
@@ -338,12 +339,12 @@ function insertScriptHotReloadCode(src, filePath) {
|
|
|
338
339
|
return undefined;
|
|
339
340
|
// make import path from engine package
|
|
340
341
|
const fullPathToHotReload = process.cwd() + "/node_modules/@needle-tools/engine/src/engine/engine_hot_reload.ts";
|
|
341
|
-
//
|
|
342
|
+
// needleLog(pluginName, fullPathToHotReload);
|
|
342
343
|
const fileDirectory = path.dirname(filePath);
|
|
343
|
-
//
|
|
344
|
+
// needleLog(pluginName, "DIR", fileDirectory)
|
|
344
345
|
const relativePath = path.relative(fileDirectory, fullPathToHotReload);
|
|
345
346
|
importPath = relativePath.replace(/\\/g, "/");
|
|
346
|
-
//
|
|
347
|
+
// needleLog(pluginName, "importPath: ", importPath);
|
|
347
348
|
}
|
|
348
349
|
|
|
349
350
|
// console.log(importPath, ">", filePath);
|
package/plugins/vite/server.js
CHANGED
|
@@ -60,7 +60,8 @@ export function needleServer(command, config, userSettings) {
|
|
|
60
60
|
})
|
|
61
61
|
.catch((err) => console.error("ERR: [needle:server] 'open' package not found - please make sure to install 'open' in your package.json\n", err));
|
|
62
62
|
}
|
|
63
|
-
}, 100)
|
|
63
|
+
}, 100);
|
|
64
|
+
i.unref();
|
|
64
65
|
}
|
|
65
66
|
},
|
|
66
67
|
}
|