server/app_server.ts

Server assembly factory.

Consumers provide a pre-initialized AppBackend and options (session, origins, routes); create_app_server() handles middleware, bootstrap status, surface generation, and Hono app assembly.

Declarations
#

6 declarations

view source

AppServer
#

server/app_server.ts view source

AppServer

Result of create_app_server().

app

type Hono

surface_spec

Surface spec — serializable surface + raw specs that produced it.

bootstrap_status

app_settings

Global app settings (mutable ref — mutated by settings admin route).

migration_results

Migration results from create_app_backend (auth + any migration_namespaces passed there).

type ReadonlyArray<MigrationResult>

audit_sse

Factory-managed audit log SSE. null when audit_log_sse option is not set.

type AuditLogSse | null

close

Close the database connection. Propagated from AppBackend.

type () => Promise<void>

AppServerContext
#

server/app_server.ts view source

AppServerContext

Context passed to create_route_specs.

deps

type AppDeps

backend

bootstrap_status

session_options

type SessionOptions<string>

ip_rate_limiter

Shared IP rate limiter (from options). null when not configured.

type RateLimiter | null

login_account_rate_limiter

Per-account login rate limiter (from options). null when not configured.

type RateLimiter | null

signup_account_rate_limiter

Per-account signup rate limiter (from options). null when not configured.

type RateLimiter | null

action_ip_rate_limiter

Per-IP action-dispatcher rate limiter — shared across HTTP RPC + WS. null when not configured.

type RateLimiter | null

action_account_rate_limiter

Per-actor action-dispatcher rate limiter — shared across HTTP RPC + WS. null when not configured.

type RateLimiter | null

app_settings

Global app settings (mutable ref — mutated by settings admin route).

audit_sse

Factory-managed audit log SSE. null when audit_log_sse option is not set.

type AuditLogSse | null

AppServerOptions
#

server/app_server.ts view source

AppServerOptions

Configuration for create_app_server().

Requires a pre-initialized AppBackend from create_app_backend(). Two explicit steps: init backend then assemble server.

backend

Pre-initialized backend from create_app_backend().

session_options

Session options for cookie-based auth.

type SessionOptions<string>

allowed_origins

Parsed allowed origin patterns.

type Array<RegExp>

proxy

Trusted proxy options.

type { trusted_proxies: Array<string>; get_connection_ip: (c: Context) => string | undefined; }

ip_rate_limiter

Shared IP rate limiter for login, bootstrap, and bearer auth. Omit or undefined to use a default limiter (5 attempts per 15 minutes). Pass null to explicitly disable rate limiting. Also available on AppServerContext for route factory callbacks.

type RateLimiter | null

login_account_rate_limiter

Per-account rate limiter for login attempts. Omit or undefined to use a default limiter (10 attempts per 30 minutes). Pass null to explicitly disable rate limiting. Also available on AppServerContext for route factory callbacks.

type RateLimiter | null

signup_account_rate_limiter

Per-account rate limiter for signup attempts, keyed by submitted username. Omit or undefined to use a default limiter (10 attempts per 30 minutes). Pass null to explicitly disable rate limiting. Also available on AppServerContext for route factory callbacks.

type RateLimiter | null

bearer_ip_rate_limiter

Rate limiter for bearer token auth attempts (per-IP). Omit or undefined to use a default limiter (5 attempts per 15 minutes). Pass null to explicitly disable rate limiting.

type RateLimiter | null

action_ip_rate_limiter

Per-IP rate limiter for the action dispatchers (HTTP RPC + WebSocket). Consulted for actions whose spec declares rate_limit: 'ip' or 'both'. Same limiter applies across transports — one budget per action. Omit or undefined to use a default limiter (600 attempts per 15 minutes — permissive). Pass null to explicitly disable. Also available on AppServerContext for consumers wiring register_action_ws.

type RateLimiter | null

action_account_rate_limiter

Per-actor rate limiter for the action dispatchers (HTTP RPC + WebSocket). Consulted for actions whose spec declares rate_limit: 'account' or 'both'. Keyed on request_context.actor.id (post-auth). Omit or undefined to use a default limiter (1200 attempts per 15 minutes — permissive). Pass null to explicitly disable. Also available on AppServerContext for consumers wiring register_action_ws.

type RateLimiter | null

max_body_size

Maximum allowed request body size in bytes. Omit or undefined to use the default (1 MiB). Pass null to explicitly disable body size limiting.

type number | null

daemon_token_state

Daemon token state for keeper auth. Omit to disable.

bootstrap

Bootstrap options. Omit to skip bootstrap status check and routes.

type { token_path: string | null; /** Route prefix for bootstrap routes. Default `'/api/account'`. */ route_prefix?: string; /** * Called after successful bootstrap (account + session created). * Use for app-specific post-bootstrap work like generating API tokens. */ on_bootstrap?: (result: BootstrapAccountSuccess, c: Context) => Promise<void>; }

surface_route

Set to false to disable the auto-created surface route (GET /api/surface). Default: auto-created (authenticated).

type false

create_route_specs

Build route specs from the initialized backend. Called after all middleware is ready.

type (context: AppServerContext) => Array<RouteSpec>

transform_middleware

Optional: transform middleware specs before applying.

type (specs: Array<MiddlewareSpec>) => Array<MiddlewareSpec>

audit_log_sse

Enable factory-managed audit log SSE.

When truthy, creates an AuditLogSse instance internally, appends the SSE listener to backend.deps.audit.on_event_chain (composing with the consumer's on_audit_event callback rather than rebuilding AppDeps), and auto-includes AUDIT_LOG_EVENT_SPECS in the surface. The result is exposed on AppServerContext (for route factories) and AppServer (for the caller).

Pass true for defaults (admin role), or {role: 'custom'} for a custom role. Omit to wire audit SSE manually.

type true | {role?: string}

event_specs

SSE event specs for surface generation. Defaults to [] (no SSE events).

type Array<EventSpec>

rpc_endpoints

RPC endpoint specs — single source of truth for both surface generation *and* live dispatch. Each entry is mounted via create_rpc_endpoint against the assembled Hono app, so consumers no longer call create_rpc_endpoint themselves inside create_route_specs.

Accepts either an array (evaluated eagerly) or a factory (ctx: AppServerContext) => Array<RpcEndpointSpec> (evaluated after the server context is assembled). Use the factory form when action lists depend on ctx.deps / ctx.app_settings — e.g. create_standard_rpc_actions(ctx.deps, {app_settings: ctx.app_settings}).

type Array<RpcEndpointSpec> | ((context: AppServerContext) => Array<RpcEndpointSpec>)

env_schema

Env schema for surface generation. Pass z.object({}) when there are no env vars beyond BaseServerEnv.

type z.ZodObject

post_route_middleware

Middleware applied after routes, before static serving. Included in surface.

type Array<MiddlewareSpec>

static_serving

Static file serving. Omit if not serving static files.

type { serve_static: ServeStaticFactory; spa_fallback?: string; }

await_pending_effects

Await all pending fire-and-forget effects before returning the response. Use in tests so audit log assertions don't need polling. Default false (production: true fire-and-forget).

type boolean

on_effect_error

Called when a pending effect rejects. Use for monitoring, metrics, or alerting in production. Only called when await_pending_effects is false (production mode).

type (error: unknown, context: EffectErrorContext) => void

env_values

Env values for startup summary logging.

type Record<string, unknown>

create_app_server
#

server/app_server.ts view source

(options: AppServerOptions): Promise<AppServer>

Create a fully assembled Hono app with auth, middleware, and routes.

Handles the assembly lifecycle: proxy middleware → auth middleware → bootstrap status → route specs → surface generation → Hono app assembly → static serving. Database migrations belong to the backend lifecycle — pass migration_namespaces to create_app_backend.

When audit_log_sse is set, the SSE registry's listener is appended to backend.deps.audit.on_event_chain — no shallow-copy of AppDeps.

options

returns

Promise<AppServer>

assembled Hono app, backend, surface build, and bootstrap status

DEFAULT_MAX_BODY_SIZE
#

EffectErrorContext
#

server/app_server.ts view source

EffectErrorContext

Context passed to on_effect_error when a pending effect rejects.

method

HTTP method of the request that spawned the effect.

type string

path

URL path of the request that spawned the effect.

type string

Depends on
#

Imported by
#