@ttsc/playground 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +2 -2
- package/lib/src/compiler/loadTypiaSourcePack.d.ts +4 -4
- package/lib/src/compiler/loadTypiaSourcePack.js +7 -28
- package/lib/src/compiler/loadTypiaSourcePack.js.map +1 -1
- package/lib/src/index.d.ts +2 -2
- package/lib/src/index.js +1 -3
- package/lib/src/index.js.map +1 -1
- package/lib/src/sandbox/loadTypiaRuntimePack.d.ts +4 -4
- package/lib/src/sandbox/loadTypiaRuntimePack.js +7 -25
- package/lib/src/sandbox/loadTypiaRuntimePack.js.map +1 -1
- package/lib/src/structures/IInstallTypiaSourcePackOptions.d.ts +0 -2
- package/lib/src/structures/ILoadTypiaRuntimePackOptions.d.ts +1 -3
- package/package.json +3 -3
- package/src/compiler/loadTypiaSourcePack.ts +7 -36
- package/src/index.ts +2 -8
- package/src/react/ConsoleViewer.tsx +121 -121
- package/src/react/DependencyProgressModal.tsx +73 -73
- package/src/react/DiagnosticsPanel.tsx +74 -74
- package/src/react/ExamplePicker.tsx +93 -93
- package/src/react/LintPane.tsx +58 -58
- package/src/react/OptionsPanel.tsx +132 -132
- package/src/react/ResultViewer.tsx +75 -75
- package/src/react/SourceEditor.tsx +95 -95
- package/src/sandbox/loadTypiaRuntimePack.ts +7 -33
- package/src/structures/IInstallTypiaSourcePackOptions.ts +0 -2
- package/src/structures/ILoadTypiaRuntimePackOptions.ts +1 -3
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import Editor from "@monaco-editor/react";
|
|
4
|
-
import { useEffect, useRef, useState } from "react";
|
|
5
|
-
|
|
6
|
-
interface ResultViewerProps {
|
|
7
|
-
language: "typescript" | "javascript" | "json";
|
|
8
|
-
value: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Read-only Monaco pane used to render the compiled / transformed output with a
|
|
13
|
-
* copy button. Wraps `<Editor readOnly>` and adds the toast UI.
|
|
14
|
-
*/
|
|
15
|
-
export function ResultViewer({ language, value }: ResultViewerProps) {
|
|
16
|
-
const [copied, setCopied] = useState(false);
|
|
17
|
-
const copiedTimer = useRef<number | null>(null);
|
|
18
|
-
|
|
19
|
-
useEffect(
|
|
20
|
-
() => () => {
|
|
21
|
-
if (copiedTimer.current !== null)
|
|
22
|
-
window.clearTimeout(copiedTimer.current);
|
|
23
|
-
},
|
|
24
|
-
[],
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
const onCopy = () => {
|
|
28
|
-
void navigator.clipboard.writeText(value);
|
|
29
|
-
setCopied(true);
|
|
30
|
-
if (copiedTimer.current !== null) window.clearTimeout(copiedTimer.current);
|
|
31
|
-
copiedTimer.current = window.setTimeout(() => {
|
|
32
|
-
setCopied(false);
|
|
33
|
-
copiedTimer.current = null;
|
|
34
|
-
}, 1500);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<div className="relative h-full w-full">
|
|
39
|
-
{value && (
|
|
40
|
-
<button
|
|
41
|
-
onClick={onCopy}
|
|
42
|
-
className="absolute right-3 top-2 z-10 rounded-md border border-[#b9d5ee] bg-white/90 px-2 py-1 font-mono text-[10px] text-[#235a97] shadow-sm transition-colors hover:bg-[#eaf4ff]"
|
|
43
|
-
>
|
|
44
|
-
{copied ? "Copied ✓" : "Copy"}
|
|
45
|
-
</button>
|
|
46
|
-
)}
|
|
47
|
-
<Editor
|
|
48
|
-
height="100%"
|
|
49
|
-
language={language}
|
|
50
|
-
theme="vs"
|
|
51
|
-
value={value}
|
|
52
|
-
path={`output.${
|
|
53
|
-
language === "typescript"
|
|
54
|
-
? "ts"
|
|
55
|
-
: language === "javascript"
|
|
56
|
-
? "js"
|
|
57
|
-
: "json"
|
|
58
|
-
}`}
|
|
59
|
-
options={{
|
|
60
|
-
readOnly: true,
|
|
61
|
-
tabSize: 2,
|
|
62
|
-
minimap: { enabled: false },
|
|
63
|
-
padding: { top: 12, bottom: 12 },
|
|
64
|
-
fontSize: 13,
|
|
65
|
-
fontFamily:
|
|
66
|
-
"ui-monospace, SFMono-Regular, 'JetBrains Mono', 'Fira Code', Consolas, monospace",
|
|
67
|
-
smoothScrolling: true,
|
|
68
|
-
scrollBeyondLastLine: false,
|
|
69
|
-
renderLineHighlight: "none",
|
|
70
|
-
wordWrap: "on",
|
|
71
|
-
}}
|
|
72
|
-
/>
|
|
73
|
-
</div>
|
|
74
|
-
);
|
|
75
|
-
}
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import Editor from "@monaco-editor/react";
|
|
4
|
+
import { useEffect, useRef, useState } from "react";
|
|
5
|
+
|
|
6
|
+
interface ResultViewerProps {
|
|
7
|
+
language: "typescript" | "javascript" | "json";
|
|
8
|
+
value: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Read-only Monaco pane used to render the compiled / transformed output with a
|
|
13
|
+
* copy button. Wraps `<Editor readOnly>` and adds the toast UI.
|
|
14
|
+
*/
|
|
15
|
+
export function ResultViewer({ language, value }: ResultViewerProps) {
|
|
16
|
+
const [copied, setCopied] = useState(false);
|
|
17
|
+
const copiedTimer = useRef<number | null>(null);
|
|
18
|
+
|
|
19
|
+
useEffect(
|
|
20
|
+
() => () => {
|
|
21
|
+
if (copiedTimer.current !== null)
|
|
22
|
+
window.clearTimeout(copiedTimer.current);
|
|
23
|
+
},
|
|
24
|
+
[],
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const onCopy = () => {
|
|
28
|
+
void navigator.clipboard.writeText(value);
|
|
29
|
+
setCopied(true);
|
|
30
|
+
if (copiedTimer.current !== null) window.clearTimeout(copiedTimer.current);
|
|
31
|
+
copiedTimer.current = window.setTimeout(() => {
|
|
32
|
+
setCopied(false);
|
|
33
|
+
copiedTimer.current = null;
|
|
34
|
+
}, 1500);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div className="relative h-full w-full">
|
|
39
|
+
{value && (
|
|
40
|
+
<button
|
|
41
|
+
onClick={onCopy}
|
|
42
|
+
className="absolute right-3 top-2 z-10 rounded-md border border-[#b9d5ee] bg-white/90 px-2 py-1 font-mono text-[10px] text-[#235a97] shadow-sm transition-colors hover:bg-[#eaf4ff]"
|
|
43
|
+
>
|
|
44
|
+
{copied ? "Copied ✓" : "Copy"}
|
|
45
|
+
</button>
|
|
46
|
+
)}
|
|
47
|
+
<Editor
|
|
48
|
+
height="100%"
|
|
49
|
+
language={language}
|
|
50
|
+
theme="vs"
|
|
51
|
+
value={value}
|
|
52
|
+
path={`output.${
|
|
53
|
+
language === "typescript"
|
|
54
|
+
? "ts"
|
|
55
|
+
: language === "javascript"
|
|
56
|
+
? "js"
|
|
57
|
+
: "json"
|
|
58
|
+
}`}
|
|
59
|
+
options={{
|
|
60
|
+
readOnly: true,
|
|
61
|
+
tabSize: 2,
|
|
62
|
+
minimap: { enabled: false },
|
|
63
|
+
padding: { top: 12, bottom: 12 },
|
|
64
|
+
fontSize: 13,
|
|
65
|
+
fontFamily:
|
|
66
|
+
"ui-monospace, SFMono-Regular, 'JetBrains Mono', 'Fira Code', Consolas, monospace",
|
|
67
|
+
smoothScrolling: true,
|
|
68
|
+
scrollBeyondLastLine: false,
|
|
69
|
+
renderLineHighlight: "none",
|
|
70
|
+
wordWrap: "on",
|
|
71
|
+
}}
|
|
72
|
+
/>
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import Editor, { type Monaco } from "@monaco-editor/react";
|
|
4
|
-
import { useCallback, useEffect, useMemo, useRef } from "react";
|
|
5
|
-
|
|
6
|
-
import { DEFAULT_PLAYGROUND_COMPILER_OPTIONS } from "../compiler/DEFAULT_PLAYGROUND_COMPILER_OPTIONS";
|
|
7
|
-
import type { ISourceEditorProps } from "../structures/ISourceEditorProps";
|
|
8
|
-
|
|
9
|
-
export function SourceEditor({
|
|
10
|
-
value,
|
|
11
|
-
onChange,
|
|
12
|
-
extraLibs,
|
|
13
|
-
path = "file:///src/playground.ts",
|
|
14
|
-
}: ISourceEditorProps) {
|
|
15
|
-
const monacoRef = useRef<Monaco | null>(null);
|
|
16
|
-
const libDisposables = useRef<{ dispose(): void }[]>([]);
|
|
17
|
-
const allExtraLibs = useMemo(
|
|
18
|
-
() => (extraLibs ? Object.entries(extraLibs) : []),
|
|
19
|
-
[extraLibs],
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
const installExtraLibs = useCallback(
|
|
23
|
-
(monaco: Monaco) => {
|
|
24
|
-
for (const disposable of libDisposables.current) disposable.dispose();
|
|
25
|
-
libDisposables.current = [];
|
|
26
|
-
const tsd = monaco.languages.typescript.typescriptDefaults;
|
|
27
|
-
for (const [file, content] of allExtraLibs) {
|
|
28
|
-
libDisposables.current.push(tsd.addExtraLib(content, file));
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
[allExtraLibs],
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
if (monacoRef.current) installExtraLibs(monacoRef.current);
|
|
36
|
-
return () => {
|
|
37
|
-
for (const disposable of libDisposables.current) disposable.dispose();
|
|
38
|
-
libDisposables.current = [];
|
|
39
|
-
};
|
|
40
|
-
}, [installExtraLibs]);
|
|
41
|
-
|
|
42
|
-
const handleMount = (_editor: unknown, monaco: Monaco) => {
|
|
43
|
-
monacoRef.current = monaco;
|
|
44
|
-
const tsd = monaco.languages.typescript.typescriptDefaults;
|
|
45
|
-
tsd.setCompilerOptions({
|
|
46
|
-
target: monaco.languages.typescript.ScriptTarget.ESNext,
|
|
47
|
-
module: monaco.languages.typescript.ModuleKind.ESNext,
|
|
48
|
-
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
|
|
49
|
-
esModuleInterop: DEFAULT_PLAYGROUND_COMPILER_OPTIONS.esModuleInterop,
|
|
50
|
-
strict: DEFAULT_PLAYGROUND_COMPILER_OPTIONS.strict,
|
|
51
|
-
experimentalDecorators:
|
|
52
|
-
DEFAULT_PLAYGROUND_COMPILER_OPTIONS.experimentalDecorators,
|
|
53
|
-
allowNonTsExtensions: true,
|
|
54
|
-
// External .d.ts packs (typia, etc.) routinely reference transitive types
|
|
55
|
-
// Monaco cannot reach (deep paths in JSDoc, optional peers). skipLibCheck
|
|
56
|
-
// keeps the editor lean by not type-checking the lib pack.
|
|
57
|
-
skipLibCheck: true,
|
|
58
|
-
});
|
|
59
|
-
tsd.setDiagnosticsOptions({
|
|
60
|
-
noSemanticValidation: false,
|
|
61
|
-
noSyntaxValidation: false,
|
|
62
|
-
diagnosticCodesToIgnore: [
|
|
63
|
-
// 2307: Cannot find module — JSDoc-only stubbed deps still occasionally
|
|
64
|
-
// leak through Monaco's module resolution.
|
|
65
|
-
2307,
|
|
66
|
-
],
|
|
67
|
-
});
|
|
68
|
-
installExtraLibs(monaco);
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
return (
|
|
72
|
-
<Editor
|
|
73
|
-
height="100%"
|
|
74
|
-
defaultLanguage="typescript"
|
|
75
|
-
theme="vs"
|
|
76
|
-
value={value}
|
|
77
|
-
onChange={(v) => onChange(v ?? "")}
|
|
78
|
-
onMount={handleMount}
|
|
79
|
-
path={path}
|
|
80
|
-
options={{
|
|
81
|
-
tabSize: 2,
|
|
82
|
-
minimap: { enabled: false },
|
|
83
|
-
padding: { top: 12, bottom: 12 },
|
|
84
|
-
fontSize: 13,
|
|
85
|
-
fontFamily:
|
|
86
|
-
"ui-monospace, SFMono-Regular, 'JetBrains Mono', 'Fira Code', Consolas, monospace",
|
|
87
|
-
smoothScrolling: true,
|
|
88
|
-
cursorBlinking: "smooth",
|
|
89
|
-
scrollBeyondLastLine: false,
|
|
90
|
-
renderLineHighlight: "line",
|
|
91
|
-
wordWrap: "on",
|
|
92
|
-
}}
|
|
93
|
-
/>
|
|
94
|
-
);
|
|
95
|
-
}
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import Editor, { type Monaco } from "@monaco-editor/react";
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef } from "react";
|
|
5
|
+
|
|
6
|
+
import { DEFAULT_PLAYGROUND_COMPILER_OPTIONS } from "../compiler/DEFAULT_PLAYGROUND_COMPILER_OPTIONS";
|
|
7
|
+
import type { ISourceEditorProps } from "../structures/ISourceEditorProps";
|
|
8
|
+
|
|
9
|
+
export function SourceEditor({
|
|
10
|
+
value,
|
|
11
|
+
onChange,
|
|
12
|
+
extraLibs,
|
|
13
|
+
path = "file:///src/playground.ts",
|
|
14
|
+
}: ISourceEditorProps) {
|
|
15
|
+
const monacoRef = useRef<Monaco | null>(null);
|
|
16
|
+
const libDisposables = useRef<{ dispose(): void }[]>([]);
|
|
17
|
+
const allExtraLibs = useMemo(
|
|
18
|
+
() => (extraLibs ? Object.entries(extraLibs) : []),
|
|
19
|
+
[extraLibs],
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const installExtraLibs = useCallback(
|
|
23
|
+
(monaco: Monaco) => {
|
|
24
|
+
for (const disposable of libDisposables.current) disposable.dispose();
|
|
25
|
+
libDisposables.current = [];
|
|
26
|
+
const tsd = monaco.languages.typescript.typescriptDefaults;
|
|
27
|
+
for (const [file, content] of allExtraLibs) {
|
|
28
|
+
libDisposables.current.push(tsd.addExtraLib(content, file));
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
[allExtraLibs],
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (monacoRef.current) installExtraLibs(monacoRef.current);
|
|
36
|
+
return () => {
|
|
37
|
+
for (const disposable of libDisposables.current) disposable.dispose();
|
|
38
|
+
libDisposables.current = [];
|
|
39
|
+
};
|
|
40
|
+
}, [installExtraLibs]);
|
|
41
|
+
|
|
42
|
+
const handleMount = (_editor: unknown, monaco: Monaco) => {
|
|
43
|
+
monacoRef.current = monaco;
|
|
44
|
+
const tsd = monaco.languages.typescript.typescriptDefaults;
|
|
45
|
+
tsd.setCompilerOptions({
|
|
46
|
+
target: monaco.languages.typescript.ScriptTarget.ESNext,
|
|
47
|
+
module: monaco.languages.typescript.ModuleKind.ESNext,
|
|
48
|
+
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
|
|
49
|
+
esModuleInterop: DEFAULT_PLAYGROUND_COMPILER_OPTIONS.esModuleInterop,
|
|
50
|
+
strict: DEFAULT_PLAYGROUND_COMPILER_OPTIONS.strict,
|
|
51
|
+
experimentalDecorators:
|
|
52
|
+
DEFAULT_PLAYGROUND_COMPILER_OPTIONS.experimentalDecorators,
|
|
53
|
+
allowNonTsExtensions: true,
|
|
54
|
+
// External .d.ts packs (typia, etc.) routinely reference transitive types
|
|
55
|
+
// Monaco cannot reach (deep paths in JSDoc, optional peers). skipLibCheck
|
|
56
|
+
// keeps the editor lean by not type-checking the lib pack.
|
|
57
|
+
skipLibCheck: true,
|
|
58
|
+
});
|
|
59
|
+
tsd.setDiagnosticsOptions({
|
|
60
|
+
noSemanticValidation: false,
|
|
61
|
+
noSyntaxValidation: false,
|
|
62
|
+
diagnosticCodesToIgnore: [
|
|
63
|
+
// 2307: Cannot find module — JSDoc-only stubbed deps still occasionally
|
|
64
|
+
// leak through Monaco's module resolution.
|
|
65
|
+
2307,
|
|
66
|
+
],
|
|
67
|
+
});
|
|
68
|
+
installExtraLibs(monaco);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<Editor
|
|
73
|
+
height="100%"
|
|
74
|
+
defaultLanguage="typescript"
|
|
75
|
+
theme="vs"
|
|
76
|
+
value={value}
|
|
77
|
+
onChange={(v) => onChange(v ?? "")}
|
|
78
|
+
onMount={handleMount}
|
|
79
|
+
path={path}
|
|
80
|
+
options={{
|
|
81
|
+
tabSize: 2,
|
|
82
|
+
minimap: { enabled: false },
|
|
83
|
+
padding: { top: 12, bottom: 12 },
|
|
84
|
+
fontSize: 13,
|
|
85
|
+
fontFamily:
|
|
86
|
+
"ui-monospace, SFMono-Regular, 'JetBrains Mono', 'Fira Code', Consolas, monospace",
|
|
87
|
+
smoothScrolling: true,
|
|
88
|
+
cursorBlinking: "smooth",
|
|
89
|
+
scrollBeyondLastLine: false,
|
|
90
|
+
renderLineHighlight: "line",
|
|
91
|
+
wordWrap: "on",
|
|
92
|
+
}}
|
|
93
|
+
/>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
@@ -13,9 +13,8 @@ interface RuntimePackEntry {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
interface RuntimePackCancellationReason {
|
|
16
|
-
kind: "abort"
|
|
16
|
+
kind: "abort";
|
|
17
17
|
reason?: unknown;
|
|
18
|
-
timeoutMs?: number;
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
interface RuntimePackCancellation {
|
|
@@ -23,25 +22,23 @@ interface RuntimePackCancellation {
|
|
|
23
22
|
dispose: () => void;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
export const DEFAULT_RUNTIME_PACK_TIMEOUT_MS = 30_000;
|
|
27
|
-
|
|
28
25
|
const packCache = new Map<string, RuntimePackEntry>();
|
|
29
26
|
|
|
30
27
|
/**
|
|
31
28
|
* Fetches the prebuilt runtime pack once per URL.
|
|
32
29
|
*
|
|
33
|
-
* Concurrent callers share one load. A caller abort
|
|
34
|
-
*
|
|
35
|
-
*
|
|
30
|
+
* Concurrent callers share one load. A caller abort cancels that shared
|
|
31
|
+
* attempt; rejection removes it from the cache so the next call retries from
|
|
32
|
+
* scratch. Successful packs remain cached. Nothing else ends the load: how long
|
|
33
|
+
* a fetch takes belongs to the network, not to a number chosen here.
|
|
36
34
|
*/
|
|
37
35
|
export function loadTypiaRuntimePack(
|
|
38
36
|
url: string,
|
|
39
37
|
options: ILoadTypiaRuntimePackOptions = {},
|
|
40
38
|
): Promise<Record<string, string>> {
|
|
41
|
-
const timeoutMs = resolveRuntimePackTimeout(options.timeoutMs);
|
|
42
39
|
const cached = packCache.get(url);
|
|
43
40
|
if (cached) {
|
|
44
|
-
attachRuntimePackCancellation(cached, options.signal
|
|
41
|
+
attachRuntimePackCancellation(cached, options.signal);
|
|
45
42
|
return cached.promise;
|
|
46
43
|
}
|
|
47
44
|
|
|
@@ -80,23 +77,13 @@ export function loadTypiaRuntimePack(
|
|
|
80
77
|
|
|
81
78
|
entry = { controller, promise };
|
|
82
79
|
packCache.set(url, entry);
|
|
83
|
-
attachRuntimePackCancellation(entry, options.signal
|
|
80
|
+
attachRuntimePackCancellation(entry, options.signal);
|
|
84
81
|
return promise;
|
|
85
82
|
}
|
|
86
83
|
|
|
87
|
-
function resolveRuntimePackTimeout(timeoutMs: number | undefined): number {
|
|
88
|
-
const value = timeoutMs ?? DEFAULT_RUNTIME_PACK_TIMEOUT_MS;
|
|
89
|
-
if (!Number.isSafeInteger(value) || value <= 0 || value > 2_147_483_647)
|
|
90
|
-
throw new RangeError(
|
|
91
|
-
"loadTypiaRuntimePack: timeoutMs must be a positive integer no greater than 2147483647.",
|
|
92
|
-
);
|
|
93
|
-
return value;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
84
|
function attachRuntimePackCancellation(
|
|
97
85
|
entry: RuntimePackEntry,
|
|
98
86
|
callerSignal: AbortSignal | undefined,
|
|
99
|
-
timeoutMs: number,
|
|
100
87
|
): void {
|
|
101
88
|
const abortFromCaller = (): void => {
|
|
102
89
|
if (!entry.controller.signal.aborted)
|
|
@@ -108,15 +95,7 @@ function attachRuntimePackCancellation(
|
|
|
108
95
|
if (callerSignal?.aborted) abortFromCaller();
|
|
109
96
|
else callerSignal?.addEventListener("abort", abortFromCaller, { once: true });
|
|
110
97
|
|
|
111
|
-
const timer = setTimeout(() => {
|
|
112
|
-
if (!entry.controller.signal.aborted)
|
|
113
|
-
entry.controller.abort({
|
|
114
|
-
kind: "timeout",
|
|
115
|
-
timeoutMs,
|
|
116
|
-
} satisfies RuntimePackCancellationReason);
|
|
117
|
-
}, timeoutMs);
|
|
118
98
|
const cleanup = (): void => {
|
|
119
|
-
clearTimeout(timer);
|
|
120
99
|
callerSignal?.removeEventListener("abort", abortFromCaller);
|
|
121
100
|
};
|
|
122
101
|
void entry.promise.then(cleanup, cleanup);
|
|
@@ -160,11 +139,6 @@ function runtimePackCancellationError(
|
|
|
160
139
|
phase: string,
|
|
161
140
|
): Error {
|
|
162
141
|
const reason = signal.reason as RuntimePackCancellationReason | undefined;
|
|
163
|
-
if (reason?.kind === "timeout")
|
|
164
|
-
return new Error(
|
|
165
|
-
`loadTypiaRuntimePack: timed out after ${reason.timeoutMs}ms while ${phase}.`,
|
|
166
|
-
);
|
|
167
|
-
|
|
168
142
|
const error = new Error(`loadTypiaRuntimePack: aborted while ${phase}.`);
|
|
169
143
|
const cause = reason?.kind === "abort" ? reason.reason : signal.reason;
|
|
170
144
|
if (cause !== undefined) (error as Error & { cause?: unknown }).cause = cause;
|
|
@@ -12,8 +12,6 @@ export interface IInstallTypiaSourcePackOptions {
|
|
|
12
12
|
mountRoot?: string;
|
|
13
13
|
/** Cancel the shared in-flight load. */
|
|
14
14
|
signal?: AbortSignal;
|
|
15
|
-
/** Maximum fetch and JSON-read time. Defaults to 30 seconds. */
|
|
16
|
-
timeoutMs?: number;
|
|
17
15
|
/**
|
|
18
16
|
* Optional fetcher. Defaults to `globalThis.fetch`. Override for tests or for
|
|
19
17
|
* sites that want their own caching strategy.
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
/** Cancellation
|
|
1
|
+
/** Cancellation policy for `loadTypiaRuntimePack`. */
|
|
2
2
|
export interface ILoadTypiaRuntimePackOptions {
|
|
3
3
|
/** Cancel the shared in-flight load. */
|
|
4
4
|
signal?: AbortSignal;
|
|
5
|
-
/** Maximum fetch and JSON-read time. Defaults to 30 seconds. */
|
|
6
|
-
timeoutMs?: number;
|
|
7
5
|
}
|