Pipeline

klain:sync — Go-style goroutines and CSP channels.

An explicitly-non-Node opt-in: `go` spawns a cheap goroutine onto a preemptive M:N work-stealing scheduler, and a Channel<T> is a Go channel — a blocking send/receive that parks the *goroutine* (not the OS thread), as an unbuffered rendezvous or a buffered ring.

Two patterns in one program, both running concurrently across cores:

1. A fan-out worker pool: a spawn helper launches WORKERS goroutines, each squaring one slice of the inputs and sending results over a shared buffered channel; main fans the results in. Because a top-level channel is a module global, the helper sees it with its type intact, and each worker's slice base arrives as a function parameter (a fresh binding).

2. A three-stage pipeline (generate -> square -> sum) as three goroutines handing values along unbuffered channels as rendezvous.

import { go, Channel } from 'klain:sync';

// --- Pattern 1: fan-out worker pool -------------------------------------
const WORKERS = 4;
const PER = 25;
const results = new Channel<number>(64);

function spawn(base: number): void {
  go(() => {
    for (let i = 0; i < PER; i++) {
      const n = base * PER + i;
      results.send(n * n);
    }
  });
}

for (let w = 0; w < WORKERS; w++) spawn(w);

let poolSum = 0;
for (let i = 0; i < WORKERS * PER; i++) poolSum += results.receive();

let poolExpect = 0;
for (let n = 0; n < WORKERS * PER; n++) poolExpect += n * n;
console.log(`pool: ${WORKERS} workers, sum of squares = ${poolSum} ${poolSum === poolExpect ? "ok" : "FAIL"}`);

// --- Pattern 2: three-stage CSP pipeline --------------------------------
const N = 20;
const nums = new Channel<number>(0);
const squares = new Channel<number>(0);

go(() => { for (let i = 1; i <= N; i++) nums.send(i); });
go(() => { for (let i = 0; i < N; i++) { const n = nums.receive(); squares.send(n * n); } });

let pipeSum = 0;
for (let i = 0; i < N; i++) pipeSum += squares.receive();
console.log(`pipeline: sum of squares 1..${N} = ${pipeSum} ${pipeSum === 2870 ? "ok" : "FAIL"}`);
View source on GitHubexamples/goroutines/pipeline.ts