chan.js raw
1 // chan.js — channel primitives for async message passing
2 // replaces callback maps + stale closures with linear async flow
3
4 // broadcast channel: multiple listeners, each recv() gets the next send()
5 export function chan() {
6 const waiters = []
7 return {
8 send(val) {
9 for (const w of waiters.splice(0)) w(val)
10 },
11 recv() {
12 return new Promise(resolve => waiters.push(resolve))
13 }
14 }
15 }
16
17 // multiplexed channel: keyed by request ID, one-shot per key, with timeout
18 export function mux() {
19 const pending = new Map()
20 return {
21 send(id, val) {
22 const resolve = pending.get(id)
23 if (resolve) { pending.delete(id); resolve(val) }
24 },
25 recv(id, timeoutMs = 15000) {
26 return new Promise((resolve, reject) => {
27 const timer = setTimeout(() => {
28 pending.delete(id)
29 reject(new Error('timeout'))
30 }, timeoutMs)
31 pending.set(id, (val) => { clearTimeout(timer); resolve(val) })
32 })
33 }
34 }
35 }
36