value-enhancer
Version:
Enhance value with plain and explicit reactive wrapper. Think of it as hook-style signals.
67 lines (63 loc) • 1.84 kB
text/typescript
import type { ReadonlyVal, UnwrapVal, ValConfig } from "./typings";
import type { ValImpl } from "./val";
import { flattenFrom } from "./flatten-from";
import { identity } from "./utils";
interface Flatten {
/**
* Flatten a val of val to a val of the inner val value.
* @param val Input value.
* @returns A readonly val with value of inner val.
*
* @example
* ```js
* import { flatten, val } from "value-enhancer";
*
* const inner$ = val(12);
* const outer$ = val(inner$);
*
* const flattened$ = flatten(outer$);
*
* inner$.value === flattened$.value; // true
* ```
*/
<TValOrValue = any>(val: ReadonlyVal<TValOrValue>): ReadonlyVal<
UnwrapVal<TValOrValue>
>;
/**
* Flatten an inner val extracted from a source val to a val of the inner val value.
* @param val Input value.
* @param get extract inner val or value from source val.
* @returns A readonly val with value of inner val.
*
* @example
* ```js
* import { flatten, val } from "value-enhancer";
*
* const inner$ = val(12);
* const outer$ = val({ inner$ });
*
* const flattened$ = flatten(outer$, ({ inner$ }) => inner$);
*
* inner$.value === flattened$.value; // true
* ```
*/
<TSrcValue = any, TValOrValue = any>(
val: ReadonlyVal<TSrcValue>,
get?: (value: TSrcValue) => TValOrValue,
config?: ValConfig<UnwrapVal<TValOrValue>>
): ReadonlyVal<UnwrapVal<TValOrValue>>;
}
export const flatten: Flatten = <
TSrcValue = any,
TValOrValue = any,
TSrcVal extends ValImpl = ValImpl<TSrcValue>
>(
val: TSrcVal,
get: (value: TSrcValue) => TValOrValue = identity as any,
config?: ValConfig<UnwrapVal<TValOrValue>>
): ReadonlyVal<UnwrapVal<TValOrValue>> =>
flattenFrom(
() => get(val.value),
notify => val.$valCompute(notify),
config
);