zyrk 0.5.2 → 0.5.3

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/README.md CHANGED
@@ -362,3 +362,8 @@ version-qualified selectors, self rules (`.`), and `$direct` references. Direct
362
362
  dependency overrides must match the declared specification. Workspace member
363
363
  overrides are ignored, matching npm root-only policy. Override rule order is
364
364
  recorded in the manifest fingerprint; frozen installs reject policy drift.
365
+
366
+ `zyrk help` and `zyrk --help` both show help successfully. Installs report
367
+ preparation, resolution, verified source counts, realization, approved builds,
368
+ and project linking on stderr. Interactive terminals show an activity spinner;
369
+ redirected output contains plain phase messages. `--json` disables progress.
package/VERSION CHANGED
@@ -1 +1 @@
1
- v0.5.2
1
+ v0.5.3
@@ -30,6 +30,7 @@ export type RunCliOptions = {
30
30
  };
31
31
  stderr: {
32
32
  write(chunk: string): unknown;
33
+ isTTY?: boolean;
33
34
  };
34
35
  readVersion?: () => string;
35
36
  cwd?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAe,SAAS,EAAe,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,CAAC;AACrB,OAAO,EAAoB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAM3C,OAAO,EAAqC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAEhF,eAAO,MAAM,uBAAuB,IAAI,CAAC;AA2DzC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBhD;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AA6EF;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,GACnD,SAAS,CAgDX;AAmBD,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC1C,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;CACxC,CAAC;AAEF,gFAAgF;AAChF,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAqZpE"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAe,SAAS,EAAe,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,CAAC;AACrB,OAAO,EAAoB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAM3C,OAAO,EAAqC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAEhF,eAAO,MAAM,uBAAuB,IAAI,CAAC;AA2DzC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBhD;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AA6EF;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,GACnD,SAAS,CAgDX;AAmBD,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC1C,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3D,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;CACxC,CAAC;AAEF,gFAAgF;AAChF,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ZpE"}
package/dist/cli/main.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createInstallProgress } from "./progress.js";
1
2
  import { runMaintenanceCommand } from "../commands/maintenance.js";
2
3
  import { runDeployCommand } from "../commands/deploy.js";
3
4
  import { runPatchCommand } from "../commands/patch.js";
@@ -379,6 +380,7 @@ export async function runCli(options) {
379
380
  (parsed.command === "install" || parsed.command === "i")) {
380
381
  if (isGlobalInstallRequest(parsed.command, parsed.commandArgs, options.env))
381
382
  return emit(fail(globalInstallError(parsed.command), parsed));
383
+ const progress = createInstallProgress(options.stderr, parsed.json);
382
384
  try {
383
385
  if (parsed.commandArgs.includes("--help") ||
384
386
  parsed.commandArgs.includes("-h")) {
@@ -413,6 +415,7 @@ export async function runCli(options) {
413
415
  else
414
416
  specs.push(token);
415
417
  }
418
+ progress.update({ phase: "planning" });
416
419
  const cwd = options.cwd ?? process.cwd();
417
420
  const tools = options.tools
418
421
  ? await options.tools()
@@ -429,12 +432,14 @@ export async function runCli(options) {
429
432
  }),
430
433
  };
431
434
  const result = await installProject({
435
+ onProgress: progress.update,
432
436
  ...flags,
433
437
  env: options.env,
434
438
  specs,
435
439
  projectDir: cwd,
436
440
  ...tools,
437
441
  });
442
+ progress.close();
438
443
  if (parsed.json)
439
444
  return emit({
440
445
  exitCode: 0,
@@ -451,8 +456,12 @@ export async function runCli(options) {
451
456
  });
452
457
  }
453
458
  catch (error) {
459
+ progress.close();
454
460
  return emit(fail(toZyrkError(error, "zyrk install failed."), parsed));
455
461
  }
462
+ finally {
463
+ progress.close();
464
+ }
456
465
  }
457
466
  if (!parsed.help &&
458
467
  !parsed.version &&
@@ -1 +1 @@
1
- {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/cli/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,+DAA+D;IAC/D,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,6EAA6E;IAC7E,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CAkD7D;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAOT"}
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/cli/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,+DAA+D;IAC/D,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,6EAA6E;IAC7E,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CAmD7D;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAOT"}
package/dist/cli/parse.js CHANGED
@@ -45,6 +45,8 @@ export function parseArgs(argv) {
45
45
  }
46
46
  if (parsed.command === undefined && !token.startsWith("-")) {
47
47
  parsed.command = token;
48
+ if (token === "help")
49
+ parsed.help = true;
48
50
  commandIndex = index;
49
51
  return;
50
52
  }
@@ -0,0 +1,10 @@
1
+ import type { InstallProgress } from "../install/run.ts";
2
+ /** Presentation only: never writes to stdout or exposes package URLs or paths. */
3
+ export declare function createInstallProgress(stream: {
4
+ write(chunk: string): unknown;
5
+ isTTY?: boolean;
6
+ }, quiet: boolean): {
7
+ update(event: InstallProgress): void;
8
+ close(): void;
9
+ };
10
+ //# sourceMappingURL=progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/cli/progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAWzD,kFAAkF;AAClF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE;IAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EAC1D,KAAK,EAAE,OAAO,GACb;IAAE,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IAAC,KAAK,IAAI,IAAI,CAAA;CAAE,CAuCzD"}
@@ -0,0 +1,52 @@
1
+ const labels = {
2
+ planning: "Preparing installation",
3
+ resolving: "Resolving dependencies",
4
+ fetching: "Verifying package sources",
5
+ realizing: "Preparing shared realizations",
6
+ building: "Preparing approved private builds",
7
+ linking: "Linking project dependencies",
8
+ };
9
+ /** Presentation only: never writes to stdout or exposes package URLs or paths. */
10
+ export function createInstallProgress(stream, quiet) {
11
+ let timer;
12
+ let current = "", last = "", frame = 0, closed = false;
13
+ const write = (text) => {
14
+ try {
15
+ stream.write(text);
16
+ }
17
+ catch {
18
+ /* A display failure cannot alter installation. */
19
+ }
20
+ };
21
+ const render = () => write(`\r\u001b[2K${["|", "/", "-", "\\"][frame++ % 4]} ${current}`);
22
+ return {
23
+ update(event) {
24
+ if (quiet || closed)
25
+ return;
26
+ current =
27
+ labels[event.phase] +
28
+ (event.total === undefined
29
+ ? ""
30
+ : ` (${event.completed ?? 0}/${event.total})`);
31
+ if (stream.isTTY) {
32
+ render();
33
+ if (!timer) {
34
+ timer = setInterval(render, 100);
35
+ timer.unref();
36
+ }
37
+ }
38
+ else if (current !== last)
39
+ write(`zyrk: ${current}\n`);
40
+ last = current;
41
+ },
42
+ close() {
43
+ if (closed)
44
+ return;
45
+ closed = true;
46
+ if (timer)
47
+ clearInterval(timer);
48
+ if (!quiet && stream.isTTY && current)
49
+ write("\r\u001b[2K");
50
+ },
51
+ };
52
+ }
@@ -1,7 +1,13 @@
1
1
  import { type BuildCandidate } from "./private.ts";
2
2
  import { RegistryClient } from "../fetch/registry.ts";
3
3
  import { Store } from "../store/layout.ts";
4
+ export type InstallProgress = {
5
+ phase: "planning" | "resolving" | "fetching" | "realizing" | "building" | "linking";
6
+ completed?: number;
7
+ total?: number;
8
+ };
4
9
  export type InstallOptions = {
10
+ onProgress?: (event: InstallProgress) => void;
5
11
  projectDir: string;
6
12
  store: Store;
7
13
  registry: RegistryClient;
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/install/run.ts"],"names":[],"mappings":"AAIA,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AAYtB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAgC3C,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE;QACT,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE;QACZ,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC;AACF,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EACL,OAAO,GACP,uBAAuB,GACvB,eAAe,GACf,SAAS,GACT,cAAc,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AA4GF,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAyyBxB"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/install/run.ts"],"names":[],"mappings":"AAIA,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AAYtB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAgC3C,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EACD,UAAU,GACV,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,GACV,SAAS,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AACF,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE;QACT,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE;QACZ,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC;AACF,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EACL,OAAO,GACP,uBAAuB,GACvB,eAAe,GACf,SAAS,GACT,cAAc,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AA4GF,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CA8zBxB"}
@@ -93,6 +93,7 @@ function scriptPolicy(manifest) {
93
93
  return object(manifest.zyrk) ? manifest.zyrk.scripts : undefined;
94
94
  }
95
95
  export async function installProject(options) {
96
+ options.onProgress?.({ phase: "planning" });
96
97
  if (await findWorkspaceRoot(options.projectDir)) {
97
98
  const { installWorkspaceProject } = await import("./workspace-install.js");
98
99
  return installWorkspaceProject(options);
@@ -248,6 +249,7 @@ export async function installProject(options) {
248
249
  throw error("ZYRK_OFFLINE_MISSING", "Offline installation requires an existing compatible zyrk lockfile.");
249
250
  const prior = existing?.zyrk ? lockedGraph(existing) : undefined;
250
251
  const fresh = new Set(specs.map((spec) => npa(spec).name));
252
+ options.onProgress?.({ phase: "resolving" });
251
253
  resolved = await resolveRequirements({
252
254
  overrides,
253
255
  provider: {
@@ -460,10 +462,21 @@ export async function installProject(options) {
460
462
  })
461
463
  : undefined;
462
464
  const unique = new Map(activeNodes.map((n) => [n.sourceId, n]));
465
+ let completedSources = 0;
466
+ options.onProgress?.({
467
+ phase: "fetching",
468
+ completed: 0,
469
+ total: unique.size,
470
+ });
463
471
  for (const node of unique.values()) {
464
472
  operation.operation.checkpoint();
465
473
  if (await pathExists(sourceManifestPath(options.store, node.sourceId))) {
466
474
  await readSourceManifest(options.store, node.sourceId);
475
+ options.onProgress?.({
476
+ phase: "fetching",
477
+ completed: ++completedSources,
478
+ total: unique.size,
479
+ });
467
480
  continue;
468
481
  }
469
482
  if (options.offline)
@@ -497,6 +510,11 @@ export async function installProject(options) {
497
510
  if (source.sourceId !== node.sourceId)
498
511
  throw lockMismatch("download identity disagrees with the locked source");
499
512
  await rm(tarball, { force: true });
513
+ options.onProgress?.({
514
+ phase: "fetching",
515
+ completed: ++completedSources,
516
+ total: unique.size,
517
+ });
500
518
  }
501
519
  for (const node of unique.values())
502
520
  assertSupportedSourcePayload(node, await readSourceManifest(options.store, node.sourceId));
@@ -509,6 +527,7 @@ export async function installProject(options) {
509
527
  warnings,
510
528
  };
511
529
  const graph = createGraphDoc(activeNodes.map((n) => ({ ...n, deps: n.edges })));
530
+ options.onProgress?.({ phase: "realizing" });
512
531
  const sharedRealized = await realizeGraph({
513
532
  store: options.store,
514
533
  graph,
@@ -581,6 +600,7 @@ export async function installProject(options) {
581
600
  });
582
601
  privateGraph = true;
583
602
  }
603
+ options.onProgress?.({ phase: "building" });
584
604
  await buildPrivate({
585
605
  project,
586
606
  generationId,
@@ -667,6 +687,7 @@ export async function installProject(options) {
667
687
  roots: selectedRoots.map((r) => r.target),
668
688
  readiness,
669
689
  });
690
+ options.onProgress?.({ phase: "linking" });
670
691
  const published = await installProjection(project, entries, {
671
692
  generationId,
672
693
  lockHeld: true,
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-install.d.ts","sourceRoot":"","sources":["../../src/install/workspace-install.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAyH9D,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CA6pBxB"}
1
+ {"version":3,"file":"workspace-install.d.ts","sourceRoot":"","sources":["../../src/install/workspace-install.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAyH9D,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CA6qBxB"}
@@ -161,6 +161,7 @@ export async function installWorkspaceProject(options) {
161
161
  if (!graph) {
162
162
  if (options.frozen || options.offline)
163
163
  throw lockMismatch("offline/frozen workspace install needs a compatible lock");
164
+ options.onProgress?.({ phase: "resolving" });
164
165
  graph = await resolveWorkspaceGraph(project, {
165
166
  origin: options.registry.origin,
166
167
  originFor: (name) => options.registry.originFor(name),
@@ -261,7 +262,14 @@ export async function installWorkspaceProject(options) {
261
262
  offline: options.offline === true,
262
263
  })
263
264
  : undefined;
264
- for (const node of new Map(nodes.map((n) => [n.sourceId, n])).values()) {
265
+ const uniqueSources = new Map(nodes.map((n) => [n.sourceId, n]));
266
+ let completedSources = 0;
267
+ options.onProgress?.({
268
+ phase: "fetching",
269
+ completed: 0,
270
+ total: uniqueSources.size,
271
+ });
272
+ for (const node of uniqueSources.values()) {
265
273
  operation.operation.checkpoint();
266
274
  if (!(await pathExists(sourceManifestPath(options.store, node.sourceId)))) {
267
275
  if (options.offline)
@@ -298,6 +306,11 @@ export async function installWorkspaceProject(options) {
298
306
  await rm(archive, { force: true });
299
307
  }
300
308
  assertSupportedSourcePayload(node, await readSourceManifest(options.store, node.sourceId));
309
+ options.onProgress?.({
310
+ phase: "fetching",
311
+ completed: ++completedSources,
312
+ total: uniqueSources.size,
313
+ });
301
314
  }
302
315
  if (options.fetchOnly)
303
316
  return {
@@ -306,6 +319,7 @@ export async function installWorkspaceProject(options) {
306
319
  reused: 0,
307
320
  warnings,
308
321
  };
322
+ options.onProgress?.({ phase: "realizing" });
309
323
  const shared = await realizeGraph({
310
324
  store: options.store,
311
325
  graph: pureGraph,
@@ -443,6 +457,7 @@ export async function installWorkspaceProject(options) {
443
457
  });
444
458
  // Approved writes need a coherent fully private registry closure.
445
459
  await allocatePrivate(new Set(nodes.map((n) => n.key)));
460
+ options.onProgress?.({ phase: "building" });
446
461
  await buildPrivate({
447
462
  project: root,
448
463
  generationId,
@@ -498,6 +513,7 @@ export async function installWorkspaceProject(options) {
498
513
  bins[name] = actual;
499
514
  }
500
515
  }
516
+ options.onProgress?.({ phase: "linking" });
501
517
  await installProjection(holder, node.edges.map((e) => ({
502
518
  name: e.name,
503
519
  linkTarget: realized.packageDirByKey.get(e.target),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zyrk",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Storage-efficient Node package manager: one verified store per user, shared across projects through links.",
5
5
  "license": "MIT",
6
6
  "type": "module",