Core utilities and components for Apache Superset's frontend UI framework providing data visualization, formatting, and chart composition capabilities
—
This module provides the foundational infrastructure classes and utility functions that power the entire @superset-ui/core ecosystem. It includes the registry system for managing extensible collections, the plugin architecture, and essential utility functions for common operations.
The core models and utilities are designed around the principle of extensibility and type safety. The Registry system provides a flexible foundation for managing collections of items with support for lazy loading, while the Plugin and Preset classes enable modular architecture patterns.
The Registry system is the backbone of @superset-ui/core's extensible architecture, providing type-safe collections with support for synchronous values, asynchronous loaders, and change notifications.
Generic registry for storing and retrieving items by key with support for lazy loading:
import { Registry, OverwritePolicy } from '@superset-ui/core';
interface RegistryConfig {
name?: string;
overwritePolicy?: OverwritePolicy;
}
class Registry<V, W extends InclusiveLoaderResult<V> = InclusiveLoaderResult<V>> {
constructor(config?: RegistryConfig);
// Registration methods
registerValue(key: string, value: V): this;
registerLoader(key: string, loader: () => W): this;
// Retrieval methods
get(key: string): V | W | undefined;
getAsPromise(key: string): Promise<V>;
getMap(): { [key: string]: V | W | undefined };
getMapAsPromise(): Promise<{ [key: string]: V }>;
// Collection methods
has(key: string): boolean;
keys(): string[];
values(): RegistryValue<V, W>[];
valuesAsPromise(): Promise<V[]>;
entries(): RegistryEntry<V, W>[];
entriesAsPromise(): Promise<{ key: string; value: V }[]>;
// Management methods
clear(): this;
remove(key: string): this;
// Event handling
addListener(listener: (keys: Set<string>) => void): void;
removeListener(listener: (keys: Set<string>) => void): void;
// Properties
readonly name: string;
readonly overwritePolicy: OverwritePolicy;
}
type InclusiveLoaderResult<V> = V | Promise<V>;
type RegistryValue<V, W extends InclusiveLoaderResult<V>> = V | W | undefined;
interface RegistryEntry<V, W extends InclusiveLoaderResult<V>> {
key: string;
value: RegistryValue<V, W>;
}Enumeration defining how the registry handles key overwrites:
enum OverwritePolicy {
ALLOW = 'ALLOW', // Allow overwrites silently
PROHIBIT = 'PROHIBIT', // Throw error on overwrite
WARN = 'WARN' // Log warning on overwrite
}Extended registry that supports a default key for simplified retrieval:
import { RegistryWithDefaultKey } from '@superset-ui/core';
interface RegistryWithDefaultKeyConfig extends RegistryConfig {
initialDefaultKey?: string;
setFirstItemAsDefault?: boolean;
}
class RegistryWithDefaultKey<V, W extends InclusiveLoaderResult<V> = InclusiveLoaderResult<V>>
extends Registry<V, W> {
constructor(config?: RegistryWithDefaultKeyConfig);
// Override get to use default key when no key provided
get(key?: string): V | W | undefined;
// Default key management
getDefaultKey(): string | undefined;
setDefaultKey(key: string): this;
clearDefaultKey(): this;
// Properties
readonly initialDefaultKey?: string;
readonly setFirstItemAsDefault: boolean;
}import { Registry, OverwritePolicy } from '@superset-ui/core';
// Create a registry for string values
const messageRegistry = new Registry<string>({
name: 'messages',
overwritePolicy: OverwritePolicy.WARN
});
// Register values
messageRegistry.registerValue('greeting', 'Hello World');
messageRegistry.registerValue('farewell', 'Goodbye');
// Retrieve values
const greeting = messageRegistry.get('greeting'); // "Hello World"
const keys = messageRegistry.keys(); // ["greeting", "farewell"]// Registry with lazy-loaded components
const componentRegistry = new Registry<React.ComponentType>();
// Register a loader function
componentRegistry.registerLoader('MyChart', () =>
import('./charts/MyChart').then(module => module.default)
);
// Get component asynchronously
const MyChart = await componentRegistry.getAsPromise('MyChart');import { RegistryWithDefaultKey } from '@superset-ui/core';
const formatterRegistry = new RegistryWithDefaultKey<NumberFormatter>({
initialDefaultKey: 'default',
setFirstItemAsDefault: true
});
formatterRegistry.registerValue('percent', percentFormatter);
formatterRegistry.registerValue('currency', currencyFormatter);
// Get default formatter (first registered)
const defaultFormatter = formatterRegistry.get(); // percentFormatterThe Plugin and Preset classes provide the foundation for building modular, configurable applications.
Base class for creating extensible plugins with configurable options:
import { Plugin } from '@superset-ui/core';
interface PlainObject {
[key: string]: any;
}
class Plugin {
config: PlainObject;
constructor();
// Configuration methods
configure(config: PlainObject, replace?: boolean): this;
resetConfig(): this;
// Lifecycle methods
register(): this;
unregister(): this;
}Container for grouping and managing multiple presets and plugins:
import { Preset, Plugin } from '@superset-ui/core';
interface PresetConfig {
name?: string;
description?: string;
presets?: Preset[];
plugins?: Plugin[];
}
class Preset {
readonly name: string;
readonly description: string;
readonly presets: Preset[];
readonly plugins: Plugin[];
constructor(config?: PresetConfig);
// Register all nested presets and plugins
register(): this;
}Utility class that extends Function to enable creating extensible function objects:
import { ExtensibleFunction } from '@superset-ui/core';
class ExtensibleFunction {
constructor(fn: Function);
}import { Plugin } from '@superset-ui/core';
class ChartPlugin extends Plugin {
constructor(config: { chartType: string; metadata: any }) {
super();
this.configure(config);
}
register() {
// Register chart with global registry
getChartRegistry().registerValue(this.config.chartType, this);
return this;
}
}
// Usage
const barChartPlugin = new ChartPlugin({
chartType: 'bar',
metadata: { name: 'Bar Chart', description: 'Simple bar chart' }
});
barChartPlugin.register();import { Preset } from '@superset-ui/core';
const chartPreset = new Preset({
name: 'StandardCharts',
description: 'Standard chart collection',
plugins: [
new BarChartPlugin(),
new LineChartPlugin(),
new PieChartPlugin()
]
});
// Register all charts at once
chartPreset.register();Essential utility functions for common operations throughout the Superset ecosystem.
Functions for type checking and conversion:
import {
isDefined,
ensureIsArray,
ensureIsInt,
isEqualArray
} from '@superset-ui/core';
// Type guards and checks
function isDefined(value: unknown): boolean;
function isRequired(fieldName: string): never;
// Array utilities
function ensureIsArray<T>(value?: T[] | T | null): T[];
function isEqualArray<T extends unknown[] | undefined | null>(
arrA: T,
arrB: T
): boolean;
// Number conversion
function ensureIsInt<T>(value: T, defaultValue?: number): number;Functions for object manipulation and transformation:
import {
convertKeysToCamelCase,
removeDuplicates
} from '@superset-ui/core';
// Object key transformation
function convertKeysToCamelCase<T>(object: T): T;
// Array deduplication
function removeDuplicates<T>(
items: T[],
hash?: (item: T) => unknown
): T[];Functions for asynchronous operations and timing:
import { promiseTimeout, makeSingleton } from '@superset-ui/core';
// Promise-based setTimeout
function promiseTimeout<T>(
func: (...args: unknown[]) => T,
delay?: number
): Promise<T>;
// Singleton pattern helper
function makeSingleton<T, Args extends unknown[]>(
BaseClass: new (...args: Args) => T,
...args: Args
): () => T;Safe logging interface with console method fallbacks:
import { logging } from '@superset-ui/core';
interface Logger {
log: (...args: unknown[]) => void;
debug: (...args: unknown[]) => void;
info: (...args: unknown[]) => void;
warn: (...args: unknown[]) => void;
error: (...args: unknown[]) => void;
trace: (...args: unknown[]) => void;
table: (...args: unknown[]) => void;
}
const logging: Logger;Feature flag system for conditional functionality:
import { FeatureFlag, isFeatureEnabled } from '@superset-ui/core';
enum FeatureFlag {
ALLOW_DASHBOARD_DOMAIN_SHARDING = 'ALLOW_DASHBOARD_DOMAIN_SHARDING',
ALERT_REPORTS = 'ALERT_REPORTS',
OMNIBAR = 'OMNIBAR',
// ... 30+ additional flags
}
function isFeatureEnabled(feature: FeatureFlag): boolean;Seeded random number generation for consistent results:
import { seed, seedRandom } from '@superset-ui/core';
// Create seeded PRNG
function seed(seedValue: string): () => number;
// Pre-seeded random function
function seedRandom(): number;import {
Registry,
OverwritePolicy,
Plugin,
logging
} from '@superset-ui/core';
// Create formatter registry
const formatterRegistry = new Registry<NumberFormatter>({
name: 'NumberFormatters',
overwritePolicy: OverwritePolicy.WARN
});
// Add change listener
formatterRegistry.addListener((changedKeys) => {
logging.info('Formatters updated:', Array.from(changedKeys));
});
// Register formatters
formatterRegistry.registerValue('percent', new PercentFormatter());
formatterRegistry.registerLoader('currency', () =>
import('./formatters/CurrencyFormatter').then(m => new m.default())
);import { Plugin, Registry, isFeatureEnabled, FeatureFlag } from '@superset-ui/core';
class CustomVisualizationPlugin extends Plugin {
constructor(config: { name: string; component: React.ComponentType }) {
super();
this.configure(config);
}
register() {
if (!isFeatureEnabled(FeatureFlag.CUSTOM_VISUALIZATIONS)) {
return this;
}
// Register with visualization registry
getVisualizationRegistry().registerValue(
this.config.name,
this.config.component
);
return this;
}
}Install with Tessl CLI
npx tessl i tessl/npm-superset-ui--core