@tdreyno/pretty-please
Advanced tools
Comparing version 1.7.0 to 1.8.0
@@ -5,25 +5,17 @@ 'use strict'; | ||
function initialize() { | ||
return { | ||
type: "Initialized" | ||
}; | ||
} | ||
function pending() { | ||
return { | ||
type: "Pending" | ||
}; | ||
} | ||
function succeed(result) { | ||
return { | ||
type: "Success", | ||
result | ||
}; | ||
} | ||
function fail(error) { | ||
return { | ||
type: "Failure", | ||
error | ||
}; | ||
} | ||
function fold(onInitialized, onPending, onFailure, onSuccess, remote) { | ||
const initialize = () => ({ | ||
type: "Initialized" | ||
}); | ||
const pending = () => ({ | ||
type: "Pending" | ||
}); | ||
const succeed = result => ({ | ||
type: "Success", | ||
result | ||
}); | ||
const fail = error => ({ | ||
type: "Failure", | ||
error | ||
}); | ||
const fold = (onInitialized, onPending, onFailure, onSuccess, remote) => { | ||
switch (remote.type) { | ||
@@ -42,3 +34,3 @@ case "Initialized": | ||
} | ||
} | ||
}; | ||
@@ -54,240 +46,33 @@ var RemoteData = /*#__PURE__*/Object.freeze({ | ||
function range(end, start = 0) { | ||
return Array(end - start).fill(undefined).map((_, i) => start + i); | ||
} | ||
function to(fn) { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
return (sum, _item, index, all) => { | ||
const isLast = index === all.length - 1; | ||
const range = (end, start = 0) => Array(end - start).fill(undefined).map((_, i) => start + i); | ||
const to = fn => // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
(sum, _item, index, all) => { | ||
const isLast = index === all.length - 1; | ||
if (!isLast) { | ||
return sum; | ||
} | ||
if (!isLast) { | ||
return sum; | ||
} | ||
return fn(all); | ||
}; | ||
} | ||
function constant(value) { | ||
return () => value; | ||
} | ||
function identity(x) { | ||
return x; | ||
} | ||
function toIndexedObject(fn) { | ||
return (sum, item, index) => { | ||
const [key, value] = fn(item, index); | ||
sum[key] = value; | ||
return sum; | ||
}; | ||
} | ||
function mapToIndexedObject(fn, items, initial = {}) { | ||
return items.reduce(toIndexedObject(fn), initial); | ||
} | ||
function pairsToIndexedObject(sum, [key, value]) { | ||
return fn(all); | ||
}; | ||
const constant = value => () => value; | ||
const identity = x => x; | ||
const toIndexedObject = fn => (sum, item, index) => { | ||
const [key, value] = fn(item, index); | ||
sum[key] = value; | ||
return sum; | ||
} | ||
}; | ||
const mapToIndexedObject = (fn, items, initial = {}) => items.reduce(toIndexedObject(fn), initial); | ||
const pairsToIndexedObject = (sum, [key, value]) => { | ||
sum[key] = value; | ||
return sum; | ||
}; | ||
/* eslint-disable @typescript-eslint/no-misused-promises, @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-explicit-any, @typescript-eslint/no-use-before-define */ | ||
/** | ||
* Create a new task. | ||
* @param computation A function which will be run when the task starts. | ||
*/ | ||
class Task { | ||
constructor(computation) { | ||
this.computation = computation; | ||
this.isCanceled = false; | ||
} | ||
fork(reject, resolve) { | ||
let localCancel = this.isCanceled; | ||
const result = { | ||
cancel: () => localCancel = true | ||
}; | ||
if (localCancel) { | ||
return result; | ||
} | ||
this.computation(err => { | ||
if (!localCancel) { | ||
reject(err); | ||
} | ||
}, value => { | ||
if (!localCancel) { | ||
resolve(value); | ||
} | ||
}); | ||
return result; | ||
} | ||
cancel() { | ||
this.isCanceled = true; | ||
} | ||
/** | ||
* Alias to match promise API and let async/await work. | ||
* Mostly "private". Do not use. | ||
*/ | ||
then(onfulfilled, onrejected) { | ||
return this.toPromise().then(onfulfilled, onrejected); | ||
} | ||
chain(fn) { | ||
return chain(fn, this); | ||
} | ||
succeedIf(fn) { | ||
return succeedIf(fn, this); | ||
} | ||
onlyOnce() { | ||
return onlyOnce(this); | ||
} | ||
toPromise() { | ||
return toPromise(this); | ||
} | ||
swap() { | ||
return swap(this); | ||
} | ||
map(fn) { | ||
return map(fn, this); | ||
} | ||
forward(value) { | ||
return map(constant(value), this); | ||
} | ||
append(...items) { | ||
return map(a => [a, ...items], this); | ||
} | ||
prepend(...items) { | ||
return map(a => [...items, a], this); | ||
} | ||
tap(fn) { | ||
return tap(fn, this); | ||
} | ||
tapChain(fn) { | ||
return tapChain(fn, this); | ||
} | ||
mapError(fn) { | ||
return mapError(fn, this); | ||
} | ||
mapBoth(handleError, handleSuccess) { | ||
return mapBoth(handleError, handleSuccess, this); | ||
} | ||
fold(handleError, handleSuccess) { | ||
return fold$1(handleError, handleSuccess, this); | ||
} | ||
orElse(fn) { | ||
return orElse(fn, this); | ||
} | ||
ap(taskOrPromise) { | ||
return ap(this, taskOrPromise); | ||
} | ||
wait(ms) { | ||
return wait(ms, this); | ||
} | ||
retryIn(ms) { | ||
return retryIn(ms, this); | ||
} | ||
retryWithExponentialBackoff(ms, times) { | ||
return retryWithExponentialBackoff(ms, times, this); | ||
} | ||
flatten() { | ||
return flatten(this); | ||
} | ||
} | ||
Task.fail = fail$1; | ||
Task.succeed = succeed$1; | ||
Task.empty = empty; | ||
Task.failIn = failIn; | ||
Task.succeedIn = succeedIn; | ||
Task.of = succeed$1; | ||
Task.all = all; | ||
Task.sequence = sequence; | ||
Task.firstSuccess = firstSuccess; | ||
Task.never = never; | ||
Task.fromPromise = fromPromise; | ||
Task.fromLazyPromise = fromLazyPromise; | ||
Task.race = race; | ||
Task.external = external; | ||
Task.emitter = emitter; | ||
Task.succeedBy = succeedBy; | ||
Task.ap = ap; | ||
Task.map2 = map2; | ||
Task.map3 = map3; | ||
Task.map4 = map4; | ||
Task.loop = loop; | ||
Task.reduce = reduce; | ||
Task.zip = zip; | ||
Task.zipWith = zipWith; | ||
Task.flatten = flatten; | ||
/** | ||
* A special form of Task which can be resolved/rejected externally. | ||
*/ | ||
class ExternalTask extends Task { | ||
constructor() { | ||
super((reject, resolve) => { | ||
switch (this.lastState_) { | ||
case "error": | ||
reject(this.alreadyError_); | ||
case "success": | ||
resolve(this.alreadyResult_); | ||
case "pending": | ||
this.computationReject_ = reject; | ||
this.computationResolve_ = resolve; | ||
} | ||
}); | ||
this.lastState_ = "pending"; | ||
} | ||
reject(error) { | ||
this.alreadyError_ = error; | ||
this.lastState_ = "error"; | ||
if (this.computationReject_) { | ||
this.computationReject_(error); | ||
} | ||
} | ||
resolve(result) { | ||
this.alreadyResult_ = result; | ||
this.lastState_ = "success"; | ||
if (this.computationResolve_) { | ||
this.computationResolve_(result); | ||
} | ||
} | ||
} | ||
/** | ||
* Creates a Task which can be resolved/rejected externally. | ||
*/ | ||
function external() { | ||
return new ExternalTask(); | ||
} | ||
function emitter(fn) { | ||
const external = () => new ExternalTask(); | ||
const emitter = fn => { | ||
const task = external(); | ||
@@ -301,3 +86,3 @@ return [task, (...args) => { | ||
}]; | ||
} | ||
}; | ||
/** | ||
@@ -310,5 +95,3 @@ * Creates a Task which has already successfully completed with `result`. | ||
function succeed$1(result) { | ||
return new Task((_, resolve) => resolve(result)); | ||
} | ||
const succeed$1 = result => new Task((_, resolve) => resolve(result)); | ||
const of = succeed$1; | ||
@@ -320,11 +103,9 @@ /** | ||
function succeedBy(result) { | ||
return new Task((reject, resolve) => { | ||
try { | ||
resolve(result()); | ||
} catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
} | ||
const succeedBy = result => new Task((reject, resolve) => { | ||
try { | ||
resolve(result()); | ||
} catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
/** | ||
@@ -335,5 +116,3 @@ * Creates a Task has an empty result. | ||
function empty() { | ||
return of(void 0); | ||
} | ||
const empty = () => of(void 0); | ||
/** | ||
@@ -345,5 +124,3 @@ * Creates a Task which automatically succeeds at some time in the future with `result`. | ||
function succeedIn(ms, result) { | ||
return new Task((_, resolve) => setTimeout(() => resolve(result), ms)); | ||
} | ||
const succeedIn = (ms, result) => new Task((_, resolve) => setTimeout(() => resolve(result), ms)); | ||
/** | ||
@@ -355,5 +132,3 @@ * Creates a Task which has already failed with `error`. | ||
function fail$1(error) { | ||
return new Task(reject => reject(error)); | ||
} | ||
const fail$1 = error => new Task(reject => reject(error)); | ||
/** | ||
@@ -365,5 +140,3 @@ * Creates a Task which automatically fails at some time in the future with `error`. | ||
function failIn(ms, error) { | ||
return new Task(reject => setTimeout(() => reject(error), ms)); | ||
} | ||
const failIn = (ms, error) => new Task(reject => setTimeout(() => reject(error), ms)); | ||
/** | ||
@@ -373,5 +146,3 @@ * Creates a Task will never finish. | ||
function never() { | ||
return new Task(() => void 0); | ||
} | ||
const never = () => new Task(() => void 0); | ||
/** | ||
@@ -383,5 +154,3 @@ * Chain a task to run after a previous task has succeeded. | ||
function chain(fn, task) { | ||
return new Task((reject, resolve) => task.fork(reject, b => autoPromiseToTask(fn(b)).fork(reject, resolve))); | ||
} | ||
const chain = (fn, task) => new Task((reject, resolve) => task.fork(reject, b => autoPromiseToTask(fn(b)).fork(reject, resolve))); | ||
/** | ||
@@ -393,9 +162,3 @@ * If a function returns a Promise instead of a Task, automatically | ||
function autoPromiseToTask(promiseOrTask) { | ||
if (promiseOrTask instanceof Promise) { | ||
return fromPromise(promiseOrTask); | ||
} | ||
return promiseOrTask; | ||
} | ||
const autoPromiseToTask = promiseOrTask => promiseOrTask instanceof Promise ? fromPromise(promiseOrTask) : promiseOrTask; | ||
/** | ||
@@ -408,14 +171,12 @@ * When forked, run a function which can check whether the task has already succeeded. | ||
function succeedIf(fn, task) { | ||
return new Task((reject, resolve) => { | ||
const result = fn(); | ||
const succeedIf = (fn, task) => new Task((reject, resolve) => { | ||
const result = fn(); | ||
if (result) { | ||
resolve(result); | ||
return; | ||
} | ||
if (result) { | ||
resolve(result); | ||
return; | ||
} | ||
task.fork(reject, resolve); | ||
}); | ||
} | ||
task.fork(reject, resolve); | ||
}); | ||
/** | ||
@@ -427,3 +188,3 @@ * A task which only runs once. Caches the success or failure. Be careful. | ||
function onlyOnce(task) { | ||
const onlyOnce = task => { | ||
let state = "initialized"; | ||
@@ -435,3 +196,3 @@ let cachedResult; | ||
function notify(reject, resolve) { | ||
const notify = (reject, resolve) => { | ||
const id = callbackId++; | ||
@@ -442,5 +203,5 @@ callbacks[id] = { | ||
}; | ||
} | ||
}; | ||
function triggerReject(error) { | ||
const triggerReject = error => { | ||
state = "failure"; | ||
@@ -452,5 +213,5 @@ cachedError = error; | ||
}); | ||
} | ||
}; | ||
function triggerResolve(result) { | ||
const triggerResolve = result => { | ||
state = "success"; | ||
@@ -462,3 +223,3 @@ cachedResult = result; | ||
}); | ||
} | ||
}; | ||
@@ -485,3 +246,3 @@ return new Task((reject, resolve) => { | ||
}); | ||
} | ||
}; | ||
/** | ||
@@ -492,10 +253,4 @@ * Given a promise, create a Task which relies on it. | ||
function fromPromise(maybePromise) { | ||
if (maybePromise instanceof Promise) { | ||
// eslint-disable-next-line @typescript-eslint/no-misused-promises | ||
return new Task((reject, resolve) => maybePromise.then(resolve, reject)); | ||
} | ||
return of(maybePromise); | ||
} | ||
const fromPromise = maybePromise => maybePromise instanceof Promise ? // eslint-disable-next-line @typescript-eslint/no-misused-promises | ||
new Task((reject, resolve) => maybePromise.then(resolve, reject)) : of(maybePromise); | ||
/** | ||
@@ -506,5 +261,3 @@ * Take a function which generates a promise and lazily execute it. | ||
function fromLazyPromise(getPromise) { | ||
return succeedBy(getPromise).chain(fromPromise); | ||
} | ||
const fromLazyPromise = getPromise => succeedBy(getPromise).chain(fromPromise); | ||
/** | ||
@@ -515,5 +268,3 @@ * Given a task, create a Promise which resolves when the task does. | ||
function toPromise(task) { | ||
return new Promise((resolve, reject) => task.fork(reject, resolve)); | ||
} | ||
const toPromise = task => new Promise((resolve, reject) => task.fork(reject, resolve)); | ||
/** | ||
@@ -525,22 +276,20 @@ * Given an array of tasks, return the one which finishes first. | ||
function race(tasksOrPromises) { | ||
return new Task((reject, resolve) => { | ||
let done = false; | ||
return tasksOrPromises.map(taskOrPromise => autoPromiseToTask(taskOrPromise).fork(error => { | ||
if (done) { | ||
return; | ||
} | ||
const race = tasksOrPromises => new Task((reject, resolve) => { | ||
let done = false; | ||
return tasksOrPromises.map(taskOrPromise => autoPromiseToTask(taskOrPromise).fork(error => { | ||
if (done) { | ||
return; | ||
} | ||
done = true; | ||
reject(error); | ||
}, result => { | ||
if (done) { | ||
return; | ||
} | ||
done = true; | ||
reject(error); | ||
}, result => { | ||
if (done) { | ||
return; | ||
} | ||
done = true; | ||
resolve(result); | ||
})); | ||
}); | ||
} | ||
done = true; | ||
resolve(result); | ||
})); | ||
}); | ||
class LoopBreak { | ||
@@ -565,21 +314,19 @@ constructor(value) { | ||
function loop(fn, initialValue) { | ||
return new Task((reject, resolve) => { | ||
const tryLoop = currentValue => { | ||
fn(currentValue).fork(err => { | ||
reject(err); | ||
}, result => { | ||
if (result instanceof LoopBreak) { | ||
resolve(result.value); | ||
} | ||
const loop = (fn, initialValue) => new Task((reject, resolve) => { | ||
const tryLoop = currentValue => { | ||
fn(currentValue).fork(err => { | ||
reject(err); | ||
}, result => { | ||
if (result instanceof LoopBreak) { | ||
resolve(result.value); | ||
} | ||
if (result instanceof LoopContinue) { | ||
tryLoop(result.value); | ||
} | ||
}); | ||
}; | ||
if (result instanceof LoopContinue) { | ||
tryLoop(result.value); | ||
} | ||
}); | ||
}; | ||
tryLoop(initialValue); | ||
}); | ||
} | ||
tryLoop(initialValue); | ||
}); | ||
/** | ||
@@ -594,22 +341,20 @@ * An async reducer. Given an initial return value and an array of | ||
function reduce(fn, initialValue, items) { | ||
return loop(({ | ||
remainingItems, | ||
currentResult | ||
}) => { | ||
if (remainingItems.length === 0) { | ||
return of(new LoopBreak(currentResult)); | ||
} | ||
const reduce = (fn, initialValue, items) => loop(({ | ||
remainingItems, | ||
currentResult | ||
}) => { | ||
if (remainingItems.length === 0) { | ||
return of(new LoopBreak(currentResult)); | ||
} | ||
const [head, ...tail] = remainingItems; | ||
const index = items.length - tail.length - 1; | ||
return fn(currentResult, head, index, items).map(nextResult => new LoopContinue({ | ||
remainingItems: tail, | ||
currentResult: nextResult | ||
})); | ||
}, { | ||
remainingItems: items, | ||
currentResult: initialValue | ||
}); | ||
} | ||
const [head, ...tail] = remainingItems; | ||
const index = items.length - tail.length - 1; | ||
return fn(currentResult, head, index, items).map(nextResult => new LoopContinue({ | ||
remainingItems: tail, | ||
currentResult: nextResult | ||
})); | ||
}, { | ||
remainingItems: items, | ||
currentResult: initialValue | ||
}); | ||
/** | ||
@@ -620,32 +365,26 @@ * Given an array of tasks, return the one which finishes successfully first. | ||
function firstSuccess(tasksOrPromises) { | ||
if (tasksOrPromises.length === 0) { | ||
return fail$1([]); | ||
} | ||
const firstSuccess = tasksOrPromises => tasksOrPromises.length === 0 ? fail$1([]) : new Task((reject, resolve) => { | ||
let isDone = false; | ||
let runningTasks = tasksOrPromises.length; | ||
const errors = []; | ||
return tasksOrPromises.map(taskOrPromise => autoPromiseToTask(taskOrPromise).fork(error => { | ||
if (isDone) { | ||
return; | ||
} | ||
return new Task((reject, resolve) => { | ||
let isDone = false; | ||
let runningTasks = tasksOrPromises.length; | ||
const errors = []; | ||
return tasksOrPromises.map(taskOrPromise => autoPromiseToTask(taskOrPromise).fork(error => { | ||
if (isDone) { | ||
return; | ||
} | ||
runningTasks -= 1; | ||
errors.push(error); | ||
runningTasks -= 1; | ||
errors.push(error); | ||
if (runningTasks === 0) { | ||
reject(errors); | ||
} | ||
}, result => { | ||
if (isDone) { | ||
return; | ||
} | ||
if (runningTasks === 0) { | ||
reject(errors); | ||
} | ||
}, result => { | ||
if (isDone) { | ||
return; | ||
} | ||
isDone = true; | ||
resolve(result); | ||
})); | ||
}); | ||
} | ||
isDone = true; | ||
resolve(result); | ||
})); | ||
}); | ||
/** | ||
@@ -657,32 +396,26 @@ * Given an array of task which return a result, return a new task which results an array of results. | ||
function all(tasksOrPromises) { | ||
if (tasksOrPromises.length === 0) { | ||
return of([]); | ||
} | ||
const all = tasksOrPromises => tasksOrPromises.length === 0 ? of([]) : new Task((reject, resolve) => { | ||
let isDone = false; | ||
let runningTasks = tasksOrPromises.length; | ||
const results = []; | ||
return tasksOrPromises.map((taskOrPromise, i) => autoPromiseToTask(taskOrPromise).fork(error => { | ||
if (isDone) { | ||
return; | ||
} | ||
return new Task((reject, resolve) => { | ||
let isDone = false; | ||
let runningTasks = tasksOrPromises.length; | ||
const results = []; | ||
return tasksOrPromises.map((taskOrPromise, i) => autoPromiseToTask(taskOrPromise).fork(error => { | ||
if (isDone) { | ||
return; | ||
} | ||
isDone = true; | ||
reject(error); | ||
}, result => { | ||
if (isDone) { | ||
return; | ||
} | ||
isDone = true; | ||
reject(error); | ||
}, result => { | ||
if (isDone) { | ||
return; | ||
} | ||
runningTasks -= 1; | ||
results[i] = result; | ||
runningTasks -= 1; | ||
results[i] = result; | ||
if (runningTasks === 0) { | ||
resolve(results); | ||
} | ||
})); | ||
}); | ||
} | ||
if (runningTasks === 0) { | ||
resolve(results); | ||
} | ||
})); | ||
}); | ||
/** | ||
@@ -695,5 +428,3 @@ * Creates a task that waits for two tasks of different types to | ||
function zip(taskAOrPromise, taskBOrPromise) { | ||
return map2(a => b => [a, b], taskAOrPromise, taskBOrPromise); | ||
} | ||
const zip = (taskAOrPromise, taskBOrPromise) => map2(a => b => [a, b], taskAOrPromise, taskBOrPromise); | ||
/** | ||
@@ -708,5 +439,3 @@ * Creates a task that waits for two tasks of different types to | ||
function zipWith(fn, taskAOrPromise, taskBOrPromise) { | ||
return map2(a => b => fn(a, b), taskAOrPromise, taskBOrPromise); | ||
} | ||
const zipWith = (fn, taskAOrPromise, taskBOrPromise) => map2(a => b => fn(a, b), taskAOrPromise, taskBOrPromise); | ||
/** | ||
@@ -717,13 +446,7 @@ * Given an array of task which return a result, return a new task which results an array of results. | ||
function sequence(tasksOrPromises) { | ||
if (tasksOrPromises.length === 0) { | ||
return of([]); | ||
} | ||
return tasksOrPromises.reduce((sum, taskOrPromise) => { | ||
return chain(list => { | ||
return map(result => [...list, result], autoPromiseToTask(taskOrPromise)); | ||
}, sum); | ||
}, succeed$1([])); | ||
} | ||
const sequence = tasksOrPromises => tasksOrPromises.length === 0 ? of([]) : tasksOrPromises.reduce((sum, taskOrPromise) => { | ||
return chain(list => { | ||
return map(result => [...list, result], autoPromiseToTask(taskOrPromise)); | ||
}, sum); | ||
}, succeed$1([])); | ||
/** | ||
@@ -734,5 +457,3 @@ * Given a task, swap the error and success values. | ||
function swap(task) { | ||
return new Task((reject, resolve) => task.fork(e => resolve(e), s => reject(s))); | ||
} | ||
const swap = task => new Task((reject, resolve) => task.fork(e => resolve(e), s => reject(s))); | ||
/** | ||
@@ -744,14 +465,6 @@ * Given a task, map the successful value to a Task. | ||
function map(fn, task) { | ||
return new Task((reject, resolve) => task.fork(reject, result => resolve(fn(result)))); | ||
} | ||
function map2(fn, taskA, taskB) { | ||
return Task.of(fn).ap(taskA).ap(taskB); | ||
} | ||
function map3(fn, taskA, taskB, taskC) { | ||
return Task.of(fn).ap(taskA).ap(taskB).ap(taskC); | ||
} | ||
function map4(fn, taskA, taskB, taskC, taskD) { | ||
return Task.of(fn).ap(taskA).ap(taskB).ap(taskC).ap(taskD); | ||
} | ||
const map = (fn, task) => new Task((reject, resolve) => task.fork(reject, result => resolve(fn(result)))); | ||
const map2 = (fn, taskA, taskB) => Task.of(fn).ap(taskA).ap(taskB); | ||
const map3 = (fn, taskA, taskB, taskC) => Task.of(fn).ap(taskA).ap(taskB).ap(taskC); | ||
const map4 = (fn, taskA, taskB, taskC, taskD) => Task.of(fn).ap(taskA).ap(taskB).ap(taskC).ap(taskD); | ||
/** | ||
@@ -763,8 +476,6 @@ * Run a side-effect on success. Useful for logging. | ||
function tap(fn, task) { | ||
return map(result => { | ||
fn(result); | ||
return result; | ||
}, task); | ||
} | ||
const tap = (fn, task) => map(result => { | ||
fn(result); | ||
return result; | ||
}, task); | ||
/** | ||
@@ -777,5 +488,3 @@ * Run an additional task on success. Useful for async side-effects. | ||
function tapChain(fn, task) { | ||
return chain(result => autoPromiseToTask(fn(result)).forward(result), task); | ||
} | ||
const tapChain = (fn, task) => chain(result => autoPromiseToTask(fn(result)).forward(result), task); | ||
/** | ||
@@ -789,5 +498,4 @@ * Given a task, map the failure error to a Task. | ||
function mapError(fn, task) { | ||
return new Task((reject, resolve) => task.fork(error => reject(fn(error)), resolve)); | ||
} | ||
const mapError = (fn, task) => new Task((reject, resolve) => task.fork(error => reject(fn(error)), resolve)); | ||
const errorUnion = task => task; | ||
/** | ||
@@ -800,5 +508,3 @@ * Given a task, map both the failure error and the success result to a Task. | ||
function mapBoth(handleError, handleSuccess, task) { | ||
return mapError(handleError, map(handleSuccess, task)); | ||
} | ||
const mapBoth = (handleError, handleSuccess, task) => mapError(handleError, map(handleSuccess, task)); | ||
/** | ||
@@ -811,5 +517,3 @@ * Given a task, map both the failure error and the success result to a Task which always succeeds. | ||
function fold$1(handleError, handleSuccess, task) { | ||
return new Task((_, resolve) => task.fork(error => resolve(handleError(error)), result => resolve(handleSuccess(result)))); | ||
} | ||
const fold$1 = (handleError, handleSuccess, task) => new Task((_, resolve) => task.fork(error => resolve(handleError(error)), result => resolve(handleSuccess(result)))); | ||
/** | ||
@@ -821,5 +525,3 @@ * Given a task, if the result in a failure, attemp to generate another Task from the error. | ||
function orElse(fn, task) { | ||
return new Task((reject, resolve) => task.fork(error => autoPromiseToTask(fn(error)).fork(reject, resolve), resolve)); | ||
} | ||
const orElse = (fn, task) => new Task((reject, resolve) => task.fork(error => autoPromiseToTask(fn(error)).fork(reject, resolve), resolve)); | ||
/** | ||
@@ -832,24 +534,10 @@ * Given a task that succeeds with a map function as its result, | ||
function ap(taskOrPromise, appliedTaskOrPromise) { | ||
return new Task((reject, resolve) => { | ||
let targetResult; | ||
let applierFunction; | ||
let hasResultLoaded = false; | ||
let isRejected = false; | ||
const ap = (taskOrPromise, appliedTaskOrPromise) => new Task((reject, resolve) => { | ||
let targetResult; | ||
let applierFunction; | ||
let hasResultLoaded = false; | ||
let isRejected = false; | ||
const handleResolve = onResolve => { | ||
return x => { | ||
if (isRejected) { | ||
return; | ||
} | ||
onResolve(x); | ||
if (applierFunction && hasResultLoaded) { | ||
resolve(applierFunction(targetResult)); | ||
} | ||
}; | ||
}; | ||
const handleReject = x => { | ||
const handleResolve = onResolve => { | ||
return x => { | ||
if (isRejected) { | ||
@@ -859,15 +547,27 @@ return; | ||
isRejected = true; | ||
reject(x); | ||
onResolve(x); | ||
if (applierFunction && hasResultLoaded) { | ||
resolve(applierFunction(targetResult)); | ||
} | ||
}; | ||
}; | ||
autoPromiseToTask(taskOrPromise).fork(handleReject, handleResolve(x => { | ||
applierFunction = x; | ||
})); | ||
autoPromiseToTask(appliedTaskOrPromise).fork(handleReject, handleResolve(x => { | ||
hasResultLoaded = true; | ||
targetResult = x; | ||
})); | ||
}); | ||
} | ||
const handleReject = x => { | ||
if (isRejected) { | ||
return; | ||
} | ||
isRejected = true; | ||
reject(x); | ||
}; | ||
autoPromiseToTask(taskOrPromise).fork(handleReject, handleResolve(x => { | ||
applierFunction = x; | ||
})); | ||
autoPromiseToTask(appliedTaskOrPromise).fork(handleReject, handleResolve(x => { | ||
hasResultLoaded = true; | ||
targetResult = x; | ||
})); | ||
}); | ||
/** | ||
@@ -879,7 +579,5 @@ * Wait some number of seconds to continue after a successful task. | ||
function wait(ms, task) { | ||
return new Task((reject, resolve) => { | ||
setTimeout(() => task.fork(reject, resolve), ms); | ||
}); | ||
} | ||
const wait = (ms, task) => new Task((reject, resolve) => { | ||
setTimeout(() => task.fork(reject, resolve), ms); | ||
}); | ||
/** | ||
@@ -891,5 +589,3 @@ * If a task fails, retry it in the future. | ||
function retryIn(ms, task) { | ||
return task.orElse(() => task.wait(ms)); | ||
} | ||
const retryIn = (ms, task) => task.orElse(() => task.wait(ms)); | ||
/** | ||
@@ -902,5 +598,3 @@ * If a task fails, retry it X times, with exponential backoff. | ||
function retryWithExponentialBackoff(ms, times, task) { | ||
return range(times).reduce((sum, i) => sum.retryIn(ms * 2 ** i), task); | ||
} | ||
const retryWithExponentialBackoff = (ms, times, task) => range(times).reduce((sum, i) => sum.retryIn(ms * 2 ** i), task); | ||
/** | ||
@@ -912,6 +606,201 @@ * Takes a nested task of tasks, which often comes from a map, and | ||
function flatten(task) { | ||
return task.chain(identity); | ||
const flatten = task => task.chain(identity); | ||
/** | ||
* Create a new task. | ||
* @param computation A function which will be run when the task starts. | ||
*/ | ||
class Task { | ||
constructor(computation) { | ||
this.computation = computation; | ||
this.isCanceled = false; | ||
} | ||
fork(reject, resolve) { | ||
let localCancel = this.isCanceled; | ||
const result = { | ||
cancel: () => localCancel = true | ||
}; | ||
if (localCancel) { | ||
return result; | ||
} | ||
this.computation(err => { | ||
if (!localCancel) { | ||
reject(err); | ||
} | ||
}, value => { | ||
if (!localCancel) { | ||
resolve(value); | ||
} | ||
}); | ||
return result; | ||
} | ||
cancel() { | ||
this.isCanceled = true; | ||
} | ||
/** | ||
* Alias to match promise API and let async/await work. | ||
* Mostly "private". Do not use. | ||
*/ | ||
then(onfulfilled, onrejected) { | ||
return this.toPromise().then(onfulfilled, onrejected); | ||
} | ||
chain(fn) { | ||
return chain(fn, this); | ||
} | ||
succeedIf(fn) { | ||
return succeedIf(fn, this); | ||
} | ||
onlyOnce() { | ||
return onlyOnce(this); | ||
} | ||
toPromise() { | ||
return toPromise(this); | ||
} | ||
swap() { | ||
return swap(this); | ||
} | ||
map(fn) { | ||
return map(fn, this); | ||
} | ||
forward(value) { | ||
return map(constant(value), this); | ||
} | ||
append(...items) { | ||
return map(a => [a, ...items], this); | ||
} | ||
prepend(...items) { | ||
return map(a => [...items, a], this); | ||
} | ||
tap(fn) { | ||
return tap(fn, this); | ||
} | ||
tapChain(fn) { | ||
return tapChain(fn, this); | ||
} | ||
mapError(fn) { | ||
return mapError(fn, this); | ||
} | ||
errorUnion() { | ||
return errorUnion(this); | ||
} | ||
mapBoth(handleError, handleSuccess) { | ||
return mapBoth(handleError, handleSuccess, this); | ||
} | ||
fold(handleError, handleSuccess) { | ||
return fold$1(handleError, handleSuccess, this); | ||
} | ||
orElse(fn) { | ||
return orElse(fn, this); | ||
} | ||
ap(taskOrPromise) { | ||
return ap(this, taskOrPromise); | ||
} | ||
wait(ms) { | ||
return wait(ms, this); | ||
} | ||
retryIn(ms) { | ||
return retryIn(ms, this); | ||
} | ||
retryWithExponentialBackoff(ms, times) { | ||
return retryWithExponentialBackoff(ms, times, this); | ||
} | ||
flatten() { | ||
return flatten(this); | ||
} | ||
} | ||
Task.fail = fail$1; | ||
Task.succeed = succeed$1; | ||
Task.empty = empty; | ||
Task.failIn = failIn; | ||
Task.succeedIn = succeedIn; | ||
Task.of = succeed$1; | ||
Task.all = all; | ||
Task.sequence = sequence; | ||
Task.firstSuccess = firstSuccess; | ||
Task.never = never; | ||
Task.fromPromise = fromPromise; | ||
Task.fromLazyPromise = fromLazyPromise; | ||
Task.race = race; | ||
Task.external = external; | ||
Task.emitter = emitter; | ||
Task.succeedBy = succeedBy; | ||
Task.ap = ap; | ||
Task.map2 = map2; | ||
Task.map3 = map3; | ||
Task.map4 = map4; | ||
Task.loop = loop; | ||
Task.reduce = reduce; | ||
Task.zip = zip; | ||
Task.zipWith = zipWith; | ||
Task.flatten = flatten; | ||
/** | ||
* A special form of Task which can be resolved/rejected externally. | ||
*/ | ||
class ExternalTask extends Task { | ||
constructor() { | ||
super((reject, resolve) => { | ||
switch (this.lastState_) { | ||
case "error": | ||
reject(this.alreadyError_); | ||
case "success": | ||
resolve(this.alreadyResult_); | ||
case "pending": | ||
this.computationReject_ = reject; | ||
this.computationResolve_ = resolve; | ||
} | ||
}); | ||
this.lastState_ = "pending"; | ||
} | ||
reject(error) { | ||
this.alreadyError_ = error; | ||
this.lastState_ = "error"; | ||
if (this.computationReject_) { | ||
this.computationReject_(error); | ||
} | ||
} | ||
resolve(result) { | ||
this.alreadyResult_ = result; | ||
this.lastState_ = "success"; | ||
if (this.computationResolve_) { | ||
this.computationResolve_(result); | ||
} | ||
} | ||
} | ||
class Subscription { | ||
@@ -918,0 +807,0 @@ constructor() { |
import { all, of } from "../Task/Task"; | ||
import { pairsToIndexedObject } from "../util"; | ||
const editors = ["1", "2", "3"]; | ||
function loadUserName(id) { | ||
return Promise.resolve([id, "name"]); | ||
} | ||
function loadUserNameTask(id) { | ||
return of([id, "name"]); | ||
} | ||
function editorTuplesToMap(results) { | ||
return results | ||
.filter(([, userName]) => userName) | ||
.reduce(pairsToIndexedObject, {}); | ||
} | ||
const loadUserName = (id) => Promise.resolve([id, "name"]); | ||
const loadUserNameTask = (id) => of([id, "name"]); | ||
const editorTuplesToMap = (results) => results | ||
.filter(([, userName]) => userName) | ||
.reduce(pairsToIndexedObject, {}); | ||
describe("more test", () => { | ||
@@ -16,0 +10,0 @@ test("Promises", async () => { |
@@ -68,9 +68,3 @@ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars */ | ||
const type = "png"; | ||
const devicesToScreenshot = [ | ||
iPhone, | ||
iPad, | ||
Android, | ||
desktopSmall, | ||
desktopMedium | ||
]; | ||
const devicesToScreenshot = [iPhone, iPad, Android, desktopSmall, desktopMedium]; | ||
const getLinkData = (elem) => { | ||
@@ -77,0 +71,0 @@ const attrObj = {}; |
@@ -26,13 +26,11 @@ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars */ | ||
}; | ||
function createClient(_options) { | ||
return { | ||
getSpace(__options) { | ||
return Task.of({ | ||
getEnvironment(___options) { | ||
return Task.of(ENV); | ||
} | ||
}); | ||
} | ||
}; | ||
} | ||
const createClient = (_options) => ({ | ||
getSpace(__options) { | ||
return Task.of({ | ||
getEnvironment(___options) { | ||
return Task.of(ENV); | ||
} | ||
}); | ||
} | ||
}); | ||
// CLI mock | ||
@@ -39,0 +37,0 @@ const ACCESS_TOKEN = "123"; |
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars */ | ||
import { Task } from "../Task/Task"; | ||
function slugify(..._args) { | ||
return "slug"; | ||
} | ||
function toJob(job) { | ||
const slugify = (..._args) => "slug"; | ||
const toJob = (job) => { | ||
if (!job.title || !job.id || !job.metadata || !Array.isArray(job.metadata)) { | ||
@@ -20,4 +18,4 @@ throw new Error("Invalid data"); | ||
return job; | ||
} | ||
function jsonToJobs(json) { | ||
}; | ||
const jsonToJobs = (json) => { | ||
if (!json.data || !Array.isArray(json.data.jobs)) { | ||
@@ -27,3 +25,3 @@ throw new Error("Invalid data"); | ||
return json.data.jobs.map(toJob); | ||
} | ||
}; | ||
const mergeJobsIntoContent = (pageContent, jobs) => { | ||
@@ -30,0 +28,0 @@ pageContent.body.forEach(slice => { |
@@ -14,5 +14,3 @@ import { all, of } from "../Task/Task"; | ||
const add = (a, b) => a + b; | ||
function sum(nums) { | ||
return nums.reduce(add, 0); | ||
} | ||
const sum = (nums) => nums.reduce(add, 0); | ||
const result = [1, 2, 3].reduce(to(sum)); | ||
@@ -19,0 +17,0 @@ expect(result).toBe(6); |
import { useCallback, useState } from "react"; | ||
import { fold, initialize, pending, succeed } from "../RemoteData/RemoteData"; | ||
export function useRemoteData(task) { | ||
export const useRemoteData = (task) => { | ||
const [state, setState] = useState(initialize()); | ||
@@ -18,2 +18,2 @@ const request = useCallback(() => { | ||
return [state, caseof, request]; | ||
} | ||
}; |
@@ -1,14 +0,14 @@ | ||
export function initialize() { | ||
return { type: "Initialized" }; | ||
} | ||
export function pending() { | ||
return { type: "Pending" }; | ||
} | ||
export function succeed(result) { | ||
return { type: "Success", result }; | ||
} | ||
export function fail(error) { | ||
return { type: "Failure", error }; | ||
} | ||
export function fold(onInitialized, onPending, onFailure, onSuccess, remote) { | ||
export const initialize = () => ({ | ||
type: "Initialized" | ||
}); | ||
export const pending = () => ({ type: "Pending" }); | ||
export const succeed = (result) => ({ | ||
type: "Success", | ||
result | ||
}); | ||
export const fail = (error) => ({ | ||
type: "Failure", | ||
error | ||
}); | ||
export const fold = (onInitialized, onPending, onFailure, onSuccess, remote) => { | ||
switch (remote.type) { | ||
@@ -24,2 +24,2 @@ case "Initialized": | ||
} | ||
} | ||
}; |
/* eslint-disable @typescript-eslint/no-misused-promises, @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-explicit-any, @typescript-eslint/no-use-before-define */ | ||
import { constant, identity, range } from "../util"; | ||
/** | ||
* Create a new task. | ||
* @param computation A function which will be run when the task starts. | ||
*/ | ||
export class Task { | ||
constructor(computation) { | ||
this.computation = computation; | ||
this.isCanceled = false; | ||
} | ||
fork(reject, resolve) { | ||
let localCancel = this.isCanceled; | ||
const result = { | ||
cancel: () => (localCancel = true) | ||
}; | ||
if (localCancel) { | ||
return result; | ||
} | ||
this.computation(err => { | ||
if (!localCancel) { | ||
reject(err); | ||
} | ||
}, value => { | ||
if (!localCancel) { | ||
resolve(value); | ||
} | ||
}); | ||
return result; | ||
} | ||
cancel() { | ||
this.isCanceled = true; | ||
} | ||
/** | ||
* Alias to match promise API and let async/await work. | ||
* Mostly "private". Do not use. | ||
*/ | ||
then(onfulfilled, onrejected) { | ||
return this.toPromise().then(onfulfilled, onrejected); | ||
} | ||
chain(fn) { | ||
return chain(fn, this); | ||
} | ||
succeedIf(fn) { | ||
return succeedIf(fn, this); | ||
} | ||
onlyOnce() { | ||
return onlyOnce(this); | ||
} | ||
toPromise() { | ||
return toPromise(this); | ||
} | ||
swap() { | ||
return swap(this); | ||
} | ||
map(fn) { | ||
return map(fn, this); | ||
} | ||
forward(value) { | ||
return map(constant(value), this); | ||
} | ||
append(...items) { | ||
return map(a => [a, ...items], this); | ||
} | ||
prepend(...items) { | ||
return map(a => [...items, a], this); | ||
} | ||
tap(fn) { | ||
return tap(fn, this); | ||
} | ||
tapChain(fn) { | ||
return tapChain(fn, this); | ||
} | ||
mapError(fn) { | ||
return mapError(fn, this); | ||
} | ||
mapBoth(handleError, handleSuccess) { | ||
return mapBoth(handleError, handleSuccess, this); | ||
} | ||
fold(handleError, handleSuccess) { | ||
return fold(handleError, handleSuccess, this); | ||
} | ||
orElse(fn) { | ||
return orElse(fn, this); | ||
} | ||
ap(taskOrPromise) { | ||
return ap(this, taskOrPromise); | ||
} | ||
wait(ms) { | ||
return wait(ms, this); | ||
} | ||
retryIn(ms) { | ||
return retryIn(ms, this); | ||
} | ||
retryWithExponentialBackoff(ms, times) { | ||
return retryWithExponentialBackoff(ms, times, this); | ||
} | ||
flatten() { | ||
return flatten(this); | ||
} | ||
} | ||
Task.fail = fail; | ||
Task.succeed = succeed; | ||
Task.empty = empty; | ||
Task.failIn = failIn; | ||
Task.succeedIn = succeedIn; | ||
Task.of = succeed; | ||
Task.all = all; | ||
Task.sequence = sequence; | ||
Task.firstSuccess = firstSuccess; | ||
Task.never = never; | ||
Task.fromPromise = fromPromise; | ||
Task.fromLazyPromise = fromLazyPromise; | ||
Task.race = race; | ||
Task.external = external; | ||
Task.emitter = emitter; | ||
Task.succeedBy = succeedBy; | ||
Task.ap = ap; | ||
Task.map2 = map2; | ||
Task.map3 = map3; | ||
Task.map4 = map4; | ||
Task.loop = loop; | ||
Task.reduce = reduce; | ||
Task.zip = zip; | ||
Task.zipWith = zipWith; | ||
Task.flatten = flatten; | ||
/** | ||
* A special form of Task which can be resolved/rejected externally. | ||
*/ | ||
export class ExternalTask extends Task { | ||
constructor() { | ||
super((reject, resolve) => { | ||
switch (this.lastState_) { | ||
case "error": | ||
reject(this.alreadyError_); | ||
case "success": | ||
resolve(this.alreadyResult_); | ||
case "pending": | ||
this.computationReject_ = reject; | ||
this.computationResolve_ = resolve; | ||
} | ||
}); | ||
this.lastState_ = "pending"; | ||
} | ||
reject(error) { | ||
this.alreadyError_ = error; | ||
this.lastState_ = "error"; | ||
if (this.computationReject_) { | ||
this.computationReject_(error); | ||
} | ||
} | ||
resolve(result) { | ||
this.alreadyResult_ = result; | ||
this.lastState_ = "success"; | ||
if (this.computationResolve_) { | ||
this.computationResolve_(result); | ||
} | ||
} | ||
} | ||
/** | ||
* Creates a Task which can be resolved/rejected externally. | ||
*/ | ||
export function external() { | ||
return new ExternalTask(); | ||
} | ||
export function emitter(fn) { | ||
export const external = () => new ExternalTask(); | ||
export const emitter = (fn) => { | ||
const task = external(); | ||
@@ -179,3 +20,3 @@ return [ | ||
]; | ||
} | ||
}; | ||
/** | ||
@@ -187,5 +28,3 @@ * Creates a Task which has already successfully completed with `result`. | ||
*/ | ||
export function succeed(result) { | ||
return new Task((_, resolve) => resolve(result)); | ||
} | ||
export const succeed = (result) => new Task((_, resolve) => resolve(result)); | ||
export const of = succeed; | ||
@@ -196,12 +35,10 @@ /** | ||
*/ | ||
export function succeedBy(result) { | ||
return new Task((reject, resolve) => { | ||
try { | ||
resolve(result()); | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
} | ||
export const succeedBy = (result) => new Task((reject, resolve) => { | ||
try { | ||
resolve(result()); | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
/** | ||
@@ -211,5 +48,3 @@ * Creates a Task has an empty result. | ||
*/ | ||
export function empty() { | ||
return of(void 0); | ||
} | ||
export const empty = () => of(void 0); | ||
/** | ||
@@ -220,5 +55,3 @@ * Creates a Task which automatically succeeds at some time in the future with `result`. | ||
*/ | ||
export function succeedIn(ms, result) { | ||
return new Task((_, resolve) => setTimeout(() => resolve(result), ms)); | ||
} | ||
export const succeedIn = (ms, result) => new Task((_, resolve) => setTimeout(() => resolve(result), ms)); | ||
/** | ||
@@ -229,5 +62,3 @@ * Creates a Task which has already failed with `error`. | ||
*/ | ||
export function fail(error) { | ||
return new Task(reject => reject(error)); | ||
} | ||
export const fail = (error) => new Task(reject => reject(error)); | ||
/** | ||
@@ -238,11 +69,7 @@ * Creates a Task which automatically fails at some time in the future with `error`. | ||
*/ | ||
export function failIn(ms, error) { | ||
return new Task(reject => setTimeout(() => reject(error), ms)); | ||
} | ||
export const failIn = (ms, error) => new Task(reject => setTimeout(() => reject(error), ms)); | ||
/** | ||
* Creates a Task will never finish. | ||
*/ | ||
export function never() { | ||
return new Task(() => void 0); | ||
} | ||
export const never = () => new Task(() => void 0); | ||
/** | ||
@@ -254,5 +81,3 @@ * Execute task computation and call handlers on completion. | ||
*/ | ||
export function fork(reject, resolve, task) { | ||
return task.fork(reject, resolve); | ||
} | ||
export const fork = (reject, resolve, task) => task.fork(reject, resolve); | ||
/** | ||
@@ -263,5 +88,3 @@ * Chain a task to run after a previous task has succeeded. | ||
*/ | ||
export function chain(fn, task) { | ||
return new Task((reject, resolve) => task.fork(reject, b => autoPromiseToTask(fn(b)).fork(reject, resolve))); | ||
} | ||
export const chain = (fn, task) => new Task((reject, resolve) => task.fork(reject, b => autoPromiseToTask(fn(b)).fork(reject, resolve))); | ||
/** | ||
@@ -272,8 +95,3 @@ * If a function returns a Promise instead of a Task, automatically | ||
*/ | ||
function autoPromiseToTask(promiseOrTask) { | ||
if (promiseOrTask instanceof Promise) { | ||
return fromPromise(promiseOrTask); | ||
} | ||
return promiseOrTask; | ||
} | ||
const autoPromiseToTask = (promiseOrTask) => promiseOrTask instanceof Promise ? fromPromise(promiseOrTask) : promiseOrTask; | ||
/** | ||
@@ -284,12 +102,10 @@ * When forked, run a function which can check whether the task has already succeeded. | ||
*/ | ||
export function succeedIf(fn, task) { | ||
return new Task((reject, resolve) => { | ||
const result = fn(); | ||
if (result) { | ||
resolve(result); | ||
return; | ||
} | ||
task.fork(reject, resolve); | ||
}); | ||
} | ||
export const succeedIf = (fn, task) => new Task((reject, resolve) => { | ||
const result = fn(); | ||
if (result) { | ||
resolve(result); | ||
return; | ||
} | ||
task.fork(reject, resolve); | ||
}); | ||
/** | ||
@@ -300,3 +116,3 @@ * A task which only runs once. Caches the success or failure. Be careful. | ||
*/ | ||
export function onlyOnce(task) { | ||
export const onlyOnce = (task) => { | ||
let state = "initialized"; | ||
@@ -307,7 +123,7 @@ let cachedResult; | ||
const callbacks = {}; | ||
function notify(reject, resolve) { | ||
const notify = (reject, resolve) => { | ||
const id = callbackId++; | ||
callbacks[id] = { reject, resolve }; | ||
} | ||
function triggerReject(error) { | ||
}; | ||
const triggerReject = (error) => { | ||
state = "failure"; | ||
@@ -319,4 +135,4 @@ cachedError = error; | ||
}); | ||
} | ||
function triggerResolve(result) { | ||
}; | ||
const triggerResolve = (result) => { | ||
state = "success"; | ||
@@ -328,3 +144,3 @@ cachedResult = result; | ||
}); | ||
} | ||
}; | ||
return new Task((reject, resolve) => { | ||
@@ -347,3 +163,3 @@ switch (state) { | ||
}); | ||
} | ||
}; | ||
export const share = onlyOnce; | ||
@@ -354,9 +170,6 @@ /** | ||
*/ | ||
export function fromPromise(maybePromise) { | ||
if (maybePromise instanceof Promise) { | ||
// eslint-disable-next-line @typescript-eslint/no-misused-promises | ||
return new Task((reject, resolve) => maybePromise.then(resolve, reject)); | ||
} | ||
return of(maybePromise); | ||
} | ||
export const fromPromise = (maybePromise) => maybePromise instanceof Promise | ||
? // eslint-disable-next-line @typescript-eslint/no-misused-promises | ||
new Task((reject, resolve) => maybePromise.then(resolve, reject)) | ||
: of(maybePromise); | ||
/** | ||
@@ -366,5 +179,3 @@ * Take a function which generates a promise and lazily execute it. | ||
*/ | ||
export function fromLazyPromise(getPromise) { | ||
return succeedBy(getPromise).chain(fromPromise); | ||
} | ||
export const fromLazyPromise = (getPromise) => succeedBy(getPromise).chain(fromPromise); | ||
/** | ||
@@ -374,5 +185,3 @@ * Given a task, create a Promise which resolves when the task does. | ||
*/ | ||
export function toPromise(task) { | ||
return new Promise((resolve, reject) => task.fork(reject, resolve)); | ||
} | ||
export const toPromise = (task) => new Promise((resolve, reject) => task.fork(reject, resolve)); | ||
/** | ||
@@ -383,20 +192,18 @@ * Given an array of tasks, return the one which finishes first. | ||
*/ | ||
export function race(tasksOrPromises) { | ||
return new Task((reject, resolve) => { | ||
let done = false; | ||
return tasksOrPromises.map(taskOrPromise => autoPromiseToTask(taskOrPromise).fork((error) => { | ||
if (done) { | ||
return; | ||
} | ||
done = true; | ||
reject(error); | ||
}, (result) => { | ||
if (done) { | ||
return; | ||
} | ||
done = true; | ||
resolve(result); | ||
})); | ||
}); | ||
} | ||
export const race = (tasksOrPromises) => new Task((reject, resolve) => { | ||
let done = false; | ||
return tasksOrPromises.map(taskOrPromise => autoPromiseToTask(taskOrPromise).fork((error) => { | ||
if (done) { | ||
return; | ||
} | ||
done = true; | ||
reject(error); | ||
}, (result) => { | ||
if (done) { | ||
return; | ||
} | ||
done = true; | ||
resolve(result); | ||
})); | ||
}); | ||
export class LoopBreak { | ||
@@ -418,19 +225,17 @@ constructor(value) { | ||
*/ | ||
export function loop(fn, initialValue) { | ||
return new Task((reject, resolve) => { | ||
const tryLoop = (currentValue) => { | ||
fn(currentValue).fork(err => { | ||
reject(err); | ||
}, result => { | ||
if (result instanceof LoopBreak) { | ||
resolve(result.value); | ||
} | ||
if (result instanceof LoopContinue) { | ||
tryLoop(result.value); | ||
} | ||
}); | ||
}; | ||
tryLoop(initialValue); | ||
}); | ||
} | ||
export const loop = (fn, initialValue) => new Task((reject, resolve) => { | ||
const tryLoop = (currentValue) => { | ||
fn(currentValue).fork(err => { | ||
reject(err); | ||
}, result => { | ||
if (result instanceof LoopBreak) { | ||
resolve(result.value); | ||
} | ||
if (result instanceof LoopContinue) { | ||
tryLoop(result.value); | ||
} | ||
}); | ||
}; | ||
tryLoop(initialValue); | ||
}); | ||
/** | ||
@@ -444,12 +249,10 @@ * An async reducer. Given an initial return value and an array of | ||
*/ | ||
export function reduce(fn, initialValue, items) { | ||
return loop(({ remainingItems, currentResult }) => { | ||
if (remainingItems.length === 0) { | ||
return of(new LoopBreak(currentResult)); | ||
} | ||
const [head, ...tail] = remainingItems; | ||
const index = items.length - tail.length - 1; | ||
return fn(currentResult, head, index, items).map(nextResult => new LoopContinue({ remainingItems: tail, currentResult: nextResult })); | ||
}, { remainingItems: items, currentResult: initialValue }); | ||
} | ||
export const reduce = (fn, initialValue, items) => loop(({ remainingItems, currentResult }) => { | ||
if (remainingItems.length === 0) { | ||
return of(new LoopBreak(currentResult)); | ||
} | ||
const [head, ...tail] = remainingItems; | ||
const index = items.length - tail.length - 1; | ||
return fn(currentResult, head, index, items).map(nextResult => new LoopContinue({ remainingItems: tail, currentResult: nextResult })); | ||
}, { remainingItems: items, currentResult: initialValue }); | ||
/** | ||
@@ -459,7 +262,5 @@ * Given an array of tasks, return the one which finishes successfully first. | ||
*/ | ||
export function firstSuccess(tasksOrPromises) { | ||
if (tasksOrPromises.length === 0) { | ||
return fail([]); | ||
} | ||
return new Task((reject, resolve) => { | ||
export const firstSuccess = (tasksOrPromises) => tasksOrPromises.length === 0 | ||
? fail([]) | ||
: new Task((reject, resolve) => { | ||
let isDone = false; | ||
@@ -485,3 +286,2 @@ let runningTasks = tasksOrPromises.length; | ||
}); | ||
} | ||
/** | ||
@@ -492,7 +292,5 @@ * Given an array of task which return a result, return a new task which results an array of results. | ||
*/ | ||
export function all(tasksOrPromises) { | ||
if (tasksOrPromises.length === 0) { | ||
return of([]); | ||
} | ||
return new Task((reject, resolve) => { | ||
export const all = (tasksOrPromises) => tasksOrPromises.length === 0 | ||
? of([]) | ||
: new Task((reject, resolve) => { | ||
let isDone = false; | ||
@@ -518,3 +316,2 @@ let runningTasks = tasksOrPromises.length; | ||
}); | ||
} | ||
/** | ||
@@ -526,5 +323,3 @@ * Creates a task that waits for two tasks of different types to | ||
*/ | ||
export function zip(taskAOrPromise, taskBOrPromise) { | ||
return map2(a => b => [a, b], taskAOrPromise, taskBOrPromise); | ||
} | ||
export const zip = (taskAOrPromise, taskBOrPromise) => map2(a => b => [a, b], taskAOrPromise, taskBOrPromise); | ||
/** | ||
@@ -538,5 +333,3 @@ * Creates a task that waits for two tasks of different types to | ||
*/ | ||
export function zipWith(fn, taskAOrPromise, taskBOrPromise) { | ||
return map2(a => b => fn(a, b), taskAOrPromise, taskBOrPromise); | ||
} | ||
export const zipWith = (fn, taskAOrPromise, taskBOrPromise) => map2(a => b => fn(a, b), taskAOrPromise, taskBOrPromise); | ||
/** | ||
@@ -546,7 +339,5 @@ * Given an array of task which return a result, return a new task which results an array of results. | ||
*/ | ||
export function sequence(tasksOrPromises) { | ||
if (tasksOrPromises.length === 0) { | ||
return of([]); | ||
} | ||
return tasksOrPromises.reduce((sum, taskOrPromise) => { | ||
export const sequence = (tasksOrPromises) => tasksOrPromises.length === 0 | ||
? of([]) | ||
: tasksOrPromises.reduce((sum, taskOrPromise) => { | ||
return chain(list => { | ||
@@ -556,3 +347,2 @@ return map(result => [...list, result], autoPromiseToTask(taskOrPromise)); | ||
}, succeed([])); | ||
} | ||
/** | ||
@@ -562,5 +352,3 @@ * Given a task, swap the error and success values. | ||
*/ | ||
export function swap(task) { | ||
return new Task((reject, resolve) => task.fork(e => resolve(e), s => reject(s))); | ||
} | ||
export const swap = (task) => new Task((reject, resolve) => task.fork(e => resolve(e), s => reject(s))); | ||
/** | ||
@@ -571,23 +359,15 @@ * Given a task, map the successful value to a Task. | ||
*/ | ||
export function map(fn, task) { | ||
return new Task((reject, resolve) => task.fork(reject, result => resolve(fn(result)))); | ||
} | ||
export function map2(fn, taskA, taskB) { | ||
return Task.of(fn) | ||
.ap(taskA) | ||
.ap(taskB); | ||
} | ||
export function map3(fn, taskA, taskB, taskC) { | ||
return Task.of(fn) | ||
.ap(taskA) | ||
.ap(taskB) | ||
.ap(taskC); | ||
} | ||
export function map4(fn, taskA, taskB, taskC, taskD) { | ||
return Task.of(fn) | ||
.ap(taskA) | ||
.ap(taskB) | ||
.ap(taskC) | ||
.ap(taskD); | ||
} | ||
export const map = (fn, task) => new Task((reject, resolve) => task.fork(reject, result => resolve(fn(result)))); | ||
export const map2 = (fn, taskA, taskB) => Task.of(fn) | ||
.ap(taskA) | ||
.ap(taskB); | ||
export const map3 = (fn, taskA, taskB, taskC) => Task.of(fn) | ||
.ap(taskA) | ||
.ap(taskB) | ||
.ap(taskC); | ||
export const map4 = (fn, taskA, taskB, taskC, taskD) => Task.of(fn) | ||
.ap(taskA) | ||
.ap(taskB) | ||
.ap(taskC) | ||
.ap(taskD); | ||
/** | ||
@@ -598,8 +378,6 @@ * Run a side-effect on success. Useful for logging. | ||
*/ | ||
export function tap(fn, task) { | ||
return map(result => { | ||
fn(result); | ||
return result; | ||
}, task); | ||
} | ||
export const tap = (fn, task) => map(result => { | ||
fn(result); | ||
return result; | ||
}, task); | ||
/** | ||
@@ -611,5 +389,3 @@ * Run an additional task on success. Useful for async side-effects. | ||
*/ | ||
export function tapChain(fn, task) { | ||
return chain(result => autoPromiseToTask(fn(result)).forward(result), task); | ||
} | ||
export const tapChain = (fn, task) => chain(result => autoPromiseToTask(fn(result)).forward(result), task); | ||
/** | ||
@@ -622,5 +398,4 @@ * Given a task, map the failure error to a Task. | ||
*/ | ||
export function mapError(fn, task) { | ||
return new Task((reject, resolve) => task.fork(error => reject(fn(error)), resolve)); | ||
} | ||
export const mapError = (fn, task) => new Task((reject, resolve) => task.fork(error => reject(fn(error)), resolve)); | ||
export const errorUnion = (task) => task; | ||
/** | ||
@@ -632,5 +407,3 @@ * Given a task, map both the failure error and the success result to a Task. | ||
*/ | ||
export function mapBoth(handleError, handleSuccess, task) { | ||
return mapError(handleError, map(handleSuccess, task)); | ||
} | ||
export const mapBoth = (handleError, handleSuccess, task) => mapError(handleError, map(handleSuccess, task)); | ||
/** | ||
@@ -642,5 +415,3 @@ * Given a task, map both the failure error and the success result to a Task which always succeeds. | ||
*/ | ||
export function fold(handleError, handleSuccess, task) { | ||
return new Task((_, resolve) => task.fork(error => resolve(handleError(error)), result => resolve(handleSuccess(result)))); | ||
} | ||
export const fold = (handleError, handleSuccess, task) => new Task((_, resolve) => task.fork(error => resolve(handleError(error)), result => resolve(handleSuccess(result)))); | ||
/** | ||
@@ -651,5 +422,3 @@ * Given a task, if the result in a failure, attemp to generate another Task from the error. | ||
*/ | ||
export function orElse(fn, task) { | ||
return new Task((reject, resolve) => task.fork(error => autoPromiseToTask(fn(error)).fork(reject, resolve), resolve)); | ||
} | ||
export const orElse = (fn, task) => new Task((reject, resolve) => task.fork(error => autoPromiseToTask(fn(error)).fork(reject, resolve), resolve)); | ||
/** | ||
@@ -661,35 +430,33 @@ * Given a task that succeeds with a map function as its result, | ||
*/ | ||
export function ap(taskOrPromise, appliedTaskOrPromise) { | ||
return new Task((reject, resolve) => { | ||
let targetResult; | ||
let applierFunction; | ||
let hasResultLoaded = false; | ||
let isRejected = false; | ||
const handleResolve = (onResolve) => { | ||
return (x) => { | ||
if (isRejected) { | ||
return; | ||
} | ||
onResolve(x); | ||
if (applierFunction && hasResultLoaded) { | ||
resolve(applierFunction(targetResult)); | ||
} | ||
}; | ||
}; | ||
const handleReject = (x) => { | ||
export const ap = (taskOrPromise, appliedTaskOrPromise) => new Task((reject, resolve) => { | ||
let targetResult; | ||
let applierFunction; | ||
let hasResultLoaded = false; | ||
let isRejected = false; | ||
const handleResolve = (onResolve) => { | ||
return (x) => { | ||
if (isRejected) { | ||
return; | ||
} | ||
isRejected = true; | ||
reject(x); | ||
onResolve(x); | ||
if (applierFunction && hasResultLoaded) { | ||
resolve(applierFunction(targetResult)); | ||
} | ||
}; | ||
autoPromiseToTask(taskOrPromise).fork(handleReject, handleResolve((x) => { | ||
applierFunction = x; | ||
})); | ||
autoPromiseToTask(appliedTaskOrPromise).fork(handleReject, handleResolve((x) => { | ||
hasResultLoaded = true; | ||
targetResult = x; | ||
})); | ||
}); | ||
} | ||
}; | ||
const handleReject = (x) => { | ||
if (isRejected) { | ||
return; | ||
} | ||
isRejected = true; | ||
reject(x); | ||
}; | ||
autoPromiseToTask(taskOrPromise).fork(handleReject, handleResolve((x) => { | ||
applierFunction = x; | ||
})); | ||
autoPromiseToTask(appliedTaskOrPromise).fork(handleReject, handleResolve((x) => { | ||
hasResultLoaded = true; | ||
targetResult = x; | ||
})); | ||
}); | ||
/** | ||
@@ -700,7 +467,5 @@ * Wait some number of seconds to continue after a successful task. | ||
*/ | ||
export function wait(ms, task) { | ||
return new Task((reject, resolve) => { | ||
setTimeout(() => task.fork(reject, resolve), ms); | ||
}); | ||
} | ||
export const wait = (ms, task) => new Task((reject, resolve) => { | ||
setTimeout(() => task.fork(reject, resolve), ms); | ||
}); | ||
/** | ||
@@ -711,5 +476,3 @@ * If a task fails, retry it in the future. | ||
*/ | ||
export function retryIn(ms, task) { | ||
return task.orElse(() => task.wait(ms)); | ||
} | ||
export const retryIn = (ms, task) => task.orElse(() => task.wait(ms)); | ||
/** | ||
@@ -721,5 +484,3 @@ * If a task fails, retry it X times, with exponential backoff. | ||
*/ | ||
export function retryWithExponentialBackoff(ms, times, task) { | ||
return range(times).reduce((sum, i) => sum.retryIn(ms * 2 ** i), task); | ||
} | ||
export const retryWithExponentialBackoff = (ms, times, task) => range(times).reduce((sum, i) => sum.retryIn(ms * 2 ** i), task); | ||
/** | ||
@@ -730,4 +491,162 @@ * Takes a nested task of tasks, which often comes from a map, and | ||
*/ | ||
export function flatten(task) { | ||
return task.chain(identity); | ||
export const flatten = (task) => task.chain(identity); | ||
/** | ||
* Create a new task. | ||
* @param computation A function which will be run when the task starts. | ||
*/ | ||
export class Task { | ||
constructor(computation) { | ||
this.computation = computation; | ||
this.isCanceled = false; | ||
} | ||
fork(reject, resolve) { | ||
let localCancel = this.isCanceled; | ||
const result = { | ||
cancel: () => (localCancel = true) | ||
}; | ||
if (localCancel) { | ||
return result; | ||
} | ||
this.computation(err => { | ||
if (!localCancel) { | ||
reject(err); | ||
} | ||
}, value => { | ||
if (!localCancel) { | ||
resolve(value); | ||
} | ||
}); | ||
return result; | ||
} | ||
cancel() { | ||
this.isCanceled = true; | ||
} | ||
/** | ||
* Alias to match promise API and let async/await work. | ||
* Mostly "private". Do not use. | ||
*/ | ||
then(onfulfilled, onrejected) { | ||
return this.toPromise().then(onfulfilled, onrejected); | ||
} | ||
chain(fn) { | ||
return chain(fn, this); | ||
} | ||
succeedIf(fn) { | ||
return succeedIf(fn, this); | ||
} | ||
onlyOnce() { | ||
return onlyOnce(this); | ||
} | ||
toPromise() { | ||
return toPromise(this); | ||
} | ||
swap() { | ||
return swap(this); | ||
} | ||
map(fn) { | ||
return map(fn, this); | ||
} | ||
forward(value) { | ||
return map(constant(value), this); | ||
} | ||
append(...items) { | ||
return map(a => [a, ...items], this); | ||
} | ||
prepend(...items) { | ||
return map(a => [...items, a], this); | ||
} | ||
tap(fn) { | ||
return tap(fn, this); | ||
} | ||
tapChain(fn) { | ||
return tapChain(fn, this); | ||
} | ||
mapError(fn) { | ||
return mapError(fn, this); | ||
} | ||
errorUnion() { | ||
return errorUnion(this); | ||
} | ||
mapBoth(handleError, handleSuccess) { | ||
return mapBoth(handleError, handleSuccess, this); | ||
} | ||
fold(handleError, handleSuccess) { | ||
return fold(handleError, handleSuccess, this); | ||
} | ||
orElse(fn) { | ||
return orElse(fn, this); | ||
} | ||
ap(taskOrPromise) { | ||
return ap(this, taskOrPromise); | ||
} | ||
wait(ms) { | ||
return wait(ms, this); | ||
} | ||
retryIn(ms) { | ||
return retryIn(ms, this); | ||
} | ||
retryWithExponentialBackoff(ms, times) { | ||
return retryWithExponentialBackoff(ms, times, this); | ||
} | ||
flatten() { | ||
return flatten(this); | ||
} | ||
} | ||
Task.fail = fail; | ||
Task.succeed = succeed; | ||
Task.empty = empty; | ||
Task.failIn = failIn; | ||
Task.succeedIn = succeedIn; | ||
Task.of = succeed; | ||
Task.all = all; | ||
Task.sequence = sequence; | ||
Task.firstSuccess = firstSuccess; | ||
Task.never = never; | ||
Task.fromPromise = fromPromise; | ||
Task.fromLazyPromise = fromLazyPromise; | ||
Task.race = race; | ||
Task.external = external; | ||
Task.emitter = emitter; | ||
Task.succeedBy = succeedBy; | ||
Task.ap = ap; | ||
Task.map2 = map2; | ||
Task.map3 = map3; | ||
Task.map4 = map4; | ||
Task.loop = loop; | ||
Task.reduce = reduce; | ||
Task.zip = zip; | ||
Task.zipWith = zipWith; | ||
Task.flatten = flatten; | ||
/** | ||
* A special form of Task which can be resolved/rejected externally. | ||
*/ | ||
export class ExternalTask extends Task { | ||
constructor() { | ||
super((reject, resolve) => { | ||
switch (this.lastState_) { | ||
case "error": | ||
reject(this.alreadyError_); | ||
case "success": | ||
resolve(this.alreadyResult_); | ||
case "pending": | ||
this.computationReject_ = reject; | ||
this.computationResolve_ = resolve; | ||
} | ||
}); | ||
this.lastState_ = "pending"; | ||
} | ||
reject(error) { | ||
this.alreadyError_ = error; | ||
this.lastState_ = "error"; | ||
if (this.computationReject_) { | ||
this.computationReject_(error); | ||
} | ||
} | ||
resolve(result) { | ||
this.alreadyResult_ = result; | ||
this.lastState_ = "success"; | ||
if (this.computationResolve_) { | ||
this.computationResolve_(result); | ||
} | ||
} | ||
} |
@@ -1,35 +0,25 @@ | ||
export function range(end, start = 0) { | ||
return Array(end - start) | ||
.fill(undefined) | ||
.map((_, i) => start + i); | ||
} | ||
export function to(fn) { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
return (sum, _item, index, all) => { | ||
const isLast = index === all.length - 1; | ||
if (!isLast) { | ||
return sum; | ||
} | ||
return fn(all); | ||
}; | ||
} | ||
export function constant(value) { | ||
return () => value; | ||
} | ||
export function identity(x) { | ||
return x; | ||
} | ||
export function toIndexedObject(fn) { | ||
return (sum, item, index) => { | ||
const [key, value] = fn(item, index); | ||
sum[key] = value; | ||
export const range = (end, start = 0) => Array(end - start) | ||
.fill(undefined) | ||
.map((_, i) => start + i); | ||
export const to = (fn) => | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
(sum, _item, index, all) => { | ||
const isLast = index === all.length - 1; | ||
if (!isLast) { | ||
return sum; | ||
}; | ||
} | ||
export function mapToIndexedObject(fn, items, initial = {}) { | ||
return items.reduce(toIndexedObject(fn), initial); | ||
} | ||
export function pairsToIndexedObject(sum, [key, value]) { | ||
} | ||
return fn(all); | ||
}; | ||
export const constant = (value) => () => value; | ||
export const identity = (x) => x; | ||
export const toIndexedObject = (fn) => (sum, item, index) => { | ||
const [key, value] = fn(item, index); | ||
sum[key] = value; | ||
return sum; | ||
} | ||
}; | ||
export const mapToIndexedObject = (fn, items, initial = {}) => items.reduce(toIndexedObject(fn), initial); | ||
export const pairsToIndexedObject = (sum, [key, value]) => { | ||
; | ||
sum[key] = value; | ||
return sum; | ||
}; |
import { Task } from "../Task/Task"; | ||
export declare function useRemoteData<E, S>(task: () => Task<E, S>): (import("../RemoteData/RemoteData").Initialized | import("../RemoteData/RemoteData").Pending | import("../RemoteData/RemoteData").Failure<E> | import("../RemoteData/RemoteData").Success<S> | (() => void) | (<R>(onInitialized: () => R, onPending: () => R, onFailure: (error: E) => R, onSuccess: (result: S) => R) => R))[]; | ||
export declare const useRemoteData: <E, S>(task: () => Task<E, S>) => (import("../RemoteData/RemoteData").Initialized | import("../RemoteData/RemoteData").Pending | import("../RemoteData/RemoteData").Failure<E> | import("../RemoteData/RemoteData").Success<S> | (<R>(onInitialized: () => R, onPending: () => R, onFailure: (error: E) => R, onSuccess: (result: S) => R) => R) | (() => void))[]; | ||
//# sourceMappingURL=useRemoteData.d.ts.map |
@@ -16,7 +16,7 @@ export interface Initialized { | ||
export declare type RemoteData<E, S> = Initialized | Pending | Failure<E> | Success<S>; | ||
export declare function initialize<E, S>(): RemoteData<E, S>; | ||
export declare function pending<E, S>(): RemoteData<E, S>; | ||
export declare function succeed<S>(result: S): RemoteData<never, S>; | ||
export declare function fail<E>(error: E): RemoteData<E, never>; | ||
export declare function fold<E, S, R>(onInitialized: () => R, onPending: () => R, onFailure: (error: E) => R, onSuccess: (result: S) => R, remote: RemoteData<E, S>): R; | ||
export declare const initialize: <E, S>() => RemoteData<E, S>; | ||
export declare const pending: <E, S>() => RemoteData<E, S>; | ||
export declare const succeed: <S>(result: S) => RemoteData<never, S>; | ||
export declare const fail: <E>(error: E) => RemoteData<E, never>; | ||
export declare const fold: <E, S, R>(onInitialized: () => R, onPending: () => R, onFailure: (error: E) => R, onSuccess: (result: S) => R, remote: RemoteData<E, S>) => R; | ||
//# sourceMappingURL=RemoteData.d.ts.map |
@@ -5,90 +5,6 @@ export declare type Reject<E> = (error: E) => void; | ||
/** | ||
* Create a new task. | ||
* @param computation A function which will be run when the task starts. | ||
*/ | ||
export declare class Task<E, S> implements PromiseLike<S> { | ||
private computation; | ||
static fail: typeof fail; | ||
static succeed: typeof succeed; | ||
static empty: typeof empty; | ||
static failIn: typeof failIn; | ||
static succeedIn: typeof succeedIn; | ||
static of: typeof succeed; | ||
static all: typeof all; | ||
static sequence: typeof sequence; | ||
static firstSuccess: typeof firstSuccess; | ||
static never: typeof never; | ||
static fromPromise: typeof fromPromise; | ||
static fromLazyPromise: typeof fromLazyPromise; | ||
static race: typeof race; | ||
static external: typeof external; | ||
static emitter: typeof emitter; | ||
static succeedBy: typeof succeedBy; | ||
static ap: typeof ap; | ||
static map2: typeof map2; | ||
static map3: typeof map3; | ||
static map4: typeof map4; | ||
static loop: typeof loop; | ||
static reduce: typeof reduce; | ||
static zip: typeof zip; | ||
static zipWith: typeof zipWith; | ||
static flatten: typeof flatten; | ||
isCanceled: boolean; | ||
constructor(computation: Fork<E, S>); | ||
fork(reject: Reject<E>, resolve: Resolve<S>): { | ||
cancel: () => void; | ||
}; | ||
cancel(): void; | ||
/** | ||
* Alias to match promise API and let async/await work. | ||
* Mostly "private". Do not use. | ||
*/ | ||
then<TResult1 = S, TResult2 = never>(onfulfilled?: ((value: S) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>; | ||
chain<S2>(fn: (result: S) => Task<E, S2> | Promise<S2>): Task<E, S2>; | ||
succeedIf(fn: () => S | undefined): Task<E, S>; | ||
onlyOnce(): Task<E, S>; | ||
toPromise(): Promise<S>; | ||
swap<E2 extends E, S2 extends S>(): Task<S2, E2>; | ||
map<S2>(fn: (result: S) => S2): Task<E, S2>; | ||
forward<S2>(value: S2): Task<E, S2>; | ||
append<A, B, C, D, E>(a: A, b: B, c: C, d: D, e: E): Task<E, [S, A, B, C, D, E]>; | ||
append<A, B, C, D>(a: A, b: B, c: C, d: D): Task<E, [S, A, B, C, D]>; | ||
append<A, B, C>(a: A, b: B, c: C): Task<E, [S, A, B, C]>; | ||
append<A, B>(a: A, b: B): Task<E, [S, A, B]>; | ||
append<A>(a: A): Task<E, [S, A]>; | ||
prepend<A, B, C, D, E>(a: A, b: B, c: C, d: D, e: E): Task<E, [S, A, B, C, D, E]>; | ||
prepend<A, B, C, D>(a: A, b: B, c: C, d: D): Task<E, [A, B, C, D, S]>; | ||
prepend<A, B, C>(a: A, b: B, c: C): Task<E, [A, B, C, S]>; | ||
prepend<A, B>(a: A, b: B): Task<E, [A, B, S]>; | ||
prepend<A>(a: A): Task<E, [A, S]>; | ||
tap(fn: (result: S) => void): Task<E, S>; | ||
tapChain<S2>(fn: (result: S) => Task<E, S2> | Promise<S2>): Task<E, S>; | ||
mapError<E2>(fn: (error: E) => E2): Task<E2, S>; | ||
mapBoth<E2, S2>(handleError: (error: E) => E2, handleSuccess: (success: S) => S2): Task<E2, S2>; | ||
fold<R>(handleError: (error: E) => R, handleSuccess: (success: S) => R): Task<unknown, R>; | ||
orElse<S2>(fn: (error: E) => Task<E, S | S2> | Promise<S | S2>): Task<E, S | S2>; | ||
ap<E2, S2, S3 = S extends (arg: S2) => any ? ReturnType<S> : never>(taskOrPromise: Task<E | E2, S2> | Promise<S2>): Task<E | E2, S3>; | ||
wait(ms: number): Task<E, S>; | ||
retryIn(ms: number): Task<E, S>; | ||
retryWithExponentialBackoff(ms: number, times: number): Task<E, S>; | ||
flatten<S2>(this: Task<E, Task<E, S2>>): Task<E, S2>; | ||
} | ||
/** | ||
* A special form of Task which can be resolved/rejected externally. | ||
*/ | ||
export declare class ExternalTask<E, S> extends Task<E, S> { | ||
private computationReject_?; | ||
private computationResolve_?; | ||
private alreadyError_?; | ||
private alreadyResult_?; | ||
private lastState_; | ||
constructor(); | ||
reject(error: E): void; | ||
resolve(result: S): void; | ||
} | ||
/** | ||
* Creates a Task which can be resolved/rejected externally. | ||
*/ | ||
export declare function external<E, S>(): ExternalTask<E, S>; | ||
export declare function emitter<Args extends any[], R>(fn: (...args: Args) => R): [ExternalTask<any, R>, (...args: Args) => void]; | ||
export declare const external: <E, S>() => ExternalTask<E, S>; | ||
export declare const emitter: <Args extends any[], R>(fn: (...args: Args) => R) => [ExternalTask<any, R>, (...args: Args) => void]; | ||
/** | ||
@@ -100,4 +16,4 @@ * Creates a Task which has already successfully completed with `result`. | ||
*/ | ||
export declare function succeed<S, E = any>(result: S): Task<E, S>; | ||
export declare const of: typeof succeed; | ||
export declare const succeed: <S, E = any>(result: S) => Task<E, S>; | ||
export declare const of: <S, E = any>(result: S) => Task<E, S>; | ||
/** | ||
@@ -107,3 +23,3 @@ * Creates a Task which succeeds when forked. | ||
*/ | ||
export declare function succeedBy<S, E = any>(result: () => S): Task<E, S>; | ||
export declare const succeedBy: <S, E = any>(result: () => S) => Task<E, S>; | ||
/** | ||
@@ -113,3 +29,3 @@ * Creates a Task has an empty result. | ||
*/ | ||
export declare function empty<E = any>(): Task<E, void>; | ||
export declare const empty: <E = any>() => Task<E, void>; | ||
/** | ||
@@ -120,3 +36,3 @@ * Creates a Task which automatically succeeds at some time in the future with `result`. | ||
*/ | ||
export declare function succeedIn<S, E = any>(ms: number, result: S): Task<E, S>; | ||
export declare const succeedIn: <S, E = any>(ms: number, result: S) => Task<E, S>; | ||
/** | ||
@@ -127,3 +43,3 @@ * Creates a Task which has already failed with `error`. | ||
*/ | ||
export declare function fail<E, S = any>(error: E): Task<E, S>; | ||
export declare const fail: <E, S = any>(error: E) => Task<E, S>; | ||
/** | ||
@@ -134,7 +50,7 @@ * Creates a Task which automatically fails at some time in the future with `error`. | ||
*/ | ||
export declare function failIn<E, S = any>(ms: number, error: E): Task<E, S>; | ||
export declare const failIn: <E, S = any>(ms: number, error: E) => Task<E, S>; | ||
/** | ||
* Creates a Task will never finish. | ||
*/ | ||
export declare function never(): Task<never, never>; | ||
export declare const never: () => Task<never, never>; | ||
/** | ||
@@ -146,3 +62,3 @@ * Execute task computation and call handlers on completion. | ||
*/ | ||
export declare function fork<E, S>(reject: Reject<E>, resolve: Resolve<S>, task: Task<E, S>): { | ||
export declare const fork: <E, S>(reject: Reject<E>, resolve: Resolve<S>, task: Task<E, S>) => { | ||
cancel: () => void; | ||
@@ -155,3 +71,3 @@ }; | ||
*/ | ||
export declare function chain<E, S, S2>(fn: (result: S) => Task<E, S2> | Promise<S2>, task: Task<E, S>): Task<E, S2>; | ||
export declare const chain: <E, S, S2>(fn: (result: S) => Task<E, S2> | Promise<S2>, task: Task<E, S>) => Task<E, S2>; | ||
/** | ||
@@ -162,3 +78,3 @@ * When forked, run a function which can check whether the task has already succeeded. | ||
*/ | ||
export declare function succeedIf<E, S>(fn: () => S | undefined, task: Task<E, S>): Task<E, S>; | ||
export declare const succeedIf: <E, S>(fn: () => S | undefined, task: Task<E, S>) => Task<E, S>; | ||
/** | ||
@@ -169,4 +85,4 @@ * A task which only runs once. Caches the success or failure. Be careful. | ||
*/ | ||
export declare function onlyOnce<E, S>(task: Task<E, S>): Task<E, S>; | ||
export declare const share: typeof onlyOnce; | ||
export declare const onlyOnce: <E, S>(task: Task<E, S>) => Task<E, S>; | ||
export declare const share: <E, S>(task: Task<E, S>) => Task<E, S>; | ||
/** | ||
@@ -176,3 +92,3 @@ * Given a promise, create a Task which relies on it. | ||
*/ | ||
export declare function fromPromise<S, E = any>(maybePromise: S | Promise<S>): Task<E, S>; | ||
export declare const fromPromise: <S, E = any>(maybePromise: S | Promise<S>) => Task<E, S>; | ||
/** | ||
@@ -182,3 +98,3 @@ * Take a function which generates a promise and lazily execute it. | ||
*/ | ||
export declare function fromLazyPromise<S, E = any>(getPromise: () => S | Promise<S>): Task<E, S>; | ||
export declare const fromLazyPromise: <S, E = any>(getPromise: () => S | Promise<S>) => Task<E, S>; | ||
/** | ||
@@ -188,3 +104,3 @@ * Given a task, create a Promise which resolves when the task does. | ||
*/ | ||
export declare function toPromise<E, S>(task: Task<E, S>): Promise<S>; | ||
export declare const toPromise: <E, S>(task: Task<E, S>) => Promise<S>; | ||
/** | ||
@@ -195,3 +111,3 @@ * Given an array of tasks, return the one which finishes first. | ||
*/ | ||
export declare function race<E, S>(tasksOrPromises: Array<Task<E, S> | Promise<S>>): Task<E, S>; | ||
export declare const race: <E, S>(tasksOrPromises: (Task<E, S> | Promise<S>)[]) => Task<E, S>; | ||
export declare class LoopBreak<S> { | ||
@@ -211,3 +127,3 @@ readonly value: S; | ||
*/ | ||
export declare function loop<E, S, T>(fn: (currentValue: T) => Task<E, LoopBreak<S> | LoopContinue<T>>, initialValue: T): Task<E, S>; | ||
export declare const loop: <E, S, T>(fn: (currentValue: T) => Task<E, LoopBreak<S> | LoopContinue<T>>, initialValue: T) => Task<E, S>; | ||
/** | ||
@@ -221,3 +137,3 @@ * An async reducer. Given an initial return value and an array of | ||
*/ | ||
export declare function reduce<E, T, V>(fn: (acc: V, currentValue: T, index: number, original: T[]) => Task<E, V>, initialValue: V, items: T[]): Task<E, V>; | ||
export declare const reduce: <E, T, V>(fn: (acc: V, currentValue: T, index: number, original: T[]) => Task<E, V>, initialValue: V, items: T[]) => Task<E, V>; | ||
/** | ||
@@ -227,3 +143,3 @@ * Given an array of tasks, return the one which finishes successfully first. | ||
*/ | ||
export declare function firstSuccess<E, S>(tasksOrPromises: Array<Task<E, S> | Promise<S>>): Task<E[], S>; | ||
export declare const firstSuccess: <E, S>(tasksOrPromises: (Task<E, S> | Promise<S>)[]) => Task<E[], S>; | ||
/** | ||
@@ -234,3 +150,3 @@ * Given an array of task which return a result, return a new task which results an array of results. | ||
*/ | ||
export declare function all<E, S>(tasksOrPromises: Array<Task<E, S> | Promise<S>>): Task<E, S[]>; | ||
export declare const all: <E, S>(tasksOrPromises: (Task<E, S> | Promise<S>)[]) => Task<E, S[]>; | ||
/** | ||
@@ -242,3 +158,3 @@ * Creates a task that waits for two tasks of different types to | ||
*/ | ||
export declare function zip<E, E2, S, S2>(taskAOrPromise: Task<E, S> | Promise<S>, taskBOrPromise: Task<E2, S2> | Promise<S2>): Task<E | E2, [S, S2]>; | ||
export declare const zip: <E, E2, S, S2>(taskAOrPromise: Task<E, S> | Promise<S>, taskBOrPromise: Task<E2, S2> | Promise<S2>) => Task<E | E2, [S, S2]>; | ||
/** | ||
@@ -252,3 +168,3 @@ * Creates a task that waits for two tasks of different types to | ||
*/ | ||
export declare function zipWith<E, E2, S, S2, V>(fn: (resultA: S, resultB: S2) => V, taskAOrPromise: Task<E, S> | Promise<S>, taskBOrPromise: Task<E2, S2> | Promise<S2>): Task<E | E2, V>; | ||
export declare const zipWith: <E, E2, S, S2, V>(fn: (resultA: S, resultB: S2) => V, taskAOrPromise: Task<E, S> | Promise<S>, taskBOrPromise: Task<E2, S2> | Promise<S2>) => Task<E | E2, V>; | ||
/** | ||
@@ -258,3 +174,3 @@ * Given an array of task which return a result, return a new task which results an array of results. | ||
*/ | ||
export declare function sequence<E, S>(tasksOrPromises: Array<Task<E, S> | Promise<S>>): Task<E, S[]>; | ||
export declare const sequence: <E, S>(tasksOrPromises: (Task<E, S> | Promise<S>)[]) => Task<E, S[]>; | ||
/** | ||
@@ -264,3 +180,3 @@ * Given a task, swap the error and success values. | ||
*/ | ||
export declare function swap<E, S, E2 extends E, S2 extends S>(task: Task<E, S>): Task<S2, E2>; | ||
export declare const swap: <E, S, E2 extends E, S2 extends S>(task: Task<E, S>) => Task<S2, E2>; | ||
/** | ||
@@ -271,6 +187,6 @@ * Given a task, map the successful value to a Task. | ||
*/ | ||
export declare function map<E, S, S2>(fn: (result: S) => S2, task: Task<E, S>): Task<E, S2>; | ||
export declare function map2<E, E2, S, S2, S3>(fn: (a: S) => (b: S2) => S3, taskA: Task<E, S> | Promise<S>, taskB: Task<E2, S2> | Promise<S2>): Task<E | E2, S3>; | ||
export declare function map3<E, E2, E3, S, S2, S3, S4>(fn: (a: S) => (b: S2) => (c: S3) => S4, taskA: Task<E, S> | Promise<S>, taskB: Task<E2, S2> | Promise<S2>, taskC: Task<E3, S3> | Promise<S3>): Task<E | E2 | E3, S4>; | ||
export declare function map4<E, E2, E3, E4, S, S2, S3, S4, S5>(fn: (a: S) => (b: S2) => (c: S3) => (d: S4) => S5, taskA: Task<E, S> | Promise<S>, taskB: Task<E2, S2> | Promise<S2>, taskC: Task<E3, S3> | Promise<S3>, taskD: Task<E4, S4> | Promise<S4>): Task<E | E2 | E3 | E4, S5>; | ||
export declare const map: <E, S, S2>(fn: (result: S) => S2, task: Task<E, S>) => Task<E, S2>; | ||
export declare const map2: <E, E2, S, S2, S3>(fn: (a: S) => (b: S2) => S3, taskA: Task<E, S> | Promise<S>, taskB: Task<E2, S2> | Promise<S2>) => Task<E | E2, S3>; | ||
export declare const map3: <E, E2, E3, S, S2, S3, S4>(fn: (a: S) => (b: S2) => (c: S3) => S4, taskA: Task<E, S> | Promise<S>, taskB: Task<E2, S2> | Promise<S2>, taskC: Task<E3, S3> | Promise<S3>) => Task<E | E2 | E3, S4>; | ||
export declare const map4: <E, E2, E3, E4, S, S2, S3, S4, S5>(fn: (a: S) => (b: S2) => (c: S3) => (d: S4) => S5, taskA: Task<E, S> | Promise<S>, taskB: Task<E2, S2> | Promise<S2>, taskC: Task<E3, S3> | Promise<S3>, taskD: Task<E4, S4> | Promise<S4>) => Task<E | E2 | E3 | E4, S5>; | ||
/** | ||
@@ -281,3 +197,3 @@ * Run a side-effect on success. Useful for logging. | ||
*/ | ||
export declare function tap<E, S>(fn: (result: S) => void, task: Task<E, S>): Task<E, S>; | ||
export declare const tap: <E, S>(fn: (result: S) => void, task: Task<E, S>) => Task<E, S>; | ||
/** | ||
@@ -289,3 +205,3 @@ * Run an additional task on success. Useful for async side-effects. | ||
*/ | ||
export declare function tapChain<E, S, S2>(fn: (result: S) => Task<E, S2> | Promise<S2>, task: Task<E, S>): Task<E, S>; | ||
export declare const tapChain: <E, S, S2>(fn: (result: S) => Task<E, S2> | Promise<S2>, task: Task<E, S>) => Task<E, S>; | ||
/** | ||
@@ -298,3 +214,4 @@ * Given a task, map the failure error to a Task. | ||
*/ | ||
export declare function mapError<E, S, E2>(fn: (error: E) => E2, task: Task<E, S>): Task<E2, S>; | ||
export declare const mapError: <E, S, E2>(fn: (error: E) => E2, task: Task<E, S>) => Task<E2, S>; | ||
export declare const errorUnion: <E, S, E2>(task: Task<E, S>) => Task<E | E2, S>; | ||
/** | ||
@@ -306,3 +223,3 @@ * Given a task, map both the failure error and the success result to a Task. | ||
*/ | ||
export declare function mapBoth<E, S, E2, S2>(handleError: (error: E) => E2, handleSuccess: (success: S) => S2, task: Task<E, S>): Task<E2, S2>; | ||
export declare const mapBoth: <E, S, E2, S2>(handleError: (error: E) => E2, handleSuccess: (success: S) => S2, task: Task<E, S>) => Task<E2, S2>; | ||
/** | ||
@@ -314,3 +231,3 @@ * Given a task, map both the failure error and the success result to a Task which always succeeds. | ||
*/ | ||
export declare function fold<E, S, R>(handleError: (error: E) => R, handleSuccess: (success: S) => R, task: Task<E, S>): Task<unknown, R>; | ||
export declare const fold: <E, S, R>(handleError: (error: E) => R, handleSuccess: (success: S) => R, task: Task<E, S>) => Task<unknown, R>; | ||
/** | ||
@@ -321,3 +238,3 @@ * Given a task, if the result in a failure, attemp to generate another Task from the error. | ||
*/ | ||
export declare function orElse<E, S>(fn: (error: E) => Task<E, S> | Promise<S>, task: Task<E, S>): Task<E, S>; | ||
export declare const orElse: <E, S>(fn: (error: E) => Task<E, S> | Promise<S>, task: Task<E, S>) => Task<E, S>; | ||
/** | ||
@@ -329,3 +246,3 @@ * Given a task that succeeds with a map function as its result, | ||
*/ | ||
export declare function ap<E, S, S2>(taskOrPromise: Task<E, (result: S) => S2> | Promise<(result: S) => S2>, appliedTaskOrPromise: Task<E, S> | Promise<S>): Task<E, S2>; | ||
export declare const ap: <E, S, S2>(taskOrPromise: Task<E, (result: S) => S2> | Promise<(result: S) => S2>, appliedTaskOrPromise: Task<E, S> | Promise<S>) => Task<E, S2>; | ||
/** | ||
@@ -336,3 +253,3 @@ * Wait some number of seconds to continue after a successful task. | ||
*/ | ||
export declare function wait<E, S>(ms: number, task: Task<E, S>): Task<E, S>; | ||
export declare const wait: <E, S>(ms: number, task: Task<E, S>) => Task<E, S>; | ||
/** | ||
@@ -343,3 +260,3 @@ * If a task fails, retry it in the future. | ||
*/ | ||
export declare function retryIn<E, S>(ms: number, task: Task<E, S>): Task<E, S>; | ||
export declare const retryIn: <E, S>(ms: number, task: Task<E, S>) => Task<E, S>; | ||
/** | ||
@@ -351,3 +268,3 @@ * If a task fails, retry it X times, with exponential backoff. | ||
*/ | ||
export declare function retryWithExponentialBackoff<E, S>(ms: number, times: number, task: Task<E, S>): Task<E, S>; | ||
export declare const retryWithExponentialBackoff: <E, S>(ms: number, times: number, task: Task<E, S>) => Task<E, S>; | ||
/** | ||
@@ -358,3 +275,88 @@ * Takes a nested task of tasks, which often comes from a map, and | ||
*/ | ||
export declare function flatten<E, S>(task: Task<E, Task<E, S>>): Task<E, S>; | ||
export declare const flatten: <E, S>(task: Task<E, Task<E, S>>) => Task<E, S>; | ||
/** | ||
* Create a new task. | ||
* @param computation A function which will be run when the task starts. | ||
*/ | ||
export declare class Task<E, S> implements PromiseLike<S> { | ||
private computation; | ||
static fail: <E_1, S_1 = any>(error: E_1) => Task<E_1, S_1>; | ||
static succeed: <S_1, E_1 = any>(result: S_1) => Task<E_1, S_1>; | ||
static empty: <E_1 = any>() => Task<E_1, void>; | ||
static failIn: <E_1, S_1 = any>(ms: number, error: E_1) => Task<E_1, S_1>; | ||
static succeedIn: <S_1, E_1 = any>(ms: number, result: S_1) => Task<E_1, S_1>; | ||
static of: <S_1, E_1 = any>(result: S_1) => Task<E_1, S_1>; | ||
static all: <E_1, S_1>(tasksOrPromises: (Task<E_1, S_1> | Promise<S_1>)[]) => Task<E_1, S_1[]>; | ||
static sequence: <E_1, S_1>(tasksOrPromises: (Task<E_1, S_1> | Promise<S_1>)[]) => Task<E_1, S_1[]>; | ||
static firstSuccess: <E_1, S_1>(tasksOrPromises: (Task<E_1, S_1> | Promise<S_1>)[]) => Task<E_1[], S_1>; | ||
static never: () => Task<never, never>; | ||
static fromPromise: <S_1, E_1 = any>(maybePromise: S_1 | Promise<S_1>) => Task<E_1, S_1>; | ||
static fromLazyPromise: <S_1, E_1 = any>(getPromise: () => S_1 | Promise<S_1>) => Task<E_1, S_1>; | ||
static race: <E_1, S_1>(tasksOrPromises: (Task<E_1, S_1> | Promise<S_1>)[]) => Task<E_1, S_1>; | ||
static external: <E_1, S_1>() => ExternalTask<E_1, S_1>; | ||
static emitter: <Args extends any[], R>(fn: (...args: Args) => R) => [ExternalTask<any, R>, (...args: Args) => void]; | ||
static succeedBy: <S_1, E_1 = any>(result: () => S_1) => Task<E_1, S_1>; | ||
static ap: <E_1, S_1, S2>(taskOrPromise: Task<E_1, (result: S_1) => S2> | Promise<(result: S_1) => S2>, appliedTaskOrPromise: Task<E_1, S_1> | Promise<S_1>) => Task<E_1, S2>; | ||
static map2: <E_1, E2, S_1, S2, S3>(fn: (a: S_1) => (b: S2) => S3, taskA: Task<E_1, S_1> | Promise<S_1>, taskB: Task<E2, S2> | Promise<S2>) => Task<E_1 | E2, S3>; | ||
static map3: <E_1, E2, E3, S_1, S2, S3, S4>(fn: (a: S_1) => (b: S2) => (c: S3) => S4, taskA: Task<E_1, S_1> | Promise<S_1>, taskB: Task<E2, S2> | Promise<S2>, taskC: Task<E3, S3> | Promise<S3>) => Task<E_1 | E2 | E3, S4>; | ||
static map4: <E_1, E2, E3, E4, S_1, S2, S3, S4, S5>(fn: (a: S_1) => (b: S2) => (c: S3) => (d: S4) => S5, taskA: Task<E_1, S_1> | Promise<S_1>, taskB: Task<E2, S2> | Promise<S2>, taskC: Task<E3, S3> | Promise<S3>, taskD: Task<E4, S4> | Promise<S4>) => Task<E_1 | E2 | E3 | E4, S5>; | ||
static loop: <E_1, S_1, T>(fn: (currentValue: T) => Task<E_1, LoopBreak<S_1> | LoopContinue<T>>, initialValue: T) => Task<E_1, S_1>; | ||
static reduce: <E_1, T, V>(fn: (acc: V, currentValue: T, index: number, original: T[]) => Task<E_1, V>, initialValue: V, items: T[]) => Task<E_1, V>; | ||
static zip: <E_1, E2, S_1, S2>(taskAOrPromise: Task<E_1, S_1> | Promise<S_1>, taskBOrPromise: Task<E2, S2> | Promise<S2>) => Task<E_1 | E2, [S_1, S2]>; | ||
static zipWith: <E_1, E2, S_1, S2, V>(fn: (resultA: S_1, resultB: S2) => V, taskAOrPromise: Task<E_1, S_1> | Promise<S_1>, taskBOrPromise: Task<E2, S2> | Promise<S2>) => Task<E_1 | E2, V>; | ||
static flatten: <E_1, S_1>(task: Task<E_1, Task<E_1, S_1>>) => Task<E_1, S_1>; | ||
isCanceled: boolean; | ||
constructor(computation: Fork<E, S>); | ||
fork(reject: Reject<E>, resolve: Resolve<S>): { | ||
cancel: () => void; | ||
}; | ||
cancel(): void; | ||
/** | ||
* Alias to match promise API and let async/await work. | ||
* Mostly "private". Do not use. | ||
*/ | ||
then<TResult1 = S, TResult2 = never>(onfulfilled?: ((value: S) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>; | ||
chain<S2>(fn: (result: S) => Task<E, S2> | Promise<S2>): Task<E, S2>; | ||
succeedIf(fn: () => S | undefined): Task<E, S>; | ||
onlyOnce(): Task<E, S>; | ||
toPromise(): Promise<S>; | ||
swap<E2 extends E, S2 extends S>(): Task<S2, E2>; | ||
map<S2>(fn: (result: S) => S2): Task<E, S2>; | ||
forward<S2>(value: S2): Task<E, S2>; | ||
append<A, B, C, D, E>(a: A, b: B, c: C, d: D, e: E): Task<E, [S, A, B, C, D, E]>; | ||
append<A, B, C, D>(a: A, b: B, c: C, d: D): Task<E, [S, A, B, C, D]>; | ||
append<A, B, C>(a: A, b: B, c: C): Task<E, [S, A, B, C]>; | ||
append<A, B>(a: A, b: B): Task<E, [S, A, B]>; | ||
append<A>(a: A): Task<E, [S, A]>; | ||
prepend<A, B, C, D, E>(a: A, b: B, c: C, d: D, e: E): Task<E, [S, A, B, C, D, E]>; | ||
prepend<A, B, C, D>(a: A, b: B, c: C, d: D): Task<E, [A, B, C, D, S]>; | ||
prepend<A, B, C>(a: A, b: B, c: C): Task<E, [A, B, C, S]>; | ||
prepend<A, B>(a: A, b: B): Task<E, [A, B, S]>; | ||
prepend<A>(a: A): Task<E, [A, S]>; | ||
tap(fn: (result: S) => void): Task<E, S>; | ||
tapChain<S2>(fn: (result: S) => Task<E, S2> | Promise<S2>): Task<E, S>; | ||
mapError<E2>(fn: (error: E) => E2): Task<E2, S>; | ||
errorUnion<E2>(): Task<E | E2, S>; | ||
mapBoth<E2, S2>(handleError: (error: E) => E2, handleSuccess: (success: S) => S2): Task<E2, S2>; | ||
fold<R>(handleError: (error: E) => R, handleSuccess: (success: S) => R): Task<unknown, R>; | ||
orElse<S2>(fn: (error: E) => Task<E, S | S2> | Promise<S | S2>): Task<E, S | S2>; | ||
ap<E2, S2, S3 = S extends (arg: S2) => any ? ReturnType<S> : never>(taskOrPromise: Task<E | E2, S2> | Promise<S2>): Task<E | E2, S3>; | ||
wait(ms: number): Task<E, S>; | ||
retryIn(ms: number): Task<E, S>; | ||
retryWithExponentialBackoff(ms: number, times: number): Task<E, S>; | ||
flatten<S2>(this: Task<E, Task<E, S2>>): Task<E, S2>; | ||
} | ||
/** | ||
* A special form of Task which can be resolved/rejected externally. | ||
*/ | ||
export declare class ExternalTask<E, S> extends Task<E, S> { | ||
private computationReject_?; | ||
private computationResolve_?; | ||
private alreadyError_?; | ||
private alreadyResult_?; | ||
private lastState_; | ||
constructor(); | ||
reject(error: E): void; | ||
resolve(result: S): void; | ||
} | ||
//# sourceMappingURL=Task.d.ts.map |
@@ -1,14 +0,14 @@ | ||
export declare function range(end: number, start?: number): number[]; | ||
export declare function to<A, T>(fn: (items: A[]) => T): (sum: any, _item: A, index: number, all: A[]) => T; | ||
export declare function constant<T>(value: T): () => T; | ||
export declare function identity<T>(x: T): T; | ||
export declare function toIndexedObject<T, V, R extends { | ||
export declare const range: (end: number, start?: number) => number[]; | ||
export declare const to: <A, T>(fn: (items: A[]) => T) => (sum: any, _item: A, index: number, all: A[]) => T; | ||
export declare const constant: <T>(value: T) => () => T; | ||
export declare const identity: <T>(x: T) => T; | ||
export declare const toIndexedObject: <T, V, R extends { | ||
[key: string]: V; | ||
}>(fn: (item: T, index: number) => [string, V]): (sum: R, item: T, index: number) => R; | ||
export declare function mapToIndexedObject<T, V, R extends { | ||
}>(fn: (item: T, index: number) => [string, V]) => (sum: R, item: T, index: number) => R; | ||
export declare const mapToIndexedObject: <T, V, R extends { | ||
[key: string]: V; | ||
}>(fn: (item: T, index: number) => [string, V], items: T[], initial?: R): R; | ||
export declare function pairsToIndexedObject<V, R extends { | ||
}>(fn: (item: T, index: number) => [string, V], items: T[], initial?: R) => R; | ||
export declare const pairsToIndexedObject: <V, R extends { | ||
[key: string]: V; | ||
}>(sum: R, [key, value]: [string, V]): R; | ||
}>(sum: R, [key, value]: [string, V]) => R; | ||
//# sourceMappingURL=util.d.ts.map |
@@ -1,14 +0,14 @@ | ||
function initialize() { | ||
return { type: "Initialized" }; | ||
} | ||
function pending() { | ||
return { type: "Pending" }; | ||
} | ||
function succeed(result) { | ||
return { type: "Success", result }; | ||
} | ||
function fail(error) { | ||
return { type: "Failure", error }; | ||
} | ||
function fold(onInitialized, onPending, onFailure, onSuccess, remote) { | ||
const initialize = () => ({ | ||
type: "Initialized" | ||
}); | ||
const pending = () => ({ type: "Pending" }); | ||
const succeed = (result) => ({ | ||
type: "Success", | ||
result | ||
}); | ||
const fail = (error) => ({ | ||
type: "Failure", | ||
error | ||
}); | ||
const fold = (onInitialized, onPending, onFailure, onSuccess, remote) => { | ||
switch (remote.type) { | ||
@@ -24,3 +24,3 @@ case "Initialized": | ||
} | ||
} | ||
}; | ||
@@ -36,203 +36,33 @@ var RemoteData = /*#__PURE__*/Object.freeze({ | ||
function range(end, start = 0) { | ||
return Array(end - start) | ||
.fill(undefined) | ||
.map((_, i) => start + i); | ||
} | ||
function to(fn) { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
return (sum, _item, index, all) => { | ||
const isLast = index === all.length - 1; | ||
if (!isLast) { | ||
return sum; | ||
} | ||
return fn(all); | ||
}; | ||
} | ||
function constant(value) { | ||
return () => value; | ||
} | ||
function identity(x) { | ||
return x; | ||
} | ||
function toIndexedObject(fn) { | ||
return (sum, item, index) => { | ||
const [key, value] = fn(item, index); | ||
sum[key] = value; | ||
const range = (end, start = 0) => Array(end - start) | ||
.fill(undefined) | ||
.map((_, i) => start + i); | ||
const to = (fn) => | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
(sum, _item, index, all) => { | ||
const isLast = index === all.length - 1; | ||
if (!isLast) { | ||
return sum; | ||
}; | ||
} | ||
function mapToIndexedObject(fn, items, initial = {}) { | ||
return items.reduce(toIndexedObject(fn), initial); | ||
} | ||
function pairsToIndexedObject(sum, [key, value]) { | ||
} | ||
return fn(all); | ||
}; | ||
const constant = (value) => () => value; | ||
const identity = (x) => x; | ||
const toIndexedObject = (fn) => (sum, item, index) => { | ||
const [key, value] = fn(item, index); | ||
sum[key] = value; | ||
return sum; | ||
} | ||
}; | ||
const mapToIndexedObject = (fn, items, initial = {}) => items.reduce(toIndexedObject(fn), initial); | ||
const pairsToIndexedObject = (sum, [key, value]) => { | ||
sum[key] = value; | ||
return sum; | ||
}; | ||
/* eslint-disable @typescript-eslint/no-misused-promises, @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-explicit-any, @typescript-eslint/no-use-before-define */ | ||
/** | ||
* Create a new task. | ||
* @param computation A function which will be run when the task starts. | ||
*/ | ||
class Task { | ||
constructor(computation) { | ||
this.computation = computation; | ||
this.isCanceled = false; | ||
} | ||
fork(reject, resolve) { | ||
let localCancel = this.isCanceled; | ||
const result = { | ||
cancel: () => (localCancel = true) | ||
}; | ||
if (localCancel) { | ||
return result; | ||
} | ||
this.computation(err => { | ||
if (!localCancel) { | ||
reject(err); | ||
} | ||
}, value => { | ||
if (!localCancel) { | ||
resolve(value); | ||
} | ||
}); | ||
return result; | ||
} | ||
cancel() { | ||
this.isCanceled = true; | ||
} | ||
/** | ||
* Alias to match promise API and let async/await work. | ||
* Mostly "private". Do not use. | ||
*/ | ||
then(onfulfilled, onrejected) { | ||
return this.toPromise().then(onfulfilled, onrejected); | ||
} | ||
chain(fn) { | ||
return chain(fn, this); | ||
} | ||
succeedIf(fn) { | ||
return succeedIf(fn, this); | ||
} | ||
onlyOnce() { | ||
return onlyOnce(this); | ||
} | ||
toPromise() { | ||
return toPromise(this); | ||
} | ||
swap() { | ||
return swap(this); | ||
} | ||
map(fn) { | ||
return map(fn, this); | ||
} | ||
forward(value) { | ||
return map(constant(value), this); | ||
} | ||
append(...items) { | ||
return map(a => [a, ...items], this); | ||
} | ||
prepend(...items) { | ||
return map(a => [...items, a], this); | ||
} | ||
tap(fn) { | ||
return tap(fn, this); | ||
} | ||
tapChain(fn) { | ||
return tapChain(fn, this); | ||
} | ||
mapError(fn) { | ||
return mapError(fn, this); | ||
} | ||
mapBoth(handleError, handleSuccess) { | ||
return mapBoth(handleError, handleSuccess, this); | ||
} | ||
fold(handleError, handleSuccess) { | ||
return fold$1(handleError, handleSuccess, this); | ||
} | ||
orElse(fn) { | ||
return orElse(fn, this); | ||
} | ||
ap(taskOrPromise) { | ||
return ap(this, taskOrPromise); | ||
} | ||
wait(ms) { | ||
return wait(ms, this); | ||
} | ||
retryIn(ms) { | ||
return retryIn(ms, this); | ||
} | ||
retryWithExponentialBackoff(ms, times) { | ||
return retryWithExponentialBackoff(ms, times, this); | ||
} | ||
flatten() { | ||
return flatten(this); | ||
} | ||
} | ||
Task.fail = fail$1; | ||
Task.succeed = succeed$1; | ||
Task.empty = empty; | ||
Task.failIn = failIn; | ||
Task.succeedIn = succeedIn; | ||
Task.of = succeed$1; | ||
Task.all = all; | ||
Task.sequence = sequence; | ||
Task.firstSuccess = firstSuccess; | ||
Task.never = never; | ||
Task.fromPromise = fromPromise; | ||
Task.fromLazyPromise = fromLazyPromise; | ||
Task.race = race; | ||
Task.external = external; | ||
Task.emitter = emitter; | ||
Task.succeedBy = succeedBy; | ||
Task.ap = ap; | ||
Task.map2 = map2; | ||
Task.map3 = map3; | ||
Task.map4 = map4; | ||
Task.loop = loop; | ||
Task.reduce = reduce; | ||
Task.zip = zip; | ||
Task.zipWith = zipWith; | ||
Task.flatten = flatten; | ||
/** | ||
* A special form of Task which can be resolved/rejected externally. | ||
*/ | ||
class ExternalTask extends Task { | ||
constructor() { | ||
super((reject, resolve) => { | ||
switch (this.lastState_) { | ||
case "error": | ||
reject(this.alreadyError_); | ||
case "success": | ||
resolve(this.alreadyResult_); | ||
case "pending": | ||
this.computationReject_ = reject; | ||
this.computationResolve_ = resolve; | ||
} | ||
}); | ||
this.lastState_ = "pending"; | ||
} | ||
reject(error) { | ||
this.alreadyError_ = error; | ||
this.lastState_ = "error"; | ||
if (this.computationReject_) { | ||
this.computationReject_(error); | ||
} | ||
} | ||
resolve(result) { | ||
this.alreadyResult_ = result; | ||
this.lastState_ = "success"; | ||
if (this.computationResolve_) { | ||
this.computationResolve_(result); | ||
} | ||
} | ||
} | ||
/** | ||
* Creates a Task which can be resolved/rejected externally. | ||
*/ | ||
function external() { | ||
return new ExternalTask(); | ||
} | ||
function emitter(fn) { | ||
const external = () => new ExternalTask(); | ||
const emitter = (fn) => { | ||
const task = external(); | ||
@@ -250,3 +80,3 @@ return [ | ||
]; | ||
} | ||
}; | ||
/** | ||
@@ -258,5 +88,3 @@ * Creates a Task which has already successfully completed with `result`. | ||
*/ | ||
function succeed$1(result) { | ||
return new Task((_, resolve) => resolve(result)); | ||
} | ||
const succeed$1 = (result) => new Task((_, resolve) => resolve(result)); | ||
const of = succeed$1; | ||
@@ -267,12 +95,10 @@ /** | ||
*/ | ||
function succeedBy(result) { | ||
return new Task((reject, resolve) => { | ||
try { | ||
resolve(result()); | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
} | ||
const succeedBy = (result) => new Task((reject, resolve) => { | ||
try { | ||
resolve(result()); | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
/** | ||
@@ -282,5 +108,3 @@ * Creates a Task has an empty result. | ||
*/ | ||
function empty() { | ||
return of(void 0); | ||
} | ||
const empty = () => of(void 0); | ||
/** | ||
@@ -291,5 +115,3 @@ * Creates a Task which automatically succeeds at some time in the future with `result`. | ||
*/ | ||
function succeedIn(ms, result) { | ||
return new Task((_, resolve) => setTimeout(() => resolve(result), ms)); | ||
} | ||
const succeedIn = (ms, result) => new Task((_, resolve) => setTimeout(() => resolve(result), ms)); | ||
/** | ||
@@ -300,5 +122,3 @@ * Creates a Task which has already failed with `error`. | ||
*/ | ||
function fail$1(error) { | ||
return new Task(reject => reject(error)); | ||
} | ||
const fail$1 = (error) => new Task(reject => reject(error)); | ||
/** | ||
@@ -309,11 +129,7 @@ * Creates a Task which automatically fails at some time in the future with `error`. | ||
*/ | ||
function failIn(ms, error) { | ||
return new Task(reject => setTimeout(() => reject(error), ms)); | ||
} | ||
const failIn = (ms, error) => new Task(reject => setTimeout(() => reject(error), ms)); | ||
/** | ||
* Creates a Task will never finish. | ||
*/ | ||
function never() { | ||
return new Task(() => void 0); | ||
} | ||
const never = () => new Task(() => void 0); | ||
/** | ||
@@ -324,5 +140,3 @@ * Chain a task to run after a previous task has succeeded. | ||
*/ | ||
function chain(fn, task) { | ||
return new Task((reject, resolve) => task.fork(reject, b => autoPromiseToTask(fn(b)).fork(reject, resolve))); | ||
} | ||
const chain = (fn, task) => new Task((reject, resolve) => task.fork(reject, b => autoPromiseToTask(fn(b)).fork(reject, resolve))); | ||
/** | ||
@@ -333,8 +147,3 @@ * If a function returns a Promise instead of a Task, automatically | ||
*/ | ||
function autoPromiseToTask(promiseOrTask) { | ||
if (promiseOrTask instanceof Promise) { | ||
return fromPromise(promiseOrTask); | ||
} | ||
return promiseOrTask; | ||
} | ||
const autoPromiseToTask = (promiseOrTask) => promiseOrTask instanceof Promise ? fromPromise(promiseOrTask) : promiseOrTask; | ||
/** | ||
@@ -345,12 +154,10 @@ * When forked, run a function which can check whether the task has already succeeded. | ||
*/ | ||
function succeedIf(fn, task) { | ||
return new Task((reject, resolve) => { | ||
const result = fn(); | ||
if (result) { | ||
resolve(result); | ||
return; | ||
} | ||
task.fork(reject, resolve); | ||
}); | ||
} | ||
const succeedIf = (fn, task) => new Task((reject, resolve) => { | ||
const result = fn(); | ||
if (result) { | ||
resolve(result); | ||
return; | ||
} | ||
task.fork(reject, resolve); | ||
}); | ||
/** | ||
@@ -361,3 +168,3 @@ * A task which only runs once. Caches the success or failure. Be careful. | ||
*/ | ||
function onlyOnce(task) { | ||
const onlyOnce = (task) => { | ||
let state = "initialized"; | ||
@@ -368,7 +175,7 @@ let cachedResult; | ||
const callbacks = {}; | ||
function notify(reject, resolve) { | ||
const notify = (reject, resolve) => { | ||
const id = callbackId++; | ||
callbacks[id] = { reject, resolve }; | ||
} | ||
function triggerReject(error) { | ||
}; | ||
const triggerReject = (error) => { | ||
state = "failure"; | ||
@@ -380,4 +187,4 @@ cachedError = error; | ||
}); | ||
} | ||
function triggerResolve(result) { | ||
}; | ||
const triggerResolve = (result) => { | ||
state = "success"; | ||
@@ -389,3 +196,3 @@ cachedResult = result; | ||
}); | ||
} | ||
}; | ||
return new Task((reject, resolve) => { | ||
@@ -408,3 +215,3 @@ switch (state) { | ||
}); | ||
} | ||
}; | ||
/** | ||
@@ -414,9 +221,6 @@ * Given a promise, create a Task which relies on it. | ||
*/ | ||
function fromPromise(maybePromise) { | ||
if (maybePromise instanceof Promise) { | ||
// eslint-disable-next-line @typescript-eslint/no-misused-promises | ||
return new Task((reject, resolve) => maybePromise.then(resolve, reject)); | ||
} | ||
return of(maybePromise); | ||
} | ||
const fromPromise = (maybePromise) => maybePromise instanceof Promise | ||
? // eslint-disable-next-line @typescript-eslint/no-misused-promises | ||
new Task((reject, resolve) => maybePromise.then(resolve, reject)) | ||
: of(maybePromise); | ||
/** | ||
@@ -426,5 +230,3 @@ * Take a function which generates a promise and lazily execute it. | ||
*/ | ||
function fromLazyPromise(getPromise) { | ||
return succeedBy(getPromise).chain(fromPromise); | ||
} | ||
const fromLazyPromise = (getPromise) => succeedBy(getPromise).chain(fromPromise); | ||
/** | ||
@@ -434,5 +236,3 @@ * Given a task, create a Promise which resolves when the task does. | ||
*/ | ||
function toPromise(task) { | ||
return new Promise((resolve, reject) => task.fork(reject, resolve)); | ||
} | ||
const toPromise = (task) => new Promise((resolve, reject) => task.fork(reject, resolve)); | ||
/** | ||
@@ -443,20 +243,18 @@ * Given an array of tasks, return the one which finishes first. | ||
*/ | ||
function race(tasksOrPromises) { | ||
return new Task((reject, resolve) => { | ||
let done = false; | ||
return tasksOrPromises.map(taskOrPromise => autoPromiseToTask(taskOrPromise).fork((error) => { | ||
if (done) { | ||
return; | ||
} | ||
done = true; | ||
reject(error); | ||
}, (result) => { | ||
if (done) { | ||
return; | ||
} | ||
done = true; | ||
resolve(result); | ||
})); | ||
}); | ||
} | ||
const race = (tasksOrPromises) => new Task((reject, resolve) => { | ||
let done = false; | ||
return tasksOrPromises.map(taskOrPromise => autoPromiseToTask(taskOrPromise).fork((error) => { | ||
if (done) { | ||
return; | ||
} | ||
done = true; | ||
reject(error); | ||
}, (result) => { | ||
if (done) { | ||
return; | ||
} | ||
done = true; | ||
resolve(result); | ||
})); | ||
}); | ||
class LoopBreak { | ||
@@ -478,19 +276,17 @@ constructor(value) { | ||
*/ | ||
function loop(fn, initialValue) { | ||
return new Task((reject, resolve) => { | ||
const tryLoop = (currentValue) => { | ||
fn(currentValue).fork(err => { | ||
reject(err); | ||
}, result => { | ||
if (result instanceof LoopBreak) { | ||
resolve(result.value); | ||
} | ||
if (result instanceof LoopContinue) { | ||
tryLoop(result.value); | ||
} | ||
}); | ||
}; | ||
tryLoop(initialValue); | ||
}); | ||
} | ||
const loop = (fn, initialValue) => new Task((reject, resolve) => { | ||
const tryLoop = (currentValue) => { | ||
fn(currentValue).fork(err => { | ||
reject(err); | ||
}, result => { | ||
if (result instanceof LoopBreak) { | ||
resolve(result.value); | ||
} | ||
if (result instanceof LoopContinue) { | ||
tryLoop(result.value); | ||
} | ||
}); | ||
}; | ||
tryLoop(initialValue); | ||
}); | ||
/** | ||
@@ -504,12 +300,10 @@ * An async reducer. Given an initial return value and an array of | ||
*/ | ||
function reduce(fn, initialValue, items) { | ||
return loop(({ remainingItems, currentResult }) => { | ||
if (remainingItems.length === 0) { | ||
return of(new LoopBreak(currentResult)); | ||
} | ||
const [head, ...tail] = remainingItems; | ||
const index = items.length - tail.length - 1; | ||
return fn(currentResult, head, index, items).map(nextResult => new LoopContinue({ remainingItems: tail, currentResult: nextResult })); | ||
}, { remainingItems: items, currentResult: initialValue }); | ||
} | ||
const reduce = (fn, initialValue, items) => loop(({ remainingItems, currentResult }) => { | ||
if (remainingItems.length === 0) { | ||
return of(new LoopBreak(currentResult)); | ||
} | ||
const [head, ...tail] = remainingItems; | ||
const index = items.length - tail.length - 1; | ||
return fn(currentResult, head, index, items).map(nextResult => new LoopContinue({ remainingItems: tail, currentResult: nextResult })); | ||
}, { remainingItems: items, currentResult: initialValue }); | ||
/** | ||
@@ -519,7 +313,5 @@ * Given an array of tasks, return the one which finishes successfully first. | ||
*/ | ||
function firstSuccess(tasksOrPromises) { | ||
if (tasksOrPromises.length === 0) { | ||
return fail$1([]); | ||
} | ||
return new Task((reject, resolve) => { | ||
const firstSuccess = (tasksOrPromises) => tasksOrPromises.length === 0 | ||
? fail$1([]) | ||
: new Task((reject, resolve) => { | ||
let isDone = false; | ||
@@ -545,3 +337,2 @@ let runningTasks = tasksOrPromises.length; | ||
}); | ||
} | ||
/** | ||
@@ -552,7 +343,5 @@ * Given an array of task which return a result, return a new task which results an array of results. | ||
*/ | ||
function all(tasksOrPromises) { | ||
if (tasksOrPromises.length === 0) { | ||
return of([]); | ||
} | ||
return new Task((reject, resolve) => { | ||
const all = (tasksOrPromises) => tasksOrPromises.length === 0 | ||
? of([]) | ||
: new Task((reject, resolve) => { | ||
let isDone = false; | ||
@@ -578,3 +367,2 @@ let runningTasks = tasksOrPromises.length; | ||
}); | ||
} | ||
/** | ||
@@ -586,5 +374,3 @@ * Creates a task that waits for two tasks of different types to | ||
*/ | ||
function zip(taskAOrPromise, taskBOrPromise) { | ||
return map2(a => b => [a, b], taskAOrPromise, taskBOrPromise); | ||
} | ||
const zip = (taskAOrPromise, taskBOrPromise) => map2(a => b => [a, b], taskAOrPromise, taskBOrPromise); | ||
/** | ||
@@ -598,5 +384,3 @@ * Creates a task that waits for two tasks of different types to | ||
*/ | ||
function zipWith(fn, taskAOrPromise, taskBOrPromise) { | ||
return map2(a => b => fn(a, b), taskAOrPromise, taskBOrPromise); | ||
} | ||
const zipWith = (fn, taskAOrPromise, taskBOrPromise) => map2(a => b => fn(a, b), taskAOrPromise, taskBOrPromise); | ||
/** | ||
@@ -606,7 +390,5 @@ * Given an array of task which return a result, return a new task which results an array of results. | ||
*/ | ||
function sequence(tasksOrPromises) { | ||
if (tasksOrPromises.length === 0) { | ||
return of([]); | ||
} | ||
return tasksOrPromises.reduce((sum, taskOrPromise) => { | ||
const sequence = (tasksOrPromises) => tasksOrPromises.length === 0 | ||
? of([]) | ||
: tasksOrPromises.reduce((sum, taskOrPromise) => { | ||
return chain(list => { | ||
@@ -616,3 +398,2 @@ return map(result => [...list, result], autoPromiseToTask(taskOrPromise)); | ||
}, succeed$1([])); | ||
} | ||
/** | ||
@@ -622,5 +403,3 @@ * Given a task, swap the error and success values. | ||
*/ | ||
function swap(task) { | ||
return new Task((reject, resolve) => task.fork(e => resolve(e), s => reject(s))); | ||
} | ||
const swap = (task) => new Task((reject, resolve) => task.fork(e => resolve(e), s => reject(s))); | ||
/** | ||
@@ -631,23 +410,15 @@ * Given a task, map the successful value to a Task. | ||
*/ | ||
function map(fn, task) { | ||
return new Task((reject, resolve) => task.fork(reject, result => resolve(fn(result)))); | ||
} | ||
function map2(fn, taskA, taskB) { | ||
return Task.of(fn) | ||
.ap(taskA) | ||
.ap(taskB); | ||
} | ||
function map3(fn, taskA, taskB, taskC) { | ||
return Task.of(fn) | ||
.ap(taskA) | ||
.ap(taskB) | ||
.ap(taskC); | ||
} | ||
function map4(fn, taskA, taskB, taskC, taskD) { | ||
return Task.of(fn) | ||
.ap(taskA) | ||
.ap(taskB) | ||
.ap(taskC) | ||
.ap(taskD); | ||
} | ||
const map = (fn, task) => new Task((reject, resolve) => task.fork(reject, result => resolve(fn(result)))); | ||
const map2 = (fn, taskA, taskB) => Task.of(fn) | ||
.ap(taskA) | ||
.ap(taskB); | ||
const map3 = (fn, taskA, taskB, taskC) => Task.of(fn) | ||
.ap(taskA) | ||
.ap(taskB) | ||
.ap(taskC); | ||
const map4 = (fn, taskA, taskB, taskC, taskD) => Task.of(fn) | ||
.ap(taskA) | ||
.ap(taskB) | ||
.ap(taskC) | ||
.ap(taskD); | ||
/** | ||
@@ -658,8 +429,6 @@ * Run a side-effect on success. Useful for logging. | ||
*/ | ||
function tap(fn, task) { | ||
return map(result => { | ||
fn(result); | ||
return result; | ||
}, task); | ||
} | ||
const tap = (fn, task) => map(result => { | ||
fn(result); | ||
return result; | ||
}, task); | ||
/** | ||
@@ -671,5 +440,3 @@ * Run an additional task on success. Useful for async side-effects. | ||
*/ | ||
function tapChain(fn, task) { | ||
return chain(result => autoPromiseToTask(fn(result)).forward(result), task); | ||
} | ||
const tapChain = (fn, task) => chain(result => autoPromiseToTask(fn(result)).forward(result), task); | ||
/** | ||
@@ -682,5 +449,4 @@ * Given a task, map the failure error to a Task. | ||
*/ | ||
function mapError(fn, task) { | ||
return new Task((reject, resolve) => task.fork(error => reject(fn(error)), resolve)); | ||
} | ||
const mapError = (fn, task) => new Task((reject, resolve) => task.fork(error => reject(fn(error)), resolve)); | ||
const errorUnion = (task) => task; | ||
/** | ||
@@ -692,5 +458,3 @@ * Given a task, map both the failure error and the success result to a Task. | ||
*/ | ||
function mapBoth(handleError, handleSuccess, task) { | ||
return mapError(handleError, map(handleSuccess, task)); | ||
} | ||
const mapBoth = (handleError, handleSuccess, task) => mapError(handleError, map(handleSuccess, task)); | ||
/** | ||
@@ -702,5 +466,3 @@ * Given a task, map both the failure error and the success result to a Task which always succeeds. | ||
*/ | ||
function fold$1(handleError, handleSuccess, task) { | ||
return new Task((_, resolve) => task.fork(error => resolve(handleError(error)), result => resolve(handleSuccess(result)))); | ||
} | ||
const fold$1 = (handleError, handleSuccess, task) => new Task((_, resolve) => task.fork(error => resolve(handleError(error)), result => resolve(handleSuccess(result)))); | ||
/** | ||
@@ -711,5 +473,3 @@ * Given a task, if the result in a failure, attemp to generate another Task from the error. | ||
*/ | ||
function orElse(fn, task) { | ||
return new Task((reject, resolve) => task.fork(error => autoPromiseToTask(fn(error)).fork(reject, resolve), resolve)); | ||
} | ||
const orElse = (fn, task) => new Task((reject, resolve) => task.fork(error => autoPromiseToTask(fn(error)).fork(reject, resolve), resolve)); | ||
/** | ||
@@ -721,35 +481,33 @@ * Given a task that succeeds with a map function as its result, | ||
*/ | ||
function ap(taskOrPromise, appliedTaskOrPromise) { | ||
return new Task((reject, resolve) => { | ||
let targetResult; | ||
let applierFunction; | ||
let hasResultLoaded = false; | ||
let isRejected = false; | ||
const handleResolve = (onResolve) => { | ||
return (x) => { | ||
if (isRejected) { | ||
return; | ||
} | ||
onResolve(x); | ||
if (applierFunction && hasResultLoaded) { | ||
resolve(applierFunction(targetResult)); | ||
} | ||
}; | ||
}; | ||
const handleReject = (x) => { | ||
const ap = (taskOrPromise, appliedTaskOrPromise) => new Task((reject, resolve) => { | ||
let targetResult; | ||
let applierFunction; | ||
let hasResultLoaded = false; | ||
let isRejected = false; | ||
const handleResolve = (onResolve) => { | ||
return (x) => { | ||
if (isRejected) { | ||
return; | ||
} | ||
isRejected = true; | ||
reject(x); | ||
onResolve(x); | ||
if (applierFunction && hasResultLoaded) { | ||
resolve(applierFunction(targetResult)); | ||
} | ||
}; | ||
autoPromiseToTask(taskOrPromise).fork(handleReject, handleResolve((x) => { | ||
applierFunction = x; | ||
})); | ||
autoPromiseToTask(appliedTaskOrPromise).fork(handleReject, handleResolve((x) => { | ||
hasResultLoaded = true; | ||
targetResult = x; | ||
})); | ||
}); | ||
} | ||
}; | ||
const handleReject = (x) => { | ||
if (isRejected) { | ||
return; | ||
} | ||
isRejected = true; | ||
reject(x); | ||
}; | ||
autoPromiseToTask(taskOrPromise).fork(handleReject, handleResolve((x) => { | ||
applierFunction = x; | ||
})); | ||
autoPromiseToTask(appliedTaskOrPromise).fork(handleReject, handleResolve((x) => { | ||
hasResultLoaded = true; | ||
targetResult = x; | ||
})); | ||
}); | ||
/** | ||
@@ -760,7 +518,5 @@ * Wait some number of seconds to continue after a successful task. | ||
*/ | ||
function wait(ms, task) { | ||
return new Task((reject, resolve) => { | ||
setTimeout(() => task.fork(reject, resolve), ms); | ||
}); | ||
} | ||
const wait = (ms, task) => new Task((reject, resolve) => { | ||
setTimeout(() => task.fork(reject, resolve), ms); | ||
}); | ||
/** | ||
@@ -771,5 +527,3 @@ * If a task fails, retry it in the future. | ||
*/ | ||
function retryIn(ms, task) { | ||
return task.orElse(() => task.wait(ms)); | ||
} | ||
const retryIn = (ms, task) => task.orElse(() => task.wait(ms)); | ||
/** | ||
@@ -781,5 +535,3 @@ * If a task fails, retry it X times, with exponential backoff. | ||
*/ | ||
function retryWithExponentialBackoff(ms, times, task) { | ||
return range(times).reduce((sum, i) => sum.retryIn(ms * 2 ** i), task); | ||
} | ||
const retryWithExponentialBackoff = (ms, times, task) => range(times).reduce((sum, i) => sum.retryIn(ms * 2 ** i), task); | ||
/** | ||
@@ -790,5 +542,163 @@ * Takes a nested task of tasks, which often comes from a map, and | ||
*/ | ||
function flatten(task) { | ||
return task.chain(identity); | ||
const flatten = (task) => task.chain(identity); | ||
/** | ||
* Create a new task. | ||
* @param computation A function which will be run when the task starts. | ||
*/ | ||
class Task { | ||
constructor(computation) { | ||
this.computation = computation; | ||
this.isCanceled = false; | ||
} | ||
fork(reject, resolve) { | ||
let localCancel = this.isCanceled; | ||
const result = { | ||
cancel: () => (localCancel = true) | ||
}; | ||
if (localCancel) { | ||
return result; | ||
} | ||
this.computation(err => { | ||
if (!localCancel) { | ||
reject(err); | ||
} | ||
}, value => { | ||
if (!localCancel) { | ||
resolve(value); | ||
} | ||
}); | ||
return result; | ||
} | ||
cancel() { | ||
this.isCanceled = true; | ||
} | ||
/** | ||
* Alias to match promise API and let async/await work. | ||
* Mostly "private". Do not use. | ||
*/ | ||
then(onfulfilled, onrejected) { | ||
return this.toPromise().then(onfulfilled, onrejected); | ||
} | ||
chain(fn) { | ||
return chain(fn, this); | ||
} | ||
succeedIf(fn) { | ||
return succeedIf(fn, this); | ||
} | ||
onlyOnce() { | ||
return onlyOnce(this); | ||
} | ||
toPromise() { | ||
return toPromise(this); | ||
} | ||
swap() { | ||
return swap(this); | ||
} | ||
map(fn) { | ||
return map(fn, this); | ||
} | ||
forward(value) { | ||
return map(constant(value), this); | ||
} | ||
append(...items) { | ||
return map(a => [a, ...items], this); | ||
} | ||
prepend(...items) { | ||
return map(a => [...items, a], this); | ||
} | ||
tap(fn) { | ||
return tap(fn, this); | ||
} | ||
tapChain(fn) { | ||
return tapChain(fn, this); | ||
} | ||
mapError(fn) { | ||
return mapError(fn, this); | ||
} | ||
errorUnion() { | ||
return errorUnion(this); | ||
} | ||
mapBoth(handleError, handleSuccess) { | ||
return mapBoth(handleError, handleSuccess, this); | ||
} | ||
fold(handleError, handleSuccess) { | ||
return fold$1(handleError, handleSuccess, this); | ||
} | ||
orElse(fn) { | ||
return orElse(fn, this); | ||
} | ||
ap(taskOrPromise) { | ||
return ap(this, taskOrPromise); | ||
} | ||
wait(ms) { | ||
return wait(ms, this); | ||
} | ||
retryIn(ms) { | ||
return retryIn(ms, this); | ||
} | ||
retryWithExponentialBackoff(ms, times) { | ||
return retryWithExponentialBackoff(ms, times, this); | ||
} | ||
flatten() { | ||
return flatten(this); | ||
} | ||
} | ||
Task.fail = fail$1; | ||
Task.succeed = succeed$1; | ||
Task.empty = empty; | ||
Task.failIn = failIn; | ||
Task.succeedIn = succeedIn; | ||
Task.of = succeed$1; | ||
Task.all = all; | ||
Task.sequence = sequence; | ||
Task.firstSuccess = firstSuccess; | ||
Task.never = never; | ||
Task.fromPromise = fromPromise; | ||
Task.fromLazyPromise = fromLazyPromise; | ||
Task.race = race; | ||
Task.external = external; | ||
Task.emitter = emitter; | ||
Task.succeedBy = succeedBy; | ||
Task.ap = ap; | ||
Task.map2 = map2; | ||
Task.map3 = map3; | ||
Task.map4 = map4; | ||
Task.loop = loop; | ||
Task.reduce = reduce; | ||
Task.zip = zip; | ||
Task.zipWith = zipWith; | ||
Task.flatten = flatten; | ||
/** | ||
* A special form of Task which can be resolved/rejected externally. | ||
*/ | ||
class ExternalTask extends Task { | ||
constructor() { | ||
super((reject, resolve) => { | ||
switch (this.lastState_) { | ||
case "error": | ||
reject(this.alreadyError_); | ||
case "success": | ||
resolve(this.alreadyResult_); | ||
case "pending": | ||
this.computationReject_ = reject; | ||
this.computationResolve_ = resolve; | ||
} | ||
}); | ||
this.lastState_ = "pending"; | ||
} | ||
reject(error) { | ||
this.alreadyError_ = error; | ||
this.lastState_ = "error"; | ||
if (this.computationReject_) { | ||
this.computationReject_(error); | ||
} | ||
} | ||
resolve(result) { | ||
this.alreadyResult_ = result; | ||
this.lastState_ = "success"; | ||
if (this.computationResolve_) { | ||
this.computationResolve_(result); | ||
} | ||
} | ||
} | ||
@@ -795,0 +705,0 @@ class Subscription { |
@@ -1,1 +0,1 @@ | ||
var t=Object.freeze({__proto__:null,initialize:function(){return{type:"Initialized"}},pending:function(){return{type:"Pending"}},succeed:function(t){return{type:"Success",result:t}},fail:function(t){return{type:"Failure",error:t}},fold:function(t,n,r,e,i){switch(i.type){case"Initialized":return t();case"Pending":return n();case"Failure":return r(i.error);case"Success":return e(i.result)}}});function n(t,n=0){return Array(t-n).fill(void 0).map((t,r)=>n+r)}function r(t){return(n,r,e,i)=>e===i.length-1?t(i):n}function e(t){return()=>t}function i(t){return t}function u(t){return(n,r,e)=>{const[i,u]=t(r,e);return n[i]=u,n}}function s(t,n,r={}){return n.reduce(u(t),r)}function c(t,[n,r]){return t[n]=r,t}class o{constructor(t){this.computation=t,this.isCanceled=!1}fork(t,n){let r=this.isCanceled;const e={cancel:()=>r=!0};return r||this.computation(n=>{r||t(n)},t=>{r||n(t)}),e}cancel(){this.isCanceled=!0}then(t,n){return this.toPromise().then(t,n)}chain(t){return d(t,this)}succeedIf(t){return function(t,n){return new o((r,e)=>{const i=t();i?e(i):n.fork(r,e)})}(t,this)}onlyOnce(){return function(t){let n,r,e="initialized",i=0;const u={};function s(t,n){const r=i++;u[r]={reject:t,resolve:n}}function c(t){e="failure",r=t,Object.keys(u).forEach(n=>{u[n].reject(t),delete u[n]})}function h(t){e="success",n=t,Object.keys(u).forEach(n=>{u[n].resolve(t),delete u[n]})}return new o((i,u)=>{switch(e){case"success":u(n);break;case"failure":i(r);break;case"pending":s(i,u);break;case"initialized":e="pending",s(i,u),t.fork(c,h)}})}(this)}toPromise(){return t=this,new Promise((n,r)=>t.fork(r,n));var t}swap(){return t=this,new o((n,r)=>t.fork(t=>r(t),t=>n(t)));var t}map(t){return I(t,this)}forward(t){return I(e(t),this)}append(...t){return I(n=>[n,...t],this)}prepend(...t){return I(n=>[...t,n],this)}tap(t){return function(t,n){return I(n=>(t(n),n),n)}(t,this)}tapChain(t){return function(t,n){return d(n=>m(t(n)).forward(n),n)}(t,this)}mapError(t){return P(t,this)}mapBoth(t,n){return function(t,n,r){return P(t,I(n,r))}(t,n,this)}fold(t,n){return function(t,n,r){return new o((e,i)=>r.fork(n=>i(t(n)),t=>i(n(t))))}(t,n,this)}orElse(t){return function(t,n){return new o((r,e)=>n.fork(n=>m(t(n)).fork(r,e),e))}(t,this)}ap(t){return S(this,t)}wait(t){return function(t,n){return new o((r,e)=>{setTimeout(()=>n.fork(r,e),t)})}(t,this)}retryIn(t){return function(t,n){return n.orElse(()=>n.wait(t))}(t,this)}retryWithExponentialBackoff(t,r){return function(t,r,e){return n(r).reduce((n,r)=>n.retryIn(t*2**r),e)}(t,r,this)}flatten(){return j(this)}}o.fail=p,o.succeed=a,o.empty=function(){return l(void 0)},o.failIn=function(t,n){return new o(r=>setTimeout(()=>r(n),t))},o.succeedIn=function(t,n){return new o((r,e)=>setTimeout(()=>e(n),t))},o.of=a,o.all=function(t){return 0===t.length?l([]):new o((n,r)=>{let e=!1,i=t.length;const u=[];return t.map((t,s)=>m(t).fork(t=>{e||(e=!0,n(t))},t=>{e||(i-=1,u[s]=t,0===i&&r(u))}))})},o.sequence=function(t){return 0===t.length?l([]):t.reduce((t,n)=>d(t=>I(n=>[...t,n],m(n)),t),a([]))},o.firstSuccess=function(t){return 0===t.length?p([]):new o((n,r)=>{let e=!1,i=t.length;const u=[];return t.map(t=>m(t).fork(t=>{e||(i-=1,u.push(t),0===i&&n(u))},t=>{e||(e=!0,r(t))}))})},o.never=function(){return new o(()=>{})},o.fromPromise=y,o.fromLazyPromise=function(t){return w(t).chain(y)},o.race=function(t){return new o((n,r)=>{let e=!1;return t.map(t=>m(t).fork(t=>{e||(e=!0,n(t))},t=>{e||(e=!0,r(t))}))})},o.external=f,o.emitter=function(t){const n=f();return[n,(...r)=>{try{n.resolve(t(...r))}catch(t){n.reject(t)}}]},o.succeedBy=w,o.ap=S,o.map2=k,o.map3=function(t,n,r,e){return o.of(t).ap(n).ap(r).ap(e)},o.map4=function(t,n,r,e,i){return o.of(t).ap(n).ap(r).ap(e).ap(i)},o.loop=b,o.reduce=function(t,n,r){return b(({remainingItems:n,currentResult:e})=>{if(0===n.length)return l(new g(e));const[i,...u]=n,s=r.length-u.length-1;return t(e,i,s,r).map(t=>new v({remainingItems:u,currentResult:t}))},{remainingItems:r,currentResult:n})},o.zip=function(t,n){return k(t=>n=>[t,n],t,n)},o.zipWith=function(t,n,r){return k(n=>r=>t(n,r),n,r)},o.flatten=j;class h extends o{constructor(){super((t,n)=>{switch(this.t){case"error":t(this.i);case"success":n(this.u);case"pending":this.s=t,this.o=n}}),this.t="pending"}reject(t){this.i=t,this.t="error",this.s&&this.s(t)}resolve(t){this.u=t,this.t="success",this.o&&this.o(t)}}function f(){return new h}function a(t){return new o((n,r)=>r(t))}const l=a;function w(t){return new o((n,r)=>{try{r(t())}catch(t){n(t)}})}function p(t){return new o(n=>n(t))}function d(t,n){return new o((r,e)=>n.fork(r,n=>m(t(n)).fork(r,e)))}function m(t){return t instanceof Promise?y(t):t}function y(t){return t instanceof Promise?new o((n,r)=>t.then(r,n)):l(t)}class g{constructor(t){this.value=t}}class v{constructor(t){this.value=t}}function b(t,n){return new o((r,e)=>{const i=n=>{t(n).fork(t=>{r(t)},t=>{t instanceof g&&e(t.value),t instanceof v&&i(t.value)})};i(n)})}function I(t,n){return new o((r,e)=>n.fork(r,n=>e(t(n))))}function k(t,n,r){return o.of(t).ap(n).ap(r)}function P(t,n){return new o((r,e)=>n.fork(n=>r(t(n)),e))}function S(t,n){return new o((r,e)=>{let i,u,s=!1,c=!1;const o=t=>n=>{c||(t(n),u&&s&&e(u(i)))},h=t=>{c||(c=!0,r(t))};m(t).fork(h,o(t=>{u=t})),m(n).fork(h,o(t=>{s=!0,i=t}))})}function j(t){return t.chain(i)}class z{constructor(){this.h=new Set,this.l="inactive",this.p=new Set}emit(t){return o.all(Array.from(this.h).map(n=>n(t)||o.empty()))}subscribe(t){return this.h.add(t),this.m(),()=>{this.h.delete(t),this.m()}}clear(){this.h.clear(),this.m()}onStatusChange(t){return this.p.add(t),()=>this.p.delete(t)}m(){const t=this.h.size>0?"active":"inactive";t!==this.l&&(this.l=t,Array.from(this.p).map(n=>n(t)))}}export{h as ExternalTask,g as LoopBreak,v as LoopContinue,t as RemoteData,z as Subscription,o as Task,e as constant,i as identity,s as mapToIndexedObject,c as pairsToIndexedObject,n as range,r as to,u as toIndexedObject}; | ||
var t=Object.freeze({__proto__:null,initialize:()=>({type:"Initialized"}),pending:()=>({type:"Pending"}),succeed:t=>({type:"Success",result:t}),fail:t=>({type:"Failure",error:t}),fold:(t,e,r,s,n)=>{switch(n.type){case"Initialized":return t();case"Pending":return e();case"Failure":return r(n.error);case"Success":return s(n.result)}}});const e=(t,e=0)=>Array(t-e).fill(void 0).map((t,r)=>e+r),r=t=>(e,r,s,n)=>s===n.length-1?t(n):e,s=t=>()=>t,n=t=>t,i=t=>(e,r,s)=>{const[n,i]=t(r,s);return e[n]=i,e},c=(t,e,r={})=>e.reduce(i(t),r),h=(t,[e,r])=>(t[e]=r,t),u=()=>new j,a=t=>new S((e,r)=>r(t)),o=a,l=t=>new S((e,r)=>{try{r(t())}catch(t){e(t)}}),w=t=>new S(e=>e(t)),p=(t,e)=>new S((r,s)=>e.fork(r,e=>d(t(e)).fork(r,s))),d=t=>t instanceof Promise?m(t):t,m=t=>t instanceof Promise?new S((e,r)=>t.then(r,e)):o(t);class f{constructor(t){this.value=t}}class y{constructor(t){this.value=t}}const g=(t,e)=>new S((r,s)=>{const n=e=>{t(e).fork(t=>{r(t)},t=>{t instanceof f&&s(t.value),t instanceof y&&n(t.value)})};n(e)}),v=(t,e)=>new S((r,s)=>e.fork(r,e=>s(t(e)))),b=(t,e,r)=>S.of(t).ap(e).ap(r),I=(t,e)=>new S((r,s)=>e.fork(e=>r(t(e)),s)),k=(t,e)=>new S((r,s)=>{let n,i,c=!1,h=!1;const u=t=>e=>{h||(t(e),i&&c&&s(i(n)))},a=t=>{h||(h=!0,r(t))};d(t).fork(a,u(t=>{i=t})),d(e).fork(a,u(t=>{c=!0,n=t}))}),P=t=>t.chain(n);class S{constructor(t){this.computation=t,this.isCanceled=!1}fork(t,e){let r=this.isCanceled;const s={cancel:()=>r=!0};return r||this.computation(e=>{r||t(e)},t=>{r||e(t)}),s}cancel(){this.isCanceled=!0}then(t,e){return this.toPromise().then(t,e)}chain(t){return p(t,this)}succeedIf(t){return((t,e)=>new S((r,s)=>{const n=t();n?s(n):e.fork(r,s)}))(t,this)}onlyOnce(){return(t=>{let e,r,s="initialized",n=0;const i={},c=(t,e)=>{const r=n++;i[r]={reject:t,resolve:e}},h=t=>{s="failure",r=t,Object.keys(i).forEach(e=>{i[e].reject(t),delete i[e]})},u=t=>{s="success",e=t,Object.keys(i).forEach(e=>{i[e].resolve(t),delete i[e]})};return new S((n,i)=>{switch(s){case"success":i(e);break;case"failure":n(r);break;case"pending":c(n,i);break;case"initialized":s="pending",c(n,i),t.fork(h,u)}})})(this)}toPromise(){return t=this,new Promise((e,r)=>t.fork(r,e));var t}swap(){return t=this,new S((e,r)=>t.fork(t=>r(t),t=>e(t)));var t}map(t){return v(t,this)}forward(t){return v(s(t),this)}append(...t){return v(e=>[e,...t],this)}prepend(...t){return v(e=>[...t,e],this)}tap(t){return((t,e)=>v(e=>(t(e),e),this))(t)}tapChain(t){return((t,e)=>p(e=>d(t(e)).forward(e),this))(t)}mapError(t){return I(t,this)}errorUnion(){return this}mapBoth(t,e){return((t,e,r)=>I(t,v(e,this)))(t,e)}fold(t,e){return((t,e,r)=>new S((s,n)=>r.fork(e=>n(t(e)),t=>n(e(t)))))(t,e,this)}orElse(t){return((t,e)=>new S((r,s)=>e.fork(e=>d(t(e)).fork(r,s),s)))(t,this)}ap(t){return k(this,t)}wait(t){return((t,e)=>new S((r,s)=>{setTimeout(()=>e.fork(r,s),t)}))(t,this)}retryIn(t){return((t,e)=>e.orElse(()=>e.wait(t)))(t,this)}retryWithExponentialBackoff(t,r){return((t,r,s)=>e(r).reduce((e,r)=>e.retryIn(t*2**r),s))(t,r,this)}flatten(){return P(this)}}S.fail=w,S.succeed=a,S.empty=()=>o(void 0),S.failIn=(t,e)=>new S(r=>setTimeout(()=>r(e),t)),S.succeedIn=(t,e)=>new S((r,s)=>setTimeout(()=>s(e),t)),S.of=a,S.all=t=>0===t.length?o([]):new S((e,r)=>{let s=!1,n=t.length;const i=[];return t.map((t,c)=>d(t).fork(t=>{s||(s=!0,e(t))},t=>{s||(n-=1,i[c]=t,0===n&&r(i))}))}),S.sequence=t=>0===t.length?o([]):t.reduce((t,e)=>p(t=>v(e=>[...t,e],d(e)),t),a([])),S.firstSuccess=t=>0===t.length?w([]):new S((e,r)=>{let s=!1,n=t.length;const i=[];return t.map(t=>d(t).fork(t=>{s||(n-=1,i.push(t),0===n&&e(i))},t=>{s||(s=!0,r(t))}))}),S.never=()=>new S(()=>{}),S.fromPromise=m,S.fromLazyPromise=t=>l(t).chain(m),S.race=t=>new S((e,r)=>{let s=!1;return t.map(t=>d(t).fork(t=>{s||(s=!0,e(t))},t=>{s||(s=!0,r(t))}))}),S.external=u,S.emitter=t=>{const e=u();return[e,(...r)=>{try{e.resolve(t(...r))}catch(t){e.reject(t)}}]},S.succeedBy=l,S.ap=k,S.map2=b,S.map3=(t,e,r,s)=>S.of(t).ap(e).ap(r).ap(s),S.map4=(t,e,r,s,n)=>S.of(t).ap(e).ap(r).ap(s).ap(n),S.loop=g,S.reduce=(t,e,r)=>g(({remainingItems:e,currentResult:s})=>{if(0===e.length)return o(new f(s));const[n,...i]=e,c=r.length-i.length-1;return t(s,n,c,r).map(t=>new y({remainingItems:i,currentResult:t}))},{remainingItems:r,currentResult:e}),S.zip=(t,e)=>b(t=>e=>[t,e],t,e),S.zipWith=(t,e,r)=>b(e=>r=>t(e,r),e,r),S.flatten=P;class j extends S{constructor(){super((t,e)=>{switch(this.t){case"error":t(this.s);case"success":e(this.i);case"pending":this.h=t,this.u=e}}),this.t="pending"}reject(t){this.s=t,this.t="error",this.h&&this.h(t)}resolve(t){this.i=t,this.t="success",this.u&&this.u(t)}}class z{constructor(){this.o=new Set,this.l="inactive",this.p=new Set}emit(t){return S.all(Array.from(this.o).map(e=>e(t)||S.empty()))}subscribe(t){return this.o.add(t),this.m(),()=>{this.o.delete(t),this.m()}}clear(){this.o.clear(),this.m()}onStatusChange(t){return this.p.add(t),()=>this.p.delete(t)}m(){const t=this.o.size>0?"active":"inactive";t!==this.l&&(this.l=t,Array.from(this.p).map(e=>e(t)))}}export{j as ExternalTask,f as LoopBreak,y as LoopContinue,t as RemoteData,z as Subscription,S as Task,s as constant,n as identity,c as mapToIndexedObject,h as pairsToIndexedObject,e as range,r as to,i as toIndexedObject}; |
{ | ||
"name": "@tdreyno/pretty-please", | ||
"version": "1.7.0", | ||
"version": "1.8.0", | ||
"files": [ | ||
@@ -27,6 +27,6 @@ "dist-*/", | ||
"@types/jest": "^25.1.3", | ||
"@types/puppeteer": "^2.0.0", | ||
"@types/puppeteer": "^2.0.1", | ||
"@types/react": "^16.9.23", | ||
"@typescript-eslint/eslint-plugin": "^2.21.0", | ||
"@typescript-eslint/parser": "^2.21.0", | ||
"@typescript-eslint/eslint-plugin": "^2.22.0", | ||
"@typescript-eslint/parser": "^2.22.0", | ||
"commitizen": "^4.0.3", | ||
@@ -44,6 +44,6 @@ "cz-conventional-changelog": "3.1.0", | ||
"semantic-release": "^17.0.4", | ||
"terser": "^4.6.4", | ||
"terser": "^4.6.6", | ||
"ts-jest": "^25.2.1", | ||
"ts-toolbelt": "^6.3.1", | ||
"typescript": "^3.8.2" | ||
"ts-toolbelt": "^6.3.5", | ||
"typescript": "^3.8.3" | ||
}, | ||
@@ -50,0 +50,0 @@ "publishConfig": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
294570
4378