type Transaction = { number: number; snapshot: T; timestamp: number; }; type TransactionDiff = { old: T; new: T; }; /** * Interface for a transaction API that stores state history in a chain * (with a configurable length) and allows for receiving diffs and rolling back changes. * * @template T - The type of the state being managed by the transactions. */ interface TransactionAPI { /** * The total number of transactions that have occurred since the state was initialized. */ totalTransactions: number; /** * Adds a new transaction to the transaction chain. * * @param {T} snapshot - The snapshot of the state to be added as a transaction. */ addTransaction(snapshot: T): void; /** * Retrieves the last transaction in the transaction chain. * * @returns {Transaction | null} The last transaction, or null if there are no transactions. */ getLastTransaction(): Transaction | null; /** * Retrieves all transactions that have occurred. * * @returns {Transaction[]} An array of all transactions. */ getAllTransactions(): Transaction[]; /** * Retrieves a specific transaction by its number in the transaction chain. * * @param {number} transactionNumber - The number of the transaction to retrieve. * @returns {Transaction | null} The transaction with the specified number, or null if it doesn't exist. */ getTransactionByNumber(transactionNumber: number): Transaction | null; /** * Retrieves the difference between the current state and the last transaction. * * @returns {TransactionDiff | null} The difference between the current state and the last transaction, or null if there are no transactions. */ getLastDiff(): TransactionDiff | null; /** * Retrieves the difference between two specific transactions. * * @param {number} transactionA - The number of the first transaction. * @param {number} transactionB - The number of the second transaction. * @returns {TransactionDiff | null} The difference between the two specified transactions, or null if the transactions don't exist or there is no difference. */ getDiffBetween(transactionA: number, transactionB: number): TransactionDiff | null; } interface DebugAPI { transactionService: TransactionAPI; } /** * A callback function that will be called every time the state changes. * Can take the updated state as an argument. */ type SubscriptionCb = (newState: T) => void; /** * A callback function for unsubscribing. */ type UnsubscribeCb = () => void; /** Callback for state updates. */ type UpdateCb = (state: T) => void; /** * It may contain additional information about the subscriber, * as well as a condition for notification, a mark that the subscriber is protected and properties to watch. */ type SubscriptionOptions = { notifyCondition?: (state: T) => boolean; protect?: boolean; properties?: Array; }; type CustomComparator = (a: T, b: T) => boolean; type DefaultComparator = "none" | "ref" | "shallow" | "custom"; type BaseModifyOptions = { skipComparison?: boolean; comparatorOverride?: DefaultComparator; customComparatorOverride?: CustomComparator; afterUpdate: () => void; skipGenerationIncrement?: boolean; }; type SetOptions = Omit, "afterUpdate">; type UpdateOptions = Omit, "afterUpdate">; interface StatemanjsComputedAPI { /** Get current state */ get(): T; /** * The method of subscribing to the status change. * Accepts a callback function (subscription callback), * which will be called at each update, and a subscription options object. * In the options, you can specify information about the subscription, * as well as specify the condition under which the subscriber will be notified * and mark the subscriber as protected. All subscribers are unprotected by default. * Protected subscribers can only be unsubscribed using the unsubscribe method returned by this method. * Returns the unsubscribe callback function. * * @param subscriptionCb A function that runs on every update. * @param subscriptionOptions Additional information and notification condition. * @returns Unsubscribe callback function. */ subscribe(subscriptionCb: SubscriptionCb, subscriptionOptions?: SubscriptionOptions): UnsubscribeCb; /** Remove all unprotected subscribers */ unsubscribeAll(): void; /** * Returns count of all active subscribers. * @returns number. */ getActiveSubscribersCount(): number; /** * Unwrap a proxy object to a regular JavaScript object * @returns unwrapped state */ unwrap(): T; } /** * Public API. * Interacts with the @see {StatemanjsBaseAPI}. */ interface StatemanjsAPI { /** * Accepts a new state and compares it with the current one. * Nothing will happen if the passed value is equal to the current one. * @param newState New state. * @returns Status of operation. */ set(newState: T, options?: SetOptions): boolean; /** Get current state */ get(): T; /** * The method of subscribing to the status change. * Accepts a callback function (subscription callback), * which will be called at each update, and a subscription options object. * In the options, you can specify information about the subscription, * as well as specify the condition under which the subscriber will be notified * and mark the subscriber as protected. All subscribers are unprotected by default. * Protected subscribers can only be unsubscribed using the unsubscribe method returned by this method. * Returns the unsubscribe callback function. * * @param subscriptionCb A function that runs on every update. * @param subscriptionOptions Additional information and notification condition. * @returns Unsubscribe callback function. */ subscribe(subscriptionCb: SubscriptionCb, subscriptionOptions?: SubscriptionOptions): UnsubscribeCb; /** Remove all unprotected subscribers */ unsubscribeAll(): void; /** * Returns count of all active subscribers. * @returns number. */ getActiveSubscribersCount(): number; /** * Flexible state update. * @param updateCb Callback for state updates. */ update(updateCb: UpdateCb, options?: UpdateOptions): boolean; /** * Unwrap a proxy object to a regular JavaScript object * @returns unwrapped state */ unwrap(): T; /** * Dispatch an async action * @param action An async action. It accepts a stateManager object, * which is used to access the current state. * @returns Promise. */ asyncAction(action: (stateManager: StatemanjsAPI) => Promise): Promise; /** * Create a computed state for a state property. * @param selectorFn A function that returns a value of a state property. * @returns A computed state. */ createSelector(selectorFn: (state: T) => E, subscriptionOptions?: SubscriptionOptions): StatemanjsComputedAPI; /** * Debug API. Allows you to use additional debugging functionality such as transactions. * Parameters are set when creating the state. * @see {DebugAPI} */ DEBUG?: DebugAPI; } type StatemanjsOptions = { transactionsLen?: number; customComparator?: CustomComparator; defaultComparator?: DefaultComparator; batch?: boolean; }; declare function createState(element: T, options?: StatemanjsOptions): StatemanjsAPI; declare function createComputedState(callback: () => T, deps: (StatemanjsAPI | StatemanjsComputedAPI)[], options?: StatemanjsOptions): StatemanjsComputedAPI; export { createComputedState, createState }; export type { StatemanjsAPI, StatemanjsComputedAPI, StatemanjsOptions, SubscriptionOptions };