@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
@@ -3,13 +3,13 @@ import { logger } from '../../_dependencies/@hyperfrontend/logging/index.esm.js'
3
3
  import { join, ensureDir } from '../../_dependencies/@hyperfrontend/project-scope/core/index.esm.js';
4
4
  import { join as join$1, getDirname } from '../../_dependencies/@hyperfrontend/project-scope/core/path/index.esm.js';
5
5
  import 'node:module';
6
- import 'node:path';
6
+ import { dirname, join as join$2 } from 'node:path';
7
7
  import { isArray } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.esm.js';
8
8
  import '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.esm.js';
9
9
  import '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.esm.js';
10
10
  import '../../_dependencies/@hyperfrontend/project-scope/core/fs/index.esm.js';
11
11
  import { spawn } from 'node:child_process';
12
- import { rmSync, existsSync, mkdtempSync, readFileSync } from 'node:fs';
12
+ import { existsSync, rmSync, mkdtempSync, readFileSync } from 'node:fs';
13
13
  import { tmpdir } from 'node:os';
14
14
  import { stringify, parse } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/json/index.esm.js';
15
15
  import { createPromise } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/promise/index.esm.js';
@@ -82,45 +82,91 @@ const toBinBuildDescriptor = (bin, context, format, formats, reportPath) => {
82
82
  };
83
83
  };
84
84
 
85
- const log$1 = logger.channel('builder:bundle:rollup:dispatch');
86
- const REPORT_DIR_PREFIX = 'hf-builder-rollup-';
87
85
  const SWC_NODE_REGISTER = '@swc-node/register';
88
- const swcNodeAvailable = (workspaceRoot) => existsSync(join(workspaceRoot, 'node_modules', '@swc-node', 'register', 'index.js'));
86
+ const probeDir = (dir, offset) => {
87
+ const compiled = join$2(dir, ...offset, 'index.cjs.js');
88
+ if (existsSync(compiled))
89
+ return { path: compiled, execArgv: [] };
90
+ const source = join$2(dir, ...offset, 'index.ts');
91
+ if (existsSync(source))
92
+ return { path: source, execArgv: ['--require', SWC_NODE_REGISTER] };
93
+ return undefined;
94
+ };
89
95
  /**
90
- * Default worker-path resolution: prefers the built-and-published artifact, falls
91
- * back to the workspace dist path, and finally to the in-source TypeScript file
92
- * via `@swc-node/register` (bootstrap case where builder is building itself for
93
- * the first time and the dist worker doesn't exist yet).
96
+ * Directory of the currently-executing builder module, read from `__dirname`.
97
+ * It is present in the shipped CommonJS build, in the `@swc-node/register` source
98
+ * bootstrap, and under the test runner, so callers get their own on-disk location
99
+ * and can find the worker beside them however the builder was packaged.
94
100
  *
95
- * Looks at, in order:
96
- * 1. `<workspaceRoot>/dist/libs/builder/bundle/rollup/worker/index.cjs.js`
97
- * 2. `<workspaceRoot>/node_modules/@hyperfrontend/builder/bundle/rollup/worker/index.cjs.js`
98
- * 3. `<workspaceRoot>/libs/builder/src/bundle/rollup/worker/index.ts` (with `--require \@swc-node/register`)
101
+ * @returns Absolute directory path of the running module.
99
102
  *
100
- * @param workspaceRoot - Absolute workspace root.
101
- * @returns Worker invocation descriptor, or `undefined` if no candidate exists.
102
- *
103
- * @example Locating the worker for an in-workspace consumer
103
+ * @example Anchoring a lookup beside the running builder
104
104
  * ```typescript
105
- * const invocation = resolveDefaultRollupWorkerPath('/abs/repo')
106
- * if (!invocation) throw new Error('builder rollup worker artifact not found')
105
+ * const invocation = ascendForWorker(['bundle', 'rollup', 'worker'], currentModuleDir())
107
106
  * ```
108
107
  */
109
- const resolveDefaultRollupWorkerPath = (workspaceRoot) => {
110
- const distCandidates = [
111
- join(workspaceRoot, 'dist', 'libs', 'builder', 'bundle', 'rollup', 'worker', 'index.cjs.js'),
112
- join(workspaceRoot, 'node_modules', '@hyperfrontend', 'builder', 'bundle', 'rollup', 'worker', 'index.cjs.js'),
113
- ];
114
- for (const path of distCandidates) {
115
- if (existsSync(path))
116
- return { path, execArgv: [] };
108
+ const currentModuleDir = () => {
109
+ /* 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 */
110
+ if (typeof __dirname === 'undefined') {
111
+ throw createError('@hyperfrontend/builder self-location requires the CommonJS build; drive build() from the CommonJS entry point');
117
112
  }
118
- const sourcePath = join(workspaceRoot, 'libs', 'builder', 'src', 'bundle', 'rollup', 'worker', 'index.ts');
119
- if (existsSync(sourcePath) && swcNodeAvailable(workspaceRoot)) {
120
- return { path: sourcePath, execArgv: ['--require', SWC_NODE_REGISTER] };
113
+ return __dirname;
114
+ };
115
+ /**
116
+ * Locate a builder worker entry by ascending from a start directory toward the
117
+ * filesystem root, returning the first ancestor at which the worker exists at the
118
+ * given in-package offset. The compiled `index.cjs.js` is preferred; an `index.ts`
119
+ * sibling (source-mode bootstrap) resolves with the swc loader attached.
120
+ *
121
+ * The worker ships inside the builder's own package, so resolving relative to the
122
+ * running module finds it wherever the package lives — built dist, an installed
123
+ * `node_modules` copy, or melded into a host bundle under `_dependencies/`.
124
+ *
125
+ * @param offset - In-package path segments to the worker directory (e.g. `['bundle', 'rollup', 'worker']`).
126
+ * @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.
127
+ * @returns The resolved worker invocation, or `undefined` if no worker exists at the offset under any ancestor.
128
+ *
129
+ * @example Resolving the rollup worker from the running module
130
+ * ```typescript
131
+ * const invocation = ascendForWorker(['bundle', 'rollup', 'worker'])
132
+ * if (!invocation) throw new Error('builder rollup worker not found beside the builder module')
133
+ * ```
134
+ */
135
+ const ascendForWorker = (offset, startDir = currentModuleDir()) => {
136
+ let dir = startDir;
137
+ let parent = dirname(dir);
138
+ // how: probe each level then step up; the final probe covers the filesystem root, where parent === dir
139
+ while (parent !== dir) {
140
+ const found = probeDir(dir, offset);
141
+ if (found)
142
+ return found;
143
+ dir = parent;
144
+ parent = dirname(dir);
121
145
  }
122
- return undefined;
146
+ return probeDir(dir, offset);
123
147
  };
148
+
149
+ const log$1 = logger.channel('builder:bundle:rollup:dispatch');
150
+ const REPORT_DIR_PREFIX = 'hf-builder-rollup-';
151
+ /**
152
+ * Resolves the rollup worker by self-locating it beside the running builder
153
+ * module: ascends from the module's own directory to the builder package root
154
+ * and returns the worker at `bundle/rollup/worker`. This works whether the
155
+ * builder runs from its built dist, an installed `node_modules` copy, or melded
156
+ * into a host bundle under `_dependencies/`. The compiled `index.cjs.js` is
157
+ * preferred; an `index.ts` sibling resolves with the `@swc-node/register` loader
158
+ * for source-mode bootstrap.
159
+ *
160
+ * @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.
161
+ * @returns Worker invocation descriptor, or `undefined` if no worker is found under any ancestor.
162
+ *
163
+ * @example Locating the worker beside the builder
164
+ * ```typescript
165
+ * const invocation = resolveDefaultRollupWorkerPath()
166
+ * if (!invocation) throw new Error('builder rollup worker artifact not found')
167
+ * ```
168
+ */
169
+ const resolveDefaultRollupWorkerPath = (startDir) => ascendForWorker(['bundle', 'rollup', 'worker'], startDir);
124
170
  const createReportDir = () => mkdtempSync(join(tmpdir(), REPORT_DIR_PREFIX));
125
171
  const reportPathFor = (reportDir, descriptor) => {
126
172
  const safeLabel = descriptor.inputFile.replace(/[^a-zA-Z0-9_-]+/g, '_');
@@ -200,10 +246,10 @@ const dispatchRollupWorker = async (descriptor, options) => {
200
246
  };
201
247
 
202
248
  const log = logger.channel('builder:bin:script');
203
- const resolveWorkerOrThrow = (workspaceRoot) => {
204
- const invocation = resolveDefaultRollupWorkerPath(workspaceRoot);
249
+ const resolveWorkerOrThrow = () => {
250
+ const invocation = resolveDefaultRollupWorkerPath();
205
251
  if (!invocation) {
206
- throw 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.');
252
+ throw 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.');
207
253
  }
208
254
  return invocation;
209
255
  };
@@ -244,7 +290,7 @@ const buildJsBin = async (bin, ctx) => {
244
290
  const formats = normalizeFormats(bin.format);
245
291
  const binDir = join(ctx.outputPath, 'bin');
246
292
  ensureDir(binDir);
247
- const worker = resolveWorkerOrThrow(ctx.workspaceRoot);
293
+ const worker = resolveWorkerOrThrow();
248
294
  const outputs = [];
249
295
  for (const format of formats) {
250
296
  const descriptor = toBinBuildDescriptor(bin, ctx, format, formats, '');
@@ -1 +1 @@
1
- {"version":3,"file":"dts-per-entry.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/builder/src/bundle/declarations/dts-per-entry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,cAAc,CAAA;AAqD5D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,cAAc,GAAU,SAAS,YAAY,EAAE,UAAU,aAAa,KAAG,OAAO,CAAC,IAAI,CAejG,CAAA"}
1
+ {"version":3,"file":"dts-per-entry.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/builder/src/bundle/declarations/dts-per-entry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,cAAc,CAAA;AAqD5D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,cAAc,GAAU,SAAS,YAAY,EAAE,UAAU,aAAa,KAAG,OAAO,CAAC,IAAI,CAiBjG,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"dts-pre-pass.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/builder/src/bundle/declarations/dts-pre-pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,cAAc,CAAA;AA8ErE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa,GAAU,SAAS,YAAY,EAAE,UAAU,aAAa,KAAG,OAAO,CAAC,IAAI,CAiBhG,CAAA"}
1
+ {"version":3,"file":"dts-pre-pass.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/builder/src/bundle/declarations/dts-pre-pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,cAAc,CAAA;AA8ErE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa,GAAU,SAAS,YAAY,EAAE,UAAU,aAAa,KAAG,OAAO,CAAC,IAAI,CAmBhG,CAAA"}
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- const index_cjs_js$6 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
4
- const index_cjs_js$2 = require('../../_dependencies/@hyperfrontend/logging/index.cjs.js');
5
- const index_cjs_js$3 = require('../../_dependencies/@hyperfrontend/project-scope/core/index.cjs.js');
3
+ const index_cjs_js$2 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
4
+ const index_cjs_js$3 = require('../../_dependencies/@hyperfrontend/logging/index.cjs.js');
5
+ const index_cjs_js$4 = require('../../_dependencies/@hyperfrontend/project-scope/core/index.cjs.js');
6
6
  const index_cjs_js$1 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.cjs.js');
7
7
  const index_cjs_js = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.cjs.js');
8
8
  const node_module = require('node:module');
@@ -10,8 +10,8 @@ const node_path = require('node:path');
10
10
  const node_child_process = require('node:child_process');
11
11
  const node_fs = require('node:fs');
12
12
  const node_os = require('node:os');
13
- const index_cjs_js$5 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/json/index.cjs.js');
14
- const index_cjs_js$4 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/promise/index.cjs.js');
13
+ const index_cjs_js$6 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/json/index.cjs.js');
14
+ const index_cjs_js$5 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/promise/index.cjs.js');
15
15
  const index_cjs_js$7 = require('../../_dependencies/@hyperfrontend/project-scope/core/fs/index.cjs.js');
16
16
  const index_cjs_js$8 = require('../../_dependencies/@hyperfrontend/project-scope/core/path/index.cjs.js');
17
17
  const index_cjs_js$9 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/date/index.cjs.js');
@@ -25,13 +25,77 @@ const { collectChunkSpecifiers, hasDynamicSpecifier } = require('../../_shared/b
25
25
  const { entryDirOf } = require('../../_shared/bundle/fs/entry-dir/index.cjs.js');
26
26
  const { isUnderDir } = require('../../_shared/bundle/fs/under-dir/index.cjs.js');
27
27
 
28
- const log$4 = index_cjs_js$2.logger.channel('builder:bundle:dependencies:pre-pass');
28
+ const SWC_NODE_REGISTER = '@swc-node/register';
29
+ const probeDir = (dir, offset) => {
30
+ const compiled = node_path.join(dir, ...offset, 'index.cjs.js');
31
+ if (node_fs.existsSync(compiled))
32
+ return { path: compiled, execArgv: [] };
33
+ const source = node_path.join(dir, ...offset, 'index.ts');
34
+ if (node_fs.existsSync(source))
35
+ return { path: source, execArgv: ['--require', SWC_NODE_REGISTER] };
36
+ return undefined;
37
+ };
38
+ /**
39
+ * Directory of the currently-executing builder module, read from `__dirname`.
40
+ * It is present in the shipped CommonJS build, in the `@swc-node/register` source
41
+ * bootstrap, and under the test runner, so callers get their own on-disk location
42
+ * and can find the worker beside them however the builder was packaged.
43
+ *
44
+ * @returns Absolute directory path of the running module.
45
+ *
46
+ * @example Anchoring a lookup beside the running builder
47
+ * ```typescript
48
+ * const invocation = ascendForWorker(['bundle', 'rollup', 'worker'], currentModuleDir())
49
+ * ```
50
+ */
51
+ const currentModuleDir = () => {
52
+ /* 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 */
53
+ if (typeof __dirname === 'undefined') {
54
+ throw index_cjs_js$2.createError('@hyperfrontend/builder self-location requires the CommonJS build; drive build() from the CommonJS entry point');
55
+ }
56
+ return __dirname;
57
+ };
58
+ /**
59
+ * Locate a builder worker entry by ascending from a start directory toward the
60
+ * filesystem root, returning the first ancestor at which the worker exists at the
61
+ * given in-package offset. The compiled `index.cjs.js` is preferred; an `index.ts`
62
+ * sibling (source-mode bootstrap) resolves with the swc loader attached.
63
+ *
64
+ * The worker ships inside the builder's own package, so resolving relative to the
65
+ * running module finds it wherever the package lives — built dist, an installed
66
+ * `node_modules` copy, or melded into a host bundle under `_dependencies/`.
67
+ *
68
+ * @param offset - In-package path segments to the worker directory (e.g. `['bundle', 'rollup', 'worker']`).
69
+ * @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.
70
+ * @returns The resolved worker invocation, or `undefined` if no worker exists at the offset under any ancestor.
71
+ *
72
+ * @example Resolving the rollup worker from the running module
73
+ * ```typescript
74
+ * const invocation = ascendForWorker(['bundle', 'rollup', 'worker'])
75
+ * if (!invocation) throw new Error('builder rollup worker not found beside the builder module')
76
+ * ```
77
+ */
78
+ const ascendForWorker = (offset, startDir = currentModuleDir()) => {
79
+ let dir = startDir;
80
+ let parent = node_path.dirname(dir);
81
+ // how: probe each level then step up; the final probe covers the filesystem root, where parent === dir
82
+ while (parent !== dir) {
83
+ const found = probeDir(dir, offset);
84
+ if (found)
85
+ return found;
86
+ dir = parent;
87
+ parent = node_path.dirname(dir);
88
+ }
89
+ return probeDir(dir, offset);
90
+ };
91
+
92
+ const log$4 = index_cjs_js$3.logger.channel('builder:bundle:dependencies:pre-pass');
29
93
  const REPORT_DIR_PREFIX = 'hf-builder-prepass-';
30
- const createReportDir = () => node_fs.mkdtempSync(index_cjs_js$3.join(node_os.tmpdir(), REPORT_DIR_PREFIX));
31
- const reportPathFor = (reportDir, job, index) => index_cjs_js$3.join(reportDir, `${index}-${job.dep.replace(/\//g, '__')}-${job.kind}-${job.format}.json`);
32
- const runOne = (job, reportPath, options) => index_cjs_js$4.createPromise((resolve, reject) => {
94
+ const createReportDir = () => node_fs.mkdtempSync(index_cjs_js$4.join(node_os.tmpdir(), REPORT_DIR_PREFIX));
95
+ const reportPathFor = (reportDir, job, index) => index_cjs_js$4.join(reportDir, `${index}-${job.dep.replace(/\//g, '__')}-${job.kind}-${job.format}.json`);
96
+ const runOne = (job, reportPath, options) => index_cjs_js$5.createPromise((resolve, reject) => {
33
97
  const execPath = options.execPath ?? process.execPath;
34
- const argv = [...(options.execArgv ?? []), options.workerPath, index_cjs_js$5.stringify({ ...job, reportPath })];
98
+ const argv = [...(options.execArgv ?? []), options.workerPath, index_cjs_js$6.stringify({ ...job, reportPath })];
35
99
  const child = node_child_process.spawn(execPath, argv, { stdio: ['ignore', 'pipe', 'pipe'] });
36
100
  let capturedStderr = '';
37
101
  child.stdout?.on('data', (chunk) => {
@@ -43,12 +107,12 @@ const runOne = (job, reportPath, options) => index_cjs_js$4.createPromise((resol
43
107
  process.stderr.write(text);
44
108
  });
45
109
  child.on('error', (error) => {
46
- reject(index_cjs_js$6.createError(`pre-pass worker for ${job.dep} (${job.kind}/${job.format}) failed to spawn: ${error.message}`));
110
+ reject(index_cjs_js$2.createError(`pre-pass worker for ${job.dep} (${job.kind}/${job.format}) failed to spawn: ${error.message}`));
47
111
  });
48
112
  child.on('exit', (code) => {
49
113
  if (code !== 0) {
50
114
  const tail = capturedStderr.trim().split('\n').slice(-10).join('\n');
51
- reject(index_cjs_js$6.createError(`pre-pass worker for ${job.dep} (${job.kind}/${job.format}) exited with code ${code}\n${tail}`));
115
+ reject(index_cjs_js$2.createError(`pre-pass worker for ${job.dep} (${job.kind}/${job.format}) exited with code ${code}\n${tail}`));
52
116
  return;
53
117
  }
54
118
  resolve();
@@ -56,48 +120,30 @@ const runOne = (job, reportPath, options) => index_cjs_js$4.createPromise((resol
56
120
  });
57
121
  const readReport = (reportPath, job) => {
58
122
  if (!node_fs.existsSync(reportPath)) {
59
- throw index_cjs_js$6.createError(`pre-pass worker for ${job.dep} (${job.kind}/${job.format}) did not write a report at ${reportPath}`);
123
+ throw index_cjs_js$2.createError(`pre-pass worker for ${job.dep} (${job.kind}/${job.format}) did not write a report at ${reportPath}`);
60
124
  }
61
- const data = index_cjs_js$5.parse(node_fs.readFileSync(reportPath, 'utf8'));
125
+ const data = index_cjs_js$6.parse(node_fs.readFileSync(reportPath, 'utf8'));
62
126
  return { job, outputSize: data.outputSize, endHeapMB: data.endHeapMB, endRssMB: data.endRssMB, durationMs: data.durationMs };
63
127
  };
64
- const SWC_NODE_REGISTER = '@swc-node/register';
65
- const swcNodeAvailable = (workspaceRoot) => node_fs.existsSync(index_cjs_js$3.join(workspaceRoot, 'node_modules', '@swc-node', 'register', 'index.js'));
66
128
  /**
67
- * Default worker-path resolution: prefers the built-and-published artifact, falls
68
- * back to the workspace dist path, and finally to the in-source TypeScript file
69
- * via `@swc-node/register` (bootstrap case where builder is building itself for
70
- * the first time and the dist worker doesn't exist yet).
71
- *
72
- * Looks at, in order:
73
- * 1. `<workspaceRoot>/dist/libs/builder/bundle/dependencies/worker/index.cjs.js`
74
- * 2. `<workspaceRoot>/node_modules/@hyperfrontend/builder/bundle/dependencies/worker/index.cjs.js`
75
- * 3. `<workspaceRoot>/libs/builder/src/bundle/dependencies/worker/index.ts` (with `--require \@swc-node/register`)
76
- *
77
- * @param workspaceRoot - Absolute workspace root.
78
- * @returns Worker invocation descriptor, or `undefined` if no candidate exists.
79
- *
80
- * @example Locating the worker for an in-workspace consumer
129
+ * Resolves the dependency pre-pass worker by self-locating it beside the running
130
+ * builder module: ascends from the module's own directory to the builder package
131
+ * root and returns the worker at `bundle/dependencies/worker`. This works whether
132
+ * the builder runs from its built dist, an installed `node_modules` copy, or
133
+ * melded into a host bundle under `_dependencies/`. The compiled `index.cjs.js`
134
+ * is preferred; an `index.ts` sibling resolves with the `@swc-node/register`
135
+ * loader for source-mode bootstrap.
136
+ *
137
+ * @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.
138
+ * @returns Worker invocation descriptor, or `undefined` if no worker is found under any ancestor.
139
+ *
140
+ * @example Locating the worker beside the builder
81
141
  * ```typescript
82
- * const invocation = resolveDefaultWorkerPath('/abs/repo')
142
+ * const invocation = resolveDefaultWorkerPath()
83
143
  * if (!invocation) throw new Error('builder worker artifact not found')
84
144
  * ```
85
145
  */
86
- const resolveDefaultWorkerPath = (workspaceRoot) => {
87
- const distCandidates = [
88
- index_cjs_js$3.join(workspaceRoot, 'dist', 'libs', 'builder', 'bundle', 'dependencies', 'worker', 'index.cjs.js'),
89
- index_cjs_js$3.join(workspaceRoot, 'node_modules', '@hyperfrontend', 'builder', 'bundle', 'dependencies', 'worker', 'index.cjs.js'),
90
- ];
91
- for (const path of distCandidates) {
92
- if (node_fs.existsSync(path))
93
- return { path, execArgv: [] };
94
- }
95
- const sourcePath = index_cjs_js$3.join(workspaceRoot, 'libs', 'builder', 'src', 'bundle', 'dependencies', 'worker', 'index.ts');
96
- if (node_fs.existsSync(sourcePath) && swcNodeAvailable(workspaceRoot)) {
97
- return { path: sourcePath, execArgv: ['--require', SWC_NODE_REGISTER] };
98
- }
99
- return undefined;
100
- };
146
+ const resolveDefaultWorkerPath = (startDir) => ascendForWorker(['bundle', 'dependencies', 'worker'], startDir);
101
147
  /**
102
148
  * Sequentially runs the supplied pre-pass jobs by forking a fresh Node child
103
149
  * per invocation. Strict sequential execution is mandatory — concurrent
@@ -335,14 +381,14 @@ const filterSiblings = (srcPath, entries) => entries.filter((entry) => entry.src
335
381
  */
336
382
  const dtsPathFor = (outputPath, srcPath) => srcPath ? join(outputPath, srcPath, 'index.d.ts') : join(outputPath, 'index.d.ts');
337
383
 
338
- const log$3 = index_cjs_js$2.logger.channel('builder:bundle:declarations:dts-per-entry');
384
+ const log$3 = index_cjs_js$3.logger.channel('builder:bundle:declarations:dts-per-entry');
339
385
  const buildSiblingDescriptors = (entries, context, currentSrcPath) => {
340
386
  const descriptors = [];
341
387
  for (const entry of entries) {
342
388
  if (entry.srcPath === currentSrcPath)
343
389
  continue;
344
390
  const indexDtsPath = dtsPathFor(context.outputPath, entry.srcPath);
345
- if (!index_cjs_js$3.exists(indexDtsPath))
391
+ if (!index_cjs_js$4.exists(indexDtsPath))
346
392
  continue;
347
393
  descriptors.push({ srcPath: entry.srcPath, indexDtsPath });
348
394
  }
@@ -356,7 +402,7 @@ const buildJobs$1 = (entries, context) => {
356
402
  const depsRoot = depsRootOf(context);
357
403
  for (const entry of entries) {
358
404
  const inputPath = dtsPathFor(context.outputPath, entry.srcPath);
359
- if (!index_cjs_js$3.exists(inputPath))
405
+ if (!index_cjs_js$4.exists(inputPath))
360
406
  continue;
361
407
  const siblingEntries = buildSiblingDescriptors(entries, context, entry.srcPath);
362
408
  jobs.push({
@@ -403,9 +449,9 @@ const buildJobs$1 = (entries, context) => {
403
449
  const runDtsPerEntry = async (context, monitor) => {
404
450
  if (context.bundledDeps.length === 0 && context.workspaceBundledDeps.length === 0)
405
451
  return;
406
- const invocation = resolveDefaultWorkerPath(context.workspaceRoot);
452
+ const invocation = resolveDefaultWorkerPath();
407
453
  if (!invocation) {
408
- 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.');
454
+ throw index_cjs_js$2.createError('bundleAllDeps is enabled but the pre-pass worker could not be located beside the builder module for the per-entry d.ts pass.');
409
455
  }
410
456
  const jobs = buildJobs$1(context.entryPointDiscovery.entryPoints, context);
411
457
  if (jobs.length === 0) {
@@ -498,17 +544,17 @@ const resolveDepEntry = (options) => {
498
544
  const { dep, projectRoot, workspaceRoot} = options;
499
545
  const pkgPath = findPackageJsonViaRequire(dep, ROOTS(projectRoot, workspaceRoot));
500
546
  if (!pkgPath)
501
- throw index_cjs_js$6.createError(`pre-pass: cannot locate package.json for dep "${dep}"`);
547
+ throw index_cjs_js$2.createError(`pre-pass: cannot locate package.json for dep "${dep}"`);
502
548
  const pkg = index_cjs_js$7.readJsonFileIfExists(pkgPath);
503
549
  if (!pkg)
504
- throw index_cjs_js$6.createError(`pre-pass: package.json for dep "${dep}" could not be read at ${pkgPath}`);
550
+ throw index_cjs_js$2.createError(`pre-pass: package.json for dep "${dep}" could not be read at ${pkgPath}`);
505
551
  const relative = ensureDtsEntry(pkg);
506
552
  if (!relative)
507
- throw index_cjs_js$6.createError(`pre-pass: dep "${dep}" has no ${'types/typings'} entry`);
553
+ throw index_cjs_js$2.createError(`pre-pass: dep "${dep}" has no ${'types/typings'} entry`);
508
554
  return absolutize(node_path.dirname(pkgPath), relative);
509
555
  };
510
556
 
511
- const log$2 = index_cjs_js$2.logger.channel('builder:bundle:declarations:dts-pre-pass');
557
+ const log$2 = index_cjs_js$3.logger.channel('builder:bundle:declarations:dts-pre-pass');
512
558
  const workspaceDtsOutputFile = (entry) => entry.subPath ? `${entry.specifier}/index.d.ts` : `${entry.packageName}/index.d.ts`;
513
559
  const filterRouteEntries = (entry, all) => all.filter((other) => (entry.policy === 'sub-path' ? other.specifier !== entry.specifier : other.packageName !== entry.packageName));
514
560
  const buildJobs = (deps, context) => {
@@ -532,7 +578,7 @@ const buildJobs = (deps, context) => {
532
578
  dep,
533
579
  inputPath,
534
580
  format: 'esm',
535
- outputPath: index_cjs_js$3.join(depsRoot, dep, 'index.d.ts'),
581
+ outputPath: index_cjs_js$4.join(depsRoot, dep, 'index.d.ts'),
536
582
  otherDeps: [...otherNpmDeps, ...workspacePrefixDeps],
537
583
  otherWorkspaceSpecifiers: workspaceExactSpecifiers,
538
584
  npmDeps: otherNpmDeps,
@@ -558,7 +604,7 @@ const buildWorkspaceJobs = (context, npmDeps) => {
558
604
  dep: entry.specifier,
559
605
  inputPath: entry.inputPath,
560
606
  format: 'esm',
561
- outputPath: index_cjs_js$3.join(depsRoot, workspaceDtsOutputFile(entry)),
607
+ outputPath: index_cjs_js$4.join(depsRoot, workspaceDtsOutputFile(entry)),
562
608
  otherDeps: [...npmDeps, ...otherWorkspacePackages],
563
609
  otherWorkspaceSpecifiers: otherSubPathSpecifiers,
564
610
  tsConfigPath: entry.tsConfigPath,
@@ -587,9 +633,9 @@ const buildWorkspaceJobs = (context, npmDeps) => {
587
633
  const runDtsPrePass = async (context, monitor) => {
588
634
  if (context.bundledDeps.length === 0 && context.workspaceBundledDeps.length === 0)
589
635
  return;
590
- const invocation = resolveDefaultWorkerPath(context.workspaceRoot);
636
+ const invocation = resolveDefaultWorkerPath();
591
637
  if (!invocation) {
592
- throw index_cjs_js$6.createError('bundleAllDeps is enabled but the pre-pass worker artifact was not found for the d.ts pre-pass.');
638
+ throw index_cjs_js$2.createError('bundleAllDeps is enabled but the pre-pass worker could not be located beside the builder module for the d.ts pre-pass.');
593
639
  }
594
640
  const npmJobs = buildJobs(context.bundledDeps, context);
595
641
  const workspaceJobs = buildWorkspaceJobs(context, context.bundledDeps);
@@ -604,7 +650,7 @@ const runDtsPrePass = async (context, monitor) => {
604
650
  monitor?.check('bundle:declarations:dts-prepass:end');
605
651
  };
606
652
 
607
- const log$1 = index_cjs_js$2.logger.channel('builder:bundle:declarations');
653
+ const log$1 = index_cjs_js$3.logger.channel('builder:bundle:declarations');
608
654
  const HEARTBEAT_INTERVAL_MS = 5000;
609
655
  const BYTES_PER_MB = 1024 * 1024;
610
656
  const formatMB = (bytes) => (bytes / BYTES_PER_MB).toFixed(1);
@@ -613,7 +659,7 @@ const startHeartbeat = (label, startedAt) => index_cjs_js$a.setInterval(() => {
613
659
  const elapsedSec = ((index_cjs_js$9.dateNow() - startedAt) / 1000).toFixed(1);
614
660
  log$1.info(`${label} still running: elapsed=${elapsedSec}s parent heap=${formatMB(usage.heapUsed)}MB rss=${formatMB(usage.rss)}MB`);
615
661
  }, HEARTBEAT_INTERVAL_MS);
616
- const runTsc = (tscPath, args, cwd) => index_cjs_js$4.createPromise((resolve, reject) => {
662
+ const runTsc = (tscPath, args, cwd) => index_cjs_js$5.createPromise((resolve, reject) => {
617
663
  const startedAt = index_cjs_js$9.dateNow();
618
664
  const child = node_child_process.spawn(tscPath, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] });
619
665
  log$1.info(`tsc spawned: pid=${child.pid ?? 'unknown'}`);
@@ -641,7 +687,7 @@ const runTsc = (tscPath, args, cwd) => index_cjs_js$4.createPromise((resolve, re
641
687
  const durationMs = index_cjs_js$9.dateNow() - startedAt;
642
688
  if (code !== 0) {
643
689
  log$1.error(`tsc failed with exit code ${code} after ${durationMs}ms`);
644
- reject(index_cjs_js$6.createError(`tsc failed with exit code ${code}`));
690
+ reject(index_cjs_js$2.createError(`tsc failed with exit code ${code}`));
645
691
  return;
646
692
  }
647
693
  log$1.info(`tsc exited 0 in ${durationMs}ms`);
@@ -691,7 +737,7 @@ const generateDeclarations = async (context) => {
691
737
  return result;
692
738
  };
693
739
 
694
- const log = index_cjs_js$2.logger.channel('builder:bundle:declarations:prune-orphans');
740
+ const log = index_cjs_js$3.logger.channel('builder:bundle:declarations:prune-orphans');
695
741
  const ORPHAN_DTS_RE = /\.d\.ts$|\.d\.ts\.map$/;
696
742
  const INDEX_DTS_NAME = 'index.d.ts';
697
743
  /**
@@ -712,13 +758,13 @@ const INDEX_DTS_NAME = 'index.d.ts';
712
758
  * @returns Absolute `.d.ts` path of the referenced sibling, or `null`.
713
759
  */
714
760
  const toDtsTarget = (dir, spec, depsRoot) => {
715
- const abs = index_cjs_js$3.join(dir, spec);
761
+ const abs = index_cjs_js$4.join(dir, spec);
716
762
  // why: a `.js` specifier is the bundled-dep routing shape; map it onto its declaration sibling.
717
- const candidates = spec.endsWith('.js') ? [`${abs.slice(0, -3)}.d.ts`] : [`${abs}.d.ts`, index_cjs_js$3.join(abs, INDEX_DTS_NAME)];
763
+ const candidates = spec.endsWith('.js') ? [`${abs.slice(0, -3)}.d.ts`] : [`${abs}.d.ts`, index_cjs_js$4.join(abs, INDEX_DTS_NAME)];
718
764
  for (const candidate of candidates) {
719
765
  if (isUnderDir(candidate, depsRoot))
720
766
  return null;
721
- if (index_cjs_js$3.exists(candidate))
767
+ if (index_cjs_js$4.exists(candidate))
722
768
  return candidate;
723
769
  }
724
770
  return null;
@@ -746,7 +792,7 @@ const computeReachableDeclarations = (roots, depsRoot) => {
746
792
  const reachable = index_cjs_js.createSet([]);
747
793
  const queue = [];
748
794
  for (const root of roots) {
749
- if (index_cjs_js$3.exists(root) && !reachable.has(root)) {
795
+ if (index_cjs_js$4.exists(root) && !reachable.has(root)) {
750
796
  reachable.add(root);
751
797
  queue.push(root);
752
798
  }
@@ -756,12 +802,12 @@ const computeReachableDeclarations = (roots, depsRoot) => {
756
802
  const file = queue[head];
757
803
  head += 1;
758
804
  // why: every queued path was `exists`-checked before enqueue (roots and `toDtsTarget` targets), so a direct read is safe.
759
- const source = index_cjs_js$3.readFileContent(file);
805
+ const source = index_cjs_js$4.readFileContent(file);
760
806
  if (hasDynamicSpecifier(source)) {
761
807
  log.warn(`dynamic import/require in ${file}; keeping all orphan declarations for safety`);
762
808
  return null;
763
809
  }
764
- const dir = index_cjs_js$3.getDirname(file);
810
+ const dir = index_cjs_js$4.getDirname(file);
765
811
  for (const spec of collectChunkSpecifiers(source)) {
766
812
  const target = toDtsTarget(dir, spec, depsRoot);
767
813
  if (target !== null && !reachable.has(target)) {
@@ -783,10 +829,10 @@ const computeReachableDeclarations = (roots, depsRoot) => {
783
829
  */
784
830
  const collectDeclarationFiles = (root, depsRoot) => {
785
831
  const files = [];
786
- if (!index_cjs_js$3.exists(root))
832
+ if (!index_cjs_js$4.exists(root))
787
833
  return files;
788
834
  const visit = (dir) => {
789
- for (const entry of index_cjs_js$3.readDirectory(dir)) {
835
+ for (const entry of index_cjs_js$4.readDirectory(dir)) {
790
836
  if (entry.isDirectory) {
791
837
  if (isUnderDir(entry.path, depsRoot))
792
838
  continue;
@@ -837,7 +883,7 @@ const pruneOrphanDeclarations = (context) => {
837
883
  const dir = entryDirOf(entry, context);
838
884
  if (isUnderDir(dir, depsRoot))
839
885
  continue;
840
- roots.push(index_cjs_js$3.join(dir, INDEX_DTS_NAME));
886
+ roots.push(index_cjs_js$4.join(dir, INDEX_DTS_NAME));
841
887
  }
842
888
  const reachable = computeReachableDeclarations(roots, depsRoot);
843
889
  if (reachable === null)