| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 | 
							- /*
 
- 	MIT License http://www.opensource.org/licenses/mit-license.php
 
- 	Author Tobias Koppers @sokra
 
- */
 
- "use strict";
 
- const Source = require("./Source");
 
- const streamAndGetSourceAndMap = require("./helpers/streamAndGetSourceAndMap");
 
- const streamChunksOfRawSource = require("./helpers/streamChunksOfRawSource");
 
- const streamChunksOfSourceMap = require("./helpers/streamChunksOfSourceMap");
 
- const {
 
- 	isDualStringBufferCachingEnabled,
 
- } = require("./helpers/stringBufferUtils");
 
- /** @typedef {import("./Source").HashLike} HashLike */
 
- /** @typedef {import("./Source").MapOptions} MapOptions */
 
- /** @typedef {import("./Source").RawSourceMap} RawSourceMap */
 
- /** @typedef {import("./Source").SourceAndMap} SourceAndMap */
 
- /** @typedef {import("./Source").SourceValue} SourceValue */
 
- /** @typedef {import("./helpers/getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */
 
- /** @typedef {import("./helpers/streamChunks").OnChunk} OnChunk */
 
- /** @typedef {import("./helpers/streamChunks").OnName} OnName */
 
- /** @typedef {import("./helpers/streamChunks").OnSource} OnSource */
 
- /** @typedef {import("./helpers/streamChunks").Options} Options */
 
- /**
 
-  * @typedef {object} BufferedMap
 
-  * @property {number} version version
 
-  * @property {string[]} sources sources
 
-  * @property {string[]} names name
 
-  * @property {string=} sourceRoot source root
 
-  * @property {(Buffer | "")[]=} sourcesContent sources content
 
-  * @property {Buffer=} mappings mappings
 
-  * @property {string} file file
 
-  */
 
- /**
 
-  * @param {null | RawSourceMap} map map
 
-  * @returns {null | BufferedMap} buffered map
 
-  */
 
- const mapToBufferedMap = (map) => {
 
- 	if (typeof map !== "object" || !map) return map;
 
- 	const bufferedMap =
 
- 		/** @type {BufferedMap} */
 
- 		(/** @type {unknown} */ ({ ...map }));
 
- 	if (map.mappings) {
 
- 		bufferedMap.mappings = Buffer.from(map.mappings, "utf8");
 
- 	}
 
- 	if (map.sourcesContent) {
 
- 		bufferedMap.sourcesContent = map.sourcesContent.map(
 
- 			(str) => str && Buffer.from(str, "utf8"),
 
- 		);
 
- 	}
 
- 	return bufferedMap;
 
- };
 
- /**
 
-  * @param {null | BufferedMap} bufferedMap buffered map
 
-  * @returns {null | RawSourceMap} map
 
-  */
 
- const bufferedMapToMap = (bufferedMap) => {
 
- 	if (typeof bufferedMap !== "object" || !bufferedMap) return bufferedMap;
 
- 	const map =
 
- 		/** @type {RawSourceMap} */
 
- 		(/** @type {unknown} */ ({ ...bufferedMap }));
 
- 	if (bufferedMap.mappings) {
 
- 		map.mappings = bufferedMap.mappings.toString("utf8");
 
- 	}
 
- 	if (bufferedMap.sourcesContent) {
 
- 		map.sourcesContent = bufferedMap.sourcesContent.map(
 
- 			(buffer) => buffer && buffer.toString("utf8"),
 
- 		);
 
- 	}
 
- 	return map;
 
- };
 
- /** @typedef {{ map?: null | RawSourceMap, bufferedMap?: null | BufferedMap }} BufferEntry */
 
- /** @typedef {Map<string, BufferEntry>} BufferedMaps */
 
- /**
 
-  * @typedef {object} CachedData
 
-  * @property {boolean=} source source
 
-  * @property {Buffer} buffer buffer
 
-  * @property {number=} size size
 
-  * @property {BufferedMaps} maps maps
 
-  * @property {(string | Buffer)[]=} hash hash
 
-  */
 
- class CachedSource extends Source {
 
- 	/**
 
- 	 * @param {Source | (() => Source)} source source
 
- 	 * @param {CachedData=} cachedData cached data
 
- 	 */
 
- 	constructor(source, cachedData) {
 
- 		super();
 
- 		this._source = source;
 
- 		this._cachedSourceType = cachedData ? cachedData.source : undefined;
 
- 		/**
 
- 		 * @private
 
- 		 * @type {undefined | string}
 
- 		 */
 
- 		this._cachedSource = undefined;
 
- 		this._cachedBuffer = cachedData ? cachedData.buffer : undefined;
 
- 		this._cachedSize = cachedData ? cachedData.size : undefined;
 
- 		/**
 
- 		 * @private
 
- 		 * @type {BufferedMaps}
 
- 		 */
 
- 		this._cachedMaps = cachedData ? cachedData.maps : new Map();
 
- 		this._cachedHashUpdate = cachedData ? cachedData.hash : undefined;
 
- 	}
 
- 	/**
 
- 	 * @returns {CachedData} cached data
 
- 	 */
 
- 	getCachedData() {
 
- 		/** @type {BufferedMaps} */
 
- 		const bufferedMaps = new Map();
 
- 		for (const pair of this._cachedMaps) {
 
- 			const [, cacheEntry] = pair;
 
- 			if (cacheEntry.bufferedMap === undefined) {
 
- 				cacheEntry.bufferedMap = mapToBufferedMap(
 
- 					this._getMapFromCacheEntry(cacheEntry),
 
- 				);
 
- 			}
 
- 			bufferedMaps.set(pair[0], {
 
- 				map: undefined,
 
- 				bufferedMap: cacheEntry.bufferedMap,
 
- 			});
 
- 		}
 
- 		return {
 
- 			// We don't want to cache strings
 
- 			// So if we have a caches sources
 
- 			// create a buffer from it and only store
 
- 			// if it was a Buffer or string
 
- 			buffer: this._cachedSource
 
- 				? this.buffer()
 
- 				: /** @type {Buffer} */ (this._cachedBuffer),
 
- 			source:
 
- 				this._cachedSourceType !== undefined
 
- 					? this._cachedSourceType
 
- 					: typeof this._cachedSource === "string"
 
- 						? true
 
- 						: Buffer.isBuffer(this._cachedSource)
 
- 							? false
 
- 							: undefined,
 
- 			size: this._cachedSize,
 
- 			maps: bufferedMaps,
 
- 			hash: this._cachedHashUpdate,
 
- 		};
 
- 	}
 
- 	originalLazy() {
 
- 		return this._source;
 
- 	}
 
- 	original() {
 
- 		if (typeof this._source === "function") this._source = this._source();
 
- 		return this._source;
 
- 	}
 
- 	/**
 
- 	 * @returns {SourceValue} source
 
- 	 */
 
- 	source() {
 
- 		const source = this._getCachedSource();
 
- 		if (source !== undefined) return source;
 
- 		return (this._cachedSource =
 
- 			/** @type {string} */
 
- 			(this.original().source()));
 
- 	}
 
- 	/**
 
- 	 * @private
 
- 	 * @param {BufferEntry} cacheEntry cache entry
 
- 	 * @returns {null | RawSourceMap} raw source map
 
- 	 */
 
- 	_getMapFromCacheEntry(cacheEntry) {
 
- 		if (cacheEntry.map !== undefined) {
 
- 			return cacheEntry.map;
 
- 		} else if (cacheEntry.bufferedMap !== undefined) {
 
- 			return (cacheEntry.map = bufferedMapToMap(cacheEntry.bufferedMap));
 
- 		}
 
- 		return null;
 
- 	}
 
- 	/**
 
- 	 * @private
 
- 	 * @returns {undefined | string} cached source
 
- 	 */
 
- 	_getCachedSource() {
 
- 		if (this._cachedSource !== undefined) return this._cachedSource;
 
- 		if (this._cachedBuffer && this._cachedSourceType !== undefined) {
 
- 			const value = this._cachedSourceType
 
- 				? this._cachedBuffer.toString("utf8")
 
- 				: this._cachedBuffer;
 
- 			if (isDualStringBufferCachingEnabled()) {
 
- 				this._cachedSource = /** @type {string} */ (value);
 
- 			}
 
- 			return /** @type {string} */ (value);
 
- 		}
 
- 	}
 
- 	/**
 
- 	 * @returns {Buffer} buffer
 
- 	 */
 
- 	buffer() {
 
- 		if (this._cachedBuffer !== undefined) return this._cachedBuffer;
 
- 		if (this._cachedSource !== undefined) {
 
- 			const value = Buffer.isBuffer(this._cachedSource)
 
- 				? this._cachedSource
 
- 				: Buffer.from(this._cachedSource, "utf8");
 
- 			if (isDualStringBufferCachingEnabled()) {
 
- 				this._cachedBuffer = value;
 
- 			}
 
- 			return value;
 
- 		}
 
- 		if (typeof this.original().buffer === "function") {
 
- 			return (this._cachedBuffer = this.original().buffer());
 
- 		}
 
- 		const bufferOrString = this.source();
 
- 		if (Buffer.isBuffer(bufferOrString)) {
 
- 			return (this._cachedBuffer = bufferOrString);
 
- 		}
 
- 		const value = Buffer.from(bufferOrString, "utf8");
 
- 		if (isDualStringBufferCachingEnabled()) {
 
- 			this._cachedBuffer = value;
 
- 		}
 
- 		return value;
 
- 	}
 
- 	/**
 
- 	 * @returns {number} size
 
- 	 */
 
- 	size() {
 
- 		if (this._cachedSize !== undefined) return this._cachedSize;
 
- 		if (this._cachedBuffer !== undefined) {
 
- 			return (this._cachedSize = this._cachedBuffer.length);
 
- 		}
 
- 		const source = this._getCachedSource();
 
- 		if (source !== undefined) {
 
- 			return (this._cachedSize = Buffer.byteLength(source));
 
- 		}
 
- 		return (this._cachedSize = this.original().size());
 
- 	}
 
- 	/**
 
- 	 * @param {MapOptions=} options map options
 
- 	 * @returns {SourceAndMap} source and map
 
- 	 */
 
- 	sourceAndMap(options) {
 
- 		const key = options ? JSON.stringify(options) : "{}";
 
- 		const cacheEntry = this._cachedMaps.get(key);
 
- 		// Look for a cached map
 
- 		if (cacheEntry !== undefined) {
 
- 			// We have a cached map in some representation
 
- 			const map = this._getMapFromCacheEntry(cacheEntry);
 
- 			// Either get the cached source or compute it
 
- 			return { source: this.source(), map };
 
- 		}
 
- 		// Look for a cached source
 
- 		let source = this._getCachedSource();
 
- 		// Compute the map
 
- 		let map;
 
- 		if (source !== undefined) {
 
- 			map = this.original().map(options);
 
- 		} else {
 
- 			// Compute the source and map together.
 
- 			const sourceAndMap = this.original().sourceAndMap(options);
 
- 			source = /** @type {string} */ (sourceAndMap.source);
 
- 			map = sourceAndMap.map;
 
- 			this._cachedSource = source;
 
- 		}
 
- 		this._cachedMaps.set(key, {
 
- 			map,
 
- 			bufferedMap: undefined,
 
- 		});
 
- 		return { source, map };
 
- 	}
 
- 	/**
 
- 	 * @param {Options} options options
 
- 	 * @param {OnChunk} onChunk called for each chunk of code
 
- 	 * @param {OnSource} onSource called for each source
 
- 	 * @param {OnName} onName called for each name
 
- 	 * @returns {GeneratedSourceInfo} generated source info
 
- 	 */
 
- 	streamChunks(options, onChunk, onSource, onName) {
 
- 		const key = options ? JSON.stringify(options) : "{}";
 
- 		if (
 
- 			this._cachedMaps.has(key) &&
 
- 			(this._cachedBuffer !== undefined || this._cachedSource !== undefined)
 
- 		) {
 
- 			const { source, map } = this.sourceAndMap(options);
 
- 			if (map) {
 
- 				return streamChunksOfSourceMap(
 
- 					/** @type {string} */
 
- 					(source),
 
- 					map,
 
- 					onChunk,
 
- 					onSource,
 
- 					onName,
 
- 					Boolean(options && options.finalSource),
 
- 					true,
 
- 				);
 
- 			}
 
- 			return streamChunksOfRawSource(
 
- 				/** @type {string} */
 
- 				(source),
 
- 				onChunk,
 
- 				onSource,
 
- 				onName,
 
- 				Boolean(options && options.finalSource),
 
- 			);
 
- 		}
 
- 		const sourceAndMap = streamAndGetSourceAndMap(
 
- 			this.original(),
 
- 			options,
 
- 			onChunk,
 
- 			onSource,
 
- 			onName,
 
- 		);
 
- 		this._cachedSource = sourceAndMap.source;
 
- 		this._cachedMaps.set(key, {
 
- 			map: /** @type {RawSourceMap} */ (sourceAndMap.map),
 
- 			bufferedMap: undefined,
 
- 		});
 
- 		return sourceAndMap.result;
 
- 	}
 
- 	/**
 
- 	 * @param {MapOptions=} options map options
 
- 	 * @returns {RawSourceMap | null} map
 
- 	 */
 
- 	map(options) {
 
- 		const key = options ? JSON.stringify(options) : "{}";
 
- 		const cacheEntry = this._cachedMaps.get(key);
 
- 		if (cacheEntry !== undefined) {
 
- 			return this._getMapFromCacheEntry(cacheEntry);
 
- 		}
 
- 		const map = this.original().map(options);
 
- 		this._cachedMaps.set(key, {
 
- 			map,
 
- 			bufferedMap: undefined,
 
- 		});
 
- 		return map;
 
- 	}
 
- 	/**
 
- 	 * @param {HashLike} hash hash
 
- 	 * @returns {void}
 
- 	 */
 
- 	updateHash(hash) {
 
- 		if (this._cachedHashUpdate !== undefined) {
 
- 			for (const item of this._cachedHashUpdate) hash.update(item);
 
- 			return;
 
- 		}
 
- 		/** @type {(string | Buffer)[]} */
 
- 		const update = [];
 
- 		/** @type {string | undefined} */
 
- 		let currentString;
 
- 		const tracker = {
 
- 			/**
 
- 			 * @param {string | Buffer} item item
 
- 			 * @returns {void}
 
- 			 */
 
- 			update: (item) => {
 
- 				if (typeof item === "string" && item.length < 10240) {
 
- 					if (currentString === undefined) {
 
- 						currentString = item;
 
- 					} else {
 
- 						currentString += item;
 
- 						if (currentString.length > 102400) {
 
- 							update.push(Buffer.from(currentString));
 
- 							currentString = undefined;
 
- 						}
 
- 					}
 
- 				} else {
 
- 					if (currentString !== undefined) {
 
- 						update.push(Buffer.from(currentString));
 
- 						currentString = undefined;
 
- 					}
 
- 					update.push(item);
 
- 				}
 
- 			},
 
- 		};
 
- 		this.original().updateHash(/** @type {HashLike} */ (tracker));
 
- 		if (currentString !== undefined) {
 
- 			update.push(Buffer.from(currentString));
 
- 		}
 
- 		for (const item of update) hash.update(item);
 
- 		this._cachedHashUpdate = update;
 
- 	}
 
- }
 
- module.exports = CachedSource;
 
 
  |