feat: add display kiosk host
CI / verify (pull_request) Successful in 38s
CI / infrastructure-smoke (pull_request) Successful in 20s
CI / migration-smoke (pull_request) Successful in 59s

This commit is contained in:
ekklesia
2026-08-23 20:50:56 -05:00
parent be5ed7853d
commit 2e0fe059c3
80 changed files with 4868 additions and 397 deletions
+3 -1
View File
@@ -41,7 +41,9 @@ export type ModuleUiPrincipal = ModuleUiAnonymousPrincipal | ModuleUiAuthenticat
* than to add. See ADR 0022.
*
* Nothing in this object is an Ekklesia implementation. Every member is satisfiable by a standalone
* host that never runs Core, which is what makes one module UI hostable by both. This package has
* host that never runs Core, which is what makes one module UI hostable by both. The same context is
* supplied to primary and display artifacts: there is deliberately no role or presentation-mode
* flag, because the separately declared artifact already selects the experience. This package has
* no dependencies at all, so importing it cannot pull a backend type graph into a browser program.
*/
export interface ModuleUiHostContext {
+5 -3
View File
@@ -11,7 +11,8 @@ export type Awaitable<Value> = Value | PromiseLike<Value>;
export type ModuleUiUnmount = () => Awaitable<void>;
/**
* What a module's compiled `entrypoints.ui` artifact default-exports (ADR 0021, ADR 0022).
* What either compiled browser artifact (`entrypoints.ui` or `entrypoints.display.artifact`)
* default-exports (ADR 0021, ADR 0022, ADR 0033).
*
* `id` and `version` are build-artifact identity markers, mirroring `ModuleRuntimeDefinition`
* exactly (ADR 0006): they let a host prove the UI bundle it imported was built from the module it
@@ -115,8 +116,9 @@ export interface ModuleUiIdentity {
* Deliberately does **not** import anything itself. Each host performs its own dynamic import — a
* browser host from a served URL, a test host from a file URL — and passes the resulting module
* namespace here. That keeps this package free of any loader, bundler, or URL assumption, and keeps
* Core out of the business of evaluating browser code entirely: module discovery still only
* resolves and validates the `entrypoints.ui` path and never executes it (ADR 0021).
* Core out of the business of evaluating browser code entirely: module discovery only resolves
* and validates each declared browser artifact path and never executes either role (ADR 0021,
* ADR 0033).
*/
export function parseModuleUiExport(
namespace: unknown,
@@ -14,8 +14,8 @@ async function sourceFiles(): Promise<string[]> {
* This package is bundled into a browser. `@ekklesia/module-sdk` re-exports all of
* `@ekklesia/contracts`, which pulls Zod, Drizzle, and semver behind one barrel export, so a single
* value import from a backend package here would drag that whole graph into every module UI bundle
* (ADR 0022). The dependency on `@ekklesia/contracts` is deliberately type-only and must stay that
* way; `import type` is erased at build time, a plain `import` is not.
* (ADR 0022). ADR 0024 removed even the former type-only contracts dependency because its type graph
* leaked Node globals into browser programs; this package must remain completely dependency-free.
*/
describe("module UI SDK stays browser-safe", () => {
it("imports nothing from another package at all, at type level or runtime", async () => {