@heybox/hb-sdk 0.7.0-alpha.5 → 0.7.0

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +17 -16
  3. package/dist/cli-chunks/{build-35mI_IwM.cjs → build-CsXk21Yi.cjs} +2 -2
  4. package/dist/cli-chunks/{context-DysC5qrh.cjs → context-ClUhQYbA.cjs} +1 -1
  5. package/dist/cli-chunks/{create-BJSQzUeZ.cjs → create-vadbYtVj.cjs} +1 -1
  6. package/dist/cli-chunks/{dev-DiGtxt4q.cjs → dev-Dkk4qHsv.cjs} +5 -5
  7. package/dist/cli-chunks/{doctor-DWWVwcd7.cjs → doctor-DzgWYWKU.cjs} +1 -1
  8. package/dist/cli-chunks/{index-k5wJ6TMJ.cjs → index-BMddcNGi.cjs} +1 -1
  9. package/dist/cli-chunks/{index-CgCp6jGG.cjs → index-EYRMHb10.cjs} +14 -14
  10. package/dist/cli-chunks/{login-CzkMdcXM.cjs → login-5TM5_o8q.cjs} +2 -2
  11. package/dist/cli-chunks/{project-vite-TBMlJw8y.cjs → project-vite-eJ89lO8_.cjs} +1 -1
  12. package/dist/cli-chunks/{remote-DE9DIxqw.cjs → remote-DxiHjrI9.cjs} +4 -4
  13. package/dist/cli-chunks/{session--DdaUkcq.cjs → session-DYEm6ALx.cjs} +1 -1
  14. package/dist/cli.cjs +1 -1
  15. package/dist/devtools/mock-host/main.js +43 -23
  16. package/dist/index.cjs.js +108 -68
  17. package/dist/index.esm.js +107 -68
  18. package/dist/protocol.cjs.js +19 -0
  19. package/dist/protocol.esm.js +19 -1
  20. package/dist/templates/vue3-vite-ts/src/App.vue +29 -19
  21. package/dist/templates/vue3-vite-ts/src/__tests__/App.spec.ts +82 -9
  22. package/dist/vite.cjs.js +1 -1
  23. package/dist/vite.esm.js +1 -1
  24. package/package.json +1 -1
  25. package/skill/SKILL.md +8 -7
  26. package/skill/references/api-protocol.md +6 -2
  27. package/skill/references/api-root.md +65 -19
  28. package/skill/references/examples.md +30 -9
  29. package/skill/references/recipes.md +48 -26
  30. package/skill/references/safety-boundaries.md +3 -1
  31. package/skill/references/smoke-evaluation.md +3 -1
  32. package/skill/scripts/sync-references.mjs +31 -9
  33. package/skill/skill.json +4 -4
  34. package/types/core/client.d.ts +15 -9
  35. package/types/core/handshake-state.d.ts +24 -0
  36. package/types/core/sdk.d.ts +6 -17
  37. package/types/core/singleton.d.ts +5 -7
  38. package/types/index.d.ts +5 -3
  39. package/types/protocol/trusted-user-gesture.d.ts +6 -0
  40. package/types/protocol/types.d.ts +1 -1
  41. package/types/protocol.d.ts +1 -0
@@ -26,7 +26,26 @@
26
26
 
27
27
  # 快速开始
28
28
 
29
- 如果页面不需要小黑盒开放能力,可以不接入 SDK。需要开放能力时,先等待 `ready()`,再根据小程序是否开通网络权限选择身份流程。
29
+ 如果页面不需要小黑盒开放能力,可以不接入 SDK。SDK 导入时会自动启动握手,能力调用会自动等待;业务只需根据小程序是否开通网络权限选择身份流程。
30
+
31
+ ## 交互控件与握手状态
32
+
33
+ `auth.login()`、`user.getLocalIdentity()` 等可能展示授权 UI 的能力必须保留原始可信用户手势。不要在点击回调中等待握手;页面加载时读取并订阅持久握手状态,只在 `status === 'ready'` 时启用按钮:
34
+
35
+ ```ts
36
+ import hbSDK, { type MiniProgramSDKHandshakeState } from '@heybox/hb-sdk'
37
+ import { computed, onUnmounted, ref } from 'vue'
38
+
39
+ const handshakeState = ref<MiniProgramSDKHandshakeState>(hbSDK.getHandshakeState())
40
+ const stopHandshakeState = hbSDK.onHandshakeStateChange((state) => {
41
+ handshakeState.value = state
42
+ })
43
+ const sdkReady = computed(() => handshakeState.value.status === 'ready')
44
+
45
+ onUnmounted(stopHandshakeState)
46
+ ```
47
+
48
+ 把 `sdkReady` 用作按钮的 `disabled` 条件。订阅会立即回放当前状态,因此晚挂载组件也能得到 `ready` 或 `failed` 终态。`ready` 生命周期事件只在握手成功瞬间派发且不会重放,不能作为当前状态来源。
30
49
 
31
50
  ## 未开通网络权限
32
51
 
@@ -36,8 +55,6 @@
36
55
  import hbSDK, { HbMiniProgramSDKError } from '@heybox/hb-sdk'
37
56
 
38
57
  async function getLocalIdentityFromUserAction() {
39
- await hbSDK.ready()
40
-
41
58
  try {
42
59
  const { appUserId } = await hbSDK.user.getLocalIdentity()
43
60
  return appUserId
@@ -56,11 +73,11 @@ async function getLocalIdentityFromUserAction() {
56
73
 
57
74
  有网络小程序通过 `auth.login()` 获取短期授权码。登录可能展示 UI,因此应绑定到按钮点击等明确的用户操作:
58
75
 
76
+ SDK 会自动完成握手。登录按钮应按上面的持久握手状态启用;点击回调直接调用 `auth.login()`,不要先等待其他异步任务,以免首次操作丢失可信手势。
77
+
59
78
  ```ts
60
79
  import hbSDK, { HbMiniProgramSDKError } from '@heybox/hb-sdk'
61
80
 
62
- await hbSDK.ready()
63
-
64
81
  async function loginFromUserAction() {
65
82
  try {
66
83
  const result = await hbSDK.auth.login({ scopes: ['profile'] })
@@ -79,11 +96,7 @@ async function loginFromUserAction() {
79
96
  }
80
97
  ```
81
98
 
82
- 返回值与边界以[用户身份与登录](/guide/auth)为准。页面只把 `code` 提交给自己的服务端。不要在页面初始化阶段自动调用 `auth.login()`。
83
-
84
- ## ready 的含义
85
-
86
- `ready()` 只表示 SDK 已就绪,可以安全调用开放能力。它不表示已经取得用户授权,也不返回用户身份。
99
+ 返回值与边界以[用户身份与登录](https://docs.xiaoheihe.cn/hb_sdk/guide/auth)为准。页面只把 `code` 提交给自己的服务端。不要在页面初始化阶段自动调用 `auth.login()`。
87
100
 
88
101
  ## 默认单例
89
102
 
@@ -107,12 +120,12 @@ async function loginFromUserAction() {
107
120
 
108
121
  在登录、绑定账号或读取资料等明确的用户操作中调用 `auth.login()`:
109
122
 
123
+ SDK 会在导入时自动握手,能力调用也会自动等待。不要在按钮回调中等待握手;用 `getHandshakeState()` 读取当前状态、用 `onHandshakeStateChange()` 订阅并立即接收状态,只在 `status === 'ready'` 时启用按钮,并在组件销毁时取消订阅。`ready` 生命周期事件不会重放,只是边沿通知,不能作为握手状态。
124
+
110
125
  ```ts
111
126
  import hbSDK, { HbMiniProgramSDKError } from '@heybox/hb-sdk'
112
127
 
113
128
  async function loginFromUserAction() {
114
- await hbSDK.ready()
115
-
116
129
  try {
117
130
  const { code, expiresIn, scopes } = await hbSDK.auth.login({ scopes: ['profile'] })
118
131
  // expiresIn 以服务端返回为准,单位秒;当前后端签发 300 秒一次性 code
@@ -189,8 +202,6 @@ async function revokeAuthorizationFromUserAction() {
189
202
  import hbSDK, { HbMiniProgramSDKError } from '@heybox/hb-sdk'
190
203
 
191
204
  async function getLocalIdentityFromUserAction() {
192
- await hbSDK.ready()
193
-
194
205
  try {
195
206
  const { appUserId } = await hbSDK.user.getLocalIdentity()
196
207
  return appUserId
@@ -252,7 +263,7 @@ onUnmounted(stopLifecycleEvents)
252
263
  | 事件 | 触发时机 | 典型用途 |
253
264
  | ------------------------- | ------------------------ | -------------------------------- |
254
265
  | `launch` | 小程序首次启动 | 初始化一次性数据 |
255
- | `ready` | SDK 可安全调用开放能力 | 标记 SDK 可用 |
266
+ | `ready` | SDK 握手成功瞬间 | 不可重放的边沿通知 |
256
267
  | `show` | 小程序页面展示 | 刷新可见态数据 |
257
268
  | `hide` | 小程序页面隐藏 | 暂停轮询、暂停播放 |
258
269
  | `unload` | 当前小程序运行环境终止 | 清理资源并停止请求 |
@@ -266,11 +277,13 @@ onUnmounted(stopLifecycleEvents)
266
277
 
267
278
  ## 生命周期建议
268
279
 
269
- - 初始化开放能力前先 `await ready()`。
280
+ - SDK 导入时自动启动握手,能力调用会自动等待;不要在用户手势回调中额外等待握手。
281
+ - 当前握手状态只通过 `getHandshakeState()` 查询、通过 `onHandshakeStateChange()` 订阅;订阅会立即回放当前值并返回取消函数。
282
+ - `ready` 事件只在握手成功瞬间派发,不会向晚订阅者重放,不能用于驱动按钮可用状态或替代握手状态 API。
270
283
  - UI 可见性相关逻辑放在 `show`、`hide`。
271
284
  - 使用 Host current-user APIs 的无网络小程序,可以在 `heybox_app_login_change` 后刷新本地状态。已开通网络权限的小程序使用 `auth.login()` 获取 code,并由开发者服务端维护业务会话。
272
285
  - 组件或页面销毁时清理 `on` 注册的监听,避免重复响应。
273
- - 事件只派发给注册当时存在的监听器,不会重放;一次性 `launch`/`ready` 状态应以 `ready()` Promise 为准。
286
+ - 生命周期事件只派发给注册当时存在的监听器,不会重放;一次性 `launch` 信息应在页面启动阶段通过业务能力调用处理。
274
287
  - 收到 `unload` 后,当前 SDK 上下文不可恢复,未完成请求会失败;不要在同一页面上下文继续重试能力调用。
275
288
 
276
289
  ## Error handling
@@ -327,7 +340,6 @@ type LoginViewState =
327
340
 
328
341
  async function loginFromUserAction(): Promise<LoginViewState> {
329
342
  try {
330
- await hbSDK.ready()
331
343
  const result = await hbSDK.auth.login()
332
344
  await exchangeCodeWithDeveloperServer(result.code)
333
345
  return { status: 'ready' }
@@ -370,8 +382,6 @@ function reportSDKError(errorCode: string, message: string, data?: unknown) {
370
382
  import hbSDK, { HbMiniProgramSDKError } from '@heybox/hb-sdk'
371
383
 
372
384
  export async function createServerSessionFromUserAction() {
373
- await hbSDK.ready()
374
-
375
385
  try {
376
386
  const { code } = await hbSDK.auth.login({ scopes: ['profile'] })
377
387
  return await hbSDK.network.request({
@@ -399,9 +409,11 @@ async function handleSubmit() {
399
409
  }
400
410
  ```
401
411
 
412
+ 按钮在页面初始化时通过 `getHandshakeState()` 读取握手状态,并通过 `onHandshakeStateChange()` 持续更新;只在 `status === 'ready'` 时启用,组件卸载时调用订阅返回的取消函数。点击回调直接进入 `createServerSessionFromUserAction()`,不要在其中等待握手。完整接线见[快速开始](https://docs.xiaoheihe.cn/hb_sdk/guide/quick-start)。
413
+
402
414
  ## 注意事项
403
415
 
404
- 完整授权契约见[用户身份与登录](/guide/auth)。本页只保留调用骨架。
416
+ 完整授权契约见[用户身份与登录](https://docs.xiaoheihe.cn/hb_sdk/guide/auth)。本页只保留调用骨架。
405
417
 
406
418
  ## Community share recipe
407
419
 
@@ -415,9 +427,7 @@ async function handleSubmit() {
415
427
  普通分享只支持一个默认分区,并且配置 `post` 时不要同时指定站外 `channel`。
416
428
 
417
429
  ```ts
418
- import { ready, share } from '@heybox/hb-sdk'
419
-
420
- await ready()
430
+ import { share } from '@heybox/hb-sdk'
421
431
 
422
432
  await share.showShareMenu({
423
433
  title: '本局战绩',
@@ -466,7 +476,6 @@ await share.screenshot({
466
476
  ```ts
467
477
  import hbSDK from '@heybox/hb-sdk'
468
478
 
469
- await hbSDK.ready()
470
479
  ```
471
480
 
472
481
  ## 测试环境注入 window
@@ -474,8 +483,21 @@ await hbSDK.ready()
474
483
  测试需要替换 bridge 或 window 时,应在应用测试边界 mock `@heybox/hb-sdk` 公开模块,不要从业务代码访问内部构造器。
475
484
 
476
485
  ```ts
486
+ import type { MiniProgramSDKHandshakeStateHandler } from '@heybox/hb-sdk'
487
+
488
+ const sdkMock = vi.hoisted(() => ({
489
+ state: { status: 'ready' as const },
490
+ unsubscribe: vi.fn(),
491
+ }))
492
+
477
493
  vi.mock('@heybox/hb-sdk', () => ({
478
- default: { ready: vi.fn(async () => undefined) },
494
+ default: {
495
+ getHandshakeState: vi.fn(() => sdkMock.state),
496
+ onHandshakeStateChange: vi.fn((handler: MiniProgramSDKHandshakeStateHandler) => {
497
+ handler(sdkMock.state)
498
+ return sdkMock.unsubscribe
499
+ }),
500
+ },
479
501
  }))
480
502
  ```
481
503
 
@@ -10,7 +10,9 @@
10
10
 
11
11
  ## 关键约束
12
12
 
13
- - `ready()` 只表示 SDK 可调用,不表示已取得用户授权。
13
+ - SDK 会自动等待与父容器完成握手;握手失败会在能力调用时抛出公开 SDK 错误。
14
+ - 交互控件通过 `getHandshakeState()` 和 `onHandshakeStateChange()` 判断是否可用,只在 `status === 'ready'` 时启用;销毁时取消订阅。
15
+ - `ready` 生命周期事件是不可重放的边沿通知,不代表可查询状态,也不能替代握手状态 API。
14
16
  - `auth.login({ scopes? })` 只返回 `{ code, expiresIn: 300, scopes }`;identity 隐式强制包含,code 只能提交给开发者服务端。
15
17
  - 需要授权 UI 时,`auth.login()` 必须来自可信用户手势,否则返回 `USER_GESTURE_REQUIRED`;用户取消或关闭时返回 `AUTHORIZATION_CANCELLED`。已授权时可以静默返回新 code。
16
18
  - `user.getSteamGameList()` 仅供未开通网络权限的小程序通过 Host 读取;已开通网络权限时返回 `SERVER_API_REQUIRED`,且授权码与 OpenAPI 不提供 Steam 游戏库 scope 或资源接口。
@@ -11,7 +11,9 @@ Use this template when evaluating whether an agent followed the hb-sdk skill.
11
11
  - [ ] Uses `@heybox/hb-sdk` root imports for iframe business code.
12
12
  - [ ] Uses `@heybox/hb-sdk/protocol` only for host/runtime/protocol tasks.
13
13
  - [ ] Uses `hb-sdk create`, `hb-sdk dev`, or `hb-sdk login` correctly for CLI tasks.
14
- - [ ] Calls or relies on `ready()` before capability calls.
14
+ - [ ] Uses `getHandshakeState()` plus `onHandshakeStateChange()` for gesture-gated control state, enables only on `status === 'ready'`, and cleans up the subscription.
15
+ - [ ] Treats the non-replayed `ready` lifecycle event as an edge notification that may repeat after a duplicate handshake, never as current state.
16
+ - [ ] Calls gesture-gated capabilities directly from the original user action without waiting for handshake inside the handler.
15
17
  - [ ] Handles login, null user, and SDK errors safely.
16
18
  - [ ] Keeps CLI login cache separate from iframe SDK login state.
17
19
  - [ ] Avoids deep imports, token/cookie access, raw bridge mutation, second mock runtimes, and unsupported capabilities.
@@ -610,15 +610,39 @@ files.set(
610
610
  'apps/docs/hb-sdk/recipes/**',
611
611
  ])}## Positive examples
612
612
 
613
+ ### Gesture-gated control handshake state
614
+
615
+ ${fenced(
616
+ 'ts',
617
+ `import hbSDK, { type MiniProgramSDKHandshakeState } from '@heybox/hb-sdk';
618
+
619
+ let handshakeState: MiniProgramSDKHandshakeState = hbSDK.getHandshakeState();
620
+ const stopHandshakeState = hbSDK.onHandshakeStateChange((state) => {
621
+ handshakeState = state;
622
+ setLoginButtonDisabled(state.status !== 'ready');
623
+ });
624
+
625
+ export function disposePage() {
626
+ stopHandshakeState();
627
+ }
628
+
629
+ export async function loginFromUserAction() {
630
+ if (handshakeState.status !== 'ready') return;
631
+ return hbSDK.auth.login();
632
+ }
633
+
634
+ function setLoginButtonDisabled(disabled: boolean) {
635
+ document.querySelector('button')?.toggleAttribute('disabled', disabled);
636
+ }`,
637
+ )}
638
+
613
639
  ### Local identity for a network-disabled mini-program
614
640
 
615
641
  ${fenced(
616
642
  'ts',
617
- `import { ready, user, HbMiniProgramSDKError } from '@heybox/hb-sdk';
643
+ `import { user, HbMiniProgramSDKError } from '@heybox/hb-sdk';
618
644
 
619
645
  export async function getLocalIdentityFromUserAction() {
620
- await ready();
621
-
622
646
  try {
623
647
  return await user.getLocalIdentity();
624
648
  } catch (error) {
@@ -634,11 +658,9 @@ export async function getLocalIdentityFromUserAction() {
634
658
 
635
659
  ${fenced(
636
660
  'ts',
637
- `import { auth, network, ready, HbMiniProgramSDKError } from '@heybox/hb-sdk';
661
+ `import { auth, network, HbMiniProgramSDKError } from '@heybox/hb-sdk';
638
662
 
639
663
  export async function createServerSessionFromUserAction() {
640
- await ready();
641
-
642
664
  try {
643
665
  const result = await auth.login({ scopes: ['profile'] });
644
666
  await exchangeCodeWithDeveloperServer(result.code);
@@ -664,11 +686,9 @@ async function exchangeCodeWithDeveloperServer(code: string) {
664
686
 
665
687
  ${fenced(
666
688
  'ts',
667
- `import { ready, network, HbMiniProgramNetworkError, HbMiniProgramSDKError } from '@heybox/hb-sdk';
689
+ `import { network, HbMiniProgramNetworkError, HbMiniProgramSDKError } from '@heybox/hb-sdk';
668
690
 
669
691
  try {
670
- await ready();
671
-
672
692
  const response = await network.request<{ ok: boolean }>({
673
693
  url: 'https://api.example.com/demo',
674
694
  method: 'GET',
@@ -746,6 +766,8 @@ export default defineConfig({
746
766
  ## Negative examples
747
767
 
748
768
  - Do not import from internal hb-sdk implementation paths.
769
+ - The non-replayed \`ready\` lifecycle event is only an edge notification. After a duplicate handshake it may repeat; never treat it as current state, and query or subscribe to the persistent state APIs instead.
770
+ - Do not wait for handshake inside a gesture-gated click handler; keep the control disabled until the persistent state is \`ready\`.
749
771
  - Do not read cookies, tokens, phone numbers, or private credentials.
750
772
  - Do not create raw \`postMessage\` bridge envelopes in business pages.
751
773
  - Do not call unsupported storage delete/clear/info operations.
package/skill/skill.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "hb-sdk",
3
- "skillVersion": "0.7.0-alpha.2+skill.c5541658a22b",
3
+ "skillVersion": "0.7.0+skill.f8e5c8b940ab",
4
4
  "sdk": {
5
5
  "package": "@heybox/hb-sdk",
6
- "version": "0.7.0-alpha.2",
7
- "compatibility": "0.7.0-alpha.2"
6
+ "version": "0.7.0",
7
+ "compatibility": "0.7.0"
8
8
  },
9
9
  "source": "https://open.xiaoheihe.cn/agent-skills/hb-sdk",
10
- "integrity": "sha256-c5541658a22b5ef1a47a24dcdd617e59ef2a118858bedf547ac2833637f865b8"
10
+ "integrity": "sha256-f8e5c8b940abd2e9c14ae3407bc99ed1a8a8b5fb15a2577433226ec48f0dad22"
11
11
  }
@@ -1,3 +1,4 @@
1
+ import { type MiniProgramSDKHandshakeState, type MiniProgramSDKHandshakeStateHandler } from './handshake-state';
1
2
  import type { MiniProgramBridgeMethod, MiniProgramCapabilityPayload, MiniProgramCapabilityResult } from '../protocol/capabilities';
2
3
  import type { MiniProgramEventHandler, MiniProgramEventName } from '../protocol/types';
3
4
  /**
@@ -40,18 +41,23 @@ export declare class MiniProgramBridgeClient implements MiniProgramRequester {
40
41
  private readonly handleSecurityPolicyViolation;
41
42
  private unsubscribeHistoryChanges?;
42
43
  private started;
43
- private readySettled;
44
- private readyPromise;
45
- private resolveReady;
46
- private rejectReady;
47
- private readyTimer?;
44
+ private readonly handshakeState;
45
+ private handshakeSettled;
46
+ private handshakePromise;
47
+ private resolveHandshake;
48
+ private rejectHandshake;
49
+ private handshakeTimer?;
48
50
  private handshakeRetryTimer?;
49
51
  private destroyed;
50
52
  private runtimeUnavailable;
51
53
  private runtimeUnavailableError?;
52
54
  constructor(options?: MiniProgramSDKOptions);
53
55
  /** 等待父容器握手完成。 */
54
- ready(): Promise<void>;
56
+ waitForHandshake(): Promise<void>;
57
+ /** 获取当前握手状态。 */
58
+ getHandshakeState(): MiniProgramSDKHandshakeState;
59
+ /** 订阅握手状态,并立即接收当前状态。 */
60
+ onHandshakeStateChange(handler: MiniProgramSDKHandshakeStateHandler): () => void;
55
61
  /** 注册小程序事件监听。 */
56
62
  on<T extends MiniProgramEventName>(eventName: T, handler: MiniProgramEventHandler<T>): () => void;
57
63
  /** 移除小程序事件监听。 */
@@ -68,9 +74,9 @@ export declare class MiniProgramBridgeClient implements MiniProgramRequester {
68
74
  private handleEvent;
69
75
  private handleResponse;
70
76
  private postMessage;
71
- private resolveReadyOnce;
72
- private failReady;
73
- private clearReadyTimers;
77
+ private resolveHandshakeOnce;
78
+ private failHandshake;
79
+ private clearHandshakeTimers;
74
80
  private markRuntimeUnavailable;
75
81
  private getRuntimeUnavailableError;
76
82
  private rejectAllPending;
@@ -0,0 +1,24 @@
1
+ import type { HbMiniProgramSDKError } from './errors';
2
+ /** SDK 与 Host 握手的持久状态。 */
3
+ export type MiniProgramSDKHandshakeState = {
4
+ readonly status: 'connecting';
5
+ } | {
6
+ readonly status: 'ready';
7
+ } | {
8
+ readonly status: 'failed';
9
+ readonly error: HbMiniProgramSDKError;
10
+ };
11
+ /** SDK 握手状态变化处理函数。 */
12
+ export type MiniProgramSDKHandshakeStateHandler = (state: MiniProgramSDKHandshakeState) => void;
13
+ /** 保存握手终态,并向订阅者同步派发唯一一次状态迁移。 */
14
+ export declare class MiniProgramSDKHandshakeStateStore {
15
+ private state;
16
+ private readonly handlers;
17
+ getState(): MiniProgramSDKHandshakeState;
18
+ subscribe(handler: MiniProgramSDKHandshakeStateHandler): () => void;
19
+ clear(): void;
20
+ settle(state: Extract<MiniProgramSDKHandshakeState, {
21
+ status: 'ready' | 'failed';
22
+ }>): void;
23
+ private notify;
24
+ }
@@ -10,6 +10,7 @@ import { type MiniProgramUiModule } from '../modules/ui';
10
10
  import { type MiniProgramDeviceModule } from '../modules/device';
11
11
  import { type MiniProgramNavigationModule } from '../modules/navigation';
12
12
  import type { MiniProgramEventHandler, MiniProgramEventName } from '../protocol/types';
13
+ import type { MiniProgramSDKHandshakeState, MiniProgramSDKHandshakeStateHandler } from './handshake-state';
13
14
  /**
14
15
  * 外部小程序 SDK 实例。
15
16
  *
@@ -20,16 +21,7 @@ import type { MiniProgramEventHandler, MiniProgramEventName } from '../protocol/
20
21
  * 多数业务页直接使用默认单例即可;只有在测试、多实例或需要定制运行参数时,
21
22
  * 才建议显式创建独立实例。
22
23
  *
23
- * @example
24
- * ```ts
25
- * import { createMiniProgramSDK } from '@heybox/hb-sdk'
26
- *
27
- * const sdk = createMiniProgramSDK({
28
- * timeout: 15000,
29
- * })
30
- *
31
- * await sdk.ready()
32
- * ```
24
+ * 能力调用会自动等待与父容器完成握手。
33
25
  */
34
26
  export declare class MiniProgramSDK {
35
27
  private readonly client;
@@ -54,13 +46,10 @@ export declare class MiniProgramSDK {
54
46
  /** 云端数据相关开放能力。 */
55
47
  readonly cloud: MiniProgramCloudModule;
56
48
  constructor(options?: MiniProgramSDKOptions);
57
- /**
58
- * 等待 SDK 与父容器完成握手。
59
- *
60
- * @returns bridge 握手成功后 resolve。
61
- * @throws {HbMiniProgramSDKError} 当当前页面不在 iframe 中、缺少 nonce 或握手超时时抛出。
62
- */
63
- ready(): Promise<void>;
49
+ /** 获取当前握手状态。 */
50
+ getHandshakeState(): MiniProgramSDKHandshakeState;
51
+ /** 订阅握手状态,并立即接收当前状态。 */
52
+ onHandshakeStateChange(handler: MiniProgramSDKHandshakeStateHandler): () => void;
64
53
  /**
65
54
  * 注册小程序生命周期或业务事件。
66
55
  *
@@ -9,13 +9,11 @@ import type { MiniProgramUiModule } from '../modules/ui';
9
9
  import type { MiniProgramDeviceModule } from '../modules/device';
10
10
  import type { MiniProgramNavigationModule } from '../modules/navigation';
11
11
  import type { MiniProgramEventHandler, MiniProgramEventName } from '../protocol/types';
12
- /**
13
- * 等待默认 SDK 实例与父容器完成握手。
14
- *
15
- * @returns 当默认 SDK 单例与父容器握手成功后 resolve。
16
- * @throws {HbMiniProgramSDKError} 当当前页面不在 iframe 中、缺少 nonce 或握手超时时抛出。
17
- */
18
- export declare function ready(): Promise<void>;
12
+ import type { MiniProgramSDKHandshakeState, MiniProgramSDKHandshakeStateHandler } from './handshake-state';
13
+ /** 获取默认 SDK 实例的当前握手状态。 */
14
+ export declare function getHandshakeState(): MiniProgramSDKHandshakeState;
15
+ /** 订阅默认 SDK 实例的握手状态,并立即接收当前状态。 */
16
+ export declare function onHandshakeStateChange(handler: MiniProgramSDKHandshakeStateHandler): () => void;
19
17
  /**
20
18
  * 注册默认 SDK 实例的事件监听。
21
19
  *
package/types/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { HbMiniProgramSDKError, HbMiniProgramNetworkError } from './core/errors';
2
- export { ready, on, off, auth, user, share, viewport, storage, network, ui, device, navigation, cloud } from './core/singleton';
2
+ export { getHandshakeState, onHandshakeStateChange, on, off, auth, user, share, viewport, storage, network, ui, device, navigation, cloud, } from './core/singleton';
3
+ export type { MiniProgramSDKHandshakeState, MiniProgramSDKHandshakeStateHandler } from './core/handshake-state';
3
4
  export type { MiniProgramEventHandler, MiniProgramEventName, MiniProgramEventPayloadMap } from './protocol/types';
4
5
  export type { LoginOptions, LoginPayload, LoginResult, LoginScope, MiniProgramAuthModule } from './modules/auth';
5
6
  export type { DeleteCurrentUserLeaderboardEntryPayload, DeleteCurrentUserLeaderboardEntryResult, GetCurrentUserLeaderboardEntryPayload, GetCurrentUserLeaderboardEntryResult, GetLeaderboardInfoPayload, GetLeaderboardInfoResult, GetLeaderboardListPayload, GetLeaderboardListResult, LeaderboardEntry, LeaderboardOrder, MiniProgramCloudLeaderboardModule, MiniProgramCloudModule, SubmitLeaderboardEntryPayload, SubmitLeaderboardEntryResult, } from './modules/cloud';
@@ -11,9 +12,10 @@ export type { MiniProgramNetworkHeaders, MiniProgramNetworkModule, MiniProgramNe
11
12
  export type { HideLoadingPayload, HideLoadingResult, MiniProgramToastStatus, MiniProgramUiModule, ShowLoadingPayload, ShowLoadingResult, ShowToastPayload, ShowToastResult, } from './modules/ui';
12
13
  export type { MiniProgramDeviceModule, MiniProgramVibrateIntensity, SetClipboardPayload, SetClipboardResult, VibratePayload, VibrateResult, } from './modules/device';
13
14
  export type { ClosePayload, CloseResult, MiniProgramAppPageTarget, MiniProgramGameDetailGameType, MiniProgramGameDetailPage, MiniProgramNavigationModule, OpenAppPageOptions, OpenAppPagePayload, OpenAppPageResult, OpenGameDetailAppPagePayload, OpenGameDetailAppPageOptions, OpenPostDetailAppPagePayload, OpenPostDetailAppPageOptions, OpenUserDetailAppPagePayload, OpenUserDetailAppPageOptions, ReloadPayload, ReloadResult, } from './modules/navigation';
14
- import { off, on, ready } from './core/singleton';
15
+ import { getHandshakeState, off, on, onHandshakeStateChange } from './core/singleton';
15
16
  declare const hbSDK: {
16
- ready: typeof ready;
17
+ getHandshakeState: typeof getHandshakeState;
18
+ onHandshakeStateChange: typeof onHandshakeStateChange;
17
19
  on: typeof on;
18
20
  off: typeof off;
19
21
  auth: import(".").MiniProgramAuthModule;
@@ -0,0 +1,6 @@
1
+ export interface TrustedIframeUserGestureEnvironment {
2
+ readonly activeElement: Element | null;
3
+ readonly userActivation?: Pick<UserActivation, 'isActive'>;
4
+ }
5
+ /** 按当前浏览器消息、用户激活和目标 iframe 焦点生成请求级可信手势快照。 */
6
+ export declare function computeTrustedIframeUserGesture(event: Pick<MessageEvent, 'isTrusted'>, iframe: HTMLIFrameElement, environment?: TrustedIframeUserGestureEnvironment): boolean;
@@ -109,7 +109,7 @@ export interface MiniProgramEventPayloadMap {
109
109
  /** 父容器最终加载到 iframe 的 URL。 */
110
110
  url?: string;
111
111
  };
112
- /** SDK 已可安全调用开放能力。 */
112
+ /** SDK 握手成功时派发的不可重放边沿通知,不是持久状态;需要当前状态时使用 `getHandshakeState()` / `onHandshakeStateChange()`。 */
113
113
  ready: {
114
114
  /** 事件时间戳。 */
115
115
  timestamp: number;
@@ -1,5 +1,6 @@
1
1
  export { MINI_PROGRAM_BRIDGE_NONCE_PARAM, MINI_PROGRAM_MESSAGE_NAMESPACE, MINI_PROGRAM_MESSAGE_VERSION, RUNTIME_LOCATION_PROBE_METHOD, SDK_CSP_VIOLATION_METHOD, SDK_HANDSHAKE_METHOD, SDK_LOCATION_REPORT_METHOD, } from './protocol/constants';
2
2
  export { isMiniProgramBridgeMessage } from './protocol/guards';
3
+ export { computeTrustedIframeUserGesture, type TrustedIframeUserGestureEnvironment, } from './protocol/trusted-user-gesture';
3
4
  export { isManagedMiniProgramRuntimePermissionKey, parseMiniProgramRuntimePermissions } from './protocol/runtime-permissions';
4
5
  export { isOfficialMiniProgramNetworkUrl, isProtectedMiniProgramNetworkPath, MINI_PROGRAM_NETWORK_PROTECTED_PATHS, normalizeMiniProgramNetworkPathname, } from './protocol/network-policy';
5
6
  export type { MiniProgramRuntimePermissionEntry, MiniProgramRuntimePermissionStatus, MiniProgramRuntimePermissionsSnapshot, ParsedMiniProgramRuntimePermissions, } from './protocol/runtime-permissions';