@webqit/observer 2.1.10 → 2.1.11
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 +36 -121
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<!-- /BADGES -->
|
|
8
8
|
|
|
9
|
-
**[Motivation](#motivation) • [Overview](#an-overview) • [
|
|
9
|
+
**[Motivation](#motivation) • [Overview](#an-overview) • [Documentation](#documentation) • [Polyfill](#the-polyfill) • [Getting Involved](#getting-involved) • [License](#license)**
|
|
10
10
|
|
|
11
11
|
Observe and intercept operations on arbitrary JavaScript objects and arrays using a utility-first, general-purpose reactivity API! This API re-explores the unique design of the [`Object.observe()`](https://web.dev/es7-observe/) API and takes a stab at what could be **a unifying API** over *related but disparate* things like `Object.observe()`, [Reflect](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect) APIs, and the "traps" API (proxy traps)!
|
|
12
12
|
|
|
@@ -14,7 +14,7 @@ Observer API is an upcoming proposal!
|
|
|
14
14
|
|
|
15
15
|
## Motivation
|
|
16
16
|
|
|
17
|
-
Tracking mutations on JavaScript objects has historically relied on "object wrapping" techniques with [ES6 Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy), and on "property mangling" techniques with [getters and setters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty). Besides the *object identity* problem
|
|
17
|
+
Tracking mutations on JavaScript objects has historically relied on "object wrapping" techniques with [ES6 Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy), and on "property mangling" techniques with [getters and setters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty). Besides how the first poses an *object identity* problem and the second, an *interoperability* problem, there is also much inflexibility in the programming model they enable!
|
|
18
18
|
|
|
19
19
|
This is discussed extensively in [the introductory blog post](https://dev.to/oxharris/reinvestigating-reactivity-22e0-temp-slug-5973064?preview=8afd0f8b156bf0b0b1c08058837fe4986054e52a7450f0a28adbaf07dcb7f5659b724166f553fb98ceab3d080748e86b244684f515d579bcd0f48cbb#introducing-the-observer-api)<sup>draft</sup>
|
|
20
20
|
|
|
@@ -24,22 +24,6 @@ We find a design precedent to object observability in the [`Object.observe()`](h
|
|
|
24
24
|
|
|
25
25
|
The Observer API is a set of utility functions.
|
|
26
26
|
|
|
27
|
-
<details>
|
|
28
|
-
<summary><b>Show Outline</b></summary>
|
|
29
|
-
|
|
30
|
-
+ [Method: `Observer.observe()`](#method-observerobserve)
|
|
31
|
-
+ [Usage](#usage)
|
|
32
|
-
+ [Concept: *Mutation APIs*](#concept-mutation-apis)
|
|
33
|
-
+ [Concept: *Paths*](#concept-paths)
|
|
34
|
-
+ [Concept: *Batch Mutations*](#concept-batch-mutations)
|
|
35
|
-
+ [Concept: *Custom Details*](#concept-custom-details)
|
|
36
|
-
+ [Concept: *Diffing*](#concept-diffing)
|
|
37
|
-
+ [Method: `Observer.intercept()`](#method-observerintercept)
|
|
38
|
-
+ [Usage](#usage-1)
|
|
39
|
-
+ [API Reference](#api-reference)
|
|
40
|
-
|
|
41
|
-
</details>
|
|
42
|
-
|
|
43
27
|
> **Note**
|
|
44
28
|
> <br>This is documentation for `Observer@2.x`. (Looking for [`Observer@1.x`](https://github.com/webqit/observer/tree/v1.7.6)?)
|
|
45
29
|
|
|
@@ -70,21 +54,21 @@ Observe arbitrary objects and arrays:
|
|
|
70
54
|
// An object
|
|
71
55
|
const obj = {};
|
|
72
56
|
// Mtation observer on an object
|
|
73
|
-
const abortController = Observer.observe( obj,
|
|
57
|
+
const abortController = Observer.observe( obj, inspect );
|
|
74
58
|
```
|
|
75
59
|
|
|
76
60
|
```js
|
|
77
61
|
// An array
|
|
78
62
|
const arr = [];
|
|
79
63
|
// Mtation observer on an array
|
|
80
|
-
const abortController = Observer.observe( arr,
|
|
64
|
+
const abortController = Observer.observe( arr, inspect );
|
|
81
65
|
```
|
|
82
66
|
|
|
83
|
-
└ *Changes are delivered [**synchronously**](https://
|
|
67
|
+
└ *Changes are delivered [**synchronously**](https://github.com/webqit/observer/wiki/#timing-and-batching) - as they happen.*
|
|
84
68
|
|
|
85
69
|
```js
|
|
86
70
|
// The change handler
|
|
87
|
-
function
|
|
71
|
+
function inspect( mutations ) {
|
|
88
72
|
mutations.forEach( mutation => {
|
|
89
73
|
console.log( mutation.type, mutation.key, mutation.value, mutation.oldValue );
|
|
90
74
|
} );
|
|
@@ -103,7 +87,7 @@ abortController.abort();
|
|
|
103
87
|
```js
|
|
104
88
|
// Providing an AbortSignal
|
|
105
89
|
const abortController = new AbortController;
|
|
106
|
-
Observer.observe( obj,
|
|
90
|
+
Observer.observe( obj, inspect, { signal: abortController.signal } );
|
|
107
91
|
```
|
|
108
92
|
|
|
109
93
|
```js
|
|
@@ -118,12 +102,18 @@ abortController.abort();
|
|
|
118
102
|
const abortController = Observer.observe( obj, ( mutations, flags ) => {
|
|
119
103
|
|
|
120
104
|
// Child
|
|
121
|
-
Observer.observe( obj,
|
|
105
|
+
Observer.observe( obj, inspect, { signal: flags.signal } ); // <<<---- AbortSignal-cascading
|
|
106
|
+
|
|
107
|
+
Observer.observe( obj, inspect, { signal: flags.signal } ); // <<<---- AbortSignal-cascading
|
|
122
108
|
|
|
123
109
|
} );
|
|
124
110
|
```
|
|
125
111
|
|
|
126
|
-
|
|
112
|
+
> **Note**
|
|
113
|
+
> <br>This is documentation for `Observer@2.x`. (Looking for [`Observer@1.x`](https://github.com/webqit/observer/tree/v1.7.6)?)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
└ *"Child" observers get automatically aborted at parent's "next turn", and at parent's own abortion!*
|
|
127
117
|
|
|
128
118
|
#### Concept: *Mutation APIs*
|
|
129
119
|
|
|
@@ -267,7 +257,7 @@ obj = Observer.unproxy( $obj );
|
|
|
267
257
|
|
|
268
258
|
#### Concept: *Paths*
|
|
269
259
|
|
|
270
|
-
Observe "
|
|
260
|
+
Observe "a property" at a path in a given tree:
|
|
271
261
|
|
|
272
262
|
```js
|
|
273
263
|
const obj = {
|
|
@@ -425,31 +415,6 @@ Observer.observe( obj, 'prop1', mutation => {
|
|
|
425
415
|
} );
|
|
426
416
|
```
|
|
427
417
|
|
|
428
|
-
#### Concept: *Diffing*
|
|
429
|
-
|
|
430
|
-
Receive notifications only for mutations that actually change property state, and ignore those that don't.
|
|
431
|
-
|
|
432
|
-
```js
|
|
433
|
-
// Responding to state changes only
|
|
434
|
-
Observer.observe( obj, handleChanges, { diff: true } );
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
```js
|
|
438
|
-
// Recieved
|
|
439
|
-
Observer.set( obj, 'prop0', 'value' );
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
```js
|
|
443
|
-
// Ignored
|
|
444
|
-
Observer.set( obj, 'prop0', 'value' );
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
<!--
|
|
448
|
-
### Concept: *Live*
|
|
449
|
-
descripted
|
|
450
|
-
namespace
|
|
451
|
-
-->
|
|
452
|
-
|
|
453
418
|
### Method: `Observer.intercept()`
|
|
454
419
|
|
|
455
420
|
Intercept operations on any object or array before they happen!
|
|
@@ -516,91 +481,41 @@ Observer.intercept( obj, {
|
|
|
516
481
|
} );
|
|
517
482
|
```
|
|
518
483
|
|
|
519
|
-
##
|
|
484
|
+
## Documentation
|
|
520
485
|
|
|
521
|
-
|
|
486
|
+
Visit the [docs](https://github.com/webqit/observer/wiki) for all what's possible - including [Reflect APIs](https://github.com/webqit/observer/wiki#featuring-reflect-apis-extended), [Timing and Batching](https://github.com/webqit/observer/wiki#timing-and-batching), [API Reference](https://github.com/webqit/observer/wiki#putting-it-all-together), etc.
|
|
522
487
|
|
|
523
|
-
|
|
524
|
-
npm i @webqit/observer
|
|
525
|
-
```
|
|
488
|
+
## The Polyfill
|
|
526
489
|
|
|
527
|
-
|
|
528
|
-
// Import
|
|
529
|
-
import Observer from '@webqit/observer';;
|
|
530
|
-
```
|
|
490
|
+
The Observer API is being developed as something to be used today - via a polyfill. The polyfill features all of what's documented - with limitations in the area of making mutations: you can only make mutations using the [Mutation APIs](#concept-mutation-apis).
|
|
531
491
|
|
|
532
|
-
|
|
492
|
+
<details><summary>Load from a CDN</summary>
|
|
533
493
|
|
|
534
494
|
```html
|
|
535
495
|
<script src="https://unpkg.com/@webqit/observer/dist/main.js"></script>
|
|
536
496
|
```
|
|
537
497
|
|
|
538
|
-
> 4.4 kB min + gz | 13.9 KB min [↗](https://bundlephobia.com/package/@webqit/observer
|
|
498
|
+
> `4.4` kB min + gz | `13.9` KB min [↗](https://bundlephobia.com/package/@webqit/observer)
|
|
539
499
|
|
|
540
500
|
```js
|
|
541
501
|
// Obtain the APIs
|
|
542
502
|
const Observer = window.webqit.Observer;
|
|
543
503
|
```
|
|
544
504
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
| `getOwnPropertyDescriptor()` | ✓ | Obtains property descriptor [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor) | `getOwnPropertyDescriptor() {}` |
|
|
560
|
-
| `getPrototypeOf()` | ✓ | Obtains object prototype [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf) | `getPrototypeOf() {}` |
|
|
561
|
-
| `has()` | ✓ | Checks property existence [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/has) | `has() {}` |
|
|
562
|
-
| `intercept()` | `×` | Binds a "traps" object [↗](https://github.com/webqit/observer#method-observerintercept) | `-` |
|
|
563
|
-
| `isExtensible()` | ✓ | Checks object extensibility [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible) | `isExtensible() {}` |
|
|
564
|
-
| `observe()` | `×` | Binds a mutation observer [↗](https://github.com/webqit/observer#method-observerobserve) | `-` |
|
|
565
|
-
| `ownKeys()` | ✓ | Obtains object keys [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys) | `ownKeys() {}` |
|
|
566
|
-
| `path()` | `×` | Evaluates a path [↗](#) | `-` |
|
|
567
|
-
| `preventExtensions()` | ✓ | Prevents object extensibility [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions) | `preventExtensions() {}` |
|
|
568
|
-
| `set()` | ✓ | Sets a property [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/set) | `set() {}` |
|
|
569
|
-
| `setPrototypeOf()` | ✓ | Sets object prototype [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf) | `setPrototypeOf() {}` |
|
|
570
|
-
| . | . | . | . |
|
|
571
|
-
| `accessorize()` | `×` | Applies pre-intercepted getters/setters to properties [↗](https://github.com/webqit/observer#:~:text=enable%20reactivity%20on%20specific%20properties%20with%20literal%20object%20accessors%20-%20using%20the%20observer.accessorize()%20method) | `-` |
|
|
572
|
-
| `proxy()` | `×` | Creates a pre-intercepted proxy object [↗](https://github.com/webqit/observer#:~:text=enable%20reactivity%20on%20arbitray%20properties%20with%20proxies%20-%20using%20the%20observer.proxy()%20method) | `-` |
|
|
573
|
-
|
|
574
|
-
-->
|
|
575
|
-
|
|
576
|
-
| Observer API | Reflect API | Trap |
|
|
577
|
-
| -------------- | ------------ | ----------- |
|
|
578
|
-
| `apply()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/apply) | ✓ | `apply() {}` |
|
|
579
|
-
| `batch()` [↗](https://github.com/webqit/observer#concept-batch-mutations) | `×` | `-` |
|
|
580
|
-
| `construct()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/construct) | ✓ | `construct() {}` |
|
|
581
|
-
| `defineProperties()` [↗]() | `×` | `defineProperty() {}` |
|
|
582
|
-
| `defineProperty()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty) | ✓ | `defineProperty() {}` |
|
|
583
|
-
| `deleteProperties()` [↗]() | `×` | `deleteProperty() {}` |
|
|
584
|
-
| `deleteProperty()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/deleteProperty) | ✓ | `deleteProperty() {}` |
|
|
585
|
-
| `get()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/get) | ✓ | `get() {}` |
|
|
586
|
-
| `getOwnPropertyDescriptor()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor) | ✓ | `getOwnPropertyDescriptor() {}` |
|
|
587
|
-
| `getPrototypeOf()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf) | ✓ | `getPrototypeOf() {}` |
|
|
588
|
-
| `has()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/has) | ✓ | `has() {}` |
|
|
589
|
-
| `intercept()`[↗](https://github.com/webqit/observer#method-observerintercept) | `×` | `-` |
|
|
590
|
-
| `isExtensible()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible) | ✓ | `isExtensible() {}` |
|
|
591
|
-
| `observe()` [↗](https://github.com/webqit/observer#method-observerobserve) | `×` | `-` |
|
|
592
|
-
| `ownKeys()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys) | ✓ | `ownKeys() {}` |
|
|
593
|
-
| `path()` [↗](https://github.com/webqit/observer#concept-paths) | `×` | `-` |
|
|
594
|
-
| `preventExtensions()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions) | ✓ | `preventExtensions() {}` |
|
|
595
|
-
| `set()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/set) | ✓ | `set() {}` |
|
|
596
|
-
| `setPrototypeOf()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf) | ✓ | `setPrototypeOf() {}` |
|
|
597
|
-
| . | . | . | . |
|
|
598
|
-
| `accessorize()` [↗](https://github.com/webqit/observer#:~:text=enable%20reactivity%20on%20specific%20properties%20with%20literal%20object%20accessors%20-%20using%20the%20observer.accessorize()%20method) | `×` | `-` |
|
|
599
|
-
| `proxy()` [↗](https://github.com/webqit/observer#:~:text=enable%20reactivity%20on%20arbitray%20properties%20with%20proxies%20-%20using%20the%20observer.proxy()%20method) | `×` | `-` |
|
|
600
|
-
|
|
601
|
-
## Design Discussion
|
|
602
|
-
|
|
603
|
-
[See more in the introductory blog post](https://dev.to/oxharris/reinvestigating-reactivity-22e0-temp-slug-5973064?preview=8afd0f8b156bf0b0b1c08058837fe4986054e52a7450f0a28adbaf07dcb7f5659b724166f553fb98ceab3d080748e86b244684f515d579bcd0f48cbb#introducing-the-observer-api)<sup>draft</sup>
|
|
505
|
+
</details>
|
|
506
|
+
|
|
507
|
+
<details><summary>Install from NPM</summary>
|
|
508
|
+
|
|
509
|
+
```bash
|
|
510
|
+
npm i @webqit/observer
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
```js
|
|
514
|
+
// Import
|
|
515
|
+
import Observer from '@webqit/observer';;
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
</details>
|
|
604
519
|
|
|
605
520
|
## Getting Involved
|
|
606
521
|
|