diff --git a/Cargo.lock b/Cargo.lock index fc5ccc2..f14f41b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -780,6 +780,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "console_log" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f" +dependencies = [ + "log", + "web-sys", +] + [[package]] name = "const_format" version = "0.2.32" @@ -2851,6 +2861,8 @@ dependencies = [ "anyhow", "arm-attr", "byteorder", + "console_error_panic_hook", + "console_log", "cpp_demangle", "cwdemangle", "cwextab", @@ -2876,6 +2888,7 @@ dependencies = [ "serde_yaml", "similar", "strum", + "tsify-next", "unarm", "wasm-bindgen", ] @@ -3860,6 +3873,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_derive" version = "1.0.199" @@ -3871,6 +3895,17 @@ dependencies = [ "syn 2.0.60", ] +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "serde_json" version = "1.0.116" @@ -4447,6 +4482,30 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tsify-next" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4a645dca4ee0800f5ab60ce166deba2db6a0315de795a2691e138a3d55d756" +dependencies = [ + "serde", + "serde-wasm-bindgen", + "tsify-next-macros", + "wasm-bindgen", +] + +[[package]] +name = "tsify-next-macros" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d5c06f8a51d759bb58129e30b2631739e7e1e4579fad1f30ac09a6c88e488a6" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.60", +] + [[package]] name = "ttf-parser" version = "0.20.0" diff --git a/objdiff-core/Cargo.toml b/objdiff-core/Cargo.toml index 605f559..2afa29b 100644 --- a/objdiff-core/Cargo.toml +++ b/objdiff-core/Cargo.toml @@ -23,7 +23,7 @@ mips = ["any-arch", "rabbitizer"] ppc = ["any-arch", "cwdemangle", "cwextab", "ppc750cl"] x86 = ["any-arch", "cpp_demangle", "iced-x86", "msvc-demangler"] arm = ["any-arch", "cpp_demangle", "unarm", "arm-attr"] -wasm = ["serde_json"] +wasm = ["serde_json", "console_error_panic_hook", "console_log"] [dependencies] anyhow = "1.0.82" @@ -40,6 +40,9 @@ serde = { version = "1", features = ["derive"] } similar = { version = "2.5.0", default-features = false } strum = { version = "0.26.2", features = ["derive"] } wasm-bindgen = "0.2.93" +tsify-next = { version = "0.5.4", default-features = false, features = ["js"] } +console_log = { version = "1.0.0", optional = true } +console_error_panic_hook = { version = "0.1.7", optional = true } # config globset = { version = "0.4.14", features = ["serde1"], optional = true } diff --git a/objdiff-core/src/bindings/wasm.rs b/objdiff-core/src/bindings/wasm.rs index 0ed4bc9..1a6be61 100644 --- a/objdiff-core/src/bindings/wasm.rs +++ b/objdiff-core/src/bindings/wasm.rs @@ -1,53 +1,78 @@ -use anyhow::Context; use prost::Message; use wasm_bindgen::prelude::*; use crate::{bindings::diff::DiffResult, diff, obj}; -#[wasm_bindgen] -pub fn run_diff( +fn parse_object( + data: Option>, + config: &diff::DiffObjConfig, +) -> Result, JsError> { + data.as_ref().map(|data| obj::read::parse(data, config)).transpose().to_js() +} + +fn parse_and_run_diff( left: Option>, right: Option>, config: diff::DiffObjConfig, -) -> Result { - let target = left - .as_ref() - .map(|data| obj::read::parse(data, &config).context("Loading target")) - .transpose() - .map_err(|e| JsError::new(&e.to_string()))?; - let base = right - .as_ref() - .map(|data| obj::read::parse(data, &config).context("Loading base")) - .transpose() - .map_err(|e| JsError::new(&e.to_string()))?; - let result = diff::diff_objs(&config, target.as_ref(), base.as_ref(), None) - .map_err(|e| JsError::new(&e.to_string()))?; - let left = target.as_ref().and_then(|o| result.left.as_ref().map(|d| (o, d))); - let right = base.as_ref().and_then(|o| result.right.as_ref().map(|d| (o, d))); - let out = DiffResult::new(left, right); - serde_json::to_string(&out).map_err(|e| JsError::new(&e.to_string())) +) -> Result { + let target = parse_object(left, &config)?; + let base = parse_object(right, &config)?; + run_diff(target.as_ref(), base.as_ref(), config) } +fn run_diff( + left: Option<&obj::ObjInfo>, + right: Option<&obj::ObjInfo>, + config: diff::DiffObjConfig, +) -> Result { + log::debug!("Running diff with config: {:?}", config); + let result = diff::diff_objs(&config, left, right, None).to_js()?; + let left = left.and_then(|o| result.left.as_ref().map(|d| (o, d))); + let right = right.and_then(|o| result.right.as_ref().map(|d| (o, d))); + Ok(DiffResult::new(left, right)) +} + +// #[wasm_bindgen] +// pub fn run_diff_json( +// left: Option>, +// right: Option>, +// config: diff::DiffObjConfig, +// ) -> Result { +// let out = run_diff_opt_box(left, right, config)?; +// serde_json::to_string(&out).map_err(|e| JsError::new(&e.to_string())) +// } + #[wasm_bindgen] pub fn run_diff_proto( left: Option>, right: Option>, config: diff::DiffObjConfig, ) -> Result, JsError> { - let target = left - .as_ref() - .map(|data| obj::read::parse(data, &config).context("Loading target")) - .transpose() - .map_err(|e| JsError::new(&e.to_string()))?; - let base = right - .as_ref() - .map(|data| obj::read::parse(data, &config).context("Loading base")) - .transpose() - .map_err(|e| JsError::new(&e.to_string()))?; - let result = diff::diff_objs(&config, target.as_ref(), base.as_ref(), None) - .map_err(|e| JsError::new(&e.to_string()))?; - let left = target.as_ref().and_then(|o| result.left.as_ref().map(|d| (o, d))); - let right = base.as_ref().and_then(|o| result.right.as_ref().map(|d| (o, d))); - let out = DiffResult::new(left, right); + let out = parse_and_run_diff(left, right, config)?; Ok(out.encode_to_vec().into_boxed_slice()) } + +#[wasm_bindgen(start)] +fn start() -> Result<(), JsError> { + console_error_panic_hook::set_once(); + #[cfg(debug_assertions)] + console_log::init_with_level(log::Level::Debug).to_js()?; + #[cfg(not(debug_assertions))] + console_log::init_with_level(log::Level::Info).to_js()?; + Ok(()) +} + +#[inline] +fn to_js_error(e: impl std::fmt::Display) -> JsError { JsError::new(&e.to_string()) } + +trait ToJsResult { + type Output; + + fn to_js(self) -> Result; +} + +impl ToJsResult for Result { + type Output = T; + + fn to_js(self) -> Result { self.map_err(to_js_error) } +} diff --git a/objdiff-core/src/diff/mod.rs b/objdiff-core/src/diff/mod.rs index a87ff78..caa35b5 100644 --- a/objdiff-core/src/diff/mod.rs +++ b/objdiff-core/src/diff/mod.rs @@ -1,7 +1,6 @@ use std::collections::HashSet; use anyhow::Result; -use wasm_bindgen::prelude::wasm_bindgen; use crate::{ diff::{ @@ -18,7 +17,6 @@ pub mod code; pub mod data; pub mod display; -#[wasm_bindgen] #[derive( Debug, Copy, @@ -30,6 +28,7 @@ pub mod display; serde::Serialize, strum::VariantArray, strum::EnumMessage, + tsify_next::Tsify, )] pub enum X86Formatter { #[default] @@ -43,7 +42,6 @@ pub enum X86Formatter { Masm, } -#[wasm_bindgen] #[derive( Debug, Copy, @@ -55,6 +53,7 @@ pub enum X86Formatter { serde::Serialize, strum::VariantArray, strum::EnumMessage, + tsify_next::Tsify, )] pub enum MipsAbi { #[default] @@ -68,7 +67,6 @@ pub enum MipsAbi { N64, } -#[wasm_bindgen] #[derive( Debug, Copy, @@ -80,6 +78,7 @@ pub enum MipsAbi { serde::Serialize, strum::VariantArray, strum::EnumMessage, + tsify_next::Tsify, )] pub enum MipsInstrCategory { #[default] @@ -97,7 +96,6 @@ pub enum MipsInstrCategory { R5900, } -#[wasm_bindgen] #[derive( Debug, Copy, @@ -109,6 +107,7 @@ pub enum MipsInstrCategory { serde::Serialize, strum::VariantArray, strum::EnumMessage, + tsify_next::Tsify, )] pub enum ArmArchVersion { #[default] @@ -122,7 +121,6 @@ pub enum ArmArchVersion { V6K, } -#[wasm_bindgen] #[derive( Debug, Copy, @@ -134,6 +132,7 @@ pub enum ArmArchVersion { serde::Serialize, strum::VariantArray, strum::EnumMessage, + tsify_next::Tsify, )] pub enum ArmR9Usage { #[default] @@ -154,8 +153,8 @@ pub enum ArmR9Usage { #[inline] const fn default_true() -> bool { true } -#[wasm_bindgen] -#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, tsify_next::Tsify)] +#[tsify(from_wasm_abi)] #[serde(default)] pub struct DiffObjConfig { pub relax_reloc_diffs: bool, @@ -207,9 +206,6 @@ impl DiffObjConfig { } } -#[wasm_bindgen] -pub fn default_diff_obj_config() -> DiffObjConfig { Default::default() } - #[derive(Debug, Clone)] pub struct ObjSectionDiff { pub symbols: Vec, diff --git a/objdiff-wasm/eslint.config.js b/objdiff-wasm/eslint.config.js index d00320c..2019c35 100644 --- a/objdiff-wasm/eslint.config.js +++ b/objdiff-wasm/eslint.config.js @@ -7,5 +7,22 @@ export default [ {languageOptions: {globals: globals.browser}}, pluginJs.configs.recommended, ...tseslint.configs.recommended, - {rules: {"semi": [2, "always"]}}, + { + rules: { + "semi": [2, "always"], + "@typescript-eslint/no-unused-vars": [ + "error", + // https://typescript-eslint.io/rules/no-unused-vars/#benefits-over-typescript + { + "args": "all", + "argsIgnorePattern": "^_", + "caughtErrors": "all", + "caughtErrorsIgnorePattern": "^_", + "destructuredArrayIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "ignoreRestSiblings": true + }, + ], + } + }, ]; \ No newline at end of file diff --git a/objdiff-wasm/package-lock.json b/objdiff-wasm/package-lock.json index d920662..a66f8d3 100644 --- a/objdiff-wasm/package-lock.json +++ b/objdiff-wasm/package-lock.json @@ -1,24 +1,24 @@ { "name": "objdiff-wasm", - "version": "2.0.0-beta.6", + "version": "2.0.0-beta.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "objdiff-wasm", - "version": "2.0.0-beta.6", + "version": "2.0.0-beta.10", "license": "MIT OR Apache-2.0", "dependencies": { - "@protobuf-ts/runtime": "2.9.4" + "@protobuf-ts/runtime": "^2.9.4" }, "devDependencies": { "@eslint/js": "^9.9.0", - "@protobuf-ts/plugin": "2.9.4", - "@types/node": "22.4.1", - "esbuild": "0.23.1", + "@protobuf-ts/plugin": "^2.9.4", + "@types/node": "^22.4.1", + "esbuild": "^0.23.1", "eslint": "^9.9.0", "globals": "^15.9.0", - "tsup": "8.2.4", + "tsup": "^8.2.4", "typescript-eslint": "^8.2.0" } }, diff --git a/objdiff-wasm/package.json b/objdiff-wasm/package.json index 4b9decf..f29a457 100644 --- a/objdiff-wasm/package.json +++ b/objdiff-wasm/package.json @@ -1,6 +1,6 @@ { "name": "objdiff-wasm", - "version": "2.0.0-beta.6", + "version": "2.0.0-beta.10", "description": "A local diffing tool for decompilation projects.", "author": { "name": "Luke Street", @@ -19,21 +19,21 @@ "types": "dist/main.d.ts", "scripts": { "build": "tsup", - "build:all": "npm run build && npm run build:proto && npm run build:wasm", + "build:all": "npm run build:wasm && npm run build:proto && npm run build", "build:proto": "protoc --ts_out=gen --ts_opt add_pb_suffix,eslint_disable,ts_nocheck,use_proto_field_name --proto_path=../objdiff-core/protos ../objdiff-core/protos/*.proto", "build:wasm": "cd ../objdiff-core && wasm-pack build --out-dir ../objdiff-wasm/pkg --target web -- --features arm,dwarf,ppc,x86,wasm" }, "dependencies": { - "@protobuf-ts/runtime": "2.9.4" + "@protobuf-ts/runtime": "^2.9.4" }, "devDependencies": { "@eslint/js": "^9.9.0", - "@protobuf-ts/plugin": "2.9.4", - "@types/node": "22.4.1", - "esbuild": "0.23.1", + "@protobuf-ts/plugin": "^2.9.4", + "@types/node": "^22.4.1", + "esbuild": "^0.23.1", "eslint": "^9.9.0", "globals": "^15.9.0", - "tsup": "8.2.4", + "tsup": "^8.2.4", "typescript-eslint": "^8.2.0" } } diff --git a/objdiff-wasm/src/main.ts b/objdiff-wasm/src/main.ts index 6aab965..0d5ad81 100644 --- a/objdiff-wasm/src/main.ts +++ b/objdiff-wasm/src/main.ts @@ -2,61 +2,94 @@ import {ArgumentValue, DiffResult, InstructionDiff, RelocationTarget} from "../g import type { ArmArchVersion, ArmR9Usage, - DiffObjConfig as WasmDiffObjConfig, + DiffObjConfig, MipsAbi, MipsInstrCategory, X86Formatter } from '../pkg'; -import {InMessage, OutMessage} from './worker'; +import {AnyHandlerData, InMessage, OutMessage} from './worker'; // Export wasm types -export type DiffObjConfig = Omit, 'free'>; -export {ArmArchVersion, ArmR9Usage, MipsAbi, MipsInstrCategory, X86Formatter}; +export {ArmArchVersion, ArmR9Usage, MipsAbi, MipsInstrCategory, X86Formatter, DiffObjConfig}; // Export protobuf types export * from '../gen/diff_pb'; -interface PromiseCallbacks { +interface PromiseCallbacks { start: number; - resolve: (value: unknown) => void; - reject: (reason?: unknown) => void; + resolve: (value: T | PromiseLike) => void; + reject: (reason?: string) => void; } let workerInit = false; -let workerCallbacks: PromiseCallbacks | null = null; +let workerCallbacks: PromiseCallbacks; const workerReady = new Promise((resolve, reject) => { workerCallbacks = {start: performance.now(), resolve, reject}; }); -export function initialize(workerUrl?: string | URL) { +export async function initialize(data?: { + workerUrl?: string | URL, + wasmUrl?: string | URL, // Relative to worker URL +}): Promise { if (workerInit) { - return; + return workerReady; } workerInit = true; - const worker = new Worker(workerUrl || 'worker.js', {type: 'module'}); - worker.onmessage = onMessage.bind(null, worker); - worker.onerror = (error) => { - console.error("Worker error", error); - workerCallbacks.reject(error); + let {workerUrl, wasmUrl} = data || {}; + if (!workerUrl) { + try { + // Bundlers will convert this into an asset URL + workerUrl = new URL('./worker.js', import.meta.url); + } catch (_) { + workerUrl = 'worker.js'; + } + } + if (!wasmUrl) { + try { + // Bundlers will convert this into an asset URL + wasmUrl = new URL('./objdiff_core_bg.wasm', import.meta.url); + } catch (_) { + wasmUrl = 'objdiff_core_bg.js'; + } + } + const worker = new Worker(workerUrl, { + name: 'objdiff', + type: 'module', + }); + worker.onmessage = onMessage; + worker.onerror = (event) => { + console.error("Worker error", event); + workerCallbacks.reject("Worker failed to initialize, wrong URL?"); }; + defer({ + type: 'init', + // URL can't be sent directly + wasmUrl: wasmUrl.toString(), + }, worker).then(() => { + workerCallbacks.resolve(worker); + }, (e) => { + workerCallbacks.reject(e); + }); + return workerReady; } let globalMessageId = 0; -const messageCallbacks = new Map(); +const messageCallbacks = new Map>(); -function onMessage(worker: Worker, event: MessageEvent) { +function onMessage(event: MessageEvent) { switch (event.data.type) { - case 'ready': - workerCallbacks.resolve(worker); - break; case 'result': { - const {messageId, result} = event.data; + const {result, error, messageId} = event.data; const callbacks = messageCallbacks.get(messageId); if (callbacks) { const end = performance.now(); console.debug(`Message ${messageId} took ${end - callbacks.start}ms`); messageCallbacks.delete(messageId); - callbacks.resolve(result); + if (error != null) { + callbacks.reject(error); + } else { + callbacks.resolve(result as never); + } } else { console.warn(`Unknown message ID ${messageId}`); } @@ -65,11 +98,8 @@ function onMessage(worker: Worker, event: MessageEvent) { } } -async function defer(message: Omit): Promise { - if (!workerInit) { - throw new Error('Worker not initialized'); - } - const worker = await workerReady; +async function defer(message: AnyHandlerData, worker?: Worker): Promise { + worker = worker || await initialize(); const messageId = globalMessageId++; const promise = new Promise((resolve, reject) => { messageCallbacks.set(messageId, {start: performance.now(), resolve, reject}); @@ -77,17 +107,17 @@ async function defer(message: Omit): Promise { worker.postMessage({ ...message, messageId - }); + } as InMessage); return promise; } export async function runDiff(left: Uint8Array | undefined, right: Uint8Array | undefined, config?: DiffObjConfig): Promise { const data = await defer({ - type: 'run_diff', + type: 'run_diff_proto', left, right, config - } as InMessage); + }); const parseStart = performance.now(); const result = DiffResult.fromBinary(data, {readUnknownField: false}); const end = performance.now(); @@ -148,11 +178,6 @@ export type DiffTextSpacing = DiffTextBase & { count: number, }; -// TypeScript workaround for oneof types -export function oneof(type: T): T & { oneofKind: string } { - return type as T & { oneofKind: string }; -} - // Native JavaScript implementation of objdiff_core::diff::display::display_diff export function displayDiff(diff: InstructionDiff, baseAddr: bigint, cb: (text: DiffText) => void) { const ins = diff.instruction; @@ -173,7 +198,7 @@ export function displayDiff(diff: InstructionDiff, baseAddr: bigint, cb: (text: if (i === 0) { cb({type: 'spacing', count: 1}); } - const arg = oneof(ins.arguments[i].value); + const arg = ins.arguments[i].value; const diff_index = diff.arg_diff[i]?.diff_index; switch (arg.oneofKind) { case "plain_text": @@ -184,7 +209,7 @@ export function displayDiff(diff: InstructionDiff, baseAddr: bigint, cb: (text: break; case "relocation": { const reloc = ins.relocation!; - cb({type: 'symbol', target: reloc.target, diff_index}); + cb({type: 'symbol', target: reloc.target!, diff_index}); break; } case "branch_dest": diff --git a/objdiff-wasm/src/worker.ts b/objdiff-wasm/src/worker.ts index 3dacce9..c9e78b5 100644 --- a/objdiff-wasm/src/worker.ts +++ b/objdiff-wasm/src/worker.ts @@ -1,81 +1,93 @@ -import wasmInit, {default_diff_obj_config, run_diff_proto} from '../pkg'; -import {DiffObjConfig} from "./main"; +import wasmInit, * as exports from '../pkg'; -self.postMessage({type: 'init'} as OutMessage); -await wasmInit({}); -self.postMessage({type: 'ready'} as OutMessage); - -type ExtractParam = { - [K in keyof T]: T[K] extends (arg1: infer U, ...args: any[]) => any ? U & { type: K } : never; -}[keyof T]; -type HandlerData = ExtractParam<{ - run_diff: typeof run_diff, -}>; -const handlers: { - [K in HandlerData['type']]: (data: Omit) => unknown -} = { - 'run_diff': run_diff, +const handlers = { + init: init, + // run_diff_json: run_diff_json, + run_diff_proto: run_diff_proto, +} as const; +type ExtractData = T extends (arg: infer U) => Promise ? U : never; +type HandlerData = { + [K in keyof typeof handlers]: { type: K } & ExtractData; }; -function run_diff({left, right, config}: { - left: Uint8Array | undefined, - right: Uint8Array | undefined, - config?: DiffObjConfig -}): Uint8Array { - const cfg = default_diff_obj_config(); - if (config) { - for (const key in config) { - if (key in config) { - cfg[key] = config[key]; - } - } +let wasmReady: Promise | null = null; + +async function init({wasmUrl}: { wasmUrl?: string }): Promise { + if (wasmReady != null) { + throw new Error('Already initialized'); } - return run_diff_proto(left, right, cfg); + wasmReady = wasmInit({module_or_path: wasmUrl}) + .then(() => { + }); + return wasmReady; } -export type InMessage = HandlerData & { messageId: number }; +async function initIfNeeded() { + if (wasmReady == null) { + await init({}); + } + return wasmReady; +} -export type OutMessage = ({ +// async function run_diff_json({left, right, config}: { +// left: Uint8Array | undefined, +// right: Uint8Array | undefined, +// config?: exports.DiffObjConfig, +// }): Promise { +// config = config || exports.default_diff_obj_config(); +// return exports.run_diff_json(left, right, cfg); +// } + +async function run_diff_proto({left, right, config}: { + left: Uint8Array | undefined, + right: Uint8Array | undefined, + config?: exports.DiffObjConfig, +}): Promise { + config = config || {}; + return exports.run_diff_proto(left, right, config); +} + +export type AnyHandlerData = HandlerData[keyof HandlerData]; +export type InMessage = AnyHandlerData & { messageId: number }; + +export type OutMessage = { type: 'result', result: unknown | null, - error: unknown | null, -} | { - type: 'init', - msg: string -} | { - type: 'ready', - msg: string -}) & { messageId: number }; + error: string | null, + messageId: number, +}; -self.onmessage = async (event: MessageEvent) => { +self.onmessage = (event: MessageEvent) => { const data = event.data; - const handler = handlers[data.type]; - if (handler) { - try { + const messageId = data?.messageId; + (async () => { + if (!data) { + throw new Error('No data'); + } + const handler = handlers[data.type]; + if (handler) { + if (data.type !== 'init') { + await initIfNeeded(); + } const start = performance.now(); - const result = handler(data); + const result = await handler(data as never); const end = performance.now(); console.debug(`Worker message ${data.messageId} took ${end - start}ms`); self.postMessage({ type: 'result', result: result, error: null, - messageId: data.messageId - }); - } catch (error) { - self.postMessage({ - type: 'result', - result: null, - error: error, - messageId: data.messageId - }); + messageId, + } as OutMessage); + } else { + throw new Error(`No handler for ${data.type}`); } - } else { + })().catch(error => { self.postMessage({ type: 'result', result: null, - error: `No handler for ${data.type}`, - messageId: data.messageId - }); - } + error: error.toString(), + messageId, + } as OutMessage); + }); }; diff --git a/objdiff-wasm/tsconfig.json b/objdiff-wasm/tsconfig.json index 16f1f56..6f36d92 100644 --- a/objdiff-wasm/tsconfig.json +++ b/objdiff-wasm/tsconfig.json @@ -1,8 +1,9 @@ { "compilerOptions": { + "esModuleInterop": true, "module": "ES2022", "moduleResolution": "Node", + "strict": true, "target": "ES2022", - "esModuleInterop": true } -} \ No newline at end of file +} diff --git a/objdiff-wasm/tsup.config.ts b/objdiff-wasm/tsup.config.ts index 02a8fbb..f2a5246 100644 --- a/objdiff-wasm/tsup.config.ts +++ b/objdiff-wasm/tsup.config.ts @@ -1,15 +1,33 @@ import {defineConfig} from 'tsup'; import fs from 'node:fs/promises'; -export default defineConfig({ - entry: ['src/main.ts', 'src/worker.ts'], - clean: true, - dts: true, - format: 'esm', - sourcemap: true, - splitting: false, - target: ['es2022', 'chrome89', 'edge89', 'firefox89', 'safari15', 'node14.8'], - async onSuccess() { - await fs.copyFile('pkg/objdiff_core_bg.wasm', 'dist/objdiff_core_bg.wasm'); +export default defineConfig([ + // Build main library + { + entry: ['src/main.ts'], + clean: true, + dts: true, + format: 'esm', + outDir: 'dist', + skipNodeModulesBundle: true, + sourcemap: true, + splitting: false, + target: 'es2022', + }, + // Build web worker + { + entry: ['src/worker.ts'], + clean: true, + dts: true, + format: 'esm', // type: 'module' + minify: true, + outDir: 'dist', + sourcemap: true, + splitting: false, + target: 'es2022', + // https://github.com/egoist/tsup/issues/278 + async onSuccess() { + await fs.copyFile('pkg/objdiff_core_bg.wasm', 'dist/objdiff_core_bg.wasm'); + } } -}); +]);