@webqit/observer 2.0.7 → 2.1.1
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/.gitignore +3 -3
- package/LICENSE +20 -20
- package/README.md +425 -202
- package/dist/main.js +1 -1
- package/dist/main.js.map +3 -3
- package/package.json +68 -68
- package/src/actors.js +180 -176
- package/src/core/Descriptor.js +22 -22
- package/src/core/ListenerRegistration.js +61 -57
- package/src/core/ListenerRegistry.js +73 -70
- package/src/core/Registration.js +34 -34
- package/src/core/Registry.js +92 -92
- package/src/core/TrapsRegistration.js +34 -34
- package/src/core/TrapsRegistry.js +50 -50
- package/src/index.js +9 -9
- package/src/main.js +585 -561
- package/src/targets.browser.js +8 -8
- package/src/util.js +9 -7
- package/test/reactions.test.js +351 -352
- package/webpack.config.cjs +5 -5
package/README.md
CHANGED
|
@@ -1,202 +1,425 @@
|
|
|
1
|
-
# The Observer API
|
|
2
|
-
|
|
3
|
-
<!-- BADGES/ -->
|
|
4
|
-
|
|
5
|
-
<span class="badge-npmversion"><a href="https://npmjs.org/package/@webqit/observer" title="View this project on NPM"><img src="https://img.shields.io/npm/v/@webqit/observer.svg" alt="NPM version" /></a></span> <span class="badge-npmdownloads"><a href="https://npmjs.org/package/@webqit/observer" title="View this project on NPM"><img src="https://img.shields.io/npm/dm/@webqit/observer.svg" alt="NPM downloads" /></a></span>
|
|
6
|
-
|
|
7
|
-
<!-- /BADGES -->
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
//
|
|
84
|
-
Observer.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
```js
|
|
132
|
-
//
|
|
133
|
-
Observer.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
1
|
+
# The Observer API
|
|
2
|
+
|
|
3
|
+
<!-- BADGES/ -->
|
|
4
|
+
|
|
5
|
+
<span class="badge-npmversion"><a href="https://npmjs.org/package/@webqit/observer" title="View this project on NPM"><img src="https://img.shields.io/npm/v/@webqit/observer.svg" alt="NPM version" /></a></span> <span class="badge-npmdownloads"><a href="https://npmjs.org/package/@webqit/observer" title="View this project on NPM"><img src="https://img.shields.io/npm/dm/@webqit/observer.svg" alt="NPM downloads" /></a></span>
|
|
6
|
+
|
|
7
|
+
<!-- /BADGES -->
|
|
8
|
+
|
|
9
|
+
A web-native object observability API!
|
|
10
|
+
|
|
11
|
+
Observe and intercept operations on any type of JavaScript objects and arrays, using a notably lightweight and predictable utility-first reactivity API!
|
|
12
|
+
|
|
13
|
+
## Motivation
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Table of Contents
|
|
18
|
+
|
|
19
|
+
+ [Motivation](#motivation)
|
|
20
|
+
+ [Download Options](#download-options)
|
|
21
|
+
+ [An Overview](#an-overview)
|
|
22
|
+
+ [Method: `Observer.observe()`](#method-observerobserve)
|
|
23
|
+
+ [Concept: *Observers*](#concept-observers)
|
|
24
|
+
+ [Concept: *Mutations*](#concept-mutations)
|
|
25
|
+
+ [Concept: *Batch Mutations*](#concept-batch-mutations)
|
|
26
|
+
+ [Concept: *Custom Details*](#concept-custom-details)
|
|
27
|
+
+ [Concept: *Diffing*](#concept-diffing)
|
|
28
|
+
+ [Method: `Observer.intercept()`](#method-observerintercept)
|
|
29
|
+
+ [Concept: *Traps*](#concept-traps)
|
|
30
|
+
+ [Issues](#issues)
|
|
31
|
+
+ [License](#license)
|
|
32
|
+
|
|
33
|
+
## Download Options
|
|
34
|
+
|
|
35
|
+
**_Use as an npm package:_**
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm i @webqit/observer
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
// Import
|
|
43
|
+
import Observer from '@webqit/observer';;
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**_Use as a script:_**
|
|
47
|
+
|
|
48
|
+
```html
|
|
49
|
+
<script src="https://unpkg.com/@webqit/observer/dist/main.js"></script>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
// Obtain the APIs
|
|
54
|
+
const Observer = window.webqit.Observer;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## An Overview
|
|
58
|
+
|
|
59
|
+
> **Note**
|
|
60
|
+
> <br>This is documentation for `Observer@2.x`. (Looking for [`Observer@1.x`](https://github.com/webqit/observer/tree/v1.7.6)?)
|
|
61
|
+
|
|
62
|
+
### Method: `Observer.observe()`
|
|
63
|
+
|
|
64
|
+
Observe mutations on any object or array!
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
// Signature 1
|
|
68
|
+
Observer.observe( obj, callback[, options = {} ]);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
// Signature 2
|
|
73
|
+
Observer.observe( obj, props, callback[, options = {} ]);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### Concept: *Observers*
|
|
77
|
+
|
|
78
|
+
Observe arbitrary objects and arrays:
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
// An object
|
|
82
|
+
const obj = {};
|
|
83
|
+
// Mtation observer on an object
|
|
84
|
+
const abortController = Observer.observe( obj, handleChanges );
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
// An array
|
|
89
|
+
const arr = [];
|
|
90
|
+
// Mtation observer on an array
|
|
91
|
+
const abortController = Observer.observe( arr, handleChanges );
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
*Now changes will be delivered **synchronously** - as they happen. (The *sync* design is discussed shortly.)*
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
// The change handler
|
|
98
|
+
function handleChanges( mutations ) {
|
|
99
|
+
mutations.forEach( mutation => {
|
|
100
|
+
console.log( mutation.type, mutation.key, mutation.value, mutation.oldValue );
|
|
101
|
+
} );
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**-->** Stop observing at any time by calling `abort()` on the returned *abortController*...
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
// Remove listener
|
|
109
|
+
abortController.abort();
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
...or by using an [Abort Signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) instance:
|
|
113
|
+
|
|
114
|
+
```js
|
|
115
|
+
// Providing an AbortSignal
|
|
116
|
+
const abortController = new AbortController;
|
|
117
|
+
Observer.observe( obj, mutations => {
|
|
118
|
+
// Handle...
|
|
119
|
+
}, { signal: abortController.signal } );
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```js
|
|
123
|
+
// Abort at any time
|
|
124
|
+
abortController.abort();
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### Concept: *Mutations*
|
|
128
|
+
|
|
129
|
+
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:
|
|
130
|
+
|
|
131
|
+
```js
|
|
132
|
+
// A single "set" operation on an object
|
|
133
|
+
Observer.set( obj, 'prop0', 'value0' );
|
|
134
|
+
Observer.defineProperty( obj, 'prop1', { get: () => 'value1' } );
|
|
135
|
+
Observer.deleteProperty( obj, 'prop2' );
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
// A single "set" operation on an array
|
|
140
|
+
Observer.set( arr, 0, 'item0' ); // Array [ 'item0' ]
|
|
141
|
+
Observer.deleteProperty( arr, 0 ); // Array [ <1 empty slot> ]
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
*Beware non-reactive operations*:
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
// Literal object accessors
|
|
148
|
+
delete obj.prop0;
|
|
149
|
+
obj.prop3 = 'value3';
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```js
|
|
153
|
+
// Array methods
|
|
154
|
+
arr.push( 'item3' );
|
|
155
|
+
arr.pop();
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**-->** Enable reactivity on *specific* properties with literal *object accessors* - using the `Observer.accessorize()` method:
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
// Accessorize all (existing) properties
|
|
162
|
+
Observer.accessorize( obj );
|
|
163
|
+
// Accessorize specific properties (existing or new)
|
|
164
|
+
Observer.accessorize( obj, [ 'prop0', 'prop1', 'prop2' ] );
|
|
165
|
+
|
|
166
|
+
// Make reactive UPDATES
|
|
167
|
+
obj.prop0 = 'value0';
|
|
168
|
+
obj.prop1 = 'value1';
|
|
169
|
+
obj.prop2 = 'value2';
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
// Accessorize all (existing) indexes
|
|
174
|
+
Observer.accessorize( arr );
|
|
175
|
+
// Accessorize specific indexes (existing or new)
|
|
176
|
+
Observer.accessorize( arr, [ 0, 1, 2 ] );
|
|
177
|
+
|
|
178
|
+
// Make reactive UPDATES
|
|
179
|
+
arr[ 0 ] = 'item0';
|
|
180
|
+
arr[ 1 ] = 'item1';
|
|
181
|
+
arr[ 2 ] = 'item2';
|
|
182
|
+
|
|
183
|
+
// Bonus reactivity: array methods that re-index existing items
|
|
184
|
+
arr.unshift( 'new-item0' );
|
|
185
|
+
arr.shift();
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
*Beware non-reactive operations*:
|
|
189
|
+
|
|
190
|
+
```js
|
|
191
|
+
// The delete operator and object properties that haven't been accessorized
|
|
192
|
+
delete obj.prop0;
|
|
193
|
+
obj.prop3 = 'value3';
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
```js
|
|
197
|
+
// Array methods that do not re-index existing items
|
|
198
|
+
arr.push( 'item0' );
|
|
199
|
+
arr.pop();
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**-->** Enable reactivity on *arbitray* properties with *Proxies* - using the `Observer.proxy()` method:
|
|
203
|
+
|
|
204
|
+
```js
|
|
205
|
+
// Obtain a reactive Proxy for an object
|
|
206
|
+
const _obj = Observer.proxy( obj );
|
|
207
|
+
|
|
208
|
+
// Make reactive operations
|
|
209
|
+
_obj.prop1 = 'value1';
|
|
210
|
+
_obj.prop4 = 'value4';
|
|
211
|
+
_obj.prop8 = 'value8';
|
|
212
|
+
|
|
213
|
+
// With the delete operator
|
|
214
|
+
delete _obj.prop0;
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
```js
|
|
218
|
+
// Obtain a reactive Proxy for an array
|
|
219
|
+
const _arr = Observer.proxy( arr );
|
|
220
|
+
|
|
221
|
+
// Make reactive operations
|
|
222
|
+
_arr[ 0 ] = 'item0';
|
|
223
|
+
_arr[ 1 ] = 'item1';
|
|
224
|
+
_arr[ 2 ] = 'item2';
|
|
225
|
+
|
|
226
|
+
// With an instance method
|
|
227
|
+
_arr.push( 'item3' );
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
*And no problem if you end up nesting the approaches.*
|
|
231
|
+
|
|
232
|
+
```js
|
|
233
|
+
// 'value1'-->obj
|
|
234
|
+
Observer.accessorize( obj, [ 'prop0', 'prop1', 'prop2', ] );
|
|
235
|
+
obj.prop1 = 'value1';
|
|
236
|
+
|
|
237
|
+
// 'value1'-->_obj-->obj
|
|
238
|
+
let _obj = Observer.proxy( obj );
|
|
239
|
+
_obj.prop1 = 'value1';
|
|
240
|
+
|
|
241
|
+
// 'value1'-->set()-->_obj-->obj
|
|
242
|
+
Observer.set( _obj, 'prop1', 'value1' );
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**-->** "Restore" accessorized properties to their normal state by using the `unaccessorize()` method:
|
|
246
|
+
|
|
247
|
+
```js
|
|
248
|
+
Observer.unaccessorize( obj, [ 'prop1', 'prop6', 'prop10' ] );
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
**-->** "Reproduce" original objects from Proxies obtained via `Observer.proxy()` by using the `unproxy()` method:
|
|
252
|
+
|
|
253
|
+
```js
|
|
254
|
+
obj = Observer.unproxy( _obj );
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
#### Concept: *Batch Mutations*
|
|
258
|
+
|
|
259
|
+
Make multiple mutations at a go, and they'll be correctly delivered in batch to observers!
|
|
260
|
+
|
|
261
|
+
```js
|
|
262
|
+
// Batch operations on an object
|
|
263
|
+
Observer.set( obj, {
|
|
264
|
+
prop0: 'value0',
|
|
265
|
+
prop1: 'value1',
|
|
266
|
+
prop2: 'value2',
|
|
267
|
+
} );
|
|
268
|
+
Observer.defineProperties( obj, {
|
|
269
|
+
prop0: { value: 'value0' },
|
|
270
|
+
prop1: { value: 'value1' },
|
|
271
|
+
prop2: { get: () => 'value2' },
|
|
272
|
+
} );
|
|
273
|
+
Observer.deleteProperties( obj, [ 'prop0', 'prop1', 'prop2' ] );
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
```js
|
|
277
|
+
// Batch operations on an array
|
|
278
|
+
Observer.set( arr, {
|
|
279
|
+
'0': 'item0',
|
|
280
|
+
'1': 'item1',
|
|
281
|
+
'2': 'item2',
|
|
282
|
+
} );
|
|
283
|
+
Object.proxy( arr ).push( 'item3', 'item4', 'item5', );
|
|
284
|
+
Object.proxy( arr ).unshift( 'new-item0' );
|
|
285
|
+
Object.proxy( arr ).splice( 0 );
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**-->** Use the `Observer.batch()` to batch multiple arbitrary mutations - whether related or not:
|
|
289
|
+
|
|
290
|
+
```js
|
|
291
|
+
Observer.batch( arr, async () => {
|
|
292
|
+
Observer.set( arr, 0, 'item0' ); // Array [ 'item0' ]
|
|
293
|
+
await somePromise();
|
|
294
|
+
Observer.set( arr, 2, 'item2' ); // Array [ 'item0', <1 empty slot>, 'item2' ]
|
|
295
|
+
} );
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
> Method calls on a proxied instance - e.g. `Object.proxy( arr ).splice( 0 )` - also follow this strategy.
|
|
299
|
+
|
|
300
|
+
#### Concept: *Custom Details*
|
|
301
|
+
|
|
302
|
+
Pass some custom detail - an arbitrary value - to observers via a `params.detail` property.
|
|
303
|
+
|
|
304
|
+
```js
|
|
305
|
+
// A set operation with detail
|
|
306
|
+
Observer.set( obj, {
|
|
307
|
+
prop2: 'value2',
|
|
308
|
+
prop3: 'value3',
|
|
309
|
+
}, { detail: 'Certain detail' } );
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
*Observers recieve this value on their `mutation.detail` property.*
|
|
313
|
+
|
|
314
|
+
```js
|
|
315
|
+
// An observer with detail
|
|
316
|
+
Observer.observe( obj, 'prop1', mutation => {
|
|
317
|
+
console.log( 'A mutation has been made with detail:' + mutation.detail );
|
|
318
|
+
} );
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
#### Concept: *Diffing*
|
|
322
|
+
|
|
323
|
+
Receive notifications only for mutations that actually change property state, and ignore those that don't.
|
|
324
|
+
|
|
325
|
+
```js
|
|
326
|
+
// Responding to state changes only
|
|
327
|
+
Observer.observe( obj, handleChanges, { diff: true } );
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
```js
|
|
331
|
+
// Recieved
|
|
332
|
+
Observer.set( obj, 'prop0', 'value' );
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
```js
|
|
336
|
+
// Ignored
|
|
337
|
+
Observer.set( obj, 'prop0', 'value' );
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
<!--
|
|
341
|
+
### Concept: *Live*
|
|
342
|
+
descripted
|
|
343
|
+
namespace
|
|
344
|
+
-->
|
|
345
|
+
|
|
346
|
+
### Method: `Observer.intercept()`
|
|
347
|
+
|
|
348
|
+
Intercept operations on any object or array before they happen!
|
|
349
|
+
|
|
350
|
+
```js
|
|
351
|
+
// Signature 1
|
|
352
|
+
Observer.intercept( obj, prop, handler[, options = {} ]);
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
```js
|
|
356
|
+
// Signature 2
|
|
357
|
+
Observer.intercept( obj, traps[, options = {} ]);
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
#### Concept: *Traps*
|
|
361
|
+
|
|
362
|
+
Extend standard operations on an object - `Observer.set()`, `Observer.deleteProperty()`, etc - with custom traps using the [`Observer.intercept()`](https://webqit.io/tooling/observer/docs/api/reactions/intercept) method!
|
|
363
|
+
|
|
364
|
+
*Below, we intercept all "set" operations for an HTTP URL then transform it to an HTTPS URL.*
|
|
365
|
+
|
|
366
|
+
```js
|
|
367
|
+
const setTrap = ( operation, previous, next ) => {
|
|
368
|
+
if ( operation.key === 'url' && operation.value.startsWith( 'http:' ) ) {
|
|
369
|
+
operation.value = operation.value.replace( 'http:', 'https:' );
|
|
370
|
+
}
|
|
371
|
+
return next();
|
|
372
|
+
};
|
|
373
|
+
Observer.intercept( obj, 'set', setTrap );
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
*Now, only the first of the following will fly as-is.*
|
|
377
|
+
|
|
378
|
+
```js
|
|
379
|
+
// Not transformed
|
|
380
|
+
Observer.set( obj, 'url', 'https://webqit.io' );
|
|
381
|
+
|
|
382
|
+
// Transformed
|
|
383
|
+
Observer.set( obj, 'url', 'http://webqit.io' );
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
*And below, we intercept all "get" operations for a certain value to trigger a network fetch behind the scenes.*
|
|
387
|
+
|
|
388
|
+
```js
|
|
389
|
+
const getTrap = ( operation, previous, next ) => {
|
|
390
|
+
if ( operation.key === 'token' ) {
|
|
391
|
+
return next( fetch( tokenUrl ) );
|
|
392
|
+
}
|
|
393
|
+
return next();
|
|
394
|
+
};
|
|
395
|
+
Observer.intercept( obj, 'get', getTrap );
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
*And all of that can go into one "traps" object:*
|
|
399
|
+
|
|
400
|
+
```js
|
|
401
|
+
Observer.intercept( obj, {
|
|
402
|
+
get: getTrap,
|
|
403
|
+
set: setTrap,
|
|
404
|
+
deleteProperty: deletePropertyTrap,
|
|
405
|
+
defineProperty: definePropertyTrap,
|
|
406
|
+
ownKeys: ownKeysTrap,
|
|
407
|
+
has: hasTrap,
|
|
408
|
+
// etc
|
|
409
|
+
} );
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## The End?
|
|
413
|
+
|
|
414
|
+
Certainly not! But this rundown should be a good start. Next:
|
|
415
|
+
|
|
416
|
+
+ Visit the [download](https://webqit.io/tooling/observer/docs/getting-started/download) page to obtain the Observer API.
|
|
417
|
+
+ Explore the [API Reference](https://webqit.io/tooling/observer/docs/api).
|
|
418
|
+
|
|
419
|
+
## Issues
|
|
420
|
+
|
|
421
|
+
To report bugs or request features, please submit an [issue](https://github.com/webqit/observer/issues).
|
|
422
|
+
|
|
423
|
+
## License
|
|
424
|
+
|
|
425
|
+
MIT.
|