@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.
- package/dist/compilers/index.d.ts +24 -0
- package/dist/compilers/index.d.ts.map +1 -0
- package/dist/compilers/index.js +42 -0
- package/dist/compilers/index.js.map +1 -0
- package/dist/compilers/javascript.d.ts +117 -0
- package/dist/compilers/javascript.d.ts.map +1 -0
- package/dist/compilers/javascript.js +462 -0
- package/dist/compilers/javascript.js.map +1 -0
- package/dist/compilers/python.d.ts +140 -0
- package/dist/compilers/python.d.ts.map +1 -0
- package/dist/compilers/python.js +650 -0
- package/dist/compilers/python.js.map +1 -0
- package/dist/compilers/typescript.d.ts +99 -0
- package/dist/compilers/typescript.d.ts.map +1 -0
- package/dist/compilers/typescript.js +323 -0
- package/dist/compilers/typescript.js.map +1 -0
- package/dist/core/cell.d.ts +160 -0
- package/dist/core/cell.d.ts.map +1 -0
- package/dist/core/cell.js +319 -0
- package/dist/core/cell.js.map +1 -0
- package/dist/core/compiler.d.ts +126 -0
- package/dist/core/compiler.d.ts.map +1 -0
- package/dist/core/compiler.js +123 -0
- package/dist/core/compiler.js.map +1 -0
- package/dist/core/index.d.ts +19 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +14 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/limits.d.ts +173 -0
- package/dist/core/limits.d.ts.map +1 -0
- package/dist/core/limits.js +440 -0
- package/dist/core/limits.js.map +1 -0
- package/dist/core/permissions.d.ts +103 -0
- package/dist/core/permissions.d.ts.map +1 -0
- package/dist/core/permissions.js +341 -0
- package/dist/core/permissions.js.map +1 -0
- package/dist/core/runtime.d.ts +127 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +325 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/types.d.ts +380 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +67 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +145 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +279 -0
- package/dist/index.js.map +1 -0
- package/dist/multi/index.d.ts +9 -0
- package/dist/multi/index.d.ts.map +1 -0
- package/dist/multi/index.js +7 -0
- package/dist/multi/index.js.map +1 -0
- package/dist/multi/polyglot.d.ts +179 -0
- package/dist/multi/polyglot.d.ts.map +1 -0
- package/dist/multi/polyglot.js +319 -0
- package/dist/multi/polyglot.js.map +1 -0
- package/dist/runtimes/docker.d.ts +97 -0
- package/dist/runtimes/docker.d.ts.map +1 -0
- package/dist/runtimes/docker.js +368 -0
- package/dist/runtimes/docker.js.map +1 -0
- package/dist/runtimes/index.d.ts +11 -0
- package/dist/runtimes/index.d.ts.map +1 -0
- package/dist/runtimes/index.js +9 -0
- package/dist/runtimes/index.js.map +1 -0
- package/dist/runtimes/process.d.ts +47 -0
- package/dist/runtimes/process.d.ts.map +1 -0
- package/dist/runtimes/process.js +230 -0
- package/dist/runtimes/process.js.map +1 -0
- package/dist/session/index.d.ts +12 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +9 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/kernel.d.ts +199 -0
- package/dist/session/kernel.d.ts.map +1 -0
- package/dist/session/kernel.js +400 -0
- package/dist/session/kernel.js.map +1 -0
- package/dist/session/notebook.d.ts +168 -0
- package/dist/session/notebook.d.ts.map +1 -0
- package/dist/session/notebook.js +499 -0
- package/dist/session/notebook.js.map +1 -0
- package/dist/session/repl.d.ts +159 -0
- package/dist/session/repl.d.ts.map +1 -0
- package/dist/session/repl.js +409 -0
- package/dist/session/repl.js.map +1 -0
- package/package.json +142 -0
- package/src/compilers/index.ts +80 -0
- package/src/compilers/javascript.ts +571 -0
- package/src/compilers/python.ts +785 -0
- package/src/compilers/typescript.ts +442 -0
- package/src/core/cell.ts +439 -0
- package/src/core/compiler.ts +250 -0
- package/src/core/index.ts +123 -0
- package/src/core/limits.ts +508 -0
- package/src/core/permissions.ts +409 -0
- package/src/core/runtime.ts +499 -0
- package/src/core/types.ts +528 -0
- package/src/global.d.ts +59 -0
- package/src/index.ts +515 -0
- package/src/multi/index.ts +22 -0
- package/src/multi/polyglot.ts +461 -0
- package/src/runtimes/docker.ts +501 -0
- package/src/runtimes/index.ts +21 -0
- package/src/runtimes/process.ts +316 -0
- package/src/session/index.ts +41 -0
- package/src/session/kernel.ts +553 -0
- package/src/session/notebook.ts +635 -0
- package/src/session/repl.ts +521 -0
- package/src/wasm2wasm.d.ts +35 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript Compiler for @ebowwa/sandbox
|
|
3
|
+
*
|
|
4
|
+
* Compiles TypeScript to WASM via JavaScript.
|
|
5
|
+
* Uses esbuild for fast TypeScript transpilation, then delegates to JavaScript compiler.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
BaseCompiler,
|
|
10
|
+
type CompileResult,
|
|
11
|
+
type CompilerOptions,
|
|
12
|
+
type LanguageCapabilities,
|
|
13
|
+
} from "../core/compiler.js";
|
|
14
|
+
import type { Permissions, Limits } from "../core/types.js";
|
|
15
|
+
import { JavaScriptCompiler, type JavaScriptCompilerOptions } from "./javascript.js";
|
|
16
|
+
|
|
17
|
+
/** TypeScript compiler options */
|
|
18
|
+
export interface TypeScriptCompilerOptions extends CompilerOptions {
|
|
19
|
+
/** TypeScript target */
|
|
20
|
+
target?: "es2015" | "es2016" | "es2017" | "es2018" | "es2019" | "es2020" | "es2021" | "es2022" | "esnext";
|
|
21
|
+
/** Module format */
|
|
22
|
+
module?: "esm" | "cjs" | "iife";
|
|
23
|
+
/** Enable strict type checking */
|
|
24
|
+
strict?: boolean;
|
|
25
|
+
/** Emit declaration files */
|
|
26
|
+
declaration?: boolean;
|
|
27
|
+
/** Source map generation */
|
|
28
|
+
sourceMap?: boolean;
|
|
29
|
+
/** JSX transform */
|
|
30
|
+
jsx?: "transform" | "preserve" | "automatic";
|
|
31
|
+
/** JSX factory */
|
|
32
|
+
jsxFactory?: string;
|
|
33
|
+
/** JSX fragment factory */
|
|
34
|
+
jsxFragment?: string;
|
|
35
|
+
/** Use AssemblyScript for compilation */
|
|
36
|
+
useAssemblyScript?: boolean;
|
|
37
|
+
/** Transpiler to use */
|
|
38
|
+
transpiler?: "esbuild" | "swc" | "tsc";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Transpilation result */
|
|
42
|
+
interface TranspileResult {
|
|
43
|
+
code: string;
|
|
44
|
+
map?: string;
|
|
45
|
+
declarations?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Dynamic import type for esbuild (optional dependency)
|
|
49
|
+
type EsbuildModule = {
|
|
50
|
+
transform: (input: string, options?: Record<string, unknown>) => Promise<{ code: string; map?: string }>;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Dynamic import type for SWC (optional dependency)
|
|
54
|
+
type SwcModule = {
|
|
55
|
+
transform: (code: string, options?: Record<string, unknown>) => Promise<{ code: string; map?: string }>;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* TypeScript Compiler
|
|
60
|
+
*
|
|
61
|
+
* Transpiles TypeScript to JavaScript, then compiles to WASM.
|
|
62
|
+
* Supports both standard TypeScript and AssemblyScript syntax.
|
|
63
|
+
*/
|
|
64
|
+
export class TypeScriptCompiler extends BaseCompiler {
|
|
65
|
+
readonly language = "typescript" as const;
|
|
66
|
+
|
|
67
|
+
private jsCompiler: JavaScriptCompiler;
|
|
68
|
+
private esbuildAvailable: boolean | null = null;
|
|
69
|
+
private swcAvailable: boolean | null = null;
|
|
70
|
+
|
|
71
|
+
constructor() {
|
|
72
|
+
super();
|
|
73
|
+
this.jsCompiler = new JavaScriptCompiler();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Check if TypeScript compiler is available
|
|
78
|
+
*/
|
|
79
|
+
async isAvailable(): Promise<boolean> {
|
|
80
|
+
// TypeScript compiler is always available (we have built-in support)
|
|
81
|
+
// But transpilers may vary
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Validate TypeScript syntax
|
|
87
|
+
*/
|
|
88
|
+
async validate(source: string): Promise<{ valid: boolean; error?: string }> {
|
|
89
|
+
try {
|
|
90
|
+
const transpiler = await this.getTranspiler("esbuild");
|
|
91
|
+
|
|
92
|
+
if (transpiler?.type === "esbuild") {
|
|
93
|
+
await transpiler.module.transform(source, {
|
|
94
|
+
loader: "ts",
|
|
95
|
+
target: "es2020",
|
|
96
|
+
tsconfigRaw: {
|
|
97
|
+
compilerOptions: {
|
|
98
|
+
strict: true,
|
|
99
|
+
noEmit: true,
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
return { valid: true };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Fallback: basic regex check for common syntax errors
|
|
107
|
+
const syntaxErrors = this.checkBasicSyntax(source);
|
|
108
|
+
if (syntaxErrors) {
|
|
109
|
+
return { valid: false, error: syntaxErrors };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return { valid: true };
|
|
113
|
+
} catch (error) {
|
|
114
|
+
return {
|
|
115
|
+
valid: false,
|
|
116
|
+
error: error instanceof Error ? error.message : String(error),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Compile TypeScript to WASM
|
|
123
|
+
*
|
|
124
|
+
* 1. Transpile TypeScript to JavaScript
|
|
125
|
+
* 2. Use JavaScript compiler for WASM compilation
|
|
126
|
+
*/
|
|
127
|
+
async compile(
|
|
128
|
+
source: string,
|
|
129
|
+
permissions: Permissions,
|
|
130
|
+
limits: Limits,
|
|
131
|
+
options?: TypeScriptCompilerOptions
|
|
132
|
+
): Promise<CompileResult> {
|
|
133
|
+
const opts: TypeScriptCompilerOptions = {
|
|
134
|
+
target: "es2020",
|
|
135
|
+
module: "esm",
|
|
136
|
+
strict: true,
|
|
137
|
+
declaration: false,
|
|
138
|
+
sourceMap: options?.sourceMap ?? false,
|
|
139
|
+
jsx: "transform",
|
|
140
|
+
jsxFactory: "React.createElement",
|
|
141
|
+
jsxFragment: "React.Fragment",
|
|
142
|
+
useAssemblyScript: false,
|
|
143
|
+
transpiler: "esbuild",
|
|
144
|
+
...options,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// Check if source uses AssemblyScript types
|
|
148
|
+
const isAssemblyScript = this.detectAssemblyScript(source);
|
|
149
|
+
const effectiveUseAssemblyScript = opts.useAssemblyScript || isAssemblyScript;
|
|
150
|
+
|
|
151
|
+
// Transpile TypeScript to JavaScript
|
|
152
|
+
const transpiled = await this.transpile(source, {
|
|
153
|
+
...opts,
|
|
154
|
+
useAssemblyScript: effectiveUseAssemblyScript,
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Delegate to JavaScript compiler
|
|
158
|
+
const jsOptions: JavaScriptCompilerOptions = {
|
|
159
|
+
target: opts.target,
|
|
160
|
+
module: opts.module,
|
|
161
|
+
strict: opts.strict,
|
|
162
|
+
useAssemblyScript: effectiveUseAssemblyScript,
|
|
163
|
+
optimize: opts.optimize,
|
|
164
|
+
debug: opts.debug,
|
|
165
|
+
sourceMap: opts.sourceMap,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const result = await this.jsCompiler.compile(
|
|
169
|
+
transpiled.code,
|
|
170
|
+
permissions,
|
|
171
|
+
limits,
|
|
172
|
+
jsOptions
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
// Include source map if generated
|
|
176
|
+
if (transpiled.map) {
|
|
177
|
+
result.sourceMap = transpiled.map;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Get language capabilities
|
|
185
|
+
*/
|
|
186
|
+
getCapabilities(): LanguageCapabilities {
|
|
187
|
+
return {
|
|
188
|
+
repl: true,
|
|
189
|
+
stateful: true,
|
|
190
|
+
compiled: false, // TS transpiles to JS, which is interpreted
|
|
191
|
+
gc: true, // JavaScript has garbage collection
|
|
192
|
+
imports: true,
|
|
193
|
+
async: true,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Transpile TypeScript to JavaScript
|
|
199
|
+
*/
|
|
200
|
+
private async transpile(
|
|
201
|
+
source: string,
|
|
202
|
+
options: TypeScriptCompilerOptions
|
|
203
|
+
): Promise<TranspileResult> {
|
|
204
|
+
// If using AssemblyScript, don't transpile types
|
|
205
|
+
if (options.useAssemblyScript) {
|
|
206
|
+
return {
|
|
207
|
+
code: source,
|
|
208
|
+
map: undefined,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const transpiler = await this.getTranspiler(options.transpiler || "esbuild");
|
|
213
|
+
|
|
214
|
+
if (transpiler?.type === "esbuild") {
|
|
215
|
+
return this.transpileWithEsbuild(source, options, transpiler.module);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (transpiler?.type === "swc") {
|
|
219
|
+
return this.transpileWithSwc(source, options, transpiler.module);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Fallback: strip types using regex (not recommended for production)
|
|
223
|
+
return this.transpileWithRegex(source);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Transpile using esbuild
|
|
228
|
+
*/
|
|
229
|
+
private async transpileWithEsbuild(
|
|
230
|
+
source: string,
|
|
231
|
+
options: TypeScriptCompilerOptions,
|
|
232
|
+
esbuild: EsbuildModule
|
|
233
|
+
): Promise<TranspileResult> {
|
|
234
|
+
const result = await esbuild.transform(source, {
|
|
235
|
+
loader: "ts",
|
|
236
|
+
target: options.target || "es2020",
|
|
237
|
+
format: options.module === "cjs" ? "cjs" : "esm",
|
|
238
|
+
minify: options.optimize,
|
|
239
|
+
sourcemap: options.sourceMap ? "external" : false,
|
|
240
|
+
jsx: options.jsx === "automatic" ? "automatic" : "transform",
|
|
241
|
+
jsxFactory: options.jsxFactory,
|
|
242
|
+
jsxFragment: options.jsxFragment,
|
|
243
|
+
tsconfigRaw: {
|
|
244
|
+
compilerOptions: {
|
|
245
|
+
strict: options.strict,
|
|
246
|
+
target: options.target,
|
|
247
|
+
module: options.module?.toUpperCase(),
|
|
248
|
+
esModuleInterop: true,
|
|
249
|
+
allowSyntheticDefaultImports: true,
|
|
250
|
+
resolveJsonModule: true,
|
|
251
|
+
declaration: options.declaration,
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
code: result.code,
|
|
258
|
+
map: result.map,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Transpile using SWC
|
|
264
|
+
*/
|
|
265
|
+
private async transpileWithSwc(
|
|
266
|
+
source: string,
|
|
267
|
+
options: TypeScriptCompilerOptions,
|
|
268
|
+
swc: SwcModule
|
|
269
|
+
): Promise<TranspileResult> {
|
|
270
|
+
const result = await swc.transform(source, {
|
|
271
|
+
jsc: {
|
|
272
|
+
parser: {
|
|
273
|
+
syntax: "typescript",
|
|
274
|
+
tsx: options.jsx !== "preserve",
|
|
275
|
+
},
|
|
276
|
+
transform: {
|
|
277
|
+
react: {
|
|
278
|
+
runtime: options.jsx === "automatic" ? "automatic" : "classic",
|
|
279
|
+
pragma: options.jsxFactory,
|
|
280
|
+
pragmaFrag: options.jsxFragment,
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
target: options.target?.replace("es", "es") || "es2020",
|
|
284
|
+
},
|
|
285
|
+
module: {
|
|
286
|
+
type: options.module === "cjs" ? "commonjs" : "es6",
|
|
287
|
+
},
|
|
288
|
+
minify: options.optimize,
|
|
289
|
+
sourceMaps: options.sourceMap,
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
return {
|
|
293
|
+
code: result.code,
|
|
294
|
+
map: result.map,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Fallback transpilation using regex (basic type stripping)
|
|
300
|
+
*
|
|
301
|
+
* Note: This is not a complete TypeScript implementation.
|
|
302
|
+
* Use esbuild or swc for production code.
|
|
303
|
+
*/
|
|
304
|
+
private transpileWithRegex(source: string): TranspileResult {
|
|
305
|
+
let code = source;
|
|
306
|
+
|
|
307
|
+
// Strip type annotations
|
|
308
|
+
// This is a simplified implementation
|
|
309
|
+
const patterns = [
|
|
310
|
+
// Remove type annotations: : Type
|
|
311
|
+
/:\s*[A-Z][a-zA-Z0-9_]*(?:<[^>]+>)?(?:\[\])?(?:\s*\|\s*[A-Z][a-zA-Z0-9_]*(?:<[^>]+>)?(?:\[\])?)*/g,
|
|
312
|
+
// Remove interface declarations
|
|
313
|
+
/interface\s+[A-Z][a-zA-Z0-9_]*\s*(?:<[^>]+>)?\s*\{[^}]*\}/g,
|
|
314
|
+
// Remove type declarations
|
|
315
|
+
/type\s+[A-Z][a-zA-Z0-9_]*\s*(?:<[^>]+>)?\s*=\s*[^;]+;/g,
|
|
316
|
+
// Remove enum declarations (convert to const objects)
|
|
317
|
+
/enum\s+([A-Z][a-zA-Z0-9_]*)\s*\{([^}]*)\}/g,
|
|
318
|
+
// Remove generic type parameters
|
|
319
|
+
/<[^>]+>/g,
|
|
320
|
+
// Remove 'as' type assertions
|
|
321
|
+
/\s+as\s+[A-Z][a-zA-Z0-9_]*(?:<[^>]+>)?/g,
|
|
322
|
+
// Remove 'satisfies' type assertions
|
|
323
|
+
/\s+satisfies\s+[A-Z][a-zA-Z0-9_]*(?:<[^>]+>)?/g,
|
|
324
|
+
// Remove 'declare' statements
|
|
325
|
+
/declare\s+(?:const|let|var|function|class|interface|type|enum)\s+[^;]+;/g,
|
|
326
|
+
// Remove 'public', 'private', 'protected', 'readonly' modifiers
|
|
327
|
+
/\b(?:public|private|protected|readonly)\s+/g,
|
|
328
|
+
// Remove 'abstract' modifier
|
|
329
|
+
/\babstract\s+/g,
|
|
330
|
+
// Remove parameter properties in constructors
|
|
331
|
+
/constructor\s*\(([^)]*)\)/g,
|
|
332
|
+
];
|
|
333
|
+
|
|
334
|
+
for (const pattern of patterns) {
|
|
335
|
+
code = code.replace(pattern, "");
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return {
|
|
339
|
+
code,
|
|
340
|
+
map: undefined,
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Get the best available transpiler
|
|
346
|
+
*/
|
|
347
|
+
private async getTranspiler(
|
|
348
|
+
preferred: "esbuild" | "swc" | "tsc"
|
|
349
|
+
): Promise<
|
|
350
|
+
| {
|
|
351
|
+
type: "esbuild";
|
|
352
|
+
module: EsbuildModule;
|
|
353
|
+
}
|
|
354
|
+
| {
|
|
355
|
+
type: "swc";
|
|
356
|
+
module: SwcModule;
|
|
357
|
+
}
|
|
358
|
+
| null
|
|
359
|
+
> {
|
|
360
|
+
if (preferred === "esbuild" || preferred === "tsc") {
|
|
361
|
+
if (this.esbuildAvailable === null) {
|
|
362
|
+
try {
|
|
363
|
+
await import("esbuild");
|
|
364
|
+
this.esbuildAvailable = true;
|
|
365
|
+
} catch {
|
|
366
|
+
this.esbuildAvailable = false;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (this.esbuildAvailable) {
|
|
371
|
+
const esbuild = await import("esbuild") as EsbuildModule;
|
|
372
|
+
return { type: "esbuild", module: esbuild };
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (preferred === "swc") {
|
|
377
|
+
if (this.swcAvailable === null) {
|
|
378
|
+
try {
|
|
379
|
+
await import("@swc/core");
|
|
380
|
+
this.swcAvailable = true;
|
|
381
|
+
} catch {
|
|
382
|
+
this.swcAvailable = false;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (this.swcAvailable) {
|
|
387
|
+
const swc = await import("@swc/core") as SwcModule;
|
|
388
|
+
return { type: "swc", module: swc };
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Fallback to esbuild if swc was preferred but not available
|
|
393
|
+
if (preferred === "swc" && this.esbuildAvailable !== false) {
|
|
394
|
+
return this.getTranspiler("esbuild");
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Detect if source uses AssemblyScript-specific types
|
|
402
|
+
*/
|
|
403
|
+
private detectAssemblyScript(source: string): boolean {
|
|
404
|
+
// AssemblyScript uses specific types: i8, i16, i32, i64, f32, f64, usize, etc.
|
|
405
|
+
const assemblyScriptTypes = /\b(i8|i16|i32|i64|f32|f64|usize|isize|bool)\b/;
|
|
406
|
+
return assemblyScriptTypes.test(source);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Basic syntax check for TypeScript
|
|
411
|
+
*/
|
|
412
|
+
private checkBasicSyntax(source: string): string | null {
|
|
413
|
+
// Check for common syntax errors
|
|
414
|
+
const errors: string[] = [];
|
|
415
|
+
|
|
416
|
+
// Check for unmatched braces
|
|
417
|
+
const openBraces = (source.match(/\{/g) || []).length;
|
|
418
|
+
const closeBraces = (source.match(/\}/g) || []).length;
|
|
419
|
+
if (openBraces !== closeBraces) {
|
|
420
|
+
errors.push(`Unmatched braces: ${openBraces} open, ${closeBraces} close`);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Check for unmatched parentheses
|
|
424
|
+
const openParens = (source.match(/\(/g) || []).length;
|
|
425
|
+
const closeParens = (source.match(/\)/g) || []).length;
|
|
426
|
+
if (openParens !== closeParens) {
|
|
427
|
+
errors.push(`Unmatched parentheses: ${openParens} open, ${closeParens} close`);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Check for unmatched brackets
|
|
431
|
+
const openBrackets = (source.match(/\[/g) || []).length;
|
|
432
|
+
const closeBrackets = (source.match(/\]/g) || []).length;
|
|
433
|
+
if (openBrackets !== closeBrackets) {
|
|
434
|
+
errors.push(`Unmatched brackets: ${openBrackets} open, ${closeBrackets} close`);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return errors.length > 0 ? errors.join("; ") : null;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Default instance
|
|
442
|
+
export const typescriptCompiler = new TypeScriptCompiler();
|