Core concepts
UDIOT provides composable APIs rather than a mandatory application bootstrap. Begin with the runnable quick start; this page explains the contracts behind those examples.
Middleware pipelines
A MiddlewarePipeline<T> carries a shared context through async handlers.
Contexts extend BaseContext: they contain metadata: Map and timestamp,
and may contain a result. Public context builders initialize those fields.
Handlers call await next() to continue. Omitting it short-circuits processing.
Handlers execute in priority order (lower first), with registration order for
equal priorities. execute() returns a result envelope containing success,
result and error information; do not assume every failure throws.
Authentication belongs in a real credential validator. A header's presence is not proof of identity and must not assign a hard-coded user or role.
See pipeline, contexts and composition.
Dependency injection
A Container maps tokens to class, value, factory or existing providers.
Class services are singleton by default. Decorated constructor injection needs
metadata emitted by TypeScript; resolve<T>() uses an explicit generic for
the service result type.
Use child/request scopes for request-owned data. A child container may resolve a parent singleton, so child construction does not make every dependency request-scoped. Tenant selection is not authorization.
See providers, request scope, and tenants.
State and reactivity
Subclass Store<TState>, supply initial state and implement reduce(state, action). Dispatch invokes the reducer and notifies observers when state changes.
Await dispatch before checking the result. Returning a new state from an
arbitrary decorated method does not by itself register that method as a reducer.
Import the action-object type as StoreAction; root Action is the method
decorator. Use asObservable() for observable store state. Clean up subscriptions.
Type-level readonly declarations and runtime immutability are different concepts.
See store, decorators, observables and persistence.
Telemetry
Public metrics, logging and tracing live in @tagna/udiot/telemetry.
Use getTelemetryLogger(), metrics registries and startSpan(); configure
exporters deliberately and flush/shut down during application teardown.
Redact secrets and avoid sensitive/high-cardinality attributes.
See telemetry and run events.
Modules and runtime boundaries
The public Module decorator records DI grouping metadata; it does not
automatically load a module graph. Internal loaders exposed only as type
declarations are not callable runtime exports. See module composition.
Use the appropriate public entry point. Browser-specific imports, Node/server APIs and development tools have different runtime needs. Some APIs remain experimental and some internal features are not exported at all; review support levels.