import type { ReadableSignal, StoreInput, StoresInputValues, WritableSignal } from '@amadeus-it-group/tansu';
import type { ConfigValidator, PropsConfig, ValuesOrReadableSignals, WritableWithDefaultOptions } from '../types';
/**
* Transforms the properties of a given type `P` into writable signals.
* Each property key in `P` is suffixed with a `$` and its type is converted to a `WritableSignal`.
* @template P - The original type whose properties are to be transformed.
*/
export type ToWritableSignal
= {
[K in keyof P as `${K & string}$`]-?: WritableSignal
;
};
/**
* Represents a collection of readable signals for an object type `T`.
* Each key in the object corresponds to a key in `T`, and the value is an optional `ReadableSignal`
* that can hold the value of the corresponding property in `T` or `undefined`.
*
* @template T - The object type for which the readable signals are defined.
*/
export type ReadableSignals = {
[K in keyof T]?: ReadableSignal;
};
/**
* A utility type that removes the trailing dollar sign (`$`) from a string type.
*
* @template S - A string type that ends with a dollar sign (`$`).
* @returns The string type without the trailing dollar sign (`$`), or `never` if the input type does not end with a dollar sign.
*/
export type WithoutDollar = S extends `${infer U}$` ? U : never;
/**
*
* Utility function designed to create a `patch` function related to the provided stores.
* Any key given to the patch function which is not in the original object will be ignored.
*
* @example
*
* ```typescript
* const storeA$ = writable(1);
* const storeB$ = writable(1);
* const patch = createPatch({a: storeA$, b: storeB$});
*
* patch({a: 2}) // will perform storeA$.set(2)
* patch({a: 2, b: 2}) // will perform storeA$.set(2) and storeB$.set(2) in the same batch.
* patch({a: 2, c: 2}) // will perform storeA$.set(2), c is ignored.
*
* ```
* @template T - The type of the object that the stores represent.
* @param stores - The stores to be updated.
* @returns - A function that takes partial values of the stores and updates them.
*/
export declare function createPatch(stores: ToWritableSignal): (storesValues: Partial) => void;
/**
* This utility function is designed to compare the first level of two objects.
*
* It returns a new object which has all the keys for which the values in `obj1`
* and `obj2` are different, with the values from `obj2`, or null if objects
* are identical.
*
* @template T - The type of the objects being compared.
* @param obj1 - The first partial object to compare.
* @param obj2 - The second partial object to compare.
* @returns A partial object containing the properties that have different values, or `null` if the objects are identical.
*/
export declare function findChangedProperties>(obj1: Partial, obj2: Partial): Partial | null;
/**
* Returns a writable store whose value is either its own value (when it is not undefined) or a default value
* that comes either from the `config$` store (when it is not undefined) or from `defValue`.
* If a normalizeValue function is passed in the options, it is called to normalize non-undefined values coming
* either from the `config$` store or from the `set` or `update` functions. If a value is invalid (i.e. normalizeValue
* returns the `invalidValue` symbol), an error is logged on the console and it is either not set (if it comes from the
* `set` or `update` functions), or the `defValue` is used instead (if the invalid value comes from the `config$` store).
*
* @template T - The type of the value.
*
* @param defValue - Default value used when both the own value and the config$ value are undefined.
* @param config$ - Store containing the default value used when the own value is undefined
* @param options - Object which can contain the following optional functions: normalizeValue and equal
* @param own$ - Store containing the own value
* @returns a writable store with the extra default value and normalization logic described above
*/
export declare function writableWithDefault(defValue: T, config$?: ReadableSignal, options?: WritableWithDefaultOptions, own$?: WritableSignal): WritableSignal;
/**
* Returns true if the provided argument is a store (ReadableSignal).
* @param x - argument that is tested
* @returns true if the argument is a store (ReadableSignal)
*/
export declare const isStore: (x: any) => x is ReadableSignal;
/**
* If the provided argument is already a store, it is returned as is, otherwise, a readable store is created with the provided argument as its initial value.
* @template T - The type of the value.
* @param x - The value to be converted to a readable store.
* @returns - The readable store containing the value.
*/
export declare const toReadableStore: (x: ReadableSignal | T) => ReadableSignal;
/**
* Converts a value or a writable signal into a writable signal.
*
* @template T - The type of the value or signal.
* @param x - The value or writable signal to convert.
* @returns - The resulting writable signal.
*/
export declare const toWritableStore: (x: WritableSignal | T) => WritableSignal;
/**
* Normalizes configuration stores by converting them into readable signals.
*
* @template T - The type of the configuration object.
* @param keys - An array of keys to normalize from the configuration object.
* @param [config] - The configuration object or readable signals to normalize.
* @returns An object containing readable signals for each key in the configuration.
*/
export declare const normalizeConfigStores: (keys: (keyof T)[], config?: ReadableSignal> | ValuesOrReadableSignals) => ReadableSignals;
/**
* Merges two configuration stores into one, prioritizing the first store's values
* when both stores have a value for the same key.
*
* @template T - The type of the configuration object.
* @param keys - The keys to merge from the configuration stores.
* @param [config1] - The first configuration store.
* @param [config2] - The second configuration store.
* @returns - The merged configuration store.
*/
export declare const mergeConfigStores: (keys: (keyof T)[], config1?: ReadableSignals, config2?: ReadableSignals) => ReadableSignals;
/**
* Returns an object containing, for each property of `defConfig`, a corresponding writable with the normalization and default value logic
* described in {@link writableWithDefault}. Keys in the returned object are the same as the ones present in `defConfig`,
* with the exta `$` suffix (showing that they are stores).
*
* @template T - The type of the default configuration object.
*
* @param defConfig - object containing, for each property, a default value to use in case `config$` does not provide the suitable default
* value for that property
* @param propsConfig - object defining the config and props
* @param options - object containing, for each property of `defConfig`, an optional object with the following optional functions: normalizeValue and equal
* @returns an object containing writables
*
* @example With a store
* ```ts
* const defConfig = {propA: 1};
* const validation = {propA: {normalizeValue: value => +value}};
* const config = writable({propA: 5});
* const {propA$} = writablesWithDefault(defConfig, {config}, validation);
* ```
*
* @example With an object containing a value and a store
* ```ts
* const defConfig = {propA: 1, propB: 2};
* const validation = {propA: {normalizeValue: value => +value}};
* const config = {propA: 5, propB: writable(3)};
* const {propA$, propB$} = writablesWithDefault(defConfig, {config}, validation);
* ```
*/
export declare const writablesWithDefault: (defConfig: T, propsConfig?: PropsConfig, options?: ConfigValidator) => ToWritableSignal;
/**
* Shortcut for calling both {@link writablesWithDefault} and {@link createPatch} in one call.
*
* @template T - The type of the properties configuration object.
* @param defConfig - object containing, for each property, a default value to use in case `config` does not provide the suitable default
* value for that property
* @param propsConfig - either a store of objects containing, for each property of `defConfig`, the default value or an object containing
* for each property of `defConfig` either a store containing the default value or the default value itself
* @param options - object containing, for each property of `defConfig`, an optional object with the following optional functions: normalizeValue and equal
* @returns an array with two items: the first one containing the writables (returned by {@link writablesWithDefault}),
* and the second one containing the patch function (returned by {@link createPatch})
*
* @example With a store
* ```ts
* const defConfig = {propA: 1};
* const validation = {propA: {normalizeValue: value => +value}};
* const config$ = writable({propA: 5});
* const [{propA$}, patch] = writablesForProps(defConfig, config$, validation);
* ```
*
* @example With an object containing a value and a store
* ```ts
* const defConfig = {propA: 1, propB: 2};
* const validation = {propA: {normalizeValue: value => +value}};
* const config = {propA: 5, propB: writable(3)};
* const [{propA$, propB$}, patch] = writablesForProps(defConfig, config, validation);
* ```
*/
export declare const writablesForProps: (defConfig: T, propsConfig?: PropsConfig, options?: { [K in keyof T]: WritableWithDefaultOptions | undefined; }) => [ToWritableSignal, ReturnType>];
/**
* Using input stores, this function builds an object containing the stores as readable and a global state.
*
* @template A - The type of the state object.
* @param inputStores - the input stores
* @returns the object containing the stores as readable and the global state
*/
export declare const stateStores: (inputStores: { [K in keyof A as `${K & string}$`]: ReadableSignal; }) => {
state$: ReadableSignal;
stores: { [K in keyof A as `${K & string}$`]: ReadableSignal; };
};
/**
* Creates a writable signal that derives its value from multiple stores and allows for custom adjustment and equality checks.
*
* @template T - The type of the derived value.
* @template U - A tuple type where the first element is a writable signal of type T and the rest are store inputs.
*
* @param onChange$ - A readable signal that emits a function to be called when the derived value changes.
* @param stores - A tuple of stores where the first element is a writable signal of type T and the rest are store inputs.
* @param adjustValue - A function to adjust the derived value based on the input values from the stores.
* @param equal - A function to compare the current and new values for equality.
*
* @returns A writable signal that derives its value from the provided stores and allows for custom adjustment and equality checks.
*/
export declare const bindableDerived: , ...StoreInput[]]>(onChange$: ReadableSignal<(value: T) => void>, stores: U, adjustValue?: (arg: StoresInputValues) => T, equal?: (currentValue: T, newValue: T) => boolean) => WritableSignal;
/**
* Creates a bindable property that synchronizes a writable signal with an optional adjustment function and equality check.
*
* @template T - The type of the value being stored.
* @param store$ - The writable signal that holds the current value.
* @param onChange$ - A readable signal that triggers a callback when the value changes.
* @param [adjustValue] - An optional function to adjust the value before storing it. Defaults to the identity function.
* @param [equal] - An optional function to compare values for equality. Defaults to `tansuDefaultEqual`.
* @returns A writable signal that synchronizes with the provided store and triggers the onChange callback when updated.
*/
export declare const bindableProp: (store$: WritableSignal, onChange$: ReadableSignal<(newValue: T) => void>, adjustValue?: (value: T) => T, equal?: (a: T, b: T) => boolean) => WritableSignal;
/**
* Wraps an id store in a computed so that undefined and empty values are replaced by a generated id.
*
* @param id$ - the id store to use
* @returns the id store with a default generation if the id is not provided
*/
export declare function idWithDefault(id$: ReadableSignal): ReadableSignal;
export declare const true$: ReadableSignal;
export declare const false$: ReadableSignal;