stunk
Version:
Stunk is a lightweight, framework-agnostic state management library for JavaScript and TypeScript. It uses chunk-based state units for efficient updates, reactivity, and performance optimization in React, Vue(WIP), Svelte(Coming soon), and Vanilla JS/TS a
100 lines (94 loc) • 3.73 kB
TypeScript
import { M as Middleware, C as Chunk } from '../core-DAc7hZla.js';
/**
* Middleware that logs every value passed to `set()` to the console.
*
* @example
* const count = chunk(0, { middleware: [logger()] });
* count.set(5); // logs: "Setting value: 5"
*/
declare function logger<T>(): Middleware<T>;
/**
* Middleware that throws if a numeric value is set below zero.
*
* @example
* const balance = chunk(100, { middleware: [nonNegativeValidator] });
* balance.set(-1); // throws: "Value must be non-negative!"
*/
declare const nonNegativeValidator: Middleware<number>;
interface ChunkWithHistory<T> extends Chunk<T> {
/** Reverts to the previous state (if available). */
undo: () => void;
/** Moves to the next state (if available). */
redo: () => void;
/** Returns true if there is a previous state to revert to. */
canUndo: () => boolean;
/** Returns true if there is a next state to move to. */
canRedo: () => boolean;
/** Returns an array of all the values in the history. */
getHistory: () => T[];
/** Clears the history, keeping only the current value. */
clearHistory: () => void;
}
/**
* Wraps a chunk with undo/redo history tracking.
*
* Every `set()` call is recorded. `undo()` and `redo()` move through the stack.
* Branching is supported — calling `set()` after `undo()` discards forward history.
*
* @param baseChunk - The chunk to wrap.
* @param options.maxHistory - Max entries to keep (default: 100).
* @param options.skipDuplicates - `true` skips strictly equal values.
* `'shallow'` also skips shallowly equal objects.
*
* @example
* const count = chunk(0);
* const tracked = history(count);
* tracked.set(1); tracked.set(2);
* tracked.undo(); // 1
* tracked.redo(); // 2
*/
declare function history<T>(baseChunk: Chunk<T>, options?: {
maxHistory?: number;
/**
* true — skip entries that are strictly equal (===) to the current value.
* 'shallow' — also skip entries that are shallowly equal to the current value.
*/
skipDuplicates?: boolean | "shallow";
}): ChunkWithHistory<T>;
interface PersistOptions<T> {
/** Storage key (required). */
key: string;
/** Storage engine (default: localStorage). */
storage?: Storage;
/** Serialize value to string (default: JSON.stringify). */
serialize?: (value: T) => string;
/** Deserialize string to value (default: JSON.parse). */
deserialize?: (value: string) => T;
/** Called on load/save errors and type mismatches. */
onError?: (error: Error, operation: 'load' | 'save') => void;
}
interface PersistedChunk<T> extends Chunk<T> {
/** Remove the persisted key from storage without destroying the chunk. */
clearStorage: () => void;
}
/**
* Wraps a chunk with automatic persistence to a storage engine.
*
* Loads any saved value on creation. Saves on every `set()`.
* Gracefully disabled in SSR when no storage is available.
*
* @param baseChunk - The chunk to wrap.
* @param options.key - Storage key (required).
* @param options.storage - Storage engine (default: `localStorage`).
* @param options.serialize - Custom serializer (default: `JSON.stringify`).
* @param options.deserialize - Custom deserializer (default: `JSON.parse`).
* @param options.onError - Called on load/save errors or type mismatches.
*
* @example
* const user = chunk({ name: 'Alice' });
* const persisted = persist(user, { key: 'user' });
* persisted.set({ name: 'Bob' }); // saved to localStorage
* persisted.clearStorage(); // removes the key
*/
declare function persist<T>(baseChunk: Chunk<T>, options: PersistOptions<T>): PersistedChunk<T>;
export { history, logger, nonNegativeValidator, persist };