@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
package/package.json CHANGED
@@ -1,68 +1,68 @@
1
- {
2
- "name": "@webqit/observer",
3
- "title": "Observer",
4
- "description": "A simple set of functions for intercepting and observing JavaScript objects and arrays.",
5
- "keywords": [
6
- "observer",
7
- "reflection",
8
- "interception",
9
- "pub/sub pattern",
10
- "object.observe",
11
- "array.observe",
12
- "events"
13
- ],
14
- "homepage": "https://webqit.io/tooling/observer",
15
- "version": "1.7.6",
16
- "license": "MIT",
17
- "repository": {
18
- "type": "git",
19
- "url": "git+https://github.com/webqit/observer.git"
20
- },
21
- "bugs": {
22
- "url": "https://github.com/webqit/observer/issues"
23
- },
24
- "type": "module",
25
- "sideEffects": false,
26
- "main": "src/index.js",
27
- "scripts": {
28
- "test": "mocha --extension .test.js --exit",
29
- "test:coverage": "c8 --reporter=text-lcov npm run test | coveralls",
30
- "build": "webpack --config ./webpack.config.cjs",
31
- "preversion": "npm run test && npm run build && git add -A dist",
32
- "postversion": "npm publish",
33
- "postpublish": "git push && git push --tags"
34
- },
35
- "dependencies": {
36
- "@webqit/util": "^0.8.7"
37
- },
38
- "devDependencies": {
39
- "chai": "^4.3.4",
40
- "coveralls": "^3.1.1",
41
- "mocha-lcov-reporter": "^1.3.0",
42
- "webpack": "^4.44.1",
43
- "webpack-cli": "^3.3.12"
44
- },
45
- "author": "Oxford Harrison <oxharris.dev@gmail.com>",
46
- "maintainers": [
47
- "Oxford Harrison <oxharris.dev@gmail.com>"
48
- ],
49
- "contributors": [],
50
- "funding": {
51
- "type": "patreon",
52
- "url": "https://patreon.com/ox_harris"
53
- },
54
- "badges": {
55
- "list": [
56
- "npmversion",
57
- "npmdownloads",
58
- "patreon"
59
- ],
60
- "config": {
61
- "patreonUsername": "ox_harris",
62
- "githubUsername": "webqit",
63
- "githubRepository": "observer",
64
- "githubSlug": "webqit/observer",
65
- "npmPackageName": "@webqit/observer"
66
- }
67
- }
68
- }
1
+ {
2
+ "name": "@webqit/observer",
3
+ "title": "Observer",
4
+ "description": "A simple set of functions for intercepting and observing JavaScript objects and arrays.",
5
+ "keywords": [
6
+ "observer",
7
+ "reflection",
8
+ "interception",
9
+ "pub/sub pattern",
10
+ "object.observe",
11
+ "array.observe",
12
+ "events"
13
+ ],
14
+ "homepage": "https://webqit.io/tooling/observer",
15
+ "version": "2.0.0",
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/webqit/observer.git"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/webqit/observer/issues"
23
+ },
24
+ "type": "module",
25
+ "sideEffects": false,
26
+ "main": "src/index.js",
27
+ "scripts": {
28
+ "test": "mocha --extension .test.js --exit",
29
+ "test:coverage": "c8 --reporter=text-lcov npm run test | coveralls",
30
+ "build": "esbuild main=src/targets.browser.js --bundle --minify --sourcemap --outdir=dist",
31
+ "preversion": "npm run test && npm run build && git add -A dist",
32
+ "postversion": "npm publish",
33
+ "postpublish": "git push && git push --tags"
34
+ },
35
+ "dependencies": {
36
+ "@webqit/util": "^0.8.7"
37
+ },
38
+ "devDependencies": {
39
+ "chai": "^4.3.4",
40
+ "coveralls": "^3.1.1",
41
+ "esbuild": "^0.17.9",
42
+ "mocha": "^10.2.0",
43
+ "mocha-lcov-reporter": "^1.3.0"
44
+ },
45
+ "author": "Oxford Harrison <oxharris.dev@gmail.com>",
46
+ "maintainers": [
47
+ "Oxford Harrison <oxharris.dev@gmail.com>"
48
+ ],
49
+ "contributors": [],
50
+ "funding": {
51
+ "type": "patreon",
52
+ "url": "https://patreon.com/ox_harris"
53
+ },
54
+ "badges": {
55
+ "list": [
56
+ "npmversion",
57
+ "npmdownloads",
58
+ "patreon"
59
+ ],
60
+ "config": {
61
+ "patreonUsername": "ox_harris",
62
+ "githubUsername": "webqit",
63
+ "githubRepository": "observer",
64
+ "githubSlug": "webqit/observer",
65
+ "npmPackageName": "@webqit/observer"
66
+ }
67
+ }
68
+ }
package/src/actors.js ADDED
@@ -0,0 +1,175 @@
1
+
2
+ /**
3
+ * @imports
4
+ */
5
+ import { _from as _arrFrom } from '@webqit/util/arr/index.js';
6
+ import { _isClass, _isFunction, _isTypeObject, _getType, _internals } from '@webqit/util/js/index.js';
7
+ import { set, deleteProperty, has, get, ownKeys, defineProperty, getOwnPropertyDescriptor } from "./main.js";
8
+ import { apply, construct, getPrototypeOf, setPrototypeOf, isExtensible, preventExtensions } from "./main.js";
9
+
10
+ /* ---------------ACCESSORIZE METHODS--------------- */
11
+
12
+ /**
13
+ * Accessorizes props.
14
+ *
15
+ * @param Array|Object target
16
+ * @param String|Array props
17
+ * @param Object params
18
+ *
19
+ * @return Array
20
+ */
21
+ export function accessorize( target, props, params = {} ) {
22
+ target = resolveTarget( target );
23
+ const accessorizedProps = _internals( target, 'accessorizedProps' );
24
+ // ---------
25
+ function getDescriptorDeep( prop ) {
26
+ let descriptor, proto = target;
27
+ while ( !descriptor && ( proto = Object.getPrototypeOf( proto ) ) ) {
28
+ descriptor = Object.getOwnPropertyDescriptor( proto, prop );
29
+ }
30
+ return descriptor
31
+ ? { proto, descriptor }
32
+ : { descriptor: { value: undefined } };
33
+ }
34
+ // ---------
35
+ function accessorizeProp( prop ) {
36
+ if ( accessorizedProps.has( prop ) ) return true;
37
+ // ------------------
38
+ // Current Descriptor Record
39
+ const currentDescriptorRecord = getDescriptorDeep( prop );
40
+ currentDescriptorRecord.getValue = function() {
41
+ return 'get' in this.descriptor ? this.descriptor.get() : this.descriptor.value;
42
+ };
43
+ currentDescriptorRecord.setValue = function( value ) {
44
+ return 'set' in this.descriptor ? this.descriptor.set( value ) : ( this.descriptor.value = value )
45
+ };
46
+ currentDescriptorRecord.intact = function() {
47
+ const currentDescriptor = Object.getOwnPropertyDescriptor( target, prop );
48
+ return currentDescriptor.get === accessorization.get
49
+ && currentDescriptor.set === accessorization.set
50
+ && accessorizedProps.get( prop ) === this;
51
+ };
52
+ currentDescriptorRecord.restore = function() {
53
+ if ( !this.intact() ) return false;
54
+ if ( this.proto !== target ) { delete target[ prop ]; }
55
+ else { Object.defineProperty( target, prop, this.descriptor ); }
56
+ accessorizedProps.delete( prop );
57
+ return true;
58
+ };
59
+ accessorizedProps.set( prop, currentDescriptorRecord );
60
+ // ------------------
61
+ // enumerable, configurable
62
+ const { enumerable = true, configurable = true } = currentDescriptorRecord.descriptor;
63
+ const accessorization = { enumerable, configurable };
64
+ // set, get
65
+ if ( [ 'value', 'set' ].some( x => x in currentDescriptorRecord.descriptor ) ) {
66
+ accessorization.set = function ( value ) { return set( this, prop, value, params ); };
67
+ }
68
+ if ( [ 'value', 'get' ].some( x => x in currentDescriptorRecord.descriptor ) ) {
69
+ accessorization.get = function () { return get( this, prop, params ); };
70
+ }
71
+ try {
72
+ Object.defineProperty( target, prop, accessorization );
73
+ return true;
74
+ } catch( e ) {
75
+ accessorizedProps.delete( prop );
76
+ return false;
77
+ }
78
+ }
79
+ const _props = Array.isArray( props ) ? props : (
80
+ props === undefined ? Object.keys( target ) : [ props ]
81
+ );
82
+ const statuses = _props.map( accessorizeProp );
83
+ return props === undefined || Array.isArray( props )
84
+ ? statuses
85
+ : statuses[ 0 ];
86
+ }
87
+
88
+ /**
89
+ * Unaccessorizes previously accessorized props.
90
+ *
91
+ * @param Array|Object target
92
+ * @param String|Array props
93
+ * @param Object params
94
+ *
95
+ * @return Array
96
+ */
97
+ export function unaccessorize( target, props, params = {} ) {
98
+ target = resolveTarget( target );
99
+ const accessorizedProps = _internals( target, 'accessorizedProps' );
100
+ function unaccessorizeProp( prop ) {
101
+ if ( !accessorizedProps.has( prop ) ) return true;
102
+ return accessorizedProps.get( prop ).restore();
103
+ }
104
+ const _props = Array.isArray( props ) ? props : (
105
+ props === undefined ? Object.keys( target ) : [ props ]
106
+ );
107
+ const statuses = _props.map( unaccessorizeProp );
108
+ return props === undefined || Array.isArray( props )
109
+ ? statuses
110
+ : statuses[ 0 ];
111
+ }
112
+
113
+ /* ---------------PROXY METHODS--------------- */
114
+
115
+ /**
116
+ * Returns an object as a proxy and binds all instance methods
117
+ * to the proxy instead of the object itself.
118
+ *
119
+ * @param Array|Object target
120
+ * @param Object params
121
+ *
122
+ * @return Proxy
123
+ */
124
+ export function proxy( target, params = {} ) {
125
+ target = resolveTarget( target );
126
+ const proxy = new Proxy( target, {
127
+ apply: ( target, thisArgument, argumentsList ) => apply( target, thisArgument, argumentsList, params ),
128
+ construct: ( target, argumentsList, newTarget = null ) => construct( target, argumentsList, newTarget, params ),
129
+ defineProperty: ( target, propertyKey, attributes ) => defineProperty( target, propertyKey, attributes, params ),
130
+ deleteProperty: ( target, propertyKey ) => deleteProperty( target, propertyKey, params ),
131
+ get: ( target, propertyKey, receiver = null ) => {
132
+ const val = get( target, propertyKey, { ...params, receiver } );
133
+ if ( params.proxyAutoBinding !== false && _isFunction( val ) && !_isClass( val )) {
134
+ return val.bind( proxy );
135
+ }
136
+ return val;
137
+ },
138
+ getOwnPropertyDescriptor: ( target, propertyKey ) => getOwnPropertyDescriptor( target, propertyKey, params ),
139
+ getPrototypeOf: target => getPrototypeOf( target, params ),
140
+ has: ( target, propertyKey ) => has( target, propertyKey, params ),
141
+ isExtensible: target => isExtensible( target, params ),
142
+ ownKeys: target => ownKeys( target, params ),
143
+ preventExtensions: target => preventExtensions( target, params ),
144
+ set: ( target, propertyKey, value, receiver = null ) => set( target, propertyKey, value, { ...params, receiver } ),
145
+ setPrototypeOf: ( target, prototype ) => setPrototypeOf( target, prototype, params ),
146
+ });
147
+ _internals( proxy ).set( proxy, target );
148
+ return proxy;
149
+ }
150
+
151
+ /**
152
+ * Returns the original object earlier proxied by proxy().
153
+ *
154
+ * @param Proxy|Any target
155
+ *
156
+ * @return Any
157
+ */
158
+ export function unproxy( target ) {
159
+ // Proxy targets are mapped to their own instances internally
160
+ return _internals( target, false ).get( target ) || target;
161
+ }
162
+
163
+ /* ---------------HELPERS--------------- */
164
+
165
+ /**
166
+ * Ensures target object is an object or array.
167
+ *
168
+ * @param Array|Object target
169
+ *
170
+ * @return Array|Object
171
+ */
172
+ function resolveTarget( target ) {
173
+ if ( !target || !_isTypeObject( target ) ) throw new Error('Target must be of type object!');
174
+ return unproxy( target );
175
+ }
@@ -0,0 +1,23 @@
1
+
2
+ /**
3
+ * ---------------------------
4
+ * The Descriptor class
5
+ * ---------------------------
6
+ */
7
+
8
+ export default class Descriptor {
9
+
10
+ /**
11
+ * Initializes the instance.
12
+ *
13
+ * @param array|object target
14
+ * @param object dfn
15
+ *
16
+ * @return void
17
+ */
18
+ constructor( target, dfn ) {
19
+ this.target = target;
20
+ if ( !( dfn.type ) ) throw new Error( 'Descriptor type must be given in definition!' );
21
+ Object.assign( this, dfn );
22
+ }
23
+ }
@@ -0,0 +1,54 @@
1
+
2
+ /**
3
+ * @imports
4
+ */
5
+ import { _from as _arrFrom } from '@webqit/util/arr/index.js';
6
+ import Registration from './Registration.js';
7
+
8
+ /**
9
+ * ---------------------------
10
+ * The ListenerRegistration class
11
+ * ---------------------------
12
+ */
13
+
14
+ export default class ListenerRegistration extends Registration {
15
+
16
+ /**
17
+ * @constructor
18
+ */
19
+ constructor() {
20
+ super( ...arguments );
21
+ Object.defineProperty( this, 'abortController', { value: new AbortController } );
22
+ Object.defineProperty( this, 'signal', { value: this.abortController.signal } );
23
+ }
24
+
25
+ /**
26
+ * De-registers the instance.
27
+ *
28
+ * @return Void
29
+ */
30
+ remove() {
31
+ this.abortController.abort();
32
+ super.remove();
33
+ }
34
+
35
+ /**
36
+ * Calls the observer's handler function
37
+ * on matching with the event's fields.
38
+ *
39
+ * @param Array events
40
+ *
41
+ * @return Any
42
+ */
43
+ fire( events ) {
44
+ let matches = events, filter = this.filter;
45
+ if ( filter !== Infinity && ( filter = _arrFrom( filter ) ) ) {
46
+ matches = events.filter( event => filter.includes( event.key ) );
47
+ }
48
+ if ( matches.length ) {
49
+ return this.filter === Infinity || Array.isArray( this.filter )
50
+ ? this.handler( matches, this )
51
+ : this.handler( matches[ 0 ], this );
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,41 @@
1
+
2
+ /**
3
+ * @imports
4
+ */
5
+ import ListenerRegistration from './ListenerRegistration.js';
6
+ import Registry from './Registry.js';
7
+
8
+ /**
9
+ * ---------------------------
10
+ * The ListenerRegistry class
11
+ * ---------------------------
12
+ */
13
+
14
+ export default class ListenerRegistry extends Registry {
15
+
16
+ static getInstance( target, createIfNotExists = true, namespace = null ) {
17
+ return super._getInstance( 'listeners', ...arguments );
18
+ }
19
+
20
+ static namespace( namespace, ImplementationClass = null ) {
21
+ return super._namespace( 'listeners', ...arguments );
22
+ }
23
+
24
+ /**
25
+ * @inheritdoc
26
+ */
27
+ addRegistration( filter, handler, params ) {
28
+ return super.addRegistration( new ListenerRegistration( this, { filter, handler, params } ) );
29
+ }
30
+
31
+ /**
32
+ * Fires all observers with the given evt (change).
33
+ *
34
+ * @param Arrayn events
35
+ *
36
+ * @return Void
37
+ */
38
+ emit( events ) {
39
+ this.entries.forEach( listener => listener.fire( events ) );
40
+ }
41
+ }
@@ -0,0 +1,35 @@
1
+
2
+ /**
3
+ * ---------------------------
4
+ * The Registration class
5
+ * ---------------------------
6
+ */
7
+
8
+ export default class Registration {
9
+
10
+ /**
11
+ * Initializes the instance.
12
+ *
13
+ * @param Registry registry
14
+ * @param object dfn
15
+ *
16
+ * @return void
17
+ */
18
+ constructor( registry, dfn ) {
19
+ this.registry = registry;
20
+ Object.assign( this, { ...dfn, target: registry.target } );
21
+ if ( this.params.signal ) {
22
+ this.params.signal.addEventListener( 'abort', () => this.remove() );
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Sets a "disconnected" flag on the Registration.
28
+ *
29
+ * @return void
30
+ */
31
+ remove() {
32
+ this.removed = true;
33
+ return this.registry.removeRegistration( this );
34
+ }
35
+ }
@@ -0,0 +1,96 @@
1
+
2
+ /**
3
+ * @imports
4
+ */
5
+ import { _isTypeObject, _getType, _internals } from '@webqit/util/js/index.js';
6
+ import { _from as _arrFrom, _intersect, _equals as _arrEquals } from '@webqit/util/arr/index.js';
7
+
8
+ /**
9
+ * ---------------------------
10
+ * The Registry class
11
+ * ---------------------------
12
+ */
13
+
14
+ export default class Registry {
15
+
16
+ /**
17
+ * Initializes the instance.
18
+ *
19
+ * @param object target
20
+ *
21
+ * @return void
22
+ */
23
+ constructor( target ) {
24
+ this.target = target;
25
+ this.entries = [];
26
+ }
27
+
28
+ /**
29
+ * Adds an Registration instance
30
+ * with optional tags.
31
+ *
32
+ * @param Registration registration
33
+ *
34
+ * @return Registration
35
+ */
36
+ addRegistration( registration ) {
37
+ this.entries.push( registration );
38
+ return registration;
39
+ }
40
+
41
+ /**
42
+ * Removes registrations by reference.
43
+ *
44
+ * @param Registration registration
45
+ *
46
+ * @return void
47
+ */
48
+ removeRegistration( registration ) {
49
+ this.entries = this.entries.filter( _entry => _entry !== registration );
50
+ }
51
+
52
+ /**
53
+ * Returns a observer-specific object embedded on an element.
54
+ *
55
+ * @param string type
56
+ * @param array|object target
57
+ * @param bool createIfNotExists
58
+ * @param string namespace
59
+ *
60
+ * @return Registry
61
+ */
62
+ static _getInstance( type, target, createIfNotExists = true, namespace = this.__namespace ) {
63
+ if ( !_isTypeObject( target ) ) throw new Error( `Subject must be of type object; "${ _getType( target ) }" given!` );
64
+ let ImplementationClass = this;
65
+ if ( namespace && globalThis.WebQitObserverNamespaceRegistry.has( type + '-' + namespace ) ) {
66
+ ImplementationClass = globalThis.WebQitObserverNamespaceRegistry.get( type + '-' + namespace );
67
+ type += '-' + namespace
68
+ }
69
+ if ( !_internals( target, 'observerApi' ).has( type ) && createIfNotExists ) {
70
+ _internals( target, 'observerApi' ).set( type, new ImplementationClass( target ) );
71
+ }
72
+ return _internals( target, 'observerApi' ).get( type );
73
+ }
74
+
75
+ /**
76
+ * Extend a Fireable Class with a namespace.
77
+ *
78
+ * @param string namespace
79
+ * @param class ImplementationClass
80
+ *
81
+ * @return void|class
82
+ */
83
+ static _namespace( type, namespace, ImplementationClass = null ) {
84
+ type += '-' + namespace;
85
+ if ( arguments.length === 2 ) return globalThis.WebQitObserverNamespaceRegistry.get( type );
86
+ if ( !( ImplementationClass.prototype instanceof this ) ) {
87
+ throw new Error( `The implementation of the namespace ${ this.name }.${ namespace } must be a subclass of ${ this.name }.` );
88
+ }
89
+ globalThis.WebQitObserverNamespaceRegistry.set( type, ImplementationClass );
90
+ ImplementationClass.__namespace = namespace;
91
+ }
92
+ }
93
+
94
+ if ( !globalThis.WebQitObserverNamespaceRegistry ) {
95
+ globalThis.WebQitObserverNamespaceRegistry = new Map;
96
+ }
@@ -0,0 +1,35 @@
1
+
2
+ /**
3
+ * @imports
4
+ */
5
+ import Registration from './Registration.js';
6
+
7
+ /**
8
+ * ---------------------------
9
+ * The TrapsRegistration class
10
+ * ---------------------------
11
+ */
12
+
13
+ export default class TrapsRegistration extends Registration {
14
+
15
+ /**
16
+ * Calls the observer's handler function
17
+ * on matching with the descriptor's fields.
18
+ *
19
+ * @param Descriptor descriptor
20
+ * @param function next
21
+ * @param mixed recieved
22
+ *
23
+ * @return void
24
+ */
25
+ exec( descriptor, next, recieved ) {
26
+ if ( this.running || !this.traps[ descriptor.type ] ) {
27
+ return next( ...Array.prototype.slice.call( arguments, 2 ) );
28
+ }
29
+ this.running = true;
30
+ return this.traps[ descriptor.type ]( descriptor, recieved, ( ...args ) => {
31
+ this.running = false;
32
+ return next( ...args );
33
+ } );
34
+ }
35
+ }
@@ -0,0 +1,51 @@
1
+
2
+ /**
3
+ * @imports
4
+ */
5
+ import TrapsRegistration from './TrapsRegistration.js';
6
+ import Registry from './Registry.js';
7
+
8
+ /**
9
+ * ---------------------------
10
+ * The TrapsRegistry class
11
+ * ---------------------------
12
+ */
13
+
14
+ export default class TrapsRegistry extends Registry {
15
+
16
+ static getInstance( target, createIfNotExists = true, namespace = null ) {
17
+ return super._getInstance( 'traps', ...arguments );
18
+ }
19
+
20
+ static namespace( namespace, ImplementationClass = null ) {
21
+ return super._namespace( 'traps', ...arguments );
22
+ }
23
+
24
+ /**
25
+ * @inheritdoc
26
+ */
27
+ addRegistration( dfn ) {
28
+ return super.addRegistration( new TrapsRegistration( this, dfn ) );
29
+ }
30
+
31
+ /**
32
+ * Fires all interceptors with the given action.
33
+ *
34
+ * @param Descriptor descriptor
35
+ * @param function defaultHandler
36
+ *
37
+ * @return mixed
38
+ */
39
+ emit( descriptor, defaultHandler = null ) {
40
+ const $this = this;
41
+ return ( function next( index, ..._args ) {
42
+ const registration = $this.entries[ index ];
43
+ if ( registration ) {
44
+ return registration.exec( descriptor, ( ...args ) => {
45
+ return next( index + 1, ...args );
46
+ }/*next*/, ..._args );
47
+ }
48
+ return defaultHandler ? defaultHandler( descriptor, ..._args ) : _args[ 0 ];
49
+ } )( 0 );
50
+ }
51
+ }