@richardmcquiston01/dashboard-widgets-toolkit 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/payload.ts","../src/core/compat.ts","../src/core/definition.ts","../src/core/format.ts","../src/core/layout.ts","../src/core/result.ts","../src/core/url.ts","../src/core/validate.ts","../src/core/resolve.ts","../src/core/scale.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Widget data payloads, one shape per kind, discriminated by `kind`.\n *\n * The kind names are upper case to stay compatible with Maker Toolkit's\n * `WidgetViewType` (`TEXT`, `GAUGE`, `TABLE`, `GRAPH`). `KPI`, `BAR_LIST`\n * and `ALERT_LIST` are new. Every payload is plain JSON: strings, finite\n * numbers, booleans, null, arrays and objects. No dates (send ISO strings),\n * no functions, no class instances.\n */\n\n/** Every widget kind, in a stable order. */\nexport const WIDGET_KINDS = [\n 'TEXT',\n 'KPI',\n 'GAUGE',\n 'TABLE',\n 'BAR_LIST',\n 'ALERT_LIST',\n 'GRAPH',\n] as const;\n\nexport type WidgetKind = (typeof WIDGET_KINDS)[number];\n\nexport function isWidgetKind(value: unknown): value is WidgetKind {\n return (\n typeof value === 'string' &&\n (WIDGET_KINDS as readonly string[]).includes(value)\n );\n}\n\n/** How a number is shown: a plain count, money, or a fraction as a percent. */\nexport const VALUE_FORMATS = ['number', 'currency', 'percent'] as const;\n\nexport type ValueFormat = (typeof VALUE_FORMATS)[number];\n\n/** A single headline value as text, e.g. \"12\" or \"Open\". */\nexport interface TextWidgetData {\n readonly kind: 'TEXT';\n readonly value: string;\n readonly label: string;\n}\n\n/**\n * A stat tile: one number, optionally compared with the previous period.\n *\n * `value` and `previous` are in major units for `currency` (12.5 is $12.50)\n * and fractions for `percent` (0.25 is 25%).\n */\nexport interface KpiWidgetData {\n readonly kind: 'KPI';\n readonly value: number;\n /** The same measure for the previous period; null or absent for none. */\n readonly previous?: number | null;\n readonly format: ValueFormat;\n /** ISO 4217 code for `currency`, e.g. \"USD\". Defaults to USD. */\n readonly currency?: string;\n readonly label: string;\n /** Short context under the value, e.g. \"Incl. shipping and tax\". */\n readonly hint?: string;\n /** Whether a rise is good news (default true). Colours the change. */\n readonly higherIsBetter?: boolean;\n}\n\n/** A value against a maximum, drawn as a meter. */\nexport interface GaugeWidgetData {\n readonly kind: 'GAUGE';\n readonly value: number;\n readonly max: number;\n readonly label: string;\n}\n\nexport interface TableColumn {\n readonly label: string;\n /** Right-aligned, tabular figures. */\n readonly numeric?: boolean;\n}\n\nexport interface TableCell {\n readonly text: string;\n /** Renders the cell as a link (http, https, mailto or relative only). */\n readonly href?: string;\n}\n\nexport interface TableWidgetData {\n readonly kind: 'TABLE';\n readonly columns: readonly TableColumn[];\n /** One array of cells per row, each as long as `columns`. */\n readonly rows: readonly (readonly TableCell[])[];\n /** A note under the table, e.g. \"and 12 more\". */\n readonly footer?: string;\n}\n\nexport interface BarListItem {\n readonly label: string;\n readonly value: number;\n /** Text shown beside the bar; defaults to the formatted value. */\n readonly display?: string;\n}\n\n/**\n * Labelled horizontal bars, e.g. ratings or purchases by country. Bars are a\n * share of `total` when it is given, otherwise of the largest value.\n */\nexport interface BarListWidgetData {\n readonly kind: 'BAR_LIST';\n readonly items: readonly BarListItem[];\n readonly total?: number;\n}\n\nexport interface AlertListItem {\n readonly title: string;\n /** Renders the title as a link (http, https, mailto or relative only). */\n readonly href?: string;\n /** A small square image (http, https or relative only). */\n readonly thumbnailUrl?: string;\n /** The short figure on the right, e.g. \"2 left\" or \"31 views\". */\n readonly valueLabel: string;\n /** A secondary line under the title. */\n readonly detail?: string;\n}\n\n/**\n * Things that need attention (low stock, stale listings...). `items` may be\n * the first few of `total`; the renderer says \"and N more\".\n */\nexport interface AlertListWidgetData {\n readonly kind: 'ALERT_LIST';\n readonly items: readonly AlertListItem[];\n readonly total: number;\n /** Shown when there is nothing to flag, e.g. \"Nothing low on stock.\" */\n readonly emptyText: string;\n}\n\nexport interface GraphPoint {\n /** The category or date label on the x axis, e.g. \"Oct 2026\". */\n readonly label: string;\n readonly value: number;\n}\n\nexport interface GraphSeries {\n readonly name: string;\n readonly points: readonly GraphPoint[];\n}\n\n/** The most series a graph may carry: the categorical palette's eight slots. */\nexport const MAX_GRAPH_SERIES = 8;\n\n/**\n * A bar (grouped for several series) or line chart. All series share the\n * x labels of the first series, by position, and one y axis.\n */\nexport interface GraphWidgetData {\n readonly kind: 'GRAPH';\n readonly series: readonly GraphSeries[];\n readonly chartType: 'bar' | 'line';\n readonly valueFormat: ValueFormat;\n /** ISO 4217 code for `currency`. Defaults to USD. */\n readonly currency?: string;\n /** Heading for the label column in the table view, e.g. \"Month\". */\n readonly xLabel?: string;\n}\n\n/** Any widget's data, discriminated by `kind`. */\nexport type WidgetData =\n | TextWidgetData\n | KpiWidgetData\n | GaugeWidgetData\n | TableWidgetData\n | BarListWidgetData\n | AlertListWidgetData\n | GraphWidgetData;\n\n/** The payload type for one kind, e.g. `WidgetDataOf<'KPI'>`. */\nexport type WidgetDataOf<K extends WidgetKind> = Extract<\n WidgetData,\n { kind: K }\n>;\n\n/**\n * A widget with nothing to show yet, with the reason as text (\"No orders\n * synced yet.\"). Any widget may return this instead of its kind's payload.\n */\nexport interface WidgetEmptyState {\n readonly empty: true;\n readonly text: string;\n}\n\n/** What a provider or API returns for a widget: its data, or an empty state. */\nexport type WidgetPayload = WidgetData | WidgetEmptyState;\n\n/** The default text for an empty widget. */\nexport const DEFAULT_EMPTY_TEXT = 'Nothing to show yet.';\n\n/** Builds an empty state. */\nexport function emptyWidget(\n text: string = DEFAULT_EMPTY_TEXT\n): WidgetEmptyState {\n return { empty: true, text };\n}\n\nexport function isWidgetEmptyState(\n payload: WidgetPayload\n): payload is WidgetEmptyState {\n return 'empty' in payload && payload.empty === true;\n}\n\n/**\n * The empty text for a payload with nothing in it (a table with no rows, a\n * list with no items, a graph with no points), or null when it has content.\n * TEXT, KPI and GAUGE always have content.\n */\nexport function emptyTextFor(payload: WidgetPayload): string | null {\n if (isWidgetEmptyState(payload)) {\n return payload.text;\n }\n switch (payload.kind) {\n case 'TABLE':\n return payload.rows.length === 0 ? DEFAULT_EMPTY_TEXT : null;\n case 'BAR_LIST':\n return payload.items.length === 0 ? DEFAULT_EMPTY_TEXT : null;\n case 'ALERT_LIST':\n return payload.items.length === 0 ? payload.emptyText : null;\n case 'GRAPH':\n return payload.series.every((series) => series.points.length === 0)\n ? DEFAULT_EMPTY_TEXT\n : null;\n case 'TEXT':\n case 'KPI':\n case 'GAUGE':\n return null;\n }\n}\n","/**\n * Maker Toolkit compatibility. Its API (`apps/api/src/widgets`) serves\n * `TEXT`, `GAUGE`, `TABLE` and `GRAPH` payloads; `TEXT` and `GAUGE` are\n * unchanged here, while `TABLE` and `GRAPH` grew richer shapes. These\n * helpers upgrade the older shapes so `validateWidgetData` accepts them.\n */\n\nimport type { WidgetDefinition } from './definition.js';\nimport { isWidgetKind } from './payload.js';\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((v) => typeof v === 'string');\n}\n\n/**\n * Upgrades a Maker Toolkit payload to this package's shape:\n *\n * - `TABLE` `{columns: string[], rows: string[][]}` → `{label}` columns and\n * `{text}` cells.\n * - `GRAPH` `{points}` → one unnamed bar series with `valueFormat: 'number'`.\n *\n * Anything else, including payloads already in the new shape, is returned\n * unchanged. Validate the result with `validateWidgetData`.\n */\nexport function upgradeLegacyWidgetData(value: unknown): unknown {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return value;\n }\n const record = value as Readonly<Record<string, unknown>>;\n if (\n record['kind'] === 'TABLE' &&\n isStringArray(record['columns']) &&\n Array.isArray(record['rows']) &&\n record['rows'].every(isStringArray)\n ) {\n const rows = record['rows'] as string[][];\n return {\n ...record,\n columns: record['columns'].map((label) => ({ label })),\n rows: rows.map((row) => row.map((text) => ({ text }))),\n };\n }\n if (\n record['kind'] === 'GRAPH' &&\n Array.isArray(record['points']) &&\n record['series'] === undefined\n ) {\n const { points, ...rest } = record;\n return {\n ...rest,\n series: [{ name: 'Value', points }],\n chartType: 'bar',\n valueFormat: 'number',\n };\n }\n return value;\n}\n\n/** Maker Toolkit's served widget definition (`WidgetDefinition` in its API). */\nexport interface LegacyWidgetDefinition {\n readonly widgetKey: string;\n readonly title: string;\n readonly description: string | null;\n readonly viewType: string;\n readonly sortOrder: number;\n}\n\n/**\n * Maps a Maker Toolkit definition onto this package's. Returns null when\n * the view type isn't a known kind.\n */\nexport function fromLegacyDefinition(\n legacy: LegacyWidgetDefinition\n): WidgetDefinition | null {\n if (!isWidgetKind(legacy.viewType)) {\n return null;\n }\n return {\n key: legacy.widgetKey,\n title: legacy.title,\n ...(legacy.description === null ? {} : { description: legacy.description }),\n kind: legacy.viewType,\n sortOrder: legacy.sortOrder,\n };\n}\n","import type { WidgetKind } from './payload.js';\n\n/** A size hint for grid layouts; renderers may map it to column spans. */\nexport const WIDGET_SIZES = ['small', 'medium', 'large', 'full'] as const;\n\nexport type WidgetSize = (typeof WIDGET_SIZES)[number];\n\n/**\n * What a widget is, independent of its data. Mirrors Maker Toolkit's\n * `widget` table (`widget_key`, `title`, `description`, `view_type`,\n * `roles`, `sort_order`, `active`).\n */\nexport interface WidgetDefinition {\n /** Stable, unique id. Layouts and providers are keyed by it. */\n readonly key: string;\n readonly title: string;\n readonly description?: string;\n readonly kind: WidgetKind;\n /** Lower comes first. Default 0; ties keep definition order. */\n readonly sortOrder?: number;\n /** Roles allowed to see it. Absent or empty means everyone. */\n readonly roles?: readonly string[];\n /** False hides it from every user. Default true. */\n readonly active?: boolean;\n readonly defaultSize?: WidgetSize;\n}\n\n/**\n * Identity helper that keeps the literal `kind` (so typed providers can be\n * checked against it) and gives a definition its type without a cast.\n */\nexport function defineWidget<const D extends WidgetDefinition>(\n definition: D\n): D {\n return definition;\n}\n\n/** Definitions sorted by `sortOrder` (stable: ties keep their input order). */\nexport function sortDefinitions<D extends WidgetDefinition>(\n definitions: readonly D[]\n): D[] {\n return definitions\n .map((definition, index) => ({ definition, index }))\n .sort(\n (a, b) =>\n (a.definition.sortOrder ?? 0) - (b.definition.sortOrder ?? 0) ||\n a.index - b.index\n )\n .map(({ definition }) => definition);\n}\n\n/** Whether a widget is active and visible to someone with these roles. */\nexport function isWidgetVisibleTo(\n definition: WidgetDefinition,\n roles: readonly string[] | undefined\n): boolean {\n if (definition.active === false) {\n return false;\n }\n if (definition.roles === undefined || definition.roles.length === 0) {\n return true;\n }\n if (roles === undefined) {\n return false;\n }\n return definition.roles.some((role) => roles.includes(role));\n}\n","/**\n * Number formatting via `Intl`, with an injectable locale (undefined uses\n * the runtime's default), plus KPI period-over-period deltas.\n */\n\nimport type { ValueFormat } from './payload.js';\n\nexport type Locale = string | readonly string[] | undefined;\n\nexport interface FormatOptions {\n readonly locale?: Locale;\n /** ISO 4217 code for `currency`. Default \"USD\". */\n readonly currency?: string;\n /** \"1.2K\" style, for axis ticks. */\n readonly compact?: boolean;\n}\n\nexport const DEFAULT_CURRENCY = 'USD';\n\nfunction localeArgument(locale: Locale): string | string[] | undefined {\n return locale === undefined || typeof locale === 'string'\n ? locale\n : [...locale];\n}\n\nfunction numberFormat(\n locale: Locale,\n options: Intl.NumberFormatOptions\n): Intl.NumberFormat {\n try {\n return new Intl.NumberFormat(localeArgument(locale), options);\n } catch {\n // An invalid locale tag or currency code: fall back to the default\n // locale and a plain number rather than throwing mid-render.\n const { style: _style, currency: _currency, ...rest } = options;\n return new Intl.NumberFormat(undefined, rest);\n }\n}\n\n/**\n * Formats `value` as a count (\"1,284\"), money (\"$12.50\", major units) or a\n * percent (\"25%\" from 0.25).\n */\nexport function formatValue(\n value: number,\n format: ValueFormat,\n options: FormatOptions = {}\n): string {\n if (!Number.isFinite(value)) {\n return '—';\n }\n const compact: Intl.NumberFormatOptions = options.compact\n ? { notation: 'compact', maximumFractionDigits: 1 }\n : {};\n switch (format) {\n case 'number':\n return numberFormat(options.locale, {\n maximumFractionDigits: 2,\n ...compact,\n }).format(value);\n case 'currency': {\n const currency: string = (\n options.currency ?? DEFAULT_CURRENCY\n ).toUpperCase();\n const formatter = numberFormat(options.locale, {\n style: 'currency',\n currency,\n ...compact,\n });\n const text: string = formatter.format(value);\n // The fallback formatter has no currency, so say which one it was.\n return formatter.resolvedOptions().style === 'currency'\n ? text\n : `${text} ${currency}`;\n }\n case 'percent':\n return numberFormat(options.locale, {\n style: 'percent',\n maximumFractionDigits: 1,\n ...compact,\n }).format(value);\n }\n}\n\n/** A plain count, e.g. \"1,284\". */\nexport function formatCount(value: number, locale?: Locale): string {\n return formatValue(value, 'number', { locale });\n}\n\n/** `part` as a whole percentage of `total` (0 when total is 0 or less). */\nexport function shareOf(part: number, total: number): number {\n return total <= 0 ? 0 : Math.round((part / total) * 100);\n}\n\n/**\n * Change from `previous` to `current` in percent (unrounded), or null when\n * there is nothing to compare: no previous value, or a previous of 0.\n */\nexport function percentChange(\n current: number,\n previous: number | null | undefined\n): number | null {\n if (\n previous === null ||\n previous === undefined ||\n previous === 0 ||\n !Number.isFinite(previous) ||\n !Number.isFinite(current)\n ) {\n return null;\n }\n return ((current - previous) / Math.abs(previous)) * 100;\n}\n\n/**\n * \"+12%\", \"-8%\", \"±0%\". Below 10% one decimal is kept (\"+2.5%\"), so small\n * changes don't round away.\n */\nexport function formatPercentChange(change: number, locale?: Locale): string {\n const digits: number = Math.abs(change) < 10 ? 1 : 0;\n const rounded: number = Number(change.toFixed(digits));\n if (rounded === 0) {\n return '±0%';\n }\n return numberFormat(locale, {\n style: 'percent',\n maximumFractionDigits: digits,\n signDisplay: 'exceptZero',\n }).format(rounded / 100);\n}\n\nexport type DeltaDirection = 'up' | 'down' | 'flat';\nexport type DeltaSentiment = 'good' | 'bad' | 'neutral';\n\nexport interface KpiDelta {\n /** Percent change, unrounded. */\n readonly percent: number;\n readonly direction: DeltaDirection;\n /** Direction combined with whether higher is better. */\n readonly sentiment: DeltaSentiment;\n /** \"+12%\" */\n readonly text: string;\n /** \"+12% vs previous period\" */\n readonly description: string;\n}\n\nexport interface KpiDeltaOptions {\n /** Default true. */\n readonly higherIsBetter?: boolean;\n readonly locale?: Locale;\n /** What the change is against. Default \"previous period\". */\n readonly comparisonLabel?: string;\n}\n\n/** The default comparison wording in delta descriptions. */\nexport const DEFAULT_COMPARISON_LABEL = 'previous period';\n\n/**\n * The period-over-period change for a KPI, or null when it can't be worked\n * out (no previous value, or a previous of 0).\n */\nexport function kpiDelta(\n current: number,\n previous: number | null | undefined,\n options: KpiDeltaOptions = {}\n): KpiDelta | null {\n const percent: number | null = percentChange(current, previous);\n if (percent === null) {\n return null;\n }\n const text: string = formatPercentChange(percent, options.locale);\n const direction: DeltaDirection =\n text === '±0%' ? 'flat' : percent > 0 ? 'up' : 'down';\n const higherIsBetter: boolean = options.higherIsBetter ?? true;\n const sentiment: DeltaSentiment =\n direction === 'flat'\n ? 'neutral'\n : (direction === 'up') === higherIsBetter\n ? 'good'\n : 'bad';\n return {\n percent,\n direction,\n sentiment,\n text,\n description: `${text} vs ${options.comparisonLabel ?? DEFAULT_COMPARISON_LABEL}`,\n };\n}\n","/**\n * A viewer's dashboard customisation: order, hidden and minimised widgets.\n * Pure functions over a small JSON-serialisable object. Persist it however\n * you like (a settings table, localStorage); `parseLayout` tolerates\n * anything, so a corrupt saved value never breaks the dashboard.\n *\n * Generalised from Maker Toolkit's desktop `dashboard-layout.ts`.\n */\n\n/** What layout functions need from a widget definition. */\nexport interface LayoutItem {\n readonly key: string;\n readonly sortOrder?: number;\n}\n\nexport interface DashboardLayout {\n /** Widget keys in display order. Keys not listed follow, by sortOrder. */\n readonly order: readonly string[];\n /** Widget keys removed from the dashboard (restorable). */\n readonly hidden: readonly string[];\n /** Widget keys collapsed to their header. */\n readonly minimized: readonly string[];\n}\n\nexport const EMPTY_LAYOUT: DashboardLayout = Object.freeze({\n order: Object.freeze([]) as readonly string[],\n hidden: Object.freeze([]) as readonly string[],\n minimized: Object.freeze([]) as readonly string[],\n});\n\nfunction uniqueStrings(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n const seen = new Set<string>();\n for (const entry of value) {\n if (typeof entry === 'string' && entry !== '') seen.add(entry);\n }\n return [...seen];\n}\n\n/**\n * Reads a saved layout: a JSON string or an already-parsed object. Missing,\n * corrupt or wrongly typed values give the empty layout (or empty lists for\n * the fields that are wrong); non-string and duplicate keys are dropped.\n */\nexport function parseLayout(raw: unknown): DashboardLayout {\n let value: unknown = raw;\n if (typeof raw === 'string') {\n try {\n value = JSON.parse(raw);\n } catch {\n return EMPTY_LAYOUT;\n }\n }\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return EMPTY_LAYOUT;\n }\n const record = value as Readonly<Record<string, unknown>>;\n const order: string[] = uniqueStrings(record['order']);\n const hidden: string[] = uniqueStrings(record['hidden']);\n const minimized: string[] = uniqueStrings(record['minimized']);\n if (order.length === 0 && hidden.length === 0 && minimized.length === 0) {\n return EMPTY_LAYOUT;\n }\n return { order, hidden, minimized };\n}\n\n/** The JSON string to persist. */\nexport function serializeLayout(layout: DashboardLayout): string {\n return JSON.stringify({\n order: [...layout.order],\n hidden: [...layout.hidden],\n minimized: [...layout.minimized],\n });\n}\n\nfunction bySortOrder<T extends LayoutItem>(items: readonly T[]): T[] {\n return items\n .map((item, index) => ({ item, index }))\n .sort(\n (a, b) =>\n (a.item.sortOrder ?? 0) - (b.item.sortOrder ?? 0) || a.index - b.index\n )\n .map(({ item }) => item);\n}\n\n/**\n * The widgets to show, in order: saved keys first (when still present),\n * then widgets the layout doesn't know yet, by sortOrder. Hidden widgets\n * are left out.\n */\nexport function visibleWidgets<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout\n): T[] {\n const hidden = new Set<string>(layout.hidden);\n const visible: T[] = definitions.filter((d) => !hidden.has(d.key));\n const byKey = new Map<string, T>(visible.map((d) => [d.key, d]));\n const ordered: T[] = [];\n for (const key of layout.order) {\n const definition: T | undefined = byKey.get(key);\n if (definition !== undefined) {\n ordered.push(definition);\n byKey.delete(key);\n }\n }\n for (const definition of bySortOrder(visible)) {\n if (byKey.has(definition.key)) ordered.push(definition);\n }\n return ordered;\n}\n\n/** Hidden widgets, by sortOrder, for a \"restore\" menu. */\nexport function hiddenWidgets<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout\n): T[] {\n const hidden = new Set<string>(layout.hidden);\n return bySortOrder(definitions.filter((d) => hidden.has(d.key)));\n}\n\n/**\n * Moves `key` to `toIndex` within the current visible order. Returns the\n * same layout object when the key isn't visible or the index is out of\n * range, so callers can skip a save.\n */\nexport function moveWidget<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout,\n key: string,\n toIndex: number\n): DashboardLayout {\n const current: string[] = visibleWidgets(definitions, layout).map(\n (d) => d.key\n );\n const fromIndex: number = current.indexOf(key);\n if (\n fromIndex === -1 ||\n !Number.isInteger(toIndex) ||\n toIndex < 0 ||\n toIndex >= current.length ||\n toIndex === fromIndex\n ) {\n return layout;\n }\n const next: string[] = [...current];\n next.splice(fromIndex, 1);\n next.splice(toIndex, 0, key);\n return { ...layout, order: next };\n}\n\n/** Moves `key` by `offset` places (negative is earlier). Clamped at the ends. */\nexport function moveWidgetBy<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout,\n key: string,\n offset: number\n): DashboardLayout {\n const current: string[] = visibleWidgets(definitions, layout).map(\n (d) => d.key\n );\n const fromIndex: number = current.indexOf(key);\n if (fromIndex === -1) return layout;\n const toIndex: number = Math.max(\n 0,\n Math.min(current.length - 1, fromIndex + Math.trunc(offset))\n );\n return moveWidget(definitions, layout, key, toIndex);\n}\n\n/** Moves `key` one place earlier. */\nexport function moveWidgetUp<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n return moveWidgetBy(definitions, layout, key, -1);\n}\n\n/** Moves `key` one place later. */\nexport function moveWidgetDown<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n return moveWidgetBy(definitions, layout, key, 1);\n}\n\nexport function isHidden(layout: DashboardLayout, key: string): boolean {\n return layout.hidden.includes(key);\n}\n\nexport function isMinimized(layout: DashboardLayout, key: string): boolean {\n return layout.minimized.includes(key);\n}\n\n/** Hides `key`. No-op (same object) if already hidden. */\nexport function hideWidget(\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n if (isHidden(layout, key)) return layout;\n return { ...layout, hidden: [...layout.hidden, key] };\n}\n\n/** Shows `key` again, expanded. No-op (same object) if not hidden. */\nexport function showWidget(\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n if (!isHidden(layout, key)) return layout;\n return {\n ...layout,\n hidden: layout.hidden.filter((k) => k !== key),\n minimized: layout.minimized.filter((k) => k !== key),\n };\n}\n\n/** Hides or shows `key` (showing also clears its minimised state). */\nexport function toggleHidden(\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n return isHidden(layout, key)\n ? showWidget(layout, key)\n : hideWidget(layout, key);\n}\n\n/** Collapses `key` to its header. No-op (same object) if already minimised. */\nexport function minimizeWidget(\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n if (isMinimized(layout, key)) return layout;\n return { ...layout, minimized: [...layout.minimized, key] };\n}\n\n/** Expands `key`. No-op (same object) if not minimised. */\nexport function restoreWidget(\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n if (!isMinimized(layout, key)) return layout;\n return { ...layout, minimized: layout.minimized.filter((k) => k !== key) };\n}\n\n/** Minimises or restores `key`. */\nexport function toggleMinimized(\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n return isMinimized(layout, key)\n ? restoreWidget(layout, key)\n : minimizeWidget(layout, key);\n}\n\n/**\n * Drops keys for widgets that no longer exist. Only pass the full list of\n * definitions (not a role-filtered one), or a viewer's settings for widgets\n * they temporarily can't see are lost.\n */\nexport function pruneLayout<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout\n): DashboardLayout {\n const known = new Set<string>(definitions.map((d) => d.key));\n const keep = (keys: readonly string[]): string[] =>\n keys.filter((k) => known.has(k));\n const next: DashboardLayout = {\n order: keep(layout.order),\n hidden: keep(layout.hidden),\n minimized: keep(layout.minimized),\n };\n return next.order.length === layout.order.length &&\n next.hidden.length === layout.hidden.length &&\n next.minimized.length === layout.minimized.length\n ? layout\n : next;\n}\n","/**\n * A small Result type. Functions in this package return a Result rather than\n * throwing, so the caller has to look at the outcome. `throw` is reserved for\n * programmer error.\n */\n\nexport interface Ok<T> {\n readonly ok: true;\n readonly value: T;\n}\n\nexport interface Err {\n readonly ok: false;\n /** Specific enough to act on: names the field, the widget and the problem. */\n readonly error: string;\n}\n\nexport type Result<T> = Ok<T> | Err;\n\nexport function ok<T>(value: T): Ok<T> {\n return { ok: true, value };\n}\n\nexport function err(error: string): Err {\n return { ok: false, error };\n}\n\n/** Turns an unknown thrown value into a readable message. */\nexport function describeUnknownError(cause: unknown): string {\n if (cause instanceof Error) {\n return cause.message === '' ? cause.name : cause.message;\n }\n if (typeof cause === 'string') {\n return cause;\n }\n try {\n const json: string | undefined = JSON.stringify(cause);\n return json ?? String(cause);\n } catch {\n return String(cause);\n }\n}\n","/**\n * Link and image URL checks. Payloads often come from an API, so a link is\n * only rendered when it can't run script: http(s), mailto, or a relative\n * path. Nothing here fetches anything.\n */\n\nconst SCHEME_PATTERN = /^([a-z][a-z0-9+.-]*):/i;\n\n// Browsers ignore ASCII control characters and whitespace inside a scheme\n// (\"java\\tscript:\"), so strip them before reading it.\n// eslint-disable-next-line no-control-regex\nconst IGNORED_IN_SCHEME = /[\\u0000- \\u007f]/g;\n\nfunction schemeOf(url: string): string | null {\n const match: RegExpExecArray | null = SCHEME_PATTERN.exec(\n url.replace(IGNORED_IN_SCHEME, '')\n );\n return match === null ? null : (match[1] ?? '').toLowerCase();\n}\n\n/** Whether `url` is safe as an anchor href: http, https, mailto or relative. */\nexport function isSafeHref(url: string): boolean {\n if (url.trim() === '') {\n return false;\n }\n const scheme: string | null = schemeOf(url);\n return (\n scheme === null ||\n scheme === 'http' ||\n scheme === 'https' ||\n scheme === 'mailto'\n );\n}\n\n/** Whether `url` is safe as an image source: http, https or relative. */\nexport function isSafeImageUrl(url: string): boolean {\n if (url.trim() === '') {\n return false;\n }\n const scheme: string | null = schemeOf(url);\n return scheme === null || scheme === 'http' || scheme === 'https';\n}\n","/**\n * Hand-written validators for widget payloads and definitions, so data from\n * an API can be checked in a client without a schema library. Problems name\n * the widget, the field path and what was wrong, e.g.\n * `Widget \"top-products\" (TABLE): rows[2][0].text must be a string, got number.`\n */\n\nimport { WIDGET_SIZES, type WidgetDefinition } from './definition.js';\nimport {\n MAX_GRAPH_SERIES,\n VALUE_FORMATS,\n WIDGET_KINDS,\n isWidgetKind,\n type WidgetKind,\n type WidgetPayload,\n} from './payload.js';\nimport { err, ok, type Result } from './result.js';\nimport { isSafeHref, isSafeImageUrl } from './url.js';\n\n/** At most this many problems are listed in one error message. */\nexport const MAX_REPORTED_PROBLEMS = 10;\n\nexport interface ValidateWidgetDataOptions {\n /** Named in error messages, e.g. the widget key. */\n readonly widgetKey?: string;\n /** Fails unless the payload is this kind (an empty state always passes). */\n readonly expectedKind?: WidgetKind;\n}\n\ntype Problems = string[];\ntype Record_ = Readonly<Record<string, unknown>>;\n\nfunction describeType(value: unknown): string {\n if (value === null) return 'null';\n if (Array.isArray(value)) return 'array';\n if (typeof value === 'number' && !Number.isFinite(value)) {\n return String(value);\n }\n return typeof value;\n}\n\nfunction isRecord(value: unknown): value is Record_ {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction join(path: string, field: string): string {\n return path === '' ? field : `${path}.${field}`;\n}\n\nfunction requireString(\n record: Record_,\n field: string,\n path: string,\n problems: Problems\n): void {\n const value: unknown = record[field];\n if (typeof value !== 'string') {\n problems.push(\n `${join(path, field)} must be a string, got ${describeType(value)}.`\n );\n }\n}\n\nfunction optionalString(\n record: Record_,\n field: string,\n path: string,\n problems: Problems\n): void {\n if (record[field] !== undefined) {\n requireString(record, field, path, problems);\n }\n}\n\nfunction requireNumber(\n record: Record_,\n field: string,\n path: string,\n problems: Problems\n): void {\n const value: unknown = record[field];\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n problems.push(\n `${join(path, field)} must be a finite number, got ${describeType(value)}.`\n );\n }\n}\n\nfunction optionalNumber(\n record: Record_,\n field: string,\n path: string,\n problems: Problems\n): void {\n if (record[field] !== undefined) {\n requireNumber(record, field, path, problems);\n }\n}\n\nfunction optionalBoolean(\n record: Record_,\n field: string,\n path: string,\n problems: Problems\n): void {\n const value: unknown = record[field];\n if (value !== undefined && typeof value !== 'boolean') {\n problems.push(\n `${join(path, field)} must be a boolean, got ${describeType(value)}.`\n );\n }\n}\n\nfunction optionalUrl(\n record: Record_,\n field: string,\n path: string,\n problems: Problems,\n isSafe: (url: string) => boolean,\n allowed: string\n): void {\n const value: unknown = record[field];\n if (value === undefined) return;\n if (typeof value !== 'string') {\n problems.push(\n `${join(path, field)} must be a string, got ${describeType(value)}.`\n );\n } else if (!isSafe(value)) {\n problems.push(\n `${join(path, field)} must be ${allowed}, got ${JSON.stringify(value.slice(0, 80))}.`\n );\n }\n}\n\nfunction requireArray(\n record: Record_,\n field: string,\n path: string,\n problems: Problems\n): readonly unknown[] | null {\n const value: unknown = record[field];\n if (!Array.isArray(value)) {\n problems.push(\n `${join(path, field)} must be an array, got ${describeType(value)}.`\n );\n return null;\n }\n return value;\n}\n\nfunction requireOneOf(\n record: Record_,\n field: string,\n options: readonly string[],\n path: string,\n problems: Problems\n): void {\n const value: unknown = record[field];\n if (typeof value !== 'string' || !options.includes(value)) {\n problems.push(\n `${join(path, field)} must be one of ${options.map((o) => `\"${o}\"`).join(', ')}, got ${\n typeof value === 'string' ? JSON.stringify(value) : describeType(value)\n }.`\n );\n }\n}\n\n/** Runs `check` on each element that is an object, reporting the others. */\nfunction eachRecord(\n items: readonly unknown[],\n path: string,\n problems: Problems,\n check: (item: Record_, itemPath: string) => void\n): void {\n items.forEach((item: unknown, index: number) => {\n const itemPath = `${path}[${index}]`;\n if (isRecord(item)) {\n check(item, itemPath);\n } else {\n problems.push(\n `${itemPath} must be an object, got ${describeType(item)}.`\n );\n }\n });\n}\n\nconst HREF_RULE = 'an http(s), mailto or relative URL';\nconst IMAGE_RULE = 'an http(s) or relative URL';\n\nfunction checkPayloadFields(\n kind: WidgetKind,\n data: Record_,\n problems: Problems\n): void {\n switch (kind) {\n case 'TEXT':\n requireString(data, 'value', '', problems);\n requireString(data, 'label', '', problems);\n return;\n case 'KPI':\n requireNumber(data, 'value', '', problems);\n if (data['previous'] !== null) {\n optionalNumber(data, 'previous', '', problems);\n }\n requireOneOf(data, 'format', VALUE_FORMATS, '', problems);\n optionalString(data, 'currency', '', problems);\n requireString(data, 'label', '', problems);\n optionalString(data, 'hint', '', problems);\n optionalBoolean(data, 'higherIsBetter', '', problems);\n return;\n case 'GAUGE':\n requireNumber(data, 'value', '', problems);\n requireNumber(data, 'max', '', problems);\n requireString(data, 'label', '', problems);\n if (typeof data['max'] === 'number' && data['max'] <= 0) {\n problems.push(`max must be greater than 0, got ${data['max']}.`);\n }\n return;\n case 'TABLE': {\n const columns = requireArray(data, 'columns', '', problems);\n if (columns !== null) {\n eachRecord(columns, 'columns', problems, (column, path) => {\n requireString(column, 'label', path, problems);\n optionalBoolean(column, 'numeric', path, problems);\n });\n }\n const rows = requireArray(data, 'rows', '', problems);\n if (rows !== null) {\n rows.forEach((row: unknown, rowIndex: number) => {\n const rowPath = `rows[${rowIndex}]`;\n if (!Array.isArray(row)) {\n problems.push(\n `${rowPath} must be an array of cells, got ${describeType(row)}.`\n );\n return;\n }\n if (columns !== null && row.length !== columns.length) {\n problems.push(\n `${rowPath} has ${row.length} cell(s) but there are ${columns.length} column(s).`\n );\n }\n eachRecord(row, rowPath, problems, (cell, cellPath) => {\n requireString(cell, 'text', cellPath, problems);\n optionalUrl(\n cell,\n 'href',\n cellPath,\n problems,\n isSafeHref,\n HREF_RULE\n );\n });\n });\n }\n optionalString(data, 'footer', '', problems);\n return;\n }\n case 'BAR_LIST': {\n const items = requireArray(data, 'items', '', problems);\n if (items !== null) {\n eachRecord(items, 'items', problems, (item, path) => {\n requireString(item, 'label', path, problems);\n requireNumber(item, 'value', path, problems);\n optionalString(item, 'display', path, problems);\n });\n }\n optionalNumber(data, 'total', '', problems);\n return;\n }\n case 'ALERT_LIST': {\n const items = requireArray(data, 'items', '', problems);\n if (items !== null) {\n eachRecord(items, 'items', problems, (item, path) => {\n requireString(item, 'title', path, problems);\n optionalUrl(item, 'href', path, problems, isSafeHref, HREF_RULE);\n optionalUrl(\n item,\n 'thumbnailUrl',\n path,\n problems,\n isSafeImageUrl,\n IMAGE_RULE\n );\n requireString(item, 'valueLabel', path, problems);\n optionalString(item, 'detail', path, problems);\n });\n }\n requireNumber(data, 'total', '', problems);\n requireString(data, 'emptyText', '', problems);\n if (\n items !== null &&\n typeof data['total'] === 'number' &&\n data['total'] < items.length\n ) {\n problems.push(\n `total (${data['total']}) must be at least the number of items (${items.length}).`\n );\n }\n return;\n }\n case 'GRAPH': {\n const series = requireArray(data, 'series', '', problems);\n if (series !== null) {\n if (series.length > MAX_GRAPH_SERIES) {\n problems.push(\n `series has ${series.length} entries; at most ${MAX_GRAPH_SERIES} are allowed (fold the rest into \"Other\").`\n );\n }\n eachRecord(series, 'series', problems, (entry, path) => {\n requireString(entry, 'name', path, problems);\n const points = requireArray(entry, 'points', path, problems);\n if (points !== null) {\n eachRecord(\n points,\n `${path}.points`,\n problems,\n (point, pointPath) => {\n requireString(point, 'label', pointPath, problems);\n requireNumber(point, 'value', pointPath, problems);\n }\n );\n }\n });\n }\n requireOneOf(data, 'chartType', ['bar', 'line'], '', problems);\n requireOneOf(data, 'valueFormat', VALUE_FORMATS, '', problems);\n optionalString(data, 'currency', '', problems);\n optionalString(data, 'xLabel', '', problems);\n return;\n }\n }\n}\n\nfunction formatProblems(prefix: string, problems: Problems): string {\n const shown: Problems = problems.slice(0, MAX_REPORTED_PROBLEMS);\n const more: number = problems.length - shown.length;\n return `${prefix}: ${shown.join(' ')}${more > 0 ? ` (and ${more} more problem(s))` : ''}`;\n}\n\n/**\n * Checks that `value` is a valid widget payload (any kind, or an empty\n * state). Returns it typed, or an error naming every problem found (up to\n * `MAX_REPORTED_PROBLEMS`). Unknown extra fields are allowed and ignored.\n */\nexport function validateWidgetData(\n value: unknown,\n options: ValidateWidgetDataOptions = {}\n): Result<WidgetPayload> {\n const subject: string =\n options.widgetKey === undefined\n ? 'Widget data'\n : `Widget ${JSON.stringify(options.widgetKey)}`;\n if (!isRecord(value)) {\n return err(`${subject}: must be an object, got ${describeType(value)}.`);\n }\n if (value['empty'] === true) {\n if (typeof value['text'] !== 'string') {\n return err(\n `${subject} (empty): text must be a string, got ${describeType(value['text'])}.`\n );\n }\n return ok(value as unknown as WidgetPayload);\n }\n const kind: unknown = value['kind'];\n if (!isWidgetKind(kind)) {\n return err(\n `${subject}: kind must be one of ${WIDGET_KINDS.join(', ')} (or the payload must be {\"empty\": true, \"text\": ...}), got ${\n typeof kind === 'string' ? JSON.stringify(kind) : describeType(kind)\n }.`\n );\n }\n if (options.expectedKind !== undefined && kind !== options.expectedKind) {\n return err(\n `${subject}: expected kind ${options.expectedKind} from its definition, got ${kind}.`\n );\n }\n const problems: Problems = [];\n checkPayloadFields(kind, value, problems);\n if (problems.length > 0) {\n return err(formatProblems(`${subject} (${kind})`, problems));\n }\n return ok(value as unknown as WidgetPayload);\n}\n\n/**\n * Checks that `value` is a valid widget definition. Returns it typed, or an\n * error naming every problem found.\n */\nexport function validateWidgetDefinition(\n value: unknown\n): Result<WidgetDefinition> {\n if (!isRecord(value)) {\n return err(\n `Widget definition: must be an object, got ${describeType(value)}.`\n );\n }\n const subject: string =\n typeof value['key'] === 'string'\n ? `Widget definition ${JSON.stringify(value['key'])}`\n : 'Widget definition';\n const problems: Problems = [];\n requireString(value, 'key', '', problems);\n if (value['key'] === '') {\n problems.push('key must not be empty.');\n }\n requireString(value, 'title', '', problems);\n optionalString(value, 'description', '', problems);\n requireOneOf(value, 'kind', WIDGET_KINDS, '', problems);\n optionalNumber(value, 'sortOrder', '', problems);\n if (value['roles'] !== undefined) {\n const roles = requireArray(value, 'roles', '', problems);\n roles?.forEach((role: unknown, index: number) => {\n if (typeof role !== 'string') {\n problems.push(\n `roles[${index}] must be a string, got ${describeType(role)}.`\n );\n }\n });\n }\n optionalBoolean(value, 'active', '', problems);\n if (value['defaultSize'] !== undefined) {\n requireOneOf(value, 'defaultSize', WIDGET_SIZES, '', problems);\n }\n if (problems.length > 0) {\n return err(formatProblems(subject, problems));\n }\n return ok(value as unknown as WidgetDefinition);\n}\n","/**\n * Runs each widget's data provider and collects the outcome per widget, so\n * one failing provider never breaks the rest of the dashboard. The package\n * never fetches anything itself: providers are the consumer's functions\n * (a Prisma query, an HTTP call, a computed value).\n */\n\nimport {\n isWidgetVisibleTo,\n sortDefinitions,\n type WidgetDefinition,\n} from './definition.js';\nimport {\n emptyTextFor,\n type WidgetData,\n type WidgetPayload,\n} from './payload.js';\nimport { describeUnknownError } from './result.js';\nimport { validateWidgetData } from './validate.js';\n\n/** The minimum a resolve context carries; add whatever your providers need. */\nexport interface WidgetContext {\n /** The viewer's roles. Widgets with `roles` need at least one of them. */\n readonly roles?: readonly string[];\n}\n\n/** Loads one widget's payload. May be sync or async; may throw. */\nexport type WidgetProvider<C = WidgetContext> = (\n context: C,\n definition: WidgetDefinition\n) => WidgetPayload | Promise<WidgetPayload>;\n\n/** Providers keyed by widget key. */\nexport type WidgetProviders<C = WidgetContext> = Readonly<\n Record<string, WidgetProvider<C>>\n>;\n\nexport interface OkWidget {\n readonly definition: WidgetDefinition;\n readonly status: 'ok';\n readonly data: WidgetData;\n}\n\nexport interface EmptyWidget {\n readonly definition: WidgetDefinition;\n readonly status: 'empty';\n /** Why there is nothing to show, e.g. \"No orders synced yet.\" */\n readonly emptyText: string;\n}\n\nexport interface ErrorWidget {\n readonly definition: WidgetDefinition;\n readonly status: 'error';\n /** Names the widget and what failed. */\n readonly error: string;\n}\n\n/** One widget after its provider ran. */\nexport type ResolvedWidget = OkWidget | EmptyWidget | ErrorWidget;\n\n/** A widget whose data hasn't arrived yet (for client-side loading states). */\nexport interface LoadingWidget {\n readonly definition: WidgetDefinition;\n readonly status: 'loading';\n}\n\n/** Anything a dashboard can render: resolved, or still loading. */\nexport type DashboardWidget = ResolvedWidget | LoadingWidget;\n\nexport type WidgetStatus = DashboardWidget['status'];\n\nexport interface ResolveOptions {\n /**\n * Validate each provider's payload with `validateWidgetData` (and check\n * its kind matches the definition). Default true; turn off only for\n * trusted, typed providers.\n */\n readonly validate?: boolean;\n}\n\n/**\n * Turns a payload (typically JSON from an API) into a resolved widget:\n * validated against the definition's kind, and marked empty when it has\n * nothing to show.\n */\nexport function resolvePayload(\n definition: WidgetDefinition,\n payload: unknown,\n options: ResolveOptions = {}\n): ResolvedWidget {\n let checked: WidgetPayload;\n if (options.validate === false) {\n checked = payload as WidgetPayload;\n } else {\n const result = validateWidgetData(payload, {\n widgetKey: definition.key,\n expectedKind: definition.kind,\n });\n if (!result.ok) {\n return { definition, status: 'error', error: result.error };\n }\n checked = result.value;\n }\n const emptyText: string | null = emptyTextFor(checked);\n if (emptyText !== null) {\n return { definition, status: 'empty', emptyText };\n }\n return { definition, status: 'ok', data: checked as WidgetData };\n}\n\n/** A widget that failed, with the reason. */\nexport function failedWidget(\n definition: WidgetDefinition,\n error: string\n): ErrorWidget {\n return { definition, status: 'error', error };\n}\n\n/** Loading placeholders for definitions, before their data arrives. */\nexport function loadingWidgets(\n definitions: readonly WidgetDefinition[]\n): LoadingWidget[] {\n return definitions.map((definition) => ({ definition, status: 'loading' }));\n}\n\n/** Runs one widget's provider, capturing a throw or bad payload as an error. */\nexport async function resolveWidget<C extends WidgetContext>(\n definition: WidgetDefinition,\n provider: WidgetProvider<C> | undefined,\n context: C,\n options: ResolveOptions = {}\n): Promise<ResolvedWidget> {\n if (provider === undefined) {\n return failedWidget(\n definition,\n `Widget ${JSON.stringify(definition.key)}: no provider is registered for this key.`\n );\n }\n let payload: WidgetPayload;\n try {\n payload = await provider(context, definition);\n } catch (cause: unknown) {\n return failedWidget(\n definition,\n `Widget ${JSON.stringify(definition.key)}: provider failed: ${describeUnknownError(cause)}`\n );\n }\n return resolvePayload(definition, payload, options);\n}\n\n/**\n * The widgets a viewer can see: active, allowed for `roles`, in sort order.\n */\nexport function widgetsFor(\n definitions: readonly WidgetDefinition[],\n roles: readonly string[] | undefined\n): WidgetDefinition[] {\n return sortDefinitions(\n definitions.filter((definition) => isWidgetVisibleTo(definition, roles))\n );\n}\n\n/**\n * Resolves every widget the context's roles may see, in parallel. Inactive\n * and role-filtered widgets are skipped (and their providers never run).\n * Results come back in sort order; a provider that throws, is missing or\n * returns a bad payload yields an `error` widget and never rejects.\n */\nexport async function resolveWidgets<C extends WidgetContext>(\n definitions: readonly WidgetDefinition[],\n providers: WidgetProviders<C>,\n context: C,\n options: ResolveOptions = {}\n): Promise<ResolvedWidget[]> {\n const visible: WidgetDefinition[] = widgetsFor(definitions, context.roles);\n return Promise.all(\n visible.map((definition) =>\n resolveWidget(\n definition,\n Object.prototype.hasOwnProperty.call(providers, definition.key)\n ? providers[definition.key]\n : undefined,\n context,\n options\n )\n )\n );\n}\n","/** Axis maths for charts: clean domains and tick values. Pure. */\n\n/** The smallest 1, 2 or 5 × 10^n that is at least `value` (1 for 0 or less). */\nexport function niceStep(value: number): number {\n if (!(value > 0) || !Number.isFinite(value)) return 1;\n const exponent: number = Math.floor(Math.log10(value));\n const fraction: number = value / 10 ** exponent;\n const nice: number =\n fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10;\n return nice * 10 ** exponent;\n}\n\nexport interface NiceDomain {\n readonly min: number;\n readonly max: number;\n /** From min to max inclusive, evenly spaced on a clean step. */\n readonly ticks: readonly number[];\n}\n\n/**\n * A y-axis domain that always includes 0 (bars grow from a single\n * baseline), rounded out to a clean step, with about `tickCount` intervals.\n */\nexport function niceDomain(\n values: readonly number[],\n tickCount: number = 4\n): NiceDomain {\n const finite: number[] = values.filter((v) => Number.isFinite(v));\n let low: number = Math.min(0, ...finite);\n let high: number = Math.max(0, ...finite);\n if (low === high) {\n high = 1;\n low = 0;\n }\n const step: number = niceStep((high - low) / Math.max(1, tickCount));\n const min: number = Math.floor(low / step) * step;\n const max: number = Math.ceil(high / step) * step;\n const ticks: number[] = [];\n const count: number = Math.round((max - min) / step);\n for (let index = 0; index <= count; index++) {\n ticks.push(Number((min + index * step).toPrecision(12)));\n }\n return { min, max, ticks };\n}\n\n/**\n * Show every `n`th x label so at most `maxLabels` appear (always at least 1).\n */\nexport function labelStride(count: number, maxLabels: number = 6): number {\n return Math.max(1, Math.ceil(count / Math.max(1, maxLabels)));\n}\n"]}
1
+ {"version":3,"sources":["../src/core/payload.ts","../src/core/compat.ts","../src/core/definition.ts","../src/core/format.ts","../src/core/grid.ts","../src/core/layout.ts","../src/core/result.ts","../src/core/url.ts","../src/core/validate.ts","../src/core/resolve.ts","../src/core/scale.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Widget data payloads, one shape per kind, discriminated by `kind`.\n *\n * The kind names are upper case to stay compatible with Maker Toolkit's\n * `WidgetViewType` (`TEXT`, `GAUGE`, `TABLE`, `GRAPH`). `KPI`, `BAR_LIST`\n * and `ALERT_LIST` are new. Every payload is plain JSON: strings, finite\n * numbers, booleans, null, arrays and objects. No dates (send ISO strings),\n * no functions, no class instances.\n */\n\n/** Every widget kind, in a stable order. */\nexport const WIDGET_KINDS = [\n 'TEXT',\n 'KPI',\n 'GAUGE',\n 'TABLE',\n 'BAR_LIST',\n 'ALERT_LIST',\n 'GRAPH',\n] as const;\n\nexport type WidgetKind = (typeof WIDGET_KINDS)[number];\n\nexport function isWidgetKind(value: unknown): value is WidgetKind {\n return (\n typeof value === 'string' &&\n (WIDGET_KINDS as readonly string[]).includes(value)\n );\n}\n\n/** How a number is shown: a plain count, money, or a fraction as a percent. */\nexport const VALUE_FORMATS = ['number', 'currency', 'percent'] as const;\n\nexport type ValueFormat = (typeof VALUE_FORMATS)[number];\n\n/** A single headline value as text, e.g. \"12\" or \"Open\". */\nexport interface TextWidgetData {\n readonly kind: 'TEXT';\n readonly value: string;\n readonly label: string;\n}\n\n/**\n * A stat tile: one number, optionally compared with the previous period.\n *\n * `value` and `previous` are in major units for `currency` (12.5 is $12.50)\n * and fractions for `percent` (0.25 is 25%).\n */\nexport interface KpiWidgetData {\n readonly kind: 'KPI';\n readonly value: number;\n /** The same measure for the previous period; null or absent for none. */\n readonly previous?: number | null;\n readonly format: ValueFormat;\n /** ISO 4217 code for `currency`, e.g. \"USD\". Defaults to USD. */\n readonly currency?: string;\n readonly label: string;\n /** Short context under the value, e.g. \"Incl. shipping and tax\". */\n readonly hint?: string;\n /** Whether a rise is good news (default true). Colours the change. */\n readonly higherIsBetter?: boolean;\n}\n\n/** A value against a maximum, drawn as a meter. */\nexport interface GaugeWidgetData {\n readonly kind: 'GAUGE';\n readonly value: number;\n readonly max: number;\n readonly label: string;\n}\n\nexport interface TableColumn {\n readonly label: string;\n /** Right-aligned, tabular figures. */\n readonly numeric?: boolean;\n}\n\nexport interface TableCell {\n readonly text: string;\n /** Renders the cell as a link (http, https, mailto or relative only). */\n readonly href?: string;\n}\n\nexport interface TableWidgetData {\n readonly kind: 'TABLE';\n readonly columns: readonly TableColumn[];\n /** One array of cells per row, each as long as `columns`. */\n readonly rows: readonly (readonly TableCell[])[];\n /** A note under the table, e.g. \"and 12 more\". */\n readonly footer?: string;\n}\n\nexport interface BarListItem {\n readonly label: string;\n readonly value: number;\n /** Text shown beside the bar; defaults to the formatted value. */\n readonly display?: string;\n}\n\n/**\n * Labelled horizontal bars, e.g. ratings or purchases by country. Bars are a\n * share of `total` when it is given, otherwise of the largest value.\n */\nexport interface BarListWidgetData {\n readonly kind: 'BAR_LIST';\n readonly items: readonly BarListItem[];\n readonly total?: number;\n}\n\nexport interface AlertListItem {\n readonly title: string;\n /** Renders the title as a link (http, https, mailto or relative only). */\n readonly href?: string;\n /** A small square image (http, https or relative only). */\n readonly thumbnailUrl?: string;\n /** The short figure on the right, e.g. \"2 left\" or \"31 views\". */\n readonly valueLabel: string;\n /** A secondary line under the title. */\n readonly detail?: string;\n}\n\n/**\n * Things that need attention (low stock, stale listings...). `items` may be\n * the first few of `total`; the renderer says \"and N more\".\n */\nexport interface AlertListWidgetData {\n readonly kind: 'ALERT_LIST';\n readonly items: readonly AlertListItem[];\n readonly total: number;\n /** Shown when there is nothing to flag, e.g. \"Nothing low on stock.\" */\n readonly emptyText: string;\n}\n\nexport interface GraphPoint {\n /** The category or date label on the x axis, e.g. \"Oct 2026\". */\n readonly label: string;\n readonly value: number;\n}\n\nexport interface GraphSeries {\n readonly name: string;\n readonly points: readonly GraphPoint[];\n}\n\n/** The most series a graph may carry: the categorical palette's eight slots. */\nexport const MAX_GRAPH_SERIES = 8;\n\n/**\n * A bar (grouped for several series) or line chart. All series share the\n * x labels of the first series, by position, and one y axis.\n */\nexport interface GraphWidgetData {\n readonly kind: 'GRAPH';\n readonly series: readonly GraphSeries[];\n readonly chartType: 'bar' | 'line';\n readonly valueFormat: ValueFormat;\n /** ISO 4217 code for `currency`. Defaults to USD. */\n readonly currency?: string;\n /** Heading for the label column in the table view, e.g. \"Month\". */\n readonly xLabel?: string;\n}\n\n/** Any widget's data, discriminated by `kind`. */\nexport type WidgetData =\n | TextWidgetData\n | KpiWidgetData\n | GaugeWidgetData\n | TableWidgetData\n | BarListWidgetData\n | AlertListWidgetData\n | GraphWidgetData;\n\n/** The payload type for one kind, e.g. `WidgetDataOf<'KPI'>`. */\nexport type WidgetDataOf<K extends WidgetKind> = Extract<\n WidgetData,\n { kind: K }\n>;\n\n/**\n * A widget with nothing to show yet, with the reason as text (\"No orders\n * synced yet.\"). Any widget may return this instead of its kind's payload.\n */\nexport interface WidgetEmptyState {\n readonly empty: true;\n readonly text: string;\n}\n\n/** What a provider or API returns for a widget: its data, or an empty state. */\nexport type WidgetPayload = WidgetData | WidgetEmptyState;\n\n/** The default text for an empty widget. */\nexport const DEFAULT_EMPTY_TEXT = 'Nothing to show yet.';\n\n/** Builds an empty state. */\nexport function emptyWidget(\n text: string = DEFAULT_EMPTY_TEXT\n): WidgetEmptyState {\n return { empty: true, text };\n}\n\nexport function isWidgetEmptyState(\n payload: WidgetPayload\n): payload is WidgetEmptyState {\n return 'empty' in payload && payload.empty === true;\n}\n\n/**\n * The empty text for a payload with nothing in it (a table with no rows, a\n * list with no items, a graph with no points), or null when it has content.\n * TEXT, KPI and GAUGE always have content.\n */\nexport function emptyTextFor(payload: WidgetPayload): string | null {\n if (isWidgetEmptyState(payload)) {\n return payload.text;\n }\n switch (payload.kind) {\n case 'TABLE':\n return payload.rows.length === 0 ? DEFAULT_EMPTY_TEXT : null;\n case 'BAR_LIST':\n return payload.items.length === 0 ? DEFAULT_EMPTY_TEXT : null;\n case 'ALERT_LIST':\n return payload.items.length === 0 ? payload.emptyText : null;\n case 'GRAPH':\n return payload.series.every((series) => series.points.length === 0)\n ? DEFAULT_EMPTY_TEXT\n : null;\n case 'TEXT':\n case 'KPI':\n case 'GAUGE':\n return null;\n }\n}\n","/**\n * Maker Toolkit compatibility. Its API (`apps/api/src/widgets`) serves\n * `TEXT`, `GAUGE`, `TABLE` and `GRAPH` payloads; `TEXT` and `GAUGE` are\n * unchanged here, while `TABLE` and `GRAPH` grew richer shapes. These\n * helpers upgrade the older shapes so `validateWidgetData` accepts them.\n */\n\nimport type { WidgetDefinition } from './definition.js';\nimport { isWidgetKind } from './payload.js';\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((v) => typeof v === 'string');\n}\n\n/**\n * Upgrades a Maker Toolkit payload to this package's shape:\n *\n * - `TABLE` `{columns: string[], rows: string[][]}` → `{label}` columns and\n * `{text}` cells.\n * - `GRAPH` `{points}` → one unnamed bar series with `valueFormat: 'number'`.\n *\n * Anything else, including payloads already in the new shape, is returned\n * unchanged. Validate the result with `validateWidgetData`.\n */\nexport function upgradeLegacyWidgetData(value: unknown): unknown {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return value;\n }\n const record = value as Readonly<Record<string, unknown>>;\n if (\n record['kind'] === 'TABLE' &&\n isStringArray(record['columns']) &&\n Array.isArray(record['rows']) &&\n record['rows'].every(isStringArray)\n ) {\n const rows = record['rows'] as string[][];\n return {\n ...record,\n columns: record['columns'].map((label) => ({ label })),\n rows: rows.map((row) => row.map((text) => ({ text }))),\n };\n }\n if (\n record['kind'] === 'GRAPH' &&\n Array.isArray(record['points']) &&\n record['series'] === undefined\n ) {\n const { points, ...rest } = record;\n return {\n ...rest,\n series: [{ name: 'Value', points }],\n chartType: 'bar',\n valueFormat: 'number',\n };\n }\n return value;\n}\n\n/** Maker Toolkit's served widget definition (`WidgetDefinition` in its API). */\nexport interface LegacyWidgetDefinition {\n readonly widgetKey: string;\n readonly title: string;\n readonly description: string | null;\n readonly viewType: string;\n readonly sortOrder: number;\n}\n\n/**\n * Maps a Maker Toolkit definition onto this package's. Returns null when\n * the view type isn't a known kind.\n */\nexport function fromLegacyDefinition(\n legacy: LegacyWidgetDefinition\n): WidgetDefinition | null {\n if (!isWidgetKind(legacy.viewType)) {\n return null;\n }\n return {\n key: legacy.widgetKey,\n title: legacy.title,\n ...(legacy.description === null ? {} : { description: legacy.description }),\n kind: legacy.viewType,\n sortOrder: legacy.sortOrder,\n };\n}\n","import type { WidgetKind } from './payload.js';\n\n/** A size hint for grid layouts; renderers may map it to column spans. */\nexport const WIDGET_SIZES = ['small', 'medium', 'large', 'full'] as const;\n\nexport type WidgetSize = (typeof WIDGET_SIZES)[number];\n\n/**\n * How a widget fills free space in a grid layout. `height` stretches it to\n * the height of its row; `width` widens it to take the columns left over in\n * its row; `both` does both. Absent, a widget is only as big as its content\n * and `defaultSize`.\n */\nexport const WIDGET_FILLS = ['height', 'width', 'both'] as const;\n\nexport type WidgetFill = (typeof WIDGET_FILLS)[number];\n\n/**\n * What a widget is, independent of its data. Mirrors Maker Toolkit's\n * `widget` table (`widget_key`, `title`, `description`, `view_type`,\n * `roles`, `sort_order`, `active`).\n */\nexport interface WidgetDefinition {\n /** Stable, unique id. Layouts and providers are keyed by it. */\n readonly key: string;\n readonly title: string;\n readonly description?: string;\n readonly kind: WidgetKind;\n /** Lower comes first. Default 0; ties keep definition order. */\n readonly sortOrder?: number;\n /** Roles allowed to see it. Absent or empty means everyone. */\n readonly roles?: readonly string[];\n /** False hides it from every user. Default true. */\n readonly active?: boolean;\n readonly defaultSize?: WidgetSize;\n /** Fill free space in the row (height, width or both). Default: none. */\n readonly fill?: WidgetFill;\n}\n\n/**\n * Identity helper that keeps the literal `kind` (so typed providers can be\n * checked against it) and gives a definition its type without a cast.\n */\nexport function defineWidget<const D extends WidgetDefinition>(\n definition: D\n): D {\n return definition;\n}\n\n/** Definitions sorted by `sortOrder` (stable: ties keep their input order). */\nexport function sortDefinitions<D extends WidgetDefinition>(\n definitions: readonly D[]\n): D[] {\n return definitions\n .map((definition, index) => ({ definition, index }))\n .sort(\n (a, b) =>\n (a.definition.sortOrder ?? 0) - (b.definition.sortOrder ?? 0) ||\n a.index - b.index\n )\n .map(({ definition }) => definition);\n}\n\n/** Whether a widget is active and visible to someone with these roles. */\nexport function isWidgetVisibleTo(\n definition: WidgetDefinition,\n roles: readonly string[] | undefined\n): boolean {\n if (definition.active === false) {\n return false;\n }\n if (definition.roles === undefined || definition.roles.length === 0) {\n return true;\n }\n if (roles === undefined) {\n return false;\n }\n return definition.roles.some((role) => roles.includes(role));\n}\n","/**\n * Number formatting via `Intl`, with an injectable locale (undefined uses\n * the runtime's default), plus KPI period-over-period deltas.\n */\n\nimport type { ValueFormat } from './payload.js';\n\nexport type Locale = string | readonly string[] | undefined;\n\nexport interface FormatOptions {\n readonly locale?: Locale;\n /** ISO 4217 code for `currency`. Default \"USD\". */\n readonly currency?: string;\n /** \"1.2K\" style, for axis ticks. */\n readonly compact?: boolean;\n}\n\nexport const DEFAULT_CURRENCY = 'USD';\n\nfunction localeArgument(locale: Locale): string | string[] | undefined {\n return locale === undefined || typeof locale === 'string'\n ? locale\n : [...locale];\n}\n\nfunction numberFormat(\n locale: Locale,\n options: Intl.NumberFormatOptions\n): Intl.NumberFormat {\n try {\n return new Intl.NumberFormat(localeArgument(locale), options);\n } catch {\n // An invalid locale tag or currency code: fall back to the default\n // locale and a plain number rather than throwing mid-render.\n const { style: _style, currency: _currency, ...rest } = options;\n return new Intl.NumberFormat(undefined, rest);\n }\n}\n\n/**\n * Formats `value` as a count (\"1,284\"), money (\"$12.50\", major units) or a\n * percent (\"25%\" from 0.25).\n */\nexport function formatValue(\n value: number,\n format: ValueFormat,\n options: FormatOptions = {}\n): string {\n if (!Number.isFinite(value)) {\n return '—';\n }\n const compact: Intl.NumberFormatOptions = options.compact\n ? { notation: 'compact', maximumFractionDigits: 1 }\n : {};\n switch (format) {\n case 'number':\n return numberFormat(options.locale, {\n maximumFractionDigits: 2,\n ...compact,\n }).format(value);\n case 'currency': {\n const currency: string = (\n options.currency ?? DEFAULT_CURRENCY\n ).toUpperCase();\n const formatter = numberFormat(options.locale, {\n style: 'currency',\n currency,\n ...compact,\n });\n const text: string = formatter.format(value);\n // The fallback formatter has no currency, so say which one it was.\n return formatter.resolvedOptions().style === 'currency'\n ? text\n : `${text} ${currency}`;\n }\n case 'percent':\n return numberFormat(options.locale, {\n style: 'percent',\n maximumFractionDigits: 1,\n ...compact,\n }).format(value);\n }\n}\n\n/** A plain count, e.g. \"1,284\". */\nexport function formatCount(value: number, locale?: Locale): string {\n return formatValue(value, 'number', { locale });\n}\n\n/** `part` as a whole percentage of `total` (0 when total is 0 or less). */\nexport function shareOf(part: number, total: number): number {\n return total <= 0 ? 0 : Math.round((part / total) * 100);\n}\n\n/**\n * Change from `previous` to `current` in percent (unrounded), or null when\n * there is nothing to compare: no previous value, or a previous of 0.\n */\nexport function percentChange(\n current: number,\n previous: number | null | undefined\n): number | null {\n if (\n previous === null ||\n previous === undefined ||\n previous === 0 ||\n !Number.isFinite(previous) ||\n !Number.isFinite(current)\n ) {\n return null;\n }\n return ((current - previous) / Math.abs(previous)) * 100;\n}\n\n/**\n * \"+12%\", \"-8%\", \"±0%\". Below 10% one decimal is kept (\"+2.5%\"), so small\n * changes don't round away.\n */\nexport function formatPercentChange(change: number, locale?: Locale): string {\n const digits: number = Math.abs(change) < 10 ? 1 : 0;\n const rounded: number = Number(change.toFixed(digits));\n if (rounded === 0) {\n return '±0%';\n }\n return numberFormat(locale, {\n style: 'percent',\n maximumFractionDigits: digits,\n signDisplay: 'exceptZero',\n }).format(rounded / 100);\n}\n\nexport type DeltaDirection = 'up' | 'down' | 'flat';\nexport type DeltaSentiment = 'good' | 'bad' | 'neutral';\n\nexport interface KpiDelta {\n /** Percent change, unrounded. */\n readonly percent: number;\n readonly direction: DeltaDirection;\n /** Direction combined with whether higher is better. */\n readonly sentiment: DeltaSentiment;\n /** \"+12%\" */\n readonly text: string;\n /** \"+12% vs previous period\" */\n readonly description: string;\n}\n\nexport interface KpiDeltaOptions {\n /** Default true. */\n readonly higherIsBetter?: boolean;\n readonly locale?: Locale;\n /** What the change is against. Default \"previous period\". */\n readonly comparisonLabel?: string;\n}\n\n/** The default comparison wording in delta descriptions. */\nexport const DEFAULT_COMPARISON_LABEL = 'previous period';\n\n/**\n * The period-over-period change for a KPI, or null when it can't be worked\n * out (no previous value, or a previous of 0).\n */\nexport function kpiDelta(\n current: number,\n previous: number | null | undefined,\n options: KpiDeltaOptions = {}\n): KpiDelta | null {\n const percent: number | null = percentChange(current, previous);\n if (percent === null) {\n return null;\n }\n const text: string = formatPercentChange(percent, options.locale);\n const direction: DeltaDirection =\n text === '±0%' ? 'flat' : percent > 0 ? 'up' : 'down';\n const higherIsBetter: boolean = options.higherIsBetter ?? true;\n const sentiment: DeltaSentiment =\n direction === 'flat'\n ? 'neutral'\n : (direction === 'up') === higherIsBetter\n ? 'good'\n : 'bad';\n return {\n percent,\n direction,\n sentiment,\n text,\n description: `${text} vs ${options.comparisonLabel ?? DEFAULT_COMPARISON_LABEL}`,\n };\n}\n","import type { WidgetFill, WidgetSize } from './definition.js';\n\n/** The parts of a widget definition that decide its place in a grid. */\nexport interface GridItem {\n readonly key: string;\n readonly defaultSize?: WidgetSize;\n readonly fill?: WidgetFill;\n}\n\n/** Whether the widget should take the columns left over in its row. */\nexport function fillsWidth(fill: WidgetFill | undefined): boolean {\n return fill === 'width' || fill === 'both';\n}\n\n/** Whether the widget should stretch to the height of its row. */\nexport function fillsHeight(fill: WidgetFill | undefined): boolean {\n return fill === 'height' || fill === 'both';\n}\n\n/**\n * Columns a size takes in a grid of `columns` tracks: `large` spans\n * `largeSpan` (default 2), `full` spans every column, anything else one.\n */\nexport function baseColumnSpan(\n size: WidgetSize | undefined,\n columns: number,\n largeSpan = 2\n): number {\n if (size === 'full') return columns;\n if (size === 'large') return Math.min(largeSpan, columns);\n return 1;\n}\n\n/**\n * Places `items` in a grid of `columns` tracks the way a sparse grid\n * auto-places them (left to right, wrapping to a new row when an item does\n * not fit), then gives the columns left over in each row to the items that\n * `fill` their width, shared evenly (earlier items get the remainder).\n *\n * Returns the column span for each width-filling item, keyed by `key`. Items\n * that do not fill width keep their normal size and are not in the map.\n */\nexport function fillColumnSpans(\n items: readonly GridItem[],\n columns: number,\n largeSpan = 2\n): Map<string, number> {\n const trackCount: number = Math.max(1, Math.floor(columns));\n const spans = new Map<string, number>();\n let row: { item: GridItem; span: number }[] = [];\n let used = 0;\n\n function closeRow(): void {\n const fillers = row.filter(({ item }) => fillsWidth(item.fill));\n const leftover: number = trackCount - used;\n if (fillers.length > 0) {\n const share: number = Math.floor(leftover / fillers.length);\n const remainder: number = leftover % fillers.length;\n fillers.forEach(({ item, span }, index) => {\n spans.set(item.key, span + share + (index < remainder ? 1 : 0));\n });\n }\n row = [];\n used = 0;\n }\n\n for (const item of items) {\n const span: number = baseColumnSpan(\n item.defaultSize,\n trackCount,\n largeSpan\n );\n if (used + span > trackCount && row.length > 0) closeRow();\n row.push({ item, span });\n used += span;\n }\n closeRow();\n return spans;\n}\n","/**\n * A viewer's dashboard customisation: order, hidden and minimised widgets.\n * Pure functions over a small JSON-serialisable object. Persist it however\n * you like (a settings table, localStorage); `parseLayout` tolerates\n * anything, so a corrupt saved value never breaks the dashboard.\n *\n * Generalised from Maker Toolkit's desktop `dashboard-layout.ts`.\n */\n\n/** What layout functions need from a widget definition. */\nexport interface LayoutItem {\n readonly key: string;\n readonly sortOrder?: number;\n}\n\nexport interface DashboardLayout {\n /** Widget keys in display order. Keys not listed follow, by sortOrder. */\n readonly order: readonly string[];\n /** Widget keys removed from the dashboard (restorable). */\n readonly hidden: readonly string[];\n /** Widget keys collapsed to their header. */\n readonly minimized: readonly string[];\n}\n\nexport const EMPTY_LAYOUT: DashboardLayout = Object.freeze({\n order: Object.freeze([]) as readonly string[],\n hidden: Object.freeze([]) as readonly string[],\n minimized: Object.freeze([]) as readonly string[],\n});\n\nfunction uniqueStrings(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n const seen = new Set<string>();\n for (const entry of value) {\n if (typeof entry === 'string' && entry !== '') seen.add(entry);\n }\n return [...seen];\n}\n\n/**\n * Reads a saved layout: a JSON string or an already-parsed object. Missing,\n * corrupt or wrongly typed values give the empty layout (or empty lists for\n * the fields that are wrong); non-string and duplicate keys are dropped.\n */\nexport function parseLayout(raw: unknown): DashboardLayout {\n let value: unknown = raw;\n if (typeof raw === 'string') {\n try {\n value = JSON.parse(raw);\n } catch {\n return EMPTY_LAYOUT;\n }\n }\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return EMPTY_LAYOUT;\n }\n const record = value as Readonly<Record<string, unknown>>;\n const order: string[] = uniqueStrings(record['order']);\n const hidden: string[] = uniqueStrings(record['hidden']);\n const minimized: string[] = uniqueStrings(record['minimized']);\n if (order.length === 0 && hidden.length === 0 && minimized.length === 0) {\n return EMPTY_LAYOUT;\n }\n return { order, hidden, minimized };\n}\n\n/** The JSON string to persist. */\nexport function serializeLayout(layout: DashboardLayout): string {\n return JSON.stringify({\n order: [...layout.order],\n hidden: [...layout.hidden],\n minimized: [...layout.minimized],\n });\n}\n\nfunction bySortOrder<T extends LayoutItem>(items: readonly T[]): T[] {\n return items\n .map((item, index) => ({ item, index }))\n .sort(\n (a, b) =>\n (a.item.sortOrder ?? 0) - (b.item.sortOrder ?? 0) || a.index - b.index\n )\n .map(({ item }) => item);\n}\n\n/**\n * The widgets to show, in order: saved keys first (when still present),\n * then widgets the layout doesn't know yet, by sortOrder. Hidden widgets\n * are left out.\n */\nexport function visibleWidgets<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout\n): T[] {\n const hidden = new Set<string>(layout.hidden);\n const visible: T[] = definitions.filter((d) => !hidden.has(d.key));\n const byKey = new Map<string, T>(visible.map((d) => [d.key, d]));\n const ordered: T[] = [];\n for (const key of layout.order) {\n const definition: T | undefined = byKey.get(key);\n if (definition !== undefined) {\n ordered.push(definition);\n byKey.delete(key);\n }\n }\n for (const definition of bySortOrder(visible)) {\n if (byKey.has(definition.key)) ordered.push(definition);\n }\n return ordered;\n}\n\n/** Hidden widgets, by sortOrder, for a \"restore\" menu. */\nexport function hiddenWidgets<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout\n): T[] {\n const hidden = new Set<string>(layout.hidden);\n return bySortOrder(definitions.filter((d) => hidden.has(d.key)));\n}\n\n/**\n * Moves `key` to `toIndex` within the current visible order. Returns the\n * same layout object when the key isn't visible or the index is out of\n * range, so callers can skip a save.\n */\nexport function moveWidget<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout,\n key: string,\n toIndex: number\n): DashboardLayout {\n const current: string[] = visibleWidgets(definitions, layout).map(\n (d) => d.key\n );\n const fromIndex: number = current.indexOf(key);\n if (\n fromIndex === -1 ||\n !Number.isInteger(toIndex) ||\n toIndex < 0 ||\n toIndex >= current.length ||\n toIndex === fromIndex\n ) {\n return layout;\n }\n const next: string[] = [...current];\n next.splice(fromIndex, 1);\n next.splice(toIndex, 0, key);\n return { ...layout, order: next };\n}\n\n/** Moves `key` by `offset` places (negative is earlier). Clamped at the ends. */\nexport function moveWidgetBy<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout,\n key: string,\n offset: number\n): DashboardLayout {\n const current: string[] = visibleWidgets(definitions, layout).map(\n (d) => d.key\n );\n const fromIndex: number = current.indexOf(key);\n if (fromIndex === -1) return layout;\n const toIndex: number = Math.max(\n 0,\n Math.min(current.length - 1, fromIndex + Math.trunc(offset))\n );\n return moveWidget(definitions, layout, key, toIndex);\n}\n\n/** Moves `key` one place earlier. */\nexport function moveWidgetUp<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n return moveWidgetBy(definitions, layout, key, -1);\n}\n\n/** Moves `key` one place later. */\nexport function moveWidgetDown<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n return moveWidgetBy(definitions, layout, key, 1);\n}\n\nexport function isHidden(layout: DashboardLayout, key: string): boolean {\n return layout.hidden.includes(key);\n}\n\nexport function isMinimized(layout: DashboardLayout, key: string): boolean {\n return layout.minimized.includes(key);\n}\n\n/** Hides `key`. No-op (same object) if already hidden. */\nexport function hideWidget(\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n if (isHidden(layout, key)) return layout;\n return { ...layout, hidden: [...layout.hidden, key] };\n}\n\n/** Shows `key` again, expanded. No-op (same object) if not hidden. */\nexport function showWidget(\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n if (!isHidden(layout, key)) return layout;\n return {\n ...layout,\n hidden: layout.hidden.filter((k) => k !== key),\n minimized: layout.minimized.filter((k) => k !== key),\n };\n}\n\n/** Hides or shows `key` (showing also clears its minimised state). */\nexport function toggleHidden(\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n return isHidden(layout, key)\n ? showWidget(layout, key)\n : hideWidget(layout, key);\n}\n\n/** Collapses `key` to its header. No-op (same object) if already minimised. */\nexport function minimizeWidget(\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n if (isMinimized(layout, key)) return layout;\n return { ...layout, minimized: [...layout.minimized, key] };\n}\n\n/** Expands `key`. No-op (same object) if not minimised. */\nexport function restoreWidget(\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n if (!isMinimized(layout, key)) return layout;\n return { ...layout, minimized: layout.minimized.filter((k) => k !== key) };\n}\n\n/** Minimises or restores `key`. */\nexport function toggleMinimized(\n layout: DashboardLayout,\n key: string\n): DashboardLayout {\n return isMinimized(layout, key)\n ? restoreWidget(layout, key)\n : minimizeWidget(layout, key);\n}\n\n/**\n * Drops keys for widgets that no longer exist. Only pass the full list of\n * definitions (not a role-filtered one), or a viewer's settings for widgets\n * they temporarily can't see are lost.\n */\nexport function pruneLayout<T extends LayoutItem>(\n definitions: readonly T[],\n layout: DashboardLayout\n): DashboardLayout {\n const known = new Set<string>(definitions.map((d) => d.key));\n const keep = (keys: readonly string[]): string[] =>\n keys.filter((k) => known.has(k));\n const next: DashboardLayout = {\n order: keep(layout.order),\n hidden: keep(layout.hidden),\n minimized: keep(layout.minimized),\n };\n return next.order.length === layout.order.length &&\n next.hidden.length === layout.hidden.length &&\n next.minimized.length === layout.minimized.length\n ? layout\n : next;\n}\n","/**\n * A small Result type. Functions in this package return a Result rather than\n * throwing, so the caller has to look at the outcome. `throw` is reserved for\n * programmer error.\n */\n\nexport interface Ok<T> {\n readonly ok: true;\n readonly value: T;\n}\n\nexport interface Err {\n readonly ok: false;\n /** Specific enough to act on: names the field, the widget and the problem. */\n readonly error: string;\n}\n\nexport type Result<T> = Ok<T> | Err;\n\nexport function ok<T>(value: T): Ok<T> {\n return { ok: true, value };\n}\n\nexport function err(error: string): Err {\n return { ok: false, error };\n}\n\n/** Turns an unknown thrown value into a readable message. */\nexport function describeUnknownError(cause: unknown): string {\n if (cause instanceof Error) {\n return cause.message === '' ? cause.name : cause.message;\n }\n if (typeof cause === 'string') {\n return cause;\n }\n try {\n const json: string | undefined = JSON.stringify(cause);\n return json ?? String(cause);\n } catch {\n return String(cause);\n }\n}\n","/**\n * Link and image URL checks. Payloads often come from an API, so a link is\n * only rendered when it can't run script: http(s), mailto, or a relative\n * path. Nothing here fetches anything.\n */\n\nconst SCHEME_PATTERN = /^([a-z][a-z0-9+.-]*):/i;\n\n// Browsers ignore ASCII control characters and whitespace inside a scheme\n// (\"java\\tscript:\"), so strip them before reading it.\n// eslint-disable-next-line no-control-regex\nconst IGNORED_IN_SCHEME = /[\\u0000- \\u007f]/g;\n\nfunction schemeOf(url: string): string | null {\n const match: RegExpExecArray | null = SCHEME_PATTERN.exec(\n url.replace(IGNORED_IN_SCHEME, '')\n );\n return match === null ? null : (match[1] ?? '').toLowerCase();\n}\n\n/** Whether `url` is safe as an anchor href: http, https, mailto or relative. */\nexport function isSafeHref(url: string): boolean {\n if (url.trim() === '') {\n return false;\n }\n const scheme: string | null = schemeOf(url);\n return (\n scheme === null ||\n scheme === 'http' ||\n scheme === 'https' ||\n scheme === 'mailto'\n );\n}\n\n/** Whether `url` is safe as an image source: http, https or relative. */\nexport function isSafeImageUrl(url: string): boolean {\n if (url.trim() === '') {\n return false;\n }\n const scheme: string | null = schemeOf(url);\n return scheme === null || scheme === 'http' || scheme === 'https';\n}\n","/**\n * Hand-written validators for widget payloads and definitions, so data from\n * an API can be checked in a client without a schema library. Problems name\n * the widget, the field path and what was wrong, e.g.\n * `Widget \"top-products\" (TABLE): rows[2][0].text must be a string, got number.`\n */\n\nimport {\n WIDGET_FILLS,\n WIDGET_SIZES,\n type WidgetDefinition,\n} from './definition.js';\nimport {\n MAX_GRAPH_SERIES,\n VALUE_FORMATS,\n WIDGET_KINDS,\n isWidgetKind,\n type WidgetKind,\n type WidgetPayload,\n} from './payload.js';\nimport { err, ok, type Result } from './result.js';\nimport { isSafeHref, isSafeImageUrl } from './url.js';\n\n/** At most this many problems are listed in one error message. */\nexport const MAX_REPORTED_PROBLEMS = 10;\n\nexport interface ValidateWidgetDataOptions {\n /** Named in error messages, e.g. the widget key. */\n readonly widgetKey?: string;\n /** Fails unless the payload is this kind (an empty state always passes). */\n readonly expectedKind?: WidgetKind;\n}\n\ntype Problems = string[];\ntype Record_ = Readonly<Record<string, unknown>>;\n\nfunction describeType(value: unknown): string {\n if (value === null) return 'null';\n if (Array.isArray(value)) return 'array';\n if (typeof value === 'number' && !Number.isFinite(value)) {\n return String(value);\n }\n return typeof value;\n}\n\nfunction isRecord(value: unknown): value is Record_ {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction join(path: string, field: string): string {\n return path === '' ? field : `${path}.${field}`;\n}\n\nfunction requireString(\n record: Record_,\n field: string,\n path: string,\n problems: Problems\n): void {\n const value: unknown = record[field];\n if (typeof value !== 'string') {\n problems.push(\n `${join(path, field)} must be a string, got ${describeType(value)}.`\n );\n }\n}\n\nfunction optionalString(\n record: Record_,\n field: string,\n path: string,\n problems: Problems\n): void {\n if (record[field] !== undefined) {\n requireString(record, field, path, problems);\n }\n}\n\nfunction requireNumber(\n record: Record_,\n field: string,\n path: string,\n problems: Problems\n): void {\n const value: unknown = record[field];\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n problems.push(\n `${join(path, field)} must be a finite number, got ${describeType(value)}.`\n );\n }\n}\n\nfunction optionalNumber(\n record: Record_,\n field: string,\n path: string,\n problems: Problems\n): void {\n if (record[field] !== undefined) {\n requireNumber(record, field, path, problems);\n }\n}\n\nfunction optionalBoolean(\n record: Record_,\n field: string,\n path: string,\n problems: Problems\n): void {\n const value: unknown = record[field];\n if (value !== undefined && typeof value !== 'boolean') {\n problems.push(\n `${join(path, field)} must be a boolean, got ${describeType(value)}.`\n );\n }\n}\n\nfunction optionalUrl(\n record: Record_,\n field: string,\n path: string,\n problems: Problems,\n isSafe: (url: string) => boolean,\n allowed: string\n): void {\n const value: unknown = record[field];\n if (value === undefined) return;\n if (typeof value !== 'string') {\n problems.push(\n `${join(path, field)} must be a string, got ${describeType(value)}.`\n );\n } else if (!isSafe(value)) {\n problems.push(\n `${join(path, field)} must be ${allowed}, got ${JSON.stringify(value.slice(0, 80))}.`\n );\n }\n}\n\nfunction requireArray(\n record: Record_,\n field: string,\n path: string,\n problems: Problems\n): readonly unknown[] | null {\n const value: unknown = record[field];\n if (!Array.isArray(value)) {\n problems.push(\n `${join(path, field)} must be an array, got ${describeType(value)}.`\n );\n return null;\n }\n return value;\n}\n\nfunction requireOneOf(\n record: Record_,\n field: string,\n options: readonly string[],\n path: string,\n problems: Problems\n): void {\n const value: unknown = record[field];\n if (typeof value !== 'string' || !options.includes(value)) {\n problems.push(\n `${join(path, field)} must be one of ${options.map((o) => `\"${o}\"`).join(', ')}, got ${\n typeof value === 'string' ? JSON.stringify(value) : describeType(value)\n }.`\n );\n }\n}\n\n/** Runs `check` on each element that is an object, reporting the others. */\nfunction eachRecord(\n items: readonly unknown[],\n path: string,\n problems: Problems,\n check: (item: Record_, itemPath: string) => void\n): void {\n items.forEach((item: unknown, index: number) => {\n const itemPath = `${path}[${index}]`;\n if (isRecord(item)) {\n check(item, itemPath);\n } else {\n problems.push(\n `${itemPath} must be an object, got ${describeType(item)}.`\n );\n }\n });\n}\n\nconst HREF_RULE = 'an http(s), mailto or relative URL';\nconst IMAGE_RULE = 'an http(s) or relative URL';\n\nfunction checkPayloadFields(\n kind: WidgetKind,\n data: Record_,\n problems: Problems\n): void {\n switch (kind) {\n case 'TEXT':\n requireString(data, 'value', '', problems);\n requireString(data, 'label', '', problems);\n return;\n case 'KPI':\n requireNumber(data, 'value', '', problems);\n if (data['previous'] !== null) {\n optionalNumber(data, 'previous', '', problems);\n }\n requireOneOf(data, 'format', VALUE_FORMATS, '', problems);\n optionalString(data, 'currency', '', problems);\n requireString(data, 'label', '', problems);\n optionalString(data, 'hint', '', problems);\n optionalBoolean(data, 'higherIsBetter', '', problems);\n return;\n case 'GAUGE':\n requireNumber(data, 'value', '', problems);\n requireNumber(data, 'max', '', problems);\n requireString(data, 'label', '', problems);\n if (typeof data['max'] === 'number' && data['max'] <= 0) {\n problems.push(`max must be greater than 0, got ${data['max']}.`);\n }\n return;\n case 'TABLE': {\n const columns = requireArray(data, 'columns', '', problems);\n if (columns !== null) {\n eachRecord(columns, 'columns', problems, (column, path) => {\n requireString(column, 'label', path, problems);\n optionalBoolean(column, 'numeric', path, problems);\n });\n }\n const rows = requireArray(data, 'rows', '', problems);\n if (rows !== null) {\n rows.forEach((row: unknown, rowIndex: number) => {\n const rowPath = `rows[${rowIndex}]`;\n if (!Array.isArray(row)) {\n problems.push(\n `${rowPath} must be an array of cells, got ${describeType(row)}.`\n );\n return;\n }\n if (columns !== null && row.length !== columns.length) {\n problems.push(\n `${rowPath} has ${row.length} cell(s) but there are ${columns.length} column(s).`\n );\n }\n eachRecord(row, rowPath, problems, (cell, cellPath) => {\n requireString(cell, 'text', cellPath, problems);\n optionalUrl(\n cell,\n 'href',\n cellPath,\n problems,\n isSafeHref,\n HREF_RULE\n );\n });\n });\n }\n optionalString(data, 'footer', '', problems);\n return;\n }\n case 'BAR_LIST': {\n const items = requireArray(data, 'items', '', problems);\n if (items !== null) {\n eachRecord(items, 'items', problems, (item, path) => {\n requireString(item, 'label', path, problems);\n requireNumber(item, 'value', path, problems);\n optionalString(item, 'display', path, problems);\n });\n }\n optionalNumber(data, 'total', '', problems);\n return;\n }\n case 'ALERT_LIST': {\n const items = requireArray(data, 'items', '', problems);\n if (items !== null) {\n eachRecord(items, 'items', problems, (item, path) => {\n requireString(item, 'title', path, problems);\n optionalUrl(item, 'href', path, problems, isSafeHref, HREF_RULE);\n optionalUrl(\n item,\n 'thumbnailUrl',\n path,\n problems,\n isSafeImageUrl,\n IMAGE_RULE\n );\n requireString(item, 'valueLabel', path, problems);\n optionalString(item, 'detail', path, problems);\n });\n }\n requireNumber(data, 'total', '', problems);\n requireString(data, 'emptyText', '', problems);\n if (\n items !== null &&\n typeof data['total'] === 'number' &&\n data['total'] < items.length\n ) {\n problems.push(\n `total (${data['total']}) must be at least the number of items (${items.length}).`\n );\n }\n return;\n }\n case 'GRAPH': {\n const series = requireArray(data, 'series', '', problems);\n if (series !== null) {\n if (series.length > MAX_GRAPH_SERIES) {\n problems.push(\n `series has ${series.length} entries; at most ${MAX_GRAPH_SERIES} are allowed (fold the rest into \"Other\").`\n );\n }\n eachRecord(series, 'series', problems, (entry, path) => {\n requireString(entry, 'name', path, problems);\n const points = requireArray(entry, 'points', path, problems);\n if (points !== null) {\n eachRecord(\n points,\n `${path}.points`,\n problems,\n (point, pointPath) => {\n requireString(point, 'label', pointPath, problems);\n requireNumber(point, 'value', pointPath, problems);\n }\n );\n }\n });\n }\n requireOneOf(data, 'chartType', ['bar', 'line'], '', problems);\n requireOneOf(data, 'valueFormat', VALUE_FORMATS, '', problems);\n optionalString(data, 'currency', '', problems);\n optionalString(data, 'xLabel', '', problems);\n return;\n }\n }\n}\n\nfunction formatProblems(prefix: string, problems: Problems): string {\n const shown: Problems = problems.slice(0, MAX_REPORTED_PROBLEMS);\n const more: number = problems.length - shown.length;\n return `${prefix}: ${shown.join(' ')}${more > 0 ? ` (and ${more} more problem(s))` : ''}`;\n}\n\n/**\n * Checks that `value` is a valid widget payload (any kind, or an empty\n * state). Returns it typed, or an error naming every problem found (up to\n * `MAX_REPORTED_PROBLEMS`). Unknown extra fields are allowed and ignored.\n */\nexport function validateWidgetData(\n value: unknown,\n options: ValidateWidgetDataOptions = {}\n): Result<WidgetPayload> {\n const subject: string =\n options.widgetKey === undefined\n ? 'Widget data'\n : `Widget ${JSON.stringify(options.widgetKey)}`;\n if (!isRecord(value)) {\n return err(`${subject}: must be an object, got ${describeType(value)}.`);\n }\n if (value['empty'] === true) {\n if (typeof value['text'] !== 'string') {\n return err(\n `${subject} (empty): text must be a string, got ${describeType(value['text'])}.`\n );\n }\n return ok(value as unknown as WidgetPayload);\n }\n const kind: unknown = value['kind'];\n if (!isWidgetKind(kind)) {\n return err(\n `${subject}: kind must be one of ${WIDGET_KINDS.join(', ')} (or the payload must be {\"empty\": true, \"text\": ...}), got ${\n typeof kind === 'string' ? JSON.stringify(kind) : describeType(kind)\n }.`\n );\n }\n if (options.expectedKind !== undefined && kind !== options.expectedKind) {\n return err(\n `${subject}: expected kind ${options.expectedKind} from its definition, got ${kind}.`\n );\n }\n const problems: Problems = [];\n checkPayloadFields(kind, value, problems);\n if (problems.length > 0) {\n return err(formatProblems(`${subject} (${kind})`, problems));\n }\n return ok(value as unknown as WidgetPayload);\n}\n\n/**\n * Checks that `value` is a valid widget definition. Returns it typed, or an\n * error naming every problem found.\n */\nexport function validateWidgetDefinition(\n value: unknown\n): Result<WidgetDefinition> {\n if (!isRecord(value)) {\n return err(\n `Widget definition: must be an object, got ${describeType(value)}.`\n );\n }\n const subject: string =\n typeof value['key'] === 'string'\n ? `Widget definition ${JSON.stringify(value['key'])}`\n : 'Widget definition';\n const problems: Problems = [];\n requireString(value, 'key', '', problems);\n if (value['key'] === '') {\n problems.push('key must not be empty.');\n }\n requireString(value, 'title', '', problems);\n optionalString(value, 'description', '', problems);\n requireOneOf(value, 'kind', WIDGET_KINDS, '', problems);\n optionalNumber(value, 'sortOrder', '', problems);\n if (value['roles'] !== undefined) {\n const roles = requireArray(value, 'roles', '', problems);\n roles?.forEach((role: unknown, index: number) => {\n if (typeof role !== 'string') {\n problems.push(\n `roles[${index}] must be a string, got ${describeType(role)}.`\n );\n }\n });\n }\n optionalBoolean(value, 'active', '', problems);\n if (value['defaultSize'] !== undefined) {\n requireOneOf(value, 'defaultSize', WIDGET_SIZES, '', problems);\n }\n if (value['fill'] !== undefined) {\n requireOneOf(value, 'fill', WIDGET_FILLS, '', problems);\n }\n if (problems.length > 0) {\n return err(formatProblems(subject, problems));\n }\n return ok(value as unknown as WidgetDefinition);\n}\n","/**\n * Runs each widget's data provider and collects the outcome per widget, so\n * one failing provider never breaks the rest of the dashboard. The package\n * never fetches anything itself: providers are the consumer's functions\n * (a Prisma query, an HTTP call, a computed value).\n */\n\nimport {\n isWidgetVisibleTo,\n sortDefinitions,\n type WidgetDefinition,\n} from './definition.js';\nimport {\n emptyTextFor,\n type WidgetData,\n type WidgetPayload,\n} from './payload.js';\nimport { describeUnknownError } from './result.js';\nimport { validateWidgetData } from './validate.js';\n\n/** The minimum a resolve context carries; add whatever your providers need. */\nexport interface WidgetContext {\n /** The viewer's roles. Widgets with `roles` need at least one of them. */\n readonly roles?: readonly string[];\n}\n\n/** Loads one widget's payload. May be sync or async; may throw. */\nexport type WidgetProvider<C = WidgetContext> = (\n context: C,\n definition: WidgetDefinition\n) => WidgetPayload | Promise<WidgetPayload>;\n\n/** Providers keyed by widget key. */\nexport type WidgetProviders<C = WidgetContext> = Readonly<\n Record<string, WidgetProvider<C>>\n>;\n\nexport interface OkWidget {\n readonly definition: WidgetDefinition;\n readonly status: 'ok';\n readonly data: WidgetData;\n}\n\nexport interface EmptyWidget {\n readonly definition: WidgetDefinition;\n readonly status: 'empty';\n /** Why there is nothing to show, e.g. \"No orders synced yet.\" */\n readonly emptyText: string;\n}\n\nexport interface ErrorWidget {\n readonly definition: WidgetDefinition;\n readonly status: 'error';\n /** Names the widget and what failed. */\n readonly error: string;\n}\n\n/** One widget after its provider ran. */\nexport type ResolvedWidget = OkWidget | EmptyWidget | ErrorWidget;\n\n/** A widget whose data hasn't arrived yet (for client-side loading states). */\nexport interface LoadingWidget {\n readonly definition: WidgetDefinition;\n readonly status: 'loading';\n}\n\n/** Anything a dashboard can render: resolved, or still loading. */\nexport type DashboardWidget = ResolvedWidget | LoadingWidget;\n\nexport type WidgetStatus = DashboardWidget['status'];\n\nexport interface ResolveOptions {\n /**\n * Validate each provider's payload with `validateWidgetData` (and check\n * its kind matches the definition). Default true; turn off only for\n * trusted, typed providers.\n */\n readonly validate?: boolean;\n}\n\n/**\n * Turns a payload (typically JSON from an API) into a resolved widget:\n * validated against the definition's kind, and marked empty when it has\n * nothing to show.\n */\nexport function resolvePayload(\n definition: WidgetDefinition,\n payload: unknown,\n options: ResolveOptions = {}\n): ResolvedWidget {\n let checked: WidgetPayload;\n if (options.validate === false) {\n checked = payload as WidgetPayload;\n } else {\n const result = validateWidgetData(payload, {\n widgetKey: definition.key,\n expectedKind: definition.kind,\n });\n if (!result.ok) {\n return { definition, status: 'error', error: result.error };\n }\n checked = result.value;\n }\n const emptyText: string | null = emptyTextFor(checked);\n if (emptyText !== null) {\n return { definition, status: 'empty', emptyText };\n }\n return { definition, status: 'ok', data: checked as WidgetData };\n}\n\n/** A widget that failed, with the reason. */\nexport function failedWidget(\n definition: WidgetDefinition,\n error: string\n): ErrorWidget {\n return { definition, status: 'error', error };\n}\n\n/** Loading placeholders for definitions, before their data arrives. */\nexport function loadingWidgets(\n definitions: readonly WidgetDefinition[]\n): LoadingWidget[] {\n return definitions.map((definition) => ({ definition, status: 'loading' }));\n}\n\n/** Runs one widget's provider, capturing a throw or bad payload as an error. */\nexport async function resolveWidget<C extends WidgetContext>(\n definition: WidgetDefinition,\n provider: WidgetProvider<C> | undefined,\n context: C,\n options: ResolveOptions = {}\n): Promise<ResolvedWidget> {\n if (provider === undefined) {\n return failedWidget(\n definition,\n `Widget ${JSON.stringify(definition.key)}: no provider is registered for this key.`\n );\n }\n let payload: WidgetPayload;\n try {\n payload = await provider(context, definition);\n } catch (cause: unknown) {\n return failedWidget(\n definition,\n `Widget ${JSON.stringify(definition.key)}: provider failed: ${describeUnknownError(cause)}`\n );\n }\n return resolvePayload(definition, payload, options);\n}\n\n/**\n * The widgets a viewer can see: active, allowed for `roles`, in sort order.\n */\nexport function widgetsFor(\n definitions: readonly WidgetDefinition[],\n roles: readonly string[] | undefined\n): WidgetDefinition[] {\n return sortDefinitions(\n definitions.filter((definition) => isWidgetVisibleTo(definition, roles))\n );\n}\n\n/**\n * Resolves every widget the context's roles may see, in parallel. Inactive\n * and role-filtered widgets are skipped (and their providers never run).\n * Results come back in sort order; a provider that throws, is missing or\n * returns a bad payload yields an `error` widget and never rejects.\n */\nexport async function resolveWidgets<C extends WidgetContext>(\n definitions: readonly WidgetDefinition[],\n providers: WidgetProviders<C>,\n context: C,\n options: ResolveOptions = {}\n): Promise<ResolvedWidget[]> {\n const visible: WidgetDefinition[] = widgetsFor(definitions, context.roles);\n return Promise.all(\n visible.map((definition) =>\n resolveWidget(\n definition,\n Object.prototype.hasOwnProperty.call(providers, definition.key)\n ? providers[definition.key]\n : undefined,\n context,\n options\n )\n )\n );\n}\n","/** Axis maths for charts: clean domains and tick values. Pure. */\n\n/** The smallest 1, 2 or 5 × 10^n that is at least `value` (1 for 0 or less). */\nexport function niceStep(value: number): number {\n if (!(value > 0) || !Number.isFinite(value)) return 1;\n const exponent: number = Math.floor(Math.log10(value));\n const fraction: number = value / 10 ** exponent;\n const nice: number =\n fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10;\n return nice * 10 ** exponent;\n}\n\nexport interface NiceDomain {\n readonly min: number;\n readonly max: number;\n /** From min to max inclusive, evenly spaced on a clean step. */\n readonly ticks: readonly number[];\n}\n\n/**\n * A y-axis domain that always includes 0 (bars grow from a single\n * baseline), rounded out to a clean step, with about `tickCount` intervals.\n */\nexport function niceDomain(\n values: readonly number[],\n tickCount: number = 4\n): NiceDomain {\n const finite: number[] = values.filter((v) => Number.isFinite(v));\n let low: number = Math.min(0, ...finite);\n let high: number = Math.max(0, ...finite);\n if (low === high) {\n high = 1;\n low = 0;\n }\n const step: number = niceStep((high - low) / Math.max(1, tickCount));\n const min: number = Math.floor(low / step) * step;\n const max: number = Math.ceil(high / step) * step;\n const ticks: number[] = [];\n const count: number = Math.round((max - min) / step);\n for (let index = 0; index <= count; index++) {\n ticks.push(Number((min + index * step).toPrecision(12)));\n }\n return { min, max, ticks };\n}\n\n/**\n * Show every `n`th x label so at most `maxLabels` appear (always at least 1).\n */\nexport function labelStride(count: number, maxLabels: number = 6): number {\n return Math.max(1, Math.ceil(count / Math.max(1, maxLabels)));\n}\n"]}
package/dist/react.cjs CHANGED
@@ -5,6 +5,50 @@ var jsxRuntime = require('react/jsx-runtime');
5
5
 
6
6
  // src/react/card.tsx
7
7
 
8
+ // src/core/grid.ts
9
+ function fillsWidth(fill) {
10
+ return fill === "width" || fill === "both";
11
+ }
12
+ function fillsHeight(fill) {
13
+ return fill === "height" || fill === "both";
14
+ }
15
+ function baseColumnSpan(size, columns, largeSpan = 2) {
16
+ if (size === "full") return columns;
17
+ if (size === "large") return Math.min(largeSpan, columns);
18
+ return 1;
19
+ }
20
+ function fillColumnSpans(items, columns, largeSpan = 2) {
21
+ const trackCount = Math.max(1, Math.floor(columns));
22
+ const spans = /* @__PURE__ */ new Map();
23
+ let row = [];
24
+ let used = 0;
25
+ function closeRow() {
26
+ const fillers = row.filter(({ item }) => fillsWidth(item.fill));
27
+ const leftover = trackCount - used;
28
+ if (fillers.length > 0) {
29
+ const share = Math.floor(leftover / fillers.length);
30
+ const remainder = leftover % fillers.length;
31
+ fillers.forEach(({ item, span }, index) => {
32
+ spans.set(item.key, span + share + (index < remainder ? 1 : 0));
33
+ });
34
+ }
35
+ row = [];
36
+ used = 0;
37
+ }
38
+ for (const item of items) {
39
+ const span = baseColumnSpan(
40
+ item.defaultSize,
41
+ trackCount,
42
+ largeSpan
43
+ );
44
+ if (used + span > trackCount && row.length > 0) closeRow();
45
+ row.push({ item, span });
46
+ used += span;
47
+ }
48
+ closeRow();
49
+ return spans;
50
+ }
51
+
8
52
  // src/core/format.ts
9
53
  var DEFAULT_CURRENCY = "USD";
10
54
  function localeArgument(locale) {
@@ -904,6 +948,8 @@ function WidgetCard({
904
948
  onRetry,
905
949
  footer,
906
950
  size,
951
+ fill,
952
+ columnSpan,
907
953
  headingLevel = 2,
908
954
  className,
909
955
  children
@@ -949,8 +995,11 @@ function WidgetCard({
949
995
  `dwt-card--${status}`,
950
996
  minimized && "dwt-card--minimized",
951
997
  size !== void 0 && `dwt-card--size-${size}`,
998
+ fillsHeight(fill) && "dwt-card--fill-height",
999
+ fillsWidth(fill) && "dwt-card--fill-width",
952
1000
  className
953
1001
  ),
1002
+ ...columnSpan === void 0 ? {} : { style: { gridColumn: `span ${columnSpan}` } },
954
1003
  children: [
955
1004
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: slot("cardHeader", "dwt-card-header"), children: [
956
1005
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dwt-card-heading", children: [
@@ -1014,6 +1063,7 @@ function ResolvedWidgetCard({
1014
1063
  status: widget.status,
1015
1064
  ...definition.description === void 0 ? {} : { description: definition.description },
1016
1065
  ...definition.defaultSize === void 0 ? {} : { size: definition.defaultSize },
1066
+ ...definition.fill === void 0 ? {} : { fill: definition.fill },
1017
1067
  ...widget.status === "empty" ? { emptyText: widget.emptyText } : {},
1018
1068
  ...widget.status === "error" ? { error: widget.error } : {},
1019
1069
  children: widget.status === "ok" ? /* @__PURE__ */ jsxRuntime.jsx(WidgetContent, { data: widget.data }) : null
@@ -1107,6 +1157,41 @@ function restoreWidget(layout, key) {
1107
1157
  function toggleMinimized(layout, key) {
1108
1158
  return isMinimized(layout, key) ? restoreWidget(layout, key) : minimizeWidget(layout, key);
1109
1159
  }
1160
+ var NARROW_VIEWPORT_QUERY = "(max-width: 640px)";
1161
+ function useFillSpans(definitions, gridRef) {
1162
+ const [metrics, setMetrics] = react.useState(void 0);
1163
+ const needsSpans = definitions.some(
1164
+ (definition) => fillsWidth(definition.fill)
1165
+ );
1166
+ react.useEffect(() => {
1167
+ const grid = gridRef.current;
1168
+ if (!needsSpans || grid === null || typeof ResizeObserver === "undefined") {
1169
+ setMetrics(void 0);
1170
+ return void 0;
1171
+ }
1172
+ function measure() {
1173
+ if (grid === null) return;
1174
+ const tracks = getComputedStyle(grid).gridTemplateColumns;
1175
+ const columns = tracks === "" || tracks === "none" ? 0 : tracks.trim().split(/\s+/).length;
1176
+ const largeSpan = window.matchMedia(NARROW_VIEWPORT_QUERY).matches ? 1 : 2;
1177
+ setMetrics(
1178
+ (previous) => columns === 0 ? void 0 : previous?.columns === columns && previous.largeSpan === largeSpan ? previous : { columns, largeSpan }
1179
+ );
1180
+ }
1181
+ measure();
1182
+ const observer = new ResizeObserver(measure);
1183
+ observer.observe(grid);
1184
+ return () => observer.disconnect();
1185
+ }, [needsSpans, gridRef]);
1186
+ return react.useMemo(
1187
+ () => metrics === void 0 ? /* @__PURE__ */ new Map() : fillColumnSpans(definitions, metrics.columns, metrics.largeSpan),
1188
+ [definitions, metrics]
1189
+ );
1190
+ }
1191
+ function spanProps(spans, key) {
1192
+ const columnSpan = spans.get(key);
1193
+ return columnSpan === void 0 ? {} : { columnSpan };
1194
+ }
1110
1195
  function WidgetGrid({
1111
1196
  widgets,
1112
1197
  onRetry,
@@ -1114,10 +1199,14 @@ function WidgetGrid({
1114
1199
  className
1115
1200
  }) {
1116
1201
  const slot = useSlotClassName();
1117
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: slot("grid", "dwt-grid", className), children: widgets.map((widget) => /* @__PURE__ */ jsxRuntime.jsx(
1202
+ const gridRef = react.useRef(null);
1203
+ const definitions = widgets.map((w) => w.definition);
1204
+ const spans = useFillSpans(definitions, gridRef);
1205
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: gridRef, className: slot("grid", "dwt-grid", className), children: widgets.map((widget) => /* @__PURE__ */ jsxRuntime.jsx(
1118
1206
  ResolvedWidgetCard,
1119
1207
  {
1120
1208
  widget,
1209
+ ...spanProps(spans, widget.definition.key),
1121
1210
  ...headingLevel === void 0 ? {} : { headingLevel },
1122
1211
  ...onRetry === void 0 || widget.status !== "error" ? {} : { onRetry: () => onRetry(widget.definition.key) }
1123
1212
  },
@@ -1141,6 +1230,8 @@ function DashboardInner({
1141
1230
  const visible = visibleWidgets(definitions, layout);
1142
1231
  const hidden = hiddenWidgets(definitions, layout);
1143
1232
  const editable = onLayoutChange !== void 0;
1233
+ const gridRef = react.useRef(null);
1234
+ const spans = useFillSpans(visible, gridRef);
1144
1235
  function change(next) {
1145
1236
  if (next !== layout) onLayoutChange?.(next);
1146
1237
  }
@@ -1162,7 +1253,7 @@ function DashboardInner({
1162
1253
  definition.key
1163
1254
  ))
1164
1255
  ] }),
1165
- visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: slot("empty", "dwt-empty", "dwt-dashboard-empty"), children: definitions.length === 0 ? labels.noWidgets : labels.allHidden }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: slot("grid", "dwt-grid"), children: visible.map((definition, index) => {
1256
+ visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: slot("empty", "dwt-empty", "dwt-dashboard-empty"), children: definitions.length === 0 ? labels.noWidgets : labels.allHidden }) : /* @__PURE__ */ jsxRuntime.jsx("div", { ref: gridRef, className: slot("grid", "dwt-grid"), children: visible.map((definition, index) => {
1166
1257
  const widget = byKey.get(
1167
1258
  definition.key
1168
1259
  );
@@ -1210,6 +1301,7 @@ function DashboardInner({
1210
1301
  ResolvedWidgetCard,
1211
1302
  {
1212
1303
  widget,
1304
+ ...spanProps(spans, key),
1213
1305
  minimized: isMinimized(layout, key),
1214
1306
  ...actions === void 0 ? {} : { actions },
1215
1307
  ...editable ? {