@hylid/call 3.1.2 → 3.2.0-alpha.1

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,3 @@
1
+ import { Message, MessageHandler } from './types';
2
+ export declare function mpWebOnMessage(cb: MessageHandler): () => void;
3
+ export declare function mpWebPostMessage(message: Message): void;
@@ -0,0 +1,75 @@
1
+ var __rest = this && this.__rest || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
4
+ if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
5
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
6
+ }
7
+ return t;
8
+ };
9
+ /** 加载 appx 脚本 */
10
+ var loadAppxBridge = function loadAppxBridge(cb) {
11
+ var _a;
12
+ try {
13
+ // umd 包用的 IFF 模式,会立即向 window.my 上注入 jsapi,所以不能使用 window.my 判断是否已经加载了 appx 脚本
14
+ // umd 版本和 modules 版本不能混用
15
+ if ((_a = window.my) === null || _a === void 0 ? void 0 : _a.__hy_mounted__) {
16
+ cb && cb("ready" /* BridgeReady.READY */);
17
+ return;
18
+ }
19
+ var hyMy_1 = window.my || {};
20
+ var script_1 = document.createElement('script');
21
+ script_1.src = 'https://appx/web-view.min.js';
22
+ script_1.onload = function onload() {
23
+ var readyState = script_1['readyState'];
24
+ if (typeof readyState === 'undefined' || /^(loaded|complete)$/.test(readyState)) {
25
+ script_1.onload = null;
26
+ // appx 脚本覆盖了 window 的 my 属性,这里再把 hylid-bridge 的 API 挂上去
27
+ var postMessage_1 = hyMy_1.postMessage,
28
+ api = __rest(hyMy_1, ["postMessage"]);
29
+ Object.assign(window.my, api, {
30
+ __hy_mounted__: true
31
+ });
32
+ cb && cb("loaded" /* BridgeReady.LOADED */);
33
+ }
34
+ };
35
+ var head = document.getElementsByTagName('head')[0] || document.body;
36
+ head.appendChild(script_1);
37
+ } catch (e) {
38
+ cb && cb(null);
39
+ }
40
+ };
41
+ var isListening = false;
42
+ var WAITING_QUEUE = [];
43
+ var MESSAGE_HANDLER = [];
44
+ export function mpWebOnMessage(cb) {
45
+ MESSAGE_HANDLER.push(cb);
46
+ return function () {
47
+ var index = MESSAGE_HANDLER.indexOf(cb);
48
+ if (index > -1) {
49
+ MESSAGE_HANDLER.splice(index, 1);
50
+ }
51
+ };
52
+ }
53
+ export function mpWebPostMessage(message) {
54
+ return loadAppxBridge(function (bridgeReady) {
55
+ if (bridgeReady) {
56
+ if (!isListening) {
57
+ var messageHandler_1 = window.my.onMessage;
58
+ window.my.onMessage = function (message) {
59
+ MESSAGE_HANDLER.forEach(function (fn) {
60
+ return fn(message);
61
+ });
62
+ if (messageHandler_1) messageHandler_1(message);
63
+ };
64
+ isListening = true;
65
+ }
66
+ if (WAITING_QUEUE.length) {
67
+ WAITING_QUEUE.forEach(window.my.postMessage);
68
+ WAITING_QUEUE = [];
69
+ }
70
+ window.my.postMessage(message);
71
+ } else {
72
+ WAITING_QUEUE.push(message);
73
+ }
74
+ });
75
+ }
@@ -1,5 +1,11 @@
1
- import { PickMPArgs, PickMpReturns, MPApi } from '@hylid/types';
2
- import { MpWebJsApiConfig } from './types';
3
- declare type Callback<T> = (result?: T) => void;
4
- export declare const mpWebCall: <T extends keyof MPApi>(api: ({} & string) | T, options?: PickMPArgs<T> | Callback<ReturnType<MPApi[T]>> | undefined, config?: MpWebJsApiConfig) => void;
5
- export {};
1
+ import { MPApi } from '@hylid/types';
2
+ import { MpWebJsApiConfig, MpWebJsApiOptions } from './types';
3
+ import { mpWebOnMessage, mpWebPostMessage } from './mpWebBridge';
4
+ export declare function mpWebCall<T extends keyof MPApi>(api: T | ({} & string), options?: MpWebJsApiOptions<T>, config?: MpWebJsApiConfig): void;
5
+ export declare namespace mpWebCall {
6
+ var onMessage: typeof mpWebOnMessage;
7
+ var postMessage: typeof mpWebPostMessage;
8
+ var broadcastGlobalData: (key: string, payload: any) => void;
9
+ var onReceiveGlobalData: (key: string, callback: (data: any, form: string) => void) => () => void;
10
+ var onPageEvent: (event: ({} & string) | "onShow" | "onHide" | "onTitleClick" | "onOptionMenuClick" | "onTabItemTap", callback: (data: any) => void) => () => void;
11
+ }
package/lib/mpWebCall.js CHANGED
@@ -1,119 +1,100 @@
1
- var loadAppxBridge = function loadAppxBridge(cb) {
1
+ import { mpWebOnMessage, mpWebPostMessage } from "./mpWebBridge";
2
+ // 关联 postMessage 和 onMessage,根据 serialId 执行回调
3
+ var callMap = {};
4
+ // 注册 jsapi 的 message 处理器
5
+ mpWebOnMessage(function (msg) {
2
6
  var _a;
3
- try {
4
- // umd 包用的 IFF 模式,会立即向 window.my 上注入 jsapi,所以不能使用 window.my 判断是否已经加载了 appx 脚本
5
- // umd 版本和 modules 版本不能混用
6
- if ((_a = window.my) === null || _a === void 0 ? void 0 : _a.__hy_mounted__) {
7
- cb && cb("ready" /* BridgeReady.READY */);
8
- return;
9
- }
10
- var hyMy_1 = window.my || {};
11
- var script_1 = document.createElement('script');
12
- script_1.src = 'https://appx/web-view.min.js';
13
- script_1.onload = function onload() {
14
- var readyState = script_1['readyState'];
15
- if (typeof readyState === 'undefined' || /^(loaded|complete)$/.test(readyState)) {
16
- script_1.onload = null;
17
- Object.assign(window.my, hyMy_1, {
18
- __hy_mounted__: true
19
- });
20
- cb && cb("loaded" /* BridgeReady.LOADED */);
21
- }
22
- };
23
-
24
- var head = document.getElementsByTagName('head')[0] || document.body;
25
- head.appendChild(script_1);
26
- } catch (e) {
27
- cb && cb(null);
28
- }
29
- };
30
- var callbackFn = function callbackFn(res, callback) {
31
- var _a = callback || {},
32
- success = _a.success,
33
- fail = _a.fail,
34
- complete = _a.complete;
35
- var _b = res || {},
36
- _data_ = _b._data_,
37
- _type_ = _b._type_;
7
+ var message = msg;
8
+ var serialId = message.serialId;
9
+ // 不是 jsapi 的调用的消息
10
+ if (message.type !== 'apiCall') return;
11
+ if (!serialId) return;
12
+ if (!callMap[serialId]) return;
13
+ var callback = callMap[serialId];
14
+ var data = message.result;
15
+ var type = (_a = message.config) === null || _a === void 0 ? void 0 : _a.type; // JsApi 的类型
16
+ if (type === 'callback') return callback(data);
17
+ var _b = callback || {},
18
+ success = _b.success,
19
+ fail = _b.fail,
20
+ complete = _b.complete;
21
+ var _c = data || {},
22
+ _data_ = _c._data_,
23
+ _type_ = _c._type_;
38
24
  // 新版本协议
39
25
  if (_type_) {
40
26
  if (_type_ === 'success') success === null || success === void 0 ? void 0 : success(_data_);
41
27
  if (_type_ === 'fail') fail === null || fail === void 0 ? void 0 : fail(_data_);
42
- return complete === null || complete === void 0 ? void 0 : complete(_data_);
43
- }
44
- // 下面兼容老版本(老版本消息识别不明确,导致 H5 中走 success/fail 逻辑可能岔了)
45
- // @ts-ignore
46
- if (res === null || res === void 0 ? void 0 : res.error) {
47
- fail === null || fail === void 0 ? void 0 : fail(res);
28
+ complete === null || complete === void 0 ? void 0 : complete(_data_);
48
29
  } else {
49
- success === null || success === void 0 ? void 0 : success(res);
30
+ // 下面兼容老版本(老版本消息识别不明确,导致 H5 中走 success/fail 逻辑可能岔了)
31
+ // @ts-ignore
32
+ if (data === null || data === void 0 ? void 0 : data.error) {
33
+ fail === null || fail === void 0 ? void 0 : fail(data);
34
+ } else {
35
+ success === null || success === void 0 ? void 0 : success(data);
36
+ }
37
+ complete === null || complete === void 0 ? void 0 : complete(data);
50
38
  }
51
- complete === null || complete === void 0 ? void 0 : complete(res);
52
- };
53
- export var mpWebCall = function () {
54
- var callMap = {};
55
- var WAITING_QUEUE = [];
56
- var isListening = false;
57
- function onMessage() {
58
- var messageHandler = window.my.onMessage;
59
- window.my.onMessage = function (message) {
60
- var _a;
61
- var serialId = message.serialId;
62
- var data = message.result;
63
- var type = (_a = message.config) === null || _a === void 0 ? void 0 : _a.type; // JsApi 的类型
64
- if (serialId) {
65
- var callback = callMap[serialId];
66
- if (!callback) return;
67
- if (type === 'callback') {
68
- callback(data);
69
- } else {
70
- callbackFn(data, callback);
71
- delete callMap[serialId];
72
- }
73
- } else if (messageHandler) {
74
- messageHandler(message);
75
- }
76
- };
39
+ delete callMap[serialId];
40
+ });
41
+ export function mpWebCall(api, options, config) {
42
+ var random = Math.floor(Math.random() * 1000000);
43
+ var serialId = api + '_' + random;
44
+ // 只调用,没有参数,不需要接收 jsapi 执行结果
45
+ if (options) {
46
+ callMap[serialId] = options;
77
47
  }
78
- function fireMessage(_a) {
79
- var api = _a.api,
80
- options = _a.options,
81
- config = _a.config;
82
- var random = Math.floor(Math.random() * 1000000);
83
- var serialId = api + '_' + random;
84
- if (options) {
85
- callMap[serialId] = options;
48
+ var message = {
49
+ source: 'hylid',
50
+ type: 'apiCall',
51
+ api: api,
52
+ serialId: serialId,
53
+ options: options,
54
+ config: config
55
+ };
56
+ mpWebPostMessage(message);
57
+ }
58
+ function broadcastGlobalData(key, payload) {
59
+ var message = {
60
+ source: 'hylid',
61
+ type: 'broadcast',
62
+ from: window.location.href,
63
+ result: {
64
+ key: key,
65
+ payload: payload
86
66
  }
87
- var params = {
88
- source: 'hylid',
89
- type: 'apiCall',
90
- api: api,
91
- serialId: serialId,
92
- options: options,
93
- config: config
94
- };
95
- window.my.postMessage(params);
96
- }
97
- return function call(api, options, config) {
98
- loadAppxBridge(function (bridgeReady) {
99
- var params = {
100
- api: api,
101
- options: options,
102
- config: config
103
- };
104
- if (bridgeReady) {
105
- if (!isListening) {
106
- onMessage();
107
- isListening = true;
108
- }
109
- if (WAITING_QUEUE.length) {
110
- WAITING_QUEUE.forEach(fireMessage);
111
- WAITING_QUEUE = [];
112
- }
113
- fireMessage(params);
114
- } else {
115
- WAITING_QUEUE.push(params);
116
- }
117
- });
118
67
  };
119
- }();
68
+ mpWebPostMessage(message);
69
+ }
70
+ function onReceiveGlobalData(key, callback) {
71
+ return mpWebOnMessage(function (msg) {
72
+ var _a, _b;
73
+ var message = msg;
74
+ if (message.source !== 'hylid') return;
75
+ if (message.type !== 'broadcast') return;
76
+ // 不是接收的目标消息
77
+ if (((_a = message.result) === null || _a === void 0 ? void 0 : _a.key) !== key) return;
78
+ callback((_b = message.result) === null || _b === void 0 ? void 0 : _b.payload, message.from);
79
+ });
80
+ }
81
+ function onPageEvent(event, callback) {
82
+ // 告诉小程序侧,监听 event 事件
83
+ mpWebPostMessage({
84
+ source: 'hylid',
85
+ type: 'pageEvent',
86
+ event: event
87
+ });
88
+ return mpWebOnMessage(function (msg) {
89
+ var message = msg;
90
+ if (message.source !== 'hylid') return;
91
+ if (message.type !== 'pageEvent') return;
92
+ if (message.event !== event) return;
93
+ callback(message.result);
94
+ });
95
+ }
96
+ mpWebCall.onMessage = mpWebOnMessage;
97
+ mpWebCall.postMessage = mpWebPostMessage;
98
+ mpWebCall.broadcastGlobalData = broadcastGlobalData;
99
+ mpWebCall.onReceiveGlobalData = onReceiveGlobalData;
100
+ mpWebCall.onPageEvent = onPageEvent;
package/lib/types.d.ts CHANGED
@@ -1,20 +1,39 @@
1
- import { JsApiType, MPApi } from '@hylid/types';
1
+ import { JsApiType, MPApi, PickMPArgs, PickMpReturns } from '@hylid/types';
2
2
  export declare type JsApi = keyof MPApi;
3
3
  export interface MpWebJsApiConfig {
4
4
  type?: JsApiType;
5
5
  }
6
6
  export declare type Config = MpWebJsApiConfig;
7
- export interface MpWebMessageResult {
7
+ export interface MpWebJsApiMessageResult {
8
8
  _type_: 'success' | 'fail';
9
9
  _data_: any;
10
10
  }
11
- export interface MpWebMessage {
11
+ export interface MpWebJsApiMessage {
12
12
  source: 'hylid';
13
13
  type: 'apiCall';
14
14
  api: string;
15
15
  serialId: string;
16
16
  options: any;
17
17
  config?: MpWebJsApiConfig;
18
- result?: MpWebMessageResult;
18
+ result?: MpWebJsApiMessageResult;
19
19
  }
20
- export declare type JsApiInfo = Pick<MpWebMessage, 'api' | 'options' | 'config'>;
20
+ export interface MpWebBroadcastMessage {
21
+ source: 'hylid';
22
+ type: 'broadcast';
23
+ from: string;
24
+ result?: {
25
+ key: string;
26
+ payload: any;
27
+ };
28
+ }
29
+ export interface MpWebPageEventMessage {
30
+ source: 'hylid';
31
+ type: 'pageEvent';
32
+ event: 'onShow' | 'onHide' | 'onTitleClick' | 'onOptionMenuClick' | 'onTabItemTap' | ({} & string);
33
+ result?: any;
34
+ }
35
+ export declare type Message = MpWebJsApiMessage | MpWebBroadcastMessage | MpWebPageEventMessage;
36
+ export declare type MessageHandler = (message: Message) => void;
37
+ declare type Callback<T> = (result?: T) => void;
38
+ export declare type MpWebJsApiOptions<T extends keyof MPApi> = PickMPArgs<T> | Callback<PickMpReturns<T>>;
39
+ export {};
@@ -1,8 +1,11 @@
1
1
  /// <reference types="miniprogram" />
2
- import { MpWebMessage } from './types';
2
+ import { Message, MessageHandler, MpWebBroadcastMessage, MpWebJsApiMessage, MpWebPageEventMessage } from './types';
3
3
  interface Config {
4
+ /** 允许调用 jsApi 的白名单 */
4
5
  whitelist?: string[];
6
+ /** 禁止调用 jsApi 的黑名单 */
5
7
  blacklist?: string[];
8
+ /** 自定义 jsApi [ 优先级比较高,可以覆盖原生的 jsApi ] */
6
9
  customApi?: CustomApi;
7
10
  }
8
11
  interface CustomApi {
@@ -14,11 +17,22 @@ interface CustomApi {
14
17
  export declare class WebViewBridge {
15
18
  webview: WebViewContext;
16
19
  config: Config;
17
- constructor(ctx: WebViewContext, config?: Config);
20
+ context: any;
21
+ MESSAGE_HANDLER: MessageHandler[];
22
+ /**
23
+ *
24
+ * @param webviewId webview 组件的 id,可传字符串,或者 my.createWebViewContext 创建出的实例
25
+ * @param config Config 配置
26
+ * @param context 页面上下文,传 this 即可。传入后,H5 侧可以使用广播、可以监听页面事件
27
+ */
28
+ constructor(webviewId: string | WebViewContext, config?: Config, context?: any);
18
29
  listen: (data: {
19
- detail: MpWebMessage;
20
- }) => Promise<true | undefined>;
30
+ detail: Message;
31
+ }) => void;
21
32
  isAllowed(api: string): boolean;
22
- handleApi: (data: MpWebMessage) => Promise<unknown>;
33
+ jsApiHandler: (command: MpWebJsApiMessage) => void;
34
+ broadcastHandler: (data: MpWebBroadcastMessage) => void;
35
+ pageEventHandler: (data: MpWebPageEventMessage) => void;
36
+ bindCtxEvent(event: string, callback: (...rest: any) => void): void;
23
37
  }
24
38
  export {};
@@ -8,224 +8,169 @@ var __assign = this && this.__assign || function () {
8
8
  };
9
9
  return __assign.apply(this, arguments);
10
10
  };
11
- var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) {
12
- function adopt(value) {
13
- return value instanceof P ? value : new P(function (resolve) {
14
- resolve(value);
15
- });
16
- }
17
- return new (P || (P = Promise))(function (resolve, reject) {
18
- function fulfilled(value) {
19
- try {
20
- step(generator.next(value));
21
- } catch (e) {
22
- reject(e);
23
- }
24
- }
25
- function rejected(value) {
26
- try {
27
- step(generator["throw"](value));
28
- } catch (e) {
29
- reject(e);
30
- }
31
- }
32
- function step(result) {
33
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
34
- }
35
- step((generator = generator.apply(thisArg, _arguments || [])).next());
36
- });
37
- };
38
- var __generator = this && this.__generator || function (thisArg, body) {
39
- var _ = {
40
- label: 0,
41
- sent: function sent() {
42
- if (t[0] & 1) throw t[1];
43
- return t[1];
44
- },
45
- trys: [],
46
- ops: []
47
- },
48
- f,
49
- y,
50
- t,
51
- g;
52
- return g = {
53
- next: verb(0),
54
- "throw": verb(1),
55
- "return": verb(2)
56
- }, typeof Symbol === "function" && (g[Symbol.iterator] = function () {
57
- return this;
58
- }), g;
59
- function verb(n) {
60
- return function (v) {
61
- return step([n, v]);
62
- };
63
- }
64
- function step(op) {
65
- if (f) throw new TypeError("Generator is already executing.");
66
- while (_) try {
67
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
68
- if (y = 0, t) op = [op[0] & 2, t.value];
69
- switch (op[0]) {
70
- case 0:
71
- case 1:
72
- t = op;
73
- break;
74
- case 4:
75
- _.label++;
76
- return {
77
- value: op[1],
78
- done: false
79
- };
80
- case 5:
81
- _.label++;
82
- y = op[1];
83
- op = [0];
84
- continue;
85
- case 7:
86
- op = _.ops.pop();
87
- _.trys.pop();
88
- continue;
89
- default:
90
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
91
- _ = 0;
92
- continue;
93
- }
94
- if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
95
- _.label = op[1];
96
- break;
97
- }
98
- if (op[0] === 6 && _.label < t[1]) {
99
- _.label = t[1];
100
- t = op;
101
- break;
102
- }
103
- if (t && _.label < t[2]) {
104
- _.label = t[2];
105
- _.ops.push(op);
106
- break;
107
- }
108
- if (t[2]) _.ops.pop();
109
- _.trys.pop();
110
- continue;
111
- }
112
- op = body.call(thisArg, _);
113
- } catch (e) {
114
- op = [6, e];
115
- y = 0;
116
- } finally {
117
- f = t = 0;
118
- }
119
- if (op[0] & 5) throw op[1];
120
- return {
121
- value: op[0] ? op[1] : void 0,
122
- done: true
123
- };
124
- }
125
- };
11
+ var broadcastTargets = [];
126
12
  var WebViewBridge = /** @class */function () {
127
- function WebViewBridge(ctx, config) {
13
+ /**
14
+ *
15
+ * @param webviewId webview 组件的 id,可传字符串,或者 my.createWebViewContext 创建出的实例
16
+ * @param config Config 配置
17
+ * @param context 页面上下文,传 this 即可。传入后,H5 侧可以使用广播、可以监听页面事件
18
+ */
19
+ function WebViewBridge(webviewId, config, context) {
128
20
  if (config === void 0) {
129
21
  config = {};
130
22
  }
131
23
  var _this = this;
132
24
  this.config = {};
25
+ this.MESSAGE_HANDLER = [];
133
26
  this.listen = function (data) {
134
- return __awaiter(_this, void 0, void 0, function () {
135
- var command, config, api, type, notAllowedMessage;
136
- var _this = this;
137
- return __generator(this, function (_a) {
138
- command = data.detail;
139
- if (command.source === 'hylid') {
140
- config = command.config, api = command.api;
141
- type = (config || {}).type;
142
- // 权限管控不允许调用 JSAPI
143
- if (!this.isAllowed(api)) {
144
- notAllowedMessage = __assign(__assign({}, command), {
145
- result: {
146
- _type_: 'fail',
147
- _data_: {
148
- errorCode: -2,
149
- errorMessage: 'api is not allowed'
150
- }
151
- }
27
+ if (data.detail.source !== 'hylid') return;
28
+ _this.MESSAGE_HANDLER.forEach(function (fn) {
29
+ return fn(data.detail);
30
+ });
31
+ };
32
+ this.jsApiHandler = function (command) {
33
+ if (command.type !== 'apiCall') return;
34
+ var getApiResult = function getApiResult(data) {
35
+ var api = data.api,
36
+ _options = data.options,
37
+ config = data.config;
38
+ var _a = (config || {}).type,
39
+ type = _a === void 0 ? 'async' : _a;
40
+ return new Promise(function (resolve) {
41
+ var _a;
42
+ var options = __assign(__assign({}, _options), {
43
+ success: function success(res) {
44
+ resolve({
45
+ _type_: 'success',
46
+ _data_: res
47
+ });
48
+ },
49
+ fail: function fail(res) {
50
+ resolve({
51
+ _type_: 'fail',
52
+ _data_: res
152
53
  });
153
- this.webview.postMessage(notAllowedMessage);
154
- return [2 /*return*/];
155
54
  }
156
-
157
- if (type === 'callback') {
55
+ });
56
+ // @ts-ignore
57
+ var mpApi = ((_a = _this.config.customApi) === null || _a === void 0 ? void 0 : _a[api]) || my[api];
58
+ if (type === 'sync') {
59
+ var data_1 = mpApi(_options);
60
+ resolve({
61
+ _type_: 'success',
62
+ _data_: data_1
63
+ });
64
+ }
65
+ if (type === 'async') {
66
+ if (!mpApi) {
158
67
  // @ts-ignore
159
- my[api](function (result) {
160
- _this.webview.postMessage(__assign(__assign({}, command), {
161
- result: result
162
- }));
163
- });
68
+ my.call(api, options);
164
69
  } else {
165
- this.handleApi(command).then(function (result) {
166
- _this.webview.postMessage(__assign(__assign({}, command), {
167
- result: result
168
- }));
169
- });
70
+ mpApi(options);
170
71
  }
171
- // 表示被 hylid-bridge 消费了
172
- return [2 /*return*/, true];
173
72
  }
174
- return [2 /*return*/];
175
73
  });
176
- });
177
- };
178
-
179
- this.handleApi = function (data) {
180
- var api = data.api,
181
- _options = data.options,
182
- config = data.config;
183
- var _a = (config || {}).type,
184
- type = _a === void 0 ? 'async' : _a;
185
- return new Promise(function (resolve) {
186
- var _a;
187
- var options = __assign(__assign({}, _options), {
188
- success: function success(res) {
189
- resolve({
190
- _type_: 'success',
191
- _data_: res
192
- });
193
- },
194
- fail: function fail(res) {
195
- resolve({
196
- _type_: 'fail',
197
- _data_: res
198
- });
74
+ };
75
+ var config = command.config,
76
+ api = command.api;
77
+ var type = (config || {}).type;
78
+ // 权限管控不允许调用 JSAPI
79
+ if (!_this.isAllowed(api)) {
80
+ var notAllowedMessage = __assign(__assign({}, command), {
81
+ result: {
82
+ _type_: 'fail',
83
+ _data_: {
84
+ errorCode: -2,
85
+ errorMessage: 'api is not allowed'
86
+ }
199
87
  }
200
88
  });
89
+ _this.webview.postMessage(notAllowedMessage);
90
+ return;
91
+ }
92
+ if (type === 'callback') {
201
93
  // @ts-ignore
202
- var mpApi = ((_a = _this.config.customApi) === null || _a === void 0 ? void 0 : _a[api]) || my[api];
203
- if (type === 'sync') {
204
- var data_1 = mpApi(_options);
205
- resolve({
206
- _type_: 'success',
207
- _data_: data_1
208
- });
209
- }
210
- if (type === 'async') {
211
- if (!mpApi) {
212
- // @ts-ignore
213
- my.call(api, options);
214
- } else {
215
- mpApi(options);
216
- }
217
- }
94
+ my[api](function (result) {
95
+ _this.webview.postMessage(__assign(__assign({}, command), {
96
+ result: result
97
+ }));
98
+ });
99
+ } else {
100
+ getApiResult(command).then(function (result) {
101
+ _this.webview.postMessage(__assign(__assign({}, command), {
102
+ result: result
103
+ }));
104
+ });
105
+ }
106
+ };
107
+ this.broadcastHandler = function (data) {
108
+ if (data.type !== 'broadcast') return;
109
+ broadcastTargets.forEach(function (target) {
110
+ if (target === _this) return;
111
+ target.webview.postMessage(data);
112
+ });
113
+ };
114
+ this.pageEventHandler = function (data) {
115
+ var _a;
116
+ if (data.type !== 'pageEvent') return;
117
+ var event = data.event;
118
+ if (!event) return;
119
+ if (!_this.context) {
120
+ console.info("[hylid-call]: context \u5728\u5C0F\u7A0B\u5E8F\u4FA7\u672A\u4F20\u5165\uFF0C".concat(event, " \u76D1\u542C\u5931\u8D25"));
121
+ return;
122
+ }
123
+ // 已经监听过了
124
+ if ((_a = _this.context[event]) === null || _a === void 0 ? void 0 : _a._hy_listener_) return;
125
+ _this.bindCtxEvent(event, function (payload) {
126
+ _this.webview.postMessage(__assign(__assign({}, data), {
127
+ result: payload
128
+ }));
218
129
  });
130
+ _this.context[event]._hy_listener_ = true;
219
131
  };
220
- this.webview = ctx;
132
+ if (typeof webviewId === 'string') {
133
+ this.webview = my.createWebViewContext(webviewId);
134
+ } else {
135
+ this.webview = webviewId;
136
+ }
221
137
  this.config = config;
138
+ this.context = context;
139
+ this.MESSAGE_HANDLER.push(this.jsApiHandler);
140
+ this.MESSAGE_HANDLER.push(this.broadcastHandler);
141
+ this.MESSAGE_HANDLER.push(this.pageEventHandler);
142
+ if (context) {
143
+ broadcastTargets.push(this);
144
+ this.bindCtxEvent('onUnload', function () {
145
+ broadcastTargets = broadcastTargets.filter(function (target) {
146
+ return target !== _this;
147
+ });
148
+ });
149
+ } else {
150
+ console.info("[hylid-call]: context \u5728\u5C0F\u7A0B\u5E8F\u4FA7\u672A\u4F20\u5165\uFF0Cbroadcast \u529F\u80FD\u3001\u9875\u9762\u76D1\u542C\u5C06\u65E0\u6CD5\u4F7F\u7528");
151
+ }
222
152
  }
223
153
  WebViewBridge.prototype.isAllowed = function (api) {
154
+ var _a = this.config || {},
155
+ whitelist = _a.whitelist,
156
+ blacklist = _a.blacklist;
224
157
  // 黑白名单校验
225
- if (this.config.whitelist && !this.config.whitelist.includes(api)) return false;
226
- if (this.config.blacklist && this.config.blacklist.includes(api)) return false;
158
+ if (whitelist && !whitelist.includes(api)) return false;
159
+ if (blacklist && blacklist.includes(api)) return false;
227
160
  return true;
228
161
  };
162
+ WebViewBridge.prototype.bindCtxEvent = function (event, callback) {
163
+ if (!this.context) return;
164
+ var userEvent = this.context[event];
165
+ this.context[event] = function () {
166
+ var rest = [];
167
+ for (var _i = 0; _i < arguments.length; _i++) {
168
+ rest[_i] = arguments[_i];
169
+ }
170
+ if (userEvent) userEvent.apply(void 0, rest);
171
+ callback.apply(void 0, rest);
172
+ }.bind(this.context);
173
+ };
229
174
  return WebViewBridge;
230
175
  }();
231
176
  export { WebViewBridge };
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@hylid/call",
3
- "version": "3.1.2",
3
+ "version": "3.2.0-alpha.1",
4
4
  "main": "lib/index.js",
5
5
  "files": [
6
6
  "lib"
7
7
  ],
8
8
  "dependencies": {
9
- "@hylid/env": "^3.1.2",
10
- "@hylid/types": "^3.1.2"
9
+ "@hylid/env": "^3.2.0-alpha.1",
10
+ "@hylid/types": "^3.2.0-alpha.1"
11
11
  },
12
12
  "publishConfig": {
13
13
  "access": "public"