@devicechain/widgets 0.22.0 → 0.23.0-rc.1

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.
Files changed (54) hide show
  1. package/README.md +15 -0
  2. package/dist/access-strings.d.ts +6 -0
  3. package/dist/chunks/{aggregate-feed-6ZYKOQOB.js → aggregate-feed-BD3CHNFU.js} +5 -4
  4. package/dist/chunks/aggregate-feed-BD3CHNFU.js.map +7 -0
  5. package/dist/chunks/{aggregate-widgets-WVXAW3UL.js → aggregate-widgets-HZQI5HTX.js} +3 -2
  6. package/dist/chunks/{aggregate-widgets-WVXAW3UL.js.map → aggregate-widgets-HZQI5HTX.js.map} +1 -1
  7. package/dist/chunks/alarm-widgets-7UY6MIYZ.js +9 -0
  8. package/dist/chunks/alarm-widgets-7UY6MIYZ.js.map +7 -0
  9. package/dist/chunks/chunk-6OGI4UFJ.js +367 -0
  10. package/dist/chunks/chunk-6OGI4UFJ.js.map +7 -0
  11. package/dist/chunks/chunk-BRH66T5F.js +15 -0
  12. package/dist/chunks/chunk-BRH66T5F.js.map +7 -0
  13. package/dist/chunks/chunk-FM7OI5TQ.js +87 -0
  14. package/dist/chunks/chunk-FM7OI5TQ.js.map +7 -0
  15. package/dist/chunks/chunk-USRYKW2J.js +55 -0
  16. package/dist/chunks/chunk-USRYKW2J.js.map +7 -0
  17. package/dist/chunks/{chunk-S2OMBJLI.js → chunk-WBKHYZU2.js} +7 -3
  18. package/dist/chunks/{chunk-S2OMBJLI.js.map → chunk-WBKHYZU2.js.map} +2 -2
  19. package/dist/chunks/chunk-XSLFHCNI.js +419 -0
  20. package/dist/chunks/chunk-XSLFHCNI.js.map +7 -0
  21. package/dist/chunks/{control-widgets-UDS4ET3T.js → control-widgets-3V2LSSRF.js} +4 -2
  22. package/dist/chunks/{control-widgets-UDS4ET3T.js.map → control-widgets-3V2LSSRF.js.map} +1 -1
  23. package/dist/chunks/entity-selector-3JJFI4DT.js +7 -0
  24. package/dist/chunks/entity-selector-3JJFI4DT.js.map +7 -0
  25. package/dist/chunks/{fleet-feed-FK4ZMKIK.js → fleet-feed-5QGDLOV5.js} +27 -7
  26. package/dist/chunks/fleet-feed-5QGDLOV5.js.map +7 -0
  27. package/dist/chunks/table-6EVV7QZH.js +7 -0
  28. package/dist/chunks/table-6EVV7QZH.js.map +7 -0
  29. package/dist/connected-widget.d.ts +2 -0
  30. package/dist/dashboard-renderer.d.ts +1 -0
  31. package/dist/fleet-feed.d.ts +1 -0
  32. package/dist/index.d.ts +1 -0
  33. package/dist/index.js +478 -1142
  34. package/dist/index.js.map +4 -4
  35. package/dist/preload.d.ts +2 -0
  36. package/dist/widgets/alarm-count.d.ts +0 -46
  37. package/dist/widgets/alarm-lazy.d.ts +123 -0
  38. package/dist/widgets/alarm-table.d.ts +0 -76
  39. package/dist/widgets/alarm-widgets.d.ts +2 -0
  40. package/dist/widgets/command-button.d.ts +0 -38
  41. package/dist/widgets/control-lazy.d.ts +38 -0
  42. package/dist/widgets/control-widgets.d.ts +1 -0
  43. package/dist/widgets/entity-selector.d.ts +0 -15
  44. package/dist/widgets/gauge.d.ts +4 -0
  45. package/dist/widgets/lazy-chunk.d.ts +2 -1
  46. package/dist/widgets/selection-lazy.d.ts +16 -0
  47. package/dist/widgets/table-lazy.d.ts +39 -0
  48. package/dist/widgets/table.d.ts +0 -38
  49. package/dist/widgets/time-series-chart.d.ts +4 -0
  50. package/package.json +10 -7
  51. package/dist/chunks/aggregate-feed-6ZYKOQOB.js.map +0 -7
  52. package/dist/chunks/chunk-YPFB6DAL.js +0 -157
  53. package/dist/chunks/chunk-YPFB6DAL.js.map +0 -7
  54. package/dist/chunks/fleet-feed-FK4ZMKIK.js.map +0 -7
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/widgets/command-status.ts", "../../src/widgets/command-params.ts", "../../src/widgets/command-button.tsx"],
4
+ "sourcesContent": ["// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Command delivery-status presentation for the command-button widget (command-delivery\n// lifecycle: QUEUED \u2192 SENT \u2192 SUCCESSFUL | FAILED, with HELD for a dispatch withheld from\n// a known-absent device, PARKED for one published to a device that turned out to be\n// unreachable, and TIMEOUT / EXPIRED / CANCELLED as the other terminals).\n// Status color is SEMANTIC (good/working/waiting/bad), deliberately fixed rather than\n// derived from the dashboard accent, so the same status reads the same on every theme \u2014\n// and it mirrors the console's DeviceCommandsPanel status variants (success /\n// destructive / outline / in-flight) so an operator reads the same signal on both\n// surfaces.\n\nimport { isTerminalCommandStatus } from '@devicechain/dashboards';\n\n// \uD83D\uDD34 EVERY STATUS NEEDS AN ENTRY, INCLUDING THE ONES THAT LOOK NEUTRAL. UNKNOWN_COLOR\n// below is the same slate as EXPIRED, so a status with no entry does not merely fall\n// back \u2014 it becomes INDISTINGUISHABLE from \"lapsed before it was sent\". HELD and PARKED\n// (the command is still coming) rendered in EXPIRED's slate tell an operator the opposite\n// of the truth, which is why they, and CANCELLED, are spelled out rather than left to the\n// fallback.\n//\n// The scheme is by MEANING, not by lifecycle position: sky = moving under its own steam,\n// amber = waiting on a device that isn't there. HELD and PARKED share the amber family\n// because they are the same answer to \"why hasn't it arrived?\" \u2014 the device is away \u2014 and\n// take different shades because they are different answers to \"what did the platform\n// already try?\": HELD never left the platform, PARKED was published and found nobody home.\nconst STATUS_COLORS: Record<string, string> = {\n SUCCESSFUL: '#16a34a', // green-600 \u2014 acknowledged by the device\n FAILED: '#dc2626', // red-600\n TIMEOUT: '#dc2626', // red-600 \u2014 never acknowledged in time\n EXPIRED: '#64748b', // slate-500 \u2014 lapsed before it was ever sent\n CANCELLED: '#7c3aed', // violet-600 \u2014 deliberately called off; a decision, not a failure\n QUEUED: '#0284c7', // sky-600 \u2014 in flight\n SENT: '#0284c7',\n HELD: '#d97706', // amber-600 \u2014 withheld: the device is absent, the command still stands\n PARKED: '#f59e0b', // amber-500 \u2014 published, nobody home; held for the device's return\n};\n\nconst UNKNOWN_COLOR = '#64748b';\n\n// commandStatusColor maps a status to its badge color, falling back to muted slate for\n// an unrecognized value (a future/hand-edited status).\nexport function commandStatusColor(status: string): string {\n return STATUS_COLORS[status] ?? UNKNOWN_COLOR;\n}\n\n// isTerminalStatus reports whether a command has reached a state it can't leave \u2014 the\n// widget stops treating it as in-flight.\n//\n// It is NOT the question \"can this still be cancelled?\": SENT is non-terminal and is not\n// cancellable, so a host gating a cancel control must ask @devicechain/dashboards'\n// isCancellableCommandStatus instead of negating this.\n//\n// It is an alias, not a second definition: the terminal set lives in @devicechain/dashboards\n// so the console, this package and the preview cannot disagree about it. The name is kept\n// because it is part of this package's published surface.\nexport function isTerminalStatus(status: string): boolean {\n return isTerminalCommandStatus(status);\n}\n\n// commandStatusLabel renders a status in Title Case ('SUCCESSFUL' \u2192 'Successful').\nexport function commandStatusLabel(status: string): string {\n if (!status) return '';\n return status.charAt(0).toUpperCase() + status.slice(1).toLowerCase();\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Pure form logic for the command-button widget's typed parameter form (ADR-043). The\n// console bakes a command definition's `parameterSchema` (a JSON string) into the\n// widget's options; these helpers parse it, seed defaults, validate operator input, and\n// serialize the typed values back to the JSON payload command-delivery sends the device.\n// Kept separate from the widget so the coercion/validation is unit-tested in isolation.\n//\n// SCOPE: the form types top-level SCALAR parameters (DOUBLE / INT / BOOLEAN / STRING,\n// with enum / bounds / required / default). OBJECT (nested) parameters are not\n// form-editable \u2014 the form blocks sending when one is REQUIRED (it can't be satisfied\n// here) and otherwise omits it. The payload is a flat JSON object keyed by parameter name.\n\nimport type { CommandParameter } from '@devicechain/dashboards';\n\nconst DATA_TYPES = new Set(['DOUBLE', 'INT', 'BOOLEAN', 'STRING']);\n\n// parseParameterSchema turns the baked JSON string into descriptors, defensively:\n// a null/empty/malformed schema (or a non-array root) yields an empty list so a command\n// with no arguments (or a hand-broken schema) renders as a bare Send button, never throws.\n// Each descriptor is NORMALIZED (enum\u2192string[], default\u2192string, bounds\u2192finite number,\n// kind/dataType\u2192known value) so a hand-edited dashboard definition with wrong-typed fields\n// (e.g. `enum: \"on\"` or `default: 5`) can't crash the form at render/send time.\nexport function parseParameterSchema(schema: string | null | undefined): CommandParameter[] {\n if (!schema) return [];\n let parsed: unknown;\n try {\n parsed = JSON.parse(schema);\n } catch {\n return [];\n }\n if (!Array.isArray(parsed)) return [];\n const out: CommandParameter[] = [];\n for (const raw of parsed) {\n const norm = normalizeParam(raw);\n if (norm) out.push(norm);\n }\n return out;\n}\n\n// normalizeParam validates one descriptor and coerces every field to its expected type,\n// dropping the descriptor entirely if it has no string `name`. Unknown/wrong-typed fields\n// are discarded rather than trusted, so downstream code never sees a non-array enum or a\n// numeric default.\nfunction normalizeParam(raw: unknown): CommandParameter | null {\n if (typeof raw !== 'object' || raw === null) return null;\n const r = raw as Record<string, unknown>;\n if (typeof r.name !== 'string') return null;\n\n const param: CommandParameter = { name: r.name };\n if (typeof r.description === 'string') param.description = r.description;\n if (r.kind === 'OBJECT') param.kind = 'OBJECT';\n else if (r.kind === 'SCALAR') param.kind = 'SCALAR';\n if (typeof r.dataType === 'string' && DATA_TYPES.has(r.dataType)) {\n param.dataType = r.dataType as CommandParameter['dataType'];\n }\n if (typeof r.unit === 'string') param.unit = r.unit;\n if (r.required === true) param.required = true;\n if (typeof r.default === 'string') param.default = r.default;\n if (typeof r.minValue === 'number' && Number.isFinite(r.minValue)) param.minValue = r.minValue;\n if (typeof r.maxValue === 'number' && Number.isFinite(r.maxValue)) param.maxValue = r.maxValue;\n if (Array.isArray(r.enum)) {\n const values = r.enum.filter((v): v is string => typeof v === 'string');\n if (values.length > 0) param.enum = values;\n }\n return param;\n}\n\n// isScalar reports whether a parameter is a typed single value the form renders an input\n// for. Kind absent means SCALAR (the Go default); only an explicit OBJECT is nested.\nexport function isScalar(param: CommandParameter): boolean {\n return param.kind !== 'OBJECT';\n}\n\n// parseBool interprets a schema/string boolean the way the server's strconv.ParseBool\n// does (accepting '1'/'t'/'true'/'yes'/'on', case-insensitively) so a definition default\n// of \"True\" doesn't silently render \u2014 and send \u2014 as false.\nexport function parseBool(raw: string): boolean {\n const s = raw.trim().toLowerCase();\n return s === 'true' || s === '1' || s === 't' || s === 'yes' || s === 'on';\n}\n\n// defaultValues seeds the form's value map from each scalar parameter. A BOOLEAN always\n// gets a concrete 'true'/'false' (default false) \u2014 a checkbox is never \"empty\", so the\n// value must reflect the box's state exactly. Other scalars seed from their declared\n// default (as a string \u2014 inputs are string-backed), else start empty.\nexport function defaultValues(params: CommandParameter[]): Record<string, string> {\n const values: Record<string, string> = {};\n for (const p of params) {\n if (!isScalar(p)) continue;\n if (p.dataType === 'BOOLEAN') values[p.name] = parseBool(p.default ?? '') ? 'true' : 'false';\n else if (p.default != null) values[p.name] = p.default;\n }\n return values;\n}\n\n// validateParams returns a per-parameter error map (empty = valid). It enforces required\n// (a missing value on a required scalar; a BOOLEAN always has a value so is never\n// \"required-missing\"), numeric validity/bounds for INT/DOUBLE, and blocks a REQUIRED\n// OBJECT parameter (it can't be supplied through the typed form).\nexport function validateParams(\n params: CommandParameter[],\n values: Record<string, string>,\n): Record<string, string> {\n const errors: Record<string, string> = {};\n for (const p of params) {\n if (!isScalar(p)) {\n // A required structured parameter can't be satisfied here \u2014 refuse to send an\n // incomplete command rather than silently omitting it.\n if (p.required) errors[p.name] = 'Structured parameter \u2014 not supported here';\n continue;\n }\n if (p.dataType === 'BOOLEAN') continue; // a checkbox always carries a valid value\n const raw = (values[p.name] ?? '').trim();\n if (raw === '') {\n if (p.required) errors[p.name] = 'Required';\n continue; // an empty optional value is fine \u2014 it's just omitted from the payload\n }\n if (p.dataType === 'INT' || p.dataType === 'DOUBLE') {\n const n = Number(raw);\n if (!Number.isFinite(n)) {\n errors[p.name] = 'Must be a number';\n } else if (p.dataType === 'INT' && !Number.isInteger(n)) {\n errors[p.name] = 'Must be a whole number';\n } else if (p.minValue != null && n < p.minValue) {\n errors[p.name] = `Must be \u2265 ${p.minValue}`;\n } else if (p.maxValue != null && n > p.maxValue) {\n errors[p.name] = `Must be \u2264 ${p.maxValue}`;\n }\n }\n }\n return errors;\n}\n\n// buildPayload serializes the typed values to the JSON payload string command-delivery\n// sends the device \u2014 coercing each scalar to its declared type (INT/DOUBLE \u2192 number,\n// BOOLEAN \u2192 boolean, STRING \u2192 string). A BOOLEAN is always included (its checkbox state\n// is meaningful); other empty optional values are omitted. OBJECT parameters are omitted\n// (validateParams blocks a required one first). Returns undefined when no parameter\n// contributes a value (a parameterless command sends no payload).\nexport function buildPayload(\n params: CommandParameter[],\n values: Record<string, string>,\n): string | undefined {\n const payload: Record<string, unknown> = {};\n for (const p of params) {\n if (!isScalar(p)) continue;\n const raw = (values[p.name] ?? '').trim();\n if (p.dataType === 'BOOLEAN') {\n payload[p.name] = parseBool(raw);\n continue;\n }\n if (raw === '') continue;\n payload[p.name] = coerce(p, raw);\n }\n return Object.keys(payload).length === 0 ? undefined : JSON.stringify(payload);\n}\n\nfunction coerce(param: CommandParameter, raw: string): unknown {\n switch (param.dataType) {\n case 'INT':\n case 'DOUBLE': {\n const n = Number(raw);\n return Number.isFinite(n) ? n : raw; // validation gates this; fall back to raw defensively\n }\n case 'BOOLEAN':\n return parseBool(raw);\n default:\n return raw; // STRING (and untyped)\n }\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// command-button \u2014 issue a device command from the dashboard and watch its delivery\n// lifecycle (command-delivery). The console bakes a command definition into the widget's\n// options at author time (its name + parameterSchema); this renders a typed form from\n// that schema, issues via the action seam (gated on command:write), and shows the recent\n// commands for the target device with live status (QUEUED \u2192 SENT \u2192\n// SUCCESSFUL / FAILED \u2026), so an operator can see whether a command was acted on rather\n// than only that it was sent. Bound through the hub's control channel, so it renders identically from live\n// data or the synthetic preview source.\n//\n// The baked schema is a SNAPSHOT taken when the author picked the command: a later edit\n// to the profile's command definition (a changed schema, or a deleted command) leaves\n// this widget's form stale until the author re-picks it. That's acceptable \u2014 dashboards\n// are opaque snapshots \u2014 and a since-removed command fails visibly at the delivery\n// boundary (the server validates device existence and JSON); it isn't silently wrong.\n\nimport type { CommandDispatch, CommandParameter } from '@devicechain/dashboards';\nimport { useEffect, useMemo, useRef, useState, type CSSProperties } from 'react';\n\nimport {\n type CommandStreamState,\n css,\n fontVar,\n formatDateTime,\n optString,\n useWidgetTimeZone,\n WidgetFrame,\n type WidgetProps,\n} from '@devicechain/widget-sdk';\n\nimport { commandStatusColor, commandStatusLabel } from './command-status';\nimport {\n buildPayload,\n defaultValues,\n isScalar,\n parseBool,\n parseParameterSchema,\n validateParams,\n} from './command-params';\n\nexport function CommandButton({ widget, data, actions }: WidgetProps<CommandStreamState>) {\n const commandName = optString(widget.options, 'commandName');\n const commandLabel = optString(widget.options, 'commandLabel') ?? commandName;\n const parameterSchema = optString(widget.options, 'parameterSchema') ?? null;\n\n const params = useMemo(() => parseParameterSchema(parameterSchema), [parameterSchema]);\n // A stable key over the configured command: reset the form when the author repoints\n // the widget at a different command (or edits its schema).\n const schemaKey = `${commandName ?? ''}::${parameterSchema ?? ''}`;\n\n const [values, setValues] = useState<Record<string, string>>(() => defaultValues(params));\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [pending, setPending] = useState(false);\n const [sendError, setSendError] = useState<string | null>(null);\n const [sentToken, setSentToken] = useState<string | null>(null);\n // Bumped whenever the configured command changes; an in-flight send captures the\n // current value and drops its result if it settles after a repoint (so command A's\n // dispatch token/error can't land under a freshly-configured command B).\n const sendGen = useRef(0);\n\n // Reset the form to the schema's defaults whenever the configured command changes.\n useEffect(() => {\n sendGen.current += 1;\n setValues(defaultValues(params));\n setErrors({});\n setSendError(null);\n setSentToken(null);\n // params is derived from schemaKey; keying on schemaKey avoids re-running on an\n // equal-but-new params array reference.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [schemaKey]);\n\n const canWrite = actions?.can('command:write') ?? false;\n const hasSeam = typeof actions?.sendCommand === 'function';\n const deviceToken = data.deviceToken;\n // The form is operable only when the viewer may write AND the runtime supplies the send\n // seam; a read-only mount shows the form disabled. Sending additionally needs a bound\n // target device and a configured command.\n const formDisabled = !canWrite || !hasSeam || pending;\n const canSend = !formDisabled && !!deviceToken && !!commandName;\n\n const setField = (name: string, value: string) => {\n setValues((prev) => ({ ...prev, [name]: value }));\n // Clear a field's error as the operator edits it.\n setErrors((prev) => (prev[name] ? { ...prev, [name]: '' } : prev));\n setSendError(null);\n };\n\n const send = () => {\n if (!deviceToken || !commandName || !actions?.sendCommand) return;\n const found = validateParams(params, values);\n const active = Object.fromEntries(Object.entries(found).filter(([, v]) => v));\n if (Object.keys(active).length > 0) {\n setErrors(active);\n return;\n }\n const payload = buildPayload(params, values);\n const gen = sendGen.current; // capture: drop the result if the command is repointed mid-flight\n setPending(true);\n setSendError(null);\n // Call synchronously so a dispatch is observable, but guard a synchronous throw so a\n // misbehaving seam can't leave the button stuck-disabled.\n let promise: Promise<CommandDispatch>;\n try {\n promise = actions.sendCommand(deviceToken, commandName, payload);\n } catch {\n setSendError(SEND_FAILED);\n setPending(false);\n return;\n }\n promise\n .then((dispatch) => {\n if (gen !== sendGen.current) return;\n // \uD83D\uDD34 A REFUSAL IS SHOWN, A FAILURE IS NOT. The server decided this command was\n // wrong and said why in client-safe terms (an unknown command for this device, a\n // parameter that violates the schema, the tenant's held-command ceiling) \u2014 that\n // reason is the whole point of the answer, and an operator can act on it. A\n // thrown error, below, is an availability failure: it says nothing about the\n // command, and its text is internal, so it gets one fixed message instead.\n if (dispatch.status === 'rejected') {\n setSendError(dispatch.reason);\n return;\n }\n setSentToken(dispatch.token);\n })\n .catch(() => {\n if (gen === sendGen.current) setSendError(SEND_FAILED);\n })\n .finally(() => {\n if (gen === sendGen.current) setPending(false);\n });\n };\n\n return (\n <WidgetFrame title={optString(widget.options, 'title')}>\n {/* A short widget (its minimum is two rows, and a cell on a phone is ~56 px) scrolls the\n form down rather than cutting off the send button or the line explaining why it is off. */}\n <div style={{ display: 'flex', flexDirection: 'column', height: '100%', gap: 10, overflowY: 'auto' }}>\n {!commandName ? (\n <div style={{ ...hint, margin: 'auto' }}>No command configured.</div>\n ) : (\n <>\n {/* Typed parameter form. */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8, flexShrink: 0 }}>\n {params.map((param) =>\n isScalar(param) ? (\n <ParamField\n key={param.name}\n widgetId={widget.id}\n param={param}\n value={values[param.name] ?? ''}\n error={errors[param.name]}\n disabled={formDisabled}\n onChange={(v) => setField(param.name, v)}\n />\n ) : (\n // A structured (OBJECT) parameter isn't form-editable. A REQUIRED one\n // blocks sending (validateParams flags it); flag that in the note.\n <div key={param.name} style={{ ...hint, color: param.required ? commandStatusColor('FAILED') : css('muted-foreground') }}>\n {param.name}: {param.required ? 'required ' : ''}structured parameter \u2014 not supported here.\n </div>\n ),\n )}\n\n <button\n type=\"button\"\n style={{ ...sendButton, opacity: canSend ? 1 : 0.55, cursor: canSend ? 'pointer' : 'not-allowed' }}\n disabled={!canSend}\n aria-busy={pending}\n onClick={send}\n >\n {pending ? 'Sending\u2026' : `Send ${commandLabel}`}\n </button>\n\n {!canWrite ? (\n <div style={hint}>You don\u2019t have permission to issue commands.</div>\n ) : !hasSeam ? (\n <div style={hint}>Commands aren\u2019t available in this view.</div>\n ) : !deviceToken ? (\n <div style={hint}>No device is selected for this command.</div>\n ) : null}\n {sendError ? (\n <div role=\"alert\" style={{ ...hint, color: commandStatusColor('FAILED') }}>\n {sendError}\n </div>\n ) : null}\n </div>\n\n {/* Recent-command history with live delivery status. */}\n <CommandHistory commands={data.commands} sentToken={sentToken} loading={data.loading} error={data.error} />\n </>\n )}\n </div>\n </WidgetFrame>\n );\n}\n\n// \u2500\u2500 Parameter field \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction ParamField({\n widgetId,\n param,\n value,\n error,\n disabled,\n onChange,\n}: {\n widgetId: string;\n param: CommandParameter;\n value: string;\n error?: string;\n disabled: boolean;\n onChange: (value: string) => void;\n}) {\n // Scope the input id to the widget so two command-buttons sharing a parameter name\n // don't produce duplicate DOM ids (which would misdirect a label click to the first).\n const labelId = `cmd-${widgetId}-${param.name}`;\n const unit = param.unit ? ` (${param.unit})` : '';\n return (\n <label htmlFor={labelId} style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>\n <span style={{ fontSize: fontVar('sm'), color: css('muted-foreground') }}>\n {param.name}\n {unit}\n {param.required ? <span style={{ color: commandStatusColor('FAILED') }}> *</span> : null}\n </span>\n <ParamInput id={labelId} param={param} value={value} disabled={disabled} onChange={onChange} />\n {error ? (\n <span style={{ fontSize: fontVar('xs'), color: commandStatusColor('FAILED') }}>{error}</span>\n ) : null}\n </label>\n );\n}\n\nfunction ParamInput({\n id,\n param,\n value,\n disabled,\n onChange,\n}: {\n id: string;\n param: CommandParameter;\n value: string;\n disabled: boolean;\n onChange: (value: string) => void;\n}) {\n // An enum (of any data type) \u2192 a select; a boolean \u2192 a checkbox; a number \u2192 a numeric\n // input with the declared bounds; everything else \u2192 text.\n if (param.enum && param.enum.length > 0) {\n return (\n <select id={id} style={inputStyle} value={value} disabled={disabled} onChange={(e) => onChange(e.target.value)}>\n {!param.required ? <option value=\"\">\u2014</option> : null}\n {param.enum.map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n );\n }\n if (param.dataType === 'BOOLEAN') {\n return (\n <input\n id={id}\n type=\"checkbox\"\n style={{ width: 16, height: 16 }}\n checked={parseBool(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.checked ? 'true' : 'false')}\n />\n );\n }\n const numeric = param.dataType === 'INT' || param.dataType === 'DOUBLE';\n return (\n <input\n id={id}\n type={numeric ? 'number' : 'text'}\n style={inputStyle}\n value={value}\n disabled={disabled}\n min={param.minValue ?? undefined}\n max={param.maxValue ?? undefined}\n step={param.dataType === 'INT' ? 1 : 'any'}\n placeholder={param.default ?? undefined}\n onChange={(e) => onChange(e.target.value)}\n />\n );\n}\n\n// \u2500\u2500 History \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction CommandHistory({\n commands,\n sentToken,\n loading,\n error,\n}: {\n commands: CommandStreamState['commands'];\n sentToken: string | null;\n loading: boolean;\n error: unknown;\n}) {\n // An error is shown inline here (not by replacing the whole widget) so a transient poll\n // blip never tears down the still-usable send form. Last-good rows stay on screen when\n // present; only an empty-and-errored history shows the notice.\n const empty = commands.length === 0;\n const timeZone = useWidgetTimeZone();\n return (\n <div\n style={{\n flex: 1,\n minHeight: 0,\n overflow: 'auto',\n borderTop: `1px solid ${css('border')}`,\n paddingTop: 6,\n }}\n >\n {empty ? (\n <div style={{ ...hint, textAlign: 'center', color: error ? commandStatusColor('FAILED') : css('muted-foreground') }}>\n {error ? 'Couldn\u2019t load command history.' : loading ? 'Loading\u2026' : 'No commands issued yet.'}\n </div>\n ) : (\n <ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 4 }}>\n {commands.map((command) => (\n <li\n key={command.token}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n fontSize: fontVar('sm'),\n // Highlight the command just issued from this widget.\n fontWeight: command.token === sentToken ? 600 : 400,\n }}\n >\n <StatusBadge status={command.status} />\n <span style={{ color: css('foreground'), whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>\n {command.name}\n </span>\n <span style={{ marginLeft: 'auto', color: css('muted-foreground'), whiteSpace: 'nowrap' }}>\n {formatDateTime(command.queuedTime, timeZone)}\n </span>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n\nfunction StatusBadge({ status }: { status: string }) {\n const color = commandStatusColor(status);\n return (\n <span\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n flexShrink: 0,\n fontSize: fontVar('xs'),\n fontWeight: 600,\n color,\n }}\n >\n <span aria-hidden=\"true\" style={{ width: 7, height: 7, borderRadius: '50%', background: color }} />\n {commandStatusLabel(status)}\n </span>\n );\n}\n\n// \u2500\u2500 styles / helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst hint: CSSProperties = { fontSize: fontVar('xs'), color: css('muted-foreground') };\n\n// What a viewer is told when the platform could not decide the enqueue. It is fixed\n// prose on purpose: the thrown error's text describes in-cluster machinery, and a\n// dashboard is the surface most likely to be embedded outside the tenant's own console.\nconst SEND_FAILED = 'Couldn\u2019t issue the command. Try again.';\n\nconst inputStyle: CSSProperties = {\n width: '100%',\n boxSizing: 'border-box',\n padding: '4px 8px',\n fontSize: fontVar('md'),\n borderRadius: 4,\n border: `1px solid ${css('border')}`,\n background: css('background'),\n color: css('foreground'),\n};\n\nconst sendButton: CSSProperties = {\n padding: '6px 12px',\n fontSize: fontVar('md'),\n fontWeight: 600,\n borderRadius: 4,\n border: 'none',\n background: css('primary'),\n color: css('background'),\n marginTop: 2,\n};\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,11 +1,12 @@
1
1
  import {
2
+ CommandButton,
2
3
  buildPayload,
3
4
  commandStatusColor,
4
5
  commandStatusLabel,
5
6
  isScalar,
6
7
  parseParameterSchema,
7
8
  validateParams
8
- } from "./chunk-YPFB6DAL.js";
9
+ } from "./chunk-XSLFHCNI.js";
9
10
 
10
11
  // src/widgets/command-slider.tsx
11
12
  import { useEffect as useEffect2, useId, useMemo, useRef as useRef2, useState as useState2 } from "react";
@@ -769,7 +770,8 @@ function ToggleBody({
769
770
  );
770
771
  }
771
772
  export {
773
+ CommandButton,
772
774
  CommandSlider,
773
775
  CommandToggle
774
776
  };
775
- //# sourceMappingURL=control-widgets-UDS4ET3T.js.map
777
+ //# sourceMappingURL=control-widgets-3V2LSSRF.js.map
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/widgets/command-slider.tsx", "../../src/command-control-core.ts", "../../src/command-control.tsx", "../../src/command-control-strings.ts", "../../src/widgets/command-toggle.tsx"],
4
4
  "sourcesContent": ["// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// command-slider \u2014 sends a command carrying ONE numeric parameter, chosen with a slider. The range\n// comes from the command definition baked into the options (the same snapshot the command button\n// renders its form from); the author's min/max/step fill only what the definition leaves open.\n//\n// \uD83D\uDD34 DRAGGING SENDS NOTHING. The thumb stages a value; releasing it on the slider (or pressing\n// Enter, for a keyboard user) sends it, once. A staged value that is not committed is DISCARDED,\n// never sent later: a cancelled pointer (the browser took the gesture for a scroll), a lost\n// capture or a release off the slider, Escape, or focus leaving the slider. While a send is in\n// flight the slider is aria-disabled and ignores input, so a second release cannot queue a second\n// command; it is not `disabled`, which would drop a keyboard user's focus on the page body.\n//\n// Keyboard: the arrow, Page and Home/End keys stage a value (the native range input's own\n// behaviour, so aria-valuetext follows the staged value) and Enter sends it. That departure from a\n// plain slider is announced: the input is described by a hint saying so, as well as by the\n// last-sent caption, which reads \"Not sent yet. ... press Enter to send\" while a value is staged.\n//\n// \uD83D\uDD34 IT SHOWS WHAT WAS SENT, NOT WHAT THE DEVICE IS DOING. The thumb rests at the last value sent\n// (read off the command history) and the caption says so with that command's delivery status.\n// With nothing sent the thumb rests at the bottom of the range and the readout is a dash.\n\nimport { useEffect, useId, useMemo, useRef, useState, type ReactNode } from 'react';\n\nimport {\n css,\n FIT_MIN_FONT_PX,\n fitValueFont,\n fitValueFontCss,\n fontVar,\n optNumber,\n optString,\n spaceVar,\n useStickyChars,\n WidgetFrame,\n type CommandStreamState,\n type WidgetProps,\n type WidgetScale,\n} from '@devicechain/widget-sdk';\n\nimport {\n bindControl,\n clampToRange,\n lastSent,\n payloadFor,\n type Binding,\n} from '../command-control-core';\nimport {\n ControlEmpty,\n ControlNotes,\n readOnlyId,\n LastSentCaption,\n refusalText,\n TOUCH_TARGET_PX,\n useCommandSender,\n type CommandSender,\n} from '../command-control';\n\ntype Bound = Extract<Binding, { ok: true }>;\n\nconst withUnit = (v: number, unit: string | undefined) => (unit ? `${v} ${unit}` : String(v));\n\nexport function CommandSlider({ widget, data, actions }: WidgetProps<CommandStreamState>) {\n const commandName = optString(widget.options, 'commandName');\n const commandLabel = optString(widget.options, 'commandLabel') ?? commandName;\n const parameterSchema = optString(widget.options, 'parameterSchema') ?? null;\n const parameter = optString(widget.options, 'parameter');\n const min = optNumber(widget.options, 'min');\n const max = optNumber(widget.options, 'max');\n const step = optNumber(widget.options, 'step');\n\n const binding = useMemo(\n () => bindControl('number', { commandName, parameterSchema, parameter, min, max, step }),\n [commandName, parameterSchema, parameter, min, max, step],\n );\n const sender = useCommandSender(\n actions,\n data.deviceToken,\n commandName,\n `${commandName ?? ''}::${parameterSchema ?? ''}::${parameter ?? ''}`,\n );\n\n const last =\n binding.ok && commandName\n ? lastSent('number', data.commands, commandName, binding.param.name, sender.optimistic)\n : null;\n\n // The staged value. A ref mirrors it so a release reads what the last change set, not the value\n // the previous render closed over.\n const [draft, setDraftState] = useState<number | null>(null);\n const draftRef = useRef<number | null>(null);\n const setDraft = (v: number | null) => {\n draftRef.current = v;\n setDraftState(v);\n };\n const captionId = useId();\n const hintId = useId();\n\n // A pointer pressed on the slider whose release has not been seen. A release anywhere but on\n // the slider, a cancel or a lost capture while it is set discards the staged value.\n const pressed = useRef(false);\n const offRelease = useRef<(() => void) | null>(null);\n useEffect(() => () => offRelease.current?.(), []);\n const discard = () => {\n pressed.current = false;\n offRelease.current?.();\n offRelease.current = null;\n if (draftRef.current !== null) setDraft(null);\n };\n const press = (input: HTMLInputElement) => {\n pressed.current = true;\n offRelease.current?.();\n const doc = input.ownerDocument;\n const onRelease = (e: PointerEvent) => {\n // The slider's own release commits through onPointerUp; this one sees releases elsewhere.\n if (e.target instanceof Node && input.contains(e.target)) return;\n discard();\n };\n doc.addEventListener('pointerup', onRelease, true);\n offRelease.current = () => doc.removeEventListener('pointerup', onRelease, true);\n };\n\n const commit = () => {\n if (!binding.ok) return;\n const staged = draftRef.current;\n if (staged === null || !sender.canSend) return;\n if (sender.send(payloadFor(binding, staged), staged)) setDraft(null);\n };\n const release = () => {\n pressed.current = false;\n offRelease.current?.();\n offRelease.current = null;\n commit();\n };\n\n return (\n <WidgetFrame title={optString(widget.options, 'title')}>\n {(scale) =>\n !binding.ok ? (\n <ControlEmpty message={refusalText(binding.refusal, sender.strings, 'number')} />\n ) : (\n <SliderBody\n binding={binding}\n label={commandLabel ?? binding.param.name}\n draft={draft}\n lastValue={typeof last?.value === 'number' ? last.value : undefined}\n sender={sender}\n captionId={captionId}\n hintId={hintId}\n caption={\n <LastSentCaption\n id={captionId}\n last={last}\n strings={sender.strings}\n truncated={data.total > data.commands.length}\n format={(v) => (typeof v === 'number' ? withUnit(v, binding.param.unit) : sender.strings.noValue)}\n override={draft !== null ? sender.strings.unsent : sender.pending ? sender.strings.sending : undefined}\n />\n }\n onStage={(v) => {\n // A value moved while a send is in flight is not staged: the slider is aria-disabled.\n if (!sender.pending) setDraft(clampToRange(binding.range!, v));\n }}\n onCommit={commit}\n onPress={press}\n onRelease={release}\n onDiscard={discard}\n onLostCapture={() => {\n if (pressed.current) discard();\n }}\n scale={scale}\n />\n )\n }\n </WidgetFrame>\n );\n}\n\nfunction SliderBody({\n binding,\n label,\n draft,\n lastValue,\n sender,\n captionId,\n hintId,\n caption,\n onStage,\n onCommit,\n onPress,\n onRelease,\n onDiscard,\n onLostCapture,\n scale: ws,\n}: {\n binding: Bound;\n label: string;\n draft: number | null;\n lastValue: number | undefined;\n sender: CommandSender;\n captionId: string;\n hintId: string;\n caption: ReactNode;\n onStage: (v: number) => void;\n onCommit: () => void;\n onPress: (input: HTMLInputElement) => void;\n onRelease: () => void;\n onDiscard: () => void;\n onLostCapture: () => void;\n scale: WidgetScale;\n}) {\n const range = binding.range!;\n const unit = binding.param.unit;\n // Read-only is `disabled`; in flight is only aria-disabled, so focus stays on the slider.\n const disabled = !sender.canSend;\n const busy = sender.pending;\n const rest = lastValue !== undefined ? clampToRange(range, lastValue) : range.min;\n const shown = draft ?? rest;\n const known = draft !== null || lastValue !== undefined;\n const readout = known ? String(shown) : '\u2014';\n\n // The readout fits the room left beside the track, with the same curve the value widgets use.\n const chars = useStickyChars(readout.length + (unit && known ? Math.ceil(unit.length / 2) + 1 : 0));\n const floor = Math.round(FIT_MIN_FONT_PX * ws.scale);\n const measured = ws.size.width > 0 && ws.size.height > 0;\n const room = {\n width: Math.floor(ws.size.width * 0.34),\n height: Math.max(TOUCH_TARGET_PX, Math.floor(ws.size.height * 0.5)),\n };\n const font = measured ? fitValueFont(room, chars, { floor }) : fitValueFontCss(chars, { floor });\n\n return (\n <div\n style={{\n height: '100%',\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'safe center',\n gap: spaceVar(1),\n overflow: 'hidden',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: spaceVar(2), minHeight: TOUCH_TARGET_PX }}>\n <input\n type=\"range\"\n aria-label={label}\n aria-valuetext={withUnit(shown, unit)}\n aria-describedby={`${hintId} ${captionId}${sender.readOnlyReason ? ` ${readOnlyId(captionId)}` : ''}`}\n aria-disabled={busy || undefined}\n aria-busy={busy || undefined}\n min={range.min}\n max={range.max}\n step={range.step}\n value={shown}\n disabled={disabled}\n data-staged={draft !== null ? 'true' : undefined}\n onChange={(e) => onStage(Number(e.target.value))}\n onPointerDown={(e) => onPress(e.currentTarget)}\n onPointerUp={onRelease}\n onPointerCancel={onDiscard}\n onLostPointerCapture={onLostCapture}\n onBlur={onDiscard}\n onKeyDown={(e) => {\n if (e.key === 'Enter') onCommit();\n else if (e.key === 'Escape') onDiscard();\n }}\n style={{\n flex: '1 1 0',\n minWidth: 0,\n height: TOUCH_TARGET_PX,\n margin: 0,\n accentColor: css('primary'),\n cursor: disabled || busy ? 'not-allowed' : 'pointer',\n }}\n />\n <span id={hintId} hidden>\n {sender.strings.sliderHint}\n </span>\n <output\n aria-hidden=\"true\"\n data-slider-readout=\"\"\n style={{\n flex: '0 0 auto',\n fontSize: font,\n fontWeight: 600,\n lineHeight: 1.1,\n whiteSpace: 'nowrap',\n fontVariantNumeric: 'tabular-nums',\n color: draft !== null ? css('foreground') : css('muted-foreground'),\n }}\n >\n {readout}\n {unit && known ? (\n <span style={{ fontSize: fontVar('sm'), marginLeft: spaceVar(1), color: css('muted-foreground') }}>{unit}</span>\n ) : null}\n </output>\n </div>\n {/* One row, so the short read-only caption costs no height at a two-row widget's minimum span. */}\n <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'baseline', columnGap: spaceVar(2) }}>\n {caption}\n <ControlNotes sender={sender} captionId={captionId} />\n </div>\n </div>\n );\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// The pure half of the command slider and toggle: which parameter a control is bound to and why\n// it may refuse to be, the payload it sends, and the last value sent read back off the command\n// history. Nothing here reads a widget's options (the widgets hand the values in), so it is\n// tested on its own.\n//\n// \uD83D\uDD34 A CONTROL THAT CANNOT SEND SAYS SO. Every way the binding can be wrong is a named refusal\n// with the parameter it concerns, never a fallback value: a control that guesses at its range, its\n// type or a required parameter sends a plausible command the author did not mean.\n\nimport type { CommandParameter, CommandRow } from '@devicechain/dashboards';\n\nimport { buildPayload, isScalar, parseParameterSchema, validateParams } from './widgets/command-params';\n\nexport type ControlKind = 'number' | 'boolean';\n\nexport type Refusal =\n | { code: 'noCommand' }\n | { code: 'setParameter' }\n | { code: 'parameterMissing'; name: string }\n | { code: 'wrongType'; name: string; kind: ControlKind }\n | { code: 'fixedChoices'; name: string }\n | { code: 'otherRequired'; names: string[] }\n | { code: 'badDefault'; names: string[] }\n | { code: 'setRange' }\n | { code: 'badRange' };\n\nexport interface BindInput {\n commandName: string | undefined;\n parameterSchema: string | null | undefined;\n parameter: string | undefined;\n // Authored fallbacks for a slider: used only where the command definition leaves the end (or\n // the step) open. The definition is the authority on what the command accepts.\n min?: number;\n max?: number;\n step?: number;\n}\n\nexport interface Range {\n min: number;\n max: number;\n step: number;\n integer: boolean;\n}\n\nexport type Binding =\n | { ok: true; kind: ControlKind; param: CommandParameter; range?: Range; sent: CommandParameter[] }\n | { ok: false; refusal: Refusal };\n\nconst refuse = (refusal: Refusal): Binding => ({ ok: false, refusal });\n\n// 100 notches across a continuous range: the step a DOUBLE slider gets when nobody set one.\nconst DEFAULT_NOTCHES = 100;\n\nexport function bindControl(kind: ControlKind, input: BindInput): Binding {\n if (!input.commandName) return refuse({ code: 'noCommand' });\n const params = parseParameterSchema(input.parameterSchema);\n const wanted = (p: CommandParameter) =>\n isScalar(p) && (kind === 'boolean' ? p.dataType === 'BOOLEAN' : p.dataType === 'INT' || p.dataType === 'DOUBLE');\n\n let param: CommandParameter | undefined;\n if (input.parameter) {\n param = params.find((p) => p.name === input.parameter);\n if (!param) return refuse({ code: 'parameterMissing', name: input.parameter });\n if (!wanted(param)) return refuse({ code: 'wrongType', name: param.name, kind });\n } else {\n // Unambiguous or not at all: one candidate of the right type is the parameter; none or several\n // is the author's to resolve.\n const candidates = params.filter(wanted);\n if (candidates.length !== 1) return refuse({ code: 'setParameter' });\n param = candidates[0];\n }\n if (param.enum && param.enum.length > 0) return refuse({ code: 'fixedChoices', name: param.name });\n\n // Every other parameter either has a declared default (sent as is) or is optional (omitted).\n // A required one with neither would have to be invented, so the control refuses instead.\n const others = params.filter((p) => p !== param);\n const unsatisfied = others.filter((p) => p.required && (!isScalar(p) || p.default == null || p.default === ''));\n if (unsatisfied.length > 0) return refuse({ code: 'otherRequired', names: unsatisfied.map((p) => p.name) });\n const defaulted = others.filter((p) => isScalar(p) && p.default != null && p.default !== '');\n // A default is sent as written, so one the definition's own rules reject (not a number, not a\n // whole number, outside its range) would be a command the server refuses on every send.\n const invalid = new Set(\n Object.keys(validateParams(defaulted, Object.fromEntries(defaulted.map((p) => [p.name, p.default ?? ''])))),\n );\n for (const p of defaulted) if (p.enum && p.enum.length > 0 && !p.enum.includes(p.default ?? '')) invalid.add(p.name);\n if (invalid.size > 0) return refuse({ code: 'badDefault', names: defaulted.filter((p) => invalid.has(p.name)).map((p) => p.name) });\n const sent = [param, ...defaulted];\n\n if (kind === 'boolean') return { ok: true, kind, param, sent };\n\n const min = param.minValue ?? input.min;\n const max = param.maxValue ?? input.max;\n if (min === undefined || max === undefined) return refuse({ code: 'setRange' });\n if (!(max > min)) return refuse({ code: 'badRange' });\n const integer = param.dataType === 'INT';\n const step = input.step !== undefined && input.step > 0 ? input.step : integer ? 1 : (max - min) / DEFAULT_NOTCHES;\n return { ok: true, kind, param, range: { min, max, step, integer }, sent };\n}\n\n// The decimals a step carries, so snapped values do not pick up float noise (0.1 steps).\nfunction decimalsOf(n: number): number {\n const text = String(n);\n const e = /e-(\\d+)$/.exec(text);\n if (e) return Number(e[1]);\n const dot = text.indexOf('.');\n return dot < 0 ? 0 : text.length - dot - 1;\n}\n\n// clampToRange puts a raw value on the slider's grid: inside [min, max], on a whole step from min\n// (an INT rounds to a whole number whatever the step), and never NaN.\nexport function clampToRange(range: Range, raw: number): number {\n const finite = Number.isFinite(raw) ? raw : range.min;\n const bounded = Math.min(range.max, Math.max(range.min, finite));\n const steps = Math.round((bounded - range.min) / range.step);\n const decimals = Math.max(decimalsOf(range.step), decimalsOf(range.min));\n let snapped = Number((range.min + steps * range.step).toFixed(Math.min(decimals, 12)));\n if (snapped > range.max) snapped = Number((snapped - range.step).toFixed(Math.min(decimals, 12)));\n if (range.integer) snapped = Math.round(snapped);\n return Math.min(range.max, Math.max(range.min, snapped));\n}\n\n// The JSON the command carries: the bound parameter as its real type, the other parameters that\n// have a declared default, nothing else.\nexport function payloadFor(binding: Extract<Binding, { ok: true }>, value: number | boolean): string {\n const values: Record<string, string> = {};\n for (const p of binding.sent) {\n values[p.name] = p.default ?? '';\n if (p === binding.param) values[p.name] = String(value);\n }\n const payload = buildPayload(binding.sent, values);\n // sent always holds the bound parameter, so a payload always exists.\n return payload as string;\n}\n\nexport type DeliveryGroup = 'pending' | 'delivered' | 'failed' | 'unknown';\n\n// Which of the three things an operator asks of a command its status answers. An unrecognised\n// status is its own group, rendered as the raw word: it is not known to be pending.\nexport function deliveryGroup(status: string): DeliveryGroup {\n switch (status) {\n case 'QUEUED':\n case 'HELD':\n case 'SENT':\n case 'PARKED':\n return 'pending';\n case 'SUCCESSFUL':\n return 'delivered';\n case 'FAILED':\n case 'TIMEOUT':\n case 'EXPIRED':\n case 'CANCELLED':\n return 'failed';\n default:\n return 'unknown';\n }\n}\n\nexport interface LastSent {\n token: string;\n // The value the command carried for the bound parameter; undefined when the command (sent from\n // somewhere else) did not carry one this control can read.\n value: number | boolean | undefined;\n status: string;\n}\n\n// An accepted send not yet seen in the history.\nexport interface Optimistic {\n token: string;\n value: number | boolean;\n}\n\nfunction readValue(kind: ControlKind, payload: string | null, name: string): number | boolean | undefined {\n if (!payload) return undefined;\n let parsed: unknown;\n try {\n parsed = JSON.parse(payload);\n } catch {\n return undefined;\n }\n if (typeof parsed !== 'object' || parsed === null) return undefined;\n const v = (parsed as Record<string, unknown>)[name];\n if (kind === 'number') return typeof v === 'number' && Number.isFinite(v) ? v : undefined;\n if (typeof v === 'boolean') return v;\n return undefined;\n}\n\n// lastSent reads the newest command of this control's name off the history. It is the newest, not\n// the newest that happens to parse: skipping to an older row would report a value that has since\n// been superseded. A send the history has not caught up with yet stands in until it does.\nexport function lastSent(\n kind: ControlKind,\n commands: readonly CommandRow[],\n commandName: string,\n parameter: string,\n optimistic: Optimistic | null,\n): LastSent | null {\n let newest: CommandRow | undefined;\n for (const c of commands) {\n if (c.name !== commandName) continue;\n if (!newest || (c.queuedTime ?? '') > (newest.queuedTime ?? '')) newest = c;\n }\n if (optimistic && !commands.some((c) => c.token === optimistic.token)) {\n return { token: optimistic.token, value: optimistic.value, status: 'QUEUED' };\n }\n if (!newest) return null;\n return { token: newest.token, value: readValue(kind, newest.payload, parameter), status: newest.status };\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// What the command slider and toggle share beyond the pure logic: the send itself (one at a time,\n// the permission gate, the refusal's reason), the \"last sent\" caption with its delivery status, and\n// the explained empty state. Neither control shows device state: the caption names what was SENT.\n\nimport type { CommandDispatch, WidgetActions } from '@devicechain/dashboards';\nimport { useCallback, useEffect, useRef, useState, type CSSProperties } from 'react';\n\nimport { css, fontVar, spaceVar } from '@devicechain/widget-sdk';\n\nimport { controlStrings, type ControlStrings } from './command-control-strings';\nimport { deliveryGroup, type LastSent, type Optimistic, type Refusal } from './command-control-core';\nimport { commandStatusColor, commandStatusLabel } from './widgets/command-status';\n\n// The smallest hit area a touch control may have, in CSS px.\nexport const TOUCH_TARGET_PX = 44;\n\nexport function refusalText(r: Refusal, s: ControlStrings, expect: 'number' | 'boolean'): string {\n switch (r.code) {\n case 'noCommand':\n return s.noCommand;\n case 'setParameter':\n return s.setParameter;\n case 'parameterMissing':\n return s.parameterMissing(r.name);\n case 'wrongType':\n return s.wrongType(r.name, expect === 'number' ? s.numberKind : s.booleanKind);\n case 'fixedChoices':\n return s.fixedChoices(r.name);\n case 'otherRequired':\n return s.otherRequired(r.names);\n case 'badDefault':\n return s.badDefault(r.names);\n case 'setRange':\n return s.setRange;\n case 'badRange':\n return s.badRange;\n }\n}\n\nexport interface CommandSender {\n strings: ControlStrings;\n // Why the control is read-only, or undefined when the viewer may send.\n readOnlyReason: string | undefined;\n canSend: boolean;\n // A dispatch is in flight.\n pending: boolean;\n error: string | null;\n // A send the platform accepted, until the history shows it.\n optimistic: Optimistic | null;\n // Returns whether a command was dispatched. At most one is in flight at a time.\n send: (payload: string, value: number | boolean) => boolean;\n}\n\n// useCommandSender owns one control's sending. `resetKey` identifies the configured command: when\n// it changes, an in-flight send's result is dropped rather than landing under the new command.\nexport function useCommandSender(\n actions: WidgetActions | undefined,\n deviceToken: string | null | undefined,\n commandName: string | undefined,\n resetKey: string,\n): CommandSender {\n const strings = controlStrings();\n const canWrite = actions?.can('command:write') ?? false;\n const hasSeam = typeof actions?.sendCommand === 'function';\n const canSend = canWrite && hasSeam && !!deviceToken && !!commandName;\n\n // The in-flight flag is a ref, not state: two clicks in the same tick both see the state before\n // either has re-rendered, and only a ref closes that window.\n const inFlight = useRef(false);\n const generation = useRef(0);\n const [pending, setPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [optimistic, setOptimistic] = useState<Optimistic | null>(null);\n\n useEffect(() => {\n generation.current += 1;\n inFlight.current = false;\n setPending(false);\n setError(null);\n setOptimistic(null);\n }, [resetKey]);\n\n const send = useCallback(\n (payload: string, value: number | boolean): boolean => {\n if (!canSend || inFlight.current || !actions?.sendCommand || !deviceToken || !commandName) return false;\n const gen = generation.current;\n inFlight.current = true;\n setPending(true);\n setError(null);\n const settle = () => {\n if (gen !== generation.current) return;\n inFlight.current = false;\n setPending(false);\n };\n let promise: Promise<CommandDispatch>;\n try {\n promise = actions.sendCommand(deviceToken, commandName, payload);\n } catch {\n setError(strings.sendFailed);\n settle();\n return true;\n }\n promise\n .then((dispatch) => {\n if (gen !== generation.current) return;\n // A refusal is shown with the server's reason (it is client-safe and the operator can act\n // on it); a thrown error is an availability failure whose text is internal, so it gets\n // one fixed message instead. A refused value is not \"last sent\".\n if (dispatch.status === 'rejected') setError(dispatch.reason);\n else setOptimistic({ token: dispatch.token, value });\n })\n .catch(() => {\n if (gen === generation.current) setError(strings.sendFailed);\n })\n .finally(settle);\n return true;\n },\n [actions, canSend, commandName, deviceToken, strings.sendFailed],\n );\n\n // A view with no send seam at all (a read-only embed) is told so, rather than blamed on the\n // viewer's permissions.\n const readOnlyReason = !hasSeam\n ? strings.noSeam\n : !canWrite\n ? strings.noPermission\n : !deviceToken\n ? strings.noDevice\n : undefined;\n return { strings, readOnlyReason, canSend, pending, error, optimistic, send };\n}\n\nconst note: CSSProperties = {\n fontSize: fontVar('xs'),\n lineHeight: 1.25,\n color: css('muted-foreground'),\n overflowWrap: 'anywhere',\n};\n\n// The explained empty state: why the control has nothing to offer, as an alert so it is announced.\nexport function ControlEmpty({ message }: { message: string }) {\n return (\n <div\n role=\"alert\"\n data-control-empty=\"\"\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: '100%',\n textAlign: 'center',\n color: css('muted-foreground'),\n fontSize: fontVar('sm'),\n overflowWrap: 'anywhere',\n }}\n >\n {message}\n </div>\n );\n}\n\n// The id of the full read-only reason, derived from the caption's id so the control can name it in\n// aria-describedby. The visible caption is the short \"View only\" so it fits a two-row widget at\n// one-column width; the full sentence lives here, hidden from the eye but not from assistive tech.\nexport const readOnlyId = (captionId: string) => `${captionId}-ro`;\n\n// The notes under a control: a short \"View only\" caption (the full reason is its title and the\n// control's description), and the last send's error.\nexport function ControlNotes({ sender, captionId }: { sender: CommandSender; captionId: string }) {\n return (\n <>\n {sender.readOnlyReason ? (\n <span id={readOnlyId(captionId)} hidden>\n {sender.readOnlyReason}\n </span>\n ) : null}\n {sender.readOnlyReason ? (\n <div data-read-only=\"\" title={sender.readOnlyReason} style={{ ...note, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>\n {sender.strings.viewOnly}\n </div>\n ) : null}\n {sender.error ? (\n <div role=\"alert\" style={{ ...note, color: commandStatusColor('FAILED') }}>\n {sender.error}\n </div>\n ) : null}\n </>\n );\n}\n\n// \"Last sent: 22 C \u00B7 Pending\". The words are the viewer's: pending, delivered or failed, with the\n// precise status on hover. `override` replaces the whole line (the slider's \"not sent yet\" while a\n// value is staged), so the caption never claims a staged value was sent.\nexport function LastSentCaption({\n id,\n last,\n format,\n strings,\n override,\n truncated = false,\n}: {\n id: string;\n last: LastSent | null;\n format: (value: number | boolean | undefined) => string;\n strings: ControlStrings;\n override?: string;\n // The device has more commands than the page read, so an empty match proves nothing.\n truncated?: boolean;\n}) {\n const group = last ? deliveryGroup(last.status) : undefined;\n const word =\n group === 'pending'\n ? strings.pending\n : group === 'delivered'\n ? strings.delivered\n : group === 'failed'\n ? strings.failed\n : last\n ? commandStatusLabel(last.status)\n : '';\n return (\n <div\n id={id}\n role=\"status\"\n aria-live=\"polite\"\n data-last-sent=\"\"\n data-delivery={group}\n style={{ ...note, fontSize: fontVar('sm'), display: 'flex', flexWrap: 'wrap', alignItems: 'center', columnGap: spaceVar(1) }}\n >\n {override ? (\n <span>{override}</span>\n ) : last ? (\n <>\n <span>{strings.lastSent}:</span>\n <span style={{ color: css('foreground'), fontWeight: 600 }}>{format(last.value)}</span>\n <span aria-hidden=\"true\">\u00B7</span>\n <span\n title={last.status}\n style={{ display: 'inline-flex', alignItems: 'center', gap: 4, color: commandStatusColor(last.status), fontWeight: 600 }}\n >\n <span aria-hidden=\"true\" style={{ width: 7, height: 7, borderRadius: '50%', background: commandStatusColor(last.status) }} />\n {word}\n </span>\n </>\n ) : (\n <span>{truncated ? strings.beyondHistory : strings.nothingSent}</span>\n )}\n </div>\n );\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// The fixed words the command slider and toggle render themselves: why they will not send, what\n// they last sent, and where that command is in its delivery. The widget packages carry no i18n\n// runtime, so this is the one small per-language table, in the manner of level-strings.ts; option\n// labels are translated in the console's catalogs, not here.\n//\n// The caption is worded as what was SENT. These controls know the history of the commands issued\n// to the device, not what the device is doing, and no string here may read as the latter.\n\nimport { viewerLocale } from '@devicechain/widget-sdk';\n\nexport interface ControlStrings {\n noCommand: string;\n setParameter: string;\n parameterMissing: (name: string) => string;\n wrongType: (name: string, expected: string) => string;\n fixedChoices: (name: string) => string;\n otherRequired: (names: string[]) => string;\n badDefault: (names: string[]) => string;\n setRange: string;\n badRange: string;\n numberKind: string;\n booleanKind: string;\n // The caption.\n lastSent: string;\n nothingSent: string;\n // The history is longer than the page this control reads, and none of this command is on it.\n beyondHistory: string;\n noValue: string;\n unsent: string;\n // The slider's keyboard description: arrows choose, Enter sends.\n sliderHint: string;\n pending: string;\n delivered: string;\n failed: string;\n sending: string;\n on: string;\n off: string;\n // Read-only reasons.\n // The short visible caption beside a read-only control; the full reason is its description.\n viewOnly: string;\n noPermission: string;\n noSeam: string;\n noDevice: string;\n sendFailed: string;\n}\n\nexport const CONTROL_STRINGS: Record<'en' | 'es', ControlStrings> = {\n en: {\n noCommand: 'No command configured',\n setParameter: 'Set which parameter this control sends',\n parameterMissing: (n) => `The command has no parameter \u201C${n}\u201D`,\n wrongType: (n, e) => `Parameter \u201C${n}\u201D is not ${e}`,\n fixedChoices: (n) => `Parameter \u201C${n}\u201D takes fixed choices, not a range`,\n otherRequired: (ns) => `Not sent: the command also requires ${ns.map((n) => `\u201C${n}\u201D`).join(', ')}, which has no default value`,\n badDefault: (ns) => `Not sent: the default value of ${ns.map((n) => `\u201C${n}\u201D`).join(', ')} is not valid for the command`,\n setRange: 'Set min and max',\n badRange: 'Max must be above min',\n numberKind: 'a number',\n booleanKind: 'a boolean',\n lastSent: 'Last sent',\n nothingSent: 'Nothing sent yet',\n beyondHistory: 'Not among the recent commands',\n noValue: 'no value',\n unsent: 'Not sent yet. Release or press Enter to send',\n sliderHint: 'Arrow keys choose a value; press Enter to send it, or Escape to discard it.',\n pending: 'Pending',\n delivered: 'Delivered',\n failed: 'Failed',\n sending: 'Sending\u2026',\n on: 'On',\n off: 'Off',\n viewOnly: 'View only',\n noPermission: 'You don\u2019t have permission to send commands.',\n noSeam: 'Commands aren\u2019t available in this view.',\n noDevice: 'No device is selected for this command.',\n sendFailed: 'Couldn\u2019t send the command. Try again.',\n },\n es: {\n noCommand: 'No hay un comando configurado',\n setParameter: 'Defina qu\u00E9 par\u00E1metro env\u00EDa este control',\n parameterMissing: (n) => `El comando no tiene el par\u00E1metro \u201C${n}\u201D`,\n wrongType: (n, e) => `El par\u00E1metro \u201C${n}\u201D no es ${e}`,\n fixedChoices: (n) => `El par\u00E1metro \u201C${n}\u201D admite opciones fijas, no un rango`,\n otherRequired: (ns) => `No se env\u00EDa: el comando tambi\u00E9n exige ${ns.map((n) => `\u201C${n}\u201D`).join(', ')}, que no tiene valor por defecto`,\n badDefault: (ns) => `No se env\u00EDa: el valor por defecto de ${ns.map((n) => `\u201C${n}\u201D`).join(', ')} no es v\u00E1lido para el comando`,\n setRange: 'Defina m\u00EDn. y m\u00E1x.',\n badRange: 'El m\u00E1x. debe superar el m\u00EDn.',\n numberKind: 'un n\u00FAmero',\n booleanKind: 'un booleano',\n lastSent: '\u00DAltimo enviado',\n nothingSent: 'A\u00FAn no se ha enviado nada',\n beyondHistory: 'No figura entre los comandos recientes',\n noValue: 'sin valor',\n unsent: 'A\u00FAn no enviado. Suelte o pulse Intro para enviar',\n sliderHint: 'Las flechas eligen un valor; pulse Intro para enviarlo o Escape para descartarlo.',\n pending: 'Pendiente',\n delivered: 'Entregado',\n failed: 'Fallido',\n sending: 'Enviando\u2026',\n on: 'Encendido',\n off: 'Apagado',\n viewOnly: 'Solo lectura',\n noPermission: 'No tiene permiso para enviar comandos.',\n noSeam: 'Los comandos no est\u00E1n disponibles en esta vista.',\n noDevice: 'No hay un dispositivo seleccionado para este comando.',\n sendFailed: 'No se pudo enviar el comando. Int\u00E9ntelo de nuevo.',\n },\n};\n\nexport function controlStrings(locale: string | undefined = viewerLocale()): ControlStrings {\n return locale?.toLowerCase().split('-')[0] === 'es' ? CONTROL_STRINGS.es : CONTROL_STRINGS.en;\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// command-toggle \u2014 sends a command carrying ONE boolean parameter, one command per click.\n//\n// \uD83D\uDD34 THE SWITCH SHOWS THE LAST VALUE SENT, NOT THE DEVICE'S STATE. It rests where the newest\n// command left it (read off the command history) and the caption says \"Last sent\" with that\n// command's delivery status.\n//\n// \uD83D\uDD34 IT NEVER GUESSES WHICH WAY TO FLIP. A click sends the opposite of the last value sent only\n// when that value is a live intent: a command that is pending or was delivered, carrying a value\n// this control can read. With nothing sent, a history too short to show this command, a newest\n// command with no readable value, or a newest command that FAILED (its value never reached the\n// device, so flipping relative to it would send what the operator may already have), the switch\n// is replaced by two explicit buttons, On and Off, and the operator chooses.\n//\n// A click while a send is in flight does nothing, so rapid clicks make one command, not a queue of\n// alternating ones.\n\nimport { useId, useMemo, type ReactNode } from 'react';\n\nimport {\n css,\n FIT_MIN_FONT_PX,\n fitValueFont,\n fitValueFontCss,\n optString,\n spaceVar,\n useStickyChars,\n WidgetFrame,\n type CommandStreamState,\n type WidgetProps,\n type WidgetScale,\n} from '@devicechain/widget-sdk';\n\nimport { bindControl, deliveryGroup, lastSent, payloadFor, type Binding, type LastSent } from '../command-control-core';\nimport {\n ControlEmpty,\n ControlNotes,\n readOnlyId,\n LastSentCaption,\n refusalText,\n TOUCH_TARGET_PX,\n useCommandSender,\n type CommandSender,\n} from '../command-control';\n\ntype Bound = Extract<Binding, { ok: true }>;\n\nconst TRACK_W = 52;\nconst TRACK_H = 30;\nconst THUMB = 24;\n\nexport function CommandToggle({ widget, data, actions }: WidgetProps<CommandStreamState>) {\n const commandName = optString(widget.options, 'commandName');\n const commandLabel = optString(widget.options, 'commandLabel') ?? commandName;\n const parameterSchema = optString(widget.options, 'parameterSchema') ?? null;\n const parameter = optString(widget.options, 'parameter');\n\n const binding = useMemo(\n () => bindControl('boolean', { commandName, parameterSchema, parameter }),\n [commandName, parameterSchema, parameter],\n );\n const sender = useCommandSender(\n actions,\n data.deviceToken,\n commandName,\n `${commandName ?? ''}::${parameterSchema ?? ''}::${parameter ?? ''}`,\n );\n const last =\n binding.ok && commandName\n ? lastSent('boolean', data.commands, commandName, binding.param.name, sender.optimistic)\n : null;\n const captionId = useId();\n\n return (\n <WidgetFrame title={optString(widget.options, 'title')}>\n {(scale) =>\n !binding.ok ? (\n <ControlEmpty message={refusalText(binding.refusal, sender.strings, 'boolean')} />\n ) : (\n <ToggleBody\n binding={binding}\n label={commandLabel ?? binding.param.name}\n value={intentOf(last)}\n sender={sender}\n captionId={captionId}\n caption={\n <LastSentCaption\n id={captionId}\n last={last}\n strings={sender.strings}\n truncated={data.total > data.commands.length}\n format={(v) => (typeof v === 'boolean' ? (v ? sender.strings.on : sender.strings.off) : sender.strings.noValue)}\n override={sender.pending ? sender.strings.sending : undefined}\n />\n }\n scale={scale}\n />\n )\n }\n </WidgetFrame>\n );\n}\n\n// The value a flip may be computed from, or undefined when the operator has to choose. Only a\n// command that is still on its way, or arrived, states an intent the device is acting on.\nexport function intentOf(last: LastSent | null): boolean | undefined {\n if (!last || typeof last.value !== 'boolean') return undefined;\n const group = deliveryGroup(last.status);\n return group === 'pending' || group === 'delivered' ? last.value : undefined;\n}\n\nfunction ToggleBody({\n binding,\n label,\n value,\n sender,\n captionId,\n caption,\n scale: ws,\n}: {\n binding: Bound;\n label: string;\n value: boolean | undefined;\n sender: CommandSender;\n captionId: string;\n caption: ReactNode;\n scale: WidgetScale;\n}) {\n const checked = value === true;\n const unknown = value === undefined;\n const disabled = !sender.canSend;\n const word = checked ? sender.strings.on : sender.strings.off;\n\n const chars = useStickyChars(word.length);\n const floor = Math.round(FIT_MIN_FONT_PX * ws.scale);\n const measured = ws.size.width > 0 && ws.size.height > 0;\n const room = {\n width: Math.floor(ws.size.width - TRACK_W - 16),\n height: Math.max(TOUCH_TARGET_PX, Math.floor(ws.size.height * 0.5)),\n };\n const font = measured ? fitValueFont(room, chars, { floor }) : fitValueFontCss(chars, { floor });\n\n const sendValue = (next: boolean) => {\n sender.send(payloadFor(binding, next), next);\n };\n\n return (\n <div\n style={{\n height: '100%',\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'safe center',\n gap: spaceVar(1),\n overflow: 'hidden',\n }}\n >\n {unknown ? (\n <div role=\"group\" aria-label={label} aria-describedby={sender.readOnlyReason ? `${captionId} ${readOnlyId(captionId)}` : captionId} data-toggle-choose=\"\" style={{ display: 'flex', gap: spaceVar(2) }}>\n {([true, false] as const).map((v) => (\n <button\n key={String(v)}\n type=\"button\"\n disabled={disabled}\n aria-busy={sender.pending}\n onClick={() => sendValue(v)}\n style={{\n flex: '1 1 0',\n minHeight: TOUCH_TARGET_PX,\n minWidth: TOUCH_TARGET_PX,\n padding: `0 ${spaceVar(2)}`,\n borderRadius: 6,\n border: `1px solid ${css('border')}`,\n background: css('background'),\n color: css('foreground'),\n fontWeight: 600,\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.6 : 1,\n }}\n >\n {v ? sender.strings.on : sender.strings.off}\n </button>\n ))}\n </div>\n ) : (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n aria-label={label}\n aria-describedby={sender.readOnlyReason ? `${captionId} ${readOnlyId(captionId)}` : captionId}\n aria-busy={sender.pending}\n disabled={disabled}\n onClick={() => sendValue(!checked)}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: spaceVar(2),\n minHeight: TOUCH_TARGET_PX,\n minWidth: TOUCH_TARGET_PX,\n padding: 0,\n border: 'none',\n background: 'transparent',\n color: css('foreground'),\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.6 : 1,\n textAlign: 'left',\n }}\n >\n <span\n aria-hidden=\"true\"\n style={{\n position: 'relative',\n flex: '0 0 auto',\n width: TRACK_W,\n height: TRACK_H,\n borderRadius: TRACK_H / 2,\n boxSizing: 'border-box',\n border: `1px solid ${css('border')}`,\n background: checked ? css('primary') : css('muted'),\n }}\n >\n <span\n style={{\n position: 'absolute',\n top: (TRACK_H - THUMB) / 2 - 1,\n left: checked ? TRACK_W - THUMB - 3 : 2,\n width: THUMB,\n height: THUMB,\n borderRadius: '50%',\n background: checked ? css('primary-foreground') : css('background'),\n border: `1px solid ${css('border')}`,\n boxSizing: 'border-box',\n }}\n />\n </span>\n <span\n data-toggle-word=\"\"\n style={{\n fontSize: font,\n fontWeight: 600,\n lineHeight: 1.1,\n whiteSpace: 'nowrap',\n color: css('foreground'),\n }}\n >\n {word}\n </span>\n </button>\n )}\n {/* One row, so the short read-only caption costs no height at a two-row widget's minimum span. */}\n <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'baseline', columnGap: spaceVar(2) }}>\n {caption}\n <ControlNotes sender={sender} captionId={captionId} />\n </div>\n </div>\n );\n}\n"],
5
- "mappings": "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",
5
+ "mappings": "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",
6
6
  "names": ["useEffect", "useRef", "useState", "css", "fontVar", "spaceVar", "jsx", "jsxs", "useState", "useRef", "useEffect", "spaceVar", "css", "fontVar", "useId", "useMemo", "css", "FIT_MIN_FONT_PX", "fitValueFont", "fitValueFontCss", "optString", "spaceVar", "useStickyChars", "WidgetFrame", "jsx", "jsxs", "optString", "useMemo", "useId", "WidgetFrame", "useStickyChars", "FIT_MIN_FONT_PX", "fitValueFont", "fitValueFontCss", "spaceVar", "css"]
7
7
  }
@@ -0,0 +1,7 @@
1
+ import {
2
+ EntitySelector
3
+ } from "./chunk-FM7OI5TQ.js";
4
+ export {
5
+ EntitySelector
6
+ };
7
+ //# sourceMappingURL=entity-selector-3JJFI4DT.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -1,15 +1,16 @@
1
+ import {
2
+ measurementSpan
3
+ } from "./chunk-2D7JNKFE.js";
1
4
  import {
2
5
  buildFleet,
3
6
  fleetStrings,
4
7
  newestMemberTime,
5
8
  seedWindow
6
- } from "./chunk-S2OMBJLI.js";
9
+ } from "./chunk-WBKHYZU2.js";
10
+ import "./chunk-BRH66T5F.js";
7
11
  import {
8
12
  LevelEmpty
9
13
  } from "./chunk-XQQQNTBX.js";
10
- import {
11
- measurementSpan
12
- } from "./chunk-2D7JNKFE.js";
13
14
 
14
15
  // src/fleet-feed.tsx
15
16
  import {
@@ -113,6 +114,8 @@ async function sharpen(seed, recent, window, fold) {
113
114
  import { jsx } from "react/jsx-runtime";
114
115
  var FLUSH_MS = 250;
115
116
  var AGE_OUT_MS = 3e4;
117
+ var RESEED_SETTLE_MS = 2e3;
118
+ var MINUTE_MS2 = 6e4;
116
119
  var emptyStore = (key) => ({ key, roster: null, live: /* @__PURE__ */ new Map(), seeds: /* @__PURE__ */ new Map(), forbidden: false, error: null });
117
120
  function record(into, sample) {
118
121
  let byName = into.get(sample.deviceToken);
@@ -150,6 +153,8 @@ function FleetFeed({ hub, widget, descriptor, Component, actions, ErrorFrame })
150
153
  const [version, bump] = useReducer((n) => n + 1, 0);
151
154
  const [rosterKey, setRosterKey] = useState(null);
152
155
  const flushTimer = useRef(void 0);
156
+ const [resumes, resumed] = useReducer((n) => n + 1, 0);
157
+ const boundaryTimer = useRef(void 0);
153
158
  const schedule = () => {
154
159
  if (flushTimer.current !== void 0) return;
155
160
  flushTimer.current = setTimeout(() => {
@@ -181,12 +186,25 @@ function FleetFeed({ hub, widget, descriptor, Component, actions, ErrorFrame })
181
186
  error: (err) => {
182
187
  s.error = err;
183
188
  schedule();
189
+ },
190
+ // Every member stream on the socket resumes at once; the reducer folds them into one render,
191
+ // and one boundary read covers them all.
192
+ reconnected: () => {
193
+ resumed();
194
+ if (boundaryTimer.current !== void 0) return;
195
+ const at = now();
196
+ boundaryTimer.current = setTimeout(() => {
197
+ boundaryTimer.current = void 0;
198
+ resumed();
199
+ }, MINUTE_MS2 - at % MINUTE_MS2 + RESEED_SETTLE_MS);
184
200
  }
185
201
  });
186
202
  return () => {
187
203
  dispose();
188
204
  if (flushTimer.current !== void 0) clearTimeout(flushTimer.current);
189
205
  flushTimer.current = void 0;
206
+ if (boundaryTimer.current !== void 0) clearTimeout(boundaryTimer.current);
207
+ boundaryTimer.current = void 0;
190
208
  };
191
209
  }, [hub, dsKey, supported]);
192
210
  useEffect(() => {
@@ -209,7 +227,8 @@ function FleetFeed({ hub, widget, descriptor, Component, actions, ErrorFrame })
209
227
  memberSeedPlan(seedWindow(spanSeconds, pausedAt ?? now()), names),
210
228
  (token, seed, failure) => {
211
229
  if (failure === "forbidden") s.forbidden = true;
212
- else s.seeds.set(token, seed ?? "failed");
230
+ else if (seed) s.seeds.set(token, seed);
231
+ else if (s.seeds.get(token) === void 0) s.seeds.set(token, "failed");
213
232
  schedule();
214
233
  },
215
234
  () => cancelled
@@ -217,7 +236,7 @@ function FleetFeed({ hub, widget, descriptor, Component, actions, ErrorFrame })
217
236
  return () => {
218
237
  cancelled = true;
219
238
  };
220
- }, [hub, supported, dsKey, rosterKey, spanSeconds, pausedAt, namesKey]);
239
+ }, [hub, supported, dsKey, rosterKey, spanSeconds, pausedAt, namesKey, resumes]);
221
240
  useEffect(() => {
222
241
  if (pausedAt !== void 0) return;
223
242
  const id = setInterval(bump, AGE_OUT_MS);
@@ -246,7 +265,8 @@ function FleetFeed({ hub, widget, descriptor, Component, actions, ErrorFrame })
246
265
  export {
247
266
  FLUSH_MS,
248
267
  GroupRefusal,
268
+ RESEED_SETTLE_MS,
249
269
  FleetEntry as default,
250
270
  shownMeasurements
251
271
  };
252
- //# sourceMappingURL=fleet-feed-FK4ZMKIK.js.map
272
+ //# sourceMappingURL=fleet-feed-5QGDLOV5.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/fleet-feed.tsx", "../../src/fleet-seed.ts"],
4
+ "sourcesContent": ["// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// The data feed of a fleet widget (one row or one bar per member of an anchor): the roster, each\n// member's own live readings, and one seed read per member for what it last reported before the\n// board was opened. Loaded on first use (connected-widget.tsx imports it dynamically), so a board\n// with no fleet widget never downloads it.\n//\n// - ONE subscription per widget (hub.subscribeMembers). The samples it delivers carry their\n// device, and everything here is keyed by device and measurement together -- the measurement\n// channel's name-only `latest` is exactly what this exists to get away from;\n// - the seed is read per member, bounded hub-wide and shared between widgets that ask the same\n// question; what is read is fleet-seed.ts's plan (the last few minutes first, the span only for\n// what that left empty). The window is the widget's pinned span, else the board's, ending at the\n// freeze instant while paused;\n// - paused, live readings queue (newest per device and measurement) and merge on resume, so the\n// table on screen does not move under a \"Paused\" badge;\n// - a change of span re-reads the seeds; a reading older than the span is no longer shown;\n// - a member stream that resumes after an interruption re-reads the seeds, at once and again just\n// after the next minute boundary: the readings sent during the outage were never delivered, and\n// a seed window ends on a minute boundary, so only the second read reaches the outage's last\n// minute. A re-read that fails keeps the seed it would have replaced.\n//\n// Rebuilding the whole state per sample would re-render a 500-row table hundreds of times a\n// second, so changes are folded into a store and flushed at most once per FLUSH_MS.\n\nimport {\n DEFAULT_TIME_RANGE_SECONDS,\n type FleetState,\n type MeasurementSample,\n type MeasurementStreamState,\n type MemberRoster,\n type MemberSeed,\n type WidgetActions,\n type WidgetDataSource,\n type WidgetDescriptor,\n type WidgetInstance,\n} from '@devicechain/dashboards';\nimport { optString, resolveStaleAfterSeconds, useWidgetTimeRange, WidgetFrame, WidgetFreshnessProvider } from '@devicechain/widget-sdk';\nimport { useEffect, useMemo, useReducer, useRef, useState, type ComponentType } from 'react';\n\nimport { measurementSpan } from './binding-policy';\nimport { buildFleet, newestMemberTime, seedWindow } from './fleet-model';\nimport { memberSeedPlan } from './fleet-seed';\nimport { fleetStrings } from './fleet-strings';\nimport { LevelEmpty } from './level-readout';\n\n// The most often the state is rebuilt from live samples.\nexport const FLUSH_MS = 250;\n// How often a reading that has aged out of the span is dropped when nothing else changes.\nconst AGE_OUT_MS = 30_000;\n// How long past a minute boundary the second re-read after an interruption waits, so the minute\n// that just closed is in the store's one-minute summaries before it is read.\nexport const RESEED_SETTLE_MS = 2_000;\nconst MINUTE_MS = 60_000;\n\ninterface Store {\n // The selector this store was filled for: a render that carries a new selector must not show the\n // previous fleet's rows under it while the effect that resets the store has yet to run.\n key: string | null;\n roster: MemberRoster | null;\n live: Map<string, Map<string, MeasurementSample>>;\n seeds: Map<string, MemberSeed | 'failed'>;\n forbidden: boolean;\n error: unknown | null;\n}\n\nconst emptyStore = (key: string | null): Store => ({ key, roster: null, live: new Map(), seeds: new Map(), forbidden: false, error: null });\n\nfunction record(into: Map<string, Map<string, MeasurementSample>>, sample: MeasurementSample): void {\n let byName = into.get(sample.deviceToken);\n if (!byName) into.set(sample.deviceToken, (byName = new Map()));\n // Newest wins; an out-of-order older sample must not roll a cell back.\n const held = byName.get(sample.name);\n if (held?.occurredTime && sample.occurredTime && Date.parse(sample.occurredTime) < Date.parse(held.occurredTime)) return;\n byName.set(sample.name, sample);\n}\n\nexport interface FleetFeedProps {\n hub: WidgetDataSource;\n widget: WidgetInstance;\n descriptor: WidgetDescriptor;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Component: ComponentType<any>;\n actions: WidgetActions | undefined;\n ErrorFrame: ComponentType<{ widget: WidgetInstance; error: unknown }>;\n // Not a fleet widget, but bound to a group: say so instead (GroupRefusal).\n refuse?: boolean;\n}\n\n// What a widget that shows ONE device's readings keyed by measurement name renders when it is bound\n// to a group: every device reporting \"temperature\" would overwrite the others in it, so it shows a\n// sentence instead of whichever device spoke last. A widget with a per-device mode (the bar chart's\n// one bar per device) is pointed at that mode; any other at the fleet table.\nexport function GroupRefusal({ widget, descriptor }: { widget: WidgetInstance; descriptor: WidgetDescriptor }) {\n const strings = fleetStrings();\n const perDevice = (descriptor.binding as { members?: unknown }).members !== undefined;\n return (\n <WidgetFrame title={optString(widget.options, 'title')}>\n <div data-group-refused=\"\" style={{ display: 'contents' }}>\n <LevelEmpty message={`${strings.oneDevice} ${perDevice ? strings.usePerDevice : strings.useFleetTable}`} />\n </div>\n </WidgetFrame>\n );\n}\n\n// The measurements a fleet widget shows, and so the ones its seed must find AND its live feed must\n// carry: the datasource's, and the `measurement` option a per-device bar chart compares. Empty: every\n// measurement reported. One list for both, because the hub's live feed delivers only the names its\n// selector lists: a bar chart comparing a measurement its datasource does not name would otherwise\n// be seeded with it and then never hear of it again.\nexport function shownMeasurements(widget: WidgetInstance): string[] {\n const one = widget.options?.measurement;\n const named = [...(widget.datasource?.measurements ?? []), ...(typeof one === 'string' && one !== '' ? [one] : [])];\n return [...new Set(named)];\n}\n\nexport default function FleetEntry(props: FleetFeedProps) {\n return props.refuse ? <GroupRefusal widget={props.widget} descriptor={props.descriptor} /> : <FleetFeed {...props} />;\n}\n\nfunction FleetFeed({ hub, widget, descriptor, Component, actions, ErrorFrame }: FleetFeedProps) {\n const range = useWidgetTimeRange();\n const now = useMemo(() => (hub.now ? () => hub.now!() : Date.now), [hub]);\n const spanSeconds = measurementSpan(descriptor, widget, range?.spanSeconds) ?? range?.spanSeconds ?? DEFAULT_TIME_RANGE_SECONDS;\n const pausedAt = range?.paused ? range.pausedAt : undefined;\n const names = shownMeasurements(widget);\n const ds = widget.datasource && { ...widget.datasource, measurements: names };\n const dsKey = JSON.stringify(ds ?? null);\n const namesKey = JSON.stringify(names);\n const supported = hub.subscribeMembers !== undefined && hub.readMemberSeeds !== undefined;\n\n const store = useRef<Store>(emptyStore(dsKey));\n // Live samples that arrive while paused, newest per device and measurement.\n const queued = useRef<Map<string, Map<string, MeasurementSample>>>(new Map());\n const pausedRef = useRef(pausedAt !== undefined);\n const [version, bump] = useReducer((n: number) => n + 1, 0);\n const [rosterKey, setRosterKey] = useState<string | null>(null);\n const flushTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n // Re-reads asked for by a member stream that resumed; the seeds effect re-runs on each.\n const [resumes, resumed] = useReducer((n: number) => n + 1, 0);\n const boundaryTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n const schedule = (): void => {\n if (flushTimer.current !== undefined) return;\n flushTimer.current = setTimeout(() => {\n flushTimer.current = undefined;\n bump();\n }, FLUSH_MS);\n };\n\n // The subscription: the roster, then the live samples. A new selector starts from nothing.\n useEffect(() => {\n const s = emptyStore(dsKey);\n store.current = s;\n queued.current = new Map();\n setRosterKey(null);\n bump();\n if (!ds || !supported) return;\n const dispose = hub.subscribeMembers!(ds, {\n roster: (roster) => {\n s.roster = roster;\n setRosterKey(roster.members.map((m) => m.token).join('\\n'));\n schedule();\n },\n next: (sample) => {\n record(pausedRef.current ? queued.current : s.live, sample);\n if (!pausedRef.current) schedule();\n },\n forbidden: () => {\n s.forbidden = true;\n schedule();\n },\n error: (err) => {\n s.error = err;\n schedule();\n },\n // Every member stream on the socket resumes at once; the reducer folds them into one render,\n // and one boundary read covers them all.\n reconnected: () => {\n resumed();\n if (boundaryTimer.current !== undefined) return;\n const at = now();\n boundaryTimer.current = setTimeout(() => {\n boundaryTimer.current = undefined;\n resumed();\n }, MINUTE_MS - (at % MINUTE_MS) + RESEED_SETTLE_MS);\n },\n });\n return () => {\n dispose();\n if (flushTimer.current !== undefined) clearTimeout(flushTimer.current);\n flushTimer.current = undefined;\n if (boundaryTimer.current !== undefined) clearTimeout(boundaryTimer.current);\n boundaryTimer.current = undefined;\n };\n // `ds` is read through `dsKey` (value identity), not by reference.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hub, dsKey, supported]);\n\n // The pause gate: resuming merges what queued while frozen.\n useEffect(() => {\n const was = pausedRef.current;\n pausedRef.current = pausedAt !== undefined;\n if (was && pausedAt === undefined) {\n for (const byName of queued.current.values()) for (const sample of byName.values()) record(store.current.live, sample);\n queued.current = new Map();\n schedule();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pausedAt]);\n\n // The seeds: one read per member for the window, again when the span or the freeze instant changes.\n useEffect(() => {\n const s = store.current;\n if (!supported || !s.roster || rosterKey === null) return;\n const tokens = s.roster.members.map((m) => m.token);\n if (tokens.length === 0) return;\n let cancelled = false;\n void hub.readMemberSeeds!(\n tokens,\n memberSeedPlan(seedWindow(spanSeconds, pausedAt ?? now()), names),\n (token, seed, failure) => {\n if (failure === 'forbidden') s.forbidden = true;\n else if (seed) s.seeds.set(token, seed);\n // A re-read that failed keeps the seed it would have replaced: that reading is still true.\n else if (s.seeds.get(token) === undefined) s.seeds.set(token, 'failed');\n schedule();\n },\n () => cancelled,\n );\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hub, supported, dsKey, rosterKey, spanSeconds, pausedAt, namesKey, resumes]);\n\n // A reading ages out of the span with no event to say so.\n useEffect(() => {\n if (pausedAt !== undefined) return;\n const id = setInterval(bump, AGE_OUT_MS);\n return () => clearInterval(id);\n }, [pausedAt]);\n\n const members = useMemo<FleetState>(() => {\n const s = store.current.key === dsKey ? store.current : emptyStore(dsKey);\n if (!supported) return { status: 'unsupported', members: [], total: 0, truncated: false };\n return buildFleet({\n roster: s.roster,\n seeds: s.seeds,\n live: s.live,\n since: (pausedAt ?? now()) - spanSeconds * 1000,\n forbidden: s.forbidden,\n });\n // `version` is the store's change counter; the store itself is mutable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [version, supported, dsKey, spanSeconds, pausedAt, now]);\n\n const error = store.current.key === dsKey ? store.current.error : null;\n const data: MeasurementStreamState = { latest: {}, samples: [], error, members };\n\n // Opt-in through the descriptor, as for any measurement widget. The frame's age is the newest\n // reading anywhere in the fleet; a widget that shows ages per row takes them from the members.\n const freshness = useMemo(\n () =>\n descriptor.freshness === true\n ? { at: newestMemberTime(members), staleAfterSeconds: resolveStaleAfterSeconds(widget.options) }\n : undefined,\n [descriptor, widget.options, members],\n );\n if (error) return <ErrorFrame widget={widget} error={error} />;\n return (\n <WidgetFreshnessProvider freshness={freshness}>\n <Component widget={widget} data={data} actions={actions} />\n </WidgetFreshnessProvider>\n );\n}\n", "// Copyright The DeviceChain Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// What a fleet widget reads to fill its cells before the live feed has, and how it makes a seed of\n// the answer. Loaded with the fleet feed (a lazy chunk), never by a board without a fleet widget.\n//\n// A fleet of 500 is 500 devices to ask, so the cost per device is what matters. The obvious read --\n// every measurement of the device over the whole span in the span's buckets -- returns up to 240\n// buckets per measurement per device (a megabyte or more per device on a long span, tens of\n// megabytes per viewer) to find ONE number per cell. The plan instead asks the question the cell\n// asks, cheapest first:\n//\n// 1. THE LAST FEW MINUTES (TAIL_SECONDS, in one-minute buckets): at most five rows per measurement,\n// read from the store's one-minute summaries. A device that is reporting -- the ordinary case,\n// and the expensive one, because a busy device is the one with the most history -- is done here,\n// with its newest minute.\n// 2. Only for what that left empty, the whole span. One read PER missing measurement, narrowed to\n// that name (the store aggregates one name or all), when the device did report in the tail --\n// which is also what tells \"does not report this\" from \"sent nothing\", so the narrow read loses\n// nothing. Otherwise (a quiet device, or more missing names than are worth a read each) one read\n// of every measurement over the span, as before.\n//\n// A table that names no columns gets the span read alone: its columns ARE the names its devices\n// reported in the span, which only a read of the whole span can list.\n//\n// 3. A value a span read found is the AVERAGE of a span bucket (42 minutes wide on a week), not the\n// device's latest reading: a machine that read 14, was refuelled to 40 and then parked would\n// show 27. So the newest span bucket is read again in one-minute buckets -- at most a bucket's\n// worth of rows -- and its newest minute is what the cell shows, as for a device seen in the\n// tail. Names whose newest buckets coincide share one such read, and a device gets at most\n// MAX_NARROW_READS of them, newest bucket first. A name left past that bound is not shown\n// rather than shown as an average (an average is never the latest reading), and is marked\n// `unread`: the device has data for it, so its cell says \"not loaded\", never \"no data\".\n//\n// Ages. The store returns a bucket's start, not the time of its newest reading, so a seeded reading is\n// stamped at the start of its bucket (or of the span, when the bucket began before it). The reading\n// happened at or after that instant, so its age is OVERSTATED, never understated: by less than a\n// minute for a device seen in the tail, by up to one span bucket (bucketSecondsFor) otherwise. The\n// first live reading replaces the stamp with the real time.\n\nimport type {\n HistoryWindow,\n MeasurementBucket,\n MeasurementSample,\n MemberBucketCriteria,\n MemberSeed,\n MemberSeedPlan,\n} from '@devicechain/dashboards';\n\nconst MINUTE_MS = 60_000;\n\n// The tail read first: long enough to catch a device that reports every minute or two, short enough\n// that it is a handful of rows per measurement.\nexport const TAIL_SECONDS = 300;\n\n// The most narrowed (one-name) span reads one device gets before a single read of every name is the\n// cheaper question.\nexport const MAX_NARROW_READS = 2;\n\nconst has = (o: object, key: string): boolean => Object.prototype.hasOwnProperty.call(o, key);\n\n// foldMemberSeed turns one device's buckets into its seed: the newest bucket with a mean wins per\n// name, stamped at max(bucket start, `notBefore`) (see \"Ages\" above). A name whose buckets hold\n// readings is observed even when none has a mean.\nexport function foldMemberSeed(deviceToken: string, buckets: readonly MeasurementBucket[], notBefore?: string): MemberSeed {\n const floor = notBefore === undefined ? Number.NaN : Date.parse(notBefore);\n const latest: Record<string, MeasurementSample> = {};\n const at: Record<string, number> = {};\n const observed = new Set<string>();\n for (const b of buckets) {\n if (b.count === undefined ? b.avg != null : b.count > 0) observed.add(b.name);\n if (b.avg == null) continue;\n const start = Date.parse(b.bucketStart);\n if (has(at, b.name) && at[b.name] >= start) continue;\n at[b.name] = start;\n latest[b.name] = {\n id: `seed-${deviceToken}-${b.name}-${b.bucketStart}`,\n deviceToken,\n eventType: 0,\n occurredTime: start < floor ? new Date(floor).toISOString() : b.bucketStart,\n name: b.name,\n value: b.avg,\n classifier: null,\n };\n }\n return { latest, observed: [...observed] };\n}\n\n// Two seeds of one device: `newer` (read over a later stretch) wins per name; observed is the union.\nexport function mergeSeeds(newer: MemberSeed, older: MemberSeed): MemberSeed {\n return {\n latest: { ...older.latest, ...newer.latest },\n observed: [...new Set([...newer.observed, ...older.observed])],\n };\n}\n\n// The tail of a window: its last TAIL_SECONDS, on whole minutes, in one-minute buckets. Undefined\n// when the window is no longer than that (the window itself is then the cheap read).\nexport function tailWindow(window: HistoryWindow): HistoryWindow | undefined {\n const start = Math.floor((Date.parse(window.endTime) + 1) / MINUTE_MS) * MINUTE_MS - TAIL_SECONDS * 1000;\n if (!(start > Date.parse(window.startTime))) return undefined;\n return { startTime: new Date(start).toISOString(), endTime: window.endTime, intervalSeconds: 60 };\n}\n\n// The plan a fleet widget hands the hub: the window is the widget's span, `names` the measurements\n// it shows (empty: every measurement its devices report).\nexport function memberSeedPlan(window: HistoryWindow, names: readonly string[]): MemberSeedPlan {\n const wanted = [...new Set(names)];\n return {\n async seed(deviceToken, read) {\n const fold = (c: MemberBucketCriteria) => read(c).then((b) => foldMemberSeed(deviceToken, b, c.startTime));\n const tail = tailWindow(window);\n let seed: MemberSeed;\n let recent: MemberSeed | undefined;\n if (wanted.length === 0 || !tail) seed = await fold(window);\n else {\n recent = await fold(tail);\n const missing = wanted.filter((name) => !has(recent!.latest, name));\n // Nothing missing falls through the loop below with no read: the tail was the whole answer.\n if (recent.observed.length === 0 || missing.length > MAX_NARROW_READS) seed = mergeSeeds(recent, await fold(window));\n else {\n seed = recent;\n for (const name of missing) seed = mergeSeeds(seed, await fold({ ...window, name }));\n }\n }\n return window.intervalSeconds > 60 ? sharpen(seed, recent, window, fold) : seed;\n },\n };\n}\n\n// Step 3 above: replaces each value a span read found (any not from the tail's minutes) with the\n// newest minute of its span bucket. A span value is stamped at its bucket's start (or the window's),\n// so the bucket's readings lie between that stamp and one bucket width after it.\nasync function sharpen(\n seed: MemberSeed,\n recent: MemberSeed | undefined,\n window: HistoryWindow,\n fold: (c: MemberBucketCriteria) => Promise<MemberSeed>,\n): Promise<MemberSeed> {\n const byStamp = new Map<number, string[]>();\n for (const [name, sample] of Object.entries(seed.latest)) {\n if (recent && has(recent.latest, name)) continue;\n const at = Date.parse(sample.occurredTime ?? '');\n byStamp.set(at, [...(byStamp.get(at) ?? []), name]);\n }\n const latest = { ...seed.latest };\n const unread: string[] = [];\n const end = Date.parse(window.endTime) + 1;\n const stamps = [...byStamp.keys()].sort((a, b) => b - a);\n for (const [i, at] of stamps.entries()) {\n const names = byStamp.get(at)!;\n const minutes =\n i < MAX_NARROW_READS\n ? (\n await fold({\n startTime: new Date(at).toISOString(),\n endTime: new Date(Math.min(at + window.intervalSeconds * 1000, end) - 1).toISOString(),\n intervalSeconds: 60,\n ...(names.length === 1 ? { name: names[0] } : {}),\n })\n ).latest\n : {};\n for (const name of names) {\n if (has(minutes, name)) latest[name] = minutes[name];\n else {\n delete latest[name];\n unread.push(name);\n }\n }\n }\n return { latest, observed: seed.observed, unread };\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;AA0BA;AAAA,EACE;AAAA,OAUK;AACP,SAAS,WAAW,0BAA0B,oBAAoB,aAAa,+BAA+B;AAC9G,SAAS,WAAW,SAAS,YAAY,QAAQ,gBAAoC;;;ACUrF,IAAM,YAAY;AAIX,IAAM,eAAe;AAIrB,IAAM,mBAAmB;AAEhC,IAAM,MAAM,CAAC,GAAW,QAAyB,OAAO,UAAU,eAAe,KAAK,GAAG,GAAG;AAKrF,SAAS,eAAe,aAAqB,SAAuC,WAAgC;AACzH,QAAM,QAAQ,cAAc,SAAY,OAAO,MAAM,KAAK,MAAM,SAAS;AACzE,QAAM,SAA4C,CAAC;AACnD,QAAM,KAA6B,CAAC;AACpC,QAAM,WAAW,oBAAI,IAAY;AACjC,aAAW,KAAK,SAAS;AACvB,QAAI,EAAE,UAAU,SAAY,EAAE,OAAO,OAAO,EAAE,QAAQ,EAAG,UAAS,IAAI,EAAE,IAAI;AAC5E,QAAI,EAAE,OAAO,KAAM;AACnB,UAAM,QAAQ,KAAK,MAAM,EAAE,WAAW;AACtC,QAAI,IAAI,IAAI,EAAE,IAAI,KAAK,GAAG,EAAE,IAAI,KAAK,MAAO;AAC5C,OAAG,EAAE,IAAI,IAAI;AACb,WAAO,EAAE,IAAI,IAAI;AAAA,MACf,IAAI,QAAQ,WAAW,IAAI,EAAE,IAAI,IAAI,EAAE,WAAW;AAAA,MAClD;AAAA,MACA,WAAW;AAAA,MACX,cAAc,QAAQ,QAAQ,IAAI,KAAK,KAAK,EAAE,YAAY,IAAI,EAAE;AAAA,MAChE,MAAM,EAAE;AAAA,MACR,OAAO,EAAE;AAAA,MACT,YAAY;AAAA,IACd;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,UAAU,CAAC,GAAG,QAAQ,EAAE;AAC3C;AAGO,SAAS,WAAW,OAAmB,OAA+B;AAC3E,SAAO;AAAA,IACL,QAAQ,EAAE,GAAG,MAAM,QAAQ,GAAG,MAAM,OAAO;AAAA,IAC3C,UAAU,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,CAAC;AAAA,EAC/D;AACF;AAIO,SAAS,WAAW,QAAkD;AAC3E,QAAM,QAAQ,KAAK,OAAO,KAAK,MAAM,OAAO,OAAO,IAAI,KAAK,SAAS,IAAI,YAAY,eAAe;AACpG,MAAI,EAAE,QAAQ,KAAK,MAAM,OAAO,SAAS,GAAI,QAAO;AACpD,SAAO,EAAE,WAAW,IAAI,KAAK,KAAK,EAAE,YAAY,GAAG,SAAS,OAAO,SAAS,iBAAiB,GAAG;AAClG;AAIO,SAAS,eAAe,QAAuB,OAA0C;AAC9F,QAAM,SAAS,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC;AACjC,SAAO;AAAA,IACL,MAAM,KAAK,aAAa,MAAM;AAC5B,YAAM,OAAO,CAAC,MAA4B,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,eAAe,aAAa,GAAG,EAAE,SAAS,CAAC;AACzG,YAAM,OAAO,WAAW,MAAM;AAC9B,UAAI;AACJ,UAAI;AACJ,UAAI,OAAO,WAAW,KAAK,CAAC,KAAM,QAAO,MAAM,KAAK,MAAM;AAAA,WACrD;AACH,iBAAS,MAAM,KAAK,IAAI;AACxB,cAAM,UAAU,OAAO,OAAO,CAAC,SAAS,CAAC,IAAI,OAAQ,QAAQ,IAAI,CAAC;AAElE,YAAI,OAAO,SAAS,WAAW,KAAK,QAAQ,SAAS,iBAAkB,QAAO,WAAW,QAAQ,MAAM,KAAK,MAAM,CAAC;AAAA,aAC9G;AACH,iBAAO;AACP,qBAAW,QAAQ,QAAS,QAAO,WAAW,MAAM,MAAM,KAAK,EAAE,GAAG,QAAQ,KAAK,CAAC,CAAC;AAAA,QACrF;AAAA,MACF;AACA,aAAO,OAAO,kBAAkB,KAAK,QAAQ,MAAM,QAAQ,QAAQ,IAAI,IAAI;AAAA,IAC7E;AAAA,EACF;AACF;AAKA,eAAe,QACb,MACA,QACA,QACA,MACqB;AACrB,QAAM,UAAU,oBAAI,IAAsB;AAC1C,aAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,KAAK,MAAM,GAAG;AACxD,QAAI,UAAU,IAAI,OAAO,QAAQ,IAAI,EAAG;AACxC,UAAM,KAAK,KAAK,MAAM,OAAO,gBAAgB,EAAE;AAC/C,YAAQ,IAAI,IAAI,CAAC,GAAI,QAAQ,IAAI,EAAE,KAAK,CAAC,GAAI,IAAI,CAAC;AAAA,EACpD;AACA,QAAM,SAAS,EAAE,GAAG,KAAK,OAAO;AAChC,QAAM,SAAmB,CAAC;AAC1B,QAAM,MAAM,KAAK,MAAM,OAAO,OAAO,IAAI;AACzC,QAAM,SAAS,CAAC,GAAG,QAAQ,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACvD,aAAW,CAAC,GAAG,EAAE,KAAK,OAAO,QAAQ,GAAG;AACtC,UAAM,QAAQ,QAAQ,IAAI,EAAE;AAC5B,UAAM,UACJ,IAAI,oBAEE,MAAM,KAAK;AAAA,MACT,WAAW,IAAI,KAAK,EAAE,EAAE,YAAY;AAAA,MACpC,SAAS,IAAI,KAAK,KAAK,IAAI,KAAK,OAAO,kBAAkB,KAAM,GAAG,IAAI,CAAC,EAAE,YAAY;AAAA,MACrF,iBAAiB;AAAA,MACjB,GAAI,MAAM,WAAW,IAAI,EAAE,MAAM,MAAM,CAAC,EAAE,IAAI,CAAC;AAAA,IACjD,CAAC,GACD,SACF,CAAC;AACP,eAAW,QAAQ,OAAO;AACxB,UAAI,IAAI,SAAS,IAAI,EAAG,QAAO,IAAI,IAAI,QAAQ,IAAI;AAAA,WAC9C;AACH,eAAO,OAAO,IAAI;AAClB,eAAO,KAAK,IAAI;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,UAAU,KAAK,UAAU,OAAO;AACnD;;;ADvEQ;AApDD,IAAM,WAAW;AAExB,IAAM,aAAa;AAGZ,IAAM,mBAAmB;AAChC,IAAMA,aAAY;AAalB,IAAM,aAAa,CAAC,SAA+B,EAAE,KAAK,QAAQ,MAAM,MAAM,oBAAI,IAAI,GAAG,OAAO,oBAAI,IAAI,GAAG,WAAW,OAAO,OAAO,KAAK;AAEzI,SAAS,OAAO,MAAmD,QAAiC;AAClG,MAAI,SAAS,KAAK,IAAI,OAAO,WAAW;AACxC,MAAI,CAAC,OAAQ,MAAK,IAAI,OAAO,aAAc,SAAS,oBAAI,IAAI,CAAE;AAE9D,QAAM,OAAO,OAAO,IAAI,OAAO,IAAI;AACnC,MAAI,MAAM,gBAAgB,OAAO,gBAAgB,KAAK,MAAM,OAAO,YAAY,IAAI,KAAK,MAAM,KAAK,YAAY,EAAG;AAClH,SAAO,IAAI,OAAO,MAAM,MAAM;AAChC;AAkBO,SAAS,aAAa,EAAE,QAAQ,WAAW,GAA6D;AAC7G,QAAM,UAAU,aAAa;AAC7B,QAAM,YAAa,WAAW,QAAkC,YAAY;AAC5E,SACE,oBAAC,eAAY,OAAO,UAAU,OAAO,SAAS,OAAO,GACnD,8BAAC,SAAI,sBAAmB,IAAG,OAAO,EAAE,SAAS,WAAW,GACtD,8BAAC,cAAW,SAAS,GAAG,QAAQ,SAAS,IAAI,YAAY,QAAQ,eAAe,QAAQ,aAAa,IAAI,GAC3G,GACF;AAEJ;AAOO,SAAS,kBAAkB,QAAkC;AAClE,QAAM,MAAM,OAAO,SAAS;AAC5B,QAAM,QAAQ,CAAC,GAAI,OAAO,YAAY,gBAAgB,CAAC,GAAI,GAAI,OAAO,QAAQ,YAAY,QAAQ,KAAK,CAAC,GAAG,IAAI,CAAC,CAAE;AAClH,SAAO,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC;AAC3B;AAEe,SAAR,WAA4B,OAAuB;AACxD,SAAO,MAAM,SAAS,oBAAC,gBAAa,QAAQ,MAAM,QAAQ,YAAY,MAAM,YAAY,IAAK,oBAAC,aAAW,GAAG,OAAO;AACrH;AAEA,SAAS,UAAU,EAAE,KAAK,QAAQ,YAAY,WAAW,SAAS,WAAW,GAAmB;AAC9F,QAAM,QAAQ,mBAAmB;AACjC,QAAM,MAAM,QAAQ,MAAO,IAAI,MAAM,MAAM,IAAI,IAAK,IAAI,KAAK,KAAM,CAAC,GAAG,CAAC;AACxE,QAAM,cAAc,gBAAgB,YAAY,QAAQ,OAAO,WAAW,KAAK,OAAO,eAAe;AACrG,QAAM,WAAW,OAAO,SAAS,MAAM,WAAW;AAClD,QAAM,QAAQ,kBAAkB,MAAM;AACtC,QAAM,KAAK,OAAO,cAAc,EAAE,GAAG,OAAO,YAAY,cAAc,MAAM;AAC5E,QAAM,QAAQ,KAAK,UAAU,MAAM,IAAI;AACvC,QAAM,WAAW,KAAK,UAAU,KAAK;AACrC,QAAM,YAAY,IAAI,qBAAqB,UAAa,IAAI,oBAAoB;AAEhF,QAAM,QAAQ,OAAc,WAAW,KAAK,CAAC;AAE7C,QAAM,SAAS,OAAoD,oBAAI,IAAI,CAAC;AAC5E,QAAM,YAAY,OAAO,aAAa,MAAS;AAC/C,QAAM,CAAC,SAAS,IAAI,IAAI,WAAW,CAAC,MAAc,IAAI,GAAG,CAAC;AAC1D,QAAM,CAAC,WAAW,YAAY,IAAI,SAAwB,IAAI;AAC9D,QAAM,aAAa,OAAkD,MAAS;AAE9E,QAAM,CAAC,SAAS,OAAO,IAAI,WAAW,CAAC,MAAc,IAAI,GAAG,CAAC;AAC7D,QAAM,gBAAgB,OAAkD,MAAS;AAEjF,QAAM,WAAW,MAAY;AAC3B,QAAI,WAAW,YAAY,OAAW;AACtC,eAAW,UAAU,WAAW,MAAM;AACpC,iBAAW,UAAU;AACrB,WAAK;AAAA,IACP,GAAG,QAAQ;AAAA,EACb;AAGA,YAAU,MAAM;AACd,UAAM,IAAI,WAAW,KAAK;AAC1B,UAAM,UAAU;AAChB,WAAO,UAAU,oBAAI,IAAI;AACzB,iBAAa,IAAI;AACjB,SAAK;AACL,QAAI,CAAC,MAAM,CAAC,UAAW;AACvB,UAAM,UAAU,IAAI,iBAAkB,IAAI;AAAA,MACxC,QAAQ,CAAC,WAAW;AAClB,UAAE,SAAS;AACX,qBAAa,OAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;AAC1D,iBAAS;AAAA,MACX;AAAA,MACA,MAAM,CAAC,WAAW;AAChB,eAAO,UAAU,UAAU,OAAO,UAAU,EAAE,MAAM,MAAM;AAC1D,YAAI,CAAC,UAAU,QAAS,UAAS;AAAA,MACnC;AAAA,MACA,WAAW,MAAM;AACf,UAAE,YAAY;AACd,iBAAS;AAAA,MACX;AAAA,MACA,OAAO,CAAC,QAAQ;AACd,UAAE,QAAQ;AACV,iBAAS;AAAA,MACX;AAAA;AAAA;AAAA,MAGA,aAAa,MAAM;AACjB,gBAAQ;AACR,YAAI,cAAc,YAAY,OAAW;AACzC,cAAM,KAAK,IAAI;AACf,sBAAc,UAAU,WAAW,MAAM;AACvC,wBAAc,UAAU;AACxB,kBAAQ;AAAA,QACV,GAAGA,aAAa,KAAKA,aAAa,gBAAgB;AAAA,MACpD;AAAA,IACF,CAAC;AACD,WAAO,MAAM;AACX,cAAQ;AACR,UAAI,WAAW,YAAY,OAAW,cAAa,WAAW,OAAO;AACrE,iBAAW,UAAU;AACrB,UAAI,cAAc,YAAY,OAAW,cAAa,cAAc,OAAO;AAC3E,oBAAc,UAAU;AAAA,IAC1B;AAAA,EAGF,GAAG,CAAC,KAAK,OAAO,SAAS,CAAC;AAG1B,YAAU,MAAM;AACd,UAAM,MAAM,UAAU;AACtB,cAAU,UAAU,aAAa;AACjC,QAAI,OAAO,aAAa,QAAW;AACjC,iBAAW,UAAU,OAAO,QAAQ,OAAO,EAAG,YAAW,UAAU,OAAO,OAAO,EAAG,QAAO,MAAM,QAAQ,MAAM,MAAM;AACrH,aAAO,UAAU,oBAAI,IAAI;AACzB,eAAS;AAAA,IACX;AAAA,EAEF,GAAG,CAAC,QAAQ,CAAC;AAGb,YAAU,MAAM;AACd,UAAM,IAAI,MAAM;AAChB,QAAI,CAAC,aAAa,CAAC,EAAE,UAAU,cAAc,KAAM;AACnD,UAAM,SAAS,EAAE,OAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,KAAK;AAClD,QAAI,OAAO,WAAW,EAAG;AACzB,QAAI,YAAY;AAChB,SAAK,IAAI;AAAA,MACP;AAAA,MACA,eAAe,WAAW,aAAa,YAAY,IAAI,CAAC,GAAG,KAAK;AAAA,MAChE,CAAC,OAAO,MAAM,YAAY;AACxB,YAAI,YAAY,YAAa,GAAE,YAAY;AAAA,iBAClC,KAAM,GAAE,MAAM,IAAI,OAAO,IAAI;AAAA,iBAE7B,EAAE,MAAM,IAAI,KAAK,MAAM,OAAW,GAAE,MAAM,IAAI,OAAO,QAAQ;AACtE,iBAAS;AAAA,MACX;AAAA,MACA,MAAM;AAAA,IACR;AACA,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EAEF,GAAG,CAAC,KAAK,WAAW,OAAO,WAAW,aAAa,UAAU,UAAU,OAAO,CAAC;AAG/E,YAAU,MAAM;AACd,QAAI,aAAa,OAAW;AAC5B,UAAM,KAAK,YAAY,MAAM,UAAU;AACvC,WAAO,MAAM,cAAc,EAAE;AAAA,EAC/B,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,UAAU,QAAoB,MAAM;AACxC,UAAM,IAAI,MAAM,QAAQ,QAAQ,QAAQ,MAAM,UAAU,WAAW,KAAK;AACxE,QAAI,CAAC,UAAW,QAAO,EAAE,QAAQ,eAAe,SAAS,CAAC,GAAG,OAAO,GAAG,WAAW,MAAM;AACxF,WAAO,WAAW;AAAA,MAChB,QAAQ,EAAE;AAAA,MACV,OAAO,EAAE;AAAA,MACT,MAAM,EAAE;AAAA,MACR,QAAQ,YAAY,IAAI,KAAK,cAAc;AAAA,MAC3C,WAAW,EAAE;AAAA,IACf,CAAC;AAAA,EAGH,GAAG,CAAC,SAAS,WAAW,OAAO,aAAa,UAAU,GAAG,CAAC;AAE1D,QAAM,QAAQ,MAAM,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,QAAQ;AAClE,QAAM,OAA+B,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC,GAAG,OAAO,QAAQ;AAI/E,QAAM,YAAY;AAAA,IAChB,MACE,WAAW,cAAc,OACrB,EAAE,IAAI,iBAAiB,OAAO,GAAG,mBAAmB,yBAAyB,OAAO,OAAO,EAAE,IAC7F;AAAA,IACN,CAAC,YAAY,OAAO,SAAS,OAAO;AAAA,EACtC;AACA,MAAI,MAAO,QAAO,oBAAC,cAAW,QAAgB,OAAc;AAC5D,SACE,oBAAC,2BAAwB,WACvB,8BAAC,aAAU,QAAgB,MAAY,SAAkB,GAC3D;AAEJ;",
6
+ "names": ["MINUTE_MS"]
7
+ }
@@ -0,0 +1,7 @@
1
+ import {
2
+ Table
3
+ } from "./chunk-USRYKW2J.js";
4
+ export {
5
+ Table
6
+ };
7
+ //# sourceMappingURL=table-6EVV7QZH.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -6,5 +6,7 @@ export interface ConnectedWidgetProps {
6
6
  registry?: WidgetRegistry;
7
7
  actions?: WidgetActions;
8
8
  initialSamples?: MeasurementSample[];
9
+ initialSamplesAsOf?: number;
10
+ onReconnect?: () => void;
9
11
  }
10
12
  export declare function ConnectedWidget(props: ConnectedWidgetProps): import("react").JSX.Element;
@@ -31,3 +31,4 @@ export declare function relativeBoxStyle(p: RelativePlacement, lengths: Pick<Gri
31
31
  export declare function sizingStyle(sizing: CanvasSizing, bg: CanvasBackground | undefined): CSSProperties;
32
32
  export declare function resolveWidgets(widgets: WidgetInstance[], bindings: Record<string, SlotBinding> | undefined): WidgetInstance[];
33
33
  export declare function widgetSubjectLabel(widget: WidgetInstance): string | undefined;
34
+ export declare const RESEED_RETRY_MS = 30000;
@@ -1,6 +1,7 @@
1
1
  import { type WidgetActions, type WidgetDataSource, type WidgetDescriptor, type WidgetInstance } from '@devicechain/dashboards';
2
2
  import { type ComponentType } from 'react';
3
3
  export declare const FLUSH_MS = 250;
4
+ export declare const RESEED_SETTLE_MS = 2000;
4
5
  export interface FleetFeedProps {
5
6
  hub: WidgetDataSource;
6
7
  widget: WidgetInstance;
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { DEFAULT_TIME_RANGE_LABELS, PausedIndicator, TimeRangeBar, useBoardTimeR
3
3
  export { ConnectedWidget, type ConnectedWidgetProps } from './connected-widget';
4
4
  export { builtinWidgetCatalog, builtinWidgetDescriptors } from './builtin-descriptors';
5
5
  export { builtinWidgetDefinitions, createBuiltinWidgetRegistry } from './builtin-registry';
6
+ export { preloadWidgets } from './preload';
6
7
  export { WIDGET_CHANNEL, WIDGET_BINDS_DATASOURCE, type WidgetChannel } from './registry';
7
8
  export { pickSample, optBoolean, type WidgetProps, type WidgetComponent } from '@devicechain/widget-sdk';
8
9
  export { TenantBasemapProvider, useTenantBasemap } from './basemap-context';