@heybox/hb-sdk 0.1.2 → 0.1.3
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/README.md +5 -2
- package/dist/index.cjs.js +37 -9
- package/dist/index.esm.js +37 -9
- package/package.json +1 -1
- package/types/core/client.d.ts +4 -1
package/README.md
CHANGED
|
@@ -112,10 +112,12 @@ sdk.destroy();
|
|
|
112
112
|
SDK 与父容器之间通过 `postMessage` 通信,消息会带上固定命名空间、协议版本与 iframe 实例 nonce。SDK 内部负责:
|
|
113
113
|
|
|
114
114
|
- 从 URL query 读取 `hb_mini_bridge_nonce`,也支持通过 `MiniProgramSDKOptions.nonce` 显式传入。
|
|
115
|
-
- 向父容器发送 `sdk.handshake`
|
|
115
|
+
- 向父容器发送 `sdk.handshake` 握手消息;如果还没有收到 `ready` 事件,会在总超时窗口内短间隔重试。
|
|
116
116
|
- 为每次能力调用生成请求 ID,匹配父容器返回的 response。
|
|
117
117
|
- 过滤非小程序消息、非当前 nonce 消息以及非目标父窗口消息。
|
|
118
|
-
-
|
|
118
|
+
- 处理请求超时、握手总超时和销毁后的未完成请求。
|
|
119
|
+
|
|
120
|
+
父容器应幂等响应握手:重复 `sdk.handshake` 只代表 SDK 在补偿早期消息丢失,父容器可以重复派发 `ready`,但不应重复执行一次性启动副作用。
|
|
119
121
|
|
|
120
122
|
### 标准错误
|
|
121
123
|
|
|
@@ -430,6 +432,7 @@ sdk.destroy();
|
|
|
430
432
|
|
|
431
433
|
- SDK 只能在父容器创建的小程序 iframe 沙盒中正常完成握手;非 iframe 环境会抛出 `NOT_IN_IFRAME`。
|
|
432
434
|
- 父容器必须在小程序 URL 上注入 `hb_mini_bridge_nonce`,否则会抛出 `MISSING_NONCE`。
|
|
435
|
+
- 父容器需要幂等响应 `sdk.handshake`;SDK 会在收到 `ready` 前自动重试握手,不引用 SDK 的普通页面不会触发握手。
|
|
433
436
|
- 调用模块能力前会自动等待 `ready()`,但业务仍建议在页面启动阶段显式 `await ready()`,便于集中处理握手失败。
|
|
434
437
|
- `user.getInfo()` 只查询登录态,不会主动唤起登录。
|
|
435
438
|
- `user.login()` 只返回公开用户资料,不返回 token、cookie 或私有凭据。
|
package/dist/index.cjs.js
CHANGED
|
@@ -112,6 +112,7 @@ function isMiniProgramBridgeMessage(value) {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
const DEFAULT_TIMEOUT = 10000;
|
|
115
|
+
const HANDSHAKE_RETRY_INTERVAL = 250;
|
|
115
116
|
/** 底层 bridge client,负责握手、请求响应、事件分发与超时清理。 */
|
|
116
117
|
class MiniProgramBridgeClient {
|
|
117
118
|
timeout;
|
|
@@ -127,6 +128,8 @@ class MiniProgramBridgeClient {
|
|
|
127
128
|
resolveReady;
|
|
128
129
|
rejectReady;
|
|
129
130
|
readyTimer;
|
|
131
|
+
handshakeRetryTimer;
|
|
132
|
+
destroyed = false;
|
|
130
133
|
constructor(options = {}) {
|
|
131
134
|
this.timeout = options.timeout || DEFAULT_TIMEOUT;
|
|
132
135
|
this.selfWindow = options.selfWindow || getGlobalWindow();
|
|
@@ -189,11 +192,17 @@ class MiniProgramBridgeClient {
|
|
|
189
192
|
}
|
|
190
193
|
/** 销毁 SDK 实例,并拒绝尚未完成的请求。 */
|
|
191
194
|
destroy() {
|
|
195
|
+
this.destroyed = true;
|
|
192
196
|
this.selfWindow?.removeEventListener('message', this.handleMessage);
|
|
193
|
-
|
|
194
|
-
this.
|
|
197
|
+
const error = createSDKError('SDK_DESTROYED', '小程序 SDK 已销毁');
|
|
198
|
+
this.failReady(error);
|
|
199
|
+
this.rejectAllPending(error);
|
|
195
200
|
}
|
|
196
201
|
ensureStarted() {
|
|
202
|
+
if (this.destroyed) {
|
|
203
|
+
this.failReady(createSDKError('SDK_DESTROYED', '小程序 SDK 已销毁'));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
197
206
|
if (this.started) {
|
|
198
207
|
return;
|
|
199
208
|
}
|
|
@@ -210,6 +219,22 @@ class MiniProgramBridgeClient {
|
|
|
210
219
|
this.readyTimer = setTimeout(() => {
|
|
211
220
|
this.failReady(createSDKError('READY_TIMEOUT', '小程序沙盒握手超时'));
|
|
212
221
|
}, this.timeout);
|
|
222
|
+
try {
|
|
223
|
+
this.postHandshake();
|
|
224
|
+
this.handshakeRetryTimer = setInterval(() => {
|
|
225
|
+
this.postHandshake();
|
|
226
|
+
}, HANDSHAKE_RETRY_INTERVAL);
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
this.failReady(error instanceof HbMiniProgramSDKError
|
|
230
|
+
? error
|
|
231
|
+
: createSDKError('HANDSHAKE_FAILED', '小程序沙盒握手发送失败', error));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
postHandshake() {
|
|
235
|
+
if (!this.selfWindow) {
|
|
236
|
+
throw createSDKError('NOT_IN_IFRAME', '当前页面不在小程序沙盒 iframe 中');
|
|
237
|
+
}
|
|
213
238
|
this.postMessage({
|
|
214
239
|
namespace: MINI_PROGRAM_MESSAGE_NAMESPACE,
|
|
215
240
|
version: MINI_PROGRAM_MESSAGE_VERSION,
|
|
@@ -272,7 +297,7 @@ class MiniProgramBridgeClient {
|
|
|
272
297
|
return;
|
|
273
298
|
}
|
|
274
299
|
this.readySettled = true;
|
|
275
|
-
this.
|
|
300
|
+
this.clearReadyTimers();
|
|
276
301
|
this.resolveReady();
|
|
277
302
|
}
|
|
278
303
|
failReady(error) {
|
|
@@ -280,15 +305,18 @@ class MiniProgramBridgeClient {
|
|
|
280
305
|
return;
|
|
281
306
|
}
|
|
282
307
|
this.readySettled = true;
|
|
283
|
-
this.
|
|
308
|
+
this.clearReadyTimers();
|
|
284
309
|
this.rejectReady(error);
|
|
285
310
|
}
|
|
286
|
-
|
|
287
|
-
if (
|
|
288
|
-
|
|
311
|
+
clearReadyTimers() {
|
|
312
|
+
if (this.readyTimer) {
|
|
313
|
+
clearTimeout(this.readyTimer);
|
|
314
|
+
this.readyTimer = undefined;
|
|
315
|
+
}
|
|
316
|
+
if (this.handshakeRetryTimer) {
|
|
317
|
+
clearInterval(this.handshakeRetryTimer);
|
|
318
|
+
this.handshakeRetryTimer = undefined;
|
|
289
319
|
}
|
|
290
|
-
clearTimeout(this.readyTimer);
|
|
291
|
-
this.readyTimer = undefined;
|
|
292
320
|
}
|
|
293
321
|
rejectAllPending(error) {
|
|
294
322
|
this.pendingRequests.forEach((pending) => {
|
package/dist/index.esm.js
CHANGED
|
@@ -108,6 +108,7 @@ function isMiniProgramBridgeMessage(value) {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
const DEFAULT_TIMEOUT = 10000;
|
|
111
|
+
const HANDSHAKE_RETRY_INTERVAL = 250;
|
|
111
112
|
/** 底层 bridge client,负责握手、请求响应、事件分发与超时清理。 */
|
|
112
113
|
class MiniProgramBridgeClient {
|
|
113
114
|
timeout;
|
|
@@ -123,6 +124,8 @@ class MiniProgramBridgeClient {
|
|
|
123
124
|
resolveReady;
|
|
124
125
|
rejectReady;
|
|
125
126
|
readyTimer;
|
|
127
|
+
handshakeRetryTimer;
|
|
128
|
+
destroyed = false;
|
|
126
129
|
constructor(options = {}) {
|
|
127
130
|
this.timeout = options.timeout || DEFAULT_TIMEOUT;
|
|
128
131
|
this.selfWindow = options.selfWindow || getGlobalWindow();
|
|
@@ -185,11 +188,17 @@ class MiniProgramBridgeClient {
|
|
|
185
188
|
}
|
|
186
189
|
/** 销毁 SDK 实例,并拒绝尚未完成的请求。 */
|
|
187
190
|
destroy() {
|
|
191
|
+
this.destroyed = true;
|
|
188
192
|
this.selfWindow?.removeEventListener('message', this.handleMessage);
|
|
189
|
-
|
|
190
|
-
this.
|
|
193
|
+
const error = createSDKError('SDK_DESTROYED', '小程序 SDK 已销毁');
|
|
194
|
+
this.failReady(error);
|
|
195
|
+
this.rejectAllPending(error);
|
|
191
196
|
}
|
|
192
197
|
ensureStarted() {
|
|
198
|
+
if (this.destroyed) {
|
|
199
|
+
this.failReady(createSDKError('SDK_DESTROYED', '小程序 SDK 已销毁'));
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
193
202
|
if (this.started) {
|
|
194
203
|
return;
|
|
195
204
|
}
|
|
@@ -206,6 +215,22 @@ class MiniProgramBridgeClient {
|
|
|
206
215
|
this.readyTimer = setTimeout(() => {
|
|
207
216
|
this.failReady(createSDKError('READY_TIMEOUT', '小程序沙盒握手超时'));
|
|
208
217
|
}, this.timeout);
|
|
218
|
+
try {
|
|
219
|
+
this.postHandshake();
|
|
220
|
+
this.handshakeRetryTimer = setInterval(() => {
|
|
221
|
+
this.postHandshake();
|
|
222
|
+
}, HANDSHAKE_RETRY_INTERVAL);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
this.failReady(error instanceof HbMiniProgramSDKError
|
|
226
|
+
? error
|
|
227
|
+
: createSDKError('HANDSHAKE_FAILED', '小程序沙盒握手发送失败', error));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
postHandshake() {
|
|
231
|
+
if (!this.selfWindow) {
|
|
232
|
+
throw createSDKError('NOT_IN_IFRAME', '当前页面不在小程序沙盒 iframe 中');
|
|
233
|
+
}
|
|
209
234
|
this.postMessage({
|
|
210
235
|
namespace: MINI_PROGRAM_MESSAGE_NAMESPACE,
|
|
211
236
|
version: MINI_PROGRAM_MESSAGE_VERSION,
|
|
@@ -268,7 +293,7 @@ class MiniProgramBridgeClient {
|
|
|
268
293
|
return;
|
|
269
294
|
}
|
|
270
295
|
this.readySettled = true;
|
|
271
|
-
this.
|
|
296
|
+
this.clearReadyTimers();
|
|
272
297
|
this.resolveReady();
|
|
273
298
|
}
|
|
274
299
|
failReady(error) {
|
|
@@ -276,15 +301,18 @@ class MiniProgramBridgeClient {
|
|
|
276
301
|
return;
|
|
277
302
|
}
|
|
278
303
|
this.readySettled = true;
|
|
279
|
-
this.
|
|
304
|
+
this.clearReadyTimers();
|
|
280
305
|
this.rejectReady(error);
|
|
281
306
|
}
|
|
282
|
-
|
|
283
|
-
if (
|
|
284
|
-
|
|
307
|
+
clearReadyTimers() {
|
|
308
|
+
if (this.readyTimer) {
|
|
309
|
+
clearTimeout(this.readyTimer);
|
|
310
|
+
this.readyTimer = undefined;
|
|
311
|
+
}
|
|
312
|
+
if (this.handshakeRetryTimer) {
|
|
313
|
+
clearInterval(this.handshakeRetryTimer);
|
|
314
|
+
this.handshakeRetryTimer = undefined;
|
|
285
315
|
}
|
|
286
|
-
clearTimeout(this.readyTimer);
|
|
287
|
-
this.readyTimer = undefined;
|
|
288
316
|
}
|
|
289
317
|
rejectAllPending(error) {
|
|
290
318
|
this.pendingRequests.forEach((pending) => {
|
package/package.json
CHANGED
package/types/core/client.d.ts
CHANGED
|
@@ -30,6 +30,8 @@ export declare class MiniProgramBridgeClient implements MiniProgramRequester {
|
|
|
30
30
|
private resolveReady;
|
|
31
31
|
private rejectReady;
|
|
32
32
|
private readyTimer?;
|
|
33
|
+
private handshakeRetryTimer?;
|
|
34
|
+
private destroyed;
|
|
33
35
|
constructor(options?: MiniProgramSDKOptions);
|
|
34
36
|
/** 等待父容器握手完成。 */
|
|
35
37
|
ready(): Promise<void>;
|
|
@@ -42,12 +44,13 @@ export declare class MiniProgramBridgeClient implements MiniProgramRequester {
|
|
|
42
44
|
/** 销毁 SDK 实例,并拒绝尚未完成的请求。 */
|
|
43
45
|
destroy(): void;
|
|
44
46
|
private ensureStarted;
|
|
47
|
+
private postHandshake;
|
|
45
48
|
private onMessage;
|
|
46
49
|
private handleEvent;
|
|
47
50
|
private handleResponse;
|
|
48
51
|
private postMessage;
|
|
49
52
|
private resolveReadyOnce;
|
|
50
53
|
private failReady;
|
|
51
|
-
private
|
|
54
|
+
private clearReadyTimers;
|
|
52
55
|
private rejectAllPending;
|
|
53
56
|
}
|