createApp
createApp(options) builds an App — a bounded context with its container, plugins, wires, and runtime.
Signature
ts
function createApp(options: CreateAppOptions): AppCreateAppOptions
ts
interface CreateAppOptions {
readonly appName: string
readonly plugins?: readonly PluginDefinition[]
readonly handlers?: readonly ActionDefinition[]
// The container the App owns. Pass a pre-configured one to override
// the default; otherwise an in-memory container is created.
readonly container?: Container
// Optional logger. Defaults to ConsoleLogger.
readonly logger?: Logger
}Example
ts
import { createApp, defineRegistry, definePlugin } from "@nwire/app"
import { forgePlugins } from "@nwire/forge"
import { Submission } from "./actor"
import { submissionsByStudent, listSubmissions } from "./projections"
import { autoGrade } from "./workflows/auto-grade"
import { submitAnswer, gradeAnswer } from "./actions"
export function buildSubmissionsApp() {
return createApp({
appName: "submissions",
registry: defineRegistry({
handlers: [submitAnswer, gradeAnswer, listSubmissions],
actors: [Submission],
projections: [submissionsByStudent],
workflows: [autoGrade],
}),
plugins: [
definePlugin("custom-store", ({ bind }) => {
bind("notification.queue", new InMemoryNotificationQueue())
}),
...forgePlugins(),
],
})
}App handle
ts
interface App {
readonly appName: string
readonly container: Container
readonly runtime: Runtime
readonly interface: { readonly wires: ReadonlyArray<Wire> }
wire(binding: Binding, handler: HandlerDef): this
provide(name: string, value: unknown): this
start(): Promise<void>
stop(): Promise<void>
}Boot the App, register wires, mount under an endpoint:
ts
const app = buildSubmissionsApp()
app.wire(post("/submissions"), submitAnswer)
await app.start()
await endpoint("submissions", { port: 3000 })
.use(httpKoa())
.mount(app)
.run()Multi-app composition
For multi-BC apps, use appCompose(...):
ts
import { appCompose } from "@nwire/app"
const submissions = buildSubmissionsApp()
const enrollments = buildEnrollmentsApp()
const monolith = appCompose(submissions, enrollments)
// monolith.interface.wires contains both apps' wires tagged with source
// adopters mount monolith and dispatch each request through the source
// App's container per wire — no cross-App container leakageMulti-tenancy
Apps don't declare a tenant model; tenancy lives on envelope.tenant which threads through every dispatch. HTTP adopters read x-tenant from the request by default; bus adopters preserve it across services.
See Multi-tenancy for the patterns.
See also
- Concepts → App
- Apps + composition — the end-to-end pattern
- definePlugin — plugin contract