assemblerjs 0.7.7 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +130 -16
- package/dist/index.js +921 -1
- package/package.json +28 -41
- package/dist/index.mjs +0 -975
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
|
*/
|
|
@@ -105,7 +120,7 @@ declare type ArrayLengthMutationKeys = 'splice' | 'push' | 'pop' | 'shift' | 'un
|
|
|
105
120
|
*/
|
|
106
121
|
export declare const Assemblage: <T>(definition?: AssemblageDefinition) => ClassDecorator;
|
|
107
122
|
|
|
108
|
-
declare interface AssemblageDefinition {
|
|
123
|
+
export declare interface AssemblageDefinition {
|
|
109
124
|
singleton?: false;
|
|
110
125
|
events?: string[];
|
|
111
126
|
inject?: Injection<unknown>[];
|
|
@@ -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
|
*
|
|
@@ -338,7 +353,7 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
338
353
|
/**
|
|
339
354
|
* Create a custom decorator that adds a function called after the original constructor
|
|
340
355
|
* and that can wrap an `Assemblage` with its own parameters decorator (e.g. @Use, @Context, ...).
|
|
341
|
-
* Note that it must be placed before the `
|
|
356
|
+
* Note that it must be placed before the `Assemblage` decorator.
|
|
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.
|
|
@@ -351,7 +366,7 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
351
366
|
/**
|
|
352
367
|
* Decorator as a wrapper function.
|
|
353
368
|
*/
|
|
354
|
-
export declare const decorateUse: (identifier: string |
|
|
369
|
+
export declare const decorateUse: (identifier: string | symbol, target: any, index: number) => void;
|
|
355
370
|
|
|
356
371
|
/**
|
|
357
372
|
* Injects the assemblage's definition object.
|
|
@@ -363,6 +378,16 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
363
378
|
*/
|
|
364
379
|
export declare const Dispose: () => ParameterDecorator;
|
|
365
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
|
+
|
|
366
391
|
export declare class EventManager implements AbstractEventManager {
|
|
367
392
|
private readonly listeners;
|
|
368
393
|
private readonly onceListeners;
|
|
@@ -389,7 +414,7 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
389
414
|
declare class Injectable<T> implements AbstractInjectable<T> {
|
|
390
415
|
readonly privateContext: AssemblerPrivateContext;
|
|
391
416
|
readonly publicContext: AssemblerContext;
|
|
392
|
-
readonly identifier: Identifier<T> | string |
|
|
417
|
+
readonly identifier: Identifier<T> | string | symbol;
|
|
393
418
|
readonly concrete: Concrete<T>;
|
|
394
419
|
readonly configuration: Record<string, any>;
|
|
395
420
|
private dependenciesIds;
|
|
@@ -449,7 +474,7 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
449
474
|
/**
|
|
450
475
|
* Injectable binds an instance of a class to an identifier (abstract or concrete).
|
|
451
476
|
*/
|
|
452
|
-
declare type InstanceInjection<T> = Tuple<[Identifier<T> | string |
|
|
477
|
+
declare type InstanceInjection<T> = Tuple<[Identifier<T> | string | symbol, T]>;
|
|
453
478
|
|
|
454
479
|
/**
|
|
455
480
|
* Check if a given class is an `Assemblage`.
|
|
@@ -462,7 +487,96 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
462
487
|
/**
|
|
463
488
|
* Describes a listener type as a function taking any number of arguments and returning `void`.
|
|
464
489
|
*/
|
|
465
|
-
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
|
+
}
|
|
466
580
|
|
|
467
581
|
declare interface ParametersDecoratorsIndexes {
|
|
468
582
|
Context: number[];
|
|
@@ -500,8 +614,8 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
500
614
|
};
|
|
501
615
|
|
|
502
616
|
/**
|
|
503
|
-
* Injects an object passed with `string` or `
|
|
617
|
+
* Injects an object passed with `string` or `symbol` identifier.
|
|
504
618
|
*/
|
|
505
|
-
export declare const Use: (identifier: string |
|
|
619
|
+
export declare const Use: (identifier: string | symbol) => ParameterDecorator;
|
|
506
620
|
|
|
507
621
|
export { }
|