assemblerjs 0.7.6 → 0.8.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/README.md +1 -1
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +129 -16
- package/dist/index.js +921 -1
- package/package.json +28 -41
- package/dist/index.mjs +0 -975
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A general purpose and zero-dependency [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) library for node and browser.
|
|
4
4
|
|
|
5
|
-
   
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="design:paramtypes";var t,n;(t||(t={})).IsAssemblage="is_assemblage",(n||(n={})).AssemblageDefinition="assemblage:definition.value";const s=(...e)=>{},i=(...e)=>t=>{if(e.includes(typeof t))return typeof t},r=e=>!(e=>void 0===e)(e)&&!(e=>null===e)(e),o=e=>e&&"function"==typeof e&&void 0!==e.constructor,a=e=>"function"==typeof e&&"AsyncFunction"===e.constructor.name,c=(e,...t)=>{t.map(((e,n)=>{const s=/\S/.test(e);return s&&(t[n]=t[n].trim()),s?-1:n})).filter((e=>e>=0)).every((e=>{t[e]=" ",((e,t,n)=>{const s=e[t];e.splice(t,1),e.splice(n,0,s)})(t,e,t.length-1)})),t=(e=>Array.from(new Set(e)))(t);const n=new RegExp(`[^A-Za-zÀ-ÖØ-öø-ÿ0-9${t.join("")}]`,"gi");return e.replace(n,"")},l=(...e)=>t=>e.reduce(((e,t)=>t(e)),t),h=e=>t=>e.if(t)?e.then(t):e.else?e.else(t):void 0,f=e=>t=>{const n=Array.isArray(e)?e=>parseInt(e):s;for(const[s,i]of Object.entries(e))t(i,n(s))},u=(e,t)=>{const n=new Proxy(e,{get:function(n,s){return s===Symbol.iterator?n[Symbol.iterator].bind(n):((e,t)=>[...Object.getOwnPropertyNames(t.prototype),...Object.getOwnPropertyNames(Object.getPrototypeOf(e)),...Object.getOwnPropertyNames(e)])(e,t).includes(s)?n[s]:n.collection[s]},set:function(e,t,n){return Reflect.set(e,t,n)}});return n},p=(e,t)=>{const n=e;for(const s of((e,t)=>[...Object.getOwnPropertyNames(t.prototype),...Object.getOwnPropertyNames(Object.getPrototypeOf(e)),...Object.getOwnPropertyNames(e)])(e,t))delete n[s]},d=(e,t,n)=>{Reflect.defineMetadata(`__${e}__`,t,n)},g=(e,t)=>Reflect.getOwnMetadata(`__${e}__`,t),m=t=>Reflect.getMetadata(e,t)||[],x=e=>g(t.IsAssemblage,e)||!1,b={singleton:{test:e=>"boolean"==typeof e||void 0===e,throw:()=>{throw new Error("'singleton' property must be of type 'boolean' or 'undefined'.")},transform:e=>void 0===e||!!e},events:{test:e=>void 0===e||Array.isArray(e)&&e.every((e=>"string"==typeof e)),throw:()=>{throw new Error("'events' property must be an array of strings or 'undefined'.")},transform:e=>e},inject:{test:e=>void 0===e||Array.isArray(e)&&e.every((e=>Array.isArray(e)&&e.length>=1&&e.length<=3)),throw:()=>{throw new Error("'inject' property must be an array of tuples of length 1, 2 or 3.")},transform:e=>e},use:{test:e=>void 0===e||Array.isArray(e)&&e.every((e=>Array.isArray(e)&&2==e.length)),throw:()=>{throw new Error("'use' property must be an array of tuples of length 2.")},transform:e=>e},tags:{test:e=>void 0===e||"string"==typeof e||Array.isArray(e)&&e.every((e=>"string"==typeof e)),throw:()=>{throw new Error("'tags' property must be a string or an array of strings.")},transform:e=>"string"==typeof e?[e]:e},metadata:{test:e=>("object"==typeof e||void 0===e)&&!Array.isArray(e),throw:()=>{throw new Error("'metadata' property must be of type 'object' or 'undefined'.")},transform:e=>e}},y=e=>{const t={...e};for(const n in t)if(!Object.keys(b).includes(n))throw new Error(`Property '${n}' is not a valid assemblage definition property.`);for(const n in b){const e=b[n].test,s=b[n].throw,i=b[n].transform;e(t[n])||s(),t[n]=i(t[n])}return t},C=e=>{if(!x(e))throw new Error(`Class '${e.name}' is not an assemblage.`);return g(n.AssemblageDefinition,e)},v=(e,t)=>C(t)[e],w=e=>{const t=()=>o(e[0])&&(e=>"object"==typeof e&&!Array.isArray(e)&&!o(e))(e[1]);return l(h({if:()=>o(e[0])&&o(e[1]),then:()=>({identifier:e[0],concrete:e[1],configuration:{}})}),h({if:()=>t(),then:()=>({identifier:e[0],concrete:e[0],configuration:e[1]}),else:e=>e}))()},I=(e,s)=>{const i=y(s||{});return d(t.IsAssemblage,!0,e),d(n.AssemblageDefinition,i,e),e};class j{dispose(){p(this,j)}add(...e){const t=e=>this.collection[e.channel].push(e.listener),n=h({if:()=>2===e.length,then:()=>({channel:e[0],listener:e[1]}),else:()=>{const t=e[0];return{channel:t[0],listener:t[1]}}}),s=h({if:e=>!r(this.collection[e.channel]),then:e=>{this.collection[e.channel]=[],t(e)},else:e=>{t(e)}});return l(n,s)(),this}remove(e,t){const n=t=>this.collection[e].splice(t,1),s=h({if:()=>this.collection[e]&&0===this.collection[e].length,then:()=>delete this.collection[e]}),i=h({if:()=>r(t),then:()=>n(this.collection[e].indexOf(t)),else:()=>delete this.collection[e]}),o=h({if:e=>this.has(e),then:e=>this.collection[e]});return l(o,i,s)(),this}has(...e){return i("string")(e[0])?Object.keys(this.collection).includes(e[0]):!!i("function")(e[0])&&Object.values(this.collection).flat().includes(e[0])}get(...e){return i("string")(e[0])?this.collection[e[0]]:i("function")(e[0])?Object.values(this.collection).flat().filter((t=>t===e[0])):[]}clear(){const e=(e=>t=>{const n=Array.isArray(e)?e=>parseInt(e):e=>e;for(const s in e)t(n(s))})(this.collection),t=e=>f(this.collection[e])((t=>this.remove(e,t)));return e((e=>t(e))),this}get listeners(){return Object.values(this.collection).flat()}get channels(){return Object.keys(this.collection)}get length(){return Object.values(this.collection).flat().length}[Symbol.iterator](){let e=-1;const t=this.collection?Object.keys(this.collection):[];return{next:()=>({value:t[++e],done:!(e in t)})}}constructor(){this.collection={};return u(this,j)}}class A{}class P{dispose(){this.listeners.dispose(),this.channels.clear(),p(this,P)}addChannels(...e){return f(e)((e=>{const t=this.cleanChannel(e);if(this.channels.has(t))throw new Error(`Channel '${t}' already exists.`);this.channels.add(t)})),this}removeChannels(...e){return f(e)((e=>{const t=this.cleanChannel(e);"*"!==t&&this.channels.has(t)&&(this.channels.delete(t),this.listeners.remove(t),this.onceListeners.remove(t))})),this}on(e,t){const n=this.cleanChannel(e);if(!this.channels.has(n))throw new Error(`Channel '${n}' was not registered.`);return this.listeners.add(n,t),this}once(e,t){const n=this.cleanChannel(e);if(!this.channels.has(n))throw new Error(`Channel '${n}' was not registered.`);return this.onceListeners.add(n,t),this}off(e,t){const n=this.cleanChannel(e);return this.listeners.remove(n,t),this}emit(e,...t){const n=this.cleanChannel(e);if(this.channels.has(n)){const e=this.onceListeners.get("*")||[],s=this.listeners.get("*")||[],i=this.onceListeners.get(n)||[],r=this.listeners.get(n)||[],o=f(e),a=f(s),c=f(i),l=f(r);o((e=>{this.run(e,...t),this.onceListeners.remove("*",e)})),a((e=>{this.run(e,...t)})),c((e=>{this.run(e,...t),this.onceListeners.remove(n,e)})),l((e=>{this.run(e,...t)}))}return this}run(e,...t){if(a(e)){return e(...t).then((()=>Promise.resolve()))}e(...t)}cleanChannel(e){return c(e,"*")}constructor(...e){this.listeners=new j,this.onceListeners=new j,this.channels=new Set(["*"]),this.addChannels(...e)}}exports.ReflectParamValue=void 0,(exports.ReflectParamValue||(exports.ReflectParamValue={})).UseIdentifier="assemblage:use.param.value",exports.ReflectParamIndex=void 0,function(e){e.Context="assembler:context.param.index",e.Dispose="assembler:dispose.param.index",e.Definition="assemblage:definition.param.index",e.Configuration="assemblage:configuration.param.index",e.Use="assemblage:use.param.index"}(exports.ReflectParamIndex||(exports.ReflectParamIndex={}));const R=e=>()=>(t,n,s)=>{const i=g(e,t)||[];i.push(s),d(e,i,t)},O=R(exports.ReflectParamIndex.Context),D=R(exports.ReflectParamIndex.Configuration),E=R(exports.ReflectParamIndex.Definition),U=R(exports.ReflectParamIndex.Dispose),S=(e,t,n)=>{const s=g(exports.ReflectParamIndex.Use,t)||[];s.push(n),d(exports.ReflectParamIndex.Use,s,t);const i=g(exports.ReflectParamValue.UseIdentifier,t)||{};i[n]=e,d(exports.ReflectParamValue.UseIdentifier,i,t)},$=e=>{const t=(e=>g(exports.ReflectParamIndex.Context,e)||[])(e)||[],n=(e=>g(exports.ReflectParamIndex.Definition,e)||[])(e)||[],s=(e=>g(exports.ReflectParamIndex.Configuration,e)||[])(e)||[],i=(e=>g(exports.ReflectParamIndex.Dispose,e)||[])(e)||[],r=(e=>g(exports.ReflectParamIndex.Use,e)||[])(e)||[];return{Context:t,Definition:n,Configuration:s,Dispose:i,Use:r}},L=(t,s=!0)=>i=>{const r=class extends i{constructor(...e){super(...e),t&&t.call(this)}};if(Object.defineProperty(r,"name",{value:i.name}),!s)return r;const o=Reflect.getOwnMetadata(e,i)||[],a=$(i),c=[];for(let e=0;e<o.length;e++)if(a.Context.includes(e)){const t=g(exports.ReflectParamIndex.Context,i)||[];t.push(e),d(exports.ReflectParamIndex.Context,t,r)}else if(a.Definition.includes(e)){const t=g(exports.ReflectParamIndex.Definition,i)||[];t.push(e),d(exports.ReflectParamIndex.Definition,t,r)}else if(a.Configuration.includes(e)){const t=g(exports.ReflectParamIndex.Configuration,i)||[];t.push(e),d(exports.ReflectParamIndex.Configuration,t,r)}else if(a.Dispose.includes(e)){const t=g(exports.ReflectParamIndex.Dispose,i)||[];t.push(e),d(exports.ReflectParamIndex.Dispose,t,r),c.push(o[e])}else if(a.Use.includes(e)){const t=g(exports.ReflectParamValue.UseIdentifier,i);S(t[e],r,e)}else;return s?I(r,g(n.AssemblageDefinition,i)):r};class M{static of(e,t,n){return new M(e,t,n)}dispose(){this.singletonInstance&&(((e,t)=>{if(e.concrete.prototype instanceof P){const n=t;for(const t of e.events)n.off(t);n.removeChannels(...e.events),e.privateContext.removeChannels(...e.events)}})(this,this.singletonInstance),_(this.singletonInstance,"onDispose",this.publicContext,this.configuration),p(this.singletonInstance,this.concrete)),p(this,M)}build(){if(this.singletonInstance)return this.singletonInstance;const e=(e=>{const t=[],n=m(e.concrete),s=$(e.concrete);let i=0;for(const r of n)if(s.Context.includes(i))t.push(e.publicContext),i++;else if(s.Configuration.includes(i))t.push(e.configuration),i++;else if(s.Definition.includes(i))t.push(e.definition),i++;else if(s.Dispose.includes(i))t.push(e.privateContext.dispose),i++;else if(s.Use.includes(i)){const n=g(exports.ReflectParamValue.UseIdentifier,e.concrete)[i];t.push(e.privateContext.require(n)),i++}else t.push(e.privateContext.require(r)),i++;return t})(this),t=new this.concrete(...e);return((e,t)=>{if(e.concrete.prototype instanceof P){const n=t,s=n.channels;for(const t of e.events)s.has(t)||n.addChannels(t),e.privateContext.events.has(t)||e.privateContext.addChannels(t);for(const i of e.events)t.on(i,((...t)=>{e.privateContext.emit(i,...t)}))}})(this,t),this.isSingleton?(this.singletonInstance=t,this.privateContext.prepareInitHook(t,this.configuration),this.singletonInstance):(_(t,"onInit",this.publicContext),t)}get dependencies(){return this.dependenciesIds}get definition(){return C(this.concrete)||{}}get isSingleton(){return v("singleton",this.concrete)}get singleton(){return this.singletonInstance}get injections(){return v("inject",this.concrete)||[]}get objects(){return v("use",this.concrete)||[]}get tags(){return v("tags",this.concrete)||[]}get events(){return v("events",this.concrete)||[]}constructor(e,t,n){if(this.privateContext=t,this.publicContext=n,this.dependenciesIds=[],this.identifier=e.identifier,this.concrete=e.concrete,this.configuration=e.configuration,!x(this.concrete))throw new Error(`Class '${this.concrete.name}' is not an Assemblage.`);const s=f(this.injections),i=f(this.objects);s((e=>this.privateContext.register(e))),i((e=>{"string"==typeof e[0]||"symbol"==typeof e[0]?this.privateContext.use(e[0],e[1]):this.privateContext.register(e,!0)})),this.dependenciesIds=(e=>{const t=[],n=m(e),s=$(e);let i=0;for(const r of n)s.Context.includes(i)||s.Configuration.includes(i)||s.Definition.includes(i)||s.Dispose.includes(i)||s.Use.includes(i)||t.push(r),i++;return t})(this.concrete),e.instance?this.singletonInstance=e.instance:this.isSingleton}}const _=(e,t,n,s)=>new Promise((i=>{const r=e[t];if(r){if(a(r))return void r.bind(e)(n,s).then((()=>{i()}));i(r.bind(e)(n,s))}}));class k extends P{static build(e){const t=new k;((e,t,s)=>{const i=C(s);i[e]=t;const r=y(i);d(n.AssemblageDefinition,r,s)})("singleton",!0,e);const s=t.register([e]),i=t.require(s.identifier),r=t.initCache.find((e=>e.instance===i));if(!r)throw new Error("Root instance not found in assemblages cache.");const o=t.initCache.indexOf(r);t.initCache.splice(o,1);for(const n of t.initCache)_(n.instance,"onInit",t.publicContext,n.configuration);return _(i,"onInit",t.publicContext,s.configuration),t.initCache.length=0,i}dispose(){for(const[e,t]of this.injectables)t.dispose();p(this,k)}register(e,t=!1){const n=!0===t?(e=>({identifier:e[0],concrete:e[0],instance:e[1],configuration:{}}))(e):(e=>((e,t)=>(n,...s)=>e[n]?e[n](...s):t?t(n,...s):void 0)({1:()=>(e=>({identifier:e[0],concrete:e[0],configuration:{}}))(e),2:()=>w(e),3:()=>(e=>({identifier:e[0],concrete:e[1],configuration:e[2]}))(e)},(()=>{throw new Error("Injection tuple must be of length 1, 2 or 3.")}))(e.length))(e);if(this.has(n.identifier))throw new Error(`An assemblage is already registered with identifier '${n.identifier.name}'.`);const s=M.of(n,this.privateContext,this.publicContext);return this.injectables.set(s.identifier,s),_(s.concrete,"onRegister",this.publicContext,s.configuration),s}use(e,t){if(this.has(e))throw new Error(`A value is already registered with identifier '${String(e)}'.`);return this.objects.set(e,t),t}prepareInitHook(e,t){return this.initCache.push({instance:e,configuration:t}),this.initCache}has(e){return"string"==typeof e||"symbol"==typeof e?this.objects.has(e):this.injectables.has(e)}require(e){switch(typeof e){case"string":case"symbol":if(!this.objects.has(e))throw new Error(`Injected object with identifier '${String(e)}' has not been registered.`);return this.objects.get(e);default:if(!this.injectables.has(e))throw new Error(`Class with identifier '${e.name}' has not been registered or is a circular dependency.`);return this.injectables.get(e).build()}}concrete(e){const t=this.injectables.get(e);if(t)return t.concrete}tagged(...e){const t=[];for(const n of e)for(const[e,s]of this.injectables)s.tags.includes(n)&&t.push(s.build());return t}get size(){return this.injectables.size}constructor(){super(),this.injectables=new Map,this.objects=new Map,this.initCache=[],this.publicContext={has:this.has.bind(this),require:this.require.bind(this),concrete:this.concrete.bind(this),tagged:this.tagged.bind(this),dispose:this.dispose.bind(this),on:this.on.bind(this),once:this.once.bind(this),off:this.off.bind(this),events:this.channels},this.privateContext={...this.publicContext,register:this.register.bind(this),use:this.use.bind(this),prepareInitHook:this.prepareInitHook.bind(this),emit:this.emit.bind(this),addChannels:this.addChannels.bind(this),removeChannels:this.removeChannels.bind(this)}}}exports.AbstractAssemblage=class{static onRegister(e,t){}},exports.AbstractAssembler=class extends A{},exports.AbstractEventManager=A,exports.AbstractListenerCollection=class{},exports.Assemblage=e=>t=>I(t,e),exports.Assembler=k,exports.Await=(e,t=25)=>(n,s,i)=>{const r=i.value;i.value=async function(){return new Promise((n=>{if(this[e])r.apply(this),n();else{const s=setInterval((()=>{this[e]&&(clearInterval(s),r.apply(this),n())}),t)}}))}},exports.Configuration=D,exports.ConstructorDecorator=L,exports.Context=O,exports.Definition=E,exports.Dispose=U,exports.EventManager=P,exports.ListenerCollection=j,exports.Use=e=>(t,n,s)=>{S(e,t,s)},exports.createConstructorDecorator=e=>(t=!0)=>L(e,t),exports.decorateAssemblage=I,exports.decorateUse=S,exports.getDecoratedParametersIndexes=$,exports.isAssemblage=x;
|
package/dist/index.d.ts
CHANGED
|
@@ -48,10 +48,10 @@ export declare abstract class AbstractAssembler extends AbstractEventManager {
|
|
|
48
48
|
abstract publicContext: AssemblerContext;
|
|
49
49
|
abstract size: number;
|
|
50
50
|
abstract register<T>(injection: Injection<T>, instance?: boolean): Injectable<T>;
|
|
51
|
-
abstract use<T>(identifier: string |
|
|
51
|
+
abstract use<T>(identifier: string | symbol, object: T): T;
|
|
52
52
|
abstract prepareInitHook<T = AbstractAssemblage>(instance: T, configuration?: Record<string, any>): unknown[];
|
|
53
53
|
abstract has<T>(identifier: Identifier<T>): boolean;
|
|
54
|
-
abstract require<T>(identifier: Identifier<T> | string |
|
|
54
|
+
abstract require<T>(identifier: Identifier<T> | string | symbol): T;
|
|
55
55
|
abstract concrete<T>(identifier: Identifier<T>): Concrete<T> | undefined;
|
|
56
56
|
abstract tagged(...tags: string[]): any[];
|
|
57
57
|
abstract dispose(): void;
|
|
@@ -71,7 +71,7 @@ export declare abstract class AbstractEventManager {
|
|
|
71
71
|
declare abstract class AbstractInjectable<T> {
|
|
72
72
|
abstract readonly privateContext: AssemblerPrivateContext;
|
|
73
73
|
abstract readonly publicContext: AssemblerContext;
|
|
74
|
-
abstract readonly identifier: Identifier<T> | string |
|
|
74
|
+
abstract readonly identifier: Identifier<T> | string | symbol;
|
|
75
75
|
abstract readonly concrete: Concrete<T>;
|
|
76
76
|
abstract readonly configuration: Record<string, any>;
|
|
77
77
|
abstract dependencies: (Identifier<unknown> | any)[];
|
|
@@ -87,6 +87,21 @@ declare abstract class AbstractInjectable<T> {
|
|
|
87
87
|
abstract build(): T;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
/**
|
|
91
|
+
* An abstract class for `ListenerCollection` implementation.
|
|
92
|
+
*/
|
|
93
|
+
export declare abstract class AbstractListenerCollection {
|
|
94
|
+
[key: EventChannel]: any;
|
|
95
|
+
abstract listeners: Listener[];
|
|
96
|
+
abstract channels: EventChannel[];
|
|
97
|
+
abstract add(channel: EventChannel, listener: Listener): AbstractListenerCollection;
|
|
98
|
+
abstract remove(channel: EventChannel, listener?: Listener): AbstractListenerCollection;
|
|
99
|
+
abstract has(...args: (EventChannel | Listener)[]): boolean;
|
|
100
|
+
abstract get(...args: (EventChannel | Listener)[]): (EventChannel | Listener)[];
|
|
101
|
+
abstract clear(): AbstractListenerCollection;
|
|
102
|
+
abstract [Symbol.iterator](): Iterator<EventChannel>;
|
|
103
|
+
}
|
|
104
|
+
|
|
90
105
|
/**
|
|
91
106
|
* Generic `Array` items.
|
|
92
107
|
*/
|
|
@@ -126,7 +141,7 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
126
141
|
*/
|
|
127
142
|
static build<T>(entry: Concrete<T>): T;
|
|
128
143
|
protected injectables: Map<Identifier<unknown>, Injectable<unknown>>;
|
|
129
|
-
protected objects: Map<string |
|
|
144
|
+
protected objects: Map<string | symbol, unknown>;
|
|
130
145
|
private initCache;
|
|
131
146
|
/**
|
|
132
147
|
* Context passed to internal classes.
|
|
@@ -177,7 +192,7 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
177
192
|
* }
|
|
178
193
|
* ```
|
|
179
194
|
*/
|
|
180
|
-
use<T>(identifier: string |
|
|
195
|
+
use<T>(identifier: string | symbol, object: T): T;
|
|
181
196
|
/**
|
|
182
197
|
* Cache an instaance to be inited with `onInit` hook
|
|
183
198
|
* when the dependency tree will be fully resolved.
|
|
@@ -191,17 +206,17 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
191
206
|
* Check if `Assembler` has given identifier registered.
|
|
192
207
|
*
|
|
193
208
|
* @param { Identifier<T> | string | symbol } identifier An abstract or concrete class,
|
|
194
|
-
* or a string or
|
|
209
|
+
* or a string or symbol as identifier.
|
|
195
210
|
* @returns { boolean } `true` if dependency has been registered.
|
|
196
211
|
*/
|
|
197
|
-
has<T>(identifier: Identifier<T> | string |
|
|
212
|
+
has<T>(identifier: Identifier<T> | string | symbol): boolean;
|
|
198
213
|
/**
|
|
199
214
|
* Get or instantiate an assemblage for given identifier.
|
|
200
215
|
*
|
|
201
216
|
* @param { Identifier<T> | string | symbol } identifier The identifier to get instance from.
|
|
202
217
|
* @returns { T } An instance of Concrete<T>.
|
|
203
218
|
*/
|
|
204
|
-
require<T>(identifier: Identifier<T> | string |
|
|
219
|
+
require<T>(identifier: Identifier<T> | string | symbol): T;
|
|
205
220
|
/**
|
|
206
221
|
* Return a `Concrete` class for given identifier.
|
|
207
222
|
*
|
|
@@ -342,17 +357,16 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
342
357
|
*
|
|
343
358
|
* @param { function(): void | undefined } fn A function to execute after `super`.
|
|
344
359
|
* Do not use arrow function here if access to `this` is required.
|
|
345
|
-
* @param { boolean | undefined } asAssemblage If `true` decorate the class as an assemblage (defaults to `true`).
|
|
346
360
|
* @returns A new decorator.
|
|
347
361
|
*/
|
|
348
|
-
export declare const createConstructorDecorator: (fn?: () => void
|
|
362
|
+
export declare const createConstructorDecorator: (fn?: () => void) => any;
|
|
349
363
|
|
|
350
364
|
export declare const decorateAssemblage: <T>(target: Concrete<T>, definition?: AssemblageDefinition) => Concrete<T>;
|
|
351
365
|
|
|
352
366
|
/**
|
|
353
367
|
* Decorator as a wrapper function.
|
|
354
368
|
*/
|
|
355
|
-
export declare const decorateUse: (identifier: string |
|
|
369
|
+
export declare const decorateUse: (identifier: string | symbol, target: any, index: number) => void;
|
|
356
370
|
|
|
357
371
|
/**
|
|
358
372
|
* Injects the assemblage's definition object.
|
|
@@ -364,6 +378,16 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
364
378
|
*/
|
|
365
379
|
export declare const Dispose: () => ParameterDecorator;
|
|
366
380
|
|
|
381
|
+
/**
|
|
382
|
+
* `EventChannel` extends `string`.
|
|
383
|
+
*/
|
|
384
|
+
export declare type EventChannel = string;
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Describes a list of event channels as Record<EventChannel, string>
|
|
388
|
+
*/
|
|
389
|
+
export declare type EventChannelList = Record<EventChannel, string>;
|
|
390
|
+
|
|
367
391
|
export declare class EventManager implements AbstractEventManager {
|
|
368
392
|
private readonly listeners;
|
|
369
393
|
private readonly onceListeners;
|
|
@@ -390,7 +414,7 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
390
414
|
declare class Injectable<T> implements AbstractInjectable<T> {
|
|
391
415
|
readonly privateContext: AssemblerPrivateContext;
|
|
392
416
|
readonly publicContext: AssemblerContext;
|
|
393
|
-
readonly identifier: Identifier<T> | string |
|
|
417
|
+
readonly identifier: Identifier<T> | string | symbol;
|
|
394
418
|
readonly concrete: Concrete<T>;
|
|
395
419
|
readonly configuration: Record<string, any>;
|
|
396
420
|
private dependenciesIds;
|
|
@@ -450,7 +474,7 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
450
474
|
/**
|
|
451
475
|
* Injectable binds an instance of a class to an identifier (abstract or concrete).
|
|
452
476
|
*/
|
|
453
|
-
declare type InstanceInjection<T> = Tuple<[Identifier<T> | string |
|
|
477
|
+
declare type InstanceInjection<T> = Tuple<[Identifier<T> | string | symbol, T]>;
|
|
454
478
|
|
|
455
479
|
/**
|
|
456
480
|
* Check if a given class is an `Assemblage`.
|
|
@@ -463,7 +487,96 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
463
487
|
/**
|
|
464
488
|
* Describes a listener type as a function taking any number of arguments and returning `void`.
|
|
465
489
|
*/
|
|
466
|
-
declare type Listener = (...args: any[]) => void | Promise<void>;
|
|
490
|
+
export declare type Listener = (...args: any[]) => void | Promise<void>;
|
|
491
|
+
|
|
492
|
+
export declare class ListenerCollection implements AbstractListenerCollection {
|
|
493
|
+
/**
|
|
494
|
+
* Class is indexable by `EventChannel`.
|
|
495
|
+
*/
|
|
496
|
+
[key: string]: Listener[] | any;
|
|
497
|
+
/**
|
|
498
|
+
* Internal listeners `Object`.
|
|
499
|
+
*/
|
|
500
|
+
readonly collection: Record<EventChannel, Array<Listener>>;
|
|
501
|
+
constructor();
|
|
502
|
+
/**
|
|
503
|
+
* Clean up the collection by removing all listeners and channels
|
|
504
|
+
* and deleting listeners private property.
|
|
505
|
+
*/
|
|
506
|
+
dispose(): void;
|
|
507
|
+
/**
|
|
508
|
+
* Add a listener to the collection.
|
|
509
|
+
*
|
|
510
|
+
* @param { EventChannel } channel The channel to add the listener to.
|
|
511
|
+
* @param { Listener } listener The callback function to run when the event is emitted.
|
|
512
|
+
* @returns { ListenerCollection } This collection.
|
|
513
|
+
*/
|
|
514
|
+
add(channel: EventChannel, listener: Listener): ListenerCollection;
|
|
515
|
+
/**
|
|
516
|
+
* Add a listener to the collection.
|
|
517
|
+
*
|
|
518
|
+
* @param { Tuple<EventChannel, Listener> } tuple The channel and its listener in a tuple.
|
|
519
|
+
* @returns { ListenerCollection } This collection.
|
|
520
|
+
*/
|
|
521
|
+
add(tuple: Tuple<[EventChannel, Listener]>): ListenerCollection;
|
|
522
|
+
/**
|
|
523
|
+
* Removes a listener or all listeners for a given channel.
|
|
524
|
+
* If the channel or the provided listener does not exist, fails silently.
|
|
525
|
+
*
|
|
526
|
+
* @param { EventChannel } channel The channel the listener is listening to.
|
|
527
|
+
* @param { Listener } listener The listener to remove. If not provided, remove all listeners for given channel.
|
|
528
|
+
* @returns { ListenerCollection } This collection.
|
|
529
|
+
*/
|
|
530
|
+
remove(channel: string, listener?: Listener): ListenerCollection;
|
|
531
|
+
/**
|
|
532
|
+
* Checks if the collection includes a specific channel or listener.
|
|
533
|
+
*
|
|
534
|
+
* @param { EventChannel | Listener } value The channel or the listener to find in the collection.
|
|
535
|
+
* @returns { boolean } true if the collection includes this channel / this listener,
|
|
536
|
+
* false if not.
|
|
537
|
+
*/
|
|
538
|
+
has(value: EventChannel): boolean;
|
|
539
|
+
has(value: Listener): boolean;
|
|
540
|
+
/**
|
|
541
|
+
* Get a specific channel listeners array or a specific listener channels array.
|
|
542
|
+
*
|
|
543
|
+
* @param { EventChannel | Listener } value The channel or the listener to find in the collection.
|
|
544
|
+
* @returns { EventChannel[] | Listener[] } An array of channels or listeners.
|
|
545
|
+
*/
|
|
546
|
+
get(value: EventChannel): Listener[];
|
|
547
|
+
get(value: Listener): EventChannel[];
|
|
548
|
+
/**
|
|
549
|
+
* Clear the entire collction.
|
|
550
|
+
*
|
|
551
|
+
* @returns { ListenerCollection } This collection.
|
|
552
|
+
*/
|
|
553
|
+
clear(): ListenerCollection;
|
|
554
|
+
/**
|
|
555
|
+
* The listeners of this collection flatten in a single array.
|
|
556
|
+
*/
|
|
557
|
+
get listeners(): Listener[];
|
|
558
|
+
/**
|
|
559
|
+
* The listeners collection channels.
|
|
560
|
+
*/
|
|
561
|
+
get channels(): EventChannel[];
|
|
562
|
+
/**
|
|
563
|
+
* Returns the total listeners length.
|
|
564
|
+
*/
|
|
565
|
+
get length(): number;
|
|
566
|
+
/**
|
|
567
|
+
* Allows iterating over listeners in specific channel with 'for... of...' loop.
|
|
568
|
+
*
|
|
569
|
+
* @returns { Listener } A listener function.
|
|
570
|
+
*
|
|
571
|
+
* @example
|
|
572
|
+
* // Iterates listeners in a specific channel.
|
|
573
|
+
* for (const listener of myListenerCollection) {
|
|
574
|
+
* // Calls the registered listener.
|
|
575
|
+
* listener();
|
|
576
|
+
* }
|
|
577
|
+
*/
|
|
578
|
+
[Symbol.iterator](): Iterator<EventChannel>;
|
|
579
|
+
}
|
|
467
580
|
|
|
468
581
|
declare interface ParametersDecoratorsIndexes {
|
|
469
582
|
Context: number[];
|
|
@@ -501,8 +614,8 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
501
614
|
};
|
|
502
615
|
|
|
503
616
|
/**
|
|
504
|
-
* Injects an object passed with `string` or `
|
|
617
|
+
* Injects an object passed with `string` or `symbol` identifier.
|
|
505
618
|
*/
|
|
506
|
-
export declare const Use: (identifier: string |
|
|
619
|
+
export declare const Use: (identifier: string | symbol) => ParameterDecorator;
|
|
507
620
|
|
|
508
621
|
export { }
|