atomaric
Version:
Manage your project state
147 lines (125 loc) • 5.22 kB
TypeScript
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useSyncExternalStore } from 'react';
import { IAtomArrayDoActions } from './do.classes.model/Array';
import { IAtomBooleanDoActions } from './do.classes.model/Boolean';
import { IAtomMapDoActions } from './do.classes.model/Map';
import { IAtomNumberDoActions } from './do.classes.model/Number';
import { IAtomObjectDoActions } from './do.classes.model/Object';
import { IAtomSetDoActions } from './do.classes.model/Set';
import { Path, PathValue, PathValueDonor } from './paths';
export type AtomSecureLevel = 0 | 1 | 2 | 3;
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface Register {}
export type ObjectActionsSetDeepPartialSeparator = Register extends {
keyPathSeparator: infer Separator extends string;
}
? Separator
: '.';
type Sunscriber<Value> = (value: Value) => void;
export type AtomStoreKey = `${string}${string}:${string}${string}`;
export type AtomOptions<Value, Actions extends Record<string, AnyFunc> = Record<string, AnyFunc>> = {
/** **default: true** */
warnOnDuplicateStoreKey?: boolean;
/** will update value if localStorage value is changed
* **default: true**
*/
listenStorageChanges?: boolean;
/** zip Value to stringifiable value */
zipValue?: (value: Value) => any;
/** unzip stringifiable value to Value */
unzipValue?: (packedValue: any) => Value;
/** make your localStorage value unchangable */
unchangable?: true;
/** return value expire Date */
exp?: (self: Atom<Value>, isValueWasStoraged: boolean) => Date;
} & (
| {
/** save in localStorage by this key */
storeKey: AtomStoreKey;
securifyKeyLevel?: AtomSecureLevel;
securifyValueLevel?: AtomSecureLevel;
}
| {
/** declare your custom actions */
do: (
set: AtomSetMethod<Value>,
get: () => Value,
self: Atom<Value>,
setDeferred: AtomSetDeferredMethod<Value>,
) => Actions;
}
);
export type AtomSetMethod<Value> = (value: Value | ((prev: Value) => Value), isPreventSave?: boolean) => void;
export type AtomSetDeferredMethod<Value> = (
value: Value | ((prev: Value) => Value),
debounceMs?: number,
isPreventSave?: boolean,
isInitInvoke?: boolean,
) => void;
export type AtomSubscribeMethod<Value> = (subscriber: Sunscriber<Value>) => () => void;
export type ObjectActionsSetDeepPartialDoAction<Value> = <
ValuePath extends Path<Value, Sep>,
Val extends PathValue<Value, Sep, ValuePath>,
Sep extends string = ObjectActionsSetDeepPartialSeparator,
>(
path: ValuePath,
value: Val | ((value: Val) => Val),
donor: PathValueDonor<Value, Sep, ValuePath> | null,
separator?: Sep,
) => void;
export type DefaultActions<Value> = Value extends Set<infer Val>
? IAtomSetDoActions<Val>
: Value extends Map<infer Key, infer Val>
? IAtomMapDoActions<Value, Key, Val>
: Value extends boolean
? IAtomBooleanDoActions
: Value extends (infer Val)[]
? IAtomArrayDoActions<Val>
: Value extends number
? IAtomNumberDoActions
: Value extends object
? IAtomObjectDoActions<Value>
: object;
declare class Atom<Value, Actions extends Record<string, AnyFunc> = Record<string, AnyFunc>> {
constructor(initialValue: Value | (() => Value), storeKeyOrOptions: StoreKeyOrOptions<Value, Actions> | undefined);
/** initial value */
readonly initialValue: Value;
/** get current value */
readonly get: () => Value;
/** set current value */
readonly set: AtomSetMethod<Value>;
/** set current value with debounce */
readonly setDeferred: AtomSetDeferredMethod<Value>;
/** set current value as default (initial) */
readonly reset: () => void;
/** subscribe on value changes */
readonly subscribe: AtomSubscribeMethod<Value>;
/** your custom actions */
readonly do: Actions & DefaultActions<Value>;
/** check is current value not changed */
readonly isInitialValue: () => boolean;
}
export function useAtom<Value>(atom: Atom<Value>): [Value, AtomSetMethod<Value>];
/** observable atom value */
export function useAtomValue<Value>(atom: Atom<Value>): Value;
export function useAtomSet<Value>(atom: Atom<Value>): AtomSetMethod<Value>;
export function useAtomSetDeferred<Value>(atom: Atom<Value>): AtomSetDeferredMethod<Value>;
export function useAtomGet<Value>(atom: Atom<Value>): () => Value;
/** get your custom actions */
export function useAtomDo<Value, Actions extends Record<string, AnyFunc> = Record<string, AnyFunc>>(
atom: Atom<Value, Actions>,
): Actions & DefaultActions<Value>;
export type StoreKeyOrOptions<Value, Actions extends Record<string, AnyFunc> = Record<string, AnyFunc>> =
| AtomStoreKey
| AtomOptions<Value, Actions>;
export function atom<Value, Actions extends Record<string, AnyFunc> = Record<string, AnyFunc>>(
value: Value | (() => Value),
storeKeyOrOptions?: StoreKeyOrOptions<Value, Actions>,
): Atom<Value, Actions>;
/** invoke this function before all atom usages */
export function configureAtomaric(options: {
useSyncExternalStore: typeof useSyncExternalStore;
keyPathSeparator: ObjectActionsSetDeepPartialSeparator;
securifyKeyLevel?: AtomSecureLevel;
securifyValueLevel?: AtomSecureLevel;
}): void;