@medievalrain/emitter 0.2.20 → 0.3.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.
package/dist/index.d.ts CHANGED
@@ -1,13 +1,17 @@
1
1
  //#region src/types.d.ts
2
- type EventMap = Record<PropertyKey, (...args: any[]) => void>;
2
+ type EventMap = Record<PropertyKey, any>;
3
3
  type CallbackOptions = {
4
4
  once?: boolean;
5
5
  signal?: AbortSignal;
6
6
  };
7
- type Emitter<Events$1 extends EventMap> = {
8
- emit: <EM extends keyof Events$1>(eventName: EM, ...args: Parameters<Events$1[EM]>) => void;
9
- on: <EM extends keyof Events$1>(eventName: EM, callback: Events$1[EM], options?: CallbackOptions) => void;
10
- off: <EM extends keyof Events$1>(eventName: EM, callback: Events$1[EM]) => void;
7
+ type Callback<E extends EventMap, K$1 extends keyof E> = (...args: [E[K$1]] extends [void] ? [] : [E[K$1]]) => void;
8
+ type OnAnyCallback<Events extends EventMap> = (data: Events[keyof Events]) => void;
9
+ type Emitter<Events extends EventMap> = {
10
+ emit: <EM extends keyof Events>(eventName: EM, ...args: Parameters<Callback<Events, EM>>) => void;
11
+ on: <EM extends keyof Events>(eventName: EM, callback: Callback<Events, EM>, options?: CallbackOptions) => void;
12
+ onAny: (callback: OnAnyCallback<Events>, options?: CallbackOptions) => void;
13
+ offAny: (callback: OnAnyCallback<Events>) => void;
14
+ off: <EM extends keyof Events>(eventName: EM, callback: Callback<Events, EM>) => void;
11
15
  };
12
16
  //#endregion
13
17
  //#region src/emitter.d.ts
package/dist/index.js CHANGED
@@ -1,16 +1,16 @@
1
1
  //#region src/emitter.ts
2
2
  const createEmitter = () => {
3
- const callbackMap = /* @__PURE__ */ new Map();
3
+ const callbackMap = {};
4
+ const onAnyCallbacks = /* @__PURE__ */ new Map();
4
5
  const off = (eventName, callback) => {
5
- const callbacks = callbackMap.get(eventName);
6
+ const callbacks = callbackMap[eventName];
6
7
  if (!callbacks) return;
7
- const controller = callbacks.get(callback)?.controller;
8
- if (controller) controller.abort();
8
+ callbacks.get(callback)?.controller?.abort();
9
9
  callbacks.delete(callback);
10
- if (!callbacks.size) callbackMap.delete(eventName);
10
+ if (!callbacks.size) delete callbackMap[eventName];
11
11
  };
12
12
  const emit = (eventName, ...args) => {
13
- const callbacks = callbackMap.get(eventName);
13
+ const callbacks = callbackMap[eventName];
14
14
  if (!callbacks?.size) return;
15
15
  Array.from(callbacks.entries()).forEach(([callback, { once }]) => {
16
16
  if (!callbacks.has(callback)) return;
@@ -20,14 +20,22 @@ const createEmitter = () => {
20
20
  if (once) off(eventName, callback);
21
21
  }
22
22
  });
23
+ Array.from(onAnyCallbacks.entries()).forEach(([callback, options]) => {
24
+ if (!onAnyCallbacks.has(callback)) return;
25
+ try {
26
+ callback(args);
27
+ } finally {
28
+ if (options?.once) offAny(callback);
29
+ }
30
+ });
23
31
  };
24
32
  const on = (eventName, callback, options) => {
25
33
  if (options?.signal && options.signal.aborted) return;
26
- let callbacks = callbackMap.get(eventName);
34
+ let callbacks = callbackMap[eventName];
27
35
  let unsubController;
28
36
  if (!callbacks) {
29
37
  callbacks = /* @__PURE__ */ new Map();
30
- callbackMap.set(eventName, callbacks);
38
+ callbackMap[eventName] = callbacks;
31
39
  } else if (callbacks.get(callback)) return;
32
40
  if (options?.signal) {
33
41
  unsubController = new AbortController();
@@ -41,10 +49,32 @@ const createEmitter = () => {
41
49
  controller: unsubController
42
50
  });
43
51
  };
52
+ const offAny = (callback) => {
53
+ onAnyCallbacks.get(callback)?.controller?.abort();
54
+ onAnyCallbacks.delete(callback);
55
+ };
56
+ const onAny = (callback, options) => {
57
+ if (options?.signal && options.signal.aborted) return;
58
+ if (onAnyCallbacks.get(callback)) return;
59
+ let unsubController;
60
+ if (options?.signal) {
61
+ unsubController = new AbortController();
62
+ options.signal.addEventListener("abort", () => offAny(callback), {
63
+ once: true,
64
+ signal: unsubController.signal
65
+ });
66
+ }
67
+ onAnyCallbacks.set(callback, {
68
+ once: options?.once,
69
+ controller: unsubController
70
+ });
71
+ };
44
72
  return {
45
73
  emit,
46
74
  on,
47
- off
75
+ off,
76
+ onAny,
77
+ offAny
48
78
  };
49
79
  };
50
80
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medievalrain/emitter",
3
- "version": "0.2.20",
3
+ "version": "0.3.0",
4
4
  "description": "A typesafe event emitter",
5
5
  "type": "module",
6
6
  "repository": {
@@ -29,9 +29,9 @@
29
29
  "devDependencies": {
30
30
  "oxlint": "1.24.0",
31
31
  "prettier": "3.6.2",
32
- "tsdown": "0.15.9",
32
+ "tsdown": "0.15.10",
33
33
  "typescript": "5.9.3",
34
- "vitest": "4.0.1"
34
+ "vitest": "4.0.4"
35
35
  },
36
36
  "packageManager": "pnpm@10.19.0",
37
37
  "publishConfig": {