stunk 2.0.0 → 2.1.0

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.
Files changed (40) hide show
  1. package/README.md +1 -1
  2. package/dist/core/asyncChunk.d.ts +4 -4
  3. package/dist/core/asyncChunk.js +2 -3
  4. package/dist/core/computed.js +36 -24
  5. package/dist/core/selector.js +3 -17
  6. package/dist/core/types.d.ts +3 -3
  7. package/dist/use-react/hooks/useAsyncChunk.d.ts +3 -3
  8. package/dist/use-react/hooks/useAsyncChunk.js +1 -1
  9. package/package.json +26 -14
  10. package/jest.config.js +0 -4
  11. package/src/core/asyncChunk.ts +0 -83
  12. package/src/core/computed.ts +0 -65
  13. package/src/core/core.ts +0 -128
  14. package/src/core/selector.ts +0 -27
  15. package/src/core/types.ts +0 -17
  16. package/src/index.ts +0 -10
  17. package/src/middleware/history.ts +0 -113
  18. package/src/middleware/index.ts +0 -7
  19. package/src/middleware/logger.ts +0 -6
  20. package/src/middleware/persistence.ts +0 -45
  21. package/src/middleware/validator.ts +0 -8
  22. package/src/use-react/hooks/useAsyncChunk.ts +0 -38
  23. package/src/use-react/hooks/useChunk.ts +0 -40
  24. package/src/use-react/hooks/useChunkProperty.ts +0 -21
  25. package/src/use-react/hooks/useChunkValue.ts +0 -15
  26. package/src/use-react/hooks/useChunkValues.ts +0 -35
  27. package/src/use-react/hooks/useComputed.ts +0 -34
  28. package/src/use-react/hooks/useDerive.ts +0 -15
  29. package/src/use-react/index.ts +0 -9
  30. package/src/utils.ts +0 -103
  31. package/tests/async-chunk.test.ts +0 -215
  32. package/tests/batch-chunk.test.ts +0 -108
  33. package/tests/chunk.test.ts +0 -189
  34. package/tests/computed.test.ts +0 -93
  35. package/tests/history.test.ts +0 -99
  36. package/tests/middleware.test.ts +0 -37
  37. package/tests/persist.test.ts +0 -57
  38. package/tests/select-chunk.test.ts +0 -133
  39. package/tests/update.test.ts +0 -70
  40. package/tsconfig.json +0 -23
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Stunk
2
2
 
3
- A lightweight, reactive state management library for TypeScript/JavaScript applications. Stunk combines atomic state management with powerful features like middleware, time travel, and async state handling.
3
+ Stunk is a lightweight, framework-agnostic state management library built on atomic state principles. It simplifies state management by breaking state into manageable "chunks", ensuring efficient updates and reactivity.
4
4
 
5
5
  - **Pronunciation**: _Stunk_ (A playful blend of "state" and "chunk")
6
6
 
@@ -1,11 +1,11 @@
1
1
  import { Chunk } from "./core";
2
2
  import { AsyncChunkOpt } from "./types";
3
- export interface AsyncState<T> {
3
+ export interface AsyncState<T, E extends Error> {
4
4
  loading: boolean;
5
- error: Error | null;
5
+ error: E | null;
6
6
  data: T | null;
7
7
  }
8
- export interface AsyncChunk<T> extends Chunk<AsyncState<T>> {
8
+ export interface AsyncChunk<T, E extends Error = Error> extends Chunk<AsyncState<T, E>> {
9
9
  /**
10
10
  * Reload the data from the source.
11
11
  */
@@ -19,4 +19,4 @@ export interface AsyncChunk<T> extends Chunk<AsyncState<T>> {
19
19
  */
20
20
  reset: () => void;
21
21
  }
22
- export declare function asyncChunk<T>(fetcher: () => Promise<T>, options?: AsyncChunkOpt<T>): AsyncChunk<T>;
22
+ export declare function asyncChunk<T, E extends Error = Error>(fetcher: () => Promise<T>, options?: AsyncChunkOpt<T, E>): AsyncChunk<T, E>;
@@ -18,10 +18,9 @@ export function asyncChunk(fetcher, options = {}) {
18
18
  await new Promise(resolve => setTimeout(resolve, retryDelay));
19
19
  return fetchData(retries - 1);
20
20
  }
21
- const errorObj = error instanceof Error ? error : new Error(String(error));
22
- baseChunk.set({ loading: false, error: errorObj, data: baseChunk.get().data });
21
+ baseChunk.set({ loading: false, error: error, data: baseChunk.get().data });
23
22
  if (onError) {
24
- onError(errorObj);
23
+ onError(error);
25
24
  }
26
25
  }
27
26
  };
@@ -1,42 +1,54 @@
1
1
  import { chunk } from "./core";
2
2
  export function computed(dependencies, computeFn) {
3
- let isDirty = false; // Initialized to false
4
- let cachedValue = computeFn(...dependencies.map(d => d.get()));
3
+ const initialValues = dependencies.map(dep => dep.get());
4
+ let cachedValue = computeFn(...initialValues);
5
+ let isDirty = false;
6
+ let lastDependencyValues = [...initialValues];
7
+ const computedChunk = chunk(cachedValue);
8
+ const originalSet = computedChunk.set;
5
9
  const recalculate = () => {
6
- const values = dependencies.map(dep => dep.get());
7
- cachedValue = computeFn(...values);
8
- isDirty = false; // Reset to false after recomputation
10
+ if (!isDirty)
11
+ return;
12
+ const currentValues = dependencies.map(dep => dep.get());
13
+ const hasChanges = currentValues.some((val, i) => val !== lastDependencyValues[i]);
14
+ if (hasChanges) {
15
+ lastDependencyValues = [...currentValues];
16
+ const newValue = computeFn(...currentValues);
17
+ if (newValue !== cachedValue) {
18
+ cachedValue = newValue;
19
+ originalSet(newValue);
20
+ }
21
+ }
22
+ // Always clear the dirty flag after recalculation
23
+ isDirty = false;
9
24
  };
10
- const computedChunk = chunk(cachedValue);
11
- const originalGet = computedChunk.get;
12
25
  computedChunk.get = () => {
13
26
  if (isDirty) {
14
27
  recalculate();
15
- computedChunk.set(cachedValue); // Update the chunk value after recomputation
16
28
  }
17
- return cachedValue; // Return the cached value directly
29
+ return cachedValue;
18
30
  };
19
- const lastValues = dependencies.map(dep => dep.get());
20
- dependencies.forEach((dep, index) => {
21
- dep.subscribe(() => {
22
- const newValue = dep.get();
23
- if (newValue !== lastValues[index] && !isDirty) {
24
- lastValues[index] = newValue;
25
- isDirty = true;
26
- }
27
- });
28
- });
31
+ const unsub = dependencies.map(dep => dep.subscribe(() => {
32
+ if (!isDirty) {
33
+ isDirty = true;
34
+ recalculate();
35
+ }
36
+ }));
29
37
  return {
30
38
  ...computedChunk,
31
39
  isDirty: () => isDirty,
32
40
  recompute: () => {
33
- if (isDirty) {
34
- recalculate();
35
- computedChunk.set(cachedValue); // Update the chunk value after manual recomputation
36
- }
41
+ isDirty = true;
42
+ recalculate();
37
43
  },
38
44
  set: () => {
39
- throw new Error('Cannot directly set a computed value');
45
+ throw new Error('Cannot set values directly on computed. Modify the source chunk instead.');
46
+ },
47
+ destroy: () => {
48
+ unsub.forEach(cleanup => cleanup());
49
+ if (computedChunk.destroy) {
50
+ computedChunk.destroy();
51
+ }
40
52
  }
41
53
  };
42
54
  }
@@ -1,23 +1,9 @@
1
- import { chunk } from "./core";
1
+ import { computed } from "./computed";
2
2
  export function select(sourceChunk, selector) {
3
- const initialValue = selector(sourceChunk.get());
4
- const selectedChunk = chunk(initialValue);
5
- let previousSelected = initialValue;
6
- // Subscribe to source changes with equality checking
7
- sourceChunk.subscribe((newValue) => {
8
- const newSelected = selector(newValue);
9
- // Only update if the selected value actually changed
10
- if (!Object.is(newSelected, previousSelected)) {
11
- previousSelected = newSelected;
12
- selectedChunk.set(newSelected);
13
- }
14
- });
15
- // Return read-only version of the chunk
16
3
  return {
17
- ...selectedChunk,
18
- // Prevent setting values directly on the selector
4
+ ...computed([sourceChunk], (value) => selector(value)),
19
5
  set: () => {
20
6
  throw new Error('Cannot set values directly on a selector. Modify the source chunk instead.');
21
- }
7
+ },
22
8
  };
23
9
  }
@@ -1,11 +1,11 @@
1
1
  import { AsyncChunk } from "./asyncChunk";
2
- export type AsyncChunkOpt<T> = {
2
+ export type AsyncChunkOpt<T, E extends Error> = {
3
3
  initialData?: T | null;
4
- onError?: (error: Error) => void;
4
+ onError?: (error: E) => void;
5
5
  retryCount?: number;
6
6
  retryDelay?: number;
7
7
  };
8
- export type InferAsyncData<T> = T extends AsyncChunk<infer U> ? U : never;
8
+ export type InferAsyncData<T> = T extends AsyncChunk<infer U, Error> ? U : never;
9
9
  export type CombinedData<T> = {
10
10
  [K in keyof T]: InferAsyncData<T[K]> | null;
11
11
  };
@@ -3,11 +3,11 @@ import { AsyncChunk, AsyncState } from "../../core/asyncChunk";
3
3
  * A hook that handles asynchronous state with built-in reactivity.
4
4
  * Provides loading, error, and data states.
5
5
  */
6
- export declare function useAsyncChunk<T>(asyncChunk: AsyncChunk<T>): {
7
- state: AsyncState<T>;
6
+ export declare function useAsyncChunk<T, E extends Error>(asyncChunk: AsyncChunk<T, E>): {
7
+ state: AsyncState<T, E>;
8
8
  data: T | null;
9
9
  loading: boolean;
10
- error: Error | null;
10
+ error: E | null;
11
11
  reload: () => Promise<void>;
12
12
  mutate: (mutator: (currentData: T | null) => T) => void;
13
13
  reset: () => void;
@@ -22,6 +22,6 @@ export function useAsyncChunk(asyncChunk) {
22
22
  error,
23
23
  reload,
24
24
  mutate,
25
- reset
25
+ reset,
26
26
  };
27
27
  }
package/package.json CHANGED
@@ -1,17 +1,26 @@
1
1
  {
2
2
  "name": "stunk",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
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
+ "scripts": {
6
+ "build": "tsc",
7
+ "test": "vitest",
8
+ "prepublishOnly": "vitest && tsc",
9
+ "prepare": "npm run build"
10
+ },
5
11
  "repository": {
6
12
  "type": "git",
7
13
  "url": "https://github.com/I-am-abdulazeez/stunk"
8
14
  },
9
- "homepage": "https://github.com/I-am-abdulazeez/stunk#readme",
15
+ "homepage": "https://stunk.vercel.app/",
10
16
  "bugs": {
11
17
  "url": "https://github.com/I-am-abdulazeez/stunk/issues"
12
18
  },
13
19
  "main": "dist/index.js",
14
20
  "types": "dist/index.d.ts",
21
+ "files": [
22
+ "dist"
23
+ ],
15
24
  "exports": {
16
25
  ".": {
17
26
  "import": "./dist/index.js",
@@ -24,14 +33,12 @@
24
33
  "./react": {
25
34
  "import": "./dist/use-react/index.js",
26
35
  "types": "./dist/types/use-react/index.d.ts"
36
+ },
37
+ "./vue": {
38
+ "import": "./dist/use-vue/index.js",
39
+ "types": "./dist/types/use-vue/index.d.ts"
27
40
  }
28
41
  },
29
- "scripts": {
30
- "build": "tsc",
31
- "test": "jest --runInBand",
32
- "prepare": "npm run build"
33
- },
34
- "testEnvironment": "jsdom",
35
42
  "keywords": [
36
43
  "state-management",
37
44
  "atomic-state",
@@ -64,16 +71,21 @@
64
71
  ],
65
72
  "license": "MIT",
66
73
  "devDependencies": {
67
- "@types/jest": "^29.5.14",
74
+ "@testing-library/dom": "^10.4.0",
75
+ "@testing-library/react": "^16.2.0",
76
+ "@testing-library/vue": "^8.1.0",
68
77
  "@types/react": "^19.0.10",
69
- "jest": "^29.7.0",
70
- "jest-environment-jsdom": "^29.7.0",
78
+ "@vitejs/plugin-react": "^4.3.4",
79
+ "@vitejs/plugin-vue": "^5.2.1",
80
+ "jsdom": "^26.0.0",
71
81
  "react": "^19.0.0",
72
82
  "react-dom": "^19.0.0",
73
- "ts-jest": "^29.2.5",
74
- "typescript": "^5.0.0"
83
+ "typescript": "^5.0.0",
84
+ "vitest": "^3.0.8",
85
+ "vue": "^3.5.13"
75
86
  },
76
87
  "peerDependencies": {
77
- "react": "^19.0.0"
88
+ "react": "^19.0.0",
89
+ "vue": "^3.5.13"
78
90
  }
79
91
  }
package/jest.config.js DELETED
@@ -1,4 +0,0 @@
1
- module.exports = {
2
- preset: "ts-jest",
3
- testEnvironment: "node",
4
- };
@@ -1,83 +0,0 @@
1
- import { chunk, Chunk } from "./core";
2
- import { AsyncChunkOpt } from "./types";
3
-
4
- export interface AsyncState<T> {
5
- loading: boolean;
6
- error: Error | null;
7
- data: T | null;
8
- }
9
-
10
- export interface AsyncChunk<T> extends Chunk<AsyncState<T>> {
11
- /**
12
- * Reload the data from the source.
13
- */
14
- reload: () => Promise<void>;
15
- /**
16
- * Mutate the data directly.
17
- */
18
- mutate: (mutator: (currentData: T | null) => T) => void;
19
- /**
20
- * Reset the state to the initial value.
21
- */
22
- reset: () => void;
23
- }
24
-
25
- export function asyncChunk<T>(fetcher: () => Promise<T>, options: AsyncChunkOpt<T> = {}): AsyncChunk<T> {
26
- const {
27
- initialData = null,
28
- onError,
29
- retryCount = 0,
30
- retryDelay = 1000,
31
- } = options;
32
-
33
- const initialState: AsyncState<T> = {
34
- loading: true,
35
- error: null,
36
- data: initialData,
37
- };
38
-
39
- const baseChunk = chunk(initialState);
40
-
41
- const fetchData = async (retries = retryCount): Promise<void> => {
42
- baseChunk.set({ ...baseChunk.get(), loading: true, error: null });
43
-
44
- try {
45
- const data = await fetcher();
46
- baseChunk.set({ loading: false, error: null, data });
47
- } catch (error) {
48
- if (retries > 0) {
49
- await new Promise(resolve => setTimeout(resolve, retryDelay));
50
- return fetchData(retries - 1);
51
- }
52
-
53
- const errorObj = error instanceof Error ? error : new Error(String(error));
54
- baseChunk.set({ loading: false, error: errorObj, data: baseChunk.get().data });
55
-
56
- if (onError) {
57
- onError(errorObj);
58
- }
59
-
60
- }
61
- }
62
-
63
- // Initial fetch
64
- fetchData();
65
-
66
- const asyncChunkInstance: AsyncChunk<T> = {
67
- ...baseChunk,
68
- reload: async () => {
69
- await fetchData();
70
- },
71
- mutate: (mutator: (currentData: T | null) => T) => {
72
- const currentState = baseChunk.get();
73
- const newData = mutator(currentState.data);
74
- baseChunk.set({ ...currentState, data: newData });
75
- },
76
- reset: () => {
77
- baseChunk.set(initialState);
78
- fetchData();
79
- },
80
- }
81
-
82
- return asyncChunkInstance;
83
- }
@@ -1,65 +0,0 @@
1
- import { Chunk, chunk } from "./core";
2
-
3
- // Helper type to extract the value type from a Chunk
4
- export type ChunkValue<T> = T extends Chunk<infer U> ? U : never;
5
-
6
- // Helper type to transform an array of Chunks into an array of their value types
7
- export type DependencyValues<T extends Chunk<any>[]> = {
8
- [K in keyof T]: T[K] extends Chunk<any> ? ChunkValue<T[K]> : never;
9
- };
10
-
11
- export interface Computed<T> extends Chunk<T> {
12
- isDirty: () => boolean;
13
- recompute: () => void;
14
- }
15
-
16
- export function computed<TDeps extends Chunk<any>[], TResult>(
17
- dependencies: [...TDeps],
18
- computeFn: (...args: DependencyValues<TDeps>) => TResult
19
- ): Computed<TResult> {
20
- let isDirty = false; // Initialized to false
21
- let cachedValue: TResult = computeFn(...dependencies.map(d => d.get()) as DependencyValues<TDeps>);
22
-
23
- const recalculate = () => {
24
- const values = dependencies.map(dep => dep.get()) as DependencyValues<TDeps>;
25
- cachedValue = computeFn(...values);
26
- isDirty = false; // Reset to false after recomputation
27
- };
28
-
29
- const computedChunk = chunk(cachedValue);
30
-
31
- const originalGet = computedChunk.get;
32
- computedChunk.get = () => {
33
- if (isDirty) {
34
- recalculate();
35
- computedChunk.set(cachedValue); // Update the chunk value after recomputation
36
- }
37
- return cachedValue; // Return the cached value directly
38
- };
39
-
40
- const lastValues = dependencies.map(dep => dep.get());
41
-
42
- dependencies.forEach((dep, index) => {
43
- dep.subscribe(() => {
44
- const newValue = dep.get();
45
- if (newValue !== lastValues[index] && !isDirty) {
46
- lastValues[index] = newValue;
47
- isDirty = true;
48
- }
49
- });
50
- });
51
-
52
- return {
53
- ...computedChunk,
54
- isDirty: () => isDirty,
55
- recompute: () => {
56
- if (isDirty) {
57
- recalculate();
58
- computedChunk.set(cachedValue); // Update the chunk value after manual recomputation
59
- }
60
- },
61
- set: () => {
62
- throw new Error('Cannot directly set a computed value');
63
- }
64
- };
65
- }
package/src/core/core.ts DELETED
@@ -1,128 +0,0 @@
1
- import { processMiddleware } from "../utils";
2
-
3
- export type Subscriber<T> = (newValue: T) => void;
4
- export type Middleware<T> = (value: T, next: (newValue: T) => void) => void;
5
-
6
- export interface Chunk<T> {
7
- /** Get the current value of the chunk. */
8
- get: () => T;
9
- /** Set a new value for the chunk & Update existing value efficiently. */
10
- set: (newValueOrUpdater: T | ((currentValue: T) => T)) => void;
11
- /** Subscribe to changes in the chunk. Returns an unsubscribe function. */
12
- subscribe: (callback: Subscriber<T>) => () => void;
13
- /** Create a derived chunk based on this chunk's value. */
14
- derive: <D>(fn: (value: T) => D) => Chunk<D>;
15
- /** Reset the chunk to its initial value. */
16
- reset: () => void;
17
- /** Destroy the chunk and all its subscribers. */
18
- destroy: () => void;
19
- }
20
-
21
- let batchDepth = 0;
22
- const batchQueue = new Set<() => void>();
23
-
24
- export function batch(callback: () => void) {
25
- batchDepth++;
26
- try {
27
- callback();
28
- } finally {
29
- batchDepth--;
30
- if (batchDepth === 0) {
31
- // Execute all queued updates
32
- batchQueue.forEach(update => update());
33
- batchQueue.clear();
34
- }
35
- }
36
- }
37
-
38
- export function chunk<T>(initialValue: T, middleware: Middleware<T>[] = []): Chunk<T> {
39
- if (initialValue === undefined || initialValue === null) {
40
- throw new Error("Initial value cannot be undefined or null.");
41
- }
42
-
43
- let value = initialValue;
44
- const subscribers = new Set<Subscriber<T>>();
45
- let isDirty = false;
46
-
47
- const notifySubscribers = () => {
48
- if (batchDepth > 0) {
49
- if (!isDirty) {
50
- isDirty = true;
51
- batchQueue.add(() => {
52
- if (isDirty) {
53
- subscribers.forEach((subscriber) => subscriber(value));
54
- isDirty = false;
55
- }
56
- });
57
- }
58
- } else {
59
- subscribers.forEach((subscriber) => subscriber(value));
60
- }
61
- }
62
-
63
- const get = () => value;
64
-
65
- const set = (newValueOrUpdater: T | ((currentValue: T) => T)) => {
66
- let newValue: T;
67
-
68
- if (typeof newValueOrUpdater === 'function') {
69
- // Handle updater function
70
- newValue = (newValueOrUpdater as (currentValue: T) => T)(value);
71
- } else {
72
- // Handle direct value assignment
73
- newValue = newValueOrUpdater;
74
- }
75
-
76
- const processedValue = processMiddleware(newValue, middleware);
77
-
78
- if (processedValue !== value) {
79
- value = processedValue as T & {};
80
- notifySubscribers();
81
- }
82
- };
83
-
84
- const subscribe = (callback: Subscriber<T>) => {
85
- if (typeof callback !== "function") {
86
- throw new Error("Callback must be a function.");
87
- }
88
- if (subscribers.has(callback)) {
89
- console.warn("Callback is already subscribed. This may lead to duplicate updates.");
90
- }
91
- subscribers.add(callback);
92
- callback(value);
93
-
94
- return () => subscribers.delete(callback);
95
- };
96
-
97
- const reset = () => {
98
- value = initialValue;
99
- subscribers.forEach((subscriber) => subscriber(value));
100
- };
101
-
102
- const destroy = () => {
103
- if (subscribers.size > 0) {
104
- console.warn("Destroying chunk with active subscribers. This may lead to memory leaks.");
105
- }
106
- // Just clear subscribers without calling unsubscribe
107
- subscribers.clear();
108
- value = initialValue;
109
- };
110
-
111
-
112
- const derive = <D>(fn: (value: T) => D) => {
113
- if (typeof fn !== "function") {
114
- throw new Error("Derive function must be a function.");
115
- }
116
- const derivedValue = fn(value);
117
- const derivedChunk = chunk(derivedValue);
118
-
119
- subscribe(() => {
120
- const newDerivedValue = fn(value);
121
- derivedChunk.set(newDerivedValue);
122
- });
123
-
124
- return derivedChunk;
125
- };
126
-
127
- return { get, set, subscribe, derive, reset, destroy };
128
- }
@@ -1,27 +0,0 @@
1
- import { chunk, Chunk } from "./core";
2
-
3
- export function select<T, S>(sourceChunk: Chunk<T>, selector: (value: T) => S): Chunk<S> {
4
- const initialValue = selector(sourceChunk.get());
5
- const selectedChunk = chunk(initialValue);
6
- let previousSelected = initialValue;
7
-
8
- // Subscribe to source changes with equality checking
9
- sourceChunk.subscribe((newValue) => {
10
- const newSelected = selector(newValue);
11
-
12
- // Only update if the selected value actually changed
13
- if (!Object.is(newSelected, previousSelected)) {
14
- previousSelected = newSelected;
15
- selectedChunk.set(newSelected);
16
- }
17
- });
18
-
19
- // Return read-only version of the chunk
20
- return {
21
- ...selectedChunk,
22
- // Prevent setting values directly on the selector
23
- set: () => {
24
- throw new Error('Cannot set values directly on a selector. Modify the source chunk instead.');
25
- }
26
- };
27
- }
package/src/core/types.ts DELETED
@@ -1,17 +0,0 @@
1
- import { AsyncChunk } from "./asyncChunk";
2
-
3
- export type AsyncChunkOpt<T> = {
4
- initialData?: T | null;
5
- onError?: (error: Error) => void;
6
- retryCount?: number;
7
- retryDelay?: number;
8
- }
9
-
10
- export type InferAsyncData<T> = T extends AsyncChunk<infer U> ? U : never;
11
-
12
- export type CombinedData<T> = { [K in keyof T]: InferAsyncData<T[K]> | null };
13
- export type CombinedState<T> = {
14
- loading: boolean;
15
- error: Error | null;
16
- data: CombinedData<T>;
17
- };
package/src/index.ts DELETED
@@ -1,10 +0,0 @@
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
-
6
- export { combineAsyncChunks, once, isChunk, isValidChunkValue } from './utils';
7
-
8
- export type { Chunk, Middleware } from './core/core';
9
-
10
- export * as middleware from "./middleware";