UNPKG

solid-atom

Version:
165 lines (157 loc) 6.59 kB
import { Accessor } from 'solid-js'; import { MemoOptions } from 'solid-js'; import { Signal } from 'solid-js'; import { SignalOptions } from 'solid-js'; /** Reactive atomic value without the inconveniences of {@link Signal} */ export declare class Atom<T> { get: Accessor<T>; set: (x: T) => void; get value(): T; set value(v: T); constructor(get: Accessor<T>, set: (x: T) => void); /** * Creates a new {@link Atom} with the setter of the current one and a memoized version of its getter * @param opts The memo's settings */ memo(opts?: MemoOptions<T>): Atom<T>; /** * Creates a new {@link Atom} that applies a conversion to the current one * @param to Conversion function from {@link S} to {@link D} * @param from Conversion function from {@link D} to {@link S} */ convert<R>(to: (x: T) => R, from: (x: R) => T): Atom<R>; /** * Allows you to execute {@link set} on the current {@link Atom} based on its current value. * The current value gets read through {@link untrack} to mimic the {@link Setter} behaviour. * If {@link f} is not provided, it will set the current value again * @param f Function that creates a new value based on the current one * @returns Whatever {@link f} returned */ update<V extends T>(f?: (prev: T) => V): V; /** * Creates a new {@link Atom} that defers the setter of the current one. * When the setter is called, it will schedule the value to be set using {@link scheduler}. * If the setter gets called again, the previous operation will be cancelled, unless it has already finished * @param scheduler Function that schedules an operation and provides another function to cancel it */ defer(scheduler: (f: () => void) => () => void): Atom<T>; /** * Two way version of {@link createSelector} * @param comp The comparer function * @returns A boolean {@link Atom} factory */ selector(comp?: (a: T, b: T) => boolean): (f: Accessor<T>, def: T | (T extends undefined ? void : never)) => Atom<boolean>; /** * Creates a new {@link Atom} that throws an error when trying to set it * @param f The getter for the new {@link Atom} */ static readOnly<T>(f: Accessor<T>): Atom<T>; /** * Creates an {@link Atom} that forwards an {@link Accessor} to another {@link Atom} * @param f The reactive {@link Accessor} to the {@link Atom} to forward */ static unwrap<T>(f: Accessor<Atom<T>>): Atom<T>; /** * Creates an {@link Atom} based on a {@link Signal} * @param param0 The {@link Signal} to forward */ static from<T>([get, set]: Signal<T>): Atom<T>; /** * Creates an {@link Atom} based on an object property * @param obj The object containing the property * @param k A function that returns the key of the property and will be passed to {@link nameOf} */ static prop<T, K extends keyof T>(obj: Accessor<T>, k: (x: NamesOf<T>) => K): Atom<T[K]>; /** * Creates a new {@link Atom} that directly stores a value. * Creates a new {@link Signal} and passes it to {@link from} * @param v The value to store in the new {@link Signal} * @param opts The {@link Signal}'s settings */ static value<T>(v?: undefined, opts?: SignalOptions<T>): Atom<T | undefined>; static value<T>(v: T, opts?: SignalOptions<T>): Atom<T>; /** * Creates a bindable data source. * If {@link bind} returns an {@link Atom} it gets wrapped, otherwise it creates a {@link Signal} using {@link f} and uses it to store the value until {@link bind}'s value changes * @param bind The bound {@link Atom} * @param f The function that will create the actual {@link Signal} that will store the {@link Atom}'s data in case that {@link bind} doesn't return anything */ static source<T>(bind: Accessor<Atom<T> | undefined>): Atom<T | undefined>; static source<T>(bind: Accessor<Atom<T> | undefined>, f: Accessor<Signal<T>>): Atom<T>; } /** Function that returns passed value and can be used as a class */ export declare const IDENTITY: Identity; /** Type definition of {@link IDENTITY} */ declare interface Identity { /** * Returns the passed value * - * Maintains the type of the input * @param x The value to be returned */ <T>(x: T): T; /** * Returns the passed value * - * Allows the function to be used to fake any conversion. * Example: * ```ts * const a = IDENTITY(12); * // ^? 12 * * const b: (x: string) => number = IDENTITY; * // No error * ``` * It is important to this overload to be defined after the previous one * @param x The value to be returned */ (x: any): any; /** * Returns the passed value * - * Allows you to extend a specific instance rather than a class. * Private field example: * ```ts * class Something extends IDENTITY { * #value = 12; * * static get(obj: object) { return (obj as Something).#value; } * * static set(obj: object, v: number) { (obj as Something).#value = v; } * } * * const a = {}; * const b = new Something(a); * const c = a === b; // true * const d = Something.get(a); // 12 * ``` * Custom function example: * ```ts * class CoolFunction<T> extends IDENTITY<() => T> { * constructor(public f: () => T) { super(f); } * } * * const a = () => 12; * const b = new CoolFunction(a); * const c = a === b && b === b.f; // true * const d = b(); // 12 * const e = b.f(); // 12 * ``` * @param x The value to be returned */ new <T = object>(x: T): T; } /** * Function that returns the name of the field accessed inside of {@link f}. * This function is not meant to be used on its own because it has very poor type inference * @param f A function that returns a value based on {@link NamesOf} * @returns The same thing that {@link f} returned */ export declare const nameOf: <T, const R>(f: (x: NamesOf<T>) => R) => R; /** Type that maps each key of {@link T} to itself */ export declare type NamesOf<T> = { readonly [k in keyof T]-?: k; }; /** Function that does nothing */ export declare const NO_OP: () => void; export { }