@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
package/src/kernel.ts
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { MemFS } from "./memfs";
|
|
2
|
+
import type { IExecuteResult } from "./runtime-interface";
|
|
3
|
+
import { simpleHash } from "./utils/hash";
|
|
4
|
+
import { createFsShim, FsShim } from "./polyfills/fs";
|
|
5
|
+
import * as pathShim from "./polyfills/path";
|
|
6
|
+
import { createProcess, Process } from "./polyfills/process";
|
|
7
|
+
import { initChildProcess } from "./polyfills/child_process";
|
|
8
|
+
import { initChokidar } from "./polyfills/chokidar";
|
|
9
|
+
import { initReaddirp } from "./polyfills/readdirp";
|
|
10
|
+
import { initModule } from "./polyfills/module";
|
|
11
|
+
import { bufferPolyfill } from "./builtins";
|
|
12
|
+
import {
|
|
13
|
+
initTranspiler,
|
|
14
|
+
isInitialized,
|
|
15
|
+
needsTranspilation,
|
|
16
|
+
type InitOptions,
|
|
17
|
+
} from "./transpiler";
|
|
18
|
+
import {
|
|
19
|
+
transpileCache,
|
|
20
|
+
ensureTranspiled,
|
|
21
|
+
transformEsmToCjs,
|
|
22
|
+
getProcessedSource,
|
|
23
|
+
} from "./code-transform";
|
|
24
|
+
import {
|
|
25
|
+
ModuleResolver,
|
|
26
|
+
type Module,
|
|
27
|
+
type RuntimeOptions,
|
|
28
|
+
type RequireFunction,
|
|
29
|
+
} from "./module-resolver";
|
|
30
|
+
import {
|
|
31
|
+
wrapDynamicImport,
|
|
32
|
+
buildConsoleProxy,
|
|
33
|
+
buildModuleWrapper,
|
|
34
|
+
} from "./runtime-helpers";
|
|
35
|
+
import { builtinModules } from "./builtins";
|
|
36
|
+
import type { PluginRegistry } from "./plugin";
|
|
37
|
+
|
|
38
|
+
export type { Module, RuntimeOptions, RequireFunction };
|
|
39
|
+
|
|
40
|
+
function createRequire(
|
|
41
|
+
vfs: MemFS,
|
|
42
|
+
fsShim: FsShim,
|
|
43
|
+
process: Process,
|
|
44
|
+
currentDir: string,
|
|
45
|
+
moduleCache: Record<string, Module>,
|
|
46
|
+
options: RuntimeOptions,
|
|
47
|
+
processedCodeCache?: Map<string, string>,
|
|
48
|
+
pluginRegistry?: PluginRegistry,
|
|
49
|
+
): RequireFunction {
|
|
50
|
+
const resolver = new ModuleResolver(
|
|
51
|
+
vfs,
|
|
52
|
+
fsShim,
|
|
53
|
+
process,
|
|
54
|
+
moduleCache,
|
|
55
|
+
options,
|
|
56
|
+
processedCodeCache || new Map(),
|
|
57
|
+
pluginRegistry,
|
|
58
|
+
);
|
|
59
|
+
return resolver.makeRequire(currentDir);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class Kernel {
|
|
63
|
+
vfs: MemFS;
|
|
64
|
+
fsShim: FsShim;
|
|
65
|
+
process: Process;
|
|
66
|
+
moduleCache: Record<string, Module> = {};
|
|
67
|
+
processedCodeCache = new Map<string, string>();
|
|
68
|
+
private options: RuntimeOptions;
|
|
69
|
+
private maxCacheSize = 4000;
|
|
70
|
+
private cacheAccessTime = new Map<string, number>();
|
|
71
|
+
private resolver: ModuleResolver;
|
|
72
|
+
/** Plugin registry for this kernel (shared with child kernels). */
|
|
73
|
+
readonly pluginRegistry?: PluginRegistry;
|
|
74
|
+
|
|
75
|
+
constructor(
|
|
76
|
+
vfs: MemFS,
|
|
77
|
+
options: RuntimeOptions = {},
|
|
78
|
+
pluginRegistry?: PluginRegistry,
|
|
79
|
+
) {
|
|
80
|
+
this.vfs = vfs;
|
|
81
|
+
this.options = options;
|
|
82
|
+
this.pluginRegistry = pluginRegistry;
|
|
83
|
+
this.process = createProcess({
|
|
84
|
+
cwd: options.cwd || "/",
|
|
85
|
+
env: options.env,
|
|
86
|
+
onStdout: options.onStdout,
|
|
87
|
+
onStderr: options.onStderr,
|
|
88
|
+
});
|
|
89
|
+
this.fsShim = createFsShim(vfs, () => this.process.cwd());
|
|
90
|
+
this.resolver = new ModuleResolver(
|
|
91
|
+
vfs,
|
|
92
|
+
this.fsShim,
|
|
93
|
+
this.process,
|
|
94
|
+
this.moduleCache,
|
|
95
|
+
this.options,
|
|
96
|
+
this.processedCodeCache,
|
|
97
|
+
pluginRegistry,
|
|
98
|
+
);
|
|
99
|
+
initChildProcess(
|
|
100
|
+
vfs,
|
|
101
|
+
(v, opts) => new Kernel(v, opts as RuntimeOptions, pluginRegistry),
|
|
102
|
+
);
|
|
103
|
+
initChokidar(vfs);
|
|
104
|
+
initReaddirp(vfs);
|
|
105
|
+
initModule(dir => this.resolver.makeRequire(dir));
|
|
106
|
+
this.patchGlobals();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async init(options?: InitOptions): Promise<void> {
|
|
110
|
+
await initTranspiler(options);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async prepareFile(filename: string): Promise<void> {
|
|
114
|
+
if (!isInitialized()) await initTranspiler();
|
|
115
|
+
await this.walkImports(filename, new Set());
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private async walkImports(file: string, seen: Set<string>): Promise<void> {
|
|
119
|
+
if (seen.has(file)) return;
|
|
120
|
+
seen.add(file);
|
|
121
|
+
if (!this.vfs.existsSync(file)) return;
|
|
122
|
+
|
|
123
|
+
const source = this.vfs.readFileSync(file, "utf8");
|
|
124
|
+
await ensureTranspiled(file, source);
|
|
125
|
+
|
|
126
|
+
const hash = simpleHash(source);
|
|
127
|
+
const processed = transpileCache.get(`${file}:${hash}`) || source;
|
|
128
|
+
|
|
129
|
+
const importPattern =
|
|
130
|
+
/(?:require\s*\(\s*['"]|from\s+['"]|import\s+['"])([^'"]+)['"]/g;
|
|
131
|
+
const dir = pathShim.dirname(file);
|
|
132
|
+
|
|
133
|
+
let m;
|
|
134
|
+
while ((m = importPattern.exec(processed)) !== null) {
|
|
135
|
+
const spec = m[1];
|
|
136
|
+
if (!spec.startsWith(".") && !spec.startsWith("/")) continue;
|
|
137
|
+
const abs = spec.startsWith("/") ? spec : pathShim.resolve(dir, spec);
|
|
138
|
+
const resolved = this.resolver.probeFile(abs);
|
|
139
|
+
if (resolved) await this.walkImports(resolved, seen);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private patchGlobals(): void {
|
|
144
|
+
const inBrowser =
|
|
145
|
+
typeof window !== "undefined" || typeof importScripts === "function";
|
|
146
|
+
|
|
147
|
+
if (!globalThis.Buffer || inBrowser) {
|
|
148
|
+
(globalThis as any).Buffer = bufferPolyfill.Buffer;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (typeof globalThis.setImmediate === "undefined") {
|
|
152
|
+
(globalThis as any).setImmediate = (fn: () => void, ...args: unknown[]) =>
|
|
153
|
+
setTimeout(fn, 0, ...args);
|
|
154
|
+
(globalThis as any).clearImmediate = clearTimeout;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (inBrowser && !(globalThis.setTimeout as any).__patched) {
|
|
158
|
+
const origTimeout = globalThis.setTimeout;
|
|
159
|
+
const origInterval = globalThis.setInterval;
|
|
160
|
+
const timerExtras = () => ({
|
|
161
|
+
ref() {
|
|
162
|
+
return this;
|
|
163
|
+
},
|
|
164
|
+
unref() {
|
|
165
|
+
return this;
|
|
166
|
+
},
|
|
167
|
+
refresh() {
|
|
168
|
+
return this;
|
|
169
|
+
},
|
|
170
|
+
hasRef() {
|
|
171
|
+
return true;
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
(globalThis as any).setTimeout = Object.assign(
|
|
175
|
+
(fn: () => void, ms?: number, ...args: unknown[]) => {
|
|
176
|
+
const id = origTimeout(fn, ms, ...args);
|
|
177
|
+
return Object.assign(id, {
|
|
178
|
+
...timerExtras(),
|
|
179
|
+
[Symbol.toPrimitive]() {
|
|
180
|
+
return id;
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
},
|
|
184
|
+
{ __patched: true },
|
|
185
|
+
);
|
|
186
|
+
(globalThis as any).setInterval = Object.assign(
|
|
187
|
+
(fn: () => void, ms?: number, ...args: unknown[]) => {
|
|
188
|
+
const id = origInterval(fn, ms, ...args);
|
|
189
|
+
return Object.assign(id, {
|
|
190
|
+
...timerExtras(),
|
|
191
|
+
[Symbol.toPrimitive]() {
|
|
192
|
+
return id;
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
},
|
|
196
|
+
{ __patched: true },
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (!(Error as any).captureStackTrace) {
|
|
201
|
+
(Error as any).captureStackTrace = (target: Error) => {
|
|
202
|
+
const trace = new Error().stack;
|
|
203
|
+
if (trace)
|
|
204
|
+
Object.defineProperty(target, "stack", {
|
|
205
|
+
value: trace,
|
|
206
|
+
writable: true,
|
|
207
|
+
configurable: true,
|
|
208
|
+
});
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
if (!(Error as any).prepareStackTrace) {
|
|
212
|
+
(Error as any).prepareStackTrace = undefined;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
execute(code: string, filename?: string): IExecuteResult {
|
|
217
|
+
const fname = filename || `/__exec_${simpleHash(code)}.js`;
|
|
218
|
+
this.vfs.writeFileSync(fname, code);
|
|
219
|
+
return this.runFileSync(fname);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
executeSync(code: string, filename?: string): IExecuteResult {
|
|
223
|
+
return this.execute(code, filename);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async executeAsync(code: string, filename?: string): Promise<IExecuteResult> {
|
|
227
|
+
return this.execute(code, filename);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
runFile(filename: string): IExecuteResult {
|
|
231
|
+
return this.runFileSync(filename);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
runFileSync(filename: string): IExecuteResult {
|
|
235
|
+
const dir = pathShim.dirname(filename);
|
|
236
|
+
const localRequire = this.resolver.makeRequire(dir);
|
|
237
|
+
|
|
238
|
+
this.trimCacheIfOversized();
|
|
239
|
+
|
|
240
|
+
const entry: Module = {
|
|
241
|
+
id: filename,
|
|
242
|
+
filename,
|
|
243
|
+
exports: {},
|
|
244
|
+
loaded: false,
|
|
245
|
+
children: [],
|
|
246
|
+
paths: [dir],
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const rawSource = this.vfs.readFileSync(filename, "utf8");
|
|
250
|
+
let source = getProcessedSource(
|
|
251
|
+
rawSource,
|
|
252
|
+
filename,
|
|
253
|
+
this.processedCodeCache,
|
|
254
|
+
this.options.sourceMaps,
|
|
255
|
+
);
|
|
256
|
+
// Run plugin transform pipeline on the executed file.
|
|
257
|
+
if (this.pluginRegistry) {
|
|
258
|
+
source = this.pluginRegistry.runTransform(filename, source);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const meta = { url: `file://${filename}`, dirname: dir, filename };
|
|
262
|
+
const dynImport = wrapDynamicImport(localRequire);
|
|
263
|
+
const consoleFacade = buildConsoleProxy(this.options.onConsole);
|
|
264
|
+
const wrapper = buildModuleWrapper(source, filename);
|
|
265
|
+
|
|
266
|
+
wrapper(
|
|
267
|
+
entry.exports,
|
|
268
|
+
localRequire,
|
|
269
|
+
entry,
|
|
270
|
+
filename,
|
|
271
|
+
dir,
|
|
272
|
+
this.process,
|
|
273
|
+
consoleFacade,
|
|
274
|
+
meta,
|
|
275
|
+
dynImport,
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
entry.loaded = true;
|
|
279
|
+
this.moduleCache[filename] = entry;
|
|
280
|
+
this.cacheAccessTime.set(filename, Date.now());
|
|
281
|
+
return { exports: entry.exports, module: entry };
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
async runFileAsync(filename: string): Promise<IExecuteResult> {
|
|
285
|
+
return this.runFileSync(filename);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
clearCache(): void {
|
|
289
|
+
for (const key of Object.keys(this.moduleCache)) {
|
|
290
|
+
delete this.moduleCache[key];
|
|
291
|
+
}
|
|
292
|
+
this.cacheAccessTime.clear();
|
|
293
|
+
this.processedCodeCache.clear();
|
|
294
|
+
this.resolver.clearMemos();
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
invalidateModule(path: string): void {
|
|
298
|
+
delete this.moduleCache[path];
|
|
299
|
+
const prefix = `${path}:`;
|
|
300
|
+
for (const key of this.processedCodeCache.keys()) {
|
|
301
|
+
if (key.startsWith(prefix)) this.processedCodeCache.delete(key);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
invalidateModulesMatching(predicate: (path: string) => boolean): void {
|
|
306
|
+
for (const key of Object.keys(this.moduleCache)) {
|
|
307
|
+
if (predicate(key)) delete this.moduleCache[key];
|
|
308
|
+
}
|
|
309
|
+
for (const key of this.processedCodeCache.keys()) {
|
|
310
|
+
if (predicate(key.split(":")[0])) this.processedCodeCache.delete(key);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
getVFS(): MemFS {
|
|
315
|
+
return this.vfs;
|
|
316
|
+
}
|
|
317
|
+
getProcess(): Process {
|
|
318
|
+
return this.process;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
private trimCacheIfOversized(): void {
|
|
322
|
+
const keys = Object.keys(this.moduleCache);
|
|
323
|
+
if (keys.length > this.maxCacheSize) {
|
|
324
|
+
// Sort by last-access time (LRU first) and evict least recently used
|
|
325
|
+
const sorted = keys.sort((a, b) => {
|
|
326
|
+
const aTime = this.cacheAccessTime.get(a) || 0;
|
|
327
|
+
const bTime = this.cacheAccessTime.get(b) || 0;
|
|
328
|
+
return aTime - bTime;
|
|
329
|
+
});
|
|
330
|
+
const evictCount = keys.length - this.maxCacheSize + 100;
|
|
331
|
+
const stale = sorted.slice(0, evictCount);
|
|
332
|
+
for (const k of stale) {
|
|
333
|
+
delete this.moduleCache[k];
|
|
334
|
+
this.cacheAccessTime.delete(k);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** Record access time for a module cache entry */
|
|
340
|
+
touchCacheEntry(key: string): void {
|
|
341
|
+
this.cacheAccessTime.set(key, Date.now());
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
createREPL(): { eval: (code: string) => unknown } {
|
|
345
|
+
const scope: Record<string, unknown> = {};
|
|
346
|
+
const dir = this.process.cwd();
|
|
347
|
+
const localRequire = this.resolver.makeRequire(dir);
|
|
348
|
+
const VALID_IDENT = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
eval: (input: string): unknown => {
|
|
352
|
+
const adapted = input.replace(/^(const|let)\s+/gm, "var ");
|
|
353
|
+
// Filter scope keys to only valid JS identifiers to prevent code injection
|
|
354
|
+
const safeKeys = Object.keys(scope).filter(k => VALID_IDENT.test(k));
|
|
355
|
+
const safeValues = safeKeys.map(k => scope[k]);
|
|
356
|
+
try {
|
|
357
|
+
const fn = new Function(
|
|
358
|
+
"require",
|
|
359
|
+
"process",
|
|
360
|
+
"console",
|
|
361
|
+
...safeKeys,
|
|
362
|
+
`return (${adapted})`,
|
|
363
|
+
);
|
|
364
|
+
return fn(localRequire, this.process, console, ...safeValues);
|
|
365
|
+
} catch {
|
|
366
|
+
const fn = new Function(
|
|
367
|
+
"require",
|
|
368
|
+
"process",
|
|
369
|
+
"console",
|
|
370
|
+
...safeKeys,
|
|
371
|
+
adapted,
|
|
372
|
+
);
|
|
373
|
+
return fn(localRequire, this.process, console, ...safeValues);
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export { transformEsmToCjs, createRequire, builtinModules };
|
|
381
|
+
export { Kernel as Runtime };
|