sandlot 0.1.3 → 0.2.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/bundler.d.ts +68 -0
- package/dist/browser/bundler.d.ts.map +1 -0
- package/dist/browser/executor.d.ts +46 -0
- package/dist/browser/executor.d.ts.map +1 -0
- package/dist/browser/index.d.ts +9 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +2692 -0
- package/dist/browser/preset.d.ts +63 -0
- package/dist/browser/preset.d.ts.map +1 -0
- package/dist/commands/index.d.ts +20 -11
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/types.d.ts +31 -132
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/core/bundler-utils.d.ts +142 -0
- package/dist/core/bundler-utils.d.ts.map +1 -0
- package/dist/core/esm-types-resolver.d.ts +125 -0
- package/dist/core/esm-types-resolver.d.ts.map +1 -0
- package/dist/core/executor.d.ts +35 -0
- package/dist/core/executor.d.ts.map +1 -0
- package/dist/{fs.d.ts → core/fs.d.ts} +27 -29
- package/dist/core/fs.d.ts.map +1 -0
- package/dist/core/sandbox.d.ts +30 -0
- package/dist/core/sandbox.d.ts.map +1 -0
- package/dist/core/sandlot.d.ts +30 -0
- package/dist/core/sandlot.d.ts.map +1 -0
- package/dist/core/shared-module-registry.d.ts +46 -0
- package/dist/core/shared-module-registry.d.ts.map +1 -0
- package/dist/core/typechecker.d.ts +60 -0
- package/dist/core/typechecker.d.ts.map +1 -0
- package/dist/index.d.ts +11 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1405 -2049
- package/dist/node/bundler.d.ts +48 -0
- package/dist/node/bundler.d.ts.map +1 -0
- package/dist/node/executor.d.ts +48 -0
- package/dist/node/executor.d.ts.map +1 -0
- package/dist/node/index.d.ts +9 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +2646 -0
- package/dist/node/preset.d.ts +62 -0
- package/dist/node/preset.d.ts.map +1 -0
- package/dist/types.d.ts +525 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +27 -8
- package/src/browser/bundler.ts +294 -0
- package/src/browser/executor.ts +71 -0
- package/src/browser/index.ts +57 -0
- package/src/browser/preset.ts +179 -0
- package/src/commands/index.ts +526 -43
- package/src/commands/types.ts +82 -146
- package/src/core/bundler-utils.ts +630 -0
- package/src/core/esm-types-resolver.ts +432 -0
- package/src/core/executor.ts +161 -0
- package/src/{fs.ts → core/fs.ts} +59 -37
- package/src/core/sandbox.ts +621 -0
- package/src/core/sandlot.ts +77 -0
- package/src/core/shared-module-registry.ts +138 -0
- package/src/core/typechecker.ts +607 -0
- package/src/index.ts +104 -139
- package/src/node/bundler.ts +194 -0
- package/src/node/executor.ts +87 -0
- package/src/node/index.ts +39 -0
- package/src/node/preset.ts +178 -0
- package/src/types.ts +668 -0
- package/README.md +0 -243
- package/dist/build-emitter.d.ts +0 -47
- package/dist/build-emitter.d.ts.map +0 -1
- package/dist/builder.d.ts +0 -370
- package/dist/builder.d.ts.map +0 -1
- package/dist/bundler.d.ts +0 -148
- package/dist/bundler.d.ts.map +0 -1
- package/dist/commands/compile.d.ts +0 -13
- package/dist/commands/compile.d.ts.map +0 -1
- package/dist/commands/packages.d.ts +0 -17
- package/dist/commands/packages.d.ts.map +0 -1
- package/dist/commands/run.d.ts +0 -40
- package/dist/commands/run.d.ts.map +0 -1
- package/dist/commands.d.ts +0 -179
- package/dist/commands.d.ts.map +0 -1
- package/dist/fs.d.ts.map +0 -1
- package/dist/internal.d.ts +0 -79
- package/dist/internal.d.ts.map +0 -1
- package/dist/internal.js +0 -1976
- package/dist/loader.d.ts +0 -164
- package/dist/loader.d.ts.map +0 -1
- package/dist/packages.d.ts +0 -199
- package/dist/packages.d.ts.map +0 -1
- package/dist/runner.d.ts +0 -314
- package/dist/runner.d.ts.map +0 -1
- package/dist/sandbox-manager.d.ts +0 -261
- package/dist/sandbox-manager.d.ts.map +0 -1
- package/dist/sandbox.d.ts +0 -267
- package/dist/sandbox.d.ts.map +0 -1
- package/dist/shared-modules.d.ts +0 -148
- package/dist/shared-modules.d.ts.map +0 -1
- package/dist/shared-resources.d.ts +0 -102
- package/dist/shared-resources.d.ts.map +0 -1
- package/dist/ts-libs.d.ts +0 -98
- package/dist/ts-libs.d.ts.map +0 -1
- package/dist/typechecker.d.ts +0 -127
- package/dist/typechecker.d.ts.map +0 -1
- package/src/build-emitter.ts +0 -64
- package/src/builder.ts +0 -498
- package/src/bundler.ts +0 -542
- package/src/commands/compile.ts +0 -236
- package/src/commands/packages.ts +0 -154
- package/src/commands/run.ts +0 -245
- package/src/internal.ts +0 -119
- package/src/loader.ts +0 -229
- package/src/packages.ts +0 -936
- package/src/sandbox.ts +0 -396
- package/src/shared-modules.ts +0 -280
- package/src/shared-resources.ts +0 -166
- package/src/ts-libs.ts +0 -320
- package/src/typechecker.ts +0 -635
package/src/types.ts
ADDED
|
@@ -0,0 +1,668 @@
|
|
|
1
|
+
import type { IFileSystem, FsEntry, FsStat } from "just-bash/browser";
|
|
2
|
+
import type { Filesystem } from "./core/fs";
|
|
3
|
+
|
|
4
|
+
// =============================================================================
|
|
5
|
+
// Re-export filesystem types for convenience
|
|
6
|
+
// =============================================================================
|
|
7
|
+
|
|
8
|
+
export type { IFileSystem, FsEntry, FsStat } from "just-bash/browser";
|
|
9
|
+
export type { Filesystem } from "./core/fs";
|
|
10
|
+
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Bundler Interface
|
|
13
|
+
// =============================================================================
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Bundler interface - transforms source files into executable JavaScript.
|
|
17
|
+
*
|
|
18
|
+
* Implementations handle their own initialization and caching (e.g., WASM loading).
|
|
19
|
+
*/
|
|
20
|
+
export interface IBundler {
|
|
21
|
+
/**
|
|
22
|
+
* Bundle source files from a filesystem into a single output
|
|
23
|
+
*/
|
|
24
|
+
bundle(options: BundleOptions): Promise<BundleResult>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface BundleOptions {
|
|
28
|
+
fs: Filesystem;
|
|
29
|
+
entryPoint: string;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Map of installed package names to versions.
|
|
33
|
+
* Used by the bundler to resolve imports to specific versions.
|
|
34
|
+
*
|
|
35
|
+
* @example { "lodash": "4.17.21", "react": "18.2.0" }
|
|
36
|
+
*/
|
|
37
|
+
installedPackages?: Record<string, string>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Module IDs that resolve to shared modules instead of bundling.
|
|
41
|
+
* These are provided by the host environment at runtime.
|
|
42
|
+
*/
|
|
43
|
+
sharedModules?: string[];
|
|
44
|
+
|
|
45
|
+
/** Shared module registry for resolving shared imports */
|
|
46
|
+
sharedModuleRegistry?: ISharedModuleRegistry;
|
|
47
|
+
|
|
48
|
+
/** Modules to treat as external (don't bundle or rewrite) */
|
|
49
|
+
external?: string[];
|
|
50
|
+
|
|
51
|
+
format?: "esm" | "iife" | "cjs";
|
|
52
|
+
minify?: boolean;
|
|
53
|
+
sourcemap?: boolean;
|
|
54
|
+
target?: string[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Bundle result - success or failure with structured errors.
|
|
59
|
+
*/
|
|
60
|
+
export type BundleResult = BundleSuccess | BundleFailure;
|
|
61
|
+
|
|
62
|
+
export interface BundleSuccess {
|
|
63
|
+
success: true;
|
|
64
|
+
code: string;
|
|
65
|
+
warnings: BundleWarning[];
|
|
66
|
+
includedFiles: string[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface BundleFailure {
|
|
70
|
+
success: false;
|
|
71
|
+
errors: BundleError[];
|
|
72
|
+
warnings: BundleWarning[];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface BundleWarning {
|
|
76
|
+
text: string;
|
|
77
|
+
location?: BundleLocation;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface BundleError {
|
|
81
|
+
text: string;
|
|
82
|
+
location?: BundleLocation;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface BundleLocation {
|
|
86
|
+
file: string;
|
|
87
|
+
line: number;
|
|
88
|
+
column?: number;
|
|
89
|
+
/** The source line text (if available from esbuild) */
|
|
90
|
+
lineText?: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// =============================================================================
|
|
94
|
+
// Typechecker Interface
|
|
95
|
+
// =============================================================================
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Typechecker interface - validates TypeScript code.
|
|
99
|
+
*
|
|
100
|
+
* Implementations handle their own lib file loading and caching.
|
|
101
|
+
*/
|
|
102
|
+
export interface ITypechecker {
|
|
103
|
+
/**
|
|
104
|
+
* Type check files against a virtual filesystem
|
|
105
|
+
*/
|
|
106
|
+
typecheck(options: TypecheckOptions): Promise<TypecheckResult>;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface TypecheckOptions {
|
|
110
|
+
/** Sync filesystem to read source files from */
|
|
111
|
+
fs: Filesystem;
|
|
112
|
+
/** Entry point path (absolute path in the filesystem) */
|
|
113
|
+
entryPoint: string;
|
|
114
|
+
/** Path to tsconfig.json (default: "/tsconfig.json") */
|
|
115
|
+
tsconfigPath?: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface TypecheckResult {
|
|
119
|
+
success: boolean;
|
|
120
|
+
diagnostics: Diagnostic[];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface Diagnostic {
|
|
124
|
+
file?: string;
|
|
125
|
+
line?: number;
|
|
126
|
+
column?: number;
|
|
127
|
+
message: string;
|
|
128
|
+
severity: "error" | "warning" | "info";
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// =============================================================================
|
|
132
|
+
// Types Resolver Interface
|
|
133
|
+
// =============================================================================
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Types resolver interface - fetches type definitions for npm packages.
|
|
137
|
+
*
|
|
138
|
+
* Implementations handle their own caching (in-memory, KV, R2, etc.).
|
|
139
|
+
*/
|
|
140
|
+
export interface ITypesResolver {
|
|
141
|
+
/**
|
|
142
|
+
* Fetch type definitions for a package.
|
|
143
|
+
* Returns a map of file paths to content for .d.ts files.
|
|
144
|
+
*/
|
|
145
|
+
resolveTypes(
|
|
146
|
+
packageName: string,
|
|
147
|
+
version?: string
|
|
148
|
+
): Promise<Record<string, string>>;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// =============================================================================
|
|
152
|
+
// Shared Module Registry Interface
|
|
153
|
+
// =============================================================================
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Shared module registry interface - provides host modules to bundled code.
|
|
157
|
+
*
|
|
158
|
+
* This allows dynamic code to use the same React/library instances as the host,
|
|
159
|
+
* avoiding the "multiple React instances" problem.
|
|
160
|
+
*
|
|
161
|
+
* Each registry instance has a unique key for global exposure, allowing multiple
|
|
162
|
+
* Sandlot instances to coexist without sharing module state.
|
|
163
|
+
*/
|
|
164
|
+
export interface ISharedModuleRegistry {
|
|
165
|
+
/**
|
|
166
|
+
* The unique global key where this registry is exposed.
|
|
167
|
+
* Bundled code accesses the registry via `globalThis[registryKey]`.
|
|
168
|
+
*/
|
|
169
|
+
readonly registryKey: string;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Get a registered module by ID
|
|
173
|
+
*/
|
|
174
|
+
get(moduleId: string): unknown;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Check if a module is registered
|
|
178
|
+
*/
|
|
179
|
+
has(moduleId: string): boolean;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Get export names for a module (for generating re-exports)
|
|
183
|
+
*/
|
|
184
|
+
getExportNames(moduleId: string): string[];
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* List all registered module IDs
|
|
188
|
+
*/
|
|
189
|
+
list(): string[];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// =============================================================================
|
|
193
|
+
// Executor Interface
|
|
194
|
+
// =============================================================================
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Executor interface - runs bundled code in an isolated context.
|
|
198
|
+
*
|
|
199
|
+
* Different implementations provide different isolation levels:
|
|
200
|
+
* - MainThreadExecutor: Runs in the main thread (no isolation, for trusted code)
|
|
201
|
+
* - WorkerExecutor: Runs in a Web Worker (memory isolation, can be terminated)
|
|
202
|
+
* - IframeExecutor: Runs in a sandboxed iframe (DOM isolation, CSP control)
|
|
203
|
+
*
|
|
204
|
+
* The executor receives a code string (bundled JavaScript) and options,
|
|
205
|
+
* and returns the execution result including captured logs and return value.
|
|
206
|
+
*/
|
|
207
|
+
export interface IExecutor {
|
|
208
|
+
/**
|
|
209
|
+
* Execute bundled code and return the result.
|
|
210
|
+
*
|
|
211
|
+
* @param code - The bundled JavaScript code to execute
|
|
212
|
+
* @param options - Execution options (entry export, context, timeout)
|
|
213
|
+
* @returns Execution result with logs, return value, and any error
|
|
214
|
+
*/
|
|
215
|
+
execute(code: string, options?: ExecuteOptions): Promise<ExecuteResult>;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Options for code execution.
|
|
220
|
+
*/
|
|
221
|
+
export interface ExecuteOptions {
|
|
222
|
+
/**
|
|
223
|
+
* Which export to call:
|
|
224
|
+
* - 'main': Calls `main(context)` export with the provided context
|
|
225
|
+
* - 'default': Calls the default export (no arguments)
|
|
226
|
+
*
|
|
227
|
+
* If neither export exists, top-level code still runs on import.
|
|
228
|
+
* @default 'main'
|
|
229
|
+
*/
|
|
230
|
+
entryExport?: "main" | "default";
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Context object passed to `main(context)` when entryExport is 'main'.
|
|
234
|
+
* Typically includes things like args, env, logging functions.
|
|
235
|
+
*/
|
|
236
|
+
context?: Record<string, unknown>;
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Execution timeout in milliseconds.
|
|
240
|
+
* Set to 0 to disable timeout.
|
|
241
|
+
* @default 30000
|
|
242
|
+
*/
|
|
243
|
+
timeout?: number;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Result of code execution.
|
|
248
|
+
*/
|
|
249
|
+
export interface ExecuteResult {
|
|
250
|
+
/** Whether execution completed successfully */
|
|
251
|
+
success: boolean;
|
|
252
|
+
|
|
253
|
+
/** Captured console output (log, warn, error, info, debug) */
|
|
254
|
+
logs: string[];
|
|
255
|
+
|
|
256
|
+
/** Return value from the executed function (if any) */
|
|
257
|
+
returnValue?: unknown;
|
|
258
|
+
|
|
259
|
+
/** Error message if execution failed */
|
|
260
|
+
error?: string;
|
|
261
|
+
|
|
262
|
+
/** Execution time in milliseconds */
|
|
263
|
+
executionTimeMs?: number;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// =============================================================================
|
|
267
|
+
// Sandlot Configuration
|
|
268
|
+
// =============================================================================
|
|
269
|
+
|
|
270
|
+
export interface SandlotOptions {
|
|
271
|
+
/**
|
|
272
|
+
* Bundler implementation.
|
|
273
|
+
* Handles its own initialization and WASM loading.
|
|
274
|
+
*/
|
|
275
|
+
bundler: IBundler;
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Executor implementation (optional).
|
|
279
|
+
* Handles running bundled code in an appropriate context.
|
|
280
|
+
* If not provided, sandbox.run() will throw an error.
|
|
281
|
+
*/
|
|
282
|
+
executor?: IExecutor;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Typechecker implementation (optional - skip type checking if not provided).
|
|
286
|
+
* Handles its own TypeScript lib file loading and caching.
|
|
287
|
+
*/
|
|
288
|
+
typechecker?: ITypechecker;
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Types resolver for npm packages (optional).
|
|
292
|
+
* Handles its own caching. If not provided, `install` command won't fetch types.
|
|
293
|
+
*/
|
|
294
|
+
typesResolver?: ITypesResolver;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Shared modules - host modules to share with sandboxed code.
|
|
298
|
+
* Keys are import specifiers, values are the actual module objects.
|
|
299
|
+
*
|
|
300
|
+
* @example { 'react': React, 'react-dom/client': ReactDOM }
|
|
301
|
+
*/
|
|
302
|
+
sharedModules?: Record<string, unknown>;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Default options for sandboxes created from this instance
|
|
306
|
+
*/
|
|
307
|
+
sandboxDefaults?: {
|
|
308
|
+
maxFilesystemSize?: number;
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// =============================================================================
|
|
313
|
+
// Sandbox Types
|
|
314
|
+
// =============================================================================
|
|
315
|
+
|
|
316
|
+
export interface SandboxOptions {
|
|
317
|
+
/**
|
|
318
|
+
* Initial files to populate the filesystem with.
|
|
319
|
+
*
|
|
320
|
+
* If `/package.json` is not provided, a default one will be created with:
|
|
321
|
+
* ```json
|
|
322
|
+
* { "main": "./index.ts", "dependencies": {} }
|
|
323
|
+
* ```
|
|
324
|
+
*
|
|
325
|
+
* If `/tsconfig.json` is not provided, sensible defaults will be created.
|
|
326
|
+
*
|
|
327
|
+
* The `main` field in package.json determines the entry point for build/typecheck.
|
|
328
|
+
*/
|
|
329
|
+
initialFiles?: Record<string, string>;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Maximum filesystem size in bytes
|
|
333
|
+
*/
|
|
334
|
+
maxFilesystemSize?: number;
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Callback invoked when a build succeeds
|
|
338
|
+
*/
|
|
339
|
+
onBuild?: (result: BuildSuccess) => void | Promise<void>;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Build phases that can fail.
|
|
344
|
+
*/
|
|
345
|
+
export type BuildPhase = "entry" | "typecheck" | "bundle";
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Build result - success or failure with structured errors.
|
|
349
|
+
*
|
|
350
|
+
* On success, contains the bundled code string.
|
|
351
|
+
* On failure, contains the phase that failed and structured error information.
|
|
352
|
+
*
|
|
353
|
+
* Note: Build does NOT load or execute the module. Use an executor to run the code.
|
|
354
|
+
* This keeps the build phase pure (no code execution) and allows different execution
|
|
355
|
+
* contexts (main thread, web worker, iframe, remote server).
|
|
356
|
+
*/
|
|
357
|
+
export type BuildResult = BuildSuccess | BuildFailure;
|
|
358
|
+
|
|
359
|
+
export interface BuildSuccess {
|
|
360
|
+
success: true;
|
|
361
|
+
/** The bundled JavaScript code */
|
|
362
|
+
code: string;
|
|
363
|
+
/** Files that were included in the bundle */
|
|
364
|
+
includedFiles: string[];
|
|
365
|
+
/** Any warnings from the bundler */
|
|
366
|
+
warnings: BundleWarning[];
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export interface BuildFailure {
|
|
370
|
+
success: false;
|
|
371
|
+
/** Which phase of the build failed */
|
|
372
|
+
phase: BuildPhase;
|
|
373
|
+
/** Error message (for entry failures) */
|
|
374
|
+
message?: string;
|
|
375
|
+
/** Type check diagnostics (for typecheck failures) */
|
|
376
|
+
diagnostics?: Diagnostic[];
|
|
377
|
+
/** Bundle errors (for bundle failures) */
|
|
378
|
+
bundleErrors?: BundleError[];
|
|
379
|
+
/** Bundle warnings (may be present even on failure) */
|
|
380
|
+
bundleWarnings?: BundleWarning[];
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
// -----------------------------------------------------------------------------
|
|
385
|
+
// Install/Uninstall Types
|
|
386
|
+
// -----------------------------------------------------------------------------
|
|
387
|
+
|
|
388
|
+
export interface InstallResult {
|
|
389
|
+
/** Package name */
|
|
390
|
+
name: string;
|
|
391
|
+
/** Resolved version */
|
|
392
|
+
version: string;
|
|
393
|
+
/** Whether type definitions were installed */
|
|
394
|
+
typesInstalled: boolean;
|
|
395
|
+
/** Number of .d.ts files written */
|
|
396
|
+
typeFilesCount: number;
|
|
397
|
+
/** Whether types came from cache */
|
|
398
|
+
fromCache?: boolean;
|
|
399
|
+
/** Error message if types failed to install */
|
|
400
|
+
typesError?: string;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export interface UninstallResult {
|
|
404
|
+
/** Package name */
|
|
405
|
+
name: string;
|
|
406
|
+
/** Whether the package was installed (and thus removed) */
|
|
407
|
+
removed: boolean;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// -----------------------------------------------------------------------------
|
|
411
|
+
// Build Options
|
|
412
|
+
// -----------------------------------------------------------------------------
|
|
413
|
+
|
|
414
|
+
export interface SandboxBuildOptions {
|
|
415
|
+
/**
|
|
416
|
+
* Entry point to build.
|
|
417
|
+
* If not specified, reads from `main` field in /package.json.
|
|
418
|
+
* Falls back to "./index.ts" if not found.
|
|
419
|
+
*/
|
|
420
|
+
entryPoint?: string;
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Skip type checking before bundling.
|
|
424
|
+
* @default false
|
|
425
|
+
*/
|
|
426
|
+
skipTypecheck?: boolean;
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Minify the output.
|
|
430
|
+
* @default false
|
|
431
|
+
*/
|
|
432
|
+
minify?: boolean;
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Output format.
|
|
436
|
+
* @default "esm"
|
|
437
|
+
*/
|
|
438
|
+
format?: "esm" | "iife" | "cjs";
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// -----------------------------------------------------------------------------
|
|
442
|
+
// Typecheck Options
|
|
443
|
+
// -----------------------------------------------------------------------------
|
|
444
|
+
|
|
445
|
+
export interface SandboxTypecheckOptions {
|
|
446
|
+
/**
|
|
447
|
+
* Entry point to typecheck.
|
|
448
|
+
* If not specified, reads from `main` field in /package.json.
|
|
449
|
+
* Falls back to "./index.ts" if not found.
|
|
450
|
+
*/
|
|
451
|
+
entryPoint?: string;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// -----------------------------------------------------------------------------
|
|
455
|
+
// Run Options and Result
|
|
456
|
+
// -----------------------------------------------------------------------------
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Options for running code in the sandbox.
|
|
460
|
+
*/
|
|
461
|
+
export interface RunOptions {
|
|
462
|
+
/**
|
|
463
|
+
* Entry point to build and run.
|
|
464
|
+
* If not specified, reads from `main` field in /package.json.
|
|
465
|
+
* Falls back to "./index.ts" if not found.
|
|
466
|
+
*/
|
|
467
|
+
entryPoint?: string;
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Skip type checking before building.
|
|
471
|
+
* @default false
|
|
472
|
+
*/
|
|
473
|
+
skipTypecheck?: boolean;
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Which export to call:
|
|
477
|
+
* - 'main': Calls `main(context)` export with the provided context
|
|
478
|
+
* - 'default': Calls the default export (no arguments)
|
|
479
|
+
* @default 'main'
|
|
480
|
+
*/
|
|
481
|
+
entryExport?: "main" | "default";
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Context object passed to `main(context)` when entryExport is 'main'.
|
|
485
|
+
*/
|
|
486
|
+
context?: Record<string, unknown>;
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Execution timeout in milliseconds.
|
|
490
|
+
* Set to 0 to disable timeout.
|
|
491
|
+
* @default 30000
|
|
492
|
+
*/
|
|
493
|
+
timeout?: number;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Result of running code in the sandbox.
|
|
498
|
+
*
|
|
499
|
+
* Extends ExecuteResult with build failure information.
|
|
500
|
+
* If `buildFailure` is present, the build failed before execution.
|
|
501
|
+
*/
|
|
502
|
+
export interface RunResult extends ExecuteResult {
|
|
503
|
+
/** If build failed, contains failure details */
|
|
504
|
+
buildFailure?: {
|
|
505
|
+
phase: BuildPhase;
|
|
506
|
+
message?: string;
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// -----------------------------------------------------------------------------
|
|
511
|
+
// Sandbox Interface
|
|
512
|
+
// -----------------------------------------------------------------------------
|
|
513
|
+
|
|
514
|
+
export interface Sandbox {
|
|
515
|
+
/**
|
|
516
|
+
* The virtual filesystem (sync)
|
|
517
|
+
*/
|
|
518
|
+
readonly fs: Filesystem;
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Execute a shell command
|
|
522
|
+
*/
|
|
523
|
+
exec(command: string): Promise<ExecResult>;
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* The last successful build result (code string + metadata)
|
|
527
|
+
*/
|
|
528
|
+
readonly lastBuild: BuildSuccess | null;
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Get the current sandbox state for persistence
|
|
532
|
+
*/
|
|
533
|
+
getState(): SandboxState;
|
|
534
|
+
|
|
535
|
+
// ---------------------------------------------------------------------------
|
|
536
|
+
// File Operations (convenience methods)
|
|
537
|
+
// ---------------------------------------------------------------------------
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Read a file from the virtual filesystem.
|
|
541
|
+
*
|
|
542
|
+
* @param path - Absolute path to the file (e.g., "/src/app.ts")
|
|
543
|
+
* @returns File contents as a string
|
|
544
|
+
* @throws If the file does not exist
|
|
545
|
+
*/
|
|
546
|
+
readFile(path: string): string;
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Write a file to the virtual filesystem.
|
|
550
|
+
* Creates parent directories automatically if they don't exist.
|
|
551
|
+
*
|
|
552
|
+
* @param path - Absolute path to the file (e.g., "/src/app.ts")
|
|
553
|
+
* @param content - File contents to write
|
|
554
|
+
*/
|
|
555
|
+
writeFile(path: string, content: string): void;
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Subscribe to build events
|
|
559
|
+
*/
|
|
560
|
+
onBuild(callback: (result: BuildSuccess) => void | Promise<void>): () => void;
|
|
561
|
+
|
|
562
|
+
// ---------------------------------------------------------------------------
|
|
563
|
+
// Direct Methods (also available via exec)
|
|
564
|
+
// ---------------------------------------------------------------------------
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Install a package from npm.
|
|
568
|
+
* Updates /package.json and fetches type definitions if typesResolver is configured.
|
|
569
|
+
*
|
|
570
|
+
* @param packageSpec - Package specifier (e.g., "lodash", "lodash@4.17.21", "@types/node@20")
|
|
571
|
+
* @returns Installation result with version and types info
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* await sandbox.install("lodash@4.17.21");
|
|
575
|
+
* await sandbox.install("@tanstack/react-query");
|
|
576
|
+
*/
|
|
577
|
+
install(packageSpec: string): Promise<InstallResult>;
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Uninstall a package.
|
|
581
|
+
* Removes from /package.json and deletes type definition files.
|
|
582
|
+
*
|
|
583
|
+
* @param packageName - Package name (e.g., "lodash", "@tanstack/react-query")
|
|
584
|
+
* @returns Whether the package was removed
|
|
585
|
+
*/
|
|
586
|
+
uninstall(packageName: string): Promise<UninstallResult>;
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* Build the project.
|
|
590
|
+
* Reads dependencies from /package.json, optionally typechecks, and bundles.
|
|
591
|
+
* Returns the bundled code string (does NOT execute it).
|
|
592
|
+
*
|
|
593
|
+
* @param options - Build options
|
|
594
|
+
* @returns Build result - check `success` field to determine outcome
|
|
595
|
+
*/
|
|
596
|
+
build(options?: SandboxBuildOptions): Promise<BuildResult>;
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Type check the project.
|
|
600
|
+
* Reads tsconfig from filesystem and runs the typechecker.
|
|
601
|
+
*
|
|
602
|
+
* @param options - Typecheck options
|
|
603
|
+
* @returns Typecheck result with diagnostics
|
|
604
|
+
*/
|
|
605
|
+
typecheck(options?: SandboxTypecheckOptions): Promise<TypecheckResult>;
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Build and run code using the configured executor.
|
|
609
|
+
*
|
|
610
|
+
* This is a convenience method that:
|
|
611
|
+
* 1. Builds the code (typecheck + bundle)
|
|
612
|
+
* 2. Passes the bundled code to the executor
|
|
613
|
+
* 3. Returns the execution result
|
|
614
|
+
*
|
|
615
|
+
* Requires an executor to be configured when creating Sandlot.
|
|
616
|
+
*
|
|
617
|
+
* @param options - Run options (entry point, context, timeout, etc.)
|
|
618
|
+
* @returns Run result with logs, return value, and any error
|
|
619
|
+
* @throws If no executor was configured
|
|
620
|
+
*
|
|
621
|
+
* @example
|
|
622
|
+
* ```ts
|
|
623
|
+
* // Script style - top-level code runs on import
|
|
624
|
+
* sandbox.writeFile('/index.ts', 'console.log("Hello!")');
|
|
625
|
+
* const result = await sandbox.run();
|
|
626
|
+
* console.log(result.logs); // ['Hello!']
|
|
627
|
+
*
|
|
628
|
+
* // Main function style - gets context
|
|
629
|
+
* sandbox.writeFile('/index.ts', `
|
|
630
|
+
* export function main(ctx) {
|
|
631
|
+
* ctx.log("Args:", ctx.args);
|
|
632
|
+
* return { success: true };
|
|
633
|
+
* }
|
|
634
|
+
* `);
|
|
635
|
+
* const result = await sandbox.run({
|
|
636
|
+
* context: { args: ['--verbose'] }
|
|
637
|
+
* });
|
|
638
|
+
* console.log(result.returnValue); // { success: true }
|
|
639
|
+
* ```
|
|
640
|
+
*/
|
|
641
|
+
run(options?: RunOptions): Promise<RunResult>;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
export interface ExecResult {
|
|
645
|
+
exitCode: number;
|
|
646
|
+
stdout: string;
|
|
647
|
+
stderr: string;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
export interface SandboxState {
|
|
651
|
+
files: Record<string, string>;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// =============================================================================
|
|
655
|
+
// Sandlot Interface
|
|
656
|
+
// =============================================================================
|
|
657
|
+
|
|
658
|
+
export interface Sandlot {
|
|
659
|
+
/**
|
|
660
|
+
* Create a new sandbox environment
|
|
661
|
+
*/
|
|
662
|
+
createSandbox(options?: SandboxOptions): Promise<Sandbox>;
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* The shared module registry (if shared modules were provided)
|
|
666
|
+
*/
|
|
667
|
+
readonly sharedModules: ISharedModuleRegistry | null;
|
|
668
|
+
}
|