Skip to content

Release notes

Eugene Lazutkin edited this page May 19, 2026 · 4 revisions

Release notes

2.0.0 — multi-primitive surface

Functional rewrite around three primitives plus a picker helper layer. Adopts fleet conventions (source layout, AI-agent docs, CI matrix).

Behavior

  • The package now exports three primitives: fork (broadcast, the default export), route (per-chunk single-target dispatch), and filter (per-chunk predicate-per-output subset). All three are Writables and gate upstream backpressure on the receiving downstreams' write callbacks — for fork every live output, for route the single picked one, for filter the predicate-matched subset.
  • All primitives expose .outputs (read-only snapshot of the live downstreams) and .isEmpty() (true once every downstream has failed). Dead downstreams are filtered out of subsequent writes automatically.
  • All primitives accept options.ignoreErrors: when truthy, downstream errors are silently swallowed and the failing stream is dropped from the live set; when falsy (default), the first error per round is forwarded to the primitive's own 'error' event.
  • New picker helpers under stream-fork/utils/:
    • pickRoundRobin(count) — load-balance.
    • pickByHash(keyFn, count) — stable shard via djb2 (numeric keys used directly modulo count).
    • pickByKey(keyFn, table) — explicit key→index lookup (plain object or Map).
    • pickFirstMatch(predicates) — first-true predicate's index; append () => true for catch-all.
  • All three primitives are built on a shared internal makeStreamPusher(stream) (src/stream-pusher.js) that wraps stream.write / stream.end in a Promise-based interface and installs its own 'error' listener so Node never crashes on otherwise-unhandled downstream errors. Mirrors stream-join's makeStreamPuller substrate.

Breaking changes

  • Functional API. new Fork(outputs, options) from 1.x becomes fork(outputs, options) — no new, no class. The static Fork.fork(...) factory is gone (the function IS the factory).
  • Node 22+ required. 1.x supported Node 6+ via the old CI matrix.
  • Subpath imports for non-default primitives. route and filter import as stream-fork/route.js and stream-fork/filter.js; picker helpers as stream-fork/utils/<name>.js. The default export (require('stream-fork') or import fork from 'stream-fork') remains fork() for back-compat with 1.x callers.

Fleet-standard adoption

  • src/ layout with .js source and hand-written .d.ts sidecar per file (// @ts-self-types="./<name>.d.ts" directive at the top of each .js).
  • Added: AGENTS.md, CLAUDE.md, .github/COPILOT-INSTRUCTIONS.md, byte-identical .windsurfrules / .cursorrules / .clinerules, llms.txt, llms-full.txt, ARCHITECTURE.md, LICENSE.
  • Paired .claude/commands/ + .windsurf/workflows/ for ai-docs-update and release-check.
  • Tests migrated from heya-unit to tape-six (.mjs test files).
  • CI: Node 22, 24, 26 on ubuntu-latest, windows-latest, macos-latest; actions/checkout@v6 + actions/setup-node@v6; runs ts-check + js-check in addition to tests.
  • Added .github/dependabot.yml (npm + github-actions, weekly, grouped, npm versioning-strategy: increase-if-necessary).
  • Added .github/FUNDING.yml.
  • Wiki content refreshed (this page + per-primitive references) and the wiki repository is mounted as a submodule in the package repo.

1.0.5 — technical release

No functional changes; metadata only. Safe to skip.

1.0.4 — bugfix

  • Errors from downstream streams are now forwarded correctly. Thanks to dbubovych.

1.0.3 — technical release

Republished to support Node 14.

1.0.2 — Node 6 workaround

Switched from _final() to the 'finish' event so the package would work on Node 6.

1.0.1 — improved documentation

Documentation polish; no behavior change.

1.0.0 — initial release

First public release. A single Fork class — a Writable that broadcast every chunk to every output, with proper backpressure handling.

Clone this wiki locally