@webkrafters/react-observable-context 4.6.1 → 4.7.0

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/README.md CHANGED
@@ -418,13 +418,13 @@ The `React.Observable.Context` context `store` is the client's portal into the c
418
418
  <li>
419
419
  <p style="margin: 0 0 0 10px">
420
420
  <a href="#store-resetstate"><b>resetState:</b></a>
421
- <code style="margin-left: 5px">(propertyPaths?: Array<string>) => void // resets slices of state referenced by the property paths to their initial values.</code>
421
+ <code style="margin-left: 5px">(propertyPaths?: Array&lt;string&gt;) => void // resets slices of state referenced by the property paths to their initial values.</code>
422
422
  </p>
423
423
  </li>
424
424
  <li>
425
425
  <p style="margin: 0 0 0 10px">
426
426
  <a href="#store-setstate"><b>setState:</b></a>
427
- <code style="margin-left: 5px">(changes: PartialState<State>) => void // merges only new/changed state slices.</code>
427
+ <code style="margin-left: 5px">(changes: Changes&lt;State&gt;) => void // merges only new/changed state slices.</code>
428
428
  </p>
429
429
  </li>
430
430
  </ol>
@@ -440,7 +440,18 @@ The `React.Observable.Context` context `store` is the client's portal into the c
440
440
  <blockquote>[This store's] internal state is <u><b>immutable</b></u> and <u><b>private</b></u>.</blockquote>
441
441
  New updates are merged into state by default. To overwrite state, use the <a href="setstate-tags">tag</a> command.<br />
442
442
  :warning: <b><i>Do this:</i></b> <code>setState({stateKey0: changes0[, ...]});</code><br />
443
- :warning: <b><i>Not this:</i></b> <code>setState({stateKey0: {...state.stateKey0, ...changes0}[, ...]});</code>
443
+ :warning: <b><i>Not this:</i></b> <code>setState({stateKey0: {...state.stateKey0, ...changes0}[, ...]});</code><br />
444
+ :warning: <b><i>Or this:</i></b> <code>setState([<br />
445
+ &nbsp;&nbsp;&nbsp;&nbsp;{ stateKey0: changes0[, ...] },<br />
446
+ &nbsp;&nbsp;&nbsp;&nbsp;{ stateKey1: changes1[, ...] },<br />
447
+ &nbsp;&nbsp;&nbsp;&nbsp;...<br />
448
+ ]);</code><br />
449
+ :warning: <b><i>Not this:</i></b> <code>setState([<br />
450
+ &nbsp;&nbsp;&nbsp;&nbsp;{stateKey0: {...state.stateKey0, ...changes0}[, ...]},<br />
451
+ &nbsp;&nbsp;&nbsp;&nbsp;{stateKey1: {...state.stateKey1, ...changes1}[, ...]},<br />
452
+ &nbsp;&nbsp;&nbsp;&nbsp;...<br />
453
+ ]);</code>
454
+
444
455
  <h3 id="indexing"><b><i><u>Indexing</u></i></b></h3>
445
456
  Existing array state property can be overridden with a new array.<br />
446
457
  Use the indexed object to update array content at indexes.<br />
@@ -573,7 +584,7 @@ store.setState({ a: { [ PUSH_TAG ]: [{ n: 5 }] } }) // assigning a '@@PUSH' comm
573
584
  store.setState({ a: { b: { [ PUSH_TAG ]: [{ x: 27, y: 28, z: 29 }, { x: 37, y: 38, z: 39 }] } } })
574
585
  ```
575
586
 
576
- <i id="replace-tag-usage"><b>@@REPLACE:</b> (takes an argument holding the replacment value)</i>
587
+ <i id="replace-tag-usage"><b>@@REPLACE:</b> (takes an argument holding the replacement value)</i>
577
588
 
578
589
  ```jsx
579
590
  import { REPLACE_TAG } from '@webkrafters/react-observable-context'; // REPLACE_TAG = "@@REPLACE"
@@ -623,7 +634,7 @@ store.setState({ a: { b: [ state.a.b[ 0 ], { [ SET_TAG ]: currentValue => ({ ...
623
634
  store.setState({ a: { b: { 1: { [ SET_TAG ]: currentValue => ({ ...currentValue, x: 97, y: 98, z: 99 }) } } } })
624
635
  ```
625
636
 
626
- <i id="splice-tag-usage"><b>@@SPLICE:</b> (takes an array argumenst listing: -/+fromIndex, +deleteCount and optional ...newItems? newItems = ...[] by default)</i>
637
+ <i id="splice-tag-usage"><b>@@SPLICE:</b> (takes an array argument listing: -/+fromIndex, +deleteCount and optional ...newItems? newItems = ...[] by default)</i>
627
638
 
628
639
  ```jsx
629
640
  import { SPLICE_TAG } from '@webkrafters/react-observable-context'; // SPLICE_TAG = "@@SPLICE"
@@ -683,6 +694,10 @@ store.setState({
683
694
  <h1 id="changes">What's Changed?</h1>
684
695
 
685
696
  <table>
697
+ <thead><tr><th>v4.7.0</th></tr></thead>
698
+ <tbody>
699
+ <tr><td><b>1.</b></td><td><a href="#store-setstate"><code>store.setState</code></a> can now accept an array of updates for gurranteed orderly processing.</td></tr>
700
+ </tbody>
686
701
  <thead><tr><th>v4.6.0</th></tr></thead>
687
702
  <tbody>
688
703
  <tr><td><b>1.</b></td><td><a href="#store-resetstate"><code>store.resetState</code></a> can now update reset current state even when initial state does not exist. Formerly, a resetState call on a non-existent initial state had no effect.</td></tr>
@@ -25,7 +25,7 @@ var useStateManager = function useStateManager(initStateValue) {
25
25
  _useState4 = _slicedToArray(_useState3, 1),
26
26
  cache = _useState4[0];
27
27
  var select = (0, _react.useCallback)(cache.get.bind(cache), []);
28
- var stateWatch = (0, _react.useCallback)(cache.watchSource.bind(cache), []);
28
+ var stateWatch = (0, _react.useCallback)(cache.atomize.bind(cache), []);
29
29
  var unlink = (0, _react.useCallback)(function (clientId) {
30
30
  return cache.unlinkClient(clientId);
31
31
  }, []);
@@ -4,7 +4,7 @@ export namespace deps {
4
4
  }
5
5
  export default useStore;
6
6
  export type IStorage<T extends import("../../../types").State> = import("../../../types").IStorage<T>;
7
- export type UpdatePayload<T extends import("../../../types").State> = import("../../../types").UpdatePayload<PartialState<T>>;
7
+ export type Changes<T extends import("../../../types").State> = import("../../../types").Changes<T>;
8
8
  export type PartialState<T extends import("../../../types").State> = import('../../../types').PartialState<T>;
9
9
  export type Prehooks<T extends import("../../../types").State> = import("../../../types").Prehooks<T>;
10
10
  export type StoreInternal<T extends import("../../../types").State> = import("../../../types").StoreInternal<T>;
@@ -116,8 +116,9 @@ var useContext = function useContext(context) {
116
116
  try {
117
117
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
118
118
  var path = _step2.value;
119
- if (data[selectorMapInverse[path]] !== state[path]) {
120
- data[selectorMapInverse[path]] = state[path];
119
+ var dPath = selectorMapInverse[path];
120
+ if (data[dPath] !== state[path]) {
121
+ data[dPath] = state[path];
121
122
  hasChanges = true;
122
123
  }
123
124
  }
@@ -134,7 +135,8 @@ var useContext = function useContext(context) {
134
135
  }, []);
135
136
  _react["default"].useEffect(function () {
136
137
  if ((0, _lodash["default"])(_renderKeys)) {
137
- !(0, _lodash2["default"])({}, data) && setData({});
138
+ var _default = {};
139
+ !(0, _lodash2["default"])(_default, data) && setData(_default);
138
140
  return;
139
141
  }
140
142
  for (var selectorKey in data) {
@@ -25,8 +25,7 @@ export type HasRoot<K extends import("../../types").KeyType = string, T> = K ext
25
25
  };
26
26
  export type KeyType = import("../../types").KeyType;
27
27
  export type Listener<T extends import("../../types").State> = import("../../types").Listener<T>;
28
- export type UpdatePayload<T> = import("../../types").UpdatePayload<T>;
29
- export type PartialState<T extends import("../../types").State> = import("../../types").PartialState<T>;
28
+ export type Changes<T> = import("../../types").Changes<T>;
30
29
  export type State = import("../../types").State;
31
30
  export type Stats = import("../../types").UpdateStats;
32
- declare function setState<T extends import("../../types").State>(state: T, changes: UpdatePayload<import("../../types").PartialState<T>>, onStateChange?: Listener<T>): void;
31
+ declare function setState<T extends import("../../types").State>(state: T, changes: Changes<T>, onStateChange?: Listener<T>): void;
@@ -11,6 +11,7 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
11
11
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
12
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
13
13
  function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
14
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
14
15
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
15
16
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
16
17
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
@@ -182,11 +183,29 @@ function setState(state, changes, onStateChange) {
182
183
  var stats = {
183
184
  hasChanges: false
184
185
  };
185
- var changeRequest = {
186
- state: (0, _utils.clonedeep)(changes)
187
- };
188
- set({
189
- state: state
190
- }, changeRequest, stats);
186
+ if (!Array.isArray(changes)) {
187
+ set({
188
+ state: state
189
+ }, {
190
+ state: (0, _utils.clonedeep)(changes)
191
+ }, stats);
192
+ } else {
193
+ var _iterator = _createForOfIteratorHelper(changes),
194
+ _step;
195
+ try {
196
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
197
+ var _cGroup = _step.value;
198
+ set({
199
+ state: state
200
+ }, {
201
+ state: (0, _utils.clonedeep)(_cGroup)
202
+ }, stats);
203
+ }
204
+ } catch (err) {
205
+ _iterator.e(err);
206
+ } finally {
207
+ _iterator.f();
208
+ }
209
+ }
191
210
  stats.hasChanges && (onStateChange === null || onStateChange === void 0 ? void 0 : onStateChange(changes));
192
211
  }
@@ -234,7 +234,7 @@ var $set = function () {
234
234
  var toString = Object.prototype.toString;
235
235
  var set = function set(state, stateKey, stats, changes) {
236
236
  if (toString.call(changes[stateKey][_constants.SET_TAG]) === '[object Function]') {
237
- changes[stateKey][_constants.SET_TAG] = changes[stateKey][_constants.SET_TAG]((0, _utils.clonedeep)(state[stateKey]));
237
+ changes[stateKey][_constants.SET_TAG] = (0, _utils.clonedeep)(changes[stateKey][_constants.SET_TAG]((0, _utils.clonedeep)(state[stateKey])));
238
238
  }
239
239
  applyReplaceCommand(_constants.SET_TAG, state, changes, stateKey, stats);
240
240
  };
@@ -3,10 +3,10 @@ export type Listener<T extends import("../../types").State> = import("../../type
3
3
  export type State = import("../../types").State;
4
4
  declare class AccessorCache<T extends import("../../types").State> {
5
5
  constructor(origin: T);
6
+ atomize(changes: import("../../types").Changes<T>): void;
6
7
  get(clientId: string, ...propertyPaths: string[]): {
7
8
  [propertyPaths: string]: Readonly<any>;
8
9
  };
9
10
  unlinkClient(clientId: string): void;
10
- watchSource(changes: import("../../types").Changes<T>): void;
11
11
  #private;
12
12
  }
@@ -55,9 +55,50 @@ var AccessorCache = function () {
55
55
  _classPrivateFieldSet(this, _origin, origin);
56
56
  }
57
57
  _createClass(AccessorCache, [{
58
+ key: "atomize",
59
+ value: function atomize(originChanges) {
60
+ var accessors = _classPrivateFieldGet(this, _accessors);
61
+ var atoms = _classPrivateFieldGet(this, _atoms);
62
+ var updatedPaths = [];
63
+ for (var path in atoms) {
64
+ var _classPrivateMethodGe = _classPrivateMethodGet(this, _getOriginAt, _getOriginAt2).call(this, path),
65
+ exists = _classPrivateMethodGe.exists,
66
+ newAtomVal = _classPrivateMethodGe.value;
67
+ if (path !== _constants.FULL_STATE_SELECTOR && exists && (newAtomVal === null || newAtomVal === undefined)) {
68
+ if (!Array.isArray(originChanges)) {
69
+ if (!(0, _utils.getProperty)(originChanges, path).trail.length) {
70
+ continue;
71
+ }
72
+ } else {
73
+ var found = false;
74
+ for (var i = originChanges.length; i--;) {
75
+ if ((0, _utils.getProperty)(originChanges, "".concat(i, ".").concat(path)).trail.length) {
76
+ found = true;
77
+ break;
78
+ }
79
+ }
80
+ if (!found) {
81
+ continue;
82
+ }
83
+ }
84
+ }
85
+ if ((0, _lodash2["default"])(newAtomVal, atoms[path].value)) {
86
+ continue;
87
+ }
88
+ atoms[path].setValue(newAtomVal);
89
+ updatedPaths.push(path);
90
+ }
91
+ if (!updatedPaths.length) {
92
+ return;
93
+ }
94
+ for (var k in accessors) {
95
+ var _accessors$k$outdated;
96
+ (_accessors$k$outdated = accessors[k].outdatedPaths).push.apply(_accessors$k$outdated, updatedPaths);
97
+ }
98
+ }
99
+ }, {
58
100
  key: "get",
59
- value:
60
- function get(clientId) {
101
+ value: function get(clientId) {
61
102
  for (var _len = arguments.length, propertyPaths = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
62
103
  propertyPaths[_key - 1] = arguments[_key];
63
104
  }
@@ -96,30 +137,6 @@ var AccessorCache = function () {
96
137
  delete accessors[k];
97
138
  }
98
139
  }
99
- }, {
100
- key: "watchSource",
101
- value: function watchSource(originChanges) {
102
- var accessors = _classPrivateFieldGet(this, _accessors);
103
- var atoms = _classPrivateFieldGet(this, _atoms);
104
- var updatedPaths = [];
105
- for (var path in atoms) {
106
- var _classPrivateMethodGe = _classPrivateMethodGet(this, _getOriginAt, _getOriginAt2).call(this, path),
107
- exists = _classPrivateMethodGe.exists,
108
- newAtomVal = _classPrivateMethodGe.value;
109
- if (path !== _constants.FULL_STATE_SELECTOR && exists && (newAtomVal === null || newAtomVal === 'undefined') && !(0, _utils.getProperty)(originChanges, path).trail.length || (0, _lodash2["default"])(newAtomVal, atoms[path].value)) {
110
- continue;
111
- }
112
- atoms[path].setValue(newAtomVal);
113
- updatedPaths.push(path);
114
- }
115
- if (!updatedPaths.length) {
116
- return;
117
- }
118
- for (var k in accessors) {
119
- var _accessors$k$outdated;
120
- (_accessors$k$outdated = accessors[k].outdatedPaths).push.apply(_accessors$k$outdated, updatedPaths);
121
- }
122
- }
123
140
  }]);
124
141
  return AccessorCache;
125
142
  }();
package/dist/types.d.ts CHANGED
@@ -53,10 +53,11 @@ export type Store<T extends State, SELECTOR_MAP extends BaseSelectorMap<T> = Bas
53
53
  resetState: (propertyPaths?: string[]) => void;
54
54
  setState: (changes: Changes<T>) => void;
55
55
  };
56
- export type Changes<T extends State> = UpdatePayload<PartialState<T>>;
56
+ export type Changes<T extends State> = UpdatePayload<PartialState<T>> | UpdatePayloadArray<PartialState<T>>;
57
57
  export type UpdateStats = {
58
58
  hasChanges: boolean;
59
59
  };
60
+ export type UpdatePayloadArray<T> = Array<UpdatePayload<T>>;
60
61
  export type UpdatePayload<T> = "@@CLEAR" | T | ClearCommand | DeleteCommand<T> | MoveCommand | PushCommand | ReplaceCommand | SetCommand<T> | SpliceCommand | { [K in keyof T]?: UpdatePayload<T[K]>; };
61
62
  export type ClearCommand = {
62
63
  "@@CLEAR": any;
@@ -5,6 +5,8 @@ export function mapPathsToObject<T extends {
5
5
  [x: string]: any;
6
6
  }>(source: T, propertyPaths: Array<string>, transform?: Tranform): { [K in keyof T]?: any; };
7
7
  export function clonedeep<T, R>(value: T): R;
8
- export const getProperty: any;
8
+ export const getProperty: typeof get;
9
9
  export const stringToDotPath: (path: string) => string;
10
- export type Tranform = (property: any) => T;
10
+ export type Tranform<T = any> = (property: PropertyInfo) => T;
11
+ export type PropertyInfo = import("@webkrafters/get-property").PropertyInfo;
12
+ import get from "@webkrafters/get-property";
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "steveswork <stephen.isienyi@gmail.com> (https://github.com/steveswork)"
8
8
  ],
9
9
  "dependencies": {
10
- "@webkrafters/get-property": "^1.1.1",
10
+ "@webkrafters/get-property": "^1.1.2",
11
11
  "lodash.clonedeepwith": "^4.5.0",
12
12
  "lodash.isboolean": "^3.0.3",
13
13
  "lodash.isempty": "^4.4.0",
@@ -133,5 +133,5 @@
133
133
  "test:watch": "eslint --fix && jest --updateSnapshot --watchAll"
134
134
  },
135
135
  "types": "dist/main/index.d.ts",
136
- "version": "4.6.1"
136
+ "version": "4.7.0"
137
137
  }