@chhsiao1981/use-thunk 9.0.5 → 10.0.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/README.md +52 -55
- package/dist/index.js +1723 -0
- package/dist/index.umd.cjs +50 -0
- package/package.json +2 -2
- package/src/ThunkContext.tsx +34 -0
- package/src/dispatchFuncMap.ts +48 -4
- package/src/index.ts +4 -18
- package/src/init.ts +12 -30
- package/src/reduceMap.ts +0 -14
- package/src/registerThunk.ts +35 -0
- package/src/remove.ts +6 -32
- package/src/setRoot.ts +4 -1
- package/src/stateTypes.ts +0 -29
- package/src/states.ts +4 -1
- package/src/thunk.ts +1 -1
- package/src/thunkContextMap.ts +22 -0
- package/src/thunkContextTypes.ts +8 -0
- package/src/thunkModuleFuncMap.ts +0 -11
- package/src/useThunk.ts +31 -55
- package/src/useThunkReducer.ts +19 -22
- package/types/ThunkContext.d.ts +7 -0
- package/types/dispatchFuncMap.d.ts +6 -5
- package/types/index.d.ts +3 -8
- package/types/init.d.ts +1 -1
- package/types/registerThunk.d.ts +4 -0
- package/types/remove.d.ts +2 -2
- package/types/stateTypes.d.ts +0 -19
- package/types/thunk.d.ts +1 -1
- package/types/thunkContextMap.d.ts +15 -0
- package/types/thunkContextTypes.d.ts +8 -0
- package/types/thunkModuleFuncMap.d.ts +1 -5
- package/types/useThunk.d.ts +6 -3
- package/types/useThunkReducer.d.ts +3 -4
- package/src/addChild.ts +0 -16
- package/src/addLink.ts +0 -27
- package/src/addRelation.ts +0 -32
- package/src/getRelation.ts +0 -43
- package/src/removeChild.ts +0 -46
- package/src/removeLink.ts +0 -47
- package/src/removeRelation.ts +0 -84
- package/types/addChild.d.ts +0 -5
- package/types/addLink.d.ts +0 -6
- package/types/addRelation.d.ts +0 -6
- package/types/getRelation.d.ts +0 -5
- package/types/reducerModuleFuncMap.d.ts +0 -10
- package/types/removeChild.d.ts +0 -9
- package/types/removeLink.d.ts +0 -9
- package/types/removeRelation.d.ts +0 -12
- package/types/thunk-reducer.d.ts +0 -16
- package/types/thunkReducer.d.ts +0 -18
- package/types/useReducer.d.ts +0 -8
package/src/useThunk.ts
CHANGED
|
@@ -1,40 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { ActionFunc } from './action'
|
|
1
|
+
import { useMemo } from 'react'
|
|
3
2
|
import { createReducer } from './createReducer'
|
|
4
|
-
import
|
|
5
|
-
|
|
3
|
+
import {
|
|
4
|
+
constructDispatchMap,
|
|
5
|
+
type DispatchFuncMap,
|
|
6
|
+
type DispatchFuncMapByClassMap,
|
|
7
|
+
} from './dispatchFuncMap'
|
|
8
|
+
import type { ClassState, State } from './stateTypes'
|
|
6
9
|
import type { ThunkModule, ThunkModuleFunc } from './thunk'
|
|
7
|
-
import { DEFAULT_THUNK_MODULE_FUNC_MAP } from './thunkModuleFuncMap'
|
|
8
10
|
import useThunkReducer from './useThunkReducer'
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
// biome-ignore lint/suspicious/noExplicitAny: DISPACH_MAP_BY_CLASS can by any type
|
|
13
|
+
const DISPACH_MAP_BY_CLASS: DispatchFuncMapByClassMap<any, any> = {}
|
|
14
|
+
|
|
15
|
+
export type UseThunk<S extends State, R extends ThunkModuleFunc<S>> = [
|
|
16
|
+
ClassState<S>,
|
|
17
|
+
DispatchFuncMap<S, R>,
|
|
18
|
+
]
|
|
11
19
|
|
|
12
20
|
/**********
|
|
13
21
|
* useThunk
|
|
14
22
|
**********/
|
|
15
23
|
export default <S extends State, R extends ThunkModuleFunc<S>>(
|
|
16
24
|
theDo: ThunkModule<S, R>,
|
|
17
|
-
// biome-ignore lint/suspicious/noExplicitAny: params can by any types.
|
|
18
|
-
init?: (...params: any[]) => S,
|
|
19
25
|
): UseThunk<S, R> => {
|
|
20
26
|
const { myClass } = theDo
|
|
21
27
|
|
|
22
28
|
// 1. dispatchMapByClass
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
//
|
|
30
|
+
// INFO The reason why we need to useRef is because we don't want to
|
|
31
|
+
// rebuild dispatchMap every time we call useThunk.
|
|
32
|
+
const dispatchMapByClass: DispatchFuncMapByClassMap<S, R> = DISPACH_MAP_BY_CLASS
|
|
25
33
|
|
|
26
34
|
// 2. It requires shared nodes for the same class to have the same dispatchMap.
|
|
27
35
|
// We don't optimize the dispatchMap in this PR.
|
|
28
36
|
const isFirstTime = !dispatchMapByClass[myClass]
|
|
29
37
|
if (isFirstTime) {
|
|
30
|
-
// @ts-expect-error
|
|
38
|
+
// @ts-expect-error init dispatchMap
|
|
31
39
|
dispatchMapByClass[myClass] = {}
|
|
32
40
|
}
|
|
33
41
|
const dispatchMap = dispatchMapByClass[myClass]
|
|
34
42
|
|
|
35
|
-
// 3. local nodes
|
|
36
|
-
const nodes: NodeStateMap<S> = {}
|
|
37
|
-
|
|
38
43
|
// 4. reducer.
|
|
39
44
|
// using useState to have theDo.default as optional.
|
|
40
45
|
// theReducer won't be changed.
|
|
@@ -44,52 +49,23 @@ export default <S extends State, R extends ThunkModuleFunc<S>>(
|
|
|
44
49
|
// However, because theReducer is a pure function
|
|
45
50
|
// having ClassState as the input. It is ok to have
|
|
46
51
|
// different reducers within the same class.
|
|
47
|
-
|
|
52
|
+
//
|
|
53
|
+
// INFO useMemo is to avoid accidental re-init createReducer every-time.
|
|
54
|
+
const theReducer = useMemo(() => theDo.default ?? createReducer<S>(), [])
|
|
48
55
|
|
|
49
56
|
// 5. useThunkReducer
|
|
50
|
-
const [classState, dispatch] = useThunkReducer(
|
|
51
|
-
theReducer,
|
|
52
|
-
{
|
|
53
|
-
myClass,
|
|
54
|
-
// @ts-expect-error doMe is a hidden variable for ClassState
|
|
55
|
-
doMe: dispatchMap,
|
|
56
|
-
nodes,
|
|
57
|
-
},
|
|
58
|
-
init,
|
|
59
|
-
)
|
|
57
|
+
const [classState, dispatch] = useThunkReducer(theReducer, myClass)
|
|
60
58
|
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
if (!isFirstTime) {
|
|
59
|
+
// INFO useMemo is to avoid accidental included in useEffect.
|
|
60
|
+
const ret: UseThunk<S, R> = useMemo(() => {
|
|
64
61
|
return [classState, dispatchMap]
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// 8. setup dispatchMap
|
|
68
|
-
Object.keys(theDo)
|
|
69
|
-
// default and myClass are reserved words.
|
|
70
|
-
// functions starting reduce are included in default and not exported.
|
|
71
|
-
.filter((each) => typeof theDo[each] === 'function')
|
|
72
|
-
.reduce((val, eachAction) => {
|
|
73
|
-
const action: ActionFunc<S> = theDo[eachAction]
|
|
74
|
-
// @ts-expect-error eachAction is in DispatchFuncMap<S, R>
|
|
75
|
-
// biome-ignore lint/suspicious/noExplicitAny: action parameters can be any types.
|
|
76
|
-
val[eachAction] = (...params: any[]) => dispatch(action(...params))
|
|
77
|
-
return val
|
|
78
|
-
}, dispatchMap)
|
|
62
|
+
}, [classState, dispatchMap])
|
|
79
63
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return val
|
|
84
|
-
}
|
|
85
|
-
// @ts-expect-error DEFAULT_REDUCER_MODULE_FUNCS are all ActionFunc<S>
|
|
86
|
-
const action: ActionFunc<S> = DEFAULT_THUNK_MODULE_FUNC_MAP[eachAction]
|
|
64
|
+
if (!isFirstTime) {
|
|
65
|
+
return ret
|
|
66
|
+
}
|
|
87
67
|
|
|
88
|
-
|
|
89
|
-
// biome-ignore lint/suspicious/noExplicitAny: action parameters can be any types.
|
|
90
|
-
val[eachAction] = (...params: any[]) => dispatch(action(...params))
|
|
91
|
-
return val
|
|
92
|
-
}, dispatchMap)
|
|
68
|
+
constructDispatchMap(theDo, dispatch, dispatchMap)
|
|
93
69
|
|
|
94
|
-
return
|
|
70
|
+
return ret
|
|
95
71
|
}
|
package/src/useThunkReducer.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
//https://medium.com/solute-labs/configuring-thunk-action-creators-and-redux-dev-tools-with-reacts-usereducer-hook-5a1608476812
|
|
2
2
|
//https://github.com/nathanbuchar/react-hook-thunk-reducer/blob/master/src/thunk-reducer.js
|
|
3
3
|
|
|
4
|
-
import { type Dispatch, type Reducer, useCallback,
|
|
4
|
+
import { type Dispatch, type Reducer, useCallback, useContext } from 'react'
|
|
5
5
|
import type { BaseAction } from './action'
|
|
6
6
|
import type { ClassState, State } from './stateTypes'
|
|
7
|
+
import { THUNK_CONTEXT_MAP } from './thunkContextMap'
|
|
7
8
|
|
|
8
9
|
export type Thunk<S extends State, A extends BaseAction> = (
|
|
9
10
|
dispatch: Dispatch<ActionOrThunk<S, A>>,
|
|
@@ -18,39 +19,34 @@ export type ActionOrThunk<S extends State, A extends BaseAction> = A | Thunk<S,
|
|
|
18
19
|
* dispatcher supports thunks.
|
|
19
20
|
*
|
|
20
21
|
* @param {Function} reducer
|
|
21
|
-
* @param {
|
|
22
|
-
* @
|
|
23
|
-
* @returns {[State, Dispatch]}
|
|
22
|
+
* @param {string} className
|
|
23
|
+
* @returns {[ClassState<S>, Dispatch]}
|
|
24
24
|
*/
|
|
25
25
|
export default <S extends State, A extends BaseAction>(
|
|
26
26
|
reducer: Reducer<ClassState<S>, A>,
|
|
27
|
-
|
|
28
|
-
init?: (initArg: ClassState<S>) => ClassState<S>,
|
|
27
|
+
className: string,
|
|
29
28
|
): [ClassState<S>, Dispatch<A | Thunk<S, A>>] => {
|
|
30
|
-
|
|
31
|
-
const initClassState = init ? () => init(initArg) : initArg
|
|
29
|
+
const { context } = THUNK_CONTEXT_MAP.theMap[className]
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
const
|
|
31
|
+
const { refClassState, setClassState: setClassState_c } = useContext(context)
|
|
32
|
+
const getClassState = useCallback(() => {
|
|
33
|
+
return refClassState.current
|
|
34
|
+
}, [refClassState])
|
|
35
35
|
|
|
36
|
-
// 3. hookState
|
|
37
|
-
const hookClassState = renderClassState
|
|
38
|
-
|
|
39
|
-
// 4. state management.
|
|
40
|
-
const classState = useRef(hookClassState)
|
|
41
|
-
const getClassState = useCallback(() => classState.current, [classState])
|
|
42
36
|
const setClassState = useCallback(
|
|
43
37
|
(newClassState: ClassState<S>) => {
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
refClassState.current = newClassState
|
|
39
|
+
setClassState_c(newClassState)
|
|
46
40
|
},
|
|
47
|
-
[
|
|
41
|
+
[refClassState, setClassState_c],
|
|
48
42
|
)
|
|
49
43
|
|
|
50
44
|
// 5. reducer.
|
|
51
45
|
const reduce = useCallback(
|
|
52
46
|
(action: A): ClassState<S> => {
|
|
53
|
-
|
|
47
|
+
const classState = getClassState()
|
|
48
|
+
const newClassState = reducer(classState, action)
|
|
49
|
+
return newClassState
|
|
54
50
|
},
|
|
55
51
|
[reducer, getClassState],
|
|
56
52
|
)
|
|
@@ -63,10 +59,11 @@ export default <S extends State, A extends BaseAction>(
|
|
|
63
59
|
return
|
|
64
60
|
}
|
|
65
61
|
|
|
66
|
-
|
|
62
|
+
const newClassState = reduce(action)
|
|
63
|
+
setClassState(newClassState)
|
|
67
64
|
},
|
|
68
65
|
[getClassState, setClassState, reduce],
|
|
69
66
|
)
|
|
70
67
|
|
|
71
|
-
return [
|
|
68
|
+
return [refClassState.current, dispatch]
|
|
72
69
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
type Props = {
|
|
3
|
+
classes?: string[];
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
};
|
|
6
|
+
declare const ThunkContext: (props: Props) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
|
|
7
|
+
export default ThunkContext;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { BaseAction } from './action';
|
|
1
2
|
import type { State } from './stateTypes';
|
|
2
|
-
import type { ThunkModuleFunc } from './thunk';
|
|
3
|
-
import type
|
|
3
|
+
import type { ThunkModule, ThunkModuleFunc } from './thunk';
|
|
4
|
+
import { type DefaultThunkModuleFuncMap } from './thunkModuleFuncMap';
|
|
5
|
+
import type { Thunk as rThunk } from './useThunkReducer';
|
|
4
6
|
type VoidReturnType<T extends (...params: any[]) => unknown> = (...params: Parameters<T>) => void;
|
|
5
7
|
export type DispatchFuncMap<S extends State, T extends ThunkModuleFunc<S>> = {
|
|
6
8
|
[action in keyof T]: VoidReturnType<T[action]>;
|
|
@@ -11,7 +13,6 @@ export type DefaultDispatchFuncMap = {
|
|
|
11
13
|
export interface DispatchFuncMapByClassMap<S extends State, T extends ThunkModuleFunc<S>> {
|
|
12
14
|
[className: string]: DispatchFuncMap<S, T>;
|
|
13
15
|
}
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
}
|
|
16
|
+
export declare const DISPATCH_FUNC_MAP_BY_CLASS_MAP: DispatchFuncMapByClassMap<any, any>;
|
|
17
|
+
export declare const constructDispatchMap: <S extends State, T extends ThunkModuleFunc<S>, A extends BaseAction>(theDo: ThunkModule<S, T>, dispatch: (action: A | rThunk<S, A>) => void, dispatchMap: DispatchFuncMap<S, T>) => DispatchFuncMap<S, T>;
|
|
17
18
|
export {};
|
package/types/index.d.ts
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
import type { GetClassState, Thunk } from './action';
|
|
2
|
-
import { addChild } from './addChild';
|
|
3
|
-
import { addLink } from './addLink';
|
|
4
|
-
import type { AddRelationAction } from './addRelation';
|
|
5
2
|
import type { Dispatch } from './dispatch';
|
|
6
3
|
import type { DispatchFuncMap } from './dispatchFuncMap';
|
|
7
4
|
import { genUUID } from './genUUID';
|
|
8
|
-
import { getChildID, getChildIDs, getLinkID, getLinkIDs } from './getRelation';
|
|
9
5
|
import { type InitParams, init } from './init';
|
|
6
|
+
import registerThunk from './registerThunk';
|
|
10
7
|
import { remove } from './remove';
|
|
11
|
-
import { removeChild } from './removeChild';
|
|
12
|
-
import { removeLink } from './removeLink';
|
|
13
|
-
import type { RemoveRelationAction } from './removeRelation';
|
|
14
8
|
import { setData } from './setData';
|
|
15
9
|
import { getNode, getRootID, getState } from './states';
|
|
16
10
|
import type { ClassState, NodeMeta, NodeState, NodeStateMap, State } from './stateTypes';
|
|
11
|
+
import ThunkContext from './ThunkContext';
|
|
17
12
|
import type { ThunkModule, ThunkModuleToFunc } from './thunk';
|
|
18
13
|
import useThunk, { type UseThunk } from './useThunk';
|
|
19
|
-
export { useThunk, type UseThunk, type State, type NodeState, type NodeMeta, type NodeStateMap, type ClassState, type GetClassState, type Thunk, type ThunkModule, type ThunkModuleToFunc, type Dispatch, type DispatchFuncMap, getRootID, getNode, getState,
|
|
14
|
+
export { registerThunk, useThunk, ThunkContext, type UseThunk, type State, type NodeState, type NodeMeta, type NodeStateMap, type ClassState, type GetClassState, type Thunk, type ThunkModule, type ThunkModuleToFunc, type Dispatch, type DispatchFuncMap, getRootID, getNode, getState, init, type InitParams, setData, remove, genUUID, };
|
package/types/init.d.ts
CHANGED
package/types/remove.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BaseAction, Thunk } from './action';
|
|
2
|
-
import {
|
|
3
|
-
export declare const remove: <S extends State>(myID: string
|
|
2
|
+
import type { ClassState, State } from './stateTypes';
|
|
3
|
+
export declare const remove: <S extends State>(myID: string) => Thunk<S>;
|
|
4
4
|
export declare const REMOVE = "@chhsiao1981/use-thunk/REMOVE";
|
|
5
5
|
export declare const reduceRemove: <S extends State>(classState: ClassState<S>, action: BaseAction) => ClassState<S>;
|
package/types/stateTypes.d.ts
CHANGED
|
@@ -1,27 +1,9 @@
|
|
|
1
|
-
export declare enum StateType {
|
|
2
|
-
LOCAL = "local"
|
|
3
|
-
}
|
|
4
|
-
export declare enum Relation {
|
|
5
|
-
CHILDREN = "_children",
|
|
6
|
-
LINKS = "_links"
|
|
7
|
-
}
|
|
8
|
-
export declare const PARENT = "_parent";
|
|
9
1
|
export interface State {
|
|
10
2
|
[key: string]: unknown;
|
|
11
3
|
}
|
|
12
4
|
export type NodeState<S extends State> = {
|
|
13
5
|
id: string;
|
|
14
6
|
state: S;
|
|
15
|
-
[Relation.CHILDREN]?: NodeStateRelationMap | null;
|
|
16
|
-
[PARENT]?: NodeMeta | null;
|
|
17
|
-
[Relation.LINKS]?: NodeStateRelationMap | null;
|
|
18
|
-
};
|
|
19
|
-
type NodeStateRelationMap = {
|
|
20
|
-
[relationClass: string]: NodeStateRelation;
|
|
21
|
-
};
|
|
22
|
-
type NodeStateRelation = {
|
|
23
|
-
list: string[];
|
|
24
|
-
do: DispatchFuncMap;
|
|
25
7
|
};
|
|
26
8
|
export type NodeStateMap<S extends State> = {
|
|
27
9
|
[key: string]: NodeState<S>;
|
|
@@ -39,4 +21,3 @@ export type NodeMeta = {
|
|
|
39
21
|
theClass: string;
|
|
40
22
|
do: DispatchFuncMap;
|
|
41
23
|
};
|
|
42
|
-
export {};
|
package/types/thunk.d.ts
CHANGED
|
@@ -7,6 +7,6 @@ export interface ThunkModuleFunc<S extends State> {
|
|
|
7
7
|
export type ThunkModule<S extends State, T extends ThunkModuleFunc<S>> = {
|
|
8
8
|
myClass: string;
|
|
9
9
|
default?: Reducer<S>;
|
|
10
|
-
defaultState
|
|
10
|
+
defaultState: S;
|
|
11
11
|
} & T;
|
|
12
12
|
export type ThunkModuleToFunc<T> = Omit<T, 'myClass' | 'default' | 'defaultState'>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Context as rContext } from 'react';
|
|
2
|
+
import type { ClassState } from './stateTypes';
|
|
3
|
+
import type { Context } from './thunkContextTypes';
|
|
4
|
+
export type ThunkContextMap = {
|
|
5
|
+
theMap: {
|
|
6
|
+
[classname: string]: {
|
|
7
|
+
context: rContext<Context<any>>;
|
|
8
|
+
refClassState: {
|
|
9
|
+
current: ClassState<any>;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
theList: string[];
|
|
14
|
+
};
|
|
15
|
+
export declare const THUNK_CONTEXT_MAP: ThunkContextMap;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
import type { ClassState, State } from './stateTypes';
|
|
3
|
+
export type Context<S extends State> = {
|
|
4
|
+
refClassState: {
|
|
5
|
+
current: ClassState<S>;
|
|
6
|
+
};
|
|
7
|
+
setClassState: Dispatch<SetStateAction<ClassState<S>>>;
|
|
8
|
+
};
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
export declare const DEFAULT_THUNK_MODULE_FUNC_MAP: {
|
|
2
2
|
init: <S extends import("./stateTypes").State>(params: import("./init").InitParams<S>, myuuidv4?: () => string) => import("./action").Thunk<S>;
|
|
3
3
|
setData: <S extends import("./stateTypes").State>(myID: string, data: Partial<S>) => import("./action").BaseAction;
|
|
4
|
-
remove: <S extends import("./stateTypes").State>(myID: string
|
|
5
|
-
addChild: (myID: string, child: import("./stateTypes").NodeMeta) => import("./addRelation").AddRelationAction;
|
|
6
|
-
removeChild: <S extends import("./stateTypes").State>(myID: string, childID: string, childClass: string, isFromChild?: boolean) => import("./action").Thunk<S>;
|
|
7
|
-
addLink: <S extends import("./stateTypes").State>(myID: string, link: import("./stateTypes").NodeMeta, isFromLink?: boolean) => import("./action").Thunk<S>;
|
|
8
|
-
removeLink: <S extends import("./stateTypes").State>(myID: string, linkID: string, linkClass: string, isFromLink?: boolean) => import("./action").Thunk<S>;
|
|
4
|
+
remove: <S extends import("./stateTypes").State>(myID: string) => import("./action").Thunk<S>;
|
|
9
5
|
};
|
|
10
6
|
export type DefaultThunkModuleFuncMap = typeof DEFAULT_THUNK_MODULE_FUNC_MAP;
|
package/types/useThunk.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type DispatchFuncMap } from './dispatchFuncMap';
|
|
2
2
|
import type { ClassState, State } from './stateTypes';
|
|
3
3
|
import type { ThunkModule, ThunkModuleFunc } from './thunk';
|
|
4
|
-
export type UseThunk<S extends State, R extends ThunkModuleFunc<S>> = [
|
|
4
|
+
export type UseThunk<S extends State, R extends ThunkModuleFunc<S>> = [
|
|
5
|
+
ClassState<S>,
|
|
6
|
+
DispatchFuncMap<S, R>
|
|
7
|
+
];
|
|
5
8
|
/**********
|
|
6
9
|
* useThunk
|
|
7
10
|
**********/
|
|
8
|
-
declare const _default: <S extends State, R extends ThunkModuleFunc<S>>(theDo: ThunkModule<S, R
|
|
11
|
+
declare const _default: <S extends State, R extends ThunkModuleFunc<S>>(theDo: ThunkModule<S, R>) => UseThunk<S, R>;
|
|
9
12
|
export default _default;
|
|
@@ -10,9 +10,8 @@ export type ActionOrThunk<S extends State, A extends BaseAction> = A | Thunk<S,
|
|
|
10
10
|
* dispatcher supports thunks.
|
|
11
11
|
*
|
|
12
12
|
* @param {Function} reducer
|
|
13
|
-
* @param {
|
|
14
|
-
* @
|
|
15
|
-
* @returns {[State, Dispatch]}
|
|
13
|
+
* @param {string} className
|
|
14
|
+
* @returns {[ClassState<S>, Dispatch]}
|
|
16
15
|
*/
|
|
17
|
-
declare const _default: <S extends State, A extends BaseAction>(reducer: Reducer<ClassState<S>, A>,
|
|
16
|
+
declare const _default: <S extends State, A extends BaseAction>(reducer: Reducer<ClassState<S>, A>, className: string) => [ClassState<S>, Dispatch<A | Thunk<S, A>>];
|
|
18
17
|
export default _default;
|
package/src/addChild.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { type AddRelationAction, reduceAddRelation } from './addRelation'
|
|
2
|
-
import { type ClassState, type NodeMeta, Relation, type State } from './stateTypes'
|
|
3
|
-
|
|
4
|
-
export const ADD_CHILD = '@chhsiao1981/use-thunk/ADD_CHILD'
|
|
5
|
-
export const addChild = (myID: string, child: NodeMeta): AddRelationAction => ({
|
|
6
|
-
myID,
|
|
7
|
-
type: ADD_CHILD,
|
|
8
|
-
relaton: child,
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
export const reduceAddChild = <S extends State>(
|
|
12
|
-
classState: ClassState<S>,
|
|
13
|
-
action: AddRelationAction,
|
|
14
|
-
): ClassState<S> => {
|
|
15
|
-
return reduceAddRelation(classState, action, Relation.CHILDREN)
|
|
16
|
-
}
|
package/src/addLink.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { Thunk } from './action'
|
|
2
|
-
import { type AddRelationAction, reduceAddRelation } from './addRelation'
|
|
3
|
-
import { type ClassState, type NodeMeta, Relation, type State } from './stateTypes'
|
|
4
|
-
|
|
5
|
-
export const addLink = <S extends State>(myID: string, link: NodeMeta, isFromLink = false): Thunk<S> => {
|
|
6
|
-
return (dispatch, getClassState) => {
|
|
7
|
-
dispatch(addLinkCore(myID, link))
|
|
8
|
-
|
|
9
|
-
if (!isFromLink) {
|
|
10
|
-
// I connect to the other, would like the other to connect to me as well.
|
|
11
|
-
// @ts-expect-error XXX doMe is a hidden variable for links.
|
|
12
|
-
const { doMe, myClass } = getClassState()
|
|
13
|
-
link.do.addLink(link.id, { id: myID, theClass: myClass, do: doMe }, true)
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const ADD_LINK = '@chhsiao1981/use-thunk/ADD_LINK'
|
|
19
|
-
const addLinkCore = (myID: string, link: NodeMeta): AddRelationAction => ({
|
|
20
|
-
myID,
|
|
21
|
-
type: ADD_LINK,
|
|
22
|
-
relaton: link,
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
export const reduceAddLink = <S extends State>(classState: ClassState<S>, action: AddRelationAction): ClassState<S> => {
|
|
26
|
-
return reduceAddRelation(classState, action, Relation.LINKS)
|
|
27
|
-
}
|
package/src/addRelation.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { BaseAction } from './action'
|
|
2
|
-
import type { ClassState, NodeMeta, Relation, State } from './stateTypes'
|
|
3
|
-
|
|
4
|
-
export interface AddRelationAction extends BaseAction {
|
|
5
|
-
relaton: NodeMeta
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export const reduceAddRelation = <S extends State>(
|
|
9
|
-
classState: ClassState<S>,
|
|
10
|
-
action: AddRelationAction,
|
|
11
|
-
relationName: Relation,
|
|
12
|
-
): ClassState<S> => {
|
|
13
|
-
const { myID, relaton: relation } = action
|
|
14
|
-
const myNode = classState.nodes[myID]
|
|
15
|
-
if (!myNode) {
|
|
16
|
-
return classState
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const { theClass, id: theID, do: theDo } = relation
|
|
20
|
-
|
|
21
|
-
const relations = myNode[relationName] ?? {}
|
|
22
|
-
const relationsByClass = relations[theClass] ?? { list: [] }
|
|
23
|
-
const relationIDs = relationsByClass.list ?? []
|
|
24
|
-
const newIDs = theID ? relationIDs.concat([theID]) : relationIDs
|
|
25
|
-
|
|
26
|
-
const newRelations = Object.assign({}, myNode[relationName], { [theClass]: { list: newIDs, do: theDo } })
|
|
27
|
-
const newMyNode = Object.assign({}, myNode, { [relationName]: newRelations })
|
|
28
|
-
const newNodes = Object.assign({}, classState.nodes, { [myID]: newMyNode })
|
|
29
|
-
const newClassState = Object.assign({}, classState, { nodes: newNodes })
|
|
30
|
-
|
|
31
|
-
return newClassState
|
|
32
|
-
}
|
package/src/getRelation.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { type NodeState, Relation, type State } from './stateTypes'
|
|
2
|
-
|
|
3
|
-
export const getChildIDs = <S extends State>(myNode: NodeState<S>, childClass: string): string[] => {
|
|
4
|
-
return getRelationIDs(myNode, childClass, Relation.CHILDREN)
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export const getChildID = <S extends State>(myNode: NodeState<S>, childClass: string): string => {
|
|
8
|
-
return getRelationID(myNode, childClass, Relation.CHILDREN)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const getLinkIDs = <S extends State>(myNode: NodeState<S>, linkClass: string): string[] => {
|
|
12
|
-
return getRelationIDs(myNode, linkClass, Relation.LINKS)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const getLinkID = <S extends State>(myNode: NodeState<S>, linkClass: string): string => {
|
|
16
|
-
return getRelationID(myNode, linkClass, Relation.LINKS)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const getRelationIDs = <S extends State>(
|
|
20
|
-
myNode: NodeState<S>,
|
|
21
|
-
relationClass: string,
|
|
22
|
-
relationName: Relation,
|
|
23
|
-
): string[] => {
|
|
24
|
-
const relations = myNode[relationName]
|
|
25
|
-
if (!relations) {
|
|
26
|
-
return []
|
|
27
|
-
}
|
|
28
|
-
const relationsByClass = relations[relationClass]
|
|
29
|
-
if (!relationsByClass) {
|
|
30
|
-
return []
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return relationsByClass.list
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const getRelationID = <S extends State>(
|
|
37
|
-
myNode: NodeState<S>,
|
|
38
|
-
relationClass: string,
|
|
39
|
-
relationName: Relation,
|
|
40
|
-
): string => {
|
|
41
|
-
const ids = getRelationIDs(myNode, relationClass, relationName)
|
|
42
|
-
return ids.length ? ids[0] : ''
|
|
43
|
-
}
|
package/src/removeChild.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { Thunk } from './action'
|
|
2
|
-
import { type RemoveRelationAction, reduceRemoveRelation, removeRelation } from './removeRelation'
|
|
3
|
-
import { type ClassState, Relation, type State } from './stateTypes'
|
|
4
|
-
|
|
5
|
-
/***
|
|
6
|
-
* remove-child
|
|
7
|
-
*/
|
|
8
|
-
export const removeChild = <S extends State>(
|
|
9
|
-
myID: string,
|
|
10
|
-
childID: string,
|
|
11
|
-
childClass: string,
|
|
12
|
-
isFromChild = false,
|
|
13
|
-
): Thunk<S> => {
|
|
14
|
-
return (dispatch, getClassState) => {
|
|
15
|
-
// @ts-expect-error theDo (from child) can by any type
|
|
16
|
-
const relationRemove = (theDo: DispatchFuncMap) => theDo.remove(childID, true)
|
|
17
|
-
removeRelation(
|
|
18
|
-
dispatch,
|
|
19
|
-
getClassState,
|
|
20
|
-
myID,
|
|
21
|
-
childID,
|
|
22
|
-
childClass,
|
|
23
|
-
isFromChild,
|
|
24
|
-
relationRemove,
|
|
25
|
-
removeChildCore,
|
|
26
|
-
Relation.CHILDREN,
|
|
27
|
-
)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const REMOVE_CHILD = '@chhsiao1981/use-thunk/REMOVE_CHILD'
|
|
32
|
-
const removeChildCore = (myID: string, childID: string, childClass: string): RemoveRelationAction => ({
|
|
33
|
-
myID,
|
|
34
|
-
type: REMOVE_CHILD,
|
|
35
|
-
relationID: childID,
|
|
36
|
-
relationClass: childClass,
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
export const reduceRemoveChild = <S extends State>(
|
|
40
|
-
classState: ClassState<S>,
|
|
41
|
-
action: RemoveRelationAction,
|
|
42
|
-
): ClassState<S> => {
|
|
43
|
-
const { myID, relationID, relationClass } = action
|
|
44
|
-
|
|
45
|
-
return reduceRemoveRelation(classState, myID, relationID, relationClass, Relation.CHILDREN)
|
|
46
|
-
}
|
package/src/removeLink.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { Thunk } from './action'
|
|
2
|
-
import { type RemoveRelationAction, reduceRemoveRelation, removeRelation } from './removeRelation'
|
|
3
|
-
import { type ClassState, Relation, type State } from './stateTypes'
|
|
4
|
-
|
|
5
|
-
/***
|
|
6
|
-
* remove-link
|
|
7
|
-
*/
|
|
8
|
-
export const removeLink = <S extends State>(
|
|
9
|
-
myID: string,
|
|
10
|
-
linkID: string,
|
|
11
|
-
linkClass: string,
|
|
12
|
-
isFromLink = false,
|
|
13
|
-
): Thunk<S> => {
|
|
14
|
-
return (dispatch, getClassState) => {
|
|
15
|
-
const myClass = getClassState().myClass
|
|
16
|
-
// @ts-expect-error theDo (from link) can be any type
|
|
17
|
-
const relationRemove = (theDo: DispatchFuncMap) => theDo.removeLink(linkID, myID, myClass, true)
|
|
18
|
-
removeRelation(
|
|
19
|
-
dispatch,
|
|
20
|
-
getClassState,
|
|
21
|
-
myID,
|
|
22
|
-
linkID,
|
|
23
|
-
linkClass,
|
|
24
|
-
isFromLink,
|
|
25
|
-
relationRemove,
|
|
26
|
-
removeLinkCore,
|
|
27
|
-
Relation.LINKS,
|
|
28
|
-
)
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export const REMOVE_LINK = '@chhsiao1981/use-thunk/REMOVE_LINK'
|
|
33
|
-
const removeLinkCore = (myID: string, linkID: string, linkClass: string): RemoveRelationAction => ({
|
|
34
|
-
myID,
|
|
35
|
-
type: REMOVE_LINK,
|
|
36
|
-
relationID: linkID,
|
|
37
|
-
relationClass: linkClass,
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
export const reduceRemoveLink = <S extends State>(
|
|
41
|
-
classState: ClassState<S>,
|
|
42
|
-
action: RemoveRelationAction,
|
|
43
|
-
): ClassState<S> => {
|
|
44
|
-
const { myID, relationID, relationClass } = action
|
|
45
|
-
|
|
46
|
-
return reduceRemoveRelation(classState, myID, relationID, relationClass, Relation.LINKS)
|
|
47
|
-
}
|