Skip to content
Permalink
9bfb9ba527
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
126 lines (105 sloc) 2.2 KB
'use strict'
const NOOP_RECURSOR = {
size: 0,
next () { return null },
}
exports.NOOP_RECURSOR = NOOP_RECURSOR
function fork (recursor) {
const buffer = []
return {
shared () {
const next = recursor()
if (next !== null) buffer.push(next)
return next
},
recursor () {
if (buffer.length > 0) return buffer.shift()
return recursor()
},
}
}
exports.fork = fork
function consumeDeep (recursor) {
const stack = [recursor]
while (stack.length > 0) {
const subject = stack[stack.length - 1]()
if (subject === null) {
stack.pop()
continue
}
if (typeof subject.createRecursor === 'function') {
stack.push(subject.createRecursor())
}
}
}
exports.consumeDeep = consumeDeep
function map (recursor, mapFn) {
return () => {
const next = recursor()
if (next === null) return null
return mapFn(next)
}
}
exports.map = map
function replay (state, create) {
if (!state) {
const recursor = create()
if (recursor === NOOP_RECURSOR) {
state = recursor
} else {
state = Object.assign({
buffer: [],
done: false,
}, recursor)
}
}
if (state === NOOP_RECURSOR) return { state, recursor: state }
let done = false
let index = 0
const next = () => {
if (done) return null
let retval = state.buffer[index]
if (retval === undefined) {
retval = state.buffer[index] = state.next()
}
index++
if (retval === null) {
done = true
}
return retval
}
return { state, recursor: { next, size: state.size } }
}
exports.replay = replay
function sequence (first, second) {
let fromFirst = true
return () => {
if (fromFirst) {
const next = first()
if (next !== null) return next
fromFirst = false
}
return second()
}
}
exports.sequence = sequence
function singleValue (value) {
let done = false
return () => {
if (done) return null
done = true
return value
}
}
exports.singleValue = singleValue
function unshift (recursor, value) {
return () => {
if (value !== null) {
const next = value
value = null
return next
}
return recursor()
}
}
exports.unshift = unshift