@webkrafters/react-observable-context 4.0.0 → 4.1.0-alpha.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 +201 -0
- package/dist/constants.d.ts +8 -1
- package/dist/constants.js +16 -2
- package/dist/main/hooks/use-state-manager/index.js +2 -2
- package/dist/main/hooks/use-store/index.d.ts +2 -1
- package/dist/main/hooks/use-store/index.js +5 -6
- package/dist/main/index.d.ts +10 -9
- package/dist/main/set-state/index.d.ts +4 -4
- package/dist/main/set-state/index.js +94 -67
- package/dist/main/set-state/tag-functions/index.d.ts +37 -0
- package/dist/main/set-state/tag-functions/index.js +348 -0
- package/dist/model/accessor-cache/index.d.ts +1 -1
- package/dist/model/accessor-cache/index.js +7 -8
- package/dist/model/atom/index.js +1 -3
- package/dist/model/storage/index.js +2 -3
- package/dist/types.d.ts +48 -4
- package/dist/utils/clonedeep-eligibility-check.d.ts +7 -0
- package/dist/utils/clonedeep-eligibility-check.js +52 -0
- package/dist/utils/index.d.ts +7 -1
- package/dist/utils/index.js +126 -4
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -207,6 +207,198 @@ store.setState({ ...state, a: { ...state.a, b: [ { ...first, y: 30 }, 22, ...res
|
|
|
207
207
|
// Refrain from doing this, please!
|
|
208
208
|
```
|
|
209
209
|
|
|
210
|
+
<h3 id="setstate-tags"><b><i><u>Rewriting state using tag commands</u></i></b></h3>
|
|
211
|
+
By default setState merges new changes into the current state slices. To overwrite current state slices with new state values, <b>7</b> tag commands have been provided for:
|
|
212
|
+
<ol>
|
|
213
|
+
<li><span style="margin-left: 10px"><b><code>@@CLEAR:</code></b> setting state slice to its corresponding empty value</span></li>
|
|
214
|
+
<li><span style="margin-left: 10px"><b><code>@@DELETE:</code></b> deleting properties</span></li>
|
|
215
|
+
<li><span style="margin-left: 10px"><b><code>@@MOVE:</code></b> moving array elements</span></li>
|
|
216
|
+
<li><span style="margin-left: 10px"><b><code>@@PUSH:</code></b> pushing new items into an array</span></li>
|
|
217
|
+
<li><span style="margin-left: 10px"><b><code>@@REPLACE:</code></b> replacing property values</span></li>
|
|
218
|
+
<li><span style="margin-left: 10px"><b><code>@@SET:</code></b> setting property values</span></li>
|
|
219
|
+
<li><span style="margin-left: 10px"><b><code>@@SPLICE:</code></b> splicing array items</span></li>
|
|
220
|
+
</ol>
|
|
221
|
+
<strong>Examples:</strong>
|
|
222
|
+
|
|
223
|
+
<b><code>@@CLEAR:</code></b> <i>takes no arguments.</i>
|
|
224
|
+
|
|
225
|
+
```jsx
|
|
226
|
+
const state = {
|
|
227
|
+
a: { b: [{ x: 7, y: 8, z: 9 }, { x: 17, y: 18, z: 19 }] },
|
|
228
|
+
j: 10
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
store.setState( '@@CLEAR' ) // or store.setState({ @@CLEAR: <anything> })
|
|
232
|
+
|
|
233
|
+
/* empties the value at state.a.b; sets state.a.b = [] */
|
|
234
|
+
store.setState({ a: { b: '@@CLEAR' } }) // or store.setState({ a: { b: { @@CLEAR: <anything> } } })
|
|
235
|
+
|
|
236
|
+
/* empties the value at state.a.j; sets state.a.j = null */
|
|
237
|
+
store.setState({ a: { j: '@@CLEAR' } }) // or store.setState({ a: { j: { @@CLEAR: <anything> } } })
|
|
238
|
+
|
|
239
|
+
/* empties the value at state.a.b[ 0 ]; sets state.a.b = [{}] */
|
|
240
|
+
store.setState({ a: { b: [ '@@CLEAR' ] } }) // or store.setState({ a: { b: [ { @@CLEAR: <anything> } ] } })
|
|
241
|
+
|
|
242
|
+
/* empties the value at state.a.b[0]; sets state.a.b = [{}, state.a.b[1]] */
|
|
243
|
+
store.setState({ a: { b: [ '@@CLEAR', state.a.b[1] ] } }) // or store.setState({ a: { b: [ { @@CLEAR: <anything> }, state.a.b[1] ] } })
|
|
244
|
+
|
|
245
|
+
/* empties the value at state.a.b[0]; sets state.a.b = [{}, a.b[1]] using indexing (RECOMMENDED) */
|
|
246
|
+
store.setState({ a: { b: { 0: '@@CLEAR' } } }) // or store.setState({ a: { b: { 0: { @@CLEAR: <anything> } } } })
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
<b><code>@@DELETE:</code></b> <i>takes an array argument listing property keys to delete.</i>
|
|
250
|
+
|
|
251
|
+
```jsx
|
|
252
|
+
const state = {
|
|
253
|
+
a: { b: [{ x: 7, y: 8, z: 9 }, { x: 17, y: 18, z: 19 }] },
|
|
254
|
+
j: 10
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
store.setState({ '@@DELETE': [ 'a' ] }) // removes state.a; sets state = {j: 10}
|
|
258
|
+
|
|
259
|
+
store.setState({ a: { '@@DELETE': [ 'b' ] } }) // removes state.a.b; sets state.a = {}
|
|
260
|
+
|
|
261
|
+
/* removes state.a.b[0]; leaving state.a.b = [{ x: 17, y: 18, z: 19 }] */
|
|
262
|
+
store.setState({ a: { b: { '@@DELETE': [ 0 ] } } }) // or store.setState({ a: { b: { '@@DELETE': [ -2 ] } } })
|
|
263
|
+
|
|
264
|
+
/* removes `x` and `z` properties from state.a.b[1]; sets state.a.b = [{ x: 7, y: 8, z: 9 }, {y: 18}] */
|
|
265
|
+
store.setState({ a: { b: [ state.a.b[ 0 ], { '@@DELETE': [ 'x', 'z' ] } ] } })
|
|
266
|
+
|
|
267
|
+
/* removes `x` and `z` properties from state.a.b[1]; sets state.a.b = [{ x: 7, y: 8, z: 9 }, {y: 18}] using indexing (RECOMMENDED) */
|
|
268
|
+
store.setState({ a: { b: { 1: { '@@DELETE': [ 'x', 'z' ] } } } })
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
<b><code>@@MOVE:</code></b> <i>takes an array argument listing: -/+fromIndex, -/+toIndex and optional +numItems?. numItems = 1 by default. </i>
|
|
272
|
+
|
|
273
|
+
```jsx
|
|
274
|
+
const state = {
|
|
275
|
+
a: { b: [{ x: 7, y: 8, z: 9 }, { x: 17, y: 18, z: 19 }] },
|
|
276
|
+
j: 10,
|
|
277
|
+
q: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
store.setState({ a: { '@@MOVE': [ 0, 1 ] } }) // assigning a @@MOVE command to a non-array property has no effect.
|
|
281
|
+
|
|
282
|
+
/* moves state.a.b[0] into index 1; leaving state.a.b = [{ x: 17, y: 18, z: 19 }, { x: 7, y: 8, z: 9 }] */
|
|
283
|
+
store.setState({ a: { b: { '@@MOVE': [ 0, 1 ] } } }) // or store.setState({ a: { b: { '@@MOVE': [ -2, -1 ] } } })
|
|
284
|
+
|
|
285
|
+
/* moves state.q[4] - [7] into indexes 1 - 4; leaving state.q = [ 1, 5, 6, 7, 8, 2, 3, 4, 9 ] */
|
|
286
|
+
store.setState({ a: { q: { '@@MOVE': [ 4, 1, 4 ] } } }) // or store.setState({ a: { q: { '@@MOVE': [ -5, -8, 4 ] } } })
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
<b><code>@@PUSH:</code></b> <i>takes an array argument listing new values to append. </i>
|
|
290
|
+
|
|
291
|
+
```jsx
|
|
292
|
+
const state = {
|
|
293
|
+
a: { b: [{ x: 7, y: 8, z: 9 }, { x: 17, y: 18, z: 19 }] },
|
|
294
|
+
j: 10
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
store.setState({ a: { '@@PUSH': [{ n: 5 }] } }) // assigning a @@PUSH command to a non-array property has no effect.
|
|
298
|
+
|
|
299
|
+
/* appends 2 new items into state.a.b; leaving state.a.b = [...state.a.b, { x: 27, y: 28, z: 29 }, { x: 37, y: 38, z: 39 }] */
|
|
300
|
+
store.setState({ a: { b: { '@@PUSH': [{ x: 27, y: 28, z: 29 }, { x: 37, y: 38, z: 39 }] } } })
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
<b><code>@@REPLACE:</code></b> <i>takes an argument holding the replacment value. </i>
|
|
304
|
+
|
|
305
|
+
```jsx
|
|
306
|
+
const state = {
|
|
307
|
+
a: { b: [{ x: 7, y: 8, z: 9 }, { x: 17, y: 18, z: 19 }] },
|
|
308
|
+
j: 10
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
store.setState({ '@@REPLACE': { a: 'Demo', j: 17 } }) // rewrites state to { a: 'Demo', j: 17 };
|
|
312
|
+
|
|
313
|
+
store.setState({ a: { '@@REPLACE': { message: 'Testing...' } } }) // rewrites state.a.b to { message: 'Testing...' }
|
|
314
|
+
|
|
315
|
+
/* rewrites state.a.b[1] to { x: 97, y: 98, z: 99 }; leaving state.a.b = [{ x: 7, y: 8, z: 9 }, { x: 97, y: 98, z: 99 }] */
|
|
316
|
+
store.setState({ a: { b: [ state.a.b[ 0 ], { '@@REPLACE': { x: 97, y: 98, z: 99 } } ] } })
|
|
317
|
+
|
|
318
|
+
/* rewrites state.a.b[1] to { x: 97, y: 98, z: 99 }; leaving state.a.b = [{ x: 7, y: 8, z: 9 }, { x: 97, y: 98, z: 99 }] using indexing (RECOMMENDED) */
|
|
319
|
+
store.setState({ a: { b: { 1: { '@@REPLACE': { x: 97, y: 98, z: 99 } } } } })
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
<b><code>@@SET:</code></b> <i>takes an argument holding either the replacment value or a compute function returning the replacement value. </i>
|
|
323
|
+
|
|
324
|
+
```jsx
|
|
325
|
+
/*
|
|
326
|
+
@@SET and @@REPLACE tags are functionally equivalent when using replacement value argument.
|
|
327
|
+
However, @@SET also accepts a compute function argument for calculating a replacement value based on current value.
|
|
328
|
+
This tag is for handling edge cases only. Please use sparingly. In most cases, store.setState with or without any of the other tags is sufficient and most efficient.
|
|
329
|
+
*/
|
|
330
|
+
|
|
331
|
+
const state = {
|
|
332
|
+
a: { b: [{ x: 7, y: 8, z: 9 }, { x: 17, y: 18, z: 19 }] },
|
|
333
|
+
j: 10
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
store.setState({ '@@SET': currentValue => ({ ...currentValue, a: 'Demo', j: 17 }) }) // rewrites state to { ...state, a: 'Demo', j: 17 };
|
|
337
|
+
|
|
338
|
+
store.setState({ a: { '@@SET': currentValue => ({ ...currentValue, message: 'Testing...' }) } }) // rewrites state.a.b to { ...state, message: 'Testing...' }
|
|
339
|
+
|
|
340
|
+
/* rewrites state.a.b[1] to { x: 97, y: 98, z: 99 }; leaving state.a.b = [{ x: 7, y: 8, z: 9 }, { x: 97, y: 98, z: 99 }] */
|
|
341
|
+
store.setState({ a: { b: [ state.a.b[ 0 ], { '@@SET': currentValue => ({ ...currentValue, x: 97, y: 98, z: 99 }) } ] } })
|
|
342
|
+
|
|
343
|
+
/* rewrites state.a.b[1] to { x: 97, y: 98, z: 99 }; leaving state.a.b = [{ x: 7, y: 8, z: 9 }, { x: 97, y: 98, z: 99 }] using indexing (RECOMMENDED) */
|
|
344
|
+
store.setState({ a: { b: { 1: { '@@SET': currentValue => ({ ...currentValue, x: 97, y: 98, z: 99 }) } } } })
|
|
345
|
+
|
|
346
|
+
/** be aware: currentValue may be `undefined` when adding new state slice properties. */
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
<b><code>@@SPLICE:</code></b> <i>takes an array argument listing: -/+fromIndex, +deleteCount and optional ...newItems? newItems = ...[] by default. </i>
|
|
350
|
+
|
|
351
|
+
```jsx
|
|
352
|
+
const state = {
|
|
353
|
+
a: { b: [{ x: 7, y: 8, z: 9 }, { x: 17, y: 18, z: 19 }] },
|
|
354
|
+
j: 10,
|
|
355
|
+
q: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
store.setState({ a: { '@@SPLICE': [ 0, 1 ] } }) // assigning a @@SPLICE command to a non-array property has no effect.
|
|
359
|
+
|
|
360
|
+
/* removes state.a.b[0]; leaving state.a.b = [{ x: 17, y: 18, z: 19 }] */
|
|
361
|
+
store.setState({ a: { b: { '@@SPLICE': [ 0, 1 ] } } }) // or store.setState({ a: { b: { SPLICE': [ -2, -1 ] } } })
|
|
362
|
+
|
|
363
|
+
/* replaces state.q[4] - [7] with 2 items; leaving state.q = [ 1, 2, 3, 4, 33, 88, 9 ] */
|
|
364
|
+
store.setState({ a: { q: { '@@SPLICE': [ 4, 4, 33, 88 ] } } }) // or store.setState({ a: { q: { '@@SPLICE': [ -5, 4, 33, 88 ] } } })
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
<b><code>Combination Usage:</code></b>
|
|
368
|
+
|
|
369
|
+
These tags may be used in combination with the default usage where all nth-level tag command results are sequentially merged into state followed by the merging of the rest of the nth-level changes.
|
|
370
|
+
|
|
371
|
+
<strong>Example:</strong>
|
|
372
|
+
|
|
373
|
+
```jsx
|
|
374
|
+
const state = {
|
|
375
|
+
a: { b: [{ x: 7, y: 8, z: 9 }, { x: 17, y: 18, z: 19 }] },
|
|
376
|
+
j: 10,
|
|
377
|
+
q: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
store.setState({
|
|
381
|
+
a: {
|
|
382
|
+
b: {
|
|
383
|
+
/* evaluated 1st */ '@@DELETE': [ 0 ], // upon deleting state.a.b[0] -> state.a.b[1] becomes the new state.a.b[0]
|
|
384
|
+
/* evaluated 3rd */ 0: '@@CLEAR', // clear the new state.a.b[0]
|
|
385
|
+
/* evaluated 4th */ 2: { x: 47, y: 48, z: 49 }, // add new item at state.a.b[2],
|
|
386
|
+
/* evaluated 2md */ '@@PUSH': [{ x: 107, y: 108, z: 109 }] // appends state.a.b[1]
|
|
387
|
+
},
|
|
388
|
+
j: { '@@SET': currentValue => currentValue < 10 ? currentValue : 0 },
|
|
389
|
+
q: {
|
|
390
|
+
/* evaluated 1st */ '@@MOVE': [ 5, 3, 2 ],
|
|
391
|
+
/* evaluated 2md */ 12: 11
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
})
|
|
395
|
+
// => {
|
|
396
|
+
// a: { b: [{}, { x: 107, y: 108, z: 109 }, { x: 47, y: 48, z: 49 }] },
|
|
397
|
+
// j: 0,
|
|
398
|
+
// q: [ 1, 2, 3, 6, 7, 4, 5, 8, 9, <empty>, <empty>, <empty>, 11 ]
|
|
399
|
+
// }
|
|
400
|
+
```
|
|
401
|
+
|
|
210
402
|
# API
|
|
211
403
|
|
|
212
404
|
The React-Observable-Context module contains **4** exports namely:
|
|
@@ -389,6 +581,15 @@ ReactDOM.render( <Provider />, document.getElementById( 'root' ) );
|
|
|
389
581
|
```
|
|
390
582
|
|
|
391
583
|
<h1 id="changes">What's Changed?</h1>
|
|
584
|
+
<b>v4.1.0</b>
|
|
585
|
+
<table>
|
|
586
|
+
<tbody>
|
|
587
|
+
<tr><td><b>1.</b></td><td>Added new setState command <a href="#setstate-tags">tags</a>: <b><code>@@CLEAR<b><code>, <b><code>@@DELETE</code></b>, <b><code>@@MOVE</code></b>, <b><code>@@PUSH</code></b>, <b><code>@@REPLACE</code></b>, <b><code>@@SET</code></b> and <b><code>@@SPLICE</code></b>.</td></tr>
|
|
588
|
+
</tbody>
|
|
589
|
+
</table>
|
|
590
|
+
<hr />
|
|
591
|
+
|
|
592
|
+
<b>v4.0.0</b>
|
|
392
593
|
<table>
|
|
393
594
|
<tbody>
|
|
394
595
|
<tr><td><b>1.</b></td><td>Added the <a href="#connect"><code>connect</code></a> function to facilitate the encapsulated context-usage method.</td></tr>
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
+
export const CLEAR_TAG: "@@CLEAR";
|
|
2
|
+
export const DELETE_TAG: "@@DELETE";
|
|
1
3
|
export const FULL_STATE_SELECTOR: "@@STATE";
|
|
2
|
-
export const
|
|
4
|
+
export const MOVE_TAG: "@@MOVE";
|
|
5
|
+
export const NULL_STATE_SELECTOR: "";
|
|
6
|
+
export const PUSH_TAG: "@@PUSH";
|
|
7
|
+
export const REPLACE_TAG: "@@REPLACE";
|
|
8
|
+
export const SET_TAG: "@@SET";
|
|
9
|
+
export const SPLICE_TAG: "@@SPLICE";
|
package/dist/constants.js
CHANGED
|
@@ -2,8 +2,22 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
|
-
exports.NULL_STATE_SELECTOR = exports.FULL_STATE_SELECTOR = void 0;
|
|
5
|
+
exports.SPLICE_TAG = exports.SET_TAG = exports.REPLACE_TAG = exports.PUSH_TAG = exports.NULL_STATE_SELECTOR = exports.MOVE_TAG = exports.FULL_STATE_SELECTOR = exports.DELETE_TAG = exports.CLEAR_TAG = void 0;
|
|
6
|
+
var CLEAR_TAG = '@@CLEAR';
|
|
7
|
+
exports.CLEAR_TAG = CLEAR_TAG;
|
|
8
|
+
var DELETE_TAG = '@@DELETE';
|
|
9
|
+
exports.DELETE_TAG = DELETE_TAG;
|
|
6
10
|
var FULL_STATE_SELECTOR = '@@STATE';
|
|
7
11
|
exports.FULL_STATE_SELECTOR = FULL_STATE_SELECTOR;
|
|
12
|
+
var MOVE_TAG = '@@MOVE';
|
|
13
|
+
exports.MOVE_TAG = MOVE_TAG;
|
|
8
14
|
var NULL_STATE_SELECTOR = '';
|
|
9
|
-
exports.NULL_STATE_SELECTOR = NULL_STATE_SELECTOR;
|
|
15
|
+
exports.NULL_STATE_SELECTOR = NULL_STATE_SELECTOR;
|
|
16
|
+
var PUSH_TAG = '@@PUSH';
|
|
17
|
+
exports.PUSH_TAG = PUSH_TAG;
|
|
18
|
+
var REPLACE_TAG = '@@REPLACE';
|
|
19
|
+
exports.REPLACE_TAG = REPLACE_TAG;
|
|
20
|
+
var SET_TAG = '@@SET';
|
|
21
|
+
exports.SET_TAG = SET_TAG;
|
|
22
|
+
var SPLICE_TAG = '@@SPLICE';
|
|
23
|
+
exports.SPLICE_TAG = SPLICE_TAG;
|
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
exports["default"] = void 0;
|
|
6
6
|
var _react = require("react");
|
|
7
|
-
var
|
|
7
|
+
var _utils = require("../../../utils");
|
|
8
8
|
var _accessorCache = _interopRequireDefault(require("../../../model/accessor-cache"));
|
|
9
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
10
10
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
@@ -15,7 +15,7 @@ function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefine
|
|
|
15
15
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
16
16
|
var useStateManager = function useStateManager(initStateValue) {
|
|
17
17
|
var _useState = (0, _react.useState)(function () {
|
|
18
|
-
return (0,
|
|
18
|
+
return (0, _utils.clonedeep)(initStateValue);
|
|
19
19
|
}),
|
|
20
20
|
_useState2 = _slicedToArray(_useState, 1),
|
|
21
21
|
state = _useState2[0];
|
|
@@ -4,6 +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
8
|
export type PartialState<T extends import("../../../types").State> = import('../../../types').PartialState<T>;
|
|
8
9
|
export type Prehooks<T extends import("../../../types").State> = import("../../../types").Prehooks<T>;
|
|
9
10
|
export type StoreInternal<T extends import("../../../types").State> = import("../../../types").StoreInternal<T>;
|
|
@@ -15,7 +16,7 @@ declare function useStore<T extends import("../../../types").State>(prehooks: Pr
|
|
|
15
16
|
[propertyPaths: string]: Readonly<any>;
|
|
16
17
|
};
|
|
17
18
|
resetState: (propertyPaths?: string[]) => void;
|
|
18
|
-
setState: (changes: import("../../../types").PartialState<T
|
|
19
|
+
setState: (changes: import("../../../types").UpdatePayload<import("../../../types").PartialState<T>>) => void;
|
|
19
20
|
subscribe: (listener: import("../../../types").Listener<T>) => VoidFunction;
|
|
20
21
|
unlinkCache: (clientId: string) => void;
|
|
21
22
|
};
|
|
@@ -4,8 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
exports.deps = exports["default"] = void 0;
|
|
6
6
|
var _react = require("react");
|
|
7
|
-
var _lodash = _interopRequireDefault(require("lodash.
|
|
8
|
-
var _lodash2 = _interopRequireDefault(require("lodash.isboolean"));
|
|
7
|
+
var _lodash = _interopRequireDefault(require("lodash.isboolean"));
|
|
9
8
|
var _uuid = require("uuid");
|
|
10
9
|
var _constants = require("../../../constants");
|
|
11
10
|
var _utils = require("../../../utils");
|
|
@@ -34,7 +33,7 @@ function runPrehook(prehooks, name, args) {
|
|
|
34
33
|
return true;
|
|
35
34
|
}
|
|
36
35
|
var res = prehooks[name].apply(prehooks, _toConsumableArray(args));
|
|
37
|
-
if (!(0,
|
|
36
|
+
if (!(0, _lodash["default"])(res)) {
|
|
38
37
|
throw new TypeError("`".concat(name, "` prehook must return a boolean value."));
|
|
39
38
|
}
|
|
40
39
|
return res;
|
|
@@ -75,12 +74,12 @@ var useStore = function useStore(prehooks, value, storage) {
|
|
|
75
74
|
var original = _storage.clone(_storage.getItem(storageKey.current));
|
|
76
75
|
var resetData = !propertyPaths.length ? {} : propertyPaths.includes(_constants.FULL_STATE_SELECTOR) ? original : (0, _utils.mapPathsToObject)(original, propertyPaths);
|
|
77
76
|
runPrehook(prehooksRef.current, 'resetState', [resetData, {
|
|
78
|
-
current: (0,
|
|
77
|
+
current: (0, _utils.clonedeep)(state),
|
|
79
78
|
original: original
|
|
80
79
|
}]) && deps.setState(state, resetData, onChange);
|
|
81
80
|
}, []);
|
|
82
81
|
var setState = (0, _react.useCallback)(function (changes) {
|
|
83
|
-
changes = (0,
|
|
82
|
+
changes = (0, _utils.clonedeep)(changes);
|
|
84
83
|
runPrehook(prehooksRef.current, 'setState', [changes]) && deps.setState(state, changes, onChange);
|
|
85
84
|
}, []);
|
|
86
85
|
var subscribe = (0, _react.useCallback)(function (listener) {
|
|
@@ -101,7 +100,7 @@ var useStore = function useStore(prehooks, value, storage) {
|
|
|
101
100
|
mounted.current = true;
|
|
102
101
|
return;
|
|
103
102
|
}
|
|
104
|
-
setState((0,
|
|
103
|
+
setState((0, _utils.clonedeep)(value));
|
|
105
104
|
}, [value]);
|
|
106
105
|
(0, _react.useEffect)(function () {
|
|
107
106
|
if (!listeners.size) {
|
package/dist/main/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @param {ObservableContext<T>} context Refers to the PublicObservableContext<T> type of the ObservableContext<T>
|
|
3
|
-
* @param {
|
|
3
|
+
* @param {SelectorMap<T>} [selectorMap] Key:value pairs where `key` => arbitrary key given to a Store.data property holding a state slice and `value` => property path to a state slice used by this component: see examples below. May add a mapping for a certain arbitrary key='state' and value='@@STATE' to indicate a desire to obtain the entire state object and assign to a `state` property of Store.data. A change in any of the referenced properties results in this component render. When using '@@STATE', note that any change within the state object will result in this component render.
|
|
4
4
|
* @returns {(WrappedComponent: C) => MemoExoticComponent<P>}
|
|
5
5
|
* @template {State} T
|
|
6
6
|
* @template {PartialStore<T> & {[x:string]:*}} [P=PartialStore<T>]
|
|
@@ -10,9 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
export function connect<T extends import("../types").State, P extends PartialStore<T> & {
|
|
12
12
|
[x: string]: any;
|
|
13
|
-
} = PartialStore<T>, C extends ComponentType<P> | import("react").ExoticComponent<ComponentType<P>>>(context: ObservableContext<T>, selectorMap?:
|
|
14
|
-
[selectorKey: string]: string | keyof T;
|
|
15
|
-
}): (WrappedComponent: C) => MemoExoticComponent<P>;
|
|
13
|
+
} = PartialStore<T>, C extends ComponentType<P> | import("react").ExoticComponent<ComponentType<P>>>(context: ObservableContext<T>, selectorMap?: SelectorMap<T>): (WrappedComponent: C) => MemoExoticComponent<P>;
|
|
16
14
|
|
|
17
15
|
/**
|
|
18
16
|
* @returns {ObservableContext<T>} Refers to the IObservableContext<T> type of the ObservableContext<T>
|
|
@@ -27,7 +25,7 @@ export class UsageError extends Error {
|
|
|
27
25
|
* Actively monitors the store and triggers component re-render if any of the watched keys in the state objects changes
|
|
28
26
|
*
|
|
29
27
|
* @param {ObservableContext<T>} context Refers to the PublicObservableContext<T> type of the ObservableContext<T>
|
|
30
|
-
* @param {
|
|
28
|
+
* @param {SelectorMap<T>} [selectorMap = {}] Key:value pairs where `key` => arbitrary key given to a Store.data property holding a state slice and `value` => property path to a state slice used by this component: see examples below. May add a mapping for a certain arbitrary key='state' and value='@@STATE' to indicate a desire to obtain the entire state object and assign to a `state` property of Store.data. A change in any of the referenced properties results in this component render. When using '@@STATE', note that any change within the state object will result in this component render.
|
|
31
29
|
* @returns {Store<T>}
|
|
32
30
|
* @template {State} T
|
|
33
31
|
* @see {ObservableContext<T>}
|
|
@@ -48,9 +46,7 @@ export class UsageError extends Error {
|
|
|
48
46
|
* {myX: 'd.e.f[1].x'} or {myX: 'd.e.f.1.x'} => {myX: 7} // same applies to {myY: 'd.e.f[1].y'} = {myY: 8}; {myZ: 'd.e.f[1].z'} = {myZ: 9}
|
|
49
47
|
* {myData: '@@STATE'} => {myData: state}
|
|
50
48
|
*/
|
|
51
|
-
export function useContext<T extends import("../types").State>(context: ObservableContext<T>, selectorMap?:
|
|
52
|
-
[selectorKey: string]: string | keyof T;
|
|
53
|
-
}): Store<T>;
|
|
49
|
+
export function useContext<T extends import("../types").State>(context: ObservableContext<T>, selectorMap?: SelectorMap<T>): Store<T>;
|
|
54
50
|
export type ObservableContext<T extends import("../types").State> = IObservableContext<T> | PublicObservableContext<T>;
|
|
55
51
|
export type PublicObservableContext<T extends import("../types").State> = WithObservableProvider<Context<Store<T>>, T>;
|
|
56
52
|
export type IObservableContext<T extends import("../types").State> = WithObservableProvider<Context<IStore>, T>;
|
|
@@ -66,11 +62,16 @@ export type ObservableProvider<T extends import("../types").State> = FC<{
|
|
|
66
62
|
export type State = import("../types").State;
|
|
67
63
|
export type PartialState<T extends import("../types").State> = import("../types").PartialState<T>;
|
|
68
64
|
export type Prehooks<T extends import("../types").State> = import("../types").Prehooks<T>;
|
|
65
|
+
export type SelectorMap<T extends import("../types").State> = {
|
|
66
|
+
[dataPropKey: string]: string | keyof T;
|
|
67
|
+
} & {
|
|
68
|
+
[dataPropKey: string]: "@@STATE";
|
|
69
|
+
};
|
|
69
70
|
export type StoreInternal<T extends import("../types").State> = import("../types").StoreInternal<T>;
|
|
70
71
|
export type PartialStore<T extends import("../types").State> = {
|
|
71
72
|
data?: import("../types").Data;
|
|
72
73
|
resetState?: (propertyPaths?: string[]) => void;
|
|
73
|
-
setState?: (changes: import("../types").PartialState<T
|
|
74
|
+
setState?: (changes: import("../types").UpdatePayload<import("../types").PartialState<T>>) => void;
|
|
74
75
|
};
|
|
75
76
|
export type Store<T extends import("../types").State> = import("../types").Store<T>;
|
|
76
77
|
export type IStore = import("../types").IStore;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export default setState;
|
|
2
|
+
export type TagKey = import("./tag-functions").TagKey;
|
|
2
3
|
export type HasArrayRoot<K extends KeyTypes = string> = HasRoot<K, Array<any>>;
|
|
3
4
|
export type HasObjectRoot<K extends KeyTypes = string> = K extends number ? {
|
|
4
5
|
[rootKey: number]: {
|
|
@@ -24,9 +25,8 @@ export type HasRoot<K extends KeyTypes = string, T> = K extends number ? {
|
|
|
24
25
|
};
|
|
25
26
|
export type KeyTypes = number | string | symbol;
|
|
26
27
|
export type Listener<T extends import("../../types").State> = import("../../types").Listener<T>;
|
|
28
|
+
export type UpdatePayload<T> = import("../../types").UpdatePayload<T>;
|
|
27
29
|
export type PartialState<T extends import("../../types").State> = import("../../types").PartialState<T>;
|
|
28
30
|
export type State = import("../../types").State;
|
|
29
|
-
export type Stats =
|
|
30
|
-
|
|
31
|
-
};
|
|
32
|
-
declare function setState<T extends import("../../types").State>(state: T, newState: import("../../types").PartialState<T>, onStateChange?: Listener<T>): void;
|
|
31
|
+
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;
|
|
@@ -3,95 +3,122 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
5
|
exports["default"] = void 0;
|
|
6
|
-
var _lodash = _interopRequireDefault(require("lodash.
|
|
7
|
-
var _lodash2 = _interopRequireDefault(require("lodash.
|
|
8
|
-
var
|
|
6
|
+
var _lodash = _interopRequireDefault(require("lodash.isequal"));
|
|
7
|
+
var _lodash2 = _interopRequireDefault(require("lodash.isplainobject"));
|
|
8
|
+
var _utils = require("../../utils");
|
|
9
|
+
var _tagFunctions = _interopRequireWildcard(require("./tag-functions"));
|
|
10
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
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; }
|
|
9
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
10
|
-
function
|
|
11
|
-
function
|
|
12
|
-
function
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
function
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
});
|
|
22
|
-
};
|
|
23
|
-
function setAtomic(state, newState, stateKey, stats) {
|
|
24
|
-
if ((0, _lodash2["default"])(state[stateKey], newState[stateKey])) {
|
|
25
|
-
return;
|
|
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 _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
15
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
|
|
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
|
+
var _default = setState;
|
|
18
|
+
exports["default"] = _default;
|
|
19
|
+
function isIndexBasedObj(obj) {
|
|
20
|
+
for (var k in obj) {
|
|
21
|
+
if (!(k in _tagFunctions["default"] || Number.isInteger(+k))) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
26
24
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
function resolveTags(state, changes, stateKey, stats) {
|
|
28
|
+
var resolvedTags = [];
|
|
29
|
+
if ((0, _tagFunctions.isClosedTag)(changes[stateKey])) {
|
|
30
|
+
changes[stateKey] = _defineProperty({}, changes[stateKey], null);
|
|
31
|
+
}
|
|
32
|
+
if (!(0, _utils.isDataContainer)(changes[stateKey])) {
|
|
33
|
+
return resolvedTags;
|
|
34
|
+
}
|
|
35
|
+
for (var k in changes[stateKey]) {
|
|
36
|
+
if (!(stateKey in changes)) {
|
|
37
|
+
break;
|
|
32
38
|
}
|
|
33
|
-
if (
|
|
34
|
-
|
|
39
|
+
if ((0, _tagFunctions.isClosedTag)(changes[stateKey][k])) {
|
|
40
|
+
changes[stateKey][k] = _defineProperty({}, changes[stateKey][k], null);
|
|
41
|
+
}
|
|
42
|
+
if (k in _tagFunctions["default"]) {
|
|
43
|
+
_tagFunctions["default"][k](state, stateKey, stats, changes);
|
|
44
|
+
resolvedTags.push(k);
|
|
35
45
|
}
|
|
36
46
|
}
|
|
37
|
-
|
|
38
|
-
|
|
47
|
+
return resolvedTags;
|
|
48
|
+
}
|
|
49
|
+
function set(state, changes, stats) {
|
|
50
|
+
for (var k in changes) {
|
|
51
|
+
setAtomic(state, changes, k, stats);
|
|
39
52
|
}
|
|
40
|
-
stats.hasChanges = true;
|
|
41
|
-
state[stateKey] = isArrayNewState || isPlainObjectNewState ? (0, _lodash["default"])(newState[stateKey]) : newState[stateKey];
|
|
42
53
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
var nsLength = newState[rootKey].length;
|
|
54
|
+
function setArray(state, changes, rootKey, stats) {
|
|
55
|
+
var nsLength = changes[rootKey].length;
|
|
46
56
|
if (state[rootKey].length !== nsLength) {
|
|
47
57
|
state[rootKey].length = nsLength;
|
|
48
58
|
stats.hasChanges = true;
|
|
49
59
|
}
|
|
50
60
|
for (var i = 0; i < nsLength; i++) {
|
|
51
|
-
setAtomic(state[rootKey],
|
|
61
|
+
setAtomic(state[rootKey], changes[rootKey], i, stats);
|
|
52
62
|
}
|
|
53
63
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
var
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
function setArrayIndex(state, changes, rootKey, stats) {
|
|
65
|
+
var incomingIndexes = [];
|
|
66
|
+
for (var k in changes[rootKey]) {
|
|
67
|
+
var index = +k;
|
|
68
|
+
if (index < 0) {
|
|
69
|
+
index = state[rootKey].length + index;
|
|
70
|
+
changes[rootKey][index] = changes[rootKey][k];
|
|
71
|
+
delete changes[rootKey][k];
|
|
72
|
+
}
|
|
73
|
+
index >= 0 && incomingIndexes.push(index);
|
|
74
|
+
}
|
|
75
|
+
var maxIncomingIndex = Math.max.apply(Math, incomingIndexes);
|
|
60
76
|
if (maxIncomingIndex >= state[rootKey].length) {
|
|
61
77
|
state[rootKey].length = maxIncomingIndex + 1;
|
|
62
78
|
stats.hasChanges = true;
|
|
63
79
|
}
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
68
|
-
var i = _step.value;
|
|
69
|
-
setAtomic(state[rootKey], newState[rootKey], i, stats);
|
|
70
|
-
}
|
|
71
|
-
} catch (err) {
|
|
72
|
-
_iterator.e(err);
|
|
73
|
-
} finally {
|
|
74
|
-
_iterator.f();
|
|
80
|
+
for (var _i = 0, _incomingIndexes = incomingIndexes; _i < _incomingIndexes.length; _i++) {
|
|
81
|
+
var i = _incomingIndexes[_i];
|
|
82
|
+
setAtomic(state[rootKey], changes[rootKey], i, stats);
|
|
75
83
|
}
|
|
76
84
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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);
|
|
85
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
|
+
function setPlainObject(state, changes, rootKey, stats) {
|
|
111
|
+
set(state[rootKey], changes[rootKey], stats);
|
|
86
112
|
}
|
|
87
|
-
|
|
88
|
-
function setState(state, newState, onStateChange) {
|
|
113
|
+
function setState(state, changes, onStateChange) {
|
|
89
114
|
var stats = {
|
|
90
115
|
hasChanges: false
|
|
91
116
|
};
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
117
|
+
var changeRequest = {
|
|
118
|
+
state: (0, _utils.clonedeep)(changes)
|
|
119
|
+
};
|
|
120
|
+
set({
|
|
121
|
+
state: state
|
|
122
|
+
}, changeRequest, stats);
|
|
123
|
+
stats.hasChanges && (onStateChange === null || onStateChange === void 0 ? void 0 : onStateChange(changes));
|
|
124
|
+
}
|