mooncat-browser 0.1.0 → 0.2.1
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/browser-op/backend/browserd.cjs +4 -1
- package/browser-op/extension/server.cjs +3 -2
- package/browser-op/extension/service.cjs +7 -2
- package/browser-op/index.cjs +14 -17
- package/browser-op/webplater/dist/chrome-mv3/chunks/offscreen-JoFB8k4y.js +1 -0
- package/browser-op/webplater/dist/chrome-mv3/manifest.json +1 -1
- package/browser-op/webplater/dist/chrome-mv3/offscreen.html +1 -1
- package/browser-op/webplater/entrypoints/offscreen/main.ts +4 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +363 -85
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +63 -42
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +69 -73
- package/dist/config.js.map +1 -1
- package/dist/instance.d.ts +57 -0
- package/dist/instance.d.ts.map +1 -0
- package/dist/instance.js +128 -0
- package/dist/instance.js.map +1 -0
- package/dist/prepare-extension.d.ts +37 -0
- package/dist/prepare-extension.d.ts.map +1 -0
- package/dist/prepare-extension.js +144 -0
- package/dist/prepare-extension.js.map +1 -0
- package/dist/server.d.ts +40 -23
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +51 -35
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/skills/browser/SKILL.md +37 -14
- package/skills/browser/references/collect.md +4 -2
- package/skills/browser/references/high-risk.md +27 -14
- package/skills/browser/references/probing.md +6 -4
- package/browser-op/webplater/dist/chrome-mv3/chunks/offscreen-CFXYw9Mo.js +0 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { BrowserInstanceConfig } from "./config.js";
|
|
2
|
+
/** 源码 offscreen/main.ts 里的占位符,wxt build 保留字符串字面量。 */
|
|
3
|
+
export declare const HOST_WS_URL_PLACEHOLDER = "__MOONCAT_BROWSER_HOST_WS_URL__";
|
|
4
|
+
/** 包内 webplater 扩展模板目录。dist/cli.js -> ../../browser-op/webplater/dist/chrome-mv3。 */
|
|
5
|
+
export declare function extensionTemplateDir(): string;
|
|
6
|
+
/** 实例扩展目录内的 metadata 文件名。 */
|
|
7
|
+
export declare const METADATA_FILENAME = ".mooncat-instance.json";
|
|
8
|
+
/** metadata 结构。 */
|
|
9
|
+
export interface InstanceExtensionMetadata {
|
|
10
|
+
instance: string;
|
|
11
|
+
extensionPort: number;
|
|
12
|
+
hostWsUrl: string;
|
|
13
|
+
generatedAt: string;
|
|
14
|
+
/** 模板来源的 manifest version(用于检测包升级后需要重 prepare)。 */
|
|
15
|
+
sourceBuildVersion: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 为实例生成 unpacked 扩展目录。
|
|
19
|
+
*
|
|
20
|
+
* 步骤:rm 旧目录 → mkdir → copy 模板 → 替换占位符 → 写 metadata。
|
|
21
|
+
* 幂等:重复调用会清空重建。
|
|
22
|
+
*
|
|
23
|
+
* @returns 被替换占位符的文件数 + metadata
|
|
24
|
+
*/
|
|
25
|
+
export declare function prepareExtension(cfg: BrowserInstanceConfig): {
|
|
26
|
+
replacedFiles: number;
|
|
27
|
+
metadata: InstanceExtensionMetadata;
|
|
28
|
+
templateDir: string;
|
|
29
|
+
};
|
|
30
|
+
/** 读实例 extensionDir 的 metadata。不存在返回 null。 */
|
|
31
|
+
export declare function readInstanceMetadata(cfg: BrowserInstanceConfig): InstanceExtensionMetadata | null;
|
|
32
|
+
/**
|
|
33
|
+
* 校验实例 extensionDir 是否就绪(用于 start --route extension 前置检查)。
|
|
34
|
+
* 返回 null 表示就绪;返回字符串表示需要重 prepare 的原因。
|
|
35
|
+
*/
|
|
36
|
+
export declare function verifyInstanceExtension(cfg: BrowserInstanceConfig): string | null;
|
|
37
|
+
//# sourceMappingURL=prepare-extension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare-extension.d.ts","sourceRoot":"","sources":["../src/prepare-extension.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAIzD,qDAAqD;AACrD,eAAO,MAAM,uBAAuB,oCAAoC,CAAC;AAEzE,qFAAqF;AACrF,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAED,6BAA6B;AAC7B,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAE1D,mBAAmB;AACnB,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAoCD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,qBAAqB,GAAG;IAC5D,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,yBAAyB,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;CACrB,CA8CA;AAED,8CAA8C;AAC9C,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,qBAAqB,GAAG,yBAAyB,GAAG,IAAI,CAQjG;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAwBjF"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// -*- coding: utf-8 -*-
|
|
2
|
+
// prepare-extension.ts — 为实例生成 unpacked 扩展目录。
|
|
3
|
+
//
|
|
4
|
+
// 多实例 extension 隔离靠:独立 profileDir + 独立 extensionDir + 独立 extensionPort。
|
|
5
|
+
// 包内 browser-op/webplater/dist/chrome-mv3 是只 build 一次的模板(含占位符)。
|
|
6
|
+
// 本模块在 prepare-extension <name> 时:
|
|
7
|
+
// 1. copy 模板 → 实例 extensionDir
|
|
8
|
+
// 2. 替换所有产物里的 __MOONCAT_BROWSER_HOST_WS_URL__ → ws://127.0.0.1:<extensionPort>
|
|
9
|
+
// 3. 写 metadata(.mooncat-instance.json)
|
|
10
|
+
//
|
|
11
|
+
// 用户随后手动 load unpacked 这个实例 extensionDir 到实例 profileDir 的 Chrome。
|
|
12
|
+
// 共享同一 key/extensionId:不同 profileDir 里的同 id 扩展互不冲突。
|
|
13
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
17
|
+
/** 源码 offscreen/main.ts 里的占位符,wxt build 保留字符串字面量。 */
|
|
18
|
+
export const HOST_WS_URL_PLACEHOLDER = "__MOONCAT_BROWSER_HOST_WS_URL__";
|
|
19
|
+
/** 包内 webplater 扩展模板目录。dist/cli.js -> ../../browser-op/webplater/dist/chrome-mv3。 */
|
|
20
|
+
export function extensionTemplateDir() {
|
|
21
|
+
return (process.env.MOONCAT_BROWSER_EXTENSION_TEMPLATE ||
|
|
22
|
+
join(__dirname, "..", "browser-op", "webplater", "dist", "chrome-mv3"));
|
|
23
|
+
}
|
|
24
|
+
/** 实例扩展目录内的 metadata 文件名。 */
|
|
25
|
+
export const METADATA_FILENAME = ".mooncat-instance.json";
|
|
26
|
+
/** 读模板 manifest 的 version(build 时间戳)。 */
|
|
27
|
+
function readTemplateManifestVersion(templateDir) {
|
|
28
|
+
try {
|
|
29
|
+
const m = JSON.parse(readFileSync(join(templateDir, "manifest.json"), "utf8"));
|
|
30
|
+
return m.version || "unknown";
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return "unknown";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** 递归遍历 dir,对所有 .js/.html/.json 文件做字符串替换。返回被改写的文件数。 */
|
|
37
|
+
function replaceInDir(dir, from, to) {
|
|
38
|
+
let touched = 0;
|
|
39
|
+
const walk = (d) => {
|
|
40
|
+
for (const entry of readdirSync(d)) {
|
|
41
|
+
const p = join(d, entry);
|
|
42
|
+
const st = statSync(p);
|
|
43
|
+
if (st.isDirectory()) {
|
|
44
|
+
walk(p);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (/\.(js|html|json|mjs|css)$/.test(entry)) {
|
|
48
|
+
const original = readFileSync(p, "utf8");
|
|
49
|
+
if (original.includes(from)) {
|
|
50
|
+
writeFileSync(p, original.split(from).join(to), "utf8");
|
|
51
|
+
touched++;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
walk(dir);
|
|
57
|
+
return touched;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 为实例生成 unpacked 扩展目录。
|
|
61
|
+
*
|
|
62
|
+
* 步骤:rm 旧目录 → mkdir → copy 模板 → 替换占位符 → 写 metadata。
|
|
63
|
+
* 幂等:重复调用会清空重建。
|
|
64
|
+
*
|
|
65
|
+
* @returns 被替换占位符的文件数 + metadata
|
|
66
|
+
*/
|
|
67
|
+
export function prepareExtension(cfg) {
|
|
68
|
+
const templateDir = extensionTemplateDir();
|
|
69
|
+
if (!existsSync(templateDir)) {
|
|
70
|
+
throw new Error(`extension template not found: ${templateDir}\n` +
|
|
71
|
+
`hint: 包发布时漏了 browser-op/webplater/dist,或跑 npm run build:extension 重建。`);
|
|
72
|
+
}
|
|
73
|
+
const targetDir = cfg.extensionDir;
|
|
74
|
+
// 清空重建(幂等)
|
|
75
|
+
rmSync(targetDir, { recursive: true, force: true });
|
|
76
|
+
mkdirSync(targetDir, { recursive: true });
|
|
77
|
+
// copy 模板 → 实例 extensionDir
|
|
78
|
+
cpSync(templateDir, targetDir, { recursive: true, force: true });
|
|
79
|
+
// 替换占位符
|
|
80
|
+
const hostWsUrl = `ws://127.0.0.1:${cfg.extensionPort}`;
|
|
81
|
+
const replacedFiles = replaceInDir(targetDir, HOST_WS_URL_PLACEHOLDER, hostWsUrl);
|
|
82
|
+
// 验证占位符确实被换掉了(否则扩展连不上)
|
|
83
|
+
if (replacedFiles === 0) {
|
|
84
|
+
// 扫一下目标里还有没有残留占位符
|
|
85
|
+
const stillHasPlaceholder = readFileSync(join(targetDir, "chunks", readdirSync(join(targetDir, "chunks")).find((f) => f.startsWith("offscreen-")) || ""), "utf8").includes(HOST_WS_URL_PLACEHOLDER);
|
|
86
|
+
if (stillHasPlaceholder) {
|
|
87
|
+
throw new Error(`placeholder ${HOST_WS_URL_PLACEHOLDER} 未被替换(模板可能不含占位符,需检查 browser-op/webplater/dist)`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// 写 metadata
|
|
91
|
+
const metadata = {
|
|
92
|
+
instance: cfg.name,
|
|
93
|
+
extensionPort: cfg.extensionPort,
|
|
94
|
+
hostWsUrl,
|
|
95
|
+
generatedAt: new Date().toISOString(),
|
|
96
|
+
sourceBuildVersion: readTemplateManifestVersion(templateDir),
|
|
97
|
+
};
|
|
98
|
+
writeFileSync(join(targetDir, METADATA_FILENAME), JSON.stringify(metadata, null, 2) + "\n", "utf8");
|
|
99
|
+
return { replacedFiles, metadata, templateDir };
|
|
100
|
+
}
|
|
101
|
+
/** 读实例 extensionDir 的 metadata。不存在返回 null。 */
|
|
102
|
+
export function readInstanceMetadata(cfg) {
|
|
103
|
+
const p = join(cfg.extensionDir, METADATA_FILENAME);
|
|
104
|
+
if (!existsSync(p))
|
|
105
|
+
return null;
|
|
106
|
+
try {
|
|
107
|
+
return JSON.parse(readFileSync(p, "utf8"));
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 校验实例 extensionDir 是否就绪(用于 start --route extension 前置检查)。
|
|
115
|
+
* 返回 null 表示就绪;返回字符串表示需要重 prepare 的原因。
|
|
116
|
+
*/
|
|
117
|
+
export function verifyInstanceExtension(cfg) {
|
|
118
|
+
if (!existsSync(cfg.extensionDir)) {
|
|
119
|
+
return `extension dir 不存在: ${cfg.extensionDir}`;
|
|
120
|
+
}
|
|
121
|
+
if (!existsSync(join(cfg.extensionDir, METADATA_FILENAME))) {
|
|
122
|
+
return `metadata 缺失(.mooncat-instance.json),可能是手动建的目录`;
|
|
123
|
+
}
|
|
124
|
+
const meta = readInstanceMetadata(cfg);
|
|
125
|
+
if (!meta)
|
|
126
|
+
return `metadata 解析失败`;
|
|
127
|
+
if (meta.extensionPort !== cfg.extensionPort) {
|
|
128
|
+
return `端口已变(metadata=${meta.extensionPort}, cfg=${cfg.extensionPort})`;
|
|
129
|
+
}
|
|
130
|
+
const currentTemplateVersion = (() => {
|
|
131
|
+
try {
|
|
132
|
+
const m = JSON.parse(readFileSync(join(extensionTemplateDir(), "manifest.json"), "utf8"));
|
|
133
|
+
return m.version || "unknown";
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return "unknown";
|
|
137
|
+
}
|
|
138
|
+
})();
|
|
139
|
+
if (meta.sourceBuildVersion !== currentTemplateVersion) {
|
|
140
|
+
return `包升级了(metadata=${meta.sourceBuildVersion}, current=${currentTemplateVersion})`;
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=prepare-extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare-extension.js","sourceRoot":"","sources":["../src/prepare-extension.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,35 +1,49 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
/** browserd.cjs
|
|
1
|
+
import { type BrowserInstanceConfig } from "./config.js";
|
|
2
|
+
/** browserd.cjs 路径:dist/ 在包根下,browser-op 在包根下。允许用环境变量覆盖(开发态)。 */
|
|
3
3
|
export declare function browserdScriptPath(): string;
|
|
4
|
-
/** wrapper
|
|
5
|
-
export declare function serviceStatePath(
|
|
6
|
-
/** wrapper
|
|
4
|
+
/** 实例的 wrapper 状态文件路径(放实例 stateDir)。 */
|
|
5
|
+
export declare function serviceStatePath(cfg: BrowserInstanceConfig): string;
|
|
6
|
+
/** wrapper 进程状态(stop/status 命令据此定位 healthPort)。 */
|
|
7
7
|
export interface ServiceState {
|
|
8
8
|
pid: number;
|
|
9
|
+
instance: string;
|
|
9
10
|
rpcPort: number;
|
|
10
11
|
healthPort: number;
|
|
11
|
-
|
|
12
|
+
extensionPort: number;
|
|
13
|
+
profileDir: string;
|
|
14
|
+
stateDir: string;
|
|
15
|
+
logsDir: string;
|
|
12
16
|
startedAt: string;
|
|
13
17
|
}
|
|
14
|
-
/**
|
|
18
|
+
/** /health 返回结构(增强版:含 instance 标识 + browserd 真实字段)。 */
|
|
15
19
|
export interface ServiceStatus {
|
|
16
20
|
ok: boolean;
|
|
17
21
|
status: "ok" | "degraded" | "down" | "stopping";
|
|
22
|
+
instance: string;
|
|
18
23
|
rpcPort: number;
|
|
19
24
|
healthPort: number;
|
|
25
|
+
extensionPort: number;
|
|
26
|
+
profileDir: string;
|
|
27
|
+
stateDir: string;
|
|
28
|
+
logsDir: string;
|
|
20
29
|
browserd: boolean;
|
|
21
30
|
browserdPid: number | null;
|
|
31
|
+
chromePid: number | null;
|
|
32
|
+
/** wrapper(本进程)pid,用于 list/status 校验响应来自 state 记录的同一进程。 */
|
|
33
|
+
wrapperPid: number;
|
|
34
|
+
mode: string | null;
|
|
35
|
+
pageCount: number;
|
|
36
|
+
browserOpen: boolean;
|
|
22
37
|
lastExit: {
|
|
23
38
|
code: number | string | null;
|
|
24
39
|
at: string;
|
|
25
40
|
} | null;
|
|
26
|
-
profile: string;
|
|
27
41
|
}
|
|
28
42
|
/**
|
|
29
43
|
* browserd 服务包装器。
|
|
30
44
|
*
|
|
31
|
-
* 用 startService(cfg)
|
|
32
|
-
*
|
|
45
|
+
* 用 startService(cfg) 启动;返回的对象含 stop() 用于 graceful 关闭。
|
|
46
|
+
* 进程信号(SIGINT/SIGTERM)会触发 graceful 关闭。
|
|
33
47
|
*/
|
|
34
48
|
export declare class BrowserService {
|
|
35
49
|
private readonly cfg;
|
|
@@ -40,27 +54,30 @@ export declare class BrowserService {
|
|
|
40
54
|
private restartTimer;
|
|
41
55
|
private healthServer;
|
|
42
56
|
private shuttingDown;
|
|
43
|
-
constructor(cfg:
|
|
57
|
+
constructor(cfg: BrowserInstanceConfig);
|
|
44
58
|
private log;
|
|
45
|
-
/** 启动 wrapper
|
|
59
|
+
/** 启动 wrapper:写 pidfile + spawn browserd + 起 health server + 注册信号。 */
|
|
46
60
|
start(): Promise<void>;
|
|
47
|
-
/** spawn browserd
|
|
61
|
+
/** spawn browserd 子进程(崩溃自动重启,除非 stopping)。 */
|
|
48
62
|
private startBrowserd;
|
|
49
|
-
/**
|
|
63
|
+
/** 拉一次 browserd /health,合并 wrapper 状态成完整 status。 */
|
|
50
64
|
status(): Promise<ServiceStatus>;
|
|
51
65
|
/**
|
|
52
|
-
* Graceful
|
|
53
|
-
* 1. 标记 stopping
|
|
54
|
-
* 2. 发 close 给 browserd
|
|
55
|
-
* 3. 等 browserd
|
|
66
|
+
* Graceful 关闭:
|
|
67
|
+
* 1. 标记 stopping(阻止重启)
|
|
68
|
+
* 2. 发 close 给 browserd(browserd graceful 关 Chrome,保留登录态)
|
|
69
|
+
* 3. 等 browserd 退出(最多 10s),仍未退则 kill
|
|
56
70
|
* 4. 关 health server + 删 pidfile + exit
|
|
57
71
|
*/
|
|
58
72
|
stop(): Promise<void>;
|
|
59
|
-
/** 等 browserd
|
|
73
|
+
/** 等 browserd 子进程退出,最多 timeoutMs;超时则 SIGKILL。 */
|
|
60
74
|
private waitForBrowserdExit;
|
|
61
75
|
}
|
|
62
|
-
/**
|
|
63
|
-
export declare function startService(cfg:
|
|
64
|
-
/**
|
|
65
|
-
|
|
76
|
+
/** 便捷入口:用实例配置启动 wrapper(CLI start 命令调用)。 */
|
|
77
|
+
export declare function startService(cfg: BrowserInstanceConfig): Promise<BrowserService>;
|
|
78
|
+
/**
|
|
79
|
+
* 按"项目配置 + 实例名"读取已运行 wrapper 的状态(stop/status 命令定位用)。
|
|
80
|
+
* state 文件在实例 stateDir/service.json。
|
|
81
|
+
*/
|
|
82
|
+
export declare function readServiceState(cfg: BrowserInstanceConfig): ServiceState | null;
|
|
66
83
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAe,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAItE,iEAAiE;AACjE,wBAAgB,kBAAkB,IAAI,MAAM,CAK3C;AAED,wCAAwC;AACxC,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAEnE;AAED,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAaD,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,MAAM,GAAG,UAAU,CAAC;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC/D;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAwB;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IACjE,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,QAAQ,CAA6D;IAC7E,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,YAAY,CAAS;gBAEjB,GAAG,EAAE,qBAAqB;IAOtC,OAAO,CAAC,GAAG;IAUX,sEAAsE;IAChE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiD5B,8CAA8C;IAC9C,OAAO,CAAC,aAAa;IA0BrB,oDAAoD;IAC9C,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;IAwCtC;;;;;;OAMG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+C3B,iDAAiD;IACjD,OAAO,CAAC,mBAAmB;CAsB5B;AAED,4CAA4C;AAC5C,wBAAsB,YAAY,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAItF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,qBAAqB,GAAG,YAAY,GAAG,IAAI,CAShF"}
|
package/dist/server.js
CHANGED
|
@@ -1,41 +1,39 @@
|
|
|
1
1
|
// -*- coding: utf-8 -*-
|
|
2
2
|
// server.ts — @mooncat/browser 服务包装层。
|
|
3
3
|
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// ->
|
|
8
|
-
// -> wrapper spawn browserd.cjs(RPC on rpcPort)
|
|
4
|
+
// 形态:
|
|
5
|
+
// mooncat-browser start <name>
|
|
6
|
+
// -> 启动本 wrapper(health server on instance.healthPort)
|
|
7
|
+
// -> wrapper spawn browserd.cjs(RPC on instance.rpcPort)
|
|
9
8
|
// -> GET /health 代理 browserd /health + wrapper 状态
|
|
10
9
|
// -> POST /shutdown graceful:发 close 给 browserd(graceful 关 Chrome),
|
|
11
10
|
// 等其退出,wrapper 退出(不重启)
|
|
12
11
|
//
|
|
13
12
|
// browserd 崩溃(非 shutdown)时 wrapper 自动 3s 后重启。
|
|
14
13
|
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
// 把本包的配置语义桥接给 browserd。
|
|
14
|
+
// 一个 browser 实例 = 一个 wrapper = 一个 browserd = 一个 Chrome = 一份 profile
|
|
15
|
+
// = 一组端口 + 一套 state/log,实例间在文件系统与端口上完全隔离。
|
|
18
16
|
import http from "node:http";
|
|
19
17
|
import { spawn } from "node:child_process";
|
|
20
18
|
import { createWriteStream, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
21
19
|
import { join } from "node:path";
|
|
22
20
|
import { fileURLToPath } from "node:url";
|
|
23
|
-
import {
|
|
21
|
+
import { browserdEnv } from "./config.js";
|
|
24
22
|
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
25
|
-
/** browserd.cjs
|
|
23
|
+
/** browserd.cjs 路径:dist/ 在包根下,browser-op 在包根下。允许用环境变量覆盖(开发态)。 */
|
|
26
24
|
export function browserdScriptPath() {
|
|
27
25
|
return (process.env.MOONCAT_BROWSERD_BIN ||
|
|
28
26
|
join(__dirname, "..", "browser-op", "backend", "browserd.cjs"));
|
|
29
27
|
}
|
|
30
|
-
/** wrapper
|
|
31
|
-
export function serviceStatePath(
|
|
32
|
-
return join(
|
|
28
|
+
/** 实例的 wrapper 状态文件路径(放实例 stateDir)。 */
|
|
29
|
+
export function serviceStatePath(cfg) {
|
|
30
|
+
return join(cfg.stateDir, "service.json");
|
|
33
31
|
}
|
|
34
32
|
/**
|
|
35
33
|
* browserd 服务包装器。
|
|
36
34
|
*
|
|
37
|
-
* 用 startService(cfg)
|
|
38
|
-
*
|
|
35
|
+
* 用 startService(cfg) 启动;返回的对象含 stop() 用于 graceful 关闭。
|
|
36
|
+
* 进程信号(SIGINT/SIGTERM)会触发 graceful 关闭。
|
|
39
37
|
*/
|
|
40
38
|
export class BrowserService {
|
|
41
39
|
cfg;
|
|
@@ -49,6 +47,7 @@ export class BrowserService {
|
|
|
49
47
|
constructor(cfg) {
|
|
50
48
|
this.cfg = cfg;
|
|
51
49
|
mkdirSync(this.cfg.logsDir, { recursive: true });
|
|
50
|
+
mkdirSync(this.cfg.stateDir, { recursive: true });
|
|
52
51
|
this.logStream = createWriteStream(join(this.cfg.logsDir, "service.log"), { flags: "a" });
|
|
53
52
|
}
|
|
54
53
|
log(msg) {
|
|
@@ -61,17 +60,21 @@ export class BrowserService {
|
|
|
61
60
|
/* 日志写入失败不阻塞主流程 */
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
|
-
/** 启动 wrapper
|
|
63
|
+
/** 启动 wrapper:写 pidfile + spawn browserd + 起 health server + 注册信号。 */
|
|
65
64
|
async start() {
|
|
66
65
|
const state = {
|
|
67
66
|
pid: process.pid,
|
|
67
|
+
instance: this.cfg.name,
|
|
68
68
|
rpcPort: this.cfg.rpcPort,
|
|
69
69
|
healthPort: this.cfg.healthPort,
|
|
70
|
-
|
|
70
|
+
extensionPort: this.cfg.extensionPort,
|
|
71
|
+
profileDir: this.cfg.profileDir,
|
|
72
|
+
stateDir: this.cfg.stateDir,
|
|
73
|
+
logsDir: this.cfg.logsDir,
|
|
71
74
|
startedAt: new Date().toISOString(),
|
|
72
75
|
};
|
|
73
|
-
writeFileSync(serviceStatePath(this.cfg
|
|
74
|
-
this.log(`service wrapper started pid=${process.pid} (rpc :${this.cfg.rpcPort}, health :${this.cfg.healthPort})`);
|
|
76
|
+
writeFileSync(serviceStatePath(this.cfg), JSON.stringify(state, null, 2), "utf8");
|
|
77
|
+
this.log(`service wrapper started pid=${process.pid} instance=${this.cfg.name} (rpc :${this.cfg.rpcPort}, health :${this.cfg.healthPort})`);
|
|
75
78
|
this.startBrowserd();
|
|
76
79
|
this.healthServer = http.createServer(async (req, res) => {
|
|
77
80
|
res.setHeader("Content-Type", "application/json");
|
|
@@ -100,7 +103,7 @@ export class BrowserService {
|
|
|
100
103
|
process.on("SIGINT", shutdownSignal("SIGINT"));
|
|
101
104
|
process.on("SIGTERM", shutdownSignal("SIGTERM"));
|
|
102
105
|
}
|
|
103
|
-
/** spawn browserd
|
|
106
|
+
/** spawn browserd 子进程(崩溃自动重启,除非 stopping)。 */
|
|
104
107
|
startBrowserd() {
|
|
105
108
|
const env = { ...process.env, ...browserdEnv(this.cfg) };
|
|
106
109
|
this.browserd = spawn(process.execPath, [browserdScriptPath()], {
|
|
@@ -114,7 +117,7 @@ export class BrowserService {
|
|
|
114
117
|
this.log(`browserd exited code=${code} signal=${signal}`);
|
|
115
118
|
this.browserd = null;
|
|
116
119
|
if (this.stopping) {
|
|
117
|
-
//
|
|
120
|
+
// 主动关闭触发的退出,不重启;由 stop() 继续收尾
|
|
118
121
|
return;
|
|
119
122
|
}
|
|
120
123
|
// 非主动退出 → 3s 后重启
|
|
@@ -126,13 +129,14 @@ export class BrowserService {
|
|
|
126
129
|
}, 3000);
|
|
127
130
|
});
|
|
128
131
|
}
|
|
129
|
-
/**
|
|
132
|
+
/** 拉一次 browserd /health,合并 wrapper 状态成完整 status。 */
|
|
130
133
|
async status() {
|
|
131
134
|
let browserdUp = false;
|
|
135
|
+
let bd = {};
|
|
132
136
|
try {
|
|
133
137
|
const resp = await fetch(`http://127.0.0.1:${this.cfg.rpcPort}/health`);
|
|
134
138
|
if (resp.ok) {
|
|
135
|
-
await resp.
|
|
139
|
+
bd = (await resp.json());
|
|
136
140
|
browserdUp = true;
|
|
137
141
|
}
|
|
138
142
|
}
|
|
@@ -149,19 +153,28 @@ export class BrowserService {
|
|
|
149
153
|
return {
|
|
150
154
|
ok: status === "ok",
|
|
151
155
|
status,
|
|
156
|
+
instance: this.cfg.name,
|
|
152
157
|
rpcPort: this.cfg.rpcPort,
|
|
153
158
|
healthPort: this.cfg.healthPort,
|
|
159
|
+
extensionPort: this.cfg.extensionPort,
|
|
160
|
+
profileDir: this.cfg.profileDir,
|
|
161
|
+
stateDir: this.cfg.stateDir,
|
|
162
|
+
logsDir: this.cfg.logsDir,
|
|
154
163
|
browserd: browserdUp,
|
|
155
164
|
browserdPid: this.browserd?.pid ?? null,
|
|
165
|
+
chromePid: bd.pid ?? null,
|
|
166
|
+
wrapperPid: process.pid,
|
|
167
|
+
mode: bd.mode ?? null,
|
|
168
|
+
pageCount: bd.pageCount ?? 0,
|
|
169
|
+
browserOpen: bd.browserOpen ?? false,
|
|
156
170
|
lastExit: this.lastExit,
|
|
157
|
-
profile: this.cfg.profile,
|
|
158
171
|
};
|
|
159
172
|
}
|
|
160
173
|
/**
|
|
161
|
-
* Graceful
|
|
162
|
-
* 1. 标记 stopping
|
|
163
|
-
* 2. 发 close 给 browserd
|
|
164
|
-
* 3. 等 browserd
|
|
174
|
+
* Graceful 关闭:
|
|
175
|
+
* 1. 标记 stopping(阻止重启)
|
|
176
|
+
* 2. 发 close 给 browserd(browserd graceful 关 Chrome,保留登录态)
|
|
177
|
+
* 3. 等 browserd 退出(最多 10s),仍未退则 kill
|
|
165
178
|
* 4. 关 health server + 删 pidfile + exit
|
|
166
179
|
*/
|
|
167
180
|
async stop() {
|
|
@@ -174,7 +187,7 @@ export class BrowserService {
|
|
|
174
187
|
this.restartTimer = null;
|
|
175
188
|
}
|
|
176
189
|
this.log(`graceful shutdown begin`);
|
|
177
|
-
// 1) 发 close 给 browserd
|
|
190
|
+
// 1) 发 close 给 browserd(graceful 关 Chrome)
|
|
178
191
|
try {
|
|
179
192
|
const body = JSON.stringify({ id: 1, method: "close", params: {} });
|
|
180
193
|
await fetch(`http://127.0.0.1:${this.cfg.rpcPort}/rpc`, {
|
|
@@ -197,7 +210,7 @@ export class BrowserService {
|
|
|
197
210
|
});
|
|
198
211
|
// 4) 删 pidfile + exit
|
|
199
212
|
try {
|
|
200
|
-
unlinkSync(serviceStatePath(this.cfg
|
|
213
|
+
unlinkSync(serviceStatePath(this.cfg));
|
|
201
214
|
}
|
|
202
215
|
catch {
|
|
203
216
|
/* ignore */
|
|
@@ -211,7 +224,7 @@ export class BrowserService {
|
|
|
211
224
|
}
|
|
212
225
|
process.exit(0);
|
|
213
226
|
}
|
|
214
|
-
/** 等 browserd
|
|
227
|
+
/** 等 browserd 子进程退出,最多 timeoutMs;超时则 SIGKILL。 */
|
|
215
228
|
waitForBrowserdExit(timeoutMs) {
|
|
216
229
|
return new Promise((resolve) => {
|
|
217
230
|
if (!this.browserd)
|
|
@@ -237,15 +250,18 @@ export class BrowserService {
|
|
|
237
250
|
});
|
|
238
251
|
}
|
|
239
252
|
}
|
|
240
|
-
/**
|
|
253
|
+
/** 便捷入口:用实例配置启动 wrapper(CLI start 命令调用)。 */
|
|
241
254
|
export async function startService(cfg) {
|
|
242
255
|
const svc = new BrowserService(cfg);
|
|
243
256
|
await svc.start();
|
|
244
257
|
return svc;
|
|
245
258
|
}
|
|
246
|
-
/**
|
|
247
|
-
|
|
248
|
-
|
|
259
|
+
/**
|
|
260
|
+
* 按"项目配置 + 实例名"读取已运行 wrapper 的状态(stop/status 命令定位用)。
|
|
261
|
+
* state 文件在实例 stateDir/service.json。
|
|
262
|
+
*/
|
|
263
|
+
export function readServiceState(cfg) {
|
|
264
|
+
const f = serviceStatePath(cfg);
|
|
249
265
|
if (!existsSync(f))
|
|
250
266
|
return null;
|
|
251
267
|
try {
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,sCAAsC;AACtC,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|