@chhsiao1981/use-thunk 10.3.0 → 10.4.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/package.json +2 -2
- package/src/ThunkContext.tsx +14 -9
- package/src/dispatchFuncMap.ts +3 -2
- package/src/registerThunk.ts +10 -4
- package/src/thunk.ts +7 -3
- package/src/thunkContextMap.ts +1 -1
- package/src/useThunk.ts +1 -1
- package/src/useThunkReducer.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chhsiao1981/use-thunk",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A framework easily using useThunk to manage the data-state.",
|
|
6
6
|
"homepage": "https://github.com/chhsiao1981/use-thunk",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"vite": "^6.4.1",
|
|
57
57
|
"vitest": "^4.1.0"
|
|
58
58
|
},
|
|
59
|
-
"
|
|
59
|
+
"peerDependencies": {
|
|
60
60
|
"react": ">=18.3.1",
|
|
61
61
|
"uuid": "^14.0.0"
|
|
62
62
|
}
|
package/src/ThunkContext.tsx
CHANGED
|
@@ -1,28 +1,31 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ReactNode, useMemo, useState } from 'react'
|
|
2
2
|
import { THUNK_CONTEXT_MAP } from './thunkContextMap'
|
|
3
3
|
|
|
4
4
|
type Props = {
|
|
5
5
|
classes?: string[]
|
|
6
|
-
children?:
|
|
6
|
+
children?: ReactNode
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
|
|
9
|
+
const ThunkContext = (props: Props): ReactNode => {
|
|
10
|
+
const { classes: propsClasses, children } = props
|
|
11
|
+
const classes = propsClasses || THUNK_CONTEXT_MAP.theList
|
|
12
|
+
// 0. if there is no Thunk classes (no registerThunk): return children.
|
|
13
13
|
if (classes.length === 0) {
|
|
14
|
-
// @ts-expect-error with children
|
|
15
14
|
return children
|
|
16
15
|
}
|
|
17
16
|
|
|
17
|
+
// render the 0th class.
|
|
18
18
|
const theClass = classes[0]
|
|
19
19
|
|
|
20
|
+
// 1. get the context and classState from context map.
|
|
20
21
|
const { context: Context_m, refClassState } = THUNK_CONTEXT_MAP.theMap[theClass]
|
|
21
22
|
|
|
23
|
+
// 2. setup classState.
|
|
22
24
|
// biome-ignore lint/correctness/useHookAtTopLevel: the order is fixed.
|
|
23
25
|
const [classState, setClassState] = useState(refClassState.current)
|
|
24
|
-
|
|
25
26
|
refClassState.current = classState
|
|
27
|
+
|
|
28
|
+
// 3. value reset only if classState is changed.
|
|
26
29
|
// biome-ignore lint/correctness/useHookAtTopLevel: the order is fixed.
|
|
27
30
|
const value = useMemo(
|
|
28
31
|
() => ({
|
|
@@ -32,9 +35,11 @@ const ThunkContext = (props: Props): JSX.Element => {
|
|
|
32
35
|
[classState],
|
|
33
36
|
)
|
|
34
37
|
|
|
38
|
+
// 4. get theChildren
|
|
35
39
|
const theChildren =
|
|
36
40
|
classes.length === 1 ? children : ThunkContext({ classes: classes.slice(1), children })
|
|
37
41
|
|
|
42
|
+
// 5. return context.
|
|
38
43
|
return <Context_m.Provider value={value}>{theChildren}</Context_m.Provider>
|
|
39
44
|
}
|
|
40
45
|
|
package/src/dispatchFuncMap.ts
CHANGED
|
@@ -27,7 +27,7 @@ export const constructDispatchMap = <
|
|
|
27
27
|
T extends ThunkModuleFunc<S>,
|
|
28
28
|
A extends BaseAction,
|
|
29
29
|
>(
|
|
30
|
-
theDo: ThunkModule<S
|
|
30
|
+
theDo: ThunkModule<S>,
|
|
31
31
|
dispatch: (action: A | rThunk<S, A>) => void,
|
|
32
32
|
dispatchMap: DispatchFuncMap<S, T>,
|
|
33
33
|
) => {
|
|
@@ -40,7 +40,8 @@ export const constructDispatchMap = <
|
|
|
40
40
|
return val
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
// because action is a function.
|
|
44
|
+
const action = theDo[eachAction] as ActionFunc<S>
|
|
44
45
|
|
|
45
46
|
// @ts-expect-error eachAction is in DispatchFuncMap<S, R>
|
|
46
47
|
// biome-ignore lint/suspicious/noExplicitAny: action parameters can be any types.
|
package/src/registerThunk.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { createContext, type Dispatch, type SetStateAction } from 'react'
|
|
2
2
|
import type { ClassState, State } from './stateTypes'
|
|
3
|
-
import type { ThunkModule
|
|
3
|
+
import type { ThunkModule } from './thunk'
|
|
4
4
|
import { THUNK_CONTEXT_MAP } from './thunkContextMap'
|
|
5
5
|
|
|
6
|
-
export default <S extends State
|
|
6
|
+
export default <S extends State>(theDo: ThunkModule<S>) => {
|
|
7
7
|
const { myClass, defaultState } = theDo
|
|
8
8
|
|
|
9
9
|
if (THUNK_CONTEXT_MAP.theMap[myClass]) {
|
|
10
|
-
// already init
|
|
11
|
-
console.
|
|
10
|
+
// 1. already init
|
|
11
|
+
console.warn('regsterThunk: already init:', myClass)
|
|
12
12
|
return
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
// 2. to initialize classState, setClassState, and refClassState.
|
|
15
16
|
const classState: ClassState<S> = {
|
|
16
17
|
myClass,
|
|
17
18
|
nodes: {},
|
|
@@ -19,15 +20,20 @@ export default <S extends State, R extends ThunkModuleFunc<S>>(theDo: ThunkModul
|
|
|
19
20
|
}
|
|
20
21
|
const setClassState: Dispatch<SetStateAction<ClassState<S>>> = () => {}
|
|
21
22
|
const refClassState = { current: classState }
|
|
23
|
+
|
|
24
|
+
// 3. create context
|
|
22
25
|
const context = createContext({
|
|
23
26
|
refClassState,
|
|
24
27
|
setClassState,
|
|
25
28
|
})
|
|
26
29
|
|
|
30
|
+
// 4. setup THUNK_CONTEXT_MAP.theMap.
|
|
27
31
|
THUNK_CONTEXT_MAP.theMap[myClass] = {
|
|
28
32
|
context,
|
|
29
33
|
refClassState,
|
|
30
34
|
}
|
|
35
|
+
|
|
36
|
+
// 5. setup THUNK_CONTEXT_MAP.theList, to ensure the rendering order.
|
|
31
37
|
const theList = Object.keys(THUNK_CONTEXT_MAP.theMap)
|
|
32
38
|
theList.sort()
|
|
33
39
|
THUNK_CONTEXT_MAP.theList = theList
|
package/src/thunk.ts
CHANGED
|
@@ -2,15 +2,19 @@ import type { ActionFunc } from './action'
|
|
|
2
2
|
import type { Reducer } from './reducer'
|
|
3
3
|
import type { State } from './stateTypes'
|
|
4
4
|
|
|
5
|
-
export interface
|
|
5
|
+
export interface ThunkModuleBase<S extends State> {
|
|
6
|
+
[idx: string]: ActionFunc<S> | string | Reducer<S> | S | undefined
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ThunkModuleFunc<S extends State> extends ThunkModuleBase<S> {
|
|
6
10
|
[action: string]: ActionFunc<S>
|
|
7
11
|
}
|
|
8
12
|
|
|
9
13
|
// This is used as the parameter for useThunk.
|
|
10
|
-
export type ThunkModule<S extends State
|
|
14
|
+
export type ThunkModule<S extends State> = {
|
|
11
15
|
myClass: string
|
|
12
16
|
default?: Reducer<S>
|
|
13
17
|
defaultState: S
|
|
14
|
-
} &
|
|
18
|
+
} & ThunkModuleBase<S>
|
|
15
19
|
|
|
16
20
|
export type ThunkModuleToFunc<T> = Omit<T, 'myClass' | 'default' | 'defaultState'>
|
package/src/thunkContextMap.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type ThunkContextMap = {
|
|
|
8
8
|
// biome-ignore lint/suspicious/noExplicitAny: ThunkContextMap can be any type
|
|
9
9
|
context: rContext<Context<any>>
|
|
10
10
|
|
|
11
|
-
//
|
|
11
|
+
// we need to use refClassState to sync all the classState in all ops.
|
|
12
12
|
// biome-ignore lint/suspicious/noExplicitAny: ThunkContextMap can be any type
|
|
13
13
|
refClassState: { current: ClassState<any> }
|
|
14
14
|
}
|
package/src/useThunk.ts
CHANGED
|
@@ -21,7 +21,7 @@ export type UseThunk<S extends State, R extends ThunkModuleFunc<S>> = [
|
|
|
21
21
|
* useThunk
|
|
22
22
|
**********/
|
|
23
23
|
export default <S extends State, R extends ThunkModuleFunc<S>>(
|
|
24
|
-
theDo: ThunkModule<S
|
|
24
|
+
theDo: ThunkModule<S>,
|
|
25
25
|
): UseThunk<S, R> => {
|
|
26
26
|
const { myClass } = theDo
|
|
27
27
|
|
package/src/useThunkReducer.ts
CHANGED
|
@@ -55,10 +55,12 @@ export default <S extends State, A extends BaseAction>(
|
|
|
55
55
|
const dispatch = useCallback(
|
|
56
56
|
(action: A | Thunk<S, A>) => {
|
|
57
57
|
if (typeof action === 'function') {
|
|
58
|
+
// action is Thunk<S, A>
|
|
58
59
|
action(dispatch, getClassState)
|
|
59
60
|
return
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
// action is not function. so action is A
|
|
62
64
|
const newClassState = reduce(action)
|
|
63
65
|
setClassState(newClassState)
|
|
64
66
|
},
|