Skip to content

Commit fcfc18b

Browse files
docs: clean up roadmap — remove completed items, keep future work
Remove completed sections: range mappings, streaming composition, ecosystem adoption phases 1-2 (wrapper packages shipped), resolved Rust performance gaps (VLQ encoding, composition, structured output), and completed extended APIs (from_data_url, browser WASM target, ConcatBuilder, applySourceMap). Keep: function name mappings, scopes spec alignment, sources hash, debug ID extraction, mappings v2, env metadata, remaining ecosystem targets.
1 parent c31d408 commit fcfc18b

1 file changed

Lines changed: 6 additions & 164 deletions

File tree

ROADMAP.md

Lines changed: 6 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -2,72 +2,6 @@
22

33
What's next for srcmap, and why.
44

5-
## Range Mappings
6-
7-
**ECMA-426 proposal, Stage 2**[tc39/ecma426#233](https://github.com/nicolo-ribaudo/ecma-426/blob/main/proposals/range-mappings.md)
8-
9-
A new `"rangeMappings"` field that marks certain mappings as covering an entire range, not just a single point. This directly solves precision loss during source map composition — the exact problem Rolldown hits ([rolldown#7555](https://github.com/nicolo-ribaudo/ecma-426/blob/main/proposals/range-mappings.md)).
10-
11-
### Encoding
12-
13-
The `rangeMappings` field uses the same `;`-separated line structure as `mappings`. Each line contains unsigned VLQs encoding **relative offsets** (1-based) to the index of each range mapping on that line. The offset is relative to the previous range mapping index on the same line.
14-
15-
```json
16-
{
17-
"mappings": "AAAA,CAAC,GAAG,...",
18-
"rangeMappings": "ABCgB;;B"
19-
}
20-
```
21-
22-
Decoding `ABCgB` on line 1 gives offsets `[0, 1, 2, 32, 1]`, meaning mappings at indices 0, 1, 3, 35, and 36 are range mappings.
23-
24-
### Lookup behavior
25-
26-
A range mapping maps every position from its generated position up to (but not including) the next mapping. The original position is computed with a delta:
27-
28-
```
29-
lineDelta = lookupLine - mapping.generatedLine
30-
columnDelta = if lineDelta == 0 { lookupColumn - mapping.generatedColumn } else { 0 }
31-
result = OriginalPosition {
32-
line: mapping.originalLine + lineDelta,
33-
column: mapping.originalColumn + columnDelta,
34-
}
35-
```
36-
37-
### Data model change
38-
39-
The `Mapping` struct gains an `is_range_mapping: bool` field (default `false`). On decode, `rangeMappings` is parsed and `is_range_mapping` is set on the referenced mappings. On encode, range mappings are collected and written to `rangeMappings`.
40-
41-
### What to implement
42-
43-
- [x] Decode `rangeMappings` field and set `is_range_mapping` on `Mapping` structs
44-
- [x] Encode `rangeMappings` from `Mapping` structs with `is_range_mapping = true`
45-
- [x] Update `original_position_for` to apply range delta when the matched mapping is a range mapping
46-
- [x] Update `remap()` to preserve and compose range mappings through transform chains
47-
- [x] Generator API: `add_range_mapping()` for marking a mapping as a range
48-
- [x] WASM/NAPI bindings
49-
- [x] CLI: show range mappings in `srcmap info` and `srcmap mappings`
50-
51-
---
52-
53-
## Streaming Source Map Composition
54-
55-
**Ecosystem demand**[rolldown#8632](https://github.com/nicolo-ribaudo/ecma-426/blob/main/proposals/range-mappings.md)
56-
57-
Rolldown's `collapse_sourcemaps` materializes the entire token stream into `Vec<Token>` before constructing the final `SourceMap`. For large bundles with many transform plugins, this causes excessive allocations.
58-
59-
### What to implement
60-
61-
- [x] `MappingsIter`: lazy iterator over VLQ-encoded mappings (decodes one at a time, no `Vec<Mapping>`)
62-
- [x] `StreamingGenerator`: on-the-fly VLQ encoder that emits mappings in sorted order without collecting
63-
- [x] `remap_streaming()`: composition pipeline that streams through mappings without intermediate allocation
64-
- [x] Criterion benchmarks (500 / 10K / 60K mappings) — 15-20% faster than materialized `remap()`
65-
66-
- [x] Builder pattern (`SourceMap::builder()`) that consumes iterators for names/sources/source_contents
67-
- [x] Bundler-scale benchmark (60K mappings across 20 sources, materialized vs streaming)
68-
69-
---
70-
715
## Function Name Mappings
726

737
**ECMA-426, standardized**[bloomberg.github.io/js-blog/post/standardizing-source-maps](https://bloomberg.github.io/js-blog/post/standardizing-source-maps/)
@@ -183,8 +117,6 @@ srcmap already parses `debugId` from source map JSON. What's missing is extracti
183117

184118
---
185119

186-
---
187-
188120
## Mappings v2 Encoding `[Discussion — not implementing yet]`
189121

190122
**ECMA-426 discussion**[tc39/ecma426#155](https://github.com/nicolo-ribaudo/ecma-426/blob/main/proposals/range-mappings.md)
@@ -230,85 +162,15 @@ Environment metadata for source maps. The proposal is minimal at Stage 1 — tra
230162

231163
## Ecosystem Adoption
232164

233-
Based on integration testing across 21 projects. Prioritized by impact and dependency chains.
234-
235-
### Adoption Phase 1: Ship What Already Works
236-
237-
**Commit accumulated bug fixes** found during outreach testing:
238-
- Path normalization (`normalizePath()`) — matches jridgewell's `resolve-uri` behavior
239-
- WASM source name resolution through `resolvedSources` in `originalPositionFor`
240-
- `generatedPositionFor` bias handling (GLB/LUB) and same-line constraint
241-
- `allGeneratedPositionsFor` LUB semantics and result sorting
242-
- Reverse index tie-breaking by generated position
243-
- Decoded mappings stride fix (6→7 for `is_range_mapping`)
244-
- `SectionedSourceMapInput` type and callable `AnyMap` type signature
245-
- Dual CJS/ESM exports for `@srcmap/trace-mapping`
246-
247-
**Publish `@srcmap/trace-mapping` v0.3.0**, then open PRs:
248-
249-
| Project | Stars | Downloads/wk | Test Results | Effort |
250-
|---------|-------|-------------|--------------|--------|
251-
| v8-to-istanbul | 220 | ~8M (via c8/Jest) | 3/3 files, all snapshots match | `package.json` swap |
252-
| Jest | 44k | ~30M | 0 regressions (28 pre-existing) | `package.json` swap |
253-
| Vitest | 14k | ~10M | 600/600 files, 6582 tests | Swap + externalize WASM in 3 Rollup configs |
165+
### Remaining Rust performance gaps
254166

255-
### Adoption Phase 2: Wrapper Packages
167+
| Gap | Severity | Impact |
168+
|-----|----------|--------|
169+
| Serialization overhead | Medium | Rspack |
256170

257-
Three wrapper packages unlock 10+ major projects:
171+
VLQ encoding and composition have been optimized. Serialization may still have room for improvement — profile against rspack-sources to verify.
258172

259-
**`@srcmap/source-map`** — Mozilla `source-map` v0.6 synchronous API compat
260-
- Already prototyped and validated (source-map-support: 33/33 tests pass)
261-
- `SourceMapConsumer`: constructor, `originalPositionFor`, `generatedPositionFor`, `eachMapping`, `sourceContentFor`
262-
- Unlocks: **Next.js** (130k), **PostCSS** (29k), **Terser** (9k), **source-map-support** (3.3k)
263-
264-
**`@srcmap/remapping`**`@ampproject/remapping` API compat
265-
- Default export accepting `(input, loader)` where input is string, object, or array
266-
- Unlocks: **Vite** (71k), **Angular CLI** (27k), **Babel** (43k, also needs gen-mapping)
267-
268-
**`@srcmap/gen-mapping`**`@jridgewell/gen-mapping` API compat
269-
- `GenMapping` constructor, `maybeAddMapping`, `toEncodedMap`, `toDecodedMap`, `setSourceContent`
270-
- Unlocks: **Babel** (43k)
271-
272-
```
273-
trace-mapping v0.3 ──→ Jest PR (44k⭐)
274-
│ Vitest PR (14k⭐)
275-
│ v8-to-istanbul PR (220⭐, 8M dl/wk)
276-
277-
├─→ @srcmap/source-map ──→ Next.js (130k⭐)
278-
│ Terser (9k⭐)
279-
│ source-map-support (3.3k⭐)
280-
│ PostCSS (29k⭐, needs applySourceMap too)
281-
282-
├─→ @srcmap/remapping ───→ Vite (71k⭐)
283-
│ Angular CLI (27k⭐)
284-
│ Babel (43k⭐, needs gen-mapping too)
285-
286-
└─→ @srcmap/gen-mapping ─→ Babel (43k⭐)
287-
```
288-
289-
Total ecosystem reach with Phase 1+2: **~434k GitHub stars** across 10 projects.
290-
291-
### Adoption Phase 3: Rust Performance Gaps
292-
293-
These block adoption in Rust-native tools:
294-
295-
| Gap | Severity | Impact | Details |
296-
|-----|----------|--------|---------|
297-
| VLQ encoding 1.8x slower | High | OXC, SWC, Lightning CSS | Profile + optimize `encode_vlq`, consider SIMD/lookup-table |
298-
| Serialization 2.25x slower | Medium | Rspack | Pre-allocate output buffer, avoid intermediate allocations |
299-
| Composition 8x slower | High | Rolldown | Missing lookup table API for O(1) line/column access |
300-
| No structured SourceMap output | Medium | OXC | Export `SourceMap` struct with typed fields |
301-
302-
### Adoption Phase 4: Extended APIs
303-
304-
| API | Effort | Unlocks |
305-
|-----|--------|---------|
306-
| `ConcatSourceMapBuilder` (Rust) | Medium | OXC (13k) |
307-
| `from_data_url()` / `to_data_url()` (Rust) | Small | Lightning CSS (7k) |
308-
| `fromSourceMap()` / `applySourceMap()` (JS) | Medium | PostCSS (29k) |
309-
| WASM browser target (`--target web`) | Medium | Vitest browser, all browser tools |
310-
311-
### Adoption Phase 5: Long-Term Strategic
173+
### Long-term strategic targets
312174

313175
| Target | Approach | Stars |
314176
|--------|----------|-------|
@@ -317,26 +179,6 @@ These block adoption in Rust-native tools:
317179
| Webpack | Add streaming API matching `StreamChunksOfCombinedSourceMap` pattern | 65k |
318180
| Metro | Low priority — needs multiple wrappers for custom source map extensions | 5.2k |
319181

320-
### Adoption Priority Matrix
321-
322-
| Priority | Item | Effort | Impact |
323-
|----------|------|--------|--------|
324-
| **P0** | Commit bug fixes + publish trace-mapping v0.3 | S ||
325-
| **P0** | PRs to Jest, Vitest, v8-to-istanbul | S | 58k⭐, 48M dl/wk |
326-
| **P1** | `@srcmap/source-map` wrapper | M | 171k⭐ |
327-
| **P1** | `@srcmap/remapping` wrapper | M | 141k⭐ |
328-
| **P1** | WASM browser target | M | All browser tools |
329-
| **P2** | `@srcmap/gen-mapping` wrapper | M | 43k⭐ |
330-
| **P2** | VLQ encoding optimization | M | OXC+SWC+LightningCSS |
331-
| **P2** | Data URL utilities | S | Lightning CSS (7k⭐) |
332-
| **P3** | Serialization performance | M | Rspack (12k⭐) |
333-
| **P3** | Composition performance + lookup table | L | Rolldown (20k⭐) |
334-
| **P3** | Structured SourceMap type + ConcatBuilder | M | OXC (13k⭐) |
335-
| **P3** | `fromSourceMap`/`applySourceMap` | M | PostCSS (29k⭐) |
336-
| **P4** | Node.js benchmarks, Webpack streaming, Metro, Sentry | L | Long-term |
337-
338-
Effort: **S** = days, **M** = 1-2 weeks, **L** = 2+ weeks
339-
340182
---
341183

342184
## Non-goals

0 commit comments

Comments
 (0)