@webkrafters/react-observable-context 4.1.0-rc.2 → 4.1.0-rc.3

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.
Files changed (2) hide show
  1. package/README.md +113 -77
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -41,6 +41,43 @@ npm install --save @webkrafters/react-observable-context
41
41
 
42
42
  May also see <b><a href="#changes">What's Changed?</a></b> section below.
43
43
 
44
+ <h1 id="toc">Table of Contents</h1>
45
+
46
+ <a href="#intro">Intro</a><br />
47
+ <a href="#concepts">Concepts</a><br />
48
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#client">Client</a><br />
49
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#prehooks">Prehooks</a><br />
50
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#property-path">Property Path</a><br />
51
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#fullstate-selectorkey">@@STATE</a><br />
52
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#provider">Provider</a><br />
53
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#selector-map">Selector Map</a><br />
54
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#storage">Storage</a><br />
55
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#store">Store</a><br />
56
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#store-resetstate">Reset State</a><br />
57
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#store-setstate">Set State</a><br />
58
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#indexing">Array Indexing</a><br />
59
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#setstate-tags">Using Tag Commands</a><br />
60
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#clear-tag-usage">@@CLEAR Usage Example</a><br />
61
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#delete-tag-usage">@@DELETE Usage Example</a><br />
62
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#move-tag-usage">@@MOVE Usage Example</a><br />
63
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#push-tag-usage">@@PUSH Usage Example</a><br />
64
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#replace-tag-usage">@@REPLACE Usage Example</a><br />
65
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#set-tag-usage">@@SET Usage Example</a><br />
66
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#splice-tag-usage">@@SPLICE Usage Example</a><br />
67
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#set-state-with-tags">Combination Usage Example</a><br />
68
+ <a href="#api">API</a><br />
69
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#connect">Connect HoC</a><br />
70
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#create-context">CreateContext Function</a><br />
71
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#usage-error">UsageError Exception</a><br />
72
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#usecontext">UseContext Hook</a><br />
73
+ <a href="#usage">Usage</a><br />
74
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#create-context-usage">Creating context</a><br />
75
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#provider-usage">Setting up the Provider</a><br />
76
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#connect-usage">Consuming context (hoc method)</a><br />
77
+ &nbsp;&nbsp;&nbsp;&nbsp;<a href="#usecontext-usage">Consuming context (hook with memo method)</a><br />
78
+ <a href="#changes">What's Changed?</a><br />
79
+ <a href="#license">License</a><br />
80
+
44
81
  # Intro
45
82
 
46
83
  A context bearing an observable consumer [store](#store). State changes within the store's internal state are only broadcasted to components subscribed to the store (the [clients](#client)). In this way, the `React-Observable-Context` prevents repeated automatic re-renderings of entire component trees resulting from ***context*** state changes.
@@ -215,7 +252,7 @@ To overwrite current state slices with new values, <b>7</b> tag commands have be
215
252
  </ol>
216
253
  <b>Examples:</b><br /><br />
217
254
 
218
- <i><b>@@CLEAR:</b> (takes no arguments)</i>
255
+ <i id="clear-tag-usage"><b>@@CLEAR:</b> (takes no arguments)</i>
219
256
 
220
257
  ```jsx
221
258
  const state = {
@@ -242,7 +279,7 @@ store.setState({ a: { b: [ '@@CLEAR', state.a.b[1] ] } }) // or store.setState({
242
279
  store.setState({ a: { b: { 0: '@@CLEAR' } } }) // or store.setState({ a: { b: { 0: { '@@CLEAR': <anything> } } } })
243
280
  ```
244
281
 
245
- <i><b>@@DELETE:</b> (takes an array argument listing property keys to delete)</i>
282
+ <i id="delete-tag-usage"><b>@@DELETE:</b> (takes an array argument listing property keys to delete)</i>
246
283
 
247
284
  ```jsx
248
285
  const state = {
@@ -264,7 +301,7 @@ store.setState({ a: { b: [ state.a.b[ 0 ], { '@@DELETE': [ 'x', 'z' ] } ] } })
264
301
  store.setState({ a: { b: { 1: { '@@DELETE': [ 'x', 'z' ] } } } })
265
302
  ```
266
303
 
267
- <i><b>@@MOVE:</b> (takes an array argument listing: -/+fromIndex, -/+toIndex and optional +numItems?. numItems = 1 by default)</i>
304
+ <i id="move-tag-usage"><b>@@MOVE:</b> (takes an array argument listing: -/+fromIndex, -/+toIndex and optional +numItems?. numItems = 1 by default)</i>
268
305
 
269
306
  ```jsx
270
307
  const state = {
@@ -282,7 +319,7 @@ store.setState({ a: { b: { '@@MOVE': [ 0, 1 ] } } }) // or store.setState({ a: {
282
319
  store.setState({ a: { q: { '@@MOVE': [ 4, 1, 4 ] } } }) // or store.setState({ a: { q: { '@@MOVE': [ -5, -8, 4 ] } } })
283
320
  ```
284
321
 
285
- <i><b>@@PUSH:</b> (takes an array argument listing new values to append)</i>
322
+ <i id="push-tag-usage"><b>@@PUSH:</b> (takes an array argument listing new values to append)</i>
286
323
 
287
324
  ```jsx
288
325
  const state = {
@@ -296,7 +333,7 @@ store.setState({ a: { '@@PUSH': [{ n: 5 }] } }) // assigning a '@@PUSH' command
296
333
  store.setState({ a: { b: { '@@PUSH': [{ x: 27, y: 28, z: 29 }, { x: 37, y: 38, z: 39 }] } } })
297
334
  ```
298
335
 
299
- <i><b>@@REPLACE:</b> (takes an argument holding the replacment value)</i>
336
+ <i id="replace-tag-usage"><b>@@REPLACE:</b> (takes an argument holding the replacment value)</i>
300
337
 
301
338
  ```jsx
302
339
  const state = {
@@ -315,7 +352,7 @@ store.setState({ a: { b: [ state.a.b[ 0 ], { '@@REPLACE': { x: 97, y: 98, z: 99
315
352
  store.setState({ a: { b: { 1: { '@@REPLACE': { x: 97, y: 98, z: 99 } } } } })
316
353
  ```
317
354
 
318
- <i><b>@@SET:</b> (takes an argument holding either the replacment value or a compute function returning the replacement value)</i>
355
+ <i id="set-tag-usage"><b>@@SET:</b> (takes an argument holding either the replacment value or a compute function returning the replacement value)</i>
319
356
 
320
357
  ```jsx
321
358
  /*
@@ -342,7 +379,7 @@ store.setState({ a: { b: [ state.a.b[ 0 ], { '@@SET': currentValue => ({ ...curr
342
379
  store.setState({ a: { b: { 1: { '@@SET': currentValue => ({ ...currentValue, x: 97, y: 98, z: 99 }) } } } })
343
380
  ```
344
381
 
345
- <i><b>@@SPLICE:</b> (takes an array argument listing: -/+fromIndex, +deleteCount and optional ...newItems? newItems = ...[] by default)</i>
382
+ <i id="splice-tag-usage"><b>@@SPLICE:</b> (takes an array argument listing: -/+fromIndex, +deleteCount and optional ...newItems? newItems = ...[] by default)</i>
346
383
 
347
384
  ```jsx
348
385
  const state = {
@@ -360,7 +397,7 @@ store.setState({ a: { b: { '@@SPLICE': [ 0, 1 ] } } }) // or store.setState({ a:
360
397
  store.setState({ a: { q: { '@@SPLICE': [ 4, 4, 33, 88 ] } } }) // or store.setState({ a: { q: { '@@SPLICE': [ -5, 4, 33, 88 ] } } })
361
398
  ```
362
399
 
363
- <h3><b><i>Combination Usage:</i></b></h3>
400
+ <h3 id="set-state-with-tags"><b><i>Combination Usage:</i></b></h3>
364
401
 
365
402
  These tags may be used in combination with the default usage where all top-level tag command results in property are sequentially merged into state followed by the merging of the rest of the property changes.
366
403
 
@@ -397,7 +434,7 @@ store.setState({
397
434
 
398
435
  # API
399
436
 
400
- The React-Observable-Context module contains **4** exports namely:
437
+ The React-Observable-Context module exports named constants and the following **4** main entities namely:
401
438
  <ol>
402
439
  <li style="padding-bottom: 5px">
403
440
  <p style="margin: 0 0 5px 5px">
@@ -415,12 +452,12 @@ The React-Observable-Context module contains **4** exports namely:
415
452
  </li>
416
453
  <li style="padding-bottom: 5px">
417
454
  <p style="margin: 0 0 5px 5px">
418
- <b>createContext</b> is a zero-parameter function returning a <code>React-Observable-Context</code> object. This object is the store-bearing context. To access the context's <a href="#store">store</a>, pass the context as a <code>context</code> parameter to either the <a href="#connect">connect</a> function or the <a href="#usecontext">useContext</a> hook.
455
+ <b id="create-context">createContext</b> is a zero-parameter function returning a <code>React-Observable-Context</code> object. This object is the store-bearing context. To access the context's <a href="#store">store</a>, pass the context as a <code>context</code> parameter to either the <a href="#connect">connect</a> function or the <a href="#usecontext">useContext</a> hook.
419
456
  </p>
420
457
  </li>
421
458
  <li style="padding-bottom: 5px">
422
459
  <p style="margin: 0 0 5px 5px">
423
- <b>UsageError</b> class is the Error type reported for attempts to access this context's store outside of its Provider component tree.
460
+ <b id="usage-error">UsageError</b> class is the Error type reported for attempts to access this context's store outside of its Provider component tree.
424
461
  </p>
425
462
  </li>
426
463
  <li>
@@ -440,14 +477,74 @@ The React-Observable-Context module contains **4** exports namely:
440
477
 
441
478
  # Usage
442
479
 
443
- <i><u><b>context.js</b></u></i>
480
+ <i id="create-context-usage"><u><b>context.js</b></u></i>
444
481
 
445
482
  ```jsx
446
483
  import { createContext } from '@webkrafters/react-observable-context';
447
484
  export default createContext();
448
485
  ```
449
486
 
450
- <i><u><b>ui.js</b></u> (connect method)</i>
487
+ <i id="provider-usage"><b><u>provider.js</u></b></i>
488
+
489
+ ```jsx
490
+ import React, { useEffect, useState } from 'react';
491
+ import ObservableContext from './context';
492
+ import Ui from './ui';
493
+
494
+ const DEFAULT_C = 36;
495
+
496
+ const updateHooks = {
497
+ resetState: ( ...args ) => {
498
+ console.log( 'resetting state with >>>> ', JSON.stringify( args ) );
499
+ return true;
500
+ },
501
+ setState: ( ...args ) => {
502
+ console.log( 'merging following into state >>>> ', JSON.stringify( args ) );
503
+ return true;
504
+ }
505
+ };
506
+
507
+ const storageStub = {
508
+ clone( data ) { return your_clone_function( data ) },
509
+ data: null,
510
+ getItem( key ) { return this.data },
511
+ removeItem( key ) { this.data = null },
512
+ setItem( key, data ) { this.data = data }
513
+ };
514
+
515
+ const Provider = ({ c = DEFAULT_C }) => {
516
+
517
+ const storeRef = useRef();
518
+
519
+ const [ state, setState ] = useState(() => ({
520
+ a: { b: { c, x: { y: { z: [ 2022 ] } } } }
521
+ }));
522
+
523
+ useEffect(() => {
524
+ // similar to `store.setState`, use the following to update
525
+ // only the changed slice of the context internal state.
526
+ setState({ a: { b: { c } } });
527
+ // Do not do the following: it will override the context internal state.
528
+ // setState({ ...state, a: { ...state.a, b: { ...state.a.b, c } } });
529
+ }, [ c ]);
530
+
531
+ return (
532
+ <ObservableContext.Provider
533
+ prehooks={ updateHooks }
534
+ ref={ storeRef }
535
+ storage={ storageStub }
536
+ value={ state }
537
+ >
538
+ <Ui />
539
+ </ObservableContext.Provider>
540
+ );
541
+ };
542
+ Provider.displayName = 'Provider';
543
+
544
+ export default Provider;
545
+ ```
546
+
547
+ <i id="connect-usage"><u><b>ui.js</b></u> (connect method)</i>
451
548
 
452
549
  ```jsx
453
550
  import React, { useCallback, useEffect } from 'react';
@@ -479,7 +576,7 @@ const Ui = () => (
479
576
  export default Ui;
480
577
  ```
481
578
 
482
- <i><u><b>ui.js</b></u> (useContext with memo method)</i>
579
+ <i id="usecontext-usage"><u><b>ui.js</b></u> (useContext with memo method)</i>
483
580
 
484
581
  ```jsx
485
582
  import React, { memo, useCallback, useEffect } from 'react';
@@ -514,66 +611,6 @@ const Ui = () => (
514
611
  export default Ui;
515
612
  ```
516
613
 
517
- <i id="provider-usage"><b><u>provider.js</u></b></i>
518
-
519
- ```jsx
520
- import React, { useEffect, useState } from 'react';
521
- import ObservableContext from './context';
522
- import Ui from './ui';
523
-
524
- const DEFAULT_C = 36;
525
-
526
- const updateHooks = {
527
- resetState: ( ...args ) => {
528
- console.log( 'resetting state with >>>> ', JSON.stringify( args ) );
529
- return true;
530
- },
531
- setState: ( ...args ) => {
532
- console.log( 'merging following into state >>>> ', JSON.stringify( args ) );
533
- return true;
534
- }
535
- };
536
-
537
- const storageStub = {
538
- clone( data ) { return your_clone_function( data ) },
539
- data: null,
540
- getItem( key ) { return this.data },
541
- removeItem( key ) { this.data = null },
542
- setItem( key, data ) { this.data = data }
543
- };
544
-
545
- const Provider = ({ c = DEFAULT_C }) => {
546
-
547
- const storeRef = useRef();
548
-
549
- const [ state, setState ] = useState(() => ({
550
- a: { b: { c, x: { y: { z: [ 2022 ] } } } }
551
- }));
552
-
553
- useEffect(() => {
554
- // similar to `store.setState`, use the following to update
555
- // only the changed slice of the context internal state.
556
- setState({ a: { b: { c } } });
557
- // Do not do the following: it will override the context internal state.
558
- // setState({ ...state, a: { ...state.a, b: { ...state.a.b, c } } });
559
- }, [ c ]);
560
-
561
- return (
562
- <ObservableContext.Provider
563
- prehooks={ updateHooks }
564
- ref={ storeRef }
565
- storage={ storageStub }
566
- value={ state }
567
- >
568
- <Ui />
569
- </ObservableContext.Provider>
570
- );
571
- };
572
- Provider.displayName = 'Provider';
573
-
574
- export default Provider;
575
- ```
576
-
577
614
  <i><b><u>index.js</u></b></i>
578
615
 
579
616
  ```jsx
@@ -590,8 +627,8 @@ ReactDOM.render( <Provider />, document.getElementById( 'root' ) );
590
627
  <thead><tr><th>v4.1.0</th></tr></thead>
591
628
  <tbody>
592
629
  <tr><td><b>1.</b></td><td>Added new setState <a href="#setstate-tags">tags</a> to facilitate state update operations.</td></tr>
593
- <tr><td><b>2.</b></td><td>Exposing the store via its Context Provider `ref` attribute.</td></tr>
594
- <tr><td><b>3.</b></td><td>Exporting crucial constants such as @@STATE and setState <a href="#setstate-tags">tags</a> such as @@CLEAR, @@MOVE etc.</td></tr>
630
+ <tr><td><b>2.</b></td><td>Exposing the store via its Context Provider <code>ref</code> attribute.</td></tr>
631
+ <tr><td><b>3.</b></td><td>Exporting crucial constants such as <b>@@STATE</b> and setState <a href="#setstate-tags">tags</a> such as <b>@@CLEAR</b>, <b>@@MOVE</b> etc.</td></tr>
595
632
  </tbody>
596
633
  <thead><tr><th>v4.0.0</th></tr></thead>
597
634
  <tbody>
@@ -605,7 +642,6 @@ ReactDOM.render( <Provider />, document.getElementById( 'root' ) );
605
642
  </tbody>
606
643
  </table>
607
644
 
608
-
609
645
  # License
610
646
 
611
647
  MIT
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.1.0-rc.2"
136
+ "version": "4.1.0-rc.3"
137
137
  }