@tdreyno/pretty-please
Advanced tools
Comparing version 1.0.0-beta.3 to 1.0.0-beta.4
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
var axios = _interopDefault(require('axios')); | ||
Object.prototype.andThen = function (fn) { | ||
return fn(this); | ||
}; | ||
function range(end, start = 0) { | ||
return Array(end - start).fill(undefined).map((_, i) => start + i); | ||
} | ||
function to(fn) { | ||
return (sum, _item, index, all) => { | ||
const isLast = index === all.length - 1; | ||
if (!isLast) { | ||
return sum; | ||
} | ||
return fn(all); | ||
}; | ||
} | ||
/** | ||
* Create a new task. | ||
* @param computation A function which will be run when the task starts. | ||
*/ | ||
class Task { | ||
constructor(computation) { | ||
this.fork = computation; | ||
} | ||
andThen(fn) { | ||
return andThen(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); | ||
} | ||
tap(fn) { | ||
return tap(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(task) { | ||
return ap(this, task); | ||
} | ||
wait(ms) { | ||
return wait(ms, this); | ||
} | ||
retryIn(ms) { | ||
return retryIn(ms, this); | ||
} | ||
retryWithExponentialBackoff(ms, times) { | ||
return retryWithExponentialBackoff(ms, times, this); | ||
} | ||
} | ||
Task.fail = fail; | ||
Task.succeed = succeed; | ||
Task.failIn = failIn; | ||
Task.succeedIn = succeedIn; | ||
Task.of = succeed; | ||
Task.all = all; | ||
Task.sequence = sequence; | ||
Task.firstSuccess = firstSuccess; | ||
Task.never = never; | ||
Task.fromPromise = fromPromise; | ||
/** | ||
* Creates a Task which has already successfully completed with `result`. | ||
* @alias of | ||
* @param result The value to place into the successful Task. | ||
*/ | ||
function succeed(result) { | ||
return new Task((_, resolve) => resolve(result)); | ||
} | ||
const of = succeed; | ||
/** | ||
* Creates a Task which automatically succeeds at some time in the future with `result`. | ||
* @param ms How many milliseconds until it succeeds. | ||
* @param result The value to place into the successful Task. | ||
*/ | ||
function succeedIn(ms, result) { | ||
return new Task((_, resolve) => setTimeout(() => resolve(result), ms)); | ||
} | ||
/** | ||
* Creates a Task which has already failed with `error`. | ||
* @param error The error to place into the failed Task. | ||
*/ | ||
function fail(error) { | ||
return new Task((reject, _) => reject(error)); | ||
} | ||
/** | ||
* Creates a Task which automatically fails at some time in the future with `error`. | ||
* @param ms How many milliseconds until it succeeds. | ||
* @param error The error to place into the failed Task. | ||
*/ | ||
function failIn(ms, error) { | ||
return new Task((reject, _) => setTimeout(() => reject(error), ms)); | ||
} | ||
/** | ||
* Creates a Task will never finish. | ||
*/ | ||
function never() { | ||
return new Task(() => void 0); | ||
} | ||
/** | ||
* Chain a task to run after a previous task has succeeded. | ||
* @alias chain | ||
* @param fn Takes a successful result and returns a new task. | ||
* @param task The task which will chain to the next one on success. | ||
*/ | ||
function andThen(fn, task) { | ||
return new Task((reject, resolve) => task.fork(reject, b => fn(b).fork(reject, resolve))); | ||
} | ||
/** | ||
* When forked, run a function which can check whether the task has already succeeded. | ||
* @param fn The function which either returns a success value or undefined. | ||
* @param task The task to run if the check fails (returns undefined). | ||
*/ | ||
function succeedIf(fn, task) { | ||
return new Task((reject, resolve) => { | ||
const result = fn(); | ||
if (result) { | ||
resolve(result); | ||
return; | ||
} | ||
task.fork(reject, resolve); | ||
}); | ||
} | ||
/** | ||
* A task which only runs once. Caches the success or failure. Be careful. | ||
* @alias share | ||
* @param task The task to cache results. | ||
*/ | ||
function onlyOnce(task) { | ||
let state = "initialized"; | ||
let cachedResult; | ||
let cachedError; | ||
let callbackId = 0; | ||
const callbacks = {}; | ||
function notify(reject, resolve) { | ||
const id = callbackId++; | ||
callbacks[id] = { | ||
reject, | ||
resolve | ||
}; | ||
} | ||
function triggerReject(error) { | ||
state = "failure"; | ||
cachedError = error; | ||
Object.keys(callbacks).forEach(id => { | ||
callbacks[id].reject(error); | ||
delete callbacks[id]; | ||
}); | ||
} | ||
function triggerResolve(result) { | ||
state = "success"; | ||
cachedResult = result; | ||
Object.keys(callbacks).forEach(id => { | ||
callbacks[id].resolve(result); | ||
delete callbacks[id]; | ||
}); | ||
} | ||
return new Task((reject, resolve) => { | ||
switch (state) { | ||
case "success": | ||
resolve(cachedResult); | ||
break; | ||
case "failure": | ||
reject(cachedError); | ||
break; | ||
case "pending": | ||
notify(reject, resolve); | ||
break; | ||
case "initialized": | ||
state = "pending"; | ||
notify(reject, resolve); | ||
task.fork(triggerReject, triggerResolve); | ||
} | ||
}); | ||
} | ||
/** | ||
* Given a promise, create a Task which relies on it. | ||
* @param promise The promise we will gather the success from. | ||
*/ | ||
function fromPromise(promise) { | ||
return new Task((reject, resolve) => promise.then(resolve, reject)); | ||
} | ||
/** | ||
* Given a task, create a Promise which resolves when the task does. | ||
* @param task The task we will convert to a promise. | ||
*/ | ||
function toPromise(task) { | ||
return new Promise((resolve, reject) => task.fork(reject, resolve)); | ||
} | ||
/** | ||
* Given an array of tasks, return the one which finishes successfully first. | ||
* @param tasks The tasks to run in parallel. | ||
*/ | ||
function firstSuccess(tasks) { | ||
return new Task((reject, resolve) => { | ||
let isDone = false; | ||
let runningTasks = tasks.length; | ||
const errors = []; | ||
return tasks.map(task => task.fork(error => { | ||
/* Should be impossible. */ | ||
/* istanbul ignore next */ | ||
if (isDone) { | ||
return; | ||
} | ||
runningTasks -= 1; | ||
errors.push(error); | ||
if (runningTasks === 0) { | ||
reject(errors); | ||
} | ||
}, result => { | ||
/* Should be impossible. */ | ||
/* istanbul ignore next */ | ||
if (isDone) { | ||
return; | ||
} | ||
isDone = true; | ||
resolve(result); | ||
})); | ||
}); | ||
} | ||
/** | ||
* Given an array of task which return a result, return a new task which results an array of results. | ||
* @param tasks The tasks to run in parallel. | ||
*/ | ||
function all(tasks) { | ||
return new Task((reject, resolve) => { | ||
let isDone = false; | ||
let runningTasks = tasks.length; | ||
const results = []; | ||
return tasks.map((task, i) => task.fork(error => { | ||
/* Should be impossible. */ | ||
/* istanbul ignore next */ | ||
if (isDone) { | ||
return; | ||
} | ||
isDone = true; | ||
reject(error); | ||
}, result => { | ||
/* Should be impossible. */ | ||
/* istanbul ignore next */ | ||
if (isDone) { | ||
return; | ||
} | ||
runningTasks -= 1; | ||
results[i] = result; | ||
if (runningTasks === 0) { | ||
resolve(results); | ||
} | ||
})); | ||
}); | ||
} | ||
/** | ||
* Given an array of task which return a result, return a new task which results an array of results. | ||
* @param tasks The tasks to run in sequence. | ||
*/ | ||
function sequence(tasks) { | ||
return tasks.reduce((sum, task) => { | ||
return andThen(list => { | ||
return map(result => [...list, result], task); | ||
}, sum); | ||
}, succeed([])); | ||
} | ||
/** | ||
* Given a task, swap the error and success values. | ||
* @param task The task to swap the results of. | ||
*/ | ||
function swap(task) { | ||
return new Task((reject, resolve) => task.fork(resolve, reject)); | ||
} | ||
/** | ||
* Given a task, map the successful value to a Task. | ||
* @param fn A function which takes the original successful result and returns the new one. | ||
* @param task The task to map the succcessful result. | ||
*/ | ||
function map(fn, task) { | ||
return new Task((reject, resolve) => task.fork(reject, result => resolve(fn(result)))); | ||
} | ||
/** | ||
* Run a side-effect on success. Useful for logging. | ||
* @param fn A function will fire with the successful value. | ||
* @param task The task to tap on succcess. | ||
*/ | ||
function tap(fn, task) { | ||
return map(result => { | ||
fn(result); | ||
return result; | ||
}, task); | ||
} | ||
/** | ||
* Given a task, map the failure error to a Task. | ||
* @param fn A function which takes the original failure error and returns the new one. | ||
* @param task The task to map the failure. | ||
*/ | ||
function mapError(fn, task) { | ||
return new Task((reject, resolve) => task.fork(error => reject(fn(error)), resolve)); | ||
} | ||
/** | ||
* Given a task, map both the failure error and the success result to a Task. | ||
* @param handleError A function which takes the original failure error and returns the new one. | ||
* @param handleSuccess A function which takes the original successful result and returns the new one. | ||
* @param task The task to map the failure and succeess of. | ||
*/ | ||
function mapBoth(handleError, handleSuccess, task) { | ||
return mapError(handleError, map(handleSuccess, task)); | ||
} | ||
/** | ||
* Given a task, map both the failure error and the success result to a Task which always succeeds. | ||
* @param handleError A function which takes the original failure error and returns a successful result. | ||
* @param handleSuccess A function which takes the original successful result and returns a new successful result. | ||
* @param task The task to map failure and succeess to a success for. | ||
*/ | ||
function fold(handleError, handleSuccess, task) { | ||
return new Task((_, resolve) => task.fork(error => resolve(handleError(error)), result => resolve(handleSuccess(result)))); | ||
} | ||
/** | ||
* Given a task, if the result in a failure, attemp to generate another Task from the error. | ||
* @param fn A function which takes the original failure error and returns a Task. | ||
* @param task The task to try to run a recovery function on failure. | ||
*/ | ||
function orElse(fn, task) { | ||
return new Task((reject, resolve) => task.fork(error => fn(error).fork(reject, resolve), resolve)); | ||
} | ||
/** | ||
* Given a task that succeeds with a map function as its result, | ||
* run that function over the result of a second successful Task. | ||
* @param appliedTask The task whose value will be passed to the map function. | ||
* @param task The task who will return a map function as the success result. | ||
*/ | ||
function ap(task, appliedTask) { | ||
return new Task((reject, resolve) => { | ||
let targetResult; | ||
let applierFunction; | ||
let hasResultLoaded = false; | ||
let isRejected = false; | ||
const handleResolve = onResolve => { | ||
return x => { | ||
/* Should be impossible. */ | ||
/* istanbul ignore next */ | ||
if (isRejected) { | ||
return; | ||
} | ||
onResolve(x); | ||
if (applierFunction && hasResultLoaded) { | ||
resolve(applierFunction(targetResult)); | ||
} | ||
}; | ||
}; | ||
const handleReject = x => { | ||
/* Should be impossible. */ | ||
/* istanbul ignore next */ | ||
if (isRejected) { | ||
return; | ||
} | ||
isRejected = true; | ||
reject(x); | ||
}; | ||
task.fork(handleReject, handleResolve(x => { | ||
applierFunction = x; | ||
})); | ||
appliedTask.fork(handleReject, handleResolve(x => { | ||
hasResultLoaded = true; | ||
targetResult = x; | ||
})); | ||
}); | ||
} | ||
/** | ||
* Wait some number of seconds to continue after a successful task. | ||
* @param ms How long to wait in milliseconds. | ||
* @param task Which task to wait to succeed with. | ||
*/ | ||
function wait(ms, task) { | ||
return new Task((reject, resolve) => { | ||
setTimeout(() => task.fork(reject, resolve), ms); | ||
}); | ||
} | ||
/** | ||
* If a task fails, retry it in the future. | ||
* @param ms How long to wait before trying. | ||
* @param task Which task to retry. | ||
*/ | ||
function retryIn(ms, task) { | ||
return task.orElse(() => task.wait(ms)); | ||
} | ||
/** | ||
* If a task fails, retry it X times, with exponential backoff. | ||
* @param ms How long to wait before trying the first time. | ||
* @param times How many times to attempt, each waiting 2x the previous time. | ||
* @param task Which task to retry. | ||
*/ | ||
function retryWithExponentialBackoff(ms, times, task) { | ||
return range(times).reduce((sum, i) => sum.retryIn(ms * 2 ** i), task); | ||
} | ||
function get(url, config) { | ||
return fromPromise(axios.get(url, config)); | ||
} | ||
/* istanbul ignore next */ | ||
function delete_(url, config) { | ||
return fromPromise(axios.delete(url, config)); | ||
} | ||
/* istanbul ignore next */ | ||
function head(url, config) { | ||
return fromPromise(axios.head(url, config)); | ||
} | ||
/* istanbul ignore next */ | ||
function post(url, data, config) { | ||
return fromPromise(axios.post(url, data, config)); | ||
} | ||
/* istanbul ignore next */ | ||
function put(url, data, config) { | ||
return fromPromise(axios.put(url, data, config)); | ||
} | ||
/* istanbul ignore next */ | ||
function patch(url, data, config) { | ||
return fromPromise(axios.patch(url, data, config)); | ||
} | ||
function toJSON(resp) { | ||
const type = resp.config ? resp.config.responseType : "text"; | ||
switch (type) { | ||
case "json": | ||
return succeed(resp.data); | ||
case "text": | ||
try { | ||
return succeed(JSON.parse(resp.data)); | ||
} catch (e) { | ||
return fail(e); | ||
} | ||
default: | ||
return fail(new Error("Invalid data")); | ||
} | ||
} | ||
var HTTP = /*#__PURE__*/Object.freeze({ | ||
__proto__: null, | ||
get: get, | ||
delete_: delete_, | ||
head: head, | ||
post: post, | ||
put: put, | ||
patch: patch, | ||
toJSON: toJSON | ||
}); | ||
function initialize() { | ||
return { | ||
type: "Initialized" | ||
}; | ||
} | ||
function pending() { | ||
return { | ||
type: "Pending" | ||
}; | ||
} | ||
function succeed$1(result) { | ||
return { | ||
type: "Success", | ||
result | ||
}; | ||
} | ||
function fail$1(error) { | ||
return { | ||
type: "Failure", | ||
error | ||
}; | ||
} | ||
function fold$1(onInitialized, onPending, onFailure, onSuccess, remote) { | ||
switch (remote.type) { | ||
case "Initialized": | ||
return onInitialized(); | ||
case "Pending": | ||
return onPending(); | ||
case "Failure": | ||
return onFailure(remote.error); | ||
case "Success": | ||
return onSuccess(remote.result); | ||
} | ||
} | ||
function fromTask(task) { | ||
return task.map(succeed$1).orElse(e => of(fail$1(e))); | ||
} | ||
var RemoteData = /*#__PURE__*/Object.freeze({ | ||
__proto__: null, | ||
initialize: initialize, | ||
pending: pending, | ||
succeed: succeed$1, | ||
fail: fail$1, | ||
fold: fold$1, | ||
fromTask: fromTask | ||
}); | ||
exports.HTTP = HTTP; | ||
exports.RemoteData = RemoteData; | ||
exports.Task = Task; | ||
exports.range = range; | ||
exports.to = to; | ||
//# sourceMappingURL=index.js.map |
import "../extend"; | ||
import { all, of } from "../Task"; | ||
import { all, of } from "../Task/Task"; | ||
describe("to", () => { | ||
@@ -4,0 +4,0 @@ test("should work with reduce to wrap a value", () => { |
@@ -1,2 +0,2 @@ | ||
import { all, of } from "../Task"; | ||
import { all, of } from "../Task/Task"; | ||
const editors = ["1", "2", "3"]; | ||
@@ -3,0 +3,0 @@ function loadUserName(id) { |
import mockAxios from "axios"; | ||
import { get, toJSON } from "../HTTP"; | ||
import { fromPromise, of } from "../Task"; | ||
import { get, toJSON } from "../HTTP/HTTP"; | ||
import { fromPromise, of } from "../Task/Task"; | ||
function slugify(..._args) { | ||
@@ -5,0 +5,0 @@ return "slug"; |
@@ -1,2 +0,2 @@ | ||
import { all, of } from "../Task"; | ||
import { all, of } from "../Task/Task"; | ||
import { range, to } from "../util"; | ||
@@ -3,0 +3,0 @@ describe("range", () => { |
import mockAxios from "axios"; | ||
import { all, fail, succeed } from "../../Task"; | ||
import { all, fail, succeed } from "../../Task/Task"; | ||
import { get, toJSON } from "../HTTP"; | ||
@@ -4,0 +4,0 @@ describe("HTTP", () => { |
import axios from "axios"; | ||
import { fail, fromPromise, succeed } from "../Task"; | ||
import { fail, fromPromise, succeed } from "../Task/Task"; | ||
export function get(url, config) { | ||
@@ -4,0 +4,0 @@ return fromPromise(axios.get(url, config)); |
@@ -1,2 +0,3 @@ | ||
export * from "./HTTP"; | ||
import * as HTTP from "./HTTP"; | ||
export default HTTP; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,7 @@ | ||
"use strict"; | ||
import "./extend"; | ||
import HTTP from "./HTTP/index"; | ||
import RemoteData from "./RemoteData/index"; | ||
import Task from "./Task/index"; | ||
export * from "./util"; | ||
export { HTTP, RemoteData, Task }; | ||
//# sourceMappingURL=index.js.map |
import { useCallback, useState } from "react"; | ||
import { fail, fold, initialize, pending, succeed } from "../RemoteData"; | ||
import { fold, initialize, pending, succeed } from "../RemoteData/RemoteData"; | ||
export function useRemoteData(task) { | ||
@@ -4,0 +4,0 @@ const [state, setState] = useState(initialize()); |
@@ -1,2 +0,2 @@ | ||
import { get } from "../../HTTP"; | ||
import { get } from "../../HTTP/HTTP"; | ||
import { fromTask, initialize } from "../RemoteData"; | ||
@@ -3,0 +3,0 @@ describe("Remote Data", () => { |
@@ -1,2 +0,3 @@ | ||
export * from "./RemoteData"; | ||
import * as RemoteData from "./RemoteData"; | ||
export default RemoteData; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
import { of } from "../Task"; | ||
import { of } from "../Task/Task"; | ||
export function initialize() { | ||
@@ -3,0 +3,0 @@ return { type: "Initialized" }; |
@@ -1,2 +0,3 @@ | ||
export * from "./Task"; | ||
import { Task } from "./Task"; | ||
export default Task; | ||
//# sourceMappingURL=index.js.map |
@@ -56,2 +56,12 @@ import { range } from "../util"; | ||
} | ||
Task.fail = fail; | ||
Task.succeed = succeed; | ||
Task.failIn = failIn; | ||
Task.succeedIn = succeedIn; | ||
Task.of = succeed; | ||
Task.all = all; | ||
Task.sequence = sequence; | ||
Task.firstSuccess = firstSuccess; | ||
Task.never = never; | ||
Task.fromPromise = fromPromise; | ||
/** | ||
@@ -58,0 +68,0 @@ * Creates a Task which has already successfully completed with `result`. |
@@ -1,2 +0,2 @@ | ||
import { Task } from "../Task"; | ||
import { Task } from "../Task/Task"; | ||
interface Request { | ||
@@ -3,0 +3,0 @@ } |
import { AxiosRequestConfig, AxiosResponse } from "axios"; | ||
import { Task } from "../Task"; | ||
import { Task } from "../Task/Task"; | ||
export declare function get<T = any>(url: string, config?: AxiosRequestConfig): Task<Error, AxiosResponse<T>>; | ||
@@ -4,0 +4,0 @@ export declare function delete_<T = any>(url: string, config?: AxiosRequestConfig): Task<Error, AxiosResponse<T>>; |
@@ -1,2 +0,3 @@ | ||
export * from "./HTTP"; | ||
import * as HTTP from "./HTTP"; | ||
export default HTTP; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -0,1 +1,7 @@ | ||
import "./extend"; | ||
import HTTP from "./HTTP/index"; | ||
import RemoteData from "./RemoteData/index"; | ||
import Task from "./Task/index"; | ||
export * from "./util"; | ||
export { HTTP, RemoteData, Task }; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,3 +0,3 @@ | ||
import { Task } from "../Task"; | ||
export declare function useRemoteData<E, S>(task: () => Task<E, S>): (import("../RemoteData").Initialized | import("../RemoteData").Pending | import("../RemoteData").Failure<E> | import("../RemoteData").Success<S> | ((onInitialized: () => unknown, onPending: () => unknown, onFailure: (error: E) => unknown, onSuccess: (result: S) => unknown) => unknown))[]; | ||
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> | ((onInitialized: () => unknown, onPending: () => unknown, onFailure: (error: E) => unknown, onSuccess: (result: S) => unknown) => unknown))[]; | ||
//# sourceMappingURL=useRemoteData.d.ts.map |
@@ -1,2 +0,3 @@ | ||
export * from "./RemoteData"; | ||
import * as RemoteData from "./RemoteData"; | ||
export default RemoteData; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,2 +0,2 @@ | ||
import { Task } from "../Task"; | ||
import { Task } from "../Task/Task"; | ||
export interface Initialized { | ||
@@ -3,0 +3,0 @@ type: "Initialized"; |
@@ -1,2 +0,3 @@ | ||
export * from "./Task"; | ||
import { Task } from "./Task"; | ||
export default Task; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -9,2 +9,12 @@ export declare type Reject<E> = (error: E) => void; | ||
export declare class Task<E, S> { | ||
static fail: typeof fail; | ||
static succeed: typeof succeed; | ||
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; | ||
fork: Fork<E, S>; | ||
@@ -11,0 +21,0 @@ constructor(computation: Fork<E, S>); |
@@ -0,2 +1,505 @@ | ||
import axios from 'axios'; | ||
Object.prototype.andThen = function (fn) { | ||
return fn(this); | ||
}; | ||
function range(end, start = 0) { | ||
return Array(end - start) | ||
.fill(undefined) | ||
.map((_, i) => start + i); | ||
} | ||
function to(fn) { | ||
return (sum, _item, index, all) => { | ||
const isLast = index === all.length - 1; | ||
if (!isLast) { | ||
return sum; | ||
} | ||
return fn(all); | ||
}; | ||
} | ||
/** | ||
* Create a new task. | ||
* @param computation A function which will be run when the task starts. | ||
*/ | ||
class Task { | ||
constructor(computation) { | ||
this.fork = computation; | ||
} | ||
andThen(fn) { | ||
return andThen(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); | ||
} | ||
tap(fn) { | ||
return tap(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(task) { | ||
return ap(this, task); | ||
} | ||
wait(ms) { | ||
return wait(ms, this); | ||
} | ||
retryIn(ms) { | ||
return retryIn(ms, this); | ||
} | ||
retryWithExponentialBackoff(ms, times) { | ||
return retryWithExponentialBackoff(ms, times, this); | ||
} | ||
} | ||
Task.fail = fail; | ||
Task.succeed = succeed; | ||
Task.failIn = failIn; | ||
Task.succeedIn = succeedIn; | ||
Task.of = succeed; | ||
Task.all = all; | ||
Task.sequence = sequence; | ||
Task.firstSuccess = firstSuccess; | ||
Task.never = never; | ||
Task.fromPromise = fromPromise; | ||
/** | ||
* Creates a Task which has already successfully completed with `result`. | ||
* @alias of | ||
* @param result The value to place into the successful Task. | ||
*/ | ||
function succeed(result) { | ||
return new Task((_, resolve) => resolve(result)); | ||
} | ||
const of = succeed; | ||
/** | ||
* Creates a Task which automatically succeeds at some time in the future with `result`. | ||
* @param ms How many milliseconds until it succeeds. | ||
* @param result The value to place into the successful Task. | ||
*/ | ||
function succeedIn(ms, result) { | ||
return new Task((_, resolve) => setTimeout(() => resolve(result), ms)); | ||
} | ||
/** | ||
* Creates a Task which has already failed with `error`. | ||
* @param error The error to place into the failed Task. | ||
*/ | ||
function fail(error) { | ||
return new Task((reject, _) => reject(error)); | ||
} | ||
/** | ||
* Creates a Task which automatically fails at some time in the future with `error`. | ||
* @param ms How many milliseconds until it succeeds. | ||
* @param error The error to place into the failed Task. | ||
*/ | ||
function failIn(ms, error) { | ||
return new Task((reject, _) => setTimeout(() => reject(error), ms)); | ||
} | ||
/** | ||
* Creates a Task will never finish. | ||
*/ | ||
function never() { | ||
return new Task(() => void 0); | ||
} | ||
/** | ||
* Chain a task to run after a previous task has succeeded. | ||
* @alias chain | ||
* @param fn Takes a successful result and returns a new task. | ||
* @param task The task which will chain to the next one on success. | ||
*/ | ||
function andThen(fn, task) { | ||
return new Task((reject, resolve) => task.fork(reject, b => fn(b).fork(reject, resolve))); | ||
} | ||
/** | ||
* When forked, run a function which can check whether the task has already succeeded. | ||
* @param fn The function which either returns a success value or undefined. | ||
* @param task The task to run if the check fails (returns undefined). | ||
*/ | ||
function succeedIf(fn, task) { | ||
return new Task((reject, resolve) => { | ||
const result = fn(); | ||
if (result) { | ||
resolve(result); | ||
return; | ||
} | ||
task.fork(reject, resolve); | ||
}); | ||
} | ||
/** | ||
* A task which only runs once. Caches the success or failure. Be careful. | ||
* @alias share | ||
* @param task The task to cache results. | ||
*/ | ||
function onlyOnce(task) { | ||
let state = "initialized"; | ||
let cachedResult; | ||
let cachedError; | ||
let callbackId = 0; | ||
const callbacks = {}; | ||
function notify(reject, resolve) { | ||
const id = callbackId++; | ||
callbacks[id] = { reject, resolve }; | ||
} | ||
function triggerReject(error) { | ||
state = "failure"; | ||
cachedError = error; | ||
Object.keys(callbacks).forEach(id => { | ||
callbacks[id].reject(error); | ||
delete callbacks[id]; | ||
}); | ||
} | ||
function triggerResolve(result) { | ||
state = "success"; | ||
cachedResult = result; | ||
Object.keys(callbacks).forEach(id => { | ||
callbacks[id].resolve(result); | ||
delete callbacks[id]; | ||
}); | ||
} | ||
return new Task((reject, resolve) => { | ||
switch (state) { | ||
case "success": | ||
resolve(cachedResult); | ||
break; | ||
case "failure": | ||
reject(cachedError); | ||
break; | ||
case "pending": | ||
notify(reject, resolve); | ||
break; | ||
case "initialized": | ||
state = "pending"; | ||
notify(reject, resolve); | ||
task.fork(triggerReject, triggerResolve); | ||
} | ||
}); | ||
} | ||
/** | ||
* Given a promise, create a Task which relies on it. | ||
* @param promise The promise we will gather the success from. | ||
*/ | ||
function fromPromise(promise) { | ||
return new Task((reject, resolve) => promise.then(resolve, reject)); | ||
} | ||
/** | ||
* Given a task, create a Promise which resolves when the task does. | ||
* @param task The task we will convert to a promise. | ||
*/ | ||
function toPromise(task) { | ||
return new Promise((resolve, reject) => task.fork(reject, resolve)); | ||
} | ||
/** | ||
* Given an array of tasks, return the one which finishes successfully first. | ||
* @param tasks The tasks to run in parallel. | ||
*/ | ||
function firstSuccess(tasks) { | ||
return new Task((reject, resolve) => { | ||
let isDone = false; | ||
let runningTasks = tasks.length; | ||
const errors = []; | ||
return tasks.map(task => task.fork((error) => { | ||
/* Should be impossible. */ | ||
/* istanbul ignore next */ | ||
if (isDone) { | ||
return; | ||
} | ||
runningTasks -= 1; | ||
errors.push(error); | ||
if (runningTasks === 0) { | ||
reject(errors); | ||
} | ||
}, (result) => { | ||
/* Should be impossible. */ | ||
/* istanbul ignore next */ | ||
if (isDone) { | ||
return; | ||
} | ||
isDone = true; | ||
resolve(result); | ||
})); | ||
}); | ||
} | ||
/** | ||
* Given an array of task which return a result, return a new task which results an array of results. | ||
* @param tasks The tasks to run in parallel. | ||
*/ | ||
function all(tasks) { | ||
return new Task((reject, resolve) => { | ||
let isDone = false; | ||
let runningTasks = tasks.length; | ||
const results = []; | ||
return tasks.map((task, i) => task.fork((error) => { | ||
/* Should be impossible. */ | ||
/* istanbul ignore next */ | ||
if (isDone) { | ||
return; | ||
} | ||
isDone = true; | ||
reject(error); | ||
}, (result) => { | ||
/* Should be impossible. */ | ||
/* istanbul ignore next */ | ||
if (isDone) { | ||
return; | ||
} | ||
runningTasks -= 1; | ||
results[i] = result; | ||
if (runningTasks === 0) { | ||
resolve(results); | ||
} | ||
})); | ||
}); | ||
} | ||
/** | ||
* Given an array of task which return a result, return a new task which results an array of results. | ||
* @param tasks The tasks to run in sequence. | ||
*/ | ||
function sequence(tasks) { | ||
return tasks.reduce((sum, task) => { | ||
return andThen(list => { | ||
return map(result => [...list, result], task); | ||
}, sum); | ||
}, succeed([])); | ||
} | ||
/** | ||
* Given a task, swap the error and success values. | ||
* @param task The task to swap the results of. | ||
*/ | ||
function swap(task) { | ||
return new Task((reject, resolve) => task.fork(resolve, reject)); | ||
} | ||
/** | ||
* Given a task, map the successful value to a Task. | ||
* @param fn A function which takes the original successful result and returns the new one. | ||
* @param task The task to map the succcessful result. | ||
*/ | ||
function map(fn, task) { | ||
return new Task((reject, resolve) => task.fork(reject, result => resolve(fn(result)))); | ||
} | ||
/** | ||
* Run a side-effect on success. Useful for logging. | ||
* @param fn A function will fire with the successful value. | ||
* @param task The task to tap on succcess. | ||
*/ | ||
function tap(fn, task) { | ||
return map(result => { | ||
fn(result); | ||
return result; | ||
}, task); | ||
} | ||
/** | ||
* Given a task, map the failure error to a Task. | ||
* @param fn A function which takes the original failure error and returns the new one. | ||
* @param task The task to map the failure. | ||
*/ | ||
function mapError(fn, task) { | ||
return new Task((reject, resolve) => task.fork(error => reject(fn(error)), resolve)); | ||
} | ||
/** | ||
* Given a task, map both the failure error and the success result to a Task. | ||
* @param handleError A function which takes the original failure error and returns the new one. | ||
* @param handleSuccess A function which takes the original successful result and returns the new one. | ||
* @param task The task to map the failure and succeess of. | ||
*/ | ||
function mapBoth(handleError, handleSuccess, task) { | ||
return mapError(handleError, map(handleSuccess, task)); | ||
} | ||
/** | ||
* Given a task, map both the failure error and the success result to a Task which always succeeds. | ||
* @param handleError A function which takes the original failure error and returns a successful result. | ||
* @param handleSuccess A function which takes the original successful result and returns a new successful result. | ||
* @param task The task to map failure and succeess to a success for. | ||
*/ | ||
function fold(handleError, handleSuccess, task) { | ||
return new Task((_, resolve) => task.fork(error => resolve(handleError(error)), result => resolve(handleSuccess(result)))); | ||
} | ||
/** | ||
* Given a task, if the result in a failure, attemp to generate another Task from the error. | ||
* @param fn A function which takes the original failure error and returns a Task. | ||
* @param task The task to try to run a recovery function on failure. | ||
*/ | ||
function orElse(fn, task) { | ||
return new Task((reject, resolve) => task.fork(error => fn(error).fork(reject, resolve), resolve)); | ||
} | ||
/** | ||
* Given a task that succeeds with a map function as its result, | ||
* run that function over the result of a second successful Task. | ||
* @param appliedTask The task whose value will be passed to the map function. | ||
* @param task The task who will return a map function as the success result. | ||
*/ | ||
function ap(task, appliedTask) { | ||
return new Task((reject, resolve) => { | ||
let targetResult; | ||
let applierFunction; | ||
let hasResultLoaded = false; | ||
let isRejected = false; | ||
const handleResolve = (onResolve) => { | ||
return (x) => { | ||
/* Should be impossible. */ | ||
/* istanbul ignore next */ | ||
if (isRejected) { | ||
return; | ||
} | ||
onResolve(x); | ||
if (applierFunction && hasResultLoaded) { | ||
resolve(applierFunction(targetResult)); | ||
} | ||
}; | ||
}; | ||
const handleReject = (x) => { | ||
/* Should be impossible. */ | ||
/* istanbul ignore next */ | ||
if (isRejected) { | ||
return; | ||
} | ||
isRejected = true; | ||
reject(x); | ||
}; | ||
task.fork(handleReject, handleResolve((x) => { | ||
applierFunction = x; | ||
})); | ||
appliedTask.fork(handleReject, handleResolve((x) => { | ||
hasResultLoaded = true; | ||
targetResult = x; | ||
})); | ||
}); | ||
} | ||
/** | ||
* Wait some number of seconds to continue after a successful task. | ||
* @param ms How long to wait in milliseconds. | ||
* @param task Which task to wait to succeed with. | ||
*/ | ||
function wait(ms, task) { | ||
return new Task((reject, resolve) => { | ||
setTimeout(() => task.fork(reject, resolve), ms); | ||
}); | ||
} | ||
/** | ||
* If a task fails, retry it in the future. | ||
* @param ms How long to wait before trying. | ||
* @param task Which task to retry. | ||
*/ | ||
function retryIn(ms, task) { | ||
return task.orElse(() => task.wait(ms)); | ||
} | ||
/** | ||
* If a task fails, retry it X times, with exponential backoff. | ||
* @param ms How long to wait before trying the first time. | ||
* @param times How many times to attempt, each waiting 2x the previous time. | ||
* @param task Which task to retry. | ||
*/ | ||
function retryWithExponentialBackoff(ms, times, task) { | ||
return range(times).reduce((sum, i) => sum.retryIn(ms * 2 ** i), task); | ||
} | ||
function get(url, config) { | ||
return fromPromise(axios.get(url, config)); | ||
} | ||
/* istanbul ignore next */ | ||
function delete_(url, config) { | ||
return fromPromise(axios.delete(url, config)); | ||
} | ||
/* istanbul ignore next */ | ||
function head(url, config) { | ||
return fromPromise(axios.head(url, config)); | ||
} | ||
/* istanbul ignore next */ | ||
function post(url, data, config) { | ||
return fromPromise(axios.post(url, data, config)); | ||
} | ||
/* istanbul ignore next */ | ||
function put(url, data, config) { | ||
return fromPromise(axios.put(url, data, config)); | ||
} | ||
/* istanbul ignore next */ | ||
function patch(url, data, config) { | ||
return fromPromise(axios.patch(url, data, config)); | ||
} | ||
function toJSON(resp) { | ||
const type = resp.config ? resp.config.responseType : "text"; | ||
switch (type) { | ||
case "json": | ||
return succeed(resp.data); | ||
case "text": | ||
try { | ||
return succeed(JSON.parse(resp.data)); | ||
} | ||
catch (e) { | ||
return fail(e); | ||
} | ||
default: | ||
return fail(new Error("Invalid data")); | ||
} | ||
} | ||
var HTTP = /*#__PURE__*/Object.freeze({ | ||
__proto__: null, | ||
get: get, | ||
delete_: delete_, | ||
head: head, | ||
post: post, | ||
put: put, | ||
patch: patch, | ||
toJSON: toJSON | ||
}); | ||
function initialize() { | ||
return { type: "Initialized" }; | ||
} | ||
function pending() { | ||
return { type: "Pending" }; | ||
} | ||
function succeed$1(result) { | ||
return { type: "Success", result }; | ||
} | ||
function fail$1(error) { | ||
return { type: "Failure", error }; | ||
} | ||
function fold$1(onInitialized, onPending, onFailure, onSuccess, remote) { | ||
switch (remote.type) { | ||
case "Initialized": | ||
return onInitialized(); | ||
case "Pending": | ||
return onPending(); | ||
case "Failure": | ||
return onFailure(remote.error); | ||
case "Success": | ||
return onSuccess(remote.result); | ||
} | ||
} | ||
function fromTask(task) { | ||
return task.map(succeed$1).orElse(e => of(fail$1(e))); | ||
} | ||
var RemoteData = /*#__PURE__*/Object.freeze({ | ||
__proto__: null, | ||
initialize: initialize, | ||
pending: pending, | ||
succeed: succeed$1, | ||
fail: fail$1, | ||
fold: fold$1, | ||
fromTask: fromTask | ||
}); | ||
export { HTTP, RemoteData, Task, range, to }; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@tdreyno/pretty-please", | ||
"version": "1.0.0-beta.3", | ||
"version": "1.0.0-beta.4", | ||
"files": [ | ||
@@ -5,0 +5,0 @@ "dist-*/", |
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
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
246963
2829
0