@busy-hour/blaze
Version:
<h1 align='center'>🔥 Blaze</h1> <div align='center'> An event driven framework for 🔥 Hono.js </div>
202 lines (201 loc) • 5.17 kB
JavaScript
// src/router/Blaze.ts
import fs from "node:fs";
import { BlazeConfig } from "../internal/config/instance.js";
import { BlazeContext } from "../internal/context/index.js";
import { Logger } from "../internal/logger/index.js";
import { BlazeService } from "../loader/service.js";
import { useTrpc } from "../loader/trpc/index.js";
import { isNil, toArray } from "../utils/common.js";
import {
ExternalModule,
PossibleRunTime
} from "../utils/constant/config/index.js";
import { BlazeRouter } from "./BlazeRouter.js";
var Blaze = class {
$services;
router;
/**
* Shorthand for `app.router.doc`.
* It allows you to generate OpenAPI documents and serve it at the given path.
* @example
* ```ts
* app.doc('/doc', {
* openapi: '3.0.0',
* info: {
* version: '1.0.0',
* title: 'Blaze OpenAPI Example'
* }
* })
* ```
* @see {@link BlazeRouter.doc}
*/
doc;
/**
* Shorthand for `app.router.doc31`.
* It allows you to generate OpenAPI documents and serve it at the given path.
* @example
* ```ts
* app.doc31('/doc', {
* openapi: '3.1.0',
* info: {
* version: '1.0.0',
* title: 'Blaze OpenAPI Example'
* }
* })
* ```
* @see {@link BlazeRouter.doc}
*/
doc31;
/**
* Shorthand for `app.router.use`.
* It allows you to add middleware to the router
* @example
* ```ts
* app.use(cors())
* ```
* @see {@link BlazeRouter.use}
*/
use;
ctx;
adapter;
fetch;
trpc;
constructor(options = {}) {
this.$services = /* @__PURE__ */ new Map();
this.router = new BlazeRouter(options);
this.doc = this.router.doc.bind(this.router);
this.doc31 = this.router.doc31.bind(this.router);
this.ctx = new BlazeContext({
body: null,
params: null,
headers: null,
honoCtx: null,
meta: null,
query: null
});
this.adapter = BlazeConfig.modules[ExternalModule.NodeAdapter];
this.fetch = this.router.fetch.bind(this.router);
this.use = this.router.use.bind(this.router);
this.trpc = useTrpc.bind(this);
if (!options.path)
return;
this.load({
path: options.path,
autoStart: options.autoStart,
middlewares: options.middlewares
});
}
/**
* Start all the loaded services
* @example
* ```ts
* app.start()
* ```
* passing `autoStart: true` on app creation (`new Blaze({ autoStart: true })`) will also start all the services
*/
start() {
this.$services.forEach((service) => service.onStarted());
}
addServices(service) {
const services = toArray(service);
services.forEach((serv) => {
if (this.$services.has(serv.serviceName))
return;
this.$services.set(serv.serviceName, serv);
});
}
/**
* `load` all the services from the given path
* @example
* ```ts
* app.load({
* path: path.resolve(__dirname, 'services'),
* autoStart: true
* })
* ```
* `autoStart` options will start all the services when all the services are loaded
*/
async load(options) {
const { autoStart, path: sourcePath, middlewares } = options;
if (!fs.existsSync(sourcePath)) {
throw Logger.throw("Service path doesn't exist");
}
const serviceFiles = fs.readdirSync(sourcePath);
const services = await Promise.all(
serviceFiles.map((servicePath) => {
const service = BlazeService.create({
app: this.router,
servicePath,
ctx: this.ctx,
sourcePath,
middlewares: middlewares ?? []
});
return service;
})
);
this.addServices(services);
if (!autoStart)
return;
this.start();
}
/**
* Same as `load` but requires an array of services instead of a path. Recommended if you want to bundle those services with Bun
* @example
* ```ts
* app.import({
* services: [userService, authService, ...],
* autoStart: true
* })
* ```
*/
import(options) {
const services = options.services.map((serv) => {
const service = new BlazeService({
app: this.router,
ctx: this.ctx,
middlewares: options.middlewares ?? [],
service: serv,
servicePath: ""
});
return service;
});
this.addServices(services);
if (!options.autoStart)
return;
this.start();
}
/**
* List of all the loaded services
* @see {@link BlazeService}
*/
get services() {
return [...this.$services.values()];
}
getServeConfig(port, listener) {
const config = {
fetch: this.fetch,
reusePort: true,
port
};
return [config, listener];
}
serve(port, listener) {
const args = this.getServeConfig(port, listener);
if (!isNil(port)) {
if (BlazeConfig.runTime === PossibleRunTime.NODE && this.adapter) {
this.adapter.serve(...args);
}
if (isNil(listener)) {
return args[0];
}
return args;
}
if (BlazeConfig.runTime === PossibleRunTime.NODE && this.adapter) {
this.adapter.serve(...args);
}
return this.fetch;
}
};
export {
Blaze
};