@jointhedots/gear 1.1.10 → 1.1.11
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/esm/builder/build-app-bundle.js +3 -2
- package/esm/builder/build-app-host.js +2 -0
- package/esm/builder/build-application.js +2 -0
- package/esm/builder/build-library.js +3 -2
- package/esm/builder/build-target.js +18 -3
- package/esm/builder/esbuild-plugins.js +88 -11
- package/esm/commands/init.js +13 -0
- package/esm/commands/make.js +5 -1
- package/esm/commands/publish.js +4 -1
- package/esm/commands/serve.js +5 -2
- package/esm/model/helpers/create-manifests.js +26 -12
- package/esm/model/helpers/discover-workspace.js +21 -5
- package/esm/model/helpers/logger.js +25 -1
- package/esm/model/workspace.js +27 -7
- package/package.json +4 -3
- package/readme.md +136 -0
- package/schemas/declaration.schema.json +76 -0
- package/esm/builder/build-app-bundle.js.map +0 -1
- package/esm/builder/build-app-host.js.map +0 -1
- package/esm/builder/build-application.js.map +0 -1
- package/esm/builder/build-library.js.map +0 -1
- package/esm/builder/build-target.js.map +0 -1
- package/esm/builder/emit-dts.js.map +0 -1
- package/esm/builder/esbuild-plugins.js.map +0 -1
- package/esm/builder/helpers/path-helpers.js.map +0 -1
- package/esm/cli.js.map +0 -1
- package/esm/commands/init.js.map +0 -1
- package/esm/commands/make.js.map +0 -1
- package/esm/commands/publish.js.map +0 -1
- package/esm/commands/run.js.map +0 -1
- package/esm/commands/serve.js.map +0 -1
- package/esm/model/component.js.map +0 -1
- package/esm/model/helpers/config-loader.js.map +0 -1
- package/esm/model/helpers/create-manifests.js.map +0 -1
- package/esm/model/helpers/discover-workspace.js.map +0 -1
- package/esm/model/helpers/logger.js.map +0 -1
- package/esm/model/helpers/package-npm.js.map +0 -1
- package/esm/model/storage.js.map +0 -1
- package/esm/model/workspace.js.map +0 -1
- package/esm/publish/publish_aws_s3.js.map +0 -1
- package/esm/utils/file.js.map +0 -1
- package/esm/utils/graph-ordering.js.map +0 -1
- package/esm/utils/normalized-name.js.map +0 -1
|
@@ -19,15 +19,16 @@ export function create_bundle_target(opts) {
|
|
|
19
19
|
const lib = library;
|
|
20
20
|
const target = new BuildTarget(bundle.id, storage, lib.workspace, opts.devmode == true, opts.watch == true, opts.clean == true);
|
|
21
21
|
const manifs = create_manifests(lib, bundle, opts.version);
|
|
22
|
+
// Prepare esm setup
|
|
23
|
+
target.esmodules.set_root(lib.path);
|
|
22
24
|
// Add bundle package.json
|
|
23
25
|
target.assets.add_static_json("package.json", manifs.package);
|
|
24
26
|
// Add bundle types.d.ts
|
|
25
27
|
target.tasks.push(new TypescriptDefinitionTask(target, lib));
|
|
26
28
|
// Add bundle exporteds
|
|
27
|
-
const { esmodules } = target;
|
|
28
29
|
for (const exp_id in manifs.entries) {
|
|
29
30
|
const exp = manifs.entries[exp_id];
|
|
30
|
-
esmodules.add_entry(exp.basename, exp.source);
|
|
31
|
+
target.esmodules.add_entry(exp.basename, exp.source);
|
|
31
32
|
}
|
|
32
33
|
// Add bundle content
|
|
33
34
|
if (bundle) {
|
|
@@ -12,6 +12,8 @@ function create_application_composable_target(opts) {
|
|
|
12
12
|
const bundle = lib.bundle;
|
|
13
13
|
const ws = lib.workspace;
|
|
14
14
|
const target = new BuildTarget(name, opts.storage, ws, opts.devmode == true, opts.watch == true, opts.clean == true);
|
|
15
|
+
// Prepare esm setup
|
|
16
|
+
target.esmodules.set_root(lib.path);
|
|
15
17
|
// Generate hotreload assets
|
|
16
18
|
const html_injects = [];
|
|
17
19
|
if (opts.devserver) {
|
|
@@ -36,6 +36,8 @@ export function create_application_monolith_target(opts) {
|
|
|
36
36
|
const target = new BuildTarget(name, opts.storage, ws, opts.devmode == true, opts.watch == true, opts.clean == true);
|
|
37
37
|
const libs = collect_app_libraries(app);
|
|
38
38
|
target.log.info(`+ 🧭 app-library-graph: ${libs.map(lib => `${lib.name}@${lib.descriptor.version}`).join(", ")}`);
|
|
39
|
+
// Prepare esm setup
|
|
40
|
+
target.esmodules.set_root(lib.path);
|
|
39
41
|
// Generate hotreload assets
|
|
40
42
|
const html_injects = [];
|
|
41
43
|
if (opts.devserver) {
|
|
@@ -9,11 +9,12 @@ export function create_library_target(opts) {
|
|
|
9
9
|
const lib = opts.library;
|
|
10
10
|
const target = new BuildTarget(lib.name, opts.storage, lib.workspace, opts.devmode == true, opts.watch == true, opts.clean == true);
|
|
11
11
|
const manifs = create_manifests(lib, lib.bundle, opts.version);
|
|
12
|
+
// Prepare esm setup
|
|
13
|
+
target.esmodules.set_root(lib.path);
|
|
12
14
|
// Add bundle exporteds
|
|
13
|
-
const { esmodules } = target;
|
|
14
15
|
for (const exp_id in manifs.entries) {
|
|
15
16
|
const exp = manifs.entries[exp_id];
|
|
16
|
-
esmodules.add_entry(exp.basename, exp.source);
|
|
17
|
+
target.esmodules.add_entry(exp.basename, exp.source);
|
|
17
18
|
}
|
|
18
19
|
// Add library types.d.ts
|
|
19
20
|
target.tasks.push(new TypescriptDefinitionTask(target, lib));
|
|
@@ -87,6 +87,10 @@ export class ESModulesTask extends BuildTask {
|
|
|
87
87
|
context = null;
|
|
88
88
|
transaction = null;
|
|
89
89
|
polyfilled = true;
|
|
90
|
+
rootPath = null;
|
|
91
|
+
set_root(path) {
|
|
92
|
+
this.rootPath = path;
|
|
93
|
+
}
|
|
90
94
|
add_entry(name, path) {
|
|
91
95
|
this.entries[name] = path;
|
|
92
96
|
this.imports[path] = name;
|
|
@@ -194,17 +198,28 @@ export class BuildTarget {
|
|
|
194
198
|
}
|
|
195
199
|
this.components.set(id, manifest);
|
|
196
200
|
}
|
|
201
|
+
async chrona(task) {
|
|
202
|
+
const name = task.constructor.name;
|
|
203
|
+
const start = Date.now();
|
|
204
|
+
await task.execute();
|
|
205
|
+
const elapsed = (Date.now() - start) / 1000;
|
|
206
|
+
this.log.info(`⏱ ${name} completed in ${elapsed.toFixed(2)}s`);
|
|
207
|
+
}
|
|
197
208
|
async build() {
|
|
209
|
+
const buildStartTime = Date.now();
|
|
198
210
|
if (this.clean)
|
|
199
211
|
this.storage.clean();
|
|
200
212
|
// Make assets
|
|
201
|
-
await this.assets
|
|
213
|
+
await this.chrona(this.assets);
|
|
202
214
|
// Make generic tasks
|
|
203
215
|
for (const task of this.tasks) {
|
|
204
|
-
await
|
|
216
|
+
await this.chrona(task);
|
|
205
217
|
}
|
|
206
218
|
// Make esmodules
|
|
207
|
-
await this.esmodules
|
|
219
|
+
await this.chrona(this.esmodules);
|
|
220
|
+
// Trace time
|
|
221
|
+
const buildTime = (Date.now() - buildStartTime) / 1000;
|
|
222
|
+
this.log.info(`Build completed in ${buildTime.toFixed(2)}s`);
|
|
208
223
|
if (this.watch) {
|
|
209
224
|
await new Promise((resolve) => {
|
|
210
225
|
process.on('SIGQUIT', () => resolve(null));
|
|
@@ -9,6 +9,17 @@ import { ESModulesTask } from "./build-target.js";
|
|
|
9
9
|
import { PackageRootDir } from "../utils/file.js";
|
|
10
10
|
import { Library } from "../model/workspace.js";
|
|
11
11
|
const VirtualOutDir = Path.normalize('X:/');
|
|
12
|
+
function getEsbuildLogLevel(mode) {
|
|
13
|
+
switch (mode) {
|
|
14
|
+
case "verbose":
|
|
15
|
+
return "debug";
|
|
16
|
+
case "debug":
|
|
17
|
+
return "info";
|
|
18
|
+
case "normal":
|
|
19
|
+
default:
|
|
20
|
+
return "silent";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
12
23
|
export async function create_esbuild_context(task, devmode) {
|
|
13
24
|
const ws = task.target.workspace;
|
|
14
25
|
// Define modules mapping - using @jspm/core polyfills (same as Vite)
|
|
@@ -40,6 +51,7 @@ export async function create_esbuild_context(task, devmode) {
|
|
|
40
51
|
}
|
|
41
52
|
return result;
|
|
42
53
|
}
|
|
54
|
+
const tsconfig = new TSConfig(task.rootPath, ws.path);
|
|
43
55
|
const modules_mapping = {
|
|
44
56
|
task,
|
|
45
57
|
routeds: {
|
|
@@ -74,13 +86,14 @@ export async function create_esbuild_context(task, devmode) {
|
|
|
74
86
|
format: 'esm',
|
|
75
87
|
target: 'es2022',
|
|
76
88
|
platform: "browser",
|
|
89
|
+
tsconfig: tsconfig.configFile ?? undefined,
|
|
77
90
|
sourcemap: devmode ? "linked" : false,
|
|
78
91
|
minify: devmode ? false : true,
|
|
79
92
|
bundle: true,
|
|
80
93
|
splitting: true,
|
|
81
94
|
treeShaking: true,
|
|
82
95
|
write: false,
|
|
83
|
-
logLevel:
|
|
96
|
+
logLevel: getEsbuildLogLevel(ws.logger.mode),
|
|
84
97
|
chunkNames: "chunk.[hash]",
|
|
85
98
|
jsx: "automatic",
|
|
86
99
|
jsxImportSource: "react",
|
|
@@ -94,8 +107,8 @@ export async function create_esbuild_context(task, devmode) {
|
|
|
94
107
|
...workspace_constants,
|
|
95
108
|
},
|
|
96
109
|
plugins: [
|
|
110
|
+
ESModuleResolverPlugin(modules_mapping, tsconfig),
|
|
97
111
|
...task.plugins,
|
|
98
|
-
ESModuleResolverPlugin(modules_mapping),
|
|
99
112
|
StyleSheetPlugin(task),
|
|
100
113
|
StoragePlugin(task),
|
|
101
114
|
],
|
|
@@ -245,11 +258,10 @@ export function StoragePlugin(task) {
|
|
|
245
258
|
return {
|
|
246
259
|
name: "dipatch-files",
|
|
247
260
|
setup: (build) => {
|
|
248
|
-
|
|
261
|
+
let buildStartTime = 0;
|
|
249
262
|
build.onStart(() => {
|
|
250
263
|
task.log.clear();
|
|
251
|
-
|
|
252
|
-
buildStartTime = performance.now();
|
|
264
|
+
buildStartTime = Date.now();
|
|
253
265
|
});
|
|
254
266
|
build.onEnd(async (result) => {
|
|
255
267
|
if (result.errors.length > 0) {
|
|
@@ -262,7 +274,7 @@ export function StoragePlugin(task) {
|
|
|
262
274
|
task.log.warn(warning);
|
|
263
275
|
}
|
|
264
276
|
if (result.outputFiles) {
|
|
265
|
-
const storeStart =
|
|
277
|
+
const storeStart = Date.now();
|
|
266
278
|
const tx = task.target.edit();
|
|
267
279
|
for (const file of result.outputFiles) {
|
|
268
280
|
if (file.path.startsWith(VirtualOutDir)) {
|
|
@@ -275,9 +287,9 @@ export function StoragePlugin(task) {
|
|
|
275
287
|
}
|
|
276
288
|
}
|
|
277
289
|
task.target.store();
|
|
278
|
-
const storeTime = (
|
|
279
|
-
const buildTime = (
|
|
280
|
-
task.log.info(`Build
|
|
290
|
+
const storeTime = (Date.now() - storeStart) / 1000;
|
|
291
|
+
const buildTime = (Date.now() - buildStartTime) / 1000;
|
|
292
|
+
task.log.info(`Build ES modules in ${result.outputFiles.length} file(s) (compile: ${buildTime.toFixed(2)}s, store: ${storeTime.toFixed(2)}s)`);
|
|
281
293
|
}
|
|
282
294
|
return null;
|
|
283
295
|
});
|
|
@@ -389,7 +401,7 @@ export function DependencyDeduplicationPlugin(libraries, rootNodeModules, log) {
|
|
|
389
401
|
const is = isSingletonPackage(result.path, pkg);
|
|
390
402
|
singletonCache.set(pkg, is);
|
|
391
403
|
if (is)
|
|
392
|
-
log.
|
|
404
|
+
log.debug(`[dedup] singleton: ${pkg}`);
|
|
393
405
|
}
|
|
394
406
|
// Singleton → force root resolution
|
|
395
407
|
if (singletonCache.get(pkg)) {
|
|
@@ -411,7 +423,65 @@ export function DependencyDeduplicationPlugin(libraries, rootNodeModules, log) {
|
|
|
411
423
|
}
|
|
412
424
|
};
|
|
413
425
|
}
|
|
414
|
-
|
|
426
|
+
/**
|
|
427
|
+
* Parses tsconfig.json compilerOptions (paths + baseUrl) and exposes resolved alias patterns.
|
|
428
|
+
* Looks for tsconfig.json in libraryPath first, then workspacePath as fallback.
|
|
429
|
+
*/
|
|
430
|
+
export class TSConfig {
|
|
431
|
+
baseUrl = null;
|
|
432
|
+
patterns = [];
|
|
433
|
+
configFile = null;
|
|
434
|
+
configData = null;
|
|
435
|
+
constructor(libraryPath, workspacePath) {
|
|
436
|
+
const tsconfigFile = [libraryPath, workspacePath]
|
|
437
|
+
.filter(Boolean)
|
|
438
|
+
.map(dir => Path.join(dir, 'tsconfig.json'))
|
|
439
|
+
.find(f => Fs.existsSync(f));
|
|
440
|
+
if (!tsconfigFile)
|
|
441
|
+
return;
|
|
442
|
+
try {
|
|
443
|
+
const raw = Fs.readFileSync(tsconfigFile, 'utf-8');
|
|
444
|
+
const cleaned = raw.replace(/^\s*\/\/.*$/gm, '').replace(/,\s*([}\]])/g, '$1');
|
|
445
|
+
const tsconfig = JSON.parse(cleaned);
|
|
446
|
+
const opts = tsconfig.compilerOptions;
|
|
447
|
+
if (!opts?.paths)
|
|
448
|
+
return;
|
|
449
|
+
this.configData = tsconfig;
|
|
450
|
+
this.configFile = tsconfigFile;
|
|
451
|
+
this.baseUrl = Path.resolve(Path.dirname(tsconfigFile), opts.baseUrl || '.');
|
|
452
|
+
for (const [alias, targets] of Object.entries(opts.paths)) {
|
|
453
|
+
for (const target of targets) {
|
|
454
|
+
const prefix = alias === '*' ? '' : alias.endsWith('/*') ? alias.slice(0, -2) : alias;
|
|
455
|
+
const targetPath = target.endsWith('/*') ? target.slice(0, -2) : target;
|
|
456
|
+
this.patterns.push([prefix, Path.resolve(this.baseUrl, targetPath)]);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
catch { }
|
|
461
|
+
}
|
|
462
|
+
get hasAliases() {
|
|
463
|
+
return this.patterns.length > 0;
|
|
464
|
+
}
|
|
465
|
+
/** Resolve an import path against tsconfig path aliases. Returns the resolved file path or null. */
|
|
466
|
+
resolve(importPath, resolveFilePath) {
|
|
467
|
+
for (const [prefix, dir] of this.patterns) {
|
|
468
|
+
if (prefix === '') {
|
|
469
|
+
// Wildcard "*" pattern: try resolving the full import path under the target dir
|
|
470
|
+
const resolved = resolveFilePath('./' + importPath, dir);
|
|
471
|
+
if (resolved)
|
|
472
|
+
return resolved;
|
|
473
|
+
}
|
|
474
|
+
else if (importPath === prefix || importPath.startsWith(prefix + '/')) {
|
|
475
|
+
const rest = importPath.slice(prefix.length);
|
|
476
|
+
const resolved = resolveFilePath('.' + rest, dir);
|
|
477
|
+
if (resolved)
|
|
478
|
+
return resolved;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
export function ESModuleResolverPlugin(opts, tsconfigPaths) {
|
|
415
485
|
const internalLoaders = {
|
|
416
486
|
".ts": "ts", ".tsx": "tsx", ".js": "js", ".jsx": "jsx",
|
|
417
487
|
".json": "json", ".txt": "text", ".md": "text", ".css": "css",
|
|
@@ -481,6 +551,13 @@ export function ESModuleResolverPlugin(opts) {
|
|
|
481
551
|
return { path: resolved, namespace: "file" };
|
|
482
552
|
}
|
|
483
553
|
}
|
|
554
|
+
// 4. Resolve tsconfig path aliases (e.g. @app/* -> ./src/*)
|
|
555
|
+
if (tsconfigPaths?.hasAliases) {
|
|
556
|
+
const resolved = tsconfigPaths.resolve(args.path, resolveFilePath);
|
|
557
|
+
if (resolved) {
|
|
558
|
+
return { path: resolved, namespace: "file" };
|
|
559
|
+
}
|
|
560
|
+
}
|
|
484
561
|
});
|
|
485
562
|
// Loader for internal modules
|
|
486
563
|
build.onLoad({ filter: /.*/, namespace: 'internal' }, (args) => {
|
package/esm/commands/init.js
CHANGED
|
@@ -36,6 +36,19 @@ export function command_init() {
|
|
|
36
36
|
],
|
|
37
37
|
"url": "./node_modules/@jointhedots/gear/schemas/component.schema.json"
|
|
38
38
|
},
|
|
39
|
+
{
|
|
40
|
+
"fileMatch": [
|
|
41
|
+
"declaration.json",
|
|
42
|
+
"*.declaration.json",
|
|
43
|
+
"declaration.yaml",
|
|
44
|
+
"*.declaration.yaml",
|
|
45
|
+
"declaration.yml",
|
|
46
|
+
"*.declaration.yml",
|
|
47
|
+
"declaration.toml",
|
|
48
|
+
"*.declaration.toml",
|
|
49
|
+
],
|
|
50
|
+
"url": "./node_modules/@jointhedots/gear/schemas/declaration.schema.json"
|
|
51
|
+
},
|
|
39
52
|
]
|
|
40
53
|
});
|
|
41
54
|
}
|
package/esm/commands/make.js
CHANGED
|
@@ -61,7 +61,11 @@ export function command_make() {
|
|
|
61
61
|
default: "./dist",
|
|
62
62
|
}),
|
|
63
63
|
handler: async (argv) => {
|
|
64
|
-
const ws = await open_workspace(
|
|
64
|
+
const ws = await open_workspace({
|
|
65
|
+
workspace_path: argv.ws,
|
|
66
|
+
devmode: argv.devmode,
|
|
67
|
+
ignored_directory: Path.resolve(argv.dist),
|
|
68
|
+
});
|
|
65
69
|
if (argv.devmode)
|
|
66
70
|
ws.log.warn("Use devmode");
|
|
67
71
|
let version = argv.versioned;
|
package/esm/commands/publish.js
CHANGED
|
@@ -25,7 +25,10 @@ export function command_publish() {
|
|
|
25
25
|
}),
|
|
26
26
|
handler: async (argv) => {
|
|
27
27
|
const outputDir = Path.resolve(argv.dist);
|
|
28
|
-
const ws = await open_workspace(
|
|
28
|
+
const ws = await open_workspace({
|
|
29
|
+
workspace_path: ".",
|
|
30
|
+
devmode: false,
|
|
31
|
+
});
|
|
29
32
|
await publish_aws_s3(argv.app, ws, argv.bucket, argv.region, outputDir);
|
|
30
33
|
}
|
|
31
34
|
};
|
package/esm/commands/serve.js
CHANGED
|
@@ -38,10 +38,13 @@ export function command_serve() {
|
|
|
38
38
|
default: "./dist",
|
|
39
39
|
}),
|
|
40
40
|
handler: async (argv) => {
|
|
41
|
-
const ws = await open_workspace(
|
|
41
|
+
const ws = await open_workspace({
|
|
42
|
+
workspace_path: argv.ws,
|
|
43
|
+
devmode: argv.devmode,
|
|
44
|
+
});
|
|
42
45
|
const app = ws.get_application(argv.app);
|
|
43
46
|
if (!app)
|
|
44
|
-
throw new Error(`Application '${argv.app}' not exists
|
|
47
|
+
throw new Error(`Application '${argv.app}' not exists.`);
|
|
45
48
|
if (argv.devmode)
|
|
46
49
|
ws.log.warn("Use devmode");
|
|
47
50
|
let version = argv.versioned;
|
|
@@ -1,4 +1,19 @@
|
|
|
1
|
+
import Path from "node:path";
|
|
1
2
|
import { makeComponentPublication } from "../component.js";
|
|
3
|
+
function add_export_entry(exports, lib, key, value, baseDir) {
|
|
4
|
+
const basename = key.startsWith("./") ? key.slice(2) : key;
|
|
5
|
+
const filename = lib.make_file_id("export", basename);
|
|
6
|
+
const source_ref = typeof value === "string" ? value : value?.import ?? value?.default ?? value?.require;
|
|
7
|
+
const entry = source_ref ? lib.resolve_entry_path(source_ref, baseDir) : null;
|
|
8
|
+
const id = `${lib.name}${basename === "." ? "" : "/" + basename}`;
|
|
9
|
+
exports[id] = {
|
|
10
|
+
id,
|
|
11
|
+
exported: key,
|
|
12
|
+
basename: filename,
|
|
13
|
+
filename: `${filename}.js`,
|
|
14
|
+
source: entry,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
2
17
|
function create_export_map(lib, bun) {
|
|
3
18
|
const exports = {};
|
|
4
19
|
if (bun) {
|
|
@@ -13,19 +28,18 @@ function create_export_map(lib, bun) {
|
|
|
13
28
|
};
|
|
14
29
|
}
|
|
15
30
|
}
|
|
16
|
-
for (const key in lib.descriptor.exports) {
|
|
31
|
+
for (const key in (lib.descriptor.exports || {})) {
|
|
17
32
|
const exp = lib.descriptor.exports[key];
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
};
|
|
33
|
+
add_export_entry(exports, lib, key, exp, lib.path);
|
|
34
|
+
}
|
|
35
|
+
for (const [decl_path, declaration] of lib.declarations) {
|
|
36
|
+
if (!declaration.exports)
|
|
37
|
+
continue;
|
|
38
|
+
const decl_base_dir = Path.dirname(decl_path);
|
|
39
|
+
for (const key in declaration.exports) {
|
|
40
|
+
const exp = declaration.exports[key];
|
|
41
|
+
add_export_entry(exports, lib, key, exp, decl_base_dir);
|
|
42
|
+
}
|
|
29
43
|
}
|
|
30
44
|
return exports;
|
|
31
45
|
}
|
|
@@ -8,6 +8,15 @@ import { Bundle, Library, Workspace } from "../workspace.js";
|
|
|
8
8
|
import { make_canonical_path, make_normalized_dirname, make_normalized_path, make_relative_path } from "../../utils/file.js";
|
|
9
9
|
import { is_config_filename, readConfigFile, readSingletonConfigFile } from "./config-loader.js";
|
|
10
10
|
const exclude_dirs = ["node_modules"];
|
|
11
|
+
function is_ignored_dir(ws, path) {
|
|
12
|
+
const normalized_path = make_normalized_path(path);
|
|
13
|
+
for (const ignored of ws.ignored_directories) {
|
|
14
|
+
if (normalized_path === ignored || normalized_path.startsWith(ignored + "/")) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
11
20
|
function setup_library_bundle(lib, bundle_desc) {
|
|
12
21
|
const manif = make_library_bundle_manifest(lib, bundle_desc);
|
|
13
22
|
const ws = lib.workspace;
|
|
@@ -165,19 +174,23 @@ function make_library_bundle_manifest(lib, file_desc) {
|
|
|
165
174
|
};
|
|
166
175
|
return manifest;
|
|
167
176
|
}
|
|
168
|
-
async function discover_library(ws, location) {
|
|
177
|
+
async function discover_library(ws, location, installed) {
|
|
169
178
|
const lib_path = make_canonical_path(ws.path, location);
|
|
179
|
+
if (is_ignored_dir(ws, lib_path))
|
|
180
|
+
return false;
|
|
170
181
|
const lib_not_exists = ws.libraries.reduce((r, lib) => r && lib.path !== lib_path, true);
|
|
171
182
|
if (lib_not_exists) {
|
|
172
183
|
const lib_desc = await readJsonFile(lib_path + "/package.json");
|
|
184
|
+
if (!lib_desc?.name)
|
|
185
|
+
return false;
|
|
173
186
|
const bundle_result = await readSingletonConfigFile(lib_path, "bundle.component");
|
|
174
187
|
const bundle_desc = bundle_result?.data;
|
|
175
|
-
if (bundle_desc ||
|
|
188
|
+
if (bundle_desc || !installed) {
|
|
176
189
|
const other = ws.get_library(lib_desc.name);
|
|
177
190
|
if (other) {
|
|
178
191
|
if (lib_path.includes(other.path)) {
|
|
179
192
|
ws.log.info(`ignore library build at ${lib_path}`);
|
|
180
|
-
return;
|
|
193
|
+
return false;
|
|
181
194
|
}
|
|
182
195
|
else {
|
|
183
196
|
throw new Error(`library '${lib_desc.name}' declared multiple times\n - ${other.path}\n - ${lib_path}`);
|
|
@@ -185,6 +198,7 @@ async function discover_library(ws, location) {
|
|
|
185
198
|
}
|
|
186
199
|
const lib = new Library(lib_desc.name, lib_path, lib_desc, ws);
|
|
187
200
|
ws.libraries.push(lib);
|
|
201
|
+
ws.log.info(`+ 📚 library: ${lib.get_id()} (${make_relative_path(ws.path, location)})`);
|
|
188
202
|
if (bundle_desc) {
|
|
189
203
|
setup_library_bundle(lib, bundle_desc);
|
|
190
204
|
}
|
|
@@ -193,12 +207,14 @@ async function discover_library(ws, location) {
|
|
|
193
207
|
lib.search_directories.push(lib_search_path);
|
|
194
208
|
}
|
|
195
209
|
await discover_library_components(lib, lib_path);
|
|
210
|
+
return true;
|
|
196
211
|
}
|
|
197
212
|
}
|
|
213
|
+
return false;
|
|
198
214
|
}
|
|
199
215
|
async function discover_workspace_libraries(ws) {
|
|
200
216
|
async function walk(dir) {
|
|
201
|
-
await discover_library(ws, dir);
|
|
217
|
+
await discover_library(ws, dir, false);
|
|
202
218
|
for (const entry of Fs.readdirSync(dir, { withFileTypes: true })) {
|
|
203
219
|
if (entry.name === "node_modules")
|
|
204
220
|
continue;
|
|
@@ -245,7 +261,7 @@ export async function discover_workspace(ws) {
|
|
|
245
261
|
}
|
|
246
262
|
await discover_workspace_libraries(ws);
|
|
247
263
|
for (const location in package_lock.packages) {
|
|
248
|
-
await discover_library(ws, location);
|
|
264
|
+
await discover_library(ws, location, true);
|
|
249
265
|
}
|
|
250
266
|
for (const bun of ws.bundles) {
|
|
251
267
|
if (bun.source) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Process from "node:process";
|
|
1
2
|
export class Log {
|
|
2
3
|
id;
|
|
3
4
|
entries = [];
|
|
@@ -41,7 +42,12 @@ export class Log {
|
|
|
41
42
|
}
|
|
42
43
|
export class Logger {
|
|
43
44
|
loggers = new Map();
|
|
44
|
-
|
|
45
|
+
mode;
|
|
46
|
+
silentKinds;
|
|
47
|
+
constructor(mode = getLogModeFromEnv()) {
|
|
48
|
+
this.mode = mode;
|
|
49
|
+
this.silentKinds = getSilentKinds(mode);
|
|
50
|
+
}
|
|
45
51
|
get(id) {
|
|
46
52
|
let logger = this.loggers.get(id);
|
|
47
53
|
if (!logger) {
|
|
@@ -63,6 +69,24 @@ export class Logger {
|
|
|
63
69
|
this.loggers.clear();
|
|
64
70
|
}
|
|
65
71
|
}
|
|
72
|
+
function getLogModeFromEnv() {
|
|
73
|
+
const value = Process.env.JTDGEAR_LOG_MODE?.trim().toLowerCase();
|
|
74
|
+
if (value === "debug" || value === "verbose" || value === "normal") {
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
return "normal";
|
|
78
|
+
}
|
|
79
|
+
function getSilentKinds(mode) {
|
|
80
|
+
switch (mode) {
|
|
81
|
+
case "verbose":
|
|
82
|
+
return new Set();
|
|
83
|
+
case "debug":
|
|
84
|
+
return new Set(["trace"]);
|
|
85
|
+
case "normal":
|
|
86
|
+
default:
|
|
87
|
+
return new Set(["trace", "debug"]);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
66
90
|
export function stringifyLocation(loc) {
|
|
67
91
|
if (!loc)
|
|
68
92
|
return "";
|
package/esm/model/workspace.js
CHANGED
|
@@ -109,6 +109,7 @@ export class Workspace {
|
|
|
109
109
|
libraries = [];
|
|
110
110
|
constants = {};
|
|
111
111
|
search_directories = [];
|
|
112
|
+
ignored_directories = new Set();
|
|
112
113
|
logger = new Logger();
|
|
113
114
|
log;
|
|
114
115
|
constructor(name, version, path, devmode) {
|
|
@@ -152,28 +153,32 @@ export class Workspace {
|
|
|
152
153
|
return null;
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
|
-
export async function open_workspace(
|
|
156
|
-
workspace_path = Path.resolve(workspace_path);
|
|
156
|
+
export async function open_workspace(options) {
|
|
157
|
+
const workspace_path = Path.resolve(options.workspace_path);
|
|
158
|
+
const { devmode } = options;
|
|
159
|
+
const parsed_env = load_env_from_cwd_parents();
|
|
157
160
|
const package_json = await readJsonFile(workspace_path + "/package.json");
|
|
158
161
|
if (!package_json)
|
|
159
162
|
throw new Error(`No 'package.json' found at workspace path: ${workspace_path}`);
|
|
160
163
|
const ws = new Workspace(package_json.name, package_json.version, workspace_path, devmode);
|
|
161
|
-
|
|
164
|
+
if (options.ignored_directory) {
|
|
165
|
+
ws.ignored_directories.add(Path.resolve(options.ignored_directory).replace(/\\/g, "/"));
|
|
166
|
+
}
|
|
167
|
+
ws.constants = patch_constants_from_env(package_json.constants || {}, devmode, parsed_env);
|
|
162
168
|
await discover_workspace(ws);
|
|
163
169
|
return ws;
|
|
164
170
|
}
|
|
165
|
-
function patch_constants_from_env(constants, devmode) {
|
|
166
|
-
const env = DotEnv.config();
|
|
171
|
+
function patch_constants_from_env(constants, devmode, parsedEnv) {
|
|
167
172
|
for (const key in constants) {
|
|
168
173
|
if (devmode) {
|
|
169
|
-
const dvalue =
|
|
174
|
+
const dvalue = parsedEnv["DCONST_" + key];
|
|
170
175
|
if (dvalue !== undefined) {
|
|
171
176
|
constants[key] = dvalue;
|
|
172
177
|
continue;
|
|
173
178
|
}
|
|
174
179
|
}
|
|
175
180
|
{
|
|
176
|
-
const value =
|
|
181
|
+
const value = parsedEnv["CONST_" + key];
|
|
177
182
|
if (value !== undefined) {
|
|
178
183
|
constants[key] = value;
|
|
179
184
|
continue;
|
|
@@ -182,6 +187,21 @@ function patch_constants_from_env(constants, devmode) {
|
|
|
182
187
|
}
|
|
183
188
|
return constants;
|
|
184
189
|
}
|
|
190
|
+
function load_env_from_cwd_parents() {
|
|
191
|
+
let currentPath = Process.cwd();
|
|
192
|
+
while (true) {
|
|
193
|
+
const envPath = Path.join(currentPath, ".env");
|
|
194
|
+
if (Fs.existsSync(envPath)) {
|
|
195
|
+
const env = DotEnv.config({ path: envPath });
|
|
196
|
+
return env.parsed || {};
|
|
197
|
+
}
|
|
198
|
+
const parentPath = Path.dirname(currentPath);
|
|
199
|
+
if (parentPath === currentPath)
|
|
200
|
+
break;
|
|
201
|
+
currentPath = parentPath;
|
|
202
|
+
}
|
|
203
|
+
return {};
|
|
204
|
+
}
|
|
185
205
|
export function matchComponentSelection(components, selectors) {
|
|
186
206
|
if (components?.selectors) {
|
|
187
207
|
if (!selectors)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jointhedots/gear",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"jointhedots-gear": "esm/cli.js"
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"files": [
|
|
9
9
|
"esm",
|
|
10
10
|
"browser-modules",
|
|
11
|
-
"schemas"
|
|
11
|
+
"schemas",
|
|
12
|
+
"!**/*.map"
|
|
12
13
|
],
|
|
13
14
|
"scripts": {
|
|
14
15
|
"watch": "tsc -w",
|
|
@@ -22,7 +23,7 @@
|
|
|
22
23
|
"serve:mono": "node --enable-source-maps --watch-path=esm esm/cli serve --app playground:ui --devmode --port 3002 --ws ../jointhedots-core",
|
|
23
24
|
"serve:host": "node --enable-source-maps --watch-path=esm esm/cli serve --app playground:ui:host --port 3002 --ws ../jointhedots-core",
|
|
24
25
|
"serve:sfe": "node --enable-source-maps --watch-path=esm esm/cli serve --app sfe-demo --devmode --ws ../sf-explorer-app",
|
|
25
|
-
"make:sfe": "node --enable-source-maps --watch-path=esm esm/cli make --
|
|
26
|
+
"make:sfe": "node --enable-source-maps --watch-path=esm esm/cli make --libs @sf-explorer/app --devmode --ws ../sf-explorer-app",
|
|
26
27
|
"prepublishOnly": "node scripts/prepublish.mjs"
|
|
27
28
|
},
|
|
28
29
|
"dependencies": {
|