import { DeepReadonly } from "utility-types";
import ObservableSlim from "observable-slim";
export declare type DeepMutable<T> = T extends (...args: any[]) => any ? T : T extends Readonly<[any, ...any[]]> ? _DeepMutableObject<T> : T extends ReadonlyArray<any> ? _DeepMutableArray<T[number]> : T extends object ? _DeepMutableObject<T> : T;
export interface _DeepMutableArray<T> extends Array<DeepMutable<T>> {
}
export declare type _DeepMutableObject<T> = {
    -readonly [P in keyof T]: DeepMutable<T[P]>;
};
export declare type Transaction<T extends {}> = {
    source: string;
    changes: ObservableSlim.Change<T>[];
};
export interface Mutate<T extends object> {
    (mutator: (mutable: T) => void, no_log?: boolean): void;
    objs<T extends any[]>(objs: T, mutator: (...muts: DeepMutable<T>) => void, no_log?: boolean): void;
}
export declare function stasis<T extends {}>(state: T, on_change?: (tx: Transaction<T>) => unknown): {
    state: DeepReadonly<T>;
    log: Transaction<T>[];
    mutate: Mutate<T>;
};
