UNPKG

signal-utils

Version:

Utils for use with the Signals Proposal: https://github.com/proposal-signals/proposal-signals

125 lines (112 loc) 4.04 kB
/** A very cheap representation of the of a promise. */ type StateRepr<T> = [tag: "PENDING"] | [tag: "RESOLVED", value: T] | [tag: "REJECTED", error: unknown]; export declare class SignalAsyncData<T> { #private; /** @param promise The promise to inspect. */ constructor(data: T | Promise<T>); then: (onResolved: (value: T) => null | undefined, onRejected?: ((reason: unknown) => void) | undefined) => void | Promise<void | null | undefined> | null; /** * The resolution state of the promise. */ get state(): StateRepr<T>[0]; /** The value of the resolved promise. @note It is only valid to access `error` when `.isError` is true, that is, when `TrackedAsyncData.state` is `"ERROR"`. @warning You should not rely on this returning `T | null`! In a future breaking change which drops support for pre-Octane idioms, it will *only* return `T` and will *throw* if you access it when the state is wrong. */ get value(): T | null; /** The error of the rejected promise. @note It is only valid to access `error` when `.isError` is true, that is, when `TrackedAsyncData.state` is `"ERROR"`. @warning You should not rely on this returning `null` when the state is not `"ERROR"`! In a future breaking change which drops support for pre-Octane idioms, it will *only* return `E` and will *throw* if you access it when the state is wrong. */ get error(): unknown; /** Is the state `"PENDING"`. */ get isPending(): boolean; /** Is the state `"RESOLVED"`? */ get isResolved(): boolean; /** Is the state `"REJECTED"`? */ get isRejected(): boolean; toJSON(): JSONRepr<T>; toString(): string; } /** The JSON representation of a `TrackedAsyncData`, useful for e.g. logging. Note that you cannot reconstruct a `TrackedAsyncData` *from* this, because it is impossible to get the original promise when in a pending state! */ export type JSONRepr<T> = { isPending: true; isResolved: false; isRejected: false; } | { isPending: false; isResolved: true; isRejected: false; value: T; } | { isPending: false; isResolved: false; isRejected: true; error: unknown; }; /** Given a `Promise`, return a `TrackedAsyncData` object which exposes the state of the promise, as well as the resolved value or thrown error once the promise resolves or fails. The function and helper accept any data, so you may use it freely in contexts where you are receiving data which may or may not be a `Promise`. ## Example Given a backing class like this: ```js import Component from '@glimmer/component'; import { signal } from 'signal-utils'; import { load } from 'ember-tracked-data/helpers/load'; export default class ExtraInfo extends Component { @signal get someData() {return load(fetch('some-url', this.args.someArg)); } } ``` You can use the result in your template like this: ```hbs {{#if this.someData.isLoading}} loading... {{else if this.someData.isLoaded}} {{this.someData.value}} {{else if this.someData.isError}} Whoops! Something went wrong: {{this.someData.error}} {{/if}} ``` You can also use the helper directly in your template: ```hbs {{#let (load @somePromise) as |data|}} {{#if data.isLoading}} <LoadingSpinner /> {{else if data.isLoaded}} <SomeComponent @data={{data.value}} /> {{else if data.isError}} <Error @cause={{data.error}} /> {{/if}} {{/let}} ``` @param data The (async) data we want to operate on: a value or a `Promise` of a value. @returns An object containing the state(, value, and error). @note Prefer to use `TrackedAsyncData` directly! This function is provided simply for symmetry with the helper and backwards compatibility. */ export declare function load<T>(data: T | Promise<T>): SignalAsyncData<T>; export {}; //# sourceMappingURL=async-data.d.ts.map