@run0/jiki 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/dist/browser-bundle.d.ts +40 -0
- package/dist/builtins.d.ts +22 -0
- package/dist/code-transform.d.ts +7 -0
- package/dist/config/cdn.d.ts +13 -0
- package/dist/container.d.ts +101 -0
- package/dist/dev-server.d.ts +69 -0
- package/dist/errors.d.ts +19 -0
- package/dist/frameworks/code-transforms.d.ts +32 -0
- package/dist/frameworks/next-api-handler.d.ts +72 -0
- package/dist/frameworks/next-dev-server.d.ts +141 -0
- package/dist/frameworks/next-html-generator.d.ts +36 -0
- package/dist/frameworks/next-route-resolver.d.ts +19 -0
- package/dist/frameworks/next-shims.d.ts +78 -0
- package/dist/frameworks/remix-dev-server.d.ts +47 -0
- package/dist/frameworks/sveltekit-dev-server.d.ts +43 -0
- package/dist/frameworks/vite-dev-server.d.ts +50 -0
- package/dist/fs-errors.d.ts +36 -0
- package/dist/index.cjs +14916 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.mjs +14898 -0
- package/dist/index.mjs.map +1 -0
- package/dist/kernel.d.ts +48 -0
- package/dist/memfs.d.ts +144 -0
- package/dist/metrics.d.ts +78 -0
- package/dist/module-resolver.d.ts +60 -0
- package/dist/network-interceptor.d.ts +71 -0
- package/dist/npm/cache.d.ts +76 -0
- package/dist/npm/index.d.ts +60 -0
- package/dist/npm/lockfile-reader.d.ts +32 -0
- package/dist/npm/pnpm.d.ts +18 -0
- package/dist/npm/registry.d.ts +45 -0
- package/dist/npm/resolver.d.ts +39 -0
- package/dist/npm/sync-installer.d.ts +18 -0
- package/dist/npm/tarball.d.ts +4 -0
- package/dist/npm/workspaces.d.ts +46 -0
- package/dist/persistence.d.ts +94 -0
- package/dist/plugin.d.ts +156 -0
- package/dist/polyfills/assert.d.ts +30 -0
- package/dist/polyfills/child_process.d.ts +116 -0
- package/dist/polyfills/chokidar.d.ts +18 -0
- package/dist/polyfills/crypto.d.ts +49 -0
- package/dist/polyfills/events.d.ts +28 -0
- package/dist/polyfills/fs.d.ts +82 -0
- package/dist/polyfills/http.d.ts +147 -0
- package/dist/polyfills/module.d.ts +29 -0
- package/dist/polyfills/net.d.ts +53 -0
- package/dist/polyfills/os.d.ts +91 -0
- package/dist/polyfills/path.d.ts +96 -0
- package/dist/polyfills/perf_hooks.d.ts +21 -0
- package/dist/polyfills/process.d.ts +99 -0
- package/dist/polyfills/querystring.d.ts +15 -0
- package/dist/polyfills/readdirp.d.ts +18 -0
- package/dist/polyfills/readline.d.ts +32 -0
- package/dist/polyfills/stream.d.ts +106 -0
- package/dist/polyfills/stubs.d.ts +737 -0
- package/dist/polyfills/tty.d.ts +25 -0
- package/dist/polyfills/url.d.ts +41 -0
- package/dist/polyfills/util.d.ts +61 -0
- package/dist/polyfills/v8.d.ts +43 -0
- package/dist/polyfills/vm.d.ts +76 -0
- package/dist/polyfills/worker-threads.d.ts +77 -0
- package/dist/polyfills/ws.d.ts +32 -0
- package/dist/polyfills/zlib.d.ts +87 -0
- package/dist/runtime-helpers.d.ts +4 -0
- package/dist/runtime-interface.d.ts +39 -0
- package/dist/sandbox.d.ts +69 -0
- package/dist/server-bridge.d.ts +55 -0
- package/dist/shell-commands.d.ts +2 -0
- package/dist/shell.d.ts +101 -0
- package/dist/transpiler.d.ts +47 -0
- package/dist/type-checker.d.ts +57 -0
- package/dist/types/package-json.d.ts +17 -0
- package/dist/utils/binary-encoding.d.ts +4 -0
- package/dist/utils/hash.d.ts +6 -0
- package/dist/utils/safe-path.d.ts +6 -0
- package/dist/worker-runtime.d.ts +34 -0
- package/package.json +59 -0
- package/src/browser-bundle.ts +498 -0
- package/src/builtins.ts +222 -0
- package/src/code-transform.ts +183 -0
- package/src/config/cdn.ts +17 -0
- package/src/container.ts +343 -0
- package/src/dev-server.ts +322 -0
- package/src/errors.ts +604 -0
- package/src/frameworks/code-transforms.ts +667 -0
- package/src/frameworks/next-api-handler.ts +366 -0
- package/src/frameworks/next-dev-server.ts +1252 -0
- package/src/frameworks/next-html-generator.ts +585 -0
- package/src/frameworks/next-route-resolver.ts +521 -0
- package/src/frameworks/next-shims.ts +1084 -0
- package/src/frameworks/remix-dev-server.ts +163 -0
- package/src/frameworks/sveltekit-dev-server.ts +197 -0
- package/src/frameworks/vite-dev-server.ts +370 -0
- package/src/fs-errors.ts +118 -0
- package/src/index.ts +188 -0
- package/src/kernel.ts +381 -0
- package/src/memfs.ts +1006 -0
- package/src/metrics.ts +140 -0
- package/src/module-resolver.ts +511 -0
- package/src/network-interceptor.ts +143 -0
- package/src/npm/cache.ts +172 -0
- package/src/npm/index.ts +377 -0
- package/src/npm/lockfile-reader.ts +105 -0
- package/src/npm/pnpm.ts +108 -0
- package/src/npm/registry.ts +120 -0
- package/src/npm/resolver.ts +339 -0
- package/src/npm/sync-installer.ts +217 -0
- package/src/npm/tarball.ts +136 -0
- package/src/npm/workspaces.ts +255 -0
- package/src/persistence.ts +235 -0
- package/src/plugin.ts +293 -0
- package/src/polyfills/assert.ts +164 -0
- package/src/polyfills/child_process.ts +535 -0
- package/src/polyfills/chokidar.ts +52 -0
- package/src/polyfills/crypto.ts +433 -0
- package/src/polyfills/events.ts +178 -0
- package/src/polyfills/fs.ts +297 -0
- package/src/polyfills/http.ts +478 -0
- package/src/polyfills/module.ts +97 -0
- package/src/polyfills/net.ts +123 -0
- package/src/polyfills/os.ts +108 -0
- package/src/polyfills/path.ts +169 -0
- package/src/polyfills/perf_hooks.ts +30 -0
- package/src/polyfills/process.ts +349 -0
- package/src/polyfills/querystring.ts +66 -0
- package/src/polyfills/readdirp.ts +72 -0
- package/src/polyfills/readline.ts +80 -0
- package/src/polyfills/stream.ts +610 -0
- package/src/polyfills/stubs.ts +600 -0
- package/src/polyfills/tty.ts +43 -0
- package/src/polyfills/url.ts +97 -0
- package/src/polyfills/util.ts +173 -0
- package/src/polyfills/v8.ts +62 -0
- package/src/polyfills/vm.ts +111 -0
- package/src/polyfills/worker-threads.ts +189 -0
- package/src/polyfills/ws.ts +73 -0
- package/src/polyfills/zlib.ts +244 -0
- package/src/runtime-helpers.ts +83 -0
- package/src/runtime-interface.ts +46 -0
- package/src/sandbox.ts +178 -0
- package/src/server-bridge.ts +473 -0
- package/src/service-worker.ts +153 -0
- package/src/shell-commands.ts +708 -0
- package/src/shell.ts +795 -0
- package/src/transpiler.ts +282 -0
- package/src/type-checker.ts +241 -0
- package/src/types/package-json.ts +17 -0
- package/src/utils/binary-encoding.ts +38 -0
- package/src/utils/hash.ts +24 -0
- package/src/utils/safe-path.ts +38 -0
- package/src/worker-runtime.ts +42 -0
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
import { MemFS } from "./memfs";
|
|
2
|
+
import { transformEsmToCjs, removeShebang } from "./code-transform";
|
|
3
|
+
import { isBuiltinModule } from "./builtins";
|
|
4
|
+
import * as pathShim from "./polyfills/path";
|
|
5
|
+
import type { PackageJson } from "./types/package-json";
|
|
6
|
+
import { resolve as resolveExports } from "resolve.exports";
|
|
7
|
+
|
|
8
|
+
const FILE_EXTENSIONS = [
|
|
9
|
+
".js",
|
|
10
|
+
".ts",
|
|
11
|
+
".tsx",
|
|
12
|
+
".jsx",
|
|
13
|
+
".json",
|
|
14
|
+
".node",
|
|
15
|
+
".mjs",
|
|
16
|
+
".cjs",
|
|
17
|
+
];
|
|
18
|
+
const INDEX_NAMES = [
|
|
19
|
+
"index.js",
|
|
20
|
+
"index.ts",
|
|
21
|
+
"index.tsx",
|
|
22
|
+
"index.json",
|
|
23
|
+
"index.node",
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
export interface BrowserBundle {
|
|
27
|
+
modules: Map<string, string>;
|
|
28
|
+
entryPath: string;
|
|
29
|
+
depMap: Map<string, string>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface BundleError {
|
|
33
|
+
packageName: string;
|
|
34
|
+
message: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function readPkg(vfs: MemFS, pkgPath: string): PackageJson | null {
|
|
38
|
+
try {
|
|
39
|
+
if (!vfs.existsSync(pkgPath)) return null;
|
|
40
|
+
return JSON.parse(vfs.readFileSync(pkgPath, "utf8")) as PackageJson;
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function probeFile(vfs: MemFS, base: string): string | null {
|
|
47
|
+
if (vfs.existsSync(base)) {
|
|
48
|
+
const st = vfs.statSync(base);
|
|
49
|
+
if (st.isFile()) return base;
|
|
50
|
+
if (st.isDirectory()) {
|
|
51
|
+
const pkg = readPkg(vfs, pathShim.join(base, "package.json"));
|
|
52
|
+
if (pkg) {
|
|
53
|
+
for (const field of ["main", "module"] as const) {
|
|
54
|
+
const val = pkg[field];
|
|
55
|
+
if (typeof val === "string") {
|
|
56
|
+
const hit = probeFile(vfs, pathShim.join(base, val));
|
|
57
|
+
if (hit) return hit;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
for (const idx of INDEX_NAMES) {
|
|
62
|
+
const p = pathShim.join(base, idx);
|
|
63
|
+
if (vfs.existsSync(p)) return p;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
for (const ext of FILE_EXTENSIONS) {
|
|
68
|
+
const p = base + ext;
|
|
69
|
+
if (vfs.existsSync(p)) return p;
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Apply the `browser` field (object form) remapping for a given require id.
|
|
76
|
+
* Returns the remapped path, `false` (meaning "ignore this module"), or `null`
|
|
77
|
+
* (no remapping applies).
|
|
78
|
+
*/
|
|
79
|
+
function applyBrowserFieldRemap(
|
|
80
|
+
browserMap: Record<string, string | false>,
|
|
81
|
+
id: string,
|
|
82
|
+
pkgRoot: string,
|
|
83
|
+
): string | false | null {
|
|
84
|
+
if (id in browserMap) {
|
|
85
|
+
const mapped = browserMap[id];
|
|
86
|
+
if (mapped === false) return false;
|
|
87
|
+
return pathShim.join(pkgRoot, mapped);
|
|
88
|
+
}
|
|
89
|
+
const relative = "./" + id;
|
|
90
|
+
if (relative in browserMap) {
|
|
91
|
+
const mapped = browserMap[relative];
|
|
92
|
+
if (mapped === false) return false;
|
|
93
|
+
return pathShim.join(pkgRoot, mapped);
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function resolvePackageEntry(
|
|
99
|
+
vfs: MemFS,
|
|
100
|
+
pkgRoot: string,
|
|
101
|
+
pkgName: string,
|
|
102
|
+
subpath: string,
|
|
103
|
+
): string | null {
|
|
104
|
+
const pkg = readPkg(vfs, pathShim.join(pkgRoot, "package.json"));
|
|
105
|
+
if (pkg) {
|
|
106
|
+
if (pkg.exports) {
|
|
107
|
+
const target = subpath ? `${pkgName}/${subpath}` : pkgName;
|
|
108
|
+
for (const cond of [
|
|
109
|
+
{ browser: true, require: true } as const,
|
|
110
|
+
{ require: true } as const,
|
|
111
|
+
{ browser: true, import: true } as const,
|
|
112
|
+
{ import: true } as const,
|
|
113
|
+
]) {
|
|
114
|
+
try {
|
|
115
|
+
const resolved = resolveExports(pkg, target, cond);
|
|
116
|
+
if (resolved?.length) {
|
|
117
|
+
const hit = probeFile(vfs, pathShim.join(pkgRoot, resolved[0]));
|
|
118
|
+
if (hit) return hit;
|
|
119
|
+
}
|
|
120
|
+
} catch {
|
|
121
|
+
/* continue */
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (subpath) {
|
|
126
|
+
const hit = probeFile(vfs, pathShim.join(pkgRoot, subpath));
|
|
127
|
+
if (hit) return hit;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (typeof pkg.browser === "object" && pkg.browser !== null) {
|
|
131
|
+
const mainField = pkg.main || "index.js";
|
|
132
|
+
const remap = applyBrowserFieldRemap(
|
|
133
|
+
pkg.browser as Record<string, string | false>,
|
|
134
|
+
mainField,
|
|
135
|
+
pkgRoot,
|
|
136
|
+
);
|
|
137
|
+
if (typeof remap === "string") {
|
|
138
|
+
const hit = probeFile(vfs, remap);
|
|
139
|
+
if (hit) return hit;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (typeof pkg.browser === "string") {
|
|
143
|
+
const hit = probeFile(vfs, pathShim.join(pkgRoot, pkg.browser));
|
|
144
|
+
if (hit) return hit;
|
|
145
|
+
}
|
|
146
|
+
if (pkg.main) {
|
|
147
|
+
const hit = probeFile(vfs, pathShim.join(pkgRoot, pkg.main));
|
|
148
|
+
if (hit) return hit;
|
|
149
|
+
}
|
|
150
|
+
if (pkg.module) {
|
|
151
|
+
const hit = probeFile(vfs, pathShim.join(pkgRoot, pkg.module));
|
|
152
|
+
if (hit) return hit;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return probeFile(vfs, subpath ? pathShim.join(pkgRoot, subpath) : pkgRoot);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function extractPackageName(id: string): string {
|
|
159
|
+
const segments = id.split("/");
|
|
160
|
+
if (segments[0].startsWith("@") && segments.length > 1) {
|
|
161
|
+
return `${segments[0]}/${segments[1]}`;
|
|
162
|
+
}
|
|
163
|
+
return segments[0];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function resolveModuleId(
|
|
167
|
+
vfs: MemFS,
|
|
168
|
+
id: string,
|
|
169
|
+
fromDir: string,
|
|
170
|
+
): string | null {
|
|
171
|
+
if (id.startsWith("./") || id.startsWith("../") || id.startsWith("/")) {
|
|
172
|
+
const abs = id.startsWith("/") ? id : pathShim.resolve(fromDir, id);
|
|
173
|
+
return probeFile(vfs, abs);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const pkgName = extractPackageName(id);
|
|
177
|
+
const segments = id.split("/");
|
|
178
|
+
const subpath = segments.slice(pkgName.split("/").length).join("/");
|
|
179
|
+
|
|
180
|
+
let dir = fromDir;
|
|
181
|
+
while (true) {
|
|
182
|
+
const nm = pathShim.join(dir, "node_modules");
|
|
183
|
+
if (vfs.existsSync(nm)) {
|
|
184
|
+
const pkgRoot = pathShim.join(nm, pkgName);
|
|
185
|
+
const hit = resolvePackageEntry(vfs, pkgRoot, pkgName, subpath);
|
|
186
|
+
if (hit) return hit;
|
|
187
|
+
}
|
|
188
|
+
if (dir === "/") break;
|
|
189
|
+
dir = pathShim.dirname(dir);
|
|
190
|
+
}
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const REQUIRE_PATTERN = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
195
|
+
const DYNAMIC_IMPORT_PATTERN = /__dynamicImport\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Bundle a package from the VFS for browser consumption.
|
|
199
|
+
* Reads the package entry point, transforms ESM to CJS, and recursively
|
|
200
|
+
* bundles all local dependencies. External packages and Node builtins are skipped.
|
|
201
|
+
*/
|
|
202
|
+
export function bundlePackageForBrowser(
|
|
203
|
+
vfs: MemFS,
|
|
204
|
+
packageName: string,
|
|
205
|
+
externals: Set<string>,
|
|
206
|
+
): BrowserBundle {
|
|
207
|
+
const modules = new Map<string, string>();
|
|
208
|
+
const visited = new Set<string>();
|
|
209
|
+
const depMap = new Map<string, string>();
|
|
210
|
+
|
|
211
|
+
const entryPath = resolveModuleId(vfs, packageName, "/");
|
|
212
|
+
if (!entryPath) {
|
|
213
|
+
throw new Error(
|
|
214
|
+
`Cannot resolve package "${packageName}" from /node_modules`,
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function walk(filePath: string): void {
|
|
219
|
+
if (visited.has(filePath)) return;
|
|
220
|
+
visited.add(filePath);
|
|
221
|
+
|
|
222
|
+
let source: string;
|
|
223
|
+
try {
|
|
224
|
+
const raw = vfs.readFileSync(filePath, "utf8");
|
|
225
|
+
source = removeShebang(raw);
|
|
226
|
+
} catch {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (filePath.endsWith(".json")) {
|
|
231
|
+
modules.set(filePath, `module.exports = ${source};`);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
let transformed: string;
|
|
236
|
+
try {
|
|
237
|
+
transformed = transformEsmToCjs(source, filePath);
|
|
238
|
+
} catch {
|
|
239
|
+
transformed = source;
|
|
240
|
+
}
|
|
241
|
+
modules.set(filePath, transformed);
|
|
242
|
+
|
|
243
|
+
const depPatterns = [
|
|
244
|
+
new RegExp(REQUIRE_PATTERN.source, "g"),
|
|
245
|
+
new RegExp(DYNAMIC_IMPORT_PATTERN.source, "g"),
|
|
246
|
+
];
|
|
247
|
+
for (const pattern of depPatterns) {
|
|
248
|
+
let match;
|
|
249
|
+
while ((match = pattern.exec(transformed)) !== null) {
|
|
250
|
+
const dep = match[1];
|
|
251
|
+
|
|
252
|
+
if (isBuiltinModule(dep)) continue;
|
|
253
|
+
|
|
254
|
+
const depPkgName = extractPackageName(dep);
|
|
255
|
+
if (externals.has(depPkgName)) continue;
|
|
256
|
+
|
|
257
|
+
const resolved = resolveModuleId(vfs, dep, pathShim.dirname(filePath));
|
|
258
|
+
if (resolved) {
|
|
259
|
+
if (
|
|
260
|
+
!dep.startsWith("./") &&
|
|
261
|
+
!dep.startsWith("../") &&
|
|
262
|
+
!dep.startsWith("/")
|
|
263
|
+
) {
|
|
264
|
+
depMap.set(dep, resolved);
|
|
265
|
+
}
|
|
266
|
+
walk(resolved);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
walk(entryPath);
|
|
273
|
+
return { modules, entryPath, depMap };
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Escape code for safe embedding inside an HTML `<script>` tag.
|
|
278
|
+
* Only needs to prevent premature closing of the script element.
|
|
279
|
+
*/
|
|
280
|
+
function escapeForScriptEmbed(code: string): string {
|
|
281
|
+
return code.replace(/<\/script>/gi, "<\\/script>");
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Generate a `<script>` containing a require() shim and all bundled modules.
|
|
286
|
+
* Globals map package names to window properties (e.g. { "react": "React" }).
|
|
287
|
+
*/
|
|
288
|
+
export function generateRequireScript(
|
|
289
|
+
bundles: Map<string, BrowserBundle>,
|
|
290
|
+
globals: Record<string, string>,
|
|
291
|
+
): string {
|
|
292
|
+
const pkgMap: Record<string, string> = {};
|
|
293
|
+
const dedupedModules = new Map<string, string>();
|
|
294
|
+
|
|
295
|
+
for (const [pkgName, bundle] of bundles) {
|
|
296
|
+
pkgMap[pkgName] = bundle.entryPath;
|
|
297
|
+
for (const [specifier, resolvedPath] of bundle.depMap) {
|
|
298
|
+
if (!(specifier in pkgMap)) {
|
|
299
|
+
pkgMap[specifier] = resolvedPath;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
for (const [modPath, code] of bundle.modules) {
|
|
303
|
+
dedupedModules.set(modPath, code);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if ("react" in globals) {
|
|
308
|
+
pkgMap["react/jsx-runtime"] = "__jsx_runtime__";
|
|
309
|
+
pkgMap["react/jsx-dev-runtime"] = "__jsx_runtime__";
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const allModules = [...dedupedModules.entries()].map(([path, code]) => ({
|
|
313
|
+
path,
|
|
314
|
+
code,
|
|
315
|
+
}));
|
|
316
|
+
|
|
317
|
+
const globalsJson = JSON.stringify(globals);
|
|
318
|
+
const pkgMapJson = JSON.stringify(pkgMap);
|
|
319
|
+
|
|
320
|
+
const moduleRegistrations = allModules
|
|
321
|
+
.map(({ path, code }) => {
|
|
322
|
+
const escaped = escapeForScriptEmbed(code);
|
|
323
|
+
return (
|
|
324
|
+
"__m[" +
|
|
325
|
+
JSON.stringify(path) +
|
|
326
|
+
"] = function(module, exports, require) {\n" +
|
|
327
|
+
escaped +
|
|
328
|
+
"\n};"
|
|
329
|
+
);
|
|
330
|
+
})
|
|
331
|
+
.join("\n");
|
|
332
|
+
|
|
333
|
+
const jsxRuntimeShim =
|
|
334
|
+
"react" in globals
|
|
335
|
+
? '\n __m["__jsx_runtime__"] = function(module, exports, require) {\n' +
|
|
336
|
+
' var React = require("react");\n' +
|
|
337
|
+
" function jsx(type, props, key) {\n" +
|
|
338
|
+
" if (key !== undefined && props) props.key = key;\n" +
|
|
339
|
+
" return React.createElement(type, props);\n" +
|
|
340
|
+
" }\n" +
|
|
341
|
+
" exports.jsx = jsx;\n" +
|
|
342
|
+
" exports.jsxs = jsx;\n" +
|
|
343
|
+
" exports.jsxDEV = jsx;\n" +
|
|
344
|
+
" exports.Fragment = React.Fragment;\n" +
|
|
345
|
+
" };\n"
|
|
346
|
+
: "";
|
|
347
|
+
|
|
348
|
+
return (
|
|
349
|
+
"<script>\n" +
|
|
350
|
+
"(function() {\n" +
|
|
351
|
+
" var __m = {};\n" +
|
|
352
|
+
" var __c = {};\n" +
|
|
353
|
+
" var __pkg = " +
|
|
354
|
+
pkgMapJson +
|
|
355
|
+
";\n" +
|
|
356
|
+
" var __g = " +
|
|
357
|
+
globalsJson +
|
|
358
|
+
";\n" +
|
|
359
|
+
' var process = { env: { NODE_ENV: "production" } };\n' +
|
|
360
|
+
"\n" +
|
|
361
|
+
" function __dirname(p) {\n" +
|
|
362
|
+
' var idx = p.lastIndexOf("/");\n' +
|
|
363
|
+
' return idx > 0 ? p.substring(0, idx) : "/";\n' +
|
|
364
|
+
" }\n" +
|
|
365
|
+
"\n" +
|
|
366
|
+
" function __resolve(from, rel) {\n" +
|
|
367
|
+
' var parts = from.split("/").filter(Boolean);\n' +
|
|
368
|
+
' var segs = rel.split("/");\n' +
|
|
369
|
+
" for (var i = 0; i < segs.length; i++) {\n" +
|
|
370
|
+
' if (segs[i] === "..") parts.pop();\n' +
|
|
371
|
+
' else if (segs[i] !== ".") parts.push(segs[i]);\n' +
|
|
372
|
+
" }\n" +
|
|
373
|
+
' return "/" + parts.join("/");\n' +
|
|
374
|
+
" }\n" +
|
|
375
|
+
"\n" +
|
|
376
|
+
" function __probe(id) {\n" +
|
|
377
|
+
" if (__m[id]) return id;\n" +
|
|
378
|
+
' var exts = [".js", ".cjs", ".mjs", ".json", "/index.js", "/index.cjs", "/index.mjs"];\n' +
|
|
379
|
+
" for (var i = 0; i < exts.length; i++) {\n" +
|
|
380
|
+
" if (__m[id + exts[i]]) return id + exts[i];\n" +
|
|
381
|
+
" }\n" +
|
|
382
|
+
" return null;\n" +
|
|
383
|
+
" }\n" +
|
|
384
|
+
"\n" +
|
|
385
|
+
" function require(id) {\n" +
|
|
386
|
+
" if (id in __g) return window[__g[id]];\n" +
|
|
387
|
+
"\n" +
|
|
388
|
+
" var resolved = __pkg[id] || id;\n" +
|
|
389
|
+
" if (!__m[resolved]) {\n" +
|
|
390
|
+
" var probed = __probe(resolved);\n" +
|
|
391
|
+
" if (probed) resolved = probed;\n" +
|
|
392
|
+
" }\n" +
|
|
393
|
+
"\n" +
|
|
394
|
+
" if (__c[resolved]) return __c[resolved].exports;\n" +
|
|
395
|
+
"\n" +
|
|
396
|
+
" var fn = __m[resolved];\n" +
|
|
397
|
+
" if (!fn) {\n" +
|
|
398
|
+
" if (id in __g) return window[__g[id]];\n" +
|
|
399
|
+
' console.warn("[require] Cannot find module: " + id + " (resolved: " + resolved + ")");\n' +
|
|
400
|
+
" return {};\n" +
|
|
401
|
+
" }\n" +
|
|
402
|
+
" var mod = { exports: {} };\n" +
|
|
403
|
+
" __c[resolved] = mod;\n" +
|
|
404
|
+
" try {\n" +
|
|
405
|
+
" fn(mod, mod.exports, function localRequire(dep) {\n" +
|
|
406
|
+
' if (dep.startsWith(".") || dep.startsWith("/")) {\n' +
|
|
407
|
+
' var base = dep.startsWith("/") ? dep : __resolve(__dirname(resolved), dep);\n' +
|
|
408
|
+
" var found = __probe(base);\n" +
|
|
409
|
+
" if (found) return require(found);\n" +
|
|
410
|
+
' console.warn("[require] Cannot resolve: " + dep + " from " + resolved);\n' +
|
|
411
|
+
" return {};\n" +
|
|
412
|
+
" }\n" +
|
|
413
|
+
" return require(dep);\n" +
|
|
414
|
+
" });\n" +
|
|
415
|
+
" } catch (e) {\n" +
|
|
416
|
+
' console.error("[require] Error executing module: " + resolved, e);\n' +
|
|
417
|
+
" }\n" +
|
|
418
|
+
" return mod.exports;\n" +
|
|
419
|
+
" }\n" +
|
|
420
|
+
"\n" +
|
|
421
|
+
" " +
|
|
422
|
+
moduleRegistrations +
|
|
423
|
+
"\n" +
|
|
424
|
+
jsxRuntimeShim +
|
|
425
|
+
"\n" +
|
|
426
|
+
" window.require = require;\n" +
|
|
427
|
+
" window.__dynamicImport = function(id) {\n" +
|
|
428
|
+
" return Promise.resolve().then(function() {\n" +
|
|
429
|
+
" var mod = require(id);\n" +
|
|
430
|
+
' if (mod && typeof mod === "object" && ("default" in mod || "__esModule" in mod)) {\n' +
|
|
431
|
+
" return mod;\n" +
|
|
432
|
+
" }\n" +
|
|
433
|
+
' return Object.assign({ default: mod }, mod && typeof mod === "object" ? mod : {});\n' +
|
|
434
|
+
" });\n" +
|
|
435
|
+
" };\n" +
|
|
436
|
+
"})();\n" +
|
|
437
|
+
"</script>"
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Transform ES module `import` statements into `window.require()` calls.
|
|
443
|
+
* Used to pre-process component source before host-side JSX transpilation
|
|
444
|
+
* via esbuild. The output is plain JS that can run in a regular `<script>` tag.
|
|
445
|
+
*
|
|
446
|
+
* Uses `var` (not `const`) so declarations hoist to function/global scope.
|
|
447
|
+
* Uses `window.require` (not bare `require`) to avoid strict-mode scoping issues.
|
|
448
|
+
*/
|
|
449
|
+
export function preprocessImports(code: string): string {
|
|
450
|
+
return code
|
|
451
|
+
.replace(
|
|
452
|
+
/^import\s+type\s+\{[^}]*\}\s+from\s+['"][^'"]+['"]\s*;?\s*$/gm,
|
|
453
|
+
"",
|
|
454
|
+
)
|
|
455
|
+
.replace(
|
|
456
|
+
/^import\s+(\w+)\s*,\s*\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]\s*;?\s*$/gm,
|
|
457
|
+
(_, def, named, mod) =>
|
|
458
|
+
`var __imp = window.require("${mod}"); var ${def} = __imp && __imp.__esModule ? __imp.default : __imp; var {${named}} = __imp;`,
|
|
459
|
+
)
|
|
460
|
+
.replace(
|
|
461
|
+
/^import\s+\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]\s*;?\s*$/gm,
|
|
462
|
+
(_, imports, mod) => `var {${imports}} = window.require("${mod}");`,
|
|
463
|
+
)
|
|
464
|
+
.replace(
|
|
465
|
+
/^import\s+\*\s+as\s+(\w+)\s+from\s+['"]([^'"]+)['"]\s*;?\s*$/gm,
|
|
466
|
+
(_, name, mod) => `var ${name} = window.require("${mod}");`,
|
|
467
|
+
)
|
|
468
|
+
.replace(
|
|
469
|
+
/^import\s+(\w+)\s+from\s+['"]([^'"]+)['"]\s*;?\s*$/gm,
|
|
470
|
+
(_, name, mod) =>
|
|
471
|
+
`var ${name} = (function(m){return m&&m.__esModule?m.default:m})(window.require("${mod}"));`,
|
|
472
|
+
)
|
|
473
|
+
.replace(/^import\s+['"][^'"]+['"]\s*;?\s*$/gm, "");
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Scan source files for bare-specifier imports (e.g. `import { X } from 'pkg'`
|
|
478
|
+
* or `import { Y } from '@scope/pkg/subpath'`).
|
|
479
|
+
* Returns a set of unique full import specifiers found, preserving subpaths
|
|
480
|
+
* so they can be individually resolved and bundled.
|
|
481
|
+
* Handles: named imports, default imports, namespace imports, multi-line destructuring.
|
|
482
|
+
* Skips: `import type` (TS type-only imports), side-effect imports without a specifier.
|
|
483
|
+
*/
|
|
484
|
+
export function scanBareImports(sources: string[]): Set<string> {
|
|
485
|
+
const found = new Set<string>();
|
|
486
|
+
const pattern =
|
|
487
|
+
/import\s+(?:type\s+)?(?:[\w{},*\s]+)\s+from\s+['"]([^./][^'"]*)['"]/g;
|
|
488
|
+
for (const src of sources) {
|
|
489
|
+
let match;
|
|
490
|
+
const re = new RegExp(pattern.source, "g");
|
|
491
|
+
while ((match = re.exec(src)) !== null) {
|
|
492
|
+
const full = match[0];
|
|
493
|
+
if (/^import\s+type\s/.test(full)) continue;
|
|
494
|
+
found.add(match[1]);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
return found;
|
|
498
|
+
}
|