or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

data-binding.mdelement-creation.mdgesture-system.mdindex.mdlegacy-support.mdmixins.mdproperty-system.mdutilities.md
tile.json

utilities.mddocs/

Utility Functions

Helper functions for common operations including path manipulation, async operations, debouncing, gesture handling, and DOM utilities.

Capabilities

Path Utilities

Functions for working with property paths in data binding and observation.

/**
 * Get value at a property path on an object
 */
function get(object: any, path: string): any;

/**
 * Set value at a property path on an object
 */
function set(object: any, path: string, value: any): void;

/**
 * Check if a string represents a property path
 */
function isPath(path: string): boolean;

/**
 * Get root property name from a path
 */
function root(path: string): string;

/**
 * Check if a path is an ancestor of another path
 */
function isAncestor(base: string, path: string): boolean;

/**
 * Check if a path is a descendant of another path
 */
function isDescendant(base: string, path: string): boolean;

/**
 * Translate a path relative to another path
 */
function translate(base: string, newBase: string, path: string): string;

/**
 * Check if a path matches a pattern (supports wildcards)
 */
function matches(base: string, path: string): boolean;

/**
 * Normalize a property path
 */
function normalize(path: string): string;

/**
 * Split property path into array of path parts
 */
function split(path: string): string[];

Usage Examples:

import { get, set, isPath } from '@polymer/polymer/lib/utils/path.js';

const obj = {
  user: {
    profile: {
      name: 'Alice',
      settings: {
        theme: 'dark'
      }
    },
    posts: [
      { title: 'First Post', likes: 5 },
      { title: 'Second Post', likes: 10 }
    ]
  }
};

// Get values using paths
console.log(get(obj, 'user.profile.name')); // 'Alice'
console.log(get(obj, 'user.posts.0.title')); // 'First Post'

// Set values using paths
set(obj, 'user.profile.name', 'Bob');
set(obj, 'user.posts.1.likes', 15);

// Check if string is a path
console.log(isPath('user.name')); // true
console.log(isPath('simple')); // false

// Path manipulation
import { root, isAncestor, translate } from '@polymer/polymer/lib/utils/path.js';

console.log(root('user.profile.name')); // 'user'
console.log(isAncestor('user', 'user.profile.name')); // true
console.log(translate('old.path', 'new.path', 'old.path.prop')); // 'new.path.prop'

Async Utilities

Async interfaces for different timing mechanisms.

/**
 * Async interface for timeout-based operations
 */
interface AsyncInterface {
  /** Run function after delay */
  run(fn: () => void, delay?: number): number;
  
  /** Cancel scheduled function */
  cancel(handle: number): void;
}

/**
 * Timeout-based async interface
 */
const timeOut: AsyncInterface;

/**
 * Animation frame-based async interface
 */
const animationFrame: AsyncInterface;

/**
 * Idle period-based async interface
 */
const idlePeriod: AsyncInterface;

/**
 * Microtask-based async interface
 */
const microTask: AsyncInterface;

Usage Examples:

import { timeOut, animationFrame, microTask } from '@polymer/polymer/lib/utils/async.js';

// Timeout-based async
const timeoutHandle = timeOut.run(() => {
  console.log('Executed after 1000ms');
}, 1000);

// Cancel if needed
timeOut.cancel(timeoutHandle);

// Animation frame timing
const animationHandle = animationFrame.run(() => {
  console.log('Executed on next animation frame');
});

// Microtask timing
const microtaskHandle = microTask.run(() => {
  console.log('Executed on next microtask');
});

Debouncing

Debouncing utility for batching rapid function calls.

/**
 * Debouncer class for batching function calls
 */
class Debouncer {
  /** Create debouncer with async interface */
  constructor(asyncModule: AsyncInterface);
  
  /** Debounce a function call */
  debounce(fn: () => void): void;
  
  /** Cancel pending debounced call */
  cancel(): void;
  
  /** Immediately flush pending call */
  flush(): void;
  
  /** Check if debouncer is active */
  isActive(): boolean;
}

/**
 * Enqueue debouncer for automatic flushing
 */
function enqueueDebouncer(debouncer: Debouncer): void;

/**
 * Flush all enqueued debouncers
 */
function flushDebouncers(): void;

Usage Examples:

import { Debouncer, enqueueDebouncer, flushDebouncers } from '@polymer/polymer/lib/utils/debounce.js';
import { timeOut } from '@polymer/polymer/lib/utils/async.js';

class MyElement extends PolymerElement {
  constructor() {
    super();
    this._debouncer = null;
  }
  
  _debouncedMethod() {
    this._debouncer = Debouncer.debounce(
      this._debouncer,
      timeOut.after(100),
      () => {
        console.log('Debounced execution');
        this._actualWork();
      }
    );
    enqueueDebouncer(this._debouncer);
  }
  
  _actualWork() {
    // Heavy work that should be debounced
    console.log('Doing expensive operation');
  }
  
  // Call multiple times rapidly - only executes once
  rapidCalls() {
    this._debouncedMethod();
    this._debouncedMethod();
    this._debouncedMethod(); // Only the last call will execute after delay
  }
}

Flush Utilities

Functions for flushing pending operations.

/**
 * Flush all pending Polymer operations
 */
function flush(): void;

Usage Examples:

import { flush } from '@polymer/polymer/lib/utils/flush.js';

// Force all pending property changes and template updates
flush();

// Useful in tests to ensure synchronous updates
element.someProperty = 'new value';
flush(); // Ensures all bindings are updated immediately

Gesture System

Cross-platform gesture recognition and event handling.

/**
 * Gesture recognizer registry
 */
interface GestureRecognizer {
  name: string;
  deps: string[];
  flow: {
    start: (e: Event, state: any) => void;
    move: (e: Event, state: any) => void;
    end: (e: Event, state: any) => void;
  };
  emits: string[];
}

/**
 * Gesture system interface
 */
interface Gestures {
  /** Array of registered recognizers */
  recognizers: GestureRecognizer[];
  
  /** Add gesture event listener */
  addListener(node: Node, evType: string, handler: (e: Event) => void): void;
  
  /** Remove gesture event listener */
  removeListener(node: Node, evType: string, handler: (e: Event) => void): void;
  
  /** Register gesture recognizer */
  register(recog: GestureRecognizer): void;
  
  /** Find deepest element at coordinates */
  deepTargetFind(x: number, y: number): Element;
  
  /** Set touch-action CSS property */
  setTouchAction(node: Node, value: string): void;
  
  /** Prevent gesture default behavior */
  prevent(evName: string): void;
  
  /** Reset mouse event cancellation */
  resetMouseCanceller(): void;
}

/**
 * Main gestures object
 */
const gestures: Gestures;

Usage Examples:

import { gestures } from '@polymer/polymer/lib/utils/gestures.js';

class GestureElement extends PolymerElement {
  ready() {
    super.ready();
    
    // Add gesture listeners
    gestures.addListener(this, 'tap', this._handleTap.bind(this));
    gestures.addListener(this, 'track', this._handleTrack.bind(this));
    
    // Prevent default touch behaviors
    gestures.setTouchAction(this, 'none');
  }
  
  _handleTap(e) {
    console.log('Tap at:', e.detail.x, e.detail.y);
  }
  
  _handleTrack(e) {
    switch (e.detail.state) {
      case 'start':
        console.log('Track started');
        break;
      case 'track':
        console.log('Tracking:', e.detail.dx, e.detail.dy);
        break;
      case 'end':
        console.log('Track ended');
        break;
    }
  }
}

Case Conversion

String case conversion utilities.

/**
 * Convert dash-case to camelCase
 */
function dashToCamelCase(dash: string): string;

/**
 * Convert camelCase to dash-case
 */
function camelToDashCase(camel: string): string;

Usage Examples:

import { dashToCamelCase, camelToDashCase } from '@polymer/polymer/lib/utils/case-map.js';

console.log(dashToCamelCase('my-property')); // 'myProperty'
console.log(dashToCamelCase('data-binding-example')); // 'dataBindingExample'

console.log(camelToDashCase('myProperty')); // 'my-property'
console.log(camelToDashCase('dataBindingExample')); // 'data-binding-example'

Array Utilities

Array manipulation and observation utilities.

/**
 * Calculate splice operations needed to transform one array to another
 */
function calculateSplices(current: any[], previous: any[]): Splice[];

interface Splice {
  index: number;
  removed: any[];
  addedCount: number;
  object: any[];
  type: 'splice';
}

Flattened Node Observer

Observer for flattened DOM tree changes (considering shadow DOM).

/**
 * Observer for changes to flattened node tree
 */
class FlattenedNodesObserver {
  /** Create observer for a node */
  constructor(target: Node, callback: (info: FlattenedNodesInfo) => void);
  
  /** Start observing */
  connect(): void;
  
  /** Stop observing */
  disconnect(): void;
  
  /** Force synchronous update */
  flush(): void;
}

interface FlattenedNodesInfo {
  target: Node;
  addedNodes: Node[];
  removedNodes: Node[];
}

Render Status

Functions for scheduling work relative to rendering.

/**
 * Schedule callback before next render
 */
function beforeNextRender(element: Element, fn: () => void): void;

/**
 * Schedule callback after next render
 */
function afterNextRender(element: Element, fn: () => void): void;

Usage Examples:

import { beforeNextRender, afterNextRender } from '@polymer/polymer/lib/utils/render-status.js';

class RenderElement extends PolymerElement {
  ready() {
    super.ready();
    
    // Schedule work before next render
    beforeNextRender(this, () => {
      console.log('Before render - good for DOM measurements');
      const rect = this.getBoundingClientRect();
    });
    
    // Schedule work after next render
    afterNextRender(this, () => {
      console.log('After render - DOM is updated');
      this.focusFirstInput();
    });
  }
  
  focusFirstInput() {
    const input = this.shadowRoot.querySelector('input');
    if (input) input.focus();
  }
}

URL Resolution

URL resolution utilities for relative paths and CSS.

/**
 * Resolve relative URL against base URL
 */
function resolveUrl(url: string, base?: string): string;

/**
 * Resolve URLs in CSS text
 */
function resolveCss(cssText: string, baseUrl: string): string;

/**
 * Extract path from URL
 */
function pathFromUrl(url: string): string;

Usage Examples:

import { resolveUrl, resolveCss, pathFromUrl } from '@polymer/polymer/lib/utils/resolve-url.js';

// Resolve relative URLs
console.log(resolveUrl('image.png', 'https://example.com/assets/')); 
// 'https://example.com/assets/image.png'

// Resolve CSS URLs
const css = 'background: url(../images/bg.png);';
const resolved = resolveCss(css, 'https://example.com/styles/');
// 'background: url(https://example.com/images/bg.png);'

// Extract path from URL
console.log(pathFromUrl('https://example.com/path/to/file.js')); 
// 'https://example.com/path/to/'

Settings & Configuration

Global configuration functions for Polymer behavior.

/**
 * Set the root path for resolving URLs
 */
function setRootPath(path: string): void;

/**
 * Set DOM value sanitization function
 */
function setSanitizeDOMValue(fn: (value: any, name: string, type: string, node: Element) => any): void;

/**
 * Get current DOM value sanitization function
 */
function getSanitizeDOMValue(): (value: any, name: string, type: string, node: Element) => any;

/**
 * Enable/disable passive touch gesture handling
 */
function setPassiveTouchGestures(usePassive: boolean): void;

/**
 * Enable/disable strict template policy
 */
function setStrictTemplatePolicy(useStrictPolicy: boolean): void;

/**
 * Set whether templates can be created from dom-module
 */
function setAllowTemplateFromDomModule(allowDomModule: boolean): void;

/**
 * Enable/disable legacy optimizations
 */
function setLegacyOptimizations(useLegacyOptimizations: boolean): void;

/**
 * Enable/disable legacy warnings
 */
function setLegacyWarnings(useLegacyWarnings: boolean): void;

/**
 * Enable/disable synchronous initial render
 */
function setSyncInitialRender(useSyncInitialRender: boolean): void;

Usage Examples:

import { 
  setRootPath, 
  setSanitizeDOMValue, 
  setPassiveTouchGestures 
} from '@polymer/polymer/lib/utils/settings.js';

// Configure root path for URL resolution
setRootPath('/my-app/');

// Set up DOM sanitization
setSanitizeDOMValue((value, name, type, node) => {
  if (type === 'property' && name === 'innerHTML') {
    return sanitizeHTML(value); // Your sanitization logic
  }
  return value;
});

// Enable passive touch gestures for better scroll performance
setPassiveTouchGestures(true);

Style Gathering

Utilities for gathering and processing styles from templates and modules.

/**
 * Get styles from multiple modules
 */
function stylesFromModules(moduleIds: string[]): CSSResult[];

/**
 * Get styles from a single module
 */
function stylesFromModule(moduleId: string): CSSResult[];

/**
 * Get styles from a template element
 */
function stylesFromTemplate(template: HTMLTemplateElement, baseURI?: string): CSSResult[];

/**
 * Get CSS text from multiple modules
 */
function cssFromModules(moduleIds: string[]): string;

/**
 * Get CSS text from a single module
 */
function cssFromModule(moduleId: string): string;

/**
 * Get CSS text from a template element
 */
function cssFromTemplate(template: HTMLTemplateElement, baseURI?: string): string;

Usage Examples:

import { 
  stylesFromModules, 
  cssFromTemplate 
} from '@polymer/polymer/lib/utils/style-gather.js';

class StyledElement extends PolymerElement {
  static get template() {
    const template = html`
      <style include="shared-styles theme-styles">
        :host {
          display: block;
        }
      </style>
      <div>Styled content</div>
    `;
    
    // Process styles from included modules
    const moduleStyles = stylesFromModules(['shared-styles', 'theme-styles']);
    
    return template;
  }
}

DOM Wrapping

ShadyDOM compatibility utilities.

/**
 * Wrap a node for ShadyDOM compatibility
 */
const wrap: <T extends Node>(node: T) => T;

Usage Examples:

import { wrap } from '@polymer/polymer/lib/utils/wrap.js';

// Wrap nodes when using ShadyDOM
const wrappedElement = wrap(someElement);
wrappedElement.appendChild(wrap(childNode));

Telemetry

Registration and instance tracking utilities.

/**
 * Array of all registered element constructors
 */
const registrations: PolymerElementConstructor[];

/**
 * Current instance count
 */
let instanceCount: number;

/**
 * Increment global instance count
 */
function incrementInstanceCount(): void;

/**
 * Register an element constructor
 */
function register(prototype: any): void;

/**
 * Dump registration information
 */
function dumpRegistrations(): void;

Types

interface AsyncInterface {
  run(fn: () => void, delay?: number): number;
  cancel(handle: number): void;
}

interface GestureRecognizer {
  name: string;
  deps: string[];
  flow: {
    start: (e: Event, state: any) => void;
    move: (e: Event, state: any) => void;
    end: (e: Event, state: any) => void;
  };
  emits: string[];
}

interface Splice {
  index: number;
  removed: any[];
  addedCount: number;
  object: any[];
  type: 'splice';
}