moonbit-sourcemap

    Source Map v3 mappings, lookup, and Wasm sourceMappingURL integration for MoonBit

    source-map
    vlq
    wasm
    debugging
    tooling
    Download zip
    Version
    0.1.1
    License
    Apache-2.0
    Last updated
    2 months ago
    Downloads
    29

    No dependencies

    #xiaoxiao1211/moonbit-sourcemap

    Source Map v3 support for MoonBit projects. The package provides Base64 VLQ, mappings parsing and generation, validated JSON models, incremental map construction, bidirectional position lookup, and WebAssembly sourceMappingURL custom-section integration.

    The implementation is pure MoonBit and depends only on MoonBit core packages. It is intended for compiler integrations, Web IDEs, debuggers, test runners and other tools that need to relate generated Wasm-facing positions to .mbt source locations.

    #Install

    Add the published package to a MoonBit module:

    moon add xiaoxiao1211/moonbit-sourcemap@0.1.1

    The package can then be imported with the generated alias @moonbit_sourcemap (or a local alias chosen in moon.pkg).

    #Features

    • Signed Base64 VLQ encoding and decoding with structured errors.
    • Source Map v3 JSON parsing, validation and compact/pretty serialization.
    • Mappings parsing and canonical generation.
    • Incremental SourceMapBuilder with source/name interning.
    • Generated-to-original and original-to-generated position lookup.
    • Greatest-lower-bound and least-upper-bound lookup bias.
    • Exact one-to-many reverse lookup with generated_positions_for.
    • Read, add, replace and remove Wasm sourceMappingURL custom sections.
    • sourcesContent, unmapped segments and named segments.

    #Library example

    Positions are zero-based. Mapping calls must be added in generated position order so the builder can preserve Source Map v3 delta encoding:

    let builder = @moonbit_sourcemap.SourceMapBuilder::new()
    builder.add_mapping(
    0,
    0,
    "src/main.mbt",
    4,
    2,
    name=Some("main"),
    source_content=Some("fn main { println(\"hello\") }")
    )
    builder.add_mapping(0, 12, "src/main.mbt", 5, 4)

    let map = builder.build(file=Some("app.wasm"))
    let json = map.to_json(pretty=true)
    let compact_mappings = map.encode_mappings()

    match map.original_position_for(0, 14) {
    Some(position) => println(position)
    None => println("no mapping")
    }

    Use parse_json to validate and decode an existing regular Source Map v3 document:

    ///|
    let map = @moonbit_sourcemap.parse_json(json_text)

    #Wasm integration

    The Wasm helpers operate on complete Wasm byte arrays and preserve unrelated sections:

    ///|
    let linked = @moonbit_sourcemap.wasm_set_source_mapping_url(
    wasm_bytes, "app.wasm.map",
    )

    ///|
    let url = @moonbit_sourcemap.wasm_source_mapping_url(linked)

    ///|
    let unlinked = @moonbit_sourcemap.wasm_remove_source_mapping_url(linked)

    #CLI and examples

    The repository includes a native CLI and runnable fixtures. From a checkout:

    moon run cmd/main --target native -- inspect examples/basic.map moon run cmd/main --target native -- lookup examples/basic.map 0 14 moon run cmd/main --target native -- reverse examples/basic.map src/main.mbt 5 4 moon run cmd/main --target native -- wasm-url examples/basic.wasm moon run cmd/main -- demo

    #Scope

    Version 0.1.0 implements regular Source Map v3 documents, the mappings layer, position lookup and Wasm sourceMappingURL custom-section I/O. Index Map sections are deliberately rejected and remain future work. No performance claim is made without a reproducible benchmark.

    #Development

    moon info moon fmt --check moon check moon test moon build --target all moon package --list

    The source repository, design notes, verification record and release process are available at https://github.com/xiaoxiao1211/moonbit-sourcemap. The project is licensed under Apache-2.0.

    SourceMapError

    pub(all) suberror SourceMapError {
    At(Int, String)
    }

    A malformed Base64 VLQ value or Source Map mappings field.

    SourceMapError::to_string

    fn SourceMapError::to_string(self : SourceMapError) -> String

    Mapping

    pub struct Mapping {
    generated_line : Int
    generated_column : Int
    source_index : Int?
    original_line : Int?
    original_column : Int?
    name_index : Int?
    } derive(Eq,
    Debug
    )

    One decoded Source Map segment. Lines and columns are zero-based.

    Mapping::make

    fn Mapping::make(generated_line : Int, generated_column : Int, source_index? : Int?, original_line? : Int?, original_column? : Int?, name_index? : Int?) -> Mapping

    Construct one generated-only or original-source mapping segment.

    MappingBias

    pub(all) enum MappingBias {
    GreatestLowerBound
    LeastUpperBound
    } derive(Eq,
    Debug
    )

    Select which neighboring mapping a position query returns.

    ResolvedMapping

    pub struct ResolvedMapping {
    generated_line : Int
    generated_column : Int
    source : String?
    original_line : Int?
    original_column : Int?
    name : String?
    } derive(Eq,
    Debug
    )

    A resolved mapping suitable for debugger and editor integrations.

    SourceMap

    pub struct SourceMap {
    file : String?
    source_root : String?
    sources : Array[String]
    sources_content : Array[String?]
    names : Array[String]
    mappings : Array[Mapping]
    }

    A decoded Source Map v3 core model.

    SourceMap::encode_mappings

    fn SourceMap::encode_mappings(self : SourceMap) -> String

    Encode decoded mappings into a canonical Source Map v3 mappings string.

    SourceMap::generated_position_for

    fn SourceMap::generated_position_for(self : SourceMap, source : String, line : Int, column : Int) -> ResolvedMapping?

    Find the closest mapping at or before an original column on the same source line.

    SourceMap::generated_position_for_with_bias

    fn SourceMap::generated_position_for_with_bias(self : SourceMap, source : String, line : Int, column : Int, bias : MappingBias) -> ResolvedMapping?

    Find a mapping neighboring an original position on the same source line.

    SourceMap::generated_positions_for

    fn SourceMap::generated_positions_for(self : SourceMap, source : String, line : Int, column : Int) -> Array[ResolvedMapping]

    Find every generated position that maps to an exact original position. This preserves generated mapping order and supports one-to-many mappings.

    SourceMap::make

    fn SourceMap::make(sources : Array[String], names : Array[String], mappings : Array[Mapping], file? : String?, source_root? : String?, sources_content? : Array[String?]) -> SourceMap raise SourceMapError

    Build and validate a decoded Source Map.

    SourceMap::original_position_for

    fn SourceMap::original_position_for(self : SourceMap, line : Int, column : Int) -> ResolvedMapping?

    Find the greatest mapping at or before a generated position on the same line.

    SourceMap::original_position_for_with_bias

    fn SourceMap::original_position_for_with_bias(self : SourceMap, line : Int, column : Int, bias : MappingBias) -> ResolvedMapping?

    Find a mapping neighboring a generated position on the same line.

    SourceMap::to_json

    fn SourceMap::to_json(self : SourceMap, pretty? : Bool) -> String

    Serialize a regular Source Map v3 document as compact or indented JSON.

    SourceMapBuilder

    pub struct SourceMapBuilder {
    sources : Array[String]
    sources_content : Array[String?]
    names : Array[String]
    mappings : Array[Mapping]
    last_line : Int
    last_column : Int
    }

    Incremental Source Map builder. Mappings must be added in generated order.

    SourceMapBuilder::add_mapping

    fn SourceMapBuilder::add_mapping(self : SourceMapBuilder, generated_line : Int, generated_column : Int, source : String, original_line : Int, original_column : Int, name? : String?, source_content? : String?) -> Unit raise SourceMapError

    Add a segment linked to an original source position and optional symbol.

    SourceMapBuilder::add_unmapped

    fn SourceMapBuilder::add_unmapped(self : SourceMapBuilder, generated_line : Int, generated_column : Int) -> Unit raise SourceMapError

    Add a generated-only segment.

    SourceMapBuilder::build

    fn SourceMapBuilder::build(self : SourceMapBuilder, file? : String?, source_root? : String?) -> SourceMap raise SourceMapError

    Finish the map. The builder remains readable but should not be reused.

    SourceMapBuilder::new

    decode_vlq

    fn decode_vlq(encoded : String) -> Int raise SourceMapError

    Decode exactly one signed Base64 VLQ integer.

    decode_vlq_values

    fn decode_vlq_values(encoded : String) -> Array[Int] raise SourceMapError

    Decode all signed values in one mapping segment.

    encode_vlq

    fn encode_vlq(value : Int) -> String

    Encode one signed integer using Source Map Base64 VLQ.

    parse_json

    fn parse_json(input : String) -> SourceMap raise SourceMapError

    Parse a regular (non-indexed) Source Map v3 JSON document.

    parse_mappings

    fn parse_mappings(encoded : String, sources : Array[String], names : Array[String]) -> SourceMap raise SourceMapError

    Parse a Source Map v3 mappings string using the supplied tables.

    wasm_remove_source_mapping_url

    fn wasm_remove_source_mapping_url(wasm : Bytes) -> Bytes raise SourceMapError

    Remove a WebAssembly sourceMappingURL custom section when present.

    wasm_set_source_mapping_url

    fn wasm_set_source_mapping_url(wasm : Bytes, url : String) -> Bytes raise SourceMapError

    Add or replace a WebAssembly sourceMappingURL custom section.

    wasm_source_mapping_url

    fn wasm_source_mapping_url(wasm : Bytes) -> String? raise SourceMapError

    Read the URL stored in a WebAssembly sourceMappingURL custom section.