or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.mdjson-schema.mdlogging.mdnode-integration.mdutilities.mdvirtual-filesystem.mdworkspace.md
tile.json

utilities.mddocs/

Utilities

Collection of utility functions for string processing, templating, data structures, and object manipulation, including case conversion, template parsing, priority queues, and deep copying capabilities.

Capabilities

Object Utilities

Deep copying and object manipulation utilities.

/**
 * Deep copy utility that handles circular references and toJSON methods
 * Creates a complete deep copy of the input value, handling:
 * - Circular references (throws error to prevent infinite recursion)
 * - Objects with toJSON methods (calls toJSON for serialization)
 * - Arrays, nested objects, and primitive values
 * - Date objects, RegExp, and other built-in types
 * 
 * @param value - Value to deep copy
 * @returns Deep copy of the input value
 * @throws Error if circular reference is detected
 */
function deepCopy<T>(value: T): T;

Template Processing

EJS-like template engine with TypeScript support and source map generation.

/**
 * Template compilation options
 */
interface TemplateOptions {
  /** Module name for source maps */
  module?: boolean;
  /** File name for source maps and error reporting */
  filename?: string;
  /** Generate source maps for debugging */
  sourceMap?: boolean;
  /** Custom variable name for template context (default: 'it') */
  variable?: string;
}

/**
 * EJS-like template engine with optional source map support
 * Compiles template strings into functions that can be executed with context data
 * Supports JavaScript expressions, HTML escaping, and raw output
 * 
 * @param content - Template string with embedded expressions
 * @param options - Template compilation options
 * @returns Function that takes context and returns rendered string
 */
function template<T = {}>(content: string, options?: TemplateOptions): (context: T) => string;

/**
 * Parser for template AST (Abstract Syntax Tree)
 * Parses template strings into structured AST nodes for analysis
 * 
 * @param content - Template string to parse
 * @param options - Parsing options
 * @returns Template AST representing the parsed structure
 */
function templateParser(content: string, options?: TemplateOptions): TemplateAst;

Template AST Types

Types for representing parsed template structure.

/**
 * Root template AST node containing all parsed elements
 */
interface TemplateAst {
  /** Array of AST nodes representing template content */
  content: TemplateAstNode[];
  /** Source information for debugging */
  source: {
    start: number;
    end: number;
  };
}

/**
 * Union type of all possible AST node types
 */
type TemplateAstNode = 
  | TemplateAstContent 
  | TemplateAstComment 
  | TemplateAstEvaluate 
  | TemplateAstEscape 
  | TemplateAstInterpolate;

/**
 * Static content node (literal text)
 */
interface TemplateAstContent {
  kind: 'content';
  value: string;
  source: { start: number; end: number };
}

/**
 * Comment node (<%# comment %>)
 */
interface TemplateAstComment {
  kind: 'comment';
  value: string;
  source: { start: number; end: number };
}

/**
 * Evaluation node (<% code %>) - executes JavaScript without output
 */
interface TemplateAstEvaluate {
  kind: 'evaluate';
  value: string;
  source: { start: number; end: number };
}

/**
 * HTML escape node (<%- expression %>) - outputs HTML-escaped result
 */
interface TemplateAstEscape {
  kind: 'escape';
  value: string;
  source: { start: number; end: number };
}

/**
 * Interpolation node (<%= expression %>) - outputs raw result
 */
interface TemplateAstInterpolate {
  kind: 'interpolate';
  value: string;
  source: { start: number; end: number };
}

String Processing

Comprehensive string manipulation functions for case conversion and text processing.

namespace strings {
  /**
   * Convert camelCase to snake_case
   * @param str - String to convert
   * @returns snake_case version of input
   */
  function decamelize(str: string): string;
  
  /**
   * Convert to kebab-case (dash-separated)
   * @param str - String to convert
   * @returns kebab-case version of input
   */
  function dasherize(str: string): string;
  
  /**
   * Convert to camelCase
   * @param str - String to convert
   * @returns camelCase version of input
   */
  function camelize(str: string): string;
  
  /**
   * Convert to PascalCase/UpperCamelCase
   * @param str - String to convert
   * @returns PascalCase version of input
   */
  function classify(str: string): string;
  
  /**
   * Convert to snake_case
   * @param str - String to convert
   * @returns snake_case version of input
   */
  function underscore(str: string): string;
  
  /**
   * Capitalize first letter, leave rest unchanged
   * @param str - String to capitalize
   * @returns String with first letter capitalized
   */
  function capitalize(str: string): string;
  
  /**
   * Calculate Levenshtein distance (edit distance) between two strings
   * Returns minimum number of single-character edits needed to transform one string into another
   * @param a - First string
   * @param b - Second string
   * @returns Edit distance between the strings
   */
  function levenshtein(a: string, b: string): number;
}

Template Literal Tags

Tagged template literal functions for string formatting and manipulation.

namespace tags {
  /**
   * Template literal tag function interface
   */
  interface TemplateTag {
    (strings: TemplateStringsArray, ...values: any[]): string;
  }
  
  /**
   * Template tag to join lines into a single line, collapsing whitespace
   * Removes line breaks and normalizes spacing
   * @param strings - Template string parts
   * @param values - Template expression values
   * @returns Single-line string
   */
  function oneLine(strings: TemplateStringsArray, ...values: any[]): string;
  
  /**
   * Template tag factory for consistent indentation
   * Creates a template tag that indents all lines by specified amount
   * @param spaces - Number of spaces to indent each line
   * @returns Template tag function for indenting
   */
  function indentBy(spaces: number): TemplateTag;
  
  /**
   * Template tag to remove common leading indentation from all lines
   * Preserves relative indentation between lines
   * @param strings - Template string parts
   * @param values - Template expression values
   * @returns String with common indentation removed
   */
  function stripIndent(strings: TemplateStringsArray, ...values: any[]): string;
  
  /**
   * Template tag to remove all leading indentation from all lines
   * Makes all lines start at column 0
   * @param strings - Template string parts
   * @param values - Template expression values
   * @returns String with all indentation removed
   */
  function stripIndents(strings: TemplateStringsArray, ...values: any[]): string;
  
  /**
   * Template tag to remove leading and trailing newlines
   * Preserves internal line structure
   * @param strings - Template string parts
   * @param values - Template expression values
   * @returns String with outer newlines trimmed
   */
  function trimNewlines(strings: TemplateStringsArray, ...values: any[]): string;
}

Data Structures

Advanced data structures for specialized use cases.

/**
 * Set with dependency ordering support
 * Maintains items in topological order based on dependencies
 * Throws errors on circular dependencies or missing dependencies
 */
class PartiallyOrderedSet<T> implements Iterable<T> {
  /** Number of items in the set */
  readonly size: number;
  
  constructor();
  
  /**
   * Add an item with optional dependencies
   * @param item - Item to add
   * @param deps - Items this item depends on (must be added first)
   */
  add(item: T, deps?: Set<T>): this;
  
  /**
   * Remove an item from the set
   * @param item - Item to remove
   * @returns True if item was removed, false if not found
   */
  delete(item: T): boolean;
  
  /**
   * Check if item exists in the set
   * @param item - Item to check
   * @returns True if item exists
   */
  has(item: T): boolean;
  
  /**
   * Clear all items from the set
   */
  clear(): void;
  
  /**
   * Iterate over items in dependency order
   */
  [Symbol.iterator](): Iterator<T>;
  
  /**
   * Get items as array in dependency order
   * @returns Array of items in topological order
   */
  toArray(): T[];
}

/**
 * Exception thrown when a required dependency is not found in the set
 */
class DependencyNotFoundException extends BaseException {
  constructor(missing: string);
}

/**
 * Exception thrown when a circular dependency is detected
 */
class CircularDependencyFoundException extends BaseException {
  constructor(cycle: string[]);
}

/**
 * Basic priority queue implementation
 * Items are ordered by priority value (lower numbers = higher priority)
 */
class PriorityQueue<T> {
  /** Number of items in the queue */
  readonly size: number;
  
  constructor();
  
  /**
   * Add item to queue with specified priority
   * @param item - Item to add
   * @param priority - Priority value (lower = higher priority)
   */
  push(item: T, priority: number): void;
  
  /**
   * Remove and return highest priority item
   * @returns Highest priority item, or undefined if queue is empty
   */
  pop(): T | undefined;
  
  /**
   * View highest priority item without removing it
   * @returns Highest priority item, or undefined if queue is empty
   */
  peek(): T | undefined;
  
  /**
   * Check if queue is empty
   * @returns True if queue has no items
   */
  isEmpty(): boolean;
  
  /**
   * Remove all items from the queue
   */
  clear(): void;
}

Language Utilities

Utility functions for working with JavaScript language features.

/**
 * Type guard to check if object is Promise-like
 * Checks for presence of 'then' method to identify thenable objects
 * @param obj - Object to check
 * @returns True if object appears to be a Promise
 */
function isPromise(obj: any): obj is Promise<any>;

Usage Examples

String Processing

import { strings } from "@angular-devkit/core";

// Case conversions
const camelCase = strings.camelize('hello-world-example');     // 'helloWorldExample'
const pascalCase = strings.classify('hello-world-example');    // 'HelloWorldExample'
const kebabCase = strings.dasherize('HelloWorldExample');      // 'hello-world-example'
const snakeCase = strings.underscore('HelloWorldExample');     // 'hello_world_example'
const decamelized = strings.decamelize('helloWorldExample');   // 'hello_world_example'
const capitalized = strings.capitalize('hello world');         // 'Hello world'

// Edit distance calculation
const distance = strings.levenshtein('kitten', 'sitting');     // 3
console.log(`Edit distance: ${distance}`);

Template Processing

import { template } from "@angular-devkit/core";

// Basic template compilation
const tmpl = template(`
  Hello <%= name %>!
  <% if (showAge) { %>
    You are <%= age %> years old.
  <% } %>
`);

const result = tmpl({ 
  name: 'Alice', 
  age: 25, 
  showAge: true 
});
console.log(result);
// Output: "Hello Alice!\n  You are 25 years old."

// Template with HTML escaping
const safeTmpl = template(`
  <p>Message: <%- userInput %></p>
  <p>Raw: <%= userInput %></p>
`);

const safeResult = safeTmpl({ 
  userInput: '<script>alert("xss")</script>' 
});
// HTML in userInput is escaped in <%- %> but not in <%= %>

Tagged Template Literals

import { tags } from "@angular-devkit/core";

// Remove line breaks and normalize spacing
const singleLine = tags.oneLine`
  This is a very long
  message that spans
  multiple lines
`;
console.log(singleLine); // "This is a very long message that spans multiple lines"

// Remove common indentation
const code = tags.stripIndent`
    function example() {
      console.log('Hello');
      return true;
    }
  `;
console.log(code);
// Output has leading spaces removed but relative indentation preserved

// Add consistent indentation
const indent4 = tags.indentBy(4);
const indented = indent4`
  Line 1
  Line 2
`;
// Each line is indented by 4 additional spaces

// Remove all indentation
const noIndent = tags.stripIndents`
    First line
      Second line
        Third line
  `;
console.log(noIndent);
// Output: "First line\nSecond line\nThird line"

Data Structures

import { PartiallyOrderedSet, PriorityQueue } from "@angular-devkit/core";

// Partially ordered set with dependencies
const buildOrder = new PartiallyOrderedSet<string>();

// Add items with dependencies
buildOrder.add('app');
buildOrder.add('utils');
buildOrder.add('components', new Set(['utils']));
buildOrder.add('pages', new Set(['components', 'utils']));
buildOrder.add('main', new Set(['app', 'pages']));

// Iterate in dependency order
for (const item of buildOrder) {
  console.log(`Building: ${item}`);
}
// Output: utils, app, components, pages, main

// Priority queue
const tasks = new PriorityQueue<string>();

tasks.push('Low priority task', 10);
tasks.push('High priority task', 1);
tasks.push('Medium priority task', 5);

while (!tasks.isEmpty()) {
  const task = tasks.pop();
  console.log(`Processing: ${task}`);
}
// Output: High priority task, Medium priority task, Low priority task

Object Utilities

import { deepCopy, isPromise } from "@angular-devkit/core";

// Deep copy complex objects
const original = {
  name: 'Test',
  config: {
    enabled: true,
    options: ['a', 'b', 'c']
  },
  created: new Date()
};

const copy = deepCopy(original);
copy.config.enabled = false;
console.log(original.config.enabled); // true (original unchanged)
console.log(copy.config.enabled);     // false

// Promise detection
const maybePromise = someAsyncFunction();
if (isPromise(maybePromise)) {
  const result = await maybePromise;
  console.log('Got async result:', result);
} else {
  console.log('Got sync result:', maybePromise);
}

Template AST Analysis

import { templateParser } from "@angular-devkit/core";

const template = `
  <h1><%= title %></h1>
  <% if (showContent) { %>
    <p><%- content %></p>
  <% } %>
  <%# This is a comment %>
`;

const ast = templateParser(template);

// Analyze AST nodes
for (const node of ast.content) {
  switch (node.kind) {
    case 'content':
      console.log('Static content:', node.value.trim());
      break;
    case 'interpolate':
      console.log('Expression (raw):', node.value);
      break;
    case 'escape':
      console.log('Expression (escaped):', node.value);
      break;
    case 'evaluate':
      console.log('Code block:', node.value);
      break;
    case 'comment':
      console.log('Comment:', node.value);
      break;
  }
}