assemblerjs 0.8.6 → 0.8.8
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 +23 -7
- package/dist/index.js +1 -1
- package/dist/index.mjs +36 -22
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -16,12 +16,20 @@ export declare abstract class AbstractAssemblage {
|
|
|
16
16
|
*/
|
|
17
17
|
static onRegister(context: AssemblerContext, configuration?: Record<string, any>): void;
|
|
18
18
|
/**
|
|
19
|
-
* Called on instantiated class after the dependency tree is fully resolved.
|
|
19
|
+
* Called on instantiated class in less dependent to more dependent order after the dependency tree is fully resolved.
|
|
20
20
|
*
|
|
21
21
|
* @param { AssemblerContext } context The assembler's context.
|
|
22
22
|
* @param { Reord<string, any> } configuration The configuration object.
|
|
23
23
|
*/
|
|
24
24
|
abstract onInit?(context: AssemblerContext, configuration?: Record<string, any>): void | Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Called by the `Assembler` when all classes have been inited with `onInit`, including the entry point,
|
|
27
|
+
* in more dependent to less dependent order.
|
|
28
|
+
*
|
|
29
|
+
* @param { AssemblerContext } context The assembler's context.
|
|
30
|
+
* @param { Reord<string, any> } configuration The configuration object.
|
|
31
|
+
*/
|
|
32
|
+
abstract onInited?(context: AssemblerContext, configuration?: Record<string, any>): void | Promise<void>;
|
|
25
33
|
/**
|
|
26
34
|
* Called when instance of class is disposed.
|
|
27
35
|
*
|
|
@@ -182,7 +190,7 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
182
190
|
*/
|
|
183
191
|
use<T>(identifier: string | symbol, object: T): T;
|
|
184
192
|
/**
|
|
185
|
-
* Cache an
|
|
193
|
+
* Cache an instance to be inited with `onInit` hook
|
|
186
194
|
* when the dependency tree will be fully resolved.
|
|
187
195
|
*
|
|
188
196
|
* @param { T = AbstractAssemblage } instance The built instance.
|
|
@@ -320,13 +328,14 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
320
328
|
* A custom decorator that adds a function called after the original constructor
|
|
321
329
|
* and that can wrap an `Assemblage` with its own parameters decorator (e.g. @Use, @Context, ...).
|
|
322
330
|
* Note that it must be placed before the `Assemnblage` decorator.
|
|
331
|
+
* The `definition` optional parameter allows passing a configuration object to the decorator.
|
|
323
332
|
*
|
|
324
|
-
* @param { function(): void | undefined } fn A function to execute after `super`.
|
|
333
|
+
* @param { function(definition?: ObjectLiteral): void | undefined } fn A function to execute after `super`.
|
|
325
334
|
* Do not use arrow function here if access to `this` is required.
|
|
326
335
|
* @param { boolean | undefined } asAssemblage If `true` decorate the class as an assemblage (defaults to `true`).
|
|
327
336
|
* @returns A new decorator.
|
|
328
337
|
*/
|
|
329
|
-
export declare const ConstructorDecorator: (fn?: () => void,
|
|
338
|
+
export declare const ConstructorDecorator: <T extends ObjectLiteral>(fn?: (definition?: T) => void, definition?: T) => any;
|
|
330
339
|
|
|
331
340
|
/**
|
|
332
341
|
* Injects the Assembler's context.
|
|
@@ -337,12 +346,13 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
337
346
|
* Create a custom decorator that adds a function called after the original constructor
|
|
338
347
|
* and that can wrap an `Assemblage` with its own parameters decorator (e.g. @Use, @Context, ...).
|
|
339
348
|
* Note that it must be placed before the `Assemblage` decorator.
|
|
349
|
+
* The `definition` optional parameter allows passing a configuration object to the decorator.
|
|
340
350
|
*
|
|
341
|
-
* @param { function(): void | undefined } fn A function to execute after `super`.
|
|
351
|
+
* @param { function(definition?: ObjectLiteral): void | undefined } fn A function to execute after `super`.
|
|
342
352
|
* Do not use arrow function here if access to `this` is required.
|
|
343
353
|
* @returns A new decorator.
|
|
344
354
|
*/
|
|
345
|
-
export declare const createConstructorDecorator: (fn?: () => void) => any;
|
|
355
|
+
export declare const createConstructorDecorator: <T extends ObjectLiteral>(fn?: (definition?: T) => void) => any;
|
|
346
356
|
|
|
347
357
|
/**
|
|
348
358
|
* Manually decorate a class to be an `Assemblage`.
|
|
@@ -394,12 +404,14 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
394
404
|
private cleanChannel;
|
|
395
405
|
}
|
|
396
406
|
|
|
407
|
+
export declare const getAssemblageDefinition: <T>(target: Concrete<T>) => AssemblageDefinition;
|
|
408
|
+
|
|
397
409
|
export declare const getDecoratedParametersIndexes: <T>(target: Concrete<T>) => ParametersDecoratorsIndexes;
|
|
398
410
|
|
|
399
411
|
/**
|
|
400
412
|
* An identifier can be an abstract or a concrete class.
|
|
401
413
|
*/
|
|
402
|
-
declare type Identifier<T> = Class<T>;
|
|
414
|
+
export declare type Identifier<T> = Class<T>;
|
|
403
415
|
|
|
404
416
|
declare class Injectable<T> implements AbstractInjectable<T> {
|
|
405
417
|
readonly privateContext: AssemblerPrivateContext;
|
|
@@ -568,6 +580,10 @@ export declare class Assembler extends EventManager implements AbstractAssembler
|
|
|
568
580
|
[Symbol.iterator](): Iterator<EventChannel>;
|
|
569
581
|
}
|
|
570
582
|
|
|
583
|
+
export declare interface ObjectLiteral {
|
|
584
|
+
[key: string]: any;
|
|
585
|
+
}
|
|
586
|
+
|
|
571
587
|
declare interface ParametersDecoratorsIndexes {
|
|
572
588
|
Context: number[];
|
|
573
589
|
Definition: number[];
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@assemblerjs/core");const t="design:paramtypes";var n,s;(n||(n={})).IsAssemblage="is_assemblage",(s||(s={})).AssemblageDefinition="assemblage:definition.value";const i=(e,t,n)=>{Reflect.defineMetadata(`__${e}__`,t,n)},r=(e,t)=>Reflect.getOwnMetadata(`__${e}__`,t),o=e=>Reflect.getMetadata(t,e)||[],a=e=>r(n.IsAssemblage,e)||!1,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||!!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}},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.`);for(const n in c){const e=c[n].test,s=c[n].throw,i=c[n].transform;e(t[n])||s(),t[n]=i(t[n])}return t},h=e=>{if(!a(e))throw new Error(`Class '${e.name}' is not an assemblage.`);return r(s.AssemblageDefinition,e)},f=(e,t)=>h(t)[e],d=t=>e.pipe(e.conditionally({if:()=>e.isClass(t[0])&&e.isClass(t[1]),then:()=>({identifier:t[0],concrete:t[1],configuration:{}})}),e.conditionally({if:()=>e.isClass(t[0])&&e.isObject(t[1]),then:()=>({identifier:t[0],concrete:t[0],configuration:t[1]}),else:e=>e}))(),u=(e,t)=>{const r=l(t||{});return i(n.IsAssemblage,!0,e),i(s.AssemblageDefinition,r,e),e};class p{dispose(){e.clearInstance(this,p)}add(...t){const n=e=>this.collection[e.channel].push(e.listener),s=e.conditionally({if:()=>2===t.length,then:()=>({channel:t[0],listener:t[1]}),else:()=>{const e=t[0];return{channel:e[0],listener:e[1]}}}),i=e.conditionally({if:t=>!e.isDefined(this.collection[t.channel]),then:e=>{this.collection[e.channel]=[],n(e)},else:e=>{n(e)}});return e.pipe(s,i)(),this}remove(t,n){const s=e=>this.collection[t].splice(e,1),i=e.conditionally({if:()=>this.collection[t]&&0===this.collection[t].length,then:()=>delete this.collection[t]}),r=e.conditionally({if:()=>e.isDefined(n),then:()=>s(this.collection[t].indexOf(n)),else:()=>delete this.collection[t]}),o=e.conditionally({if:e=>this.has(e),then:e=>this.collection[e]});return e.pipe(o,r,i)(),this}has(...t){return e.isOfType("string")(t[0])?Object.keys(this.collection).includes(t[0]):!!e.isOfType("function")(t[0])&&Object.values(this.collection).flat().includes(t[0])}get(...t){return e.isOfType("string")(t[0])?this.collection[t[0]]:e.isOfType("function")(t[0])?Object.values(this.collection).flat().filter((e=>e===t[0])):[]}clear(){const t=e.forIn(this.collection),n=t=>e.forOf(this.collection[t])((e=>this.remove(t,e)));return t((e=>n(e))),this}get listeners(){return Object.values(this.collection).flat()}get channels(){return Object.keys(this.collection)}get length(){return Object.values(this.collection).flat().length}[Symbol.iterator](){let e=-1;const t=this.collection?Object.keys(this.collection):[];return{next:()=>({value:t[++e],done:!(e in t)})}}constructor(){this.collection={};return e.proxifyIterable(this,p)}}class g{}class x{dispose(){this.listeners.dispose(),this.channels.clear(),e.clearInstance(this,x)}addChannels(...t){return e.forOf(t)((e=>{const t=this.cleanChannel(e);if(this.channels.has(t))throw new Error(`Channel '${t}' already exists.`);this.channels.add(t)})),this}removeChannels(...t){return e.forOf(t)((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(t,...n){const s=this.cleanChannel(t);if(this.channels.has(s)){const t=this.onceListeners.get("*")||[],i=this.listeners.get("*")||[],r=this.onceListeners.get(s)||[],o=this.listeners.get(s)||[],a=e.forOf(t),c=e.forOf(i),l=e.forOf(r),h=e.forOf(o);a((e=>{this.run(e,...n),this.onceListeners.remove("*",e)})),c((e=>{this.run(e,...n)})),l((e=>{this.run(e,...n),this.onceListeners.remove(s,e)})),h((e=>{this.run(e,...n)}))}return this}run(t,...n){if(e.isAsync(t)){return t(...n).then((()=>Promise.resolve()))}t(...n)}cleanChannel(t){return e.onlyAlphanumeric(t,"*")}constructor(...e){this.listeners=new p,this.onceListeners=new p,this.channels=new Set(["*"]),this.addChannels(...e)}}exports.ReflectParamValue=void 0,(exports.ReflectParamValue||(exports.ReflectParamValue={})).UseIdentifier="assemblage:use.param.value",exports.ReflectParamIndex=void 0,function(e){e.Context="assembler:context.param.index",e.Dispose="assembler:dispose.param.index",e.Definition="assemblage:definition.param.index",e.Configuration="assemblage:configuration.param.index",e.Use="assemblage:use.param.index"}(exports.ReflectParamIndex||(exports.ReflectParamIndex={}));const m=e=>()=>(t,n,s)=>{const o=r(e,t)||[];o.push(s),i(e,o,t)},b=m(exports.ReflectParamIndex.Context),C=m(exports.ReflectParamIndex.Configuration),y=m(exports.ReflectParamIndex.Definition),v=m(exports.ReflectParamIndex.Dispose),w=(e,t,n)=>{const s=r(exports.ReflectParamIndex.Use,t)||[];s.push(n),i(exports.ReflectParamIndex.Use,s,t);const o=r(exports.ReflectParamValue.UseIdentifier,t)||{};o[n]=e,i(exports.ReflectParamValue.UseIdentifier,o,t)},I=e=>{const t=(e=>r(exports.ReflectParamIndex.Context,e)||[])(e)||[],n=(e=>r(exports.ReflectParamIndex.Definition,e)||[])(e)||[],s=(e=>r(exports.ReflectParamIndex.Configuration,e)||[])(e)||[],i=(e=>r(exports.ReflectParamIndex.Dispose,e)||[])(e)||[],o=(e=>r(exports.ReflectParamIndex.Use,e)||[])(e)||[];return{Context:t,Definition:n,Configuration:s,Dispose:i,Use:o}},A=(e,n=!0)=>o=>{const a=class extends o{constructor(...t){super(...t),e&&e.call(this)}};if(Object.defineProperty(a,"name",{value:o.name}),!n)return a;const c=Reflect.getOwnMetadata(t,o)||[],l=I(o),h=[];for(let e=0;e<c.length;e++)if(l.Context.includes(e)){const t=r(exports.ReflectParamIndex.Context,o)||[];t.push(e),i(exports.ReflectParamIndex.Context,t,a)}else if(l.Definition.includes(e)){const t=r(exports.ReflectParamIndex.Definition,o)||[];t.push(e),i(exports.ReflectParamIndex.Definition,t,a)}else if(l.Configuration.includes(e)){const t=r(exports.ReflectParamIndex.Configuration,o)||[];t.push(e),i(exports.ReflectParamIndex.Configuration,t,a)}else if(l.Dispose.includes(e)){const t=r(exports.ReflectParamIndex.Dispose,o)||[];t.push(e),i(exports.ReflectParamIndex.Dispose,t,a),h.push(c[e])}else if(l.Use.includes(e)){const t=r(exports.ReflectParamValue.UseIdentifier,o);w(t[e],a,e)}else;return u(a,r(s.AssemblageDefinition,o))};class j{static of(e,t,n){return new j(e,t,n)}dispose(){this.singletonInstance&&(((e,t)=>{if(e.concrete.prototype instanceof x){const n=t;for(const t of e.events)n.off(t);n.removeChannels(...e.events),e.privateContext.removeChannels(...e.events)}})(this,this.singletonInstance),P(this.singletonInstance,"onDispose",this.publicContext,this.configuration),e.clearInstance(this.singletonInstance,this.concrete)),e.clearInstance(this,j)}build(){if(this.singletonInstance)return this.singletonInstance;const e=(e=>{const t=[],n=o(e.concrete),s=I(e.concrete);let i=0;for(const o 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=r(exports.ReflectParamValue.UseIdentifier,e.concrete)[i];t.push(e.privateContext.require(n)),i++}else t.push(e.privateContext.require(o)),i++;return t})(this),t=new this.concrete(...e);return((e,t)=>{if(e.concrete.prototype instanceof x){const n=t,s=n.channels;for(const t of e.events)s.has(t)||n.addChannels(t),e.privateContext.events.has(t)||e.privateContext.addChannels(t);for(const i of e.events)t.on(i,((...t)=>{e.privateContext.emit(i,...t)}))}})(this,t),this.isSingleton?(this.singletonInstance=t,this.privateContext.prepareInitHook(t,this.configuration),this.singletonInstance):(P(t,"onInit",this.publicContext),t)}get dependencies(){return this.dependenciesIds}get definition(){return h(this.concrete)||{}}get isSingleton(){return f("singleton",this.concrete)}get singleton(){return this.singletonInstance}get injections(){return f("inject",this.concrete)||[]}get objects(){return f("use",this.concrete)||[]}get tags(){return f("tags",this.concrete)||[]}get events(){return f("events",this.concrete)||[]}constructor(t,n,s){if(this.privateContext=n,this.publicContext=s,this.dependenciesIds=[],this.identifier=t.identifier,this.concrete=t.concrete,this.configuration=t.configuration,!a(this.concrete))throw new Error(`Class '${this.concrete.name}' is not an Assemblage.`);const i=e.forOf(this.injections),r=e.forOf(this.objects);i((e=>this.privateContext.register(e))),r((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=o(e),s=I(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),t.instance?this.singletonInstance=t.instance:this.isSingleton}}const P=(t,n,s,i)=>new Promise((r=>{const o=t[n];if(o){if(e.isAsync(o))return void o.bind(t)(s,i).then((()=>{r()}));r(o.bind(t)(s,i))}}));class R extends x{static build(e){const t=new R;((e,t,n)=>{const r=h(n);r[e]=t;const o=l(r);i(s.AssemblageDefinition,o,n)})("singleton",!0,e);const n=t.register([e]),r=t.require(n.identifier),o=t.initCache.find((e=>e.instance===r));if(!o)throw new Error("Root instance not found in assemblages cache.");const a=t.initCache.indexOf(o);t.initCache.splice(a,1);for(const s of t.initCache)P(s.instance,"onInit",t.publicContext,s.configuration);return P(r,"onInit",t.publicContext,n.configuration),t.initCache.length=0,r}dispose(){for(const[e,t]of this.injectables)t.dispose();e.clearInstance(this,R)}register(t,n=!1){const s=!0===n?(e=>({identifier:e[0],concrete:e[0],instance:e[1],configuration:{}}))(t):(t=>e.switchCase({1:()=>(e=>({identifier:e[0],concrete:e[0],configuration:{}}))(t),2:()=>d(t),3:()=>(e=>({identifier:e[0],concrete:e[1],configuration:e[2]}))(t)},(()=>{throw new Error("Injection tuple must be of length 1, 2 or 3.")}))(t.length))(t);if(this.has(s.identifier))throw new Error(`An assemblage is already registered with identifier '${s.identifier.name}'.`);const i=j.of(s,this.privateContext,this.publicContext);return this.injectables.set(i.identifier,i),P(i.concrete,"onRegister",this.publicContext,i.configuration),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}prepareInitHook(e,t){return this.initCache.push({instance:e,configuration:t}),this.initCache}has(e){return"string"==typeof e||"symbol"==typeof e?this.objects.has(e):this.injectables.has(e)}require(e){switch(typeof e){case"string":case"symbol":if(!this.objects.has(e))throw new Error(`Injected object with identifier '${String(e)}' has not been registered.`);return this.objects.get(e);default:if(!this.injectables.has(e))throw new Error(`Class with identifier '${e.name}' has not been registered or is a circular dependency.`);return this.injectables.get(e).build()}}concrete(e){const t=this.injectables.get(e);if(t)return t.concrete}tagged(...e){const t=[];for(const n of e)for(const[e,s]of this.injectables)s.tags.includes(n)&&t.push(s.build());return t}get size(){return this.injectables.size}constructor(){super(),this.injectables=new Map,this.objects=new Map,this.initCache=[],this.publicContext={has:this.has.bind(this),require:this.require.bind(this),concrete:this.concrete.bind(this),tagged:this.tagged.bind(this),dispose:this.dispose.bind(this),on:this.on.bind(this),once:this.once.bind(this),off:this.off.bind(this),events:this.channels},this.privateContext={...this.publicContext,register:this.register.bind(this),use:this.use.bind(this),prepareInitHook:this.prepareInitHook.bind(this),emit:this.emit.bind(this),addChannels:this.addChannels.bind(this),removeChannels:this.removeChannels.bind(this)}}}exports.AbstractAssemblage=class{static onRegister(e,t){}},exports.AbstractAssembler=class extends g{},exports.AbstractEventManager=g,exports.AbstractListenerCollection=class{},exports.Assemblage=e=>t=>u(t,e),exports.Assembler=R,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=C,exports.ConstructorDecorator=A,exports.Context=b,exports.Definition=y,exports.Dispose=v,exports.EventManager=x,exports.ListenerCollection=p,exports.Use=e=>(t,n,s)=>{w(e,t,s)},exports.createConstructorDecorator=e=>(t=!0)=>A(e,t),exports.decorateAssemblage=u,exports.decorateUse=w,exports.getDecoratedParametersIndexes=I,exports.isAssemblage=a;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@assemblerjs/core");const t="design:paramtypes";var n,s;(n||(n={})).IsAssemblage="is_assemblage",(s||(s={})).AssemblageDefinition="assemblage:definition.value";const i=(e,t,n)=>{Reflect.defineMetadata(`__${e}__`,t,n)},r=(e,t)=>Reflect.getOwnMetadata(`__${e}__`,t),o=e=>Reflect.getMetadata(t,e)||[],a=e=>r(n.IsAssemblage,e)||!1,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||!!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}},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.`);for(const n in c){const e=c[n].test,s=c[n].throw,i=c[n].transform;e(t[n])||s(),t[n]=i(t[n])}return t},h=e=>{if(!a(e))throw new Error(`Class '${e.name}' is not an assemblage.`);return r(s.AssemblageDefinition,e)},f=(e,t)=>h(t)[e],d=t=>e.pipe(e.conditionally({if:()=>e.isClass(t[0])&&e.isClass(t[1]),then:()=>({identifier:t[0],concrete:t[1],configuration:{}})}),e.conditionally({if:()=>e.isClass(t[0])&&e.isObject(t[1]),then:()=>({identifier:t[0],concrete:t[0],configuration:t[1]}),else:e=>e}))(),u=(e,t)=>{const r=l(t||{});return i(n.IsAssemblage,!0,e),i(s.AssemblageDefinition,r,e),e};class p{dispose(){e.clearInstance(this,p)}add(...t){const n=e=>this.collection[e.channel].push(e.listener),s=e.conditionally({if:()=>2===t.length,then:()=>({channel:t[0],listener:t[1]}),else:()=>{const e=t[0];return{channel:e[0],listener:e[1]}}}),i=e.conditionally({if:t=>!e.isDefined(this.collection[t.channel]),then:e=>{this.collection[e.channel]=[],n(e)},else:e=>{n(e)}});return e.pipe(s,i)(),this}remove(t,n){const s=e=>this.collection[t].splice(e,1),i=e.conditionally({if:()=>this.collection[t]&&0===this.collection[t].length,then:()=>delete this.collection[t]}),r=e.conditionally({if:()=>e.isDefined(n),then:()=>s(this.collection[t].indexOf(n)),else:()=>delete this.collection[t]}),o=e.conditionally({if:e=>this.has(e),then:e=>this.collection[e]});return e.pipe(o,r,i)(),this}has(...t){return e.isOfType("string")(t[0])?Object.keys(this.collection).includes(t[0]):!!e.isOfType("function")(t[0])&&Object.values(this.collection).flat().includes(t[0])}get(...t){return e.isOfType("string")(t[0])?this.collection[t[0]]:e.isOfType("function")(t[0])?Object.values(this.collection).flat().filter((e=>e===t[0])):[]}clear(){const t=e.forIn(this.collection),n=t=>e.forOf(this.collection[t])((e=>this.remove(t,e)));return t((e=>n(e))),this}get listeners(){return Object.values(this.collection).flat()}get channels(){return Object.keys(this.collection)}get length(){return Object.values(this.collection).flat().length}[Symbol.iterator](){let e=-1;const t=this.collection?Object.keys(this.collection):[];return{next:()=>({value:t[++e],done:!(e in t)})}}constructor(){this.collection={};return e.proxifyIterable(this,p)}}class g{}class x{dispose(){this.listeners.dispose(),this.channels.clear(),e.clearInstance(this,x)}addChannels(...t){return e.forOf(t)((e=>{const t=this.cleanChannel(e);if(this.channels.has(t))throw new Error(`Channel '${t}' already exists.`);this.channels.add(t)})),this}removeChannels(...t){return e.forOf(t)((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(t,...n){const s=this.cleanChannel(t);if(this.channels.has(s)){const t=this.onceListeners.get("*")||[],i=this.listeners.get("*")||[],r=this.onceListeners.get(s)||[],o=this.listeners.get(s)||[],a=e.forOf(t),c=e.forOf(i),l=e.forOf(r),h=e.forOf(o);a((e=>{this.run(e,...n),this.onceListeners.remove("*",e)})),c((e=>{this.run(e,...n)})),l((e=>{this.run(e,...n),this.onceListeners.remove(s,e)})),h((e=>{this.run(e,...n)}))}return this}run(t,...n){if(e.isAsync(t)){return t(...n).then((()=>Promise.resolve()))}t(...n)}cleanChannel(t){return e.onlyAlphanumeric(t,"*",":",".","-","_")}constructor(...e){this.listeners=new p,this.onceListeners=new p,this.channels=new Set(["*"]),this.addChannels(...e)}}exports.ReflectParamValue=void 0,(exports.ReflectParamValue||(exports.ReflectParamValue={})).UseIdentifier="assemblage:use.param.value",exports.ReflectParamIndex=void 0,function(e){e.Context="assembler:context.param.index",e.Dispose="assembler:dispose.param.index",e.Definition="assemblage:definition.param.index",e.Configuration="assemblage:configuration.param.index",e.Use="assemblage:use.param.index"}(exports.ReflectParamIndex||(exports.ReflectParamIndex={}));const m=e=>()=>(t,n,s)=>{const o=r(e,t)||[];o.push(s),i(e,o,t)},b=m(exports.ReflectParamIndex.Context),C=m(exports.ReflectParamIndex.Configuration),v=m(exports.ReflectParamIndex.Definition),y=m(exports.ReflectParamIndex.Dispose),w=(e,t,n)=>{const s=r(exports.ReflectParamIndex.Use,t)||[];s.push(n),i(exports.ReflectParamIndex.Use,s,t);const o=r(exports.ReflectParamValue.UseIdentifier,t)||{};o[n]=e,i(exports.ReflectParamValue.UseIdentifier,o,t)},I=e=>{const t=(e=>r(exports.ReflectParamIndex.Context,e)||[])(e)||[],n=(e=>r(exports.ReflectParamIndex.Definition,e)||[])(e)||[],s=(e=>r(exports.ReflectParamIndex.Configuration,e)||[])(e)||[],i=(e=>r(exports.ReflectParamIndex.Dispose,e)||[])(e)||[],o=(e=>r(exports.ReflectParamIndex.Use,e)||[])(e)||[];return{Context:t,Definition:n,Configuration:s,Dispose:i,Use:o}},A=(e,n)=>o=>{const a=class extends o{constructor(...t){super(...t),e&&e.call(this,n)}};Object.defineProperty(a,"name",{value:o.name});const c=Reflect.getOwnMetadata(t,o)||[],l=I(o),h=[];for(let e=0;e<c.length;e++)if(l.Context.includes(e)){const t=r(exports.ReflectParamIndex.Context,o)||[];t.push(e),i(exports.ReflectParamIndex.Context,t,a)}else if(l.Definition.includes(e)){const t=r(exports.ReflectParamIndex.Definition,o)||[];t.push(e),i(exports.ReflectParamIndex.Definition,t,a)}else if(l.Configuration.includes(e)){const t=r(exports.ReflectParamIndex.Configuration,o)||[];t.push(e),i(exports.ReflectParamIndex.Configuration,t,a)}else if(l.Dispose.includes(e)){const t=r(exports.ReflectParamIndex.Dispose,o)||[];t.push(e),i(exports.ReflectParamIndex.Dispose,t,a),h.push(c[e])}else if(l.Use.includes(e)){const t=r(exports.ReflectParamValue.UseIdentifier,o);w(t[e],a,e)}else;return u(a,r(s.AssemblageDefinition,o))};class j{static of(e,t,n){return new j(e,t,n)}dispose(){this.singletonInstance&&(((e,t)=>{if(e.concrete.prototype instanceof x){const n=t;for(const t of e.events)n.off(t);n.removeChannels(...e.events),e.privateContext.removeChannels(...e.events)}else for(const n of e.events)e.privateContext.events.has(n)&&e.privateContext.removeChannels(n)})(this,this.singletonInstance),P(this.singletonInstance,"onDispose",this.publicContext,this.configuration),e.clearInstance(this.singletonInstance,this.concrete)),e.clearInstance(this,j)}build(){if(this.singletonInstance)return this.singletonInstance;const e=(e=>{const t=[],n=o(e.concrete),s=I(e.concrete);let i=0;for(const o 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=r(exports.ReflectParamValue.UseIdentifier,e.concrete)[i];t.push(e.privateContext.require(n)),i++}else t.push(e.privateContext.require(o)),i++;return t})(this),t=new this.concrete(...e);return((e,t)=>{if(e.concrete.prototype instanceof x){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)}))}else for(const n of e.events)e.privateContext.events.has(n)||e.privateContext.addChannels(n)})(this,t),this.isSingleton?(this.singletonInstance=t,this.privateContext.prepareInitHook(t,this.configuration),this.singletonInstance):(P(t,"onInit",this.publicContext),t)}get dependencies(){return this.dependenciesIds}get definition(){return h(this.concrete)||{}}get isSingleton(){return f("singleton",this.concrete)}get singleton(){return this.singletonInstance}get injections(){return f("inject",this.concrete)||[]}get objects(){return f("use",this.concrete)||[]}get tags(){return f("tags",this.concrete)||[]}get events(){return f("events",this.concrete)||[]}constructor(t,n,s){if(this.privateContext=n,this.publicContext=s,this.dependenciesIds=[],this.identifier=t.identifier,this.concrete=t.concrete,this.configuration=t.configuration,!a(this.concrete))throw new Error(`Class '${this.concrete.name}' is not an Assemblage.`);const i=e.forOf(this.injections),r=e.forOf(this.objects);i((e=>this.privateContext.register(e))),r((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=o(e),s=I(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),t.instance?this.singletonInstance=t.instance:this.isSingleton}}const P=(t,n,s,i)=>new Promise((r=>{const o=t[n];if(o){if(e.isAsync(o))return void o.bind(t)(s,i).then((()=>{r()}));r(o.bind(t)(s,i))}}));class R extends x{static build(e){const t=new R;((e,t,n)=>{const r=h(n);r[e]=t;const o=l(r);i(s.AssemblageDefinition,o,n)})("singleton",!0,e);const n=t.register([e]),r=t.require(n.identifier),o=t.initCache.find((e=>e.instance===r));if(!o)throw new Error("Root instance not found in assemblages cache.");const a=t.initCache.indexOf(o);t.initCache.splice(a,1);for(const s of t.initCache)P(s.instance,"onInit",t.publicContext,s.configuration);P(r,"onInit",t.publicContext,n.configuration);for(const s of t.initCache.reverse())P(s.instance,"onInited",t.publicContext,s.configuration);return P(r,"onInited",t.publicContext,n.configuration),t.initCache.length=0,r}dispose(){for(const[e,t]of this.injectables)t.dispose();e.clearInstance(this,R)}register(t,n=!1){const s=!0===n?(e=>({identifier:e[0],concrete:e[0],instance:e[1],configuration:{}}))(t):(t=>e.switchCase({1:()=>(e=>({identifier:e[0],concrete:e[0],configuration:{}}))(t),2:()=>d(t),3:()=>(e=>({identifier:e[0],concrete:e[1],configuration:e[2]}))(t)},(()=>{throw new Error("Injection tuple must be of length 1, 2 or 3.")}))(t.length))(t);if(this.has(s.identifier))throw new Error(`An assemblage is already registered with identifier '${s.identifier.name}'.`);const i=j.of(s,this.privateContext,this.publicContext);return this.injectables.set(i.identifier,i),P(i.concrete,"onRegister",this.publicContext,i.configuration),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}prepareInitHook(e,t){return this.initCache.push({instance:e,configuration:t}),this.initCache}has(e){return"string"==typeof e||"symbol"==typeof e?this.objects.has(e):this.injectables.has(e)}require(e){switch(typeof e){case"string":case"symbol":if(!this.objects.has(e))throw new Error(`Injected object with identifier '${String(e)}' has not been registered.`);return this.objects.get(e);default:if(!this.injectables.has(e))throw new Error(`Class with identifier '${e.name}' has not been registered or is a circular dependency.`);return this.injectables.get(e).build()}}concrete(e){const t=this.injectables.get(e);if(t)return t.concrete}tagged(...e){const t=[];for(const n of e)for(const[e,s]of this.injectables)s.tags.includes(n)&&t.push(s.build());return t}get size(){return this.injectables.size}constructor(){super(),this.injectables=new Map,this.objects=new Map,this.initCache=[],this.publicContext={has:this.has.bind(this),require:this.require.bind(this),concrete:this.concrete.bind(this),tagged:this.tagged.bind(this),dispose:this.dispose.bind(this),on:this.on.bind(this),once:this.once.bind(this),off:this.off.bind(this),events:this.channels},this.privateContext={...this.publicContext,register:this.register.bind(this),use:this.use.bind(this),prepareInitHook:this.prepareInitHook.bind(this),emit:this.emit.bind(this),addChannels:this.addChannels.bind(this),removeChannels:this.removeChannels.bind(this)}}}exports.AbstractAssemblage=class{static onRegister(e,t){}},exports.AbstractAssembler=class extends g{},exports.AbstractEventManager=g,exports.AbstractListenerCollection=class{},exports.Assemblage=e=>t=>u(t,e),exports.Assembler=R,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=C,exports.ConstructorDecorator=A,exports.Context=b,exports.Definition=v,exports.Dispose=y,exports.EventManager=x,exports.ListenerCollection=p,exports.Use=e=>(t,n,s)=>{w(e,t,s)},exports.createConstructorDecorator=e=>t=>A(e,t),exports.decorateAssemblage=u,exports.decorateUse=w,exports.getAssemblageDefinition=e=>r(s.AssemblageDefinition,e),exports.getDecoratedParametersIndexes=I,exports.isAssemblage=a;
|
package/dist/index.mjs
CHANGED
|
@@ -26,8 +26,11 @@ const getParamTypes = (e)=>{
|
|
|
26
26
|
return Reflect.getMetadata(ReflectParamTypes, e) || [];
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
const isAssemblage = (
|
|
30
|
-
return getOwnCustomMetadata(ReflectFlags.IsAssemblage,
|
|
29
|
+
const isAssemblage = (s)=>{
|
|
30
|
+
return getOwnCustomMetadata(ReflectFlags.IsAssemblage, s) || false;
|
|
31
|
+
};
|
|
32
|
+
const getAssemblageDefinition = (e)=>{
|
|
33
|
+
return getOwnCustomMetadata(ReflectValue.AssemblageDefinition, e);
|
|
31
34
|
};
|
|
32
35
|
|
|
33
36
|
const n = {
|
|
@@ -377,7 +380,7 @@ class EventManager {
|
|
|
377
380
|
e(...s);
|
|
378
381
|
}
|
|
379
382
|
cleanChannel(e) {
|
|
380
|
-
return onlyAlphanumeric(e, '*');
|
|
383
|
+
return onlyAlphanumeric(e, '*', ':', '.', '-', '_');
|
|
381
384
|
}
|
|
382
385
|
constructor(...e){
|
|
383
386
|
this.listeners = new ListenerCollection();
|
|
@@ -403,6 +406,10 @@ const registerEvents = (t, n)=>{
|
|
|
403
406
|
t.privateContext.emit(e, ...n);
|
|
404
407
|
});
|
|
405
408
|
}
|
|
409
|
+
} else {
|
|
410
|
+
for (const e of t.events){
|
|
411
|
+
if (!t.privateContext.events.has(e)) t.privateContext.addChannels(e);
|
|
412
|
+
}
|
|
406
413
|
}
|
|
407
414
|
};
|
|
408
415
|
const unregisterEvents = (t, n)=>{
|
|
@@ -414,6 +421,12 @@ const unregisterEvents = (t, n)=>{
|
|
|
414
421
|
}
|
|
415
422
|
e.removeChannels(...t.events);
|
|
416
423
|
t.privateContext.removeChannels(...t.events);
|
|
424
|
+
} else {
|
|
425
|
+
for (const e of t.events){
|
|
426
|
+
if (t.privateContext.events.has(e)) {
|
|
427
|
+
t.privateContext.removeChannels(e);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
417
430
|
}
|
|
418
431
|
};
|
|
419
432
|
|
|
@@ -509,53 +522,50 @@ const getDecoratedParametersIndexes = (t)=>{
|
|
|
509
522
|
};
|
|
510
523
|
|
|
511
524
|
const createConstructorDecorator = (t)=>{
|
|
512
|
-
return (
|
|
525
|
+
return (o)=>ConstructorDecorator(t, o);
|
|
513
526
|
};
|
|
514
|
-
const ConstructorDecorator = (a, f
|
|
527
|
+
const ConstructorDecorator = (a, f)=>(p)=>{
|
|
515
528
|
const m = class extends p {
|
|
516
529
|
constructor(...t){
|
|
517
530
|
super(...t);
|
|
518
|
-
if (a) a.call(this);
|
|
531
|
+
if (a) a.call(this, f);
|
|
519
532
|
}
|
|
520
533
|
};
|
|
521
534
|
Object.defineProperty(m, 'name', {
|
|
522
535
|
value: p.name
|
|
523
536
|
});
|
|
524
|
-
if (!f) {
|
|
525
|
-
return m;
|
|
526
|
-
}
|
|
527
537
|
const l = Reflect.getOwnMetadata(ReflectParamTypes, p) || [];
|
|
528
538
|
const D = getDecoratedParametersIndexes(p);
|
|
529
539
|
const d = [];
|
|
530
|
-
for(let
|
|
531
|
-
if (D.Context.includes(
|
|
540
|
+
for(let e = 0; e < l.length; e++){
|
|
541
|
+
if (D.Context.includes(e)) {
|
|
532
542
|
const n = getOwnCustomMetadata(ReflectParamIndex.Context, p) || [];
|
|
533
|
-
n.push(
|
|
543
|
+
n.push(e);
|
|
534
544
|
defineCustomMetadata(ReflectParamIndex.Context, n, m);
|
|
535
545
|
continue;
|
|
536
546
|
}
|
|
537
|
-
if (D.Definition.includes(
|
|
547
|
+
if (D.Definition.includes(e)) {
|
|
538
548
|
const n = getOwnCustomMetadata(ReflectParamIndex.Definition, p) || [];
|
|
539
|
-
n.push(
|
|
549
|
+
n.push(e);
|
|
540
550
|
defineCustomMetadata(ReflectParamIndex.Definition, n, m);
|
|
541
551
|
continue;
|
|
542
552
|
}
|
|
543
|
-
if (D.Configuration.includes(
|
|
553
|
+
if (D.Configuration.includes(e)) {
|
|
544
554
|
const n = getOwnCustomMetadata(ReflectParamIndex.Configuration, p) || [];
|
|
545
|
-
n.push(
|
|
555
|
+
n.push(e);
|
|
546
556
|
defineCustomMetadata(ReflectParamIndex.Configuration, n, m);
|
|
547
557
|
continue;
|
|
548
558
|
}
|
|
549
|
-
if (D.Dispose.includes(
|
|
559
|
+
if (D.Dispose.includes(e)) {
|
|
550
560
|
const n = getOwnCustomMetadata(ReflectParamIndex.Dispose, p) || [];
|
|
551
|
-
n.push(
|
|
561
|
+
n.push(e);
|
|
552
562
|
defineCustomMetadata(ReflectParamIndex.Dispose, n, m);
|
|
553
|
-
d.push(l[
|
|
563
|
+
d.push(l[e]);
|
|
554
564
|
continue;
|
|
555
565
|
}
|
|
556
|
-
if (D.Use.includes(
|
|
566
|
+
if (D.Use.includes(e)) {
|
|
557
567
|
const t = getOwnCustomMetadata(ReflectParamValue.UseIdentifier, p);
|
|
558
|
-
decorateUse(t[
|
|
568
|
+
decorateUse(t[e], m, e);
|
|
559
569
|
continue;
|
|
560
570
|
}
|
|
561
571
|
}
|
|
@@ -725,6 +735,10 @@ class Assembler extends EventManager {
|
|
|
725
735
|
callHook(e.instance, 'onInit', i.publicContext, e.configuration);
|
|
726
736
|
}
|
|
727
737
|
callHook(n, 'onInit', i.publicContext, s.configuration);
|
|
738
|
+
for (const e of i.initCache.reverse()){
|
|
739
|
+
callHook(e.instance, 'onInited', i.publicContext, e.configuration);
|
|
740
|
+
}
|
|
741
|
+
callHook(n, 'onInited', i.publicContext, s.configuration);
|
|
728
742
|
i.initCache.length = 0;
|
|
729
743
|
return n;
|
|
730
744
|
}
|
|
@@ -832,4 +846,4 @@ class Assembler extends EventManager {
|
|
|
832
846
|
class AbstractAssembler extends AbstractEventManager {
|
|
833
847
|
}
|
|
834
848
|
|
|
835
|
-
export { AbstractAssemblage, AbstractAssembler, AbstractEventManager, AbstractListenerCollection, Assemblage, Assembler, Await, r$1 as Configuration, ConstructorDecorator, s$1 as Context, c$1 as Definition, e$1 as Dispose, EventManager, ListenerCollection, ReflectParamIndex, ReflectParamValue, Use, createConstructorDecorator, decorateAssemblage, decorateUse, getDecoratedParametersIndexes, isAssemblage };
|
|
849
|
+
export { AbstractAssemblage, AbstractAssembler, AbstractEventManager, AbstractListenerCollection, Assemblage, Assembler, Await, r$1 as Configuration, ConstructorDecorator, s$1 as Context, c$1 as Definition, e$1 as Dispose, EventManager, ListenerCollection, ReflectParamIndex, ReflectParamValue, Use, createConstructorDecorator, decorateAssemblage, decorateUse, getAssemblageDefinition, getDecoratedParametersIndexes, isAssemblage };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "assemblerjs",
|
|
3
3
|
"description": "A general purpose Dependency Injection library for node and browser.",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.8",
|
|
5
5
|
"author": "Benoît LAHOZ <info@benoitlahoz.io>",
|
|
6
6
|
"bugs": "https://github.com/benoitlahoz/assemblerjs/issues",
|
|
7
7
|
"homepage": "https://github.com/benoitlahoz/assemblerjs#README",
|