import type { ImportableSchemaBase, CollectionSchemaBase, SchemaBase } from './dsl.js'; import { DtoField } from './dto.js'; import type { DtoMessage, DtoArrayField, DtoObjectField } from './dto.js'; import type { ComponentSchema } from './component.js'; import type { PageActionSchema } from './page-action.js'; export type { RouteDataSchema } from './route.js'; export { defineRouteData } from './route.js'; // PageDef: a page skeleton declaration. Describes what data a page needs // and where each field comes from (route params, provider calls, or literals). // Driver identifies the source by inspecting each field's .schema back-reference. /** Page lifecycle events that trigger data loading. */ export interface EventSchema extends SchemaBase { type: 'onLoad' | 'onShow' | 'onHide' | 'onPullDownRefresh' | 'onReachBottom'; /** Page actions that fire when this event occurs. */ actions?: PageActionSchema[]; } export const events = { onLoad(actions?: PageActionSchema[], description?: string): EventSchema { return { name: 'onLoad', type: 'onLoad', actions, description }; }, onShow(actions?: PageActionSchema[], description?: string): EventSchema { return { name: 'onShow', type: 'onShow', actions, description }; }, onHide(actions?: PageActionSchema[], description?: string): EventSchema { return { name: 'onHide', type: 'onHide', actions, description }; }, onPullDownRefresh(actions?: PageActionSchema[], description?: string): EventSchema { return { name: 'onPullDownRefresh', type: 'onPullDownRefresh', actions, description }; }, onReachBottom(actions?: PageActionSchema[], description?: string): EventSchema { return { name: 'onReachBottom', type: 'onReachBottom', actions, description }; }, }; /** Page data: a named collection of fields that defines the page's data shape. */ export interface PageDataSchema extends CollectionSchemaBase { type: 'pageData'; fields: Record; } export function definePageData(fields: PageDataSchema['fields']): PageDataSchema { // Page data has no meaningful identity of its own; the page name already // scopes it, so the schema name defaults to 'data'. const data: PageDataSchema = { name: 'data', type: 'pageData', fields }; // Write back field names (same convention as buildMessage) so defineRef // produces refs with a real field name instead of ''. for (const key of Object.keys(data.fields)) { const df = data.fields[key]; if (df instanceof DtoField) { df.name = key; df.schema = data; } } return data; } /** Page skeleton definition. */ export interface PageDef extends ImportableSchemaBase { data: PageDataSchema; /** Lifecycle events that trigger data loading. */ events: EventSchema[]; /** Page actions (provider calls, navigation, etc.). */ actions: PageActionSchema[]; /** UI component declarations that make up the page skeleton. */ components: ComponentSchema[]; /** Whether the driver should generate page-level loading / error / empty state wrappers. */ handleStates?: boolean; } /** Define a page skeleton. */ export function definePageDef( name: string, schema: Omit, ): PageDef { return { name, ...schema }; }