mirror of
https://github.com/ZiuChen/ZiuChen.github.io.git
synced 2025-12-18 00:44:18 +08:00
fix: 调整 Promiseify PostMessage 实现
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import get from 'lodash-es/get'
|
||||
import { FuncMap } from './types'
|
||||
import { BridgeMap } from './types'
|
||||
import { JSBridgeParams } from './sdk'
|
||||
|
||||
/**
|
||||
@@ -10,7 +9,7 @@ export function registerBase(target: Window) {
|
||||
const params = e.data as JSBridgeParams<any>
|
||||
const namespace = params.namespace
|
||||
const action = params.action
|
||||
const callback = get(callbackMap, [namespace, action])
|
||||
const callback = callbackMap?.[namespace]?.[action]
|
||||
if (callback) {
|
||||
const result = await callback(params.payload)
|
||||
target.postMessage(
|
||||
@@ -24,10 +23,10 @@ export function registerBase(target: Window) {
|
||||
})
|
||||
}
|
||||
|
||||
type Namespace = keyof FuncMap
|
||||
type Action = keyof FuncMap[Namespace]
|
||||
type Payload = FuncMap[Namespace][Action] extends { payload: infer P } ? P : never
|
||||
type Result = FuncMap[Namespace][Action] extends { result: infer R } ? R : never
|
||||
type Namespace = keyof BridgeMap
|
||||
type Action = keyof BridgeMap[Namespace]
|
||||
type Payload = BridgeMap[Namespace][Action] extends { payload: infer P } ? P : never
|
||||
type Result = BridgeMap[Namespace][Action] extends { result: infer R } ? R : never
|
||||
|
||||
const callbackMap: Record<
|
||||
Namespace,
|
||||
|
||||
@@ -1,46 +1,47 @@
|
||||
import { FuncMap } from './types'
|
||||
import { BridgeMap } from './types'
|
||||
|
||||
export interface JSBridgeParams<T extends keyof FuncMap> {
|
||||
export interface JSBridgeParams<T extends keyof BridgeMap> {
|
||||
namespace: T
|
||||
action: keyof FuncMap[T]
|
||||
payload: FuncMap[T][keyof FuncMap[T]] extends { payload: infer P } ? P : never
|
||||
action: keyof BridgeMap[T]
|
||||
payload: BridgeMap[T][keyof BridgeMap[T]] extends { payload: infer P } ? P : never
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册 SDK 应用
|
||||
*/
|
||||
export function registerSdk() {
|
||||
window.addEventListener('message', messageHandler)
|
||||
window.addEventListener('message', ({ data, type }: MessageEvent) => {
|
||||
if (type === 'message') {
|
||||
const { params, result } = data
|
||||
const key = `${params.namespace}.${params.action}_${params.id}`
|
||||
const callback = postMessageCallbackMap.get(key)
|
||||
if (callback) {
|
||||
callback(result)
|
||||
postMessageCallbackMap.delete(key)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const postMessageCallbackMap = new Map()
|
||||
|
||||
function messageHandler({ data, type }: MessageEvent) {
|
||||
if (type === 'message') {
|
||||
const { params, result } = data
|
||||
const key = [params.namespace, params.action, params.id].join('.')
|
||||
const callback = postMessageCallbackMap.get(key)
|
||||
if (callback) {
|
||||
callback(result)
|
||||
postMessageCallbackMap.delete(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let uniqueId = 0
|
||||
|
||||
export function postMessage<T extends keyof FuncMap>(
|
||||
export function postMessage<T extends keyof BridgeMap>(
|
||||
params: JSBridgeParams<T>
|
||||
): Promise<FuncMap[T][keyof FuncMap[T]] extends { result: infer R } ? R : never> {
|
||||
): Promise<BridgeMap[T][keyof BridgeMap[T]] extends { result: infer R } ? R : never> {
|
||||
return new Promise((resolve) => {
|
||||
if (window.parent) {
|
||||
const id = uniqueId++
|
||||
const key = [params.namespace, params.action, id].join('.')
|
||||
const key = `${params.namespace}.${String(params.action)}_${id}`
|
||||
postMessageCallbackMap.set(key, resolve)
|
||||
const _params = structuredClone(params)
|
||||
// @ts-expect-error - id is private field.
|
||||
_params.id = id
|
||||
window.parent.postMessage(_params, '*')
|
||||
window.parent.postMessage(
|
||||
{
|
||||
id,
|
||||
...params
|
||||
},
|
||||
'*'
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* 基座与 SDK 共享同一份类型定义
|
||||
*/
|
||||
export interface FuncMap {
|
||||
export interface BridgeMap {
|
||||
user: {
|
||||
getUserToken: {
|
||||
payload: { userId: string }
|
||||
|
||||
Reference in New Issue
Block a user