@10stars/config 17.0.4 → 17.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@10stars/config",
3
- "version": "17.0.4",
3
+ "version": "17.0.6",
4
4
  "private": false,
5
5
  "bin": {
6
6
  "config": "./src/index.ts"
package/src/index.ts CHANGED
@@ -3,11 +3,11 @@ import { execSync } from "node:child_process"
3
3
  import fs from "node:fs/promises"
4
4
  import path from "node:path"
5
5
 
6
- import { resetColorIndex } from "./colors"
7
- import { checkIsMonorepo, dedupeSingletons, linkPackages, linkSelf } from "./link-packages"
8
- import { dedupeRemote, linkRemote } from "./link-remote"
6
+ import { checkIsMonorepo, dedupeSingletons, linkPackages, linkSelf } from "./linking/link-packages"
7
+ import { dedupeRemote, linkRemote } from "./linking/link-remote"
9
8
  import { setupOverrides } from "./manage-overrides"
10
- import { runConcurrently, type CommandConfig } from "./runner"
9
+ import { resetColorIndex } from "./run/colors"
10
+ import { runConcurrently, type CommandConfig } from "./run/runner"
11
11
  import { setupSideEffects } from "./vanilla-extract/manage-side-effects"
12
12
  import { patchVanillaExtract } from "./vanilla-extract/patch-vanilla-extract"
13
13
  import { setupVSCode } from "./vscode-config"
@@ -5,7 +5,7 @@ import { promisify } from "node:util"
5
5
 
6
6
  import type * as TF from "type-fest"
7
7
 
8
- import { dedupeSingletons } from "./link-packages"
8
+ import { dedupeSingletons, linkSelf } from "./link-packages"
9
9
 
10
10
  interface Config {
11
11
  dedupeSingletons?: boolean | string[]
@@ -57,8 +57,16 @@ const tryGit = (args: string[], cwd?: string): string | null => {
57
57
  }
58
58
  }
59
59
 
60
- const bunInstall = (cwd: string): void =>
61
- void execFileSync(`bun`, [`install`], { cwd, stdio: `inherit` })
60
+ // --ignore-scripts: a sibling is only a dependency here, so skip its postinstall (`config prepare`)
61
+ // — its Vanilla-Extract patch isn't needed (nothing builds it; typecheck doesn't run VE) and the
62
+ // cross-repo `@types/*` dedupe runs once via the consumer's `dedupe` afterwards. We still restore
63
+ // the one thing a sibling's own src needs: its self-symlink, so `<self>/src/…` self-imports resolve
64
+ // at realpath in the flat-peer layout. (Workspace-root siblings, e.g. backend-api, get their
65
+ // subpackage self-links from bun's own workspace linking, so linkSelf no-ops on them.)
66
+ const bunInstall = async (cwd: string): Promise<void> => {
67
+ await execFileAsync(`bun`, [`install`, `--ignore-scripts`], { cwd })
68
+ await linkSelf(cwd)
69
+ }
62
70
 
63
71
  const exists = (p: string): Promise<boolean> =>
64
72
  fs
@@ -136,7 +144,8 @@ const bfsSiblings = async (
136
144
  level.push(sib)
137
145
  }
138
146
  }
139
- await Promise.all(level.map(visit)) // clone this level's siblings in parallel
147
+ // clone this level's siblings in parallel; unbounded fan-out, fine for the handful in practice
148
+ await Promise.all(level.map(visit))
140
149
  order.push(...level)
141
150
  frontier = level
142
151
  }
@@ -267,7 +276,7 @@ const linkRemoteFromManifest = async (cwd: string, manifestPath: string): Promis
267
276
  }
268
277
 
269
278
  // Pinned clones are mutually independent (each at a recorded SHA, no discovery), so materialize
270
- // them all in parallel; leaves-first install order is still enforced below.
279
+ // them all in parallel; the installs below are likewise parallel and order-independent.
271
280
  await Promise.all(
272
281
  manifest.siblings.map(async (sib) => {
273
282
  const abs = path.resolve(cwd, sib.path)
@@ -281,29 +290,32 @@ const linkRemoteFromManifest = async (cwd: string, manifestPath: string): Promis
281
290
  }),
282
291
  )
283
292
 
284
- installLeavesFirst(
293
+ await installSiblings(
285
294
  cwd,
286
295
  manifest.siblings.map((s) => path.resolve(cwd, s.path)),
287
296
  )
288
297
  }
289
298
 
290
299
  /**
291
- * Install siblings leaves-first (reverse of dependents-first discovery order) so a hoisted
292
- * sibling (e.g. `common`) is installed before a repo that links into it.
293
- * Assumes an acyclic, mostly-linear `file:` graph; a diamond could need a real topological sort.
300
+ * Install every cloned sibling, in parallel. `--ignore-scripts` (in bunInstall) removes the
301
+ * postinstall that used to make this order-sensitive, so ordering no longer matters: each install
302
+ * is independent it resolves its own `file:` deps from their on-disk package.json and hoists into
303
+ * its OWN node_modules, writing nobody else's tree. (Bun's global cache is concurrency-safe.)
294
304
  */
295
- const installLeavesFirst = (cwd: string, siblingsInDiscoveryOrder: string[]): void => {
296
- for (const abs of [...siblingsInDiscoveryOrder].reverse()) {
297
- console.info(`linkRemote: bun install in ${path.relative(cwd, abs)}`)
298
- bunInstall(abs)
299
- }
305
+ const installSiblings = async (cwd: string, siblings: string[]): Promise<void> => {
306
+ await Promise.all(
307
+ siblings.map(async (abs) => {
308
+ console.info(`linkRemote: bun install in ${path.relative(cwd, abs)}`)
309
+ await bunInstall(abs)
310
+ }),
311
+ )
300
312
  }
301
313
 
302
314
  /**
303
315
  * CI: materialize the transitive `file:` sibling graph that a standalone checkout lacks.
304
316
  *
305
317
  * Default (branch-first): BFS the graph, shallow single-branch clone each missing sibling at
306
- * its resolved ref, then `bun install` leaves-first. `--emit-manifest` records the exact
318
+ * its resolved ref, then `bun install --ignore-scripts` each in parallel. `--emit-manifest` records the exact
307
319
  * {repo, ref, sha, version} set (a cross-repo lockfile snapshot for revert). `--from` skips
308
320
  * branch-first and pin-clones each sibling at the manifest's recorded SHA.
309
321
  *
@@ -320,7 +332,7 @@ export const linkRemote = async (cwd: string, opts: LinkRemoteOptions = {}): Pro
320
332
  return
321
333
  }
322
334
 
323
- installLeavesFirst(
335
+ await installSiblings(
324
336
  cwd,
325
337
  siblings.map((s) => s.abs),
326
338
  )
@@ -23,18 +23,32 @@ const PATCHED = String.raw`/(?:^|[/\\])css\.(js|cjs|mjs|jsx|ts|tsx)(\?used)?$/`
23
23
  export const patchVanillaExtract = async (cwd: string): Promise<boolean> => {
24
24
  const nodeModules = path.join(cwd, `node_modules`)
25
25
 
26
- // Recursively collect `@vanilla-extract/integration/dist/*.js` WITHOUT following directory
27
- // symlinks. A `file:` self-dep (e.g. frontend-toolkit's `frontend-toolkit: file:.` creates
28
- // node_modules/frontend-toolkit -> .) makes symlink-following recurse forever Bun.Glob does,
29
- // even with `followSymlinks: false`. A linked sibling patches its own VE during its own install,
30
- // and this repo's own copy is hoisted as a real dir, so real-dir-only recursion is sufficient.
31
- const integrationDist = /[/\\]@vanilla-extract[/\\]integration[/\\]dist[/\\][^/\\]+\.js$/
26
+ // Collect every real `@vanilla-extract/integration/dist/*.js`. VE always sits directly under a
27
+ // `node_modules` dir, so we read each node_modules' own integration/dist and recurse ONLY into
28
+ // *nested* node_modules never into package source trees. (A flat hoisted tree is hundreds of
29
+ // packages; recursing each one's dist/esm/cjs/… was the bulk of the old cost.) Symlinks are
30
+ // skipped: a `file:` self-dep links node_modules/<pkg> -> repo root, so following links recurses
31
+ // forever also why Bun.Glob (which follows links even with `followSymlinks: false`) can't be
32
+ // used. A linked sibling patches its own VE during its own install; this repo's copy is hoisted
33
+ // as a real dir, so real-dir-only descent finds every copy that this install must patch.
32
34
  const findFiles = async (dir: string, out: string[] = []): Promise<string[]> => {
35
+ const distDir = path.join(dir, `@vanilla-extract`, `integration`, `dist`)
36
+ for (const entry of await fs.readdir(distDir, { withFileTypes: true }).catch(() => [])) {
37
+ if (entry.isFile() && entry.name.endsWith(`.js`)) out.push(path.join(distDir, entry.name))
38
+ }
39
+
33
40
  for (const entry of await fs.readdir(dir, { withFileTypes: true }).catch(() => [])) {
34
- if (entry.isSymbolicLink()) continue
35
- const full = path.join(dir, entry.name)
36
- if (entry.isDirectory()) await findFiles(full, out)
37
- else if (entry.isFile() && integrationDist.test(full)) out.push(full)
41
+ if (entry.isSymbolicLink() || !entry.isDirectory()) continue
42
+ const pkgDir = path.join(dir, entry.name)
43
+ if (entry.name.startsWith(`@`)) {
44
+ // scoped packages nest a level deeper: node_modules/@scope/<pkg>/node_modules
45
+ for (const scoped of await fs.readdir(pkgDir, { withFileTypes: true }).catch(() => [])) {
46
+ if (scoped.isSymbolicLink() || !scoped.isDirectory()) continue
47
+ await findFiles(path.join(pkgDir, scoped.name, `node_modules`), out)
48
+ }
49
+ } else {
50
+ await findFiles(path.join(pkgDir, `node_modules`), out)
51
+ }
38
52
  }
39
53
  return out
40
54
  }
File without changes
File without changes