ts-repo-utils 3.1.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/functions/index.mjs +2 -1
  2. package/dist/functions/index.mjs.map +1 -1
  3. package/dist/functions/workspace-utils/execute-parallel.d.mts +25 -0
  4. package/dist/functions/workspace-utils/execute-parallel.d.mts.map +1 -0
  5. package/dist/functions/workspace-utils/execute-parallel.mjs +162 -0
  6. package/dist/functions/workspace-utils/execute-parallel.mjs.map +1 -0
  7. package/dist/functions/workspace-utils/get-workspace-packages.d.mts +1 -29
  8. package/dist/functions/workspace-utils/get-workspace-packages.d.mts.map +1 -1
  9. package/dist/functions/workspace-utils/get-workspace-packages.mjs +11 -163
  10. package/dist/functions/workspace-utils/get-workspace-packages.mjs.map +1 -1
  11. package/dist/functions/workspace-utils/index.d.mts +2 -0
  12. package/dist/functions/workspace-utils/index.d.mts.map +1 -1
  13. package/dist/functions/workspace-utils/index.mjs +2 -1
  14. package/dist/functions/workspace-utils/index.mjs.map +1 -1
  15. package/dist/functions/workspace-utils/run-cmd-in-parallel.d.mts.map +1 -1
  16. package/dist/functions/workspace-utils/run-cmd-in-parallel.mjs +2 -1
  17. package/dist/functions/workspace-utils/run-cmd-in-parallel.mjs.map +1 -1
  18. package/dist/functions/workspace-utils/run-cmd-in-stages.d.mts.map +1 -1
  19. package/dist/functions/workspace-utils/run-cmd-in-stages.mjs +2 -1
  20. package/dist/functions/workspace-utils/run-cmd-in-stages.mjs.map +1 -1
  21. package/dist/functions/workspace-utils/types.d.mts +7 -0
  22. package/dist/functions/workspace-utils/types.d.mts.map +1 -0
  23. package/dist/functions/workspace-utils/types.mjs +2 -0
  24. package/dist/functions/workspace-utils/types.mjs.map +1 -0
  25. package/dist/index.mjs +2 -1
  26. package/dist/index.mjs.map +1 -1
  27. package/package.json +7 -8
  28. package/src/functions/workspace-utils/execute-parallel.mts +247 -0
  29. package/src/functions/workspace-utils/get-workspace-packages.mts +12 -251
  30. package/src/functions/workspace-utils/index.mts +2 -0
  31. package/src/functions/workspace-utils/run-cmd-in-parallel.mts +2 -4
  32. package/src/functions/workspace-utils/run-cmd-in-stages.mts +2 -4
  33. package/src/functions/workspace-utils/types.mts +7 -0
@@ -6,7 +6,8 @@ export { $ } from './exec-async.mjs';
6
6
  export { formatDiffFrom, formatFiles, formatFilesList, formatUntracked } from './format.mjs';
7
7
  export { genIndex } from './gen-index.mjs';
8
8
  export { checkShouldRunTypeChecks } from './should-run.mjs';
9
- export { executeParallel, executeStages, getWorkspacePackages } from './workspace-utils/get-workspace-packages.mjs';
9
+ export { executeParallel, executeStages } from './workspace-utils/execute-parallel.mjs';
10
+ export { getWorkspacePackages } from './workspace-utils/get-workspace-packages.mjs';
10
11
  export { runCmdInParallelAcrossWorkspaces } from './workspace-utils/run-cmd-in-parallel.mjs';
11
12
  export { runCmdInStagesAcrossWorkspaces } from './workspace-utils/run-cmd-in-stages.mjs';
12
13
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
@@ -0,0 +1,25 @@
1
+ import { Result } from 'ts-data-forge';
2
+ import '../../node-global.mjs';
3
+ import { type Package } from './types.mjs';
4
+ /**
5
+ * Executes a npm script across multiple packages in parallel with a concurrency limit.
6
+ * @param packages - Array of Package objects to execute the script in
7
+ * @param scriptName - The name of the npm script to execute
8
+ * @param concurrency - Maximum number of packages to process simultaneously (default: 3)
9
+ * @returns A promise that resolves to an array of execution results
10
+ */
11
+ export declare const executeParallel: (packages: readonly Package[], scriptName: string, concurrency?: number) => Promise<readonly Result<Readonly<{
12
+ code?: number;
13
+ skipped?: boolean;
14
+ }>, Error>[]>;
15
+ /**
16
+ * Executes a npm script across packages in dependency order stages.
17
+ * Packages are grouped into stages where each stage contains packages whose
18
+ * dependencies have been completed in previous stages.
19
+ * @param packages - Array of Package objects to execute the script in
20
+ * @param scriptName - The name of the npm script to execute
21
+ * @param concurrency - Maximum number of packages to process simultaneously within each stage (default: 3)
22
+ * @returns A promise that resolves when all stages are complete
23
+ */
24
+ export declare const executeStages: (packages: readonly Package[], scriptName: string, concurrency?: number) => Promise<void>;
25
+ //# sourceMappingURL=execute-parallel.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute-parallel.d.mts","sourceRoot":"","sources":["../../../src/functions/workspace-utils/execute-parallel.mts"],"names":[],"mappings":"AACA,OAAO,EAML,MAAM,EACP,MAAM,eAAe,CAAC;AACvB,OAAO,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,SAAS,OAAO,EAAE,EAC5B,YAAY,MAAM,EAClB,cAAa,MAAU,KACtB,OAAO,CACR,SAAS,MAAM,CAAC,QAAQ,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAkCzE,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GACxB,UAAU,SAAS,OAAO,EAAE,EAC5B,YAAY,MAAM,EAClB,cAAa,MAAU,KACtB,OAAO,CAAC,IAAI,CAuCd,CAAC"}
@@ -0,0 +1,162 @@
1
+ import { spawn } from 'child_process';
2
+ import { pipe, createPromise, isRecord, hasKey, Result, isNotUndefined } from 'ts-data-forge';
3
+ import '../../node-global.mjs';
4
+
5
+ /**
6
+ * Executes a npm script across multiple packages in parallel with a concurrency limit.
7
+ * @param packages - Array of Package objects to execute the script in
8
+ * @param scriptName - The name of the npm script to execute
9
+ * @param concurrency - Maximum number of packages to process simultaneously (default: 3)
10
+ * @returns A promise that resolves to an array of execution results
11
+ */
12
+ const executeParallel = async (packages, scriptName, concurrency = 3) => {
13
+ const mut_resultPromises = [];
14
+ const executing = new Set();
15
+ for (const pkg of packages) {
16
+ const promise = executeScript(pkg, scriptName);
17
+ mut_resultPromises.push(promise);
18
+ const wrappedPromise = promise.finally(() => {
19
+ executing.delete(wrappedPromise);
20
+ });
21
+ executing.add(wrappedPromise);
22
+ // If we reach concurrency limit, wait for one to finish
23
+ if (executing.size >= concurrency) {
24
+ // eslint-disable-next-line no-await-in-loop
25
+ await Promise.race(executing);
26
+ }
27
+ }
28
+ return Promise.all(mut_resultPromises);
29
+ };
30
+ /**
31
+ * Executes a npm script across packages in dependency order stages.
32
+ * Packages are grouped into stages where each stage contains packages whose
33
+ * dependencies have been completed in previous stages.
34
+ * @param packages - Array of Package objects to execute the script in
35
+ * @param scriptName - The name of the npm script to execute
36
+ * @param concurrency - Maximum number of packages to process simultaneously within each stage (default: 3)
37
+ * @returns A promise that resolves when all stages are complete
38
+ */
39
+ const executeStages = async (packages, scriptName, concurrency = 3) => {
40
+ const dependencyGraph = buildDependencyGraph(packages);
41
+ const sorted = topologicalSortPackages(packages, dependencyGraph);
42
+ const stages = [];
43
+ const completed = new Set();
44
+ while (completed.size < sorted.length) {
45
+ const stage = [];
46
+ for (const pkg of sorted) {
47
+ if (completed.has(pkg.name))
48
+ continue;
49
+ const deps = dependencyGraph.get(pkg.name) ?? [];
50
+ const depsCompleted = deps.every((dep) => completed.has(dep));
51
+ if (depsCompleted) {
52
+ stage.push(pkg);
53
+ }
54
+ }
55
+ if (stage.length === 0) {
56
+ throw new Error('Circular dependency detected');
57
+ }
58
+ stages.push(stage);
59
+ for (const pkg of stage)
60
+ completed.add(pkg.name);
61
+ }
62
+ console.log(`\nExecuting ${scriptName} in ${stages.length} stages...\n`);
63
+ for (const [i, stage] of stages.entries()) {
64
+ if (stage.length > 0) {
65
+ console.log(`Stage ${i + 1}: ${stage.map((p) => p.name).join(', ')}`);
66
+ // eslint-disable-next-line no-await-in-loop
67
+ await executeParallel(stage, scriptName, concurrency);
68
+ }
69
+ }
70
+ };
71
+ /**
72
+ * Executes a npm script in a specific package directory.
73
+ * @param pkg - The package object containing path and metadata
74
+ * @param scriptName - The name of the npm script to execute
75
+ * @param options - Configuration options
76
+ * @param options.prefix - Whether to prefix output with package name (default: true)
77
+ * @returns A promise that resolves to execution result with exit code or skipped flag
78
+ */
79
+ const executeScript = (pkg, scriptName, { prefix = true } = {}) => pipe(createPromise((resolve, reject) => {
80
+ const packageJsonScripts = isRecord(pkg.packageJson) && isRecord(pkg.packageJson['scripts'])
81
+ ? pkg.packageJson['scripts']
82
+ : {};
83
+ const hasScript = hasKey(packageJsonScripts, scriptName);
84
+ if (!hasScript) {
85
+ resolve({ skipped: true });
86
+ return;
87
+ }
88
+ const prefixStr = prefix ? `[${pkg.name}] ` : '';
89
+ const proc = spawn('npm', ['run', scriptName], {
90
+ cwd: pkg.path,
91
+ shell: true,
92
+ stdio: 'pipe',
93
+ });
94
+ proc.stdout.on('data', (data) => {
95
+ process.stdout.write(prefixStr + data.toString());
96
+ });
97
+ proc.stderr.on('data', (data) => {
98
+ process.stderr.write(prefixStr + data.toString());
99
+ });
100
+ proc.on('close', (code) => {
101
+ if (code === 0) {
102
+ resolve({ code });
103
+ }
104
+ else {
105
+ reject(new Error(`${pkg.name} exited with code ${code}`));
106
+ }
107
+ });
108
+ proc.on('error', reject);
109
+ })).map((result) => result.then(Result.mapErr((err) => {
110
+ const errorMessage = err instanceof Error
111
+ ? err.message
112
+ : isRecord(err) && hasKey(err, 'message')
113
+ ? (err.message?.toString() ?? 'Unknown error message')
114
+ : 'Unknown error';
115
+ console.error(`\nError in ${pkg.name}:`, errorMessage);
116
+ return err instanceof Error ? err : new Error(errorMessage);
117
+ }))).value;
118
+ /**
119
+ * Performs a topological sort on packages based on their dependencies,
120
+ * ensuring dependencies are ordered before their dependents.
121
+ * @param packages - Array of Package objects to sort
122
+ * @returns An array of packages in dependency order (dependencies first)
123
+ */
124
+ const topologicalSortPackages = (packages, dependencyGraph) => {
125
+ const visited = new Set();
126
+ const result = [];
127
+ const packageMap = new Map(packages.map((p) => [p.name, p]));
128
+ const visit = (pkgName) => {
129
+ if (visited.has(pkgName))
130
+ return;
131
+ visited.add(pkgName);
132
+ const deps = dependencyGraph.get(pkgName) ?? [];
133
+ for (const dep of deps) {
134
+ visit(dep);
135
+ }
136
+ result.push(pkgName);
137
+ };
138
+ for (const pkg of packages) {
139
+ visit(pkg.name);
140
+ }
141
+ return result
142
+ .map((pkgName) => packageMap.get(pkgName))
143
+ .filter(isNotUndefined);
144
+ };
145
+ /**
146
+ * Builds a dependency graph from the given packages, mapping each package name
147
+ * to its internal workspace dependencies.
148
+ * @param packages - Array of Package objects to analyze
149
+ * @returns A readonly map where keys are package names and values are arrays of their dependency package names
150
+ */
151
+ const buildDependencyGraph = (packages) => {
152
+ const packageMap = new Map(packages.map((p) => [p.name, p]));
153
+ const graph = new Map();
154
+ for (const pkg of packages) {
155
+ const deps = Object.keys(pkg.dependencies).filter((depName) => packageMap.has(depName));
156
+ graph.set(pkg.name, deps);
157
+ }
158
+ return graph;
159
+ };
160
+
161
+ export { executeParallel, executeStages };
162
+ //# sourceMappingURL=execute-parallel.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute-parallel.mjs","sources":["../../../src/functions/workspace-utils/execute-parallel.mts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -1,12 +1,6 @@
1
1
  #!/usr/bin/env tsx
2
- import { Result } from 'ts-data-forge';
3
2
  import '../../node-global.mjs';
4
- type Package = Readonly<{
5
- name: string;
6
- path: string;
7
- packageJson: JsonValue;
8
- dependencies: ReadonlyRecord<string, string>;
9
- }>;
3
+ import { type Package } from './types.mjs';
10
4
  /**
11
5
  * Retrieves all workspace packages from a monorepo based on the workspace patterns
12
6
  * defined in the root package.json file.
@@ -14,26 +8,4 @@ type Package = Readonly<{
14
8
  * @returns A promise that resolves to an array of Package objects containing package metadata
15
9
  */
16
10
  export declare const getWorkspacePackages: (rootPackageJsonDir: string) => Promise<readonly Package[]>;
17
- /**
18
- * Executes a npm script across multiple packages in parallel with a concurrency limit.
19
- * @param packages - Array of Package objects to execute the script in
20
- * @param scriptName - The name of the npm script to execute
21
- * @param concurrency - Maximum number of packages to process simultaneously (default: 3)
22
- * @returns A promise that resolves to an array of execution results
23
- */
24
- export declare const executeParallel: (packages: readonly Package[], scriptName: string, concurrency?: number) => Promise<readonly Result<Readonly<{
25
- code?: number;
26
- skipped?: boolean;
27
- }>, Error>[]>;
28
- /**
29
- * Executes a npm script across packages in dependency order stages.
30
- * Packages are grouped into stages where each stage contains packages whose
31
- * dependencies have been completed in previous stages.
32
- * @param packages - Array of Package objects to execute the script in
33
- * @param scriptName - The name of the npm script to execute
34
- * @param concurrency - Maximum number of packages to process simultaneously within each stage (default: 3)
35
- * @returns A promise that resolves when all stages are complete
36
- */
37
- export declare const executeStages: (packages: readonly Package[], scriptName: string, concurrency?: number) => Promise<void>;
38
- export {};
39
11
  //# sourceMappingURL=get-workspace-packages.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-workspace-packages.d.mts","sourceRoot":"","sources":["../../../src/functions/workspace-utils/get-workspace-packages.mts"],"names":[],"mappings":";AAGA,OAAO,EAOL,MAAM,EACP,MAAM,eAAe,CAAC;AACvB,OAAO,uBAAuB,CAAC;AAK/B,KAAK,OAAO,GAAG,QAAQ,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,SAAS,CAAC;IACvB,YAAY,EAAE,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C,CAAC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,oBAAoB,MAAM,KACzB,OAAO,CAAC,SAAS,OAAO,EAAE,CAyD5B,CAAC;AAuKF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,SAAS,OAAO,EAAE,EAC5B,YAAY,MAAM,EAClB,cAAa,MAAU,KACtB,OAAO,CACR,SAAS,MAAM,CAAC,QAAQ,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAkCzE,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GACxB,UAAU,SAAS,OAAO,EAAE,EAC5B,YAAY,MAAM,EAClB,cAAa,MAAU,KACtB,OAAO,CAAC,IAAI,CAuCd,CAAC"}
1
+ {"version":3,"file":"get-workspace-packages.d.mts","sourceRoot":"","sources":["../../../src/functions/workspace-utils/get-workspace-packages.mts"],"names":[],"mappings":";AAUA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,oBAAoB,MAAM,KACzB,OAAO,CAAC,SAAS,OAAO,EAAE,CA+D5B,CAAC"}
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env tsx
2
- import { spawn } from 'child_process';
3
- import { Result, isNotUndefined, pipe, isRecord, hasKey, isString, createPromise } from 'ts-data-forge';
2
+ import { Result, Json, isNotUndefined, isRecord, hasKey, isString } from 'ts-data-forge';
4
3
  import '../../node-global.mjs';
5
4
 
6
5
  /**
@@ -18,19 +17,24 @@ const getWorkspacePackages = async (rootPackageJsonDir) => {
18
17
  const matches = await glob(pattern, {
19
18
  cwd: rootPackageJsonDir,
20
19
  ignore: ['**/node_modules/**'],
20
+ onlyDirectories: true,
21
+ absolute: true,
21
22
  });
22
23
  const packageJsonList = await Promise.all(matches.map(async (match) => {
23
- const packagePath = path.join(rootPackageJsonDir, match);
24
- const result = await Result.fromPromise(fs.readFile(path.join(packagePath, 'package.json'), 'utf8'));
24
+ const maybePackagePath = path.join(match, 'package.json');
25
+ const result = await Result.fromPromise(fs.readFile(maybePackagePath, 'utf8'));
25
26
  if (Result.isErr(result))
26
27
  return undefined;
27
- return [packagePath, result.value];
28
+ const parsed = Json.parse(result.value);
29
+ if (Result.isErr(parsed))
30
+ return undefined;
31
+ return [maybePackagePath, parsed.value];
28
32
  }));
29
33
  const packageInfos = await Promise.all(packageJsonList
30
34
  .filter(isNotUndefined)
31
35
  .map(([packagePath, packageJson]) => ({
32
36
  name: getStrFromJsonValue(packageJson, 'name'),
33
- path: packagePath,
37
+ path: path.dirname(packagePath),
34
38
  packageJson,
35
39
  dependencies: {
36
40
  ...getKeyValueRecordFromJsonValue(packageJson, 'dependencies'),
@@ -64,162 +68,6 @@ const getKeyValueRecordFromJsonValue = (value, key) => {
64
68
  const entries = Object.entries(obj).filter((entry) => isString(entry[1]));
65
69
  return Object.fromEntries(entries);
66
70
  };
67
- /**
68
- * Builds a dependency graph from the given packages, mapping each package name
69
- * to its internal workspace dependencies.
70
- * @param packages - Array of Package objects to analyze
71
- * @returns A readonly map where keys are package names and values are arrays of their dependency package names
72
- */
73
- const buildDependencyGraph = (packages) => {
74
- const packageMap = new Map(packages.map((p) => [p.name, p]));
75
- const graph = new Map();
76
- for (const pkg of packages) {
77
- const deps = Object.keys(pkg.dependencies).filter((depName) => packageMap.has(depName));
78
- graph.set(pkg.name, deps);
79
- }
80
- return graph;
81
- };
82
- /**
83
- * Performs a topological sort on packages based on their dependencies,
84
- * ensuring dependencies are ordered before their dependents.
85
- * @param packages - Array of Package objects to sort
86
- * @returns An array of packages in dependency order (dependencies first)
87
- */
88
- const topologicalSortPackages = (packages) => {
89
- const graph = buildDependencyGraph(packages);
90
- const visited = new Set();
91
- const result = [];
92
- const packageMap = new Map(packages.map((p) => [p.name, p]));
93
- const visit = (pkgName) => {
94
- if (visited.has(pkgName))
95
- return;
96
- visited.add(pkgName);
97
- const deps = graph.get(pkgName) ?? [];
98
- for (const dep of deps) {
99
- visit(dep);
100
- }
101
- result.push(pkgName);
102
- };
103
- for (const pkg of packages) {
104
- visit(pkg.name);
105
- }
106
- return result
107
- .map((pkgName) => packageMap.get(pkgName))
108
- .filter(isNotUndefined);
109
- };
110
- /**
111
- * Executes a npm script in a specific package directory.
112
- * @param pkg - The package object containing path and metadata
113
- * @param scriptName - The name of the npm script to execute
114
- * @param options - Configuration options
115
- * @param options.prefix - Whether to prefix output with package name (default: true)
116
- * @returns A promise that resolves to execution result with exit code or skipped flag
117
- */
118
- const executeScript = (pkg, scriptName, { prefix = true } = {}) => pipe(createPromise((resolve, reject) => {
119
- const packageJsonScripts = isRecord(pkg.packageJson) && isRecord(pkg.packageJson['scripts'])
120
- ? pkg.packageJson['scripts']
121
- : {};
122
- const hasScript = hasKey(packageJsonScripts, scriptName);
123
- if (!hasScript) {
124
- resolve({ skipped: true });
125
- return;
126
- }
127
- const prefixStr = prefix ? `[${pkg.name}] ` : '';
128
- const proc = spawn('npm', ['run', scriptName], {
129
- cwd: pkg.path,
130
- shell: true,
131
- stdio: 'pipe',
132
- });
133
- proc.stdout.on('data', (data) => {
134
- process.stdout.write(prefixStr + data.toString());
135
- });
136
- proc.stderr.on('data', (data) => {
137
- process.stderr.write(prefixStr + data.toString());
138
- });
139
- proc.on('close', (code) => {
140
- if (code === 0) {
141
- resolve({ code });
142
- }
143
- else {
144
- reject(new Error(`${pkg.name} exited with code ${code}`));
145
- }
146
- });
147
- proc.on('error', reject);
148
- })).map((result) => result.then(Result.mapErr((err) => {
149
- const errorMessage = err instanceof Error
150
- ? err.message
151
- : isRecord(err) && hasKey(err, 'message')
152
- ? (err.message?.toString() ?? 'Unknown error message')
153
- : 'Unknown error';
154
- console.error(`\nError in ${pkg.name}:`, errorMessage);
155
- return err instanceof Error ? err : new Error(errorMessage);
156
- }))).value;
157
- /**
158
- * Executes a npm script across multiple packages in parallel with a concurrency limit.
159
- * @param packages - Array of Package objects to execute the script in
160
- * @param scriptName - The name of the npm script to execute
161
- * @param concurrency - Maximum number of packages to process simultaneously (default: 3)
162
- * @returns A promise that resolves to an array of execution results
163
- */
164
- const executeParallel = async (packages, scriptName, concurrency = 3) => {
165
- const mut_resultPromises = [];
166
- const executing = new Set();
167
- for (const pkg of packages) {
168
- const promise = executeScript(pkg, scriptName);
169
- mut_resultPromises.push(promise);
170
- const wrappedPromise = promise.finally(() => {
171
- executing.delete(wrappedPromise);
172
- });
173
- executing.add(wrappedPromise);
174
- // If we reach concurrency limit, wait for one to finish
175
- if (executing.size >= concurrency) {
176
- // eslint-disable-next-line no-await-in-loop
177
- await Promise.race(executing);
178
- }
179
- }
180
- return Promise.all(mut_resultPromises);
181
- };
182
- /**
183
- * Executes a npm script across packages in dependency order stages.
184
- * Packages are grouped into stages where each stage contains packages whose
185
- * dependencies have been completed in previous stages.
186
- * @param packages - Array of Package objects to execute the script in
187
- * @param scriptName - The name of the npm script to execute
188
- * @param concurrency - Maximum number of packages to process simultaneously within each stage (default: 3)
189
- * @returns A promise that resolves when all stages are complete
190
- */
191
- const executeStages = async (packages, scriptName, concurrency = 3) => {
192
- const sorted = topologicalSortPackages(packages);
193
- const stages = [];
194
- const completed = new Set();
195
- const dependencyGraph = buildDependencyGraph(packages);
196
- while (completed.size < sorted.length) {
197
- const stage = [];
198
- for (const pkg of sorted) {
199
- if (completed.has(pkg.name))
200
- continue;
201
- const deps = dependencyGraph.get(pkg.name) ?? [];
202
- const depsCompleted = deps.every((dep) => completed.has(dep));
203
- if (depsCompleted) {
204
- stage.push(pkg);
205
- }
206
- }
207
- if (stage.length === 0) {
208
- throw new Error('Circular dependency detected');
209
- }
210
- stages.push(stage);
211
- for (const pkg of stage)
212
- completed.add(pkg.name);
213
- }
214
- console.log(`\nExecuting ${scriptName} in ${stages.length} stages...\n`);
215
- for (const [i, stage] of stages.entries()) {
216
- if (stage.length > 0) {
217
- console.log(`Stage ${i + 1}: ${stage.map((p) => p.name).join(', ')}`);
218
- // eslint-disable-next-line no-await-in-loop
219
- await executeParallel(stage, scriptName, concurrency);
220
- }
221
- }
222
- };
223
71
 
224
- export { executeParallel, executeStages, getWorkspacePackages };
72
+ export { getWorkspacePackages };
225
73
  //# sourceMappingURL=get-workspace-packages.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-workspace-packages.mjs","sources":["../../../src/functions/workspace-utils/get-workspace-packages.mts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"get-workspace-packages.mjs","sources":["../../../src/functions/workspace-utils/get-workspace-packages.mts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
+ export * from './execute-parallel.mjs';
1
2
  export * from './get-workspace-packages.mjs';
2
3
  export * from './run-cmd-in-parallel.mjs';
3
4
  export * from './run-cmd-in-stages.mjs';
5
+ export * from './types.mjs';
4
6
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../src/functions/workspace-utils/index.mts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../src/functions/workspace-utils/index.mts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,aAAa,CAAC"}
@@ -1,4 +1,5 @@
1
- export { executeParallel, executeStages, getWorkspacePackages } from './get-workspace-packages.mjs';
1
+ export { executeParallel, executeStages } from './execute-parallel.mjs';
2
+ export { getWorkspacePackages } from './get-workspace-packages.mjs';
2
3
  export { runCmdInParallelAcrossWorkspaces } from './run-cmd-in-parallel.mjs';
3
4
  export { runCmdInStagesAcrossWorkspaces } from './run-cmd-in-stages.mjs';
4
5
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"run-cmd-in-parallel.d.mts","sourceRoot":"","sources":["../../../src/functions/workspace-utils/run-cmd-in-parallel.mts"],"names":[],"mappings":";AAOA;;;;;;;;GAQG;AACH,eAAO,MAAM,gCAAgC,GAAU,mEAKpD,QAAQ,CAAC;IACV,kBAAkB,EAAE,MAAM,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3D,CAAC,KAAG,OAAO,CAAC,IAAI,CAkBhB,CAAC"}
1
+ {"version":3,"file":"run-cmd-in-parallel.d.mts","sourceRoot":"","sources":["../../../src/functions/workspace-utils/run-cmd-in-parallel.mts"],"names":[],"mappings":";AAKA;;;;;;;;GAQG;AACH,eAAO,MAAM,gCAAgC,GAAU,mEAKpD,QAAQ,CAAC;IACV,kBAAkB,EAAE,MAAM,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3D,CAAC,KAAG,OAAO,CAAC,IAAI,CAkBhB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env tsx
2
- import { getWorkspacePackages, executeParallel } from './get-workspace-packages.mjs';
2
+ import { executeParallel } from './execute-parallel.mjs';
3
+ import { getWorkspacePackages } from './get-workspace-packages.mjs';
3
4
 
4
5
  /**
5
6
  * Executes a npm script command across all workspace packages in parallel.
@@ -1 +1 @@
1
- {"version":3,"file":"run-cmd-in-parallel.mjs","sources":["../../../src/functions/workspace-utils/run-cmd-in-parallel.mts"],"sourcesContent":[null],"names":[],"mappings":";;;AAOA;;;;;;;;AAQG;AACI,MAAM,gCAAgC,GAAG,OAAO,EACrD,kBAAkB,EAClB,GAAG,EACH,WAAW,GAAG,CAAC,EACf,sBAAsB,GAMtB,KAAmB;AACnB,IAAA,IAAI;AACF,QAAA,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,kBAAkB,CAAC;AAE/D,QAAA,MAAM,gBAAgB,GACpB,sBAAsB,KAAK;AACzB,cAAE;AACF,cAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEhE,MAAM,eAAe,CAAC,gBAAgB,EAAE,GAAG,EAAE,WAAW,CAAC;AACzD,QAAA,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAA,uBAAA,CAAyB,CAAC;;IAChD,OAAO,GAAG,EAAE;AACZ,QAAA,OAAO,CAAC,KAAK,CACX,CAAA,IAAA,EAAO,GAAG,CAAA,QAAA,CAAU,EACpB,GAAG,YAAY,KAAK,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAC7D;AACD,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;;AAEnB;;;;"}
1
+ {"version":3,"file":"run-cmd-in-parallel.mjs","sources":["../../../src/functions/workspace-utils/run-cmd-in-parallel.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAKA;;;;;;;;AAQG;AACI,MAAM,gCAAgC,GAAG,OAAO,EACrD,kBAAkB,EAClB,GAAG,EACH,WAAW,GAAG,CAAC,EACf,sBAAsB,GAMtB,KAAmB;AACnB,IAAA,IAAI;AACF,QAAA,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,kBAAkB,CAAC;AAE/D,QAAA,MAAM,gBAAgB,GACpB,sBAAsB,KAAK;AACzB,cAAE;AACF,cAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEhE,MAAM,eAAe,CAAC,gBAAgB,EAAE,GAAG,EAAE,WAAW,CAAC;AACzD,QAAA,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAA,uBAAA,CAAyB,CAAC;;IAChD,OAAO,GAAG,EAAE;AACZ,QAAA,OAAO,CAAC,KAAK,CACX,CAAA,IAAA,EAAO,GAAG,CAAA,QAAA,CAAU,EACpB,GAAG,YAAY,KAAK,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAC7D;AACD,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;;AAEnB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"run-cmd-in-stages.d.mts","sourceRoot":"","sources":["../../../src/functions/workspace-utils/run-cmd-in-stages.mts"],"names":[],"mappings":";AAOA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,8BAA8B,GAAU,mEAKlD,QAAQ,CAAC;IACV,kBAAkB,EAAE,MAAM,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3D,CAAC,KAAG,OAAO,CAAC,IAAI,CAkBhB,CAAC"}
1
+ {"version":3,"file":"run-cmd-in-stages.d.mts","sourceRoot":"","sources":["../../../src/functions/workspace-utils/run-cmd-in-stages.mts"],"names":[],"mappings":";AAKA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,8BAA8B,GAAU,mEAKlD,QAAQ,CAAC;IACV,kBAAkB,EAAE,MAAM,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3D,CAAC,KAAG,OAAO,CAAC,IAAI,CAkBhB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env tsx
2
- import { getWorkspacePackages, executeStages } from './get-workspace-packages.mjs';
2
+ import { executeStages } from './execute-parallel.mjs';
3
+ import { getWorkspacePackages } from './get-workspace-packages.mjs';
3
4
 
4
5
  /**
5
6
  * Executes a npm script command across all workspace packages in dependency order stages.
@@ -1 +1 @@
1
- {"version":3,"file":"run-cmd-in-stages.mjs","sources":["../../../src/functions/workspace-utils/run-cmd-in-stages.mts"],"sourcesContent":[null],"names":[],"mappings":";;;AAOA;;;;;;;;;;AAUG;AACI,MAAM,8BAA8B,GAAG,OAAO,EACnD,kBAAkB,EAClB,GAAG,EACH,WAAW,GAAG,CAAC,EACf,sBAAsB,GAMtB,KAAmB;AACnB,IAAA,IAAI;AACF,QAAA,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,kBAAkB,CAAC;AAE/D,QAAA,MAAM,gBAAgB,GACpB,sBAAsB,KAAK;AACzB,cAAE;AACF,cAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEhE,MAAM,aAAa,CAAC,gBAAgB,EAAE,GAAG,EAAE,WAAW,CAAC;AACvD,QAAA,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAA,uBAAA,CAAyB,CAAC;;IAChD,OAAO,GAAG,EAAE;AACZ,QAAA,OAAO,CAAC,KAAK,CACX,CAAA,IAAA,EAAO,GAAG,CAAA,QAAA,CAAU,EACpB,GAAG,YAAY,KAAK,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAC7D;AACD,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;;AAEnB;;;;"}
1
+ {"version":3,"file":"run-cmd-in-stages.mjs","sources":["../../../src/functions/workspace-utils/run-cmd-in-stages.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAKA;;;;;;;;;;AAUG;AACI,MAAM,8BAA8B,GAAG,OAAO,EACnD,kBAAkB,EAClB,GAAG,EACH,WAAW,GAAG,CAAC,EACf,sBAAsB,GAMtB,KAAmB;AACnB,IAAA,IAAI;AACF,QAAA,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,kBAAkB,CAAC;AAE/D,QAAA,MAAM,gBAAgB,GACpB,sBAAsB,KAAK;AACzB,cAAE;AACF,cAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEhE,MAAM,aAAa,CAAC,gBAAgB,EAAE,GAAG,EAAE,WAAW,CAAC;AACvD,QAAA,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAA,uBAAA,CAAyB,CAAC;;IAChD,OAAO,GAAG,EAAE;AACZ,QAAA,OAAO,CAAC,KAAK,CACX,CAAA,IAAA,EAAO,GAAG,CAAA,QAAA,CAAU,EACpB,GAAG,YAAY,KAAK,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAC7D;AACD,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;;AAEnB;;;;"}
@@ -0,0 +1,7 @@
1
+ export type Package = Readonly<{
2
+ name: string;
3
+ path: string;
4
+ packageJson: JsonValue;
5
+ dependencies: ReadonlyRecord<string, string>;
6
+ }>;
7
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../../../src/functions/workspace-utils/types.mts"],"names":[],"mappings":"AACA,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,SAAS,CAAC;IACvB,YAAY,EAAE,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/dist/index.mjs CHANGED
@@ -6,7 +6,8 @@ export { $ } from './functions/exec-async.mjs';
6
6
  export { formatDiffFrom, formatFiles, formatFilesList, formatUntracked } from './functions/format.mjs';
7
7
  export { genIndex } from './functions/gen-index.mjs';
8
8
  export { checkShouldRunTypeChecks } from './functions/should-run.mjs';
9
- export { executeParallel, executeStages, getWorkspacePackages } from './functions/workspace-utils/get-workspace-packages.mjs';
9
+ export { executeParallel, executeStages } from './functions/workspace-utils/execute-parallel.mjs';
10
+ export { getWorkspacePackages } from './functions/workspace-utils/get-workspace-packages.mjs';
10
11
  export { runCmdInParallelAcrossWorkspaces } from './functions/workspace-utils/run-cmd-in-parallel.mjs';
11
12
  export { runCmdInStagesAcrossWorkspaces } from './functions/workspace-utils/run-cmd-in-stages.mjs';
12
13
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-repo-utils",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "typescript"
@@ -30,14 +30,14 @@
30
30
  "LICENSE"
31
31
  ],
32
32
  "scripts": {
33
- "build": "npm run z:node-esm -- ./scripts/cmd/build.mjs",
34
- "check-all": "npm run z:node-esm -- ./scripts/cmd/check-all.mjs",
35
- "check:ext": "npm run z:node-esm -- ./scripts/cmd/check-ext.mjs",
33
+ "build": "tsx ./scripts/cmd/build.mjs",
34
+ "check-all": "tsx ./scripts/cmd/check-all.mjs",
35
+ "check:ext": "tsx ./scripts/cmd/check-ext.mjs",
36
36
  "cspell": "cspell \"**\" --gitignore --gitignore-root ./ --no-progress",
37
- "doc": "npm run z:node-esm -- ./scripts/cmd/gen-docs.mjs",
38
- "fmt": "npm run z:node-esm -- ./scripts/cmd/fmt-diff.mjs",
37
+ "doc": "tsx ./scripts/cmd/gen-docs.mjs",
38
+ "fmt": "tsx ./scripts/cmd/fmt-diff.mjs",
39
39
  "fmt:full": "prettier --write .",
40
- "gi": "npm run z:node-esm -- ./scripts/cmd/gi.mjs",
40
+ "gi": "tsx ./scripts/cmd/gi.mjs",
41
41
  "lint": "eslint .",
42
42
  "lint:fix": "eslint . --fix",
43
43
  "md": "markdownlint-cli2",
@@ -50,7 +50,6 @@
50
50
  "tscw": "tsc --noEmit --watch",
51
51
  "type-check": "tsc --noEmit",
52
52
  "update-packages": "npx npm-check-updates -u --install always --reject @types/node",
53
- "z:node-esm": "node --import tsx/esm",
54
53
  "z:vitest": "vitest --config ./configs/vitest.config.ts"
55
54
  },
56
55
  "dependencies": {
@@ -0,0 +1,247 @@
1
+ import { spawn } from 'child_process';
2
+ import {
3
+ createPromise,
4
+ hasKey,
5
+ isNotUndefined,
6
+ isRecord,
7
+ pipe,
8
+ Result,
9
+ } from 'ts-data-forge';
10
+ import '../../node-global.mjs';
11
+ import { type Package } from './types.mjs';
12
+
13
+ const DEBUG = false as boolean;
14
+
15
+ /**
16
+ * Executes a npm script across multiple packages in parallel with a concurrency limit.
17
+ * @param packages - Array of Package objects to execute the script in
18
+ * @param scriptName - The name of the npm script to execute
19
+ * @param concurrency - Maximum number of packages to process simultaneously (default: 3)
20
+ * @returns A promise that resolves to an array of execution results
21
+ */
22
+ export const executeParallel = async (
23
+ packages: readonly Package[],
24
+ scriptName: string,
25
+ concurrency: number = 3,
26
+ ): Promise<
27
+ readonly Result<Readonly<{ code?: number; skipped?: boolean }>, Error>[]
28
+ > => {
29
+ const mut_resultPromises: Promise<
30
+ Result<Readonly<{ code?: number; skipped?: boolean }>, Error>
31
+ >[] = [];
32
+
33
+ const executing = new Set<Promise<unknown>>();
34
+
35
+ for (const pkg of packages) {
36
+ const promise = executeScript(pkg, scriptName);
37
+
38
+ mut_resultPromises.push(promise);
39
+
40
+ const wrappedPromise = promise.finally(() => {
41
+ executing.delete(wrappedPromise);
42
+ if (DEBUG) {
43
+ console.debug('executing size', executing.size);
44
+ }
45
+ });
46
+
47
+ executing.add(wrappedPromise);
48
+
49
+ if (DEBUG) {
50
+ console.debug('executing size', executing.size);
51
+ }
52
+
53
+ // If we reach concurrency limit, wait for one to finish
54
+ if (executing.size >= concurrency) {
55
+ // eslint-disable-next-line no-await-in-loop
56
+ await Promise.race(executing);
57
+ }
58
+ }
59
+
60
+ return Promise.all(mut_resultPromises);
61
+ };
62
+
63
+ /**
64
+ * Executes a npm script across packages in dependency order stages.
65
+ * Packages are grouped into stages where each stage contains packages whose
66
+ * dependencies have been completed in previous stages.
67
+ * @param packages - Array of Package objects to execute the script in
68
+ * @param scriptName - The name of the npm script to execute
69
+ * @param concurrency - Maximum number of packages to process simultaneously within each stage (default: 3)
70
+ * @returns A promise that resolves when all stages are complete
71
+ */
72
+ export const executeStages = async (
73
+ packages: readonly Package[],
74
+ scriptName: string,
75
+ concurrency: number = 3,
76
+ ): Promise<void> => {
77
+ const dependencyGraph = buildDependencyGraph(packages);
78
+
79
+ const sorted = topologicalSortPackages(packages, dependencyGraph);
80
+
81
+ const stages: (readonly Package[])[] = [];
82
+ const completed = new Set<string>();
83
+
84
+ while (completed.size < sorted.length) {
85
+ const stage: Package[] = [];
86
+
87
+ for (const pkg of sorted) {
88
+ if (completed.has(pkg.name)) continue;
89
+
90
+ const deps = dependencyGraph.get(pkg.name) ?? [];
91
+ const depsCompleted = deps.every((dep) => completed.has(dep));
92
+
93
+ if (depsCompleted) {
94
+ stage.push(pkg);
95
+ }
96
+ }
97
+
98
+ if (stage.length === 0) {
99
+ throw new Error('Circular dependency detected');
100
+ }
101
+
102
+ stages.push(stage);
103
+ for (const pkg of stage) completed.add(pkg.name);
104
+ }
105
+
106
+ console.log(`\nExecuting ${scriptName} in ${stages.length} stages...\n`);
107
+
108
+ for (const [i, stage] of stages.entries()) {
109
+ if (stage.length > 0) {
110
+ console.log(`Stage ${i + 1}: ${stage.map((p) => p.name).join(', ')}`);
111
+ // eslint-disable-next-line no-await-in-loop
112
+ await executeParallel(stage, scriptName, concurrency);
113
+ }
114
+ }
115
+ };
116
+
117
+ /**
118
+ * Executes a npm script in a specific package directory.
119
+ * @param pkg - The package object containing path and metadata
120
+ * @param scriptName - The name of the npm script to execute
121
+ * @param options - Configuration options
122
+ * @param options.prefix - Whether to prefix output with package name (default: true)
123
+ * @returns A promise that resolves to execution result with exit code or skipped flag
124
+ */
125
+ const executeScript = (
126
+ pkg: Package,
127
+ scriptName: string,
128
+ { prefix = true }: Readonly<{ prefix?: boolean }> = {},
129
+ ): Promise<Result<Readonly<{ code?: number; skipped?: boolean }>, Error>> =>
130
+ pipe(
131
+ createPromise(
132
+ (
133
+ resolve: (
134
+ value: Readonly<{ code?: number; skipped?: boolean }>,
135
+ ) => void,
136
+ reject: (reason: unknown) => void,
137
+ ) => {
138
+ const packageJsonScripts =
139
+ isRecord(pkg.packageJson) && isRecord(pkg.packageJson['scripts'])
140
+ ? pkg.packageJson['scripts']
141
+ : {};
142
+
143
+ const hasScript = hasKey(packageJsonScripts, scriptName);
144
+ if (!hasScript) {
145
+ resolve({ skipped: true });
146
+ return;
147
+ }
148
+
149
+ const prefixStr = prefix ? `[${pkg.name}] ` : '';
150
+ const proc = spawn('npm', ['run', scriptName], {
151
+ cwd: pkg.path,
152
+ shell: true,
153
+ stdio: 'pipe',
154
+ });
155
+
156
+ proc.stdout.on('data', (data: Readonly<Buffer>) => {
157
+ process.stdout.write(prefixStr + data.toString());
158
+ });
159
+
160
+ proc.stderr.on('data', (data: Readonly<Buffer>) => {
161
+ process.stderr.write(prefixStr + data.toString());
162
+ });
163
+
164
+ proc.on('close', (code: number | null) => {
165
+ if (code === 0) {
166
+ resolve({ code });
167
+ } else {
168
+ reject(new Error(`${pkg.name} exited with code ${code}`));
169
+ }
170
+ });
171
+
172
+ proc.on('error', reject);
173
+ },
174
+ ),
175
+ ).map((result) =>
176
+ result.then(
177
+ Result.mapErr((err) => {
178
+ const errorMessage: string =
179
+ err instanceof Error
180
+ ? err.message
181
+ : isRecord(err) && hasKey(err, 'message')
182
+ ? (err.message?.toString() ?? 'Unknown error message')
183
+ : 'Unknown error';
184
+
185
+ console.error(`\nError in ${pkg.name}:`, errorMessage);
186
+ return err instanceof Error ? err : new Error(errorMessage);
187
+ }),
188
+ ),
189
+ ).value;
190
+
191
+ /**
192
+ * Performs a topological sort on packages based on their dependencies,
193
+ * ensuring dependencies are ordered before their dependents.
194
+ * @param packages - Array of Package objects to sort
195
+ * @returns An array of packages in dependency order (dependencies first)
196
+ */
197
+ const topologicalSortPackages = (
198
+ packages: readonly Package[],
199
+ dependencyGraph: ReadonlyMap<string, readonly string[]>,
200
+ ): readonly Package[] => {
201
+ const visited = new Set<string>();
202
+ const result: string[] = [];
203
+
204
+ const packageMap = new Map(packages.map((p) => [p.name, p]));
205
+
206
+ const visit = (pkgName: string): void => {
207
+ if (visited.has(pkgName)) return;
208
+ visited.add(pkgName);
209
+
210
+ const deps = dependencyGraph.get(pkgName) ?? [];
211
+ for (const dep of deps) {
212
+ visit(dep);
213
+ }
214
+
215
+ result.push(pkgName);
216
+ };
217
+
218
+ for (const pkg of packages) {
219
+ visit(pkg.name);
220
+ }
221
+
222
+ return result
223
+ .map((pkgName) => packageMap.get(pkgName))
224
+ .filter(isNotUndefined);
225
+ };
226
+
227
+ /**
228
+ * Builds a dependency graph from the given packages, mapping each package name
229
+ * to its internal workspace dependencies.
230
+ * @param packages - Array of Package objects to analyze
231
+ * @returns A readonly map where keys are package names and values are arrays of their dependency package names
232
+ */
233
+ const buildDependencyGraph = (
234
+ packages: readonly Package[],
235
+ ): ReadonlyMap<string, readonly string[]> => {
236
+ const packageMap = new Map(packages.map((p) => [p.name, p]));
237
+ const graph = new Map<string, readonly string[]>();
238
+
239
+ for (const pkg of packages) {
240
+ const deps = Object.keys(pkg.dependencies).filter((depName) =>
241
+ packageMap.has(depName),
242
+ );
243
+ graph.set(pkg.name, deps);
244
+ }
245
+
246
+ return graph;
247
+ };
@@ -1,26 +1,15 @@
1
1
  #!/usr/bin/env tsx
2
2
 
3
- import { spawn } from 'child_process';
4
3
  import {
5
- createPromise,
6
4
  hasKey,
7
5
  isNotUndefined,
8
6
  isRecord,
9
7
  isString,
10
- pipe,
8
+ Json,
11
9
  Result,
12
10
  } from 'ts-data-forge';
13
11
  import '../../node-global.mjs';
14
-
15
- const DEBUG = false as boolean;
16
-
17
- // Get all workspace packages
18
- type Package = Readonly<{
19
- name: string;
20
- path: string;
21
- packageJson: JsonValue;
22
- dependencies: ReadonlyRecord<string, string>;
23
- }>;
12
+ import { type Package } from './types.mjs';
24
13
 
25
14
  /**
26
15
  * Retrieves all workspace packages from a monorepo based on the workspace patterns
@@ -46,6 +35,8 @@ export const getWorkspacePackages = async (
46
35
  const matches = await glob(pattern, {
47
36
  cwd: rootPackageJsonDir,
48
37
  ignore: ['**/node_modules/**'],
38
+ onlyDirectories: true,
39
+ absolute: true,
49
40
  });
50
41
 
51
42
  const packageJsonList: readonly (
@@ -53,15 +44,19 @@ export const getWorkspacePackages = async (
53
44
  | undefined
54
45
  )[] = await Promise.all(
55
46
  matches.map(async (match) => {
56
- const packagePath = path.join(rootPackageJsonDir, match);
47
+ const maybePackagePath = path.join(match, 'package.json');
57
48
 
58
49
  const result = await Result.fromPromise(
59
- fs.readFile(path.join(packagePath, 'package.json'), 'utf8'),
50
+ fs.readFile(maybePackagePath, 'utf8'),
60
51
  );
61
52
 
62
53
  if (Result.isErr(result)) return undefined;
63
54
 
64
- return [packagePath, result.value] as const;
55
+ const parsed = Json.parse(result.value);
56
+
57
+ if (Result.isErr(parsed)) return undefined;
58
+
59
+ return [maybePackagePath, parsed.value] as const;
65
60
  }),
66
61
  );
67
62
 
@@ -70,7 +65,7 @@ export const getWorkspacePackages = async (
70
65
  .filter(isNotUndefined)
71
66
  .map(([packagePath, packageJson]) => ({
72
67
  name: getStrFromJsonValue(packageJson, 'name'),
73
- path: packagePath,
68
+ path: path.dirname(packagePath),
74
69
  packageJson,
75
70
  dependencies: {
76
71
  ...getKeyValueRecordFromJsonValue(packageJson, 'dependencies'),
@@ -121,237 +116,3 @@ const getKeyValueRecordFromJsonValue = (
121
116
  );
122
117
  return Object.fromEntries(entries);
123
118
  };
124
-
125
- /**
126
- * Builds a dependency graph from the given packages, mapping each package name
127
- * to its internal workspace dependencies.
128
- * @param packages - Array of Package objects to analyze
129
- * @returns A readonly map where keys are package names and values are arrays of their dependency package names
130
- */
131
- const buildDependencyGraph = (
132
- packages: readonly Package[],
133
- ): ReadonlyMap<string, readonly string[]> => {
134
- const packageMap = new Map(packages.map((p) => [p.name, p]));
135
- const graph = new Map<string, string[]>();
136
-
137
- for (const pkg of packages) {
138
- const deps = Object.keys(pkg.dependencies).filter((depName) =>
139
- packageMap.has(depName),
140
- );
141
- graph.set(pkg.name, deps);
142
- }
143
-
144
- return graph;
145
- };
146
-
147
- /**
148
- * Performs a topological sort on packages based on their dependencies,
149
- * ensuring dependencies are ordered before their dependents.
150
- * @param packages - Array of Package objects to sort
151
- * @returns An array of packages in dependency order (dependencies first)
152
- */
153
- const topologicalSortPackages = (
154
- packages: readonly Package[],
155
- ): readonly Package[] => {
156
- const graph = buildDependencyGraph(packages);
157
- const visited = new Set<string>();
158
- const result: string[] = [];
159
-
160
- const packageMap = new Map(packages.map((p) => [p.name, p]));
161
-
162
- const visit = (pkgName: string): void => {
163
- if (visited.has(pkgName)) return;
164
- visited.add(pkgName);
165
-
166
- const deps = graph.get(pkgName) ?? [];
167
- for (const dep of deps) {
168
- visit(dep);
169
- }
170
-
171
- result.push(pkgName);
172
- };
173
-
174
- for (const pkg of packages) {
175
- visit(pkg.name);
176
- }
177
-
178
- return result
179
- .map((pkgName) => packageMap.get(pkgName))
180
- .filter(isNotUndefined);
181
- };
182
-
183
- /**
184
- * Executes a npm script in a specific package directory.
185
- * @param pkg - The package object containing path and metadata
186
- * @param scriptName - The name of the npm script to execute
187
- * @param options - Configuration options
188
- * @param options.prefix - Whether to prefix output with package name (default: true)
189
- * @returns A promise that resolves to execution result with exit code or skipped flag
190
- */
191
- const executeScript = (
192
- pkg: Package,
193
- scriptName: string,
194
- { prefix = true }: Readonly<{ prefix?: boolean }> = {},
195
- ): Promise<Result<Readonly<{ code?: number; skipped?: boolean }>, Error>> =>
196
- pipe(
197
- createPromise(
198
- (
199
- resolve: (
200
- value: Readonly<{ code?: number; skipped?: boolean }>,
201
- ) => void,
202
- reject: (reason: unknown) => void,
203
- ) => {
204
- const packageJsonScripts =
205
- isRecord(pkg.packageJson) && isRecord(pkg.packageJson['scripts'])
206
- ? pkg.packageJson['scripts']
207
- : {};
208
-
209
- const hasScript = hasKey(packageJsonScripts, scriptName);
210
- if (!hasScript) {
211
- resolve({ skipped: true });
212
- return;
213
- }
214
-
215
- const prefixStr = prefix ? `[${pkg.name}] ` : '';
216
- const proc = spawn('npm', ['run', scriptName], {
217
- cwd: pkg.path,
218
- shell: true,
219
- stdio: 'pipe',
220
- });
221
-
222
- proc.stdout.on('data', (data: Readonly<Buffer>) => {
223
- process.stdout.write(prefixStr + data.toString());
224
- });
225
-
226
- proc.stderr.on('data', (data: Readonly<Buffer>) => {
227
- process.stderr.write(prefixStr + data.toString());
228
- });
229
-
230
- proc.on('close', (code: number | null) => {
231
- if (code === 0) {
232
- resolve({ code });
233
- } else {
234
- reject(new Error(`${pkg.name} exited with code ${code}`));
235
- }
236
- });
237
-
238
- proc.on('error', reject);
239
- },
240
- ),
241
- ).map((result) =>
242
- result.then(
243
- Result.mapErr((err) => {
244
- const errorMessage: string =
245
- err instanceof Error
246
- ? err.message
247
- : isRecord(err) && hasKey(err, 'message')
248
- ? (err.message?.toString() ?? 'Unknown error message')
249
- : 'Unknown error';
250
-
251
- console.error(`\nError in ${pkg.name}:`, errorMessage);
252
- return err instanceof Error ? err : new Error(errorMessage);
253
- }),
254
- ),
255
- ).value;
256
-
257
- /**
258
- * Executes a npm script across multiple packages in parallel with a concurrency limit.
259
- * @param packages - Array of Package objects to execute the script in
260
- * @param scriptName - The name of the npm script to execute
261
- * @param concurrency - Maximum number of packages to process simultaneously (default: 3)
262
- * @returns A promise that resolves to an array of execution results
263
- */
264
- export const executeParallel = async (
265
- packages: readonly Package[],
266
- scriptName: string,
267
- concurrency: number = 3,
268
- ): Promise<
269
- readonly Result<Readonly<{ code?: number; skipped?: boolean }>, Error>[]
270
- > => {
271
- const mut_resultPromises: Promise<
272
- Result<Readonly<{ code?: number; skipped?: boolean }>, Error>
273
- >[] = [];
274
-
275
- const executing = new Set<Promise<unknown>>();
276
-
277
- for (const pkg of packages) {
278
- const promise = executeScript(pkg, scriptName);
279
-
280
- mut_resultPromises.push(promise);
281
-
282
- const wrappedPromise = promise.finally(() => {
283
- executing.delete(wrappedPromise);
284
- if (DEBUG) {
285
- console.debug('executing size', executing.size);
286
- }
287
- });
288
-
289
- executing.add(wrappedPromise);
290
-
291
- if (DEBUG) {
292
- console.debug('executing size', executing.size);
293
- }
294
-
295
- // If we reach concurrency limit, wait for one to finish
296
- if (executing.size >= concurrency) {
297
- // eslint-disable-next-line no-await-in-loop
298
- await Promise.race(executing);
299
- }
300
- }
301
-
302
- return Promise.all(mut_resultPromises);
303
- };
304
-
305
- /**
306
- * Executes a npm script across packages in dependency order stages.
307
- * Packages are grouped into stages where each stage contains packages whose
308
- * dependencies have been completed in previous stages.
309
- * @param packages - Array of Package objects to execute the script in
310
- * @param scriptName - The name of the npm script to execute
311
- * @param concurrency - Maximum number of packages to process simultaneously within each stage (default: 3)
312
- * @returns A promise that resolves when all stages are complete
313
- */
314
- export const executeStages = async (
315
- packages: readonly Package[],
316
- scriptName: string,
317
- concurrency: number = 3,
318
- ): Promise<void> => {
319
- const sorted = topologicalSortPackages(packages);
320
-
321
- const stages: (readonly Package[])[] = [];
322
- const completed = new Set<string>();
323
-
324
- const dependencyGraph = buildDependencyGraph(packages);
325
-
326
- while (completed.size < sorted.length) {
327
- const stage: Package[] = [];
328
-
329
- for (const pkg of sorted) {
330
- if (completed.has(pkg.name)) continue;
331
-
332
- const deps = dependencyGraph.get(pkg.name) ?? [];
333
- const depsCompleted = deps.every((dep) => completed.has(dep));
334
-
335
- if (depsCompleted) {
336
- stage.push(pkg);
337
- }
338
- }
339
-
340
- if (stage.length === 0) {
341
- throw new Error('Circular dependency detected');
342
- }
343
-
344
- stages.push(stage);
345
- for (const pkg of stage) completed.add(pkg.name);
346
- }
347
-
348
- console.log(`\nExecuting ${scriptName} in ${stages.length} stages...\n`);
349
-
350
- for (const [i, stage] of stages.entries()) {
351
- if (stage.length > 0) {
352
- console.log(`Stage ${i + 1}: ${stage.map((p) => p.name).join(', ')}`);
353
- // eslint-disable-next-line no-await-in-loop
354
- await executeParallel(stage, scriptName, concurrency);
355
- }
356
- }
357
- };
@@ -1,3 +1,5 @@
1
+ export * from './execute-parallel.mjs';
1
2
  export * from './get-workspace-packages.mjs';
2
3
  export * from './run-cmd-in-parallel.mjs';
3
4
  export * from './run-cmd-in-stages.mjs';
5
+ export * from './types.mjs';
@@ -1,9 +1,7 @@
1
1
  #!/usr/bin/env tsx
2
2
 
3
- import {
4
- executeParallel,
5
- getWorkspacePackages,
6
- } from './get-workspace-packages.mjs';
3
+ import { executeParallel } from './execute-parallel.mjs';
4
+ import { getWorkspacePackages } from './get-workspace-packages.mjs';
7
5
 
8
6
  /**
9
7
  * Executes a npm script command across all workspace packages in parallel.
@@ -1,9 +1,7 @@
1
1
  #!/usr/bin/env tsx
2
2
 
3
- import {
4
- executeStages,
5
- getWorkspacePackages,
6
- } from './get-workspace-packages.mjs';
3
+ import { executeStages } from './execute-parallel.mjs';
4
+ import { getWorkspacePackages } from './get-workspace-packages.mjs';
7
5
 
8
6
  /**
9
7
  * Executes a npm script command across all workspace packages in dependency order stages.
@@ -0,0 +1,7 @@
1
+ // Get all workspace packages
2
+ export type Package = Readonly<{
3
+ name: string;
4
+ path: string;
5
+ packageJson: JsonValue;
6
+ dependencies: ReadonlyRecord<string, string>;
7
+ }>;