fix: make empty runtime state reachable

This commit is contained in:
vince 2026-06-18 19:32:32 +02:00
parent c2fb20b066
commit 35855f018f
3 changed files with 44 additions and 15 deletions

View file

@ -20,7 +20,7 @@ describe("dashboard runtime loader", () => {
test("seeds and loads the active dashboard from sqlite", async () => { test("seeds and loads the active dashboard from sqlite", async () => {
const store = await createTestStore(); const store = await createTestStore();
const runtime = loadDashboardRuntime(store); const runtime = loadDashboardRuntime(store, { seedIfEmpty: true });
expect(runtime.state).toBe("ready"); expect(runtime.state).toBe("ready");
if (runtime.state !== "ready") throw new Error("expected ready dashboard"); if (runtime.state !== "ready") throw new Error("expected ready dashboard");
@ -46,6 +46,17 @@ describe("dashboard runtime loader", () => {
expect(runtime.document.metadata.title).toBe(genericDashboardFixture.metadata.title); expect(runtime.document.metadata.title).toBe(genericDashboardFixture.metadata.title);
expect(store.listRevisions()).toHaveLength(1); expect(store.listRevisions()).toHaveLength(1);
}); });
test("returns empty state when no dashboard is active and seeding is disabled", async () => {
const store = await createTestStore();
const runtime = loadDashboardRuntime(store);
expect(runtime.state).toBe("empty");
if (runtime.state !== "empty") throw new Error("expected empty dashboard");
expect(runtime.title).toBe("No Dashboard Model");
expect(store.listRevisions()).toHaveLength(0);
});
}); });
async function createTestStore() { async function createTestStore() {

View file

@ -42,21 +42,24 @@ export interface DashboardRuntimeInvalid {
errors: string[]; errors: string[];
} }
export interface DashboardRuntimeOptions {
seedIfEmpty?: boolean;
seedDocument?: DashboardDocument;
}
export function loadDashboardRuntime( export function loadDashboardRuntime(
store?: DashboardStore, store?: DashboardStore,
options: DashboardRuntimeOptions = {},
): DashboardRuntimeState { ): DashboardRuntimeState {
const dashboardStore = store || createDashboardStore(); const dashboardStore = store || createDashboardStore();
try { try {
const seeded = dashboardStore.seedDashboardIfEmpty(dimensionLabDashboardFixture, {
actor: "initial-seed",
message: "load initial dashboard document",
});
const active = dashboardStore.getActiveDashboard(); const active = dashboardStore.getActiveDashboard();
const document = active?.document || seeded.document; if (active) {
const currentRevisionId = active?.currentRevisionId || seeded.id; return readyRuntimeState(active.document, active.currentRevisionId);
}
if (!document) { if (!options.seedIfEmpty) {
return { return {
state: "empty", state: "empty",
title: "No Dashboard Model", title: "No Dashboard Model",
@ -65,12 +68,15 @@ export function loadDashboardRuntime(
}; };
} }
return { const seeded = dashboardStore.seedDashboardIfEmpty(
state: "ready", options.seedDocument || dimensionLabDashboardFixture,
document, {
schemaVersion: document.schemaVersion, actor: "initial-seed",
currentRevisionId, message: "load initial dashboard document",
}; },
);
return readyRuntimeState(seeded.document, seeded.id);
} catch (error) { } catch (error) {
if (error instanceof DashboardPersistenceValidationError) { if (error instanceof DashboardPersistenceValidationError) {
return invalidRuntimeState(error.failure.errors); return invalidRuntimeState(error.failure.errors);
@ -86,6 +92,18 @@ export function loadDashboardRuntime(
} }
} }
function readyRuntimeState(
document: DashboardDocument,
currentRevisionId: string,
): DashboardRuntimeReady {
return {
state: "ready",
document,
schemaVersion: document.schemaVersion,
currentRevisionId,
};
}
function invalidRuntimeState(errors: string[]): DashboardRuntimeInvalid { function invalidRuntimeState(errors: string[]): DashboardRuntimeInvalid {
return { return {
state: "invalid", state: "invalid",

View file

@ -2,6 +2,6 @@ import { loadDashboardRuntime } from "$lib/server/dashboard";
export function load() { export function load() {
return { return {
dashboard: loadDashboardRuntime(), dashboard: loadDashboardRuntime(undefined, { seedIfEmpty: true }),
}; };
} }