@webqit/observer 1.7.6 → 2.0.0
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 +202 -199
- package/dist/main.js +2 -2
- package/dist/main.js.map +7 -1
- package/package.json +68 -68
- package/src/actors.js +175 -0
- package/src/core/Descriptor.js +23 -0
- package/src/core/ListenerRegistration.js +54 -0
- package/src/core/ListenerRegistry.js +41 -0
- package/src/core/Registration.js +35 -0
- package/src/core/Registry.js +96 -0
- package/src/core/TrapsRegistration.js +35 -0
- package/src/core/TrapsRegistry.js +51 -0
- package/src/index.js +10 -74
- package/src/main.js +547 -0
- package/src/targets.browser.js +9 -0
- package/test/reactions.test.js +326 -337
- package/webpack.config.cjs +5 -5
- package/src/actions/_exec.js +0 -33
- package/src/actions/_setOrDefine.js +0 -136
- package/src/actions/apply.js +0 -19
- package/src/actions/construct.js +0 -19
- package/src/actions/defineProperty.js +0 -20
- package/src/actions/deleteProperty.js +0 -80
- package/src/actions/get.js +0 -53
- package/src/actions/getOwnPropertyDescriptor.js +0 -18
- package/src/actions/getPrototypeOf.js +0 -17
- package/src/actions/has.js +0 -18
- package/src/actions/isExtensible.js +0 -17
- package/src/actions/ownKeys.js +0 -17
- package/src/actions/preventExtensions.js +0 -17
- package/src/actions/set.js +0 -21
- package/src/actions/setPrototypeOf.js +0 -18
- package/src/actors/accessorize.js +0 -162
- package/src/actors/proxy.js +0 -59
- package/src/actors/unaccessorize.js +0 -26
- package/src/actors/unproxy.js +0 -17
- package/src/browser-entry.js +0 -11
- package/src/connectors/build.js +0 -64
- package/src/connectors/link.js +0 -76
- package/src/connectors/unlink.js +0 -35
- package/src/core/Action.js +0 -33
- package/src/core/Delta.js +0 -46
- package/src/core/Event.js +0 -141
- package/src/core/Fireable.js +0 -34
- package/src/core/Firebase.js +0 -136
- package/src/core/Interceptor.js +0 -33
- package/src/core/Interceptors.js +0 -61
- package/src/core/Mutation.js +0 -46
- package/src/core/Observer.js +0 -99
- package/src/core/Observers.js +0 -75
- package/src/core/utils.js +0 -51
- package/src/reactions/closure.js +0 -88
- package/src/reactions/intercept.js +0 -53
- package/src/reactions/observe.js +0 -45
- package/src/reactions/unintercept.js +0 -43
- package/src/reactions/unobserve.js +0 -36
package/src/core/Interceptor.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import { _from as _arrFrom } from '@webqit/util/arr/index.js';
|
|
6
|
-
import { _intersect } from '@webqit/util/arr/index.js';
|
|
7
|
-
import Fireable from './Fireable.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* ---------------------------
|
|
11
|
-
* The Trap class
|
|
12
|
-
* ---------------------------
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
export default class Interceptor extends Fireable {
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Calls the observer's handler function
|
|
19
|
-
* on matching with the event's fields.
|
|
20
|
-
*
|
|
21
|
-
* @param Event event
|
|
22
|
-
* @param function next
|
|
23
|
-
* @param mixed recieved
|
|
24
|
-
*
|
|
25
|
-
* @return void
|
|
26
|
-
*/
|
|
27
|
-
fire(event, next, recieved) {
|
|
28
|
-
if (this.disconnected || (this.filter && !_intersect(_arrFrom(this.filter), [event.type]).length)) {
|
|
29
|
-
return next(...Array.prototype.slice.call(arguments, 2));
|
|
30
|
-
}
|
|
31
|
-
return this.handler(event, recieved, next);
|
|
32
|
-
}
|
|
33
|
-
}
|
package/src/core/Interceptors.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import Firebase from './Firebase.js';
|
|
6
|
-
import Interceptor from './Interceptor.js';
|
|
7
|
-
import Action from './Action.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* ---------------------------
|
|
11
|
-
* The Reactive class
|
|
12
|
-
* ---------------------------
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
export default class Interceptors extends Firebase {
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* @inheritdoc
|
|
19
|
-
*/
|
|
20
|
-
add(dfn) {
|
|
21
|
-
return super.add(new Interceptor(this.target, dfn));
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Fires all interceptors with the given action.
|
|
26
|
-
*
|
|
27
|
-
* @param Action action
|
|
28
|
-
* @param function defaultHandler
|
|
29
|
-
*
|
|
30
|
-
* @return mixed
|
|
31
|
-
*/
|
|
32
|
-
fire(action, defaultHandler = null) {
|
|
33
|
-
if (!(action instanceof Action)) {
|
|
34
|
-
action = new Action(this.target, action);
|
|
35
|
-
}
|
|
36
|
-
if (this.currentlyFiring.filter(a => a.type === action.type && a.name === action.name).length) {
|
|
37
|
-
return defaultHandler ? defaultHandler() : undefined;
|
|
38
|
-
}
|
|
39
|
-
this.currentlyFiring.push(action);
|
|
40
|
-
const next = (index, ..._args) => {
|
|
41
|
-
var interceptor = this.fireables[index];
|
|
42
|
-
if (interceptor) {
|
|
43
|
-
return interceptor.fire(action, (...args) => {
|
|
44
|
-
return next(index + 1, ...args);
|
|
45
|
-
}/*next*/, ..._args);
|
|
46
|
-
}
|
|
47
|
-
return defaultHandler ? defaultHandler(..._args) : _args[0];
|
|
48
|
-
};
|
|
49
|
-
var value = next(0);
|
|
50
|
-
this.currentlyFiring.pop();
|
|
51
|
-
return value;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
static getFirebase(target, createIfNotExists = true, namespace = null) {
|
|
55
|
-
return super._getFirebase('interceptor', ...arguments);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
static namespace(namespace, ImplementationClass = null) {
|
|
59
|
-
return super._namespace('interceptor', ...arguments);
|
|
60
|
-
}
|
|
61
|
-
}
|
package/src/core/Mutation.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import { _each } from '@webqit/util/obj/index.js';
|
|
6
|
-
import { DotSafePath } from './utils.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* ---------------------------
|
|
10
|
-
* The QueryEvent class
|
|
11
|
-
* ---------------------------
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
export default class Mutation {
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Initializes the instance.
|
|
18
|
-
*
|
|
19
|
-
* @param array|object target
|
|
20
|
-
* @param object dfn
|
|
21
|
-
*
|
|
22
|
-
* @return void
|
|
23
|
-
*/
|
|
24
|
-
constructor(target, dfn) {
|
|
25
|
-
this.target = target;
|
|
26
|
-
if (!dfn.originalSubject) {
|
|
27
|
-
this.originalSubject = target;
|
|
28
|
-
}
|
|
29
|
-
if (!('type' in dfn)) {
|
|
30
|
-
throw new Error('Mutation type must be given in definition!');
|
|
31
|
-
}
|
|
32
|
-
if (!('name' in dfn)) {
|
|
33
|
-
throw new Error('Property name must be given in definition!');
|
|
34
|
-
}
|
|
35
|
-
_each(dfn, (key, value) => {
|
|
36
|
-
if (key === 'path') {
|
|
37
|
-
value = DotSafePath.resolve(value);
|
|
38
|
-
}
|
|
39
|
-
Object.defineProperty(this, key, {value, enumerable:true});
|
|
40
|
-
});
|
|
41
|
-
if (!this.path) {
|
|
42
|
-
Object.defineProperty(this, 'path', {value: DotSafePath.resolve([dfn.name]), enumerable:true});
|
|
43
|
-
}
|
|
44
|
-
Object.seal(this);
|
|
45
|
-
}
|
|
46
|
-
}
|
package/src/core/Observer.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import {
|
|
6
|
-
_after as _arrAfter, _startsWith as _arrStartsWith,
|
|
7
|
-
_any, _equals as _arrEquals,
|
|
8
|
-
} from '@webqit/util/arr/index.js';
|
|
9
|
-
import { _isNumeric, _isFunction, _isObject } from '@webqit/util/js/index.js';
|
|
10
|
-
import { paths2D, pathsIs2D, pathsIsDynamic, paths2DIsDynamic } from './utils.js'
|
|
11
|
-
import Fireable from './Fireable.js';
|
|
12
|
-
import Event from './Event.js';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* ---------------------------
|
|
16
|
-
* The Observer class
|
|
17
|
-
* ---------------------------
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
export default class Observer extends Fireable {
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Initializes the instance.
|
|
24
|
-
*
|
|
25
|
-
* @param array|object target
|
|
26
|
-
* @param object dfn
|
|
27
|
-
*
|
|
28
|
-
* @return void
|
|
29
|
-
*/
|
|
30
|
-
constructor(target, dfn) {
|
|
31
|
-
super(target, dfn);
|
|
32
|
-
// The rest of this code is designed for a 2-dimensional array.
|
|
33
|
-
this.filters2D = paths2D(this.filter);
|
|
34
|
-
this.filtersIsOriginally2D = pathsIs2D(this.filter);
|
|
35
|
-
this.filtersIsDynamic = paths2DIsDynamic(this.filters2D);
|
|
36
|
-
if (this.filtersIsDynamic && this.filters2D.length > 1) {
|
|
37
|
-
throw new Error('Only one "Dynamic Filter" must be observed at a time! "' + this.filters2D.map(pathArray => '[' + pathArray.join(', ') + ']').join(', ') + '" have been bound together.');
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Calls the observer's handler function
|
|
43
|
-
* on matching with the event's filter.
|
|
44
|
-
*
|
|
45
|
-
* @param array changes
|
|
46
|
-
*
|
|
47
|
-
* @return void
|
|
48
|
-
*/
|
|
49
|
-
fire(changes) {
|
|
50
|
-
if (this.disconnected || (this.params.type && !_any(changes, delta => this.params.type === delta.type))) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const diff = delta => !['set', 'def'].includes(delta.type) || (
|
|
54
|
-
!this.params.diff || (_isFunction(this.params.diff) ? this.params.diff(delta.value, delta.oldValue) : delta.value !== delta.oldValue)
|
|
55
|
-
);
|
|
56
|
-
var evt = new Event(this.target);
|
|
57
|
-
if (this.filters2D.length) {
|
|
58
|
-
var matches = changes.filter(delta => {
|
|
59
|
-
// one observerPathArray can turn out to be two if dynamic
|
|
60
|
-
// OR evt.originatingFields is multiple and this.params.subtree
|
|
61
|
-
return this.filters2D.filter((observerPathArray, i) => {
|
|
62
|
-
var observerPathArray_Resolved = observerPathArray.slice();
|
|
63
|
-
if (this.filtersIsDynamic) {
|
|
64
|
-
// Note that if we had tried to loop thru observerPathArray_Resolved,
|
|
65
|
-
// we wouldn't be able tp access slots that are truly empty, as in: [ 'key', <1 empty item> ]
|
|
66
|
-
delta.path.forEach((_seg, i) => {
|
|
67
|
-
observerPathArray_Resolved[i] = observerPathArray_Resolved[i] || observerPathArray_Resolved[i] === 0
|
|
68
|
-
? observerPathArray_Resolved[i]
|
|
69
|
-
: _seg;
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
return (!this.filtersIsDynamic || !pathsIsDynamic(observerPathArray_Resolved)) && diff(delta) && ((!this.params.subtree && _arrEquals(observerPathArray_Resolved, delta.path))
|
|
73
|
-
|| (this.params.suptree && _arrStartsWith(observerPathArray_Resolved, delta.path) && (!_isNumeric(this.params.suptree) || _arrAfter(observerPathArray_Resolved, delta.path).length <= this.params.suptree))
|
|
74
|
-
|| (this.params.subtree && delta.path.length >= observerPathArray_Resolved.length && _arrStartsWith(delta.path, observerPathArray_Resolved) && (!_isNumeric(this.params.subtree) || _arrAfter(delta.path, observerPathArray_Resolved).length <= this.params.subtree))
|
|
75
|
-
);
|
|
76
|
-
}).length;
|
|
77
|
-
});
|
|
78
|
-
if (matches.length) {
|
|
79
|
-
if (this.filtersIsOriginally2D || this.params.subtree) {
|
|
80
|
-
var changesObject = matches;
|
|
81
|
-
if (_isObject(this.filter)) {
|
|
82
|
-
changesObject = {...this.filter};
|
|
83
|
-
matches.forEach((e, i) => {
|
|
84
|
-
changesObject[e.name] = e;
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
evt.respondWith(this.handler(changesObject, evt));
|
|
88
|
-
} else {
|
|
89
|
-
matches.forEach((e, i) => {
|
|
90
|
-
evt.respondWith(this.handler(e, evt));
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
} else if ((this.params.subtree || changes.filter(delta => _arrEquals(delta.path, [delta.name])).length === changes.length) && changes.filter(delta => diff(delta)).length) {
|
|
95
|
-
evt.respondWith(this.handler(changes, evt));
|
|
96
|
-
}
|
|
97
|
-
return evt;
|
|
98
|
-
}
|
|
99
|
-
}
|
package/src/core/Observers.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import { _from as _arrFrom, _remove, _last } from '@webqit/util/arr/index.js';
|
|
6
|
-
import Firebase from './Firebase.js';
|
|
7
|
-
import Observer from './Observer.js';
|
|
8
|
-
import Mutation from './Mutation.js';
|
|
9
|
-
import Event from './Event.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* ---------------------------
|
|
13
|
-
* The Reactive class
|
|
14
|
-
* ---------------------------
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
export default class Observers extends Firebase {
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Initializes the instance.
|
|
21
|
-
*
|
|
22
|
-
* @param object target
|
|
23
|
-
*
|
|
24
|
-
* @return void
|
|
25
|
-
*/
|
|
26
|
-
constructor(target) {
|
|
27
|
-
super(target);
|
|
28
|
-
this.buffers = [];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* @inheritdoc
|
|
33
|
-
*/
|
|
34
|
-
add(dfn) {
|
|
35
|
-
return super.add(new Observer(this.target, dfn));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Fires all observers with the given evt (change).
|
|
40
|
-
*
|
|
41
|
-
* @param array|Mutation changes
|
|
42
|
-
* @param bool cancellable
|
|
43
|
-
*
|
|
44
|
-
* @return Event
|
|
45
|
-
*/
|
|
46
|
-
fire(changes, cancellable) {
|
|
47
|
-
var evt = new Event(this.target, cancellable);
|
|
48
|
-
// We accept multiple changes
|
|
49
|
-
changes = _arrFrom(changes, false).map(delta => !(delta instanceof Mutation) ? new Mutation(this.target, delta) : delta);
|
|
50
|
-
if (this.buffers.length) {
|
|
51
|
-
_last(this.buffers)(changes);
|
|
52
|
-
return evt;
|
|
53
|
-
}
|
|
54
|
-
if (this.currentlyFiring.filter(d => changes.filter(delta => d.type === delta.type && d.name === delta.name).length).length) {
|
|
55
|
-
//return false;
|
|
56
|
-
}
|
|
57
|
-
//this.currentlyFiring.push(...changes);
|
|
58
|
-
this.fireables.forEach(observer => {
|
|
59
|
-
if (evt.propagationStopped && cancellable) {
|
|
60
|
-
return evt;
|
|
61
|
-
}
|
|
62
|
-
evt.respondWith(observer.fire(changes));
|
|
63
|
-
});
|
|
64
|
-
//changes.forEach(delta => _remove(this.currentlyFiring, delta));
|
|
65
|
-
return evt;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
static getFirebase(target, createIfNotExists = true, namespace = null) {
|
|
69
|
-
return super._getFirebase('observer', ...arguments);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
static namespace(namespace, ImplementationClass = null) {
|
|
73
|
-
return super._namespace('observer', ...arguments);
|
|
74
|
-
}
|
|
75
|
-
}
|
package/src/core/utils.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import { _isArray } from '@webqit/util/js/index.js';
|
|
6
|
-
import { _from as _arrFrom, _all } from '@webqit/util/arr/index.js';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Returns paths in 2-dimensional form.
|
|
11
|
-
*
|
|
12
|
-
* - key => [ [key] ]
|
|
13
|
-
* - [key] => [ [key] ]
|
|
14
|
-
* - [key, key2] => [ [key, key2] ]
|
|
15
|
-
* - [ [key] ] => [ [key] ]
|
|
16
|
-
* - [ [key1, key2] ] => [ [key1, key2] ]
|
|
17
|
-
*
|
|
18
|
-
* @param Array|String paths
|
|
19
|
-
*
|
|
20
|
-
* @return Array
|
|
21
|
-
*/
|
|
22
|
-
export function paths2D(paths) {
|
|
23
|
-
return (pathsIs2D(paths) ? paths : (_arrFrom(paths).length ? [paths] : []))
|
|
24
|
-
.reduce((multiple, path) => multiple.concat([_arrFrom(path)]), [])
|
|
25
|
-
.map(path => DotSafePath.resolve(path));
|
|
26
|
-
}
|
|
27
|
-
export class DotSafePath extends Array {
|
|
28
|
-
static resolve(path) {
|
|
29
|
-
// Note the concat() below...
|
|
30
|
-
// the spread operator: new DotSafePath(...path) doesn't work when path is [0].
|
|
31
|
-
return path.every(v => !(v + '').includes('.')) ? (new DotSafePath).concat(path) : path;
|
|
32
|
-
}
|
|
33
|
-
get dotSafe() { return true }
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* OTHER HELPERS
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
export function pathsIs2D(paths) {
|
|
41
|
-
return _arrFrom(paths).reduce((yes, path) => yes || _isArray(path), false);
|
|
42
|
-
}
|
|
43
|
-
export function pathsIsDynamic(pathArray) {
|
|
44
|
-
// Note that trying to simply match empty slots, as in: pathArray.filter(seg => !seg && seg !== 0).length
|
|
45
|
-
// doesn't work when the empty slots are really empty slote, as in: [ 'key', <1 empty item> ]
|
|
46
|
-
return pathArray.filter(seg => seg || seg === 0).length !== pathArray.length;
|
|
47
|
-
}
|
|
48
|
-
export function paths2DIsDynamic(paths) {
|
|
49
|
-
return paths.filter(pathArray => pathsIsDynamic(_arrFrom(pathArray))).length > 0;
|
|
50
|
-
}
|
|
51
|
-
|
package/src/reactions/closure.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import { _copy } from '@webqit/util/obj/index.js';
|
|
6
|
-
import { _unique } from '@webqit/util/arr/index.js';
|
|
7
|
-
import { _isArray, _isTypeObject } from '@webqit/util/js/index.js';
|
|
8
|
-
import _unproxy from '../actors/unproxy.js';
|
|
9
|
-
import Observers from '../core/Observers.js';
|
|
10
|
-
import unlink from '../connectors/unlink.js';
|
|
11
|
-
import link from '../connectors/link.js';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Executes a callback function on a target in "closure" mode.
|
|
15
|
-
* Fires any observers that may be bound to target on recorded changes.
|
|
16
|
-
*
|
|
17
|
-
* @param function callback
|
|
18
|
-
* @param array ...subjects
|
|
19
|
-
*
|
|
20
|
-
* @return array|Event
|
|
21
|
-
*/
|
|
22
|
-
export default function(callback, ...subjects) {
|
|
23
|
-
var context = subjects.map(target => {
|
|
24
|
-
target = _unproxy(target);
|
|
25
|
-
if (!_isTypeObject(target)) {
|
|
26
|
-
throw new Error('Target must be of type object!');
|
|
27
|
-
}
|
|
28
|
-
return {
|
|
29
|
-
target,
|
|
30
|
-
subjectCopy: _isArray(target) ? target.slice(0) : _copy(target),
|
|
31
|
-
};
|
|
32
|
-
});
|
|
33
|
-
// ---------------------------------
|
|
34
|
-
var result = callback(...subjects);
|
|
35
|
-
// ---------------------------------
|
|
36
|
-
const fireDiffs = () => {
|
|
37
|
-
context.map(cntxt => {
|
|
38
|
-
var initialKeys = Object.keys(cntxt.subjectCopy);
|
|
39
|
-
var currentKeys = Object.keys(cntxt.target);
|
|
40
|
-
var related = [];
|
|
41
|
-
var changes = _unique(initialKeys.concat(currentKeys)).map(key => {
|
|
42
|
-
if (cntxt.subjectCopy[key] !== cntxt.target[key]) {
|
|
43
|
-
related.push(key);
|
|
44
|
-
// ---------------------------------
|
|
45
|
-
// The event object
|
|
46
|
-
var e = {
|
|
47
|
-
name:key,
|
|
48
|
-
related,
|
|
49
|
-
buffered: true,
|
|
50
|
-
};
|
|
51
|
-
if (currentKeys.includes(key)) {
|
|
52
|
-
e.type = 'set';
|
|
53
|
-
e.value = cntxt.target[key];
|
|
54
|
-
if (initialKeys.includes(key)) {
|
|
55
|
-
e.isUpdate = true;
|
|
56
|
-
}
|
|
57
|
-
} else {
|
|
58
|
-
e.type = 'del';
|
|
59
|
-
}
|
|
60
|
-
if (initialKeys.includes(key)) {
|
|
61
|
-
e.oldValue = cntxt.subjectCopy[key];
|
|
62
|
-
}
|
|
63
|
-
// ---------------------------------
|
|
64
|
-
// Unobserve outgoing value for bubbling
|
|
65
|
-
if (_isTypeObject(cntxt.subjectCopy[key])) {
|
|
66
|
-
unlink(cntxt.target, key, cntxt.subjectCopy[key]);
|
|
67
|
-
}
|
|
68
|
-
// Observe incoming value for bubbling
|
|
69
|
-
if (_isTypeObject(cntxt.target[key])) {
|
|
70
|
-
link(cntxt.target, key, cntxt.target[key]);
|
|
71
|
-
}
|
|
72
|
-
return e;
|
|
73
|
-
}
|
|
74
|
-
}).filter(c => c);
|
|
75
|
-
// ---------------------------------
|
|
76
|
-
var observers;
|
|
77
|
-
if (changes.length && (observers = Observers.getFirebase(cntxt.target, false))) {
|
|
78
|
-
return observers.fire(changes);
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
};
|
|
82
|
-
if (result instanceof Promise) {
|
|
83
|
-
result.then(fireDiffs);
|
|
84
|
-
} else {
|
|
85
|
-
fireDiffs();
|
|
86
|
-
}
|
|
87
|
-
return result;
|
|
88
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import { _isFunction, _isTypeObject, _isObject, _getType } from '@webqit/util/js/index.js';
|
|
6
|
-
import _unproxy from '../actors/unproxy.js';
|
|
7
|
-
import Interceptors from '../core/Interceptors.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Adds a trap to an target's firebase.
|
|
11
|
-
*
|
|
12
|
-
* @param array|object target
|
|
13
|
-
* @param object trap
|
|
14
|
-
* @param object params
|
|
15
|
-
*
|
|
16
|
-
* @return Interceptor
|
|
17
|
-
*/
|
|
18
|
-
export default function(target, trap, params = {}) {
|
|
19
|
-
target = _unproxy(target);
|
|
20
|
-
if (!_isTypeObject(target)) {
|
|
21
|
-
throw new Error('Object must be of type target; "' + _getType(handler) + '" given!');
|
|
22
|
-
}
|
|
23
|
-
var returnObj = {}, isOriginallyObj = true;
|
|
24
|
-
if (!_isObject(trap)) {
|
|
25
|
-
// Backwards compatibility
|
|
26
|
-
if (_isFunction(trap)) {
|
|
27
|
-
trap = { '': trap };
|
|
28
|
-
} else if (_isFunction(params)) {
|
|
29
|
-
trap = { [trap]: params };
|
|
30
|
-
params = arguments.length > 3 ? arguments[3] : {};
|
|
31
|
-
}
|
|
32
|
-
isOriginallyObj = false;
|
|
33
|
-
}
|
|
34
|
-
var interceptors = Interceptors.getFirebase(target, true, params.namespace);
|
|
35
|
-
Object.keys(trap).forEach(filter => {
|
|
36
|
-
if (!_isFunction(trap[filter])) {
|
|
37
|
-
throw new Error('Callback' + (filter === null ? '' : ' for ' + filter) + ' must be a function; "' + _getType(trap[filter]) + '" given!');
|
|
38
|
-
}
|
|
39
|
-
var dfn = { filter, handler: trap[filter], params }, existing;
|
|
40
|
-
if (dfn.params.unique && (existing = interceptors.match(dfn)).length) {
|
|
41
|
-
if (dfn.params.unique !== 'replace') {
|
|
42
|
-
return existing[0];
|
|
43
|
-
}
|
|
44
|
-
interceptors.remove(existing[0]);
|
|
45
|
-
}
|
|
46
|
-
if (isOriginallyObj) {
|
|
47
|
-
returnObj[filter] = interceptors.add(dfn);
|
|
48
|
-
} else {
|
|
49
|
-
returnObj = interceptors.add(dfn);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
return returnObj;
|
|
53
|
-
}
|
package/src/reactions/observe.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import { _isFunction, _isTypeObject, _getType } from '@webqit/util/js/index.js';
|
|
6
|
-
import build, { isUserObject } from '../connectors/build.js';
|
|
7
|
-
import _unproxy from '../actors/unproxy.js';
|
|
8
|
-
import Observers from '../core/Observers.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Adds an observer to an target's firebase.
|
|
12
|
-
*
|
|
13
|
-
* @param array|object target
|
|
14
|
-
* @param string|array|function filter
|
|
15
|
-
* @param function handler
|
|
16
|
-
* @param object params
|
|
17
|
-
*
|
|
18
|
-
* @return Observer
|
|
19
|
-
*/
|
|
20
|
-
export default function(target, filter, handler = null, params = {}) {
|
|
21
|
-
target = _unproxy(target);
|
|
22
|
-
if (!target || !_isTypeObject(target)) {
|
|
23
|
-
throw new Error('Observable subjects must be of type object; "' + _getType(target) + '" given!');
|
|
24
|
-
}
|
|
25
|
-
if (_isFunction(filter)) {
|
|
26
|
-
params = arguments.length > 2 ? handler : {};
|
|
27
|
-
handler = filter;
|
|
28
|
-
filter = null;
|
|
29
|
-
}
|
|
30
|
-
if (!_isFunction(handler)) {
|
|
31
|
-
throw new Error('Handler must be a function; "' + _getType(handler) + '" given!');
|
|
32
|
-
}
|
|
33
|
-
var existing, observers = Observers.getFirebase(target, true, params.namespace);
|
|
34
|
-
var dfn = {filter, handler, params,};
|
|
35
|
-
if (dfn.filter || dfn.params.subtree === '*' || (dfn.params.subtree && isUserObject(target))) {
|
|
36
|
-
build(target, dfn.filter, dfn.params.subtree, params.namespace);
|
|
37
|
-
}
|
|
38
|
-
if (dfn.params.unique && (existing = observers.match({filter, params})).length) {
|
|
39
|
-
if (dfn.params.unique !== 'replace') {
|
|
40
|
-
return existing[0];
|
|
41
|
-
}
|
|
42
|
-
observers.remove(existing[0]);
|
|
43
|
-
}
|
|
44
|
-
return observers.add(dfn);
|
|
45
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import { _isFunction, _isTypeObject, _getType } from '@webqit/util/js/index.js';
|
|
6
|
-
import _unproxy from '../actors/unproxy.js';
|
|
7
|
-
import Interceptors from '../core/Interceptors.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Removes traps from an target's firebase.
|
|
11
|
-
*
|
|
12
|
-
* @param array|object target
|
|
13
|
-
* @param object trap
|
|
14
|
-
* @param object params
|
|
15
|
-
*
|
|
16
|
-
* @return void
|
|
17
|
-
*/
|
|
18
|
-
export default function(target, trap = null, params = {}) {
|
|
19
|
-
target = _unproxy(target);
|
|
20
|
-
if (!target || !_isTypeObject(target)) {
|
|
21
|
-
throw new Error('Object must be of type target; "' + _getType(target) + '" given!');
|
|
22
|
-
}
|
|
23
|
-
var interceptors = Interceptors.getFirebase(target, false, params.namespace);
|
|
24
|
-
if (!_isObject(trap)) {
|
|
25
|
-
// Backwards compatibility
|
|
26
|
-
if (_isFunction(trap)) {
|
|
27
|
-
trap = { [null]: trap };
|
|
28
|
-
} else if (_isFunction(params)) {
|
|
29
|
-
trap = { [trap]: params };
|
|
30
|
-
params = arguments.length > 3 ? arguments[3] : {};
|
|
31
|
-
}
|
|
32
|
-
isOriginallyObj = false;
|
|
33
|
-
}
|
|
34
|
-
if (interceptors = Interceptors.getFirebase(target, false, params.namespace)) {
|
|
35
|
-
Object.keys(trap).forEach(filter => {
|
|
36
|
-
if (!_isFunction(trap[filter])) {
|
|
37
|
-
throw new Error('Callback' + (filter === null ? '' : ' for ' + filter) + ' must be a function; "' + _getType(trap[filter]) + '" given!');
|
|
38
|
-
}
|
|
39
|
-
var dfn = { filter, originalHandler: trap[filter], params };
|
|
40
|
-
return interceptors.removeMatches(dfn);
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import { _isFunction, _isTypeObject, _getType } from '@webqit/util/js/index.js';
|
|
6
|
-
import _unproxy from '../actors/unproxy.js';
|
|
7
|
-
import Observers from '../core/Observers.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Removes observers from an target's firebase.
|
|
11
|
-
*
|
|
12
|
-
* @param array|object target
|
|
13
|
-
* @param string|array|function filter
|
|
14
|
-
* @param function originalHandler
|
|
15
|
-
* @param object params
|
|
16
|
-
*
|
|
17
|
-
* @return void
|
|
18
|
-
*/
|
|
19
|
-
export default function(target, filter, originalHandler = null, params = {}) {
|
|
20
|
-
target = _unproxy(target);
|
|
21
|
-
if (!target || !_isTypeObject(target)) {
|
|
22
|
-
throw new Error('Observable subjects must be of type object; "' + _getType(target) + '" given!');
|
|
23
|
-
}
|
|
24
|
-
if (_isFunction(filter)) {
|
|
25
|
-
params = arguments.length > 2 ? originalHandler : {};
|
|
26
|
-
originalHandler = filter;
|
|
27
|
-
filter = null;
|
|
28
|
-
}
|
|
29
|
-
if (originalHandler && !_isFunction(originalHandler)) {
|
|
30
|
-
throw new Error('Handler must be a function; "' + _getType(originalHandler) + '" given!');
|
|
31
|
-
}
|
|
32
|
-
var observers;
|
|
33
|
-
if (observers = Observers.getFirebase(target, false, params.namespace)) {
|
|
34
|
-
return observers.removeMatches({filter, originalHandler, params});
|
|
35
|
-
}
|
|
36
|
-
}
|