@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.
Files changed (58) hide show
  1. package/.gitignore +3 -3
  2. package/LICENSE +20 -20
  3. package/README.md +202 -199
  4. package/dist/main.js +2 -2
  5. package/dist/main.js.map +7 -1
  6. package/package.json +68 -68
  7. package/src/actors.js +175 -0
  8. package/src/core/Descriptor.js +23 -0
  9. package/src/core/ListenerRegistration.js +54 -0
  10. package/src/core/ListenerRegistry.js +41 -0
  11. package/src/core/Registration.js +35 -0
  12. package/src/core/Registry.js +96 -0
  13. package/src/core/TrapsRegistration.js +35 -0
  14. package/src/core/TrapsRegistry.js +51 -0
  15. package/src/index.js +10 -74
  16. package/src/main.js +547 -0
  17. package/src/targets.browser.js +9 -0
  18. package/test/reactions.test.js +326 -337
  19. package/webpack.config.cjs +5 -5
  20. package/src/actions/_exec.js +0 -33
  21. package/src/actions/_setOrDefine.js +0 -136
  22. package/src/actions/apply.js +0 -19
  23. package/src/actions/construct.js +0 -19
  24. package/src/actions/defineProperty.js +0 -20
  25. package/src/actions/deleteProperty.js +0 -80
  26. package/src/actions/get.js +0 -53
  27. package/src/actions/getOwnPropertyDescriptor.js +0 -18
  28. package/src/actions/getPrototypeOf.js +0 -17
  29. package/src/actions/has.js +0 -18
  30. package/src/actions/isExtensible.js +0 -17
  31. package/src/actions/ownKeys.js +0 -17
  32. package/src/actions/preventExtensions.js +0 -17
  33. package/src/actions/set.js +0 -21
  34. package/src/actions/setPrototypeOf.js +0 -18
  35. package/src/actors/accessorize.js +0 -162
  36. package/src/actors/proxy.js +0 -59
  37. package/src/actors/unaccessorize.js +0 -26
  38. package/src/actors/unproxy.js +0 -17
  39. package/src/browser-entry.js +0 -11
  40. package/src/connectors/build.js +0 -64
  41. package/src/connectors/link.js +0 -76
  42. package/src/connectors/unlink.js +0 -35
  43. package/src/core/Action.js +0 -33
  44. package/src/core/Delta.js +0 -46
  45. package/src/core/Event.js +0 -141
  46. package/src/core/Fireable.js +0 -34
  47. package/src/core/Firebase.js +0 -136
  48. package/src/core/Interceptor.js +0 -33
  49. package/src/core/Interceptors.js +0 -61
  50. package/src/core/Mutation.js +0 -46
  51. package/src/core/Observer.js +0 -99
  52. package/src/core/Observers.js +0 -75
  53. package/src/core/utils.js +0 -51
  54. package/src/reactions/closure.js +0 -88
  55. package/src/reactions/intercept.js +0 -53
  56. package/src/reactions/observe.js +0 -45
  57. package/src/reactions/unintercept.js +0 -43
  58. package/src/reactions/unobserve.js +0 -36
@@ -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
- }
@@ -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
- }
@@ -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
- }
@@ -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
- }
@@ -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
-
@@ -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
- }
@@ -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
- }