fastevent 1.1.0 → 1.1.2
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.
- package/CHANGELOG.md +16 -0
- package/dist/devTools.d.mts +543 -0
- package/dist/devTools.d.ts +543 -0
- package/dist/devTools.js +3 -0
- package/dist/devTools.js.map +1 -0
- package/dist/devTools.mjs +3 -0
- package/dist/devTools.mjs.map +1 -0
- package/dist/index.d.mts +282 -37
- package/dist/index.d.ts +282 -37
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/example/README.md +54 -0
- package/example/eslint.config.js +28 -0
- package/example/index.html +13 -0
- package/example/package.json +29 -0
- package/example/pnpm-lock.yaml +2047 -0
- package/example/public/vite.svg +1 -0
- package/example/src/App.css +42 -0
- package/example/src/App.tsx +60 -0
- package/example/src/assets/react.svg +1 -0
- package/example/src/index.css +68 -0
- package/example/src/main.tsx +10 -0
- package/example/src/myEvent.ts +32 -0
- package/example/src/vite-env.d.ts +1 -0
- package/example/tsconfig.app.json +26 -0
- package/example/tsconfig.json +7 -0
- package/example/tsconfig.node.json +24 -0
- package/example/vite.config.ts +7 -0
- package/package.json +15 -2
- package/packages/native/index.ts +1 -0
- package/packages/turbo/.zig-cache/h/271c82d991949fd7788fd5451f0ca834.txt +0 -0
- package/packages/turbo/.zig-cache/h/timestamp +0 -0
- package/packages/turbo/.zig-cache/o/ebd7ddab8ffe003267120d598aecce68/dependencies.zig +2 -0
- package/packages/turbo/.zig-cache/z/c8114b040daa461a9e2eabd0357554a4 +0 -0
- package/packages/turbo/build.zig +60 -0
- package/packages/turbo/examples/basic.zig +107 -0
- package/packages/turbo/src/event.zig +251 -0
- package/packages/turbo/src/index.zig +70 -0
- package/packages/turbo/src/scope.zig +104 -0
- package/packages/turbo/src/types.zig +88 -0
- package/packages/turbo/src/utils.zig +171 -0
- package/readme.md +86 -2
- package/readme_cn.md +86 -2
- package/src/__tests__/scope.test.ts +2 -2
- package/src/__tests__/types.test.ts +23 -12
- package/src/__tests__/waitFor.test.ts +1 -0
- package/src/devTools.ts +166 -0
- package/src/event.ts +272 -38
- package/src/scope.ts +52 -11
- package/src/types.ts +11 -4
- package/src/utils/WeakObjectMap.ts +64 -0
- package/tsconfig.json +103 -111
- package/tsup.config.ts +17 -6
package/readme.md
CHANGED
|
@@ -346,9 +346,23 @@ events.on('process', () => {
|
|
|
346
346
|
events.emit('process');
|
|
347
347
|
```
|
|
348
348
|
|
|
349
|
-
##
|
|
349
|
+
## Generic Parameters
|
|
350
350
|
|
|
351
|
-
FastEvent
|
|
351
|
+
FastEvent supports three generic type parameters for precise type control:
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
class FastEvent<
|
|
355
|
+
Events extends Record<string, any> = Record<string, any>,
|
|
356
|
+
Meta extends Record<string, any> = Record<string, any>,
|
|
357
|
+
Types extends keyof Events = keyof Events
|
|
358
|
+
>
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
1. `Events`: Defines the mapping between event types and their payload types
|
|
362
|
+
2. `Meta`: Defines the type of metadata that can be attached to events
|
|
363
|
+
3. `Types`: The union type of all event types (usually inferred from Events)
|
|
364
|
+
|
|
365
|
+
### Basic Type Safety
|
|
352
366
|
|
|
353
367
|
```typescript
|
|
354
368
|
// Define event types
|
|
@@ -373,6 +387,59 @@ events.emit('wrong/event', {});
|
|
|
373
387
|
events.emit('user/login', { wrong: 'type' });
|
|
374
388
|
```
|
|
375
389
|
|
|
390
|
+
### Custom Metadata Types
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
// Define metadata structure
|
|
394
|
+
interface MyMeta {
|
|
395
|
+
timestamp: number;
|
|
396
|
+
source: string;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Define events with custom metadata
|
|
400
|
+
const events = new FastEvent<MyEvents, MyMeta>();
|
|
401
|
+
|
|
402
|
+
events.on('user/login', (message) => {
|
|
403
|
+
// message.meta is typed as MyMeta
|
|
404
|
+
const { timestamp, source } = message.meta;
|
|
405
|
+
console.log(`Login from ${source} at ${timestamp}`);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
// Emit with typed metadata
|
|
409
|
+
events.emit('user/login', { id: 1, name: 'Alice' }, false, { timestamp: Date.now(), source: 'web' });
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Advanced Type Usage
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
// Define events with different payload types
|
|
416
|
+
interface ComplexEvents {
|
|
417
|
+
'data/number': number;
|
|
418
|
+
'data/string': string;
|
|
419
|
+
'data/object': { value: any };
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const events = new FastEvent<ComplexEvents>();
|
|
423
|
+
|
|
424
|
+
// TypeScript ensures type safety for each event
|
|
425
|
+
events.on('data/number', (message) => {
|
|
426
|
+
const sum = message.payload + 1; // payload is typed as number
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
events.on('data/string', (message) => {
|
|
430
|
+
const upper = message.payload.toUpperCase(); // payload is typed as string
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
events.on('data/object', (message) => {
|
|
434
|
+
const value = message.payload.value; // payload is typed as { value: any }
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
// All emissions are type checked
|
|
438
|
+
events.emit('data/number', 42);
|
|
439
|
+
events.emit('data/string', 'hello');
|
|
440
|
+
events.emit('data/object', { value: true });
|
|
441
|
+
```
|
|
442
|
+
|
|
376
443
|
## Custom Options
|
|
377
444
|
|
|
378
445
|
The FastEvent constructor supports multiple options:
|
|
@@ -399,6 +466,23 @@ const events = new FastEvent({
|
|
|
399
466
|
onRemoveListener: (path, listener) => {
|
|
400
467
|
console.log('Listener removed:', path);
|
|
401
468
|
}
|
|
469
|
+
onClearListeners: () => {
|
|
470
|
+
console.log('清空监听器:', path);
|
|
471
|
+
},
|
|
472
|
+
onExecuteListener: (message: FastEventMessage, returns: any[], listeners: (FastEventListener<any, any, any> | [FastEventListener<any, any>, number])[]) => {
|
|
473
|
+
console.log('监听器执行后的回调:');
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### debug
|
|
479
|
+
|
|
480
|
+
Use `debug` option to enable debug mode and import `fastevent/devtools`, so that you can see the events in `Redux Dev Tools`.
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
import 'fastevent/devtools';
|
|
484
|
+
const emitter = new FastEvent({
|
|
485
|
+
debug: true,
|
|
402
486
|
});
|
|
403
487
|
```
|
|
404
488
|
|
package/readme_cn.md
CHANGED
|
@@ -346,9 +346,23 @@ events.on('process', () => {
|
|
|
346
346
|
events.emit('process');
|
|
347
347
|
```
|
|
348
348
|
|
|
349
|
-
##
|
|
349
|
+
## 泛型参数
|
|
350
350
|
|
|
351
|
-
FastEvent
|
|
351
|
+
FastEvent 支持三个泛型类型参数来实现精确的类型控制:
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
class FastEvent<
|
|
355
|
+
Events extends Record<string, any> = Record<string, any>,
|
|
356
|
+
Meta extends Record<string, any> = Record<string, any>,
|
|
357
|
+
Types extends keyof Events = keyof Events
|
|
358
|
+
>
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
1. `Events`:定义事件类型和对应的载荷(payload)类型的映射
|
|
362
|
+
2. `Meta`:定义可以附加到事件的元数据类型
|
|
363
|
+
3. `Types`:所有事件类型的联合类型(通常从 Events 中推导)
|
|
364
|
+
|
|
365
|
+
### 基本类型安全
|
|
352
366
|
|
|
353
367
|
```typescript
|
|
354
368
|
// 定义事件类型
|
|
@@ -373,6 +387,59 @@ events.emit('wrong/event', {});
|
|
|
373
387
|
events.emit('user/login', { wrong: 'type' });
|
|
374
388
|
```
|
|
375
389
|
|
|
390
|
+
### 自定义元数据类型
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
// 定义元数据结构
|
|
394
|
+
interface MyMeta {
|
|
395
|
+
timestamp: number;
|
|
396
|
+
source: string;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// 创建带自定义元数据的事件发射器
|
|
400
|
+
const events = new FastEvent<MyEvents, MyMeta>();
|
|
401
|
+
|
|
402
|
+
events.on('user/login', (message) => {
|
|
403
|
+
// message.meta 的类型为 MyMeta
|
|
404
|
+
const { timestamp, source } = message.meta;
|
|
405
|
+
console.log(`来自 ${source} 的登录,时间:${timestamp}`);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
// 发送带类型化元数据的事件
|
|
409
|
+
events.emit('user/login', { id: 1, name: 'Alice' }, false, { timestamp: Date.now(), source: 'web' });
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### 高级类型用法
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
// 定义具有不同载荷类型的事件
|
|
416
|
+
interface ComplexEvents {
|
|
417
|
+
'data/number': number;
|
|
418
|
+
'data/string': string;
|
|
419
|
+
'data/object': { value: any };
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const events = new FastEvent<ComplexEvents>();
|
|
423
|
+
|
|
424
|
+
// TypeScript 确保每个事件的类型安全
|
|
425
|
+
events.on('data/number', (message) => {
|
|
426
|
+
const sum = message.payload + 1; // payload 的类型为 number
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
events.on('data/string', (message) => {
|
|
430
|
+
const upper = message.payload.toUpperCase(); // payload 的类型为 string
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
events.on('data/object', (message) => {
|
|
434
|
+
const value = message.payload.value; // payload 的类型为 { value: any }
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
// 所有的事件发送都会进行类型检查
|
|
438
|
+
events.emit('data/number', 42);
|
|
439
|
+
events.emit('data/string', 'hello');
|
|
440
|
+
events.emit('data/object', { value: true });
|
|
441
|
+
```
|
|
442
|
+
|
|
376
443
|
## 自定义选项
|
|
377
444
|
|
|
378
445
|
FastEvent 构造函数支持多个选项:
|
|
@@ -398,10 +465,27 @@ const events = new FastEvent({
|
|
|
398
465
|
},
|
|
399
466
|
onRemoveListener: (path, listener) => {
|
|
400
467
|
console.log('移除监听器:', path);
|
|
468
|
+
},
|
|
469
|
+
onClearListeners: () => {
|
|
470
|
+
console.log('清空监听器:', path);
|
|
471
|
+
},
|
|
472
|
+
onExecuteListener: (message: FastEventMessage, returns: any[], listeners: (FastEventListener<any, any, any> | [FastEventListener<any, any>, number])[]) => {
|
|
473
|
+
console.log('监听器执行后的回调:');
|
|
401
474
|
}
|
|
402
475
|
});
|
|
403
476
|
```
|
|
404
477
|
|
|
478
|
+
### 调试
|
|
479
|
+
|
|
480
|
+
启用`debug=true`并导入`fastevent/devtools`,可以在`Redux Dev Tools`中查看事件.
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
import 'fastevent/devtools';
|
|
484
|
+
const emitter = new FastEvent<MyEvents>({
|
|
485
|
+
debug: true,
|
|
486
|
+
});
|
|
487
|
+
```
|
|
488
|
+
|
|
405
489
|
# 性能
|
|
406
490
|
|
|
407
491
|

|
|
@@ -95,14 +95,14 @@ describe("scope", () => {
|
|
|
95
95
|
]);
|
|
96
96
|
|
|
97
97
|
expect(results[0].status).toBe('fulfilled');
|
|
98
|
-
expect((results[0] as any).value).toEqual({ type: '
|
|
98
|
+
expect((results[0] as any).value).toEqual({ type: 'x', payload: 'payload1', meta: undefined });
|
|
99
99
|
|
|
100
100
|
expect(results[1].status).toBe('rejected');
|
|
101
101
|
//@ts-ignore
|
|
102
102
|
expect(results[1].reason).toBeInstanceOf(Error);
|
|
103
103
|
|
|
104
104
|
expect(results[2].status).toBe('fulfilled');
|
|
105
|
-
expect((results[2] as any).value).toEqual({ type: '
|
|
105
|
+
expect((results[2] as any).value).toEqual({ type: 'z', payload: 'payload3', meta: undefined });
|
|
106
106
|
});
|
|
107
107
|
|
|
108
108
|
|
|
@@ -85,6 +85,28 @@ describe("Types", () => {
|
|
|
85
85
|
})
|
|
86
86
|
emitter.emit("x/y/z", 1)
|
|
87
87
|
|
|
88
|
+
emitter.on("x/y/z", (message) => {
|
|
89
|
+
type cases = [
|
|
90
|
+
Expect<Equal<typeof message.type, "x/y/z">>,
|
|
91
|
+
Expect<Equal<typeof message.payload, unknown>>
|
|
92
|
+
]
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
emitter.on("x/y/z/a", (message) => {
|
|
96
|
+
type cases = [
|
|
97
|
+
Expect<Equal<typeof message.type, "x/y/z/a">>,
|
|
98
|
+
Expect<Equal<typeof message.payload, 1>>
|
|
99
|
+
]
|
|
100
|
+
})
|
|
101
|
+
emitter.waitFor("x/y/z/a").then((message) => {
|
|
102
|
+
type cases = [
|
|
103
|
+
Expect<Equal<typeof message.type, "x/y/z/a">>,
|
|
104
|
+
Expect<Equal<typeof message.payload, 1>>
|
|
105
|
+
]
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
88
110
|
// ----- scope -----
|
|
89
111
|
|
|
90
112
|
const scope = emitter.scope("x/y/z")
|
|
@@ -116,19 +138,8 @@ describe("Types", () => {
|
|
|
116
138
|
Expect<Equal<typeof message.payload, 3>>
|
|
117
139
|
]
|
|
118
140
|
})
|
|
119
|
-
emitter.on("x/y/z", (message) => {
|
|
120
|
-
type cases = [
|
|
121
|
-
Expect<Equal<typeof message.type, "x/y/z">>,
|
|
122
|
-
Expect<Equal<typeof message.payload, unknown>>
|
|
123
|
-
]
|
|
124
|
-
})
|
|
125
141
|
|
|
126
|
-
|
|
127
|
-
type cases = [
|
|
128
|
-
Expect<Equal<typeof message.type, "x/y/z/a">>,
|
|
129
|
-
Expect<Equal<typeof message.payload, 1>>
|
|
130
|
-
]
|
|
131
|
-
})
|
|
142
|
+
|
|
132
143
|
|
|
133
144
|
})
|
|
134
145
|
})
|
package/src/devTools.ts
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* 基于开发工具
|
|
4
|
+
*
|
|
5
|
+
* Redux DevTools 是一个实用工具,用于开发和调试 Redux 应用程序。
|
|
6
|
+
* FLEXEVENT是基于Redux DevTools 的简单包装,可以让开发者使用Redux DevTools
|
|
7
|
+
* 来查看FLEXEVENT的状态变化
|
|
8
|
+
*
|
|
9
|
+
* import { createStore } from "@FLEXEVENTjs/react"
|
|
10
|
+
* import { install } from "@FLEXEVENTjs/devtools"
|
|
11
|
+
*
|
|
12
|
+
*
|
|
13
|
+
* const store = createStore({})
|
|
14
|
+
*
|
|
15
|
+
* install()
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
//@ts-ignore
|
|
20
|
+
import { legacy_createStore as createStore } from "redux"
|
|
21
|
+
import { WeakObjectMap } from "./utils/WeakObjectMap"
|
|
22
|
+
import { FastEvent } from "./event"
|
|
23
|
+
|
|
24
|
+
const initialState = {
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
function getDefaultFastEventState(instance: FastEvent) {
|
|
30
|
+
return {
|
|
31
|
+
messageCount: 0,
|
|
32
|
+
listenerCount: instance.listenerCount,
|
|
33
|
+
retainMessageCount: instance.retainedMessages.size,
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class FlexEventDevTools {
|
|
38
|
+
private reduxStore: any
|
|
39
|
+
private _installed: boolean = false
|
|
40
|
+
fastEvents = new WeakObjectMap()
|
|
41
|
+
constructor() {
|
|
42
|
+
this.install()
|
|
43
|
+
}
|
|
44
|
+
add(instance: FastEvent) {
|
|
45
|
+
this.fastEvents.set(instance.id, instance)
|
|
46
|
+
|
|
47
|
+
instance.options.onAddListener = (type: string[], listener: any) => {
|
|
48
|
+
this.reduxStore.dispatch({
|
|
49
|
+
type: "__ADD_LISTENER__",
|
|
50
|
+
event: type.join("/"),
|
|
51
|
+
listener,
|
|
52
|
+
fastEventId: instance.id
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
instance.options.onRemoveListener = (type: string[], listener: any) => {
|
|
56
|
+
this.reduxStore.dispatch({
|
|
57
|
+
type: "__REMOVE_LISTENER__",
|
|
58
|
+
event: type.join("/"),
|
|
59
|
+
listener,
|
|
60
|
+
fastEventId: instance.id
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
instance.options.onClearListeners = () => {
|
|
64
|
+
this.reduxStore.dispatch({
|
|
65
|
+
type: "__CLEAR_LISTENERS__",
|
|
66
|
+
fastEventId: instance.id
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
instance.options.onExecuteListener = (message, returns, listeners) => {
|
|
70
|
+
const results = returns.map(r => r instanceof Error ? `Error(${r.message})` : r)
|
|
71
|
+
const sresults = listeners.map(listener => (listener as any).name || 'anonymous')
|
|
72
|
+
.reduce((pre, cur, index) => {
|
|
73
|
+
pre[cur] = results[index]
|
|
74
|
+
return pre
|
|
75
|
+
}, {})
|
|
76
|
+
console.log(`FastEvent<\x1B[31m${message.type}<\x1B[30m> is emit, listeners:`, listeners)
|
|
77
|
+
this.reduxStore.dispatch({
|
|
78
|
+
type: message.type,
|
|
79
|
+
payload: message.payload,
|
|
80
|
+
meta: message.meta,
|
|
81
|
+
returns: sresults,
|
|
82
|
+
fastEventId: instance.id
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
this.reduxStore.dispatch({
|
|
86
|
+
type: "__ADD_FASTEVENT__",
|
|
87
|
+
fastEventId: instance.id
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
remove(instance: FastEvent) {
|
|
91
|
+
if (this.fastEvents.has(instance.id)) {
|
|
92
|
+
this.fastEvents.delete(instance.id)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
private reducer(state: any = initialState, action: any) {
|
|
96
|
+
if (action.type.startsWith("@@")) return state
|
|
97
|
+
const instance = this.fastEvents.get(action.fastEventId) as FastEvent
|
|
98
|
+
if (action.type === '__ADD_FASTEVENT__') {
|
|
99
|
+
return {
|
|
100
|
+
...state,
|
|
101
|
+
[action.fastEventId]: getDefaultFastEventState(instance)
|
|
102
|
+
}
|
|
103
|
+
} else if (action.type == '__ADD_LISTENER__') {
|
|
104
|
+
const eventState = state[action.fastEventId] || getDefaultFastEventState(instance)
|
|
105
|
+
eventState.listenerCount++
|
|
106
|
+
return {
|
|
107
|
+
...state,
|
|
108
|
+
[action.fastEventId]: {
|
|
109
|
+
...eventState
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
} else if (action.type == '__REMOVE_LISTENER__') {
|
|
113
|
+
const eventState = state[action.fastEventId]
|
|
114
|
+
if (!eventState) return state
|
|
115
|
+
eventState.listenerCount++
|
|
116
|
+
return {
|
|
117
|
+
...state,
|
|
118
|
+
[action.fastEventId]: {
|
|
119
|
+
...eventState
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} else if (action.type === '__CLEAR_LISTENERS__') {
|
|
123
|
+
const eventState = state[action.fastEventId]
|
|
124
|
+
if (!eventState) return state
|
|
125
|
+
eventState.listenerCount++
|
|
126
|
+
return {
|
|
127
|
+
...state,
|
|
128
|
+
[action.fastEventId]: getDefaultFastEventState(instance)
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
const eventState = state[action.fastEventId]
|
|
132
|
+
if (!eventState) return state
|
|
133
|
+
eventState.messageCount++
|
|
134
|
+
eventState.listenerCount = instance.listenerCount
|
|
135
|
+
eventState.retainMessageCount = instance.retainedMessages.size
|
|
136
|
+
return {
|
|
137
|
+
...state,
|
|
138
|
+
[action.fastEventId]: { ...eventState }
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
private install() {
|
|
143
|
+
if (this._installed) return
|
|
144
|
+
this.reduxStore = createStore(
|
|
145
|
+
this.reducer.bind(this),
|
|
146
|
+
// @ts-ignore
|
|
147
|
+
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
|
|
148
|
+
);
|
|
149
|
+
this._installed = true
|
|
150
|
+
console.info('%c FlexEventDevTools installed. Please open <Redux devtools> to view. %c', "color:red;", '')
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function install() {
|
|
155
|
+
// @ts-ignore
|
|
156
|
+
if (!globalThis.__FLEXEVENT_DEVTOOLS__) globalThis.__FLEXEVENT_DEVTOOLS__ = new FlexEventDevTools()
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
declare global {
|
|
160
|
+
// @ts-ignore
|
|
161
|
+
var __FLEXEVENT_DEVTOOLS__: FlexEventDevTools
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
install()
|
|
166
|
+
|