@thefoxieflow/signalctx 0.1.0 → 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 +4 -4
- package/dist/index.d.mts +12 -25
- package/dist/index.d.ts +12 -25
- package/dist/index.js +54 -42
- package/dist/index.mjs +55 -43
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -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
|
package/dist/index.d.mts
CHANGED
|
@@ -1,49 +1,36 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { PropsWithChildren } from 'react';
|
|
3
3
|
|
|
4
|
-
type
|
|
4
|
+
type SetAction<T> = T | ((prev: T) => void);
|
|
5
5
|
type Subscriber = () => void;
|
|
6
|
-
|
|
7
|
-
* @function calling the store internal state reference
|
|
8
|
-
* @method on subscribe to state changes
|
|
9
|
-
* @method set update the state without notifying subscribers
|
|
10
|
-
* @method reset reset the state to initial value without notifying subscribers
|
|
11
|
-
* @method notify manually notify all subscribers
|
|
12
|
-
*/
|
|
13
|
-
type InnerStore<T> = {
|
|
6
|
+
type Signal<T> = {
|
|
14
7
|
(): T;
|
|
15
8
|
on: (sub: Subscriber) => () => void;
|
|
16
9
|
notify: () => void;
|
|
17
10
|
reset: () => void;
|
|
18
|
-
set: (action:
|
|
11
|
+
set: (action: SetAction<T>) => void;
|
|
19
12
|
};
|
|
20
|
-
/**
|
|
21
|
-
* @function calling the store returns a copy of the internal state
|
|
22
|
-
* @method on subscribe to state changes
|
|
23
|
-
* @method set update the state with notifying subscribers
|
|
24
|
-
* @method reset reset the state to initial value with notifying subscribers
|
|
25
|
-
* @property $ access to non-notifying methods
|
|
26
|
-
*/
|
|
27
13
|
type Store<T> = {
|
|
28
14
|
(): T;
|
|
29
15
|
on: (sub: Subscriber) => () => void;
|
|
30
16
|
reset: () => void;
|
|
31
|
-
set: (action:
|
|
32
|
-
$:
|
|
17
|
+
set: (action: SetAction<T>) => void;
|
|
18
|
+
$: Signal<T>;
|
|
33
19
|
};
|
|
34
|
-
declare const useValue: <T extends object, Dest = T>(store: Store<T>, selector?: (state: T) => Dest) => Dest;
|
|
35
|
-
declare const useSet: <T extends object = any, Dest extends object = T>(store: Store<T>, selector?: (state: T) => Dest) => (action: SetStateAction<Dest>) => Dest;
|
|
36
20
|
type StoreOption = {
|
|
37
21
|
storeName?: string;
|
|
38
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;
|
|
39
26
|
declare function createCtx<T extends object>(init: () => T): {
|
|
40
27
|
<Dest = any>(selector: (state: T) => Dest, opt?: StoreOption): Dest;
|
|
41
|
-
|
|
28
|
+
Provider: ({ children, value, storeName, }: PropsWithChildren<{
|
|
42
29
|
value?: T;
|
|
43
30
|
storeName?: string;
|
|
44
|
-
}) =>
|
|
45
|
-
useSet: <Dest extends object = T>(selector?: (state: T) => Dest, opt?: StoreOption) => (action:
|
|
31
|
+
}>) => react_jsx_runtime.JSX.Element;
|
|
32
|
+
useSet: <Dest extends object = T>(selector?: (state: T) => Dest, opt?: StoreOption) => (action: SetAction<Dest>) => void;
|
|
46
33
|
useStore: (opt?: StoreOption) => Store<T>;
|
|
47
34
|
};
|
|
48
35
|
|
|
49
|
-
export { type
|
|
36
|
+
export { type SetAction, type Signal, type Store, type Subscriber, createCtx, newStore, useSet, useValue };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,49 +1,36 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { PropsWithChildren } from 'react';
|
|
3
3
|
|
|
4
|
-
type
|
|
4
|
+
type SetAction<T> = T | ((prev: T) => void);
|
|
5
5
|
type Subscriber = () => void;
|
|
6
|
-
|
|
7
|
-
* @function calling the store internal state reference
|
|
8
|
-
* @method on subscribe to state changes
|
|
9
|
-
* @method set update the state without notifying subscribers
|
|
10
|
-
* @method reset reset the state to initial value without notifying subscribers
|
|
11
|
-
* @method notify manually notify all subscribers
|
|
12
|
-
*/
|
|
13
|
-
type InnerStore<T> = {
|
|
6
|
+
type Signal<T> = {
|
|
14
7
|
(): T;
|
|
15
8
|
on: (sub: Subscriber) => () => void;
|
|
16
9
|
notify: () => void;
|
|
17
10
|
reset: () => void;
|
|
18
|
-
set: (action:
|
|
11
|
+
set: (action: SetAction<T>) => void;
|
|
19
12
|
};
|
|
20
|
-
/**
|
|
21
|
-
* @function calling the store returns a copy of the internal state
|
|
22
|
-
* @method on subscribe to state changes
|
|
23
|
-
* @method set update the state with notifying subscribers
|
|
24
|
-
* @method reset reset the state to initial value with notifying subscribers
|
|
25
|
-
* @property $ access to non-notifying methods
|
|
26
|
-
*/
|
|
27
13
|
type Store<T> = {
|
|
28
14
|
(): T;
|
|
29
15
|
on: (sub: Subscriber) => () => void;
|
|
30
16
|
reset: () => void;
|
|
31
|
-
set: (action:
|
|
32
|
-
$:
|
|
17
|
+
set: (action: SetAction<T>) => void;
|
|
18
|
+
$: Signal<T>;
|
|
33
19
|
};
|
|
34
|
-
declare const useValue: <T extends object, Dest = T>(store: Store<T>, selector?: (state: T) => Dest) => Dest;
|
|
35
|
-
declare const useSet: <T extends object = any, Dest extends object = T>(store: Store<T>, selector?: (state: T) => Dest) => (action: SetStateAction<Dest>) => Dest;
|
|
36
20
|
type StoreOption = {
|
|
37
21
|
storeName?: string;
|
|
38
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;
|
|
39
26
|
declare function createCtx<T extends object>(init: () => T): {
|
|
40
27
|
<Dest = any>(selector: (state: T) => Dest, opt?: StoreOption): Dest;
|
|
41
|
-
|
|
28
|
+
Provider: ({ children, value, storeName, }: PropsWithChildren<{
|
|
42
29
|
value?: T;
|
|
43
30
|
storeName?: string;
|
|
44
|
-
}) =>
|
|
45
|
-
useSet: <Dest extends object = T>(selector?: (state: T) => Dest, opt?: StoreOption) => (action:
|
|
31
|
+
}>) => react_jsx_runtime.JSX.Element;
|
|
32
|
+
useSet: <Dest extends object = T>(selector?: (state: T) => Dest, opt?: StoreOption) => (action: SetAction<Dest>) => void;
|
|
46
33
|
useStore: (opt?: StoreOption) => Store<T>;
|
|
47
34
|
};
|
|
48
35
|
|
|
49
|
-
export { type
|
|
36
|
+
export { type SetAction, type Signal, type Store, type Subscriber, createCtx, newStore, useSet, useValue };
|
package/dist/index.js
CHANGED
|
@@ -21,18 +21,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
createCtx: () => createCtx,
|
|
24
|
+
newStore: () => newStore,
|
|
24
25
|
useSet: () => useSet,
|
|
25
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
|
+
var newSignal = (init) => {
|
|
31
32
|
let ref;
|
|
32
33
|
const subs = /* @__PURE__ */ new Set();
|
|
33
34
|
const store = () => ref || (ref = init());
|
|
34
35
|
store.set = (action) => {
|
|
35
|
-
|
|
36
|
+
act(store(), action);
|
|
36
37
|
};
|
|
37
38
|
store.reset = () => {
|
|
38
39
|
ref = init();
|
|
@@ -46,23 +47,23 @@ var createInnerStore = (init) => {
|
|
|
46
47
|
};
|
|
47
48
|
return store;
|
|
48
49
|
};
|
|
49
|
-
var
|
|
50
|
-
|
|
51
|
-
if (Object.is(target, newVal)) return target;
|
|
50
|
+
var replaceIfDiff = (target, newVal) => {
|
|
51
|
+
if (Object.is(target, newVal)) return;
|
|
52
52
|
Object.keys(target).forEach((k) => delete target[k]);
|
|
53
53
|
Object.keys(newVal).forEach((k) => target[k] = newVal[k]);
|
|
54
|
-
return target;
|
|
55
54
|
};
|
|
56
|
-
var
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
var act = (target, action) => {
|
|
56
|
+
if (typeof action === "function") {
|
|
57
|
+
action(target);
|
|
58
|
+
} else {
|
|
59
|
+
replaceIfDiff(target, action);
|
|
60
|
+
}
|
|
59
61
|
};
|
|
60
|
-
|
|
61
|
-
const $ =
|
|
62
|
-
const store = () =>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
};
|
|
62
|
+
var newStore = (init) => {
|
|
63
|
+
const $ = newSignal(init);
|
|
64
|
+
const store = () => $();
|
|
65
|
+
store.$ = $;
|
|
66
|
+
store.on = $.on;
|
|
66
67
|
store.reset = () => {
|
|
67
68
|
$.reset();
|
|
68
69
|
$.notify();
|
|
@@ -71,29 +72,29 @@ function createStore(init) {
|
|
|
71
72
|
$.set(action);
|
|
72
73
|
$.notify();
|
|
73
74
|
};
|
|
74
|
-
store.on = $.on;
|
|
75
|
-
store.$ = $;
|
|
76
75
|
return store;
|
|
77
|
-
}
|
|
76
|
+
};
|
|
78
77
|
var useValue = (store, selector) => {
|
|
79
78
|
const get = () => selector ? selector(store()) : store();
|
|
80
79
|
return (0, import_react.useSyncExternalStore)(store.on, get, get);
|
|
81
80
|
};
|
|
82
81
|
var useSet = (store, selector) => {
|
|
83
82
|
const setter = (action) => {
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
store
|
|
88
|
-
return target;
|
|
83
|
+
const ref = store.$();
|
|
84
|
+
const targetRef = selector ? selector(ref) : ref;
|
|
85
|
+
act(targetRef, action);
|
|
86
|
+
store.$.notify();
|
|
89
87
|
};
|
|
90
88
|
return setter;
|
|
91
89
|
};
|
|
92
90
|
function createCtx(init) {
|
|
93
|
-
const ctx = (0, import_react.createContext)(
|
|
91
|
+
const ctx = (0, import_react.createContext)(null);
|
|
94
92
|
const stores = /* @__PURE__ */ new Map();
|
|
95
|
-
const initStore = (
|
|
96
|
-
if (!
|
|
93
|
+
const initStore = (init2, name) => {
|
|
94
|
+
if (!name) return newStore(init2);
|
|
95
|
+
if (!stores.has(name)) {
|
|
96
|
+
stores.set(name, newStore(init2));
|
|
97
|
+
}
|
|
97
98
|
return stores.get(name);
|
|
98
99
|
};
|
|
99
100
|
const useStore = (opt) => {
|
|
@@ -102,19 +103,29 @@ function createCtx(init) {
|
|
|
102
103
|
if (!store) throw new Error("useCtx must be used within a Provider");
|
|
103
104
|
return store;
|
|
104
105
|
};
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return
|
|
114
|
-
};
|
|
115
|
-
|
|
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
|
+
] });
|
|
116
127
|
};
|
|
117
|
-
const
|
|
128
|
+
const useSelect = (selector, opt) => {
|
|
118
129
|
const store = useStore(opt);
|
|
119
130
|
return useValue(store, selector);
|
|
120
131
|
};
|
|
@@ -122,14 +133,15 @@ function createCtx(init) {
|
|
|
122
133
|
const store = useStore(opt);
|
|
123
134
|
return useSet(store, selector);
|
|
124
135
|
};
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
return
|
|
136
|
+
useSelect.Provider = Provider;
|
|
137
|
+
useSelect.useSet = useSetter;
|
|
138
|
+
useSelect.useStore = useStore;
|
|
139
|
+
return useSelect;
|
|
129
140
|
}
|
|
130
141
|
// Annotate the CommonJS export names for ESM import in node:
|
|
131
142
|
0 && (module.exports = {
|
|
132
143
|
createCtx,
|
|
144
|
+
newStore,
|
|
133
145
|
useSet,
|
|
134
146
|
useValue
|
|
135
147
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -3,15 +3,16 @@ import {
|
|
|
3
3
|
createContext,
|
|
4
4
|
useContext,
|
|
5
5
|
useEffect,
|
|
6
|
+
useMemo,
|
|
6
7
|
useSyncExternalStore
|
|
7
8
|
} from "react";
|
|
8
|
-
import {
|
|
9
|
-
var
|
|
9
|
+
import { jsxs } from "react/jsx-runtime";
|
|
10
|
+
var newSignal = (init) => {
|
|
10
11
|
let ref;
|
|
11
12
|
const subs = /* @__PURE__ */ new Set();
|
|
12
13
|
const store = () => ref || (ref = init());
|
|
13
14
|
store.set = (action) => {
|
|
14
|
-
|
|
15
|
+
act(store(), action);
|
|
15
16
|
};
|
|
16
17
|
store.reset = () => {
|
|
17
18
|
ref = init();
|
|
@@ -25,23 +26,23 @@ var createInnerStore = (init) => {
|
|
|
25
26
|
};
|
|
26
27
|
return store;
|
|
27
28
|
};
|
|
28
|
-
var
|
|
29
|
-
|
|
30
|
-
if (Object.is(target, newVal)) return target;
|
|
29
|
+
var replaceIfDiff = (target, newVal) => {
|
|
30
|
+
if (Object.is(target, newVal)) return;
|
|
31
31
|
Object.keys(target).forEach((k) => delete target[k]);
|
|
32
32
|
Object.keys(newVal).forEach((k) => target[k] = newVal[k]);
|
|
33
|
-
return target;
|
|
34
33
|
};
|
|
35
|
-
var
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
var act = (target, action) => {
|
|
35
|
+
if (typeof action === "function") {
|
|
36
|
+
action(target);
|
|
37
|
+
} else {
|
|
38
|
+
replaceIfDiff(target, action);
|
|
39
|
+
}
|
|
38
40
|
};
|
|
39
|
-
|
|
40
|
-
const $ =
|
|
41
|
-
const store = () =>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
};
|
|
41
|
+
var newStore = (init) => {
|
|
42
|
+
const $ = newSignal(init);
|
|
43
|
+
const store = () => $();
|
|
44
|
+
store.$ = $;
|
|
45
|
+
store.on = $.on;
|
|
45
46
|
store.reset = () => {
|
|
46
47
|
$.reset();
|
|
47
48
|
$.notify();
|
|
@@ -50,29 +51,29 @@ function createStore(init) {
|
|
|
50
51
|
$.set(action);
|
|
51
52
|
$.notify();
|
|
52
53
|
};
|
|
53
|
-
store.on = $.on;
|
|
54
|
-
store.$ = $;
|
|
55
54
|
return store;
|
|
56
|
-
}
|
|
55
|
+
};
|
|
57
56
|
var useValue = (store, selector) => {
|
|
58
57
|
const get = () => selector ? selector(store()) : store();
|
|
59
58
|
return useSyncExternalStore(store.on, get, get);
|
|
60
59
|
};
|
|
61
60
|
var useSet = (store, selector) => {
|
|
62
61
|
const setter = (action) => {
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
store
|
|
67
|
-
return target;
|
|
62
|
+
const ref = store.$();
|
|
63
|
+
const targetRef = selector ? selector(ref) : ref;
|
|
64
|
+
act(targetRef, action);
|
|
65
|
+
store.$.notify();
|
|
68
66
|
};
|
|
69
67
|
return setter;
|
|
70
68
|
};
|
|
71
69
|
function createCtx(init) {
|
|
72
|
-
const ctx = createContext(
|
|
70
|
+
const ctx = createContext(null);
|
|
73
71
|
const stores = /* @__PURE__ */ new Map();
|
|
74
|
-
const initStore = (
|
|
75
|
-
if (!
|
|
72
|
+
const initStore = (init2, name) => {
|
|
73
|
+
if (!name) return newStore(init2);
|
|
74
|
+
if (!stores.has(name)) {
|
|
75
|
+
stores.set(name, newStore(init2));
|
|
76
|
+
}
|
|
76
77
|
return stores.get(name);
|
|
77
78
|
};
|
|
78
79
|
const useStore = (opt) => {
|
|
@@ -81,19 +82,29 @@ function createCtx(init) {
|
|
|
81
82
|
if (!store) throw new Error("useCtx must be used within a Provider");
|
|
82
83
|
return store;
|
|
83
84
|
};
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return
|
|
93
|
-
};
|
|
94
|
-
|
|
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
|
+
] });
|
|
95
106
|
};
|
|
96
|
-
const
|
|
107
|
+
const useSelect = (selector, opt) => {
|
|
97
108
|
const store = useStore(opt);
|
|
98
109
|
return useValue(store, selector);
|
|
99
110
|
};
|
|
@@ -101,13 +112,14 @@ function createCtx(init) {
|
|
|
101
112
|
const store = useStore(opt);
|
|
102
113
|
return useSet(store, selector);
|
|
103
114
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return
|
|
115
|
+
useSelect.Provider = Provider;
|
|
116
|
+
useSelect.useSet = useSetter;
|
|
117
|
+
useSelect.useStore = useStore;
|
|
118
|
+
return useSelect;
|
|
108
119
|
}
|
|
109
120
|
export {
|
|
110
121
|
createCtx,
|
|
122
|
+
newStore,
|
|
111
123
|
useSet,
|
|
112
124
|
useValue
|
|
113
125
|
};
|