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

@oligami/browser_wasi_shim-threads

v0.5.0

Published

A pure javascript shim for WASI with support for threads

Readme

A pure javascript shim for WASI Preview 1 threads

[!WARNING] The code in this directory is less production ready than the main browser_wasi_shim code. This code requires SharedArrayBuffer, waitAsync and Atomics to be enabled in the browser, so it may not work in all browsers. For example, Firefox failed to run the demo in this directory. Chrome worked fine. This library require cross-origin isolation to be enabled in the browser.

This project implement threads on browser_wasi_shim

Features

  • [x] thread creation
  • [x] Filesystem wrapper accessible by multiple workers
  • [ ] thread pool

Building

$ npm install
$ npm run build

Running the demo

$ git submodule update --init
$ cd examples && npm install && npm run dev

And visit http://localhost

Farm base calls

WASIFarm accepts an unknown_fn callback that Animals invoke with call_unknown_fn. Calls from different Animals can run concurrently, and each caller receives its own result or thrown error even when callbacks complete out of order.

max_base_calls_limit controls concurrent user calls. It defaults to 128 and must be an integer from 1 through 1024; one additional slot is reserved for system operations. Synchronous Animal calls fail immediately with BaseCallCapacityError when every user slot is occupied.

Animal base calls use blocking Atomics.wait, so they must run in a Worker that is separate from the agent running the Park listener. The Park agent must remain able to process callbacks asynchronously; do not make a blocking Animal call on that same agent or on a browser agent where Atomics.wait is forbidden.

Forcibly terminating a Worker while it owns a base-call slot cannot run the caller's SharedArrayBuffer cleanup. The slot therefore remains occupied until the Farm is destroyed. Terminate callers cooperatively when the Farm must remain usable; otherwise call WASIFarm.destroy() to cancel the remaining slots and discard late response payloads.

Worker runtime destruction

WASIFarm.destroy() remains Park-only. It synchronously and idempotently destroys the Farm's owned Park, rejects new Park calls, wakes blocked callers, discards late callback results, and makes later get_ref() calls fail. It does not destroy Animals, the worker runtime, or external Workers.

WASIFarmAnimal.destroy() and DestroyerHandle.destroy() synchronously make the shared worker runtime reject new work and initiate runtime-wide teardown. Returning means logical teardown has started, not that every Worker has physically exited. Neither method destroys a Park.

WASIFarmAnimal.async_destroy() and DestroyerHandle.async_destroy() observe logical teardown completion, including released coordinator state and issued termination operations. Browser platforms do not provide a physical thread join, so resolution does not guarantee host thread reclamation. When an elected managed requester initiates teardown, its Promise resolves after every other managed Worker receives termination and its own close is scheduled; code after the await must not start new runtime work.

A transferred DestroyerHandleObject inside a managed worker must be reconstructed with WASIFarmAnimal.init_destroyer() so the receiving Animal is bound as the local requester. DestroyerHandle.init_self() creates an unbound handle for an external controller.

WASIFarmAnimal.kill_animal(animal_id) affects only the published, registered Animal with that ID. Unknown, unpublished, completed, or already killed IDs are idempotent no-ops and do not change the runtime lifecycle. Returning acknowledges the request, not physical termination. The coordinator reserves termination, acknowledges any in-flight command, and waits for short shared-memory updates to release ownership before terminating the captured Worker. This also permits a Worker to request its own termination without abandoning the command lock. Sibling Workers remain usable after an individual kill; runtime-wide completion and destruction still stop the applicable Workers.

The Park-specific methods remain separate: destroy_park(n) destroys one referenced Park, destroy_park_all() destroys all referenced Parks, and destroy_with_park() destroys the referenced Parks before initiating worker runtime teardown.

Architecture

In the thread that maintains the file system for @bjorn3/browser_wasi_shim, file access is awaited asynchronously, while in the thread executing the WASM, file access is performed synchronously.

Since the functions called within the WASM are invoked synchronously, it is not possible to properly create web workers. Therefore, it is necessary to first create a dedicated thread for generating web workers.

Please refer to the diagram below for more details.

slide1

Additionally, since data of unknown size is being exchanged, an allocator is essential. A simple allocator is implemented on the assumption that the allocated memory will be released promptly.

slide2