@thefoxieflow/signalctx 0.0.1 → 0.1.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/README.md +13 -13
- package/dist/index.d.mts +22 -21
- package/dist/index.d.ts +22 -21
- package/dist/index.js +90 -62
- package/dist/index.mjs +89 -61
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# signalctx
|
|
2
2
|
|
|
3
3
|
A tiny, signal-based state utility for React that **solves the `useContext` re-render problem** using
|
|
4
4
|
**`useSyncExternalStore`**.
|
|
@@ -10,7 +10,7 @@ If you’ve ever had this issue:
|
|
|
10
10
|
// updating count re-renders book components 😡
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
`
|
|
13
|
+
`signalctx` is designed specifically to fix that.
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
@@ -57,7 +57,7 @@ So only the components that *actually use* the changed data re-render.
|
|
|
57
57
|
## 📦 Installation
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
|
-
npm install @thefoxieflow/
|
|
60
|
+
npm install @thefoxieflow/signalctx
|
|
61
61
|
```
|
|
62
62
|
|
|
63
63
|
> **Peer dependency:** React 18+
|
|
@@ -100,12 +100,12 @@ type Store<T> = {
|
|
|
100
100
|
|
|
101
101
|
### `createStore(()=>{})`
|
|
102
102
|
|
|
103
|
-
### `
|
|
103
|
+
### `useValue(store, selector?)`
|
|
104
104
|
|
|
105
105
|
Subscribe to a signal.
|
|
106
106
|
|
|
107
107
|
```tsx
|
|
108
|
-
const count =
|
|
108
|
+
const count = useValue(store, s => s.count)
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
* Uses `useSyncExternalStore`
|
|
@@ -114,12 +114,12 @@ const count = useStoreValue(store, s => s.count)
|
|
|
114
114
|
|
|
115
115
|
---
|
|
116
116
|
|
|
117
|
-
### `
|
|
117
|
+
### `useSet(store, selector?)`
|
|
118
118
|
|
|
119
119
|
Returns a setter function.
|
|
120
120
|
|
|
121
121
|
```ts
|
|
122
|
-
const set =
|
|
122
|
+
const set = useSet(store)
|
|
123
123
|
|
|
124
124
|
set(prev => ({ ...prev, count: prev.count + 1 }))
|
|
125
125
|
```
|
|
@@ -128,7 +128,7 @@ Scoped update:
|
|
|
128
128
|
|
|
129
129
|
```ts
|
|
130
130
|
// book must be object for selector
|
|
131
|
-
const setBook =
|
|
131
|
+
const setBook = useSet(store, s => s.book)
|
|
132
132
|
|
|
133
133
|
|
|
134
134
|
// put: update an object
|
|
@@ -219,7 +219,7 @@ function Book() {
|
|
|
219
219
|
|
|
220
220
|
```tsx
|
|
221
221
|
function Increment() {
|
|
222
|
-
const set = useStore.
|
|
222
|
+
const set = useStore.useSet()
|
|
223
223
|
|
|
224
224
|
return (
|
|
225
225
|
<button onClick={() =>
|
|
@@ -308,7 +308,7 @@ function AppB(){
|
|
|
308
308
|
const storeABook = useStore(s => s.book,{ storeName :"storeA" })
|
|
309
309
|
|
|
310
310
|
// same apply to setter
|
|
311
|
-
const setBookStoreA = useStore.
|
|
311
|
+
const setBookStoreA = useStore.useSet((s)=>s.book, {storeName : "storeA"})
|
|
312
312
|
|
|
313
313
|
const handleClick = (text)=>{
|
|
314
314
|
setCountStoreA((s) => {
|
|
@@ -327,7 +327,7 @@ Each store is independent.
|
|
|
327
327
|
|
|
328
328
|
## 🌐 Server-Side Rendering (SSR)
|
|
329
329
|
|
|
330
|
-
`
|
|
330
|
+
`Signal Ctx` is SSR-safe.
|
|
331
331
|
|
|
332
332
|
* Uses `useSyncExternalStore`
|
|
333
333
|
* Identical snapshot logic on server & client
|
|
@@ -368,7 +368,7 @@ MIT
|
|
|
368
368
|
|
|
369
369
|
## ⭐ Philosophy
|
|
370
370
|
|
|
371
|
-
`
|
|
371
|
+
`signalctx` is intentionally small.
|
|
372
372
|
|
|
373
373
|
It favors:
|
|
374
374
|
|
|
@@ -376,4 +376,4 @@ It favors:
|
|
|
376
376
|
* Predictable updates
|
|
377
377
|
* Minimal abstraction
|
|
378
378
|
|
|
379
|
-
If you understand React, you understand `
|
|
379
|
+
If you understand React, you understand `signalctx`.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { PropsWithChildren } from 'react';
|
|
3
3
|
|
|
4
|
-
type
|
|
4
|
+
type SetAction<T> = T | ((prev: T) => void);
|
|
5
5
|
type Subscriber = () => void;
|
|
6
|
-
|
|
7
|
-
* @description: create a signal with subscribe and update methods
|
|
8
|
-
*/
|
|
9
|
-
declare function createStore<T = Record<string, any>>(init: () => T): {
|
|
6
|
+
type Signal<T> = {
|
|
10
7
|
(): T;
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
on: (sub: Subscriber) => () => void;
|
|
9
|
+
notify: () => void;
|
|
10
|
+
reset: () => void;
|
|
11
|
+
set: (action: SetAction<T>) => void;
|
|
12
|
+
};
|
|
13
|
+
type Store<T> = {
|
|
14
|
+
(): T;
|
|
15
|
+
on: (sub: Subscriber) => () => void;
|
|
16
|
+
reset: () => void;
|
|
17
|
+
set: (action: SetAction<T>) => void;
|
|
18
|
+
$: Signal<T>;
|
|
13
19
|
};
|
|
14
|
-
declare const useStoreValue: <T extends object, Dest = T>(store: Store<T>, selector?: (state: T) => Dest) => Dest;
|
|
15
|
-
declare const useSetStore: <T extends object = any, Dest extends object = T>(store: Store<T>, selector?: (state: T) => Dest) => (action: SetStateAction<Dest>) => void;
|
|
16
20
|
type StoreOption = {
|
|
17
21
|
storeName?: string;
|
|
18
22
|
};
|
|
23
|
+
declare const newStore: <T extends Record<string, any>>(init: () => T) => Store<T>;
|
|
24
|
+
declare const useValue: <T extends object, Dest = T>(store: Store<T>, selector?: (state: T) => Dest) => Dest;
|
|
25
|
+
declare const useSet: <T extends object = any, Dest extends object = T>(store: Store<T>, selector?: (state: T) => Dest) => (action: SetAction<Dest>) => void;
|
|
19
26
|
declare function createCtx<T extends object>(init: () => T): {
|
|
20
27
|
<Dest = any>(selector: (state: T) => Dest, opt?: StoreOption): Dest;
|
|
21
|
-
|
|
28
|
+
Provider: ({ children, value, storeName, }: PropsWithChildren<{
|
|
22
29
|
value?: T;
|
|
23
30
|
storeName?: string;
|
|
24
|
-
}) =>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
useSetter: <Dest extends object = T>(selector?: (state: T) => Dest, opt?: StoreOption) => (action: SetStateAction<Dest>) => void;
|
|
28
|
-
useStore: (opt?: StoreOption) => {
|
|
29
|
-
(): T;
|
|
30
|
-
subscribe(subscriber: Subscriber): () => boolean;
|
|
31
|
-
set(action: SetStateAction<T>): void;
|
|
32
|
-
};
|
|
31
|
+
}>) => react_jsx_runtime.JSX.Element;
|
|
32
|
+
useSet: <Dest extends object = T>(selector?: (state: T) => Dest, opt?: StoreOption) => (action: SetAction<Dest>) => void;
|
|
33
|
+
useStore: (opt?: StoreOption) => Store<T>;
|
|
33
34
|
};
|
|
34
35
|
|
|
35
|
-
export { type
|
|
36
|
+
export { type SetAction, type Signal, type Store, type Subscriber, createCtx, newStore, useSet, useValue };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { PropsWithChildren } from 'react';
|
|
3
3
|
|
|
4
|
-
type
|
|
4
|
+
type SetAction<T> = T | ((prev: T) => void);
|
|
5
5
|
type Subscriber = () => void;
|
|
6
|
-
|
|
7
|
-
* @description: create a signal with subscribe and update methods
|
|
8
|
-
*/
|
|
9
|
-
declare function createStore<T = Record<string, any>>(init: () => T): {
|
|
6
|
+
type Signal<T> = {
|
|
10
7
|
(): T;
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
on: (sub: Subscriber) => () => void;
|
|
9
|
+
notify: () => void;
|
|
10
|
+
reset: () => void;
|
|
11
|
+
set: (action: SetAction<T>) => void;
|
|
12
|
+
};
|
|
13
|
+
type Store<T> = {
|
|
14
|
+
(): T;
|
|
15
|
+
on: (sub: Subscriber) => () => void;
|
|
16
|
+
reset: () => void;
|
|
17
|
+
set: (action: SetAction<T>) => void;
|
|
18
|
+
$: Signal<T>;
|
|
13
19
|
};
|
|
14
|
-
declare const useStoreValue: <T extends object, Dest = T>(store: Store<T>, selector?: (state: T) => Dest) => Dest;
|
|
15
|
-
declare const useSetStore: <T extends object = any, Dest extends object = T>(store: Store<T>, selector?: (state: T) => Dest) => (action: SetStateAction<Dest>) => void;
|
|
16
20
|
type StoreOption = {
|
|
17
21
|
storeName?: string;
|
|
18
22
|
};
|
|
23
|
+
declare const newStore: <T extends Record<string, any>>(init: () => T) => Store<T>;
|
|
24
|
+
declare const useValue: <T extends object, Dest = T>(store: Store<T>, selector?: (state: T) => Dest) => Dest;
|
|
25
|
+
declare const useSet: <T extends object = any, Dest extends object = T>(store: Store<T>, selector?: (state: T) => Dest) => (action: SetAction<Dest>) => void;
|
|
19
26
|
declare function createCtx<T extends object>(init: () => T): {
|
|
20
27
|
<Dest = any>(selector: (state: T) => Dest, opt?: StoreOption): Dest;
|
|
21
|
-
|
|
28
|
+
Provider: ({ children, value, storeName, }: PropsWithChildren<{
|
|
22
29
|
value?: T;
|
|
23
30
|
storeName?: string;
|
|
24
|
-
}) =>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
useSetter: <Dest extends object = T>(selector?: (state: T) => Dest, opt?: StoreOption) => (action: SetStateAction<Dest>) => void;
|
|
28
|
-
useStore: (opt?: StoreOption) => {
|
|
29
|
-
(): T;
|
|
30
|
-
subscribe(subscriber: Subscriber): () => boolean;
|
|
31
|
-
set(action: SetStateAction<T>): void;
|
|
32
|
-
};
|
|
31
|
+
}>) => react_jsx_runtime.JSX.Element;
|
|
32
|
+
useSet: <Dest extends object = T>(selector?: (state: T) => Dest, opt?: StoreOption) => (action: SetAction<Dest>) => void;
|
|
33
|
+
useStore: (opt?: StoreOption) => Store<T>;
|
|
33
34
|
};
|
|
34
35
|
|
|
35
|
-
export { type
|
|
36
|
+
export { type SetAction, type Signal, type Store, type Subscriber, createCtx, newStore, useSet, useValue };
|
package/dist/index.js
CHANGED
|
@@ -21,99 +21,127 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
createCtx: () => createCtx,
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
newStore: () => newStore,
|
|
25
|
+
useSet: () => useSet,
|
|
26
|
+
useValue: () => useValue
|
|
26
27
|
});
|
|
27
28
|
module.exports = __toCommonJS(index_exports);
|
|
28
29
|
var import_react = require("react");
|
|
29
30
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
30
|
-
var
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const subscribers = /* @__PURE__ */ new Set();
|
|
37
|
-
const get = () => {
|
|
38
|
-
if (!isInit) {
|
|
39
|
-
val = init();
|
|
40
|
-
isInit = true;
|
|
41
|
-
}
|
|
42
|
-
return val;
|
|
31
|
+
var newSignal = (init) => {
|
|
32
|
+
let ref;
|
|
33
|
+
const subs = /* @__PURE__ */ new Set();
|
|
34
|
+
const store = () => ref || (ref = init());
|
|
35
|
+
store.set = (action) => {
|
|
36
|
+
act(store(), action);
|
|
43
37
|
};
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const unsubscribe = () => subscribers.delete(subscriber);
|
|
47
|
-
return unsubscribe;
|
|
38
|
+
store.reset = () => {
|
|
39
|
+
ref = init();
|
|
48
40
|
};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
subscribers.forEach((subscriber) => subscriber());
|
|
41
|
+
store.notify = () => {
|
|
42
|
+
subs.forEach((sub) => sub());
|
|
52
43
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
44
|
+
store.on = (sub) => {
|
|
45
|
+
subs.add(sub);
|
|
46
|
+
return () => subs.delete(sub);
|
|
47
|
+
};
|
|
48
|
+
return store;
|
|
49
|
+
};
|
|
50
|
+
var replaceIfDiff = (target, newVal) => {
|
|
51
|
+
if (Object.is(target, newVal)) return;
|
|
52
|
+
Object.keys(target).forEach((k) => delete target[k]);
|
|
53
|
+
Object.keys(newVal).forEach((k) => target[k] = newVal[k]);
|
|
54
|
+
};
|
|
55
|
+
var act = (target, action) => {
|
|
56
|
+
if (typeof action === "function") {
|
|
57
|
+
action(target);
|
|
58
|
+
} else {
|
|
59
|
+
replaceIfDiff(target, action);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
var newStore = (init) => {
|
|
63
|
+
const $ = newSignal(init);
|
|
64
|
+
const store = () => $();
|
|
65
|
+
store.$ = $;
|
|
66
|
+
store.on = $.on;
|
|
67
|
+
store.reset = () => {
|
|
68
|
+
$.reset();
|
|
69
|
+
$.notify();
|
|
70
|
+
};
|
|
71
|
+
store.set = (action) => {
|
|
72
|
+
$.set(action);
|
|
73
|
+
$.notify();
|
|
74
|
+
};
|
|
75
|
+
return store;
|
|
76
|
+
};
|
|
77
|
+
var useValue = (store, selector) => {
|
|
78
|
+
const get = () => selector ? selector(store()) : store();
|
|
79
|
+
return (0, import_react.useSyncExternalStore)(store.on, get, get);
|
|
59
80
|
};
|
|
60
|
-
var
|
|
81
|
+
var useSet = (store, selector) => {
|
|
61
82
|
const setter = (action) => {
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
store
|
|
83
|
+
const ref = store.$();
|
|
84
|
+
const targetRef = selector ? selector(ref) : ref;
|
|
85
|
+
act(targetRef, action);
|
|
86
|
+
store.$.notify();
|
|
66
87
|
};
|
|
67
88
|
return setter;
|
|
68
89
|
};
|
|
69
90
|
function createCtx(init) {
|
|
70
|
-
const ctx = (0, import_react.createContext)(
|
|
91
|
+
const ctx = (0, import_react.createContext)(null);
|
|
71
92
|
const stores = /* @__PURE__ */ new Map();
|
|
72
|
-
const initStore = (
|
|
93
|
+
const initStore = (init2, name) => {
|
|
94
|
+
if (!name) return newStore(init2);
|
|
73
95
|
if (!stores.has(name)) {
|
|
74
|
-
|
|
75
|
-
stores.set(name, store);
|
|
96
|
+
stores.set(name, newStore(init2));
|
|
76
97
|
}
|
|
77
98
|
return stores.get(name);
|
|
78
99
|
};
|
|
79
100
|
const useStore = (opt) => {
|
|
80
101
|
const store = (0, import_react.useContext)(ctx);
|
|
81
|
-
if (opt?.storeName && stores.has(opt.storeName))
|
|
82
|
-
return stores.get(opt.storeName);
|
|
83
|
-
}
|
|
102
|
+
if (opt?.storeName && stores.has(opt.storeName)) return stores.get(opt.storeName);
|
|
84
103
|
if (!store) throw new Error("useCtx must be used within a Provider");
|
|
85
104
|
return store;
|
|
86
105
|
};
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
106
|
+
const Provider = ({
|
|
107
|
+
children,
|
|
108
|
+
value,
|
|
109
|
+
storeName
|
|
110
|
+
}) => {
|
|
111
|
+
const [store, name] = (0, import_react.useMemo)(() => {
|
|
112
|
+
const storeInit = value ? () => value : init;
|
|
113
|
+
const store2 = initStore(storeInit, storeName);
|
|
114
|
+
return [store2, storeName];
|
|
115
|
+
}, [value, storeName]);
|
|
116
|
+
(0, import_react.useEffect)(
|
|
117
|
+
() => () => {
|
|
118
|
+
if (name) stores.delete(name);
|
|
119
|
+
},
|
|
120
|
+
[store, name]
|
|
121
|
+
);
|
|
122
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ctx.Provider, { value: store, children: [
|
|
123
|
+
" ",
|
|
124
|
+
children,
|
|
125
|
+
" "
|
|
126
|
+
] });
|
|
100
127
|
};
|
|
101
|
-
const
|
|
128
|
+
const useSelect = (selector, opt) => {
|
|
102
129
|
const store = useStore(opt);
|
|
103
|
-
return
|
|
130
|
+
return useValue(store, selector);
|
|
104
131
|
};
|
|
105
132
|
const useSetter = (selector, opt) => {
|
|
106
133
|
const store = useStore(opt);
|
|
107
|
-
return
|
|
134
|
+
return useSet(store, selector);
|
|
108
135
|
};
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return
|
|
136
|
+
useSelect.Provider = Provider;
|
|
137
|
+
useSelect.useSet = useSetter;
|
|
138
|
+
useSelect.useStore = useStore;
|
|
139
|
+
return useSelect;
|
|
113
140
|
}
|
|
114
141
|
// Annotate the CommonJS export names for ESM import in node:
|
|
115
142
|
0 && (module.exports = {
|
|
116
143
|
createCtx,
|
|
117
|
-
|
|
118
|
-
|
|
144
|
+
newStore,
|
|
145
|
+
useSet,
|
|
146
|
+
useValue
|
|
119
147
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -3,95 +3,123 @@ import {
|
|
|
3
3
|
createContext,
|
|
4
4
|
useContext,
|
|
5
5
|
useEffect,
|
|
6
|
+
useMemo,
|
|
6
7
|
useSyncExternalStore
|
|
7
8
|
} from "react";
|
|
8
|
-
import {
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const subscribers = /* @__PURE__ */ new Set();
|
|
16
|
-
const get = () => {
|
|
17
|
-
if (!isInit) {
|
|
18
|
-
val = init();
|
|
19
|
-
isInit = true;
|
|
20
|
-
}
|
|
21
|
-
return val;
|
|
9
|
+
import { jsxs } from "react/jsx-runtime";
|
|
10
|
+
var newSignal = (init) => {
|
|
11
|
+
let ref;
|
|
12
|
+
const subs = /* @__PURE__ */ new Set();
|
|
13
|
+
const store = () => ref || (ref = init());
|
|
14
|
+
store.set = (action) => {
|
|
15
|
+
act(store(), action);
|
|
22
16
|
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const unsubscribe = () => subscribers.delete(subscriber);
|
|
26
|
-
return unsubscribe;
|
|
17
|
+
store.reset = () => {
|
|
18
|
+
ref = init();
|
|
27
19
|
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
subscribers.forEach((subscriber) => subscriber());
|
|
20
|
+
store.notify = () => {
|
|
21
|
+
subs.forEach((sub) => sub());
|
|
31
22
|
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
23
|
+
store.on = (sub) => {
|
|
24
|
+
subs.add(sub);
|
|
25
|
+
return () => subs.delete(sub);
|
|
26
|
+
};
|
|
27
|
+
return store;
|
|
28
|
+
};
|
|
29
|
+
var replaceIfDiff = (target, newVal) => {
|
|
30
|
+
if (Object.is(target, newVal)) return;
|
|
31
|
+
Object.keys(target).forEach((k) => delete target[k]);
|
|
32
|
+
Object.keys(newVal).forEach((k) => target[k] = newVal[k]);
|
|
33
|
+
};
|
|
34
|
+
var act = (target, action) => {
|
|
35
|
+
if (typeof action === "function") {
|
|
36
|
+
action(target);
|
|
37
|
+
} else {
|
|
38
|
+
replaceIfDiff(target, action);
|
|
39
|
+
}
|
|
38
40
|
};
|
|
39
|
-
var
|
|
41
|
+
var newStore = (init) => {
|
|
42
|
+
const $ = newSignal(init);
|
|
43
|
+
const store = () => $();
|
|
44
|
+
store.$ = $;
|
|
45
|
+
store.on = $.on;
|
|
46
|
+
store.reset = () => {
|
|
47
|
+
$.reset();
|
|
48
|
+
$.notify();
|
|
49
|
+
};
|
|
50
|
+
store.set = (action) => {
|
|
51
|
+
$.set(action);
|
|
52
|
+
$.notify();
|
|
53
|
+
};
|
|
54
|
+
return store;
|
|
55
|
+
};
|
|
56
|
+
var useValue = (store, selector) => {
|
|
57
|
+
const get = () => selector ? selector(store()) : store();
|
|
58
|
+
return useSyncExternalStore(store.on, get, get);
|
|
59
|
+
};
|
|
60
|
+
var useSet = (store, selector) => {
|
|
40
61
|
const setter = (action) => {
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
store
|
|
62
|
+
const ref = store.$();
|
|
63
|
+
const targetRef = selector ? selector(ref) : ref;
|
|
64
|
+
act(targetRef, action);
|
|
65
|
+
store.$.notify();
|
|
45
66
|
};
|
|
46
67
|
return setter;
|
|
47
68
|
};
|
|
48
69
|
function createCtx(init) {
|
|
49
|
-
const ctx = createContext(
|
|
70
|
+
const ctx = createContext(null);
|
|
50
71
|
const stores = /* @__PURE__ */ new Map();
|
|
51
|
-
const initStore = (
|
|
72
|
+
const initStore = (init2, name) => {
|
|
73
|
+
if (!name) return newStore(init2);
|
|
52
74
|
if (!stores.has(name)) {
|
|
53
|
-
|
|
54
|
-
stores.set(name, store);
|
|
75
|
+
stores.set(name, newStore(init2));
|
|
55
76
|
}
|
|
56
77
|
return stores.get(name);
|
|
57
78
|
};
|
|
58
79
|
const useStore = (opt) => {
|
|
59
80
|
const store = useContext(ctx);
|
|
60
|
-
if (opt?.storeName && stores.has(opt.storeName))
|
|
61
|
-
return stores.get(opt.storeName);
|
|
62
|
-
}
|
|
81
|
+
if (opt?.storeName && stores.has(opt.storeName)) return stores.get(opt.storeName);
|
|
63
82
|
if (!store) throw new Error("useCtx must be used within a Provider");
|
|
64
83
|
return store;
|
|
65
84
|
};
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
85
|
+
const Provider = ({
|
|
86
|
+
children,
|
|
87
|
+
value,
|
|
88
|
+
storeName
|
|
89
|
+
}) => {
|
|
90
|
+
const [store, name] = useMemo(() => {
|
|
91
|
+
const storeInit = value ? () => value : init;
|
|
92
|
+
const store2 = initStore(storeInit, storeName);
|
|
93
|
+
return [store2, storeName];
|
|
94
|
+
}, [value, storeName]);
|
|
95
|
+
useEffect(
|
|
96
|
+
() => () => {
|
|
97
|
+
if (name) stores.delete(name);
|
|
98
|
+
},
|
|
99
|
+
[store, name]
|
|
100
|
+
);
|
|
101
|
+
return /* @__PURE__ */ jsxs(ctx.Provider, { value: store, children: [
|
|
102
|
+
" ",
|
|
103
|
+
children,
|
|
104
|
+
" "
|
|
105
|
+
] });
|
|
79
106
|
};
|
|
80
|
-
const
|
|
107
|
+
const useSelect = (selector, opt) => {
|
|
81
108
|
const store = useStore(opt);
|
|
82
|
-
return
|
|
109
|
+
return useValue(store, selector);
|
|
83
110
|
};
|
|
84
111
|
const useSetter = (selector, opt) => {
|
|
85
112
|
const store = useStore(opt);
|
|
86
|
-
return
|
|
113
|
+
return useSet(store, selector);
|
|
87
114
|
};
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return
|
|
115
|
+
useSelect.Provider = Provider;
|
|
116
|
+
useSelect.useSet = useSetter;
|
|
117
|
+
useSelect.useStore = useStore;
|
|
118
|
+
return useSelect;
|
|
92
119
|
}
|
|
93
120
|
export {
|
|
94
121
|
createCtx,
|
|
95
|
-
|
|
96
|
-
|
|
122
|
+
newStore,
|
|
123
|
+
useSet,
|
|
124
|
+
useValue
|
|
97
125
|
};
|