Blueprint & build
Meta-modules & define*
The imperative paradigm is not a lesser path; it is the same destination reached with plain values. A define* helper wraps your module in a meta-module, a small descriptor the build phase merges into the Blueprint. It is exactly what a decorator produces, written by hand.
#What a meta-module is
A meta-module is a descriptor: the module itself plus flags telling the builder how to treat it. Its shape is deliberately tiny.
interface MetaModule {
module: unknown // the class, factory or function
isClass?: boolean // treat module as a class
isFactory?: boolean // treat module as a factory (receives the container)
// ...plus the options specific to each kind (alias, path, event, ...)
}#The define* family
Each declarative decorator has an imperative twin. The third argument of most helpers is the isFactory flag; pass true for a factory, omit it for a class.
| Helper | Type | Description |
|---|---|---|
| defineStoneApp(config, blueprints) | app | The manifest (equivalent of @StoneApp). |
| defineService(mod, opts, isFactory?) | service | A service (equivalent of @Service). |
| defineServiceProvider(mod, opts, isFactory?) | provider | A provider (equivalent of @Provider). |
| defineEventHandler(mod, method?) | handler | A route handler (equivalent of @EventHandler + verbs). |
| defineMiddleware(mod, opts) | middleware | Middleware (equivalent of @Middleware). |
| defineEventListener(mod, opts, isFactory?) | listener | An event listener (equivalent of @Listener). |
| defineErrorHandler(mod, opts, isFactory?) | error handler | An error handler (equivalent of @ErrorHandler). |
| defineLogger / defineBlueprintMiddleware / ... | various | One helper per declarative decorator. |
#Assembling an app imperatively
import { defineStoneApp, defineService } from '@stone-js/core'
import { defineEventHandler, defineRoutes, routerBlueprint } from '@stone-js/router'
import { nodeHttpAdapterBlueprint } from '@stone-js/node-http-adapter'
const TaskService = () => ({ list: () => [/* ... */] })
const TaskController = ({ tasks }) => ({ list: () => tasks.list() })
export const App = defineStoneApp({ name: 'tasks' }, [
routerBlueprint,
nodeHttpAdapterBlueprint,
{ services: [defineService(TaskService, { alias: 'tasks' }, true)] },
{ routes: defineRoutes([[defineEventHandler(TaskController, 'list'), { path: '/tasks', method: 'GET' }]]) }
])