@webqit/observer 2.1.9 → 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 -116
- 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,17 +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
|
-
+ [Method: `Observer.observe()`](#method-observerobserve)
|
|
28
|
-
+ [Usage](#usage)
|
|
29
|
-
+ [Concept: *Mutation APIs*](#concept-mutation-apis)
|
|
30
|
-
+ [Concept: *Paths*](#concept-paths)
|
|
31
|
-
+ [Concept: *Batch Mutations*](#concept-batch-mutations)
|
|
32
|
-
+ [Concept: *Custom Details*](#concept-custom-details)
|
|
33
|
-
+ [Concept: *Diffing*](#concept-diffing)
|
|
34
|
-
+ [Method: `Observer.intercept()`](#method-observerintercept)
|
|
35
|
-
+ [Usage](#usage-1)
|
|
36
|
-
+ [API Reference](#api-reference)
|
|
37
|
-
|
|
38
27
|
> **Note**
|
|
39
28
|
> <br>This is documentation for `Observer@2.x`. (Looking for [`Observer@1.x`](https://github.com/webqit/observer/tree/v1.7.6)?)
|
|
40
29
|
|
|
@@ -65,21 +54,21 @@ Observe arbitrary objects and arrays:
|
|
|
65
54
|
// An object
|
|
66
55
|
const obj = {};
|
|
67
56
|
// Mtation observer on an object
|
|
68
|
-
const abortController = Observer.observe( obj,
|
|
57
|
+
const abortController = Observer.observe( obj, inspect );
|
|
69
58
|
```
|
|
70
59
|
|
|
71
60
|
```js
|
|
72
61
|
// An array
|
|
73
62
|
const arr = [];
|
|
74
63
|
// Mtation observer on an array
|
|
75
|
-
const abortController = Observer.observe( arr,
|
|
64
|
+
const abortController = Observer.observe( arr, inspect );
|
|
76
65
|
```
|
|
77
66
|
|
|
78
|
-
└ *Changes are delivered [**synchronously**](https://
|
|
67
|
+
└ *Changes are delivered [**synchronously**](https://github.com/webqit/observer/wiki/#timing-and-batching) - as they happen.*
|
|
79
68
|
|
|
80
69
|
```js
|
|
81
70
|
// The change handler
|
|
82
|
-
function
|
|
71
|
+
function inspect( mutations ) {
|
|
83
72
|
mutations.forEach( mutation => {
|
|
84
73
|
console.log( mutation.type, mutation.key, mutation.value, mutation.oldValue );
|
|
85
74
|
} );
|
|
@@ -98,7 +87,7 @@ abortController.abort();
|
|
|
98
87
|
```js
|
|
99
88
|
// Providing an AbortSignal
|
|
100
89
|
const abortController = new AbortController;
|
|
101
|
-
Observer.observe( obj,
|
|
90
|
+
Observer.observe( obj, inspect, { signal: abortController.signal } );
|
|
102
91
|
```
|
|
103
92
|
|
|
104
93
|
```js
|
|
@@ -113,12 +102,18 @@ abortController.abort();
|
|
|
113
102
|
const abortController = Observer.observe( obj, ( mutations, flags ) => {
|
|
114
103
|
|
|
115
104
|
// Child
|
|
116
|
-
Observer.observe( obj,
|
|
105
|
+
Observer.observe( obj, inspect, { signal: flags.signal } ); // <<<---- AbortSignal-cascading
|
|
106
|
+
|
|
107
|
+
Observer.observe( obj, inspect, { signal: flags.signal } ); // <<<---- AbortSignal-cascading
|
|
117
108
|
|
|
118
109
|
} );
|
|
119
110
|
```
|
|
120
111
|
|
|
121
|
-
|
|
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!*
|
|
122
117
|
|
|
123
118
|
#### Concept: *Mutation APIs*
|
|
124
119
|
|
|
@@ -262,7 +257,7 @@ obj = Observer.unproxy( $obj );
|
|
|
262
257
|
|
|
263
258
|
#### Concept: *Paths*
|
|
264
259
|
|
|
265
|
-
Observe "
|
|
260
|
+
Observe "a property" at a path in a given tree:
|
|
266
261
|
|
|
267
262
|
```js
|
|
268
263
|
const obj = {
|
|
@@ -420,31 +415,6 @@ Observer.observe( obj, 'prop1', mutation => {
|
|
|
420
415
|
} );
|
|
421
416
|
```
|
|
422
417
|
|
|
423
|
-
#### Concept: *Diffing*
|
|
424
|
-
|
|
425
|
-
Receive notifications only for mutations that actually change property state, and ignore those that don't.
|
|
426
|
-
|
|
427
|
-
```js
|
|
428
|
-
// Responding to state changes only
|
|
429
|
-
Observer.observe( obj, handleChanges, { diff: true } );
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
```js
|
|
433
|
-
// Recieved
|
|
434
|
-
Observer.set( obj, 'prop0', 'value' );
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
```js
|
|
438
|
-
// Ignored
|
|
439
|
-
Observer.set( obj, 'prop0', 'value' );
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
<!--
|
|
443
|
-
### Concept: *Live*
|
|
444
|
-
descripted
|
|
445
|
-
namespace
|
|
446
|
-
-->
|
|
447
|
-
|
|
448
418
|
### Method: `Observer.intercept()`
|
|
449
419
|
|
|
450
420
|
Intercept operations on any object or array before they happen!
|
|
@@ -511,91 +481,41 @@ Observer.intercept( obj, {
|
|
|
511
481
|
} );
|
|
512
482
|
```
|
|
513
483
|
|
|
514
|
-
##
|
|
484
|
+
## Documentation
|
|
515
485
|
|
|
516
|
-
|
|
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.
|
|
517
487
|
|
|
518
|
-
|
|
519
|
-
npm i @webqit/observer
|
|
520
|
-
```
|
|
488
|
+
## The Polyfill
|
|
521
489
|
|
|
522
|
-
|
|
523
|
-
// Import
|
|
524
|
-
import Observer from '@webqit/observer';;
|
|
525
|
-
```
|
|
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).
|
|
526
491
|
|
|
527
|
-
|
|
492
|
+
<details><summary>Load from a CDN</summary>
|
|
528
493
|
|
|
529
494
|
```html
|
|
530
495
|
<script src="https://unpkg.com/@webqit/observer/dist/main.js"></script>
|
|
531
496
|
```
|
|
532
497
|
|
|
533
|
-
> 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)
|
|
534
499
|
|
|
535
500
|
```js
|
|
536
501
|
// Obtain the APIs
|
|
537
502
|
const Observer = window.webqit.Observer;
|
|
538
503
|
```
|
|
539
504
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
| `getOwnPropertyDescriptor()` | ✓ | Obtains property descriptor [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor) | `getOwnPropertyDescriptor() {}` |
|
|
555
|
-
| `getPrototypeOf()` | ✓ | Obtains object prototype [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf) | `getPrototypeOf() {}` |
|
|
556
|
-
| `has()` | ✓ | Checks property existence [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/has) | `has() {}` |
|
|
557
|
-
| `intercept()` | `×` | Binds a "traps" object [↗](https://github.com/webqit/observer#method-observerintercept) | `-` |
|
|
558
|
-
| `isExtensible()` | ✓ | Checks object extensibility [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible) | `isExtensible() {}` |
|
|
559
|
-
| `observe()` | `×` | Binds a mutation observer [↗](https://github.com/webqit/observer#method-observerobserve) | `-` |
|
|
560
|
-
| `ownKeys()` | ✓ | Obtains object keys [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys) | `ownKeys() {}` |
|
|
561
|
-
| `path()` | `×` | Evaluates a path [↗](#) | `-` |
|
|
562
|
-
| `preventExtensions()` | ✓ | Prevents object extensibility [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions) | `preventExtensions() {}` |
|
|
563
|
-
| `set()` | ✓ | Sets a property [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/set) | `set() {}` |
|
|
564
|
-
| `setPrototypeOf()` | ✓ | Sets object prototype [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf) | `setPrototypeOf() {}` |
|
|
565
|
-
| . | . | . | . |
|
|
566
|
-
| `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) | `-` |
|
|
567
|
-
| `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) | `-` |
|
|
568
|
-
|
|
569
|
-
-->
|
|
570
|
-
|
|
571
|
-
| Observer API | Reflect API | Trap |
|
|
572
|
-
| -------------- | ------------ | ----------- |
|
|
573
|
-
| `apply()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/apply) | ✓ | `apply() {}` |
|
|
574
|
-
| `batch()` [↗](https://github.com/webqit/observer#concept-batch-mutations) | `×` | `-` |
|
|
575
|
-
| `construct()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/construct) | ✓ | `construct() {}` |
|
|
576
|
-
| `defineProperties()` [↗]() | `×` | `defineProperty() {}` |
|
|
577
|
-
| `defineProperty()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty) | ✓ | `defineProperty() {}` |
|
|
578
|
-
| `deleteProperties()` [↗]() | `×` | `deleteProperty() {}` |
|
|
579
|
-
| `deleteProperty()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/deleteProperty) | ✓ | `deleteProperty() {}` |
|
|
580
|
-
| `get()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/get) | ✓ | `get() {}` |
|
|
581
|
-
| `getOwnPropertyDescriptor()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor) | ✓ | `getOwnPropertyDescriptor() {}` |
|
|
582
|
-
| `getPrototypeOf()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf) | ✓ | `getPrototypeOf() {}` |
|
|
583
|
-
| `has()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/has) | ✓ | `has() {}` |
|
|
584
|
-
| `intercept()`[↗](https://github.com/webqit/observer#method-observerintercept) | `×` | `-` |
|
|
585
|
-
| `isExtensible()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible) | ✓ | `isExtensible() {}` |
|
|
586
|
-
| `observe()` [↗](https://github.com/webqit/observer#method-observerobserve) | `×` | `-` |
|
|
587
|
-
| `ownKeys()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys) | ✓ | `ownKeys() {}` |
|
|
588
|
-
| `path()` [↗](https://github.com/webqit/observer#concept-paths) | `×` | `-` |
|
|
589
|
-
| `preventExtensions()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions) | ✓ | `preventExtensions() {}` |
|
|
590
|
-
| `set()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/set) | ✓ | `set() {}` |
|
|
591
|
-
| `setPrototypeOf()` [↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf) | ✓ | `setPrototypeOf() {}` |
|
|
592
|
-
| . | . | . | . |
|
|
593
|
-
| `accessorize()` [↗](https://github.com/webqit/observer#:~:text=enable%20reactivity%20on%20specific%20properties%20with%20literal%20object%20accessors%20-%20using%20the%20observer.accessorize()%20method) | `×` | `-` |
|
|
594
|
-
| `proxy()` [↗](https://github.com/webqit/observer#:~:text=enable%20reactivity%20on%20arbitray%20properties%20with%20proxies%20-%20using%20the%20observer.proxy()%20method) | `×` | `-` |
|
|
595
|
-
|
|
596
|
-
## Design Discussion
|
|
597
|
-
|
|
598
|
-
[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>
|
|
599
519
|
|
|
600
520
|
## Getting Involved
|
|
601
521
|
|