stunk 1.4.5 → 1.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ import { Chunk } from "./core";
2
+ import { AsyncChunkOpt } from "./types";
3
+ export interface AsyncState<T> {
4
+ loading: boolean;
5
+ error: Error | null;
6
+ data: T | null;
7
+ }
8
+ export interface AsyncChunk<T> extends Chunk<AsyncState<T>> {
9
+ /**
10
+ * Reload the data from the source.
11
+ */
12
+ reload: () => Promise<void>;
13
+ /**
14
+ * Mutate the data directly.
15
+ */
16
+ mutate: (mutator: (currentData: T | null) => T) => void;
17
+ /**
18
+ * Reset the state to the initial value.
19
+ */
20
+ reset: () => void;
21
+ }
22
+ export declare function asyncChunk<T>(fetcher: () => Promise<T>, options?: AsyncChunkOpt<T>): AsyncChunk<T>;
@@ -0,0 +1,10 @@
1
+ import { Chunk } from "./core";
2
+ export type ChunkValue<T> = T extends Chunk<infer U> ? U : never;
3
+ export type DependencyValues<T extends Chunk<any>[]> = {
4
+ [K in keyof T]: T[K] extends Chunk<any> ? ChunkValue<T[K]> : never;
5
+ };
6
+ export interface Computed<T> extends Chunk<T> {
7
+ isDirty: () => boolean;
8
+ recompute: () => void;
9
+ }
10
+ export declare function computed<TDeps extends Chunk<any>[], TResult>(dependencies: [...TDeps], computeFn: (...args: DependencyValues<TDeps>) => TResult): Computed<TResult>;
@@ -0,0 +1,20 @@
1
+ export type Subscriber<T> = (newValue: T) => void;
2
+ export type Middleware<T> = (value: T, next: (newValue: T) => void) => void;
3
+ export interface Chunk<T> {
4
+ /** Get the current value of the chunk. */
5
+ get: () => T;
6
+ /** Set a new value for the chunk. */
7
+ set: (value: T) => void;
8
+ /** Update existing value efficiently */
9
+ update: (updater: (currentValue: T) => T) => void;
10
+ /** Subscribe to changes in the chunk. Returns an unsubscribe function. */
11
+ subscribe: (callback: Subscriber<T>) => () => void;
12
+ /** Create a derived chunk based on this chunk's value. */
13
+ derive: <D>(fn: (value: T) => D) => Chunk<D>;
14
+ /** Reset the chunk to its initial value. */
15
+ reset: () => void;
16
+ /** Destroy the chunk and all its subscribers. */
17
+ destroy: () => void;
18
+ }
19
+ export declare function batch(callback: () => void): void;
20
+ export declare function chunk<T>(initialValue: T, middleware?: Middleware<T>[]): Chunk<T>;
@@ -0,0 +1,2 @@
1
+ import { Chunk } from "./core";
2
+ export declare function select<T, S>(sourceChunk: Chunk<T>, selector: (value: T) => S): Chunk<S>;
@@ -0,0 +1,16 @@
1
+ import { AsyncChunk } from "./asyncChunk";
2
+ export type AsyncChunkOpt<T> = {
3
+ initialData?: T | null;
4
+ onError?: (error: Error) => void;
5
+ retryCount?: number;
6
+ retryDelay?: number;
7
+ };
8
+ export type InferAsyncData<T> = T extends AsyncChunk<infer U> ? U : never;
9
+ export type CombinedData<T> = {
10
+ [K in keyof T]: InferAsyncData<T[K]> | null;
11
+ };
12
+ export type CombinedState<T> = {
13
+ loading: boolean;
14
+ error: Error | null;
15
+ data: CombinedData<T>;
16
+ };
@@ -0,0 +1,7 @@
1
+ export { chunk, batch } from './core/core';
2
+ export { asyncChunk } from './core/asyncChunk';
3
+ export { computed } from './core/computed';
4
+ export { select } from './core/selector';
5
+ export { combineAsyncChunks, once, isChunk, isValidChunkValue } from './utils';
6
+ export type { Chunk, Middleware } from './core/core';
7
+ export * as middleware from "./middleware";
@@ -0,0 +1,30 @@
1
+ import { Chunk } from "../core/core";
2
+ export interface ChunkWithHistory<T> extends Chunk<T> {
3
+ /**
4
+ * Reverts to the previous state (if available).
5
+ */
6
+ undo: () => void;
7
+ /**
8
+ * Moves to the next state (if available).
9
+ */
10
+ redo: () => void;
11
+ /**
12
+ * Returns true if there is a previous state to revert to.
13
+ */
14
+ canUndo: () => boolean;
15
+ /**
16
+ * Returns true if there is a next state to move to.
17
+ */
18
+ canRedo: () => boolean;
19
+ /**
20
+ * Returns an array of all the values in the history.
21
+ */
22
+ getHistory: () => T[];
23
+ /**
24
+ * Clears the history, keeping only the current value.
25
+ */
26
+ clearHistory: () => void;
27
+ }
28
+ export declare function withHistory<T>(baseChunk: Chunk<T>, options?: {
29
+ maxHistory?: number;
30
+ }): ChunkWithHistory<T>;
@@ -0,0 +1,4 @@
1
+ export { logger } from "./logger";
2
+ export { nonNegativeValidator } from "./validator";
3
+ export { withHistory } from "./history";
4
+ export { withPersistence } from './persistence';
@@ -0,0 +1,2 @@
1
+ import { Middleware } from "../core/core";
2
+ export declare const logger: Middleware<any>;
@@ -0,0 +1,8 @@
1
+ import { Chunk } from "../core/core";
2
+ export interface PersistOptions<T> {
3
+ key: string;
4
+ storage?: Storage;
5
+ serialize?: (value: T) => string;
6
+ deserialize?: (value: string) => T;
7
+ }
8
+ export declare function withPersistence<T>(baseChunk: Chunk<T>, options: PersistOptions<T>): Chunk<T>;
@@ -0,0 +1,2 @@
1
+ import { Middleware } from "../core/core";
2
+ export declare const nonNegativeValidator: Middleware<number>;
@@ -0,0 +1,14 @@
1
+ import { AsyncChunk, AsyncState } from "../../core/asyncChunk";
2
+ /**
3
+ * A hook that handles asynchronous state with built-in reactivity.
4
+ * Provides loading, error, and data states.
5
+ */
6
+ export declare function useAsyncChunk<T>(asyncChunk: AsyncChunk<T>): {
7
+ state: AsyncState<T>;
8
+ data: T | null;
9
+ loading: boolean;
10
+ error: Error | null;
11
+ reload: () => Promise<void>;
12
+ mutate: (mutator: (currentData: T | null) => T) => void;
13
+ reset: () => void;
14
+ };
@@ -0,0 +1,6 @@
1
+ import type { Chunk } from "../../core/core";
2
+ /**
3
+ * A lightweight hook that subscribes to a chunk and returns its current value, along with setters, selector, reset and destroy.
4
+ * Ensures reactivity and prevents unnecessary re-renders.
5
+ */
6
+ export declare function useChunk<T, S = T>(chunk: Chunk<T>, selector?: (value: T) => S): readonly [S, (value: T) => void, (updater: (currentValue: T) => T) => void, () => void, () => void];
@@ -0,0 +1,6 @@
1
+ import type { Chunk } from "../../core/core";
2
+ /**
3
+ * A hook that subscribes to a specific property of a chunk.
4
+ * This optimizes renders by only updating when the selected property changes.
5
+ */
6
+ export declare function useChunkProperty<T, K extends keyof T>(chunk: Chunk<T>, property: K): T[K];
@@ -0,0 +1,6 @@
1
+ import type { Chunk } from "../../core/core";
2
+ /**
3
+ * A lightweight hook that subscribes to a chunk and returns only its current value.
4
+ * Useful for read-only components that don't need to update the chunk.
5
+ */
6
+ export declare function useChunkValue<T, S = T>(chunk: Chunk<T>, selector?: (value: T) => S): S;
@@ -0,0 +1,8 @@
1
+ import type { Chunk } from "../../core/core";
2
+ /**
3
+ * Hook to read values from multiple chunks at once.
4
+ * Only re-renders when any of the chunk values change.
5
+ */
6
+ export declare function useChunkValues<T extends Chunk<any>[]>(chunks: [...T]): {
7
+ [K in keyof T]: T[K] extends Chunk<infer U> ? U : never;
8
+ };
@@ -0,0 +1,7 @@
1
+ import { DependencyValues } from "../../core/computed";
2
+ import type { Chunk } from "../../core/core";
3
+ /**
4
+ * A hook that computes a value based on multiple chunks.
5
+ * Automatically re-computes when any dependency changes.
6
+ */
7
+ export declare function useComputed<TDeps extends Chunk<any>[], TResult>(dependencies: [...TDeps], computeFn: (...args: DependencyValues<TDeps>) => TResult): TResult;
@@ -0,0 +1,6 @@
1
+ import type { Chunk } from "../../core/core";
2
+ /**
3
+ * A hook for creating a read-only derived value from a chunk.
4
+ * Ensures reactivity and updates when the source chunk changes.
5
+ */
6
+ export declare function useDerive<T, D>(chunk: Chunk<T>, fn: (value: T) => D): D;
@@ -0,0 +1,7 @@
1
+ export { useChunk } from './hooks/useChunk';
2
+ export { useDerive } from './hooks/useDerive';
3
+ export { useComputed } from './hooks/useComputed';
4
+ export { useChunkValue } from './hooks/useChunkValue';
5
+ export { useChunkProperty } from './hooks/useChunkProperty';
6
+ export { useChunkValues } from './hooks/useChunkValues';
7
+ export { useAsyncChunk } from './hooks/useAsyncChunk';
@@ -0,0 +1,14 @@
1
+ import { Chunk, Middleware } from "./core/core";
2
+ import { AsyncChunk } from "./core/asyncChunk";
3
+ import { InferAsyncData } from "./core/types";
4
+ export declare function isValidChunkValue(value: any): boolean;
5
+ export declare function isChunk<T>(value: any): value is Chunk<T>;
6
+ export declare function once<T>(fn: () => T): () => T;
7
+ export declare function combineAsyncChunks<T extends Record<string, AsyncChunk<any>>>(chunks: T): Chunk<{
8
+ loading: boolean;
9
+ error: Error | null;
10
+ data: {
11
+ [K in keyof T]: InferAsyncData<T[K]> | null;
12
+ };
13
+ }>;
14
+ export declare function processMiddleware<T>(initialValue: T, middleware?: Middleware<T>[]): T;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stunk",
3
- "version": "1.4.5",
3
+ "version": "1.4.6",
4
4
  "description": "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, Svelte, and Vanilla JS/TS applications.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -11,19 +11,19 @@
11
11
  "url": "https://github.com/I-am-abdulazeez/stunk/issues"
12
12
  },
13
13
  "main": "dist/index.js",
14
- "types": "dist/types/index.d.ts",
14
+ "types": "dist/index.d.ts",
15
15
  "exports": {
16
16
  ".": {
17
17
  "import": "./dist/index.js",
18
- "types": "./dist/types/index.d.ts"
18
+ "types": "./dist/index.d.ts"
19
19
  },
20
20
  "./middleware": {
21
21
  "import": "./dist/middleware/index.js",
22
- "types": "./dist/types/middleware/index.d.ts"
22
+ "types": "./dist/middleware/index.d.ts"
23
23
  },
24
24
  "./react": {
25
25
  "import": "./dist/use-react/index.js",
26
- "types": "./dist/types/use-react/index.d.ts"
26
+ "types": "./dist/use-react/index.d.ts"
27
27
  }
28
28
  },
29
29
  "scripts": {
package/tsconfig.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "moduleResolution": "Node",
6
6
  "outDir": "./dist",
7
7
  "declaration": true,
8
- "declarationDir": "./dist/types",
8
+ "declarationDir": "./dist",
9
9
  "baseUrl": "./src",
10
10
  "paths": {
11
11
  "stunk/middleware": ["middleware"],
@@ -18,6 +18,6 @@
18
18
  "esModuleInterop": true,
19
19
  "allowSyntheticDefaultImports": true
20
20
  },
21
- "include": ["src/**/*", "types/stunk.d.ts"],
21
+ "include": ["src/**/*"],
22
22
  "exclude": ["node_modules", "dist"]
23
23
  }
package/types/stunk.d.ts DELETED
@@ -1,15 +0,0 @@
1
- declare module 'stunk' {
2
- export type Subscriber<T> = (newValue: T) => void;
3
-
4
- export interface Chunk<T> {
5
- get: () => T;
6
- set: (value: T) => void;
7
- update: (updater: (currentValue: T) => T) => void;
8
- subscribe: (callback: Subscriber<T>) => () => void;
9
- derive: <D>(fn: (value: T) => D) => Chunk<D>;
10
- reset: () => void;
11
- destroy: () => void;
12
- }
13
-
14
- export function chunk<T>(initialValue: T): Chunk<T>;
15
- }