assemblerjs 0.0.97 → 0.0.99
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 +8 -0
- package/dist/index.d.ts +56 -42
- package/dist/index.js +1 -1
- package/dist/index.mjs +587 -186
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# assembler.js
|
|
2
2
|
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/js/assemblerjs)
|
|
6
|
+
|
|
7
|
+
   
|
|
8
|
+
|
|
9
|
+
<br />
|
|
10
|
+
|
|
3
11
|
`assembler.js` name is a tribute to Gilles Deleuze and Felix Guattari concept of [_Agencement_](<https://fr.wikipedia.org/wiki/Agencement_(philosophie)>) (in french) that can be translated into [Assemblage](<https://en.wikipedia.org/wiki/Assemblage_(philosophy)>).
|
|
4
12
|
|
|
5
13
|
## Install
|
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,54 +153,60 @@ 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
|
*/
|
|
149
161
|
declare type Identifier<T> = Concrete<T> | Abstract<T>;
|
|
150
162
|
|
|
151
163
|
declare class Injectable<T> {
|
|
152
|
-
|
|
164
|
+
readonly context: AssemblerContext;
|
|
153
165
|
readonly identifier: Identifier<T>;
|
|
154
166
|
readonly concrete: Concrete<T>;
|
|
155
167
|
readonly configuration: Record<string, any>;
|
|
156
|
-
|
|
168
|
+
private dependenciesIds;
|
|
169
|
+
private singletonInstance;
|
|
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
|
/**
|
|
179
|
-
*
|
|
195
|
+
* The singleton instance if this `Injectable` wraps a singleton assemblage.
|
|
180
196
|
*/
|
|
181
|
-
get
|
|
197
|
+
get singleton(): T | undefined;
|
|
182
198
|
/**
|
|
183
|
-
* Injectable assemblage's
|
|
199
|
+
* Injectable assemblage's own injections defined in its decorator's definition.
|
|
184
200
|
*/
|
|
185
|
-
get
|
|
201
|
+
get injections(): Injection<unknown>[];
|
|
186
202
|
/**
|
|
187
|
-
* Tags passed in assemblage's definition
|
|
203
|
+
* Tags passed in assemblage's definition.
|
|
188
204
|
*/
|
|
189
205
|
get tags(): string[];
|
|
190
206
|
/**
|
|
191
|
-
*
|
|
207
|
+
* Event channels passed in assemblage's definition.
|
|
192
208
|
*/
|
|
193
|
-
get
|
|
209
|
+
get events(): string[];
|
|
194
210
|
}
|
|
195
211
|
|
|
196
212
|
/**
|
|
@@ -198,8 +214,6 @@ declare class Injectable<T> {
|
|
|
198
214
|
*/
|
|
199
215
|
declare type Injection<T> = BaseInjection<T> | ConfiguredInjection<T> | ConcreteInjection<T> | ConcreteConfiguredInjection<T>;
|
|
200
216
|
|
|
201
|
-
export declare const Metadata: () => ParameterDecorator;
|
|
202
|
-
|
|
203
217
|
/**
|
|
204
218
|
* An array of fixed length typed values.
|
|
205
219
|
*
|
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",s=(e,t,n)=>{Reflect.defineMetadata(`__${e}__`,t,n)},i=(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}},a=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,s=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]=s(t[n])}return t},l=t=>i(e,t),h=(e,t)=>l(t)[e],u=e=>()=>(t,n,r)=>{const o=i(e,t)||[];o.push(r),s(e,o,t)},f=u(t),d=u(n),g=u(r),p=e=>{const s=(e=>i(t,e)||[])(e),o=(e=>i(r,e)||[])(e),c=(e=>i(n,e)||[])(e);return{context:s,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,s]of Object.entries(e))t(s,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 s=e[t];if(s){if(v(s))return void s.bind(e)(n).then((()=>{r()}));r(s.bind(e)(n))}}));let _=Symbol.iterator;class I{dispose(){P(this,I)}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]}),s=x({if:()=>m(t),then:()=>n(this.collection[e].indexOf(t)),else:()=>delete this.collection[e]}),i=x({if:e=>this.has(e),then:e=>this.collection[e]});return O(i,s,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,I)}}function S(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class ${dispose(){this.listeners.dispose(),this.channels.clear(),P(this,$)}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("*")||[],s=this.onceListeners.get(n)||[],i=this.listeners.get(n)||[],o=A(e),c=A(r),a=A(s),l=A(i);o((e=>{this.run(e,...t),this.onceListeners.remove("*",e)})),c((e=>{this.run(e,...t)})),a((e=>{this.run(e,...t),this.onceListeners.remove(n,e)})),l((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){S(this,"listeners",new I),S(this,"onceListeners",new I),S(this,"channels",new Set(["*"])),this.addChannels(...e)}}const k=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}))()},L=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:()=>k(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 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.singletonInstance&&C(this.singletonInstance,"onDispose",this.context),P(this,N)}build(){if(this.singletonInstance)return this.singletonInstance;const e=(e=>{const t=[],n=o(e.concrete),r=p(e.concrete);let s=0;for(const i of n)r.context.includes(s)?(t.push(e.context),s++):r.configuration.includes(s)?(t.push(e.configuration),s++):r.definition.includes(s)?(t.push(e.definition),s++):(t.push(e.context.require(i)),s++);return t})(this),t=new this.concrete(...e);return this.concrete.prototype instanceof $&&t.addChannels(...this.events),C(t,"onInit",this.context),this.isSingleton&&(this.singletonInstance=t),t}get dependencies(){return this.dependenciesIds}get definition(){return l(this.concrete)||{}}get isSingleton(){return h("singleton",this.concrete)||!0}get singleton(){return this.singletonInstance}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,"dependenciesIds",void 0),R(this,"singletonInstance",void 0),this.context=t,this.dependenciesIds=[];const n=L(e);this.identifier=n.identifier,this.concrete=n.concrete,this.configuration=n.configuration;A(this.injections)((e=>this.context.register(e))),this.dependenciesIds=(e=>{const t=[],n=o(e),r=p(e);let s=0;for(const i of n)r.context.includes(s)||r.configuration.includes(s)||r.definition.includes(s)||t.push(i),s++;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=l(n);r[e]=t,a(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?a(t):{};return t=>(s("is_assemblage",!0,t),s(e,n,t),t)},exports.Assembler=M,exports.Configuration=d,exports.Context=f,exports.Definition=g;
|
package/dist/index.mjs
CHANGED
|
@@ -1,101 +1,498 @@
|
|
|
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$4 = (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$4(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
|
+
};
|
|
270
|
+
|
|
271
|
+
function e$3(e, t, n) {
|
|
272
|
+
if (t in e) {
|
|
273
|
+
Object.defineProperty(e, t, {
|
|
274
|
+
value: n,
|
|
275
|
+
enumerable: true,
|
|
276
|
+
configurable: true,
|
|
277
|
+
writable: true
|
|
278
|
+
});
|
|
279
|
+
} else {
|
|
280
|
+
e[t] = n;
|
|
281
|
+
}
|
|
282
|
+
return e;
|
|
283
|
+
}
|
|
284
|
+
let h = Symbol.iterator;
|
|
285
|
+
class ListenerCollection {
|
|
286
|
+
dispose() {
|
|
287
|
+
clearInstance(this, ListenerCollection);
|
|
288
|
+
}
|
|
289
|
+
add(...e) {
|
|
290
|
+
const n = (e)=>this.collection[e.channel].push(e.listener);
|
|
291
|
+
const c = conditionally({
|
|
292
|
+
if: ()=>e.length === 2,
|
|
293
|
+
then: ()=>{
|
|
294
|
+
return {
|
|
295
|
+
channel: e[0],
|
|
296
|
+
listener: e[1]
|
|
297
|
+
};
|
|
298
|
+
},
|
|
299
|
+
else: ()=>{
|
|
300
|
+
const t = e[0];
|
|
301
|
+
return {
|
|
302
|
+
channel: t[0],
|
|
303
|
+
listener: t[1]
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
const o = conditionally({
|
|
308
|
+
if: (e)=>!isDefined(this.collection[e.channel]),
|
|
309
|
+
then: (e)=>{
|
|
310
|
+
this.collection[e.channel] = [];
|
|
311
|
+
n(e);
|
|
312
|
+
},
|
|
313
|
+
else: (e)=>{
|
|
314
|
+
n(e);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
pipe(c, o)();
|
|
318
|
+
return this;
|
|
319
|
+
}
|
|
320
|
+
remove(e, n) {
|
|
321
|
+
const c = (t)=>this.collection[e].splice(t, 1);
|
|
322
|
+
const o = conditionally({
|
|
323
|
+
if: ()=>this.collection[e] && this.collection[e].length === 0,
|
|
324
|
+
then: ()=>delete this.collection[e]
|
|
325
|
+
});
|
|
326
|
+
const s = conditionally({
|
|
327
|
+
if: ()=>isDefined(n),
|
|
328
|
+
then: ()=>c(this.collection[e].indexOf(n)),
|
|
329
|
+
else: ()=>delete this.collection[e]
|
|
330
|
+
});
|
|
331
|
+
const r = conditionally({
|
|
332
|
+
if: (e)=>this.has(e),
|
|
333
|
+
then: (e)=>this.collection[e]
|
|
334
|
+
});
|
|
335
|
+
pipe(r, s, o)();
|
|
336
|
+
return this;
|
|
337
|
+
}
|
|
338
|
+
has(...e) {
|
|
339
|
+
if (isOfType('string')(e[0])) {
|
|
340
|
+
return Object.keys(this.collection).includes(e[0]);
|
|
341
|
+
} else if (isOfType('function')(e[0])) {
|
|
342
|
+
return Object.values(this.collection).flat().includes(e[0]);
|
|
343
|
+
}
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
get(...e) {
|
|
347
|
+
if (isOfType('string')(e[0])) {
|
|
348
|
+
return this.collection[e[0]];
|
|
349
|
+
} else if (isOfType('function')(e[0])) {
|
|
350
|
+
return Object.values(this.collection).flat().filter((t)=>t === e[0]);
|
|
351
|
+
}
|
|
352
|
+
return [];
|
|
353
|
+
}
|
|
354
|
+
clear() {
|
|
355
|
+
const e = forIn(this.collection);
|
|
356
|
+
const t = (e)=>forOf(this.collection[e])((t)=>this.remove(e, t));
|
|
357
|
+
e((e)=>t(e));
|
|
358
|
+
return this;
|
|
359
|
+
}
|
|
360
|
+
get listeners() {
|
|
361
|
+
return Object.values(this.collection).flat();
|
|
362
|
+
}
|
|
363
|
+
get channels() {
|
|
364
|
+
return Object.keys(this.collection);
|
|
365
|
+
}
|
|
366
|
+
get length() {
|
|
367
|
+
return Object.values(this.collection).flat().length;
|
|
368
|
+
}
|
|
369
|
+
[h]() {
|
|
370
|
+
let e = -1;
|
|
371
|
+
const t = this.collection ? Object.keys(this.collection) : [];
|
|
372
|
+
return {
|
|
373
|
+
next: ()=>({
|
|
374
|
+
value: t[++e],
|
|
375
|
+
done: !(e in t)
|
|
376
|
+
})
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
constructor(){
|
|
380
|
+
e$3(this, "collection", {});
|
|
381
|
+
const t = proxifyIterable(this, ListenerCollection);
|
|
382
|
+
return t;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function e$2(e, n, s) {
|
|
387
|
+
if (n in e) {
|
|
388
|
+
Object.defineProperty(e, n, {
|
|
389
|
+
value: s,
|
|
390
|
+
enumerable: true,
|
|
391
|
+
configurable: true,
|
|
392
|
+
writable: true
|
|
393
|
+
});
|
|
394
|
+
} else {
|
|
395
|
+
e[n] = s;
|
|
396
|
+
}
|
|
397
|
+
return e;
|
|
398
|
+
}
|
|
399
|
+
class EventManager {
|
|
400
|
+
dispose() {
|
|
401
|
+
this.listeners.dispose();
|
|
402
|
+
this.channels.clear();
|
|
403
|
+
clearInstance(this, EventManager);
|
|
404
|
+
}
|
|
405
|
+
addChannels(...e) {
|
|
406
|
+
const n = forOf(e);
|
|
407
|
+
n((e)=>{
|
|
408
|
+
const n = this.cleanChannel(e);
|
|
409
|
+
if (this.channels.has(n)) {
|
|
410
|
+
throw new Error(`Channel '${n}' already exists.`);
|
|
411
|
+
}
|
|
412
|
+
this.channels.add(n);
|
|
413
|
+
});
|
|
414
|
+
return this;
|
|
415
|
+
}
|
|
416
|
+
removeChannels(...e) {
|
|
417
|
+
const n = forOf(e);
|
|
418
|
+
n((e)=>{
|
|
419
|
+
const n = this.cleanChannel(e);
|
|
420
|
+
if (n !== '*' && this.channels.has(n)) {
|
|
421
|
+
this.channels.delete(n);
|
|
422
|
+
this.listeners.remove(n);
|
|
423
|
+
this.onceListeners.remove(n);
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
return this;
|
|
427
|
+
}
|
|
428
|
+
on(e, n) {
|
|
429
|
+
const s = this.cleanChannel(e);
|
|
430
|
+
if (!this.channels.has(s)) {
|
|
431
|
+
throw new Error(`Channel '${s}' was not registered.`);
|
|
432
|
+
}
|
|
433
|
+
this.listeners.add(s, n);
|
|
434
|
+
return this;
|
|
435
|
+
}
|
|
436
|
+
once(e, n) {
|
|
437
|
+
const s = this.cleanChannel(e);
|
|
438
|
+
if (!this.channels.has(s)) {
|
|
439
|
+
throw new Error(`Channel '${s}' was not registered.`);
|
|
440
|
+
}
|
|
441
|
+
this.onceListeners.add(s, n);
|
|
442
|
+
return this;
|
|
443
|
+
}
|
|
444
|
+
off(e, n) {
|
|
445
|
+
const s = this.cleanChannel(e);
|
|
446
|
+
this.listeners.remove(s, n);
|
|
447
|
+
return this;
|
|
448
|
+
}
|
|
449
|
+
emit(e, ...n) {
|
|
450
|
+
const t = this.cleanChannel(e);
|
|
451
|
+
if (this.channels.has(t)) {
|
|
452
|
+
const e = this.onceListeners.get('*') || [];
|
|
453
|
+
const r = this.listeners.get('*') || [];
|
|
454
|
+
const i = this.onceListeners.get(t) || [];
|
|
455
|
+
const h = this.listeners.get(t) || [];
|
|
456
|
+
const o = forOf(e);
|
|
457
|
+
const a = forOf(r);
|
|
458
|
+
const c = forOf(i);
|
|
459
|
+
const l = forOf(h);
|
|
460
|
+
o((e)=>{
|
|
461
|
+
this.run(e, ...n);
|
|
462
|
+
this.onceListeners.remove('*', e);
|
|
463
|
+
});
|
|
464
|
+
a((e)=>{
|
|
465
|
+
this.run(e, ...n);
|
|
466
|
+
});
|
|
467
|
+
c((e)=>{
|
|
468
|
+
this.run(e, ...n);
|
|
469
|
+
this.onceListeners.remove(t, e);
|
|
470
|
+
});
|
|
471
|
+
l((e)=>{
|
|
472
|
+
this.run(e, ...n);
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
return this;
|
|
476
|
+
}
|
|
477
|
+
run(e, ...n) {
|
|
478
|
+
if (isAsync(e)) {
|
|
479
|
+
const s = e;
|
|
480
|
+
return s(...n).then(()=>Promise.resolve());
|
|
481
|
+
}
|
|
482
|
+
e(...n);
|
|
483
|
+
}
|
|
484
|
+
cleanChannel(e) {
|
|
485
|
+
return onlyAlphanumeric(e, '*');
|
|
486
|
+
}
|
|
487
|
+
constructor(...n){
|
|
488
|
+
e$2(this, "listeners", new ListenerCollection());
|
|
489
|
+
e$2(this, "onceListeners", new ListenerCollection());
|
|
490
|
+
e$2(this, "channels", new Set([
|
|
491
|
+
'*'
|
|
492
|
+
]));
|
|
493
|
+
this.addChannels(...n);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
99
496
|
|
|
100
497
|
const i = (n)=>{
|
|
101
498
|
return {
|
|
@@ -144,129 +541,129 @@ const resolveInjectionTuple = (n)=>switchCase({
|
|
|
144
541
|
throw new Error(`Injection tuple must be of length 1, 2 or 3.`);
|
|
145
542
|
})(n.length);
|
|
146
543
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
544
|
+
const resolveParameters = (o)=>{
|
|
545
|
+
const t = [];
|
|
546
|
+
const c = getParamTypes(o.concrete);
|
|
547
|
+
const i = getDecoratedParametersIndexes(o.concrete);
|
|
548
|
+
let s = 0;
|
|
549
|
+
for (const n of c){
|
|
550
|
+
if (i.context.includes(s)) {
|
|
551
|
+
t.push(o.context);
|
|
552
|
+
s++;
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
if (i.configuration.includes(s)) {
|
|
556
|
+
t.push(o.configuration);
|
|
557
|
+
s++;
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
if (i.definition.includes(s)) {
|
|
561
|
+
t.push(o.definition);
|
|
562
|
+
s++;
|
|
563
|
+
continue;
|
|
564
|
+
}
|
|
565
|
+
t.push(o.context.require(n));
|
|
566
|
+
s++;
|
|
567
|
+
}
|
|
568
|
+
return t;
|
|
569
|
+
};
|
|
570
|
+
const resolveDependencies = (o)=>{
|
|
571
|
+
const t = [];
|
|
572
|
+
const c = getParamTypes(o);
|
|
573
|
+
const i = getDecoratedParametersIndexes(o);
|
|
574
|
+
let s = 0;
|
|
575
|
+
for (const n of c){
|
|
576
|
+
if (i.context.includes(s) || i.configuration.includes(s) || i.definition.includes(s)) {
|
|
577
|
+
s++;
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
t.push(n);
|
|
581
|
+
s++;
|
|
582
|
+
}
|
|
583
|
+
return t;
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
function e$1(e, t, n) {
|
|
587
|
+
if (t in e) {
|
|
588
|
+
Object.defineProperty(e, t, {
|
|
150
589
|
value: n,
|
|
151
590
|
enumerable: true,
|
|
152
591
|
configurable: true,
|
|
153
592
|
writable: true
|
|
154
593
|
});
|
|
155
594
|
} else {
|
|
156
|
-
t
|
|
595
|
+
e[t] = n;
|
|
157
596
|
}
|
|
158
|
-
return
|
|
597
|
+
return e;
|
|
159
598
|
}
|
|
160
599
|
class Injectable {
|
|
161
|
-
static of(
|
|
162
|
-
return new Injectable(
|
|
600
|
+
static of(e, t) {
|
|
601
|
+
return new Injectable(e, t);
|
|
163
602
|
}
|
|
164
|
-
|
|
165
|
-
if (this.
|
|
166
|
-
|
|
167
|
-
const e = new this.concrete(...t);
|
|
168
|
-
if (this.isSingleton) {
|
|
169
|
-
this.singleton = e;
|
|
603
|
+
dispose() {
|
|
604
|
+
if (this.singletonInstance) {
|
|
605
|
+
callHook(this.singletonInstance, 'onDispose', this.context);
|
|
170
606
|
}
|
|
171
|
-
|
|
607
|
+
clearInstance(this, Injectable);
|
|
172
608
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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++;
|
|
609
|
+
build() {
|
|
610
|
+
if (this.singletonInstance) return this.singletonInstance;
|
|
611
|
+
const e = resolveParameters(this);
|
|
612
|
+
const t = new this.concrete(...e);
|
|
613
|
+
const n = this.concrete.prototype instanceof EventManager;
|
|
614
|
+
if (n) {
|
|
615
|
+
t.addChannels(...this.events);
|
|
616
|
+
}
|
|
617
|
+
callHook(t, 'onInit', this.context);
|
|
618
|
+
if (this.isSingleton) {
|
|
619
|
+
this.singletonInstance = t;
|
|
197
620
|
}
|
|
198
621
|
return t;
|
|
199
622
|
}
|
|
623
|
+
get dependencies() {
|
|
624
|
+
return this.dependenciesIds;
|
|
625
|
+
}
|
|
626
|
+
get definition() {
|
|
627
|
+
return getDefinition(this.concrete) || {};
|
|
628
|
+
}
|
|
200
629
|
get isSingleton() {
|
|
201
|
-
return
|
|
630
|
+
return getDefinitionValue('singleton', this.concrete) || true;
|
|
202
631
|
}
|
|
203
|
-
get
|
|
204
|
-
return
|
|
632
|
+
get singleton() {
|
|
633
|
+
return this.singletonInstance;
|
|
205
634
|
}
|
|
206
|
-
get
|
|
207
|
-
return
|
|
635
|
+
get injections() {
|
|
636
|
+
return getDefinitionValue('inject', this.concrete) || [];
|
|
208
637
|
}
|
|
209
638
|
get tags() {
|
|
210
|
-
return
|
|
211
|
-
}
|
|
212
|
-
get metadata() {
|
|
213
|
-
return getCustomMetadata('metadata', this.concrete) || {};
|
|
214
|
-
}
|
|
215
|
-
constructor(e, n){
|
|
216
|
-
t(this, "context", undefined);
|
|
217
|
-
t(this, "identifier", undefined);
|
|
218
|
-
t(this, "concrete", undefined);
|
|
219
|
-
t(this, "configuration", undefined);
|
|
220
|
-
t(this, "singleton", undefined);
|
|
221
|
-
this.context = n;
|
|
222
|
-
const i = resolveInjectionTuple(e);
|
|
223
|
-
this.identifier = i.identifier;
|
|
224
|
-
this.concrete = i.concrete;
|
|
225
|
-
this.configuration = i.configuration;
|
|
226
|
-
for (const t of this.injections){
|
|
227
|
-
this.context.register(t);
|
|
228
|
-
}
|
|
639
|
+
return getDefinitionValue('tags', this.concrete) || [];
|
|
229
640
|
}
|
|
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;
|
|
641
|
+
get events() {
|
|
642
|
+
return getDefinitionValue('events', this.concrete) || [];
|
|
242
643
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
644
|
+
constructor(t, i){
|
|
645
|
+
e$1(this, "context", undefined);
|
|
646
|
+
e$1(this, "identifier", undefined);
|
|
647
|
+
e$1(this, "concrete", undefined);
|
|
648
|
+
e$1(this, "configuration", undefined);
|
|
649
|
+
e$1(this, "dependenciesIds", undefined);
|
|
650
|
+
e$1(this, "singletonInstance", undefined);
|
|
651
|
+
this.context = i;
|
|
652
|
+
this.dependenciesIds = [];
|
|
653
|
+
const s = resolveInjectionTuple(t);
|
|
654
|
+
this.identifier = s.identifier;
|
|
655
|
+
this.concrete = s.concrete;
|
|
656
|
+
this.configuration = s.configuration;
|
|
657
|
+
const o = forOf(this.injections);
|
|
658
|
+
o((e)=>this.context.register(e));
|
|
659
|
+
this.dependenciesIds = resolveDependencies(this.concrete);
|
|
660
|
+
if (this.isSingleton) {
|
|
661
|
+
this.build();
|
|
249
662
|
}
|
|
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
663
|
}
|
|
267
664
|
}
|
|
268
665
|
|
|
269
|
-
function e
|
|
666
|
+
function e(e, t, i) {
|
|
270
667
|
if (t in e) {
|
|
271
668
|
Object.defineProperty(e, t, {
|
|
272
669
|
value: i,
|
|
@@ -283,12 +680,19 @@ class Assembler {
|
|
|
283
680
|
static build(e) {
|
|
284
681
|
return new Assembler(e);
|
|
285
682
|
}
|
|
683
|
+
dispose() {
|
|
684
|
+
for (const [e, t] of this.injectables){
|
|
685
|
+
t.dispose();
|
|
686
|
+
}
|
|
687
|
+
clearInstance(this, Assembler);
|
|
688
|
+
}
|
|
286
689
|
register(e) {
|
|
287
690
|
const t = Injectable.of(e, this.context);
|
|
288
691
|
if (this.has(t.identifier)) {
|
|
289
692
|
throw new Error(`An assemblage is already registered with identifier '${t.identifier.name}'.`);
|
|
290
693
|
}
|
|
291
694
|
this.injectables.set(t.identifier, t);
|
|
695
|
+
callHook(t.concrete, 'onRegister', this.context);
|
|
292
696
|
return t;
|
|
293
697
|
}
|
|
294
698
|
has(e) {
|
|
@@ -304,33 +708,30 @@ class Assembler {
|
|
|
304
708
|
tagged(...e) {
|
|
305
709
|
const t = [];
|
|
306
710
|
for (const i of e){
|
|
307
|
-
for (const [e,
|
|
308
|
-
if (
|
|
711
|
+
for (const [e, s] of this.injectables){
|
|
712
|
+
if (s.tags.includes(i)) t.push(s.build());
|
|
309
713
|
}
|
|
310
714
|
}
|
|
311
715
|
return t;
|
|
312
716
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
717
|
+
get size() {
|
|
718
|
+
return this.injectables.size;
|
|
719
|
+
}
|
|
720
|
+
constructor(t){
|
|
721
|
+
e(this, "injectables", new Map());
|
|
722
|
+
e(this, "context", undefined);
|
|
723
|
+
this.context = {
|
|
724
|
+
register: this.register.bind(this),
|
|
725
|
+
has: this.has.bind(this),
|
|
726
|
+
require: this.require.bind(this),
|
|
727
|
+
tagged: this.tagged.bind(this)
|
|
728
|
+
};
|
|
729
|
+
setDefinitionValue('singleton', true, t);
|
|
730
|
+
const i = this.register([
|
|
731
|
+
t
|
|
320
732
|
]);
|
|
321
|
-
return
|
|
733
|
+
return this.require(i.identifier);
|
|
322
734
|
}
|
|
323
735
|
}
|
|
324
736
|
|
|
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 };
|
|
737
|
+
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.99",
|
|
5
5
|
"author": "Benoît LAHOZ <info@benoitlahoz.io>",
|
|
6
6
|
"bugs": "https://github.com/benoitlahoz/assemblerjs/issues",
|
|
7
7
|
"devDependencies": {
|