reactish-state 0.10.4 → 0.11.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +42 -9
- package/dist/esm/index.js +1 -0
- package/dist/esm/react/useSelector.js +33 -0
- package/dist/esm/utils.js +13 -0
- package/dist/esm/vanilla/selector.js +8 -15
- package/package.json +19 -19
- package/types/common.d.ts +10 -0
- package/types/index.d.ts +1 -0
- package/types/react/useSelector.d.ts +3 -0
- package/types/utils.d.ts +4 -0
- package/types/vanilla/selector.d.ts +1 -10
package/dist/cjs/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var shim = require('use-sync-external-store/shim');
|
|
4
|
+
var react = require('react');
|
|
4
5
|
|
|
5
6
|
const createState = ({
|
|
6
7
|
middleware
|
|
@@ -39,6 +40,12 @@ const isEqual = (args1, args2) => {
|
|
|
39
40
|
}
|
|
40
41
|
return true;
|
|
41
42
|
};
|
|
43
|
+
const createSubscriber = items => listener => {
|
|
44
|
+
const unsubscribers = items.map(item => item.subscribe(listener));
|
|
45
|
+
return () => unsubscribers.forEach(unsubscribe => unsubscribe());
|
|
46
|
+
};
|
|
47
|
+
const getReactishValues = items => items.map(item => item.get());
|
|
48
|
+
|
|
42
49
|
const createSelector = ({
|
|
43
50
|
plugin
|
|
44
51
|
} = {}) => (...items) => {
|
|
@@ -52,19 +59,16 @@ const createSelector = ({
|
|
|
52
59
|
let cache;
|
|
53
60
|
const selector = {
|
|
54
61
|
get: () => {
|
|
55
|
-
const args = items
|
|
56
|
-
if (cache && isEqual(args, cache.args)) return cache.
|
|
57
|
-
const
|
|
62
|
+
const args = getReactishValues(items);
|
|
63
|
+
if (cache && isEqual(args, cache.args)) return cache.val;
|
|
64
|
+
const val = selectorFunc(...args);
|
|
58
65
|
cache = {
|
|
59
66
|
args,
|
|
60
|
-
|
|
67
|
+
val
|
|
61
68
|
};
|
|
62
|
-
return
|
|
69
|
+
return val;
|
|
63
70
|
},
|
|
64
|
-
subscribe:
|
|
65
|
-
const unsubscribers = items.map(item => item.subscribe(listener));
|
|
66
|
-
return () => unsubscribers.forEach(unsubscribe => unsubscribe());
|
|
67
|
-
}
|
|
71
|
+
subscribe: createSubscriber(items)
|
|
68
72
|
};
|
|
69
73
|
plugin == null ? void 0 : plugin(selector, config);
|
|
70
74
|
return selector;
|
|
@@ -76,8 +80,37 @@ const useSnapshot = ({
|
|
|
76
80
|
get
|
|
77
81
|
}) => shim.useSyncExternalStore(subscribe, get, get);
|
|
78
82
|
|
|
83
|
+
const useSelector = (selectorParamFactory, deps) => {
|
|
84
|
+
const items = selectorParamFactory();
|
|
85
|
+
const cutoff = items.length - 1;
|
|
86
|
+
const selectorFunc = items[cutoff];
|
|
87
|
+
items.length = cutoff;
|
|
88
|
+
const [context] = react.useState(() => ({
|
|
89
|
+
sub: createSubscriber(items)
|
|
90
|
+
}));
|
|
91
|
+
const get = () => {
|
|
92
|
+
const {
|
|
93
|
+
cache
|
|
94
|
+
} = context;
|
|
95
|
+
const reactishValues = getReactishValues(items);
|
|
96
|
+
const args = reactishValues.concat(deps || selectorFunc);
|
|
97
|
+
if (cache && isEqual(args, cache.args)) return cache.val;
|
|
98
|
+
const val = selectorFunc(...reactishValues);
|
|
99
|
+
context.cache = {
|
|
100
|
+
args,
|
|
101
|
+
val
|
|
102
|
+
};
|
|
103
|
+
return val;
|
|
104
|
+
};
|
|
105
|
+
return useSnapshot({
|
|
106
|
+
get,
|
|
107
|
+
subscribe: context.sub
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
|
|
79
111
|
exports.createSelector = createSelector;
|
|
80
112
|
exports.createState = createState;
|
|
81
113
|
exports.selector = selector;
|
|
82
114
|
exports.state = state;
|
|
115
|
+
exports.useSelector = useSelector;
|
|
83
116
|
exports.useSnapshot = useSnapshot;
|
package/dist/esm/index.js
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { createSubscriber, getReactishValues, isEqual } from '../utils.js';
|
|
3
|
+
import { useSnapshot } from './useSnapshot.js';
|
|
4
|
+
|
|
5
|
+
const useSelector = (selectorParamFactory, deps) => {
|
|
6
|
+
const items = selectorParamFactory();
|
|
7
|
+
const cutoff = items.length - 1;
|
|
8
|
+
const selectorFunc = items[cutoff];
|
|
9
|
+
items.length = cutoff;
|
|
10
|
+
const [context] = useState(() => ({
|
|
11
|
+
sub: createSubscriber(items)
|
|
12
|
+
}));
|
|
13
|
+
const get = () => {
|
|
14
|
+
const {
|
|
15
|
+
cache
|
|
16
|
+
} = context;
|
|
17
|
+
const reactishValues = getReactishValues(items);
|
|
18
|
+
const args = reactishValues.concat(deps || selectorFunc);
|
|
19
|
+
if (cache && isEqual(args, cache.args)) return cache.val;
|
|
20
|
+
const val = selectorFunc(...reactishValues);
|
|
21
|
+
context.cache = {
|
|
22
|
+
args,
|
|
23
|
+
val
|
|
24
|
+
};
|
|
25
|
+
return val;
|
|
26
|
+
};
|
|
27
|
+
return useSnapshot({
|
|
28
|
+
get,
|
|
29
|
+
subscribe: context.sub
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export { useSelector };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const isEqual = (args1, args2) => {
|
|
2
|
+
for (let i = 0; i < args1.length; i++) {
|
|
3
|
+
if (!Object.is(args1[i], args2[i])) return false;
|
|
4
|
+
}
|
|
5
|
+
return true;
|
|
6
|
+
};
|
|
7
|
+
const createSubscriber = items => listener => {
|
|
8
|
+
const unsubscribers = items.map(item => item.subscribe(listener));
|
|
9
|
+
return () => unsubscribers.forEach(unsubscribe => unsubscribe());
|
|
10
|
+
};
|
|
11
|
+
const getReactishValues = items => items.map(item => item.get());
|
|
12
|
+
|
|
13
|
+
export { createSubscriber, getReactishValues, isEqual };
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
if (!Object.is(args1[i], args2[i])) return false;
|
|
4
|
-
}
|
|
5
|
-
return true;
|
|
6
|
-
};
|
|
1
|
+
import { getReactishValues, createSubscriber, isEqual } from '../utils.js';
|
|
2
|
+
|
|
7
3
|
const createSelector = ({
|
|
8
4
|
plugin
|
|
9
5
|
} = {}) => (...items) => {
|
|
@@ -17,19 +13,16 @@ const createSelector = ({
|
|
|
17
13
|
let cache;
|
|
18
14
|
const selector = {
|
|
19
15
|
get: () => {
|
|
20
|
-
const args = items
|
|
21
|
-
if (cache && isEqual(args, cache.args)) return cache.
|
|
22
|
-
const
|
|
16
|
+
const args = getReactishValues(items);
|
|
17
|
+
if (cache && isEqual(args, cache.args)) return cache.val;
|
|
18
|
+
const val = selectorFunc(...args);
|
|
23
19
|
cache = {
|
|
24
20
|
args,
|
|
25
|
-
|
|
21
|
+
val
|
|
26
22
|
};
|
|
27
|
-
return
|
|
23
|
+
return val;
|
|
28
24
|
},
|
|
29
|
-
subscribe:
|
|
30
|
-
const unsubscribers = items.map(item => item.subscribe(listener));
|
|
31
|
-
return () => unsubscribers.forEach(unsubscribe => unsubscribe());
|
|
32
|
-
}
|
|
25
|
+
subscribe: createSubscriber(items)
|
|
33
26
|
};
|
|
34
27
|
plugin == null ? void 0 : plugin(selector, config);
|
|
35
28
|
return selector;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reactish-state",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0-alpha.0",
|
|
4
4
|
"description": "Simple, decentralized state management for React.",
|
|
5
5
|
"author": "Zheng Song",
|
|
6
6
|
"license": "MIT",
|
|
@@ -73,35 +73,35 @@
|
|
|
73
73
|
"use-sync-external-store": "^1.2.0"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@babel/core": "^7.
|
|
77
|
-
"@babel/preset-env": "^7.
|
|
76
|
+
"@babel/core": "^7.21.4",
|
|
77
|
+
"@babel/preset-env": "^7.21.4",
|
|
78
78
|
"@babel/preset-react": "^7.18.6",
|
|
79
|
-
"@babel/preset-typescript": "^7.
|
|
79
|
+
"@babel/preset-typescript": "^7.21.4",
|
|
80
80
|
"@redux-devtools/extension": "^3.2.5",
|
|
81
81
|
"@rollup/plugin-babel": "^6.0.3",
|
|
82
|
-
"@rollup/plugin-node-resolve": "^15.0.
|
|
82
|
+
"@rollup/plugin-node-resolve": "^15.0.2",
|
|
83
83
|
"@testing-library/jest-dom": "^5.16.5",
|
|
84
|
-
"@testing-library/react": "^
|
|
85
|
-
"@types/jest": "^29.
|
|
86
|
-
"@types/react": "^18.0.
|
|
84
|
+
"@testing-library/react": "^14.0.0",
|
|
85
|
+
"@types/jest": "^29.5.0",
|
|
86
|
+
"@types/react": "^18.0.34",
|
|
87
87
|
"@types/use-sync-external-store": "^0.0.3",
|
|
88
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
89
|
-
"@typescript-eslint/parser": "^5.
|
|
88
|
+
"@typescript-eslint/eslint-plugin": "^5.58.0",
|
|
89
|
+
"@typescript-eslint/parser": "^5.58.0",
|
|
90
90
|
"babel-plugin-pure-annotations": "^0.1.2",
|
|
91
|
-
"eslint": "^8.
|
|
92
|
-
"eslint-config-prettier": "^8.
|
|
91
|
+
"eslint": "^8.38.0",
|
|
92
|
+
"eslint-config-prettier": "^8.8.0",
|
|
93
93
|
"eslint-plugin-jest": "^27.2.1",
|
|
94
|
-
"eslint-plugin-react": "^7.32.
|
|
94
|
+
"eslint-plugin-react": "^7.32.2",
|
|
95
95
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
96
96
|
"eslint-plugin-react-hooks-addons": "^0.3.1",
|
|
97
|
-
"immer": "^9.0.
|
|
98
|
-
"jest": "^29.
|
|
99
|
-
"jest-environment-jsdom": "^29.
|
|
97
|
+
"immer": "^9.0.21",
|
|
98
|
+
"jest": "^29.5.0",
|
|
99
|
+
"jest-environment-jsdom": "^29.5.0",
|
|
100
100
|
"npm-run-all": "^4.1.5",
|
|
101
|
-
"prettier": "^2.8.
|
|
101
|
+
"prettier": "^2.8.7",
|
|
102
102
|
"react": "^18.2.0",
|
|
103
103
|
"react-dom": "^18.2.0",
|
|
104
|
-
"rollup": "^3.
|
|
105
|
-
"typescript": "^
|
|
104
|
+
"rollup": "^3.20.2",
|
|
105
|
+
"typescript": "^5.0.4"
|
|
106
106
|
}
|
|
107
107
|
}
|
package/types/common.d.ts
CHANGED
|
@@ -20,3 +20,13 @@ export interface Middleware {
|
|
|
20
20
|
export interface Plugin {
|
|
21
21
|
<T>(reactish: Reactish<T>, config?: Config): void;
|
|
22
22
|
}
|
|
23
|
+
export type ReactishArray = Reactish<unknown>[];
|
|
24
|
+
export type ReactishValueArray<RA extends ReactishArray> = {
|
|
25
|
+
[index in keyof RA]: ReturnType<RA[index]['get']>;
|
|
26
|
+
};
|
|
27
|
+
export type SelectorFunc<RA extends ReactishArray, T> = (...args: ReactishValueArray<RA>) => T;
|
|
28
|
+
export type SelectorParams<RA extends ReactishArray, T> = [...RA, SelectorFunc<RA, T>];
|
|
29
|
+
export interface Selector {
|
|
30
|
+
<RA extends ReactishArray, T>(...items: SelectorParams<RA, T>): Reactish<T>;
|
|
31
|
+
<RA extends ReactishArray, T>(...items: [...SelectorParams<RA, T>, Config]): Reactish<T>;
|
|
32
|
+
}
|
package/types/index.d.ts
CHANGED
package/types/utils.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Subscriber, ReactishArray, ReactishValueArray } from './common';
|
|
2
|
+
export declare const isEqual: (args1: unknown[], args2: unknown[]) => boolean;
|
|
3
|
+
export declare const createSubscriber: (items: ReactishArray) => Subscriber;
|
|
4
|
+
export declare const getReactishValues: <RA extends ReactishArray>(items: ReactishArray) => ReactishValueArray<RA>;
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
type ReactishArray = Reactish<unknown>[];
|
|
3
|
-
type ReactishValueArray<R extends ReactishArray> = {
|
|
4
|
-
[index in keyof R]: ReturnType<R[index]['get']>;
|
|
5
|
-
};
|
|
6
|
-
type SelectorFunc<R extends ReactishArray, T> = (...args: ReactishValueArray<R>) => T;
|
|
7
|
-
interface Selector {
|
|
8
|
-
<R extends ReactishArray, T>(...items: [...R, SelectorFunc<R, T>]): Reactish<T>;
|
|
9
|
-
<R extends ReactishArray, T>(...items: [...R, SelectorFunc<R, T>, Config]): Reactish<T>;
|
|
10
|
-
}
|
|
1
|
+
import type { Plugin, Selector } from '../common';
|
|
11
2
|
declare const createSelector: ({ plugin }?: {
|
|
12
3
|
plugin?: Plugin | undefined;
|
|
13
4
|
}) => Selector;
|