Nile Server
Type: Reference / Specification
Path: nile/
1. Purpose
The Nile Server module provides the top-level factory for bootstrapping a Nile application. createNileServer is the single entry point developers use to wire together the Action Engine, shared context, and interface layers (REST, and later WebSocket/RPC).
1.1 Responsibilities
- Bootstrapping: Create and connect the Action Engine,
NileContext, and REST interface from a singleServerConfig - Context ownership: Create a single
NileContextinstance shared across all interfaces - Context access: Export
getContext()to retrieve the runtime context from anywhere within a request scope - Lifecycle: Execute
onBoothooks after initialization with crash safety - Diagnostics: Route diagnostic output through
createDiagnosticsLogfromutils/diagnostics-log.ts, which checksresources.loggerfirst and falls back toconsole.log. Seedocs/internals/logging.mdsection 7.
1.2 Non-Goals
- Transport logic: The server module does not handle HTTP routing, CORS, or request parsing. That is the REST layer's responsibility.
- Engine internals: The server does not manage action execution or hook pipelines. It delegates to the engine.
2. createNileServer
Path: nile/server.ts
2.1 Initialization Sequence
- Validate — Throws immediately if
config.servicesis empty - Create
NileContext— Single instance withconfig.resourcesattached - Create Engine — Passes
services,diagnostics, and global hook handlers - Log services table — When
config.logServicesistrue, prints aconsole.tableof registered services (name, description, actions). Always prints — not gated bydiagnostics - Create REST app — Only if
config.restis provided. Passes engine, context,serverName, andruntime(defaults to"bun") - Print REST endpoint URLs — When REST is configured, prints
POST http://host:port/baseUrl/servicesand optionallyGET http://host:port/statusviaconsole.log. Usesrest.host(default"localhost") andrest.port(default8000) - Run
onBoot— Fire-and-forget async IIFE. Failures are logged viaconsole.errorbut do not crash the server
2.2 Return Value (NileServer)
restis only present whenconfig.restwas providedengineprovides direct access togetServices,getServiceActions,getAction,executeActioncontextis the sharedNileContextpassed to all layers
3. ServerConfig
runtimelives only onServerConfigand is piped tocreateRestAppas a parameter. It is not duplicated ontoRestConfig.servicesis required. An empty array throws at initialization.diagnosticsdefaults tofalse. When enabled, internal modules emit diagnostic output throughcreateDiagnosticsLog.logServicesdefaults totrue. Prints aconsole.tableof registered services (Service, Description, Actions count). Not gated bydiagnostics— setlogServices: falseto suppress.- When REST is configured, endpoint URLs are always printed via
console.logusingrest.host(default"localhost") andrest.port(default8000).
4. NileContext
Path: nile/nile.ts
Factory: createNileContext(params?)
The context is a singleton per server. It carries interface-specific data, hook execution state, session storage, and a general-purpose key-value store. It supports an optional TDB generic to provide type safety for the database resource.
4.1 Key-Value Store
_store is a Map<string, unknown> exposed as readonly. Use get/set methods for access.
4.2 Sessions
Each NileContext owns its own session store. Multiple server instances do not share session state.
Session keys are "rest" | "ws" | "rpc", matching the interface types.
4.3 Hook Context
hookContext tracks the lifecycle of a single action execution. It is reset at the start of each executeAction call via resetHookContext(actionName, input).
Mutation methods: updateHookState, addHookLog, setHookError, setHookOutput.
4.4 Interface Contexts
These are set once during createNileContext via the interfaceContext parameter. The REST layer creates a fresh context per request with the Hono context attached.
4.5 Resources
Extensible via index signature. Passed through from ServerConfig.resources. The database field is typed as TDB (defaulting to unknown).
5. Key Types
5.1 BeforeActionHandler
Global hook that runs before every action. Returns a Result — Err halts the pipeline.
5.2 AfterActionHandler
Global hook that runs after every action. Receives the action result and can transform it.
5.3 Sessions
5.4 Resources
The logger field accepts a NileLogger — the return type of createLogger from the logging module. This enables handleError and createDiagnosticsLog to log through the same logger instance.
6. Constraints
- One context per server —
createNileContextis called once increateNileServer. All interfaces share this instance. - Generic Database Support — To avoid generic leakage into the core engine, the database type
TDBis only present inNileContextandResources. High-level components (Engine, REST) useunknown. onBootis fire-and-forget — It runs in an async IIFE and is not awaited. Errors are caught bysafeTryand logged toconsole.error.- Runtime default — If
config.runtimeis omitted, it defaults to"bun". This affects static file serving and runtime-specific behavior. - No dynamic service injection — Services are fixed at boot time. Adding services after initialization is not supported.
7. Failure Modes
- Empty services —
createNileServerthrows immediately with a descriptive error onBootcrash — Caught bysafeTry, logged toconsole.error, does not prevent server from starting- Missing resources —
resourcesis optional. Diagnostics fall back toconsole.logwhenresources.loggeris absent (handled bycreateDiagnosticsLog)
8. getContext
Path: nile/server.ts
Exported function that retrieves the runtime NileContext from anywhere within a request scope. It accepts an optional TDB generic for type-safe database access. The context is stored in a module-level variable set during createNileServer initialization.
8.1 Usage Pattern
getContext is designed to be called from action handlers or utility functions that need access to the context but don't receive it as a parameter:
8.2 Constraints
- Must be called after server initialization —
getContextthrows if called beforecreateNileServerhas run - Must be called within a request scope — The context is set once at server boot, not per-request. For per-request isolation, use the context passed to action handlers
8.3 Failure Modes
- Called before server boot — Throws
"getContext: Server not initialized. Call createNileServer first."