@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.
Files changed (147) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/assets/generateMeshBVH.worker-b7788939.js +25 -0
  3. package/dist/needle-engine.bundle.js +7043 -6766
  4. package/dist/needle-engine.bundle.light.js +7205 -6928
  5. package/dist/needle-engine.bundle.light.min.js +169 -139
  6. package/dist/needle-engine.bundle.light.umd.cjs +173 -143
  7. package/dist/needle-engine.bundle.min.js +169 -139
  8. package/dist/needle-engine.bundle.umd.cjs +172 -142
  9. package/dist/needle-engine.js +468 -467
  10. package/dist/needle-engine.light.js +468 -467
  11. package/dist/needle-engine.light.min.js +1 -1
  12. package/dist/needle-engine.light.umd.cjs +1 -1
  13. package/dist/needle-engine.min.js +1 -1
  14. package/dist/needle-engine.umd.cjs +1 -1
  15. package/dist/vendor.js +5108 -5122
  16. package/dist/vendor.light.js +5108 -5122
  17. package/dist/vendor.light.min.js +84 -84
  18. package/dist/vendor.light.umd.cjs +78 -78
  19. package/dist/vendor.min.js +84 -84
  20. package/dist/vendor.umd.cjs +78 -78
  21. package/lib/engine/codegen/register_types.js +2 -0
  22. package/lib/engine/codegen/register_types.js.map +1 -1
  23. package/lib/engine/engine_addressables.js.map +1 -1
  24. package/lib/engine/engine_components.js +3 -1
  25. package/lib/engine/engine_components.js.map +1 -1
  26. package/lib/engine/engine_context.d.ts +141 -14
  27. package/lib/engine/engine_context.js +164 -26
  28. package/lib/engine/engine_context.js.map +1 -1
  29. package/lib/engine/engine_element.js +12 -10
  30. package/lib/engine/engine_element.js.map +1 -1
  31. package/lib/engine/engine_gameobject.js +5 -0
  32. package/lib/engine/engine_gameobject.js.map +1 -1
  33. package/lib/engine/engine_license.d.ts +2 -0
  34. package/lib/engine/engine_license.js +103 -62
  35. package/lib/engine/engine_license.js.map +1 -1
  36. package/lib/engine/engine_networking_blob.js +40 -24
  37. package/lib/engine/engine_networking_blob.js.map +1 -1
  38. package/lib/engine/engine_physics_rapier.js +10 -9
  39. package/lib/engine/engine_physics_rapier.js.map +1 -1
  40. package/lib/engine/engine_serialization_core.js +6 -2
  41. package/lib/engine/engine_serialization_core.js.map +1 -1
  42. package/lib/engine/engine_utils_screenshot.js +1 -1
  43. package/lib/engine/engine_utils_screenshot.js.map +1 -1
  44. package/lib/engine/js-extensions/RGBAColor.d.ts +1 -0
  45. package/lib/engine/js-extensions/RGBAColor.js +56 -7
  46. package/lib/engine/js-extensions/RGBAColor.js.map +1 -1
  47. package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +4 -3
  48. package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js.map +1 -1
  49. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +6 -6
  50. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
  51. package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +4 -0
  52. package/lib/engine/webcomponents/needle menu/needle-menu.js +13 -2
  53. package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
  54. package/lib/engine/xr/NeedleXRController.js +2 -3
  55. package/lib/engine/xr/NeedleXRController.js.map +1 -1
  56. package/lib/engine/xr/NeedleXRSession.js +12 -12
  57. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  58. package/lib/engine-components/AudioSource.js +7 -0
  59. package/lib/engine-components/AudioSource.js.map +1 -1
  60. package/lib/engine-components/Camera.js +18 -12
  61. package/lib/engine-components/Camera.js.map +1 -1
  62. package/lib/engine-components/CameraUtils.js +8 -14
  63. package/lib/engine-components/CameraUtils.js.map +1 -1
  64. package/lib/engine-components/GroundProjection.js +1 -1
  65. package/lib/engine-components/GroundProjection.js.map +1 -1
  66. package/lib/engine-components/NeedleMenu.js +1 -1
  67. package/lib/engine-components/NeedleMenu.js.map +1 -1
  68. package/lib/engine-components/OrbitControls.js +3 -1
  69. package/lib/engine-components/OrbitControls.js.map +1 -1
  70. package/lib/engine-components/ReflectionProbe.d.ts +1 -0
  71. package/lib/engine-components/ReflectionProbe.js +16 -9
  72. package/lib/engine-components/ReflectionProbe.js.map +1 -1
  73. package/lib/engine-components/SceneSwitcher.js +28 -7
  74. package/lib/engine-components/SceneSwitcher.js.map +1 -1
  75. package/lib/engine-components/SyncedTransform.d.ts +6 -0
  76. package/lib/engine-components/SyncedTransform.js +10 -5
  77. package/lib/engine-components/SyncedTransform.js.map +1 -1
  78. package/lib/engine-components/codegen/components.d.ts +1 -0
  79. package/lib/engine-components/codegen/components.js +1 -0
  80. package/lib/engine-components/codegen/components.js.map +1 -1
  81. package/lib/engine-components/export/usdz/extensions/USDZUI.js +2 -1
  82. package/lib/engine-components/export/usdz/extensions/USDZUI.js.map +1 -1
  83. package/lib/engine-components/ui/BaseUIComponent.d.ts +0 -1
  84. package/lib/engine-components/ui/BaseUIComponent.js +1 -1
  85. package/lib/engine-components/ui/BaseUIComponent.js.map +1 -1
  86. package/lib/engine-components/ui/EventSystem.js +1 -1
  87. package/lib/engine-components/ui/EventSystem.js.map +1 -1
  88. package/lib/engine-components/ui/Graphic.js +1 -0
  89. package/lib/engine-components/ui/Graphic.js.map +1 -1
  90. package/lib/engine-components/ui/RaycastUtils.js +1 -1
  91. package/lib/engine-components/ui/RaycastUtils.js.map +1 -1
  92. package/lib/engine-components/ui/RectTransform.d.ts +2 -2
  93. package/lib/engine-components/ui/RectTransform.js +9 -6
  94. package/lib/engine-components/ui/RectTransform.js.map +1 -1
  95. package/lib/engine-components/ui/Symbols.d.ts +1 -0
  96. package/lib/engine-components/ui/Symbols.js +2 -0
  97. package/lib/engine-components/ui/Symbols.js.map +1 -0
  98. package/lib/engine-components/ui/Utils.js +1 -1
  99. package/lib/engine-components/ui/Utils.js.map +1 -1
  100. package/lib/engine-components/utils/EnvironmentScene.d.ts +1 -1
  101. package/lib/engine-components/utils/EnvironmentScene.js +1 -1
  102. package/lib/engine-components/utils/EnvironmentScene.js.map +1 -1
  103. package/package.json +3 -3
  104. package/plugins/common/license.js +115 -27
  105. package/plugins/types/userconfig.d.ts +8 -0
  106. package/plugins/vite/build-pipeline.js +1 -1
  107. package/plugins/vite/defines.js +3 -1
  108. package/plugins/vite/dependencies.js +23 -4
  109. package/plugins/vite/facebook-instant-games.js +7 -4
  110. package/plugins/vite/index.js +1 -1
  111. package/plugins/vite/license.js +2 -1
  112. package/src/engine/codegen/register_types.ts +2 -0
  113. package/src/engine/engine_addressables.ts +3 -2
  114. package/src/engine/engine_components.ts +2 -1
  115. package/src/engine/engine_context.ts +169 -33
  116. package/src/engine/engine_element.ts +10 -9
  117. package/src/engine/engine_gameobject.ts +7 -0
  118. package/src/engine/engine_license.ts +116 -67
  119. package/src/engine/engine_networking_blob.ts +47 -26
  120. package/src/engine/engine_physics_rapier.ts +10 -12
  121. package/src/engine/engine_serialization_core.ts +6 -1
  122. package/src/engine/engine_utils_screenshot.ts +1 -1
  123. package/src/engine/js-extensions/RGBAColor.ts +59 -8
  124. package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +6 -6
  125. package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +6 -6
  126. package/src/engine/webcomponents/needle menu/needle-menu.ts +13 -2
  127. package/src/engine/xr/NeedleXRController.ts +2 -3
  128. package/src/engine/xr/NeedleXRSession.ts +12 -12
  129. package/src/engine-components/AudioSource.ts +8 -3
  130. package/src/engine-components/Camera.ts +34 -22
  131. package/src/engine-components/CameraUtils.ts +8 -16
  132. package/src/engine-components/GroundProjection.ts +1 -1
  133. package/src/engine-components/NeedleMenu.ts +1 -1
  134. package/src/engine-components/OrbitControls.ts +2 -1
  135. package/src/engine-components/ReflectionProbe.ts +15 -8
  136. package/src/engine-components/SceneSwitcher.ts +28 -11
  137. package/src/engine-components/SyncedTransform.ts +11 -6
  138. package/src/engine-components/codegen/components.ts +1 -0
  139. package/src/engine-components/export/usdz/extensions/USDZUI.ts +2 -2
  140. package/src/engine-components/ui/BaseUIComponent.ts +1 -1
  141. package/src/engine-components/ui/EventSystem.ts +1 -1
  142. package/src/engine-components/ui/Graphic.ts +1 -1
  143. package/src/engine-components/ui/RaycastUtils.ts +1 -1
  144. package/src/engine-components/ui/RectTransform.ts +10 -7
  145. package/src/engine-components/ui/Symbols.ts +2 -0
  146. package/src/engine-components/ui/Utils.ts +2 -1
  147. 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.indexOf("NEEDLE_ENGINE_LICENSE_TYPE");
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 && process.env.NEEDLE_CLOUD_TOKEN) {
42
- console.log("[needle-license] INFO: Using Needle Cloud access token from environment variable");
43
- accessToken = process.env.NEEDLE_CLOUD_TOKEN;
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 (err.cause.code === "ECONNREFUSED") {
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
- console.error("[needle-license] ERROR: Failed to fetch license");
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
- console.error(`[needle-identifier] Could not fetch project identifier from Needle Cloud API (${res.status})`);
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
- if (err.cause.code === "ECONNREFUSED") {
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
- // If we run the build command without an editor and the license server is just being started
247
- // we need to to wait for the root URL to return a response
248
- async function waitForLicenseServer() {
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 = 10;
316
+ const maxAttempts = 5;
254
317
  do {
255
- const response = await fetch(licenseServerUrl, {
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 (err.cause.code === "ECONNREFUSED") {
259
- console.warn("[needle-license] WARN: Stop waiting for license server because the connection was actively refused. (ECONNREFUSED)");
260
- attempts += maxAttempts;
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, reject) => {
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
  }
@@ -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).catch(console.warn);
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
- if (rollupOutput.manualChunks) {
76
- // if the user has already defined manualChunks, we don't want to overwrite it
77
- console.log("[needle-dependencies] manualChunks already defined");
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
- log("Setup Facebook Instant Games", config.facebookInstantGames);
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("Found facebook bundle config exists at " + bundleConfigPath + " ...");
54
+ log(`Found facebook bundle config exists at "${bundleConfigPath}" ...`);
52
55
  bundleConfig = JSON.parse(readFileSync(bundleConfigPath, 'utf8'));
53
56
  }
54
57
  else {
55
- log("No facebook bundle config exists at " + bundleConfigPath + " - will generate one now");
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:
@@ -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 = {}) => {
@@ -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
- if (prog)
284
- this._progressListeners.push(prog);
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.components) {
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?