@webqit/observer 2.1.2 → 2.1.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.
- package/README.md +52 -49
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,62 +6,34 @@
|
|
|
6
6
|
|
|
7
7
|
<!-- /BADGES -->
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**[Motivation](#motivation) • [Overview](#an-overview) • [Polyfill](#the-polyfill) • [Design Discussion](#design-discussion) • [Getting Involved](#getting-involved) • [License](#license)**
|
|
10
10
|
|
|
11
|
-
Observe and intercept operations on
|
|
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 extends it with the best of JavaScript's other [reflection](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect) and interception APIs - *Proxies*, *accessors* - to support any kind of reactive programming model!
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Tracking mutations on JavaScript objects has historically relied on "object wrapping" with [ES6 Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) and "property mangling" with [getters and setters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty). Besides the *object identity trade-off* problem of the first and the *property compromisal* problem of the second, there is also the "scalability" issue inherent to the techniques and much "inflexibility" in the programming model they enable:
|
|
16
|
-
|
|
17
|
-
+ **Scalability**: objects have to be created a certain way, or purpose-built for the specific technique, to participate in the reactive system; objects *you don't own* have to be altered in some way - where that's even possible - to be onboarded into the reactivity system. Scalability is hamstrung as we must fulfill the **implementation criteria** for as many objects as will be needed in the design - clamped to the finite number of objects that can be made to work this way!
|
|
18
|
-
|
|
19
|
-
+ **Programming model**: proxy traps and object accessors by design only interface with one listenining logic in the entire program. Objects are effectively open to multiple interactions on the outside but closed-off to one observer on the inside, enabling just a "many to one" model. This does not correctly reflect the most common usecases where the idea is to have any number of listeners per event; i.e. a "many to many" model! It takes yet a non-trivial effort to go from the default model to the one desired.
|
|
20
|
-
|
|
21
|
-
Surprisingly, we at one time had an *object observability* primitive that checked all the boxes and touched the very pain points we have today: the [`Object.observe()`](https://web.dev/es7-observe/) API. How about an equivalent API that brings all of the good thinking from `Object.observe()` together with the idea of *Proxies* and *accessors* in one design, delivered as one utility for all things *reactivity*? This is the idea with the new **Observer API**!
|
|
22
|
-
|
|
23
|
-
## Table of Contents
|
|
24
|
-
|
|
25
|
-
+ [Motivation](#motivation)
|
|
26
|
-
+ [Download Options](#download-options)
|
|
27
|
-
+ [An Overview](#an-overview)
|
|
28
|
-
+ [Method: `Observer.observe()`](#method-observerobserve)
|
|
29
|
-
+ [Concept](#concept)
|
|
30
|
-
+ [Concept: *Mutations*](#concept-mutations)
|
|
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
|
-
+ [Concept](#concept)
|
|
36
|
-
+ [Design Discussion](#design-discussion)
|
|
37
|
-
+ [Issues](#issues)
|
|
38
|
-
+ [License](#license)
|
|
13
|
+
Observer API is an upcoming proposal!
|
|
39
14
|
|
|
40
|
-
##
|
|
15
|
+
## Motivation
|
|
41
16
|
|
|
42
|
-
|
|
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 trade-off* problem of the first and the *property compromisal* problem of the second, there is also the "scalability" issue inherent to the techniques and much "inflexibility" in the programming model they enable:
|
|
43
18
|
|
|
44
|
-
|
|
45
|
-
npm i @webqit/observer
|
|
46
|
-
```
|
|
19
|
+
+ **Scalability**: objects have to be created a certain way, or be purpose-built for the specific technique, to participate in the reactivity system; objects *you don't own* have to be altered in some way - where that's even possible - to be onboarded into the reactivity system. Scalability is inhibited as we must fulfill the **implementation criteria** for as many objects as will be needed in the design - clamped to the finite number of objects that can be made to work this way!
|
|
47
20
|
|
|
48
|
-
|
|
49
|
-
// Import
|
|
50
|
-
import Observer from '@webqit/observer';;
|
|
51
|
-
```
|
|
21
|
+
+ **Programming model**: proxy traps and object accessors only lend themselves to being wired to *one* underlying listenining logic in the entire program. Objects are effectively open to multiple interactions on the outside but "locked" to one observer on the inside, enabling just a "many to one" communication model. This does not correctly reflect the most common usecases where the idea is to have any number of listeners per event, to enable a "many to many" model! It takes yet a non-trivial amount of effort to go from the default model to the one desired.
|
|
52
22
|
|
|
53
|
-
|
|
23
|
+
Interestingly, we at one time had an *object observability* primitive that checked all the boxes and touched the very pain points we have today: the [`Object.observe()`](https://web.dev/es7-observe/) API. So, how about an equivalent API that brings all of the good thinking from `Object.observe()` together with the idea of *Proxies*, *accessors*, and JavaScript's other [*reflection* API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect) in one design, delivered as one utility for all things *reactivity*? This is the idea with the new **Observer API**!
|
|
54
24
|
|
|
55
|
-
|
|
56
|
-
<script src="https://unpkg.com/@webqit/observer/dist/main.js"></script>
|
|
57
|
-
```
|
|
25
|
+
## An Overview
|
|
58
26
|
|
|
59
|
-
|
|
60
|
-
// Obtain the APIs
|
|
61
|
-
const Observer = window.webqit.Observer;
|
|
62
|
-
```
|
|
27
|
+
The Observer API comes as a set of utility functions.
|
|
63
28
|
|
|
64
|
-
|
|
29
|
+
+ [Method: `Observer.observe()`](#method-observerobserve)
|
|
30
|
+
+ [Concept](#concept)
|
|
31
|
+
+ [Concept: *Mutation APIs*](#concept-mutation-apis)
|
|
32
|
+
+ [Concept: *Batch Mutations*](#concept-batch-mutations)
|
|
33
|
+
+ [Concept: *Custom Details*](#concept-custom-details)
|
|
34
|
+
+ [Concept: *Diffing*](#concept-diffing)
|
|
35
|
+
+ [Method: `Observer.intercept()`](#method-observerintercept)
|
|
36
|
+
+ [Concept](#concept-1)
|
|
65
37
|
|
|
66
38
|
> **Note**
|
|
67
39
|
> <br>This is documentation for `Observer@2.x`. (Looking for [`Observer@1.x`](https://github.com/webqit/observer/tree/v1.7.6)?)
|
|
@@ -131,7 +103,7 @@ Observer.observe( obj, mutations => {
|
|
|
131
103
|
abortController.abort();
|
|
132
104
|
```
|
|
133
105
|
|
|
134
|
-
#### Concept: *
|
|
106
|
+
#### Concept: *Mutation APIs*
|
|
135
107
|
|
|
136
108
|
Programmatically mutate properties of an object using the *[Reflect](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect#static_methods)-like* set of operators; each operation will be reported by observers:
|
|
137
109
|
|
|
@@ -416,13 +388,44 @@ Observer.intercept( obj, {
|
|
|
416
388
|
} );
|
|
417
389
|
```
|
|
418
390
|
|
|
391
|
+
## The Polyfill
|
|
392
|
+
|
|
393
|
+
**_Use as an npm package:_**
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
npm i @webqit/observer
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
```js
|
|
400
|
+
// Import
|
|
401
|
+
import Observer from '@webqit/observer';;
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**_Use as a script:_**
|
|
405
|
+
|
|
406
|
+
```html
|
|
407
|
+
<script src="https://unpkg.com/@webqit/observer/dist/main.js"></script>
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
> 4.54 KB min+compressed | 12.85 KB min
|
|
411
|
+
|
|
412
|
+
```js
|
|
413
|
+
// Obtain the APIs
|
|
414
|
+
const Observer = window.webqit.Observer;
|
|
415
|
+
```
|
|
416
|
+
|
|
419
417
|
## Design Discussion
|
|
420
418
|
|
|
421
419
|
*[TODO]*
|
|
422
420
|
|
|
423
|
-
##
|
|
421
|
+
## Getting Involved
|
|
422
|
+
|
|
423
|
+
All forms of contributions are welcome at this time. For example, implementation details are all up for discussion. And here are specific links:
|
|
424
424
|
|
|
425
|
-
|
|
425
|
+
+ [Project](https://github.com/webqit/observer)
|
|
426
|
+
+ [Documentation](https://github.com/webqit/observer/wiki)
|
|
427
|
+
+ [Discusions](https://github.com/webqit/observer/discussions)
|
|
428
|
+
+ [Issues](https://github.com/webqit/observer/issues)
|
|
426
429
|
|
|
427
430
|
## License
|
|
428
431
|
|