@hylid/call 3.2.0-alpha.1 → 3.2.0-alpha.4

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.
@@ -44,10 +44,9 @@ var MESSAGE_HANDLER = [];
44
44
  export function mpWebOnMessage(cb) {
45
45
  MESSAGE_HANDLER.push(cb);
46
46
  return function () {
47
- var index = MESSAGE_HANDLER.indexOf(cb);
48
- if (index > -1) {
49
- MESSAGE_HANDLER.splice(index, 1);
50
- }
47
+ MESSAGE_HANDLER = MESSAGE_HANDLER.filter(function (o) {
48
+ return o !== cb;
49
+ });
51
50
  };
52
51
  }
53
52
  export function mpWebPostMessage(message) {
@@ -5,7 +5,7 @@ export declare function mpWebCall<T extends keyof MPApi>(api: T | ({} & string),
5
5
  export declare namespace mpWebCall {
6
6
  var onMessage: typeof mpWebOnMessage;
7
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;
8
+ var broadcastGlobalData: (key: string, result: any) => void;
9
+ var onReceiveGlobalData: (key: string, callback: (data: any, error: any, form: string) => void) => () => void;
10
+ var onPageEvent: (event: ({} & string) | "onShow" | "onHide" | "onTitleClick" | "onOptionMenuClick" | "onTabItemTap", callback: (data: any, err?: any) => void) => () => void;
11
11
  }
package/lib/mpWebCall.js CHANGED
@@ -7,20 +7,26 @@ mpWebOnMessage(function (msg) {
7
7
  var message = msg;
8
8
  var serialId = message.serialId;
9
9
  // 不是 jsapi 的调用的消息
10
- if (message.type !== 'apiCall') return;
10
+ if (message.type && message.type !== 'apiCall') return;
11
11
  if (!serialId) return;
12
12
  if (!callMap[serialId]) return;
13
13
  var callback = callMap[serialId];
14
14
  var data = message.result;
15
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_;
16
+ if (type === 'callback') {
17
+ var _b = data || {},
18
+ _data_1 = _b._data_,
19
+ _type_1 = _b._type_;
20
+ if (_type_1 === 'success') return callback(_data_1);
21
+ return callback(undefined, _data_1);
22
+ }
23
+ var _c = callback || {},
24
+ success = _c.success,
25
+ fail = _c.fail,
26
+ complete = _c.complete;
27
+ var _d = data || {},
28
+ _data_ = _d._data_,
29
+ _type_ = _d._type_;
24
30
  // 新版本协议
25
31
  if (_type_) {
26
32
  if (_type_ === 'success') success === null || success === void 0 ? void 0 : success(_data_);
@@ -55,27 +61,28 @@ export function mpWebCall(api, options, config) {
55
61
  };
56
62
  mpWebPostMessage(message);
57
63
  }
58
- function broadcastGlobalData(key, payload) {
64
+ function broadcastGlobalData(key, result) {
59
65
  var message = {
60
66
  source: 'hylid',
61
67
  type: 'broadcast',
62
68
  from: window.location.href,
63
- result: {
64
- key: key,
65
- payload: payload
66
- }
69
+ key: key,
70
+ result: result
67
71
  };
68
72
  mpWebPostMessage(message);
69
73
  }
70
74
  function onReceiveGlobalData(key, callback) {
71
75
  return mpWebOnMessage(function (msg) {
72
- var _a, _b;
73
76
  var message = msg;
74
77
  if (message.source !== 'hylid') return;
75
78
  if (message.type !== 'broadcast') return;
76
79
  // 不是接收的目标消息
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);
80
+ if (message.key !== key) return;
81
+ var _a = message.result || {},
82
+ _data_ = _a._data_,
83
+ _type_ = _a._type_;
84
+ if (_type_ === 'success') return callback(_data_, undefined, message.from);
85
+ return callback(undefined, _data_, message.from);
79
86
  });
80
87
  }
81
88
  function onPageEvent(event, callback) {
@@ -90,7 +97,11 @@ function onPageEvent(event, callback) {
90
97
  if (message.source !== 'hylid') return;
91
98
  if (message.type !== 'pageEvent') return;
92
99
  if (message.event !== event) return;
93
- callback(message.result);
100
+ var _a = message.result || {},
101
+ _data_ = _a._data_,
102
+ _type_ = _a._type_;
103
+ if (_type_ === 'success') return callback(_data_);
104
+ return callback(undefined, _data_);
94
105
  });
95
106
  }
96
107
  mpWebCall.onMessage = mpWebOnMessage;
package/lib/notFound.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createError } from "./utils";
1
2
  export var notFound = function notFound(name, opt, config) {
2
3
  var _a;
3
4
  if (config === void 0) {
@@ -5,10 +6,7 @@ export var notFound = function notFound(name, opt, config) {
5
6
  }
6
7
  var _b = config.type,
7
8
  type = _b === void 0 ? 'async' : _b;
8
- var response = {
9
- error: -1,
10
- errorMessage: "".concat(name, " is not found")
11
- };
9
+ var response = createError('NOTFOUND', name);
12
10
  if (type === 'sync') return response;
13
11
  if (type === 'callback') {
14
12
  opt === null || opt === void 0 ? void 0 : opt(response);
package/lib/types.d.ts CHANGED
@@ -4,9 +4,9 @@ export interface MpWebJsApiConfig {
4
4
  type?: JsApiType;
5
5
  }
6
6
  export declare type Config = MpWebJsApiConfig;
7
- export interface MpWebJsApiMessageResult {
7
+ export interface MpWebMessageResult<T = any> {
8
8
  _type_: 'success' | 'fail';
9
- _data_: any;
9
+ _data_: T;
10
10
  }
11
11
  export interface MpWebJsApiMessage {
12
12
  source: 'hylid';
@@ -15,25 +15,37 @@ export interface MpWebJsApiMessage {
15
15
  serialId: string;
16
16
  options: any;
17
17
  config?: MpWebJsApiConfig;
18
- result?: MpWebJsApiMessageResult;
18
+ result?: MpWebMessageResult;
19
19
  }
20
20
  export interface MpWebBroadcastMessage {
21
21
  source: 'hylid';
22
22
  type: 'broadcast';
23
23
  from: string;
24
- result?: {
25
- key: string;
26
- payload: any;
27
- };
24
+ key: string;
25
+ result?: MpWebMessageResult;
28
26
  }
29
27
  export interface MpWebPageEventMessage {
30
28
  source: 'hylid';
31
29
  type: 'pageEvent';
32
30
  event: 'onShow' | 'onHide' | 'onTitleClick' | 'onOptionMenuClick' | 'onTabItemTap' | ({} & string);
33
- result?: any;
31
+ result?: MpWebMessageResult;
34
32
  }
35
33
  export declare type Message = MpWebJsApiMessage | MpWebBroadcastMessage | MpWebPageEventMessage;
36
34
  export declare type MessageHandler = (message: Message) => void;
37
35
  declare type Callback<T> = (result?: T) => void;
38
36
  export declare type MpWebJsApiOptions<T extends keyof MPApi> = PickMPArgs<T> | Callback<PickMpReturns<T>>;
37
+ export interface WebviewBridgeConfig {
38
+ /** 允许调用 jsApi 的白名单 */
39
+ whitelist?: string[];
40
+ /** 禁止调用 jsApi 的黑名单 */
41
+ blacklist?: string[];
42
+ /** 自定义 jsApi [ 优先级比较高,可以覆盖原生的 jsApi ] */
43
+ customApi?: CustomApi;
44
+ }
45
+ export interface CustomApi {
46
+ [key: string]: (params: {
47
+ success(v: any): void;
48
+ fail(v: any): void;
49
+ }) => void;
50
+ }
39
51
  export {};
package/lib/utils.d.ts ADDED
@@ -0,0 +1,25 @@
1
+ import { MpWebMessageResult } from './types';
2
+ declare const ERROR: {
3
+ NOTFOUND: {
4
+ code: number;
5
+ message: (name: string) => string;
6
+ };
7
+ NOTALLOWED: {
8
+ code: number;
9
+ message: (name: string) => string;
10
+ };
11
+ INVALID: {
12
+ code: number;
13
+ message: (name: string) => string;
14
+ };
15
+ NOTBIND: {
16
+ code: number;
17
+ message: (name: string) => string;
18
+ };
19
+ };
20
+ export declare const createError: (type: keyof typeof ERROR, name: string) => {
21
+ errorCode: number;
22
+ errorMessage: string;
23
+ };
24
+ export declare function createMessage(message: any, type?: 'success' | 'fail'): MpWebMessageResult;
25
+ export {};
package/lib/utils.js ADDED
@@ -0,0 +1,44 @@
1
+ var ERROR = {
2
+ NOTFOUND: {
3
+ code: -1,
4
+ message: function message(name) {
5
+ return "".concat(name, " is not found");
6
+ }
7
+ },
8
+ NOTALLOWED: {
9
+ code: -2,
10
+ message: function message(name) {
11
+ return "".concat(name, " is not allowed");
12
+ }
13
+ },
14
+ INVALID: {
15
+ code: -3,
16
+ message: function message(name) {
17
+ return "".concat(name, " is invalid");
18
+ }
19
+ },
20
+ NOTBIND: {
21
+ code: -4,
22
+ message: function message(name) {
23
+ return "".concat(name, " exec fail, webviewBridge not bind context");
24
+ }
25
+ }
26
+ };
27
+ export var createError = function createError(type, name) {
28
+ var _a = ERROR[type],
29
+ code = _a.code,
30
+ message = _a.message;
31
+ return {
32
+ errorCode: code,
33
+ errorMessage: message(name)
34
+ };
35
+ };
36
+ export function createMessage(message, type) {
37
+ if (type === void 0) {
38
+ type = 'success';
39
+ }
40
+ return {
41
+ _type_: type,
42
+ _data_: message
43
+ };
44
+ }
@@ -0,0 +1,26 @@
1
+ import { Message, WebviewBridgeConfig } from '../types';
2
+ interface WebViewContext {
3
+ postMessage(message: Message): void;
4
+ }
5
+ export declare class WebViewBridge {
6
+ private webview;
7
+ private config;
8
+ private context;
9
+ private MESSAGE_HANDLER;
10
+ /**
11
+ *
12
+ * @param webviewId webview 组件的 id,可传字符串,或者 my.createWebViewContext 创建出的实例
13
+ * @param config Config 配置
14
+ * @param context 页面上下文,传 this 即可。传入后,H5 侧可以使用广播、可以监听页面事件
15
+ */
16
+ constructor(webviewId: string | WebViewContext, config?: WebviewBridgeConfig, context?: any);
17
+ listen: (data: {
18
+ detail: Message;
19
+ }) => void;
20
+ private jsApiHandler;
21
+ private broadcastHandler;
22
+ private pageEventHandler;
23
+ private bindCtxEvent;
24
+ private sendMessage;
25
+ }
26
+ export {};
@@ -0,0 +1,129 @@
1
+ var __assign = this && this.__assign || function () {
2
+ __assign = Object.assign || function (t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
6
+ }
7
+ return t;
8
+ };
9
+ return __assign.apply(this, arguments);
10
+ };
11
+ import { __hy_internal__ } from "./internal";
12
+ import { callbackApi, getApiResult, isAllowed } from "./utils";
13
+ import { createMessage, createError } from "../utils";
14
+ var broadcastTargets = [];
15
+ var WebViewBridge = /** @class */function () {
16
+ /**
17
+ *
18
+ * @param webviewId webview 组件的 id,可传字符串,或者 my.createWebViewContext 创建出的实例
19
+ * @param config Config 配置
20
+ * @param context 页面上下文,传 this 即可。传入后,H5 侧可以使用广播、可以监听页面事件
21
+ */
22
+ function WebViewBridge(webviewId, config, context) {
23
+ if (config === void 0) {
24
+ config = {};
25
+ }
26
+ var _this = this;
27
+ this.config = {};
28
+ this.MESSAGE_HANDLER = [];
29
+ this.listen = function (data) {
30
+ if (data.detail.source !== 'hylid') return;
31
+ _this.MESSAGE_HANDLER.forEach(function (fn) {
32
+ return fn(data.detail);
33
+ });
34
+ };
35
+ this.jsApiHandler = function (data) {
36
+ var _a;
37
+ if (data.type !== 'apiCall') return;
38
+ var config = data.config,
39
+ api = data.api;
40
+ var type = (config || {}).type;
41
+ // 权限管控不允许调用 JSAPI
42
+ if (!isAllowed(_this.config, api)) {
43
+ return _this.sendMessage(data, createMessage(createError('NOTALLOWED', api), 'fail'));
44
+ }
45
+ var jsapi = ((_a = _this.config.customApi) === null || _a === void 0 ? void 0 : _a[api]) || {
46
+ __hy_internal__: __hy_internal__
47
+ }[api] || my[api];
48
+ if (type === 'callback') {
49
+ callbackApi(jsapi, data, function (result) {
50
+ return _this.sendMessage(data, result);
51
+ });
52
+ } else {
53
+ getApiResult(jsapi, data).then(function (result) {
54
+ _this.sendMessage(data, result);
55
+ });
56
+ }
57
+ };
58
+ this.broadcastHandler = function (data) {
59
+ if (data.type !== 'broadcast') return;
60
+ if (!_this.context) {
61
+ _this.sendMessage(data, createMessage(createError('NOTBIND', 'broadcast'), 'fail'));
62
+ return;
63
+ }
64
+ broadcastTargets.forEach(function (target) {
65
+ if (target === _this) return;
66
+ _this.sendMessage(data, createMessage(data.result), target);
67
+ });
68
+ };
69
+ this.pageEventHandler = function (data) {
70
+ var _a;
71
+ if (data.type !== 'pageEvent') return;
72
+ var event = data.event;
73
+ if (!event) {
74
+ _this.sendMessage(data, createMessage(createError('NOTFOUND', event), 'fail'));
75
+ return;
76
+ }
77
+ if (!_this.context) {
78
+ _this.sendMessage(data, createMessage(createError('NOTBIND', event), 'fail'));
79
+ return;
80
+ }
81
+ // 已经监听过了
82
+ if ((_a = _this.context[event]) === null || _a === void 0 ? void 0 : _a._hy_listener_) return;
83
+ _this.bindCtxEvent(event, function (payload) {
84
+ return _this.sendMessage(data, payload);
85
+ });
86
+ _this.context[event]._hy_listener_ = true;
87
+ };
88
+ if (typeof webviewId === 'string') {
89
+ this.webview = my.createWebViewContext(webviewId);
90
+ } else {
91
+ this.webview = webviewId;
92
+ }
93
+ this.config = config;
94
+ this.context = context;
95
+ this.MESSAGE_HANDLER.push(this.jsApiHandler);
96
+ this.MESSAGE_HANDLER.push(this.broadcastHandler);
97
+ this.MESSAGE_HANDLER.push(this.pageEventHandler);
98
+ if (context) {
99
+ broadcastTargets.push(this);
100
+ this.bindCtxEvent('onUnload', function () {
101
+ broadcastTargets = broadcastTargets.filter(function (target) {
102
+ return target !== _this;
103
+ });
104
+ });
105
+ } else {
106
+ 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");
107
+ }
108
+ }
109
+ WebViewBridge.prototype.bindCtxEvent = function (event, callback) {
110
+ if (!this.context) {
111
+ return callback(createMessage(createError('NOTBIND', event), 'fail'));
112
+ }
113
+ var userEvent = this.context[event];
114
+ this.context[event] = function (opts) {
115
+ if (userEvent) userEvent.bind(this.context)(opts);
116
+ callback(createMessage(opts));
117
+ };
118
+ };
119
+ WebViewBridge.prototype.sendMessage = function (origin, result, context) {
120
+ if (context === void 0) {
121
+ context = this;
122
+ }
123
+ context.webview.postMessage(__assign(__assign({}, origin), {
124
+ result: result
125
+ }));
126
+ };
127
+ return WebViewBridge;
128
+ }();
129
+ export { WebViewBridge };
@@ -0,0 +1,3 @@
1
+ export declare function canIUse(payload: {
2
+ jsapi: string;
3
+ }): boolean;
@@ -0,0 +1,4 @@
1
+ export function canIUse(payload) {
2
+ var jsapi = payload.jsapi;
3
+ return my.canIUse(jsapi);
4
+ }
@@ -0,0 +1 @@
1
+ export declare function _getCurrentPages(): any[];
@@ -0,0 +1,6 @@
1
+ export function _getCurrentPages() {
2
+ if (typeof getCurrentPages === 'undefined') {
3
+ return [];
4
+ }
5
+ return getCurrentPages();
6
+ }
@@ -0,0 +1,18 @@
1
+ import { _getCurrentPages as getCurrentPages } from './getCurrentPages';
2
+ import { getMemory, removeMemory, setMemory } from './memory';
3
+ import { canIUse } from './canIUse';
4
+ declare const jsapis: {
5
+ getMemory: typeof getMemory;
6
+ setMemory: typeof setMemory;
7
+ removeMemory: typeof removeMemory;
8
+ getCurrentPages: typeof getCurrentPages;
9
+ canIUse: typeof canIUse;
10
+ };
11
+ interface InternalOptions {
12
+ name: keyof typeof jsapis;
13
+ payload: any;
14
+ success(res: any): void;
15
+ fail(e: any): void;
16
+ }
17
+ export declare function __hy_internal__(options: InternalOptions): Promise<void>;
18
+ export {};
@@ -0,0 +1,156 @@
1
+ var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) {
3
+ return value instanceof P ? value : new P(function (resolve) {
4
+ resolve(value);
5
+ });
6
+ }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) {
9
+ try {
10
+ step(generator.next(value));
11
+ } catch (e) {
12
+ reject(e);
13
+ }
14
+ }
15
+ function rejected(value) {
16
+ try {
17
+ step(generator["throw"](value));
18
+ } catch (e) {
19
+ reject(e);
20
+ }
21
+ }
22
+ function step(result) {
23
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
24
+ }
25
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
26
+ });
27
+ };
28
+ var __generator = this && this.__generator || function (thisArg, body) {
29
+ var _ = {
30
+ label: 0,
31
+ sent: function sent() {
32
+ if (t[0] & 1) throw t[1];
33
+ return t[1];
34
+ },
35
+ trys: [],
36
+ ops: []
37
+ },
38
+ f,
39
+ y,
40
+ t,
41
+ g;
42
+ return g = {
43
+ next: verb(0),
44
+ "throw": verb(1),
45
+ "return": verb(2)
46
+ }, typeof Symbol === "function" && (g[Symbol.iterator] = function () {
47
+ return this;
48
+ }), g;
49
+ function verb(n) {
50
+ return function (v) {
51
+ return step([n, v]);
52
+ };
53
+ }
54
+ function step(op) {
55
+ if (f) throw new TypeError("Generator is already executing.");
56
+ while (_) try {
57
+ 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;
58
+ if (y = 0, t) op = [op[0] & 2, t.value];
59
+ switch (op[0]) {
60
+ case 0:
61
+ case 1:
62
+ t = op;
63
+ break;
64
+ case 4:
65
+ _.label++;
66
+ return {
67
+ value: op[1],
68
+ done: false
69
+ };
70
+ case 5:
71
+ _.label++;
72
+ y = op[1];
73
+ op = [0];
74
+ continue;
75
+ case 7:
76
+ op = _.ops.pop();
77
+ _.trys.pop();
78
+ continue;
79
+ default:
80
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
81
+ _ = 0;
82
+ continue;
83
+ }
84
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
85
+ _.label = op[1];
86
+ break;
87
+ }
88
+ if (op[0] === 6 && _.label < t[1]) {
89
+ _.label = t[1];
90
+ t = op;
91
+ break;
92
+ }
93
+ if (t && _.label < t[2]) {
94
+ _.label = t[2];
95
+ _.ops.push(op);
96
+ break;
97
+ }
98
+ if (t[2]) _.ops.pop();
99
+ _.trys.pop();
100
+ continue;
101
+ }
102
+ op = body.call(thisArg, _);
103
+ } catch (e) {
104
+ op = [6, e];
105
+ y = 0;
106
+ } finally {
107
+ f = t = 0;
108
+ }
109
+ if (op[0] & 5) throw op[1];
110
+ return {
111
+ value: op[0] ? op[1] : void 0,
112
+ done: true
113
+ };
114
+ }
115
+ };
116
+ import { _getCurrentPages as getCurrentPages } from "./getCurrentPages";
117
+ import { getMemory, removeMemory, setMemory } from "./memory";
118
+ import { canIUse } from "./canIUse";
119
+ import { createError } from "../../utils";
120
+ var jsapis = {
121
+ getMemory: getMemory,
122
+ setMemory: setMemory,
123
+ removeMemory: removeMemory,
124
+ getCurrentPages: getCurrentPages,
125
+ canIUse: canIUse
126
+ };
127
+ export function __hy_internal__(options) {
128
+ return __awaiter(this, void 0, void 0, function () {
129
+ var _a, success, fail, name, payload, jsapi, res, e_1;
130
+ return __generator(this, function (_b) {
131
+ switch (_b.label) {
132
+ case 0:
133
+ _a = options || {}, success = _a.success, fail = _a.fail, name = _a.name, payload = _a.payload;
134
+ jsapi = jsapis[name];
135
+ if (!jsapi) {
136
+ fail(createError('NOTFOUND', name));
137
+ return [2 /*return*/];
138
+ }
139
+ _b.label = 1;
140
+ case 1:
141
+ _b.trys.push([1, 3,, 4]);
142
+ return [4 /*yield*/, jsapi(payload)];
143
+ case 2:
144
+ res = _b.sent();
145
+ success(res);
146
+ return [3 /*break*/, 4];
147
+ case 3:
148
+ e_1 = _b.sent();
149
+ fail(e_1);
150
+ return [3 /*break*/, 4];
151
+ case 4:
152
+ return [2 /*return*/];
153
+ }
154
+ });
155
+ });
156
+ }
@@ -0,0 +1,10 @@
1
+ export declare function getMemory(payload: {
2
+ key: string;
3
+ }): any;
4
+ export declare function setMemory(payload: {
5
+ key: string;
6
+ value: any;
7
+ }): void;
8
+ export declare function removeMemory(payload: {
9
+ key: string;
10
+ }): void;
@@ -0,0 +1,12 @@
1
+ var data = {};
2
+ export function getMemory(payload) {
3
+ return data[payload.key];
4
+ }
5
+ export function setMemory(payload) {
6
+ data[payload.key] = {
7
+ data: payload.value
8
+ };
9
+ }
10
+ export function removeMemory(payload) {
11
+ delete data[payload.key];
12
+ }
@@ -0,0 +1,4 @@
1
+ import { MpWebJsApiMessage, MpWebMessageResult, WebviewBridgeConfig } from '../types';
2
+ export declare function callbackApi(jsapi: any, data: MpWebJsApiMessage, cb: (msg: MpWebMessageResult) => void): void;
3
+ export declare const getApiResult: (jsapi: any, data: MpWebJsApiMessage) => Promise<MpWebMessageResult>;
4
+ export declare function isAllowed(config: WebviewBridgeConfig, api: string): boolean;
@@ -0,0 +1,195 @@
1
+ var __assign = this && this.__assign || function () {
2
+ __assign = Object.assign || function (t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
6
+ }
7
+ return t;
8
+ };
9
+ return __assign.apply(this, arguments);
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
+ };
126
+ import { createMessage, createError } from "../utils";
127
+ function getSyncApi(apiName, jsapi, options) {
128
+ // 同步场景无该 API
129
+ if (!jsapi) {
130
+ return createMessage(createError('NOTFOUND', apiName), 'fail');
131
+ }
132
+ // 传进来的 API 不是函数
133
+ if (typeof jsapi !== 'function') {
134
+ return createMessage(createError('INVALID', apiName), 'fail');
135
+ }
136
+ return createMessage(jsapi(options));
137
+ }
138
+ function getAsyncApi(apiName, jsapi, _options) {
139
+ return new Promise(function (resolve) {
140
+ var options = __assign(__assign({}, _options), {
141
+ success: function success(res) {
142
+ resolve(createMessage(res));
143
+ },
144
+ fail: function fail(res) {
145
+ resolve(createMessage(res, 'fail'));
146
+ }
147
+ });
148
+ // @ts-ignore
149
+ if (!jsapi) return my.call(api, options);
150
+ if (typeof jsapi !== 'function') {
151
+ return options.fail(createError('INVALID', apiName));
152
+ }
153
+ jsapi(options);
154
+ });
155
+ }
156
+ export function callbackApi(jsapi, data, cb) {
157
+ var api = (data || {}).api;
158
+ // 无该 API
159
+ if (!jsapi) {
160
+ return cb(createMessage(createError('NOTFOUND', api), 'fail'));
161
+ }
162
+ // 传进来的 API 不是函数
163
+ if (typeof jsapi !== 'function') {
164
+ return cb(createMessage(createError('INVALID', api), 'fail'));
165
+ }
166
+ jsapi(function (result) {
167
+ return cb(createMessage(result));
168
+ });
169
+ }
170
+ export var getApiResult = function getApiResult(jsapi, data) {
171
+ return __awaiter(void 0, void 0, void 0, function () {
172
+ var api, options, config, _a, type;
173
+ return __generator(this, function (_b) {
174
+ api = data.api, options = data.options, config = data.config;
175
+ _a = (config || {}).type, type = _a === void 0 ? 'async' : _a;
176
+ if (type === 'sync') {
177
+ return [2 /*return*/, getSyncApi(api, jsapi, options)];
178
+ }
179
+ if (type === 'async') {
180
+ return [2 /*return*/, getAsyncApi(api, jsapi, options)];
181
+ }
182
+ // 不识别的类型
183
+ return [2 /*return*/, createMessage(createError('INVALID', api), 'fail')];
184
+ });
185
+ });
186
+ };
187
+ export function isAllowed(config, api) {
188
+ var _a = config || {},
189
+ whitelist = _a.whitelist,
190
+ blacklist = _a.blacklist;
191
+ // 黑白名单校验
192
+ if (whitelist && !whitelist.includes(api)) return false;
193
+ if (blacklist && blacklist.includes(api)) return false;
194
+ return true;
195
+ }
@@ -1,11 +1,8 @@
1
1
  /// <reference types="miniprogram" />
2
- import { Message, MessageHandler, MpWebBroadcastMessage, MpWebJsApiMessage, MpWebPageEventMessage } from './types';
2
+ import { MpWebMessage } from './types';
3
3
  interface Config {
4
- /** 允许调用 jsApi 的白名单 */
5
4
  whitelist?: string[];
6
- /** 禁止调用 jsApi 的黑名单 */
7
5
  blacklist?: string[];
8
- /** 自定义 jsApi [ 优先级比较高,可以覆盖原生的 jsApi ] */
9
6
  customApi?: CustomApi;
10
7
  }
11
8
  interface CustomApi {
@@ -17,22 +14,11 @@ interface CustomApi {
17
14
  export declare class WebViewBridge {
18
15
  webview: WebViewContext;
19
16
  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);
17
+ constructor(ctx: WebViewContext, config?: Config);
29
18
  listen: (data: {
30
- detail: Message;
31
- }) => void;
19
+ detail: MpWebMessage;
20
+ }) => Promise<true | undefined>;
32
21
  isAllowed(api: string): boolean;
33
- jsApiHandler: (command: MpWebJsApiMessage) => void;
34
- broadcastHandler: (data: MpWebBroadcastMessage) => void;
35
- pageEventHandler: (data: MpWebPageEventMessage) => void;
36
- bindCtxEvent(event: string, callback: (...rest: any) => void): void;
22
+ handleApi: (data: MpWebMessage) => Promise<unknown>;
37
23
  }
38
24
  export {};
@@ -8,169 +8,222 @@ var __assign = this && this.__assign || function () {
8
8
  };
9
9
  return __assign.apply(this, arguments);
10
10
  };
11
- var broadcastTargets = [];
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
+ };
12
126
  var WebViewBridge = /** @class */function () {
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) {
127
+ function WebViewBridge(ctx, config) {
20
128
  if (config === void 0) {
21
129
  config = {};
22
130
  }
23
131
  var _this = this;
24
132
  this.config = {};
25
- this.MESSAGE_HANDLER = [];
26
133
  this.listen = function (data) {
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
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
+ }
53
152
  });
153
+ this.webview.postMessage(notAllowedMessage);
154
+ return [2 /*return*/];
54
155
  }
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) {
156
+ if (type === 'callback') {
67
157
  // @ts-ignore
68
- my.call(api, options);
158
+ my[api](function (result) {
159
+ _this.webview.postMessage(__assign(__assign({}, command), {
160
+ result: result
161
+ }));
162
+ });
69
163
  } else {
70
- mpApi(options);
164
+ this.handleApi(command).then(function (result) {
165
+ _this.webview.postMessage(__assign(__assign({}, command), {
166
+ result: result
167
+ }));
168
+ });
71
169
  }
170
+ // 表示被 hylid-bridge 消费了
171
+ return [2 /*return*/, true];
72
172
  }
173
+ return [2 /*return*/];
73
174
  });
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
- }
175
+ });
176
+ };
177
+ this.handleApi = function (data) {
178
+ var api = data.api,
179
+ _options = data.options,
180
+ config = data.config;
181
+ var _a = (config || {}).type,
182
+ type = _a === void 0 ? 'async' : _a;
183
+ return new Promise(function (resolve) {
184
+ var _a;
185
+ var options = __assign(__assign({}, _options), {
186
+ success: function success(res) {
187
+ resolve({
188
+ _type_: 'success',
189
+ _data_: res
190
+ });
191
+ },
192
+ fail: function fail(res) {
193
+ resolve({
194
+ _type_: 'fail',
195
+ _data_: res
196
+ });
87
197
  }
88
198
  });
89
- _this.webview.postMessage(notAllowedMessage);
90
- return;
91
- }
92
- if (type === 'callback') {
93
199
  // @ts-ignore
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
- }));
200
+ var mpApi = ((_a = _this.config.customApi) === null || _a === void 0 ? void 0 : _a[api]) || my[api];
201
+ if (type === 'sync') {
202
+ var data_1 = mpApi(_options);
203
+ resolve({
204
+ _type_: 'success',
205
+ _data_: data_1
206
+ });
207
+ }
208
+ if (type === 'async') {
209
+ if (!mpApi) {
210
+ // @ts-ignore
211
+ my.call(api, options);
212
+ } else {
213
+ mpApi(options);
214
+ }
215
+ }
129
216
  });
130
- _this.context[event]._hy_listener_ = true;
131
217
  };
132
- if (typeof webviewId === 'string') {
133
- this.webview = my.createWebViewContext(webviewId);
134
- } else {
135
- this.webview = webviewId;
136
- }
218
+ this.webview = ctx;
137
219
  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
- }
152
220
  }
153
221
  WebViewBridge.prototype.isAllowed = function (api) {
154
- var _a = this.config || {},
155
- whitelist = _a.whitelist,
156
- blacklist = _a.blacklist;
157
222
  // 黑白名单校验
158
- if (whitelist && !whitelist.includes(api)) return false;
159
- if (blacklist && blacklist.includes(api)) return false;
223
+ if (this.config.whitelist && !this.config.whitelist.includes(api)) return false;
224
+ if (this.config.blacklist && this.config.blacklist.includes(api)) return false;
160
225
  return true;
161
226
  };
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
- };
174
227
  return WebViewBridge;
175
228
  }();
176
229
  export { WebViewBridge };
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@hylid/call",
3
- "version": "3.2.0-alpha.1",
3
+ "version": "3.2.0-alpha.4",
4
4
  "main": "lib/index.js",
5
5
  "files": [
6
6
  "lib"
7
7
  ],
8
8
  "dependencies": {
9
- "@hylid/env": "^3.2.0-alpha.1",
10
- "@hylid/types": "^3.2.0-alpha.1"
9
+ "@hylid/env": "^3.2.0-alpha.4",
10
+ "@hylid/types": "^3.2.0-alpha.4"
11
11
  },
12
12
  "publishConfig": {
13
13
  "access": "public"