getInitialModuleChains = (
	module,
	moduleGraph,
	chunkGraph,
	requestShortener
) => {
	const queue = [
		{ head: module, message: module.readableIdentifier(requestShortener) }
	];
	/** @type {Set<string>} */
	const results = new Set();
	/** @type {Set<string>} */
	const incompleteResults = new Set();
	/** @type {Set<Module>} */
	const visitedModules = new Set();

	for (const chain of queue) {
		const { head, message } = chain;
		let final = true;
		/** @type {Set<Module>} */
		const alreadyReferencedModules = new Set();
		for (const connection of moduleGraph.getIncomingConnections(head)) {
			const newHead = connection.originModule;
			if (newHead) {
				if (!chunkGraph.getModuleChunks(newHead).some(c => c.canBeInitial()))
					continue;
				final = false;
				if (alreadyReferencedModules.has(newHead)) continue;
				alreadyReferencedModules.add(newHead);
				const moduleName = newHead.readableIdentifier(requestShortener);
				const detail = connection.explanation
					? ` (${connection.explanation})`
					: "";
				const newMessage = `${moduleName}${detail} --> ${message}`;
				if (visitedModules.has(newHead)) {
					incompleteResults.add(`... --> ${newMessage}`);
					continue;
				}
				visitedModules.add(newHead);
				queue.push({
					head: newHead,
					message: newMessage
				});
			} else {
				final = false;
				const newMessage = connection.explanation
					? `(${connection.explanation}) --> ${message}`
					: message;
				results.add(newMessage);
			}
		}
		if (final) {
			results.add(message);
		}
	}
	for (const result of incompleteResults) {
		results.add(result);
	}
	return Array.from(results);
}
@param {Module} module module to get chains from
@param {ModuleGraph} moduleGraph the module graph
@param {ChunkGraph} chunkGraph the chunk graph
@param {RequestShortener} requestShortener to make readable identifiers
@returns {string[]} all chains to the module