@zenbujs/core 0.0.3 → 0.0.5
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/dist/{advice-config-CjgkEf2E.mjs → advice-config-QYB2qEd_.mjs} +32 -14
- package/dist/advice.mjs +1 -1
- package/dist/{base-window-BUt8pwbw.mjs → base-window-BbFRRhKP.mjs} +9 -4
- package/dist/{build-config-pbv0w4oN.mjs → build-config-C3a-o3_B.mjs} +8 -2
- package/dist/{build-electron-BzHa_hRi.mjs → build-electron-CNJ0dLND.mjs} +12 -6
- package/dist/{build-source-CnTfQBGK.mjs → build-source-C2puqEVr.mjs} +13 -8
- package/dist/chunk-DsiFFCwN.mjs +16 -0
- package/dist/cli/bin.mjs +12 -15
- package/dist/cli/build.d.mts +1 -52
- package/dist/cli/build.mjs +2 -47
- package/dist/cli/resolve-config.mjs +37 -0
- package/dist/{cli-BLbQQIVB.mjs → cli-C3R1LBMY.mjs} +5 -5
- package/dist/{config-CdVrW85P.mjs → config-DXRCDUxG.mjs} +1 -1
- package/dist/config.d.mts +3 -0
- package/dist/config.mjs +4 -0
- package/dist/{db-BXadETOb.mjs → db-xjvahRFJ.mjs} +47 -41
- package/dist/db.d.mts +1 -1
- package/dist/db.mjs +2 -2
- package/dist/env-bootstrap.d.mts +1 -1
- package/dist/env-bootstrap.mjs +52 -1
- package/dist/index-ClXLQ1fw.d.mts +1 -0
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +4 -4
- package/dist/{link-VOoGs-pY.mjs → link-c0_aLWQ3.mjs} +87 -120
- package/dist/load-config-xMf2wxH8.mjs +141 -0
- package/dist/loaders/zenbu.d.mts +17 -0
- package/dist/loaders/zenbu.mjs +144 -135
- package/dist/{monorepo-CQeQBIpa.mjs → monorepo-3avKJwzJ.mjs} +5 -2
- package/dist/node-loader.mjs +1 -1
- package/dist/{publish-source-BJdpDAFH.mjs → publish-source-Dill72NS.mjs} +12 -6
- package/dist/react.d.mts +3 -3
- package/dist/react.mjs +2 -2
- package/dist/{registry-Dh_e7HU1.d.mts → registry-eX6e2oql.d.mts} +1 -1
- package/dist/registry.d.mts +1 -1
- package/dist/{reloader-lLAJ3lqg.mjs → reloader-DzEO8kJr.mjs} +6 -4
- package/dist/{renderer-host-Bg8QdeeH.mjs → renderer-host-Cau9JK0v.mjs} +90 -212
- package/dist/{rpc-BwwQK6hD.mjs → rpc-JfGv-Wuw.mjs} +7 -5
- package/dist/rpc.d.mts +1 -1
- package/dist/rpc.mjs +1 -1
- package/dist/{runtime-CjqDr8Yf.d.mts → runtime-pCeVzj--.d.mts} +73 -1
- package/dist/runtime.d.mts +2 -2
- package/dist/runtime.mjs +522 -2
- package/dist/{schema-DMoSkwUx.d.mts → schema-Dl85YjXW.d.mts} +1 -1
- package/dist/schema.d.mts +1 -1
- package/dist/schema.mjs +27 -1
- package/dist/{server-BXwZEQ-n.mjs → server-y3PPbh3l.mjs} +5 -3
- package/dist/services/default.mjs +10 -10
- package/dist/services/index.d.mts +8 -4
- package/dist/services/index.mjs +6 -6
- package/dist/setup-gate.d.mts +1 -1
- package/dist/setup-gate.mjs +248 -1
- package/dist/{transform-DJH3vN4b.mjs → transform-CmFYPmt8.mjs} +1 -1
- package/dist/transforms-CuTODvDx.d.mts +145 -0
- package/dist/transforms-htxfTwsY.mjs +47 -0
- package/dist/{transport-BMSzG2-F.mjs → transport-F2hv_OEm.mjs} +1 -1
- package/dist/{vite-plugins-Bh3SCOw-.mjs → vite-plugins-Do7liKi_.mjs} +5 -19
- package/dist/vite.mjs +1 -1
- package/dist/{window-CmmpCVX6.mjs → window-o2NGUsIb.mjs} +10 -7
- package/dist/{write-9dRFczGJ.mjs → write-DgIRjo23.mjs} +1 -1
- package/package.json +11 -10
- package/dist/advice-config-Cy133IQP.mjs +0 -2
- package/dist/base-window-DEIAk618.mjs +0 -2
- package/dist/chunk-Dm34NbLt.mjs +0 -6
- package/dist/config-LK73dJmO.mjs +0 -2
- package/dist/db-ByKPbnP6.mjs +0 -2
- package/dist/env-bootstrap-rj7I-59x.mjs +0 -53
- package/dist/http-IBcLzbYu.mjs +0 -2
- package/dist/load-build-config-DozuRhAN.mjs +0 -40
- package/dist/reloader-BCkLjDhS.mjs +0 -2
- package/dist/renderer-host-DpvBPTHJ.mjs +0 -2
- package/dist/rpc-CqitnyR4.mjs +0 -2
- package/dist/runtime-DUFKDIe4.mjs +0 -409
- package/dist/schema-dGK6qkfR.mjs +0 -28
- package/dist/server-DjrZUbbu.mjs +0 -2
- package/dist/setup-gate-BcoqWu8S.mjs +0 -110
- package/dist/view-registry-BualWgAf.mjs +0 -2
- package/dist/window-CM2a9Kyc.mjs +0 -2
- package/dist/{index-FtE8MXJ_.d.mts → cli/resolve-config.d.mts} +0 -0
- package/dist/{dev-BU_llQh1.mjs → dev-Dazhu66l.mjs} +0 -0
- package/dist/{env-bootstrap-BtVME-CU.d.mts → env-bootstrap-DW2hVhSO.d.mts} +0 -0
- package/dist/{index-Bhlbyrn7.d.mts → index-C-ALz_SH.d.mts} +0 -0
- package/dist/{index-CPZ5d6Hl.d.mts → index-M_lSNBrq.d.mts} +0 -0
- package/dist/{log-CyKv8hQg.mjs → log-6rzaCV0I.mjs} +0 -0
- package/dist/{mirror-sync-BN59kMCG.mjs → mirror-sync-PDzxhf1w.mjs} +1 -1
- /package/dist/{node-D4M19_mV.mjs → node-_8xShqxr.mjs} +0 -0
- /package/dist/{schema-CIg4GzHQ.mjs → schema-Ca7SxXgS.mjs} +0 -0
- /package/dist/{setup-gate-BqOzm7zp.d.mts → setup-gate-Dcy8gGPJ.d.mts} +0 -0
- /package/dist/{src-pELM4_iH.mjs → src-Cven45mq.mjs} +0 -0
- /package/dist/{trace-DCB7qFzT.mjs → trace-BaVg0rnY.mjs} +0 -0
package/dist/db.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as createSchema, n as blob, r as collection } from "./schema-
|
|
2
|
-
import { i as dbStringify, r as dbParse, t as connectReplica } from "./transport-
|
|
1
|
+
import { i as createSchema, n as blob, r as collection } from "./schema-Ca7SxXgS.mjs";
|
|
2
|
+
import { i as dbStringify, r as dbParse, t as connectReplica } from "./transport-F2hv_OEm.mjs";
|
|
3
3
|
import { z as z$1 } from "zod";
|
|
4
4
|
//#region src/db.ts
|
|
5
5
|
/**
|
package/dist/env-bootstrap.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as bootstrapEnv } from "./env-bootstrap-
|
|
1
|
+
import { t as bootstrapEnv } from "./env-bootstrap-DW2hVhSO.mjs";
|
|
2
2
|
export { bootstrapEnv };
|
package/dist/env-bootstrap.mjs
CHANGED
|
@@ -1,2 +1,53 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
//#region src/env-bootstrap.ts
|
|
5
|
+
const internalDir = path.join(os.homedir(), ".zenbu", ".internal");
|
|
6
|
+
const pathsJson = path.join(internalDir, "paths.json");
|
|
7
|
+
function userCacheRoot() {
|
|
8
|
+
if (process.platform === "darwin") return path.join(os.homedir(), "Library", "Caches");
|
|
9
|
+
if (process.platform === "win32") return process.env.LOCALAPPDATA ?? path.join(os.homedir(), "AppData", "Local");
|
|
10
|
+
return process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), ".cache");
|
|
11
|
+
}
|
|
12
|
+
function computePaths() {
|
|
13
|
+
const cacheRoot = path.join(userCacheRoot(), "Zenbu");
|
|
14
|
+
const binDir = path.join(cacheRoot, "bin");
|
|
15
|
+
return {
|
|
16
|
+
cacheRoot,
|
|
17
|
+
binDir,
|
|
18
|
+
bunInstall: path.join(cacheRoot, "bun"),
|
|
19
|
+
bunPath: path.join(binDir, "bun"),
|
|
20
|
+
pnpmHome: path.join(cacheRoot, "pnpm"),
|
|
21
|
+
pnpmPath: path.join(binDir, "pnpm"),
|
|
22
|
+
gitPath: path.join(binDir, "git"),
|
|
23
|
+
writtenAt: Date.now()
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function bootstrapEnv() {
|
|
27
|
+
const paths = computePaths();
|
|
28
|
+
try {
|
|
29
|
+
fs.mkdirSync(paths.binDir, { recursive: true });
|
|
30
|
+
} catch {}
|
|
31
|
+
const toolchainReady = fs.existsSync(paths.bunPath) && fs.existsSync(paths.pnpmPath);
|
|
32
|
+
if (toolchainReady) {
|
|
33
|
+
process.env.BUN_INSTALL ??= paths.bunInstall;
|
|
34
|
+
process.env.PNPM_HOME ??= paths.pnpmHome;
|
|
35
|
+
}
|
|
36
|
+
const pathParts = toolchainReady ? [paths.binDir, process.env.PATH ?? ""] : [process.env.PATH ?? ""];
|
|
37
|
+
const seen = /* @__PURE__ */ new Set();
|
|
38
|
+
process.env.PATH = pathParts.flatMap((part) => part.split(path.delimiter)).filter((part) => {
|
|
39
|
+
if (!part || seen.has(part)) return false;
|
|
40
|
+
seen.add(part);
|
|
41
|
+
return true;
|
|
42
|
+
}).join(path.delimiter);
|
|
43
|
+
try {
|
|
44
|
+
fs.mkdirSync(internalDir, { recursive: true });
|
|
45
|
+
fs.writeFileSync(pathsJson, JSON.stringify(paths, null, 2));
|
|
46
|
+
} catch {}
|
|
47
|
+
return {
|
|
48
|
+
paths,
|
|
49
|
+
needsToolchainDownload: !toolchainReady
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
2
53
|
export { bootstrapEnv };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import { t as
|
|
3
|
-
import {
|
|
4
|
-
import { n as SchemaRoot, o as schema, t as CoreSchema } from "./schema-
|
|
5
|
-
import { i as CoreServiceRouter, n as CoreEvents, r as CorePreloads, t as CoreDbSections } from "./registry-
|
|
1
|
+
import { a as ServiceRuntime, d as optional, g as serviceWithDeps, h as runtime, i as Service, t as CleanupReason } from "./runtime-pCeVzj--.mjs";
|
|
2
|
+
import { t as bootstrapEnv } from "./env-bootstrap-DW2hVhSO.mjs";
|
|
3
|
+
import { t as setupGate } from "./setup-gate-Dcy8gGPJ.mjs";
|
|
4
|
+
import { n as SchemaRoot, o as schema, t as CoreSchema } from "./schema-Dl85YjXW.mjs";
|
|
5
|
+
import { i as CoreServiceRouter, n as CoreEvents, r as CorePreloads, t as CoreDbSections } from "./registry-eX6e2oql.mjs";
|
|
6
6
|
export { CleanupReason, CoreDbSections, CoreEvents, CorePreloads, CoreSchema, SchemaRoot as CoreSchemaRoot, CoreServiceRouter, Service, ServiceRuntime, bootstrapEnv, schema as coreSchema, optional, runtime, serviceWithDeps, setupGate };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { bootstrapEnv } from "./env-bootstrap.mjs";
|
|
2
|
+
import { setupGate } from "./setup-gate.mjs";
|
|
3
|
+
import { Service, ServiceRuntime, optional, runtime, serviceWithDeps } from "./runtime.mjs";
|
|
4
|
+
import { schema } from "./schema.mjs";
|
|
5
5
|
export { Service, ServiceRuntime, bootstrapEnv, schema as coreSchema, optional, runtime, serviceWithDeps, setupGate };
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
+
import { t as loadConfig } from "./load-config-xMf2wxH8.mjs";
|
|
1
2
|
import fs from "node:fs";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
//#region src/cli/commands/link.ts
|
|
4
|
-
|
|
5
|
+
const CONFIG_NAMES = [
|
|
6
|
+
"zenbu.config.ts",
|
|
7
|
+
"zenbu.config.mts",
|
|
8
|
+
"zenbu.config.js",
|
|
9
|
+
"zenbu.config.mjs"
|
|
10
|
+
];
|
|
11
|
+
function findProjectDir(from) {
|
|
5
12
|
let dir = path.resolve(from);
|
|
6
13
|
while (true) {
|
|
7
|
-
const
|
|
8
|
-
if (fs.existsSync(candidate)) return candidate;
|
|
14
|
+
for (const name of CONFIG_NAMES) if (fs.existsSync(path.join(dir, name))) return dir;
|
|
9
15
|
const parent = path.dirname(dir);
|
|
10
16
|
if (parent === dir) return null;
|
|
11
17
|
dir = parent;
|
|
@@ -44,23 +50,12 @@ function readRegistryDirFromTsconfig(tsconfigPath) {
|
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
/**
|
|
47
|
-
* An app root is the nearest ancestor (or self) that contains
|
|
48
|
-
* `zenbu.
|
|
49
|
-
*
|
|
53
|
+
* An app root is the nearest ancestor (or self) that contains a
|
|
54
|
+
* `zenbu.config.ts` (or its .mts/.js/.mjs variants). That single file
|
|
55
|
+
* uniquely identifies a Zenbu project root.
|
|
50
56
|
*/
|
|
51
57
|
function findAppRoot(from) {
|
|
52
|
-
|
|
53
|
-
while (true) {
|
|
54
|
-
const manifest = path.join(dir, "zenbu.plugin.json");
|
|
55
|
-
const config = path.join(dir, "config.json");
|
|
56
|
-
if (fs.existsSync(manifest) && fs.existsSync(config)) try {
|
|
57
|
-
const parsed = JSON.parse(fs.readFileSync(config, "utf8"));
|
|
58
|
-
if (Array.isArray(parsed?.plugins)) return dir;
|
|
59
|
-
} catch {}
|
|
60
|
-
const parent = path.dirname(dir);
|
|
61
|
-
if (parent === dir) return null;
|
|
62
|
-
dir = parent;
|
|
63
|
-
}
|
|
58
|
+
return findProjectDir(from);
|
|
64
59
|
}
|
|
65
60
|
/**
|
|
66
61
|
* Pick the directory `zen link` should write registry types into.
|
|
@@ -86,10 +81,10 @@ function resolveRegistryDir(opts) {
|
|
|
86
81
|
if (appRoot) return path.join(appRoot, "types");
|
|
87
82
|
console.error(`zen link: could not determine target types directory for ${opts.manifestPath}.`);
|
|
88
83
|
console.error(` Try one of:`);
|
|
89
|
-
console.error(`
|
|
90
|
-
console.error(`
|
|
91
|
-
console.error(`
|
|
92
|
-
console.error(`
|
|
84
|
+
console.error(` - run from inside an app dir (with a zenbu.config.ts),`);
|
|
85
|
+
console.error(` - add a "devAppPath" field to ${path.basename(opts.manifestPath)} pointing at the host app,`);
|
|
86
|
+
console.error(` - create a tsconfig.local.json with a "#registry/*" path mapping,`);
|
|
87
|
+
console.error(` - or pass --registry <dir>.`);
|
|
93
88
|
process.exit(1);
|
|
94
89
|
}
|
|
95
90
|
function expandGlob(baseDir, pattern) {
|
|
@@ -307,7 +302,6 @@ function readExistingRegistry(registryDir) {
|
|
|
307
302
|
if (fs.existsSync(servicesPath)) {
|
|
308
303
|
const content = fs.readFileSync(servicesPath, "utf8");
|
|
309
304
|
const importRe = /import type \{ (\w+)(?:\s+as\s+(\w+))? \} from "([^"]+)"/g;
|
|
310
|
-
const routerRe = /^\s+(?:"([^"]+)"|(\w+)):\s+ExtractRpcMethods<(\w+)>/gm;
|
|
311
305
|
const importMap = /* @__PURE__ */ new Map();
|
|
312
306
|
for (const m of content.matchAll(importRe)) {
|
|
313
307
|
const className = m[1];
|
|
@@ -319,31 +313,6 @@ function readExistingRegistry(registryDir) {
|
|
|
319
313
|
filePath: absPath
|
|
320
314
|
});
|
|
321
315
|
}
|
|
322
|
-
for (const m of content.matchAll(routerRe)) {
|
|
323
|
-
const key = m[1] ?? m[2];
|
|
324
|
-
const alias = m[3];
|
|
325
|
-
const imp = importMap.get(alias);
|
|
326
|
-
if (!imp) continue;
|
|
327
|
-
let pluginName = null;
|
|
328
|
-
let dir = path.dirname(imp.filePath);
|
|
329
|
-
while (dir !== path.dirname(dir)) {
|
|
330
|
-
const candidate = path.join(dir, "zenbu.plugin.json");
|
|
331
|
-
if (fs.existsSync(candidate)) {
|
|
332
|
-
try {
|
|
333
|
-
pluginName = JSON.parse(fs.readFileSync(candidate, "utf8")).name;
|
|
334
|
-
} catch {}
|
|
335
|
-
break;
|
|
336
|
-
}
|
|
337
|
-
dir = path.dirname(dir);
|
|
338
|
-
}
|
|
339
|
-
if (!pluginName) continue;
|
|
340
|
-
if (!services.has(pluginName)) services.set(pluginName, []);
|
|
341
|
-
services.get(pluginName).push({
|
|
342
|
-
className: imp.className,
|
|
343
|
-
key,
|
|
344
|
-
filePath: imp.filePath
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
316
|
}
|
|
348
317
|
const dbPath = path.join(registryDir, "db-sections.ts");
|
|
349
318
|
if (fs.existsSync(dbPath)) {
|
|
@@ -387,32 +356,6 @@ function readExistingRegistry(registryDir) {
|
|
|
387
356
|
});
|
|
388
357
|
}
|
|
389
358
|
}
|
|
390
|
-
const eventsRegistryPath = path.join(registryDir, "events.ts");
|
|
391
|
-
if (fs.existsSync(eventsRegistryPath)) {
|
|
392
|
-
const content = fs.readFileSync(eventsRegistryPath, "utf8");
|
|
393
|
-
for (const m of content.matchAll(/import type \{ Events as (\w+) \} from "([^"]+)"/g)) {
|
|
394
|
-
m[1];
|
|
395
|
-
const relPath = m[2];
|
|
396
|
-
const eventsPath = path.resolve(registryDir, relPath) + ".ts";
|
|
397
|
-
let pluginName = null;
|
|
398
|
-
let dir = path.dirname(eventsPath);
|
|
399
|
-
while (dir !== path.dirname(dir)) {
|
|
400
|
-
const candidate = path.join(dir, "zenbu.plugin.json");
|
|
401
|
-
if (fs.existsSync(candidate)) {
|
|
402
|
-
try {
|
|
403
|
-
pluginName = JSON.parse(fs.readFileSync(candidate, "utf8")).name;
|
|
404
|
-
} catch {}
|
|
405
|
-
break;
|
|
406
|
-
}
|
|
407
|
-
dir = path.dirname(dir);
|
|
408
|
-
}
|
|
409
|
-
if (!pluginName) continue;
|
|
410
|
-
events.set(pluginName, {
|
|
411
|
-
name: pluginName,
|
|
412
|
-
eventsPath
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
359
|
return {
|
|
417
360
|
services,
|
|
418
361
|
schemas,
|
|
@@ -438,10 +381,48 @@ function parseLinkArgs(argv) {
|
|
|
438
381
|
registryOverride
|
|
439
382
|
};
|
|
440
383
|
}
|
|
441
|
-
|
|
442
|
-
|
|
384
|
+
/**
|
|
385
|
+
* Variant for path-based plugin sources (a `zenbu.plugin.ts` whose default
|
|
386
|
+
* export is a `definePlugin({...})`). Resolved upstream by `loadConfig` so
|
|
387
|
+
* we just consume the resolved record here.
|
|
388
|
+
*/
|
|
389
|
+
function linkResolvedPlugin(plugin, existing) {
|
|
390
|
+
console.log(`Linking types "${plugin.name}" from ${plugin.dir}`);
|
|
391
|
+
const serviceGlobs = plugin.services.map((abs) => path.relative(plugin.dir, abs).split(path.sep).join("/"));
|
|
392
|
+
const serviceEntries = discoverServices(plugin.dir, serviceGlobs);
|
|
393
|
+
console.log(` Found ${serviceEntries.length} service(s)`);
|
|
394
|
+
const schemaEntry = plugin.schemaPath ? {
|
|
395
|
+
name: plugin.name,
|
|
396
|
+
schemaPath: plugin.schemaPath
|
|
397
|
+
} : null;
|
|
398
|
+
if (schemaEntry) console.log(` Schema: ${schemaEntry.schemaPath}`);
|
|
399
|
+
const preloadEntry = plugin.preloadPath ? {
|
|
400
|
+
name: plugin.name,
|
|
401
|
+
preloadPath: plugin.preloadPath
|
|
402
|
+
} : null;
|
|
403
|
+
if (preloadEntry) console.log(` Preload: ${preloadEntry.preloadPath}`);
|
|
404
|
+
const eventsEntry = plugin.eventsPath ? {
|
|
405
|
+
name: plugin.name,
|
|
406
|
+
eventsPath: plugin.eventsPath
|
|
407
|
+
} : null;
|
|
408
|
+
if (eventsEntry) console.log(` Events: ${eventsEntry.eventsPath}`);
|
|
409
|
+
existing.services.set(plugin.name, serviceEntries);
|
|
410
|
+
if (schemaEntry) existing.schemas.set(plugin.name, schemaEntry);
|
|
411
|
+
if (preloadEntry) existing.preloads.set(plugin.name, preloadEntry);
|
|
412
|
+
else existing.preloads.delete(plugin.name);
|
|
413
|
+
if (eventsEntry) existing.events.set(plugin.name, eventsEntry);
|
|
414
|
+
else existing.events.delete(plugin.name);
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Variant for the framework-internal `--types-config <path>` flow where the
|
|
418
|
+
* input is a small JSON file (e.g. `packages/core/zenbu-types.config.json`).
|
|
419
|
+
* Used by `pnpm link:types` inside core to bake its own services/registry
|
|
420
|
+
* types without going through a `zenbu.config.ts`.
|
|
421
|
+
*/
|
|
422
|
+
function linkTypesConfig(jsonPath, existing) {
|
|
423
|
+
const manifest = JSON.parse(fs.readFileSync(jsonPath, "utf8"));
|
|
443
424
|
const pluginName = manifest.name;
|
|
444
|
-
const baseDir = path.dirname(
|
|
425
|
+
const baseDir = path.dirname(jsonPath);
|
|
445
426
|
console.log(`Linking types "${pluginName}" from ${baseDir}`);
|
|
446
427
|
const serviceEntries = discoverServices(baseDir, manifest.services ?? []);
|
|
447
428
|
console.log(` Found ${serviceEntries.length} service(s)`);
|
|
@@ -491,11 +472,10 @@ function linkOne(manifestPath, existing) {
|
|
|
491
472
|
* `"extends": "./tsconfig.local.json"`. The generated file then carries
|
|
492
473
|
* `paths` + `include`, which TS merges into the IDE's resolved program.
|
|
493
474
|
*/
|
|
494
|
-
function writePluginTsconfigLocal(
|
|
495
|
-
const pluginDir = path.dirname(pluginManifestPath);
|
|
475
|
+
function writePluginTsconfigLocal(pluginDir, registryDir) {
|
|
496
476
|
const ownTsconfig = path.join(pluginDir, "tsconfig.json");
|
|
497
477
|
if (!fs.existsSync(ownTsconfig)) return;
|
|
498
|
-
if (fs.existsSync(path.join(pluginDir,
|
|
478
|
+
for (const name of CONFIG_NAMES) if (fs.existsSync(path.join(pluginDir, name))) return;
|
|
499
479
|
const target = path.join(pluginDir, "tsconfig.local.json");
|
|
500
480
|
let registryRel = path.relative(pluginDir, registryDir);
|
|
501
481
|
if (!registryRel.startsWith(".")) registryRel = "./" + registryRel;
|
|
@@ -512,55 +492,44 @@ function writePluginTsconfigLocal(pluginManifestPath, registryDir) {
|
|
|
512
492
|
fs.writeFileSync(target, next);
|
|
513
493
|
console.log(` Wrote ${target}`);
|
|
514
494
|
}
|
|
515
|
-
/**
|
|
516
|
-
* When the manifest being linked is the host app's own manifest (sitting
|
|
517
|
-
* next to its `config.json`), expand the work list to also include every
|
|
518
|
-
* plugin path declared in `config.json#plugins`. For any other manifest
|
|
519
|
-
* (a plugin sitting inside or outside the app), only that single manifest
|
|
520
|
-
* is returned — the caller decides not to touch sibling plugins.
|
|
521
|
-
*/
|
|
522
|
-
function expandAppManifests(manifestPath) {
|
|
523
|
-
const manifestDir = path.dirname(manifestPath);
|
|
524
|
-
const appRoot = findAppRoot(manifestDir);
|
|
525
|
-
if (appRoot !== manifestDir) return [manifestPath];
|
|
526
|
-
const configPath = path.join(appRoot, "config.json");
|
|
527
|
-
let pluginEntries = [];
|
|
528
|
-
try {
|
|
529
|
-
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
530
|
-
if (Array.isArray(config?.plugins)) pluginEntries = config.plugins;
|
|
531
|
-
} catch {}
|
|
532
|
-
const all = [manifestPath];
|
|
533
|
-
for (const entry of pluginEntries) {
|
|
534
|
-
const resolved = path.isAbsolute(entry) ? entry : path.resolve(appRoot, entry);
|
|
535
|
-
if (path.resolve(resolved) === path.resolve(manifestPath)) continue;
|
|
536
|
-
if (!fs.existsSync(resolved)) {
|
|
537
|
-
console.warn(` ⚠ skipping ${entry} (not found at ${resolved})`);
|
|
538
|
-
continue;
|
|
539
|
-
}
|
|
540
|
-
all.push(resolved);
|
|
541
|
-
}
|
|
542
|
-
return all;
|
|
543
|
-
}
|
|
544
495
|
async function runLink(argv) {
|
|
545
496
|
const { manifestArg, typesConfigArg, registryOverride } = parseLinkArgs(argv);
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
497
|
+
if (typesConfigArg) {
|
|
498
|
+
const typeConfigPath = path.resolve(typesConfigArg);
|
|
499
|
+
const registryDir = resolveRegistryDir({
|
|
500
|
+
manifestPath: typeConfigPath,
|
|
501
|
+
manifest: JSON.parse(fs.readFileSync(typeConfigPath, "utf8")),
|
|
502
|
+
registryOverride
|
|
503
|
+
});
|
|
504
|
+
console.log(`Registry: ${registryDir}`);
|
|
505
|
+
fs.mkdirSync(registryDir, { recursive: true });
|
|
506
|
+
const existing = readExistingRegistry(registryDir);
|
|
507
|
+
linkTypesConfig(typeConfigPath, existing);
|
|
508
|
+
writeRegistryFiles(registryDir, existing);
|
|
509
|
+
console.log("Done.");
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
const projectDir = manifestArg ? path.resolve(manifestArg) : findProjectDir(process.cwd());
|
|
513
|
+
if (!projectDir) {
|
|
514
|
+
console.error("zen link: could not find zenbu.config.ts in current directory or any parent.");
|
|
550
515
|
console.error(" For internal framework types, pass --types-config <path>.");
|
|
551
516
|
process.exit(1);
|
|
552
517
|
}
|
|
553
|
-
const
|
|
518
|
+
const { resolved } = await loadConfig(projectDir);
|
|
554
519
|
const registryDir = resolveRegistryDir({
|
|
555
|
-
manifestPath:
|
|
556
|
-
manifest:
|
|
520
|
+
manifestPath: resolved.configPath,
|
|
521
|
+
manifest: {},
|
|
557
522
|
registryOverride
|
|
558
523
|
});
|
|
559
524
|
console.log(`Registry: ${registryDir}`);
|
|
560
|
-
const manifestPaths = typeConfigPath ? [typeConfigPath] : expandAppManifests(manifestPath);
|
|
561
525
|
fs.mkdirSync(registryDir, { recursive: true });
|
|
562
526
|
const existing = readExistingRegistry(registryDir);
|
|
563
|
-
for (const
|
|
527
|
+
for (const plugin of resolved.plugins) linkResolvedPlugin(plugin, existing);
|
|
528
|
+
writeRegistryFiles(registryDir, existing);
|
|
529
|
+
for (const plugin of resolved.plugins) writePluginTsconfigLocal(plugin.dir, registryDir);
|
|
530
|
+
console.log("Done.");
|
|
531
|
+
}
|
|
532
|
+
function writeRegistryFiles(registryDir, existing) {
|
|
564
533
|
const writes = [
|
|
565
534
|
["services.ts", generateServicesFile(registryDir, existing.services)],
|
|
566
535
|
["db-sections.ts", generateDbSectionsFile(registryDir, existing.schemas)],
|
|
@@ -573,8 +542,6 @@ async function runLink(argv) {
|
|
|
573
542
|
fs.writeFileSync(target, body);
|
|
574
543
|
console.log(` Wrote ${target}`);
|
|
575
544
|
}
|
|
576
|
-
for (const mp of manifestPaths) writePluginTsconfigLocal(mp, registryDir);
|
|
577
|
-
console.log("Done.");
|
|
578
545
|
}
|
|
579
546
|
//#endregion
|
|
580
547
|
export { runLink };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { n as __exportAll } from "./chunk-DsiFFCwN.mjs";
|
|
2
|
+
import { i as resolveBuildConfig } from "./build-config-C3a-o3_B.mjs";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
//#region src/cli/lib/load-config.ts
|
|
8
|
+
var load_config_exports = /* @__PURE__ */ __exportAll({
|
|
9
|
+
findConfigPath: () => findConfigPath,
|
|
10
|
+
loadConfig: () => loadConfig
|
|
11
|
+
});
|
|
12
|
+
const localRequire = createRequire(import.meta.url);
|
|
13
|
+
const CONFIG_NAMES = [
|
|
14
|
+
"zenbu.config.ts",
|
|
15
|
+
"zenbu.config.mts",
|
|
16
|
+
"zenbu.config.js",
|
|
17
|
+
"zenbu.config.mjs"
|
|
18
|
+
];
|
|
19
|
+
const PLUGIN_FILE_RE = /\.(?:ts|mts|js|mjs|cjs)$/;
|
|
20
|
+
function findConfigPath(projectDir) {
|
|
21
|
+
for (const name of CONFIG_NAMES) {
|
|
22
|
+
const candidate = path.join(projectDir, name);
|
|
23
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
24
|
+
}
|
|
25
|
+
throw new Error(`No zenbu config found at ${projectDir}. Expected one of: ${CONFIG_NAMES.join(", ")}`);
|
|
26
|
+
}
|
|
27
|
+
let tsxRegistered = null;
|
|
28
|
+
function ensureTsxRegistered() {
|
|
29
|
+
if (tsxRegistered) return tsxRegistered;
|
|
30
|
+
tsxRegistered = (async () => {
|
|
31
|
+
try {
|
|
32
|
+
const tsxApi = localRequire("tsx/esm/api");
|
|
33
|
+
if (typeof tsxApi.register === "function") tsxApi.register();
|
|
34
|
+
} catch {}
|
|
35
|
+
})();
|
|
36
|
+
return tsxRegistered;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Dynamically import a TS module with a cache-busting query string. Each call
|
|
40
|
+
* forces tsx + Node's ESM loader to re-evaluate the file. Used to rebuild
|
|
41
|
+
* the resolved config + plugin set every time the loader is invoked, so a
|
|
42
|
+
* change to the source TS triggers a fresh `default` export.
|
|
43
|
+
*
|
|
44
|
+
* The returned object is whatever the module's default export is. Older
|
|
45
|
+
* defineConfig-style files that exported the object directly (no `default`)
|
|
46
|
+
* also work via the `mod.default ?? mod` fallback.
|
|
47
|
+
*/
|
|
48
|
+
async function importFresh(absPath) {
|
|
49
|
+
await ensureTsxRegistered();
|
|
50
|
+
const mod = await import(pathToFileURL(absPath).href + "?t=" + Date.now());
|
|
51
|
+
return mod.default ?? mod;
|
|
52
|
+
}
|
|
53
|
+
function assertPluginShape(p, source) {
|
|
54
|
+
if (!p || typeof p !== "object") throw new Error(`${source} did not export a Plugin object.`);
|
|
55
|
+
const obj = p;
|
|
56
|
+
if (typeof obj.name !== "string" || obj.name.length === 0) throw new Error(`${source}: plugin missing required string \`name\`.`);
|
|
57
|
+
if (!Array.isArray(obj.services)) throw new Error(`${source}: plugin \`services\` must be an array of glob strings.`);
|
|
58
|
+
}
|
|
59
|
+
function resolvePluginPaths(plugin, dir) {
|
|
60
|
+
const abs = (rel) => path.isAbsolute(rel) ? rel : path.resolve(dir, rel);
|
|
61
|
+
return {
|
|
62
|
+
name: plugin.name,
|
|
63
|
+
dir,
|
|
64
|
+
services: plugin.services.map((s) => path.isAbsolute(s) ? s : path.resolve(dir, s)),
|
|
65
|
+
schemaPath: plugin.schema ? abs(plugin.schema) : void 0,
|
|
66
|
+
migrationsPath: plugin.migrations ? abs(plugin.migrations) : void 0,
|
|
67
|
+
preloadPath: plugin.preload ? abs(plugin.preload) : void 0,
|
|
68
|
+
eventsPath: plugin.events ? abs(plugin.events) : void 0,
|
|
69
|
+
icons: plugin.icons
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async function resolvePluginEntry(entry, configDir) {
|
|
73
|
+
if (typeof entry === "string") {
|
|
74
|
+
const absPath = path.isAbsolute(entry) ? entry : path.resolve(configDir, entry);
|
|
75
|
+
if (!PLUGIN_FILE_RE.test(absPath)) throw new Error(`Plugin entry "${entry}" must point at a .ts/.js file (got ${path.basename(absPath)}). JSON plugin manifests are not supported in the new config; convert to \`zenbu.plugin.ts\`.`);
|
|
76
|
+
if (!fs.existsSync(absPath)) throw new Error(`Plugin entry "${entry}" does not exist at ${absPath}.`);
|
|
77
|
+
const plugin = await importFresh(absPath);
|
|
78
|
+
assertPluginShape(plugin, absPath);
|
|
79
|
+
return {
|
|
80
|
+
resolved: resolvePluginPaths(plugin, path.dirname(absPath)),
|
|
81
|
+
sourceFile: absPath
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
assertPluginShape(entry, "(inline plugin)");
|
|
85
|
+
return {
|
|
86
|
+
resolved: resolvePluginPaths(entry, configDir),
|
|
87
|
+
sourceFile: null
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Read `<projectDir>/zenbu.config.ts`, resolve all plugin entries (inline +
|
|
92
|
+
* path), make every relative path absolute, and fill in `build` defaults.
|
|
93
|
+
*
|
|
94
|
+
* Used both by the loader (to generate the plugin barrel; cache-busted on
|
|
95
|
+
* every invocation) and by CLI commands (`build:source`, `build:electron`,
|
|
96
|
+
* `link`, `db generate`, `publish:source`).
|
|
97
|
+
*/
|
|
98
|
+
async function loadConfig(projectDir) {
|
|
99
|
+
const configPath = findConfigPath(projectDir);
|
|
100
|
+
const config = await importFresh(configPath);
|
|
101
|
+
if (!config || typeof config !== "object") throw new Error(`${configPath} default export is not a Config object.`);
|
|
102
|
+
if (typeof config.db !== "string" || config.db.length === 0) throw new Error(`${configPath}: missing required \`db\` field (path to the database directory).`);
|
|
103
|
+
if (typeof config.uiEntrypoint !== "string" || config.uiEntrypoint.length === 0) throw new Error(`${configPath}: missing required \`uiEntrypoint\` field (directory holding index.html + splash.html).`);
|
|
104
|
+
if (!Array.isArray(config.plugins)) throw new Error(`${configPath}: \`plugins\` must be an array.`);
|
|
105
|
+
const configDir = path.dirname(configPath);
|
|
106
|
+
const dbPath = path.isAbsolute(config.db) ? config.db : path.resolve(configDir, config.db);
|
|
107
|
+
const uiEntrypointPath = path.isAbsolute(config.uiEntrypoint) ? config.uiEntrypoint : path.resolve(configDir, config.uiEntrypoint);
|
|
108
|
+
if (!(() => {
|
|
109
|
+
try {
|
|
110
|
+
return fs.statSync(uiEntrypointPath);
|
|
111
|
+
} catch {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
})()?.isDirectory()) throw new Error(`${configPath}: uiEntrypoint must point at a directory; got ${config.uiEntrypoint}.`);
|
|
115
|
+
const splashPath = path.join(uiEntrypointPath, "splash.html");
|
|
116
|
+
if (!fs.existsSync(splashPath)) throw new Error(`${configPath}: uiEntrypoint directory ${config.uiEntrypoint} is missing required \`splash.html\`. The splash file is shown raw (no Vite) during the brief window between Electron startup and the app's first paint.`);
|
|
117
|
+
const plugins = [];
|
|
118
|
+
const pluginSourceFiles = [];
|
|
119
|
+
for (const entry of config.plugins) {
|
|
120
|
+
const { resolved, sourceFile } = await resolvePluginEntry(entry, configDir);
|
|
121
|
+
plugins.push(resolved);
|
|
122
|
+
if (sourceFile) pluginSourceFiles.push(sourceFile);
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
resolved: {
|
|
126
|
+
configPath,
|
|
127
|
+
projectDir: configDir,
|
|
128
|
+
dbPath,
|
|
129
|
+
uiEntrypointPath,
|
|
130
|
+
splashPath,
|
|
131
|
+
plugins,
|
|
132
|
+
build: resolveBuildConfig(config.build ?? {
|
|
133
|
+
source: ".",
|
|
134
|
+
include: ["**/*"]
|
|
135
|
+
})
|
|
136
|
+
},
|
|
137
|
+
pluginSourceFiles
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
141
|
+
export { load_config_exports as n, loadConfig as t };
|
package/dist/loaders/zenbu.d.mts
CHANGED
|
@@ -14,8 +14,25 @@ type TracePort = {
|
|
|
14
14
|
};
|
|
15
15
|
type InitializeData = {
|
|
16
16
|
tracePort?: TracePort;
|
|
17
|
+
payload?: RegistryPayload;
|
|
18
|
+
pluginSourceFiles?: string[];
|
|
17
19
|
};
|
|
18
20
|
declare function initialize(data?: InitializeData): void;
|
|
21
|
+
interface ResolvedPluginRecord {
|
|
22
|
+
name: string;
|
|
23
|
+
dir: string;
|
|
24
|
+
services: string[];
|
|
25
|
+
schemaPath?: string;
|
|
26
|
+
migrationsPath?: string;
|
|
27
|
+
preloadPath?: string;
|
|
28
|
+
eventsPath?: string;
|
|
29
|
+
icons?: Record<string, string>;
|
|
30
|
+
}
|
|
31
|
+
interface RegistryPayload {
|
|
32
|
+
plugins: ResolvedPluginRecord[];
|
|
33
|
+
appEntrypoint: string;
|
|
34
|
+
splashPath: string;
|
|
35
|
+
}
|
|
19
36
|
declare function resolve(specifier: string, context: LoaderContext, nextResolve: NextResolve): unknown;
|
|
20
37
|
declare function load(url: string, context: LoaderContext, nextLoad: NextLoad): unknown;
|
|
21
38
|
//#endregion
|