@travetto/di 7.0.0-rc.1 → 7.0.0-rc.2

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
@@ -135,7 +135,7 @@ The [@Inject](https://github.com/travetto/travetto/tree/main/module/di/src/decor
135
135
  **Code: Example Injectable with dependencies as Inject fields**
136
136
  ```typescript
137
137
  import { Injectable, Inject } from '@travetto/di';
138
- import { DependentService } from './dep.ts';
138
+ import { DependentService } from './dependency.ts';
139
139
 
140
140
  @Injectable()
141
141
  class CustomService {
@@ -153,15 +153,15 @@ The [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/d
153
153
  **Code: Example Injectable with dependencies in constructor**
154
154
  ```typescript
155
155
  import { Injectable } from '@travetto/di';
156
- import { DependentService } from './dep.ts';
156
+ import { DependentService } from './dependency.ts';
157
157
 
158
158
  @Injectable()
159
159
  class CustomService {
160
160
 
161
161
  dependentService: DependentService;
162
162
 
163
- constructor(svc: DependentService) {
164
- this.dependentService = svc;
163
+ constructor(service: DependentService) {
164
+ this.dependentService = service;
165
165
  }
166
166
 
167
167
  async coolOperation() {
@@ -176,7 +176,7 @@ Via [@InjectableFactory](https://github.com/travetto/travetto/tree/main/module/d
176
176
  ```typescript
177
177
  import { InjectableFactory } from '@travetto/di';
178
178
 
179
- import { DependentService, CustomService } from './dep.ts';
179
+ import { DependentService, CustomService } from './dependency.ts';
180
180
 
181
181
  class Config {
182
182
  @InjectableFactory()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/di",
3
- "version": "7.0.0-rc.1",
3
+ "version": "7.0.0-rc.2",
4
4
  "description": "Dependency registration/management and injection support.",
5
5
  "keywords": [
6
6
  "ast-transformations",
@@ -27,10 +27,10 @@
27
27
  "directory": "module/di"
28
28
  },
29
29
  "dependencies": {
30
- "@travetto/registry": "^7.0.0-rc.1"
30
+ "@travetto/registry": "^7.0.0-rc.2"
31
31
  },
32
32
  "peerDependencies": {
33
- "@travetto/transformer": "^7.0.0-rc.1"
33
+ "@travetto/transformer": "^7.0.0-rc.2"
34
34
  },
35
35
  "peerDependenciesMeta": {
36
36
  "@travetto/transformer": {
package/src/decorator.ts CHANGED
@@ -4,17 +4,17 @@ import { CONSTRUCTOR_PROPERTY } from '@travetto/schema';
4
4
  import { InjectableCandidate, ResolutionType } from './types.ts';
5
5
  import { DependencyRegistryIndex } from './registry/registry-index.ts';
6
6
 
7
- const fromArg = <T extends { qualifier?: symbol }>(arg?: T | symbol): T =>
8
- typeof arg === 'symbol' ? castTo({ qualifier: arg }) : (arg ?? castTo<T>({}));
7
+ const fromInput = <T extends { qualifier?: symbol }>(input?: T | symbol): T =>
8
+ typeof input === 'symbol' ? castTo({ qualifier: input }) : (input ?? castTo<T>({}));
9
9
 
10
10
  /**
11
11
  * Indicate that a class is able to be injected
12
12
  * @augments `@travetto/schema:Schema`
13
13
  * @kind decorator
14
14
  */
15
- export function Injectable(config?: Partial<InjectableCandidate> | symbol) {
15
+ export function Injectable(input?: Partial<InjectableCandidate> | symbol) {
16
16
  return <T extends Class>(cls: T): void => {
17
- DependencyRegistryIndex.getForRegister(cls).registerClass(fromArg(config));
17
+ DependencyRegistryIndex.getForRegister(cls).registerClass(fromInput(input));
18
18
  };
19
19
  }
20
20
 
@@ -26,15 +26,15 @@ export type InjectConfig = { qualifier?: symbol, resolution?: ResolutionType };
26
26
  * @augments `@travetto/schema:Input`
27
27
  * @kind decorator
28
28
  */
29
- export function Inject(config?: InjectConfig | symbol) {
30
- return (instanceOrCls: Class | ClassInstance, property?: string | symbol, idx?: number | PropertyDescriptor): void => {
31
- const cfg = fromArg(config);
29
+ export function Inject(input?: InjectConfig | symbol) {
30
+ return (instanceOrCls: Class | ClassInstance, property?: string, idx?: number | PropertyDescriptor): void => {
31
+ const config = fromInput(input);
32
32
  const cls = getClass(instanceOrCls);
33
33
  const propertyKey = property ?? CONSTRUCTOR_PROPERTY;
34
34
  if (typeof idx !== 'number') {
35
- DependencyRegistryIndex.registerFieldMetadata(cls, propertyKey, cfg);
35
+ DependencyRegistryIndex.registerFieldMetadata(cls, propertyKey, config);
36
36
  } else {
37
- DependencyRegistryIndex.registerParameterMetadata(cls, propertyKey, idx, cfg);
37
+ DependencyRegistryIndex.registerParameterMetadata(cls, propertyKey, idx, config);
38
38
  }
39
39
  };
40
40
  }
@@ -44,9 +44,9 @@ export function Inject(config?: InjectConfig | symbol) {
44
44
  * @augments `@travetto/schema:Method`
45
45
  * @kind decorator
46
46
  */
47
- export function InjectableFactory(config?: Partial<InjectableCandidate> | symbol) {
48
- return <T extends Class>(cls: T, property: string | symbol, descriptor: TypedPropertyDescriptor<(...args: Any[]) => Any>): void => {
49
- DependencyRegistryIndex.getForRegister(cls).registerFactory(property, fromArg(config), {
47
+ export function InjectableFactory(input?: Partial<InjectableCandidate> | symbol) {
48
+ return <T extends Class>(cls: T, property: string, descriptor: TypedPropertyDescriptor<(...args: Any[]) => Any>): void => {
49
+ DependencyRegistryIndex.getForRegister(cls).registerFactory(property, fromInput(input), {
50
50
  factory: (...params: unknown[]) => descriptor.value!.apply(cls, params),
51
51
  });
52
52
  };
@@ -1,24 +1,24 @@
1
1
  import { RegistryAdapter } from '@travetto/registry';
2
- import { Class, classConstruct, describeFunction, getAllEntries, safeAssign } from '@travetto/runtime';
2
+ import { Class, classConstruct, describeFunction, safeAssign } from '@travetto/runtime';
3
3
  import { CONSTRUCTOR_PROPERTY, SchemaRegistryIndex } from '@travetto/schema';
4
4
 
5
5
  import { InjectableConfig, getDefaultQualifier, InjectableCandidate } from '../types';
6
6
 
7
- function combineInjectableCandidates<T extends InjectableCandidate>(base: T, ...override: Partial<T>[]): typeof base {
8
- for (const o of override) {
9
- safeAssign(base, o);
7
+ function combineInjectableCandidates<T extends InjectableCandidate>(base: T, ...overrides: Partial<T>[]): typeof base {
8
+ for (const override of overrides) {
9
+ safeAssign(base, override);
10
10
  }
11
11
  return base;
12
12
  }
13
13
 
14
- function combineClasses<T extends InjectableConfig>(base: T, ...override: Partial<T>[]): typeof base {
15
- for (const o of override) {
14
+ function combineClasses<T extends InjectableConfig>(base: T, ...overrides: Partial<T>[]): typeof base {
15
+ for (const override of overrides) {
16
16
  Object.assign(base, {
17
17
  ...base,
18
- ...o,
18
+ ...override,
19
19
  candidates: {
20
20
  ...base.candidates,
21
- ...o.candidates,
21
+ ...override.candidates,
22
22
  }
23
23
  });
24
24
  }
@@ -38,7 +38,7 @@ export class DependencyRegistryAdapter implements RegistryAdapter<InjectableConf
38
38
  return combineClasses(this.#config, ...data);
39
39
  }
40
40
 
41
- registerFactory(method: string | symbol, ...data: Partial<InjectableCandidate<unknown>>[]): InjectableCandidate {
41
+ registerFactory(method: string, ...data: Partial<InjectableCandidate<unknown>>[]): InjectableCandidate {
42
42
  const { candidates } = this.register();
43
43
  candidates[method] ??= {
44
44
  class: this.#cls,
@@ -62,17 +62,16 @@ export class DependencyRegistryAdapter implements RegistryAdapter<InjectableConf
62
62
  }
63
63
 
64
64
  finalize(): void {
65
- for (const [k] of getAllEntries(this.#config.candidates)) {
66
- const v = this.#config.candidates[k];
67
- const candidateType = SchemaRegistryIndex.get(v.class).getMethodReturnType(k);
68
- v.candidateType = candidateType;
69
- v.qualifier ??= getDefaultQualifier(candidateType);
65
+ for (const method of Object.keys(this.#config.candidates)) {
66
+ const candidate = this.#config.candidates[method];
67
+ const candidateType = SchemaRegistryIndex.get(candidate.class).getMethodReturnType(method);
68
+ candidate.candidateType = candidateType;
69
+ candidate.qualifier ??= getDefaultQualifier(candidateType);
70
70
  }
71
71
  }
72
72
 
73
73
  getCandidateConfigs(): InjectableCandidate[] {
74
- const entries = getAllEntries(this.#config.candidates).map(([_, item]) => item);
75
- return entries
74
+ return Object.values(this.#config.candidates)
76
75
  .filter(item => (item.enabled ?? true) === true || (typeof item.enabled === 'function' && item.enabled()))
77
76
  .filter(item => item.method !== CONSTRUCTOR_PROPERTY || !describeFunction(item.candidateType)?.abstract);
78
77
  }
@@ -33,15 +33,15 @@ export class DependencyRegistryIndex implements RegistryIndex {
33
33
  }
34
34
 
35
35
  static getCandidateTypes<T>(candidateType: Class<T>): Class<T>[] {
36
- return this.#instance.getCandidates(candidateType).map(c => c.candidateType);
36
+ return this.#instance.getCandidates(candidateType).map(candidate => candidate.candidateType);
37
37
  }
38
38
 
39
- static getInstances<T>(candidateType: Class<T>, predicate?: (cfg: InjectableCandidate<T>) => boolean): Promise<T[]> {
39
+ static getInstances<T>(candidateType: Class<T>, predicate?: (config: InjectableCandidate<T>) => boolean): Promise<T[]> {
40
40
  return this.#instance.getInstances<T>(candidateType, predicate);
41
41
  }
42
42
 
43
- static injectFields<T extends { constructor: Class<T> }>(o: T, cls = o.constructor): Promise<T> {
44
- return this.#instance.injectFields(cls, o, cls);
43
+ static injectFields<T extends { constructor: Class<T> }>(item: T, cls = item.constructor): Promise<T> {
44
+ return this.#instance.injectFields(cls, item, cls);
45
45
  }
46
46
 
47
47
  static getOptional(cls: Class): InjectableConfig | undefined {
@@ -52,11 +52,11 @@ export class DependencyRegistryIndex implements RegistryIndex {
52
52
  SchemaRegistryIndex.getForRegister(cls).registerMetadata<InjectableClassMetadata>(MetadataSymbol, metadata);
53
53
  }
54
54
 
55
- static registerParameterMetadata(cls: Class, method: string | symbol, index: number, metadata: Dependency): void {
55
+ static registerParameterMetadata(cls: Class, method: string, index: number, metadata: Dependency): void {
56
56
  SchemaRegistryIndex.getForRegister(cls).registerParameterMetadata(method, index, MetadataSymbol, metadata);
57
57
  }
58
58
 
59
- static registerFieldMetadata(cls: Class, field: string | symbol, metadata: Dependency): void {
59
+ static registerFieldMetadata(cls: Class, field: string, metadata: Dependency): void {
60
60
  SchemaRegistryIndex.getForRegister(cls).registerFieldMetadata(field, MetadataSymbol, metadata);
61
61
  }
62
62
 
@@ -117,18 +117,18 @@ export class DependencyRegistryIndex implements RegistryIndex {
117
117
  }
118
118
 
119
119
 
120
- async #resolveDependencyValue(dependency: Dependency, input: SchemaFieldConfig | SchemaParameterConfig, src: Class): Promise<unknown> {
120
+ async #resolveDependencyValue(dependency: Dependency, input: SchemaFieldConfig | SchemaParameterConfig, cls: Class): Promise<unknown> {
121
121
  try {
122
122
  const target = dependency.target ?? input.type;
123
123
  return await this.getInstance(target, dependency.qualifier, dependency.resolution);
124
- } catch (err) {
125
- if (input.required?.active === false && err instanceof InjectionError && err.category === 'notfound') {
124
+ } catch (error) {
125
+ if (input.required?.active === false && error instanceof InjectionError && error.category === 'notfound') {
126
126
  return undefined;
127
127
  } else {
128
- if (err && err instanceof Error) {
129
- err.message = `${err.message} via=${src.Ⲑid}[${input.name?.toString() ?? 'constructor'}]`;
128
+ if (error && error instanceof Error) {
129
+ error.message = `${error.message} via=${cls.Ⲑid}[${input.name?.toString() ?? 'constructor'}]`;
130
130
  }
131
- throw err;
131
+ throw error;
132
132
  }
133
133
  }
134
134
  }
@@ -140,12 +140,12 @@ export class DependencyRegistryIndex implements RegistryIndex {
140
140
  }
141
141
 
142
142
  process(events: ChangeEvent<Class>[]): void {
143
- for (const ev of events) {
144
- if ('prev' in ev) {
145
- this.#removeClass(ev.prev);
143
+ for (const event of events) {
144
+ if ('previous' in event) {
145
+ this.#removeClass(event.previous);
146
146
  }
147
- if ('curr' in ev) {
148
- this.#addClass(ev.curr, 'prev' in ev);
147
+ if ('current' in event) {
148
+ this.#addClass(event.current, 'previous' in event);
149
149
  }
150
150
  }
151
151
  }
@@ -154,15 +154,15 @@ export class DependencyRegistryIndex implements RegistryIndex {
154
154
  * Get all available candidates for a given type
155
155
  */
156
156
  getCandidates<T>(candidateType: Class<T>): InjectableCandidate<T>[] {
157
- return this.#resolver.getCandidateEntries(candidateType).map(([_, x]) => castTo<InjectableCandidate<T>>(x));
157
+ return this.#resolver.getCandidateEntries(candidateType).map(([_, candidate]) => castTo<InjectableCandidate<T>>(candidate));
158
158
  }
159
159
 
160
160
  /**
161
161
  * Get candidate instances by target type, with an optional filter
162
162
  */
163
- getInstances<T>(candidateType: Class<T>, predicate?: (cfg: InjectableCandidate<T>) => boolean): Promise<T[]> {
164
- const inputs = this.getCandidates<T>(candidateType).filter(x => !predicate || predicate(x));
165
- return Promise.all(inputs.map(l => this.getInstance<T>(l.class, l.qualifier)));
163
+ getInstances<T>(candidateType: Class<T>, predicate?: (config: InjectableCandidate<T>) => boolean): Promise<T[]> {
164
+ const inputs = this.getCandidates<T>(candidateType).filter(candidate => !predicate || predicate(candidate));
165
+ return Promise.all(inputs.map(candidate => this.getInstance<T>(candidate.class, candidate.qualifier)));
166
166
  }
167
167
 
168
168
  /**
@@ -185,13 +185,13 @@ export class DependencyRegistryIndex implements RegistryIndex {
185
185
  const inputs = SchemaRegistryIndex.getOptional(candidateType)?.getFields() ?? {};
186
186
 
187
187
  const promises = TypedObject.entries(inputs)
188
- .filter(([k, input]) => readMetadata(input) !== undefined && (input.access !== 'readonly' && instance[castKey(k)] === undefined))
189
- .map(async ([k, input]) => [k, await this.#resolveDependencyValue(readMetadata(input) ?? {}, input, srcClass)] as const);
188
+ .filter(([key, input]) => readMetadata(input) !== undefined && (input.access !== 'readonly' && instance[castKey(key)] === undefined))
189
+ .map(async ([key, input]) => [key, await this.#resolveDependencyValue(readMetadata(input) ?? {}, input, srcClass)] as const);
190
190
 
191
191
  const pairs = await Promise.all(promises);
192
192
 
193
- for (const [k, v] of pairs) {
194
- instance[castKey(k)] = castTo(v);
193
+ for (const [key, value] of pairs) {
194
+ instance[castKey(key)] = castTo(value);
195
195
  }
196
196
  return instance;
197
197
  }
@@ -217,8 +217,8 @@ export class DependencyRegistryIndex implements RegistryIndex {
217
217
  SchemaRegistryIndex.get(targetType).getMetadata<InjectableClassMetadata>(MetadataSymbol) : undefined;
218
218
 
219
219
  // Run post constructors
220
- for (const op of Object.values(metadata?.postConstruct ?? {})) {
221
- await op(inst);
220
+ for (const operation of Object.values(metadata?.postConstruct ?? {})) {
221
+ await operation(inst);
222
222
  }
223
223
 
224
224
  // Proxy if necessary
@@ -250,10 +250,10 @@ export class DependencyRegistryIndex implements RegistryIndex {
250
250
  const instance = await instancePromise;
251
251
  this.#instances.get(target)!.set(qualifier, instance);
252
252
  return instance;
253
- } catch (err) {
253
+ } catch (error) {
254
254
  // Clear it out, don't save failed constructions
255
255
  this.#instancePromises.get(target)!.delete(qualifier);
256
- throw err;
256
+ throw error;
257
257
  }
258
258
  }
259
259
 
@@ -6,11 +6,11 @@ import { InjectionError } from '../error';
6
6
 
7
7
  type Resolved<T> = { candidate: InjectableCandidate<T>, qualifier: symbol, target: Class };
8
8
 
9
- function setInMap<T>(map: Map<Class, Map<typeof key, T>>, src: Class, key: symbol | string, dest: T): void {
10
- if (!map.has(src)) {
11
- map.set(src, new Map());
9
+ function setInMap<T>(map: Map<Class, Map<typeof key, T>>, cls: Class, key: symbol | string, dest: T): void {
10
+ if (!map.has(cls)) {
11
+ map.set(cls, new Map());
12
12
  }
13
- map.get(src)!.set(key, dest);
13
+ map.get(cls)!.set(key, dest);
14
14
  }
15
15
 
16
16
  export class DependencyRegistryResolver {
@@ -38,15 +38,17 @@ export class DependencyRegistryResolver {
38
38
  if (qualifiers.has(PrimaryCandidateSymbol)) {
39
39
  return PrimaryCandidateSymbol;
40
40
  } else {
41
- const filtered = resolved.filter(x => !!x).filter(x => this.#defaultSymbols.has(x));
41
+ const filtered = resolved
42
+ .filter(qualifier => !!qualifier)
43
+ .filter(qualifier => this.#defaultSymbols.has(qualifier));
42
44
  // If there is only one default symbol
43
45
  if (filtered.length === 1) {
44
46
  return filtered[0];
45
47
  } else if (filtered.length > 1) {
46
48
  // If dealing with sub types, prioritize exact matches
47
49
  const exact = this.getCandidateEntries(type)
48
- .map(([_, x]) => x)
49
- .filter(x => x.candidateType === type);
50
+ .map(([_, candidate]) => candidate)
51
+ .filter(candidate => candidate.candidateType === type);
50
52
 
51
53
  if (exact.length === 1) {
52
54
  return exact[0].qualifier;
package/src/types.ts CHANGED
@@ -32,7 +32,7 @@ export interface InjectableCandidate<T = unknown> {
32
32
  /**
33
33
  * Method that is injectable on class
34
34
  */
35
- method: string | symbol;
35
+ method: string;
36
36
  /**
37
37
  * Method handle
38
38
  */
@@ -74,7 +74,7 @@ export interface InjectableConfig<T = unknown> {
74
74
  /**
75
75
  * Candidates that are injectable
76
76
  */
77
- candidates: Record<string | symbol, InjectableCandidate>;
77
+ candidates: Record<string, InjectableCandidate>;
78
78
  }
79
79
 
80
80
  export function getDefaultQualifier(cls: Class): symbol {
@@ -85,5 +85,5 @@ export function getDefaultQualifier(cls: Class): symbol {
85
85
  export const PrimaryCandidateSymbol = Symbol();
86
86
 
87
87
  export type InjectableClassMetadata = {
88
- postConstruct: Record<string | symbol, (<T>(inst: T) => Promise<void>)>;
88
+ postConstruct: Record<string, (<T>(inst: T) => Promise<void>)>;
89
89
  };