@ox-content/code-play 3.0.0-alpha.1 → 3.0.0-alpha.11
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/README.md +35 -6
- package/dist/browser.mjs +561 -58
- package/dist/client.mjs +192 -28
- package/dist/client.mjs.map +1 -1
- package/dist/config.d.mts +47 -2
- package/dist/config.d.mts.map +1 -1
- package/dist/hydrate.d.mts +5 -2
- package/dist/hydrate.d.mts.map +1 -1
- package/dist/hydrate.mjs +2 -2
- package/dist/hydrate2.d.mts +2 -2
- package/dist/hydrate2.mjs +369 -33
- package/dist/hydrate2.mjs.map +1 -1
- package/dist/index.d.mts +50 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/payload.mjs +10 -2
- package/dist/payload.mjs.map +1 -1
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin2.mjs +712 -162
- package/dist/plugin2.mjs.map +1 -1
- package/package.json +1 -1
package/dist/client.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as escapeHtml,
|
|
1
|
+
import { a as escapeHtml, d as mergeConfig, f as resolveCodePlayOptions, h as resolveLanguage } from "./payload.mjs";
|
|
2
2
|
//#region \0rolldown/runtime.js
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __exportAll = (all, no_symbols) => {
|
|
@@ -336,10 +336,115 @@ function buildJavaScriptSandboxDocument(code, messageId) {
|
|
|
336
336
|
})();
|
|
337
337
|
<\/script></body></html>`;
|
|
338
338
|
}
|
|
339
|
+
function buildJavaScriptWorkerSource() {
|
|
340
|
+
return `
|
|
341
|
+
(function () {
|
|
342
|
+
function format(args) {
|
|
343
|
+
return Array.prototype.map.call(args, function (value) {
|
|
344
|
+
if (typeof value === "string") return value;
|
|
345
|
+
if (value === undefined) return "undefined";
|
|
346
|
+
if (value === null) return "null";
|
|
347
|
+
try { return JSON.stringify(value); } catch (error) { return String(value); }
|
|
348
|
+
}).join(" ") + "\\n";
|
|
349
|
+
}
|
|
350
|
+
self.onmessage = function (event) {
|
|
351
|
+
var data = event.data || {};
|
|
352
|
+
if (!data.id) return;
|
|
353
|
+
var stdout = [];
|
|
354
|
+
var stderr = [];
|
|
355
|
+
var consoleLike = {
|
|
356
|
+
log: function () { stdout.push(format(arguments)); },
|
|
357
|
+
info: function () { stdout.push(format(arguments)); },
|
|
358
|
+
warn: function () { stderr.push(format(arguments)); },
|
|
359
|
+
error: function () { stderr.push(format(arguments)); }
|
|
360
|
+
};
|
|
361
|
+
try {
|
|
362
|
+
var run = new Function("console", '"use strict";\\n' + String(data.code || ""));
|
|
363
|
+
var value = run(consoleLike);
|
|
364
|
+
self.postMessage({
|
|
365
|
+
id: data.id,
|
|
366
|
+
stdout: stdout,
|
|
367
|
+
stderr: stderr,
|
|
368
|
+
value: value === undefined ? undefined : String(value)
|
|
369
|
+
});
|
|
370
|
+
} catch (error) {
|
|
371
|
+
var message = error && error.message ? String(error.message) : String(error);
|
|
372
|
+
self.postMessage({ id: data.id, stdout: stdout, stderr: stderr, error: message });
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
})();
|
|
376
|
+
`;
|
|
377
|
+
}
|
|
339
378
|
function applySandboxStreams(stdio, message) {
|
|
340
379
|
for (const text of message.stdout ?? []) stdio.push("stdout", text);
|
|
341
380
|
for (const text of message.stderr ?? []) stdio.push("stderr", text);
|
|
342
381
|
}
|
|
382
|
+
const WORKER_UNAVAILABLE_CODE = "ERR_SCRIPT_WORKER_UNAVAILABLE";
|
|
383
|
+
function workerUnavailableError(error) {
|
|
384
|
+
const message = error instanceof Error && error.message ? error.message : "JavaScript worker sandbox is unavailable.";
|
|
385
|
+
return Object.assign(new Error(message), { code: WORKER_UNAVAILABLE_CODE });
|
|
386
|
+
}
|
|
387
|
+
function isSandboxWorkerUnavailable(error) {
|
|
388
|
+
return Boolean(error && typeof error === "object" && "code" in error && error.code === WORKER_UNAVAILABLE_CODE);
|
|
389
|
+
}
|
|
390
|
+
function canUseSandboxWorker() {
|
|
391
|
+
return typeof Worker !== "undefined" && typeof Blob !== "undefined" && typeof URL !== "undefined" && typeof URL.createObjectURL === "function" && typeof URL.revokeObjectURL === "function";
|
|
392
|
+
}
|
|
393
|
+
async function executeInSandboxWorker(code, timeoutMs, stdio, signal) {
|
|
394
|
+
if (!canUseSandboxWorker()) throw workerUnavailableError(/* @__PURE__ */ new Error("JavaScript worker sandbox needs Worker, Blob, and object URLs."));
|
|
395
|
+
if (signal?.aborted) throw abortError();
|
|
396
|
+
const messageId = `ox-code-play-${Math.random().toString(36).slice(2)}`;
|
|
397
|
+
const url = URL.createObjectURL(new Blob([buildJavaScriptWorkerSource()], { type: "text/javascript" }));
|
|
398
|
+
let worker;
|
|
399
|
+
try {
|
|
400
|
+
worker = new Worker(url);
|
|
401
|
+
} catch (error) {
|
|
402
|
+
URL.revokeObjectURL(url);
|
|
403
|
+
throw workerUnavailableError(error);
|
|
404
|
+
}
|
|
405
|
+
return new Promise((resolve, reject) => {
|
|
406
|
+
let settled = false;
|
|
407
|
+
const cleanup = () => {
|
|
408
|
+
if (settled) return;
|
|
409
|
+
settled = true;
|
|
410
|
+
clearTimeout(timer);
|
|
411
|
+
signal?.removeEventListener("abort", onAbort);
|
|
412
|
+
worker.onmessage = null;
|
|
413
|
+
worker.onerror = null;
|
|
414
|
+
worker.terminate();
|
|
415
|
+
URL.revokeObjectURL(url);
|
|
416
|
+
};
|
|
417
|
+
const onAbort = () => {
|
|
418
|
+
cleanup();
|
|
419
|
+
reject(abortError());
|
|
420
|
+
};
|
|
421
|
+
const onMessage = (event) => {
|
|
422
|
+
if (event.data?.id !== messageId) return;
|
|
423
|
+
cleanup();
|
|
424
|
+
applySandboxStreams(stdio, event.data);
|
|
425
|
+
if (event.data.error) {
|
|
426
|
+
reject(new Error(event.data.error));
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
resolve(event.data.value);
|
|
430
|
+
};
|
|
431
|
+
const onError = (event) => {
|
|
432
|
+
cleanup();
|
|
433
|
+
reject(workerUnavailableError(new Error(event.message || "JavaScript worker sandbox failed.")));
|
|
434
|
+
};
|
|
435
|
+
const timer = setTimeout(() => {
|
|
436
|
+
cleanup();
|
|
437
|
+
reject(Object.assign(/* @__PURE__ */ new Error("JavaScript execution timed out."), { code: "ERR_SCRIPT_EXECUTION_TIMEOUT" }));
|
|
438
|
+
}, timeoutMs);
|
|
439
|
+
worker.onmessage = onMessage;
|
|
440
|
+
worker.onerror = onError;
|
|
441
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
442
|
+
worker.postMessage({
|
|
443
|
+
id: messageId,
|
|
444
|
+
code
|
|
445
|
+
});
|
|
446
|
+
});
|
|
447
|
+
}
|
|
343
448
|
async function executeInSandboxIframe(code, timeoutMs, stdio, signal) {
|
|
344
449
|
if (typeof document === "undefined" || typeof window === "undefined") throw new Error("JavaScript sandbox iframe needs a document.");
|
|
345
450
|
if (signal?.aborted) throw abortError();
|
|
@@ -391,24 +496,23 @@ async function runJavaScript(request) {
|
|
|
391
496
|
const tracker = new PhaseTracker();
|
|
392
497
|
tracker.start("execute", "Execute");
|
|
393
498
|
const stdio = new StdioBuffer(tracker.startedAt);
|
|
394
|
-
const
|
|
395
|
-
|
|
396
|
-
runtime: hasNodeVm() ? "node:vm" : "iframe",
|
|
397
|
-
sandbox: hasNodeVm() ? "vm" : "srcdoc"
|
|
398
|
-
} };
|
|
499
|
+
const runtime = currentJavaScriptRuntime();
|
|
500
|
+
let executedRuntime = runtime;
|
|
399
501
|
try {
|
|
400
|
-
const
|
|
502
|
+
const result = await executeScriptWithRuntime(request.code, request.timeoutMs, stdio, request.signal, runtime);
|
|
503
|
+
executedRuntime = result.runtime;
|
|
401
504
|
tracker.stop();
|
|
402
505
|
return {
|
|
403
506
|
status: "ok",
|
|
404
507
|
stdio: stdio.snapshot(),
|
|
405
508
|
diagnostics: [],
|
|
406
|
-
provenance,
|
|
509
|
+
provenance: { execute: javascriptRuntimeProvenance(executedRuntime) },
|
|
407
510
|
timing: tracker.report(),
|
|
408
|
-
value: value === void 0 ? void 0 : String(value)
|
|
511
|
+
value: result.value === void 0 ? void 0 : String(result.value)
|
|
409
512
|
};
|
|
410
513
|
} catch (error) {
|
|
411
514
|
if (isAbortError(error) || request.signal?.aborted) throw error;
|
|
515
|
+
executedRuntime = executionRuntimeFromError(error) ?? executedRuntime;
|
|
412
516
|
tracker.stop();
|
|
413
517
|
const diagnostic = toDiagnostic(error);
|
|
414
518
|
stdio.push("stderr", `${diagnostic.message}\n`);
|
|
@@ -416,12 +520,30 @@ async function runJavaScript(request) {
|
|
|
416
520
|
status: isTimeout(error) ? "timeout" : "error",
|
|
417
521
|
stdio: stdio.snapshot(),
|
|
418
522
|
diagnostics: [diagnostic],
|
|
419
|
-
provenance,
|
|
523
|
+
provenance: { execute: javascriptRuntimeProvenance(executedRuntime) },
|
|
420
524
|
timing: tracker.report()
|
|
421
525
|
};
|
|
422
526
|
}
|
|
423
527
|
}
|
|
424
|
-
async function
|
|
528
|
+
async function executeScriptWithRuntime(code, timeoutMs, stdio, signal, runtime = currentJavaScriptRuntime()) {
|
|
529
|
+
try {
|
|
530
|
+
return {
|
|
531
|
+
value: await executeScriptInRuntime(code, timeoutMs, stdio, signal, runtime),
|
|
532
|
+
runtime
|
|
533
|
+
};
|
|
534
|
+
} catch (error) {
|
|
535
|
+
if (runtime === "worker" && isSandboxWorkerUnavailable(error) && typeof document !== "undefined") try {
|
|
536
|
+
return {
|
|
537
|
+
value: await executeScriptInRuntime(code, timeoutMs, stdio, signal, "iframe"),
|
|
538
|
+
runtime: "iframe"
|
|
539
|
+
};
|
|
540
|
+
} catch (fallbackError) {
|
|
541
|
+
throw withExecutionRuntime(fallbackError, "iframe");
|
|
542
|
+
}
|
|
543
|
+
throw withExecutionRuntime(error, runtime);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
async function executeScriptInRuntime(code, timeoutMs, stdio, signal, runtime) {
|
|
425
547
|
const consoleLike = {
|
|
426
548
|
log: (...args) => stdio.push("stdout", formatConsoleArgs(args)),
|
|
427
549
|
info: (...args) => stdio.push("stdout", formatConsoleArgs(args)),
|
|
@@ -429,7 +551,7 @@ async function executeScript(code, timeoutMs, stdio, signal) {
|
|
|
429
551
|
error: (...args) => stdio.push("stderr", formatConsoleArgs(args))
|
|
430
552
|
};
|
|
431
553
|
if (signal?.aborted) throw abortError();
|
|
432
|
-
if (
|
|
554
|
+
if (runtime === "vm") {
|
|
433
555
|
const vm = await import("node:vm");
|
|
434
556
|
const context = vm.createContext({ console: consoleLike });
|
|
435
557
|
return vm.runInContext(code, context, {
|
|
@@ -437,12 +559,45 @@ async function executeScript(code, timeoutMs, stdio, signal) {
|
|
|
437
559
|
displayErrors: true
|
|
438
560
|
});
|
|
439
561
|
}
|
|
562
|
+
if (runtime === "worker") return executeInSandboxWorker(code, timeoutMs, stdio, signal);
|
|
440
563
|
return executeInSandboxIframe(code, timeoutMs, stdio, signal);
|
|
441
564
|
}
|
|
442
|
-
function
|
|
565
|
+
function currentJavaScriptRuntime() {
|
|
566
|
+
return javascriptExecuteRuntime(hasNodeVm(), canUseSandboxWorker(), typeof document !== "undefined");
|
|
567
|
+
}
|
|
568
|
+
function javascriptExecuteRuntime(hasVm, hasWorker, hasDocument) {
|
|
443
569
|
if (hasVm) return "vm";
|
|
570
|
+
if (hasWorker) return "worker";
|
|
444
571
|
if (hasDocument) return "iframe";
|
|
445
|
-
throw new Error("JavaScript execute needs node:vm or a document for the sandbox iframe.");
|
|
572
|
+
throw new Error("JavaScript execute needs node:vm, a browser worker sandbox, or a document for the sandbox iframe.");
|
|
573
|
+
}
|
|
574
|
+
function javascriptRuntimeProvenance(runtime) {
|
|
575
|
+
if (runtime === "vm") return {
|
|
576
|
+
host: "local",
|
|
577
|
+
runtime: "node:vm",
|
|
578
|
+
sandbox: "vm"
|
|
579
|
+
};
|
|
580
|
+
if (runtime === "worker") return {
|
|
581
|
+
host: "local",
|
|
582
|
+
runtime: "web-worker",
|
|
583
|
+
sandbox: "worker"
|
|
584
|
+
};
|
|
585
|
+
return {
|
|
586
|
+
host: "local",
|
|
587
|
+
runtime: "iframe",
|
|
588
|
+
sandbox: "srcdoc"
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
function withExecutionRuntime(error, runtime) {
|
|
592
|
+
if (error instanceof Error) return Object.assign(error, { executionRuntime: runtime });
|
|
593
|
+
if (isErrorLike(error)) return Object.assign(error, { executionRuntime: runtime });
|
|
594
|
+
return Object.assign(new Error(String(error)), { executionRuntime: runtime });
|
|
595
|
+
}
|
|
596
|
+
function executionRuntimeFromError(error) {
|
|
597
|
+
if (error && typeof error === "object" && "executionRuntime" in error && isJavaScriptExecutionRuntime(error.executionRuntime)) return error.executionRuntime;
|
|
598
|
+
}
|
|
599
|
+
function isJavaScriptExecutionRuntime(value) {
|
|
600
|
+
return value === "vm" || value === "worker" || value === "iframe";
|
|
446
601
|
}
|
|
447
602
|
function isTimeout(error) {
|
|
448
603
|
return Boolean(error && typeof error === "object" && "code" in error && error.code === "ERR_SCRIPT_EXECUTION_TIMEOUT");
|
|
@@ -709,9 +864,12 @@ async function runTypeScript(request) {
|
|
|
709
864
|
const stdio = new StdioBuffer(tracker.startedAt);
|
|
710
865
|
tracker.start("compile", "Strip types");
|
|
711
866
|
const javascript = stripTypeScript(request.code);
|
|
867
|
+
const runtime = currentJavaScriptRuntime();
|
|
868
|
+
let executedRuntime = runtime;
|
|
712
869
|
tracker.start("execute", "Execute");
|
|
713
870
|
try {
|
|
714
|
-
const
|
|
871
|
+
const result = await executeScriptWithRuntime(javascript, request.timeoutMs, stdio, request.signal, runtime);
|
|
872
|
+
executedRuntime = result.runtime;
|
|
715
873
|
tracker.stop();
|
|
716
874
|
return {
|
|
717
875
|
status: "ok",
|
|
@@ -722,14 +880,10 @@ async function runTypeScript(request) {
|
|
|
722
880
|
host: "local",
|
|
723
881
|
runtime: "strip-types"
|
|
724
882
|
},
|
|
725
|
-
execute:
|
|
726
|
-
host: "local",
|
|
727
|
-
runtime: hasNodeVm() ? "node:vm" : "iframe",
|
|
728
|
-
sandbox: hasNodeVm() ? "vm" : "srcdoc"
|
|
729
|
-
}
|
|
883
|
+
execute: javascriptRuntimeProvenance(executedRuntime)
|
|
730
884
|
},
|
|
731
885
|
timing: tracker.report(),
|
|
732
|
-
value: value === void 0 ? void 0 : String(value)
|
|
886
|
+
value: result.value === void 0 ? void 0 : String(result.value)
|
|
733
887
|
};
|
|
734
888
|
} catch (error) {
|
|
735
889
|
if (isAbortError(error) || request.signal?.aborted) throw error;
|
|
@@ -749,11 +903,7 @@ async function runTypeScript(request) {
|
|
|
749
903
|
host: "local",
|
|
750
904
|
runtime: "strip-types"
|
|
751
905
|
},
|
|
752
|
-
execute:
|
|
753
|
-
host: "local",
|
|
754
|
-
runtime: hasNodeVm() ? "node:vm" : "iframe",
|
|
755
|
-
sandbox: hasNodeVm() ? "vm" : "srcdoc"
|
|
756
|
-
}
|
|
906
|
+
execute: javascriptRuntimeProvenance(executedRuntime)
|
|
757
907
|
},
|
|
758
908
|
timing: tracker.report()
|
|
759
909
|
};
|
|
@@ -926,9 +1076,12 @@ function errorMessage(error) {
|
|
|
926
1076
|
}
|
|
927
1077
|
function friendlyTransportMessage(error) {
|
|
928
1078
|
const message = errorMessage(error);
|
|
929
|
-
if ((error
|
|
1079
|
+
if (isOfflineError(error)) return "The executor is offline or unreachable from this page (for example, CORS). Set endpoints to a host that allows browser POST, or use the Vite dev proxy.";
|
|
930
1080
|
return message;
|
|
931
1081
|
}
|
|
1082
|
+
function transportFailureStatus(error) {
|
|
1083
|
+
return isOfflineError(error) ? "offline" : "error";
|
|
1084
|
+
}
|
|
932
1085
|
function errorResult(message, source = "code-play", status = "error") {
|
|
933
1086
|
return withStdioText({
|
|
934
1087
|
status,
|
|
@@ -942,6 +1095,14 @@ function errorResult(message, source = "code-play", status = "error") {
|
|
|
942
1095
|
timing: emptyTiming()
|
|
943
1096
|
});
|
|
944
1097
|
}
|
|
1098
|
+
function isOfflineError(error) {
|
|
1099
|
+
const message = errorMessage(error);
|
|
1100
|
+
const name = error && typeof error === "object" && "name" in error ? String(error.name) : void 0;
|
|
1101
|
+
const typeError = error instanceof TypeError || name === "TypeError";
|
|
1102
|
+
if (name === "MissingTransportError") return true;
|
|
1103
|
+
if (typeError && /failed to fetch|networkerror|load failed|network request failed/i.test(message)) return true;
|
|
1104
|
+
return /\boffline\b|no code play transport|network request failed/i.test(message);
|
|
1105
|
+
}
|
|
945
1106
|
//#endregion
|
|
946
1107
|
//#region src/session.ts
|
|
947
1108
|
var CodePlaySession = class {
|
|
@@ -961,6 +1122,7 @@ var CodePlaySession = class {
|
|
|
961
1122
|
timeoutMs;
|
|
962
1123
|
transport;
|
|
963
1124
|
endpoints;
|
|
1125
|
+
project;
|
|
964
1126
|
loadTypeScript;
|
|
965
1127
|
listeners = /* @__PURE__ */ new Map();
|
|
966
1128
|
abort;
|
|
@@ -972,6 +1134,7 @@ var CodePlaySession = class {
|
|
|
972
1134
|
this.timeoutMs = input.timeoutMs;
|
|
973
1135
|
this.transport = input.transport;
|
|
974
1136
|
this.endpoints = input.endpoints;
|
|
1137
|
+
this.project = input.project;
|
|
975
1138
|
this.loadTypeScript = input.loadTypeScript;
|
|
976
1139
|
}
|
|
977
1140
|
on(event, listener) {
|
|
@@ -1012,6 +1175,7 @@ var CodePlaySession = class {
|
|
|
1012
1175
|
transport: this.transport,
|
|
1013
1176
|
loadTypeScript: this.loadTypeScript,
|
|
1014
1177
|
endpoints: this.endpoints,
|
|
1178
|
+
project: this.project,
|
|
1015
1179
|
signal
|
|
1016
1180
|
};
|
|
1017
1181
|
try {
|
|
@@ -1019,7 +1183,7 @@ var CodePlaySession = class {
|
|
|
1019
1183
|
return this.finish(result);
|
|
1020
1184
|
} catch (error) {
|
|
1021
1185
|
if (signal.aborted || isAbortError(error)) return this.finish(errorResult("Run cancelled.", "code-play", "cancelled"));
|
|
1022
|
-
return this.finish(errorResult(friendlyTransportMessage(error)));
|
|
1186
|
+
return this.finish(errorResult(friendlyTransportMessage(error), "code-play", transportFailureStatus(error)));
|
|
1023
1187
|
}
|
|
1024
1188
|
}
|
|
1025
1189
|
finish(result) {
|