Foundations
The Continuum
This is the one idea the rest of the framework serves. Once it clicks, adapters, blueprints, the container and the lifecycle stop being features to memorise and become obvious consequences, and the idea outlives any single stack.
#An application is an act
The principle
We are taught to think of an application as a thing: a binary, a server, a bundle. But nothing happens until something arrives, a request, a message, a command, and something responds. The application only exists in that meeting. It is an act, not an object.
Name the two parts of the act. The domain is what your software means: its rules, its language, the part that would still be true on any platform. The context is everything the domain does not control: the runtime, the protocol, the shape of the input, the way a response leaves.
In Stone.js
Stone.js takes the radical position: it is the context. You write the domain once; the framework supplies the context at execution and applies it to your domain, not the other way around.
So a Stone.js app has no main() that reaches out to a server. It declares a domain and lets a context arrive. The same class is an HTTP handler, a Lambda, an edge function or an agent tool depending only on which context collapses onto it.
Application = Domain × Context → Resolution
#The four dimensions
The act unfolds across four dimensions. Each has a precise incarnation in the framework, and each later page in Foundations lives in one of them.
The principle
- Setup: describe the application once, before anything runs.
- Integration: capture a raw cause and normalise it into an intention.
- Initialization: apply the domain to that intention, per event.
- Functional: your logic, running, unaware of the platform.
In Stone.js
- Setup → the
Blueprint, built from your decorators or define* modules. - Integration → the
Adapter, one per platform, turning a cause into anIncomingEvent. - Initialization → the
Kernel, with a fresh container per event. - Functional → your handlers and services. No imposed structure.
#One request, all four
The dimensions are not abstract; they are the stages a single request passes through. Follow one POST /tasks:
- Setup (once, before any request): the Blueprint is built from your decorators; the adapter starts listening.
- Integration: the HTTP request arrives; the adapter normalises it into an
IncomingEventcarryingtitle. - Initialization: the kernel opens a fresh container, resolves your handler and its services into it.
- Functional: your
createmethod runs, returns the task; the response leaves, the container is discarded.
Only the first stage is platform-shaped, and it happens at the edge. From Initialization inward, nothing knows an HTTP server was involved.
#Why this buys you freedom
Because the domain never names the context, the context can change without the domain knowing. Move from a container to a Lambda to an edge worker, and the code that expresses what your product does is untouched. The platform churn of the last thirty years becomes a deployment detail.
// The manifest names contexts. The domain, elsewhere, never does.
@NodeHttp()
@AwsLambdaHttp()
@Routing()
@StoneApp()
export class Application {}