@tanstack/store 0.7.0 → 0.7.1
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.
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/store.cjs +16 -7
- package/dist/cjs/store.cjs.map +1 -1
- package/dist/cjs/store.d.cts +6 -1
- package/dist/cjs/types.cjs +7 -0
- package/dist/cjs/types.cjs.map +1 -0
- package/dist/cjs/types.d.cts +8 -0
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/store.d.ts +6 -1
- package/dist/esm/store.js +16 -7
- package/dist/esm/store.js.map +1 -1
- package/dist/esm/types.d.ts +8 -0
- package/dist/esm/types.js +7 -0
- package/dist/esm/types.js.map +1 -0
- package/package.json +5 -5
- package/src/store.ts +19 -5
- package/src/types.ts +14 -0
package/dist/cjs/index.cjs
CHANGED
|
@@ -3,10 +3,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const derived = require("./derived.cjs");
|
|
4
4
|
const effect = require("./effect.cjs");
|
|
5
5
|
const store = require("./store.cjs");
|
|
6
|
+
const types = require("./types.cjs");
|
|
6
7
|
const scheduler = require("./scheduler.cjs");
|
|
7
8
|
exports.Derived = derived.Derived;
|
|
8
9
|
exports.Effect = effect.Effect;
|
|
9
10
|
exports.Store = store.Store;
|
|
11
|
+
exports.isUpdaterFunction = types.isUpdaterFunction;
|
|
10
12
|
exports.__depsThatHaveWrittenThisTick = scheduler.__depsThatHaveWrittenThisTick;
|
|
11
13
|
exports.__derivedToStore = scheduler.__derivedToStore;
|
|
12
14
|
exports.__flush = scheduler.__flush;
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
|
package/dist/cjs/store.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const scheduler = require("./scheduler.cjs");
|
|
4
|
+
const types = require("./types.cjs");
|
|
4
5
|
class Store {
|
|
5
6
|
constructor(initialState, options) {
|
|
6
7
|
this.listeners = /* @__PURE__ */ new Set();
|
|
@@ -13,17 +14,25 @@ class Store {
|
|
|
13
14
|
unsub == null ? void 0 : unsub();
|
|
14
15
|
};
|
|
15
16
|
};
|
|
16
|
-
this.setState = (updater) => {
|
|
17
|
-
var _a, _b, _c;
|
|
18
|
-
this.prevState = this.state;
|
|
19
|
-
this.state = ((_a = this.options) == null ? void 0 : _a.updateFn) ? this.options.updateFn(this.prevState)(updater) : updater(this.prevState);
|
|
20
|
-
(_c = (_b = this.options) == null ? void 0 : _b.onUpdate) == null ? void 0 : _c.call(_b);
|
|
21
|
-
scheduler.__flush(this);
|
|
22
|
-
};
|
|
23
17
|
this.prevState = initialState;
|
|
24
18
|
this.state = initialState;
|
|
25
19
|
this.options = options;
|
|
26
20
|
}
|
|
21
|
+
setState(updater) {
|
|
22
|
+
var _a, _b, _c;
|
|
23
|
+
this.prevState = this.state;
|
|
24
|
+
if ((_a = this.options) == null ? void 0 : _a.updateFn) {
|
|
25
|
+
this.state = this.options.updateFn(this.prevState)(updater);
|
|
26
|
+
} else {
|
|
27
|
+
if (types.isUpdaterFunction(updater)) {
|
|
28
|
+
this.state = updater(this.prevState);
|
|
29
|
+
} else {
|
|
30
|
+
this.state = updater;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
(_c = (_b = this.options) == null ? void 0 : _b.onUpdate) == null ? void 0 : _c.call(_b);
|
|
34
|
+
scheduler.__flush(this);
|
|
35
|
+
}
|
|
27
36
|
}
|
|
28
37
|
exports.Store = Store;
|
|
29
38
|
//# sourceMappingURL=store.cjs.map
|
package/dist/cjs/store.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.cjs","sources":["../../src/store.ts"],"sourcesContent":["import { __flush } from './scheduler'\nimport type { AnyUpdater, Listener } from './types'\n\nexport interface StoreOptions<\n TState,\n TUpdater extends AnyUpdater = (cb: TState) => TState,\n> {\n /**\n * Replace the default update function with a custom one.\n */\n updateFn?: (previous: TState) => (updater: TUpdater) => TState\n /**\n * Called when a listener subscribes to the store.\n *\n * @return a function to unsubscribe the listener\n */\n onSubscribe?: (\n listener: Listener<TState>,\n store: Store<TState, TUpdater>,\n ) => () => void\n /**\n * Called after the state has been updated, used to derive other state.\n */\n onUpdate?: () => void\n}\n\nexport class Store<\n TState,\n TUpdater extends AnyUpdater = (cb: TState) => TState,\n> {\n listeners = new Set<Listener<TState>>()\n state: TState\n prevState: TState\n options?: StoreOptions<TState, TUpdater>\n\n constructor(initialState: TState, options?: StoreOptions<TState, TUpdater>) {\n this.prevState = initialState\n this.state = initialState\n this.options = options\n }\n\n subscribe = (listener: Listener<TState>) => {\n this.listeners.add(listener)\n const unsub = this.options?.onSubscribe?.(listener, this)\n return () => {\n this.listeners.delete(listener)\n unsub?.()\n }\n }\n\n setState
|
|
1
|
+
{"version":3,"file":"store.cjs","sources":["../../src/store.ts"],"sourcesContent":["import { __flush } from './scheduler'\nimport { isUpdaterFunction } from './types'\nimport type { AnyUpdater, Listener, Updater } from './types'\n\nexport interface StoreOptions<\n TState,\n TUpdater extends AnyUpdater = (cb: TState) => TState,\n> {\n /**\n * Replace the default update function with a custom one.\n */\n updateFn?: (previous: TState) => (updater: TUpdater) => TState\n /**\n * Called when a listener subscribes to the store.\n *\n * @return a function to unsubscribe the listener\n */\n onSubscribe?: (\n listener: Listener<TState>,\n store: Store<TState, TUpdater>,\n ) => () => void\n /**\n * Called after the state has been updated, used to derive other state.\n */\n onUpdate?: () => void\n}\n\nexport class Store<\n TState,\n TUpdater extends AnyUpdater = (cb: TState) => TState,\n> {\n listeners = new Set<Listener<TState>>()\n state: TState\n prevState: TState\n options?: StoreOptions<TState, TUpdater>\n\n constructor(initialState: TState, options?: StoreOptions<TState, TUpdater>) {\n this.prevState = initialState\n this.state = initialState\n this.options = options\n }\n\n subscribe = (listener: Listener<TState>) => {\n this.listeners.add(listener)\n const unsub = this.options?.onSubscribe?.(listener, this)\n return () => {\n this.listeners.delete(listener)\n unsub?.()\n }\n }\n\n /**\n * Update the store state safely with improved type checking\n */\n setState(updater: (prevState: TState) => TState): void\n setState(updater: TState): void\n setState(updater: TUpdater): void\n setState(updater: Updater<TState> | TUpdater): void {\n this.prevState = this.state\n\n if (this.options?.updateFn) {\n this.state = this.options.updateFn(this.prevState)(updater as TUpdater)\n } else {\n if (isUpdaterFunction(updater)) {\n this.state = updater(this.prevState)\n } else {\n this.state = updater as TState\n }\n }\n\n // Always run onUpdate, regardless of batching\n this.options?.onUpdate?.()\n\n // Attempt to flush\n __flush(this as never)\n }\n}\n"],"names":["isUpdaterFunction","__flush"],"mappings":";;;;AA2BO,MAAM,MAGX;AAAA,EAMA,YAAY,cAAsB,SAA0C;AAL5E,SAAA,gCAAgB,IAAsB;AAWtC,SAAA,YAAY,CAAC,aAA+B;;AACrC,WAAA,UAAU,IAAI,QAAQ;AAC3B,YAAM,SAAQ,gBAAK,YAAL,mBAAc,gBAAd,4BAA4B,UAAU;AACpD,aAAO,MAAM;AACN,aAAA,UAAU,OAAO,QAAQ;AACtB;AAAA,MACV;AAAA,IACF;AAZE,SAAK,YAAY;AACjB,SAAK,QAAQ;AACb,SAAK,UAAU;AAAA,EAAA;AAAA,EAkBjB,SAAS,SAA2C;;AAClD,SAAK,YAAY,KAAK;AAElB,SAAA,UAAK,YAAL,mBAAc,UAAU;AAC1B,WAAK,QAAQ,KAAK,QAAQ,SAAS,KAAK,SAAS,EAAE,OAAmB;AAAA,IAAA,OACjE;AACD,UAAAA,MAAAA,kBAAkB,OAAO,GAAG;AACzB,aAAA,QAAQ,QAAQ,KAAK,SAAS;AAAA,MAAA,OAC9B;AACL,aAAK,QAAQ;AAAA,MAAA;AAAA,IACf;AAIF,qBAAK,YAAL,mBAAc,aAAd;AAGAC,cAAAA,QAAQ,IAAa;AAAA,EAAA;AAEzB;;"}
|
package/dist/cjs/store.d.cts
CHANGED
|
@@ -22,5 +22,10 @@ export declare class Store<TState, TUpdater extends AnyUpdater = (cb: TState) =>
|
|
|
22
22
|
options?: StoreOptions<TState, TUpdater>;
|
|
23
23
|
constructor(initialState: TState, options?: StoreOptions<TState, TUpdater>);
|
|
24
24
|
subscribe: (listener: Listener<TState>) => () => void;
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Update the store state safely with improved type checking
|
|
27
|
+
*/
|
|
28
|
+
setState(updater: (prevState: TState) => TState): void;
|
|
29
|
+
setState(updater: TState): void;
|
|
30
|
+
setState(updater: TUpdater): void;
|
|
26
31
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.cjs","sources":["../../src/types.ts"],"sourcesContent":["/**\n * @private\n */\nexport type AnyUpdater = (prev: any) => any\n\n/**\n * Type-safe updater that can be either a function or direct value\n */\nexport type Updater<T> = ((prev: T) => T) | T\n\n/**\n * @private\n */\nexport interface ListenerValue<T> {\n prevVal: T\n currentVal: T\n}\n\n/**\n * @private\n */\nexport type Listener<T> = (value: ListenerValue<T>) => void\n\n/**\n * Type guard to check if updater is a function\n */\nexport function isUpdaterFunction<T>(\n updater: Updater<T>,\n): updater is (prev: T) => T {\n return typeof updater === 'function'\n}\n"],"names":[],"mappings":";;AA0BO,SAAS,kBACd,SAC2B;AAC3B,SAAO,OAAO,YAAY;AAC5B;;"}
|
package/dist/cjs/types.d.cts
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* @private
|
|
3
3
|
*/
|
|
4
4
|
export type AnyUpdater = (prev: any) => any;
|
|
5
|
+
/**
|
|
6
|
+
* Type-safe updater that can be either a function or direct value
|
|
7
|
+
*/
|
|
8
|
+
export type Updater<T> = ((prev: T) => T) | T;
|
|
5
9
|
/**
|
|
6
10
|
* @private
|
|
7
11
|
*/
|
|
@@ -13,3 +17,7 @@ export interface ListenerValue<T> {
|
|
|
13
17
|
* @private
|
|
14
18
|
*/
|
|
15
19
|
export type Listener<T> = (value: ListenerValue<T>) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Type guard to check if updater is a function
|
|
22
|
+
*/
|
|
23
|
+
export declare function isUpdaterFunction<T>(updater: Updater<T>): updater is (prev: T) => T;
|
package/dist/esm/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Derived } from "./derived.js";
|
|
2
2
|
import { Effect } from "./effect.js";
|
|
3
3
|
import { Store } from "./store.js";
|
|
4
|
+
import { isUpdaterFunction } from "./types.js";
|
|
4
5
|
import { __depsThatHaveWrittenThisTick, __derivedToStore, __flush, __storeToDerived, batch } from "./scheduler.js";
|
|
5
6
|
export {
|
|
6
7
|
Derived,
|
|
@@ -10,6 +11,7 @@ export {
|
|
|
10
11
|
__derivedToStore,
|
|
11
12
|
__flush,
|
|
12
13
|
__storeToDerived,
|
|
13
|
-
batch
|
|
14
|
+
batch,
|
|
15
|
+
isUpdaterFunction
|
|
14
16
|
};
|
|
15
17
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
package/dist/esm/store.d.ts
CHANGED
|
@@ -22,5 +22,10 @@ export declare class Store<TState, TUpdater extends AnyUpdater = (cb: TState) =>
|
|
|
22
22
|
options?: StoreOptions<TState, TUpdater>;
|
|
23
23
|
constructor(initialState: TState, options?: StoreOptions<TState, TUpdater>);
|
|
24
24
|
subscribe: (listener: Listener<TState>) => () => void;
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Update the store state safely with improved type checking
|
|
27
|
+
*/
|
|
28
|
+
setState(updater: (prevState: TState) => TState): void;
|
|
29
|
+
setState(updater: TState): void;
|
|
30
|
+
setState(updater: TUpdater): void;
|
|
26
31
|
}
|
package/dist/esm/store.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { __flush } from "./scheduler.js";
|
|
2
|
+
import { isUpdaterFunction } from "./types.js";
|
|
2
3
|
class Store {
|
|
3
4
|
constructor(initialState, options) {
|
|
4
5
|
this.listeners = /* @__PURE__ */ new Set();
|
|
@@ -11,17 +12,25 @@ class Store {
|
|
|
11
12
|
unsub == null ? void 0 : unsub();
|
|
12
13
|
};
|
|
13
14
|
};
|
|
14
|
-
this.setState = (updater) => {
|
|
15
|
-
var _a, _b, _c;
|
|
16
|
-
this.prevState = this.state;
|
|
17
|
-
this.state = ((_a = this.options) == null ? void 0 : _a.updateFn) ? this.options.updateFn(this.prevState)(updater) : updater(this.prevState);
|
|
18
|
-
(_c = (_b = this.options) == null ? void 0 : _b.onUpdate) == null ? void 0 : _c.call(_b);
|
|
19
|
-
__flush(this);
|
|
20
|
-
};
|
|
21
15
|
this.prevState = initialState;
|
|
22
16
|
this.state = initialState;
|
|
23
17
|
this.options = options;
|
|
24
18
|
}
|
|
19
|
+
setState(updater) {
|
|
20
|
+
var _a, _b, _c;
|
|
21
|
+
this.prevState = this.state;
|
|
22
|
+
if ((_a = this.options) == null ? void 0 : _a.updateFn) {
|
|
23
|
+
this.state = this.options.updateFn(this.prevState)(updater);
|
|
24
|
+
} else {
|
|
25
|
+
if (isUpdaterFunction(updater)) {
|
|
26
|
+
this.state = updater(this.prevState);
|
|
27
|
+
} else {
|
|
28
|
+
this.state = updater;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
(_c = (_b = this.options) == null ? void 0 : _b.onUpdate) == null ? void 0 : _c.call(_b);
|
|
32
|
+
__flush(this);
|
|
33
|
+
}
|
|
25
34
|
}
|
|
26
35
|
export {
|
|
27
36
|
Store
|
package/dist/esm/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sources":["../../src/store.ts"],"sourcesContent":["import { __flush } from './scheduler'\nimport type { AnyUpdater, Listener } from './types'\n\nexport interface StoreOptions<\n TState,\n TUpdater extends AnyUpdater = (cb: TState) => TState,\n> {\n /**\n * Replace the default update function with a custom one.\n */\n updateFn?: (previous: TState) => (updater: TUpdater) => TState\n /**\n * Called when a listener subscribes to the store.\n *\n * @return a function to unsubscribe the listener\n */\n onSubscribe?: (\n listener: Listener<TState>,\n store: Store<TState, TUpdater>,\n ) => () => void\n /**\n * Called after the state has been updated, used to derive other state.\n */\n onUpdate?: () => void\n}\n\nexport class Store<\n TState,\n TUpdater extends AnyUpdater = (cb: TState) => TState,\n> {\n listeners = new Set<Listener<TState>>()\n state: TState\n prevState: TState\n options?: StoreOptions<TState, TUpdater>\n\n constructor(initialState: TState, options?: StoreOptions<TState, TUpdater>) {\n this.prevState = initialState\n this.state = initialState\n this.options = options\n }\n\n subscribe = (listener: Listener<TState>) => {\n this.listeners.add(listener)\n const unsub = this.options?.onSubscribe?.(listener, this)\n return () => {\n this.listeners.delete(listener)\n unsub?.()\n }\n }\n\n setState
|
|
1
|
+
{"version":3,"file":"store.js","sources":["../../src/store.ts"],"sourcesContent":["import { __flush } from './scheduler'\nimport { isUpdaterFunction } from './types'\nimport type { AnyUpdater, Listener, Updater } from './types'\n\nexport interface StoreOptions<\n TState,\n TUpdater extends AnyUpdater = (cb: TState) => TState,\n> {\n /**\n * Replace the default update function with a custom one.\n */\n updateFn?: (previous: TState) => (updater: TUpdater) => TState\n /**\n * Called when a listener subscribes to the store.\n *\n * @return a function to unsubscribe the listener\n */\n onSubscribe?: (\n listener: Listener<TState>,\n store: Store<TState, TUpdater>,\n ) => () => void\n /**\n * Called after the state has been updated, used to derive other state.\n */\n onUpdate?: () => void\n}\n\nexport class Store<\n TState,\n TUpdater extends AnyUpdater = (cb: TState) => TState,\n> {\n listeners = new Set<Listener<TState>>()\n state: TState\n prevState: TState\n options?: StoreOptions<TState, TUpdater>\n\n constructor(initialState: TState, options?: StoreOptions<TState, TUpdater>) {\n this.prevState = initialState\n this.state = initialState\n this.options = options\n }\n\n subscribe = (listener: Listener<TState>) => {\n this.listeners.add(listener)\n const unsub = this.options?.onSubscribe?.(listener, this)\n return () => {\n this.listeners.delete(listener)\n unsub?.()\n }\n }\n\n /**\n * Update the store state safely with improved type checking\n */\n setState(updater: (prevState: TState) => TState): void\n setState(updater: TState): void\n setState(updater: TUpdater): void\n setState(updater: Updater<TState> | TUpdater): void {\n this.prevState = this.state\n\n if (this.options?.updateFn) {\n this.state = this.options.updateFn(this.prevState)(updater as TUpdater)\n } else {\n if (isUpdaterFunction(updater)) {\n this.state = updater(this.prevState)\n } else {\n this.state = updater as TState\n }\n }\n\n // Always run onUpdate, regardless of batching\n this.options?.onUpdate?.()\n\n // Attempt to flush\n __flush(this as never)\n }\n}\n"],"names":[],"mappings":";;AA2BO,MAAM,MAGX;AAAA,EAMA,YAAY,cAAsB,SAA0C;AAL5E,SAAA,gCAAgB,IAAsB;AAWtC,SAAA,YAAY,CAAC,aAA+B;;AACrC,WAAA,UAAU,IAAI,QAAQ;AAC3B,YAAM,SAAQ,gBAAK,YAAL,mBAAc,gBAAd,4BAA4B,UAAU;AACpD,aAAO,MAAM;AACN,aAAA,UAAU,OAAO,QAAQ;AACtB;AAAA,MACV;AAAA,IACF;AAZE,SAAK,YAAY;AACjB,SAAK,QAAQ;AACb,SAAK,UAAU;AAAA,EAAA;AAAA,EAkBjB,SAAS,SAA2C;;AAClD,SAAK,YAAY,KAAK;AAElB,SAAA,UAAK,YAAL,mBAAc,UAAU;AAC1B,WAAK,QAAQ,KAAK,QAAQ,SAAS,KAAK,SAAS,EAAE,OAAmB;AAAA,IAAA,OACjE;AACD,UAAA,kBAAkB,OAAO,GAAG;AACzB,aAAA,QAAQ,QAAQ,KAAK,SAAS;AAAA,MAAA,OAC9B;AACL,aAAK,QAAQ;AAAA,MAAA;AAAA,IACf;AAIF,qBAAK,YAAL,mBAAc,aAAd;AAGA,YAAQ,IAAa;AAAA,EAAA;AAEzB;"}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* @private
|
|
3
3
|
*/
|
|
4
4
|
export type AnyUpdater = (prev: any) => any;
|
|
5
|
+
/**
|
|
6
|
+
* Type-safe updater that can be either a function or direct value
|
|
7
|
+
*/
|
|
8
|
+
export type Updater<T> = ((prev: T) => T) | T;
|
|
5
9
|
/**
|
|
6
10
|
* @private
|
|
7
11
|
*/
|
|
@@ -13,3 +17,7 @@ export interface ListenerValue<T> {
|
|
|
13
17
|
* @private
|
|
14
18
|
*/
|
|
15
19
|
export type Listener<T> = (value: ListenerValue<T>) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Type guard to check if updater is a function
|
|
22
|
+
*/
|
|
23
|
+
export declare function isUpdaterFunction<T>(updater: Updater<T>): updater is (prev: T) => T;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../src/types.ts"],"sourcesContent":["/**\n * @private\n */\nexport type AnyUpdater = (prev: any) => any\n\n/**\n * Type-safe updater that can be either a function or direct value\n */\nexport type Updater<T> = ((prev: T) => T) | T\n\n/**\n * @private\n */\nexport interface ListenerValue<T> {\n prevVal: T\n currentVal: T\n}\n\n/**\n * @private\n */\nexport type Listener<T> = (value: ListenerValue<T>) => void\n\n/**\n * Type guard to check if updater is a function\n */\nexport function isUpdaterFunction<T>(\n updater: Updater<T>,\n): updater is (prev: T) => T {\n return typeof updater === 'function'\n}\n"],"names":[],"mappings":"AA0BO,SAAS,kBACd,SAC2B;AAC3B,SAAO,OAAO,YAAY;AAC5B;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/store",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Framework agnostic type-safe store w/ reactive framework adapters",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,10 +41,10 @@
|
|
|
41
41
|
"src"
|
|
42
42
|
],
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@angular/core": "^19.
|
|
45
|
-
"@preact/signals": "^1.3.
|
|
46
|
-
"solid-js": "^1.9.
|
|
47
|
-
"vue": "^3.5.
|
|
44
|
+
"@angular/core": "^19.2.13",
|
|
45
|
+
"@preact/signals": "^1.3.2",
|
|
46
|
+
"solid-js": "^1.9.7",
|
|
47
|
+
"vue": "^3.5.14"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {}
|
|
50
50
|
}
|
package/src/store.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { __flush } from './scheduler'
|
|
2
|
-
import
|
|
2
|
+
import { isUpdaterFunction } from './types'
|
|
3
|
+
import type { AnyUpdater, Listener, Updater } from './types'
|
|
3
4
|
|
|
4
5
|
export interface StoreOptions<
|
|
5
6
|
TState,
|
|
@@ -48,11 +49,24 @@ export class Store<
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Update the store state safely with improved type checking
|
|
54
|
+
*/
|
|
55
|
+
setState(updater: (prevState: TState) => TState): void
|
|
56
|
+
setState(updater: TState): void
|
|
57
|
+
setState(updater: TUpdater): void
|
|
58
|
+
setState(updater: Updater<TState> | TUpdater): void {
|
|
52
59
|
this.prevState = this.state
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
|
|
61
|
+
if (this.options?.updateFn) {
|
|
62
|
+
this.state = this.options.updateFn(this.prevState)(updater as TUpdater)
|
|
63
|
+
} else {
|
|
64
|
+
if (isUpdaterFunction(updater)) {
|
|
65
|
+
this.state = updater(this.prevState)
|
|
66
|
+
} else {
|
|
67
|
+
this.state = updater as TState
|
|
68
|
+
}
|
|
69
|
+
}
|
|
56
70
|
|
|
57
71
|
// Always run onUpdate, regardless of batching
|
|
58
72
|
this.options?.onUpdate?.()
|
package/src/types.ts
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export type AnyUpdater = (prev: any) => any
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Type-safe updater that can be either a function or direct value
|
|
8
|
+
*/
|
|
9
|
+
export type Updater<T> = ((prev: T) => T) | T
|
|
10
|
+
|
|
6
11
|
/**
|
|
7
12
|
* @private
|
|
8
13
|
*/
|
|
@@ -15,3 +20,12 @@ export interface ListenerValue<T> {
|
|
|
15
20
|
* @private
|
|
16
21
|
*/
|
|
17
22
|
export type Listener<T> = (value: ListenerValue<T>) => void
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Type guard to check if updater is a function
|
|
26
|
+
*/
|
|
27
|
+
export function isUpdaterFunction<T>(
|
|
28
|
+
updater: Updater<T>,
|
|
29
|
+
): updater is (prev: T) => T {
|
|
30
|
+
return typeof updater === 'function'
|
|
31
|
+
}
|