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 -1
View File
@@ -20,12 +20,14 @@ import {
createModuleUiPublicationRegistry,
type DiscoveredModule,
discoverModules,
EMPTY_MODULE_REALTIME_REGISTRY,
} from "@ekklesia/core/modules";
import type { Hono } from "hono";
import { afterEach, describe, expect, it, vi } from "vitest";
import { createInMemoryDashboardStore } from "./support/in-memory-dashboard-store.js";
import { createApiApp } from "../src/app.js";
import { moduleApiBaseUrl } from "../src/module-http-routes.js";
import { moduleRealtimeBaseUrl } from "../src/module-realtime-routes.js";
import { MODULE_UI_INVENTORY_PATH } from "../src/module-ui-inventory.js";
import { moduleUiArtifactUrl } from "../src/module-ui-routes.js";
import {
@@ -173,6 +175,7 @@ async function install(options: InstallOptions): Promise<Installation> {
const app = createApiApp({
authorization: { evaluator, registry: permissionRegistry, store },
moduleRoutes: Object.freeze([]),
moduleRealtime: EMPTY_MODULE_REALTIME_REGISTRY,
moduleServices: services,
moduleUi: createModuleUiPublicationRegistry(modules),
moduleLifecycle: {
@@ -219,13 +222,14 @@ describe("module UI inventory — what it lists", () => {
api: { baseUrl: "/api/v1/modules/example" },
id: "example",
permissions: [],
realtime: { baseUrl: "/api/v1/module-realtime/example" },
ui: { url: "/api/v1/module-ui/example/0.1.0" },
version: "0.1.0",
},
]);
});
it("builds both URLs with the server's own canonical helpers", async () => {
it("builds all host URLs with the server's own canonical helpers", async () => {
const { app, modules: discovered } = await install({
fixtures: [{ id: "example", version: "2.4.1", withUi: true }],
principal: signedIn(),
@@ -240,6 +244,9 @@ describe("module UI inventory — what it lists", () => {
url: moduleUiArtifactUrl({ moduleId: module.manifest.id, version: module.manifest.version }),
});
expect(modules[0]?.api).toEqual({ baseUrl: moduleApiBaseUrl(module.manifest.id) });
expect(modules[0]?.realtime).toEqual({
baseUrl: moduleRealtimeBaseUrl(module.manifest.id),
});
});
it("omits a module that declares no UI entrypoint", async () => {
@@ -310,6 +317,7 @@ describe("module UI inventory — what it lists", () => {
"api",
"id",
"permissions",
"realtime",
"ui",
"version",
]);