fix: 调整 Promiseify PostMessage 实现

This commit is contained in:
ZiuChen
2024-04-02 14:22:37 +08:00
parent 73252a5728
commit f0451e0a72
5 changed files with 40 additions and 181 deletions

View File

@@ -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,

View File

@@ -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
},
'*'
)
}
})
}

View File

@@ -1,7 +1,7 @@
/**
* 基座与 SDK 共享同一份类型定义
*/
export interface FuncMap {
export interface BridgeMap {
user: {
getUserToken: {
payload: { userId: string }