recoil
Version:
Recoil - A state management library for React
108 lines (104 loc) • 3.9 kB
Flow
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* A type that represents a value that may or may not be loaded. It differs from
* LoadObject in that the `loading` state has a Promise that is meant to resolve
* when the value is available (but as with LoadObject, an individual Loadable
* is a value type and is not mutated when the status of a request changes).
*
* @emails oncall+recoil
* @flow strict
* @format
*/
'use strict';
const err = require('../util/Recoil_err');
const isPromise = require('../util/Recoil_isPromise');
const nullthrows = require('../util/Recoil_nullthrows');
declare class BaseLoadable<T> {
getValue(): T,
toPromise(): Promise<T>,
valueMaybe(): T | void,
valueOrThrow(): T,
promiseMaybe(): Promise<T> | void,
promiseOrThrow(): Promise<T>,
errorMaybe(): mixed | void,
errorOrThrow(): mixed,
is(other: Loadable<mixed>): boolean,
map<S>(_map: (T) => Promise<S> | Loadable<S> | S): Loadable<S>,
}
declare class ValueLoadable<T> extends BaseLoadable<T> {
state: 'hasValue',
contents: T,
constructor(value: T): any,
getValue(): T,
toPromise(): Promise<T>,
valueMaybe(): T,
valueOrThrow(): T,
promiseMaybe(): void,
errorMaybe(): void,
map<S>(map: (T) => Promise<S> | Loadable<S> | S): Loadable<S>,
}
declare class ErrorLoadable<T> extends BaseLoadable<T> {
state: 'hasError',
contents: mixed,
constructor(error: mixed): any,
getValue(): T,
toPromise(): Promise<T>,
valueMaybe(): void,
promiseMaybe(): void,
errorMaybe(): mixed,
errorOrThrow(): mixed,
map<S>(_map: (T) => Promise<S> | Loadable<S> | S): $ReadOnly<ErrorLoadable<S>>,
}
declare class LoadingLoadable<T> extends BaseLoadable<T> {
state: 'loading',
contents: Promise<T>,
constructor(promise: Promise<T>): any,
getValue(): T,
toPromise(): Promise<T>,
valueMaybe(): void,
promiseMaybe(): Promise<T>,
promiseOrThrow(): Promise<T>,
errorMaybe(): void,
map<S>(map: (T) => Promise<S> | Loadable<S> | S): $ReadOnly<LoadingLoadable<S>>,
}
export type Loadable<+T> = $ReadOnly<ValueLoadable<T>> | $ReadOnly<ErrorLoadable<T>> | $ReadOnly<LoadingLoadable<T>>;
declare function loadableWithValue<+T>(value: T): $ReadOnly<ValueLoadable<T>>;
declare function loadableWithError<+T>(error: mixed): $ReadOnly<ErrorLoadable<T>>;
declare function loadableWithPromise<+T>(promise: Promise<T>): $ReadOnly<LoadingLoadable<T>>;
declare function loadableLoading<+T>(): $ReadOnly<LoadingLoadable<T>>;
type UnwrapLoadables<Loadables> = $TupleMap<Loadables, <T>(Loadable<T>) => T>;
type LoadableAllOfTuple = <Tuple: $ReadOnlyArray<Loadable<mixed>>>(tuple: Tuple) => Loadable<$TupleMap<Tuple, <V>(Loadable<V>) => V>>;
type LoadableAllOfObj = <Obj: $ReadOnly<{
[string]: Loadable<mixed>,
...
}>>(obj: Obj) => Loadable<$ObjMap<Obj, <V>(Loadable<V>) => V>>;
type LoadableAll = LoadableAllOfTuple & LoadableAllOfObj;
declare function loadableAllArray<Inputs: $ReadOnlyArray<Loadable<mixed>>>(inputs: Inputs): Loadable<UnwrapLoadables<Inputs>>;
declare function loadableAll<Inputs: $ReadOnlyArray<Loadable<mixed>> | $ReadOnly<{
[string]: Loadable<mixed>,
...
}>>(inputs: Inputs): Loadable<$ReadOnlyArray<mixed> | $ReadOnly<{
[string]: mixed,
...
}>>;
declare function isLoadable(x: mixed): boolean;
const LoadableStaticInterface = {
of: <T>(value: Promise<T> | T): Loadable<T> => isPromise(value) ? loadableWithPromise(value) : loadableWithValue(value),
error: <T>(error: mixed): $ReadOnly<ErrorLoadable<T>> => loadableWithError(error),
// $FlowIssue[unclear-type]
all: ((loadableAll: any): LoadableAll),
isLoadable
};
module.exports = {
loadableWithValue,
loadableWithError,
loadableWithPromise,
loadableLoading,
loadableAll,
isLoadable,
RecoilLoadable: LoadableStaticInterface
};