assemblerjs 0.0.9

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 ADDED
@@ -0,0 +1 @@
1
+ # assembler.js
@@ -0,0 +1,194 @@
1
+ /**
2
+ * An abstract class.
3
+ */
4
+ declare interface Abstract<T> extends Function {
5
+ prototype: T;
6
+ }
7
+
8
+ export declare abstract class AbstractAssemblage {
9
+ [key: string]: any;
10
+ abstract onInit?(): void | Promise<void>;
11
+ abstract onDispose?(): void;
12
+ }
13
+
14
+ export declare abstract class AbstractAssembler {
15
+ abstract context: AssemblerContext;
16
+ abstract register<T>(injection: Injection<T>): void;
17
+ abstract has<T>(identifier: Identifier<T>): boolean;
18
+ abstract require<T>(identifier: Identifier<T>): T;
19
+ }
20
+
21
+ /**
22
+ * Generic `Array` items.
23
+ */
24
+ declare type ArrayItems<T extends Array<any>> = T extends Array<infer TItems> ? TItems : never;
25
+
26
+ /**
27
+ * Methods or keys that mutate an `Array`.
28
+ */
29
+ declare type ArrayLengthMutationKeys = 'splice' | 'push' | 'pop' | 'shift' | 'unshift' | number;
30
+
31
+ export declare const Assemblage: (definition?: AssemblageDefinition) => ClassDecorator;
32
+
33
+ declare interface AssemblageDefinition {
34
+ singleton?: false;
35
+ inject?: Injection<unknown>[][];
36
+ tags?: string | string[];
37
+ controller?: true;
38
+ path?: string;
39
+ metadata?: Record<string, any>;
40
+ }
41
+
42
+ export declare class Assembler implements AbstractAssembler {
43
+ protected injectables: Map<Identifier<unknown>, Injectable<unknown>>;
44
+ readonly context: AssemblerContext;
45
+ static build(entry: Concrete<any>): Assembler;
46
+ private constructor();
47
+ /**
48
+ * Recursively register an `Injection` tuple and its inner injected dependencies.
49
+ *
50
+ * @param { Injection<T> } injection The injection tuple to register.
51
+ */
52
+ register<T>(injection: Injection<T>): Injectable<T>;
53
+ /**
54
+ * Check if `Assembler` has given identifier registered.
55
+ *
56
+ * @param { Identifier<T> } identifier An identifier (abstract or concrete class).
57
+ * @returns { boolean } `true` if dependency has been registered.
58
+ */
59
+ has<T>(identifier: Identifier<T>): boolean;
60
+ /**
61
+ * Get or instantiate an assemblage for given identifier.
62
+ *
63
+ * @param { Identifier<T> } identifier The identifier to get instance from.
64
+ * @returns { T } An instance of Concrete<T>.
65
+ */
66
+ require<T>(identifier: Identifier<T>): T;
67
+ }
68
+
69
+ declare class AssemblerContext {
70
+ /**
71
+ * User-defined data. Can be used to add properties to context after creation.
72
+ */
73
+ readonly userData: Record<string, any>;
74
+ register: AbstractAssembler['register'];
75
+ has: AbstractAssembler['has'];
76
+ require: AbstractAssembler['require'];
77
+ constructor(assembler: AbstractAssembler);
78
+ /**
79
+ * Add a value to user-defined data.
80
+ *
81
+ * @param { string } key The key to add.
82
+ * @param { any } value The value to add.
83
+ * @returns { this } This context.
84
+ */
85
+ set(key: string, value: any): this;
86
+ /**
87
+ * Get a value in user-defined data for given key.
88
+ *
89
+ * @param { string } key The key to get from user-defined data.
90
+ * @returns { any } The result.
91
+ */
92
+ get(key: string): any;
93
+ }
94
+
95
+ /**
96
+ * Injectable binds a concrete class to an abstract class as identifier without configuration.
97
+ */
98
+ declare type BaseInjection<T> = Tuple<[Abstract<T>, Concrete<T>]>;
99
+
100
+ /**
101
+ * A concrete (newable) class.
102
+ */
103
+ declare interface Concrete<T> extends Function {
104
+ new (...args: any[]): T;
105
+ }
106
+
107
+ /**
108
+ * Injection binds a concrete class to itself as identifier
109
+ * and provides a configuration object that will be passed to context.
110
+ */
111
+ declare type ConcreteConfiguredInjection<T> = Tuple<[
112
+ Concrete<T>,
113
+ Record<string, any>
114
+ ]>;
115
+
116
+ /**
117
+ * Injectable binds a conrete class to itself as identifier.
118
+ */
119
+ declare type ConcreteInjection<T> = Tuple<[Concrete<T>]>;
120
+
121
+ export declare const Configuration: () => ParameterDecorator;
122
+
123
+ /**
124
+ * Injectable binds a concrete class to an abstract class as identifier
125
+ * and provides a configuration object that will be passed to context.
126
+ */
127
+ declare type ConfiguredInjection<T> = Tuple<[
128
+ Abstract<T>,
129
+ Concrete<T>,
130
+ Record<string, any>
131
+ ]>;
132
+
133
+ export declare const Context: () => ParameterDecorator;
134
+
135
+ /**
136
+ * An identifier can be an abstract or a concrete class.
137
+ */
138
+ declare type Identifier<T> = Concrete<T> | Abstract<T>;
139
+
140
+ declare class Injectable<T> {
141
+ private context;
142
+ readonly identifier: Identifier<T>;
143
+ readonly concrete: Concrete<T>;
144
+ readonly configuration: Record<string, any>;
145
+ singleton: T | undefined;
146
+ static of<TNew>(injection: Injection<TNew>, context: AssemblerContext): Injectable<TNew>;
147
+ private constructor();
148
+ /**
149
+ * Instantiate the assemblage or get its singleton instance.
150
+ *
151
+ * @param { ...any[] } args The arguments to be passed to asssemblage's constructor.
152
+ * @returns { T } The assemblage instance.
153
+ */
154
+ build(): T;
155
+ /**
156
+ * Resolve dependencies passed as parameters in constructor.
157
+ *
158
+ * @returns { (Identifier<unknown> | any)[] } An array of parameters.
159
+ */
160
+ private resolveDependencies;
161
+ /**
162
+ * `true` if assemblage is a singleton.
163
+ *
164
+ * @todo Change assembler to avoid checking instance.
165
+ */
166
+ get isSingleton(): boolean;
167
+ /**
168
+ * Injectable assemblage's own injections defined in its decorator's definition.
169
+ */
170
+ get injections(): Injection<unknown>[];
171
+ /**
172
+ * Injectable assemblage's dependencies passed as 'constructor' parameters.
173
+ */
174
+ get dependencies(): (Identifier<unknown> | any)[];
175
+ get metadata(): Record<string, any>;
176
+ }
177
+
178
+ /**
179
+ * A generic injection tuple.
180
+ */
181
+ declare type Injection<T> = BaseInjection<T> | ConfiguredInjection<T> | ConcreteInjection<T> | ConcreteConfiguredInjection<T>;
182
+
183
+ export declare const Metadata: () => ParameterDecorator;
184
+
185
+ /**
186
+ * An array of fixed length typed values.
187
+ *
188
+ * @see https://stackoverflow.com/a/59906630/1060921
189
+ */
190
+ declare type Tuple<T extends any[]> = Pick<T, Exclude<keyof T, ArrayLengthMutationKeys>> & {
191
+ [Symbol.iterator]: () => IterableIterator<ArrayItems<T>>;
192
+ };
193
+
194
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,306 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ class AbstractAssemblage {
6
+ }
7
+
8
+ const ReflectCustomPrefix = '__';
9
+ const ReflectCustomSuffix = '__';
10
+ const ReflectParamTypes = 'design:paramtypes';
11
+ const ReflectIsAssemblageFlag = `is_assemblage`;
12
+ const ReflectIsSingletonFlag = `is_singleton`;
13
+ const ReflectIsControllerFlag = `is_controller`;
14
+ const ReflectContextParamIndex = `context_param_index`;
15
+ const ReflectConfigurationParamIndex = `config_param_index`;
16
+ const ReflectMetadataParamIndex = `metadata_param_index`;
17
+
18
+ const defineCustomMetadata = (a, o, n)=>{
19
+ Reflect.defineMetadata(`${ReflectCustomPrefix}${a}${ReflectCustomSuffix}`, o, n);
20
+ };
21
+ const getCustomMetadata = (a, o)=>{
22
+ return Reflect.getMetadata(`${ReflectCustomPrefix}${a}${ReflectCustomSuffix}`, o);
23
+ };
24
+ const getOwnCustomMetadata = (a, o)=>{
25
+ return Reflect.getOwnMetadata(`${ReflectCustomPrefix}${a}${ReflectCustomSuffix}`, o);
26
+ };
27
+
28
+ const Assemblage = (n)=>{
29
+ const s = n || {};
30
+ return (n)=>{
31
+ defineCustomMetadata(ReflectIsAssemblageFlag, true, n);
32
+ defineCustomMetadata(ReflectIsSingletonFlag, true, n);
33
+ for(const e in s){
34
+ if (s.hasOwnProperty(e)) {
35
+ switch(e){
36
+ case 'singleton':
37
+ {
38
+ if (s.singleton === false) {
39
+ defineCustomMetadata(ReflectIsSingletonFlag, false, n);
40
+ }
41
+ break;
42
+ }
43
+ case 'controller':
44
+ {
45
+ if (s.controller === true) {
46
+ if (typeof s.path !== 'string') {
47
+ throw new Error(`Controller assemblage '${n.name}' must define a path.`);
48
+ }
49
+ defineCustomMetadata(ReflectIsControllerFlag, true, n);
50
+ }
51
+ break;
52
+ }
53
+ default:
54
+ {
55
+ defineCustomMetadata(e, s[e], n);
56
+ }
57
+ }
58
+ }
59
+ }
60
+ return n;
61
+ };
62
+ };
63
+
64
+ class AbstractAssembler {
65
+ }
66
+
67
+ const NoOp = (...e)=>{};
68
+ const isClass = (e)=>{
69
+ return e && typeof e === 'function' && typeof e.constructor !== 'undefined';
70
+ };
71
+ const isObject = (e)=>typeof e === 'object' && !Array.isArray(e) && !isClass(e);
72
+ const switchCase = (e, t)=>(o, ...s)=>e[o] ? e[o](...s) : t ? t(o, ...s) : NoOp();
73
+ const pipe = (...e)=>(t)=>e.reduce((e, t)=>t(e), t);
74
+ const conditionally = (e)=>(t)=>{
75
+ return e.if(t) ? e.then(t) : e.else ? e.else(t) : undefined;
76
+ };
77
+
78
+ const i = (n)=>{
79
+ return {
80
+ identifier: n[0],
81
+ concrete: n[0],
82
+ configuration: {}
83
+ };
84
+ };
85
+ const c = (r)=>{
86
+ const i = ()=>isClass(r[0]) && isClass(r[1]);
87
+ const c = ()=>isClass(r[0]) && isObject(r[1]);
88
+ const u = ()=>pipe(conditionally({
89
+ if: ()=>i(),
90
+ then: ()=>{
91
+ return {
92
+ identifier: r[0],
93
+ concrete: r[1],
94
+ configuration: {}
95
+ };
96
+ }
97
+ }), conditionally({
98
+ if: ()=>c(),
99
+ then: ()=>{
100
+ return {
101
+ identifier: r[0],
102
+ concrete: r[0],
103
+ configuration: r[1]
104
+ };
105
+ },
106
+ else: (n)=>n
107
+ }))();
108
+ return u();
109
+ };
110
+ const u = (n)=>{
111
+ return {
112
+ identifier: n[0],
113
+ concrete: n[1],
114
+ configuration: n[2]
115
+ };
116
+ };
117
+ const resolveInjectionTuple = (n)=>switchCase({
118
+ 1: ()=>i(n),
119
+ 2: ()=>c(n),
120
+ 3: ()=>u(n)
121
+ }, ()=>{
122
+ throw new Error(`Injection tuple must be of length 1, 2 or 3.`);
123
+ })(n.length);
124
+
125
+ function t(t, e, n) {
126
+ if (e in t) {
127
+ Object.defineProperty(t, e, {
128
+ value: n,
129
+ enumerable: true,
130
+ configurable: true,
131
+ writable: true
132
+ });
133
+ } else {
134
+ t[e] = n;
135
+ }
136
+ return t;
137
+ }
138
+ class Injectable {
139
+ static of(t, e) {
140
+ return new Injectable(t, e);
141
+ }
142
+ build() {
143
+ if (this.singleton) return this.singleton;
144
+ const t = this.resolveDependencies();
145
+ const e = new this.concrete(...t);
146
+ if (this.isSingleton) {
147
+ this.singleton = e;
148
+ }
149
+ return e;
150
+ }
151
+ resolveDependencies() {
152
+ const t = [];
153
+ const i = getOwnCustomMetadata(ReflectContextParamIndex, this.concrete) || [];
154
+ const s = getOwnCustomMetadata(ReflectConfigurationParamIndex, this.concrete) || [];
155
+ const h = getCustomMetadata(ReflectMetadataParamIndex, this.concrete) || [];
156
+ let u = 0;
157
+ for (const e of this.dependencies){
158
+ if (i.includes(u)) {
159
+ t.push(this.context);
160
+ u++;
161
+ continue;
162
+ }
163
+ if (s.includes(u)) {
164
+ t.push(this.configuration);
165
+ u++;
166
+ continue;
167
+ }
168
+ if (h.includes(u)) {
169
+ t.push(this.metadata);
170
+ u++;
171
+ continue;
172
+ }
173
+ t.push(this.context.require(e));
174
+ u++;
175
+ }
176
+ return t;
177
+ }
178
+ get isSingleton() {
179
+ return getOwnCustomMetadata(ReflectIsSingletonFlag, this.concrete) || false;
180
+ }
181
+ get injections() {
182
+ return getOwnCustomMetadata('inject', this.concrete) || [];
183
+ }
184
+ get dependencies() {
185
+ return Reflect.getMetadata(ReflectParamTypes, this.concrete) || [];
186
+ }
187
+ get metadata() {
188
+ return getCustomMetadata('metadata', this.concrete) || {};
189
+ }
190
+ constructor(e, n){
191
+ t(this, "context", undefined);
192
+ t(this, "identifier", undefined);
193
+ t(this, "concrete", undefined);
194
+ t(this, "configuration", undefined);
195
+ t(this, "singleton", undefined);
196
+ this.context = n;
197
+ const i = resolveInjectionTuple(e);
198
+ this.identifier = i.identifier;
199
+ this.concrete = i.concrete;
200
+ this.configuration = i.configuration;
201
+ for (const t of this.injections){
202
+ this.context.register(t);
203
+ }
204
+ }
205
+ }
206
+
207
+ function e$2(e, r, t) {
208
+ if (r in e) {
209
+ Object.defineProperty(e, r, {
210
+ value: t,
211
+ enumerable: true,
212
+ configurable: true,
213
+ writable: true
214
+ });
215
+ } else {
216
+ e[r] = t;
217
+ }
218
+ return e;
219
+ }
220
+ class AssemblerContext {
221
+ set(e, r) {
222
+ if (this.userData[e]) {
223
+ throw new Error(`Key '${e}' is already defined in context's user data.`);
224
+ }
225
+ this.userData[e] = r;
226
+ return this;
227
+ }
228
+ get(e) {
229
+ return this.userData[e];
230
+ }
231
+ constructor(r){
232
+ e$2(this, "userData", {});
233
+ e$2(this, "register", undefined);
234
+ e$2(this, "has", undefined);
235
+ e$2(this, "require", undefined);
236
+ this.register = r.register.bind(r);
237
+ this.has = r.has.bind(r);
238
+ this.require = r.require.bind(r);
239
+ }
240
+ }
241
+
242
+ function e$1(e, t, i) {
243
+ if (t in e) {
244
+ Object.defineProperty(e, t, {
245
+ value: i,
246
+ enumerable: true,
247
+ configurable: true,
248
+ writable: true
249
+ });
250
+ } else {
251
+ e[t] = i;
252
+ }
253
+ return e;
254
+ }
255
+ class Assembler {
256
+ static build(e) {
257
+ return new Assembler(e);
258
+ }
259
+ register(e) {
260
+ const t = Injectable.of(e, this.context);
261
+ if (this.has(t.identifier)) {
262
+ throw new Error(`An assemblage is already registered with identifier '${t.identifier.name}'.`);
263
+ }
264
+ this.injectables.set(t.identifier, t);
265
+ return t;
266
+ }
267
+ has(e) {
268
+ return this.injectables.has(e);
269
+ }
270
+ require(e) {
271
+ if (!this.injectables.has(e)) {
272
+ throw new Error(`Assemblage with identifier '${e.name}' has not been registered.`);
273
+ }
274
+ const t = this.injectables.get(e);
275
+ return t.build();
276
+ }
277
+ constructor(r){
278
+ e$1(this, "injectables", new Map());
279
+ e$1(this, "context", undefined);
280
+ this.context = new AssemblerContext(this);
281
+ defineCustomMetadata(ReflectIsSingletonFlag, true, r);
282
+ const s = this.register([
283
+ r
284
+ ]);
285
+ return s.build();
286
+ }
287
+ }
288
+
289
+ const m = (o)=>()=>{
290
+ return (t, n, m)=>{
291
+ const s = getOwnCustomMetadata(o, t) || [];
292
+ s.push(m);
293
+ defineCustomMetadata(o, s, t);
294
+ };
295
+ };
296
+ const s = m(ReflectContextParamIndex);
297
+ const e = m(ReflectConfigurationParamIndex);
298
+ const a = m(ReflectMetadataParamIndex);
299
+
300
+ exports.AbstractAssemblage = AbstractAssemblage;
301
+ exports.AbstractAssembler = AbstractAssembler;
302
+ exports.Assemblage = Assemblage;
303
+ exports.Assembler = Assembler;
304
+ exports.Configuration = e;
305
+ exports.Context = s;
306
+ exports.Metadata = a;
package/dist/index.mjs ADDED
@@ -0,0 +1,296 @@
1
+ class AbstractAssemblage {
2
+ }
3
+
4
+ const ReflectCustomPrefix = '__';
5
+ const ReflectCustomSuffix = '__';
6
+ const ReflectParamTypes = 'design:paramtypes';
7
+ const ReflectIsAssemblageFlag = `is_assemblage`;
8
+ const ReflectIsSingletonFlag = `is_singleton`;
9
+ const ReflectIsControllerFlag = `is_controller`;
10
+ const ReflectContextParamIndex = `context_param_index`;
11
+ const ReflectConfigurationParamIndex = `config_param_index`;
12
+ const ReflectMetadataParamIndex = `metadata_param_index`;
13
+
14
+ const defineCustomMetadata = (a, o, n)=>{
15
+ Reflect.defineMetadata(`${ReflectCustomPrefix}${a}${ReflectCustomSuffix}`, o, n);
16
+ };
17
+ const getCustomMetadata = (a, o)=>{
18
+ return Reflect.getMetadata(`${ReflectCustomPrefix}${a}${ReflectCustomSuffix}`, o);
19
+ };
20
+ const getOwnCustomMetadata = (a, o)=>{
21
+ return Reflect.getOwnMetadata(`${ReflectCustomPrefix}${a}${ReflectCustomSuffix}`, o);
22
+ };
23
+
24
+ const Assemblage = (n)=>{
25
+ const s = n || {};
26
+ return (n)=>{
27
+ defineCustomMetadata(ReflectIsAssemblageFlag, true, n);
28
+ defineCustomMetadata(ReflectIsSingletonFlag, true, n);
29
+ for(const e in s){
30
+ if (s.hasOwnProperty(e)) {
31
+ switch(e){
32
+ case 'singleton':
33
+ {
34
+ if (s.singleton === false) {
35
+ defineCustomMetadata(ReflectIsSingletonFlag, false, n);
36
+ }
37
+ break;
38
+ }
39
+ case 'controller':
40
+ {
41
+ if (s.controller === true) {
42
+ if (typeof s.path !== 'string') {
43
+ throw new Error(`Controller assemblage '${n.name}' must define a path.`);
44
+ }
45
+ defineCustomMetadata(ReflectIsControllerFlag, true, n);
46
+ }
47
+ break;
48
+ }
49
+ default:
50
+ {
51
+ defineCustomMetadata(e, s[e], n);
52
+ }
53
+ }
54
+ }
55
+ }
56
+ return n;
57
+ };
58
+ };
59
+
60
+ class AbstractAssembler {
61
+ }
62
+
63
+ const NoOp = (...e)=>{};
64
+ const isClass = (e)=>{
65
+ return e && typeof e === 'function' && typeof e.constructor !== 'undefined';
66
+ };
67
+ const isObject = (e)=>typeof e === 'object' && !Array.isArray(e) && !isClass(e);
68
+ const switchCase = (e, t)=>(o, ...s)=>e[o] ? e[o](...s) : t ? t(o, ...s) : NoOp();
69
+ const pipe = (...e)=>(t)=>e.reduce((e, t)=>t(e), t);
70
+ const conditionally = (e)=>(t)=>{
71
+ return e.if(t) ? e.then(t) : e.else ? e.else(t) : undefined;
72
+ };
73
+
74
+ const i = (n)=>{
75
+ return {
76
+ identifier: n[0],
77
+ concrete: n[0],
78
+ configuration: {}
79
+ };
80
+ };
81
+ const c = (r)=>{
82
+ const i = ()=>isClass(r[0]) && isClass(r[1]);
83
+ const c = ()=>isClass(r[0]) && isObject(r[1]);
84
+ const u = ()=>pipe(conditionally({
85
+ if: ()=>i(),
86
+ then: ()=>{
87
+ return {
88
+ identifier: r[0],
89
+ concrete: r[1],
90
+ configuration: {}
91
+ };
92
+ }
93
+ }), conditionally({
94
+ if: ()=>c(),
95
+ then: ()=>{
96
+ return {
97
+ identifier: r[0],
98
+ concrete: r[0],
99
+ configuration: r[1]
100
+ };
101
+ },
102
+ else: (n)=>n
103
+ }))();
104
+ return u();
105
+ };
106
+ const u = (n)=>{
107
+ return {
108
+ identifier: n[0],
109
+ concrete: n[1],
110
+ configuration: n[2]
111
+ };
112
+ };
113
+ const resolveInjectionTuple = (n)=>switchCase({
114
+ 1: ()=>i(n),
115
+ 2: ()=>c(n),
116
+ 3: ()=>u(n)
117
+ }, ()=>{
118
+ throw new Error(`Injection tuple must be of length 1, 2 or 3.`);
119
+ })(n.length);
120
+
121
+ function t(t, e, n) {
122
+ if (e in t) {
123
+ Object.defineProperty(t, e, {
124
+ value: n,
125
+ enumerable: true,
126
+ configurable: true,
127
+ writable: true
128
+ });
129
+ } else {
130
+ t[e] = n;
131
+ }
132
+ return t;
133
+ }
134
+ class Injectable {
135
+ static of(t, e) {
136
+ return new Injectable(t, e);
137
+ }
138
+ build() {
139
+ if (this.singleton) return this.singleton;
140
+ const t = this.resolveDependencies();
141
+ const e = new this.concrete(...t);
142
+ if (this.isSingleton) {
143
+ this.singleton = e;
144
+ }
145
+ return e;
146
+ }
147
+ resolveDependencies() {
148
+ const t = [];
149
+ const i = getOwnCustomMetadata(ReflectContextParamIndex, this.concrete) || [];
150
+ const s = getOwnCustomMetadata(ReflectConfigurationParamIndex, this.concrete) || [];
151
+ const h = getCustomMetadata(ReflectMetadataParamIndex, this.concrete) || [];
152
+ let u = 0;
153
+ for (const e of this.dependencies){
154
+ if (i.includes(u)) {
155
+ t.push(this.context);
156
+ u++;
157
+ continue;
158
+ }
159
+ if (s.includes(u)) {
160
+ t.push(this.configuration);
161
+ u++;
162
+ continue;
163
+ }
164
+ if (h.includes(u)) {
165
+ t.push(this.metadata);
166
+ u++;
167
+ continue;
168
+ }
169
+ t.push(this.context.require(e));
170
+ u++;
171
+ }
172
+ return t;
173
+ }
174
+ get isSingleton() {
175
+ return getOwnCustomMetadata(ReflectIsSingletonFlag, this.concrete) || false;
176
+ }
177
+ get injections() {
178
+ return getOwnCustomMetadata('inject', this.concrete) || [];
179
+ }
180
+ get dependencies() {
181
+ return Reflect.getMetadata(ReflectParamTypes, this.concrete) || [];
182
+ }
183
+ get metadata() {
184
+ return getCustomMetadata('metadata', this.concrete) || {};
185
+ }
186
+ constructor(e, n){
187
+ t(this, "context", undefined);
188
+ t(this, "identifier", undefined);
189
+ t(this, "concrete", undefined);
190
+ t(this, "configuration", undefined);
191
+ t(this, "singleton", undefined);
192
+ this.context = n;
193
+ const i = resolveInjectionTuple(e);
194
+ this.identifier = i.identifier;
195
+ this.concrete = i.concrete;
196
+ this.configuration = i.configuration;
197
+ for (const t of this.injections){
198
+ this.context.register(t);
199
+ }
200
+ }
201
+ }
202
+
203
+ function e$2(e, r, t) {
204
+ if (r in e) {
205
+ Object.defineProperty(e, r, {
206
+ value: t,
207
+ enumerable: true,
208
+ configurable: true,
209
+ writable: true
210
+ });
211
+ } else {
212
+ e[r] = t;
213
+ }
214
+ return e;
215
+ }
216
+ class AssemblerContext {
217
+ set(e, r) {
218
+ if (this.userData[e]) {
219
+ throw new Error(`Key '${e}' is already defined in context's user data.`);
220
+ }
221
+ this.userData[e] = r;
222
+ return this;
223
+ }
224
+ get(e) {
225
+ return this.userData[e];
226
+ }
227
+ constructor(r){
228
+ e$2(this, "userData", {});
229
+ e$2(this, "register", undefined);
230
+ e$2(this, "has", undefined);
231
+ e$2(this, "require", undefined);
232
+ this.register = r.register.bind(r);
233
+ this.has = r.has.bind(r);
234
+ this.require = r.require.bind(r);
235
+ }
236
+ }
237
+
238
+ function e$1(e, t, i) {
239
+ if (t in e) {
240
+ Object.defineProperty(e, t, {
241
+ value: i,
242
+ enumerable: true,
243
+ configurable: true,
244
+ writable: true
245
+ });
246
+ } else {
247
+ e[t] = i;
248
+ }
249
+ return e;
250
+ }
251
+ class Assembler {
252
+ static build(e) {
253
+ return new Assembler(e);
254
+ }
255
+ register(e) {
256
+ const t = Injectable.of(e, this.context);
257
+ if (this.has(t.identifier)) {
258
+ throw new Error(`An assemblage is already registered with identifier '${t.identifier.name}'.`);
259
+ }
260
+ this.injectables.set(t.identifier, t);
261
+ return t;
262
+ }
263
+ has(e) {
264
+ return this.injectables.has(e);
265
+ }
266
+ require(e) {
267
+ if (!this.injectables.has(e)) {
268
+ throw new Error(`Assemblage with identifier '${e.name}' has not been registered.`);
269
+ }
270
+ const t = this.injectables.get(e);
271
+ return t.build();
272
+ }
273
+ constructor(r){
274
+ e$1(this, "injectables", new Map());
275
+ e$1(this, "context", undefined);
276
+ this.context = new AssemblerContext(this);
277
+ defineCustomMetadata(ReflectIsSingletonFlag, true, r);
278
+ const s = this.register([
279
+ r
280
+ ]);
281
+ return s.build();
282
+ }
283
+ }
284
+
285
+ const m = (o)=>()=>{
286
+ return (t, n, m)=>{
287
+ const s = getOwnCustomMetadata(o, t) || [];
288
+ s.push(m);
289
+ defineCustomMetadata(o, s, t);
290
+ };
291
+ };
292
+ const s = m(ReflectContextParamIndex);
293
+ const e = m(ReflectConfigurationParamIndex);
294
+ const a = m(ReflectMetadataParamIndex);
295
+
296
+ export { AbstractAssemblage, AbstractAssembler, Assemblage, Assembler, e as Configuration, s as Context, a as Metadata };
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "assemblerjs",
3
+ "description": "A simple and zero-dependency DI package written in typescript.",
4
+ "version": "0.0.9",
5
+ "author": "Benoît LAHOZ <info@benoitlahoz.io>",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/benoitlahoz/assemblerjs"
9
+ },
10
+ "bugs": {
11
+ "url": "https://github.com/benoitlahoz/assemblerjs/issues"
12
+ },
13
+ "homepage": "https://github.com/benoitlahoz/assemblerjs#README",
14
+ "devDependencies": {
15
+ "@swc/core": "^1.9.3",
16
+ "@types/node": "^22.5.5",
17
+ "@vitest/coverage-istanbul": "^2.1.1",
18
+ "assert": "^2.1.0",
19
+ "istanbul": "^0.4.5",
20
+ "istanbul-badges-readme": "^1.9.0",
21
+ "reflect-metadata": ">=0.2.2",
22
+ "rollup-plugin-swc": "^0.2.1",
23
+ "terser": "^5.34.1",
24
+ "vite": "6.0.2",
25
+ "vite-plugin-dts": "^4.4.0",
26
+ "vitest": "^2.1.1"
27
+ },
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.mjs",
32
+ "require": "./dist/index.js"
33
+ }
34
+ },
35
+ "files": [
36
+ "dist/**/*",
37
+ "README.md"
38
+ ],
39
+ "keywords": [
40
+ "composition",
41
+ "decorators",
42
+ "dependency",
43
+ "di",
44
+ "injection",
45
+ "reflection",
46
+ "swc",
47
+ "typescript"
48
+ ],
49
+ "license": "MIT",
50
+ "main": "dist/index.js",
51
+ "scripts": {
52
+ "build": "vite build",
53
+ "coverage": "vitest run --coverage --passWithNoTests && istanbul-badges-readme",
54
+ "test": "vitest --coverage --passWithNoTests"
55
+ },
56
+ "types": "dist/index.d.ts"
57
+ }