@needle-tools/engine 4.15.0-next.f391a30 → 4.15.0
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/components.needle.json +1 -1
- package/dist/{gltf-progressive-CTlvpS3A.js → gltf-progressive-Bm_6aEi4.js} +1 -1
- package/dist/{gltf-progressive-CMwJPwEt.umd.cjs → gltf-progressive-BttGBXw6.umd.cjs} +1 -1
- package/dist/{gltf-progressive-DYL3SLVb.min.js → gltf-progressive-T5WKTux5.min.js} +1 -1
- package/dist/materialx-CJyQZtjt.min.js +90 -0
- package/dist/materialx-DMs1E08Z.js +4636 -0
- package/dist/materialx-DaKKOoVk.umd.cjs +90 -0
- package/dist/{needle-engine.bundle-DsTdfmeb.min.js → needle-engine.bundle-CBq_OMnI.min.js} +122 -124
- package/dist/{needle-engine.bundle-DB4kLWO_.js → needle-engine.bundle-DGyiwNWR.js} +3226 -3232
- package/dist/{needle-engine.bundle-C1BFRZDF.umd.cjs → needle-engine.bundle-JN3eiiYc.umd.cjs} +113 -115
- package/dist/needle-engine.d.ts +52 -33
- package/dist/needle-engine.js +288 -287
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/{postprocessing-BN-f4viE.min.js → postprocessing-06AXuvdv.min.js} +1 -1
- package/dist/{postprocessing-De9ZpJrk.js → postprocessing-CI2x8Cln.js} +1 -1
- package/dist/{postprocessing-DYmYOVm4.umd.cjs → postprocessing-CPDcA21P.umd.cjs} +1 -1
- package/dist/{three-examples-BHqRVpO_.umd.cjs → three-examples-BMmNgNCN.umd.cjs} +12 -12
- package/dist/{three-examples-C0ZCCA_K.js → three-examples-CMYCd5nH.js} +192 -182
- package/dist/{three-examples-DmTY8tGr.min.js → three-examples-CQl1fFZp.min.js} +14 -14
- package/lib/engine/api.d.ts +2 -0
- package/lib/engine/api.js +2 -0
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/debug/debug.js +1 -1
- package/lib/engine/debug/debug.js.map +1 -1
- package/lib/engine/debug/debug_spatial_console.js +1 -1
- package/lib/engine/debug/debug_spatial_console.js.map +1 -1
- package/lib/engine/engine_accessibility.d.ts +1 -1
- package/lib/engine/engine_accessibility.js +1 -1
- package/lib/engine/engine_accessibility.js.map +1 -1
- package/lib/engine/engine_context.d.ts +1 -1
- package/lib/engine/engine_context.js +2 -2
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_create_objects.js +1 -1
- package/lib/engine/engine_create_objects.js.map +1 -1
- package/lib/engine/engine_gizmos.js +1 -1
- package/lib/engine/engine_gizmos.js.map +1 -1
- package/lib/engine/engine_license.js +2 -7
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_test_utils.d.ts +39 -0
- package/lib/engine/engine_test_utils.js +84 -0
- package/lib/engine/engine_test_utils.js.map +1 -0
- package/lib/engine/engine_utils.js +2 -2
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/export/gltf/index.js +1 -1
- package/lib/engine/export/gltf/index.js.map +1 -1
- package/lib/engine/webcomponents/logo-element.d.ts +3 -6
- package/lib/engine/webcomponents/logo-element.js +0 -18
- package/lib/engine/webcomponents/logo-element.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 +7 -10
- package/lib/engine/webcomponents/needle menu/needle-menu.js +4 -14
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js +1 -10
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +0 -3
- package/lib/engine/webcomponents/needle-engine.js +0 -10
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine-components/Component.js +1 -0
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/ReflectionProbe.d.ts +2 -24
- package/lib/engine-components/ReflectionProbe.js +2 -28
- package/lib/engine-components/ReflectionProbe.js.map +1 -1
- package/lib/engine-components/Skybox.js +2 -4
- package/lib/engine-components/Skybox.js.map +1 -1
- package/lib/engine-components/export/gltf/GltfExport.js +1 -1
- package/lib/engine-components/export/gltf/GltfExport.js.map +1 -1
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js +2 -2
- package/lib/engine-components/export/usdz/USDZExporter.js +1 -1
- package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/behavior/PhysicsExtension.js +2 -2
- package/lib/engine-components/export/usdz/extensions/behavior/PhysicsExtension.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
- package/lib/include/three/EXT_mesh_gpu_instancing_exporter.js.map +1 -0
- package/package.json +14 -18
- package/plugins/common/buildinfo.js +10 -46
- package/plugins/common/files.js +1 -2
- package/plugins/common/license.js +69 -144
- package/plugins/common/logger.js +11 -172
- package/plugins/common/worker.js +4 -5
- package/plugins/types/userconfig.d.ts +2 -40
- package/plugins/vite/alias.js +5 -6
- package/plugins/vite/asap.js +5 -6
- package/plugins/vite/build-pipeline.js +41 -224
- package/plugins/vite/buildinfo.js +6 -66
- package/plugins/vite/copyfiles.js +12 -41
- package/plugins/vite/custom-element-data.js +16 -26
- package/plugins/vite/defines.js +5 -8
- package/plugins/vite/dependencies.js +10 -16
- package/plugins/vite/dependency-watcher.js +7 -35
- package/plugins/vite/drop-client.js +5 -7
- package/plugins/vite/drop.js +14 -16
- package/plugins/vite/editor-connection.js +16 -18
- package/plugins/vite/imports-logger.js +2 -12
- package/plugins/vite/index.js +3 -8
- package/plugins/vite/local-files.js +441 -2
- package/plugins/vite/logger.client.js +35 -45
- package/plugins/vite/logger.js +3 -6
- package/plugins/vite/meta.js +4 -18
- package/plugins/vite/needle-app.js +3 -4
- package/plugins/vite/peer.js +1 -2
- package/plugins/vite/pwa.js +17 -33
- package/plugins/vite/reload.js +2 -24
- package/src/engine/api.ts +3 -0
- package/src/engine/debug/debug.ts +1 -1
- package/src/engine/debug/debug_spatial_console.ts +1 -5
- package/src/engine/engine_accessibility.ts +1 -2
- package/src/engine/engine_context.ts +2 -2
- package/src/engine/engine_create_objects.ts +1 -1
- package/src/engine/engine_gizmos.ts +5 -9
- package/src/engine/engine_license.ts +2 -7
- package/src/engine/engine_test_utils.ts +109 -0
- package/src/engine/engine_utils.ts +2 -2
- package/src/engine/export/gltf/index.ts +1 -1
- package/src/engine/webcomponents/logo-element.ts +3 -20
- package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +2 -6
- package/src/engine/webcomponents/needle menu/needle-menu.ts +11 -23
- package/src/engine/webcomponents/needle-engine.ar-overlay.ts +2 -13
- package/src/engine/webcomponents/needle-engine.ts +1 -13
- package/src/engine-components/Component.ts +2 -1
- package/src/engine-components/ReflectionProbe.ts +9 -33
- package/src/engine-components/Skybox.ts +2 -4
- package/src/engine-components/export/gltf/GltfExport.ts +1 -1
- package/src/engine-components/export/usdz/ThreeUSDZExporter.ts +2 -2
- package/src/engine-components/export/usdz/USDZExporter.ts +1 -1
- package/src/engine-components/export/usdz/extensions/behavior/PhysicsExtension.ts +2 -2
- package/src/include/draco/draco_decoder.js +34 -0
- package/src/include/draco/draco_decoder.wasm +0 -0
- package/src/include/draco/draco_wasm_wrapper.js +117 -0
- package/src/include/ktx2/basis_transcoder.js +19 -0
- package/src/include/ktx2/basis_transcoder.wasm +0 -0
- package/src/include/needle/arial-msdf.json +1472 -0
- package/src/include/needle/arial.png +0 -0
- package/src/include/needle/poweredbyneedle.webp +0 -0
- package/dist/materialx-4jJLLe9Q.js +0 -4174
- package/dist/materialx-Bt9FHwco.min.js +0 -158
- package/dist/materialx-NDD0y4JY.umd.cjs +0 -158
- package/lib/engine/export/gltf/EXT_mesh_gpu_instancing_exporter.js.map +0 -1
- package/plugins/common/needle-engine-skill.md +0 -175
- package/plugins/vite/ai.js +0 -71
- package/plugins/vite/local-files-analysis.js +0 -789
- package/plugins/vite/local-files-core.js +0 -992
- package/plugins/vite/local-files-internals.js +0 -28
- package/plugins/vite/local-files-types.d.ts +0 -111
- package/plugins/vite/local-files-utils.js +0 -359
- package/plugins/vite/logging.js +0 -129
- /package/lib/{engine/export/gltf → include/three}/EXT_mesh_gpu_instancing_exporter.d.ts +0 -0
- /package/lib/{engine/export/gltf → include/three}/EXT_mesh_gpu_instancing_exporter.js +0 -0
- /package/src/{engine/export/gltf → include/three}/EXT_mesh_gpu_instancing_exporter.js +0 -0
package/plugins/vite/logger.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-check
|
|
2
1
|
import { existsSync, readFileSync } from 'fs';
|
|
3
2
|
import path from 'path';
|
|
4
3
|
import { fileURLToPath } from 'url';
|
|
@@ -10,8 +9,6 @@ const __dirname = path.dirname(__filename);
|
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* write logs to local file
|
|
13
|
-
* @param {string} command
|
|
14
|
-
* @param {unknown} config
|
|
15
12
|
* @param {import('../types/userconfig.js').userSettings} userSettings
|
|
16
13
|
* @returns {import('vite').Plugin | null}
|
|
17
14
|
*/
|
|
@@ -21,7 +18,7 @@ export const needleLogger = (command, config, userSettings) => {
|
|
|
21
18
|
return null;
|
|
22
19
|
}
|
|
23
20
|
|
|
24
|
-
patchConsoleLogs(
|
|
21
|
+
patchConsoleLogs();
|
|
25
22
|
captureLogMessage("server", "info", "Vite started with command \"" + command + "\" in " + __dirname, null);
|
|
26
23
|
|
|
27
24
|
return {
|
|
@@ -54,7 +51,7 @@ export const needleLogger = (command, config, userSettings) => {
|
|
|
54
51
|
}
|
|
55
52
|
}
|
|
56
53
|
},
|
|
57
|
-
}
|
|
54
|
+
},
|
|
58
55
|
}
|
|
59
56
|
}
|
|
60
57
|
|
|
@@ -84,7 +81,7 @@ function logRequests(server, log_http_requests = false) {
|
|
|
84
81
|
});
|
|
85
82
|
});
|
|
86
83
|
// Client log messages via websocket
|
|
87
|
-
server.ws.on('needle:client-log', async (
|
|
84
|
+
server.ws.on('needle:client-log', async (data, client) => {
|
|
88
85
|
if (!data || !data.level || !data.message) {
|
|
89
86
|
console.warn("Received empty log data, ignoring");
|
|
90
87
|
return;
|
package/plugins/vite/meta.js
CHANGED
|
@@ -3,7 +3,6 @@ import fs from 'fs';
|
|
|
3
3
|
import { tryGetNeedleEngineVersion } from '../common/version.js';
|
|
4
4
|
import { loadConfig } from './config.js';
|
|
5
5
|
import { getPosterPath } from './poster.js';
|
|
6
|
-
import { needleGreenBold, needleLog } from './logging.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* @param {string} command
|
|
@@ -26,7 +25,7 @@ export const needleMeta = (command, config, userSettings) => {
|
|
|
26
25
|
name: 'needle:meta',
|
|
27
26
|
transformIndexHtml: {
|
|
28
27
|
order: 'pre',
|
|
29
|
-
handler(
|
|
28
|
+
handler(html, _ctx) {
|
|
30
29
|
|
|
31
30
|
if (userSettings.allowMetaPlugin === false) return [];
|
|
32
31
|
|
|
@@ -75,7 +74,7 @@ export const needleMeta = (command, config, userSettings) => {
|
|
|
75
74
|
tags.push({ tag: 'meta', attrs: { name: 'og:image:height', content: 1080 } });
|
|
76
75
|
}
|
|
77
76
|
else if (isBuild) {
|
|
78
|
-
|
|
77
|
+
console.warn(`Needle: meta.image is set but absolutePath is ${config.absolutePath} in userSettings. Skipping meta.image.`);
|
|
79
78
|
}
|
|
80
79
|
}
|
|
81
80
|
|
|
@@ -115,10 +114,10 @@ export const needleMeta = (command, config, userSettings) => {
|
|
|
115
114
|
const needleEngineVersion = tryGetNeedleEngineVersion();
|
|
116
115
|
if (needleEngineVersion) {
|
|
117
116
|
if (command === "build")
|
|
118
|
-
|
|
117
|
+
console.log("Needle Engine version: " + needleEngineVersion);
|
|
119
118
|
tags.push({ tag: 'meta', attrs: { name: 'needle-engine', content: needleEngineVersion } });
|
|
120
119
|
}
|
|
121
|
-
else
|
|
120
|
+
else console.log("WARN: could not find needle engine package.json")
|
|
122
121
|
|
|
123
122
|
tags.push({ tag: 'meta', attrs: { name: 'needle:buildtime', content: new Date().toISOString() } });
|
|
124
123
|
|
|
@@ -129,11 +128,6 @@ export const needleMeta = (command, config, userSettings) => {
|
|
|
129
128
|
}
|
|
130
129
|
|
|
131
130
|
|
|
132
|
-
/**
|
|
133
|
-
* @param {string} html
|
|
134
|
-
* @param {string} url
|
|
135
|
-
* @returns {string}
|
|
136
|
-
*/
|
|
137
131
|
function updateUrlMetaTag(html, url) {
|
|
138
132
|
const result = `<meta name="url" content="${url}">`;
|
|
139
133
|
html = html.replace(`<meta name="url" content="https://needle.tools">`, result);
|
|
@@ -141,21 +135,14 @@ function updateUrlMetaTag(html, url) {
|
|
|
141
135
|
return html;
|
|
142
136
|
}
|
|
143
137
|
|
|
144
|
-
/** @param {string} str @returns {string} */
|
|
145
138
|
function appendVersion(str) {
|
|
146
139
|
return str + "?v=" + Date.now();
|
|
147
140
|
}
|
|
148
141
|
|
|
149
|
-
/** @param {string} url @returns {string} */
|
|
150
142
|
function removeDuplicateSlashesInUrl(url) {
|
|
151
143
|
return url.replace(/([^:]\/)\/+/g, "$1");
|
|
152
144
|
}
|
|
153
145
|
|
|
154
|
-
/**
|
|
155
|
-
* @param {string} html
|
|
156
|
-
* @param {string} name
|
|
157
|
-
* @returns {string}
|
|
158
|
-
*/
|
|
159
146
|
function removeMetaTag(html, name) {
|
|
160
147
|
// TODO: maybe we could also just replace the content
|
|
161
148
|
const regex = new RegExp(`<meta (name|property)="${name}".+?\/?>`, 'gs');
|
|
@@ -167,7 +154,6 @@ function removeMetaTag(html, name) {
|
|
|
167
154
|
return newHtml;
|
|
168
155
|
}
|
|
169
156
|
|
|
170
|
-
/** @param {string} html @returns {string} */
|
|
171
157
|
function insertNeedleCredits(html) {
|
|
172
158
|
const needleCredits = `<!-- 🌵 Made with Needle — https://needle.tools -->`;
|
|
173
159
|
html = html.replace(
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { writeFile } from 'fs';
|
|
2
2
|
import { tryParseNeedleEngineSrcAttributeFromHtml } from '../common/needle-engine.js';
|
|
3
|
-
import { needleLog } from './logging.js';
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
|
|
@@ -55,15 +54,15 @@ export const needleApp = (command, config, userSettings) => {
|
|
|
55
54
|
const webComponent = generateNeedleEmbedWebComponent(path, main_asset);
|
|
56
55
|
await writeFile(`${outputDir}/needle-app.js`, webComponent, (err) => {
|
|
57
56
|
if (err) {
|
|
58
|
-
|
|
57
|
+
console.error("[needle-app] could not create needle-app.js", err);
|
|
59
58
|
}
|
|
60
59
|
else {
|
|
61
|
-
|
|
60
|
+
console.log("[needle-app] created needle-app.js");
|
|
62
61
|
}
|
|
63
62
|
});
|
|
64
63
|
}
|
|
65
64
|
catch (e) {
|
|
66
|
-
|
|
65
|
+
console.warn("WARN: could not create needle-app.js\n", e);
|
|
67
66
|
}
|
|
68
67
|
}
|
|
69
68
|
}
|
package/plugins/vite/peer.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const peerjsString = `/* needle: fix for peerjs */ window.global = window; var parcelRequire;`
|
|
2
|
-
import { needleLog } from './logging.js';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* @param {import('../types').userSettings} userSettings
|
|
@@ -81,7 +80,7 @@ function patchWebRTCAdapterForGemini(code, id) {
|
|
|
81
80
|
if(!didTransform) return undefined;
|
|
82
81
|
|
|
83
82
|
if(!didLog) {
|
|
84
|
-
|
|
83
|
+
console.log("[needle:peerjs] Fixed WebRTC assignment");
|
|
85
84
|
didLog = true;
|
|
86
85
|
}
|
|
87
86
|
|
package/plugins/vite/pwa.js
CHANGED
|
@@ -7,7 +7,6 @@ import { getPosterPath } from './poster.js';
|
|
|
7
7
|
const pwaErrorWithInstructions = "It seems that you're trying to build a PWA using 'vite-plugin-pwa'!\nNeedle can manage PWA settings for you – just pass the same 'pwaOptions' to the needlePlugins and VitePWA plugins:\n\n1. Install the vite PWA plugin: npm install vite-plugin-pwa --save-dev\n\n2. Then update your vite.config.js:\n\n import { VitePWA } from 'vite-plugin-pwa';\n ...\n needlePlugins(command, needleConfig, { pwa: pwaOptions }),\n VitePWA(pwaOptions),\n\nIf you want to manage PWA building yourself and skip this check, please pass '{ pwa: false }' to needlePlugins.";
|
|
8
8
|
|
|
9
9
|
/** Provides reasonable defaults for a PWA manifest and workbox settings.
|
|
10
|
-
* @param {string} command
|
|
11
10
|
* @param {import('../types').userSettings} userSettings
|
|
12
11
|
* @param {import("../types/needleConfig").needleMeta | null} config
|
|
13
12
|
* @returns {import('vite').Plugin | void}
|
|
@@ -72,7 +71,7 @@ export const needlePWA = (command, config, userSettings) => {
|
|
|
72
71
|
const customManifest = manifests.length > 0 ? manifests[0] : {};
|
|
73
72
|
|
|
74
73
|
// ensure we have proper icons/name/description to match user settings
|
|
75
|
-
processPWA(customManifest, context, pwaOptions, config, userSettings).catch(
|
|
74
|
+
processPWA(customManifest, context, pwaOptions, config, userSettings).catch(e => log("Error post processing PWA", customManifest, e));
|
|
76
75
|
// ensures we have a valid workbox config
|
|
77
76
|
processWorkboxConfig(pwaOptions);
|
|
78
77
|
|
|
@@ -82,15 +81,14 @@ export const needlePWA = (command, config, userSettings) => {
|
|
|
82
81
|
// for debugging
|
|
83
82
|
// log("PWA options", pwaOptions);
|
|
84
83
|
|
|
85
|
-
return
|
|
84
|
+
return {
|
|
86
85
|
name: 'needle:pwa',
|
|
87
86
|
apply: 'build',
|
|
88
87
|
enforce: "post",
|
|
89
|
-
config(
|
|
88
|
+
config(viteConfig) {
|
|
90
89
|
// Move the gzip plugin after PWA bundling
|
|
91
90
|
let gzipPluginIndex = -1;
|
|
92
91
|
let pwaPluginIndex = -1;
|
|
93
|
-
/** @type {Record<string, unknown> | null} */
|
|
94
92
|
let gzipPlugin = null;
|
|
95
93
|
if (viteConfig.plugins) {
|
|
96
94
|
for (let i = viteConfig.plugins.length - 1; i >= 0; i--) {
|
|
@@ -170,7 +168,7 @@ export const needlePWA = (command, config, userSettings) => {
|
|
|
170
168
|
}
|
|
171
169
|
}
|
|
172
170
|
}
|
|
173
|
-
catch (
|
|
171
|
+
catch (err) {
|
|
174
172
|
cleanup(context);
|
|
175
173
|
throw err;
|
|
176
174
|
}
|
|
@@ -253,7 +251,7 @@ updateSW = registerSW({
|
|
|
253
251
|
try {
|
|
254
252
|
copyIcons(pwaOptions.manifest, outputDir);
|
|
255
253
|
}
|
|
256
|
-
catch (
|
|
254
|
+
catch (e) {
|
|
257
255
|
log("Error post processing PWA", e);
|
|
258
256
|
}
|
|
259
257
|
|
|
@@ -263,23 +261,20 @@ updateSW = registerSW({
|
|
|
263
261
|
console.log(msg);
|
|
264
262
|
}
|
|
265
263
|
}
|
|
266
|
-
}
|
|
264
|
+
}
|
|
267
265
|
}
|
|
268
266
|
|
|
269
267
|
/** Checks if the vite-plugin-pwa is present in the vite config
|
|
270
|
-
* @param {
|
|
268
|
+
* @param {import('vite').ResolvedConfig} config
|
|
271
269
|
* @returns {import('vite-plugin-pwa').VitePWAOptions | null}
|
|
272
270
|
*/
|
|
273
271
|
function findVitePWAPlugin(config) {
|
|
274
|
-
const plugins =
|
|
275
|
-
/** @param {unknown} p
|
|
276
|
-
* @returns {Record<string, unknown> | undefined}
|
|
277
|
-
*/
|
|
272
|
+
const plugins = config.plugins || [];
|
|
278
273
|
function _findVitePWAPlugin(p) {
|
|
279
274
|
if (Array.isArray(p))
|
|
280
|
-
return
|
|
281
|
-
if (
|
|
282
|
-
return
|
|
275
|
+
return p.find(_findVitePWAPlugin);
|
|
276
|
+
if (p?.name === "vite-plugin-pwa")
|
|
277
|
+
return p;
|
|
283
278
|
}
|
|
284
279
|
for (const plugin of plugins) {
|
|
285
280
|
const foundVitePWAPlugin = _findVitePWAPlugin(plugin);
|
|
@@ -288,7 +283,6 @@ function findVitePWAPlugin(config) {
|
|
|
288
283
|
return null;
|
|
289
284
|
}
|
|
290
285
|
|
|
291
|
-
/** @param {import('../types/index.d.ts').NeedlePWAProcessContext} context */
|
|
292
286
|
function cleanup(context) {
|
|
293
287
|
for (const file of context.generatedFiles) {
|
|
294
288
|
log("Cleanup generated file", file);
|
|
@@ -297,7 +291,6 @@ function cleanup(context) {
|
|
|
297
291
|
context.generatedFiles.length = 0;
|
|
298
292
|
}
|
|
299
293
|
|
|
300
|
-
/** @param {...unknown} args */
|
|
301
294
|
function log(...args) {
|
|
302
295
|
console.log("[needle-pwa]", ...args);
|
|
303
296
|
}
|
|
@@ -344,16 +337,10 @@ async function processPWA(webmanifestPath, context, pwaOptions, config, userSett
|
|
|
344
337
|
// pwaOptions.includeAssets = [...pwaOptions.includeAssets, ...manifest.icons?.map(i => i.src)];
|
|
345
338
|
|
|
346
339
|
const packageJsonPath = process.cwd() + "/package.json";
|
|
347
|
-
const packageJson =
|
|
340
|
+
const packageJson = existsSync(packageJsonPath) ? JSON.parse(readFileSync(packageJsonPath, 'utf8')) : {};
|
|
348
341
|
|
|
342
|
+
const name = packageJson.name;
|
|
349
343
|
const appName = config?.sceneName || packageJson.name || "Needle App";
|
|
350
|
-
const packageName = typeof packageJson.name === "string" && packageJson.name.length > 0
|
|
351
|
-
? packageJson.name
|
|
352
|
-
: appName;
|
|
353
|
-
const packageNameSanitized = packageName
|
|
354
|
-
.toLowerCase()
|
|
355
|
-
.replace(/[^a-z0-9\/\-]/g, '')
|
|
356
|
-
.replace("\/", ".");
|
|
357
344
|
const description = typeof config?.meta === "string"
|
|
358
345
|
? config.meta : config?.meta?.description
|
|
359
346
|
|| packageJson.description
|
|
@@ -364,11 +351,9 @@ async function processPWA(webmanifestPath, context, pwaOptions, config, userSett
|
|
|
364
351
|
// Use the same title as in NeedleMeta
|
|
365
352
|
name: appName,
|
|
366
353
|
short_name: appName,
|
|
367
|
-
id: "app.made-with-needle." +
|
|
354
|
+
id: "app.made-with-needle." + name.toLowerCase().replace(/[^a-z0-9\/\-]/g, '').replace("\/", "."),
|
|
368
355
|
description,
|
|
369
356
|
start_url: "./index.html",
|
|
370
|
-
theme_color: "#000000",
|
|
371
|
-
background_color: "#000000",
|
|
372
357
|
display: "standalone",
|
|
373
358
|
display_override: [
|
|
374
359
|
"window-controls-overlay",
|
|
@@ -438,7 +423,7 @@ function processIcons(manifest, outDir, context) {
|
|
|
438
423
|
modified = true;
|
|
439
424
|
}
|
|
440
425
|
}
|
|
441
|
-
catch (
|
|
426
|
+
catch (e) {
|
|
442
427
|
log("Error processing PWA icon[" + i + "]", e);
|
|
443
428
|
}
|
|
444
429
|
}
|
|
@@ -475,7 +460,6 @@ function generateIcons(manifest, context) {
|
|
|
475
460
|
/** Tries to copy the icons to the output directory
|
|
476
461
|
* TODO this should not be needed if we use pwaOptions.includeAssets
|
|
477
462
|
* @param {Partial<import("vite-plugin-pwa").ManifestOptions>} manifest
|
|
478
|
-
* @param {string} outDir
|
|
479
463
|
*/
|
|
480
464
|
function copyIcons(manifest, outDir) {
|
|
481
465
|
for (let i = 0; i < manifest.icons?.length; i++) {
|
|
@@ -508,7 +492,7 @@ function copyIcons(manifest, outDir) {
|
|
|
508
492
|
copyFileSync(srcPath, targetPath);
|
|
509
493
|
}
|
|
510
494
|
}
|
|
511
|
-
catch (
|
|
495
|
+
catch (e) {
|
|
512
496
|
log("Error processing PWA icon[" + i + "]", e);
|
|
513
497
|
}
|
|
514
498
|
}
|
|
@@ -598,7 +582,7 @@ function processWorkboxConfig(manifest) {
|
|
|
598
582
|
},
|
|
599
583
|
// allow caching local resources
|
|
600
584
|
{
|
|
601
|
-
urlPattern: (
|
|
585
|
+
urlPattern: ({ url }) => url,
|
|
602
586
|
// Apply a network-first strategy.
|
|
603
587
|
handler: 'NetworkFirst',
|
|
604
588
|
options: {
|
package/plugins/vite/reload.js
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
|
-
// @ts-check
|
|
2
1
|
import path from 'path';
|
|
3
2
|
import { loadConfig, tryLoadProjectConfig } from './config.js';
|
|
4
3
|
import { getPosterPath } from './poster.js';
|
|
5
4
|
import * as crypto from 'crypto';
|
|
6
5
|
import { existsSync, readFileSync, statSync } from 'fs';
|
|
7
6
|
import { fileURLToPath } from 'url';
|
|
8
|
-
import { needleLog } from './logging.js';
|
|
9
7
|
|
|
10
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
9
|
const __dirname = path.dirname(__filename);
|
|
12
10
|
|
|
13
|
-
/** @type {Set<string>} */
|
|
14
11
|
const filesUsingHotReload = new Set();
|
|
15
12
|
let assetsDirectory = "";
|
|
16
13
|
|
|
17
14
|
/**
|
|
18
|
-
* @param {string} command
|
|
19
|
-
* @param {import('../types').userSettings | null} config
|
|
20
15
|
* @param {import('../types').userSettings} userSettings
|
|
21
16
|
*/
|
|
22
17
|
export const needleReload = (command, config, userSettings) => {
|
|
@@ -39,8 +34,7 @@ export const needleReload = (command, config, userSettings) => {
|
|
|
39
34
|
|
|
40
35
|
const buildDirectory = projectConfig?.buildDirectory?.length ? process.cwd().replaceAll("\\", "/") + "/" + projectConfig?.buildDirectory : "";
|
|
41
36
|
if (buildDirectory?.length) {
|
|
42
|
-
|
|
43
|
-
setTimeout(() => needleLog("needle-reload", "Build directory: " + relativeBuildDirectory), 100);
|
|
37
|
+
setTimeout(() => console.log("Build directory: ", buildDirectory), 100);
|
|
44
38
|
}
|
|
45
39
|
|
|
46
40
|
// These ignore patterns will be injected into user config to better control vite reloading
|
|
@@ -50,7 +44,6 @@ export const needleReload = (command, config, userSettings) => {
|
|
|
50
44
|
|
|
51
45
|
return {
|
|
52
46
|
name: 'needle:reload',
|
|
53
|
-
/** @param {import('vite').UserConfig} config */
|
|
54
47
|
config(config) {
|
|
55
48
|
if (!config.server) config.server = { watch: { ignored: [] } };
|
|
56
49
|
else if (!config.server.watch) config.server.watch = { ignored: [] };
|
|
@@ -58,14 +51,12 @@ export const needleReload = (command, config, userSettings) => {
|
|
|
58
51
|
for (const pattern of ignorePatterns)
|
|
59
52
|
config.server.watch.ignored.push(pattern);
|
|
60
53
|
if (config?.debug === true || userSettings?.debug === true)
|
|
61
|
-
setTimeout(() =>
|
|
54
|
+
setTimeout(() => console.log("Updated server ignore patterns: ", config.server.watch.ignored), 100);
|
|
62
55
|
},
|
|
63
|
-
/** @param {{file: string, server: import('vite').ViteDevServer, modules: unknown[], read: (file?: string) => Promise<string>, buildDirectory?: string}} args */
|
|
64
56
|
handleHotUpdate(args) {
|
|
65
57
|
args.buildDirectory = buildDirectory;
|
|
66
58
|
return handleReload(args);
|
|
67
59
|
},
|
|
68
|
-
/** @param {string} src @param {string} id */
|
|
69
60
|
transform(src, id) {
|
|
70
61
|
if (!id.includes(".ts")) return;
|
|
71
62
|
updateConfig();
|
|
@@ -76,7 +67,6 @@ export const needleReload = (command, config, userSettings) => {
|
|
|
76
67
|
},
|
|
77
68
|
transformIndexHtml: {
|
|
78
69
|
order: 'pre',
|
|
79
|
-
/** @param {string} html @param {unknown} _ */
|
|
80
70
|
handler(html, _) {
|
|
81
71
|
if (config?.allowHotReload === false) return html;
|
|
82
72
|
if (userSettings?.allowHotReload === false) return html;
|
|
@@ -101,7 +91,6 @@ export const needleReload = (command, config, userSettings) => {
|
|
|
101
91
|
}
|
|
102
92
|
|
|
103
93
|
|
|
104
|
-
/** @type {string[]} */
|
|
105
94
|
const ignorePatterns = [];
|
|
106
95
|
const ignoreRegex = new RegExp(ignorePatterns.join("|"));
|
|
107
96
|
|
|
@@ -110,15 +99,11 @@ const posterPath = getPosterPath();
|
|
|
110
99
|
let reloadIsScheduled = false;
|
|
111
100
|
const lockFileName = "needle.lock";
|
|
112
101
|
|
|
113
|
-
/** @param {import('vite').ViteDevServer} server @param {string} [file] */
|
|
114
102
|
function notifyClientWillReload(server, file) {
|
|
115
103
|
console.log("Send reload notification");
|
|
116
104
|
server.ws.send('needle:reload', { type: 'will-reload', file: file });
|
|
117
105
|
}
|
|
118
106
|
|
|
119
|
-
/**
|
|
120
|
-
* @param {{file: string, server: import('vite').ViteDevServer, modules: unknown[], read: (file?: string) => Promise<string>, buildDirectory?: string}} param0
|
|
121
|
-
*/
|
|
122
107
|
async function handleReload({ file, server, modules, read, buildDirectory }) {
|
|
123
108
|
|
|
124
109
|
// dont reload the full page on css changes
|
|
@@ -206,7 +191,6 @@ async function handleReload({ file, server, modules, read, buildDirectory }) {
|
|
|
206
191
|
}
|
|
207
192
|
|
|
208
193
|
|
|
209
|
-
/** @param {import('vite').ViteDevServer} server @param {number} [level] */
|
|
210
194
|
async function scheduleReload(server, level = 0) {
|
|
211
195
|
if (reloadIsScheduled && level === 0) return;
|
|
212
196
|
reloadIsScheduled = true;
|
|
@@ -240,7 +224,6 @@ async function scheduleReload(server, level = 0) {
|
|
|
240
224
|
|
|
241
225
|
const projectDirectory = process.cwd().replaceAll("\\", "/");
|
|
242
226
|
|
|
243
|
-
/** @param {string} file @returns {string} */
|
|
244
227
|
function getFileNameLog(file) {
|
|
245
228
|
if (file.startsWith(projectDirectory)) {
|
|
246
229
|
return file.substring(projectDirectory.length);
|
|
@@ -248,11 +231,9 @@ function getFileNameLog(file) {
|
|
|
248
231
|
return file;
|
|
249
232
|
}
|
|
250
233
|
|
|
251
|
-
/** @type {Map<string, string>} */
|
|
252
234
|
const hashes = new Map();
|
|
253
235
|
const hash256 = crypto.createHash('sha256');
|
|
254
236
|
|
|
255
|
-
/** @param {string} file @param {(file?: string) => Promise<string>} read @returns {Promise<boolean>} */
|
|
256
237
|
async function testIfFileContentChanged(file, read) {
|
|
257
238
|
let content = await read(file);
|
|
258
239
|
content = removeVersionQueryArgument(content);
|
|
@@ -271,7 +252,6 @@ async function testIfFileContentChanged(file, read) {
|
|
|
271
252
|
}
|
|
272
253
|
return false;
|
|
273
254
|
}
|
|
274
|
-
/** @param {string} content @returns {string} */
|
|
275
255
|
function removeVersionQueryArgument(content) {
|
|
276
256
|
if (typeof content === "string") {
|
|
277
257
|
// Some codegen files include hashes for loading glb files (e.g. ?v=213213124)
|
|
@@ -286,7 +266,6 @@ function removeVersionQueryArgument(content) {
|
|
|
286
266
|
|
|
287
267
|
|
|
288
268
|
|
|
289
|
-
/** @param {string} src @param {string} filePath @returns {string} */
|
|
290
269
|
function insertScriptRegisterHotReloadCode(src, filePath) {
|
|
291
270
|
|
|
292
271
|
// We only want to inject the hot reload code in the needle-engine root file
|
|
@@ -305,7 +284,6 @@ globalThis.NEEDLE_HOT_RELOAD_ENABLED = true;
|
|
|
305
284
|
const HOT_RELOAD_START_MARKER = "NEEDLE_HOT_RELOAD_BEGIN";
|
|
306
285
|
const HOT_RELOAD_END_MARKER = "NEEDLE_HOT_RELOAD_END";
|
|
307
286
|
|
|
308
|
-
/** @param {string} src @param {string} filePath @returns {{code: string, map: null} | undefined} */
|
|
309
287
|
function insertScriptHotReloadCode(src, filePath) {
|
|
310
288
|
if (filePath.includes("engine_hot_reload")) return;
|
|
311
289
|
if (filePath.includes(".vite")) return;
|
package/src/engine/api.ts
CHANGED
|
@@ -354,6 +354,9 @@ export { type ISerializable } from "./engine_serialization_core.js";
|
|
|
354
354
|
// General-purpose utility functions and helpers.
|
|
355
355
|
// ============================================================================
|
|
356
356
|
|
|
357
|
+
/** Testing utilities for automated tests */
|
|
358
|
+
export * from "./engine_test_utils.js";
|
|
359
|
+
|
|
357
360
|
/** Texture utilities and processing */
|
|
358
361
|
export * from "./engine_texture.js";
|
|
359
362
|
|
|
@@ -8,7 +8,7 @@ export {
|
|
|
8
8
|
clearMessages as clearOverlayMessages,
|
|
9
9
|
LogType,
|
|
10
10
|
setAllowBalloonMessages,
|
|
11
|
-
// eslint-disable-next-line
|
|
11
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
12
12
|
setAllowOverlayMessages,
|
|
13
13
|
};
|
|
14
14
|
export { enableSpatialConsole } from "./debug_spatial_console.js";
|
|
@@ -169,11 +169,7 @@ class SpatialMessagesHandler {
|
|
|
169
169
|
|
|
170
170
|
if (!fontFamily) {
|
|
171
171
|
fontFamily = ThreeMeshUI.FontLibrary.addFontFamily(this.familyName);
|
|
172
|
-
const variant = fontFamily.addVariant(
|
|
173
|
-
"normal",
|
|
174
|
-
"normal",
|
|
175
|
-
"https://cdn.needle.tools/static/fonts/msdf/arial/arial-msdf.json",
|
|
176
|
-
"https://cdn.needle.tools/static/fonts/msdf/arial/arial.png") as any as ThreeMeshUI.FontVariant;
|
|
172
|
+
const variant = fontFamily.addVariant("normal", "normal", "./include/needle/arial-msdf.json", "./include/needle/arial.png") as any as ThreeMeshUI.FontVariant;
|
|
177
173
|
/** @ts-ignore */
|
|
178
174
|
variant?.addEventListener('ready', () => {
|
|
179
175
|
ThreeMeshUI.update();
|
|
@@ -15,7 +15,6 @@ import { nodeFrame } from "three/examples/jsm/renderers/webgl-legacy/nodes/WebGL
|
|
|
15
15
|
|
|
16
16
|
import { initSpectorIfAvailable } from './debug/debug_spector.js';
|
|
17
17
|
import { isDevEnvironment, LogType, showBalloonError, showBalloonMessage } from './debug/index.js';
|
|
18
|
-
import { AccessibilityManager } from './engine_accessibility.js';
|
|
19
18
|
import { Addressables } from './engine_addressables.js';
|
|
20
19
|
import { AnimationsRegistry } from './engine_animation.js';
|
|
21
20
|
import { Application } from './engine_application.js';
|
|
@@ -45,6 +44,7 @@ import { deepClone, delay, DeviceUtilities, getParam } from './engine_utils.js';
|
|
|
45
44
|
import type { INeedleXRSessionEventReceiver, NeedleXRSession } from './engine_xr.js';
|
|
46
45
|
import { NeedleMenu } from './webcomponents/needle menu/needle-menu.js';
|
|
47
46
|
import type { NeedleEngineWebComponent } from './webcomponents/needle-engine.js';
|
|
47
|
+
import { AccessibilityManager } from './engine_accessibility.js';
|
|
48
48
|
|
|
49
49
|
const debug = getParam("debugcontext");
|
|
50
50
|
const stats = getParam("stats");
|
|
@@ -565,7 +565,7 @@ export class Context implements IContext {
|
|
|
565
565
|
this.input = new Input(this);
|
|
566
566
|
this.physics = new Physics(this);
|
|
567
567
|
this.connection = new NetworkConnection(this);
|
|
568
|
-
// eslint-disable-next-line
|
|
568
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
569
569
|
this.assets = new AssetDatabase();
|
|
570
570
|
this.sceneLighting = new SceneLighting(this);
|
|
571
571
|
this.addressables = new Addressables(this);
|
|
@@ -338,7 +338,7 @@ function loadFont(family: string | null): Font | Promise<Font> {
|
|
|
338
338
|
url = "https://cdn.needle.tools/static/fonts/facetype/Open Sans_Regular_ascii.json";
|
|
339
339
|
break;
|
|
340
340
|
case "Helvetiker":
|
|
341
|
-
url = "https://
|
|
341
|
+
url = "https://raw.githubusercontent.com/mrdoob/three.js/master/examples/fonts/helvetiker_regular.typeface.json";
|
|
342
342
|
break;
|
|
343
343
|
}
|
|
344
344
|
if (fontsDict.has(url)) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Box3, BoxGeometry, BufferAttribute, BufferGeometry, Color, type ColorRepresentation, CylinderGeometry, EdgesGeometry, Line, LineBasicMaterial, LineSegments, Material, Matrix4, Mesh, MeshBasicMaterial, Object3D, Quaternion, SphereGeometry, Vector3 } from 'three';
|
|
2
|
-
import ThreeMeshUI, { Text } from "three-mesh-ui"
|
|
1
|
+
import { AxesHelper, Box3, BoxGeometry, BufferAttribute, BufferGeometry, Color, type ColorRepresentation, CylinderGeometry, EdgesGeometry, Line, LineBasicMaterial, LineSegments, Material, Matrix4, Mesh, MeshBasicMaterial, Object3D, Quaternion, SphereGeometry, Vector3 } from 'three';
|
|
2
|
+
import ThreeMeshUI, { Inline, Text } from "three-mesh-ui"
|
|
3
3
|
import { type Options } from 'three-mesh-ui/build/types/core/elements/MeshUIBaseElement.js';
|
|
4
4
|
|
|
5
5
|
import { isDestroyed } from './engine_gameobject.js';
|
|
6
|
-
import { Context } from './engine_setup.js';
|
|
7
|
-
import { getTempVector, lookAtObject, setWorldPositionXYZ } from './engine_three_utils.js';
|
|
6
|
+
import { Context, FrameEvent } from './engine_setup.js';
|
|
7
|
+
import { getTempVector, getWorldPosition, lookAtObject, setWorldPositionXYZ } from './engine_three_utils.js';
|
|
8
8
|
import type { Vec3, Vec4 } from './engine_types.js';
|
|
9
9
|
import { getParam } from './engine_utils.js';
|
|
10
10
|
import { NeedleXRSession } from './engine_xr.js';
|
|
@@ -341,11 +341,7 @@ class Internal {
|
|
|
341
341
|
|
|
342
342
|
if (!fontFamily) {
|
|
343
343
|
fontFamily = ThreeMeshUI.FontLibrary.addFontFamily(this.familyName);
|
|
344
|
-
const variant = fontFamily.addVariant(
|
|
345
|
-
"normal",
|
|
346
|
-
"normal",
|
|
347
|
-
"https://cdn.needle.tools/static/fonts/msdf/arial/arial-msdf.json",
|
|
348
|
-
"https://cdn.needle.tools/static/fonts/msdf/arial/arial.png");
|
|
344
|
+
const variant = fontFamily.addVariant("normal", "normal", "https://uploads.needle.tools/include/font-msdf.json", "https://uploads.needle.tools/include/font.png") as any as ThreeMeshUI.FontVariant;
|
|
349
345
|
/** @ts-ignore */
|
|
350
346
|
variant?.addEventListener('ready', () => {
|
|
351
347
|
ThreeMeshUI.update();
|
|
@@ -407,12 +407,7 @@ function insertNonCommercialUseHint(ctx: IContext) {
|
|
|
407
407
|
padding-left: 30px;
|
|
408
408
|
`;
|
|
409
409
|
if (NEEDLE_ENGINE_LICENSE_TYPE === "edu") {
|
|
410
|
-
|
|
411
|
-
console.log("This project is supported by Needle for Education – https://needle.tools");
|
|
412
|
-
}
|
|
413
|
-
else {
|
|
414
|
-
console.log("%c " + "This project is supported by Needle for Education – https://needle.tools", style);
|
|
415
|
-
}
|
|
410
|
+
console.log("%c " + "This project is supported by Needle for Education – https://needle.tools", style);
|
|
416
411
|
}
|
|
417
412
|
else {
|
|
418
413
|
// if the user has a basic license we already show the logo in the menu and log a license message
|
|
@@ -507,7 +502,7 @@ async function logNonCommercialUse(_logo?: string) {
|
|
|
507
502
|
// url must contain https for firefox to make it clickable
|
|
508
503
|
const version = VERSION;
|
|
509
504
|
const licenseText = `Needle Engine — No license active, commercial use is not allowed. Visit https://needle.tools/pricing for more information and licensing options! v${version}`;
|
|
510
|
-
if (Context.Current?.xr
|
|
505
|
+
if (Context.Current?.xr) {
|
|
511
506
|
console.log(licenseText);
|
|
512
507
|
}
|
|
513
508
|
else {
|