88 useCallback ,
99 useContext ,
1010 useEffect ,
11+ useRef ,
1112 useState ,
1213} from "react" ;
1314import { useEmbedContext } from "../embedContext" ;
@@ -16,18 +17,21 @@ import { RuntimeContext } from "../runtime";
1617
1718export const compilerOptions : CompilerOptions = { } ;
1819
19- const TypeScriptContext = createContext < VirtualTypeScriptEnvironment | null > (
20- null
21- ) ;
20+ const TypeScriptContext = createContext < {
21+ init : ( ) => void ;
22+ tsEnv : VirtualTypeScriptEnvironment | null ;
23+ } > ( { init : ( ) => undefined , tsEnv : null } ) ;
2224export function TypeScriptProvider ( { children } : { children : ReactNode } ) {
2325 const [ tsEnv , setTSEnv ] = useState < VirtualTypeScriptEnvironment | null > ( null ) ;
24-
25- useEffect ( ( ) => {
26- // useEffectはサーバーサイドでは実行されないが、
26+ const initializing = useRef ( false ) ;
27+ const init = useCallback ( ( ) => {
28+ if ( initializing . current ) {
29+ return ;
30+ }
31+ initializing . current = true ;
2732 // typeof window !== "undefined" でガードしないとなぜかesbuildが"typescript"を
2833 // サーバーサイドでのインポート対象とみなしてしまう。
2934 if ( tsEnv === null && typeof window !== "undefined" ) {
30- const abortController = new AbortController ( ) ;
3135 ( async ( ) => {
3236 const ts = await import ( "typescript" ) ;
3337 const vfs = await import ( "@typescript/vfs" ) ;
@@ -39,8 +43,7 @@ export function TypeScriptProvider({ children }: { children: ReactNode }) {
3943 const libFileContents = await Promise . all (
4044 libFiles . map ( async ( libFile ) => {
4145 const response = await fetch (
42- `/typescript/${ ts . version } /${ libFile } ` ,
43- { signal : abortController . signal }
46+ `/typescript/${ ts . version } /${ libFile } `
4447 ) ;
4548 if ( response . ok ) {
4649 return response . text ( ) ;
@@ -63,20 +66,17 @@ export function TypeScriptProvider({ children }: { children: ReactNode }) {
6366 ) ;
6467 setTSEnv ( env ) ;
6568 } ) ( ) ;
66- return ( ) => {
67- abortController . abort ( ) ;
68- } ;
6969 }
7070 } , [ tsEnv , setTSEnv ] ) ;
7171 return (
72- < TypeScriptContext . Provider value = { tsEnv } >
72+ < TypeScriptContext . Provider value = { { init , tsEnv } } >
7373 { children }
7474 </ TypeScriptContext . Provider >
7575 ) ;
7676}
7777
7878export function useTypeScript ( jsEval : RuntimeContext ) : RuntimeContext {
79- const tsEnv = useContext ( TypeScriptContext ) ;
79+ const { init , tsEnv } = useContext ( TypeScriptContext ) ;
8080
8181 const { writeFile } = useEmbedContext ( ) ;
8282 const runFiles = useCallback (
@@ -139,6 +139,7 @@ export function useTypeScript(jsEval: RuntimeContext): RuntimeContext {
139139 [ tsEnv , writeFile , jsEval ]
140140 ) ;
141141 return {
142+ init,
142143 ready : tsEnv !== null ,
143144 runFiles,
144145 getCommandlineStr,
0 commit comments