almostnode 0.1.0
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/LICENSE +21 -0
- package/README.md +731 -0
- package/dist/__sw__.js +394 -0
- package/dist/ai-chatbot-demo-entry.d.ts +6 -0
- package/dist/ai-chatbot-demo-entry.d.ts.map +1 -0
- package/dist/ai-chatbot-demo.d.ts +42 -0
- package/dist/ai-chatbot-demo.d.ts.map +1 -0
- package/dist/assets/runtime-worker-D9x_Ddwz.js +60543 -0
- package/dist/assets/runtime-worker-D9x_Ddwz.js.map +1 -0
- package/dist/convex-app-demo-entry.d.ts +6 -0
- package/dist/convex-app-demo-entry.d.ts.map +1 -0
- package/dist/convex-app-demo.d.ts +68 -0
- package/dist/convex-app-demo.d.ts.map +1 -0
- package/dist/cors-proxy.d.ts +46 -0
- package/dist/cors-proxy.d.ts.map +1 -0
- package/dist/create-runtime.d.ts +42 -0
- package/dist/create-runtime.d.ts.map +1 -0
- package/dist/demo.d.ts +6 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/dev-server.d.ts +97 -0
- package/dist/dev-server.d.ts.map +1 -0
- package/dist/frameworks/next-dev-server.d.ts +202 -0
- package/dist/frameworks/next-dev-server.d.ts.map +1 -0
- package/dist/frameworks/vite-dev-server.d.ts +85 -0
- package/dist/frameworks/vite-dev-server.d.ts.map +1 -0
- package/dist/index.cjs +14965 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +14867 -0
- package/dist/index.mjs.map +1 -0
- package/dist/next-demo.d.ts +49 -0
- package/dist/next-demo.d.ts.map +1 -0
- package/dist/npm/index.d.ts +71 -0
- package/dist/npm/index.d.ts.map +1 -0
- package/dist/npm/registry.d.ts +66 -0
- package/dist/npm/registry.d.ts.map +1 -0
- package/dist/npm/resolver.d.ts +52 -0
- package/dist/npm/resolver.d.ts.map +1 -0
- package/dist/npm/tarball.d.ts +29 -0
- package/dist/npm/tarball.d.ts.map +1 -0
- package/dist/runtime-interface.d.ts +90 -0
- package/dist/runtime-interface.d.ts.map +1 -0
- package/dist/runtime.d.ts +103 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/sandbox-helpers.d.ts +43 -0
- package/dist/sandbox-helpers.d.ts.map +1 -0
- package/dist/sandbox-runtime.d.ts +65 -0
- package/dist/sandbox-runtime.d.ts.map +1 -0
- package/dist/server-bridge.d.ts +89 -0
- package/dist/server-bridge.d.ts.map +1 -0
- package/dist/shims/assert.d.ts +51 -0
- package/dist/shims/assert.d.ts.map +1 -0
- package/dist/shims/async_hooks.d.ts +37 -0
- package/dist/shims/async_hooks.d.ts.map +1 -0
- package/dist/shims/buffer.d.ts +20 -0
- package/dist/shims/buffer.d.ts.map +1 -0
- package/dist/shims/child_process-browser.d.ts +92 -0
- package/dist/shims/child_process-browser.d.ts.map +1 -0
- package/dist/shims/child_process.d.ts +93 -0
- package/dist/shims/child_process.d.ts.map +1 -0
- package/dist/shims/chokidar.d.ts +55 -0
- package/dist/shims/chokidar.d.ts.map +1 -0
- package/dist/shims/cluster.d.ts +52 -0
- package/dist/shims/cluster.d.ts.map +1 -0
- package/dist/shims/crypto.d.ts +122 -0
- package/dist/shims/crypto.d.ts.map +1 -0
- package/dist/shims/dgram.d.ts +34 -0
- package/dist/shims/dgram.d.ts.map +1 -0
- package/dist/shims/diagnostics_channel.d.ts +80 -0
- package/dist/shims/diagnostics_channel.d.ts.map +1 -0
- package/dist/shims/dns.d.ts +87 -0
- package/dist/shims/dns.d.ts.map +1 -0
- package/dist/shims/domain.d.ts +25 -0
- package/dist/shims/domain.d.ts.map +1 -0
- package/dist/shims/esbuild.d.ts +105 -0
- package/dist/shims/esbuild.d.ts.map +1 -0
- package/dist/shims/events.d.ts +37 -0
- package/dist/shims/events.d.ts.map +1 -0
- package/dist/shims/fs.d.ts +115 -0
- package/dist/shims/fs.d.ts.map +1 -0
- package/dist/shims/fsevents.d.ts +67 -0
- package/dist/shims/fsevents.d.ts.map +1 -0
- package/dist/shims/http.d.ts +217 -0
- package/dist/shims/http.d.ts.map +1 -0
- package/dist/shims/http2.d.ts +81 -0
- package/dist/shims/http2.d.ts.map +1 -0
- package/dist/shims/https.d.ts +36 -0
- package/dist/shims/https.d.ts.map +1 -0
- package/dist/shims/inspector.d.ts +25 -0
- package/dist/shims/inspector.d.ts.map +1 -0
- package/dist/shims/module.d.ts +22 -0
- package/dist/shims/module.d.ts.map +1 -0
- package/dist/shims/net.d.ts +100 -0
- package/dist/shims/net.d.ts.map +1 -0
- package/dist/shims/os.d.ts +159 -0
- package/dist/shims/os.d.ts.map +1 -0
- package/dist/shims/path.d.ts +72 -0
- package/dist/shims/path.d.ts.map +1 -0
- package/dist/shims/perf_hooks.d.ts +50 -0
- package/dist/shims/perf_hooks.d.ts.map +1 -0
- package/dist/shims/process.d.ts +93 -0
- package/dist/shims/process.d.ts.map +1 -0
- package/dist/shims/querystring.d.ts +23 -0
- package/dist/shims/querystring.d.ts.map +1 -0
- package/dist/shims/readdirp.d.ts +52 -0
- package/dist/shims/readdirp.d.ts.map +1 -0
- package/dist/shims/readline.d.ts +62 -0
- package/dist/shims/readline.d.ts.map +1 -0
- package/dist/shims/rollup.d.ts +34 -0
- package/dist/shims/rollup.d.ts.map +1 -0
- package/dist/shims/sentry.d.ts +163 -0
- package/dist/shims/sentry.d.ts.map +1 -0
- package/dist/shims/stream.d.ts +181 -0
- package/dist/shims/stream.d.ts.map +1 -0
- package/dist/shims/tls.d.ts +53 -0
- package/dist/shims/tls.d.ts.map +1 -0
- package/dist/shims/tty.d.ts +30 -0
- package/dist/shims/tty.d.ts.map +1 -0
- package/dist/shims/url.d.ts +64 -0
- package/dist/shims/url.d.ts.map +1 -0
- package/dist/shims/util.d.ts +106 -0
- package/dist/shims/util.d.ts.map +1 -0
- package/dist/shims/v8.d.ts +73 -0
- package/dist/shims/v8.d.ts.map +1 -0
- package/dist/shims/vfs-adapter.d.ts +126 -0
- package/dist/shims/vfs-adapter.d.ts.map +1 -0
- package/dist/shims/vm.d.ts +45 -0
- package/dist/shims/vm.d.ts.map +1 -0
- package/dist/shims/worker_threads.d.ts +66 -0
- package/dist/shims/worker_threads.d.ts.map +1 -0
- package/dist/shims/ws.d.ts +66 -0
- package/dist/shims/ws.d.ts.map +1 -0
- package/dist/shims/zlib.d.ts +161 -0
- package/dist/shims/zlib.d.ts.map +1 -0
- package/dist/transform.d.ts +24 -0
- package/dist/transform.d.ts.map +1 -0
- package/dist/virtual-fs.d.ts +226 -0
- package/dist/virtual-fs.d.ts.map +1 -0
- package/dist/vite-demo.d.ts +35 -0
- package/dist/vite-demo.d.ts.map +1 -0
- package/dist/vite-sw.js +132 -0
- package/dist/worker/runtime-worker.d.ts +8 -0
- package/dist/worker/runtime-worker.d.ts.map +1 -0
- package/dist/worker-runtime.d.ts +50 -0
- package/dist/worker-runtime.d.ts.map +1 -0
- package/package.json +85 -0
- package/src/ai-chatbot-demo-entry.ts +244 -0
- package/src/ai-chatbot-demo.ts +509 -0
- package/src/convex-app-demo-entry.ts +1107 -0
- package/src/convex-app-demo.ts +1316 -0
- package/src/cors-proxy.ts +81 -0
- package/src/create-runtime.ts +147 -0
- package/src/demo.ts +304 -0
- package/src/dev-server.ts +274 -0
- package/src/frameworks/next-dev-server.ts +2224 -0
- package/src/frameworks/vite-dev-server.ts +702 -0
- package/src/index.ts +101 -0
- package/src/next-demo.ts +1784 -0
- package/src/npm/index.ts +347 -0
- package/src/npm/registry.ts +152 -0
- package/src/npm/resolver.ts +385 -0
- package/src/npm/tarball.ts +209 -0
- package/src/runtime-interface.ts +103 -0
- package/src/runtime.ts +1046 -0
- package/src/sandbox-helpers.ts +173 -0
- package/src/sandbox-runtime.ts +252 -0
- package/src/server-bridge.ts +426 -0
- package/src/shims/assert.ts +664 -0
- package/src/shims/async_hooks.ts +86 -0
- package/src/shims/buffer.ts +75 -0
- package/src/shims/child_process-browser.ts +217 -0
- package/src/shims/child_process.ts +463 -0
- package/src/shims/chokidar.ts +313 -0
- package/src/shims/cluster.ts +67 -0
- package/src/shims/crypto.ts +830 -0
- package/src/shims/dgram.ts +47 -0
- package/src/shims/diagnostics_channel.ts +196 -0
- package/src/shims/dns.ts +172 -0
- package/src/shims/domain.ts +58 -0
- package/src/shims/esbuild.ts +805 -0
- package/src/shims/events.ts +195 -0
- package/src/shims/fs.ts +803 -0
- package/src/shims/fsevents.ts +63 -0
- package/src/shims/http.ts +904 -0
- package/src/shims/http2.ts +96 -0
- package/src/shims/https.ts +86 -0
- package/src/shims/inspector.ts +30 -0
- package/src/shims/module.ts +82 -0
- package/src/shims/net.ts +359 -0
- package/src/shims/os.ts +195 -0
- package/src/shims/path.ts +199 -0
- package/src/shims/perf_hooks.ts +92 -0
- package/src/shims/process.ts +346 -0
- package/src/shims/querystring.ts +97 -0
- package/src/shims/readdirp.ts +228 -0
- package/src/shims/readline.ts +110 -0
- package/src/shims/rollup.ts +80 -0
- package/src/shims/sentry.ts +133 -0
- package/src/shims/stream.ts +1126 -0
- package/src/shims/tls.ts +95 -0
- package/src/shims/tty.ts +64 -0
- package/src/shims/url.ts +171 -0
- package/src/shims/util.ts +312 -0
- package/src/shims/v8.ts +113 -0
- package/src/shims/vfs-adapter.ts +402 -0
- package/src/shims/vm.ts +83 -0
- package/src/shims/worker_threads.ts +111 -0
- package/src/shims/ws.ts +382 -0
- package/src/shims/zlib.ts +289 -0
- package/src/transform.ts +313 -0
- package/src/types/external.d.ts +67 -0
- package/src/virtual-fs.ts +903 -0
- package/src/vite-demo.ts +577 -0
- package/src/worker/runtime-worker.ts +128 -0
- package/src/worker-runtime.ts +145 -0
package/src/transform.ts
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESM to CJS Transformer using esbuild-wasm
|
|
3
|
+
*
|
|
4
|
+
* Transforms ES modules to CommonJS format during npm install,
|
|
5
|
+
* so require() can work synchronously.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { VirtualFS } from './virtual-fs';
|
|
9
|
+
|
|
10
|
+
// Check if we're in a browser environment
|
|
11
|
+
const isBrowser = typeof window !== 'undefined';
|
|
12
|
+
|
|
13
|
+
// Window.__esbuild type is declared in src/types/external.d.ts
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Initialize esbuild-wasm (reuses existing instance if already initialized)
|
|
17
|
+
*/
|
|
18
|
+
export async function initTransformer(): Promise<void> {
|
|
19
|
+
// Skip in non-browser environments (tests)
|
|
20
|
+
if (!isBrowser) {
|
|
21
|
+
console.log('[transform] Skipping esbuild init (not in browser)');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Reuse existing esbuild instance from window (may have been initialized by next-dev-server)
|
|
26
|
+
if (window.__esbuild) {
|
|
27
|
+
console.log('[transform] Reusing existing esbuild instance');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// If another init is in progress, wait for it
|
|
32
|
+
if (window.__esbuildInitPromise) {
|
|
33
|
+
return window.__esbuildInitPromise;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
window.__esbuildInitPromise = (async () => {
|
|
37
|
+
try {
|
|
38
|
+
console.log('[transform] Loading esbuild-wasm...');
|
|
39
|
+
|
|
40
|
+
// Load esbuild-wasm from CDN
|
|
41
|
+
const mod = await import(
|
|
42
|
+
/* @vite-ignore */
|
|
43
|
+
'https://esm.sh/esbuild-wasm@0.20.0'
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
// esm.sh wraps the module - get the actual esbuild object
|
|
47
|
+
const esbuildMod = mod.default || mod;
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
await esbuildMod.initialize({
|
|
51
|
+
wasmURL: 'https://unpkg.com/esbuild-wasm@0.20.0/esbuild.wasm',
|
|
52
|
+
});
|
|
53
|
+
console.log('[transform] esbuild-wasm initialized');
|
|
54
|
+
} catch (initError) {
|
|
55
|
+
// Handle "already initialized" error gracefully
|
|
56
|
+
if (initError instanceof Error && initError.message.includes('Cannot call "initialize" more than once')) {
|
|
57
|
+
console.log('[transform] esbuild-wasm already initialized, reusing');
|
|
58
|
+
} else {
|
|
59
|
+
throw initError;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
window.__esbuild = esbuildMod;
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error('[transform] Failed to initialize esbuild:', error);
|
|
66
|
+
window.__esbuildInitPromise = undefined;
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
})();
|
|
70
|
+
|
|
71
|
+
return window.__esbuildInitPromise;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Check if transformer is ready
|
|
76
|
+
*/
|
|
77
|
+
export function isTransformerReady(): boolean {
|
|
78
|
+
// In non-browser, we skip transformation
|
|
79
|
+
if (!isBrowser) return true;
|
|
80
|
+
return window.__esbuild !== undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Transform a single file from ESM to CJS
|
|
85
|
+
*/
|
|
86
|
+
export async function transformFile(
|
|
87
|
+
code: string,
|
|
88
|
+
filename: string
|
|
89
|
+
): Promise<string> {
|
|
90
|
+
// Skip in non-browser environments
|
|
91
|
+
if (!isBrowser) {
|
|
92
|
+
return code;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!window.__esbuild) {
|
|
96
|
+
await initTransformer();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const esbuild = window.__esbuild;
|
|
100
|
+
if (!esbuild) {
|
|
101
|
+
throw new Error('esbuild not initialized');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Determine loader based on file extension
|
|
105
|
+
let loader: 'js' | 'jsx' | 'ts' | 'tsx' = 'js';
|
|
106
|
+
if (filename.endsWith('.jsx')) loader = 'jsx';
|
|
107
|
+
else if (filename.endsWith('.ts')) loader = 'ts';
|
|
108
|
+
else if (filename.endsWith('.tsx')) loader = 'tsx';
|
|
109
|
+
else if (filename.endsWith('.mjs')) loader = 'js';
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const result = await esbuild.transform(code, {
|
|
113
|
+
loader,
|
|
114
|
+
format: 'cjs',
|
|
115
|
+
target: 'esnext',
|
|
116
|
+
platform: 'neutral',
|
|
117
|
+
// Replace import.meta with our runtime-provided variable
|
|
118
|
+
// This is the proper esbuild way to handle import.meta in CJS
|
|
119
|
+
define: {
|
|
120
|
+
'import.meta.url': 'import_meta.url',
|
|
121
|
+
'import.meta.dirname': 'import_meta.dirname',
|
|
122
|
+
'import.meta.filename': 'import_meta.filename',
|
|
123
|
+
'import.meta': 'import_meta',
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
let transformed = result.code;
|
|
128
|
+
|
|
129
|
+
// Convert dynamic import() of node: modules to require()
|
|
130
|
+
// This is necessary because the browser tries to fetch 'node:http' as a URL
|
|
131
|
+
// Pattern: import("node:xxx") or import('node:xxx') -> Promise.resolve(require("node:xxx"))
|
|
132
|
+
transformed = transformed.replace(
|
|
133
|
+
/\bimport\s*\(\s*["']node:([^"']+)["']\s*\)/g,
|
|
134
|
+
'Promise.resolve(require("node:$1"))'
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
// Also handle dynamic imports of bare node built-in modules (without node: prefix)
|
|
138
|
+
const nodeBuiltins = [
|
|
139
|
+
'assert', 'buffer', 'child_process', 'cluster', 'crypto', 'dgram', 'dns',
|
|
140
|
+
'events', 'fs', 'http', 'http2', 'https', 'net', 'os', 'path', 'perf_hooks',
|
|
141
|
+
'querystring', 'readline', 'stream', 'string_decoder', 'timers', 'tls',
|
|
142
|
+
'url', 'util', 'v8', 'vm', 'worker_threads', 'zlib', 'async_hooks', 'inspector', 'module'
|
|
143
|
+
];
|
|
144
|
+
for (const builtin of nodeBuiltins) {
|
|
145
|
+
// Match import("fs") or import('fs') but not import("fs-extra") etc
|
|
146
|
+
const pattern = new RegExp(`\\bimport\\s*\\(\\s*["']${builtin}["']\\s*\\)`, 'g');
|
|
147
|
+
transformed = transformed.replace(pattern, `Promise.resolve(require("${builtin}"))`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return transformed;
|
|
151
|
+
} catch (error: unknown) {
|
|
152
|
+
// Check if it's a top-level await error - these files are usually CLI entry points
|
|
153
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
154
|
+
if (errorMsg.includes('Top-level await')) {
|
|
155
|
+
console.log(`[transform] Skipping ${filename} (has top-level await, likely CLI entry point)`);
|
|
156
|
+
// Return original code - it won't be require()'d directly anyway
|
|
157
|
+
return code;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
console.warn(`[transform] Failed to transform ${filename}:`, error);
|
|
161
|
+
// Return original code if transform fails
|
|
162
|
+
return code;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Check if a file needs ESM to CJS transformation
|
|
168
|
+
*/
|
|
169
|
+
function needsTransform(filename: string, code: string): boolean {
|
|
170
|
+
// .mjs files are always ESM
|
|
171
|
+
if (filename.endsWith('.mjs')) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// .cjs files are always CJS
|
|
176
|
+
if (filename.endsWith('.cjs')) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Check for ESM syntax
|
|
181
|
+
const hasImport = /\bimport\s+[\w{*'"]/m.test(code);
|
|
182
|
+
const hasExport = /\bexport\s+(?:default|const|let|var|function|class|{|\*)/m.test(code);
|
|
183
|
+
const hasImportMeta = /\bimport\.meta\b/.test(code);
|
|
184
|
+
|
|
185
|
+
return hasImport || hasExport || hasImportMeta;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Check if a file has dynamic imports that need patching
|
|
190
|
+
*/
|
|
191
|
+
function hasDynamicNodeImports(code: string): boolean {
|
|
192
|
+
// Check for import("node:...") or import('node:...')
|
|
193
|
+
if (/\bimport\s*\(\s*["']node:/.test(code)) {
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
// Check for dynamic imports of common node builtins
|
|
197
|
+
if (/\bimport\s*\(\s*["'](fs|path|http|https|net|url|util|events|stream|os|crypto)["']/.test(code)) {
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Patch dynamic imports in already-CJS code (e.g., pre-bundled packages)
|
|
205
|
+
*/
|
|
206
|
+
function patchDynamicImports(code: string): string {
|
|
207
|
+
let patched = code;
|
|
208
|
+
|
|
209
|
+
// Convert dynamic import() of node: modules to require()
|
|
210
|
+
patched = patched.replace(
|
|
211
|
+
/\bimport\s*\(\s*["']node:([^"']+)["']\s*\)/g,
|
|
212
|
+
'Promise.resolve(require("node:$1"))'
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
// Also handle dynamic imports of bare node built-in modules
|
|
216
|
+
const nodeBuiltins = [
|
|
217
|
+
'assert', 'buffer', 'child_process', 'cluster', 'crypto', 'dgram', 'dns',
|
|
218
|
+
'events', 'fs', 'http', 'http2', 'https', 'net', 'os', 'path', 'perf_hooks',
|
|
219
|
+
'querystring', 'readline', 'stream', 'string_decoder', 'timers', 'tls',
|
|
220
|
+
'url', 'util', 'v8', 'vm', 'worker_threads', 'zlib', 'async_hooks', 'inspector', 'module'
|
|
221
|
+
];
|
|
222
|
+
for (const builtin of nodeBuiltins) {
|
|
223
|
+
const pattern = new RegExp(`\\bimport\\s*\\(\\s*["']${builtin}["']\\s*\\)`, 'g');
|
|
224
|
+
patched = patched.replace(pattern, `Promise.resolve(require("${builtin}"))`);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return patched;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Transform all ESM files in a package directory to CJS
|
|
232
|
+
*/
|
|
233
|
+
export async function transformPackage(
|
|
234
|
+
vfs: VirtualFS,
|
|
235
|
+
pkgPath: string,
|
|
236
|
+
onProgress?: (msg: string) => void
|
|
237
|
+
): Promise<number> {
|
|
238
|
+
let transformedCount = 0;
|
|
239
|
+
|
|
240
|
+
// Find all JS files in the package
|
|
241
|
+
const jsFiles = findJsFiles(vfs, pkgPath);
|
|
242
|
+
|
|
243
|
+
onProgress?.(` Transforming ${jsFiles.length} files in ${pkgPath}...`);
|
|
244
|
+
|
|
245
|
+
// Transform files in batches
|
|
246
|
+
const BATCH_SIZE = 10;
|
|
247
|
+
for (let i = 0; i < jsFiles.length; i += BATCH_SIZE) {
|
|
248
|
+
const batch = jsFiles.slice(i, i + BATCH_SIZE);
|
|
249
|
+
|
|
250
|
+
await Promise.all(
|
|
251
|
+
batch.map(async (filePath) => {
|
|
252
|
+
try {
|
|
253
|
+
const code = vfs.readFileSync(filePath, 'utf8');
|
|
254
|
+
|
|
255
|
+
if (needsTransform(filePath, code)) {
|
|
256
|
+
// Full ESM to CJS transformation
|
|
257
|
+
const transformed = await transformFile(code, filePath);
|
|
258
|
+
vfs.writeFileSync(filePath, transformed);
|
|
259
|
+
transformedCount++;
|
|
260
|
+
} else if (hasDynamicNodeImports(code)) {
|
|
261
|
+
// Just patch dynamic imports in already-CJS code
|
|
262
|
+
const patched = patchDynamicImports(code);
|
|
263
|
+
vfs.writeFileSync(filePath, patched);
|
|
264
|
+
transformedCount++;
|
|
265
|
+
}
|
|
266
|
+
} catch (error) {
|
|
267
|
+
// Skip files that can't be read/transformed
|
|
268
|
+
console.warn(`[transform] Skipping ${filePath}:`, error);
|
|
269
|
+
}
|
|
270
|
+
})
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return transformedCount;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Find all JavaScript files in a directory recursively
|
|
279
|
+
*/
|
|
280
|
+
function findJsFiles(vfs: VirtualFS, dir: string): string[] {
|
|
281
|
+
const files: string[] = [];
|
|
282
|
+
|
|
283
|
+
try {
|
|
284
|
+
const entries = vfs.readdirSync(dir);
|
|
285
|
+
|
|
286
|
+
for (const entry of entries) {
|
|
287
|
+
const fullPath = dir + '/' + entry;
|
|
288
|
+
|
|
289
|
+
try {
|
|
290
|
+
const stat = vfs.statSync(fullPath);
|
|
291
|
+
|
|
292
|
+
if (stat.isDirectory()) {
|
|
293
|
+
// Skip node_modules inside packages (nested deps)
|
|
294
|
+
if (entry !== 'node_modules') {
|
|
295
|
+
files.push(...findJsFiles(vfs, fullPath));
|
|
296
|
+
}
|
|
297
|
+
} else if (
|
|
298
|
+
entry.endsWith('.js') ||
|
|
299
|
+
entry.endsWith('.mjs') ||
|
|
300
|
+
entry.endsWith('.jsx')
|
|
301
|
+
) {
|
|
302
|
+
files.push(fullPath);
|
|
303
|
+
}
|
|
304
|
+
} catch {
|
|
305
|
+
// Skip files we can't stat
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
} catch {
|
|
309
|
+
// Skip directories we can't read
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return files;
|
|
313
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type declarations for CDN-loaded modules
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Type declarations for esbuild-wasm to support dynamic import from CDN
|
|
6
|
+
interface EsbuildTransformOptions {
|
|
7
|
+
loader?: string;
|
|
8
|
+
jsx?: string;
|
|
9
|
+
jsxFactory?: string;
|
|
10
|
+
jsxFragment?: string;
|
|
11
|
+
jsxImportSource?: string;
|
|
12
|
+
sourcemap?: boolean | 'inline' | 'external' | 'both';
|
|
13
|
+
sourcefile?: string;
|
|
14
|
+
target?: string | string[];
|
|
15
|
+
format?: 'iife' | 'cjs' | 'esm';
|
|
16
|
+
minify?: boolean;
|
|
17
|
+
tsconfigRaw?: string | object;
|
|
18
|
+
platform?: 'browser' | 'node' | 'neutral';
|
|
19
|
+
define?: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface EsbuildTransformResult {
|
|
23
|
+
code: string;
|
|
24
|
+
map: string;
|
|
25
|
+
warnings: unknown[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Declare the esbuild-wasm module for type-only imports
|
|
29
|
+
declare module 'esbuild-wasm' {
|
|
30
|
+
export function initialize(options?: { wasmURL?: string; worker?: boolean }): Promise<void>;
|
|
31
|
+
export function transform(input: string, options?: EsbuildTransformOptions): Promise<EsbuildTransformResult>;
|
|
32
|
+
export function build(options: unknown): Promise<unknown>;
|
|
33
|
+
export function formatMessages(messages: unknown[], options: unknown): Promise<string[]>;
|
|
34
|
+
export const version: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
declare module 'https://esm.sh/esbuild-wasm@0.20.0' {
|
|
38
|
+
export function initialize(options?: { wasmURL?: string; worker?: boolean }): Promise<void>;
|
|
39
|
+
export function transform(input: string, options?: EsbuildTransformOptions): Promise<EsbuildTransformResult>;
|
|
40
|
+
export function build(options: unknown): Promise<unknown>;
|
|
41
|
+
export function formatMessages(messages: unknown[], options: unknown): Promise<string[]>;
|
|
42
|
+
export const version: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
declare module 'https://unpkg.com/esbuild-wasm@0.20.0/esm/browser.min.js' {
|
|
46
|
+
export function initialize(options?: { wasmURL?: string; worker?: boolean }): Promise<void>;
|
|
47
|
+
export function transform(input: string, options?: EsbuildTransformOptions): Promise<EsbuildTransformResult>;
|
|
48
|
+
export function build(options: unknown): Promise<unknown>;
|
|
49
|
+
export function formatMessages(messages: unknown[], options: unknown): Promise<string[]>;
|
|
50
|
+
export const version: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Rollup browser module
|
|
54
|
+
declare module 'https://esm.sh/@rollup/browser@4.9.0' {
|
|
55
|
+
export function rollup(options: unknown): Promise<{
|
|
56
|
+
generate(outputOptions: unknown): Promise<{ output: unknown[] }>;
|
|
57
|
+
write(outputOptions: unknown): Promise<{ output: unknown[] }>;
|
|
58
|
+
close(): Promise<void>;
|
|
59
|
+
}>;
|
|
60
|
+
export const VERSION: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Centralized Window interface augmentation for esbuild
|
|
64
|
+
interface Window {
|
|
65
|
+
__esbuild?: typeof import('esbuild-wasm');
|
|
66
|
+
__esbuildInitPromise?: Promise<void>;
|
|
67
|
+
}
|