Skip to content

Commit 767da2f

Browse files
OttoAllmendingerllm-git
andcommitted
feat(wasm-utxo): add ESM support as primary format with CJS fallback
This change migrates the package to use ESM as the primary format while maintaining compatibility with CommonJS consumers. Key changes: - Set "type": "module" in package.json - Configure dual ESM/CJS output with proper exports field - Add .js extensions to all imports for ESM compatibility - Update build scripts to create both ESM and CJS outputs - Configure tests to work with ESM imports - Add bundler compatibility tests for both ESM and CJS usage - Update mocha config for ESM testing Issue: esm-first.2 Co-authored-by: llm-git <[email protected]>
1 parent 56ba79a commit 767da2f

30 files changed

+228
-123
lines changed

package-lock.json

Lines changed: 2 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/wasm-utxo-ui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"private": true,
1313
"scripts": {
1414
"build": "webpack --mode production --progress --config ./webpack.config.js",
15+
"typecheck": "tsc --noEmit",
1516
"test": "echo \"Error: no test specified\"",
1617
"dev": "webpack serve --mode development --progress --hot --config ./webpack.config.js",
1718
"fmt": "prettier --write .",
@@ -21,7 +22,6 @@
2122
"deploy": "gh-pages -d dist"
2223
},
2324
"dependencies": {
24-
"@bitgo/utxo-lib": "^10.1.0",
2525
"@bitgo/wasm-utxo": "*",
2626
"assert": "^2.1.0",
2727
"buffer": "^6.0.3",

packages/wasm-utxo-ui/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"compilerOptions": {
3+
"composite": true,
34
"allowSyntheticDefaultImports": true,
45
"esModuleInterop": true,
56
"forceConsistentCasingInFileNames": true,

packages/wasm-utxo/.mocharc.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2-
"extension": ["js", "ts"],
3-
"node-option": ["import=tsx"]
2+
"extensions": ["ts", "tsx", "js", "jsx"],
3+
"spec": ["test/**/*.ts"],
4+
"node-option": ["import=tsx/esm", "experimental-wasm-modules"]
45
}

packages/wasm-utxo/Makefile

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ define SHOW_WASM_SIZE
2323
@find $(1) -name "*.wasm" -exec gzip -k {} \;
2424
@find $(1) -name "*.wasm" -exec du -h {} \;
2525
@find $(1) -name "*.wasm.gz" -exec du -h {} \;
26+
@find $(1) -name "*.wasm.gz" -delete
2627
endef
2728

2829
define BUILD
@@ -35,15 +36,15 @@ endef
3536

3637
.PHONY: js/wasm/
3738
js/wasm/:
38-
$(call BUILD,$@,nodejs)
39+
$(call BUILD,$@,bundler)
3940

40-
.PHONY: dist/node/js/wasm/
41-
dist/node/js/wasm/:
42-
$(call BUILD,$@,nodejs)
41+
.PHONY: dist/esm/wasm/
42+
dist/esm/wasm/:
43+
$(call BUILD,$@,bundler)
4344

44-
.PHONY: dist/browser/js/wasm/
45-
dist/browser/js/wasm/:
46-
$(call BUILD,$@,browser)
45+
.PHONY: dist/cjs/wasm/
46+
dist/cjs/wasm/:
47+
$(call BUILD,$@,nodejs)
4748

4849
.PHONY: lint
4950
lint:
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Test script to verify CommonJS compatibility
3+
* Run with: node bundler-test/test-cjs-import.cjs
4+
*/
5+
6+
console.log("Testing CommonJS require() compatibility...\n");
7+
8+
// Use standard CommonJS require
9+
let wasmUtxo;
10+
try {
11+
wasmUtxo = require("../dist/cjs/index.js");
12+
} catch (error) {
13+
console.error("✗ require() failed:", error.message);
14+
process.exit(1);
15+
}
16+
17+
console.log("✓ require() successful from CJS context");
18+
console.log("✓ Available exports:", Object.keys(wasmUtxo).join(", "));
19+
20+
// Test that we can access the main APIs
21+
if (wasmUtxo.Descriptor) {
22+
console.log("✓ Descriptor API available");
23+
}
24+
if (wasmUtxo.Psbt) {
25+
console.log("✓ Psbt API available");
26+
}
27+
if (wasmUtxo.address) {
28+
console.log("✓ address namespace available");
29+
}
30+
if (wasmUtxo.fixedScriptWallet) {
31+
console.log("✓ fixedScriptWallet namespace available");
32+
}
33+
34+
// Try to use the Descriptor API
35+
try {
36+
const descriptor = wasmUtxo.Descriptor.fromString(
37+
"wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/0/*)",
38+
"derivable",
39+
);
40+
console.log("✓ Descriptor.fromString() works");
41+
console.log(" Descriptor type:", descriptor.descType());
42+
} catch (err) {
43+
console.log("✗ Descriptor test failed:", err.message);
44+
process.exit(1);
45+
}
46+
47+
console.log("\n✅ All CJS compatibility tests passed!");
48+
console.log("\nCJS consumers can use standard require() with this package.");
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Test script to verify ESM import works correctly
3+
* Run with: node --experimental-wasm-modules bundler-test/test-esm-import.mjs
4+
*/
5+
6+
import { Descriptor, Psbt, address, fixedScriptWallet } from "../dist/esm/index.js";
7+
8+
console.log("Testing ESM import...\n");
9+
10+
console.log("✓ ESM import successful");
11+
console.log("✓ Descriptor API available");
12+
console.log("✓ Psbt API available");
13+
console.log("✓ address namespace available");
14+
console.log("✓ fixedScriptWallet namespace available");
15+
16+
// Test that we can use the Descriptor API
17+
try {
18+
const descriptor = Descriptor.fromString(
19+
"wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/0/*)",
20+
"derivable",
21+
);
22+
console.log("✓ Descriptor.fromString() works");
23+
console.log(" Descriptor type:", descriptor.descType());
24+
25+
// Test address derivation
26+
const derived = descriptor.atDerivationIndex(0);
27+
console.log("✓ Descriptor derivation works");
28+
console.log(" Script pubkey length:", derived.scriptPubkey().length);
29+
} catch (err) {
30+
console.log("✗ Descriptor test failed:", err.message);
31+
process.exit(1);
32+
}
33+
34+
console.log("\n✅ All ESM tests passed!");
35+
console.log("\nThis is the primary/recommended way to use this package.");

packages/wasm-utxo/js/address.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { AddressNamespace } from "./wasm/wasm_utxo";
2-
import type { CoinName } from "./coinName";
1+
import { AddressNamespace } from "./wasm/wasm_utxo.js";
2+
import type { CoinName } from "./coinName.js";
33

44
/**
55
* Most coins only have one unambiguous address format (base58check and bech32/bech32m)

packages/wasm-utxo/js/ast/fromWasmNode.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { DescriptorNode, MiniscriptNode, TapTreeNode } from "./formatNode";
2-
import { Descriptor, Miniscript } from "../index";
1+
import { DescriptorNode, MiniscriptNode, TapTreeNode } from "./formatNode.js";
2+
import { Descriptor, Miniscript } from "../index.js";
33

44
function getSingleEntry(v: unknown): [string, unknown] {
55
if (typeof v === "object" && v) {

packages/wasm-utxo/js/ast/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
export * from "./formatNode";
2-
export * from "./fromWasmNode";
1+
export * from "./formatNode.js";
2+
export * from "./fromWasmNode.js";

0 commit comments

Comments
 (0)