ez-saga 0.0.1
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/LICENSE +21 -0
- package/README.md +1 -0
- package/package.json +41 -0
- package/src/index.js +4 -0
- package/src/redux/createApp.js +116 -0
- package/src/redux/createPromiseMiddleware.js +31 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 davinyue
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
The dy-saga project is a project that imitates dva-js
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ez-saga",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "The ez-saga project is a project that imitates dva-js",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/davinyue/ez-saga"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/davinyue/ez-saga",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"ez-saga",
|
|
14
|
+
"dva",
|
|
15
|
+
"redux",
|
|
16
|
+
"redux-saga",
|
|
17
|
+
"framework",
|
|
18
|
+
"frontend"
|
|
19
|
+
],
|
|
20
|
+
"authors": [
|
|
21
|
+
"davinyue <davinyue@gmail.com> (https://github.com/davinyue)"
|
|
22
|
+
],
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"redux": "^4.1.2",
|
|
26
|
+
"redux-saga": "^1.2.1"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"redux": "4.x"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"mm": "^2.5.0",
|
|
33
|
+
"redux": "^4.1.2"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"lib",
|
|
38
|
+
"src",
|
|
39
|
+
"index.js"
|
|
40
|
+
]
|
|
41
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { legacy_createStore as createStore, applyMiddleware, compose } from 'redux';
|
|
2
|
+
import { createSlice, combineReducers } from '@reduxjs/toolkit';
|
|
3
|
+
import createSagaMiddleware from 'redux-saga';
|
|
4
|
+
import { call, put, select, takeEvery, putResolve } from 'redux-saga/effects';
|
|
5
|
+
import win from 'global/window';
|
|
6
|
+
import createPromiseMiddleware from './createPromiseMiddleware';
|
|
7
|
+
|
|
8
|
+
function saveState(state, action) {
|
|
9
|
+
let newStat = {
|
|
10
|
+
...state,
|
|
11
|
+
...action.payload
|
|
12
|
+
};
|
|
13
|
+
return newStat;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 获取注册model函数
|
|
18
|
+
* @param store redux store
|
|
19
|
+
* @param registedModel 已注册model, 对象, 属性为model名称, value为model
|
|
20
|
+
* @param allReducers 所有的reducers
|
|
21
|
+
* @param sagaMiddleware saga中间件
|
|
22
|
+
* @returns 返回function regist(model)
|
|
23
|
+
*/
|
|
24
|
+
function getRegistModelFunc(store, registedModel, allReducers, sagaMiddleware) {
|
|
25
|
+
/** model函数注册函数
|
|
26
|
+
* @param model 模块, 其格式为
|
|
27
|
+
* {
|
|
28
|
+
* name: 'name',
|
|
29
|
+
* state: {},
|
|
30
|
+
* reducers: {},
|
|
31
|
+
* effects: {}
|
|
32
|
+
* }
|
|
33
|
+
*/
|
|
34
|
+
return function regist(model) {
|
|
35
|
+
if (registedModel[model.name]) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (!model.reducers) {
|
|
39
|
+
model.reducers = {};
|
|
40
|
+
}
|
|
41
|
+
if (!model.effect) {
|
|
42
|
+
model.effect = {};
|
|
43
|
+
}
|
|
44
|
+
const modelSlice = createSlice(model);
|
|
45
|
+
const reducer = modelSlice.reducer;
|
|
46
|
+
allReducers[model.name] = reducer;
|
|
47
|
+
registedModel[model.name] = model;
|
|
48
|
+
//获得一个新的reducer, 将所有的reducer整合成一个
|
|
49
|
+
let newReducer = combineReducers(allReducers);
|
|
50
|
+
store.replaceReducer(newReducer);
|
|
51
|
+
//注册effects
|
|
52
|
+
for (let effect in model.effects) {
|
|
53
|
+
let type = `${model.name}/${effect}`;
|
|
54
|
+
let execFun = model.effects[effect];
|
|
55
|
+
|
|
56
|
+
function* loading(opFun, action) {
|
|
57
|
+
// 开始异步任务设置loading状态
|
|
58
|
+
yield putResolve({ type: `${model.name}/saveState`, payload: { loading: true } });
|
|
59
|
+
let ret = yield call(execFun, action, opFun);
|
|
60
|
+
// 结束异步任务关闭loading状态
|
|
61
|
+
yield putResolve({ type: `${model.name}/saveState`, payload: { loading: false } });
|
|
62
|
+
if (action._dy_resolve) {
|
|
63
|
+
action._dy_resolve(ret);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function* runEffect() {
|
|
68
|
+
//yield takeLatest(type, loading, { call, put, putResolve, select });
|
|
69
|
+
yield takeEvery(type, loading, { call, put, putResolve, select });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
sagaMiddleware.run(runEffect);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** 创建store */
|
|
78
|
+
export default function create() {
|
|
79
|
+
//已经注册的reducer, key是名字, value是reducer
|
|
80
|
+
const allReducers = {};
|
|
81
|
+
//已注册model
|
|
82
|
+
const registedModel = {};
|
|
83
|
+
|
|
84
|
+
const sagaMiddleware = createSagaMiddleware();
|
|
85
|
+
|
|
86
|
+
const promiseMiddleware = createPromiseMiddleware(registedModel);
|
|
87
|
+
|
|
88
|
+
const middlewares = [
|
|
89
|
+
promiseMiddleware,
|
|
90
|
+
sagaMiddleware
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
// eslint-disable-next-line no-undef
|
|
94
|
+
const composeEnhancers = process.env.NODE_ENV !== 'production'
|
|
95
|
+
&& win.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
|
|
96
|
+
win.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ trace: true, maxAge: 30 }) : compose;
|
|
97
|
+
|
|
98
|
+
const enhancers = [applyMiddleware(...middlewares)];
|
|
99
|
+
|
|
100
|
+
//redux store
|
|
101
|
+
const store = createStore(
|
|
102
|
+
saveState,
|
|
103
|
+
{},
|
|
104
|
+
composeEnhancers(...enhancers)
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const regist = getRegistModelFunc(store, registedModel, allReducers, sagaMiddleware);
|
|
108
|
+
return {
|
|
109
|
+
/** redux store */
|
|
110
|
+
store: store,
|
|
111
|
+
/** saga中间件 */
|
|
112
|
+
sagaMiddleware: sagaMiddleware,
|
|
113
|
+
/** model注册函数 */
|
|
114
|
+
regist: regist
|
|
115
|
+
};
|
|
116
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param registedModel 已注册model
|
|
3
|
+
*/
|
|
4
|
+
export default function createPromiseMiddleware(registedModel) {
|
|
5
|
+
return () => next => action => {
|
|
6
|
+
const { type } = action;
|
|
7
|
+
if (isEffect(type)) {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
next({
|
|
10
|
+
_dy_resolve: resolve,
|
|
11
|
+
_dy_reject: reject,
|
|
12
|
+
...action,
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
} else {
|
|
16
|
+
return next(action);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function isEffect(type) {
|
|
21
|
+
if (!type || typeof type !== 'string') return false;
|
|
22
|
+
const [modelName, effect] = type.split('/');
|
|
23
|
+
const model = registedModel[modelName];
|
|
24
|
+
if (model) {
|
|
25
|
+
if (model.effects && model.effects[effect]) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|