@@ -36,6 +36,9 @@ struct Js {
3636 /// Type script definitions which will become the export object
3737 export_object : wit_bindgen_core:: Source ,
3838
39+ /// Core module count
40+ core_module_cnt : usize ,
41+
3942 /// Various options for code generation.
4043 opts : Opts ,
4144
@@ -48,35 +51,34 @@ struct Js {
4851pub struct Opts {
4952 /// Disables generation of `*.d.ts` files and instead only generates `*.js`
5053 /// source files.
51- #[ cfg_attr( feature = "clap" , arg( long = "no-typescript" ) ) ]
54+ #[ cfg_attr( feature = "clap" , arg( long) ) ]
5255 pub no_typescript : bool ,
5356 /// Provide a custom JS instantiation API for the component instead
5457 /// of the direct importable native ESM output.
5558 #[ cfg_attr(
5659 feature = "clap" ,
5760 arg(
58- long = "instantiation" ,
61+ long,
5962 short = 'I' ,
6063 conflicts_with = "compatibility" ,
6164 conflicts_with = "compat"
6265 )
6366 ) ]
6467 pub instantiation : bool ,
68+ /// Inline core WebAssembly modules as base64 strings.
69+ #[ cfg_attr( feature = "clap" , arg( long, conflicts_with = "instantiation" ) ) ]
70+ pub base64 : bool ,
6571 /// Comma-separated list of "from-specifier=./to-specifier.js" mappings of
6672 /// component import specifiers to JS import specifiers.
67- #[ cfg_attr( feature = "clap" , arg( long = "map" ) , clap( value_parser = maps_str_to_map) ) ]
73+ #[ cfg_attr( feature = "clap" , arg( long) , clap( value_parser = maps_str_to_map) ) ]
6874 pub map : Option < HashMap < String , String > > ,
6975 /// Enables all compat flags: --nodejs-compat.
70- #[ cfg_attr( feature = "clap" , arg( long = "compat" ) ) ]
76+ #[ cfg_attr( feature = "clap" , arg( long) ) ]
7177 pub compat : bool ,
7278 /// Enables compatibility in Node.js without a fetch global.
7379 #[ cfg_attr(
7480 feature = "clap" ,
75- arg(
76- long = "nodejs-compat" ,
77- group = "compatibility" ,
78- conflicts_with = "compat"
79- )
81+ arg( long, group = "compatibility" , conflicts_with = "compat" )
8082 ) ]
8183 pub nodejs_compat : bool ,
8284}
@@ -183,6 +185,8 @@ impl ComponentGenerator for Js {
183185 modules : & PrimaryMap < StaticModuleIndex , ModuleTranslation < ' _ > > ,
184186 interfaces : & ComponentInterfaces ,
185187 ) {
188+ self . core_module_cnt = modules. len ( ) ;
189+
186190 // Generate the TypeScript definition of the `instantiate` function
187191 // which is the main workhorse of the generated bindings.
188192 if self . opts . instantiation {
@@ -257,6 +261,21 @@ impl ComponentGenerator for Js {
257261 }
258262 }
259263
264+ if self . opts . base64 && self . core_module_cnt > 0 {
265+ let mut first = true ;
266+ output. push_str ( "const " ) ;
267+ for i in 0 ..self . core_module_cnt {
268+ if first {
269+ first = false ;
270+ } else {
271+ output. push_str ( ", " ) ;
272+ }
273+ let data = files. remove ( & self . core_file_name ( name, i as u32 ) ) . unwrap ( ) ;
274+ uwrite ! ( output, "BINARY{i} = '{}'" , base64:: encode( & data) ) ;
275+ }
276+ output. push_str ( ";" ) ;
277+ }
278+
260279 output. push_str ( & self . src . js ) ;
261280
262281 let mut bytes = output. as_bytes ( ) ;
@@ -426,7 +445,17 @@ impl Js {
426445 const dataView = mem => dv.buffer === mem.buffer ? dv : dv = new DataView(mem.buffer);
427446 " ) ,
428447
429- Intrinsic :: LoadWasm => if self . opts . nodejs_compat {
448+ Intrinsic :: LoadWasm => if self . opts . base64 {
449+ if self . opts . nodejs_compat {
450+ self . src . js ( "
451+ const loadWasm = str => WebAssembly.compile(typeof Buffer !== 'undefined' ? Buffer.from(str, 'base64') : Uint8Array.from(atob(str), b => b.charCodeAt(0)));
452+ " )
453+ } else {
454+ self . src . js ( "
455+ const loadWasm = str => WebAssembly.compile(Uint8Array.from(atob(str), b => b.charCodeAt(0)));
456+ " )
457+ }
458+ } else if self . opts . nodejs_compat {
430459 self . src . js ( "
431460 const isNode = typeof process !== 'undefined' && process.versions && process.versions.node;
432461 let _fs;
@@ -723,12 +752,19 @@ impl Instantiator<'_> {
723752 }
724753
725754 let local_name = format ! ( "module{}" , idx. as_u32( ) ) ;
726- let name = self . gen . core_file_name ( & self . name , * idx) ;
755+ let name = self . gen . core_file_name ( & self . name , idx. as_u32 ( ) ) ;
727756 if self . gen . opts . instantiation {
728757 uwrite ! (
729758 self . src. js,
730759 "const {local_name} = compileCore(\" {name}\" );\n "
731760 ) ;
761+ } else if self . gen . opts . base64 {
762+ let load_wasm = self . gen . intrinsic ( Intrinsic :: LoadWasm ) ;
763+ let idx_num = idx. as_u32 ( ) ;
764+ uwrite ! (
765+ self . src. js,
766+ "const {local_name} = {load_wasm}(BINARY{idx_num});\n "
767+ ) ;
732768 } else {
733769 let load_wasm = self . gen . intrinsic ( Intrinsic :: LoadWasm ) ;
734770 uwrite ! (
0 commit comments