@cloudbase/utilities 2.5.7-beta.0 → 2.5.20-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.js +15 -0
  3. package/dist/{adapters → cjs/adapters}/index.js +1 -1
  4. package/dist/cjs/adapters/platforms/web.js +213 -0
  5. package/dist/cjs/constants/common.js +24 -0
  6. package/dist/cjs/constants/errors.js +12 -0
  7. package/dist/{constants → cjs/constants}/index.js +1 -1
  8. package/dist/cjs/helpers/decorators.js +238 -0
  9. package/dist/{helpers → cjs/helpers}/index.js +1 -1
  10. package/dist/{index.js → cjs/index.js} +1 -1
  11. package/dist/cjs/libs/cache.js +259 -0
  12. package/dist/cjs/libs/events.js +104 -0
  13. package/dist/cjs/libs/util.js +221 -0
  14. package/dist/esm/adapters/index.d.ts +13 -0
  15. package/dist/esm/adapters/index.js +27 -0
  16. package/dist/esm/adapters/platforms/web.d.ts +15 -0
  17. package/dist/esm/adapters/platforms/web.js +209 -0
  18. package/dist/esm/constants/common.d.ts +6 -0
  19. package/dist/esm/constants/common.js +17 -0
  20. package/dist/esm/constants/errors.d.ts +8 -0
  21. package/dist/esm/constants/errors.js +9 -0
  22. package/dist/esm/constants/index.d.ts +3 -0
  23. package/dist/esm/constants/index.js +4 -0
  24. package/dist/esm/helpers/decorators.d.ts +11 -0
  25. package/dist/esm/helpers/decorators.js +234 -0
  26. package/dist/esm/helpers/index.d.ts +1 -0
  27. package/dist/esm/helpers/index.js +2 -0
  28. package/dist/esm/index.d.ts +11 -0
  29. package/dist/esm/index.js +12 -0
  30. package/dist/esm/libs/cache.d.ts +17 -0
  31. package/dist/esm/libs/cache.js +256 -0
  32. package/dist/esm/libs/events.d.ts +27 -0
  33. package/dist/esm/libs/events.js +98 -0
  34. package/dist/esm/libs/util.d.ts +35 -0
  35. package/dist/esm/libs/util.js +194 -0
  36. package/package.json +6 -16
  37. package/src/adapters/index.ts +28 -0
  38. package/src/adapters/platforms/web.ts +182 -0
  39. package/src/constants/common.ts +21 -0
  40. package/src/constants/errors.ts +8 -0
  41. package/src/constants/index.ts +4 -0
  42. package/src/global.d.ts +3 -0
  43. package/src/helpers/decorators.ts +228 -0
  44. package/src/helpers/index.ts +1 -0
  45. package/src/index.ts +22 -0
  46. package/src/libs/cache.ts +192 -0
  47. package/src/libs/events.ts +154 -0
  48. package/src/libs/util.ts +216 -0
  49. package/tsconfig.esm.json +16 -0
  50. package/tsconfig.json +21 -0
  51. package/dist/adapters/platforms/web.js +0 -213
  52. package/dist/constants/common.js +0 -24
  53. package/dist/constants/errors.js +0 -12
  54. package/dist/helpers/decorators.js +0 -238
  55. package/dist/libs/cache.js +0 -259
  56. package/dist/libs/events.js +0 -104
  57. package/dist/libs/util.js +0 -221
  58. /package/dist/{adapters → cjs/adapters}/index.d.ts +0 -0
  59. /package/dist/{adapters → cjs/adapters}/platforms/web.d.ts +0 -0
  60. /package/dist/{constants → cjs/constants}/common.d.ts +0 -0
  61. /package/dist/{constants → cjs/constants}/errors.d.ts +0 -0
  62. /package/dist/{constants → cjs/constants}/index.d.ts +0 -0
  63. /package/dist/{helpers → cjs/helpers}/decorators.d.ts +0 -0
  64. /package/dist/{helpers → cjs/helpers}/index.d.ts +0 -0
  65. /package/dist/{index.d.ts → cjs/index.d.ts} +0 -0
  66. /package/dist/{libs → cjs/libs}/cache.d.ts +0 -0
  67. /package/dist/{libs → cjs/libs}/events.d.ts +0 -0
  68. /package/dist/{libs → cjs/libs}/util.d.ts +0 -0
@@ -0,0 +1,3 @@
1
+ declare module 'crypto-js/hmac-sha256';
2
+ declare module 'crypto-js/enc-base64';
3
+ declare module 'crypto-js/enc-utf8';
@@ -0,0 +1,228 @@
1
+ import { printGroupLog } from '../libs/util'
2
+ import { IS_DEBUG_MODE } from '../constants'
3
+
4
+ interface ICatchErrorsDecoratorOptions {
5
+ mode?: 'sync' | 'async';
6
+ customInfo?: {
7
+ className?: string;
8
+ methodName?: string;
9
+ };
10
+ title?: string;
11
+ messages?: string[];
12
+ }
13
+ // firefox的stack格式与chrome不同
14
+ let isFirefox = false
15
+ if (typeof navigator !== 'undefined' && navigator.userAgent) {
16
+ isFirefox = navigator.userAgent.indexOf('Firefox') !== -1
17
+ }
18
+ /**
19
+ * decorate在stack中一般都特定的规范
20
+ */
21
+ const REG_STACK_DECORATE = isFirefox
22
+ ? /(\.js\/)?__decorate(\$\d+)?<@.*\d$/
23
+ : /(\/\w+\.js\.)?__decorate(\$\d+)?\s*\(.*\)$/
24
+ const REG_STACK_LINK = /https?:\/\/.+:\d*\/.*\.js:\d+:\d+/
25
+ /**
26
+ * debug模式强化日志信息
27
+ * @param options
28
+ */
29
+ export function catchErrorsDecorator(options: ICatchErrorsDecoratorOptions) {
30
+ const { mode = 'async', customInfo = {}, title, messages = [] } = options
31
+
32
+ return function (
33
+ target: any,
34
+ methodName: string,
35
+ descriptor: TypedPropertyDescriptor<Function>
36
+ ) {
37
+ // 生产环境禁用
38
+ if (!IS_DEBUG_MODE) {
39
+ return
40
+ }
41
+ const className = customInfo.className || target.constructor.name
42
+ const fnName = customInfo.methodName || methodName
43
+ const fn = descriptor.value
44
+
45
+ // 被decorator装饰的源码link
46
+ // 在descriptor.value外部此处创建的stack层次可触达源码
47
+ // 而descriptor.value内部有可能由于stack太深无法触达
48
+ const sourceLink = getSourceLink(new Error())
49
+
50
+ if (mode === 'sync') {
51
+ descriptor.value = function (...args: any[]) {
52
+ // 此处的stack作用主要是为了获取被decorator装饰的源码class和method名称
53
+ const innerErr: any = getRewritedError({
54
+ err: new Error(),
55
+ className,
56
+ methodName: fnName,
57
+ sourceLink,
58
+ })
59
+ try {
60
+ return fn.apply(this, args)
61
+ } catch (err) {
62
+ let failErr = err
63
+ const { message: errMsg, error, error_description: errorDescription } = err
64
+ const logs: any = {
65
+ title: title || `${className}.${fnName} failed`,
66
+ content: [{
67
+ type: 'error',
68
+ body: err,
69
+ }],
70
+ }
71
+ // 只特殊处理SDK业务逻辑抛出的错误-JSON string
72
+ if (errMsg && /^\{.*\}$/.test(errMsg)) {
73
+ const msg = JSON.parse(errMsg)
74
+ logs.subtitle = errMsg
75
+ if (msg.code) {
76
+ if (innerErr) {
77
+ innerErr.code = msg.code
78
+ innerErr.msg = msg.msg
79
+ } else {
80
+ err.code = msg.code
81
+ err.message = msg.msg
82
+ }
83
+ failErr = innerErr || err
84
+ logs.content = messages.map(msg => ({
85
+ type: 'info',
86
+ body: msg,
87
+ }))
88
+ }
89
+ }
90
+
91
+ // oauth 错误特殊处理
92
+ if (error && errorDescription) {
93
+ logs.subtitle = errorDescription
94
+ if (innerErr) {
95
+ innerErr.code = error
96
+ innerErr.msg = errorDescription
97
+ } else {
98
+ err.code = error
99
+ err.message = errorDescription
100
+ }
101
+ failErr = innerErr || err
102
+ logs.content = messages.map(msg => ({
103
+ type: 'info',
104
+ body: msg,
105
+ }))
106
+ }
107
+ printGroupLog(logs)
108
+ throw failErr
109
+ }
110
+ }
111
+ } else {
112
+ descriptor.value = async function (...args: any[]) {
113
+ const innerErr: any = getRewritedError({
114
+ err: new Error(),
115
+ className,
116
+ methodName: fnName,
117
+ sourceLink,
118
+ })
119
+
120
+ try {
121
+ return await fn.apply(this, args)
122
+ } catch (err) {
123
+ let failErr = err
124
+ const { message: errMsg, error, error_description: errorDescription } = err
125
+ const logs: any = {
126
+ title: title || `${className}.${fnName} failed`,
127
+ content: [{
128
+ type: 'error',
129
+ body: err,
130
+ }],
131
+ }
132
+ // 只特殊处理SDK业务逻辑抛出的错误-JSON string
133
+ if (errMsg && /^\{.*\}$/.test(errMsg)) {
134
+ const msg = JSON.parse(errMsg)
135
+ logs.subtitle = msg
136
+ if (msg.code) {
137
+ if (innerErr) {
138
+ innerErr.code = msg.code
139
+ innerErr.message = msg.msg
140
+ } else {
141
+ err.code = msg.code
142
+ err.message = msg.msg
143
+ }
144
+ failErr = innerErr || err
145
+ logs.content = messages.map(msg => ({
146
+ type: 'info',
147
+ body: msg,
148
+ }))
149
+ }
150
+ }
151
+
152
+ // oauth 错误特殊处理
153
+ if (error && errorDescription) {
154
+ logs.subtitle = errorDescription
155
+ if (innerErr) {
156
+ innerErr.code = error
157
+ innerErr.msg = errorDescription
158
+ } else {
159
+ err.code = error
160
+ err.message = errorDescription
161
+ }
162
+ failErr = innerErr || err
163
+ logs.content = messages.map(msg => ({
164
+ type: 'info',
165
+ body: msg,
166
+ }))
167
+ }
168
+ printGroupLog(logs)
169
+ throw failErr
170
+ }
171
+ }
172
+ }
173
+ }
174
+ }
175
+
176
+ /**
177
+ * 在原始堆栈中查找装饰器条目并返回源码链接link
178
+ * @param err
179
+ */
180
+ function getSourceLink(err: Error) {
181
+ let sourceLink = ''
182
+ const outterErrStacks = err.stack.split('\n')
183
+ const indexOfDecorator = outterErrStacks.findIndex(str => REG_STACK_DECORATE.test(str))
184
+
185
+ if (indexOfDecorator !== -1) {
186
+ const match = REG_STACK_LINK.exec(outterErrStacks[indexOfDecorator + 1] || '')
187
+
188
+ sourceLink = match ? match[0] : ''
189
+ }
190
+ return sourceLink
191
+ }
192
+
193
+ /**
194
+ * 在原始堆栈中查找装饰器条目,剔除其后的无用堆栈,并将链接替换为源码link
195
+ * @param options
196
+ */
197
+ function getRewritedError(options: {
198
+ err: Error;
199
+ className: string;
200
+ methodName: string;
201
+ sourceLink: string;
202
+ }) {
203
+ const { err, className, methodName, sourceLink } = options
204
+ // 找不到源码link返回null,后续逻辑将打印原堆栈信息
205
+ if (!sourceLink) {
206
+ return null
207
+ }
208
+
209
+ const innerErrStack = err.stack.split('\n')
210
+ const REG_STACK_INNER_METHOD = isFirefox
211
+ ? /^catchErrorsDecorator\/<\/descriptor.value@.*\d$/
212
+ : new RegExp(`${className}\\.descriptor.value\\s*\\[as\\s${methodName}\\]\\s*\\(.*\\)$`)
213
+ const REG_STACK_INNER_METHOD_WITHOUT_LINK = isFirefox
214
+ ? /^catchErrorsDecorator\/<\/descriptor.value/
215
+ : new RegExp(`${className}\\.descriptor.value\\s*\\[as\\s${methodName}\\]`)
216
+ const indexOfSource = innerErrStack.findIndex(str => REG_STACK_INNER_METHOD.test(str))
217
+ let innerErr: Error
218
+ if (indexOfSource !== -1) {
219
+ // @ts-ignore
220
+ const realErrStack = innerErrStack.filter((v, i) => i > indexOfSource)
221
+ realErrStack.unshift(innerErrStack[indexOfSource]
222
+ .replace(REG_STACK_INNER_METHOD_WITHOUT_LINK, `${className}.${methodName}`)
223
+ .replace(REG_STACK_LINK, sourceLink))
224
+ innerErr = new Error()
225
+ innerErr.stack = `${isFirefox ? '@debugger' : 'Error'}\n${realErrStack.join('\n')}`
226
+ }
227
+ return innerErr
228
+ }
@@ -0,0 +1 @@
1
+ export * from './decorators'
package/src/index.ts ADDED
@@ -0,0 +1,22 @@
1
+ import * as constants from './constants'
2
+ import * as adapters from './adapters'
3
+ import * as cache from './libs/cache'
4
+ import * as events from './libs/events'
5
+ import * as utils from './libs/util'
6
+ import * as helpers from './helpers'
7
+
8
+ import jwtDecode from 'jwt-decode'
9
+
10
+ const jwt = {
11
+ decode: jwtDecode,
12
+ }
13
+
14
+ export {
15
+ constants,
16
+ adapters,
17
+ cache,
18
+ events,
19
+ utils,
20
+ helpers,
21
+ jwt,
22
+ }
@@ -0,0 +1,192 @@
1
+ import { StorageInterface, AbstractStorage, SDKAdapterInterface } from '@cloudbase/adapter-interface'
2
+ import { ICloudbaseCache, ICacheConfig } from '@cloudbase/types/cache'
3
+ import { KV, Persistence, ICloudbasePlatformInfo } from '@cloudbase/types'
4
+ import { printWarn } from './util'
5
+ import { ERRORS, getSdkName } from '../constants'
6
+
7
+ /**
8
+ * persitence=none时登录态保存在内存中
9
+ */
10
+ class TcbCacheObject extends AbstractStorage {
11
+ private readonly root: any;
12
+ constructor(root: any) {
13
+ super()
14
+ this.root = root
15
+ if (!root.tcbCacheObject) {
16
+ root.tcbCacheObject = {}
17
+ }
18
+ }
19
+ public setItem(key: string, value: any) {
20
+ this.root.tcbCacheObject[key] = value
21
+ }
22
+ public getItem(key: string) {
23
+ return this.root.tcbCacheObject[key]
24
+ }
25
+ public removeItem(key: string) {
26
+ delete this.root.tcbCacheObject[key]
27
+ }
28
+ public clear() {
29
+ delete this.root.tcbCacheObject
30
+ }
31
+ }
32
+ /**
33
+ * 工厂函数
34
+ */
35
+ function createStorage(persistence: Persistence, adapter: SDKAdapterInterface): StorageInterface {
36
+ switch (persistence) {
37
+ case 'local':
38
+ if (!adapter.localStorage) {
39
+ printWarn(ERRORS.INVALID_PARAMS, 'localStorage is not supported on current platform')
40
+ // 不支持localstorage的平台降级为none
41
+ return new TcbCacheObject(adapter.root)
42
+ }
43
+ return adapter.localStorage
44
+ case 'none':
45
+ return new TcbCacheObject(adapter.root)
46
+ default:
47
+ if (!adapter.localStorage) {
48
+ printWarn(ERRORS.INVALID_PARAMS, 'localStorage is not supported on current platform')
49
+ // 不支持localstorage的平台降级为none
50
+ return new TcbCacheObject(adapter.root)
51
+ }
52
+ return adapter.localStorage
53
+ }
54
+ }
55
+
56
+ export class CloudbaseCache implements ICloudbaseCache {
57
+ public keys: KV<string> = {};
58
+
59
+ private persistenceTag: Persistence;
60
+ private platformInfo: ICloudbasePlatformInfo;
61
+ private storage: StorageInterface;
62
+
63
+ constructor(config: ICacheConfig) {
64
+ const { persistence, platformInfo = {}, keys = {} } = config
65
+ this.platformInfo = platformInfo
66
+ if (!this.storage) {
67
+ this.persistenceTag = this.platformInfo.adapter.primaryStorage || persistence
68
+ this.storage = createStorage(this.persistenceTag, this.platformInfo.adapter)
69
+ this.keys = keys
70
+ }
71
+ }
72
+ /**
73
+ * @getter storage模式-同步/异步
74
+ */
75
+ get mode() {
76
+ return this.storage.mode || 'sync'
77
+ }
78
+ get persistence(): Persistence {
79
+ return this.persistenceTag
80
+ }
81
+
82
+ public setStore(key: string, value: any, version?: any) {
83
+ if (this.mode === 'async') {
84
+ printWarn(ERRORS.INVALID_OPERATION, 'current platform\'s storage is asynchronous, please use setStoreAsync insteed')
85
+ return
86
+ }
87
+ if (!this.storage) {
88
+ return
89
+ }
90
+
91
+ try {
92
+ const val = {
93
+ version: version || 'localCachev1',
94
+ content: value,
95
+ }
96
+ this.storage.setItem(key, JSON.stringify(val))
97
+ } catch (e) {
98
+ throw new Error(JSON.stringify({
99
+ code: ERRORS.OPERATION_FAIL,
100
+ msg: `[${getSdkName()}][${ERRORS.OPERATION_FAIL}]setStore failed`,
101
+ info: e,
102
+ }))
103
+ }
104
+
105
+ return
106
+ }
107
+ public async setStoreAsync(key: string, value: any, version?: any) {
108
+ if (!this.storage) {
109
+ return
110
+ }
111
+
112
+ try {
113
+ const val = {
114
+ version: version || 'localCachev1',
115
+ content: value,
116
+ }
117
+ await this.storage.setItem(key, JSON.stringify(val))
118
+ } catch (e) {
119
+ return
120
+ }
121
+
122
+ return
123
+ }
124
+ public getStore(key: string, version?: string) {
125
+ if (this.mode === 'async') {
126
+ printWarn(ERRORS.INVALID_OPERATION, 'current platform\'s storage is asynchronous, please use getStoreAsync insteed')
127
+ return
128
+ }
129
+ try {
130
+ // 测试用例使用
131
+ if (typeof process !== 'undefined' && process.env?.tcb_token) {
132
+ return process.env.tcb_token
133
+ }
134
+
135
+ if (!this.storage) {
136
+ return ''
137
+ }
138
+ } catch (e) {
139
+ return ''
140
+ }
141
+
142
+ version = version || 'localCachev1'
143
+
144
+ const content = this.storage.getItem(key)
145
+ if (!content) {
146
+ return ''
147
+ }
148
+
149
+ if (content.indexOf(version) >= 0) {
150
+ const d = JSON.parse(content)
151
+ return d.content
152
+ }
153
+ return ''
154
+ }
155
+ public async getStoreAsync(key: string, version?: string) {
156
+ try {
157
+ // 测试用例使用
158
+ if (typeof process !== 'undefined' && process.env?.tcb_token) {
159
+ return process.env.tcb_token
160
+ }
161
+
162
+ if (!this.storage) {
163
+ return ''
164
+ }
165
+ } catch (e) {
166
+ return ''
167
+ }
168
+
169
+ version = version || 'localCachev1'
170
+
171
+ const content = await this.storage.getItem(key)
172
+ if (!content) {
173
+ return ''
174
+ }
175
+
176
+ if (content.indexOf(version) >= 0) {
177
+ const d = JSON.parse(content)
178
+ return d.content
179
+ }
180
+ return ''
181
+ }
182
+ public removeStore(key: string) {
183
+ if (this.mode === 'async') {
184
+ printWarn(ERRORS.INVALID_OPERATION, 'current platform\'s storage is asynchronous, please use removeStoreAsync insteed')
185
+ return
186
+ }
187
+ this.storage.removeItem(key)
188
+ }
189
+ public async removeStoreAsync(key: string) {
190
+ await this.storage.removeItem(key)
191
+ }
192
+ }
@@ -0,0 +1,154 @@
1
+ import { isString, isInstanceOf } from './util'
2
+ import { Listeners, ICloudbaseEventEmitter } from '@cloudbase/types/events'
3
+
4
+
5
+ /**
6
+ * @private
7
+ * @function _addEventListener - 添加监听
8
+ * @param {string} name - event名称
9
+ * @param {Function} listener - 响应函数
10
+ * @param {Listeners} listeners - 已存响应函数集合
11
+ */
12
+ function customeAddEventListener(name: string, listener: Function, listeners: Listeners) {
13
+ listeners[name] = listeners[name] || []
14
+ listeners[name].push(listener)
15
+ }
16
+ /**
17
+ * @private
18
+ * @function _removeEventListener - 移除监听
19
+ * @param {string} name - event名称
20
+ * @param {Function} listener - 响应函数
21
+ * @param {Listeners} listeners - 已存响应函数集合
22
+ */
23
+ function customRemoveEventListener(name: string, listener: Function, listeners: Listeners) {
24
+ if (listeners?.[name]) {
25
+ const index = listeners[name].indexOf(listener)
26
+ if (index !== -1) {
27
+ listeners[name].splice(index, 1)
28
+ }
29
+ }
30
+ }
31
+ interface IEvent {
32
+ name: string;
33
+ target: any;
34
+ data: any;
35
+ }
36
+ /**
37
+ * 自定义事件
38
+ * @class CloudbaseEvent
39
+ * @param {string} name - 类型
40
+ * @param {any} data - 数据
41
+ */
42
+ export class CloudbaseEvent implements IEvent {
43
+ public readonly name: string;
44
+ public target: any;
45
+ public data: any;
46
+
47
+ constructor(name: string, data: any) {
48
+ this.data = data || null
49
+ this.name = name
50
+ }
51
+ }
52
+ /**
53
+ * 自定义错误事件
54
+ * @class IErrorEvent
55
+ * @extends CloudbaseEvent
56
+ * @param {Error} error - 错误信息对象
57
+ * @param {any} data - 数据
58
+ */
59
+ export class IErrorEvent extends CloudbaseEvent {
60
+ public readonly error: Error;
61
+ constructor(error: Error, data?: any) {
62
+ super('error', { error, data })
63
+ this.error = error
64
+ }
65
+ }
66
+
67
+ /**
68
+ * @class CloudbaseEventEmitter
69
+ */
70
+ export class CloudbaseEventEmitter implements ICloudbaseEventEmitter {
71
+ /**
72
+ * @private
73
+ * @readonly
74
+ * @property {Listeners} listeners - 响应函数集合
75
+ * @default `{}`
76
+ */
77
+ private readonly listeners: Listeners = {};
78
+
79
+ /**
80
+ * @public
81
+ * @method on - 添加监听
82
+ * @param {string} name - event名称
83
+ * @param {Function} listener - 响应函数
84
+ * @return `this`
85
+ */
86
+ public on(name: string, listener: Function): this {
87
+ customeAddEventListener(name, listener, this.listeners)
88
+ return this
89
+ }
90
+ /**
91
+ * @public
92
+ * @method off - 移除监听
93
+ * @param {string} name - event名称
94
+ * @param {Function} listener - 响应函数
95
+ * @return `this`
96
+ */
97
+ public off(name: string, listener: Function): this {
98
+ customRemoveEventListener(name, listener, this.listeners)
99
+ return this
100
+ }
101
+ /**
102
+ * @public
103
+ * @method fire - 触发事件
104
+ * @param {string|CloudbaseEvent} event - event
105
+ * @return `this`
106
+ */
107
+ public fire(event: string | CloudbaseEvent, data?: any): this {
108
+ // 打印错误信息
109
+ if (isInstanceOf(event, IErrorEvent)) {
110
+ console.error((event as IErrorEvent).error)
111
+ return this
112
+ }
113
+
114
+ const ev: CloudbaseEvent = isString(event) ? new CloudbaseEvent(event as string, data || {}) : event as CloudbaseEvent
115
+
116
+ const { name } = ev
117
+
118
+ if (this.listens(name)) {
119
+ ev.target = this
120
+
121
+ const handlers = this.listeners[name] ? [...this.listeners[name]] : []
122
+ for (const fn of handlers) {
123
+ fn.call(this, ev)
124
+ }
125
+ }
126
+
127
+ return this
128
+ }
129
+
130
+ /**
131
+ * @private
132
+ * @method listens - 判断是否监听了name事件
133
+ * @param {string} name - event名称
134
+ * @return `boolean`
135
+ */
136
+ private listens(name: string): boolean {
137
+ return this.listeners[name] && this.listeners[name].length > 0
138
+ }
139
+ }
140
+
141
+
142
+ const eventEmitter = new CloudbaseEventEmitter()
143
+
144
+ export function addEventListener(event: string, callback: Function) {
145
+ eventEmitter.on(event, callback)
146
+ }
147
+
148
+ export function activateEvent(event: string, data: any = {}) {
149
+ eventEmitter.fire(event, data)
150
+ }
151
+
152
+ export function removeEventListener(event: string, callback: Function) {
153
+ eventEmitter.off(event, callback)
154
+ }