or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

application-management.mdattribute-management.mdcontrollers.mdcoordinate-systems.mdeffects-and-lighting.mdindex.mdlayer-system.mdtransitions-and-animation.mdutilities-and-helpers.mdviews-and-viewports.md
tile.json

utilities-and-helpers.mddocs/

Utilities and Helpers

Essential utility functions for data processing, mathematical operations, development support, and performance optimization in deck.gl applications.

Capabilities

Data Processing Utilities

createIterable

Create iterables from various data sources for efficient data processing.

/**
 * Create iterable from various data sources
 * Handles arrays, array-like objects, and iterables uniformly
 * @param data - Data source to make iterable
 * @param objectInfo - Additional metadata about objects
 * @returns Iterable that can be used in for...of loops
 */
function createIterable<T>(data: any, objectInfo?: any): Iterable<T>;

Usage Examples:

import { createIterable } from "@deck.gl/core";

// Works with arrays
const arrayData = [1, 2, 3, 4, 5];
for (const item of createIterable(arrayData)) {
  console.log(item);
}

// Works with array-like objects
const arrayLike = {0: 'a', 1: 'b', 2: 'c', length: 3};
for (const item of createIterable(arrayLike)) {
  console.log(item);
}

// Works with typed arrays
const typedArray = new Float32Array([1.1, 2.2, 3.3]);
for (const item of createIterable(typedArray)) {
  console.log(item);
}

// Custom data source with metadata
const customIterable = createIterable(data, {
  geometrySize: 3,
  hasTimestamp: true
});

Mathematical Utilities

fp64LowPart

Extract low part of 64-bit floating point for high-precision shader calculations.

/**
 * Extract low part of 64-bit floating point number
 * Used for high-precision calculations in WebGL shaders
 * @param x - Input number
 * @returns Low 32-bit part for shader precision
 */
function fp64LowPart(x: number): number;

Usage Examples:

import { fp64LowPart } from "@deck.gl/core";

// High-precision coordinate handling
const processHighPrecisionCoords = (coordinates) => {
  return coordinates.map(coord => ({
    high: coord,
    low: fp64LowPart(coord)
  }));
};

// Custom layer with high-precision positions
class HighPrecisionLayer extends Layer {
  initializeState() {
    this.getAttributeManager().add({
      positions: {
        size: 3,
        accessor: 'getPosition'
      },
      positions64Low: {
        size: 3,
        accessor: 'getPosition',
        transform: (position) => position.map(fp64LowPart)
      }
    });
  }
}

Geometry Processing

Tesselator

Polygon tessellation for complex geometries and GPU rendering.

/**
 * Polygon tessellation utility
 * Converts complex polygons into triangles for GPU rendering
 */
class Tesselator {
  /** Initialize tesselator with options */
  constructor(opts?: TesselatorOptions);
  
  /** Tessellate polygon data into triangles */
  tesselate(opts: TesselateOptions): TesselationResult;
  
  /** Get tessellation statistics */
  getStats(): TesselationStats;
}

interface TesselatorOptions {
  /** Winding order for triangles */
  windingOrder?: 'CW' | 'CCW';
  
  /** Whether to generate vertex normals */
  generateNormals?: boolean;
  
  /** Tolerance for tessellation */
  tolerance?: number;
  
  /** Whether to optimize output */
  optimize?: boolean;
}

interface TesselateOptions {
  /** Polygon data to tessellate */
  data: any[];
  
  /** Accessor for polygon coordinates */
  getPolygon: (d: any) => number[][] | number[][][];
  
  /** Accessor for polygon holes */
  getHoles?: (d: any) => number[][][];
  
  /** Number of dimensions (2 or 3) */
  dimensions?: number;
  
  /** Position format */
  positionFormat?: 'XY' | 'XYZ';
  
  /** Whether to normalize coordinates */
  normalize?: boolean;
}

interface TesselationResult {
  /** Tessellated vertex positions */
  positions: Float32Array;
  
  /** Triangle indices */
  indices: Uint32Array;
  
  /** Vertex normals (if generated) */
  normals?: Float32Array;
  
  /** Number of vertices */
  vertexCount: number;
  
  /** Number of triangles */
  triangleCount: number;
  
  /** Metadata for each polygon */
  polygonMetadata: PolygonMetadata[];
}

interface PolygonMetadata {
  /** Start index in vertex array */
  startIndex: number;
  
  /** Number of vertices for this polygon */
  vertexCount: number;
  
  /** Original polygon index */
  polygonIndex: number;
}

interface TesselationStats {
  /** Total polygons processed */
  polygonCount: number;
  
  /** Total vertices generated */
  vertexCount: number;
  
  /** Total triangles generated */
  triangleCount: number;
  
  /** Processing time in milliseconds */
  processingTime: number;
}

Usage Examples:

import { Tesselator } from "@deck.gl/core";

// Create tesselator for complex polygons
const tesselator = new Tesselator({
  windingOrder: 'CCW',
  generateNormals: true,
  tolerance: 1e-6
});

// Tessellate building footprints
const buildingData = [
  {
    id: 1,
    coordinates: [[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]],
    holes: [[[2, 2], [8, 2], [8, 8], [2, 8], [2, 2]]]
  }
];

const tessellationResult = tesselator.tesselate({
  data: buildingData,
  getPolygon: d => d.coordinates,
  getHoles: d => d.holes,
  dimensions: 2,
  positionFormat: 'XY'
});

console.log(`Generated ${tessellationResult.triangleCount} triangles`);

// Use tessellated data in custom layer
class TessellatedPolygonLayer extends Layer {
  initializeState() {
    const {gl} = this.context;
    
    const tessellationResult = tesselator.tesselate({
      data: this.props.data,
      getPolygon: this.props.getPolygon
    });
    
    this.setState({
      model: new Model(gl, {
        vs: vertexShader,
        fs: fragmentShader,
        geometry: new Geometry({
          attributes: {
            positions: tessellationResult.positions,
            normals: tessellationResult.normals
          },
          indices: tessellationResult.indices
        })
      })
    });
  }
}

Logging and Debugging

log

Comprehensive logging system with levels and conditional logging.

/**
 * Logging utility with multiple levels
 * Provides conditional logging and performance tracking
 */
const log: {
  /** Log info message */
  info: (message: string, ...args: any[]) => void;
  
  /** Log warning message */
  warn: (message: string, ...args: any[]) => void;
  
  /** Log error message */
  error: (message: string, ...args: any[]) => void;
  
  /** Log debug message (only in development) */
  debug: (message: string, ...args: any[]) => void;
  
  /** Create deprecated function warning */
  deprecated: (oldUsage: string, newUsage: string) => () => void;
  
  /** Time a code block */
  time: (id: string) => void;
  
  /** End timing and log result */
  timeEnd: (id: string) => void;
  
  /** Create performance probe */
  probe: (id: string, message: string) => {
    start: () => void;
    end: () => void;
  };
  
  /** Set logging level */
  level: number;
  
  /** Enable/disable specific log types */
  enable: (types: string[]) => void;
  
  /** Disable specific log types */
  disable: (types: string[]) => void;
};

// Log levels
const LOG_LEVELS = {
  ERROR: 0,
  WARN: 1,
  INFO: 2,
  DEBUG: 3
};

Usage Examples:

import { log } from "@deck.gl/core";

// Basic logging
log.info('Layer initialized successfully');
log.warn('Large dataset detected, performance may be affected');
log.error('Failed to load data:', error);

// Performance timing
log.time('data-processing');
processLargeDataset(data);
log.timeEnd('data-processing');

// Performance probes
const renderProbe = log.probe('layer-render', 'Rendering layer');
renderProbe.start();
layer.draw();
renderProbe.end();

// Deprecation warnings
const deprecatedFunction = log.deprecated('oldFunction()', 'newFunction()');
const myOldFunction = () => {
  deprecatedFunction();
  // Function implementation
};

// Conditional logging based on environment
if (process.env.NODE_ENV === 'development') {
  log.level = LOG_LEVELS.DEBUG;
  log.debug('Debug information:', debugData);
} else {
  log.level = LOG_LEVELS.WARN;
}

assert

Development-time assertion utility for validation.

/**
 * Assertion utility for development-time validation
 * Throws error if condition is false (only in development builds)
 * @param condition - Condition to test
 * @param message - Error message if assertion fails
 */
function assert(condition: any, message?: string): asserts condition;

Usage Examples:

import { assert } from "@deck.gl/core";

// Parameter validation
const validateLayerProps = (props) => {
  assert(props.data, 'Layer data is required');
  assert(Array.isArray(props.data) || props.data.length !== undefined, 
         'Layer data must be array-like');
  assert(typeof props.getPosition === 'function', 
         'getPosition accessor must be a function');
};

// Range validation
const validateCoordinates = (coords) => {
  assert(coords.length >= 2, 'Coordinates must have at least 2 elements');
  assert(coords[0] >= -180 && coords[0] <= 180, 'Longitude out of range');
  assert(coords[1] >= -90 && coords[1] <= 90, 'Latitude out of range');
};

// Custom layer with assertions
class ValidatedLayer extends Layer {
  updateState({props, oldProps}) {
    assert(props.data, 'Data is required');
    assert(props.data !== oldProps.data || 
           JSON.stringify(props.updateTriggers) !== JSON.stringify(oldProps.updateTriggers),
           'Props or update triggers must change to trigger update');
    
    super.updateState({props, oldProps});
  }
}

Experimental Utilities

Array Manipulation

/**
 * Fill array with values efficiently
 * @param array - Target array to fill
 * @param value - Value or function to fill with
 * @param start - Start index
 * @param end - End index
 */
function _fillArray(
  array: any[], 
  value: any | ((index: number) => any),
  start?: number, 
  end?: number
): any[];

/**
 * Flatten nested arrays
 * @param array - Array to flatten
 * @param depth - Depth to flatten (default: 1)
 * @param filter - Optional filter function
 */
function _flatten<T>(
  array: any[], 
  depth?: number,
  filter?: (item: any) => boolean
): T[];

Data Analysis

/**
 * Count data instances efficiently
 * @param data - Data to count
 * @param accessor - Optional accessor function
 */
function _count(data: any, accessor?: (item: any) => boolean): number;

/**
 * Deep equality comparison
 * @param a - First object to compare
 * @param b - Second object to compare
 * @param depth - Maximum depth to compare
 */
function _deepEqual(a: any, b: any, depth?: number): boolean;

Performance Optimization

/**
 * Memoize expensive function calls
 * @param fn - Function to memoize
 * @param getKey - Key generation function
 */
function _memoize<T extends (...args: any[]) => any>(
  fn: T,
  getKey?: (...args: Parameters<T>) => string
): T;

/**
 * Merge shader code efficiently
 * @param shaders - Array of shader objects to merge
 */
function _mergeShaders(shaders: any[]): any;

/**
 * Compare props efficiently for updates
 * @param newProps - New properties
 * @param oldProps - Old properties  
 * @param compareKeys - Keys to compare
 */
function _compareProps(
  newProps: any,
  oldProps: any,
  compareKeys?: string[]
): boolean;

DOM Utilities

/**
 * Apply CSS styles to DOM element
 * @param element - Target DOM element
 * @param styles - Styles to apply
 */
function _applyStyles(
  element: HTMLElement,
  styles: Partial<CSSStyleDeclaration>
): void;

/**
 * Remove CSS styles from DOM element
 * @param element - Target DOM element
 * @param styleNames - Style names to remove
 */
function _removeStyles(
  element: HTMLElement,
  styleNames: string[]
): void;

Usage Examples:

import { 
  _fillArray, 
  _flatten, 
  _count, 
  _deepEqual, 
  _memoize,
  _compareProps
} from "@deck.gl/core";

// Efficient array operations
const positions = new Float32Array(1000 * 3);
_fillArray(positions, (i) => Math.random() * 100, 0, positions.length);

// Flatten nested coordinate arrays
const nestedCoords = [[[1, 2]], [[3, 4]], [[5, 6]]];
const flatCoords = _flatten(nestedCoords, 2); // [1, 2, 3, 4, 5, 6]

// Count filtered data
const validCount = _count(data, item => item.valid === true);

// Deep comparison for prop changes
const hasChanged = !_deepEqual(newProps, oldProps, 3);

// Memoize expensive calculations
const expensiveCalculation = _memoize((data, options) => {
  // Complex calculation
  return processData(data, options);
}, (data, options) => `${data.id}-${JSON.stringify(options)}`);

// Efficient prop comparison in layers
class OptimizedLayer extends Layer {
  shouldUpdateState({props, oldProps, changeFlags}) {
    return changeFlags.somethingChanged || 
           !_compareProps(props, oldProps, ['data', 'getPosition', 'getColor']);
  }
}

// DOM styling utilities
import { _applyStyles, _removeStyles } from "@deck.gl/core";

const canvas = deck.getCanvas();
_applyStyles(canvas, {
  cursor: 'pointer',
  borderRadius: '8px',
  boxShadow: '0 4px 8px rgba(0,0,0,0.1)'
});

// Remove styles when done
_removeStyles(canvas, ['cursor', 'borderRadius', 'boxShadow']);

Version Information

VERSION

Package version constant for compatibility checking.

/**
 * Current package version string
 * Used for compatibility checking and debugging
 */
const VERSION: string;

Usage Examples:

import { VERSION } from "@deck.gl/core";

console.log(`Using @deck.gl/core version ${VERSION}`);

// Version compatibility checking
const checkCompatibility = (requiredVersion) => {
  const [major, minor, patch] = VERSION.split('.').map(n => parseInt(n));
  const [reqMajor, reqMinor, reqPatch] = requiredVersion.split('.').map(n => parseInt(n));
  
  if (major > reqMajor) return true;
  if (major === reqMajor && minor > reqMinor) return true;
  if (major === reqMajor && minor === reqMinor && patch >= reqPatch) return true;
  
  return false;
};

if (!checkCompatibility('9.0.0')) {
  console.warn('This application requires @deck.gl/core version 9.0.0 or higher');
}

Performance Utilities

Typed Array Management

Efficient memory management for large datasets.

interface TypedArrayManager {
  /** Allocate typed array */
  allocate(size: number, type: string): TypedArray;
  
  /** Release typed array back to pool */
  release(array: TypedArray): void;
  
  /** Get memory usage statistics */
  getStats(): {
    totalAllocated: number;
    totalReleased: number;
    currentUsage: number;
    poolSize: number;
  };
}

interface TypedArrayManagerOptions {
  /** Pool size for array reuse */
  poolSize?: number;
  
  /** Enable memory tracking */
  trackMemory?: boolean;
  
  /** Maximum total memory usage */
  maxMemory?: number;
}

Usage Examples:

// Efficient memory management for large datasets
const createOptimizedLayer = (data) => {
  const typedArrayManager = new TypedArrayManager({
    poolSize: 100,
    trackMemory: true,
    maxMemory: 1024 * 1024 * 512 // 512MB limit
  });
  
  return new ScatterplotLayer({
    id: 'optimized-points',
    data: data,
    getPosition: d => d.coordinates,
    
    // Custom attribute update with memory pooling
    updateAttributes: ({props, oldProps}) => {
      if (props.data !== oldProps.data) {
        const positions = typedArrayManager.allocate(
          props.data.length * 3, 
          'Float32Array'
        );
        
        // Fill positions array
        props.data.forEach((d, i) => {
          const pos = d.coordinates;
          positions[i * 3] = pos[0];
          positions[i * 3 + 1] = pos[1];
          positions[i * 3 + 2] = pos[2] || 0;
        });
        
        return {positions};
      }
    }
  });
};