generateImportObject = (
	chunkGraph,
	module,
	mangle,
	declarations,
	runtime
) => {
	const moduleGraph = chunkGraph.moduleGraph;
	/** @type {Map<string, string | number>} */
	const waitForInstances = new Map();
	const properties = [];
	const usedWasmDependencies = WebAssemblyUtils.getUsedDependencies(
		moduleGraph,
		module,
		mangle
	);
	for (const usedDep of usedWasmDependencies) {
		const dep = usedDep.dependency;
		const importedModule = moduleGraph.getModule(dep);
		const exportName = dep.name;
		const usedName =
			importedModule &&
			moduleGraph
				.getExportsInfo(importedModule)
				.getUsedName(exportName, runtime);
		const description = dep.description;
		const direct = dep.onlyDirectImport;

		const module = usedDep.module;
		const name = usedDep.name;

		if (direct) {
			const instanceVar = `m${waitForInstances.size}`;
			waitForInstances.set(
				instanceVar,
				/** @type {ModuleId} */
				(chunkGraph.getModuleId(/** @type {Module} */ (importedModule)))
			);
			properties.push({
				module,
				name,
				value: `${instanceVar}[${JSON.stringify(usedName)}]`
			});
		} else {
			const params =
				/** @type {Signature} */
				(description.signature).params.map(
					(param, k) => `p${k}${param.valtype}`
				);

			const mod = `${RuntimeGlobals.moduleCache}[${JSON.stringify(
				chunkGraph.getModuleId(/** @type {Module} */ (importedModule))
			)}]`;
			const modExports = `${mod}.exports`;

			const cache = `wasmImportedFuncCache${declarations.length}`;
			declarations.push(`var ${cache};`);

			const modCode =
				/** @type {Module} */
				(importedModule).type.startsWith("webassembly")
					? `${mod} ? ${modExports}[${JSON.stringify(usedName)}] : `
					: "";

			properties.push({
				module,
				name,
				value: Template.asString([
					`${modCode}function(${params}) {`,
					Template.indent([
						`if(${cache} === undefined) ${cache} = ${modExports};`,
						`return ${cache}[${JSON.stringify(usedName)}](${params});`
					]),
					"}"
				])
			});
		}
	}

	let importObject;
	if (mangle) {
		importObject = [
			"return {",
			Template.indent([
				properties.map(p => `${JSON.stringify(p.name)}: ${p.value}`).join(",\n")
			]),
			"};"
		];
	} else {
		/** @type {Map<string, Array<{ name: string, value: string }>>} */
		const propertiesByModule = new Map();
		for (const p of properties) {
			let list = propertiesByModule.get(p.module);
			if (list === undefined) {
				propertiesByModule.set(p.module, (list = []));
			}
			list.push(p);
		}
		importObject = [
			"return {",
			Template.indent([
				Array.from(propertiesByModule, ([module, list]) =>
					Template.asString([
						`${JSON.stringify(module)}: {`,
						Template.indent([
							list.map(p => `${JSON.stringify(p.name)}: ${p.value}`).join(",\n")
						]),
						"}"
					])
				).join(",\n")
			]),
			"};"
		];
	}

	const moduleIdStringified = JSON.stringify(chunkGraph.getModuleId(module));
	if (waitForInstances.size === 1) {
		const moduleId = Array.from(waitForInstances.values())[0];
		const promise = `installedWasmModules[${JSON.stringify(moduleId)}]`;
		const variable = Array.from(waitForInstances.keys())[0];
		return Template.asString([
			`${moduleIdStringified}: function() {`,
			Template.indent([
				`return promiseResolve().then(function() { return ${promise}; }).then(function(${variable}) {`,
				Template.indent(importObject),
				"});"
			]),
			"},"
		]);
	} else if (waitForInstances.size > 0) {
		const promises = Array.from(
			waitForInstances.values(),
			id => `installedWasmModules[${JSON.stringify(id)}]`
		).join(", ");
		const variables = Array.from(
			waitForInstances.keys(),
			(name, i) => `${name} = array[${i}]`
		).join(", ");
		return Template.asString([
			`${moduleIdStringified}: function() {`,
			Template.indent([
				`return promiseResolve().then(function() { return Promise.all([${promises}]); }).then(function(array) {`,
				Template.indent([`var ${variables};`, ...importObject]),
				"});"
			]),
			"},"
		]);
	}
	return Template.asString([
		`${moduleIdStringified}: function() {`,
		Template.indent(importObject),
		"},"
	]);
}
generates the import object function for a module
@param {ChunkGraph} chunkGraph the chunk graph
@param {Module} module the module
@param {boolean | undefined} mangle mangle imports
@param {string[]} declarations array where declarations are pushed to
@param {RuntimeSpec} runtime the runtime
@returns {string} source code