UNPKG

@fine-js/channels

Version:

Bits of Clojure's `core.async` ported to JS

116 lines (97 loc) 2.37 kB
'use strict' const rename = (func, name, arity = func.length) => Object.defineProperties(func, { name: {value: name}, length: {value: arity}, }) const createBuffer = (name, blocking, impl) => rename((capacity = 1) => { const buf = impl(capacity) const kind = buf.kind || `${name}(${capacity})` return { kind, load: buf.load, capacity, blocking, readable: buf.readable, writable: buf.writable, peek: () => { if (!buf.readable()) throw new Error(`${kind} is empty`) return buf.peek() }, read: () => { if (!buf.readable()) throw new Error(`${kind} is empty`) return buf.read() }, write: (val) => { if (!buf.writable()) throw new Error(`${kind} is full`) buf.write(val) }, status: () => ({ kind, load: buf.load(), capacity, blocking, readable: buf.readable(), writable: buf.writable(), }), } }, name) const buffer = createBuffer('buffer', true, (capacity) => { const buf = [] return { load: () => buf.length, peek: () => buf[0], read: () => buf.shift(), write: (val) => buf.push(val), readable: () => buf.length > 0, writable: () => buf.length < capacity, } }) const dropping = createBuffer('dropping', false, (capacity) => { const buf = [] return { load: () => buf.length, peek: () => buf[0], read: () => buf.shift(), write: (val) => { if (capacity > buf.length) buf.push(val) }, readable: () => buf.length > 0, writable: () => true, } }) const sliding = createBuffer('sliding', false, (capacity) => { const buf = [] return { load: () => buf.length, peek: () => buf[0], read: () => buf.shift(), write: (val) => { if (buf.push(val) > capacity) buf.shift() }, readable: () => buf.length > 0, writable: () => true, } }) const unbuffered = () => Object.freeze({ kind: 'unbuffered()', load: () => 0, capacity: 0, blocking: true, readable: () => false, writable: () => false, peek: () => { throw new Error('peeking into unbuffered()') }, read: () => { throw new Error('reading from unbuffered()') }, write: () => { throw new Error('writing to unbuffered()') }, status: () => null, }) module.exports = { unbuffered, buffer, dropping, sliding, }