@wapri/gjsbridge 0.0.0-stage → 3.0.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.
@@ -0,0 +1,49 @@
1
+ import type { BridgeApiConfig } from '../registers';
2
+ import type { JSBridgeConfig, NativeEventListener, NativeTransport } from '../types/bridge';
3
+ /** 统一维护 Native 响应回调、请求 ID、pending Map 与订阅事件。 */
4
+ export declare class BridgeCB {
5
+ private readonly config;
6
+ constructor(config: JSBridgeConfig);
7
+ private readonly pendingRequests;
8
+ private readonly eventListeners;
9
+ private requestSequence;
10
+ /** 接收 Native 一次性事务响应的全局回调。 */
11
+ readonly onNativeMessage: (rawResponse: string) => void;
12
+ /** 接收 Native 长连接或订阅事件的全局回调。 */
13
+ readonly onNativeEvent: (eventName: string, data: unknown) => void;
14
+ /**
15
+ * 创建一个等待 Native 响应的事务,并通过 transport 发送请求。
16
+ *
17
+ * @param options 本次 Native 调用的执行配置。
18
+ * @returns code 为 0 时解析 data,否则以携带 Native code 的 BridgeError 拒绝。
19
+ */
20
+ call<TData = unknown, TParams extends Record<string, unknown> = Record<string, unknown>>(method: string, params: TParams, transport: NativeTransport, options: Omit<BridgeApiConfig, 'nativeMethod' | 'initialParams'>): Promise<TData>;
21
+ /**
22
+ * 订阅指定 Native 事件。
23
+ *
24
+ * @returns 取消本次订阅的函数。
25
+ */
26
+ on<TData = unknown>(eventName: string, listener: NativeEventListener<TData>): () => void;
27
+ /**
28
+ * 订阅一次指定 Native 事件,首次触发后自动取消。
29
+ *
30
+ * @returns 提前取消本次订阅的函数。
31
+ */
32
+ once<TData = unknown>(eventName: string, listener: NativeEventListener<TData>): () => void;
33
+ /** 移除指定事件的一个监听函数。 */
34
+ off<TData = unknown>(eventName: string, listener: NativeEventListener<TData>): void;
35
+ /** 拒绝未完成请求并清空所有事件订阅。 */
36
+ destroy(): void;
37
+ /** 生成当前实例内唯一的请求 ID。 */
38
+ private createRequestId;
39
+ /** 根据 requestId 清理事务,并将结果交给对应的 Promise。 */
40
+ private settleRequest;
41
+ /** 解析 Native 返回的 JSON 响应,并匹配对应的一次性事务。 */
42
+ private handleNativeResponse;
43
+ /** 解析并分发指定名称的 Native 订阅事件。 */
44
+ private handleNativeEvent;
45
+ /** 尝试将 Native 传入的 JSON 字符串还原为事件数据。 */
46
+ private parseEventData;
47
+ /** 仅在当前 JSBridge 实例开启调试时输出 Native 原始数据。 */
48
+ private debugLog;
49
+ }
@@ -0,0 +1,217 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
4
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
5
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
7
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
8
+ import { get, isNumber, isObject, isString } from '@wapri/gbase';
9
+ import { BridgeError } from "../errors";
10
+ var DEFAULT_TIMEOUT = 10000;
11
+ /** 统一维护 Native 响应回调、请求 ID、pending Map 与订阅事件。 */
12
+ export var BridgeCB = /*#__PURE__*/function () {
13
+ function BridgeCB(config) {
14
+ var _this = this;
15
+ _classCallCheck(this, BridgeCB);
16
+ _defineProperty(this, "pendingRequests", new Map());
17
+ _defineProperty(this, "eventListeners", new Map());
18
+ _defineProperty(this, "requestSequence", 0);
19
+ /** 接收 Native 一次性事务响应的全局回调。 */
20
+ _defineProperty(this, "onNativeMessage", function (rawResponse) {
21
+ _this.debugLog('[jsbridge] Native -> JS', rawResponse);
22
+ _this.handleNativeResponse(rawResponse);
23
+ });
24
+ /** 接收 Native 长连接或订阅事件的全局回调。 */
25
+ _defineProperty(this, "onNativeEvent", function (eventName, data) {
26
+ _this.debugLog('[jsbridge] Native -> JS event', eventName, data);
27
+ _this.handleNativeEvent(eventName, data);
28
+ });
29
+ this.config = config;
30
+ }
31
+ _createClass(BridgeCB, [{
32
+ key: "call",
33
+ value:
34
+ /**
35
+ * 创建一个等待 Native 响应的事务,并通过 transport 发送请求。
36
+ *
37
+ * @param options 本次 Native 调用的执行配置。
38
+ * @returns code 为 0 时解析 data,否则以携带 Native code 的 BridgeError 拒绝。
39
+ */
40
+ function call(method, params, transport, options) {
41
+ var _this2 = this;
42
+ var requestId = this.createRequestId();
43
+ var request = {
44
+ method: method,
45
+ params: params,
46
+ requestId: requestId
47
+ };
48
+ return new Promise(function (_resolve, reject) {
49
+ var timer = window.setTimeout(function () {
50
+ _this2.settleRequest(requestId, new Error('KMBridge 请求超时'));
51
+ }, (options === null || options === void 0 ? void 0 : options.timeout) || DEFAULT_TIMEOUT);
52
+ _this2.pendingRequests.set(requestId, {
53
+ resolve: function resolve(data) {
54
+ return _resolve(data);
55
+ },
56
+ reject: reject,
57
+ timer: timer
58
+ });
59
+ try {
60
+ transport(request);
61
+ } catch (error) {
62
+ _this2.settleRequest(requestId, error instanceof Error ? error : new Error('KMBridge 调用失败'));
63
+ }
64
+ });
65
+ }
66
+
67
+ /**
68
+ * 订阅指定 Native 事件。
69
+ *
70
+ * @returns 取消本次订阅的函数。
71
+ */
72
+ }, {
73
+ key: "on",
74
+ value: function on(eventName, listener) {
75
+ var _this$eventListeners$,
76
+ _this3 = this;
77
+ var listeners = (_this$eventListeners$ = this.eventListeners.get(eventName)) !== null && _this$eventListeners$ !== void 0 ? _this$eventListeners$ : new Set();
78
+ var eventListener = listener;
79
+ listeners.add(eventListener);
80
+ this.eventListeners.set(eventName, listeners);
81
+ return function () {
82
+ return _this3.off(eventName, eventListener);
83
+ };
84
+ }
85
+
86
+ /**
87
+ * 订阅一次指定 Native 事件,首次触发后自动取消。
88
+ *
89
+ * @returns 提前取消本次订阅的函数。
90
+ */
91
+ }, {
92
+ key: "once",
93
+ value: function once(eventName, listener) {
94
+ var remove = this.on(eventName, function (data) {
95
+ remove();
96
+ listener(data);
97
+ });
98
+ return remove;
99
+ }
100
+
101
+ /** 移除指定事件的一个监听函数。 */
102
+ }, {
103
+ key: "off",
104
+ value: function off(eventName, listener) {
105
+ var listeners = this.eventListeners.get(eventName);
106
+ if (!listeners) {
107
+ return;
108
+ }
109
+ listeners.delete(listener);
110
+ if (listeners.size === 0) {
111
+ this.eventListeners.delete(eventName);
112
+ }
113
+ }
114
+
115
+ /** 拒绝未完成请求并清空所有事件订阅。 */
116
+ }, {
117
+ key: "destroy",
118
+ value: function destroy() {
119
+ this.pendingRequests.forEach(function (pendingRequest) {
120
+ clearTimeout(pendingRequest.timer);
121
+ pendingRequest.reject(new Error('KMBridge 已销毁'));
122
+ });
123
+ this.pendingRequests.clear();
124
+ this.eventListeners.clear();
125
+ }
126
+
127
+ /** 生成当前实例内唯一的请求 ID。 */
128
+ }, {
129
+ key: "createRequestId",
130
+ value: function createRequestId() {
131
+ this.requestSequence += 1;
132
+ return "BridgeHandle".concat(Date.now()).concat(this.requestSequence);
133
+ }
134
+
135
+ /** 根据 requestId 清理事务,并将结果交给对应的 Promise。 */
136
+ }, {
137
+ key: "settleRequest",
138
+ value: function settleRequest(requestId, error, data) {
139
+ var pendingRequest = this.pendingRequests.get(requestId);
140
+ if (!pendingRequest) {
141
+ return;
142
+ }
143
+ clearTimeout(pendingRequest.timer);
144
+ this.pendingRequests.delete(requestId);
145
+ if (error) {
146
+ pendingRequest.reject(error);
147
+ return;
148
+ }
149
+ pendingRequest.resolve(data);
150
+ }
151
+
152
+ /** 解析 Native 返回的 JSON 响应,并匹配对应的一次性事务。 */
153
+ }, {
154
+ key: "handleNativeResponse",
155
+ value: function handleNativeResponse(rawResponse) {
156
+ try {
157
+ var response = JSON.parse(rawResponse);
158
+ if (!isObject(response)) {
159
+ return;
160
+ }
161
+ var requestId = get(response, 'requestId');
162
+ var code = get(response, 'code');
163
+ var message = get(response, 'message');
164
+ if (!isString(requestId) || !isNumber(code) || !isString(message)) {
165
+ return;
166
+ }
167
+ var nativeCode = Number(code);
168
+ if (nativeCode === 0) {
169
+ this.settleRequest(requestId, undefined, get(response, 'data'));
170
+ return;
171
+ }
172
+ this.settleRequest(requestId, new BridgeError(nativeCode, message));
173
+ } catch (_unused) {
174
+ // Native 返回非法 JSON 时忽略,不影响仍在等待的其他事务。
175
+ }
176
+ }
177
+
178
+ /** 解析并分发指定名称的 Native 订阅事件。 */
179
+ }, {
180
+ key: "handleNativeEvent",
181
+ value: function handleNativeEvent(eventName, data) {
182
+ var listeners = this.eventListeners.get(eventName);
183
+ if (!listeners) {
184
+ return;
185
+ }
186
+ var eventData = this.parseEventData(data);
187
+ listeners.forEach(function (listener) {
188
+ return listener(eventData);
189
+ });
190
+ }
191
+
192
+ /** 尝试将 Native 传入的 JSON 字符串还原为事件数据。 */
193
+ }, {
194
+ key: "parseEventData",
195
+ value: function parseEventData(data) {
196
+ if (!isString(data)) {
197
+ return data;
198
+ }
199
+ try {
200
+ return JSON.parse(data);
201
+ } catch (_unused2) {
202
+ return data;
203
+ }
204
+ }
205
+
206
+ /** 仅在当前 JSBridge 实例开启调试时输出 Native 原始数据。 */
207
+ }, {
208
+ key: "debugLog",
209
+ value: function debugLog() {
210
+ if (this.config.debug) {
211
+ var _console;
212
+ (_console = console).log.apply(_console, arguments);
213
+ }
214
+ }
215
+ }]);
216
+ return BridgeCB;
217
+ }();
@@ -0,0 +1,43 @@
1
+ import type { BridgeApiConfig } from '../registers';
2
+ import { BridgeCB } from './bridgeCB';
3
+ import type { JSBridgeConfig } from '../types/bridge';
4
+ /** 只负责三端 Native transport,并复用 BridgeCB 的回调能力。 */
5
+ export declare class JSBNative {
6
+ /** 当前实例的运行时配置。 */
7
+ readonly config: JSBridgeConfig;
8
+ /** 可复用的请求响应与事件回调管理器。 */
9
+ readonly cb: BridgeCB;
10
+ /** 挂载供 Native 调用的全局响应与事件回调。 */
11
+ constructor();
12
+ /** 设置是否打印当前实例与 Native 通信的原始数据。 */
13
+ setDebug(debug: boolean): void;
14
+ /**
15
+ * 将业务方法及参数交给当前 WebView 容器的 Native 通道。
16
+ *
17
+ * @param options 本次 Native 调用的执行配置。
18
+ * @returns Native 成功响应中的 data。
19
+ */
20
+ callNative<TData = unknown, TParams extends Record<string, unknown> = Record<string, unknown>>(method: string, params: TParams, options: Omit<BridgeApiConfig, 'nativeMethod' | 'initialParams'>): Promise<TData>;
21
+ /** 清理未完成请求、事件订阅以及本实例挂载的全局回调。 */
22
+ destroy(): void;
23
+ /**
24
+ * 检查 Native 通道是否已注入到当前页面。
25
+ *
26
+ * @returns `true` 表示 Android/鸿蒙或 iOS 的 Native 通道已挂载。
27
+ */
28
+ webReady(): boolean;
29
+ /** 将 BridgeCB 的处理函数注册为 Native 回调入口。 */
30
+ private installNativeCallbacks;
31
+ /**
32
+ * 按业务方法获取 iOS 消息通道,未注入时回退到 Android/鸿蒙通道。
33
+ *
34
+ * iOS 使用 `webkit.messageHandlers[method]`,报文中不重复携带 method;
35
+ * Android/鸿蒙继续使用 `KMBridge.handle`,报文中携带完整请求。
36
+ *
37
+ * @param method 本次调用对应的 Native 方法名。
38
+ * @returns 可调用的 Native 消息发送函数;容器未注入时返回 undefined。
39
+ */
40
+ private getNativeTransport;
41
+ /** 仅在当前实例开启调试时输出发送给 Native 的原始报文。 */
42
+ private debugLog;
43
+ }
@@ -0,0 +1,145 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
4
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
5
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
7
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
8
+ import { isFunction, isUndefined } from '@wapri/gbase';
9
+ import { BridgeCB } from "./bridgeCB";
10
+ import { getBridgeWindow } from "../utils";
11
+
12
+ /** 只负责三端 Native transport,并复用 BridgeCB 的回调能力。 */
13
+ export var JSBNative = /*#__PURE__*/function () {
14
+ /** 挂载供 Native 调用的全局响应与事件回调。 */
15
+ function JSBNative() {
16
+ _classCallCheck(this, JSBNative);
17
+ /** 当前实例的运行时配置。 */
18
+ _defineProperty(this, "config", {
19
+ debug: false
20
+ });
21
+ /** 可复用的请求响应与事件回调管理器。 */
22
+ _defineProperty(this, "cb", new BridgeCB(this.config));
23
+ this.installNativeCallbacks();
24
+ }
25
+
26
+ /** 设置是否打印当前实例与 Native 通信的原始数据。 */
27
+ _createClass(JSBNative, [{
28
+ key: "setDebug",
29
+ value: function setDebug(debug) {
30
+ this.config.debug = debug;
31
+ }
32
+
33
+ /**
34
+ * 将业务方法及参数交给当前 WebView 容器的 Native 通道。
35
+ *
36
+ * @param options 本次 Native 调用的执行配置。
37
+ * @returns Native 成功响应中的 data。
38
+ */
39
+ }, {
40
+ key: "callNative",
41
+ value: function callNative(method, params, options) {
42
+ var transport = this.getNativeTransport(method);
43
+ if (isUndefined(transport)) {
44
+ console.log('KMBridge 当前未就绪');
45
+ console.dir({
46
+ method: method,
47
+ params: params
48
+ });
49
+ return Promise.reject(new Error('KMBridge 当前未就绪'));
50
+ }
51
+ return this.cb.call(method, params, transport, options);
52
+ }
53
+
54
+ /** 清理未完成请求、事件订阅以及本实例挂载的全局回调。 */
55
+ }, {
56
+ key: "destroy",
57
+ value: function destroy() {
58
+ this.cb.destroy();
59
+ var bridgeWindow = getBridgeWindow();
60
+ if ((bridgeWindow === null || bridgeWindow === void 0 ? void 0 : bridgeWindow.onNativeMessage) === this.cb.onNativeMessage) {
61
+ delete bridgeWindow.onNativeMessage;
62
+ }
63
+ if ((bridgeWindow === null || bridgeWindow === void 0 ? void 0 : bridgeWindow.onNativeEvent) === this.cb.onNativeEvent) {
64
+ delete bridgeWindow.onNativeEvent;
65
+ }
66
+ }
67
+
68
+ /**
69
+ * 检查 Native 通道是否已注入到当前页面。
70
+ *
71
+ * @returns `true` 表示 Android/鸿蒙或 iOS 的 Native 通道已挂载。
72
+ */
73
+ }, {
74
+ key: "webReady",
75
+ value: function webReady() {
76
+ var _bridgeWindow$webkit;
77
+ var bridgeWindow = getBridgeWindow();
78
+ return !isUndefined(bridgeWindow === null || bridgeWindow === void 0 ? void 0 : bridgeWindow.KMBridge) || !isUndefined(bridgeWindow === null || bridgeWindow === void 0 || (_bridgeWindow$webkit = bridgeWindow.webkit) === null || _bridgeWindow$webkit === void 0 ? void 0 : _bridgeWindow$webkit.messageHandlers);
79
+ }
80
+
81
+ /** 将 BridgeCB 的处理函数注册为 Native 回调入口。 */
82
+ }, {
83
+ key: "installNativeCallbacks",
84
+ value: function installNativeCallbacks() {
85
+ var bridgeWindow = getBridgeWindow();
86
+ if (isUndefined(bridgeWindow)) {
87
+ return;
88
+ }
89
+ bridgeWindow.onNativeMessage = this.cb.onNativeMessage;
90
+ bridgeWindow.onNativeEvent = this.cb.onNativeEvent;
91
+ }
92
+
93
+ /**
94
+ * 按业务方法获取 iOS 消息通道,未注入时回退到 Android/鸿蒙通道。
95
+ *
96
+ * iOS 使用 `webkit.messageHandlers[method]`,报文中不重复携带 method;
97
+ * Android/鸿蒙继续使用 `KMBridge.handle`,报文中携带完整请求。
98
+ *
99
+ * @param method 本次调用对应的 Native 方法名。
100
+ * @returns 可调用的 Native 消息发送函数;容器未注入时返回 undefined。
101
+ */
102
+ }, {
103
+ key: "getNativeTransport",
104
+ value: function getNativeTransport(method) {
105
+ var _bridgeWindow$webkit2,
106
+ _this = this;
107
+ var bridgeWindow = getBridgeWindow();
108
+ var iOSHandler = bridgeWindow === null || bridgeWindow === void 0 || (_bridgeWindow$webkit2 = bridgeWindow.webkit) === null || _bridgeWindow$webkit2 === void 0 || (_bridgeWindow$webkit2 = _bridgeWindow$webkit2.messageHandlers) === null || _bridgeWindow$webkit2 === void 0 ? void 0 : _bridgeWindow$webkit2[method];
109
+ if (isFunction(iOSHandler === null || iOSHandler === void 0 ? void 0 : iOSHandler.postMessage)) {
110
+ var postMessage = iOSHandler.postMessage.bind(iOSHandler);
111
+ return function (_ref) {
112
+ var params = _ref.params,
113
+ requestId = _ref.requestId;
114
+ var message = JSON.stringify({
115
+ params: params,
116
+ requestId: requestId
117
+ });
118
+ _this.debugLog('[jsbridge] JS -> Native', message);
119
+ postMessage(message);
120
+ };
121
+ }
122
+ var nativeBridge = bridgeWindow === null || bridgeWindow === void 0 ? void 0 : bridgeWindow.KMBridge;
123
+ if (isFunction(nativeBridge === null || nativeBridge === void 0 ? void 0 : nativeBridge.handle)) {
124
+ var handle = nativeBridge.handle.bind(nativeBridge);
125
+ return function (request) {
126
+ var message = JSON.stringify(request);
127
+ _this.debugLog('[jsbridge] JS -> Native', message);
128
+ handle(message);
129
+ };
130
+ }
131
+ return undefined;
132
+ }
133
+
134
+ /** 仅在当前实例开启调试时输出发送给 Native 的原始报文。 */
135
+ }, {
136
+ key: "debugLog",
137
+ value: function debugLog() {
138
+ if (this.config.debug) {
139
+ var _console;
140
+ (_console = console).log.apply(_console, arguments);
141
+ }
142
+ }
143
+ }]);
144
+ return JSBNative;
145
+ }();
@@ -0,0 +1,6 @@
1
+ /** Native 业务方法返回失败时抛出的错误,保留原始错误码与错误信息。 */
2
+ export declare class BridgeError extends Error {
3
+ /** Native 响应中的 code。 */
4
+ readonly code: number;
5
+ constructor(code: number, message: string);
6
+ }
@@ -0,0 +1,33 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
3
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
4
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
6
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
7
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
8
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
9
+ function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
10
+ function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct.bind(); } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
11
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
12
+ function _isNativeFunction(fn) { try { return Function.toString.call(fn).indexOf("[native code]") !== -1; } catch (e) { return typeof fn === "function"; } }
13
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
14
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
15
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
16
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
17
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
18
+ /** Native 业务方法返回失败时抛出的错误,保留原始错误码与错误信息。 */
19
+ export var BridgeError = /*#__PURE__*/function (_Error) {
20
+ _inherits(BridgeError, _Error);
21
+ var _super = _createSuper(BridgeError);
22
+ function BridgeError(code, message) {
23
+ var _this;
24
+ _classCallCheck(this, BridgeError);
25
+ _this = _super.call(this, message);
26
+ /** Native 响应中的 code。 */
27
+ _defineProperty(_assertThisInitialized(_this), "code", void 0);
28
+ _this.name = 'BridgeError';
29
+ _this.code = code;
30
+ return _this;
31
+ }
32
+ return _createClass(BridgeError);
33
+ }( /*#__PURE__*/_wrapNativeSuper(Error));
@@ -0,0 +1 @@
1
+ export { BridgeError } from './bridgeError';
@@ -0,0 +1 @@
1
+ export { BridgeError } from "./bridgeError";
@@ -0,0 +1,6 @@
1
+ import type { JSBridge } from './types/bridge';
2
+ export { BridgeError } from './errors';
3
+ export type { JSBridgeConfig } from './types/bridge';
4
+ /** 业务侧唯一入口:使用 jsbridge.<具体 Native 方法名>(params)。 */
5
+ export declare const jsbridge: JSBridge;
6
+ export default jsbridge;
package/dist/index.js ADDED
@@ -0,0 +1,77 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ var _excluded = ["nativeMethod", "initialParams"];
3
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
7
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
8
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
9
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
10
+ import { isFunction, isObject, isString, isUndefined } from '@wapri/gbase';
11
+ import { JSBNative } from "./core";
12
+ import { getBridgeWindow } from "./utils";
13
+ import { apiRegistry } from "./registers";
14
+ export { BridgeError } from "./errors";
15
+ var EVENT_METHODS = new Set(['on', 'once', 'off']);
16
+ var INTERNAL_METHODS = new Set(['handle', 'ready', 'request', 'callNative', 'onNativeMessage', 'onNativeEvent', 'installNativeCallbacks', 'cb']);
17
+
18
+ /**
19
+ * 创建并缓存业务侧唯一的 Bridge 代理。
20
+ *
21
+ * 代理会将未注册的属性访问转换为 Native 方法调用,同时屏蔽底层通道与回调实现。
22
+ */
23
+ var createJSB = function createJSB() {
24
+ var bridgeWindow = getBridgeWindow();
25
+ if (!isUndefined(bridgeWindow === null || bridgeWindow === void 0 ? void 0 : bridgeWindow.__kaimaiJSBridge)) {
26
+ return bridgeWindow.__kaimaiJSBridge;
27
+ }
28
+ var nativeBridge = new JSBNative();
29
+ var bridge = new Proxy(nativeBridge, {
30
+ /** 根据属性名分发事件订阅、销毁方法或 Native 业务方法。 */get: function get(target, property) {
31
+ if (!isString(property)) {
32
+ return undefined;
33
+ }
34
+ if (EVENT_METHODS.has(property)) {
35
+ var eventMethod = Reflect.get(target.cb, property);
36
+ return isFunction(eventMethod) ? eventMethod.bind(target.cb) : undefined;
37
+ }
38
+ if (property === 'config') {
39
+ return target.config;
40
+ }
41
+ if (property === 'setDebug') {
42
+ return target.setDebug.bind(target);
43
+ }
44
+ if (property === 'destroy') {
45
+ return target.destroy.bind(target);
46
+ }
47
+ if (property === 'webReady') {
48
+ return target.webReady.bind(target);
49
+ }
50
+ if (property === 'then' || INTERNAL_METHODS.has(property)) {
51
+ return undefined;
52
+ }
53
+ return function () {
54
+ var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
55
+ if (!isObject(params)) {
56
+ return Promise.reject(new Error('jsbridge 参数必须是对象'));
57
+ }
58
+ var config = apiRegistry === null || apiRegistry === void 0 ? void 0 : apiRegistry[property];
59
+ var _ref = config || {},
60
+ nativeMethod = _ref.nativeMethod,
61
+ _ref$initialParams = _ref.initialParams,
62
+ initialParams = _ref$initialParams === void 0 ? {} : _ref$initialParams,
63
+ other = _objectWithoutProperties(_ref, _excluded);
64
+ var methodName = nativeMethod || property;
65
+ return target.callNative(methodName, _objectSpread(_objectSpread({}, initialParams), params), other);
66
+ };
67
+ }
68
+ });
69
+ if (!isUndefined(bridgeWindow)) {
70
+ bridgeWindow.__kaimaiJSBridge = bridge;
71
+ }
72
+ return bridge;
73
+ };
74
+
75
+ /** 业务侧唯一入口:使用 jsbridge.<具体 Native 方法名>(params)。 */
76
+ export var jsbridge = createJSB();
77
+ export default jsbridge;
@@ -0,0 +1,36 @@
1
+ <script lang="tsx">
2
+ import { defineComponent, ref } from 'vue'
3
+ import { jsbridge } from '@wapri/gjsbridge'
4
+
5
+ export default defineComponent({
6
+ setup(props) {
7
+ const result = ref('')
8
+ const errors = ref('')
9
+ const handleClick = () => {
10
+ jsbridge
11
+ .canIUse({ api: 'debug.demp' })
12
+ .then((res) => {
13
+ result.value = JSON.stringify(res)
14
+ })
15
+ .catch((error) => {
16
+ errors.value = error.message
17
+ })
18
+ }
19
+ return () => {
20
+ return (
21
+ <div>
22
+ <div>
23
+ <strong>result:</strong>
24
+ {result.value}
25
+ </div>
26
+ <div>
27
+ <strong>error:</strong>
28
+ {errors.value}
29
+ </div>
30
+ <button onClick={handleClick}>点击</button>
31
+ </div>
32
+ )
33
+ }
34
+ },
35
+ })
36
+ </script>
@@ -0,0 +1,12 @@
1
+ import type { BridgeRegister } from '../types/register';
2
+ /** 单个业务 Bridge 方法的 Native 调用配置。 */
3
+ export type BridgeApiConfig = {
4
+ /** Native 方法未响应时的超时,单位毫秒。 */
5
+ nativeMethod?: string;
6
+ timeout?: number;
7
+ initialParams?: Record<string, unknown>;
8
+ };
9
+ /**
10
+ * 对业务暴露api转换为调用原生的api
11
+ * */
12
+ export declare const apiRegistry: Partial<Record<keyof BridgeRegister, BridgeApiConfig>>;
@@ -0,0 +1,22 @@
1
+ /** 单个业务 Bridge 方法的 Native 调用配置。 */
2
+
3
+ /**
4
+ * 对业务暴露api转换为调用原生的api
5
+ * */
6
+ export var apiRegistry = {
7
+ canIUse: {
8
+ nativeMethod: 'permission.caniuse',
9
+ initialParams: {
10
+ userType: 'kaimai'
11
+ }
12
+ },
13
+ getSafeArea: {
14
+ nativeMethod: 'getSafeArea'
15
+ },
16
+ close: {
17
+ nativeMethod: 'closeWebview'
18
+ },
19
+ makePhoneCall: {
20
+ nativeMethod: 'makePhoneCall'
21
+ }
22
+ };
@@ -0,0 +1 @@
1
+ export type ApiKeys = 'debug.demp';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,41 @@
1
+ import { BridgeRegister } from './register';
2
+ export interface JSBridgeConfig {
3
+ /** 是否在控制台打印 JS 与 Native 通信的原始数据。 */
4
+ debug: boolean;
5
+ }
6
+ export interface NativeRequest<TParams = Record<string, unknown>> {
7
+ method: string;
8
+ params: TParams;
9
+ requestId: string;
10
+ }
11
+ export type NativeTransport = (request: NativeRequest) => void;
12
+ export interface NativeBridge {
13
+ handle?: (message: string) => void;
14
+ }
15
+ export interface IOSBridgeHandler {
16
+ postMessage?: (message: string) => void;
17
+ }
18
+ export type NativeEventListener<TData = unknown> = (data: TData) => void;
19
+ export interface PendingRequest {
20
+ reject: (reason: Error) => void;
21
+ resolve: (data: unknown) => void;
22
+ timer: number;
23
+ }
24
+ export interface JSBridge extends BridgeRegister {
25
+ config: JSBridgeConfig;
26
+ setDebug(debug: boolean): void;
27
+ on<TData = unknown>(eventName: string, listener: NativeEventListener<TData>): () => void;
28
+ once<TData = unknown>(eventName: string, listener: NativeEventListener<TData>): () => void;
29
+ off<TData = unknown>(eventName: string, listener: NativeEventListener<TData>): void;
30
+ webReady(): boolean;
31
+ destroy(): void;
32
+ }
33
+ export interface BridgeWindow extends Window {
34
+ KMBridge?: NativeBridge;
35
+ webkit?: {
36
+ messageHandlers?: Record<string, IOSBridgeHandler | undefined>;
37
+ };
38
+ onNativeMessage?: (message: string) => void;
39
+ onNativeEvent?: (eventName: string, data: unknown) => void;
40
+ __kaimaiJSBridge?: JSBridge;
41
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ import { ApiKeys } from './apis';
2
+ interface BridgeMethod<P, R> {
3
+ params: P;
4
+ reponse: R;
5
+ entity: P extends undefined ? () => Promise<R> : (args: P) => Promise<R>;
6
+ }
7
+ type BridgeMethodCanIUse = BridgeMethod<{
8
+ /** api名称 */
9
+ api: ApiKeys;
10
+ }, {
11
+ /** 0 失败 1 成功 */
12
+ result: '0' | '1';
13
+ }>;
14
+ type SafeAreaInfo = Record<'safeAreaTop' | 'safeAreaBottom' | 'safeAreaLeft' | 'safeAreaRight', number>;
15
+ type BridgeMethodGetSafeArea = BridgeMethod<undefined, SafeAreaInfo>;
16
+ export interface BridgeRegister {
17
+ canIUse: BridgeMethodCanIUse['entity'];
18
+ getSafeArea: BridgeMethodGetSafeArea['entity'];
19
+ close: BridgeMethod<undefined, undefined>['entity'];
20
+ makePhoneCall: BridgeMethod<{
21
+ phoneNumber: string;
22
+ }, undefined>['entity'];
23
+ }
24
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { BridgeWindow } from '../types/bridge';
2
+ /** 获取当前浏览器环境的 window;非浏览器环境返回 undefined。 */
3
+ export declare function getBridgeWindow(): BridgeWindow | undefined;
@@ -0,0 +1,6 @@
1
+ import { isUndefined } from '@wapri/gbase';
2
+ /** 获取当前浏览器环境的 window;非浏览器环境返回 undefined。 */
3
+ export function getBridgeWindow() {
4
+ var bridgeWindow = globalThis.window;
5
+ return isUndefined(bridgeWindow) ? undefined : bridgeWindow;
6
+ }
package/package.json CHANGED
@@ -1,6 +1,45 @@
1
1
  {
2
2
  "name": "@wapri/gjsbridge",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "3.0.0",
4
+ "description": "麦仓 App WebView JSBridge",
5
+ "keywords": [
6
+ "jsbridge",
7
+ "ios",
8
+ "android",
9
+ "harmonyos"
10
+ ],
11
+ "license": "UNLICENSED",
12
+ "author": "wa",
13
+ "sideEffects": true,
14
+ "type": "module",
15
+ "module": "dist/index.js",
16
+ "types": "dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js",
21
+ "default": "./dist/index.js"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "dependencies": {
28
+ "@wapri/gbase": "^1.0.0"
29
+ },
30
+ "devDependencies": {
31
+ "@wapri/gbase": "^1.0.0"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public",
35
+ "registry": "https://registry.npmjs.org/"
36
+ },
37
+ "peerDependenciesMeta": {},
38
+ "peerDependencies": {
39
+ "@wapri/gbase": "*"
40
+ },
41
+ "scripts": {
42
+ "build": "father build",
43
+ "dev": "father dev"
44
+ }
6
45
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.