Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

each-package

Package Overview
Dependencies
Maintainers
1
Versions
237
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

each-package - npm Package Compare versions

Comparing version
1.4.7
to
1.4.8
+2
-7
dist/cjs/lib/packageLayers.d.cts
import { type Entry } from 'fs-iterator';
import { type DependencyGraph } from 'topological-sort-group';
export interface PackageEntry extends Entry {

@@ -10,9 +11,3 @@ package: {

import type { EachOptions } from '../types.js';
export interface PackageGraph {
entries: Record<string, PackageEntry>;
dependencies: Record<string, string[]>;
dependents: Record<string, string[]>;
roots: string[];
}
export type Callback = (err?: Error, result?: PackageEntry[][] | PackageGraph) => undefined;
export type Callback = (err?: Error, result?: PackageEntry[][] | DependencyGraph<PackageEntry>) => undefined;
export default function packageLayers(options: EachOptions, callback: Callback): undefined;
import { type Entry } from 'fs-iterator';
import { type DependencyGraph } from 'topological-sort-group';
export interface PackageEntry extends Entry {

@@ -10,9 +11,3 @@ package: {

import type { EachOptions } from '../types.js';
export interface PackageGraph {
entries: Record<string, PackageEntry>;
dependencies: Record<string, string[]>;
dependents: Record<string, string[]>;
roots: string[];
}
export type Callback = (err?: Error, result?: PackageEntry[][] | PackageGraph) => undefined;
export type Callback = (err?: Error, result?: PackageEntry[][] | DependencyGraph<PackageEntry>) => undefined;
export default function packageLayers(options: EachOptions, callback: Callback): undefined;

@@ -13,3 +13,2 @@ "use strict";

var _fsiterator = /*#__PURE__*/ _interop_require_default(require("fs-iterator"));
var _lodashfind = /*#__PURE__*/ _interop_require_default(require("lodash.find"));
var _path = /*#__PURE__*/ _interop_require_default(require("path"));

@@ -111,118 +110,63 @@ var _removebombuffer = /*#__PURE__*/ _interop_require_default(require("remove-bom-buffer"));

}
var graph = new _topologicalsortgroup.default({
path: 'package.name'
});
entries.forEach(function(entry) {
graph.add(entry);
});
// Build maps for streaming execution
var entriesMap = {};
var dependenciesMap = {};
var dependentsMap = {};
entries.forEach(function(entry) {
entriesMap[entry.package.name] = entry;
dependenciesMap[entry.package.name] = [];
dependentsMap[entry.package.name] = [];
});
// build graph edges from dependencies and optionalDependencies
entries.forEach(function(entry) {
var _loop = function(name) {
var found = (0, _lodashfind.default)(entries, function(x) {
return x.package.name === name;
}); // dependency in graph
if (found) {
graph.add(name, entry.package.name);
// Track dependencies: entry depends on name
dependenciesMap[entry.package.name].push(name);
// Track dependents: name has entry as a dependent
dependentsMap[name].push(entry.package.name);
// Build nodes map
var nodes = {};
var dependencies = {};
for(var i = 0; i < entries.length; i++){
var entry = entries[i];
nodes[entry.package.name] = entry;
dependencies[entry.package.name] = [];
}
// Build dependencies from package.json dependencies and optionalDependencies
for(var j = 0; j < entries.length; j++){
var e = entries[j];
var deps = _object_spread({}, e.package.dependencies || {}, e.package.optionalDependencies || {});
for(var name in deps){
if (nodes[name]) {
// This package depends on another package in the graph
dependencies[e.package.name].push(name);
}
};
var deps = _object_spread({}, entry.package.dependencies || {}, entry.package.optionalDependencies || {});
for(var name in deps)_loop(name);
}
}
// Use Graph for cycle detection
var graph = _topologicalsortgroup.default.from({
nodes: nodes,
dependencies: dependencies
});
var _graph_sort = graph.sort(), cycles = _graph_sort.cycles, duplicates = _graph_sort.duplicates;
if (cycles && cycles.length) cycles.forEach(function(c) {
console.log("Skipping cycle: ".concat(c.join(' -> ')));
});
if (duplicates && duplicates.length) duplicates.forEach(function(d) {
console.log("Skipping duplicates: ".concat(JSON.stringify(d.values.map(function(x) {
return x.path;
}))));
});
// Find roots (packages with no internal dependencies)
var roots = [];
for(var name in dependenciesMap){
if (dependenciesMap[name].length === 0) {
roots.push(name);
}
if (cycles && cycles.length) {
cycles.forEach(function(c) {
console.log("Skipping cycle: ".concat(c.join(' -> ')));
});
}
if (duplicates && duplicates.length) {
duplicates.forEach(function(d) {
console.log("Skipping duplicates: ".concat(JSON.stringify(d.values.map(function(x) {
return x.path;
}))));
});
}
// Remove cyclic packages from the graph
if (cycles && cycles.length) {
var cyclicPackages = {};
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
try {
for(var _iterator = cycles[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
var c = _step.value;
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
try {
for(var _iterator1 = c[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
var n = _step1.value;
cyclicPackages[String(n)] = true;
}
} catch (err) {
_didIteratorError1 = true;
_iteratorError1 = err;
} finally{
try {
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
_iterator1.return();
}
} finally{
if (_didIteratorError1) {
throw _iteratorError1;
}
}
}
for(var ci = 0; ci < cycles.length; ci++){
var c = cycles[ci];
for(var cj = 0; cj < c.length; cj++){
cyclicPackages[String(c[cj])] = true;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally{
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally{
if (_didIteratorError) {
throw _iteratorError;
}
}
}
for(var name1 in cyclicPackages){
delete entriesMap[name1];
delete dependenciesMap[name1];
delete dependentsMap[name1];
var rootIdx = roots.indexOf(name1);
if (rootIdx >= 0) roots.splice(rootIdx, 1);
for(var cyclicName in cyclicPackages){
delete nodes[cyclicName];
delete dependencies[cyclicName];
}
// Remove references to cyclic packages from dependencies/dependents
for(var key in dependenciesMap){
var deps = dependenciesMap[key];
for(var i = deps.length - 1; i >= 0; i--){
if (cyclicPackages[deps[i]]) deps.splice(i, 1);
// Remove references to cyclic packages from dependencies
for(var key in dependencies){
var depList = dependencies[key];
for(var di = depList.length - 1; di >= 0; di--){
if (cyclicPackages[depList[di]]) depList.splice(di, 1);
}
}
for(var key1 in dependentsMap){
var deps1 = dependentsMap[key1];
for(var i1 = deps1.length - 1; i1 >= 0; i1--){
if (cyclicPackages[deps1[i1]]) deps1.splice(i1, 1);
}
}
}
return callback(null, {
entries: entriesMap,
dependencies: dependenciesMap,
dependents: dependentsMap,
roots: roots
nodes: nodes,
dependencies: dependencies
});

@@ -229,0 +173,0 @@ });

@@ -1,1 +0,1 @@

{"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/lib/packageLayers.ts"],"sourcesContent":["import fs from 'fs';\nimport Iterator, { type Entry } from 'fs-iterator';\nimport find from 'lodash.find';\nimport path from 'path';\nimport removeBOM from 'remove-bom-buffer';\nimport match from 'test-match';\nimport Graph from 'topological-sort-group';\n\nexport interface PackageEntry extends Entry {\n package: { name: string; dependencies: object; optionalDependencies: object };\n}\n\nimport type { EachOptions } from '../types.ts';\n\nexport interface PackageGraph {\n entries: Record<string, PackageEntry>;\n dependencies: Record<string, string[]>;\n dependents: Record<string, string[]>;\n roots: string[];\n}\n\nexport type Callback = (err?: Error, result?: PackageEntry[][] | PackageGraph) => undefined;\n\nconst defaultIgnores = 'node_modules,.git';\n\nexport default function packageLayers(options: EachOptions, callback: Callback): undefined {\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n\n const cwd = options.cwd || process.cwd();\n\n const ignores = options.ignore ? options.ignore : defaultIgnores;\n const matcher = match({ exclude: ignores });\n\n const iterator = new Iterator(cwd as string, {\n filter: function filter(entry) {\n if (entry.stats.isDirectory() || entry.realStats?.isDirectory()) return entry.basename[0] !== '.' && matcher(entry.basename);\n if (entry.stats.isFile()) {\n // Only include package.json files\n if (entry.basename !== 'package.json') return false;\n // Exclude root package.json unless --root flag is set\n if (!options.root && entry.path === 'package.json') return false;\n return true;\n }\n return false;\n },\n depth,\n lstat: true,\n });\n const entries = [];\n iterator.forEach(\n (entry: PackageEntry, cb): undefined => {\n if (!entry.stats.isFile()) {\n cb();\n return;\n }\n fs.readFile(entry.fullPath, 'utf8', (err, contents) => {\n if (err) return cb(err);\n try {\n const pkg = JSON.parse(removeBOM(contents));\n if (pkg.private && !options.private) return cb();\n if (pkg.name === undefined) return cb(); // skip packages without names\n entry.package = pkg;\n entries.push(entry);\n cb();\n } catch (_err) {\n console.log(`Failed to parse JSON for ${entry.path}`);\n cb();\n }\n });\n },\n { concurrency: Infinity, callbacks: true },\n (err) => {\n if (err) return callback(err);\n\n // full graph at one layer, sorted by relative path\n if (!options.topological) {\n const sorted = entries.sort((a, b) => path.dirname(a.path).localeCompare(path.dirname(b.path))) as PackageEntry[];\n return callback(null, [sorted]);\n }\n\n const graph = new Graph<PackageEntry>({ path: 'package.name' });\n entries.forEach((entry) => {\n graph.add(entry);\n });\n\n // Build maps for streaming execution\n const entriesMap: Record<string, PackageEntry> = {};\n const dependenciesMap: Record<string, string[]> = {};\n const dependentsMap: Record<string, string[]> = {};\n\n entries.forEach((entry: PackageEntry) => {\n entriesMap[entry.package.name] = entry;\n dependenciesMap[entry.package.name] = [];\n dependentsMap[entry.package.name] = [];\n });\n\n // build graph edges from dependencies and optionalDependencies\n entries.forEach((entry: PackageEntry) => {\n const deps = { ...(entry.package.dependencies || {}), ...(entry.package.optionalDependencies || {}) };\n for (const name in deps) {\n const found = find(entries, (x) => x.package.name === name); // dependency in graph\n if (found) {\n graph.add(name, entry.package.name);\n // Track dependencies: entry depends on name\n dependenciesMap[entry.package.name].push(name);\n // Track dependents: name has entry as a dependent\n dependentsMap[name].push(entry.package.name);\n }\n }\n });\n\n const { cycles, duplicates } = graph.sort();\n if (cycles && cycles.length)\n cycles.forEach((c) => {\n console.log(`Skipping cycle: ${c.join(' -> ')}`);\n });\n if (duplicates && duplicates.length)\n duplicates.forEach((d) => {\n console.log(`Skipping duplicates: ${JSON.stringify(d.values.map((x) => x.path))}`);\n });\n\n // Find roots (packages with no internal dependencies)\n const roots: string[] = [];\n for (const name in dependenciesMap) {\n if (dependenciesMap[name].length === 0) {\n roots.push(name);\n }\n }\n\n // Remove cyclic packages from the graph\n if (cycles && cycles.length) {\n const cyclicPackages: Record<string, boolean> = {};\n for (const c of cycles) {\n for (const n of c) {\n cyclicPackages[String(n)] = true;\n }\n }\n for (const name in cyclicPackages) {\n delete entriesMap[name];\n delete dependenciesMap[name];\n delete dependentsMap[name];\n const rootIdx = roots.indexOf(name);\n if (rootIdx >= 0) roots.splice(rootIdx, 1);\n }\n // Remove references to cyclic packages from dependencies/dependents\n for (const key in dependenciesMap) {\n const deps = dependenciesMap[key];\n for (let i = deps.length - 1; i >= 0; i--) {\n if (cyclicPackages[deps[i]]) deps.splice(i, 1);\n }\n }\n for (const key in dependentsMap) {\n const deps = dependentsMap[key];\n for (let i = deps.length - 1; i >= 0; i--) {\n if (cyclicPackages[deps[i]]) deps.splice(i, 1);\n }\n }\n }\n\n return callback(null, {\n entries: entriesMap,\n dependencies: dependenciesMap,\n dependents: dependentsMap,\n roots,\n });\n }\n );\n}\n"],"names":["packageLayers","defaultIgnores","options","callback","depth","Infinity","cwd","process","ignores","ignore","matcher","match","exclude","iterator","Iterator","filter","entry","stats","isDirectory","realStats","basename","isFile","root","path","lstat","entries","forEach","cb","fs","readFile","fullPath","err","contents","pkg","JSON","parse","removeBOM","private","name","undefined","package","push","_err","console","log","concurrency","callbacks","topological","sorted","sort","a","b","dirname","localeCompare","graph","Graph","add","entriesMap","dependenciesMap","dependentsMap","found","find","x","deps","dependencies","optionalDependencies","cycles","duplicates","length","c","join","d","stringify","values","map","roots","cyclicPackages","n","String","rootIdx","indexOf","splice","key","i","dependents"],"mappings":"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"}
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/lib/packageLayers.ts"],"sourcesContent":["import fs from 'fs';\nimport Iterator, { type Entry } from 'fs-iterator';\nimport path from 'path';\nimport removeBOM from 'remove-bom-buffer';\nimport match from 'test-match';\nimport Graph, { type DependencyGraph } from 'topological-sort-group';\n\nexport interface PackageEntry extends Entry {\n package: { name: string; dependencies: object; optionalDependencies: object };\n}\n\nimport type { EachOptions } from '../types.ts';\n\nexport type Callback = (err?: Error, result?: PackageEntry[][] | DependencyGraph<PackageEntry>) => undefined;\n\nconst defaultIgnores = 'node_modules,.git';\n\nexport default function packageLayers(options: EachOptions, callback: Callback): undefined {\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n\n const cwd = options.cwd || process.cwd();\n\n const ignores = options.ignore ? options.ignore : defaultIgnores;\n const matcher = match({ exclude: ignores });\n\n const iterator = new Iterator(cwd as string, {\n filter: function filter(entry) {\n if (entry.stats.isDirectory() || entry.realStats?.isDirectory()) return entry.basename[0] !== '.' && matcher(entry.basename);\n if (entry.stats.isFile()) {\n // Only include package.json files\n if (entry.basename !== 'package.json') return false;\n // Exclude root package.json unless --root flag is set\n if (!options.root && entry.path === 'package.json') return false;\n return true;\n }\n return false;\n },\n depth,\n lstat: true,\n });\n const entries: PackageEntry[] = [];\n iterator.forEach(\n (entry: PackageEntry, cb): undefined => {\n if (!entry.stats.isFile()) {\n cb();\n return;\n }\n fs.readFile(entry.fullPath, 'utf8', (err, contents) => {\n if (err) return cb(err);\n try {\n const pkg = JSON.parse(removeBOM(contents));\n if (pkg.private && !options.private) return cb();\n if (pkg.name === undefined) return cb(); // skip packages without names\n entry.package = pkg;\n entries.push(entry);\n cb();\n } catch (_err) {\n console.log(`Failed to parse JSON for ${entry.path}`);\n cb();\n }\n });\n },\n { concurrency: Infinity, callbacks: true },\n (err) => {\n if (err) return callback(err);\n\n // full graph at one layer, sorted by relative path\n if (!options.topological) {\n const sorted = entries.sort((a, b) => path.dirname(a.path).localeCompare(path.dirname(b.path))) as PackageEntry[];\n return callback(null, [sorted]);\n }\n\n // Build nodes map\n const nodes: Record<string, PackageEntry> = {};\n const dependencies: Record<string, string[]> = {};\n for (var i = 0; i < entries.length; i++) {\n var entry = entries[i];\n nodes[entry.package.name] = entry;\n dependencies[entry.package.name] = [];\n }\n\n // Build dependencies from package.json dependencies and optionalDependencies\n for (var j = 0; j < entries.length; j++) {\n var e = entries[j];\n var deps = { ...(e.package.dependencies || {}), ...(e.package.optionalDependencies || {}) };\n for (var name in deps) {\n if (nodes[name]) {\n // This package depends on another package in the graph\n dependencies[e.package.name].push(name);\n }\n }\n }\n\n // Use Graph for cycle detection\n const graph = Graph.from<PackageEntry>({ nodes, dependencies });\n const { cycles, duplicates } = graph.sort();\n\n if (cycles && cycles.length) {\n cycles.forEach((c) => {\n console.log(`Skipping cycle: ${c.join(' -> ')}`);\n });\n }\n if (duplicates && duplicates.length) {\n duplicates.forEach((d) => {\n console.log(`Skipping duplicates: ${JSON.stringify(d.values.map((x) => x.path))}`);\n });\n }\n\n // Remove cyclic packages from the graph\n if (cycles && cycles.length) {\n const cyclicPackages: Record<string, boolean> = {};\n for (var ci = 0; ci < cycles.length; ci++) {\n var c = cycles[ci];\n for (var cj = 0; cj < c.length; cj++) {\n cyclicPackages[String(c[cj])] = true;\n }\n }\n for (var cyclicName in cyclicPackages) {\n delete nodes[cyclicName];\n delete dependencies[cyclicName];\n }\n // Remove references to cyclic packages from dependencies\n for (var key in dependencies) {\n var depList = dependencies[key];\n for (var di = depList.length - 1; di >= 0; di--) {\n if (cyclicPackages[depList[di]]) depList.splice(di, 1);\n }\n }\n }\n\n return callback(null, { nodes, dependencies });\n }\n );\n}\n"],"names":["packageLayers","defaultIgnores","options","callback","depth","Infinity","cwd","process","ignores","ignore","matcher","match","exclude","iterator","Iterator","filter","entry","stats","isDirectory","realStats","basename","isFile","root","path","lstat","entries","forEach","cb","fs","readFile","fullPath","err","contents","pkg","JSON","parse","removeBOM","private","name","undefined","package","push","_err","console","log","concurrency","callbacks","topological","sorted","sort","a","b","dirname","localeCompare","nodes","dependencies","i","length","j","e","deps","optionalDependencies","graph","Graph","from","cycles","duplicates","c","join","d","stringify","values","map","x","cyclicPackages","ci","cj","String","cyclicName","key","depList","di","splice"],"mappings":"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"}

@@ -14,2 +14,3 @@ "use strict";

var _spawnstreaming = /*#__PURE__*/ _interop_require_default(require("spawn-streaming"));
var _topologicalscheduler = /*#__PURE__*/ _interop_require_default(require("topological-scheduler"));
var _loadSpawnTermts = /*#__PURE__*/ _interop_require_default(require("./lib/loadSpawnTerm.js"));

@@ -155,55 +156,5 @@ var _packageLayersts = /*#__PURE__*/ _interop_require_default(require("./lib/packageLayers.js"));

}
// Topological mode: streaming execution
// Topological mode: use topological-scheduler
var graph = result;
var entries = graph.entries, dependencies = graph.dependencies, dependents = graph.dependents, roots = graph.roots;
// Track in-degrees (number of incomplete dependencies)
var inDegree = {};
for(var name in dependencies){
inDegree[name] = dependencies[name].length;
}
var completed = {};
var failed = {};
var skipped = {};
var running = {};
var runningCount = 0;
var completedCount = 0;
var ready = roots.slice();
// Count total entries
var totalEntries = 0;
for(var _name in entries){
totalEntries++;
}
var hasFailedDependency = function(name) {
if (!options.failDependents) return false;
var deps = dependencies[name] || [];
for(var i = 0; i < deps.length; i++){
if (failed[deps[i]] || skipped[deps[i]]) return true;
}
return false;
};
var onComplete = function(name, didFail) {
var wasSkipped = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : false;
delete running[name];
runningCount--;
completed[name] = true;
completedCount++;
if (didFail) failed[name] = true;
if (wasSkipped) skipped[name] = true;
// Unlock dependents
var deps = dependents[name] || [];
for(var i = 0; i < deps.length; i++){
var dep = deps[i];
inDegree[dep]--;
if (inDegree[dep] === 0) {
ready.push(dep);
}
}
if (completedCount === totalEntries) {
finalize();
} else {
tryStartNext();
}
};
var runPackage = function(name) {
var entry = entries[name];
(0, _topologicalscheduler.default)(graph, function(entry, _id, cb) {
var spawnOptions = _object_spread_props(_object_spread({}, options), {

@@ -225,3 +176,3 @@ cwd: _path.default.dirname(entry.fullPath)

});
onComplete(name, !!err);
cb(err, res);
};

@@ -235,23 +186,8 @@ if (session) session.spawn(command, args, spawnOptions, {

}, next);
};
var tryStartNext = function() {
while(ready.length > 0 && runningCount < concurrency){
var name = ready.shift();
if (hasFailedDependency(name)) {
// Skip this package and mark as skipped
skipped[name] = true;
onComplete(name, false, true);
continue;
}
running[name] = true;
runningCount++;
runPackage(name);
}
};
// Handle empty graph
if (totalEntries === 0) {
finalize();
return;
}
tryStartNext();
}, {
concurrency: concurrency,
failDependents: options.failDependents
}, function(err) {
finalize(err);
});
});

@@ -258,0 +194,0 @@ });

@@ -1,1 +0,1 @@

{"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/worker.ts"],"sourcesContent":["import type { SpawnResult } from 'cross-spawn-cb';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport spawnStreaming from 'spawn-streaming';\nimport loadSpawnTerm from './lib/loadSpawnTerm.ts';\nimport packageLayers, { type PackageEntry, type PackageGraph } from './lib/packageLayers.ts';\n\nimport type { EachCallback, EachError, EachOptions, EachResult } from './types.ts';\n\nexport default function worker(command: string, args: string[], options: EachOptions, callback: EachCallback): undefined {\n // Load spawn-term lazily\n loadSpawnTerm((loadErr, mod) => {\n if (loadErr) return callback(loadErr);\n const createSession = mod.createSession;\n\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n const concurrency = typeof options.concurrency === 'undefined' ? 1 : options.concurrency;\n\n packageLayers(options, (err, result) => {\n if (err) return callback(err);\n\n // Create session once for all processes (only when interactive is explicitly enabled, e.g. by CLI)\n const interactive = !!options.interactive;\n const quotedArgs = args.map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg));\n const session = createSession && !options.streaming && interactive ? createSession({ header: `${process.cwd()}> ${command} ${quotedArgs.join(' ')}`, showStatusBar: true, interactive }) : null;\n\n // Show command header when not using terminal session (unless silent)\n if (!session && !options.silent) {\n console.log(`$ ${command} ${quotedArgs.join(' ')}`);\n }\n\n const results: EachResult[] = [];\n\n const finalize = (err?: Error): void => {\n if (err) (err as EachError).results = results;\n if (session) {\n session.waitAndClose(() => {\n err ? callback(err) : callback(null, results);\n });\n } else {\n err ? callback(err) : callback(null, results);\n }\n };\n\n // Non-topological mode: layers is PackageEntry[][]\n if (Array.isArray(result)) {\n const layers = result as PackageEntry[][];\n const processLayers = (layers: PackageEntry[][], done: (err?: Error) => void): void => {\n if (layers.length === 0) {\n done();\n return;\n }\n const layerEntries = layers.shift();\n\n const queue = new Queue(concurrency);\n layerEntries.forEach((entry) => {\n queue.defer((cb: () => void) => {\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): undefined => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n cb();\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n });\n });\n\n queue.await((err: Error) => (err ? done(err) : processLayers(layers, done)));\n };\n\n processLayers(layers, finalize);\n return;\n }\n\n // Topological mode: streaming execution\n const graph = result as PackageGraph;\n const { entries, dependencies, dependents, roots } = graph;\n\n // Track in-degrees (number of incomplete dependencies)\n const inDegree: Record<string, number> = {};\n for (const name in dependencies) {\n inDegree[name] = dependencies[name].length;\n }\n\n const completed: Record<string, boolean> = {};\n const failed: Record<string, boolean> = {};\n const skipped: Record<string, boolean> = {};\n const running: Record<string, boolean> = {};\n let runningCount = 0;\n let completedCount = 0;\n const ready: string[] = roots.slice();\n\n // Count total entries\n let totalEntries = 0;\n for (const _name in entries) {\n totalEntries++;\n }\n\n const hasFailedDependency = (name: string): boolean => {\n if (!options.failDependents) return false;\n const deps = dependencies[name] || [];\n for (let i = 0; i < deps.length; i++) {\n if (failed[deps[i]] || skipped[deps[i]]) return true;\n }\n return false;\n };\n\n const onComplete = (name: string, didFail: boolean, wasSkipped = false): void => {\n delete running[name];\n runningCount--;\n completed[name] = true;\n completedCount++;\n if (didFail) failed[name] = true;\n if (wasSkipped) skipped[name] = true;\n\n // Unlock dependents\n const deps = dependents[name] || [];\n for (let i = 0; i < deps.length; i++) {\n const dep = deps[i];\n inDegree[dep]--;\n if (inDegree[dep] === 0) {\n ready.push(dep);\n }\n }\n\n if (completedCount === totalEntries) {\n finalize();\n } else {\n tryStartNext();\n }\n };\n\n const runPackage = (name: string): void => {\n const entry = entries[name];\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): undefined => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n onComplete(name, !!err);\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n };\n\n const tryStartNext = (): void => {\n while (ready.length > 0 && runningCount < concurrency) {\n const name = ready.shift();\n if (hasFailedDependency(name)) {\n // Skip this package and mark as skipped\n skipped[name] = true;\n onComplete(name, false, true);\n continue;\n }\n running[name] = true;\n runningCount++;\n runPackage(name);\n }\n };\n\n // Handle empty graph\n if (totalEntries === 0) {\n finalize();\n return;\n }\n\n tryStartNext();\n });\n });\n}\n"],"names":["worker","command","args","options","callback","loadSpawnTerm","loadErr","mod","createSession","depth","Infinity","concurrency","packageLayers","err","result","interactive","quotedArgs","map","arg","test","session","streaming","header","process","cwd","join","showStatusBar","silent","console","log","results","finalize","waitAndClose","Array","isArray","layers","processLayers","done","length","layerEntries","shift","queue","Queue","forEach","entry","defer","cb","spawnOptions","path","dirname","fullPath","prefix","next","res","message","indexOf","push","error","spawn","group","expanded","spawnStreaming","await","graph","entries","dependencies","dependents","roots","inDegree","name","completed","failed","skipped","running","runningCount","completedCount","ready","slice","totalEntries","_name","hasFailedDependency","failDependents","deps","i","onComplete","didFail","wasSkipped","dep","tryStartNext","runPackage"],"mappings":"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"}
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/worker.ts"],"sourcesContent":["import type { SpawnResult } from 'cross-spawn-cb';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport spawnStreaming from 'spawn-streaming';\nimport schedule, { type DependencyGraph } from 'topological-scheduler';\nimport loadSpawnTerm from './lib/loadSpawnTerm.ts';\nimport packageLayers, { type PackageEntry } from './lib/packageLayers.ts';\n\nimport type { EachCallback, EachError, EachOptions, EachResult } from './types.ts';\n\nexport default function worker(command: string, args: string[], options: EachOptions, callback: EachCallback): undefined {\n // Load spawn-term lazily\n loadSpawnTerm((loadErr, mod) => {\n if (loadErr) return callback(loadErr);\n const createSession = mod.createSession;\n\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n const concurrency = typeof options.concurrency === 'undefined' ? 1 : options.concurrency;\n\n packageLayers(options, (err, result) => {\n if (err) return callback(err);\n\n // Create session once for all processes (only when interactive is explicitly enabled, e.g. by CLI)\n const interactive = !!options.interactive;\n const quotedArgs = args.map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg));\n const session = createSession && !options.streaming && interactive ? createSession({ header: `${process.cwd()}> ${command} ${quotedArgs.join(' ')}`, showStatusBar: true, interactive }) : null;\n\n // Show command header when not using terminal session (unless silent)\n if (!session && !options.silent) {\n console.log(`$ ${command} ${quotedArgs.join(' ')}`);\n }\n\n const results: EachResult[] = [];\n\n const finalize = (err?: Error): void => {\n if (err) (err as EachError).results = results;\n if (session) {\n session.waitAndClose(() => {\n err ? callback(err) : callback(null, results);\n });\n } else {\n err ? callback(err) : callback(null, results);\n }\n };\n\n // Non-topological mode: layers is PackageEntry[][]\n if (Array.isArray(result)) {\n const layers = result as PackageEntry[][];\n const processLayers = (layers: PackageEntry[][], done: (err?: Error) => void): void => {\n if (layers.length === 0) {\n done();\n return;\n }\n const layerEntries = layers.shift();\n\n const queue = new Queue(concurrency);\n layerEntries.forEach((entry) => {\n queue.defer((cb: () => void) => {\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): undefined => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n cb();\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n });\n });\n\n queue.await((err: Error) => (err ? done(err) : processLayers(layers, done)));\n };\n\n processLayers(layers, finalize);\n return;\n }\n\n // Topological mode: use topological-scheduler\n const graph = result as DependencyGraph<PackageEntry>;\n\n schedule(\n graph,\n (entry, _id, cb) => {\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): undefined => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n cb(err, res);\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n },\n { concurrency, failDependents: options.failDependents },\n (err) => {\n finalize(err);\n }\n );\n });\n });\n}\n"],"names":["worker","command","args","options","callback","loadSpawnTerm","loadErr","mod","createSession","depth","Infinity","concurrency","packageLayers","err","result","interactive","quotedArgs","map","arg","test","session","streaming","header","process","cwd","join","showStatusBar","silent","console","log","results","finalize","waitAndClose","Array","isArray","layers","processLayers","done","length","layerEntries","shift","queue","Queue","forEach","entry","defer","cb","spawnOptions","path","dirname","fullPath","prefix","next","res","message","indexOf","push","error","spawn","group","expanded","spawnStreaming","await","graph","schedule","_id","failDependents"],"mappings":"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"}
import { type Entry } from 'fs-iterator';
import { type DependencyGraph } from 'topological-sort-group';
export interface PackageEntry extends Entry {

@@ -10,9 +11,3 @@ package: {

import type { EachOptions } from '../types.js';
export interface PackageGraph {
entries: Record<string, PackageEntry>;
dependencies: Record<string, string[]>;
dependents: Record<string, string[]>;
roots: string[];
}
export type Callback = (err?: Error, result?: PackageEntry[][] | PackageGraph) => undefined;
export type Callback = (err?: Error, result?: PackageEntry[][] | DependencyGraph<PackageEntry>) => undefined;
export default function packageLayers(options: EachOptions, callback: Callback): undefined;
import fs from 'fs';
import Iterator from 'fs-iterator';
import find from 'lodash.find';
import path from 'path';

@@ -65,84 +64,66 @@ import removeBOM from 'remove-bom-buffer';

}
const graph = new Graph({
path: 'package.name'
});
entries.forEach((entry)=>{
graph.add(entry);
});
// Build maps for streaming execution
const entriesMap = {};
const dependenciesMap = {};
const dependentsMap = {};
entries.forEach((entry)=>{
entriesMap[entry.package.name] = entry;
dependenciesMap[entry.package.name] = [];
dependentsMap[entry.package.name] = [];
});
// build graph edges from dependencies and optionalDependencies
entries.forEach((entry)=>{
const deps = {
...entry.package.dependencies || {},
...entry.package.optionalDependencies || {}
// Build nodes map
const nodes = {};
const dependencies = {};
for(var i = 0; i < entries.length; i++){
var entry = entries[i];
nodes[entry.package.name] = entry;
dependencies[entry.package.name] = [];
}
// Build dependencies from package.json dependencies and optionalDependencies
for(var j = 0; j < entries.length; j++){
var e = entries[j];
var deps = {
...e.package.dependencies || {},
...e.package.optionalDependencies || {}
};
for(const name in deps){
const found = find(entries, (x)=>x.package.name === name); // dependency in graph
if (found) {
graph.add(name, entry.package.name);
// Track dependencies: entry depends on name
dependenciesMap[entry.package.name].push(name);
// Track dependents: name has entry as a dependent
dependentsMap[name].push(entry.package.name);
for(var name in deps){
if (nodes[name]) {
// This package depends on another package in the graph
dependencies[e.package.name].push(name);
}
}
}
// Use Graph for cycle detection
const graph = Graph.from({
nodes,
dependencies
});
const { cycles, duplicates } = graph.sort();
if (cycles && cycles.length) cycles.forEach((c)=>{
console.log(`Skipping cycle: ${c.join(' -> ')}`);
});
if (duplicates && duplicates.length) duplicates.forEach((d)=>{
console.log(`Skipping duplicates: ${JSON.stringify(d.values.map((x)=>x.path))}`);
});
// Find roots (packages with no internal dependencies)
const roots = [];
for(const name in dependenciesMap){
if (dependenciesMap[name].length === 0) {
roots.push(name);
}
if (cycles && cycles.length) {
cycles.forEach((c)=>{
console.log(`Skipping cycle: ${c.join(' -> ')}`);
});
}
if (duplicates && duplicates.length) {
duplicates.forEach((d)=>{
console.log(`Skipping duplicates: ${JSON.stringify(d.values.map((x)=>x.path))}`);
});
}
// Remove cyclic packages from the graph
if (cycles && cycles.length) {
const cyclicPackages = {};
for (const c of cycles){
for (const n of c){
cyclicPackages[String(n)] = true;
for(var ci = 0; ci < cycles.length; ci++){
var c = cycles[ci];
for(var cj = 0; cj < c.length; cj++){
cyclicPackages[String(c[cj])] = true;
}
}
for(const name in cyclicPackages){
delete entriesMap[name];
delete dependenciesMap[name];
delete dependentsMap[name];
const rootIdx = roots.indexOf(name);
if (rootIdx >= 0) roots.splice(rootIdx, 1);
for(var cyclicName in cyclicPackages){
delete nodes[cyclicName];
delete dependencies[cyclicName];
}
// Remove references to cyclic packages from dependencies/dependents
for(const key in dependenciesMap){
const deps = dependenciesMap[key];
for(let i = deps.length - 1; i >= 0; i--){
if (cyclicPackages[deps[i]]) deps.splice(i, 1);
// Remove references to cyclic packages from dependencies
for(var key in dependencies){
var depList = dependencies[key];
for(var di = depList.length - 1; di >= 0; di--){
if (cyclicPackages[depList[di]]) depList.splice(di, 1);
}
}
for(const key in dependentsMap){
const deps = dependentsMap[key];
for(let i = deps.length - 1; i >= 0; i--){
if (cyclicPackages[deps[i]]) deps.splice(i, 1);
}
}
}
return callback(null, {
entries: entriesMap,
dependencies: dependenciesMap,
dependents: dependentsMap,
roots
nodes,
dependencies
});
});
}

@@ -1,1 +0,1 @@

{"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/lib/packageLayers.ts"],"sourcesContent":["import fs from 'fs';\nimport Iterator, { type Entry } from 'fs-iterator';\nimport find from 'lodash.find';\nimport path from 'path';\nimport removeBOM from 'remove-bom-buffer';\nimport match from 'test-match';\nimport Graph from 'topological-sort-group';\n\nexport interface PackageEntry extends Entry {\n package: { name: string; dependencies: object; optionalDependencies: object };\n}\n\nimport type { EachOptions } from '../types.ts';\n\nexport interface PackageGraph {\n entries: Record<string, PackageEntry>;\n dependencies: Record<string, string[]>;\n dependents: Record<string, string[]>;\n roots: string[];\n}\n\nexport type Callback = (err?: Error, result?: PackageEntry[][] | PackageGraph) => undefined;\n\nconst defaultIgnores = 'node_modules,.git';\n\nexport default function packageLayers(options: EachOptions, callback: Callback): undefined {\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n\n const cwd = options.cwd || process.cwd();\n\n const ignores = options.ignore ? options.ignore : defaultIgnores;\n const matcher = match({ exclude: ignores });\n\n const iterator = new Iterator(cwd as string, {\n filter: function filter(entry) {\n if (entry.stats.isDirectory() || entry.realStats?.isDirectory()) return entry.basename[0] !== '.' && matcher(entry.basename);\n if (entry.stats.isFile()) {\n // Only include package.json files\n if (entry.basename !== 'package.json') return false;\n // Exclude root package.json unless --root flag is set\n if (!options.root && entry.path === 'package.json') return false;\n return true;\n }\n return false;\n },\n depth,\n lstat: true,\n });\n const entries = [];\n iterator.forEach(\n (entry: PackageEntry, cb): undefined => {\n if (!entry.stats.isFile()) {\n cb();\n return;\n }\n fs.readFile(entry.fullPath, 'utf8', (err, contents) => {\n if (err) return cb(err);\n try {\n const pkg = JSON.parse(removeBOM(contents));\n if (pkg.private && !options.private) return cb();\n if (pkg.name === undefined) return cb(); // skip packages without names\n entry.package = pkg;\n entries.push(entry);\n cb();\n } catch (_err) {\n console.log(`Failed to parse JSON for ${entry.path}`);\n cb();\n }\n });\n },\n { concurrency: Infinity, callbacks: true },\n (err) => {\n if (err) return callback(err);\n\n // full graph at one layer, sorted by relative path\n if (!options.topological) {\n const sorted = entries.sort((a, b) => path.dirname(a.path).localeCompare(path.dirname(b.path))) as PackageEntry[];\n return callback(null, [sorted]);\n }\n\n const graph = new Graph<PackageEntry>({ path: 'package.name' });\n entries.forEach((entry) => {\n graph.add(entry);\n });\n\n // Build maps for streaming execution\n const entriesMap: Record<string, PackageEntry> = {};\n const dependenciesMap: Record<string, string[]> = {};\n const dependentsMap: Record<string, string[]> = {};\n\n entries.forEach((entry: PackageEntry) => {\n entriesMap[entry.package.name] = entry;\n dependenciesMap[entry.package.name] = [];\n dependentsMap[entry.package.name] = [];\n });\n\n // build graph edges from dependencies and optionalDependencies\n entries.forEach((entry: PackageEntry) => {\n const deps = { ...(entry.package.dependencies || {}), ...(entry.package.optionalDependencies || {}) };\n for (const name in deps) {\n const found = find(entries, (x) => x.package.name === name); // dependency in graph\n if (found) {\n graph.add(name, entry.package.name);\n // Track dependencies: entry depends on name\n dependenciesMap[entry.package.name].push(name);\n // Track dependents: name has entry as a dependent\n dependentsMap[name].push(entry.package.name);\n }\n }\n });\n\n const { cycles, duplicates } = graph.sort();\n if (cycles && cycles.length)\n cycles.forEach((c) => {\n console.log(`Skipping cycle: ${c.join(' -> ')}`);\n });\n if (duplicates && duplicates.length)\n duplicates.forEach((d) => {\n console.log(`Skipping duplicates: ${JSON.stringify(d.values.map((x) => x.path))}`);\n });\n\n // Find roots (packages with no internal dependencies)\n const roots: string[] = [];\n for (const name in dependenciesMap) {\n if (dependenciesMap[name].length === 0) {\n roots.push(name);\n }\n }\n\n // Remove cyclic packages from the graph\n if (cycles && cycles.length) {\n const cyclicPackages: Record<string, boolean> = {};\n for (const c of cycles) {\n for (const n of c) {\n cyclicPackages[String(n)] = true;\n }\n }\n for (const name in cyclicPackages) {\n delete entriesMap[name];\n delete dependenciesMap[name];\n delete dependentsMap[name];\n const rootIdx = roots.indexOf(name);\n if (rootIdx >= 0) roots.splice(rootIdx, 1);\n }\n // Remove references to cyclic packages from dependencies/dependents\n for (const key in dependenciesMap) {\n const deps = dependenciesMap[key];\n for (let i = deps.length - 1; i >= 0; i--) {\n if (cyclicPackages[deps[i]]) deps.splice(i, 1);\n }\n }\n for (const key in dependentsMap) {\n const deps = dependentsMap[key];\n for (let i = deps.length - 1; i >= 0; i--) {\n if (cyclicPackages[deps[i]]) deps.splice(i, 1);\n }\n }\n }\n\n return callback(null, {\n entries: entriesMap,\n dependencies: dependenciesMap,\n dependents: dependentsMap,\n roots,\n });\n }\n );\n}\n"],"names":["fs","Iterator","find","path","removeBOM","match","Graph","defaultIgnores","packageLayers","options","callback","depth","Infinity","cwd","process","ignores","ignore","matcher","exclude","iterator","filter","entry","stats","isDirectory","realStats","basename","isFile","root","lstat","entries","forEach","cb","readFile","fullPath","err","contents","pkg","JSON","parse","private","name","undefined","package","push","_err","console","log","concurrency","callbacks","topological","sorted","sort","a","b","dirname","localeCompare","graph","add","entriesMap","dependenciesMap","dependentsMap","deps","dependencies","optionalDependencies","found","x","cycles","duplicates","length","c","join","d","stringify","values","map","roots","cyclicPackages","n","String","rootIdx","indexOf","splice","key","i","dependents"],"mappings":"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"}
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/lib/packageLayers.ts"],"sourcesContent":["import fs from 'fs';\nimport Iterator, { type Entry } from 'fs-iterator';\nimport path from 'path';\nimport removeBOM from 'remove-bom-buffer';\nimport match from 'test-match';\nimport Graph, { type DependencyGraph } from 'topological-sort-group';\n\nexport interface PackageEntry extends Entry {\n package: { name: string; dependencies: object; optionalDependencies: object };\n}\n\nimport type { EachOptions } from '../types.ts';\n\nexport type Callback = (err?: Error, result?: PackageEntry[][] | DependencyGraph<PackageEntry>) => undefined;\n\nconst defaultIgnores = 'node_modules,.git';\n\nexport default function packageLayers(options: EachOptions, callback: Callback): undefined {\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n\n const cwd = options.cwd || process.cwd();\n\n const ignores = options.ignore ? options.ignore : defaultIgnores;\n const matcher = match({ exclude: ignores });\n\n const iterator = new Iterator(cwd as string, {\n filter: function filter(entry) {\n if (entry.stats.isDirectory() || entry.realStats?.isDirectory()) return entry.basename[0] !== '.' && matcher(entry.basename);\n if (entry.stats.isFile()) {\n // Only include package.json files\n if (entry.basename !== 'package.json') return false;\n // Exclude root package.json unless --root flag is set\n if (!options.root && entry.path === 'package.json') return false;\n return true;\n }\n return false;\n },\n depth,\n lstat: true,\n });\n const entries: PackageEntry[] = [];\n iterator.forEach(\n (entry: PackageEntry, cb): undefined => {\n if (!entry.stats.isFile()) {\n cb();\n return;\n }\n fs.readFile(entry.fullPath, 'utf8', (err, contents) => {\n if (err) return cb(err);\n try {\n const pkg = JSON.parse(removeBOM(contents));\n if (pkg.private && !options.private) return cb();\n if (pkg.name === undefined) return cb(); // skip packages without names\n entry.package = pkg;\n entries.push(entry);\n cb();\n } catch (_err) {\n console.log(`Failed to parse JSON for ${entry.path}`);\n cb();\n }\n });\n },\n { concurrency: Infinity, callbacks: true },\n (err) => {\n if (err) return callback(err);\n\n // full graph at one layer, sorted by relative path\n if (!options.topological) {\n const sorted = entries.sort((a, b) => path.dirname(a.path).localeCompare(path.dirname(b.path))) as PackageEntry[];\n return callback(null, [sorted]);\n }\n\n // Build nodes map\n const nodes: Record<string, PackageEntry> = {};\n const dependencies: Record<string, string[]> = {};\n for (var i = 0; i < entries.length; i++) {\n var entry = entries[i];\n nodes[entry.package.name] = entry;\n dependencies[entry.package.name] = [];\n }\n\n // Build dependencies from package.json dependencies and optionalDependencies\n for (var j = 0; j < entries.length; j++) {\n var e = entries[j];\n var deps = { ...(e.package.dependencies || {}), ...(e.package.optionalDependencies || {}) };\n for (var name in deps) {\n if (nodes[name]) {\n // This package depends on another package in the graph\n dependencies[e.package.name].push(name);\n }\n }\n }\n\n // Use Graph for cycle detection\n const graph = Graph.from<PackageEntry>({ nodes, dependencies });\n const { cycles, duplicates } = graph.sort();\n\n if (cycles && cycles.length) {\n cycles.forEach((c) => {\n console.log(`Skipping cycle: ${c.join(' -> ')}`);\n });\n }\n if (duplicates && duplicates.length) {\n duplicates.forEach((d) => {\n console.log(`Skipping duplicates: ${JSON.stringify(d.values.map((x) => x.path))}`);\n });\n }\n\n // Remove cyclic packages from the graph\n if (cycles && cycles.length) {\n const cyclicPackages: Record<string, boolean> = {};\n for (var ci = 0; ci < cycles.length; ci++) {\n var c = cycles[ci];\n for (var cj = 0; cj < c.length; cj++) {\n cyclicPackages[String(c[cj])] = true;\n }\n }\n for (var cyclicName in cyclicPackages) {\n delete nodes[cyclicName];\n delete dependencies[cyclicName];\n }\n // Remove references to cyclic packages from dependencies\n for (var key in dependencies) {\n var depList = dependencies[key];\n for (var di = depList.length - 1; di >= 0; di--) {\n if (cyclicPackages[depList[di]]) depList.splice(di, 1);\n }\n }\n }\n\n return callback(null, { nodes, dependencies });\n }\n );\n}\n"],"names":["fs","Iterator","path","removeBOM","match","Graph","defaultIgnores","packageLayers","options","callback","depth","Infinity","cwd","process","ignores","ignore","matcher","exclude","iterator","filter","entry","stats","isDirectory","realStats","basename","isFile","root","lstat","entries","forEach","cb","readFile","fullPath","err","contents","pkg","JSON","parse","private","name","undefined","package","push","_err","console","log","concurrency","callbacks","topological","sorted","sort","a","b","dirname","localeCompare","nodes","dependencies","i","length","j","e","deps","optionalDependencies","graph","from","cycles","duplicates","c","join","d","stringify","values","map","x","cyclicPackages","ci","cj","String","cyclicName","key","depList","di","splice"],"mappings":"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"}
import path from 'path';
import Queue from 'queue-cb';
import spawnStreaming from 'spawn-streaming';
import schedule from 'topological-scheduler';
import loadSpawnTerm from './lib/loadSpawnTerm.js';

@@ -84,54 +85,5 @@ import packageLayers from './lib/packageLayers.js';

}
// Topological mode: streaming execution
// Topological mode: use topological-scheduler
const graph = result;
const { entries, dependencies, dependents, roots } = graph;
// Track in-degrees (number of incomplete dependencies)
const inDegree = {};
for(const name in dependencies){
inDegree[name] = dependencies[name].length;
}
const completed = {};
const failed = {};
const skipped = {};
const running = {};
let runningCount = 0;
let completedCount = 0;
const ready = roots.slice();
// Count total entries
let totalEntries = 0;
for(const _name in entries){
totalEntries++;
}
const hasFailedDependency = (name)=>{
if (!options.failDependents) return false;
const deps = dependencies[name] || [];
for(let i = 0; i < deps.length; i++){
if (failed[deps[i]] || skipped[deps[i]]) return true;
}
return false;
};
const onComplete = (name, didFail, wasSkipped = false)=>{
delete running[name];
runningCount--;
completed[name] = true;
completedCount++;
if (didFail) failed[name] = true;
if (wasSkipped) skipped[name] = true;
// Unlock dependents
const deps = dependents[name] || [];
for(let i = 0; i < deps.length; i++){
const dep = deps[i];
inDegree[dep]--;
if (inDegree[dep] === 0) {
ready.push(dep);
}
}
if (completedCount === totalEntries) {
finalize();
} else {
tryStartNext();
}
};
const runPackage = (name)=>{
const entry = entries[name];
schedule(graph, (entry, _id, cb)=>{
const spawnOptions = {

@@ -154,3 +106,3 @@ ...options,

});
onComplete(name, !!err);
cb(err, res);
};

@@ -164,25 +116,10 @@ if (session) session.spawn(command, args, spawnOptions, {

}, next);
};
const tryStartNext = ()=>{
while(ready.length > 0 && runningCount < concurrency){
const name = ready.shift();
if (hasFailedDependency(name)) {
// Skip this package and mark as skipped
skipped[name] = true;
onComplete(name, false, true);
continue;
}
running[name] = true;
runningCount++;
runPackage(name);
}
};
// Handle empty graph
if (totalEntries === 0) {
finalize();
return;
}
tryStartNext();
}, {
concurrency,
failDependents: options.failDependents
}, (err)=>{
finalize(err);
});
});
});
}

@@ -1,1 +0,1 @@

{"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/worker.ts"],"sourcesContent":["import type { SpawnResult } from 'cross-spawn-cb';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport spawnStreaming from 'spawn-streaming';\nimport loadSpawnTerm from './lib/loadSpawnTerm.ts';\nimport packageLayers, { type PackageEntry, type PackageGraph } from './lib/packageLayers.ts';\n\nimport type { EachCallback, EachError, EachOptions, EachResult } from './types.ts';\n\nexport default function worker(command: string, args: string[], options: EachOptions, callback: EachCallback): undefined {\n // Load spawn-term lazily\n loadSpawnTerm((loadErr, mod) => {\n if (loadErr) return callback(loadErr);\n const createSession = mod.createSession;\n\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n const concurrency = typeof options.concurrency === 'undefined' ? 1 : options.concurrency;\n\n packageLayers(options, (err, result) => {\n if (err) return callback(err);\n\n // Create session once for all processes (only when interactive is explicitly enabled, e.g. by CLI)\n const interactive = !!options.interactive;\n const quotedArgs = args.map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg));\n const session = createSession && !options.streaming && interactive ? createSession({ header: `${process.cwd()}> ${command} ${quotedArgs.join(' ')}`, showStatusBar: true, interactive }) : null;\n\n // Show command header when not using terminal session (unless silent)\n if (!session && !options.silent) {\n console.log(`$ ${command} ${quotedArgs.join(' ')}`);\n }\n\n const results: EachResult[] = [];\n\n const finalize = (err?: Error): void => {\n if (err) (err as EachError).results = results;\n if (session) {\n session.waitAndClose(() => {\n err ? callback(err) : callback(null, results);\n });\n } else {\n err ? callback(err) : callback(null, results);\n }\n };\n\n // Non-topological mode: layers is PackageEntry[][]\n if (Array.isArray(result)) {\n const layers = result as PackageEntry[][];\n const processLayers = (layers: PackageEntry[][], done: (err?: Error) => void): void => {\n if (layers.length === 0) {\n done();\n return;\n }\n const layerEntries = layers.shift();\n\n const queue = new Queue(concurrency);\n layerEntries.forEach((entry) => {\n queue.defer((cb: () => void) => {\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): undefined => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n cb();\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n });\n });\n\n queue.await((err: Error) => (err ? done(err) : processLayers(layers, done)));\n };\n\n processLayers(layers, finalize);\n return;\n }\n\n // Topological mode: streaming execution\n const graph = result as PackageGraph;\n const { entries, dependencies, dependents, roots } = graph;\n\n // Track in-degrees (number of incomplete dependencies)\n const inDegree: Record<string, number> = {};\n for (const name in dependencies) {\n inDegree[name] = dependencies[name].length;\n }\n\n const completed: Record<string, boolean> = {};\n const failed: Record<string, boolean> = {};\n const skipped: Record<string, boolean> = {};\n const running: Record<string, boolean> = {};\n let runningCount = 0;\n let completedCount = 0;\n const ready: string[] = roots.slice();\n\n // Count total entries\n let totalEntries = 0;\n for (const _name in entries) {\n totalEntries++;\n }\n\n const hasFailedDependency = (name: string): boolean => {\n if (!options.failDependents) return false;\n const deps = dependencies[name] || [];\n for (let i = 0; i < deps.length; i++) {\n if (failed[deps[i]] || skipped[deps[i]]) return true;\n }\n return false;\n };\n\n const onComplete = (name: string, didFail: boolean, wasSkipped = false): void => {\n delete running[name];\n runningCount--;\n completed[name] = true;\n completedCount++;\n if (didFail) failed[name] = true;\n if (wasSkipped) skipped[name] = true;\n\n // Unlock dependents\n const deps = dependents[name] || [];\n for (let i = 0; i < deps.length; i++) {\n const dep = deps[i];\n inDegree[dep]--;\n if (inDegree[dep] === 0) {\n ready.push(dep);\n }\n }\n\n if (completedCount === totalEntries) {\n finalize();\n } else {\n tryStartNext();\n }\n };\n\n const runPackage = (name: string): void => {\n const entry = entries[name];\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): undefined => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n onComplete(name, !!err);\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n };\n\n const tryStartNext = (): void => {\n while (ready.length > 0 && runningCount < concurrency) {\n const name = ready.shift();\n if (hasFailedDependency(name)) {\n // Skip this package and mark as skipped\n skipped[name] = true;\n onComplete(name, false, true);\n continue;\n }\n running[name] = true;\n runningCount++;\n runPackage(name);\n }\n };\n\n // Handle empty graph\n if (totalEntries === 0) {\n finalize();\n return;\n }\n\n tryStartNext();\n });\n });\n}\n"],"names":["path","Queue","spawnStreaming","loadSpawnTerm","packageLayers","worker","command","args","options","callback","loadErr","mod","createSession","depth","Infinity","concurrency","err","result","interactive","quotedArgs","map","arg","test","session","streaming","header","process","cwd","join","showStatusBar","silent","console","log","results","finalize","waitAndClose","Array","isArray","layers","processLayers","done","length","layerEntries","shift","queue","forEach","entry","defer","cb","spawnOptions","dirname","fullPath","prefix","next","res","message","indexOf","push","error","spawn","group","expanded","await","graph","entries","dependencies","dependents","roots","inDegree","name","completed","failed","skipped","running","runningCount","completedCount","ready","slice","totalEntries","_name","hasFailedDependency","failDependents","deps","i","onComplete","didFail","wasSkipped","dep","tryStartNext","runPackage"],"mappings":"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"}
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/monorepo/each-package/src/worker.ts"],"sourcesContent":["import type { SpawnResult } from 'cross-spawn-cb';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport spawnStreaming from 'spawn-streaming';\nimport schedule, { type DependencyGraph } from 'topological-scheduler';\nimport loadSpawnTerm from './lib/loadSpawnTerm.ts';\nimport packageLayers, { type PackageEntry } from './lib/packageLayers.ts';\n\nimport type { EachCallback, EachError, EachOptions, EachResult } from './types.ts';\n\nexport default function worker(command: string, args: string[], options: EachOptions, callback: EachCallback): undefined {\n // Load spawn-term lazily\n loadSpawnTerm((loadErr, mod) => {\n if (loadErr) return callback(loadErr);\n const createSession = mod.createSession;\n\n let depth = typeof options.depth === 'undefined' ? Infinity : options.depth;\n if (depth !== Infinity) depth++; // depth is relative to first level of packages\n const concurrency = typeof options.concurrency === 'undefined' ? 1 : options.concurrency;\n\n packageLayers(options, (err, result) => {\n if (err) return callback(err);\n\n // Create session once for all processes (only when interactive is explicitly enabled, e.g. by CLI)\n const interactive = !!options.interactive;\n const quotedArgs = args.map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg));\n const session = createSession && !options.streaming && interactive ? createSession({ header: `${process.cwd()}> ${command} ${quotedArgs.join(' ')}`, showStatusBar: true, interactive }) : null;\n\n // Show command header when not using terminal session (unless silent)\n if (!session && !options.silent) {\n console.log(`$ ${command} ${quotedArgs.join(' ')}`);\n }\n\n const results: EachResult[] = [];\n\n const finalize = (err?: Error): void => {\n if (err) (err as EachError).results = results;\n if (session) {\n session.waitAndClose(() => {\n err ? callback(err) : callback(null, results);\n });\n } else {\n err ? callback(err) : callback(null, results);\n }\n };\n\n // Non-topological mode: layers is PackageEntry[][]\n if (Array.isArray(result)) {\n const layers = result as PackageEntry[][];\n const processLayers = (layers: PackageEntry[][], done: (err?: Error) => void): void => {\n if (layers.length === 0) {\n done();\n return;\n }\n const layerEntries = layers.shift();\n\n const queue = new Queue(concurrency);\n layerEntries.forEach((entry) => {\n queue.defer((cb: () => void) => {\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): undefined => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n cb();\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n });\n });\n\n queue.await((err: Error) => (err ? done(err) : processLayers(layers, done)));\n };\n\n processLayers(layers, finalize);\n return;\n }\n\n // Topological mode: use topological-scheduler\n const graph = result as DependencyGraph<PackageEntry>;\n\n schedule(\n graph,\n (entry, _id, cb) => {\n const spawnOptions = { ...options, cwd: path.dirname(entry.fullPath) };\n const prefix = path.dirname(entry.path);\n\n const next = (err?: Error, res?: SpawnResult): undefined => {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err as unknown as SpawnResult;\n err = null;\n }\n\n results.push({ path: prefix, command, args, error: err, result: res });\n cb(err, res);\n };\n\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: options.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n },\n { concurrency, failDependents: options.failDependents },\n (err) => {\n finalize(err);\n }\n );\n });\n });\n}\n"],"names":["path","Queue","spawnStreaming","schedule","loadSpawnTerm","packageLayers","worker","command","args","options","callback","loadErr","mod","createSession","depth","Infinity","concurrency","err","result","interactive","quotedArgs","map","arg","test","session","streaming","header","process","cwd","join","showStatusBar","silent","console","log","results","finalize","waitAndClose","Array","isArray","layers","processLayers","done","length","layerEntries","shift","queue","forEach","entry","defer","cb","spawnOptions","dirname","fullPath","prefix","next","res","message","indexOf","push","error","spawn","group","expanded","await","graph","_id","failDependents"],"mappings":"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"}
{
"name": "each-package",
"version": "1.4.7",
"version": "1.4.8",
"description": "Run commands in each package folder starting with cwd skipping node_modules folders",

@@ -48,3 +48,2 @@ "keywords": [

"install-module-linked": "^1.3.10",
"lodash.find": "^4.6.0",
"queue-cb": "^1.6.1",

@@ -54,10 +53,11 @@ "remove-bom-buffer": "^3.0.0",

"test-match": "^1.1.1",
"topological-sort-group": "^3.0.3"
"topological-scheduler": "^0.1.0",
"topological-sort-group": "^4.0.0"
},
"devDependencies": {
"@types/mocha": "^10.0.10",
"@types/node": "^24.10.1",
"@types/node": "^24.10.2",
"cr": "^0.1.0",
"is-version": "^1.0.7",
"node-version-use": "^1.9.7",
"node-version-use": "^1.9.9",
"pinkie-promise": "^2.0.1",

@@ -64,0 +64,0 @@ "ts-dev-stack": "^1.21.2",