@jhh96/light-app-bridge 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lightAppBridge.d.ts +8 -7
- package/dist/lightAppBridge.js +55 -60
- package/package.json +1 -1
package/dist/lightAppBridge.d.ts
CHANGED
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
*
|
|
13
13
|
* 收消息不强依赖 waltz,按以下优先级自动选择监听后端:
|
|
14
14
|
* 1. window.waltz.event.on('native-call-js') —— 有 waltz 的环境(推荐)
|
|
15
|
-
* 2. window.handleMessageFromNative —— 无 waltz
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* 2. window.handleMessageFromNative —— 无 waltz 时由本 SDK 定义此方法
|
|
16
|
+
* (该方法由 waltz.min.js 注册;无 waltz 时为 undefined,renderer 投递消息前
|
|
17
|
+
* 会检查其类型,没人定义则消息被丢弃。故由本 SDK 照 waltz.min.js 方式定义,
|
|
18
|
+
* renderer 收到消息后主动调用它传入消息)
|
|
18
19
|
*
|
|
19
20
|
* 消息信封:
|
|
20
21
|
* { __sdk: 'LightAppBridge', v: 1, id, type, data }
|
|
@@ -36,7 +37,7 @@ export interface Envelope {
|
|
|
36
37
|
export interface BridgeOptions {
|
|
37
38
|
/** send 默认超时(ms),默认 3000 */
|
|
38
39
|
timeout?: number;
|
|
39
|
-
/** 握手超时(ms),默认 30000 */
|
|
40
|
+
/** 握手超时(ms),默认 30000。仅 plugin 角色生效;lightapp 端持续等待,不超时 */
|
|
40
41
|
handshakeTimeout?: number;
|
|
41
42
|
}
|
|
42
43
|
/** send 单次调用选项 */
|
|
@@ -77,7 +78,7 @@ export default class LightAppBridge {
|
|
|
77
78
|
constructor(role?: BridgeRole, options?: BridgeOptions);
|
|
78
79
|
/** 校验依赖是否就绪,缺失抛出明确异常 */
|
|
79
80
|
private _checkDeps;
|
|
80
|
-
/**
|
|
81
|
+
/** 绑定消息监听:优先 waltz;无 waltz 时定义/包装 window.handleMessageFromNative */
|
|
81
82
|
private _startListener;
|
|
82
83
|
/** 构造消息信封 */
|
|
83
84
|
private _envelope;
|
|
@@ -85,8 +86,8 @@ export default class LightAppBridge {
|
|
|
85
86
|
private _onMessage;
|
|
86
87
|
/**
|
|
87
88
|
* 建立连接(握手)。构造时已自动调用,通常无需手动调;如需重新握手可再次调用。
|
|
88
|
-
* - 插件:发起握手(解析目标 id → 发 hello → 每秒重试直到收到 ack
|
|
89
|
-
* -
|
|
89
|
+
* - 插件:发起握手(解析目标 id → 发 hello → 每秒重试直到收到 ack 或超时)
|
|
90
|
+
* - 轻应用:被动等待 hello(持续监听,不超时——插件可能任意晚才发起连接)
|
|
90
91
|
* 多次调用幂等,返回同一个连接 Promise。
|
|
91
92
|
* @returns 对端 webContentsId
|
|
92
93
|
*/
|
package/dist/lightAppBridge.js
CHANGED
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
*
|
|
13
13
|
* 收消息不强依赖 waltz,按以下优先级自动选择监听后端:
|
|
14
14
|
* 1. window.waltz.event.on('native-call-js') —— 有 waltz 的环境(推荐)
|
|
15
|
-
* 2. window.handleMessageFromNative —— 无 waltz
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* 2. window.handleMessageFromNative —— 无 waltz 时由本 SDK 定义此方法
|
|
16
|
+
* (该方法由 waltz.min.js 注册;无 waltz 时为 undefined,renderer 投递消息前
|
|
17
|
+
* 会检查其类型,没人定义则消息被丢弃。故由本 SDK 照 waltz.min.js 方式定义,
|
|
18
|
+
* renderer 收到消息后主动调用它传入消息)
|
|
18
19
|
*
|
|
19
20
|
* 消息信封:
|
|
20
21
|
* { __sdk: 'LightAppBridge', v: 1, id, type, data }
|
|
@@ -52,38 +53,19 @@ function getInvoke() {
|
|
|
52
53
|
}
|
|
53
54
|
return null;
|
|
54
55
|
}
|
|
55
|
-
/** 等待 handleMessageFromNative 出现的轮询间隔(ms) */
|
|
56
|
-
const BACKEND_POLL_INTERVAL = 100;
|
|
57
|
-
/** 等待监听后端就绪的超时(ms) */
|
|
58
|
-
const BACKEND_POLL_TIMEOUT = 10000;
|
|
59
56
|
/** waltz 路径是否可用 */
|
|
60
57
|
function hasWaltz() {
|
|
61
58
|
const w = window.waltz;
|
|
62
59
|
return !!(w && w.event && typeof w.event.on === 'function');
|
|
63
60
|
}
|
|
64
|
-
/** handleMessageFromNative 是否可用 */
|
|
65
|
-
function hasHandleMessageFromNative() {
|
|
66
|
-
return typeof window.handleMessageFromNative === 'function';
|
|
67
|
-
}
|
|
68
|
-
/** 轮询等待条件成立 */
|
|
69
|
-
function waitFor(check, timeout) {
|
|
70
|
-
return new Promise((resolve, reject) => {
|
|
71
|
-
const start = Date.now();
|
|
72
|
-
const tick = () => {
|
|
73
|
-
if (check())
|
|
74
|
-
return resolve();
|
|
75
|
-
if (Date.now() - start > timeout) {
|
|
76
|
-
return reject(new Error(`等待超时 (${timeout}ms)`));
|
|
77
|
-
}
|
|
78
|
-
setTimeout(tick, BACKEND_POLL_INTERVAL);
|
|
79
|
-
};
|
|
80
|
-
tick();
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
61
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
62
|
+
* 解析可用的监听后端并绑定:优先 waltz,回退定义 window.handleMessageFromNative。
|
|
63
|
+
*
|
|
64
|
+
* 说明:handleMessageFromNative 由 waltz.min.js 注册(参考其实现)。
|
|
65
|
+
* 无 waltz 的环境里它是 undefined,且 renderer(waltzBridge preload)投递消息前
|
|
66
|
+
* 会检查 typeof window.handleMessageFromNative === 'function'——
|
|
67
|
+
* 没人定义它消息就会被丢弃。因此无 waltz 时由本 SDK 定义此方法,
|
|
68
|
+
* renderer 收到消息后会主动调用它传入消息。
|
|
87
69
|
*/
|
|
88
70
|
function bindMessageBackend(cb) {
|
|
89
71
|
const w = window;
|
|
@@ -104,24 +86,35 @@ function bindMessageBackend(cb) {
|
|
|
104
86
|
ev.removeListener('native-call-js', handler);
|
|
105
87
|
});
|
|
106
88
|
}
|
|
107
|
-
// 2.
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
89
|
+
// 2. 定义 handleMessageFromNative 路径:无 waltz 时。
|
|
90
|
+
// renderer(waltzBridge)投递:handleMessageFromNative(JSON.stringify({responseId, responseData})),
|
|
91
|
+
// 其中 responseData = {code, body:{eventName, params:{message, fromWebContentsId}}, msg}
|
|
92
|
+
if (typeof w.handleMessageFromNative !== 'function') {
|
|
93
|
+
// 尚未定义(无 waltz 的正常情况):由本 SDK 定义,renderer 主动调它传消息
|
|
94
|
+
const handler = function (raw) {
|
|
112
95
|
const msg = parseHandleMessageFromNative(raw);
|
|
113
96
|
if (msg)
|
|
114
97
|
cb(msg);
|
|
115
|
-
// 透传给原 handler(若存在),保持 waltz/业务自身逻辑不被破坏
|
|
116
|
-
if (typeof prev === 'function')
|
|
117
|
-
return prev.apply(this, arguments);
|
|
118
|
-
};
|
|
119
|
-
w.handleMessageFromNative = wrapped;
|
|
120
|
-
return () => {
|
|
121
|
-
// 还原:仅当仍为自身 wrapped 时才还原,避免覆盖后续可能的重新赋值
|
|
122
|
-
if (w.handleMessageFromNative === wrapped)
|
|
123
|
-
w.handleMessageFromNative = prev;
|
|
124
98
|
};
|
|
99
|
+
w.handleMessageFromNative = handler;
|
|
100
|
+
return Promise.resolve(() => {
|
|
101
|
+
// 清理:仅当仍为自身 handler 时才删除,避免误删后续重新赋值
|
|
102
|
+
if (w.handleMessageFromNative === handler)
|
|
103
|
+
delete w.handleMessageFromNative;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// 已存在(如 waltz 晚于本 SDK 加载、或其它实例已定义):包装透传,不破坏原逻辑
|
|
107
|
+
const prev = w.handleMessageFromNative;
|
|
108
|
+
const wrapped = function (raw) {
|
|
109
|
+
const msg = parseHandleMessageFromNative(raw);
|
|
110
|
+
if (msg)
|
|
111
|
+
cb(msg);
|
|
112
|
+
return prev.apply(this, arguments);
|
|
113
|
+
};
|
|
114
|
+
w.handleMessageFromNative = wrapped;
|
|
115
|
+
return Promise.resolve(() => {
|
|
116
|
+
if (w.handleMessageFromNative === wrapped)
|
|
117
|
+
w.handleMessageFromNative = prev;
|
|
125
118
|
});
|
|
126
119
|
}
|
|
127
120
|
/**
|
|
@@ -185,7 +178,7 @@ export default class LightAppBridge {
|
|
|
185
178
|
return peerId;
|
|
186
179
|
});
|
|
187
180
|
this._checkDeps(); // 依赖校验,缺失直接抛异常
|
|
188
|
-
this._startListener(); //
|
|
181
|
+
this._startListener(); // 绑定消息监听(waltz 或定义 handleMessageFromNative)
|
|
189
182
|
this.connect(); // 构造即自动发起握手(内部会等监听就绪)
|
|
190
183
|
}
|
|
191
184
|
/** 校验依赖是否就绪,缺失抛出明确异常 */
|
|
@@ -197,10 +190,10 @@ export default class LightAppBridge {
|
|
|
197
190
|
if (this.role === 'plugin' && typeof (w.worklink.plugin && w.worklink.plugin.getContentContext) !== 'function') {
|
|
198
191
|
throw new Error('LightAppBridge(plugin) 依赖 window.worklink.plugin.getContentContext,当前环境不可用');
|
|
199
192
|
}
|
|
200
|
-
//
|
|
201
|
-
//
|
|
193
|
+
// 监听后端不强校验:有 waltz 走 waltz;无 waltz 由 _startListener 定义
|
|
194
|
+
// window.handleMessageFromNative(renderer 会主动调用它传入消息)。
|
|
202
195
|
}
|
|
203
|
-
/**
|
|
196
|
+
/** 绑定消息监听:优先 waltz;无 waltz 时定义/包装 window.handleMessageFromNative */
|
|
204
197
|
_startListener() {
|
|
205
198
|
if (this._started)
|
|
206
199
|
return;
|
|
@@ -210,8 +203,8 @@ export default class LightAppBridge {
|
|
|
210
203
|
this._unlisten = unlisten;
|
|
211
204
|
})
|
|
212
205
|
.catch((e) => {
|
|
213
|
-
//
|
|
214
|
-
this._connectDeferred.reject(new Error('LightAppBridge
|
|
206
|
+
// 理论上不会发生(无 waltz 时必走定义路径),保险起见让连接失败并给出原因
|
|
207
|
+
this._connectDeferred.reject(new Error('LightAppBridge 监听后端绑定失败 (' +
|
|
215
208
|
(e && e.message ? e.message : String(e)) + ')'));
|
|
216
209
|
});
|
|
217
210
|
}
|
|
@@ -244,8 +237,8 @@ export default class LightAppBridge {
|
|
|
244
237
|
// —— 连接 / 握手 —— //
|
|
245
238
|
/**
|
|
246
239
|
* 建立连接(握手)。构造时已自动调用,通常无需手动调;如需重新握手可再次调用。
|
|
247
|
-
* - 插件:发起握手(解析目标 id → 发 hello → 每秒重试直到收到 ack
|
|
248
|
-
* -
|
|
240
|
+
* - 插件:发起握手(解析目标 id → 发 hello → 每秒重试直到收到 ack 或超时)
|
|
241
|
+
* - 轻应用:被动等待 hello(持续监听,不超时——插件可能任意晚才发起连接)
|
|
249
242
|
* 多次调用幂等,返回同一个连接 Promise。
|
|
250
243
|
* @returns 对端 webContentsId
|
|
251
244
|
*/
|
|
@@ -254,16 +247,18 @@ export default class LightAppBridge {
|
|
|
254
247
|
if (this._connectStarted)
|
|
255
248
|
return this._connectPromise;
|
|
256
249
|
this._connectStarted = true;
|
|
257
|
-
//
|
|
258
|
-
// 避免对端的 ack/hello 在监听绑定前到达而丢失
|
|
250
|
+
// 等监听后端绑定完成后再握手,避免对端的 ack/hello 在监听绑定前到达而丢失
|
|
259
251
|
const listenerReady = (_a = this._listenerReady) !== null && _a !== void 0 ? _a : Promise.resolve();
|
|
260
|
-
//
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
this.
|
|
265
|
-
|
|
266
|
-
|
|
252
|
+
// 握手超时保护:仅插件(主动方)需要——它发了 hello 却收不到 ack 说明对端异常。
|
|
253
|
+
// 轻应用(被动方)持续等待,不超时:插件可能任意晚才发起连接。
|
|
254
|
+
if (this.role === 'plugin') {
|
|
255
|
+
this._handshakeTimer = setTimeout(() => {
|
|
256
|
+
if (!this._connected) {
|
|
257
|
+
this._connectDeferred.reject(new Error(`握手超时 (${this.handshakeTimeout}ms),对端未响应`));
|
|
258
|
+
this._clearHelloTimer();
|
|
259
|
+
}
|
|
260
|
+
}, this.handshakeTimeout);
|
|
261
|
+
}
|
|
267
262
|
listenerReady
|
|
268
263
|
.then(() => {
|
|
269
264
|
if (this._connected)
|