@needle-tools/engine 4.14.0 → 4.15.0-next.f391a30
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 +8 -0
- package/components.needle.json +1 -1
- package/dist/{gltf-progressive-BttGBXw6.umd.cjs → gltf-progressive-CMwJPwEt.umd.cjs} +1 -1
- package/dist/{gltf-progressive-Bm_6aEi4.js → gltf-progressive-CTlvpS3A.js} +1 -1
- package/dist/{gltf-progressive-T5WKTux5.min.js → gltf-progressive-DYL3SLVb.min.js} +1 -1
- package/dist/materialx-4jJLLe9Q.js +4174 -0
- package/dist/materialx-Bt9FHwco.min.js +158 -0
- package/dist/materialx-NDD0y4JY.umd.cjs +158 -0
- package/dist/{needle-engine.bundle-COL2Bar3.umd.cjs → needle-engine.bundle-C1BFRZDF.umd.cjs} +150 -140
- package/dist/{needle-engine.bundle-Z_gAD7Kg.js → needle-engine.bundle-DB4kLWO_.js} +6651 -6400
- package/dist/{needle-engine.bundle-NolzHLqO.min.js → needle-engine.bundle-DsTdfmeb.min.js} +151 -141
- package/dist/needle-engine.d.ts +345 -88
- package/dist/needle-engine.js +322 -322
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/{postprocessing-06AXuvdv.min.js → postprocessing-BN-f4viE.min.js} +1 -1
- package/dist/{postprocessing-CPDcA21P.umd.cjs → postprocessing-DYmYOVm4.umd.cjs} +1 -1
- package/dist/{postprocessing-CI2x8Cln.js → postprocessing-De9ZpJrk.js} +1 -1
- package/dist/{three-examples-BMmNgNCN.umd.cjs → three-examples-BHqRVpO_.umd.cjs} +12 -12
- package/dist/{three-examples-CMYCd5nH.js → three-examples-C0ZCCA_K.js} +182 -192
- package/dist/{three-examples-CQl1fFZp.min.js → three-examples-DmTY8tGr.min.js} +14 -14
- package/lib/engine/api.d.ts +0 -2
- package/lib/engine/api.js +0 -2
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/debug/debug.js +1 -1
- package/lib/engine/debug/debug.js.map +1 -1
- package/lib/engine/debug/debug_spatial_console.js +1 -1
- package/lib/engine/debug/debug_spatial_console.js.map +1 -1
- package/lib/engine/engine_accessibility.d.ts +77 -0
- package/lib/engine/engine_accessibility.js +162 -0
- package/lib/engine/engine_accessibility.js.map +1 -0
- package/lib/engine/engine_context.d.ts +2 -0
- package/lib/engine/engine_context.js +8 -1
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_create_objects.js +1 -1
- package/lib/engine/engine_create_objects.js.map +1 -1
- package/lib/engine/engine_gizmos.js +1 -1
- package/lib/engine/engine_gizmos.js.map +1 -1
- package/lib/engine/engine_license.js +7 -2
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_materialpropertyblock.d.ts +90 -4
- package/lib/engine/engine_materialpropertyblock.js +97 -7
- package/lib/engine/engine_materialpropertyblock.js.map +1 -1
- package/lib/engine/engine_math.d.ts +34 -1
- package/lib/engine/engine_math.js +34 -1
- package/lib/engine/engine_math.js.map +1 -1
- package/lib/engine/engine_networking.js +1 -1
- package/lib/engine/engine_networking.js.map +1 -1
- package/lib/engine/engine_types.d.ts +2 -0
- package/lib/engine/engine_types.js +2 -0
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/engine_utils.js +2 -2
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/export/gltf/EXT_mesh_gpu_instancing_exporter.js.map +1 -0
- package/lib/engine/export/gltf/index.js +1 -1
- package/lib/engine/export/gltf/index.js.map +1 -1
- package/lib/engine/webcomponents/icons.js +3 -0
- package/lib/engine/webcomponents/icons.js.map +1 -1
- package/lib/engine/webcomponents/logo-element.d.ts +7 -3
- package/lib/engine/webcomponents/logo-element.js +21 -1
- package/lib/engine/webcomponents/logo-element.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +2 -2
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +10 -7
- package/lib/engine/webcomponents/needle menu/needle-menu.js +14 -4
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-button.d.ts +37 -11
- package/lib/engine/webcomponents/needle-button.js +42 -11
- package/lib/engine/webcomponents/needle-button.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js +10 -1
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +13 -2
- package/lib/engine/webcomponents/needle-engine.js +23 -3
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine-components/Component.d.ts +1 -2
- package/lib/engine-components/Component.js +1 -3
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/DragControls.d.ts +1 -0
- package/lib/engine-components/DragControls.js +21 -0
- package/lib/engine-components/DragControls.js.map +1 -1
- package/lib/engine-components/NeedleMenu.d.ts +2 -0
- package/lib/engine-components/NeedleMenu.js +2 -0
- package/lib/engine-components/NeedleMenu.js.map +1 -1
- package/lib/engine-components/Networking.d.ts +28 -3
- package/lib/engine-components/Networking.js +28 -3
- package/lib/engine-components/Networking.js.map +1 -1
- package/lib/engine-components/ReflectionProbe.d.ts +25 -2
- package/lib/engine-components/ReflectionProbe.js +46 -2
- package/lib/engine-components/ReflectionProbe.js.map +1 -1
- package/lib/engine-components/Skybox.js +4 -2
- package/lib/engine-components/Skybox.js.map +1 -1
- package/lib/engine-components/export/gltf/GltfExport.js +1 -1
- package/lib/engine-components/export/gltf/GltfExport.js.map +1 -1
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js +2 -2
- package/lib/engine-components/export/usdz/USDZExporter.js +1 -1
- package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.d.ts +15 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js +77 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/behavior/PhysicsExtension.js +2 -2
- package/lib/engine-components/export/usdz/extensions/behavior/PhysicsExtension.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
- package/lib/engine-components/ui/Button.d.ts +1 -0
- package/lib/engine-components/ui/Button.js +11 -0
- package/lib/engine-components/ui/Button.js.map +1 -1
- package/lib/engine-components/ui/Text.d.ts +1 -0
- package/lib/engine-components/ui/Text.js +11 -0
- package/lib/engine-components/ui/Text.js.map +1 -1
- package/package.json +18 -14
- package/plugins/common/buildinfo.js +46 -10
- package/plugins/common/files.js +2 -1
- package/plugins/common/license.js +144 -69
- package/plugins/common/logger.js +172 -11
- package/plugins/common/needle-engine-skill.md +175 -0
- package/plugins/common/worker.js +5 -4
- package/plugins/types/userconfig.d.ts +40 -2
- package/plugins/vite/ai.js +71 -0
- package/plugins/vite/alias.js +6 -5
- package/plugins/vite/asap.js +6 -5
- package/plugins/vite/build-pipeline.js +224 -41
- package/plugins/vite/buildinfo.js +66 -6
- package/plugins/vite/copyfiles.js +41 -12
- package/plugins/vite/custom-element-data.js +26 -16
- package/plugins/vite/defines.js +8 -5
- package/plugins/vite/dependencies.js +16 -10
- package/plugins/vite/dependency-watcher.js +35 -7
- package/plugins/vite/drop-client.js +7 -5
- package/plugins/vite/drop.js +16 -14
- package/plugins/vite/editor-connection.js +18 -16
- package/plugins/vite/imports-logger.js +12 -2
- package/plugins/vite/index.js +8 -3
- package/plugins/vite/local-files-analysis.js +789 -0
- package/plugins/vite/local-files-core.js +992 -0
- package/plugins/vite/local-files-internals.js +28 -0
- package/plugins/vite/local-files-types.d.ts +111 -0
- package/plugins/vite/local-files-utils.js +359 -0
- package/plugins/vite/local-files.js +2 -441
- package/plugins/vite/logger.client.js +45 -35
- package/plugins/vite/logger.js +6 -3
- package/plugins/vite/logging.js +129 -0
- package/plugins/vite/meta.js +18 -4
- package/plugins/vite/needle-app.js +4 -3
- package/plugins/vite/peer.js +2 -1
- package/plugins/vite/pwa.js +33 -17
- package/plugins/vite/reload.js +24 -2
- package/src/engine/api.ts +0 -3
- package/src/engine/debug/debug.ts +1 -1
- package/src/engine/debug/debug_spatial_console.ts +5 -1
- package/src/engine/engine_accessibility.ts +198 -0
- package/src/engine/engine_context.ts +10 -1
- package/src/engine/engine_create_objects.ts +1 -1
- package/src/engine/engine_gizmos.ts +9 -5
- package/src/engine/engine_license.ts +7 -2
- package/src/engine/engine_materialpropertyblock.ts +102 -11
- package/src/engine/engine_math.ts +34 -1
- package/src/engine/engine_networking.ts +1 -1
- package/src/engine/engine_types.ts +5 -0
- package/src/engine/engine_utils.ts +2 -2
- package/src/engine/export/gltf/index.ts +1 -1
- package/src/engine/webcomponents/icons.ts +3 -0
- package/src/engine/webcomponents/logo-element.ts +24 -4
- package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +6 -2
- package/src/engine/webcomponents/needle menu/needle-menu.ts +23 -11
- package/src/engine/webcomponents/needle-button.ts +44 -13
- package/src/engine/webcomponents/needle-engine.ar-overlay.ts +13 -2
- package/src/engine/webcomponents/needle-engine.ts +31 -8
- package/src/engine-components/Component.ts +2 -5
- package/src/engine-components/DragControls.ts +29 -4
- package/src/engine-components/NeedleMenu.ts +5 -3
- package/src/engine-components/Networking.ts +29 -4
- package/src/engine-components/ReflectionProbe.ts +52 -9
- package/src/engine-components/Skybox.ts +4 -2
- package/src/engine-components/export/gltf/GltfExport.ts +1 -1
- package/src/engine-components/export/usdz/ThreeUSDZExporter.ts +2 -2
- package/src/engine-components/export/usdz/USDZExporter.ts +1 -1
- package/src/engine-components/export/usdz/extensions/behavior/BehaviourComponents.ts +108 -32
- package/src/engine-components/export/usdz/extensions/behavior/PhysicsExtension.ts +2 -2
- package/src/engine-components/ui/Button.ts +12 -0
- package/src/engine-components/ui/Text.ts +13 -0
- package/dist/materialx-CJyQZtjt.min.js +0 -90
- package/dist/materialx-DMs1E08Z.js +0 -4636
- package/dist/materialx-DaKKOoVk.umd.cjs +0 -90
- package/lib/engine/engine_test_utils.d.ts +0 -39
- package/lib/engine/engine_test_utils.js +0 -84
- package/lib/engine/engine_test_utils.js.map +0 -1
- package/lib/include/three/EXT_mesh_gpu_instancing_exporter.js.map +0 -1
- package/src/engine/engine_test_utils.ts +0 -109
- package/src/include/draco/draco_decoder.js +0 -34
- package/src/include/draco/draco_decoder.wasm +0 -0
- package/src/include/draco/draco_wasm_wrapper.js +0 -117
- package/src/include/ktx2/basis_transcoder.js +0 -19
- package/src/include/ktx2/basis_transcoder.wasm +0 -0
- package/src/include/needle/arial-msdf.json +0 -1472
- package/src/include/needle/arial.png +0 -0
- package/src/include/needle/poweredbyneedle.webp +0 -0
- /package/lib/{include/three → engine/export/gltf}/EXT_mesh_gpu_instancing_exporter.d.ts +0 -0
- /package/lib/{include/three → engine/export/gltf}/EXT_mesh_gpu_instancing_exporter.js +0 -0
- /package/src/{include/three → engine/export/gltf}/EXT_mesh_gpu_instancing_exporter.js +0 -0
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import fs from 'fs';
|
|
2
3
|
import path from 'path';
|
|
3
4
|
|
|
5
|
+
/** @typedef {{ version?: number, tags?: {name: string, [key: string]: unknown}[], valueSets?: {name: string, [key: string]: unknown}[], globalAttributes?: unknown[] }} CustomElementData */
|
|
6
|
+
|
|
4
7
|
/** Known needle-engine tag names that should be updated from the source */
|
|
5
8
|
const NEEDLE_TAG_NAMES = ['needle-engine', 'needle-menu', 'needle-button'];
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* Merges needle-engine custom element data into an existing custom-elements.json file.
|
|
9
12
|
* Preserves user-defined tags while updating needle-engine specific tags.
|
|
10
|
-
* @param {
|
|
11
|
-
* @param {
|
|
12
|
-
* @returns {
|
|
13
|
+
* @param {CustomElementData} sourceData - The needle-engine custom-elements.json data
|
|
14
|
+
* @param {CustomElementData} targetData - The existing project custom-elements.json data
|
|
15
|
+
* @returns {CustomElementData} Merged data
|
|
13
16
|
*/
|
|
14
17
|
function mergeCustomElementData(sourceData, targetData) {
|
|
15
18
|
const merged = { ...targetData };
|
|
@@ -74,23 +77,30 @@ export const needleCustomElementData = (command, config, userSettings = {}) => {
|
|
|
74
77
|
|
|
75
78
|
// Path to source custom-elements.json in node_modules
|
|
76
79
|
const sourceFile = path.join(cwd, 'node_modules', '@needle-tools', 'engine', 'custom-elements.json');
|
|
77
|
-
// Path to target custom-elements.json in project
|
|
78
|
-
const targetFile = path.join(cwd, 'custom-elements.json');
|
|
80
|
+
// Path to target custom-elements.json in project vs code directory
|
|
81
|
+
const targetFile = path.join(cwd, '.vscode', 'custom-elements.json');
|
|
79
82
|
|
|
80
83
|
// Copy/merge custom-elements.json to project
|
|
81
84
|
if (fs.existsSync(sourceFile)) {
|
|
82
85
|
try {
|
|
83
|
-
const sourceData = JSON.parse(fs.readFileSync(sourceFile, 'utf8'));
|
|
86
|
+
const sourceData = /** @type {CustomElementData} */ (JSON.parse(fs.readFileSync(sourceFile, 'utf8')));
|
|
84
87
|
|
|
85
|
-
let targetData = {};
|
|
88
|
+
let targetData = /** @type {CustomElementData} */ ({});
|
|
86
89
|
if (fs.existsSync(targetFile)) {
|
|
87
90
|
// Merge with existing file to preserve user content
|
|
88
91
|
try {
|
|
89
|
-
targetData = JSON.parse(fs.readFileSync(targetFile, 'utf8'));
|
|
92
|
+
targetData = /** @type {CustomElementData} */ (JSON.parse(fs.readFileSync(targetFile, 'utf8')));
|
|
90
93
|
} catch {
|
|
91
94
|
targetData = {};
|
|
92
95
|
}
|
|
93
96
|
}
|
|
97
|
+
else {
|
|
98
|
+
// Ensure .vscode directory exists
|
|
99
|
+
const vscodeDir = path.dirname(targetFile);
|
|
100
|
+
if (!fs.existsSync(vscodeDir)) {
|
|
101
|
+
fs.mkdirSync(vscodeDir);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
94
104
|
|
|
95
105
|
const mergedData = mergeCustomElementData(sourceData, targetData);
|
|
96
106
|
const newContent = JSON.stringify(mergedData, null, 2);
|
|
@@ -125,7 +135,7 @@ export const needleCustomElementData = (command, config, userSettings = {}) => {
|
|
|
125
135
|
const full = path.join(cwd, f);
|
|
126
136
|
try {
|
|
127
137
|
const raw = fs.readFileSync(full, 'utf8');
|
|
128
|
-
const data = JSON.parse(raw);
|
|
138
|
+
const data = /** @type {{settings?: {'html.customData'?: string[], [key: string]: unknown}}} */ (JSON.parse(raw));
|
|
129
139
|
|
|
130
140
|
// Ensure settings.html.customData contains the local path
|
|
131
141
|
data.settings = data.settings || {};
|
|
@@ -156,20 +166,20 @@ export const needleCustomElementData = (command, config, userSettings = {}) => {
|
|
|
156
166
|
if (fs.existsSync(settingsFile)) {
|
|
157
167
|
try {
|
|
158
168
|
const rawSettings = fs.readFileSync(settingsFile, 'utf8');
|
|
159
|
-
/** @type {Record<string,
|
|
169
|
+
/** @type {Record<string, unknown>} */
|
|
160
170
|
const settings = JSON.parse(rawSettings) || {};
|
|
161
|
-
|
|
162
|
-
settings['html.customData'] =
|
|
171
|
+
const htmlData = /** @type {string[]} */ (settings['html.customData'] || []);
|
|
172
|
+
settings['html.customData'] = htmlData;
|
|
163
173
|
|
|
164
174
|
// Remove old node_modules path if present
|
|
165
|
-
const oldIndex =
|
|
175
|
+
const oldIndex = htmlData.indexOf(oldNodeModulesPath);
|
|
166
176
|
if (oldIndex >= 0) {
|
|
167
|
-
|
|
177
|
+
htmlData.splice(oldIndex, 1);
|
|
168
178
|
}
|
|
169
179
|
|
|
170
180
|
// Add local path if not present
|
|
171
|
-
if (!
|
|
172
|
-
|
|
181
|
+
if (!htmlData.includes(localCustomDataPath)) {
|
|
182
|
+
htmlData.push(localCustomDataPath);
|
|
173
183
|
|
|
174
184
|
// Write back settings.json if changed
|
|
175
185
|
const newRawSettings = JSON.stringify(settings, null, 2);
|
package/plugins/vite/defines.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { loadConfig } from "./config.js";
|
|
2
2
|
import { tryGetNeedleEngineVersion } from "../common/version.js";
|
|
3
3
|
import { getPublicIdentifier as getPublicIdentifier } from "../common/license.js";
|
|
4
|
+
import { needleLog } from "./logging.js";
|
|
4
5
|
|
|
5
6
|
// NOTE: ALL DEFINES MUST BE SET HERE! NEVER ADD OR RELY ON DEFINES IN ANY OTHER PLUGIN
|
|
6
7
|
|
|
@@ -11,6 +12,8 @@ import { getPublicIdentifier as getPublicIdentifier } from "../common/license.js
|
|
|
11
12
|
// https://vitejs.dev/config/#using-environment-variables-in-config
|
|
12
13
|
|
|
13
14
|
/**
|
|
15
|
+
* @param {string} command
|
|
16
|
+
* @param {{ generator?: string, useRapier?: boolean } | null | undefined} needleEngineConfig
|
|
14
17
|
* @param {import('../types').userSettings} userSettings
|
|
15
18
|
*/
|
|
16
19
|
export const needleDefines = (command, needleEngineConfig, userSettings) => {
|
|
@@ -28,11 +31,11 @@ export const needleDefines = (command, needleEngineConfig, userSettings) => {
|
|
|
28
31
|
return {
|
|
29
32
|
name: 'needle:defines',
|
|
30
33
|
enforce: 'pre',
|
|
31
|
-
async config(viteConfig) {
|
|
34
|
+
async config(/** @type {{ define?: Record<string, unknown> }} */ viteConfig) {
|
|
32
35
|
// console.log("Update vite defines -------------------------------------------");
|
|
33
36
|
if (!viteConfig.define) viteConfig.define = {};
|
|
34
37
|
const version = tryGetNeedleEngineVersion();
|
|
35
|
-
|
|
38
|
+
needleLog("needle-defines", "Needle Engine Version: " + version + " " + (needleEngineConfig?.generator ?? "(unknown generator)"));
|
|
36
39
|
if (version)
|
|
37
40
|
viteConfig.define.NEEDLE_ENGINE_VERSION = "\"" + version + "\"";
|
|
38
41
|
if (needleEngineConfig)
|
|
@@ -57,11 +60,11 @@ export const needleDefines = (command, needleEngineConfig, userSettings) => {
|
|
|
57
60
|
// this gives a timestamp containing the timezone
|
|
58
61
|
viteConfig.define.NEEDLE_PROJECT_BUILD_TIME = "\"" + new Date().toString() + "\"";
|
|
59
62
|
|
|
60
|
-
const projectId = undefined; // TODO: this needs to be exported by the integration (if any)
|
|
63
|
+
const projectId = /** @type {string | undefined} */ (undefined); // TODO: this needs to be exported by the integration (if any)
|
|
61
64
|
const publicIdentifier = await getPublicIdentifier(projectId, {
|
|
62
65
|
loglevel: userSettings?.debugLicense === true ? "verbose" : undefined,
|
|
63
|
-
}).catch(err => {
|
|
64
|
-
|
|
66
|
+
}).catch((/** @type {{ message?: string }} */ err) => {
|
|
67
|
+
needleLog("needle-defines", "Failed to get public identifier: " + err.message, "warn");
|
|
65
68
|
});
|
|
66
69
|
if (publicIdentifier) {
|
|
67
70
|
viteConfig.define.NEEDLE_PUBLIC_KEY = "\"" + publicIdentifier + "\"";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { tryGetNeedleEngineVersion, tryGetPackageVersion } from '../common/version.js';
|
|
2
|
+
import { needleLog } from './logging.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* @type {string[]}
|
|
@@ -39,9 +40,10 @@ const excludeDependencies = [
|
|
|
39
40
|
* @param {import('vite').UserConfig} config
|
|
40
41
|
*/
|
|
41
42
|
function handleOptimizeDeps(config) {
|
|
43
|
+
const logLines = [];
|
|
42
44
|
excludeDependencies.forEach(dep => {
|
|
43
45
|
if (config.optimizeDeps?.include?.includes(dep)) {
|
|
44
|
-
|
|
46
|
+
logLines.push(`${dep} is included in the optimizeDeps.include array. This may cause issues with the worker import.`);
|
|
45
47
|
}
|
|
46
48
|
else {
|
|
47
49
|
if (!config.optimizeDeps) {
|
|
@@ -54,7 +56,7 @@ function handleOptimizeDeps(config) {
|
|
|
54
56
|
// This needs to be excluded from optimization because otherwise the worker import fails
|
|
55
57
|
// three-mesh-bvh/src/workers/generateMeshBVH.worker.js?worker
|
|
56
58
|
// same for gltf-progressive
|
|
57
|
-
|
|
59
|
+
logLines.push(`Adding ${dep} to the optimizeDeps.exclude array to support workers.`);
|
|
58
60
|
config.optimizeDeps.exclude.push(dep);
|
|
59
61
|
|
|
60
62
|
if (!config.server) config.server = {};
|
|
@@ -65,12 +67,14 @@ function handleOptimizeDeps(config) {
|
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
69
|
});
|
|
70
|
+
if (logLines.length) needleLog("needle-dependencies", logLines.join("\n"));
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
/**
|
|
71
74
|
* @param {import('vite').UserConfig} config
|
|
72
75
|
*/
|
|
73
76
|
function handleManualChunks(config) {
|
|
77
|
+
const logLines = [];
|
|
74
78
|
if (!config.build) {
|
|
75
79
|
config.build = {};
|
|
76
80
|
}
|
|
@@ -85,7 +89,7 @@ function handleManualChunks(config) {
|
|
|
85
89
|
|
|
86
90
|
if (Array.isArray(rollupOutput)) {
|
|
87
91
|
// append the manualChunks function to the array
|
|
88
|
-
|
|
92
|
+
logLines.push("registering manualChunks");
|
|
89
93
|
rollupOutput.push({
|
|
90
94
|
manualChunks: needleManualChunks
|
|
91
95
|
})
|
|
@@ -96,37 +100,39 @@ function handleManualChunks(config) {
|
|
|
96
100
|
if ("manualChunks" in rollupOutput) {
|
|
97
101
|
allowManualChunks = false;
|
|
98
102
|
// if the user has already defined manualChunks (even when set to undefined), we don't want to overwrite it
|
|
99
|
-
|
|
103
|
+
logLines.push("manualChunks already found in vite config - will not overwrite it");
|
|
100
104
|
}
|
|
101
105
|
else if (rollupOutput.preserveModules === true) {
|
|
102
106
|
allowManualChunks = false;
|
|
103
|
-
|
|
107
|
+
logLines.push("manualChunks can not be registered because preserveModules is true");
|
|
104
108
|
}
|
|
105
109
|
if (rollupOutput.inlineDynamicImports === true) {
|
|
106
110
|
allowManualChunks = false;
|
|
107
|
-
|
|
111
|
+
logLines.push("manualChunks can not be registered because inlineDynamicImports is true");
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
if (allowManualChunks) {
|
|
111
|
-
|
|
115
|
+
logLines.push("registering manualChunks");
|
|
112
116
|
rollupOutput.manualChunks = needleManualChunks;
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
if (rollupOutput.chunkFileNames) {
|
|
116
|
-
|
|
120
|
+
logLines.push("chunkFileNames already defined");
|
|
117
121
|
}
|
|
118
122
|
else {
|
|
119
123
|
rollupOutput.chunkFileNames = handleChunkFileNames;
|
|
120
124
|
}
|
|
121
125
|
|
|
122
126
|
if (rollupOutput.assetFileNames) {
|
|
123
|
-
|
|
127
|
+
logLines.push("assetFileNames already defined");
|
|
124
128
|
}
|
|
125
129
|
else {
|
|
126
130
|
rollupOutput.assetFileNames = assetFileNames;
|
|
127
131
|
}
|
|
128
132
|
}
|
|
129
133
|
|
|
134
|
+
if (logLines.length) needleLog("needle-dependencies", logLines.join("\n"));
|
|
135
|
+
|
|
130
136
|
// TODO: this was a test if it allows us to remove the sync import of postprocessing due to n8ao's import
|
|
131
137
|
// config.build.rollupOptions.external = (source, importer, isResolved) => {
|
|
132
138
|
// if (importer?.includes("node_modules/n8ao/") || importer?.includes("node_modules/postprocessing/")) {
|
|
@@ -159,7 +165,7 @@ function handleManualChunks(config) {
|
|
|
159
165
|
}
|
|
160
166
|
}
|
|
161
167
|
catch (e) {
|
|
162
|
-
|
|
168
|
+
needleLog("needle-dependencies", "Error reading version " + e, "warn");
|
|
163
169
|
}
|
|
164
170
|
}
|
|
165
171
|
else if (chunk.name === 'three') {
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import { exec, execSync } from 'child_process';
|
|
2
3
|
import { existsSync, readFileSync, rmSync, statSync, writeFileSync } from 'fs';
|
|
3
4
|
import path from 'path';
|
|
5
|
+
import { needleLog } from './logging.js';
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
/** @typedef {{dependencies?: Record<string, string>, devDependencies?: Record<string, string>}} PackageJson */
|
|
8
|
+
|
|
9
|
+
/** @param {...string} msg */
|
|
6
10
|
function log(...msg) {
|
|
7
|
-
|
|
11
|
+
needleLog("needle-dependency-watcher", msg.join(" "));
|
|
8
12
|
}
|
|
9
13
|
|
|
10
14
|
/**
|
|
15
|
+
* @param {string} command
|
|
16
|
+
* @param {unknown} config
|
|
11
17
|
* @param {import('../types').userSettings} userSettings
|
|
12
18
|
*/
|
|
13
19
|
export const needleDependencyWatcher = (command, config, userSettings) => {
|
|
@@ -19,17 +25,26 @@ export const needleDependencyWatcher = (command, config, userSettings) => {
|
|
|
19
25
|
const packageJsonPath = path.join(dir, "package.json");
|
|
20
26
|
const viteCacheDir = path.join(dir, "node_modules", ".vite");
|
|
21
27
|
|
|
22
|
-
return {
|
|
28
|
+
return /** @type {import('vite').Plugin} */ ({
|
|
23
29
|
name: 'needle-dependency-watcher',
|
|
30
|
+
/** @param {import('vite').ViteDevServer} server */
|
|
24
31
|
configureServer(server) {
|
|
25
|
-
watchPackageJson(server, dir, packageJsonPath, viteCacheDir);
|
|
26
32
|
manageClients(server);
|
|
33
|
+
const startWatching = () => watchPackageJson(server, dir, packageJsonPath, viteCacheDir);
|
|
34
|
+
if (server.httpServer?.listening) {
|
|
35
|
+
startWatching();
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
server.httpServer?.once("listening", startWatching);
|
|
39
|
+
}
|
|
27
40
|
}
|
|
28
|
-
}
|
|
41
|
+
});
|
|
29
42
|
}
|
|
30
43
|
|
|
44
|
+
/** @type {Set<{send: (data: string) => void, on: (event: string, cb: () => void) => void}>} */
|
|
31
45
|
const currentClients = new Set();
|
|
32
46
|
|
|
47
|
+
/** @param {import('vite').ViteDevServer} server */
|
|
33
48
|
function manageClients(server) {
|
|
34
49
|
server.ws.on("connection", (socket) => {
|
|
35
50
|
currentClients.add(socket);
|
|
@@ -50,12 +65,22 @@ async function triggerReloadOnClients() {
|
|
|
50
65
|
}
|
|
51
66
|
|
|
52
67
|
|
|
68
|
+
/** @type {import('fs').Stats | undefined} */
|
|
53
69
|
let packageJsonStat;
|
|
70
|
+
/** @type {Date | undefined} */
|
|
54
71
|
let lastEditTime;
|
|
72
|
+
/** @type {number | undefined} */
|
|
55
73
|
let packageJsonSize;
|
|
74
|
+
/** @type {PackageJson | undefined} */
|
|
56
75
|
let packageJson;
|
|
57
76
|
let requireInstall = false;
|
|
58
77
|
|
|
78
|
+
/**
|
|
79
|
+
* @param {import('vite').ViteDevServer} server
|
|
80
|
+
* @param {string} projectDir
|
|
81
|
+
* @param {string} packageJsonPath
|
|
82
|
+
* @param {string} cachePath
|
|
83
|
+
*/
|
|
59
84
|
function watchPackageJson(server, projectDir, packageJsonPath, cachePath) {
|
|
60
85
|
|
|
61
86
|
if (!existsSync(packageJsonPath)) {
|
|
@@ -68,6 +93,7 @@ function watchPackageJson(server, projectDir, packageJsonPath, cachePath) {
|
|
|
68
93
|
packageJsonStat = statSync(packageJsonPath);
|
|
69
94
|
lastEditTime = packageJsonStat.mtime;
|
|
70
95
|
packageJsonSize = packageJsonStat.size;
|
|
96
|
+
/** @type {PackageJson} */
|
|
71
97
|
packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
72
98
|
|
|
73
99
|
setTimeout(() => {
|
|
@@ -91,7 +117,7 @@ function watchPackageJson(server, projectDir, packageJsonPath, cachePath) {
|
|
|
91
117
|
}
|
|
92
118
|
|
|
93
119
|
// test if dependencies changed
|
|
94
|
-
let newPackageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
120
|
+
let newPackageJson = /** @type {PackageJson} */ (JSON.parse(readFileSync(packageJsonPath, "utf8")));
|
|
95
121
|
if (newPackageJson.dependencies) {
|
|
96
122
|
for (const key in newPackageJson.dependencies) {
|
|
97
123
|
if (packageJson.dependencies[key] !== newPackageJson.dependencies[key] && newPackageJson.dependencies[key] !== undefined) {
|
|
@@ -125,6 +151,7 @@ function watchPackageJson(server, projectDir, packageJsonPath, cachePath) {
|
|
|
125
151
|
}, 2000);
|
|
126
152
|
}
|
|
127
153
|
|
|
154
|
+
/** @param {string} projectDir @param {PackageJson | undefined} packageJson @returns {boolean} */
|
|
128
155
|
function testIfInstallIsRequired(projectDir, packageJson) {
|
|
129
156
|
if (packageJson.dependencies) {
|
|
130
157
|
for (const key in packageJson.dependencies) {
|
|
@@ -195,6 +222,7 @@ let isRunningRestart = false;
|
|
|
195
222
|
let restartId = 0;
|
|
196
223
|
let lastRestartTime = 0;
|
|
197
224
|
|
|
225
|
+
/** @param {import('vite').ViteDevServer} server @param {string} projectDir @param {string} cachePath */
|
|
198
226
|
async function restart(server, projectDir, cachePath) {
|
|
199
227
|
|
|
200
228
|
if (isRunningRestart) return;
|
|
@@ -233,7 +261,7 @@ async function restart(server, projectDir, cachePath) {
|
|
|
233
261
|
server.restart();
|
|
234
262
|
}
|
|
235
263
|
isRunningRestart = false;
|
|
236
|
-
|
|
264
|
+
needleLog("needle-dependency-watcher", "-----------------------------------------------");
|
|
237
265
|
}
|
|
238
266
|
catch (err) {
|
|
239
267
|
log("Error restarting server", err);
|
|
@@ -6,8 +6,8 @@ import { Context, destroy, loadSync } from "@needle-tools/engine"
|
|
|
6
6
|
|
|
7
7
|
if (import.meta?.hot) {
|
|
8
8
|
|
|
9
|
-
const previouslyLoaded = [];
|
|
10
|
-
import.meta.hot.on("needle-editor:exported-file", async msg => {
|
|
9
|
+
const previouslyLoaded = /** @type {unknown[]} */ ([]);
|
|
10
|
+
import.meta.hot.on("needle-editor:exported-file", async (/** @type {{ path: string }} */ msg) => {
|
|
11
11
|
try {
|
|
12
12
|
console.log(msg);
|
|
13
13
|
const ctx = Context.Current;
|
|
@@ -21,11 +21,12 @@ if (import.meta?.hot) {
|
|
|
21
21
|
console.log(glb);
|
|
22
22
|
ctx.scene.add(glb.scene);
|
|
23
23
|
}
|
|
24
|
-
catch (err) {
|
|
24
|
+
catch (/** @type {unknown} */ err) {
|
|
25
25
|
console.error(err);
|
|
26
26
|
}
|
|
27
27
|
})
|
|
28
28
|
|
|
29
|
+
/** @param {unknown} target */
|
|
29
30
|
function isNeedleCanvas(target) {
|
|
30
31
|
if (target instanceof HTMLCanvasElement) {
|
|
31
32
|
return true
|
|
@@ -45,8 +46,9 @@ if (import.meta?.hot) {
|
|
|
45
46
|
|
|
46
47
|
window.addEventListener('drop', (e) => {
|
|
47
48
|
if (!isNeedleCanvas(e.target)) return;
|
|
49
|
+
if (!e.dataTransfer) return;
|
|
48
50
|
|
|
49
|
-
for (const file of e.dataTransfer.files) {
|
|
51
|
+
for (const file of /** @type {Iterable<File>} */ (e.dataTransfer.files)) {
|
|
50
52
|
if (file.name.endsWith(".prefab") ||
|
|
51
53
|
file.name.endsWith(".fbx") ||
|
|
52
54
|
file.name.endsWith(".gltf") ||
|
|
@@ -60,7 +62,7 @@ if (import.meta?.hot) {
|
|
|
60
62
|
name: file.name,
|
|
61
63
|
size: file.size,
|
|
62
64
|
lastModified: file.lastModified,
|
|
63
|
-
location: undefined
|
|
65
|
+
location: /** @type {{ x: number, y: number, z: number } | undefined} */ (undefined)
|
|
64
66
|
};
|
|
65
67
|
|
|
66
68
|
const hits = Context.Current?.physics.raycast();
|
package/plugins/vite/drop.js
CHANGED
|
@@ -8,6 +8,8 @@ const __dirname = path.dirname(__filename);
|
|
|
8
8
|
|
|
9
9
|
/** experimental, allow dropping files from Unity into the running scene */
|
|
10
10
|
/**
|
|
11
|
+
* @param {string} command
|
|
12
|
+
* @param {import('../types/needleConfig').needleMeta | null | undefined} config
|
|
11
13
|
* @param {import('../types/userconfig.js').userSettings} userSettings
|
|
12
14
|
*/
|
|
13
15
|
export const needleDrop = (command, config, userSettings) => {
|
|
@@ -17,16 +19,16 @@ export const needleDrop = (command, config, userSettings) => {
|
|
|
17
19
|
|
|
18
20
|
return {
|
|
19
21
|
name: "needle:drop",
|
|
20
|
-
config(
|
|
22
|
+
config(/** @type {{ server?: { hmr?: { port?: number } } }} */ viteConfig) {
|
|
21
23
|
if(userSettings)
|
|
22
|
-
if (!
|
|
23
|
-
if (!
|
|
24
|
-
|
|
25
|
-
setTimeout(() => console.log("Update HMR port to " +
|
|
24
|
+
if (!viteConfig.server) viteConfig.server = {};
|
|
25
|
+
if (!viteConfig.server.hmr) viteConfig.server.hmr = {};
|
|
26
|
+
viteConfig.server.hmr.port = 8080;
|
|
27
|
+
setTimeout(() => console.log("Update HMR port to " + viteConfig.server?.hmr?.port));
|
|
26
28
|
},
|
|
27
29
|
transformIndexHtml: {
|
|
28
30
|
order: 'pre',
|
|
29
|
-
handler(html, _) {
|
|
31
|
+
handler(/** @type {string} */ html, /** @type {unknown} */ _) {
|
|
30
32
|
const file = path.join(__dirname, 'drop-client.js');
|
|
31
33
|
return [
|
|
32
34
|
{
|
|
@@ -40,28 +42,28 @@ export const needleDrop = (command, config, userSettings) => {
|
|
|
40
42
|
];
|
|
41
43
|
},
|
|
42
44
|
},
|
|
43
|
-
configureServer(server) {
|
|
45
|
+
configureServer(/** @type {{ ws: { on(event: string, cb: (...args: unknown[]) => void): void, send(type: string, data?: unknown): void } }} */ server) {
|
|
44
46
|
|
|
45
|
-
server.ws.on('needle:drop-file', async (data, client) => {
|
|
46
|
-
server.ws.send(
|
|
47
|
+
server.ws.on('needle:drop-file', async (/** @type {unknown} */ data, /** @type {unknown} */ client) => {
|
|
48
|
+
server.ws.send('needle-editor:drop-file', data);
|
|
47
49
|
});
|
|
48
50
|
// TODO: not sure how we can receive it with the normal vite server
|
|
49
51
|
// server.ws.on("custom", (data, client) => {
|
|
50
52
|
// console.log(data);
|
|
51
53
|
// })
|
|
52
54
|
|
|
53
|
-
server.ws.on('connection', (socket, request) => {
|
|
54
|
-
socket.on('message', async (bytes) => {
|
|
55
|
+
server.ws.on('connection', (/** @type {{ on(event: string, cb: (...args: unknown[]) => void): void }} */ socket, /** @type {unknown} */ request) => {
|
|
56
|
+
socket.on('message', async (/** @type {Buffer | string} */ bytes) => {
|
|
55
57
|
try {
|
|
56
|
-
const message = Buffer.from(bytes).toString();
|
|
58
|
+
const message = Buffer.from(/** @type {ArrayBuffer} */ (bytes)).toString();
|
|
57
59
|
if (message && message.startsWith("{")) {
|
|
58
|
-
const obj = JSON.parse(message);
|
|
60
|
+
const obj = /** @type {{ type: string, data: unknown }} */ (JSON.parse(message));
|
|
59
61
|
if (obj.type === "needle-editor:exported-file") {
|
|
60
62
|
server.ws.send(obj.type, obj.data);
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
|
-
catch (e) {
|
|
66
|
+
catch (/** @type {{ message?: string }} */ e) {
|
|
65
67
|
console.error(e.message);
|
|
66
68
|
}
|
|
67
69
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { existsSync } from "fs";
|
|
2
|
+
import { needleLog } from "./logging.js";
|
|
2
3
|
|
|
3
4
|
const root = process.cwd();
|
|
4
5
|
|
|
@@ -13,7 +14,7 @@ const editorSyncPackageName = "@needle-tools/editor-sync"
|
|
|
13
14
|
let editorSyncEnabled = false;
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
|
-
* @
|
|
17
|
+
* @type {(command: string, config: { generator?: string | null, needleEditor?: { enabled?: boolean } | string | null, dontInstallEditor?: boolean }, userSettings: { dontInstallEditor?: boolean }, pluginsArray: unknown[]) => Promise<import('vite').Plugin | undefined>}
|
|
17
18
|
*/
|
|
18
19
|
export const editorConnection = async (command, config, userSettings, pluginsArray) => {
|
|
19
20
|
if (command === "build") return;
|
|
@@ -22,7 +23,7 @@ export const editorConnection = async (command, config, userSettings, pluginsArr
|
|
|
22
23
|
if (typeof config.generator === "string" && !config.generator.includes("Unity")) return;
|
|
23
24
|
|
|
24
25
|
if (!config) {
|
|
25
|
-
setTimeout(() =>
|
|
26
|
+
setTimeout(() => needleLog("needle-editor-sync", "Needle Editor Sync can not be installed automatically to vite: missing config", "warn"), 1000);
|
|
26
27
|
return createPlugin(false);
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -37,29 +38,31 @@ export const editorConnection = async (command, config, userSettings, pluginsArr
|
|
|
37
38
|
// }
|
|
38
39
|
// }
|
|
39
40
|
if (needleEditorSettings && needleEditorSettings.enabled === false) {
|
|
40
|
-
setTimeout(() =>
|
|
41
|
+
setTimeout(() => needleLog("needle-editor-sync", "Needle Editor Sync is not enabled. Add a 'Needle Editor Sync' component to your scene to enable", "warn"), 1000);
|
|
41
42
|
return createPlugin(false);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
// Check if the editor package is installed
|
|
45
46
|
let path = root + `/node_modules/${editorSyncPackageName}/plugins/index.js`;
|
|
46
47
|
if (existsSync(path) === false) {
|
|
47
|
-
setTimeout(() =>
|
|
48
|
+
setTimeout(() => needleLog("needle-editor-sync", `${editorSyncPackageName} is not installed: Add the "Needle Editor Sync" component to your scene if you want to send changes directly from the Unity Editor to web app`, "warn"), 1000);
|
|
48
49
|
return createPlugin(false);
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
|
|
52
53
|
// Load vite plugin
|
|
53
54
|
if (!path.startsWith("file:")) path = "file:" + path;
|
|
54
|
-
const { needleEditor } = await import(path);
|
|
55
|
-
setTimeout(() =>
|
|
55
|
+
const { needleEditor } = /** @type {{ needleEditor: () => Record<string, unknown> }} */ (await import(path));
|
|
56
|
+
setTimeout(() => needleLog("needle-editor-sync", "Automatically installed Needle Editor Sync"), 500)
|
|
56
57
|
const method = needleEditor();
|
|
57
|
-
pluginsArray
|
|
58
|
+
const typedPluginsArray = /** @type {Array<Record<string, unknown>>} */ (pluginsArray);
|
|
59
|
+
typedPluginsArray.push(method);
|
|
58
60
|
return createPlugin(true);
|
|
59
61
|
}
|
|
60
62
|
|
|
63
|
+
/** @param {boolean} isInstalled */
|
|
61
64
|
function createPlugin(isInstalled) {
|
|
62
|
-
return {
|
|
65
|
+
return /** @type {import('vite').Plugin} */ ({
|
|
63
66
|
name: "needle-editor-connection",
|
|
64
67
|
// Setup HMR port for connecting to the editor
|
|
65
68
|
config(config) {
|
|
@@ -67,12 +70,12 @@ function createPlugin(isInstalled) {
|
|
|
67
70
|
if (!config.server) config.server = {};
|
|
68
71
|
if (!config.server.hmr) config.server.hmr = {};
|
|
69
72
|
if (config.server.hmr === false) {
|
|
70
|
-
setTimeout(() =>
|
|
73
|
+
setTimeout(() => needleLog("needle-editor-sync", "HMR is disabled, not initializing Needle Editor", "warn"));
|
|
71
74
|
return;
|
|
72
75
|
}
|
|
73
76
|
if (config.server.hmr.port === undefined) {
|
|
74
77
|
config.server.hmr.port = 1107;
|
|
75
|
-
setTimeout(() =>
|
|
78
|
+
setTimeout(() => needleLog("needle-editor-sync", "Update HMR port to " + config.server.hmr.port));
|
|
76
79
|
}
|
|
77
80
|
}
|
|
78
81
|
|
|
@@ -94,7 +97,7 @@ function createPlugin(isInstalled) {
|
|
|
94
97
|
if (bytes?.length < 50) {
|
|
95
98
|
const message = Buffer.from(bytes).toString();
|
|
96
99
|
if (message === "needle:editor:restart") {
|
|
97
|
-
|
|
100
|
+
needleLog("needle-editor-sync", "Received request for a soft restart of the vite server...")
|
|
98
101
|
// This just restarts the vite server
|
|
99
102
|
server.restart();
|
|
100
103
|
}
|
|
@@ -105,7 +108,7 @@ function createPlugin(isInstalled) {
|
|
|
105
108
|
socket.send(JSON.stringify({ type: "pong" }));
|
|
106
109
|
}
|
|
107
110
|
else if (message === "needle:editor:editor-sync-enabled") {
|
|
108
|
-
|
|
111
|
+
needleLog("needle-editor-sync", "Editor sync enabled")
|
|
109
112
|
editorSyncEnabled = true;
|
|
110
113
|
}
|
|
111
114
|
else if (message === "needle:editor:editor-sync-disabled") {
|
|
@@ -115,11 +118,10 @@ function createPlugin(isInstalled) {
|
|
|
115
118
|
})
|
|
116
119
|
});
|
|
117
120
|
}
|
|
118
|
-
catch(err){
|
|
119
|
-
|
|
121
|
+
catch(/** @type {unknown} */ err){
|
|
122
|
+
needleLog("needle-editor-sync", "Error in needle-editor-connection", "error")
|
|
120
123
|
console.error(err)
|
|
121
124
|
}
|
|
122
125
|
}
|
|
123
|
-
|
|
124
|
-
}
|
|
126
|
+
})
|
|
125
127
|
}
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import path from 'path';
|
|
2
3
|
import fs from 'fs';
|
|
3
4
|
|
|
5
|
+
/** @typedef {{ id: string, imports: GraphNode[], importedBy: GraphNode[] }} GraphNode */
|
|
6
|
+
|
|
4
7
|
/**
|
|
8
|
+
* @param {string} command
|
|
9
|
+
* @param {unknown} config
|
|
5
10
|
* @param {import('../types').userSettings} userSettings
|
|
6
11
|
*/
|
|
7
12
|
export const needleImportsLogger = (command, config, userSettings) => {
|
|
8
13
|
|
|
9
14
|
if (!userSettings.debugImportChains) return;
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
/** @type {{allNodes: Map<string, GraphNode>, graph: Record<string, unknown>}} */
|
|
17
|
+
const graph = {
|
|
12
18
|
allNodes: new Map(),
|
|
13
19
|
graph: {},
|
|
14
20
|
};
|
|
@@ -21,6 +27,7 @@ export const needleImportsLogger = (command, config, userSettings) => {
|
|
|
21
27
|
return {
|
|
22
28
|
name: 'needle:imports-logger',
|
|
23
29
|
enforce: 'pre',
|
|
30
|
+
/** @param {string} id @param {string | undefined} importer */
|
|
24
31
|
resolveId(id, importer) {
|
|
25
32
|
|
|
26
33
|
// we want to make a graph of all the imports
|
|
@@ -57,6 +64,7 @@ export const needleImportsLogger = (command, config, userSettings) => {
|
|
|
57
64
|
|
|
58
65
|
return;
|
|
59
66
|
},
|
|
67
|
+
/** @param {Error | undefined} [error] */
|
|
60
68
|
buildEnd(error) {
|
|
61
69
|
try {
|
|
62
70
|
// create log file and append lines to it
|
|
@@ -64,6 +72,7 @@ export const needleImportsLogger = (command, config, userSettings) => {
|
|
|
64
72
|
// append a single line efficiently; replace if necessary
|
|
65
73
|
const fd = fs.openSync(logFile, "w");
|
|
66
74
|
|
|
75
|
+
/** @param {string} str */
|
|
67
76
|
const write = (str) => {
|
|
68
77
|
if (logToConsole)
|
|
69
78
|
console.log(str);
|
|
@@ -76,7 +85,8 @@ export const needleImportsLogger = (command, config, userSettings) => {
|
|
|
76
85
|
}
|
|
77
86
|
|
|
78
87
|
// log graph
|
|
79
|
-
const loggedNodes = new Set();
|
|
88
|
+
const loggedNodes = /** @type {Set<string>} */ (new Set());
|
|
89
|
+
/** @param {GraphNode} node @param {number} depth @param {0|1|2} type */
|
|
80
90
|
const logNode = (node, depth, type) => {
|
|
81
91
|
if (!showOneLevelOfImportsThatWereAlreadyLogged && loggedNodes.has(node.id))
|
|
82
92
|
return;
|