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