@@ -3,6 +3,11 @@ import { EditorSystem } from './editor.js';
33import ts from 'typescript' ;
44import { TypeProcessor } from './processor.js' ;
55import { CodeShareManager } from './code-share.js' ;
6+ import {
7+ createSystem ,
8+ createDefaultMapFromCDN ,
9+ createVirtualCompilerHost
10+ } from '@typescript/vfs' ;
611
712/**
813 * @typedef {import('../../.build/plugins/PackageToJS/outputs/Package/bridge-js.js').PlayBridgeJS } PlayBridgeJS
@@ -38,6 +43,14 @@ export class BridgeJSPlayground {
3843 this . copyButton = /** @type {HTMLButtonElement } */ ( document . getElementById ( 'copyButton' ) ) ;
3944 /** @type {HTMLButtonElement } */
4045 this . closeShareDialogButton = /** @type {HTMLButtonElement } */ ( document . getElementById ( 'closeShareDialog' ) ) ;
46+
47+ // Progress UI elements
48+ /** @type {HTMLDivElement | null } */
49+ this . progressBar = /** @type {HTMLDivElement } */ ( document . getElementById ( 'progressBar' ) ) ;
50+ /** @type {HTMLDivElement | null } */
51+ this . progressFill = /** @type {HTMLDivElement } */ ( document . getElementById ( 'progressFill' ) ) ;
52+ /** @type {HTMLDivElement | null } */
53+ this . progressLabel = /** @type {HTMLDivElement } */ ( document . getElementById ( 'progressLabel' ) ) ;
4154 }
4255
4356 /**
@@ -50,44 +63,53 @@ export class BridgeJSPlayground {
5063 }
5164
5265 try {
66+ this . showProgress ( 'Starting…' , 5 ) ;
5367 // Initialize editor system
5468 await this . editorSystem . init ( ) ;
69+ this . setProgress ( 'Editor ready' , 30 ) ;
5570
5671 // Initialize BridgeJS
5772 await this . initializeBridgeJS ( ) ;
73+ this . setProgress ( 'BridgeJS ready' , 70 ) ;
5874
5975 // Set up event listeners
6076 this . setupEventListeners ( ) ;
6177
6278 // Check for shared code in URL
79+ this . setProgress ( 'Checking shared code…' , 80 ) ;
6380 const sharedCode = await CodeShareManager . extractCodeFromUrl ( ) ;
6481 if ( sharedCode ) {
6582 this . editorSystem . setInputs ( sharedCode ) ;
6683 } else {
6784 // Load sample code
6885 this . editorSystem . setInputs ( sampleCode ) ;
6986 }
70-
87+ this . setProgress ( 'Finalizing…' , 95 ) ;
7188 this . isInitialized = true ;
7289 console . log ( 'BridgeJS Playground initialized successfully' ) ;
90+ this . setProgress ( 'Ready' , 100 ) ;
91+ setTimeout ( ( ) => this . hideProgress ( ) , 400 ) ;
7392 } catch ( error ) {
7493 console . error ( 'Failed to initialize BridgeJS Playground:' , error ) ;
7594 this . showError ( 'Failed to initialize application: ' + error . message ) ;
95+ this . hideProgress ( ) ;
7696 }
7797 }
7898
7999 // Initialize BridgeJS
80100 async initializeBridgeJS ( ) {
81101 try {
82102 // Import the BridgeJS module
103+ this . setProgress ( 'Loading BridgeJS…' , 50 ) ;
83104 const { init } = await import ( "../../.build/plugins/PackageToJS/outputs/Package/index.js" ) ;
105+ const virtualHost = await this . createTS2SkeletonFactory ( ) ;
106+ this . setProgress ( 'Preparing TypeScript host…' , 60 ) ;
84107 const { exports } = await init ( {
85- getImports : ( ) => {
86- return {
87- createTS2Skeleton : this . createTS2Skeleton
88- } ;
89- }
108+ getImports : ( ) => ( {
109+ createTS2Skeleton : ( ) => this . createTS2Skeleton ( virtualHost )
110+ } )
90111 } ) ;
112+ this . setProgress ( 'Creating runtime…' , 65 ) ;
91113 this . playBridgeJS = new exports . PlayBridgeJS ( ) ;
92114 console . log ( 'BridgeJS initialized successfully' ) ;
93115 } catch ( error ) {
@@ -171,32 +193,44 @@ export class BridgeJSPlayground {
171193 } ) ;
172194 }
173195
174- createTS2Skeleton ( ) {
196+ async createTS2SkeletonFactory ( ) {
197+ const createVirtualHost = async ( ) => {
198+ const fsMap = await createDefaultMapFromCDN (
199+ { target : ts . ScriptTarget . ES2015 } ,
200+ ts . version ,
201+ true ,
202+ ts
203+ ) ;
204+
205+ const system = createSystem ( fsMap ) ;
206+
207+ const compilerOptions = {
208+ target : ts . ScriptTarget . ES2015 ,
209+ lib : [ "es2015" , "dom" ] ,
210+ } ;
211+
212+ return createVirtualCompilerHost ( system , compilerOptions , ts ) ;
213+ }
214+ return await createVirtualHost ( ) ;
215+ }
216+
217+ /**
218+ * @param {ReturnType<typeof createVirtualCompilerHost> } virtualHost
219+ */
220+ createTS2Skeleton ( virtualHost ) {
175221 return {
222+ /**
223+ * @param {string } dtsCode
224+ * @returns {string }
225+ */
176226 convert : ( dtsCode ) => {
177- const virtualFilePath = "bridge-js.d.ts"
178- const virtualHost = {
179- fileExists : fileName => fileName === virtualFilePath ,
180- readFile : fileName => dtsCode ,
181- getSourceFile : ( fileName , languageVersion ) => {
182- const sourceText = dtsCode ;
183- if ( sourceText === undefined ) return undefined ;
184- return ts . createSourceFile ( fileName , sourceText , languageVersion ) ;
185- } ,
186- getDefaultLibFileName : options => "lib.d.ts" ,
187- writeFile : ( fileName , data ) => {
188- console . log ( `[emit] ${ fileName } :\n${ data } ` ) ;
189- } ,
190- getCurrentDirectory : ( ) => "" ,
191- getDirectories : ( ) => [ ] ,
192- getCanonicalFileName : fileName => fileName ,
193- getNewLine : ( ) => "\n" ,
194- useCaseSensitiveFileNames : ( ) => true
195- }
196227 // Create TypeScript program from d.ts content
228+ const virtualFilePath = "bridge-js.d.ts"
229+ const sourceFile = ts . createSourceFile ( virtualFilePath , dtsCode , ts . ScriptTarget . ES2015 ) ;
230+ virtualHost . updateFile ( sourceFile ) ;
197231 const tsProgram = ts . createProgram ( {
198232 rootNames : [ virtualFilePath ] ,
199- host : virtualHost ,
233+ host : virtualHost . compilerHost ,
200234 options : {
201235 noEmit : true ,
202236 declaration : true ,
@@ -268,4 +302,42 @@ export class BridgeJSPlayground {
268302 hideError ( ) {
269303 this . errorDisplay . classList . remove ( 'show' ) ;
270304 }
305+
306+ /**
307+ * Shows progress bar.
308+ * @param {string } label
309+ * @param {number } percent
310+ */
311+ showProgress ( label , percent ) {
312+ if ( this . progressBar ) {
313+ this . progressBar . classList . add ( 'show' ) ;
314+ this . progressBar . classList . remove ( 'hidden' ) ;
315+ }
316+ this . setProgress ( label , percent ) ;
317+ }
318+
319+ /**
320+ * Updates progress label and percentage.
321+ * @param {string } label
322+ * @param {number } percent
323+ */
324+ setProgress ( label , percent ) {
325+ if ( this . progressLabel ) {
326+ this . progressLabel . textContent = label ;
327+ }
328+ if ( this . progressFill ) {
329+ const clamped = Math . max ( 0 , Math . min ( 100 , Number ( percent ) || 0 ) ) ;
330+ this . progressFill . style . width = clamped + '%' ;
331+ }
332+ }
333+
334+ /**
335+ * Hides progress bar.
336+ */
337+ hideProgress ( ) {
338+ if ( this . progressBar ) {
339+ this . progressBar . classList . remove ( 'show' ) ;
340+ this . progressBar . classList . add ( 'hidden' ) ;
341+ }
342+ }
271343}
0 commit comments