/** * Dashboard config — typy odpowiadające JSON Schema configu. * * Format pliku: JSONC (JSON z komentarzami dla biznesu). * Walidacja: Ajv przy load + `echelon-lint` semantyczne reguły. * * W prod: config sygnowany (JWS) + verify przed executionem. */ import type { AclKey } from '../acl/index.js'; import type { ComplianceRuleRef } from '../compliance/index.js'; import type { FeatureFlagRef } from '../feature-flags/index.js'; /** Rezerwowane pole — na razie nieużywane, ale wymagane w każdym configu. */ export type SchemaVersion = string & { readonly _brand: 'SchemaVersion'; }; export interface PageConfig { readonly $schemaVersion: SchemaVersion; readonly page: PageSection; } export interface PageSection { readonly id: string; readonly title: string; readonly acl?: { readonly require?: AclKey; }; readonly context?: Readonly>; readonly compliance?: DashboardComplianceConfig; readonly datasources?: Readonly>; readonly computed?: Readonly>; readonly layout: LayoutConfig; readonly widgets: Readonly>; readonly eventHandlers?: readonly EventHandlerConfig[]; readonly errorPolicy?: ErrorPolicyConfig; /** * Cykle życia dashboardu — deklaratywne akcje wykonywane automatycznie. * Wszystkie używają tej samej listy akcji co `eventHandlers.do`. * - `onInit` — po pierwszym wyrenderowaniu (load + bootstrap datasources) * - `onDestroy`— przy wyjściu z dashboardu (nawigacja / unmount) * - `onFocus` — gdy user wraca do karty z innej (visibility API) * - `onBlur` — gdy karta przestaje być aktywna */ readonly lifecycle?: { readonly onInit?: readonly EventAction[]; readonly onDestroy?: readonly EventAction[]; readonly onFocus?: readonly EventAction[]; readonly onBlur?: readonly EventAction[]; }; } export interface DashboardComplianceConfig { readonly subject: string; readonly required: readonly ComplianceRuleRef[]; } export type DatasourceKind = 'transport' | 'local' | 'computed' | 'pipeline'; export interface DatasourceConfig { /** Domyślnie 'transport' (back-compat — pole `transport` istnieje). */ readonly kind?: DatasourceKind; readonly transport?: string; readonly channel?: string; readonly endpoint?: string; readonly params?: Readonly>; readonly refetchOn?: readonly string[]; readonly throttleMs?: number; readonly shape?: string; readonly initial?: unknown; readonly fn?: string; readonly inputs?: readonly string[]; readonly pipelineId?: string; readonly cache?: CacheConfig; readonly featureFlag?: FeatureFlagRef; readonly persistence?: PersistenceConfig; } /** * Konfiguracja persistencji datasource. Pozwala na przywracanie stanu (np. * niedokończonego formularza) po reloadzie, opcjonalnie też zapisuje draft na * serwerze. */ export interface PersistenceConfig { /** Gdzie trzymać lokalną kopię. Default 'storage' (STORAGE token z DI). */ readonly adapter?: 'storage' | 'memory'; /** Klucz w storage. Default: `echelon.ds.`. */ readonly key?: string; /** TTL lokalnej kopii (ms). Po tym czasie snapshot znika. */ readonly ttlMs?: number; /** Oznacz wartość jako sensitive — implementacja Storage powinna ją szyfrować. */ readonly encrypted?: boolean; /** Auto-save co N ms (debounce). 0 / undefined = zapis przy każdym push. */ readonly autoSaveMs?: number; /** Opcjonalny endpoint do zapisu draftu po stronie serwera. */ readonly draftEndpoint?: string; /** Jak rozwiązywać konflikt hydracji ze stanem serwera. Default: 'server-wins'. */ readonly conflictResolution?: 'server-wins' | 'client-wins' | 'newest-wins'; } /** Strategia odświeżania po wykryciu TTL. */ export type CacheStrategy = /** Wartość staje się `stale`, subskrybenci muszą wywołać `refresh()` ręcznie. */ 'lazy' /** Emituj stare dane + automatycznie w tle wywołaj `refresh()`. */ | 'stale-while-revalidate' /** Po TTL datasource zostaje automatycznie przeładowany (hard refresh). */ | 'hard-refresh'; export interface CacheConfig { /** Time-to-live w ms. Po tym czasie snapshot trafia do statusu `stale`. */ readonly ttl?: number; /** Strategia po wygaśnięciu TTL. Default: 'lazy'. */ readonly strategy?: CacheStrategy; /** Tagi używane przez `dataBus.invalidateByTags(...)` do bulk-invalidation. */ readonly tags?: readonly string[]; /** Lista nazw eventów (EventBus), po których datasource jest invalidowany. */ readonly invalidateOn?: readonly string[]; } export interface ComputedConfig { readonly expr: string; readonly deps: readonly string[]; } export interface LayoutConfig { readonly type: string; readonly cols?: number; readonly items: readonly LayoutItem[]; } export interface LayoutItem { readonly widget: string; readonly x?: number; readonly y?: number; readonly w?: number; readonly h?: number; } export interface WidgetConfig { readonly type: string; /** * @deprecated Migracja na `inPorts` (PortSource per port). Stary format wspierany * przez page-renderer dla backwards compat — nowy generator wystawia `inPorts`. */ readonly bind?: Readonly>; /** * @deprecated Statyczna konfiguracja przeniesiona do pola `config`. `options` * zachowane dla backwards compat — runtime czyta `config ?? options`. */ readonly options?: Readonly>; /** * Statyczna konfiguracja widgetu (kolumny tabeli, etykiety, layout) — niezmienna w runtime. * Następca `options`. Page-renderer scala oba: `config ?? options`. */ readonly config?: Readonly>; /** * Wejścia widgetu — port name → źródło danych (literal | datasource | session | transform). * Następca `bind`. Page-renderer resolveuje przez `resolvePortSourceSnapshot`. */ readonly inPorts?: Readonly>; /** * Wyjścia widgetu — port name → lista akcji (multi-target). Następca `eventHandlers`. * Każdy klucz to nazwa eventu emitowanego przez widget; wartość to `PortTarget[]`. */ readonly outPorts?: Readonly>; readonly acl?: { readonly require?: AclKey; }; readonly validation?: readonly ValidationRule[]; readonly actions?: readonly ActionConfig[]; readonly schema?: Readonly>; /** * Warunek pokazania widgetu. Akceptuje: * - string — ścieżka `datasource.path`, render gdy truthy * - obiekt — operator DSL (patrz `WidgetCondition`) */ readonly when?: string | WidgetCondition; /** * Dev mode — pokazuje overlay "info" na widget'cie. Kliknięcie otwiera panel * ze zresolvowanymi inputs, bindingami i informacjami z manifestu. Przydatne * do debugowania configów. */ readonly debug?: boolean; /** * Feature flag gate — widget jest renderowany wyłącznie gdy flaga jest * włączona (i opcjonalnie zwraca oczekiwany wariant). */ readonly featureFlag?: FeatureFlagRef; } export type WidgetCondition = { readonly path: string; readonly eq?: unknown; } | { readonly path: string; readonly neq?: unknown; } | { readonly path: string; readonly in?: readonly unknown[]; } | { readonly path: string; readonly notIn?: readonly unknown[]; } | { readonly path: string; readonly gt?: number; } | { readonly path: string; readonly gte?: number; } | { readonly path: string; readonly lt?: number; } | { readonly path: string; readonly lte?: number; } | { readonly path: string; readonly exists?: boolean; } | { readonly path: string; readonly truthy?: boolean; } | { readonly path: string; readonly empty?: boolean; } | { readonly and: readonly (string | WidgetCondition)[]; } | { readonly or: readonly (string | WidgetCondition)[]; } | { readonly not: string | WidgetCondition; }; export interface ValidationRule { readonly rule: string; readonly message: string; } export interface ActionConfig { readonly id: string; readonly label?: string; readonly acl?: AclKey; readonly confirm?: { readonly template: string; }; readonly preflight?: readonly Readonly>[]; readonly emit?: { readonly event: string; readonly payload: string; }; } export interface EventHandlerConfig { readonly on: string; readonly do: readonly EventAction[]; /** Handler uruchamiany tylko gdy feature flag jest włączona. */ readonly featureFlag?: FeatureFlagRef; } export type EventAction = { readonly call: string; readonly with?: string; } | { readonly emit: string; readonly payload?: string | Readonly>; } | { readonly setDatasource: string; readonly from: string; } | { readonly mergeDatasource: string; readonly from: string; } | { readonly clearDatasource: string; }; export type ErrorUxKind = 'inline' | 'toast' | 'modal' | 'banner' | 'errorBoundary' | 'flashWidget'; export interface ErrorPolicyConfig { readonly datasources?: Readonly>; readonly actions?: Readonly>; }>>; } /** * Circuit breaker — otwiera się po `failureThreshold` kolejnych błędów. W stanie * otwartym: żądania są natychmiast odrzucane (nie wysyłane do transportu) i * UI powinno pokazać degraded state (np. stale cache). Po `timeoutMs` przechodzi * w stan half-open — dopuszcza próbne żądanie; po `successThreshold` udanych * odpowiedziach wraca do `closed`. */ export interface CircuitBreakerConfig { readonly failureThreshold: number; readonly successThreshold: number; readonly timeoutMs: number; /** Co robić gdy jest otwarty. Default 'lastKnown'. */ readonly fallback?: 'lastKnown' | 'empty' | 'error'; } /** * Bulkhead — limit równoległych żądań do datasource / grupy. Nowe żądania * czekają w kolejce (maksymalnie `maxQueue`), nadmiarowe są odrzucane. */ export interface BulkheadConfig { readonly maxConcurrent: number; readonly maxQueue?: number; } //# sourceMappingURL=index.d.ts.map