dsh-xrxs-lingting 0.4.0-dev.47 → 0.4.0-dev.49
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/README.md +13 -0
- package/package.json +3 -2
- package/plugin-dist/client.js +64 -7
- package/plugin-dist/index.js +2 -2
package/README.md
CHANGED
|
@@ -95,3 +95,16 @@ LINGTING_XIN_PROBE=1 nohup "/path/to/DSH Desktop Dev.app/Contents/MacOS/DSH Desk
|
|
|
95
95
|
记录保存在公司服务端(aim/cinlyn),插件不落本地数据文件。业务 origin、平台身份与 moduleId 等上下文由宿主或 `VITE_*` 环境变量注入,见 `src/integrations/xin-ui/config.ts`。
|
|
96
96
|
|
|
97
97
|
凭据由 Host 经 `ctx.xrxsAuth` 现取,浏览器不持有,也不在授权失败时回退到直连或本机 Cookie 注入。
|
|
98
|
+
|
|
99
|
+
## 客户端兼容性验证
|
|
100
|
+
|
|
101
|
+
`0.4.0-dev.48` 起不再要求宿主提供旧版补丁的 `layout.business`。标准薪灵客户端通过公开的 `shell.overlay` 插槽显示灵听页面,页面中的「返回聊天」关闭页面;提供业务页扩展的旧宿主仍沿用原入口。
|
|
102
|
+
|
|
103
|
+
发布前除单元测试外,应在构建后对目标薪灵源码运行客户端产物冒烟,验证真实布局对象、公开插槽、页面打开及返回聊天:
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
npm run build:plugin
|
|
107
|
+
npm run smoke:client -- /path/to/cinlyn-desktop
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
该检查不代替安装后对授权、录音、转写和回放的人工验证。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-xrxs-lingting",
|
|
3
|
-
"version": "0.4.0-dev.
|
|
3
|
+
"version": "0.4.0-dev.49",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite --host 127.0.0.1",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"test:watch": "vitest",
|
|
11
11
|
"build:plugin": "tsc --noEmit && node scripts/build-plugin.mjs",
|
|
12
12
|
"build:helper": "node scripts/build-helper.mjs",
|
|
13
|
-
"prepack": "npm run build:plugin"
|
|
13
|
+
"prepack": "npm run build:plugin",
|
|
14
|
+
"smoke:client": "node scripts/smoke-client.mjs"
|
|
14
15
|
},
|
|
15
16
|
"engines": {
|
|
16
17
|
"node": ">=22.12.0"
|
package/plugin-dist/client.js
CHANGED
|
@@ -4449,24 +4449,39 @@ function isState(value) {
|
|
|
4449
4449
|
const state = value;
|
|
4450
4450
|
return typeof state?.reason === "string" && typeof state.businessReady === "boolean";
|
|
4451
4451
|
}
|
|
4452
|
+
function unavailableHostState() {
|
|
4453
|
+
return {
|
|
4454
|
+
protocol: 1,
|
|
4455
|
+
providerAvailable: false,
|
|
4456
|
+
configured: false,
|
|
4457
|
+
authorized: false,
|
|
4458
|
+
businessReady: false,
|
|
4459
|
+
reason: "state-unavailable",
|
|
4460
|
+
context: null,
|
|
4461
|
+
capabilities: { atomicSnapshot: false, recoverSession: false, versioned: false }
|
|
4462
|
+
};
|
|
4463
|
+
}
|
|
4452
4464
|
async function fetchXinHostState(fetchImpl = (input, init) => fetch(input, init)) {
|
|
4453
4465
|
let response;
|
|
4454
4466
|
try {
|
|
4455
4467
|
response = await fetchImpl(XIN_STATE_ENDPOINT, { headers: { accept: "application/json" } });
|
|
4456
4468
|
} catch {
|
|
4457
|
-
return
|
|
4469
|
+
return unavailableHostState();
|
|
4458
4470
|
}
|
|
4459
|
-
if (
|
|
4471
|
+
if (response.status === 404) return null;
|
|
4472
|
+
if (!response.ok) return unavailableHostState();
|
|
4460
4473
|
try {
|
|
4461
4474
|
const payload = await response.json();
|
|
4462
|
-
return isState(payload) ? payload :
|
|
4475
|
+
return isState(payload) ? payload : unavailableHostState();
|
|
4463
4476
|
} catch {
|
|
4464
|
-
return
|
|
4477
|
+
return unavailableHostState();
|
|
4465
4478
|
}
|
|
4466
4479
|
}
|
|
4467
4480
|
function explainXinState(state) {
|
|
4468
4481
|
if (!state || state.businessReady) return "";
|
|
4469
4482
|
switch (state.reason) {
|
|
4483
|
+
case "state-unavailable":
|
|
4484
|
+
return "\u65E0\u6CD5\u8BFB\u53D6\u85AA\u4EBA\u85AA\u4E8B\u6388\u6743\u72B6\u6001\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\uFF1B\u82E5\u6301\u7EED\u5931\u8D25\uFF0C\u8BF7\u91CD\u542F\u5BA2\u6237\u7AEF\u3002";
|
|
4470
4485
|
case "provider-missing":
|
|
4471
4486
|
return "\u672A\u5B89\u88C5\u300C\u85AA\u4EBA\u85AA\u4E8B\u6388\u6743\u300D\u63D2\u4EF6\uFF1A\u8BF7\u5728\u540C\u4E00 profile \u4E2D\u5B89\u88C5\u540E\u91CD\u542F DSH\u3002";
|
|
4472
4487
|
case "provider-unconfigured":
|
|
@@ -5365,11 +5380,50 @@ function createSidebarController() {
|
|
|
5365
5380
|
};
|
|
5366
5381
|
}
|
|
5367
5382
|
|
|
5383
|
+
// src/plugin/navigation.ts
|
|
5384
|
+
function createBusinessNavigation() {
|
|
5385
|
+
let snapshot = { activeId: null };
|
|
5386
|
+
const registrations = /* @__PURE__ */ new Map();
|
|
5387
|
+
const listeners2 = /* @__PURE__ */ new Set();
|
|
5388
|
+
const select = (activeId) => {
|
|
5389
|
+
if (snapshot.activeId === activeId) return;
|
|
5390
|
+
snapshot = { activeId };
|
|
5391
|
+
listeners2.forEach((listener) => listener());
|
|
5392
|
+
};
|
|
5393
|
+
return {
|
|
5394
|
+
register: (id) => {
|
|
5395
|
+
registrations.set(id, (registrations.get(id) ?? 0) + 1);
|
|
5396
|
+
let disposed = false;
|
|
5397
|
+
return () => {
|
|
5398
|
+
if (disposed) return;
|
|
5399
|
+
disposed = true;
|
|
5400
|
+
const count = (registrations.get(id) ?? 1) - 1;
|
|
5401
|
+
if (count > 0) registrations.set(id, count);
|
|
5402
|
+
else {
|
|
5403
|
+
registrations.delete(id);
|
|
5404
|
+
if (snapshot.activeId === id) select(null);
|
|
5405
|
+
}
|
|
5406
|
+
};
|
|
5407
|
+
},
|
|
5408
|
+
open: (id) => {
|
|
5409
|
+
if (registrations.has(id)) select(id);
|
|
5410
|
+
},
|
|
5411
|
+
close: () => select(null),
|
|
5412
|
+
subscribe: (listener) => {
|
|
5413
|
+
listeners2.add(listener);
|
|
5414
|
+
return () => {
|
|
5415
|
+
listeners2.delete(listener);
|
|
5416
|
+
};
|
|
5417
|
+
},
|
|
5418
|
+
getSnapshot: () => snapshot
|
|
5419
|
+
};
|
|
5420
|
+
}
|
|
5421
|
+
|
|
5368
5422
|
// src/plugin/embedded.css
|
|
5369
5423
|
var tag3 = document.createElement("style");
|
|
5370
5424
|
tag3.dataset.plugin = "dsh-xrxs-lingting";
|
|
5371
5425
|
tag3.dataset.pluginCss = "dsh-xrxs-lingting/embedded.css";
|
|
5372
|
-
tag3.textContent = ".lingting-root { color-scheme: light; }\n/* Host \u9002\u914D\u5C42\u72B6\u6001\u63D0\u793A\uFF08\u6388\u6743/\u8EAB\u4EFD/\u76EE\u7684\u5730\u672A\u5C31\u7EEA\uFF09\uFF1A\u56FA\u5B9A\u9876\u90E8\uFF0C\u53EF\u5173\u95ED\uFF0C\u4E0D\u53C2\u4E0E\u9875\u9762\u5E03\u5C40 */\n.lt-host-notice { position: fixed; top: 12px; left: 50%; transform: translateX(-50%); z-index: 60; display: flex; align-items: center; gap: 12px; max-width: min(680px, calc(100vw - 32px)); padding: 10px 14px; border: 1px solid #e7e0fa; border-radius: 10px; background: #fff; box-shadow: 0 6px 24px rgb(40 28 74 / 16%); color: #605972; font-size: 13px; line-height: 1.5; }\n.lt-host-notice-text { flex: 1; }\n.lt-host-notice-close { flex-shrink: 0; border: 0; background: transparent; color: inherit; font-size: 16px; line-height: 1; padding: 2px 4px; border-radius: 6px; cursor: pointer; }\n.lt-host-notice-close:hover { background: #6650d814; }\n.lt-host-notice-close:focus-visible { outline: 2px solid #6650d8; outline-offset: 2px; }\n/* \u5D4C\u5165\u6A21\u5F0F\u4E0B\u6839\u5143\u7D20\u5373 .app\uFF08lingting-root app \u540C\u5143\u7D20\uFF09\uFF0C\u89C4\u5219\u9700\u7528\u7EC4\u5408\u9009\u62E9\u5668\uFF1B\u4FDD\u7559\u540E\u4EE3\u5F62\u5F0F\u517C\u5BB9\u53CC\u5C42\u5305\u88F9\u7ED3\u6784 */\n.lingting-root[data-embedded] { height: 100%; min-height: 0; container-type: inline-size; }\n.lingting-root[data-embedded].app, .lingting-root[data-embedded] .app { height: 100%; min-height: 0; display: flex; flex-direction: column; overflow: hidden; position: relative; padding-bottom: 0; }\n.lingting-root[data-embedded].app .app-header, .lingting-root[data-embedded] .app-header { height: 66px; flex-shrink: 0; }\n.lingting-root[data-embedded].app .header-inner, .lingting-root[data-embedded] .header-inner { padding: 0 28px; max-width: none; }\n.lingting-root[data-embedded].app .brand-caption, .lingting-root[data-embedded] .brand-caption { display: none; }\n.lingting-root[data-embedded].app .main-content, .lingting-root[data-embedded] .main-content { width: 100%; max-width: none; min-height: 0; flex: 1; overflow: auto; padding: 30px 28px 0; scrollbar-width: thin; }\n\n.lingting-root[data-embedded].app .toast, .lingting-root[data-embedded] .toast { position: absolute; top: 77px; }\n.lingting-root[data-global-status] { flex-shrink: 0; border-top: 1px solid #e7e0fa; background: white; padding: 0 24px; }\n.lingting-root[data-global-status] .recording-controls.compact { min-height: 76px; padding: 12px 0; }\n.lingting-root[data-global-status] .error-notice { margin: 8px 0 0; }\n.lingting-sidebar-entry { display: flex; align-items: center; gap: 10px; border: 0; background: transparent; color: var(--dsw-alias-text-primary, #605972); padding: 10px 12px; width: 100%; border-radius: 9px; cursor: pointer; font: inherit; font-size: 14px; }\n.lingting-sidebar-entry:hover, .lingting-sidebar-entry[data-active] { background: #6650d814; color: #6650d8; }\n.lingting-sidebar-entry:focus-visible { outline: 2px solid #6650d8; outline-offset: 2px; }\n@container (max-width: 900px) {\n .lingting-root[data-embedded] .overview-note { display: none; }\n .lingting-root[data-embedded] .overview { grid-template-columns: 1fr 1fr; }\n .lingting-root[data-embedded] .list-heading { flex-wrap: wrap; }\n .lingting-root[data-embedded] .source-label { display: none; }\n}\n";
|
|
5426
|
+
tag3.textContent = ".lingting-root { color-scheme: light; }\n/* Host \u9002\u914D\u5C42\u72B6\u6001\u63D0\u793A\uFF08\u6388\u6743/\u8EAB\u4EFD/\u76EE\u7684\u5730\u672A\u5C31\u7EEA\uFF09\uFF1A\u56FA\u5B9A\u9876\u90E8\uFF0C\u53EF\u5173\u95ED\uFF0C\u4E0D\u53C2\u4E0E\u9875\u9762\u5E03\u5C40 */\n.lt-host-notice { position: fixed; top: 12px; left: 50%; transform: translateX(-50%); z-index: 60; display: flex; align-items: center; gap: 12px; max-width: min(680px, calc(100vw - 32px)); padding: 10px 14px; border: 1px solid #e7e0fa; border-radius: 10px; background: #fff; box-shadow: 0 6px 24px rgb(40 28 74 / 16%); color: #605972; font-size: 13px; line-height: 1.5; }\n.lt-host-notice-text { flex: 1; }\n.lt-host-notice-close { flex-shrink: 0; border: 0; background: transparent; color: inherit; font-size: 16px; line-height: 1; padding: 2px 4px; border-radius: 6px; cursor: pointer; }\n.lt-host-notice-close:hover { background: #6650d814; }\n.lt-host-notice-close:focus-visible { outline: 2px solid #6650d8; outline-offset: 2px; }\n/* \u5D4C\u5165\u6A21\u5F0F\u4E0B\u6839\u5143\u7D20\u5373 .app\uFF08lingting-root app \u540C\u5143\u7D20\uFF09\uFF0C\u89C4\u5219\u9700\u7528\u7EC4\u5408\u9009\u62E9\u5668\uFF1B\u4FDD\u7559\u540E\u4EE3\u5F62\u5F0F\u517C\u5BB9\u53CC\u5C42\u5305\u88F9\u7ED3\u6784 */\n.lingting-root[data-embedded] { height: 100%; min-height: 0; container-type: inline-size; }\n.lingting-root[data-embedded].app, .lingting-root[data-embedded] .app { height: 100%; min-height: 0; display: flex; flex-direction: column; overflow: hidden; position: relative; padding-bottom: 0; }\n.lingting-root[data-embedded].app .app-header, .lingting-root[data-embedded] .app-header { height: 66px; flex-shrink: 0; }\n.lingting-root[data-embedded].app .header-inner, .lingting-root[data-embedded] .header-inner { padding: 0 28px; max-width: none; }\n.lingting-root[data-embedded].app .brand-caption, .lingting-root[data-embedded] .brand-caption { display: none; }\n.lingting-root[data-embedded].app .main-content, .lingting-root[data-embedded] .main-content { width: 100%; max-width: none; min-height: 0; flex: 1; overflow: auto; padding: 30px 28px 0; scrollbar-width: thin; }\n\n.lingting-root[data-embedded].app .toast, .lingting-root[data-embedded] .toast { position: absolute; top: 77px; }\n.lingting-root[data-global-status] { flex-shrink: 0; border-top: 1px solid #e7e0fa; background: white; padding: 0 24px; }\n.lingting-root[data-global-status] .recording-controls.compact { min-height: 76px; padding: 12px 0; }\n.lingting-root[data-global-status] .error-notice { margin: 8px 0 0; }\n.lingting-sidebar-entry { display: flex; align-items: center; gap: 10px; border: 0; background: transparent; color: var(--dsw-alias-text-primary, #605972); padding: 10px 12px; width: 100%; border-radius: 9px; cursor: pointer; font: inherit; font-size: 14px; }\n.lingting-sidebar-entry:hover, .lingting-sidebar-entry[data-active] { background: #6650d814; color: #6650d8; }\n.lingting-sidebar-entry:focus-visible { outline: 2px solid #6650d8; outline-offset: 2px; }\n@container (max-width: 900px) {\n .lingting-root[data-embedded] .overview-note { display: none; }\n .lingting-root[data-embedded] .overview { grid-template-columns: 1fr 1fr; }\n .lingting-root[data-embedded] .list-heading { flex-wrap: wrap; }\n .lingting-root[data-embedded] .source-label { display: none; }\n}\n\n/* Standard DSH has no layout.business extension; keep the page in its public overlay slot. */\n.lt-business-surface { position: fixed; inset: 48px 12px 12px; z-index: 40; min-width: 0; overflow: hidden; border: 1px solid #e7e0fa; border-radius: 12px; background: #fff; box-shadow: 0 8px 32px #2c245221; pointer-events: auto; -webkit-app-region: no-drag; }\n";
|
|
5373
5427
|
document.querySelectorAll("style[data-plugin-css=" + JSON.stringify("dsh-xrxs-lingting/embedded.css") + "]").forEach((old) => old.remove());
|
|
5374
5428
|
document.head.appendChild(tag3);
|
|
5375
5429
|
|
|
@@ -5408,7 +5462,8 @@ async function apply(ctx) {
|
|
|
5408
5462
|
});
|
|
5409
5463
|
const controller = createSidebarController();
|
|
5410
5464
|
const navigation = createMemoryNavigation();
|
|
5411
|
-
const
|
|
5465
|
+
const hostBusiness = ctx.layout.business;
|
|
5466
|
+
const business = hostBusiness ?? createBusinessNavigation();
|
|
5412
5467
|
let previousActive = service.getSnapshot().active?.id ?? null;
|
|
5413
5468
|
ctx.effect(() => service.subscribe(() => {
|
|
5414
5469
|
const activeId = service.getSnapshot().active?.id ?? null;
|
|
@@ -5428,7 +5483,9 @@ async function apply(ctx) {
|
|
|
5428
5483
|
return activeId === ID ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PanelBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LingtingApp, { service, navigation, visible: true, embedded: true, hostState, onBackToHost: () => business.close(), onOpenLive: () => controller.open(), onOpenRecord: (id) => controller.openRecord(id) }) }) : null;
|
|
5429
5484
|
}
|
|
5430
5485
|
function Overlay() {
|
|
5486
|
+
const page = (0, import_react22.useSyncExternalStore)(business.subscribe, business.getSnapshot, business.getSnapshot);
|
|
5431
5487
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
5488
|
+
!hostBusiness && page.activeId === ID && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("section", { className: "lt-business-surface", "aria-label": "\u7075\u542C", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Page, { activeId: page.activeId }) }),
|
|
5432
5489
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PanelBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(XinHostNotice, { store: hostState }) }),
|
|
5433
5490
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PanelBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LingtingSidebar, { service, controller, onOpenPage: () => business.open(ID) }) }),
|
|
5434
5491
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PanelBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MeetingPrompt, { service }) })
|
|
@@ -5439,7 +5496,7 @@ async function apply(ctx) {
|
|
|
5439
5496
|
service.dispose();
|
|
5440
5497
|
hostState.dispose();
|
|
5441
5498
|
});
|
|
5442
|
-
ctx.slots.inject("desktop.business.page", () => ctx.slots.register({ name: "desktop.business.page", id: ID }, Page));
|
|
5499
|
+
if (hostBusiness) ctx.slots.inject("desktop.business.page", () => ctx.slots.register({ name: "desktop.business.page", id: ID }, Page));
|
|
5443
5500
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register({ name: "shell.overlay", id: ID }, Overlay));
|
|
5444
5501
|
ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register({ name: "sidebar.footer.action", id: ID }, Entry));
|
|
5445
5502
|
}
|
package/plugin-dist/index.js
CHANGED
|
@@ -65,7 +65,7 @@ var PRESENCE_STATES = /* @__PURE__ */ new Set(["idle", "starting", "recording",
|
|
|
65
65
|
function registerMeetingRoutes(connection, runtime) {
|
|
66
66
|
const disposers = [];
|
|
67
67
|
const register = (path, methods, fetch2) => {
|
|
68
|
-
disposers.push(connection.fetch.register({ path, methods, fetch: fetch2 }));
|
|
68
|
+
disposers.push(connection.fetch.register({ path, methods, requestBody: "buffered", fetch: fetch2 }));
|
|
69
69
|
};
|
|
70
70
|
register("/api/lingting/meeting.state", ["GET"], () => json(runtime.view()));
|
|
71
71
|
register("/api/lingting/runtime.state", ["GET"], () => {
|
|
@@ -2840,7 +2840,7 @@ function registerXinRoutes(deps) {
|
|
|
2840
2840
|
let counter = 0;
|
|
2841
2841
|
const requestId = () => `xz-${Date.now().toString(36)}-${(counter += 1).toString(36)}`;
|
|
2842
2842
|
const register = (path, methods, fetch2) => {
|
|
2843
|
-
disposers.push(deps.connection.fetch.register({ path, methods, fetch: fetch2 }));
|
|
2843
|
+
disposers.push(deps.connection.fetch.register({ path, methods, requestBody: "buffered", fetch: fetch2 }));
|
|
2844
2844
|
};
|
|
2845
2845
|
register("/api/lingting/xin.state", ["GET"], async () => {
|
|
2846
2846
|
const state = await deps.context.state();
|