Skip to content

Instantly share code, notes, and snippets.

@itacirgabral
Created March 29, 2022 15:05
Show Gist options
  • Select an option

  • Save itacirgabral/90ed004d42240edd4742ab85a829c6dd to your computer and use it in GitHub Desktop.

Select an option

Save itacirgabral/90ed004d42240edd4742ab85a829c6dd to your computer and use it in GitHub Desktop.

Revisions

  1. itacirgabral created this gist Mar 29, 2022.
    84 changes: 84 additions & 0 deletions intermittentDrummer.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    import Yallist from 'yallist'

    const intermittentDrummer = const mkStepwand = ({ delay = 1000, delta = 200, breads = [] }: { delay?: number; delta?: number; breads?: Array<Bread> }) => {
    const indians = new Yallist<{ goodFor: number; bread: Bread }>()
    let dontStop = true

    const steps = () => indians.toArray().map(el => el.bread)
    const dates = () => indians.toArray().map(el => el.goodFor)

    // pre feeed
    for (const bread of breads) {
    indians.push({
    bread,
    goodFor: delay + Math.trunc(delta * (Math.random() - 0.5))
    })
    }

    let blockerResolve: (value: unknown) => void
    let blockerReject: (value: unknown) => void
    let mkBlocker = new Promise((resolve, reject) => {
    blockerResolve = resolve
    blockerReject = reject
    })

    const close = () => {
    dontStop = false
    blockerReject(null)
    }

    const pub = (bread: Bread) => {
    indians.push({
    bread,
    goodFor: delay + Math.trunc(delta * (Math.random() - 0.5))
    })
    if (indians.length === 1) {
    blockerResolve(null)
    }
    }

    const pubOver = (bread: Bread) => {
    indians.unshift({
    bread,
    goodFor: delay + Math.trunc(delta * (Math.random() - 0.5))
    })
    if (indians.length === 1) {
    blockerResolve(null)
    }
    }

    const gen = async function * gen () {
    while (dontStop) {
    if (indians.head) {
    const sleepms = indians.head?.value.goodFor ?? 0
    await setTimeout(sleepms > delta ? sleepms : delta)
    const bread = indians.shift()?.bread
    if (bread && dontStop) {
    yield bread
    } else {
    dontStop = false
    console.log(`dontStop=${dontStop}`)
    }
    } else {
    await mkBlocker
    mkBlocker = new Promise((resolve, reject) => {
    blockerResolve = resolve
    blockerReject = reject
    })
    }
    }
    }

    return {
    pub,
    pubOver,
    gen,
    steps,
    dates,
    close
    }
    }

    export {
    intermittentDrummer
    }