@@ -51,6 +51,17 @@ const DEFAULT_AOT_CACHE = fileURLToPath(
5151 new URL ( `../lib/starlingmonkey_ics.wevalcache` , import . meta. url ) ,
5252) ;
5353
54+ /** Default settings for debug options */
55+ const DEFAULT_DEBUG_SETTINGS = {
56+ bindings : false ,
57+ bindingsDir : null ,
58+
59+ binary : false ,
60+ binaryPath : null ,
61+
62+ wizerLogging : false ,
63+ } ;
64+
5465function maybeWindowsPath ( path ) {
5566 if ( ! path ) return path ;
5667 if ( ! IS_WINDOWS ) return resolve ( path ) ;
@@ -96,13 +107,21 @@ export async function componentize(
96107 worldName,
97108 disableFeatures = [ ] ,
98109 enableFeatures = [ ] ,
110+
111+ debug = { ...DEFAULT_DEBUG_SETTINGS } ,
99112 debugBuild = false ,
100- runtimeArgs,
101113 debugBindings = false ,
102114 enableWizerLogging = false ,
115+
116+ runtimeArgs,
117+
103118 aotCache = DEFAULT_AOT_CACHE ,
104119 } = opts ;
105120
121+ debugBindings = debugBindings || debug ?. bindings ;
122+ debugBuild = debugBuild || debug ?. build ;
123+ enableWizerLogging = enableWizerLogging || debug ?. enableWizerLogging ;
124+
106125 // Determine the path to the StarlingMonkey binary
107126 const engine = getEnginePath ( opts ) ;
108127
@@ -121,27 +140,52 @@ export async function componentize(
121140 await writeFile ( join ( sourcesDir , 'initializer.js' ) , jsBindings ) ;
122141
123142 if ( debugBindings ) {
124- console . log ( '--- JS Bindings ---' ) ;
125- console . log (
126- jsBindings
127- . split ( '\n' )
128- . map ( ( ln , idx ) => `${ ( idx + 1 ) . toString ( ) . padStart ( 4 , ' ' ) } | ${ ln } ` )
129- . join ( '\n' ) ,
130- ) ;
131- console . log ( '--- JS Imports ---' ) ;
132- console . log ( imports ) ;
133- console . log ( '--- JS Exports ---' ) ;
134- console . log ( exports ) ;
143+ // If a bindings output directory was specified, output generated bindings to files
144+ if ( debug ?. bindingsDir ) {
145+ console . error ( `outputting debug files to [${ debug ?. bindingsDir } ]...\n` ) ;
146+ // Ensure the debug bindings dir exists, and is a directory
147+ if ( ! ( await stat ( debug ?. bindingsDir ) . then ( ( s ) => s . isDirectory ( ) ) ) ) {
148+ throw new Error (
149+ `Missing/invalid debug bindings directory [${ debug ?. bindingsDir } ]` ,
150+ ) ;
151+ }
152+ // Write debug to bindings debug directory
153+ await Promise . all ( [
154+ writeFile ( join ( debug ?. bindingsDir , 'source.debug.js' ) , jsSource ) ,
155+ writeFile ( join ( debug ?. bindingsDir , 'bindings.debug.js' ) , jsBindings ) ,
156+ writeFile (
157+ join ( debug ?. bindingsDir , 'imports.debug.json' ) ,
158+ JSON . stringify ( imports , null , 2 ) ,
159+ ) ,
160+ writeFile (
161+ join ( debug ?. bindingsDir , 'exports.debug.json' ) ,
162+ JSON . stringify ( exports , null , 2 ) ,
163+ ) ,
164+ ] ) ;
165+ } else {
166+ // If a bindings output directory was not specified, output to stdout
167+ console . error ( '--- JS Bindings ---' ) ;
168+ console . error (
169+ jsBindings
170+ . split ( '\n' )
171+ . map ( ( ln , idx ) => `${ ( idx + 1 ) . toString ( ) . padStart ( 4 , ' ' ) } | ${ ln } ` )
172+ . join ( '\n' ) ,
173+ ) ;
174+ console . error ( '--- JS Imports ---' ) ;
175+ console . error ( imports ) ;
176+ console . error ( '--- JS Exports ---' ) ;
177+ console . error ( exports ) ;
178+ }
135179 }
136180
137181 if ( ! useOriginalSourceFile ) {
138182 if ( debugBindings ) {
139- console . log ( `> Writing JS source to ${ tmpDir } /sources` ) ;
183+ console . error ( `> Writing JS source to ${ tmpDir } /sources` ) ;
140184 }
141185 await writeFile ( sourcePath , jsSource ) ;
142186 }
143187
144- // we never disable a feature that is already in the target world usage
188+ // We never disable a feature that is already in the target world usage
145189 const features = [ ] ;
146190 if ( ! disableFeatures . includes ( 'stdio' ) ) {
147191 features . push ( 'stdio' ) ;
@@ -185,8 +229,8 @@ export async function componentize(
185229 env [ 'IMPORT_CNT' ] = imports . length ;
186230
187231 if ( debugBindings ) {
188- console . log ( '--- Wizer Env ---' ) ;
189- console . log ( env ) ;
232+ console . error ( '--- Wizer Env ---' ) ;
233+ console . error ( env ) ;
190234 }
191235
192236 let initializerPath = join ( sourcesDir , 'initializer.js' ) ;
@@ -208,17 +252,18 @@ export async function componentize(
208252 sourcePath = sourcePath . slice ( workspacePrefix . length + 1 ) ;
209253 }
210254 }
255+
211256 let args = `--initializer-script-path ${ initializerPath } --strip-path-prefix ${ workspacePrefix } / ${ sourcePath } ` ;
212257 runtimeArgs = runtimeArgs ? `${ runtimeArgs } ${ args } ` : args ;
258+
213259 let preopens = [ `--dir ${ sourcesDir } ` ] ;
214260 if ( opts . enableAot ) {
215261 preopens . push ( `--dir ${ workspacePrefix } ` ) ;
216262 } else {
217263 preopens . push ( `--mapdir /::${ workspacePrefix } ` ) ;
218264 }
219265
220- let wizerProcess ;
221-
266+ let postProcess ;
222267 if ( opts . enableAot ) {
223268 // Determine the weval bin path, possibly using a pre-downloaded version
224269 let wevalBin ;
@@ -240,7 +285,7 @@ export async function componentize(
240285 env . RUST_MIN_STACK = defaultMinStackSize ( ) ;
241286 }
242287
243- wizerProcess = spawnSync (
288+ postProcess = spawnSync (
244289 wevalBin ,
245290 [
246291 'weval' ,
@@ -261,7 +306,7 @@ export async function componentize(
261306 } ,
262307 ) ;
263308 } else {
264- wizerProcess = spawnSync (
309+ postProcess = spawnSync (
265310 wizer ,
266311 [
267312 '--allow-wasi' ,
@@ -283,11 +328,12 @@ export async function componentize(
283328 ) ;
284329 }
285330
286- if ( wizerProcess . status !== 0 ) {
287- let wizerErr = parseWizerStderr ( wizerProcess . stderr ) ;
331+ // If the wizer (or weval) process failed, parse the output and display to the user
332+ if ( postProcess . status !== 0 ) {
333+ let wizerErr = parseWizerStderr ( postProcess . stderr ) ;
288334 let err = `Failed to initialize component:\n${ wizerErr } ` ;
289335 if ( debugBindings ) {
290- err += `\n\nBinary and sources available for debugging at ${ tmpDir } \n` ;
336+ err += `\n\nBinary and sources available for debugging at ${ workDir } \n` ;
291337 } else {
292338 await rm ( workDir , { recursive : true } ) ;
293339 }
@@ -312,7 +358,7 @@ export async function componentize(
312358 /// Process output of check init, throwing if necessary
313359 handleCheckInitOutput ( check_init ( ) , initializerPath , workDir , getStderr ) ;
314360
315- // after wizening, stub out the wasi imports depending on what features are enabled
361+ // After wizening, stub out the wasi imports depending on what features are enabled
316362 const finalBin = stubWasi (
317363 bin ,
318364 features ,
@@ -339,14 +385,26 @@ export async function componentize(
339385 } ) ,
340386 ) ;
341387
342- // convert CABI import conventions to ESM import conventions
388+ // Convert CABI import conventions to ESM import conventions
343389 imports = imports . map ( ( [ specifier , impt ] ) =>
344390 specifier === '$root' ? [ impt , 'default' ] : [ specifier , impt ] ,
345391 ) ;
346392
393+ // Build debug object to return
394+ let debugOutput ;
395+ if ( debugBindings ) {
396+ debugOutput . bindings = debug . bindings ;
397+ debugOutput . workDir = workDir ;
398+ }
399+ if ( debug ?. binary ) {
400+ debugOutput . binary = debug . binary ;
401+ debugOutput . binaryPath = debug . binaryPath ;
402+ }
403+
347404 return {
348405 component,
349406 imports,
407+ debug : debugOutput ,
350408 } ;
351409}
352410
0 commit comments