Comparing version
@@ -1,3 +0,5 @@ | ||
export * from "./Promist.js"; | ||
export * from "./LazyPromist.js"; | ||
export * from "./types.js"; | ||
export * from "./CancellablePromise.js"; | ||
export * from "./DeferredPromise.js"; | ||
export * from "./ExtensiblePromise.js"; | ||
export * from "./LazyPromise.js"; | ||
export * from "./SyncPromise.js"; |
@@ -1,4 +0,4 @@ | ||
export * from "./create/index.js"; | ||
export * from "./classes/index.js"; | ||
export * from "./utils/index.js"; | ||
export * from "./collections/index.js"; | ||
export * from "./collection/index.js"; | ||
export * from "./creation/index.js"; | ||
export * from "./utils/index.js"; // TODO: upgrade to native AbortController |
export * from "./control.js"; | ||
export * from "./is-promise.js"; | ||
export * from "./guards.js"; |
@@ -0,180 +1,253 @@ | ||
import { TypeGuard } from 'type-core'; | ||
var _Symbol$toStringTag; | ||
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); } | ||
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } | ||
function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); } | ||
function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } | ||
function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; } | ||
function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } | ||
function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } } | ||
var _promise = /*#__PURE__*/new WeakMap(); | ||
_Symbol$toStringTag = Symbol.toStringTag; | ||
/** | ||
* Will wait for `ms` milliseconds before resolving with an empty response. | ||
* A safe to extend Promise, as its methods will | ||
* not use the new class' constructor, | ||
* but the one of the global Promise object. | ||
*/ | ||
function wait(ms) { | ||
return new Promise(resolve => setTimeout(resolve, ms)); | ||
class ExtensiblePromise { | ||
constructor(executor) { | ||
_classPrivateFieldInitSpec(this, _promise, { | ||
writable: true, | ||
value: void 0 | ||
}); | ||
_classPrivateFieldSet(this, _promise, new Promise(executor)); | ||
} | ||
get [_Symbol$toStringTag]() { | ||
return 'ExtensiblePromise'; | ||
} | ||
then(onfulfilled, onrejected) { | ||
return _classPrivateFieldGet(this, _promise).then(onfulfilled, onrejected); | ||
} | ||
catch(onrejected) { | ||
return _classPrivateFieldGet(this, _promise).catch(onrejected); | ||
} | ||
finally(onfinally) { | ||
return _classPrivateFieldGet(this, _promise).finally(onfinally); | ||
} | ||
} | ||
var _Symbol$toStringTag$1; | ||
function _classPrivateFieldInitSpec$1(obj, privateMap, value) { _checkPrivateRedeclaration$1(obj, privateMap); privateMap.set(obj, value); } | ||
function _checkPrivateRedeclaration$1(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } | ||
function _classPrivateFieldGet$1(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor$1(receiver, privateMap, "get"); return _classApplyDescriptorGet$1(receiver, descriptor); } | ||
function _classApplyDescriptorGet$1(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } | ||
function _classPrivateFieldSet$1(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor$1(receiver, privateMap, "set"); _classApplyDescriptorSet$1(receiver, descriptor, value); return value; } | ||
function _classExtractFieldDescriptor$1(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } | ||
function _classApplyDescriptorSet$1(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } } | ||
var _onCancel = /*#__PURE__*/new WeakMap(); | ||
_Symbol$toStringTag$1 = Symbol.toStringTag; | ||
/** | ||
* Will not resolve until `test` returns `true`, running it every `ms` | ||
* milliseconds. If `safe` is `true`, it will treat `test` throws and | ||
* rejections as `false`, instead of rejecting itself. | ||
* A cancellable Promise, taking a cancellation | ||
* function returning executor. | ||
* Cancellation can be triggered through | ||
* the `cancel` method, or by an AbortSignal. | ||
*/ | ||
function until(test, safe) { | ||
var ms = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 25; | ||
return new Promise((resolve, reject) => { | ||
var reset = () => setTimeout(trunk, ms); | ||
class CancellablePromise extends ExtensiblePromise { | ||
constructor(executor, signal) { | ||
var onCancel = null; | ||
super((resolve, reject) => { | ||
onCancel = executor(resolve, reject); | ||
}); | ||
trunk(); | ||
_classPrivateFieldInitSpec$1(this, _onCancel, { | ||
writable: true, | ||
value: void 0 | ||
}); | ||
function trunk() { | ||
try { | ||
Promise.resolve(test()).then(value => value ? resolve() : reset(), reason => safe ? reset() : reject(reason)); | ||
} catch (err) { | ||
safe ? reset() : reject(err); | ||
_classPrivateFieldSet$1(this, _onCancel, onCancel); | ||
if (signal) { | ||
if (signal.aborted) this.cancel();else { | ||
var onAbort = () => { | ||
signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort); | ||
this.cancel(); | ||
}; | ||
signal.addEventListener('abort', onAbort); | ||
} | ||
} | ||
}); | ||
} | ||
get [_Symbol$toStringTag$1]() { | ||
return 'CancellablePromise'; | ||
} | ||
/** | ||
* Trigger Promise cancellation | ||
*/ | ||
cancel() { | ||
var onCancel = _classPrivateFieldGet$1(this, _onCancel); | ||
if (!onCancel) return; | ||
_classPrivateFieldSet$1(this, _onCancel, null); | ||
onCancel(); | ||
} | ||
} | ||
/** | ||
* Subscribes to an `observable` and resolves/rejects with | ||
* its first value. By default, it will reject if the observable | ||
* completes before emitting any values, though this behavior | ||
* can be controlled via `onComplete`. | ||
*/ | ||
function subscribe(observable, onComplete) { | ||
return new Promise((resolve, reject) => { | ||
var emitted = false; | ||
var subscription = observable.subscribe({ | ||
next(value) { | ||
resolve(value); | ||
unsubscribe(); | ||
}, | ||
class Util { | ||
static noop() { | ||
return undefined; | ||
} | ||
error(error) { | ||
reject(error); | ||
unsubscribe(); | ||
}, | ||
static operate(cb, success, failure) { | ||
var response; | ||
complete() { | ||
if (emitted) return; | ||
if (onComplete) onComplete(resolve, reject);else reject(Error("Source completed without emitting any values")); | ||
unsubscribe(); | ||
} | ||
try { | ||
response = cb(); | ||
} catch (err) { | ||
if (failure) return failure(err);else throw err; | ||
} | ||
}); | ||
if (TypeGuard.isPromiseLike(response)) { | ||
return success || failure ? response.then(success, failure) : response; | ||
} else { | ||
return success ? success(response) : response; | ||
} | ||
} | ||
function unsubscribe() { | ||
emitted = true; | ||
until(() => Boolean(subscription), true).then(() => subscription.unsubscribe()); | ||
} | ||
}); | ||
} | ||
var _Symbol$toStringTag; | ||
var _Symbol$toStringTag$2; | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
var INTERNAL_SYMBOL = Symbol('internal'); | ||
_Symbol$toStringTag = Symbol.toStringTag; | ||
function _classPrivateFieldInitSpec$2(obj, privateMap, value) { _checkPrivateRedeclaration$2(obj, privateMap); privateMap.set(obj, value); } | ||
function _checkPrivateRedeclaration$2(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } | ||
function _classPrivateFieldGet$2(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor$2(receiver, privateMap, "get"); return _classApplyDescriptorGet$2(receiver, descriptor); } | ||
function _classApplyDescriptorGet$2(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } | ||
function _classPrivateFieldSet$2(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor$2(receiver, privateMap, "set"); _classApplyDescriptorSet$2(receiver, descriptor, value); return value; } | ||
function _classExtractFieldDescriptor$2(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } | ||
function _classApplyDescriptorSet$2(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } } | ||
/** | ||
* `Promist` behaves just like a traditional `Promise`, with a few | ||
* additional features: | ||
* - It can be externally resolved and/or rejected. | ||
* - It can also be externally cancelled. If using an executor on | ||
* the `Promist` constructor, you can receive external completion | ||
* events (resolution/rejection/cancellation) via the returned | ||
* callback, in order to free up resources, if needed. Externally, | ||
* you also have access to this event (including cancellation) | ||
* via the `Promist.react` promise. | ||
* - It will always have the `finally` method available, | ||
* regardless of the underlying `Promise` implementation. | ||
* | ||
* The difference between `Promist`s static methods and create functions | ||
* is that in any completion event, they will always clean up after themselves, | ||
* clearing the underlying timeouts and/or subscriptions. | ||
* An externally actionable Promise | ||
* with `resolve` and `reject` methods. | ||
*/ | ||
class Promist { | ||
/** | ||
* Creates a `Promist` from a `Promise` or a *sync* or *async* function. | ||
*/ | ||
static from(promise) { | ||
return new this((resolve, reject) => { | ||
try { | ||
Promise.resolve(typeof promise === 'function' ? promise() : promise).then(resolve).catch(reject); | ||
} catch (err) { | ||
return reject(err); | ||
} | ||
var _resolve = /*#__PURE__*/new WeakMap(); | ||
var _reject = /*#__PURE__*/new WeakMap(); | ||
_Symbol$toStringTag$2 = Symbol.toStringTag; | ||
class DeferredPromise extends ExtensiblePromise { | ||
constructor() { | ||
var res = Util.noop; | ||
var rej = Util.noop; | ||
super((resolve, reject) => { | ||
res = resolve; | ||
rej = reject; | ||
}); | ||
_classPrivateFieldInitSpec$2(this, _resolve, { | ||
writable: true, | ||
value: void 0 | ||
}); | ||
_classPrivateFieldInitSpec$2(this, _reject, { | ||
writable: true, | ||
value: void 0 | ||
}); | ||
_classPrivateFieldSet$2(this, _resolve, res); | ||
_classPrivateFieldSet$2(this, _reject, rej); | ||
} | ||
get [_Symbol$toStringTag$2]() { | ||
return 'DeferredPromise'; | ||
} | ||
/** | ||
* Will wait for `ms` milliseconds before resolving with an empty response. | ||
* Resolves the promise with `value`. | ||
*/ | ||
static wait(ms) { | ||
return new this(resolve => { | ||
var timeout = setTimeout(resolve, ms); | ||
return () => clearTimeout(timeout); | ||
}); | ||
resolve(value) { | ||
_classPrivateFieldGet$2(this, _resolve).call(this, value); | ||
} | ||
/** | ||
* Will not resolve until `test` returns `true`, running it every `ms` | ||
* milliseconds. If `safe` is `true`, it will treat `test` throws and | ||
* rejections as `false`, instead of rejecting itself. | ||
* Rejects the promise with `reason`. | ||
*/ | ||
static until(test, safe) { | ||
var ms = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 25; | ||
return new this((resolve, reject) => { | ||
var didComplete = false; | ||
var timeout = null; | ||
trunk(); | ||
reject(reason) { | ||
_classPrivateFieldGet$2(this, _reject).call(this, reason); | ||
} | ||
function reset() { | ||
if (didComplete) return; | ||
timeout = setTimeout(trunk, ms); | ||
} | ||
} | ||
function trunk() { | ||
try { | ||
Promise.resolve(test()).then(value => value ? resolve() : reset(), reason => safe ? reset() : reject(reason)); | ||
} catch (err) { | ||
safe ? reset() : reject(err); | ||
} | ||
} | ||
var _Symbol$toStringTag$3; | ||
return () => { | ||
didComplete = true; | ||
if (timeout) clearTimeout(timeout); | ||
}; | ||
}); | ||
} | ||
/** | ||
* Subscribes to an `observable` and resolves/rejects with | ||
* its first value. By default, it will reject if the observable | ||
* completes before emitting any values, though this behavior | ||
* can be controlled via `onComplete`. | ||
*/ | ||
function _classPrivateFieldInitSpec$3(obj, privateMap, value) { _checkPrivateRedeclaration$3(obj, privateMap); privateMap.set(obj, value); } | ||
function _checkPrivateRedeclaration$3(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } | ||
static subscribe(observable, onComplete) { | ||
return new this((resolve, reject) => { | ||
var emitted = false; | ||
var subscription = observable.subscribe({ | ||
next(value) { | ||
emitted = true; | ||
resolve(value); | ||
}, | ||
function _classPrivateFieldGet$3(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor$3(receiver, privateMap, "get"); return _classApplyDescriptorGet$3(receiver, descriptor); } | ||
error(error) { | ||
emitted = true; | ||
reject(error); | ||
}, | ||
function _classApplyDescriptorGet$3(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } | ||
complete() { | ||
if (emitted) return; | ||
function _classPrivateFieldSet$3(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor$3(receiver, privateMap, "set"); _classApplyDescriptorSet$3(receiver, descriptor, value); return value; } | ||
if (onComplete) { | ||
onComplete(resolve, reject); | ||
until(() => Boolean(subscription), true).then(() => subscription.unsubscribe()); | ||
} else { | ||
reject(Error("Source completed without emitting any values")); | ||
} | ||
} | ||
function _classExtractFieldDescriptor$3(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } | ||
}); | ||
return () => subscription.unsubscribe(); | ||
function _classApplyDescriptorSet$3(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } } | ||
var _execute = /*#__PURE__*/new WeakMap(); | ||
_Symbol$toStringTag$3 = Symbol.toStringTag; | ||
/** | ||
* A Promise whose executor will not execute | ||
* until the first time it is awaited. | ||
*/ | ||
class LazyPromise extends ExtensiblePromise { | ||
/** | ||
* Creates a LazyPromise from a function. | ||
*/ | ||
static from(create) { | ||
return new LazyPromise((resolve, reject) => { | ||
Promise.resolve().then(() => create()).then(resolve, reject); | ||
}); | ||
@@ -184,149 +257,249 @@ } | ||
constructor(executor) { | ||
_defineProperty(this, INTERNAL_SYMBOL, void 0); | ||
var execute = Util.noop; | ||
super((resolve, reject) => { | ||
execute = () => executor(resolve, reject); | ||
}); | ||
var actions = null; | ||
var promise = new Promise((resolve, reject) => { | ||
actions = { | ||
resolve, | ||
reject | ||
}; | ||
_classPrivateFieldInitSpec$3(this, _execute, { | ||
writable: true, | ||
value: void 0 | ||
}); | ||
var internal = { | ||
promise, | ||
state: { | ||
status: 'pending', | ||
value: null, | ||
reason: null | ||
}, | ||
actions | ||
}; | ||
this[INTERNAL_SYMBOL] = internal; | ||
if (executor) { | ||
var complete = executor(this.resolve.bind(this), this.reject.bind(this)); | ||
_classPrivateFieldSet$3(this, _execute, () => { | ||
_classPrivateFieldSet$3(this, _execute, Util.noop); | ||
if (complete && typeof complete === 'function') { | ||
if (internal.state.status === 'pending') this.react.then(complete);else complete(); | ||
} | ||
} | ||
execute(); | ||
}); | ||
} | ||
get [_Symbol$toStringTag]() { | ||
return 'Promise'; | ||
get [_Symbol$toStringTag$3]() { | ||
return 'LazyPromise'; | ||
} | ||
get status() { | ||
return this[INTERNAL_SYMBOL].state.status; | ||
then(onfulfilled, onrejected) { | ||
_classPrivateFieldGet$3(this, _execute).call(this); | ||
return super.then(onfulfilled, onrejected); | ||
} | ||
get value() { | ||
return this[INTERNAL_SYMBOL].state.value; | ||
catch(onrejected) { | ||
_classPrivateFieldGet$3(this, _execute).call(this); | ||
return super.catch(onrejected); | ||
} | ||
get reason() { | ||
return this[INTERNAL_SYMBOL].state.reason; | ||
finally(onfinally) { | ||
_classPrivateFieldGet$3(this, _execute).call(this); | ||
return super.finally(onfinally); | ||
} | ||
get react() { | ||
var internal = this[INTERNAL_SYMBOL]; | ||
return new Promise(resolve => { | ||
if (internal.state.status !== 'pending') return resolve(); | ||
var oncomplete = internal.oncomplete; | ||
internal.oncomplete = oncomplete ? () => { | ||
oncomplete(); | ||
resolve(); | ||
} : resolve; | ||
} | ||
var _Symbol$toStringTag$4; | ||
function _classPrivateFieldInitSpec$4(obj, privateMap, value) { _checkPrivateRedeclaration$4(obj, privateMap); privateMap.set(obj, value); } | ||
function _checkPrivateRedeclaration$4(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } | ||
function _classPrivateFieldGet$4(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor$4(receiver, privateMap, "get"); return _classApplyDescriptorGet$4(receiver, descriptor); } | ||
function _classApplyDescriptorGet$4(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } | ||
function _classPrivateFieldSet$4(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor$4(receiver, privateMap, "set"); _classApplyDescriptorSet$4(receiver, descriptor, value); return value; } | ||
function _classExtractFieldDescriptor$4(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } | ||
function _classApplyDescriptorSet$4(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } } | ||
var _response = /*#__PURE__*/new WeakMap(); | ||
_Symbol$toStringTag$4 = Symbol.toStringTag; | ||
/** | ||
* A promise that will make its resolved or rejected values | ||
* synchronously available and operable. | ||
*/ | ||
class SyncPromise extends ExtensiblePromise { | ||
/** | ||
* Creates a SyncPromise from a function. | ||
*/ | ||
static from(create) { | ||
return new SyncPromise((resolve, reject) => { | ||
try { | ||
var response = create(); | ||
if (TypeGuard.isPromiseLike(response)) { | ||
Promise.resolve(response).then(resolve, reject); | ||
} else { | ||
resolve(response); | ||
} | ||
} catch (err) { | ||
reject(err); | ||
} | ||
}); | ||
} | ||
then(onfulfilled, onrejected) { | ||
return this[INTERNAL_SYMBOL].promise.then(onfulfilled, onrejected); | ||
} | ||
constructor(executor) { | ||
var complete = false; | ||
var response = { | ||
data: null | ||
}; | ||
super((resolve, reject) => { | ||
executor(value => { | ||
if (complete) return; | ||
complete = true; | ||
catch(onrejected) { | ||
return this.then(undefined, onrejected); | ||
if (TypeGuard.isPromiseLike(value)) { | ||
Promise.resolve(value).then(value => { | ||
response.data = [value]; | ||
}, reason => { | ||
response.data = [null, reason]; | ||
}); | ||
} else { | ||
response.data = [value]; | ||
} | ||
resolve(value); | ||
}, reason => { | ||
if (complete) return; | ||
complete = true; | ||
response.data = [null, reason]; | ||
reject(reason); | ||
}); | ||
}); | ||
_classPrivateFieldInitSpec$4(this, _response, { | ||
writable: true, | ||
value: void 0 | ||
}); | ||
_classPrivateFieldSet$4(this, _response, response); | ||
} | ||
finally(fn) { | ||
return this.then(value => Promise.resolve(fn && fn()).then(() => value), reason => Promise.resolve(fn && fn()).then(() => Promise.reject(reason))); | ||
get [_Symbol$toStringTag$4]() { | ||
return 'SyncPromise'; | ||
} | ||
/** | ||
* Resolves the `Promist` with `value`. | ||
* Returns a Promise if pending, otherwise | ||
* it will synchronously return or throw. | ||
*/ | ||
resolve(value) { | ||
var { | ||
state, | ||
actions, | ||
oncomplete | ||
} = this[INTERNAL_SYMBOL]; | ||
if (state.status !== 'pending') return; | ||
state.status = 'resolved'; | ||
state.value = value; | ||
actions.resolve(value); | ||
if (oncomplete) oncomplete(); | ||
consume() { | ||
var data = _classPrivateFieldGet$4(this, _response).data; | ||
if (!data) return Promise.resolve(this); | ||
if (data.length === 1) return data[0]; // prevent promise rejection | ||
this.catch(() => undefined); | ||
throw data[1]; | ||
} | ||
/** | ||
* Rejects the `Promist` with `reason`. | ||
* An agnostic and chainable method to operate | ||
* on a SyncPromise. It will execute asynchronously | ||
* if values are pending, and synchronously otherwise. | ||
*/ | ||
reject(reason) { | ||
var { | ||
state, | ||
actions, | ||
oncomplete | ||
} = this[INTERNAL_SYMBOL]; | ||
if (state.status !== 'pending') return; | ||
state.status = 'rejected'; | ||
state.reason = reason; | ||
actions.reject(reason); | ||
if (oncomplete) oncomplete(); | ||
operate(success, failure, finalize) { | ||
return new SyncPromise((resolve, reject) => { | ||
Util.operate(() => this.consume(), value => { | ||
if (success) { | ||
return Util.operate(() => success(value), response => { | ||
return finalize ? Util.operate(finalize, () => resolve(response), reject) : resolve(response); | ||
}, err => { | ||
return finalize ? Util.operate(finalize, () => reject(err), reject) : reject(err); | ||
}); | ||
} else if (finalize) { | ||
return Util.operate(finalize, () => resolve(value), reject); | ||
} else { | ||
return resolve(value); | ||
} | ||
}, err => { | ||
if (failure) { | ||
return Util.operate(() => failure(err), response => { | ||
return finalize ? Util.operate(finalize, () => resolve(response), reject) : resolve(response); | ||
}, err => { | ||
return finalize ? Util.operate(finalize, () => reject(err), reject) : reject(err); | ||
}); | ||
} else if (finalize) { | ||
return Util.operate(finalize, () => reject(err), reject); | ||
} else { | ||
return reject(err); | ||
} | ||
}); | ||
}); | ||
} | ||
} | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } | ||
class Parallel { | ||
/** | ||
* Cancels the `Promist`. | ||
* If it didn't already, it will never resolve nor reject. | ||
* Maps an iterable by running the callback | ||
* function in parallel. | ||
*/ | ||
static map(iterable, fn) { | ||
return _asyncToGenerator(function* () { | ||
var arr = Array.from(iterable); | ||
var response = yield Promise.all(arr); | ||
return Promise.all(response.map(fn)); | ||
})(); | ||
} | ||
/** | ||
* Filters an iterable by running the callback | ||
* function in parallel. | ||
*/ | ||
cancel() { | ||
var { | ||
state, | ||
oncomplete | ||
} = this[INTERNAL_SYMBOL]; | ||
if (state.status !== 'pending') return; | ||
state.status = 'cancelled'; | ||
if (oncomplete) oncomplete(); | ||
static filter(iterable, fn) { | ||
return _asyncToGenerator(function* () { | ||
var skip = {}; | ||
var arr = Array.from(iterable); | ||
var values = yield Parallel.map(arr, /*#__PURE__*/function () { | ||
var _ref = _asyncToGenerator(function* (x, i, arr) { | ||
var select = yield fn(x, i, arr); | ||
return select ? x : skip; | ||
}); | ||
return function (_x, _x2, _x3) { | ||
return _ref.apply(this, arguments); | ||
}; | ||
}()); | ||
return values.filter(x => x !== skip); | ||
})(); | ||
} | ||
/** | ||
* Sets a timeout of `ms` milliseconds after which, if the `Promist` | ||
* hasn't resolved, rejected, or cancelled, it will reject with `reason`. | ||
* Reduces an iterable by running the callback | ||
* function in parallel. | ||
*/ | ||
timeout(ms, reason) { | ||
var { | ||
state | ||
} = this[INTERNAL_SYMBOL]; | ||
if (state.status !== 'pending') return; | ||
var timeout = setTimeout(() => { | ||
this.reject(reason || Error('Promise timed out')); | ||
}, ms); | ||
this.react.then(() => clearTimeout(timeout)); | ||
static reduce(iterable, fn, initialValue) { | ||
return _asyncToGenerator(function* () { | ||
var arr = Array.from(iterable); | ||
var values = yield Promise.all(arr); | ||
var acc = initialValue === undefined ? Promise.resolve(arr[0]) : Promise.resolve(fn(Promise.resolve(initialValue), yield arr[0], 0, values)); | ||
for (var i = 1; i < arr.length; i++) { | ||
acc = Promise.resolve(fn(acc, yield arr[i], i, values)); | ||
} | ||
return acc; | ||
})(); | ||
} | ||
/** | ||
* Sets a timeout of `ms` milliseconds after which, if the `Promist` | ||
* hasn't resolved, rejected, or cancelled, it will resolve | ||
* by falling back to `value`. | ||
* Runs a callback for each item of | ||
* an Iterable in parallel. | ||
*/ | ||
fallback(ms, value) { | ||
var { | ||
state | ||
} = this[INTERNAL_SYMBOL]; | ||
if (state.status !== 'pending') return; | ||
var timeout = setTimeout(() => this.resolve(value), ms); | ||
this.react.then(() => clearTimeout(timeout)); | ||
static each(iterable, fn) { | ||
return _asyncToGenerator(function* () { | ||
yield Parallel.map(iterable, fn); | ||
})(); | ||
} | ||
@@ -336,83 +509,147 @@ | ||
function _defineProperty$1(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
var INTERNAL_SYMBOL$1 = Symbol('internal'); | ||
function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
/** | ||
* `LazyPromist`s don't run their constructor `executor` until | ||
* after they've been explicitly expected to resolve | ||
* by a `then`, `catch`, or `finally` call. | ||
*/ | ||
class LazyPromist extends Promist { | ||
constructor(executor) { | ||
super(); | ||
function _asyncToGenerator$1(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } | ||
_defineProperty$1(this, INTERNAL_SYMBOL$1, void 0); | ||
class Series { | ||
/** | ||
* Maps an iterable by running the callback | ||
* function in series. | ||
*/ | ||
static map(iterable, fn) { | ||
return _asyncToGenerator$1(function* () { | ||
var arr = Array.from(iterable); | ||
var response = []; | ||
var executed = false; | ||
this[INTERNAL_SYMBOL$1] = { | ||
get executed() { | ||
return executed; | ||
}, | ||
for (var i = 0; i < arr.length; i++) { | ||
response.push(yield fn(yield arr[i], i, arr)); | ||
} | ||
execute: () => { | ||
if (executed || this.status !== 'pending') return; | ||
executed = true; | ||
var complete = executor(this.resolve.bind(this), this.reject.bind(this)); | ||
var { | ||
onstart | ||
} = this[INTERNAL_SYMBOL$1]; | ||
if (onstart) onstart(); | ||
return response; | ||
})(); | ||
} | ||
/** | ||
* Filters an iterable by running the callback | ||
* function in series. | ||
*/ | ||
if (complete && typeof complete === 'function') { | ||
if (this.status === 'pending') this.react.then(complete);else complete(); | ||
} | ||
static filter(iterable, fn) { | ||
return _asyncToGenerator$1(function* () { | ||
var arr = Array.from(iterable); | ||
var response = []; | ||
for (var i = 0; i < arr.length; i++) { | ||
var _value = yield arr[i]; | ||
var select = yield fn(_value, i, arr); | ||
if (select) response.push(_value); | ||
} | ||
}; | ||
return response; | ||
})(); | ||
} | ||
/** | ||
* Reduces an iterable by running the callback | ||
* function in series. | ||
*/ | ||
then(onfulfilled, onrejected) { | ||
this[INTERNAL_SYMBOL$1].execute(); | ||
return super.then(onfulfilled, onrejected); | ||
static reduce(iterable, fn, initialValue) { | ||
return _asyncToGenerator$1(function* () { | ||
var arr = Array.from(iterable); | ||
var response = initialValue === undefined ? yield arr[0] : yield fn(yield initialValue, yield arr[0], 0, arr); | ||
for (var i = 1; i < arr.length; i++) { | ||
response = yield fn(response, yield arr[i], i, arr); | ||
} | ||
return response; | ||
})(); | ||
} | ||
/** | ||
* Runs a callback for each item of | ||
* an Iterable in series. | ||
*/ | ||
timeout(ms, reason) { | ||
var { | ||
executed, | ||
onstart | ||
} = this[INTERNAL_SYMBOL$1]; | ||
if (executed) { | ||
super.timeout(ms, reason); | ||
} else { | ||
this[INTERNAL_SYMBOL$1].onstart = onstart ? () => { | ||
onstart(); | ||
super.timeout(ms, reason); | ||
} : () => super.timeout(ms, reason); | ||
} | ||
static each(iterable, fn) { | ||
return _asyncToGenerator$1(function* () { | ||
yield Series.map(iterable, fn); | ||
})(); | ||
} | ||
fallback(ms, value) { | ||
var { | ||
executed, | ||
onstart | ||
} = this[INTERNAL_SYMBOL$1]; | ||
} | ||
if (executed) { | ||
super.fallback(ms, value); | ||
} else { | ||
this[INTERNAL_SYMBOL$1].onstart = onstart ? () => { | ||
onstart(); | ||
super.fallback(ms, value); | ||
} : () => super.fallback(ms, value); | ||
/** | ||
* Will cancel a CancellablePromise in `delay` milliseconds | ||
*/ | ||
function timeout(delay, executor) { | ||
var opts = TypeGuard.isNumber(delay) ? { | ||
delay | ||
} : delay; | ||
var promise = new CancellablePromise((resolve, reject) => { | ||
var timeout = setTimeout(() => promise.cancel(), opts.delay); | ||
var onCancel = executor(resolve, reject); | ||
return () => { | ||
if (timeout) clearTimeout(timeout); | ||
onCancel(); | ||
}; | ||
}, opts.abortSignal); | ||
return promise; | ||
} | ||
/** | ||
* Will not resolve until `test` returns `true`. | ||
*/ | ||
function until(delay, test) { | ||
var opts = TypeGuard.isNumber(delay) ? { | ||
delay | ||
} : delay; | ||
return new CancellablePromise((resolve, reject) => { | ||
var timeout = null; | ||
var reset = () => { | ||
timeout = setTimeout(trunk, opts.delay || 0); | ||
}; | ||
trunk(); | ||
function trunk() { | ||
try { | ||
Promise.resolve(test()).then(value => value ? resolve() : reset(), reason => opts.ignoreError ? reset() : reject(reason)); | ||
} catch (err) { | ||
opts.ignoreError ? reset() : reject(err); | ||
} | ||
} | ||
} | ||
return () => { | ||
if (timeout) clearTimeout(timeout); | ||
resolve(); | ||
}; | ||
}, opts.abortSignal); | ||
} | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
/** | ||
* Will wait for `delay` milliseconds before resolving with an empty response. | ||
*/ | ||
function wait(delay) { | ||
var opts = TypeGuard.isNumber(delay) ? { | ||
delay | ||
} : delay; | ||
return new CancellablePromise(resolve => { | ||
var timeout = setTimeout(resolve, opts.delay || 0); | ||
return () => { | ||
clearTimeout(timeout); | ||
resolve(); | ||
}; | ||
}, opts.abortSignal); | ||
} | ||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } | ||
function asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
function _asyncToGenerator$2(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } | ||
function control(test, generator) { | ||
return /*#__PURE__*/_asyncToGenerator(function* () { | ||
return /*#__PURE__*/_asyncToGenerator$2(function* () { | ||
var iterator = generator(...arguments); | ||
@@ -435,63 +672,9 @@ var value; | ||
function isPromise(item) { | ||
return isPromiseLike(item) && typeof item.catch === 'function'; | ||
return TypeGuard.isPromise(item); | ||
} | ||
function isPromiseLike(item) { | ||
var typeofItem = typeof item; | ||
return (typeofItem === 'object' && item !== null || typeofItem === 'function') && typeof item.then === 'function'; | ||
return TypeGuard.isPromiseLike(item); | ||
} | ||
function map(arr, fn) { | ||
return Promise.all(arr).then(resArr => Promise.all(resArr.map(fn))); | ||
} | ||
function filter(arr, fn) { | ||
var filterVal = {}; | ||
return Promise.all(arr).then(resArr => Promise.all(resArr.map((x, i) => Promise.resolve(fn(x, i, resArr)).then(ans => ans ? x : filterVal)))).then(arr => arr.filter(x => x !== filterVal)); | ||
} | ||
function reduce(arr, fn, initialValue) { | ||
return Promise.all(arr).then(resArr => { | ||
return resArr.slice(1).reduce((acc, x, i) => { | ||
var p = new Promist(); | ||
acc.then(val => p.resolve(val)).catch(err => p.reject(err)); | ||
return fn(p, x, i + 1, resArr); | ||
}, initialValue === undefined ? Promise.resolve(resArr[0]) : Promise.resolve(fn(Promise.resolve(initialValue), resArr[0], 0, resArr))); | ||
}); | ||
} | ||
function each(arr, fn) { | ||
return map(arr, fn).then(() => undefined); | ||
} | ||
var parallel = { | ||
map, | ||
filter, | ||
reduce, | ||
each | ||
}; | ||
function map$1(arr, fn) { | ||
var ans = []; | ||
return arr.reduce((acc, x, i) => { | ||
return acc.then(() => x).then(val => fn(val, i, arr)).then(res => ans.push(res)); | ||
}, Promise.resolve()).then(() => ans); | ||
} | ||
function filter$1(arr, fn) { | ||
var ans = []; | ||
return arr.reduce((acc, x, i) => { | ||
return acc.then(() => x).then(val => Promise.resolve(fn(val, i, arr)).then(res => res && ans.push(val))); | ||
}, Promise.resolve()).then(() => ans); | ||
} | ||
function reduce$1(arr, fn, initialValue) { | ||
return arr.slice(1).reduce((acc, x, i) => acc.then(val => Promise.resolve(x).then(x => fn(val, x, i + 1, arr))), initialValue === undefined ? Promise.resolve(arr[0]) : Promise.resolve(initialValue).then(val => Promise.resolve(arr[0]).then(x => fn(val, x, 0, arr)))); | ||
} | ||
function each$1(arr, fn) { | ||
return arr.reduce((acc, x, i) => { | ||
return acc.then(() => x).then(val => fn(val, i, arr)); | ||
}, Promise.resolve()).then(() => undefined); | ||
} | ||
var series = { | ||
map: map$1, | ||
filter: filter$1, | ||
reduce: reduce$1, | ||
each: each$1 | ||
}; | ||
export { LazyPromist, Promist, control, isPromise, isPromiseLike, parallel, series, subscribe, until, wait }; | ||
export { CancellablePromise, DeferredPromise, ExtensiblePromise, LazyPromise, Parallel, Series, SyncPromise, control, isPromise, isPromiseLike, timeout, until, wait }; | ||
//# sourceMappingURL=index.js.map |
@@ -1,3 +0,5 @@ | ||
export * from './Promist'; | ||
export * from './LazyPromist'; | ||
export * from './types'; | ||
export * from './CancellablePromise'; | ||
export * from './DeferredPromise'; | ||
export * from './ExtensiblePromise'; | ||
export * from './LazyPromise'; | ||
export * from './SyncPromise'; |
@@ -7,10 +7,11 @@ "use strict"; | ||
var _Promist = require("./Promist"); | ||
var _CancellablePromise = require("./CancellablePromise"); | ||
Object.keys(_Promist).forEach(function (key) { | ||
Object.keys(_CancellablePromise).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _CancellablePromise[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _Promist[key]; | ||
return _CancellablePromise[key]; | ||
} | ||
@@ -20,10 +21,11 @@ }); | ||
var _LazyPromist = require("./LazyPromist"); | ||
var _DeferredPromise = require("./DeferredPromise"); | ||
Object.keys(_LazyPromist).forEach(function (key) { | ||
Object.keys(_DeferredPromise).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _DeferredPromise[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _LazyPromist[key]; | ||
return _DeferredPromise[key]; | ||
} | ||
@@ -33,13 +35,40 @@ }); | ||
var _types = require("./types"); | ||
var _ExtensiblePromise = require("./ExtensiblePromise"); | ||
Object.keys(_types).forEach(function (key) { | ||
Object.keys(_ExtensiblePromise).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _ExtensiblePromise[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _types[key]; | ||
return _ExtensiblePromise[key]; | ||
} | ||
}); | ||
}); | ||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGFzc2VzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFDQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBQ0E7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9Qcm9taXN0JztcbmV4cG9ydCAqIGZyb20gJy4vTGF6eVByb21pc3QnO1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcyc7XG4iXX0= | ||
var _LazyPromise = require("./LazyPromise"); | ||
Object.keys(_LazyPromise).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _LazyPromise[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _LazyPromise[key]; | ||
} | ||
}); | ||
}); | ||
var _SyncPromise = require("./SyncPromise"); | ||
Object.keys(_SyncPromise).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _SyncPromise[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _SyncPromise[key]; | ||
} | ||
}); | ||
}); | ||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGFzc2VzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUNBOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUNBOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUNBOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUNBOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9DYW5jZWxsYWJsZVByb21pc2UnO1xuZXhwb3J0ICogZnJvbSAnLi9EZWZlcnJlZFByb21pc2UnO1xuZXhwb3J0ICogZnJvbSAnLi9FeHRlbnNpYmxlUHJvbWlzZSc7XG5leHBvcnQgKiBmcm9tICcuL0xhenlQcm9taXNlJztcbmV4cG9ydCAqIGZyb20gJy4vU3luY1Byb21pc2UnO1xuIl19 |
@@ -1,4 +0,4 @@ | ||
export * from './create'; | ||
export * from './classes'; | ||
export * from './collection'; | ||
export * from './creation'; | ||
export * from './utils'; | ||
export * from './collections'; |
@@ -7,10 +7,11 @@ "use strict"; | ||
var _create = require("./create"); | ||
var _classes = require("./classes"); | ||
Object.keys(_create).forEach(function (key) { | ||
Object.keys(_classes).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _classes[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _create[key]; | ||
return _classes[key]; | ||
} | ||
@@ -20,10 +21,11 @@ }); | ||
var _classes = require("./classes"); | ||
var _collection = require("./collection"); | ||
Object.keys(_classes).forEach(function (key) { | ||
Object.keys(_collection).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _collection[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _classes[key]; | ||
return _collection[key]; | ||
} | ||
@@ -33,10 +35,11 @@ }); | ||
var _utils = require("./utils"); | ||
var _creation = require("./creation"); | ||
Object.keys(_utils).forEach(function (key) { | ||
Object.keys(_creation).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _creation[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _utils[key]; | ||
return _creation[key]; | ||
} | ||
@@ -46,13 +49,14 @@ }); | ||
var _collections = require("./collections"); | ||
var _utils = require("./utils"); | ||
Object.keys(_collections).forEach(function (key) { | ||
Object.keys(_utils).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _utils[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _collections[key]; | ||
return _utils[key]; | ||
} | ||
}); | ||
}); | ||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBQ0E7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUNBOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFDQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2NyZWF0ZSc7XG5leHBvcnQgKiBmcm9tICcuL2NsYXNzZXMnO1xuZXhwb3J0ICogZnJvbSAnLi91dGlscyc7XG5leHBvcnQgKiBmcm9tICcuL2NvbGxlY3Rpb25zJztcbiJdfQ== | ||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFDQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFDQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFDQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vY2xhc3Nlcyc7XG5leHBvcnQgKiBmcm9tICcuL2NvbGxlY3Rpb24nO1xuZXhwb3J0ICogZnJvbSAnLi9jcmVhdGlvbic7XG5leHBvcnQgKiBmcm9tICcuL3V0aWxzJztcblxuLy8gVE9ETzogdXBncmFkZSB0byBuYXRpdmUgQWJvcnRDb250cm9sbGVyXG4iXX0= |
export * from './control'; | ||
export * from './is-promise'; | ||
export * from './guards'; |
@@ -11,2 +11,3 @@ "use strict"; | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _control[key]) return; | ||
Object.defineProperty(exports, key, { | ||
@@ -20,13 +21,14 @@ enumerable: true, | ||
var _isPromise = require("./is-promise"); | ||
var _guards = require("./guards"); | ||
Object.keys(_isPromise).forEach(function (key) { | ||
Object.keys(_guards).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _guards[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _isPromise[key]; | ||
return _guards[key]; | ||
} | ||
}); | ||
}); | ||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy91dGlscy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBQ0E7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9jb250cm9sJztcbmV4cG9ydCAqIGZyb20gJy4vaXMtcHJvbWlzZSc7XG4iXX0= | ||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy91dGlscy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFDQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vY29udHJvbCc7XG5leHBvcnQgKiBmcm9tICcuL2d1YXJkcyc7XG4iXX0= |
{ | ||
"name": "promist", | ||
"description": "A dependable promises and async utility belt", | ||
"version": "4.0.0", | ||
"version": "5.0.0", | ||
"license": "MIT", | ||
@@ -9,3 +9,2 @@ "files": [ | ||
"bin/", | ||
"static/", | ||
"dist/" | ||
@@ -38,17 +37,13 @@ ], | ||
}, | ||
"dependencies": {}, | ||
"dependencies": { | ||
"abort-controller": "^3.0.0", | ||
"type-core": "^0.12.0" | ||
}, | ||
"devDependencies": { | ||
"@pika/pack": "^0.4.0", | ||
"@pika/plugin-build-web": "^0.9.2", | ||
"@pika/plugin-standard-pkg": "^0.9.2", | ||
"@riseup/library": "^0.5.0", | ||
"@riseup/tooling": "^0.5.0", | ||
"@types/jest": "^26.0.8", | ||
"@zerollup/ts-transform-paths": "^1.7.11", | ||
"@jest/globals": "^27.0.3", | ||
"@riseup/library": "^0.13.1", | ||
"coveralls": "^3.0.9", | ||
"husky": "^4.2.5", | ||
"kpo": "^0.11.1", | ||
"onchange": "^7.0.2", | ||
"rxjs": "^6.6.2", | ||
"typescript": "^3.7.5" | ||
"kpo": "^0.22.0", | ||
"simple-git-hooks": "^2.7.0", | ||
"typescript": "^4.3.4" | ||
}, | ||
@@ -58,6 +53,7 @@ "engines": { | ||
}, | ||
"private": false, | ||
"main": "dist/", | ||
"types": "dist/", | ||
"esnext": "dist-src/index.js", | ||
"module": "dist-web/index.js", | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts" | ||
} | ||
"module": "dist-web/index.js" | ||
} |
348
README.md
@@ -17,272 +17,37 @@ # promist | ||
## Basics | ||
## Documentation | ||
*Promist* intends to cover and abstract the most common day to day dealings with *async* behavior and promises. It doesn't intend to be the most complete library, or an incredibly slim one, but rather be a dependable set of functions that serve as go-to for most use cases. | ||
* *Classes:* a set of promise classes. | ||
* [`ExtensiblePromise`:](https://rafamel.github.io/promist/classes/ExtensiblePromise.html) a safe to extend promise class. | ||
* [`CancellablePromise`:](https://rafamel.github.io/promist/classes/CancellablePromise.html) a cancellable promise. | ||
* [`cancel`](https://rafamel.github.io/promist/classes/CancellablePromise.html#cancel) | ||
* [`DeferredPromise`:](https://rafamel.github.io/promist/classes/DeferredPromise.html) an externally actionable promise. | ||
* [`resolve`](https://rafamel.github.io/promist/classes/DeferredPromise.html#resolve) | ||
* [`reject`](https://rafamel.github.io/promist/classes/DeferredPromise.html#reject) | ||
* [`LazyPromise`:](https://rafamel.github.io/promist/classes/LazyPromise.html) a promise that will not execute until awaited. | ||
* [static `from`](https://rafamel.github.io/promist/classes/LazyPromise.html#from) | ||
* [`consume`](https://rafamel.github.io/promist/classes/LazyPromise.html#consume) | ||
* [`operate`](https://rafamel.github.io/promist/classes/LazyPromise.html#operate) | ||
* [`SyncPromise`:](https://rafamel.github.io/promist/classes/SyncPromise.html) a promise with values synchronously available and operable. | ||
* [static `from`](https://rafamel.github.io/promist/classes/SyncPromise.html#from) | ||
* *Creation*: a set of promise returning conveniency functions. | ||
* [`wait`:](https://rafamel.github.io/promist/modules.html#wait) waits for a set time. | ||
* [`until`:](https://rafamel.github.io/promist/modules.html#until) resolves once a test function returns true. | ||
* [`timeout`:](https://rafamel.github.io/promist/modules.html#timeout) cancels a promise after a set time. | ||
* *Iterables*: a set of functions to deal with iterables of promises. | ||
* [`Series`:](https://rafamel.github.io/promist/classes/Series.html) executes operations' callbacks in series. | ||
* [`map`](https://rafamel.github.io/promist/classes/Series.html#map) | ||
* [`filter`](https://rafamel.github.io/promist/classes/Series.html#filter) | ||
* [`reduce`](https://rafamel.github.io/promist/classes/Series.html#reduce) | ||
* [`each`](https://rafamel.github.io/promist/classes/Series.html#each) | ||
* [`Parallel`:](https://rafamel.github.io/promist/classes/Parallel.html) executes operations' callbacks in parallel. | ||
* [`map`](https://rafamel.github.io/promist/classes/Parallel.html#map) | ||
* [`filter`](https://rafamel.github.io/promist/classes/Parallel.html#filter) | ||
* [`reduce`](https://rafamel.github.io/promist/classes/Parallel.html#reduce) | ||
* [`each`](https://rafamel.github.io/promist/classes/Parallel.html#each) | ||
* *Utils:* a set of utility functions. | ||
* [`control`:](#controltest-function-generator-function-function) for async flow control via generators. | ||
* [`isPromise`:](#ispromisevalue-any-boolean) a type guard for promises. | ||
* [`isPromiseLike`:](#ispromiselikevalue-any-boolean) a type guard for thenable objects. | ||
* [*Create* functions:](#create-functions) return a new promise. | ||
* [`wait`](#waitms-number-promise) | ||
* [`until`](#untiltest-function-safe-boolean-ms-number-promise) | ||
* [`subscribe`](#subscribeobservable-observable-oncomplete-function-promise) | ||
* [*Classes:*](#classes) both `Promist` and `LazyPromist` behave just like a `Promise`, but pack a few additional features. | ||
* [`Promist`](#promist-class) | ||
* [`LazyPromist`](#lazypromist-class) | ||
* [Static methods](#static-methods) | ||
* [`from`](#promistfrompromise-promise--function-promist) | ||
* [`wait`](#promistwaitms-number-promist) | ||
* [`until`](#promistuntiltest-function-safe-boolean-ms-number-promist) | ||
* [`subscribe`](#promistsubscribeobservable-observable-oncomplete-function-promist) | ||
* [Instance fields](#instance-fields) | ||
* [`status`](#promiststatus) | ||
* [`value`](#promistvalue) | ||
* [`reason`](#promistreason) | ||
* [`react`](#promistreact) | ||
* [Instance methods](#instance-methods) | ||
* [`resolve`](#promistresolvevalue-any-void) | ||
* [`reject`](#promistrejectreason-Error-void) | ||
* [`cancel`](#promistcancel-void) | ||
* [`timeout`](#promisttimeoutms-number-reason-error-void) | ||
* [`fallback`](#promistfallbackms-number-value-any-void) | ||
* [*Utils:*](#utils) a set of conveniency utility functions. | ||
* [`control`](#controltest-function-generator-function-function) | ||
* [`isPromise`](#ispromisevalue-any-boolean) | ||
* [`isPromiseLike`](#ispromiselikevalue-any-boolean) | ||
* [*Collections*:](#collections) handled either in *parallel* or *series.* | ||
* [`map`](#maparr-promise-callback-function-promise) | ||
* [`filter`](#filterarr-promise-callback-function-promise) | ||
* [`reduce`](#reducearr-promise-callback-function-initialvalue-any-promise) | ||
* [`each`](#eacharr-promise-callback-function-promise) | ||
## Create functions | ||
*Create* functions return a new promise. | ||
### `wait(ms: number): Promise` | ||
Returns a promise that will resolve after `ms` milliseconds; | ||
* `ms`: number of milliseconds to wait for until resolution. | ||
```javascript | ||
import { wait } from 'promist'; | ||
wait(100).then(() => console.log('Resolved after 100ms')); | ||
``` | ||
### `until(test: Function, safe?: boolean, ms?: number): Promise` | ||
Returns a promise that resolves when `test` returns `true`. | ||
* `test`: test function, with signature `() => boolean | Promise<boolean>`. | ||
* `safe`: if `true`, it will treat `test` throws and rejections as `false`, instead of rejecting itself. | ||
* `ms`: the frequency `test` should be called at until it returns truthy. Default: `25`. | ||
```javascript | ||
import { until } from 'promist'; | ||
let example = 1; | ||
until(() => example === 10) | ||
.then(() => console.log('Resolved after example = 10')); | ||
example = 10; | ||
``` | ||
### `subscribe(observable: Observable, onComplete?: Function): Promise` | ||
Subscribes to an `observable` and resolves/rejects with its first value. By default, it will reject if the observable completes before emitting any values, though this behavior can be controlled via `onComplete`. | ||
* `observable`: an *Observable* object. | ||
* `onComplete`: a promise *executor* function, handling the event of the observable completing without emitting any values, and with signature: `(resolve: Function, reject: Function): void`. | ||
```javascript | ||
import { subscribe } from 'promist'; | ||
import { Subject } from 'rxjs'; | ||
const subject = new Subject(); | ||
subscribe(subject) | ||
.then(console.log); // foo | ||
subject.next('foo'); | ||
``` | ||
## Classes | ||
### `Promist` class | ||
`Promist` behaves just like a `Promise`, but packs a few additional features. | ||
* It can be externally resolved and/or rejected. | ||
* It can also be externally cancelled. If using an executor on the `Promist` constructor, you can receive external completion events (resolution/rejection/cancellation) via the returned callback in order to free up resources, if needed. Externally, you also have access to this event -including cancellation- via the `Promist.react` promise. | ||
* It will always have the `finally` method available, regardless of the underlying `Promise` implementation. | ||
The difference between `Promist`s static methods and *create* functions is that in any completion event, they will always clean up after themselves, clearing the underlying timeouts and/or subscriptions. | ||
Its *constructor* takes an optional *executor* function, just as | ||
you would use to instantiate a normal promise. | ||
```javascript | ||
import { Promist } from 'promist'; | ||
const promist = new Promist((resolve, reject) => { | ||
// Counter will start on instantiation | ||
const timeout = setTimeout(() => resolve('foo'), 250); | ||
return function cleanup() { | ||
// Will run after the function resolves, rejects, or cancels | ||
clearTimeout(timeout); | ||
} | ||
}); | ||
``` | ||
### `LazyPromist` class | ||
Inherits from `Promist`, having the same *constructor* signature, with the diference of the *executor* not being optional. All of its static methods promises will execute lazily, as expected. | ||
`LazyPromist`s don't run their constructor `executor` until after they've been explicitly expected to resolve by a `then`, `catch`, or `finally` call. | ||
```javascript | ||
import { LazyPromist } from 'promist'; | ||
const promist = new LazyPromist((resolve, reject) => { | ||
// Counter will start after `then`, `catch`, or `finally` are called. | ||
const timeout = setTimeout(() => resolve('foo'), 250); | ||
return function cleanup() { | ||
// Will run after the function resolves, rejects, or cancels | ||
clearTimeout(timeout); | ||
} | ||
}); | ||
``` | ||
### Static methods | ||
#### `Promist.from(promise: Promise | Function): Promist` | ||
Creates a `Promist` from a `Promise` or a *sync* or *async* function. | ||
* `promise`: a `Promise` or a function. | ||
```javascript | ||
import { Promist } from 'promist'; | ||
Promist.from(Promise.resolve('foo')); | ||
Promist.from(async () => 'bar'); | ||
Promist.from(() => 'baz'); | ||
``` | ||
#### `Promist.wait(ms: number): Promist` | ||
See [`wait`](#waitms-number-promise) and [the differences between `Promist` static methods and *create* functions.](#promist-class) | ||
#### `Promist.until(test: Function, safe?: boolean, ms?: number): Promist` | ||
See [`until`](#untiltest-function-safe-boolean-ms-number-promise) and [the differences between `Promist` static methods and *create* functions.](#promist-class) | ||
#### `Promist.subscribe(observable: Observable, onComplete?: Function): Promist` | ||
See [`subscribe`](#subscribeobservable-observable-oncomplete-function-promise) and [the differences between `Promist` static methods and *create* functions.](#promist-class) | ||
### Instance fields | ||
#### `promist.status` | ||
Any of `'pending'`, `'resolved'`, `'rejected'` and `'cancelled'`. | ||
#### `promist.value` | ||
The value the promise has resolved to, if any. Otherwise `null`. | ||
#### `promist.reason` | ||
The reason the promise has rejected with, if any. Otherwise `null`. | ||
#### `promist.react` | ||
An empty promise that resolves once the promise has resolved, rejected, or has gotten cancelled. | ||
### Instance methods | ||
#### `promist.resolve(value?: any): void` | ||
Resolves the `Promist` with `value`. | ||
* `value`: the value to resolve to. | ||
```javascript | ||
import { Promist } from 'promist'; | ||
const promist = new Promist(); | ||
promist.then(console.log); // foo | ||
promist.resolve('foo'); | ||
``` | ||
#### `promist.reject(reason: Error): void` | ||
Rejects the `Promist` with `reason`. | ||
* `reason`: the *Error* to reject with. | ||
```javascript | ||
import { Promist } from 'promist'; | ||
const promist = new Promist(); | ||
promist.catch(console.error); // Error: foo | ||
promist.reject(Error('foo')); | ||
``` | ||
#### `promist.cancel(): void` | ||
Cancels the `Promist`. If it didn't already, it will never resolve nor reject. | ||
```javascript | ||
import { Promist } from 'promist'; | ||
const promist = new Promist((resolve) => { | ||
const timeout = setTimeout(resolve, 150); | ||
return () => clearTimeout(timeout); | ||
}); | ||
promist.cancel(); | ||
promist.then(console.log); // will never execute `then` callback | ||
``` | ||
#### `promist.timeout(ms: number, reason?: Error): void` | ||
Sets a timeout of `ms` milliseconds after which, if the `Promist` hasn't resolved, rejected, or cancelled, it will reject with `reason`, or a default error if no `reason` is passed. | ||
* `ms`: timeout in milliseconds. | ||
* `reason`: *Error* to reject with. | ||
```javascript | ||
import { Promist } from 'promist'; | ||
const promist = new Promist((resolve) => { | ||
const timeout = setTimeout(resolve, 150); | ||
return () => clearTimeout(timeout); | ||
}); | ||
promist.timeout(50); | ||
promist.catch(console.error); // will reject | ||
``` | ||
#### `promist.fallback(ms: number, value: any): void` | ||
Sets a timeout of `ms` milliseconds after which, if the `Promist` hasn't resolved, rejected, or cancelled, it will resolve by falling back to `value`. | ||
* `ms`: timeout in milliseconds. | ||
* `value`: value to resolve with. | ||
```javascript | ||
import { Promist } from 'promist'; | ||
const promist = new Promist((resolve) => { | ||
const timeout = setTimeout(() => resolve('foo'), 150); | ||
return () => clearTimeout(timeout); | ||
}); | ||
promist.fallback(50, 'bar'); | ||
promist.then(console.log); // 'bar' | ||
``` | ||
## Utils | ||
@@ -349,48 +114,1 @@ | ||
``` | ||
## Collections | ||
* *Series:* | ||
* Collection functions execute serially. | ||
* The passed functions (callbacks) receive an array of promises. | ||
* *Parallel:* | ||
* Collection functions execute in parallel in two stages: first, the resolution of all promises, then the passed function calls. | ||
* The passed functions (callbacks) receive an array with the values the input array of promises resolved to. | ||
* `parallel.reduce()` receives a promise as the accumulator parameter. | ||
```javascript | ||
import { parallel } from 'promist'; | ||
import { series } from 'promist'; | ||
parallel.map(promiseArr, (x, i, arr) => { | ||
// arr will contain the resolved values. | ||
return x; | ||
}); | ||
series.map(promiseArr, (x, i, arr) => { | ||
// arr will be promiseArr | ||
return x; | ||
}) | ||
``` | ||
### `map(arr: Promise[], callback: Function): Promise` | ||
* `arr`: An array of promises. | ||
* `callback`: With the same signature as [`Array.prototype.map()`.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) Can be a promise returning/*async* function. | ||
### `filter(arr: Promise[], callback: Function): Promise` | ||
* `arr`: An array of promises. | ||
* `callback`: With the same signature as [`Array.prototype.filter()`.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) Can be a promise returning/*async* function. | ||
### `reduce(arr: Promise[], callback: Function, initialValue: any): Promise` | ||
* `arr`: An array of promises. | ||
* `callback`: With the same signature as [`Array.prototype.reduce()`.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) Can be a promise returning/*async* function. | ||
* `initialValue`: An initial value; if absent, the resolved value of the first promise in the array will be taken as `initialValue`. | ||
### `each(arr: Promise[], callback: Function): Promise` | ||
* `arr`: An array of promises. | ||
* `callback`: With the same signature as [`Array.prototype.forEach()`.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) Can be a promise returning/*async* function. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
199604
25.07%6
-53.85%2045
21.8%2
Infinity%113
-71.39%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added