createObjectForExportsInfo = (data, exportsInfo, runtime) => {
	if (exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused)
		return data;
	const isArray = Array.isArray(data);
	/** @type {JsonObject | JsonArray} */
	const reducedData = isArray ? [] : {};
	for (const key of Object.keys(data)) {
		const exportInfo = exportsInfo.getReadOnlyExportInfo(key);
		const used = exportInfo.getUsed(runtime);
		if (used === UsageState.Unused) continue;

		// The real type is `JsonObject | JsonArray`, but typescript doesn't work `Object.keys(['string', 'other-string', 'etc'])` properly
		const newData = /** @type {JsonObject} */ (data)[key];
		const value =
			used === UsageState.OnlyPropertiesUsed &&
			exportInfo.exportsInfo &&
			typeof newData === "object" &&
			newData
				? createObjectForExportsInfo(newData, exportInfo.exportsInfo, runtime)
				: newData;

		const name = /** @type {string} */ (exportInfo.getUsedName(key, runtime));
		/** @type {JsonObject} */
		(reducedData)[name] = value;
	}
	if (isArray) {
		const arrayLengthWhenUsed =
			exportsInfo.getReadOnlyExportInfo("length").getUsed(runtime) !==
			UsageState.Unused
				? data.length
				: undefined;

		let sizeObjectMinusArray = 0;
		const reducedDataLength =
			/** @type {JsonArray} */
			(reducedData).length;
		for (let i = 0; i < reducedDataLength; i++) {
			if (/** @type {JsonArray} */ (reducedData)[i] === undefined) {
				sizeObjectMinusArray -= 2;
			} else {
				sizeObjectMinusArray += `${i}`.length + 3;
			}
		}
		if (arrayLengthWhenUsed !== undefined) {
			sizeObjectMinusArray +=
				`${arrayLengthWhenUsed}`.length +
				8 -
				(arrayLengthWhenUsed - reducedDataLength) * 2;
		}
		if (sizeObjectMinusArray < 0)
			return Object.assign(
				arrayLengthWhenUsed === undefined
					? {}
					: { length: arrayLengthWhenUsed },
				reducedData
			);
		/** @type {number} */
		const generatedLength =
			arrayLengthWhenUsed !== undefined
				? Math.max(arrayLengthWhenUsed, reducedDataLength)
				: reducedDataLength;
		for (let i = 0; i < generatedLength; i++) {
			if (/** @type {JsonArray} */ (reducedData)[i] === undefined) {
				/** @type {JsonArray} */
				(reducedData)[i] = 0;
			}
		}
	}
	return reducedData;
}
@param {JsonObject | JsonArray} data Raw JSON data (always an object or array)
@param {ExportsInfo} exportsInfo exports info
@param {RuntimeSpec} runtime the runtime
@returns {JsonObject | JsonArray} reduced data