@travetto/manifest 4.0.0-rc.1 → 4.0.0-rc.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/bin/context.js +9 -15
- package/package.json +1 -1
- package/src/dependencies.ts +61 -33
- package/src/module.ts +1 -2
- package/src/package.ts +1 -33
- package/src/runtime.ts +7 -0
- package/src/types/package.ts +1 -19
- package/support/transformer.function-metadata.ts +1 -4
package/bin/context.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @typedef {import('../src/types/package').Package & { path:string }} Pkg
|
|
5
|
-
* @typedef {Pkg & { mono: boolean, manager: 'yarn'|'npm', resolve: (file:string) => string}} Workspace
|
|
5
|
+
* @typedef {Pkg & { mono: boolean, manager: 'yarn'|'npm', resolve: (file:string) => string, stripRoot: (file:string)=>string}} Workspace
|
|
6
6
|
* @typedef {import('../src/types/context').ManifestContext} ManifestContext
|
|
7
7
|
*/
|
|
8
|
-
import { existsSync,
|
|
8
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
9
9
|
import path from 'node:path';
|
|
10
10
|
import { createRequire } from 'node:module';
|
|
11
11
|
|
|
@@ -79,6 +79,7 @@ function $resolveWorkspace(base = process.cwd()) {
|
|
|
79
79
|
type: pkg.type,
|
|
80
80
|
manager: existsSync(path.resolve(pkg.path, 'yarn.lock')) ? 'yarn' : 'npm',
|
|
81
81
|
resolve: createRequire(`${pkg.path}/node_modules`).resolve.bind(null),
|
|
82
|
+
stripRoot: (full) => full === pkg.path ? '' : full.replace(`${pkg.path}/`, ''),
|
|
82
83
|
mono: !!pkg.workspaces || (!pkg.travetto?.build?.isolated && !!prevPkg) // Workspaces or nested projects
|
|
83
84
|
};
|
|
84
85
|
}
|
|
@@ -86,18 +87,11 @@ function $resolveWorkspace(base = process.cwd()) {
|
|
|
86
87
|
/**
|
|
87
88
|
* Get Compiler url
|
|
88
89
|
* @param {Workspace} ws
|
|
89
|
-
* @param {string} toolFolder
|
|
90
90
|
*/
|
|
91
|
-
function $getCompilerUrl(ws
|
|
92
|
-
const file = path.resolve(ws.path, toolFolder, 'build.compilerUrl');
|
|
91
|
+
function $getCompilerUrl(ws) {
|
|
93
92
|
// eslint-disable-next-line no-bitwise
|
|
94
|
-
const port = (Math.abs([...
|
|
95
|
-
|
|
96
|
-
if (!existsSync(file)) {
|
|
97
|
-
mkdirSync(path.dirname(file), { recursive: true });
|
|
98
|
-
writeFileSync(file, out, 'utf8');
|
|
99
|
-
}
|
|
100
|
-
return out;
|
|
93
|
+
const port = (Math.abs([...ws.path].reduce((a, b) => (a * 33) ^ b.charCodeAt(0), 5381)) % 29000) + 20000;
|
|
94
|
+
return `http://localhost:${port}`;
|
|
101
95
|
}
|
|
102
96
|
|
|
103
97
|
/**
|
|
@@ -156,14 +150,14 @@ export function getManifestContext(folder) {
|
|
|
156
150
|
},
|
|
157
151
|
build: {
|
|
158
152
|
compilerFolder: build.compilerFolder ?? COMPILER_FOLDER,
|
|
159
|
-
compilerUrl: build.compilerUrl ?? $getCompilerUrl(workspace
|
|
160
|
-
compilerModuleFolder: path.dirname(workspace.resolve('@travetto/compiler/package.json'))
|
|
153
|
+
compilerUrl: build.compilerUrl ?? $getCompilerUrl(workspace),
|
|
154
|
+
compilerModuleFolder: workspace.stripRoot(path.dirname(workspace.resolve('@travetto/compiler/package.json'))),
|
|
161
155
|
outputFolder: build.outputFolder ?? OUTPUT_FOLDER,
|
|
162
156
|
toolFolder
|
|
163
157
|
},
|
|
164
158
|
main: {
|
|
165
159
|
name: mod.name ?? 'untitled',
|
|
166
|
-
folder:
|
|
160
|
+
folder: workspace.stripRoot(mod.path),
|
|
167
161
|
version: mod.version,
|
|
168
162
|
description: mod.description
|
|
169
163
|
}
|
package/package.json
CHANGED
package/src/dependencies.ts
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
import { PackageUtil } from './package';
|
|
2
2
|
import { path } from './path';
|
|
3
3
|
|
|
4
|
-
import type { Package, PackageDepType
|
|
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
|
|
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<
|
|
27
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
45
|
-
|
|
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
|
|
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(
|
|
63
|
-
const
|
|
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
|
|
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
|
|
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
|
*/
|
package/src/runtime.ts
CHANGED
|
@@ -126,6 +126,13 @@ export const RuntimeContext = build({
|
|
|
126
126
|
workspaceRelative(...rel: string[]): string {
|
|
127
127
|
return path.resolve(RuntimeIndex.manifest.workspace.path, ...rel);
|
|
128
128
|
},
|
|
129
|
+
/**
|
|
130
|
+
* Strip off the workspace path from a file
|
|
131
|
+
* @param full A full path
|
|
132
|
+
*/
|
|
133
|
+
stripWorkspacePath(full: string): string {
|
|
134
|
+
return full === RuntimeIndex.manifest.workspace.path ? '' : full.replace(`${RuntimeIndex.manifest.workspace.path}/`, '');
|
|
135
|
+
},
|
|
129
136
|
/**
|
|
130
137
|
* Produce a workspace path for tooling, with '@' being replaced by node_module/name folder
|
|
131
138
|
* @param rel The relative path
|
package/src/types/package.ts
CHANGED
|
@@ -44,6 +44,7 @@ export type Package = {
|
|
|
44
44
|
build?: Partial<ManifestContext['build']> & {
|
|
45
45
|
isolated?: boolean;
|
|
46
46
|
withModules?: Record<string, 'main' | true>;
|
|
47
|
+
watchIgnores?: string[];
|
|
47
48
|
};
|
|
48
49
|
};
|
|
49
50
|
workspaces?: string[];
|
|
@@ -53,23 +54,4 @@ export type Package = {
|
|
|
53
54
|
|
|
54
55
|
export type PackageDepType = 'dependencies' | 'devDependencies' | 'optionalDependencies' | 'peerDependencies';
|
|
55
56
|
|
|
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
57
|
export type PackageWorkspaceEntry = { name: string, path: string };
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
|
|
8
8
|
const MANIFEST_MOD = '@travetto/manifest';
|
|
9
9
|
const MANIFEST_IDX = `${MANIFEST_MOD}/__index__`;
|
|
10
|
-
const ENTRY_POINT = 'support/entry';
|
|
11
10
|
|
|
12
11
|
const RUNTIME_IDX_IMPORT = `${MANIFEST_MOD}/src/runtime`;
|
|
13
12
|
const RUNTIME_IDX_CLS = 'RuntimeIndex';
|
|
@@ -32,9 +31,7 @@ interface MetadataInfo {
|
|
|
32
31
|
export class RegisterTransformer {
|
|
33
32
|
|
|
34
33
|
static #valid({ importName: imp }: TransformerState): boolean {
|
|
35
|
-
return !imp.startsWith(MANIFEST_MOD)
|
|
36
|
-
!imp.includes(ENTRY_POINT) :
|
|
37
|
-
!(/[/](src|support)[/]/.test(imp) || imp === MANIFEST_IDX);
|
|
34
|
+
return !imp.startsWith(MANIFEST_MOD) || !(/[/](src|support)[/]/.test(imp) || imp === MANIFEST_IDX);
|
|
38
35
|
}
|
|
39
36
|
|
|
40
37
|
/**
|