@orkestrel/scaffold 0.0.16 → 0.0.17

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.
@@ -787,13 +787,13 @@ export declare function readFileHex(root: string, path: string, code: ScaffoldEr
787
787
  export declare function readFileText(root: string, path: string, code: ScaffoldErrorCode, boundary: string, limit?: number): string;
788
788
 
789
789
  /**
790
- * Read bounded physical local guide mirrors for declared dependencies.
790
+ * Read bounded physical local guide mirrors for package names.
791
791
  *
792
792
  * @param target - The package root.
793
- * @param dependencies - The declared dependencies whose mirrors are eligible.
794
- * @returns Existing guide content keyed by dependency name.
793
+ * @param names - The package names whose mirrors are eligible.
794
+ * @returns Existing guide content keyed by package name.
795
795
  */
796
- export declare function readGuideReferences(target: string, dependencies: readonly Dependency[]): Readonly<Record<string, string>>;
796
+ export declare function readGuideReferences(target: string, names: readonly string[]): Readonly<Record<string, string>>;
797
797
 
798
798
  /**
799
799
  * Read and validate a vendored host root's `manifest.json`, when present.
@@ -1028,8 +1028,10 @@ export declare function storagePath(path: string): string;
1028
1028
  * map, a fetched guide byte-equal to its entry verdicts `current`, anything
1029
1029
  * differing or absent from the map verdicts `behind`; WITHOUT the map, every
1030
1030
  * successful fetch verdicts `behind` (no reference means it needs syncing).
1031
- * `pull` builds that map itself from the TARGET's own `guides/src/<short>.md`
1032
- * mirrors, so its verdicts are target-relative; `write` commits only the
1031
+ * `pull` builds that map itself from the TARGET's declared dependency mirrors;
1032
+ * `mirror` builds it from the registry's exact organization package list,
1033
+ * excluding the target's own guide and issuing no registry version reads. Both
1034
+ * verdicts are target-relative; `write` commits only the
1033
1035
  * `behind` guides (never `current`, `missing`, or `failed`, which carries no
1034
1036
  * trustworthy content) under the same realpath-anchored containment law
1035
1037
  * `Materializer` enforces. After `destroy()` every method throws `DESTROYED`;
@@ -1080,6 +1082,7 @@ export declare class Sync implements SyncInterface {
1080
1082
  */
1081
1083
  catalog(): Promise<readonly CatalogEntry[]>;
1082
1084
  pull(target: string, dependencies?: readonly Dependency[]): Promise<SyncReport>;
1085
+ mirror(target: string): Promise<SyncReport>;
1083
1086
  write(report: SyncReport, target: string): Promise<readonly string[]>;
1084
1087
  destroy(): void;
1085
1088
  }
@@ -1135,6 +1138,7 @@ export declare interface SyncInterface {
1135
1138
  versions(deps: readonly Dependency[]): Promise<readonly VersionSync[]>;
1136
1139
  catalog(): Promise<readonly CatalogEntry[]>;
1137
1140
  pull(target: string, dependencies?: readonly Dependency[]): Promise<SyncReport>;
1141
+ mirror(target: string): Promise<SyncReport>;
1138
1142
  write(report: SyncReport, target: string): Promise<readonly string[]>;
1139
1143
  destroy(): void;
1140
1144
  }
@@ -787,13 +787,13 @@ export declare function readFileHex(root: string, path: string, code: ScaffoldEr
787
787
  export declare function readFileText(root: string, path: string, code: ScaffoldErrorCode, boundary: string, limit?: number): string;
788
788
 
789
789
  /**
790
- * Read bounded physical local guide mirrors for declared dependencies.
790
+ * Read bounded physical local guide mirrors for package names.
791
791
  *
792
792
  * @param target - The package root.
793
- * @param dependencies - The declared dependencies whose mirrors are eligible.
794
- * @returns Existing guide content keyed by dependency name.
793
+ * @param names - The package names whose mirrors are eligible.
794
+ * @returns Existing guide content keyed by package name.
795
795
  */
796
- export declare function readGuideReferences(target: string, dependencies: readonly Dependency[]): Readonly<Record<string, string>>;
796
+ export declare function readGuideReferences(target: string, names: readonly string[]): Readonly<Record<string, string>>;
797
797
 
798
798
  /**
799
799
  * Read and validate a vendored host root's `manifest.json`, when present.
@@ -1028,8 +1028,10 @@ export declare function storagePath(path: string): string;
1028
1028
  * map, a fetched guide byte-equal to its entry verdicts `current`, anything
1029
1029
  * differing or absent from the map verdicts `behind`; WITHOUT the map, every
1030
1030
  * successful fetch verdicts `behind` (no reference means it needs syncing).
1031
- * `pull` builds that map itself from the TARGET's own `guides/src/<short>.md`
1032
- * mirrors, so its verdicts are target-relative; `write` commits only the
1031
+ * `pull` builds that map itself from the TARGET's declared dependency mirrors;
1032
+ * `mirror` builds it from the registry's exact organization package list,
1033
+ * excluding the target's own guide and issuing no registry version reads. Both
1034
+ * verdicts are target-relative; `write` commits only the
1033
1035
  * `behind` guides (never `current`, `missing`, or `failed`, which carries no
1034
1036
  * trustworthy content) under the same realpath-anchored containment law
1035
1037
  * `Materializer` enforces. After `destroy()` every method throws `DESTROYED`;
@@ -1080,6 +1082,7 @@ export declare class Sync implements SyncInterface {
1080
1082
  */
1081
1083
  catalog(): Promise<readonly CatalogEntry[]>;
1082
1084
  pull(target: string, dependencies?: readonly Dependency[]): Promise<SyncReport>;
1085
+ mirror(target: string): Promise<SyncReport>;
1083
1086
  write(report: SyncReport, target: string): Promise<readonly string[]>;
1084
1087
  destroy(): void;
1085
1088
  }
@@ -1135,6 +1138,7 @@ export declare interface SyncInterface {
1135
1138
  versions(deps: readonly Dependency[]): Promise<readonly VersionSync[]>;
1136
1139
  catalog(): Promise<readonly CatalogEntry[]>;
1137
1140
  pull(target: string, dependencies?: readonly Dependency[]): Promise<SyncReport>;
1141
+ mirror(target: string): Promise<SyncReport>;
1138
1142
  write(report: SyncReport, target: string): Promise<readonly string[]>;
1139
1143
  destroy(): void;
1140
1144
  }
@@ -956,16 +956,16 @@ function packageShortName(name) {
956
956
  return name.startsWith("@orkestrel/") ? name.slice(11) : name;
957
957
  }
958
958
  /**
959
- * Read bounded physical local guide mirrors for declared dependencies.
959
+ * Read bounded physical local guide mirrors for package names.
960
960
  *
961
961
  * @param target - The package root.
962
- * @param dependencies - The declared dependencies whose mirrors are eligible.
963
- * @returns Existing guide content keyed by dependency name.
962
+ * @param names - The package names whose mirrors are eligible.
963
+ * @returns Existing guide content keyed by package name.
964
964
  */
965
- function readGuideReferences(target, dependencies) {
965
+ function readGuideReferences(target, names) {
966
966
  const current = {};
967
- for (const dependency of dependencies) {
968
- const path = `guides/src/${packageShortName(dependency.name)}.md`;
967
+ for (const name of names) {
968
+ const path = `guides/src/${packageShortName(name)}.md`;
969
969
  const full = resolvePhysicalPath(target, path, "TARGET", "target");
970
970
  const status = attempt(() => lstatSync(full));
971
971
  if (!status.success) {
@@ -976,7 +976,7 @@ function readGuideReferences(target, dependencies) {
976
976
  });
977
977
  }
978
978
  if (!status.value.isFile() || status.value.isSymbolicLink() || status.value.nlink !== 1) throw new ScaffoldError("TARGET", `Local guide is not a physical file at ${path}`, { path });
979
- current[dependency.name] = readFileText(target, path, "TARGET", "target");
979
+ current[name] = readFileText(target, path, "TARGET", "target");
980
980
  }
981
981
  return Object.freeze(current);
982
982
  }
@@ -3515,8 +3515,10 @@ var Materializer = class {
3515
3515
  * map, a fetched guide byte-equal to its entry verdicts `current`, anything
3516
3516
  * differing or absent from the map verdicts `behind`; WITHOUT the map, every
3517
3517
  * successful fetch verdicts `behind` (no reference means it needs syncing).
3518
- * `pull` builds that map itself from the TARGET's own `guides/src/<short>.md`
3519
- * mirrors, so its verdicts are target-relative; `write` commits only the
3518
+ * `pull` builds that map itself from the TARGET's declared dependency mirrors;
3519
+ * `mirror` builds it from the registry's exact organization package list,
3520
+ * excluding the target's own guide and issuing no registry version reads. Both
3521
+ * verdicts are target-relative; `write` commits only the
3520
3522
  * `behind` guides (never `current`, `missing`, or `failed`, which carries no
3521
3523
  * trustworthy content) under the same realpath-anchored containment law
3522
3524
  * `Materializer` enforces. After `destroy()` every method throws `DESTROYED`;
@@ -3574,29 +3576,30 @@ var Sync = class Sync {
3574
3576
  }
3575
3577
  async guides(deps, current) {
3576
3578
  this.#ensureAlive();
3577
- return this.#guides(deps, current, Float64Array.of(this.#budget));
3579
+ const parsed = parseSyncDependencies(deps, false);
3580
+ return this.#guides(parsed.map((dependency) => dependency.name), current, Float64Array.of(this.#budget));
3578
3581
  }
3579
3582
  async versions(deps) {
3580
3583
  this.#ensureAlive();
3581
3584
  return this.#versions(deps, Float64Array.of(this.#budget));
3582
3585
  }
3583
- #guides(deps, current, allowance) {
3584
- const parsed = parseSyncDependencies(deps, false);
3586
+ #guides(names, current, allowance) {
3587
+ const parsed = parseSyncNames(names);
3585
3588
  if (parsed.length > this.#items) throw new ScaffoldError("INVALID", "Sync dependency count exceeds its item limit", {
3586
3589
  items: parsed.length,
3587
3590
  limit: this.#items
3588
3591
  });
3589
- const reference = parseSyncCurrent(current, parsed.map((dependency) => dependency.name), this.#budget);
3590
- return Sync.#runPool(parsed, this.#concurrency, async (dep) => {
3591
- const short = packageShortName(dep.name);
3592
+ const reference = parseSyncCurrent(current, parsed, this.#budget);
3593
+ return Sync.#runPool(parsed, this.#concurrency, async (name) => {
3594
+ const short = packageShortName(name);
3592
3595
  const url = this.#guideUrl(short);
3593
3596
  const outcome = await Sync.#fetchText(url, this.#guidesTimeout, this.#retries, this.#limit, allowance, this.#controller.signal);
3594
- const guide = Sync.#toGuideSync(dep.name, short, outcome, reference);
3597
+ const guide = Sync.#toGuideSync(name, short, outcome, reference);
3595
3598
  if (outcome.kind === "failed") this.#emitter.emit("error", outcome.error);
3596
- this.#emitter.emit("guide", dep.name);
3599
+ this.#emitter.emit("guide", name);
3597
3600
  if (this.#strict && (guide.freshness === "missing" || guide.freshness === "failed")) throw new ScaffoldError("FETCH", `Failed to fetch guide at ${url}`, {
3598
3601
  url,
3599
- name: dep.name
3602
+ name
3600
3603
  });
3601
3604
  return guide;
3602
3605
  });
@@ -3660,16 +3663,9 @@ var Sync = class Sync {
3660
3663
  */
3661
3664
  async catalog() {
3662
3665
  this.#ensureAlive();
3663
- const orgUrl = this.#orgUrl();
3664
3666
  const allowance = Float64Array.of(this.#budget);
3665
- const orgOutcome = await Sync.#fetchText(orgUrl, this.#registryTimeout, this.#retries, this.#limit, allowance, this.#controller.signal);
3666
- const names = Sync.#toOrgPackages(orgOutcome, orgUrl);
3667
- if (names.length > this.#items) throw new ScaffoldError("FETCH", `Package list at ${orgUrl} exceeds the item limit`, {
3668
- url: orgUrl,
3669
- items: names.length,
3670
- limit: this.#items
3671
- });
3672
- return [...await Sync.#runPool(names, this.#concurrency, async (name) => {
3667
+ const names = await this.#packages(allowance);
3668
+ return await Sync.#runPool(names, this.#concurrency, async (name) => {
3673
3669
  const packumentOutcome = await Sync.#fetchText(this.#registryUrl(name), this.#registryTimeout, this.#retries, this.#limit, allowance, this.#controller.signal);
3674
3670
  const packument = Sync.#toPackument(packumentOutcome);
3675
3671
  const short = packageShortName(name);
@@ -3685,7 +3681,7 @@ var Sync = class Sync {
3685
3681
  version: packument.version,
3686
3682
  description
3687
3683
  };
3688
- })].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
3684
+ });
3689
3685
  }
3690
3686
  async pull(target, dependencies) {
3691
3687
  this.#ensureAlive();
@@ -3694,10 +3690,21 @@ var Sync = class Sync {
3694
3690
  const deps = dependencies === void 0 ? declared : parseSyncDependencies(dependencies, false);
3695
3691
  if (dependencies !== void 0 && deps.some((dependency) => !declared.some((candidate) => candidate.name === dependency.name && candidate.range === dependency.range))) throw new ScaffoldError("INVALID", "Sync pull selection is not declared by the target");
3696
3692
  const name = manifestToName(manifest);
3697
- const guideDependencies = name === void 0 ? deps : deps.filter((dependency) => dependency.name !== name);
3698
- const current = readGuideReferences(target, guideDependencies);
3693
+ const guideNames = deps.map((dependency) => dependency.name).filter((dependency) => dependency !== name);
3694
+ const current = readGuideReferences(target, guideNames);
3699
3695
  const allowance = Float64Array.of(this.#budget);
3700
- const report = syncReportOf(target, await this.#guides(guideDependencies, current, allowance), await this.#versions(deps, allowance));
3696
+ const report = syncReportOf(target, await this.#guides(guideNames, current, allowance), await this.#versions(deps, allowance));
3697
+ this.#emitter.emit("done", report);
3698
+ return report;
3699
+ }
3700
+ async mirror(target) {
3701
+ this.#ensureAlive();
3702
+ const manifest = readManifest(target);
3703
+ const name = manifestToName(manifest);
3704
+ const allowance = Float64Array.of(this.#budget);
3705
+ const names = (await this.#packages(allowance)).filter((candidate) => candidate !== name);
3706
+ const current = readGuideReferences(target, names);
3707
+ const report = syncReportOf(target, await this.#guides(names, current, allowance), []);
3701
3708
  this.#emitter.emit("done", report);
3702
3709
  return report;
3703
3710
  }
@@ -3790,6 +3797,17 @@ var Sync = class Sync {
3790
3797
  #orgUrl() {
3791
3798
  return `${this.#registryBase}/-/org/orkestrel/package`;
3792
3799
  }
3800
+ async #packages(allowance) {
3801
+ const url = this.#orgUrl();
3802
+ const outcome = await Sync.#fetchText(url, this.#registryTimeout, this.#retries, this.#limit, allowance, this.#controller.signal);
3803
+ const names = Sync.#toOrgPackages(outcome, url);
3804
+ if (names.length > this.#items) throw new ScaffoldError("FETCH", `Package list at ${url} exceeds the item limit`, {
3805
+ url,
3806
+ items: names.length,
3807
+ limit: this.#items
3808
+ });
3809
+ return [...names].sort((left, right) => left < right ? -1 : left > right ? 1 : 0);
3810
+ }
3793
3811
  static async #runPool(items, concurrency, worker) {
3794
3812
  const results = new Array(items.length);
3795
3813
  const state = {