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 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,4 @@
1
+ import createApp from './redux/createApp';
2
+ export {
3
+ createApp
4
+ }
@@ -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
+ }