@zenbujs/core 0.0.9 → 0.0.13
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-BiYhyeTz.d.mts +41 -0
- package/dist/advice.d.mts +2 -36
- package/dist/advice.mjs +2 -2
- package/dist/{base-window-BxBZ2md_.mjs → base-window-4P-fVvC_.mjs} +37 -26
- package/dist/{build-config-Dzg2frpk.d.mts → build-config-GF0XzR_Y.d.mts} +42 -18
- package/dist/{build-config-pWdmLnrk.mjs → build-config-HMMqpXI1.mjs} +0 -8
- package/dist/{build-electron-Dsbb1EMl.mjs → build-electron-Di_FE62r.mjs} +10 -6
- package/dist/{build-source-d1J3shV8.mjs → build-source-BIaWpaxE.mjs} +2 -2
- package/dist/cli/bin.mjs +7 -7
- package/dist/cli/build.d.mts +1 -1
- package/dist/cli/build.mjs +1 -1
- package/dist/cli/resolve-config.mjs +6 -1
- package/dist/{cli-kL6mPgBE.mjs → cli-5jFDJWM4.mjs} +4 -4
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +2 -2
- package/dist/{db-Bc292RYo.mjs → db-MkOccvBS.mjs} +2 -2
- package/dist/db.d.mts +3 -2
- package/dist/db.mjs +2 -10
- package/dist/{dev-B2emj0HZ.mjs → dev-BSDyzO4j.mjs} +3 -9
- package/dist/env-bootstrap.d.mts +1 -1
- package/dist/events.d.mts +0 -9
- package/dist/{host-version-BIrF8tX7.mjs → host-version-Cog_odmD.mjs} +4 -3
- package/dist/{index-CVF768Xs.d.mts → index-C0mXKol5.d.mts} +188 -143
- package/dist/{index-DeDxePAa.d.mts → index-FaexRVl_.d.mts} +13 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +2 -2
- package/dist/launcher.mjs +64 -6
- package/dist/link-Bt3LB_NW.mjs +586 -0
- package/dist/{load-config-C4Oe2qZO.mjs → load-config-C2XloBaQ.mjs} +68 -5
- package/dist/node-loader.mjs +1 -1
- package/dist/{publish-source-Dq2c0iOw.mjs → publish-source-v93eB9kA.mjs} +6 -2
- package/dist/react.d.mts +6 -6
- package/dist/react.mjs +4 -4
- package/dist/registry-generated.d.mts +19 -14
- package/dist/registry-saQDMUhT.d.mts +13 -0
- package/dist/registry.d.mts +1 -1
- package/dist/{reloader-B22UiNA2.mjs → reloader-CFzxYa67.mjs} +3 -3
- package/dist/{renderer-host-DD16MXhI.mjs → renderer-host-Cw38dSDe.mjs} +35 -24
- package/dist/{rpc-C4_NQmpT.mjs → rpc-Dg9zwZ33.mjs} +4 -4
- package/dist/rpc.d.mts +1 -1
- package/dist/rpc.mjs +1 -1
- package/dist/runtime-DYUONc3S.mjs +861 -0
- package/dist/{runtime-BQWntcOb.d.mts → runtime-fnPDZFYM.d.mts} +100 -3
- package/dist/runtime.d.mts +2 -2
- package/dist/runtime.mjs +2 -578
- package/dist/{schema-CjrMVk36.d.mts → schema-brYpUjYO.d.mts} +13 -25
- package/dist/schema.d.mts +2 -2
- package/dist/schema.mjs +9 -2
- package/dist/{server-CZLMF8Dj.mjs → server-BJ2ZC2z2.mjs} +2 -2
- package/dist/services/default.d.mts +1 -5
- package/dist/services/default.mjs +12 -16
- package/dist/services/index.d.mts +1 -1
- package/dist/services/index.mjs +7 -7
- package/dist/setup-gate.d.mts +1 -1
- package/dist/setup-gate.mjs +20 -12
- package/dist/{transport-F2hv_OEm.mjs → transport-Bqlv9pmJ.mjs} +1 -1
- package/dist/updater-Bs1Jtem6.mjs +480 -0
- package/dist/{vite-plugins-tt6KAtyE.mjs → vite-plugins-Df-cfldF.mjs} +2 -49
- package/dist/vite.d.mts +0 -5
- package/dist/vite.mjs +1 -1
- package/dist/{window-YFKvAM0l.mjs → window-DgB70qeZ.mjs} +113 -22
- package/dist/{write-DgIRjo23.mjs → write-7IfKa_nq.mjs} +1 -1
- package/dist/zenbu-bg-parse-CIyPkJOY.mjs +46 -0
- package/package.json +6 -5
- package/dist/advice-config-DXSIo0sg.mjs +0 -154
- package/dist/link-glX89NV5.mjs +0 -673
- package/dist/registry-CMp8FYgS.d.mts +0 -47
- package/dist/updater-BtB_Ki1r.mjs +0 -1011
- /package/dist/{config-BK78JDRI.mjs → config-DfciRzDu.mjs} +0 -0
- /package/dist/{env-bootstrap-rTs8KR3-.d.mts → env-bootstrap-UBug-4Kw.d.mts} +0 -0
- /package/dist/{index-C-ALz_SH.d.mts → index-CSMHYi3u.d.mts} +0 -0
- /package/dist/{index-ClXLQ1fw.d.mts → index-DJOHDG5e.d.mts} +0 -0
- /package/dist/{log-6rzaCV0I.mjs → log-BkRqDwwB.mjs} +0 -0
- /package/dist/{mirror-sync-pYU6f3-c.mjs → mirror-sync-snqh9kEp.mjs} +0 -0
- /package/dist/{monorepo-Dct-kkbQ.mjs → monorepo-CBzK3l2i.mjs} +0 -0
- /package/dist/{node-BhfLKYCi.mjs → node-BuHlEsE4.mjs} +0 -0
- /package/dist/{schema-Ca7SxXgS.mjs → schema-C6k0SroY.mjs} +0 -0
- /package/dist/{setup-gate-BQq0QgZH.d.mts → setup-gate-DkysEZQO.d.mts} +0 -0
- /package/dist/{src-Cven45mq.mjs → src-BpZAt9zL.mjs} +0 -0
- /package/dist/{trace-BaVg0rnY.mjs → trace-BVcQSD59.mjs} +0 -0
- /package/dist/{transform-BzrwkEdf.mjs → transform-czrcGnVV.mjs} +0 -0
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
//#region src/services/default.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* `./index.ts` (which statically re-exports the service classes for
|
|
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)`.
|
|
3
|
+
* parallelize? i forgor is it serial no matter what?
|
|
8
4
|
*/
|
|
9
5
|
async function defaultServices() {
|
|
10
|
-
await import("../server-
|
|
11
|
-
await import("../reloader-
|
|
12
|
-
await import("../renderer-host-
|
|
13
|
-
await import("../renderer-host-
|
|
14
|
-
await import("../renderer-host-
|
|
15
|
-
await import("../base-window-
|
|
16
|
-
await import("../rpc-
|
|
17
|
-
await import("../renderer-host-
|
|
18
|
-
await import("../window-
|
|
19
|
-
await import("../
|
|
20
|
-
await import("../updater-
|
|
6
|
+
await import("../server-BJ2ZC2z2.mjs").then((n) => n.n);
|
|
7
|
+
await import("../reloader-CFzxYa67.mjs").then((n) => n.n);
|
|
8
|
+
await import("../renderer-host-Cw38dSDe.mjs").then((n) => n.n);
|
|
9
|
+
await import("../renderer-host-Cw38dSDe.mjs").then((n) => n.c);
|
|
10
|
+
await import("../renderer-host-Cw38dSDe.mjs").then((n) => n.o);
|
|
11
|
+
await import("../base-window-4P-fVvC_.mjs").then((n) => n.r);
|
|
12
|
+
await import("../rpc-Dg9zwZ33.mjs").then((n) => n.n);
|
|
13
|
+
await import("../renderer-host-Cw38dSDe.mjs").then((n) => n.i);
|
|
14
|
+
await import("../window-DgB70qeZ.mjs").then((n) => n.n);
|
|
15
|
+
await import("../runtime-DYUONc3S.mjs").then((n) => n.h);
|
|
16
|
+
await import("../updater-Bs1Jtem6.mjs").then((n) => n.n);
|
|
21
17
|
}
|
|
22
18
|
//#endregion
|
|
23
19
|
export { defaultServices };
|
|
@@ -1,2 +1,2 @@
|
|
|
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-
|
|
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-C0mXKol5.mjs";
|
|
2
2
|
export { BaseWindowService, DbService, HttpService, MAIN_WINDOW_ID, ReloaderService, RendererHostService, RpcService, ServerService, UpdaterService, ViewRegistryService, WindowService };
|
package/dist/services/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as ServerService } from "../server-
|
|
2
|
-
import { t as ReloaderService } from "../reloader-
|
|
3
|
-
import { a as DbService, r as ViewRegistryService, s as HttpService, t as RendererHostService } from "../renderer-host-
|
|
4
|
-
import { n as MAIN_WINDOW_ID, t as BaseWindowService } from "../base-window-
|
|
5
|
-
import { t as RpcService } from "../rpc-
|
|
6
|
-
import { t as WindowService } from "../window-
|
|
7
|
-
import { t as UpdaterService } from "../updater-
|
|
1
|
+
import { t as ServerService } from "../server-BJ2ZC2z2.mjs";
|
|
2
|
+
import { t as ReloaderService } from "../reloader-CFzxYa67.mjs";
|
|
3
|
+
import { a as DbService, r as ViewRegistryService, s as HttpService, t as RendererHostService } from "../renderer-host-Cw38dSDe.mjs";
|
|
4
|
+
import { n as MAIN_WINDOW_ID, t as BaseWindowService } from "../base-window-4P-fVvC_.mjs";
|
|
5
|
+
import { t as RpcService } from "../rpc-Dg9zwZ33.mjs";
|
|
6
|
+
import { t as WindowService } from "../window-DgB70qeZ.mjs";
|
|
7
|
+
import { t as UpdaterService } from "../updater-Bs1Jtem6.mjs";
|
|
8
8
|
export { BaseWindowService, DbService, HttpService, MAIN_WINDOW_ID, ReloaderService, RendererHostService, RpcService, ServerService, UpdaterService, ViewRegistryService, WindowService };
|
package/dist/setup-gate.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as setupGate } from "./setup-gate-
|
|
1
|
+
import { t as setupGate } from "./setup-gate-DkysEZQO.mjs";
|
|
2
2
|
export { setupGate };
|
package/dist/setup-gate.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { bootstrapEnv } from "./env-bootstrap.mjs";
|
|
2
|
+
import { n as pickZenbuBgEntry, t as parseZenbuBgEntries } from "./zenbu-bg-parse-CIyPkJOY.mjs";
|
|
2
3
|
import { createRequire, register } from "node:module";
|
|
3
4
|
import fs from "node:fs";
|
|
4
5
|
import os from "node:os";
|
|
@@ -87,16 +88,23 @@ async function closeRegisteredWatchers() {
|
|
|
87
88
|
await (await import("@zenbujs/hmr/pause")).closeAllWatchers?.();
|
|
88
89
|
}
|
|
89
90
|
/**
|
|
90
|
-
* Extract the splash's intended background color from
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
91
|
+
* Extract the splash's intended background color from `<meta name="zenbu-bg">`
|
|
92
|
+
* tag(s). Used as the BaseWindow's `backgroundColor` so the OS doesn't
|
|
93
|
+
* paint a single mismatched frame before the WebContentsView's pixels
|
|
94
|
+
* reach the screen.
|
|
95
|
+
*
|
|
96
|
+
* Supports the `media` attribute (mirrors the W3C `theme-color` pattern),
|
|
97
|
+
* so the splash can declare separate colors per system theme:
|
|
98
|
+
*
|
|
99
|
+
* <meta name="zenbu-bg" content="#fafafa" media="(prefers-color-scheme: light)">
|
|
100
|
+
* <meta name="zenbu-bg" content="#09090b" media="(prefers-color-scheme: dark)">
|
|
101
|
+
*
|
|
102
|
+
* Defaults to `#F4F4F4` when no tag matches.
|
|
95
103
|
*/
|
|
96
|
-
function readSplashBgColor(splashPath) {
|
|
104
|
+
function readSplashBgColor(splashPath, dark) {
|
|
97
105
|
try {
|
|
98
|
-
const
|
|
99
|
-
if (
|
|
106
|
+
const picked = pickZenbuBgEntry(parseZenbuBgEntries(fs.readFileSync(splashPath, "utf8")), dark);
|
|
107
|
+
if (picked) return picked;
|
|
100
108
|
} catch {}
|
|
101
109
|
return "#F4F4F4";
|
|
102
110
|
}
|
|
@@ -125,7 +133,7 @@ async function spawnSplashWindow(splashPath) {
|
|
|
125
133
|
}
|
|
126
134
|
const slot = globalThis;
|
|
127
135
|
const electron = await import("electron");
|
|
128
|
-
const backgroundColor = readSplashBgColor(splashPath);
|
|
136
|
+
const backgroundColor = readSplashBgColor(splashPath, electron.nativeTheme.shouldUseDarkColors);
|
|
129
137
|
const existing = slot.__zenbu_boot_windows__?.find((b) => b.windowId === "main");
|
|
130
138
|
let win;
|
|
131
139
|
if (existing) {
|
|
@@ -186,10 +194,10 @@ async function spawnSplashWindow(splashPath) {
|
|
|
186
194
|
*/
|
|
187
195
|
async function loadConfigPhase(tsconfig, projectRoot) {
|
|
188
196
|
register$1({ tsconfig });
|
|
189
|
-
const { loadConfig } = await import("./load-config-
|
|
197
|
+
const { loadConfig } = await import("./load-config-C2XloBaQ.mjs").then((n) => n.a);
|
|
190
198
|
const { resolved, pluginSourceFiles } = await loadConfig(projectRoot);
|
|
191
199
|
try {
|
|
192
|
-
const { linkProject } = await import("./link-
|
|
200
|
+
const { linkProject } = await import("./link-Bt3LB_NW.mjs").then((n) => n.n);
|
|
193
201
|
await linkProject(projectRoot, { quiet: true });
|
|
194
202
|
} catch (err) {
|
|
195
203
|
console.warn(`[setup-gate] zen link failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -225,7 +233,7 @@ async function loadConfigPhase(tsconfig, projectRoot) {
|
|
|
225
233
|
async function registerLoadersPhase(projectRoot, loaderData) {
|
|
226
234
|
registerLoader(import.meta.resolve("@zenbujs/core/loaders/zenbu"), { data: loaderData });
|
|
227
235
|
process.env.ZENBU_ADVICE_ROOT = projectRoot;
|
|
228
|
-
await import("./node-
|
|
236
|
+
await import("./node-BuHlEsE4.mjs");
|
|
229
237
|
const dynohot = await import(pathToFileURL(createRequire(import.meta.url).resolve("@zenbujs/hmr/register")).href);
|
|
230
238
|
if (typeof dynohot.register === "function") dynohot.register({ ignore: /[/\\](?:node_modules|dist)[/\\]/ });
|
|
231
239
|
}
|
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
import { n as __exportAll } from "./chunk-DsiFFCwN.mjs";
|
|
2
|
+
import { f as runtime, n as Service } from "./runtime-DYUONc3S.mjs";
|
|
3
|
+
import { t as createLogger } from "./log-BkRqDwwB.mjs";
|
|
4
|
+
import { n as tryReadHostVersion } from "./host-version-Cog_odmD.mjs";
|
|
5
|
+
import fs, { existsSync } from "node:fs";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { spawn } from "node:child_process";
|
|
9
|
+
import crypto from "node:crypto";
|
|
10
|
+
import fsp from "node:fs/promises";
|
|
11
|
+
import { app } from "electron";
|
|
12
|
+
import * as git from "isomorphic-git";
|
|
13
|
+
import http from "isomorphic-git/http/node";
|
|
14
|
+
//#region src/shared/pm-install.ts
|
|
15
|
+
/**
|
|
16
|
+
* Bundled-toolchain `<pm> install` helpers.
|
|
17
|
+
*
|
|
18
|
+
* Imported by both:
|
|
19
|
+
* - `packages/core/src/launcher.ts` (tsdown inlines this into
|
|
20
|
+
* `dist/launcher.mjs`; the launcher cannot `import "@zenbujs/core"`)
|
|
21
|
+
* - `packages/core/src/services/updater.ts` (resolved through normal
|
|
22
|
+
* `@zenbujs/core/...` resolution at runtime)
|
|
23
|
+
*
|
|
24
|
+
* Both call sites operate on the apps-dir (`~/.zenbu/apps/<name>/`) and
|
|
25
|
+
* the .app's `Resources/` (where `provisionToolchain` staged
|
|
26
|
+
* `bun`, `pnpm`, etc.). The launcher kicks off the FIRST install at
|
|
27
|
+
* launch; the updater service runs the SAME logic when an `update()`
|
|
28
|
+
* lockfile-diff says deps drifted.
|
|
29
|
+
*/
|
|
30
|
+
function lockfileFor(type) {
|
|
31
|
+
switch (type) {
|
|
32
|
+
case "pnpm": return "pnpm-lock.yaml";
|
|
33
|
+
case "npm": return "package-lock.json";
|
|
34
|
+
case "yarn": return "yarn.lock";
|
|
35
|
+
case "bun": return "bun.lock";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function isYarnBerry(version) {
|
|
39
|
+
const major = parseInt(version.split(".")[0] ?? "", 10);
|
|
40
|
+
return Number.isFinite(major) && major >= 2;
|
|
41
|
+
}
|
|
42
|
+
function bundledToolPath(name, resourcesPath) {
|
|
43
|
+
const candidates = [path.join(resourcesPath, "toolchain", "bin", name), path.join(resourcesPath, "toolchain", name)];
|
|
44
|
+
for (const candidate of candidates) if (existsSync(candidate)) return candidate;
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolve the entrypoint we'll exec for a given PM, mirroring the layout
|
|
49
|
+
* `provisionToolchain` writes into the bundle's `Resources/toolchain/`.
|
|
50
|
+
*/
|
|
51
|
+
function bundledPmEntry(pm, resourcesPath) {
|
|
52
|
+
switch (pm.type) {
|
|
53
|
+
case "pnpm": {
|
|
54
|
+
const p = path.join(resourcesPath, "toolchain", "pnpm", "bin", "pnpm.cjs");
|
|
55
|
+
if (!existsSync(p)) throw new Error(`bundled pnpm entry not found at ${p}. The .app's toolchain is incomplete.`);
|
|
56
|
+
return {
|
|
57
|
+
kind: "js",
|
|
58
|
+
path: p
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
case "npm": {
|
|
62
|
+
const p = path.join(resourcesPath, "toolchain", "npm", "bin", "npm-cli.js");
|
|
63
|
+
if (!existsSync(p)) throw new Error(`bundled npm entry not found at ${p}. The .app's toolchain is incomplete.`);
|
|
64
|
+
return {
|
|
65
|
+
kind: "js",
|
|
66
|
+
path: p
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
case "yarn": {
|
|
70
|
+
if (isYarnBerry(pm.version)) {
|
|
71
|
+
const p = path.join(resourcesPath, "toolchain", "yarn.cjs");
|
|
72
|
+
if (!existsSync(p)) throw new Error(`bundled yarn (berry) entry not found at ${p}. The .app's toolchain is incomplete.`);
|
|
73
|
+
return {
|
|
74
|
+
kind: "js",
|
|
75
|
+
path: p
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const p = path.join(resourcesPath, "toolchain", "yarn", "bin", "yarn.js");
|
|
79
|
+
if (!existsSync(p)) throw new Error(`bundled yarn (classic) entry not found at ${p}. The .app's toolchain is incomplete.`);
|
|
80
|
+
return {
|
|
81
|
+
kind: "js",
|
|
82
|
+
path: p
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
case "bun": return { kind: "bun" };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function electronTargetVersion(appsDir) {
|
|
89
|
+
if (process.versions.electron) return process.versions.electron;
|
|
90
|
+
try {
|
|
91
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(appsDir, "package.json"), "utf8"));
|
|
92
|
+
return (pkg.devDependencies?.electron ?? pkg.dependencies?.electron ?? "").replace(/^[^\d]*/, "") || "42.0.0";
|
|
93
|
+
} catch {
|
|
94
|
+
return "42.0.0";
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function buildInstallEnv(appsDir) {
|
|
98
|
+
const target = electronTargetVersion(appsDir);
|
|
99
|
+
return {
|
|
100
|
+
...process.env,
|
|
101
|
+
CI: "true",
|
|
102
|
+
HOME: path.join(appsDir, ".zenbu", ".node-gyp"),
|
|
103
|
+
npm_config_runtime: "electron",
|
|
104
|
+
npm_config_target: target,
|
|
105
|
+
npm_config_disturl: "https://electronjs.org/headers",
|
|
106
|
+
npm_config_arch: process.arch
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Best-effort progress regex per package manager. We pass each stdout line
|
|
111
|
+
* through these and return a `progress` payload when one matches; otherwise
|
|
112
|
+
* `null`. Failing to match is fine — the UI just won't show fine-grained
|
|
113
|
+
* progress for that PM.
|
|
114
|
+
*/
|
|
115
|
+
const PNPM_RESOLVED_RE = /Progress:\s+resolved\s+(\d+),\s+reused\s+(\d+),\s+downloaded\s+(\d+)/i;
|
|
116
|
+
const PNPM_PROGRESS_RE = /(\d+)\s*\/\s*(\d+)/;
|
|
117
|
+
function parseInstallProgress(pm, line) {
|
|
118
|
+
if (pm === "pnpm") {
|
|
119
|
+
const m = line.match(PNPM_RESOLVED_RE);
|
|
120
|
+
if (m) {
|
|
121
|
+
const resolved = parseInt(m[1], 10);
|
|
122
|
+
const reused = parseInt(m[2], 10);
|
|
123
|
+
const downloaded = parseInt(m[3], 10);
|
|
124
|
+
return {
|
|
125
|
+
phase: "resolve",
|
|
126
|
+
loaded: reused + downloaded,
|
|
127
|
+
total: resolved,
|
|
128
|
+
ratio: resolved > 0 ? (reused + downloaded) / resolved : void 0
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const m = line.match(PNPM_PROGRESS_RE);
|
|
133
|
+
if (m) {
|
|
134
|
+
const loaded = parseInt(m[1], 10);
|
|
135
|
+
const total = parseInt(m[2], 10);
|
|
136
|
+
if (total > 0) return {
|
|
137
|
+
loaded,
|
|
138
|
+
total,
|
|
139
|
+
ratio: loaded / total
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
function spawnInstall(args) {
|
|
145
|
+
const { bin, cliArgs, cwd, env, label, pmType, reporter, signal } = args;
|
|
146
|
+
return new Promise((resolve, reject) => {
|
|
147
|
+
if (signal?.aborted) {
|
|
148
|
+
reject(/* @__PURE__ */ new Error(`${label} aborted before start`));
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const usePiped = reporter != null;
|
|
152
|
+
const child = spawn(bin, cliArgs, {
|
|
153
|
+
cwd,
|
|
154
|
+
stdio: usePiped ? [
|
|
155
|
+
"inherit",
|
|
156
|
+
"pipe",
|
|
157
|
+
"pipe"
|
|
158
|
+
] : "inherit",
|
|
159
|
+
env
|
|
160
|
+
});
|
|
161
|
+
const onAbort = () => {
|
|
162
|
+
try {
|
|
163
|
+
child.kill("SIGTERM");
|
|
164
|
+
} catch {}
|
|
165
|
+
};
|
|
166
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
167
|
+
if (usePiped) {
|
|
168
|
+
const wireStream = (stream, which) => {
|
|
169
|
+
if (!stream) return;
|
|
170
|
+
let buf = "";
|
|
171
|
+
stream.setEncoding("utf8");
|
|
172
|
+
stream.on("data", (chunk) => {
|
|
173
|
+
buf += chunk;
|
|
174
|
+
let nl;
|
|
175
|
+
while ((nl = buf.indexOf("\n")) >= 0) {
|
|
176
|
+
const rawLine = buf.slice(0, nl);
|
|
177
|
+
buf = buf.slice(nl + 1);
|
|
178
|
+
reporter?.rawLine?.(which, rawLine);
|
|
179
|
+
const line = rawLine.replace(/\r/g, "").trimEnd();
|
|
180
|
+
if (!line) continue;
|
|
181
|
+
reporter?.message?.(line);
|
|
182
|
+
const progress = parseInstallProgress(pmType, line);
|
|
183
|
+
if (progress) reporter?.progress?.(progress);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
stream.on("end", () => {
|
|
187
|
+
if (buf.length > 0) {
|
|
188
|
+
reporter?.rawLine?.(which, buf);
|
|
189
|
+
const line = buf.replace(/\r/g, "").trimEnd();
|
|
190
|
+
if (line) reporter?.message?.(line);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
wireStream(child.stdout, "stdout");
|
|
195
|
+
wireStream(child.stderr, "stderr");
|
|
196
|
+
}
|
|
197
|
+
child.on("error", (err) => {
|
|
198
|
+
signal?.removeEventListener("abort", onAbort);
|
|
199
|
+
reject(err);
|
|
200
|
+
});
|
|
201
|
+
child.on("close", (code, sig) => {
|
|
202
|
+
signal?.removeEventListener("abort", onAbort);
|
|
203
|
+
if (code === 0) resolve();
|
|
204
|
+
else if (signal?.aborted) reject(/* @__PURE__ */ new Error(`${label} aborted (${sig ?? code})`));
|
|
205
|
+
else reject(/* @__PURE__ */ new Error(`${label} exited with code ${code}`));
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
async function runInstall(opts) {
|
|
210
|
+
const { appsDir, resourcesPath, pm, reporter = null, signal } = opts;
|
|
211
|
+
const env = buildInstallEnv(appsDir);
|
|
212
|
+
const entry = bundledPmEntry(pm, resourcesPath);
|
|
213
|
+
switch (pm.type) {
|
|
214
|
+
case "pnpm": {
|
|
215
|
+
if (entry.kind !== "js") throw new Error("internal: pnpm entry shape");
|
|
216
|
+
const bun = bundledToolPath("bun", resourcesPath);
|
|
217
|
+
if (!bun) throw new Error(`bundled bun not found in ${resourcesPath}/toolchain (required to host the pnpm.cjs entry)`);
|
|
218
|
+
await spawnInstall({
|
|
219
|
+
bin: bun,
|
|
220
|
+
cliArgs: [
|
|
221
|
+
entry.path,
|
|
222
|
+
"install",
|
|
223
|
+
"--reporter=append-only"
|
|
224
|
+
],
|
|
225
|
+
cwd: appsDir,
|
|
226
|
+
env,
|
|
227
|
+
label: "pnpm install",
|
|
228
|
+
pmType: pm.type,
|
|
229
|
+
reporter,
|
|
230
|
+
signal
|
|
231
|
+
});
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
case "npm": {
|
|
235
|
+
if (entry.kind !== "js") throw new Error("internal: npm entry shape");
|
|
236
|
+
const bun = bundledToolPath("bun", resourcesPath);
|
|
237
|
+
if (!bun) throw new Error(`bundled bun not found in ${resourcesPath}/toolchain (required to host the npm-cli.js entry)`);
|
|
238
|
+
await spawnInstall({
|
|
239
|
+
bin: bun,
|
|
240
|
+
cliArgs: [
|
|
241
|
+
entry.path,
|
|
242
|
+
"install",
|
|
243
|
+
"--no-audit",
|
|
244
|
+
"--no-fund",
|
|
245
|
+
"--no-progress"
|
|
246
|
+
],
|
|
247
|
+
cwd: appsDir,
|
|
248
|
+
env,
|
|
249
|
+
label: "npm install",
|
|
250
|
+
pmType: pm.type,
|
|
251
|
+
reporter,
|
|
252
|
+
signal
|
|
253
|
+
});
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
case "yarn": {
|
|
257
|
+
if (entry.kind !== "js") throw new Error("internal: yarn entry shape");
|
|
258
|
+
const bun = bundledToolPath("bun", resourcesPath);
|
|
259
|
+
if (!bun) throw new Error(`bundled bun not found in ${resourcesPath}/toolchain (required to host the yarn.js entry)`);
|
|
260
|
+
if (isYarnBerry(pm.version)) await spawnInstall({
|
|
261
|
+
bin: bun,
|
|
262
|
+
cliArgs: [entry.path, "install"],
|
|
263
|
+
cwd: appsDir,
|
|
264
|
+
env: {
|
|
265
|
+
...env,
|
|
266
|
+
YARN_ENABLE_IMMUTABLE_INSTALLS: "false"
|
|
267
|
+
},
|
|
268
|
+
label: `yarn install (${pm.version})`,
|
|
269
|
+
pmType: pm.type,
|
|
270
|
+
reporter,
|
|
271
|
+
signal
|
|
272
|
+
});
|
|
273
|
+
else {
|
|
274
|
+
const rcPath = path.join(appsDir, ".zenbu", "yarn-classic-bun.yarnrc");
|
|
275
|
+
await fsp.mkdir(path.dirname(rcPath), { recursive: true });
|
|
276
|
+
await fsp.writeFile(rcPath, "strict-ssl false\n");
|
|
277
|
+
await spawnInstall({
|
|
278
|
+
bin: bun,
|
|
279
|
+
cliArgs: [
|
|
280
|
+
entry.path,
|
|
281
|
+
"install",
|
|
282
|
+
"--non-interactive",
|
|
283
|
+
"--no-progress",
|
|
284
|
+
"--network-timeout",
|
|
285
|
+
"600000",
|
|
286
|
+
"--use-yarnrc",
|
|
287
|
+
rcPath,
|
|
288
|
+
"--registry",
|
|
289
|
+
"https://registry.npmjs.org/"
|
|
290
|
+
],
|
|
291
|
+
cwd: appsDir,
|
|
292
|
+
env,
|
|
293
|
+
label: `yarn install (${pm.version})`,
|
|
294
|
+
pmType: pm.type,
|
|
295
|
+
reporter,
|
|
296
|
+
signal
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
case "bun": {
|
|
302
|
+
const bun = bundledToolPath("bun", resourcesPath);
|
|
303
|
+
if (!bun) throw new Error(`bundled bun not found in ${resourcesPath}/toolchain. The .app is missing required toolchain binaries.`);
|
|
304
|
+
await spawnInstall({
|
|
305
|
+
bin: bun,
|
|
306
|
+
cliArgs: ["install", "--no-progress"],
|
|
307
|
+
cwd: appsDir,
|
|
308
|
+
env,
|
|
309
|
+
label: "bun install",
|
|
310
|
+
pmType: pm.type,
|
|
311
|
+
reporter,
|
|
312
|
+
signal
|
|
313
|
+
});
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
async function fileHash(hash, filePath) {
|
|
319
|
+
hash.update(filePath);
|
|
320
|
+
hash.update("\0");
|
|
321
|
+
try {
|
|
322
|
+
hash.update(await fsp.readFile(filePath));
|
|
323
|
+
} catch {}
|
|
324
|
+
hash.update("\0");
|
|
325
|
+
}
|
|
326
|
+
async function depsSignature(appsDir, pm) {
|
|
327
|
+
const hash = crypto.createHash("sha256");
|
|
328
|
+
await fileHash(hash, path.join(appsDir, "package.json"));
|
|
329
|
+
await fileHash(hash, path.join(appsDir, lockfileFor(pm.type)));
|
|
330
|
+
hash.update(`${pm.type}@${pm.version}`);
|
|
331
|
+
hash.update("\0");
|
|
332
|
+
hash.update(process.versions.electron ?? "no-electron");
|
|
333
|
+
hash.update("\0");
|
|
334
|
+
hash.update(process.platform);
|
|
335
|
+
hash.update("\0");
|
|
336
|
+
hash.update(process.arch);
|
|
337
|
+
return hash.digest("hex");
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Read `<appsDir>/.zenbu/deps-sig` (the signature recorded after the
|
|
341
|
+
* last successful install). Returns `null` when missing.
|
|
342
|
+
*/
|
|
343
|
+
async function readDepsSig(appsDir) {
|
|
344
|
+
const sigPath = path.join(appsDir, ".zenbu", "deps-sig");
|
|
345
|
+
try {
|
|
346
|
+
return await fsp.readFile(sigPath, "utf8");
|
|
347
|
+
} catch {
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
async function writeDepsSig(appsDir, sig) {
|
|
352
|
+
const sigPath = path.join(appsDir, ".zenbu", "deps-sig");
|
|
353
|
+
await fsp.mkdir(path.dirname(sigPath), { recursive: true });
|
|
354
|
+
await fsp.writeFile(sigPath, sig);
|
|
355
|
+
}
|
|
356
|
+
//#endregion
|
|
357
|
+
//#region src/services/updater.ts
|
|
358
|
+
/**
|
|
359
|
+
* Atomic, thin wrappers over `isomorphic-git` plus a single `install()`
|
|
360
|
+
* primitive over `runInstall`. Each public method is one underlying
|
|
361
|
+
* call; callers compose update flows themselves.
|
|
362
|
+
*
|
|
363
|
+
* `getAppContext()` is a read-only convenience that surfaces the
|
|
364
|
+
* running .app's `app-config.json` + `host.json` so callers don't have
|
|
365
|
+
* to re-parse them. It returns `null` in dev or when the bundle is
|
|
366
|
+
* missing those files.
|
|
367
|
+
*/
|
|
368
|
+
var updater_exports = /* @__PURE__ */ __exportAll({ UpdaterService: () => UpdaterService });
|
|
369
|
+
const log = createLogger("updater");
|
|
370
|
+
const LEGACY_PACKAGE_MANAGER = {
|
|
371
|
+
type: "pnpm",
|
|
372
|
+
version: "10.33.0"
|
|
373
|
+
};
|
|
374
|
+
function isBundleMode() {
|
|
375
|
+
return process.env.ZENBU_LAUNCHED_FROM_BUNDLE === "1";
|
|
376
|
+
}
|
|
377
|
+
function readAppConfig(appPath) {
|
|
378
|
+
const configPath = path.join(appPath, "app-config.json");
|
|
379
|
+
try {
|
|
380
|
+
return JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
381
|
+
} catch {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
function appsDirFor(name) {
|
|
386
|
+
if (process.env.ZENBU_APPS_DIR) return path.resolve(process.env.ZENBU_APPS_DIR);
|
|
387
|
+
return path.join(os.homedir(), ".zenbu", "apps", name);
|
|
388
|
+
}
|
|
389
|
+
var UpdaterService = class extends Service.create({ key: "updater" }) {
|
|
390
|
+
evaluate() {
|
|
391
|
+
log.verbose(`updater service ready (mode=${isBundleMode() ? "bundle" : "dev"})`);
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Snapshot of the running .app's mirror + toolchain. Returns `null`
|
|
395
|
+
* in dev (no bundle) or when `app-config.json` / `host.json` are
|
|
396
|
+
* missing. No side effects.
|
|
397
|
+
*/
|
|
398
|
+
async getAppContext() {
|
|
399
|
+
if (!isBundleMode()) return null;
|
|
400
|
+
const appPath = app.getAppPath();
|
|
401
|
+
const cfg = readAppConfig(appPath);
|
|
402
|
+
if (!cfg || !cfg.mirrorUrl) return null;
|
|
403
|
+
const host = tryReadHostVersion(appPath);
|
|
404
|
+
if (!host) return null;
|
|
405
|
+
return {
|
|
406
|
+
appsDir: appsDirFor(cfg.name),
|
|
407
|
+
resourcesPath: path.dirname(appPath),
|
|
408
|
+
mirror: {
|
|
409
|
+
url: cfg.mirrorUrl,
|
|
410
|
+
branch: cfg.branch ?? "main"
|
|
411
|
+
},
|
|
412
|
+
packageManager: cfg.packageManager ?? LEGACY_PACKAGE_MANAGER,
|
|
413
|
+
hostVersion: host.version,
|
|
414
|
+
appName: cfg.name
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
async fetch(opts) {
|
|
418
|
+
return git.fetch({
|
|
419
|
+
fs,
|
|
420
|
+
http,
|
|
421
|
+
...opts
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
async clone(opts) {
|
|
425
|
+
await git.clone({
|
|
426
|
+
fs,
|
|
427
|
+
http,
|
|
428
|
+
...opts
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
async checkout(opts) {
|
|
432
|
+
await git.checkout({
|
|
433
|
+
fs,
|
|
434
|
+
...opts
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
async resolveRef(opts) {
|
|
438
|
+
return git.resolveRef({
|
|
439
|
+
fs,
|
|
440
|
+
...opts
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
async statusMatrix(opts) {
|
|
444
|
+
return git.statusMatrix({
|
|
445
|
+
fs,
|
|
446
|
+
...opts
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
async log(opts) {
|
|
450
|
+
return git.log({
|
|
451
|
+
fs,
|
|
452
|
+
...opts
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Run `<pm> install` in `dir` using the bundled toolchain at
|
|
457
|
+
* `resourcesPath`. Always runs; no signature gating. Compose with
|
|
458
|
+
* `getDepsSignature` / `readDepsSignature` / `writeDepsSignature`
|
|
459
|
+
* if you want a skip-when-clean gate.
|
|
460
|
+
*/
|
|
461
|
+
async install(opts) {
|
|
462
|
+
await runInstall({
|
|
463
|
+
appsDir: opts.dir,
|
|
464
|
+
resourcesPath: opts.resourcesPath,
|
|
465
|
+
pm: opts.pm
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
async getDepsSignature(opts) {
|
|
469
|
+
return depsSignature(opts.dir, opts.pm);
|
|
470
|
+
}
|
|
471
|
+
async readDepsSignature(opts) {
|
|
472
|
+
return readDepsSig(opts.dir);
|
|
473
|
+
}
|
|
474
|
+
async writeDepsSignature(opts) {
|
|
475
|
+
await writeDepsSig(opts.dir, opts.sig);
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
runtime.register(UpdaterService, import.meta);
|
|
479
|
+
//#endregion
|
|
480
|
+
export { updater_exports as n, UpdaterService as t };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as require_lib, t as zenbuAdviceTransform$1 } from "./transform-
|
|
3
|
-
import { a as getAllTypes, i as getAllContentScriptPaths, n as getAdvice, o as getContentScripts } from "./advice-config-DXSIo0sg.mjs";
|
|
1
|
+
import { b as getContentScripts, g as getAdvice, v as getAllContentScriptPaths, y as getAllTypes } from "./runtime-DYUONc3S.mjs";
|
|
2
|
+
import { n as require_lib, t as zenbuAdviceTransform$1 } from "./transform-czrcGnVV.mjs";
|
|
4
3
|
import path from "node:path";
|
|
5
4
|
import { fileURLToPath } from "node:url";
|
|
6
5
|
//#region ../advice/src/vite.ts
|
|
@@ -99,47 +98,6 @@ function zenbuFrameworkResolve() {
|
|
|
99
98
|
] },
|
|
100
99
|
server: { fs: { allow: [CORE_PACKAGE_ROOT] } }
|
|
101
100
|
};
|
|
102
|
-
},
|
|
103
|
-
/**
|
|
104
|
-
* Vite's built-in tsconfig watcher (`reloadOnTsconfigChange` in
|
|
105
|
-
* `plugins/esbuild.ts`) only triggers a cache-clear + full reload when
|
|
106
|
-
* the changed path ends in exactly `/tsconfig.json` — non-canonical
|
|
107
|
-
* names like `tsconfig.local.json` are silently ignored even though the
|
|
108
|
-
* underlying chokidar watcher does fire on them. We use that pattern
|
|
109
|
-
* (a committed `tsconfig.json` that extends a generated, gitignored
|
|
110
|
-
* `tsconfig.local.json`) so plugin sources can `#registry/*`-import
|
|
111
|
-
* the host's typed registry without a host-specific path leaking into
|
|
112
|
-
* a committed file.
|
|
113
|
-
*
|
|
114
|
-
* Without this hook, every `zen link` run would silently leave esbuild
|
|
115
|
-
* with a stale "extends target missing" cache and plugin sources would
|
|
116
|
-
* fail to load until the dev process is killed by hand. This watches
|
|
117
|
-
* the plugin directories declared in the host's `config.json` and
|
|
118
|
-
* proactively calls `server.restart()` on add/change/unlink of any
|
|
119
|
-
* `tsconfig.local.json`.
|
|
120
|
-
*/
|
|
121
|
-
configureServer(server) {
|
|
122
|
-
const tsconfigPaths = getPlugins().map((p) => path.join(p.dir, "tsconfig.local.json"));
|
|
123
|
-
if (tsconfigPaths.length === 0) return;
|
|
124
|
-
server.watcher.add(tsconfigPaths);
|
|
125
|
-
let restarting = false;
|
|
126
|
-
const handle = (file) => {
|
|
127
|
-
if (!file.endsWith("tsconfig.local.json")) return;
|
|
128
|
-
if (restarting) return;
|
|
129
|
-
restarting = true;
|
|
130
|
-
server.config.logger.info(`[zenbu] ${file} changed — restarting Vite to refresh tsconfig (vite's built-in watcher only fires on /tsconfig.json)`, {
|
|
131
|
-
timestamp: true,
|
|
132
|
-
clear: false
|
|
133
|
-
});
|
|
134
|
-
server.restart().catch((err) => {
|
|
135
|
-
server.config.logger.error(`[zenbu] vite restart failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
136
|
-
}).finally(() => {
|
|
137
|
-
restarting = false;
|
|
138
|
-
});
|
|
139
|
-
};
|
|
140
|
-
server.watcher.on("add", handle);
|
|
141
|
-
server.watcher.on("change", handle);
|
|
142
|
-
server.watcher.on("unlink", handle);
|
|
143
101
|
}
|
|
144
102
|
};
|
|
145
103
|
}
|
|
@@ -294,11 +252,6 @@ function zenbuAdviceTransform() {
|
|
|
294
252
|
};
|
|
295
253
|
}
|
|
296
254
|
/**
|
|
297
|
-
* Returns the framework Vite plugins in the canonical order. Auto-injected
|
|
298
|
-
* by `ReloaderService` for every renderer; exported for advanced users who
|
|
299
|
-
* want to compose them into a custom Vite stack.
|
|
300
|
-
*
|
|
301
|
-
* Order matters:
|
|
302
255
|
* 1. `zenbuFrameworkResolve` — `enforce: "pre"`, runs first so it gets
|
|
303
256
|
* `react` / `@zenbujs/core/*` *before* Vite's default resolver walks
|
|
304
257
|
* up and finds plugin-local copies.
|