Skip to content

Commit

Permalink
feat(di): add events function to emit event
Browse files Browse the repository at this point in the history
  • Loading branch information
Romakita committed Oct 8, 2024
1 parent c2a779d commit bea2874
Show file tree
Hide file tree
Showing 28 changed files with 392 additions and 266 deletions.
2 changes: 1 addition & 1 deletion packages/di/.barrelsby.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"directory": ["./src/common", "./src/node"],
"exclude": ["**/__mock__", "**/__mocks__", "**/*.spec.ts"],
"exclude": ["**/__mock__", "**/__mocks__", "**/*.spec.ts", "localsContainer.ts"],
"delete": true
}
4 changes: 1 addition & 3 deletions packages/di/src/common/decorators/autoInjectable.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import {catchError} from "@tsed/core";
import {Logger} from "@tsed/logger";
import {beforeEach} from "vitest";

Expand Down Expand Up @@ -105,9 +104,8 @@ describe("AutoInjectable", () => {
class Test {
@Inject(Logger)
logger: Logger;

private value: string;
instances?: InterfaceGroup[];
private value: string;

constructor(initialValue: string, @Inject(TOKEN_GROUPS) instances?: InterfaceGroup[]) {
this.value = initialValue;
Expand Down
8 changes: 3 additions & 5 deletions packages/di/src/common/decorators/autoInjectable.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {isArray, type Type} from "@tsed/core";

import {LocalsContainer} from "../domain/LocalsContainer.js";
import {$injector} from "../fn/injector.js";
import {injector} from "../fn/injector.js";
import type {TokenProvider} from "../interfaces/TokenProvider.js";
import {getConstructorDependencies} from "../utils/getConstructorDependencies.js";

function resolveAutoInjectableArgs(token: Type, args: unknown[]) {
const injector = $injector();
const inj = injector();
const locals = new LocalsContainer();
const deps: TokenProvider[] = getConstructorDependencies(token);
const list: any[] = [];
Expand All @@ -17,9 +17,7 @@ function resolveAutoInjectableArgs(token: Type, args: unknown[]) {
list.push(args[i]);
} else {
const value = deps[i];
const instance = isArray(value)
? injector!.getMany(value[0], locals, {parent: token})
: injector!.invoke(value, locals, {parent: token});
const instance = isArray(value) ? inj!.getMany(value[0], locals, {parent: token}) : inj!.invoke(value, locals, {parent: token});

list.push(instance);
}
Expand Down
37 changes: 19 additions & 18 deletions packages/di/src/common/decorators/inject.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {catchAsyncError} from "@tsed/core";

import {DITest} from "../../node/index.js";
import {injector} from "../fn/injector.js";
import {registerProvider} from "../registries/ProviderRegistry.js";
import {InjectorService} from "../services/InjectorService.js";
import {Inject} from "./inject.js";
Expand All @@ -19,8 +20,8 @@ describe("@Inject()", () => {
test: InjectorService;
}

const injector = new InjectorService();
const instance = await injector.invoke<Test>(Test);
const inj = injector({rebuild: true});
const instance = await inj.invoke<Test>(Test);

expect(instance).toBeInstanceOf(Test);
expect(instance.test).toBeInstanceOf(InjectorService);
Expand Down Expand Up @@ -54,12 +55,12 @@ describe("@Inject()", () => {
test: Test;
}

const injector = new InjectorService();
const inj = injector({rebuild: true});

await injector.load();
await inj.load();

const parent1 = await injector.invoke<Parent1>(Parent1);
const parent2 = await injector.invoke<Parent2>(Parent2);
const parent1 = await inj.invoke<Parent1>(Parent1);
const parent2 = await inj.invoke<Parent2>(Parent2);

expect(parent1.test).toBeInstanceOf(Test);
expect(parent2.test).toBeInstanceOf(Test);
Expand All @@ -72,8 +73,8 @@ describe("@Inject()", () => {
test: InjectorService;
}

const injector = new InjectorService();
const instance = await injector.invoke<Test>(Test);
const inj = injector({rebuild: true});
const instance = await inj.invoke<Test>(Test);

expect(instance).toBeInstanceOf(Test);
expect(instance.test).toBeInstanceOf(InjectorService);
Expand All @@ -86,8 +87,8 @@ describe("@Inject()", () => {
test: InjectorService;
}

const injector = new InjectorService();
const instance = await injector.invoke<Test>(Test);
const inj = injector({rebuild: true});
const instance = await inj.invoke<Test>(Test);

expect(instance).toBeInstanceOf(Test);
expect(instance.test).toBeInstanceOf(InjectorService);
Expand Down Expand Up @@ -136,11 +137,11 @@ describe("@Inject()", () => {
instances: InterfaceGroup[];
}

const injector = new InjectorService();
const inj = injector({rebuild: true});

await injector.load();
await inj.load();

const instance = await injector.invoke<MyInjectable>(MyInjectable);
const instance = await inj.invoke<MyInjectable>(MyInjectable);

expect(instance.instances).toBeInstanceOf(Array);
expect(instance.instances).toHaveLength(3);
Expand Down Expand Up @@ -197,8 +198,8 @@ describe("@Inject()", () => {
constructor(@Inject(InjectorService) readonly injector: InjectorService) {}
}

const injector = new InjectorService();
const instance = await injector.invoke<MyInjectable>(MyInjectable);
const inj = injector({rebuild: true});
const instance = await inj.invoke<MyInjectable>(MyInjectable);

expect(instance.injector).toBeInstanceOf(InjectorService);
});
Expand Down Expand Up @@ -248,11 +249,11 @@ describe("@Inject()", () => {
constructor(@Inject(TOKEN_GROUPS) readonly instances: InterfaceGroup[]) {}
}

const injector = new InjectorService();
const inj = injector({rebuild: true});

await injector.load();
await inj.load();

const instance = await injector.invoke<MyInjectable>(MyInjectable);
const instance = await inj.invoke<MyInjectable>(MyInjectable);

expect(instance.instances).toBeInstanceOf(Array);
expect(instance.instances).toHaveLength(3);
Expand Down
2 changes: 0 additions & 2 deletions packages/di/src/common/decorators/inject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import {DI_INJECTABLE_PROPS, DI_INVOKE_OPTIONS, DI_USE_OPTIONS} from "../constan
import {InvalidPropertyTokenError} from "../errors/InvalidPropertyTokenError.js";
import {inject} from "../fn/inject.js";
import {injectMany} from "../fn/injectMany.js";
import {$injector} from "../fn/injector.js";
import type {InvokeOptions} from "../interfaces/InvokeOptions.js";
import {TokenProvider} from "../interfaces/TokenProvider.js";
import {InjectorService} from "../services/InjectorService.js";
import {getConstructorDependencies, setConstructorDependencies} from "../utils/getConstructorDependencies.js";

function setToken(
Expand Down
4 changes: 0 additions & 4 deletions packages/di/src/common/decorators/intercept.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ import {Service} from "./service.js";

@Interceptor()
class MyInterceptor implements InterceptorMethods {
constructor(injSrv: InjectorService) {
// do some logic
}

intercept(context: InterceptorContext<any>) {
const r = typeof context.args[0] === "string" ? undefined : new Error(`Error message`);
const retValue = context.next(r);
Expand Down
30 changes: 15 additions & 15 deletions packages/di/src/common/decorators/lazyInject.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {catchAsyncError, classOf, nameOf} from "@tsed/core";

import {InjectorService} from "../services/InjectorService.js";
import {injector} from "../fn/injector.js";
import type {MyLazyModule} from "./__mock__/lazy.module.js";
import {Injectable} from "./injectable.js";
import {LazyInject, OptionalLazyInject} from "./lazyInject.js";
Expand All @@ -13,14 +13,14 @@ describe("LazyInject", () => {
lazy: Promise<MyLazyModule>;
}

const injector = new InjectorService();
const service = await injector.invoke<MyInjectable>(MyInjectable);
const nbProviders = injector.getProviders().length;
const inj = injector({rebuild: true});
const service = await inj.invoke<MyInjectable>(MyInjectable);
const nbProviders = inj.getProviders().length;

const lazyService = await service.lazy;

expect(nameOf(classOf(lazyService))).toEqual("MyLazyModule");
expect(nbProviders).not.toEqual(injector.getProviders().length);
expect(nbProviders).not.toEqual(inj.getProviders().length);
});

it("should throw an error when token isn't a valid provider", async () => {
Expand All @@ -30,8 +30,8 @@ describe("LazyInject", () => {
lazy?: Promise<MyLazyModule>;
}

const injector = new InjectorService();
const service = await injector.invoke<MyInjectable>(MyInjectable);
const inj = injector({rebuild: true});
const service = await inj.invoke<MyInjectable>(MyInjectable);
const error = await catchAsyncError(() => service.lazy);

expect(error?.message).toEqual('Unable to lazy load the "TKO". The token isn\'t a valid token provider.');
Expand All @@ -45,8 +45,8 @@ describe("LazyInject", () => {
lazy?: Promise<MyLazyModule>;
}

const injector = new InjectorService();
const service = await injector.invoke<MyInjectable>(MyInjectable);
const inj = injector({rebuild: true});
const service = await inj.invoke<MyInjectable>(MyInjectable);
const error = await catchAsyncError(() => service.lazy);

expect(error?.message).toContain("Failed to load url lazy-module");
Expand All @@ -60,8 +60,8 @@ describe("LazyInject", () => {
lazy?: Promise<MyLazyModule>;
}

const injector = new InjectorService();
const service = await injector.invoke<MyInjectable>(MyInjectable);
const inj = injector({rebuild: true});
const service = await inj.invoke<MyInjectable>(MyInjectable);
const lazyService = await service.lazy;

expect(lazyService).toEqual({});
Expand All @@ -74,13 +74,13 @@ describe("LazyInject", () => {
lazy: Promise<MyLazyModule>;
}

const injector = new InjectorService();
const service = await injector.invoke<MyInjectable>(MyInjectable);
const originalLazyInvoke = injector.lazyInvoke.bind(injector);
const inj = injector({rebuild: true});
const service = await inj.invoke<MyInjectable>(MyInjectable);
const originalLazyInvoke = inj.lazyInvoke.bind(inj);
const promise1 = service.lazy;
let promise2: Promise<MyLazyModule> | undefined;

vi.spyOn(injector, "lazyInvoke").mockImplementationOnce((token) => {
vi.spyOn(inj, "lazyInvoke").mockImplementationOnce((token) => {
promise2 = service.lazy;
return originalLazyInvoke(token);
});
Expand Down
4 changes: 2 additions & 2 deletions packages/di/src/common/decorators/lazyInject.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {catchError, importPackage} from "@tsed/core";

import {$injector} from "../fn/injector.js";
import {injector} from "../fn/injector.js";

/**
* Lazy load a provider from his package and invoke only when the provider is used
Expand Down Expand Up @@ -42,7 +42,7 @@ export function LazyInject(
}
}

bean = token ? await $injector().lazyInvoke(token) : {};
bean = token ? await injector().lazyInvoke(token) : {};
}

return bean;
Expand Down
7 changes: 4 additions & 3 deletions packages/di/src/common/decorators/value.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {DITest} from "../../node/index.js";
import {configuration} from "../fn/configuration.js";
import {Value} from "./value.js";

describe("@Value()", () => {
Expand All @@ -25,7 +26,7 @@ describe("@Value()", () => {
expect(test.test).toEqual("off");
});
it("should create a getter with default value", async () => {
expect(DITest.injector.settings.get("logger.test")).toEqual(undefined);
expect(configuration().get("logger.test")).toEqual(undefined);

// WHEN
class Test {
Expand All @@ -38,7 +39,7 @@ describe("@Value()", () => {
const test = await DITest.invoke<Test>(Test);

expect(test.test).toEqual("default value");
expect(DITest.injector.settings.get("logger.test")).toEqual(undefined);
expect(configuration().get("logger.test")).toEqual(undefined);
});
it("should create a getter with native default value", async () => {
// WHEN
Expand All @@ -52,7 +53,7 @@ describe("@Value()", () => {
const test = await DITest.invoke<Test>(Test);

expect(test.test).toEqual("default prop");
expect(DITest.injector.settings.get("logger.test")).toEqual("default prop");
expect(configuration().get("logger.test")).toEqual("default prop");
});
});
});
6 changes: 3 additions & 3 deletions packages/di/src/common/decorators/value.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {catchError} from "@tsed/core";

import {$injector} from "../fn/injector.js";
import {injector} from "../fn/injector.js";

export function bindValue(target: any, propertyKey: string | symbol, expression: string, defaultValue?: any) {
const descriptor = {
get() {
return $injector().settings.get(expression, defaultValue);
return injector().settings.get(expression, defaultValue);
},
set(value: unknown) {
$injector().settings.set(expression, value);
injector().settings.set(expression, value);
},
enumerable: true,
configurable: true
Expand Down
Loading

0 comments on commit bea2874

Please sign in to comment.