wasm-idle 1.0.7 → 1.0.9

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 (59) hide show
  1. package/README.md +48 -11
  2. package/dist/playground/applicationAssets.js +18 -0
  3. package/dist/playground/assetBridge.js +7 -0
  4. package/dist/playground/assets.d.ts +70 -0
  5. package/dist/playground/assets.js +120 -0
  6. package/dist/playground/cachedClang.js +43 -5
  7. package/dist/playground/clang.d.ts +5 -0
  8. package/dist/playground/clang.js +96 -0
  9. package/dist/playground/clangAssetIntegrity.d.ts +6 -0
  10. package/dist/playground/clangAssetIntegrity.js +3 -2
  11. package/dist/playground/clangWorkerProtocol.d.ts +12 -1
  12. package/dist/playground/fennel.d.ts +9 -0
  13. package/dist/playground/fennel.js +30 -0
  14. package/dist/playground/fennelBootstrap.d.ts +31 -0
  15. package/dist/playground/fennelBootstrap.js +118 -0
  16. package/dist/playground/grain.d.ts +9 -0
  17. package/dist/playground/grain.js +127 -0
  18. package/dist/playground/hy.d.ts +21 -0
  19. package/dist/playground/hy.js +24 -0
  20. package/dist/playground/index.d.ts +1 -1
  21. package/dist/playground/index.js +49 -0
  22. package/dist/playground/lua.d.ts +19 -0
  23. package/dist/playground/lua.js +64 -39
  24. package/dist/playground/objectivec.d.ts +3 -1
  25. package/dist/playground/objectivec.js +6 -2
  26. package/dist/playground/options.js +1 -1
  27. package/dist/playground/postgresql.d.ts +36 -0
  28. package/dist/playground/postgresql.js +543 -0
  29. package/dist/playground/python.d.ts +5 -0
  30. package/dist/playground/python.js +13 -0
  31. package/dist/playground/rescript.d.ts +5 -0
  32. package/dist/playground/rescript.js +58 -0
  33. package/dist/playground/rescriptPreflight.d.ts +26 -0
  34. package/dist/playground/rescriptPreflight.js +381 -0
  35. package/dist/playground/staticRuntimeModuleVersion.d.ts +1 -1
  36. package/dist/playground/staticRuntimeModuleVersion.js +1 -1
  37. package/dist/playground/staticRuntimePreflightExecute.d.ts +2 -1
  38. package/dist/playground/staticRuntimePreflightExecute.js +9 -0
  39. package/dist/playground/staticRuntimePreflightProtocol.d.ts +1 -1
  40. package/dist/playground/v.d.ts +46 -0
  41. package/dist/playground/v.js +703 -0
  42. package/dist/playground/wasmFennelVersion.d.ts +23 -0
  43. package/dist/playground/wasmFennelVersion.js +16 -0
  44. package/dist/playground/wasmGrainVersion.d.ts +24 -0
  45. package/dist/playground/wasmGrainVersion.js +25 -0
  46. package/dist/playground/wasmHyVersion.d.ts +7 -0
  47. package/dist/playground/wasmHyVersion.js +15 -0
  48. package/dist/playground/wasmReScriptVersion.d.ts +20 -0
  49. package/dist/playground/wasmReScriptVersion.js +20 -0
  50. package/dist/playground/worker/cachedClangCompile.js +37 -4
  51. package/dist/playground/worker/clang.js +35 -7
  52. package/dist/playground/worker/lua.js +48 -11
  53. package/dist/playground/worker/postgresql.d.ts +1 -0
  54. package/dist/playground/worker/postgresql.js +205 -0
  55. package/dist/playground/worker/python.js +106 -9
  56. package/dist/playground/worker/staticRuntimePreflight.js +2 -1
  57. package/dist/playground/worker/v.d.ts +1 -0
  58. package/dist/playground/worker/v.js +106 -0
  59. package/package.json +18 -7
@@ -0,0 +1,9 @@
1
+ import { StaticWorkerRuntimeSandbox } from './staticWorkerRuntime';
2
+ /** Upstream Grain compiler (js_of_ocaml build) plus a WASI host for the program it emits. */
3
+ declare class Grain extends StaticWorkerRuntimeSandbox {
4
+ readonly memoryEvidence: {
5
+ current: unknown;
6
+ };
7
+ constructor();
8
+ }
9
+ export default Grain;
@@ -0,0 +1,127 @@
1
+ import { resolveGrainBaseUrl } from './assets';
2
+ import { StaticWorkerRuntimeSandbox } from './staticWorkerRuntime';
3
+ import { bundledGrainProfile as profile, bundledGrainWorkerReceipt } from './wasmGrainVersion';
4
+ import { preflightRuntimeAssets } from '@wasm-idle/core';
5
+ const registry = {
6
+ schemaVersion: 2,
7
+ manifestId: 'wasm-idle/grain-preflight',
8
+ revision: profile.compilerJavaScript.sha256,
9
+ runtimes: [
10
+ {
11
+ runtimeId: 'GRAIN',
12
+ identity: {
13
+ languageId: 'GRAIN',
14
+ implementationId: 'grainc',
15
+ implementationVersion: profile.grainVersion,
16
+ profile: {
17
+ profileId: profile.profileId,
18
+ manifestSchemaVersion: 1,
19
+ manifestSha256: profile.compilerJavaScript.sha256,
20
+ protocolVersion: 1,
21
+ trustProfileId: 'wasm-idle-static-worker-v1',
22
+ trustProfileSchemaVersion: 1
23
+ }
24
+ },
25
+ capabilities: {
26
+ stdin: 'streaming',
27
+ workspace: true,
28
+ abort: true,
29
+ artifacts: false,
30
+ streamingOutput: true
31
+ },
32
+ workerLifetime: { mode: 'per-run' },
33
+ requiredBrowserFeatures: ['wasm'],
34
+ assetRoot: '.',
35
+ assets: [
36
+ {
37
+ key: 'compilerBytes',
38
+ path: 'grainc.js.gz.bin',
39
+ mediaType: 'text/javascript',
40
+ compressedSha256: profile.compilerStorage.sha256,
41
+ compressedBytes: profile.compilerStorage.bytes,
42
+ uncompressedSha256: profile.compilerJavaScript.sha256,
43
+ uncompressedBytes: profile.compilerJavaScript.bytes,
44
+ encoding: 'gzip'
45
+ },
46
+ {
47
+ key: 'stdlibBytes',
48
+ path: 'stdlib.pack.gz.bin',
49
+ mediaType: 'application/octet-stream',
50
+ compressedSha256: profile.stdlibStorage.sha256,
51
+ compressedBytes: profile.stdlibStorage.bytes,
52
+ uncompressedSha256: profile.stdlibPack.sha256,
53
+ uncompressedBytes: profile.stdlibPack.bytes,
54
+ encoding: 'gzip'
55
+ }
56
+ ],
57
+ contracts: {
58
+ routeId: 'grain',
59
+ runtimeAssetKey: 'grain',
60
+ documentationId: 'GRAIN',
61
+ syncTarget: 'sync:wasm-grain',
62
+ browserTestId: 'browser:grain'
63
+ }
64
+ }
65
+ ]
66
+ };
67
+ /** Upstream Grain compiler (js_of_ocaml build) plus a WASI host for the program it emits. */
68
+ class Grain extends StaticWorkerRuntimeSandbox {
69
+ memoryEvidence;
70
+ constructor() {
71
+ const memoryEvidence = { current: undefined };
72
+ super({
73
+ displayName: 'Grain',
74
+ languageId: 'GRAIN',
75
+ defaultActivePath: 'main.gr',
76
+ workerLifetime: { mode: 'per-run' },
77
+ runtimePreflightDelivery: 'transfer-owned',
78
+ stdin: {
79
+ mode: 'streaming',
80
+ sourceHintPattern: /\bFile\.(?:fdRead|stdin)\b|"wasi\/file"/u
81
+ },
82
+ inlineVerifiedWorker: true,
83
+ moduleWorker: true,
84
+ includeExecutionLimits: true,
85
+ enforcePhaseTimeouts: true,
86
+ onEvidence(evidence) {
87
+ memoryEvidence.current = evidence;
88
+ },
89
+ resolveRuntimeAssets(runtimeAssets, currentUrl) {
90
+ const baseUrl = resolveGrainBaseUrl(runtimeAssets, currentUrl);
91
+ return {
92
+ baseUrl,
93
+ workerUrl: new URL('runner-worker.js', baseUrl).href,
94
+ manifestUrl: new URL('runtime-build.json', baseUrl).href,
95
+ manifestFingerprint: profile.compilerJavaScript.sha256,
96
+ preflightKey: profile.stdlibPack.sha256,
97
+ workerReceipt: bundledGrainWorkerReceipt
98
+ };
99
+ },
100
+ async preflightRuntimeAssets(urls, context) {
101
+ memoryEvidence.current = undefined;
102
+ const result = await preflightRuntimeAssets({
103
+ manifest: registry,
104
+ runtimeId: 'GRAIN',
105
+ rootUrl: urls.baseUrl,
106
+ limits: context.limits,
107
+ persistentCache: context.persistentCache,
108
+ signal: context.signal,
109
+ redirect: 'error',
110
+ requireExactResponseUrl: true,
111
+ maxTotalDeliveryBytes: profile.compilerStorage.bytes + profile.stdlibStorage.bytes,
112
+ reportProgress(progress) {
113
+ context.reportProgress(0.1, `Preflighting Grain ${progress.assetKey}`);
114
+ }
115
+ });
116
+ return context.createOwnedDelivery(Object.freeze({
117
+ protocol: 'wasm-idle-grain-preflight',
118
+ profileId: profile.profileId,
119
+ compilerBytes: result.assets.compilerBytes.bytes,
120
+ stdlibBytes: result.assets.stdlibBytes.bytes
121
+ }));
122
+ }
123
+ });
124
+ this.memoryEvidence = memoryEvidence;
125
+ }
126
+ }
127
+ export default Grain;
@@ -0,0 +1,21 @@
1
+ import Python from './python';
2
+ import { type PlaygroundRuntimeAssets } from './assets';
3
+ export type HyWorkerExtension = {
4
+ language: 'hy';
5
+ version: string;
6
+ wheels: {
7
+ url: string;
8
+ fileName: string;
9
+ bytes: number;
10
+ sha256: string;
11
+ }[];
12
+ };
13
+ /**
14
+ * Hy runs on the shared Pyodide worker: the pinned Hy and funcparserlib wheels are fetched from
15
+ * local static assets, verified against code-pinned receipts, and unpacked into site-packages.
16
+ */
17
+ declare class Hy extends Python {
18
+ protected readonly workerLanguage: "hy";
19
+ protected workerLoadExtension(runtimeAssets: string | PlaygroundRuntimeAssets, currentUrl: string): HyWorkerExtension;
20
+ }
21
+ export default Hy;
@@ -0,0 +1,24 @@
1
+ import Python from './python';
2
+ import { resolveHyBaseUrl } from './assets';
3
+ import { WASM_HY_VERSION, WASM_HY_WHEELS } from './wasmHyVersion';
4
+ /**
5
+ * Hy runs on the shared Pyodide worker: the pinned Hy and funcparserlib wheels are fetched from
6
+ * local static assets, verified against code-pinned receipts, and unpacked into site-packages.
7
+ */
8
+ class Hy extends Python {
9
+ workerLanguage = 'hy';
10
+ workerLoadExtension(runtimeAssets, currentUrl) {
11
+ const baseUrl = resolveHyBaseUrl(runtimeAssets, currentUrl);
12
+ return {
13
+ language: 'hy',
14
+ version: WASM_HY_VERSION,
15
+ wheels: WASM_HY_WHEELS.map((wheel) => ({
16
+ url: `${baseUrl}${wheel.fileName}`,
17
+ fileName: wheel.fileName,
18
+ bytes: wheel.bytes,
19
+ sha256: wheel.sha256
20
+ }))
21
+ };
22
+ }
23
+ }
24
+ export default Hy;
@@ -1,6 +1,6 @@
1
1
  import type { BoundSandbox, PlaygroundBinding, Sandbox, SandboxRuntimeAssets } from './sandbox';
2
2
  import { type PlaygroundBindingOptions } from '@wasm-idle/core';
3
- export declare const supportedLanguages: ("C" | "CPP" | "OBJC" | "D" | "TINYGO" | "RUBY" | "PERL" | "TCL" | "AWK" | "PASCAL" | "JANET" | "JULIA" | "NIM" | "BASH" | "BQN" | "CLOJURESCRIPT" | "FORTH" | "J" | "PROLOG" | "C3" | "PYTHON3" | "JAVA" | "RUST" | "GO" | "CSHARP" | "FSHARP" | "VBNET" | "ELIXIR" | "ERLANG" | "GLEAM" | "FORTRAN" | "LFORTRAN" | "COBOL" | "OCAML" | "JAVASCRIPT" | "TYPESCRIPT" | "ASSEMBLYSCRIPT" | "WAT" | "WASM" | "LUA" | "ZIG" | "LISP" | "HASKELL" | "R" | "OCTAVE" | "DUCKDB" | "SQLITE" | "PHP")[];
3
+ export declare const supportedLanguages: ("C" | "CPP" | "OBJC" | "OBJECTIVECXX" | "D" | "TINYGO" | "RUBY" | "PERL" | "TCL" | "AWK" | "PASCAL" | "JANET" | "JULIA" | "NIM" | "BASH" | "BQN" | "CLOJURESCRIPT" | "FORTH" | "J" | "PROLOG" | "RESCRIPT" | "C3" | "PYTHON3" | "JAVA" | "RUST" | "GO" | "CSHARP" | "FSHARP" | "VBNET" | "ELIXIR" | "ERLANG" | "GLEAM" | "GRAIN" | "HY" | "FORTRAN" | "LFORTRAN" | "COBOL" | "V" | "OCAML" | "JAVASCRIPT" | "TYPESCRIPT" | "ASSEMBLYSCRIPT" | "WAT" | "WASM" | "LUA" | "FENNEL" | "ZIG" | "LISP" | "HASKELL" | "R" | "OCTAVE" | "DUCKDB" | "SQLITE" | "POSTGRESQL" | "PHP")[];
4
4
  export declare function createPlaygroundBinding(runtimeAssets: SandboxRuntimeAssets, options?: PlaygroundBindingOptions): PlaygroundBinding;
5
5
  declare function playground(language: string): Promise<Sandbox>;
6
6
  declare function playground(language: string, runtimeAssets: SandboxRuntimeAssets, options?: PlaygroundBindingOptions): Promise<BoundSandbox>;
@@ -14,6 +14,13 @@ const sandboxRoutes = [
14
14
  return new Python();
15
15
  }
16
16
  },
17
+ {
18
+ languageId: 'HY',
19
+ load: async () => {
20
+ const { default: Hy } = await import('./hy');
21
+ return new Hy();
22
+ }
23
+ },
17
24
  {
18
25
  languageId: 'C',
19
26
  load: async () => {
@@ -35,6 +42,13 @@ const sandboxRoutes = [
35
42
  return new ObjectiveC();
36
43
  }
37
44
  },
45
+ {
46
+ languageId: 'OBJECTIVECXX',
47
+ load: async () => {
48
+ const { default: ObjectiveC } = await import('./objectivec');
49
+ return new ObjectiveC('OBJECTIVECXX');
50
+ }
51
+ },
38
52
  {
39
53
  languageId: 'JAVA',
40
54
  load: async () => {
@@ -112,6 +126,13 @@ const sandboxRoutes = [
112
126
  return new Gleam();
113
127
  }
114
128
  },
129
+ {
130
+ languageId: 'GRAIN',
131
+ load: async () => {
132
+ const { default: Grain } = await import('./grain');
133
+ return new Grain();
134
+ }
135
+ },
115
136
  {
116
137
  languageId: 'PERL',
117
138
  load: async () => {
@@ -147,6 +168,13 @@ const sandboxRoutes = [
147
168
  return new ClojureScript();
148
169
  }
149
170
  },
171
+ {
172
+ languageId: 'RESCRIPT',
173
+ load: async () => {
174
+ const { default: ReScript } = await import('./rescript');
175
+ return new ReScript();
176
+ }
177
+ },
150
178
  {
151
179
  languageId: 'FORTH',
152
180
  load: async () => {
@@ -217,6 +245,13 @@ const sandboxRoutes = [
217
245
  return new Cobol();
218
246
  }
219
247
  },
248
+ {
249
+ languageId: 'V',
250
+ load: async () => {
251
+ const { default: VLang } = await import('./v');
252
+ return new VLang();
253
+ }
254
+ },
220
255
  {
221
256
  languageId: 'TINYGO',
222
257
  load: async () => {
@@ -273,6 +308,13 @@ const sandboxRoutes = [
273
308
  return new Lua();
274
309
  }
275
310
  },
311
+ {
312
+ languageId: 'FENNEL',
313
+ load: async () => {
314
+ const { default: Fennel } = await import('./fennel');
315
+ return new Fennel();
316
+ }
317
+ },
276
318
  {
277
319
  languageId: 'ZIG',
278
320
  load: async () => {
@@ -329,6 +371,13 @@ const sandboxRoutes = [
329
371
  return new Sqlite();
330
372
  }
331
373
  },
374
+ {
375
+ languageId: 'POSTGRESQL',
376
+ load: async () => {
377
+ const { default: Postgresql } = await import('./postgresql');
378
+ return new Postgresql();
379
+ }
380
+ },
332
381
  {
333
382
  languageId: 'PHP',
334
383
  load: async () => {
@@ -1,6 +1,20 @@
1
1
  import { type PlaygroundRuntimeAssets } from './assets';
2
2
  import { type CompilerDiagnostic, type SandboxExecutionOptions } from './options';
3
3
  import type { Sandbox, SandboxProgress } from './sandbox';
4
+ /**
5
+ * Describes a language that runs on the wasm-lua (wasmoon) VM. Lua itself uses the
6
+ * default dialect; Fennel reuses this sandbox and worker with the pinned fennel.lua compiler.
7
+ */
8
+ export interface LuaSandboxDialect {
9
+ label: string;
10
+ runtimeId: string;
11
+ defaultActivePath: string;
12
+ /**
13
+ * Extra worker load fields. The value is also part of the worker identity, so a change
14
+ * replaces the loaded worker.
15
+ */
16
+ resolveWorkerLoadExtras?: (runtimeAssets: string | PlaygroundRuntimeAssets, currentUrl: string) => Record<string, unknown>;
17
+ }
4
18
  declare class Lua implements Sandbox {
5
19
  output: any;
6
20
  worker?: Worker;
@@ -17,8 +31,13 @@ declare class Lua implements Sandbox {
17
31
  private activeOperation;
18
32
  private disposed;
19
33
  private disposePromise;
34
+ private readonly dialect;
35
+ private readonly label;
36
+ private readonly runtimeId;
37
+ private workerIdentity;
20
38
  private readonly disposeCancellation;
21
39
  private readonly workerSession;
40
+ constructor(dialect?: LuaSandboxDialect);
22
41
  private requireOperationIdle;
23
42
  private beginOperation;
24
43
  private isOperationActive;
@@ -6,9 +6,16 @@ import { createWasmIdleSharedBuffer } from './sharedBuffer';
6
6
  import { WorkerSession } from './workerSession';
7
7
  import { reportWorkerInputReady, reportWorkerProgress } from './workerProgress';
8
8
  const OUTPUT_ENCODER = new TextEncoder();
9
- const abortReason = (signal, phase) => signal.reason !== undefined
9
+ const abortReason = (signal, phase, label) => signal.reason !== undefined
10
10
  ? signal.reason
11
- : new DOMException(phase === 'startup' ? 'Lua runtime startup aborted' : 'Lua execution aborted', 'AbortError');
11
+ : new DOMException(phase === 'startup'
12
+ ? `${label} runtime startup aborted`
13
+ : `${label} execution aborted`, 'AbortError');
14
+ const LUA_DIALECT = {
15
+ label: 'Lua',
16
+ runtimeId: 'LUA',
17
+ defaultActivePath: 'main.lua'
18
+ };
12
19
  class Lua {
13
20
  output = null;
14
21
  worker = null;
@@ -25,34 +32,45 @@ class Lua {
25
32
  activeOperation = null;
26
33
  disposed = false;
27
34
  disposePromise = null;
28
- disposeCancellation = new CancelledError('Lua sandbox disposed', {
29
- phase: 'dispose',
30
- runtimeId: 'LUA',
31
- recoverable: false
32
- });
33
- workerSession = new WorkerSession({
34
- label: 'Lua',
35
- onDispose: (worker) => {
36
- if (this.worker === worker)
37
- delete this.worker;
38
- this.exit = true;
39
- this.waitingForInput = false;
40
- this.pendingEof = false;
41
- }
42
- });
35
+ dialect;
36
+ label;
37
+ runtimeId;
38
+ workerIdentity = '';
39
+ disposeCancellation;
40
+ workerSession;
41
+ constructor(dialect = LUA_DIALECT) {
42
+ this.dialect = dialect;
43
+ this.label = dialect.label;
44
+ this.runtimeId = dialect.runtimeId;
45
+ this.disposeCancellation = new CancelledError(`${this.label} sandbox disposed`, {
46
+ phase: 'dispose',
47
+ runtimeId: this.runtimeId,
48
+ recoverable: false
49
+ });
50
+ this.workerSession = new WorkerSession({
51
+ label: this.label,
52
+ onDispose: (worker) => {
53
+ if (this.worker === worker)
54
+ delete this.worker;
55
+ this.exit = true;
56
+ this.waitingForInput = false;
57
+ this.pendingEof = false;
58
+ }
59
+ });
60
+ }
43
61
  requireOperationIdle() {
44
62
  if (!this.activeOperation)
45
63
  return;
46
- throw new BusyError('Lua runtime already has an active operation', {
47
- runtimeId: 'LUA',
64
+ throw new BusyError(`${this.label} runtime already has an active operation`, {
65
+ runtimeId: this.runtimeId,
48
66
  phase: this.activeOperation.phase
49
67
  });
50
68
  }
51
69
  beginOperation(phase) {
52
70
  if (this.disposed) {
53
- throw new RuntimeConfigurationError('Lua sandbox is disposed', {
71
+ throw new RuntimeConfigurationError(`${this.label} sandbox is disposed`, {
54
72
  phase: 'dispose',
55
- runtimeId: 'LUA'
73
+ runtimeId: this.runtimeId
56
74
  });
57
75
  }
58
76
  this.requireOperationIdle();
@@ -113,7 +131,7 @@ class Lua {
113
131
  return;
114
132
  let reason;
115
133
  try {
116
- reason = abortReason(signal, operation.phase);
134
+ reason = abortReason(signal, operation.phase, this.label);
117
135
  }
118
136
  catch (error) {
119
137
  reason = error;
@@ -149,7 +167,7 @@ class Lua {
149
167
  return;
150
168
  let reason;
151
169
  try {
152
- reason = abortReason(signal, operation.phase);
170
+ reason = abortReason(signal, operation.phase, this.label);
153
171
  }
154
172
  catch (error) {
155
173
  reason = error;
@@ -189,9 +207,9 @@ class Lua {
189
207
  if (!this.isOperationActive(operation))
190
208
  return;
191
209
  const label = operation.phase === 'startup' ? 'startup' : 'execution';
192
- this.cancelOperation(operation, new TimeoutError(`Lua ${label} timed out after ${timeoutMs} ms`, {
210
+ this.cancelOperation(operation, new TimeoutError(`${this.label} ${label} timed out after ${timeoutMs} ms`, {
193
211
  phase: operation.phase,
194
- runtimeId: 'LUA',
212
+ runtimeId: this.runtimeId,
195
213
  timeoutMs
196
214
  }));
197
215
  }, timeoutMs);
@@ -234,11 +252,11 @@ class Lua {
234
252
  signal = options.signal;
235
253
  unbindPreSessionAbort = this.bindPreSessionAbort(activeOperation, signal);
236
254
  if (!this.isOperationActive(activeOperation) || signal?.aborted) {
237
- return Promise.reject(this.releaseBeforeSession(activeOperation, 'Lua runtime startup cancelled'));
255
+ return Promise.reject(this.releaseBeforeSession(activeOperation, `${this.label} runtime startup cancelled`));
238
256
  }
239
257
  limits = resolveExecutionLimits(options.limits);
240
258
  if (!this.isOperationActive(activeOperation) || signal?.aborted) {
241
- return Promise.reject(this.releaseBeforeSession(activeOperation, 'Lua runtime startup cancelled'));
259
+ return Promise.reject(this.releaseBeforeSession(activeOperation, `${this.label} runtime startup cancelled`));
242
260
  }
243
261
  unbindPreSessionAbort();
244
262
  }
@@ -246,7 +264,7 @@ class Lua {
246
264
  return Promise.reject(this.releaseBeforeSession(activeOperation, error));
247
265
  }
248
266
  if (!this.isOperationActive(activeOperation)) {
249
- return Promise.reject(this.releaseBeforeSession(activeOperation, 'Lua runtime startup cancelled'));
267
+ return Promise.reject(this.releaseBeforeSession(activeOperation, `${this.label} runtime startup cancelled`));
250
268
  }
251
269
  const loadPromise = this.workerSession.load(async (resolve, reject) => {
252
270
  const resolveLoad = () => {
@@ -274,8 +292,13 @@ class Lua {
274
292
  if (!nextModuleUrl) {
275
293
  return rejectLoad('Lua runtime is not configured. Set PUBLIC_WASM_LUA_MODULE_URL or runtimeAssets.lua.moduleUrl.');
276
294
  }
277
- const needsWorkerReset = !this.worker || this.moduleUrl !== nextModuleUrl;
295
+ const loadExtras = this.dialect.resolveWorkerLoadExtras?.(runtimeAssets, currentUrl) ?? {};
296
+ if (!this.isOperationActive(activeOperation))
297
+ return;
298
+ const nextWorkerIdentity = JSON.stringify([nextModuleUrl, loadExtras]);
299
+ const needsWorkerReset = !this.worker || this.workerIdentity !== nextWorkerIdentity;
278
300
  this.moduleUrl = nextModuleUrl;
301
+ this.workerIdentity = nextWorkerIdentity;
279
302
  if (needsWorkerReset && this.worker) {
280
303
  this.workerSession.reset();
281
304
  }
@@ -320,6 +343,7 @@ class Lua {
320
343
  };
321
344
  worker.onmessage = handler;
322
345
  worker.postMessage({
346
+ ...loadExtras,
323
347
  load: true,
324
348
  moduleUrl: this.moduleUrl
325
349
  });
@@ -392,12 +416,12 @@ class Lua {
392
416
  signal = options.signal;
393
417
  unbindPreSessionAbort = this.bindPreSessionAbort(activeOperation, signal);
394
418
  if (!this.isOperationActive(activeOperation)) {
395
- return Promise.reject(this.releaseBeforeSession(activeOperation, 'Lua execution cancelled'));
419
+ return Promise.reject(this.releaseBeforeSession(activeOperation, `${this.label} execution cancelled`));
396
420
  }
397
- executionArgs = resolveSandboxExecutionArgs('LUA', args, options);
421
+ executionArgs = resolveSandboxExecutionArgs(this.runtimeId, args, options);
398
422
  limits = resolveExecutionLimits(options.limits);
399
423
  const workspaceFiles = options.workspaceFiles ?? [];
400
- const activePath = options.activePath ?? 'main.lua';
424
+ const activePath = options.activePath ?? this.dialect.defaultActivePath;
401
425
  const workspaceLimits = options.workspaceLimits;
402
426
  workspace = validateExecutionWorkspace(code, workspaceFiles, activePath, {
403
427
  ...workspaceLimits,
@@ -406,7 +430,7 @@ class Lua {
406
430
  });
407
431
  stdin = options.stdin;
408
432
  if (!this.isOperationActive(activeOperation) || signal?.aborted) {
409
- return Promise.reject(this.releaseBeforeSession(activeOperation, 'Lua execution cancelled'));
433
+ return Promise.reject(this.releaseBeforeSession(activeOperation, `${this.label} execution cancelled`));
410
434
  }
411
435
  unbindPreSessionAbort();
412
436
  }
@@ -414,7 +438,7 @@ class Lua {
414
438
  return Promise.reject(this.releaseBeforeSession(activeOperation, error));
415
439
  }
416
440
  if (!this.isOperationActive(activeOperation)) {
417
- return Promise.reject(this.releaseBeforeSession(activeOperation, 'Lua execution cancelled'));
441
+ return Promise.reject(this.releaseBeforeSession(activeOperation, `${this.label} execution cancelled`));
418
442
  }
419
443
  const hasExplicitStdin = stdin !== undefined;
420
444
  if (hasExplicitStdin) {
@@ -476,7 +500,7 @@ class Lua {
476
500
  if (buffer && !hasExplicitStdin) {
477
501
  this.waitingForInput = true;
478
502
  if (!prepare) {
479
- reportWorkerInputReady(_prog, 'Lua runtime ready for input');
503
+ reportWorkerInputReady(_prog, `${this.label} runtime ready for input`);
480
504
  if (!ownsRun())
481
505
  return;
482
506
  }
@@ -490,11 +514,11 @@ class Lua {
490
514
  if (output) {
491
515
  const actual = outputBytes + OUTPUT_ENCODER.encode(String(output)).byteLength;
492
516
  if (actual > limits.maxOutputBytes) {
493
- failRun(new OutputLimitError(`Lua output exceeded ${limits.maxOutputBytes} bytes`, {
517
+ failRun(new OutputLimitError(`${this.label} output exceeded ${limits.maxOutputBytes} bytes`, {
494
518
  actual,
495
519
  limit: limits.maxOutputBytes,
496
520
  phase: 'execute',
497
- runtimeId: 'LUA'
521
+ runtimeId: this.runtimeId
498
522
  }), true);
499
523
  return;
500
524
  }
@@ -506,11 +530,11 @@ class Lua {
506
530
  if (diagnostic) {
507
531
  const actual = diagnosticCount + 1;
508
532
  if (actual > limits.maxDiagnostics) {
509
- failRun(new DiagnosticLimitError(`Lua diagnostics exceeded ${limits.maxDiagnostics} messages`, {
533
+ failRun(new DiagnosticLimitError(`${this.label} diagnostics exceeded ${limits.maxDiagnostics} messages`, {
510
534
  actual,
511
535
  limit: limits.maxDiagnostics,
512
536
  phase: 'execute',
513
- runtimeId: 'LUA'
537
+ runtimeId: this.runtimeId
514
538
  }), true);
515
539
  return;
516
540
  }
@@ -613,6 +637,7 @@ class Lua {
613
637
  const activeOperation = this.activeOperation;
614
638
  delete this.worker;
615
639
  this.moduleUrl = '';
640
+ this.workerIdentity = '';
616
641
  this.output = null;
617
642
  this.oncompilerdiagnostic = undefined;
618
643
  this.resetExplicitStdinState();
@@ -3,8 +3,9 @@ import type { DebugCommand, DebugSessionEvent } from './options';
3
3
  import { type PlaygroundRuntimeAssets } from './assets';
4
4
  import type { SandboxExecutionOptions } from './options';
5
5
  import type { Sandbox, SandboxProgress } from './sandbox';
6
+ export type ObjectiveCSandboxLanguage = 'OBJC' | 'OBJECTIVECXX';
6
7
  declare class ObjectiveC implements Sandbox {
7
- language: string;
8
+ language: ObjectiveCSandboxLanguage;
8
9
  output?: (data: string) => void;
9
10
  ondebug?: (event: DebugSessionEvent) => void;
10
11
  worker?: Worker;
@@ -24,6 +25,7 @@ declare class ObjectiveC implements Sandbox {
24
25
  assetBridge: WorkerAssetBridge | null;
25
26
  activeObjectiveCAssetsKey: string;
26
27
  private readonly workerSession;
28
+ constructor(language?: ObjectiveCSandboxLanguage);
27
29
  load(runtimeAssets?: string | PlaygroundRuntimeAssets, code?: string, log?: boolean, args?: string[], options?: SandboxExecutionOptions, progress?: SandboxProgress): Promise<void>;
28
30
  write(input: string): void;
29
31
  eof(): void;
@@ -9,7 +9,7 @@ import { AssetTooLargeError, createRuntimeAssetsKey, resolveExecutionLimits } fr
9
9
  const debugBreakpointBufferInts = 1028;
10
10
  const objectiveCAssetsKey = (assets) => createRuntimeAssetsKey({ objectivec: assets }) || '';
11
11
  class ObjectiveC {
12
- language = 'OBJC';
12
+ language;
13
13
  output;
14
14
  ondebug;
15
15
  worker = null;
@@ -49,6 +49,9 @@ class ObjectiveC {
49
49
  this.ondebug?.({ type: 'stop' });
50
50
  }
51
51
  });
52
+ constructor(language = 'OBJC') {
53
+ this.language = language;
54
+ }
52
55
  load(runtimeAssets = '', code = '', log = true, args = [], options = {}, progress) {
53
56
  let limits;
54
57
  try {
@@ -220,7 +223,8 @@ class ObjectiveC {
220
223
  log,
221
224
  compileArgs,
222
225
  programArgs,
223
- activePath: options.activePath,
226
+ activePath: options.activePath ||
227
+ (this.language === 'OBJECTIVECXX' ? 'main.mm' : undefined),
224
228
  workspaceFiles: options.workspaceFiles,
225
229
  debug: !!options.debug,
226
230
  breakpoints: [...(options.breakpoints || [])],
@@ -1,7 +1,7 @@
1
1
  function cloneArgs(value) {
2
2
  return Array.isArray(value) ? [...value] : [];
3
3
  }
4
- const compileArgLanguages = new Set(['C', 'CPP', 'OBJC']);
4
+ const compileArgLanguages = new Set(['C', 'CPP', 'OBJC', 'OBJECTIVECXX']);
5
5
  export function resolveSandboxExecutionArgs(language, args = [], options = {}) {
6
6
  if (compileArgLanguages.has(language)) {
7
7
  return {
@@ -0,0 +1,36 @@
1
+ import type { CompilerDiagnostic, SandboxExecutionOptions } from './options';
2
+ import { type PlaygroundRuntimeAssets } from './assets';
3
+ import type { Sandbox, SandboxProgress } from './sandbox';
4
+ declare class Postgresql implements Sandbox {
5
+ output: any;
6
+ worker?: Worker;
7
+ begin: number;
8
+ elapse: number;
9
+ uid: number;
10
+ exit: boolean;
11
+ moduleUrl: string;
12
+ oncompilerdiagnostic?: (diagnostic: CompilerDiagnostic) => void;
13
+ private activeOperation;
14
+ private disposed;
15
+ private disposePromise;
16
+ private readonly disposeCancellation;
17
+ private readonly workerSession;
18
+ private beginOperation;
19
+ private isOperationActive;
20
+ private releaseOperation;
21
+ private cleanupOperation;
22
+ private releaseBeforeSession;
23
+ private bindPreSessionAbort;
24
+ private bindAbortSignal;
25
+ private bindOperationTimeout;
26
+ private cancelOperation;
27
+ load(runtimeAssets?: string | PlaygroundRuntimeAssets, _code?: string, _log?: boolean, _args?: string[], options?: SandboxExecutionOptions, progress?: SandboxProgress): Promise<void>;
28
+ write(): void;
29
+ eof(): void;
30
+ run(code: string, prepare: boolean, _log?: boolean, _prog?: SandboxProgress, _args?: string[], options?: SandboxExecutionOptions): Promise<boolean | string>;
31
+ kill(): void;
32
+ terminate(reason?: unknown): void;
33
+ clear(): Promise<void>;
34
+ dispose(): Promise<void>;
35
+ }
36
+ export default Postgresql;