diff --git a/packages/website/src/components/Playground.tsx b/packages/website/src/components/Playground.tsx index f3c13bee498b..d6ddcb5efe19 100644 --- a/packages/website/src/components/Playground.tsx +++ b/packages/website/src/components/Playground.tsx @@ -152,6 +152,7 @@ function Playground(): React.JSX.Element { onMarkersChange={setMarkers} onSelect={setPosition} selectedRange={selectedRange} + setState={setState} /> diff --git a/packages/website/src/components/editor/useSandboxServices.ts b/packages/website/src/components/editor/useSandboxServices.ts index d3a6e7fc00e3..5f52c33358f6 100644 --- a/packages/website/src/components/editor/useSandboxServices.ts +++ b/packages/website/src/components/editor/useSandboxServices.ts @@ -7,7 +7,7 @@ import semverSatisfies from 'semver/functions/satisfies'; import type { createTypeScriptSandbox } from '../../vendor/sandbox'; import type { CreateLinter } from '../linter/createLinter'; import type { PlaygroundSystem } from '../linter/types'; -import type { RuleDetails } from '../types'; +import type { ConfigModel, RuleDetails } from '../types'; import type { CommonEditorProps } from './types'; import rootPackageJson from '../../../../../package.json'; @@ -23,6 +23,7 @@ export interface SandboxServicesProps { ruleDetails: RuleDetails[], tsVersions: readonly string[], ) => void; + readonly setState: (value: Partial) => void; readonly ts: string; } @@ -34,6 +35,23 @@ export interface SandboxServices { webLinter: CreateLinter; } +const checkUseSupportedTypescriptVersion = async (tsVersion: string) => { + const supportedVersionsResponse = await fetch( + 'https://typescript.azureedge.net/indexes/releases.json', + ); + + if (supportedVersionsResponse.ok) { + const supportedVersions = (await supportedVersionsResponse.json()) as { + versions: string[]; + }; + const filteredVersions = supportedVersions.versions.filter(item => + semverSatisfies(item, rootPackageJson.devDependencies.typescript), + ); + return filteredVersions.includes(tsVersion); + } + return false; +}; + export const useSandboxServices = ( props: CommonEditorProps & SandboxServicesProps, ): Error | SandboxServices | undefined => { @@ -44,107 +62,122 @@ export const useSandboxServices = ( useEffect(() => { let sandboxInstance: SandboxInstance | undefined; - sandboxSingleton(props.ts) - .then(async ({ lintUtils, main, sandboxFactory }) => { - const compilerOptions = createCompilerOptions(); - - sandboxInstance = sandboxFactory.createTypeScriptSandbox( - { - acquireTypes: true, - compilerOptions: - compilerOptions as Monaco.languages.typescript.CompilerOptions, - domID: editorEmbedId, - monacoSettings: { - autoIndent: 'full', - fontSize: 13, - formatOnPaste: true, - formatOnType: true, - hover: { above: false }, - minimap: { enabled: false }, - scrollBeyondLastLine: false, - smoothScrolling: true, - wordWrap: 'off', - wrappingIndent: 'same', - }, - text: props.code, - }, - main, - window.ts, - ); - sandboxInstance.monaco.editor.setTheme( - colorMode === 'dark' ? 'vs-dark' : 'vs-light', - ); - - sandboxInstance.monaco.languages.registerInlayHintsProvider( - sandboxInstance.language, - createTwoslashInlayProvider(sandboxInstance), - ); - - const system = createFileSystem(props, sandboxInstance.tsvfs); - - // Write files in vfs when a model is created in the editor (this is used only for ATA types) - sandboxInstance.monaco.editor.onDidCreateModel(model => { - if (!model.uri.path.includes('node_modules')) { - return; - } - const path = model.uri.path.replace('/file:///', '/'); - system.writeFile(path, model.getValue()); - }); - // Delete files in vfs when a model is disposed in the editor (this is used only for ATA types) - sandboxInstance.monaco.editor.onWillDisposeModel(model => { - if (!model.uri.path.includes('node_modules')) { - return; - } - const path = model.uri.path.replace('/file:///', '/'); - system.deleteFile(path); - }); - - // Load the lib files from typescript to vfs (eg. es2020.d.ts) - const worker = await sandboxInstance.getWorkerProcess(); - if (worker.getLibFiles) { - const libs = await worker.getLibFiles(); - for (const [key, value] of Object.entries(libs)) { - system.writeFile(`/${key}`, value); - } + checkUseSupportedTypescriptVersion(props.ts) + .then(res => { + if (!res) { + props.setState({ ts: process.env.TS_VERSION }); } - - window.system = system; - window.esquery = lintUtils.esquery; - window.visitorKeys = lintUtils.visitorKeys; - - const webLinter = createLinter( - system, - lintUtils, - sandboxInstance.tsvfs, - ); - - onLoaded( - [...webLinter.rules.values()], - [ - ...new Set([ - window.ts.version, - ...sandboxInstance.supportedVersions, - ]), - ] - .filter(item => - semverSatisfies(item, rootPackageJson.devDependencies.typescript), - ) - .sort((a, b) => b.localeCompare(a)), - ); - - setServices({ - sandboxInstance, - system, - webLinter, - }); + }) + .then(() => { + sandboxSingleton(props.ts) + .then(async ({ lintUtils, main, sandboxFactory }) => { + const compilerOptions = createCompilerOptions(); + + sandboxInstance = sandboxFactory.createTypeScriptSandbox( + { + acquireTypes: true, + compilerOptions: + compilerOptions as Monaco.languages.typescript.CompilerOptions, + domID: editorEmbedId, + monacoSettings: { + autoIndent: 'full', + fontSize: 13, + formatOnPaste: true, + formatOnType: true, + hover: { above: false }, + minimap: { enabled: false }, + scrollBeyondLastLine: false, + smoothScrolling: true, + wordWrap: 'off', + wrappingIndent: 'same', + }, + text: props.code, + }, + main, + window.ts, + ); + sandboxInstance.monaco.editor.setTheme( + colorMode === 'dark' ? 'vs-dark' : 'vs-light', + ); + + sandboxInstance.monaco.languages.registerInlayHintsProvider( + sandboxInstance.language, + createTwoslashInlayProvider(sandboxInstance), + ); + + const system = createFileSystem(props, sandboxInstance.tsvfs); + + // Write files in vfs when a model is created in the editor (this is used only for ATA types) + sandboxInstance.monaco.editor.onDidCreateModel(model => { + if (!model.uri.path.includes('node_modules')) { + return; + } + const path = model.uri.path.replace('/file:///', '/'); + system.writeFile(path, model.getValue()); + }); + // Delete files in vfs when a model is disposed in the editor (this is used only for ATA types) + sandboxInstance.monaco.editor.onWillDisposeModel(model => { + if (!model.uri.path.includes('node_modules')) { + return; + } + const path = model.uri.path.replace('/file:///', '/'); + system.deleteFile(path); + }); + + // Load the lib files from typescript to vfs (eg. es2020.d.ts) + const worker = await sandboxInstance.getWorkerProcess(); + if (worker.getLibFiles) { + const libs = await worker.getLibFiles(); + for (const [key, value] of Object.entries(libs)) { + system.writeFile(`/${key}`, value); + } + } + + window.system = system; + window.esquery = lintUtils.esquery; + window.visitorKeys = lintUtils.visitorKeys; + + const webLinter = createLinter( + system, + lintUtils, + sandboxInstance.tsvfs, + ); + + onLoaded( + [...webLinter.rules.values()], + [ + ...new Set([ + window.ts.version, + ...sandboxInstance.supportedVersions, + ]), + ] + .filter(item => + semverSatisfies( + item, + rootPackageJson.devDependencies.typescript, + ), + ) + .sort((a, b) => b.localeCompare(a)), + ); + + setServices({ + sandboxInstance, + system, + webLinter, + }); + }) + .catch((err: unknown) => { + if (err instanceof Error) { + setServices(err); + } else { + setServices(new Error(String(err))); + } + }); }) .catch((err: unknown) => { - if (err instanceof Error) { - setServices(err); - } else { - setServices(new Error(String(err))); - } + console.error(err); }); + return (): void => { if (!sandboxInstance) { return; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy