@webkrafters/react-observable-context 4.4.3 → 4.5.0-rc

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
@@ -342,6 +342,7 @@ Routinely, the `value` prop is initialized with the full initial state. It may o
342
342
 
343
343
  <h2 id="selector-map">Selector Map</h2>
344
344
  A selector map is an object holding key:value pairs.<br />
345
+ <i><b>An array of <a href="#property-path">property paths</a> is also acceptable:</b> indexes serve as keys for this purpose.</i><br />
345
346
  <span style="margin-right: 10px">-</span><code>key</code> refers to an arbitrary name to be assigned to a given property in the <a href="#store"><code>store.data</code></a>.<br />
346
347
  <span style="margin-right: 10px">-</span><code>value</code> refers to the <a href="#property-path">property path</a> leading to a state slice whose value will be assigned to and observed by this <a href="#store"><code>store.data</code></a> property.<br />
347
348
  <span style="margin-right: 10px">-</span>A special '<a href="#fullstate-selectorkey">@@STATE</a>' value may be used to access and observe the full state object.<br />
@@ -361,7 +362,9 @@ const state = {
361
362
  }
362
363
  };
363
364
 
364
- // a client observing the following selector map
365
+ /* --------------------------------------------- */
366
+ /* a client observing the following selector map */
367
+ /* --------------------------------------------- */
365
368
  const selectorMap = {
366
369
  all: '@@STATE',
367
370
  myData: 'd',
@@ -373,7 +376,20 @@ store.data = {
373
376
  all: state,
374
377
  myData: state.d,
375
378
  secondFElement: state.d.f[1]
376
- }
379
+ };
380
+
381
+ /* --------------------------------------------------- */
382
+ /* a client observing the following property path list */
383
+ /* --------------------------------------------------- */
384
+ const propertyPaths = [ '@@STATE', 'd', 'd.f[1]' ];
385
+
386
+ // will receive the following store data
387
+ store.data = {
388
+ 0: state,
389
+ 1: state.d,
390
+ 2: state.d.f[1]
391
+ };
392
+
377
393
  ```
378
394
 
379
395
  ## Storage
@@ -1,6 +1,6 @@
1
1
  export default useRenderKeyProvider;
2
- export type Provider<T extends import("../../../types").State> = (selectorMap: {
3
- [selectorKey: string]: string | keyof T;
4
- }) => [string | keyof T];
2
+ export type Provider<T extends import("../../../types").State, MAP extends BaseSelectorMap<T> = BaseSelectorMap<T>> = (selectorMap: SelectorMap<T, MAP>) => [string | keyof T];
3
+ export type SelectorMap<STATE extends import("../../../types").State = import("../../../types").State, MAP extends BaseSelectorMap<STATE> = BaseSelectorMap<STATE>> = import("../../../types").SelectorMap<STATE>;
4
+ export type BaseSelectorMap<STATE extends import("../../../types").State = import("../../../types").State> = import("../../../types").BaseSelectorMap<STATE>;
5
5
  export type State = import("../../../types").State;
6
- declare const useRenderKeyProvider: Provider<T>;
6
+ declare const useRenderKeyProvider: Provider<T, BaseSelectorMap<T>>;
@@ -18,6 +18,10 @@ export function createContext<T extends import("../types").State>(): ObservableC
18
18
  * a valid property path follows the `lodash` object property path convention.
19
19
  * for a state = { a: 1, b: 2, c: 3, d: { e: 5, f: [6, { x: 7, y: 8, z: 9 } ] } }
20
20
  * Any of the following is an applicable selector map.
21
+ * ['d', 'a'] => {
22
+ * 0: { e: 5, f: [6, { x: 7, y: 8, z: 9 } ] },
23
+ * 1: 1
24
+ * }
21
25
  * {myData: 'd', count: 'a'} => {
22
26
  * myData: { e: 5, f: [6, { x: 7, y: 8, z: 9 } ] },
23
27
  * count: 1
@@ -16,6 +16,86 @@ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _ty
16
16
  function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
17
17
  var _default = setState;
18
18
  exports["default"] = _default;
19
+ var setAtomic = function () {
20
+ var toStringProto = Object.prototype.toString;
21
+ var getCompositeDesc = function getCompositeDesc(value) {
22
+ return Array.isArray(value) ? 'ARRAY' : (0, _lodash2["default"])(value) ? 'OBJECT' : undefined;
23
+ };
24
+ var finalizeAtomicSet = function finalizeAtomicSet(state, changes, stateKey) {
25
+ var compositeChangeDesc = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
26
+ var change = changes[stateKey];
27
+ if (!compositeChangeDesc) {
28
+ if (!(0, _tagFunctions.isClosedTag)(change)) {
29
+ state[stateKey] = change;
30
+ return;
31
+ }
32
+ } else if (compositeChangeDesc === 'ARRAY') {
33
+ state[stateKey] = [];
34
+ } else if (compositeChangeDesc === 'OBJECT') {
35
+ if (isIndexBasedObj(change)) {
36
+ state[stateKey] = [];
37
+ } else {
38
+ var newState = {};
39
+ for (var k in change) {
40
+ var childChange = change[k];
41
+ if (toStringProto.call(childChange) === '[object String]') {
42
+ newState[k] = childChange;
43
+ continue;
44
+ }
45
+ var hasProps = false;
46
+ for (var p in childChange !== null && childChange !== void 0 ? childChange : {}) {
47
+ hasProps = true;
48
+ break;
49
+ }
50
+ if (!hasProps) {
51
+ newState[k] = childChange;
52
+ } else if (isArrayTaggedPayload(childChange)) {
53
+ newState[k] = [];
54
+ }
55
+ }
56
+ state[stateKey] = newState;
57
+ }
58
+ }
59
+ return setAtomic(state, changes, stateKey);
60
+ };
61
+ var setAtomic = function setAtomic(state, changes, stateKey) {
62
+ var stats = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
63
+ hasChanges: false
64
+ };
65
+ if ((0, _lodash["default"])(state[stateKey], changes[stateKey])) {
66
+ return;
67
+ }
68
+ var tagsResolved = resolveTags(state, changes, stateKey, stats);
69
+ var compositeChangeDesc = getCompositeDesc(changes[stateKey]);
70
+ if (Array.isArray(state[stateKey])) {
71
+ if (compositeChangeDesc === 'ARRAY') {
72
+ return setArray(state, changes, stateKey, stats);
73
+ }
74
+ if (compositeChangeDesc === 'OBJECT' && isIndexBasedObj(changes[stateKey])) {
75
+ return setArrayIndex(state, changes, stateKey, stats);
76
+ }
77
+ }
78
+ if (compositeChangeDesc === 'OBJECT' && (0, _lodash2["default"])(state[stateKey])) {
79
+ return setPlainObject(state, changes, stateKey, stats);
80
+ }
81
+ if (tagsResolved.length || !(stateKey in changes)) {
82
+ return;
83
+ }
84
+ ;
85
+ stats.hasChanges = true;
86
+ finalizeAtomicSet(state, changes, stateKey, compositeChangeDesc);
87
+ };
88
+ return setAtomic;
89
+ }();
90
+ function isArrayTaggedPayload(payload) {
91
+ for (var k in payload) {
92
+ if (!(0, _tagFunctions.isArrayOnlyTag)(k)) {
93
+ return false;
94
+ }
95
+ }
96
+ return true;
97
+ }
98
+ ;
19
99
  function isIndexBasedObj(obj) {
20
100
  for (var k in obj) {
21
101
  if (!(k in _tagFunctions["default"] || Number.isInteger(+k))) {
@@ -32,6 +112,9 @@ function resolveTags(state, changes, stateKey, stats) {
32
112
  if (!(0, _utils.isDataContainer)(changes[stateKey])) {
33
113
  return resolvedTags;
34
114
  }
115
+ if (!(stateKey in state) && isArrayTaggedPayload(changes[stateKey])) {
116
+ state[stateKey] = [];
117
+ }
35
118
  for (var k in changes[stateKey]) {
36
119
  if (!(stateKey in changes)) {
37
120
  break;
@@ -82,31 +165,6 @@ function setArrayIndex(state, changes, rootKey, stats) {
82
165
  setAtomic(state[rootKey], changes[rootKey], i, stats);
83
166
  }
84
167
  }
85
- function setAtomic(state, changes, stateKey, stats) {
86
- if ((0, _lodash["default"])(state[stateKey], changes[stateKey])) {
87
- return;
88
- }
89
- var tagsResolved = resolveTags(state, changes, stateKey, stats);
90
- var isPlainObjectNewState = (0, _lodash2["default"])(changes[stateKey]);
91
- var isArrayNewState = Array.isArray(changes[stateKey]);
92
- if (Array.isArray(state[stateKey])) {
93
- if (isArrayNewState) {
94
- return setArray(state, changes, stateKey, stats);
95
- }
96
- if (isPlainObjectNewState && isIndexBasedObj(changes[stateKey])) {
97
- return setArrayIndex(state, changes, stateKey, stats);
98
- }
99
- }
100
- if (isPlainObjectNewState && (0, _lodash2["default"])(state[stateKey])) {
101
- return setPlainObject(state, changes, stateKey, stats);
102
- }
103
- if (tagsResolved.length || !(stateKey in changes)) {
104
- return;
105
- }
106
- ;
107
- stats.hasChanges = true;
108
- state[stateKey] = isArrayNewState || isPlainObjectNewState ? (0, _utils.clonedeep)(changes[stateKey]) : changes[stateKey];
109
- }
110
168
  function setPlainObject(state, changes, rootKey, stats) {
111
169
  set(state[rootKey], changes[rootKey], stats);
112
170
  }
@@ -10,6 +10,7 @@ export function $set(state: T, stateKey: K, stats: Stats, changes: (import("../.
10
10
  }; })): void;
11
11
  export const $splice: TagFunction<T, K, import("../../../types").SpliceCommand>;
12
12
  export default tagMap;
13
+ export const isArrayOnlyTag: (tag: TagKey | BaseType) => boolean;
13
14
  export const isClosedTag: (tag: TagKey | BaseType) => boolean;
14
15
  export type TagKey = keyof typeof tagMap;
15
16
  export type TagFunction<T extends any[] | import("../../../types").State, K extends keyof T, TAG extends {
@@ -3,7 +3,7 @@ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" =
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isClosedTag = exports["default"] = exports.$splice = exports.$set = exports.$replace = exports.$push = exports.$move = exports.$delete = exports.$clear = void 0;
6
+ exports.isClosedTag = exports.isArrayOnlyTag = exports["default"] = exports.$splice = exports.$set = exports.$replace = exports.$push = exports.$move = exports.$delete = exports.$clear = void 0;
7
7
  var _lodash = _interopRequireDefault(require("lodash.isempty"));
8
8
  var _lodash2 = _interopRequireDefault(require("lodash.isequal"));
9
9
  var _lodash3 = _interopRequireDefault(require("lodash.isplainobject"));
@@ -287,10 +287,21 @@ exports.$splice = $splice;
287
287
  var tagMap = (_tagMap = {}, _defineProperty(_tagMap, _constants.CLEAR_TAG, $clear), _defineProperty(_tagMap, _constants.DELETE_TAG, $delete), _defineProperty(_tagMap, _constants.MOVE_TAG, $move), _defineProperty(_tagMap, _constants.PUSH_TAG, $push), _defineProperty(_tagMap, _constants.REPLACE_TAG, $replace), _defineProperty(_tagMap, _constants.SET_TAG, $set), _defineProperty(_tagMap, _constants.SPLICE_TAG, $splice), _tagMap);
288
288
  var _default = tagMap;
289
289
  exports["default"] = _default;
290
+ var containsTag = function containsTag(tagsMap, tag) {
291
+ return tag in tagsMap && !Array.isArray(tag);
292
+ };
293
+ var isArrayOnlyTag = function () {
294
+ var _ARRAY_TAGS;
295
+ var ARRAY_TAGS = (_ARRAY_TAGS = {}, _defineProperty(_ARRAY_TAGS, _constants.MOVE_TAG, null), _defineProperty(_ARRAY_TAGS, _constants.PUSH_TAG, null), _defineProperty(_ARRAY_TAGS, _constants.SPLICE_TAG, null), _ARRAY_TAGS);
296
+ return function (tag) {
297
+ return containsTag(ARRAY_TAGS, tag);
298
+ };
299
+ }();
300
+ exports.isArrayOnlyTag = isArrayOnlyTag;
290
301
  var isClosedTag = function () {
291
302
  var NO_PARAM_TAGS = _defineProperty({}, _constants.CLEAR_TAG, null);
292
303
  return function (tag) {
293
- return tag in NO_PARAM_TAGS && !Array.isArray(tag);
304
+ return containsTag(NO_PARAM_TAGS, tag);
294
305
  };
295
306
  }();
296
307
  exports.isClosedTag = isClosedTag;
@@ -17,6 +17,17 @@ function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) {
17
17
  function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
18
18
  function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
19
19
  function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
20
+ var isFunction = function () {
21
+ var toString = Function.prototype.toString;
22
+ var is = function is(v) {
23
+ try {
24
+ return toString.call(v);
25
+ } catch (e) {
26
+ return false;
27
+ }
28
+ };
29
+ return is;
30
+ }();
20
31
  var _connections = new WeakMap();
21
32
  var _value = new WeakMap();
22
33
  var Atom = function () {
@@ -59,7 +70,7 @@ var Atom = function () {
59
70
  }, {
60
71
  key: "setValue",
61
72
  value: function setValue(newValue) {
62
- _classPrivateFieldSet(this, _value, (0, _utils.makeReadonly)((0, _utils.clonedeep)(newValue)));
73
+ _classPrivateFieldSet(this, _value, !isFunction(newValue) ? (0, _utils.makeReadonly)((0, _utils.clonedeep)(newValue)) : newValue);
63
74
  }
64
75
  }]);
65
76
  return Atom;
package/dist/types.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  declare const _default: any;
2
2
  export default _default;
3
- export type BaseSelectorMap<T extends State> = {
3
+ export type BaseSelectorMap<T extends State> = (string | keyof T)[] | ({
4
4
  [dataPropKey: string]: string | keyof T;
5
5
  } & {
6
6
  [dataPropKey: string]: "@@STATE";
7
- };
7
+ });
8
8
  export type BaseType = boolean | any[] | {
9
9
  [x: string]: any;
10
10
  } | KeyType;
package/package.json CHANGED
@@ -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.4.3"
136
+ "version": "4.5.0-rc"
137
137
  }