or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-models.mddashboard.mddata-connection.mddata-formatting.mdindex.mdplugin-system.mdtranslation.mdui-styling.mdvalidation-math.md

core-models.mddocs/

0

# Core Models & Utilities

1

2

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.

3

4

## Overview

5

6

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.

7

8

## Registry System

9

10

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.

11

12

### Registry { .api }

13

14

Generic registry for storing and retrieving items by key with support for lazy loading:

15

16

```typescript

17

import { Registry, OverwritePolicy } from '@superset-ui/core';

18

19

interface RegistryConfig {

20

name?: string;

21

overwritePolicy?: OverwritePolicy;

22

}

23

24

class Registry<V, W extends InclusiveLoaderResult<V> = InclusiveLoaderResult<V>> {

25

constructor(config?: RegistryConfig);

26

27

// Registration methods

28

registerValue(key: string, value: V): this;

29

registerLoader(key: string, loader: () => W): this;

30

31

// Retrieval methods

32

get(key: string): V | W | undefined;

33

getAsPromise(key: string): Promise<V>;

34

getMap(): { [key: string]: V | W | undefined };

35

getMapAsPromise(): Promise<{ [key: string]: V }>;

36

37

// Collection methods

38

has(key: string): boolean;

39

keys(): string[];

40

values(): RegistryValue<V, W>[];

41

valuesAsPromise(): Promise<V[]>;

42

entries(): RegistryEntry<V, W>[];

43

entriesAsPromise(): Promise<{ key: string; value: V }[]>;

44

45

// Management methods

46

clear(): this;

47

remove(key: string): this;

48

49

// Event handling

50

addListener(listener: (keys: Set<string>) => void): void;

51

removeListener(listener: (keys: Set<string>) => void): void;

52

53

// Properties

54

readonly name: string;

55

readonly overwritePolicy: OverwritePolicy;

56

}

57

58

type InclusiveLoaderResult<V> = V | Promise<V>;

59

60

type RegistryValue<V, W extends InclusiveLoaderResult<V>> = V | W | undefined;

61

62

interface RegistryEntry<V, W extends InclusiveLoaderResult<V>> {

63

key: string;

64

value: RegistryValue<V, W>;

65

}

66

```

67

68

#### OverwritePolicy { .api }

69

70

Enumeration defining how the registry handles key overwrites:

71

72

```typescript

73

enum OverwritePolicy {

74

ALLOW = 'ALLOW', // Allow overwrites silently

75

PROHIBIT = 'PROHIBIT', // Throw error on overwrite

76

WARN = 'WARN' // Log warning on overwrite

77

}

78

```

79

80

### RegistryWithDefaultKey { .api }

81

82

Extended registry that supports a default key for simplified retrieval:

83

84

```typescript

85

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

86

87

interface RegistryWithDefaultKeyConfig extends RegistryConfig {

88

initialDefaultKey?: string;

89

setFirstItemAsDefault?: boolean;

90

}

91

92

class RegistryWithDefaultKey<V, W extends InclusiveLoaderResult<V> = InclusiveLoaderResult<V>>

93

extends Registry<V, W> {

94

95

constructor(config?: RegistryWithDefaultKeyConfig);

96

97

// Override get to use default key when no key provided

98

get(key?: string): V | W | undefined;

99

100

// Default key management

101

getDefaultKey(): string | undefined;

102

setDefaultKey(key: string): this;

103

clearDefaultKey(): this;

104

105

// Properties

106

readonly initialDefaultKey?: string;

107

readonly setFirstItemAsDefault: boolean;

108

}

109

```

110

111

### Usage Examples

112

113

#### Basic Registry Usage

114

115

```typescript

116

import { Registry, OverwritePolicy } from '@superset-ui/core';

117

118

// Create a registry for string values

119

const messageRegistry = new Registry<string>({

120

name: 'messages',

121

overwritePolicy: OverwritePolicy.WARN

122

});

123

124

// Register values

125

messageRegistry.registerValue('greeting', 'Hello World');

126

messageRegistry.registerValue('farewell', 'Goodbye');

127

128

// Retrieve values

129

const greeting = messageRegistry.get('greeting'); // "Hello World"

130

const keys = messageRegistry.keys(); // ["greeting", "farewell"]

131

```

132

133

#### Lazy Loading with Loaders

134

135

```typescript

136

// Registry with lazy-loaded components

137

const componentRegistry = new Registry<React.ComponentType>();

138

139

// Register a loader function

140

componentRegistry.registerLoader('MyChart', () =>

141

import('./charts/MyChart').then(module => module.default)

142

);

143

144

// Get component asynchronously

145

const MyChart = await componentRegistry.getAsPromise('MyChart');

146

```

147

148

#### Registry with Default Key

149

150

```typescript

151

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

152

153

const formatterRegistry = new RegistryWithDefaultKey<NumberFormatter>({

154

initialDefaultKey: 'default',

155

setFirstItemAsDefault: true

156

});

157

158

formatterRegistry.registerValue('percent', percentFormatter);

159

formatterRegistry.registerValue('currency', currencyFormatter);

160

161

// Get default formatter (first registered)

162

const defaultFormatter = formatterRegistry.get(); // percentFormatter

163

```

164

165

## Plugin Architecture

166

167

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

168

169

### Plugin { .api }

170

171

Base class for creating extensible plugins with configurable options:

172

173

```typescript

174

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

175

176

interface PlainObject {

177

[key: string]: any;

178

}

179

180

class Plugin {

181

config: PlainObject;

182

183

constructor();

184

185

// Configuration methods

186

configure(config: PlainObject, replace?: boolean): this;

187

resetConfig(): this;

188

189

// Lifecycle methods

190

register(): this;

191

unregister(): this;

192

}

193

```

194

195

### Preset { .api }

196

197

Container for grouping and managing multiple presets and plugins:

198

199

```typescript

200

import { Preset, Plugin } from '@superset-ui/core';

201

202

interface PresetConfig {

203

name?: string;

204

description?: string;

205

presets?: Preset[];

206

plugins?: Plugin[];

207

}

208

209

class Preset {

210

readonly name: string;

211

readonly description: string;

212

readonly presets: Preset[];

213

readonly plugins: Plugin[];

214

215

constructor(config?: PresetConfig);

216

217

// Register all nested presets and plugins

218

register(): this;

219

}

220

```

221

222

### ExtensibleFunction { .api }

223

224

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

225

226

```typescript

227

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

228

229

class ExtensibleFunction {

230

constructor(fn: Function);

231

}

232

```

233

234

### Usage Examples

235

236

#### Creating Custom Plugins

237

238

```typescript

239

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

240

241

class ChartPlugin extends Plugin {

242

constructor(config: { chartType: string; metadata: any }) {

243

super();

244

this.configure(config);

245

}

246

247

register() {

248

// Register chart with global registry

249

getChartRegistry().registerValue(this.config.chartType, this);

250

return this;

251

}

252

}

253

254

// Usage

255

const barChartPlugin = new ChartPlugin({

256

chartType: 'bar',

257

metadata: { name: 'Bar Chart', description: 'Simple bar chart' }

258

});

259

260

barChartPlugin.register();

261

```

262

263

#### Organizing with Presets

264

265

```typescript

266

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

267

268

const chartPreset = new Preset({

269

name: 'StandardCharts',

270

description: 'Standard chart collection',

271

plugins: [

272

new BarChartPlugin(),

273

new LineChartPlugin(),

274

new PieChartPlugin()

275

]

276

});

277

278

// Register all charts at once

279

chartPreset.register();

280

```

281

282

## Utility Functions

283

284

Essential utility functions for common operations throughout the Superset ecosystem.

285

286

### Type Utilities { .api }

287

288

Functions for type checking and conversion:

289

290

```typescript

291

import {

292

isDefined,

293

ensureIsArray,

294

ensureIsInt,

295

isEqualArray

296

} from '@superset-ui/core';

297

298

// Type guards and checks

299

function isDefined(value: unknown): boolean;

300

function isRequired(fieldName: string): never;

301

302

// Array utilities

303

function ensureIsArray<T>(value?: T[] | T | null): T[];

304

function isEqualArray<T extends unknown[] | undefined | null>(

305

arrA: T,

306

arrB: T

307

): boolean;

308

309

// Number conversion

310

function ensureIsInt<T>(value: T, defaultValue?: number): number;

311

```

312

313

### Object Utilities { .api }

314

315

Functions for object manipulation and transformation:

316

317

```typescript

318

import {

319

convertKeysToCamelCase,

320

removeDuplicates

321

} from '@superset-ui/core';

322

323

// Object key transformation

324

function convertKeysToCamelCase<T>(object: T): T;

325

326

// Array deduplication

327

function removeDuplicates<T>(

328

items: T[],

329

hash?: (item: T) => unknown

330

): T[];

331

```

332

333

### Async Utilities { .api }

334

335

Functions for asynchronous operations and timing:

336

337

```typescript

338

import { promiseTimeout, makeSingleton } from '@superset-ui/core';

339

340

// Promise-based setTimeout

341

function promiseTimeout<T>(

342

func: (...args: unknown[]) => T,

343

delay?: number

344

): Promise<T>;

345

346

// Singleton pattern helper

347

function makeSingleton<T, Args extends unknown[]>(

348

BaseClass: new (...args: Args) => T,

349

...args: Args

350

): () => T;

351

```

352

353

### Logging Utilities { .api }

354

355

Safe logging interface with console method fallbacks:

356

357

```typescript

358

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

359

360

interface Logger {

361

log: (...args: unknown[]) => void;

362

debug: (...args: unknown[]) => void;

363

info: (...args: unknown[]) => void;

364

warn: (...args: unknown[]) => void;

365

error: (...args: unknown[]) => void;

366

trace: (...args: unknown[]) => void;

367

table: (...args: unknown[]) => void;

368

}

369

370

const logging: Logger;

371

```

372

373

### Feature Flags { .api }

374

375

Feature flag system for conditional functionality:

376

377

```typescript

378

import { FeatureFlag, isFeatureEnabled } from '@superset-ui/core';

379

380

enum FeatureFlag {

381

ALLOW_DASHBOARD_DOMAIN_SHARDING = 'ALLOW_DASHBOARD_DOMAIN_SHARDING',

382

ALERT_REPORTS = 'ALERT_REPORTS',

383

OMNIBAR = 'OMNIBAR',

384

// ... 30+ additional flags

385

}

386

387

function isFeatureEnabled(feature: FeatureFlag): boolean;

388

```

389

390

### Random Number Generation { .api }

391

392

Seeded random number generation for consistent results:

393

394

```typescript

395

import { seed, seedRandom } from '@superset-ui/core';

396

397

// Create seeded PRNG

398

function seed(seedValue: string): () => number;

399

400

// Pre-seeded random function

401

function seedRandom(): number;

402

```

403

404

## Usage Examples

405

406

### Complete Registry Setup

407

408

```typescript

409

import {

410

Registry,

411

OverwritePolicy,

412

Plugin,

413

logging

414

} from '@superset-ui/core';

415

416

// Create formatter registry

417

const formatterRegistry = new Registry<NumberFormatter>({

418

name: 'NumberFormatters',

419

overwritePolicy: OverwritePolicy.WARN

420

});

421

422

// Add change listener

423

formatterRegistry.addListener((changedKeys) => {

424

logging.info('Formatters updated:', Array.from(changedKeys));

425

});

426

427

// Register formatters

428

formatterRegistry.registerValue('percent', new PercentFormatter());

429

formatterRegistry.registerLoader('currency', () =>

430

import('./formatters/CurrencyFormatter').then(m => new m.default())

431

);

432

```

433

434

### Plugin Development Pattern

435

436

```typescript

437

import { Plugin, Registry, isFeatureEnabled, FeatureFlag } from '@superset-ui/core';

438

439

class CustomVisualizationPlugin extends Plugin {

440

constructor(config: { name: string; component: React.ComponentType }) {

441

super();

442

this.configure(config);

443

}

444

445

register() {

446

if (!isFeatureEnabled(FeatureFlag.CUSTOM_VISUALIZATIONS)) {

447

return this;

448

}

449

450

// Register with visualization registry

451

getVisualizationRegistry().registerValue(

452

this.config.name,

453

this.config.component

454

);

455

456

return this;

457

}

458

}

459

```

460

461

## Related Documentation

462

463

- [Plugin System](./plugin-system.md) - Chart plugins and dynamic loading

464

- [Data Formatting](./data-formatting.md) - Formatter registries and usage

465

- [UI & Styling](./ui-styling.md) - Theme system architecture