@sfmc-bds/cli 0.2.0-beta.13 → 0.2.0-beta.15
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/command-surface.js +1 -1
- package/dist/command-surface.js.map +2 -2
- package/dist/i18n/locales/en.d.ts +10 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +10 -0
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.d.ts.map +1 -1
- package/dist/i18n/locales/zh-CN.js +10 -0
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/module-pack-build.d.ts +14 -4
- package/dist/module-pack-build.d.ts.map +1 -1
- package/dist/module-pack-build.js +73 -105
- package/dist/module-pack-build.js.map +2 -2
- package/dist/pack-bundle.test.js +105 -0
- package/dist/pack-bundle.test.js.map +7 -0
- package/dist/pack-lifecycle.d.ts +14 -1
- package/dist/pack-lifecycle.d.ts.map +1 -1
- package/dist/pack-lifecycle.js +222 -11
- package/dist/pack-lifecycle.js.map +2 -2
- package/dist/repl-windows/host.d.ts +6 -3
- package/dist/repl-windows/host.d.ts.map +1 -1
- package/dist/repl-windows/host.js +12 -6
- package/dist/repl-windows/host.js.map +2 -2
- package/dist/repl-windows/host.test.js +72 -0
- package/dist/repl-windows/host.test.js.map +7 -0
- package/dist/repl-windows/index.d.ts +1 -0
- package/dist/repl-windows/index.d.ts.map +1 -1
- package/dist/repl-windows/index.js +3 -0
- package/dist/repl-windows/index.js.map +2 -2
- package/dist/repl-windows/sfmc-window.d.ts +7 -0
- package/dist/repl-windows/sfmc-window.d.ts.map +1 -0
- package/dist/repl-windows/sfmc-window.js +28 -0
- package/dist/repl-windows/sfmc-window.js.map +7 -0
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +21 -7
- package/dist/repl.js.map +2 -2
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +10 -0
- package/dist/runtime.js.map +2 -2
- package/dist/send-target.d.ts +2 -0
- package/dist/send-target.d.ts.map +1 -1
- package/dist/send-target.js +4 -0
- package/dist/send-target.js.map +2 -2
- package/dist/world-packs.d.ts.map +1 -1
- package/dist/world-packs.js +84 -13
- package/dist/world-packs.js.map +3 -3
- package/package.json +4 -4
- package/scripts/module-install/check-modules.mjs +42 -2
- package/scripts/module-install/fetch-module.mjs +70 -46
- package/scripts/module-install/lib/config-seeding.mjs +128 -0
- package/scripts/module-install/test/check-modules-config.test.ts +46 -0
- package/scripts/module-install/test/config-seeding.test.ts +99 -0
|
@@ -34,15 +34,18 @@ export declare class WindowHost {
|
|
|
34
34
|
setBuffer(id: string, lines: string[]): void;
|
|
35
35
|
invalidateBuffer(id: string): void;
|
|
36
36
|
private appendToBuffer;
|
|
37
|
-
/**
|
|
37
|
+
/** 按活跃服务与平台窗同步轮转 id 列表(id = svc:<name> 或 sfmc) */
|
|
38
38
|
setServiceOrder(ids: string[]): void;
|
|
39
39
|
open(id: string): boolean;
|
|
40
40
|
back(): boolean;
|
|
41
41
|
/**
|
|
42
|
-
*
|
|
42
|
+
* 在服务窗与平台窗之间循环;返回是否成功切换及新激活窗的 serviceName(供同步发送目标)。
|
|
43
43
|
* 若当前在非服务窗,先回到服务环。
|
|
44
44
|
*/
|
|
45
|
-
cycleServiceWindows():
|
|
45
|
+
cycleServiceWindows(): {
|
|
46
|
+
switched: boolean;
|
|
47
|
+
serviceName: ServiceName | null;
|
|
48
|
+
};
|
|
46
49
|
/**
|
|
47
50
|
* 新日志:写入所有已 seed 缓存且 accept 的窗口;仅活动窗刷到 TTY。
|
|
48
51
|
* 活动窗尚未 seed:只刷 TTY(随后 showActiveWindow 会 seed 含历史的缓存)。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/repl-windows/host.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/repl-windows/host.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE5F,MAAM,MAAM,YAAY,GAAG,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;AAEzD,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,6CAA6C;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,qBAAqB;IACrB,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA2B;IAE1D,YAAY,IAAI,EAAE;QAAE,QAAQ,EAAE,YAAY,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,EAGxE;IAED,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAE9B;IAED,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAS3B;IAED,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEvB;IAED,SAAS,IAAI,UAAU,GAAG,SAAS,CAElC;IAED,WAAW,IAAI,MAAM,GAAG,IAAI,CAE3B;IAED,SAAS,IAAI,YAAY,CAUxB;IAED,6BAA6B;IAC7B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE7B;IAED,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAEvC;IAED,iBAAiB;IACjB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAE3C;IAED,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAEjC;IAED,OAAO,CAAC,cAAc;IAStB,kDAAkD;IAClD,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAqBnC;IAED,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAiBxB;IAED,IAAI,IAAI,OAAO,CAYd;IAED;;;OAGG;IACH,mBAAmB,IAAI;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAAA;KAAE,CAc5E;IAED;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAe9B;IAED,iCAAiC;IACjC,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAIxE;IAED,KAAK,CAAC,EAAE,EAAE,cAAc,GAAG,eAAe,CASzC;IAED,YAAY,IAAI,OAAO,CAEtB;CACF;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAEzD"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { wrapLogLine } from "../logs.js";
|
|
2
|
+
import { SFMC_WINDOW_ID } from "./sfmc-window.js";
|
|
2
3
|
class WindowHost {
|
|
3
4
|
windows = /* @__PURE__ */ new Map();
|
|
4
5
|
/** 窗口 id → 已渲染(已 wrap)的行;切回时直接 dump,无需重拉源 */
|
|
@@ -68,17 +69,19 @@ class WindowHost {
|
|
|
68
69
|
}
|
|
69
70
|
buf.push(wrappedLine);
|
|
70
71
|
}
|
|
71
|
-
/**
|
|
72
|
+
/** 按活跃服务与平台窗同步轮转 id 列表(id = svc:<name> 或 sfmc) */
|
|
72
73
|
setServiceOrder(ids) {
|
|
73
74
|
this.serviceOrder = [...ids];
|
|
74
|
-
const stale = [...this.windows.keys()].filter(
|
|
75
|
+
const stale = [...this.windows.keys()].filter(
|
|
76
|
+
(id) => (id.startsWith("svc:") || id === SFMC_WINDOW_ID) && !ids.includes(id)
|
|
77
|
+
);
|
|
75
78
|
for (const id of stale) {
|
|
76
79
|
this.windows.delete(id);
|
|
77
80
|
this.buffers.delete(id);
|
|
78
81
|
if (this.activeId === id) this.activeId = null;
|
|
79
82
|
if (this.previousId === id) this.previousId = null;
|
|
80
83
|
}
|
|
81
|
-
if (this.activeId
|
|
84
|
+
if (this.activeId && (this.activeId.startsWith("svc:") || this.activeId === SFMC_WINDOW_ID) && !ids.includes(this.activeId)) {
|
|
82
85
|
this.activeId = null;
|
|
83
86
|
}
|
|
84
87
|
if (!this.activeId && ids.length > 0) {
|
|
@@ -114,11 +117,11 @@ class WindowHost {
|
|
|
114
117
|
return this.open(fallback);
|
|
115
118
|
}
|
|
116
119
|
/**
|
|
117
|
-
*
|
|
120
|
+
* 在服务窗与平台窗之间循环;返回是否成功切换及新激活窗的 serviceName(供同步发送目标)。
|
|
118
121
|
* 若当前在非服务窗,先回到服务环。
|
|
119
122
|
*/
|
|
120
123
|
cycleServiceWindows() {
|
|
121
|
-
if (this.serviceOrder.length === 0) return null;
|
|
124
|
+
if (this.serviceOrder.length === 0) return { switched: false, serviceName: null };
|
|
122
125
|
const cur = this.activeId;
|
|
123
126
|
const idx = cur ? this.serviceOrder.indexOf(cur) : -1;
|
|
124
127
|
if (idx < 0) {
|
|
@@ -127,7 +130,10 @@ class WindowHost {
|
|
|
127
130
|
const next = this.serviceOrder[(idx + 1) % this.serviceOrder.length];
|
|
128
131
|
this.open(next);
|
|
129
132
|
}
|
|
130
|
-
return
|
|
133
|
+
return {
|
|
134
|
+
switched: true,
|
|
135
|
+
serviceName: this.getActive()?.serviceName ?? null
|
|
136
|
+
};
|
|
131
137
|
}
|
|
132
138
|
/**
|
|
133
139
|
* 新日志:写入所有已 seed 缓存且 accept 的窗口;仅活动窗刷到 TTY。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/repl-windows/host.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * repl-windows/host.ts \u2014 \u7A97\u53E3\u6CE8\u518C\u4E0E\u5207\u6362\uFF08\u4E0D\u5199\u4E1A\u52A1\uFF0C\u53EA\u8C03\u5EA6 ReplWindow\uFF09\n *\n * \u6BCF\u6247\u7A97\u7EF4\u62A4\u5DF2\u6E32\u67D3\u884C\u7F13\u5B58\uFF1A\u5207\u8D70\u6E05\u5C4F\uFF0C\u5207\u56DE\u76F4\u63A5\u6062\u590D\uFF1B\u540E\u53F0\u4ECD\u628A\u5339\u914D\u65E5\u5FD7\u5199\u5165\u5BF9\u5E94\u7F13\u5B58\u3002\n */\nimport { wrapLogLine, type UnifiedLog } from \"../logs.js\";\nimport type { ServiceName } from \"../services.js\";\nimport type { ReplWindow, WindowChrome, WindowKeyEvent, WindowKeyResult } from \"./types.js\";\n\nexport type HostWriteLog = (wrappedLine: string) => void;\n\nexport class WindowHost {\n private readonly windows = new Map<string, ReplWindow>();\n /** \u7A97\u53E3 id \u2192 \u5DF2\u6E32\u67D3\uFF08\u5DF2 wrap\uFF09\u7684\u884C\uFF1B\u5207\u56DE\u65F6\u76F4\u63A5 dump\uFF0C\u65E0\u9700\u91CD\u62C9\u6E90 */\n private readonly buffers = new Map<string, string[]>();\n /** \u670D\u52A1\u7A97\u5FAA\u73AF\u987A\u5E8F\uFF08\u4EC5\u6D3B\u8DC3\u670D\u52A1\uFF09 */\n private serviceOrder: string[] = [];\n private activeId: string | null = null;\n private previousId: string | null = null;\n private readonly writeLog: HostWriteLog;\n private readonly onChromeChange: (() => void) | undefined;\n\n constructor(opts: { writeLog: HostWriteLog; onChromeChange?: () => void }) {\n this.writeLog = opts.writeLog;\n this.onChromeChange = opts.onChromeChange;\n }\n\n register(win: ReplWindow): void {\n this.windows.set(win.id, win);\n }\n\n unregister(id: string): void {\n if (this.activeId === id) {\n this.activeId = this.previousId;\n this.previousId = null;\n }\n if (this.previousId === id) this.previousId = null;\n this.windows.delete(id);\n this.buffers.delete(id);\n this.serviceOrder = this.serviceOrder.filter((x) => x !== id);\n }\n\n has(id: string): boolean {\n return this.windows.has(id);\n }\n\n getActive(): ReplWindow | undefined {\n return this.activeId ? this.windows.get(this.activeId) : undefined;\n }\n\n getActiveId(): string | null {\n return this.activeId;\n }\n\n getChrome(): WindowChrome {\n const w = this.getActive();\n if (!w) {\n return { showsInput: true, footerShortcuts: \"\", title: \"\" };\n }\n return {\n showsInput: w.showsInput,\n footerShortcuts: w.footerShortcuts,\n title: w.title,\n };\n }\n\n /** \u662F\u5426\u5DF2\u6709\u5C55\u793A\u7F13\u5B58\uFF08\u6709\u5219\u5207\u56DE\u65F6\u52FF\u518D seed\uFF09 */\n hasBuffer(id: string): boolean {\n return this.buffers.has(id);\n }\n\n getBuffer(id: string): readonly string[] {\n return this.buffers.get(id) ?? [];\n }\n\n /** \u9996\u6B21\u8FDB\u5165\u65F6\u5199\u5165\u79CD\u5B50\u884C */\n setBuffer(id: string, lines: string[]): void {\n this.buffers.set(id, [...lines]);\n }\n\n invalidateBuffer(id: string): void {\n this.buffers.delete(id);\n }\n\n private appendToBuffer(id: string, wrappedLine: string): void {\n let buf = this.buffers.get(id);\n if (!buf) {\n buf = [];\n this.buffers.set(id, buf);\n }\n buf.push(wrappedLine);\n }\n\n /** \u6309\u6D3B\u8DC3\u670D\u52A1\u540C\u6B65
|
|
5
|
-
"mappings": "AAKA,SAAS,mBAAoC;
|
|
4
|
+
"sourcesContent": ["/**\n * repl-windows/host.ts \u2014 \u7A97\u53E3\u6CE8\u518C\u4E0E\u5207\u6362\uFF08\u4E0D\u5199\u4E1A\u52A1\uFF0C\u53EA\u8C03\u5EA6 ReplWindow\uFF09\n *\n * \u6BCF\u6247\u7A97\u7EF4\u62A4\u5DF2\u6E32\u67D3\u884C\u7F13\u5B58\uFF1A\u5207\u8D70\u6E05\u5C4F\uFF0C\u5207\u56DE\u76F4\u63A5\u6062\u590D\uFF1B\u540E\u53F0\u4ECD\u628A\u5339\u914D\u65E5\u5FD7\u5199\u5165\u5BF9\u5E94\u7F13\u5B58\u3002\n */\nimport { wrapLogLine, type UnifiedLog } from \"../logs.js\";\nimport type { ServiceName } from \"../services.js\";\nimport { SFMC_WINDOW_ID } from \"./sfmc-window.js\";\nimport type { ReplWindow, WindowChrome, WindowKeyEvent, WindowKeyResult } from \"./types.js\";\n\nexport type HostWriteLog = (wrappedLine: string) => void;\n\nexport class WindowHost {\n private readonly windows = new Map<string, ReplWindow>();\n /** \u7A97\u53E3 id \u2192 \u5DF2\u6E32\u67D3\uFF08\u5DF2 wrap\uFF09\u7684\u884C\uFF1B\u5207\u56DE\u65F6\u76F4\u63A5 dump\uFF0C\u65E0\u9700\u91CD\u62C9\u6E90 */\n private readonly buffers = new Map<string, string[]>();\n /** \u670D\u52A1\u7A97\u5FAA\u73AF\u987A\u5E8F\uFF08\u4EC5\u6D3B\u8DC3\u670D\u52A1\uFF09 */\n private serviceOrder: string[] = [];\n private activeId: string | null = null;\n private previousId: string | null = null;\n private readonly writeLog: HostWriteLog;\n private readonly onChromeChange: (() => void) | undefined;\n\n constructor(opts: { writeLog: HostWriteLog; onChromeChange?: () => void }) {\n this.writeLog = opts.writeLog;\n this.onChromeChange = opts.onChromeChange;\n }\n\n register(win: ReplWindow): void {\n this.windows.set(win.id, win);\n }\n\n unregister(id: string): void {\n if (this.activeId === id) {\n this.activeId = this.previousId;\n this.previousId = null;\n }\n if (this.previousId === id) this.previousId = null;\n this.windows.delete(id);\n this.buffers.delete(id);\n this.serviceOrder = this.serviceOrder.filter((x) => x !== id);\n }\n\n has(id: string): boolean {\n return this.windows.has(id);\n }\n\n getActive(): ReplWindow | undefined {\n return this.activeId ? this.windows.get(this.activeId) : undefined;\n }\n\n getActiveId(): string | null {\n return this.activeId;\n }\n\n getChrome(): WindowChrome {\n const w = this.getActive();\n if (!w) {\n return { showsInput: true, footerShortcuts: \"\", title: \"\" };\n }\n return {\n showsInput: w.showsInput,\n footerShortcuts: w.footerShortcuts,\n title: w.title,\n };\n }\n\n /** \u662F\u5426\u5DF2\u6709\u5C55\u793A\u7F13\u5B58\uFF08\u6709\u5219\u5207\u56DE\u65F6\u52FF\u518D seed\uFF09 */\n hasBuffer(id: string): boolean {\n return this.buffers.has(id);\n }\n\n getBuffer(id: string): readonly string[] {\n return this.buffers.get(id) ?? [];\n }\n\n /** \u9996\u6B21\u8FDB\u5165\u65F6\u5199\u5165\u79CD\u5B50\u884C */\n setBuffer(id: string, lines: string[]): void {\n this.buffers.set(id, [...lines]);\n }\n\n invalidateBuffer(id: string): void {\n this.buffers.delete(id);\n }\n\n private appendToBuffer(id: string, wrappedLine: string): void {\n let buf = this.buffers.get(id);\n if (!buf) {\n buf = [];\n this.buffers.set(id, buf);\n }\n buf.push(wrappedLine);\n }\n\n /** \u6309\u6D3B\u8DC3\u670D\u52A1\u4E0E\u5E73\u53F0\u7A97\u540C\u6B65\u8F6E\u8F6C id \u5217\u8868\uFF08id = svc:<name> \u6216 sfmc\uFF09 */\n setServiceOrder(ids: string[]): void {\n this.serviceOrder = [...ids];\n const stale = [...this.windows.keys()].filter(\n (id) => (id.startsWith(\"svc:\") || id === SFMC_WINDOW_ID) && !ids.includes(id)\n );\n for (const id of stale) {\n this.windows.delete(id);\n this.buffers.delete(id);\n if (this.activeId === id) this.activeId = null;\n if (this.previousId === id) this.previousId = null;\n }\n if (\n this.activeId &&\n (this.activeId.startsWith(\"svc:\") || this.activeId === SFMC_WINDOW_ID) &&\n !ids.includes(this.activeId)\n ) {\n this.activeId = null;\n }\n if (!this.activeId && ids.length > 0) {\n this.open(ids[0]!);\n }\n }\n\n open(id: string): boolean {\n const next = this.windows.get(id);\n if (!next) return false;\n if (this.activeId === id) {\n next.onActivate?.();\n this.onChromeChange?.();\n return true;\n }\n const prev = this.getActive();\n prev?.onDeactivate?.();\n if (this.activeId && this.activeId !== id) {\n this.previousId = this.activeId;\n }\n this.activeId = id;\n next.onActivate?.();\n this.onChromeChange?.();\n return true;\n }\n\n back(): boolean {\n const fallback =\n (this.previousId && this.windows.has(this.previousId) ? this.previousId : null) ??\n this.serviceOrder.find((id) => this.windows.has(id)) ??\n null;\n this.previousId = null;\n if (!fallback) {\n this.activeId = null;\n this.onChromeChange?.();\n return false;\n }\n return this.open(fallback);\n }\n\n /**\n * \u5728\u670D\u52A1\u7A97\u4E0E\u5E73\u53F0\u7A97\u4E4B\u95F4\u5FAA\u73AF\uFF1B\u8FD4\u56DE\u662F\u5426\u6210\u529F\u5207\u6362\u53CA\u65B0\u6FC0\u6D3B\u7A97\u7684 serviceName\uFF08\u4F9B\u540C\u6B65\u53D1\u9001\u76EE\u6807\uFF09\u3002\n * \u82E5\u5F53\u524D\u5728\u975E\u670D\u52A1\u7A97\uFF0C\u5148\u56DE\u5230\u670D\u52A1\u73AF\u3002\n */\n cycleServiceWindows(): { switched: boolean; serviceName: ServiceName | null } {\n if (this.serviceOrder.length === 0) return { switched: false, serviceName: null };\n const cur = this.activeId;\n const idx = cur ? this.serviceOrder.indexOf(cur) : -1;\n if (idx < 0) {\n this.open(this.serviceOrder[0]!);\n } else {\n const next = this.serviceOrder[(idx + 1) % this.serviceOrder.length]!;\n this.open(next);\n }\n return {\n switched: true,\n serviceName: this.getActive()?.serviceName ?? null,\n };\n }\n\n /**\n * \u65B0\u65E5\u5FD7\uFF1A\u5199\u5165\u6240\u6709\u5DF2 seed \u7F13\u5B58\u4E14 accept \u7684\u7A97\u53E3\uFF1B\u4EC5\u6D3B\u52A8\u7A97\u5237\u5230 TTY\u3002\n * \u6D3B\u52A8\u7A97\u5C1A\u672A seed\uFF1A\u53EA\u5237 TTY\uFF08\u968F\u540E showActiveWindow \u4F1A seed \u542B\u5386\u53F2\u7684\u7F13\u5B58\uFF09\u3002\n */\n routeLog(log: UnifiedLog): void {\n for (const [id, w] of this.windows) {\n if (!w.acceptLog(log)) continue;\n if (!this.buffers.has(id)) {\n if (id === this.activeId) {\n const { text, indent } = w.formatLogLine(log);\n this.writeLog(wrapLogLine(text, indent));\n }\n continue;\n }\n const { text, indent } = w.formatLogLine(log);\n const wrapped = wrapLogLine(text, indent);\n this.appendToBuffer(id, wrapped);\n if (id === this.activeId) this.writeLog(wrapped);\n }\n }\n\n /** \u8FD4\u56DE\u6D3B\u52A8\u7A97\u5BF9\u65E5\u5FD7\u7684\u5C55\u793A\u7ED3\u679C\uFF08\u542B acceptLog\uFF09 */\n formatActiveLog(log: UnifiedLog): { text: string; indent: number } | null {\n const w = this.getActive();\n if (!w || !w.acceptLog(log)) return null;\n return w.formatLogLine(log);\n }\n\n onKey(ev: WindowKeyEvent): WindowKeyResult {\n const w = this.getActive();\n if (!w?.onKey) return { action: \"none\" };\n const r = w.onKey(ev);\n if (r.action === \"back\") {\n this.back();\n return { action: \"redraw\" };\n }\n return r;\n }\n\n isLogsActive(): boolean {\n return this.activeId === \"logs\";\n }\n}\n\nexport function serviceWindowId(name: ServiceName): string {\n return `svc:${name}`;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["text", "indent"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { WindowHost, serviceWindowId } from "./host.js";
|
|
4
|
+
import { createServiceWindow } from "./service-window.js";
|
|
5
|
+
import { createSfmcWindow, SFMC_WINDOW_ID } from "./sfmc-window.js";
|
|
6
|
+
test("WindowHost: \u7BA1\u7406\u670D\u52A1\u7A97\u4E0E SFMC \u5E73\u53F0\u7A97\u751F\u547D\u5468\u671F", () => {
|
|
7
|
+
const written = [];
|
|
8
|
+
const host = new WindowHost({ writeLog: (l) => written.push(l) });
|
|
9
|
+
let activeTargets = ["bds"];
|
|
10
|
+
host.register(createServiceWindow("bds"));
|
|
11
|
+
host.register(createSfmcWindow({ getActiveTargets: () => activeTargets }));
|
|
12
|
+
host.setServiceOrder([serviceWindowId("bds"), SFMC_WINDOW_ID]);
|
|
13
|
+
assert.equal(host.getActiveId(), serviceWindowId("bds"));
|
|
14
|
+
assert.equal(host.getActive()?.title, "BDS");
|
|
15
|
+
assert.equal(host.getActive()?.serviceName, "bds");
|
|
16
|
+
const res1 = host.cycleServiceWindows();
|
|
17
|
+
assert.equal(res1.switched, true);
|
|
18
|
+
assert.equal(res1.serviceName, null);
|
|
19
|
+
assert.equal(host.getActiveId(), SFMC_WINDOW_ID);
|
|
20
|
+
assert.equal(host.getActive()?.title, "SFMC");
|
|
21
|
+
assert.equal(host.getActive()?.serviceName, void 0);
|
|
22
|
+
const res2 = host.cycleServiceWindows();
|
|
23
|
+
assert.equal(res2.switched, true);
|
|
24
|
+
assert.equal(res2.serviceName, "bds");
|
|
25
|
+
assert.equal(host.getActiveId(), serviceWindowId("bds"));
|
|
26
|
+
activeTargets = [];
|
|
27
|
+
host.setServiceOrder([]);
|
|
28
|
+
assert.equal(host.getActiveId(), null);
|
|
29
|
+
assert.equal(host.has(serviceWindowId("bds")), false);
|
|
30
|
+
assert.equal(host.has(SFMC_WINDOW_ID), false);
|
|
31
|
+
});
|
|
32
|
+
test("createSfmcWindow: acceptLog \u8FC7\u6EE4\u6D3B\u8DC3\u670D\u52A1\u65E5\u5FD7\u5E76\u63A5\u6536\u975E\u670D\u52A1/\u5E73\u53F0\u65E5\u5FD7", () => {
|
|
33
|
+
const activeTargets = ["bds", "db"];
|
|
34
|
+
const win = createSfmcWindow({ getActiveTargets: () => activeTargets });
|
|
35
|
+
const now = /* @__PURE__ */ new Date();
|
|
36
|
+
const bdsLog = { time: now, source: "bds", level: "info", text: "Server started" };
|
|
37
|
+
const dbLog = { time: now, source: "db", level: "info", text: "Database ready" };
|
|
38
|
+
const packLog = { time: now, source: "pack", level: "info", text: "assembled BP uuid=xxx" };
|
|
39
|
+
const sysLog = { time: now, source: "system", level: "info", text: "Platform initialized" };
|
|
40
|
+
const qqLog = { time: now, source: "qq", level: "info", text: "QQ stopped" };
|
|
41
|
+
assert.equal(win.acceptLog(bdsLog), false);
|
|
42
|
+
assert.equal(win.acceptLog(dbLog), false);
|
|
43
|
+
assert.equal(win.acceptLog(packLog), true);
|
|
44
|
+
assert.equal(win.acceptLog(sysLog), true);
|
|
45
|
+
assert.equal(win.acceptLog(qqLog), true);
|
|
46
|
+
const formatted = win.formatLogLine(packLog);
|
|
47
|
+
assert.ok(formatted.text.includes("[PAK]"));
|
|
48
|
+
});
|
|
49
|
+
test("WindowHost: routeLog \u5C06\u65E5\u5FD7\u6B63\u786E\u5206\u6D41\u5230\u6D3B\u52A8\u7A97\u53E3\u4E0E\u540E\u53F0\u7A97\u53E3\u7F13\u5B58", () => {
|
|
50
|
+
const written = [];
|
|
51
|
+
const host = new WindowHost({ writeLog: (l) => written.push(l) });
|
|
52
|
+
const activeTargets = ["bds"];
|
|
53
|
+
host.register(createServiceWindow("bds"));
|
|
54
|
+
host.register(createSfmcWindow({ getActiveTargets: () => activeTargets }));
|
|
55
|
+
host.setServiceOrder([serviceWindowId("bds"), SFMC_WINDOW_ID]);
|
|
56
|
+
host.setBuffer(serviceWindowId("bds"), []);
|
|
57
|
+
host.setBuffer(SFMC_WINDOW_ID, []);
|
|
58
|
+
assert.equal(host.getActiveId(), serviceWindowId("bds"));
|
|
59
|
+
const now = /* @__PURE__ */ new Date();
|
|
60
|
+
const bdsLog = { time: now, source: "bds", level: "info", text: "Hello BDS" };
|
|
61
|
+
const packLog = { time: now, source: "pack", level: "info", text: "Building pack" };
|
|
62
|
+
host.routeLog(bdsLog);
|
|
63
|
+
assert.equal(written.length, 1);
|
|
64
|
+
assert.ok(written[0]?.includes("Hello BDS"));
|
|
65
|
+
host.routeLog(packLog);
|
|
66
|
+
assert.equal(written.length, 1);
|
|
67
|
+
const sfmcBuffer = host.getBuffer(SFMC_WINDOW_ID);
|
|
68
|
+
assert.equal(sfmcBuffer.length, 1);
|
|
69
|
+
assert.ok(sfmcBuffer[0]?.includes("Building pack"));
|
|
70
|
+
assert.ok(sfmcBuffer[0]?.includes("[PAK]"));
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=host.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/repl-windows/host.test.ts"],
|
|
4
|
+
"sourcesContent": ["import assert from \"node:assert/strict\";\nimport test from \"node:test\";\nimport type { UnifiedLog } from \"../logs.js\";\nimport type { ServiceName } from \"../services.js\";\nimport { WindowHost, serviceWindowId } from \"./host.js\";\nimport { createServiceWindow } from \"./service-window.js\";\nimport { createSfmcWindow, SFMC_WINDOW_ID } from \"./sfmc-window.js\";\n\ntest(\"WindowHost: \u7BA1\u7406\u670D\u52A1\u7A97\u4E0E SFMC \u5E73\u53F0\u7A97\u751F\u547D\u5468\u671F\", () => {\n const written: string[] = [];\n const host = new WindowHost({ writeLog: (l) => written.push(l) });\n\n let activeTargets: ServiceName[] = [\"bds\"];\n host.register(createServiceWindow(\"bds\"));\n host.register(createSfmcWindow({ getActiveTargets: () => activeTargets }));\n\n host.setServiceOrder([serviceWindowId(\"bds\"), SFMC_WINDOW_ID]);\n\n // \u521D\u59CB\u6FC0\u6D3B\u7B2C 1 \u4E2A\u7A97\u53E3\uFF08bds\uFF09\n assert.equal(host.getActiveId(), serviceWindowId(\"bds\"));\n assert.equal(host.getActive()?.title, \"BDS\");\n assert.equal(host.getActive()?.serviceName, \"bds\");\n\n // Tab \u8F6E\u6362\u81F3 SFMC \u7A97\n const res1 = host.cycleServiceWindows();\n assert.equal(res1.switched, true);\n assert.equal(res1.serviceName, null);\n assert.equal(host.getActiveId(), SFMC_WINDOW_ID);\n assert.equal(host.getActive()?.title, \"SFMC\");\n assert.equal(host.getActive()?.serviceName, undefined);\n\n // \u518D\u6B21 Tab \u8F6E\u6362\u56DE BDS \u7A97\n const res2 = host.cycleServiceWindows();\n assert.equal(res2.switched, true);\n assert.equal(res2.serviceName, \"bds\");\n assert.equal(host.getActiveId(), serviceWindowId(\"bds\"));\n\n // \u670D\u52A1\u505C\u6B62\uFF1AsetServiceOrder \u6E05\u7A7A\u65F6\u5E94\u6CE8\u9500\u670D\u52A1\u7A97\u4E0E SFMC \u7A97\n activeTargets = [];\n host.setServiceOrder([]);\n assert.equal(host.getActiveId(), null);\n assert.equal(host.has(serviceWindowId(\"bds\")), false);\n assert.equal(host.has(SFMC_WINDOW_ID), false);\n});\n\ntest(\"createSfmcWindow: acceptLog \u8FC7\u6EE4\u6D3B\u8DC3\u670D\u52A1\u65E5\u5FD7\u5E76\u63A5\u6536\u975E\u670D\u52A1/\u5E73\u53F0\u65E5\u5FD7\", () => {\n const activeTargets: ServiceName[] = [\"bds\", \"db\"];\n const win = createSfmcWindow({ getActiveTargets: () => activeTargets });\n\n const now = new Date();\n const bdsLog: UnifiedLog = { time: now, source: \"bds\", level: \"info\", text: \"Server started\" };\n const dbLog: UnifiedLog = { time: now, source: \"db\", level: \"info\", text: \"Database ready\" };\n const packLog: UnifiedLog = { time: now, source: \"pack\", level: \"info\", text: \"assembled BP uuid=xxx\" };\n const sysLog: UnifiedLog = { time: now, source: \"system\", level: \"info\", text: \"Platform initialized\" };\n const qqLog: UnifiedLog = { time: now, source: \"qq\", level: \"info\", text: \"QQ stopped\" };\n\n // \u6D3B\u8DC3\u670D\u52A1\uFF08bds, db\uFF09\u7684\u65E5\u5FD7\u5728 SFMC \u7A97\u88AB\u8FC7\u6EE4\n assert.equal(win.acceptLog(bdsLog), false);\n assert.equal(win.acceptLog(dbLog), false);\n\n // \u975E\u6D3B\u8DC3\u670D\u52A1\u6216\u5E73\u53F0\u65E5\u5FD7\uFF08pack, system, qq\uFF09\u5728 SFMC \u7A97\u88AB\u63A5\u6536\n assert.equal(win.acceptLog(packLog), true);\n assert.equal(win.acceptLog(sysLog), true);\n assert.equal(win.acceptLog(qqLog), true);\n\n // \u683C\u5F0F\u5316\u8F93\u51FA\u5E94\u5305\u542B\u6765\u6E90\u6807\u7B7E\uFF08omitSource: false\uFF09\n const formatted = win.formatLogLine(packLog);\n assert.ok(formatted.text.includes(\"[PAK]\"));\n});\n\ntest(\"WindowHost: routeLog \u5C06\u65E5\u5FD7\u6B63\u786E\u5206\u6D41\u5230\u6D3B\u52A8\u7A97\u53E3\u4E0E\u540E\u53F0\u7A97\u53E3\u7F13\u5B58\", () => {\n const written: string[] = [];\n const host = new WindowHost({ writeLog: (l) => written.push(l) });\n\n const activeTargets: ServiceName[] = [\"bds\"];\n host.register(createServiceWindow(\"bds\"));\n host.register(createSfmcWindow({ getActiveTargets: () => activeTargets }));\n host.setServiceOrder([serviceWindowId(\"bds\"), SFMC_WINDOW_ID]);\n\n // \u7ED9\u4E24\u4E2A\u7A97\u53E3\u9884\u8BBE buffer\uFF08\u6A21\u62DF seed\uFF09\n host.setBuffer(serviceWindowId(\"bds\"), []);\n host.setBuffer(SFMC_WINDOW_ID, []);\n\n // \u5F53\u524D\u5728 BDS \u7A97\n assert.equal(host.getActiveId(), serviceWindowId(\"bds\"));\n\n const now = new Date();\n const bdsLog: UnifiedLog = { time: now, source: \"bds\", level: \"info\", text: \"Hello BDS\" };\n const packLog: UnifiedLog = { time: now, source: \"pack\", level: \"info\", text: \"Building pack\" };\n\n // \u4EA7\u751F BDS \u65E5\u5FD7\uFF1A\u6D3B\u52A8\u7A97\u7ACB\u5373\u6536\u5230\u5199\u5165\n host.routeLog(bdsLog);\n assert.equal(written.length, 1);\n assert.ok(written[0]?.includes(\"Hello BDS\"));\n\n // \u4EA7\u751F Pack \u65E5\u5FD7\uFF1A\u5F53\u524D\u5728 BDS \u7A97\uFF0CTty \u4E0D\u76F4\u63A5\u5199\uFF0C\u4F46 SFMC \u7A97\u53E3\u540E\u53F0 buffer \u5E94\u8FFD\u52A0\n host.routeLog(packLog);\n assert.equal(written.length, 1); // \u6CA1\u6709\u76F4\u63A5\u5199\u5230\u5F53\u524D Tty\n const sfmcBuffer = host.getBuffer(SFMC_WINDOW_ID);\n assert.equal(sfmcBuffer.length, 1);\n assert.ok(sfmcBuffer[0]?.includes(\"Building pack\"));\n assert.ok(sfmcBuffer[0]?.includes(\"[PAK]\"));\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -5,5 +5,6 @@ export { formatLogDisplay, logDisplayPrefixWidth } from "./format-display.js";
|
|
|
5
5
|
export { WindowHost, serviceWindowId } from "./host.js";
|
|
6
6
|
export { createLogsFilterWindow, type LogsFilterState } from "./logs-filter-window.js";
|
|
7
7
|
export { createServiceWindow } from "./service-window.js";
|
|
8
|
+
export { createSfmcWindow, SFMC_WINDOW_ID } from "./sfmc-window.js";
|
|
8
9
|
export type { ReplWindow, WindowChrome, WindowKeyEvent, WindowKeyResult } from "./types.js";
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repl-windows/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repl-windows/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -2,10 +2,13 @@ import { formatLogDisplay, logDisplayPrefixWidth } from "./format-display.js";
|
|
|
2
2
|
import { WindowHost, serviceWindowId } from "./host.js";
|
|
3
3
|
import { createLogsFilterWindow } from "./logs-filter-window.js";
|
|
4
4
|
import { createServiceWindow } from "./service-window.js";
|
|
5
|
+
import { createSfmcWindow, SFMC_WINDOW_ID } from "./sfmc-window.js";
|
|
5
6
|
export {
|
|
7
|
+
SFMC_WINDOW_ID,
|
|
6
8
|
WindowHost,
|
|
7
9
|
createLogsFilterWindow,
|
|
8
10
|
createServiceWindow,
|
|
11
|
+
createSfmcWindow,
|
|
9
12
|
formatLogDisplay,
|
|
10
13
|
logDisplayPrefixWidth,
|
|
11
14
|
serviceWindowId
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/repl-windows/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * repl-windows/index.ts \u2014 \u7C7B\u7A97\u53E3\u7CFB\u7EDF\u51FA\u53E3\n */\nexport { formatLogDisplay, logDisplayPrefixWidth } from \"./format-display.js\";\nexport { WindowHost, serviceWindowId } from \"./host.js\";\nexport { createLogsFilterWindow, type LogsFilterState } from \"./logs-filter-window.js\";\nexport { createServiceWindow } from \"./service-window.js\";\nexport type { ReplWindow, WindowChrome, WindowKeyEvent, WindowKeyResult } from \"./types.js\";\n"],
|
|
5
|
-
"mappings": "AAGA,SAAS,kBAAkB,6BAA6B;AACxD,SAAS,YAAY,uBAAuB;AAC5C,SAAS,8BAAoD;AAC7D,SAAS,2BAA2B;",
|
|
4
|
+
"sourcesContent": ["/**\n * repl-windows/index.ts \u2014 \u7C7B\u7A97\u53E3\u7CFB\u7EDF\u51FA\u53E3\n */\nexport { formatLogDisplay, logDisplayPrefixWidth } from \"./format-display.js\";\nexport { WindowHost, serviceWindowId } from \"./host.js\";\nexport { createLogsFilterWindow, type LogsFilterState } from \"./logs-filter-window.js\";\nexport { createServiceWindow } from \"./service-window.js\";\nexport { createSfmcWindow, SFMC_WINDOW_ID } from \"./sfmc-window.js\";\nexport type { ReplWindow, WindowChrome, WindowKeyEvent, WindowKeyResult } from \"./types.js\";\n"],
|
|
5
|
+
"mappings": "AAGA,SAAS,kBAAkB,6BAA6B;AACxD,SAAS,YAAY,uBAAuB;AAC5C,SAAS,8BAAoD;AAC7D,SAAS,2BAA2B;AACpC,SAAS,kBAAkB,sBAAsB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ServiceName } from "../services.js";
|
|
2
|
+
import type { ReplWindow } from "./types.js";
|
|
3
|
+
export declare const SFMC_WINDOW_ID = "sfmc";
|
|
4
|
+
export declare function createSfmcWindow(opts: {
|
|
5
|
+
getActiveTargets: () => ServiceName[];
|
|
6
|
+
}): ReplWindow;
|
|
7
|
+
//# sourceMappingURL=sfmc-window.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sfmc-window.d.ts","sourceRoot":"","sources":["../../src/repl-windows/sfmc-window.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,cAAc,SAAS,CAAC;AAErC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,gBAAgB,EAAE,MAAM,WAAW,EAAE,CAAC;CACvC,GAAG,UAAU,CAoBb"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { formatLogDisplay, logDisplayPrefixWidth } from "./format-display.js";
|
|
2
|
+
const SFMC_WINDOW_ID = "sfmc";
|
|
3
|
+
function createSfmcWindow(opts) {
|
|
4
|
+
return {
|
|
5
|
+
id: SFMC_WINDOW_ID,
|
|
6
|
+
title: "SFMC",
|
|
7
|
+
showsInput: true,
|
|
8
|
+
footerShortcuts: "",
|
|
9
|
+
acceptLog(log) {
|
|
10
|
+
const active = opts.getActiveTargets();
|
|
11
|
+
return !active.includes(log.source);
|
|
12
|
+
},
|
|
13
|
+
formatLogLine(log) {
|
|
14
|
+
return {
|
|
15
|
+
text: formatLogDisplay(log, { omitSource: false }),
|
|
16
|
+
indent: logDisplayPrefixWidth(log, { omitSource: false })
|
|
17
|
+
};
|
|
18
|
+
},
|
|
19
|
+
getReplayFilter() {
|
|
20
|
+
return { levels: [], sources: [] };
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
SFMC_WINDOW_ID,
|
|
26
|
+
createSfmcWindow
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=sfmc-window.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/repl-windows/sfmc-window.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * repl-windows/sfmc-window.ts \u2014 \u5E73\u53F0\u7CFB\u7EDF\u7A97\u53E3\uFF08\u5C55\u793A\u9664\u6D3B\u8DC3\u8FD0\u884C\u670D\u52A1\u5916\u6240\u6709\u6765\u6E90\u7684\u65E5\u5FD7\uFF09\n */\nimport type { UnifiedLog } from \"../logs.js\";\nimport type { ServiceName } from \"../services.js\";\nimport { formatLogDisplay, logDisplayPrefixWidth } from \"./format-display.js\";\nimport type { ReplWindow } from \"./types.js\";\n\nexport const SFMC_WINDOW_ID = \"sfmc\";\n\nexport function createSfmcWindow(opts: {\n getActiveTargets: () => ServiceName[];\n}): ReplWindow {\n return {\n id: SFMC_WINDOW_ID,\n title: \"SFMC\",\n showsInput: true,\n footerShortcuts: \"\",\n acceptLog(log: UnifiedLog): boolean {\n const active = opts.getActiveTargets();\n return !active.includes(log.source as ServiceName);\n },\n formatLogLine(log: UnifiedLog) {\n return {\n text: formatLogDisplay(log, { omitSource: false }),\n indent: logDisplayPrefixWidth(log, { omitSource: false }),\n };\n },\n getReplayFilter() {\n return { levels: [], sources: [] };\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "AAKA,SAAS,kBAAkB,6BAA6B;AAGjD,MAAM,iBAAiB;AAEvB,SAAS,iBAAiB,MAElB;AACb,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,UAAU,KAA0B;AAClC,YAAM,SAAS,KAAK,iBAAiB;AACrC,aAAO,CAAC,OAAO,SAAS,IAAI,MAAqB;AAAA,IACnD;AAAA,IACA,cAAc,KAAiB;AAC7B,aAAO;AAAA,QACL,MAAM,iBAAiB,KAAK,EAAE,YAAY,MAAM,CAAC;AAAA,QACjD,QAAQ,sBAAsB,KAAK,EAAE,YAAY,MAAM,CAAC;AAAA,MAC1D;AAAA,IACF;AAAA,IACA,kBAAkB;AAChB,aAAO,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC,EAAE;AAAA,IACnC;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/repl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repl.d.ts","sourceRoot":"","sources":["../src/repl.ts"],"names":[],"mappings":"AAcA,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"repl.d.ts","sourceRoot":"","sources":["../src/repl.ts"],"names":[],"mappings":"AAcA,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAgN9B,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiD1D;AAcD,wBAAgB,OAAO,CAAC,IAAI,GAAE,WAAoB,GAAG,MAAM,CAE1D;AAifD,mCAAmC;AACnC,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAG9D,CAAC;AAmBJ,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CA4R/C"}
|
package/dist/repl.js
CHANGED
|
@@ -41,10 +41,12 @@ import { listRegistryModuleIdsSync } from "./registry.js";
|
|
|
41
41
|
import {
|
|
42
42
|
createLogsFilterWindow,
|
|
43
43
|
createServiceWindow,
|
|
44
|
+
createSfmcWindow,
|
|
44
45
|
serviceWindowId,
|
|
46
|
+
SFMC_WINDOW_ID,
|
|
45
47
|
WindowHost
|
|
46
48
|
} from "./repl-windows/index.js";
|
|
47
|
-
import { listActiveSendTargets, paintSendPrompt, plainPrompt } from "./send-target.js";
|
|
49
|
+
import { listActiveSendTargets, paintSendPrompt, paintSfmcPrompt, plainPrompt } from "./send-target.js";
|
|
48
50
|
import { forceStopAll, onServiceStateChange, SERVICE_NAMES, stopAll } from "./services.js";
|
|
49
51
|
import { c, T } from "./theme.js";
|
|
50
52
|
import { dispatchPacksCommand, isPacksCommand } from "./world-packs.js";
|
|
@@ -752,11 +754,19 @@ async function startRepl() {
|
|
|
752
754
|
})
|
|
753
755
|
);
|
|
754
756
|
function syncServiceWindows(targets) {
|
|
757
|
+
if (targets.length === 0) {
|
|
758
|
+
host.setServiceOrder([]);
|
|
759
|
+
preferredTarget = null;
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
755
762
|
for (const name of targets) {
|
|
756
763
|
const id = serviceWindowId(name);
|
|
757
764
|
if (!host.has(id)) host.register(createServiceWindow(name));
|
|
758
765
|
}
|
|
759
|
-
host.
|
|
766
|
+
if (!host.has(SFMC_WINDOW_ID)) {
|
|
767
|
+
host.register(createSfmcWindow({ getActiveTargets: () => activeTargets }));
|
|
768
|
+
}
|
|
769
|
+
host.setServiceOrder([...targets.map(serviceWindowId), SFMC_WINDOW_ID]);
|
|
760
770
|
const svc = host.getActive()?.serviceName;
|
|
761
771
|
if (svc) preferredTarget = svc;
|
|
762
772
|
}
|
|
@@ -801,6 +811,7 @@ async function startRepl() {
|
|
|
801
811
|
process.stdout.on("resize", onResize);
|
|
802
812
|
function currentTarget() {
|
|
803
813
|
if (activeTargets.length === 0) return null;
|
|
814
|
+
if (host.getActive()?.id === SFMC_WINDOW_ID) return null;
|
|
804
815
|
const fromWin = host.getActive()?.serviceName;
|
|
805
816
|
if (fromWin && activeTargets.includes(fromWin)) {
|
|
806
817
|
preferredTarget = fromWin;
|
|
@@ -811,6 +822,9 @@ async function startRepl() {
|
|
|
811
822
|
return preferredTarget;
|
|
812
823
|
}
|
|
813
824
|
function buildPrompt() {
|
|
825
|
+
if (host.getActive()?.id === SFMC_WINDOW_ID) {
|
|
826
|
+
return paintSfmcPrompt();
|
|
827
|
+
}
|
|
814
828
|
const tgt = currentTarget();
|
|
815
829
|
return tgt ? paintSendPrompt(tgt) : plainPrompt();
|
|
816
830
|
}
|
|
@@ -818,8 +832,8 @@ async function startRepl() {
|
|
|
818
832
|
await refreshTargetsFromRuntime();
|
|
819
833
|
const result = await readLine({
|
|
820
834
|
getPrompt: buildPrompt,
|
|
821
|
-
/*
|
|
822
|
-
autoSlash: () => activeTargets.length === 0,
|
|
835
|
+
/* 无服务或在 SFMC 平台窗时默认加 /(与窗口系统前行为一致);用 getter 以便进程退出后即时生效 */
|
|
836
|
+
autoSlash: () => activeTargets.length === 0 || host.getActive()?.id === SFMC_WINDOW_ID,
|
|
823
837
|
getChrome: () => host.getChrome(),
|
|
824
838
|
onWindowKey: (ev) => {
|
|
825
839
|
const r = host.onKey(ev);
|
|
@@ -827,9 +841,9 @@ async function startRepl() {
|
|
|
827
841
|
return r;
|
|
828
842
|
},
|
|
829
843
|
cycleSendTarget: () => {
|
|
830
|
-
const
|
|
831
|
-
if (!
|
|
832
|
-
preferredTarget =
|
|
844
|
+
const res = host.cycleServiceWindows();
|
|
845
|
+
if (!res.switched) return false;
|
|
846
|
+
preferredTarget = res.serviceName;
|
|
833
847
|
showActiveWindow();
|
|
834
848
|
return true;
|
|
835
849
|
},
|