MDK Logo
ReferenceUI Kitui-foundation

Utilities

Public utility functions exported by @tetherto/mdk-ui-foundation.

Imported from @tetherto/mdk-ui-foundation.

Alerts

NameSignature / TypeDescription
breakTimeIntoIntervals(start: number, end: number, intervalMs: number = ONE_DAY_MS) => TimeInterval[]Split `[start, end]` into consecutive windows of `intervalMs`. The final window is clamped to `end`. Returns an empty array when the range is empty or inverted. Mirrors Mining OS's `breakTimeIntoIntervals`.
buildCurrentAlertDevicesParams(filterTags: string[] = []) => ListThingsParams`list-things` params for the current-alerts table: every device that currently carries one or more alerts, with the fields the `<CurrentAlerts>` table reads. Consumed by `useCurrentAlertDevices`.
buildHistoricalAlertsParams(range: HistoricalAlertsRange) => HistoryLogParams`history-log` params for a single alerts window. The chunked fetch (`useHistoricalAlerts`) calls this once per 24h sub-window.
fetchHistoricalAlertsInChunks(range: { start: number; end: number }, fetchWindow: (window: TimeInterval) => Promise<T[]>, options: FetchHistoricalAlertsOptions = {}) => Promise<T[]>Fetch a historical-alerts range as successive 24h windows, merging the results by `uuid`. `fetchWindow` is called once per window (oldest → newest); individual window failures are swallowed (matches Mining OS) so one bad window doesn't dro…
getAlertsForDevices(devices: ListThingsDevice[], formatDate: (d: Date) => string = (d) => d.toISOString()) => IncidentRow[]Flatten an array of devices into a list of incident rows, one per alert. Devices without `last.alerts` are skipped. The output is **not yet sorted**; pair with {@link sortIncidentsBySeverity} for the final list-view order.
getDefaultHistoricalAlertsRange(now: number = Date.now()) => HistoricalAlertsRangeDefault historical-alerts range: the last {@link DEFAULT_HISTORICAL_WINDOW_MS} ending now. Used by the devkit `<Alerts>` feature and the shell Alerts page to seed their range state.
mapDevicesToIncidents(devices: ListThingsDevice[], formatDate?: (d: Date) => string) => IncidentRow[]One-shot helper: `devices → sorted rows`. Used by the `useActiveIncidents` hook's `select` projection.
mapHistoryLogToAlerts(rows: HistoricalAlert[] = []) => HistoricalAlert[]Normalise raw `history-log` alert rows into the shape the devkit `<HistoricalAlerts>` table consumes. The table derives its device label, short code, and filter tokens from each row's `thing` (treated as a device), so this guarantees `thin…
mergeAlertsByUuid(prev: T[], next: T[]) => T[]Concatenate `next` onto `prev`, replacing any row that shares a `uuid` (later windows win) and appending the rest. Rows without a `uuid` are always appended. Mirrors Mining OS's `updateHistoricalData`.
sortIncidentsBySeverity(rows: IncidentRow[]) => IncidentRow[]Sort rows by severity (critical → high → medium), then by `id` for deterministic ordering when severities tie. Returns a new array.

Auth

NameSignature / TypeDescription
extractAuthTokenFromUrl(search: string) => string | nullExtract `?authToken=` from a URL search string. Accepts either a full URL, a query string with leading `?`, or a bare query string.
stripAuthTokenFromUrl(search: string) => stringBuild a URL string with the `?authToken=` parameter stripped. Used after the OAuth callback to remove the token from the address bar without losing any other query state.

Dashboard

NameSignature / TypeDescription
buildHashrateTailLogParams(range: DashboardQueryRange) => TailLogParamsHashrate tail-log params — per-miner 1-minute aggregate, summed across the `t-miner` tag.
buildMinerpoolStatsHistoryExtDataParams(range: MinerpoolStatsHistoryRange = {}) => ExtDataParamsExt-data params for `type=minerpool, key=stats-history` — per-pool hashrate snapshots over time. Pair with `extDataQuery` to feed the multi-series Hash Rate chart (Mining OS + Aggr Pool + per-pool lines).
buildSiteConsumptionTailLogParams(range: DashboardQueryRange) => TailLogParamsSite-level consumption tail-log params — reads the dedicated powermeter's `site_power_w` aggregate (Mining OS's `type=powermeter, tag=t-powermeter, aggrFields={site_power_w:1}` query). Returns the same series the header's `useSitePowerMete…
getTimelineOptions(opts: { includeOneMinute?: boolean } = {}) => TimelineOption[]Default options for the dashboard timeline selector. Mirrors Mining OS's `timelineRadioButtons` (5m / 30m / 3h / 1D) — the production dashboard doesn't expose `stat-1m` because the backend typically only emits 5-minute and longer aggregate…
normalizeAlertSeverity(raw: string | null | undefined) => AlertSeverityNarrow an arbitrary backend severity string to the `AlertSeverity` literal union expected by the `ActiveIncidentsCard` row component. Unknown values fall back to `'medium'` so the row still renders rather than crashing on an unexpected pay…
readHashrateMhs(entry: { hashrate_mhs_1m_sum_aggr?: unknown hashrate_mhs_5m_sum_aggr?: unknown }) => number | undefinedReads the hashrate aggregate from a tail-log entry. Mining OS emits `hashrate_mhs_1m_sum_aggr` across every `stat-*` bucket, so a single field check covers all timelines; the `_5m_` legacy fallback is retained as a defensive secondary in c…

General

NameSignature / TypeDescription
appendContainerToTag(deviceId: string) => string
appendIdToTag(deviceId: string) => string
appendIdToTags(deviceIdList: string[]) => string[]
buildCabinetDetailParams(root: string) => ListThingsParamsList-things params for one LV cabinet's family of devices — the powermeters and temperature sensors whose `info.pos` sits under the cabinet `root`. Mirrors the reference app's `getLvCabinetDevicesByRoot(root)`; the detail hook groups the r…
buildContainerCrossThing(containers: string[]) => DeviceActionCrossThing`{ type: 'container', params: { containers } }` fan-out for miner-level actions.
buildContainerDetailParams(containerKeys: string[]) => ListThingsParamsList-things params for the selected containers' detail snapshots. Takes the raw container keys (the `selectedDevicesTags` outer keys / `info.container` names), tags them with `container-` and filters to `t-container` things — mirrors the r…
buildContainerWidgetsListParams() => ListThingsParamsList-things params for the Site Overview container widgets grid.
buildContainerWidgetsRealtimeTailLogParams() => TailLogParamsTail-log params for the Container Widgets realtime snapshot — the latest `stat-realtime` sample across all miners, grouped so the cards can slice per container.
buildDeviceActionSubmission(action: DeviceActionValue, tags: string[], params: VotingActionParam[] = [], extras: Record<string, unknown> = {}) => DeviceActionSubmissionCore submission assembler. Prefer the per-action builders below — they pin each action's param arity/encoding; this is the escape hatch for actions without a dedicated builder. `extras` is spread first so it can never override the pinned s…
buildExplorerListThingsParams(tab: ExplorerTabValue, options: { limit?: number; offset?: number } = {}) => ListThingsParamsList-things params for one Explorer tab: tag-filtered, status-enriched, projected to {@link OP_CENTRE_LIST_THINGS_FIELDS}.
buildMinerCrossThing(containers: string[]) => DeviceActionCrossThing`{ type: 'miner', params: { containers } }` fan-out for container-level actions.
buildRebootAction(tags: string[]) => DeviceActionSubmission`reboot` — no params.
buildResetAlarmAction(tags: string[]) => DeviceActionSubmission`resetAlarm` — no params.
buildSetAirExhaustEnabledAction(tags: string[], isOn: boolean) => DeviceActionSubmission`setAirExhaustEnabled` — single boolean param.
buildSetLedAction(tags: string[], isOn: boolean) => DeviceActionSubmission`setLED` — single boolean param.
buildSetPlcRegistersAction(tags: string[], registers: Record<string, unknown>) => DeviceActionSubmission`setPlcRegisters` (Gamma) — single `{ register: value }` map param.
buildSetPowerModeAction(tags: string[], mode: PowerModeValue, crossThing?: DeviceActionCrossThing) => DeviceActionSubmission`setPowerMode` — single power-mode param, optional container fan-out.
buildSetPowerPctAction(tags: string[], percentage: number, crossThing?: DeviceActionCrossThing) => DeviceActionSubmission`setPowerPct` — percentage encoded as a string, optional container fan-out.
buildSetTankEnabledAction(tags: string[], tankNumber: number, isOn: boolean) => DeviceActionSubmission`setTankEnabled` — positional `[tankNumber, isOn]`.
buildSwitchContainerAction(tags: string[], isOn: boolean) => DeviceActionSubmission`switchContainer` — single boolean param.
buildSwitchCoolingSystemAction(tags: string[], isOn: boolean, crossThing?: DeviceActionCrossThing) => DeviceActionSubmission`switchCoolingSystem` — single boolean param, optional miner fan-out.
buildSwitchSocketAction(tags: string[], sockets: SocketSwitch[]) => DeviceActionSubmission`switchSocket` — one `{ pdu, socket, enabled }` param per toggled socket.
buildUpdateThingBatchEntry(params: UpdateThingParams, minerId: string = params.id) => VotingActionPayloadOne `updateThing` entry inside a move/add/replace-miner batch — carries the miner's new rack/position/network config plus the owning `minerId` the backend uses to group batch progress.
checkPermission(config: AuthConfig | null | undefined, { perm, write, cap }: PermissionCheck) => booleanCheck if user has the requested permission
deriveContainerActivity(realtime: TailLogEntry | undefined, containerModel: string, total: number) => ContainerActivitySlice the realtime aggregate into one container's per-status miner counts. `total` is the container's nominal miner capacity; miners not accounted for by any status count collapse into `disconnected` (never negative). With no realtime samp…
deriveContainerSummary(realtime: TailLogEntry | undefined, containerModel: string) => ContainerSummary
deriveContainerTanks(container: ListThingsDevice) => TankReading[]Derive the per-tank readings for a container's immersion cooling system — one entry per oil pump, joined with the matching water pump and (when present) the tank pressure. Returns an empty array for containers without an immersion cooling…
deriveSelectedSockets(containers: ContainerSnapshotForSockets[] | undefined, selectedDevicesTags: Record<string, Record<string, unknown>>, allDevices: MinerForSocket[] | undefined) => Record<string, { sockets: DerivedSoc…Derive the store's `selectedSockets` map (keyed by container tag) from the selected device-tags — the pure body of the reference app's `findAndSetSelectedSockets`. Each per-container tag key (`pos-…` / `id-…`) is stripped of its `pos-` pre…
exportSettingsToFile(data: SettingsExportData) => string
filterUsers({ users, email, role }: FilterUsersParams) => SettingsUser[]
findMatchingContainer(settings: ContainerSettingsEntry[] | undefined, containerType: string | undefined) => ContainerSettingsEntry | nullFind the container-settings row for a container type: an exact `model` match first, else the settings-model family fallback. Mirrors the reference app's `findMatchingContainer`.
flattenKernelEnvelope(envelope: ReadonlyArray<readonly (T | null | undefined)[] | null | undefined> | null | undefined) => T[]Flattens the per-Kernel response envelope the gateway wraps around merged worker responses (`/auth/list-things`, `/auth/list-racks`, ... return `[[row, ...], [row, ...]]` — one inner array per Kernel). Null-safe on both levels: a missing e…
formatLastActive(timestamp: string | undefined) => string
formatRoleLabel(role: string) => string
getAntspaceHydroIndexes(pos: string) => string[]Antspace Hydro position → `[rack, pdu, socket]`.
getAntspaceImmersionIndexes(pos: string) => string[]Antspace Immersion position → `[pdu, socket]`.
getBitdeerIndexes(pos: string) => string[]Bitdeer / MicroBT position → `[pdu, socket]`.
getByIdsQuery(ids: string[], allowEmptyArray?: boolean) => string
getByTagsQuery(filterTags: string[], allowEmptyArray?: boolean) => string
getByTagsWithAlertsQuery(filterTags: string[], allowEmptyArray?: boolean) => string
getByTagsWithCriticalAlertsQuery(filterTags: string[], allowEmptyArray?: boolean) => string
getByThingsAttributeQuery(filterAttributes: FilterAttribute[], selectedTypes: string[], allowEmptyArray?: boolean) => UnknownRecord
getByTypesQuery(filterTypes: string[], allowEmptyArray?: boolean) => string
getConnectedMinerForSocket(devices: MinerForSocket[] | undefined, pos: string) => MinerForSocket | undefinedThe selected miner sitting at `pos`, if any (miners only, exact position).
getContainerByContainerTagsQuery(filterTags: string[], allowEmptyArray?: boolean) => string
getContainerMinersByContainerTagsQuery(filterTags: string[], allowEmptyArray?: boolean) => string
getContainerSettingsModel(containerType: string | undefined) => string | nullMap a container type string to its settings-model key (`bd` / `mbt` / `hydro` / `immersion`), or `null` for an unknown family. Mirrors the reference app's `getContainerSettingsModel`.
getDeviceByAlertId(uuid: string) => string
getFiltersQuery(filterTags?: string[], filters?: Record<string, string[]>, selectedTypes: string[] = ['t-container']) => UnknownRecord
getListQuery(filterTags: string[], filters?: Record<string, string[]>, selectedTypes: string[] = ['t-container']) => string
getLvCabinetDevicesByRoot(root: string) => string
getMinersByContainerTagsQuery(filterTags: string[], allowEmptyArray?: boolean) => string
getPduByIndex(container: ContainerSnapshotForSockets | undefined, pduIndex: string | number) => PduSnapshot | undefinedThe PDU row whose `pdu` matches `pduIndex` on this container, or undefined.
getPduData(last: ContainerSnapshotForSockets['last']) => PduSnapshot[] | undefinedThe `pdu_data` array off a container detail snapshot, or undefined.
getRolesFromAuthToken(authToken?: string) => string[]Extract roles from authentication token
getSignInRedirectUrl(authToken: string | null | undefined) => stringGet redirect URL based on user's primary role
getSitePowerMeterQuery() => string
getSocketInfo(container: ContainerSnapshotForSockets, pos: string, allDevices: MinerForSocket[] | undefined) => DerivedSocketResolve one socket for `pos` on `container`: pick the vendor index scheme off the container name, then (for Bitdeer / MicroBT) join the live PDU row so `enabled` / `cooling` reflect the snapshot. Hydro / Immersion have no live socket table…
getSupportedContainerTabs(type: string | undefined) => ContainerTabValue[]Full tab sequence for a container type: the family's base sequence, plus Power Adjustment spliced in after the PDU tab for Whatsminer containers. Unknown types resolve to an empty list.
getWidgetAlarmState(_container: ListThingsDevice, _settings: ContainerSettingsEntry | null = null) => ContainerAlarmStateResolve a container's alarm state from its live stats and matched settings.
isAntminer(type: string | undefined) => boolean
isAntspaceHydroContainer(type: string | undefined) => booleanAntspace/Bitmain hydro family (`as-hk3`, `antspace-hydro`, `bitmain-hydro`).
isAntspaceImmersionContainer(type: string | undefined) => booleanAntspace/Bitmain immersion family (`as-immersion`, `bitmain-imm[ersion]`).
isAvalon(type: string | undefined) => boolean
isBitdeerContainer(type: string | undefined) => booleanBitdeer family — `container-bd-*` and anything mentioning `bitdeer`.
isContainer(type: string | undefined) => boolean
isGammaContainer(type: string | undefined) => booleanGamma family (`m221`, `gamma`).
isMicroBTContainer(type: string | undefined) => booleanMicroBT family (`mbt`, `microbt`).
isMiner(type: string | undefined) => boolean
isPduContainerTab(tab: string | undefined) => booleanThe PDU grid renders under the `pdu` tab key.
isWhatsminer(type: string | undefined) => boolean
isWhatsminerContainer(type: string | undefined) => booleanContainers populated with Whatsminer miners (`m56` / `m30` positions, or any MicroBT container) — the set that gets the Power Adjustment tab.
parseSettingsFile(file: File) => Promise<SettingsExportData>
removeContainerPrefix(text: string) => string
resolveContainerModelFamily(type: string | undefined) => ContainerModelFamily | undefinedResolves a raw container `type` string (e.g. `container-bd-d40-m56`) to its model family, or `undefined` for unknown types. First match wins, in the reference app's original branch order.
validateSettingsJson(data: unknown) => data is SettingsExportData

Utils

NameSignature / TypeDescription
getLatestSample(entries: readonly T[] | null | undefined) => T | undefinedTiny projection helper used by the dashboard's header-stat hooks.