Files
Genarrative/apps/mobile-shell/src/host-bridge/bridge.ts
T
kdletters ef2200f8ac 收口宿主响应回放缓存边界
将 HostBridge 响应回放缓存上限提升到共享契约

让 Expo 移动壳复用共享缓存上限并拒绝本地重声明

让 Tauri 桌面壳配置检查反查共享缓存上限

补充两端回放缓存淘汰测试和壳方案文档
2026-06-19 13:33:46 +08:00

93 lines
2.5 KiB
TypeScript

import {
HOST_BRIDGE_RESPONSE_CACHE_MAX,
type HostBridgeRequest,
type HostBridgeResponse,
normalizeHostBridgeRequestId,
} from '../../../../packages/shared/src/contracts/hostBridge';
import {
dispatchMobileHostBridgeRequest,
resetMobileHostBridgeDispatchForTest,
} from './dispatch';
import {
failure,
invalidRequest,
isHostBridgeRequest,
normalizeMobileHostBridgeError,
parseRequest,
} from './protocol';
export {
IOS_MOBILE_HOST_CAPABILITIES,
MOBILE_HOST_CAPABILITIES,
resolveMobileHostCapabilities,
} from './capabilities';
export { configureMobileHostBridgeNavigation } from './dispatch';
const completedHostBridgeResponses = new Map<string, HostBridgeResponse>();
const inFlightHostBridgeResponses = new Map<
string,
Promise<HostBridgeResponse>
>();
function rememberHostBridgeResponse(response: HostBridgeResponse) {
completedHostBridgeResponses.set(response.id, response);
if (completedHostBridgeResponses.size > HOST_BRIDGE_RESPONSE_CACHE_MAX) {
const oldestRequestId = completedHostBridgeResponses.keys().next().value;
if (oldestRequestId) {
completedHostBridgeResponses.delete(oldestRequestId);
}
}
return response;
}
async function resolveMobileHostBridgeResponse(request: HostBridgeRequest) {
const completedResponse = completedHostBridgeResponses.get(request.id);
if (completedResponse) {
return completedResponse;
}
const inFlightResponse = inFlightHostBridgeResponses.get(request.id);
if (inFlightResponse) {
return await inFlightResponse;
}
const responsePromise = dispatchMobileHostBridgeRequest(request)
.catch((error: unknown) =>
failure(request, normalizeMobileHostBridgeError(error)),
)
.then(rememberHostBridgeResponse);
inFlightHostBridgeResponses.set(request.id, responsePromise);
try {
return await responsePromise;
} finally {
inFlightHostBridgeResponses.delete(request.id);
}
}
export async function handleMobileHostBridgeMessage(
rawMessage: string,
sendResponse: (response: HostBridgeResponse) => void,
) {
const parsed = parseRequest(rawMessage);
if (!isHostBridgeRequest(parsed)) {
sendResponse(
failure(
{ id: 'invalid' },
invalidRequest('invalid host bridge request'),
),
);
return;
}
parsed.id = normalizeHostBridgeRequestId(parsed.id) ?? parsed.id;
sendResponse(await resolveMobileHostBridgeResponse(parsed));
}
export function resetMobileHostBridgeForTest() {
resetMobileHostBridgeDispatchForTest();
completedHostBridgeResponses.clear();
inFlightHostBridgeResponses.clear();
}