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

walkout-engine

v0.1.0

Published

A deterministic simulation of the coordination problem behind general strikes: participation thresholds, preference falsification, financial buffers, and cascading institutional defection.

Readme

walkout-engine

A deterministic simulation of the coordination problem behind general strikes.

Not whether people want change — whether enough of them move at the same time, in the right places, for long enough, and what that does to the institutions a regime depends on.

npm install walkout-engine
import { runSimulation, scenarioToConfig } from 'walkout-engine';
import scenario from 'walkout-engine/scenarios/petro-state.json' with { type: 'json' };

const run = runSimulation(scenarioToConfig(scenario, { seed: 1 }));

console.log(run.outcome.kind);      // 'collapse' | 'stalemate' | 'negotiated' | …
console.log(run.outcome.reasons);   // why, assembled from the run log itself
console.log(run.widestGap);         // { value: 0.62, day: 0 }
  • Deterministic. Same config and seed produce a byte-identical run, always. One seeded PRNG; no Math.random, no clock reads, enforced by lint and test.
  • UI-free. No DOM, no Node builtins. Runs in Node, in a browser, and in a Web Worker.
  • One dependency (zod, for scenario validation).
  • Fully typed, with every parameter documented.

What it models

Three quantities, kept strictly separate: private support (who wants it), public participation (who is acting), and spent (whose savings are gone). The gap between the first two is the thing worth looking at — it can sit at sixty percentage points, and that is what makes cascades appear to come from nowhere.

Campaigns win by institutional defection, not headcount. Security forces, civil service, judiciary, media, business elites and international backers each independently decide whether to keep cooperating; breadth of participation erodes them faster than raw numbers.

The model can lose. Across a randomised sweep the most common outcome takes about a third of runs, and all five terminal states occur — including collapse and violent escalation.

Adapting it

Every parameter is described in the exported registry, including whether anyone has actually measured it:

import { ALL_PARAMETERS, judgementParameters } from 'walkout-engine';

judgementParameters().length; // 29 of 46 — the ones nobody has measured

29 of the 46 are judgement, including every internal rate. The right way to use this is to vary what you cannot source and check whether your conclusion survives.

Overrides cover every parameter and can add or remove sectors and institutions outright:

const config = scenarioToConfig(scenario, {
  seed: 1,
  movement: { strikeFundDays: 45 },
  sectors: { transport: { bufferDays: 3 } },
  addSectors: [myOwnSector],
});

configToScenario() turns an edited model back into a validated scenario file you can cite and share.

Documentation

  • MODEL.md — every mechanic in plain language, with citations
  • Limitations — what this model cannot tell you. Read this one.
  • The simulator — the interface built on this engine

Grounded in Chenoweth & Stephan (2011), Sharp (1973), Helvey (2004), Granovetter (1978), Kuran (1995) and Martin (2007). Every numeric constant carries either a citation or an explicit UNSOURCED — tunable marker.

This is not a forecasting tool. It is not fitted to historical outcomes and has never been validated against them. It is for reasoning about mechanisms.

MIT licensed. Model critiques are the most welcome kind of issue.