@proteinjs/reflection-build 1.4.6 → 1.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/src/runWatch.js +3 -30
  3. package/dist/src/runWatch.js.map +1 -1
  4. package/dist/src/watch.d.ts +1 -1
  5. package/dist/src/watch.js +39 -28
  6. package/dist/src/watch.js.map +1 -1
  7. package/package.json +2 -2
  8. package/src/runWatch.ts +3 -8
  9. package/src/watch.ts +44 -35
  10. package/test/examples/source-repository/a/node_modules/.package-lock.json +6 -6
  11. package/test/examples/source-repository/a/node_modules/@proteinjs/util-node/CHANGELOG.md +11 -0
  12. package/test/examples/source-repository/a/node_modules/@proteinjs/util-node/dist/src/PackageUtil.d.ts +44 -1
  13. package/test/examples/source-repository/a/node_modules/@proteinjs/util-node/dist/src/PackageUtil.js +207 -142
  14. package/test/examples/source-repository/a/node_modules/@proteinjs/util-node/dist/src/PackageUtil.js.map +1 -1
  15. package/test/examples/source-repository/a/node_modules/@proteinjs/util-node/package.json +2 -2
  16. package/test/examples/source-repository/a/node_modules/@proteinjs/util-node/src/PackageUtil.ts +176 -102
  17. package/test/examples/source-repository/a/node_modules/@proteinjs/util-node/test/PackageUtil.symlinkDependencies.test.ts +76 -0
  18. package/test/examples/source-repository/a/package-lock.json +8 -8
  19. package/test/examples/source-repository/a/package.json +2 -2
  20. package/test/examples/source-repository/b/node_modules/.package-lock.json +4 -4
  21. package/test/examples/source-repository/b/node_modules/@proteinjs/util-node/CHANGELOG.md +11 -0
  22. package/test/examples/source-repository/b/node_modules/@proteinjs/util-node/dist/src/PackageUtil.d.ts +44 -1
  23. package/test/examples/source-repository/b/node_modules/@proteinjs/util-node/dist/src/PackageUtil.js +207 -142
  24. package/test/examples/source-repository/b/node_modules/@proteinjs/util-node/dist/src/PackageUtil.js.map +1 -1
  25. package/test/examples/source-repository/b/node_modules/@proteinjs/util-node/package.json +2 -2
  26. package/test/examples/source-repository/b/node_modules/@proteinjs/util-node/src/PackageUtil.ts +176 -102
  27. package/test/examples/source-repository/b/node_modules/@proteinjs/util-node/test/PackageUtil.symlinkDependencies.test.ts +76 -0
  28. package/test/examples/source-repository/b/package-lock.json +6 -6
  29. package/test/examples/source-repository/b/package.json +2 -2
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
+ ## [1.4.7](https://github.com/proteinjs/reflection/compare/@proteinjs/reflection-build@1.4.6...@proteinjs/reflection-build@1.4.7) (2026-05-21)
7
+
8
+
9
+ ### Performance Improvements
10
+
11
+ * **reflection-build:** run watch in-process and clean up build logging ([d7f21f7](https://github.com/proteinjs/reflection/commit/d7f21f7c5fa233b423af27f6f90e728c0b193a34))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [1.4.4](https://github.com/proteinjs/reflection/compare/@proteinjs/reflection-build@1.4.3...@proteinjs/reflection-build@1.4.4) (2026-04-08)
7
18
 
8
19
 
@@ -1,34 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || function (mod) {
20
- if (mod && mod.__esModule) return mod;
21
- var result = {};
22
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
- __setModuleDefault(result, mod);
24
- return result;
25
- };
26
3
  Object.defineProperty(exports, "__esModule", { value: true });
27
- var path = __importStar(require("path"));
28
- var util_node_1 = require("@proteinjs/util-node");
29
- // Determine the paths to gulp and the src/watch.ts
30
- var gulpPath = require.resolve('gulp/bin/gulp.js');
31
- var gulpfilePath = path.resolve(__dirname, './watch.js');
32
- // Run the Gulp script
33
- (0, util_node_1.cmd)(gulpPath, ['--gulpfile', gulpfilePath, '--cwd', process.cwd()]);
4
+ var watch_1 = require("./watch");
5
+ // Run the watcher in-process; no separate gulp process is spawned.
6
+ (0, watch_1.watch)();
34
7
  //# sourceMappingURL=runWatch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runWatch.js","sourceRoot":"","sources":["../../src/runWatch.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,yCAA6B;AAC7B,kDAA2C;AAE3C,mDAAmD;AACnD,IAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;AACrD,IAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AAE3D,sBAAsB;AACtB,IAAA,eAAG,EAAC,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"runWatch.js","sourceRoot":"","sources":["../../src/runWatch.ts"],"names":[],"mappings":";;;AAEA,iCAAgC;AAEhC,mEAAmE;AACnE,IAAA,aAAK,GAAE,CAAC"}
@@ -1 +1 @@
1
- export {};
1
+ export declare function watch(): void;
package/dist/src/watch.js CHANGED
@@ -23,43 +23,54 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.watch = void 0;
26
27
  var gulp = __importStar(require("gulp"));
27
28
  var child_process_1 = require("child_process");
28
29
  var path = __importStar(require("path"));
29
30
  function getBuildScript() {
30
31
  return process.env.BUILD_SCRIPT || 'build';
31
32
  }
32
- // Utility function to execute shell commands
33
- function executeCommand(command, cb) {
34
- (0, child_process_1.exec)(command, function (err, stdout, stderr) {
35
- if (err) {
36
- console.error(err.message);
37
- }
38
- if (stderr) {
39
- console.error(stderr);
33
+ function timestamp() {
34
+ return new Date().toTimeString().slice(0, 8);
35
+ }
36
+ function formatElapsed(ms) {
37
+ return ms >= 1000 ? "".concat((ms / 1000).toFixed(2), " s") : "".concat(ms, " ms");
38
+ }
39
+ // Run the package build script, always signaling completion so the watcher stays alive.
40
+ // `--silent` suppresses npm's per-script banner (and propagates to nested `npm run` calls),
41
+ // so each build reduces to a clear start/end line plus any real build output.
42
+ function runBuild(cb) {
43
+ var start = Date.now();
44
+ console.log("[".concat(timestamp(), "] build started"));
45
+ (0, child_process_1.exec)("npm run --silent ".concat(getBuildScript()), function (err, stdout, stderr) {
46
+ var output = [stdout, stderr]
47
+ .map(function (stream) { return stream.trim(); })
48
+ .filter(Boolean)
49
+ .join('\n');
50
+ if (output) {
51
+ console.log(output);
40
52
  }
41
- if (stdout) {
42
- console.log(stdout);
53
+ else if (err) {
54
+ console.log(err.message);
43
55
  }
44
- cb(); // Always call the callback to signal task completion
56
+ // Trailing newline separates consecutive builds into discrete, scannable blocks.
57
+ var result = err ? 'FAILED' : 'succeeded';
58
+ console.log("[".concat(timestamp(), "] build ").concat(result, " in ").concat(formatElapsed(Date.now() - start), "\n"));
59
+ cb();
45
60
  });
46
61
  }
47
- // Task to run the package build script
48
- gulp.task('build', function (cb) {
49
- var scriptName = getBuildScript();
50
- var command = "npm run ".concat(scriptName);
51
- executeCommand(command, cb);
52
- });
53
- gulp.task('watch', function () {
54
- var watcher = gulp.watch([
55
- path.resolve(process.cwd(), 'src/**/*'),
56
- path.resolve(process.cwd(), 'test/**/*'),
57
- path.resolve(process.cwd(), 'index.ts'),
58
- ], gulp.series('build'));
59
- watcher.on('error', function (err) {
60
- console.error('Error:', err.toString());
61
- this.emit('end'); // End the task to allow the watch task to continue
62
+ function watch() {
63
+ // Build once at startup, then watch for changes.
64
+ runBuild(function () {
65
+ var watcher = gulp.watch([
66
+ path.resolve(process.cwd(), 'src/**/*'),
67
+ path.resolve(process.cwd(), 'test/**/*'),
68
+ path.resolve(process.cwd(), 'index.ts'),
69
+ ], function (cb) { return runBuild(cb); });
70
+ watcher.on('error', function (err) {
71
+ console.log("[".concat(timestamp(), "] watch error: ").concat(err.toString()));
72
+ });
62
73
  });
63
- });
64
- gulp.task('default', gulp.series('build', 'watch')); // run build once at the start
74
+ }
75
+ exports.watch = watch;
65
76
  //# sourceMappingURL=watch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/watch.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAA6B;AAC7B,+CAAqC;AACrC,yCAA6B;AAE7B,SAAS,cAAc;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC;AAC7C,CAAC;AAED,6CAA6C;AAC7C,SAAS,cAAc,CAAC,OAAe,EAAE,EAAyB;IAChE,IAAA,oBAAI,EAAC,OAAO,EAAE,UAAC,GAAG,EAAE,MAAM,EAAE,MAAM;QAChC,IAAI,GAAG,EAAE;YACP,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;SAC5B;QACD,IAAI,MAAM,EAAE;YACV,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;SACvB;QACD,IAAI,MAAM,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;SACrB;QAED,EAAE,EAAE,CAAC,CAAC,qDAAqD;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,uCAAuC;AACvC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAC,EAAE;IACpB,IAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IACpC,IAAM,OAAO,GAAG,kBAAW,UAAU,CAAE,CAAC;IACxC,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC9B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;IACjB,IAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CACxB;QACE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC;KACxC,EACD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CACrB,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,UAAgC,GAAQ;QAC1D,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,mDAAmD;IACvE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,8BAA8B"}
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/watch.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAA6B;AAC7B,+CAAqC;AACrC,yCAA6B;AAE7B,SAAS,cAAc;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC;AAC7C,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,IAAI,IAAI,EAAE,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,aAAa,CAAC,EAAU;IAC/B,OAAO,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,UAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAI,CAAC,CAAC,CAAC,UAAG,EAAE,QAAK,CAAC;AACjE,CAAC;AAED,wFAAwF;AACxF,4FAA4F;AAC5F,8EAA8E;AAC9E,SAAS,QAAQ,CAAC,EAAyB;IACzC,IAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,WAAI,SAAS,EAAE,oBAAiB,CAAC,CAAC;IAE9C,IAAA,oBAAI,EAAC,2BAAoB,cAAc,EAAE,CAAE,EAAE,UAAC,GAAG,EAAE,MAAM,EAAE,MAAM;QAC/D,IAAM,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;aAC5B,GAAG,CAAC,UAAC,MAAM,IAAK,OAAA,MAAM,CAAC,IAAI,EAAE,EAAb,CAAa,CAAC;aAC9B,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,IAAI,MAAM,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;SACrB;aAAM,IAAI,GAAG,EAAE;YACd,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;SAC1B;QAED,iFAAiF;QACjF,IAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,WAAI,SAAS,EAAE,qBAAW,MAAM,iBAAO,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,OAAI,CAAC,CAAC;QAC1F,EAAE,EAAE,CAAC;IACP,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,KAAK;IACnB,iDAAiD;IACjD,QAAQ,CAAC;QACP,IAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CACxB;YACE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC;YACxC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC;SACxC,EACD,UAAC,EAAE,IAAK,OAAA,QAAQ,CAAC,EAAE,CAAC,EAAZ,CAAY,CACrB,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,UAAC,GAAQ;YAC3B,OAAO,CAAC,GAAG,CAAC,WAAI,SAAS,EAAE,4BAAkB,GAAG,CAAC,QAAQ,EAAE,CAAE,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAhBD,sBAgBC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proteinjs/reflection-build",
3
- "version": "1.4.6",
3
+ "version": "1.4.8",
4
4
  "description": "Build system for reflection",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -31,7 +31,7 @@
31
31
  "@dagrejs/graphlib": "2.1.4",
32
32
  "@proteinjs/reflection": "^1.1.11",
33
33
  "@proteinjs/util": "^1.6.0",
34
- "@proteinjs/util-node": "^1.8.1",
34
+ "@proteinjs/util-node": "^1.9.0",
35
35
  "globby": "11.0.1",
36
36
  "gulp": "4.0.2",
37
37
  "gulp-shell": "0.8.0",
package/src/runWatch.ts CHANGED
@@ -1,11 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import * as path from 'path';
4
- import { cmd } from '@proteinjs/util-node';
3
+ import { watch } from './watch';
5
4
 
6
- // Determine the paths to gulp and the src/watch.ts
7
- const gulpPath = require.resolve('gulp/bin/gulp.js');
8
- const gulpfilePath = path.resolve(__dirname, './watch.js');
9
-
10
- // Run the Gulp script
11
- cmd(gulpPath, ['--gulpfile', gulpfilePath, '--cwd', process.cwd()]);
5
+ // Run the watcher in-process; no separate gulp process is spawned.
6
+ watch();
package/src/watch.ts CHANGED
@@ -6,44 +6,53 @@ function getBuildScript(): string {
6
6
  return process.env.BUILD_SCRIPT || 'build';
7
7
  }
8
8
 
9
- // Utility function to execute shell commands
10
- function executeCommand(command: string, cb: (error?: any) => void): void {
11
- exec(command, (err, stdout, stderr) => {
12
- if (err) {
13
- console.error(err.message);
14
- }
15
- if (stderr) {
16
- console.error(stderr);
17
- }
18
- if (stdout) {
19
- console.log(stdout);
9
+ function timestamp(): string {
10
+ return new Date().toTimeString().slice(0, 8);
11
+ }
12
+
13
+ function formatElapsed(ms: number): string {
14
+ return ms >= 1000 ? `${(ms / 1000).toFixed(2)} s` : `${ms} ms`;
15
+ }
16
+
17
+ // Run the package build script, always signaling completion so the watcher stays alive.
18
+ // `--silent` suppresses npm's per-script banner (and propagates to nested `npm run` calls),
19
+ // so each build reduces to a clear start/end line plus any real build output.
20
+ function runBuild(cb: (error?: any) => void): void {
21
+ const start = Date.now();
22
+ console.log(`[${timestamp()}] build started`);
23
+
24
+ exec(`npm run --silent ${getBuildScript()}`, (err, stdout, stderr) => {
25
+ const output = [stdout, stderr]
26
+ .map((stream) => stream.trim())
27
+ .filter(Boolean)
28
+ .join('\n');
29
+ if (output) {
30
+ console.log(output);
31
+ } else if (err) {
32
+ console.log(err.message);
20
33
  }
21
34
 
22
- cb(); // Always call the callback to signal task completion
35
+ // Trailing newline separates consecutive builds into discrete, scannable blocks.
36
+ const result = err ? 'FAILED' : 'succeeded';
37
+ console.log(`[${timestamp()}] build ${result} in ${formatElapsed(Date.now() - start)}\n`);
38
+ cb();
23
39
  });
24
40
  }
25
41
 
26
- // Task to run the package build script
27
- gulp.task('build', (cb) => {
28
- const scriptName = getBuildScript();
29
- const command = `npm run ${scriptName}`;
30
- executeCommand(command, cb);
31
- });
32
-
33
- gulp.task('watch', () => {
34
- const watcher = gulp.watch(
35
- [
36
- path.resolve(process.cwd(), 'src/**/*'),
37
- path.resolve(process.cwd(), 'test/**/*'),
38
- path.resolve(process.cwd(), 'index.ts'),
39
- ],
40
- gulp.series('build')
41
- );
42
-
43
- watcher.on('error', function (this: typeof watcher, err: any) {
44
- console.error('Error:', err.toString());
45
- this.emit('end'); // End the task to allow the watch task to continue
46
- });
47
- });
42
+ export function watch(): void {
43
+ // Build once at startup, then watch for changes.
44
+ runBuild(() => {
45
+ const watcher = gulp.watch(
46
+ [
47
+ path.resolve(process.cwd(), 'src/**/*'),
48
+ path.resolve(process.cwd(), 'test/**/*'),
49
+ path.resolve(process.cwd(), 'index.ts'),
50
+ ],
51
+ (cb) => runBuild(cb)
52
+ );
48
53
 
49
- gulp.task('default', gulp.series('build', 'watch')); // run build once at the start
54
+ watcher.on('error', (err: any) => {
55
+ console.log(`[${timestamp()}] watch error: ${err.toString()}`);
56
+ });
57
+ });
58
+ }
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@proteinjs/reflection-build-test-a",
3
- "version": "0.0.20",
3
+ "version": "0.0.21",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "../b": {
8
8
  "name": "@proteinjs/reflection-build-test-b",
9
- "version": "0.0.20",
9
+ "version": "0.0.21",
10
10
  "license": "ISC",
11
11
  "dependencies": {
12
12
  "@dagrejs/graphlib": "2.1.4",
13
13
  "@proteinjs/reflection": "^1.1.11",
14
14
  "@proteinjs/util": "^1.6.0",
15
- "@proteinjs/util-node": "^1.8.1",
15
+ "@proteinjs/util-node": "^1.9.0",
16
16
  "globby": "11.0.1",
17
17
  "gulp": "4.0.2",
18
18
  "gulp-shell": "0.8.0",
@@ -1103,9 +1103,9 @@
1103
1103
  }
1104
1104
  },
1105
1105
  "node_modules/@proteinjs/util-node": {
1106
- "version": "1.8.1",
1107
- "resolved": "https://registry.npmjs.org/@proteinjs/util-node/-/util-node-1.8.1.tgz",
1108
- "integrity": "sha512-F4BEBmroyTuRjQGYkJQhs2JoTg6VUIeEveMZbHzV5mG8jIyF2zbIF+qQCJ0cV2pdQg2PLhi61VlstTwJrEIKdQ==",
1106
+ "version": "1.9.0",
1107
+ "resolved": "https://registry.npmjs.org/@proteinjs/util-node/-/util-node-1.9.0.tgz",
1108
+ "integrity": "sha512-kn9zzmm7tUmlZiiJxGjkekhwsNprUzZM2r5rWZYgDD/BWdGCTA1QCfKEhmjCHLJutR1J+i4NmWcSfuYdyt+hjw==",
1109
1109
  "license": "ISC",
1110
1110
  "dependencies": {
1111
1111
  "@dagrejs/graphlib": "2.1.4",
@@ -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
+ # [1.9.0](https://github.com/proteinjs/util/compare/@proteinjs/util-node@1.8.1...@proteinjs/util-node@1.9.0) (2026-06-24)
7
+
8
+
9
+ ### Features
10
+
11
+ * symlink-workspace links each package's transitive workspace-dep closure ([55a7c25](https://github.com/proteinjs/util/commit/55a7c2541f500bec4e12bb05454acadd6b4c4b66))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [1.8.1](https://github.com/proteinjs/util/compare/@proteinjs/util-node@1.8.0...@proteinjs/util-node@1.8.1) (2026-04-14)
7
18
 
8
19
 
@@ -101,9 +101,52 @@ export declare class PackageUtil {
101
101
  static getWorkspaceMetadata(workspacePath: string): Promise<WorkspaceMetadata>;
102
102
  /**
103
103
  * Symlink the dependencies of `localPackage` to other local packages in the workspace.
104
+ *
105
+ * This links the package's full TRANSITIVE closure of workspace dependencies,
106
+ * not just its directly-declared ones. A package's `package.json` only lists
107
+ * its direct deps, but those deps pull in workspace packages of their own
108
+ * (e.g. `flow-server` declares `@n3xah/space-server`, which itself depends on
109
+ * `@n3xah/space-common`). Node resolves a transitive dep like `space-common`
110
+ * out of the consumer's own `node_modules` first, so if we only symlinked
111
+ * direct deps, npm would satisfy `space-common` with a stale registry copy
112
+ * that lags the live workspace source — causing schema/version drift. By
113
+ * linking the whole closure, every workspace package a package can reach at
114
+ * runtime resolves to the live source tree.
115
+ *
104
116
  * @param localPackage package to symlink the dependencies of
105
117
  * @param localPackageMap `LocalPackageMap` of the workspace
106
- * @param logger optionally provide a logger to capture this method's logging
107
118
  */
108
119
  static symlinkDependencies(localPackage: LocalPackage, localPackageMap: LocalPackageMap): Promise<void>;
120
+ /**
121
+ * Compute the transitive closure of workspace dependencies for `localPackage`.
122
+ *
123
+ * Reuses `getPackageDependencyGraph`, which already crawls `dependencies` and
124
+ * `devDependencies` (transitively, across the whole workspace) and adds an
125
+ * edge `consumer -> dependency` for each. So the workspace deps reachable from
126
+ * a package are exactly the nodes reachable by following `successors` from its
127
+ * node. We do a cycle-safe traversal (a `visited` set), since the dependency
128
+ * graph can contain cycles. The package itself is excluded from the result.
129
+ *
130
+ * Only names present in `localPackageMap` are returned — i.e. packages that
131
+ * actually live in the workspace and can be symlinked (the graph already
132
+ * filters to file:/relative/workspace deps in `addDependencies`, but we filter
133
+ * again here so the result is exactly the set of linkable packages).
134
+ *
135
+ * @returns workspace package names this package transitively depends on
136
+ */
137
+ private static getTransitiveWorkspaceDependencies;
138
+ /**
139
+ * Symlink a single workspace package into `nodeModulesPath`, and create
140
+ * `node_modules/.bin/<name>` shims for any `bin` it declares.
141
+ *
142
+ * This is the per-dependency linking logic used by `symlinkDependencies` for
143
+ * each package in the transitive closure. The caller is responsible for
144
+ * deciding WHICH packages to link; this method just links the one named.
145
+ *
146
+ * @param dependencyPackageName name of the workspace package to link
147
+ * @param nodeModulesPath absolute path to the consumer's `node_modules`
148
+ * @param packageDir absolute path to the consumer package's directory (cwd for `ln`)
149
+ * @param localPackageMap `LocalPackageMap` of the workspace
150
+ */
151
+ private static symlinkPackage;
109
152
  }