提交 0f19e6d9 编写于 作者: fxy060608's avatar fxy060608

wip(uts): compiler

上级 b1e03a7e
// @ts-expect-error
const proxy = uni.requireNativePlugin('proxy-module')
// @ts-expect-error
const moduleName = __MODULE_NAME__
// @ts-expect-error
const moduleDefine = __MODULE_DEFINE__
const moduleName = '__MODULE_NAME__'
const moduleDefine = '__MODULE_DEFINE__'
var module = initModule(moduleDefine)
let callbackId = 0
let callbackId = 1
const objectToString = Object.prototype.toString
const toTypeString = (value) => objectToString.call(value)
const isPlainObject = (val) => toTypeString(val) === '[object Object]'
const callbacks = {}
function normalizeArg(arg) {
if (typeof arg === 'function') {
const id = callbackId++
callbacks[id] = arg
return {
type: 'function',
value: callbackId++,
$$type: 'function',
value: id,
}
} else if (isPlainObject(arg)) {
Object.keys(arg).forEach((name) => {
......@@ -22,19 +21,60 @@ function normalizeArg(arg) {
}
return arg
}
function moduleGetter(module, method) {
function isProxyInvokeCallbackResponse(res) {
return !!res.name
}
function moduleGetter(proxy, module, method, defines) {
const invokeCallback = ({ id, name, params, keepAlive }) => {
const callback = callbacks[id]
if (callback) {
callback(...params)
if (!keepAlive) {
delete callbacks[id]
}
} else {
console.error(`${module}.${method} ${name} is not found`)
}
}
return (...args) => {
const params = args.map((arg) => normalizeArg(arg))
proxy.invoke({ module, method, params }, () => {})
const invokeArgs = { module, method, params, async: !!defines.async }
if (defines.async) {
return new Promise((resolve, reject) => {
proxy.invoke(invokeArgs, (res) => {
if (isProxyInvokeCallbackResponse(res)) {
invokeCallback(res)
} else {
if (res.errMsg) {
reject(res.errMsg)
} else {
resolve(res.params)
}
}
})
})
}
return proxy.invoke(invokeArgs, invokeCallback)
}
}
function initModule(moduleDefine) {
let proxy
const moduleProxy = {}
for (const methodName in moduleDefine) {
Object.defineProperty(moduleProxy, methodName, {
enumerable: true,
configurable: true,
get: () => moduleGetter(moduleName, methodName),
get: () => {
if (!proxy) {
proxy = uni.requireNativePlugin('proxy-module')
}
return moduleGetter(
proxy,
moduleName,
methodName,
moduleDefine[methodName]
)
},
})
}
}
......
......@@ -4,9 +4,16 @@ declare const uni: {
const moduleName = '__MODULE_NAME__'
const moduleDefine = '__MODULE_DEFINE__'
const moduleDefine = '__MODULE_DEFINE__' as unknown as Record<
string,
ModuleMethodDefine
>
export default initModule(moduleDefine as unknown as Record<string, boolean>)
interface ModuleMethodDefine {
async?: boolean
}
export default initModule(moduleDefine)
let callbackId = 1
......@@ -16,11 +23,14 @@ const toTypeString = (value: unknown): string => objectToString.call(value)
const isPlainObject = (val: unknown): val is object =>
toTypeString(val) === '[object Object]'
const callbacks: Record<string, Function> = {}
export function normalizeArg(arg: unknown) {
if (typeof arg === 'function') {
const id = callbackId++
callbacks[id] = arg
return {
$$type: 'function',
value: callbackId++,
value: id,
}
} else if (isPlainObject(arg)) {
Object.keys(arg).forEach((name) => {
......@@ -29,22 +39,87 @@ export function normalizeArg(arg: unknown) {
}
return arg
}
interface ProxyInvokeAsyncResponse {
errMsg: string
params: unknown
}
interface ProxyInvokeCallbackResponse {
id: number
name: string
params: unknown[]
keepAlive: boolean
}
type ProxyInvokeResponse =
| ProxyInvokeAsyncResponse
| ProxyInvokeCallbackResponse
function moduleGetter(proxy: any, module: string, method: string) {
function isProxyInvokeCallbackResponse(
res: ProxyInvokeResponse
): res is ProxyInvokeCallbackResponse {
return !!(res as ProxyInvokeCallbackResponse).name
}
function moduleGetter(
proxy: any,
module: string,
method: string,
defines: ModuleMethodDefine
) {
const invokeCallback = ({
id,
name,
params,
keepAlive,
}: ProxyInvokeCallbackResponse) => {
const callback = callbacks[id]
if (callback) {
callback(...params)
if (!keepAlive) {
delete callbacks[id]
}
} else {
console.error(`${module}.${method} ${name} is not found`)
}
}
return (...args: unknown[]) => {
const params = args.map((arg) => normalizeArg(arg))
proxy.invoke({ module, method, params }, () => {})
const invokeArgs = { module, method, params, async: !!defines.async }
if (defines.async) {
return new Promise((resolve, reject) => {
proxy.invoke(invokeArgs, (res: ProxyInvokeResponse) => {
if (isProxyInvokeCallbackResponse(res)) {
invokeCallback(res)
} else {
if (res.errMsg) {
reject(res.errMsg)
} else {
resolve(res.params)
}
}
})
})
}
return proxy.invoke(invokeArgs, invokeCallback)
}
}
function initModule(moduleDefine: Record<string, unknown>) {
const proxy = uni.requireNativePlugin('proxy-module')
function initModule(moduleDefine: Record<string, ModuleMethodDefine>) {
let proxy: any
const moduleProxy = {}
for (const methodName in moduleDefine) {
Object.defineProperty(moduleProxy, methodName, {
enumerable: true,
configurable: true,
get: () => moduleGetter(proxy, moduleName, methodName),
get: () => {
if (!proxy) {
proxy = uni.requireNativePlugin('proxy-module')
}
return moduleGetter(
proxy,
moduleName,
methodName,
moduleDefine[methodName]
)
},
})
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册