index.ts 3.1 KB
Newer Older
1 2 3 4 5 6
import { ApiOptions, ApiProtocol, ProtocolOptions } from '../../protocols/type'
import {
  createAsyncApiCallback,
  createKeepAliveApiCallback,
  invokeCallback,
} from './callback'
fxy060608's avatar
fxy060608 已提交
7
import { promisify } from './promise'
8 9 10 11

type ApiProtocols = ApiProtocol | ProtocolOptions[]

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 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
  | typeof API_TYPE_SYNC
  | typeof API_TYPE_ASYNC

function validateProtocol(
  _name: string,
  _args: any[],
  _protocol: ApiProtocols
) {
  return true
}

function formatApiArgs(args: any[], options?: ApiOptions) {
  return args
}

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

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

44 45 46 47 48 49 50
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 已提交
51 52 53 54
    const res = fn.apply(null, [args, callbackId])
    if (res) {
      invokeCallback(callbackId, res)
    }
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
  }
}

function wrapperApi<T extends Function>(
  fn: Function,
  name?: string,
  protocol?: ApiProtocols,
  options?: ApiOptions
) {
  return (function (...args: any[]) {
    if (!(__DEV__ && protocol && !validateProtocol(name!, args, protocol))) {
      return fn.apply(null, formatApiArgs(args, options))
    }
  } as unknown) as T
}

export function createOnApi<T extends Function>(
  name: string,
  fn: T,
  options?: ApiOptions,
  protocol?: ApiProtocols
) {
  return createApi(API_TYPE_ON, name, fn, protocol, options)
}

fxy060608's avatar
fxy060608 已提交
80
export function createTaskApi<T extends Function>(
81 82 83 84 85
  name: string,
  fn: T,
  protocol?: ApiProtocols,
  options?: ApiOptions
) {
fxy060608's avatar
fxy060608 已提交
86
  return createApi(API_TYPE_TASK, name, fn, protocol, options)
87 88
}

fxy060608's avatar
fxy060608 已提交
89
export function createSyncApi<T extends Function>(
90 91 92 93 94
  name: string,
  fn: T,
  protocol?: ApiProtocols,
  options?: ApiOptions
) {
fxy060608's avatar
fxy060608 已提交
95
  return createApi(API_TYPE_SYNC, name, fn, protocol, options)
96 97
}

fxy060608's avatar
fxy060608 已提交
98
export function createAsyncApi<T extends Function>(
99 100 101 102 103
  name: string,
  fn: T,
  protocol?: ApiProtocols,
  options?: ApiOptions
) {
fxy060608's avatar
fxy060608 已提交
104
  return promisify(createApi(API_TYPE_ASYNC, name, fn, protocol, options))
105 106 107 108 109 110 111 112 113 114 115 116
}

function createApi<T extends Function>(
  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 已提交
117 118
    case API_TYPE_TASK:
      return wrapperApi<T>(wrapperTaskApi(name, fn), name, protocol, options)
119 120 121 122 123 124 125 126 127 128 129
    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
      )
  }
}