* Flattens the bundle into a single `MagicString`, so the concatenated result can be * processed further with the full `MagicString` API. The returned string's `original` * is the concatenation of every source's `original`, and all existing edits, inserts, * intros, outros and separators ar
()
| 161 | * over; generate the bundle's map before flattening if you need the multi-source mapping. |
| 162 | */ |
| 163 | toMagicString(): MagicString { |
| 164 | const combined = new MagicString(this.sources.map(source => source.content.original).join('')) |
| 165 | |
| 166 | let offset = 0 |
| 167 | let pending = this.intro |
| 168 | let first: Chunk | null = null |
| 169 | let last: Chunk | null = null |
| 170 | const byStart = new Map<number, Chunk>() |
| 171 | const byEnd = new Map<number, Chunk>() |
| 172 | let hasMovedChunks = false |
| 173 | |
| 174 | this.sources.forEach((source, i) => { |
| 175 | const magicString = source.content |
| 176 | const separator = i > 0 |
| 177 | /* v8 ignore next -- addSource always normalizes source.separator */ |
| 178 | ? (source.separator !== undefined ? source.separator : this.separator) |
| 179 | : '' |
| 180 | |
| 181 | // A source with no original contributes only inserted text (its intro, any |
| 182 | // appends, its outro), which has no place in the combined coordinate space, |
| 183 | // so fold it into the text waiting in front of the next real chunk. |
| 184 | if (magicString.original.length === 0) { |
| 185 | pending += separator + magicString.toString() |
| 186 | return |
| 187 | } |
| 188 | |
| 189 | pending += separator + magicString.intro |
| 190 | |
| 191 | let sourceFirst: Chunk | null = null |
| 192 | let previous: Chunk | null = null |
| 193 | let originalChunk: Chunk | null = magicString.firstChunk |
| 194 | while (originalChunk) { |
| 195 | const chunk = originalChunk.clone() |
| 196 | chunk.start += offset |
| 197 | chunk.end += offset |
| 198 | chunk.previous = previous |
| 199 | chunk.next = null |
| 200 | if (previous) |
| 201 | previous.next = chunk |
| 202 | byStart.set(chunk.start, chunk) |
| 203 | byEnd.set(chunk.end, chunk) |
| 204 | sourceFirst ??= chunk |
| 205 | previous = chunk |
| 206 | originalChunk = originalChunk.next |
| 207 | } |
| 208 | const sourceLast = previous! |
| 209 | |
| 210 | sourceFirst!.intro = pending + sourceFirst!.intro |
| 211 | pending = '' |
| 212 | sourceLast.outro += magicString.outro |
| 213 | |
| 214 | if (last) { |
| 215 | last.next = sourceFirst |
| 216 | sourceFirst!.previous = last |
| 217 | } |
| 218 | else { |
| 219 | first = sourceFirst |
| 220 | } |
no test coverage detected