Skip to content

Advanced Runtime Composition

Use await zelavis(...) when you intentionally need lower-level runtime assembly instead of the guarded new Zelavis(...) class API.

Reach for the lower-level function when you need things like:

  • coreServices overrides
  • direct services injection
  • custom servicePrefixes
  • custom pathOverrides
  • explicit low-level runtime composition in tests or internal infrastructure

For normal application code, prefer:

import { Zelavis } from "zelavis";
import { nodeAdapter } from "zelavis/adapters/node";
const zelavis = new Zelavis({
adapter: nodeAdapter(),
});

There are two layers:

  1. new Zelavis(...) The safe product-facing entrypoint.
  2. await zelavis(...) The advanced runtime-facing entrypoint.

The class is intentionally guarded and does not accept internal runtime knobs like coreServices or direct services.

import { zelavis } from "zelavis";
const runtime = await zelavis({
rootPath: "/admin",
coreServices: {
dashboard: false,
database: false,
},
services: [],
});

That returns a lower-level mounted runtime object with fetch, dispatch, plain, resolved routes, and the service map.

There is no separate defineCoreService(...) helper today.

The pattern is:

  1. A package exposes a normal server-service factory.
  2. That factory uses defineService(...).
  3. The high-level zelavis(...) runtime decides when to call that factory and include the result as a built-in core service.

For example:

Concretely:

  • @zelavis/database exports defineDatabaseService(database)
  • that function returns defineService({ ... })
  • then zelavis(...) calls resolveDatabaseCoreService(...), wraps the returned database API with defineDatabaseService(...), and adds it to the built-in core service list

The same shape is used for auth, dashboard, website, and storage.

So the “core” part is not a special helper. The “core” part is that the high-level Zelavis runtime owns when those service factories are created, mounted, and protected.

This gives Zelavis two useful properties:

  • packages like @zelavis/database stay independently usable
  • the high-level runtime can still reserve extra privileges for built-in core services

That means the service factory itself can stay ordinary, while the runtime decides which services are privileged built-ins.