@pixotope/event-bus 0.2.0 → 0.4.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @pixotope/event-bus@0.2.0 build /home/circleci/project/packages/event-bus
2
+ > @pixotope/event-bus@0.4.0 build /home/circleci/project/packages/event-bus
3
3
  > tsup src/index.ts --format cjs,esm --dts --sourcemap
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -8,13 +8,13 @@
8
8
  CLI Target: es2020
9
9
  CJS Build start
10
10
  ESM Build start
11
- CJS dist/index.cjs 2.39 KB
12
- CJS dist/index.cjs.map 3.90 KB
13
- CJS ⚡️ Build success in 393ms
14
- ESM dist/index.js 1.39 KB
15
- ESM dist/index.js.map 3.81 KB
16
- ESM ⚡️ Build success in 394ms
11
+ ESM dist/index.js 1.40 KB
12
+ ESM dist/index.js.map 3.67 KB
13
+ ESM ⚡️ Build success in 198ms
14
+ CJS dist/index.cjs 2.36 KB
15
+ CJS dist/index.cjs.map 3.76 KB
16
+ CJS ⚡️ Build success in 199ms
17
17
  DTS Build start
18
- DTS ⚡️ Build success in 1702ms
19
- DTS dist/index.d.cts 1.53 KB
20
- DTS dist/index.d.ts 1.53 KB
18
+ DTS ⚡️ Build success in 2192ms
19
+ DTS dist/index.d.cts 1.94 KB
20
+ DTS dist/index.d.ts 1.94 KB
@@ -1,4 +1,4 @@
1
1
 
2
- > @pixotope/event-bus@0.2.0 check-types /home/circleci/project/packages/event-bus
2
+ > @pixotope/event-bus@0.4.0 check-types /home/circleci/project/packages/event-bus
3
3
  > tsc --noEmit
4
4
 
@@ -1,14 +1,14 @@
1
1
 
2
- > @pixotope/event-bus@0.2.0 test /home/circleci/project/packages/event-bus
2
+ > @pixotope/event-bus@0.4.0 test /home/circleci/project/packages/event-bus
3
3
  > vitest
4
4
 
5
5
 
6
6
   RUN  v3.2.4 /home/circleci/project/packages/event-bus
7
7
 
8
- ✓ src/EventBus.test.ts (8 tests) 7ms
8
+ ✓ src/EventBus.test.ts (8 tests) 99ms
9
9
 
10
10
   Test Files  1 passed (1)
11
11
   Tests  8 passed (8)
12
-  Start at  17:44:39
13
-  Duration  4.21s (transform 500ms, setup 0ms, collect 286ms, tests 7ms, environment 0ms, prepare 1.11s)
12
+  Start at  16:16:57
13
+  Duration  4.18s (transform 712ms, setup 0ms, collect 893ms, tests 99ms, environment 0ms, prepare 1.21s)
14
14
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @pixotope/event-bus
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1a24c42: stronger event-bus types
8
+
9
+ ## 0.3.0
10
+
11
+ ### Minor Changes
12
+
13
+ - dddca36: use set for event bus
14
+
3
15
  ## 0.2.0
4
16
 
5
17
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -22,8 +22,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
22
22
  // src/index.ts
23
23
  var index_exports = {};
24
24
  __export(index_exports, {
25
- EventBus: () => EventBus,
26
- createEventBus: () => createEventBus
25
+ EventBus: () => EventBus
27
26
  });
28
27
  module.exports = __toCommonJS(index_exports);
29
28
 
@@ -36,48 +35,45 @@ var EventBus = class {
36
35
  on(type, handler) {
37
36
  const handlers = this.all.get(type);
38
37
  if (handlers) {
39
- handlers.push(handler);
38
+ handlers.add(handler);
40
39
  } else {
41
- this.all.set(type, [handler]);
40
+ this.all.set(type, /* @__PURE__ */ new Set([handler]));
42
41
  }
43
42
  return () => this.off(type, handler);
44
43
  }
44
+ /**
45
+ * Remove an event handler
46
+ * @param type - The event type
47
+ * @param handler - The event handler
48
+ */
45
49
  off(type, handler) {
46
- const handlers = this.all.get(type);
47
- if (handlers) {
48
- if (handler) {
49
- handlers.splice(handlers.indexOf(handler) >>> 0, 1);
50
- } else {
51
- this.all.set(type, []);
52
- }
53
- }
50
+ return this.all.get(type)?.delete(handler) ?? false;
54
51
  }
52
+ /**
53
+ * Emit an event
54
+ * @param type - The event type
55
+ * @param args - The event arguments
56
+ */
55
57
  emit(type, ...args) {
56
58
  const evt = args[0];
57
59
  let handlers = this.all.get(type);
58
60
  if (handlers) {
59
- handlers.forEach(
60
- (h) => h(evt)
61
- );
61
+ handlers.forEach((h) => h(evt));
62
62
  }
63
63
  handlers = this.all.get("*");
64
64
  if (handlers) {
65
- handlers.forEach(
66
- (h) => h(type, evt)
67
- );
65
+ handlers.forEach((h) => h(type, evt));
68
66
  }
69
67
  }
68
+ /**
69
+ * Clear all event handlers
70
+ */
71
+ dispose() {
72
+ this.all.clear();
73
+ }
70
74
  };
71
- function createEventBus(defaults) {
72
- return new EventBus(
73
- new Map(
74
- Object.entries(defaults || {})
75
- )
76
- );
77
- }
78
75
  // Annotate the CommonJS export names for ESM import in node:
79
76
  0 && (module.exports = {
80
- EventBus,
81
- createEventBus
77
+ EventBus
82
78
  });
83
79
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/EventBus.ts"],"sourcesContent":["export * from \"./EventBus\";\n","export type EventType = string | symbol;\n\nexport type EmitArgs<\n Events extends Record<EventType, unknown>,\n Key extends keyof Events,\n> = undefined extends Events[Key] ? [evt?: Events[Key]] : [evt: Events[Key]];\n\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (\n type: keyof T,\n event: T[keyof T]\n) => void;\n\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<\n WildcardHandler<T>\n>;\n\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n keyof Events | \"*\",\n EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\ntype GenericEventHandler<Events extends Record<EventType, unknown>> =\n | Handler<Events[keyof Events]>\n | WildcardHandler<Events>;\n\nexport class EventBus<Events extends Record<EventType, unknown>> {\n public readonly all: EventHandlerMap<Events> = new Map();\n\n public constructor(all?: EventHandlerMap<Events>) {\n this.all = all || new Map();\n }\n\n public on<Key extends keyof Events | \"*\">(\n type: Key,\n handler: GenericEventHandler<Events>\n ) {\n const handlers: Array<GenericEventHandler<Events>> | undefined =\n this.all.get(type);\n if (handlers) {\n handlers.push(handler);\n } else {\n this.all.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n }\n\n return () => this.off(type, handler);\n }\n\n public off<Key extends keyof Events | \"*\">(\n type: Key,\n handler?: GenericEventHandler<Events>\n ) {\n const handlers: Array<GenericEventHandler<Events>> | undefined =\n this.all.get(type);\n if (handlers) {\n if (handler) {\n handlers.splice(handlers.indexOf(handler) >>> 0, 1);\n } else {\n this.all.set(type, []);\n }\n }\n }\n\n public emit<Key extends keyof Events | \"*\">(\n type: Key,\n ...args: EmitArgs<Events, Key>\n ) {\n const evt = args[0] as Events[Key];\n let handlers = this.all.get(type);\n if (handlers) {\n (handlers as EventHandlerList<Events[keyof Events]>).forEach((h) =>\n h(evt!)\n );\n }\n\n handlers = this.all.get(\"*\");\n if (handlers) {\n (handlers as WildCardEventHandlerList<Events>).forEach((h) =>\n h(type, evt!)\n );\n }\n }\n}\n\nexport function createEventBus<Events extends Record<EventType, unknown>>(\n defaults?: Record<keyof Events | \"*\", GenericEventHandler<Events>[]>\n) {\n return new EventBus<Events>(\n new Map(\n Object.entries(defaults || {}) as [\n keyof Events | \"*\",\n (\n | EventHandlerList<Events[keyof Events]>\n | WildCardEventHandlerList<Events>\n ),\n ][]\n )\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC2BO,IAAM,WAAN,MAA0D;AAAA,EAGxD,YAAY,KAA+B;AAFlD,wBAAgB,OAA+B,oBAAI,IAAI;AAGrD,SAAK,MAAM,OAAO,oBAAI,IAAI;AAAA,EAC5B;AAAA,EAEO,GACL,MACA,SACA;AACA,UAAM,WACJ,KAAK,IAAI,IAAI,IAAI;AACnB,QAAI,UAAU;AACZ,eAAS,KAAK,OAAO;AAAA,IACvB,OAAO;AACL,WAAK,IAAI,IAAI,MAAM,CAAC,OAAO,CAA2C;AAAA,IACxE;AAEA,WAAO,MAAM,KAAK,IAAI,MAAM,OAAO;AAAA,EACrC;AAAA,EAEO,IACL,MACA,SACA;AACA,UAAM,WACJ,KAAK,IAAI,IAAI,IAAI;AACnB,QAAI,UAAU;AACZ,UAAI,SAAS;AACX,iBAAS,OAAO,SAAS,QAAQ,OAAO,MAAM,GAAG,CAAC;AAAA,MACpD,OAAO;AACL,aAAK,IAAI,IAAI,MAAM,CAAC,CAAC;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA,EAEO,KACL,SACG,MACH;AACA,UAAM,MAAM,KAAK,CAAC;AAClB,QAAI,WAAW,KAAK,IAAI,IAAI,IAAI;AAChC,QAAI,UAAU;AACZ,MAAC,SAAoD;AAAA,QAAQ,CAAC,MAC5D,EAAE,GAAI;AAAA,MACR;AAAA,IACF;AAEA,eAAW,KAAK,IAAI,IAAI,GAAG;AAC3B,QAAI,UAAU;AACZ,MAAC,SAA8C;AAAA,QAAQ,CAAC,MACtD,EAAE,MAAM,GAAI;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,eACd,UACA;AACA,SAAO,IAAI;AAAA,IACT,IAAI;AAAA,MACF,OAAO,QAAQ,YAAY,CAAC,CAAC;AAAA,IAO/B;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/EventBus.ts"],"sourcesContent":["export * from \"./EventBus\";\n","export type EventType = string | symbol;\n\nexport type EmitArgs<\n Events extends Record<EventType, unknown>,\n Key extends keyof Events,\n> = undefined extends Events[Key] ? [evt?: Events[Key]] : [evt: Events[Key]];\n\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (\n type: keyof T,\n event: T[keyof T]\n) => void;\n\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n keyof Events | \"*\",\n Set<GenericEventHandler<Events>>\n>;\n\nexport type GenericEventHandler<Events extends Record<EventType, unknown>> =\n | Handler<Events[keyof Events]>\n | WildcardHandler<Events>;\n\ntype IsLooseEvents<Events extends Record<EventType, unknown>> =\n string extends keyof Events ? true : false;\n\nexport class EventBus<\n Events extends Record<EventType, unknown> = Record<EventType, unknown>,\n> {\n public readonly all: EventHandlerMap<Events> = new Map();\n\n public constructor(all?: EventHandlerMap<Events>) {\n this.all = all || new Map();\n }\n\n /**\n * Add an event handler\n * @param type - The event type\n * @param handler - The event handler\n * @returns A function to remove the event handler\n */\n public on(\n type: keyof Events,\n handler: Handler<Events[typeof type]>\n ): () => void;\n public on(type: \"*\", handler: WildcardHandler<Events>): () => void;\n public on<T extends string>(\n type: IsLooseEvents<Events> extends true ? T : never,\n handler: IsLooseEvents<Events> extends true\n ? (...args: any[]) => void\n : never\n ): () => void;\n public on(type: keyof Events | \"*\", handler: GenericEventHandler<Events>) {\n const handlers = this.all.get(type);\n if (handlers) {\n handlers.add(handler);\n } else {\n this.all.set(type, new Set([handler]));\n }\n\n return () => this.off(type, handler);\n }\n\n /**\n * Remove an event handler\n * @param type - The event type\n * @param handler - The event handler\n */\n public off(\n type: keyof Events | \"*\",\n handler: (...args: any[]) => any\n ): boolean {\n return this.all.get(type)?.delete(handler) ?? false;\n }\n\n /**\n * Emit an event\n * @param type - The event type\n * @param args - The event arguments\n */\n public emit<Key extends keyof Events>(\n type: Key,\n ...args: EmitArgs<Events, Key>\n ) {\n const evt = args[0] as Events[Key];\n let handlers = this.all.get(type);\n if (handlers) {\n (handlers as Set<Handler<Events[Key]>>).forEach((h) => h(evt!));\n }\n\n handlers = this.all.get(\"*\");\n if (handlers) {\n (handlers as Set<WildcardHandler<Events>>).forEach((h) => h(type, evt!));\n }\n }\n\n /**\n * Clear all event handlers\n */\n public dispose() {\n this.all.clear();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACyBO,IAAM,WAAN,MAEL;AAAA,EAGO,YAAY,KAA+B;AAFlD,wBAAgB,OAA+B,oBAAI,IAAI;AAGrD,SAAK,MAAM,OAAO,oBAAI,IAAI;AAAA,EAC5B;AAAA,EAmBO,GAAG,MAA0B,SAAsC;AACxE,UAAM,WAAW,KAAK,IAAI,IAAI,IAAI;AAClC,QAAI,UAAU;AACZ,eAAS,IAAI,OAAO;AAAA,IACtB,OAAO;AACL,WAAK,IAAI,IAAI,MAAM,oBAAI,IAAI,CAAC,OAAO,CAAC,CAAC;AAAA,IACvC;AAEA,WAAO,MAAM,KAAK,IAAI,MAAM,OAAO;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,IACL,MACA,SACS;AACT,WAAO,KAAK,IAAI,IAAI,IAAI,GAAG,OAAO,OAAO,KAAK;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,KACL,SACG,MACH;AACA,UAAM,MAAM,KAAK,CAAC;AAClB,QAAI,WAAW,KAAK,IAAI,IAAI,IAAI;AAChC,QAAI,UAAU;AACZ,MAAC,SAAuC,QAAQ,CAAC,MAAM,EAAE,GAAI,CAAC;AAAA,IAChE;AAEA,eAAW,KAAK,IAAI,IAAI,GAAG;AAC3B,QAAI,UAAU;AACZ,MAAC,SAA0C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAI,CAAC;AAAA,IACzE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,UAAU;AACf,SAAK,IAAI,MAAM;AAAA,EACjB;AACF;","names":[]}
package/dist/index.d.cts CHANGED
@@ -2,17 +2,37 @@ type EventType = string | symbol;
2
2
  type EmitArgs<Events extends Record<EventType, unknown>, Key extends keyof Events> = undefined extends Events[Key] ? [evt?: Events[Key]] : [evt: Events[Key]];
3
3
  type Handler<T = unknown> = (event: T) => void;
4
4
  type WildcardHandler<T = Record<string, unknown>> = (type: keyof T, event: T[keyof T]) => void;
5
- type EventHandlerList<T = unknown> = Array<Handler<T>>;
6
- type WildCardEventHandlerList<T = Record<string, unknown>> = Array<WildcardHandler<T>>;
7
- type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<keyof Events | "*", EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>>;
5
+ type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<keyof Events | "*", Set<GenericEventHandler<Events>>>;
8
6
  type GenericEventHandler<Events extends Record<EventType, unknown>> = Handler<Events[keyof Events]> | WildcardHandler<Events>;
9
- declare class EventBus<Events extends Record<EventType, unknown>> {
7
+ type IsLooseEvents<Events extends Record<EventType, unknown>> = string extends keyof Events ? true : false;
8
+ declare class EventBus<Events extends Record<EventType, unknown> = Record<EventType, unknown>> {
10
9
  readonly all: EventHandlerMap<Events>;
11
10
  constructor(all?: EventHandlerMap<Events>);
12
- on<Key extends keyof Events | "*">(type: Key, handler: GenericEventHandler<Events>): () => void;
13
- off<Key extends keyof Events | "*">(type: Key, handler?: GenericEventHandler<Events>): void;
14
- emit<Key extends keyof Events | "*">(type: Key, ...args: EmitArgs<Events, Key>): void;
11
+ /**
12
+ * Add an event handler
13
+ * @param type - The event type
14
+ * @param handler - The event handler
15
+ * @returns A function to remove the event handler
16
+ */
17
+ on(type: keyof Events, handler: Handler<Events[typeof type]>): () => void;
18
+ on(type: "*", handler: WildcardHandler<Events>): () => void;
19
+ on<T extends string>(type: IsLooseEvents<Events> extends true ? T : never, handler: IsLooseEvents<Events> extends true ? (...args: any[]) => void : never): () => void;
20
+ /**
21
+ * Remove an event handler
22
+ * @param type - The event type
23
+ * @param handler - The event handler
24
+ */
25
+ off(type: keyof Events | "*", handler: (...args: any[]) => any): boolean;
26
+ /**
27
+ * Emit an event
28
+ * @param type - The event type
29
+ * @param args - The event arguments
30
+ */
31
+ emit<Key extends keyof Events>(type: Key, ...args: EmitArgs<Events, Key>): void;
32
+ /**
33
+ * Clear all event handlers
34
+ */
35
+ dispose(): void;
15
36
  }
16
- declare function createEventBus<Events extends Record<EventType, unknown>>(defaults?: Record<keyof Events | "*", GenericEventHandler<Events>[]>): EventBus<Events>;
17
37
 
18
- export { type EmitArgs, EventBus, type EventHandlerList, type EventHandlerMap, type EventType, type Handler, type WildCardEventHandlerList, type WildcardHandler, createEventBus };
38
+ export { type EmitArgs, EventBus, type EventHandlerMap, type EventType, type GenericEventHandler, type Handler, type WildcardHandler };
package/dist/index.d.ts CHANGED
@@ -2,17 +2,37 @@ type EventType = string | symbol;
2
2
  type EmitArgs<Events extends Record<EventType, unknown>, Key extends keyof Events> = undefined extends Events[Key] ? [evt?: Events[Key]] : [evt: Events[Key]];
3
3
  type Handler<T = unknown> = (event: T) => void;
4
4
  type WildcardHandler<T = Record<string, unknown>> = (type: keyof T, event: T[keyof T]) => void;
5
- type EventHandlerList<T = unknown> = Array<Handler<T>>;
6
- type WildCardEventHandlerList<T = Record<string, unknown>> = Array<WildcardHandler<T>>;
7
- type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<keyof Events | "*", EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>>;
5
+ type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<keyof Events | "*", Set<GenericEventHandler<Events>>>;
8
6
  type GenericEventHandler<Events extends Record<EventType, unknown>> = Handler<Events[keyof Events]> | WildcardHandler<Events>;
9
- declare class EventBus<Events extends Record<EventType, unknown>> {
7
+ type IsLooseEvents<Events extends Record<EventType, unknown>> = string extends keyof Events ? true : false;
8
+ declare class EventBus<Events extends Record<EventType, unknown> = Record<EventType, unknown>> {
10
9
  readonly all: EventHandlerMap<Events>;
11
10
  constructor(all?: EventHandlerMap<Events>);
12
- on<Key extends keyof Events | "*">(type: Key, handler: GenericEventHandler<Events>): () => void;
13
- off<Key extends keyof Events | "*">(type: Key, handler?: GenericEventHandler<Events>): void;
14
- emit<Key extends keyof Events | "*">(type: Key, ...args: EmitArgs<Events, Key>): void;
11
+ /**
12
+ * Add an event handler
13
+ * @param type - The event type
14
+ * @param handler - The event handler
15
+ * @returns A function to remove the event handler
16
+ */
17
+ on(type: keyof Events, handler: Handler<Events[typeof type]>): () => void;
18
+ on(type: "*", handler: WildcardHandler<Events>): () => void;
19
+ on<T extends string>(type: IsLooseEvents<Events> extends true ? T : never, handler: IsLooseEvents<Events> extends true ? (...args: any[]) => void : never): () => void;
20
+ /**
21
+ * Remove an event handler
22
+ * @param type - The event type
23
+ * @param handler - The event handler
24
+ */
25
+ off(type: keyof Events | "*", handler: (...args: any[]) => any): boolean;
26
+ /**
27
+ * Emit an event
28
+ * @param type - The event type
29
+ * @param args - The event arguments
30
+ */
31
+ emit<Key extends keyof Events>(type: Key, ...args: EmitArgs<Events, Key>): void;
32
+ /**
33
+ * Clear all event handlers
34
+ */
35
+ dispose(): void;
15
36
  }
16
- declare function createEventBus<Events extends Record<EventType, unknown>>(defaults?: Record<keyof Events | "*", GenericEventHandler<Events>[]>): EventBus<Events>;
17
37
 
18
- export { type EmitArgs, EventBus, type EventHandlerList, type EventHandlerMap, type EventType, type Handler, type WildCardEventHandlerList, type WildcardHandler, createEventBus };
38
+ export { type EmitArgs, EventBus, type EventHandlerMap, type EventType, type GenericEventHandler, type Handler, type WildcardHandler };
package/dist/index.js CHANGED
@@ -11,47 +11,44 @@ var EventBus = class {
11
11
  on(type, handler) {
12
12
  const handlers = this.all.get(type);
13
13
  if (handlers) {
14
- handlers.push(handler);
14
+ handlers.add(handler);
15
15
  } else {
16
- this.all.set(type, [handler]);
16
+ this.all.set(type, /* @__PURE__ */ new Set([handler]));
17
17
  }
18
18
  return () => this.off(type, handler);
19
19
  }
20
+ /**
21
+ * Remove an event handler
22
+ * @param type - The event type
23
+ * @param handler - The event handler
24
+ */
20
25
  off(type, handler) {
21
- const handlers = this.all.get(type);
22
- if (handlers) {
23
- if (handler) {
24
- handlers.splice(handlers.indexOf(handler) >>> 0, 1);
25
- } else {
26
- this.all.set(type, []);
27
- }
28
- }
26
+ return this.all.get(type)?.delete(handler) ?? false;
29
27
  }
28
+ /**
29
+ * Emit an event
30
+ * @param type - The event type
31
+ * @param args - The event arguments
32
+ */
30
33
  emit(type, ...args) {
31
34
  const evt = args[0];
32
35
  let handlers = this.all.get(type);
33
36
  if (handlers) {
34
- handlers.forEach(
35
- (h) => h(evt)
36
- );
37
+ handlers.forEach((h) => h(evt));
37
38
  }
38
39
  handlers = this.all.get("*");
39
40
  if (handlers) {
40
- handlers.forEach(
41
- (h) => h(type, evt)
42
- );
41
+ handlers.forEach((h) => h(type, evt));
43
42
  }
44
43
  }
44
+ /**
45
+ * Clear all event handlers
46
+ */
47
+ dispose() {
48
+ this.all.clear();
49
+ }
45
50
  };
46
- function createEventBus(defaults) {
47
- return new EventBus(
48
- new Map(
49
- Object.entries(defaults || {})
50
- )
51
- );
52
- }
53
51
  export {
54
- EventBus,
55
- createEventBus
52
+ EventBus
56
53
  };
57
54
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/EventBus.ts"],"sourcesContent":["export type EventType = string | symbol;\n\nexport type EmitArgs<\n Events extends Record<EventType, unknown>,\n Key extends keyof Events,\n> = undefined extends Events[Key] ? [evt?: Events[Key]] : [evt: Events[Key]];\n\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (\n type: keyof T,\n event: T[keyof T]\n) => void;\n\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<\n WildcardHandler<T>\n>;\n\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n keyof Events | \"*\",\n EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\ntype GenericEventHandler<Events extends Record<EventType, unknown>> =\n | Handler<Events[keyof Events]>\n | WildcardHandler<Events>;\n\nexport class EventBus<Events extends Record<EventType, unknown>> {\n public readonly all: EventHandlerMap<Events> = new Map();\n\n public constructor(all?: EventHandlerMap<Events>) {\n this.all = all || new Map();\n }\n\n public on<Key extends keyof Events | \"*\">(\n type: Key,\n handler: GenericEventHandler<Events>\n ) {\n const handlers: Array<GenericEventHandler<Events>> | undefined =\n this.all.get(type);\n if (handlers) {\n handlers.push(handler);\n } else {\n this.all.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n }\n\n return () => this.off(type, handler);\n }\n\n public off<Key extends keyof Events | \"*\">(\n type: Key,\n handler?: GenericEventHandler<Events>\n ) {\n const handlers: Array<GenericEventHandler<Events>> | undefined =\n this.all.get(type);\n if (handlers) {\n if (handler) {\n handlers.splice(handlers.indexOf(handler) >>> 0, 1);\n } else {\n this.all.set(type, []);\n }\n }\n }\n\n public emit<Key extends keyof Events | \"*\">(\n type: Key,\n ...args: EmitArgs<Events, Key>\n ) {\n const evt = args[0] as Events[Key];\n let handlers = this.all.get(type);\n if (handlers) {\n (handlers as EventHandlerList<Events[keyof Events]>).forEach((h) =>\n h(evt!)\n );\n }\n\n handlers = this.all.get(\"*\");\n if (handlers) {\n (handlers as WildCardEventHandlerList<Events>).forEach((h) =>\n h(type, evt!)\n );\n }\n }\n}\n\nexport function createEventBus<Events extends Record<EventType, unknown>>(\n defaults?: Record<keyof Events | \"*\", GenericEventHandler<Events>[]>\n) {\n return new EventBus<Events>(\n new Map(\n Object.entries(defaults || {}) as [\n keyof Events | \"*\",\n (\n | EventHandlerList<Events[keyof Events]>\n | WildCardEventHandlerList<Events>\n ),\n ][]\n )\n );\n}\n"],"mappings":";;;;;AA2BO,IAAM,WAAN,MAA0D;AAAA,EAGxD,YAAY,KAA+B;AAFlD,wBAAgB,OAA+B,oBAAI,IAAI;AAGrD,SAAK,MAAM,OAAO,oBAAI,IAAI;AAAA,EAC5B;AAAA,EAEO,GACL,MACA,SACA;AACA,UAAM,WACJ,KAAK,IAAI,IAAI,IAAI;AACnB,QAAI,UAAU;AACZ,eAAS,KAAK,OAAO;AAAA,IACvB,OAAO;AACL,WAAK,IAAI,IAAI,MAAM,CAAC,OAAO,CAA2C;AAAA,IACxE;AAEA,WAAO,MAAM,KAAK,IAAI,MAAM,OAAO;AAAA,EACrC;AAAA,EAEO,IACL,MACA,SACA;AACA,UAAM,WACJ,KAAK,IAAI,IAAI,IAAI;AACnB,QAAI,UAAU;AACZ,UAAI,SAAS;AACX,iBAAS,OAAO,SAAS,QAAQ,OAAO,MAAM,GAAG,CAAC;AAAA,MACpD,OAAO;AACL,aAAK,IAAI,IAAI,MAAM,CAAC,CAAC;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA,EAEO,KACL,SACG,MACH;AACA,UAAM,MAAM,KAAK,CAAC;AAClB,QAAI,WAAW,KAAK,IAAI,IAAI,IAAI;AAChC,QAAI,UAAU;AACZ,MAAC,SAAoD;AAAA,QAAQ,CAAC,MAC5D,EAAE,GAAI;AAAA,MACR;AAAA,IACF;AAEA,eAAW,KAAK,IAAI,IAAI,GAAG;AAC3B,QAAI,UAAU;AACZ,MAAC,SAA8C;AAAA,QAAQ,CAAC,MACtD,EAAE,MAAM,GAAI;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,eACd,UACA;AACA,SAAO,IAAI;AAAA,IACT,IAAI;AAAA,MACF,OAAO,QAAQ,YAAY,CAAC,CAAC;AAAA,IAO/B;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/EventBus.ts"],"sourcesContent":["export type EventType = string | symbol;\n\nexport type EmitArgs<\n Events extends Record<EventType, unknown>,\n Key extends keyof Events,\n> = undefined extends Events[Key] ? [evt?: Events[Key]] : [evt: Events[Key]];\n\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (\n type: keyof T,\n event: T[keyof T]\n) => void;\n\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n keyof Events | \"*\",\n Set<GenericEventHandler<Events>>\n>;\n\nexport type GenericEventHandler<Events extends Record<EventType, unknown>> =\n | Handler<Events[keyof Events]>\n | WildcardHandler<Events>;\n\ntype IsLooseEvents<Events extends Record<EventType, unknown>> =\n string extends keyof Events ? true : false;\n\nexport class EventBus<\n Events extends Record<EventType, unknown> = Record<EventType, unknown>,\n> {\n public readonly all: EventHandlerMap<Events> = new Map();\n\n public constructor(all?: EventHandlerMap<Events>) {\n this.all = all || new Map();\n }\n\n /**\n * Add an event handler\n * @param type - The event type\n * @param handler - The event handler\n * @returns A function to remove the event handler\n */\n public on(\n type: keyof Events,\n handler: Handler<Events[typeof type]>\n ): () => void;\n public on(type: \"*\", handler: WildcardHandler<Events>): () => void;\n public on<T extends string>(\n type: IsLooseEvents<Events> extends true ? T : never,\n handler: IsLooseEvents<Events> extends true\n ? (...args: any[]) => void\n : never\n ): () => void;\n public on(type: keyof Events | \"*\", handler: GenericEventHandler<Events>) {\n const handlers = this.all.get(type);\n if (handlers) {\n handlers.add(handler);\n } else {\n this.all.set(type, new Set([handler]));\n }\n\n return () => this.off(type, handler);\n }\n\n /**\n * Remove an event handler\n * @param type - The event type\n * @param handler - The event handler\n */\n public off(\n type: keyof Events | \"*\",\n handler: (...args: any[]) => any\n ): boolean {\n return this.all.get(type)?.delete(handler) ?? false;\n }\n\n /**\n * Emit an event\n * @param type - The event type\n * @param args - The event arguments\n */\n public emit<Key extends keyof Events>(\n type: Key,\n ...args: EmitArgs<Events, Key>\n ) {\n const evt = args[0] as Events[Key];\n let handlers = this.all.get(type);\n if (handlers) {\n (handlers as Set<Handler<Events[Key]>>).forEach((h) => h(evt!));\n }\n\n handlers = this.all.get(\"*\");\n if (handlers) {\n (handlers as Set<WildcardHandler<Events>>).forEach((h) => h(type, evt!));\n }\n }\n\n /**\n * Clear all event handlers\n */\n public dispose() {\n this.all.clear();\n }\n}\n"],"mappings":";;;;;AAyBO,IAAM,WAAN,MAEL;AAAA,EAGO,YAAY,KAA+B;AAFlD,wBAAgB,OAA+B,oBAAI,IAAI;AAGrD,SAAK,MAAM,OAAO,oBAAI,IAAI;AAAA,EAC5B;AAAA,EAmBO,GAAG,MAA0B,SAAsC;AACxE,UAAM,WAAW,KAAK,IAAI,IAAI,IAAI;AAClC,QAAI,UAAU;AACZ,eAAS,IAAI,OAAO;AAAA,IACtB,OAAO;AACL,WAAK,IAAI,IAAI,MAAM,oBAAI,IAAI,CAAC,OAAO,CAAC,CAAC;AAAA,IACvC;AAEA,WAAO,MAAM,KAAK,IAAI,MAAM,OAAO;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,IACL,MACA,SACS;AACT,WAAO,KAAK,IAAI,IAAI,IAAI,GAAG,OAAO,OAAO,KAAK;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,KACL,SACG,MACH;AACA,UAAM,MAAM,KAAK,CAAC;AAClB,QAAI,WAAW,KAAK,IAAI,IAAI,IAAI;AAChC,QAAI,UAAU;AACZ,MAAC,SAAuC,QAAQ,CAAC,MAAM,EAAE,GAAI,CAAC;AAAA,IAChE;AAEA,eAAW,KAAK,IAAI,IAAI,GAAG;AAC3B,QAAI,UAAU;AACZ,MAAC,SAA0C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAI,CAAC;AAAA,IACzE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,UAAU;AACf,SAAK,IAAI,MAAM;AAAA,EACjB;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixotope/event-bus",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Typed in-memory event bus for Pixotope Foundation",
5
5
  "private": false,
6
6
  "type": "module",
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, vi } from "vitest";
2
- import { EventBus, createEventBus } from "./EventBus";
2
+ import { EventBus } from "./EventBus";
3
3
 
4
4
  describe("EventBus", () => {
5
5
  it("should create an event bus", () => {
@@ -11,8 +11,8 @@ describe("EventBus", () => {
11
11
  const bus = new EventBus();
12
12
  const handler = vi.fn();
13
13
  bus.on("test", handler);
14
- bus.emit("test");
15
- expect(handler).toHaveBeenCalled();
14
+ bus.emit("test", { payload: "test" });
15
+ expect(handler).toHaveBeenCalledWith({ payload: "test" });
16
16
  });
17
17
 
18
18
  it("should be able to off an event", () => {
@@ -24,45 +24,97 @@ describe("EventBus", () => {
24
24
  expect(handler).not.toHaveBeenCalled();
25
25
  });
26
26
 
27
- it("should be able to off all events", () => {
27
+ it("should be able to emit an event with a wildcard handler", () => {
28
28
  const bus = new EventBus();
29
29
  const handler = vi.fn();
30
- bus.on("test", handler);
31
- bus.off("test");
32
- bus.emit("test");
33
- expect(handler).not.toHaveBeenCalled();
30
+ bus.on("*", handler);
31
+ bus.emit("test", { payload: "test" });
32
+ expect(handler).toHaveBeenCalledWith("test", { payload: "test" });
34
33
  });
35
34
 
36
- it("should be able to off a specific event", () => {
35
+ it("should return off function when on is called", () => {
37
36
  const bus = new EventBus();
38
37
  const handler = vi.fn();
39
- bus.on("test", handler);
40
- bus.off("test", handler);
38
+ const off = bus.on("test", handler);
39
+ off();
41
40
  bus.emit("test");
42
41
  expect(handler).not.toHaveBeenCalled();
43
42
  });
44
43
 
45
- it("should be able to emit an event with a wildcard handler", () => {
44
+ it("should be able to achieve once functionality", () => {
46
45
  const bus = new EventBus();
47
46
  const handler = vi.fn();
48
- bus.on("*", handler);
47
+ const off = bus.on("test", () => {
48
+ handler();
49
+ off();
50
+ });
49
51
  bus.emit("test");
50
- expect(handler).toHaveBeenCalled();
52
+ bus.emit("test");
53
+ expect(handler).toHaveBeenCalledTimes(1);
51
54
  });
52
55
 
53
- it("should return off function when on is called", () => {
54
- const bus = new EventBus();
56
+ it("should work with correct event types", () => {
57
+ const bus = new EventBus<{
58
+ test: { payload: string };
59
+ test2: { payload: number };
60
+ test3: { payload: boolean };
61
+ }>();
55
62
  const handler = vi.fn();
56
- const off = bus.on("test", handler);
57
- off();
58
- bus.emit("test");
59
- expect(handler).not.toHaveBeenCalled();
63
+ const handler2 = vi.fn();
64
+
65
+ bus.on("test", handler);
66
+ bus.on("test", ({ payload }) => {
67
+ expect(payload).toBeTypeOf("string");
68
+ expect(payload).toBe("test");
69
+ });
70
+ bus.on("test2", ({ payload }) => {
71
+ expect(payload).toBeTypeOf("number");
72
+ expect(payload).toBe(1);
73
+ });
74
+ bus.on("test2", handler2);
75
+ bus.on("test3", ({ payload }) => {
76
+ expect(payload).toBeTypeOf("boolean");
77
+ expect(payload).toBe(true);
78
+ });
79
+
80
+ bus.emit("test", { payload: "test" });
81
+ bus.emit("test2", { payload: 1 });
82
+ bus.emit("test3", { payload: true });
83
+
84
+ expect(handler).toHaveBeenCalledWith({ payload: "test" });
85
+ expect(handler2).toHaveBeenCalledWith({ payload: 1 });
86
+
87
+ const off = bus.off("test", handler);
88
+ expect(off).toBe(true);
89
+ bus.emit("test", { payload: "test" });
90
+ expect(handler).toHaveBeenCalledTimes(1);
60
91
  });
61
- });
62
92
 
63
- describe("createEventBus", () => {
64
- it("should create an event bus with a specific type", () => {
65
- const bus = createEventBus();
66
- expect(bus).toBeDefined();
93
+ it("should be able to work without providing event types", () => {
94
+ const bus = new EventBus();
95
+ const handler = vi.fn();
96
+ const handler2 = vi.fn();
97
+
98
+ bus.on("test", ({ payload }: { payload: string }) => {
99
+ expect(payload).toBeTypeOf("string");
100
+ expect(payload).toBe("test");
101
+ });
102
+
103
+ bus.on("test", handler);
104
+ bus.emit("test", { payload: "test" });
105
+ expect(handler).toHaveBeenCalledWith({ payload: "test" });
106
+ const off = bus.off("test", handler);
107
+ expect(off).toBe(true);
108
+ bus.emit("test", { payload: "test" });
109
+ expect(handler).toHaveBeenCalledTimes(1);
110
+
111
+ bus.on("test2", handler2);
112
+ bus.emit("test2", { payload: "test2" });
113
+ bus.emit("test2", { payload: "test2" });
114
+ expect(handler2).toHaveBeenCalledTimes(2);
115
+ expect(bus.off("test2", handler2)).toBe(true);
116
+
117
+ const testTypedHandler = (_args: { payload: string }) => {};
118
+ expect(bus.off("randomChannel", testTypedHandler)).toBe(false);
67
119
  });
68
120
  });
package/src/EventBus.ts CHANGED
@@ -11,90 +11,92 @@ export type WildcardHandler<T = Record<string, unknown>> = (
11
11
  event: T[keyof T]
12
12
  ) => void;
13
13
 
14
- export type EventHandlerList<T = unknown> = Array<Handler<T>>;
15
- export type WildCardEventHandlerList<T = Record<string, unknown>> = Array<
16
- WildcardHandler<T>
17
- >;
18
-
19
14
  export type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<
20
15
  keyof Events | "*",
21
- EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>
16
+ Set<GenericEventHandler<Events>>
22
17
  >;
23
18
 
24
- type GenericEventHandler<Events extends Record<EventType, unknown>> =
19
+ export type GenericEventHandler<Events extends Record<EventType, unknown>> =
25
20
  | Handler<Events[keyof Events]>
26
21
  | WildcardHandler<Events>;
27
22
 
28
- export class EventBus<Events extends Record<EventType, unknown>> {
23
+ type IsLooseEvents<Events extends Record<EventType, unknown>> =
24
+ string extends keyof Events ? true : false;
25
+
26
+ export class EventBus<
27
+ Events extends Record<EventType, unknown> = Record<EventType, unknown>,
28
+ > {
29
29
  public readonly all: EventHandlerMap<Events> = new Map();
30
30
 
31
31
  public constructor(all?: EventHandlerMap<Events>) {
32
32
  this.all = all || new Map();
33
33
  }
34
34
 
35
- public on<Key extends keyof Events | "*">(
36
- type: Key,
37
- handler: GenericEventHandler<Events>
38
- ) {
39
- const handlers: Array<GenericEventHandler<Events>> | undefined =
40
- this.all.get(type);
35
+ /**
36
+ * Add an event handler
37
+ * @param type - The event type
38
+ * @param handler - The event handler
39
+ * @returns A function to remove the event handler
40
+ */
41
+ public on(
42
+ type: keyof Events,
43
+ handler: Handler<Events[typeof type]>
44
+ ): () => void;
45
+ public on(type: "*", handler: WildcardHandler<Events>): () => void;
46
+ public on<T extends string>(
47
+ type: IsLooseEvents<Events> extends true ? T : never,
48
+ handler: IsLooseEvents<Events> extends true
49
+ ? (...args: any[]) => void
50
+ : never
51
+ ): () => void;
52
+ public on(type: keyof Events | "*", handler: GenericEventHandler<Events>) {
53
+ const handlers = this.all.get(type);
41
54
  if (handlers) {
42
- handlers.push(handler);
55
+ handlers.add(handler);
43
56
  } else {
44
- this.all.set(type, [handler] as EventHandlerList<Events[keyof Events]>);
57
+ this.all.set(type, new Set([handler]));
45
58
  }
46
59
 
47
60
  return () => this.off(type, handler);
48
61
  }
49
62
 
50
- public off<Key extends keyof Events | "*">(
51
- type: Key,
52
- handler?: GenericEventHandler<Events>
53
- ) {
54
- const handlers: Array<GenericEventHandler<Events>> | undefined =
55
- this.all.get(type);
56
- if (handlers) {
57
- if (handler) {
58
- handlers.splice(handlers.indexOf(handler) >>> 0, 1);
59
- } else {
60
- this.all.set(type, []);
61
- }
62
- }
63
+ /**
64
+ * Remove an event handler
65
+ * @param type - The event type
66
+ * @param handler - The event handler
67
+ */
68
+ public off(
69
+ type: keyof Events | "*",
70
+ handler: (...args: any[]) => any
71
+ ): boolean {
72
+ return this.all.get(type)?.delete(handler) ?? false;
63
73
  }
64
74
 
65
- public emit<Key extends keyof Events | "*">(
75
+ /**
76
+ * Emit an event
77
+ * @param type - The event type
78
+ * @param args - The event arguments
79
+ */
80
+ public emit<Key extends keyof Events>(
66
81
  type: Key,
67
82
  ...args: EmitArgs<Events, Key>
68
83
  ) {
69
84
  const evt = args[0] as Events[Key];
70
85
  let handlers = this.all.get(type);
71
86
  if (handlers) {
72
- (handlers as EventHandlerList<Events[keyof Events]>).forEach((h) =>
73
- h(evt!)
74
- );
87
+ (handlers as Set<Handler<Events[Key]>>).forEach((h) => h(evt!));
75
88
  }
76
89
 
77
90
  handlers = this.all.get("*");
78
91
  if (handlers) {
79
- (handlers as WildCardEventHandlerList<Events>).forEach((h) =>
80
- h(type, evt!)
81
- );
92
+ (handlers as Set<WildcardHandler<Events>>).forEach((h) => h(type, evt!));
82
93
  }
83
94
  }
84
- }
85
95
 
86
- export function createEventBus<Events extends Record<EventType, unknown>>(
87
- defaults?: Record<keyof Events | "*", GenericEventHandler<Events>[]>
88
- ) {
89
- return new EventBus<Events>(
90
- new Map(
91
- Object.entries(defaults || {}) as [
92
- keyof Events | "*",
93
- (
94
- | EventHandlerList<Events[keyof Events]>
95
- | WildCardEventHandlerList<Events>
96
- ),
97
- ][]
98
- )
99
- );
96
+ /**
97
+ * Clear all event handlers
98
+ */
99
+ public dispose() {
100
+ this.all.clear();
101
+ }
100
102
  }