@chhsiao1981/use-thunk 12.0.0 → 14.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 +211 -122
- package/{types → dist}/action/ActionOrThunk.d.ts +1 -1
- package/{types → dist}/action/index.d.ts +2 -2
- package/dist/action/thunk.d.ts +5 -0
- package/dist/defaultThunks/index.d.ts +10 -0
- package/dist/defaultThunks/init/index.d.ts +9 -0
- package/{types → dist/defaultThunks}/init/initCore.d.ts +2 -2
- package/{types → dist/defaultThunks}/remove.d.ts +2 -2
- package/{types → dist/defaultThunks}/setDefaultID.d.ts +2 -2
- package/{types → dist/defaultThunks}/update.d.ts +2 -2
- package/dist/defaultThunks/upsert.d.ts +5 -0
- package/dist/dispatch.d.ts +3 -3
- package/dist/get.d.ts +3 -0
- package/dist/index.d.ts +11 -14
- package/dist/index.js +173 -0
- package/dist/index.umd.cjs +1 -0
- package/dist/reducer/createReducer.d.ts +3 -0
- package/dist/reducer/defaultReduceMap.d.ts +2 -0
- package/{types/reducer.d.ts → dist/reducer/index.d.ts} +4 -2
- package/dist/reducer/reduceMap.d.ts +5 -0
- package/{types/createThunk.d.ts → dist/registerThunk.d.ts} +1 -1
- package/dist/set/index.d.ts +5 -0
- package/dist/set/setMap.d.ts +16 -0
- package/dist/states/index.d.ts +10 -0
- package/{types/stateTypes.d.ts → dist/states/types.d.ts} +5 -4
- package/dist/thunkContext/ThunkContext.d.ts +7 -0
- package/dist/thunkContext/index.d.ts +6 -0
- package/{types → dist/thunkContext}/thunkContextMap.d.ts +2 -2
- package/{types/thunkContextTypes.d.ts → dist/thunkContext/types.d.ts} +1 -1
- package/dist/thunkModule/defaultDoModule.d.ts +5 -0
- package/dist/thunkModule/index.d.ts +13 -0
- package/dist/useThunk/index.d.ts +9 -0
- package/{types → dist/useThunk}/useThunkReducer.d.ts +3 -3
- package/dist/utils/deepCopy.d.ts +2 -0
- package/dist/utils/genID.d.ts +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/package.json +35 -30
- package/dist/ThunkContext.d.ts +0 -7
- package/dist/action.d.ts +0 -11
- package/dist/createReducer.d.ts +0 -4
- package/dist/createThunk.d.ts +0 -4
- package/dist/dispatchFuncMap.d.ts +0 -18
- package/dist/genUUID.d.ts +0 -1
- package/dist/init.d.ts +0 -16
- package/dist/reduceMap.d.ts +0 -6
- package/dist/reducer.d.ts +0 -5
- package/dist/remove.d.ts +0 -5
- package/dist/setDefaultID.d.ts +0 -5
- package/dist/stateTypes.d.ts +0 -16
- package/dist/states.d.ts +0 -9
- package/dist/thunk.d.ts +0 -15
- package/dist/thunkContextMap.d.ts +0 -15
- package/dist/thunkContextTypes.d.ts +0 -8
- package/dist/thunkModuleFuncMap.d.ts +0 -7
- package/dist/update.d.ts +0 -6
- package/dist/useThunk.d.ts +0 -12
- package/dist/useThunkReducer.d.ts +0 -17
- package/src/ThunkContext.tsx +0 -46
- package/src/action/ActionOrThunk.ts +0 -5
- package/src/action/baseAction.ts +0 -6
- package/src/action/index.ts +0 -16
- package/src/action/thunk.ts +0 -9
- package/src/createReducer.ts +0 -24
- package/src/createThunk.ts +0 -24
- package/src/genUUID.ts +0 -38
- package/src/get.ts +0 -3
- package/src/index.ts +0 -42
- package/src/init/index.ts +0 -26
- package/src/init/initCore.ts +0 -31
- package/src/reduceMap.ts +0 -22
- package/src/reducer.ts +0 -9
- package/src/remove.ts +0 -35
- package/src/set.ts +0 -7
- package/src/setDefaultID.ts +0 -17
- package/src/setMap.ts +0 -65
- package/src/stateTypes.ts +0 -22
- package/src/states.ts +0 -50
- package/src/thunkContextMap.ts +0 -22
- package/src/thunkContextTypes.ts +0 -8
- package/src/thunkModule/defaultThunkModuleFuncMap.ts +0 -15
- package/src/thunkModule/index.ts +0 -20
- package/src/update.ts +0 -26
- package/src/useThunk.ts +0 -50
- package/src/useThunkReducer.ts +0 -70
- package/types/ThunkContext.d.ts +0 -7
- package/types/action/thunk.d.ts +0 -3
- package/types/createReducer.d.ts +0 -4
- package/types/dispatch.d.ts +0 -4
- package/types/dispatchFuncMap.d.ts +0 -17
- package/types/genUUID.d.ts +0 -1
- package/types/get.d.ts +0 -2
- package/types/index.d.ts +0 -16
- package/types/init/index.d.ts +0 -7
- package/types/reduceMap.d.ts +0 -6
- package/types/set.d.ts +0 -4
- package/types/setMap.d.ts +0 -17
- package/types/states.d.ts +0 -9
- package/types/thunkModule/defaultThunkModuleFuncMap.d.ts +0 -5
- package/types/thunkModule/index.d.ts +0 -15
- package/types/useThunk.d.ts +0 -9
- /package/{types → dist}/action/baseAction.d.ts +0 -0
package/README.md
CHANGED
|
@@ -2,43 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://codecov.io/gh/chhsiao1981/use-thunk)
|
|
4
4
|
|
|
5
|
-
A framework easily
|
|
5
|
+
A framework for easily managing global data state with `useThunk`, with [`zustand`](https://github.com/pmndrs/zustand)-like taste.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Inspired by the concepts of [Redux Thunk](https://redux.js.org/usage/writing-logic-thunks) and [Redux Duck](https://github.com/PlatziDev/redux-duck).
|
|
8
8
|
|
|
9
|
-
[src/useThunkReducer.ts](src/useThunkReducer.ts) is
|
|
9
|
+
[src/useThunkReducer.ts](src/useThunkReducer.ts) is adapted from [nathanbuchar/react-hook-thunk-reducer](https://github.com/nathanbuchar/react-hook-thunk-reducer/blob/master/src/thunk-reducer.js).
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
For more information, please check [docs/00-introduction.md](docs/00-introduction.md).
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
2. Instead of action / reducer, we focus only on `thunk`, and have the primitive actions/reducers.
|
|
15
|
-
|
|
16
|
-
Please check [docs/00-introduction.md](docs/00-introduction.md) for more information.
|
|
17
|
-
|
|
18
|
-
Please check [demo-use-thunk](https://github.com/chhsiao1981/demo-use-thunk) for a demo to use Thunk.
|
|
19
|
-
|
|
20
|
-
### Breaking Changes
|
|
21
|
-
|
|
22
|
-
* Starting from [`12.0.0`](https://github.com/chhsiao1981/use-thunk/releases/tag/12.0.0): redefining the `getState` functions.
|
|
23
|
-
1. `getState` => `getStateOrNullByModule`, `mustGetState` => `getStateByModule`.
|
|
24
|
-
2. `mustGetStateByThunk` => `getState`.
|
|
25
|
-
* Starting from [`11.0.0`](https://github.com/chhsiao1981/use-thunk/releases/tag/11.0.0):
|
|
26
|
-
1. `setData` => `update`, `registerThunk` => `createThunk`, `dispatch` => `set`, `ClassState` => `ModuleState`, and `ModuleState.myClass` => `ModuleState.name`.
|
|
27
|
-
2. `Thunk` is `(set, get, getModuleState) => {}`, where `get(id)` directly returns object-level state.
|
|
28
|
-
* Starting from [`10.0.0`](https://github.com/chhsiao1981/use-thunk/releases/tag/10.0.0): The ClassState is shared globally, with `registerThunk` and `ThunkContext`.
|
|
29
|
-
* Starting from [`9.0.0`](https://github.com/chhsiao1981/use-thunk/releases/tag/9.0.0): npm package is renamed as [@chhsiao1981/use-thunk](https://www.npmjs.com/package/%40chhsiao1981/use-thunk)
|
|
30
|
-
* Starting from [`8.0.0`](https://github.com/chhsiao1981/use-thunk/releases/tag/8.0.0): [Totally renamed as `useThunk`](https://github.com/chhsiao1981/use-thunk/issues/105).
|
|
13
|
+
For usage examples, please refer to [demo-use-thunk](https://github.com/chhsiao1981/demo-use-thunk).
|
|
31
14
|
|
|
32
15
|
## Install
|
|
33
16
|
|
|
34
|
-
npm install
|
|
17
|
+
npm install @chhsiao1981/use-thunk
|
|
35
18
|
|
|
36
|
-
##
|
|
19
|
+
## Getting Started
|
|
37
20
|
|
|
38
|
-
Thunk module able to do increment (
|
|
21
|
+
Thunk module able to do increment (thunks/increment.ts):
|
|
39
22
|
|
|
40
23
|
```ts
|
|
41
|
-
import {
|
|
24
|
+
import { type Thunk, type State as rState, update } from '@chhsiao1981/use-thunk'
|
|
42
25
|
|
|
43
26
|
export const name = 'demo/Increment'
|
|
44
27
|
|
|
@@ -50,51 +33,53 @@ export const defaultState: State = {
|
|
|
50
33
|
count: 0
|
|
51
34
|
}
|
|
52
35
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return async (set) => {
|
|
56
|
-
|
|
36
|
+
// upsert directly with set.
|
|
37
|
+
export const increment = (myID: string, num: number = 1): Thunk<State> => {
|
|
38
|
+
return async (set, get) => {
|
|
39
|
+
let me = get(myID)
|
|
40
|
+
const {count} = me
|
|
41
|
+
|
|
42
|
+
set(myID, { count: count + num })
|
|
57
43
|
}
|
|
58
44
|
}
|
|
59
45
|
|
|
60
|
-
|
|
46
|
+
// or we can treat set as dispatching a base action.
|
|
47
|
+
export const increment2 = (myID: string): Thunk<State> => {
|
|
61
48
|
return async (set, get) => {
|
|
62
49
|
let me = get(myID)
|
|
63
|
-
if(!me) {
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
50
|
const {count} = me
|
|
67
51
|
|
|
68
|
-
set(update(
|
|
52
|
+
set(update({ count: count + 2 }))
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// or we can use set as dispatching a thunk function.
|
|
57
|
+
export const increment3 = (myID: string): Thunk<State> => {
|
|
58
|
+
return async (set) => {
|
|
59
|
+
set(increment(myID, 3))
|
|
69
60
|
}
|
|
70
61
|
}
|
|
71
62
|
```
|
|
72
63
|
|
|
73
|
-
App.tsx:
|
|
64
|
+
components/App.tsx:
|
|
74
65
|
|
|
75
66
|
```tsx
|
|
76
67
|
import { type ThunkModuleToFunc, useThunk, getState } from '@chhsiao1981/use-thunk'
|
|
77
|
-
import * as DoIncrement from './
|
|
68
|
+
import * as DoIncrement from './thunks/increment'
|
|
78
69
|
|
|
79
|
-
type
|
|
70
|
+
type doIncrement = toDoModule(typeof DoIncrement)
|
|
80
71
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
export default (props: Props) => {
|
|
85
|
-
const useIncrement = useThunk<DoIncrement.State, TDoIncrement>(DoIncrement, StateType.LOCAL)
|
|
72
|
+
export default () => {
|
|
73
|
+
const useIncrement = useThunk<DoIncrement.State, doIncrement>(DoIncrement)
|
|
86
74
|
const [increment, doIncrement, incrementID] = getState(useIncrement)
|
|
87
75
|
|
|
88
|
-
//init
|
|
89
|
-
useEffect(() => {
|
|
90
|
-
doIncrement.init()
|
|
91
|
-
}, [])
|
|
92
|
-
|
|
93
76
|
// to render
|
|
94
77
|
return (
|
|
95
78
|
<div>
|
|
96
79
|
<p>count: {increment.count}</p>
|
|
97
|
-
<button onClick={() => doIncrement.increment(incrementID)}>increase</button>
|
|
80
|
+
<button onClick={() => doIncrement.increment(incrementID)}>increase 1</button>
|
|
81
|
+
<button onClick={() => doIncrement.increment2(incrementID)}>increase 2</button>
|
|
82
|
+
<button onClick={() => doIncrement.increment3(incrementID)}>increase 3</button>
|
|
98
83
|
</div>
|
|
99
84
|
)
|
|
100
85
|
}
|
|
@@ -102,13 +87,13 @@ export default (props: Props) => {
|
|
|
102
87
|
|
|
103
88
|
main.tsx:
|
|
104
89
|
```tsx
|
|
105
|
-
import {
|
|
90
|
+
import { registerThunk, ThunkContext } from "@chhsiao1981/use-thunk";
|
|
106
91
|
import { StrictMode } from "react";
|
|
107
92
|
import { createRoot } from "react-dom/client";
|
|
108
|
-
import * as DoIncrement from './
|
|
109
|
-
import App from "./App
|
|
93
|
+
import * as DoIncrement from './thunks/increment'
|
|
94
|
+
import App from "./components/App";
|
|
110
95
|
|
|
111
|
-
|
|
96
|
+
registerThunk(DoIncrement)
|
|
112
97
|
|
|
113
98
|
createRoot(document.getElementById("root")!).render(
|
|
114
99
|
<StrictMode>
|
|
@@ -119,6 +104,7 @@ createRoot(document.getElementById("root")!).render(
|
|
|
119
104
|
)
|
|
120
105
|
```
|
|
121
106
|
|
|
107
|
+
## Development Pattern
|
|
122
108
|
### Must Included in a Thunk Module
|
|
123
109
|
|
|
124
110
|
```ts
|
|
@@ -138,29 +124,30 @@ export const defaultState: State = {}
|
|
|
138
124
|
.
|
|
139
125
|
```
|
|
140
126
|
|
|
141
|
-
### Must Included in a
|
|
127
|
+
### Must Included in a Statically-allocated (always allocated) Component
|
|
142
128
|
|
|
143
129
|
```ts
|
|
144
|
-
import { type
|
|
145
|
-
import * as DoModule from '../
|
|
130
|
+
import { type toDoModule, useThunk, getState } from '@chhsiao1981/use-thunk'
|
|
131
|
+
import * as DoModule from '../thunks/module'
|
|
146
132
|
|
|
147
|
-
type
|
|
133
|
+
type doModule = toDoModule<typeof DoModule>
|
|
148
134
|
|
|
149
135
|
const Component = () => {
|
|
150
|
-
const useModule = useThunk<DoModule.State,
|
|
136
|
+
const useModule = useThunk<DoModule.State, doModule>(DoModule)
|
|
151
137
|
const [module, doModule, moduleID] = getState(useModule)
|
|
152
138
|
|
|
153
139
|
.
|
|
154
|
-
|
|
155
|
-
|
|
140
|
+
.
|
|
141
|
+
.
|
|
156
142
|
}
|
|
157
143
|
```
|
|
158
144
|
|
|
159
|
-
### Must Included in main.tsx
|
|
145
|
+
### Must Included in `main.tsx`
|
|
160
146
|
|
|
161
147
|
```tsx
|
|
162
|
-
import {
|
|
163
|
-
|
|
148
|
+
import { registerThunk, ThunkContext } from '@chhsiao1981/use-thunk'
|
|
149
|
+
import * as DoModule from '../thunks/module'
|
|
150
|
+
registerThunk(DoModule)
|
|
164
151
|
.
|
|
165
152
|
.
|
|
166
153
|
.
|
|
@@ -174,14 +161,23 @@ createRoot(document.getElementById("root")!).render(
|
|
|
174
161
|
)
|
|
175
162
|
```
|
|
176
163
|
|
|
177
|
-
##
|
|
164
|
+
## Introduction
|
|
165
|
+
|
|
166
|
+
Global state management (GSM) is tricky when developing complex ReactJS applications. [Redux/RTK](https://redux-toolkit.js.org/) and [zustand](https://zustand-demo.pmnd.rs/) focus on "We create stores that manage the global states". However, the stores can quickly become gigantic functions in complex ReacJS applications. On the other hand, `useContext` is too primitive for complex ReactJS applications.
|
|
167
|
+
|
|
168
|
+
`use-thunk` uses a different approach: All the data management is through module-based functions. With `use-thunk`:
|
|
169
|
+
1. We treat the files as modules, and we write the module-based functions like what we typically do in other programming languages.
|
|
170
|
+
2. React components can focus on data presentation, with obtaining the data from thunk modules.
|
|
171
|
+
3. From React components' perspective, we directly call `do[Module].function(id)`.
|
|
172
|
+
4. There is only 1 `ThunkContext`, which wraps around `<App />` in `main.tsx`. We no longer need to worry that the `Context` may appear in unexpected code-base and affect the underlying `useContext`.
|
|
173
|
+
|
|
174
|
+
### Normalized State
|
|
178
175
|
|
|
179
|
-
The general concept of normalized state can be found in [Normalizing State Shape](https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape)
|
|
180
|
-
with the following features:
|
|
176
|
+
The general concept of normalized state can be found in [Normalizing State Shape](https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape). We use the following hierarchy to represent the normalized states:
|
|
181
177
|
|
|
182
|
-
1.
|
|
183
|
-
2. NodeState: the state of a node, including the id of the node and the
|
|
184
|
-
3. State: the
|
|
178
|
+
1. ModuleState: the state of a module, including the nodes and related information of the module.
|
|
179
|
+
2. NodeState: the state of a node, including the id of the node and the data (state) of the node.
|
|
180
|
+
3. State: the data of the node, represented as a state.
|
|
185
181
|
|
|
186
182
|
For example, the example [in the redux link](https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape) is represented as:
|
|
187
183
|
|
|
@@ -189,24 +185,24 @@ For example, the example [in the redux link](https://redux.js.org/recipes/struct
|
|
|
189
185
|
moduleStatePost = {
|
|
190
186
|
name: 'post',
|
|
191
187
|
nodes: {
|
|
192
|
-
[
|
|
193
|
-
id:
|
|
188
|
+
[postID1] : {
|
|
189
|
+
id: postID1,
|
|
194
190
|
state: {
|
|
195
|
-
author :
|
|
191
|
+
author : userID1,
|
|
196
192
|
body : "......",
|
|
197
|
-
comments: [
|
|
193
|
+
comments: [commentID1, commentID2]
|
|
198
194
|
},
|
|
199
195
|
},
|
|
200
|
-
[
|
|
201
|
-
id :
|
|
196
|
+
[postID2] : {
|
|
197
|
+
id : postID2,
|
|
202
198
|
state: {
|
|
203
|
-
author :
|
|
199
|
+
author : userID2,
|
|
204
200
|
body : "......",
|
|
205
|
-
comments: [
|
|
201
|
+
comments: [commentID3, commentID4, commentID5]
|
|
206
202
|
}
|
|
207
203
|
}
|
|
208
204
|
},
|
|
209
|
-
defaultID,
|
|
205
|
+
defaultID,
|
|
210
206
|
defaultState,
|
|
211
207
|
}
|
|
212
208
|
```
|
|
@@ -215,40 +211,40 @@ and:
|
|
|
215
211
|
|
|
216
212
|
```ts
|
|
217
213
|
moduleStateComment = {
|
|
218
|
-
|
|
214
|
+
name: 'comment',
|
|
219
215
|
nodes: {
|
|
220
|
-
[
|
|
221
|
-
id:
|
|
216
|
+
[commentID1] : {
|
|
217
|
+
id: commentID1,
|
|
222
218
|
state: {
|
|
223
|
-
author :
|
|
219
|
+
author : userID2,
|
|
224
220
|
comment : ".....",
|
|
225
221
|
}
|
|
226
222
|
},
|
|
227
|
-
[
|
|
228
|
-
id :
|
|
223
|
+
[commentID2] : {
|
|
224
|
+
id : commentID2,
|
|
229
225
|
state: {
|
|
230
|
-
author :
|
|
226
|
+
author : userID3,
|
|
231
227
|
comment : ".....",
|
|
232
228
|
}
|
|
233
229
|
},
|
|
234
|
-
[
|
|
235
|
-
id :
|
|
230
|
+
[commentID3] : {
|
|
231
|
+
id : commentID3,
|
|
236
232
|
state: {
|
|
237
|
-
author :
|
|
233
|
+
author : userID3,
|
|
238
234
|
comment : ".....",
|
|
239
235
|
}
|
|
240
236
|
},
|
|
241
|
-
[
|
|
242
|
-
id :
|
|
237
|
+
[commentID4] : {
|
|
238
|
+
id : commentID4,
|
|
243
239
|
state: {
|
|
244
|
-
author :
|
|
240
|
+
author : userID1,
|
|
245
241
|
comment : ".....",
|
|
246
242
|
}
|
|
247
243
|
},
|
|
248
|
-
[
|
|
249
|
-
id :
|
|
244
|
+
[commentID5] : {
|
|
245
|
+
id : commentID5,
|
|
250
246
|
state: {
|
|
251
|
-
author :
|
|
247
|
+
author : userID3,
|
|
252
248
|
comment : ".....",
|
|
253
249
|
}
|
|
254
250
|
}
|
|
@@ -263,22 +259,22 @@ and:
|
|
|
263
259
|
moduleStateUser = {
|
|
264
260
|
name: 'user',
|
|
265
261
|
nodes: {
|
|
266
|
-
[
|
|
267
|
-
id:
|
|
262
|
+
[userID1] : {
|
|
263
|
+
id: userID1,
|
|
268
264
|
state: {
|
|
269
265
|
username : "user1",
|
|
270
266
|
name : "User 1",
|
|
271
267
|
}
|
|
272
268
|
},
|
|
273
|
-
[
|
|
274
|
-
id:
|
|
269
|
+
[userID2] : {
|
|
270
|
+
id: userID2,
|
|
275
271
|
state: {
|
|
276
272
|
username : "user2",
|
|
277
273
|
name : "User 2",
|
|
278
274
|
}
|
|
279
275
|
},
|
|
280
|
-
[
|
|
281
|
-
id:
|
|
276
|
+
[userID3] : {
|
|
277
|
+
id: userID3,
|
|
282
278
|
state: {
|
|
283
279
|
username : "user3",
|
|
284
280
|
name : "User 3",
|
|
@@ -292,52 +288,145 @@ moduleStateUser = {
|
|
|
292
288
|
|
|
293
289
|
## [APIs](https://github.com/chhsiao1981/use-thunk/blob/main/src/index.d.ts)
|
|
294
290
|
|
|
295
|
-
|
|
291
|
+
#### Types
|
|
292
|
+
|
|
293
|
+
##### `ThunkModule<S extends State>`
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
export type ThunkModule<S extends State> = {
|
|
297
|
+
name: string
|
|
298
|
+
defaultState: S
|
|
299
|
+
|
|
300
|
+
// The rest of the variables are doModule.
|
|
301
|
+
// Specifying index-signatures to include all the variables.
|
|
302
|
+
[action: string]: ThunkFunc<S> | string | S
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
A ThunkModule represents a self-contained domain state slice implemented within a single file. It encapsulates the module's identity, its initial data structure, and the business logic workflows (thunk functions) that act upon it.
|
|
307
|
+
|
|
308
|
+
##### `ThunkFunc<S extends State>`
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
export type ThunkFunc<S extends State> = (...params: any[]) => Thunk<S>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
The thunk functions in a thunk module.
|
|
296
315
|
|
|
297
|
-
##### `
|
|
316
|
+
##### `Thunk`
|
|
298
317
|
|
|
299
|
-
|
|
318
|
+
`Thunk` is defined as:
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
export type Thunk<S extends State> = async (
|
|
322
|
+
set: set<S>,
|
|
323
|
+
get: (id?: string) => S,
|
|
324
|
+
getOrNull: (id?: string) => S | null | undefined,
|
|
325
|
+
dispatch: dispatch<S>,
|
|
326
|
+
getModuleState: () => ModuleState<S>,
|
|
327
|
+
) => void
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
`Thunk`s can be async functions if needed (ex: `fetch` data).
|
|
331
|
+
|
|
332
|
+
We generally use only `set` and `get`.
|
|
333
|
+
|
|
334
|
+
* `set`: can be used in the following setting:
|
|
335
|
+
* `set(ThunkFunc())`: calling a thunk function.
|
|
336
|
+
* `set(id, data: Partial<S>)`: upsert state of `id` (syntax sugar of `set(upsert(id, data))`).
|
|
337
|
+
* `get`: (Guaranteed) get the state of `id` (or `defaultID` if `id` is not present).
|
|
338
|
+
* `getOrNull`: get the state of `id`. Get the state of `defaultID` if `id` is not present. Return `null` if `id` or state is not available.
|
|
339
|
+
* `dispatch`: `dispatch(ThunkFunc())` (calling a thunk function).
|
|
340
|
+
* `getModuleState`: get the whole module state.
|
|
341
|
+
|
|
342
|
+
##### `doModule<S extends State>`
|
|
343
|
+
|
|
344
|
+
```ts
|
|
345
|
+
export interface doModule<S extends State> {
|
|
346
|
+
[action: string]: ThunkFunc<S>
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
##### `toDoModule`
|
|
351
|
+
|
|
352
|
+
```ts
|
|
353
|
+
export type toDoModule<T extends ThunkModule<any>> = Omit<T, 'name' | 'defaultState'>
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Converting `ThunkModule` to `doModule` by omitting `name` and `defaultState`.
|
|
357
|
+
|
|
358
|
+
#### RegisterThunk / ThunkContext / useThunk
|
|
359
|
+
|
|
360
|
+
##### `registerThunk(module: ThunkModule)`
|
|
361
|
+
|
|
362
|
+
Register a thunk module.
|
|
300
363
|
|
|
301
364
|
##### `<ThunkContext>{children}</ThunkContext>`
|
|
302
365
|
|
|
303
|
-
Rendering
|
|
366
|
+
Rendering thunk context.
|
|
304
367
|
|
|
305
368
|
##### `useThunk(theDo: ThunkModule): UseThunk`
|
|
306
369
|
|
|
307
|
-
Similar to `React.useReducer`, but we use `useThunk
|
|
370
|
+
Similar to `React.useReducer`, but we use `useThunk`. In addition, we bind the thunk functions with `dispatch`, so we can directly use `do[Module].[function]()` (similar concept as `zustand`).
|
|
308
371
|
|
|
309
372
|
return: `UseThunk`
|
|
310
373
|
|
|
311
|
-
|
|
374
|
+
#### State
|
|
312
375
|
|
|
313
|
-
##### `
|
|
376
|
+
##### `getState(theUseThunk: UseThunk, id?: string): [state, doModule, theID]`
|
|
314
377
|
|
|
315
|
-
|
|
378
|
+
(Guaranteed) Get the state of `id` (or `defaultID` if `id` is not present) by `UseThunk`. If `defaultID` is not available, generate new ID as `defaultID`. If state is not available, clone `defaultState` as the state.
|
|
316
379
|
|
|
317
|
-
|
|
380
|
+
return: `[state, doModule, theID]`
|
|
318
381
|
|
|
319
|
-
|
|
382
|
+
#### Misc
|
|
320
383
|
|
|
321
|
-
##### `
|
|
384
|
+
##### `genID(): string`
|
|
322
385
|
|
|
323
|
-
|
|
386
|
+
Generate `id` for the state.
|
|
324
387
|
|
|
325
|
-
|
|
388
|
+
### Advanced Usage
|
|
326
389
|
|
|
327
|
-
|
|
390
|
+
#### types
|
|
328
391
|
|
|
329
|
-
|
|
392
|
+
##### `UseThunk`
|
|
330
393
|
|
|
331
|
-
|
|
394
|
+
```ts
|
|
395
|
+
export type UseThunk<S extends State, R extends doModule<S>> = [Readonly<ModuleState<S>>, setMap<S, R>]
|
|
396
|
+
```
|
|
332
397
|
|
|
333
|
-
|
|
398
|
+
##### `setMap`
|
|
334
399
|
|
|
335
|
-
|
|
400
|
+
```ts
|
|
401
|
+
export type setMap<S extends State, T extends doModule<S>> = {
|
|
402
|
+
[action in keyof T]: VoidReturnType<T[action]>
|
|
403
|
+
} & Omit<DefaultSetMap, keyof T>
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
#### Primitive Thunk Functions.
|
|
407
|
+
|
|
408
|
+
##### `init({id, parentID, doParent, state})`
|
|
409
|
+
|
|
410
|
+
Initialize the state.
|
|
411
|
+
|
|
412
|
+
##### `update(id, data)`
|
|
413
|
+
|
|
414
|
+
Update the data to `id`.
|
|
415
|
+
|
|
416
|
+
##### `upsert(id, data)`
|
|
417
|
+
|
|
418
|
+
Initialize the state with `defaultState` if it does not exist, and update the data to `id`.
|
|
419
|
+
|
|
420
|
+
##### `remove(id)`
|
|
421
|
+
|
|
422
|
+
Remove the state.
|
|
423
|
+
|
|
424
|
+
#### State
|
|
336
425
|
|
|
337
|
-
##### `getStateOrNullByModule(moduleState: ModuleState,
|
|
426
|
+
##### `getStateOrNullByModule(moduleState: ModuleState, id?: string): state | null`
|
|
338
427
|
|
|
339
|
-
Get the state of `
|
|
428
|
+
Get the state of `id`. Get the state of `defaultID` if `id` is not present. Return `null` if not available.
|
|
340
429
|
|
|
341
|
-
##### `getStateByModule(moduleState: ModuleState,
|
|
430
|
+
##### `getStateByModule(moduleState: ModuleState, id?: string): state`
|
|
342
431
|
|
|
343
|
-
Get the state of `
|
|
432
|
+
(Guaranteed) Get the state of `id` (or `defaultID` if `id` is not present) by module state. If `defaultID` is not available, generate new ID as `defaultID`. If state is not available, clone `defaultState` as the state.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { ModuleState, State } from '../
|
|
1
|
+
import type { ModuleState, State } from '../states';
|
|
2
2
|
import type { ActionOrThunk } from './ActionOrThunk';
|
|
3
3
|
import type BaseAction from './baseAction';
|
|
4
4
|
import type { Thunk } from './thunk';
|
|
5
5
|
export type { Thunk, ActionOrThunk, BaseAction };
|
|
6
6
|
export type ActionFunc<S extends State> = (...params: any[]) => ActionOrThunk<S>;
|
|
7
7
|
export type ThunkFunc<S extends State> = (...params: any[]) => Thunk<S>;
|
|
8
|
-
export type
|
|
8
|
+
export type getModuleState<S extends State> = () => ModuleState<S>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { dispatch } from '../dispatch';
|
|
2
|
+
import type { get, getOrNull } from '../get';
|
|
3
|
+
import type { set } from '../set';
|
|
4
|
+
import type { ModuleState, State } from '../states';
|
|
5
|
+
export type Thunk<S extends State> = (set: set<S>, get: get<S>, getOrNull: getOrNull<S>, dispatch: dispatch<S>, getModuleState: () => ModuleState<S>) => void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { INIT, type InitParams, init, reduceInit } from './init';
|
|
2
|
+
export { INIT, type InitParams, init, reduceInit };
|
|
3
|
+
import { reduceUpdate, UPDATE, update } from './update';
|
|
4
|
+
export { reduceUpdate, UPDATE, update };
|
|
5
|
+
import { REMOVE, reduceRemove, remove } from './remove';
|
|
6
|
+
export { REMOVE, reduceRemove, remove };
|
|
7
|
+
import { reduceUpsert, UPSERT, upsert } from './upsert';
|
|
8
|
+
export { UPSERT, upsert, reduceUpsert };
|
|
9
|
+
import { reduceSetDefaultID, SET_DEFAULT_ID, setDefaultID } from './setDefaultID';
|
|
10
|
+
export { SET_DEFAULT_ID, setDefaultID, reduceSetDefaultID };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Thunk } from '../../action';
|
|
2
|
+
import type { State } from '../../states';
|
|
3
|
+
import { INIT, reduceInit } from './initCore';
|
|
4
|
+
export { INIT, reduceInit };
|
|
5
|
+
export interface InitParams<S extends State> {
|
|
6
|
+
myID?: string;
|
|
7
|
+
state: S;
|
|
8
|
+
}
|
|
9
|
+
export declare const init: <S extends State>(params: InitParams<S>) => Thunk<S>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type BaseAction from '
|
|
2
|
-
import type { ModuleState, State } from '
|
|
1
|
+
import type { BaseAction } from '../../action';
|
|
2
|
+
import type { ModuleState, State } from '../../states';
|
|
3
3
|
export interface InitAction<S extends State> extends BaseAction {
|
|
4
4
|
state: S;
|
|
5
5
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type BaseAction from '
|
|
2
|
-
import type { ModuleState, State } from '
|
|
1
|
+
import type { BaseAction } from '../action';
|
|
2
|
+
import type { ModuleState, State } from '../states';
|
|
3
3
|
export declare const REMOVE = "@chhsiao1981/use-thunk/REMOVE";
|
|
4
4
|
export declare const remove: (myID: string) => BaseAction;
|
|
5
5
|
export declare const reduceRemove: <S extends State>(moduleState: ModuleState<S>, action: BaseAction) => ModuleState<S>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type BaseAction from '
|
|
2
|
-
import type { ModuleState, State } from '
|
|
1
|
+
import type { BaseAction } from '../action';
|
|
2
|
+
import type { ModuleState, State } from '../states';
|
|
3
3
|
export declare const SET_DEFAULT_ID = "@chhsiao1981/use-thunk/SET_DEFAULT_ID";
|
|
4
4
|
export declare const setDefaultID: (myID: string) => BaseAction;
|
|
5
5
|
export declare const reduceSetDefaultID: <S extends State>(moduleState: ModuleState<S>, action: BaseAction) => ModuleState<S>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type BaseAction from '
|
|
2
|
-
import type { ModuleState, State } from '
|
|
1
|
+
import type { BaseAction } from '../action';
|
|
2
|
+
import type { ModuleState, State } from '../states';
|
|
3
3
|
export declare const UPDATE = "@chhsiao1981/use-thunk/UPDATE";
|
|
4
4
|
export declare const update: <S extends State>(myID: string, data: Partial<S>) => BaseAction;
|
|
5
5
|
export declare const reduceUpdate: <S extends State>(moduleState: ModuleState<S>, action: BaseAction) => ModuleState<S>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BaseAction } from '../action';
|
|
2
|
+
import type { ModuleState, State } from '../states';
|
|
3
|
+
export declare const UPSERT = "@chhsiao1981/use-thunk/UPSERT";
|
|
4
|
+
export declare const upsert: <S extends State>(myID: string, data: Partial<S>) => BaseAction;
|
|
5
|
+
export declare const reduceUpsert: <S extends State>(moduleState: ModuleState<S>, action: BaseAction) => ModuleState<S>;
|
package/dist/dispatch.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Dispatch
|
|
1
|
+
import type { Dispatch } from 'react';
|
|
2
2
|
import type { ActionOrThunk } from './action';
|
|
3
|
-
import type { State } from './
|
|
4
|
-
export type
|
|
3
|
+
import type { State } from './states';
|
|
4
|
+
export type dispatch<S extends State> = Dispatch<ActionOrThunk<S>>;
|
package/dist/get.d.ts
ADDED
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import type { ClassState, NodeState, NodeStateMap, State } from './stateTypes';
|
|
11
|
-
import ThunkContext from './ThunkContext';
|
|
12
|
-
import type { ThunkModule, ThunkModuleToFunc } from './thunk';
|
|
13
|
-
import { setData, update } from './update';
|
|
1
|
+
import type { getModuleState, Thunk, ThunkFunc } from './action';
|
|
2
|
+
import { type InitParams, init, remove, setDefaultID, update, upsert } from './defaultThunks';
|
|
3
|
+
import type { dispatch } from './dispatch';
|
|
4
|
+
import type { get, getOrNull } from './get';
|
|
5
|
+
import registerThunk from './registerThunk';
|
|
6
|
+
import type { set, setMap } from './set';
|
|
7
|
+
import { getDefaultID, getNodeOrNull, getState, getStateByModule, getStateOrNullByModule, type ModuleState, type State } from './states';
|
|
8
|
+
import { ThunkContext } from './thunkContext';
|
|
9
|
+
import type { doModule, ThunkModule, toDoModule } from './thunkModule';
|
|
14
10
|
import useThunk, { type UseThunk } from './useThunk';
|
|
15
|
-
|
|
11
|
+
import { genID } from './utils';
|
|
12
|
+
export { type Thunk, type set, type get, type getOrNull, type dispatch, type getModuleState, registerThunk, useThunk, type UseThunk, ThunkContext, type State, getState, type ModuleState, type ThunkModule, type toDoModule, type doModule, type ThunkFunc, init, type InitParams, update, upsert, remove, genID, type setMap, setDefaultID, getNodeOrNull, getDefaultID, getStateOrNullByModule, getStateByModule, };
|