zyrk 0.6.2 → 0.6.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
@@ -394,7 +394,12 @@ recorded in the manifest fingerprint; frozen installs reject policy drift.
394
394
  `zyrk help` and `zyrk --help` both show help successfully. Installs report
395
395
  preparation, resolution, verified source counts, realization, approved builds,
396
396
  and project linking on stderr. Interactive terminals show an activity spinner;
397
- redirected output contains plain phase messages. `--json` disables progress.
397
+ redirected output contains plain progress messages. Both `zyrk add prettier` and
398
+ `zyrk install prettier` show these details. Source counters distinguish verified
399
+ reuse from newly downloaded sources; downloads show received bytes. A checkmark
400
+ lists each unique package/version linked after the project transaction commits.
401
+ Source counts differ from dependency contexts when peers split a package.
402
+ `--json` disables progress.
398
403
 
399
404
  Install resolution has a five-minute deadline; each archive extraction has a
400
405
  two-minute deadline. Set `ZYRK_RESOLVE_TIMEOUT_MS` or `ZYRK_EXTRACT_TIMEOUT_MS`
package/VERSION CHANGED
@@ -1 +1 @@
1
- v0.6.2
1
+ v0.6.3
@@ -1 +1 @@
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,CAyBhD;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"}
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,CAyBhD;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,CAkapE"}
package/dist/cli/main.js CHANGED
@@ -480,11 +480,13 @@ export async function runCli(options) {
480
480
  parsed.command === "remove" ||
481
481
  parsed.command === "update" ||
482
482
  parsed.command === "import")) {
483
+ const progress = createInstallProgress(options.stderr, parsed.json);
483
484
  try {
484
485
  const tools = options.tools === undefined
485
486
  ? await defaultTools(options.env, version, options.cwd ?? process.cwd())
486
487
  : await options.tools();
487
488
  const result = await runDependencyCommand({
489
+ onProgress: progress.update,
488
490
  command: parsed.command,
489
491
  env: options.env,
490
492
  args: parsed.commandArgs,
@@ -492,6 +494,7 @@ export async function runCli(options) {
492
494
  store: tools.store,
493
495
  registry: tools.registry,
494
496
  });
497
+ progress.close();
495
498
  if (parsed.json) {
496
499
  return emit({
497
500
  exitCode: 0,
@@ -501,13 +504,17 @@ export async function runCli(options) {
501
504
  }
502
505
  return emit({
503
506
  exitCode: 0,
504
- stdout: `Dependency command ${parsed.command} completed.\n`,
505
- stderr: "",
507
+ stdout: `Dependency command ${parsed.command} completed: ${result.packages} packages, ${result.reused} realizations reused; ${result.readiness}.\n`,
508
+ stderr: result.warnings.map((w) => `zyrk: ${w}\n`).join(""),
506
509
  });
507
510
  }
508
511
  catch (error) {
512
+ progress.close();
509
513
  return emit(fail(toZyrkError(error, `zyrk ${parsed.command} failed.`), parsed));
510
514
  }
515
+ finally {
516
+ progress.close();
517
+ }
511
518
  }
512
519
  // Project commands: run, exec, list, why, doctor, repair
513
520
  if (!parsed.help &&
@@ -1 +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"}
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/cli/progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAYzD,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,CA2DzD"}
@@ -5,11 +5,13 @@ const labels = {
5
5
  realizing: "Preparing shared realizations",
6
6
  building: "Preparing approved private builds",
7
7
  linking: "Linking project dependencies",
8
+ complete: "Installation complete",
8
9
  };
9
10
  /** Presentation only: never writes to stdout or exposes package URLs or paths. */
10
11
  export function createInstallProgress(stream, quiet) {
11
12
  let timer;
12
13
  let current = "", last = "", frame = 0, closed = false;
14
+ let lastDownload = 0;
13
15
  const write = (text) => {
14
16
  try {
15
17
  stream.write(text);
@@ -23,11 +25,33 @@ export function createInstallProgress(stream, quiet) {
23
25
  update(event) {
24
26
  if (quiet || closed)
25
27
  return;
28
+ const pkg = event.package;
29
+ // Registry names are validated elsewhere; strip control characters here
30
+ // as presentation defense for direct API callers and hostile metadata.
31
+ const label = pkg
32
+ ? `${pkg.name}@${pkg.version}`.replace(/[\x00-\x1f\x7f-\x9f]/g, "")
33
+ : "";
34
+ if (pkg?.status === "linked") {
35
+ if (stream.isTTY)
36
+ write("\r\u001b[2K");
37
+ write(`✓ ${label} linked\n`);
38
+ return;
39
+ }
40
+ const downloading = pkg?.status === "downloading";
41
+ if (downloading && pkg.bytes && Date.now() - lastDownload < 100)
42
+ return;
43
+ if (downloading)
44
+ lastDownload = Date.now();
26
45
  current =
27
- labels[event.phase] +
46
+ (downloading
47
+ ? `Downloading ${label}: ${((pkg.bytes ?? 0) / 1024).toFixed(1)} KiB`
48
+ : labels[event.phase]) +
28
49
  (event.total === undefined
29
50
  ? ""
30
- : ` (${event.completed ?? 0}/${event.total})`);
51
+ : ` (${event.completed ?? 0}/${event.total})`) +
52
+ (event.reused === undefined
53
+ ? ""
54
+ : ` — reused ${event.reused}, downloaded ${event.downloaded ?? 0}`);
31
55
  if (stream.isTTY) {
32
56
  render();
33
57
  if (!timer) {
@@ -1,6 +1,6 @@
1
1
  import type { RegistryClient } from "../fetch/registry.ts";
2
2
  import type { Store } from "../store/layout.ts";
3
- import { type InstallResult } from "../install/run.ts";
3
+ import { type InstallOptions, type InstallResult } from "../install/run.ts";
4
4
  export type DependencyCommand = "add" | "remove" | "update" | "import";
5
5
  export declare function runDependencyCommand(options: {
6
6
  command: DependencyCommand;
@@ -9,5 +9,6 @@ export declare function runDependencyCommand(options: {
9
9
  store: Store;
10
10
  registry: RegistryClient;
11
11
  env?: NodeJS.ProcessEnv;
12
+ onProgress?: InstallOptions["onProgress"];
12
13
  }): Promise<InstallResult>;
13
14
  //# sourceMappingURL=dependencies.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../src/commands/dependencies.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAavE,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,OAAO,EAAE,iBAAiB,CAAC;IAC3B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,GAAG,OAAO,CAAC,aAAa,CAAC,CA2HzB"}
1
+ {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../src/commands/dependencies.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAavE,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,OAAO,EAAE,iBAAiB,CAAC;IAC3B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;CAC3C,GAAG,OAAO,CAAC,aAAa,CAAC,CA4HzB"}
@@ -15,6 +15,7 @@ export async function runDependencyCommand(options) {
15
15
  store: options.store,
16
16
  registry: options.registry,
17
17
  ...(options.env ? { env: options.env } : {}),
18
+ ...(options.onProgress ? { onProgress: options.onProgress } : {}),
18
19
  };
19
20
  const names = [];
20
21
  let from;
@@ -0,0 +1,14 @@
1
+ import type { InstallOptions } from "./run.ts";
2
+ type Package = {
3
+ name: string;
4
+ version: string;
5
+ };
6
+ /** Counts verified source identities, independent of peer-split realizations. */
7
+ export declare function sourceProgress(onProgress: InstallOptions["onProgress"], total: number): {
8
+ downloading(pkg: Package): (chunk: number) => void;
9
+ verified(pkg: Package, status: "reused" | "downloaded"): void;
10
+ };
11
+ /** Only called after transactional projection publication succeeds. */
12
+ export declare function reportLinked(onProgress: InstallOptions["onProgress"], packages: readonly Package[]): void;
13
+ export {};
14
+ //# sourceMappingURL=progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/install/progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,UAAU,CAAC;AAEhE,KAAK,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACjD,iFAAiF;AACjF,wBAAgB,cAAc,CAC5B,UAAU,EAAE,cAAc,CAAC,YAAY,CAAC,EACxC,KAAK,EAAE,MAAM;IAcX,WAAW,MAAM,OAAO,WAGP,MAAM;IAKvB,QAAQ,MAAM,OAAO,UAAU,QAAQ,GAAG,YAAY;EAMzD;AACD,uEAAuE;AACvE,wBAAgB,YAAY,CAC1B,UAAU,EAAE,cAAc,CAAC,YAAY,CAAC,EACxC,QAAQ,EAAE,SAAS,OAAO,EAAE,QAU7B"}
@@ -0,0 +1,38 @@
1
+ /** Counts verified source identities, independent of peer-split realizations. */
2
+ export function sourceProgress(onProgress, total) {
3
+ let reused = 0, downloaded = 0;
4
+ const emit = (pkg) => onProgress?.({
5
+ phase: "fetching",
6
+ total,
7
+ completed: reused + downloaded,
8
+ reused,
9
+ downloaded,
10
+ ...(pkg ? { package: pkg } : {}),
11
+ });
12
+ return {
13
+ downloading(pkg) {
14
+ let bytes = 0;
15
+ emit({ ...pkg, status: "downloading", bytes });
16
+ return (chunk) => {
17
+ bytes += chunk;
18
+ emit({ ...pkg, status: "downloading", bytes });
19
+ };
20
+ },
21
+ verified(pkg, status) {
22
+ if (status === "reused")
23
+ reused++;
24
+ else
25
+ downloaded++;
26
+ emit({ ...pkg, status });
27
+ },
28
+ };
29
+ }
30
+ /** Only called after transactional projection publication succeeds. */
31
+ export function reportLinked(onProgress, packages) {
32
+ const unique = new Map(packages.map((pkg) => [JSON.stringify([pkg.name, pkg.version]), pkg]));
33
+ for (const pkg of unique.values())
34
+ onProgress?.({
35
+ phase: "complete",
36
+ package: { name: pkg.name, version: pkg.version, status: "linked" },
37
+ });
38
+ }
@@ -5,9 +5,17 @@ import type { ResolverLimits } from "../resolve/resolver.ts";
5
5
  import type { ExtractionLimits } from "../extract/tarball.ts";
6
6
  import { Store } from "../store/layout.ts";
7
7
  export type InstallProgress = {
8
- phase: "planning" | "resolving" | "fetching" | "realizing" | "building" | "linking";
8
+ phase: "planning" | "resolving" | "fetching" | "realizing" | "building" | "linking" | "complete";
9
9
  completed?: number;
10
10
  total?: number;
11
+ reused?: number;
12
+ downloaded?: number;
13
+ package?: {
14
+ name: string;
15
+ version: string;
16
+ status: "downloading" | "downloaded" | "reused" | "linked";
17
+ bytes?: number;
18
+ };
11
19
  };
12
20
  export type InstallOptions = {
13
21
  onProgress?: (event: InstallProgress) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/install/run.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAK9D,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AAYtB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AA+B3C,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,sEAAsE;IACtE,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,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,aAAa,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC1C,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,CAoyBxB"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/install/run.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { sourceProgress, reportLinked } from "./progress.js";
1
2
  import { selectPlatformGraph } from "./platform.js";
2
3
  import { findWorkspaceRoot } from "./workspaces.js";
3
4
  import { assertSupportedSourcePayload } from "./source-policy.js";
@@ -441,7 +442,7 @@ export async function installProject(options) {
441
442
  })
442
443
  : undefined;
443
444
  const unique = new Map(activeNodes.map((n) => [n.sourceId, n]));
444
- let completedSources = 0;
445
+ const progress = sourceProgress(options.onProgress, unique.size);
445
446
  options.onProgress?.({
446
447
  phase: "fetching",
447
448
  completed: 0,
@@ -451,21 +452,21 @@ export async function installProject(options) {
451
452
  operation.operation.checkpoint();
452
453
  if (await pathExists(sourceManifestPath(options.store, node.sourceId))) {
453
454
  await readSourceManifest(options.store, node.sourceId);
454
- options.onProgress?.({
455
- phase: "fetching",
456
- completed: ++completedSources,
457
- total: unique.size,
458
- });
455
+ progress.verified(node, "reused");
459
456
  continue;
460
457
  }
461
458
  if (options.offline)
462
459
  throw error("ZYRK_OFFLINE_MISSING", `Verified source for ${node.name}@${node.version} is missing from the store.`);
463
460
  const tarball = path.join(txn.dir, `${node.sourceId}.tgz`);
461
+ const downloadProgress = progress.downloading(node);
464
462
  const download = await options.registry
465
463
  .forPackage(node.name)
466
464
  .downloadTarball({
467
465
  signal: operation.operation.signal,
468
- onBytes: operation.operation.consumeArchiveBytes,
466
+ onBytes(bytes) {
467
+ operation.operation.consumeArchiveBytes(bytes);
468
+ downloadProgress(bytes);
469
+ },
469
470
  url: node.tarballUrl,
470
471
  expectedIntegrity: node.integrity,
471
472
  destPath: tarball,
@@ -490,11 +491,7 @@ export async function installProject(options) {
490
491
  if (source.sourceId !== node.sourceId)
491
492
  throw lockMismatch("download identity disagrees with the locked source");
492
493
  await rm(tarball, { force: true });
493
- options.onProgress?.({
494
- phase: "fetching",
495
- completed: ++completedSources,
496
- total: unique.size,
497
- });
494
+ progress.verified(node, "downloaded");
498
495
  }
499
496
  for (const node of unique.values())
500
497
  assertSupportedSourcePayload(node, await readSourceManifest(options.store, node.sourceId));
@@ -707,6 +704,7 @@ export async function installProject(options) {
707
704
  });
708
705
  registration.activate();
709
706
  await txn.setState("committed");
707
+ reportLinked(options.onProgress, activeNodes);
710
708
  return {
711
709
  readiness,
712
710
  packages: activeNodes.length,
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-install.d.ts","sourceRoot":"","sources":["../../src/install/workspace-install.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAuH9D,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAmrBxB"}
1
+ {"version":3,"file":"workspace-install.d.ts","sourceRoot":"","sources":["../../src/install/workspace-install.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAuH9D,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAqrBxB"}
@@ -1,3 +1,4 @@
1
+ import { sourceProgress, reportLinked } from "./progress.js";
1
2
  import { selectWorkspacePlatform } from "./platform.js";
2
3
  /** Multi-importer live workspace installation with one publication journal. */
3
4
  import { chmod, copyFile, lstat, mkdir, readFile, realpath, rename, rm, symlink, } from "node:fs/promises";
@@ -264,7 +265,7 @@ export async function installWorkspaceProject(options) {
264
265
  })
265
266
  : undefined;
266
267
  const uniqueSources = new Map(nodes.map((n) => [n.sourceId, n]));
267
- let completedSources = 0;
268
+ const progress = sourceProgress(options.onProgress, uniqueSources.size);
268
269
  options.onProgress?.({
269
270
  phase: "fetching",
270
271
  completed: 0,
@@ -272,11 +273,13 @@ export async function installWorkspaceProject(options) {
272
273
  });
273
274
  for (const node of uniqueSources.values()) {
274
275
  operation.operation.checkpoint();
275
- if (!(await pathExists(sourceManifestPath(options.store, node.sourceId)))) {
276
+ const cached = await pathExists(sourceManifestPath(options.store, node.sourceId));
277
+ if (!cached) {
276
278
  if (options.offline)
277
279
  throw new ZyrkError("ZYRK_OFFLINE_MISSING", `Verified workspace dependency ${node.name}@${node.version} is missing.`, {
278
280
  remedy: "Fetch the exact locked sources online before retrying offline.",
279
281
  });
282
+ const downloadProgress = progress.downloading(node);
280
283
  const archive = path.join(txn.dir, `${node.sourceId}.tgz`), download = await options.registry
281
284
  .forPackage(node.name)
282
285
  .downloadTarball({
@@ -285,7 +288,10 @@ export async function installWorkspaceProject(options) {
285
288
  destPath: archive,
286
289
  label: `${node.name}@${node.version}`,
287
290
  signal: operation.operation.signal,
288
- onBytes: operation.operation.consumeArchiveBytes,
291
+ onBytes(bytes) {
292
+ operation.operation.consumeArchiveBytes(bytes);
293
+ downloadProgress(bytes);
294
+ },
289
295
  });
290
296
  const extraction = await extractTarball({
291
297
  limits: options.extractBudget,
@@ -308,11 +314,7 @@ export async function installWorkspaceProject(options) {
308
314
  await rm(archive, { force: true });
309
315
  }
310
316
  assertSupportedSourcePayload(node, await readSourceManifest(options.store, node.sourceId));
311
- options.onProgress?.({
312
- phase: "fetching",
313
- completed: ++completedSources,
314
- total: uniqueSources.size,
315
- });
317
+ progress.verified(node, cached ? "reused" : "downloaded");
316
318
  }
317
319
  if (options.fetchOnly)
318
320
  return {
@@ -562,6 +564,7 @@ export async function installWorkspaceProject(options) {
562
564
  throw lockMismatch("workspace manifest changed during install");
563
565
  await publishWorkspaceProjection(root, generationId, project.importers.map((i) => i.id), lockText, manifestChanges);
564
566
  registration.activate();
567
+ reportLinked(options.onProgress, nodes);
565
568
  return {
566
569
  readiness,
567
570
  packages: nodes.length,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zyrk",
3
- "version": "0.6.2",
3
+ "version": "0.6.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",