@proteinjs/build 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.0.1](https://github.com/proteinjs/build/compare/@proteinjs/build@2.0.0...@proteinjs/build@2.0.1) (2026-05-21)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Performance Improvements
|
|
10
|
+
|
|
11
|
+
* **watch-workspace:** invoke watch scripts directly; clean up stale watchers ([e28d0a5](https://github.com/proteinjs/build/commit/e28d0a57fe258b3d0490dd492603d52cab4527fd))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## [1.9.2](https://github.com/proteinjs/build/compare/@proteinjs/build@1.9.1...@proteinjs/build@1.9.2) (2026-04-17)
|
|
7
18
|
|
|
8
19
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watchWorkspace.d.ts","sourceRoot":"","sources":["../../src/watchWorkspace.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,iBAAiB,EAAwB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"watchWorkspace.d.ts","sourceRoot":"","sources":["../../src/watchWorkspace.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,iBAAiB,EAAwB,MAAM,sBAAsB,CAAC;AAoE5F,eAAO,MAAM,cAAc,uBAA8B,iBAAiB,kBAiGzE,CAAC"}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
2
13
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
14
|
if (k2 === undefined) k2 = k;
|
|
4
15
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -58,16 +69,92 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
58
69
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
59
70
|
}
|
|
60
71
|
};
|
|
72
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
73
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
74
|
+
if (ar || !(i in from)) {
|
|
75
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
76
|
+
ar[i] = from[i];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
80
|
+
};
|
|
61
81
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
62
82
|
exports.watchWorkspace = void 0;
|
|
63
83
|
var path = __importStar(require("path"));
|
|
64
84
|
var util_node_1 = require("@proteinjs/util-node");
|
|
65
85
|
var logger_1 = require("@proteinjs/logger");
|
|
66
86
|
var logColors_1 = require("./logColors");
|
|
67
|
-
|
|
68
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Collect node_modules/.bin directories from `fromDir` up to (and including) `untilDir`.
|
|
89
|
+
* This mirrors the PATH that `npm run` provides, so a watch script's bins resolve when we
|
|
90
|
+
* invoke it directly via `sh -c` instead of paying for a resident `npm run` process per package.
|
|
91
|
+
*/
|
|
92
|
+
var nodeModulesBinPaths = function (fromDir, untilDir) {
|
|
93
|
+
var binPaths = [];
|
|
94
|
+
var current = path.resolve(fromDir);
|
|
95
|
+
var stop = path.resolve(untilDir);
|
|
96
|
+
// eslint-disable-next-line no-constant-condition
|
|
97
|
+
while (true) {
|
|
98
|
+
binPaths.push(path.join(current, 'node_modules', '.bin'));
|
|
99
|
+
if (current === stop) {
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
var parent_1 = path.dirname(current);
|
|
103
|
+
if (parent_1 === current) {
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
current = parent_1;
|
|
107
|
+
}
|
|
108
|
+
return binPaths;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Find watcher processes (`reflection-watch`) belonging to this workspace. Used to clean up
|
|
112
|
+
* watchers orphaned by a previous `watch-workspace` run (e.g. one that was force-killed) —
|
|
113
|
+
* leftover watchers would otherwise make every file change trigger duplicate builds.
|
|
114
|
+
*/
|
|
115
|
+
var findWorkspaceWatchers = function (workspacePath) { return __awaiter(void 0, void 0, void 0, function () {
|
|
116
|
+
var psStdout, result, _a, watcherSignature, workspacePrefix, pids, _i, _b, line, match, pid, command;
|
|
69
117
|
return __generator(this, function (_c) {
|
|
70
118
|
switch (_c.label) {
|
|
119
|
+
case 0:
|
|
120
|
+
_c.trys.push([0, 2, , 3]);
|
|
121
|
+
return [4 /*yield*/, (0, util_node_1.cmd)('ps', ['-eo', 'pid=,command='], {}, { omitLogs: { stdout: { omit: true }, stderr: { omit: true } } })];
|
|
122
|
+
case 1:
|
|
123
|
+
result = _c.sent();
|
|
124
|
+
psStdout = result.stdout;
|
|
125
|
+
return [3 /*break*/, 3];
|
|
126
|
+
case 2:
|
|
127
|
+
_a = _c.sent();
|
|
128
|
+
return [2 /*return*/, []];
|
|
129
|
+
case 3:
|
|
130
|
+
watcherSignature = '/node_modules/.bin/reflection-watch';
|
|
131
|
+
workspacePrefix = workspacePath.endsWith('/') ? workspacePath : "".concat(workspacePath, "/");
|
|
132
|
+
pids = [];
|
|
133
|
+
for (_i = 0, _b = psStdout.split('\n'); _i < _b.length; _i++) {
|
|
134
|
+
line = _b[_i];
|
|
135
|
+
match = line.match(/^\s*(\d+)\s+(.*)$/);
|
|
136
|
+
if (!match) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
pid = Number(match[1]);
|
|
140
|
+
command = match[2];
|
|
141
|
+
// Never match ourselves; only match watchers rooted under this exact workspace.
|
|
142
|
+
if (pid === process.pid) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (command.includes(workspacePrefix) && command.includes(watcherSignature)) {
|
|
146
|
+
pids.push(pid);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return [2 /*return*/, pids];
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}); };
|
|
153
|
+
var watchWorkspace = function (workspaceMetadata) { return __awaiter(void 0, void 0, void 0, function () {
|
|
154
|
+
var cw, logger, workspacePath, _a, packageMap, sortedPackageNames, _b, skippedPackages, filteredPackageNames, staleWatchers, _i, staleWatchers_1, pid, loggingStartDelay, _loop_1, _c, filteredPackageNames_1, packageName;
|
|
155
|
+
var _d;
|
|
156
|
+
return __generator(this, function (_e) {
|
|
157
|
+
switch (_e.label) {
|
|
71
158
|
case 0:
|
|
72
159
|
cw = new util_node_1.LogColorWrapper();
|
|
73
160
|
logger = new logger_1.Logger({ name: cw.color('workspace:', logColors_1.primaryLogColor) + cw.color('watch', logColors_1.secondaryLogColor) });
|
|
@@ -77,12 +164,29 @@ var watchWorkspace = function (workspaceMetadata) { return __awaiter(void 0, voi
|
|
|
77
164
|
return [3 /*break*/, 3];
|
|
78
165
|
case 1: return [4 /*yield*/, util_node_1.PackageUtil.getWorkspaceMetadata(workspacePath)];
|
|
79
166
|
case 2:
|
|
80
|
-
_b =
|
|
81
|
-
|
|
167
|
+
_b = _e.sent();
|
|
168
|
+
_e.label = 3;
|
|
82
169
|
case 3:
|
|
83
170
|
_a = _b, packageMap = _a.packageMap, sortedPackageNames = _a.sortedPackageNames;
|
|
84
171
|
skippedPackages = ['root'];
|
|
85
172
|
filteredPackageNames = sortedPackageNames.filter(function (packageName) { var _a; return !!((_a = packageMap[packageName].packageJson.scripts) === null || _a === void 0 ? void 0 : _a.watch) && !skippedPackages.includes(packageName); });
|
|
173
|
+
return [4 /*yield*/, findWorkspaceWatchers(workspacePath)];
|
|
174
|
+
case 4:
|
|
175
|
+
staleWatchers = _e.sent();
|
|
176
|
+
if (staleWatchers.length > 0) {
|
|
177
|
+
logger.info({
|
|
178
|
+
message: "> Cleaning up ".concat(cw.color("".concat(staleWatchers.length), logColors_1.secondaryLogColor), " stale watcher").concat(staleWatchers.length != 1 ? 's' : '', " from a previous run"),
|
|
179
|
+
});
|
|
180
|
+
for (_i = 0, staleWatchers_1 = staleWatchers; _i < staleWatchers_1.length; _i++) {
|
|
181
|
+
pid = staleWatchers_1[_i];
|
|
182
|
+
try {
|
|
183
|
+
process.kill(pid, 'SIGTERM');
|
|
184
|
+
}
|
|
185
|
+
catch (_f) {
|
|
186
|
+
// Process already exited; nothing to clean up.
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
86
190
|
logger.info({
|
|
87
191
|
message: "> Watching ".concat(cw.color("".concat(filteredPackageNames.length), logColors_1.secondaryLogColor), " package").concat(filteredPackageNames.length != 1 ? 's' : '', " in workspace (").concat(workspacePath, ")"),
|
|
88
192
|
});
|
|
@@ -122,7 +226,15 @@ var watchWorkspace = function (workspaceMetadata) { return __awaiter(void 0, voi
|
|
|
122
226
|
}
|
|
123
227
|
return filteredOutput;
|
|
124
228
|
};
|
|
125
|
-
(
|
|
229
|
+
var watchScript = (_d = localPackage.packageJson.scripts) === null || _d === void 0 ? void 0 : _d.watch;
|
|
230
|
+
if (!watchScript) {
|
|
231
|
+
return "continue";
|
|
232
|
+
}
|
|
233
|
+
// Invoke the watch script directly instead of through `npm run`, which would leave a
|
|
234
|
+
// resident npm process per package. `sh -c` exec-replaces itself with the script's
|
|
235
|
+
// command, so no extra shell lingers either.
|
|
236
|
+
var watchEnv = __assign(__assign({}, process.env), { PATH: __spreadArray(__spreadArray([], nodeModulesBinPaths(packageDir, workspacePath), true), [process.env.PATH], false).filter(Boolean).join(path.delimiter) });
|
|
237
|
+
(0, util_node_1.cmd)('/bin/sh', ['-c', watchScript], { cwd: packageDir, env: watchEnv }, {
|
|
126
238
|
omitLogs: {
|
|
127
239
|
stdout: {
|
|
128
240
|
filter: stdoutFilter,
|
|
@@ -130,8 +242,8 @@ var watchWorkspace = function (workspaceMetadata) { return __awaiter(void 0, voi
|
|
|
130
242
|
},
|
|
131
243
|
});
|
|
132
244
|
};
|
|
133
|
-
for (
|
|
134
|
-
packageName = filteredPackageNames_1[
|
|
245
|
+
for (_c = 0, filteredPackageNames_1 = filteredPackageNames; _c < filteredPackageNames_1.length; _c++) {
|
|
246
|
+
packageName = filteredPackageNames_1[_c];
|
|
135
247
|
_loop_1(packageName);
|
|
136
248
|
}
|
|
137
249
|
return [2 /*return*/];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watchWorkspace.js","sourceRoot":"","sources":["../../src/watchWorkspace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"watchWorkspace.js","sourceRoot":"","sources":["../../src/watchWorkspace.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteinjs/build",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Workspace build tools",
|
|
5
5
|
"main": "./dist/generated/index.js",
|
|
6
6
|
"types": "./dist/generated/index.d.ts",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@octokit/core": "6.1.2",
|
|
39
|
-
"@proteinjs/logger": "^1.0.
|
|
39
|
+
"@proteinjs/logger": "^1.0.19",
|
|
40
40
|
"@proteinjs/util-node": "^1.8.1",
|
|
41
41
|
"semver": "7.6.0"
|
|
42
42
|
},
|
package/src/watchWorkspace.ts
CHANGED
|
@@ -3,6 +3,70 @@ import { PackageUtil, WorkspaceMetadata, cmd, LogColorWrapper } from '@proteinjs
|
|
|
3
3
|
import { Logger } from '@proteinjs/logger';
|
|
4
4
|
import { primaryLogColor, secondaryLogColor } from './logColors';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Collect node_modules/.bin directories from `fromDir` up to (and including) `untilDir`.
|
|
8
|
+
* This mirrors the PATH that `npm run` provides, so a watch script's bins resolve when we
|
|
9
|
+
* invoke it directly via `sh -c` instead of paying for a resident `npm run` process per package.
|
|
10
|
+
*/
|
|
11
|
+
const nodeModulesBinPaths = (fromDir: string, untilDir: string): string[] => {
|
|
12
|
+
const binPaths: string[] = [];
|
|
13
|
+
let current = path.resolve(fromDir);
|
|
14
|
+
const stop = path.resolve(untilDir);
|
|
15
|
+
// eslint-disable-next-line no-constant-condition
|
|
16
|
+
while (true) {
|
|
17
|
+
binPaths.push(path.join(current, 'node_modules', '.bin'));
|
|
18
|
+
if (current === stop) {
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
const parent = path.dirname(current);
|
|
22
|
+
if (parent === current) {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
current = parent;
|
|
26
|
+
}
|
|
27
|
+
return binPaths;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Find watcher processes (`reflection-watch`) belonging to this workspace. Used to clean up
|
|
32
|
+
* watchers orphaned by a previous `watch-workspace` run (e.g. one that was force-killed) —
|
|
33
|
+
* leftover watchers would otherwise make every file change trigger duplicate builds.
|
|
34
|
+
*/
|
|
35
|
+
const findWorkspaceWatchers = async (workspacePath: string): Promise<number[]> => {
|
|
36
|
+
let psStdout: string;
|
|
37
|
+
try {
|
|
38
|
+
const result = await cmd(
|
|
39
|
+
'ps',
|
|
40
|
+
['-eo', 'pid=,command='],
|
|
41
|
+
{},
|
|
42
|
+
{ omitLogs: { stdout: { omit: true }, stderr: { omit: true } } }
|
|
43
|
+
);
|
|
44
|
+
psStdout = result.stdout;
|
|
45
|
+
} catch {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const watcherSignature = '/node_modules/.bin/reflection-watch';
|
|
50
|
+
const workspacePrefix = workspacePath.endsWith('/') ? workspacePath : `${workspacePath}/`;
|
|
51
|
+
const pids: number[] = [];
|
|
52
|
+
for (const line of psStdout.split('\n')) {
|
|
53
|
+
const match = line.match(/^\s*(\d+)\s+(.*)$/);
|
|
54
|
+
if (!match) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const pid = Number(match[1]);
|
|
58
|
+
const command = match[2];
|
|
59
|
+
// Never match ourselves; only match watchers rooted under this exact workspace.
|
|
60
|
+
if (pid === process.pid) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (command.includes(workspacePrefix) && command.includes(watcherSignature)) {
|
|
64
|
+
pids.push(pid);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return pids;
|
|
68
|
+
};
|
|
69
|
+
|
|
6
70
|
export const watchWorkspace = async (workspaceMetadata?: WorkspaceMetadata) => {
|
|
7
71
|
const cw = new LogColorWrapper();
|
|
8
72
|
const logger = new Logger({ name: cw.color('workspace:', primaryLogColor) + cw.color('watch', secondaryLogColor) });
|
|
@@ -15,6 +79,22 @@ export const watchWorkspace = async (workspaceMetadata?: WorkspaceMetadata) => {
|
|
|
15
79
|
(packageName) => !!packageMap[packageName].packageJson.scripts?.watch && !skippedPackages.includes(packageName)
|
|
16
80
|
);
|
|
17
81
|
|
|
82
|
+
// Kill watchers left behind by a previous run before spawning fresh ones, so a package is
|
|
83
|
+
// never watched twice (which would double every build).
|
|
84
|
+
const staleWatchers = await findWorkspaceWatchers(workspacePath);
|
|
85
|
+
if (staleWatchers.length > 0) {
|
|
86
|
+
logger.info({
|
|
87
|
+
message: `> Cleaning up ${cw.color(`${staleWatchers.length}`, secondaryLogColor)} stale watcher${staleWatchers.length != 1 ? 's' : ''} from a previous run`,
|
|
88
|
+
});
|
|
89
|
+
for (const pid of staleWatchers) {
|
|
90
|
+
try {
|
|
91
|
+
process.kill(pid, 'SIGTERM');
|
|
92
|
+
} catch {
|
|
93
|
+
// Process already exited; nothing to clean up.
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
18
98
|
logger.info({
|
|
19
99
|
message: `> Watching ${cw.color(`${filteredPackageNames.length}`, secondaryLogColor)} package${filteredPackageNames.length != 1 ? 's' : ''} in workspace (${workspacePath})`,
|
|
20
100
|
});
|
|
@@ -59,10 +139,22 @@ export const watchWorkspace = async (workspaceMetadata?: WorkspaceMetadata) => {
|
|
|
59
139
|
|
|
60
140
|
return filteredOutput;
|
|
61
141
|
};
|
|
142
|
+
const watchScript = localPackage.packageJson.scripts?.watch;
|
|
143
|
+
if (!watchScript) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Invoke the watch script directly instead of through `npm run`, which would leave a
|
|
148
|
+
// resident npm process per package. `sh -c` exec-replaces itself with the script's
|
|
149
|
+
// command, so no extra shell lingers either.
|
|
150
|
+
const watchEnv = {
|
|
151
|
+
...process.env,
|
|
152
|
+
PATH: [...nodeModulesBinPaths(packageDir, workspacePath), process.env.PATH].filter(Boolean).join(path.delimiter),
|
|
153
|
+
};
|
|
62
154
|
cmd(
|
|
63
|
-
'
|
|
64
|
-
['
|
|
65
|
-
{ cwd: packageDir },
|
|
155
|
+
'/bin/sh',
|
|
156
|
+
['-c', watchScript],
|
|
157
|
+
{ cwd: packageDir, env: watchEnv },
|
|
66
158
|
{
|
|
67
159
|
omitLogs: {
|
|
68
160
|
stdout: {
|