Skip to content

608 run set up scripts before loading modules #638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 15, 2025
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ The following projects focus on one particular concept at a time. The examples a
1. [Health checks](health-checks/README.md) - Demonstrates how to use health checks.
1. [Middleware](middleware/README.md) - Demonstrates how to use middleware.
1. [Cors](cors/README.md) - Demonstrates how to enable cors.
1. [Construction](construction/README.md) - Demonstrates how to use a set up and tear down scripts.
1. [Resources](resources/README.md) - Demonstrates how to use resources.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# Jitar | Construction example
# Jitar | Resources example

This example demonstrates how to construct and deconstruct a Jitar application.
This example demonstrates how to use resources in a Jitar application.

The application creates and fills a database before the server starts.
When the application gets shut down, the database gets cleared.
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "jitar-construction-example",
"name": "jitar-resources-example",
"private": true,
"type": "module",
"scripts": {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
1,370 changes: 681 additions & 689 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions packages/build/src/BuildManager.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

import type { RuntimeConfiguration } from '@jitar/configuration';
import { Logger, LogLevel } from '@jitar/logging';
import { Files, FileManager } from '@jitar/sourcing';
import { Files, LocalFileManager } from '@jitar/sourcing';

import { ApplicationReader } from './source';
import { ApplicationBuilder } from './target';
Expand All @@ -20,10 +20,10 @@ export default class BuildManager
{
this.#logger = new Logger(logLevel);

const sourceFileManager = new FileManager(configuration.source);
const targetFileManager = new FileManager(configuration.target);
const resourceFileManager = new FileManager(configuration.resources);
const segmentFileManager = new FileManager(configuration.segments);
const sourceFileManager = new LocalFileManager(configuration.source);
const targetFileManager = new LocalFileManager(configuration.target);
const resourceFileManager = new LocalFileManager(configuration.resources);
const segmentFileManager = new LocalFileManager(configuration.segments);

this.#fileManager = new ProjectFileManager(sourceFileManager, targetFileManager, resourceFileManager, segmentFileManager);

Expand Down
5 changes: 2 additions & 3 deletions packages/cli/src/commands/StartServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ConfigurationManager, RuntimeConfiguration, ServerConfiguration } from
import { HttpRemoteBuilder, HttpServer } from '@jitar/http';
import { LogLevel, LogLevelParser } from '@jitar/logging';
import { ServerBuilder } from '@jitar/runtime';
import { FileManager, SourcingManager } from '@jitar/sourcing';
import { LocalSourcingManager } from '@jitar/sourcing';

import ArgumentProcessor from '../ArgumentProcessor';
import Command from '../Command';
Expand Down Expand Up @@ -49,8 +49,7 @@ export default class StartServer implements Command
{
const [, , port] = serverConfiguration.url.split(':');

const fileManager = new FileManager(runtimeConfiguration.target);
const sourcingManager = new SourcingManager(fileManager);
const sourcingManager = new LocalSourcingManager(runtimeConfiguration.target);
const remoteBuilder = new HttpRemoteBuilder();
const serverBuilder = new ServerBuilder(sourcingManager, remoteBuilder);

Expand Down
4 changes: 2 additions & 2 deletions packages/configuration/src/ConfigurationManager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

import { Validator } from '@jitar/validation';
import { FileManager } from '@jitar/sourcing';
import { LocalFileManager } from '@jitar/sourcing';

import { EnvironmentConfigurator } from './environment';
import { RuntimeConfiguration, RuntimeConfigurationBuilder } from './runtime';
Expand All @@ -18,7 +18,7 @@ export default class ConfigurationManager

constructor(rootPath: string = DEFAULT_ROOT_PATH)
{
const fileManager = new FileManager(rootPath);
const fileManager = new LocalFileManager(rootPath);
const reader = new ConfigurationReader(fileManager);
const validator = new Validator();

Expand Down
3 changes: 2 additions & 1 deletion packages/execution/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"clean": "rm -rf dist"
},
"dependencies": {
"@jitar/errors": "*"
"@jitar/errors": "*",
"@jitar/sourcing": "*"
}
}
38 changes: 38 additions & 0 deletions packages/execution/src/ExecutionManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

import type { ModuleImporter } from '@jitar/sourcing';

import StatusCodes from './definitions/StatusCodes';
import RunModes from './definitions/RunModes';

Expand All @@ -22,10 +24,36 @@ import ErrorConverter from './utils/ErrorConverter';

export default class ExecutionManager implements Runner
{
readonly #moduleImporter: ModuleImporter;
readonly #segmentFiles: string[];

readonly #argumentConstructor: ArgumentConstructor = new ArgumentConstructor();
readonly #errorConverter: ErrorConverter = new ErrorConverter();
readonly #application: Application = new Application();

constructor(moduleImporter: ModuleImporter, segmentFiles: string[] = [])
{
this.#moduleImporter = moduleImporter;
this.#segmentFiles = segmentFiles;
}

async start(): Promise<void>
{
return this.#loadSegments();
}

async stop(): Promise<void>
{
return this.#clearSegments();
}

async loadSegment(filename: string): Promise<void>
{
const module = await this.#moduleImporter.import(filename);

this.addSegment(module.default as Segment);
}

async addSegment(segment: Segment): Promise<void>
{
if ((segment instanceof Segment) === false)
Expand Down Expand Up @@ -85,6 +113,16 @@ export default class ExecutionManager implements Runner
return this.#runImplementation(request, implementation, args);
}

async #loadSegments(): Promise<void>
{
await Promise.all(this.#segmentFiles.map(filename => this.loadSegment(filename)));
}

#clearSegments(): void
{
this.#application.clearSegments();
}

#getImplementation(fqn: string, version: Version): Implementation
{
const procedure = this.#application.getProcedure(fqn);
Expand Down
5 changes: 5 additions & 0 deletions packages/execution/src/models/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ export default class Application
this.#segments.set(segment.id, segment);
}

clearSegments(): void
{
this.#segments.clear();
}

getClassNames(): string[]
{
const names = new Set<string>();
Expand Down
33 changes: 33 additions & 0 deletions packages/health/src/HealthManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

import type { ModuleImporter } from '@jitar/sourcing';

import InvalidHealthCheck from './errors/InvalidHealthCheck';
import type HealthCheck from './interfaces/HealthCheck';

Expand All @@ -10,8 +12,34 @@ type HealthCheckResult =

export default class HealthManager
{
readonly #moduleImporter: ModuleImporter;
readonly #healthCheckFiles: string[];

readonly #healthChecks = new Map<string, HealthCheck>();

constructor(moduleImporter: ModuleImporter, healthCheckFiles: string[] = [])
{
this.#moduleImporter = moduleImporter;
this.#healthCheckFiles = healthCheckFiles;
}

async start(): Promise<void>
{
return this.#loadHealthChecks();
}

async stop(): Promise<void>
{
return this.clearHealthChecks();
}

async loadHealthCheck(filename: string): Promise<void>
{
const module = await this.#moduleImporter.import(filename);

this.addHealthCheck(module.default as HealthCheck);
}

addHealthCheck(healthCheck: HealthCheck): void
{
if (healthCheck.isHealthy === undefined)
Expand Down Expand Up @@ -63,6 +91,11 @@ export default class HealthManager
.then(() => healthChecks);
}

async #loadHealthChecks(): Promise<void>
{
await Promise.all(this.#healthCheckFiles.map(filename => this.loadHealthCheck(filename)));
}

#handleHealthCheckResult(result: PromiseSettledResult<HealthCheckResult>, healthChecks: Map<string, boolean>): void
{
if (result.status !== 'fulfilled')
Expand Down
32 changes: 32 additions & 0 deletions packages/middleware/src/MiddlewareManager.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,41 @@

import { Request, Response, StatusCodes } from '@jitar/execution';
import type { ModuleImporter } from '@jitar/sourcing';

import InvalidMiddleware from './errors/InvalidMiddleware';
import type Middleware from './interfaces/Middleware';
import type NextHandler from './types/NextHandler';

export default class MiddlewareManager
{
readonly #moduleImporter: ModuleImporter;
readonly #middlewareFiles: string[];

#middlewares: Middleware[] = [];

constructor(moduleImporter: ModuleImporter, middlewareFiles: string[] = [])
{
this.#moduleImporter = moduleImporter;
this.#middlewareFiles = middlewareFiles;
}

async start(): Promise<void>
{
return this.#loadMiddlewares();
}

async stop(): Promise<void>
{
return this.clearMiddlewares();
}

async loadMiddleware(filename:string): Promise<void>
{
const module = await this.#moduleImporter.import(filename);

this.addMiddleware(module.default as Middleware);
}

addMiddleware(middleware: Middleware): void
{
if (middleware?.handle === undefined)
Expand Down Expand Up @@ -38,6 +65,11 @@ export default class MiddlewareManager
return startHandler();
}

async #loadMiddlewares(): Promise<void>
{
await Promise.all(this.#middlewareFiles.map(filename => this.loadMiddleware(filename)));
}

#getNextHandler(request: Request, index: number): NextHandler
{
const next = this.#middlewares[index];
Expand Down
5 changes: 3 additions & 2 deletions packages/plugin-vite/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,9 @@ export default function viteJitar(pluginConfig: PluginConfig): PluginOption

const remoteBuilder = 'const remoteBuilder = new HttpRemoteBuilder();';
const clientBuilder = 'const clientBuilder = new ClientBuilder(remoteBuilder);';
const build = 'clientBuilder.build({remoteUrl, segments, middleware});';
const client = [remoteBuilder, clientBuilder, build].join('\n');
const build = 'const client = clientBuilder.build({remoteUrl, segments, middleware});';
const start = 'client.start();';
const client = [remoteBuilder, clientBuilder, build, start].join('\n');

const exports = `export * from "${JITAR_CLIENT_ID}";`;

Expand Down
28 changes: 23 additions & 5 deletions packages/runtime/src/client/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,18 @@ export default class Client extends Runtime
});

this.#middlewareManager = configuration.middlewareManager;

const procedureRunner = new ProcedureRunner(this.#worker);
this.#middlewareManager.addMiddleware(procedureRunner);
}

get worker() { return this.#worker; }

start(): Promise<void>
{
return this.#worker.start();
return this.#setUp();
}

stop(): Promise<void>
{
return this.#worker.stop();
return this.#tearDown();
}

getTrustKey(): string | undefined
Expand All @@ -64,4 +61,25 @@ export default class Client extends Runtime
{
return this.#middlewareManager.handle(request);
}

async #setUp(): Promise<void>
{
await Promise.all(
[
this.#worker.start(),
this.#middlewareManager.start()
]);

const procedureRunner = new ProcedureRunner(this.#worker);
this.#middlewareManager.addMiddleware(procedureRunner);
}

async #tearDown(): Promise<void>
{
await Promise.all(
[
this.#middlewareManager.stop(),
this.#worker.stop()
]);
}
}
17 changes: 11 additions & 6 deletions packages/runtime/src/client/ClientBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { Segment, ExecutionManager } from '@jitar/execution';
import { RemoteBuilder } from '@jitar/services';
import { Middleware, MiddlewareManager } from '@jitar/middleware';
import { RemoteSourcingManager } from '@jitar/sourcing';

import Client from './Client';

Expand All @@ -24,25 +25,29 @@ export default class ClientBuilder
build(configuration: ClientConfiguration): Client
{
const remoteUrl = configuration.remoteUrl;
const middleware = configuration.middleware;
const segments = configuration.segments;

const remote = this.#remoteBuilder.build(remoteUrl);
const middlewareManager = this.#buildMiddlewareManager(configuration.middleware ?? []);
const executionManager = this.#buildExecutionManager(configuration.segments ?? []);
const sourcingManager = new RemoteSourcingManager(remoteUrl);
const middlewareManager = this.#buildMiddlewareManager(sourcingManager, middleware);
const executionManager = this.#buildExecutionManager(sourcingManager, segments);

return new Client({ remoteUrl, remote, middlewareManager, executionManager });
}

#buildMiddlewareManager(middleware: Middleware[]): MiddlewareManager
#buildMiddlewareManager(sourcingManager: RemoteSourcingManager, middleware: Middleware[] = []): MiddlewareManager
{
const manager = new MiddlewareManager();
const manager = new MiddlewareManager(sourcingManager);

middleware.forEach(middleware => manager.addMiddleware(middleware));

return manager;
}

#buildExecutionManager(segments: Segment[]): ExecutionManager
#buildExecutionManager(sourcingManager: RemoteSourcingManager, segments: Segment[] = []): ExecutionManager
{
const manager = new ExecutionManager();
const manager = new ExecutionManager(sourcingManager);

segments.forEach(segment => manager.addSegment(segment));

Expand Down
Loading