@hyperfrontend/builder 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/_dependencies/@hyperfrontend/project-scope/core/fs/index.cjs.js +10 -3
  3. package/_dependencies/@hyperfrontend/project-scope/core/fs/index.esm.js +10 -3
  4. package/_dependencies/@hyperfrontend/project-scope/core/index.cjs.js +16 -6
  5. package/_dependencies/@hyperfrontend/project-scope/core/index.esm.js +16 -6
  6. package/_dependencies/@hyperfrontend/project-scope/core/path/index.cjs.js +4 -5
  7. package/_dependencies/@hyperfrontend/project-scope/core/path/index.esm.js +5 -4
  8. package/_dependencies/@hyperfrontend/project-scope/project/root/index.cjs.js +5 -1
  9. package/_dependencies/@hyperfrontend/project-scope/project/root/index.esm.js +5 -1
  10. package/bin/hf-build.js +110 -82
  11. package/bin/hf-build.linux-x64 +0 -0
  12. package/bin/index.cjs.js +82 -36
  13. package/bin/index.esm.js +82 -36
  14. package/bin/script/index.cjs.js +91 -45
  15. package/bin/script/index.esm.js +81 -35
  16. package/bundle/declarations/dts-per-entry.d.ts.map +1 -1
  17. package/bundle/declarations/dts-pre-pass.d.ts.map +1 -1
  18. package/bundle/declarations/index.cjs.js +118 -72
  19. package/bundle/declarations/index.esm.js +83 -37
  20. package/bundle/dependencies/index.cjs.js +95 -49
  21. package/bundle/dependencies/index.d.ts +13 -24
  22. package/bundle/dependencies/index.esm.js +79 -33
  23. package/bundle/dependencies/pre-pass.d.ts +13 -24
  24. package/bundle/dependencies/pre-pass.d.ts.map +1 -1
  25. package/bundle/index.cjs.js +203 -175
  26. package/bundle/index.esm.js +107 -79
  27. package/bundle/rollup/dispatch.d.ts +12 -14
  28. package/bundle/rollup/dispatch.d.ts.map +1 -1
  29. package/bundle/rollup/index.cjs.js +75 -29
  30. package/bundle/rollup/index.d.ts +14 -16
  31. package/bundle/rollup/index.esm.js +76 -30
  32. package/bundle/worker-locator.d.ts +47 -0
  33. package/bundle/worker-locator.d.ts.map +1 -0
  34. package/index.cjs.js +112 -84
  35. package/index.esm.js +113 -85
  36. package/package.json +31 -3
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.1.1](https://github.com/AndrewRedican/hyperfrontend/compare/5f116abb8ba6355dfb283fa03b7481e5eb029480...7fb26b6a30c007cd0392f1fc973265c3d25e16dd) - 2026-06-28
6
+
7
+ ### Bug Fixes
8
+
9
+ - self-locate workers beside the running module to make the builder embeddable
10
+
5
11
  ## 0.1.0 - 2026-06-23
6
12
 
7
13
  ### Features
@@ -80,6 +80,10 @@ function createScopedLogger(namespace, options = {}) {
80
80
  }
81
81
  createScopedLogger('project-scope');
82
82
 
83
+ function isSafePath(filePath) {
84
+ return !filePath.includes('\u0000');
85
+ }
86
+
83
87
  const fsLogger = createScopedLogger('project-scope:fs');
84
88
  function createFileSystemError(message, code, context) {
85
89
  const error = index_cjs_js$6.createError(message);
@@ -90,7 +94,7 @@ function createFileSystemError(message, code, context) {
90
94
  return error;
91
95
  }
92
96
  function readFileIfExists(filePath, encoding = 'utf-8') {
93
- if (!node_fs.existsSync(filePath)) {
97
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
94
98
  return null;
95
99
  }
96
100
  try {
@@ -101,6 +105,9 @@ function readFileIfExists(filePath, encoding = 'utf-8') {
101
105
  }
102
106
  }
103
107
  function readJsonFile(filePath, options) {
108
+ if (!isSafePath(filePath)) {
109
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
110
+ }
104
111
  if (!node_fs.existsSync(filePath)) {
105
112
  if (options && 'default' in options) {
106
113
  fsLogger.debug('JSON file not found, using default', { path: filePath });
@@ -127,7 +134,7 @@ function readJsonFile(filePath, options) {
127
134
  }
128
135
  }
129
136
  function readJsonFileIfExists(filePath) {
130
- if (!node_fs.existsSync(filePath)) {
137
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
131
138
  return null;
132
139
  }
133
140
  try {
@@ -139,7 +146,7 @@ function readJsonFileIfExists(filePath) {
139
146
  }
140
147
  }
141
148
  function exists(filePath) {
142
- return node_fs.existsSync(filePath);
149
+ return isSafePath(filePath) && node_fs.existsSync(filePath);
143
150
  }
144
151
 
145
152
  const fsDirLogger = createScopedLogger('project-scope:fs:dir');
@@ -78,6 +78,10 @@ function createScopedLogger(namespace, options = {}) {
78
78
  }
79
79
  createScopedLogger('project-scope');
80
80
 
81
+ function isSafePath(filePath) {
82
+ return !filePath.includes('\u0000');
83
+ }
84
+
81
85
  const fsLogger = createScopedLogger('project-scope:fs');
82
86
  function createFileSystemError(message, code, context) {
83
87
  const error = createError(message);
@@ -88,7 +92,7 @@ function createFileSystemError(message, code, context) {
88
92
  return error;
89
93
  }
90
94
  function readFileIfExists(filePath, encoding = 'utf-8') {
91
- if (!existsSync(filePath)) {
95
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
92
96
  return null;
93
97
  }
94
98
  try {
@@ -99,6 +103,9 @@ function readFileIfExists(filePath, encoding = 'utf-8') {
99
103
  }
100
104
  }
101
105
  function readJsonFile(filePath, options) {
106
+ if (!isSafePath(filePath)) {
107
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
108
+ }
102
109
  if (!existsSync(filePath)) {
103
110
  if (options && 'default' in options) {
104
111
  fsLogger.debug('JSON file not found, using default', { path: filePath });
@@ -125,7 +132,7 @@ function readJsonFile(filePath, options) {
125
132
  }
126
133
  }
127
134
  function readJsonFileIfExists(filePath) {
128
- if (!existsSync(filePath)) {
135
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
129
136
  return null;
130
137
  }
131
138
  try {
@@ -137,7 +144,7 @@ function readJsonFileIfExists(filePath) {
137
144
  }
138
145
  }
139
146
  function exists(filePath) {
140
- return existsSync(filePath);
147
+ return isSafePath(filePath) && existsSync(filePath);
141
148
  }
142
149
 
143
150
  const fsDirLogger = createScopedLogger('project-scope:fs:dir');
@@ -87,6 +87,10 @@ const encodingLogger = createScopedLogger('project-scope:encoding');
87
87
 
88
88
  const convertLogger = createScopedLogger('project-scope:encoding:convert');
89
89
 
90
+ function isSafePath(filePath) {
91
+ return !filePath.includes('\u0000');
92
+ }
93
+
90
94
  const fsLogger = createScopedLogger('project-scope:fs');
91
95
  function createFileSystemError(message, code, context) {
92
96
  const error = index_cjs_js$8.createError(message);
@@ -97,6 +101,9 @@ function createFileSystemError(message, code, context) {
97
101
  return error;
98
102
  }
99
103
  function readFileContent(filePath, encoding = 'utf-8') {
104
+ if (!isSafePath(filePath)) {
105
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
106
+ }
100
107
  if (!node_fs.existsSync(filePath)) {
101
108
  fsLogger.debug('File not found', { path: filePath });
102
109
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
@@ -110,6 +117,9 @@ function readFileContent(filePath, encoding = 'utf-8') {
110
117
  }
111
118
  }
112
119
  function readJsonFile(filePath, options) {
120
+ if (!isSafePath(filePath)) {
121
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
122
+ }
113
123
  if (!node_fs.existsSync(filePath)) {
114
124
  if (options && 'default' in options) {
115
125
  fsLogger.debug('JSON file not found, using default', { path: filePath });
@@ -137,7 +147,7 @@ function readJsonFile(filePath, options) {
137
147
  }
138
148
 
139
149
  function getFileStat(filePath, followSymlinks = true) {
140
- if (!node_fs.existsSync(filePath)) {
150
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
141
151
  return null;
142
152
  }
143
153
  try {
@@ -166,7 +176,7 @@ function isDirectory(dirPath) {
166
176
  return stats?.isDirectory ?? false;
167
177
  }
168
178
  function exists(filePath) {
169
- return node_fs.existsSync(filePath);
179
+ return isSafePath(filePath) && node_fs.existsSync(filePath);
170
180
  }
171
181
 
172
182
  const fsDirLogger = createScopedLogger('project-scope:fs:dir');
@@ -246,16 +256,16 @@ function removeDirectory(dirPath, options) {
246
256
  });
247
257
  }
248
258
 
249
- function join(...paths) {
250
- return node_path.join(...paths);
251
- }
252
-
253
259
  function normalizePath(filePath) {
254
260
  if (!filePath)
255
261
  return '';
256
262
  const normalized = node_path.normalize(filePath);
257
263
  return node_path.sep === '\\' ? normalized.replace(/\\/g, '/') : normalized;
258
264
  }
265
+
266
+ function join(...paths) {
267
+ return node_path.join(...paths);
268
+ }
259
269
  function relativePath(from, to) {
260
270
  return normalizePath(node_path.relative(from, to));
261
271
  }
@@ -87,6 +87,10 @@ const encodingLogger = createScopedLogger('project-scope:encoding');
87
87
 
88
88
  const convertLogger = createScopedLogger('project-scope:encoding:convert');
89
89
 
90
+ function isSafePath(filePath) {
91
+ return !filePath.includes('\u0000');
92
+ }
93
+
90
94
  const fsLogger = createScopedLogger('project-scope:fs');
91
95
  function createFileSystemError(message, code, context) {
92
96
  const error = createError(message);
@@ -97,6 +101,9 @@ function createFileSystemError(message, code, context) {
97
101
  return error;
98
102
  }
99
103
  function readFileContent(filePath, encoding = 'utf-8') {
104
+ if (!isSafePath(filePath)) {
105
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
106
+ }
100
107
  if (!existsSync(filePath)) {
101
108
  fsLogger.debug('File not found', { path: filePath });
102
109
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
@@ -110,6 +117,9 @@ function readFileContent(filePath, encoding = 'utf-8') {
110
117
  }
111
118
  }
112
119
  function readJsonFile(filePath, options) {
120
+ if (!isSafePath(filePath)) {
121
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
122
+ }
113
123
  if (!existsSync(filePath)) {
114
124
  if (options && 'default' in options) {
115
125
  fsLogger.debug('JSON file not found, using default', { path: filePath });
@@ -137,7 +147,7 @@ function readJsonFile(filePath, options) {
137
147
  }
138
148
 
139
149
  function getFileStat(filePath, followSymlinks = true) {
140
- if (!existsSync(filePath)) {
150
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
141
151
  return null;
142
152
  }
143
153
  try {
@@ -166,7 +176,7 @@ function isDirectory(dirPath) {
166
176
  return stats?.isDirectory ?? false;
167
177
  }
168
178
  function exists(filePath) {
169
- return existsSync(filePath);
179
+ return isSafePath(filePath) && existsSync(filePath);
170
180
  }
171
181
 
172
182
  const fsDirLogger = createScopedLogger('project-scope:fs:dir');
@@ -246,16 +256,16 @@ function removeDirectory(dirPath, options) {
246
256
  });
247
257
  }
248
258
 
249
- function join(...paths) {
250
- return join$1(...paths);
251
- }
252
-
253
259
  function normalizePath(filePath) {
254
260
  if (!filePath)
255
261
  return '';
256
262
  const normalized = normalize(filePath);
257
263
  return sep === '\\' ? normalized.replace(/\\/g, '/') : normalized;
258
264
  }
265
+
266
+ function join(...paths) {
267
+ return join$1(...paths);
268
+ }
259
269
  function relativePath(from, to) {
260
270
  return normalizePath(relative(from, to));
261
271
  }
@@ -1,11 +1,6 @@
1
1
  'use strict';
2
-
3
2
  const node_path = require('node:path');
4
3
 
5
- function join(...paths) {
6
- return node_path.join(...paths);
7
- }
8
-
9
4
  function normalizePath(filePath) {
10
5
  if (!filePath)
11
6
  return '';
@@ -17,6 +12,10 @@ function normalizeToForwardSlashes(filePath) {
17
12
  return '';
18
13
  return node_path.normalize(filePath).split(node_path.sep).join('/');
19
14
  }
15
+
16
+ function join(...paths) {
17
+ return node_path.join(...paths);
18
+ }
20
19
  function getDirname(filePath) {
21
20
  return normalizePath(node_path.dirname(filePath));
22
21
  }
@@ -1,8 +1,5 @@
1
- import { join as join$1, normalize, sep, dirname } from 'node:path';
2
1
 
3
- function join(...paths) {
4
- return join$1(...paths);
5
- }
2
+ import { normalize, sep, join as join$1, dirname } from 'node:path';
6
3
 
7
4
  function normalizePath(filePath) {
8
5
  if (!filePath)
@@ -15,6 +12,10 @@ function normalizeToForwardSlashes(filePath) {
15
12
  return '';
16
13
  return normalize(filePath).split(sep).join('/');
17
14
  }
15
+
16
+ function join(...paths) {
17
+ return join$1(...paths);
18
+ }
18
19
  function getDirname(filePath) {
19
20
  return normalizePath(dirname(filePath));
20
21
  }
@@ -80,10 +80,14 @@ function createScopedLogger(namespace, options = {}) {
80
80
  }
81
81
  createScopedLogger('project-scope');
82
82
 
83
+ function isSafePath(filePath) {
84
+ return !filePath.includes('\u0000');
85
+ }
86
+
83
87
  createScopedLogger('project-scope:fs');
84
88
 
85
89
  function exists(filePath) {
86
- return node_fs.existsSync(filePath);
90
+ return isSafePath(filePath) && node_fs.existsSync(filePath);
87
91
  }
88
92
 
89
93
  createScopedLogger('project-scope:fs:dir');
@@ -78,10 +78,14 @@ function createScopedLogger(namespace, options = {}) {
78
78
  }
79
79
  createScopedLogger('project-scope');
80
80
 
81
+ function isSafePath(filePath) {
82
+ return !filePath.includes('\u0000');
83
+ }
84
+
81
85
  createScopedLogger('project-scope:fs');
82
86
 
83
87
  function exists(filePath) {
84
- return existsSync(filePath);
88
+ return isSafePath(filePath) && existsSync(filePath);
85
89
  }
86
90
 
87
91
  createScopedLogger('project-scope:fs:dir');
package/bin/hf-build.js CHANGED
@@ -112,8 +112,8 @@ const removeCodesign = (inputs) => {
112
112
 
113
113
  const log$g = index_cjs_js$3.logger.channel('builder:bin:native:dispatch');
114
114
  const REPORT_DIR_PREFIX$2 = 'hf-builder-inject-';
115
- const SWC_NODE_REGISTER$2 = '@swc-node/register';
116
- const swcNodeAvailable$2 = (workspaceRoot) => node_fs.existsSync(index_cjs_js$4.join(workspaceRoot, 'node_modules', '@swc-node', 'register', 'index.js'));
115
+ const SWC_NODE_REGISTER$1 = '@swc-node/register';
116
+ const swcNodeAvailable = (workspaceRoot) => node_fs.existsSync(index_cjs_js$4.join(workspaceRoot, 'node_modules', '@swc-node', 'register', 'index.js'));
117
117
  /**
118
118
  * Default worker-path resolution: prefers the built-and-published artifact, falls
119
119
  * back to the workspace dist path, and finally to the in-source TypeScript file
@@ -144,8 +144,8 @@ const resolveDefaultInjectWorkerPath = (workspaceRoot) => {
144
144
  return { path, execArgv: [] };
145
145
  }
146
146
  const sourcePath = index_cjs_js$4.join(workspaceRoot, 'libs', 'builder', 'src', 'bin', 'native', 'worker', 'index.ts');
147
- if (node_fs.existsSync(sourcePath) && swcNodeAvailable$2(workspaceRoot)) {
148
- return { path: sourcePath, execArgv: ['--require', SWC_NODE_REGISTER$2] };
147
+ if (node_fs.existsSync(sourcePath) && swcNodeAvailable(workspaceRoot)) {
148
+ return { path: sourcePath, execArgv: ['--require', SWC_NODE_REGISTER$1] };
149
149
  }
150
150
  return undefined;
151
151
  };
@@ -932,45 +932,91 @@ const toUmdBuildDescriptor = (entry, config, context, reportPath) => {
932
932
  };
933
933
  };
934
934
 
935
- const log$e = index_cjs_js$3.logger.channel('builder:bundle:rollup:dispatch');
936
- const REPORT_DIR_PREFIX$1 = 'hf-builder-rollup-';
937
- const SWC_NODE_REGISTER$1 = '@swc-node/register';
938
- const swcNodeAvailable$1 = (workspaceRoot) => node_fs.existsSync(index_cjs_js$4.join(workspaceRoot, 'node_modules', '@swc-node', 'register', 'index.js'));
935
+ const SWC_NODE_REGISTER = '@swc-node/register';
936
+ const probeDir = (dir, offset) => {
937
+ const compiled = node_path.join(dir, ...offset, 'index.cjs.js');
938
+ if (node_fs.existsSync(compiled))
939
+ return { path: compiled, execArgv: [] };
940
+ const source = node_path.join(dir, ...offset, 'index.ts');
941
+ if (node_fs.existsSync(source))
942
+ return { path: source, execArgv: ['--require', SWC_NODE_REGISTER] };
943
+ return undefined;
944
+ };
939
945
  /**
940
- * Default worker-path resolution: prefers the built-and-published artifact, falls
941
- * back to the workspace dist path, and finally to the in-source TypeScript file
942
- * via `@swc-node/register` (bootstrap case where builder is building itself for
943
- * the first time and the dist worker doesn't exist yet).
944
- *
945
- * Looks at, in order:
946
- * 1. `<workspaceRoot>/dist/libs/builder/bundle/rollup/worker/index.cjs.js`
947
- * 2. `<workspaceRoot>/node_modules/@hyperfrontend/builder/bundle/rollup/worker/index.cjs.js`
948
- * 3. `<workspaceRoot>/libs/builder/src/bundle/rollup/worker/index.ts` (with `--require \@swc-node/register`)
946
+ * Directory of the currently-executing builder module, read from `__dirname`.
947
+ * It is present in the shipped CommonJS build, in the `@swc-node/register` source
948
+ * bootstrap, and under the test runner, so callers get their own on-disk location
949
+ * and can find the worker beside them however the builder was packaged.
949
950
  *
950
- * @param workspaceRoot - Absolute workspace root.
951
- * @returns Worker invocation descriptor, or `undefined` if no candidate exists.
951
+ * @returns Absolute directory path of the running module.
952
952
  *
953
- * @example Locating the worker for an in-workspace consumer
953
+ * @example Anchoring a lookup beside the running builder
954
954
  * ```typescript
955
- * const invocation = resolveDefaultRollupWorkerPath('/abs/repo')
956
- * if (!invocation) throw new Error('builder rollup worker artifact not found')
955
+ * const invocation = ascendForWorker(['bundle', 'rollup', 'worker'], currentModuleDir())
957
956
  * ```
958
957
  */
959
- const resolveDefaultRollupWorkerPath = (workspaceRoot) => {
960
- const distCandidates = [
961
- index_cjs_js$4.join(workspaceRoot, 'dist', 'libs', 'builder', 'bundle', 'rollup', 'worker', 'index.cjs.js'),
962
- index_cjs_js$4.join(workspaceRoot, 'node_modules', '@hyperfrontend', 'builder', 'bundle', 'rollup', 'worker', 'index.cjs.js'),
963
- ];
964
- for (const path of distCandidates) {
965
- if (node_fs.existsSync(path))
966
- return { path, execArgv: [] };
958
+ const currentModuleDir = () => {
959
+ /* istanbul ignore if -- @preserve the ESM build has no __dirname; the shipped CommonJS build and the test runner always define it, so this guard is unreachable under test */
960
+ if (typeof __dirname === 'undefined') {
961
+ throw index_cjs_js$6.createError('@hyperfrontend/builder self-location requires the CommonJS build; drive build() from the CommonJS entry point');
967
962
  }
968
- const sourcePath = index_cjs_js$4.join(workspaceRoot, 'libs', 'builder', 'src', 'bundle', 'rollup', 'worker', 'index.ts');
969
- if (node_fs.existsSync(sourcePath) && swcNodeAvailable$1(workspaceRoot)) {
970
- return { path: sourcePath, execArgv: ['--require', SWC_NODE_REGISTER$1] };
963
+ return __dirname;
964
+ };
965
+ /**
966
+ * Locate a builder worker entry by ascending from a start directory toward the
967
+ * filesystem root, returning the first ancestor at which the worker exists at the
968
+ * given in-package offset. The compiled `index.cjs.js` is preferred; an `index.ts`
969
+ * sibling (source-mode bootstrap) resolves with the swc loader attached.
970
+ *
971
+ * The worker ships inside the builder's own package, so resolving relative to the
972
+ * running module finds it wherever the package lives — built dist, an installed
973
+ * `node_modules` copy, or melded into a host bundle under `_dependencies/`.
974
+ *
975
+ * @param offset - In-package path segments to the worker directory (e.g. `['bundle', 'rollup', 'worker']`).
976
+ * @param startDir - Directory to begin the ascent from. Defaults to the running module's directory; pass an explicit value to resolve from another anchor or under test.
977
+ * @returns The resolved worker invocation, or `undefined` if no worker exists at the offset under any ancestor.
978
+ *
979
+ * @example Resolving the rollup worker from the running module
980
+ * ```typescript
981
+ * const invocation = ascendForWorker(['bundle', 'rollup', 'worker'])
982
+ * if (!invocation) throw new Error('builder rollup worker not found beside the builder module')
983
+ * ```
984
+ */
985
+ const ascendForWorker = (offset, startDir = currentModuleDir()) => {
986
+ let dir = startDir;
987
+ let parent = node_path.dirname(dir);
988
+ // how: probe each level then step up; the final probe covers the filesystem root, where parent === dir
989
+ while (parent !== dir) {
990
+ const found = probeDir(dir, offset);
991
+ if (found)
992
+ return found;
993
+ dir = parent;
994
+ parent = node_path.dirname(dir);
971
995
  }
972
- return undefined;
996
+ return probeDir(dir, offset);
973
997
  };
998
+
999
+ const log$e = index_cjs_js$3.logger.channel('builder:bundle:rollup:dispatch');
1000
+ const REPORT_DIR_PREFIX$1 = 'hf-builder-rollup-';
1001
+ /**
1002
+ * Resolves the rollup worker by self-locating it beside the running builder
1003
+ * module: ascends from the module's own directory to the builder package root
1004
+ * and returns the worker at `bundle/rollup/worker`. This works whether the
1005
+ * builder runs from its built dist, an installed `node_modules` copy, or melded
1006
+ * into a host bundle under `_dependencies/`. The compiled `index.cjs.js` is
1007
+ * preferred; an `index.ts` sibling resolves with the `@swc-node/register` loader
1008
+ * for source-mode bootstrap.
1009
+ *
1010
+ * @param startDir - Directory to begin the ascent from. Defaults to the running module's directory; pass an explicit value to resolve from another anchor or under test.
1011
+ * @returns Worker invocation descriptor, or `undefined` if no worker is found under any ancestor.
1012
+ *
1013
+ * @example Locating the worker beside the builder
1014
+ * ```typescript
1015
+ * const invocation = resolveDefaultRollupWorkerPath()
1016
+ * if (!invocation) throw new Error('builder rollup worker artifact not found')
1017
+ * ```
1018
+ */
1019
+ const resolveDefaultRollupWorkerPath = (startDir) => ascendForWorker(['bundle', 'rollup', 'worker'], startDir);
974
1020
  const createReportDir$1 = () => node_fs.mkdtempSync(index_cjs_js$4.join(node_os.tmpdir(), REPORT_DIR_PREFIX$1));
975
1021
  const reportPathFor$1 = (reportDir, descriptor) => {
976
1022
  const safeLabel = descriptor.inputFile.replace(/[^a-zA-Z0-9_-]+/g, '_');
@@ -1050,10 +1096,10 @@ const dispatchRollupWorker = async (descriptor, options) => {
1050
1096
  };
1051
1097
 
1052
1098
  const log$d = index_cjs_js$3.logger.channel('builder:bin:script');
1053
- const resolveWorkerOrThrow = (workspaceRoot) => {
1054
- const invocation = resolveDefaultRollupWorkerPath(workspaceRoot);
1099
+ const resolveWorkerOrThrow = () => {
1100
+ const invocation = resolveDefaultRollupWorkerPath();
1055
1101
  if (!invocation) {
1056
- throw index_cjs_js$6.createError('rollup worker could not be resolved for bin script bundling. Build @hyperfrontend/builder at least once before invoking the bin phase, or ensure @swc-node/register is installed for source-mode bootstrap.');
1102
+ throw index_cjs_js$6.createError('rollup worker could not be located beside the builder module for bin script bundling. The @hyperfrontend/builder package appears incomplete, or @swc-node/register is missing for source-mode bootstrap.');
1057
1103
  }
1058
1104
  return invocation;
1059
1105
  };
@@ -1094,7 +1140,7 @@ const buildJsBin = async (bin, ctx) => {
1094
1140
  const formats = normalizeFormats(bin.format);
1095
1141
  const binDir = index_cjs_js$4.join(ctx.outputPath, 'bin');
1096
1142
  index_cjs_js$4.ensureDir(binDir);
1097
- const worker = resolveWorkerOrThrow(ctx.workspaceRoot);
1143
+ const worker = resolveWorkerOrThrow();
1098
1144
  const outputs = [];
1099
1145
  for (const format of formats) {
1100
1146
  const descriptor = toBinBuildDescriptor(bin, ctx, format, formats, '');
@@ -1634,43 +1680,25 @@ const readReport = (reportPath, job) => {
1634
1680
  const data = index_cjs_js$5.parse(node_fs.readFileSync(reportPath, 'utf8'));
1635
1681
  return { job, outputSize: data.outputSize, endHeapMB: data.endHeapMB, endRssMB: data.endRssMB, durationMs: data.durationMs };
1636
1682
  };
1637
- const SWC_NODE_REGISTER = '@swc-node/register';
1638
- const swcNodeAvailable = (workspaceRoot) => node_fs.existsSync(index_cjs_js$4.join(workspaceRoot, 'node_modules', '@swc-node', 'register', 'index.js'));
1639
1683
  /**
1640
- * Default worker-path resolution: prefers the built-and-published artifact, falls
1641
- * back to the workspace dist path, and finally to the in-source TypeScript file
1642
- * via `@swc-node/register` (bootstrap case where builder is building itself for
1643
- * the first time and the dist worker doesn't exist yet).
1644
- *
1645
- * Looks at, in order:
1646
- * 1. `<workspaceRoot>/dist/libs/builder/bundle/dependencies/worker/index.cjs.js`
1647
- * 2. `<workspaceRoot>/node_modules/@hyperfrontend/builder/bundle/dependencies/worker/index.cjs.js`
1648
- * 3. `<workspaceRoot>/libs/builder/src/bundle/dependencies/worker/index.ts` (with `--require \@swc-node/register`)
1684
+ * Resolves the dependency pre-pass worker by self-locating it beside the running
1685
+ * builder module: ascends from the module's own directory to the builder package
1686
+ * root and returns the worker at `bundle/dependencies/worker`. This works whether
1687
+ * the builder runs from its built dist, an installed `node_modules` copy, or
1688
+ * melded into a host bundle under `_dependencies/`. The compiled `index.cjs.js`
1689
+ * is preferred; an `index.ts` sibling resolves with the `@swc-node/register`
1690
+ * loader for source-mode bootstrap.
1649
1691
  *
1650
- * @param workspaceRoot - Absolute workspace root.
1651
- * @returns Worker invocation descriptor, or `undefined` if no candidate exists.
1692
+ * @param startDir - Directory to begin the ascent from. Defaults to the running module's directory; pass an explicit value to resolve from another anchor or under test.
1693
+ * @returns Worker invocation descriptor, or `undefined` if no worker is found under any ancestor.
1652
1694
  *
1653
- * @example Locating the worker for an in-workspace consumer
1695
+ * @example Locating the worker beside the builder
1654
1696
  * ```typescript
1655
- * const invocation = resolveDefaultWorkerPath('/abs/repo')
1697
+ * const invocation = resolveDefaultWorkerPath()
1656
1698
  * if (!invocation) throw new Error('builder worker artifact not found')
1657
1699
  * ```
1658
1700
  */
1659
- const resolveDefaultWorkerPath = (workspaceRoot) => {
1660
- const distCandidates = [
1661
- index_cjs_js$4.join(workspaceRoot, 'dist', 'libs', 'builder', 'bundle', 'dependencies', 'worker', 'index.cjs.js'),
1662
- index_cjs_js$4.join(workspaceRoot, 'node_modules', '@hyperfrontend', 'builder', 'bundle', 'dependencies', 'worker', 'index.cjs.js'),
1663
- ];
1664
- for (const path of distCandidates) {
1665
- if (node_fs.existsSync(path))
1666
- return { path, execArgv: [] };
1667
- }
1668
- const sourcePath = index_cjs_js$4.join(workspaceRoot, 'libs', 'builder', 'src', 'bundle', 'dependencies', 'worker', 'index.ts');
1669
- if (node_fs.existsSync(sourcePath) && swcNodeAvailable(workspaceRoot)) {
1670
- return { path: sourcePath, execArgv: ['--require', SWC_NODE_REGISTER] };
1671
- }
1672
- return undefined;
1673
- };
1701
+ const resolveDefaultWorkerPath = (startDir) => ascendForWorker(['bundle', 'dependencies', 'worker'], startDir);
1674
1702
  /**
1675
1703
  * Sequentially runs the supplied pre-pass jobs by forking a fresh Node child
1676
1704
  * per invocation. Strict sequential execution is mandatory — concurrent
@@ -1799,9 +1827,9 @@ const buildJobs$1 = (entries, context) => {
1799
1827
  const runDtsPerEntry = async (context, monitor) => {
1800
1828
  if (context.bundledDeps.length === 0 && context.workspaceBundledDeps.length === 0)
1801
1829
  return;
1802
- const invocation = resolveDefaultWorkerPath(context.workspaceRoot);
1830
+ const invocation = resolveDefaultWorkerPath();
1803
1831
  if (!invocation) {
1804
- throw index_cjs_js$6.createError('bundleAllDeps is enabled but the pre-pass worker artifact was not found for the per-entry d.ts pass.');
1832
+ throw index_cjs_js$6.createError('bundleAllDeps is enabled but the pre-pass worker could not be located beside the builder module for the per-entry d.ts pass.');
1805
1833
  }
1806
1834
  const jobs = buildJobs$1(context.entryPointDiscovery.entryPoints, context);
1807
1835
  if (jobs.length === 0) {
@@ -1984,9 +2012,9 @@ const buildWorkspaceJobs = (context, npmDeps) => {
1984
2012
  const runDtsPrePass = async (context, monitor) => {
1985
2013
  if (context.bundledDeps.length === 0 && context.workspaceBundledDeps.length === 0)
1986
2014
  return;
1987
- const invocation = resolveDefaultWorkerPath(context.workspaceRoot);
2015
+ const invocation = resolveDefaultWorkerPath();
1988
2016
  if (!invocation) {
1989
- throw index_cjs_js$6.createError('bundleAllDeps is enabled but the pre-pass worker artifact was not found for the d.ts pre-pass.');
2017
+ throw index_cjs_js$6.createError('bundleAllDeps is enabled but the pre-pass worker could not be located beside the builder module for the d.ts pre-pass.');
1990
2018
  }
1991
2019
  const npmJobs = buildJobs(context.bundledDeps, context);
1992
2020
  const workspaceJobs = buildWorkspaceJobs(context, context.bundledDeps);
@@ -207186,25 +207214,25 @@ const buildWorkspaceJsPrePassJobs = (npmDeps, formats, context) => {
207186
207214
  }
207187
207215
  return jobs;
207188
207216
  };
207189
- const resolvePrePassWorkerOrThrow = (workspaceRoot) => {
207190
- const invocation = resolveDefaultWorkerPath(workspaceRoot);
207217
+ const resolvePrePassWorkerOrThrow = () => {
207218
+ const invocation = resolveDefaultWorkerPath();
207191
207219
  if (!invocation) {
207192
- throw index_cjs_js$6.createError('bundleAllDeps is enabled but the pre-pass worker could not be resolved. Build @hyperfrontend/builder once with bundleAllDeps disabled, or ensure @swc-node/register is installed for source-mode bootstrap.');
207220
+ throw index_cjs_js$6.createError('bundleAllDeps is enabled but the pre-pass worker could not be located beside the builder module. The @hyperfrontend/builder package appears incomplete, or @swc-node/register is missing for source-mode bootstrap.');
207193
207221
  }
207194
207222
  return invocation;
207195
207223
  };
207196
- const resolveRollupWorkerOrThrow = (workspaceRoot) => {
207197
- const invocation = resolveDefaultRollupWorkerPath(workspaceRoot);
207224
+ const resolveRollupWorkerOrThrow = () => {
207225
+ const invocation = resolveDefaultRollupWorkerPath();
207198
207226
  if (!invocation) {
207199
- throw index_cjs_js$6.createError('rollup worker could not be resolved. Build @hyperfrontend/builder at least once before invoking the bundle phase, or ensure @swc-node/register is installed for source-mode bootstrap.');
207227
+ throw index_cjs_js$6.createError('rollup worker could not be located beside the builder module. The @hyperfrontend/builder package appears incomplete, or @swc-node/register is missing for source-mode bootstrap.');
207200
207228
  }
207201
207229
  return invocation;
207202
207230
  };
207203
- const createLazyDispatchResolver = (workspaceRoot) => {
207231
+ const createLazyDispatchResolver = () => {
207204
207232
  let cached = null;
207205
207233
  return () => {
207206
207234
  if (!cached) {
207207
- const invocation = resolveRollupWorkerOrThrow(workspaceRoot);
207235
+ const invocation = resolveRollupWorkerOrThrow();
207208
207236
  cached = { workerPath: invocation.path, execArgv: invocation.execArgv };
207209
207237
  }
207210
207238
  return cached;
@@ -207298,7 +207326,7 @@ const runBundlePhase = async (context, config, monitor) => {
207298
207326
  const outputs = { esm: [], cjs: [], iife: [], umd: [] };
207299
207327
  const requestedPrePassFormats = collectFormatsRequestingPrePass(config);
207300
207328
  if (requestedPrePassFormats.length > 0 && (context.bundledDeps.length > 0 || context.workspaceBundledDeps.length > 0)) {
207301
- const invocation = resolvePrePassWorkerOrThrow(context.workspaceRoot);
207329
+ const invocation = resolvePrePassWorkerOrThrow();
207302
207330
  const npmJobs = buildJsPrePassJobs(context.bundledDeps, requestedPrePassFormats, context);
207303
207331
  const workspaceJobs = buildWorkspaceJsPrePassJobs(context.bundledDeps, requestedPrePassFormats, context);
207304
207332
  const jobs = [...npmJobs, ...workspaceJobs];
@@ -207307,7 +207335,7 @@ const runBundlePhase = async (context, config, monitor) => {
207307
207335
  await runPrePass(jobs, { workerPath: invocation.path, execArgv: invocation.execArgv, monitor });
207308
207336
  monitor?.check('bundle:dependencies:prepass:end');
207309
207337
  }
207310
- const resolveDispatch = createLazyDispatchResolver(context.workspaceRoot);
207338
+ const resolveDispatch = createLazyDispatchResolver();
207311
207339
  await runEsmFormats(config, context, outputs, resolveDispatch, monitor);
207312
207340
  await recover();
207313
207341
  monitor?.check('bundle:esm:end:post-recover');
Binary file