CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-yallist

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

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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>
  );
}
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/yallist@5.0.x
Publish Source
CLI
Badge
tessl/npm-yallist badge