@co0ontty/wand 4.52.0 → 4.53.0
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/build-info.json +3 -3
- package/dist/distribution-manager.js +2 -2
- package/dist/ios-ota.d.ts +42 -0
- package/dist/ios-ota.js +440 -0
- package/dist/models.d.ts +8 -0
- package/dist/models.js +47 -6
- package/dist/process-manager.js +4 -2
- package/dist/server-session-routes.js +8 -1
- package/dist/server-update-routes.js +135 -1
- package/dist/server-workspace-routes.js +40 -17
- package/dist/session-transport.js +2 -2
- package/dist/web-ui/content/scripts.js +67 -67
- package/dist/web-ui/content/styles.css +1 -1
- package/dist/web-ui/embedded-assets.js +2 -2
- package/dist/ws-broadcast.js +29 -8
- package/package.json +1 -1
package/dist/ws-broadcast.js
CHANGED
|
@@ -27,6 +27,31 @@ const HEARTBEAT_STALE_MS = 45_000;
|
|
|
27
27
|
const PTY_UNACKED_HIGH_WATER = 512 * 1024;
|
|
28
28
|
const PTY_UNACKED_LOW_WATER = 128 * 1024;
|
|
29
29
|
const MAX_PTY_INPUT_CHARS = 128 * 1024;
|
|
30
|
+
function asEventData(data) {
|
|
31
|
+
return data && typeof data === "object" && !Array.isArray(data)
|
|
32
|
+
? data
|
|
33
|
+
: {};
|
|
34
|
+
}
|
|
35
|
+
function isRawPtyChunkData(data) {
|
|
36
|
+
return data.incremental === true && typeof data.chunk === "string";
|
|
37
|
+
}
|
|
38
|
+
function hasSessionTopicData(data) {
|
|
39
|
+
return "title" in data || "description" in data || "titleGenerating" in data;
|
|
40
|
+
}
|
|
41
|
+
function outputEventShapeMismatch(prevData, curData) {
|
|
42
|
+
const prevHasMessages = "messages" in prevData && prevData.messages !== undefined;
|
|
43
|
+
const prevHasLastMsg = "lastMessage" in prevData && prevData.lastMessage !== undefined;
|
|
44
|
+
const curHasMessages = "messages" in curData && curData.messages !== undefined;
|
|
45
|
+
const curHasLastMsg = "lastMessage" in curData && curData.lastMessage !== undefined;
|
|
46
|
+
if ((prevHasMessages && curHasLastMsg && !curHasMessages)
|
|
47
|
+
|| (prevHasLastMsg && curHasMessages && !curHasLastMsg)) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
// Title metadata must not ride along with raw PTY bytes: the web client
|
|
51
|
+
// treats incremental+chunk as chunk-only and drops title/titleGenerating.
|
|
52
|
+
return hasSessionTopicData(prevData) !== hasSessionTopicData(curData)
|
|
53
|
+
&& (isRawPtyChunkData(prevData) || isRawPtyChunkData(curData));
|
|
54
|
+
}
|
|
30
55
|
// ── Manager ──
|
|
31
56
|
export class WsBroadcastManager {
|
|
32
57
|
wss;
|
|
@@ -248,8 +273,8 @@ export class WsBroadcastManager {
|
|
|
248
273
|
if (event.type === "output") {
|
|
249
274
|
const existing = this.outputDebounceCache.get(event.sessionId);
|
|
250
275
|
if (existing) {
|
|
251
|
-
const prevData = existing.event.data
|
|
252
|
-
const curData = event.data
|
|
276
|
+
const prevData = asEventData(existing.event.data);
|
|
277
|
+
const curData = asEventData(event.data);
|
|
253
278
|
// 跨"事件形状"不能简单 shallow-merge:
|
|
254
279
|
// - 全量事件(带 messages)+ 增量事件(带 lastMessage,不带 messages)
|
|
255
280
|
// 合并后变成 { messages, incremental: true, lastMessage }。客户端
|
|
@@ -257,14 +282,10 @@ export class WsBroadcastManager {
|
|
|
257
282
|
// 表现是"刷新页面才出来的消失文字"。
|
|
258
283
|
// - 反过来:增量在前,全量在后,cur 覆盖 prev 后 incremental 仍为 true
|
|
259
284
|
// 而 messages 来自 cur——这种顺序原本是安全的,但风险一致就一起处理。
|
|
285
|
+
// - 会话标题不能并进 raw PTY chunk:web 的 chunk-only 快路径会丢掉 title。
|
|
260
286
|
// 形状不一致时 flush 上一条立即广播,新事件单独开窗口。这样客户端永远
|
|
261
287
|
// 不会在一条 WS 消息里同时看到 messages 和 lastMessage 两种语义。
|
|
262
|
-
const
|
|
263
|
-
const prevHasLastMsg = "lastMessage" in prevData && prevData.lastMessage !== undefined;
|
|
264
|
-
const curHasMessages = "messages" in curData && curData.messages !== undefined;
|
|
265
|
-
const curHasLastMsg = "lastMessage" in curData && curData.lastMessage !== undefined;
|
|
266
|
-
const shapeMismatch = (prevHasMessages && curHasLastMsg && !curHasMessages) ||
|
|
267
|
-
(prevHasLastMsg && curHasMessages && !curHasLastMsg);
|
|
288
|
+
const shapeMismatch = outputEventShapeMismatch(prevData, curData);
|
|
268
289
|
if (shapeMismatch) {
|
|
269
290
|
clearTimeout(existing.timer);
|
|
270
291
|
this.outputDebounceCache.delete(event.sessionId);
|