commit b5f48369619a86a598a59487231d871b94aff0e5 Author: Jesse McDonald Date: Tue Mar 31 18:46:43 2020 -0500 initial commit diff --git a/package.json b/package.json new file mode 100644 index 0000000..7c2b3e7 --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "promise-stream", + "version": "0.1.0", + "description": "a stream of updates connected with promises", + "main": "promise-stream.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Jesse McDonald ", + "license": "CC-PDDC" +} diff --git a/promise-stream.js b/promise-stream.js new file mode 100644 index 0000000..087add1 --- /dev/null +++ b/promise-stream.js @@ -0,0 +1,72 @@ +(function(factory) { + if (typeof define !== 'undefined' && define.amd) { + define([], factory); + } else if (typeof define !== 'undefined' && define.petal) { + define(['promise-stream'], [], factory); + } else if (typeof module !== 'undefined' && module.exports) { + module.exports = factory(); + } else { + window.PromiseStream = factory(); + } +})(function() { + class PromiseStream { + constructor() { + this._current = new Promise((resolve) => { + this._resolve = resolve; + }); + this._next = this._current; + this._value = undefined; + } + + get promise() { + /* waits for the _first_ update, or completes immediately */ + return this._current; + } + + get next_promise() { + /* waits for the _next_ update (which may be the first) */ + return this._next; + } + + get value() { + return this._value; + } + + update(value) { + if (value !== undefined && value !== this._value) { + const resolve = this._resolve; + const current = this._next; + const next = new Promise((resolve) => { + this._resolve = resolve; + }); + + this._current = current; + this._next = next; + this._value = value; + + resolve({ value, next }); + } + } + + once(cb) { + this.promise.then((v) => { cb(v.value); }); + } + + listen(cb) { + let cancelled = false; + + function renew(v) { + if (!cancelled) { + cb(v.value); + v.next.then(renew); + } + } + + this.promise.then(renew); + + return () => { cancelled = true; }; + } + } + + return PromiseStream; +});