@ebowwa/sandbox 0.1.1

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.
Files changed (108) hide show
  1. package/dist/compilers/index.d.ts +24 -0
  2. package/dist/compilers/index.d.ts.map +1 -0
  3. package/dist/compilers/index.js +42 -0
  4. package/dist/compilers/index.js.map +1 -0
  5. package/dist/compilers/javascript.d.ts +117 -0
  6. package/dist/compilers/javascript.d.ts.map +1 -0
  7. package/dist/compilers/javascript.js +462 -0
  8. package/dist/compilers/javascript.js.map +1 -0
  9. package/dist/compilers/python.d.ts +140 -0
  10. package/dist/compilers/python.d.ts.map +1 -0
  11. package/dist/compilers/python.js +650 -0
  12. package/dist/compilers/python.js.map +1 -0
  13. package/dist/compilers/typescript.d.ts +99 -0
  14. package/dist/compilers/typescript.d.ts.map +1 -0
  15. package/dist/compilers/typescript.js +323 -0
  16. package/dist/compilers/typescript.js.map +1 -0
  17. package/dist/core/cell.d.ts +160 -0
  18. package/dist/core/cell.d.ts.map +1 -0
  19. package/dist/core/cell.js +319 -0
  20. package/dist/core/cell.js.map +1 -0
  21. package/dist/core/compiler.d.ts +126 -0
  22. package/dist/core/compiler.d.ts.map +1 -0
  23. package/dist/core/compiler.js +123 -0
  24. package/dist/core/compiler.js.map +1 -0
  25. package/dist/core/index.d.ts +19 -0
  26. package/dist/core/index.d.ts.map +1 -0
  27. package/dist/core/index.js +14 -0
  28. package/dist/core/index.js.map +1 -0
  29. package/dist/core/limits.d.ts +173 -0
  30. package/dist/core/limits.d.ts.map +1 -0
  31. package/dist/core/limits.js +440 -0
  32. package/dist/core/limits.js.map +1 -0
  33. package/dist/core/permissions.d.ts +103 -0
  34. package/dist/core/permissions.d.ts.map +1 -0
  35. package/dist/core/permissions.js +341 -0
  36. package/dist/core/permissions.js.map +1 -0
  37. package/dist/core/runtime.d.ts +127 -0
  38. package/dist/core/runtime.d.ts.map +1 -0
  39. package/dist/core/runtime.js +325 -0
  40. package/dist/core/runtime.js.map +1 -0
  41. package/dist/core/types.d.ts +380 -0
  42. package/dist/core/types.d.ts.map +1 -0
  43. package/dist/core/types.js +67 -0
  44. package/dist/core/types.js.map +1 -0
  45. package/dist/index.d.ts +145 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +279 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/multi/index.d.ts +9 -0
  50. package/dist/multi/index.d.ts.map +1 -0
  51. package/dist/multi/index.js +7 -0
  52. package/dist/multi/index.js.map +1 -0
  53. package/dist/multi/polyglot.d.ts +179 -0
  54. package/dist/multi/polyglot.d.ts.map +1 -0
  55. package/dist/multi/polyglot.js +319 -0
  56. package/dist/multi/polyglot.js.map +1 -0
  57. package/dist/runtimes/docker.d.ts +97 -0
  58. package/dist/runtimes/docker.d.ts.map +1 -0
  59. package/dist/runtimes/docker.js +368 -0
  60. package/dist/runtimes/docker.js.map +1 -0
  61. package/dist/runtimes/index.d.ts +11 -0
  62. package/dist/runtimes/index.d.ts.map +1 -0
  63. package/dist/runtimes/index.js +9 -0
  64. package/dist/runtimes/index.js.map +1 -0
  65. package/dist/runtimes/process.d.ts +47 -0
  66. package/dist/runtimes/process.d.ts.map +1 -0
  67. package/dist/runtimes/process.js +230 -0
  68. package/dist/runtimes/process.js.map +1 -0
  69. package/dist/session/index.d.ts +12 -0
  70. package/dist/session/index.d.ts.map +1 -0
  71. package/dist/session/index.js +9 -0
  72. package/dist/session/index.js.map +1 -0
  73. package/dist/session/kernel.d.ts +199 -0
  74. package/dist/session/kernel.d.ts.map +1 -0
  75. package/dist/session/kernel.js +400 -0
  76. package/dist/session/kernel.js.map +1 -0
  77. package/dist/session/notebook.d.ts +168 -0
  78. package/dist/session/notebook.d.ts.map +1 -0
  79. package/dist/session/notebook.js +499 -0
  80. package/dist/session/notebook.js.map +1 -0
  81. package/dist/session/repl.d.ts +159 -0
  82. package/dist/session/repl.d.ts.map +1 -0
  83. package/dist/session/repl.js +409 -0
  84. package/dist/session/repl.js.map +1 -0
  85. package/package.json +142 -0
  86. package/src/compilers/index.ts +80 -0
  87. package/src/compilers/javascript.ts +571 -0
  88. package/src/compilers/python.ts +785 -0
  89. package/src/compilers/typescript.ts +442 -0
  90. package/src/core/cell.ts +439 -0
  91. package/src/core/compiler.ts +250 -0
  92. package/src/core/index.ts +123 -0
  93. package/src/core/limits.ts +508 -0
  94. package/src/core/permissions.ts +409 -0
  95. package/src/core/runtime.ts +499 -0
  96. package/src/core/types.ts +528 -0
  97. package/src/global.d.ts +59 -0
  98. package/src/index.ts +515 -0
  99. package/src/multi/index.ts +22 -0
  100. package/src/multi/polyglot.ts +461 -0
  101. package/src/runtimes/docker.ts +501 -0
  102. package/src/runtimes/index.ts +21 -0
  103. package/src/runtimes/process.ts +316 -0
  104. package/src/session/index.ts +41 -0
  105. package/src/session/kernel.ts +553 -0
  106. package/src/session/notebook.ts +635 -0
  107. package/src/session/repl.ts +521 -0
  108. package/src/wasm2wasm.d.ts +35 -0
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Language Compilers
3
+ *
4
+ * Export all available compilers for the sandbox.
5
+ * Each compiler transforms source code to WASM format.
6
+ */
7
+ export { PythonCompiler, createPythonCompiler, pythonCompiler, type PythonValidationResult, } from "./python.js";
8
+ export { JavaScriptCompiler, javascriptCompiler, type JavaScriptCompilerOptions, } from "./javascript.js";
9
+ export { TypeScriptCompiler, typescriptCompiler, type TypeScriptCompilerOptions, } from "./typescript.js";
10
+ export type { CompileResult, ImportDefinition, CompilerOptions, ICompiler, LanguageCapabilities, } from "../core/compiler.js";
11
+ export { BaseCompiler, WasmCompiler, CompilerRegistry, defaultCompilerRegistry, } from "../core/compiler.js";
12
+ /**
13
+ * Create a compiler registry with all available compilers
14
+ */
15
+ import { CompilerRegistry } from "../core/compiler.js";
16
+ /**
17
+ * Create a compiler registry pre-populated with all available compilers
18
+ */
19
+ export declare function createCompilerRegistry(): CompilerRegistry;
20
+ /**
21
+ * Default compiler registry with all language support
22
+ */
23
+ export declare const compilers: CompilerRegistry;
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compilers/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,KAAK,sBAAsB,GAC5B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,OAAO,EAAE,gBAAgB,EAA2B,MAAM,qBAAqB,CAAC;AAKhF;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAazD;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,kBAA2B,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Language Compilers
3
+ *
4
+ * Export all available compilers for the sandbox.
5
+ * Each compiler transforms source code to WASM format.
6
+ */
7
+ // Python compiler
8
+ export { PythonCompiler, createPythonCompiler, pythonCompiler, } from "./python.js";
9
+ // JavaScript compiler
10
+ export { JavaScriptCompiler, javascriptCompiler, } from "./javascript.js";
11
+ // TypeScript compiler
12
+ export { TypeScriptCompiler, typescriptCompiler, } from "./typescript.js";
13
+ export { BaseCompiler, WasmCompiler, CompilerRegistry, defaultCompilerRegistry, } from "../core/compiler.js";
14
+ /**
15
+ * Create a compiler registry with all available compilers
16
+ */
17
+ import { CompilerRegistry, defaultCompilerRegistry } from "../core/compiler.js";
18
+ import { PythonCompiler } from "./python.js";
19
+ import { JavaScriptCompiler } from "./javascript.js";
20
+ import { TypeScriptCompiler } from "./typescript.js";
21
+ /**
22
+ * Create a compiler registry pre-populated with all available compilers
23
+ */
24
+ export function createCompilerRegistry() {
25
+ const registry = new CompilerRegistry();
26
+ // Register Python compiler
27
+ registry.register(new PythonCompiler());
28
+ // Register JavaScript compiler
29
+ registry.register(new JavaScriptCompiler());
30
+ // Register TypeScript compiler
31
+ registry.register(new TypeScriptCompiler());
32
+ return registry;
33
+ }
34
+ /**
35
+ * Default compiler registry with all language support
36
+ */
37
+ export const compilers = createCompilerRegistry();
38
+ // Register all compilers with the default registry
39
+ defaultCompilerRegistry.register(new PythonCompiler());
40
+ defaultCompilerRegistry.register(new JavaScriptCompiler());
41
+ defaultCompilerRegistry.register(new TypeScriptCompiler());
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/compilers/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,kBAAkB;AAClB,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,cAAc,GAEf,MAAM,aAAa,CAAC;AAErB,sBAAsB;AACtB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GAEnB,MAAM,iBAAiB,CAAC;AAEzB,sBAAsB;AACtB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GAEnB,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD;;GAEG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,QAAQ,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAExC,2BAA2B;IAC3B,QAAQ,CAAC,QAAQ,CAAC,IAAI,cAAc,EAAE,CAAC,CAAC;IAExC,+BAA+B;IAC/B,QAAQ,CAAC,QAAQ,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAC;IAE5C,+BAA+B;IAC/B,QAAQ,CAAC,QAAQ,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAC;IAE5C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,sBAAsB,EAAE,CAAC;AAElD,mDAAmD;AACnD,uBAAuB,CAAC,QAAQ,CAAC,IAAI,cAAc,EAAE,CAAC,CAAC;AACvD,uBAAuB,CAAC,QAAQ,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAC;AAC3D,uBAAuB,CAAC,QAAQ,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAC"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * JavaScript Compiler for @ebowwa/sandbox
3
+ *
4
+ * Compiles JavaScript to WASM or provides sandboxed execution.
5
+ * Uses AssemblyScript for strict JS/TS-to-WASM compilation when possible,
6
+ * falls back to sandboxed QuickJS or native execution for dynamic JS.
7
+ */
8
+ import { BaseCompiler, type CompileResult, type CompilerOptions, type LanguageCapabilities } from "../core/compiler.js";
9
+ import type { Permissions, Limits } from "../core/types.js";
10
+ /** JavaScript compiler options */
11
+ export interface JavaScriptCompilerOptions extends CompilerOptions {
12
+ /** Target ES version */
13
+ target?: "es2015" | "es2016" | "es2017" | "es2018" | "es2019" | "es2020" | "es2021" | "es2022" | "esnext";
14
+ /** Module format */
15
+ module?: "esm" | "cjs" | "iife";
16
+ /** Enable strict mode */
17
+ strict?: boolean;
18
+ /** Use AssemblyScript for compilation (requires strict typing) */
19
+ useAssemblyScript?: boolean;
20
+ /** Sandbox mode when not using WASM */
21
+ sandboxMode?: "quickjs" | "isolated-vm" | "vm" | "none";
22
+ }
23
+ /**
24
+ * JavaScript Compiler
25
+ *
26
+ * Provides JavaScript execution in a sandboxed environment.
27
+ * For true WASM compilation, AssemblyScript is used but requires
28
+ * strict typing with WebAssembly types (i32, i64, f32, f64).
29
+ */
30
+ export declare class JavaScriptCompiler extends BaseCompiler {
31
+ readonly language: "javascript";
32
+ private assemblyScriptAvailable;
33
+ private esbuildAvailable;
34
+ /**
35
+ * Check if AssemblyScript is available for WASM compilation
36
+ */
37
+ isAvailable(): Promise<boolean>;
38
+ /**
39
+ * Validate JavaScript syntax
40
+ */
41
+ validate(source: string): Promise<{
42
+ valid: boolean;
43
+ error?: string;
44
+ }>;
45
+ /**
46
+ * Compile JavaScript to WASM or prepare for sandboxed execution
47
+ *
48
+ * For dynamic JavaScript (with closures, objects, etc.), we create a WASM
49
+ * wrapper that includes a minimal JS runtime or use sandboxed execution.
50
+ */
51
+ compile(source: string, permissions: Permissions, limits: Limits, options?: JavaScriptCompilerOptions): Promise<CompileResult>;
52
+ /**
53
+ * Get language capabilities
54
+ */
55
+ getCapabilities(): LanguageCapabilities;
56
+ /**
57
+ * Compile with AssemblyScript
58
+ *
59
+ * Note: AssemblyScript requires strict typing with WASM types.
60
+ * Standard JavaScript with dynamic features won't compile.
61
+ */
62
+ private compileWithAssemblyScript;
63
+ /**
64
+ * Create a sandboxed execution wrapper
65
+ *
66
+ * Instead of compiling to WASM, we create a WASM module that
67
+ * provides a sandboxed JavaScript execution environment.
68
+ * For simplicity, we use a minimal wrapper that can be executed
69
+ * by a JavaScript runtime.
70
+ */
71
+ private createSandboxedWrapper;
72
+ /**
73
+ * Create a WASM wrapper for sandboxed JavaScript execution
74
+ *
75
+ * This creates a WASM module that:
76
+ * 1. Contains the JavaScript source code as data
77
+ * 2. Exports functions for the runtime to execute
78
+ * 3. Provides memory for execution results
79
+ */
80
+ private createSandboxWasmWrapper;
81
+ /**
82
+ * Build the sandbox WASM module
83
+ *
84
+ * Creates a minimal WASM binary that contains:
85
+ * - Data section with JS source
86
+ * - Exported functions for runtime interaction
87
+ */
88
+ private buildSandboxWasm;
89
+ private buildTypeSection;
90
+ private buildFunctionSection;
91
+ private buildMemorySection;
92
+ private buildExportSection;
93
+ private buildCodeSection;
94
+ private buildDataSection;
95
+ private encodeLEB128;
96
+ /**
97
+ * Wrap JavaScript source for AssemblyScript compilation
98
+ *
99
+ * AssemblyScript requires explicit types and specific syntax.
100
+ * This wrapper attempts to make standard JS compatible.
101
+ */
102
+ private wrapForAssemblyScript;
103
+ /**
104
+ * Get esbuild instance for transpilation
105
+ */
106
+ private getEsbuild;
107
+ /**
108
+ * Parse memory string to bytes
109
+ */
110
+ private parseMemory;
111
+ /**
112
+ * Parse time string to milliseconds
113
+ */
114
+ private parseTime;
115
+ }
116
+ export declare const javascriptCompiler: JavaScriptCompiler;
117
+ //# sourceMappingURL=javascript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"javascript.d.ts","sourceRoot":"","sources":["../../src/compilers/javascript.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE5D,kCAAkC;AAClC,MAAM,WAAW,yBAA0B,SAAQ,eAAe;IAChE,wBAAwB;IACxB,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1G,oBAAoB;IACpB,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAChC,yBAAyB;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uCAAuC;IACvC,WAAW,CAAC,EAAE,SAAS,GAAG,aAAa,GAAG,IAAI,GAAG,MAAM,CAAC;CACzD;AAcD;;;;;;GAMG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,QAAQ,CAAC,QAAQ,EAAG,YAAY,CAAU;IAE1C,OAAO,CAAC,uBAAuB,CAAwB;IACvD,OAAO,CAAC,gBAAgB,CAAwB;IAEhD;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAerC;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAwB3E;;;;;OAKG;IACG,OAAO,CACX,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC,aAAa,CAAC;IAmBzB;;OAEG;IACH,eAAe,IAAI,oBAAoB;IAWvC;;;;;OAKG;YACW,yBAAyB;IAqEvC;;;;;;;OAOG;YACW,sBAAsB;IA0BpC;;;;;;;OAOG;YACW,wBAAwB;IAiDtC;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAoDxB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,gBAAgB;IAsBxB,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,YAAY;IAgBpB;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;OAEG;YACW,UAAU;IAexB;;OAEG;IACH,OAAO,CAAC,WAAW;IAanB;;OAEG;IACH,OAAO,CAAC,SAAS;CAYlB;AAGD,eAAO,MAAM,kBAAkB,oBAA2B,CAAC"}
@@ -0,0 +1,462 @@
1
+ /**
2
+ * JavaScript Compiler for @ebowwa/sandbox
3
+ *
4
+ * Compiles JavaScript to WASM or provides sandboxed execution.
5
+ * Uses AssemblyScript for strict JS/TS-to-WASM compilation when possible,
6
+ * falls back to sandboxed QuickJS or native execution for dynamic JS.
7
+ */
8
+ import { BaseCompiler, } from "../core/compiler.js";
9
+ /**
10
+ * JavaScript Compiler
11
+ *
12
+ * Provides JavaScript execution in a sandboxed environment.
13
+ * For true WASM compilation, AssemblyScript is used but requires
14
+ * strict typing with WebAssembly types (i32, i64, f32, f64).
15
+ */
16
+ export class JavaScriptCompiler extends BaseCompiler {
17
+ language = "javascript";
18
+ assemblyScriptAvailable = null;
19
+ esbuildAvailable = null;
20
+ /**
21
+ * Check if AssemblyScript is available for WASM compilation
22
+ */
23
+ async isAvailable() {
24
+ if (this.assemblyScriptAvailable !== null) {
25
+ return this.assemblyScriptAvailable;
26
+ }
27
+ try {
28
+ await import("assemblyscript");
29
+ this.assemblyScriptAvailable = true;
30
+ return true;
31
+ }
32
+ catch {
33
+ this.assemblyScriptAvailable = false;
34
+ return false;
35
+ }
36
+ }
37
+ /**
38
+ * Validate JavaScript syntax
39
+ */
40
+ async validate(source) {
41
+ try {
42
+ // Use esbuild for syntax validation if available
43
+ const esbuild = await this.getEsbuild();
44
+ if (esbuild) {
45
+ await esbuild.transform(source, {
46
+ loader: "js",
47
+ target: "es2020",
48
+ });
49
+ return { valid: true };
50
+ }
51
+ // Fallback: use Function constructor for basic syntax check
52
+ // This doesn't execute the code, just parses it
53
+ new Function(source);
54
+ return { valid: true };
55
+ }
56
+ catch (error) {
57
+ return {
58
+ valid: false,
59
+ error: error instanceof Error ? error.message : String(error),
60
+ };
61
+ }
62
+ }
63
+ /**
64
+ * Compile JavaScript to WASM or prepare for sandboxed execution
65
+ *
66
+ * For dynamic JavaScript (with closures, objects, etc.), we create a WASM
67
+ * wrapper that includes a minimal JS runtime or use sandboxed execution.
68
+ */
69
+ async compile(source, permissions, limits, options) {
70
+ const opts = {
71
+ target: "es2020",
72
+ module: "esm",
73
+ strict: true,
74
+ useAssemblyScript: false, // Default to sandboxed execution
75
+ sandboxMode: "vm",
76
+ ...options,
77
+ };
78
+ // Try AssemblyScript compilation if explicitly requested and available
79
+ if (opts.useAssemblyScript && (await this.isAvailable())) {
80
+ return this.compileWithAssemblyScript(source, permissions, limits, opts);
81
+ }
82
+ // For standard JavaScript, create a sandboxed execution wrapper
83
+ return this.createSandboxedWrapper(source, permissions, limits, opts);
84
+ }
85
+ /**
86
+ * Get language capabilities
87
+ */
88
+ getCapabilities() {
89
+ return {
90
+ repl: true,
91
+ stateful: true,
92
+ compiled: false, // JS is interpreted, not compiled to WASM
93
+ gc: true, // JavaScript has garbage collection
94
+ imports: true,
95
+ async: true,
96
+ };
97
+ }
98
+ /**
99
+ * Compile with AssemblyScript
100
+ *
101
+ * Note: AssemblyScript requires strict typing with WASM types.
102
+ * Standard JavaScript with dynamic features won't compile.
103
+ */
104
+ async compileWithAssemblyScript(source, _permissions, _limits, _options) {
105
+ try {
106
+ const asc = (await import("assemblyscript"));
107
+ // Wrap user code in a module structure
108
+ const assemblyScriptSource = this.wrapForAssemblyScript(source);
109
+ return new Promise((resolve, reject) => {
110
+ asc.main([
111
+ "--textFile", "/dev/stdout",
112
+ "--outFile", "/dev/stdout",
113
+ "--optimize",
114
+ "--target", "release",
115
+ ], {
116
+ stdin: () => assemblyScriptSource,
117
+ listBuiltins: () => asc.builtins,
118
+ reportDiagnostic: (diagnostic) => {
119
+ console.error(diagnostic.messageText);
120
+ },
121
+ }, (error, result) => {
122
+ if (error) {
123
+ reject(new Error(`AssemblyScript compilation failed: ${error.message}`));
124
+ return;
125
+ }
126
+ if (!result?.stdout) {
127
+ reject(new Error("AssemblyScript produced no output"));
128
+ return;
129
+ }
130
+ // Parse the WASM module to extract exports/imports
131
+ WebAssembly.compile(result.stdout)
132
+ .then((module) => {
133
+ const exports = WebAssembly.Module.exports(module).map((e) => e.name);
134
+ const imports = WebAssembly.Module.imports(module).map((i) => ({
135
+ module: i.module,
136
+ name: i.name,
137
+ type: i.kind,
138
+ }));
139
+ resolve({
140
+ wasmBytes: result.stdout,
141
+ exports,
142
+ imports,
143
+ memoryRequirements: {
144
+ initial: 1,
145
+ maximum: 256, // 16MB max
146
+ },
147
+ });
148
+ })
149
+ .catch(reject);
150
+ });
151
+ });
152
+ }
153
+ catch (error) {
154
+ throw new Error(`AssemblyScript compilation failed: ${error instanceof Error ? error.message : String(error)}`);
155
+ }
156
+ }
157
+ /**
158
+ * Create a sandboxed execution wrapper
159
+ *
160
+ * Instead of compiling to WASM, we create a WASM module that
161
+ * provides a sandboxed JavaScript execution environment.
162
+ * For simplicity, we use a minimal wrapper that can be executed
163
+ * by a JavaScript runtime.
164
+ */
165
+ async createSandboxedWrapper(source, permissions, limits, options) {
166
+ // Transpile with esbuild if available
167
+ let processedSource = source;
168
+ const esbuild = await this.getEsbuild();
169
+ if (esbuild) {
170
+ const result = await esbuild.transform(source, {
171
+ loader: "js",
172
+ target: options.target || "es2020",
173
+ format: options.module === "cjs" ? "cjs" : "esm",
174
+ minify: options.optimize,
175
+ });
176
+ processedSource = result.code;
177
+ }
178
+ // Create a WASM wrapper that provides sandboxed execution
179
+ // This is a minimal WASM module that exports a function to get the JS source
180
+ // The actual execution happens in the JavaScript runtime
181
+ return this.createSandboxWasmWrapper(processedSource, permissions, limits);
182
+ }
183
+ /**
184
+ * Create a WASM wrapper for sandboxed JavaScript execution
185
+ *
186
+ * This creates a WASM module that:
187
+ * 1. Contains the JavaScript source code as data
188
+ * 2. Exports functions for the runtime to execute
189
+ * 3. Provides memory for execution results
190
+ */
191
+ async createSandboxWasmWrapper(source, permissions, limits) {
192
+ // Encode the source and configuration
193
+ const sourceBytes = new TextEncoder().encode(source);
194
+ const configBytes = new TextEncoder().encode(JSON.stringify({
195
+ permissions: {
196
+ fs: permissions.fs ? {
197
+ read: permissions.fs.read ?? false,
198
+ write: permissions.fs.write ?? false,
199
+ delete: permissions.fs.delete ?? false,
200
+ } : undefined,
201
+ network: permissions.network ? {
202
+ outbound: permissions.network.outbound ?? false,
203
+ inbound: permissions.network.inbound ?? false,
204
+ } : undefined,
205
+ },
206
+ limits: {
207
+ timeout: typeof limits.timeout === "string"
208
+ ? this.parseTime(limits.timeout)
209
+ : limits.timeout ?? 30000,
210
+ memory: typeof limits.memory === "string"
211
+ ? this.parseMemory(limits.memory)
212
+ : limits.memory ?? 16 * 1024 * 1024,
213
+ },
214
+ }));
215
+ // Create a minimal WASM module that holds the JavaScript source
216
+ // This module exports functions to access the source and config
217
+ const wasmBytes = this.buildSandboxWasm(sourceBytes, configBytes);
218
+ return {
219
+ wasmBytes,
220
+ exports: ["getSource", "getConfig", "execute", "getResult"],
221
+ imports: [
222
+ { module: "env", name: "log", type: "function" },
223
+ { module: "env", name: "abort", type: "function" },
224
+ ],
225
+ memoryRequirements: {
226
+ initial: Math.max(1, Math.ceil((sourceBytes.length + configBytes.length) / 65536)),
227
+ maximum: 256,
228
+ },
229
+ };
230
+ }
231
+ /**
232
+ * Build the sandbox WASM module
233
+ *
234
+ * Creates a minimal WASM binary that contains:
235
+ * - Data section with JS source
236
+ * - Exported functions for runtime interaction
237
+ */
238
+ buildSandboxWasm(sourceBytes, configBytes) {
239
+ // WASM module structure:
240
+ // - Magic number + version
241
+ // - Type section (function signatures)
242
+ // - Function section
243
+ // - Memory section
244
+ // - Export section
245
+ // - Code section
246
+ // - Data section (JS source and config)
247
+ const magicNumber = new Uint8Array([0x00, 0x61, 0x73, 0x6D]); // \0asm
248
+ const version = new Uint8Array([0x01, 0x00, 0x00, 0x00]); // version 1
249
+ // Build sections
250
+ const typeSection = this.buildTypeSection();
251
+ const functionSection = this.buildFunctionSection();
252
+ const memorySection = this.buildMemorySection(sourceBytes.length + configBytes.length + 1024);
253
+ const exportSection = this.buildExportSection();
254
+ const codeSection = this.buildCodeSection();
255
+ const dataSection = this.buildDataSection(sourceBytes, configBytes);
256
+ // Combine all sections
257
+ const sections = [
258
+ typeSection,
259
+ functionSection,
260
+ memorySection,
261
+ exportSection,
262
+ codeSection,
263
+ dataSection,
264
+ ];
265
+ const totalLength = magicNumber.length + version.length +
266
+ sections.reduce((sum, s) => sum + s.length, 0);
267
+ const wasm = new Uint8Array(totalLength);
268
+ let offset = 0;
269
+ // Write header
270
+ wasm.set(magicNumber, offset);
271
+ offset += magicNumber.length;
272
+ wasm.set(version, offset);
273
+ offset += version.length;
274
+ // Write sections
275
+ for (const section of sections) {
276
+ wasm.set(section, offset);
277
+ offset += section.length;
278
+ }
279
+ return wasm;
280
+ }
281
+ buildTypeSection() {
282
+ // Section ID 1 (type), 1 type, function type () -> i32
283
+ return new Uint8Array([
284
+ 0x01, // section id
285
+ 0x04, // section size
286
+ 0x01, // num types
287
+ 0x60, // func type
288
+ 0x00, // 0 params
289
+ 0x01, 0x7F, // 1 result: i32
290
+ ]);
291
+ }
292
+ buildFunctionSection() {
293
+ // Section ID 3 (function), 4 functions
294
+ return new Uint8Array([
295
+ 0x03, // section id
296
+ 0x05, // section size
297
+ 0x04, // num functions
298
+ 0x00, 0x00, 0x00, 0x00, // function indices (all type 0)
299
+ ]);
300
+ }
301
+ buildMemorySection(dataSize) {
302
+ const pages = Math.max(1, Math.ceil(dataSize / 65536));
303
+ // Section ID 5 (memory), 1 memory, limits
304
+ return new Uint8Array([
305
+ 0x05, // section id
306
+ 0x03, // section size
307
+ 0x01, // num memories
308
+ 0x01, // has max
309
+ pages, // initial pages
310
+ 0x80, 0x02, // max pages (256)
311
+ ]);
312
+ }
313
+ buildExportSection() {
314
+ // Section ID 7 (export)
315
+ // Export: memory, getSource, getConfig, execute, getResult
316
+ const exports = [
317
+ { name: "memory", kind: 0x02, index: 0 }, // memory
318
+ { name: "getSource", kind: 0x00, index: 0 }, // func 0
319
+ { name: "getConfig", kind: 0x00, index: 1 }, // func 1
320
+ { name: "execute", kind: 0x00, index: 2 }, // func 2
321
+ { name: "getResult", kind: 0x00, index: 3 }, // func 3
322
+ ];
323
+ const nameBytes = [];
324
+ for (const exp of exports) {
325
+ const nameEncoded = new TextEncoder().encode(exp.name);
326
+ nameBytes.push(nameEncoded.length);
327
+ nameBytes.push(...nameEncoded);
328
+ nameBytes.push(exp.kind);
329
+ nameBytes.push(exp.index);
330
+ }
331
+ const sectionContent = [exports.length, ...nameBytes];
332
+ const sectionSize = sectionContent.length;
333
+ return new Uint8Array([0x07, sectionSize, ...sectionContent]);
334
+ }
335
+ buildCodeSection() {
336
+ // Section ID 10 (code)
337
+ // 4 function bodies, each returning a constant
338
+ const functions = [
339
+ [0x00, 0x41, 0x00, 0x0B], // getSource: return 0 (offset)
340
+ [0x00, 0x41, 0x00, 0x0B], // getConfig: return 0 (placeholder)
341
+ [0x00, 0x41, 0x00, 0x0B], // execute: return 0 (placeholder)
342
+ [0x00, 0x41, 0x00, 0x0B], // getResult: return 0 (placeholder)
343
+ ];
344
+ const bodies = [];
345
+ for (const body of functions) {
346
+ bodies.push(body.length);
347
+ bodies.push(...body);
348
+ }
349
+ const sectionContent = [functions.length, ...bodies];
350
+ const sectionSize = sectionContent.length;
351
+ return new Uint8Array([0x0A, sectionSize, ...sectionContent]);
352
+ }
353
+ buildDataSection(sourceBytes, configBytes) {
354
+ // Section ID 11 (data)
355
+ // 2 data segments: source and config
356
+ const sourceLen = this.encodeLEB128(sourceBytes.length);
357
+ const configLen = this.encodeLEB128(configBytes.length);
358
+ const segment1 = [
359
+ 0x00, // active, memory 0
360
+ 0x41, 0x00, 0x23, 0x00, // i32.const 0 (offset placeholder)
361
+ ...sourceLen,
362
+ ...sourceBytes,
363
+ ];
364
+ const segment2 = [
365
+ 0x00, // active, memory 0
366
+ 0x41, 0x00, 0x23, 0x00, // i32.const 0 (offset placeholder)
367
+ ...configLen,
368
+ ...configBytes,
369
+ ];
370
+ const sectionContent = [
371
+ 0x02, // 2 data segments
372
+ ...segment1,
373
+ ...segment2,
374
+ ];
375
+ const sectionSize = sectionContent.length;
376
+ return new Uint8Array([0x0B, sectionSize, ...sectionContent]);
377
+ }
378
+ encodeLEB128(value) {
379
+ const result = [];
380
+ let remaining = value;
381
+ do {
382
+ let byte = remaining & 0x7F;
383
+ remaining >>>= 7;
384
+ if (remaining !== 0) {
385
+ byte |= 0x80;
386
+ }
387
+ result.push(byte);
388
+ } while (remaining !== 0);
389
+ return result;
390
+ }
391
+ /**
392
+ * Wrap JavaScript source for AssemblyScript compilation
393
+ *
394
+ * AssemblyScript requires explicit types and specific syntax.
395
+ * This wrapper attempts to make standard JS compatible.
396
+ */
397
+ wrapForAssemblyScript(source) {
398
+ return `
399
+ // AssemblyScript wrapper
400
+ // Note: AssemblyScript requires strict typing with i32, i64, f32, f64
401
+
402
+ ${source}
403
+
404
+ // Export a main function if not present
405
+ export function _start(): void {
406
+ // Entry point
407
+ }
408
+ `;
409
+ }
410
+ /**
411
+ * Get esbuild instance for transpilation
412
+ */
413
+ async getEsbuild() {
414
+ if (this.esbuildAvailable === false) {
415
+ return null;
416
+ }
417
+ try {
418
+ const esbuild = await import("esbuild");
419
+ this.esbuildAvailable = true;
420
+ return esbuild;
421
+ }
422
+ catch {
423
+ this.esbuildAvailable = false;
424
+ return null;
425
+ }
426
+ }
427
+ /**
428
+ * Parse memory string to bytes
429
+ */
430
+ parseMemory(mem) {
431
+ const match = mem.match(/^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)?$/i);
432
+ if (!match)
433
+ return 16 * 1024 * 1024;
434
+ const [, num, unit] = match;
435
+ const multipliers = {
436
+ b: 1,
437
+ kb: 1024,
438
+ mb: 1024 ** 2,
439
+ gb: 1024 ** 3,
440
+ };
441
+ return Math.floor(parseFloat(num) * (multipliers[unit?.toLowerCase() ?? "b"] ?? 1));
442
+ }
443
+ /**
444
+ * Parse time string to milliseconds
445
+ */
446
+ parseTime(time) {
447
+ const match = time.match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/i);
448
+ if (!match)
449
+ return 30000;
450
+ const [, num, unit] = match;
451
+ const multipliers = {
452
+ ms: 1,
453
+ s: 1000,
454
+ m: 60000,
455
+ h: 3600000,
456
+ };
457
+ return Math.floor(parseFloat(num) * (multipliers[unit?.toLowerCase() ?? "ms"] ?? 1));
458
+ }
459
+ }
460
+ // Default instance
461
+ export const javascriptCompiler = new JavaScriptCompiler();
462
+ //# sourceMappingURL=javascript.js.map