feat(harness): 支持 WebSocket 帧关键词筛选

This commit is contained in:
YBF
2026-09-11 14:31:49 +08:00
parent ba0097d3f0
commit 9eb895cbc0
4 changed files with 41 additions and 10 deletions
@@ -18,6 +18,10 @@ export const harnessEventsScript = String.raw` const writeCookie = ()
fields.copyUploadUrl.addEventListener('click', copyUploadUrl);
fields.account.addEventListener('input', resetForAccountOrQueryChange);
fields.conversationQuery.addEventListener('input', resetForAccountOrQueryChange);
fields.wsFrameFilter.addEventListener('input', () => {
state.wsFrameFilterKeyword = fields.wsFrameFilter.value.trim().toLowerCase();
renderWsFrames();
});
fields.conversation.addEventListener('change', () => {
state.conversationId = fields.conversation.value;
state.historyRequestGeneration += 1;
@@ -81,6 +81,7 @@ export const harnessPageMarkup = String.raw` <main>
<button class="floater-close secondary" type="button" aria-label="关闭 WebSocket 帧">✕</button>
</div>
<div class="floater-body">
<label>帧消息关键词<input id="ws-frame-filter" autocomplete="off" placeholder="仅显示含关键词的帧" spellcheck="false"></label>
<div id="ws-frame-empty" class="empty">尚无 WebSocket 帧。</div>
<ol id="ws-frames"></ol>
</div>
@@ -23,7 +23,9 @@ export const harnessRuntimeScript = String.raw` const heartbeatInterv
pluginOnline: false,
pendingSendRequestId: null,
uploadInFlight: false,
uploadedUrl: ''
uploadedUrl: '',
wsFrames: [],
wsFrameFilterKeyword: ''
};
const element = (id) => document.getElementById(id);
const fields = {
@@ -55,6 +57,7 @@ export const harnessRuntimeScript = String.raw` const heartbeatInterv
cookieStatus: element('cookie-status'),
pluginStatus: element('plugin-status'),
syncStatus: element('sync-status'),
wsFrameFilter: element('ws-frame-filter'),
wsFrames: element('ws-frames'),
wsFrameEmpty: element('ws-frame-empty'),
messages: element('messages'),
@@ -1,14 +1,37 @@
// 页面脚本分片:WebSocket 通道——帧展示、心跳、连接生命周期与发送(由 harness/index.ts 组装进主 IIFE
export const harnessWebsocketScript = String.raw` const appendWsFrame = (direction, serialized) => {
const item = document.createElement('li');
const heading = document.createElement('strong');
const content = document.createElement('pre');
heading.textContent = new Date().toISOString() + ' · ' + direction;
content.textContent = displayFrame(serialized);
item.append(heading, content);
fields.wsFrames.append(item);
fields.wsFrameEmpty.hidden = true;
export const harnessWebsocketScript = String.raw` const frameMatchesFilter = (displayed) => {
const keyword = state.wsFrameFilterKeyword;
return keyword === '' || displayed.toLowerCase().includes(keyword);
};
const renderWsFrames = () => {
const frames = state.wsFrames.filter((frame) => frameMatchesFilter(frame.displayed));
fields.wsFrames.replaceChildren();
frames.forEach((frame) => {
const item = document.createElement('li');
const heading = document.createElement('strong');
const content = document.createElement('pre');
heading.textContent = frame.observedAt + ' · ' + frame.direction;
content.textContent = frame.displayed;
item.append(heading, content);
fields.wsFrames.append(item);
});
fields.wsFrameEmpty.hidden = frames.length > 0;
fields.wsFrameEmpty.textContent = frames.length > 0
? ''
: state.wsFrames.length === 0
? '尚无 WebSocket 帧。'
: '没有匹配关键词的 WebSocket 帧。';
};
const appendWsFrame = (direction, serialized) => {
state.wsFrames.push({
direction,
displayed: displayFrame(serialized),
observedAt: new Date().toISOString(),
});
renderWsFrames();
};
const sendWsFrame = (socket, frame) => {