@needle-tools/engine 5.1.0-alpha → 5.1.0-alpha.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/.needle/generated/needle-bindings.gen.d.ts +5 -0
- package/CHANGELOG.md +27 -1
- package/SKILL.md +39 -21
- package/components.needle.json +1 -1
- package/dist/{gltf-progressive-DJBMx-zB.umd.cjs → gltf-progressive-BmblPzFj.umd.cjs} +4 -4
- package/dist/{gltf-progressive-BryRjllq.min.js → gltf-progressive-CN_mbb66.min.js} +2 -2
- package/dist/{gltf-progressive-Cl167Vjx.js → gltf-progressive-DUlhxdv4.js} +5 -2
- package/dist/{needle-engine.bundle-qDahLTqW.min.js → needle-engine.bundle-B-5Q2CpC.min.js} +249 -173
- package/dist/{needle-engine.bundle-CwhCzjep.js → needle-engine.bundle-dit3f1l5.js} +13238 -12724
- package/dist/{needle-engine.bundle-wM-BWPX9.umd.cjs → needle-engine.bundle-qZfVf_v-.umd.cjs} +250 -174
- package/dist/needle-engine.d.ts +295 -31
- package/dist/needle-engine.js +569 -563
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/{postprocessing-B_9sKVU7.min.js → postprocessing-B571qGWR.min.js} +34 -34
- package/dist/{postprocessing-WDc9WwI3.js → postprocessing-CfrLAbLX.js} +0 -1
- package/dist/{postprocessing-B2wb6pzI.umd.cjs → postprocessing-CiGkAeM9.umd.cjs} +17 -17
- package/dist/{vendor-CAcsI0eU.js → vendor-BFrMaK9q.js} +8983 -9136
- package/dist/vendor-CJmyOrCq.min.js +1116 -0
- package/dist/vendor-DkMW3WY4.umd.cjs +1116 -0
- package/lib/engine/api.d.ts +12 -0
- package/lib/engine/api.js +2 -0
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/debug/debug_environment.js +1 -1
- package/lib/engine/debug/debug_environment.js.map +1 -1
- package/lib/engine/engine_application.js +8 -6
- package/lib/engine/engine_application.js.map +1 -1
- package/lib/engine/engine_components.js +5 -1
- package/lib/engine/engine_components.js.map +1 -1
- package/lib/engine/engine_constants.js +6 -0
- package/lib/engine/engine_constants.js.map +1 -1
- package/lib/engine/engine_context.d.ts +33 -7
- package/lib/engine/engine_context.js +40 -2
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_context_registry.js +1 -1
- package/lib/engine/engine_context_registry.js.map +1 -1
- package/lib/engine/engine_init.js +7 -0
- package/lib/engine/engine_init.js.map +1 -1
- package/lib/engine/engine_input.d.ts +3 -2
- package/lib/engine/engine_input.js +3 -2
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_license.d.ts +2 -0
- package/lib/engine/engine_license.js +25 -15
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_lifecycle_functions_internal.js +5 -0
- package/lib/engine/engine_lifecycle_functions_internal.js.map +1 -1
- package/lib/engine/engine_networking_blob.d.ts +1 -1
- package/lib/engine/engine_networking_blob.js +5 -11
- package/lib/engine/engine_networking_blob.js.map +1 -1
- package/lib/engine/engine_physics_rapier.d.ts +3 -0
- package/lib/engine/engine_physics_rapier.js +13 -10
- package/lib/engine/engine_physics_rapier.js.map +1 -1
- package/lib/engine/engine_pmrem.js +2 -2
- package/lib/engine/engine_pmrem.js.map +1 -1
- package/lib/engine/engine_scenedata.d.ts +30 -0
- package/lib/engine/engine_scenedata.js +136 -0
- package/lib/engine/engine_scenedata.js.map +1 -0
- package/lib/engine/engine_ssr.d.ts +18 -0
- package/lib/engine/engine_ssr.js +40 -0
- package/lib/engine/engine_ssr.js.map +1 -0
- package/lib/engine/engine_three_utils.d.ts +14 -7
- package/lib/engine/engine_three_utils.js +14 -7
- package/lib/engine/engine_three_utils.js.map +1 -1
- package/lib/engine/engine_types.d.ts +2 -0
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/engine_utils.js +4 -2
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/engine_utils_hash.d.ts +9 -0
- package/lib/engine/engine_utils_hash.js +112 -0
- package/lib/engine/engine_utils_hash.js.map +1 -0
- package/lib/engine/webcomponents/jsx.d.ts +51 -0
- package/lib/engine/webcomponents/logo-element.d.ts +2 -1
- package/lib/engine/webcomponents/logo-element.js +2 -1
- package/lib/engine/webcomponents/logo-element.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +4 -4
- package/lib/engine/webcomponents/needle menu/needle-menu.js +2 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-button.d.ts +2 -1
- package/lib/engine/webcomponents/needle-button.js +2 -1
- package/lib/engine/webcomponents/needle-button.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +2 -1
- package/lib/engine/webcomponents/needle-engine.js +2 -1
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine/xr/NeedleXRSession.d.ts +1 -0
- package/lib/engine/xr/NeedleXRSession.js +5 -5
- package/lib/engine/xr/NeedleXRSession.js.map +1 -1
- package/lib/engine/xr/events.d.ts +30 -3
- package/lib/engine/xr/events.js +38 -0
- package/lib/engine/xr/events.js.map +1 -1
- package/lib/engine/xr/init.js +1 -7
- package/lib/engine/xr/init.js.map +1 -1
- package/lib/engine-components/AnimatorController.d.ts +135 -2
- package/lib/engine-components/AnimatorController.js +218 -2
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/GroundProjection.d.ts +1 -0
- package/lib/engine-components/GroundProjection.js +184 -48
- package/lib/engine-components/GroundProjection.js.map +1 -1
- package/lib/engine-components/Light.d.ts +6 -8
- package/lib/engine-components/Light.js +40 -27
- package/lib/engine-components/Light.js.map +1 -1
- package/lib/engine-components/RigidBody.js +3 -3
- package/lib/engine-components/RigidBody.js.map +1 -1
- package/lib/engine-components/SceneSwitcher.js +2 -0
- package/lib/engine-components/SceneSwitcher.js.map +1 -1
- package/lib/engine-components/api.d.ts +1 -0
- package/lib/engine-components/api.js +1 -0
- package/lib/engine-components/api.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/postprocessing/Effects/BloomEffect.d.ts +1 -1
- package/lib/engine-components/postprocessing/Effects/Sharpening.js +1 -2
- package/lib/engine-components/postprocessing/Effects/Sharpening.js.map +1 -1
- package/lib/engine-components/postprocessing/PostProcessingHandler.js +5 -6
- package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
- package/lib/engine-components/web/ScrollFollow.d.ts +0 -1
- package/lib/engine-components/web/ScrollFollow.js +3 -2
- package/lib/engine-components/web/ScrollFollow.js.map +1 -1
- package/lib/needle-engine.d.ts +2 -0
- package/lib/needle-engine.js +2 -0
- package/lib/needle-engine.js.map +1 -1
- package/package.json +6 -4
- package/plugins/common/logger.js +42 -19
- package/plugins/dts-generator/dts.codegen.js +334 -0
- package/plugins/dts-generator/dts.scan.js +99 -0
- package/plugins/dts-generator/dts.writer.js +59 -0
- package/plugins/dts-generator/glb.discovery.js +279 -0
- package/plugins/dts-generator/glb.extractor.js +215 -0
- package/plugins/dts-generator/glb.reader.js +167 -0
- package/plugins/dts-generator/index.js +36 -0
- package/plugins/dts-generator/manifest.types.js +174 -0
- package/plugins/types/index.d.ts +2 -1
- package/plugins/types/needle-bindings.d.ts +30 -0
- package/plugins/types/userconfig.d.ts +21 -2
- package/plugins/vite/asap.js +1 -1
- package/plugins/vite/dependency-watcher.d.ts +2 -2
- package/plugins/vite/dependency-watcher.js +3 -4
- package/plugins/vite/drop.d.ts +2 -2
- package/plugins/vite/drop.js +3 -4
- package/plugins/vite/dts-generator.d.ts +7 -0
- package/plugins/vite/dts-generator.js +191 -0
- package/plugins/vite/index.d.ts +10 -3
- package/plugins/vite/index.js +27 -10
- package/plugins/vite/logger.client.js +4 -3
- package/plugins/vite/logging.js +2 -2
- package/plugins/vite/meta.js +4 -2
- package/plugins/vite/poster.d.ts +2 -2
- package/plugins/vite/poster.js +3 -5
- package/plugins/vite/reload.d.ts +2 -2
- package/plugins/vite/reload.js +23 -22
- package/src/engine/api.ts +15 -1
- package/src/engine/debug/debug_environment.ts +1 -1
- package/src/engine/engine_application.ts +8 -6
- package/src/engine/engine_components.ts +7 -4
- package/src/engine/engine_constants.ts +11 -6
- package/src/engine/engine_context.ts +50 -7
- package/src/engine/engine_context_registry.ts +1 -1
- package/src/engine/engine_init.ts +6 -0
- package/src/engine/engine_input.ts +3 -2
- package/src/engine/engine_license.ts +23 -19
- package/src/engine/engine_lifecycle_functions_internal.ts +7 -0
- package/src/engine/engine_networking_blob.ts +5 -11
- package/src/engine/engine_physics_rapier.ts +14 -12
- package/src/engine/engine_pmrem.ts +3 -3
- package/src/engine/engine_scenedata.ts +134 -0
- package/src/engine/engine_ssr.ts +48 -0
- package/src/engine/engine_three_utils.ts +15 -7
- package/src/engine/engine_types.ts +2 -0
- package/src/engine/engine_utils.ts +3 -2
- package/src/engine/engine_utils_hash.ts +65 -0
- package/src/engine/webcomponents/jsx.d.ts +51 -0
- package/src/engine/webcomponents/logo-element.ts +3 -1
- package/src/engine/webcomponents/needle menu/needle-menu.ts +4 -2
- package/src/engine/webcomponents/needle-button.ts +3 -1
- package/src/engine/webcomponents/needle-engine.ts +3 -1
- package/src/engine/xr/NeedleXRSession.ts +6 -6
- package/src/engine/xr/events.ts +44 -1
- package/src/engine/xr/init.ts +0 -7
- package/src/engine-components/AnimatorController.ts +286 -4
- package/src/engine-components/GroundProjection.ts +226 -52
- package/src/engine-components/Light.ts +40 -26
- package/src/engine-components/RigidBody.ts +3 -3
- package/src/engine-components/SceneSwitcher.ts +1 -0
- package/src/engine-components/api.ts +1 -0
- package/src/engine-components/codegen/components.ts +1 -0
- package/src/engine-components/postprocessing/Effects/BloomEffect.ts +1 -1
- package/src/engine-components/postprocessing/Effects/Sharpening.ts +1 -2
- package/src/engine-components/postprocessing/PostProcessingHandler.ts +4 -8
- package/src/engine-components/web/ScrollFollow.ts +2 -2
- package/src/needle-engine.ts +3 -0
- package/src/vite-env.d.ts +16 -0
- package/dist/vendor-CEM38hLE.umd.cjs +0 -1116
- package/dist/vendor-HRlxIBga.min.js +0 -1116
|
@@ -99,8 +99,9 @@ if (import.meta && "hot" in import.meta) {
|
|
|
99
99
|
// unpatch();
|
|
100
100
|
// }, 10_000);
|
|
101
101
|
|
|
102
|
+
const isMobile = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
|
|
102
103
|
const threshold = 100;
|
|
103
|
-
const devToolsArePotentiallyOpen = window.outerHeight - window.innerHeight > threshold || window.outerWidth - window.innerWidth > threshold;
|
|
104
|
+
const devToolsArePotentiallyOpen = !isMobile && (window.outerHeight - window.innerHeight > threshold || window.outerWidth - window.innerWidth > threshold);
|
|
104
105
|
if (devToolsArePotentiallyOpen) {
|
|
105
106
|
sendLogToServer("internal", "Console logging is disabled (devtools are open)");
|
|
106
107
|
}
|
|
@@ -240,8 +241,8 @@ function stringifyLog(log, seen = /** @type {Set<unknown>} */ (new Set()), depth
|
|
|
240
241
|
const isServer = typeof window === "undefined";
|
|
241
242
|
const stringify_limits = {
|
|
242
243
|
string: isServer ? 100_000 : 1_000,
|
|
243
|
-
object_keys: isServer ?
|
|
244
|
-
object_depth: isServer ?
|
|
244
|
+
object_keys: isServer ? 10 : 10,
|
|
245
|
+
object_depth: isServer ? 3 : 3,
|
|
245
246
|
array_items: isServer ? 2_000 : 100,
|
|
246
247
|
}
|
|
247
248
|
|
package/plugins/vite/logging.js
CHANGED
|
@@ -97,8 +97,8 @@ export function needleLog(pluginName, message, level = 'log', options = undefine
|
|
|
97
97
|
? (dimBody ? leveledBody.split('\n').map(l => colors.dim(l)).join('\n') : leveledBody)
|
|
98
98
|
: "";
|
|
99
99
|
const payloadCore = emitHeader
|
|
100
|
-
? (body.length > 0 ? `${header}\n${body}
|
|
101
|
-
: (body.length > 0 ? `${body}
|
|
100
|
+
? (body.length > 0 ? `${header}\n${body}` : `${header}`)
|
|
101
|
+
: (body.length > 0 ? `${body}` : "");
|
|
102
102
|
const payload = leadingNewline ? `\n${payloadCore}` : payloadCore;
|
|
103
103
|
log(payload);
|
|
104
104
|
return;
|
package/plugins/vite/meta.js
CHANGED
|
@@ -13,8 +13,7 @@ import { needleGreenBold, needleLog } from './logging.js';
|
|
|
13
13
|
*/
|
|
14
14
|
export function needleMeta(command, config, userSettings) {
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
const isBuild = command === 'build';
|
|
16
|
+
let isBuild = command === 'build';
|
|
18
17
|
|
|
19
18
|
async function updateConfig() {
|
|
20
19
|
config = await loadConfig();
|
|
@@ -25,6 +24,9 @@ export function needleMeta(command, config, userSettings) {
|
|
|
25
24
|
return {
|
|
26
25
|
// replace meta tags
|
|
27
26
|
name: 'needle:meta',
|
|
27
|
+
configResolved(resolvedConfig) {
|
|
28
|
+
isBuild = resolvedConfig.command === 'build';
|
|
29
|
+
},
|
|
28
30
|
transformIndexHtml: {
|
|
29
31
|
order: 'pre',
|
|
30
32
|
handler(/** @type {string} */ html, /** @type {unknown} */ _ctx) {
|
package/plugins/vite/poster.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export function getPosterPath(): string;
|
|
2
2
|
/**
|
|
3
|
-
* @param {"build" | "serve"}
|
|
3
|
+
* @param {"build" | "serve" | undefined} _command
|
|
4
4
|
* @param {import('../types/needleConfig').needleMeta | null | undefined} config
|
|
5
5
|
* @param {import('../types').userSettings} userSettings
|
|
6
6
|
* @returns {import('vite').Plugin | undefined}
|
|
7
7
|
*/
|
|
8
|
-
export function needlePoster(
|
|
8
|
+
export function needlePoster(_command: "build" | "serve" | undefined, config: import("../types/needleConfig").needleMeta | null | undefined, userSettings: import("../types").userSettings): import("vite").Plugin | undefined;
|
package/plugins/vite/poster.js
CHANGED
|
@@ -10,19 +10,17 @@ export function getPosterPath() {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* @param {"build" | "serve"}
|
|
13
|
+
* @param {"build" | "serve" | undefined} _command
|
|
14
14
|
* @param {import('../types/needleConfig').needleMeta | null | undefined} config
|
|
15
15
|
* @param {import('../types').userSettings} userSettings
|
|
16
16
|
* @returns {import('vite').Plugin | undefined}
|
|
17
17
|
*/
|
|
18
|
-
export function needlePoster(
|
|
19
|
-
// only relevant for local development
|
|
20
|
-
if (command === 'build') return [];
|
|
21
|
-
|
|
18
|
+
export function needlePoster(_command, config, userSettings) {
|
|
22
19
|
if (userSettings.noPoster) return;
|
|
23
20
|
|
|
24
21
|
return {
|
|
25
22
|
name: 'needle:poster',
|
|
23
|
+
apply: 'serve',
|
|
26
24
|
configureServer(server) {
|
|
27
25
|
const hot = server.hot ?? server.ws;
|
|
28
26
|
hot.on('needle:screenshot', async (data, client) => {
|
package/plugins/vite/reload.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @param {"build" | "serve"}
|
|
2
|
+
* @param {"build" | "serve" | undefined} _command
|
|
3
3
|
* @param {import('../types/needleConfig').needleMeta | null} config
|
|
4
4
|
* @param {import('../types').userSettings} userSettings
|
|
5
5
|
* @returns {import('vite').Plugin | undefined}
|
|
6
6
|
*/
|
|
7
|
-
export function needleReload(
|
|
7
|
+
export function needleReload(_command: "build" | "serve" | undefined, config: import("../types/needleConfig").needleMeta | null, userSettings: import("../types").userSettings): import("vite").Plugin | undefined;
|
package/plugins/vite/reload.js
CHANGED
|
@@ -7,6 +7,7 @@ import { existsSync, readFileSync, statSync } from 'fs';
|
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
8
|
import { needleLog } from './logging.js';
|
|
9
9
|
|
|
10
|
+
const pluginName = "needle-reload";
|
|
10
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
12
|
const __dirname = path.dirname(__filename);
|
|
12
13
|
|
|
@@ -15,14 +16,12 @@ const filesUsingHotReload = new Set();
|
|
|
15
16
|
let assetsDirectory = "";
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
|
-
* @param {"build" | "serve"}
|
|
19
|
+
* @param {"build" | "serve" | undefined} _command
|
|
19
20
|
* @param {import('../types/needleConfig').needleMeta | null} config
|
|
20
21
|
* @param {import('../types').userSettings} userSettings
|
|
21
22
|
* @returns {import('vite').Plugin | undefined}
|
|
22
23
|
*/
|
|
23
|
-
export function needleReload(
|
|
24
|
-
if (command === "build") return undefined;
|
|
25
|
-
|
|
24
|
+
export function needleReload(_command, config, userSettings) {
|
|
26
25
|
if (userSettings?.noReload === true) return undefined;
|
|
27
26
|
|
|
28
27
|
|
|
@@ -41,7 +40,7 @@ export function needleReload(command, config, userSettings) {
|
|
|
41
40
|
const buildDirectory = projectConfig?.buildDirectory?.length ? process.cwd().replaceAll("\\", "/") + "/" + projectConfig?.buildDirectory : "";
|
|
42
41
|
if (buildDirectory?.length) {
|
|
43
42
|
const relativeBuildDirectory = path.relative(process.cwd(), buildDirectory).replaceAll("\\", "/") || ".";
|
|
44
|
-
setTimeout(() => needleLog(
|
|
43
|
+
setTimeout(() => needleLog(pluginName, "Build directory: " + relativeBuildDirectory), 100);
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
// These ignore patterns will be injected into user config to better control vite reloading
|
|
@@ -51,6 +50,7 @@ export function needleReload(command, config, userSettings) {
|
|
|
51
50
|
|
|
52
51
|
return {
|
|
53
52
|
name: 'needle:reload',
|
|
53
|
+
apply: 'serve',
|
|
54
54
|
/** @param {import('vite').UserConfig} config */
|
|
55
55
|
config(config) {
|
|
56
56
|
if (!config.server) config.server = { watch: { ignored: [] } };
|
|
@@ -60,7 +60,7 @@ export function needleReload(command, config, userSettings) {
|
|
|
60
60
|
// @ts-ignore - watch.ignored is guaranteed to be string[] by the guards above
|
|
61
61
|
config.server.watch.ignored.push(pattern);
|
|
62
62
|
if (userSettings?.debug === true)
|
|
63
|
-
setTimeout(() => needleLog(
|
|
63
|
+
setTimeout(() => needleLog(pluginName, "Updated server ignore patterns: " + JSON.stringify(config.server?.watch?.ignored)), 100);
|
|
64
64
|
},
|
|
65
65
|
/** @param {import('vite').HmrContext & {buildDirectory?: string}} args */
|
|
66
66
|
handleHotUpdate(args) {
|
|
@@ -119,7 +119,7 @@ function getHot(server) {
|
|
|
119
119
|
|
|
120
120
|
/** @param {import('vite').ViteDevServer} server @param {string} [file] */
|
|
121
121
|
function notifyClientWillReload(server, file) {
|
|
122
|
-
|
|
122
|
+
needleLog(pluginName, "Send reload notification");
|
|
123
123
|
getHot(server).send('needle:reload', { type: 'will-reload', file: file });
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -135,7 +135,7 @@ async function handleReload({ file, server, modules: _modules, read, buildDirect
|
|
|
135
135
|
|
|
136
136
|
// Dont reload the whole server when a file that is using hot reload changes
|
|
137
137
|
if (filesUsingHotReload.has(file)) {
|
|
138
|
-
|
|
138
|
+
needleLog(pluginName, "File is using hot reload: " + file);
|
|
139
139
|
return null;
|
|
140
140
|
}
|
|
141
141
|
|
|
@@ -154,7 +154,7 @@ async function handleReload({ file, server, modules: _modules, read, buildDirect
|
|
|
154
154
|
// instead of relying on the vite server watch ignore array
|
|
155
155
|
// we could here also match paths that we know we dont want to track
|
|
156
156
|
if (ignorePatterns.length > 0 && ignoreRegex.test(file)) {
|
|
157
|
-
|
|
157
|
+
needleLog(pluginName, "Ignore change in file: " + getFileNameLog(file));
|
|
158
158
|
return [];
|
|
159
159
|
}
|
|
160
160
|
|
|
@@ -164,7 +164,7 @@ async function handleReload({ file, server, modules: _modules, read, buildDirect
|
|
|
164
164
|
if (buildDirectory?.length) {
|
|
165
165
|
const dir = path.dirname(file).replaceAll("\\", "/");
|
|
166
166
|
if (dir.startsWith(buildDirectory)) {
|
|
167
|
-
|
|
167
|
+
needleLog(pluginName, "Ignore change in build directory: " + getFileNameLog(file));
|
|
168
168
|
return [];
|
|
169
169
|
}
|
|
170
170
|
}
|
|
@@ -172,19 +172,20 @@ async function handleReload({ file, server, modules: _modules, read, buildDirect
|
|
|
172
172
|
// Check if codegen files actually changed their content
|
|
173
173
|
// this will return false if its the first update
|
|
174
174
|
// meaning if its the first export after the server starts those will not trigger a reload
|
|
175
|
+
// Ignore d.ts
|
|
175
176
|
const shouldCheckIfContentChanged = file.includes("/codegen/") || file.includes("/generated/") || file.endsWith("gen.js");// || file.endsWith(".glb") || file.endsWith(".gltf") || file.endsWith(".bin");
|
|
176
|
-
if (shouldCheckIfContentChanged) {
|
|
177
|
+
if (!file.includes("/.svelte-kit/") && !file.endsWith(".d.ts") && !file.endsWith("needle-html-data.json") && shouldCheckIfContentChanged) {
|
|
177
178
|
if (reloadIsScheduled) {
|
|
178
179
|
return [];
|
|
179
180
|
}
|
|
180
181
|
if (await testIfFileContentChanged(file, read) === false) {
|
|
181
|
-
|
|
182
|
+
needleLog(pluginName, "File content didnt change: " + getFileNameLog(file));
|
|
182
183
|
return [];
|
|
183
184
|
}
|
|
184
185
|
}
|
|
185
186
|
|
|
186
187
|
// these are known file types we export from integrations
|
|
187
|
-
const knownExportFileTypes = [
|
|
188
|
+
const knownExportFileTypes = [".glb", ".gltf", ".bin", "exr", ".ktx2", ".mp3", ".ogg", ".mp4", ".webm"];
|
|
188
189
|
if (!knownExportFileTypes.some((type) => file.endsWith(type)))
|
|
189
190
|
return null;
|
|
190
191
|
|
|
@@ -208,7 +209,7 @@ async function handleReload({ file, server, modules: _modules, read, buildDirect
|
|
|
208
209
|
}
|
|
209
210
|
}
|
|
210
211
|
|
|
211
|
-
|
|
212
|
+
needleLog(pluginName, "> Detected file change: " + getFileNameLog(file) + " (" + ((fileSize / (1024 * 1024)).toFixed(1)) + " MB)");
|
|
212
213
|
notifyClientWillReload(server);
|
|
213
214
|
scheduleReload(server);
|
|
214
215
|
return [];
|
|
@@ -223,7 +224,7 @@ async function scheduleReload(server, level = 0) {
|
|
|
223
224
|
const lockFile = path.join(process.cwd(), lockFileName);
|
|
224
225
|
if (existsSync(lockFile)) {
|
|
225
226
|
if (level === 0)
|
|
226
|
-
|
|
227
|
+
needleLog(pluginName, "Lock file exists, waiting for export to finish...");
|
|
227
228
|
setTimeout(() => scheduleReload(server, level += 1), 300);
|
|
228
229
|
return;
|
|
229
230
|
}
|
|
@@ -234,13 +235,13 @@ async function scheduleReload(server, level = 0) {
|
|
|
234
235
|
if (timeDiff < 1000) {
|
|
235
236
|
// Sometimes file changes happen immediately after triggering a reload
|
|
236
237
|
// we dont want to reload again in that case
|
|
237
|
-
|
|
238
|
+
needleLog(pluginName, "Ignoring reload, last reload was too recent" + timeDiff + "ms ago");
|
|
238
239
|
return;
|
|
239
240
|
}
|
|
240
241
|
|
|
241
242
|
lastReloadTime = Date.now();
|
|
242
243
|
const readableTime = new Date(lastReloadTime).toLocaleTimeString();
|
|
243
|
-
|
|
244
|
+
needleLog(pluginName, "< Reloading... " + readableTime);
|
|
244
245
|
getHot(server).send({
|
|
245
246
|
type: 'full-reload',
|
|
246
247
|
path: '*'
|
|
@@ -299,10 +300,10 @@ function removeVersionQueryArgument(content) {
|
|
|
299
300
|
function insertScriptRegisterHotReloadCode(src, filePath) {
|
|
300
301
|
|
|
301
302
|
// We only want to inject the hot reload code in the needle-engine root file
|
|
302
|
-
if(!filePath.includes("/src/needle-engine.ts")) {
|
|
303
|
+
if (!filePath.includes("/src/needle-engine.ts")) {
|
|
303
304
|
return src;
|
|
304
305
|
}
|
|
305
|
-
|
|
306
|
+
needleLog(pluginName, "[Needle HMR] Hot reload is enabled");
|
|
306
307
|
// this code let's the engine know that we are in hot reload mode
|
|
307
308
|
const code = `
|
|
308
309
|
globalThis.NEEDLE_HOT_RELOAD_ENABLED = true;
|
|
@@ -338,12 +339,12 @@ function insertScriptHotReloadCode(src, filePath) {
|
|
|
338
339
|
return undefined;
|
|
339
340
|
// make import path from engine package
|
|
340
341
|
const fullPathToHotReload = process.cwd() + "/node_modules/@needle-tools/engine/src/engine/engine_hot_reload.ts";
|
|
341
|
-
//
|
|
342
|
+
// needleLog(pluginName, fullPathToHotReload);
|
|
342
343
|
const fileDirectory = path.dirname(filePath);
|
|
343
|
-
//
|
|
344
|
+
// needleLog(pluginName, "DIR", fileDirectory)
|
|
344
345
|
const relativePath = path.relative(fileDirectory, fullPathToHotReload);
|
|
345
346
|
importPath = relativePath.replace(/\\/g, "/");
|
|
346
|
-
//
|
|
347
|
+
// needleLog(pluginName, "importPath: ", importPath);
|
|
347
348
|
}
|
|
348
349
|
|
|
349
350
|
// console.log(importPath, ">", filePath);
|
package/src/engine/api.ts
CHANGED
|
@@ -336,6 +336,9 @@ export { loadPMREM } from "./engine_pmrem.js";
|
|
|
336
336
|
/** Scene lighting data and environment configuration */
|
|
337
337
|
export * from "./engine_scenelighting.js";
|
|
338
338
|
|
|
339
|
+
/** Typed scene data proxy — maps SceneData interface to live component instances */
|
|
340
|
+
export { getSceneData, needle } from "./engine_scenedata.js";
|
|
341
|
+
|
|
339
342
|
|
|
340
343
|
// ============================================================================
|
|
341
344
|
// SERIALIZATION
|
|
@@ -436,4 +439,15 @@ export * from "./webcomponents/needle-engine.loading.js";
|
|
|
436
439
|
* XR API: NeedleXRSession, NeedleXRController, XRRig.
|
|
437
440
|
* @see {@link https://engine.needle.tools/docs/xr.html | XR Documentation}
|
|
438
441
|
*/
|
|
439
|
-
export * from "./xr/api.js"
|
|
442
|
+
export * from "./xr/api.js"
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* HTML ↔ 3D component binding types, similar to Svelte's `PageData`.
|
|
446
|
+
* `SceneData` is a nested interface augmented per-project by the `needle:dts-generator`
|
|
447
|
+
* Vite plugin — it maps scene node names to their components and typed fields.
|
|
448
|
+
*
|
|
449
|
+
* @example
|
|
450
|
+
* import type { SceneData } from "@needle-tools/engine";
|
|
451
|
+
* type OrbitSettings = SceneData["Camera"]["OrbitControls"];
|
|
452
|
+
*/
|
|
453
|
+
export type { SceneData } from "needle-bindings";
|
|
@@ -15,7 +15,7 @@ export function isDevEnvironment(): boolean {
|
|
|
15
15
|
let res = isLocalNetwork();
|
|
16
16
|
if (!res) {
|
|
17
17
|
// is stackblitz?
|
|
18
|
-
res = window.location.hostname.endsWith(".local-credentialless.webcontainer.io");
|
|
18
|
+
res = typeof window !== "undefined" && window.location.hostname.endsWith(".local-credentialless.webcontainer.io");
|
|
19
19
|
}
|
|
20
20
|
_cachedDevEnvironment = res;
|
|
21
21
|
return res;
|
|
@@ -31,12 +31,14 @@ export function internalOnUserInputRegistered() {
|
|
|
31
31
|
userInteractionCallbacks.length = 0;
|
|
32
32
|
copy.forEach(cb => cb());
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
document.addEventListener('
|
|
36
|
-
document.addEventListener('
|
|
37
|
-
document.addEventListener('
|
|
38
|
-
document.addEventListener('
|
|
39
|
-
document.addEventListener('
|
|
34
|
+
if (typeof document !== "undefined") {
|
|
35
|
+
document.addEventListener('mousedown', internalOnUserInputRegistered);
|
|
36
|
+
document.addEventListener('pointerup', internalOnUserInputRegistered);
|
|
37
|
+
document.addEventListener('click', internalOnUserInputRegistered);
|
|
38
|
+
document.addEventListener('dragstart', internalOnUserInputRegistered);
|
|
39
|
+
document.addEventListener('touchend', internalOnUserInputRegistered);
|
|
40
|
+
document.addEventListener('keydown', internalOnUserInputRegistered);
|
|
41
|
+
}
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
// User Activation should be available across browsers since November 2023 https://developer.mozilla.org/en-US/docs/Web/API/UserActivation
|
|
@@ -10,6 +10,7 @@ import type { ComponentInit, Constructor, ConstructorConcrete, IComponent, IGame
|
|
|
10
10
|
import { $componentName } from "./engine_types.js";
|
|
11
11
|
import { getParam } from "./engine_utils.js";
|
|
12
12
|
import { apply } from "./js-extensions/index.js";
|
|
13
|
+
import { TypeStore } from "./engine_typestore.js";
|
|
13
14
|
|
|
14
15
|
const COMPONENT_GUID_NAMESPACE = 'eff8ba80-635d-11ec-90d6-0242ac120003';
|
|
15
16
|
|
|
@@ -137,7 +138,7 @@ export function addComponent<T extends IComponent>(obj: Object3D, componentInsta
|
|
|
137
138
|
if (componentInstance.guid === undefined || componentInstance.guid === "invalid") {
|
|
138
139
|
componentInstance.guid = generateDeterministicComponentGuid(obj, componentInstance);
|
|
139
140
|
}
|
|
140
|
-
if(init) componentInstance._internalInit(init);
|
|
141
|
+
if (init) componentInstance._internalInit(init);
|
|
141
142
|
// Register the component - make sure to provide the component instance context (if assigned)
|
|
142
143
|
registerComponent(componentInstance, componentInstance.context);
|
|
143
144
|
return componentInstance;
|
|
@@ -170,10 +171,12 @@ function onGetComponent<T>(obj: Object3D | null | undefined, componentType: Cons
|
|
|
170
171
|
}
|
|
171
172
|
if (!(obj?.userData?.components)) return null;
|
|
172
173
|
if (typeof componentType === "string") {
|
|
173
|
-
|
|
174
|
+
const type = TypeStore.get(componentType);
|
|
175
|
+
if (!didWarnAboutComponentAccess && !type) {
|
|
174
176
|
didWarnAboutComponentAccess = true;
|
|
175
177
|
console.warn(`Accessing components by name is not supported.\nPlease use the component type instead. This may keep working in local development but it will fail when bundling your application.\n\nYou can import other modules your main module to get access to types\nor if you use npmdefs you can make types available globally using globalThis:\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis`, componentType);
|
|
176
178
|
}
|
|
179
|
+
if (type) componentType = type as Constructor<T>;
|
|
177
180
|
}
|
|
178
181
|
|
|
179
182
|
if (debugEnabled())
|
|
@@ -248,7 +251,7 @@ export function getComponents<T extends IComponent>(obj: Object3D, componentType
|
|
|
248
251
|
* ```
|
|
249
252
|
*/
|
|
250
253
|
export function getComponentInChildren<T extends IComponent>(obj: Object3D, componentType: Constructor<T>, includeInactive: boolean = false): T | null {
|
|
251
|
-
if (includeInactive === false && obj[activeInHierarchyFieldName] === false) return null;
|
|
254
|
+
if (includeInactive === false && obj[activeInHierarchyFieldName] === false) return null;
|
|
252
255
|
const res = getComponent(obj, componentType) as IComponent | null;
|
|
253
256
|
if (includeInactive === false && (res?.enabled === false || res?.activeAndEnabled === false)) return null;
|
|
254
257
|
if (res) return res as T;
|
|
@@ -361,7 +364,7 @@ export function findObjectOfType<T extends IComponent>(type: Constructor<T>, con
|
|
|
361
364
|
if (!scene) return null;
|
|
362
365
|
|
|
363
366
|
const res = getComponentInChildren(scene, type, includeInactive);
|
|
364
|
-
if(res) return res;
|
|
367
|
+
if (res) return res;
|
|
365
368
|
return null;
|
|
366
369
|
}
|
|
367
370
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getParam } from "../engine/engine_utils.js";
|
|
2
2
|
const debug = getParam("debugdefines");
|
|
3
3
|
|
|
4
|
+
// #region global defines
|
|
5
|
+
|
|
4
6
|
// We jump through hoops like this to support 3 cases:
|
|
5
7
|
// 1) Vanilla js or angular js where global defines are not guaranteed to be made
|
|
6
8
|
// 2) Vite where global defines are made, vite defines are also automatically set to globalThis
|
|
@@ -11,11 +13,6 @@ tryEval(`if(!globalThis["NEEDLE_ENGINE_GENERATOR"]) globalThis["NEEDLE_ENGINE_GE
|
|
|
11
13
|
tryEval(`if(!globalThis["NEEDLE_PROJECT_BUILD_TIME"]) globalThis["NEEDLE_PROJECT_BUILD_TIME"] = "unknown";`);
|
|
12
14
|
tryEval(`if(!globalThis["NEEDLE_PUBLIC_KEY"]) globalThis["NEEDLE_PUBLIC_KEY"] = "unknown";`);
|
|
13
15
|
|
|
14
|
-
declare const NEEDLE_ENGINE_VERSION: string
|
|
15
|
-
declare const NEEDLE_ENGINE_GENERATOR: string;
|
|
16
|
-
declare const NEEDLE_PROJECT_BUILD_TIME: string;
|
|
17
|
-
declare const NEEDLE_PUBLIC_KEY: string;
|
|
18
|
-
|
|
19
16
|
// Make sure to wrap the new global this define in underscores to prevent the bundler from replacing it with the actual value
|
|
20
17
|
tryEval(`globalThis["__NEEDLE_ENGINE_VERSION__"] = "` + NEEDLE_ENGINE_VERSION + `";`);
|
|
21
18
|
tryEval(`globalThis["__NEEDLE_ENGINE_GENERATOR__"] = "` + NEEDLE_ENGINE_GENERATOR + `";`);
|
|
@@ -50,4 +47,12 @@ function tryEval(str: string) {
|
|
|
50
47
|
if (debug)
|
|
51
48
|
console.error(err);
|
|
52
49
|
}
|
|
53
|
-
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
// #region treeshake flags
|
|
55
|
+
// globalThis fallbacks for vanilla JS environments (no bundler define)
|
|
56
|
+
globalThis["NEEDLE_USE_RAPIER"] = globalThis["NEEDLE_USE_RAPIER"] !== undefined ? globalThis["NEEDLE_USE_RAPIER"] : true;
|
|
57
|
+
globalThis["NEEDLE_USE_POSTPROCESSING"] = globalThis["NEEDLE_USE_POSTPROCESSING"] !== undefined ? globalThis["NEEDLE_USE_POSTPROCESSING"] : true;
|
|
58
|
+
// #endregion treeshake flags
|
|
@@ -37,6 +37,8 @@ import { NetworkConnection } from './engine_networking.js';
|
|
|
37
37
|
import { Physics } from './engine_physics.js';
|
|
38
38
|
import { PlayerViewManager } from './engine_playerview.js';
|
|
39
39
|
import { RendererData as SceneLighting } from './engine_scenelighting.js';
|
|
40
|
+
import { getSceneData } from './engine_scenedata.js';
|
|
41
|
+
import type { SceneData } from 'needle-bindings';
|
|
40
42
|
import { getTempColor, logHierarchy } from './engine_three_utils.js';
|
|
41
43
|
import { Time } from './engine_time.js';
|
|
42
44
|
import { patchTonemapping } from './engine_tonemapping.js';
|
|
@@ -475,6 +477,28 @@ export class Context implements IContext {
|
|
|
475
477
|
* The main camera of the scene - this camera is used for rendering
|
|
476
478
|
* Use `setCurrentCamera` for updating the main camera.
|
|
477
479
|
*/
|
|
480
|
+
/**
|
|
481
|
+
* Access your scene's full hierarchy, objects, and components directly by name — with full autocomplete.
|
|
482
|
+
* Types are generated automatically from your GLB files when the dev server starts.
|
|
483
|
+
*
|
|
484
|
+
* You can store references to objects or components for later use.
|
|
485
|
+
* Note that the scene hierarchy can change at runtime (e.g. when objects are added, removed, or re-parented),
|
|
486
|
+
* in which case stored references may become stale.
|
|
487
|
+
*
|
|
488
|
+
* @experimental This API may change in future versions.
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* // Toggle auto-rotate on the orbit camera
|
|
492
|
+
* ctx.sceneData.Camera.OrbitControls.autoRotate = true;
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* // Change the background color
|
|
496
|
+
* ctx.sceneData.Camera.Camera.backgroundColor = new RGBAColor(1, 0, 0, 1);
|
|
497
|
+
*/
|
|
498
|
+
get sceneData(): SceneData {
|
|
499
|
+
return getSceneData(this);
|
|
500
|
+
}
|
|
501
|
+
|
|
478
502
|
get mainCamera(): Camera {
|
|
479
503
|
if (this._mainCamera) {
|
|
480
504
|
return this._mainCamera;
|
|
@@ -513,15 +537,32 @@ export class Context implements IContext {
|
|
|
513
537
|
connection: NetworkConnection;
|
|
514
538
|
/** @deprecated AssetDatabase is deprecated */
|
|
515
539
|
assets: AssetDatabase;
|
|
516
|
-
|
|
517
|
-
|
|
540
|
+
|
|
541
|
+
/** All registered lights in the scene, maintained by the Light component.
|
|
542
|
+
* @see mainLight for accessing the main directional light in the scene
|
|
543
|
+
*/
|
|
544
|
+
readonly lights = new Array<ILight>();
|
|
545
|
+
|
|
546
|
+
/** The brightest registered directional light, or null if none are registered
|
|
547
|
+
* @see lights
|
|
548
|
+
*/
|
|
549
|
+
get mainLight(): ILight | null {
|
|
550
|
+
let best: ILight | null = null;
|
|
551
|
+
for (const light of this.lights) {
|
|
552
|
+
if (light.type !== "directional") continue;
|
|
553
|
+
if (!best || light.intensity > best.intensity) best = light;
|
|
554
|
+
}
|
|
555
|
+
return best;
|
|
556
|
+
}
|
|
557
|
+
|
|
518
558
|
/** @deprecated Use sceneLighting */
|
|
519
|
-
get rendererData() { return this.sceneLighting }
|
|
559
|
+
private get rendererData() { return this.sceneLighting }
|
|
560
|
+
|
|
520
561
|
/** Access the scene lighting manager to control lighting settings in the context */
|
|
521
|
-
sceneLighting: SceneLighting;
|
|
522
|
-
addressables: Addressables;
|
|
523
|
-
lightmaps: ILightDataRegistry;
|
|
524
|
-
players: PlayerViewManager;
|
|
562
|
+
readonly sceneLighting: SceneLighting;
|
|
563
|
+
readonly addressables: Addressables;
|
|
564
|
+
readonly lightmaps: ILightDataRegistry;
|
|
565
|
+
readonly players: PlayerViewManager;
|
|
525
566
|
|
|
526
567
|
/** Access the LODs manager to control LOD behavior in the context */
|
|
527
568
|
readonly lodsManager: LODsManager;
|
|
@@ -829,6 +870,8 @@ export class Context implements IContext {
|
|
|
829
870
|
this._onBeforeRenderListeners.clear();
|
|
830
871
|
this._onAfterRenderListeners.clear();
|
|
831
872
|
|
|
873
|
+
this.lights.length = 0;
|
|
874
|
+
|
|
832
875
|
if (!this.isManagedExternally) {
|
|
833
876
|
if (this.renderer) {
|
|
834
877
|
this.renderer.renderLists.dispose();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type IComponent, type IContext, type LoadedModel } from "./engine_types.js";
|
|
2
2
|
|
|
3
|
-
const debug = typeof window !== undefined ? window.location.search.includes("debugcontext") : false;
|
|
3
|
+
const debug = typeof window !== "undefined" ? window.location.search.includes("debugcontext") : false;
|
|
4
4
|
|
|
5
5
|
/** The various events that can be dispatched by a Needle Engine {@link IContext} instance
|
|
6
6
|
*/
|
|
@@ -11,7 +11,10 @@ import { initCameraExtensions } from "./js-extensions/Camera.js";
|
|
|
11
11
|
import { patchLayers } from "./js-extensions/Layers.js";
|
|
12
12
|
import { initObject3DExtensions } from "./js-extensions/Object3D.js";
|
|
13
13
|
import { initVectorExtensions } from "./js-extensions/Vector.js";
|
|
14
|
+
import { SSR } from "./engine_ssr.js";
|
|
15
|
+
import { initLicense } from "./engine_license.js";
|
|
14
16
|
import { initWebComponents } from "./webcomponents/init.js";
|
|
17
|
+
import { initPhysics } from "./engine_physics_rapier.js";
|
|
15
18
|
import { initXR } from "./xr/init.js";
|
|
16
19
|
|
|
17
20
|
let initialized = false;
|
|
@@ -27,6 +30,7 @@ let initialized = false;
|
|
|
27
30
|
*/
|
|
28
31
|
export function initEngine() {
|
|
29
32
|
if (initialized) return;
|
|
33
|
+
if (SSR) return;
|
|
30
34
|
initialized = true;
|
|
31
35
|
|
|
32
36
|
initWebComponents();
|
|
@@ -43,5 +47,7 @@ export function initEngine() {
|
|
|
43
47
|
initAnimationAutoplay();
|
|
44
48
|
initSkyboxAttributes();
|
|
45
49
|
initSceneSwitcherAttributes();
|
|
50
|
+
initPhysics();
|
|
46
51
|
initXR();
|
|
52
|
+
initLicense();
|
|
47
53
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Intersection, Matrix4, Object3D, Ray, Vector2, Vector3 } from 'three';
|
|
2
2
|
|
|
3
3
|
import { showBalloonMessage, showBalloonWarning } from './debug/debug.js';
|
|
4
|
+
import { PointerEventBase, KeyboardEventBase } from './engine_ssr.js';
|
|
4
5
|
import { Context } from './engine_setup.js';
|
|
5
6
|
import { getTempVector, getWorldQuaternion } from './engine_three_utils.js';
|
|
6
7
|
import type { ButtonName, CursorTypeName, IGameObject, IInput, MouseButtonName, Vec2 } from './engine_types.js';
|
|
@@ -116,7 +117,7 @@ export declare type NEPointerEventIntersection = Intersection & { event?: NEPoin
|
|
|
116
117
|
* @see {@link Input} for the input management system
|
|
117
118
|
* @see {@link PointerType} for available pointer types
|
|
118
119
|
*/
|
|
119
|
-
export class NEPointerEvent extends
|
|
120
|
+
export class NEPointerEvent extends PointerEventBase {
|
|
120
121
|
|
|
121
122
|
/**
|
|
122
123
|
* Spatial input data
|
|
@@ -242,7 +243,7 @@ export class NEPointerEvent extends PointerEvent {
|
|
|
242
243
|
if (debug) console.warn("Stop propagation...", this.pointerId, this.pointerType)
|
|
243
244
|
}
|
|
244
245
|
}
|
|
245
|
-
export class NEKeyboardEvent extends
|
|
246
|
+
export class NEKeyboardEvent extends KeyboardEventBase {
|
|
246
247
|
source?: Event
|
|
247
248
|
constructor(type: InputEvents, source: Event, init: KeyboardEventInit) {
|
|
248
249
|
super(type, init)
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { dof } from "three/src/nodes/TSL.js";
|
|
2
|
-
|
|
3
|
-
import { isDevEnvironment } from "./debug/index.js";
|
|
4
1
|
import { BUILD_TIME, GENERATOR, PUBLIC_KEY, VERSION } from "./engine_constants.js";
|
|
5
2
|
import { ContextEvent, ContextRegistry } from "./engine_context_registry.js";
|
|
6
3
|
import { onInitialized } from "./engine_lifecycle_api.js";
|
|
@@ -8,7 +5,7 @@ import { isLocalNetwork } from "./engine_networking_utils.js";
|
|
|
8
5
|
import { Context } from "./engine_setup.js";
|
|
9
6
|
import type { IContext } from "./engine_types.js";
|
|
10
7
|
import { getParam } from "./engine_utils.js";
|
|
11
|
-
import {
|
|
8
|
+
import { SSR } from "./engine_ssr.js";
|
|
12
9
|
|
|
13
10
|
const debug = getParam("debuglicense");
|
|
14
11
|
|
|
@@ -77,18 +74,22 @@ function invokeLicenseCheckResultChanged(result: boolean) {
|
|
|
77
74
|
// #region Telemetry
|
|
78
75
|
export namespace Telemetry {
|
|
79
76
|
|
|
80
|
-
window
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
window.addEventListener("unhandledrejection", (event: PromiseRejectionEvent) => {
|
|
84
|
-
sendError(Context.Current, "unhandled_promise_rejection", {
|
|
85
|
-
message: event.reason?.message,
|
|
86
|
-
stack: event.reason?.stack,
|
|
87
|
-
timestamp: Date.now(),
|
|
77
|
+
if (typeof window !== "undefined") {
|
|
78
|
+
window.addEventListener("error", (event: ErrorEvent) => {
|
|
79
|
+
sendError(Context.Current, "unhandled_error", event);
|
|
88
80
|
});
|
|
89
|
-
|
|
81
|
+
window.addEventListener("unhandledrejection", (event: PromiseRejectionEvent) => {
|
|
82
|
+
sendError(Context.Current, "unhandled_promise_rejection", {
|
|
83
|
+
message: event.reason?.message,
|
|
84
|
+
stack: event.reason?.stack,
|
|
85
|
+
timestamp: Date.now(),
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
90
89
|
|
|
91
|
-
|
|
90
|
+
export function init() {
|
|
91
|
+
if(!SSR) onInitialized((ctx => sendPageViewEvent(ctx)), { once: true });
|
|
92
|
+
}
|
|
92
93
|
|
|
93
94
|
function sendPageViewEvent(ctx: IContext): Promise<void> | void {
|
|
94
95
|
if (!isAllowed(ctx)) {
|
|
@@ -241,11 +242,14 @@ export namespace Telemetry {
|
|
|
241
242
|
}
|
|
242
243
|
|
|
243
244
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
export function initLicense() {
|
|
246
|
+
Telemetry.init();
|
|
247
|
+
ContextRegistry.registerCallback(ContextEvent.ContextRegistered, evt => {
|
|
248
|
+
showLicenseInfo(evt.context);
|
|
249
|
+
handleForbidden(evt.context);
|
|
250
|
+
setTimeout(() => sendUsageMessageToAnalyticsBackend(evt.context), 2000);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
249
253
|
|
|
250
254
|
export let runtimeLicenseCheckPromise: Promise<void> | undefined = undefined;
|
|
251
255
|
let applicationIsForbidden = false;
|