Skip to content

Commit

Permalink
feat(Container): ✨ add support fluentBind (#211)
Browse files Browse the repository at this point in the history
* feat(Container): ✨ add support fluentBind

* feat: ✨ remove unused dev dependencies
  • Loading branch information
ODGodinho authored Dec 6, 2024
1 parent 844aa07 commit 65ed8ec
Show file tree
Hide file tree
Showing 17 changed files with 62 additions and 117 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"Google",
"Tests",
"Upgrade",
"Config"
"Config",
"Container"
],
"typescript.preferences.importModuleSpecifier": "non-relative",
"vitest.commandLine": "yarn test:watch",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"@odg/message": "*",
"dotenv": "^16.4.5",
"inversify": "^6.1.4",
"inversify-binding-decorators": "^4.0.0",
"playwright": "^1.49.0",
"playwright-core": "^1.49.0",
"reflect-metadata": "^0.2.2",
Expand Down
5 changes: 3 additions & 2 deletions src/Console/Kernel.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { randomUUID } from "node:crypto";

import { LoggerInterface } from "@odg/log";
import { inject, injectable } from "inversify";
import { inject } from "inversify";
import { fluentProvide } from "inversify-binding-decorators";
import { chromium } from "playwright-core";

import { ContainerInterface } from "#types";
Expand All @@ -15,7 +16,7 @@ import { ProcessKernel } from "~/Console/ProcessKernel";
*
* @class Kernel
*/
@injectable()
@(fluentProvide(ContainerName.Kernel).inSingletonScope().done())
export class Kernel {

public constructor(
Expand Down
5 changes: 3 additions & 2 deletions src/Console/ProcessKernel.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { inject, injectable } from "inversify";
import { inject } from "inversify";
import { fluentProvide } from "inversify-binding-decorators";

import Container from "@app/Container";
import { ContainerName } from "@enums";

@injectable()
@(fluentProvide(ContainerName.ProcessKernel).inSingletonScope().done())
export class ProcessKernel {

public constructor(
Expand Down
6 changes: 3 additions & 3 deletions src/Handlers/GoogleSearch/GoogleSearchHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import {
type HandlerFunction,
HandlerSolution,
RetryAction,
ContainerHelper,
} from "@odg/chemical-x";
import { type Exception } from "@odg/exception";
import { injectable } from "inversify";

import { ConfigName, EventName } from "@enums";
import { ConfigName, ContainerName, EventName } from "@enums";
import { BaseHandler } from "@handlers/BaseHandler";

@injectable()
@ContainerHelper.injectablePage(ContainerName.SearchHandlerFactory)
export class GoogleSearchToSelectionHandler extends BaseHandler implements HandlerInterface {

public async waitForHandler(): Promise<HandlerFunction> {
Expand Down
5 changes: 0 additions & 5 deletions src/Interfaces/BasePageInterface.ts

This file was deleted.

1 change: 1 addition & 0 deletions src/Interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export interface Example {}
3 changes: 1 addition & 2 deletions src/Pages/BasePage.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { BasePage as ChemicalBasePage } from "@odg/chemical-x";
import { ConfigInterface } from "@odg/config";
import { type LoggerInterface } from "@odg/log";
import { inject, injectable } from "inversify";
import { inject } from "inversify";

import { type ConfigType } from "@configs";
import { type PageClassEngine } from "@engine";
import { ContainerName } from "@enums";
import * as Selectors from "@selectors";

@injectable()
export abstract class BasePage extends ChemicalBasePage<typeof Selectors, PageClassEngine> {

@inject(ContainerName.Logger)
Expand Down
7 changes: 3 additions & 4 deletions src/Pages/Google/SearchPage.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import crypto from "node:crypto";

import { type PageInterface } from "@odg/chemical-x";
import { injectable } from "inversify";
import { ContainerHelper, type PageInterface } from "@odg/chemical-x";

import { ConfigName } from "@app/Enums";
import { ConfigName, ContainerName } from "@app/Enums";
import { BasePage } from "@pages/BasePage";
import {
type GoogleSearchSelectorType,
googleSearchSelector,
} from "@selectors";

@injectable()
@ContainerHelper.injectablePage(ContainerName.SearchPageFactory)
export class SearchPage extends BasePage implements PageInterface {

public readonly $s: GoogleSearchSelectorType = googleSearchSelector;
Expand Down
83 changes: 11 additions & 72 deletions src/app/Container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import {
type CreateContextFactoryType,
type CreatePageFactoryType,
BrowserManager,
type HandlerInterface,
type PageInterface,
type ContextChemicalXInterface,
ContainerHelper,
} from "@odg/chemical-x";
import { JsonConfig } from "@odg/config";
import { EventEmitterBus } from "@odg/events";
Expand All @@ -14,43 +13,42 @@ import { ConsoleLogger, Logger } from "@odg/log";
import {
Container as ContainerInversify, decorate, injectable, type interfaces,
} from "inversify";
import { buildProviderModule } from "inversify-binding-decorators";

import { type ContainerNameType, type ContainerType, type EventTypes } from "#types";
import { type ConfigType, configValidator } from "@configs";
import { ConfigName, ContainerName } from "@enums";
import { type PageOrHandlerFactoryType } from "@factory";
import { GoogleSearchToSelectionHandler } from "@handlers/GoogleSearch/GoogleSearchHandler";
import { type BasePageInterface } from "@interfaces/BasePageInterface";
import { SearchEventListener } from "@listeners/SearchEventListener";
import { SearchPage } from "@pages/Google/SearchPage";
import { EventServiceProvider } from "@providers/EventServiceProvider";
import { ExampleCrawlerService } from "@services/ExampleCrawlerService";

import { Browser, Context, Page } from "../Browser";
import { Kernel, ProcessKernel } from "../Console";
import {
type BrowserClassEngine,
type ContextClassEngine,
type PageClassEngine,
} from "../engine";

import "../Console";
import "@listeners";
import "@handlers";
import "@pages";
import "@providers";
import "@services";

export default class Container {

public readonly container: ContainerInversify;

private pageContainerNumber = 0;

public constructor() {
this.container = new ContainerInversify({ skipBaseClassChecks: true });
}

public async setUp(): Promise<void> {
await this.prepareInjectable();
this.container.load(buildProviderModule());
this.container.load(ContainerHelper.loadModule(this.container));
await this.bindCrawler();
await this.bindKernel();
await this.initBeginKernel();
await this.bindStanley();
await this.bindEventsAndListeners();
}

/**
Expand Down Expand Up @@ -150,25 +148,10 @@ export default class Container {
ContainerName.ConsoleLogger,
).to(ConsoleLogger).inSingletonScope();

// Event Provider
this.bind(
ContainerName.EventServiceProvider,
).to(EventServiceProvider).inSingletonScope();

// Container instance
this.bind(
ContainerName.Container,
).toDynamicValue(() => this).inSingletonScope();

// Kernel Inject Service
this.bind(
ContainerName.ProcessKernel,
).to(ProcessKernel).inSingletonScope();

// Kernel Inject Service
this.bind(
ContainerName.Kernel,
).to(Kernel).inSingletonScope();
}

/**
Expand All @@ -185,27 +168,15 @@ export default class Container {
ContainerName.Requester,
).to(AxiosMessage).inSingletonScope();

// Example Service
this.bind(
ContainerName.ExampleCrawlerService,
).to(ExampleCrawlerService).inSingletonScope();

const appName = await this.get(ContainerName.Config).get(ConfigName.APP_NAME);
this.bind(
ContainerName.JSONLogger,
).toDynamicValue(() => new JSONLoggerPlugin(appName ?? "unknown")).inSingletonScope();
}

private async bindEventsAndListeners(): Promise<void> {
// EventBus Interface
this.bind(
ContainerName.EventBus,
).to(EventEmitterBus<EventTypes>).inSingletonScope();

// SearchGoogle Listeners bind
this.bind(
ContainerName.SearchEventListeners,
).to(SearchEventListener).inSingletonScope();
}

private async bindCrawler(): Promise<void> {
Expand All @@ -227,38 +198,6 @@ export default class Container {
pageEngine: PageClassEngine,
) => new Page(context, pageEngine),
));

// SearchPage Google
this.bind(ContainerName.SearchPageFactory)
.toFactory(() => this.instancePageOrHandler<SearchPage>(SearchPage));

// SearchHandler Google
this.bind(ContainerName.SearchHandlerFactory)
.toFactory(() => this.instancePageOrHandler<GoogleSearchToSelectionHandler>(
GoogleSearchToSelectionHandler,
));
}

/**
* Use To instance a page and handler Crawler
*
* @template {PageInterface} PageType
* @memberof Container
* @param {BasePageInterface} BasePagePrepare Page Class instantiable
* @returns {PageOrHandlerFactoryType<PageType>}
*/
private instancePageOrHandler<PageType extends HandlerInterface | PageInterface>(
BasePagePrepare: BasePageInterface,
): PageOrHandlerFactoryType<PageType> {
return (page: PageClassEngine): PageType => {
const container = `PageOrHandler${this.pageContainerNumber++}`;
this.container.bind(container).to(BasePagePrepare);
const value = this.container.get<PageType>(container);
this.container.unbind(container);
(value as unknown as { page: unknown }).page = page;

return value;
};
}

}
5 changes: 3 additions & 2 deletions src/app/Listeners/SearchEventListener.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { type EventListenerInterface } from "@odg/events";
import { LoggerInterface } from "@odg/log";
import { inject, injectable } from "inversify";
import { inject } from "inversify";
import { fluentProvide } from "inversify-binding-decorators";

import { type EventBrowserParameters, type EventTypes } from "#types/EventsInterface";
import { ContainerName, type EventName } from "@enums";
import { PageOrHandlerFactoryType } from "@factory";
import { type SearchPage } from "@pages/Google/SearchPage";

@injectable()
@(fluentProvide(ContainerName.SearchEventListeners).inSingletonScope().done())
export class SearchEventListener implements EventListenerInterface<EventTypes, EventName.SearchPageEvent> {

public constructor(
Expand Down
5 changes: 3 additions & 2 deletions src/app/Provider/EventServiceProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import {
type EventListener,
} from "@odg/events";
import {
inject, injectable,
inject,
} from "inversify";
import { fluentProvide } from "inversify-binding-decorators";

import { type EventTypes } from "#types/EventsInterface";
import { ContainerName, EventName } from "@enums";
Expand All @@ -17,7 +18,7 @@ import Container from "../Container";
*
* @template {EventTypes} Events Events List
*/
@injectable()
@(fluentProvide(ContainerName.EventServiceProvider).inSingletonScope().done())
export class EventServiceProvider<Events extends EventTypes> extends EventServiceProviderBase<Events> {

/**
Expand Down
1 change: 1 addition & 0 deletions src/app/Provider/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./EventServiceProvider";
5 changes: 3 additions & 2 deletions src/app/Services/ExampleCrawlerService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { EventBusInterface } from "@odg/events";
import { LoggerInterface } from "@odg/log";
import { inject, injectable } from "inversify";
import { inject } from "inversify";
import { fluentProvide } from "inversify-binding-decorators";

import { type EventTypes } from "#types/EventsInterface";
import { MyBrowser } from "@engine";
Expand All @@ -9,7 +10,7 @@ import { ContainerName, EventName } from "@enums";
import { type GoogleSearchToSelectionHandler } from "../../Handlers/GoogleSearch/GoogleSearchHandler";
import { PageOrHandlerFactoryType } from "../Factory";

@injectable()
@(fluentProvide(ContainerName.ExampleCrawlerService).inSingletonScope().done())
export class ExampleCrawlerService {

public constructor(
Expand Down
1 change: 1 addition & 0 deletions src/app/Services/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./ExampleCrawlerService";
2 changes: 1 addition & 1 deletion tests/vitest/Containers/ContainerDynamic.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as Engine from "@engine";
import { ContainerName } from "@enums";
import * as Factory from "@factory";
import * as BasePageInterface from "@interfaces/BasePageInterface";
import * as BasePageInterface from "@interfaces";

import { container } from "../SingletonTest";

Expand Down
Loading

0 comments on commit 65ed8ec

Please sign in to comment.