@heybox/hb-sdk 0.1.2 → 0.2.0-alpha.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 (49) hide show
  1. package/README.md +172 -39
  2. package/bin/hb-sdk.cjs +3 -0
  3. package/dist/cli.cjs +9639 -0
  4. package/dist/devtools/mock-host/index.html +626 -0
  5. package/dist/index.cjs.js +513 -83
  6. package/dist/index.esm.js +499 -78
  7. package/dist/protocol.cjs.js +104 -0
  8. package/dist/protocol.esm.js +90 -0
  9. package/dist/templates/vue3-vite-ts/.gitignore.ejs +5 -0
  10. package/dist/templates/vue3-vite-ts/README.md.ejs +46 -0
  11. package/dist/templates/vue3-vite-ts/index.html.ejs +12 -0
  12. package/dist/templates/vue3-vite-ts/package.json.ejs +29 -0
  13. package/dist/templates/vue3-vite-ts/src/App.vue +63 -0
  14. package/dist/templates/vue3-vite-ts/src/__tests__/App.spec.ts +67 -0
  15. package/dist/templates/vue3-vite-ts/src/main.ts +5 -0
  16. package/dist/templates/vue3-vite-ts/src/styles.css +60 -0
  17. package/dist/templates/vue3-vite-ts/src/vite-env.d.ts +1 -0
  18. package/dist/templates/vue3-vite-ts/tsconfig.app.json +17 -0
  19. package/dist/templates/vue3-vite-ts/tsconfig.json +11 -0
  20. package/dist/templates/vue3-vite-ts/tsconfig.node.json +11 -0
  21. package/dist/templates/vue3-vite-ts/vite.config.ts +6 -0
  22. package/dist/templates/vue3-vite-ts/vitest.config.ts +10 -0
  23. package/package.json +28 -5
  24. package/types/core/client.d.ts +27 -4
  25. package/types/core/errors.d.ts +45 -2
  26. package/types/core/sdk.d.ts +78 -10
  27. package/types/core/singleton.d.ts +33 -7
  28. package/types/core/utils.d.ts +2 -0
  29. package/types/index.d.ts +10 -4
  30. package/types/modules/auth/index.d.ts +42 -0
  31. package/types/modules/network/index.d.ts +125 -0
  32. package/types/modules/share/index.d.ts +12 -2
  33. package/types/modules/share/screenshot.d.ts +14 -2
  34. package/types/modules/share/show-share-menu.d.ts +14 -2
  35. package/types/modules/share/types.d.ts +24 -4
  36. package/types/modules/storage/index.d.ts +70 -0
  37. package/types/modules/user/get-info.d.ts +11 -1
  38. package/types/modules/user/index.d.ts +13 -9
  39. package/types/modules/user/types.d.ts +1 -0
  40. package/types/modules/viewport/index.d.ts +78 -0
  41. package/types/protocol/guards.d.ts +6 -1
  42. package/types/protocol/types.d.ts +19 -4
  43. package/types/protocol.d.ts +18 -0
  44. package/types/modules/system/get-storage.d.ts +0 -15
  45. package/types/modules/system/get-window-info.d.ts +0 -16
  46. package/types/modules/system/index.d.ts +0 -23
  47. package/types/modules/system/set-storage.d.ts +0 -12
  48. package/types/modules/system/types.d.ts +0 -34
  49. package/types/modules/user/login.d.ts +0 -18
package/dist/index.cjs.js CHANGED
@@ -2,7 +2,14 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- /** SDK 对外抛出的标准错误类型。 */
5
+ /**
6
+ * SDK 对外抛出的标准 bridge / runtime 错误类型。
7
+ *
8
+ * @remarks
9
+ * 该错误用于表示握手失败、bridge 调用失败、父容器运行时错误等
10
+ * 非 HTTP 结果错误。其 `code` 字段可用于业务分支处理,
11
+ * `data` 仅作为可选调试信息,不保证结构稳定。
12
+ */
6
13
  class HbMiniProgramSDKError extends Error {
7
14
  /** 稳定错误码。 */
8
15
  code;
@@ -15,7 +22,17 @@ class HbMiniProgramSDKError extends Error {
15
22
  this.data = error.data;
16
23
  }
17
24
  }
18
- /** 创建 SDK 标准错误。 */
25
+ /**
26
+ * 创建 SDK 标准错误。
27
+ *
28
+ * @param code 稳定错误码。
29
+ * @param message 面向开发者的错误说明。
30
+ * @param data 可选调试数据。
31
+ * @returns 标准化 `HbMiniProgramSDKError` 实例。
32
+ *
33
+ * @remarks
34
+ * 仅供 SDK 内部或同仓运行时层统一构造 bridge / runtime 错误。
35
+ */
19
36
  function createSDKError(code, message, data) {
20
37
  return new HbMiniProgramSDKError({
21
38
  code,
@@ -23,6 +40,39 @@ function createSDKError(code, message, data) {
23
40
  data,
24
41
  });
25
42
  }
43
+ /**
44
+ * SDK 对外抛出的 HTTP 错误类型。
45
+ *
46
+ * @remarks
47
+ * 仅在请求已经成功走完 bridge / runtime / 宿主调用链、但最终 HTTP 状态不满足
48
+ * `validateStatus` 时抛出。它不表示握手失败或 bridge 级错误。
49
+ *
50
+ * @typeParam T 标准化响应数据的类型。
51
+ */
52
+ class HbMiniProgramNetworkError extends Error {
53
+ /** HTTP 状态码。 */
54
+ status;
55
+ /** 标准化响应数据。 */
56
+ data;
57
+ /** 标准化响应头。 */
58
+ headers;
59
+ /** SDK 公共请求配置快照。 */
60
+ config;
61
+ /** 完整标准化响应。 */
62
+ response;
63
+ /**
64
+ * @param response 已完成请求的标准化网络响应。
65
+ */
66
+ constructor(response) {
67
+ super(`network.request failed with status ${response.status}`);
68
+ this.name = 'HbMiniProgramNetworkError';
69
+ this.status = response.status;
70
+ this.data = response.data;
71
+ this.headers = response.headers;
72
+ this.config = response.config;
73
+ this.response = response;
74
+ }
75
+ }
26
76
 
27
77
  /** SDK 内部事件总线,负责管理沙盒生命周期与业务事件监听。 */
28
78
  class MiniProgramEventBus {
@@ -77,6 +127,31 @@ function getParentWindow(currentWindow) {
77
127
  }
78
128
  return currentWindow.parent;
79
129
  }
130
+ /** 尝试读取父窗口 origin;跨域读取失败时回退到 document.referrer。 */
131
+ function readParentOrigin(currentWindow) {
132
+ const parentWindow = getParentWindow(currentWindow);
133
+ if (parentWindow) {
134
+ try {
135
+ const origin = parentWindow.location?.origin;
136
+ if (origin && origin !== 'null') {
137
+ return origin;
138
+ }
139
+ }
140
+ catch {
141
+ // ignore cross-origin parent access and fall back to referrer
142
+ }
143
+ }
144
+ const referrer = currentWindow?.document?.referrer;
145
+ if (!referrer) {
146
+ return '';
147
+ }
148
+ try {
149
+ return new URL(referrer).origin;
150
+ }
151
+ catch {
152
+ return '';
153
+ }
154
+ }
80
155
  /** 从父容器注入到 URL 的 query 中读取 bridge nonce。 */
81
156
  function readBridgeNonce(currentWindow) {
82
157
  const href = currentWindow?.location?.href;
@@ -99,7 +174,12 @@ function createMessageId() {
99
174
  return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`;
100
175
  }
101
176
 
102
- /** 判断未知数据是否符合小程序 bridge 消息信封。 */
177
+ /**
178
+ * 判断未知数据是否符合小程序 bridge 消息信封。
179
+ *
180
+ * @param value 待判断的未知数据。
181
+ * @returns 当数据满足小程序 bridge 消息基础结构时返回 `true`。
182
+ */
103
183
  function isMiniProgramBridgeMessage(value) {
104
184
  if (!value || typeof value !== 'object') {
105
185
  return false;
@@ -112,11 +192,13 @@ function isMiniProgramBridgeMessage(value) {
112
192
  }
113
193
 
114
194
  const DEFAULT_TIMEOUT = 10000;
195
+ const HANDSHAKE_RETRY_INTERVAL = 250;
115
196
  /** 底层 bridge client,负责握手、请求响应、事件分发与超时清理。 */
116
197
  class MiniProgramBridgeClient {
117
198
  timeout;
118
199
  selfWindow;
119
200
  targetWindow;
201
+ targetOrigin;
120
202
  nonce;
121
203
  pendingRequests = new Map();
122
204
  eventBus = new MiniProgramEventBus();
@@ -127,11 +209,14 @@ class MiniProgramBridgeClient {
127
209
  resolveReady;
128
210
  rejectReady;
129
211
  readyTimer;
212
+ handshakeRetryTimer;
213
+ destroyed = false;
130
214
  constructor(options = {}) {
131
215
  this.timeout = options.timeout || DEFAULT_TIMEOUT;
132
216
  this.selfWindow = options.selfWindow || getGlobalWindow();
133
217
  this.targetWindow =
134
218
  options.targetWindow === undefined ? getParentWindow(this.selfWindow) : options.targetWindow;
219
+ this.targetOrigin = options.targetOrigin || readParentOrigin(this.selfWindow) || '*';
135
220
  this.nonce = options.nonce || readBridgeNonce(this.selfWindow);
136
221
  this.handleMessage = this.onMessage.bind(this);
137
222
  this.readyPromise = new Promise((resolve, reject) => {
@@ -189,11 +274,17 @@ class MiniProgramBridgeClient {
189
274
  }
190
275
  /** 销毁 SDK 实例,并拒绝尚未完成的请求。 */
191
276
  destroy() {
277
+ this.destroyed = true;
192
278
  this.selfWindow?.removeEventListener('message', this.handleMessage);
193
- this.clearReadyTimer();
194
- this.rejectAllPending(createSDKError('SDK_DESTROYED', '小程序 SDK 已销毁'));
279
+ const error = createSDKError('SDK_DESTROYED', '小程序 SDK 已销毁');
280
+ this.failReady(error);
281
+ this.rejectAllPending(error);
195
282
  }
196
283
  ensureStarted() {
284
+ if (this.destroyed) {
285
+ this.failReady(createSDKError('SDK_DESTROYED', '小程序 SDK 已销毁'));
286
+ return;
287
+ }
197
288
  if (this.started) {
198
289
  return;
199
290
  }
@@ -210,6 +301,22 @@ class MiniProgramBridgeClient {
210
301
  this.readyTimer = setTimeout(() => {
211
302
  this.failReady(createSDKError('READY_TIMEOUT', '小程序沙盒握手超时'));
212
303
  }, this.timeout);
304
+ try {
305
+ this.postHandshake();
306
+ this.handshakeRetryTimer = setInterval(() => {
307
+ this.postHandshake();
308
+ }, HANDSHAKE_RETRY_INTERVAL);
309
+ }
310
+ catch (error) {
311
+ this.failReady(error instanceof HbMiniProgramSDKError
312
+ ? error
313
+ : createSDKError('HANDSHAKE_FAILED', '小程序沙盒握手发送失败', error));
314
+ }
315
+ }
316
+ postHandshake() {
317
+ if (!this.selfWindow) {
318
+ throw createSDKError('NOT_IN_IFRAME', '当前页面不在小程序沙盒 iframe 中');
319
+ }
213
320
  this.postMessage({
214
321
  namespace: MINI_PROGRAM_MESSAGE_NAMESPACE,
215
322
  version: MINI_PROGRAM_MESSAGE_VERSION,
@@ -265,14 +372,14 @@ class MiniProgramBridgeClient {
265
372
  if (!this.targetWindow) {
266
373
  throw createSDKError('NOT_IN_IFRAME', '当前页面不在小程序沙盒 iframe 中');
267
374
  }
268
- this.targetWindow.postMessage(message, '*');
375
+ this.targetWindow.postMessage(message, this.targetOrigin);
269
376
  }
270
377
  resolveReadyOnce() {
271
378
  if (this.readySettled) {
272
379
  return;
273
380
  }
274
381
  this.readySettled = true;
275
- this.clearReadyTimer();
382
+ this.clearReadyTimers();
276
383
  this.resolveReady();
277
384
  }
278
385
  failReady(error) {
@@ -280,18 +387,21 @@ class MiniProgramBridgeClient {
280
387
  return;
281
388
  }
282
389
  this.readySettled = true;
283
- this.clearReadyTimer();
390
+ this.clearReadyTimers();
284
391
  this.rejectReady(error);
285
392
  }
286
- clearReadyTimer() {
287
- if (!this.readyTimer) {
288
- return;
393
+ clearReadyTimers() {
394
+ if (this.readyTimer) {
395
+ clearTimeout(this.readyTimer);
396
+ this.readyTimer = undefined;
397
+ }
398
+ if (this.handshakeRetryTimer) {
399
+ clearInterval(this.handshakeRetryTimer);
400
+ this.handshakeRetryTimer = undefined;
289
401
  }
290
- clearTimeout(this.readyTimer);
291
- this.readyTimer = undefined;
292
402
  }
293
403
  rejectAllPending(error) {
294
- this.pendingRequests.forEach((pending) => {
404
+ this.pendingRequests.forEach(pending => {
295
405
  clearTimeout(pending.timer);
296
406
  pending.reject(error);
297
407
  });
@@ -299,21 +409,82 @@ class MiniProgramBridgeClient {
299
409
  }
300
410
  }
301
411
 
302
- /** 截图分享能力方法名。 */
412
+ /**
413
+ * 登录授权能力方法名。
414
+ *
415
+ * @remarks
416
+ * 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
417
+ */
418
+ const AUTH_LOGIN_METHOD = 'auth.login';
419
+ /**
420
+ * 唤起登录授权,并在流程返回后刷新用户公开基础资料。
421
+ *
422
+ * @param requester 底层 bridge 请求能力。
423
+ * @returns 登录流程完成后的最新用户登录态与公开资料。
424
+ * @throws {HbMiniProgramSDKError} 当 bridge、父容器或宿主运行时调用失败时抛出。
425
+ *
426
+ * @remarks
427
+ * 该能力不会向小程序暴露 token、cookie 或其他登录凭据。
428
+ */
429
+ function login(requester) {
430
+ return requester.request(AUTH_LOGIN_METHOD);
431
+ }
432
+ /**
433
+ * 创建授权模块。
434
+ *
435
+ * @param requester 底层 bridge 请求能力。
436
+ * @returns 面向业务层的授权模块对象。
437
+ */
438
+ function createAuthModule(requester) {
439
+ return {
440
+ login: () => login(requester),
441
+ };
442
+ }
443
+
444
+ /**
445
+ * 截图分享能力方法名。
446
+ *
447
+ * @remarks
448
+ * 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
449
+ */
303
450
  const SHARE_SCREENSHOT_METHOD = 'share.screenshot';
304
- /** 截图并唤起分享。 */
451
+ /**
452
+ * 截图并唤起分享。
453
+ *
454
+ * @param requester 底层 bridge 请求能力。
455
+ * @param options 截图区域、延迟与保存相册等配置。
456
+ * @returns 由宿主客户端协议决定的结果。
457
+ * @throws {HbMiniProgramSDKError} 当 bridge、父容器或宿主能力调用失败时抛出。
458
+ */
305
459
  function screenshot(requester, options) {
306
460
  return requester.request(SHARE_SCREENSHOT_METHOD, options);
307
461
  }
308
462
 
309
- /** 展示分享面板能力方法名。 */
463
+ /**
464
+ * 展示分享面板能力方法名。
465
+ *
466
+ * @remarks
467
+ * 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
468
+ */
310
469
  const SHARE_SHOW_SHARE_MENU_METHOD = 'share.showShareMenu';
311
- /** 展示基础分享面板。 */
470
+ /**
471
+ * 展示基础分享面板。
472
+ *
473
+ * @param requester 底层 bridge 请求能力。
474
+ * @param options 基础分享参数。
475
+ * @returns 由宿主客户端协议决定的结果。
476
+ * @throws {HbMiniProgramSDKError} 当 bridge、父容器或宿主能力调用失败时抛出。
477
+ */
312
478
  function showShareMenu(requester, options) {
313
479
  return requester.request(SHARE_SHOW_SHARE_MENU_METHOD, options);
314
480
  }
315
481
 
316
- /** 创建分享模块。 */
482
+ /**
483
+ * 创建分享模块。
484
+ *
485
+ * @param requester 底层 bridge 请求能力。
486
+ * @returns 面向业务层的分享模块对象。
487
+ */
317
488
  function createShareModule(requester) {
318
489
  return {
319
490
  showShareMenu: options => showShareMenu(requester, options),
@@ -321,102 +492,322 @@ function createShareModule(requester) {
321
492
  };
322
493
  }
323
494
 
324
- /** 用户信息能力方法名。 */
325
- const USER_GET_INFO_METHOD = 'user.getInfo';
326
495
  /**
327
- * 获取当前访问小程序用户的公开基础资料。
496
+ * 读取小程序隔离 storage 能力方法名。
328
497
  *
329
- * 该能力只返回 `heybox_id`、`nickname`、`avatar` 三个公开字段。
330
- * 未登录时不会触发登录流程,直接返回 `{ isLogin: false, userInfo: null }`。
498
+ * @remarks
499
+ * SDK 与父容器 runtime 共享同一 bridge method 标识。
331
500
  */
332
- function getInfo(requester) {
333
- return requester.request(USER_GET_INFO_METHOD);
501
+ const STORAGE_GET_STORAGE_METHOD = 'storage.getStorage';
502
+ /**
503
+ * 写入小程序隔离 storage 能力方法名。
504
+ *
505
+ * @remarks
506
+ * 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
507
+ */
508
+ const STORAGE_SET_STORAGE_METHOD = 'storage.setStorage';
509
+ /**
510
+ * 获取小程序隔离 storage。
511
+ *
512
+ * @param requester 底层 bridge 请求能力。
513
+ * @param options 读取的 storage key。
514
+ * @returns 对应 key 的标准化读取结果。
515
+ * @throws {HbMiniProgramSDKError} 当 bridge、父容器或宿主能力调用失败时抛出。
516
+ */
517
+ function getStorage(requester, options) {
518
+ return requester.request(STORAGE_GET_STORAGE_METHOD, options);
334
519
  }
335
-
336
- /** 用户登录能力方法名。 */
337
- const USER_LOGIN_METHOD = 'user.login';
338
520
  /**
339
- * 唤起黑盒登录流程,并在流程返回后刷新用户公开基础资料。
521
+ * 写入小程序隔离 storage。
340
522
  *
341
- * 该能力不会向小程序暴露 token、cookie 或任何登录凭据。
523
+ * @param requester 底层 bridge 请求能力。
524
+ * @param options 要写入的 storage key 与数据。
525
+ * @returns 当写入完成后 resolve。
526
+ * @throws {HbMiniProgramSDKError} 当 bridge、父容器或宿主能力调用失败时抛出。
342
527
  */
343
- function login(requester) {
344
- return requester.request(USER_LOGIN_METHOD);
528
+ function setStorage(requester, options) {
529
+ return requester.request(STORAGE_SET_STORAGE_METHOD, options);
530
+ }
531
+ /**
532
+ * 创建 storage 模块。
533
+ *
534
+ * @param requester 底层 bridge 请求能力。
535
+ * @returns 面向业务层的 storage 模块对象。
536
+ */
537
+ function createStorageModule(requester) {
538
+ return {
539
+ getStorage: options => getStorage(requester, options),
540
+ setStorage: options => setStorage(requester, options),
541
+ };
345
542
  }
346
543
 
347
- /** 创建用户模块。 */
348
- function createUserModule(requester) {
544
+ /**
545
+ * 发起网络请求能力方法名。
546
+ *
547
+ * @remarks
548
+ * 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
549
+ */
550
+ const NETWORK_REQUEST_METHOD = 'network.request';
551
+ const DEFAULT_VALIDATE_STATUS = status => status >= 200 && status < 300;
552
+ function isPlainObject(value) {
553
+ return Object.prototype.toString.call(value) === '[object Object]';
554
+ }
555
+ function clonePublicValue(value) {
556
+ if (Array.isArray(value)) {
557
+ return value.map(item => clonePublicValue(item));
558
+ }
559
+ if (isPlainObject(value)) {
560
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, clonePublicValue(item)]));
561
+ }
562
+ return value;
563
+ }
564
+ function snapshotRequestConfig(config) {
349
565
  return {
350
- getInfo: () => getInfo(requester),
351
- login: () => login(requester),
566
+ url: config.url,
567
+ ...(config.method === undefined ? {} : { method: config.method }),
568
+ ...(config.params === undefined ? {} : { params: clonePublicValue(config.params) }),
569
+ ...(config.data === undefined ? {} : { data: clonePublicValue(config.data) }),
570
+ ...(config.headers === undefined ? {} : { headers: clonePublicValue(config.headers) }),
571
+ ...(config.timeout === undefined ? {} : { timeout: config.timeout }),
572
+ ...(config.withCredentials === undefined ? {} : { withCredentials: config.withCredentials }),
573
+ ...(config.validateStatus === undefined ? {} : { validateStatus: config.validateStatus }),
574
+ };
575
+ }
576
+ function toRequestPayload(config) {
577
+ return {
578
+ url: config.url,
579
+ ...(config.method === undefined ? {} : { method: config.method }),
580
+ ...(config.params === undefined ? {} : { params: clonePublicValue(config.params) }),
581
+ ...(config.data === undefined ? {} : { data: clonePublicValue(config.data) }),
582
+ ...(config.headers === undefined ? {} : { headers: clonePublicValue(config.headers) }),
583
+ ...(config.timeout === undefined ? {} : { timeout: config.timeout }),
584
+ ...(config.withCredentials === undefined ? {} : { withCredentials: config.withCredentials }),
585
+ };
586
+ }
587
+ function normalizeHeaders(headers) {
588
+ if (!isPlainObject(headers)) {
589
+ return {};
590
+ }
591
+ return Object.fromEntries(Object.entries(headers).flatMap(([key, value]) => (typeof value === 'string' ? [[key, value]] : [])));
592
+ }
593
+ function toNetworkResponse(payload, config) {
594
+ if (typeof payload.status !== 'number' || Number.isNaN(payload.status)) {
595
+ throw createSDKError('INVALID_NETWORK_RESPONSE', 'network.request 返回了无效的 status', payload);
596
+ }
597
+ return {
598
+ data: payload.data,
599
+ status: payload.status,
600
+ ...(typeof payload.statusText === 'string' ? { statusText: payload.statusText } : {}),
601
+ headers: normalizeHeaders(payload.headers),
602
+ config: snapshotRequestConfig(config),
603
+ };
604
+ }
605
+ /**
606
+ * 发起网络请求并返回标准化响应。
607
+ *
608
+ * @param requester 底层 bridge 请求能力。
609
+ * @param config 面向业务层的网络请求配置。
610
+ * @returns 标准化网络响应。HTTP 2xx 默认返回 resolve。
611
+ * @throws {HbMiniProgramNetworkError} 当请求已完成但 HTTP 状态不满足 `validateStatus` 时抛出。
612
+ * @throws {HbMiniProgramSDKError} 当 bridge、运行时或宿主能力调用失败时抛出。
613
+ *
614
+ * @remarks
615
+ * `validateStatus` 仅在 SDK 侧执行,不会跨 bridge 传输函数值。
616
+ * 公开配置与返回结构都保持 axios-like 的窄接口,不暴露宿主原始协议字段。
617
+ *
618
+ * @example
619
+ * ```ts
620
+ * const result = await request(requester, {
621
+ * url: 'https://api.xiaoheihe.cn/demo',
622
+ * method: 'GET',
623
+ * })
624
+ * ```
625
+ */
626
+ async function request(requester, config) {
627
+ const validateStatus = config.validateStatus || DEFAULT_VALIDATE_STATUS;
628
+ const responsePayload = await requester.request(NETWORK_REQUEST_METHOD, toRequestPayload(config));
629
+ const response = toNetworkResponse(responsePayload, config);
630
+ if (!validateStatus(response.status)) {
631
+ throw new HbMiniProgramNetworkError(response);
632
+ }
633
+ return response;
634
+ }
635
+ /**
636
+ * 创建 network 模块。
637
+ *
638
+ * @param requester 底层 bridge 请求能力。
639
+ * @returns 面向业务层的网络模块对象。
640
+ */
641
+ function createNetworkModule(requester) {
642
+ return {
643
+ request: config => request(requester, config),
352
644
  };
353
645
  }
354
646
 
355
- /** 系统窗口信息能力方法名。 */
356
- const SYSTEM_GET_WINDOW_INFO_METHOD = 'system.getWindowInfo';
647
+ /**
648
+ * 视口窗口信息能力方法名。
649
+ *
650
+ * @remarks
651
+ * 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
652
+ */
653
+ const VIEWPORT_GET_WINDOW_INFO_METHOD = 'viewport.getWindowInfo';
357
654
  /**
358
655
  * 获取当前小程序窗口信息。
656
+ *
657
+ * @param requester 底层 bridge 请求能力。
658
+ * @returns 当前小程序可用窗口信息。
659
+ * @throws {HbMiniProgramSDKError} 当 bridge、父容器或宿主能力调用失败时抛出。
359
660
  */
360
661
  function getWindowInfo(requester) {
361
- return requester.request(SYSTEM_GET_WINDOW_INFO_METHOD);
662
+ return requester.request(VIEWPORT_GET_WINDOW_INFO_METHOD);
362
663
  }
363
-
364
- /** 获取小程序隔离 storage 能力方法名。 */
365
- const SYSTEM_GET_STORAGE_METHOD = 'system.getStorage';
366
- /** 获取小程序隔离 storage。 */
367
- function getStorage(requester, options) {
368
- return requester.request(SYSTEM_GET_STORAGE_METHOD, options);
664
+ /**
665
+ * 创建 Viewport 模块。
666
+ *
667
+ * @param requester 底层 bridge 请求能力。
668
+ * @returns 面向业务层的 Viewport 模块对象。
669
+ */
670
+ function createViewportModule(requester) {
671
+ return {
672
+ getWindowInfo: () => getWindowInfo(requester),
673
+ };
369
674
  }
370
675
 
371
- /** 写入小程序隔离 storage 能力方法名。 */
372
- const SYSTEM_SET_STORAGE_METHOD = 'system.setStorage';
373
- /** 写入小程序隔离 storage。 */
374
- function setStorage(requester, options) {
375
- return requester.request(SYSTEM_SET_STORAGE_METHOD, options);
676
+ /**
677
+ * 用户信息能力方法名。
678
+ *
679
+ * @remarks
680
+ * 供 SDK 与父容器 runtime 共享同一 bridge method 标识。
681
+ */
682
+ const USER_GET_INFO_METHOD = 'user.getInfo';
683
+ /**
684
+ * 获取当前访问小程序用户的公开基础资料。
685
+ *
686
+ * @param requester 底层 bridge 请求能力。
687
+ * @returns 当前用户的登录态与公开基础资料。
688
+ *
689
+ * 该能力只返回 `heybox_id`、`nickname`、`avatar` 三个公开字段。
690
+ * 未登录时不会触发登录流程,直接返回 `{ isLogin: false, userInfo: null }`。
691
+ *
692
+ * @throws {HbMiniProgramSDKError} 当 bridge、父容器或宿主运行时调用失败时抛出。
693
+ */
694
+ function getInfo(requester) {
695
+ return requester.request(USER_GET_INFO_METHOD);
376
696
  }
377
697
 
378
- /** 创建系统模块。 */
379
- function createSystemModule(requester) {
698
+ /**
699
+ * 创建用户模块。
700
+ *
701
+ * @param requester 底层 bridge 请求能力。
702
+ * @returns 面向业务层的用户模块对象。
703
+ */
704
+ function createUserModule(requester) {
380
705
  return {
381
- getWindowInfo: () => getWindowInfo(requester),
382
- getStorage: options => getStorage(requester, options),
383
- setStorage: options => setStorage(requester, options),
706
+ getInfo: () => getInfo(requester),
384
707
  };
385
708
  }
386
709
 
387
- /** 外部小程序 SDK 实例。 */
710
+ /**
711
+ * 外部小程序 SDK 实例。
712
+ *
713
+ * @remarks
714
+ * 该实例负责组织授权、用户、分享、容器、存储与网络等开放能力,并维护
715
+ * iframe 内小程序与父容器之间的 bridge 生命周期。
716
+ *
717
+ * 多数业务页直接使用默认单例即可;只有在测试、多实例或需要定制运行参数时,
718
+ * 才建议显式创建独立实例。
719
+ *
720
+ * @example
721
+ * ```ts
722
+ * import { createMiniProgramSDK } from '@heybox/hb-sdk'
723
+ *
724
+ * const sdk = createMiniProgramSDK({
725
+ * timeout: 15000,
726
+ * })
727
+ *
728
+ * await sdk.ready()
729
+ * ```
730
+ */
388
731
  class MiniProgramSDK {
389
732
  client;
390
- /** 用户相关开放能力。 */
733
+ /** 授权相关开放能力。 */
734
+ auth;
735
+ /** 用户资料相关开放能力。 */
391
736
  user;
392
737
  /** 分享相关开放能力。 */
393
738
  share;
394
- /** 系统相关开放能力。 */
395
- system;
739
+ /** 视口相关开放能力。 */
740
+ viewport;
741
+ /** Storage 相关开放能力。 */
742
+ storage;
743
+ /** 网络请求相关开放能力。 */
744
+ network;
396
745
  constructor(options) {
397
746
  this.client = new MiniProgramBridgeClient(options);
747
+ this.auth = createAuthModule(this.client);
398
748
  this.user = createUserModule(this.client);
399
749
  this.share = createShareModule(this.client);
400
- this.system = createSystemModule(this.client);
750
+ this.viewport = createViewportModule(this.client);
751
+ this.storage = createStorageModule(this.client);
752
+ this.network = createNetworkModule(this.client);
401
753
  }
402
- /** 等待 SDK 与父容器完成握手。 */
754
+ /**
755
+ * 等待 SDK 与父容器完成握手。
756
+ *
757
+ * @returns 当 bridge 握手成功后 resolve。
758
+ * @throws {HbMiniProgramSDKError} 当当前页面不在 iframe 中、缺少 nonce 或握手超时时抛出。
759
+ */
403
760
  ready() {
404
761
  return this.client.ready();
405
762
  }
406
- /** 注册小程序生命周期或业务事件。 */
763
+ /**
764
+ * 注册小程序生命周期或业务事件。
765
+ *
766
+ * @param eventName 要监听的事件名。
767
+ * @param handler 事件处理函数。
768
+ * @returns 事件解绑函数。
769
+ */
407
770
  on(eventName, handler) {
408
771
  return this.client.on(eventName, handler);
409
772
  }
410
- /** 移除小程序生命周期或业务事件。 */
773
+ /**
774
+ * 移除小程序生命周期或业务事件。
775
+ *
776
+ * @param eventName 要移除的事件名。
777
+ * @param handler 对应的事件处理函数。
778
+ */
411
779
  off(eventName, handler) {
412
780
  this.client.off(eventName, handler);
413
781
  }
414
- /** 销毁 SDK 实例。 */
782
+ /**
783
+ * 销毁 SDK 实例。
784
+ *
785
+ * @remarks
786
+ * 销毁后会移除 message 监听,并拒绝尚未完成的 bridge 请求。
787
+ * 已销毁实例不应继续复用。
788
+ */
415
789
  destroy() {
416
790
  this.client.destroy();
417
791
  }
418
792
  }
419
- /** 创建独立 SDK 实例,主要用于测试或多实例场景。 */
793
+ /**
794
+ * 创建独立 SDK 实例。
795
+ *
796
+ * @param options SDK 运行配置,例如超时时间、nonce 或测试环境注入的 window。
797
+ * @returns 可独立管理生命周期的 `MiniProgramSDK` 实例。
798
+ *
799
+ * @remarks
800
+ * 适用于测试、多实例场景,或需要自定义 `timeout`、`targetWindow` 等运行参数的场景。
801
+ *
802
+ * @example
803
+ * ```ts
804
+ * import { createMiniProgramSDK } from '@heybox/hb-sdk'
805
+ *
806
+ * const sdk = createMiniProgramSDK({
807
+ * timeout: 15000,
808
+ * })
809
+ * ```
810
+ */
420
811
  function createMiniProgramSDK(options) {
421
812
  return new MiniProgramSDK(options);
422
813
  }
@@ -428,73 +819,112 @@ function getDefaultSDK() {
428
819
  }
429
820
  return defaultSDK;
430
821
  }
431
- /** 等待默认 SDK 实例与父容器完成握手。 */
822
+ /**
823
+ * 等待默认 SDK 实例与父容器完成握手。
824
+ *
825
+ * @returns 当默认 SDK 单例与父容器握手成功后 resolve。
826
+ * @throws {HbMiniProgramSDKError} 当当前页面不在 iframe 中、缺少 nonce 或握手超时时抛出。
827
+ */
432
828
  function ready() {
433
829
  return getDefaultSDK().ready();
434
830
  }
435
- /** 注册默认 SDK 实例的事件监听。 */
831
+ /**
832
+ * 注册默认 SDK 实例的事件监听。
833
+ *
834
+ * @param eventName 要监听的事件名。
835
+ * @param handler 事件处理函数。
836
+ * @returns 事件解绑函数。
837
+ */
436
838
  function on(eventName, handler) {
437
839
  return getDefaultSDK().on(eventName, handler);
438
840
  }
439
- /** 移除默认 SDK 实例的事件监听。 */
841
+ /**
842
+ * 移除默认 SDK 实例的事件监听。
843
+ *
844
+ * @param eventName 要移除的事件名。
845
+ * @param handler 对应的事件处理函数。
846
+ * @returns 无返回值。
847
+ */
440
848
  function off(eventName, handler) {
441
849
  getDefaultSDK().off(eventName, handler);
442
850
  }
443
- /** 默认 SDK 实例的用户模块。 */
851
+ /** 默认 SDK 实例的授权模块。 */
852
+ const auth = {
853
+ login: () => getDefaultSDK().auth.login(),
854
+ };
855
+ /** 默认 SDK 实例的用户资料模块。 */
444
856
  const user = {
445
857
  getInfo: () => getDefaultSDK().user.getInfo(),
446
- login: () => getDefaultSDK().user.login(),
447
858
  };
448
859
  /** 默认 SDK 实例的分享模块。 */
449
860
  const share = {
450
861
  showShareMenu: options => getDefaultSDK().share.showShareMenu(options),
451
862
  screenshot: options => getDefaultSDK().share.screenshot(options),
452
863
  };
453
- /** 默认 SDK 实例的系统模块。 */
454
- const system = {
455
- getWindowInfo: () => getDefaultSDK().system.getWindowInfo(),
456
- getStorage: options => getDefaultSDK().system.getStorage(options),
457
- setStorage: options => getDefaultSDK().system.setStorage(options),
864
+ /** 默认 SDK 实例的 Viewport 模块。 */
865
+ const viewport = {
866
+ getWindowInfo: () => getDefaultSDK().viewport.getWindowInfo(),
867
+ };
868
+ /** 默认 SDK 实例的 storage 模块。 */
869
+ const storage = {
870
+ getStorage: options => getDefaultSDK().storage.getStorage(options),
871
+ setStorage: options => getDefaultSDK().storage.setStorage(options),
872
+ };
873
+ /** 默认 SDK 实例的 network 模块。 */
874
+ const network = {
875
+ request: config => getDefaultSDK().network.request(config),
458
876
  };
459
877
 
460
878
  const hbSDK = {
461
879
  ready,
462
880
  on,
463
881
  off,
882
+ auth,
464
883
  user,
465
884
  share,
466
- system,
885
+ viewport,
886
+ storage,
887
+ network,
467
888
  };
468
889
 
890
+ exports.AUTH_LOGIN_METHOD = AUTH_LOGIN_METHOD;
891
+ exports.HbMiniProgramNetworkError = HbMiniProgramNetworkError;
469
892
  exports.HbMiniProgramSDKError = HbMiniProgramSDKError;
470
893
  exports.MINI_PROGRAM_BRIDGE_NONCE_PARAM = MINI_PROGRAM_BRIDGE_NONCE_PARAM;
471
894
  exports.MINI_PROGRAM_MESSAGE_NAMESPACE = MINI_PROGRAM_MESSAGE_NAMESPACE;
472
895
  exports.MINI_PROGRAM_MESSAGE_VERSION = MINI_PROGRAM_MESSAGE_VERSION;
473
896
  exports.MiniProgramSDK = MiniProgramSDK;
897
+ exports.NETWORK_REQUEST_METHOD = NETWORK_REQUEST_METHOD;
474
898
  exports.SDK_HANDSHAKE_METHOD = SDK_HANDSHAKE_METHOD;
475
899
  exports.SHARE_SCREENSHOT_METHOD = SHARE_SCREENSHOT_METHOD;
476
900
  exports.SHARE_SHOW_SHARE_MENU_METHOD = SHARE_SHOW_SHARE_MENU_METHOD;
477
- exports.SYSTEM_GET_STORAGE_METHOD = SYSTEM_GET_STORAGE_METHOD;
478
- exports.SYSTEM_GET_WINDOW_INFO_METHOD = SYSTEM_GET_WINDOW_INFO_METHOD;
479
- exports.SYSTEM_SET_STORAGE_METHOD = SYSTEM_SET_STORAGE_METHOD;
901
+ exports.STORAGE_GET_STORAGE_METHOD = STORAGE_GET_STORAGE_METHOD;
902
+ exports.STORAGE_SET_STORAGE_METHOD = STORAGE_SET_STORAGE_METHOD;
480
903
  exports.USER_GET_INFO_METHOD = USER_GET_INFO_METHOD;
481
- exports.USER_LOGIN_METHOD = USER_LOGIN_METHOD;
904
+ exports.VIEWPORT_GET_WINDOW_INFO_METHOD = VIEWPORT_GET_WINDOW_INFO_METHOD;
905
+ exports.auth = auth;
906
+ exports.createAuthModule = createAuthModule;
482
907
  exports.createMiniProgramSDK = createMiniProgramSDK;
908
+ exports.createNetworkModule = createNetworkModule;
483
909
  exports.createShareModule = createShareModule;
484
- exports.createSystemModule = createSystemModule;
910
+ exports.createStorageModule = createStorageModule;
485
911
  exports.createUserModule = createUserModule;
912
+ exports.createViewportModule = createViewportModule;
486
913
  exports.default = hbSDK;
487
914
  exports.getInfo = getInfo;
488
915
  exports.getStorage = getStorage;
489
916
  exports.getWindowInfo = getWindowInfo;
490
917
  exports.isMiniProgramBridgeMessage = isMiniProgramBridgeMessage;
491
918
  exports.login = login;
919
+ exports.network = network;
492
920
  exports.off = off;
493
921
  exports.on = on;
494
922
  exports.ready = ready;
923
+ exports.request = request;
495
924
  exports.screenshot = screenshot;
496
925
  exports.setStorage = setStorage;
497
926
  exports.share = share;
498
927
  exports.showShareMenu = showShareMenu;
499
- exports.system = system;
928
+ exports.storage = storage;
500
929
  exports.user = user;
930
+ exports.viewport = viewport;