feat: add native module realtime transport
CI / verify (pull_request) Successful in 37s
CI / infrastructure-smoke (pull_request) Successful in 13s
CI / migration-smoke (pull_request) Successful in 1m7s

This commit is contained in:
ekklesia
2026-08-23 18:47:18 -05:00
parent fcc531a39c
commit fc6c8045c4
53 changed files with 3959 additions and 108 deletions
+9 -4
View File
@@ -1,9 +1,10 @@
import { z } from "zod";
import type { EkklesiaPrincipal } from "./identity.js";
import { type ModuleId, type PermissionId, permissionIdSchema } from "./identifiers.js";
import type { EkklesiaPrincipal } from "./identity.js";
import type { ModuleConfiguration } from "./module-configuration.js";
import type { ModuleStorage } from "./module-storage.js";
import type { ModuleRuntimeServices } from "./module-database.js";
import type { ModuleRealtimePublisher } from "./module-realtime.js";
import type { ModuleStorage } from "./module-storage.js";
// Not imported from `./module-runtime.js`'s own `Awaitable` (structurally identical) — importing
// it would create a source dependency cycle with that module, which also imports from this one for
@@ -188,8 +189,10 @@ export function moduleRoutesOverlap(
/**
* What a module's route handler receives about the caller, the match, and the platform services
* available to it — never an authorization-store, grant-management, storage, jobs, configuration,
* secrets, the Hono `Context`, or a raw Better Auth session. `principal` is already authorized by
* available to it — never an authorization store, grant-management state, jobs, the Hono `Context`,
* or a raw Better Auth session. Its storage, configuration, and realtime publisher are all scoped
* to the owning module; secret values appear only when explicitly declared and supplied through
* that module's configuration contract. `principal` is already authorized by
* the time a handler runs: `apps/api/src/module-http-routes.ts` mounts and enforces every route
* before ever invoking its handler; this contracts-layer module never invokes a handler itself.
* `services` is the same frozen `ModuleRuntimeServices` object the owning module's `start`/`stop`
@@ -226,6 +229,8 @@ export interface ModuleRouteHandlerContext {
* into a `Response` without the browser ever learning that object storage exists. */
readonly storage: ModuleStorage;
readonly services: ModuleRuntimeServices;
/** The identical module-scoped realtime publisher used by lifecycle hooks. */
readonly realtime: ModuleRealtimePublisher;
/** The identical frozen configuration snapshot this module's `start`/`stop` hooks received — the
* same object, not a re-read — so a handler and a lifecycle hook can never disagree about a value
* (ADR 0029). Never serialized into a response by Core; a module that chooses to expose part of