assemblerjs 0.3.21 → 0.3.22

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 CHANGED
@@ -2,10 +2,12 @@
2
2
 
3
3
  A general purpose and zero-dependency [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) framework for node and browser.
4
4
 
5
- ![Statements](https://img.shields.io/badge/statements-88.59%25-yellow.svg?style=flat) ![Branches](https://img.shields.io/badge/branches-77.32%25-red.svg?style=flat) ![Functions](https://img.shields.io/badge/functions-85.86%25-yellow.svg?style=flat) ![Lines](https://img.shields.io/badge/lines-88.67%25-yellow.svg?style=flat)
5
+ ![Statements](https://img.shields.io/badge/statements-89.74%25-yellow.svg?style=flat) ![Branches](https://img.shields.io/badge/branches-78.6%25-red.svg?style=flat) ![Functions](https://img.shields.io/badge/functions-86.51%25-yellow.svg?style=flat) ![Lines](https://img.shields.io/badge/lines-89.87%25-yellow.svg?style=flat)
6
6
 
7
7
  ---
8
8
 
9
+ `assembler.js` is inspired by both DIOD and Nestjs.
10
+
9
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)>).
10
12
 
11
13
  ## Install
@@ -20,7 +22,10 @@ npm install assemblerjs
20
22
 
21
23
  ## Usage
22
24
 
23
- ### Order of execution
25
+ The main block of `assembler.js` is the **Assemblage**. It is created by decorating classes with the `@Assemblage` decorator. To keep everything type-safe, classes may implement `AbstractAssemblage` abstract class or define their own abstract class that extends it.
26
+ These abstract classes are used as identifiers to inject dependencies.
27
+
28
+ ## Order of execution
24
29
 
25
30
  Dependencies are registered and built recursively from the entry assemblage resolved by `Assembler.build`.
26
31
 
@@ -45,7 +50,7 @@ The entry point assemblage is called last.
45
50
  Called when disposing the assembler via the `dispose` method injected by the `@Dispose` decorator.
46
51
  This will be called like the `onInit` method, walking through the dependency tree, except for the entry point assemblage, called last.
47
52
 
48
- ### Events
53
+ ## Events
49
54
 
50
55
  `assembler.js` provides an `EventManager` that can be subclassed by any assemblage.
51
56
 
package/dist/index.d.ts CHANGED
@@ -80,8 +80,6 @@ declare interface AssemblageDefinition {
80
80
  inject?: Injection<unknown>[];
81
81
  use?: InstanceInjection<unknown>[];
82
82
  tags?: string | string[];
83
- controller?: true;
84
- path?: string;
85
83
  metadata?: Record<string, any>;
86
84
  }
87
85
 
@@ -175,7 +173,7 @@ declare interface AssemblerPrivateContext extends AssemblerContext {
175
173
  * @param { number | undefined } interval The interval in milliseconds at which the value is checked (defaults to 25 milliseconds).
176
174
  * @returns { Promise<void> } A promise that calls the original method when resolving.
177
175
  */
178
- export declare const Await: (property: string, interval?: number) => (_target: any, _propertyKey: string, descriptor: TypedPropertyDescriptor<(...params: any[]) => Promise<any>>) => void;
176
+ export declare const Await: (property: string, interval?: number) => MethodDecorator;
179
177
 
180
178
  /**
181
179
  * Injectable binds a concrete class to an abstract class as identifier without configuration.
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=(...e)=>{},t=(...e)=>t=>{if(e.includes(typeof t))return typeof t},n=e=>!(e=>void 0===e)(e)&&!(e=>null===e)(e),s=e=>e&&"function"==typeof e&&void 0!==e.constructor,i=e=>"function"==typeof e&&"AsyncFunction"===e.constructor.name,r=(e,...t)=>{t.map(((e,n)=>{const s=/\S/.test(e);return s&&(t[n]=t[n].trim()),s?-1:n})).filter((e=>e>=0)).every((e=>{t[e]=" ",((e,t,n)=>{const s=e[t];e.splice(t,1),e.splice(n,0,s)})(t,e,t.length-1)})),t=(e=>Array.from(new Set(e)))(t);const n=new RegExp(`[^A-Za-zÀ-ÖØ-öø-ÿ0-9${t.join("")}]`,"gi");return e.replace(n,"")},o=(...e)=>t=>e.reduce(((e,t)=>t(e)),t),c=e=>t=>e.if(t)?e.then(t):e.else?e.else(t):void 0,a=t=>n=>{const s=Array.isArray(t)?e=>parseInt(e):e;for(const[e,i]of Object.entries(t))n(i,s(e))},h=(e,t)=>{const n=new Proxy(e,{get:function(n,s){return s===Symbol.iterator?n[Symbol.iterator].bind(n):((e,t)=>[...Object.getOwnPropertyNames(t.prototype),...Object.getOwnPropertyNames(Object.getPrototypeOf(e)),...Object.getOwnPropertyNames(e)])(e,t).includes(s)?n[s]:n.collection[s]},set:function(e,t,n){return Reflect.set(e,t,n)}});return n},l=(e,t)=>{const n=e;for(const s of((e,t)=>[...Object.getOwnPropertyNames(t.prototype),...Object.getOwnPropertyNames(Object.getPrototypeOf(e)),...Object.getOwnPropertyNames(e)])(e,t))delete n[s]};let u=Symbol.iterator;class f{dispose(){l(this,f)}add(...e){const t=e=>this.collection[e.channel].push(e.listener),s=c({if:()=>2===e.length,then:()=>({channel:e[0],listener:e[1]}),else:()=>{const t=e[0];return{channel:t[0],listener:t[1]}}}),i=c({if:e=>!n(this.collection[e.channel]),then:e=>{this.collection[e.channel]=[],t(e)},else:e=>{t(e)}});return o(s,i)(),this}remove(e,t){const s=t=>this.collection[e].splice(t,1),i=c({if:()=>this.collection[e]&&0===this.collection[e].length,then:()=>delete this.collection[e]}),r=c({if:()=>n(t),then:()=>s(this.collection[e].indexOf(t)),else:()=>delete this.collection[e]}),a=c({if:e=>this.has(e),then:e=>this.collection[e]});return o(a,r,i)(),this}has(...e){return t("string")(e[0])?Object.keys(this.collection).includes(e[0]):!!t("function")(e[0])&&Object.values(this.collection).flat().includes(e[0])}get(...e){return t("string")(e[0])?this.collection[e[0]]:t("function")(e[0])?Object.values(this.collection).flat().filter((t=>t===e[0])):[]}clear(){const e=(e=>t=>{const n=Array.isArray(e)?e=>parseInt(e):e=>e;for(const s in e)t(n(s))})(this.collection),t=e=>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}[u](){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 h(this,f)}}function d(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class p{dispose(){this.listeners.dispose(),this.channels.clear(),l(this,p)}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("*")||[],s=this.listeners.get("*")||[],i=this.onceListeners.get(n)||[],r=this.listeners.get(n)||[],o=a(e),c=a(s),h=a(i),l=a(r);o((e=>{this.run(e,...t),this.onceListeners.remove("*",e)})),c((e=>{this.run(e,...t)})),h((e=>{this.run(e,...t),this.onceListeners.remove(n,e)})),l((e=>{this.run(e,...t)}))}return this}run(e,...t){if(i(e)){return e(...t).then((()=>Promise.resolve()))}e(...t)}cleanChannel(e){return r(e,"*")}constructor(...e){d(this,"listeners",new f),d(this,"onceListeners",new f),d(this,"channels",new Set(["*"])),this.addChannels(...e)}}const g="is_assemblage",b="assemblage_definition",y="context_param_index",v="config_param_index",m="definition_param_index",w="dispose_param_index",x="use_param_index",C="use_token",j=(e,t,n)=>{Reflect.defineMetadata(`__${e}__`,t,n)},O=(e,t)=>Reflect.getOwnMetadata(`__${e}__`,t),A=e=>Reflect.getMetadata("design:paramtypes",e)||[],I={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},use:{test:e=>void 0===e||Array.isArray(e)&&e.every((e=>Array.isArray(e)&&2==e.length)),throw:()=>{throw new Error("'use' property must be an array of tuples of length 2.")},transform:e=>e},tags:{test:e=>void 0===e||"string"==typeof e||Array.isArray(e)&&e.every((e=>"string"==typeof e)),throw:()=>{throw new Error("'tags' property must be a string or an array of strings.")},transform:e=>"string"==typeof e?[e]:e},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}},E=e=>{const t={...e};for(const n in t){if(!Object.keys(I).includes(n))throw new Error(`Property '${n}' is not a valid assemblage definition property.`);const e=I[n].test,s=I[n].throw,i=I[n].transform;if(e(t[n])||s(),"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},_=e=>O(b,e),P=(e,t)=>_(t)[e];const $=e=>{const t=e?E(e):{};return e=>(j(g,!0,e),j(b,t,e),e)};class S{}S=function(e,t,n,s){var i,r=arguments.length,o=r<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,n):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,n,s);else for(var c=e.length-1;c>=0;c--)(i=e[c])&&(o=(r<3?i(o):r>3?i(t,n,o):i(t,n))||o);return r>3&&o&&Object.defineProperty(t,n,o),o}([$()],S);const R=(e,t,n)=>new Promise((s=>{const r=e[t];if(r){if(i(r))return void r.bind(e)(n).then((()=>{s()}));s(r.bind(e)(n))}})),k=e=>{const t=(e=>O(y,e)||[])(e),n=(e=>O(m,e)||[])(e),s=(e=>O(v,e)||[])(e),i=(e=>O(w,e)||[])(e),r=(e=>O(x,e)||[])(e);return{context:t,definition:n,configuration:s,dispose:i,use:r}};function M(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{static of(e,t,n){return new L(e,t,n)}dispose(){this.singletonInstance&&(((e,t)=>{if(e.concrete.prototype instanceof p){const n=t;for(const t of e.events)n.off(t);n.removeChannels(...e.events),e.privateContext.removeChannels(...e.events)}})(this,this.singletonInstance),R(this.singletonInstance,"onDispose",this.publicContext),l(this.singletonInstance,this.concrete)),l(this,L)}build(){if(this.singletonInstance)return this.singletonInstance;const e=(e=>{const t=[],n=A(e.concrete),s=k(e.concrete);let i=0;for(const r of n)if(s.context.includes(i))t.push(e.publicContext),i++;else if(s.configuration.includes(i))t.push(e.configuration),i++;else if(s.definition.includes(i))t.push(e.definition),i++;else if(s.dispose.includes(i))t.push(e.privateContext.dispose),i++;else if(s.use.includes(i)){const n=O(C,e.concrete)[i];t.push(e.privateContext.require(n)),i++}else t.push(e.privateContext.require(r)),i++;return t})(this),t=new this.concrete(...e);return((e,t)=>{if(e.concrete.prototype instanceof p){const n=t,s=n.channels;for(const t of e.events)s.has(t)||n.addChannels(t),e.privateContext.events.has(t)||e.privateContext.addChannels(t);for(const i of e.events)t.on(i,((...t)=>{e.privateContext.emit(i,...t)}))}})(this,t),this.isSingleton?(this.singletonInstance=t,this.privateContext.prepareInit(t),this.singletonInstance):(R(t,"onInit",this.publicContext),t)}get dependencies(){return this.dependenciesIds}get definition(){return _(this.concrete)||{}}get isSingleton(){return P("singleton",this.concrete)||!0}get singleton(){return this.singletonInstance}get injections(){return P("inject",this.concrete)||[]}get objects(){return P("use",this.concrete)||[]}get tags(){return P("tags",this.concrete)||[]}get events(){return P("events",this.concrete)||[]}constructor(e,t,n){if(M(this,"privateContext",void 0),M(this,"publicContext",void 0),M(this,"identifier",void 0),M(this,"concrete",void 0),M(this,"configuration",void 0),M(this,"dependenciesIds",void 0),M(this,"singletonInstance",void 0),this.privateContext=t,this.publicContext=n,this.dependenciesIds=[],this.identifier=e.identifier,this.concrete=e.concrete,this.configuration=e.configuration,!(e=>O(g,e)||!1)(this.concrete))throw new Error(`Class '${this.concrete.name}' is not an Assemblage.`);a(this.injections)((e=>this.privateContext.register(e)));a(this.objects)((e=>{"string"==typeof e[0]||"symbol"==typeof e[0]?this.privateContext.use(e[0],e[1]):this.privateContext.register(e,!0)})),this.dependenciesIds=(e=>{const t=[],n=A(e),s=k(e);let i=0;for(const r of n)s.context.includes(i)||s.configuration.includes(i)||s.definition.includes(i)||s.dispose.includes(i)||s.use.includes(i)||t.push(r),i++;return t})(this.concrete),e.instance&&(this.singletonInstance=e.instance)}}const q=e=>{const t=()=>s(e[0])&&(e=>"object"==typeof e&&!Array.isArray(e)&&!s(e))(e[1]);return o(c({if:()=>s(e[0])&&s(e[1]),then:()=>({identifier:e[0],concrete:e[1],configuration:{}})}),c({if:()=>t(),then:()=>({identifier:e[0],concrete:e[0],configuration:e[1]}),else:e=>e}))()},N=e=>((e,t)=>(n,...s)=>e[n]?e[n](...s):t?t(n,...s):void 0)({1:()=>(e=>({identifier:e[0],concrete:e[0],configuration:{}}))(e),2:()=>q(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 D(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class z extends p{static build(e){const t=new z;((e,t,n)=>{const s=_(n);s[e]=t,E(s)})("singleton",!0,e);const n=t.register([e]),s=t.require(n.identifier),i=t.initCache.indexOf(s);t.initCache.splice(i,1);for(const r of t.initCache)R(r,"onInit",t.publicContext);return R(s,"onInit",t.publicContext),t.initCache.length=0,s}dispose(){for(const[e,t]of this.injectables)t.dispose();l(this,z)}register(e,t=!1){const n=!0===t?{identifier:(s=e)[0],concrete:s[0],instance:s[1],configuration:{}}:N(e);var s;if(this.has(n.identifier))throw new Error(`An assemblage is already registered with identifier '${n.identifier.name}'.`);const i=L.of(n,this.privateContext,this.publicContext);return this.injectables.set(i.identifier,i),R(i.concrete,"onRegister",this.publicContext),i}use(e,t){if(this.has(e))throw new Error(`A valu is already registered for identifier '${String(e)}'.`);return this.objects.set(e,t),t}prepareInit(e){return this.initCache.push(e),this.initCache}has(e){return"string"==typeof e||"symbol"==typeof e?this.objects.has(e):this.injectables.has(e)}require(e){switch(typeof e){case"string":case"symbol":if(!this.objects.has(e))throw new Error(`Injected object with identifier '${String(e)}' has not been registered.`);return this.objects.get(e);default:if(!this.injectables.has(e))throw new Error(`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,s]of this.injectables)s.tags.includes(n)&&t.push(s.build());return t}get size(){return this.injectables.size}constructor(){super(),D(this,"injectables",new Map),D(this,"objects",new Map),D(this,"initCache",[]),D(this,"privateContext",void 0),D(this,"publicContext",void 0),this.publicContext={has:this.has.bind(this),require:this.require.bind(this),tagged:this.tagged.bind(this),on:this.on.bind(this),once:this.once.bind(this),off:this.off.bind(this),events:this.channels},this.privateContext={...this.publicContext,register:this.register.bind(this),use:this.use.bind(this),prepareInit:this.prepareInit.bind(this),emit:this.emit.bind(this),addChannels:this.addChannels.bind(this),removeChannels:this.removeChannels.bind(this),dispose:this.dispose.bind(this)}}}const W=e=>()=>(t,n,s)=>{const i=O(e,t)||[];i.push(s),j(e,i,t)},F=W(y),T=W(v),U=W(m),Z=W(w);class B{}exports.AbstractAssemblage=class{static onRegister(e){}},exports.AbstractAssembler=class extends B{},exports.AbstractEventManager=B,exports.Assemblage=$,exports.Assembler=z,exports.Await=(e,t=25)=>(n,s,i)=>{const r=i.value;i.value=async function(){return new Promise((n=>{if(this[e])r.apply(this),n();else{const s=setInterval((()=>{this[e]&&(clearInterval(s),r.apply(this),n())}),t)}}))}},exports.Configuration=T,exports.Context=F,exports.Definition=U,exports.Dispose=Z,exports.EventManager=p,exports.Use=e=>(t,n,s)=>{const i=O(x,t)||[];i.push(s),j(x,i,t);const r=O(C,t)||{};r[s]=e,j(C,r,t)};
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=(...e)=>{},t=(...e)=>t=>{if(e.includes(typeof t))return typeof t},n=e=>!(e=>void 0===e)(e)&&!(e=>null===e)(e),s=e=>e&&"function"==typeof e&&void 0!==e.constructor,i=e=>"function"==typeof e&&"AsyncFunction"===e.constructor.name,r=(e,...t)=>{t.map(((e,n)=>{const s=/\S/.test(e);return s&&(t[n]=t[n].trim()),s?-1:n})).filter((e=>e>=0)).every((e=>{t[e]=" ",((e,t,n)=>{const s=e[t];e.splice(t,1),e.splice(n,0,s)})(t,e,t.length-1)})),t=(e=>Array.from(new Set(e)))(t);const n=new RegExp(`[^A-Za-zÀ-ÖØ-öø-ÿ0-9${t.join("")}]`,"gi");return e.replace(n,"")},o=(...e)=>t=>e.reduce(((e,t)=>t(e)),t),c=e=>t=>e.if(t)?e.then(t):e.else?e.else(t):void 0,a=t=>n=>{const s=Array.isArray(t)?e=>parseInt(e):e;for(const[e,i]of Object.entries(t))n(i,s(e))},h=(e,t)=>{const n=new Proxy(e,{get:function(n,s){return s===Symbol.iterator?n[Symbol.iterator].bind(n):((e,t)=>[...Object.getOwnPropertyNames(t.prototype),...Object.getOwnPropertyNames(Object.getPrototypeOf(e)),...Object.getOwnPropertyNames(e)])(e,t).includes(s)?n[s]:n.collection[s]},set:function(e,t,n){return Reflect.set(e,t,n)}});return n},l=(e,t)=>{const n=e;for(const s of((e,t)=>[...Object.getOwnPropertyNames(t.prototype),...Object.getOwnPropertyNames(Object.getPrototypeOf(e)),...Object.getOwnPropertyNames(e)])(e,t))delete n[s]};let u=Symbol.iterator;class f{dispose(){l(this,f)}add(...e){const t=e=>this.collection[e.channel].push(e.listener),s=c({if:()=>2===e.length,then:()=>({channel:e[0],listener:e[1]}),else:()=>{const t=e[0];return{channel:t[0],listener:t[1]}}}),i=c({if:e=>!n(this.collection[e.channel]),then:e=>{this.collection[e.channel]=[],t(e)},else:e=>{t(e)}});return o(s,i)(),this}remove(e,t){const s=t=>this.collection[e].splice(t,1),i=c({if:()=>this.collection[e]&&0===this.collection[e].length,then:()=>delete this.collection[e]}),r=c({if:()=>n(t),then:()=>s(this.collection[e].indexOf(t)),else:()=>delete this.collection[e]}),a=c({if:e=>this.has(e),then:e=>this.collection[e]});return o(a,r,i)(),this}has(...e){return t("string")(e[0])?Object.keys(this.collection).includes(e[0]):!!t("function")(e[0])&&Object.values(this.collection).flat().includes(e[0])}get(...e){return t("string")(e[0])?this.collection[e[0]]:t("function")(e[0])?Object.values(this.collection).flat().filter((t=>t===e[0])):[]}clear(){const e=(e=>t=>{const n=Array.isArray(e)?e=>parseInt(e):e=>e;for(const s in e)t(n(s))})(this.collection),t=e=>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}[u](){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 h(this,f)}}function d(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class p{dispose(){this.listeners.dispose(),this.channels.clear(),l(this,p)}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("*")||[],s=this.listeners.get("*")||[],i=this.onceListeners.get(n)||[],r=this.listeners.get(n)||[],o=a(e),c=a(s),h=a(i),l=a(r);o((e=>{this.run(e,...t),this.onceListeners.remove("*",e)})),c((e=>{this.run(e,...t)})),h((e=>{this.run(e,...t),this.onceListeners.remove(n,e)})),l((e=>{this.run(e,...t)}))}return this}run(e,...t){if(i(e)){return e(...t).then((()=>Promise.resolve()))}e(...t)}cleanChannel(e){return r(e,"*")}constructor(...e){d(this,"listeners",new f),d(this,"onceListeners",new f),d(this,"channels",new Set(["*"])),this.addChannels(...e)}}const g="is_assemblage",b="assemblage_definition",y="context_param_index",v="config_param_index",m="definition_param_index",w="dispose_param_index",x="use_param_index",C="use_token",j=(e,t,n)=>{Reflect.defineMetadata(`__${e}__`,t,n)},O=(e,t)=>Reflect.getOwnMetadata(`__${e}__`,t),A=e=>Reflect.getMetadata("design:paramtypes",e)||[],I={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},use:{test:e=>void 0===e||Array.isArray(e)&&e.every((e=>Array.isArray(e)&&2==e.length)),throw:()=>{throw new Error("'use' property must be an array of tuples of length 2.")},transform:e=>e},tags:{test:e=>void 0===e||"string"==typeof e||Array.isArray(e)&&e.every((e=>"string"==typeof e)),throw:()=>{throw new Error("'tags' property must be a string or an array of strings.")},transform:e=>"string"==typeof e?[e]:e},metadata:{test:e=>("object"==typeof e||void 0===e)&&!Array.isArray(e),throw:()=>{throw new Error("'metadata' property must be of type 'object' or 'undefined'.")},transform:e=>e}},_=e=>{const t={...e};for(const n in t){if(!Object.keys(I).includes(n))throw new Error(`Property '${n}' is not a valid assemblage definition property.`);const e=I[n].test,s=I[n].throw,i=I[n].transform;e(t[n])||s(),t[n]=i(t[n])}return t},P=e=>O(b,e),E=(e,t)=>P(t)[e];const S=e=>{const t=e?_(e):{};return e=>(j(g,!0,e),j(b,t,e),e)};class ${}$=function(e,t,n,s){var i,r=arguments.length,o=r<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,n):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,n,s);else for(var c=e.length-1;c>=0;c--)(i=e[c])&&(o=(r<3?i(o):r>3?i(t,n,o):i(t,n))||o);return r>3&&o&&Object.defineProperty(t,n,o),o}([S()],$);const R=(e,t,n)=>new Promise((s=>{const r=e[t];if(r){if(i(r))return void r.bind(e)(n).then((()=>{s()}));s(r.bind(e)(n))}})),M=e=>{const t=(e=>O(y,e)||[])(e),n=(e=>O(m,e)||[])(e),s=(e=>O(v,e)||[])(e),i=(e=>O(w,e)||[])(e),r=(e=>O(x,e)||[])(e);return{context:t,definition:n,configuration:s,dispose:i,use:r}};function L(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class q{static of(e,t,n){return new q(e,t,n)}dispose(){this.singletonInstance&&(((e,t)=>{if(e.concrete.prototype instanceof p){const n=t;for(const t of e.events)n.off(t);n.removeChannels(...e.events),e.privateContext.removeChannels(...e.events)}})(this,this.singletonInstance),R(this.singletonInstance,"onDispose",this.publicContext),l(this.singletonInstance,this.concrete)),l(this,q)}build(){if(this.singletonInstance)return this.singletonInstance;const e=(e=>{const t=[],n=A(e.concrete),s=M(e.concrete);let i=0;for(const r of n)if(s.context.includes(i))t.push(e.publicContext),i++;else if(s.configuration.includes(i))t.push(e.configuration),i++;else if(s.definition.includes(i))t.push(e.definition),i++;else if(s.dispose.includes(i))t.push(e.privateContext.dispose),i++;else if(s.use.includes(i)){const n=O(C,e.concrete)[i];t.push(e.privateContext.require(n)),i++}else t.push(e.privateContext.require(r)),i++;return t})(this),t=new this.concrete(...e);return((e,t)=>{if(e.concrete.prototype instanceof p){const n=t,s=n.channels;for(const t of e.events)s.has(t)||n.addChannels(t),e.privateContext.events.has(t)||e.privateContext.addChannels(t);for(const i of e.events)t.on(i,((...t)=>{e.privateContext.emit(i,...t)}))}})(this,t),this.isSingleton?(this.singletonInstance=t,this.privateContext.prepareInit(t),this.singletonInstance):(R(t,"onInit",this.publicContext),t)}get dependencies(){return this.dependenciesIds}get definition(){return P(this.concrete)||{}}get isSingleton(){return E("singleton",this.concrete)||!0}get singleton(){return this.singletonInstance}get injections(){return E("inject",this.concrete)||[]}get objects(){return E("use",this.concrete)||[]}get tags(){return E("tags",this.concrete)||[]}get events(){return E("events",this.concrete)||[]}constructor(e,t,n){if(L(this,"privateContext",void 0),L(this,"publicContext",void 0),L(this,"identifier",void 0),L(this,"concrete",void 0),L(this,"configuration",void 0),L(this,"dependenciesIds",void 0),L(this,"singletonInstance",void 0),this.privateContext=t,this.publicContext=n,this.dependenciesIds=[],this.identifier=e.identifier,this.concrete=e.concrete,this.configuration=e.configuration,!(e=>O(g,e)||!1)(this.concrete))throw new Error(`Class '${this.concrete.name}' is not an Assemblage.`);a(this.injections)((e=>this.privateContext.register(e)));a(this.objects)((e=>{"string"==typeof e[0]||"symbol"==typeof e[0]?this.privateContext.use(e[0],e[1]):this.privateContext.register(e,!0)})),this.dependenciesIds=(e=>{const t=[],n=A(e),s=M(e);let i=0;for(const r of n)s.context.includes(i)||s.configuration.includes(i)||s.definition.includes(i)||s.dispose.includes(i)||s.use.includes(i)||t.push(r),i++;return t})(this.concrete),e.instance&&(this.singletonInstance=e.instance)}}const N=e=>{const t=()=>s(e[0])&&(e=>"object"==typeof e&&!Array.isArray(e)&&!s(e))(e[1]);return o(c({if:()=>s(e[0])&&s(e[1]),then:()=>({identifier:e[0],concrete:e[1],configuration:{}})}),c({if:()=>t(),then:()=>({identifier:e[0],concrete:e[0],configuration:e[1]}),else:e=>e}))()},k=e=>((e,t)=>(n,...s)=>e[n]?e[n](...s):t?t(n,...s):void 0)({1:()=>(e=>({identifier:e[0],concrete:e[0],configuration:{}}))(e),2:()=>N(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 D(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class z extends p{static build(e){const t=new z;((e,t,n)=>{const s=P(n);s[e]=t,_(s)})("singleton",!0,e);const n=t.register([e]),s=t.require(n.identifier),i=t.initCache.indexOf(s);t.initCache.splice(i,1);for(const r of t.initCache)R(r,"onInit",t.publicContext);return R(s,"onInit",t.publicContext),t.initCache.length=0,s}dispose(){for(const[e,t]of this.injectables)t.dispose();l(this,z)}register(e,t=!1){const n=!0===t?{identifier:(s=e)[0],concrete:s[0],instance:s[1],configuration:{}}:k(e);var s;if(this.has(n.identifier))throw new Error(`An assemblage is already registered with identifier '${n.identifier.name}'.`);const i=q.of(n,this.privateContext,this.publicContext);return this.injectables.set(i.identifier,i),R(i.concrete,"onRegister",this.publicContext),i}use(e,t){if(this.has(e))throw new Error(`A value is already registered with identifier '${String(e)}'.`);return this.objects.set(e,t),t}prepareInit(e){return this.initCache.push(e),this.initCache}has(e){return"string"==typeof e||"symbol"==typeof e?this.objects.has(e):this.injectables.has(e)}require(e){switch(typeof e){case"string":case"symbol":if(!this.objects.has(e))throw new Error(`Injected object with identifier '${String(e)}' has not been registered.`);return this.objects.get(e);default:if(!this.injectables.has(e))throw new Error(`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,s]of this.injectables)s.tags.includes(n)&&t.push(s.build());return t}get size(){return this.injectables.size}constructor(){super(),D(this,"injectables",new Map),D(this,"objects",new Map),D(this,"initCache",[]),D(this,"privateContext",void 0),D(this,"publicContext",void 0),this.publicContext={has:this.has.bind(this),require:this.require.bind(this),tagged:this.tagged.bind(this),on:this.on.bind(this),once:this.once.bind(this),off:this.off.bind(this),events:this.channels},this.privateContext={...this.publicContext,register:this.register.bind(this),use:this.use.bind(this),prepareInit:this.prepareInit.bind(this),emit:this.emit.bind(this),addChannels:this.addChannels.bind(this),removeChannels:this.removeChannels.bind(this),dispose:this.dispose.bind(this)}}}const F=e=>()=>(t,n,s)=>{const i=O(e,t)||[];i.push(s),j(e,i,t)},T=F(y),U=F(v),Z=F(m),B=F(w);class G{}exports.AbstractAssemblage=class{static onRegister(e){}},exports.AbstractAssembler=class extends G{},exports.AbstractEventManager=G,exports.Assemblage=S,exports.Assembler=z,exports.Await=(e,t=25)=>(n,s,i)=>{const r=i.value;i.value=async function(){return new Promise((n=>{if(this[e])r.apply(this),n();else{const s=setInterval((()=>{this[e]&&(clearInterval(s),r.apply(this),n())}),t)}}))}},exports.Configuration=U,exports.Context=T,exports.Definition=Z,exports.Dispose=B,exports.EventManager=p,exports.Use=e=>(t,n,s)=>{const i=O(x,t)||[];i.push(s),j(x,i,t);const r=O(C,t)||{};r[s]=e,j(C,r,t)};
package/dist/index.mjs CHANGED
@@ -48,7 +48,7 @@ const forIn = (e)=>(t)=>{
48
48
  t(r(o));
49
49
  }
50
50
  };
51
- const e$5 = (e, t)=>{
51
+ const e$6 = (e, t)=>{
52
52
  return [
53
53
  ...Object.getOwnPropertyNames(t.prototype),
54
54
  ...Object.getOwnPropertyNames(Object.getPrototypeOf(e)),
@@ -60,7 +60,7 @@ const proxifyIterable = (t, r)=>{
60
60
  get: function(o, n) {
61
61
  if (n === Symbol.iterator) {
62
62
  return o[Symbol.iterator].bind(o);
63
- } else if (!e$5(t, r).includes(n)) {
63
+ } else if (!e$6(t, r).includes(n)) {
64
64
  return o.collection[n];
65
65
  }
66
66
  return o[n];
@@ -85,7 +85,7 @@ const clearInstance = (e, t)=>{
85
85
  }
86
86
  };
87
87
 
88
- function e$4(e, t, n) {
88
+ function e$5(e, t, n) {
89
89
  if (t in e) {
90
90
  Object.defineProperty(e, t, {
91
91
  value: n,
@@ -194,13 +194,13 @@ class ListenerCollection {
194
194
  };
195
195
  }
196
196
  constructor(){
197
- e$4(this, "collection", {});
197
+ e$5(this, "collection", {});
198
198
  const t = proxifyIterable(this, ListenerCollection);
199
199
  return t;
200
200
  }
201
201
  }
202
202
 
203
- function e$3(e, n, s) {
203
+ function e$4(e, n, s) {
204
204
  if (n in e) {
205
205
  Object.defineProperty(e, n, {
206
206
  value: s,
@@ -302,9 +302,9 @@ class EventManager {
302
302
  return onlyAlphanumeric(e, '*');
303
303
  }
304
304
  constructor(...n){
305
- e$3(this, "listeners", new ListenerCollection());
306
- e$3(this, "onceListeners", new ListenerCollection());
307
- e$3(this, "channels", new Set([
305
+ e$4(this, "listeners", new ListenerCollection());
306
+ e$4(this, "onceListeners", new ListenerCollection());
307
+ e$4(this, "channels", new Set([
308
308
  '*'
309
309
  ]));
310
310
  this.addChannels(...n);
@@ -333,113 +333,80 @@ const getParamTypes = (e)=>{
333
333
  return Reflect.getMetadata(ReflectParamTypes, e) || [];
334
334
  };
335
335
 
336
- const t = {
336
+ const e$3 = {
337
337
  singleton: {
338
- test: (e)=>typeof e === 'boolean' || typeof e === 'undefined',
338
+ test: (r)=>typeof r === 'boolean' || typeof r === 'undefined',
339
339
  throw: ()=>{
340
340
  throw new Error(`'singleton' property must be of type 'boolean' or 'undefined'.`);
341
341
  },
342
- transform: (e)=>typeof e === 'undefined' ? true : false
342
+ transform: (r)=>typeof r === 'undefined' ? true : false
343
343
  },
344
344
  events: {
345
- test: (e)=>typeof e === 'undefined' || Array.isArray(e) && e.every((e)=>typeof e === 'string'),
345
+ test: (r)=>typeof r === 'undefined' || Array.isArray(r) && r.every((r)=>typeof r === 'string'),
346
346
  throw: ()=>{
347
347
  throw new Error(`'events' property must be an array of strings or 'undefined'.`);
348
348
  },
349
- transform: (e)=>e
349
+ transform: (r)=>r
350
350
  },
351
351
  inject: {
352
- test: (e)=>typeof e === 'undefined' || Array.isArray(e) && e.every((e)=>Array.isArray(e) && e.length >= 1 && e.length <= 3),
352
+ test: (r)=>typeof r === 'undefined' || Array.isArray(r) && r.every((r)=>Array.isArray(r) && r.length >= 1 && r.length <= 3),
353
353
  throw: ()=>{
354
354
  throw new Error(`'inject' property must be an array of tuples of length 1, 2 or 3.`);
355
355
  },
356
- transform: (e)=>e
356
+ transform: (r)=>r
357
357
  },
358
358
  use: {
359
- test: (e)=>typeof e === 'undefined' || Array.isArray(e) && e.every((e)=>Array.isArray(e) && e.length == 2),
359
+ test: (r)=>typeof r === 'undefined' || Array.isArray(r) && r.every((r)=>Array.isArray(r) && r.length == 2),
360
360
  throw: ()=>{
361
361
  throw new Error(`'use' property must be an array of tuples of length 2.`);
362
362
  },
363
- transform: (e)=>e
363
+ transform: (r)=>r
364
364
  },
365
365
  tags: {
366
- test: (e)=>typeof e === 'undefined' || typeof e === 'string' || Array.isArray(e) && e.every((e)=>typeof e === 'string'),
366
+ test: (r)=>typeof r === 'undefined' || typeof r === 'string' || Array.isArray(r) && r.every((r)=>typeof r === 'string'),
367
367
  throw: ()=>{
368
368
  throw new Error(`'tags' property must be a string or an array of strings.`);
369
369
  },
370
- transform: (e)=>typeof e === 'string' ? [
371
- e
372
- ] : e
373
- },
374
- controller: {
375
- test: (e)=>typeof e === 'boolean' || typeof e === 'undefined',
376
- throw: ()=>{
377
- throw new Error(`'controller' property must be of type 'boolean' or 'undefined'.`);
378
- },
379
- transform: (e)=>e
380
- },
381
- path: {
382
- test: (e)=>typeof e === 'string' || typeof e === 'undefined',
383
- throw: ()=>{
384
- throw new Error(`'path' property must be of type 'string' or 'undefined'.`);
385
- },
386
- transform: (e)=>{
387
- if (e) {
388
- let r = e.replace(/\/+/g, '/').replace(/\s/g, '');
389
- if (!r.startsWith('/')) {
390
- r = `/${r}`;
391
- }
392
- if (r.endsWith('/')) {
393
- const e = r.length - 1;
394
- r = r.split('').splice(0, e).join('');
395
- }
396
- return r;
397
- }
398
- return e;
399
- }
370
+ transform: (r)=>typeof r === 'string' ? [
371
+ r
372
+ ] : r
400
373
  },
401
374
  metadata: {
402
- test: (e)=>(typeof e === 'object' || typeof e === 'undefined') && !Array.isArray(e),
375
+ test: (r)=>(typeof r === 'object' || typeof r === 'undefined') && !Array.isArray(r),
403
376
  throw: ()=>{
404
377
  throw new Error(`'metadata' property must be of type 'object' or 'undefined'.`);
405
378
  },
406
- transform: (e)=>e
379
+ transform: (r)=>r
407
380
  }
408
381
  };
409
- const validateDefinition = (e)=>{
410
- const r = {
411
- ...e
382
+ const validateDefinition = (r)=>{
383
+ const t = {
384
+ ...r
412
385
  };
413
- for(const e in r){
414
- if (!Object.keys(t).includes(e)) {
415
- throw new Error(`Property '${e}' is not a valid assemblage definition property.`);
416
- }
417
- const o = t[e].test;
418
- const n = t[e].throw;
419
- const s = t[e].transform;
420
- if (!o(r[e])) {
386
+ for(const r in t){
387
+ if (!Object.keys(e$3).includes(r)) {
388
+ throw new Error(`Property '${r}' is not a valid assemblage definition property.`);
389
+ }
390
+ const o = e$3[r].test;
391
+ const n = e$3[r].throw;
392
+ const s = e$3[r].transform;
393
+ if (!o(t[r])) {
421
394
  n();
422
395
  }
423
- if (e === 'controller' && !Object.keys(r).includes('path')) {
424
- throw new Error(`Assemblage marked as 'controller' must define a 'path'.`);
425
- }
426
- if (e === 'path' && !Object.keys(r).includes('controller')) {
427
- throw new Error(`Assemblage that defines a 'path' must be marked as 'controller'.`);
428
- }
429
- r[e] = s(r[e]);
396
+ t[r] = s(t[r]);
430
397
  }
431
- return r;
398
+ return t;
432
399
  };
433
- const getDefinition = (t)=>{
434
- return getOwnCustomMetadata(ReflectDefinition, t);
400
+ const getDefinition = (e)=>{
401
+ return getOwnCustomMetadata(ReflectDefinition, e);
435
402
  };
436
- const getDefinitionValue = (e, r)=>{
437
- const t = getDefinition(r);
438
- return t[e];
403
+ const getDefinitionValue = (r, t)=>{
404
+ const e = getDefinition(t);
405
+ return e[r];
439
406
  };
440
- const setDefinitionValue = (e, r, t)=>{
441
- const o = getDefinition(t);
442
- o[e] = r;
407
+ const setDefinitionValue = (r, t, e)=>{
408
+ const o = getDefinition(e);
409
+ o[r] = t;
443
410
  const n = validateDefinition(o);
444
411
  return n;
445
412
  };
@@ -793,7 +760,7 @@ class Assembler extends EventManager {
793
760
  }
794
761
  use(e, t) {
795
762
  if (this.has(e)) {
796
- throw new Error(`A valu is already registered for identifier '${String(e)}'.`);
763
+ throw new Error(`A value is already registered with identifier '${String(e)}'.`);
797
764
  }
798
765
  this.objects.set(e, t);
799
766
  return t;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "assemblerjs",
3
3
  "description": "A general purpose and zero-dependency Dependency Injection framework for node and browser.",
4
- "version": "0.3.21",
4
+ "version": "0.3.22",
5
5
  "author": "Benoît LAHOZ <info@benoitlahoz.io>",
6
6
  "bugs": "https://github.com/benoitlahoz/assemblerjs/issues",
7
7
  "devDependencies": {
@@ -45,7 +45,8 @@
45
45
  "reflection",
46
46
  "swc",
47
47
  "typescript",
48
- "metadata"
48
+ "metadata",
49
+ "ioc"
49
50
  ],
50
51
  "license": "MIT",
51
52
  "main": "dist/index.js",