snap-store 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -1,22 +1,34 @@
1
1
  # snap-store
2
2
 
3
- ## Introduction
4
-
5
- This is an easy-to-use global state management library for React.
3
+ Easy-to-use global state management library for React.
6
4
 
7
5
  ## Installation
8
6
  ```sh
9
7
  npm install snap-store
10
8
  ```
11
9
 
12
- ## Motivation
10
+ ## Overview
11
+
12
+ **snap-store** simplifies global state management in React.
13
+
14
+ In apps like graphical editors or tools with editing functionality, it's often desirable to maintain state in a global store accessible throughout the application.
15
+
16
+ This library is designed to let you place app state to a central store while keeping your existing component implementations mostly intact.
17
+
18
+ It minimizes boilerplate code and complex hook calls, making it easy to create a central store that can be shared across multiple components.
19
+
20
+
21
+ ### Key Features
13
22
 
14
- I like [valtio](https://github.com/pmndrs/valtio). But sometimes I'm confused by its proxy based design.
15
- So I wanted to have a non-proxy version of this.
23
+ **snap-store** is designed with the following principles:
16
24
 
17
- I researched some signal based libraries and how to make them work on React.
18
- I found some hooks (`useSyncExternalStore`) could be used to implement it.
19
- After struggling for a while, finally I got my own store library working!
25
+ 1. **Easy to Migrate from Local State**: Store state is subscribed as plain values and updated with methods like `setValue(newValue)`, making it easy to migrate from local `useState` to a global store with minimal component changes.
26
+
27
+ 2. **Consistent Access Pattern**: Both in-component and out-of-component store access use a similar API, making it easy to extract complex state update logic outside of components.
28
+
29
+ 3. **Convenient Update Methods**: In addition to basic setters, the library provides useful update methods like `patch*` for partial updates and `produce*` for immer-based updates.
30
+
31
+ ## Basic Usage
20
32
 
21
33
  ```ts
22
34
  import {createStore} from "snap-store"
@@ -24,9 +36,8 @@ import {createStore} from "snap-store"
24
36
  const store = createStore({ count: 0});
25
37
 
26
38
  const Counter = () => {
27
- const { count } = store.snapshot;
28
- const { setCount } = store.mutations;
29
- return <button onClick={() => setCount(prev => prev + 1)}>
39
+ const { count } = store.useSnapshot();
40
+ return <button onClick={() => store.setCount(prev => prev + 1)}>
30
41
  {count}
31
42
  </button>
32
43
  }
@@ -37,43 +48,43 @@ const Counter = () => {
37
48
  const store = createStore({ count: 0});
38
49
  ```
39
50
  `createStore` takes an initial state object and returns a store.
40
- The store holds wrapper signals for each field of the state object.
41
51
  ```ts
42
- const { count } = store.snapshot;
52
+ const { count } = store.useSnapshot();
43
53
  ```
44
- In a component, `snapshot` getter is used to refer to the states and make them reactive.
54
+ In a component, `useSnapshot()` hook is used to refer to the states and make them reactive.
45
55
  For this line, `count` is actually a getter and it registers a listener to track the value change.
46
56
 
47
- ## Usage Examples
57
+ ## Examples
48
58
  ```ts
49
59
  const store = createStore({ count: 0});
50
60
 
51
61
  function handleButton(){
52
62
  const { count } = store.state; //read store state
53
- store.mutations.setCount(currentCount + 1); //mutate by value
54
- store.mutations.setCount(prev => prev + 1); //mutate by function
63
+ store.setCount(count + 1); //mutate by value
64
+ store.setCount(prev => prev + 1); //mutate by function
55
65
  }
56
66
 
57
67
  const Component = () => {
58
- const { count } = store.snapshot; //refer store state as reactive
68
+ const { count } = store.useSnapshot(); //refer store state as reactive
59
69
  return <button onClick={handleButton}>push me {count}</button>
60
70
  }
61
71
  ```
62
- In the component, `store.snapshot` is used to refer to the store state as a reactive value.
72
+ In the component, `store.useSnapshot()` is used to refer to the store state as a reactive value.
63
73
 
64
74
  Since this is a global state library, you can also read and write store states outside components.
65
75
  `store.state` is used to read the value in non-component functions.
66
76
 
67
- `store.mutations` has no difference in component or non-component context.
77
+ Mutation methods have no difference in component or non-component context.
68
78
 
69
79
  ```ts
70
80
  const store = createStore({ user: {name: "John", age: 20 }});
71
- store.mutations.setUser({ name: "Mike", age: 20}); //value
72
- store.mutations.setUser(prev => ({...prev, age: 21})); //by function
73
- store.mutations.patchUser({ age: 22}); //partial update (merged)
74
- store.mutations.produceUser(draft => { draft.age = 23 }) //update with immer
81
+ store.setUser({ name: "Mike", age: 20}); //value
82
+ store.setUser(prev => ({...prev, age: 21})); //by function
83
+ store.patchUser({ age: 22}); //partial update (merged)
84
+ store.produceUser(draft => { draft.age = 23 }) //update with immer
75
85
  ```
76
- It comes with various update methods for each field.
86
+
87
+ `store` object has a set of update methods for each field.
77
88
 
78
89
  `set*` methods are similar to the setter function of `useState`. It takes a value or a function.
79
90
 
@@ -87,32 +98,31 @@ const store = createStore({
87
98
  penColor: 'black',
88
99
  penStyle: 'normal'
89
100
  });
90
- store.mutations.assigns({ penWidth: 1, penStyle: 'dashed' });
101
+ store.assigns({ penWidth: 1, penStyle: 'dashed' });
91
102
  //is equivalent to
92
- store.mutations.setPenWidth(1);
93
- store.mutations.setPenStyle('dashed');
103
+ store.setPenWidth(1);
104
+ store.setPenStyle('dashed');
94
105
  ```
95
- In mutations, there is `assigns` method to set multiple fields at a time.
106
+ In store, there is `assigns` method to set multiple fields at a time.
96
107
  It is useful if you want to update multiple values.
97
108
 
98
- There is no performance difference since reactive effects (i.e. rendering) are batched and executed in the next frame.
109
+ There is no performance difference since reactive effects (i.e. rendering) are batched by React and executed in the next frame.
99
110
 
100
111
  ```ts
101
112
  const store = createStore<{theme: "light" | "dark"}>({theme: "light" })
102
113
 
103
114
  const ThemeSelector = () => {
104
- const { theme } = store.snapshot;
105
- const { setTheme } = store.mutations;
115
+ const { theme } = store.useSnapshot();
106
116
  return <div>
107
117
  <IconButton
108
118
  icon="☀️"
109
119
  active={theme === 'light'}
110
- onClick={() => setTheme("light")}
120
+ onClick={() => store.setTheme("light")}
111
121
  />
112
122
  <IconButton
113
123
  icon="🌙"
114
124
  active={theme === 'dark'}
115
- onClick={() => setTheme("dark")}
125
+ onClick={() => store.setTheme("dark")}
116
126
  />
117
127
  </div>
118
128
  }
@@ -126,18 +136,17 @@ const store = createStore<{textSize: number, bgColor: string}>({
126
136
  })
127
137
 
128
138
  const BookReaderSettings = () => {
129
- const snap = store.snapshot;
130
- const mut = store.mutations;
139
+ const snap = store.useSnapshot();;
131
140
  return <div>
132
141
  <Slider
133
142
  value={snap.textSize}
134
- onChange={mut.setTextSize}
143
+ onChange={store.setTextSize}
135
144
  min={10}
136
145
  max={20}
137
146
  />
138
147
  <ColorInput
139
148
  value={snap.bgColor}
140
- onChange={mut.setBgColor}
149
+ onChange={store.setBgColor}
141
150
  />
142
151
  </div>
143
152
  }
@@ -151,60 +160,27 @@ const store = createStore({ name: "Mike", age: 20 });
151
160
 
152
161
  //wrong code
153
162
  const Component = () => {
154
- const snap = store.snapshot;
163
+ const snap = store.useSnapshot();;
155
164
  if(snap.age < 20) return; //bad early return
156
165
  return <div>Hello Gentleman, {snap.name}</div>
157
166
  }
158
167
 
159
168
  //working code
160
169
  const Component = () => {
161
- const { age, name } = store.snapshot;
170
+ const { age, name } = store.useSnapshot();;
162
171
  if(age < 20) return; //no problem
163
172
  return <div>Hello Gentleman, {name}</div>
164
173
  }
165
174
  ```
166
- Each member of the snapshot object is a getter and it calls a hooks (`useSyncExternalStore`) internally.
175
+ Each member of the snapshot object is a getter and it calls a hooks internally.
167
176
 
168
177
  Since a component must have the same hooks count for each render, non-destructive assign and early return are a bad combination.
169
178
 
170
- The snapshot should be destructured if you have an early return.
171
-
172
- ## Other Signal functionalities
173
- ```ts
174
- const store = createStore({ count: 0 });
175
-
176
- effect(() => {
177
- const count = store.state.count;
178
- console.log("Effect:", count);
179
- });
180
-
181
- store.mutations.setCount((prev) => prev + 1);
182
-
183
- const doubled = computed(() => {
184
- const cnt = store.state.count;
185
- console.log("computing for:", cnt);
186
- return cnt * 2;
187
- });
188
- console.log("Doubled:", doubled.value);
189
- ```
190
- There are two `effect()` and `computed()` helper functions intended to be used in non-component context.
191
-
192
- `effect()` tracks the referred state changes in the callback and is automatically re-evaluated when the tracked values change.
193
-
194
- `computed()` is used for caching the computation result, returning a derived signal. It is re-evaluated when tracked values change.
195
-
196
- ## References
197
- - [valtio](https://github.com/pmndrs/valtio)
198
- - [@preact/signals-react](https://github.com/preactjs/signals)
199
-
200
- `snap-store` is highly influenced by these libraries.
201
-
202
- Compared to `valtio`, this library provides a similar design of global store but it doesn't use proxies. Also the mutations are applied by the methods not by assignment.
203
-
204
- Compared to `@preact/signals-react`, although the mechanism of the signal is similar, this library is aimed to supply an opinionated store system whereas `@preact/signals` provides the basic primitive signal functions.
179
+ The snapshot object should be destructured if you have an early return.
205
180
 
206
181
  ## License
207
182
 
208
183
  MIT License
209
184
 
210
185
 
186
+
@@ -0,0 +1,2 @@
1
+ export declare function capitalizeFirstLetter(text: string): string;
2
+ //# sourceMappingURL=helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/helper.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,UAEjD"}
@@ -0,0 +1,4 @@
1
+ export function capitalizeFirstLetter(text) {
2
+ return text.charAt(0).toUpperCase() + text.slice(1);
3
+ }
4
+ //# sourceMappingURL=helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper.js","sourceRoot":"","sources":["../../src/helper.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC"}
@@ -1,5 +1,3 @@
1
- export * from "./effects";
2
- export * from "./signal";
3
1
  export * from "./store";
4
2
  export * from "./types";
5
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
package/dist/esm/index.js CHANGED
@@ -1,5 +1,3 @@
1
- export * from "./effects";
2
- export * from "./signal";
3
1
  export * from "./store";
4
2
  export * from "./types";
5
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAmDvE"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAa,KAAK,EAAE,MAAM,SAAS,CAAC;AAE3C,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAwFvE"}
package/dist/esm/store.js CHANGED
@@ -1,48 +1,78 @@
1
1
  import { produce } from "immer";
2
- import { capitalizeFirstLetter } from "./helpers";
3
- import { createSignal } from "./signal";
2
+ import { useEffect, useId, useMemo, useState } from "react";
3
+ import { capitalizeFirstLetter } from "./helper";
4
4
  export function createStore(initialState) {
5
- const stateGetters = {};
6
- const snapshotGetters = {};
5
+ const hub = {};
6
+ const state = initialState;
7
7
  const mutations = {};
8
- const signals = {};
9
- for (const key in initialState) {
10
- const initialValue = initialState[key];
11
- const signal = createSignal(initialValue);
12
- Object.defineProperty(stateGetters, key, {
13
- get() {
14
- return signal.value;
15
- },
16
- });
17
- Object.defineProperty(snapshotGetters, key, {
18
- get() {
19
- return signal.use();
20
- },
21
- });
22
- mutations[`set${capitalizeFirstLetter(key)}`] = signal.setValue;
23
- mutations[`produce${capitalizeFirstLetter(key)}`] = (fn) => {
24
- signal.setValue((draft) => produce(draft, fn));
8
+ const _mutations = mutations;
9
+ for (const _key in initialState) {
10
+ const key = _key;
11
+ const setValue = (arg) => {
12
+ let value;
13
+ if (typeof arg === "function") {
14
+ value = arg(state[key]);
15
+ }
16
+ else {
17
+ value = arg;
18
+ }
19
+ state[key] = value;
20
+ for (const hubKey in hub) {
21
+ const entry = hub[hubKey];
22
+ if (entry.dependentFieldKeys.has(key)) {
23
+ entry.refreshView();
24
+ }
25
+ }
25
26
  };
26
- mutations[`patch${capitalizeFirstLetter(key)}`] = (attrs) => {
27
- signal.setValue((prev) => ({ ...prev, ...attrs }));
27
+ const suffix = capitalizeFirstLetter(key);
28
+ _mutations[`set${suffix}`] = setValue;
29
+ _mutations[`produce${suffix}`] = (fn) => {
30
+ setValue((draft) => produce(draft, fn));
31
+ };
32
+ _mutations[`patch${suffix}`] = (attrs) => {
33
+ setValue((prev) => ({ ...prev, ...attrs }));
28
34
  };
29
- signals[key] = signal;
30
35
  }
31
- Object.assign(mutations, {
32
- assigns: (attrs) => {
33
- for (const key in attrs) {
34
- const value = attrs[key];
35
- const setValue = mutations[`set${capitalizeFirstLetter(key)}`];
36
- setValue?.(value);
37
- }
38
- },
39
- });
36
+ mutations.assigns = (attrs) => {
37
+ for (const key in attrs) {
38
+ const suffix = capitalizeFirstLetter(key);
39
+ const value = attrs[key];
40
+ const setValue = _mutations[`set${suffix}`];
41
+ setValue?.(value);
42
+ }
43
+ };
44
+ const createHookEntry = (hookId, refreshView) => {
45
+ hub[hookId] = { dependentFieldKeys: new Set(), refreshView };
46
+ const getterObject = {};
47
+ for (const key in initialState) {
48
+ Object.defineProperty(getterObject, key, {
49
+ get() {
50
+ hub[hookId].dependentFieldKeys.add(key);
51
+ return state[key];
52
+ },
53
+ });
54
+ }
55
+ const cleanup = () => {
56
+ delete hub[hookId];
57
+ };
58
+ return { getterObject, cleanup };
59
+ };
60
+ const useSnapshot = () => {
61
+ const hookId = useId();
62
+ const [, setRenderObject] = useState({});
63
+ const hookEntry = useMemo(() => createHookEntry(hookId, () => setRenderObject({})), [hookId]);
64
+ useEffect(() => {
65
+ return hookEntry.cleanup;
66
+ }, [hookEntry]);
67
+ return hookEntry.getterObject;
68
+ };
40
69
  return {
41
- state: stateGetters,
42
- snapshot: snapshotGetters,
43
- useSnapshot: () => snapshotGetters,
44
- mutations,
45
- signals,
70
+ state,
71
+ useSnapshot,
72
+ get snapshot() {
73
+ return useSnapshot();
74
+ },
75
+ ...mutations,
46
76
  };
47
77
  }
48
78
  //# sourceMappingURL=store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxC,MAAM,UAAU,WAAW,CAAmB,YAAe;IAE3D,MAAM,YAAY,GAAQ,EAAE,CAAC;IAC7B,MAAM,eAAe,GAAQ,EAAE,CAAC;IAChC,MAAM,SAAS,GAAQ,EAAE,CAAC;IAC1B,MAAM,OAAO,GAAQ,EAAE,CAAC;IAExB,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;QAE1C,MAAM,CAAC,cAAc,CAAC,YAAY,EAAE,GAAG,EAAE;YACvC,GAAG;gBACD,OAAO,MAAM,CAAC,KAAK,CAAC;YACtB,CAAC;SACF,CAAC,CAAC;QACH,MAAM,CAAC,cAAc,CAAC,eAAe,EAAE,GAAG,EAAE;YAC1C,GAAG;gBACD,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC;YACtB,CAAC;SACF,CAAC,CAAC;QACH,SAAS,CAAC,MAAM,qBAAqB,CAAC,GAAa,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC1E,SAAS,CAAC,UAAU,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAClD,EAAyB,EACzB,EAAE;YACF,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;QACjD,CAAC,CAAC;QACF,SAAS,CAAC,QAAQ,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAChD,KAAoB,EACpB,EAAE;YACF,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;QACrD,CAAC,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACxB,CAAC;IACD,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE;QACvB,OAAO,EAAE,CAAC,KAAiB,EAAE,EAAE;YAC7B,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;gBACzB,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC/D,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE,YAAY;QACnB,QAAQ,EAAE,eAAe;QACzB,WAAW,EAAE,GAAG,EAAE,CAAC,eAAe;QAClC,SAAS;QACT,OAAO;KACR,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"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"}
@@ -1,34 +1,15 @@
1
- export type SignalListener = () => void;
2
- export type SetterPayload<T> = T | ((prev: T) => T);
3
- export type Signal<T> = {
4
- readonly value: T;
5
- setValue(arg: SetterPayload<T>): void;
6
- subscribe(listener: SignalListener): () => void;
7
- use(): T;
8
- };
9
- export type ComputedSignal<T> = {
10
- readonly value: T;
11
- subscribe(listener: SignalListener): () => void;
12
- readonly snapshotValue: T;
13
- use(): T;
14
- cleanup(): void;
15
- };
16
1
  export type Mutations<T> = {
17
2
  [K in keyof T as `set${Capitalize<K & string>}`]: (value: T[K] | ((prev: T[K]) => T[K])) => void;
18
3
  } & {
19
4
  [K in keyof T as `produce${Capitalize<K & string>}`]: (fn: (draft: T[K]) => void) => void;
20
5
  } & {
21
- [K in keyof T as `patch${Capitalize<K & string>}`]: (attrs: Partial<T[K]>) => void;
6
+ [K in keyof T as `patch${Capitalize<K & string>}`]: (attrs: Partial<Extract<T[K], object>>) => void;
22
7
  } & {
23
8
  assigns: (attrs: Partial<T>) => void;
24
9
  };
25
10
  export type Store<T extends object> = {
26
11
  state: T;
27
- snapshot: T;
28
12
  useSnapshot(): T;
29
- mutations: Mutations<T>;
30
- signals: {
31
- [K in keyof T]: Signal<T[K]>;
32
- };
33
- };
13
+ snapshot: T;
14
+ } & Mutations<T>;
34
15
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC;AAExC,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;AAGpD,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI;IACtB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACtC,SAAS,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI,CAAC;IAChD,GAAG,IAAI,CAAC,CAAC;CACV,CAAC;AAGF,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,SAAS,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI,CAAC;IAChD,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,GAAG,IAAI,CAAC,CAAC;IACT,OAAO,IAAI,IAAI,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI;KACxB,CAAC,IAAI,MAAM,CAAC,IAAI,MAAM,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,GAAG,CAChD,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KACjC,IAAI;CACV,GAAG;KACD,CAAC,IAAI,MAAM,CAAC,IAAI,UAAU,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,GAAG,CACpD,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,KACtB,IAAI;CACV,GAAG;KACD,CAAC,IAAI,MAAM,CAAC,IAAI,QAAQ,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,GAAG,CAClD,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KACjB,IAAI;CACV,GAAG;IACF,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,MAAM,IAAI;IACpC,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,CAAC,CAAC;IACZ,WAAW,IAAI,CAAC,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACxB,OAAO,EAAE;SAAG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAAE,CAAC;CAC3C,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI;KACxB,CAAC,IAAI,MAAM,CAAC,IAAI,MAAM,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,GAAG,CAChD,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KACjC,IAAI;CACV,GAAG;KACD,CAAC,IAAI,MAAM,CAAC,IAAI,UAAU,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,GAAG,CACpD,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,KACtB,IAAI;CACV,GAAG;KACD,CAAC,IAAI,MAAM,CAAC,IAAI,QAAQ,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,GAAG,CAClD,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAClC,IAAI;CACV,GAAG;IACF,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,MAAM,IAAI;IACpC,KAAK,EAAE,CAAC,CAAC;IACT,WAAW,IAAI,CAAC,CAAC;IACjB,QAAQ,EAAE,CAAC,CAAC;CACb,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snap-store",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "An easy-to-use global state management library for React.",
5
5
  "author": "yahiro",
6
6
  "license": "MIT",
@@ -53,4 +53,4 @@
53
53
  "engines": {
54
54
  "node": ">=16.0.0"
55
55
  }
56
- }
56
+ }