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

feat: defineOnApi,defineOffApi

上级 059d3dc4
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
"node": ">=10.0.0" "node": ">=10.0.0"
}, },
"devDependencies": { "devDependencies": {
"@dcloudio/types": "^2.0.24", "@dcloudio/types": "^2.0.25",
"@microsoft/api-extractor": "^7.13.2", "@microsoft/api-extractor": "^7.13.2",
"@rollup/plugin-alias": "^3.1.1", "@rollup/plugin-alias": "^3.1.1",
"@rollup/plugin-commonjs": "^17.0.0", "@rollup/plugin-commonjs": "^17.0.0",
......
...@@ -35,7 +35,7 @@ declare var __UNI_FEATURE_NAVIGATIONBAR_TRANSPARENT__: boolean ...@@ -35,7 +35,7 @@ declare var __UNI_FEATURE_NAVIGATIONBAR_TRANSPARENT__: boolean
declare var __uniRoutes: UniApp.UniRoutes declare var __uniRoutes: UniApp.UniRoutes
declare var __uniConfig: UniApp.UniConfig declare var __uniConfig: UniApp.UniConfig
declare var UniViewJSBridge: any declare var UniViewJSBridge: any
declare var UniServiceJSBridge: any declare var UniServiceJSBridge: UniApp.UniServiceJSBridge
declare const getCurrentPages: <T extends AnyObject = {}>( declare const getCurrentPages: <T extends AnyObject = {}>(
isAll?: boolean isAll?: boolean
......
...@@ -163,4 +163,45 @@ declare namespace UniApp { ...@@ -163,4 +163,45 @@ declare namespace UniApp {
leftWindow?: PagesJsonWindowOptions leftWindow?: PagesJsonWindowOptions
rightWindow?: 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: { ...@@ -13,10 +13,6 @@ const invokeCallbacks: {
} }
} = {} } = {}
function createInvokeCallbackName(name: string, callbackId: number) {
return 'api.' + name + '.' + callbackId
}
function addInvokeCallback( function addInvokeCallback(
id: number, id: number,
name: string, name: string,
...@@ -45,29 +41,41 @@ export function invokeCallback(id: number, res: unknown, extras?: unknown) { ...@@ -45,29 +41,41 @@ export function invokeCallback(id: number, res: unknown, extras?: unknown) {
return res return res
} }
function getKeepAliveApiCallback(name: string, callback: Function) { export function findInvokeCallbackByName(name: string) {
const onName = 'api.' + name.replace('off', 'on') 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) { for (const key in invokeCallbacks) {
const item = invokeCallbacks[key] const item = invokeCallbacks[key]
if (item.callback === callback && item.name.indexOf(onName) === 0) { if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key] 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) { export function createKeepAliveApiCallback(name: string, callback: Function) {
if (name.indexOf('off') === 0) { return addInvokeCallback(invokeCallbackId++, name, callback, true)
return getKeepAliveApiCallback(name, callback)
}
const id = invokeCallbackId++
return addInvokeCallback(
id,
createInvokeCallbackName(name, id),
callback,
true
)
} }
export const API_SUCCESS = 'success' export const API_SUCCESS = 'success'
...@@ -117,21 +125,17 @@ export function createAsyncApiCallback( ...@@ -117,21 +125,17 @@ export function createAsyncApiCallback(
const hasFail = isFunction(fail) const hasFail = isFunction(fail)
const hasComplete = isFunction(complete) const hasComplete = isFunction(complete)
const callbackId = invokeCallbackId++ const callbackId = invokeCallbackId++
addInvokeCallback( addInvokeCallback(callbackId, name, (res: ApiRes) => {
callbackId, res = res || {}
createInvokeCallbackName(name, callbackId), res.errMsg = normalizeErrMsg(res.errMsg, name)
(res: ApiRes) => { isFunction(beforeAll) && beforeAll(res)
res = res || {} if (res.errMsg === name + ':ok') {
res.errMsg = normalizeErrMsg(res.errMsg, name) isFunction(beforeSuccess) && beforeSuccess(res)
isFunction(beforeAll) && beforeAll(res) hasSuccess && success!(res)
if (res.errMsg === name + ':ok') { } else {
isFunction(beforeSuccess) && beforeSuccess(res) hasFail && fail!(res)
hasSuccess && success!(res)
} else {
hasFail && fail!(res)
}
hasComplete && complete!(res)
} }
) hasComplete && complete!(res)
})
return callbackId return callbackId
} }
...@@ -4,17 +4,23 @@ import { API_TYPE_ON_PROTOCOLS, validateProtocols } from '../protocol' ...@@ -4,17 +4,23 @@ import { API_TYPE_ON_PROTOCOLS, validateProtocols } from '../protocol'
import { import {
invokeCallback, invokeCallback,
createAsyncApiCallback, createAsyncApiCallback,
onKeepAliveApiCallback,
offKeepAliveApiCallback,
findInvokeCallbackByName,
createKeepAliveApiCallback, createKeepAliveApiCallback,
removeKeepAliveApiCallback,
} from './callback' } from './callback'
import { promisify } from './promise' import { promisify } from './promise'
export const API_TYPE_ON = 0 export const API_TYPE_ON = 0
export const API_TYPE_TASK = 1 export const API_TYPE_OFF = 1
export const API_TYPE_SYNC = 2 export const API_TYPE_TASK = 2
export const API_TYPE_ASYNC = 3 export const API_TYPE_SYNC = 3
export const API_TYPE_ASYNC = 4
type API_TYPES = type API_TYPES =
| typeof API_TYPE_ON | typeof API_TYPE_ON
| typeof API_TYPE_OFF
| typeof API_TYPE_TASK | typeof API_TYPE_TASK
| typeof API_TYPE_SYNC | typeof API_TYPE_SYNC
| typeof API_TYPE_ASYNC | typeof API_TYPE_ASYNC
...@@ -35,8 +41,28 @@ function formatApiArgs(args: any[], options?: ApiOptions) { ...@@ -35,8 +41,28 @@ function formatApiArgs(args: any[], options?: ApiOptions) {
} }
function wrapperOnApi(name: string, fn: Function) { function wrapperOnApi(name: string, fn: Function) {
return (callback: Function) => return (callback: Function) => {
fn.apply(null, createKeepAliveApiCallback(name, callback)) // 是否是首次调用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) { function wrapperTaskApi(name: string, fn: Function, options?: ApiOptions) {
...@@ -96,6 +122,20 @@ export function defineOnApi<T extends Function>( ...@@ -96,6 +122,20 @@ export function defineOnApi<T extends Function>(
) as T ) 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>( export function defineTaskApi<T extends Function>(
name: string, name: string,
fn: T, fn: T,
...@@ -190,6 +230,8 @@ function defineApi( ...@@ -190,6 +230,8 @@ function defineApi(
switch (type) { switch (type) {
case API_TYPE_ON: case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options) return wrapperApi(wrapperOnApi(name, fn), name, protocol, options)
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options)
case API_TYPE_TASK: case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options) return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options)
case API_TYPE_SYNC: case API_TYPE_SYNC:
......
...@@ -25,6 +25,7 @@ export * from './protocols/route/route' ...@@ -25,6 +25,7 @@ export * from './protocols/route/route'
// helpers // helpers
export { export {
defineOnApi, defineOnApi,
defineOffApi,
defineTaskApi, defineTaskApi,
defineSyncApi, defineSyncApi,
defineAsyncApi, 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 // TODO vue3 compatibility builds
const { on, off, emit } = { const emitter = new E()
on(event: string, callback: Handler) { return extend(emitter, {
console.log(event, callback) subscribe(event: string, callback: Function): void {
return emitter.on(`${namespace}.${event}`, callback)
}, },
off(event: string, callback: Handler) { unsubscribe(event: string, callback: Function): void {
console.log(event, callback) return emitter.off(`${namespace}.${event}`, callback)
}, },
emit(event: string, ...args: any[]) { subscribeHandler(event: string, args: unknown, pageId: number): void {
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) {
if (__DEV__) { if (__DEV__) {
console.log( console.log(
`[${namespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify( `[${namespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify(
...@@ -31,7 +22,7 @@ export function initBridge(namespace: 'service' | 'view') { ...@@ -31,7 +22,7 @@ export function initBridge(namespace: 'service' | 'view') {
)}, ${pageId}` )}, ${pageId}`
) )
} }
return emit(`${namespace}.${event}`, args, pageId) return emitter.emit(`${namespace}.${event}`, args, pageId)
}, },
} })
} }
import { extend } from '@vue/shared'
import { initBridge } from '../../helpers/bridge' 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) { ...@@ -55,35 +55,66 @@ function initApp$1(app) {
globalProperties.$applyOptions = applyOptions; globalProperties.$applyOptions = applyOptions;
} }
} }
function initBridge(namespace) { function E() {
const {on, off, emit} = { }
on(event2, callback) { E.prototype = {
console.log(event2, callback); on: function(name, callback, ctx) {
}, var e2 = this.e || (this.e = {});
off(event2, callback) { (e2[name] || (e2[name] = [])).push({
console.log(event2, callback); fn: callback,
}, ctx
emit(event2, ...args) { });
console.log(event2, args); return this;
},
once: function(name, callback, ctx) {
var self = this;
function listener() {
self.off(name, listener);
callback.apply(ctx, arguments);
} }
}; listener._ = callback;
return { return this.on(name, listener, ctx);
on, },
off, emit: function(name) {
emit, 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) { subscribe(event2, callback) {
return on(`${namespace}.${event2}`, callback); return emitter2.on(`${namespace}.${event2}`, callback);
}, },
unsubscribe(event2, callback) { unsubscribe(event2, callback) {
return off(`${namespace}.${event2}`, callback); return emitter2.off(`${namespace}.${event2}`, callback);
}, },
subscribeHandler(event2, args, pageId) { subscribeHandler(event2, args, pageId) {
if (process.env.NODE_ENV !== "production") { if (process.env.NODE_ENV !== "production") {
console.log(`[${namespace}][subscribeHandler][${Date.now()}]:${event2}, ${JSON.stringify(args)}, ${pageId}`); 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 ViewJSBridge = initBridge("view");
const LONGPRESS_TIMEOUT = 350; const LONGPRESS_TIMEOUT = 350;
...@@ -639,7 +670,11 @@ function initView(app) { ...@@ -639,7 +670,11 @@ function initView(app) {
} }
initAppConfig$1(app._context.config); 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) { function querySelector(vm, selector) {
const el = vm.$el.querySelector(selector); const el = vm.$el.querySelector(selector);
return el && el.__vue__; return el && el.__vue__;
...@@ -7483,6 +7518,13 @@ function decode(base64) { ...@@ -7483,6 +7518,13 @@ function decode(base64) {
} }
return arraybuffer; return arraybuffer;
} }
const API_TYPE_ON_PROTOCOLS = [
{
name: "callback",
type: Function,
required: true
}
];
function validateProtocolFail(name, msg) { function validateProtocolFail(name, msg) {
const errMsg = `${name}:fail ${msg}`; const errMsg = `${name}:fail ${msg}`;
{ {
...@@ -7617,9 +7659,6 @@ function tryCatch(fn) { ...@@ -7617,9 +7659,6 @@ function tryCatch(fn) {
} }
let invokeCallbackId = 1; let invokeCallbackId = 1;
const invokeCallbacks = {}; const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return "api." + name + "." + callbackId;
}
function addInvokeCallback(id2, name, callback, keepAlive = false) { function addInvokeCallback(id2, name, callback, keepAlive = false) {
invokeCallbacks[id2] = { invokeCallbacks[id2] = {
name, name,
...@@ -7640,23 +7679,37 @@ function invokeCallback(id2, res, extras) { ...@@ -7640,23 +7679,37 @@ function invokeCallback(id2, res, extras) {
} }
return res; return res;
} }
function getKeepAliveApiCallback(name, callback) { function findInvokeCallbackByName(name) {
const onName = "api." + name.replace("off", "on"); for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) { for (const key in invokeCallbacks) {
const item = invokeCallbacks[key]; const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) { if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key]; 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) { function createKeepAliveApiCallback(name, callback) {
if (name.indexOf("off") === 0) { return addInvokeCallback(invokeCallbackId++, name, callback, true);
return getKeepAliveApiCallback(name, callback);
}
const id2 = invokeCallbackId++;
return addInvokeCallback(id2, createInvokeCallbackName(name, id2), callback, true);
} }
const API_SUCCESS = "success"; const API_SUCCESS = "success";
const API_FAIL = "fail"; const API_FAIL = "fail";
...@@ -7687,7 +7740,7 @@ function createAsyncApiCallback(name, args = {}, {beforeAll, beforeSuccess} = {} ...@@ -7687,7 +7740,7 @@ function createAsyncApiCallback(name, args = {}, {beforeAll, beforeSuccess} = {}
const hasFail = isFunction(fail); const hasFail = isFunction(fail);
const hasComplete = isFunction(complete); const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++; const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => { addInvokeCallback(callbackId, name, (res) => {
res = res || {}; res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name); res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res); isFunction(beforeAll) && beforeAll(res);
...@@ -7727,9 +7780,10 @@ function promisify(fn) { ...@@ -7727,9 +7780,10 @@ function promisify(fn) {
}; };
} }
const API_TYPE_ON = 0; const API_TYPE_ON = 0;
const API_TYPE_TASK = 1; const API_TYPE_OFF = 1;
const API_TYPE_SYNC = 2; const API_TYPE_TASK = 2;
const API_TYPE_ASYNC = 3; const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) { function formatApiArgs(args, options) {
const params = args[0]; const params = args[0];
if (!options || !isPlainObject(options.formatArgs) && isPlainObject(params)) { if (!options || !isPlainObject(options.formatArgs) && isPlainObject(params)) {
...@@ -7742,7 +7796,25 @@ function formatApiArgs(args, options) { ...@@ -7742,7 +7796,25 @@ function formatApiArgs(args, options) {
return args; return args;
} }
function wrapperOnApi(name, fn) { 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) { function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]); return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
...@@ -7771,6 +7843,12 @@ function wrapperApi(fn, name, protocol, options) { ...@@ -7771,6 +7843,12 @@ function wrapperApi(fn, name, protocol, options) {
return fn.apply(null, formatApiArgs(args, 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) { function defineSyncApi(name, fn, protocol, options) {
return defineApi(API_TYPE_SYNC, name, fn, process.env.NODE_ENV !== "production" ? protocol : void 0, 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) { ...@@ -7781,6 +7859,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) { switch (type) {
case API_TYPE_ON: case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK: case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC: case API_TYPE_SYNC:
...@@ -8332,6 +8412,51 @@ const getSystemInfoSync = defineSyncApi("getSystemInfoSync", () => { ...@@ -8332,6 +8412,51 @@ const getSystemInfoSync = defineSyncApi("getSystemInfoSync", () => {
const getSystemInfo = defineAsyncApi("getSystemInfo", () => { const getSystemInfo = defineAsyncApi("getSystemInfo", () => {
return Promise.resolve(getSystemInfoSync()); 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}) => { const openDocument = defineAsyncApi(API_OPEN_DOCUMENT, ({filePath}) => {
window.open(filePath); window.open(filePath);
return Promise.resolve(); return Promise.resolve();
...@@ -8401,6 +8526,9 @@ var api = /* @__PURE__ */ Object.freeze({ ...@@ -8401,6 +8526,9 @@ var api = /* @__PURE__ */ Object.freeze({
makePhoneCall, makePhoneCall,
getSystemInfo, getSystemInfo,
getSystemInfoSync, getSystemInfoSync,
onNetworkStatusChange,
offNetworkStatusChange,
getNetworkType,
openDocument, openDocument,
getImageInfo, getImageInfo,
navigateBack, navigateBack,
...@@ -9516,4 +9644,4 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { ...@@ -9516,4 +9644,4 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
]); ]);
} }
_sfc_main.render = _sfc_render; _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' ...@@ -3,6 +3,7 @@ export * from './base/canIUse'
export * from './device/makePhoneCall' export * from './device/makePhoneCall'
export * from './device/getSystemInfo' export * from './device/getSystemInfo'
export * from './device/getSystemInfoSync' export * from './device/getSystemInfoSync'
export * from './device/network'
export * from './file/openDocument' export * from './file/openDocument'
......
...@@ -154,9 +154,6 @@ function tryCatch(fn) { ...@@ -154,9 +154,6 @@ function tryCatch(fn) {
let invokeCallbackId = 1; let invokeCallbackId = 1;
const invokeCallbacks = {}; const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return 'api.' + name + '.' + callbackId;
}
function addInvokeCallback(id, name, callback, keepAlive = false) { function addInvokeCallback(id, name, callback, keepAlive = false) {
invokeCallbacks[id] = { invokeCallbacks[id] = {
name, name,
...@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) { ...@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) {
} }
return res; return res;
} }
function getKeepAliveApiCallback(name, callback) { function findInvokeCallbackByName(name) {
const onName = 'api.' + name.replace('off', 'on'); for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) { for (const key in invokeCallbacks) {
const item = invokeCallbacks[key]; const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) { if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key]; 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) { function createKeepAliveApiCallback(name, callback) {
if (name.indexOf('off') === 0) { return addInvokeCallback(invokeCallbackId++, name, callback, true);
return getKeepAliveApiCallback(name, callback);
}
const id = invokeCallbackId++;
return addInvokeCallback(id, createInvokeCallbackName(name, id), callback, true);
} }
function getApiCallbacks(args) { function getApiCallbacks(args) {
const apiCallbacks = {}; const apiCallbacks = {};
...@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } = ...@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const hasFail = isFunction(fail); const hasFail = isFunction(fail);
const hasComplete = isFunction(complete); const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++; const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => { addInvokeCallback(callbackId, name, (res) => {
res = res || {}; res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name); res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res); isFunction(beforeAll) && beforeAll(res);
...@@ -250,9 +261,10 @@ function handlePromise(promise) { ...@@ -250,9 +261,10 @@ function handlePromise(promise) {
} }
const API_TYPE_ON = 0; const API_TYPE_ON = 0;
const API_TYPE_TASK = 1; const API_TYPE_OFF = 1;
const API_TYPE_SYNC = 2; const API_TYPE_TASK = 2;
const API_TYPE_ASYNC = 3; const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) { function formatApiArgs(args, options) {
const params = args[0]; const params = args[0];
if (!options || if (!options ||
...@@ -266,7 +278,27 @@ function formatApiArgs(args, options) { ...@@ -266,7 +278,27 @@ function formatApiArgs(args, options) {
return args; return args;
} }
function wrapperOnApi(name, fn) { 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) { function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]); return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
...@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) { ...@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) { switch (type) {
case API_TYPE_ON: case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK: case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC: case API_TYPE_SYNC:
......
...@@ -154,9 +154,6 @@ function tryCatch(fn) { ...@@ -154,9 +154,6 @@ function tryCatch(fn) {
let invokeCallbackId = 1; let invokeCallbackId = 1;
const invokeCallbacks = {}; const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return 'api.' + name + '.' + callbackId;
}
function addInvokeCallback(id, name, callback, keepAlive = false) { function addInvokeCallback(id, name, callback, keepAlive = false) {
invokeCallbacks[id] = { invokeCallbacks[id] = {
name, name,
...@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) { ...@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) {
} }
return res; return res;
} }
function getKeepAliveApiCallback(name, callback) { function findInvokeCallbackByName(name) {
const onName = 'api.' + name.replace('off', 'on'); for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) { for (const key in invokeCallbacks) {
const item = invokeCallbacks[key]; const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) { if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key]; 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) { function createKeepAliveApiCallback(name, callback) {
if (name.indexOf('off') === 0) { return addInvokeCallback(invokeCallbackId++, name, callback, true);
return getKeepAliveApiCallback(name, callback);
}
const id = invokeCallbackId++;
return addInvokeCallback(id, createInvokeCallbackName(name, id), callback, true);
} }
function getApiCallbacks(args) { function getApiCallbacks(args) {
const apiCallbacks = {}; const apiCallbacks = {};
...@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } = ...@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const hasFail = isFunction(fail); const hasFail = isFunction(fail);
const hasComplete = isFunction(complete); const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++; const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => { addInvokeCallback(callbackId, name, (res) => {
res = res || {}; res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name); res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res); isFunction(beforeAll) && beforeAll(res);
...@@ -250,9 +261,10 @@ function handlePromise(promise) { ...@@ -250,9 +261,10 @@ function handlePromise(promise) {
} }
const API_TYPE_ON = 0; const API_TYPE_ON = 0;
const API_TYPE_TASK = 1; const API_TYPE_OFF = 1;
const API_TYPE_SYNC = 2; const API_TYPE_TASK = 2;
const API_TYPE_ASYNC = 3; const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) { function formatApiArgs(args, options) {
const params = args[0]; const params = args[0];
if (!options || if (!options ||
...@@ -266,7 +278,27 @@ function formatApiArgs(args, options) { ...@@ -266,7 +278,27 @@ function formatApiArgs(args, options) {
return args; return args;
} }
function wrapperOnApi(name, fn) { 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) { function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]); return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
...@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) { ...@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) { switch (type) {
case API_TYPE_ON: case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK: case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC: case API_TYPE_SYNC:
......
...@@ -154,9 +154,6 @@ function tryCatch(fn) { ...@@ -154,9 +154,6 @@ function tryCatch(fn) {
let invokeCallbackId = 1; let invokeCallbackId = 1;
const invokeCallbacks = {}; const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return 'api.' + name + '.' + callbackId;
}
function addInvokeCallback(id, name, callback, keepAlive = false) { function addInvokeCallback(id, name, callback, keepAlive = false) {
invokeCallbacks[id] = { invokeCallbacks[id] = {
name, name,
...@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) { ...@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) {
} }
return res; return res;
} }
function getKeepAliveApiCallback(name, callback) { function findInvokeCallbackByName(name) {
const onName = 'api.' + name.replace('off', 'on'); for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) { for (const key in invokeCallbacks) {
const item = invokeCallbacks[key]; const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) { if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key]; 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) { function createKeepAliveApiCallback(name, callback) {
if (name.indexOf('off') === 0) { return addInvokeCallback(invokeCallbackId++, name, callback, true);
return getKeepAliveApiCallback(name, callback);
}
const id = invokeCallbackId++;
return addInvokeCallback(id, createInvokeCallbackName(name, id), callback, true);
} }
function getApiCallbacks(args) { function getApiCallbacks(args) {
const apiCallbacks = {}; const apiCallbacks = {};
...@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } = ...@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const hasFail = isFunction(fail); const hasFail = isFunction(fail);
const hasComplete = isFunction(complete); const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++; const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => { addInvokeCallback(callbackId, name, (res) => {
res = res || {}; res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name); res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res); isFunction(beforeAll) && beforeAll(res);
...@@ -250,9 +261,10 @@ function handlePromise(promise) { ...@@ -250,9 +261,10 @@ function handlePromise(promise) {
} }
const API_TYPE_ON = 0; const API_TYPE_ON = 0;
const API_TYPE_TASK = 1; const API_TYPE_OFF = 1;
const API_TYPE_SYNC = 2; const API_TYPE_TASK = 2;
const API_TYPE_ASYNC = 3; const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) { function formatApiArgs(args, options) {
const params = args[0]; const params = args[0];
if (!options || if (!options ||
...@@ -266,7 +278,27 @@ function formatApiArgs(args, options) { ...@@ -266,7 +278,27 @@ function formatApiArgs(args, options) {
return args; return args;
} }
function wrapperOnApi(name, fn) { 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) { function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]); return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
...@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) { ...@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) { switch (type) {
case API_TYPE_ON: case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK: case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC: case API_TYPE_SYNC:
......
...@@ -154,9 +154,6 @@ function tryCatch(fn) { ...@@ -154,9 +154,6 @@ function tryCatch(fn) {
let invokeCallbackId = 1; let invokeCallbackId = 1;
const invokeCallbacks = {}; const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return 'api.' + name + '.' + callbackId;
}
function addInvokeCallback(id, name, callback, keepAlive = false) { function addInvokeCallback(id, name, callback, keepAlive = false) {
invokeCallbacks[id] = { invokeCallbacks[id] = {
name, name,
...@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) { ...@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) {
} }
return res; return res;
} }
function getKeepAliveApiCallback(name, callback) { function findInvokeCallbackByName(name) {
const onName = 'api.' + name.replace('off', 'on'); for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) { for (const key in invokeCallbacks) {
const item = invokeCallbacks[key]; const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) { if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key]; 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) { function createKeepAliveApiCallback(name, callback) {
if (name.indexOf('off') === 0) { return addInvokeCallback(invokeCallbackId++, name, callback, true);
return getKeepAliveApiCallback(name, callback);
}
const id = invokeCallbackId++;
return addInvokeCallback(id, createInvokeCallbackName(name, id), callback, true);
} }
function getApiCallbacks(args) { function getApiCallbacks(args) {
const apiCallbacks = {}; const apiCallbacks = {};
...@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } = ...@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const hasFail = isFunction(fail); const hasFail = isFunction(fail);
const hasComplete = isFunction(complete); const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++; const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => { addInvokeCallback(callbackId, name, (res) => {
res = res || {}; res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name); res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res); isFunction(beforeAll) && beforeAll(res);
...@@ -250,9 +261,10 @@ function handlePromise(promise) { ...@@ -250,9 +261,10 @@ function handlePromise(promise) {
} }
const API_TYPE_ON = 0; const API_TYPE_ON = 0;
const API_TYPE_TASK = 1; const API_TYPE_OFF = 1;
const API_TYPE_SYNC = 2; const API_TYPE_TASK = 2;
const API_TYPE_ASYNC = 3; const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) { function formatApiArgs(args, options) {
const params = args[0]; const params = args[0];
if (!options || if (!options ||
...@@ -266,7 +278,27 @@ function formatApiArgs(args, options) { ...@@ -266,7 +278,27 @@ function formatApiArgs(args, options) {
return args; return args;
} }
function wrapperOnApi(name, fn) { 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) { function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]); return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
...@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) { ...@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) { switch (type) {
case API_TYPE_ON: case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK: case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC: case API_TYPE_SYNC:
......
...@@ -154,9 +154,6 @@ function tryCatch(fn) { ...@@ -154,9 +154,6 @@ function tryCatch(fn) {
let invokeCallbackId = 1; let invokeCallbackId = 1;
const invokeCallbacks = {}; const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return 'api.' + name + '.' + callbackId;
}
function addInvokeCallback(id, name, callback, keepAlive = false) { function addInvokeCallback(id, name, callback, keepAlive = false) {
invokeCallbacks[id] = { invokeCallbacks[id] = {
name, name,
...@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) { ...@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) {
} }
return res; return res;
} }
function getKeepAliveApiCallback(name, callback) { function findInvokeCallbackByName(name) {
const onName = 'api.' + name.replace('off', 'on'); for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) { for (const key in invokeCallbacks) {
const item = invokeCallbacks[key]; const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) { if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key]; 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) { function createKeepAliveApiCallback(name, callback) {
if (name.indexOf('off') === 0) { return addInvokeCallback(invokeCallbackId++, name, callback, true);
return getKeepAliveApiCallback(name, callback);
}
const id = invokeCallbackId++;
return addInvokeCallback(id, createInvokeCallbackName(name, id), callback, true);
} }
function getApiCallbacks(args) { function getApiCallbacks(args) {
const apiCallbacks = {}; const apiCallbacks = {};
...@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } = ...@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const hasFail = isFunction(fail); const hasFail = isFunction(fail);
const hasComplete = isFunction(complete); const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++; const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => { addInvokeCallback(callbackId, name, (res) => {
res = res || {}; res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name); res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res); isFunction(beforeAll) && beforeAll(res);
...@@ -250,9 +261,10 @@ function handlePromise(promise) { ...@@ -250,9 +261,10 @@ function handlePromise(promise) {
} }
const API_TYPE_ON = 0; const API_TYPE_ON = 0;
const API_TYPE_TASK = 1; const API_TYPE_OFF = 1;
const API_TYPE_SYNC = 2; const API_TYPE_TASK = 2;
const API_TYPE_ASYNC = 3; const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) { function formatApiArgs(args, options) {
const params = args[0]; const params = args[0];
if (!options || if (!options ||
...@@ -266,7 +278,27 @@ function formatApiArgs(args, options) { ...@@ -266,7 +278,27 @@ function formatApiArgs(args, options) {
return args; return args;
} }
function wrapperOnApi(name, fn) { 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) { function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]); return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
...@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) { ...@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) { switch (type) {
case API_TYPE_ON: case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK: case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC: case API_TYPE_SYNC:
......
...@@ -154,9 +154,6 @@ function tryCatch(fn) { ...@@ -154,9 +154,6 @@ function tryCatch(fn) {
let invokeCallbackId = 1; let invokeCallbackId = 1;
const invokeCallbacks = {}; const invokeCallbacks = {};
function createInvokeCallbackName(name, callbackId) {
return 'api.' + name + '.' + callbackId;
}
function addInvokeCallback(id, name, callback, keepAlive = false) { function addInvokeCallback(id, name, callback, keepAlive = false) {
invokeCallbacks[id] = { invokeCallbacks[id] = {
name, name,
...@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) { ...@@ -178,23 +175,37 @@ function invokeCallback(id, res, extras) {
} }
return res; return res;
} }
function getKeepAliveApiCallback(name, callback) { function findInvokeCallbackByName(name) {
const onName = 'api.' + name.replace('off', 'on'); for (const key in invokeCallbacks) {
if (invokeCallbacks[key].name === name) {
return true;
}
}
return false;
}
function removeKeepAliveApiCallback(name, callback) {
for (const key in invokeCallbacks) { for (const key in invokeCallbacks) {
const item = invokeCallbacks[key]; const item = invokeCallbacks[key];
if (item.callback === callback && item.name.indexOf(onName) === 0) { if (item.callback === callback && item.name === name) {
delete invokeCallbacks[key]; 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) { function createKeepAliveApiCallback(name, callback) {
if (name.indexOf('off') === 0) { return addInvokeCallback(invokeCallbackId++, name, callback, true);
return getKeepAliveApiCallback(name, callback);
}
const id = invokeCallbackId++;
return addInvokeCallback(id, createInvokeCallbackName(name, id), callback, true);
} }
function getApiCallbacks(args) { function getApiCallbacks(args) {
const apiCallbacks = {}; const apiCallbacks = {};
...@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } = ...@@ -222,7 +233,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const hasFail = isFunction(fail); const hasFail = isFunction(fail);
const hasComplete = isFunction(complete); const hasComplete = isFunction(complete);
const callbackId = invokeCallbackId++; const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, createInvokeCallbackName(name, callbackId), (res) => { addInvokeCallback(callbackId, name, (res) => {
res = res || {}; res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name); res.errMsg = normalizeErrMsg(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res); isFunction(beforeAll) && beforeAll(res);
...@@ -250,9 +261,10 @@ function handlePromise(promise) { ...@@ -250,9 +261,10 @@ function handlePromise(promise) {
} }
const API_TYPE_ON = 0; const API_TYPE_ON = 0;
const API_TYPE_TASK = 1; const API_TYPE_OFF = 1;
const API_TYPE_SYNC = 2; const API_TYPE_TASK = 2;
const API_TYPE_ASYNC = 3; const API_TYPE_SYNC = 3;
const API_TYPE_ASYNC = 4;
function formatApiArgs(args, options) { function formatApiArgs(args, options) {
const params = args[0]; const params = args[0];
if (!options || if (!options ||
...@@ -266,7 +278,27 @@ function formatApiArgs(args, options) { ...@@ -266,7 +278,27 @@ function formatApiArgs(args, options) {
return args; return args;
} }
function wrapperOnApi(name, fn) { 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) { function wrapperTaskApi(name, fn, options) {
return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]); return (args) => fn.apply(null, [args, createAsyncApiCallback(name, args, options)]);
...@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) { ...@@ -304,6 +336,8 @@ function defineApi(type, name, fn, protocol, options) {
switch (type) { switch (type) {
case API_TYPE_ON: case API_TYPE_ON:
return wrapperApi(wrapperOnApi(name, fn), name, protocol, options); return wrapperApi(wrapperOnApi(name, fn), name, protocol, options);
case API_TYPE_OFF:
return wrapperApi(wrapperOffApi(name, fn), name, protocol, options);
case API_TYPE_TASK: case API_TYPE_TASK:
return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options); return wrapperApi(wrapperTaskApi(name, fn), name, protocol, options);
case API_TYPE_SYNC: case API_TYPE_SYNC:
......
...@@ -337,10 +337,10 @@ ...@@ -337,10 +337,10 @@
exec-sh "^0.3.2" exec-sh "^0.3.2"
minimist "^1.2.0" minimist "^1.2.0"
"@dcloudio/types@^2.0.24": "@dcloudio/types@^2.0.25":
version "2.0.24" version "2.0.25"
resolved "https://registry.yarnpkg.com/@dcloudio/types/-/types-2.0.24.tgz#ed7ba22dd7604e67a7ccd3949f95055f042983e1" resolved "https://registry.yarnpkg.com/@dcloudio/types/-/types-2.0.25.tgz#c8e3de361b722e2bd7e40e477c0b9626e3777b31"
integrity sha512-R5bmKdsHv3cewuJs9eQL2nwdNzDMWic3DyJ75Atno2oti9MEk1DZqcuxu1T2VyjQnEOn85ACy/FXGsLGhInStA== integrity sha512-r+AlgylZVlX2OLepxuyKzB4mRtnfdcIrnzHWbJOgZ57WDpJEcrXpP1mO0JhRGz3ewehru7P6sAcbKqRYcTkeXw==
"@eslint/eslintrc@^0.4.0": "@eslint/eslintrc@^0.4.0":
version "0.4.0" version "0.4.0"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册