@t8/react-store 1.0.38 → 1.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.
package/dist/index.js CHANGED
@@ -1,22 +1,39 @@
1
1
  // node_modules/@t8/store/src/isStore.ts
2
2
  function isStore(x) {
3
- return x !== null && typeof x === "object" && "onUpdate" in x && typeof x.onUpdate === "function" && "getState" in x && typeof x.getState === "function" && "setState" in x && typeof x.setState === "function";
3
+ return x !== null && typeof x === "object" && "on" in x && typeof x.on === "function" && "getState" in x && typeof x.getState === "function" && "setState" in x && typeof x.setState === "function";
4
4
  }
5
5
 
6
6
  // node_modules/@t8/store/src/Store.ts
7
7
  var Store = class {
8
8
  state;
9
- callbacks = /* @__PURE__ */ new Set();
9
+ callbacks = {};
10
10
  revision = -1;
11
11
  constructor(data) {
12
12
  this.state = data;
13
13
  }
14
- onUpdate(callback) {
15
- this.callbacks.add(callback);
14
+ on(event, callback) {
15
+ (this.callbacks[event] ??= /* @__PURE__ */ new Set()).add(callback);
16
16
  return () => {
17
- this.callbacks.delete(callback);
17
+ this.off(event, callback);
18
18
  };
19
19
  }
20
+ off(event, callback) {
21
+ this.callbacks[event]?.delete(callback);
22
+ }
23
+ once(event, callback) {
24
+ let oneTimeCallback = (nextState, prevState) => {
25
+ this.off(event, oneTimeCallback);
26
+ callback(nextState, prevState);
27
+ };
28
+ return this.on(event, oneTimeCallback);
29
+ }
30
+ emit(event, nextState, prevState) {
31
+ let eventCallbacks = this.callbacks[event];
32
+ if (eventCallbacks) {
33
+ for (let callback of eventCallbacks)
34
+ callback(nextState ?? this.state, prevState ?? this.state);
35
+ }
36
+ }
20
37
  getState() {
21
38
  return this.state;
22
39
  }
@@ -25,7 +42,7 @@ var Store = class {
25
42
  let nextState = update instanceof Function ? update(this.state) : update;
26
43
  this.state = nextState;
27
44
  this.revision = Math.random();
28
- for (let callback of this.callbacks) callback(nextState, prevState);
45
+ this.emit("update", nextState, prevState);
29
46
  }
30
47
  };
31
48
 
@@ -38,8 +55,9 @@ function useStore(store, shouldUpdate = true) {
38
55
  let setState = useMemo(() => store.setState.bind(store), [store]);
39
56
  let initialStoreRevision = useRef(store.revision);
40
57
  useEffect(() => {
58
+ store.emit("effect");
41
59
  if (!shouldUpdate) return;
42
- let unsubscribe = store.onUpdate((nextState, prevState) => {
60
+ let unsubscribe = store.on("update", (nextState, prevState) => {
43
61
  if (typeof shouldUpdate !== "function" || shouldUpdate(nextState, prevState))
44
62
  setRevision(Math.random());
45
63
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t8/react-store",
3
- "version": "1.0.38",
3
+ "version": "1.1.0",
4
4
  "description": "Small React app state management lib aligned with React's state pattern, condensed to the essentials",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -45,6 +45,6 @@
45
45
  "typescript": "^5.9.3"
46
46
  },
47
47
  "dependencies": {
48
- "@t8/store": "^1.1.10"
48
+ "@t8/store": "^1.2.0"
49
49
  }
50
50
  }
package/src/useStore.ts CHANGED
@@ -45,9 +45,14 @@ export function useStore<T>(
45
45
  let initialStoreRevision = useRef(store.revision);
46
46
 
47
47
  useEffect(() => {
48
+ // Use case: a one-time subscription to this event allows to
49
+ // initialize the store state on the client without causing a
50
+ // hydration error.
51
+ store.emit("effect");
52
+
48
53
  if (!shouldUpdate) return;
49
54
 
50
- let unsubscribe = store.onUpdate((nextState, prevState) => {
55
+ let unsubscribe = store.on("update", (nextState, prevState) => {
51
56
  if (
52
57
  typeof shouldUpdate !== "function" ||
53
58
  shouldUpdate(nextState, prevState)