{"_id":"napi-wasm","_rev":"8-ef85de2182e13f2cbea341cfaebf999a","name":"napi-wasm","dist-tags":{"latest":"1.1.3"},"versions":{"0.0.1-security":{"name":"napi-wasm","version":"0.0.1-security","_id":"napi-wasm@0.0.1-security","maintainers":[{"name":"lisayu","email":"lisa@npmjs.com"}],"homepage":"https://github.com/npm/security-holder#readme","bugs":{"url":"https://github.com/npm/security-holder/issues"},"dist":{"shasum":"42b9edac076f5e73adb0338208fb1a776b1037eb","tarball":"https://registry.npmjs.org/napi-wasm/-/napi-wasm-0.0.1-security.tgz","fileCount":2,"integrity":"sha512-Qs0mROjz6h1Acc546kSRexTn3G/y2j+a0Ja1bejGk+o9oaOd73BjVvYroqBskgDOGlPWqF3f86YE8R3VK4m4PQ==","signatures":[{"sig":"MEUCIApuqmp6xlRgk/d75ZTH7syDwZnzJYRHHv5DBX7lTeReAiEAxDLs4MPaCjoaCACErOYrpbXlEc0uV3i+X2+COwG1DOU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":496,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjrXX3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpc2g//ZDAliDeqVfswlrse7ibQTtEbEG4GFZgZqxw5bW6H5XjoyuEY\r\nBNtT0P0JnN2BxL2RGud5ld46FMeLgvGJjj7PtRTlwZeLvHuaAnZtaCt56Aoa\r\nN+E5Wcks34W1hSLduJgVs+wOGP6mcLX9rCU/RAX1pbESMbIs9ybpbqan1s2c\r\n1Ogf00TRJFpcs4Xc8CK4syJbZj/8G8BMgnnqo1JAGDtsmdD1qBFBJw9dOwvL\r\nSkGC/ptTxmqUzkinOMGDsFjOqXv2ZwVYQtHLhM5kibwVNWkbilPJxLIJnxW/\r\nJSjQEzuWn6GRrCvvaop1mil1FD/3HMrnxSHt4cRY6LOMb0dYx3hAIWZJpaxE\r\nI6P7JFi2JivgMw+qA5f1i9tJxJBIEWcM7uLWIkYojaCeRvDwv85XrM6abpRN\r\nbpAoF67OdF/p/qdOol3pn8R/al78kwXdosTxhGKhYGt1Tlyrq0finioxK1GQ\r\nT9V8sEIjyGIMhzaeqvQHSy08ak0Riuj83oTLwhFEOnqG2qNm0c3WksfolpsY\r\ndVny1fFocGOTvaTu7l61jw0/Row6y6+iVUyiqnqgS8EKnkEPp8bNZQXFvO8V\r\n/ipSWh68DiL1e+tNqVClcPLkQw4gv4yapDJXzKI1S4Jv25BsqczZseebLZr3\r\nMNahWFjPAipDe7Ks1TH5+wL+aWHl64AEr3A=\r\n=HiUR\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"lisayu","email":"lisa@npmjs.com"},"repository":{"url":"git+https://github.com/npm/security-holder.git","type":"git"},"_npmVersion":"8.19.1","description":"security holding package","directories":{},"_nodeVersion":"12.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/napi-wasm_0.0.1-security_1672312311299_0.9159403851987413","host":"s3://npm-registry-packages"}},"1.0.1":{"name":"napi-wasm","version":"1.0.1","keywords":["napi","wasm","node-api","rust"],"author":{"name":"Devon Govett","email":"devongovett@gmail.com"},"license":"MIT","_id":"napi-wasm@1.0.1","maintainers":[{"name":"devongovett","email":"devongovett@gmail.com"}],"homepage":"https://github.com/devongovett/napi-wasm#readme","bugs":{"url":"https://github.com/devongovett/napi-wasm/issues"},"dist":{"shasum":"b186b9f9f1a54c321c4a1ea852a31a9691792a24","tarball":"https://registry.npmjs.org/napi-wasm/-/napi-wasm-1.0.1.tgz","fileCount":4,"integrity":"sha512-70Ks5fMTw5/5iZJg8dtyivwPP9tgyeLRHGa2j4GlFOjz4lWbbTWrDAvSeJlQg+o++cWpX2bSPGI1Hu4W2kbOoA==","signatures":[{"sig":"MEUCIQDvjJLBNv4Gd7JPLXwEXwDU/d0Or75ojVU1vupm3iJ/iAIgcUA8nQsHUzLdrQ8BngHB+O3ZOZii8ErY2NdaQaJ9+qk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":82715,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjrc6bACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpCYA/9FIG34EEBgwigsMcAybLZJcb22gauWQLpeVJaYWTyRlWUXtnw\r\nJkHebqP6d+NnVddglzu7s+fs1/APg8xAlhmglQIPWxOSJd1yXLLtm/nQpjfp\r\n3J9RaNtZATtJ0ABWs8PKiCaxfuegL/EGDZXi48w3FSoUqxVpc7vuLzw8Ajqr\r\nl8GXUdv/Bh+WoFr+PsF134kljm7bc4eNGvobUsDlbYuxNUsLu9DJ5h93c1Sz\r\ngGWw+bdlAK5AF4OlvnfS8X2/wThg2x9ORgWQ80FPLT6rDRZLqSSsSvtmBpJp\r\nEv70XH1D/EdXCRHEoIV+IwAGWEwViWRWuWt4Cu7AeXFUHlbIIu1AR9bTpdK/\r\nNd3sI8HbwBD2gBWl9oHZ30TP2aCteXItXDmu/s88uuDww4ODGIrCcHnkXVMc\r\nRWQbXBKMWpGsJJ382n0NhLA6nqbAYLIU+xBXRfIqm9BuvNnq8waK58O0rWXB\r\nYw00iwFWzj+RBdb8c+J4QaasgXGKtCrf4z5dJJNJEYj/QK/tjTFPkhOOMsuN\r\n9mqRq66kdEcC8PKnx2HxWpykDncQXPSPyF50auwH+D79DAcGmgASCAqrPVD8\r\ndK3lIxVTt3ZhoI8wTLArOxAb6wkjxJvSMGCikjlVIAMEshbcSGYIwXjVKjAG\r\nN2ffpwBQqBDxfv8OgE0W2r4yQOZyZScu7As=\r\n=zVhG\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.mjs","exports":{"import":"./index.mjs","require":"./index.js"},"gitHead":"ee05fa723927b8f58b3dd5b79ff0c83513d0e544","scripts":{"prepublishOnly":"sed 's/^export //g' index.mjs > index.js && echo '\nexports.Environment = Environment;\nexports.napi = napi;' >> index.js"},"_npmUser":{"name":"devongovett","email":"devongovett@gmail.com"},"repository":{"url":"git+https://github.com/devongovett/napi-wasm.git","type":"git"},"_npmVersion":"8.5.5","description":"An implementation of napi for wasm","directories":{},"_nodeVersion":"16.15.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/napi-wasm_1.0.1_1672335003760_0.3493354522604426","host":"s3://npm-registry-packages"}},"1.1.0":{"name":"napi-wasm","version":"1.1.0","keywords":["napi","wasm","node-api","rust"],"author":{"name":"Devon Govett","email":"devongovett@gmail.com"},"license":"MIT","_id":"napi-wasm@1.1.0","maintainers":[{"name":"devongovett","email":"devongovett@gmail.com"}],"homepage":"https://github.com/devongovett/napi-wasm#readme","bugs":{"url":"https://github.com/devongovett/napi-wasm/issues"},"dist":{"shasum":"bbe617823765ae9c1bc12ff5942370eae7b2ba4e","tarball":"https://registry.npmjs.org/napi-wasm/-/napi-wasm-1.1.0.tgz","fileCount":4,"integrity":"sha512-lHwIAJbmLSjF9VDRm9GoVOy9AGp3aIvkjv+Kvz9h16QR3uSVYH78PNQUnT2U4X53mhlnV2M7wrhibQ3GHicDmg==","signatures":[{"sig":"MEYCIQDvekjBhEUI8F3orlIVpmHSU+isdEBmtHtGWrv9VpVQiAIhALhXvCegIutE2Ufj6LQuxlrzGGlFH1Xo7OKuu4QybMIE","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86249},"main":"index.mjs","exports":{"import":"./index.mjs","require":"./index.js"},"gitHead":"e596b7a8e37f72fe2340e37d520183fc65afe3a2","scripts":{"prepublishOnly":"sed 's/^export //g' index.mjs > index.js && echo '\nexports.Environment = Environment;\nexports.napi = napi;' >> index.js"},"_npmUser":{"name":"devongovett","email":"devongovett@gmail.com"},"repository":{"url":"git+https://github.com/devongovett/napi-wasm.git","type":"git"},"_npmVersion":"8.19.4","description":"An implementation of napi for wasm","directories":{},"_nodeVersion":"16.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/napi-wasm_1.1.0_1690169208162_0.007470240092879665","host":"s3://npm-registry-packages"}},"1.1.1":{"name":"napi-wasm","version":"1.1.1","keywords":["napi","wasm","node-api","rust"],"author":{"name":"Devon Govett","email":"devongovett@gmail.com"},"license":"MIT","_id":"napi-wasm@1.1.1","maintainers":[{"name":"devongovett","email":"devongovett@gmail.com"}],"homepage":"https://github.com/devongovett/napi-wasm#readme","bugs":{"url":"https://github.com/devongovett/napi-wasm/issues"},"dist":{"shasum":"668e06561bb058e6b11e6ae367811f503cb4bf50","tarball":"https://registry.npmjs.org/napi-wasm/-/napi-wasm-1.1.1.tgz","fileCount":4,"integrity":"sha512-2tItKg75PUwE3qOEP6dvUYnLQ6FN9iN3OEwxXKv6RgEPnxZc2OXseZgtYS55bttqNedmI4hm00pvn8B5cML3Fg==","signatures":[{"sig":"MEUCIQDZmLbzbpZW+KY4yDWoRQlwkU12IPuJzmIOOntSu70/1QIgbhw2QLII3cdxFZsIo2u5+2nQ9DkLPeMkqZxfcUhUZss=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":87747},"main":"index.mjs","exports":{"import":"./index.mjs","require":"./index.js"},"gitHead":"9b78e4cfb77018099a06ba48da50f701d02b86a8","scripts":{"prepublishOnly":"sed 's/^export //g' index.mjs > index.js && echo '\nexports.Environment = Environment;\nexports.napi = napi;' >> index.js"},"_npmUser":{"name":"devongovett","email":"devongovett@gmail.com"},"repository":{"url":"git+https://github.com/devongovett/napi-wasm.git","type":"git"},"_npmVersion":"10.4.0","description":"An implementation of napi for wasm","directories":{},"_nodeVersion":"20.9.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/napi-wasm_1.1.1_1725135817279_0.9732817017549575","host":"s3://npm-registry-packages"}},"1.1.2":{"name":"napi-wasm","version":"1.1.2","keywords":["napi","wasm","node-api","rust"],"author":{"name":"Devon Govett","email":"devongovett@gmail.com"},"license":"MIT","_id":"napi-wasm@1.1.2","maintainers":[{"name":"devongovett","email":"devongovett@gmail.com"}],"homepage":"https://github.com/devongovett/napi-wasm#readme","bugs":{"url":"https://github.com/devongovett/napi-wasm/issues"},"dist":{"shasum":"d05a85222499c49e56d953e40b868110ebc294b1","tarball":"https://registry.npmjs.org/napi-wasm/-/napi-wasm-1.1.2.tgz","fileCount":4,"integrity":"sha512-yaA+PVpjOX7xdMmIZwx2IfzKmf1+3fBfshLTB3bvwZAUY2/3UBqOnzMRxwAP0hhxkpRRNtvd/dg4mDSJ/2CE6Q==","signatures":[{"sig":"MEQCIGf5dt5z7s0+iCHuTO7Eec412h90C+a1XT3QuwX5WpOBAiBGC1EvaNzxc2maUVfUTdez+H477ex/Z/bS07oai46XQQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":87749},"main":"index.mjs","exports":{"import":"./index.mjs","require":"./index.js"},"gitHead":"2ade9ac8a6d93d5d89fe7273bee49c2ad171fe04","scripts":{"prepublishOnly":"sed 's/^export //g' index.mjs > index.js && echo '\nexports.Environment = Environment;\nexports.napi = napi;' >> index.js"},"_npmUser":{"name":"devongovett","email":"devongovett@gmail.com"},"repository":{"url":"git+https://github.com/devongovett/napi-wasm.git","type":"git"},"_npmVersion":"10.4.0","description":"An implementation of napi for wasm","directories":{},"_nodeVersion":"20.9.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/napi-wasm_1.1.2_1725136290335_0.3496736054881897","host":"s3://npm-registry-packages"}},"1.1.3":{"name":"napi-wasm","version":"1.1.3","description":"An implementation of napi for wasm","main":"index.mjs","exports":{"import":"./index.mjs","require":"./index.js"},"scripts":{"prepublishOnly":"sed 's/^export //g' index.mjs > index.js && echo '\nexports.Environment = Environment;\nexports.napi = napi;' >> index.js"},"repository":{"type":"git","url":"git+https://github.com/devongovett/napi-wasm.git"},"keywords":["napi","wasm","node-api","rust"],"author":{"name":"Devon Govett","email":"devongovett@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/devongovett/napi-wasm/issues"},"homepage":"https://github.com/devongovett/napi-wasm#readme","_id":"napi-wasm@1.1.3","gitHead":"bbde4dc54b23d56889e4ca8a23704424df7ae05e","_nodeVersion":"20.9.0","_npmVersion":"10.4.0","dist":{"integrity":"sha512-h/4nMGsHjZDCYmQVNODIrYACVJ+I9KItbG+0si6W/jSjdA9JbWDoU4LLeMXVcEQGHjttI2tuXqDrbGF7qkUHHg==","shasum":"7bb95c88e6561f84880bb67195437b1cfbe99224","tarball":"https://registry.npmjs.org/napi-wasm/-/napi-wasm-1.1.3.tgz","fileCount":4,"unpackedSize":89849,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICSk6ArWgWRHeNihszPU2dgjPt0ScGoCeyYG4CnwbwkbAiEAiMl8hWXoiFWY6s+uPuArrvYbatmFD/gLYteXkIHO1S4="}]},"_npmUser":{"name":"devongovett","email":"devongovett@gmail.com"},"directories":{},"maintainers":[{"name":"devongovett","email":"devongovett@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/napi-wasm_1.1.3_1725136547912_0.26219257982901834"},"_hasShrinkwrap":false}},"time":{"created":"2022-12-29T11:11:51.299Z","modified":"2024-08-31T20:35:48.311Z","1.0.0":"2022-12-28T23:15:31.752Z","0.0.1-security":"2022-12-29T11:11:51.435Z","1.0.1":"2022-12-29T17:30:03.960Z","1.1.0":"2023-07-24T03:26:48.316Z","1.1.1":"2024-08-31T20:23:37.448Z","1.1.2":"2024-08-31T20:31:30.505Z","1.1.3":"2024-08-31T20:35:48.115Z"},"bugs":{"url":"https://github.com/devongovett/napi-wasm/issues"},"author":{"name":"Devon Govett","email":"devongovett@gmail.com"},"license":"MIT","homepage":"https://github.com/devongovett/napi-wasm#readme","keywords":["napi","wasm","node-api","rust"],"repository":{"type":"git","url":"git+https://github.com/devongovett/napi-wasm.git"},"description":"An implementation of napi for wasm","maintainers":[{"name":"devongovett","email":"devongovett@gmail.com"}],"readme":"# napi-wasm\n\nAn implementation of the [napi](https://nodejs.org/api/n-api.html) API for WASM. Enables using some native Node modules in browsers and other environments.\n\n## Setup\n\nTo use napi-wasm, there are a few requirements:\n\n1. Configure your linker to export an indirect function table. With ldd, this is the `--export-table` flag. This enables JavaScript to call callback functions registered by WASM. It is exposed in the WebAssembly exports as `__indirect_function_table`.\n2. Export a function from your WASM build named `napi_register_module_v1` (Node's default), or `napi_register_wasm_v1` for WASM-specific builds. This is called during initialization to setup the `exports` object for your module. It receives an environment and an exports object pointer as arguments, which you can add properties to.\n3. Include a function named `napi_wasm_malloc` in your WASM build. This is called from JavaScript by napi-wasm to allocate memory in the WASM heap. It should accept a `uint32` size argument indicating the number of bytes to allocate, and return a `uint8` pointer to allocated memory.\n4. Compile for the `wasm32-unknown-unknown` target.\n\n### In Rust\n\nThe above steps should apply for any programming language, but here's an example in Rust. First, define a `napi_wasm_malloc` function so JavaScript can allocate memory in the WASM heap using the default allocator.\n\n```rust\nuse std::alloc::{alloc, Layout};\n\n#[no_mangle]\npub extern \"C\" fn napi_wasm_malloc(size: usize) -> *mut u8 {\n  let align = std::mem::align_of::<usize>();\n  if let Ok(layout) = Layout::from_size_align(size, align) {\n    unsafe {\n      if layout.size() > 0 {\n        let ptr = alloc(layout);\n        if !ptr.is_null() {\n          return ptr;\n        }\n      } else {\n        return align as *mut u8;\n      }\n    }\n  }\n\n  std::process::abort();\n}\n```\n\nNext, implement `napi_register_wasm_v1` to register your module exports. We'll use the [napi-rs](https://github.com/napi-rs/napi-rs) bindings in this example to make it a bit nicer than calling C APIs directly. Note that the napi-rs `#[module_exports]` macro currently doesn't work in WASM because Rust doesn't support ctor setup functions in WASM targets yet, so we'll need to do this manually.\n\n```rust\nuse napi::{Env, JsObject, NapiValue};\n\n#[no_mangle]\npub unsafe extern \"C\" fn napi_register_wasm_v1(raw_env: napi::sys::napi_env, raw_exports: napi::sys::napi_value) {\n  let env = Env::from_raw(raw_env);\n  let exports = JsObject::from_raw_unchecked(raw_env, raw_exports);\n\n  exports.create_named_method(\"transform\", transform);\n}\n\n#[js_function(1)]\nfn transform(ctx: CallContext) -> napi::Result<JsUnknown> {\n  // ...\n}\n```\n\nTo compile, you need to export a function table and use the correct target.\n\n```shell\n RUSTFLAGS=\"-C link-arg=--export-table\" cargo build --target wasm32-unknown-unknown\n```\n\nThis will output a file in `target/wasm32-unknown-unknown/debug/YOUR_CRATE.wasm` which you can load in a JavaScript environment.\n\nYou can also put the rust flags in a `.cargo/config.toml` file so you don't need to provide the environment variable each time you run `cargo build`.\n\n```toml\n[target.wasm32-unknown-unknown]\nrustflags = [\"-C\", \"link-arg=--export-table\"]\n```\n\n### Loading\n\nTo load a WASM file and initialize a napi environment, you'll need to import the `napi-wasm` package. You instantiate a WASM module as usual, providing `napi` as the `env` import key. This provides the napi functions for your WASM module to use.\n\nThen, pass the WASM instance to the `Environment` constructor to setup a napi environment. This will call `napi_register_wasm_v1` or `napi_register_module_v1` to setup the exports object. Then you can call functions on the exports object as you would in Node.\n\n```js\nimport { Environment, napi } from 'napi-wasm';\n\n// Construct a URL and instantiate a WebAssembly module as usual.\nconst url = new URL('path/to/lib.wasm', import.meta.url);\nconst { instance } = await WebAssembly.instantiateStreaming(fetch(url), {\n  env: napi\n});\n\n// Create an environment.\nlet env = new Environment(instance);\nlet exports = env.exports;\n\n// Use exports as usual!\nexports.transform({\n  // ...\n});\n```\n\nWhen you are done with an `Environment`, call the `destroy()` function to clean up memory.\n","readmeFilename":"README.md"}