Skip to content

Commit c31d408

Browse files
docs: improve README with Node.js quick start, package guide, and missing wrapper READMEs
- Add "Choosing a package" decision guide for Node.js developers - Add Node.js quick start example showing drop-in migration - Reorder package table: drop-in replacements first, then core WASM, then NAPI - Add missing scopes CLI command to CLI section - Rename "Internals" to "Why srcmap is fast" with clearer framing - Create READMEs for @srcmap/gen-mapping, @srcmap/source-map, and @srcmap/remapping with full API compatibility tables, usage examples, and migration guides
1 parent ffd5378 commit c31d408

4 files changed

Lines changed: 309 additions & 9 deletions

File tree

README.md

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -206,16 +206,39 @@ Run `cd benchmarks && npm run download-fixtures && npm run bench:real-world` to
206206

207207
srcmap ships WASM and NAPI bindings for use in Node.js — useful for symbolication services, error monitoring, and bulk source map operations.
208208

209+
### Choosing a package
210+
211+
- **Consuming source maps?**[`@srcmap/trace-mapping`](https://www.npmjs.com/package/@srcmap/trace-mapping) (drop-in for `@jridgewell/trace-mapping`)
212+
- **Generating source maps?**[`@srcmap/gen-mapping`](https://www.npmjs.com/package/@srcmap/gen-mapping) (drop-in for `@jridgewell/gen-mapping`)
213+
- **Using Mozilla's API?**[`@srcmap/source-map`](https://www.npmjs.com/package/@srcmap/source-map) (drop-in for `source-map` v0.6)
214+
- **Composing/remapping?**[`@srcmap/remapping`](https://www.npmjs.com/package/@srcmap/remapping) (drop-in for `@ampproject/remapping`)
215+
- **Batch lookups or low-level control?**[`@srcmap/sourcemap-wasm`](https://www.npmjs.com/package/@srcmap/sourcemap-wasm) (raw WASM API, fastest for bulk ops)
216+
217+
### Quick start (Node.js)
218+
219+
```js
220+
// Swap the import — the rest of your code stays the same
221+
import { TraceMap, originalPositionFor } from '@srcmap/trace-mapping'
222+
223+
const map = new TraceMap(sourceMapJsonOrObject)
224+
const pos = originalPositionFor(map, { line: 43, column: 10 })
225+
// { source: 'src/app.ts', line: 11, column: 4, name: 'handleClick' }
226+
227+
map.free() // Release WASM memory (or use `using` with Symbol.dispose)
228+
```
229+
230+
### All packages
231+
209232
| Package | Description |
210233
|---|---|
211-
| [`@srcmap/sourcemap-wasm`](https://www.npmjs.com/package/@srcmap/sourcemap-wasm) | Parser + consumer (WASM) |
212-
| [`@srcmap/generator-wasm`](https://www.npmjs.com/package/@srcmap/generator-wasm) | Source map builder (WASM) |
213-
| [`@srcmap/remapping-wasm`](https://www.npmjs.com/package/@srcmap/remapping-wasm) | Concatenation + composition (WASM) |
214-
| [`@srcmap/symbolicate-wasm`](https://www.npmjs.com/package/@srcmap/symbolicate-wasm) | Stack trace symbolication (WASM) |
215234
| [`@srcmap/trace-mapping`](https://www.npmjs.com/package/@srcmap/trace-mapping) | Drop-in for `@jridgewell/trace-mapping` (WASM) |
216235
| [`@srcmap/gen-mapping`](https://www.npmjs.com/package/@srcmap/gen-mapping) | Drop-in for `@jridgewell/gen-mapping` (WASM) |
217236
| [`@srcmap/source-map`](https://www.npmjs.com/package/@srcmap/source-map) | Drop-in for Mozilla `source-map` v0.6 (WASM) |
218237
| [`@srcmap/remapping`](https://www.npmjs.com/package/@srcmap/remapping) | Drop-in for `@ampproject/remapping` (WASM) |
238+
| [`@srcmap/sourcemap-wasm`](https://www.npmjs.com/package/@srcmap/sourcemap-wasm) | Parser + consumer (WASM) |
239+
| [`@srcmap/generator-wasm`](https://www.npmjs.com/package/@srcmap/generator-wasm) | Source map builder (WASM) |
240+
| [`@srcmap/remapping-wasm`](https://www.npmjs.com/package/@srcmap/remapping-wasm) | Concatenation + composition (WASM) |
241+
| [`@srcmap/symbolicate-wasm`](https://www.npmjs.com/package/@srcmap/symbolicate-wasm) | Stack trace symbolication (WASM) |
219242
| [`@srcmap/sourcemap`](https://www.npmjs.com/package/@srcmap/sourcemap) | Parser + consumer (NAPI) |
220243
| [`@srcmap/codec`](https://www.npmjs.com/package/@srcmap/codec) | VLQ codec (NAPI) |
221244

@@ -234,18 +257,19 @@ srcmap encode mappings.json --json # Encode back to VLQ
234257
srcmap concat a.js.map b.js.map -o bundle.js.map # Concatenate
235258
srcmap remap minified.js.map --dir ./maps -o composed.js.map # Compose
236259
srcmap symbolicate stack.txt --dir ./maps --json # Symbolicate
260+
srcmap scopes bundle.js.map --json # Inspect ECMA-426 scopes & bindings
237261
srcmap schema # All commands as JSON (for agents)
238262
```
239263

240264
All commands support `--json` for structured output.
241265

242-
## Internals
266+
## Why srcmap is fast
243267

244-
- **Flat Mapping struct** — 28 bytes (6 × u32 + bool), cache-friendly contiguous layout
245-
- **Inlined VLQ decoder**single-char fast path for values −15..15 (~85% of real-world VLQ values)
268+
- **Cache-friendly layout** — 28-byte flat Mapping struct in contiguous memory (6 × u32 + bool)
269+
- **Single-char VLQ fast path**~85% of real-world values decode in one operation
246270
- **Lazy reverse index** — only built on first `generated_position_for` call
247-
- **Binary search lookups** — O(log n) for both forward and reverse queries
248-
- **Borrowed deserialization**`mappings` string borrowed from JSON input (zero-copy)
271+
- **Binary search** — O(log n) for both forward and reverse lookups
272+
- **Zero-copy parsing**`mappings` string borrowed directly from JSON input
249273
- **Pre-counted capacity** — segment and line counts estimated before allocation
250274

251275
## Development

packages/gen-mapping/README.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# @srcmap/gen-mapping
2+
3+
[![npm](https://img.shields.io/npm/v/@srcmap/gen-mapping.svg)](https://www.npmjs.com/package/@srcmap/gen-mapping)
4+
[![CI](https://github.com/BartWaardenburg/srcmap/actions/workflows/ci.yml/badge.svg)](https://github.com/BartWaardenburg/srcmap/actions/workflows/ci.yml)
5+
6+
Drop-in replacement for [`@jridgewell/gen-mapping`](https://github.com/jridgewell/gen-mapping) powered by Rust via WebAssembly.
7+
8+
Same API, same types, same behavior. Swap the import and get source map generation backed by Rust under the hood.
9+
10+
## Install
11+
12+
```bash
13+
npm install @srcmap/gen-mapping
14+
```
15+
16+
## Usage
17+
18+
```js
19+
// Before:
20+
// import { GenMapping, addMapping, toEncodedMap } from '@jridgewell/gen-mapping'
21+
22+
// After:
23+
import { GenMapping, addMapping, toEncodedMap } from '@srcmap/gen-mapping'
24+
25+
const map = new GenMapping({ file: 'bundle.js' })
26+
27+
addMapping(map, {
28+
generated: { line: 1, column: 0 },
29+
source: 'src/app.ts',
30+
original: { line: 10, column: 4 },
31+
name: 'handleClick',
32+
content: 'const handleClick = () => { ... }',
33+
})
34+
35+
const encoded = toEncodedMap(map)
36+
37+
// Cleanup WASM memory (optional, also via `using` with Symbol.dispose)
38+
map.free()
39+
```
40+
41+
## API compatibility
42+
43+
All exports from `@jridgewell/gen-mapping` are supported:
44+
45+
| Export | Description |
46+
|--------|-------------|
47+
| `GenMapping` | Main class — creates a new source map builder |
48+
| `addMapping(map, mapping)` | Add a mapping (1-based lines, 0-based columns) |
49+
| `maybeAddMapping(map, mapping)` | Add only if it differs from the previous mapping on the same line |
50+
| `setSourceContent(map, source, content)` | Set source content for a source file |
51+
| `setIgnore(map, source, ignore?)` | Mark a source as ignored |
52+
| `toEncodedMap(map)` | Return as encoded source map (VLQ string mappings) |
53+
| `toDecodedMap(map)` | Return as decoded source map (array mappings) |
54+
| `allMappings(map)` | Return all mappings as `Mapping[]` |
55+
| `fromMap(input)` | Construct from an existing source map |
56+
57+
### Line/column convention
58+
59+
Follows `@jridgewell/gen-mapping` conventions:
60+
- `addMapping` / `maybeAddMapping`: **1-based lines**, 0-based columns
61+
- Decoded mappings output: **0-based lines**, 0-based columns
62+
63+
## Differences from @jridgewell/gen-mapping
64+
65+
- **WASM memory**: Call `map.free()` when done, or use `using map = new GenMapping(...)` with `Symbol.dispose`
66+
- **VLQ encoding runs in WASM**: No JS-side encoding overhead
67+
68+
## Part of [srcmap](https://github.com/BartWaardenburg/srcmap)
69+
70+
High-performance source map tooling written in Rust. See also:
71+
- [`@srcmap/trace-mapping`](https://www.npmjs.com/package/@srcmap/trace-mapping) - Drop-in for `@jridgewell/trace-mapping` (consumer)
72+
- [`@srcmap/remapping`](https://www.npmjs.com/package/@srcmap/remapping) - Drop-in for `@ampproject/remapping` (composition)
73+
- [`@srcmap/generator-wasm`](https://www.npmjs.com/package/@srcmap/generator-wasm) - Lower-level WASM generator API
74+
75+
## License
76+
77+
MIT

packages/remapping/README.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# @srcmap/remapping
2+
3+
[![npm](https://img.shields.io/npm/v/@srcmap/remapping.svg)](https://www.npmjs.com/package/@srcmap/remapping)
4+
[![CI](https://github.com/BartWaardenburg/srcmap/actions/workflows/ci.yml/badge.svg)](https://github.com/BartWaardenburg/srcmap/actions/workflows/ci.yml)
5+
6+
Drop-in replacement for [`@jridgewell/remapping`](https://github.com/jridgewell/remapping) and [`@ampproject/remapping`](https://github.com/nicolo-ribaudo/remapping) powered by Rust via WebAssembly.
7+
8+
Same API, same types, same behavior. Swap the import and get source map composition backed by Rust under the hood.
9+
10+
## Install
11+
12+
```bash
13+
npm install @srcmap/remapping
14+
```
15+
16+
## Usage
17+
18+
```js
19+
// Before:
20+
// import remapping from '@jridgewell/remapping'
21+
// import remapping from '@ampproject/remapping'
22+
23+
// After:
24+
import remapping from '@srcmap/remapping'
25+
26+
// Remap a single source map through a loader
27+
const composed = remapping(minifiedMap, (sourcefile) => {
28+
// Return the upstream source map for this file, or null
29+
return upstreamMaps[sourcefile] ?? null
30+
})
31+
32+
console.log(composed.sources) // Original sources
33+
console.log(composed.mappings) // Composed VLQ mappings
34+
console.log(composed.toString()) // JSON string
35+
```
36+
37+
### Compose an array of source maps
38+
39+
```js
40+
// When you have the full chain: [minified map, intermediate map, original map]
41+
const composed = remapping([minifiedMap, intermediateMap], (sourcefile) => {
42+
return upstreamMaps[sourcefile] ?? null
43+
})
44+
```
45+
46+
### Options
47+
48+
```js
49+
const composed = remapping(minifiedMap, loader, {
50+
excludeContent: true, // Omit sourcesContent from the output
51+
})
52+
```
53+
54+
## API compatibility
55+
56+
| Export | Description |
57+
|--------|-------------|
58+
| `remapping(input, loader, options?)` | Remap a single source map through a loader |
59+
| `remapping(inputs[], loader, options?)` | Compose an array of source maps |
60+
| `SourceMap` | Result class with `version`, `file`, `mappings`, `sources`, `sourcesContent`, `names`, `ignoreList` |
61+
62+
The `loader` function receives a source filename and should return the upstream source map (as a JSON string, parsed object, or decoded source map), or `null` if no upstream map exists.
63+
64+
### SourceMap result
65+
66+
| Property / Method | Type | Description |
67+
|--------|------|-------------|
68+
| `version` | `number` | Source map version (always 3) |
69+
| `file` | `string \| undefined` | Output filename |
70+
| `mappings` | `string` | VLQ-encoded mappings |
71+
| `sources` | `(string \| null)[]` | Source filenames |
72+
| `sourcesContent` | `(string \| null)[] \| undefined` | Inline source contents |
73+
| `names` | `string[]` | Name strings |
74+
| `ignoreList` | `number[] \| undefined` | Indices of ignored sources |
75+
| `toString()` | `string` | Serialize as JSON string |
76+
| `toJSON()` | `RawSourceMap` | Return as parsed object |
77+
78+
## Differences from @jridgewell/remapping
79+
80+
- **WASM-powered**: Composition runs in Rust via WebAssembly
81+
- **Indexed source maps**: Handled natively (no JS-side flattening)
82+
83+
## Part of [srcmap](https://github.com/BartWaardenburg/srcmap)
84+
85+
High-performance source map tooling written in Rust. See also:
86+
- [`@srcmap/trace-mapping`](https://www.npmjs.com/package/@srcmap/trace-mapping) - Drop-in for `@jridgewell/trace-mapping` (consumer)
87+
- [`@srcmap/gen-mapping`](https://www.npmjs.com/package/@srcmap/gen-mapping) - Drop-in for `@jridgewell/gen-mapping` (generator)
88+
- [`@srcmap/remapping-wasm`](https://www.npmjs.com/package/@srcmap/remapping-wasm) - Lower-level WASM remapping API
89+
90+
## License
91+
92+
MIT

packages/source-map/README.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# @srcmap/source-map
2+
3+
[![npm](https://img.shields.io/npm/v/@srcmap/source-map.svg)](https://www.npmjs.com/package/@srcmap/source-map)
4+
[![CI](https://github.com/BartWaardenburg/srcmap/actions/workflows/ci.yml/badge.svg)](https://github.com/BartWaardenburg/srcmap/actions/workflows/ci.yml)
5+
6+
Drop-in replacement for [Mozilla's `source-map`](https://github.com/nicolo-ribaudo/source-map-js) v0.6 API powered by Rust via WebAssembly.
7+
8+
Same `SourceMapConsumer` and `SourceMapGenerator` classes, same behavior. Swap the import and get source map operations backed by Rust under the hood.
9+
10+
## Install
11+
12+
```bash
13+
npm install @srcmap/source-map
14+
```
15+
16+
## Usage
17+
18+
### Consumer
19+
20+
```js
21+
// Before:
22+
// import { SourceMapConsumer } from 'source-map'
23+
24+
// After:
25+
import { SourceMapConsumer } from '@srcmap/source-map'
26+
27+
const consumer = new SourceMapConsumer(sourceMapJsonOrObject)
28+
29+
const pos = consumer.originalPositionFor({ line: 43, column: 10 })
30+
// { source: 'src/app.ts', line: 11, column: 4, name: 'handleClick' }
31+
32+
const content = consumer.sourceContentFor('src/app.ts')
33+
34+
consumer.eachMapping((mapping) => {
35+
console.log(mapping.generatedLine, mapping.generatedColumn)
36+
})
37+
38+
// Cleanup WASM memory
39+
consumer.destroy()
40+
```
41+
42+
### Generator
43+
44+
```js
45+
import { SourceMapGenerator } from '@srcmap/source-map'
46+
47+
const generator = new SourceMapGenerator({ file: 'bundle.js' })
48+
49+
generator.addMapping({
50+
generated: { line: 1, column: 0 },
51+
source: 'src/app.ts',
52+
original: { line: 10, column: 4 },
53+
name: 'handleClick',
54+
})
55+
56+
generator.setSourceContent('src/app.ts', sourceCode)
57+
58+
const json = generator.toJSON()
59+
const str = generator.toString()
60+
61+
generator.destroy()
62+
```
63+
64+
## API compatibility
65+
66+
### SourceMapConsumer
67+
68+
| Method / Property | Description |
69+
|--------|-------------|
70+
| `originalPositionFor(needle)` | Forward lookup (1-based lines, 0-based columns) |
71+
| `generatedPositionFor(needle)` | Reverse lookup |
72+
| `eachMapping(callback)` | Iterate all mappings in generated order |
73+
| `sourceContentFor(source)` | Get source content for a file |
74+
| `sources` | Resolved source file URLs |
75+
| `sourcesContent` | Inline source contents |
76+
| `file` | Output filename |
77+
| `sourceRoot` | Source root prefix |
78+
| `destroy()` | Free WASM resources |
79+
| `GREATEST_LOWER_BOUND` / `LEAST_UPPER_BOUND` | Search bias constants |
80+
81+
### SourceMapGenerator
82+
83+
| Method | Description |
84+
|--------|-------------|
85+
| `addMapping(mapping)` | Add a mapping (object-based API) |
86+
| `setSourceContent(source, content)` | Set source content for a file |
87+
| `applySourceMap(consumer, source?, path?)` | Apply a consumer's mappings to this generator |
88+
| `toJSON()` | Return as parsed source map object |
89+
| `toString()` | Return as JSON string |
90+
| `destroy()` | Free WASM resources |
91+
92+
## Differences from Mozilla source-map
93+
94+
- **Synchronous API**: No `SourceMapConsumer.with()` or promise-based initialization — construction is synchronous
95+
- **WASM memory**: Call `consumer.destroy()` / `generator.destroy()` when done to free WASM memory
96+
- **Indexed source maps**: Handled natively by the WASM engine
97+
98+
## Part of [srcmap](https://github.com/BartWaardenburg/srcmap)
99+
100+
High-performance source map tooling written in Rust. See also:
101+
- [`@srcmap/trace-mapping`](https://www.npmjs.com/package/@srcmap/trace-mapping) - Drop-in for `@jridgewell/trace-mapping`
102+
- [`@srcmap/gen-mapping`](https://www.npmjs.com/package/@srcmap/gen-mapping) - Drop-in for `@jridgewell/gen-mapping`
103+
- [`@srcmap/sourcemap-wasm`](https://www.npmjs.com/package/@srcmap/sourcemap-wasm) - Lower-level WASM API (0-based lines)
104+
105+
## License
106+
107+
MIT

0 commit comments

Comments
 (0)