diff --git a/src/helpers.ts b/src/helpers.ts index 84a2ca92..c5d6c2ea 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -1,5 +1,6 @@ import * as path from "path"; import * as fs from "fs"; +import { platform } from "process"; import sharp from "sharp"; import { toIco } from "./ico"; import { FaviconImage } from "./index"; @@ -90,7 +91,7 @@ export async function sourceImages( if (!src.length) { throw new Error("No source provided"); } - const images = await Promise.all(src.map(sourceImages)); + const images = await mapAsync(src, sourceImages); return images.flat(); } else { @@ -244,14 +245,12 @@ export class Images { const properties = flattenIconOptions(iconOptions); if (path.extname(name) === ".ico" || properties.length !== 1) { - const images = await Promise.all( - properties.map((props) => - this.createPlaneFavicon( - sourceset, - props, - `${props.width}x${props.height}.rawdata`, - true - ) + const images = await mapAsync(properties, (props) => + this.createPlaneFavicon( + sourceset, + props, + `${props.width}x${props.height}.rawdata`, + true ) ); const contents = toIco(images.map((image) => image.contents as RawImage)); @@ -265,3 +264,21 @@ export class Images { return await this.createPlaneFavicon(sourceset, properties[0], name, false); } } + +export async function mapAsync( + inputs: T[], + computation: (input: T, index: number) => Promise +): Promise { + if (platform === "win32") { + // run sequentially + const result: U[] = []; + let index = 0; + for (const input of inputs) { + result.push(await computation(input, index)); + index++; + } + return result; + } else { + return await Promise.all(inputs.map(computation)); + } +} diff --git a/src/platforms/android.ts b/src/platforms/android.ts index 35972235..d2b9ba80 100644 --- a/src/platforms/android.ts +++ b/src/platforms/android.ts @@ -5,6 +5,7 @@ import { maskable, transparentIcon } from "../config/icons"; import { Dictionary, Images, + mapAsync, relativeTo, SourceImage, sourceImages, @@ -69,10 +70,10 @@ export class AndroidPlatform extends Platform { async createImages(sourceset: SourceImage[]): Promise { const images = new Images(); - let icons = await Promise.all( - Object.entries(this.iconOptions).map(([iconName, iconOption]) => + let icons = await mapAsync( + Object.entries(this.iconOptions), + ([iconName, iconOption]) => images.createFavicon(sourceset, iconName, iconOption) - ) ); // Generate android maskable images from a different source set @@ -84,10 +85,10 @@ export class AndroidPlatform extends Platform { this.options.manifestMaskable ); - const maskable = await Promise.all( - Object.entries(ICONS_OPTIONS_MASKABLE).map(([iconName, iconOption]) => + const maskable = await mapAsync( + Object.entries(ICONS_OPTIONS_MASKABLE), + ([iconName, iconOption]) => images.createFavicon(maskableSourceset, iconName, iconOption) - ) ); icons = [...icons, ...maskable]; @@ -122,20 +123,21 @@ export class AndroidPlatform extends Platform { private async shortcutIcons(): Promise { const images = new Images(); - const icons = await Promise.all( - this.options.shortcuts.map(async (shortcut, index) => { + const icons = await mapAsync( + this.options.shortcuts, + async (shortcut, index) => { if (!shortcut.name || !shortcut.url || !shortcut.icon) return null; const shortcutSourceset = await sourceImages(shortcut.icon); - return Promise.all( - Object.entries(SHORTCUT_ICONS_OPTIONS).map(([shortcutName, option]) => + return await mapAsync( + Object.entries(SHORTCUT_ICONS_OPTIONS), + ([shortcutName, option]) => images.createFavicon( shortcutSourceset, `shortcut${index + 1}-${shortcutName}`, option ) - ) ); - }) + } ); return icons.flat(); } diff --git a/src/platforms/base.ts b/src/platforms/base.ts index 5a218061..a81c1a31 100644 --- a/src/platforms/base.ts +++ b/src/platforms/base.ts @@ -11,6 +11,7 @@ import { filterKeys, Images, mapValues, + mapAsync, relativeTo, SourceImage, } from "../helpers"; @@ -62,10 +63,10 @@ export class Platform { async createImages(sourceset: SourceImage[]): Promise { const images = new Images(); - return await Promise.all( - Object.entries(this.iconOptions).map(([iconName, iconOption]) => + return await mapAsync( + Object.entries(this.iconOptions), + ([iconName, iconOption]) => images.createFavicon(sourceset, iconName, iconOption) - ) ); }