UNPKG

magic-string-stack

Version:

magic-string with the capability of committing changes

101 lines (98 loc) 3.17 kB
import remapping from '@ampproject/remapping'; import MagicString, { SourceMap } from 'magic-string'; class MagicStringStack { constructor(content, _options) { this._options = _options; this._current = new MagicString(content, this._options); this._stack.unshift(this._current); const proxy = new Proxy(new MagicString(""), { get: (_, p, receiver) => { if (Reflect.has(this, p)) return Reflect.get(this, p, receiver); const parent = Reflect.get(this._current, p, receiver); if (typeof parent === "function") { return (...args) => { const result = parent.apply(this._current, args); if (result === this._current) return proxy; return result; }; } return parent; }, set: (_, p, value) => { if (Reflect.has(this, p)) return Reflect.set(this, p, value, this); return Reflect.set(this._current, p, value); } }); return proxy; } /** * The stack of MagicString instances. * Lastest instance is pushed to the front of the array. */ _stack = []; /** * Prepresents the current MagicString instance. * It should be in the this._stack[0] */ _current; /** * Commit current changes and reset the `.original` property and the indices. * * When running `generateMap`, the sourcemaps will be generated and merged into a single sourcemap. */ commit() { const newOne = new MagicString(this._current.toString(), this._options); newOne.offset = this._current.offset; this._current = newOne; this._stack.unshift(newOne); return this; } /** * Rollback to the previous commit. */ rollback() { if (this._stack.length <= 1) throw new Error("Cannot rollback on the first commit"); this._stack.shift(); this._current = this._stack[0]; return this; } get original() { return this._current.original; } toString() { return this._current.toString(); } clone() { const s = new MagicStringStack(this._current.toString(), this._options); s._stack = this._stack.map((s2) => s2.clone()); s._current = s._stack[0]; return s; } /** * Generates a version 3 sourcemap. */ generateMap(options) { return new SourceMap(this.generateDecodedMap(options)); } /** * Generates a sourcemap object with raw mappings in array form, rather than encoded as a string. * Useful if you need to manipulate the sourcemap further, but most of the time you will use `generateMap` instead. */ generateDecodedMap(options) { if (this._stack.length === 1) return this._current.generateDecodedMap(options); const SOURCE_PLACEHOLDER = "__magic_string_placeholder__.js"; const maps = this._stack.map((s) => s.generateDecodedMap({ source: SOURCE_PLACEHOLDER, ...options })); const merged = remapping(maps, () => null, { decodedMappings: true }); merged.sources = merged.sources.map((source) => source === SOURCE_PLACEHOLDER ? "" : source); delete merged.version; return { ...merged }; } } export { MagicStringStack as default };