@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,441 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
4
|
-
import { resolve } from 'path';
|
|
5
|
-
import { start } from 'repl';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @typedef {{pluginContext:import('rollup').TransformPluginContext, cache:Cache, command:string, viteConfig:import("vite").ResolvedConfig | null}} Context
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const debug = false;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Checks if the local files plugin is enabled in user settings.
|
|
15
|
-
* @param {import('../types/userconfig.js').userSettings} userSettings - The user settings object
|
|
16
|
-
*/
|
|
17
|
-
export const makeFilesLocalIsEnabled = (userSettings) => {
|
|
18
|
-
if (typeof userSettings?.makeFilesLocal === "object") return userSettings?.makeFilesLocal?.enabled === true;
|
|
19
|
-
return userSettings?.makeFilesLocal === true;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Download files and rewrite code
|
|
24
|
-
* @param {string} command - The command that is being run
|
|
25
|
-
* @param {object} config - The config object
|
|
26
|
-
* @param {import('../types/userconfig.js').userSettings} userSettings
|
|
27
|
-
* @returns {import('vite').Plugin | null}
|
|
28
|
-
*/
|
|
29
|
-
export const needleMakeFilesLocal = (command, config, userSettings) => {
|
|
30
|
-
|
|
31
|
-
if (!makeFilesLocalIsEnabled(userSettings)) {
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
console.log(`[needle:local-files] Local files plugin is enabled`);
|
|
36
|
-
|
|
37
|
-
const cache = new Cache();
|
|
38
|
-
|
|
39
|
-
/** @type {import("vite").ResolvedConfig | null} */
|
|
40
|
-
let viteConfig = null;
|
|
41
|
-
|
|
42
|
-
/** @type {import("vite").Plugin} */
|
|
43
|
-
const plugin = {
|
|
44
|
-
name: "needle:local-files",
|
|
45
|
-
// enforce: 'pre', // explictly DON'T define enforce:pre because of svelte postcss compat
|
|
46
|
-
apply: "build",
|
|
47
|
-
configResolved(config) {
|
|
48
|
-
viteConfig = config;
|
|
49
|
-
},
|
|
50
|
-
// transform bundle
|
|
51
|
-
async transform(src, _id) {
|
|
52
|
-
src = await makeLocal(src, "ext/", "", {
|
|
53
|
-
pluginContext: this,
|
|
54
|
-
cache: cache,
|
|
55
|
-
command: command,
|
|
56
|
-
viteConfig: viteConfig,
|
|
57
|
-
});
|
|
58
|
-
return {
|
|
59
|
-
code: src,
|
|
60
|
-
map: null,
|
|
61
|
-
};
|
|
62
|
-
},
|
|
63
|
-
buildEnd() {
|
|
64
|
-
const map = cache.map;
|
|
65
|
-
console.log(""); // Make a new line for better readability
|
|
66
|
-
console.log(`[needle:local-files] Made ${map.size} files local:`);
|
|
67
|
-
for (const [key, value] of map.entries()) {
|
|
68
|
-
console.log(`- ${key} → ${value}`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return plugin;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Rewrites the source code to make local files
|
|
77
|
-
* @param {string} src - The source code to rewrite
|
|
78
|
-
* @param {string} basePath - The base path where the files will be saved
|
|
79
|
-
* @param {string} currentDir - The current directory of the file being processed
|
|
80
|
-
* @param {Context} context - The Vite plugin context and command
|
|
81
|
-
*/
|
|
82
|
-
async function makeLocal(src, basePath, currentDir, context) {
|
|
83
|
-
|
|
84
|
-
const command = context.command;
|
|
85
|
-
|
|
86
|
-
if (debug) {
|
|
87
|
-
// Find all urls in the source code.
|
|
88
|
-
// Exclude URLs inside comments, like:
|
|
89
|
-
// - // https://example.com
|
|
90
|
-
// - /* ... https://example.com ... */
|
|
91
|
-
// - @link https://example.com
|
|
92
|
-
// - * ... https://example.com
|
|
93
|
-
const urlRegexExcludingComments = /(?<!\/\/.*)(?<!\/\*.*)(?<!@link\s+)(["'])(https?:\/\/[^\s'"]+?)\1/g;
|
|
94
|
-
let match0;
|
|
95
|
-
while ((match0 = urlRegexExcludingComments.exec(src)) !== null) {
|
|
96
|
-
const url = match0[2];
|
|
97
|
-
if (debug) console.log(`\nFound URL: ${url} in ${currentDir}`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Google Fonts URLs
|
|
102
|
-
while (true) {
|
|
103
|
-
const match = /["'](https:\/\/fonts\.googleapis\.com\/.+?)["']/g.exec(src);
|
|
104
|
-
if (match === null) {
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
const url = match[1];
|
|
108
|
-
if (debug) console.log(`\nFound google font URL: ${url}`);
|
|
109
|
-
// Check if the font URL is already in the cache
|
|
110
|
-
const cachedPath = context.cache.getFromCache(url);
|
|
111
|
-
if (cachedPath) {
|
|
112
|
-
if (debug) console.log(`Using cached font URL: ${cachedPath}`);
|
|
113
|
-
src = src.replace(url, cachedPath);
|
|
114
|
-
continue; // Skip downloading if already cached
|
|
115
|
-
}
|
|
116
|
-
let font = await downloadText(url);
|
|
117
|
-
const familyNameMatch = /family=([^&]+)/.exec(url);
|
|
118
|
-
const familyName = familyNameMatch ? getValidFilename(familyNameMatch[1], font) : (new URL(url).pathname.split('/').pop());
|
|
119
|
-
font = await makeLocal(font, basePath, basePath, context);
|
|
120
|
-
const fontFileName = `font-${familyName}.css`;
|
|
121
|
-
const outputPath = basePath + fontFileName;
|
|
122
|
-
let newPath;
|
|
123
|
-
if (command === 'build') {
|
|
124
|
-
const referenceId = context.pluginContext.emitFile({
|
|
125
|
-
type: 'asset',
|
|
126
|
-
fileName: outputPath,
|
|
127
|
-
source: font,
|
|
128
|
-
});
|
|
129
|
-
const localPath = `${context.pluginContext.getFileName(referenceId)}`;
|
|
130
|
-
newPath = getRelativeToBasePath(localPath, currentDir);
|
|
131
|
-
// ensureFileExists(localPath, font);
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
// Create base64 URL for dev mode
|
|
135
|
-
const base64Font = Buffer.from(font).toString('base64');
|
|
136
|
-
newPath = `data:text/css;base64,${base64Font}`;
|
|
137
|
-
}
|
|
138
|
-
if (newPath) {
|
|
139
|
-
context.cache.addToCache(url, newPath);
|
|
140
|
-
src = src.replace(url, newPath);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Google Fonts gstatic URLs
|
|
145
|
-
while (true) {
|
|
146
|
-
const match = /["'(](https:\/\/fonts\.gstatic\.com\/)(.+?)["')]/g.exec(src);
|
|
147
|
-
if (match === null) {
|
|
148
|
-
break;
|
|
149
|
-
}
|
|
150
|
-
const fontPath = match[2];
|
|
151
|
-
const url = match[1] + fontPath;
|
|
152
|
-
if (debug) console.log(`\nFound gstatic URL: ${url}`);
|
|
153
|
-
// Check if the font URL is already in the cache
|
|
154
|
-
const cachedPath = context.cache.getFromCache(url);
|
|
155
|
-
if (cachedPath) {
|
|
156
|
-
if (debug) console.log(`Using cached gstatic font URL: ${cachedPath}`);
|
|
157
|
-
src = src.replace(url, cachedPath);
|
|
158
|
-
continue; // Skip downloading if already cached
|
|
159
|
-
}
|
|
160
|
-
const font = await downloadBinary(url);
|
|
161
|
-
const filename = getValidFilename(fontPath, font);
|
|
162
|
-
if (debug) console.log(`Saving font to: ${basePath + filename}`);
|
|
163
|
-
let newPath;
|
|
164
|
-
if (command === 'build') {
|
|
165
|
-
const referenceId = context.pluginContext.emitFile({
|
|
166
|
-
type: 'asset',
|
|
167
|
-
fileName: basePath + filename,
|
|
168
|
-
source: font,
|
|
169
|
-
});
|
|
170
|
-
const localPath = `${context.pluginContext.getFileName(referenceId)}`;
|
|
171
|
-
newPath = getRelativeToBasePath(localPath, currentDir);
|
|
172
|
-
// ensureFileExists(localPath, font);
|
|
173
|
-
} else {
|
|
174
|
-
// Create base64 URL for dev mode
|
|
175
|
-
const base64Font = Buffer.from(font).toString('base64');
|
|
176
|
-
newPath = `data:text/css;base64,${base64Font}`;
|
|
177
|
-
}
|
|
178
|
-
context.cache.addToCache(url, newPath);
|
|
179
|
-
src = src.replace(url, newPath);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Load QRCode.js
|
|
183
|
-
while (true) {
|
|
184
|
-
// https://cdn.jsdelivr.net/gh/davidshimjs/qrcodejs@gh-pages/qrcode.min.js
|
|
185
|
-
const match = /["'](https:\/\/cdn\.jsdelivr\.net\/gh\/davidshimjs\/qrcodejs@[^'"]+?\/qrcode\.min\.js)["']/g.exec(src);
|
|
186
|
-
if (match === null) {
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
const url = match[1];
|
|
190
|
-
if (debug) console.log(`\nFound QR code URL: ${url}`);
|
|
191
|
-
// Check if the QR code URL is already in the cache
|
|
192
|
-
const cachedPath = context.cache.getFromCache(url);
|
|
193
|
-
if (cachedPath) {
|
|
194
|
-
if (debug) console.log(`Using cached QR code URL: ${cachedPath}`);
|
|
195
|
-
src = src.replace(url, cachedPath);
|
|
196
|
-
continue; // Skip downloading if already cached
|
|
197
|
-
}
|
|
198
|
-
const qrCode = await downloadBinary(url);
|
|
199
|
-
const filename = getValidFilename(url, qrCode);
|
|
200
|
-
if (debug) console.log(`Saving QR code to: ${basePath + filename}`);
|
|
201
|
-
let newPath;
|
|
202
|
-
if (command === 'build') {
|
|
203
|
-
const referenceId = context.pluginContext.emitFile({
|
|
204
|
-
type: 'asset',
|
|
205
|
-
fileName: basePath + filename,
|
|
206
|
-
source: qrCode,
|
|
207
|
-
});
|
|
208
|
-
const localPath = `${context.pluginContext.getFileName(referenceId)}`;
|
|
209
|
-
newPath = getRelativeToBasePath(localPath, currentDir);
|
|
210
|
-
// ensureFileExists(localPath, qrCode);
|
|
211
|
-
} else {
|
|
212
|
-
// create base64 URL for dev mode
|
|
213
|
-
const base64QrCode = Buffer.from(qrCode).toString('base64');
|
|
214
|
-
newPath = `data:application/javascript;base64,${base64QrCode}`;
|
|
215
|
-
}
|
|
216
|
-
context.cache.addToCache(url, newPath);
|
|
217
|
-
src = src.replace(url, newPath);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Polyhaven.org URLs
|
|
221
|
-
let startIndex = 0;
|
|
222
|
-
while (true) {
|
|
223
|
-
const match = /["'](https:\/\/dl\.polyhaven\.org\/file\/.+?)["']/g.exec(src.slice(startIndex));
|
|
224
|
-
if (match === null) {
|
|
225
|
-
break;
|
|
226
|
-
}
|
|
227
|
-
startIndex += match.index + match[0].length; // Update startIndex to continue searching
|
|
228
|
-
const url = match[1];
|
|
229
|
-
if (url.endsWith("/")) {
|
|
230
|
-
if (debug) console.warn(`Skipping Polyhaven URL that ends with a slash: ${url}`);
|
|
231
|
-
continue; // Skip URLs that end with a slash
|
|
232
|
-
}
|
|
233
|
-
if (url.includes("\"") || url.includes("'")) {
|
|
234
|
-
if (debug) console.warn(`Skipping Polyhaven URL with quotes: ${url}`);
|
|
235
|
-
continue; // Skip URLs with quotes
|
|
236
|
-
}
|
|
237
|
-
if (debug) console.log(`\nFound Polyhaven URL: ${url}`);
|
|
238
|
-
// Check if the Polyhaven URL is already in the cache
|
|
239
|
-
const cachedPath = context.cache.getFromCache(url);
|
|
240
|
-
if (cachedPath) {
|
|
241
|
-
if (debug) console.log(`Using cached Polyhaven URL: ${cachedPath}`);
|
|
242
|
-
src = src.replace(url, cachedPath);
|
|
243
|
-
continue; // Skip downloading if already cached
|
|
244
|
-
}
|
|
245
|
-
const polyhavenFile = await downloadBinary(url);
|
|
246
|
-
const filename = getValidFilename(url, polyhavenFile);
|
|
247
|
-
if (debug) console.log(`Saving Polyhaven file to: ${basePath + filename}`);
|
|
248
|
-
let newPath;
|
|
249
|
-
if (command === 'build') {
|
|
250
|
-
const referenceId = context.pluginContext.emitFile({
|
|
251
|
-
type: 'asset',
|
|
252
|
-
fileName: basePath + filename,
|
|
253
|
-
source: polyhavenFile,
|
|
254
|
-
});
|
|
255
|
-
const localPath = `${context.pluginContext.getFileName(referenceId)}`;
|
|
256
|
-
newPath = getRelativeToBasePath(localPath, currentDir);
|
|
257
|
-
// ensureFileExists(localPath, polyhavenFile);
|
|
258
|
-
} else {
|
|
259
|
-
// Create base64 URL for dev mode
|
|
260
|
-
const base64PolyhavenFile = Buffer.from(polyhavenFile).toString('base64');
|
|
261
|
-
newPath = `data:application/octet-stream;base64,${base64PolyhavenFile}`;
|
|
262
|
-
}
|
|
263
|
-
if (newPath) {
|
|
264
|
-
context.cache.addToCache(url, newPath);
|
|
265
|
-
src = src.replace(url, newPath);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return src;
|
|
270
|
-
|
|
271
|
-
// /**
|
|
272
|
-
// * Ensures that a file exists at the specified relative path with the given content.
|
|
273
|
-
// * If the file does not exist, it will be created with the provided content.
|
|
274
|
-
// * @param {string} relPath - The relative path to the file
|
|
275
|
-
// * @param {string|Uint8Array} content - The content to write to the file
|
|
276
|
-
// * @returns {void}
|
|
277
|
-
// */
|
|
278
|
-
// function ensureFileExists(relPath, content) {
|
|
279
|
-
// const outputPath = context.viteConfig?.build?.outDir || "dist";
|
|
280
|
-
// const fullPath = resolve(outputPath, relPath);
|
|
281
|
-
// if (!existsSync(fullPath)) {
|
|
282
|
-
// if (debug) console.log(`Creating file: ${fullPath}`);
|
|
283
|
-
// const dir = resolve(fullPath, '..');
|
|
284
|
-
// mkdirSync(dir, { recursive: true });
|
|
285
|
-
// writeFileSync(fullPath, content);
|
|
286
|
-
// }
|
|
287
|
-
// }
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
class Cache {
|
|
292
|
-
__cache = new Map();
|
|
293
|
-
/**
|
|
294
|
-
* Adds a key-value pair to the cache.
|
|
295
|
-
* @param {string} key - The key to store the value under
|
|
296
|
-
* @param {string|Uint8Array} value - The value to store in the cache
|
|
297
|
-
* @returns {void}
|
|
298
|
-
*/
|
|
299
|
-
addToCache(key, value) {
|
|
300
|
-
if (this.__cache.has(key)) {
|
|
301
|
-
if (debug) console.warn(`Key ${key} already exists in cache, overwriting.`);
|
|
302
|
-
}
|
|
303
|
-
this.__cache.set(key, value);
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Retrieves a value from the cache by its key.
|
|
307
|
-
* @param {string} key - The key to look up in the cache
|
|
308
|
-
*/
|
|
309
|
-
getFromCache(key) {
|
|
310
|
-
if (this.__cache.has(key)) {
|
|
311
|
-
return this.__cache.get(key);
|
|
312
|
-
} else {
|
|
313
|
-
return null;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
get map() {
|
|
317
|
-
return this.__cache;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Returns a relative path based on the base path.
|
|
324
|
-
* @param {string} path - The path to check
|
|
325
|
-
* @param {string | undefined | null} basePath - The base path to compare against
|
|
326
|
-
* @return {string} - The relative path if it starts with the base path, otherwise the original path
|
|
327
|
-
*/
|
|
328
|
-
function getRelativeToBasePath(path, basePath) {
|
|
329
|
-
if (basePath?.length && path.startsWith(basePath)) {
|
|
330
|
-
return "./" + path.substring(basePath.length);
|
|
331
|
-
}
|
|
332
|
-
return path;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Generates a valid filename from a given path.
|
|
338
|
-
* @param {string} path - The path to generate a filename from
|
|
339
|
-
* @param {string|Uint8Array} content - The content to hash for uniqueness (not used in this example)
|
|
340
|
-
*/
|
|
341
|
-
function getValidFilename(path, content) {
|
|
342
|
-
if (path.startsWith("http:") || path.startsWith("https:")) {
|
|
343
|
-
const url = new URL(path);
|
|
344
|
-
const pathParts = url.pathname.split('/');
|
|
345
|
-
const filename = pathParts.pop() || 'file';
|
|
346
|
-
const nameParts = filename.split('.');
|
|
347
|
-
const nameWithoutExt = nameParts.slice(0, -1).join('.');
|
|
348
|
-
path = `${nameWithoutExt}-${createContentMd5(url.host + pathParts.join('/'))}.${nameParts.pop() || 'unknown'}`;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// Remove any characters that are not valid in filenames
|
|
352
|
-
let name = path.replace(/[^a-z0-9_\-\.\+]/gi, '-');
|
|
353
|
-
|
|
354
|
-
const maxLength = 200;
|
|
355
|
-
if (path.length > maxLength) {
|
|
356
|
-
// If the name is too long, hash it to create a unique identifier
|
|
357
|
-
const hash = createContentMd5(content);
|
|
358
|
-
let ext = "";
|
|
359
|
-
const extIndex = name.lastIndexOf('.');
|
|
360
|
-
if (extIndex !== -1) {
|
|
361
|
-
ext = name.substring(extIndex + 1);
|
|
362
|
-
name = name.substring(0, extIndex);
|
|
363
|
-
}
|
|
364
|
-
name = `${name.substring(0, maxLength)}-${hash}${ext ? `.${ext}` : ''}`;
|
|
365
|
-
}
|
|
366
|
-
return name;
|
|
367
|
-
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Creates a hash of the content using MD5.
|
|
372
|
-
* @param {string|Uint8Array} str - The content to hash
|
|
373
|
-
*/
|
|
374
|
-
function createContentMd5(str) {
|
|
375
|
-
return createHash('md5')
|
|
376
|
-
.update(str)
|
|
377
|
-
.digest('hex');
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* @param {string} url - The URL of the font to download
|
|
383
|
-
*/
|
|
384
|
-
function downloadText(url) {
|
|
385
|
-
return new Promise(((res, rej) => {
|
|
386
|
-
https.get(url, (response) => {
|
|
387
|
-
if (response.statusCode !== 200) {
|
|
388
|
-
console.log();
|
|
389
|
-
console.error(`Failed to download (${response.statusCode}): ${url}`);
|
|
390
|
-
rej(new Error(`Failed to download (${response.statusCode}): ${url}`));
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
console.log(""); // Make a new line for better readability
|
|
395
|
-
console.log(`[needle:local-files] Make local: ${url}`);
|
|
396
|
-
|
|
397
|
-
let data = '';
|
|
398
|
-
response.on('data', (chunk) => {
|
|
399
|
-
data += chunk;
|
|
400
|
-
});
|
|
401
|
-
response.on('end', () => {
|
|
402
|
-
// Here you can save the data to a file or process it as needed
|
|
403
|
-
if (debug) console.log(`Downloaded from ${url}`);
|
|
404
|
-
res(data);
|
|
405
|
-
});
|
|
406
|
-
});
|
|
407
|
-
}))
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
function downloadBinary(url) {
|
|
411
|
-
return new Promise((res, rej) => {
|
|
412
|
-
https.get(url, (response) => {
|
|
413
|
-
|
|
414
|
-
// Handle redirects
|
|
415
|
-
if (response.statusCode && response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
|
|
416
|
-
if (debug) console.log(`Redirecting to ${response.headers.location}`);
|
|
417
|
-
return downloadBinary(response.headers.location).then(res).catch(rej);
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
if (response.statusCode !== 200) {
|
|
421
|
-
console.log();
|
|
422
|
-
console.error(`Failed to download (${response.statusCode}): ${url}`);
|
|
423
|
-
rej(new Error(`Failed to download (${response.statusCode}): ${url}`));
|
|
424
|
-
return;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
console.log(""); // Make a new line for better readability
|
|
428
|
-
console.log(`[needle:local-files] Make local: ${url}`);
|
|
429
|
-
|
|
430
|
-
const chunks = [];
|
|
431
|
-
response.on('data', (chunk) => {
|
|
432
|
-
chunks.push(chunk);
|
|
433
|
-
});
|
|
434
|
-
response.on('end', () => {
|
|
435
|
-
// Here you can save the data to a file or process it as needed
|
|
436
|
-
if (debug) console.log(`Downloaded from ${url}`);
|
|
437
|
-
res(Buffer.concat(chunks));
|
|
438
|
-
});
|
|
439
|
-
});
|
|
440
|
-
});
|
|
441
|
-
}
|
|
1
|
+
export { needleMakeFilesLocal, makeFilesLocalIsEnabled } from './local-files-core.js';
|
|
2
|
+
export { needleLocalFilesSceneAnalysis } from './local-files-analysis.js';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import path from "path";
|
|
2
3
|
|
|
3
4
|
let isStringifying = false;
|
|
@@ -6,7 +7,7 @@ let isStringifying = false;
|
|
|
6
7
|
* Patches console methods to capture log messages and send them to the server.
|
|
7
8
|
* This is useful for debugging and logging in the client.
|
|
8
9
|
* @param {"log" | "warn" | "info" | "debug" | "error" | "internal"} level
|
|
9
|
-
* @param {
|
|
10
|
+
* @param {...unknown} message - The log message to capture.
|
|
10
11
|
*/
|
|
11
12
|
function sendLogToServer(level, ...message) {
|
|
12
13
|
if (isStringifying) return;
|
|
@@ -14,20 +15,20 @@ function sendLogToServer(level, ...message) {
|
|
|
14
15
|
try {
|
|
15
16
|
isStringifying = true;
|
|
16
17
|
// console.time("sendLogToServer");
|
|
17
|
-
|
|
18
|
+
let msg = /** @type {string} */ (stringifyLog(message));
|
|
18
19
|
// console.timeEnd("sendLogToServer");
|
|
19
20
|
// keep messages below payload limit
|
|
20
|
-
if (
|
|
21
|
-
|
|
21
|
+
if (msg.length > 100_000) {
|
|
22
|
+
msg = msg.slice(0, 100_000) + "... <truncated>";
|
|
22
23
|
}
|
|
23
24
|
// @ts-ignore
|
|
24
|
-
import.meta.hot.send("needle:client-log", { level, message:
|
|
25
|
-
} catch (e) {
|
|
25
|
+
import.meta.hot.send("needle:client-log", { level, message: msg });
|
|
26
|
+
} catch (/** @type {{ message?: string }} */ e) {
|
|
26
27
|
// silently fail but send a message
|
|
27
28
|
try {
|
|
28
29
|
import.meta.hot.send("needle:client-log", { level: "error", message: `Error during logging: ${e.message}` });
|
|
29
30
|
}
|
|
30
|
-
catch (e2) {
|
|
31
|
+
catch (/** @type {unknown} */ e2) {
|
|
31
32
|
// fallback failed as well
|
|
32
33
|
}
|
|
33
34
|
}
|
|
@@ -37,6 +38,7 @@ function sendLogToServer(level, ...message) {
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
/** @param {(...args: unknown[]) => void} fn @param {unknown[]} args */
|
|
40
42
|
function logHelper(fn, args) {
|
|
41
43
|
const error = new Error();
|
|
42
44
|
const stack = error.stack;
|
|
@@ -52,32 +54,32 @@ function logHelper(fn, args) {
|
|
|
52
54
|
if (import.meta && "hot" in import.meta) {
|
|
53
55
|
|
|
54
56
|
function patchLogs() {
|
|
55
|
-
const originalLog = console.log.bind(console);
|
|
56
|
-
const originalWarn = console.warn.bind(console);
|
|
57
|
-
const originalInfo = console.info.bind(console);
|
|
58
|
-
const originalDebug = console.debug.bind(console);
|
|
59
|
-
const originalError = console.error.bind(console);
|
|
57
|
+
const originalLog = /** @type {(...args: unknown[]) => void} */ (console.log.bind(console));
|
|
58
|
+
const originalWarn = /** @type {(...args: unknown[]) => void} */ (console.warn.bind(console));
|
|
59
|
+
const originalInfo = /** @type {(...args: unknown[]) => void} */ (console.info.bind(console));
|
|
60
|
+
const originalDebug = /** @type {(...args: unknown[]) => void} */ (console.debug.bind(console));
|
|
61
|
+
const originalError = /** @type {(...args: unknown[]) => void} */ (console.error.bind(console));
|
|
60
62
|
|
|
61
|
-
console.log = function (...args) {
|
|
63
|
+
console.log = /** @type {(...args: unknown[]) => void} */ (function (...args) {
|
|
62
64
|
logHelper(originalLog, args);
|
|
63
65
|
sendLogToServer("log", ...args);
|
|
64
|
-
}
|
|
65
|
-
console.warn = (...args) => {
|
|
66
|
+
})
|
|
67
|
+
console.warn = /** @type {(...args: unknown[]) => void} */ ((...args) => {
|
|
66
68
|
logHelper(originalWarn, args);
|
|
67
69
|
sendLogToServer("warn", ...args);
|
|
68
|
-
}
|
|
69
|
-
console.info = (...args) => {
|
|
70
|
+
})
|
|
71
|
+
console.info = /** @type {(...args: unknown[]) => void} */ ((...args) => {
|
|
70
72
|
logHelper(originalInfo, args);
|
|
71
73
|
sendLogToServer("info", ...args);
|
|
72
|
-
}
|
|
73
|
-
console.debug = (...args) => {
|
|
74
|
+
})
|
|
75
|
+
console.debug = /** @type {(...args: unknown[]) => void} */ ((...args) => {
|
|
74
76
|
logHelper(originalDebug, args);
|
|
75
77
|
sendLogToServer("debug", ...args);
|
|
76
|
-
}
|
|
77
|
-
console.error = (...args) => {
|
|
78
|
+
})
|
|
79
|
+
console.error = /** @type {(...args: unknown[]) => void} */ ((...args) => {
|
|
78
80
|
logHelper(originalError, args);
|
|
79
81
|
sendLogToServer("error", ...args);
|
|
80
|
-
}
|
|
82
|
+
})
|
|
81
83
|
return () => {
|
|
82
84
|
console.log = originalLog;
|
|
83
85
|
console.warn = originalWarn;
|
|
@@ -125,11 +127,12 @@ Connection: ${"connection" in navigator ? JSON.stringify(navigator.connection) :
|
|
|
125
127
|
User Activation: ${"userActivation" in navigator ? JSON.stringify(navigator.userActivation) : "Not available"}
|
|
126
128
|
`);
|
|
127
129
|
|
|
130
|
+
/** @typedef {{ vendor?: string, architecture?: string, device?: string, description?: string, features?: unknown, limits?: unknown }} GPUAdapterInfoLike */
|
|
128
131
|
if ("gpu" in navigator) {
|
|
129
132
|
// @ts-ignore
|
|
130
133
|
navigator.gpu.requestAdapter()
|
|
131
|
-
.then(adapter => adapter ? adapter.requestDevice() : null)
|
|
132
|
-
.then(device => {
|
|
134
|
+
.then(/** @type {(adapter: {requestDevice(): Promise<{adapterInfo: GPUAdapterInfoLike}>}|null) => Promise<{adapterInfo: GPUAdapterInfoLike}>|null} */ (adapter) => adapter ? adapter.requestDevice() : null)
|
|
135
|
+
.then(/** @type {(device: {adapterInfo: GPUAdapterInfoLike}|null) => void} */ (device) => {
|
|
133
136
|
if (device) {
|
|
134
137
|
const adapterInfo = device.adapterInfo;
|
|
135
138
|
if (adapterInfo) {
|
|
@@ -146,17 +149,21 @@ User Activation: ${"userActivation" in navigator ? JSON.stringify(navigator.user
|
|
|
146
149
|
});
|
|
147
150
|
}
|
|
148
151
|
}
|
|
149
|
-
catch (e) {
|
|
152
|
+
catch (/** @type {{ message?: string }} */ e) {
|
|
150
153
|
// silently fail
|
|
151
154
|
sendLogToServer("error", `Error during initial log: ${e.message}`);
|
|
152
155
|
}
|
|
153
156
|
|
|
154
157
|
window.addEventListener('error', (event) => {
|
|
155
|
-
const
|
|
158
|
+
const typedErrorEvent = /** @type {{ error: unknown, message: string }} */ (/** @type {unknown} */ (event));
|
|
159
|
+
const error = /** @type {{ stack?: string, message?: string } | null | undefined} */ (typedErrorEvent.error);
|
|
160
|
+
const errorMessage = error ? error.stack || error.message : typedErrorEvent.message;
|
|
156
161
|
sendLogToServer("error", errorMessage);
|
|
157
162
|
});
|
|
158
163
|
window.addEventListener('unhandledrejection', (event) => {
|
|
159
|
-
const
|
|
164
|
+
const typedRejEvent = /** @type {{ reason: unknown }} */ (/** @type {unknown} */ (event));
|
|
165
|
+
const rejectionReason = /** @type {{ stack?: string, message?: string } | null | undefined} */ (typedRejEvent.reason);
|
|
166
|
+
const reason = rejectionReason ? rejectionReason.stack || rejectionReason.message : "Unhandled rejection without reason";
|
|
160
167
|
sendLogToServer("error", `Unhandled promise rejection: ${reason}`);
|
|
161
168
|
});
|
|
162
169
|
window.addEventListener('beforeunload', () => {
|
|
@@ -211,7 +218,7 @@ User Activation: ${"userActivation" in navigator ? JSON.stringify(navigator.user
|
|
|
211
218
|
sendLogToServer("internal", `URL hash changed to ${location.hash}`);
|
|
212
219
|
});
|
|
213
220
|
window.addEventListener('popstate', () => {
|
|
214
|
-
sendLogToServer("internal", `History state changed: ${JSON.stringify(history.state)}`);
|
|
221
|
+
sendLogToServer("internal", `History state changed: ${JSON.stringify(/** @type {{ state: unknown }} */ (history).state)}`);
|
|
215
222
|
});
|
|
216
223
|
|
|
217
224
|
|
|
@@ -227,10 +234,10 @@ User Activation: ${"userActivation" in navigator ? JSON.stringify(navigator.user
|
|
|
227
234
|
|
|
228
235
|
/**
|
|
229
236
|
* Stringifies a log message, handling circular references and formatting.
|
|
230
|
-
* @param {
|
|
231
|
-
* @param {Set<
|
|
237
|
+
* @param {unknown} log
|
|
238
|
+
* @param {Set<unknown>} [seen]
|
|
232
239
|
*/
|
|
233
|
-
function stringifyLog(log, seen = new Set(), depth = 0) {
|
|
240
|
+
function stringifyLog(log, seen = /** @type {Set<unknown>} */ (new Set()), depth = 0) {
|
|
234
241
|
const isServer = typeof window === "undefined";
|
|
235
242
|
const stringify_limits = {
|
|
236
243
|
string: isServer ? 100_000 : 1_000,
|
|
@@ -272,8 +279,9 @@ function stringifyLog(log, seen = new Set(), depth = 0) {
|
|
|
272
279
|
|| log instanceof BigUint64Array
|
|
273
280
|
|| log instanceof Float64Array
|
|
274
281
|
) {
|
|
275
|
-
|
|
276
|
-
|
|
282
|
+
const logArr = /** @type {ArrayLike<unknown>} */ (/** @type {unknown} */ (log));
|
|
283
|
+
seen.add(logArr);
|
|
284
|
+
return stringifyArray(logArr);
|
|
277
285
|
}
|
|
278
286
|
if (typeof log === "object") {
|
|
279
287
|
|
|
@@ -287,11 +295,12 @@ function stringifyLog(log, seen = new Set(), depth = 0) {
|
|
|
287
295
|
return `<Error: ${log.message}\nStack: ${log.stack}>`;
|
|
288
296
|
}
|
|
289
297
|
|
|
290
|
-
const
|
|
298
|
+
const logObj = /** @type {Record<string, unknown>} */ (log);
|
|
299
|
+
const keys = Object.keys(logObj);
|
|
291
300
|
let res = "{";
|
|
292
301
|
for (let i = 0; i < keys.length; i++) {
|
|
293
302
|
const key = keys[i];
|
|
294
|
-
let value =
|
|
303
|
+
let value = logObj[key];
|
|
295
304
|
if (i >= stringify_limits.object_keys) {
|
|
296
305
|
res += `, ... <truncated ${keys.length - i} keys>`;
|
|
297
306
|
break;
|
|
@@ -326,6 +335,7 @@ function stringifyLog(log, seen = new Set(), depth = 0) {
|
|
|
326
335
|
|
|
327
336
|
return String(log);
|
|
328
337
|
|
|
338
|
+
/** @param {ArrayLike<unknown>} arr @returns {string} */
|
|
329
339
|
function stringifyArray(arr) {
|
|
330
340
|
let res = "";
|
|
331
341
|
for (let i = 0; i < arr.length; i++) {
|
package/plugins/vite/logger.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import { existsSync, readFileSync } from 'fs';
|
|
2
3
|
import path from 'path';
|
|
3
4
|
import { fileURLToPath } from 'url';
|
|
@@ -9,6 +10,8 @@ const __dirname = path.dirname(__filename);
|
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* write logs to local file
|
|
13
|
+
* @param {string} command
|
|
14
|
+
* @param {unknown} config
|
|
12
15
|
* @param {import('../types/userconfig.js').userSettings} userSettings
|
|
13
16
|
* @returns {import('vite').Plugin | null}
|
|
14
17
|
*/
|
|
@@ -18,7 +21,7 @@ export const needleLogger = (command, config, userSettings) => {
|
|
|
18
21
|
return null;
|
|
19
22
|
}
|
|
20
23
|
|
|
21
|
-
patchConsoleLogs();
|
|
24
|
+
patchConsoleLogs({ command });
|
|
22
25
|
captureLogMessage("server", "info", "Vite started with command \"" + command + "\" in " + __dirname, null);
|
|
23
26
|
|
|
24
27
|
return {
|
|
@@ -51,7 +54,7 @@ export const needleLogger = (command, config, userSettings) => {
|
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
56
|
},
|
|
54
|
-
}
|
|
57
|
+
}
|
|
55
58
|
}
|
|
56
59
|
}
|
|
57
60
|
|
|
@@ -81,7 +84,7 @@ function logRequests(server, log_http_requests = false) {
|
|
|
81
84
|
});
|
|
82
85
|
});
|
|
83
86
|
// Client log messages via websocket
|
|
84
|
-
server.ws.on('needle:client-log', async (data, client) => {
|
|
87
|
+
server.ws.on('needle:client-log', async (/** @type {{level: string, message: unknown}} */ data, /** @type {{socket: import('net').Socket}} */ client) => {
|
|
85
88
|
if (!data || !data.level || !data.message) {
|
|
86
89
|
console.warn("Received empty log data, ignoring");
|
|
87
90
|
return;
|