From c9997bb06b2a912dce1d57308aaf0a9af228c65b Mon Sep 17 00:00:00 2001 From: Gaubee Date: Tue, 3 Feb 2026 22:29:42 +0800 Subject: [PATCH] feat(miniapp-runtime): add context-request message listener Allow miniapp iframes to request KeyApp context by sending 'keyapp:context-request' message. The listener finds the iframe by message source or appId and sends context back. Co-Authored-By: Claude Opus 4.5 --- src/services/miniapp-runtime/index.ts | 47 +++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/services/miniapp-runtime/index.ts b/src/services/miniapp-runtime/index.ts index c72d5d068..d488b6dc7 100644 --- a/src/services/miniapp-runtime/index.ts +++ b/src/services/miniapp-runtime/index.ts @@ -169,9 +169,56 @@ function sendKeyAppContext(iframe: HTMLIFrameElement): void { iframe.contentWindow?.postMessage(context, '*'); } +type KeyAppContextRequestMessage = { + type: 'keyapp:context-request'; + payload?: { + appId?: string; + }; +}; + +function getIframeByMessageSource(source: MessageEvent['source']): HTMLIFrameElement | null { + if (!source) return null; + for (const app of miniappRuntimeStore.state.apps.values()) { + const iframe = app.containerHandle?.getIframe() ?? app.iframeRef; + if (iframe?.contentWindow === source) { + return iframe; + } + } + return null; +} + +function handleKeyAppContextRequest(event: MessageEvent): void { + const data = event.data as KeyAppContextRequestMessage | undefined; + if (!data || data.type !== 'keyapp:context-request') return; + + const targetIframe = getIframeByMessageSource(event.source); + if (targetIframe) { + sendKeyAppContext(targetIframe); + return; + } + + const appId = data.payload?.appId; + if (!appId) return; + const app = miniappRuntimeStore.state.apps.get(appId); + const iframe = app?.containerHandle?.getIframe() ?? app?.iframeRef; + if (iframe) { + sendKeyAppContext(iframe); + } +} + +let keyAppContextRequestListenerReady = false; +function ensureKeyAppContextRequestListener(): void { + if (keyAppContextRequestListenerReady) return; + keyAppContextRequestListenerReady = true; + window.addEventListener('message', handleKeyAppContextRequest); +} + /** Store 实例 */ export const miniappRuntimeStore = new Store(initialState); +// 注册 context-request 监听器(必须在 store 定义之后) +ensureKeyAppContextRequestListener(); + export function setMiniappVisualConfig(update: MiniappVisualConfigUpdate): void { miniappRuntimeStore.setState((s) => ({ ...s,