Resolve Eve documents behind provider transport

This commit is contained in:
Meta Vens 2026-07-10 07:17:55 +01:00
commit 1218dbf655
8 changed files with 129 additions and 38 deletions

View file

@ -348,6 +348,21 @@ export type AetheriaEveSurfaceRequest = {
recordKey?: string;
};
export type EveEmbeddedDocumentRequest = {
documentId: string;
schemaId?: string;
slotId?: string;
presentationKind?: string;
context?: Record<string, unknown>;
};
export type EveResolvedDocument = {
documentId: string;
schemaId: string;
document?: unknown;
surface?: AetheriaMenuSurfaceTree;
};
export type EveProviderAdvertisement = {
providerId: string;
title: string;
@ -429,6 +444,7 @@ export type AetheriaRtsApi = {
surfaceCatalogIndex(): Promise<CultMeshSurfaceCatalogIndexDiagnostic>;
eveSurface(request: AetheriaEveSurfaceRequest): Promise<AetheriaMenuSurfaceDocument>;
eveProviderAdvertisement(): Promise<EveProviderAdvertisement>;
eveDocument(request: EveEmbeddedDocumentRequest): Promise<EveResolvedDocument | undefined>;
submitEveCommand(request: AetheriaEveCommandRequest): Promise<AetheriaRuntimeDaemonCommandReceipt>;
windowControl(action: "minimize" | "maximize" | "close"): Promise<void>;
health(): Promise<unknown>;

View file

@ -6,9 +6,7 @@ import {
type EveSurfaceComponent,
} from "../node_modules/@gamecult/eve-browser-lowering/dist/index.js";
import type {
AetheriaMenuSurfaceDocument,
AetheriaRtsApi,
Viewport,
} from "./aetheria-rts-contract.js";
export {};
@ -65,44 +63,14 @@ function surfaceRequest(surface: EveProviderSurfaceAdvertisement): { surfaceId?:
async function resolveEveDocument(
request: EveEmbeddedDocumentRequest,
component: EveSurfaceComponent,
): Promise<{ document?: unknown; documentId: string; schemaId: string; surface?: AetheriaMenuSurfaceDocument["surface"] } | undefined> {
if (request.schemaId === "gamecult.eve.surface.v1" || request.slotId === "mainMenuPanel") {
const surface = await window.aetheriaRts.eveSurface({
surfaceId: request.documentId,
});
return {
documentId: request.documentId,
schemaId: "gamecult.eve.surface.v1",
surface: surface.surface,
};
}
const viewport = viewportFromComponent(component);
if (request.schemaId === "gamecult.aetheria.render_splats_viewport.v1" || request.slotId === "renderSplats") {
return {
document: await window.aetheriaRts.renderSplatsViewport(viewport),
documentId: request.documentId,
schemaId: "gamecult.aetheria.render_splats_viewport.v1",
};
}
if (request.schemaId === "gamecult.aetheria.gravity_viewport.v1" || request.slotId === "gravity") {
return {
document: await window.aetheriaRts.gravityViewport(viewport),
documentId: request.documentId,
schemaId: "gamecult.aetheria.gravity_viewport.v1",
};
}
if (request.schemaId === "gamecult.aetheria.objects_viewport.v1" || request.slotId === "objects") {
return {
document: await window.aetheriaRts.objectsViewport(viewport),
documentId: request.documentId,
schemaId: "gamecult.aetheria.objects_viewport.v1",
};
}
return undefined;
): ReturnType<AetheriaRtsApi["eveDocument"]> {
return window.aetheriaRts.eveDocument({
...request,
context: { viewport: viewportFromComponent(component) },
});
}
function viewportFromComponent(component: EveSurfaceComponent): Viewport {
function viewportFromComponent(component: EveSurfaceComponent): Record<string, number> {
const props = component.props ?? {};
return {
minX: numberProp(props.minX, -1500),

View file

@ -104,6 +104,21 @@ export type AetheriaEveSurfaceRequest = {
recordKey?: string;
};
export type EveEmbeddedDocumentRequest = {
documentId: string;
schemaId?: string;
slotId?: string;
presentationKind?: string;
context?: Record<string, unknown>;
};
export type EveResolvedDocument = {
documentId: string;
schemaId: string;
document?: unknown;
surface?: AetheriaMenuSurfaceDocument["surface"];
};
export type AetheriaEveCommandRequest = {
providerId?: string;
surfaceId?: string;
@ -406,6 +421,27 @@ export class AetheriaCultMeshClient {
return normalizeEveProviderAdvertisement(await document.latest(this.queryContext()));
}
public async eveDocument(request: EveEmbeddedDocumentRequest): Promise<EveResolvedDocument | undefined> {
const schemaId = request?.schemaId?.trim() || "";
if (!request?.documentId?.trim()) throw new Error("Eve embedded document request is missing documentId.");
if (schemaId === eveSurfaceSchemaId || request.slotId === "mainMenuPanel") {
const surface = await this.eveSurface({ surfaceId: request.documentId });
return { documentId: request.documentId, schemaId: eveSurfaceSchemaId, surface: surface.surface };
}
const viewport = viewportFromEmbeddedDocumentContext(request.context);
if (schemaId === AetheriaRtsSchemas.renderSplatsViewport || request.slotId === "renderSplats") {
return { documentId: request.documentId, schemaId: AetheriaRtsSchemas.renderSplatsViewport, document: await this.renderSplatsViewport(viewport) };
}
if (schemaId === AetheriaRtsSchemas.gravityViewport || request.slotId === "gravity") {
return { documentId: request.documentId, schemaId: AetheriaRtsSchemas.gravityViewport, document: await this.gravityViewport(viewport) };
}
if (schemaId === AetheriaRtsSchemas.objectsViewport || request.slotId === "objects") {
return { documentId: request.documentId, schemaId: AetheriaRtsSchemas.objectsViewport, document: await this.objectsViewport(viewport) };
}
return undefined;
}
public async submitEveCommand(request: AetheriaEveCommandRequest): Promise<AetheriaRuntimeDaemonCommandReceipt> {
const issuedAtUtc = request?.issuedAtUtc || new Date().toISOString();
const commandId = `${this.runtimeId}:eve:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
@ -967,6 +1003,16 @@ function normalizeEveProviderAdvertisement(document: unknown): import("./aetheri
};
}
function viewportFromEmbeddedDocumentContext(context: Record<string, unknown> | undefined): ViewportRequest {
const source = objectValue(context?.viewport);
return {
minX: numberOr(source.minX, -1500),
minY: numberOr(source.minY, -1000),
maxX: numberOr(source.maxX, 1500),
maxY: numberOr(source.maxY, 1000),
};
}
function normalizeEveSurfaceDocument(document: unknown): AetheriaMenuSurfaceDocument {
const portableSlots = Array.isArray(document) &&
typeof document[1] === "string" &&

View file

@ -130,6 +130,7 @@ export const AetheriaRtsIpcChannels = {
surfaceCatalogIndex: "aetheria-rts:surface-catalog-index",
eveSurface: "aetheria-rts:eve-surface",
eveProviderAdvertisement: "eve:provider-advertisement",
eveDocument: "eve:embedded-document",
submitEveCommand: "aetheria-rts:submit-eve-command",
windowControl: "aetheria-rts:window-control",
health: "aetheria-rts:health",
@ -1960,6 +1961,21 @@ export type AetheriaEveSurfaceRequest = {
recordKey?: string;
};
export type EveEmbeddedDocumentRequest = {
documentId: string;
schemaId?: string;
slotId?: string;
presentationKind?: string;
context?: Record<string, unknown>;
};
export type EveResolvedDocument = {
documentId: string;
schemaId: string;
document?: unknown;
surface?: AetheriaMenuSurfaceTree;
};
export type EveProviderAdvertisement = {
providerId: string;
title: string;
@ -2041,6 +2057,7 @@ export type AetheriaRtsMainClient = {
setTarget(request: AetheriaRuntimeSetTargetRequest): Promise<AetheriaRuntimeDaemonCommandReceipt>;
eveSurface(request: AetheriaEveSurfaceRequest): Promise<AetheriaMenuSurfaceDocument>;
eveProviderAdvertisement(): Promise<EveProviderAdvertisement>;
eveDocument(request: EveEmbeddedDocumentRequest): Promise<EveResolvedDocument | undefined>;
submitEveCommand(request: AetheriaEveCommandRequest): Promise<AetheriaRuntimeDaemonCommandReceipt>;
surfaceCatalogDiagnostics(): CultMeshSurfaceCatalogDiagnostic;
surfaceCatalogIndexDiagnostics(): CultMeshSurfaceCatalogIndexDiagnostic;
@ -2092,6 +2109,8 @@ export function registerAetheriaRtsIpcHandlers(
getClient().eveSurface(request));
ipcMain.handle(AetheriaRtsIpcChannels.eveProviderAdvertisement, async () =>
getClient().eveProviderAdvertisement());
ipcMain.handle(AetheriaRtsIpcChannels.eveDocument, async (_event, request: EveEmbeddedDocumentRequest) =>
getClient().eveDocument(request));
ipcMain.handle(AetheriaRtsIpcChannels.submitEveCommand, async (_event, request: AetheriaEveCommandRequest) =>
getClient().submitEveCommand(request));
ipcMain.handle(AetheriaRtsIpcChannels.surfaceCatalog, () => getClient().surfaceCatalogDiagnostics());

View file

@ -199,6 +199,7 @@ async function runElectronSmoke(window: BrowserWindow): Promise<Record<string, u
typeof api.surfaceCatalog === "function" &&
typeof api.surfaceCatalogIndex === "function" &&
typeof api.eveProviderAdvertisement === "function" &&
typeof api.eveDocument === "function" &&
typeof api.eveSurface === "function" &&
typeof api.submitEveCommand === "function",
status,

View file

@ -23,6 +23,7 @@ const channels = {
surfaceCatalogIndex: "aetheria-rts:surface-catalog-index",
eveSurface: "aetheria-rts:eve-surface",
eveProviderAdvertisement: "eve:provider-advertisement",
eveDocument: "eve:embedded-document",
submitEveCommand: "aetheria-rts:submit-eve-command",
windowControl: "aetheria-rts:window-control",
health: "aetheria-rts:health",
@ -59,6 +60,7 @@ contextBridge.exposeInMainWorld("aetheriaRts", {
surfaceCatalogIndex: () => ipcRenderer.invoke(channels.surfaceCatalogIndex),
eveSurface: request => ipcRenderer.invoke(channels.eveSurface, request),
eveProviderAdvertisement: request => ipcRenderer.invoke(channels.eveProviderAdvertisement, request),
eveDocument: request => ipcRenderer.invoke(channels.eveDocument, request),
submitEveCommand: request => ipcRenderer.invoke(channels.submitEveCommand, request),
windowControl: request => ipcRenderer.invoke(channels.windowControl, request),
health: () => ipcRenderer.invoke(channels.health),

View file

@ -43,6 +43,7 @@ const ipcChannels = [
["surfaceCatalogIndex", "aetheria-rts:surface-catalog-index"],
["eveSurface", "aetheria-rts:eve-surface"],
["eveProviderAdvertisement", "eve:provider-advertisement"],
["eveDocument", "eve:embedded-document"],
["submitEveCommand", "aetheria-rts:submit-eve-command"],
["windowControl", "aetheria-rts:window-control"],
["health", "aetheria-rts:health"],
@ -486,6 +487,21 @@ export type AetheriaEveSurfaceRequest = {
recordKey?: string;
};
export type EveEmbeddedDocumentRequest = {
documentId: string;
schemaId?: string;
slotId?: string;
presentationKind?: string;
context?: Record<string, unknown>;
};
export type EveResolvedDocument = {
documentId: string;
schemaId: string;
document?: unknown;
surface?: AetheriaMenuSurfaceTree;
};
export type EveProviderAdvertisement = {
providerId: string;
title: string;
@ -567,6 +583,7 @@ export type AetheriaRtsMainClient = {
setTarget(request: AetheriaRuntimeSetTargetRequest): Promise<AetheriaRuntimeDaemonCommandReceipt>;
eveSurface(request: AetheriaEveSurfaceRequest): Promise<AetheriaMenuSurfaceDocument>;
eveProviderAdvertisement(): Promise<EveProviderAdvertisement>;
eveDocument(request: EveEmbeddedDocumentRequest): Promise<EveResolvedDocument | undefined>;
submitEveCommand(request: AetheriaEveCommandRequest): Promise<AetheriaRuntimeDaemonCommandReceipt>;
surfaceCatalogDiagnostics(): CultMeshSurfaceCatalogDiagnostic;
surfaceCatalogIndexDiagnostics(): CultMeshSurfaceCatalogIndexDiagnostic;
@ -618,6 +635,8 @@ export function registerAetheriaRtsIpcHandlers(
getClient().eveSurface(request));
ipcMain.handle(AetheriaRtsIpcChannels.eveProviderAdvertisement, async () =>
getClient().eveProviderAdvertisement());
ipcMain.handle(AetheriaRtsIpcChannels.eveDocument, async (_event, request: EveEmbeddedDocumentRequest) =>
getClient().eveDocument(request));
ipcMain.handle(AetheriaRtsIpcChannels.submitEveCommand, async (_event, request: AetheriaEveCommandRequest) =>
getClient().submitEveCommand(request));
ipcMain.handle(AetheriaRtsIpcChannels.surfaceCatalog, () => getClient().surfaceCatalogDiagnostics());
@ -1164,6 +1183,21 @@ export type AetheriaEveSurfaceRequest = {
recordKey?: string;
};
export type EveEmbeddedDocumentRequest = {
documentId: string;
schemaId?: string;
slotId?: string;
presentationKind?: string;
context?: Record<string, unknown>;
};
export type EveResolvedDocument = {
documentId: string;
schemaId: string;
document?: unknown;
surface?: AetheriaMenuSurfaceTree;
};
export type EveProviderAdvertisement = {
providerId: string;
title: string;
@ -1245,6 +1279,7 @@ export type AetheriaRtsApi = {
surfaceCatalogIndex(): Promise<CultMeshSurfaceCatalogIndexDiagnostic>;
eveSurface(request: AetheriaEveSurfaceRequest): Promise<AetheriaMenuSurfaceDocument>;
eveProviderAdvertisement(): Promise<EveProviderAdvertisement>;
eveDocument(request: EveEmbeddedDocumentRequest): Promise<EveResolvedDocument | undefined>;
submitEveCommand(request: AetheriaEveCommandRequest): Promise<AetheriaRuntimeDaemonCommandReceipt>;
windowControl(action: "minimize" | "maximize" | "close"): Promise<void>;
health(): Promise<unknown>;

View file

@ -15,7 +15,11 @@ if (-not (Get-Content wwwroot\index.html -Raw).Contains('eve-surface-host')) {
$appText = Get-Content wwwroot\app.js -Raw
if (-not $appText.Contains('window.aetheriaRts.eveProviderAdvertisement') -or
-not $appText.Contains('EveBrowserProviderHost') -or
-not $appText.Contains('window.aetheriaRts.eveDocument') -or
$appText.Contains('eve:surface:aetheria.daemon.game') -or
$appText.Contains('gamecult.aetheria.gravity_viewport.v1') -or
$appText.Contains('gamecult.aetheria.render_splats_viewport.v1') -or
$appText.Contains('gamecult.aetheria.objects_viewport.v1') -or
$appText.Contains('legacyViewportMode') -or
$appText.Contains('mainMenuSurface') -or
$appText.Contains('main-menu-mode')) {