MDK Logo

Utilities

Helper functions exported by @mdk/core (formatting, validation, conversions) and @mdk/foundation (settings persistence)

This page documents helper functions exported by the MDK packages.

  • @mdk/core ships 15 utility modules with functions for formatting, dates, validation, conversions, class-name merging, and more
  • @mdk/foundation currently ships a single public utility module (settings-utils) for parsing, validating, and exporting settings JSON

@mdk/core utilities

Prerequisites

Import

@mdk/core
import {
  formatNumber,
  formatHashrate,
  formatDate,
  formatRelativeTime,
  cn,
  isEmpty,
  isValidEmail,
} from '@mdk/core'

Formatting utilities

formatNumber

@mdk/core

Format numbers with locale formatting and configurable options.

import { formatNumber, FALLBACK } from '@mdk/core'

formatNumber(1234.567)                          // "1,234.57"
formatNumber(null)                              // "-"
formatNumber(1234, { minimumFractionDigits: 2 }) // "1,234.00"
formatNumber(undefined, {}, 'N/A')              // "N/A"

formatHashrate

@mdk/core

Format hashrate values with rounding.

import { formatHashrate } from '@mdk/core'

formatHashrate(150.456)  // "150.46"
formatHashrate(null)     // "-"

formatCurrency

@mdk/core

Format currency values.

import { formatCurrency } from '@mdk/core'

formatCurrency(1234.56, 'USD')      // "$1,234.56"
formatCurrency(0.00012345, 'BTC')   // "₿0.00012345"

getPercentFormattedNumber

@mdk/core

Format numbers as percentages.

import { getPercentFormattedNumber } from '@mdk/core'

getPercentFormattedNumber(0.75)      // "75%"
getPercentFormattedNumber(0.1234, 1) // "12.3%"

formatValueUnit

@mdk/core

Format value-unit objects.

import { formatValueUnit } from '@mdk/core'

formatValueUnit(150, 'TH/s')  // "150 TH/s"

Date utilities

formatDate

@mdk/core

Format dates with customizable patterns.

import { formatDate } from '@mdk/core'

formatDate(new Date())                              // "Jan 15, 2025"
formatDate(1705334400000, { format: 'yyyy-MM-dd' }) // "2025-01-15"

formatRelativeTime

@mdk/core

Format dates as relative time strings.

import { formatRelativeTime } from '@mdk/core'

formatRelativeTime(new Date(Date.now() - 3600000))  // "1h ago"
formatRelativeTime(new Date(Date.now() - 86400000)) // "1d ago"

formatChartDate

@mdk/core

Format timestamps for chart display.

import { formatChartDate } from '@mdk/core'

formatChartDate(1705334400)        // "Jan 15"
formatChartDate(1705334400, true)  // "Jan 15, 2025"

isValidTimestamp

@mdk/core

Check if a timestamp is valid.

import { isValidTimestamp } from '@mdk/core'

isValidTimestamp(1705334400000)  // true
isValidTimestamp('invalid')      // false

parseMonthLabelToDate

@mdk/core

Parse month labels to Date objects.

import { parseMonthLabelToDate } from '@mdk/core'

parseMonthLabelToDate('01-26')    // Date(2026, 0, 1)
parseMonthLabelToDate('03-2025')  // Date(2025, 2, 1)

getPastDateFromDate

@mdk/core

Get a date in the past.

import { getPastDateFromDate } from '@mdk/core'

getPastDateFromDate({ dateTs: Date.now(), days: 7 })  // 7 days ago

Validation utilities

isEmpty

@mdk/core

Check if a value is empty.

import { isEmpty } from '@mdk/core'

isEmpty(null)       // true
isEmpty('')         // true
isEmpty([])         // true
isEmpty({})         // true
isEmpty('hello')    // false
isEmpty([1, 2, 3])  // false

isValidEmail

@mdk/core

Validate email addresses.

import { isValidEmail } from '@mdk/core'

isValidEmail('user@example.com')  // true
isValidEmail('invalid')           // false

isValidUrl

@mdk/core

Validate URLs.

import { isValidUrl } from '@mdk/core'

isValidUrl('https://example.com')  // true
isValidUrl('not-a-url')            // false

isNil

@mdk/core

Check if value is null or undefined.

import { isNil } from '@mdk/core'

isNil(null)       // true
isNil(undefined)  // true
isNil(0)          // false
isNil('')         // false

isPlainObject

@mdk/core

Check if value is a plain object.

import { isPlainObject } from '@mdk/core'

isPlainObject({})           // true
isPlainObject({ a: 1 })     // true
isPlainObject([])           // false
isPlainObject(new Date())   // false

Class name utilities

cn

@mdk/core

Merge class names using clsx and tailwind-merge.

import { cn } from '@mdk/core'

cn('px-4', 'py-2')                    // "px-4 py-2"
cn('text-red', isError && 'bg-red')   // conditional classes
cn('p-4', { 'hidden': !visible })     // object syntax

Conversion utilities

toMW / toMWh

@mdk/core

Convert watts to megawatts.

import { toMW, toMWh } from '@mdk/core'

toMW(1000000)   // 1
toMWh(1000000)  // 1

toPHS

@mdk/core

Convert raw hashrate to PH/s.

import { toPHS } from '@mdk/core'

toPHS(1000000000000000)  // 1

convertMpaToBar

@mdk/core

Convert pressure units.

import { convertMpaToBar } from '@mdk/core'

convertMpaToBar(0.1)  // 1

unitToKilo

@mdk/core

Convert to kilo units.

import { unitToKilo } from '@mdk/core'

unitToKilo(1000)  // 1

Number utilities

percentage

@mdk/core

Calculate percentage.

import { percentage } from '@mdk/core'

percentage(25, 100)  // 25
percentage(1, 4)     // 25

getPercentChange

@mdk/core

Calculate percentage change.

import { getPercentChange } from '@mdk/core'

getPercentChange(110, 100)  // 10
getPercentChange(90, 100)   // -10

convertUnits

@mdk/core

Convert between SI-prefix units.

import { convertUnits } from '@mdk/core'

convertUnits(1, 'k', 'M')           // 0.001
convertUnits(1000, 'decimal', 'k')  // 1

safeNumber

@mdk/core

Safely convert to number.

import { safeNumber } from '@mdk/core'

safeNumber('123')      // 123
safeNumber('invalid')  // 0
safeNumber(null)       // 0

String utilities

toTitleCase

@mdk/core

Convert string to Title Case.

import { toTitleCase } from '@mdk/core'

toTitleCase('hello world')  // "Hello World"

formatMacAddress

@mdk/core

Format MAC addresses.

import { formatMacAddress } from '@mdk/core'

formatMacAddress('aa:bb:cc:dd:ee:ff')  // "AA:BB:CC:DD:EE:FF"

safeString

@mdk/core

Safely convert to string.

import { safeString } from '@mdk/core'

safeString(123)    // "123"
safeString(null)   // ""

Time utilities

secondsToMs

@mdk/core

Convert seconds to milliseconds.

import { secondsToMs } from '@mdk/core'

secondsToMs(60)  // 60000

breakTimeIntoIntervals

@mdk/core

Split time range into intervals.

import { breakTimeIntoIntervals } from '@mdk/core'

breakTimeIntoIntervals(start, end, 3600000)  // Array of 1-hour intervals

timeRangeWalker

@mdk/core

Generator for iterating through time ranges.

import { timeRangeWalker } from '@mdk/core'

for (const interval of timeRangeWalker(start, end, duration)) {
  // Process each interval
}

Color utilities

hexToRgba

@mdk/core

Convert hex color to rgba.

import { hexToRgba } from '@mdk/core'

hexToRgba('#72F59E', 0.5)  // "rgba(114, 245, 158, 0.5)"

Array utilities

getNestedValue

@mdk/core

Get nested value by dot-path.

import { getNestedValue } from '@mdk/core'

getNestedValue({ a: { b: 1 } }, 'a.b')  // 1

getWeightedAverage

@mdk/core

Calculate weighted average.

import { getWeightedAverage } from '@mdk/core'

getWeightedAverage(items, 'value', 'weight')

circularArrayAccess

@mdk/core

Create infinite cycling generator.

import { circularArrayAccess } from '@mdk/core'

const colors = circularArrayAccess(['red', 'green', 'blue'])
colors.next().value  // 'red'
colors.next().value  // 'green'
colors.next().value  // 'blue'
colors.next().value  // 'red' (cycles)

@mdk/foundation utilities

Helpers for filtering, formatting, validating, parsing, and exporting settings data.

Prerequisites

Import

@mdk/foundation
import {
  filterUsers,
  formatRoleLabel,
  formatLastActive,
  validateSettingsJson,
  parseSettingsFile,
  exportSettingsToFile,
} from '@mdk/foundation'

Settings utilities

filterUsers

@mdk/foundation

Filter a SettingsUser[] list by email substring (case-insensitive) and exact role match. Used by the user-management table search.

import { filterUsers } from '@mdk/foundation'

filterUsers({
  users,
  email: 'alice',   // partial, case-insensitive match on user.email
  role: 'admin',    // exact match on user.role; pass null to skip
})
ParameterTypeDescription
usersSettingsUser[]Source list
emailstring | null | undefinedSubstring filter on email (case-insensitive). Skipped when falsy.
rolestring | null | undefinedExact role match. Skipped when falsy.

formatRoleLabel

@mdk/foundation

Convert a snake case role identifier to a human-readable Title Case label.

import { formatRoleLabel } from '@mdk/foundation'

formatRoleLabel('site_manager')           // "Site Manager"
formatRoleLabel('reporting_tool_manager') // "Reporting Tool Manager"
formatRoleLabel('admin')                  // "Admin"

formatLastActive

@mdk/foundation

Format a timestamp string as MM/DD/YYYY - HH:MM. Returns '-' when the input is missing or invalid.

import { formatLastActive } from '@mdk/foundation'

formatLastActive('2025-01-15T14:30:00Z')  // "01/15/2025 - 14:30"
formatLastActive(undefined)               // "-"
formatLastActive('not-a-date')            // "-"

validateSettingsJson

@mdk/foundation

Type-guard that checks whether an unknown value is a valid SettingsExportData. Returns true if the value is an object that contains at least one of headerControls, featureFlags, or timestamp.

import { validateSettingsJson } from '@mdk/foundation'

if (validateSettingsJson(parsed)) {
  // parsed is now narrowed to SettingsExportData
}

parseSettingsFile

@mdk/foundation

Read a File containing settings JSON, validate it, and resolve to SettingsExportData. Rejects on invalid JSON, an invalid format, or a file read error.

import { parseSettingsFile } from '@mdk/foundation'

try {
  const settings = await parseSettingsFile(file)
  applySettings(settings)
} catch (err) {
  notifyError('Could not import settings', err.message)
}
ThrowsReason
Invalid settings file format. Please ensure the file is a valid settings export.The JSON parsed but didn't match the SettingsExportData shape.
Failed to parse JSON file. Please ensure the file is valid JSON.The file contents weren't valid JSON.
Failed to read file.The browser couldn't read the file.

exportSettingsToFile

@mdk/foundation

Serialize SettingsExportData to JSON, package it as a downloadable Blob, and trigger a browser download. Returns the generated filename (e.g., miningos-settings-2025-01-15T14-30-00-000Z.json).

import { exportSettingsToFile } from '@mdk/foundation'

const filename = exportSettingsToFile({
  headerControls: { poolMiners: true, consumption: false },
  featureFlags: { betaCharts: true },
  timestamp: new Date().toISOString(),
  version: '1.0.0',
})

On this page