Ver código fonte

Allow arrays in key descriptor.

Herbert Vojčík 7 anos atrás
pai
commit
b0cefcedaa
2 arquivos alterados com 42 adições e 26 exclusões
  1. 32 22
      README.md
  2. 10 4
      src/cow-value-model.js

+ 32 - 22
README.md

@@ -1,12 +1,12 @@
 # redux-sac
 
-## Slice and compose redux-type reducers.
+## Slice redux objects (reducers, middleware, ...)
 
 ### `subReducer(key, reducer, additionalKey, ...)`
 
 Creates a wrapper reducer that calls `reducer`
 on the sub-state specified by `key`.
-You may use dot notation.
+Key can go in different formats, see `cowValueModel` below.
 Rest of the state is left untouched.
 
 ```js
@@ -27,7 +27,7 @@ if `personReducer` would return the identical array,
 If persons were deeper in hierarchy, it could have been created as
 `const r = subReducer("files.persons", personReducer);` for example.
 
-You may pass additional keys (also with possible dot-notation)
+You may pass additional keys
 as addition arguments. In that case, additional parts of state
 will be fetched and passed to a sub-reducer:
 
@@ -43,30 +43,13 @@ r({persons: ["John", "Jill"], assets: {cars: ["Honda"]}}, action);
 
 This technique is mentioned in Redux docs, in "Beyond combineReducers" page.
 
-### `composeReducers(reducer1, reducer2, ...)`
-
-Creates a wrapper reducer that calls passed reducers
-one after another, passing intermediate states.
-and returning the result of the last one.
-
-Useful to "concatenate" a few `subReducer`s. like:
-
-```js
-composeReducers(
-  subReducer("files.persons", personReducer, "assets.swag"),
-  subReducer("files.clients", clientReducer, "news"),
-  subReducer("assets", assetReducer),
-  baseReducer
-)
-```
-
 ### `subMiddleware(key | selectorFn, middleware)`
 
 Creates a wrapper middleware
 on the sub-state specified by `key`
 or the selector function `selectorFn`
 by decorating `getState` part of the passed arg.
-You may use dot notation.
+The `key` can have different format, see `cowValueModel` below.
 Rest of the passed arg is left untouched.
 
 ```js
@@ -125,6 +108,25 @@ store.dispatch({type: "foo"});
 // console => ["John","Jill"] 
 ```
 
+## Compose
+
+### `composeReducers(reducer1, reducer2, ...)`
+
+Creates a wrapper reducer that calls passed reducers
+one after another, passing intermediate states.
+and returning the result of the last one.
+
+Useful to "concatenate" a few `subReducer`s. like:
+
+```js
+composeReducers(
+  subReducer("files.persons", personReducer, "assets.swag"),
+  subReducer("files.clients", clientReducer, "news"),
+  subReducer("assets", assetReducer),
+  baseReducer
+)
+```
+
 ## Redux helpers
 
 ### `cowValueModel(key, ...)`
@@ -133,7 +135,10 @@ Creates an overloaded function allowing
 to set or get specified key from any object.
 Get when one arg, set when two args.
 Specify keys by passing a list of keys to `cowValueModel`.
-You can use dot notation.
+Key can be either:
+ - number
+ - array of Keys
+ - anything else, which is `toString()`ed and dot-split.
 
 Set-usage (two-arg) returns a copy with specified (sub-)property changed;
 in case no change actually happens, returns the original object.
@@ -148,6 +153,11 @@ name({name: "Tom"}, "Jerry");
   
 const city = cowValueModel("address.city");
 const city2 = cowValueModel("address", "city");
+// and other forms, like:
+// const city3 = cowValueModel(["address", "city"]);
+// const city4 = cowValueModel("address", [[], "city"]);
+// const city5 = cowValueModel([[], "address.city"]);
+// etc.
 const object = {address: {city: "New York"}};
   
 city(object);

+ 10 - 4
src/cow-value-model.js

@@ -6,10 +6,16 @@ function copyWith (obj, key, value) {
 
 export const cowValueModel = (...keyDescriptions) => {
     const keys = [];
-    keyDescriptions.forEach(each => {
-        if (typeof each === 'number') keys.push(each);
-        else keys.push(...each.toString().split('.'));
-    });
+
+    function fillKeys (keyDescriptions) {
+        keyDescriptions.forEach(each => {
+            if (typeof each === 'number') keys.push(each);
+            else if (Array.isArray(each)) fillKeys(each);
+            else keys.push(...each.toString().split('.'));
+        });
+    }
+
+    fillKeys(keyDescriptions);
 
     function setField (x = {}, index, val) {
         if (index >= keys.length) return val;