Skip to content

Commit d50f31e

Browse files
authored
Merge pull request #96 from byte-fe/develop
fix(types): correct the type of actions returned by next model
2 parents 1913871 + 7f481ad commit d50f31e

File tree

8 files changed

+95
-11
lines changed

8 files changed

+95
-11
lines changed

__test__/index.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ type CounterActionParams = {
1515
increment: number
1616
}
1717

18+
type NextCounterActionParams = {
19+
increment: number
20+
add: number
21+
}
22+
1823
type ExtraActionParams = {
1924
add: number
2025
}

__test__/index.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/// <reference path="./index.d.ts" />
22
/// <reference path="../src/index.d.ts" />
3+
import { Model } from '../src'
34
import { timeout } from '../src/helper'
5+
import { actionMiddlewares } from '../src/middlewares'
46

57
export const ActionsTester: ModelType<ActionTesterState, ActionTesterParams> = {
68
state: {
@@ -124,3 +126,28 @@ export const ErrorCounter: ModelType<CounterState, CounterActionParams> = {
124126
}
125127
}
126128
}
129+
130+
const delayMiddleware: Middleware = async (context, restMiddlewares) => {
131+
await timeout(2000, {})
132+
context.next(restMiddlewares)
133+
}
134+
135+
const nextCounterModel: NextModelType<CounterState, NextCounterActionParams> = {
136+
actions: {
137+
add: num => {
138+
return state => {
139+
state.count += num
140+
}
141+
},
142+
increment: async (num, { actions }) => {
143+
actions.add(num)
144+
await timeout(300, {})
145+
}
146+
},
147+
middlewares: [delayMiddleware, ...actionMiddlewares],
148+
state: {
149+
count: 0
150+
}
151+
}
152+
153+
export const NextCounterModel = Model(nextCounterModel)

__test__/middlewares/model.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/// <reference path="../index.d.ts" />
2+
import 'react-testing-library/cleanup-after-each'
3+
process.env.NODE_ENV = 'production'
4+
import { testHook } from 'react-hooks-testing-library'
5+
import { NextCounterModel } from '..'
6+
import { Model } from '../../src'
7+
8+
describe('NextModel', () => {
9+
test("allows you to customize model's middleware", async () => {
10+
let actions: any
11+
let state: any
12+
const { useStore, getActions } = Model({ NextCounterModel })
13+
const beginTime = Date.now()
14+
testHook(() => {
15+
;[state, actions] = useStore('NextCounterModel')
16+
})
17+
await actions.increment(2)
18+
await getActions('NextCounterModel').increment(1)
19+
expect(Date.now() - beginTime > 300)
20+
expect(state.count).toBe(3)
21+
})
22+
})

package.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-model",
3-
"version": "2.7.0",
3+
"version": "2.7.1-alpha.2",
44
"description": "The State management library for React",
55
"main": "./dist/react-model.js",
66
"umd:main": "./dist/react-model.umd.js",
@@ -13,7 +13,12 @@
1313
"test": "jest --silent",
1414
"test:coverage": "jest --collect-coverage --silent"
1515
},
16-
"keywords": ["react", "model", "state-management", "react-hooks"],
16+
"keywords": [
17+
"react",
18+
"model",
19+
"state-management",
20+
"react-hooks"
21+
],
1722
"author": "ArrayZoneYour <hustliyidong@gmail.com>",
1823
"license": "MIT",
1924
"dependencies": {
@@ -44,7 +49,7 @@
4449
"remark-preset-lint-recommended": "^3.0.2",
4550
"ts-jest": "^24.0.0",
4651
"tslint": "^5.14.0",
47-
"typescript": "^3.3.4000"
52+
"typescript": "^3.4.5"
4853
},
4954
"husky": {
5055
"hooks": {

src/global.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const State = {}
22
const Actions = {}
33
const AsyncState = {}
4+
const Middlewares = {}
45
// Communicate between Provider-Consumer and Hooks
56
const Setter: Setter = {
67
// classSetter stores the setState from Provider
@@ -21,6 +22,7 @@ let uid = Math.random() // The unique id of hooks
2122
export default {
2223
Actions,
2324
AsyncState,
25+
Middlewares,
2426
Setter,
2527
State,
2628
devTools,

src/index.d.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ interface Global {
2424
AsyncState: {
2525
[modelName: string]: undefined | ((context?: any) => Promise<Partial<any>>)
2626
}
27+
Middlewares: {
28+
[modelName: string]: Middleware[]
29+
}
2730
subscriptions: Subscriptions
2831
Setter: Setter
2932
devTools: any
@@ -48,12 +51,12 @@ type Action<S = {}, P = any, ActionKeys = {}> = (
4851
| Promise<void>
4952

5053
// v3.0 Action
51-
type NextAction<S = {}, P = any, ActionKeys = {}> = (
54+
type NextAction<S = {}, P = any, ActionKeys = {}, ExtContext = {}> = (
5255
params: P,
5356
context: {
5457
state: S
5558
actions: getConsumerNextActionsType<NextActions<S, ActionKeys>>
56-
}
59+
} & ExtContext
5760
) =>
5861
| Partial<S>
5962
| Promise<Partial<S>>
@@ -103,6 +106,7 @@ interface InnerContext<S = {}> extends BaseContext<S> {
103106

104107
type Context<S = {}> = (InnerContext<S>) & {
105108
next: Function
109+
modelMiddlewares?: Middleware[]
106110
}
107111

108112
type Middleware<S = {}> = (C: Context<S>, M: Middleware<S>[]) => void
@@ -150,7 +154,9 @@ interface APIs<M extends Models> {
150154
modelName: K
151155
) => M[K] extends ModelType
152156
? Readonly<getConsumerActionsType<Get<M[K], 'actions'>>>
153-
: undefined
157+
: M[K] extends API
158+
? M[K]['actions']
159+
: unknown
154160
getInitialState: <T extends any>(
155161
context?: T | undefined
156162
) => Promise<{
@@ -166,7 +172,11 @@ interface APIs<M extends Models> {
166172
actionName: keyof Get<M[K], 'actions'> | Array<keyof Get<M[K], 'actions'>>
167173
) => void
168174
actions: {
169-
[K in keyof M]: Readonly<getConsumerActionsType<Get<M[K], 'actions'>>>
175+
[K in keyof M]: M[K] extends ModelType
176+
? Readonly<getConsumerActionsType<Get<M[K], 'actions'>>>
177+
: M[K] extends API
178+
? M[K]['actions']
179+
: unknown
170180
}
171181
}
172182

@@ -179,14 +189,16 @@ type ModelType<InitStateType = any, ActionKeys = any> = {
179189
}
180190

181191
// v3.0
182-
type NextModelType<InitStateType = any, ActionKeys = any> = {
192+
type NextModelType<InitStateType = any, ActionKeys = any, ExtContext = {}> = {
183193
actions: {
184194
[P in keyof ActionKeys]: NextAction<
185195
InitStateType,
186196
ActionKeys[P],
187-
ActionKeys
197+
ActionKeys,
198+
ExtContext
188199
>
189200
}
201+
middlewares?: Middleware[]
190202
state: InitStateType
191203
asyncState?: (context?: any) => Promise<Partial<InitStateType>>
192204
}

src/index.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ function Model<M extends Models, MT extends NextModelType>(
3131
Global.uid += 1
3232
const hash = '__' + Global.uid
3333
Global.State[hash] = models.state
34+
if (models.middlewares) {
35+
Global.Middlewares[hash] = models.middlewares
36+
}
3437
const nextActions: Actions = Object.entries(models.actions).reduce(
3538
(o: { [name: string]: Action }, [name, action]) => {
3639
o[name] = async (state, actions, params) => {
@@ -63,6 +66,9 @@ function Model<M extends Models, MT extends NextModelType>(
6366
}
6467
Object.entries(models).forEach(([name, model]) => {
6568
if (!isAPI(model)) {
69+
console.warn(
70+
'we recommend you to use NextModel now, document link: https://github.com/byte-fe/react-model#model'
71+
)
6672
if (!Global.State[name]) {
6773
Global.State[name] = model.state
6874
}
@@ -74,6 +80,7 @@ function Model<M extends Models, MT extends NextModelType>(
7480
}
7581
Global.Actions[name] = Global.Actions[model.__id]
7682
Global.AsyncState[name] = Global.AsyncState[model.__id]
83+
Global.Middlewares[name] = Global.Middlewares[model.__id]
7784
}
7885
})
7986

@@ -156,7 +163,11 @@ const getActions = (
156163
...baseContext,
157164
Global
158165
}
159-
await applyMiddlewares(actionMiddlewares, context)
166+
if (Global.Middlewares[modelName]) {
167+
await applyMiddlewares(Global.Middlewares[modelName], context)
168+
} else {
169+
await applyMiddlewares(actionMiddlewares, context)
170+
}
160171
})
161172
)
162173
return updaters

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
"sourceMap": false,
1616
"strict": true
1717
},
18-
"include": ["src/**/*"],
18+
"include": ["./src/*"],
1919
"exclude": ["node_modules"]
2020
}

0 commit comments

Comments
 (0)