@devicechain/widget-sdk 0.0.0-bootstrap.0 → 0.0.0-stage
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/README.md +2 -83
- package/package.json +4 -74
- package/LICENSE +0 -201
- package/dist/chart/chart-options.d.ts +0 -14
- package/dist/chart/chart-theme.d.ts +0 -8
- package/dist/chart/echart.d.ts +0 -8
- package/dist/chunks/chunk-CC2V7LVI.js +0 -67
- package/dist/chunks/chunk-CC2V7LVI.js.map +0 -7
- package/dist/context.d.ts +0 -29
- package/dist/define-widget.d.ts +0 -22
- package/dist/echarts.d.ts +0 -3
- package/dist/echarts.js +0 -193
- package/dist/echarts.js.map +0 -7
- package/dist/flash.d.ts +0 -13
- package/dist/format.d.ts +0 -3
- package/dist/frame.d.ts +0 -8
- package/dist/hooks.d.ts +0 -31
- package/dist/index.d.ts +0 -12
- package/dist/index.js +0 -546
- package/dist/index.js.map +0 -7
- package/dist/registry.d.ts +0 -12
- package/dist/theme.d.ts +0 -2
- package/dist/widget-options.d.ts +0 -8
- package/dist/widget.d.ts +0 -31
package/dist/index.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/define-widget.ts", "../src/registry.ts", "../src/theme.ts", "../src/frame.tsx", "../src/format.ts", "../src/flash.tsx", "../src/widget-options.ts", "../src/hooks.ts", "../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport type {\n ChannelSnapshot,\n OptionsOf,\n WidgetChannel,\n WidgetDescriptor,\n WidgetOptionSpecs,\n} from '@devicechain/dashboards';\nimport type { ComponentType } from 'react';\n\nimport type { WidgetEditorProps, WidgetProps } from './widget';\n\n// The trusted half of a registration: the React code. Kept apart from the descriptor so\n// the descriptor stays portable plain data and headless validators never load a component.\nexport interface WidgetImplementation<C extends WidgetChannel, S extends WidgetOptionSpecs> {\n // The only execution kind in this release: React code the host bundled at build time,\n // running with the host page's privileges.\n kind: 'trusted-react';\n component: ComponentType<WidgetProps<ChannelSnapshot<C>>>;\n editor?: ComponentType<WidgetEditorProps<OptionsOf<S>>>;\n}\n\nexport interface WidgetDefinition<\n C extends WidgetChannel = WidgetChannel,\n S extends WidgetOptionSpecs = WidgetOptionSpecs,\n> {\n descriptor: WidgetDescriptor<C, S>;\n implementation: WidgetImplementation<C, S>;\n}\n\n// A component with its props type erased. `any` is deliberate and confined to this alias:\n// `ComponentType<never>` would be the principled erasure, but a class component's\n// `defaultProps` is covariant in its props and rejects it, and a registry has to hold\n// components of every channel's props.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type ErasedComponent = ComponentType<any>;\n\n// A definition with its component types erased, which is what a registry stores: any\n// specific WidgetDefinition<C, S> is assignable to it.\nexport interface ErasedWidgetDefinition {\n descriptor: WidgetDescriptor;\n implementation: {\n kind: 'trusted-react';\n component: ErasedComponent;\n editor?: ErasedComponent;\n };\n}\n\n// defineWidget is an identity at runtime; it exists for inference. The channel and the\n// option schema are inferred from the literal, so a component whose data disagrees with\n// the channel, defaults that disagree with the schema, a binding that names a missing or\n// wrong-kind option, or an interaction the channel cannot carry is a COMPILE error \u2014 and\n// createWidgetRegistry checks the same things again at runtime for callers that bypass the\n// compiler. Every widget, built-in or third-party, is declared through this one helper.\nexport function defineWidget<const C extends WidgetChannel, const S extends WidgetOptionSpecs>(\n definition: WidgetDefinition<C, S>,\n): WidgetDefinition<C, S> {\n return definition;\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n WidgetCatalogError,\n collectCatalogIssues,\n createWidgetCatalog,\n type DescriptorIssue,\n type WidgetCatalog,\n type WidgetDescriptor,\n} from '@devicechain/dashboards';\n\nimport type { ErasedWidgetDefinition } from './define-widget';\n\n// Thrown by createWidgetRegistry with EVERY problem found, so a host fixes its composition\n// in one pass instead of one failed start per fault.\nexport class WidgetRegistryError extends WidgetCatalogError {\n constructor(issues: readonly DescriptorIssue[]) {\n super(issues, 'widget registry');\n this.name = 'WidgetRegistryError';\n }\n}\n\n// A sealed registry: descriptors (through the React-free catalog the parser sees) plus the\n// trusted implementations. Immutable \u2014 there is no register(), no process-global state and\n// no replacement while a dashboard is mounted. Two registries are independent.\nexport interface WidgetRegistry {\n // The React-free view of this registry, for parsing and headless validation.\n readonly catalog: WidgetCatalog;\n descriptor(id: string): WidgetDescriptor | undefined;\n implementation(id: string): ErasedWidgetDefinition['implementation'] | undefined;\n // Definitions in the order they were supplied.\n list(): readonly ErasedWidgetDefinition[];\n}\n\nfunction isComponent(value: unknown): boolean {\n if (typeof value === 'function') return true;\n // memo / forwardRef / lazy components are objects tagged with $$typeof.\n return typeof value === 'object' && value !== null && '$$typeof' in value;\n}\n\ntype Loose = Partial<ErasedWidgetDefinition> | null | undefined;\n\n// createWidgetRegistry validates every definition (descriptor invariants, duplicate ids,\n// the implementation shape) and returns a deeply frozen registry, or throws one\n// WidgetRegistryError listing all the problems.\nexport function createWidgetRegistry(definitions: readonly ErasedWidgetDefinition[]): WidgetRegistry {\n if (!Array.isArray(definitions)) {\n throw new WidgetRegistryError([{ id: '#?', path: '', message: 'definitions must be an array' }]);\n }\n const issues: DescriptorIssue[] = collectCatalogIssues(definitions.map((d) => (d as Loose)?.descriptor));\n\n definitions.forEach((definition, index) => {\n const id: unknown = (definition as Loose)?.descriptor?.id;\n const label = typeof id === 'string' && id !== '' ? id : `#${index}`;\n const add = (path: string, message: string): void => {\n issues.push({ id: label, path, message });\n };\n const impl = (definition as Loose)?.implementation;\n if (typeof impl !== 'object' || impl === null) {\n add('implementation', 'a definition needs an implementation');\n return;\n }\n if (impl.kind !== 'trusted-react') {\n add('implementation.kind', `kind must be \"trusted-react\", got ${JSON.stringify(impl.kind)}`);\n }\n if (!isComponent(impl.component)) add('implementation.component', 'component must be a React component');\n if (impl.editor !== undefined && !isComponent(impl.editor)) {\n add('implementation.editor', 'editor, when given, must be a React component');\n }\n });\n\n if (issues.length > 0) throw new WidgetRegistryError(issues);\n\n // Through the one public, validating constructor: no unvalidated path to a catalog exists.\n // The descriptors were already checked above (so this cannot throw for them); checking\n // again is the price of not exporting a catalog builder that skips validation.\n //\n // \uD83D\uDD34 The catalog freezes each descriptor IN PLACE (deeply), so the caller's descriptor\n // objects are frozen after this call. That is deliberate: a built-in descriptor holds its\n // option schema BY IDENTITY with WIDGET_OPTIONS, and a copy would break that identity.\n const catalog = createWidgetCatalog(definitions.map((d) => d.descriptor));\n const byId = new Map<string, ErasedWidgetDefinition>();\n for (const definition of definitions) {\n // The implementation object, unlike the descriptor, is copied before freezing, so the\n // caller's implementation object is left mutable (the components it names are shared).\n byId.set(\n definition.descriptor.id,\n Object.freeze({\n descriptor: catalog.get(definition.descriptor.id) as WidgetDescriptor,\n implementation: Object.freeze({ ...definition.implementation }),\n }),\n );\n }\n const ordered: readonly ErasedWidgetDefinition[] = Object.freeze([...byId.values()]);\n\n return Object.freeze({\n catalog,\n descriptor: (id: string) => catalog.get(id),\n implementation: (id: string) => byId.get(id)?.implementation,\n list: () => ordered,\n });\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Theming without Tailwind (widgets are embeddable \u2014 no Tailwind leakage).\n//\n// Widgets style themselves with inline styles that reference the SAME CSS custom\n// properties the console (and any host) defines \u2014 `--card`, `--foreground`,\n// `--border`, `--chart-1..5`, etc. A host that sets those variables themes the\n// widgets for free (light/dark included); a host without Tailwind still works.\n//\n// DOM elements can use `hsl(var(--card))` directly. ECharts renders to a <canvas>,\n// which cannot resolve CSS variables \u2014 so for charts we read the variables off the\n// live computed style and hand ECharts concrete color strings (resolveChartTheme).\n\n// css returns an `hsl(var(--name))` reference for use in an inline style. The host\n// defines the variable as HSL channels (e.g. `--card: 0 0% 100%`), matching the\n// console's token set.\nexport function css(name: ThemeVar): string {\n return `hsl(var(--${name}))`;\n}\n\n// The subset of the console's design tokens widgets rely on. Kept small and\n// semantic so the contract a host must provide is explicit and stable.\nexport type ThemeVar =\n | 'background'\n | 'foreground'\n | 'card'\n | 'card-foreground'\n | 'muted'\n | 'muted-foreground'\n | 'primary'\n | 'border'\n | 'destructive';\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// The shared card frame every widget renders inside \u2014 a bordered, themed surface\n// that fills its dashboard-canvas slot, with an optional title bar. Styled with\n// inline CSS-variable references so it themes from the host without Tailwind.\n\nimport { type CSSProperties, type ReactNode } from 'react';\n\nimport { useWidgetSubject } from './context';\nimport { css } from './theme';\n\nexport interface WidgetFrameProps {\n title?: string;\n // An explicit subject line; when omitted the frame falls back to the resolved-entity\n // subject from WidgetSubjectContext.\n subtitle?: string;\n children: ReactNode;\n // Extra style for the body region (e.g. removing padding for a chart canvas).\n bodyStyle?: CSSProperties;\n}\n\nexport function WidgetFrame({ title, subtitle, children, bodyStyle }: WidgetFrameProps) {\n const subject = useWidgetSubject();\n const sub = subtitle ?? subject;\n return (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n height: '100%',\n boxSizing: 'border-box',\n background: css('card'),\n color: css('card-foreground'),\n border: `1px solid ${css('border')}`,\n borderRadius: 'var(--radius, 8px)',\n overflow: 'hidden',\n }}\n >\n {title || sub ? (\n <div\n style={{\n padding: '8px 12px',\n borderBottom: `1px solid ${css('border')}`,\n }}\n >\n {title ? (\n <div style={{ fontSize: 12, fontWeight: 600, color: css('muted-foreground') }}>{title}</div>\n ) : null}\n {sub ? (\n <div\n title={sub}\n style={{\n fontSize: 11,\n fontWeight: 400,\n color: css('muted-foreground'),\n opacity: 0.75,\n marginTop: title ? 2 : 0,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {sub}\n </div>\n ) : null}\n </div>\n ) : null}\n <div style={{ flex: 1, minHeight: 0, ...bodyStyle }}>{children}</div>\n </div>\n );\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Both formatters take an optional IANA `timeZone`. Omitted, they are exactly what they\n// always were: the viewer's own zone and locale defaults, which is right for a live board.\n// A host that plays a RECORDING pins one (the renderer's `timeZone` prop), because the\n// recorded instants are the point and a viewer's zone would shift them across a date line;\n// a pinned zone also prints its short name, so the reading says which clock it is.\n\n// formatTimestamp renders an RFC3339 event time as a locale time string, leaving\n// an unparseable value untouched and an absent one blank.\nexport function formatTimestamp(iso: string | null, timeZone?: string): string {\n if (!iso) return '';\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return iso;\n return timeZone ? date.toLocaleTimeString(undefined, { timeZone, timeZoneName: 'short' }) : date.toLocaleTimeString();\n}\n\n// formatDateTime renders an RFC3339 time as a locale date+time string. Unlike\n// formatTimestamp (time-only, right for a live measurement tick) this keeps the date,\n// because an alarm can have been raised days ago and a bare \"09:14:32\" would mislead.\nexport function formatDateTime(iso: string | null, timeZone?: string): string {\n if (!iso) return '';\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return iso;\n return timeZone ? date.toLocaleString(undefined, { timeZone, timeZoneName: 'short' }) : date.toLocaleString();\n}\n\n// formatValue renders a measurement value, applying a fixed precision when given\n// and showing an em dash for a missing value.\n//\n// The precision is clamped to toFixed's domain because it arrives from an opaque stored\n// definition: outside 0..100 toFixed throws a RangeError, which is an exception thrown\n// during render \u2014 it unmounts the widget's whole subtree rather than degrading, and every\n// other bad option value in this package degrades. The console's config panel can author\n// a negative one today, and a hand-edited definition always could.\nexport function formatValue(value: number | null | undefined, precision?: number): string {\n if (value == null) return '\u2014';\n if (precision == null) return String(value);\n const places = Math.min(100, Math.max(0, Math.trunc(precision)));\n return value.toFixed(places);\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Directional change-flash \u2014 an opt-in cue (widget option `flashOnChange`) that briefly\n// tints a numeric value green when it rises and red when it falls, then fades back, so a\n// glance catches direction of change on a live board (cf. a trading \"last\" column). Purely\n// presentational: no hub/model change, driven off the value the widget already renders.\n//\n// Single-value widgets (latest-card) color the number; a multi-row widget (table,\n// alarm-table) renders each value through <FlashValue>, so React's per-key component\n// instances give every row its own independent flash with no map bookkeeping. The gauge\n// (an opaque ECharts canvas whose number can't be CSS-transitioned) tints its container\n// instead \u2014 see flashBackgroundStyle.\n\nimport { useEffect, useRef, useState, type CSSProperties } from 'react';\n\nimport { formatValue } from './format';\n\nexport type FlashDirection = 'up' | 'down' | null;\n\n// Semantic up/down colors, mid-saturation so they read on both light and dark host themes;\n// a host may override with the --flash-up / --flash-down custom properties. The background\n// variants are translucent so a tint sits over the widget's own surface without hiding it.\nconst UP = {\n fg: 'var(--flash-up, hsl(142 72% 40%))',\n bg: 'var(--flash-up-bg, hsl(142 72% 45% / 0.16))',\n};\nconst DOWN = {\n fg: 'var(--flash-down, hsl(0 72% 51%))',\n bg: 'var(--flash-down-bg, hsl(0 72% 55% / 0.16))',\n};\n\n// How long (ms) the solid tint holds before fading, and how long the fade back takes.\nconst HOLD_MS = 400;\nconst FADE_MS = 600;\n\n// useFlashOnChange watches a numeric value and returns the direction of its most recent\n// change ('up' | 'down') for a short window, then null. It stays null when the feature is\n// off, on the first value (no flash on mount), on a non-finite value, or when `identity`\n// changes \u2014 the last so a widget bound to an ANCHOR (whose one measurement slot interleaves\n// values from many member devices) adopts the new device's value instead of reading the\n// device-to-device jump as a real rise/fall. Pass the value's owning entity as `identity`\n// (e.g. `deviceToken:name`); leave it undefined for a single-device value.\n//\n// The held direction auto-clears after HOLD_MS; the consumer fades it out via flashTextStyle.\n// Every early-return path resets `direction` too: the effect only re-runs on a dep change,\n// and each such change has already cancelled the pending timer, so not clearing here would\n// strand a tint (e.g. value \u2192 null, or toggled off then on, mid-hold).\nexport function useFlashOnChange(\n value: number | null | undefined,\n enabled: boolean,\n identity?: string | number,\n): FlashDirection {\n const prev = useRef<number | null | undefined>(value);\n const prevIdentity = useRef(identity);\n const [direction, setDirection] = useState<FlashDirection>(null);\n\n useEffect(() => {\n const before = prev.current;\n const sameEntity = prevIdentity.current === identity;\n prev.current = value;\n prevIdentity.current = identity;\n if (\n !enabled ||\n !sameEntity ||\n typeof value !== 'number' ||\n typeof before !== 'number' ||\n !Number.isFinite(value) ||\n !Number.isFinite(before) ||\n value === before\n ) {\n setDirection(null); // a no-op when already null (React bails out); clears a stale tint otherwise\n return;\n }\n setDirection(value > before ? 'up' : 'down');\n const timer = setTimeout(() => setDirection(null), HOLD_MS);\n return () => clearTimeout(timer);\n }, [value, enabled, identity]);\n\n // Mask any lingering state when disabled, so toggling off is immediate.\n return enabled ? direction : null;\n}\n\n// flashTextStyle colors text for the current direction: snap to the tint (no transition)\n// while flashing, then fade `color` back to the element's own color when it clears. Merge\n// it AFTER an explicit base `color` so the tint overrides while set and the base shows\n// through (and animates) once cleared.\nexport function flashTextStyle(direction: FlashDirection, fadeMs: number = FADE_MS): CSSProperties {\n if (direction) return { color: direction === 'up' ? UP.fg : DOWN.fg, transition: 'none' };\n return { transition: `color ${fadeMs}ms ease-out` };\n}\n\n// flashBackgroundStyle is the same cue as a translucent background tint, for a widget whose\n// value can't be recolored directly (the gauge's canvas). Snap in, fade the background back.\nexport function flashBackgroundStyle(direction: FlashDirection, fadeMs: number = FADE_MS): CSSProperties {\n if (direction) {\n return { backgroundColor: direction === 'up' ? UP.bg : DOWN.bg, transition: 'none' };\n }\n return { transition: `background-color ${fadeMs}ms ease-out` };\n}\n\n// FlashValue renders a formatted numeric value that flashes on change \u2014 the reusable cell\n// for multi-row widgets. Each rendered instance owns its own flash state, so keying rows by\n// entity (React's list key) gives every row an independent cue for free.\nexport function FlashValue({\n value,\n precision,\n enabled,\n identity,\n baseColor = 'inherit',\n style,\n}: {\n value: number | null | undefined;\n precision?: number;\n enabled: boolean;\n // The value's owning entity (see useFlashOnChange): when it changes, adopt the new value\n // rather than flash. Distinguishes a real per-device change from an anchor's cross-device\n // interleave. Undefined for a single-device value.\n identity?: string | number;\n // The color the value fades back to (defaults to the inherited text color).\n baseColor?: string;\n style?: CSSProperties;\n}) {\n const direction = useFlashOnChange(value, enabled, identity);\n return (\n <span style={{ color: baseColor, ...style, ...flashTextStyle(direction) }}>\n {formatValue(value, precision)}\n </span>\n );\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Small helpers for reading a widget's opaque `options` bag and picking the measurement a\n// single-value widget should show. They are the SDK's, not the built-ins': a third-party\n// widget reads its own options the same defensive way.\n\nimport type { MeasurementSample, WidgetInstance } from '@devicechain/dashboards';\n\n// pickSample chooses the sample a single-value widget (card, gauge) shows: the\n// named measurement, or the first available when no name is pinned.\nexport function pickSample(\n latest: Record<string, MeasurementSample>,\n name: string | undefined,\n): MeasurementSample | undefined {\n return name ? latest[name] : Object.values(latest)[0];\n}\n\n// --- options helpers ---------------------------------------------------------\n// A widget's `options` is opaque JSON (Record<string, unknown>) owned by the\n// widget; these read a key defensively, returning undefined on the wrong type\n// rather than throwing on a hand-edited definition.\n\ntype Options = Record<string, unknown> | undefined;\n\nexport function optString(options: Options, key: string): string | undefined {\n const value = options?.[key];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function optNumber(options: Options, key: string): number | undefined {\n const value = options?.[key];\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\n// A boolean flag option: true only when explicitly stored true (absent/other \u2192 false), so\n// an opt-in feature stays off by default and a hand-edited value can't accidentally enable it.\nexport function optBoolean(options: Options, key: string): boolean {\n return options?.[key] === true;\n}\n\n// primaryMeasurementName is the measurement a single-value widget (card, gauge)\n// displays: an explicit `options.measurement`, else the first measurement its\n// datasource selects, else undefined (fall back to whatever arrives first).\nexport function primaryMeasurementName(widget: WidgetInstance): string | undefined {\n const explicit = optString(widget.options, 'measurement');\n if (explicit) return explicit;\n const ds = widget.datasource;\n if (ds && ds.measurements.length > 0) return ds.measurements[0];\n return undefined;\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// React bindings between the imperative DashboardHub / DOM theme and widget state.\n\nimport type {\n AlarmSubscription,\n CommandSubscription,\n DashboardDefinition,\n DatasourceSelector,\n DeviceResolver,\n EntityCandidateLister,\n LocationSubscription,\n MemberResolver,\n MeasurementSample,\n SelectionCandidate,\n SlotBinding,\n WidgetDataSource,\n} from '@devicechain/dashboards';\nimport type {\n AlarmStreamState,\n CommandStreamState,\n LocationStreamState,\n MeasurementStreamState,\n} from '@devicechain/dashboards';\nimport {\n bindingsWithoutScopedSlots,\n DashboardHub,\n hasScopedSlots,\n resolveContextBindings,\n resolveSlotCandidates,\n} from '@devicechain/dashboards';\nimport { useEffect, useMemo, useRef, useState, type RefObject } from 'react';\n\nimport { useWidgetCandidates, type WidgetCandidates } from './context';\n\n// The channel snapshots moved to @devicechain/dashboards (they are pure data over the hub's\n// row types); re-exported so every import site here keeps resolving.\nexport type { AlarmStreamState, CommandStreamState, LocationStreamState, MeasurementStreamState };\n\n// useDashboardHub gives a host ONE live hub per (resolver, authorities) \u2014 compared by\n// value, so a re-rendered but equal authorities array keeps the hub \u2014 and disposes it when\n// it is replaced or the host unmounts.\n//\n// It deliberately takes no bindings. The hub holds none: the renderer resolves every slot\n// through the settled bindings (resolveWidgetDatasource) before a widget subscribes, so a\n// selection re-subscribes only the widgets bound to the re-pointed slot. A hub rebuilt per\n// selection would tear down every subscription on the board and re-fetch every history.\nexport function useDashboardHub(resolver: DeviceResolver, authorities: string[] | undefined): DashboardHub {\n const authoritiesKey = JSON.stringify(authorities ?? []);\n const hub = useMemo(\n () => new DashboardHub({ resolver, authorities }),\n // authorities read via authoritiesKey (value identity), not reference.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [resolver, authoritiesKey],\n );\n useEffect(() => () => hub.disposeAll(), [hub]);\n return hub;\n}\n\n// useResolvedBindings runs the scoped-slot cascade (ADR-039 selection amendment) for a\n// host: it takes the synchronous base manifest (effectiveBindings) plus the accumulated\n// selection overlay and returns the settled slot\u2192binding map the host feeds to the\n// renderer. Selection state lives in the host; this hook just derives bindings from it.\n//\n// The common scope-FREE dashboard needs no async work \u2014 the synchronous overlay (base\n// with the selection laid over it) is already correct, and the hook returns it directly,\n// preserving today's behavior. Only a dashboard with scoped slots runs the async pass,\n// guarded by a monotonic generation so a slow members response can't overwrite a newer\n// selection; it keeps the last settled map until the new one arrives (one re-key per\n// walk, never a stale partial). A resolution error is fail-safe: keep the last map.\nexport function useResolvedBindings(\n definition: DashboardDefinition,\n base: Record<string, SlotBinding>,\n selection: Record<string, SlotBinding>,\n resolver: MemberResolver,\n): Record<string, SlotBinding> {\n const scoped = useMemo(() => hasScopedSlots(definition), [definition]);\n // Selection wins over base. Correct as-is for root + manual slots and every scope-free\n // dashboard; scoped `first` slots are refined by the async pass below.\n const overlaid = useMemo(() => ({ ...base, ...selection }), [base, selection]);\n // Seed the settled map with scoped slots STRIPPED, so a scoped dashboard's first paint\n // is unbound-not-stale (a scoped slot's default may be out of context) until the cascade\n // derives it. For a scope-free dashboard this equals `overlaid`.\n const [resolved, setResolved] = useState(() => bindingsWithoutScopedSlots(definition, overlaid));\n const genRef = useRef(0);\n\n useEffect(() => {\n // Scope-free: `overlaid` is authoritative. Keep `resolved` synced to it anyway so that\n // if the definition later gains a scope (an authoring edit), the flip to the `resolved`\n // path starts from the CURRENT bindings, not a stale mount-time snapshot.\n if (!scoped) {\n setResolved((prev) => (sameBindings(prev, overlaid) ? prev : overlaid));\n return;\n }\n const gen = ++genRef.current;\n let live = true;\n resolveContextBindings(definition, base, selection, resolver)\n .then((next) => {\n if (!live || gen !== genRef.current) return;\n // Only swap when the value actually changed, so an equal re-resolve doesn't churn\n // a new object reference (and re-render every widget) for nothing.\n setResolved((prev) => (sameBindings(prev, next) ? prev : next));\n })\n .catch(() => {\n /* fail-safe: keep the last settled map */\n });\n return () => {\n live = false;\n };\n }, [scoped, definition, base, selection, resolver, overlaid]);\n\n return scoped ? resolved : overlaid;\n}\n\n// sameBindings is a value compare of two slot\u2192binding maps (stable-key JSON), so the\n// hook can suppress a no-op re-key.\nfunction sameBindings(a: Record<string, SlotBinding>, b: Record<string, SlotBinding>): boolean {\n const ak = Object.keys(a).sort();\n const bk = Object.keys(b).sort();\n if (ak.length !== bk.length) return false;\n for (let i = 0; i < ak.length; i += 1) {\n if (ak[i] !== bk[i]) return false;\n if (JSON.stringify(a[ak[i]]) !== JSON.stringify(b[bk[i]])) return false;\n }\n return true;\n}\n\n// useSlotCandidates builds the ambient candidate provider a host passes to the renderer\n// (ADR-039 selection amendment): a function slot\u2192candidates that a context/entity-selector\n// widget calls. It closes over the CURRENT resolved bindings, so it is rebuilt whenever a\n// binding changes \u2014 a selector's option set (a scoped child's members) then follows the\n// parent for free, and a widget re-fetches because the provider identity changed. Returns\n// undefined when no lister is supplied (a host that wires no selection), so the selector\n// stays inert. Keyed by the bindings' VALUE so an equal-but-new bindings object doesn't\n// churn the provider (and every open selector's fetch) each render.\nexport function useSlotCandidates(\n definition: DashboardDefinition,\n bindings: Record<string, SlotBinding>,\n resolver: MemberResolver,\n lister: EntityCandidateLister | undefined,\n): WidgetCandidates | undefined {\n const bindingsKey = JSON.stringify(bindings);\n return useMemo(\n () => {\n if (!lister) return undefined;\n return (slot: string) => resolveSlotCandidates(definition, slot, bindings, resolver, lister);\n },\n // bindings read via bindingsKey (value identity), not reference.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [definition, bindingsKey, resolver, lister],\n );\n}\n\n// The state a selector widget renders from: the target slot's current candidate options,\n// plus load/error flags. `wired` reports whether an ambient candidate provider exists \u2014 a\n// selector feature-detects on it (with the select callback) to stay inert where selection\n// isn't wired (edit/preview, a host that supplies no lister) rather than showing a dead picker.\nexport interface CandidatesState {\n candidates: SelectionCandidate[];\n loading: boolean;\n error: unknown | null;\n wired: boolean;\n}\n\n// useCandidates resolves the options a selector widget offers for `slot` through the ambient\n// candidate provider. Re-fetches when the provider (i.e. the resolved bindings) or the slot\n// changes, guarded by a monotonic generation so a slow list can't overwrite a newer one\n// (the parent-switch-then-open race). Fail-safe: an error yields an empty option set.\nexport function useCandidates(slot: string | undefined): CandidatesState {\n const provider = useWidgetCandidates();\n const wired = !!provider;\n // Seed loading true when a fetch is imminent (provider + slot present) so the first paint\n // reads \"Loading\u2026\", not a spurious \"No options\" for the frame before the effect runs.\n const [state, setState] = useState<Omit<CandidatesState, 'wired'>>(() => ({\n candidates: [],\n loading: Boolean(provider && slot),\n error: null,\n }));\n const genRef = useRef(0);\n\n useEffect(() => {\n if (!provider || !slot) {\n setState({ candidates: [], loading: false, error: null });\n return;\n }\n const gen = ++genRef.current;\n let live = true;\n // Clear any prior error when a fresh (healthy) fetch starts, so a retry doesn't show\n // \"Loading\u2026\" and a stale error banner together.\n setState((prev) => ({ ...prev, loading: true, error: null }));\n provider(slot)\n .then((candidates) => {\n if (live && gen === genRef.current) setState({ candidates, loading: false, error: null });\n })\n .catch((error: unknown) => {\n if (live && gen === genRef.current) setState({ candidates: [], loading: false, error });\n });\n return () => {\n live = false;\n };\n }, [provider, slot]);\n\n return { ...state, wired };\n}\n\nexport interface MeasurementStreamOptions {\n // Max samples retained in the rolling window (oldest dropped past this).\n window?: number;\n // Historical samples to seed the window with before live data arrives (from a\n // bucketedMeasurements backfill). Assumed chronological and older than the live\n // tail; live samples for the same measurement name override the seed's latest.\n initialSamples?: MeasurementSample[];\n}\n\nconst EMPTY: MeasurementStreamState = { latest: {}, samples: [], error: null };\n\n// Build a name\u2192last-sample map from a chronological list (last occurrence wins).\nfunction latestOf(samples: MeasurementSample[]): Record<string, MeasurementSample> {\n const latest: Record<string, MeasurementSample> = {};\n for (const s of samples) latest[s.name] = s;\n return latest;\n}\n\n// useMeasurementStream subscribes a widget's datasource through the hub and keeps\n// the latest value per measurement plus a bounded rolling window. It re-subscribes\n// when the datasource changes (compared by value, so a re-rendered-but-equal\n// selector doesn't churn the subscription) and tears down on unmount. When\n// initialSamples is given, it is merged ahead of the live tail so a chart shows\n// history immediately (and can arrive after the live stream opens).\nexport function useMeasurementStream(\n hub: WidgetDataSource,\n datasource: DatasourceSelector | undefined,\n options: MeasurementStreamOptions = {},\n): MeasurementStreamState {\n const windowSize = options.window ?? 300;\n const initialSamples = options.initialSamples;\n\n // Value-compare the selector so an unchanged-but-new object reference doesn't\n // resubscribe every render.\n const key = datasource ? JSON.stringify(datasource) : null;\n\n // The live buffer is TAGGED with the selector it was filled from. The effect below\n // resets it when the selector changes, but an effect runs after the render that\n // carried the new selector \u2014 so without the tag that render would show the previous\n // device's values under the new one. A buffer whose tag is not the current key is\n // treated as empty, synchronously.\n const [tagged, setTagged] = useState<{ key: string | null; state: MeasurementStreamState }>({\n key,\n state: EMPTY,\n });\n const live = tagged.key === key ? tagged.state : EMPTY;\n\n useEffect(() => {\n setTagged({ key, state: EMPTY }); // reset the live buffer whenever the datasource changes (or clears)\n if (!datasource) return;\n\n // A callback for a selector the buffer has already moved past (a sink that answers\n // after its subscription was released) leaves the buffer alone rather than re-tagging\n // it to the old selector, which would blank the current one's values.\n const update = (fn: (prev: MeasurementStreamState) => MeasurementStreamState) =>\n setTagged((prev) => (prev.key === key ? { key, state: fn(prev.state) } : prev));\n\n return hub.subscribeWidget(datasource, {\n next: (sample) =>\n update((prev) => {\n const samples = prev.samples.concat(sample);\n if (samples.length > windowSize) samples.splice(0, samples.length - windowSize);\n return { latest: { ...prev.latest, [sample.name]: sample }, samples, error: null };\n }),\n error: (err) => update((prev) => ({ ...prev, error: err })),\n });\n // `datasource` is intentionally read via `key` (value identity), not reference.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hub, key, windowSize]);\n\n // Layer the history seed under the live tail. Kept separate from the live buffer\n // so late-arriving history (async backfill) recomputes without touching the\n // subscription, and switching datasource clears live while the new seed applies.\n return useMemo(() => {\n if (!initialSamples || initialSamples.length === 0) return live;\n const merged = initialSamples.concat(live.samples);\n const samples =\n merged.length > windowSize ? merged.slice(merged.length - windowSize) : merged;\n return {\n latest: { ...latestOf(initialSamples), ...live.latest },\n samples,\n error: live.error,\n };\n }, [initialSamples, live, windowSize]);\n}\n\nconst EMPTY_ALARMS: AlarmStreamState = { alarms: [], total: 0, loading: true, error: null };\n\n// useAlarmStream binds an alarm widget's scope+filters through the hub's alarm channel\n// and keeps the latest snapshot. It re-subscribes when the subscription changes\n// (value-compared, so a re-rendered-but-equal object doesn't churn) and tears down on\n// unmount. The hub delivers whole snapshots (query-then-reconcile), so this holds the\n// last one rather than accumulating \u2014 the query is the source of truth.\nexport function useAlarmStream(\n hub: WidgetDataSource,\n subscription: AlarmSubscription,\n): AlarmStreamState {\n const [state, setState] = useState<AlarmStreamState>(EMPTY_ALARMS);\n\n // Value-compare the subscription so an unchanged-but-new object reference doesn't\n // resubscribe every render.\n const key = JSON.stringify(subscription);\n\n useEffect(() => {\n setState(EMPTY_ALARMS); // reset to loading whenever the subscription changes\n return hub.subscribeAlarms(subscription, {\n next: (snapshot) =>\n setState({ alarms: snapshot.alarms, total: snapshot.total, loading: false, error: null }),\n error: (err) => setState((prev) => ({ ...prev, loading: false, error: err })),\n });\n // `subscription` is intentionally read via `key` (value identity), not reference.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hub, key]);\n\n return state;\n}\n\nconst EMPTY_COMMANDS: CommandStreamState = {\n deviceToken: null,\n commands: [],\n total: 0,\n loading: true,\n error: null,\n};\n\n// useCommandStream binds a command widget's scope through the hub's control channel and\n// keeps the latest command-history snapshot. It re-subscribes when the subscription\n// changes (value-compared) and tears down on unmount. The hub delivers whole snapshots\n// (poll-then-emit), so this holds the last one rather than accumulating.\nexport function useCommandStream(\n hub: WidgetDataSource,\n subscription: CommandSubscription,\n): CommandStreamState {\n const [state, setState] = useState<CommandStreamState>(EMPTY_COMMANDS);\n\n // Value-compare the subscription so an unchanged-but-new object reference doesn't\n // resubscribe every render.\n const key = JSON.stringify(subscription);\n\n useEffect(() => {\n setState(EMPTY_COMMANDS); // reset to loading whenever the subscription changes\n return hub.subscribeCommands(subscription, {\n next: (snapshot) =>\n setState({\n deviceToken: snapshot.deviceToken,\n commands: snapshot.commands,\n total: snapshot.total,\n loading: false,\n error: null,\n }),\n error: (err) => setState((prev) => ({ ...prev, loading: false, error: err })),\n });\n // `subscription` is intentionally read via `key` (value identity), not reference.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hub, key]);\n\n return state;\n}\n\nconst EMPTY_LOCATIONS: LocationStreamState = {\n locations: [],\n deviceTokens: [],\n forbidden: false,\n loading: true,\n error: null,\n};\n\n// useLocationStream binds a map widget's selector through the hub's location channel and\n// keeps the latest position snapshot. It re-subscribes when the subscription changes\n// (value-compared, so a re-rendered-but-equal object doesn't churn) and tears down on\n// unmount. The hub delivers whole snapshots (poll-then-emit), so this holds the last one\n// rather than accumulating.\n//\n// A `forbidden` snapshot CLEARS the positions as it sets the flag: an authority can be\n// revoked mid-session, and keeping the last-seen coordinates on screen under a\n// permission banner would leave a refused viewer looking at the very data they were\n// just refused.\nexport function useLocationStream(\n hub: WidgetDataSource,\n subscription: LocationSubscription,\n): LocationStreamState {\n const [state, setState] = useState<LocationStreamState>(EMPTY_LOCATIONS);\n\n // Value-compare the subscription so an unchanged-but-new object reference doesn't\n // resubscribe every render.\n const key = JSON.stringify(subscription);\n\n useEffect(() => {\n setState(EMPTY_LOCATIONS); // reset to loading whenever the subscription changes\n return hub.subscribeLocations(subscription, {\n next: (snapshot) =>\n setState(\n snapshot.kind === 'forbidden'\n ? { locations: [], deviceTokens: [], forbidden: true, loading: false, error: null }\n : {\n locations: snapshot.locations,\n deviceTokens: snapshot.deviceTokens,\n forbidden: false,\n loading: false,\n error: null,\n },\n ),\n error: (err) => setState((prev) => ({ ...prev, loading: false, error: err })),\n });\n // `subscription` is intentionally read via `key` (value identity), not reference.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hub, key]);\n\n return state;\n}\n\n// A widget's bound-entity availability: 'unknown' until the async check resolves\n// (render optimistically meanwhile), then 'available', or 'unavailable' when the bound\n// device no longer exists (a deleted device's stable token, ADR-044).\nexport type DatasourceAvailability = 'unknown' | 'available' | 'unavailable';\n\n// While a widget shows \"unavailable\", re-check on this cadence so a device deleted then\n// recreated with the same token (ADR-042 frees tokens on delete) recovers on a long-lived\n// viewer without a reload. Only runs while unavailable \u2014 a live device is checked once.\nconst AVAILABILITY_REVALIDATE_MS = 60_000;\n\n// useDatasourceAvailability resolves whether a widget's bound device still exists,\n// WITHOUT blocking the widget's data stream (optimistic + async): it starts 'unknown'\n// (the widget renders normally), then flips to 'available'/'unavailable' once the hub's\n// existence check resolves. Fails open (\u2192'available') so a check outage never falsely\n// blanks a live widget. A widget with no datasource is trivially available (no query).\n// Re-checks when the datasource changes (value-compared), and periodically while\n// unavailable so a recreated device recovers.\nexport function useDatasourceAvailability(\n hub: WidgetDataSource,\n datasource: DatasourceSelector | undefined,\n): DatasourceAvailability {\n const [state, setState] = useState<DatasourceAvailability>('unknown');\n const key = datasource ? JSON.stringify(datasource) : null;\n\n useEffect(() => {\n // No datasource (label/image, or tenant-wide) has nothing to validate \u2014 available\n // immediately, no query, no re-render churn.\n if (!datasource) {\n setState('available');\n return;\n }\n setState('unknown');\n let cancelled = false;\n let timer: ReturnType<typeof setInterval> | undefined;\n\n const stopTimer = (): void => {\n if (timer) {\n clearInterval(timer);\n timer = undefined;\n }\n };\n\n const check = (): void => {\n hub\n .isDatasourceAvailable(datasource)\n .then((ok) => {\n if (cancelled) return;\n setState(ok ? 'available' : 'unavailable');\n if (ok) stopTimer(); // recovered (or was fine) \u2014 stop polling\n })\n .catch(() => {\n if (cancelled) return;\n setState('available'); // fail open\n stopTimer();\n });\n };\n\n check();\n // Poll only matters once unavailable; harmlessly runs until the first check clears it\n // for a live device (cleared in the resolver above, well before the first tick).\n timer = setInterval(check, AVAILABILITY_REVALIDATE_MS);\n\n return () => {\n cancelled = true;\n stopTimer();\n };\n // `datasource` is intentionally read via `key` (value identity), not reference.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hub, key]);\n\n return state;\n}\n\nexport interface ElementSize {\n width: number;\n height: number;\n}\n\n// useElementSize tracks an element's content-box size via ResizeObserver, so a\n// widget can scale its contents (chart fonts, gauge ticks, a big number) to the\n// slot it was resized to \u2014 ECharts' resize() re-lays-out the canvas but never\n// scales absolute font sizes, so a small widget crams without this. Returns\n// {0,0} until measured (and where ResizeObserver is unavailable, e.g. jsdom); the\n// consumers treat a zero size as \"use default sizing\".\nexport function useElementSize<T extends HTMLElement>(): [RefObject<T | null>, ElementSize] {\n const ref = useRef<T>(null);\n const [size, setSize] = useState<ElementSize>({ width: 0, height: 0 });\n\n useEffect(() => {\n const el = ref.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver((entries) => {\n const rect = entries[0]?.contentRect;\n if (!rect) return;\n setSize((prev) =>\n prev.width === rect.width && prev.height === rect.height\n ? prev\n : { width: rect.width, height: rect.height },\n );\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n\n return [ref, size];\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// @devicechain/widget-sdk \u2014 the supported surface for writing a dashboard widget.\n//\n// A widget is declared once with `defineWidget` (a portable, JSON-only descriptor plus a\n// trusted React component) and made available to a host by listing it in\n// `createWidgetRegistry`. The built-in widgets are declared through exactly this\n// interface. The descriptor vocabulary is React-free and lives in @devicechain/dashboards;\n// it is re-exported here so a widget package imports from one place.\n\nexport { defineWidget } from './define-widget';\nexport type { ErasedComponent, ErasedWidgetDefinition, WidgetDefinition, WidgetImplementation } from './define-widget';\nexport { createWidgetRegistry, WidgetRegistryError, type WidgetRegistry } from './registry';\nexport type {\n EditorCommandChoice,\n EditorCommandChoices,\n WidgetComponent,\n WidgetEditorProps,\n WidgetEditorServices,\n WidgetProps,\n} from './widget';\n\n// The ambient host contexts (selection, candidates, time zone, theme root, subject). Defined\n// in this package and nowhere else \u2014 see ./context.\nexport {\n WidgetCandidatesProvider,\n WidgetSelectProvider,\n WidgetSubjectProvider,\n WidgetThemeRootProvider,\n WidgetTimeZoneProvider,\n useWidgetCandidates,\n useWidgetSelect,\n useWidgetSubject,\n useWidgetThemeRoot,\n useWidgetTimeZone,\n type WidgetCandidates,\n type WidgetSelect,\n} from './context';\n\n// The building blocks every widget (built-in or third-party) composes from: the card frame,\n// theme-variable references, number/time formatting, the opt-in change-flash cue, option\n// readers, and the React bindings between the hub's channels and widget state. The chart\n// engine helpers are NOT here -- they are on the `/echarts` subpath, so importing this root\n// never pulls Apache ECharts (nor MapLibre, nor the built-in catalog).\nexport { WidgetFrame, type WidgetFrameProps } from './frame';\nexport { css, type ThemeVar } from './theme';\nexport { formatDateTime, formatTimestamp, formatValue } from './format';\nexport {\n FlashValue,\n flashBackgroundStyle,\n flashTextStyle,\n useFlashOnChange,\n type FlashDirection,\n} from './flash';\nexport { optBoolean, optNumber, optString, pickSample, primaryMeasurementName } from './widget-options';\nexport {\n useAlarmStream,\n useCandidates,\n useCommandStream,\n useDashboardHub,\n useDatasourceAvailability,\n useElementSize,\n useLocationStream,\n useMeasurementStream,\n useResolvedBindings,\n useSlotCandidates,\n type AlarmStreamState,\n type CandidatesState,\n type CommandStreamState,\n type DatasourceAvailability,\n type ElementSize,\n type LocationStreamState,\n type MeasurementStreamOptions,\n type MeasurementStreamState,\n} from './hooks';\n\n// The portable descriptor vocabulary.\nexport {\n SDK_API_VERSION,\n WidgetCatalogError,\n defineWidgetDescriptor,\n isBuiltinWidgetId,\n isNamespacedWidgetId,\n validateWidgetDescriptor,\n type AckOptionRef,\n type BooleanOptionSpec,\n type BuiltinWidgetId,\n type ChannelBindingPolicy,\n type ChannelSnapshot,\n type ConstBinding,\n type DatasourcePolicy,\n type DatasourceSelectorKind,\n type DefaultsOf,\n type DescriptorIssue,\n type EnumOptionSpec,\n type GreaterThanConstraint,\n type NamespacedWidgetId,\n type NumberOptionRef,\n type NumberOptionSpec,\n type OptionConstraint,\n type OptionSpec,\n type OptionsOf,\n type StringOptionRef,\n type StringOptionSpec,\n type WidgetCatalog,\n type WidgetChannel,\n type WidgetDescriptor,\n type WidgetDisplay,\n type WidgetId,\n type WidgetInteractionDeclaration,\n type WidgetOptionSpecs,\n} from '@devicechain/dashboards';\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["jsx", "useEffect", "useRef", "useState", "useEffect", "useState", "useRef", "WidgetCatalogError"]
|
|
7
|
-
}
|
package/dist/registry.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { WidgetCatalogError, type DescriptorIssue, type WidgetCatalog, type WidgetDescriptor } from '@devicechain/dashboards';
|
|
2
|
-
import type { ErasedWidgetDefinition } from './define-widget';
|
|
3
|
-
export declare class WidgetRegistryError extends WidgetCatalogError {
|
|
4
|
-
constructor(issues: readonly DescriptorIssue[]);
|
|
5
|
-
}
|
|
6
|
-
export interface WidgetRegistry {
|
|
7
|
-
readonly catalog: WidgetCatalog;
|
|
8
|
-
descriptor(id: string): WidgetDescriptor | undefined;
|
|
9
|
-
implementation(id: string): ErasedWidgetDefinition['implementation'] | undefined;
|
|
10
|
-
list(): readonly ErasedWidgetDefinition[];
|
|
11
|
-
}
|
|
12
|
-
export declare function createWidgetRegistry(definitions: readonly ErasedWidgetDefinition[]): WidgetRegistry;
|
package/dist/theme.d.ts
DELETED
package/dist/widget-options.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { MeasurementSample, WidgetInstance } from '@devicechain/dashboards';
|
|
2
|
-
export declare function pickSample(latest: Record<string, MeasurementSample>, name: string | undefined): MeasurementSample | undefined;
|
|
3
|
-
type Options = Record<string, unknown> | undefined;
|
|
4
|
-
export declare function optString(options: Options, key: string): string | undefined;
|
|
5
|
-
export declare function optNumber(options: Options, key: string): number | undefined;
|
|
6
|
-
export declare function optBoolean(options: Options, key: string): boolean;
|
|
7
|
-
export declare function primaryMeasurementName(widget: WidgetInstance): string | undefined;
|
|
8
|
-
export {};
|
package/dist/widget.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { MeasurementStreamState, SlotDefinition, WidgetActions, WidgetDescriptor, WidgetInstance } from '@devicechain/dashboards';
|
|
2
|
-
import type { ComponentType } from 'react';
|
|
3
|
-
export interface WidgetProps<D = MeasurementStreamState> {
|
|
4
|
-
widget: WidgetInstance;
|
|
5
|
-
data: D;
|
|
6
|
-
actions?: WidgetActions;
|
|
7
|
-
}
|
|
8
|
-
export type WidgetComponent<D = MeasurementStreamState> = ComponentType<WidgetProps<D>>;
|
|
9
|
-
export interface EditorCommandChoice {
|
|
10
|
-
commandKey: string;
|
|
11
|
-
name?: string | null;
|
|
12
|
-
parameterSchema?: string | null;
|
|
13
|
-
}
|
|
14
|
-
export interface EditorCommandChoices {
|
|
15
|
-
selectable: EditorCommandChoice[];
|
|
16
|
-
draftOnly: string[];
|
|
17
|
-
constrained: boolean;
|
|
18
|
-
}
|
|
19
|
-
export interface WidgetEditorServices {
|
|
20
|
-
readonly slots: Readonly<Record<string, SlotDefinition>>;
|
|
21
|
-
readonly deviceToken: string | undefined;
|
|
22
|
-
readonly commandChoices?: (deviceToken: string) => Promise<EditorCommandChoices>;
|
|
23
|
-
}
|
|
24
|
-
export interface WidgetEditorProps<O = Record<string, unknown>> {
|
|
25
|
-
readonly options: Readonly<Partial<O>>;
|
|
26
|
-
readonly setOptions: (patch: {
|
|
27
|
-
[K in keyof O]?: O[K] | undefined;
|
|
28
|
-
}) => void;
|
|
29
|
-
readonly services: WidgetEditorServices;
|
|
30
|
-
readonly descriptor: WidgetDescriptor;
|
|
31
|
-
}
|