diff options
author | 2020-11-16 00:10:28 +0100 | |
---|---|---|
committer | 2020-11-16 00:10:28 +0100 | |
commit | e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d (patch) | |
tree | 55713f725f77b44ebfec86e4eec3ce33e71458ca /node_modules/webpack/lib/ChunkGroup.js | |
download | website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.tar.gz website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.tar.bz2 website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.zip |
api, login, auth
Diffstat (limited to 'node_modules/webpack/lib/ChunkGroup.js')
-rw-r--r-- | node_modules/webpack/lib/ChunkGroup.js | 513 |
1 files changed, 513 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/ChunkGroup.js b/node_modules/webpack/lib/ChunkGroup.js new file mode 100644 index 0000000..6f0ad97 --- /dev/null +++ b/node_modules/webpack/lib/ChunkGroup.js @@ -0,0 +1,513 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const SortableSet = require("./util/SortableSet"); +const compareLocations = require("./compareLocations"); + +/** @typedef {import("./Chunk")} Chunk */ +/** @typedef {import("./Module")} Module */ +/** @typedef {import("./ModuleReason")} ModuleReason */ + +/** @typedef {{module: Module, loc: TODO, request: string}} OriginRecord */ +/** @typedef {string|{name: string}} ChunkGroupOptions */ + +let debugId = 5000; + +/** + * @template T + * @param {SortableSet<T>} set set to convert to array. + * @returns {T[]} the array format of existing set + */ +const getArray = set => Array.from(set); + +/** + * A convenience method used to sort chunks based on their id's + * @param {ChunkGroup} a first sorting comparator + * @param {ChunkGroup} b second sorting comparator + * @returns {1|0|-1} a sorting index to determine order + */ +const sortById = (a, b) => { + if (a.id < b.id) return -1; + if (b.id < a.id) return 1; + return 0; +}; + +/** + * @param {OriginRecord} a the first comparator in sort + * @param {OriginRecord} b the second comparator in sort + * @returns {1|-1|0} returns sorting order as index + */ +const sortOrigin = (a, b) => { + const aIdent = a.module ? a.module.identifier() : ""; + const bIdent = b.module ? b.module.identifier() : ""; + if (aIdent < bIdent) return -1; + if (aIdent > bIdent) return 1; + return compareLocations(a.loc, b.loc); +}; + +class ChunkGroup { + /** + * Creates an instance of ChunkGroup. + * @param {ChunkGroupOptions=} options chunk group options passed to chunkGroup + */ + constructor(options) { + if (typeof options === "string") { + options = { name: options }; + } else if (!options) { + options = { name: undefined }; + } + /** @type {number} */ + this.groupDebugId = debugId++; + this.options = options; + /** @type {SortableSet<ChunkGroup>} */ + this._children = new SortableSet(undefined, sortById); + this._parents = new SortableSet(undefined, sortById); + this._blocks = new SortableSet(); + /** @type {Chunk[]} */ + this.chunks = []; + /** @type {OriginRecord[]} */ + this.origins = []; + /** Indices in top-down order */ + /** @private @type {Map<Module, number>} */ + this._moduleIndices = new Map(); + /** Indices in bottom-up order */ + /** @private @type {Map<Module, number>} */ + this._moduleIndices2 = new Map(); + } + + /** + * when a new chunk is added to a chunkGroup, addingOptions will occur. + * @param {ChunkGroupOptions} options the chunkGroup options passed to addOptions + * @returns {void} + */ + addOptions(options) { + for (const key of Object.keys(options)) { + if (this.options[key] === undefined) { + this.options[key] = options[key]; + } else if (this.options[key] !== options[key]) { + if (key.endsWith("Order")) { + this.options[key] = Math.max(this.options[key], options[key]); + } else { + throw new Error( + `ChunkGroup.addOptions: No option merge strategy for ${key}` + ); + } + } + } + } + + /** + * returns the name of current ChunkGroup + * @returns {string|undefined} returns the ChunkGroup name + */ + get name() { + return this.options.name; + } + + /** + * sets a new name for current ChunkGroup + * @param {string} value the new name for ChunkGroup + * @returns {void} + */ + set name(value) { + this.options.name = value; + } + + /** + * get a uniqueId for ChunkGroup, made up of its member Chunk debugId's + * @returns {string} a unique concatenation of chunk debugId's + */ + get debugId() { + return Array.from(this.chunks, x => x.debugId).join("+"); + } + + /** + * get a unique id for ChunkGroup, made up of its member Chunk id's + * @returns {string} a unique concatenation of chunk ids + */ + get id() { + return Array.from(this.chunks, x => x.id).join("+"); + } + + /** + * Performs an unshift of a specific chunk + * @param {Chunk} chunk chunk being unshifted + * @returns {boolean} returns true if attempted chunk shift is accepted + */ + unshiftChunk(chunk) { + const oldIdx = this.chunks.indexOf(chunk); + if (oldIdx > 0) { + this.chunks.splice(oldIdx, 1); + this.chunks.unshift(chunk); + } else if (oldIdx < 0) { + this.chunks.unshift(chunk); + return true; + } + return false; + } + + /** + * inserts a chunk before another existing chunk in group + * @param {Chunk} chunk Chunk being inserted + * @param {Chunk} before Placeholder/target chunk marking new chunk insertion point + * @returns {boolean} return true if insertion was successful + */ + insertChunk(chunk, before) { + const oldIdx = this.chunks.indexOf(chunk); + const idx = this.chunks.indexOf(before); + if (idx < 0) { + throw new Error("before chunk not found"); + } + if (oldIdx >= 0 && oldIdx > idx) { + this.chunks.splice(oldIdx, 1); + this.chunks.splice(idx, 0, chunk); + } else if (oldIdx < 0) { + this.chunks.splice(idx, 0, chunk); + return true; + } + return false; + } + + /** + * add a chunk into ChunkGroup. Is pushed on or prepended + * @param {Chunk} chunk chunk being pushed into ChunkGroupS + * @returns {boolean} returns true if chunk addition was successful. + */ + pushChunk(chunk) { + const oldIdx = this.chunks.indexOf(chunk); + if (oldIdx >= 0) { + return false; + } + this.chunks.push(chunk); + return true; + } + + /** + * @param {Chunk} oldChunk chunk to be replaced + * @param {Chunk} newChunk New chunk that will be replaced with + * @returns {boolean} returns true if the replacement was successful + */ + replaceChunk(oldChunk, newChunk) { + const oldIdx = this.chunks.indexOf(oldChunk); + if (oldIdx < 0) return false; + const newIdx = this.chunks.indexOf(newChunk); + if (newIdx < 0) { + this.chunks[oldIdx] = newChunk; + return true; + } + if (newIdx < oldIdx) { + this.chunks.splice(oldIdx, 1); + return true; + } else if (newIdx !== oldIdx) { + this.chunks[oldIdx] = newChunk; + this.chunks.splice(newIdx, 1); + return true; + } + } + + removeChunk(chunk) { + const idx = this.chunks.indexOf(chunk); + if (idx >= 0) { + this.chunks.splice(idx, 1); + return true; + } + return false; + } + + isInitial() { + return false; + } + + addChild(chunk) { + if (this._children.has(chunk)) { + return false; + } + this._children.add(chunk); + return true; + } + + getChildren() { + return this._children.getFromCache(getArray); + } + + getNumberOfChildren() { + return this._children.size; + } + + get childrenIterable() { + return this._children; + } + + removeChild(chunk) { + if (!this._children.has(chunk)) { + return false; + } + + this._children.delete(chunk); + chunk.removeParent(this); + return true; + } + + addParent(parentChunk) { + if (!this._parents.has(parentChunk)) { + this._parents.add(parentChunk); + return true; + } + return false; + } + + getParents() { + return this._parents.getFromCache(getArray); + } + + setParents(newParents) { + this._parents.clear(); + for (const p of newParents) { + this._parents.add(p); + } + } + + getNumberOfParents() { + return this._parents.size; + } + + hasParent(parent) { + return this._parents.has(parent); + } + + get parentsIterable() { + return this._parents; + } + + removeParent(chunk) { + if (this._parents.delete(chunk)) { + chunk.removeChunk(this); + return true; + } + return false; + } + + /** + * @returns {Array} - an array containing the blocks + */ + getBlocks() { + return this._blocks.getFromCache(getArray); + } + + getNumberOfBlocks() { + return this._blocks.size; + } + + hasBlock(block) { + return this._blocks.has(block); + } + + get blocksIterable() { + return this._blocks; + } + + addBlock(block) { + if (!this._blocks.has(block)) { + this._blocks.add(block); + return true; + } + return false; + } + + addOrigin(module, loc, request) { + this.origins.push({ + module, + loc, + request + }); + } + + containsModule(module) { + for (const chunk of this.chunks) { + if (chunk.containsModule(module)) return true; + } + return false; + } + + getFiles() { + const files = new Set(); + + for (const chunk of this.chunks) { + for (const file of chunk.files) { + files.add(file); + } + } + + return Array.from(files); + } + + /** + * @param {string=} reason reason for removing ChunkGroup + * @returns {void} + */ + remove(reason) { + // cleanup parents + for (const parentChunkGroup of this._parents) { + // remove this chunk from its parents + parentChunkGroup._children.delete(this); + + // cleanup "sub chunks" + for (const chunkGroup of this._children) { + /** + * remove this chunk as "intermediary" and connect + * it "sub chunks" and parents directly + */ + // add parent to each "sub chunk" + chunkGroup.addParent(parentChunkGroup); + // add "sub chunk" to parent + parentChunkGroup.addChild(chunkGroup); + } + } + + /** + * we need to iterate again over the children + * to remove this from the child's parents. + * This can not be done in the above loop + * as it is not guaranteed that `this._parents` contains anything. + */ + for (const chunkGroup of this._children) { + // remove this as parent of every "sub chunk" + chunkGroup._parents.delete(this); + } + + // cleanup blocks + for (const block of this._blocks) { + block.chunkGroup = null; + } + + // remove chunks + for (const chunk of this.chunks) { + chunk.removeGroup(this); + } + } + + sortItems() { + this.origins.sort(sortOrigin); + this._parents.sort(); + this._children.sort(); + } + + /** + * Sorting predicate which allows current ChunkGroup to be compared against another. + * Sorting values are based off of number of chunks in ChunkGroup. + * + * @param {ChunkGroup} otherGroup the chunkGroup to compare this against + * @returns {-1|0|1} sort position for comparison + */ + compareTo(otherGroup) { + if (this.chunks.length > otherGroup.chunks.length) return -1; + if (this.chunks.length < otherGroup.chunks.length) return 1; + const a = this.chunks[Symbol.iterator](); + const b = otherGroup.chunks[Symbol.iterator](); + // eslint-disable-next-line no-constant-condition + while (true) { + const aItem = a.next(); + const bItem = b.next(); + if (aItem.done) return 0; + const cmp = aItem.value.compareTo(bItem.value); + if (cmp !== 0) return cmp; + } + } + + getChildrenByOrders() { + const lists = new Map(); + for (const childGroup of this._children) { + // TODO webpack 5 remove this check for options + if (typeof childGroup.options === "object") { + for (const key of Object.keys(childGroup.options)) { + if (key.endsWith("Order")) { + const name = key.substr(0, key.length - "Order".length); + let list = lists.get(name); + if (list === undefined) { + lists.set(name, (list = [])); + } + list.push({ + order: childGroup.options[key], + group: childGroup + }); + } + } + } + } + const result = Object.create(null); + for (const [name, list] of lists) { + list.sort((a, b) => { + const cmp = b.order - a.order; + if (cmp !== 0) return cmp; + // TODO webpack 5 remove this check of compareTo + if (a.group.compareTo) { + return a.group.compareTo(b.group); + } + return 0; + }); + result[name] = list.map(i => i.group); + } + return result; + } + + /** + * Sets the top-down index of a module in this ChunkGroup + * @param {Module} module module for which the index should be set + * @param {number} index the index of the module + * @returns {void} + */ + setModuleIndex(module, index) { + this._moduleIndices.set(module, index); + } + + /** + * Gets the top-down index of a module in this ChunkGroup + * @param {Module} module the module + * @returns {number} index + */ + getModuleIndex(module) { + return this._moduleIndices.get(module); + } + + /** + * Sets the bottom-up index of a module in this ChunkGroup + * @param {Module} module module for which the index should be set + * @param {number} index the index of the module + * @returns {void} + */ + setModuleIndex2(module, index) { + this._moduleIndices2.set(module, index); + } + + /** + * Gets the bottom-up index of a module in this ChunkGroup + * @param {Module} module the module + * @returns {number} index + */ + getModuleIndex2(module) { + return this._moduleIndices2.get(module); + } + + checkConstraints() { + const chunk = this; + for (const child of chunk._children) { + if (!child._parents.has(chunk)) { + throw new Error( + `checkConstraints: child missing parent ${chunk.debugId} -> ${child.debugId}` + ); + } + } + for (const parentChunk of chunk._parents) { + if (!parentChunk._children.has(chunk)) { + throw new Error( + `checkConstraints: parent missing child ${parentChunk.debugId} <- ${chunk.debugId}` + ); + } + } + } +} + +module.exports = ChunkGroup; |