Skip to content

Commit 0abcf5c

Browse files
authored
feat: Add ability to control bundling concurrency (#10)
1 parent f7db78c commit 0abcf5c

File tree

6 files changed

+55
-18
lines changed

6 files changed

+55
-18
lines changed

package-lock.json

Lines changed: 16 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"author": "Kshitij Chauhan",
2020
"license": "ISC",
2121
"dependencies": {
22+
"@supercharge/promise-pool": "^2.1.0",
2223
"@types/command-line-args": "^5.0.0",
2324
"chalk": "^4.1.2",
2425
"command-line-args": "^5.1.1",

src/bundler/esbuild.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,28 @@
1+
import { PromisePool } from "@supercharge/promise-pool";
12
import { build, BuildOptions } from "esbuild";
23
import { err, ok, Result } from "neverthrow";
34
import logger from "../logger";
45
import { BundleResult } from "./bundleResult";
56

7+
export type BundlerConfig = BuildOptions & {
8+
concurrency?: number;
9+
};
10+
611
export default async function bundleFunctions(
712
functions: Record<string, string>,
8-
bundlerConfig?: BuildOptions,
13+
bundlerConfig?: BundlerConfig,
914
): Promise<Result<BundleResult[], Error>> {
10-
try {
11-
const bundlePromises = Object.entries(functions).map(([fxName, fxPath]) =>
12-
bundleFunction(fxName, fxPath, bundlerConfig),
13-
);
14-
const bundleResults = await Promise.all(bundlePromises);
15-
return ok(bundleResults);
16-
} catch (error) {
17-
return err(<Error>error);
15+
const { concurrency = Object.keys(functions).length, ...config } = bundlerConfig ?? {};
16+
console.log("Bundling with concurrency", concurrency);
17+
18+
const { errors, results } = await PromisePool.for(Object.entries(functions))
19+
.withConcurrency(concurrency)
20+
.process(([fxName, fxPath]) => bundleFunction(fxName, fxPath, config));
21+
if (errors.length > 0) {
22+
const [error] = errors;
23+
return err(error);
1824
}
25+
return ok(results);
1926
}
2027

2128
export async function bundleFunction(
@@ -35,7 +42,6 @@ export async function bundleFunction(
3542
treeShaking: true,
3643
outdir: "bundled",
3744
...bundlerConfig,
38-
3945
write: false,
4046
});
4147

src/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
import chalk from "chalk";
44
import { bundleFunctions } from "./bundler";
5+
import { BundlerConfig } from "./bundler/esbuild";
56
import hashesDiffer from "./differ/differ";
67
import calculateHash from "./hasher/hasher";
78
import segregate from "./hasher/segregate";
89
import logger from "./logger";
9-
import { bundlerConfigFilePath, dir, prefix, separator, specFilePath, write } from "./options/options";
10+
import { bundlerConfigFilePath, concurrency, dir, prefix, separator, specFilePath, write } from "./options/options";
1011
import DifferSpec from "./parser/differSpec";
1112
import parseSpecFile, { parseBundlerConfigFile, resolveFunctionPaths } from "./parser/parser";
1213
import writeSpec from "./parser/writer";
@@ -24,7 +25,10 @@ async function main() {
2425
logger.error(bundlerConfigSpecResult.error);
2526
return;
2627
}
27-
const bundlerConfig = bundlerConfigSpecResult.value;
28+
const bundlerConfig: BundlerConfig = {
29+
...bundlerConfigSpecResult.value,
30+
concurrency,
31+
};
2832

2933
const { functions, hashes: existingHashes } = specResult.value;
3034
logger.info(`Discovered ${Object.keys(functions).length} functions`);

src/options/options.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { expect } from "chai";
2+
import commandLineArgs from "command-line-args";
3+
import { options } from "./options";
4+
5+
describe("options parsing", () => {
6+
it("should parse concurrency arg correctly", () => {
7+
const cmd = "functions-differ --concurrency 10";
8+
const { concurrency } = commandLineArgs(options, { argv: cmd.split(" "), partial: true });
9+
expect(concurrency).to.equal(10);
10+
});
11+
});

src/options/options.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import cmdArgs, { OptionDefinition } from "command-line-args";
22
import path from "path";
33

4-
const options: OptionDefinition[] = [
4+
export const options: OptionDefinition[] = [
55
{ name: "dir", alias: "d", type: String, defaultValue: process.cwd() },
66
{ name: "write", alias: "w", type: Boolean, defaultValue: true },
77
{ name: "verbose", alias: "v", type: Boolean, defaultValue: false },
88
{ name: "prefix", type: String, defaultValue: "functions:" },
99
{ name: "sep", type: String, defaultValue: "," },
10-
{ name: "bundlerConfig", type: String, defaultValue: "" }
10+
{ name: "bundlerConfig", type: String, defaultValue: "" },
11+
{ name: "concurrency", type: Number },
1112
];
1213

1314
const args = cmdArgs(options, { partial: true });
14-
const { dir, write, verbose, prefix, sep: separator, bundlerConfig } = args;
15+
const { dir, write, verbose, prefix, sep: separator, bundlerConfig, concurrency } = args;
1516
if (!dir) {
1617
console.error("Error: dir argument not supplied");
1718
process.exit(1);
@@ -20,4 +21,4 @@ if (!dir) {
2021
const specFilePath: string = path.join(dir, ".differspec.json");
2122
const bundlerConfigFilePath: string = bundlerConfig ? path.join(dir, bundlerConfig) : "";
2223

23-
export { specFilePath, dir, write, verbose, prefix, separator, bundlerConfigFilePath };
24+
export { specFilePath, dir, write, verbose, prefix, separator, bundlerConfigFilePath, concurrency };

0 commit comments

Comments
 (0)