or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-yallist

High-performance doubly-linked list implementation with bidirectional operations and array-like methods

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/yallist@5.0.x

To install, run

npx @tessl/cli install tessl/npm-yallist@5.0.0

index.mddocs/

Yallist

Yallist (Yet Another Linked List) is a high-performance doubly-linked list implementation for JavaScript and TypeScript. It provides array-like operations optimized for frequent insertions and deletions at arbitrary positions, with comprehensive bidirectional iteration capabilities.

Package Information

  • Package Name: yallist
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install yallist

Core Imports

import { Yallist, Node } from "yallist";

For CommonJS:

const { Yallist, Node } = require("yallist");

Basic Usage

import { Yallist } from "yallist";

// Create a new list from an array
const list = new Yallist([1, 2, 3]);

// Add elements
list.push(4, 5);           // Add to tail
list.unshift(0);           // Add to head

// Access elements  
console.log(list.get(0));  // 0 (from head)
console.log(list.getReverse(0)); // 5 (from tail)

// Iterate
list.forEach((value, index) => console.log(value));
list.forEachReverse((value, index) => console.log(value));

// Transform data
const doubled = list.map(x => x * 2);
const sum = list.reduce((acc, val) => acc + val, 0);

// Convert to array
console.log(list.toArray()); // [0, 1, 2, 3, 4, 5]

Architecture

Yallist consists of two main classes:

  • Yallist: The main container class managing the linked list with head/tail pointers and length tracking
  • Node: Individual list elements containing values and bidirectional references
  • Bidirectional Operations: Most operations have both forward and reverse variants for optimal performance
  • Iterator Protocol: Implements JavaScript's iterable interface for native loop support
  • Type Safety: Full TypeScript generic support with proper type inference

Capabilities

List Construction

Create and initialize linked lists from iterables or using factory methods.

/**
 * Main doubly-linked list class with generic type support
 */
class Yallist<T = unknown> {
  /** First node in the list */
  head?: Node<T>;
  /** Last node in the list */
  tail?: Node<T>;  
  /** Number of nodes in the list */
  length: number;

  /**
   * Create a new list from an iterable
   * @param list - Iterable to initialize the list from
   */
  constructor(list?: Iterable<T>);

  /**
   * Factory method to create a new list
   * @param list - Iterable to initialize the list from  
   * @returns New Yallist instance
   */
  static create<T = unknown>(list?: Iterable<T>): Yallist<T>;
}

Element Access

Retrieve values by position from either end of the list.

/**
 * Get the value at position n from the head
 * @param n - Index from head (0-based)
 * @returns Value at position or undefined if out of bounds
 */
get(n: number): T | undefined;

/**
 * Get the value at position n from the tail
 * @param n - Index from tail (0-based) 
 * @returns Value at position or undefined if out of bounds
 */
getReverse(n: number): T | undefined;

Element Addition

Add elements to the head or tail of the list.

/**
 * Add elements to the tail of the list
 * @param args - Elements to add
 * @returns New length of the list
 */
push(...args: T[]): number;

/**
 * Add elements to the head of the list
 * @param args - Elements to add
 * @returns New length of the list
 */
unshift(...args: T[]): number;

Element Removal

Remove and return elements from either end of the list.

/**
 * Remove and return the tail element
 * @returns Tail value or undefined if list is empty
 */
pop(): T | undefined;

/**
 * Remove and return the head element
 * @returns Head value or undefined if list is empty
 */
shift(): T | undefined;

Node Operations

Direct manipulation of Node objects for advanced use cases.

/**
 * Remove a specific node from the list
 * @param node - Node to remove (must belong to this list)
 * @returns Next node after the removed node, or undefined if removing tail
 * @throws Error with message "removing node which does not belong to this list"
 */
removeNode(node: Node<T>): Node<T> | undefined;

/**
 * Move a node to the head of the list
 * @param node - Node to move (will be removed from its current list if any)
 */
unshiftNode(node: Node<T>): void;

/**
 * Move a node to the tail of the list
 * @param node - Node to move (will be removed from its current list if any)
 */
pushNode(node: Node<T>): void;

Iteration

Iterate through the list in either direction with callback functions.

/**
 * Execute a function for each element from head to tail
 * @param fn - Function to execute for each element (receives value, index, and list)
 * @param thisp - Value to use as 'this' when executing fn (optional)
 */
forEach(fn: (value: T, index: number, list: Yallist<T>) => any, thisp?: any): void;

/**
 * Execute a function for each element from tail to head
 * @param fn - Function to execute for each element (receives value, index, and list)
 * @param thisp - Value to use as 'this' when executing fn (optional)
 */
forEachReverse(fn: (value: T, index: number, list: Yallist<T>) => any, thisp?: any): void;

/**
 * Make the list iterable (head to tail)
 * @returns Iterator that yields values from head to tail
 */
[Symbol.iterator](): IterableIterator<T>;

Transformation

Create new lists by transforming elements while preserving the list structure.

/**
 * Create a new list with transformed values (head to tail)
 * @param fn - Transformation function (receives value and list)
 * @param thisp - Value to use as 'this' when executing fn (optional)
 * @returns New Yallist with transformed values
 */
map<R = any>(fn: (value: T, list: Yallist<T>) => R, thisp?: any): Yallist<R>;

/**
 * Create a new list with transformed values (tail to head)
 * @param fn - Transformation function (receives value and list)
 * @param thisp - Value to use as 'this' when executing fn (optional)
 * @returns New Yallist with transformed values
 */
mapReverse<R = any>(fn: (value: T, list: Yallist<T>) => R, thisp?: any): Yallist<R>;

Reduction

Reduce the list to a single value using accumulator functions.

/**
 * Reduce list to single value without initial value (head to tail)
 * @param fn - Reducer function
 * @returns Reduced value
 * @throws TypeError with message "Reduce of empty list with no initial value"
 */
reduce(fn: (left: T, right: T, index: number) => T): T;

/**
 * Reduce list to single value with initial value (head to tail)
 * @param fn - Reducer function
 * @param initial - Initial accumulator value
 * @returns Reduced value
 */
reduce<R = any>(fn: (acc: R, next: T, index: number) => R, initial: R): R;

/**
 * Reduce list to single value without initial value (tail to head)
 * @param fn - Reducer function
 * @returns Reduced value
 * @throws TypeError with message "Reduce of empty list with no initial value"
 */
reduceReverse(fn: (left: T, right: T, index: number) => T): T;

/**
 * Reduce list to single value with initial value (tail to head)
 * @param fn - Reducer function
 * @param initial - Initial accumulator value
 * @returns Reduced value
 */
reduceReverse<R = any>(fn: (acc: R, next: T, index: number) => R, initial: R): R;

Array Conversion

Convert the list to standard JavaScript arrays in either direction.

/**
 * Convert list to array from head to tail
 * @returns Array containing all list values
 */
toArray(): T[];

/**
 * Convert list to array from tail to head
 * @returns Array containing all list values in reverse order
 */
toArrayReverse(): T[];

List Slicing

Extract portions of the list as new Yallist instances.

/**
 * Extract a slice of the list (head to tail)
 * @param from - Start index (inclusive, default 0)
 * @param to - End index (exclusive, default list.length)
 * @returns New Yallist containing the slice
 */
slice(from?: number, to?: number): Yallist<T>;

/**
 * Extract a slice of the list (tail to head)
 * @param from - Start index (inclusive, default 0)
 * @param to - End index (exclusive, default list.length)
 * @returns New Yallist containing the slice in reverse order
 */
sliceReverse(from?: number, to?: number): Yallist<T>;

List Modification

Modify the list by removing/inserting elements at arbitrary positions.

/**
 * Remove elements and/or insert new elements at a specific position
 * @param start - Start index for modification (negative indices count from end)
 * @param deleteCount - Number of elements to remove (default 0)
 * @param nodes - New elements to insert at the start position
 * @returns Array of removed elements
 */
splice(start: number, deleteCount?: number, ...nodes: T[]): T[];

/**
 * Reverse the list in place
 * @returns This list (for chaining)
 */
reverse(): Yallist<T>;

Types

/**
 * Individual node in the doubly-linked list
 */
class Node<T = unknown> {
  /** The data stored in this node */
  value: T;
  /** Reference to the next node in the list */
  next?: Node<T>;
  /** Reference to the previous node in the list */
  prev?: Node<T>;
  /** Reference to the list this node belongs to */
  list?: Yallist<T>;

  /**
   * Create a new node
   * @param value - The value to store in the node
   * @param prev - Previous node reference
   * @param next - Next node reference  
   * @param list - List this node belongs to
   */
  constructor(
    value: T,
    prev?: Node<T>,
    next?: Node<T>,
    list?: Yallist<T>
  );
}