@@ -55,40 +55,65 @@ export class Ghostty {
5555
5656 /**
5757 * Load Ghostty WASM from URL or file path
58+ * If no path is provided, attempts to load from common default locations
5859 */
59- static async load ( wasmPath : string ) : Promise < Ghostty > {
60- let wasmBytes : ArrayBuffer ;
60+ static async load ( wasmPath ?: string ) : Promise < Ghostty > {
61+ // Default WASM paths to try (in order)
62+ const defaultPaths = [
63+ // When published as npm package
64+ new URL ( '../ghostty-vt.wasm' , import . meta. url ) . href ,
65+ // When used from CDN or local dev
66+ './ghostty-vt.wasm' ,
67+ '/ghostty-vt.wasm' ,
68+ ] ;
69+
70+ const pathsToTry = wasmPath ? [ wasmPath ] : defaultPaths ;
71+ let lastError : Error | null = null ;
72+
73+ for ( const path of pathsToTry ) {
74+ try {
75+ let wasmBytes : ArrayBuffer ;
76+
77+ // Try loading as file first (for Node/Bun environments)
78+ try {
79+ const fs = await import ( 'fs/promises' ) ;
80+ const buffer = await fs . readFile ( path ) ;
81+ wasmBytes = buffer . buffer . slice ( buffer . byteOffset , buffer . byteOffset + buffer . byteLength ) ;
82+ } catch ( e ) {
83+ // Fall back to fetch (for browser environments)
84+ const response = await fetch ( path ) ;
85+ if ( ! response . ok ) {
86+ throw new Error ( `Failed to fetch WASM: ${ response . status } ${ response . statusText } ` ) ;
87+ }
88+ wasmBytes = await response . arrayBuffer ( ) ;
89+ if ( wasmBytes . byteLength === 0 ) {
90+ throw new Error ( `WASM file is empty (0 bytes). Check path: ${ path } ` ) ;
91+ }
92+ }
6193
62- // Try loading as file first (for Node/Bun environments)
63- try {
64- const fs = await import ( 'fs/promises' ) ;
65- const buffer = await fs . readFile ( wasmPath ) ;
66- wasmBytes = buffer . buffer . slice ( buffer . byteOffset , buffer . byteOffset + buffer . byteLength ) ;
67- } catch ( e ) {
68- // Fall back to fetch (for browser environments)
69- const response = await fetch ( wasmPath ) ;
70- if ( ! response . ok ) {
71- throw new Error ( `Failed to fetch WASM: ${ response . status } ${ response . statusText } ` ) ;
72- }
73- wasmBytes = await response . arrayBuffer ( ) ;
74- if ( wasmBytes . byteLength === 0 ) {
75- throw new Error ( `WASM file is empty (0 bytes). Check path: ${ wasmPath } ` ) ;
94+ // Successfully loaded, instantiate and return
95+ const wasmModule = await WebAssembly . instantiate ( wasmBytes , {
96+ env : {
97+ // Stub out C runtime functions (not used by libghostty-vt)
98+ } ,
99+ } ) ;
100+
101+ return new Ghostty ( wasmModule . instance ) ;
102+ } catch ( e ) {
103+ lastError = e instanceof Error ? e : new Error ( String ( e ) ) ;
104+ // Try next path
105+ continue ;
76106 }
77107 }
78108
79- const wasmModule = await WebAssembly . instantiate ( wasmBytes , {
80- env : {
81- log : ( ptr : number , len : number ) => {
82- const instance = ( wasmModule as any ) . instance ;
83- const bytes = new Uint8Array ( instance . exports . memory . buffer , ptr , len ) ;
84- const text = new TextDecoder ( ) . decode ( bytes ) ;
85- console . log ( '[ghostty-wasm]' , text ) ;
86- } ,
87- } ,
88- } ) ;
89-
90- return new Ghostty ( wasmModule . instance ) ;
109+ // All paths failed
110+ throw new Error (
111+ `Failed to load ghostty-vt.wasm. Tried paths: ${ pathsToTry . join ( ', ' ) } . ` +
112+ `Last error: ${ lastError ?. message } . ` +
113+ `You can specify a custom path with: new Terminal({ wasmPath: './path/to/ghostty-vt.wasm' })`
114+ ) ;
91115 }
116+
92117}
93118
94119/**
0 commit comments