diff --git a/npm/packages/rvf-wasm/package.json b/npm/packages/rvf-wasm/package.json index 9cc2dcd41..cc17ab798 100644 --- a/npm/packages/rvf-wasm/package.json +++ b/npm/packages/rvf-wasm/package.json @@ -1,22 +1,23 @@ { "name": "@ruvector/rvf-wasm", - "version": "0.1.5", + "version": "0.1.7", "description": "RuVector Format WASM microkernel for browser and edge vector operations", - "main": "pkg/rvf_wasm.js", + "type": "module", + "main": "pkg/rvf_wasm.mjs", "types": "pkg/rvf_wasm.d.ts", "exports": { ".": { "types": "./pkg/rvf_wasm.d.ts", - "import": "./pkg/rvf_wasm.mjs", - "require": "./pkg/rvf_wasm.js", - "default": "./pkg/rvf_wasm.js" + "default": "./pkg/rvf_wasm.mjs" } }, "files": [ "pkg/" ], "scripts": { - "build": "cargo build --release --target wasm32-unknown-unknown --manifest-path ../../crates/rvf/rvf-wasm/Cargo.toml && wasm-opt -Oz ../../crates/rvf/target/wasm32-unknown-unknown/release/rvf_wasm.wasm -o pkg/rvf_wasm_bg.wasm" + "build": "cargo build --release --target wasm32-unknown-unknown --manifest-path ../../crates/rvf/rvf-wasm/Cargo.toml && wasm-opt -Oz ../../crates/rvf/target/wasm32-unknown-unknown/release/rvf_wasm.wasm -o pkg/rvf_wasm_bg.wasm", + "test": "node tests/smoke.mjs", + "prepublishOnly": "node tests/smoke.mjs" }, "license": "MIT", "repository": { diff --git a/npm/packages/rvf-wasm/tests/smoke.mjs b/npm/packages/rvf-wasm/tests/smoke.mjs new file mode 100644 index 000000000..811c5b241 --- /dev/null +++ b/npm/packages/rvf-wasm/tests/smoke.mjs @@ -0,0 +1,39 @@ +// Smoke test: regression guard for issue #415. +// Verifies that @ruvector/rvf-wasm can be loaded as ESM without +// `SyntaxError: Cannot use 'import.meta' outside a module` and that +// init() returns a usable WASM exports object. + +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const pkgRoot = join(__dirname, '..'); + +let failures = 0; +function assert(cond, msg) { + if (!cond) { + console.error('FAIL:', msg); + failures++; + } else { + console.log(' ok:', msg); + } +} + +// 1. ESM import via package.json `default` (the published surface). +const mod = await import(join(pkgRoot, 'pkg/rvf_wasm.mjs')); +assert(typeof mod.default === 'function', 'mjs default export is a function'); + +// 2. Initialize and confirm we got real WASM exports back. +const exports_ = await mod.default(); +assert(exports_ != null && typeof exports_ === 'object', 'init() returned exports object'); +assert(exports_.memory instanceof WebAssembly.Memory, 'exports.memory is WebAssembly.Memory'); + +// 3. Idempotent re-init returns the cached instance. +const exports2 = await mod.default(); +assert(exports2 === exports_, 'init() is idempotent'); + +if (failures > 0) { + console.error(`\n${failures} smoke check(s) failed`); + process.exit(1); +} +console.log('\nrvf-wasm smoke OK');