1 |
- {"version":3,"file":"index.es.js","sources":["../src/ScheduledTask.js","../src/RelativeScheduler.js","../src/task.js","../src/Scheduler.js","../src/Timeline.js","../src/ClockTimer.js","../src/clock.js","../src/schedule.js","../src/relative.js","../src/index.js"],"sourcesContent":["/** @license MIT License (c) copyright 2010-2017 original author or authors */\n\nexport default class ScheduledTask {\n constructor (time, localOffset, period, task, scheduler) {\n this.time = time\n this.localOffset = localOffset\n this.period = period\n this.task = task\n this.scheduler = scheduler\n this.active = true\n }\n\n run () {\n return this.task.run(this.time - this.localOffset)\n }\n\n error (e) {\n return this.task.error(this.time - this.localOffset, e)\n }\n\n dispose () {\n this.active = false\n this.scheduler.cancel(this)\n return this.task.dispose()\n }\n}\n","export default class RelativeScheduler {\n constructor (origin, scheduler) {\n this.origin = origin\n this.scheduler = scheduler\n }\n\n currentTime () {\n return this.scheduler.currentTime() - this.origin\n }\n\n scheduleTask (localOffset, delay, period, task) {\n return this.scheduler.scheduleTask(localOffset + this.origin, delay, period, task)\n }\n\n relative (origin) {\n return new RelativeScheduler(origin + this.origin, this.scheduler)\n }\n\n cancel (task) {\n return this.scheduler.cancel(task)\n }\n\n cancelAll (f) {\n return this.scheduler.cancelAll(f)\n }\n}\n","/** @license MIT License (c) copyright 2010-2017 original author or authors */\n\nexport const defer = task =>\n Promise.resolve(task).then(runTask)\n\nexport function runTask (task) {\n try {\n return task.run()\n } catch (e) {\n return task.error(e)\n }\n}\n","/** @license MIT License (c) copyright 2010-2017 original author or authors */\n\nimport ScheduledTask from './ScheduledTask'\nimport RelativeScheduler from './RelativeScheduler'\nimport { runTask } from './task'\n\nexport default class Scheduler {\n constructor (timer, timeline) {\n this.timer = timer\n this.timeline = timeline\n\n this._timer = null\n this._nextArrival = Infinity\n\n this._runReadyTasksBound = () => this._runReadyTasks(this.currentTime())\n }\n\n currentTime () {\n return this.timer.now()\n }\n\n scheduleTask (localOffset, delay, period, task) {\n const time = this.currentTime() + Math.max(0, delay)\n const st = new ScheduledTask(time, localOffset, period, task, this)\n\n this.timeline.add(st)\n this._scheduleNextRun()\n return st\n }\n\n relative (offset) {\n return new RelativeScheduler(offset, this)\n }\n\n cancel (task) {\n task.active = false\n if (this.timeline.remove(task)) {\n this._reschedule()\n }\n }\n\n // @deprecated\n cancelAll (f) {\n this.timeline.removeAll(f)\n this._reschedule()\n }\n\n _reschedule () {\n if (this.timeline.isEmpty()) {\n this._unschedule()\n } else {\n this._scheduleNextRun(this.currentTime())\n }\n }\n\n _unschedule () {\n this.timer.clearTimer(this._timer)\n this._timer = null\n }\n\n _scheduleNextRun () { // eslint-disable-line complexity\n if (this.timeline.isEmpty()) {\n return\n }\n\n const nextArrival = this.timeline.nextArrival()\n\n if (this._timer === null) {\n this._scheduleNextArrival(nextArrival)\n } else if (nextArrival < this._nextArrival) {\n this._unschedule()\n this._scheduleNextArrival(nextArrival)\n }\n }\n\n _scheduleNextArrival (nextArrival) {\n this._nextArrival = nextArrival\n const delay = Math.max(0, nextArrival - this.currentTime())\n this._timer = this.timer.setTimer(this._runReadyTasksBound, delay)\n }\n\n _runReadyTasks () {\n this._timer = null\n this.timeline.runTasks(this.currentTime(), runTask)\n this._scheduleNextRun()\n }\n}\n","/** @license MIT License (c) copyright 2010-2017 original author or authors */\n\nimport { findIndex, removeAll } from '@most/prelude'\n\nexport default class Timeline {\n constructor () {\n this.tasks = []\n }\n\n nextArrival () {\n return this.isEmpty() ? Infinity : this.tasks[0].time\n }\n\n isEmpty () {\n return this.tasks.length === 0\n }\n\n add (st) {\n insertByTime(st, this.tasks)\n }\n\n remove (st) {\n const i = binarySearch(getTime(st), this.tasks)\n\n if (i >= 0 && i < this.tasks.length) {\n const events = this.tasks[i].events\n const at = findIndex(st, events)\n if (at >= 0) {\n events.splice(at, 1)\n if (events.length === 0) {\n this.tasks.splice(i, 1)\n }\n return true\n }\n }\n\n return false\n }\n\n // @deprecated\n removeAll (f) {\n for (let i = 0; i < this.tasks.length; ++i) {\n removeAllFrom(f, this.tasks[i])\n }\n }\n\n runTasks (t, runTask) {\n const tasks = this.tasks\n const l = tasks.length\n let i = 0\n\n while (i < l && tasks[i].time <= t) {\n ++i\n }\n\n this.tasks = tasks.slice(i)\n\n // Run all ready tasks\n for (let j = 0; j < i; ++j) {\n this.tasks = runReadyTasks(runTask, tasks[j].events, this.tasks)\n }\n }\n}\n\nfunction runReadyTasks (runTask, events, tasks) { // eslint-disable-line complexity\n for (let i = 0; i < events.length; ++i) {\n const task = events[i]\n\n if (task.active) {\n runTask(task)\n\n // Reschedule periodic repeating tasks\n // Check active again, since a task may have canceled itself\n if (task.period >= 0 && task.active) {\n task.time = task.time + task.period\n insertByTime(task, tasks)\n }\n }\n }\n\n return tasks\n}\n\nfunction insertByTime (task, timeslots) {\n const l = timeslots.length\n const time = getTime(task)\n\n if (l === 0) {\n timeslots.push(newTimeslot(time, [task]))\n return\n }\n\n const i = binarySearch(time, timeslots)\n\n if (i >= l) {\n timeslots.push(newTimeslot(time, [task]))\n } else {\n insertAtTimeslot(task, timeslots, time, i)\n }\n}\n\nfunction insertAtTimeslot (task, timeslots, time, i) {\n const timeslot = timeslots[i]\n if (time === timeslot.time) {\n addEvent(task, timeslot.events, time)\n } else {\n timeslots.splice(i, 0, newTimeslot(time, [task]))\n }\n}\n\nfunction addEvent (task, events) {\n if (events.length === 0 || task.time >= events[events.length - 1].time) {\n events.push(task)\n } else {\n spliceEvent(task, events)\n }\n}\n\nfunction spliceEvent (task, events) {\n for (let j = 0; j < events.length; j++) {\n if (task.time < events[j].time) {\n events.splice(j, 0, task)\n break\n }\n }\n}\n\nfunction getTime (scheduledTask) {\n return Math.floor(scheduledTask.time)\n}\n\n// @deprecated\nfunction removeAllFrom (f, timeslot) {\n timeslot.events = removeAll(f, timeslot.events)\n}\n\nfunction binarySearch (t, sortedArray) { // eslint-disable-line complexity\n let lo = 0\n let hi = sortedArray.length\n let mid, y\n\n while (lo < hi) {\n mid = Math.floor((lo + hi) / 2)\n y = sortedArray[mid]\n\n if (t === y.time) {\n return mid\n } else if (t < y.time) {\n hi = mid\n } else {\n lo = mid + 1\n }\n }\n return hi\n}\n\nconst newTimeslot = (t, events) => ({ time: t, events: events })\n","/** @license MIT License (c) copyright 2010-2017 original author or authors */\n\nimport { defer } from './task'\n\n/* global setTimeout, clearTimeout */\n\nexport default class ClockTimer {\n constructor (clock) {\n this._clock = clock\n }\n\n now () {\n return this._clock.now()\n }\n\n setTimer (f, dt) {\n return dt <= 0 ? runAsap(f) : setTimeout(f, dt)\n }\n\n clearTimer (t) {\n return t instanceof Asap ? t.cancel() : clearTimeout(t)\n }\n}\n\nclass Asap {\n constructor (f) {\n this.f = f\n this.active = true\n }\n\n run () {\n return this.active && this.f()\n }\n\n error (e) {\n throw e\n }\n\n cancel () {\n this.active = false\n }\n}\n\nfunction runAsap (f) {\n const task = new Asap(f)\n defer(task)\n return task\n}\n","/** @license MIT License (c) copyright 2010-2017 original author or authors */\n\n/* global performance, process */\n\nexport class RelativeClock {\n constructor (clock, origin) {\n this.origin = origin\n this.clock = clock\n }\n\n now () {\n return this.clock.now() - this.origin\n }\n}\n\nexport class HRTimeClock {\n constructor (hrtime, origin) {\n this.origin = origin\n this.hrtime = hrtime\n }\n\n now () {\n const hrt = this.hrtime(this.origin)\n return (hrt[0] * 1e9 + hrt[1]) / 1e6\n }\n}\n\nexport const clockRelativeTo = clock =>\n new RelativeClock(clock, clock.now())\n\nexport const newPerformanceClock = () =>\n clockRelativeTo(performance)\n\n
|