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
+18 -3
View File
@@ -40,6 +40,7 @@ const inventoryPayload = {
api: { baseUrl: "/api/v1/modules/example" },
id: "example",
permissions: ["example.records.read"],
realtime: { baseUrl: "/api/v1/module-realtime/example" },
ui: { url: "/api/v1/module-ui/example/0.1.0" },
version: "0.1.0",
},
@@ -50,6 +51,7 @@ const calendarDescriptor: HostModuleUiDescriptor = {
apiBaseUrl: "/api/v1/modules/calendar",
id: "calendar",
permissions: [],
realtimeBaseUrl: "/api/v1/module-realtime/calendar",
uiUrl: "/api/v1/module-ui/calendar/2.0.0",
version: "2.0.0",
};
@@ -69,6 +71,7 @@ const navigationPayload = {
api: { baseUrl: "/api/v1/modules/calendar" },
id: "calendar",
permissions: [],
realtime: { baseUrl: "/api/v1/module-realtime/calendar" },
ui: { url: "/api/v1/module-ui/calendar/2.0.0" },
version: "2.0.0",
},
@@ -81,6 +84,7 @@ const exampleDescriptor: HostModuleUiDescriptor = {
apiBaseUrl: "/api/v1/modules/example",
id: "example",
permissions: ["example.records.read"],
realtimeBaseUrl: "/api/v1/module-realtime/example",
uiUrl: "/api/v1/module-ui/example/0.1.0",
version: "0.1.0",
};
@@ -103,14 +107,18 @@ describe("host protocol — descriptor validation", () => {
{ id: "example", version: "0.1.0" },
{ ...base, ui: {} },
{ ...base, api: { baseUrl: "" } },
{ ...base, realtime: {} },
{ ...base, permissions: "example.records.read" },
{ ...base, permissions: [42] },
// Both URLs must be root-relative, so a value that would resolve against another origin is
// Every URL must be root-relative, so a value that would resolve against another origin is
// refused rather than silently used to fetch browser code.
{ ...base, ui: { url: "https://evil.example.test/x.js" } },
{ ...base, ui: { url: "//evil.example.test/x.js" } },
{ ...base, ui: { url: "relative/x.js" } },
{ ...base, api: { baseUrl: "https://evil.example.test/api" } },
{ ...base, realtime: { baseUrl: "https://evil.example.test/live" } },
{ ...base, realtime: { baseUrl: "//evil.example.test/live" } },
{ ...base, realtime: { baseUrl: "/\\evil.example.test/live" } },
];
for (const module of malformed) {
expect(
@@ -366,6 +374,7 @@ describe("module UI host context", () => {
apiBaseUrl: "/api/v1/modules/calendar",
id: "calendar",
permissions: [],
realtimeBaseUrl: "/api/v1/module-realtime/calendar",
uiUrl: "/api/v1/module-ui/calendar/2.0.0",
version: "2.0.0",
};
@@ -392,12 +401,18 @@ describe("module UI host context", () => {
expect(none.has("core.authorization.grants.manage")).toBe(false);
});
it("exposes exactly the four contract members and the browser principal", () => {
it("exposes exactly the five contract members and the browser principal", () => {
const { implementation } = recordingFetch();
const context = contextFor(implementation);
expect(Object.keys(context).sort()).toEqual(["api", "moduleId", "permissions", "principal"]);
expect(Object.keys(context).sort()).toEqual([
"api",
"moduleId",
"permissions",
"principal",
"realtime",
]);
expect(context.moduleId).toBe("example");
expect(context.principal).toEqual({ kind: "authenticated", userId: "user-1" });
});