fastevent 1.1.3 → 2.0.1

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 (80) hide show
  1. package/dist/devTools.js +2 -2
  2. package/dist/devTools.js.map +1 -1
  3. package/dist/devTools.mjs +2 -2
  4. package/dist/devTools.mjs.map +1 -1
  5. package/dist/index.d.mts +304 -53
  6. package/dist/index.d.ts +304 -53
  7. package/dist/index.js +1 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +1 -1
  10. package/dist/index.mjs.map +1 -1
  11. package/package.json +64 -50
  12. package/readme.md +517 -50
  13. package/.changeset/README.md +0 -8
  14. package/.changeset/config.json +0 -11
  15. package/.github/workflows/publish.yaml +0 -50
  16. package/.prettierrc.js +0 -20
  17. package/.vscode/launch.json +0 -20
  18. package/.vscode/settings.json +0 -18
  19. package/CHANGELOG.md +0 -60
  20. package/LICENSE +0 -21
  21. package/bench.png +0 -0
  22. package/dist/devTools.d.mts +0 -543
  23. package/dist/devTools.d.ts +0 -543
  24. package/example/README.md +0 -54
  25. package/example/eslint.config.js +0 -28
  26. package/example/index.html +0 -13
  27. package/example/package.json +0 -29
  28. package/example/pnpm-lock.yaml +0 -2047
  29. package/example/public/vite.svg +0 -1
  30. package/example/src/App.css +0 -42
  31. package/example/src/App.tsx +0 -60
  32. package/example/src/assets/react.svg +0 -1
  33. package/example/src/index.css +0 -68
  34. package/example/src/main.tsx +0 -10
  35. package/example/src/myEvent.ts +0 -32
  36. package/example/src/vite-env.d.ts +0 -1
  37. package/example/tsconfig.app.json +0 -26
  38. package/example/tsconfig.json +0 -7
  39. package/example/tsconfig.node.json +0 -24
  40. package/example/vite.config.ts +0 -7
  41. package/packages/native/index.ts +0 -1
  42. package/packages/turbo/.zig-cache/h/271c82d991949fd7788fd5451f0ca834.txt +0 -0
  43. package/packages/turbo/.zig-cache/h/timestamp +0 -0
  44. package/packages/turbo/.zig-cache/o/ebd7ddab8ffe003267120d598aecce68/dependencies.zig +0 -2
  45. package/packages/turbo/.zig-cache/z/c8114b040daa461a9e2eabd0357554a4 +0 -0
  46. package/packages/turbo/build.zig +0 -60
  47. package/packages/turbo/examples/basic.zig +0 -107
  48. package/packages/turbo/src/event.zig +0 -251
  49. package/packages/turbo/src/index.zig +0 -70
  50. package/packages/turbo/src/scope.zig +0 -104
  51. package/packages/turbo/src/types.zig +0 -88
  52. package/packages/turbo/src/utils.zig +0 -171
  53. package/readme_cn.md +0 -491
  54. package/src/__benchmarks__/index.ts +0 -3
  55. package/src/__benchmarks__/multi-level.ts +0 -40
  56. package/src/__benchmarks__/sample.ts +0 -40
  57. package/src/__benchmarks__/wildcard.ts +0 -41
  58. package/src/__tests__/emit.test.ts +0 -106
  59. package/src/__tests__/emitAsync.test.ts +0 -64
  60. package/src/__tests__/isPathMatched.test.ts +0 -205
  61. package/src/__tests__/many.test.ts +0 -22
  62. package/src/__tests__/meta.test.ts +0 -28
  63. package/src/__tests__/off.test.ts +0 -214
  64. package/src/__tests__/onany.test.ts +0 -212
  65. package/src/__tests__/once.test.ts +0 -70
  66. package/src/__tests__/retain.test.ts +0 -66
  67. package/src/__tests__/scope.test.ts +0 -110
  68. package/src/__tests__/types.test.ts +0 -145
  69. package/src/__tests__/waitFor.test.ts +0 -116
  70. package/src/__tests__/wildcard.test.ts +0 -185
  71. package/src/devTools.ts +0 -166
  72. package/src/event.ts +0 -741
  73. package/src/index.ts +0 -3
  74. package/src/scope.ts +0 -130
  75. package/src/types.ts +0 -66
  76. package/src/utils/WeakObjectMap.ts +0 -64
  77. package/src/utils/isPathMatched.ts +0 -40
  78. package/src/utils/removeItem.ts +0 -16
  79. package/tsconfig.json +0 -104
  80. package/tsup.config.ts +0 -30
@@ -1,116 +0,0 @@
1
- import { describe, test, expect } from "vitest"
2
- import { FastEvent } from "../event"
3
-
4
-
5
-
6
- describe("waitfor", () => {
7
-
8
- test('should resolve promise when event is emitted immediately', () => {
9
- return new Promise<void>((resolve) => {
10
- const emitter = new FastEvent();
11
- // Arrange
12
- const eventType = 'test-event';
13
- const expectedPayload = { data: 'test data' };
14
-
15
- // Act
16
- // Create a promise for waitFor and store it
17
- const waitPromise = emitter.waitFor(eventType);
18
-
19
- // Emit the event immediately after calling waitFor
20
- emitter.emit(eventType, expectedPayload);
21
-
22
- // Assert
23
- // Wait for the promise to resolve and check the result
24
- waitPromise.then(result => {
25
- expect(result).toEqual({
26
- type: eventType,
27
- payload: expectedPayload,
28
- meta: undefined
29
- });
30
- resolve()
31
- })
32
-
33
- })
34
- });
35
- test('should handle multiple events waiting simultaneously', async () => {
36
- return new Promise<void>((resolve) => {
37
- const emitter = new FastEvent();
38
- // Arrange
39
- const event1Promise = emitter.waitFor('event1');
40
- const event2Promise = emitter.waitFor('event2');
41
- const event3Promise = emitter.waitFor('event3');
42
-
43
- // Act
44
- setTimeout(() => {
45
- emitter.emit('event1', 'payload1');
46
- }, 100);
47
-
48
- setTimeout(() => {
49
- emitter.emit('event2', 'payload2');
50
- }, 200);
51
-
52
- setTimeout(() => {
53
- emitter.emit('event3', 'payload3');
54
- }, 300);
55
-
56
-
57
- // Assert
58
- Promise.all([
59
- event1Promise,
60
- event2Promise,
61
- event3Promise
62
- ]).then(results => {
63
- expect(results).toEqual([
64
- { type: 'event1', payload: 'payload1', meta: undefined },
65
- { type: 'event2', payload: 'payload2', meta: undefined },
66
- { type: 'event3', payload: 'payload3', meta: undefined }
67
- ]);
68
- resolve()
69
- })
70
- })
71
- });
72
-
73
- test('should handle multiple events with different timeouts', async () => {
74
- const emitter = new FastEvent();
75
- // Arrange
76
- const event1Promise = emitter.waitFor('event1', 500);
77
- const event2Promise = emitter.waitFor('event2', 200);
78
- const event3Promise = emitter.waitFor('event3', 1000);
79
-
80
- // Act
81
- setTimeout(() => {
82
- emitter.emit('event1', 'payload1');
83
- }, 100);
84
-
85
- setTimeout(() => {
86
- emitter.emit('event2', 'payload2');
87
- }, 300);
88
-
89
- // Event2 will timeout before emission
90
- setTimeout(() => {
91
- emitter.emit('event3', 'payload3');
92
- }, 300);
93
-
94
- // Assert
95
- const results = await Promise.allSettled([
96
- event1Promise,
97
- event2Promise,
98
- event3Promise
99
- ]);
100
-
101
- expect(results[0].status).toBe('fulfilled');
102
- expect((results[0] as any).value).toEqual({ type: 'event1', payload: 'payload1', meta: undefined });
103
-
104
-
105
- expect(results[1].status).toBe('rejected');
106
- //@ts-ignore
107
- expect(results[1].reason).toBeInstanceOf(Error);
108
-
109
- expect(results[2].status).toBe('fulfilled');
110
- expect((results[2] as any).value).toEqual({ type: 'event3', payload: 'payload3', meta: undefined });
111
-
112
- });
113
-
114
-
115
-
116
- })
@@ -1,185 +0,0 @@
1
- import { describe, test, expect } from "vitest"
2
- import { FastEvent } from "../event"
3
- import { FastEventSubscriber } from "../types"
4
-
5
-
6
- describe("基于通配符的发布与订阅", async () => {
7
-
8
- test("使用通配符发布订阅层级事件", () => {
9
- const emitter = new FastEvent()
10
- const events: string[] = []
11
- const subscribers: FastEventSubscriber[] = []
12
- subscribers.push(emitter.on("*/*/*", ({ payload, type }) => {
13
- expect(type).toBe("a/b/c")
14
- expect(payload).toBe(1)
15
- events.push(type)
16
- }))
17
- subscribers.push(emitter.on("a/*/*", ({ payload, type }) => {
18
- expect(type).toBe("a/b/c")
19
- expect(payload).toBe(1)
20
- events.push(type)
21
- }))
22
- subscribers.push(emitter.on("a/b/*", ({ payload, type }) => {
23
- expect(type).toBe("a/b/c")
24
- expect(payload).toBe(1)
25
- events.push(type)
26
- }))
27
- emitter.emit("a/b/c", 1)
28
- expect(events).toEqual(["a/b/c", "a/b/c", "a/b/c"])
29
- emitter.emit("a/b/c", 1)
30
- expect(events).toEqual(["a/b/c", "a/b/c", "a/b/c", "a/b/c", "a/b/c", "a/b/c"])
31
- subscribers.forEach(subscriber => subscriber.off())
32
- expect(events).toEqual(["a/b/c", "a/b/c", "a/b/c", "a/b/c", "a/b/c", "a/b/c"])
33
- })
34
-
35
- test("使用通配符发布订阅层级事件11", () => {
36
- const emitter = new FastEvent()
37
- const events: string[] = []
38
- const subscribers: FastEventSubscriber[] = []
39
- subscribers.push(emitter.on("*/*/*", ({ payload, type }) => {
40
- expect(type).toBe("a/b/c")
41
- expect(payload).toBe(1)
42
- events.push(type)
43
- }))
44
- emitter.emit("a/b/c", 1)
45
- expect(events).toEqual(["a/b/c"])
46
- })
47
-
48
-
49
- test("使用通配符发布订阅层级事件12", () => {
50
- const emitter = new FastEvent()
51
- const events: string[] = []
52
- const subscribers: FastEventSubscriber[] = []
53
- subscribers.push(emitter.on("a/*/*", ({ payload, type }) => {
54
- expect(type).toBe("a/b/c")
55
- expect(payload).toBe(1)
56
- events.push(type)
57
- }))
58
- emitter.emit("a/b/c", 1)
59
- expect(events).toEqual(["a/b/c"])
60
- })
61
- test("使用通配符发布订阅层级事件13", () => {
62
- const emitter = new FastEvent()
63
- const events: string[] = []
64
- const subscribers: FastEventSubscriber[] = []
65
- subscribers.push(emitter.on("a/b/*", ({ payload, type }) => {
66
- expect(type).toBe("a/b/c")
67
- expect(payload).toBe(1)
68
- events.push(type)
69
- }))
70
- emitter.emit("a/b/c", 1)
71
- expect(events).toEqual(["a/b/c"])
72
- })
73
-
74
- test("使用通配符发布订阅层级事件14", () => {
75
- const emitter = new FastEvent()
76
- const events: string[] = []
77
- const subscribers: FastEventSubscriber[] = []
78
- subscribers.push(emitter.on("*/*/*", ({ payload, type }) => {
79
- expect(type).toBe("a/b/c")
80
- expect(payload).toBe(1)
81
- events.push(type)
82
- }))
83
- subscribers.push(emitter.on("*/*/c", ({ payload, type }) => {
84
- expect(type).toBe("a/b/c")
85
- expect(payload).toBe(1)
86
- events.push(type)
87
- }))
88
- subscribers.push(emitter.on("*/b/c", ({ payload, type }) => {
89
- expect(type).toBe("a/b/c")
90
- expect(payload).toBe(1)
91
- events.push(type)
92
- }))
93
- emitter.emit("a/b/c", 1)
94
- expect(events).toEqual(["a/b/c", "a/b/c", "a/b/c"])
95
- emitter.emit("a/b/c", 1)
96
- expect(events).toEqual(["a/b/c", "a/b/c", "a/b/c", "a/b/c", "a/b/c", "a/b/c"])
97
- subscribers.forEach(subscriber => subscriber.off())
98
- expect(events).toEqual(["a/b/c", "a/b/c", "a/b/c", "a/b/c", "a/b/c", "a/b/c"])
99
- })
100
- test("使用通配符发布订阅层级事件15", () => {
101
- const emitter = new FastEvent()
102
- const events: string[] = []
103
- const subscribers: FastEventSubscriber[] = []
104
- subscribers.push(emitter.on("*/b/c", ({ payload, type }) => {
105
- expect(type).toBe("a/b/c")
106
- expect(payload).toBe(1)
107
- events.push(type)
108
- }))
109
- emitter.emit("a/b/c", 1)
110
- expect(events).toEqual(["a/b/c"])
111
- })
112
- test("使用通配符发布订阅层级事件16", () => {
113
- const emitter = new FastEvent()
114
- const events: string[] = []
115
- const subscribers: FastEventSubscriber[] = []
116
- subscribers.push(emitter.on("*/b/*/d/*/f", ({ payload, type }) => {
117
- events.push(type)
118
- }))
119
- emitter.emit("1/b/1/d/1/f", 1)
120
- emitter.emit("2/b/2/d/2/f", 1)
121
- emitter.emit("3/b/3/d/3/f", 1)
122
- emitter.emit("4/b/4/d/4/f", 1)
123
- emitter.emit("5/b/5/d/5/f", 1)
124
- expect(events).toEqual(["1/b/1/d/1/f", "2/b/2/d/2/f", "3/b/3/d/3/f", "4/b/4/d/4/f", "5/b/5/d/5/f"])
125
- })
126
- test("使用通配符发布订阅层级事件17", () => {
127
- return new Promise<void>((resolve) => {
128
- const emitter = new FastEvent()
129
- emitter.on('a/b/c/*', () => {
130
- resolve()
131
- })
132
- emitter.emit('a/b/c/x', 1)
133
- emitter.emit('a/b/c/x', 1)
134
- })
135
- })
136
- test("使用多级路径匹配", () => {
137
- const emitter = new FastEvent()
138
- const payloads: number[] = []
139
- const events: string[] = []
140
- emitter.on("a/**", ({ payload, type }) => {
141
- events.push(type)
142
- payloads.push(payload)
143
- })
144
- emitter.emit("a/b/c/d/e/f", 1)
145
- expect(events).toEqual(["a/b/c/d/e/f"])
146
- expect(payloads).toEqual([1])
147
- })
148
- test("使用多级路径匹配2", () => {
149
- const emitter = new FastEvent()
150
- const payloads: number[] = []
151
- const events: string[] = []
152
- emitter.on("a/**", ({ payload, type }) => {
153
- events.push(type)
154
- payloads.push(payload)
155
- })
156
-
157
- emitter.emit("a/b", 1)
158
- emitter.emit("a/b/c", 2)
159
- emitter.emit("a/b/c/d", 3)
160
- emitter.emit("a/b/c/d/e", 4)
161
- emitter.emit("a/b/c/d/e/f", 5)
162
- expect(events).toEqual(["a/b", "a/b/c", "a/b/c/d", "a/b/c/d/e", "a/b/c/d/e/f"])
163
- expect(payloads).toEqual([1, 2, 3, 4, 5])
164
- })
165
- test("使用多级路径匹配3", () => {
166
- const emitter = new FastEvent()
167
- const payloads: number[] = []
168
- const events: string[] = []
169
- emitter.on("a/**", ({ payload, type }) => {
170
- events.push(type)
171
- payloads.push(payload)
172
- })
173
- emitter.on("a/b/*", ({ payload, type }) => {
174
- events.push(type)
175
- payloads.push(payload)
176
- })
177
- emitter.emit("a/b/c", 1)
178
- emitter.emit("a/b/c/d", 2)
179
- emitter.emit("a/b/c/d/e", 3)
180
- emitter.emit("a/b/c/d/e/f", 4)
181
- expect(events).toEqual(["a/b/c", "a/b/c", "a/b/c/d", "a/b/c/d/e", "a/b/c/d/e/f"])
182
- expect(payloads).toEqual([1, 1, 2, 3, 4])
183
- })
184
- })
185
-
package/src/devTools.ts DELETED
@@ -1,166 +0,0 @@
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
-