提交 9ee05bfa 编写于 作者: fxy060608's avatar fxy060608

feat: defineOnApi,defineOffApi

上级 059d3dc4
......@@ -34,7 +34,7 @@
"node": ">=10.0.0"
},
"devDependencies": {
"@dcloudio/types": "^2.0.24",
"@dcloudio/types": "^2.0.25",
"@microsoft/api-extractor": "^7.13.2",
"@rollup/plugin-alias": "^3.1.1",
"@rollup/plugin-commonjs": "^17.0.0",
......
......@@ -35,7 +35,7 @@ declare var __UNI_FEATURE_NAVIGATIONBAR_TRANSPARENT__: boolean
declare var __uniRoutes: UniApp.UniRoutes
declare var __uniConfig: UniApp.UniConfig
declare var UniViewJSBridge: any
declare var UniServiceJSBridge: any
declare var UniServiceJSBridge: UniApp.UniServiceJSBridge
declare const getCurrentPages: <T extends AnyObject = {}>(
isAll?: boolean
......
......@@ -163,4 +163,45 @@ declare namespace UniApp {
leftWindow?: PagesJsonWindowOptions
rightWindow?: PagesJsonWindowOptions
}
type OnApiLike = (callback: (result: unknown) => void) => void
interface UniServiceJSBridge {
/**
* 监听 service 层的自定义事件。事件由 emit 触发,回调函数会接收所有传入事件触发函数的额外参数。
* @param event
* @param callback
*/
on(event: string | string[], callback: Function): void
/**
* 监听 service 层的自定义事件。仅触发一次,在第一次触发之后移除监听器。
* @param event
* @param callback
*/
once(event: string, callback: Function): void
/**
* 移除 service 层的自定义事件监听器。
* 如果没有提供参数,则移除所有的事件监听器;
* 如果只提供了事件,则移除该事件所有的监听器;
* 如果同时提供了事件与回调,则只移除这个回调的监听器。
* @param event
* @param callback
*/
off(event?: string | string[], callback?: Function): void
/**
* 触发 Service 层的事件。附加参数都会传给监听器回调。
* @param event
* @param args
*/
emit(event: string, ...args: any[]): void
/**
* 触发 Service 层事件类型API(on开头)回调。
* @param name
* @param res
*/
invokeOnCallback<T extends OnApiLike>(
name: string,
res: Parameters<Parameters<T>[0]>[0]
): void
publishHandler(event: string, args: unknown, pageId: number): void
}
}
......@@ -13,10 +13,6 @@ const invokeCallbacks: {
}
} = {}
function createInvokeCallbackName(name: string, callbackId: number) {
return 'api.' + name + '.' + callbackId
}
function addInvokeCallback(
id: number,
name: string,
......@@ -45,29 +41,41 @@ export function invokeCallback(id: number, res: unknown, extras?: unknown) {
return res
}
function getKeepAliveApiCallback(name: string, callback: Function) {
const onName = 'api.' + name.replace('off', 'on')
export function findInvokeCallbackByName(name: string) {
for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true
}
}
return false
}
export function removeKeepAliveApiCallback(name: string, callback: Function) {
for (const key in invokeCallbacks) {
const item = invokeCallbacks[key]
if (item.callback === callback && item.name.indexOf(onName) === 0) {
if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key]
return Number(key)
}
}
return -1
}
export function offKeepAliveApiCallback(name: string) {
UniServiceJSBridge.off('api.' + name)
}
export function onKeepAliveApiCallback(name: string) {
UniServiceJSBridge.on('api.' + name, (res: unknown) => {
for (const key in invokeCallbacks) {
const opts = invokeCallbacks[key]
if (opts.name === name) {
opts.callback(res)
}
}
})
}
export function createKeepAliveApiCallback(name: string, callback: Function) {
if (name.indexOf('off') === 0) {
return getKeepAliveApiCallback(name, callback)
}
const id = invokeCallbackId++
return addInvokeCallback(
id,
createInvokeCallbackName(name, id),
callback,
true
)
return addInvokeCallback(invokeCallbackId++, name, callback, true)
}
export const API_SUCCESS = 'success'
......@@ -117,21 +125,17 @@ export function createAsyncApiCallback(
const hasFail = isFunction(fail)
const hasComplete = isFunction(complete)
const callbackId = invokeCallbackId++
addInvokeCallback(
callbackId,
createInvokeCallbackName(name, callbackId),
(res: ApiRes) => {
res = res || {}
res.errMsg = normalizeErrMsg(res.errMsg, name)
isFunction(beforeAll) && beforeAll(res)
if (res.errMsg === name + ':ok') {
isFunction(beforeSuccess) && beforeSuccess(res)
hasSuccess && success!(res)
} else {
hasFail && fail!(res)
}
hasComplete && complete!(res)
addInvokeCallback(callbackId, name, (res: ApiRes) => {
res = res || {}
res.errMsg = normalizeErrMsg(res.errMsg, name)
isFunction(beforeAll) && beforeAll(res)
if (res.errMsg === name + ':ok') {
isFunction(beforeSuccess) && beforeSuccess(res)
hasSuccess && success!(res)
} else {
hasFail && fail!(res)
}
)
hasComplete && complete!(res)
})
return callbackId
}
......@@ -4,17 +4,23 @@ import { API_TYPE_ON_PROTOCOLS, validateProtocols } from '../protocol'
import {
invokeCallback,
createAsyncApiCallback,
onKeepAliveApiCallback,
offKeepAliveApiCallback,
findInvokeCallbackByName,
createKeepAliveApiCallback,
removeKeepAliveApiCallback,
} from './callback'
import { promisify } from './promise'
export const API_TYPE_ON = 0
export const API_TYPE_TASK = 1
export const API_TYPE_SYNC = 2
export const API_TYPE_ASYNC = 3
export const API_TYPE_OFF = 1
export const API_TYPE_TASK = 2
export const API_TYPE_SYNC = 3
export const API_TYPE_ASYNC = 4
type API_TYPES =
| typeof API_TYPE_ON
| typeof API_TYPE_OFF
| typeof API_TYPE_TASK
| typeof API_TYPE_SYNC
| typeof API_TYPE_ASYNC
......@@ -35,8 +41,28 @@ function formatApiArgs(args: any[], options?: ApiOptions) {
}
function wrapperOnApi(name: string, fn: Function) {
return (callback: Function) =>
fn.apply(null, createKeepAliveApiCallback(name, callback))
return (callback: Function) => {
// 是否是首次调用on,如果是首次,需要初始化onMethod监听
const isFirstInvokeOnApi = !findInvokeCallbackByName(name)
createKeepAliveApiCallback(name, callback)
if (isFirstInvokeOnApi) {
onKeepAliveApiCallback(name)
fn()
}
}
}
function wrapperOffApi(name: string, fn: Function) {
return (callback: Function) => {
name = name.replace('off', 'on')
removeKeepAliveApiCallback(name, callback)
// 是否还存在监听,若已不存在,则移除onMethod监听
const hasInvokeOnApi = findInvokeCallbackByName(name)
if (!hasInvokeOnApi) {
offKeepAliveApiCallback(name)
fn()
}
}
}
function wrapperTaskApi(name: string, fn: Function, options?: ApiOptions) {
......@@ -96,6 +122,20 @@ export function defineOnApi<T extends Function>(
) as T
}
export function defineOffApi<T extends Function>(
name: string,
fn: T,
options?: ApiOptions
) {
return defineApi(
API_TYPE_OFF,
name,
fn,
__DEV__ ? API_TYPE_ON_PROTOCOLS : undefined,
options
) as T
}
export function defineTaskApi<T extends Function>(
name: string,
fn: T,
......@@ -190,6 +230,8 @@ function defineApi(
switch (type) {
case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options)
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options)
case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options)
case API_TYPE_SYNC:
......
......@@ -25,6 +25,7 @@ export * from './protocols/route/route'
// helpers
export {
defineOnApi,
defineOffApi,
defineTaskApi,
defineSyncApi,
defineAsyncApi,
......
function E() {
// Keep this empty so it's easier to inherit from
// (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
}
E.prototype = {
on: function (name, callback, ctx) {
var e = this.e || (this.e = {})
;(e[name] || (e[name] = [])).push({
fn: callback,
ctx: ctx,
})
return this
},
once: function (name, callback, ctx) {
var self = this
function listener() {
self.off(name, listener)
callback.apply(ctx, arguments)
}
listener._ = callback
return this.on(name, listener, ctx)
},
emit: function (name) {
var data = [].slice.call(arguments, 1)
var evtArr = ((this.e || (this.e = {}))[name] || []).slice()
var i = 0
var len = evtArr.length
for (i; i < len; i++) {
evtArr[i].fn.apply(evtArr[i].ctx, data)
}
return this
},
off: function (name, callback) {
var e = this.e || (this.e = {})
var evts = e[name]
var liveEvents = []
if (evts && callback) {
for (var i = 0, len = evts.length; i < len; i++) {
if (evts[i].fn !== callback && evts[i].fn._ !== callback)
liveEvents.push(evts[i])
}
}
// Remove event from queue to prevent memory leak
// Suggested by https://github.com/lazd
// Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
liveEvents.length ? (e[name] = liveEvents) : delete e[name]
return this
},
}
export default E
type Handler<T = any> = (event?: T) => void
import { extend } from '@vue/shared'
// @ts-ignore TODO 等待 vue3 的兼容模式自带emitter
import E from './TinyEmitter'
export function initBridge(namespace: 'service' | 'view') {
export function initBridge(
namespace: 'service' | 'view'
): UniApp.UniServiceJSBridge {
// TODO vue3 compatibility builds
const { on, off, emit } = {
on(event: string, callback: Handler) {
console.log(event, callback)
const emitter = new E()
return extend(emitter, {
subscribe(event: string, callback: Function): void {
return emitter.on(`${namespace}.${event}`, callback)
},
off(event: string, callback: Handler) {
console.log(event, callback)
unsubscribe(event: string, callback: Function): void {
return emitter.off(`${namespace}.${event}`, callback)
},
emit(event: string, ...args: any[]) {
console.log(event, args)
},
}
return {
on,
off,
emit,
subscribe(event: string, callback: Handler) {
return on(`${namespace}.${event}`, callback)
},
unsubscribe(event: string, callback: Handler) {
return off(`${namespace}.${event}`, callback)
},
subscribeHandler(event: string, args: any, pageId: number) {
subscribeHandler(event: string, args: unknown, pageId: number): void {
if (__DEV__) {
console.log(
`[${namespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify(
......@@ -31,7 +22,7 @@ export function initBridge(namespace: 'service' | 'view') {
)}, ${pageId}`
)
}
return emit(`${namespace}.${event}`, args, pageId)
return emitter.emit(`${namespace}.${event}`, args, pageId)
},
}
})
}
import { extend } from '@vue/shared'
import { initBridge } from '../../helpers/bridge'
export const ServiceJSBridge = initBridge('service')
export const ServiceJSBridge = extend(initBridge('service'), {
invokeOnCallback(name: string, res: unknown) {
return UniServiceJSBridge.emit('api.' + name, res)
},
})
......@@ -55,35 +55,66 @@ function initApp$1(app) {
globalProperties.$applyOptions = applyOptions;
}
}
function initBridge(namespace) {
const {on, off, emit} = {
on(event2, callback) {
console.log(event2, callback);
},
off(event2, callback) {
console.log(event2, callback);
},
emit(event2, ...args) {
console.log(event2, args);
function E() {
}
E.prototype = {
on: function(name, callback, ctx) {
var e2 = this.e || (this.e = {});
(e2[name] || (e2[name] = [])).push({
fn: callback,
ctx
});
return this;
},
once: function(name, callback, ctx) {
var self = this;
function listener() {
self.off(name, listener);
callback.apply(ctx, arguments);
}
};
return {
on,
off,
emit,
listener._ = callback;
return this.on(name, listener, ctx);
},
emit: function(name) {
var data = [].slice.call(arguments, 1);
var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
var i = 0;
var len = evtArr.length;
for (i; i < len; i++) {
evtArr[i].fn.apply(evtArr[i].ctx, data);
}
return this;
},
off: function(name, callback) {
var e2 = this.e || (this.e = {});
var evts = e2[name];
var liveEvents = [];
if (evts && callback) {
for (var i = 0, len = evts.length; i < len; i++) {
if (evts[i].fn !== callback && evts[i].fn._ !== callback)
liveEvents.push(evts[i]);
}
}
liveEvents.length ? e2[name] = liveEvents : delete e2[name];
return this;
}
};
function initBridge(namespace) {
const emitter2 = new E();
return extend(emitter2, {
subscribe(event2, callback) {
return on(`${namespace}.${event2}`, callback);
return emitter2.on(`${namespace}.${event2}`, callback);
},
unsubscribe(event2, callback) {
return off(`${namespace}.${event2}`, callback);
return emitter2.off(`${namespace}.${event2}`, callback);
},
subscribeHandler(event2, args, pageId) {
if (process.env.NODE_ENV !== "production") {
console.log(`[${namespace}][subscribeHandler][${Date.now()}]:${event2}, ${JSON.stringify(args)}, ${pageId}`);
}
return emit(`${namespace}.${event2}`, args, pageId);
return emitter2.emit(`${namespace}.${event2}`, args, pageId);
}
};
});
}
const ViewJSBridge = initBridge("view");
const LONGPRESS_TIMEOUT = 350;
......@@ -639,7 +670,11 @@ function initView(app) {
}
initAppConfig$1(app._context.config);
}
const ServiceJSBridge = initBridge("service");
const ServiceJSBridge = extend(initBridge("service"), {
invokeOnCallback(name, res) {
return UniServiceJSBridge.emit("api." + name, res);
}
});
function querySelector(vm, selector) {
const el = vm.$el.querySelector(selector);
return el && el.__vue__;
......@@ -7483,6 +7518,13 @@ function decode(base64) {
}
return arraybuffer;
}
const API_TYPE_ON_PROTOCOLS = [
{
name: "callback",
type: Function,
required: true
}
];
function validateProtocolFail(name, msg) {
const errMsg = `${name}:fail ${msg}`;
{
......@@ -7617,9 +7659,6 @@ function tryCatch(fn) {
}
let invokeCallbackId = 1;
const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return "api." + name + "." + callbackId;
}
function addInvokeCallback(id2, name, callback, keepAlive = false) {
invokeCallbacks[id2] = {
name,
......@@ -7640,23 +7679,37 @@ function invokeCallback(id2, res, extras) {
}
return res;
}
function getKeepAliveApiCallback(name, callback) {
const onName = "api." + name.replace("off", "on");
function findInvokeCallbackByName(name) {
for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) {
const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) {
if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key];
return Number(key);
}
}
return -1;
}
function offKeepAliveApiCallback(name) {
UniServiceJSBridge.off("api." + name);
}
function onKeepAliveApiCallback(name) {
UniServiceJSBridge.on("api." + name, (res) => {
for (const key in invokeCallbacks) {
const opts = invokeCallbacks[key];
if (opts.name === name) {
opts.callback(res);
}
}
});
}
function createKeepAliveApiCallback(name, callback) {
if (name.indexOf("off") === 0) {
return getKeepAliveApiCallback(name, callback);
}
const id2 = invokeCallbackId++;
return addInvokeCallback(id2, createInvokeCallbackName(name, id2), callback, true);
return addInvokeCallback(invokeCallbackId++, name, callback, true);
}
const API_SUCCESS = "success";
const API_FAIL = "fail";
......@@ -7687,7 +7740,7 @@ function createAsyncApiCallback(name, args = {}, {beforeAll, beforeSuccess} = {}
const hasFail = isFunction(fail);
const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => {
addInvokeCallback(callbackId, name, (res) => {
res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res);
......@@ -7727,9 +7780,10 @@ function promisify(fn) {
};
}
const API_TYPE_ON = 0;
const API_TYPE_TASK = 1;
const API_TYPE_SYNC = 2;
const API_TYPE_ASYNC = 3;
const API_TYPE_OFF = 1;
const API_TYPE_TASK = 2;
const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) {
const params = args[0];
if (!options || !isPlainObject(options.formatArgs) && isPlainObject(params)) {
......@@ -7742,7 +7796,25 @@ function formatApiArgs(args, options) {
return args;
}
function wrapperOnApi(name, fn) {
return (callback) => fn.apply(null, createKeepAliveApiCallback(name, callback));
return (callback) => {
const isFirstInvokeOnApi = !findInvokeCallbackByName(name);
createKeepAliveApiCallback(name, callback);
if (isFirstInvokeOnApi) {
onKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperOffApi(name, fn) {
return (callback) => {
name = name.replace("off", "on");
removeKeepAliveApiCallback(name, callback);
const hasInvokeOnApi = findInvokeCallbackByName(name);
if (!hasInvokeOnApi) {
offKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
......@@ -7771,6 +7843,12 @@ function wrapperApi(fn, name, protocol, options) {
return fn.apply(null, formatApiArgs(args, options));
};
}
function defineOnApi(name, fn, options) {
return defineApi(API_TYPE_ON, name, fn, process.env.NODE_ENV !== "production" ? API_TYPE_ON_PROTOCOLS : void 0, options);
}
function defineOffApi(name, fn, options) {
return defineApi(API_TYPE_OFF, name, fn, process.env.NODE_ENV !== "production" ? API_TYPE_ON_PROTOCOLS : void 0, options);
}
function defineSyncApi(name, fn, protocol, options) {
return defineApi(API_TYPE_SYNC, name, fn, process.env.NODE_ENV !== "production" ? protocol : void 0, options);
}
......@@ -7781,6 +7859,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) {
case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC:
......@@ -8332,6 +8412,51 @@ const getSystemInfoSync = defineSyncApi("getSystemInfoSync", () => {
const getSystemInfo = defineAsyncApi("getSystemInfo", () => {
return Promise.resolve(getSystemInfoSync());
});
const API_ON_NETWORK_STATUS_CHANGE = "onNetworkStatusChange";
function networkListener() {
getNetworkType().then(({networkType}) => {
UniServiceJSBridge.invokeOnCallback(API_ON_NETWORK_STATUS_CHANGE, {
isConnected: networkType !== "none",
networkType
});
});
}
function getConnection() {
return navigator.connection || navigator.webkitConnection || navigator.mozConnection;
}
const onNetworkStatusChange = defineOnApi(API_ON_NETWORK_STATUS_CHANGE, () => {
const connection = getConnection();
if (connection) {
connection.addEventListener("change", networkListener);
} else {
window.addEventListener("offline", networkListener);
window.addEventListener("online", networkListener);
}
});
const offNetworkStatusChange = defineOffApi("offNetworkStatusChange", () => {
const connection = getConnection();
if (connection) {
connection.removeEventListener("change", networkListener);
} else {
window.removeEventListener("offline", networkListener);
window.removeEventListener("online", networkListener);
}
});
const getNetworkType = defineAsyncApi("getNetworkType", () => {
const connection = getConnection();
let networkType = "unknown";
if (connection) {
networkType = connection.type;
if (networkType === "cellular" && connection.effectiveType) {
networkType = connection.effectiveType.replace("slow-", "");
} else if (!["none", "wifi"].includes(networkType)) {
networkType = "unknown";
}
} else if (navigator.onLine === false) {
networkType = "none";
}
return Promise.resolve({networkType});
});
const openDocument = defineAsyncApi(API_OPEN_DOCUMENT, ({filePath}) => {
window.open(filePath);
return Promise.resolve();
......@@ -8401,6 +8526,9 @@ var api = /* @__PURE__ */ Object.freeze({
makePhoneCall,
getSystemInfo,
getSystemInfoSync,
onNetworkStatusChange,
offNetworkStatusChange,
getNetworkType,
openDocument,
getImageInfo,
navigateBack,
......@@ -9516,4 +9644,4 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
]);
}
_sfc_main.render = _sfc_render;
export {_sfc_main$1 as AsyncErrorComponent, _sfc_main as AsyncLoadingComponent, _sfc_main$o as Audio, _sfc_main$n as Canvas, _sfc_main$m as Checkbox, _sfc_main$l as CheckboxGroup, _sfc_main$k as Editor, _sfc_main$j as Form, index$2 as Icon, _sfc_main$h as Image, _sfc_main$g as Input, _sfc_main$f as Label, _sfc_main$e as MovableView, _sfc_main$d as Navigator, index as PageComponent, _sfc_main$c as Progress, _sfc_main$b as Radio, _sfc_main$a as RadioGroup, _sfc_main$i as ResizeSensor, _sfc_main$9 as RichText, _sfc_main$8 as ScrollView, _sfc_main$7 as Slider, _sfc_main$6 as SwiperItem, _sfc_main$5 as Switch, index$1 as Text, _sfc_main$4 as Textarea, UniServiceJSBridge$1 as UniServiceJSBridge, UniViewJSBridge$1 as UniViewJSBridge, _sfc_main$3 as View, addInterceptor, arrayBufferToBase64, base64ToArrayBuffer, canIUse, createIntersectionObserver, createSelectorQuery, getApp$1 as getApp, getCurrentPages$1 as getCurrentPages, getImageInfo, getSystemInfo, getSystemInfoSync, makePhoneCall, navigateBack, navigateTo, openDocument, index$3 as plugin, promiseInterceptor, reLaunch, redirectTo, removeInterceptor, switchTab, uni$1 as uni, upx2px};
export {_sfc_main$1 as AsyncErrorComponent, _sfc_main as AsyncLoadingComponent, _sfc_main$o as Audio, _sfc_main$n as Canvas, _sfc_main$m as Checkbox, _sfc_main$l as CheckboxGroup, _sfc_main$k as Editor, _sfc_main$j as Form, index$2 as Icon, _sfc_main$h as Image, _sfc_main$g as Input, _sfc_main$f as Label, _sfc_main$e as MovableView, _sfc_main$d as Navigator, index as PageComponent, _sfc_main$c as Progress, _sfc_main$b as Radio, _sfc_main$a as RadioGroup, _sfc_main$i as ResizeSensor, _sfc_main$9 as RichText, _sfc_main$8 as ScrollView, _sfc_main$7 as Slider, _sfc_main$6 as SwiperItem, _sfc_main$5 as Switch, index$1 as Text, _sfc_main$4 as Textarea, UniServiceJSBridge$1 as UniServiceJSBridge, UniViewJSBridge$1 as UniViewJSBridge, _sfc_main$3 as View, addInterceptor, arrayBufferToBase64, base64ToArrayBuffer, canIUse, createIntersectionObserver, createSelectorQuery, getApp$1 as getApp, getCurrentPages$1 as getCurrentPages, getImageInfo, getNetworkType, getSystemInfo, getSystemInfoSync, makePhoneCall, navigateBack, navigateTo, offNetworkStatusChange, onNetworkStatusChange, openDocument, index$3 as plugin, promiseInterceptor, reLaunch, redirectTo, removeInterceptor, switchTab, uni$1 as uni, upx2px};
import { defineOnApi, defineOffApi, defineAsyncApi } from '@dcloudio/uni-api'
type OnNetworkStatusChange = typeof uni.onNetworkStatusChange
const API_ON_NETWORK_STATUS_CHANGE = 'onNetworkStatusChange'
function networkListener() {
getNetworkType().then(({ networkType }) => {
UniServiceJSBridge.invokeOnCallback<OnNetworkStatusChange>(
API_ON_NETWORK_STATUS_CHANGE,
{
isConnected: networkType !== 'none',
networkType,
}
)
})
}
function getConnection() {
return (
(navigator as any).connection ||
(navigator as any).webkitConnection ||
(navigator as any).mozConnection
)
}
export const onNetworkStatusChange = defineOnApi<OnNetworkStatusChange>(
API_ON_NETWORK_STATUS_CHANGE,
() => {
const connection = getConnection()
if (connection) {
connection.addEventListener('change', networkListener)
} else {
window.addEventListener('offline', networkListener)
window.addEventListener('online', networkListener)
}
}
)
export const offNetworkStatusChange = defineOffApi<
typeof uni.offNetworkStatusChange
>('offNetworkStatusChange', () => {
const connection = getConnection()
if (connection) {
connection.removeEventListener('change', networkListener)
} else {
window.removeEventListener('offline', networkListener)
window.removeEventListener('online', networkListener)
}
})
export const getNetworkType = defineAsyncApi<typeof uni.getNetworkType>(
'getNetworkType',
() => {
const connection = getConnection()
let networkType = 'unknown'
if (connection) {
networkType = connection.type
if (networkType === 'cellular' && connection.effectiveType) {
networkType = connection.effectiveType.replace('slow-', '')
} else if (!['none', 'wifi'].includes(networkType)) {
networkType = 'unknown'
}
} else if (navigator.onLine === false) {
networkType = 'none'
}
return Promise.resolve({ networkType })
}
)
......@@ -3,6 +3,7 @@ export * from './base/canIUse'
export * from './device/makePhoneCall'
export * from './device/getSystemInfo'
export * from './device/getSystemInfoSync'
export * from './device/network'
export * from './file/openDocument'
......
......@@ -154,9 +154,6 @@ function tryCatch(fn) {
let invokeCallbackId = 1;
const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return 'api.' + name + '.' + callbackId;
}
function addInvokeCallback(id, name, callback, keepAlive = false) {
invokeCallbacks[id] = {
name,
......@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) {
}
return res;
}
function getKeepAliveApiCallback(name, callback) {
const onName = 'api.' + name.replace('off', 'on');
function findInvokeCallbackByName(name) {
for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) {
const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) {
if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key];
return Number(key);
}
}
return -1;
}
function offKeepAliveApiCallback(name) {
UniServiceJSBridge.off('api.' + name);
}
function onKeepAliveApiCallback(name) {
UniServiceJSBridge.on('api.' + name, (res) => {
for (const key in invokeCallbacks) {
const opts = invokeCallbacks[key];
if (opts.name === name) {
opts.callback(res);
}
}
});
}
function createKeepAliveApiCallback(name, callback) {
if (name.indexOf('off') === 0) {
return getKeepAliveApiCallback(name, callback);
}
const id = invokeCallbackId++;
return addInvokeCallback(id, createInvokeCallbackName(name, id), callback, true);
return addInvokeCallback(invokeCallbackId++, name, callback, true);
}
function getApiCallbacks(args) {
const apiCallbacks = {};
......@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const hasFail = isFunction(fail);
const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => {
addInvokeCallback(callbackId, name, (res) => {
res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res);
......@@ -250,9 +261,10 @@ function handlePromise(promise) {
}
const API_TYPE_ON = 0;
const API_TYPE_TASK = 1;
const API_TYPE_SYNC = 2;
const API_TYPE_ASYNC = 3;
const API_TYPE_OFF = 1;
const API_TYPE_TASK = 2;
const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) {
const params = args[0];
if (!options ||
......@@ -266,7 +278,27 @@ function formatApiArgs(args, options) {
return args;
}
function wrapperOnApi(name, fn) {
return (callback) => fn.apply(null, createKeepAliveApiCallback(name, callback));
return (callback) => {
// 是否是首次调用on,如果是首次,需要初始化onMethod监听
const isFirstInvokeOnApi = !findInvokeCallbackByName(name);
createKeepAliveApiCallback(name, callback);
if (isFirstInvokeOnApi) {
onKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperOffApi(name, fn) {
return (callback) => {
name = name.replace('off', 'on');
removeKeepAliveApiCallback(name, callback);
// 是否还存在监听,若已不存在,则移除onMethod监听
const hasInvokeOnApi = findInvokeCallbackByName(name);
if (!hasInvokeOnApi) {
offKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
......@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) {
case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC:
......
......@@ -154,9 +154,6 @@ function tryCatch(fn) {
let invokeCallbackId = 1;
const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return 'api.' + name + '.' + callbackId;
}
function addInvokeCallback(id, name, callback, keepAlive = false) {
invokeCallbacks[id] = {
name,
......@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) {
}
return res;
}
function getKeepAliveApiCallback(name, callback) {
const onName = 'api.' + name.replace('off', 'on');
function findInvokeCallbackByName(name) {
for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) {
const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) {
if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key];
return Number(key);
}
}
return -1;
}
function offKeepAliveApiCallback(name) {
UniServiceJSBridge.off('api.' + name);
}
function onKeepAliveApiCallback(name) {
UniServiceJSBridge.on('api.' + name, (res) => {
for (const key in invokeCallbacks) {
const opts = invokeCallbacks[key];
if (opts.name === name) {
opts.callback(res);
}
}
});
}
function createKeepAliveApiCallback(name, callback) {
if (name.indexOf('off') === 0) {
return getKeepAliveApiCallback(name, callback);
}
const id = invokeCallbackId++;
return addInvokeCallback(id, createInvokeCallbackName(name, id), callback, true);
return addInvokeCallback(invokeCallbackId++, name, callback, true);
}
function getApiCallbacks(args) {
const apiCallbacks = {};
......@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const hasFail = isFunction(fail);
const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => {
addInvokeCallback(callbackId, name, (res) => {
res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res);
......@@ -250,9 +261,10 @@ function handlePromise(promise) {
}
const API_TYPE_ON = 0;
const API_TYPE_TASK = 1;
const API_TYPE_SYNC = 2;
const API_TYPE_ASYNC = 3;
const API_TYPE_OFF = 1;
const API_TYPE_TASK = 2;
const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) {
const params = args[0];
if (!options ||
......@@ -266,7 +278,27 @@ function formatApiArgs(args, options) {
return args;
}
function wrapperOnApi(name, fn) {
return (callback) => fn.apply(null, createKeepAliveApiCallback(name, callback));
return (callback) => {
// 是否是首次调用on,如果是首次,需要初始化onMethod监听
const isFirstInvokeOnApi = !findInvokeCallbackByName(name);
createKeepAliveApiCallback(name, callback);
if (isFirstInvokeOnApi) {
onKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperOffApi(name, fn) {
return (callback) => {
name = name.replace('off', 'on');
removeKeepAliveApiCallback(name, callback);
// 是否还存在监听,若已不存在,则移除onMethod监听
const hasInvokeOnApi = findInvokeCallbackByName(name);
if (!hasInvokeOnApi) {
offKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
......@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) {
case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC:
......
......@@ -154,9 +154,6 @@ function tryCatch(fn) {
let invokeCallbackId = 1;
const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return 'api.' + name + '.' + callbackId;
}
function addInvokeCallback(id, name, callback, keepAlive = false) {
invokeCallbacks[id] = {
name,
......@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) {
}
return res;
}
function getKeepAliveApiCallback(name, callback) {
const onName = 'api.' + name.replace('off', 'on');
function findInvokeCallbackByName(name) {
for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) {
const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) {
if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key];
return Number(key);
}
}
return -1;
}
function offKeepAliveApiCallback(name) {
UniServiceJSBridge.off('api.' + name);
}
function onKeepAliveApiCallback(name) {
UniServiceJSBridge.on('api.' + name, (res) => {
for (const key in invokeCallbacks) {
const opts = invokeCallbacks[key];
if (opts.name === name) {
opts.callback(res);
}
}
});
}
function createKeepAliveApiCallback(name, callback) {
if (name.indexOf('off') === 0) {
return getKeepAliveApiCallback(name, callback);
}
const id = invokeCallbackId++;
return addInvokeCallback(id, createInvokeCallbackName(name, id), callback, true);
return addInvokeCallback(invokeCallbackId++, name, callback, true);
}
function getApiCallbacks(args) {
const apiCallbacks = {};
......@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const hasFail = isFunction(fail);
const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => {
addInvokeCallback(callbackId, name, (res) => {
res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res);
......@@ -250,9 +261,10 @@ function handlePromise(promise) {
}
const API_TYPE_ON = 0;
const API_TYPE_TASK = 1;
const API_TYPE_SYNC = 2;
const API_TYPE_ASYNC = 3;
const API_TYPE_OFF = 1;
const API_TYPE_TASK = 2;
const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) {
const params = args[0];
if (!options ||
......@@ -266,7 +278,27 @@ function formatApiArgs(args, options) {
return args;
}
function wrapperOnApi(name, fn) {
return (callback) => fn.apply(null, createKeepAliveApiCallback(name, callback));
return (callback) => {
// 是否是首次调用on,如果是首次,需要初始化onMethod监听
const isFirstInvokeOnApi = !findInvokeCallbackByName(name);
createKeepAliveApiCallback(name, callback);
if (isFirstInvokeOnApi) {
onKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperOffApi(name, fn) {
return (callback) => {
name = name.replace('off', 'on');
removeKeepAliveApiCallback(name, callback);
// 是否还存在监听,若已不存在,则移除onMethod监听
const hasInvokeOnApi = findInvokeCallbackByName(name);
if (!hasInvokeOnApi) {
offKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
......@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) {
case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC:
......
......@@ -154,9 +154,6 @@ function tryCatch(fn) {
let invokeCallbackId = 1;
const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return 'api.' + name + '.' + callbackId;
}
function addInvokeCallback(id, name, callback, keepAlive = false) {
invokeCallbacks[id] = {
name,
......@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) {
}
return res;
}
function getKeepAliveApiCallback(name, callback) {
const onName = 'api.' + name.replace('off', 'on');
function findInvokeCallbackByName(name) {
for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) {
const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) {
if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key];
return Number(key);
}
}
return -1;
}
function offKeepAliveApiCallback(name) {
UniServiceJSBridge.off('api.' + name);
}
function onKeepAliveApiCallback(name) {
UniServiceJSBridge.on('api.' + name, (res) => {
for (const key in invokeCallbacks) {
const opts = invokeCallbacks[key];
if (opts.name === name) {
opts.callback(res);
}
}
});
}
function createKeepAliveApiCallback(name, callback) {
if (name.indexOf('off') === 0) {
return getKeepAliveApiCallback(name, callback);
}
const id = invokeCallbackId++;
return addInvokeCallback(id, createInvokeCallbackName(name, id), callback, true);
return addInvokeCallback(invokeCallbackId++, name, callback, true);
}
function getApiCallbacks(args) {
const apiCallbacks = {};
......@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const hasFail = isFunction(fail);
const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => {
addInvokeCallback(callbackId, name, (res) => {
res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res);
......@@ -250,9 +261,10 @@ function handlePromise(promise) {
}
const API_TYPE_ON = 0;
const API_TYPE_TASK = 1;
const API_TYPE_SYNC = 2;
const API_TYPE_ASYNC = 3;
const API_TYPE_OFF = 1;
const API_TYPE_TASK = 2;
const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) {
const params = args[0];
if (!options ||
......@@ -266,7 +278,27 @@ function formatApiArgs(args, options) {
return args;
}
function wrapperOnApi(name, fn) {
return (callback) => fn.apply(null, createKeepAliveApiCallback(name, callback));
return (callback) => {
// 是否是首次调用on,如果是首次,需要初始化onMethod监听
const isFirstInvokeOnApi = !findInvokeCallbackByName(name);
createKeepAliveApiCallback(name, callback);
if (isFirstInvokeOnApi) {
onKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperOffApi(name, fn) {
return (callback) => {
name = name.replace('off', 'on');
removeKeepAliveApiCallback(name, callback);
// 是否还存在监听,若已不存在,则移除onMethod监听
const hasInvokeOnApi = findInvokeCallbackByName(name);
if (!hasInvokeOnApi) {
offKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
......@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) {
case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC:
......
......@@ -154,9 +154,6 @@ function tryCatch(fn) {
let invokeCallbackId = 1;
const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return 'api.' + name + '.' + callbackId;
}
function addInvokeCallback(id, name, callback, keepAlive = false) {
invokeCallbacks[id] = {
name,
......@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) {
}
return res;
}
function getKeepAliveApiCallback(name, callback) {
const onName = 'api.' + name.replace('off', 'on');
function findInvokeCallbackByName(name) {
for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) {
const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) {
if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key];
return Number(key);
}
}
return -1;
}
function offKeepAliveApiCallback(name) {
UniServiceJSBridge.off('api.' + name);
}
function onKeepAliveApiCallback(name) {
UniServiceJSBridge.on('api.' + name, (res) => {
for (const key in invokeCallbacks) {
const opts = invokeCallbacks[key];
if (opts.name === name) {
opts.callback(res);
}
}
});
}
function createKeepAliveApiCallback(name, callback) {
if (name.indexOf('off') === 0) {
return getKeepAliveApiCallback(name, callback);
}
const id = invokeCallbackId++;
return addInvokeCallback(id, createInvokeCallbackName(name, id), callback, true);
return addInvokeCallback(invokeCallbackId++, name, callback, true);
}
function getApiCallbacks(args) {
const apiCallbacks = {};
......@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const hasFail = isFunction(fail);
const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => {
addInvokeCallback(callbackId, name, (res) => {
res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res);
......@@ -250,9 +261,10 @@ function handlePromise(promise) {
}
const API_TYPE_ON = 0;
const API_TYPE_TASK = 1;
const API_TYPE_SYNC = 2;
const API_TYPE_ASYNC = 3;
const API_TYPE_OFF = 1;
const API_TYPE_TASK = 2;
const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) {
const params = args[0];
if (!options ||
......@@ -266,7 +278,27 @@ function formatApiArgs(args, options) {
return args;
}
function wrapperOnApi(name, fn) {
return (callback) => fn.apply(null, createKeepAliveApiCallback(name, callback));
return (callback) => {
// 是否是首次调用on,如果是首次,需要初始化onMethod监听
const isFirstInvokeOnApi = !findInvokeCallbackByName(name);
createKeepAliveApiCallback(name, callback);
if (isFirstInvokeOnApi) {
onKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperOffApi(name, fn) {
return (callback) => {
name = name.replace('off', 'on');
removeKeepAliveApiCallback(name, callback);
// 是否还存在监听,若已不存在,则移除onMethod监听
const hasInvokeOnApi = findInvokeCallbackByName(name);
if (!hasInvokeOnApi) {
offKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
......@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) {
case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC:
......
......@@ -154,9 +154,6 @@ function tryCatch(fn) {
let invokeCallbackId = 1;
const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return 'api.' + name + '.' + callbackId;
}
function addInvokeCallback(id, name, callback, keepAlive = false) {
invokeCallbacks[id] = {
name,
......@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) {
}
return res;
}
function getKeepAliveApiCallback(name, callback) {
const onName = 'api.' + name.replace('off', 'on');
function findInvokeCallbackByName(name) {
for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) {
const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) {
if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key];
return Number(key);
}
}
return -1;
}
function offKeepAliveApiCallback(name) {
UniServiceJSBridge.off('api.' + name);
}
function onKeepAliveApiCallback(name) {
UniServiceJSBridge.on('api.' + name, (res) => {
for (const key in invokeCallbacks) {
const opts = invokeCallbacks[key];
if (opts.name === name) {
opts.callback(res);
}
}
});
}
function createKeepAliveApiCallback(name, callback) {
if (name.indexOf('off') === 0) {
return getKeepAliveApiCallback(name, callback);
}
const id = invokeCallbackId++;
return addInvokeCallback(id, createInvokeCallbackName(name, id), callback, true);
return addInvokeCallback(invokeCallbackId++, name, callback, true);
}
function getApiCallbacks(args) {
const apiCallbacks = {};
......@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const hasFail = isFunction(fail);
const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => {
addInvokeCallback(callbackId, name, (res) => {
res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res);
......@@ -250,9 +261,10 @@ function handlePromise(promise) {
}
const API_TYPE_ON = 0;
const API_TYPE_TASK = 1;
const API_TYPE_SYNC = 2;
const API_TYPE_ASYNC = 3;
const API_TYPE_OFF = 1;
const API_TYPE_TASK = 2;
const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) {
const params = args[0];
if (!options ||
......@@ -266,7 +278,27 @@ function formatApiArgs(args, options) {
return args;
}
function wrapperOnApi(name, fn) {
return (callback) => fn.apply(null, createKeepAliveApiCallback(name, callback));
return (callback) => {
// 是否是首次调用on,如果是首次,需要初始化onMethod监听
const isFirstInvokeOnApi = !findInvokeCallbackByName(name);
createKeepAliveApiCallback(name, callback);
if (isFirstInvokeOnApi) {
onKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperOffApi(name, fn) {
return (callback) => {
name = name.replace('off', 'on');
removeKeepAliveApiCallback(name, callback);
// 是否还存在监听,若已不存在,则移除onMethod监听
const hasInvokeOnApi = findInvokeCallbackByName(name);
if (!hasInvokeOnApi) {
offKeepAliveApiCallback(name);
fn();
}
};
}
function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
......@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) {
case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC:
......
......@@ -337,10 +337,10 @@
exec-sh "^0.3.2"
minimist "^1.2.0"
"@dcloudio/types@^2.0.24":
version "2.0.24"
resolved "https://registry.yarnpkg.com/@dcloudio/types/-/types-2.0.24.tgz#ed7ba22dd7604e67a7ccd3949f95055f042983e1"
integrity sha512-R5bmKdsHv3cewuJs9eQL2nwdNzDMWic3DyJ75Atno2oti9MEk1DZqcuxu1T2VyjQnEOn85ACy/FXGsLGhInStA==
"@dcloudio/types@^2.0.25":
version "2.0.25"
resolved "https://registry.yarnpkg.com/@dcloudio/types/-/types-2.0.25.tgz#c8e3de361b722e2bd7e40e477c0b9626e3777b31"
integrity sha512-r+AlgylZVlX2OLepxuyKzB4mRtnfdcIrnzHWbJOgZ57WDpJEcrXpP1mO0JhRGz3ewehru7P6sAcbKqRYcTkeXw==
"@eslint/eslintrc@^0.4.0":
version "0.4.0"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册