Forráskód Böngészése

refactored CRUD generator.

Tomislav Cvetic 8 éve
szülő
commit
d4ce2f7698
4 módosított fájl, 131 hozzáadás és 97 törlés
  1. 37 0
      src/crud-api/http.js
  2. 46 0
      src/crud-api/localStorage.js
  3. 41 10
      src/redux-gen/basic.js
  4. 7 87
      src/redux-gen/crud.js

+ 37 - 0
src/crud-api/http.js

@@ -0,0 +1,37 @@
+/** The basic CRUD API supports the following functionality:
+  * /api[/module][/id|/offset[/limit]]
+  *
+  * Other functions
+  */
+
+import request from 'request-promise'
+export function crudHttpApi (action, options) {
+  const { uri } = options
+  // determine the operation
+  const [ name, actionType ] = action.type.split('/')
+  const requestOptions = {
+    uri: `${uri}/${name}`,
+    method: null,
+    body: null
+  }
+  switch (actionType) {
+    case 'READ_REQUEST':
+      options.uri = `${uri}/${action.id}`
+      options.method = 'GET'
+      break
+    case 'CREATE_REQUEST':
+      options.method = 'POST'
+      options.body = action.data
+      break
+    case 'UPDATE_REQUEST':
+      options.uri = `${uri}/${action.id}`
+      options.method = 'PUT'
+      break
+    case 'DELETE_REQUEST':
+      options.uri = `${uri}/${action.id}`
+      options.method = 'DELETE'
+      break
+  }
+  // Request from the request-promise library already returns a promise.
+  return request(requestOptions)
+}

+ 46 - 0
src/crud-api/localStorage.js

@@ -0,0 +1,46 @@
+
+export function crudLocalstorageApi (action, options) {
+  // determine the operation
+  const [ name, actionType ] = action.type.split('/')
+  switch (actionType) {
+    case 'READ_REQUEST':
+      return new Promise((resolve, reject) => {
+        const items = localStorage.getItem(name) || []
+        resolve(items[action.id])
+      })
+    case 'CREATE_REQUEST':
+      return new Promise((resolve, reject) => {
+        try {
+          const items = localStorage.getItem(name) || {}
+          items[action.id] = action.data
+          console.log(items)
+          localStorage.setItem(name, items)
+          resolve(null)
+        } catch (error) {
+          reject(error)
+        }
+      })
+    case 'UPDATE_REQUEST':
+      return new Promise((resolve, reject) => {
+        try {
+          const items = localStorage.getItem(name) || {}
+          items[action.id] = action.data
+          localStorage.setItem(name, items)
+          resolve(null)
+        } catch (error) {
+          reject(error)
+        }
+      })
+    case 'DELETE_REQUEST':
+      return new Promise((resolve, reject) => {
+        try {
+          const items = localStorage.getItem(name) || {}
+          delete items[action.id]
+          localStorage.setItem(name, items)
+          resolve(null)
+        } catch (error) {
+          reject(error)
+        }
+      })
+  }
+}

+ 41 - 10
src/redux-gen/basic.js

@@ -1,25 +1,58 @@
-/** genStuff
-  * you input the name of a module (e.g. project) and the API (e.g. http://localhost/db/project)
-  * it outputs a state, action types, action creators, reducer, workers and watchers
-  * to handle a restful API.
+/** @module redux-gen/basic */
+
+/**
+  * Generates everything which is usually required to integrate a simple module into
+  * a React-Redux environment and puts it in an object for easier integration.
+  *
+  * Usage:
+  * Suppose you want to integrate your module 'user' in the React-Redux universe.
+  * call `const user = reduxGen('user')`
+  * user now contains
+  *   - the action types `CREATE`, `UPDATE` and `DELETE`
+  *   - the actions `createUser`, `updateUser` and `deleteUser`
+  *   - the state subpart `{ user: [] }`
+  *   - the reducer which handles the actions in a default manner.
+  *
+  * Integrate the user as follows into your project:
+  *   - Extend your default state
+  *     `const defaultState = { <some definitions>, ...user.state }`
+  *   - Create the root reducer
+  *     `const rootReducer = combineReducers({ <some definitions>, ...user.reducer })`
+  *   - Create the Redux store
+  *     `const store = createStore(rootReducer, defaultState, <enhancers>)`
+  *   - Bind the actions to the dispatcher
+  *   - Connect your app to the store
+  *
+  * @param {string} name - Name of the module
   */
 export default function reduxGen (name) {
+  // Start with empty objects
   const actionTypes = {}
   const actions = {}
 
+  // Define the default actions to be handled by reduxGen
   const actionList = ['create', 'update', 'delete']
 
   /** Populate the actionTypes and actions */
   actionList.forEach(action => {
+    // actionType is sth like CREATE_ITEM
     const actionType = `${action.toUpperCase()}_${name.toUpperCase()}`
+    // actionName is sth like createItem
     const actionName = `${action}${name[0].toUpperCase()}${name.substring(1)}`
+
+    // Add the action types and actions to the array
     actionTypes[actionType] = `${name}/${actionType}`
     actions[actionName] = (id, data) => { return { type: `${name}/${actionType}`, id, data } }
   })
 
+  // Default state.
   const state = []
 
+  // Reducer
   function reducer (state = [], action) {
+    if (!action) {
+      return state
+    }
     let nextState
     switch (action.type) {
       case actionTypes[`CREATE_${name.toUpperCase()}`]:
@@ -37,11 +70,9 @@ export default function reduxGen (name) {
   }
 
   return {
-    actionTypes,
-    actions,
-    state,
-    reducer,
-    watchers: null,
-    workers: null
+    actionTypes: { [name]: actionTypes },
+    actions: { [name]: actions },
+    state: { [name]: state },
+    reducer: { [name]: reducer }
   }
 }

+ 7 - 87
src/redux-gen/crud.js

@@ -1,92 +1,12 @@
 import { call, put, takeEvery } from 'redux-saga/effects'
 
-/** The basic CRUD API supports the following functionality:
-  * /api[/module][/id|/offset[/limit]]
-  *
-  * Other functions
-  */
-
-import request from 'request-promise'
-export function crudHttpApi (action, options) {
-  const { uri } = options
-  // determine the operation
-  const [ name, actionType ] = action.type.split('/')
-  const requestOptions = {
-    uri: `${uri}/${name}`,
-    method: null,
-    body: null
-  }
-  switch (actionType) {
-    case 'READ_REQUEST':
-      options.uri = `${uri}/${action.id}`
-      options.method = 'GET'
-      break
-    case 'CREATE_REQUEST':
-      options.method = 'POST'
-      options.body = action.data
-      break
-    case 'UPDATE_REQUEST':
-      options.uri = `${uri}/${action.id}`
-      options.method = 'PUT'
-      break
-    case 'DELETE_REQUEST':
-      options.uri = `${uri}/${action.id}`
-      options.method = 'DELETE'
-      break
-  }
-  // Request from the request-promise library already returns a promise.
-  return request(requestOptions)
-}
-
-export function crudLocalstorageApi (action, options) {
-  // determine the operation
-  const [ name, actionType ] = action.type.split('/')
-  switch (actionType) {
-    case 'READ_REQUEST':
-      return new Promise((resolve, reject) => {
-        const items = localStorage.getItem(name) || []
-        resolve(items[action.id])
-      })
-    case 'CREATE_REQUEST':
-      return new Promise((resolve, reject) => {
-        try {
-          const items = localStorage.getItem(name) || {}
-          items[action.id] = action.data
-          console.log(items)
-          localStorage.setItem(name, items)
-          resolve(null)
-        } catch (error) {
-          reject(error)
-        }
-      })
-    case 'UPDATE_REQUEST':
-      return new Promise((resolve, reject) => {
-        try {
-          const items = localStorage.getItem(name) || {}
-          items[action.id] = action.data
-          localStorage.setItem(name, items)
-          resolve(null)
-        } catch (error) {
-          reject(error)
-        }
-      })
-    case 'DELETE_REQUEST':
-      return new Promise((resolve, reject) => {
-        try {
-          const items = localStorage.getItem(name) || {}
-          delete items[action.id]
-          localStorage.setItem(name, items)
-          resolve(null)
-        } catch (error) {
-          reject(error)
-        }
-      })
-  }
-}
-
 /** reduxCrudGen
   *
-  * Generates CRUD action types, actions, reducers, workers and watchers.
+  * Generates action types, actions, the reducer and redux sagas.
+  * @param {string} name - Name of the module
+  * @param {string} prefix - Prefix used for the actions
+  * @param {function} api - API called by the worker function
+  * @return {object} - { actionTypes, actions, state, reducer, worker, watcher }
   */
 export default function reduxCrudGen (name, prefix, api) {
   const actionTypes = {}
@@ -128,7 +48,7 @@ export default function reduxCrudGen (name, prefix, api) {
   /** The watcher function hijacks the _REQUEST actions and calls
     * asynchronous workers. Once they yield their result, a _SUCCESS
     * or _FAILURE action is triggered. */
-  function * watcher () {
+  function * saga () {
     let action
     for (action of actionList) {
       yield takeEvery(`${name}/${action.toUpperCase()}_REQUEST`, worker)
@@ -169,6 +89,6 @@ export default function reduxCrudGen (name, prefix, api) {
     state,
     reducer,
     worker,
-    watcher
+    saga
   }
 }