CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-volar--source-map

Provides functionality related to source maps including a SourceMap class with methods for translating between source and generated code positions, ranges, and locations with support for custom data filtering and fallback matching strategies.

Pending
Overview
Eval results
Files

@volar/source-map

@volar/source-map provides functionality for working with source maps, including bidirectional translation between source and generated code positions, ranges, and locations. It features a SourceMap class that enables precise mapping functionality with configurable fallback strategies and custom data filtering capabilities.

Package Information

  • Package Name: @volar/source-map
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @volar/source-map

Core Imports

import { SourceMap, translateOffset, type Mapping } from "@volar/source-map";

For CommonJS:

const { SourceMap, translateOffset } = require("@volar/source-map");

Basic Usage

import { SourceMap, type Mapping } from "@volar/source-map";

// Create mappings between source and generated code
const mappings: Mapping[] = [
  {
    sourceOffsets: [10, 20],
    generatedOffsets: [30, 50], 
    lengths: [5, 8],
    data: { type: "identifier" }
  },
  {
    sourceOffsets: [25],
    generatedOffsets: [65],
    lengths: [10],
    generatedLengths: [12], // Optional, defaults to lengths
    data: { type: "function" }
  }
];

// Create SourceMap instance 
const sourceMap = new SourceMap(mappings);

// Translate from generated to source
for (const [sourceOffset, mapping] of sourceMap.toSourceLocation(32)) {
  console.log(`Generated offset 32 maps to source offset ${sourceOffset}`);
}

// Translate ranges with fallback matching
for (const [sourceStart, sourceEnd, startMapping, endMapping] of 
     sourceMap.toSourceRange(30, 40, true)) {
  console.log(`Generated range [30-40] maps to source range [${sourceStart}-${sourceEnd}]`);
}

Capabilities

Source Map Translation

Core functionality for translating between source and generated code positions using mapping data.

/**
 * SourceMap class for bidirectional translation between source and generated code positions
 */
class SourceMap<Data = unknown> {
  constructor(mappings: Mapping<Data>[]);
  readonly mappings: Mapping<Data>[];
  
  /**
   * Maps generated range to source range(s)
   * @param generatedStart - Start offset in generated code
   * @param generatedEnd - End offset in generated code  
   * @param fallbackToAnyMatch - Allow start/end from different mappings
   * @param filter - Optional function to filter mappings by data
   * @returns Generator yielding [mappedStart, mappedEnd, startMapping, endMapping]
   */
  toSourceRange(
    generatedStart: number, 
    generatedEnd: number, 
    fallbackToAnyMatch: boolean, 
    filter?: (data: Data) => boolean
  ): Generator<[mappedStart: number, mappedEnd: number, startMapping: Mapping<Data>, endMapping: Mapping<Data>]>;
  
  /**
   * Maps source range to generated range(s)
   * @param sourceStart - Start offset in source code
   * @param sourceEnd - End offset in source code
   * @param fallbackToAnyMatch - Allow start/end from different mappings
   * @param filter - Optional function to filter mappings by data
   * @returns Generator yielding [mappedStart, mappedEnd, startMapping, endMapping]
   */
  toGeneratedRange(
    sourceStart: number, 
    sourceEnd: number, 
    fallbackToAnyMatch: boolean, 
    filter?: (data: Data) => boolean
  ): Generator<[mappedStart: number, mappedEnd: number, startMapping: Mapping<Data>, endMapping: Mapping<Data>]>;
  
  /**
   * Maps generated offset to source offset(s)
   * @param generatedOffset - Offset in generated code
   * @param filter - Optional function to filter mappings by data
   * @returns Generator yielding [mappedOffset, mapping]
   */
  toSourceLocation(
    generatedOffset: number, 
    filter?: (data: Data) => boolean
  ): Generator<[mappedOffset: number, mapping: Mapping<Data>]>;
  
  /**
   * Maps source offset to generated offset(s)
   * @param sourceOffset - Offset in source code
   * @param filter - Optional function to filter mappings by data
   * @returns Generator yielding [mappedOffset, mapping]
   */
  toGeneratedLocation(
    sourceOffset: number, 
    filter?: (data: Data) => boolean
  ): Generator<[mappedOffset: number, mapping: Mapping<Data>]>;
  
  /**
   * Find matching offsets for a given position (internal method exposed publicly)
   * @param offset - The offset to find matches for
   * @param fromRange - Whether searching in source or generated offsets
   * @param filter - Optional function to filter mappings by data
   * @returns Generator yielding [mappedOffset, mapping]
   */
  findMatchingOffsets(
    offset: number,
    fromRange: 'sourceOffsets' | 'generatedOffsets',
    filter?: (data: Data) => boolean
  ): Generator<[mappedOffset: number, mapping: Mapping<Data>]>;
  
  /**
   * Find matching start/end ranges (internal method exposed publicly)
   * @param start - Start offset
   * @param end - End offset
   * @param fallbackToAnyMatch - Allow start/end from different mappings
   * @param fromRange - Whether searching in source or generated offsets
   * @param filter - Optional function to filter mappings by data
   * @returns Generator yielding [mappedStart, mappedEnd, startMapping, endMapping]
   */
  findMatchingStartEnd(
    start: number,
    end: number,
    fallbackToAnyMatch: boolean,
    fromRange: 'sourceOffsets' | 'generatedOffsets',
    filter?: (data: Data) => boolean
  ): Generator<[mappedStart: number, mappedEnd: number, startMapping: Mapping<Data>, endMapping: Mapping<Data>]>;
}

Offset Translation Utility

Standalone utility function for translating offsets between ranges.

/**
 * Translates an offset from one range to another using mapping arrays
 * @param start - The offset to translate
 * @param fromOffsets - Source range offsets (should be sorted for optimal performance)
 * @param toOffsets - Target range offsets
 * @param fromLengths - Lengths for source ranges
 * @param toLengths - Lengths for target ranges (defaults to fromLengths)
 * @returns Translated offset or undefined if no mapping found
 */
function translateOffset(
  start: number,
  fromOffsets: number[],
  toOffsets: number[],
  fromLengths: number[],
  toLengths: number[] = fromLengths
): number | undefined;

Types

/**
 * Represents a single mapping between source and generated code positions
 */
interface Mapping<Data = unknown> {
  /** Array of source code offsets */
  sourceOffsets: number[];
  /** Array of generated code offsets */
  generatedOffsets: number[];
  /** Array of lengths for source offsets */
  lengths: number[];
  /** Optional array of lengths for generated offsets (defaults to lengths) */
  generatedLengths?: number[];
  /** Custom data associated with the mapping */
  data: Data;
}

Usage Examples

Basic Offset Translation

import { translateOffset } from "@volar/source-map";

// Translate offset 15 from source to generated code
const generatedOffset = translateOffset(
  15,                    // offset to translate
  [10, 20, 30],         // source offsets
  [50, 80, 120],        // generated offsets  
  [5, 8, 10],           // source lengths
  [8, 12, 15]           // generated lengths
);

console.log(generatedOffset); // 55 (if offset 15 falls in first range)

Custom Data Filtering

import { SourceMap, type Mapping } from "@volar/source-map";

interface CustomData {
  type: 'identifier' | 'function' | 'comment';
  important: boolean;
}

const mappings: Mapping<CustomData>[] = [
  {
    sourceOffsets: [10],
    generatedOffsets: [30],
    lengths: [5],
    data: { type: 'identifier', important: true }
  },
  {
    sourceOffsets: [20], 
    generatedOffsets: [40],
    lengths: [8],
    data: { type: 'comment', important: false }
  }
];

const sourceMap = new SourceMap(mappings);

// Only map important identifiers
for (const [offset, mapping] of sourceMap.toGeneratedLocation(
  12, 
  (data) => data.important && data.type === 'identifier'
)) {
  console.log(`Important identifier at source offset 12 maps to ${offset}`);
}

Range Mapping with Fallback

import { SourceMap, type Mapping } from "@volar/source-map";

const mappings: Mapping[] = [
  {
    sourceOffsets: [10, 30],
    generatedOffsets: [100, 200], 
    lengths: [5, 10],
    data: {}
  }
];

const sourceMap = new SourceMap(mappings);

// Try exact range mapping first, then fallback to any match
for (const [start, end, startMapping, endMapping] of 
     sourceMap.toGeneratedRange(12, 35, true)) {
  console.log(`Source range [12-35] maps to generated range [${start}-${end}]`);
  console.log(`Start mapping:`, startMapping);
  console.log(`End mapping:`, endMapping);
}

Error Handling

  • translateOffset returns undefined when no mapping is found for the given offset
  • SourceMap generator methods yield no results when no mappings are found
  • Console warning is logged if fromOffsets array is not sorted in translateOffset (performance optimization)
  • No exceptions are thrown by the public API - all methods handle invalid inputs gracefully

Install with Tessl CLI

npx tessl i tessl/npm-volar--source-map
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@volar/source-map@2.4.x