@dino-dev/bridge-core-ts 0.0.3 → 0.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.
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * App 端以 812 作为设计稿最长边基准,将 adaptation 注入 system 模块。
5
5
  */
6
- import { type ArAdaptationInfo } from './system-module';
6
+ import { type ArAdaptationInfo, type SafeAreaInsets } from './system-module';
7
7
  import { type Unsubscribe } from './mrp-bridge';
8
8
  export type ArAdaptationListener = (adaptation: ArAdaptationInfo) => void;
9
9
  /** 从容器读取初始适配信息,并注册横竖屏变化监听。 */
@@ -12,6 +12,8 @@ export declare function initArAdaptation(): Promise<ArAdaptationInfo | null>;
12
12
  export declare function ar(value: number): number;
13
13
  /** 获取当前适配比例,便于 Canvas 或自定义渲染使用。 */
14
14
  export declare function getArScale(): number;
15
+ /** 获取 App 注入的设备安全区;不在容器内或 App 未注入时返回全 0。 */
16
+ export declare function getSafeArea(): SafeAreaInsets;
15
17
  /** 监听 App 横竖屏或窗口尺寸变化,返回取消监听函数。 */
16
18
  export declare function onArAdaptationChange(listener: ArAdaptationListener): Unsubscribe;
17
19
  //# sourceMappingURL=adaptation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adaptation.d.ts","sourceRoot":"","sources":["../../src/adaptation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAMxD,MAAM,MAAM,oBAAoB,GAAG,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAqB1E,8BAA8B;AAC9B,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAIzE;AAED,4BAA4B;AAC5B,wBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExC;AAED,mCAAmC;AACnC,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,kCAAkC;AAClC,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,WAAW,CAIhF"}
1
+ {"version":3,"file":"adaptation.d.ts","sourceRoot":"","sources":["../../src/adaptation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEN,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AASxD,MAAM,MAAM,oBAAoB,GAAG,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAiC1E,8BAA8B;AAC9B,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAIzE;AAED,4BAA4B;AAC5B,wBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExC;AAED,mCAAmC;AACnC,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,4CAA4C;AAC5C,wBAAgB,WAAW,IAAI,cAAc,CAE5C;AAED,kCAAkC;AAClC,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,oBAAoB,GAC5B,WAAW,CAIb"}
@@ -3,17 +3,23 @@
3
3
  *
4
4
  * App 端以 812 作为设计稿最长边基准,将 adaptation 注入 system 模块。
5
5
  */
6
- import { getSystemModule } from './system-module';
6
+ import { getSystemModule, } from './system-module';
7
7
  import { bridge } from './mrp-bridge';
8
+ const ZERO_SAFE_AREA = { top: 0, bottom: 0, left: 0, right: 0 };
8
9
  let currentScale = 1;
10
+ let currentSafeArea = ZERO_SAFE_AREA;
9
11
  let bridgeUnsubscribe = null;
10
12
  const listeners = new Set();
11
13
  function applyAdaptation(adaptation) {
12
- if (!adaptation || !Number.isFinite(adaptation.scale) || adaptation.scale <= 0) {
14
+ if (!adaptation ||
15
+ !Number.isFinite(adaptation.scale) ||
16
+ adaptation.scale <= 0) {
13
17
  currentScale = 1;
18
+ currentSafeArea = ZERO_SAFE_AREA;
14
19
  return null;
15
20
  }
16
21
  currentScale = adaptation.scale;
22
+ currentSafeArea = adaptation.safeArea ?? ZERO_SAFE_AREA;
17
23
  for (const listener of listeners) {
18
24
  listener(adaptation);
19
25
  }
@@ -40,6 +46,10 @@ export function ar(value) {
40
46
  export function getArScale() {
41
47
  return currentScale;
42
48
  }
49
+ /** 获取 App 注入的设备安全区;不在容器内或 App 未注入时返回全 0。 */
50
+ export function getSafeArea() {
51
+ return currentSafeArea;
52
+ }
43
53
  /** 监听 App 横竖屏或窗口尺寸变化,返回取消监听函数。 */
44
54
  export function onArAdaptationChange(listener) {
45
55
  ensureAdaptationListener();
@@ -1 +1 @@
1
- {"version":3,"file":"adaptation.js","sourceRoot":"","sources":["../../src/adaptation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAyB,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,MAAM,EAAoB,MAAM,cAAc,CAAC;AAExD,IAAI,YAAY,GAAG,CAAC,CAAC;AACrB,IAAI,iBAAiB,GAAuB,IAAI,CAAC;AACjD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwB,CAAC;AAIlD,SAAS,eAAe,CAAC,UAA+C;IACtE,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QAC/E,YAAY,GAAG,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC;IAChC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,wBAAwB;IAC/B,IAAI,iBAAiB;QAAE,OAAO;IAC9B,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAmB,YAAY,EAAE,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;QACnF,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,8BAA8B;AAC9B,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,wBAAwB,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,MAAM,eAAe,EAAE,CAAC,gBAAgB,EAAE,CAAC;IACxD,OAAO,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,EAAE,CAAC,KAAa;IAC9B,OAAO,KAAK,GAAG,YAAY,CAAC;AAC9B,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,UAAU;IACxB,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,oBAAoB,CAAC,QAA8B;IACjE,wBAAwB,EAAE,CAAC;IAC3B,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"adaptation.js","sourceRoot":"","sources":["../../src/adaptation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACN,eAAe,GAGf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,MAAM,EAAoB,MAAM,cAAc,CAAC;AAExD,MAAM,cAAc,GAAmB,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAEhF,IAAI,YAAY,GAAG,CAAC,CAAC;AACrB,IAAI,eAAe,GAAmB,cAAc,CAAC;AACrD,IAAI,iBAAiB,GAAuB,IAAI,CAAC;AACjD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwB,CAAC;AAIlD,SAAS,eAAe,CACvB,UAA+C;IAE/C,IACC,CAAC,UAAU;QACX,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC;QAClC,UAAU,CAAC,KAAK,IAAI,CAAC,EACpB,CAAC;QACF,YAAY,GAAG,CAAC,CAAC;QACjB,eAAe,GAAG,cAAc,CAAC;QACjC,OAAO,IAAI,CAAC;IACb,CAAC;IACD,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC;IAChC,eAAe,GAAG,UAAU,CAAC,QAAQ,IAAI,cAAc,CAAC;IACxD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QAClC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,UAAU,CAAC;AACnB,CAAC;AAED,SAAS,wBAAwB;IAChC,IAAI,iBAAiB;QAAE,OAAO;IAC9B,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAC5B,YAAY,EACZ,SAAS,EACT,CAAC,OAAO,EAAE,EAAE;QACX,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC,CACD,CAAC;AACH,CAAC;AAED,8BAA8B;AAC9B,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACrC,wBAAwB,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,MAAM,eAAe,EAAE,CAAC,gBAAgB,EAAE,CAAC;IACxD,OAAO,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,EAAE,CAAC,KAAa;IAC/B,OAAO,KAAK,GAAG,YAAY,CAAC;AAC7B,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,UAAU;IACzB,OAAO,YAAY,CAAC;AACrB,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,WAAW;IAC1B,OAAO,eAAe,CAAC;AACxB,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,oBAAoB,CACnC,QAA8B;IAE9B,wBAAwB,EAAE,CAAC;IAC3B,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AACzC,CAAC"}
@@ -3,6 +3,8 @@ export declare const bridgeMessageTypes: {
3
3
  readonly render: "render";
4
4
  readonly interaction: "interaction";
5
5
  readonly error: "error";
6
+ /** 宿主镜像给 H5 的回合事件(单向:宿主 → H5)。 */
7
+ readonly agent: "agent";
6
8
  };
7
9
  export declare const renderActions: {
8
10
  readonly set: "set";
@@ -47,4 +49,45 @@ export declare const interaction: {
47
49
  export declare const bridgeError: {
48
50
  readonly report: (payload: BridgeErrorPayload) => Promise<unknown>;
49
51
  };
52
+ /**
53
+ * 回合事件协议:宿主把「现在轮到谁、这一轮发生了什么」镜像给 H5。
54
+ *
55
+ * 用在 H5 页面**作为一个交互步骤**嵌在原生流程里的场景(AI 教学 / 问诊等):
56
+ * 原生题型能收到宿主的回合事件,H5 题型也应该能。宿主只负责把事实发下来,
57
+ * 怎么响应(放开作答、复位重做、演完反馈再收尾)由 H5 自己决定。
58
+ *
59
+ * 线格式:`{ type: 'agent', action, payload: { iid, ... } }`
60
+ */
61
+ export declare const agentEvents: {
62
+ /** 作答权交回给用户(宿主的开场播报已结束)。 */
63
+ readonly startLearn: "start_learn";
64
+ /** 本题重做。 */
65
+ readonly retryLearn: "retry_learn";
66
+ /** 本题判过;若宿主把收尾交给了 H5,H5 需回发一次收尾动作,否则流程不推进。 */
67
+ readonly passLearn: "pass_learn";
68
+ /** 用户**绕过这块 H5** 上行了一次作答(原生输入栏、原生选择器等)。 */
69
+ readonly externalAnswer: "external_answer";
70
+ };
71
+ export interface AgentEventPayload {
72
+ /**
73
+ * 这条事件属于哪一屏。
74
+ *
75
+ * 内容(`render/set`)和事件通常来自宿主上游的两条独立消息,到达先后不保证。
76
+ * 拿它对齐「这条事件说的是不是我现在这一屏」,不匹配就先扣着。
77
+ */
78
+ iid?: string;
79
+ [key: string]: unknown;
80
+ }
81
+ export interface ExternalAnswerPayload extends AgentEventPayload {
82
+ /** 那次绕过本页的上行负载(形态由宿主定义)。 */
83
+ answer?: Record<string, unknown>;
84
+ }
85
+ export interface AgentEventHandlers {
86
+ startLearn?(payload: AgentEventPayload, message: BridgeMessage<AgentEventPayload>): void;
87
+ retryLearn?(payload: AgentEventPayload, message: BridgeMessage<AgentEventPayload>): void;
88
+ passLearn?(payload: AgentEventPayload, message: BridgeMessage<AgentEventPayload>): void;
89
+ externalAnswer?(payload: ExternalAnswerPayload, message: BridgeMessage<ExternalAnswerPayload>): void;
90
+ }
91
+ /** 只订阅传了 handler 的那几个事件;返回的函数一次性退订。 */
92
+ export declare function bindAgentProtocol(handlers: AgentEventHandlers, transport?: Pick<ProtocolTransport, 'on'>): Unsubscribe;
50
93
  //# sourceMappingURL=content-protocol.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-protocol.d.ts","sourceRoot":"","sources":["../../src/content-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE5E,eAAO,MAAM,kBAAkB;;;;CAIrB,CAAC;AAEX,eAAO,MAAM,aAAa;;;;;;CAMhB,CAAC;AAEX,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO;IACxC,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,OAAO;IACzC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC/E,MAAM,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACnF,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;CAC9D;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,OAAO;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,CACA,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,KAAK,IAAI,GAC7C,WAAW,CAAC;IACf,IAAI,CACF,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,EAC3B,SAAS,GAAE,iBAA0B,GACpC,WAAW,CAcb;AAED,eAAO,MAAM,cAAc;+BACV,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAQ,OAAO,CAAC,OAAO,CAAC;iCAI7C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAQ,OAAO,CAAC,OAAO,CAAC;CAGxD,CAAC;AAEX,eAAO,MAAM,WAAW;oBACjB,CAAC,UAAU,MAAM,WAAW,kBAAkB,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,OAAO,CAAC;CAGjE,CAAC;AAEX,eAAO,MAAM,WAAW;+BACN,kBAAkB,KAAG,OAAO,CAAC,OAAO,CAAC;CAG7C,CAAC"}
1
+ {"version":3,"file":"content-protocol.d.ts","sourceRoot":"","sources":["../../src/content-protocol.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,8 @@ export const bridgeMessageTypes = {
3
3
  render: 'render',
4
4
  interaction: 'interaction',
5
5
  error: 'error',
6
+ /** 宿主镜像给 H5 的回合事件(单向:宿主 → H5)。 */
7
+ agent: 'agent',
6
8
  };
7
9
  export const renderActions = {
8
10
  set: 'set',
@@ -43,4 +45,38 @@ export const bridgeError = {
43
45
  return bridge.send(bridgeMessageTypes.error, 'report', payload);
44
46
  },
45
47
  };
48
+ /**
49
+ * 回合事件协议:宿主把「现在轮到谁、这一轮发生了什么」镜像给 H5。
50
+ *
51
+ * 用在 H5 页面**作为一个交互步骤**嵌在原生流程里的场景(AI 教学 / 问诊等):
52
+ * 原生题型能收到宿主的回合事件,H5 题型也应该能。宿主只负责把事实发下来,
53
+ * 怎么响应(放开作答、复位重做、演完反馈再收尾)由 H5 自己决定。
54
+ *
55
+ * 线格式:`{ type: 'agent', action, payload: { iid, ... } }`
56
+ */
57
+ export const agentEvents = {
58
+ /** 作答权交回给用户(宿主的开场播报已结束)。 */
59
+ startLearn: 'start_learn',
60
+ /** 本题重做。 */
61
+ retryLearn: 'retry_learn',
62
+ /** 本题判过;若宿主把收尾交给了 H5,H5 需回发一次收尾动作,否则流程不推进。 */
63
+ passLearn: 'pass_learn',
64
+ /** 用户**绕过这块 H5** 上行了一次作答(原生输入栏、原生选择器等)。 */
65
+ externalAnswer: 'external_answer',
66
+ };
67
+ /** 只订阅传了 handler 的那几个事件;返回的函数一次性退订。 */
68
+ export function bindAgentProtocol(handlers, transport = bridge) {
69
+ const pairs = [
70
+ [agentEvents.startLearn, handlers.startLearn],
71
+ [agentEvents.retryLearn, handlers.retryLearn],
72
+ [agentEvents.passLearn, handlers.passLearn],
73
+ [agentEvents.externalAnswer, handlers.externalAnswer],
74
+ ];
75
+ const subscriptions = pairs
76
+ .filter(([, handler]) => handler !== undefined)
77
+ .map(([action, handler]) => transport.on(bridgeMessageTypes.agent, action, (message) => {
78
+ handler(message.payload ?? {}, message);
79
+ }));
80
+ return () => subscriptions.forEach((unsubscribe) => unsubscribe());
81
+ }
46
82
  //# sourceMappingURL=content-protocol.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-protocol.js","sourceRoot":"","sources":["../../src/content-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAwC,MAAM,cAAc,CAAC;AAE5E,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,aAAa;IAC1B,KAAK,EAAE,OAAO;CACN,CAAC;AAEX,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,KAAK;IACV,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;CACV,CAAC;AAwCX,MAAM,UAAU,kBAAkB,CAChC,QAA2B,EAC3B,YAA+B,MAAM;IAErC,MAAM,aAAa,GAAG;QACpB,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,EAAE,CAAC,OAAwC,EAAE,EAAE;YACtG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC,CAAC;QACF,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,OAAwC,EAAE,EAAE;YACzG,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC,CAAC;QACF,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACvE,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC1B,CAAC,CAAC;KACH,CAAC;IAEF,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,KAAK,CAAC,UAAmC,EAAE;QACzC,OAAO,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9E,CAAC;IAED,OAAO,CAAC,UAAmC,EAAE;QAC3C,OAAO,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChF,CAAC;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,CAAI,MAAc,EAAE,OAA8B;QACpD,OAAO,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,MAAM,CAAC,OAA2B;QAChC,OAAO,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClE,CAAC;CACO,CAAC"}
1
+ {"version":3,"file":"content-protocol.js","sourceRoot":"","sources":["../../src/content-protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * iframe 宿主模式:H5 被嵌在网页 iframe 里(如教研后台的实时预览)时,把父窗口当作原生容器。
3
+ *
4
+ * 触发条件:页面在 iframe 内,且 URL 带 `nl_host=iframe&nl_host_origin=<父窗口 origin>`。
5
+ * 父窗口 origin 由宿主显式声明:只向它发消息、只收它发来的消息,其它来源一律忽略。
6
+ *
7
+ * H5 业务代码无需改动:`bridge.whenReady()` / `bindRenderProtocol` / `bindAgentProtocol`
8
+ * 照常工作。原生模块在预览里不可用(`system` 除外),调用返回 `null` 并通知宿主记录。
9
+ *
10
+ * 线格式(postMessage,均带 `__nlBridge: 1`):
11
+ * - H5 → 宿主:`{ kind: 'send', type, action, payload }`
12
+ * - H5 → 宿主:`{ kind: 'module', namespace, method }`(预览里不可用的原生调用)
13
+ * - 宿主 → H5:`{ kind: 'message', type, action, payload }`
14
+ */
15
+ export declare const IFRAME_HOST_PARAM = "nl_host";
16
+ export declare const IFRAME_HOST_ORIGIN_PARAM = "nl_host_origin";
17
+ export declare const IFRAME_HOST_MARK = "__nlBridge";
18
+ /**
19
+ * 满足触发条件时安装 iframe 宿主桥;已在原生容器内或条件不满足时什么都不做。
20
+ *
21
+ * @returns 是否已安装
22
+ */
23
+ export declare function installIframeHostBridge(): boolean;
24
+ //# sourceMappingURL=iframe-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iframe-host.d.ts","sourceRoot":"","sources":["../../src/iframe-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAC3C,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AACzD,eAAO,MAAM,gBAAgB,eAAe,CAAC;AA4C7C;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAmGjD"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * iframe 宿主模式:H5 被嵌在网页 iframe 里(如教研后台的实时预览)时,把父窗口当作原生容器。
3
+ *
4
+ * 触发条件:页面在 iframe 内,且 URL 带 `nl_host=iframe&nl_host_origin=<父窗口 origin>`。
5
+ * 父窗口 origin 由宿主显式声明:只向它发消息、只收它发来的消息,其它来源一律忽略。
6
+ *
7
+ * H5 业务代码无需改动:`bridge.whenReady()` / `bindRenderProtocol` / `bindAgentProtocol`
8
+ * 照常工作。原生模块在预览里不可用(`system` 除外),调用返回 `null` 并通知宿主记录。
9
+ *
10
+ * 线格式(postMessage,均带 `__nlBridge: 1`):
11
+ * - H5 → 宿主:`{ kind: 'send', type, action, payload }`
12
+ * - H5 → 宿主:`{ kind: 'module', namespace, method }`(预览里不可用的原生调用)
13
+ * - 宿主 → H5:`{ kind: 'message', type, action, payload }`
14
+ */
15
+ export const IFRAME_HOST_PARAM = 'nl_host';
16
+ export const IFRAME_HOST_ORIGIN_PARAM = 'nl_host_origin';
17
+ export const IFRAME_HOST_MARK = '__nlBridge';
18
+ const DESIGN_LONG_SIDE = 812;
19
+ function isHostEnvelope(data) {
20
+ return (typeof data === 'object' &&
21
+ data !== null &&
22
+ data[IFRAME_HOST_MARK] === 1);
23
+ }
24
+ function resolveHostOrigin() {
25
+ if (!window.parent || window.parent === window || !window.location)
26
+ return null;
27
+ const params = new URLSearchParams(window.location.search);
28
+ if (params.get(IFRAME_HOST_PARAM) !== 'iframe')
29
+ return null;
30
+ const raw = params.get(IFRAME_HOST_ORIGIN_PARAM);
31
+ if (!raw)
32
+ return null;
33
+ try {
34
+ const origin = new URL(raw).origin;
35
+ return origin === 'null' ? null : origin;
36
+ }
37
+ catch {
38
+ return null;
39
+ }
40
+ }
41
+ function currentAdaptation() {
42
+ const screenWidth = window.innerWidth;
43
+ const screenHeight = window.innerHeight;
44
+ return {
45
+ designLongSide: DESIGN_LONG_SIDE,
46
+ screenWidth,
47
+ screenHeight,
48
+ scale: Math.max(screenWidth, screenHeight) / DESIGN_LONG_SIDE,
49
+ safeArea: { top: 0, bottom: 0, left: 0, right: 0 },
50
+ };
51
+ }
52
+ /**
53
+ * 满足触发条件时安装 iframe 宿主桥;已在原生容器内或条件不满足时什么都不做。
54
+ *
55
+ * @returns 是否已安装
56
+ */
57
+ export function installIframeHostBridge() {
58
+ if (typeof window === 'undefined' || window.__FLUTTER_BRIDGE__)
59
+ return false;
60
+ const hostOrigin = resolveHostOrigin();
61
+ if (!hostOrigin)
62
+ return false;
63
+ const post = (kind, body) => {
64
+ window.parent.postMessage({ [IFRAME_HOST_MARK]: 1, kind, ...body }, hostOrigin);
65
+ };
66
+ const dispatch = (type, action, payload) => {
67
+ const message = {
68
+ type,
69
+ action,
70
+ payload,
71
+ timestamp: Date.now(),
72
+ };
73
+ window.dispatchEvent(new CustomEvent('flutterMessage', { detail: message }));
74
+ };
75
+ window.addEventListener('message', (event) => {
76
+ if (event.source !== window.parent || event.origin !== hostOrigin)
77
+ return;
78
+ const data = event.data;
79
+ if (!isHostEnvelope(data) || data.kind !== 'message')
80
+ return;
81
+ if (typeof data.type !== 'string' || typeof data.action !== 'string')
82
+ return;
83
+ const payload = typeof data.payload === 'object' && data.payload !== null
84
+ ? data.payload
85
+ : {};
86
+ dispatch(data.type, data.action, payload);
87
+ });
88
+ window.addEventListener('resize', () => {
89
+ dispatch('adaptation', 'changed', currentAdaptation());
90
+ });
91
+ const systemModule = {
92
+ isModuleAllowed: () => ({ allowed: false, namespace: '' }),
93
+ getAvailableModules: () => ({ modules: [] }),
94
+ getContainerInfo: () => ({
95
+ packageId: null,
96
+ registeredModules: [],
97
+ allowedModules: [],
98
+ adaptation: currentAdaptation(),
99
+ isIframeHost: true,
100
+ }),
101
+ };
102
+ const moduleProxy = (namespace) => new Proxy({}, {
103
+ // bridge.module() 用 `NativeModules[ns][method]` 做存在性判断,必须恒为真
104
+ has: () => true,
105
+ get: (_target, method) => {
106
+ if (typeof method !== 'string')
107
+ return undefined;
108
+ return async () => {
109
+ if (namespace === 'system' && method in systemModule) {
110
+ return systemModule[method]();
111
+ }
112
+ post('module', { namespace, method });
113
+ return null;
114
+ };
115
+ },
116
+ });
117
+ window.NativeModules = new Proxy({}, {
118
+ has: () => true,
119
+ get: (_target, namespace) => typeof namespace === 'string' ? moduleProxy(namespace) : undefined,
120
+ });
121
+ window.__FLUTTER_BRIDGE__ = {
122
+ send: async (type, action, payload) => {
123
+ post('send', { type, action, payload });
124
+ return null;
125
+ },
126
+ onMessage: (jsonString) => {
127
+ try {
128
+ const message = JSON.parse(jsonString);
129
+ dispatch(message.type, message.action, message.payload);
130
+ }
131
+ catch (e) {
132
+ console.error('[MRP Bridge] iframe 宿主消息解析失败:', e);
133
+ }
134
+ },
135
+ };
136
+ return true;
137
+ }
138
+ //# sourceMappingURL=iframe-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iframe-host.js","sourceRoot":"","sources":["../../src/iframe-host.ts"],"names":[],"mappings":"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"}
@@ -8,14 +8,15 @@
8
8
  * 所有 API 从此入口统一导出,消费者无需感知内部目录结构。
9
9
  */
10
10
  export { bridge, MrpBridge } from './mrp-bridge';
11
- export type { BridgeMessage, MessageHandler, Unsubscribe, } from './mrp-bridge';
11
+ export type { BridgeMessage, MessageHandler, Unsubscribe } from './mrp-bridge';
12
+ export { IFRAME_HOST_MARK, IFRAME_HOST_ORIGIN_PARAM, IFRAME_HOST_PARAM, } from './iframe-host';
12
13
  export { getSystemModule } from './system-module';
13
- export type { SystemModule, ModuleAllowedResult, AvailableModulesResult, ContainerInfoResult, ArAdaptationInfo, } from './system-module';
14
- export { ar, getArScale, initArAdaptation, onArAdaptationChange } from './adaptation';
14
+ export type { SystemModule, ModuleAllowedResult, AvailableModulesResult, ContainerInfoResult, ArAdaptationInfo, SafeAreaInsets, } from './system-module';
15
+ export { ar, getArScale, getSafeArea, initArAdaptation, onArAdaptationChange, } from './adaptation';
15
16
  export type { ArAdaptationListener } from './adaptation';
16
17
  export * from '../generated/index';
17
18
  export { lifecycle } from './lifecycle';
18
19
  export type { RouteChangedPayload, AppMountedPayload } from './lifecycle';
19
- export { bindRenderProtocol, bridgeError, bridgeMessageTypes, interaction, renderActions, renderProtocol, } from './content-protocol';
20
- export type { BridgeErrorPayload, InteractionPayload, ProtocolTransport, RenderHandlers, RenderPayload, } from './content-protocol';
20
+ export { agentEvents, bindAgentProtocol, bindRenderProtocol, bridgeError, bridgeMessageTypes, interaction, renderActions, renderProtocol, } from './content-protocol';
21
+ export type { AgentEventHandlers, AgentEventPayload, BridgeErrorPayload, ExternalAnswerPayload, InteractionPayload, ProtocolTransport, RenderHandlers, RenderPayload, } from './content-protocol';
21
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EACV,aAAa,EACb,cAAc,EACd,WAAW,GACZ,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACtF,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGzD,cAAc,oBAAoB,CAAC;AAGnC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG1E,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,aAAa,GACd,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG/E,OAAO,EACN,gBAAgB,EAChB,wBAAwB,EACxB,iBAAiB,GACjB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EACX,YAAY,EACZ,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACN,EAAE,EACF,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,oBAAoB,GACpB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGzD,cAAc,oBAAoB,CAAC;AAGnC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG1E,OAAO,EACN,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,cAAc,GACd,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACX,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,aAAa,GACb,MAAM,oBAAoB,CAAC"}
package/dist/src/index.js CHANGED
@@ -9,14 +9,16 @@
9
9
  */
10
10
  // 核心 Bridge
11
11
  export { bridge, MrpBridge } from './mrp-bridge';
12
+ // iframe 宿主模式(网页内嵌预览)的契约常量
13
+ export { IFRAME_HOST_MARK, IFRAME_HOST_ORIGIN_PARAM, IFRAME_HOST_PARAM, } from './iframe-host';
12
14
  // 内置系统模块类型 + 工厂函数(容器核心契约)
13
15
  export { getSystemModule } from './system-module';
14
16
  // App/H5 统一屏幕适配
15
- export { ar, getArScale, initArAdaptation, onArAdaptationChange } from './adaptation';
17
+ export { ar, getArScale, getSafeArea, initArAdaptation, onArAdaptationChange, } from './adaptation';
16
18
  // Generated 模块:类型 + 工厂函数
17
19
  export * from '../generated/index';
18
20
  // 生命周期上报工具
19
21
  export { lifecycle } from './lifecycle';
20
22
  // 标准内容渲染、交互与错误协议
21
- export { bindRenderProtocol, bridgeError, bridgeMessageTypes, interaction, renderActions, renderProtocol, } from './content-protocol';
23
+ export { agentEvents, bindAgentProtocol, bindRenderProtocol, bridgeError, bridgeMessageTypes, interaction, renderActions, renderProtocol, } from './content-protocol';
22
24
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,YAAY;AACZ,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAOjD,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AASlD,gBAAgB;AAChB,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGtF,yBAAyB;AACzB,cAAc,oBAAoB,CAAC;AAEnC,WAAW;AACX,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,iBAAiB;AACjB,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,YAAY;AACZ,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGjD,2BAA2B;AAC3B,OAAO,EACN,gBAAgB,EAChB,wBAAwB,EACxB,iBAAiB,GACjB,MAAM,eAAe,CAAC;AAEvB,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAUlD,gBAAgB;AAChB,OAAO,EACN,EAAE,EACF,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,oBAAoB,GACpB,MAAM,cAAc,CAAC;AAGtB,yBAAyB;AACzB,cAAc,oBAAoB,CAAC;AAEnC,WAAW;AACX,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,iBAAiB;AACjB,OAAO,EACN,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,cAAc,GACd,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * 浏览器 Mock Bridge —— 让 H5 页面脱离 App 容器,在 Chrome 里直接开发调试。
3
+ *
4
+ * 不安装时,浏览器环境下 `whenReady()` 永不 resolve、所有原生调用静默返回 `null`,
5
+ * 页面会停在空状态且不报错。安装后即可拿到可控的假数据与事件。
6
+ *
7
+ * 仅供开发使用,请通过子路径引入,避免被打进生产包:
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * if (import.meta.env.DEV) {
12
+ * const { installMockBridge } = await import('@h5-container/bridge-core-ts/mock');
13
+ * installMockBridge({
14
+ * packageId: 'student_micro_pages',
15
+ * allowedModules: ['user', 'audio', 'navigation'],
16
+ * modules: {
17
+ * user: { getProfile: { userId: '1', nickname: '测试同学' } },
18
+ * audio: { play: async () => ({ ok: true }) },
19
+ * },
20
+ * });
21
+ * }
22
+ * ```
23
+ */
24
+ import type { ArAdaptationInfo } from './system-module';
25
+ /**
26
+ * 单个模块的 mock 实现。
27
+ *
28
+ * 值可以是函数(接收原始调用参数),也可以是静态数据(直接作为返回值)。
29
+ */
30
+ export type MockModuleImpl = Record<string, ((...args: any[]) => unknown | Promise<unknown>) | unknown>;
31
+ /** 一次原生调用的记录 */
32
+ export interface MockCallRecord {
33
+ namespace: string;
34
+ method: string;
35
+ args: unknown[];
36
+ result: unknown;
37
+ /** 未命中 mock 定义时为 true */
38
+ missing: boolean;
39
+ timestamp: number;
40
+ }
41
+ export interface MockBridgeConfig {
42
+ /** 容器信息里的包 ID */
43
+ packageId?: string;
44
+ /**
45
+ * 授权模块白名单。
46
+ *
47
+ * 传入后会像真实容器一样拦截越权调用并返回 `MODULE_ACCESS_DENIED`,
48
+ * 可在浏览器阶段提前发现 `package.meta.json` 的 `allowedModules` 漏配。
49
+ * 不传则不做权限校验。
50
+ */
51
+ allowedModules?: string[];
52
+ /** 容器已注册模块列表,默认与 allowedModules 一致 */
53
+ registeredModules?: string[];
54
+ /** 屏幕适配信息,缺省字段按当前窗口尺寸推算 */
55
+ adaptation?: Partial<ArAdaptationInfo>;
56
+ /** 注入到 getContainerInfo().auth,供 h5_app_http 读取 */
57
+ auth?: Record<string, unknown>;
58
+ /** 追加到 getContainerInfo() 的其他字段 */
59
+ containerInfoExtra?: Record<string, unknown>;
60
+ /** 各命名空间的 mock 实现 */
61
+ modules?: Record<string, MockModuleImpl>;
62
+ /** 处理 `bridge.send()`,返回值作为调用方收到的结果 */
63
+ onSend?: (type: string, action: string, payload: Record<string, unknown>) => unknown;
64
+ /** 是否打印调用日志,默认 true */
65
+ log?: boolean;
66
+ /** 窗口尺寸变化时自动重算并广播 adaptation,默认 true */
67
+ followWindowResize?: boolean;
68
+ }
69
+ /** 安装后返回的控制句柄 */
70
+ export interface MockBridgeHandle {
71
+ /** 模拟一条 Native → H5 消息 */
72
+ emit(type: string, action: string, payload?: Record<string, unknown>): void;
73
+ /** 更新屏幕适配信息并广播 `adaptation/changed` */
74
+ setAdaptation(patch: Partial<ArAdaptationInfo>): void;
75
+ /** 按时间顺序记录的原生调用 */
76
+ readonly calls: MockCallRecord[];
77
+ /** 打印所有未命中 mock 定义的调用,便于补齐 */
78
+ printMissing(): void;
79
+ /** 卸载 mock,恢复安装前的 window 状态 */
80
+ uninstall(): void;
81
+ }
82
+ declare global {
83
+ interface Window {
84
+ /** 已安装的 Mock Bridge 句柄,可在控制台直接操作 */
85
+ __MRP_MOCK__?: MockBridgeHandle;
86
+ }
87
+ }
88
+ /**
89
+ * 安装 Mock Bridge。
90
+ *
91
+ * 已经在真实容器中运行时会直接跳过,因此可以无条件调用。
92
+ */
93
+ export declare function installMockBridge(config?: MockBridgeConfig): MockBridgeHandle | null;
94
+ /**
95
+ * 仅在非容器环境安装 mock,在真机/App 中自动跳过。
96
+ *
97
+ * 等价于 `installMockBridge`,语义更明确,适合直接写在入口文件里。
98
+ */
99
+ export declare const setupDevBridge: typeof installMockBridge;
100
+ //# sourceMappingURL=mock-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-bridge.d.ts","sourceRoot":"","sources":["../../src/mock-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAkB,MAAM,iBAAiB,CAAC;AAMxE;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAClC,MAAM,EACN,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAC1D,CAAC;AAEF,gBAAgB;AAChB,MAAM,WAAW,cAAc;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,yBAAyB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,iBAAiB;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,sCAAsC;IACtC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,2BAA2B;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACvC,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,mCAAmC;IACnC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACzC,uCAAuC;IACvC,MAAM,CAAC,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC;IACb,uBAAuB;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,wCAAwC;IACxC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,iBAAiB;AACjB,MAAM,WAAW,gBAAgB;IAChC,0BAA0B;IAC1B,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5E,uCAAuC;IACvC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;IACtD,mBAAmB;IACnB,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC;IACjC,8BAA8B;IAC9B,YAAY,IAAI,IAAI,CAAC;IACrB,+BAA+B;IAC/B,SAAS,IAAI,IAAI,CAAC;CAClB;AAUD,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,MAAM;QACf,oCAAoC;QACpC,YAAY,CAAC,EAAE,gBAAgB,CAAC;KAChC;CACD;AAuBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAChC,MAAM,GAAE,gBAAqB,GAC3B,gBAAgB,GAAG,IAAI,CAgPzB;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,0BAAoB,CAAC"}