snap-store 0.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/LICENSE +21 -0
- package/README.md +210 -0
- package/dist/esm/effects.d.ts +4 -0
- package/dist/esm/effects.d.ts.map +1 -0
- package/dist/esm/effects.js +79 -0
- package/dist/esm/effects.js.map +1 -0
- package/dist/esm/helpers.d.ts +2 -0
- package/dist/esm/helpers.d.ts.map +1 -0
- package/dist/esm/helpers.js +4 -0
- package/dist/esm/helpers.js.map +1 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/reactivity-hub.d.ts +20 -0
- package/dist/esm/reactivity-hub.d.ts.map +1 -0
- package/dist/esm/reactivity-hub.js +35 -0
- package/dist/esm/reactivity-hub.js.map +1 -0
- package/dist/esm/signal.d.ts +3 -0
- package/dist/esm/signal.d.ts.map +1 -0
- package/dist/esm/signal.js +42 -0
- package/dist/esm/signal.js.map +1 -0
- package/dist/esm/store.d.ts +3 -0
- package/dist/esm/store.d.ts.map +1 -0
- package/dist/esm/store.js +48 -0
- package/dist/esm/store.js.map +1 -0
- package/dist/esm/types.d.ts +34 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 yahiro
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# snap-store
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
This is an easy-to-use global state management library for React.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
```sh
|
|
9
|
+
npm install snap-store
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Motivation
|
|
13
|
+
|
|
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.
|
|
16
|
+
|
|
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!
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import {createStore} from "snap-store"
|
|
23
|
+
|
|
24
|
+
const store = createStore({ count: 0});
|
|
25
|
+
|
|
26
|
+
const Counter = () => {
|
|
27
|
+
const { count } = store.snapshot;
|
|
28
|
+
const { setCount } = store.mutations;
|
|
29
|
+
return <button onClick={() => setCount(prev => prev + 1)}>
|
|
30
|
+
{count}
|
|
31
|
+
</button>
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## How it works
|
|
36
|
+
```ts
|
|
37
|
+
const store = createStore({ count: 0});
|
|
38
|
+
```
|
|
39
|
+
`createStore` takes an initial state object and returns a store.
|
|
40
|
+
The store holds wrapper signals for each field of the state object.
|
|
41
|
+
```ts
|
|
42
|
+
const { count } = store.snapshot;
|
|
43
|
+
```
|
|
44
|
+
In a component, `snapshot` getter is used to refer to the states and make them reactive.
|
|
45
|
+
For this line, `count` is actually a getter and it registers a listener to track the value change.
|
|
46
|
+
|
|
47
|
+
## Usage Examples
|
|
48
|
+
```ts
|
|
49
|
+
const store = createStore({ count: 0});
|
|
50
|
+
|
|
51
|
+
function handleButton(){
|
|
52
|
+
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
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const Component = () => {
|
|
58
|
+
const { count } = store.snapshot; //refer store state as reactive
|
|
59
|
+
return <button onClick={handleButton}>push me {count}</button>
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
In the component, `store.snapshot` is used to refer to the store state as a reactive value.
|
|
63
|
+
|
|
64
|
+
Since this is a global state library, you can also read and write store states outside components.
|
|
65
|
+
`store.state` is used to read the value in non-component functions.
|
|
66
|
+
|
|
67
|
+
`store.mutations` has no difference in component or non-component context.
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
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
|
|
75
|
+
```
|
|
76
|
+
It comes with various update methods for each field.
|
|
77
|
+
|
|
78
|
+
`set*` methods are similar to the setter function of `useState`. It takes a value or a function.
|
|
79
|
+
|
|
80
|
+
`patch*` could be used for a partial update. The new state is merged with the previous state and new attributes.
|
|
81
|
+
|
|
82
|
+
`produce*` wraps the `produce` function of `immer`. (`immer` is included in the dependencies.)
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const store = createStore({
|
|
86
|
+
penWidth: 3,
|
|
87
|
+
penColor: 'black',
|
|
88
|
+
penStyle: 'normal'
|
|
89
|
+
});
|
|
90
|
+
store.mutations.assigns({ penWidth: 1, penStyle: 'dashed' });
|
|
91
|
+
//is equivalent to
|
|
92
|
+
store.mutations.setPenWidth(1);
|
|
93
|
+
store.mutations.setPenStyle('dashed');
|
|
94
|
+
```
|
|
95
|
+
In mutations, there is `assigns` method to set multiple fields at a time.
|
|
96
|
+
It is useful if you want to update multiple values.
|
|
97
|
+
|
|
98
|
+
There is no performance difference since reactive effects (i.e. rendering) are batched and executed in the next frame.
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const store = createStore<{theme: "light" | "dark"}>({theme: "light" })
|
|
102
|
+
|
|
103
|
+
const ThemeSelector = () => {
|
|
104
|
+
const { theme } = store.snapshot;
|
|
105
|
+
const { setTheme } = store.mutations;
|
|
106
|
+
return <div>
|
|
107
|
+
<IconButton
|
|
108
|
+
icon="☀️"
|
|
109
|
+
active={theme === 'light'}
|
|
110
|
+
onClick={() => setTheme("light")}
|
|
111
|
+
/>
|
|
112
|
+
<IconButton
|
|
113
|
+
icon="🌙"
|
|
114
|
+
active={theme === 'dark'}
|
|
115
|
+
onClick={() => setTheme("dark")}
|
|
116
|
+
/>
|
|
117
|
+
</div>
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
Here is a typical theme selector example.
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
const store = createStore<{textSize: number, bgColor: string}>({
|
|
124
|
+
textSize: 5,
|
|
125
|
+
bgColor: "#ffffff"
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
const BookReaderSettings = () => {
|
|
129
|
+
const snap = store.snapshot;
|
|
130
|
+
const mut = store.mutations;
|
|
131
|
+
return <div>
|
|
132
|
+
<Slider
|
|
133
|
+
value={snap.textSize}
|
|
134
|
+
onChange={mut.setTextSize}
|
|
135
|
+
min={10}
|
|
136
|
+
max={20}
|
|
137
|
+
/>
|
|
138
|
+
<ColorInput
|
|
139
|
+
value={snap.bgColor}
|
|
140
|
+
onChange={mut.setBgColor}
|
|
141
|
+
/>
|
|
142
|
+
</div>
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
Sometimes it might provide good editor completions for non-destructive use.
|
|
146
|
+
However there are caveats in some cases (read below).
|
|
147
|
+
|
|
148
|
+
## Caveats
|
|
149
|
+
```ts
|
|
150
|
+
const store = createStore({ name: "Mike", age: 20 });
|
|
151
|
+
|
|
152
|
+
//wrong code
|
|
153
|
+
const Component = () => {
|
|
154
|
+
const snap = store.snapshot;
|
|
155
|
+
if(snap.age < 20) return; //bad early return
|
|
156
|
+
return <div>Hello Gentleman, {snap.name}</div>
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
//working code
|
|
160
|
+
const Component = () => {
|
|
161
|
+
const { age, name } = store.snapshot;
|
|
162
|
+
if(age < 20) return; //no problem
|
|
163
|
+
return <div>Hello Gentleman, {name}</div>
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
Each member of the snapshot object is a getter and it calls a hooks (`useSyncExternalStore`) internally.
|
|
167
|
+
|
|
168
|
+
Since a component must have the same hooks count for each render, non-destructive assign and early return are a bad combination.
|
|
169
|
+
|
|
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.
|
|
205
|
+
|
|
206
|
+
## License
|
|
207
|
+
|
|
208
|
+
MIT License
|
|
209
|
+
|
|
210
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effects.d.ts","sourceRoot":"","sources":["../../src/effects.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAUzC,eAAO,MAAM,MAAM,GAAI,IAAI,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAqBlD,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,CAAC,EAAE,IAAI,MAAM,CAAC,KAAG,cAAc,CAAC,CAAC,CAsDzD,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { reactivityHub } from "./reactivity-hub";
|
|
2
|
+
import { createSignal } from "./signal";
|
|
3
|
+
function createEffectReceiver(fn) {
|
|
4
|
+
return {
|
|
5
|
+
listener: fn,
|
|
6
|
+
signalHolders: new Set(),
|
|
7
|
+
cleanup: [],
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export const effect = (fn) => {
|
|
11
|
+
const effectReceiver = createEffectReceiver(fn);
|
|
12
|
+
// Set current effect for dependency tracking
|
|
13
|
+
const prevEffect = reactivityHub.getCurrentEffect();
|
|
14
|
+
reactivityHub.setCurrentEffect(effectReceiver);
|
|
15
|
+
try {
|
|
16
|
+
fn(); // Execute effect to collect dependencies
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
reactivityHub.setCurrentEffect(prevEffect);
|
|
20
|
+
}
|
|
21
|
+
// Return cleanup function
|
|
22
|
+
return () => {
|
|
23
|
+
effectReceiver.cleanup.forEach((cleanup) => {
|
|
24
|
+
cleanup();
|
|
25
|
+
});
|
|
26
|
+
effectReceiver.cleanup.length = 0;
|
|
27
|
+
effectReceiver.signalHolders.clear();
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export const computed = (fn) => {
|
|
31
|
+
// biome-ignore lint/style/noNonNullAssertion: false
|
|
32
|
+
const internalSignal = createSignal(undefined);
|
|
33
|
+
let initialized;
|
|
34
|
+
let cleanupEffect;
|
|
35
|
+
const ensureInitialized = () => {
|
|
36
|
+
if (!initialized) {
|
|
37
|
+
const effectReceiver = createEffectReceiver(() => {
|
|
38
|
+
const newValue = fn();
|
|
39
|
+
internalSignal.setValue(newValue);
|
|
40
|
+
});
|
|
41
|
+
const prevEffect = reactivityHub.getCurrentEffect();
|
|
42
|
+
reactivityHub.setCurrentEffect(effectReceiver);
|
|
43
|
+
try {
|
|
44
|
+
const initialValue = fn();
|
|
45
|
+
internalSignal.setValue(initialValue);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
reactivityHub.setCurrentEffect(prevEffect);
|
|
49
|
+
}
|
|
50
|
+
cleanupEffect = () => {
|
|
51
|
+
effectReceiver.cleanup.forEach((cleanup) => {
|
|
52
|
+
cleanup();
|
|
53
|
+
});
|
|
54
|
+
effectReceiver.cleanup.length = 0;
|
|
55
|
+
effectReceiver.signalHolders.clear();
|
|
56
|
+
};
|
|
57
|
+
initialized = true;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
get value() {
|
|
62
|
+
ensureInitialized();
|
|
63
|
+
return internalSignal.value;
|
|
64
|
+
},
|
|
65
|
+
get snapshotValue() {
|
|
66
|
+
ensureInitialized();
|
|
67
|
+
return internalSignal.use();
|
|
68
|
+
},
|
|
69
|
+
use() {
|
|
70
|
+
ensureInitialized();
|
|
71
|
+
return internalSignal.use();
|
|
72
|
+
},
|
|
73
|
+
subscribe: internalSignal.subscribe,
|
|
74
|
+
cleanup() {
|
|
75
|
+
cleanupEffect?.();
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=effects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effects.js","sourceRoot":"","sources":["../../src/effects.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,UAEjD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.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"}
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { SignalListener } from "./types";
|
|
2
|
+
export type SignalHolder<T> = {
|
|
3
|
+
value: T;
|
|
4
|
+
listeners: Set<SignalListener>;
|
|
5
|
+
};
|
|
6
|
+
export type EffectReceiver = {
|
|
7
|
+
listener: () => void;
|
|
8
|
+
signalHolders: Set<SignalHolder<any>>;
|
|
9
|
+
cleanup: (() => void)[];
|
|
10
|
+
};
|
|
11
|
+
type ReactivityHub = {
|
|
12
|
+
registerSignal(key: symbol, holder: SignalHolder<any>): void;
|
|
13
|
+
getCurrentEffect(): EffectReceiver | undefined;
|
|
14
|
+
setCurrentEffect(effect: EffectReceiver | undefined): void;
|
|
15
|
+
addPendingListener(listener: SignalListener): void;
|
|
16
|
+
scheduleFlush(): void;
|
|
17
|
+
};
|
|
18
|
+
export declare const reactivityHub: ReactivityHub;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=reactivity-hub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactivity-hub.d.ts","sourceRoot":"","sources":["../../src/reactivity-hub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;IAC5B,KAAK,EAAE,CAAC,CAAC;IACT,SAAS,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;CACzB,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAC7D,gBAAgB,IAAI,cAAc,GAAG,SAAS,CAAC;IAC/C,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,GAAG,IAAI,CAAC;IAC3D,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IACnD,aAAa,IAAI,IAAI,CAAC;CACvB,CAAC;AAsCF,eAAO,MAAM,aAAa,eAAwB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
function createReactivityHub() {
|
|
2
|
+
const signalHolders = new Map();
|
|
3
|
+
let currentEffect;
|
|
4
|
+
const pendingListeners = new Set();
|
|
5
|
+
let flushScheduled = false;
|
|
6
|
+
return {
|
|
7
|
+
registerSignal(key, holder) {
|
|
8
|
+
signalHolders.set(key, holder);
|
|
9
|
+
},
|
|
10
|
+
getCurrentEffect() {
|
|
11
|
+
return currentEffect;
|
|
12
|
+
},
|
|
13
|
+
setCurrentEffect(effect) {
|
|
14
|
+
currentEffect = effect;
|
|
15
|
+
},
|
|
16
|
+
addPendingListener(listener) {
|
|
17
|
+
pendingListeners.add(listener);
|
|
18
|
+
},
|
|
19
|
+
scheduleFlush() {
|
|
20
|
+
if (flushScheduled)
|
|
21
|
+
return;
|
|
22
|
+
flushScheduled = true;
|
|
23
|
+
Promise.resolve().then(() => {
|
|
24
|
+
const listeners = Array.from(pendingListeners);
|
|
25
|
+
pendingListeners.clear();
|
|
26
|
+
flushScheduled = false;
|
|
27
|
+
listeners.forEach((listener) => {
|
|
28
|
+
listener();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export const reactivityHub = createReactivityHub();
|
|
35
|
+
//# sourceMappingURL=reactivity-hub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactivity-hub.js","sourceRoot":"","sources":["../../src/reactivity-hub.ts"],"names":[],"mappings":"AAqBA,SAAS,mBAAmB;IAC1B,MAAM,aAAa,GAAG,IAAI,GAAG,EAA6B,CAAC;IAC3D,IAAI,aAAyC,CAAC;IAC9C,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACnD,IAAI,cAAc,GAAG,KAAK,CAAC;IAE3B,OAAO;QACL,cAAc,CAAC,GAAW,EAAE,MAAyB;YACnD,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjC,CAAC;QACD,gBAAgB;YACd,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,gBAAgB,CAAC,MAAkC;YACjD,aAAa,GAAG,MAAM,CAAC;QACzB,CAAC;QACD,kBAAkB,CAAC,QAAwB;YACzC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QACD,aAAa;YACX,IAAI,cAAc;gBAAE,OAAO;YAC3B,cAAc,GAAG,IAAI,CAAC;YAEtB,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;gBAC1B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBAC/C,gBAAgB,CAAC,KAAK,EAAE,CAAC;gBACzB,cAAc,GAAG,KAAK,CAAC;gBAEvB,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;oBAC7B,QAAQ,EAAE,CAAC;gBACb,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../../src/signal.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,MAAM,EAAkB,MAAM,SAAS,CAAC;AAEhE,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAyC1D"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useSyncExternalStore } from "react";
|
|
2
|
+
import { reactivityHub } from "./reactivity-hub";
|
|
3
|
+
export function createSignal(initialValue) {
|
|
4
|
+
const key = Symbol();
|
|
5
|
+
const holder = {
|
|
6
|
+
value: initialValue,
|
|
7
|
+
listeners: new Set(),
|
|
8
|
+
};
|
|
9
|
+
reactivityHub.registerSignal(key, holder);
|
|
10
|
+
const subscribe = (listener) => {
|
|
11
|
+
holder.listeners.add(listener);
|
|
12
|
+
return () => holder.listeners.delete(listener);
|
|
13
|
+
};
|
|
14
|
+
const signal = {
|
|
15
|
+
get value() {
|
|
16
|
+
const ce = reactivityHub.getCurrentEffect();
|
|
17
|
+
if (ce && !ce.signalHolders.has(holder)) {
|
|
18
|
+
ce.signalHolders.add(holder);
|
|
19
|
+
const unsubscribe = subscribe(ce.listener);
|
|
20
|
+
ce.cleanup.push(unsubscribe);
|
|
21
|
+
}
|
|
22
|
+
return holder.value;
|
|
23
|
+
},
|
|
24
|
+
setValue(arg) {
|
|
25
|
+
const value = typeof arg === "function" ? arg(holder.value) : arg;
|
|
26
|
+
if (value === holder.value)
|
|
27
|
+
return;
|
|
28
|
+
holder.value = value;
|
|
29
|
+
holder.listeners.forEach((listener) => {
|
|
30
|
+
reactivityHub.addPendingListener(listener);
|
|
31
|
+
});
|
|
32
|
+
reactivityHub.scheduleFlush();
|
|
33
|
+
},
|
|
34
|
+
subscribe,
|
|
35
|
+
use() {
|
|
36
|
+
const value = useSyncExternalStore(subscribe, () => holder.value);
|
|
37
|
+
return value;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
return signal;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.js","sourceRoot":"","sources":["../../src/signal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAgB,MAAM,kBAAkB,CAAC;AAG/D,MAAM,UAAU,YAAY,CAAI,YAAe;IAC7C,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,MAAM,MAAM,GAAoB;QAC9B,KAAK,EAAE,YAAY;QACnB,SAAS,EAAE,IAAI,GAAG,EAAE;KACrB,CAAC;IACF,aAAa,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAE1C,MAAM,SAAS,GAAG,CAAC,QAAwB,EAAE,EAAE;QAC7C,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/B,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC,CAAC;IAEF,MAAM,MAAM,GAAc;QACxB,IAAI,KAAK;YACP,MAAM,EAAE,GAAG,aAAa,CAAC,gBAAgB,EAAE,CAAC;YAC5C,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxC,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC7B,MAAM,WAAW,GAAG,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;gBAC3C,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC/B,CAAC;YACD,OAAO,MAAM,CAAC,KAAK,CAAC;QACtB,CAAC;QACD,QAAQ,CAAC,GAAqB;YAC5B,MAAM,KAAK,GACT,OAAO,GAAG,KAAK,UAAU,CAAC,CAAC,CAAE,GAAsB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAC1E,IAAI,KAAK,KAAK,MAAM,CAAC,KAAK;gBAAE,OAAO;YAEnC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;YACrB,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;gBACpC,aAAa,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAC7C,CAAC,CAAC,CAAC;YACH,aAAa,CAAC,aAAa,EAAE,CAAC;QAChC,CAAC;QACD,SAAS;QACT,GAAG;YACD,MAAM,KAAK,GAAG,oBAAoB,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAClE,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { produce } from "immer";
|
|
2
|
+
import { capitalizeFirstLetter } from "./helpers";
|
|
3
|
+
import { createSignal } from "./signal";
|
|
4
|
+
export function createStore(initialState) {
|
|
5
|
+
const stateGetters = {};
|
|
6
|
+
const snapshotGetters = {};
|
|
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));
|
|
25
|
+
};
|
|
26
|
+
mutations[`patch${capitalizeFirstLetter(key)}`] = (attrs) => {
|
|
27
|
+
signal.setValue((prev) => ({ ...prev, ...attrs }));
|
|
28
|
+
};
|
|
29
|
+
signals[key] = signal;
|
|
30
|
+
}
|
|
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
|
+
});
|
|
40
|
+
return {
|
|
41
|
+
state: stateGetters,
|
|
42
|
+
snapshot: snapshotGetters,
|
|
43
|
+
useSnapshot: () => snapshotGetters,
|
|
44
|
+
mutations,
|
|
45
|
+
signals,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
export type Mutations<T> = {
|
|
17
|
+
[K in keyof T as `set${Capitalize<K & string>}`]: (value: T[K] | ((prev: T[K]) => T[K])) => void;
|
|
18
|
+
} & {
|
|
19
|
+
[K in keyof T as `produce${Capitalize<K & string>}`]: (fn: (draft: T[K]) => void) => void;
|
|
20
|
+
} & {
|
|
21
|
+
[K in keyof T as `patch${Capitalize<K & string>}`]: (attrs: Partial<T[K]>) => void;
|
|
22
|
+
} & {
|
|
23
|
+
assigns: (attrs: Partial<T>) => void;
|
|
24
|
+
};
|
|
25
|
+
export type Store<T extends object> = {
|
|
26
|
+
state: T;
|
|
27
|
+
snapshot: T;
|
|
28
|
+
useSnapshot(): T;
|
|
29
|
+
mutations: Mutations<T>;
|
|
30
|
+
signals: {
|
|
31
|
+
[K in keyof T]: Signal<T[K]>;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "snap-store",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "An easy-to-use global state management library for React.",
|
|
5
|
+
"author": "yahiro",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/esm/index.js",
|
|
9
|
+
"types": "./dist/esm/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/esm/index.d.ts",
|
|
13
|
+
"import": "./dist/esm/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/yahiro07/snap-store.git"
|
|
24
|
+
},
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/yahiro07/snap-store/issues"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/yahiro07/snap-store#readme",
|
|
29
|
+
"keywords": [
|
|
30
|
+
"react",
|
|
31
|
+
"state",
|
|
32
|
+
"management",
|
|
33
|
+
"store",
|
|
34
|
+
"signal",
|
|
35
|
+
"reactive",
|
|
36
|
+
"hooks"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build:esm": "tsc --project tsconfig.esm.json",
|
|
40
|
+
"build": "npm run build:esm",
|
|
41
|
+
"prepublishOnly": "npm run build"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"immer": "^10.2.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"react": ">=18.0.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/react": "^19.2.2",
|
|
51
|
+
"typescript": "^5.9.3"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=16.0.0"
|
|
55
|
+
}
|
|
56
|
+
}
|