@zenbujs/core 0.0.4 → 0.0.8

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 (106) hide show
  1. package/dist/{advice-config-BLXjqjGN.mjs → advice-config-DXSIo0sg.mjs} +49 -38
  2. package/dist/advice.d.mts +8 -8
  3. package/dist/advice.mjs +2 -2
  4. package/dist/base-window-BxBZ2md_.mjs +143 -0
  5. package/dist/build-config-Dzg2frpk.d.mts +215 -0
  6. package/dist/build-config-pWdmLnrk.mjs +53 -0
  7. package/dist/{build-electron-C3Beey84.mjs → build-electron-Dsbb1EMl.mjs} +308 -120
  8. package/dist/{build-source-BvC4bPqH.mjs → build-source-d1J3shV8.mjs} +62 -27
  9. package/dist/chunk-DsiFFCwN.mjs +16 -0
  10. package/dist/cli/bin.mjs +7 -7
  11. package/dist/cli/build.d.mts +2 -2
  12. package/dist/cli/build.mjs +2 -3
  13. package/dist/cli/resolve-config.mjs +3 -2
  14. package/dist/{cli-F0B4dvSg.mjs → cli-kL6mPgBE.mjs} +4 -4
  15. package/dist/{config-BlRXeUXx.mjs → config-BK78JDRI.mjs} +1 -1
  16. package/dist/config.d.mts +3 -2
  17. package/dist/config.mjs +3 -3
  18. package/dist/{db-Cd5ETuPG.mjs → db-Bc292RYo.mjs} +2 -2
  19. package/dist/db.d.mts +1 -1
  20. package/dist/db.mjs +2 -2
  21. package/dist/dev-B2emj0HZ.mjs +301 -0
  22. package/dist/env-bootstrap.d.mts +1 -1
  23. package/dist/env-bootstrap.mjs +52 -1
  24. package/dist/events.d.mts +19 -0
  25. package/dist/events.mjs +1 -0
  26. package/dist/host-version-BIrF8tX7.mjs +65 -0
  27. package/dist/index-w5QyDjuf.d.mts +780 -0
  28. package/dist/index.d.mts +5 -6
  29. package/dist/index.mjs +5 -5
  30. package/dist/installing-preload.cjs +60 -0
  31. package/dist/launcher.mjs +2615 -122
  32. package/dist/{link-BJmsKgPa.mjs → link-glX89NV5.mjs} +215 -89
  33. package/dist/{load-config-BG2tPIfF.mjs → load-config-C4Oe2qZO.mjs} +22 -3
  34. package/dist/loaders/zenbu.d.mts +1 -0
  35. package/dist/loaders/zenbu.mjs +108 -86
  36. package/dist/{monorepo-DCruz9Jx.mjs → monorepo-Dct-kkbQ.mjs} +3 -0
  37. package/dist/node-loader.mjs +1 -1
  38. package/dist/{publish-source-34Hn9zb0.mjs → publish-source-Dq2c0iOw.mjs} +2 -2
  39. package/dist/react.d.mts +56 -7
  40. package/dist/react.mjs +118 -7
  41. package/dist/registry-CMp8FYgS.d.mts +47 -0
  42. package/dist/registry-generated.d.mts +26 -0
  43. package/dist/registry-generated.mjs +1 -0
  44. package/dist/registry.d.mts +2 -2
  45. package/dist/{reloader-DJoCB0bC.mjs → reloader-B22UiNA2.mjs} +7 -7
  46. package/dist/{renderer-host-ztaSIOGx.mjs → renderer-host-DD16MXhI.mjs} +178 -57
  47. package/dist/{rpc-CsgWnlZx.mjs → rpc-C4_NQmpT.mjs} +11 -8
  48. package/dist/rpc.d.mts +1 -1
  49. package/dist/rpc.mjs +1 -1
  50. package/dist/runtime-BQWntcOb.d.mts +218 -0
  51. package/dist/runtime.d.mts +2 -2
  52. package/dist/runtime.mjs +578 -2
  53. package/dist/{schema-DvT61x2_.d.mts → schema-CjrMVk36.d.mts} +3 -3
  54. package/dist/schema.d.mts +1 -1
  55. package/dist/schema.mjs +27 -1
  56. package/dist/{server-DB3Eki_G.mjs → server-CZLMF8Dj.mjs} +6 -6
  57. package/dist/services/default.d.mts +3 -3
  58. package/dist/services/default.mjs +14 -13
  59. package/dist/services/index.d.mts +2 -276
  60. package/dist/services/index.mjs +8 -7
  61. package/dist/setup-gate.d.mts +1 -1
  62. package/dist/setup-gate.mjs +341 -1
  63. package/dist/{transform-DJH3vN4b.mjs → transform-BzrwkEdf.mjs} +23 -917
  64. package/dist/{transport-BMSzG2-F.mjs → transport-F2hv_OEm.mjs} +1 -1
  65. package/dist/updater-DCkz9M1c.mjs +1008 -0
  66. package/dist/{vite-plugins-t4MlFcz3.mjs → vite-plugins-tt6KAtyE.mjs} +27 -26
  67. package/dist/vite.d.mts +3 -3
  68. package/dist/vite.mjs +1 -1
  69. package/dist/{window-DUvMTons.mjs → window-YFKvAM0l.mjs} +36 -19
  70. package/dist/{write-9dRFczGJ.mjs → write-DgIRjo23.mjs} +1 -1
  71. package/package.json +18 -5
  72. package/dist/advice-config-D6K_a7e9.mjs +0 -2
  73. package/dist/base-window-D8CpxMU3.mjs +0 -94
  74. package/dist/base-window-OXg2KSyP.mjs +0 -2
  75. package/dist/build-config-BwnnfrN-.mjs +0 -23
  76. package/dist/chunk-Dm34NbLt.mjs +0 -6
  77. package/dist/config-Ch1FreWU.mjs +0 -2
  78. package/dist/db-Bz_CDIWg.mjs +0 -2
  79. package/dist/dev-DLutFPyo.mjs +0 -85
  80. package/dist/env-bootstrap-rj7I-59x.mjs +0 -53
  81. package/dist/http-B36qtsm0.mjs +0 -2
  82. package/dist/load-config-CQG4297M.mjs +0 -2
  83. package/dist/registry-CioEYLI5.d.mts +0 -61
  84. package/dist/reloader-FeHKV2jd.mjs +0 -2
  85. package/dist/renderer-host-BQpS0ZM2.mjs +0 -2
  86. package/dist/rpc-D_s7-WZe.mjs +0 -2
  87. package/dist/runtime-C95iyVn6.mjs +0 -461
  88. package/dist/runtime-CsiDppGF.d.mts +0 -149
  89. package/dist/schema-dGK6qkfR.mjs +0 -28
  90. package/dist/server-CgzQOPSW.mjs +0 -2
  91. package/dist/setup-gate-D8XfYY52.mjs +0 -140
  92. package/dist/transforms-DVoy8dCu.mjs +0 -47
  93. package/dist/transforms-EVd5Fgyk.d.mts +0 -136
  94. package/dist/view-registry-2zePxTEg.mjs +0 -2
  95. package/dist/window-S3TlTXlK.mjs +0 -2
  96. /package/dist/{env-bootstrap-uCKbw2q8.d.mts → env-bootstrap-rTs8KR3-.d.mts} +0 -0
  97. /package/dist/{index-CE0iPntP.d.mts → index-C-ALz_SH.d.mts} +0 -0
  98. /package/dist/{index-CKKoxA9V.d.mts → index-ClXLQ1fw.d.mts} +0 -0
  99. /package/dist/{index-UK58xuoR.d.mts → index-DeDxePAa.d.mts} +0 -0
  100. /package/dist/{log-CyKv8hQg.mjs → log-6rzaCV0I.mjs} +0 -0
  101. /package/dist/{mirror-sync-EiWvdzTJ.mjs → mirror-sync-pYU6f3-c.mjs} +0 -0
  102. /package/dist/{node-CvZnTx53.mjs → node-BhfLKYCi.mjs} +0 -0
  103. /package/dist/{schema-CIg4GzHQ.mjs → schema-Ca7SxXgS.mjs} +0 -0
  104. /package/dist/{setup-gate-D62nX5lk.d.mts → setup-gate-BQq0QgZH.d.mts} +0 -0
  105. /package/dist/{src-pELM4_iH.mjs → src-Cven45mq.mjs} +0 -0
  106. /package/dist/{trace-DCB7qFzT.mjs → trace-BaVg0rnY.mjs} +0 -0
@@ -2,21 +2,22 @@
2
2
  /**
3
3
  * Loads and registers all built-in services. Kept separate from
4
4
  * `./index.ts` (which statically re-exports the service classes for
5
- * `serviceWithDeps(...)` consumers) so that `setup-gate` can import it without
6
- * eagerly loading every service module before `setupGate()` has had a
7
- * chance to bootstrap env vars and `process.chdir(projectRoot)`.
5
+ * `Service.withDeps(...)` consumers) so that `setup-gate` can import it
6
+ * without eagerly loading every service module before `setupGate()` has
7
+ * had a chance to bootstrap env vars and `process.chdir(projectRoot)`.
8
8
  */
9
9
  async function defaultServices() {
10
- await import("../server-CgzQOPSW.mjs");
11
- await import("../reloader-FeHKV2jd.mjs");
12
- await import("../renderer-host-BQpS0ZM2.mjs");
13
- await import("../http-B36qtsm0.mjs");
14
- await import("../db-Bz_CDIWg.mjs");
15
- await import("../base-window-OXg2KSyP.mjs");
16
- await import("../rpc-D_s7-WZe.mjs");
17
- await import("../view-registry-2zePxTEg.mjs");
18
- await import("../window-S3TlTXlK.mjs");
19
- await import("../advice-config-D6K_a7e9.mjs");
10
+ await import("../server-CZLMF8Dj.mjs").then((n) => n.n);
11
+ await import("../reloader-B22UiNA2.mjs").then((n) => n.n);
12
+ await import("../renderer-host-DD16MXhI.mjs").then((n) => n.n);
13
+ await import("../renderer-host-DD16MXhI.mjs").then((n) => n.c);
14
+ await import("../renderer-host-DD16MXhI.mjs").then((n) => n.o);
15
+ await import("../base-window-BxBZ2md_.mjs").then((n) => n.r);
16
+ await import("../rpc-C4_NQmpT.mjs").then((n) => n.n);
17
+ await import("../renderer-host-DD16MXhI.mjs").then((n) => n.i);
18
+ await import("../window-YFKvAM0l.mjs").then((n) => n.n);
19
+ await import("../advice-config-DXSIo0sg.mjs").then((n) => n.t);
20
+ await import("../updater-DCkz9M1c.mjs").then((n) => n.n);
20
21
  }
21
22
  //#endregion
22
23
  export { defaultServices };
@@ -1,276 +1,2 @@
1
- import { c as EffectFieldNode, d as KyjuError, l as FieldNode, r as createRouter, t as Db } from "../index-UK58xuoR.mjs";
2
- import { r as Service, t as CleanupReason } from "../runtime-CsiDppGF.mjs";
3
- import { o as ResolvedDbRoot, s as ResolvedEvents } from "../registry-CioEYLI5.mjs";
4
- import http from "node:http";
5
- import { WebSocket, WebSocketServer } from "ws";
6
- import { ViteDevServer } from "vite";
7
- import * as Effect from "effect/Effect";
8
- import { BaseWindow } from "electron";
9
- import * as _$stream from "stream";
10
-
11
- //#region src/services/server.d.ts
12
- type UpgradeHandler = (req: http.IncomingMessage, socket: _$stream.Duplex, head: Buffer) => boolean;
13
- declare class ServerService extends Service {
14
- static key: string;
15
- static deps: {};
16
- server: http.Server | null;
17
- wss: WebSocketServer | null;
18
- port: number;
19
- authToken: string;
20
- private upgradeHandlers;
21
- addUpgradeHandler(handler: UpgradeHandler): () => void;
22
- evaluate(): Promise<void>;
23
- private isAuthorizedUpgrade;
24
- }
25
- //#endregion
26
- //#region src/services/reloader.d.ts
27
- interface ReloaderEntry {
28
- id: string;
29
- root: string;
30
- url: string;
31
- port: number;
32
- viteServer: ViteDevServer;
33
- }
34
- declare class ReloaderService extends Service {
35
- static key: string;
36
- static deps: {};
37
- private servers;
38
- create(id: string, root: string, configFile?: string | false): Promise<ReloaderEntry>;
39
- get(id: string): ReloaderEntry | undefined;
40
- remove(id: string): Promise<void>;
41
- evaluate(): void;
42
- }
43
- //#endregion
44
- //#region src/services/http.d.ts
45
- type ConnectedCallback = (id: string, ws: WebSocket) => void;
46
- type DisconnectedCallback = (id: string) => void;
47
- type RequestHandler = (req: http.IncomingMessage, res: http.ServerResponse) => void;
48
- declare class HttpService extends Service {
49
- static key: string;
50
- static deps: {
51
- server: typeof ServerService;
52
- reloader: typeof ReloaderService;
53
- };
54
- ctx: {
55
- server: ServerService;
56
- reloader: ReloaderService;
57
- };
58
- connectedCallbacks: ConnectedCallback[];
59
- disconnectedCallbacks: DisconnectedCallback[];
60
- activeConnections: Map<string, WebSocket>;
61
- private requestHandlers;
62
- get port(): number;
63
- get authToken(): string;
64
- addRequestHandler(prefix: string, handler: RequestHandler): () => void;
65
- onConnected(cb: ConnectedCallback): () => void;
66
- onDisconnected(cb: DisconnectedCallback): () => void;
67
- evaluate(): void;
68
- }
69
- //#endregion
70
- //#region src/services/db.d.ts
71
- type EffectSectionProxy<S> = { [K in keyof S]: EffectFieldNode<S[K]> };
72
- type SectionProxy<S> = { [K in keyof S]: FieldNode<S[K]> };
73
- type Root = ResolvedDbRoot;
74
- type Plugin$1 = Root extends {
75
- plugin: infer P;
76
- } ? P : never;
77
- type SectionedEffectClient = {
78
- readRoot(): Root;
79
- update(fn: (root: Root) => void | Root): Effect.Effect<void, KyjuError>;
80
- createBlob(data: Uint8Array, hot?: boolean): Effect.Effect<string, KyjuError>;
81
- deleteBlob(blobId: string): Effect.Effect<void, KyjuError>;
82
- getBlobData(blobId: string): Effect.Effect<Uint8Array | null, KyjuError>;
83
- plugin: { [K in keyof Plugin$1]: EffectSectionProxy<Plugin$1[K]> };
84
- };
85
- type SectionedClient = {
86
- readRoot(): Root;
87
- update(fn: (root: Root) => void | Root): Promise<void>;
88
- createBlob(data: Uint8Array, hot?: boolean): Promise<string>;
89
- deleteBlob(blobId: string): Promise<void>;
90
- getBlobData(blobId: string): Promise<Uint8Array | null>;
91
- plugin: { [K in keyof Plugin$1]: SectionProxy<Plugin$1[K]> };
92
- };
93
- declare class DbService extends Service {
94
- static key: string;
95
- static deps: {
96
- http: typeof HttpService;
97
- };
98
- ctx: {
99
- http: HttpService;
100
- };
101
- db: Db | null;
102
- dbRouter: ReturnType<typeof createRouter> | null;
103
- private sectionsHash;
104
- private _dbPath;
105
- /**
106
- * Resolved DB path. Throws if accessed before `evaluate()` has run — the
107
- * service contract guarantees deps are evaluated before dependents, so any
108
- * access from a dependent service or RPC handler is safe.
109
- */
110
- get dbPath(): string;
111
- get client(): SectionedClient;
112
- get effectClient(): SectionedEffectClient;
113
- /**
114
- * Drain kyju's lagged-persistence queue. Safe to call anytime; idempotent
115
- * when nothing is pending. Used by service teardown (effect cleanup) so
116
- * shutdown / hot-reload don't lose in-memory writes.
117
- */
118
- flush(): Promise<void>;
119
- /**
120
- * Flush + release the kyju cross-process lock at `<dbPath>/.lock`.
121
- * Called on service teardown so a subsequent process can open the DB
122
- * without seeing a stale lock. Idempotent.
123
- */
124
- close(): Promise<void>;
125
- evaluate(): Promise<void>;
126
- }
127
- //#endregion
128
- //#region src/services/view-registry.d.ts
129
- interface ViewEntry {
130
- scope: string;
131
- url: string;
132
- port: number;
133
- ownsServer: boolean;
134
- meta?: {
135
- kind?: string;
136
- sidebar?: boolean;
137
- bottomPanel?: boolean;
138
- label?: string;
139
- };
140
- }
141
- declare class ViewRegistryService extends Service {
142
- static key: string;
143
- static deps: {
144
- reloader: typeof ReloaderService;
145
- db: typeof DbService;
146
- };
147
- ctx: {
148
- reloader: ReloaderService;
149
- db: DbService;
150
- };
151
- private views;
152
- private manifestIcons;
153
- register(scope: string, root: string, configFile?: string | false, meta?: {
154
- kind?: string;
155
- sidebar?: boolean;
156
- bottomPanel?: boolean;
157
- label?: string;
158
- }): Promise<ViewEntry>;
159
- registerAlias(scope: string, reloaderId: string, pathPrefix: string, meta?: {
160
- kind?: string;
161
- sidebar?: boolean;
162
- bottomPanel?: boolean;
163
- label?: string;
164
- }): ViewEntry;
165
- unregister(scope: string): Promise<void>;
166
- get(scope: string): ViewEntry | undefined;
167
- evaluate(): void;
168
- private loadManifestIcons;
169
- private syncToDb;
170
- }
171
- //#endregion
172
- //#region src/services/renderer-host.d.ts
173
- declare class RendererHostService extends Service {
174
- static key: string;
175
- static deps: {
176
- reloader: typeof ReloaderService;
177
- viewRegistry: typeof ViewRegistryService;
178
- };
179
- ctx: {
180
- reloader: ReloaderService;
181
- viewRegistry: ViewRegistryService;
182
- };
183
- url: string;
184
- port: number;
185
- evaluate(): Promise<void>;
186
- }
187
- //#endregion
188
- //#region src/services/base-window.d.ts
189
- declare const MAIN_WINDOW_ID = "main";
190
- type WindowBounds = {
191
- x: number;
192
- y: number;
193
- width: number;
194
- height: number;
195
- };
196
- declare class BaseWindowService extends Service {
197
- static key: string;
198
- static deps: {
199
- db: typeof DbService;
200
- };
201
- ctx: {
202
- db: DbService;
203
- };
204
- windows: Map<string, BaseWindow>;
205
- private get bootWindows();
206
- private set bootWindows(value);
207
- private getZenWidth;
208
- getWindowId(win: BaseWindow): string | undefined;
209
- createWindow(opts?: Partial<WindowBounds> & {
210
- windowId?: string;
211
- show?: boolean;
212
- }): {
213
- win: BaseWindow;
214
- windowId: string;
215
- };
216
- evaluate(): void;
217
- }
218
- //#endregion
219
- //#region src/services/rpc.d.ts
220
- type EmitProxy<T> = { [K in keyof T]: T[K] extends Record<string, any> ? EmitProxy<T[K]> & ((data: T[K]) => void) : (data: T[K]) => void };
221
- declare class RpcService extends Service {
222
- static key: string;
223
- static deps: {
224
- http: typeof HttpService;
225
- };
226
- ctx: {
227
- http: HttpService;
228
- };
229
- private _emit;
230
- get emit(): EmitProxy<ResolvedEvents>;
231
- evaluate(): void;
232
- }
233
- //#endregion
234
- //#region src/services/window.d.ts
235
- declare const WindowService_base: (abstract new () => {
236
- ctx: {
237
- baseWindow: BaseWindowService;
238
- viewRegistry: ViewRegistryService;
239
- http: HttpService;
240
- rendererHost: RendererHostService;
241
- };
242
- __setupCleanups: Map<string, (reason: CleanupReason) => void | Promise<void>>;
243
- evaluate(): void | Promise<void>;
244
- setup(key: string, fn: () => void | ((reason: CleanupReason) => void | Promise<void>)): void;
245
- trace<T>(_name: string, fn: () => T | Promise<T>, _meta?: Record<string, unknown>): Promise<T>;
246
- traceSync<T>(_name: string, fn: () => T, _meta?: Record<string, unknown>): T;
247
- __cleanupAllSetups(reason?: CleanupReason): Promise<void>;
248
- }) & {
249
- deps: Record<string, (string | (abstract new (...args: any[]) => Service)) | {
250
- __optional: true;
251
- ref: string | (abstract new (...args: any[]) => Service);
252
- }>;
253
- key: string;
254
- };
255
- declare class WindowService extends WindowService_base {
256
- static key: string;
257
- private mounted;
258
- evaluate(): void;
259
- openView(args: {
260
- scope: string;
261
- windowId?: string;
262
- query?: Record<string, string | number | boolean | null | undefined>;
263
- }): Promise<{
264
- windowId: string;
265
- }>;
266
- focusWindow(windowId: string): Promise<{
267
- ok: true;
268
- }>;
269
- pickFiles(): Promise<string[] | null>;
270
- pickDirectory(): Promise<string | null>;
271
- openExternal(url: string): Promise<void>;
272
- openPath(filePath: string): Promise<void>;
273
- copyToClipboard(text: string): void;
274
- }
275
- //#endregion
276
- export { BaseWindowService, DbService, HttpService, MAIN_WINDOW_ID, ReloaderService, RendererHostService, RpcService, ServerService, ViewRegistryService, WindowService };
1
+ import { a as MAIN_WINDOW_ID, c as DbService, d as ServerService, i as BaseWindowService, l as HttpService, n as WindowService, o as RendererHostService, r as RpcService, s as ViewRegistryService, t as UpdaterService, u as ReloaderService } from "../index-w5QyDjuf.mjs";
2
+ export { BaseWindowService, DbService, HttpService, MAIN_WINDOW_ID, ReloaderService, RendererHostService, RpcService, ServerService, UpdaterService, ViewRegistryService, WindowService };
@@ -1,7 +1,8 @@
1
- import { t as ServerService } from "../server-DB3Eki_G.mjs";
2
- import { t as ReloaderService } from "../reloader-DJoCB0bC.mjs";
3
- import { n as ViewRegistryService, o as HttpService, r as DbService, t as RendererHostService } from "../renderer-host-ztaSIOGx.mjs";
4
- import { n as MAIN_WINDOW_ID, t as BaseWindowService } from "../base-window-D8CpxMU3.mjs";
5
- import { t as RpcService } from "../rpc-CsgWnlZx.mjs";
6
- import { t as WindowService } from "../window-DUvMTons.mjs";
7
- export { BaseWindowService, DbService, HttpService, MAIN_WINDOW_ID, ReloaderService, RendererHostService, RpcService, ServerService, ViewRegistryService, WindowService };
1
+ import { t as ServerService } from "../server-CZLMF8Dj.mjs";
2
+ import { t as ReloaderService } from "../reloader-B22UiNA2.mjs";
3
+ import { a as DbService, r as ViewRegistryService, s as HttpService, t as RendererHostService } from "../renderer-host-DD16MXhI.mjs";
4
+ import { n as MAIN_WINDOW_ID, t as BaseWindowService } from "../base-window-BxBZ2md_.mjs";
5
+ import { t as RpcService } from "../rpc-C4_NQmpT.mjs";
6
+ import { t as WindowService } from "../window-YFKvAM0l.mjs";
7
+ import { t as UpdaterService } from "../updater-DCkz9M1c.mjs";
8
+ export { BaseWindowService, DbService, HttpService, MAIN_WINDOW_ID, ReloaderService, RendererHostService, RpcService, ServerService, UpdaterService, ViewRegistryService, WindowService };
@@ -1,2 +1,2 @@
1
- import { t as setupGate } from "./setup-gate-D62nX5lk.mjs";
1
+ import { t as setupGate } from "./setup-gate-BQq0QgZH.mjs";
2
2
  export { setupGate };
@@ -1,2 +1,342 @@
1
- import { t as setupGate } from "./setup-gate-D8XfYY52.mjs";
1
+ import { bootstrapEnv } from "./env-bootstrap.mjs";
2
+ import { createRequire, register } from "node:module";
3
+ import fs from "node:fs";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { pathToFileURL } from "node:url";
7
+ import { register as register$1 } from "tsx/esm/api";
8
+ //#region src/setup-gate.ts
9
+ /**
10
+ * this file is in a really hacky state needs to be fixed
11
+ */
12
+ function registerLoader(specifier, opts) {
13
+ return register(specifier, void 0, opts);
14
+ }
15
+ const verbose = process.env.ZENBU_VERBOSE === "1";
16
+ /**
17
+ * Suppress `@babel/generator`'s "[BABEL] Note: The code generator has
18
+ * deoptimised the styling of <file> as it exceeds the max of 500KB" notice.
19
+ * It's hardcoded as `console.error` in @babel/generator's printer with no
20
+ * opt-out (https://github.com/babel/babel/issues/7569). Vite's
21
+ * `@vitejs/plugin-react` runs Babel for fast-refresh on prebundled deps
22
+ * caches, hitting this for `react-dom_client.js` and similar large chunks
23
+ * on every dev boot. We filter the one specific message at the
24
+ * `console.error` boundary so the rest of console.error stays useful.
25
+ *
26
+ * Patched once at module init, before any Vite dev server has started.
27
+ */
28
+ const _origConsoleError = console.error.bind(console);
29
+ console.error = (...args) => {
30
+ if (args.length > 0 && typeof args[0] === "string" && args[0].startsWith("[BABEL] Note: The code generator has deoptimised")) return;
31
+ _origConsoleError(...args);
32
+ };
33
+ function isPluginModule(value) {
34
+ return typeof value === "object" && value !== null && typeof value.default === "function";
35
+ }
36
+ function isPluginController(value) {
37
+ return typeof value === "object" && value !== null && typeof value.main === "function";
38
+ }
39
+ function envMs(name) {
40
+ const raw = process.env[name];
41
+ if (!raw) return null;
42
+ const value = Number(raw);
43
+ return Number.isFinite(value) && value >= 0 ? value : null;
44
+ }
45
+ function projectArg() {
46
+ const arg = process.argv.find((item) => item.startsWith("--project="));
47
+ return arg ? path.resolve(arg.slice(10)) : null;
48
+ }
49
+ function appDirName(name) {
50
+ return name.replace(/^@/, "").replace(/[\\/]/g, "__");
51
+ }
52
+ function readPackageJson(packageDir) {
53
+ const pkgPath = path.join(packageDir, "package.json");
54
+ return JSON.parse(fs.readFileSync(pkgPath, "utf8"));
55
+ }
56
+ function findProjectRoot(projectDir) {
57
+ let dir = path.resolve(projectDir);
58
+ while (dir !== path.dirname(dir)) {
59
+ if (fs.existsSync(path.join(dir, "package.json"))) return dir;
60
+ dir = path.dirname(dir);
61
+ }
62
+ return path.resolve(projectDir);
63
+ }
64
+ function resolveConfigPath(projectRoot) {
65
+ const candidates = [
66
+ "zenbu.config.ts",
67
+ "zenbu.config.mts",
68
+ "zenbu.config.js",
69
+ "zenbu.config.mjs"
70
+ ];
71
+ for (const name of candidates) {
72
+ const candidate = path.join(projectRoot, name);
73
+ if (fs.existsSync(candidate)) return candidate;
74
+ }
75
+ throw new Error(`No zenbu config found at ${projectRoot}. Expected one of: ${candidates.join(", ")}`);
76
+ }
77
+ function findTsconfig(projectRoot) {
78
+ const candidate = path.join(projectRoot, "tsconfig.json");
79
+ return fs.existsSync(candidate) ? candidate : false;
80
+ }
81
+ function loadElectronApp() {
82
+ const electron = createRequire(import.meta.url)("electron");
83
+ if (!electron.app) throw new Error("Electron app API is unavailable; setup-gate must run inside Electron");
84
+ return electron.app;
85
+ }
86
+ async function closeRegisteredWatchers() {
87
+ await (await import("@zenbujs/hmr/pause")).closeAllWatchers?.();
88
+ }
89
+ /**
90
+ * Extract the splash's intended background color from a
91
+ * `<meta name="zenbu-bg" content="#xxx">` tag. Used as the BaseWindow's
92
+ * `backgroundColor` so the OS doesn't paint a single white frame before
93
+ * the WebContentsView's pixels reach the screen. Convention only —
94
+ * defaults to `#F4F4F4` when unset.
95
+ */
96
+ function readSplashBgColor(splashPath) {
97
+ try {
98
+ const match = fs.readFileSync(splashPath, "utf8").match(/<meta\s+name=["']zenbu-bg["']\s+content=["']([^"']+)["']/i);
99
+ if (match?.[1]) return match[1];
100
+ } catch {}
101
+ return "#F4F4F4";
102
+ }
103
+ /**
104
+ * Spawn the splash window as early as possible OR adopt the launcher's
105
+ * pre-existing installing window. The window is created with `show: true`
106
+ * and its `backgroundColor` set up front so the OS composites a colored
107
+ * frame on the next vsync — no waiting for `did-finish-load` before any
108
+ * pixels reach the screen. Splash content paints into the WebContentsView
109
+ * a frame or two later, replacing the flat color.
110
+ *
111
+ * If the launcher already opened an installing window
112
+ * (`globalThis.__zenbu_boot_windows__` is non-empty), we reuse that
113
+ * BaseWindow and just swap its child WebContentsView from installing.html
114
+ * to splash.html. The titlebar / window chrome stays continuous.
115
+ *
116
+ * `BaseWindowService.evaluate()` adopts the resulting window from
117
+ * `globalThis.__zenbu_boot_windows__` instead of creating a new one, so
118
+ * `WindowService.openView` can swap the splash content view for the
119
+ * Vite-served renderer in-place when the renderer is ready.
120
+ */
121
+ async function spawnSplashWindow(splashPath) {
122
+ if (!splashPath || !fs.existsSync(splashPath)) {
123
+ if (verbose) console.log("[setup-gate] no splash.html resolved; skipping splash window");
124
+ return;
125
+ }
126
+ const slot = globalThis;
127
+ const electron = await import("electron");
128
+ const backgroundColor = readSplashBgColor(splashPath);
129
+ const existing = slot.__zenbu_boot_windows__?.find((b) => b.windowId === "main");
130
+ let win;
131
+ if (existing) {
132
+ win = existing.win;
133
+ try {
134
+ win.setBackgroundColor(backgroundColor);
135
+ } catch {}
136
+ for (const child of [...win.contentView.children]) {
137
+ try {
138
+ win.contentView.removeChildView(child);
139
+ } catch {}
140
+ const wc = child.webContents;
141
+ try {
142
+ wc?.close();
143
+ } catch {}
144
+ }
145
+ if (verbose) console.log("[setup-gate] adopting existing installing window for splash");
146
+ } else win = new electron.BaseWindow({
147
+ width: 1100,
148
+ height: 750,
149
+ titleBarStyle: "hidden",
150
+ trafficLightPosition: {
151
+ x: 14,
152
+ y: 10
153
+ },
154
+ backgroundColor
155
+ });
156
+ const splashView = new electron.WebContentsView();
157
+ win.contentView.addChildView(splashView);
158
+ const bounds = win.getContentBounds();
159
+ splashView.setBounds({
160
+ x: 0,
161
+ y: 0,
162
+ width: bounds.width,
163
+ height: bounds.height
164
+ });
165
+ /**
166
+ * human note: this is a bad solution we should have an invariant verifying program state
167
+ * but its fine for now
168
+ */
169
+ await Promise.race([splashView.webContents.loadFile(splashPath).catch(() => {}), new Promise((resolve) => setTimeout(resolve, 1500))]);
170
+ if (!existing) {
171
+ const boot = {
172
+ windowId: "main",
173
+ win
174
+ };
175
+ slot.__zenbu_boot_windows__ = [...slot.__zenbu_boot_windows__ ?? [], boot];
176
+ }
177
+ if (verbose) console.log("[setup-gate] splash window shown with", splashPath, "bg=", backgroundColor);
178
+ }
179
+ /**
180
+ * Phase 1 of loader setup: register tsx + read the user's `zenbu.config.ts`.
181
+ * This is split out from the rest of the loader registration so the splash
182
+ * window can be spawned the moment `splashPath` is known, instead of
183
+ * waiting for advice + dynohot to register too. tsx must run with the
184
+ * project's tsconfig because user code (config + plugins) may rely on
185
+ * non-default TS settings (paths, jsx, etc.).
186
+ */
187
+ async function loadConfigPhase(tsconfig, projectRoot) {
188
+ register$1({ tsconfig });
189
+ const { loadConfig } = await import("./load-config-C4Oe2qZO.mjs").then((n) => n.n);
190
+ const { resolved, pluginSourceFiles } = await loadConfig(projectRoot);
191
+ const loaderData = {
192
+ payload: {
193
+ plugins: resolved.plugins.map((p) => ({
194
+ name: p.name,
195
+ dir: p.dir,
196
+ services: p.services,
197
+ schemaPath: p.schemaPath,
198
+ migrationsPath: p.migrationsPath,
199
+ preloadPath: p.preloadPath,
200
+ eventsPath: p.eventsPath,
201
+ icons: p.icons
202
+ })),
203
+ appEntrypoint: resolved.uiEntrypointPath,
204
+ splashPath: resolved.splashPath,
205
+ installingPath: resolved.installingPath
206
+ },
207
+ pluginSourceFiles
208
+ };
209
+ globalThis.__zenbu_main_resolved_config__ = loaderData;
210
+ return loaderData;
211
+ }
212
+ /**
213
+ * Phase 2 of loader setup: register the zenbu loader, advice, and dynohot.
214
+ * Runs AFTER the splash window is on screen so the user sees pixels while
215
+ * advice patches install and dynohot's worker spawns. Node 22+ runs loader
216
+ * hooks in a worker thread; the resolved config crosses the boundary via
217
+ * `register()`'s `data` argument.
218
+ */
219
+ async function registerLoadersPhase(projectRoot, loaderData) {
220
+ registerLoader(import.meta.resolve("@zenbujs/core/loaders/zenbu"), { data: loaderData });
221
+ process.env.ZENBU_ADVICE_ROOT = projectRoot;
222
+ await import("./node-BhfLKYCi.mjs");
223
+ const dynohot = await import(pathToFileURL(createRequire(import.meta.url).resolve("@zenbujs/hmr/register")).href);
224
+ if (typeof dynohot.register === "function") dynohot.register({ ignore: /[/\\](?:node_modules|dist)[/\\]/ });
225
+ }
226
+ async function setupGate() {
227
+ const t0 = Date.now();
228
+ const ms = () => `+${Date.now() - t0}ms`;
229
+ const step = (label) => {
230
+ console.log(`[zenbu] ${label} (${ms()})`);
231
+ };
232
+ const app = loadElectronApp();
233
+ await app.whenReady();
234
+ step("electron ready");
235
+ bootstrapEnv();
236
+ let shuttingDown = false;
237
+ const shutdown = async (exitCode = 0) => {
238
+ if (shuttingDown) return;
239
+ shuttingDown = true;
240
+ try {
241
+ await globalThis.__zenbu_service_runtime__?.shutdown();
242
+ } catch (err) {
243
+ console.error("[setup-gate] shutdown failed:", err);
244
+ }
245
+ try {
246
+ await closeRegisteredWatchers();
247
+ } catch (err) {
248
+ console.error("[setup-gate] closeAllWatchers failed:", err);
249
+ }
250
+ process.exit(exitCode);
251
+ };
252
+ app.on("before-quit", (event) => {
253
+ event.preventDefault();
254
+ shutdown(0);
255
+ });
256
+ /**
257
+ * i think we probably want to expose this in an editable form to the user
258
+ */
259
+ app.on("window-all-closed", () => {});
260
+ process.on("SIGINT", () => void shutdown(0));
261
+ process.on("SIGTERM", () => void shutdown(0));
262
+ const autoQuitReadyMs = envMs("ZENBU_AUTO_QUIT_AFTER_READY_MS");
263
+ if (autoQuitReadyMs != null) {
264
+ if (verbose) console.log("[setup-gate] auto-quit after ready scheduled:", autoQuitReadyMs);
265
+ setTimeout(() => app.quit(), autoQuitReadyMs).unref();
266
+ }
267
+ const bundledAppPath = app.getAppPath();
268
+ const appName = readPackageJson(bundledAppPath).name ?? path.basename(bundledAppPath);
269
+ const resolvedProjectDir = projectArg() ?? path.join(process.env.ZENBU_APPS_DIR ?? path.join(os.homedir(), ".zenbu", "apps"), appDirName(appName));
270
+ if (!fs.existsSync(resolvedProjectDir)) throw new Error(`setup-gate: project directory ${resolvedProjectDir} does not exist. In a shipped .app, the launcher provisions this dir before invoking setup-gate. In dev, point at an existing project with --project=.`);
271
+ const projectRoot = findProjectRoot(resolvedProjectDir);
272
+ const configPath = resolveConfigPath(projectRoot);
273
+ const tsconfig = findTsconfig(projectRoot);
274
+ process.chdir(projectRoot);
275
+ process.env.ZENBU_CONFIG_PATH = configPath;
276
+ if (!process.argv.some((arg) => arg.startsWith("--project="))) process.argv.push(`--project=${resolvedProjectDir}`);
277
+ if (verbose) {
278
+ console.log("[setup-gate] project:", resolvedProjectDir);
279
+ console.log("[setup-gate] config:", configPath);
280
+ }
281
+ let loaderData;
282
+ try {
283
+ loaderData = await loadConfigPhase(tsconfig, projectRoot);
284
+ } catch (err) {
285
+ if (shuttingDown) return;
286
+ throw err;
287
+ }
288
+ if (shuttingDown) return;
289
+ step(`config loaded (${loaderData.payload.plugins.length} plugins)`);
290
+ try {
291
+ await spawnSplashWindow(loaderData.payload.splashPath);
292
+ } catch (err) {
293
+ if (shuttingDown) return;
294
+ throw err;
295
+ }
296
+ if (shuttingDown) return;
297
+ step("splash shown");
298
+ try {
299
+ await registerLoadersPhase(projectRoot, loaderData);
300
+ } catch (err) {
301
+ if (shuttingDown) return;
302
+ throw err;
303
+ }
304
+ if (shuttingDown) return;
305
+ step("loaders registered");
306
+ try {
307
+ const { defaultServices } = await import("./services/default.mjs");
308
+ await defaultServices();
309
+ } catch (err) {
310
+ if (shuttingDown) return;
311
+ throw err;
312
+ }
313
+ if (shuttingDown) return;
314
+ const url = `zenbu:plugins?config=${encodeURIComponent(configPath)}`;
315
+ let mod;
316
+ try {
317
+ mod = await import(url, { with: { hot: "import" } });
318
+ } catch (err) {
319
+ if (shuttingDown) return;
320
+ throw err;
321
+ }
322
+ if (shuttingDown) return;
323
+ if (isPluginModule(mod)) {
324
+ const controller = mod.default();
325
+ if (isPluginController(controller)) await controller.main();
326
+ }
327
+ if (shuttingDown) return;
328
+ step("plugins evaluated");
329
+ await globalThis.__zenbu_service_runtime__?.whenIdle();
330
+ step("ready");
331
+ const autoQuitMs = envMs("ZENBU_AUTO_QUIT_AFTER_IDLE_MS");
332
+ if (autoQuitMs != null) {
333
+ if (verbose) console.log("[setup-gate] auto-quit scheduled:", autoQuitMs);
334
+ setTimeout(() => app.quit(), autoQuitMs).unref();
335
+ }
336
+ }
337
+ setupGate().catch((error) => {
338
+ console.error(error);
339
+ process.exit(1);
340
+ });
341
+ //#endregion
2
342
  export { setupGate };