@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.
Files changed (89) hide show
  1. package/dist/{advice-config-CjgkEf2E.mjs → advice-config-QYB2qEd_.mjs} +32 -14
  2. package/dist/advice.mjs +1 -1
  3. package/dist/{base-window-BUt8pwbw.mjs → base-window-BbFRRhKP.mjs} +9 -4
  4. package/dist/{build-config-pbv0w4oN.mjs → build-config-C3a-o3_B.mjs} +8 -2
  5. package/dist/{build-electron-BzHa_hRi.mjs → build-electron-CNJ0dLND.mjs} +12 -6
  6. package/dist/{build-source-CnTfQBGK.mjs → build-source-C2puqEVr.mjs} +13 -8
  7. package/dist/chunk-DsiFFCwN.mjs +16 -0
  8. package/dist/cli/bin.mjs +12 -15
  9. package/dist/cli/build.d.mts +1 -52
  10. package/dist/cli/build.mjs +2 -47
  11. package/dist/cli/resolve-config.mjs +37 -0
  12. package/dist/{cli-BLbQQIVB.mjs → cli-C3R1LBMY.mjs} +5 -5
  13. package/dist/{config-CdVrW85P.mjs → config-DXRCDUxG.mjs} +1 -1
  14. package/dist/config.d.mts +3 -0
  15. package/dist/config.mjs +4 -0
  16. package/dist/{db-BXadETOb.mjs → db-xjvahRFJ.mjs} +47 -41
  17. package/dist/db.d.mts +1 -1
  18. package/dist/db.mjs +2 -2
  19. package/dist/env-bootstrap.d.mts +1 -1
  20. package/dist/env-bootstrap.mjs +52 -1
  21. package/dist/index-ClXLQ1fw.d.mts +1 -0
  22. package/dist/index.d.mts +5 -5
  23. package/dist/index.mjs +4 -4
  24. package/dist/{link-VOoGs-pY.mjs → link-c0_aLWQ3.mjs} +87 -120
  25. package/dist/load-config-xMf2wxH8.mjs +141 -0
  26. package/dist/loaders/zenbu.d.mts +17 -0
  27. package/dist/loaders/zenbu.mjs +144 -135
  28. package/dist/{monorepo-CQeQBIpa.mjs → monorepo-3avKJwzJ.mjs} +5 -2
  29. package/dist/node-loader.mjs +1 -1
  30. package/dist/{publish-source-BJdpDAFH.mjs → publish-source-Dill72NS.mjs} +12 -6
  31. package/dist/react.d.mts +3 -3
  32. package/dist/react.mjs +2 -2
  33. package/dist/{registry-Dh_e7HU1.d.mts → registry-eX6e2oql.d.mts} +1 -1
  34. package/dist/registry.d.mts +1 -1
  35. package/dist/{reloader-lLAJ3lqg.mjs → reloader-DzEO8kJr.mjs} +6 -4
  36. package/dist/{renderer-host-Bg8QdeeH.mjs → renderer-host-Cau9JK0v.mjs} +90 -212
  37. package/dist/{rpc-BwwQK6hD.mjs → rpc-JfGv-Wuw.mjs} +7 -5
  38. package/dist/rpc.d.mts +1 -1
  39. package/dist/rpc.mjs +1 -1
  40. package/dist/{runtime-CjqDr8Yf.d.mts → runtime-pCeVzj--.d.mts} +73 -1
  41. package/dist/runtime.d.mts +2 -2
  42. package/dist/runtime.mjs +522 -2
  43. package/dist/{schema-DMoSkwUx.d.mts → schema-Dl85YjXW.d.mts} +1 -1
  44. package/dist/schema.d.mts +1 -1
  45. package/dist/schema.mjs +27 -1
  46. package/dist/{server-BXwZEQ-n.mjs → server-y3PPbh3l.mjs} +5 -3
  47. package/dist/services/default.mjs +10 -10
  48. package/dist/services/index.d.mts +8 -4
  49. package/dist/services/index.mjs +6 -6
  50. package/dist/setup-gate.d.mts +1 -1
  51. package/dist/setup-gate.mjs +248 -1
  52. package/dist/{transform-DJH3vN4b.mjs → transform-CmFYPmt8.mjs} +1 -1
  53. package/dist/transforms-CuTODvDx.d.mts +145 -0
  54. package/dist/transforms-htxfTwsY.mjs +47 -0
  55. package/dist/{transport-BMSzG2-F.mjs → transport-F2hv_OEm.mjs} +1 -1
  56. package/dist/{vite-plugins-Bh3SCOw-.mjs → vite-plugins-Do7liKi_.mjs} +5 -19
  57. package/dist/vite.mjs +1 -1
  58. package/dist/{window-CmmpCVX6.mjs → window-o2NGUsIb.mjs} +10 -7
  59. package/dist/{write-9dRFczGJ.mjs → write-DgIRjo23.mjs} +1 -1
  60. package/package.json +11 -10
  61. package/dist/advice-config-Cy133IQP.mjs +0 -2
  62. package/dist/base-window-DEIAk618.mjs +0 -2
  63. package/dist/chunk-Dm34NbLt.mjs +0 -6
  64. package/dist/config-LK73dJmO.mjs +0 -2
  65. package/dist/db-ByKPbnP6.mjs +0 -2
  66. package/dist/env-bootstrap-rj7I-59x.mjs +0 -53
  67. package/dist/http-IBcLzbYu.mjs +0 -2
  68. package/dist/load-build-config-DozuRhAN.mjs +0 -40
  69. package/dist/reloader-BCkLjDhS.mjs +0 -2
  70. package/dist/renderer-host-DpvBPTHJ.mjs +0 -2
  71. package/dist/rpc-CqitnyR4.mjs +0 -2
  72. package/dist/runtime-DUFKDIe4.mjs +0 -409
  73. package/dist/schema-dGK6qkfR.mjs +0 -28
  74. package/dist/server-DjrZUbbu.mjs +0 -2
  75. package/dist/setup-gate-BcoqWu8S.mjs +0 -110
  76. package/dist/view-registry-BualWgAf.mjs +0 -2
  77. package/dist/window-CM2a9Kyc.mjs +0 -2
  78. package/dist/{index-FtE8MXJ_.d.mts → cli/resolve-config.d.mts} +0 -0
  79. package/dist/{dev-BU_llQh1.mjs → dev-Dazhu66l.mjs} +0 -0
  80. package/dist/{env-bootstrap-BtVME-CU.d.mts → env-bootstrap-DW2hVhSO.d.mts} +0 -0
  81. package/dist/{index-Bhlbyrn7.d.mts → index-C-ALz_SH.d.mts} +0 -0
  82. package/dist/{index-CPZ5d6Hl.d.mts → index-M_lSNBrq.d.mts} +0 -0
  83. package/dist/{log-CyKv8hQg.mjs → log-6rzaCV0I.mjs} +0 -0
  84. package/dist/{mirror-sync-BN59kMCG.mjs → mirror-sync-PDzxhf1w.mjs} +1 -1
  85. /package/dist/{node-D4M19_mV.mjs → node-_8xShqxr.mjs} +0 -0
  86. /package/dist/{schema-CIg4GzHQ.mjs → schema-Ca7SxXgS.mjs} +0 -0
  87. /package/dist/{setup-gate-BqOzm7zp.d.mts → setup-gate-Dcy8gGPJ.d.mts} +0 -0
  88. /package/dist/{src-pELM4_iH.mjs → src-Cven45mq.mjs} +0 -0
  89. /package/dist/{trace-DCB7qFzT.mjs → trace-BaVg0rnY.mjs} +0 -0
@@ -1,12 +1,13 @@
1
- import { i as runtime, t as Service } from "./runtime-DUFKDIe4.mjs";
2
- import { o as getZodDefault } from "./schema-CIg4GzHQ.mjs";
3
- import { t as schema } from "./schema-dGK6qkfR.mjs";
4
- import { t as createLogger } from "./log-CyKv8hQg.mjs";
5
- import { t as ServerService } from "./server-BXwZEQ-n.mjs";
6
- import { n as DB_CONFIG_JSON, r as INTERNAL_DIR, t as ReloaderService } from "./reloader-lLAJ3lqg.mjs";
7
- import { a as createBlob, c as makeErrorAck, g as layer$1, h as writeJsonFile, i as cleanupStaleTmpFiles, l as paths, m as validateSession, n as makeRootCache, o as createCollection, p as sendAck, r as broadcastDbUpdate, s as makeAck, t as handleWrite, u as readCollectionItemRange, v as FileSystem } from "./write-9dRFczGJ.mjs";
8
- import { t as traceKyju } from "./trace-DCB7qFzT.mjs";
9
- import { a as createClient, i as dbStringify, n as createRouter, o as createEffectClient, r as dbParse, s as createReplica } from "./transport-BMSzG2-F.mjs";
1
+ import { n as __exportAll } from "./chunk-DsiFFCwN.mjs";
2
+ import { Service, getAppEntrypoint, getPlugins, runtime } from "./runtime.mjs";
3
+ import { o as getZodDefault } from "./schema-Ca7SxXgS.mjs";
4
+ import { schema } from "./schema.mjs";
5
+ import { t as createLogger } from "./log-6rzaCV0I.mjs";
6
+ import { t as ServerService } from "./server-y3PPbh3l.mjs";
7
+ import { i as INTERNAL_DIR, r as DB_CONFIG_JSON, t as ReloaderService } from "./reloader-DzEO8kJr.mjs";
8
+ import { a as createBlob, c as makeErrorAck, g as layer$1, h as writeJsonFile, i as cleanupStaleTmpFiles, l as paths, m as validateSession, n as makeRootCache, o as createCollection, p as sendAck, r as broadcastDbUpdate, s as makeAck, t as handleWrite, u as readCollectionItemRange, v as FileSystem } from "./write-DgIRjo23.mjs";
9
+ import { t as traceKyju } from "./trace-BaVg0rnY.mjs";
10
+ import { a as createClient, i as dbStringify, n as createRouter, o as createEffectClient, r as dbParse, s as createReplica } from "./transport-F2hv_OEm.mjs";
10
11
  import fs from "node:fs";
11
12
  import os from "node:os";
12
13
  import path from "node:path";
@@ -798,6 +799,7 @@ async function resolveDbPath(argv, app) {
798
799
  }
799
800
  //#endregion
800
801
  //#region src/services/http.ts
802
+ var http_exports = /* @__PURE__ */ __exportAll({ HttpService: () => HttpService });
801
803
  const log$3 = createLogger("http");
802
804
  var HttpService = class extends Service {
803
805
  static key = "http";
@@ -932,6 +934,11 @@ var HttpService = class extends Service {
932
934
  runtime.register(HttpService, import.meta);
933
935
  //#endregion
934
936
  //#region src/services/db.ts
937
+ var db_exports = /* @__PURE__ */ __exportAll({
938
+ DbService: () => DbService,
939
+ discoverSections: () => discoverSections,
940
+ resolveManifestModulePath: () => resolveManifestModulePath
941
+ });
935
942
  const log$2 = createLogger("db");
936
943
  /**
937
944
  * Walk up from this file's location until we hit the @zenbujs/core
@@ -995,88 +1002,47 @@ async function resolveManifestModulePath(baseDir, specifier) {
995
1002
  async function importFreshModule(modulePath) {
996
1003
  return import(pathToFileURL(modulePath).href);
997
1004
  }
998
- async function resolveConfigPath$1() {
999
- if (process.env.ZENBU_CONFIG_PATH) return process.env.ZENBU_CONFIG_PATH;
1000
- const jsonc = path.join(os.homedir(), ".zenbu", "config.jsonc");
1001
- try {
1002
- await fsp.access(jsonc);
1003
- return jsonc;
1004
- } catch {
1005
- return path.join(os.homedir(), ".zenbu", "config.json");
1006
- }
1007
- }
1008
- async function loadAppConfig(configPath) {
1009
- let raw;
1010
- try {
1011
- raw = parseJsonc$2(await fsp.readFile(configPath, "utf8"));
1012
- } catch (err) {
1013
- throw new Error(`Failed to read Zenbu config at ${configPath}: ${err instanceof Error ? err.message : String(err)}`);
1014
- }
1015
- if (!raw || typeof raw !== "object") throw new Error(`Zenbu config at ${configPath} is not a JSON object`);
1016
- const obj = raw;
1017
- const plugins = Array.isArray(obj.plugins) ? obj.plugins.filter((p) => typeof p === "string") : [];
1018
- return {
1019
- db: typeof obj.db === "string" ? obj.db : "",
1020
- plugins
1021
- };
1005
+ function resolveConfigPath() {
1006
+ const fromEnv = process.env.ZENBU_CONFIG_PATH;
1007
+ if (!fromEnv) throw new Error("ZENBU_CONFIG_PATH is not set; setup-gate populates this before services boot.");
1008
+ return fromEnv;
1022
1009
  }
1023
- function parseJsonc$2(str) {
1024
- let result = "";
1025
- let i = 0;
1026
- while (i < str.length) if (str[i] === "\"") {
1027
- let j = i + 1;
1028
- while (j < str.length) if (str[j] === "\\") j += 2;
1029
- else if (str[j] === "\"") {
1030
- j++;
1031
- break;
1032
- } else j++;
1033
- result += str.slice(i, j);
1034
- i = j;
1035
- } else if (str[i] === "/" && str[i + 1] === "/") {
1036
- i += 2;
1037
- while (i < str.length && str[i] !== "\n") i++;
1038
- } else if (str[i] === "/" && str[i + 1] === "*") {
1039
- i += 2;
1040
- while (i < str.length && !(str[i] === "*" && str[i + 1] === "/")) i++;
1041
- i += 2;
1042
- } else {
1043
- result += str[i];
1044
- i++;
1045
- }
1046
- return JSON.parse(result.replace(/,\s*([\]}])/g, "$1"));
1010
+ /**
1011
+ * Load just the `db` field from the user's `zenbu.config.ts`. Used to feed
1012
+ * `resolveDbPath` (which expects a relative-or-absolute string). The full
1013
+ * plugin set comes from `runtime.getPlugins()` instead populated by the
1014
+ * loader-emitted barrel before any service evaluates.
1015
+ */
1016
+ async function loadAppDbField(configPath) {
1017
+ const { loadConfig } = await import("./load-config-xMf2wxH8.mjs").then((n) => n.n);
1018
+ const { resolved } = await loadConfig(path.dirname(configPath));
1019
+ return resolved.dbPath;
1047
1020
  }
1048
- async function discoverSections(configPath) {
1049
- const resolvedConfigPath = configPath ?? await resolveConfigPath$1();
1050
- let config = { plugins: [] };
1051
- try {
1052
- config = parseJsonc$2(await fsp.readFile(resolvedConfigPath, "utf8"));
1053
- } catch (error) {
1054
- log$2.error(`failed to read plugin config at ${resolvedConfigPath}: ${error instanceof Error ? error.message : String(error)}`);
1055
- return [];
1056
- }
1021
+ async function discoverSections() {
1022
+ const plugins = getPlugins();
1057
1023
  const perPluginTimings = [];
1058
- const tasks = config.plugins.map(async (manifestPath) => {
1024
+ const tasks = plugins.map(async (plugin) => {
1059
1025
  const pluginStart = Date.now();
1060
- let manifestMs = 0;
1061
1026
  let resolveSchemaMs = 0;
1062
1027
  let importSchemaMs = 0;
1063
1028
  let resolveMigrationsMs = 0;
1064
1029
  let importMigrationsMs = 0;
1065
- let pluginName = path.basename(path.dirname(manifestPath));
1030
+ const finish = (result) => {
1031
+ perPluginTimings.push({
1032
+ name: plugin.name,
1033
+ resolveSchemaMs,
1034
+ importSchemaMs,
1035
+ resolveMigrationsMs,
1036
+ importMigrationsMs,
1037
+ totalMs: Date.now() - pluginStart
1038
+ });
1039
+ return result;
1040
+ };
1041
+ if (!plugin.schemaPath) return finish(null);
1066
1042
  try {
1067
- const t0 = Date.now();
1068
- const raw = await fsp.readFile(manifestPath, "utf8");
1069
- manifestMs = Date.now() - t0;
1070
- const manifest = JSON.parse(raw);
1071
- pluginName = manifest.name ?? pluginName;
1072
- if (!manifest.name || !manifest.schema) {
1073
- log$2.error(`skipping manifest without name/schema: ${manifestPath}`);
1074
- return null;
1075
- }
1076
- const baseDir = path.dirname(path.resolve(manifestPath));
1077
1043
  const schemaChain = (async () => {
1078
1044
  const s0 = Date.now();
1079
- const schemaPath = await resolveManifestModulePath(baseDir, manifest.schema);
1045
+ const schemaPath = await resolveManifestModulePath(plugin.dir, plugin.schemaPath);
1080
1046
  resolveSchemaMs = Date.now() - s0;
1081
1047
  const s1 = Date.now();
1082
1048
  const schemaModule = await importFreshModule(schemaPath);
@@ -1086,10 +1052,10 @@ async function discoverSections(configPath) {
1086
1052
  schemaModule
1087
1053
  };
1088
1054
  })();
1089
- const migrationsChain = manifest.migrations ? (async () => {
1055
+ const migrationsChain = plugin.migrationsPath ? (async () => {
1090
1056
  try {
1091
1057
  const m0 = Date.now();
1092
- const migrationsPath = await resolveManifestModulePath(baseDir, manifest.migrations);
1058
+ const migrationsPath = await resolveManifestModulePath(plugin.dir, plugin.migrationsPath);
1093
1059
  resolveMigrationsMs = Date.now() - m0;
1094
1060
  const m1 = Date.now();
1095
1061
  const stat = await fsp.stat(migrationsPath);
@@ -1105,7 +1071,7 @@ async function discoverSections(configPath) {
1105
1071
  failed: false
1106
1072
  };
1107
1073
  } catch (error) {
1108
- log$2.error(`failed to load migrations from ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`);
1074
+ log$2.error(`failed to load migrations for plugin "${plugin.name}": ${error instanceof Error ? error.message : String(error)}`);
1109
1075
  return {
1110
1076
  migrations: [],
1111
1077
  failed: true
@@ -1116,40 +1082,26 @@ async function discoverSections(configPath) {
1116
1082
  failed: false
1117
1083
  });
1118
1084
  const [schemaResult, migrationsResult] = await Promise.all([schemaChain, migrationsChain]);
1119
- if (migrationsResult.failed) return null;
1085
+ if (migrationsResult.failed) return finish(null);
1120
1086
  const schema = schemaResult.schemaModule.schema ?? schemaResult.schemaModule.default;
1121
1087
  if (!schema?.shape) {
1122
1088
  log$2.error(`schema module did not export a valid schema: ${schemaResult.schemaPath}`);
1123
- return null;
1089
+ return finish(null);
1124
1090
  }
1125
- return {
1126
- name: manifest.name,
1091
+ return finish({
1092
+ name: plugin.name,
1127
1093
  schema,
1128
1094
  migrations: migrationsResult.migrations
1129
- };
1130
- } catch (error) {
1131
- log$2.error(`failed to load section from ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`);
1132
- return null;
1133
- } finally {
1134
- perPluginTimings.push({
1135
- name: pluginName,
1136
- manifestMs,
1137
- resolveSchemaMs,
1138
- importSchemaMs,
1139
- resolveMigrationsMs,
1140
- importMigrationsMs,
1141
- totalMs: Date.now() - pluginStart
1142
1095
  });
1096
+ } catch (error) {
1097
+ log$2.error(`failed to load section for plugin "${plugin.name}": ${error instanceof Error ? error.message : String(error)}`);
1098
+ return finish(null);
1143
1099
  }
1144
1100
  });
1145
- const sections = (await Promise.all(tasks)).filter((s) => s !== null);
1101
+ const sections = (await Promise.all(tasks)).filter((sec) => sec !== null);
1146
1102
  const sorted = [...perPluginTimings].sort((a, b) => b.totalMs - a.totalMs);
1147
- const sum = (k) => perPluginTimings.reduce((acc, p) => acc + p[k], 0);
1148
1103
  log$2.verbose("per-plugin breakdown (ms, parallel):");
1149
- log$2.verbose(` ${"plugin".padEnd(28)} ${"total".padStart(6)} ${"man".padStart(5)} ${"resS".padStart(5)} ${"impS".padStart(6)} ${"resM".padStart(5)} ${"impM".padStart(6)}`);
1150
- for (const p of sorted) log$2.verbose(` ${p.name.padEnd(28)} ${String(p.totalMs).padStart(6)} ${String(p.manifestMs).padStart(5)} ${String(p.resolveSchemaMs).padStart(5)} ${String(p.importSchemaMs).padStart(6)} ${String(p.resolveMigrationsMs).padStart(5)} ${String(p.importMigrationsMs).padStart(6)}`);
1151
- log$2.verbose(` ${"SUM(cpu)".padEnd(28)} ${String(sum("totalMs")).padStart(6)} ${String(sum("manifestMs")).padStart(5)} ${String(sum("resolveSchemaMs")).padStart(5)} ${String(sum("importSchemaMs")).padStart(6)} ${String(sum("resolveMigrationsMs")).padStart(5)} ${String(sum("importMigrationsMs")).padStart(6)}`);
1152
- log$2.verbose(` (wall time: look at db.discover-sections span — should be ~max(totalMs) not SUM)`);
1104
+ for (const ptm of sorted) log$2.verbose(` ${ptm.name.padEnd(28)} total=${String(ptm.totalMs).padStart(6)} resS=${String(ptm.resolveSchemaMs).padStart(5)} impS=${String(ptm.importSchemaMs).padStart(6)} resM=${String(ptm.resolveMigrationsMs).padStart(5)} impM=${String(ptm.importMigrationsMs).padStart(6)}`);
1153
1105
  return sections;
1154
1106
  }
1155
1107
  var DbService = class extends Service {
@@ -1201,14 +1153,14 @@ var DbService = class extends Service {
1201
1153
  }
1202
1154
  }
1203
1155
  async evaluate() {
1204
- const configPath = await resolveConfigPath$1();
1156
+ const configPath = resolveConfigPath();
1205
1157
  const configDir = path.dirname(configPath);
1206
- const appConfig = await loadAppConfig(configPath);
1158
+ const configDbAbs = await loadAppDbField(configPath);
1207
1159
  const [coreSec, pluginSections, resolved] = await Promise.all([
1208
1160
  this.trace("build-core-section", () => buildCoreSection()),
1209
- this.trace("discover-sections", () => discoverSections(configPath)),
1161
+ this.trace("discover-sections", () => discoverSections()),
1210
1162
  resolveDbPath(process.argv, {
1211
- configDb: appConfig.db,
1163
+ configDb: configDbAbs,
1212
1164
  configDir,
1213
1165
  configPath
1214
1166
  })
@@ -1282,6 +1234,7 @@ var DbService = class extends Service {
1282
1234
  runtime.register(DbService, import.meta);
1283
1235
  //#endregion
1284
1236
  //#region src/services/view-registry.ts
1237
+ var view_registry_exports = /* @__PURE__ */ __exportAll({ ViewRegistryService: () => ViewRegistryService });
1285
1238
  const log$1 = createLogger("view-registry");
1286
1239
  var ViewRegistryService = class extends Service {
1287
1240
  static key = "view-registry";
@@ -1340,7 +1293,7 @@ var ViewRegistryService = class extends Service {
1340
1293
  return this.views.get(scope);
1341
1294
  }
1342
1295
  evaluate() {
1343
- this.loadManifestIcons().catch((err) => {});
1296
+ this.loadManifestIcons();
1344
1297
  this.syncToDb();
1345
1298
  this.setup("view-registry-cleanup", () => {
1346
1299
  return async () => {
@@ -1350,23 +1303,12 @@ var ViewRegistryService = class extends Service {
1350
1303
  };
1351
1304
  });
1352
1305
  }
1353
- async loadManifestIcons() {
1306
+ loadManifestIcons() {
1354
1307
  this.manifestIcons.clear();
1355
- try {
1356
- const configPath = await resolveConfigPath();
1357
- let raw;
1358
- try {
1359
- raw = await fsp.readFile(configPath, "utf8");
1360
- } catch {
1361
- return;
1362
- }
1363
- const config = parseJsonc$1(raw);
1364
- for (const manifestPath of config.plugins ?? []) try {
1365
- const manifestRaw = await fsp.readFile(manifestPath, "utf8");
1366
- const icons = JSON.parse(manifestRaw).icons ?? {};
1367
- for (const [scope, svg] of Object.entries(icons)) this.manifestIcons.set(scope, svg);
1368
- } catch {}
1369
- } catch {}
1308
+ for (const plugin of getPlugins()) {
1309
+ if (!plugin.icons) continue;
1310
+ for (const [scope, svg] of Object.entries(plugin.icons)) this.manifestIcons.set(scope, svg);
1311
+ }
1370
1312
  }
1371
1313
  async syncToDb() {
1372
1314
  const client = this.ctx.db.effectClient;
@@ -1382,44 +1324,13 @@ var ViewRegistryService = class extends Service {
1382
1324
  })).catch((err) => {});
1383
1325
  }
1384
1326
  };
1385
- async function resolveConfigPath() {
1386
- if (process.env.ZENBU_CONFIG_PATH) return process.env.ZENBU_CONFIG_PATH;
1387
- const jsonc = path.join(os.homedir(), ".zenbu", "config.jsonc");
1388
- try {
1389
- await fsp.access(jsonc);
1390
- return jsonc;
1391
- } catch {
1392
- return path.join(os.homedir(), ".zenbu", "config.json");
1393
- }
1394
- }
1395
- function parseJsonc$1(str) {
1396
- let result = "";
1397
- let i = 0;
1398
- while (i < str.length) if (str[i] === "\"") {
1399
- let j = i + 1;
1400
- while (j < str.length) if (str[j] === "\\") j += 2;
1401
- else if (str[j] === "\"") {
1402
- j++;
1403
- break;
1404
- } else j++;
1405
- result += str.slice(i, j);
1406
- i = j;
1407
- } else if (str[i] === "/" && str[i + 1] === "/") {
1408
- i += 2;
1409
- while (i < str.length && str[i] !== "\n") i++;
1410
- } else if (str[i] === "/" && str[i + 1] === "*") {
1411
- i += 2;
1412
- while (i < str.length && !(str[i] === "*" && str[i + 1] === "/")) i++;
1413
- i += 2;
1414
- } else {
1415
- result += str[i];
1416
- i++;
1417
- }
1418
- return JSON.parse(result.replace(/,\s*([\]}])/g, "$1"));
1419
- }
1420
1327
  runtime.register(ViewRegistryService, import.meta);
1421
1328
  //#endregion
1422
1329
  //#region src/services/renderer-host.ts
1330
+ var renderer_host_exports = /* @__PURE__ */ __exportAll({
1331
+ APP_RENDERER_RELOADER_ID: () => "app",
1332
+ RendererHostService: () => RendererHostService
1333
+ });
1423
1334
  const log = createLogger("renderer-host");
1424
1335
  async function pathExists(filePath) {
1425
1336
  try {
@@ -1429,59 +1340,26 @@ async function pathExists(filePath) {
1429
1340
  return false;
1430
1341
  }
1431
1342
  }
1432
- function parseJsonc(str) {
1433
- let result = "";
1434
- let i = 0;
1435
- while (i < str.length) if (str[i] === "\"") {
1436
- let j = i + 1;
1437
- while (j < str.length) if (str[j] === "\\") j += 2;
1438
- else if (str[j] === "\"") {
1439
- j++;
1440
- break;
1441
- } else j++;
1442
- result += str.slice(i, j);
1443
- i = j;
1444
- } else if (str[i] === "/" && str[i + 1] === "/") {
1445
- i += 2;
1446
- while (i < str.length && str[i] !== "\n") i++;
1447
- } else if (str[i] === "/" && str[i + 1] === "*") {
1448
- i += 2;
1449
- while (i < str.length && !(str[i] === "*" && str[i + 1] === "/")) i++;
1450
- i += 2;
1451
- } else {
1452
- result += str[i];
1453
- i++;
1454
- }
1455
- return JSON.parse(result.replace(/,\s*([\]}])/g, "$1"));
1456
- }
1343
+ /**
1344
+ * The app's renderer root is the `uiEntrypoint` directory in
1345
+ * `zenbu.config.ts`. Vite's `root` resolves to it, and `index.html` inside
1346
+ * it is served through Vite. `splash.html` (sibling) is loaded raw — see
1347
+ * `setup-gate.spawnSplashWindow`.
1348
+ *
1349
+ * `vite.config.ts` is picked up from the project root if present (sibling
1350
+ * of `zenbu.config.ts`).
1351
+ */
1457
1352
  async function resolveRendererRoot() {
1353
+ const rendererRoot = getAppEntrypoint();
1354
+ if (!rendererRoot) throw new Error("[renderer-host] no `uiEntrypoint` registered. Set `uiEntrypoint` in zenbu.config.ts before starting the app.");
1355
+ if (!await pathExists(rendererRoot)) throw new Error(`[renderer-host] uiEntrypoint directory does not exist: ${rendererRoot}.`);
1458
1356
  const configPath = process.env.ZENBU_CONFIG_PATH;
1459
- if (!configPath) throw new Error("ZENBU_CONFIG_PATH is required to resolve the app renderer");
1460
- const config = parseJsonc(await fsp.readFile(configPath, "utf8"));
1461
- const configDir = path.dirname(configPath);
1462
- for (const manifestRel of config.plugins ?? []) {
1463
- const resolvedManifest = path.isAbsolute(manifestRel) ? manifestRel : path.resolve(configDir, manifestRel);
1464
- try {
1465
- const manifest = JSON.parse(await fsp.readFile(resolvedManifest, "utf8"));
1466
- if (!manifest.uiEntrypoint) continue;
1467
- const projectDir = path.dirname(resolvedManifest);
1468
- const rendererDir = path.resolve(projectDir, manifest.uiEntrypoint);
1469
- const viteConfig = path.join(projectDir, "vite.config.ts");
1470
- const configFile = await pathExists(viteConfig) ? viteConfig : false;
1471
- if (!await pathExists(rendererDir)) continue;
1472
- return {
1473
- rendererRoot: rendererDir,
1474
- configFile
1475
- };
1476
- } catch {}
1477
- }
1478
- const rendererDir = path.resolve(configDir, "src", "renderer");
1479
- const viteConfig = path.join(configDir, "vite.config.ts");
1480
- if (await pathExists(rendererDir)) return {
1481
- rendererRoot: rendererDir,
1357
+ const projectDir = configPath ? path.dirname(configPath) : rendererRoot;
1358
+ const viteConfig = path.join(projectDir, "vite.config.ts");
1359
+ return {
1360
+ rendererRoot,
1482
1361
  configFile: await pathExists(viteConfig) ? viteConfig : false
1483
1362
  };
1484
- throw new Error(`No renderer entrypoint found. Add uiEntrypoint to the app plugin manifest or create ${rendererDir}.`);
1485
1363
  }
1486
1364
  var RendererHostService = class extends Service {
1487
1365
  static key = "renderer-host";
@@ -1505,4 +1383,4 @@ var RendererHostService = class extends Service {
1505
1383
  };
1506
1384
  runtime.register(RendererHostService, import.meta);
1507
1385
  //#endregion
1508
- export { resolveManifestModulePath as a, discoverSections as i, ViewRegistryService as n, HttpService as o, DbService as r, RendererHostService as t };
1386
+ export { DbService as a, http_exports as c, view_registry_exports as i, renderer_host_exports as n, db_exports as o, ViewRegistryService as r, HttpService as s, RendererHostService as t };
@@ -1,8 +1,10 @@
1
- import { i as runtime, t as Service } from "./runtime-DUFKDIe4.mjs";
2
- import { t as createLogger } from "./log-CyKv8hQg.mjs";
3
- import { o as HttpService } from "./renderer-host-Bg8QdeeH.mjs";
4
- import { n as createRpcRouter, r as createServer } from "./src-pELM4_iH.mjs";
1
+ import { n as __exportAll } from "./chunk-DsiFFCwN.mjs";
2
+ import { Service, runtime } from "./runtime.mjs";
3
+ import { t as createLogger } from "./log-6rzaCV0I.mjs";
4
+ import { s as HttpService } from "./renderer-host-Cau9JK0v.mjs";
5
+ import { n as createRpcRouter, r as createServer } from "./src-Cven45mq.mjs";
5
6
  //#region src/services/rpc.ts
7
+ var rpc_exports = /* @__PURE__ */ __exportAll({ RpcService: () => RpcService });
6
8
  const log = createLogger("rpc");
7
9
  var RpcService = class extends Service {
8
10
  static key = "rpc";
@@ -68,4 +70,4 @@ var RpcService = class extends Service {
68
70
  };
69
71
  runtime.register(RpcService, import.meta);
70
72
  //#endregion
71
- export { RpcService as t };
73
+ export { rpc_exports as n, RpcService as t };
package/dist/rpc.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { n as EventProxy, r as RouterProxy, t as connectRpc } from "./index-Bhlbyrn7.mjs";
1
+ import { n as EventProxy, r as RouterProxy, t as connectRpc } from "./index-C-ALz_SH.mjs";
2
2
  export { type EventProxy, type RouterProxy, connectRpc };
package/dist/rpc.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { t as connectRpc } from "./src-pELM4_iH.mjs";
1
+ import { t as connectRpc } from "./src-Cven45mq.mjs";
2
2
  export { connectRpc };
@@ -105,5 +105,77 @@ declare class ServiceRuntime {
105
105
  private topologicalLevels;
106
106
  }
107
107
  declare const runtime: ServiceRuntime;
108
+ /**
109
+ * A plugin manifest after the loader has resolved every relative path to
110
+ * absolute. Mirrors `ResolvedPlugin` in `cli/lib/build-config.ts` but is
111
+ * declared inline here to avoid runtime.ts importing CLI code.
112
+ */
113
+ interface PluginRecord {
114
+ name: string;
115
+ dir: string;
116
+ services: string[];
117
+ schemaPath?: string;
118
+ migrationsPath?: string;
119
+ preloadPath?: string;
120
+ eventsPath?: string;
121
+ icons?: Record<string, string>;
122
+ }
123
+ /**
124
+ * Live snapshot of the resolved Zenbu config. Returned by `getConfig()` and
125
+ * delivered to `subscribeConfig` callbacks. Re-emitted whenever the loader
126
+ * regenerates the plugin barrel — i.e. on every edit to `zenbu.config.ts`
127
+ * or any imported `zenbu.plugin.ts`.
128
+ */
129
+ interface ConfigSnapshot {
130
+ plugins: PluginRecord[];
131
+ /** Absolute path of the renderer entrypoint directory. */
132
+ appEntrypoint: string | null;
133
+ /** Absolute path of `splash.html` inside the entrypoint dir. */
134
+ splashPath: string | null;
135
+ }
136
+ /**
137
+ * Register a plugin's resolved manifest. Idempotent — replaces any existing
138
+ * entry for the same `name`. Called by the loader-emitted barrel; user code
139
+ * normally does not call this directly.
140
+ */
141
+ declare function registerPlugin(record: PluginRecord): void;
142
+ /**
143
+ * Drop a plugin from the registry. Used when the loader regenerates the
144
+ * barrel and needs to clear stale entries.
145
+ */
146
+ declare function unregisterPlugin(name: string): void;
147
+ /**
148
+ * Replace the entire plugin set in one shot. The loader uses this on every
149
+ * barrel regeneration so removed plugins disappear cleanly.
150
+ */
151
+ declare function replacePlugins(records: PluginRecord[]): void;
152
+ declare function getPlugins(): PluginRecord[];
153
+ declare function getPlugin(name: string): PluginRecord | undefined;
154
+ /**
155
+ * Set the renderer entrypoint directory + the absolute path to splash.html
156
+ * inside it. Called once by the loader-emitted barrel. Consumers
157
+ * (`view-registry`, `vite-plugins`, `setup-gate`'s splash window) read
158
+ * via `getAppEntrypoint()` / `getSplashPath()`.
159
+ */
160
+ declare function registerAppEntrypoint(rendererDir: string, splashPath: string): void;
161
+ declare function getAppEntrypoint(): string | null;
162
+ declare function getSplashPath(): string | null;
163
+ /**
164
+ * Snapshot of the current resolved config — plugins + entrypoints. Cheap;
165
+ * just walks the in-memory registry. The returned object is a fresh copy,
166
+ * safe to retain or pass through serialization boundaries.
167
+ */
168
+ declare function getConfig(): ConfigSnapshot;
169
+ /**
170
+ * Subscribe to config changes. The callback fires:
171
+ * - immediately on subscription (with the current snapshot),
172
+ * - after each `replacePlugins(...)` / `registerPlugin(...)` /
173
+ * `registerAppEntrypoint(...)` call — i.e. every time the loader
174
+ * regenerates the plugin barrel after a `zenbu.config.ts` edit.
175
+ *
176
+ * Callback exceptions are logged and swallowed so one buggy subscriber
177
+ * can't break others. The returned function unsubscribes.
178
+ */
179
+ declare function subscribeConfig(callback: (snapshot: ConfigSnapshot) => void): () => void;
108
180
  //#endregion
109
- export { runtime as a, optional as i, Service as n, serviceWithDeps as o, ServiceRuntime as r, CleanupReason as t };
181
+ export { subscribeConfig as _, ServiceRuntime as a, getPlugin as c, optional as d, registerAppEntrypoint as f, serviceWithDeps as g, runtime as h, Service as i, getPlugins as l, replacePlugins as m, ConfigSnapshot as n, getAppEntrypoint as o, registerPlugin as p, PluginRecord as r, getConfig as s, CleanupReason as t, getSplashPath as u, unregisterPlugin as v };
@@ -1,2 +1,2 @@
1
- import { a as runtime, i as optional, n as Service, o as serviceWithDeps, r as ServiceRuntime, t as CleanupReason } from "./runtime-CjqDr8Yf.mjs";
2
- export { CleanupReason, Service, ServiceRuntime, optional, runtime, serviceWithDeps };
1
+ import { _ as subscribeConfig, a as ServiceRuntime, c as getPlugin, d as optional, f as registerAppEntrypoint, g as serviceWithDeps, h as runtime, i as Service, l as getPlugins, m as replacePlugins, n as ConfigSnapshot, o as getAppEntrypoint, p as registerPlugin, r as PluginRecord, s as getConfig, t as CleanupReason, u as getSplashPath, v as unregisterPlugin } from "./runtime-pCeVzj--.mjs";
2
+ export { CleanupReason, ConfigSnapshot, PluginRecord, Service, ServiceRuntime, getAppEntrypoint, getConfig, getPlugin, getPlugins, getSplashPath, optional, registerAppEntrypoint, registerPlugin, replacePlugins, runtime, serviceWithDeps, subscribeConfig, unregisterPlugin };