CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-superset-ui--core

Core utilities and components for Apache Superset's frontend UI framework providing data visualization, formatting, and chart composition capabilities

Pending
Overview
Eval results
Files

core-models.mddocs/

Core Models & Utilities

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.

Overview

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.

Registry System

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.

Registry { .api }

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>;
}

OverwritePolicy { .api }

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
}

RegistryWithDefaultKey { .api }

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;
}

Usage Examples

Basic Registry Usage

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"]

Lazy Loading with Loaders

// 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');

Registry with Default Key

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(); // percentFormatter

Plugin Architecture

The Plugin and Preset classes provide the foundation for building modular, configurable applications.

Plugin { .api }

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;
}

Preset { .api }

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;
}

ExtensibleFunction { .api }

Utility class that extends Function to enable creating extensible function objects:

import { ExtensibleFunction } from '@superset-ui/core';

class ExtensibleFunction {
  constructor(fn: Function);
}

Usage Examples

Creating Custom Plugins

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();

Organizing with Presets

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();

Utility Functions

Essential utility functions for common operations throughout the Superset ecosystem.

Type Utilities { .api }

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;

Object Utilities { .api }

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[];

Async Utilities { .api }

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;

Logging Utilities { .api }

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 Flags { .api }

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;

Random Number Generation { .api }

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;

Usage Examples

Complete Registry Setup

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())
);

Plugin Development Pattern

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;
  }
}

Related Documentation

  • Plugin System - Chart plugins and dynamic loading
  • Data Formatting - Formatter registries and usage
  • UI & Styling - Theme system architecture

Install with Tessl CLI

npx tessl i tessl/npm-superset-ui--core

docs

core-models.md

dashboard.md

data-connection.md

data-formatting.md

index.md

plugin-system.md

translation.md

ui-styling.md

validation-math.md

tile.json