npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wasm-polycall

v2.0.0

Published

WebAssembly binding for Polycall: a Node.js host that implements the "polycall" imports of wasm32 guests by calling the real native Polycall core (binding ABI v1).

Readme

wasm-polycall

wasm-polycall is the WebAssembly binding for Polycall (binding ABI v1, Polycall

= 1.1.0). It has two halves:

  • Guest side — include/polycall_wasm.h: the functions, status codes and limits of the native polycall.h, declared as imports from the polycall import module. A C (or Rust, Zig, ...) program compiled to wasm32 calls them like the native API.
  • Host side — a Node.js host (this npm package) that implements every polycall import by calling the real native Polycall core (polycall.dll / libpolycall.dll / libpolycall.so.1) through the koffi FFI. Nothing is emulated: configuration validation, RPC calls and peer nodes all run in the core.
 guest.wasm (wasm32)            Node.js host (wasm-polycall)         native core
 polycall_peer_send(...)  --->  "polycall" imports: validate guest  --->  libpolycall
   (i32 pointers into the       pointers, pass views of guest           (binding ABI v1)
    guest's linear memory)      memory to the core via koffi

Why a host binding (and not the core compiled to wasm)

The core needs BSD sockets and POSIX threads. WASI preview 1 has neither: wasi-libc does not declare socket/connect/bind/listen and has no pthread.h, so the core cannot be compiled to wasm32-wasi with working networking (checked with clang 14 + Debian wasi-libc). The guest therefore calls the native core through host imports.

Install

npm install wasm-polycall      # pulls koffi (prebuilt binaries)

The native core must be installed separately (Polycall >= 1.1.0). The host loads, in this order: POLYCALL_LIBRARY (full path), then polycall.dll and libpolycall.dll on Windows, libpolycall.so.1 on Linux (libpolycall.1.dylib on macOS, which is not tested — see Platforms). Every symbol is resolved and polycall_ffi_abi_version() == 1 is checked before a guest runs; a missing library, an old 1.0 library or an ABI mismatch throws a PolycallLoadError (reason: not-found, missing-symbol, abi-mismatch) naming the library — never a crash.

Guest API (wasm32)

#include "polycall_wasm.h"   /* clang --target=wasm32-wasi -I<pkg>/include ... */

polycall_peer_t inbox, outbox;
polycall_peer_open("inbox", "127.0.0.1:0", NULL, &inbox);
polycall_peer_open("outbox", NULL, NULL, &outbox);           /* send-only */
polycall_peer_send(outbox, "127.0.0.1:9001", "hi", 2, "m-1", 5000);

Same signatures and semantics as polycall.h (caller-owned buffers, snprintf rules, negative POLYCALL_E_* status, polycall_last_error for the detail), with these differences forced by the wasm boundary:

| | | | --- | --- | | pointers / size_t | 32-bit offsets into the guest memory / unsigned 32-bit; size_t * and polycall_peer_t * outputs are 4-byte cells | | polycall_strerror | a guest-side inline over the import polycall_wasm_strerror(status, buf, cap); returns a static guest buffer | | polycall_get_version | not imported (1.0 API); use polycall_ffi_version | | bad guest pointers | a pointer or region outside the guest memory, or an unterminated string, is POLYCALL_E_INVALID_ARGUMENT with a host detail in polycall_last_error; the core is not called | | blocking | a polycall_peer_recv with a long timeout blocks the host thread running the guest: run such guests in a worker_threads Worker so another thread can call polycall_peer_cancel / polycall_peer_close (peer handles are process-wide, so any thread or guest instance may use them) |

The full import table (names, wasm types, C prototypes) is generated/polycall/abi.json. The wasm-polycall 1.x contract — env.polycall_ffi_run_config(path_ptr, run) — is still provided and reaches the same core function.

Security: the imports give a guest the host's network (peer nodes, RPC) and read access to configuration files by host path. Instantiate trusted modules only.

Host API (Node.js >= 22)

const {
  instantiatePolycallModule, runPolycallModule, createPolycallHost, loadPolycall,
  PolycallLoadError, STATUS, LIMITS
} = require("wasm-polycall");

// run a WASI command guest to completion (exit code)
const code = await runPolycallModule("guest.wasm", { wasi: { args: ["guest.wasm", "x"], env: {} } });

// or instantiate and drive exports yourself
const { instance, host } = await instantiatePolycallModule("guest.wasm", {
  imports: { env: { /* your own imports */ } }
});
console.log(host.library.path, host.library.version);   // the loaded core

createPolycallHost({ memory }) returns { imports, setMemory, library } for embedding into your own instantiation (imports.polycall and the legacy imports.env). WASI preview 1 (node:wasi) is supplied automatically when a module imports it.

CLI

npx wasm-polycall doctor                     # which core was loaded, version, ABI
npx wasm-polycall run guest.wasm -- ARGS     # run a guest against the real core
npx wasm-polycall inspect guest.wasm         # imports/exports, polycall imports used
npx wasm-polycall host-smoke wasm-polycallrc # validate a config from inside a wasm module

Example

clang --target=wasm32-wasi -O2 -I include examples/hello.c -o hello.wasm
npx wasm-polycall run hello.wasm -- wasm-polycallrc
# hello.wasm: Polycall 1.1.0, binding ABI 1
# hello.wasm: wasm-polycallrc is valid for running with this build
# hello.wasm: 127.0.0.1:40123 received 'hello from wasm' from wasm-outbox as hello-1

node examples/run.js wasm-polycallrc does the same check without a wasm toolchain (the module is assembled in JS).

Tests

npm ci
npm test        # tests/run.js: exit 0 pass, 1 failure, 77 something could not run

All tests use the real core (POLYCALL_LIBRARY or the default names) and the C CLI (POLYCALL_CLI or polycall on PATH); guests are built with clang --target=wasm32-wasi (WASM_CC), or taken prebuilt from WASM_POLYCALL_GUEST_DIR. Missing pieces are reported as SKIP, never as a pass.

| file | what | | --- | --- | | host.test.js | imports over guest memory, a JS-assembled wasm module, guest-pointer validation, non-ASCII config path | | real-core.test.js | tests/guest/abi_test.c (wasm32-wasi) — the whole BINDING_ABI.md checklist from inside the guest, call against polycall start and polycall daemon start, and payloads both ways with a polycall peer serve C node | | workers.test.js | guests in 4 worker threads: concurrent senders (own nodes and one shared handle), concurrent calls, a blocked receive woken by cancel, close and an arriving message | | loader.test.js | default names, POLYCALL_LIBRARY, missing / old / ABI-2 / partial libraries | | bin.test.js, package.test.js | CLI and package metadata |

Platforms

Tested: Linux x86-64 and Windows x64 (both polycall.dll from MSVC and libpolycall.dll from MSYS2 UCRT64). macOS is not claimed: the core has no verified macOS build yet.

License

MIT © Nnamdi Michael Okpala