assemblerjs 0.0.96 → 0.0.98
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.d.ts +50 -40
- package/dist/index.js +1 -1
- package/dist/index.mjs +569 -170
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -5,18 +5,43 @@ declare interface Abstract<T> extends Function {
|
|
|
5
5
|
prototype: T;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Base abstract class to implement an assemblage.
|
|
10
|
+
*/
|
|
8
11
|
export declare abstract class AbstractAssemblage {
|
|
9
12
|
[key: string]: any;
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Called on concrete class registration by assembler.
|
|
15
|
+
*
|
|
16
|
+
* @param { AssemblerContext } context The assembler's context.
|
|
17
|
+
*/
|
|
18
|
+
static onRegister(context: AssemblerContext): void;
|
|
19
|
+
/**
|
|
20
|
+
* Called when class is instantiated.
|
|
21
|
+
*
|
|
22
|
+
* @param { AssemblerContext } context The assembler's context.
|
|
23
|
+
*/
|
|
24
|
+
abstract onInit?(context: AssemblerContext): void | Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Called when instance of class is disposed.
|
|
27
|
+
*
|
|
28
|
+
* @param { AssemblerContext } context The assembler's context.
|
|
29
|
+
*/
|
|
30
|
+
abstract onDispose?(context: AssemblerContext): void;
|
|
31
|
+
/**
|
|
32
|
+
* Dispose the assemblage instance.
|
|
33
|
+
*/
|
|
34
|
+
abstract dispose?(): void;
|
|
12
35
|
}
|
|
13
36
|
|
|
14
37
|
export declare abstract class AbstractAssembler {
|
|
15
38
|
abstract context: AssemblerContext;
|
|
16
|
-
abstract
|
|
39
|
+
abstract size: number;
|
|
40
|
+
abstract register<T>(injection: Injection<T>): Injectable<T>;
|
|
17
41
|
abstract has<T>(identifier: Identifier<T>): boolean;
|
|
18
42
|
abstract require<T>(identifier: Identifier<T>): T;
|
|
19
43
|
abstract tagged(...tags: string[]): any[];
|
|
44
|
+
abstract dispose(): void;
|
|
20
45
|
}
|
|
21
46
|
|
|
22
47
|
/**
|
|
@@ -46,6 +71,7 @@ export declare class Assembler implements AbstractAssembler {
|
|
|
46
71
|
readonly context: AssemblerContext;
|
|
47
72
|
static build(entry: Concrete<any>): Assembler;
|
|
48
73
|
private constructor();
|
|
74
|
+
dispose(): void;
|
|
49
75
|
/**
|
|
50
76
|
* Recursively register an `Injection` tuple and its inner injected dependencies.
|
|
51
77
|
*
|
|
@@ -74,33 +100,17 @@ export declare class Assembler implements AbstractAssembler {
|
|
|
74
100
|
* identifier is not marked as 'singleton', will resolve in a new instance.
|
|
75
101
|
*/
|
|
76
102
|
tagged(...tags: string[]): unknown[];
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export declare class AssemblerContext {
|
|
80
103
|
/**
|
|
81
|
-
*
|
|
104
|
+
* Size of the assembler: number of registered dependencies.
|
|
82
105
|
*/
|
|
83
|
-
|
|
106
|
+
get size(): number;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export declare interface AssemblerContext {
|
|
84
110
|
register: AbstractAssembler['register'];
|
|
85
111
|
has: AbstractAssembler['has'];
|
|
86
112
|
require: AbstractAssembler['require'];
|
|
87
113
|
tagged: AbstractAssembler['tagged'];
|
|
88
|
-
constructor(assembler: AbstractAssembler);
|
|
89
|
-
/**
|
|
90
|
-
* Add a value to user-defined data.
|
|
91
|
-
*
|
|
92
|
-
* @param { string } key The key to add.
|
|
93
|
-
* @param { any } value The value to add.
|
|
94
|
-
* @returns { this } This context.
|
|
95
|
-
*/
|
|
96
|
-
set(key: string, value: any): this;
|
|
97
|
-
/**
|
|
98
|
-
* Get a value in user-defined data for given key.
|
|
99
|
-
*
|
|
100
|
-
* @param { string } key The key to get from user-defined data.
|
|
101
|
-
* @returns { any } The result.
|
|
102
|
-
*/
|
|
103
|
-
get(key: string): any;
|
|
104
114
|
}
|
|
105
115
|
|
|
106
116
|
/**
|
|
@@ -143,6 +153,8 @@ Record<string, any>
|
|
|
143
153
|
|
|
144
154
|
export declare const Context: () => ParameterDecorator;
|
|
145
155
|
|
|
156
|
+
export declare const Definition: () => ParameterDecorator;
|
|
157
|
+
|
|
146
158
|
/**
|
|
147
159
|
* An identifier can be an abstract or a concrete class.
|
|
148
160
|
*/
|
|
@@ -154,25 +166,29 @@ declare class Injectable<T> {
|
|
|
154
166
|
readonly concrete: Concrete<T>;
|
|
155
167
|
readonly configuration: Record<string, any>;
|
|
156
168
|
singleton: T | undefined;
|
|
169
|
+
private dependenciesIds;
|
|
157
170
|
static of<TNew>(injection: Injection<TNew>, context: AssemblerContext): Injectable<TNew>;
|
|
158
171
|
private constructor();
|
|
172
|
+
/**
|
|
173
|
+
* Dispose the injectable by deleting its singleton if exists.
|
|
174
|
+
*/
|
|
175
|
+
dispose(): void;
|
|
159
176
|
/**
|
|
160
177
|
* Instantiate the assemblage or get its singleton instance.
|
|
161
178
|
*
|
|
162
|
-
* @param { ...any[] } args The arguments to be passed to asssemblage's constructor.
|
|
163
179
|
* @returns { T } The assemblage instance.
|
|
164
180
|
*/
|
|
165
181
|
build(): T;
|
|
166
182
|
/**
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* @returns { (Identifier<unknown> | any)[] } An array of parameters.
|
|
183
|
+
* Injectable assemblage's dependencies passed as 'constructor' parameters.
|
|
170
184
|
*/
|
|
171
|
-
|
|
185
|
+
get dependencies(): (Identifier<unknown> | any)[];
|
|
186
|
+
/**
|
|
187
|
+
* Metadatas passed in assemblage's definition or in its parent definition.
|
|
188
|
+
*/
|
|
189
|
+
get definition(): AssemblageDefinition;
|
|
172
190
|
/**
|
|
173
191
|
* `true` if assemblage is a singleton.
|
|
174
|
-
*
|
|
175
|
-
* @todo Change assembler to avoid checking instance.
|
|
176
192
|
*/
|
|
177
193
|
get isSingleton(): boolean;
|
|
178
194
|
/**
|
|
@@ -180,17 +196,13 @@ declare class Injectable<T> {
|
|
|
180
196
|
*/
|
|
181
197
|
get injections(): Injection<unknown>[];
|
|
182
198
|
/**
|
|
183
|
-
*
|
|
184
|
-
*/
|
|
185
|
-
get dependencies(): (Identifier<unknown> | any)[];
|
|
186
|
-
/**
|
|
187
|
-
* Tags passed in assemblage's definition or in its parent definition.
|
|
199
|
+
* Tags passed in assemblage's definition.
|
|
188
200
|
*/
|
|
189
201
|
get tags(): string[];
|
|
190
202
|
/**
|
|
191
|
-
*
|
|
203
|
+
* Event channels passed in assemblage's definition.
|
|
192
204
|
*/
|
|
193
|
-
get
|
|
205
|
+
get events(): string[];
|
|
194
206
|
}
|
|
195
207
|
|
|
196
208
|
/**
|
|
@@ -198,8 +210,6 @@ declare class Injectable<T> {
|
|
|
198
210
|
*/
|
|
199
211
|
declare type Injection<T> = BaseInjection<T> | ConfiguredInjection<T> | ConcreteInjection<T> | ConcreteConfiguredInjection<T>;
|
|
200
212
|
|
|
201
|
-
export declare const Metadata: () => ParameterDecorator;
|
|
202
|
-
|
|
203
213
|
/**
|
|
204
214
|
* An array of fixed length typed values.
|
|
205
215
|
*
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="__",t="__",i="is_singleton",r="context_param_index",n="config_param_index",s="metadata_param_index",o=(i,r,n)=>{Reflect.defineMetadata(`${e}${i}${t}`,r,n)},a=(i,r)=>Reflect.getMetadata(`${e}${i}${t}`,r),c=(i,r)=>Reflect.getOwnMetadata(`${e}${i}${t}`,r);const h=e=>e&&"function"==typeof e&&void 0!==e.constructor,u=e=>t=>e.if(t)?e.then(t):e.else?e.else(t):void 0,l=e=>{const t=()=>h(e[0])&&(e=>"object"==typeof e&&!Array.isArray(e)&&!h(e))(e[1]);return((...e)=>t=>e.reduce(((e,t)=>t(e)),t))(u({if:()=>h(e[0])&&h(e[1]),then:()=>({identifier:e[0],concrete:e[1],configuration:{}})}),u({if:()=>t(),then:()=>({identifier:e[0],concrete:e[0],configuration:e[1]}),else:e=>e}))()},d=e=>((e,t)=>(i,...r)=>e[i]?e[i](...r):t?t(i,...r):void 0)({1:()=>(e=>({identifier:e[0],concrete:e[0],configuration:{}}))(e),2:()=>l(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);function f(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}class g{static of(e,t){return new g(e,t)}build(){if(this.singleton)return this.singleton;const e=this.resolveDependencies(),t=new this.concrete(...e);return this.isSingleton&&(this.singleton=t),t}resolveDependencies(){const e=[],t=c(r,this.concrete)||[],i=c(n,this.concrete)||[],o=a(s,this.concrete)||[];let h=0;for(const r of this.dependencies)t.includes(h)?(e.push(this.context),h++):i.includes(h)?(e.push(this.configuration),h++):o.includes(h)?(e.push(this.metadata),h++):(e.push(this.context.require(r)),h++);return e}get isSingleton(){return c(i,this.concrete)||!1}get injections(){return c("inject",this.concrete)||[]}get dependencies(){return Reflect.getMetadata("design:paramtypes",this.concrete)||[]}get tags(){return a("tags",this.concrete)||[]}get metadata(){return a("metadata",this.concrete)||{}}constructor(e,t){f(this,"context",void 0),f(this,"identifier",void 0),f(this,"concrete",void 0),f(this,"configuration",void 0),f(this,"singleton",void 0),this.context=t;const i=d(e);this.identifier=i.identifier,this.concrete=i.concrete,this.configuration=i.configuration;for(const r of this.injections)this.context.register(r)}}function b(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}class p{set(e,t){if(this.userData[e])throw new Error(`Key '${e}' is already defined in context's user data.`);return this.userData[e]=t,this}get(e){return this.userData[e]}constructor(e){b(this,"userData",{}),b(this,"register",void 0),b(this,"has",void 0),b(this,"require",void 0),b(this,"tagged",void 0),this.register=e.register.bind(e),this.has=e.has.bind(e),this.require=e.require.bind(e),this.tagged=e.tagged.bind(e)}}function m(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}class w{static build(e){return new w(e)}register(e){const t=g.of(e,this.context);if(this.has(t.identifier))throw new Error(`An assemblage is already registered with identifier '${t.identifier.name}'.`);return this.injectables.set(t.identifier,t),t}has(e){return this.injectables.has(e)}require(e){if(!this.injectables.has(e))throw new Error(`Assemblage with identifier '${e.name}' has not been registered.`);return this.injectables.get(e).build()}tagged(...e){const t=[];for(const i of e)for(const[e,r]of this.injectables)r.tags.includes(i)&&t.push(r.build());return t}constructor(e){m(this,"injectables",new Map),m(this,"context",void 0),this.context=new p(this),o(i,!0,e);return this.register([e]).build()}}const y=e=>()=>(t,i,r)=>{const n=c(e,t)||[];n.push(r),o(e,n,t)},x=y(r),j=y(n),A=y(s);exports.AbstractAssemblage=class{},exports.AbstractAssembler=class{},exports.Assemblage=e=>{const t=e||{};return e=>{o("is_assemblage",!0,e),o(i,!0,e);for(const r in t)if(t.hasOwnProperty(r))switch(r){case"singleton":!1===t.singleton&&o(i,!1,e);break;case"controller":if(!0===t.controller){if("string"!=typeof t.path)throw new Error(`Controller assemblage '${e.name}' must define a path.`);o("is_controller",!0,e)}break;case"tags":if(void 0!==t.tags)if("string"==typeof t.tags)o("tags",[t.tags],e);else{if(!Array.isArray(t.tags))throw new Error("Assemblage's 'tags' must be o type 'string' or 'Array'.");o("tags",t.tags,e)}break;case"inject":if(!Array.isArray(t.inject))throw new Error("Assemblage's definition 'inject' property must be an array of 'Injection' tuples.");for(const e of t.inject)if(!Array.isArray(e))throw new Error("'Injection' must be an 'Array'.");default:o(r,t[r],e)}return e}},exports.Assembler=w,exports.AssemblerContext=p,exports.Configuration=j,exports.Context=x,exports.Metadata=A;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="assemblage_definition",t="context_param_index",n="config_param_index",r="definition_param_index",i=(e,t,n)=>{Reflect.defineMetadata(`__${e}__`,t,n)},s=(e,t)=>Reflect.getOwnMetadata(`__${e}__`,t),o=e=>Reflect.getMetadata("design:paramtypes",e)||[],c={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},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},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},controller:{test:e=>"boolean"==typeof e||void 0===e,throw:()=>{throw new Error("'controller' property must be of type 'boolean' or 'undefined'.")},transform:e=>e},path:{test:e=>"string"==typeof e||void 0===e,throw:()=>{throw new Error("'path' property must be of type 'string' or 'undefined'.")},transform:e=>{if(e){let t=e.replace(/\/+/g,"/").replace(/\s/g,"");if(t.startsWith("/")||(t=`/${t}`),t.endsWith("/")){const e=t.length-1;t=t.split("").splice(0,e).join("")}return t}return 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}},l=e=>{const t={...e};for(const n in t){if(!Object.keys(c).includes(n))throw new Error(`Property '${n}' is not a valid assemblage definition property.`);const e=c[n].test,r=c[n].throw,i=c[n].transform;if(e(t[n])||r(),"controller"===n&&!Object.keys(t).includes("path"))throw new Error("Assemblage marked as 'controller' must define a 'path'.");if("path"===n&&!Object.keys(t).includes("controller"))throw new Error("Assemblage that defines a 'path' must be marked as 'controller'.");t[n]=i(t[n])}return t},a=t=>s(e,t),h=(e,t)=>a(t)[e],u=e=>()=>(t,n,r)=>{const o=s(e,t)||[];o.push(r),i(e,o,t)},f=u(t),d=u(n),g=u(r),p=e=>{const i=(e=>s(t,e)||[])(e),o=(e=>s(r,e)||[])(e),c=(e=>s(n,e)||[])(e);return{context:i,definition:o,configuration:c}};const b=(...e)=>{},y=(...e)=>t=>{if(e.includes(typeof t))return typeof t},m=e=>!(e=>void 0===e)(e)&&!(e=>null===e)(e),w=e=>e&&"function"==typeof e&&void 0!==e.constructor,v=e=>"function"==typeof e&&"AsyncFunction"===e.constructor.name,j=(e,...t)=>{t.map(((e,n)=>{const r=/\S/.test(e);return r&&(t[n]=t[n].trim()),r?-1:n})).filter((e=>e>=0)).every((e=>{t[e]=" ",((e,t,n)=>{const r=e[t];e.splice(t,1),e.splice(n,0,r)})(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,"")},O=(...e)=>t=>e.reduce(((e,t)=>t(e)),t),x=e=>t=>e.if(t)?e.then(t):e.else?e.else(t):void 0,A=e=>t=>{const n=Array.isArray(e)?e=>parseInt(e):b;for(const[r,i]of Object.entries(e))t(i,n(r))},E=(e,t)=>{const n=new Proxy(e,{get:function(n,r){return r===Symbol.iterator?n[Symbol.iterator].bind(n):((e,t)=>[...Object.getOwnPropertyNames(t.prototype),...Object.getOwnPropertyNames(Object.getPrototypeOf(e)),...Object.getOwnPropertyNames(e)])(e,t).includes(r)?n[r]:n.collection[r]},set:function(e,t,n){return Reflect.set(e,t,n)}});return n},P=(e,t)=>{const n=e;for(const r of((e,t)=>[...Object.getOwnPropertyNames(t.prototype),...Object.getOwnPropertyNames(Object.getPrototypeOf(e)),...Object.getOwnPropertyNames(e)])(e,t))delete n[r]},C=(e,t,n)=>new Promise((r=>{const i=e[t];if(i){if(v(i))return void i.bind(e)(n).then((()=>{r()}));r(i.bind(e)(n))}})),_=e=>{const t=()=>w(e[0])&&(e=>"object"==typeof e&&!Array.isArray(e)&&!w(e))(e[1]);return O(x({if:()=>w(e[0])&&w(e[1]),then:()=>({identifier:e[0],concrete:e[1],configuration:{}})}),x({if:()=>t(),then:()=>({identifier:e[0],concrete:e[0],configuration:e[1]}),else:e=>e}))()},S=e=>((e,t)=>(n,...r)=>e[n]?e[n](...r):t?t(n,...r):void 0)({1:()=>(e=>({identifier:e[0],concrete:e[0],configuration:{}}))(e),2:()=>_(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);let $=Symbol.iterator;class k{dispose(){P(this,k)}add(...e){const t=e=>this.collection[e.channel].push(e.listener),n=x({if:()=>2===e.length,then:()=>({channel:e[0],listener:e[1]}),else:()=>{const t=e[0];return{channel:t[0],listener:t[1]}}}),r=x({if:e=>!m(this.collection[e.channel]),then:e=>{this.collection[e.channel]=[],t(e)},else:e=>{t(e)}});return O(n,r)(),this}remove(e,t){const n=t=>this.collection[e].splice(t,1),r=x({if:()=>this.collection[e]&&0===this.collection[e].length,then:()=>delete this.collection[e]}),i=x({if:()=>m(t),then:()=>n(this.collection[e].indexOf(t)),else:()=>delete this.collection[e]}),s=x({if:e=>this.has(e),then:e=>this.collection[e]});return O(s,i,r)(),this}has(...e){return y("string")(e[0])?Object.keys(this.collection).includes(e[0]):!!y("function")(e[0])&&Object.values(this.collection).flat().includes(e[0])}get(...e){return y("string")(e[0])?this.collection[e[0]]:y("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 r in e)t(n(r))})(this.collection),t=e=>A(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}[$](){let e=-1;const t=this.collection?Object.keys(this.collection):[];return{next:()=>({value:t[++e],done:!(e in t)})}}constructor(){!function(e,t,n){t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n}(this,"collection",{});return E(this,k)}}function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class L{dispose(){this.listeners.dispose(),this.channels.clear(),P(this,L)}addChannels(...e){return A(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 A(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("*")||[],r=this.listeners.get("*")||[],i=this.onceListeners.get(n)||[],s=this.listeners.get(n)||[],o=A(e),c=A(r),l=A(i),a=A(s);o((e=>{this.run(e,...t),this.onceListeners.remove("*",e)})),c((e=>{this.run(e,...t)})),l((e=>{this.run(e,...t),this.onceListeners.remove(n,e)})),a((e=>{this.run(e,...t)}))}return this}run(e,...t){if(v(e)){return e(...t).then((()=>Promise.resolve()))}e(...t)}cleanChannel(e){return j(e,"*")}constructor(...e){I(this,"listeners",new k),I(this,"onceListeners",new k),I(this,"channels",new Set(["*"])),this.addChannels(...e)}}function R(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class N{static of(e,t){return new N(e,t)}dispose(){this.singleton&&C(this.singleton,"onDispose",this.context),P(this,N)}build(){if(this.singleton)return this.singleton;const e=((e,t,n,r)=>{const i=[],s=o(e),c=p(e);let l=0;for(const o of s)c.context.includes(l)?(i.push(t),l++):c.configuration.includes(l)?(i.push(r),l++):c.definition.includes(l)?(i.push(n),l++):(i.push(t.require(o)),l++);return i})(this.concrete,this.context,this.definition,this.configuration),t=new this.concrete(...e);return this.concrete.prototype instanceof L&&t.addChannels(...this.events),C(t,"onInit",this.context),this.isSingleton&&(this.singleton=t),t}get dependencies(){return this.dependenciesIds}get definition(){return a(this.concrete)||{}}get isSingleton(){return h("singleton",this.concrete)||!0}get injections(){return h("inject",this.concrete)||[]}get tags(){return h("tags",this.concrete)||[]}get events(){return h("events",this.concrete)||[]}constructor(e,t){R(this,"context",void 0),R(this,"identifier",void 0),R(this,"concrete",void 0),R(this,"configuration",void 0),R(this,"singleton",void 0),R(this,"dependenciesIds",void 0),this.context=t,this.dependenciesIds=[];const n=S(e);this.identifier=n.identifier,this.concrete=n.concrete,this.configuration=n.configuration;for(const r of this.injections)this.context.register(r);this.dependenciesIds=(e=>{const t=[],n=o(e),r=p(e);let i=0;for(const s of n)r.context.includes(i)||r.configuration.includes(i)||r.definition.includes(i)||t.push(s),i++;return t})(this.concrete),this.isSingleton&&this.build()}}function q(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class M{static build(e){return new M(e)}dispose(){for(const[e,t]of this.injectables)t.dispose();P(this,M)}register(e){const t=N.of(e,this.context);if(this.has(t.identifier))throw new Error(`An assemblage is already registered with identifier '${t.identifier.name}'.`);return this.injectables.set(t.identifier,t),C(t.concrete,"onRegister",this.context),t}has(e){return this.injectables.has(e)}require(e){if(!this.injectables.has(e))throw new Error(`Assemblage with identifier '${e.name}' has not been registered.`);return this.injectables.get(e).build()}tagged(...e){const t=[];for(const n of e)for(const[e,r]of this.injectables)r.tags.includes(n)&&t.push(r.build());return t}get size(){return this.injectables.size}constructor(e){q(this,"injectables",new Map),q(this,"context",void 0),this.context={register:this.register.bind(this),has:this.has.bind(this),require:this.require.bind(this),tagged:this.tagged.bind(this)},((e,t,n)=>{const r=a(n);r[e]=t,l(r)})("singleton",!0,e);const t=this.register([e]);return this.require(t.identifier)}}exports.AbstractAssemblage=class{static onRegister(e){}},exports.AbstractAssembler=class{},exports.Assemblage=t=>{const n=t?l(t):{};return t=>(i("is_assemblage",!0,t),i(e,n,t),t)},exports.Assembler=M,exports.Configuration=d,exports.Context=f,exports.Definition=g;
|
package/dist/index.mjs
CHANGED
|
@@ -1,101 +1,272 @@
|
|
|
1
1
|
class AbstractAssemblage {
|
|
2
|
+
static onRegister(s) {}
|
|
2
3
|
}
|
|
3
4
|
|
|
4
|
-
const ReflectCustomPrefix = '__';
|
|
5
|
-
const ReflectCustomSuffix = '__';
|
|
6
5
|
const ReflectParamTypes = 'design:paramtypes';
|
|
6
|
+
const ReflectPrefix = '__';
|
|
7
|
+
const ReflectSuffix = '__';
|
|
7
8
|
const ReflectIsAssemblageFlag = `is_assemblage`;
|
|
8
|
-
const
|
|
9
|
-
const ReflectIsControllerFlag = `is_controller`;
|
|
9
|
+
const ReflectDefinition = 'assemblage_definition';
|
|
10
10
|
const ReflectContextParamIndex = `context_param_index`;
|
|
11
11
|
const ReflectConfigurationParamIndex = `config_param_index`;
|
|
12
|
-
const
|
|
12
|
+
const ReflectDefinitionParamIndex = `definition_param_index`;
|
|
13
|
+
const defineCustomMetadata = (e, t, a)=>{
|
|
14
|
+
Reflect.defineMetadata(`${ReflectPrefix}${e}${ReflectSuffix}`, t, a);
|
|
15
|
+
};
|
|
16
|
+
const getOwnCustomMetadata = (e, t)=>{
|
|
17
|
+
return Reflect.getOwnMetadata(`${ReflectPrefix}${e}${ReflectSuffix}`, t);
|
|
18
|
+
};
|
|
19
|
+
const getParamTypes = (e)=>{
|
|
20
|
+
return Reflect.getMetadata(ReflectParamTypes, e) || [];
|
|
21
|
+
};
|
|
13
22
|
|
|
14
|
-
const
|
|
15
|
-
|
|
23
|
+
const r = {
|
|
24
|
+
singleton: {
|
|
25
|
+
test: (t)=>typeof t === 'boolean' || typeof t === 'undefined',
|
|
26
|
+
throw: ()=>{
|
|
27
|
+
throw new Error(`'singleton' property must be of type 'boolean' or 'undefined'.`);
|
|
28
|
+
},
|
|
29
|
+
transform: (t)=>typeof t === 'undefined' ? true : false
|
|
30
|
+
},
|
|
31
|
+
events: {
|
|
32
|
+
test: (t)=>typeof t === 'undefined' || Array.isArray(t) && t.every((t)=>typeof t === 'string'),
|
|
33
|
+
throw: ()=>{
|
|
34
|
+
throw new Error(`'events' property must be an array of strings or 'undefined'.`);
|
|
35
|
+
},
|
|
36
|
+
transform: (t)=>t
|
|
37
|
+
},
|
|
38
|
+
inject: {
|
|
39
|
+
test: (t)=>typeof t === 'undefined' || Array.isArray(t) && t.every((t)=>Array.isArray(t) && t.length >= 1 && t.length <= 3),
|
|
40
|
+
throw: ()=>{
|
|
41
|
+
throw new Error(`'inject' property must be an array of tuples of length 1, 2 or 3.`);
|
|
42
|
+
},
|
|
43
|
+
transform: (t)=>t
|
|
44
|
+
},
|
|
45
|
+
tags: {
|
|
46
|
+
test: (t)=>typeof t === 'undefined' || typeof t === 'string' || Array.isArray(t) && t.every((t)=>typeof t === 'string'),
|
|
47
|
+
throw: ()=>{
|
|
48
|
+
throw new Error(`'tags' property must be a string or an array of strings.`);
|
|
49
|
+
},
|
|
50
|
+
transform: (t)=>typeof t === 'string' ? [
|
|
51
|
+
t
|
|
52
|
+
] : t
|
|
53
|
+
},
|
|
54
|
+
controller: {
|
|
55
|
+
test: (t)=>typeof t === 'boolean' || typeof t === 'undefined',
|
|
56
|
+
throw: ()=>{
|
|
57
|
+
throw new Error(`'controller' property must be of type 'boolean' or 'undefined'.`);
|
|
58
|
+
},
|
|
59
|
+
transform: (t)=>t
|
|
60
|
+
},
|
|
61
|
+
path: {
|
|
62
|
+
test: (t)=>typeof t === 'string' || typeof t === 'undefined',
|
|
63
|
+
throw: ()=>{
|
|
64
|
+
throw new Error(`'path' property must be of type 'string' or 'undefined'.`);
|
|
65
|
+
},
|
|
66
|
+
transform: (t)=>{
|
|
67
|
+
if (t) {
|
|
68
|
+
let e = t.replace(/\/+/g, '/').replace(/\s/g, '');
|
|
69
|
+
if (!e.startsWith('/')) {
|
|
70
|
+
e = `/${e}`;
|
|
71
|
+
}
|
|
72
|
+
if (e.endsWith('/')) {
|
|
73
|
+
const t = e.length - 1;
|
|
74
|
+
e = e.split('').splice(0, t).join('');
|
|
75
|
+
}
|
|
76
|
+
return e;
|
|
77
|
+
}
|
|
78
|
+
return t;
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
metadata: {
|
|
82
|
+
test: (t)=>(typeof t === 'object' || typeof t === 'undefined') && !Array.isArray(t),
|
|
83
|
+
throw: ()=>{
|
|
84
|
+
throw new Error(`'metadata' property must be of type 'object' or 'undefined'.`);
|
|
85
|
+
},
|
|
86
|
+
transform: (t)=>t
|
|
87
|
+
}
|
|
16
88
|
};
|
|
17
|
-
const
|
|
18
|
-
|
|
89
|
+
const validateDefinition = (t)=>{
|
|
90
|
+
const e = {
|
|
91
|
+
...t
|
|
92
|
+
};
|
|
93
|
+
for(const t in e){
|
|
94
|
+
if (!Object.keys(r).includes(t)) {
|
|
95
|
+
throw new Error(`Property '${t}' is not a valid assemblage definition property.`);
|
|
96
|
+
}
|
|
97
|
+
const o = r[t].test;
|
|
98
|
+
const n = r[t].throw;
|
|
99
|
+
const s = r[t].transform;
|
|
100
|
+
if (!o(e[t])) {
|
|
101
|
+
n();
|
|
102
|
+
}
|
|
103
|
+
if (t === 'controller' && !Object.keys(e).includes('path')) {
|
|
104
|
+
throw new Error(`Assemblage marked as 'controller' must define a 'path'.`);
|
|
105
|
+
}
|
|
106
|
+
if (t === 'path' && !Object.keys(e).includes('controller')) {
|
|
107
|
+
throw new Error(`Assemblage that defines a 'path' must be marked as 'controller'.`);
|
|
108
|
+
}
|
|
109
|
+
e[t] = s(e[t]);
|
|
110
|
+
}
|
|
111
|
+
return e;
|
|
19
112
|
};
|
|
20
|
-
const
|
|
21
|
-
return
|
|
113
|
+
const getDefinition = (r)=>{
|
|
114
|
+
return getOwnCustomMetadata(ReflectDefinition, r);
|
|
115
|
+
};
|
|
116
|
+
const getDefinitionValue = (t, e)=>{
|
|
117
|
+
const r = getDefinition(e);
|
|
118
|
+
return r[t];
|
|
119
|
+
};
|
|
120
|
+
const setDefinitionValue = (t, e, r)=>{
|
|
121
|
+
const o = getDefinition(r);
|
|
122
|
+
o[t] = e;
|
|
123
|
+
const n = validateDefinition(o);
|
|
124
|
+
return n;
|
|
22
125
|
};
|
|
23
126
|
|
|
24
127
|
const Assemblage = (o)=>{
|
|
25
|
-
const
|
|
128
|
+
const s = o ? validateDefinition(o) : {};
|
|
26
129
|
return (o)=>{
|
|
27
130
|
defineCustomMetadata(ReflectIsAssemblageFlag, true, o);
|
|
28
|
-
defineCustomMetadata(
|
|
29
|
-
for(const r in n){
|
|
30
|
-
if (n.hasOwnProperty(r)) {
|
|
31
|
-
switch(r){
|
|
32
|
-
case 'singleton':
|
|
33
|
-
{
|
|
34
|
-
if (n.singleton === false) {
|
|
35
|
-
defineCustomMetadata(ReflectIsSingletonFlag, false, o);
|
|
36
|
-
}
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
case 'controller':
|
|
40
|
-
{
|
|
41
|
-
if (n.controller === true) {
|
|
42
|
-
if (typeof n.path !== 'string') {
|
|
43
|
-
throw new Error(`Controller assemblage '${o.name}' must define a path.`);
|
|
44
|
-
}
|
|
45
|
-
defineCustomMetadata(ReflectIsControllerFlag, true, o);
|
|
46
|
-
}
|
|
47
|
-
break;
|
|
48
|
-
}
|
|
49
|
-
case 'tags':
|
|
50
|
-
{
|
|
51
|
-
if (typeof n.tags !== 'undefined') {
|
|
52
|
-
if (typeof n.tags === 'string') {
|
|
53
|
-
defineCustomMetadata('tags', [
|
|
54
|
-
n.tags
|
|
55
|
-
], o);
|
|
56
|
-
} else if (Array.isArray(n.tags)) {
|
|
57
|
-
defineCustomMetadata('tags', n.tags, o);
|
|
58
|
-
} else {
|
|
59
|
-
throw new Error(`Assemblage's 'tags' must be o type 'string' or 'Array'.`);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
case 'inject':
|
|
65
|
-
{
|
|
66
|
-
if (!Array.isArray(n.inject)) {
|
|
67
|
-
throw new Error(`Assemblage's definition 'inject' property must be an array of 'Injection' tuples.`);
|
|
68
|
-
}
|
|
69
|
-
for (const r of n.inject){
|
|
70
|
-
if (!Array.isArray(r)) {
|
|
71
|
-
throw new Error(`'Injection' must be an 'Array'.`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
default:
|
|
76
|
-
{
|
|
77
|
-
defineCustomMetadata(r, n[r], o);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
131
|
+
defineCustomMetadata(ReflectDefinition, s, o);
|
|
82
132
|
return o;
|
|
83
133
|
};
|
|
84
134
|
};
|
|
85
135
|
|
|
136
|
+
const i$1 = (t)=>()=>{
|
|
137
|
+
return (n, e, i)=>{
|
|
138
|
+
const s = getOwnCustomMetadata(t, n) || [];
|
|
139
|
+
s.push(i);
|
|
140
|
+
defineCustomMetadata(t, s, n);
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
const s = i$1(ReflectContextParamIndex);
|
|
144
|
+
const x = i$1(ReflectConfigurationParamIndex);
|
|
145
|
+
const c$1 = i$1(ReflectDefinitionParamIndex);
|
|
146
|
+
const getContextIndex = (t)=>{
|
|
147
|
+
return getOwnCustomMetadata(ReflectContextParamIndex, t) || [];
|
|
148
|
+
};
|
|
149
|
+
const getConfigurationIndex = (n)=>{
|
|
150
|
+
return getOwnCustomMetadata(ReflectConfigurationParamIndex, n) || [];
|
|
151
|
+
};
|
|
152
|
+
const getDefinitionIndex = (t)=>{
|
|
153
|
+
return getOwnCustomMetadata(ReflectDefinitionParamIndex, t) || [];
|
|
154
|
+
};
|
|
155
|
+
const getDecoratedParametersIndexes = (t)=>{
|
|
156
|
+
const n = getContextIndex(t);
|
|
157
|
+
const e = getDefinitionIndex(t);
|
|
158
|
+
const o = getConfigurationIndex(t);
|
|
159
|
+
return {
|
|
160
|
+
context: n,
|
|
161
|
+
definition: e,
|
|
162
|
+
configuration: o
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
|
|
86
166
|
class AbstractAssembler {
|
|
87
167
|
}
|
|
88
168
|
|
|
89
169
|
const NoOp = (...e)=>{};
|
|
170
|
+
const isOfType = (...e)=>(t)=>{
|
|
171
|
+
if (!e.includes(typeof t)) return undefined;
|
|
172
|
+
return typeof t;
|
|
173
|
+
};
|
|
174
|
+
const isUndefined = (e)=>typeof e === 'undefined';
|
|
175
|
+
const isNull = (e)=>e === null;
|
|
176
|
+
const isDefined = (e)=>!isUndefined(e) && !isNull(e);
|
|
90
177
|
const isClass = (e)=>{
|
|
91
178
|
return e && typeof e === 'function' && typeof e.constructor !== 'undefined';
|
|
92
179
|
};
|
|
93
180
|
const isObject = (e)=>typeof e === 'object' && !Array.isArray(e) && !isClass(e);
|
|
94
|
-
const
|
|
181
|
+
const isAsync = (e)=>typeof e === 'function' && e.constructor.name === 'AsyncFunction';
|
|
182
|
+
const moveArrayItem = (e, t, r)=>{
|
|
183
|
+
const o = e[t];
|
|
184
|
+
e.splice(t, 1);
|
|
185
|
+
e.splice(r, 0, o);
|
|
186
|
+
return e;
|
|
187
|
+
};
|
|
188
|
+
const dedupeArray = (e)=>Array.from(new Set(e));
|
|
189
|
+
const onlyAlphanumeric = (e, ...t)=>{
|
|
190
|
+
t.map((e, r)=>{
|
|
191
|
+
const o = /\S/.test(e);
|
|
192
|
+
if (o) t[r] = t[r].trim();
|
|
193
|
+
return !o ? r : -1;
|
|
194
|
+
}).filter((e)=>e >= 0).every((e)=>{
|
|
195
|
+
t[e] = ' ';
|
|
196
|
+
moveArrayItem(t, e, t.length - 1);
|
|
197
|
+
});
|
|
198
|
+
t = dedupeArray(t);
|
|
199
|
+
const r = new RegExp(`[^A-Za-zÀ-ÖØ-öø-ÿ0-9${t.join('')}]`, 'gi');
|
|
200
|
+
return e.replace(r, '');
|
|
201
|
+
};
|
|
202
|
+
const switchCase = (e, t)=>(r, ...o)=>e[r] ? e[r](...o) : t ? t(r, ...o) : NoOp();
|
|
95
203
|
const pipe = (...e)=>(t)=>e.reduce((e, t)=>t(e), t);
|
|
96
204
|
const conditionally = (e)=>(t)=>{
|
|
97
205
|
return e.if(t) ? e.then(t) : e.else ? e.else(t) : undefined;
|
|
98
206
|
};
|
|
207
|
+
const forOf = (e)=>(t)=>{
|
|
208
|
+
const r = Array.isArray(e) ? (e)=>parseInt(e) : NoOp;
|
|
209
|
+
for (const [o, n] of Object.entries(e)){
|
|
210
|
+
t(n, r(o));
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const forIn = (e)=>(t)=>{
|
|
214
|
+
const r = Array.isArray(e) ? (e)=>parseInt(e) : (e)=>e;
|
|
215
|
+
for(const o in e){
|
|
216
|
+
t(r(o));
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
const e$3 = (e, t)=>{
|
|
220
|
+
return [
|
|
221
|
+
...Object.getOwnPropertyNames(t.prototype),
|
|
222
|
+
...Object.getOwnPropertyNames(Object.getPrototypeOf(e)),
|
|
223
|
+
...Object.getOwnPropertyNames(e)
|
|
224
|
+
];
|
|
225
|
+
};
|
|
226
|
+
const proxifyIterable = (t, r)=>{
|
|
227
|
+
const o = new Proxy(t, {
|
|
228
|
+
get: function(o, n) {
|
|
229
|
+
if (n === Symbol.iterator) {
|
|
230
|
+
return o[Symbol.iterator].bind(o);
|
|
231
|
+
} else if (!e$3(t, r).includes(n)) {
|
|
232
|
+
return o.collection[n];
|
|
233
|
+
}
|
|
234
|
+
return o[n];
|
|
235
|
+
},
|
|
236
|
+
set: function(e, t, r) {
|
|
237
|
+
return Reflect.set(e, t, r);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
return o;
|
|
241
|
+
};
|
|
242
|
+
const clearInstance = (e, t)=>{
|
|
243
|
+
const r = (e, t)=>{
|
|
244
|
+
return [
|
|
245
|
+
...Object.getOwnPropertyNames(t.prototype),
|
|
246
|
+
...Object.getOwnPropertyNames(Object.getPrototypeOf(e)),
|
|
247
|
+
...Object.getOwnPropertyNames(e)
|
|
248
|
+
];
|
|
249
|
+
};
|
|
250
|
+
const o = e;
|
|
251
|
+
for (const n of r(e, t)){
|
|
252
|
+
delete o[n];
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const callHook = (n, r, t)=>{
|
|
257
|
+
return new Promise((i)=>{
|
|
258
|
+
const e = n[r];
|
|
259
|
+
if (e) {
|
|
260
|
+
if (isAsync(e)) {
|
|
261
|
+
e.bind(n)(t).then(()=>{
|
|
262
|
+
i();
|
|
263
|
+
});
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
i(e.bind(n)(t));
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
};
|
|
99
270
|
|
|
100
271
|
const i = (n)=>{
|
|
101
272
|
return {
|
|
@@ -144,16 +315,284 @@ const resolveInjectionTuple = (n)=>switchCase({
|
|
|
144
315
|
throw new Error(`Injection tuple must be of length 1, 2 or 3.`);
|
|
145
316
|
})(n.length);
|
|
146
317
|
|
|
147
|
-
|
|
318
|
+
const resolveParameters = (o, t, i, s)=>{
|
|
319
|
+
const c = [];
|
|
320
|
+
const r = getParamTypes(o);
|
|
321
|
+
const u = getDecoratedParametersIndexes(o);
|
|
322
|
+
let f = 0;
|
|
323
|
+
for (const n of r){
|
|
324
|
+
if (u.context.includes(f)) {
|
|
325
|
+
c.push(t);
|
|
326
|
+
f++;
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
if (u.configuration.includes(f)) {
|
|
330
|
+
c.push(s);
|
|
331
|
+
f++;
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (u.definition.includes(f)) {
|
|
335
|
+
c.push(i);
|
|
336
|
+
f++;
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
c.push(t.require(n));
|
|
340
|
+
f++;
|
|
341
|
+
}
|
|
342
|
+
return c;
|
|
343
|
+
};
|
|
344
|
+
const resolveDependencies = (o)=>{
|
|
345
|
+
const t = [];
|
|
346
|
+
const i = getParamTypes(o);
|
|
347
|
+
const s = getDecoratedParametersIndexes(o);
|
|
348
|
+
let c = 0;
|
|
349
|
+
for (const n of i){
|
|
350
|
+
if (s.context.includes(c) || s.configuration.includes(c) || s.definition.includes(c)) {
|
|
351
|
+
c++;
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
t.push(n);
|
|
355
|
+
c++;
|
|
356
|
+
}
|
|
357
|
+
return t;
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
function e$2(e, t, n) {
|
|
361
|
+
if (t in e) {
|
|
362
|
+
Object.defineProperty(e, t, {
|
|
363
|
+
value: n,
|
|
364
|
+
enumerable: true,
|
|
365
|
+
configurable: true,
|
|
366
|
+
writable: true
|
|
367
|
+
});
|
|
368
|
+
} else {
|
|
369
|
+
e[t] = n;
|
|
370
|
+
}
|
|
371
|
+
return e;
|
|
372
|
+
}
|
|
373
|
+
let h = Symbol.iterator;
|
|
374
|
+
class ListenerCollection {
|
|
375
|
+
dispose() {
|
|
376
|
+
clearInstance(this, ListenerCollection);
|
|
377
|
+
}
|
|
378
|
+
add(...e) {
|
|
379
|
+
const n = (e)=>this.collection[e.channel].push(e.listener);
|
|
380
|
+
const c = conditionally({
|
|
381
|
+
if: ()=>e.length === 2,
|
|
382
|
+
then: ()=>{
|
|
383
|
+
return {
|
|
384
|
+
channel: e[0],
|
|
385
|
+
listener: e[1]
|
|
386
|
+
};
|
|
387
|
+
},
|
|
388
|
+
else: ()=>{
|
|
389
|
+
const t = e[0];
|
|
390
|
+
return {
|
|
391
|
+
channel: t[0],
|
|
392
|
+
listener: t[1]
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
const o = conditionally({
|
|
397
|
+
if: (e)=>!isDefined(this.collection[e.channel]),
|
|
398
|
+
then: (e)=>{
|
|
399
|
+
this.collection[e.channel] = [];
|
|
400
|
+
n(e);
|
|
401
|
+
},
|
|
402
|
+
else: (e)=>{
|
|
403
|
+
n(e);
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
pipe(c, o)();
|
|
407
|
+
return this;
|
|
408
|
+
}
|
|
409
|
+
remove(e, n) {
|
|
410
|
+
const c = (t)=>this.collection[e].splice(t, 1);
|
|
411
|
+
const o = conditionally({
|
|
412
|
+
if: ()=>this.collection[e] && this.collection[e].length === 0,
|
|
413
|
+
then: ()=>delete this.collection[e]
|
|
414
|
+
});
|
|
415
|
+
const s = conditionally({
|
|
416
|
+
if: ()=>isDefined(n),
|
|
417
|
+
then: ()=>c(this.collection[e].indexOf(n)),
|
|
418
|
+
else: ()=>delete this.collection[e]
|
|
419
|
+
});
|
|
420
|
+
const r = conditionally({
|
|
421
|
+
if: (e)=>this.has(e),
|
|
422
|
+
then: (e)=>this.collection[e]
|
|
423
|
+
});
|
|
424
|
+
pipe(r, s, o)();
|
|
425
|
+
return this;
|
|
426
|
+
}
|
|
427
|
+
has(...e) {
|
|
428
|
+
if (isOfType('string')(e[0])) {
|
|
429
|
+
return Object.keys(this.collection).includes(e[0]);
|
|
430
|
+
} else if (isOfType('function')(e[0])) {
|
|
431
|
+
return Object.values(this.collection).flat().includes(e[0]);
|
|
432
|
+
}
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
get(...e) {
|
|
436
|
+
if (isOfType('string')(e[0])) {
|
|
437
|
+
return this.collection[e[0]];
|
|
438
|
+
} else if (isOfType('function')(e[0])) {
|
|
439
|
+
return Object.values(this.collection).flat().filter((t)=>t === e[0]);
|
|
440
|
+
}
|
|
441
|
+
return [];
|
|
442
|
+
}
|
|
443
|
+
clear() {
|
|
444
|
+
const e = forIn(this.collection);
|
|
445
|
+
const t = (e)=>forOf(this.collection[e])((t)=>this.remove(e, t));
|
|
446
|
+
e((e)=>t(e));
|
|
447
|
+
return this;
|
|
448
|
+
}
|
|
449
|
+
get listeners() {
|
|
450
|
+
return Object.values(this.collection).flat();
|
|
451
|
+
}
|
|
452
|
+
get channels() {
|
|
453
|
+
return Object.keys(this.collection);
|
|
454
|
+
}
|
|
455
|
+
get length() {
|
|
456
|
+
return Object.values(this.collection).flat().length;
|
|
457
|
+
}
|
|
458
|
+
[h]() {
|
|
459
|
+
let e = -1;
|
|
460
|
+
const t = this.collection ? Object.keys(this.collection) : [];
|
|
461
|
+
return {
|
|
462
|
+
next: ()=>({
|
|
463
|
+
value: t[++e],
|
|
464
|
+
done: !(e in t)
|
|
465
|
+
})
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
constructor(){
|
|
469
|
+
e$2(this, "collection", {});
|
|
470
|
+
const t = proxifyIterable(this, ListenerCollection);
|
|
471
|
+
return t;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
function e$1(e, n, s) {
|
|
476
|
+
if (n in e) {
|
|
477
|
+
Object.defineProperty(e, n, {
|
|
478
|
+
value: s,
|
|
479
|
+
enumerable: true,
|
|
480
|
+
configurable: true,
|
|
481
|
+
writable: true
|
|
482
|
+
});
|
|
483
|
+
} else {
|
|
484
|
+
e[n] = s;
|
|
485
|
+
}
|
|
486
|
+
return e;
|
|
487
|
+
}
|
|
488
|
+
class EventManager {
|
|
489
|
+
dispose() {
|
|
490
|
+
this.listeners.dispose();
|
|
491
|
+
this.channels.clear();
|
|
492
|
+
clearInstance(this, EventManager);
|
|
493
|
+
}
|
|
494
|
+
addChannels(...e) {
|
|
495
|
+
const n = forOf(e);
|
|
496
|
+
n((e)=>{
|
|
497
|
+
const n = this.cleanChannel(e);
|
|
498
|
+
if (this.channels.has(n)) {
|
|
499
|
+
throw new Error(`Channel '${n}' already exists.`);
|
|
500
|
+
}
|
|
501
|
+
this.channels.add(n);
|
|
502
|
+
});
|
|
503
|
+
return this;
|
|
504
|
+
}
|
|
505
|
+
removeChannels(...e) {
|
|
506
|
+
const n = forOf(e);
|
|
507
|
+
n((e)=>{
|
|
508
|
+
const n = this.cleanChannel(e);
|
|
509
|
+
if (n !== '*' && this.channels.has(n)) {
|
|
510
|
+
this.channels.delete(n);
|
|
511
|
+
this.listeners.remove(n);
|
|
512
|
+
this.onceListeners.remove(n);
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
return this;
|
|
516
|
+
}
|
|
517
|
+
on(e, n) {
|
|
518
|
+
const s = this.cleanChannel(e);
|
|
519
|
+
if (!this.channels.has(s)) {
|
|
520
|
+
throw new Error(`Channel '${s}' was not registered.`);
|
|
521
|
+
}
|
|
522
|
+
this.listeners.add(s, n);
|
|
523
|
+
return this;
|
|
524
|
+
}
|
|
525
|
+
once(e, n) {
|
|
526
|
+
const s = this.cleanChannel(e);
|
|
527
|
+
if (!this.channels.has(s)) {
|
|
528
|
+
throw new Error(`Channel '${s}' was not registered.`);
|
|
529
|
+
}
|
|
530
|
+
this.onceListeners.add(s, n);
|
|
531
|
+
return this;
|
|
532
|
+
}
|
|
533
|
+
off(e, n) {
|
|
534
|
+
const s = this.cleanChannel(e);
|
|
535
|
+
this.listeners.remove(s, n);
|
|
536
|
+
return this;
|
|
537
|
+
}
|
|
538
|
+
emit(e, ...n) {
|
|
539
|
+
const t = this.cleanChannel(e);
|
|
540
|
+
if (this.channels.has(t)) {
|
|
541
|
+
const e = this.onceListeners.get('*') || [];
|
|
542
|
+
const r = this.listeners.get('*') || [];
|
|
543
|
+
const i = this.onceListeners.get(t) || [];
|
|
544
|
+
const h = this.listeners.get(t) || [];
|
|
545
|
+
const o = forOf(e);
|
|
546
|
+
const a = forOf(r);
|
|
547
|
+
const c = forOf(i);
|
|
548
|
+
const l = forOf(h);
|
|
549
|
+
o((e)=>{
|
|
550
|
+
this.run(e, ...n);
|
|
551
|
+
this.onceListeners.remove('*', e);
|
|
552
|
+
});
|
|
553
|
+
a((e)=>{
|
|
554
|
+
this.run(e, ...n);
|
|
555
|
+
});
|
|
556
|
+
c((e)=>{
|
|
557
|
+
this.run(e, ...n);
|
|
558
|
+
this.onceListeners.remove(t, e);
|
|
559
|
+
});
|
|
560
|
+
l((e)=>{
|
|
561
|
+
this.run(e, ...n);
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
return this;
|
|
565
|
+
}
|
|
566
|
+
run(e, ...n) {
|
|
567
|
+
if (isAsync(e)) {
|
|
568
|
+
const s = e;
|
|
569
|
+
return s(...n).then(()=>Promise.resolve());
|
|
570
|
+
}
|
|
571
|
+
e(...n);
|
|
572
|
+
}
|
|
573
|
+
cleanChannel(e) {
|
|
574
|
+
return onlyAlphanumeric(e, '*');
|
|
575
|
+
}
|
|
576
|
+
constructor(...n){
|
|
577
|
+
e$1(this, "listeners", new ListenerCollection());
|
|
578
|
+
e$1(this, "onceListeners", new ListenerCollection());
|
|
579
|
+
e$1(this, "channels", new Set([
|
|
580
|
+
'*'
|
|
581
|
+
]));
|
|
582
|
+
this.addChannels(...n);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
function t(t, e, i) {
|
|
148
587
|
if (e in t) {
|
|
149
588
|
Object.defineProperty(t, e, {
|
|
150
|
-
value:
|
|
589
|
+
value: i,
|
|
151
590
|
enumerable: true,
|
|
152
591
|
configurable: true,
|
|
153
592
|
writable: true
|
|
154
593
|
});
|
|
155
594
|
} else {
|
|
156
|
-
t[e] =
|
|
595
|
+
t[e] = i;
|
|
157
596
|
}
|
|
158
597
|
return t;
|
|
159
598
|
}
|
|
@@ -161,112 +600,68 @@ class Injectable {
|
|
|
161
600
|
static of(t, e) {
|
|
162
601
|
return new Injectable(t, e);
|
|
163
602
|
}
|
|
603
|
+
dispose() {
|
|
604
|
+
if (this.singleton) {
|
|
605
|
+
callHook(this.singleton, 'onDispose', this.context);
|
|
606
|
+
}
|
|
607
|
+
clearInstance(this, Injectable);
|
|
608
|
+
}
|
|
164
609
|
build() {
|
|
165
610
|
if (this.singleton) return this.singleton;
|
|
166
|
-
const t = this.
|
|
611
|
+
const t = resolveParameters(this.concrete, this.context, this.definition, this.configuration);
|
|
167
612
|
const e = new this.concrete(...t);
|
|
613
|
+
const i = this.concrete.prototype instanceof EventManager;
|
|
614
|
+
if (i) {
|
|
615
|
+
e.addChannels(...this.events);
|
|
616
|
+
}
|
|
617
|
+
callHook(e, 'onInit', this.context);
|
|
168
618
|
if (this.isSingleton) {
|
|
169
619
|
this.singleton = e;
|
|
170
620
|
}
|
|
171
621
|
return e;
|
|
172
622
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
let u = 0;
|
|
179
|
-
for (const e of this.dependencies){
|
|
180
|
-
if (i.includes(u)) {
|
|
181
|
-
t.push(this.context);
|
|
182
|
-
u++;
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
if (s.includes(u)) {
|
|
186
|
-
t.push(this.configuration);
|
|
187
|
-
u++;
|
|
188
|
-
continue;
|
|
189
|
-
}
|
|
190
|
-
if (h.includes(u)) {
|
|
191
|
-
t.push(this.metadata);
|
|
192
|
-
u++;
|
|
193
|
-
continue;
|
|
194
|
-
}
|
|
195
|
-
t.push(this.context.require(e));
|
|
196
|
-
u++;
|
|
197
|
-
}
|
|
198
|
-
return t;
|
|
623
|
+
get dependencies() {
|
|
624
|
+
return this.dependenciesIds;
|
|
625
|
+
}
|
|
626
|
+
get definition() {
|
|
627
|
+
return getDefinition(this.concrete) || {};
|
|
199
628
|
}
|
|
200
629
|
get isSingleton() {
|
|
201
|
-
return
|
|
630
|
+
return getDefinitionValue('singleton', this.concrete) || true;
|
|
202
631
|
}
|
|
203
632
|
get injections() {
|
|
204
|
-
return
|
|
205
|
-
}
|
|
206
|
-
get dependencies() {
|
|
207
|
-
return Reflect.getMetadata(ReflectParamTypes, this.concrete) || [];
|
|
633
|
+
return getDefinitionValue('inject', this.concrete) || [];
|
|
208
634
|
}
|
|
209
635
|
get tags() {
|
|
210
|
-
return
|
|
636
|
+
return getDefinitionValue('tags', this.concrete) || [];
|
|
211
637
|
}
|
|
212
|
-
get
|
|
213
|
-
return
|
|
638
|
+
get events() {
|
|
639
|
+
return getDefinitionValue('events', this.concrete) || [];
|
|
214
640
|
}
|
|
215
|
-
constructor(e,
|
|
641
|
+
constructor(e, i){
|
|
216
642
|
t(this, "context", undefined);
|
|
217
643
|
t(this, "identifier", undefined);
|
|
218
644
|
t(this, "concrete", undefined);
|
|
219
645
|
t(this, "configuration", undefined);
|
|
220
646
|
t(this, "singleton", undefined);
|
|
221
|
-
this
|
|
222
|
-
|
|
223
|
-
this.
|
|
224
|
-
|
|
225
|
-
this.
|
|
647
|
+
t(this, "dependenciesIds", undefined);
|
|
648
|
+
this.context = i;
|
|
649
|
+
this.dependenciesIds = [];
|
|
650
|
+
const n = resolveInjectionTuple(e);
|
|
651
|
+
this.identifier = n.identifier;
|
|
652
|
+
this.concrete = n.concrete;
|
|
653
|
+
this.configuration = n.configuration;
|
|
226
654
|
for (const t of this.injections){
|
|
227
655
|
this.context.register(t);
|
|
228
656
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
function e$2(e, t, r) {
|
|
233
|
-
if (t in e) {
|
|
234
|
-
Object.defineProperty(e, t, {
|
|
235
|
-
value: r,
|
|
236
|
-
enumerable: true,
|
|
237
|
-
configurable: true,
|
|
238
|
-
writable: true
|
|
239
|
-
});
|
|
240
|
-
} else {
|
|
241
|
-
e[t] = r;
|
|
242
|
-
}
|
|
243
|
-
return e;
|
|
244
|
-
}
|
|
245
|
-
class AssemblerContext {
|
|
246
|
-
set(e, t) {
|
|
247
|
-
if (this.userData[e]) {
|
|
248
|
-
throw new Error(`Key '${e}' is already defined in context's user data.`);
|
|
657
|
+
this.dependenciesIds = resolveDependencies(this.concrete);
|
|
658
|
+
if (this.isSingleton) {
|
|
659
|
+
this.build();
|
|
249
660
|
}
|
|
250
|
-
this.userData[e] = t;
|
|
251
|
-
return this;
|
|
252
|
-
}
|
|
253
|
-
get(e) {
|
|
254
|
-
return this.userData[e];
|
|
255
|
-
}
|
|
256
|
-
constructor(t){
|
|
257
|
-
e$2(this, "userData", {});
|
|
258
|
-
e$2(this, "register", undefined);
|
|
259
|
-
e$2(this, "has", undefined);
|
|
260
|
-
e$2(this, "require", undefined);
|
|
261
|
-
e$2(this, "tagged", undefined);
|
|
262
|
-
this.register = t.register.bind(t);
|
|
263
|
-
this.has = t.has.bind(t);
|
|
264
|
-
this.require = t.require.bind(t);
|
|
265
|
-
this.tagged = t.tagged.bind(t);
|
|
266
661
|
}
|
|
267
662
|
}
|
|
268
663
|
|
|
269
|
-
function e
|
|
664
|
+
function e(e, t, i) {
|
|
270
665
|
if (t in e) {
|
|
271
666
|
Object.defineProperty(e, t, {
|
|
272
667
|
value: i,
|
|
@@ -283,12 +678,19 @@ class Assembler {
|
|
|
283
678
|
static build(e) {
|
|
284
679
|
return new Assembler(e);
|
|
285
680
|
}
|
|
681
|
+
dispose() {
|
|
682
|
+
for (const [e, t] of this.injectables){
|
|
683
|
+
t.dispose();
|
|
684
|
+
}
|
|
685
|
+
clearInstance(this, Assembler);
|
|
686
|
+
}
|
|
286
687
|
register(e) {
|
|
287
688
|
const t = Injectable.of(e, this.context);
|
|
288
689
|
if (this.has(t.identifier)) {
|
|
289
690
|
throw new Error(`An assemblage is already registered with identifier '${t.identifier.name}'.`);
|
|
290
691
|
}
|
|
291
692
|
this.injectables.set(t.identifier, t);
|
|
693
|
+
callHook(t.concrete, 'onRegister', this.context);
|
|
292
694
|
return t;
|
|
293
695
|
}
|
|
294
696
|
has(e) {
|
|
@@ -304,33 +706,30 @@ class Assembler {
|
|
|
304
706
|
tagged(...e) {
|
|
305
707
|
const t = [];
|
|
306
708
|
for (const i of e){
|
|
307
|
-
for (const [e,
|
|
308
|
-
if (
|
|
709
|
+
for (const [e, s] of this.injectables){
|
|
710
|
+
if (s.tags.includes(i)) t.push(s.build());
|
|
309
711
|
}
|
|
310
712
|
}
|
|
311
713
|
return t;
|
|
312
714
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
715
|
+
get size() {
|
|
716
|
+
return this.injectables.size;
|
|
717
|
+
}
|
|
718
|
+
constructor(t){
|
|
719
|
+
e(this, "injectables", new Map());
|
|
720
|
+
e(this, "context", undefined);
|
|
721
|
+
this.context = {
|
|
722
|
+
register: this.register.bind(this),
|
|
723
|
+
has: this.has.bind(this),
|
|
724
|
+
require: this.require.bind(this),
|
|
725
|
+
tagged: this.tagged.bind(this)
|
|
726
|
+
};
|
|
727
|
+
setDefinitionValue('singleton', true, t);
|
|
728
|
+
const i = this.register([
|
|
729
|
+
t
|
|
320
730
|
]);
|
|
321
|
-
return
|
|
731
|
+
return this.require(i.identifier);
|
|
322
732
|
}
|
|
323
733
|
}
|
|
324
734
|
|
|
325
|
-
|
|
326
|
-
return (t, n, m)=>{
|
|
327
|
-
const s = getOwnCustomMetadata(o, t) || [];
|
|
328
|
-
s.push(m);
|
|
329
|
-
defineCustomMetadata(o, s, t);
|
|
330
|
-
};
|
|
331
|
-
};
|
|
332
|
-
const s = m(ReflectContextParamIndex);
|
|
333
|
-
const e = m(ReflectConfigurationParamIndex);
|
|
334
|
-
const a = m(ReflectMetadataParamIndex);
|
|
335
|
-
|
|
336
|
-
export { AbstractAssemblage, AbstractAssembler, Assemblage, Assembler, AssemblerContext, e as Configuration, s as Context, a as Metadata };
|
|
735
|
+
export { AbstractAssemblage, AbstractAssembler, Assemblage, Assembler, x as Configuration, s as Context, c$1 as Definition };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "assemblerjs",
|
|
3
3
|
"description": "A simple and zero-dependency DI package written in typescript.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.98",
|
|
5
5
|
"author": "Benoît LAHOZ <info@benoitlahoz.io>",
|
|
6
6
|
"bugs": "https://github.com/benoitlahoz/assemblerjs/issues",
|
|
7
7
|
"devDependencies": {
|