From fff8df03b1428e98e4f56c256c860999753bdecd Mon Sep 17 00:00:00 2001 From: Christopher Serr Date: Wed, 6 Nov 2024 00:34:10 +0100 Subject: [PATCH] Support the `web` Target of `wasm-bindgen` (#852) This emits the bindings in a way such that they are compatible with not only the `bundler` target of `wasm-bindgen`, but also the `web` target. This allows us to circumvent `webpack`, which means we are not limited by the features it supports anymore. In particular, this unblocks the usage of reference types. --- capi/bind_gen/src/main.rs | 34 +++++++++++++-- capi/bind_gen/src/wasm_bindgen.rs | 69 +++++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 11 deletions(-) diff --git a/capi/bind_gen/src/main.rs b/capi/bind_gen/src/main.rs index 27b4be0d..ad27e94a 100644 --- a/capi/bind_gen/src/main.rs +++ b/capi/bind_gen/src/main.rs @@ -312,12 +312,38 @@ fn write_files(classes: &BTreeMap, opt: &Opt) -> Result<()> { path.push("wasm_bindgen"); create_dir_all(&path)?; { - path.push("index.js"); - wasm_bindgen::write(BufWriter::new(File::create(&path)?), classes, false)?; + path.push("bundler"); + create_dir_all(&path)?; + { + path.push("index.js"); + wasm_bindgen::write(BufWriter::new(File::create(&path)?), classes, false, true)?; + path.pop(); + + path.push("index.ts"); + wasm_bindgen::write(BufWriter::new(File::create(&path)?), classes, true, true)?; + path.pop(); + } path.pop(); - path.push("index.ts"); - wasm_bindgen::write(BufWriter::new(File::create(&path)?), classes, true)?; + path.push("web"); + create_dir_all(&path)?; + { + path.push("index.js"); + wasm_bindgen::write(BufWriter::new(File::create(&path)?), classes, false, false)?; + path.pop(); + + path.push("index.ts"); + wasm_bindgen::write(BufWriter::new(File::create(&path)?), classes, true, false)?; + path.pop(); + + path.push("preload.js"); + wasm_bindgen::write_preload(BufWriter::new(File::create(&path)?), false)?; + path.pop(); + + path.push("preload.ts"); + wasm_bindgen::write_preload(BufWriter::new(File::create(&path)?), true)?; + path.pop(); + } path.pop(); } path.pop(); diff --git a/capi/bind_gen/src/wasm_bindgen.rs b/capi/bind_gen/src/wasm_bindgen.rs index bac3fae4..da3673f8 100644 --- a/capi/bind_gen/src/wasm_bindgen.rs +++ b/capi/bind_gen/src/wasm_bindgen.rs @@ -336,19 +336,60 @@ fn write_fn(mut writer: W, function: &Function, type_script: bool) -> Ok(()) } +pub fn write_preload(mut writer: W, type_script: bool) -> Result<()> { + let content = if type_script { + r#"import init, { InitOutput } from "./livesplit_core.js"; + +let promise: Promise | null = null; +export async function preloadWasm(): Promise { + if (!promise) { + promise = init(); + } + return await promise; +}"# + } else { + r#"import init from "./livesplit_core.js + +let promise = null; +export async function preloadWasm() { + if (!promise) { + promise = init(); + } + return await promise; +}"# + }; + writeln!(writer, "{content}") +} + pub fn write( mut writer: W, classes: &BTreeMap, type_script: bool, + bundler: bool, ) -> Result<()> { if type_script { + if bundler { + writeln!( + writer, + "{}", + r#"// tslint:disable +import * as wasm from "./livesplit_core_bg.wasm"; +import "./livesplit_core.js";"# + )?; + } else { + writeln!( + writer, + "{}", + r#"// tslint:disable +import { preloadWasm } from "./preload"; + +const wasm = await preloadWasm();"# + )?; + } writeln!( writer, "{}{}", - r#"// tslint:disable -import * as wasm from "./livesplit_core_bg.wasm"; -import "./livesplit_core.js"; - + r#" const encoder = new TextEncoder(); const decoder = new TextDecoder(); @@ -402,12 +443,26 @@ function dealloc(slice: Slice) { typescript::HEADER, )?; } else { + if bundler { + writeln!( + writer, + "{}", + r#"import * as wasm from "./livesplit_core_bg.wasm"; +import "./livesplit_core.js";"# + )?; + } else { + writeln!( + writer, + "{}", + r#"import { preloadWasm } from "./preload"; + +const wasm = await preloadWasm();"# + )?; + } writeln!( writer, "{}", - r#"import * as wasm from "./livesplit_core_bg.wasm"; -import "./livesplit_core.js"; - + r#" const encoder = new TextEncoder(); const decoder = new TextDecoder();