Micromark Utility for Chunked Array Operations

2.0.1 · active · verified Sun Apr 19

micromark-util-chunked is a specialized utility package within the `micromark` ecosystem, designed to perform array manipulations (`push` and `splice`) efficiently when dealing with exceptionally large arrays. Its primary purpose is to circumvent performance bottlenecks and V8 engine limitations, such as stack overflows, that can occur with native `Array.prototype.splice` when a massive number of items are involved. The current stable version is `2.0.1` (though the micromark monorepo has related packages at `4.x.x`). As part of the `micromark` monorepo, its updates typically align with the broader `micromark` project's active release schedule. A key differentiator is its optimized algorithms for chunked operations, ensuring stability and performance for complex parsing tasks often encountered within markdown processing. The package is ESM-only and ships with full TypeScript type definitions.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to use `push` and `splice` from `micromark-util-chunked` to efficiently manage large arrays of 'events' (e.g., markdown tokens), avoiding V8 limitations.

import { push, splice } from 'micromark-util-chunked';

// Simulate a context object often used in micromark tokenizers
const context = { document: 'Some markdown string with lots of tokens...' };

// Initialize an array of "events" (e.g., tokens or state changes).
// Start with a moderately large array to demonstrate the utility's purpose.
let events: Array<[string, any, typeof context]> = [];

// Populate with some initial data using `push`
for (let i = 0; i < 5000; i++) {
  events = push(events, [['text', { type: 'text', value: `item-${i}` }, context]]);
}

console.log(`Initial events length: ${events.length}`);
// Expected output: Initial events length: 5000

// Demonstrate `push` with a large chunk of new items, which avoids V8 stack limits
const newItemsToAdd: Array<[string, any, typeof context]> = [];
for (let i = 0; i < 10000; i++) {
  newItemsToAdd.push(['token', { type: 'new_token', value: `added-${i}` }, context]);
}
events = push(events, newItemsToAdd);
console.log(`Length after large push: ${events.length}`);
// Expected output: Length after large push: 15000

// Demonstrate `splice`: removing existing items and inserting new ones.
// Let's remove 500 items from index 1000 and insert 2000 new ones.
const itemsToInsert: Array<[string, any, typeof context]> = [];
for (let i = 0; i < 2000; i++) {
  itemsToInsert.push(['insert', { type: 'inserted', value: `inserted-${i}` }, context]);
}

const startIndex = 1000;
const itemsToRemove = 500;
splice(events, startIndex, itemsToRemove, itemsToInsert);
console.log(`Length after splice: ${events.length}`);
// Expected output: Length after splice: 16500 (15000 - 500 + 2000)

// Verify a few items around the spliced area
console.log('Item before splice start:', events[startIndex - 1]);
console.log('First inserted item:', events[startIndex]);
console.log('Last inserted item:', events[startIndex + itemsToInsert.length - 1]);
console.log('Item after inserted block:', events[startIndex + itemsToInsert.length]);

// Example of a small final push
events = push(events, [['final', { type: 'end' }, context]]);
console.log(`Length after final push: ${events.length}`);
// Expected output: Length after final push: 16501

view raw JSON →