@travetto/manifest 4.0.0-rc.1 → 4.0.0-rc.2

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": "@travetto/manifest",
3
- "version": "4.0.0-rc.1",
3
+ "version": "4.0.0-rc.2",
4
4
  "description": "Support for project indexing, manifesting, along with file watching",
5
5
  "keywords": [
6
6
  "path",
@@ -1,16 +1,27 @@
1
1
  import { PackageUtil } from './package';
2
2
  import { path } from './path';
3
3
 
4
- import type { Package, PackageDepType, PackageVisitReq, PackageVisitor } from './types/package';
4
+ import type { Package, PackageDepType } from './types/package';
5
5
  import type { ManifestContext } from './types/context';
6
6
  import type { PackageModule } from './types/manifest';
7
7
 
8
- type CreateOpts = Partial<Pick<PackageModule, 'main' | 'workspace' | 'prod'>> & { roleRoot?: boolean };
8
+ type CreateOpts = Partial<Pick<PackageModule, 'main' | 'workspace' | 'prod'>> & { roleRoot?: boolean, parent?: PackageModule };
9
+
10
+ type Req = {
11
+ /** Request package */
12
+ pkg: Package;
13
+ /** Children to visit */
14
+ children: Record<string, string>;
15
+ /** Value */
16
+ value: PackageModule;
17
+ /** Parent */
18
+ parent?: PackageModule;
19
+ };
9
20
 
10
21
  /**
11
22
  * Used for walking dependencies for collecting modules for the manifest
12
23
  */
13
- export class PackageModuleVisitor implements PackageVisitor<PackageModule> {
24
+ export class PackageModuleVisitor {
14
25
 
15
26
  constructor(public ctx: ManifestContext) {
16
27
  this.#mainSourcePath = path.resolve(this.ctx.workspace.path, this.ctx.main.folder);
@@ -23,9 +34,8 @@ export class PackageModuleVisitor implements PackageVisitor<PackageModule> {
23
34
  /**
24
35
  * Initialize visitor, and provide global dependencies
25
36
  */
26
- async init(): Promise<Iterable<PackageVisitReq<PackageModule>>> {
27
- const mainPkg = PackageUtil.readPackage(this.#mainSourcePath);
28
- const mainReq = this.create(mainPkg, { main: true, workspace: true, roleRoot: true, prod: true });
37
+ async init(): Promise<Iterable<Req>> {
38
+ const mainReq = this.#create(this.#mainSourcePath, { main: true, workspace: true, roleRoot: true, prod: true });
29
39
  const globals = [mainReq];
30
40
  this.#workspaceModules = new Map(
31
41
  (await PackageUtil.resolveWorkspaces(this.ctx)).map(x => [x.name, x.path])
@@ -34,33 +44,26 @@ export class PackageModuleVisitor implements PackageVisitor<PackageModule> {
34
44
  // Treat all workspace modules as main modules
35
45
  if (this.ctx.workspace.mono && !this.ctx.main.folder) {
36
46
  for (const [, loc] of this.#workspaceModules) {
37
- const depPkg = PackageUtil.readPackage(loc);
38
- globals.push(this.create(depPkg, { main: true, workspace: true, roleRoot: true }));
47
+ globals.push(this.#create(loc, { main: true, workspace: true, roleRoot: true, parent: mainReq.value }));
39
48
  }
40
49
  } else {
41
50
  // If we have 'withModules' at workspace root
42
51
  const root = PackageUtil.readPackage(this.ctx.workspace.path);
43
52
  for (const [name, type] of Object.entries(root.travetto?.build?.withModules ?? {})) {
44
- const depPkg = PackageUtil.readPackage(PackageUtil.resolvePackagePath(name));
45
- globals.push(this.create(depPkg, { main: type === 'main', workspace: true }));
53
+ globals.push(this.#create(PackageUtil.resolvePackagePath(name),
54
+ { main: type === 'main', workspace: true, parent: mainReq.value }
55
+ ));
46
56
  }
47
57
  }
48
58
 
49
- return globals.map((x, i) => i === 0 ? x : { ...x, parent: mainReq.value });
50
- }
51
-
52
- /**
53
- * Is valid dependency for searching
54
- */
55
- valid({ value: node }: PackageVisitReq<PackageModule>): boolean {
56
- return node.workspace || !!node.state.travetto; // Workspace or travetto module
59
+ return globals;
57
60
  }
58
61
 
59
62
  /**
60
63
  * Build a package module
61
64
  */
62
- create(pkg: Package, { main, workspace, prod = false, roleRoot = false }: CreateOpts = {}): PackageVisitReq<PackageModule> {
63
- const sourcePath = PackageUtil.getPackagePath(pkg);
65
+ #create(sourcePath: string, { main, workspace, prod = false, roleRoot = false, parent }: CreateOpts = {}): Req {
66
+ const pkg = PackageUtil.readPackage(sourcePath);
64
67
  const value = this.#cache[sourcePath] ??= {
65
68
  main,
66
69
  prod,
@@ -78,24 +81,13 @@ export class PackageModuleVisitor implements PackageVisitor<PackageModule> {
78
81
 
79
82
  const deps: PackageDepType[] = ['dependencies', ...(value.main ? ['devDependencies'] as const : [])];
80
83
  const children = Object.fromEntries(deps.flatMap(x => Object.entries(pkg[x] ?? {})));
81
- return { pkg, value, children };
82
- }
83
-
84
- /**
85
- * Visit dependency
86
- */
87
- visit({ value: mod, parent }: PackageVisitReq<PackageModule>): void {
88
- if (mod.name === this.ctx.main.name) { return; } // Skip root
89
- if (parent) {
90
- mod.state.parentSet.add(parent.name);
91
- parent.state.childSet.add(mod.name);
92
- }
84
+ return { pkg, value, children, parent };
93
85
  }
94
86
 
95
87
  /**
96
88
  * Propagate prod, role information through graph
97
89
  */
98
- async complete(mods: Iterable<PackageModule>): Promise<PackageModule[]> {
90
+ async #complete(mods: Iterable<PackageModule>): Promise<PackageModule[]> {
99
91
  const mapping = new Map([...mods].map(el => [el.name, { parent: new Set(el.state.parentSet), el }]));
100
92
 
101
93
  // All first-level dependencies should have role filled in (for propagation)
@@ -144,4 +136,40 @@ export class PackageModuleVisitor implements PackageVisitor<PackageModule> {
144
136
 
145
137
  return [...mods].sort((a, b) => a.name.localeCompare(b.name));
146
138
  }
139
+
140
+
141
+ /**
142
+ * Visit packages with ability to track duplicates
143
+ */
144
+ async visit(): Promise<Iterable<PackageModule>> {
145
+ const seen = new Set<PackageModule>();
146
+ const queue = [...await this.init()];
147
+
148
+ while (queue.length) {
149
+ const { value: node, parent, children, pkg } = queue.shift()!; // Visit initial set first
150
+ if (!node || (!node.workspace && !node.state.travetto)) {
151
+ continue;
152
+ }
153
+
154
+ // Track parentage
155
+ if (node.name !== this.ctx.main.name && parent) {
156
+ node.state.parentSet.add(parent.name);
157
+ parent.state.childSet.add(node.name);
158
+ }
159
+
160
+ if (seen.has(node)) {
161
+ continue;
162
+ } else {
163
+ seen.add(node);
164
+ }
165
+
166
+ const next = Object.entries(children)
167
+ .map(([n, v]) => PackageUtil.resolveVersionPath(pkg, v) ?? PackageUtil.resolvePackagePath(n))
168
+ .map(loc => this.#create(loc, { parent: node }));
169
+
170
+ queue.push(...next);
171
+ }
172
+
173
+ return await this.#complete(seen);
174
+ }
147
175
  }
package/src/module.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import fs from 'node:fs/promises';
2
2
 
3
3
  import { path } from './path';
4
- import { PackageUtil } from './package';
5
4
  import { PackageModuleVisitor } from './dependencies';
6
5
 
7
6
  import type { ManifestModuleFileType, ManifestModuleRole, ManifestModuleFolderType } from './types/common';
@@ -198,7 +197,7 @@ export class ManifestModuleUtil {
198
197
  * Produce all modules for a given manifest folder, adding in some given modules when developing framework
199
198
  */
200
199
  static async produceModules(ctx: ManifestContext): Promise<Record<string, ManifestModule>> {
201
- const pkgs = await PackageUtil.visitPackages(new PackageModuleVisitor(ctx));
200
+ const pkgs = await new PackageModuleVisitor(ctx).visit();
202
201
  const modules = await Promise.all([...pkgs].map(x => this.describeModule(ctx, x)));
203
202
  return Object.fromEntries(modules.map(m => [m.name, m]));
204
203
  }
package/src/package.ts CHANGED
@@ -4,7 +4,7 @@ import { execSync } from 'node:child_process';
4
4
  import { path } from './path';
5
5
  import { ManifestFileUtil } from './file';
6
6
 
7
- import { PackagePath, type Package, type PackageVisitor, type PackageWorkspaceEntry } from './types/package';
7
+ import { PackagePath, type Package, type PackageWorkspaceEntry } from './types/package';
8
8
  import type { ManifestContext } from './types/context';
9
9
  import type { NodePackageManager } from './types/common';
10
10
 
@@ -81,38 +81,6 @@ export class PackageUtil {
81
81
  return pkg[PackagePath];
82
82
  }
83
83
 
84
- /**
85
- * Visit packages with ability to track duplicates
86
- */
87
- static async visitPackages<T>(visitor: PackageVisitor<T>): Promise<Iterable<T>> {
88
- const seen = new Set<T>();
89
- const queue = [...await visitor.init()];
90
-
91
- while (queue.length) {
92
- const node = queue.shift()!; // Visit initial set first
93
-
94
- if (!visitor.valid(node)) {
95
- continue;
96
- }
97
-
98
- visitor.visit(node);
99
-
100
- if (seen.has(node.value)) {
101
- continue;
102
- } else {
103
- seen.add(node.value);
104
- }
105
-
106
- const children = Object.entries(node.children)
107
- .map(([n, v]) => this.readPackage(this.resolveVersionPath(node.pkg, v) ?? this.resolvePackagePath(n)))
108
- .map(pkg => ({ ...visitor.create(pkg), parent: node.value }));
109
-
110
- queue.push(...children);
111
- }
112
-
113
- return await visitor.complete(seen);
114
- }
115
-
116
84
  /**
117
85
  * Find workspace values from rootPath
118
86
  */
@@ -53,23 +53,4 @@ export type Package = {
53
53
 
54
54
  export type PackageDepType = 'dependencies' | 'devDependencies' | 'optionalDependencies' | 'peerDependencies';
55
55
 
56
- export type PackageVisitReq<T> = {
57
- /** Request package */
58
- pkg: Package;
59
- /** Children to visit */
60
- children: Record<string, string>;
61
- /** Value */
62
- value: T;
63
- /** Parent */
64
- parent?: T;
65
- };
66
-
67
- export type PackageVisitor<T> = {
68
- create(pkg: Package): PackageVisitReq<T>;
69
- init(): Promise<Iterable<PackageVisitReq<T>>>;
70
- valid(req: PackageVisitReq<T>): boolean;
71
- visit(req: PackageVisitReq<T>): void;
72
- complete(values: Iterable<T>): Promise<Iterable<T>>;
73
- };
74
-
75
56
  export type PackageWorkspaceEntry = { name: string, path: string };