index.ts 3.6 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1
import { isPlainObject } from '@vue/shared'
fxy060608's avatar
fxy060608 已提交
2 3
import { ApiOptions, ApiProtocols } from '../../protocols/type'
import { API_TYPE_ON_PROTOCOLS, validateProtocols } from '../protocol'
4
import {
fxy060608's avatar
fxy060608 已提交
5
  invokeCallback,
6 7 8
  createAsyncApiCallback,
  createKeepAliveApiCallback,
} from './callback'
fxy060608's avatar
fxy060608 已提交
9
import { promisify } from './promise'
10 11

export const API_TYPE_ON = 0
fxy060608's avatar
fxy060608 已提交
12 13 14
export const API_TYPE_TASK = 1
export const API_TYPE_SYNC = 2
export const API_TYPE_ASYNC = 3
15 16 17

type API_TYPES =
  | typeof API_TYPE_ON
fxy060608's avatar
fxy060608 已提交
18
  | typeof API_TYPE_TASK
19 20 21 22
  | typeof API_TYPE_SYNC
  | typeof API_TYPE_ASYNC

function formatApiArgs(args: any[], options?: ApiOptions) {
fxy060608's avatar
fxy060608 已提交
23 24 25 26 27 28 29 30 31 32 33
  const params = args[0]
  if (
    !options ||
    (!isPlainObject(options.formatArgs) && isPlainObject(params))
  ) {
    return args
  }
  const formatArgs = options.formatArgs!
  Object.keys(formatArgs).forEach((name) => {
    formatArgs[name](args[0][name], params)
  })
34 35 36 37 38 39 40 41
  return args
}

function wrapperOnApi(name: string, fn: Function) {
  return (callback: Function) =>
    fn.apply(null, createKeepAliveApiCallback(name, callback))
}

fxy060608's avatar
fxy060608 已提交
42 43 44 45 46
function wrapperTaskApi(name: string, fn: Function, options?: ApiOptions) {
  return (args: Record<string, any>) =>
    fn.apply(null, [args, createAsyncApiCallback(name, args, options)])
}

47 48 49 50 51 52 53
function wrapperSyncApi(fn: Function) {
  return (...args: any[]) => fn.apply(null, args)
}

function wrapperAsyncApi(name: string, fn: Function, options?: ApiOptions) {
  return (args: Record<string, any>) => {
    const callbackId = createAsyncApiCallback(name, args, options)
fxy060608's avatar
fxy060608 已提交
54 55 56 57 58 59
    const res = fn.apply(null, [
      args,
      (res: unknown) => {
        invokeCallback(callbackId, res)
      },
    ])
fxy060608's avatar
fxy060608 已提交
60 61 62
    if (res) {
      invokeCallback(callbackId, res)
    }
63 64 65 66 67 68 69 70 71 72
  }
}

function wrapperApi<T extends Function>(
  fn: Function,
  name?: string,
  protocol?: ApiProtocols,
  options?: ApiOptions
) {
  return (function (...args: any[]) {
fxy060608's avatar
fxy060608 已提交
73 74 75 76 77
    if (__DEV__) {
      const errMsg = validateProtocols(name!, args, protocol)
      if (errMsg) {
        return errMsg
      }
78
    }
fxy060608's avatar
fxy060608 已提交
79
    return fn.apply(null, formatApiArgs(args, options))
80 81 82
  } as unknown) as T
}

fxy060608's avatar
fxy060608 已提交
83
export function defineOnApi<T extends Function>(
84 85
  name: string,
  fn: T,
fxy060608's avatar
fxy060608 已提交
86
  options?: ApiOptions
87
) {
fxy060608's avatar
fxy060608 已提交
88
  return defineApi(
fxy060608's avatar
fxy060608 已提交
89 90 91
    API_TYPE_ON,
    name,
    fn,
fxy060608's avatar
fxy060608 已提交
92
    __DEV__ ? API_TYPE_ON_PROTOCOLS : undefined,
fxy060608's avatar
fxy060608 已提交
93 94
    options
  )
95 96
}

fxy060608's avatar
fxy060608 已提交
97
export function defineTaskApi<T extends Function>(
98 99 100 101 102
  name: string,
  fn: T,
  protocol?: ApiProtocols,
  options?: ApiOptions
) {
fxy060608's avatar
fxy060608 已提交
103
  return defineApi(
fxy060608's avatar
fxy060608 已提交
104 105 106 107 108 109
    API_TYPE_TASK,
    name,
    fn,
    __DEV__ ? protocol : undefined,
    options
  )
110 111
}

fxy060608's avatar
fxy060608 已提交
112
export function defineSyncApi<T extends Function>(
113 114 115 116 117
  name: string,
  fn: T,
  protocol?: ApiProtocols,
  options?: ApiOptions
) {
fxy060608's avatar
fxy060608 已提交
118
  return defineApi(
fxy060608's avatar
fxy060608 已提交
119 120 121 122 123 124
    API_TYPE_SYNC,
    name,
    fn,
    __DEV__ ? protocol : undefined,
    options
  )
125 126
}

fxy060608's avatar
fxy060608 已提交
127
export function defineAsyncApi<T extends Function>(
128 129 130 131 132
  name: string,
  fn: T,
  protocol?: ApiProtocols,
  options?: ApiOptions
) {
fxy060608's avatar
fxy060608 已提交
133
  return promisify(
fxy060608's avatar
fxy060608 已提交
134
    defineApi(API_TYPE_ASYNC, name, fn, __DEV__ ? protocol : undefined, options)
fxy060608's avatar
fxy060608 已提交
135
  )
136 137
}

fxy060608's avatar
fxy060608 已提交
138
function defineApi<T extends Function>(
139 140 141 142 143 144 145 146 147
  type: API_TYPES,
  name: string,
  fn: T,
  protocol?: ApiProtocols,
  options?: ApiOptions
) {
  switch (type) {
    case API_TYPE_ON:
      return wrapperApi<T>(wrapperOnApi(name, fn), name, protocol, options)
fxy060608's avatar
fxy060608 已提交
148 149
    case API_TYPE_TASK:
      return wrapperApi<T>(wrapperTaskApi(name, fn), name, protocol, options)
150 151 152 153 154 155 156 157 158 159 160
    case API_TYPE_SYNC:
      return wrapperApi<T>(wrapperSyncApi(fn), name, protocol, options)
    case API_TYPE_ASYNC:
      return wrapperApi<T>(
        wrapperAsyncApi(name, fn, options),
        name,
        protocol,
        options
      )
  }
}