each-package
Advanced tools
| 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":";;;;+BAyBA;;;eAAwBA;;;yDAzBT;iEACsB;iEACpB;2DACA;sEACK;gEACJ;2EACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBlB,IAAMC,iBAAiB;AAER,SAASD,cAAcE,OAAoB,EAAEC,QAAkB;IAC5E,IAAIC,QAAQ,OAAOF,QAAQE,KAAK,KAAK,cAAcC,WAAWH,QAAQE,KAAK;IAC3E,IAAIA,UAAUC,UAAUD,SAAS,+CAA+C;IAEhF,IAAME,MAAMJ,QAAQI,GAAG,IAAIC,QAAQD,GAAG;IAEtC,IAAME,UAAUN,QAAQO,MAAM,GAAGP,QAAQO,MAAM,GAAGR;IAClD,IAAMS,UAAUC,IAAAA,kBAAK,EAAC;QAAEC,SAASJ;IAAQ;IAEzC,IAAMK,WAAW,IAAIC,mBAAQ,CAACR,KAAe;QAC3CS,QAAQ,SAASA,OAAOC,KAAK;gBACMA;YAAjC,IAAIA,MAAMC,KAAK,CAACC,WAAW,QAAMF,mBAAAA,MAAMG,SAAS,cAAfH,uCAAAA,iBAAiBE,WAAW,KAAI,OAAOF,MAAMI,QAAQ,CAAC,EAAE,KAAK,OAAOV,QAAQM,MAAMI,QAAQ;YAC3H,IAAIJ,MAAMC,KAAK,CAACI,MAAM,IAAI;gBACxB,kCAAkC;gBAClC,IAAIL,MAAMI,QAAQ,KAAK,gBAAgB,OAAO;gBAC9C,sDAAsD;gBACtD,IAAI,CAAClB,QAAQoB,IAAI,IAAIN,MAAMO,IAAI,KAAK,gBAAgB,OAAO;gBAC3D,OAAO;YACT;YACA,OAAO;QACT;QACAnB,OAAAA;QACAoB,OAAO;IACT;IACA,IAAMC,UAAU,EAAE;IAClBZ,SAASa,OAAO,CACd,SAACV,OAAqBW;QACpB,IAAI,CAACX,MAAMC,KAAK,CAACI,MAAM,IAAI;YACzBM;YACA;QACF;QACAC,WAAE,CAACC,QAAQ,CAACb,MAAMc,QAAQ,EAAE,QAAQ,SAACC,KAAKC;YACxC,IAAID,KAAK,OAAOJ,GAAGI;YACnB,IAAI;gBACF,IAAME,MAAMC,KAAKC,KAAK,CAACC,IAAAA,wBAAS,EAACJ;gBACjC,IAAIC,IAAII,OAAO,IAAI,CAACnC,QAAQmC,OAAO,EAAE,OAAOV;gBAC5C,IAAIM,IAAIK,IAAI,KAAKC,WAAW,OAAOZ,MAAM,8BAA8B;gBACvEX,MAAMwB,OAAO,GAAGP;gBAChBR,QAAQgB,IAAI,CAACzB;gBACbW;YACF,EAAE,OAAOe,MAAM;gBACbC,QAAQC,GAAG,CAAC,AAAC,4BAAsC,OAAX5B,MAAMO,IAAI;gBAClDI;YACF;QACF;IACF,GACA;QAAEkB,aAAaxC;QAAUyC,WAAW;IAAK,GACzC,SAACf;QACC,IAAIA,KAAK,OAAO5B,SAAS4B;QAEzB,mDAAmD;QACnD,IAAI,CAAC7B,QAAQ6C,WAAW,EAAE;YACxB,IAAMC,SAASvB,QAAQwB,IAAI,CAAC,SAACC,GAAGC;uBAAM5B,aAAI,CAAC6B,OAAO,CAACF,EAAE3B,IAAI,EAAE8B,aAAa,CAAC9B,aAAI,CAAC6B,OAAO,CAACD,EAAE5B,IAAI;;YAC5F,OAAOpB,SAAS,MAAM;gBAAC6C;aAAO;QAChC;QAEA,IAAMM,QAAQ,IAAIC,6BAAK,CAAe;YAAEhC,MAAM;QAAe;QAC7DE,QAAQC,OAAO,CAAC,SAACV;YACfsC,MAAME,GAAG,CAACxC;QACZ;QAEA,qCAAqC;QACrC,IAAMyC,aAA2C,CAAC;QAClD,IAAMC,kBAA4C,CAAC;QACnD,IAAMC,gBAA0C,CAAC;QAEjDlC,QAAQC,OAAO,CAAC,SAACV;YACfyC,UAAU,CAACzC,MAAMwB,OAAO,CAACF,IAAI,CAAC,GAAGtB;YACjC0C,eAAe,CAAC1C,MAAMwB,OAAO,CAACF,IAAI,CAAC,GAAG,EAAE;YACxCqB,aAAa,CAAC3C,MAAMwB,OAAO,CAACF,IAAI,CAAC,GAAG,EAAE;QACxC;QAEA,+DAA+D;QAC/Db,QAAQC,OAAO,CAAC,SAACV;;gBAGb,IAAM4C,QAAQC,IAAAA,mBAAI,EAACpC,SAAS,SAACqC;2BAAMA,EAAEtB,OAAO,CAACF,IAAI,KAAKA;oBAAO,sBAAsB;gBACnF,IAAIsB,OAAO;oBACTN,MAAME,GAAG,CAAClB,MAAMtB,MAAMwB,OAAO,CAACF,IAAI;oBAClC,4CAA4C;oBAC5CoB,eAAe,CAAC1C,MAAMwB,OAAO,CAACF,IAAI,CAAC,CAACG,IAAI,CAACH;oBACzC,kDAAkD;oBAClDqB,aAAa,CAACrB,KAAK,CAACG,IAAI,CAACzB,MAAMwB,OAAO,CAACF,IAAI;gBAC7C;YACF;YAVA,IAAMyB,OAAO,mBAAM/C,MAAMwB,OAAO,CAACwB,YAAY,IAAI,CAAC,GAAQhD,MAAMwB,OAAO,CAACyB,oBAAoB,IAAI,CAAC;YACjG,IAAK,IAAM3B,QAAQyB;QAUrB;QAEA,IAA+BT,cAAAA,MAAML,IAAI,IAAjCiB,SAAuBZ,YAAvBY,QAAQC,aAAeb,YAAfa;QAChB,IAAID,UAAUA,OAAOE,MAAM,EACzBF,OAAOxC,OAAO,CAAC,SAAC2C;YACd1B,QAAQC,GAAG,CAAC,AAAC,mBAAiC,OAAfyB,EAAEC,IAAI,CAAC;QACxC;QACF,IAAIH,cAAcA,WAAWC,MAAM,EACjCD,WAAWzC,OAAO,CAAC,SAAC6C;YAClB5B,QAAQC,GAAG,CAAC,AAAC,wBAAmE,OAA5CV,KAAKsC,SAAS,CAACD,EAAEE,MAAM,CAACC,GAAG,CAAC,SAACZ;uBAAMA,EAAEvC,IAAI;;QAC/E;QAEF,sDAAsD;QACtD,IAAMoD,QAAkB,EAAE;QAC1B,IAAK,IAAMrC,QAAQoB,gBAAiB;YAClC,IAAIA,eAAe,CAACpB,KAAK,CAAC8B,MAAM,KAAK,GAAG;gBACtCO,MAAMlC,IAAI,CAACH;YACb;QACF;QAEA,wCAAwC;QACxC,IAAI4B,UAAUA,OAAOE,MAAM,EAAE;YAC3B,IAAMQ,iBAA0C,CAAC;gBAC5C,kCAAA,2BAAA;;gBAAL,QAAK,YAAWV,2BAAX,SAAA,6BAAA,QAAA,yBAAA,iCAAmB;oBAAnB,IAAMG,IAAN;wBACE,mCAAA,4BAAA;;wBAAL,QAAK,aAAWA,sBAAX,UAAA,8BAAA,SAAA,0BAAA,kCAAc;4BAAd,IAAMQ,IAAN;4BACHD,cAAc,CAACE,OAAOD,GAAG,GAAG;wBAC9B;;wBAFK;wBAAA;;;iCAAA,8BAAA;gCAAA;;;gCAAA;sCAAA;;;;gBAGP;;gBAJK;gBAAA;;;yBAAA,6BAAA;wBAAA;;;wBAAA;8BAAA;;;;YAKL,IAAK,IAAMvC,SAAQsC,eAAgB;gBACjC,OAAOnB,UAAU,CAACnB,MAAK;gBACvB,OAAOoB,eAAe,CAACpB,MAAK;gBAC5B,OAAOqB,aAAa,CAACrB,MAAK;gBAC1B,IAAMyC,UAAUJ,MAAMK,OAAO,CAAC1C;gBAC9B,IAAIyC,WAAW,GAAGJ,MAAMM,MAAM,CAACF,SAAS;YAC1C;YACA,oEAAoE;YACpE,IAAK,IAAMG,OAAOxB,gBAAiB;gBACjC,IAAMK,OAAOL,eAAe,CAACwB,IAAI;gBACjC,IAAK,IAAIC,IAAIpB,KAAKK,MAAM,GAAG,GAAGe,KAAK,GAAGA,IAAK;oBACzC,IAAIP,cAAc,CAACb,IAAI,CAACoB,EAAE,CAAC,EAAEpB,KAAKkB,MAAM,CAACE,GAAG;gBAC9C;YACF;YACA,IAAK,IAAMD,QAAOvB,cAAe;gBAC/B,IAAMI,QAAOJ,aAAa,CAACuB,KAAI;gBAC/B,IAAK,IAAIC,KAAIpB,MAAKK,MAAM,GAAG,GAAGe,MAAK,GAAGA,KAAK;oBACzC,IAAIP,cAAc,CAACb,KAAI,CAACoB,GAAE,CAAC,EAAEpB,MAAKkB,MAAM,CAACE,IAAG;gBAC9C;YACF;QACF;QAEA,OAAOhF,SAAS,MAAM;YACpBsB,SAASgC;YACTO,cAAcN;YACd0B,YAAYzB;YACZgB,OAAAA;QACF;IACF;AAEJ"} | ||
| {"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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"} |
+10
-74
@@ -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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"} |
+10
-73
| 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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"} |
+5
-5
| { | ||
| "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", |
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
13
-7.14%118702
-14.92%1215
-14.86%+ Added
+ Added
+ Added
- Removed
- Removed
- Removed