@needle-tools/engine 4.4.0-ci.1 → 4.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -0
- package/dist/assets/generateMeshBVH.worker-b7788939.js +25 -0
- package/dist/needle-engine.bundle.js +7043 -6766
- package/dist/needle-engine.bundle.light.js +7205 -6928
- package/dist/needle-engine.bundle.light.min.js +169 -139
- package/dist/needle-engine.bundle.light.umd.cjs +173 -143
- package/dist/needle-engine.bundle.min.js +169 -139
- package/dist/needle-engine.bundle.umd.cjs +172 -142
- package/dist/needle-engine.js +468 -467
- package/dist/needle-engine.light.js +468 -467
- package/dist/needle-engine.light.min.js +1 -1
- package/dist/needle-engine.light.umd.cjs +1 -1
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/vendor.js +5108 -5122
- package/dist/vendor.light.js +5108 -5122
- package/dist/vendor.light.min.js +84 -84
- package/dist/vendor.light.umd.cjs +78 -78
- package/dist/vendor.min.js +84 -84
- package/dist/vendor.umd.cjs +78 -78
- package/lib/engine/codegen/register_types.js +2 -0
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_components.js +3 -1
- package/lib/engine/engine_components.js.map +1 -1
- package/lib/engine/engine_context.d.ts +141 -14
- package/lib/engine/engine_context.js +164 -26
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_element.js +12 -10
- package/lib/engine/engine_element.js.map +1 -1
- package/lib/engine/engine_gameobject.js +5 -0
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_license.d.ts +2 -0
- package/lib/engine/engine_license.js +103 -62
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_networking_blob.js +40 -24
- package/lib/engine/engine_networking_blob.js.map +1 -1
- package/lib/engine/engine_physics_rapier.js +10 -9
- package/lib/engine/engine_physics_rapier.js.map +1 -1
- package/lib/engine/engine_serialization_core.js +6 -2
- package/lib/engine/engine_serialization_core.js.map +1 -1
- package/lib/engine/engine_utils_screenshot.js +1 -1
- package/lib/engine/engine_utils_screenshot.js.map +1 -1
- package/lib/engine/js-extensions/RGBAColor.d.ts +1 -0
- package/lib/engine/js-extensions/RGBAColor.js +56 -7
- package/lib/engine/js-extensions/RGBAColor.js.map +1 -1
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +4 -3
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +6 -6
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +4 -0
- package/lib/engine/webcomponents/needle menu/needle-menu.js +13 -2
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/xr/NeedleXRController.js +2 -3
- package/lib/engine/xr/NeedleXRController.js.map +1 -1
- package/lib/engine/xr/NeedleXRSession.js +12 -12
- package/lib/engine/xr/NeedleXRSession.js.map +1 -1
- package/lib/engine-components/AudioSource.js +7 -0
- package/lib/engine-components/AudioSource.js.map +1 -1
- package/lib/engine-components/Camera.js +18 -12
- package/lib/engine-components/Camera.js.map +1 -1
- package/lib/engine-components/CameraUtils.js +8 -14
- package/lib/engine-components/CameraUtils.js.map +1 -1
- package/lib/engine-components/GroundProjection.js +1 -1
- package/lib/engine-components/GroundProjection.js.map +1 -1
- package/lib/engine-components/NeedleMenu.js +1 -1
- package/lib/engine-components/NeedleMenu.js.map +1 -1
- package/lib/engine-components/OrbitControls.js +3 -1
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/ReflectionProbe.d.ts +1 -0
- package/lib/engine-components/ReflectionProbe.js +16 -9
- package/lib/engine-components/ReflectionProbe.js.map +1 -1
- package/lib/engine-components/SceneSwitcher.js +28 -7
- package/lib/engine-components/SceneSwitcher.js.map +1 -1
- package/lib/engine-components/SyncedTransform.d.ts +6 -0
- package/lib/engine-components/SyncedTransform.js +10 -5
- package/lib/engine-components/SyncedTransform.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +1 -0
- package/lib/engine-components/codegen/components.js +1 -0
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/USDZUI.js +2 -1
- package/lib/engine-components/export/usdz/extensions/USDZUI.js.map +1 -1
- package/lib/engine-components/ui/BaseUIComponent.d.ts +0 -1
- package/lib/engine-components/ui/BaseUIComponent.js +1 -1
- package/lib/engine-components/ui/BaseUIComponent.js.map +1 -1
- package/lib/engine-components/ui/EventSystem.js +1 -1
- package/lib/engine-components/ui/EventSystem.js.map +1 -1
- package/lib/engine-components/ui/Graphic.js +1 -0
- package/lib/engine-components/ui/Graphic.js.map +1 -1
- package/lib/engine-components/ui/RaycastUtils.js +1 -1
- package/lib/engine-components/ui/RaycastUtils.js.map +1 -1
- package/lib/engine-components/ui/RectTransform.d.ts +2 -2
- package/lib/engine-components/ui/RectTransform.js +9 -6
- package/lib/engine-components/ui/RectTransform.js.map +1 -1
- package/lib/engine-components/ui/Symbols.d.ts +1 -0
- package/lib/engine-components/ui/Symbols.js +2 -0
- package/lib/engine-components/ui/Symbols.js.map +1 -0
- package/lib/engine-components/ui/Utils.js +1 -1
- package/lib/engine-components/ui/Utils.js.map +1 -1
- package/lib/engine-components/utils/EnvironmentScene.d.ts +1 -1
- package/lib/engine-components/utils/EnvironmentScene.js +1 -1
- package/lib/engine-components/utils/EnvironmentScene.js.map +1 -1
- package/package.json +3 -3
- package/plugins/common/license.js +115 -27
- package/plugins/types/userconfig.d.ts +8 -0
- package/plugins/vite/build-pipeline.js +1 -1
- package/plugins/vite/defines.js +3 -1
- package/plugins/vite/dependencies.js +23 -4
- package/plugins/vite/facebook-instant-games.js +7 -4
- package/plugins/vite/index.js +1 -1
- package/plugins/vite/license.js +2 -1
- package/src/engine/codegen/register_types.ts +2 -0
- package/src/engine/engine_addressables.ts +3 -2
- package/src/engine/engine_components.ts +2 -1
- package/src/engine/engine_context.ts +169 -33
- package/src/engine/engine_element.ts +10 -9
- package/src/engine/engine_gameobject.ts +7 -0
- package/src/engine/engine_license.ts +116 -67
- package/src/engine/engine_networking_blob.ts +47 -26
- package/src/engine/engine_physics_rapier.ts +10 -12
- package/src/engine/engine_serialization_core.ts +6 -1
- package/src/engine/engine_utils_screenshot.ts +1 -1
- package/src/engine/js-extensions/RGBAColor.ts +59 -8
- package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +6 -6
- package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +6 -6
- package/src/engine/webcomponents/needle menu/needle-menu.ts +13 -2
- package/src/engine/xr/NeedleXRController.ts +2 -3
- package/src/engine/xr/NeedleXRSession.ts +12 -12
- package/src/engine-components/AudioSource.ts +8 -3
- package/src/engine-components/Camera.ts +34 -22
- package/src/engine-components/CameraUtils.ts +8 -16
- package/src/engine-components/GroundProjection.ts +1 -1
- package/src/engine-components/NeedleMenu.ts +1 -1
- package/src/engine-components/OrbitControls.ts +2 -1
- package/src/engine-components/ReflectionProbe.ts +15 -8
- package/src/engine-components/SceneSwitcher.ts +28 -11
- package/src/engine-components/SyncedTransform.ts +11 -6
- package/src/engine-components/codegen/components.ts +1 -0
- package/src/engine-components/export/usdz/extensions/USDZUI.ts +2 -2
- package/src/engine-components/ui/BaseUIComponent.ts +1 -1
- package/src/engine-components/ui/EventSystem.ts +1 -1
- package/src/engine-components/ui/Graphic.ts +1 -1
- package/src/engine-components/ui/RaycastUtils.ts +1 -1
- package/src/engine-components/ui/RectTransform.ts +10 -7
- package/src/engine-components/ui/Symbols.ts +2 -0
- package/src/engine-components/ui/Utils.ts +2 -1
- package/src/engine-components/utils/EnvironmentScene.ts +1 -1
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
2
|
import { NEEDLE_CLOUD_CLI_NAME } from "./cloud.js";
|
|
3
|
+
import { existsSync } from "fs";
|
|
3
4
|
|
|
4
5
|
const port = 8424;
|
|
6
|
+
const localServerUrl = `http://localhost:${port}`;
|
|
5
7
|
const licenseServerUrl = `http://localhost:${port}/api/license`;
|
|
6
8
|
const projectIdentifierUrl = `http://localhost:${port}/api/public_key`;
|
|
7
9
|
const needleCloudApiEndpoint = "https://cloud.needle.tools/api";
|
|
8
10
|
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {{loglevel?:"verbose"}} DefaultOptions
|
|
13
|
+
*/
|
|
14
|
+
|
|
9
15
|
/**
|
|
10
16
|
* Replace license string - used for webpack
|
|
11
17
|
* @param {string} code
|
|
12
|
-
* @param {{team:string|undefined}} opts
|
|
18
|
+
* @param {DefaultOptions & {accessToken?:string, team:string|undefined}} opts
|
|
13
19
|
*/
|
|
14
20
|
export async function replaceLicense(code, opts) {
|
|
15
|
-
const index = code
|
|
21
|
+
const index = code?.indexOf("NEEDLE_ENGINE_LICENSE_TYPE");
|
|
16
22
|
if (index >= 0) {
|
|
17
23
|
const licenseType = await resolveLicense(opts);
|
|
18
24
|
if (!licenseType) {
|
|
@@ -29,18 +35,22 @@ export async function replaceLicense(code, opts) {
|
|
|
29
35
|
return code;
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
|
|
33
38
|
/**
|
|
34
39
|
* Resolve the license using the needle engine licensing server
|
|
35
|
-
* @param {{accessToken?:string, team?:string} | null} args
|
|
40
|
+
* @param {DefaultOptions & {accessToken?:string, team?:string} | null} args
|
|
36
41
|
* @returns {Promise<string | null>}
|
|
37
42
|
*/
|
|
38
43
|
export async function resolveLicense(args = null) {
|
|
39
44
|
let accessToken = args?.accessToken;
|
|
40
45
|
|
|
41
|
-
if (!accessToken && process.env.CI
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
if (!accessToken && process.env.CI) {
|
|
47
|
+
if (process.env.NEEDLE_CLOUD_TOKEN) {
|
|
48
|
+
console.log("[needle-license] INFO: Using Needle Cloud access token from environment variable");
|
|
49
|
+
accessToken = process.env.NEEDLE_CLOUD_TOKEN;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.warn("[needle-license] WARN: Missing NEEDLE_CLOUD_TOKEN for CI environment run");
|
|
53
|
+
}
|
|
44
54
|
}
|
|
45
55
|
|
|
46
56
|
if (accessToken) {
|
|
@@ -66,12 +76,33 @@ export async function resolveLicense(args = null) {
|
|
|
66
76
|
}
|
|
67
77
|
else {
|
|
68
78
|
console.error(`[needle-license] Could not fetch license from Needle Cloud API (${res.status})`);
|
|
79
|
+
if (process.env.CI) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else if (process.env.CI) {
|
|
85
|
+
const isGithubCI = process.env.GITHUB_ACTIONS;
|
|
86
|
+
let message = "[needle-license] WARN: Missing NEEDLE_CLOUD_TOKEN for CI environment run.";
|
|
87
|
+
if (isGithubCI) {
|
|
88
|
+
const repositoryUrl = process.env.GITHUB_REPOSITORY;
|
|
89
|
+
const url = `${repositoryUrl}/settings/secrets/actions`;
|
|
90
|
+
message += `\nPlease add the token to your GitHub repository secrets: ${url}`;
|
|
69
91
|
}
|
|
92
|
+
console.warn(message);
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
else if (isStackblitz()) {
|
|
96
|
+
console.error("[needle-license] License server is not available in Stackblitz. Please use an access token for authorization.");
|
|
97
|
+
return null;
|
|
70
98
|
}
|
|
71
99
|
|
|
72
100
|
// Fallback to use CLI
|
|
73
101
|
// Wait for the server to start
|
|
74
|
-
await waitForLicenseServer()
|
|
102
|
+
if (!await waitForLicenseServer(args || undefined)) {
|
|
103
|
+
console.error("[needle-license] ERR: Failed to start license server...");
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
75
106
|
|
|
76
107
|
const url = new URL(licenseServerUrl);
|
|
77
108
|
if (args?.team)
|
|
@@ -86,7 +117,9 @@ export async function resolveLicense(args = null) {
|
|
|
86
117
|
method: "GET",
|
|
87
118
|
signal: timeout
|
|
88
119
|
}).catch(err => {
|
|
89
|
-
if (
|
|
120
|
+
if (args?.loglevel === "verbose") console.error("Error fetching license", err.message);
|
|
121
|
+
|
|
122
|
+
if (err.cause?.code === "ECONNREFUSED") {
|
|
90
123
|
return { error: "[needle-license] ERR: Failed to connect to license server (ECONNREFUSED)" };
|
|
91
124
|
}
|
|
92
125
|
else {
|
|
@@ -103,7 +136,10 @@ export async function resolveLicense(args = null) {
|
|
|
103
136
|
return null;
|
|
104
137
|
}
|
|
105
138
|
else if (!licenseResponse.ok) {
|
|
106
|
-
|
|
139
|
+
if (licenseResponse.status === 500)
|
|
140
|
+
console.error(`[needle-license] ERROR: Failed to fetch license (${licenseResponse.status})`);
|
|
141
|
+
else
|
|
142
|
+
console.log(`[needle-license] No license found (${licenseResponse.status})`);
|
|
107
143
|
return null;
|
|
108
144
|
}
|
|
109
145
|
|
|
@@ -119,7 +155,6 @@ function tryParseLicense(str) {
|
|
|
119
155
|
try {
|
|
120
156
|
/** @type {{needle_engine_license:string}} */
|
|
121
157
|
const licenseJson = JSON.parse(str);
|
|
122
|
-
console.log("\n");
|
|
123
158
|
if (licenseJson.needle_engine_license) {
|
|
124
159
|
console.log(`[needle-license] INFO: Successfully received \"${licenseJson.needle_engine_license?.toUpperCase()}\" license`)
|
|
125
160
|
return licenseJson.needle_engine_license;
|
|
@@ -144,11 +179,15 @@ function tryParseLicense(str) {
|
|
|
144
179
|
|
|
145
180
|
/**
|
|
146
181
|
* @param {string | undefined} project_id
|
|
182
|
+
* @param {DefaultOptions | undefined} opts
|
|
147
183
|
*/
|
|
148
|
-
export async function getPublicIdentifier(project_id) {
|
|
184
|
+
export async function getPublicIdentifier(project_id, opts = undefined) {
|
|
149
185
|
|
|
150
186
|
let accessToken = undefined;
|
|
151
187
|
if (process.env.CI) {
|
|
188
|
+
|
|
189
|
+
if (opts?.loglevel === "verbose") console.debug("[needle-identifier] INFO: Running in CI environment");
|
|
190
|
+
|
|
152
191
|
if (process.env.NEEDLE_CLOUD_TOKEN) {
|
|
153
192
|
console.log("[needle-identifier] INFO: Using Needle Cloud access token from environment variable");
|
|
154
193
|
accessToken = process.env.NEEDLE_CLOUD_TOKEN;
|
|
@@ -159,8 +198,10 @@ export async function getPublicIdentifier(project_id) {
|
|
|
159
198
|
project_id: project_id || process.env.GITHUB_REPOSITORY || undefined,
|
|
160
199
|
machine_id: process.env.GITHUB_REPOSITORY_ID || "unknown",
|
|
161
200
|
}
|
|
201
|
+
const timeout = AbortSignal.timeout(10_000);
|
|
162
202
|
const res = await fetch(url, {
|
|
163
203
|
method: "POST",
|
|
204
|
+
signal: timeout,
|
|
164
205
|
headers: {
|
|
165
206
|
Authorization: `Bearer ${accessToken}`,
|
|
166
207
|
"Content-Type": "application/json",
|
|
@@ -168,6 +209,9 @@ export async function getPublicIdentifier(project_id) {
|
|
|
168
209
|
},
|
|
169
210
|
body: JSON.stringify(body),
|
|
170
211
|
}).catch(err => {
|
|
212
|
+
if (opts?.loglevel === "verbose") {
|
|
213
|
+
console.error(err);
|
|
214
|
+
}
|
|
171
215
|
return { ok: false, error: err.message };
|
|
172
216
|
});
|
|
173
217
|
if ("error" in res) {
|
|
@@ -188,17 +232,23 @@ export async function getPublicIdentifier(project_id) {
|
|
|
188
232
|
}
|
|
189
233
|
}
|
|
190
234
|
else {
|
|
191
|
-
|
|
235
|
+
const message = await res.text();
|
|
236
|
+
console.error(`[needle-identifier] Could not fetch project identifier from Needle Cloud API (${res.status}, ${res.statusText}, ${message})`);
|
|
192
237
|
return null;
|
|
193
238
|
}
|
|
194
|
-
|
|
239
|
+
}
|
|
240
|
+
else if (isStackblitz()) {
|
|
241
|
+
console.error("[needle-license] License server is not available in Stackblitz. Please use an access token for authorization.");
|
|
195
242
|
return null;
|
|
196
243
|
}
|
|
197
244
|
|
|
198
245
|
|
|
199
246
|
|
|
200
247
|
// Wait for the server to start
|
|
201
|
-
await waitForLicenseServer()
|
|
248
|
+
if (!await waitForLicenseServer(opts)) {
|
|
249
|
+
console.error("[needle-identifier] ERR: Failed to start license server...");
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
202
252
|
|
|
203
253
|
console.log(`[needle-identifier] INFO: Fetching project identifier...`);
|
|
204
254
|
const url = new URL(projectIdentifierUrl);
|
|
@@ -208,7 +258,12 @@ export async function getPublicIdentifier(project_id) {
|
|
|
208
258
|
method: "GET",
|
|
209
259
|
signal: timeout
|
|
210
260
|
}).catch(err => {
|
|
211
|
-
|
|
261
|
+
|
|
262
|
+
if (opts?.loglevel === "verbose") {
|
|
263
|
+
console.error(err);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (err.cause?.code === "ECONNREFUSED") {
|
|
212
267
|
return { error: "[needle-identifier] Could not connect to the license server: The connection was actively refused" };
|
|
213
268
|
}
|
|
214
269
|
else {
|
|
@@ -237,30 +292,54 @@ export async function getPublicIdentifier(project_id) {
|
|
|
237
292
|
}
|
|
238
293
|
catch (err) {
|
|
239
294
|
// TODO: report error to backend
|
|
295
|
+
if (opts?.loglevel === "verbose") console.error(err);
|
|
240
296
|
return null;
|
|
241
297
|
}
|
|
242
298
|
};
|
|
243
299
|
|
|
244
300
|
|
|
245
301
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
302
|
+
/**
|
|
303
|
+
* If we run the build command without an editor and the license server is just being started we need to to wait for the root URL to return a response
|
|
304
|
+
* @param {DefaultOptions | undefined} opts
|
|
305
|
+
* @returns {Promise<boolean>}
|
|
306
|
+
*/
|
|
307
|
+
async function waitForLicenseServer(opts) {
|
|
308
|
+
if (opts?.loglevel === "verbose") console.log("[needle-license] INFO: Waiting for license server to start...");
|
|
309
|
+
|
|
249
310
|
// Make sure the licensing server is running
|
|
250
|
-
runCommand("npx", ["--yes", NEEDLE_CLOUD_CLI_NAME, "start-server"]);
|
|
311
|
+
const startcmd = runCommand("npx", ["--yes", NEEDLE_CLOUD_CLI_NAME, "start-server"], opts);
|
|
312
|
+
let isRunning = true;
|
|
313
|
+
startcmd.then(() => isRunning = false);
|
|
251
314
|
|
|
252
315
|
let attempts = 0;
|
|
253
|
-
const maxAttempts =
|
|
316
|
+
const maxAttempts = 5;
|
|
254
317
|
do {
|
|
255
|
-
const
|
|
318
|
+
const timeout = AbortSignal.timeout(10_000);
|
|
319
|
+
const response = await fetch(localServerUrl, {
|
|
256
320
|
method: "GET",
|
|
321
|
+
signal: timeout
|
|
257
322
|
}).catch(err => {
|
|
258
|
-
if (
|
|
259
|
-
console.
|
|
260
|
-
|
|
323
|
+
if (opts?.loglevel === "verbose") {
|
|
324
|
+
console.error("ERROR connecting to local license server url at " + localServerUrl, err.message);
|
|
325
|
+
}
|
|
326
|
+
if (err.cause?.code === "ECONNREFUSED") {
|
|
327
|
+
if (!isRunning) {
|
|
328
|
+
console.error("[needle-license] ERR: Failed to connect to license server (ECONNREFUSED)");
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
// Waiting for server to start
|
|
332
|
+
// EConnectRefuse happen if starting the license server for the first time
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
if (attempts === maxAttempts) {
|
|
337
|
+
console.error("[needle-license] ERR: Failed to start license server...", err.message);
|
|
338
|
+
}
|
|
261
339
|
}
|
|
262
340
|
});
|
|
263
341
|
if (response) {
|
|
342
|
+
if (opts?.loglevel === "verbose") console.log(`[needle-license] INFO: License server is running and reachable at ${localServerUrl} (Status: ${response.status})`);
|
|
264
343
|
return true;
|
|
265
344
|
}
|
|
266
345
|
if (attempts === 0) {
|
|
@@ -276,14 +355,22 @@ async function waitForLicenseServer() {
|
|
|
276
355
|
}
|
|
277
356
|
|
|
278
357
|
|
|
358
|
+
function isStackblitz() {
|
|
359
|
+
return existsSync("/home/.stackblitz")
|
|
360
|
+
}
|
|
361
|
+
|
|
279
362
|
/**
|
|
280
363
|
* @param {string} processName
|
|
281
364
|
* @param {string[]} args
|
|
365
|
+
* @param {DefaultOptions | undefined} opts
|
|
282
366
|
*/
|
|
283
|
-
async function runCommand(processName, args) {
|
|
367
|
+
async function runCommand(processName, args, opts) {
|
|
368
|
+
if (opts?.loglevel === "verbose") console.log(`[needle-license] INFO: Running command: ${processName} ${args.join(" ")}`);
|
|
284
369
|
const process = spawn(processName, [...args], { shell: true, timeout: 30_000 });
|
|
285
|
-
return new Promise((resolve,
|
|
370
|
+
return new Promise((resolve, _reject) => {
|
|
286
371
|
process.on('close', (code) => {
|
|
372
|
+
if (opts?.loglevel === "verbose")
|
|
373
|
+
console.log(`[needle-license] INFO: \"${processName}\" process exited with code ${code}`);
|
|
287
374
|
if (code === 0) {
|
|
288
375
|
resolve(true);
|
|
289
376
|
} else {
|
|
@@ -292,6 +379,7 @@ async function runCommand(processName, args) {
|
|
|
292
379
|
}
|
|
293
380
|
});
|
|
294
381
|
process.on('error', (err) => {
|
|
382
|
+
if (opts?.loglevel === "verbose") console.error("Error running " + processName, err);
|
|
295
383
|
resolve(err);
|
|
296
384
|
});
|
|
297
385
|
});
|
|
@@ -46,6 +46,8 @@ export type userSettings = {
|
|
|
46
46
|
|
|
47
47
|
noCodegenTransform?: boolean;
|
|
48
48
|
noFacebookInstantGames?: boolean;
|
|
49
|
+
/** Custom configuration for facebook instant games. */
|
|
50
|
+
facebookInstantGames: {}
|
|
49
51
|
/** Set to true to create an imports.log file that shows all module imports. The file is generated when stopping the server. */
|
|
50
52
|
logModuleImportChains?: boolean;
|
|
51
53
|
|
|
@@ -71,6 +73,9 @@ export type userSettings = {
|
|
|
71
73
|
* @example "2.2.0-alpha"
|
|
72
74
|
*/
|
|
73
75
|
version?: string;
|
|
76
|
+
|
|
77
|
+
/** If defined the access token will be used to run compression on Needle Cloud */
|
|
78
|
+
accessToken?: string | undefined;
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
/** required for @serializable https://github.com/vitejs/vite/issues/13736 */
|
|
@@ -97,6 +102,9 @@ export type userSettings = {
|
|
|
97
102
|
*/
|
|
98
103
|
license?: License;
|
|
99
104
|
|
|
105
|
+
/** Enable verbose logging */
|
|
106
|
+
debugLicense?: boolean;
|
|
107
|
+
|
|
100
108
|
/**
|
|
101
109
|
* When set to `true` a plugin will automatically attempt to open the browser using a network ip address when the local server has started
|
|
102
110
|
* @default undefined
|
|
@@ -256,7 +256,7 @@ async function invokeBuildPipeline(opts) {
|
|
|
256
256
|
/** @type {null | ChildProcess} */
|
|
257
257
|
let proc = null;
|
|
258
258
|
|
|
259
|
-
let cloudAccessToken = opts.license?.accessToken;
|
|
259
|
+
let cloudAccessToken = opts.buildPipeline?.accessToken || opts.license?.accessToken;
|
|
260
260
|
if (!cloudAccessToken) {
|
|
261
261
|
cloudAccessToken = process.env.NEEDLE_CLOUD_TOKEN;
|
|
262
262
|
}
|
package/plugins/vite/defines.js
CHANGED
|
@@ -58,7 +58,9 @@ export const needleDefines = (command, needleEngineConfig, userSettings) => {
|
|
|
58
58
|
viteConfig.define.NEEDLE_PROJECT_BUILD_TIME = "\"" + new Date().toString() + "\"";
|
|
59
59
|
|
|
60
60
|
const projectId = undefined; // TODO: this needs to be exported by the integration (if any)
|
|
61
|
-
const publicIdentifier = await getPublicIdentifier(projectId
|
|
61
|
+
const publicIdentifier = await getPublicIdentifier(projectId, {
|
|
62
|
+
loglevel: userSettings?.debugLicense === true ? "verbose" : undefined,
|
|
63
|
+
}).catch(console.warn);
|
|
62
64
|
if (publicIdentifier) {
|
|
63
65
|
viteConfig.define.NEEDLE_PUBLIC_KEY = "\"" + publicIdentifier + "\"";
|
|
64
66
|
}
|
|
@@ -45,6 +45,13 @@ function handleOptimizeDeps(config) {
|
|
|
45
45
|
// This needs to be excluded from optimization because otherwise the worker import fails
|
|
46
46
|
// three-mesh-bvh/src/workers/generateMeshBVH.worker.js?worker
|
|
47
47
|
config.optimizeDeps.exclude.push("three-mesh-bvh");
|
|
48
|
+
|
|
49
|
+
if (!config.server) config.server = {};
|
|
50
|
+
if (!config.server.fs) config.server.fs = {};
|
|
51
|
+
if (config.server.fs.strict === undefined) {
|
|
52
|
+
// we need to disable strictness to allow importing the worker from three-mesh-bvh node_modules in our GenerateMeshBVHWorker.js file
|
|
53
|
+
config.server.fs.strict = false;
|
|
54
|
+
}
|
|
48
55
|
}
|
|
49
56
|
}
|
|
50
57
|
|
|
@@ -72,11 +79,23 @@ function handleManualChunks(config) {
|
|
|
72
79
|
})
|
|
73
80
|
}
|
|
74
81
|
else {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
82
|
+
// If preserveModules is true we can not modify the chunkFileNames
|
|
83
|
+
let allowManualChunks = true;
|
|
84
|
+
if ("manualChunks" in rollupOutput) {
|
|
85
|
+
allowManualChunks = false;
|
|
86
|
+
// if the user has already defined manualChunks (even when set to undefined), we don't want to overwrite it
|
|
87
|
+
console.log("[needle-dependencies] manualChunks already found in vite config - will not overwrite it");
|
|
78
88
|
}
|
|
79
|
-
else {
|
|
89
|
+
else if (rollupOutput.preserveModules === true) {
|
|
90
|
+
allowManualChunks = false;
|
|
91
|
+
console.log("[needle-dependencies] manualChunks can not be registered because preserveModules is true");
|
|
92
|
+
}
|
|
93
|
+
if (rollupOutput.inlineDynamicImports === true) {
|
|
94
|
+
allowManualChunks = false;
|
|
95
|
+
console.log("[needle-dependencies] manualChunks can not be registered because inlineDynamicImports is true");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (allowManualChunks) {
|
|
80
99
|
console.log("[needle-dependencies] registering manualChunks");
|
|
81
100
|
rollupOutput.manualChunks = needleManualChunks;
|
|
82
101
|
}
|
|
@@ -39,20 +39,23 @@ export const needleFacebookInstantGames = (command, config, userSettings) => {
|
|
|
39
39
|
if (userSettings.noFacebookInstantGames === true) return;
|
|
40
40
|
|
|
41
41
|
// If the config is not present it means that we don't want to use fb instant games
|
|
42
|
-
if (!config || !config.facebookInstantGames) return;
|
|
42
|
+
if (!config || !(userSettings.facebookInstantGames || config.facebookInstantGames)) return;
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
/** @type {import('../types').userSettings["facebookInstantGames"]} */
|
|
45
|
+
const facebookInstantGamesConfig = { ...config.facebookInstantGames, ...userSettings.facebookInstantGames };
|
|
46
|
+
|
|
47
|
+
log("Setup Facebook Instant Games", facebookInstantGamesConfig);
|
|
45
48
|
|
|
46
49
|
|
|
47
50
|
// https://developers.facebook.com/docs/games/build/instant-games/reference/bundle-config
|
|
48
51
|
let bundleConfig = {}
|
|
49
52
|
const bundleConfigPath = process.cwd() + "/fbapp-config.json";
|
|
50
53
|
if (existsSync(bundleConfigPath)) {
|
|
51
|
-
log(
|
|
54
|
+
log(`Found facebook bundle config exists at "${bundleConfigPath}" ...`);
|
|
52
55
|
bundleConfig = JSON.parse(readFileSync(bundleConfigPath, 'utf8'));
|
|
53
56
|
}
|
|
54
57
|
else {
|
|
55
|
-
log(
|
|
58
|
+
log(`No facebook bundle config exists at "${bundleConfigPath}" - will generate one now`);
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
// Make sure the bundle has the required arguments:
|
package/plugins/vite/index.js
CHANGED
|
@@ -96,7 +96,7 @@ const defaultUserSettings = {
|
|
|
96
96
|
}
|
|
97
97
|
* ```
|
|
98
98
|
* @param {"build" | "serve"} command
|
|
99
|
-
* @param {{} | undefined} config
|
|
99
|
+
* @param {{} | undefined | null} config
|
|
100
100
|
* @param {import('../types/index.js').userSettings} userSettings
|
|
101
101
|
*/
|
|
102
102
|
export const needlePlugins = async (command, config = undefined, userSettings = {}) => {
|
package/plugins/vite/license.js
CHANGED
|
@@ -25,7 +25,8 @@ export const needleLicense = (command, config, userSettings) => {
|
|
|
25
25
|
|
|
26
26
|
license = await resolveLicense({
|
|
27
27
|
team: team,
|
|
28
|
-
accessToken: userSettings?.license?.accessToken
|
|
28
|
+
accessToken: userSettings?.license?.accessToken,
|
|
29
|
+
loglevel: userSettings?.debugLicense === true ? "verbose" : undefined
|
|
29
30
|
});
|
|
30
31
|
|
|
31
32
|
},
|
|
@@ -129,6 +129,7 @@ import { SpatialGrabRaycaster } from "../../engine-components/ui/Raycaster.js";
|
|
|
129
129
|
import { RectTransform } from "../../engine-components/ui/RectTransform.js";
|
|
130
130
|
import { SpatialHtml } from "../../engine-components/ui/SpatialHtml.js";
|
|
131
131
|
import { Text } from "../../engine-components/ui/Text.js";
|
|
132
|
+
import { EnvironmentScene } from "../../engine-components/utils/EnvironmentScene.js";
|
|
132
133
|
import { LookAt } from "../../engine-components/utils/LookAt.js";
|
|
133
134
|
import { OpenURL } from "../../engine-components/utils/OpenURL.js";
|
|
134
135
|
import { VideoPlayer } from "../../engine-components/VideoPlayer.js";
|
|
@@ -278,6 +279,7 @@ TypeStore.add("SpatialGrabRaycaster", SpatialGrabRaycaster);
|
|
|
278
279
|
TypeStore.add("RectTransform", RectTransform);
|
|
279
280
|
TypeStore.add("SpatialHtml", SpatialHtml);
|
|
280
281
|
TypeStore.add("Text", Text);
|
|
282
|
+
TypeStore.add("EnvironmentScene", EnvironmentScene);
|
|
281
283
|
TypeStore.add("LookAt", LookAt);
|
|
282
284
|
TypeStore.add("OpenURL", OpenURL);
|
|
283
285
|
TypeStore.add("VideoPlayer", VideoPlayer);
|
|
@@ -280,8 +280,9 @@ export class AssetReference {
|
|
|
280
280
|
if (debug)
|
|
281
281
|
console.log("loadAssetAsync", this.url);
|
|
282
282
|
if (!this.mustLoad) return this.asset;
|
|
283
|
-
|
|
284
|
-
|
|
283
|
+
|
|
284
|
+
if (prog) this._progressListeners.push(prog);
|
|
285
|
+
|
|
285
286
|
if (this._loading !== undefined) {
|
|
286
287
|
// console.warn("Wait for other loading thiny");
|
|
287
288
|
return this._loading.then(_ => this.asset);
|
|
@@ -92,10 +92,11 @@ export function addComponent<T extends IComponent>(obj: Object3D, componentInsta
|
|
|
92
92
|
|
|
93
93
|
if (componentInstance.gameObject === obj) return componentInstance;
|
|
94
94
|
// TODO: update raycast array
|
|
95
|
-
if (componentInstance.gameObject && componentInstance.gameObject.userData
|
|
95
|
+
if (componentInstance.gameObject && componentInstance.gameObject.userData?.components) {
|
|
96
96
|
const index = componentInstance.gameObject.userData.components.indexOf(componentInstance);
|
|
97
97
|
componentInstance.gameObject.userData.components.splice(index, 1);
|
|
98
98
|
}
|
|
99
|
+
if (!obj.userData) obj.userData = {};
|
|
99
100
|
if (!obj.userData.components) obj.userData.components = [];
|
|
100
101
|
else if (obj.userData.components.includes(componentInstance)) return componentInstance;
|
|
101
102
|
// TODO: do we want to disable and enable when moving?
|