@needle-tools/engine 5.1.0-canary.deec6e4 → 5.1.0-canary.e6680fa
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 +99 -1
- package/SKILL.md +4 -1
- package/components.needle.json +1 -1
- package/dist/needle-engine.bundle-Bl_hyH5G.umd.cjs +1734 -0
- package/dist/needle-engine.bundle-Cduc1gj6.min.js +1734 -0
- package/dist/{needle-engine.bundle-CvtELXh0.js → needle-engine.bundle-DNcqT8nJ.js} +19415 -18452
- package/dist/needle-engine.d.ts +1588 -374
- package/dist/needle-engine.js +572 -569
- 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/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 +21 -8
- package/lib/engine/engine_context.js +46 -16
- 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 +7 -7
- 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_pmrem.js +51 -3
- package/lib/engine/engine_pmrem.js.map +1 -1
- package/lib/engine/engine_scenedata.js +2 -2
- package/lib/engine/engine_scenedata.js.map +1 -1
- package/lib/engine/engine_serialization_builtin_serializer.js +28 -5
- 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_format.js +20 -14
- package/lib/engine/engine_utils_format.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/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 +2 -119
- package/lib/engine-components/AnimatorController.js +33 -232
- 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/Camera.d.ts +6 -1
- package/lib/engine-components/Camera.js +16 -3
- package/lib/engine-components/Camera.js.map +1 -1
- package/lib/engine-components/CameraUtils.js +14 -6
- package/lib/engine-components/CameraUtils.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 +4 -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 +9 -1
- 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 +1 -2
- package/lib/engine-components/OrbitControls.js +37 -14
- package/lib/engine-components/OrbitControls.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/VideoPlayer.d.ts +8 -2
- package/lib/engine-components/VideoPlayer.js +42 -19
- package/lib/engine-components/VideoPlayer.js.map +1 -1
- package/lib/engine-components/Voip.d.ts +16 -7
- package/lib/engine-components/Voip.js +90 -53
- package/lib/engine-components/Voip.js.map +1 -1
- package/lib/engine-components/api.d.ts +3 -1
- package/lib/engine-components/api.js +3 -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/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 +55 -12
- package/plugins/common/worker.js +9 -4
- package/plugins/types/userconfig.d.ts +4 -1
- package/plugins/vite/asap.js +17 -8
- package/plugins/vite/build-pipeline.js +57 -20
- 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 +1 -1
- 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/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 +52 -19
- 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 +7 -7
- 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_pmrem.ts +53 -3
- package/src/engine/engine_scenedata.ts +3 -3
- package/src/engine/engine_serialization_builtin_serializer.ts +32 -9
- 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_format.ts +20 -14
- package/src/engine/engine_utils_qrcode.ts +2 -2
- package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
- 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 +20 -291
- package/src/engine-components/AudioSource.ts +130 -79
- package/src/engine-components/Camera.ts +16 -3
- package/src/engine-components/CameraUtils.ts +12 -5
- 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 +4 -0
- package/src/engine-components/EventList.ts +45 -83
- package/src/engine-components/Joints.ts +20 -4
- package/src/engine-components/Light.ts +10 -2
- package/src/engine-components/Networking.ts +1 -1
- package/src/engine-components/OrbitControls.ts +42 -16
- 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/VideoPlayer.ts +40 -17
- package/src/engine-components/Voip.ts +88 -53
- package/src/engine-components/api.ts +3 -1
- package/src/engine-components/codegen/components.ts +7 -13
- package/src/engine-components/export/usdz/USDZExporter.ts +4 -4
- 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-1s2gOoKZ.min.js +0 -1732
- package/dist/needle-engine.bundle-j4nGJXCs.umd.cjs +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,35 +86,71 @@ 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("_Ktp");
|
|
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 = "_Ktp = \"" + 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("_HXKeIG");
|
|
113
|
+
if (jwtIndex >= 0) {
|
|
114
|
+
const jwtEnd = code.indexOf(";", jwtIndex);
|
|
115
|
+
if (jwtEnd >= 0) {
|
|
116
|
+
const jwtLine = code.substring(jwtIndex, jwtEnd);
|
|
117
|
+
const jwtReplaced = "_HXKeIG = \"" + licenseResult.jwt + "\"";
|
|
118
|
+
code = code.replace(jwtLine, jwtReplaced);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
107
121
|
}
|
|
108
122
|
}
|
|
109
123
|
return code;
|
|
110
124
|
}
|
|
111
125
|
|
|
112
126
|
/**
|
|
113
|
-
*
|
|
127
|
+
* Module-level cache keyed by `team:accessToken`. The license is stable for
|
|
128
|
+
* the lifetime of the process, so multiple callers (license plugin, build
|
|
129
|
+
* pipeline) share one fetch.
|
|
130
|
+
* @type {Map<string, Promise<LicenseResult | null>>}
|
|
131
|
+
*/
|
|
132
|
+
const licenseCache = new Map();
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Resolve the license using the needle engine licensing server.
|
|
136
|
+
* Memoized per (team, accessToken).
|
|
114
137
|
* @param {DefaultOptions & {accessToken?:string, team?:string} | null} args
|
|
115
|
-
* @returns {Promise<
|
|
138
|
+
* @returns {Promise<LicenseResult | null>}
|
|
116
139
|
*/
|
|
117
|
-
export
|
|
140
|
+
export function resolveLicense(args = null) {
|
|
141
|
+
const cacheKey = `${args?.team || ""}:${args?.accessToken || ""}`;
|
|
142
|
+
const cached = licenseCache.get(cacheKey);
|
|
143
|
+
if (cached) return cached;
|
|
144
|
+
const promise = resolveLicenseUncached(args);
|
|
145
|
+
licenseCache.set(cacheKey, promise);
|
|
146
|
+
return promise;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @param {DefaultOptions & {accessToken?:string, team?:string} | null} args
|
|
151
|
+
* @returns {Promise<LicenseResult | null>}
|
|
152
|
+
*/
|
|
153
|
+
async function resolveLicenseUncached(args = null) {
|
|
118
154
|
let accessToken = args?.accessToken;
|
|
119
155
|
|
|
120
156
|
// If a process.env.NEEDLE_CLOUD_TOKEN is set we want to use this (e.g. via nextjs)
|
|
@@ -210,7 +246,7 @@ export async function resolveLicense(args = null) {
|
|
|
210
246
|
return null;
|
|
211
247
|
}
|
|
212
248
|
else if (!licenseResponse.ok) {
|
|
213
|
-
if (licenseResponse.status
|
|
249
|
+
if (licenseResponse.status >= 500)
|
|
214
250
|
logLicense(`ERROR: Failed to fetch license (${licenseResponse.status})`, "error");
|
|
215
251
|
else
|
|
216
252
|
logLicense(`No license found (${licenseResponse.status})`);
|
|
@@ -226,10 +262,11 @@ export async function resolveLicense(args = null) {
|
|
|
226
262
|
/**
|
|
227
263
|
* @param {string} str License string
|
|
228
264
|
* @param {{includeFetchLine?: boolean}} [options]
|
|
265
|
+
* @returns {LicenseResult | null}
|
|
229
266
|
*/
|
|
230
267
|
function tryParseLicense(str, options = undefined) {
|
|
231
268
|
try {
|
|
232
|
-
/** @type {{needle_engine_license:string}} */
|
|
269
|
+
/** @type {{needle_engine_license:string, needle_license_jwt?:string}} */
|
|
233
270
|
const licenseJson = JSON.parse(str);
|
|
234
271
|
if (licenseJson.needle_engine_license) {
|
|
235
272
|
const success = `INFO: Successfully received \"${licenseJson.needle_engine_license?.toUpperCase()}\" license`;
|
|
@@ -239,7 +276,10 @@ function tryParseLicense(str, options = undefined) {
|
|
|
239
276
|
else {
|
|
240
277
|
logLicense(success);
|
|
241
278
|
}
|
|
242
|
-
return
|
|
279
|
+
return {
|
|
280
|
+
type: licenseJson.needle_engine_license,
|
|
281
|
+
jwt: licenseJson.needle_license_jwt || null,
|
|
282
|
+
};
|
|
243
283
|
}
|
|
244
284
|
if ("error" in licenseJson) {
|
|
245
285
|
logLicense(`ERROR in license check: \"${licenseJson.error}\"`, "error");
|
|
@@ -361,7 +401,10 @@ export async function getPublicIdentifier(project_id, opts = undefined) {
|
|
|
361
401
|
return null;
|
|
362
402
|
}
|
|
363
403
|
else if (!res.ok) {
|
|
364
|
-
|
|
404
|
+
if (res.status >= 500)
|
|
405
|
+
logIdentifier(`Failed to fetch project identifier (${res.status})`, "error");
|
|
406
|
+
else
|
|
407
|
+
logIdentifier(`No project identifier found (${res.status})`);
|
|
365
408
|
await releaseResponse(res);
|
|
366
409
|
return null;
|
|
367
410
|
}
|
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
|
});
|
|
@@ -82,7 +82,10 @@ export type userSettings = {
|
|
|
82
82
|
*/
|
|
83
83
|
version?: string;
|
|
84
84
|
|
|
85
|
-
/** If defined the access token will be used to run compression on Needle Cloud
|
|
85
|
+
/** If defined the access token will be used to run compression on Needle Cloud.
|
|
86
|
+
*
|
|
87
|
+
* Expected to be a Needle Cloud access token (created in the Needle Cloud UI),
|
|
88
|
+
* NOT a JWT. Do not pass a licensing JWT here. */
|
|
86
89
|
accessToken?: string | undefined;
|
|
87
90
|
|
|
88
91
|
/**
|
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: {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ChildProcess, exec } from 'child_process';
|
|
2
2
|
import { NEEDLE_CLOUD_CLI_NAME } from '../common/cloud.js';
|
|
3
|
+
import { resolveLicense } from '../common/license.js';
|
|
3
4
|
import { getOutputDirectory, loadConfig } from './config.js';
|
|
4
5
|
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'fs';
|
|
5
6
|
import { relative } from 'path';
|
|
@@ -10,6 +11,8 @@ import { needleBlue, needleDim, needleLog, needleSupportsColor, setTransientLogL
|
|
|
10
11
|
const PIPELINE_SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
11
12
|
const PIPELINE_STRUCTURED_LOG_PREFIX = "__needle_pipeline_log__:";
|
|
12
13
|
|
|
14
|
+
// #region Validation
|
|
15
|
+
|
|
13
16
|
/**
|
|
14
17
|
* @param {import('../types').userSettings} config
|
|
15
18
|
* @returns {boolean}
|
|
@@ -37,8 +40,11 @@ env:
|
|
|
37
40
|
return true;
|
|
38
41
|
}
|
|
39
42
|
|
|
43
|
+
// #endregion
|
|
44
|
+
|
|
40
45
|
// see https://linear.app/needle/issue/NE-3798
|
|
41
46
|
|
|
47
|
+
// #region State
|
|
42
48
|
|
|
43
49
|
/** @type {Promise<void>|null} */
|
|
44
50
|
let buildPipelineTask;
|
|
@@ -87,6 +93,10 @@ function increaseMaxWaitTime(debugLog) {
|
|
|
87
93
|
}
|
|
88
94
|
}
|
|
89
95
|
|
|
96
|
+
// #endregion
|
|
97
|
+
|
|
98
|
+
// #region Plugin
|
|
99
|
+
|
|
90
100
|
/** Runs the needle build pipeline as part of the vite build process.
|
|
91
101
|
* @param {"build" | "serve"} command
|
|
92
102
|
* @param {import('../types/needleConfig').needleMeta | null | undefined} config
|
|
@@ -237,9 +247,12 @@ export async function needleBuildPipeline(command, config, userSettings) {
|
|
|
237
247
|
}
|
|
238
248
|
}
|
|
239
249
|
|
|
250
|
+
// #endregion
|
|
251
|
+
|
|
252
|
+
// #region Migration
|
|
240
253
|
|
|
241
254
|
/**
|
|
242
|
-
* Previously we did always install the build pipeline and run an extra command to invoke the build pipeline.
|
|
255
|
+
* Previously we did always install the build pipeline and run an extra command to invoke the build pipeline.
|
|
243
256
|
* This is now done automatically by the needle build pipeline plugin - so we update all legacy projects to use the new method.
|
|
244
257
|
* @param {string} packageJsonPath
|
|
245
258
|
*/
|
|
@@ -258,6 +271,10 @@ async function fixPackageJson(packageJsonPath) {
|
|
|
258
271
|
writeFileSync(packageJsonPath, fixed);
|
|
259
272
|
}
|
|
260
273
|
|
|
274
|
+
// #endregion
|
|
275
|
+
|
|
276
|
+
// #region Logging
|
|
277
|
+
|
|
261
278
|
/** @param {...unknown} args */
|
|
262
279
|
function log(...args) {
|
|
263
280
|
needleLog("needle-buildpipeline", args.join(" "));
|
|
@@ -267,11 +284,15 @@ function warn(...args) {
|
|
|
267
284
|
needleLog("needle-buildpipeline", args.join(" "), "warn");
|
|
268
285
|
}
|
|
269
286
|
|
|
287
|
+
// #endregion
|
|
288
|
+
|
|
289
|
+
// #region Execution
|
|
290
|
+
|
|
270
291
|
/**
|
|
271
292
|
* @typedef {{ event?: string, phase?: string, target?: string, message?: string, level?: string }} BuildPipelinePayload
|
|
272
293
|
*/
|
|
273
294
|
/**
|
|
274
|
-
* @param {import('../types').userSettings} opts
|
|
295
|
+
* @param {import('../types').userSettings} opts
|
|
275
296
|
* @param {{verbose?:boolean}} [options]
|
|
276
297
|
* @returns {Promise<boolean>}
|
|
277
298
|
*/
|
|
@@ -283,12 +304,7 @@ async function invokeBuildPipeline(opts, options = {}) {
|
|
|
283
304
|
const supportsColor = needleSupportsColor();
|
|
284
305
|
const key = (/** @type {string} */ text) => supportsColor ? needleBlue(text) : text;
|
|
285
306
|
|
|
286
|
-
|
|
287
|
-
const fullInstallPath = process.cwd() + "/" + installPath;
|
|
288
|
-
const existsLocally = existsSync(fullInstallPath);
|
|
289
|
-
if (existsLocally) {
|
|
290
|
-
log("Found local installation at " + fullInstallPath);
|
|
291
|
-
}
|
|
307
|
+
// #region Wait for output
|
|
292
308
|
await delay(500);
|
|
293
309
|
const outputDirectory = getOutputDirectory() + "/assets";
|
|
294
310
|
const startWaitTime = Date.now();
|
|
@@ -332,17 +348,18 @@ async function invokeBuildPipeline(opts, options = {}) {
|
|
|
332
348
|
`${key("Files to process")}: ${files.length} in ${rel(outputDirectory)}, ${formatBytes(filesBytes)}`,
|
|
333
349
|
existsSync(process.cwd() + "/node_modules/.needle/build-pipeline/output") ? needleDim("Removing temporary output directory") : undefined,
|
|
334
350
|
].filter(Boolean), "log", { dimBody: false });
|
|
351
|
+
// #endregion
|
|
352
|
+
|
|
353
|
+
// #region Setup
|
|
335
354
|
|
|
336
355
|
/** @type {null | ChildProcess} */
|
|
337
356
|
let proc = null;
|
|
338
357
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
}
|
|
358
|
+
// Cloud token used by `${NEEDLE_CLOUD_CLI_NAME} optimize --token <token>`.
|
|
359
|
+
// This is a Needle Cloud access token (created in the Needle Cloud UI), NOT a JWT.
|
|
360
|
+
const cloudAccessToken = opts.buildPipeline?.accessToken;
|
|
343
361
|
const runInCloud = typeof cloudAccessToken === "string" && cloudAccessToken.length > 0;
|
|
344
|
-
|
|
345
|
-
// or perhaps log an error / prevent the build from running completely
|
|
362
|
+
|
|
346
363
|
if (opts.buildPipeline && !runInCloud && process.env.CI) {
|
|
347
364
|
warn(`No cloud access token found. Please set it via process.env.NEEDLE_CLOUD_TOKEN`);
|
|
348
365
|
return false;
|
|
@@ -367,6 +384,10 @@ async function invokeBuildPipeline(opts, options = {}) {
|
|
|
367
384
|
}
|
|
368
385
|
}
|
|
369
386
|
|
|
387
|
+
// #endregion
|
|
388
|
+
|
|
389
|
+
// #region Run
|
|
390
|
+
|
|
370
391
|
// allow running the build pipeline in the cloud. It requires and access token to be set in the vite.config.js
|
|
371
392
|
// this can be set via e.g. process.env.NEEDLE_CLOUD_TOKEN
|
|
372
393
|
const commandEnv = { ...process.env, NEEDLE_PIPELINE_STRUCTURED_LOGS: "1" };
|
|
@@ -393,11 +414,6 @@ async function invokeBuildPipeline(opts, options = {}) {
|
|
|
393
414
|
log(`Running compression in cloud ⛅ using access token: ${obfuscatedToken}`);
|
|
394
415
|
proc = exec(cmd, { env: commandEnv });
|
|
395
416
|
}
|
|
396
|
-
else if (existsLocally) {
|
|
397
|
-
const cmd = `needle-gltf transform "${outputDirectory}" \"${tempOutputPath}\"`;
|
|
398
|
-
log("Running command \"" + cmd + "\" at " + process.cwd() + "...");
|
|
399
|
-
proc = exec(cmd, { cwd: installPath, env: commandEnv });
|
|
400
|
-
}
|
|
401
417
|
else {
|
|
402
418
|
// First check if the user passed in a specific version to use via the vite config
|
|
403
419
|
let version = opts.buildPipeline?.version;
|
|
@@ -424,10 +440,21 @@ async function invokeBuildPipeline(opts, options = {}) {
|
|
|
424
440
|
if (!version) version = "stable";
|
|
425
441
|
|
|
426
442
|
const versionInfo = versionSource ? `'${version}' (${versionSource})` : `'${version}'`;
|
|
427
|
-
|
|
443
|
+
// needle-gltf 3.x requires a JWT via `--auth-token <jwt>` on every CLI invocation.
|
|
444
|
+
// The JWT comes from the needle license server — it is NOT the Needle Cloud access token.
|
|
445
|
+
const licenseResult = await resolveLicense({
|
|
446
|
+
team: opts.license?.team,
|
|
447
|
+
accessToken: opts.license?.accessToken,
|
|
448
|
+
loglevel: opts.debugLicense === true ? "verbose" : undefined,
|
|
449
|
+
});
|
|
450
|
+
const authTokenArg = licenseResult?.jwt ? ` --auth-token ${licenseResult.jwt}` : "";
|
|
451
|
+
const cmd = `npx --yes @needle-tools/gltf-build-pipeline@${version} transform "${outputDirectory}" \"${tempOutputPath}\"${authTokenArg}`;
|
|
428
452
|
log(`Running compression locally using version ${versionInfo}`);
|
|
429
453
|
proc = exec(cmd, { env: commandEnv });
|
|
430
454
|
}
|
|
455
|
+
// #endregion
|
|
456
|
+
|
|
457
|
+
// #region Output
|
|
431
458
|
let pipelineSpinnerIndex = 0;
|
|
432
459
|
let pipelineSpinnerActive = false;
|
|
433
460
|
let transformStepCount = 0;
|
|
@@ -550,6 +577,9 @@ async function invokeBuildPipeline(opts, options = {}) {
|
|
|
550
577
|
}
|
|
551
578
|
proc.stdout?.on('data', onLog);
|
|
552
579
|
proc.stderr?.on('data', onLog);
|
|
580
|
+
// #endregion
|
|
581
|
+
|
|
582
|
+
// #region Exit
|
|
553
583
|
return new Promise((resolve, reject) => {
|
|
554
584
|
proc.on('exit', (code) => {
|
|
555
585
|
clearPipelineProgress();
|
|
@@ -570,8 +600,13 @@ async function invokeBuildPipeline(opts, options = {}) {
|
|
|
570
600
|
resolve(success);
|
|
571
601
|
});
|
|
572
602
|
});
|
|
603
|
+
// #endregion
|
|
573
604
|
}
|
|
574
605
|
|
|
606
|
+
// #endregion
|
|
607
|
+
|
|
608
|
+
// #region Helpers
|
|
609
|
+
|
|
575
610
|
/** @param {string | null | undefined} directory */
|
|
576
611
|
function getDirectoryStats(directory) {
|
|
577
612
|
if (!directory || !existsSync(directory)) return { fileCount: 0, totalBytes: 0 };
|
|
@@ -597,3 +632,5 @@ function getDirectoryStats(directory) {
|
|
|
597
632
|
}
|
|
598
633
|
return { fileCount, totalBytes };
|
|
599
634
|
}
|
|
635
|
+
|
|
636
|
+
// #endregion
|
|
@@ -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("_Ktp");
|
|
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 = "_Ktp = \"" + 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("_HXKeIG");
|
|
66
|
+
if (jwtIndex >= 0) {
|
|
67
|
+
const jwtEnd = src.indexOf(";", jwtIndex);
|
|
68
|
+
if (jwtEnd >= 0) {
|
|
69
|
+
const jwtLine = src.substring(jwtIndex, jwtEnd);
|
|
70
|
+
const jwtReplaced = "_HXKeIG = \"" + 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}
|