### PostgreSQL Dialect Setup Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/data.md Example of how to create a database connection using the PostgreSQL dialect. ```APIDOC ## PostgreSQL Dialect Available from `forge/data/dialects/postgres`: ```typescript import { createDb } from "forge/data"; const db = await createDb({ dialect: "postgres", url: "postgresql://user:pass@localhost:5432/mydb", }); ``` ``` -------------------------------- ### Development Setup for Forge Source: https://github.com/infinityi-mc/forge/blob/main/README.md Clone the repository, install dependencies, build the project, and run tests. ```bash git clone https://github.com/your-org/forge.git cd forge bun install bun run build bun test ``` -------------------------------- ### SQLite Dialect Setup Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/data.md Example of how to create a database connection using the SQLite dialect. ```APIDOC ## SQLite Dialect Available from `forge/data/dialects/sqlite`: ```typescript import { createDb } from "forge/data"; const db = await createDb({ dialect: "sqlite", url: "file:./data.db", }); ``` ``` -------------------------------- ### Example: Setting Up and Managing a Message Consumer Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/messaging.md Demonstrates how to create a message consumer using in-memory transport, subscribe to a topic, define a message handler, and control its lifecycle with start() and stop(). ```typescript import { createMessageBus, createConsumer } from "forge/messaging"; import { inMemoryTransport } from "forge/messaging/transports/memory"; const transport = inMemoryTransport(); const bus = createMessageBus({ transport }); const consumer = createConsumer({ transport, topic: "order.created", handler: async (ctx) => { console.log(`Processing order`, ctx.message.payload); if (ctx.attempt > 1) { console.log(`Retry attempt ${ctx.attempt}`); } }, concurrency: 5, }); await consumer.start(); // Later... await consumer.stop(); ``` -------------------------------- ### boot Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/lifecycle.md Bootstrap the application with a given set of options. This function starts components, installs signal handlers for graceful shutdown, and optionally begins a health server. ```APIDOC ## boot(options: BootOptions): Promise ### Description Bootstrap the application. ### Signature ```typescript async function boot(options: BootOptions): Promise ``` ### Parameters #### Path Parameters - **options** (BootOptions) - Required - Configuration for the application ### Return Type `Promise` ### Behavior - Starts components in array order, failing fast with rollback if any `start()` rejects - Waits for all components to reach `ready: true` - Installs signal handlers (SIGTERM/SIGINT by default) that trigger graceful shutdown - Begins health server if configured (before components, so `/readyz` is 503 during startup) - On shutdown, stops components in strict reverse order within the timeout budget - Calls exit hook when shutdown completes ### Throws - `StartupError`: if any component's `start()` rejects - `ShutdownError`: if any component's `stop()` rejects during shutdown - `ShutdownTimeoutError`: if shutdown exceeds the timeout budget ### Example ```typescript import { forge, asComponent } from "forge/lifecycle"; import { createDb } from "forge/data"; import { serve } from "forge/http"; let server: HttpServer | undefined; const db = createDb({ /* ... */ }); const app = await forge.boot({ components: [ asComponent("db", { start: () => db.ping(), stop: () => db.shutdown(), }), asComponent("http", { start: () => { server = serve(router, { port: 3000 }); }, stop: () => server?.stop(true), }), ], shutdownTimeout: 30_000, logger: console, }); app.logger.info("Application started", { ready: app.ready }); await app.done; // Blocks until shutdown ``` ``` -------------------------------- ### HTTP Client Usage Example Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/http.md Demonstrates how to create an HTTP client with custom options, including base URL, resilience policies, and default headers, and how to perform GET and POST requests. Includes basic error handling for ProblemError. ```typescript import { createHttpClient } from "forge/http/client"; import { combine, retry, timeout, exponentialBackoff } from "forge/resilience"; const api = createHttpClient({ baseUrl: "https://api.example.com", timeoutMs: 5_000, resilience: combine( retry({ maxAttempts: 3, backoff: exponentialBackoff({ initial: 100, max: 2_000 }), }), timeout({ ms: 5_000 }), ), headers: { "Authorization": "Bearer token", }, }); // Simple GET const user = await api.get<{ id: string; name: string }>("/users/123"); console.log(user.body.name); // POST with body const created = await api.post<{ id: string }>("/posts", { title: "Hello", content: "World", }); // Error handling try { await api.delete("/posts/invalid"); } catch (e) { if (e instanceof ProblemError) { console.log(e.problem.detail); // RFC 7807 error } } ``` -------------------------------- ### ServeOptions Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/http.md Configuration options for starting the HTTP server. ```APIDOC ## ServeOptions ### Description Configuration object for the HTTP server. ### Fields - **hostname** (string) - Optional - Listen hostname. Defaults to "0.0.0.0". - **port** (number) - Optional - Listen port. Defaults to 3000. - **maxRequestBodySize** (number) - Optional - Maximum request body size in bytes. Defaults to 1048576. - **tls** (object) - Optional - TLS options for HTTPS. - **telemetry** (HttpTelemetry) - Optional - Observability handles. - **development** (boolean) - Optional - Development mode (enables helpful errors). Defaults to false. ``` -------------------------------- ### forge.boot(options) Source: https://github.com/infinityi-mc/forge/blob/main/GUIDE.md Starts components in order, provides fail-fast with rollback, and graceful shutdown capabilities. ```APIDOC ## forge.boot(options) ### Description Start components in order, fail-fast with rollback, graceful shutdown. ### Method `forge.boot(options: BootOptions): Promise` ### Parameters #### Request Body - **options** (BootOptions) - Required - Configuration for booting the application. **`BootOptions`** | Option | Type | Default | Description | |---|---|---|---| | `components` | `Component[]` | required | Ordered component list | | `shutdownTimeout` | `number` | `30_000` | Max ms for full shutdown | | `startTimeout` | `number` | = shutdownTimeout | Max ms per component start | | `preStopDelayMs` | `number` | `0` | Delay before stopping (drain) | | `installSignals` | `boolean` | `true` | Install SIGTERM/SIGINT handlers | | `logger` | `Logger` | — | Structured logger | | `telemetry` | `object` | — | Lifecycle metrics/tracing | | `clock` | `Clock` | `realClock` | Override clock for tests | | `exit` | `(code) => void` | `process.exit` | Override exit behavior | ### Request Example ```ts import { forge, asComponent } from "@infinityi/forge/lifecycle"; const app = await forge.boot({ components: [ asComponent("db", { start: () => db.ping(), stop: () => db.shutdown(), healthcheck: () => db.ping(), }), asComponent("http", { start: () => { server = serve({ router, port: 3000 }); }, stop: () => server.stop(), }), ], shutdownTimeout: 30_000, startTimeout: 15_000, preStopDelayMs: 5_000, logger, telemetry, }); // app.ready → boolean // app.stop() → trigger graceful shutdown // app.done → resolves after shutdown completes await app.done; ``` ### Response #### Success Response (Application) - **ready** (boolean) - Indicates if the application is ready. - **stop()** - Function to trigger graceful shutdown. - **done** - Promise that resolves after shutdown completes. #### Response Example ```json { "ready": true, "stop": "[Function]", "done": "[Promise]" } ``` ``` -------------------------------- ### serve Source: https://github.com/infinityi-mc/forge/blob/main/GUIDE.md Starts an HTTP server with the provided router. ```APIDOC #### `serve(options): HttpServer` ```ts const server = serve({ router, port: 3000, hostname: "0.0.0.0", }); await server.stop(); // graceful shutdown ``` ``` -------------------------------- ### Start an HTTP Server with Forge Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/http.md Use the `serve` function to start an HTTP server with a given router and optional configuration. Handles graceful shutdown on SIGTERM. ```typescript import { createRouter, serve } from "forge/http/server"; import { cors, auth, requestId, problemDetails } from "forge/http/middleware"; const router = createRouter(); router.use( requestId(), cors({ origin: "https://example.com", credentials: true, }), problemDetails(), ); router.get("/health", () => new Response("OK")); router.get("/data", auth(), async (req) => { const user = req.locals.user; return new Response(JSON.stringify({ data: user })); }); const server = serve(router, { hostname: "0.0.0.0", port: 3000, }); console.log(`Server listening on ${server.url}`); // Graceful shutdown process.on("SIGTERM", async () => { await server.stop(true); }); ``` -------------------------------- ### installSignalHandlers(options) Source: https://github.com/infinityi-mc/forge/blob/main/GUIDE.md Installs signal handlers for graceful shutdown. ```APIDOC ### Signal Handling ```ts import { installSignalHandlers } from "@infinityi/forge/lifecycle"; installSignalHandlers({ onShutdown: () => app.stop(), signals: ["SIGTERM", "SIGINT"], }); ``` ``` -------------------------------- ### serve Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/http.md Starts an HTTP server with the provided router and optional configuration. It returns an HttpServer instance that can be used for graceful shutdown. ```APIDOC ## serve(router: Router, options?: ServeOptions): HttpServer ### Description Starts an HTTP server. ### Method N/A (Function Signature) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Parameters - **router** (Router) - Required - Router with registered routes - **options** (ServeOptions) - Optional - Server configuration ### Return Type `HttpServer` ### Example ```typescript import { createRouter, serve } from "forge/http/server"; import { cors, auth, requestId, problemDetails } from "forge/http/middleware"; const router = createRouter(); router.use( requestId(), cors({ origin: "https://example.com", credentials: true, }), problemDetails(), ); router.get("/health", () => new Response("OK")); router.get("/data", auth(), async (req) => { const user = req.locals.user; return new Response(JSON.stringify({ data: user })); }); const server = serve(router, { hostname: "0.0.0.0", port: 3000, }); console.log(`Server listening on ${server.url}`); // Graceful shutdown process.on("SIGTERM", async () => { await server.stop(true); }); ``` ``` -------------------------------- ### Install Forge with Bun Source: https://github.com/infinityi-mc/forge/blob/main/README.md Use this command to add Forge to your project dependencies. ```bash bun add @infinityi/forge ``` -------------------------------- ### Example Preference Storage Source: https://github.com/infinityi-mc/forge/blob/main/src/preference/README.md Demonstrates the structure of explicit values keyed by dotted schema path in a JSON store. ```json { "appearance.theme": "dark" } ``` -------------------------------- ### Serve HTTP Requests with Options Source: https://github.com/infinityi-mc/forge/blob/main/GUIDE.md Starts an HTTP server with a specified router and port. Includes options for hostname and demonstrates how to perform a graceful shutdown. ```typescript const server = serve({ router, port: 3000, hostname: "0.0.0.0", }); await server.stop(); // graceful shutdown ``` -------------------------------- ### Quick Start: Initialize and Query SQLite Database Source: https://github.com/infinityi-mc/forge/blob/main/src/data/README.md Demonstrates how to initialize a SQLite database with a defined schema and execute a basic select query. Ensure the necessary dialect and driver are imported. ```typescript import { createDb } from "forge/data"; import { createSqliteDialect, createSqliteDriver } from "forge/data/dialects/sqlite"; interface AppDb { users: { id: number; email: string; status: "active" | "disabled"; created_at: string; }; } const db = createDb({ dialect: createSqliteDialect(), driver: createSqliteDriver(), }); const users = await db .selectFrom("users") .select(["id", "email"] as const) .where("status", "=", "active") .orderBy("created_at", "desc") .limit(10) .execute(); ``` -------------------------------- ### Create Logger Example Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/telemetry.md Demonstrates how to create a logger instance using `createLog` with a stdout exporter and resource metadata. Shows basic logging and creating a child logger. ```typescript import { createLog } from "forge/telemetry/log"; import { stdoutExporter } from "forge/telemetry/log/exporters/stdout"; const log = createLog({ exporter: stdoutExporter(), resource: { name: "order-api", version: "1.0.0" }, }); log.info("server started", { port: 3000 }); log.warn("high latency", { latencyMs: 250 }); const authLog = log.child({ module: "auth" }); authLog.error("authentication failed", { userId: "123" }); ``` -------------------------------- ### Create and Configure HTTP Router Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/http.md Demonstrates how to create a new HTTP router and register GET, POST, and DELETE routes, as well as global middleware. ```typescript import { createRouter } from "forge/http/server"; const router = createRouter(); router.get("/users/:id", async (req) => { const id = req.params.id; return new Response(JSON.stringify({ id, name: "John" }), { headers: { "Content-Type": "application/json" }, }); }); router.post("/users", async (req) => { const body = await req.json(); return new Response(JSON.stringify({ id: "123", ...body }), { status: 201, headers: { "Content-Type": "application/json" }, }); }); router.use(requestId(), accessLog(), auth()); router.delete("/users/:id", async (req) => { return new Response(null, { status: 204 }); }); ``` -------------------------------- ### Create and Use Forge Meter Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/telemetry.md Example demonstrating how to create a Meter with a stdout exporter and collect various metrics like HTTP requests and durations. ```typescript import { createMeter } from "forge/telemetry/meter"; import { stdoutExporter } from "forge/telemetry/meter/exporters/stdout"; const meter = createMeter({ exporter: stdoutExporter(), interval: 60_000, }); const httpRequests = meter.createCounter("http_requests"); const requestDuration = meter.createHistogram("http_request_duration_ms"); const activeConnections = meter.createUpDownCounter("active_connections"); httpRequests.inc({ method: "GET", status: "200" }); requestDuration.record(125, { endpoint: "/api/users" }); activeConnections.inc(); ``` -------------------------------- ### In-Memory Transport Setup Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/messaging.md Use this for testing and single-process scenarios. It requires importing `inMemoryTransport` and `createMessageBus`. ```typescript import { inMemoryTransport } from "forge/messaging/transports/memory"; const transport = inMemoryTransport(); const bus = createMessageBus({ transport }); ``` -------------------------------- ### Set up and Run Background Job Queue and Worker Source: https://github.com/infinityi-mc/forge/blob/main/GUIDE.md Demonstrates the setup for both the queue side (enqueuing jobs) and the worker side (processing jobs) using SQLite for persistence. ```typescript import { createJobQueue, createWorker, inMemoryJobStore, sqliteJobStore } from "@infinityi/forge/messaging/jobs"; // Queue side const store = sqliteJobStore({ path: "./jobs.db" }); const queue = createJobQueue({ store }); await queue.enqueue("email.send", { to: "user@example.com" }); await queue.enqueue("report.generate", { id: "r1" }, { runAt: new Date("2025-01-01") }); await queue.every("cleanup.stale", 86_400_000); // recurring daily // Worker side const worker = createWorker({ store, concurrency: 4, handlers: { "email.send": async (job) => { await sendEmail(job.payload); }, "report.generate": async (job) => { await generateReport(job.payload); }, }, deadLetter: inMemoryDeadLetterStore(), pollIntervalMs: 100, visibilityMs: 30_000, logger, }); await worker.start(); // …later await worker.stop(); ``` -------------------------------- ### Bootstrapping an Application with Forge Source: https://github.com/infinityi-mc/forge/blob/main/GUIDE.md Starts application components in order, with options for timeouts and pre-stop delays. Ensures graceful shutdown on completion. ```typescript import { forge, asComponent } from "@infinityi/forge/lifecycle"; const app = await forge.boot({ components: [ asComponent("db", { start: () => db.ping(), stop: () => db.shutdown(), healthcheck: () => db.ping(), }), asComponent("http", { start: () => { server = serve({ router, port: 3000 }); }, stop: () => server.stop(), }), ], shutdownTimeout: 30_000, startTimeout: 15_000, preStopDelayMs: 5_000, logger, telemetry, }); // app.ready → boolean // app.stop() → trigger graceful shutdown // app.done → resolves after shutdown completes await app.done; ``` -------------------------------- ### Sample Traces in Production Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/quick-reference.md Implement trace sampling in production environments to reduce overhead while still gathering performance insights. This example samples 10% of traces. ```typescript const tracer = createTrace({ exporter, sampler: () => Math.random() < 0.1, // 10% }); ``` -------------------------------- ### Example HMAC Key Store Usage Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/security.md Shows how to create an HMAC key store with a shared secret and then use it with `createJwtVerifier` for HS256 algorithm. ```typescript const keyStore = hmacKeyStore("super-secret-key"); const verifier = createJwtVerifier({ keyStore, algorithms: ["HS256"], }); ``` -------------------------------- ### Define and Use Preferences Source: https://github.com/infinityi-mc/forge/blob/main/src/preference/README.md Loads preferences asynchronously using a defined schema and store. Includes example usage of reading values and performing validated writes. ```typescript import { definePreferences, jsonFileStore, t } from "@infinityi/forge/preference"; export const prefs = await definePreferences( { appearance: { theme: t.enum(["light", "dark", "system"] as const).default("system"), fontSize: t.number.int.default(14), }, editor: { autosave: t.boolean.default(true), recentFiles: t.json().default([]), }, }, { store: jsonFileStore({ path: "./preferences.json", debounceMs: 250 }), logger: console, }, ); prefs.values.appearance.theme; // "light" | "dark" | "system" await prefs.set("appearance.theme", "dark"); await prefs.reset("appearance.fontSize"); await prefs.flush(); ``` -------------------------------- ### SELECT Query Builder Example Source: https://github.com/infinityi-mc/forge/blob/main/GUIDE.md Builds and executes a SELECT query to retrieve user IDs and names, filtered by tenant ID and ordered by name. The result is typed according to the schema. ```typescript const users = await db .selectFrom("users") .select(["id", "name"]) .where("tenant_id", "=", "t1") .orderBy("name", "asc") .limit(10) .execute(); // users.rows → Array<{ id: string; name: string }> ``` -------------------------------- ### PostgreSQL Transport Setup Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/messaging.md A scalable, distributed transport ideal for multi-server deployments. Requires `postgresTransport` and `createMessageBus`. Connection details and pool configuration are customizable. ```typescript import { postgresTransport } from "forge/messaging/transports/postgres"; const transport = await postgresTransport({ url: "postgresql://user:pass@localhost/db", pool: { min: 2, max: 10 }, }); const bus = createMessageBus({ transport }); ``` -------------------------------- ### Quick Start with Forge Lifecycle Source: https://github.com/infinityi-mc/forge/blob/main/src/lifecycle/README.md Demonstrates how to boot an application with various components like database, HTTP server, and consumer. Components are listed in dependency order and stopped in strict reverse order. Includes configuration for shutdown timeout, pre-stop delay, health checks, telemetry, and logging. ```typescript import { forge, asComponent, databaseComponent, httpServerComponent, consumerComponent, } from "forge/lifecycle"; const server = serve(router, { port: config.http.port }); const app = await forge.boot({ config, components: [ // Dependency order — stopped in strict reverse. asComponent("telemetry", { stop: () => telemetry.shutdown() }), databaseComponent("db", db), // ping on start, shutdown on stop, healthcheck consumerComponent("consumer", consumer), // stops before the db (reverse order) httpServerComponent("http", server), // stop(true) drains in-flight requests ], shutdownTimeout: 30_000, preStopDelayMs: 5_000, // let the LB notice /readyz → 503 health: { port: 9000 }, // /livez + /readyz telemetry: { meter: telemetry.meter, tracer: telemetry.tracer }, logger: telemetry.logger, }); app.logger.info("service started"); await app.done; // resolves after graceful shutdown ``` -------------------------------- ### Implementing Retry Policy with Fetch Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/resilience.md Example of combining a retry policy with exponential backoff for fetching data. This setup retries up to 5 times with specific backoff parameters. ```typescript import { combine, retry, exponentialBackoff } from "forge/resilience"; const pipeline = combine( retry({ maxAttempts: 5, backoff: exponentialBackoff({ initial: 100, max: 5_000 }), }), ); const data = await pipeline.execute(async (ctx) => { const res = await fetch(url, { signal: ctx.signal }); if (!res.ok) throw new Error(`HTTP ${res.status}`); return res.json(); }); ``` -------------------------------- ### Installing Signal Handlers for Graceful Shutdown Source: https://github.com/infinityi-mc/forge/blob/main/GUIDE.md Installs signal handlers for SIGTERM and SIGINT to trigger the application's shutdown process. ```typescript import { installSignalHandlers } from "@infinityi/forge/lifecycle"; installSignalHandlers({ onShutdown: () => app.stop(), signals: ["SIGTERM", "SIGINT"], }); ``` -------------------------------- ### Exponential Backoff Function Example Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/resilience.md Example of creating an exponential backoff strategy with custom initial delay, maximum delay, and multiplier. ```typescript exponentialBackoff({ initial: 100, max: 10_000, multiplier: 2 }) ``` -------------------------------- ### Example JWT Claim Mapping Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/security.md An example demonstrating how to map JWT claims to Principal fields, including a nested claim for roles. ```typescript const mapping: ClaimMapping = { id: "sub", // Use 'sub' claim as principal ID roles: "realm_access.roles", // Nested claim path tenantId: "org_id", }; ``` -------------------------------- ### Install Signal Handlers - TypeScript Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/lifecycle.md Install process signal handlers to enable graceful shutdown. This function takes SignalHandlerOptions and returns void. ```typescript function installSignalHandlers(options: SignalHandlerOptions): void ``` -------------------------------- ### Start Health Server - TypeScript Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/lifecycle.md Use this function to start a standalone health check server on its own port. It returns a Promise that resolves to the HealthServer instance. ```typescript async function startHealthServer(options: HealthServerOptions): Promise ``` -------------------------------- ### Start Standalone Health Server Source: https://github.com/infinityi-mc/forge/blob/main/src/lifecycle/README.md Starts a standalone HTTP server for health probes on a specified port. This is useful for Kubernetes or other orchestrators to monitor application health. ```typescript import { createProbe, startHealthServer, } from "@/lifecycle/health"; const probe = createProbe({ checks: [], ready: true, live: true, }); const server = startHealthServer(probe, { port: 9000, }); console.log(`Health server started on port ${server.port}`); // To stop the server later: // server.stop(); ``` -------------------------------- ### Installing Signal Handlers Source: https://github.com/infinityi-mc/forge/blob/main/src/lifecycle/README.md Installs signal handlers for SIGTERM and SIGINT to manage application shutdown. This function is idempotent and includes a double-signal escape hatch for immediate exit. ```typescript import { installSignalHandlers } from "forge/lifecycle/signals"; // Example usage within a larger application setup const disposer = installSignalHandlers(); // To remove listeners (e.g., in tests): // disposer(); ``` -------------------------------- ### Create Tracer Example Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/telemetry.md Demonstrates how to create a tracer using `createTrace` with a `stdoutExporter` and a resource name. Shows manual span creation and management with `startSpan`, including error handling and explicit `end()`. Also illustrates the convenience of `startActiveSpan` for automatic span lifecycle management. ```typescript import { createTrace } from "forge/telemetry/trace"; import { stdoutExporter } from "forge/telemetry/trace/exporters/stdout"; const tracer = createTrace({ exporter: stdoutExporter(), resource: { name: "order-api" }, }); const span = tracer.startSpan("process_order", { orderId: "123" }); try { // Do work span.setStatus("ok"); } catch (e) { span.setStatus("error", e.message); throw; } finally { span.end(); } // Or with auto-cleanup: await tracer.startActiveSpan("fetch_user", async (span) => { const user = await fetchUser("123"); span.setAttribute("user.id", user.id); return user; }); ``` -------------------------------- ### Bootstrap Application with Components Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/lifecycle.md Use `forge.boot` to start your application with a list of components. It handles startup order, graceful shutdown, and signal handling. Configure `shutdownTimeout` and `logger` as needed. The `app.done` promise resolves when shutdown is complete. ```typescript import { forge, asComponent } from "forge/lifecycle"; import { createDb } from "forge/data"; import { serve } from "forge/http"; let server: HttpServer | undefined; const db = createDb({ /* ... */ }); const app = await forge.boot({ components: [ asComponent("db", { start: () => db.ping(), stop: () => db.shutdown(), }), asComponent("http", { start: () => { server = serve(router, { port: 3000 }); }, stop: () => server?.stop(true), }), ], shutdownTimeout: 30_000, logger: console, }); app.logger.info("Application started", { ready: app.ready }); await app.done; // Blocks until shutdown ``` -------------------------------- ### Initialize a Forge Server Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/README.md Boots up a Forge server with configured components like database, HTTP server, and telemetry. Ensure necessary modules are imported and configuration is defined. ```typescript import { forge, asComponent } from "forge/lifecycle"; import { defineConfig, t } from "forge/config"; import { initTelemetry } from "forge/telemetry"; import { createDb } from "forge/data"; import { createRouter, serve } from "forge/http"; const config = defineConfig({ app: { port: t.port.default(3000) }, db: { url: t.url.required() }, }); const telemetry = await initTelemetry({ resource: { name: "api", version: "1.0.0" }, }); const db = await createDb({ dialect: "postgres", url: config.db.url }); const router = createRouter(); const app = await forge.boot({ components: [ asComponent("db", { start: () => db.ping(), stop: () => db.close(), }), asComponent("http", { start: () => serve(router, { port: config.app.port }), stop: () => { /* cleanup */ }, }), ], logger: telemetry.logger, }); ``` -------------------------------- ### GET /openapi.json Source: https://github.com/infinityi-mc/forge/blob/main/src/http/README.md Serves the OpenAPI 3.1 specification for the API in JSON format. ```APIDOC ## GET /openapi.json ### Description Serves the OpenAPI 3.1 specification for the API. ### Method GET ### Endpoint /openapi.json ### Response #### Success Response (200) - **body** (object) - The OpenAPI 3.1 specification document. ``` -------------------------------- ### staticKeyStore Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/security.md Creates a KeyStore with statically provided keys. ```APIDOC ## staticKeyStore(keys: Record): KeyStore ### Description Create a key store with static keys. ### Parameters #### Path Parameters - **keys** (Record) - Required - An object mapping key IDs to JsonWebKey objects. ``` -------------------------------- ### MessageConsumer Interface Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/messaging.md The MessageConsumer interface defines the methods for starting, stopping, and checking the status of a message consumer. ```APIDOC ## MessageConsumer Interface ### Description Defines the methods for starting, stopping, and checking the status of a message consumer. ### Methods #### start ##### Signature `() => Promise` ##### Description Begin consuming messages from the configured source. #### stop ##### Signature `() => Promise` ##### Description Stop consuming messages and release any associated resources. #### isRunning ##### Signature `() => boolean` ##### Description Check if the message consumer is currently running and actively processing messages. ``` -------------------------------- ### Example: Create and Use JWT Verifier Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/security.md Demonstrates creating a JWT verifier using JWKS and verifying a token. Includes importing necessary functions and configuring issuer, audience, algorithms, and claim mapping. ```typescript import { createJwtVerifier, createJwksKeyStore } from "forge/security/jwt"; const verifier = createJwtVerifier({ keyStore: createJwksKeyStore({ endpoint: "https://auth.example.com/.well-known/jwks.json", }), issuer: "https://auth.example.com", audience: "my-api", algorithms: ["RS256"], claimMapping: { id: "sub", roles: "realm_access.roles", }, }); // Verify a token const principal = await verifier.verify("eyJhbGc..."); console.log(principal.id, principal.roles); ``` -------------------------------- ### MessageConsumer Interface Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/messaging.md Defines the consumer interface for starting, stopping, and checking the running status of message consumption. ```typescript interface MessageConsumer { start(): Promise; stop(): Promise; isRunning(): boolean; } ``` -------------------------------- ### Generate and Serve OpenAPI Documentation Source: https://github.com/infinityi-mc/forge/blob/main/GUIDE.md Use `buildOpenApi` to generate OpenAPI specs from your router and `serveOpenApi` to serve them as middleware. Includes standard problem schema. ```typescript import { buildOpenApi, serveOpenApi, problemSchema } from "@infinityi/forge/http"; const doc = buildOpenApi(router, { info: { title: "My API", version: "1.0.0" }, servers: [{ url: "https://api.example.com" }], }); // Serve as middleware (GET /openapi.json) router.use(serveOpenApi(router, { info: { title: "My API", version: "1.0.0" }, path: "/openapi.json", })); // Standard problem schema for error responses const errSchema = problemSchema(); // RFC 7807 JSON Schema ``` -------------------------------- ### Stdout Exporter Usage Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/telemetry.md Example of configuring a logger to use the stdout exporter, which writes logs to the console as JSON. ```typescript import { stdoutExporter } from "forge/telemetry/log/exporters/stdout"; const log = createLog({ exporter: stdoutExporter(), }); ``` -------------------------------- ### Testing Telemetry Setup Source: https://github.com/infinityi-mc/forge/blob/main/src/telemetry/README.md Use createTestTelemetry and recording exporters for end-to-end testing of telemetry configurations and BYO exporters. ```typescript import { createTestTelemetry } from "@/telemetry/testing"; import { recordingMeterExporter } from "@/telemetry/meter/testing"; import { recordingSpanExporter } from "@/telemetry/trace/testing"; const { telemetry } = await createTestTelemetry({ resource: { name: "test-service" }, // Use recording exporters to capture telemetry data logExporter: null, // Default recording log exporter meterExporter: recordingMeterExporter(), traceExporter: recordingSpanExporter(), }); // Now you can assert on the recorded logs, metrics, and traces // For example: // expect(recordingSpanExporter.spans).toHaveLength(1); // expect(recordingMeterExporter.metrics).toEqual(...); ``` -------------------------------- ### Define Backoff Strategies Source: https://github.com/infinityi-mc/forge/blob/main/GUIDE.md Provides examples of different backoff strategies for implementing delays between retries: exponential, linear, and constant. ```typescript exponentialBackoff({ initial: 100, max: 10_000, factor: 2 }); linearBackoff({ initial: 100, increment: 200 }); constantBackoff(500); ``` -------------------------------- ### Define Static Configuration with defineConfig Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/config.md Use `defineConfig` to set up and validate application configuration at startup. It reads from environment variables, .env files, and CLI arguments by default, failing fast if required values are missing. The returned configuration object is deeply frozen. ```typescript import { defineConfig, t } from "forge/config"; const config = defineConfig({ app: { name: t.string.default("my-app"), env: t.enum(["development", "production"]).required(), debug: t.boolean.default(false), }, http: { port: t.port.default(3000), host: t.string.default("0.0.0.0"), }, database: { url: t.url.required(), }, auth: { jwtSecret: t.secret.required(), tokenExpiry: t.number.default(3600), }, }); console.log(config.http.port); // number console.log(config.app.env); // "development" | "production" const secret = config.auth.jwtSecret.reveal(); // string ``` -------------------------------- ### Structural Typing Example Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/README.md Demonstrates structural typing where an object is accepted if it has the required properties, without explicit interface implementation. ```typescript const myComponent = { name: "my-service", start: () => { /* ... */ }, stop: () => { /* ... */ }, }; const app = await forge.boot({ components: [myComponent] }); ``` -------------------------------- ### Initialize PostgreSQL Database Connection Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/data.md Establish a database connection for PostgreSQL using `createDb`. Set the dialect to 'postgres' and provide the connection URL, including user, password, host, port, and database name. ```typescript import { createDb } from "forge/data"; const db = await createDb({ dialect: "postgres", url: "postgresql://user:pass@localhost:5432/mydb", }); ``` -------------------------------- ### startHealthServer Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/lifecycle.md Starts a standalone health check server on its own port. This function is essential for monitoring the application's health externally. ```APIDOC ## startHealthServer(options: HealthServerOptions): Promise ### Description Start a standalone health check server on its own port. ### Signature ```typescript async function startHealthServer(options: HealthServerOptions): Promise ``` ``` -------------------------------- ### Configure HTTP Server with Rate Limiting and Problem Details Source: https://github.com/infinityi-mc/forge/blob/main/src/resilience/README.md Shows how to set up an HTTP server router with rate limiting and problem details middleware using `createRouter`, `problemDetails`, and `rateLimit` from `forge/http/server` and `forge/http/middleware`. ```typescript import { problemDetails, rateLimit } from "forge/http/middleware"; import { createRouter } from "forge/http/server"; import { combine, rateLimit as resilienceRateLimit } from "forge/resilience"; const limiter = combine(resilienceRateLimit({ algorithm: { kind: "sliding-window", limit: 100, windowMs: 60_000 }, })); const router = createRouter() .use(problemDetails()) .use(rateLimit({ limiter })); ``` -------------------------------- ### Create a meter with stdout exporter and record metrics Source: https://github.com/infinityi-mc/forge/blob/main/src/telemetry/README.md Initialize a meter with a service name, stdout exporter, and export interval. Demonstrates creating and adding values to Counter, UpDownCounter, Gauge, and Histogram instruments. ```typescript import { createMeter } from "forge/telemetry/meter"; import { stdoutMeterExporter } from "forge/telemetry/meter/exporters/stdout"; const meter = createMeter({ resource: { serviceName: "api" }, exporter: stdoutMeterExporter(), intervalMs: 10_000, // export every 10s; 0 disables the timer }); const requests = meter.createCounter("http.requests", { unit: "1" }); requests.add(1, { method: "GET", path: "/health" }); const inflight = meter.createUpDownCounter("http.inflight"); inflight.add(1); // … later … inflight.add(-1); const memBytes = meter.createGauge("process.memory.heap", { unit: "By" }); memBytes.record(process.memoryUsage().heapUsed); const latency = meter.createHistogram("http.duration", { unit: "ms" }); latency.record(42, { method: "POST", path: "/orders" }); // At shutdown: await meter.shutdown(); ``` -------------------------------- ### installSignalHandlers Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/lifecycle.md Installs process signal handlers to trigger a graceful shutdown of the application. This ensures that resources are cleaned up properly when the application is terminated. ```APIDOC ## installSignalHandlers(options: SignalHandlerOptions): void ### Description Install process signal handlers that trigger graceful shutdown. ### Signature ```typescript function installSignalHandlers(options: SignalHandlerOptions): void ``` ``` -------------------------------- ### Create and Use a Resource Pool Source: https://github.com/infinityi-mc/forge/blob/main/GUIDE.md Demonstrates creating a generic async resource pool with options for creation, destruction, validation, and timeouts. Acquired resources must be released. ```typescript import { createPool } from "@infinityi/forge/data"; const pool = createPool({ name: "pg", max: 10, min: 2, create: () => createConnection(), destroy: (conn) => conn.close(), validate: (conn) => conn.isAlive(), acquireTimeoutMs: 5_000, }); const lease = await pool.acquire(); try { await doWork(lease.resource); } finally { lease.release(); } pool.stats(); // { total, idle, active, waiters } await pool.drain(); ``` -------------------------------- ### SQLite Transport Setup Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/messaging.md A durable, embedded transport suitable for single-server applications. Requires `sqliteTransport` and `createMessageBus`. The database URL is configurable. ```typescript import { sqliteTransport } from "forge/messaging/transports/sqlite"; const transport = await sqliteTransport({ url: "file:./messaging.db", }); const bus = createMessageBus({ transport }); ``` -------------------------------- ### Create and Use an API Key Verifier Source: https://github.com/infinityi-mc/forge/blob/main/GUIDE.md Set up an API key verifier with a `lookup` function that retrieves API key details from a database. This involves generating an API key, fingerprinting it for storage, and then using the verifier to authenticate requests. ```typescript import { createApiKeyVerifier, generateApiKey, apiKeyFingerprint } from "@infinityi/forge/security"; // Generate a key const key = generateApiKey(); // "forge_..." // Fingerprint (for storage / lookup) const fp = await apiKeyFingerprint(key); // SHA-256 hash // Verify const verifier = createApiKeyVerifier({ lookup: async (fingerprint) => { const record = await db.findApiKey(fingerprint); if (!record) return null; return { principal: { subject: record.userId, roles: record.roles, scopes: [], issuer: "api-key" }, policy: { rateLimit: 1000 }, }; }, }); const principal = await verifier.verify(key); ``` -------------------------------- ### defineConfig Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/config.md Defines and validates static configuration at startup. It reads from environment variables, .env files, and CLI arguments by default, failing fast if required values are missing. The returned configuration object is deeply frozen. ```APIDOC ## defineConfig(schema: ConfigSchema, options?: DefineConfigOptions): Config ### Description Define and validate configuration at startup. ### Signature ```typescript function defineConfig(schema: S, options?: DefineConfigOptions): Infer ``` ### Parameters #### schema - **schema** (ConfigSchema) - Required - Nested schema object using `t` builder #### options - **options** (DefineConfigOptions) - Optional - Additional configuration sources and behavior ### Return Type Typed configuration object (inferred from schema) ### Behavior - Validates all values against the schema - Reads from environment variables, `.env` file, and CLI args (by default) - Fails fast with a diagnostic table if any required value is missing - Returns a deeply-frozen object (no mutations) ### Throws - `ConfigValidationError` — If any value fails schema validation - `ConfigError` — If sources are unavailable or configuration is invalid ### Example ```typescript import { defineConfig, t } from "forge/config"; const config = defineConfig({ app: { name: t.string.default("my-app"), env: t.enum(["development", "production"]).required(), debug: t.boolean.default(false), }, http: { port: t.port.default(3000), host: t.string.default("0.0.0.0"), }, database: { url: t.url.required(), }, auth: { jwtSecret: t.secret.required(), tokenExpiry: t.number.default(3600), }, }); console.log(config.http.port); // number console.log(config.app.env); // "development" | "production" const secret = config.auth.jwtSecret.reveal(); // string ``` ``` -------------------------------- ### Structural Typing Example Source: https://github.com/infinityi-mc/forge/blob/main/_autodocs/types-reference.md Demonstrates structural typing where an object conforming to the required properties is accepted as a Component type without explicit implementation. ```typescript const myComponent: Component = { name: "my-service", start: () => console.log("started"), stop: () => console.log("stopped") }; ``` -------------------------------- ### Basic HTTP Server Setup with Middleware Source: https://github.com/infinityi-mc/forge/blob/main/src/http/README.md Sets up an HTTP server using Forge's router and applies several middleware functions for request processing, logging, and error handling. The server listens on port 3000 and can be stopped gracefully. ```typescript import { createRouter, serve } from "forge/http/server"; import { requestId, accessLog, problemDetails, cors, bodyLimit, telemetryMiddleware, } from "forge/http/middleware"; const router = createRouter() .use(requestId()) .use(telemetryMiddleware({ telemetry })) // server span + http.server.* metrics .use(problemDetails({ logger })) // every error below → RFC 7807 .use(cors({ origin: "*" })) .use(bodyLimit({ maxBytes: 1_000_000 })) .get("/orders/:id", (req) => Response.json({ id: req.params.id })) .post("/orders", async (req) => Response.json(await req.json(), { status: 201 })); const server = serve(router, { port: 3000 }); // … later, drain in-flight requests: await server.stop(); ``` -------------------------------- ### Start a New Trace with Root Context Source: https://github.com/infinityi-mc/forge/blob/main/src/telemetry/README.md Initiates a new trace by wrapping an asynchronous operation with `withRootContext`. Useful at request entry points. ```typescript import { withRootContext, withContext, currentContext, extract, inject, objectCarrier, } from "forge/telemetry/context"; // At request entry — start a brand-new trace. await withRootContext({ baggage: { tenantId: req.tenantId } }, () => handler(req)); ``` -------------------------------- ### Create a tracer with stdout exporter and use withSpan Source: https://github.com/infinityi-mc/forge/blob/main/src/telemetry/README.md Initialize a tracer with a service name, a parent-based sampler, and a simple span processor that exports to stdout. Demonstrates creating and managing a span using `withSpan`. ```typescript import { createTracer, simpleSpanProcessor, parentBasedSampler, ratioSampler, } from "forge/telemetry/trace"; import { stdoutSpanExporter } from "forge/telemetry/trace/exporters/stdout"; const tracer = createTracer({ resource: { serviceName: "api" }, sampler: parentBasedSampler({ root: ratioSampler({ rate: 0.1 }) }), processor: simpleSpanProcessor({ exporter: stdoutSpanExporter() }), }); await tracer.withSpan("checkout", async (span) => { span.setAttribute("user.id", userId); await charge(); span.setStatus({ code: "ok" }); }); ```