@d1g1tal/subscribr 3.0.5 → 4.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.
package/LICENSE CHANGED
@@ -1,12 +1,12 @@
1
- Copyright (c) 2023, Jason DiMeo
2
-
3
- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided
4
- that the above copyright notice and this permission notice appear in all copies.
5
-
6
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
7
- INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
8
- FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
9
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
10
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
11
-
1
+ Copyright (c) 2023, Jason DiMeo
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided
4
+ that the above copyright notice and this permission notice appear in all copies.
5
+
6
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
7
+ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
8
+ FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
9
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
10
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
11
+
12
12
  Source: http://opensource.org/licenses/ISC
package/README.md CHANGED
@@ -1,75 +1,75 @@
1
- # subscribr
2
- JavaScript Publish/Subscribe
3
-
4
- This simple class enables you to subscribe and publish events using the Observer pattern.
5
-
6
- Basically, you subscribe your event handler using the `Subscribr` instance and are returned a `Subscription` instance.
7
-
8
- When the event is published, your event handler will be called.
9
-
10
- ### Installation:
11
- ```bash
12
- # Install with pnpm
13
- pnpm install @d1g1tal/subscribr
14
-
15
- # Install with NPM
16
- npm install @d1g1tal/subscribr
17
- ```
18
- Or Script tags from downloaded script or from a NPM CDN like jsDelivr
19
-
20
- ```html
21
- <!-- Load as global script -->
22
- <script src="/subscribr/dist/iife/subscribr.min.js"></script>
23
-
24
- <!-- Load from CDN -->
25
- <script src="https://cdn.jsdelivr.net/npm/@d1g1tal/subscribr@3/dist/iife/subscribr.min.js"></script>
26
-
27
- <!-- Load as ES Module -->
28
- <script type="module">
29
- import Subscribr from '/app/js/subscribr.min.js';
30
- </script>
31
-
32
- <!-- Load from CDN -->
33
- <script type="module">
34
- import Subscribr from 'https://cdn.jsdelivr.net/npm/@d1g1tal/subscribr@3/dist/subscribr.min.js';
35
- </script>
36
- ```
37
-
38
- ### Usage:
39
- ```javascript
40
- // ES Module
41
- import Subscribr from '@d1g1tal/subscribr';
42
-
43
- const subscribr = new Subscribr();
44
- const eventName = 'myEvent';
45
-
46
- // Subscribr.prototype.subscribe returns a Subscription object.
47
- const mySubscription = subscribr.subscribe(eventName, (event, data) => console.log(`Event: '${event.type}' published with data: ${data}`));
48
-
49
- // Publish the event with just the name and a CustomEvent will be created with the eventName. All handlers that have subscribed are called
50
- subscribr.publish(eventName, { foo: 'bar', zip: 'fizz' }); // Event: 'myEvent' published with data: { foo: 'bar', zip: 'fizz' }
51
-
52
- // Is the event subscribed?
53
- const isSubscribed = subscribr.isSubscribed(mySubscription); // true
54
-
55
- const isUnsubscribed = subscribr.unsubscribe(mySubscription); // true
56
-
57
- const isSubscribed = subscribr.isSubscribed(mySubscription); // false
58
-
59
-
60
- // Subscribe to a DOM event
61
- const eventTargetSubscription = subsribr.subscribe('eventTargetChanged', (event, data) => console.log(`Event target changed with data: ${data}`));
62
-
63
- // Add some event to an event target (DOMElement)
64
- new EventTarget().addEventListener('change', function(event) {
65
- // Publish the event and all handlers that have subscribed are called
66
- subscribr.publish('eventTargetChanged', event, { value: this.value }); // Event target changed with data: {value: 'new value'}
67
- });
68
-
69
- // Is the event subscribed?
70
- const isSubscribed = subscribr.isSubscribed(eventTargetSubscription); // true
71
-
72
- const isUnsubscribed = subscribr.unsubscribe(eventTargetSubscription); // true
73
-
74
- const isSubscribed = subscribr.isSubscribed(eventTargetSubscription); // false
1
+ # subscribr
2
+ JavaScript Publish/Subscribe
3
+
4
+ This simple class enables you to subscribe and publish events using the Observer pattern.
5
+
6
+ Basically, you subscribe your event handler using the `Subscribr` instance and are returned a `Subscription` instance.
7
+
8
+ When the event is published, your event handler will be called.
9
+
10
+ ### Installation:
11
+ ```bash
12
+ # Install with pnpm
13
+ pnpm install @d1g1tal/subscribr
14
+
15
+ # Install with NPM
16
+ npm install @d1g1tal/subscribr
17
+ ```
18
+ Or Script tags from downloaded script or from a NPM CDN like jsDelivr
19
+
20
+ ```html
21
+ <!-- Load as global script -->
22
+ <script src="/subscribr/dist/iife/subscribr.min.js"></script>
23
+
24
+ <!-- Load from CDN -->
25
+ <script src="https://cdn.jsdelivr.net/npm/@d1g1tal/subscribr@3/dist/iife/subscribr.min.js"></script>
26
+
27
+ <!-- Load as ES Module -->
28
+ <script type="module">
29
+ import Subscribr from '/app/js/subscribr.min.js';
30
+ </script>
31
+
32
+ <!-- Load from CDN -->
33
+ <script type="module">
34
+ import Subscribr from 'https://cdn.jsdelivr.net/npm/@d1g1tal/subscribr@3/dist/subscribr.min.js';
35
+ </script>
36
+ ```
37
+
38
+ ### Usage:
39
+ ```javascript
40
+ // ES Module
41
+ import Subscribr from '@d1g1tal/subscribr';
42
+
43
+ const subscribr = new Subscribr();
44
+ const eventName = 'myEvent';
45
+
46
+ // Subscribr.prototype.subscribe returns a Subscription object.
47
+ const mySubscription = subscribr.subscribe(eventName, (event, data) => console.log(`Event: '${event.type}' published with data: ${data}`));
48
+
49
+ // Publish the event with just the name and a CustomEvent will be created with the eventName. All handlers that have subscribed are called
50
+ subscribr.publish(eventName, { foo: 'bar', zip: 'fizz' }); // Event: 'myEvent' published with data: { foo: 'bar', zip: 'fizz' }
51
+
52
+ // Is the event subscribed?
53
+ const isSubscribed = subscribr.isSubscribed(mySubscription); // true
54
+
55
+ const isUnsubscribed = subscribr.unsubscribe(mySubscription); // true
56
+
57
+ const isSubscribed = subscribr.isSubscribed(mySubscription); // false
58
+
59
+
60
+ // Subscribe to a DOM event
61
+ const eventTargetSubscription = subsribr.subscribe('eventTargetChanged', (event, data) => console.log(`Event target changed with data: ${data}`));
62
+
63
+ // Add some event to an event target (DOMElement)
64
+ new EventTarget().addEventListener('change', function(event) {
65
+ // Publish the event and all handlers that have subscribed are called
66
+ subscribr.publish('eventTargetChanged', event, { value: this.value }); // Event target changed with data: {value: 'new value'}
67
+ });
68
+
69
+ // Is the event subscribed?
70
+ const isSubscribed = subscribr.isSubscribed(eventTargetSubscription); // true
71
+
72
+ const isUnsubscribed = subscribr.unsubscribe(eventTargetSubscription); // true
73
+
74
+ const isSubscribed = subscribr.isSubscribed(eventTargetSubscription); // false
75
75
  ```
@@ -0,0 +1,109 @@
1
+ /** Context event listener function. */
2
+ type ContextEventListener = (event: Event, data?: unknown) => void;
3
+
4
+ /** A wrapper for an event handler that binds a context to the event handler. */
5
+ declare class ContextEventHandler {
6
+ private readonly context;
7
+ private readonly eventListener;
8
+ /**
9
+ * @param {unknown} context The context to bind to the event handler.
10
+ * @param {ContextEventListener} eventListener The event handler to call when the event is published.
11
+ */
12
+ constructor(context: unknown, eventListener: ContextEventListener);
13
+ /**
14
+ * Call the event handler for the provided event.
15
+ *
16
+ * @param {Event} event The event to handle
17
+ * @param {unknown?} [data] The value to be passed to the event handler as a parameter.
18
+ */
19
+ handle(event: Event, data?: unknown): void;
20
+ /**
21
+ * A String value that is used in the creation of the default string
22
+ * description of an object. Called by the built-in method {@link Object.prototype.toString}.
23
+ *
24
+ * @returns {string} The default string description of this object.
25
+ */
26
+ get [Symbol.toStringTag](): string;
27
+ }
28
+
29
+ /** Represents a subscription to an event. */
30
+ declare class Subscription {
31
+ private readonly _eventName;
32
+ private readonly _contextEventHandler;
33
+ /**
34
+ * @param {string} eventName The event name.
35
+ * @param {ContextEventHandler} contextEventHandler Then context event handler.
36
+ */
37
+ constructor(eventName: string, contextEventHandler: ContextEventHandler);
38
+ /**
39
+ * Gets the event name for the subscription.
40
+ *
41
+ * @returns {string} The event name.
42
+ */
43
+ get eventName(): string;
44
+ /**
45
+ * Gets the context event handler.
46
+ *
47
+ * @returns {ContextEventHandler} The context event handler
48
+ */
49
+ get contextEventHandler(): ContextEventHandler;
50
+ /**
51
+ * A String value that is used in the creation of the default string
52
+ * description of an object. Called by the built-in method {@link Object.prototype.toString}.
53
+ *
54
+ * @returns {string} The default string description of this object.
55
+ */
56
+ get [Symbol.toStringTag](): string;
57
+ }
58
+
59
+ /**
60
+ * A class that allows objects to subscribe to events and be notified when the event is published.
61
+ *
62
+ * @class
63
+ * @exports Subscribr
64
+ */
65
+ declare class Subscribr {
66
+ private readonly subscribers;
67
+ constructor();
68
+ /**
69
+ * Subscribe to an event
70
+ *
71
+ * @param {string} eventName The event name to subscribe to.
72
+ * @param {ContextEventListener} eventHandler The event handler to call when the event is published.
73
+ * @param {unknown} [context] The context to bind to the event handler.
74
+ * @returns {Subscription} An object used to check if the subscription still exists and to unsubscribe from the event.
75
+ */
76
+ subscribe(eventName: string, eventHandler: ContextEventListener, context?: unknown): Subscription;
77
+ /**
78
+ * Unsubscribe from the event
79
+ *
80
+ * @param {Subscription} subscription The subscription to unsubscribe.
81
+ * @returns {boolean} true if eventListener has been removed successfully. false if the value is not found or if the value is not an object.
82
+ */
83
+ unsubscribe({ eventName, contextEventHandler }: Subscription): boolean;
84
+ /**
85
+ * Publish an event
86
+ *
87
+ * @template T
88
+ * @param {string} eventName The name of the event.
89
+ * @param {Event} [event=new CustomEvent(eventName)] The event to be handled.
90
+ * @param {T} [data] The value to be passed to the event handler as a parameter.
91
+ */
92
+ publish<T>(eventName: string, event?: Event, data?: T): void;
93
+ /**
94
+ * Check if the event and handler are subscribed.
95
+ *
96
+ * @param {Subscription} subscription The subscription object.
97
+ * @returns {boolean} true if the event name and handler are subscribed, false otherwise.
98
+ */
99
+ isSubscribed({ eventName, contextEventHandler }: Subscription): boolean;
100
+ /**
101
+ * A String value that is used in the creation of the default string
102
+ * description of an object. Called by the built-in method {@link Object.prototype.toString}.
103
+ *
104
+ * @returns {string} The default string description of this object.
105
+ */
106
+ get [Symbol.toStringTag](): string;
107
+ }
108
+
109
+ export { ContextEventHandler, type ContextEventListener, Subscribr, Subscription };
package/dist/subscribr.js CHANGED
@@ -1,171 +1,2 @@
1
- // node_modules/.pnpm/@d1g1tal+collections@1.0.1/node_modules/@d1g1tal/collections/src/set-multi-map.js
2
- var SetMultiMap = class extends Map {
3
- /**
4
- * Adds a new element with a specified key and value to the SetMultiMap.
5
- * If an element with the same key already exists, the value will be added to the underlying {@link Set}.
6
- * If the value already exists in the {@link Set}, it will not be added again.
7
- *
8
- * @param {K} key The key to set.
9
- * @param {V} value The value to add to the SetMultiMap
10
- * @returns {SetMultiMap<K, V>} The SetMultiMap with the updated key and value.
11
- */
12
- set(key, value) {
13
- super.set(key, (super.get(key) ?? /* @__PURE__ */ new Set()).add(value));
14
- return this;
15
- }
16
- /**
17
- * Checks if a specific key has a specific value.
18
- *
19
- * @param {K} key The key to check.
20
- * @param {V} value The value to check.
21
- * @returns {boolean} True if the key has the value, false otherwise.
22
- */
23
- hasValue(key, value) {
24
- const values = super.get(key);
25
- return values ? values.has(value) : false;
26
- }
27
- /**
28
- * Removes a specific value from a specific key.
29
- *
30
- * @param {K} key The key to remove the value from.
31
- * @param {V} value The value to remove.
32
- * @returns {boolean} True if the value was removed, false otherwise.
33
- */
34
- deleteValue(key, value) {
35
- const values = super.get(key);
36
- if (values) {
37
- return values.delete(value);
38
- }
39
- return false;
40
- }
41
- get [Symbol.toStringTag]() {
42
- return "SetMultiMap";
43
- }
44
- };
45
-
46
- // src/context-event-handler.js
47
- var ContextEventHandler = class {
48
- #context;
49
- #eventHandler;
50
- /**
51
- * @param {*} context The context to bind to the event handler.
52
- * @param {function(*): void} eventHandler The event handler to call when the event is published.
53
- */
54
- constructor(context, eventHandler) {
55
- this.#context = context;
56
- this.#eventHandler = eventHandler;
57
- }
58
- /**
59
- * Call the event handler for the provided event.
60
- *
61
- * @param {Event} event The event to handle
62
- * @param {*} [data] The value to be passed to the event handler as a parameter.
63
- */
64
- handle(event, data) {
65
- this.#eventHandler.call(this.#context, event, data);
66
- }
67
- get [Symbol.toStringTag]() {
68
- return "ContextEventHandler";
69
- }
70
- };
71
-
72
- // src/subscription.js
73
- var Subscription = class {
74
- #eventName;
75
- #contextEventHandler;
76
- /**
77
- * @param {string} eventName The event name.
78
- * @param {ContextEventHandler} contextEventHandler Then context event handler.
79
- */
80
- constructor(eventName, contextEventHandler) {
81
- this.#eventName = eventName;
82
- this.#contextEventHandler = contextEventHandler;
83
- }
84
- /**
85
- * Gets the event name for the subscription.
86
- *
87
- * @returns {string} The event name.
88
- */
89
- get eventName() {
90
- return this.#eventName;
91
- }
92
- /**
93
- * Gets the context event handler.
94
- *
95
- * @returns {ContextEventHandler} The context event handler
96
- */
97
- get contextEventHandler() {
98
- return this.#contextEventHandler;
99
- }
100
- get [Symbol.toStringTag]() {
101
- return "Subscription";
102
- }
103
- };
104
-
105
- // src/subscribr.js
106
- var Subscribr = class {
107
- /** @type {SetMultiMap<string, ContextEventHandler>} */
108
- #subscribers;
109
- constructor() {
110
- this.#subscribers = new SetMultiMap();
111
- }
112
- /**
113
- * Subscribe to an event
114
- *
115
- * @param {string} eventName The event name to subscribe to.
116
- * @param {function(Event, *): void} eventHandler The event handler to call when the event is published.
117
- * @param {*} [context] The context to bind to the event handler.
118
- * @returns {Subscription} An object used to check if the subscription still exists and to unsubscribe from the event.
119
- */
120
- subscribe(eventName, eventHandler, context = eventHandler) {
121
- const contextEventHandler = new ContextEventHandler(context, eventHandler);
122
- this.#subscribers.set(eventName, contextEventHandler);
123
- return new Subscription(eventName, contextEventHandler);
124
- }
125
- /**
126
- * Unsubscribe from the event
127
- *
128
- * @param {Subscription} subscription The subscription to unsubscribe.
129
- * @param {string} subscription.eventName The event name to subscribe to.
130
- * @param {ContextEventHandler} subscription.contextEventHandler The event handler to call when the event is published.
131
- * @returns {boolean} true if eventListener has been removed successfully. false if the value is not found or if the value is not an object.
132
- */
133
- unsubscribe({ eventName, contextEventHandler }) {
134
- const contextEventHandlers = this.#subscribers.get(eventName);
135
- const removed = contextEventHandlers?.delete(contextEventHandler);
136
- if (removed && contextEventHandlers.size === 0) {
137
- this.#subscribers.delete(eventName);
138
- }
139
- return removed;
140
- }
141
- /**
142
- * Publish an event
143
- *
144
- * @param {string} eventName The name of the event.
145
- * @param {Event} [event=new CustomEvent(eventName)] The event to be handled.
146
- * @param {*} [data] The value to be passed to the event handler as a parameter.
147
- */
148
- publish(eventName, event = new CustomEvent(eventName), data) {
149
- if (data == null && !(event instanceof Event)) {
150
- [data, event] = [event, new CustomEvent(eventName)];
151
- }
152
- this.#subscribers.get(eventName)?.forEach((contextEventHandler) => contextEventHandler.handle(event, data));
153
- }
154
- /**
155
- * Check if the event and handler are subscribed.
156
- *
157
- * @param {Subscription} subscription The subscription object.
158
- * @param {string} subscription.eventName The name of the event to check.
159
- * @param {ContextEventHandler} subscription.contextEventHandler The event handler to check.
160
- * @returns {boolean} true if the event name and handler are subscribed, false otherwise.
161
- */
162
- isSubscribed({ eventName, contextEventHandler }) {
163
- return this.#subscribers.get(eventName)?.has(contextEventHandler);
164
- }
165
- get [Symbol.toStringTag]() {
166
- return "Subscribr";
167
- }
168
- };
169
- export {
170
- Subscribr as default
171
- };
1
+ var s=class extends Map{set(e,t){return super.set(e,(super.get(e)??new Set).add(t)),this}hasValue(e,t){let n=super.get(e);return n?n.has(t):!1}find(e,t){let n=this.get(e);if(n!==void 0)return Array.from(n).find(t)}deleteValue(e,t){if(t===void 0)return this.delete(e);let n=super.get(e);if(n){let i=n.delete(t);return n.size===0&&super.delete(e),i}return!1}get[Symbol.toStringTag](){return"SetMultiMap"}};var r=class{context;eventListener;constructor(e,t){this.context=e,this.eventListener=t}handle(e,t){this.eventListener.call(this.context,e,t)}get[Symbol.toStringTag](){return"ContextEventHandler"}};var l=class{_eventName;_contextEventHandler;constructor(e,t){this._eventName=e,this._contextEventHandler=t}get eventName(){return this._eventName}get contextEventHandler(){return this._contextEventHandler}get[Symbol.toStringTag](){return"Subscription"}};var u=class{subscribers;constructor(){this.subscribers=new s}subscribe(e,t,n=t){let i=new r(n,t);return this.subscribers.set(e,i),new l(e,i)}unsubscribe({eventName:e,contextEventHandler:t}){let n=this.subscribers.get(e)??new Set,i=n.delete(t);return i&&n.size===0&&this.subscribers.delete(e),i}publish(e,t=new CustomEvent(e),n){this.subscribers.get(e)?.forEach(i=>i.handle(t,n))}isSubscribed({eventName:e,contextEventHandler:t}){return this.subscribers.get(e)?.has(t)??!1}get[Symbol.toStringTag](){return"Subscribr"}};export{r as ContextEventHandler,u as Subscribr,l as Subscription};
2
+ //# sourceMappingURL=subscribr.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../node_modules/.pnpm/@d1g1tal+collections@2.0.2_typescript@5.6.2/node_modules/@d1g1tal/collections/src/set-multi-map.ts", "../src/context-event-handler.ts", "../src/subscription.ts", "../src/subscribr.ts"],
4
+ "sourcesContent": ["/** A {@link Map} that can contain multiple, unique, values for the same key. */\nexport class SetMultiMap<K, V> extends Map<K, Set<V>>{\n\t/**\n\t * Adds a new element with a specified key and value to the SetMultiMap.\n\t * If an element with the same key already exists, the value will be added to the underlying {@link Set}.\n\t * If the value already exists in the {@link Set}, it will not be added again.\n\t *\n\t * @param {K} key The key to set.\n\t * @param {V} value The value to add to the SetMultiMap\n\t * @returns {SetMultiMap<K, V>} The SetMultiMap with the updated key and value.\n\t */\n\t// @ts-expect-error I am overriding the set method from the Map class\n\toverride set(key: K, value: V): SetMultiMap<K, V> {\n\t\tsuper.set(key, (super.get(key) ?? new Set()).add(value));\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Checks if a specific key has a specific value.\n\t *\n\t * @param {K} key The key to check.\n\t * @param {V} value The value to check.\n\t * @returns {boolean} True if the key has the value, false otherwise.\n\t */\n\thasValue(key: K, value: V): boolean {\n\t\tconst values = super.get(key);\n\n\t\treturn values ? values.has(value) : false;\n\t}\n\n\tfind(key: K, iterator: (value: V) => boolean): V | undefined {\n\t\tconst values = this.get(key);\n\n\t\tif (values !== undefined) {\n\t\t\treturn Array.from(values).find(iterator);\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes a specific value from a specific key.\n\t *\n\t * @param {K} key The key to remove the value from.\n\t * @param {V | undefined} value The value to remove.\n\t * @returns {boolean} True if the value was removed, false otherwise.\n\t */\n\tdeleteValue(key: K, value: V | undefined): boolean {\n\t\tif (value === undefined) { return this.delete(key) }\n\n\t\tconst values = super.get(key);\n\t\tif (values) {\n\t\t\tconst deleted = values.delete(value);\n\n\t\t\tif (values.size === 0) {\n\t\t\t\tsuper.delete(key);\n\t\t\t}\n\n\t\t\treturn deleted;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\toverride get [Symbol.toStringTag](): string {\n\t\treturn 'SetMultiMap';\n\t}\n}", "import type { ContextEventListener } from './@types';\n\n/** A wrapper for an event handler that binds a context to the event handler. */\nexport class ContextEventHandler {\n\tprivate readonly context: unknown;\n\tprivate readonly eventListener: ContextEventListener;\n\n\t/**\n\t * @param {unknown} context The context to bind to the event handler.\n\t * @param {ContextEventListener} eventListener The event handler to call when the event is published.\n\t */\n\tconstructor(context: unknown, eventListener: ContextEventListener) {\n\t\tthis.context = context;\n\t\tthis.eventListener = eventListener;\n\t}\n\n\t/**\n\t * Call the event handler for the provided event.\n\t *\n\t * @param {Event} event The event to handle\n\t * @param {unknown?} [data] The value to be passed to the event handler as a parameter.\n\t */\n\thandle(event: Event, data?: unknown): void {\n\t\tthis.eventListener.call(this.context, event, data);\n\t}\n\n\t/**\n\t * A String value that is used in the creation of the default string\n\t * description of an object. Called by the built-in method {@link Object.prototype.toString}.\n\t *\n\t * @returns {string} The default string description of this object.\n\t */\n\tget [Symbol.toStringTag](): string {\n\t\treturn 'ContextEventHandler';\n\t}\n}", "import type { ContextEventHandler } from './context-event-handler';\n\n/** Represents a subscription to an event. */\nexport class Subscription {\n\tprivate readonly _eventName: string;\n\tprivate readonly _contextEventHandler: ContextEventHandler;\n\n\t/**\n\t * @param {string} eventName The event name.\n\t * @param {ContextEventHandler} contextEventHandler Then context event handler.\n\t */\n\tconstructor(eventName: string, contextEventHandler: ContextEventHandler) {\n\t\tthis._eventName = eventName;\n\t\tthis._contextEventHandler = contextEventHandler;\n\t}\n\n\t/**\n\t * Gets the event name for the subscription.\n\t *\n\t * @returns {string} The event name.\n\t */\n\tget eventName(): string {\n\t\treturn this._eventName;\n\t}\n\n\t/**\n\t * Gets the context event handler.\n\t *\n\t * @returns {ContextEventHandler} The context event handler\n\t */\n\tget contextEventHandler(): ContextEventHandler {\n\t\treturn this._contextEventHandler;\n\t}\n\n\t/**\n\t * A String value that is used in the creation of the default string\n\t * description of an object. Called by the built-in method {@link Object.prototype.toString}.\n\t *\n\t * @returns {string} The default string description of this object.\n\t */\n\tget [Symbol.toStringTag](): string {\n\t\treturn 'Subscription';\n\t}\n}", "import { SetMultiMap } from '@d1g1tal/collections/src';\nimport { ContextEventHandler } from './context-event-handler';\nimport { Subscription } from './subscription';\nimport type { ContextEventListener } from './@types';\n\n/**\n * A class that allows objects to subscribe to events and be notified when the event is published.\n *\n * @class\n * @exports Subscribr\n */\nexport class Subscribr {\n\tprivate readonly subscribers: SetMultiMap<string, ContextEventHandler>;\n\n\tconstructor() {\n\t\tthis.subscribers = new SetMultiMap();\n\t}\n\n\t/**\n\t * Subscribe to an event\n\t *\n\t * @param {string} eventName The event name to subscribe to.\n\t * @param {ContextEventListener} eventHandler The event handler to call when the event is published.\n\t * @param {unknown} [context] The context to bind to the event handler.\n\t * @returns {Subscription} An object used to check if the subscription still exists and to unsubscribe from the event.\n\t */\n\tsubscribe(eventName: string, eventHandler: ContextEventListener, context: unknown = eventHandler): Subscription {\n\t\tconst contextEventHandler = new ContextEventHandler(context, eventHandler);\n\t\tthis.subscribers.set(eventName, contextEventHandler);\n\n\t\treturn new Subscription(eventName, contextEventHandler);\n\t}\n\n\t/**\n\t * Unsubscribe from the event\n\t *\n\t * @param {Subscription} subscription The subscription to unsubscribe.\n\t * @returns {boolean} true if eventListener has been removed successfully. false if the value is not found or if the value is not an object.\n\t */\n\tunsubscribe({ eventName, contextEventHandler }: Subscription): boolean {\n\t\tconst contextEventHandlers = this.subscribers.get(eventName) ?? new Set();\n\t\tconst removed = contextEventHandlers.delete(contextEventHandler);\n\n\t\tif (removed && contextEventHandlers.size === 0) {\tthis.subscribers.delete(eventName) }\n\n\t\treturn removed;\n\t}\n\n\t/**\n\t * Publish an event\n\t *\n\t * @template T\n\t * @param {string} eventName The name of the event.\n\t * @param {Event} [event=new CustomEvent(eventName)] The event to be handled.\n\t * @param {T} [data] The value to be passed to the event handler as a parameter.\n\t */\n\tpublish<T>(eventName: string, event: Event = new CustomEvent(eventName), data?: T): void {\n\t\tthis.subscribers.get(eventName)?.forEach((contextEventHandler: ContextEventHandler) => contextEventHandler.handle(event, data));\n\t}\n\n\t/**\n\t * Check if the event and handler are subscribed.\n\t *\n\t * @param {Subscription} subscription The subscription object.\n\t * @returns {boolean} true if the event name and handler are subscribed, false otherwise.\n\t */\n\tisSubscribed({ eventName, contextEventHandler }: Subscription): boolean {\n\t\treturn this.subscribers.get(eventName)?.has(contextEventHandler) ?? false;\n\t}\n\n\t/**\n\t * A String value that is used in the creation of the default string\n\t * description of an object. Called by the built-in method {@link Object.prototype.toString}.\n\t *\n\t * @returns {string} The default string description of this object.\n\t */\n\tget [Symbol.toStringTag](): string {\n\t\treturn 'Subscribr';\n\t}\n}"],
5
+ "mappings": "AACO,IAAMA,EAAN,cAAgC,GAAc,CAW3C,IAAIC,EAAQC,EAA6B,CACjD,aAAM,IAAID,GAAM,MAAM,IAAIA,CAAG,GAAK,IAAI,KAAO,IAAIC,CAAK,CAAC,EAEhD,IACR,CASA,SAASD,EAAQC,EAAmB,CACnC,IAAMC,EAAS,MAAM,IAAIF,CAAG,EAE5B,OAAOE,EAASA,EAAO,IAAID,CAAK,EAAI,EACrC,CAEA,KAAKD,EAAQG,EAAgD,CAC5D,IAAMD,EAAS,KAAK,IAAIF,CAAG,EAE3B,GAAIE,IAAW,OACd,OAAO,MAAM,KAAKA,CAAM,EAAE,KAAKC,CAAQ,CAIzC,CASA,YAAYH,EAAQC,EAA+B,CAClD,GAAIA,IAAU,OAAa,OAAO,KAAK,OAAOD,CAAG,EAEjD,IAAME,EAAS,MAAM,IAAIF,CAAG,EAC5B,GAAIE,EAAQ,CACX,IAAME,EAAUF,EAAO,OAAOD,CAAK,EAEnC,OAAIC,EAAO,OAAS,GACnB,MAAM,OAAOF,CAAG,EAGVI,CACR,CAEA,MAAO,EACR,CAEA,IAAc,OAAO,WAAW,GAAY,CAC3C,MAAO,aACR,CACD,ECjEO,IAAMC,EAAN,KAA0B,CACf,QACA,cAMjB,YAAYC,EAAkBC,EAAqC,CAClE,KAAK,QAAUD,EACf,KAAK,cAAgBC,CACtB,CAQA,OAAOC,EAAcC,EAAsB,CAC1C,KAAK,cAAc,KAAK,KAAK,QAASD,EAAOC,CAAI,CAClD,CAQA,IAAK,OAAO,WAAW,GAAY,CAClC,MAAO,qBACR,CACD,EChCO,IAAMC,EAAN,KAAmB,CACR,WACA,qBAMjB,YAAYC,EAAmBC,EAA0C,CACxE,KAAK,WAAaD,EAClB,KAAK,qBAAuBC,CAC7B,CAOA,IAAI,WAAoB,CACvB,OAAO,KAAK,UACb,CAOA,IAAI,qBAA2C,CAC9C,OAAO,KAAK,oBACb,CAQA,IAAK,OAAO,WAAW,GAAY,CAClC,MAAO,cACR,CACD,EChCO,IAAMC,EAAN,KAAgB,CACL,YAEjB,aAAc,CACb,KAAK,YAAc,IAAIC,CACxB,CAUA,UAAUC,EAAmBC,EAAoCC,EAAmBD,EAA4B,CAC/G,IAAME,EAAsB,IAAIC,EAAoBF,EAASD,CAAY,EACzE,YAAK,YAAY,IAAID,EAAWG,CAAmB,EAE5C,IAAIE,EAAaL,EAAWG,CAAmB,CACvD,CAQA,YAAY,CAAE,UAAAH,EAAW,oBAAAG,CAAoB,EAA0B,CACtE,IAAMG,EAAuB,KAAK,YAAY,IAAIN,CAAS,GAAK,IAAI,IAC9DO,EAAUD,EAAqB,OAAOH,CAAmB,EAE/D,OAAII,GAAWD,EAAqB,OAAS,GAAK,KAAK,YAAY,OAAON,CAAS,EAE5EO,CACR,CAUA,QAAWP,EAAmBQ,EAAe,IAAI,YAAYR,CAAS,EAAGS,EAAgB,CACxF,KAAK,YAAY,IAAIT,CAAS,GAAG,QAASG,GAA6CA,EAAoB,OAAOK,EAAOC,CAAI,CAAC,CAC/H,CAQA,aAAa,CAAE,UAAAT,EAAW,oBAAAG,CAAoB,EAA0B,CACvE,OAAO,KAAK,YAAY,IAAIH,CAAS,GAAG,IAAIG,CAAmB,GAAK,EACrE,CAQA,IAAK,OAAO,WAAW,GAAY,CAClC,MAAO,WACR,CACD",
6
+ "names": ["SetMultiMap", "key", "value", "values", "iterator", "deleted", "ContextEventHandler", "context", "eventListener", "event", "data", "Subscription", "eventName", "contextEventHandler", "Subscribr", "SetMultiMap", "eventName", "eventHandler", "context", "contextEventHandler", "ContextEventHandler", "Subscription", "contextEventHandlers", "removed", "event", "data"]
7
+ }
package/package.json CHANGED
@@ -1,15 +1,32 @@
1
1
  {
2
2
  "name": "@d1g1tal/subscribr",
3
- "version": "3.0.5",
3
+ "version": "4.0.1",
4
4
  "description": "JavaScript Publish/Subscribe Library",
5
- "type": "module",
6
- "exports": {
7
- ".": "./src/subscribr.js",
8
- "./*.js": "./src/*.js"
5
+ "author": "Jason DiMeo",
6
+ "license": "ISC",
7
+ "homepage": "https://github.com/D1g1talEntr0py/subscribr#readme",
8
+ "bugs": {
9
+ "url": "https://github.com/D1g1talEntr0py/subscribr/issues"
9
10
  },
11
+ "keywords": [
12
+ "JavaScript",
13
+ "ObserverPattern",
14
+ "Publish/Subscribe"
15
+ ],
10
16
  "publishConfig": {
11
17
  "access": "public"
12
18
  },
19
+ "type": "module",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/subscribr.d.ts",
23
+ "import": "./dist/subscribr.js"
24
+ },
25
+ "./src": {
26
+ "types": "./dist/subscribr.d.ts",
27
+ "import": "./src/index.ts"
28
+ }
29
+ },
13
30
  "files": [
14
31
  "/src",
15
32
  "/dist"
@@ -18,49 +35,48 @@
18
35
  "type": "git",
19
36
  "url": "git+https://github.com/D1g1talEntr0py/subscribr.git"
20
37
  },
21
- "keywords": [
22
- "JavaScript",
23
- "ObserverPattern",
24
- "Publish/Subscribe"
25
- ],
26
- "author": "Jason DiMeo",
27
- "license": "ISC",
28
- "bugs": {
29
- "url": "https://github.com/D1g1talEntr0py/subscribr/issues"
30
- },
31
- "homepage": "https://github.com/D1g1talEntr0py/subscribr#readme",
32
38
  "dependencies": {
33
- "@d1g1tal/collections": "^1.0.1"
39
+ "@d1g1tal/collections": "^2.0.2"
34
40
  },
35
41
  "devDependencies": {
36
42
  "@d1g1tal/chrysalis": "^2.5.0",
37
- "esbuild": "^0.20.1",
38
- "esbuild-library": "^1.0.7",
39
- "eslint": "^8.57.0",
40
- "eslint-plugin-compat": "^4.2.0",
41
- "eslint-plugin-jsdoc": "^48.2.0",
42
- "jest": "^29.7.0"
43
+ "@eslint/compat": "^1.1.1",
44
+ "@eslint/js": "^9.11.1",
45
+ "@types/eslint__js": "^8.42.3",
46
+ "@types/node": "^22.7.4",
47
+ "@typescript-eslint/eslint-plugin": "^8.7.0",
48
+ "@typescript-eslint/parser": "^8.7.0",
49
+ "@vitest/coverage-v8": "^2.1.1",
50
+ "eslint": "^9.11.1",
51
+ "eslint-plugin-compat": "^6.0.1",
52
+ "eslint-plugin-jsdoc": "^50.3.0",
53
+ "globals": "^15.9.0",
54
+ "typescript": "^5.6.2",
55
+ "typescript-eslint": "^8.7.0",
56
+ "vitest": "^2.1.1"
57
+ },
58
+ "peerDependencies": {
59
+ "typescript": "^5.0.0"
60
+ },
61
+ "peerDependenciesMeta": {
62
+ "typescript": {
63
+ "optional": true
64
+ }
43
65
  },
44
- "jest": {
45
- "verbose": true,
46
- "transform": {},
47
- "coverageDirectory": "./tests/coverage/",
48
- "coveragePathIgnorePatterns": [
49
- "/node_modules/"
50
- ],
51
- "collectCoverage": true,
52
- "collectCoverageFrom": [
53
- "src/**/*.js"
54
- ]
66
+ "engines": {
67
+ "node": ">=20.15.1"
55
68
  },
56
69
  "browserslist": [
57
70
  "defaults and fully supports es6-module",
58
- "node >= 20.10"
71
+ "node >= 20.15.1"
59
72
  ],
60
73
  "scripts": {
61
- "build": "node esbuild.js",
62
- "lint": "eslint --ext .js --fix --ignore-path .gitignore .",
63
- "d.ts": "tsc --allowJs -declaration --emitDeclarationOnly --skipLibCheck --lib esnext index.js",
64
- "test": "node --no-warnings --experimental-vm-modules node_modules/jest/bin/jest.js"
74
+ "build": "tsbuild",
75
+ "build:watch": "tsbuild --watch",
76
+ "type-check": "tsbuild --typeCheck",
77
+ "lint": "eslint ./src",
78
+ "test": "vitest run --coverage",
79
+ "test:watch": "vitest",
80
+ "prepublish": "pnpm lint && pnpm test && pnpm -s build"
65
81
  }
66
82
  }
@@ -0,0 +1,4 @@
1
+ /** Context event listener function. */
2
+ type ContextEventListener = (event: Event, data?: unknown) => void;
3
+
4
+ export type { ContextEventListener };
@@ -0,0 +1,36 @@
1
+ import type { ContextEventListener } from './@types';
2
+
3
+ /** A wrapper for an event handler that binds a context to the event handler. */
4
+ export class ContextEventHandler {
5
+ private readonly context: unknown;
6
+ private readonly eventListener: ContextEventListener;
7
+
8
+ /**
9
+ * @param {unknown} context The context to bind to the event handler.
10
+ * @param {ContextEventListener} eventListener The event handler to call when the event is published.
11
+ */
12
+ constructor(context: unknown, eventListener: ContextEventListener) {
13
+ this.context = context;
14
+ this.eventListener = eventListener;
15
+ }
16
+
17
+ /**
18
+ * Call the event handler for the provided event.
19
+ *
20
+ * @param {Event} event The event to handle
21
+ * @param {unknown?} [data] The value to be passed to the event handler as a parameter.
22
+ */
23
+ handle(event: Event, data?: unknown): void {
24
+ this.eventListener.call(this.context, event, data);
25
+ }
26
+
27
+ /**
28
+ * A String value that is used in the creation of the default string
29
+ * description of an object. Called by the built-in method {@link Object.prototype.toString}.
30
+ *
31
+ * @returns {string} The default string description of this object.
32
+ */
33
+ get [Symbol.toStringTag](): string {
34
+ return 'ContextEventHandler';
35
+ }
36
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { Subscribr } from './subscribr';
2
+ export { Subscription } from './subscription';
3
+ export { ContextEventHandler } from './context-event-handler';
4
+ export type { ContextEventListener } from './@types';
@@ -0,0 +1,80 @@
1
+ import { SetMultiMap } from '@d1g1tal/collections/src';
2
+ import { ContextEventHandler } from './context-event-handler';
3
+ import { Subscription } from './subscription';
4
+ import type { ContextEventListener } from './@types';
5
+
6
+ /**
7
+ * A class that allows objects to subscribe to events and be notified when the event is published.
8
+ *
9
+ * @class
10
+ * @exports Subscribr
11
+ */
12
+ export class Subscribr {
13
+ private readonly subscribers: SetMultiMap<string, ContextEventHandler>;
14
+
15
+ constructor() {
16
+ this.subscribers = new SetMultiMap();
17
+ }
18
+
19
+ /**
20
+ * Subscribe to an event
21
+ *
22
+ * @param {string} eventName The event name to subscribe to.
23
+ * @param {ContextEventListener} eventHandler The event handler to call when the event is published.
24
+ * @param {unknown} [context] The context to bind to the event handler.
25
+ * @returns {Subscription} An object used to check if the subscription still exists and to unsubscribe from the event.
26
+ */
27
+ subscribe(eventName: string, eventHandler: ContextEventListener, context: unknown = eventHandler): Subscription {
28
+ const contextEventHandler = new ContextEventHandler(context, eventHandler);
29
+ this.subscribers.set(eventName, contextEventHandler);
30
+
31
+ return new Subscription(eventName, contextEventHandler);
32
+ }
33
+
34
+ /**
35
+ * Unsubscribe from the event
36
+ *
37
+ * @param {Subscription} subscription The subscription to unsubscribe.
38
+ * @returns {boolean} true if eventListener has been removed successfully. false if the value is not found or if the value is not an object.
39
+ */
40
+ unsubscribe({ eventName, contextEventHandler }: Subscription): boolean {
41
+ const contextEventHandlers = this.subscribers.get(eventName) ?? new Set();
42
+ const removed = contextEventHandlers.delete(contextEventHandler);
43
+
44
+ if (removed && contextEventHandlers.size === 0) { this.subscribers.delete(eventName) }
45
+
46
+ return removed;
47
+ }
48
+
49
+ /**
50
+ * Publish an event
51
+ *
52
+ * @template T
53
+ * @param {string} eventName The name of the event.
54
+ * @param {Event} [event=new CustomEvent(eventName)] The event to be handled.
55
+ * @param {T} [data] The value to be passed to the event handler as a parameter.
56
+ */
57
+ publish<T>(eventName: string, event: Event = new CustomEvent(eventName), data?: T): void {
58
+ this.subscribers.get(eventName)?.forEach((contextEventHandler: ContextEventHandler) => contextEventHandler.handle(event, data));
59
+ }
60
+
61
+ /**
62
+ * Check if the event and handler are subscribed.
63
+ *
64
+ * @param {Subscription} subscription The subscription object.
65
+ * @returns {boolean} true if the event name and handler are subscribed, false otherwise.
66
+ */
67
+ isSubscribed({ eventName, contextEventHandler }: Subscription): boolean {
68
+ return this.subscribers.get(eventName)?.has(contextEventHandler) ?? false;
69
+ }
70
+
71
+ /**
72
+ * A String value that is used in the creation of the default string
73
+ * description of an object. Called by the built-in method {@link Object.prototype.toString}.
74
+ *
75
+ * @returns {string} The default string description of this object.
76
+ */
77
+ get [Symbol.toStringTag](): string {
78
+ return 'Subscribr';
79
+ }
80
+ }
@@ -0,0 +1,44 @@
1
+ import type { ContextEventHandler } from './context-event-handler';
2
+
3
+ /** Represents a subscription to an event. */
4
+ export class Subscription {
5
+ private readonly _eventName: string;
6
+ private readonly _contextEventHandler: ContextEventHandler;
7
+
8
+ /**
9
+ * @param {string} eventName The event name.
10
+ * @param {ContextEventHandler} contextEventHandler Then context event handler.
11
+ */
12
+ constructor(eventName: string, contextEventHandler: ContextEventHandler) {
13
+ this._eventName = eventName;
14
+ this._contextEventHandler = contextEventHandler;
15
+ }
16
+
17
+ /**
18
+ * Gets the event name for the subscription.
19
+ *
20
+ * @returns {string} The event name.
21
+ */
22
+ get eventName(): string {
23
+ return this._eventName;
24
+ }
25
+
26
+ /**
27
+ * Gets the context event handler.
28
+ *
29
+ * @returns {ContextEventHandler} The context event handler
30
+ */
31
+ get contextEventHandler(): ContextEventHandler {
32
+ return this._contextEventHandler;
33
+ }
34
+
35
+ /**
36
+ * A String value that is used in the creation of the default string
37
+ * description of an object. Called by the built-in method {@link Object.prototype.toString}.
38
+ *
39
+ * @returns {string} The default string description of this object.
40
+ */
41
+ get [Symbol.toStringTag](): string {
42
+ return 'Subscription';
43
+ }
44
+ }
@@ -1,164 +0,0 @@
1
- (() => {
2
- var SetMultiMap = class extends Map {
3
- /**
4
- * Adds a new element with a specified key and value to the SetMultiMap.
5
- * If an element with the same key already exists, the value will be added to the underlying {@link Set}.
6
- * If the value already exists in the {@link Set}, it will not be added again.
7
- *
8
- * @param {K} key The key to set.
9
- * @param {V} value The value to add to the SetMultiMap
10
- * @returns {SetMultiMap<K, V>} The SetMultiMap with the updated key and value.
11
- */
12
- set(key, value) {
13
- super.set(key, (super.get(key) ?? /* @__PURE__ */ new Set()).add(value));
14
- return this;
15
- }
16
- /**
17
- * Checks if a specific key has a specific value.
18
- *
19
- * @param {K} key The key to check.
20
- * @param {V} value The value to check.
21
- * @returns {boolean} True if the key has the value, false otherwise.
22
- */
23
- hasValue(key, value) {
24
- const values = super.get(key);
25
- return values ? values.has(value) : false;
26
- }
27
- /**
28
- * Removes a specific value from a specific key.
29
- *
30
- * @param {K} key The key to remove the value from.
31
- * @param {V} value The value to remove.
32
- * @returns {boolean} True if the value was removed, false otherwise.
33
- */
34
- deleteValue(key, value) {
35
- const values = super.get(key);
36
- if (values) {
37
- return values.delete(value);
38
- }
39
- return false;
40
- }
41
- get [Symbol.toStringTag]() {
42
- return "SetMultiMap";
43
- }
44
- };
45
- var ContextEventHandler = class {
46
- #context;
47
- #eventHandler;
48
- /**
49
- * @param {*} context The context to bind to the event handler.
50
- * @param {function(*): void} eventHandler The event handler to call when the event is published.
51
- */
52
- constructor(context, eventHandler) {
53
- this.#context = context;
54
- this.#eventHandler = eventHandler;
55
- }
56
- /**
57
- * Call the event handler for the provided event.
58
- *
59
- * @param {Event} event The event to handle
60
- * @param {*} [data] The value to be passed to the event handler as a parameter.
61
- */
62
- handle(event, data) {
63
- this.#eventHandler.call(this.#context, event, data);
64
- }
65
- get [Symbol.toStringTag]() {
66
- return "ContextEventHandler";
67
- }
68
- };
69
- var Subscription = class {
70
- #eventName;
71
- #contextEventHandler;
72
- /**
73
- * @param {string} eventName The event name.
74
- * @param {ContextEventHandler} contextEventHandler Then context event handler.
75
- */
76
- constructor(eventName, contextEventHandler) {
77
- this.#eventName = eventName;
78
- this.#contextEventHandler = contextEventHandler;
79
- }
80
- /**
81
- * Gets the event name for the subscription.
82
- *
83
- * @returns {string} The event name.
84
- */
85
- get eventName() {
86
- return this.#eventName;
87
- }
88
- /**
89
- * Gets the context event handler.
90
- *
91
- * @returns {ContextEventHandler} The context event handler
92
- */
93
- get contextEventHandler() {
94
- return this.#contextEventHandler;
95
- }
96
- get [Symbol.toStringTag]() {
97
- return "Subscription";
98
- }
99
- };
100
- var Subscribr = class {
101
- /** @type {SetMultiMap<string, ContextEventHandler>} */
102
- #subscribers;
103
- constructor() {
104
- this.#subscribers = new SetMultiMap();
105
- }
106
- /**
107
- * Subscribe to an event
108
- *
109
- * @param {string} eventName The event name to subscribe to.
110
- * @param {function(Event, *): void} eventHandler The event handler to call when the event is published.
111
- * @param {*} [context] The context to bind to the event handler.
112
- * @returns {Subscription} An object used to check if the subscription still exists and to unsubscribe from the event.
113
- */
114
- subscribe(eventName, eventHandler, context = eventHandler) {
115
- const contextEventHandler = new ContextEventHandler(context, eventHandler);
116
- this.#subscribers.set(eventName, contextEventHandler);
117
- return new Subscription(eventName, contextEventHandler);
118
- }
119
- /**
120
- * Unsubscribe from the event
121
- *
122
- * @param {Subscription} subscription The subscription to unsubscribe.
123
- * @param {string} subscription.eventName The event name to subscribe to.
124
- * @param {ContextEventHandler} subscription.contextEventHandler The event handler to call when the event is published.
125
- * @returns {boolean} true if eventListener has been removed successfully. false if the value is not found or if the value is not an object.
126
- */
127
- unsubscribe({ eventName, contextEventHandler }) {
128
- const contextEventHandlers = this.#subscribers.get(eventName);
129
- const removed = contextEventHandlers?.delete(contextEventHandler);
130
- if (removed && contextEventHandlers.size === 0) {
131
- this.#subscribers.delete(eventName);
132
- }
133
- return removed;
134
- }
135
- /**
136
- * Publish an event
137
- *
138
- * @param {string} eventName The name of the event.
139
- * @param {Event} [event=new CustomEvent(eventName)] The event to be handled.
140
- * @param {*} [data] The value to be passed to the event handler as a parameter.
141
- */
142
- publish(eventName, event = new CustomEvent(eventName), data) {
143
- if (data == null && !(event instanceof Event)) {
144
- [data, event] = [event, new CustomEvent(eventName)];
145
- }
146
- this.#subscribers.get(eventName)?.forEach((contextEventHandler) => contextEventHandler.handle(event, data));
147
- }
148
- /**
149
- * Check if the event and handler are subscribed.
150
- *
151
- * @param {Subscription} subscription The subscription object.
152
- * @param {string} subscription.eventName The name of the event to check.
153
- * @param {ContextEventHandler} subscription.contextEventHandler The event handler to check.
154
- * @returns {boolean} true if the event name and handler are subscribed, false otherwise.
155
- */
156
- isSubscribed({ eventName, contextEventHandler }) {
157
- return this.#subscribers.get(eventName)?.has(contextEventHandler);
158
- }
159
- get [Symbol.toStringTag]() {
160
- return "Subscribr";
161
- }
162
- };
163
- globalThis.Subscribr = Subscribr;
164
- })();
@@ -1,2 +0,0 @@
1
- (()=>{var n=class extends Map{set(t,e){return super.set(t,(super.get(t)??new Set).add(e)),this}hasValue(t,e){let s=super.get(t);return!!s&&s.has(e)}deleteValue(t,e){let s=super.get(t);return!!s&&s.delete(e)}get[Symbol.toStringTag](){return"SetMultiMap"}},u=class{#t;#e;constructor(t,e){this.#t=t,this.#e=e}handle(t,e){this.#e.call(this.#t,t,e)}get[Symbol.toStringTag](){return"ContextEventHandler"}},i=class{#t;#e;constructor(t,e){this.#t=t,this.#e=e}get eventName(){return this.#t}get contextEventHandler(){return this.#e}get[Symbol.toStringTag](){return"Subscription"}},l=class{#t;constructor(){this.#t=new n}subscribe(t,e,s=e){let r=new u(s,e);return this.#t.set(t,r),new i(t,r)}unsubscribe({eventName:t,contextEventHandler:e}){let s=this.#t.get(t),r=s?.delete(e);return r&&s.size===0&&this.#t.delete(t),r}publish(t,e=new CustomEvent(t),s){s!=null||e instanceof Event||([s,e]=[e,new CustomEvent(t)]),this.#t.get(t)?.forEach(r=>r.handle(e,s))}isSubscribed({eventName:t,contextEventHandler:e}){return this.#t.get(t)?.has(e)}get[Symbol.toStringTag](){return"Subscribr"}};globalThis.Subscribr=l})();
2
- //# sourceMappingURL=subscribr.min.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["subscribr.js"],
4
- "sourcesContent": ["(()=>{var e=class extends Map{set(e,t){return super.set(e,(super.get(e)??new Set).add(t)),this}hasValue(e,t){let s=super.get(e);return!!s&&s.has(t)}deleteValue(e,t){let s=super.get(e);return!!s&&s.delete(t)}get[Symbol.toStringTag](){return\"SetMultiMap\"}},t=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}handle(e,t){this.#t.call(this.#e,e,t)}get[Symbol.toStringTag](){return\"ContextEventHandler\"}},s=class{#s;#r;constructor(e,t){this.#s=e,this.#r=t}get eventName(){return this.#s}get contextEventHandler(){return this.#r}get[Symbol.toStringTag](){return\"Subscription\"}},r=class{#n;constructor(){this.#n=new e}subscribe(e,r,n=r){let u=new t(n,r);return this.#n.set(e,u),new s(e,u)}unsubscribe({eventName:e,contextEventHandler:t}){let s=this.#n.get(e),r=s?.delete(t);return r&&0===s.size&&this.#n.delete(e),r}publish(e,t=new CustomEvent(e),s){null!=s||t instanceof Event||([s,t]=[t,new CustomEvent(e)]),this.#n.get(e)?.forEach(e=>e.handle(t,s))}isSubscribed({eventName:e,contextEventHandler:t}){return this.#n.get(e)?.has(t)}get[Symbol.toStringTag](){return\"Subscribr\"}};globalThis.Subscribr=r})();"],
5
- "mappings": "CAAC,IAAI,CAAC,IAAIA,EAAE,cAAc,GAAG,CAAC,IAAIA,EAAEC,EAAE,CAAC,OAAO,MAAM,IAAID,GAAG,MAAM,IAAIA,CAAC,GAAG,IAAI,KAAK,IAAIC,CAAC,CAAC,EAAE,IAAI,CAAC,SAASD,EAAEC,EAAE,CAAC,IAAI,EAAE,MAAM,IAAID,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,IAAIC,CAAC,CAAC,CAAC,YAAYD,EAAEC,EAAE,CAAC,IAAI,EAAE,MAAM,IAAID,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,OAAOC,CAAC,CAAC,CAAC,IAAI,OAAO,WAAW,GAAG,CAAC,MAAM,aAAa,CAAC,EAAEA,EAAE,KAAK,CAACC,GAAGC,GAAG,YAAYH,EAAEC,EAAE,CAAC,KAAKC,GAAGF,EAAE,KAAKG,GAAGF,CAAC,CAAC,OAAOD,EAAEC,EAAE,CAAC,KAAKE,GAAG,KAAK,KAAKD,GAAGF,EAAEC,CAAC,CAAC,CAAC,IAAI,OAAO,WAAW,GAAG,CAAC,MAAM,qBAAqB,CAAC,EAAEG,EAAE,KAAK,CAACC,GAAGC,GAAG,YAAYN,EAAEC,EAAE,CAAC,KAAKI,GAAGL,EAAE,KAAKM,GAAGL,CAAC,CAAC,IAAI,WAAW,CAAC,OAAO,KAAKI,EAAE,CAAC,IAAI,qBAAqB,CAAC,OAAO,KAAKC,EAAE,CAAC,IAAI,OAAO,WAAW,GAAG,CAAC,MAAM,cAAc,CAAC,EAAEC,EAAE,KAAK,CAACC,GAAG,aAAa,CAAC,KAAKA,GAAG,IAAIR,CAAC,CAAC,UAAUA,EAAEO,EAAEE,EAAEF,EAAE,CAAC,IAAIG,EAAE,IAAIT,EAAEQ,EAAEF,CAAC,EAAE,OAAO,KAAKC,GAAG,IAAIR,EAAEU,CAAC,EAAE,IAAIN,EAAEJ,EAAEU,CAAC,CAAC,CAAC,YAAY,CAAC,UAAUV,EAAE,oBAAoBC,CAAC,EAAE,CAAC,IAAI,EAAE,KAAKO,GAAG,IAAIR,CAAC,EAAE,EAAE,GAAG,OAAOC,CAAC,EAAE,OAAO,GAAO,EAAE,OAAN,GAAY,KAAKO,GAAG,OAAOR,CAAC,EAAE,CAAC,CAAC,QAAQA,EAAEC,EAAE,IAAI,YAAYD,CAAC,EAAE,EAAE,CAAO,GAAN,MAASC,aAAa,QAAQ,CAAC,EAAEA,CAAC,EAAE,CAACA,EAAE,IAAI,YAAYD,CAAC,CAAC,GAAG,KAAKQ,GAAG,IAAIR,CAAC,GAAG,QAAQA,GAAGA,EAAE,OAAOC,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,UAAUD,EAAE,oBAAoBC,CAAC,EAAE,CAAC,OAAO,KAAKO,GAAG,IAAIR,CAAC,GAAG,IAAIC,CAAC,CAAC,CAAC,IAAI,OAAO,WAAW,GAAG,CAAC,MAAM,WAAW,CAAC,EAAE,WAAW,UAAUM,CAAC,GAAG",
6
- "names": ["e", "t", "#e", "#t", "s", "#s", "#r", "r", "#n", "n", "u"]
7
- }
@@ -1,2 +0,0 @@
1
- var n=class extends Map{set(t,e){return super.set(t,(super.get(t)??new Set).add(e)),this}hasValue(t,e){let s=super.get(t);return!!s&&s.has(e)}deleteValue(t,e){let s=super.get(t);return!!s&&s.delete(e)}get[Symbol.toStringTag](){return"SetMultiMap"}},u=class{#t;#e;constructor(t,e){this.#t=t,this.#e=e}handle(t,e){this.#e.call(this.#t,t,e)}get[Symbol.toStringTag](){return"ContextEventHandler"}},a=class{#t;#e;constructor(t,e){this.#t=t,this.#e=e}get eventName(){return this.#t}get contextEventHandler(){return this.#e}get[Symbol.toStringTag](){return"Subscription"}},l=class{#t;constructor(){this.#t=new n}subscribe(t,e,s=e){let r=new u(s,e);return this.#t.set(t,r),new a(t,r)}unsubscribe({eventName:t,contextEventHandler:e}){let s=this.#t.get(t),r=s?.delete(e);return r&&s.size===0&&this.#t.delete(t),r}publish(t,e=new CustomEvent(t),s){s!=null||e instanceof Event||([s,e]=[e,new CustomEvent(t)]),this.#t.get(t)?.forEach(r=>r.handle(e,s))}isSubscribed({eventName:t,contextEventHandler:e}){return this.#t.get(t)?.has(e)}get[Symbol.toStringTag](){return"Subscribr"}};export{l as default};
2
- //# sourceMappingURL=subscribr.min.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["subscribr.js"],
4
- "sourcesContent": ["var e=class extends Map{set(e,t){return super.set(e,(super.get(e)??new Set).add(t)),this}hasValue(e,t){let s=super.get(e);return!!s&&s.has(t)}deleteValue(e,t){let s=super.get(e);return!!s&&s.delete(t)}get[Symbol.toStringTag](){return\"SetMultiMap\"}},t=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}handle(e,t){this.#t.call(this.#e,e,t)}get[Symbol.toStringTag](){return\"ContextEventHandler\"}},s=class{#s;#r;constructor(e,t){this.#s=e,this.#r=t}get eventName(){return this.#s}get contextEventHandler(){return this.#r}get[Symbol.toStringTag](){return\"Subscription\"}},r=class{#n;constructor(){this.#n=new e}subscribe(e,r,n=r){let u=new t(n,r);return this.#n.set(e,u),new s(e,u)}unsubscribe({eventName:e,contextEventHandler:t}){let s=this.#n.get(e),r=s?.delete(t);return r&&0===s.size&&this.#n.delete(e),r}publish(e,t=new CustomEvent(e),s){null!=s||t instanceof Event||([s,t]=[t,new CustomEvent(e)]),this.#n.get(e)?.forEach(e=>e.handle(t,s))}isSubscribed({eventName:e,contextEventHandler:t}){return this.#n.get(e)?.has(t)}get[Symbol.toStringTag](){return\"Subscribr\"}};export{r as default};"],
5
- "mappings": "AAAA,IAAIA,EAAE,cAAc,GAAG,CAAC,IAAIA,EAAEC,EAAE,CAAC,OAAO,MAAM,IAAID,GAAG,MAAM,IAAIA,CAAC,GAAG,IAAI,KAAK,IAAIC,CAAC,CAAC,EAAE,IAAI,CAAC,SAASD,EAAEC,EAAE,CAAC,IAAI,EAAE,MAAM,IAAID,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,IAAIC,CAAC,CAAC,CAAC,YAAYD,EAAEC,EAAE,CAAC,IAAI,EAAE,MAAM,IAAID,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,OAAOC,CAAC,CAAC,CAAC,IAAI,OAAO,WAAW,GAAG,CAAC,MAAM,aAAa,CAAC,EAAEA,EAAE,KAAK,CAACC,GAAGC,GAAG,YAAYH,EAAEC,EAAE,CAAC,KAAKC,GAAGF,EAAE,KAAKG,GAAGF,CAAC,CAAC,OAAOD,EAAEC,EAAE,CAAC,KAAKE,GAAG,KAAK,KAAKD,GAAGF,EAAEC,CAAC,CAAC,CAAC,IAAI,OAAO,WAAW,GAAG,CAAC,MAAM,qBAAqB,CAAC,EAAEG,EAAE,KAAK,CAACC,GAAGC,GAAG,YAAYN,EAAEC,EAAE,CAAC,KAAKI,GAAGL,EAAE,KAAKM,GAAGL,CAAC,CAAC,IAAI,WAAW,CAAC,OAAO,KAAKI,EAAE,CAAC,IAAI,qBAAqB,CAAC,OAAO,KAAKC,EAAE,CAAC,IAAI,OAAO,WAAW,GAAG,CAAC,MAAM,cAAc,CAAC,EAAEC,EAAE,KAAK,CAACC,GAAG,aAAa,CAAC,KAAKA,GAAG,IAAIR,CAAC,CAAC,UAAUA,EAAEO,EAAEE,EAAEF,EAAE,CAAC,IAAIG,EAAE,IAAIT,EAAEQ,EAAEF,CAAC,EAAE,OAAO,KAAKC,GAAG,IAAIR,EAAEU,CAAC,EAAE,IAAIN,EAAEJ,EAAEU,CAAC,CAAC,CAAC,YAAY,CAAC,UAAUV,EAAE,oBAAoBC,CAAC,EAAE,CAAC,IAAI,EAAE,KAAKO,GAAG,IAAIR,CAAC,EAAE,EAAE,GAAG,OAAOC,CAAC,EAAE,OAAO,GAAO,EAAE,OAAN,GAAY,KAAKO,GAAG,OAAOR,CAAC,EAAE,CAAC,CAAC,QAAQA,EAAEC,EAAE,IAAI,YAAYD,CAAC,EAAE,EAAE,CAAO,GAAN,MAASC,aAAa,QAAQ,CAAC,EAAEA,CAAC,EAAE,CAACA,EAAE,IAAI,YAAYD,CAAC,CAAC,GAAG,KAAKQ,GAAG,IAAIR,CAAC,GAAG,QAAQA,GAAGA,EAAE,OAAOC,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,UAAUD,EAAE,oBAAoBC,CAAC,EAAE,CAAC,OAAO,KAAKO,GAAG,IAAIR,CAAC,GAAG,IAAIC,CAAC,CAAC,CAAC,IAAI,OAAO,WAAW,GAAG,CAAC,MAAM,WAAW,CAAC,EAAE,OAAOM,KAAK",
6
- "names": ["e", "t", "#e", "#t", "s", "#s", "#r", "r", "#n", "n", "u"]
7
- }
@@ -1,27 +0,0 @@
1
- export default class ContextEventHandler {
2
- #context;
3
- #eventHandler;
4
-
5
- /**
6
- * @param {*} context The context to bind to the event handler.
7
- * @param {function(*): void} eventHandler The event handler to call when the event is published.
8
- */
9
- constructor(context, eventHandler) {
10
- this.#context = context;
11
- this.#eventHandler = eventHandler;
12
- }
13
-
14
- /**
15
- * Call the event handler for the provided event.
16
- *
17
- * @param {Event} event The event to handle
18
- * @param {*} [data] The value to be passed to the event handler as a parameter.
19
- */
20
- handle(event, data) {
21
- this.#eventHandler.call(this.#context, event, data);
22
- }
23
-
24
- get [Symbol.toStringTag]() {
25
- return 'ContextEventHandler';
26
- }
27
- }
package/src/subscribr.js DELETED
@@ -1,75 +0,0 @@
1
- import SetMultiMap from '@d1g1tal/collections/set-multi-map.js';
2
- import ContextEventHandler from './context-event-handler.js';
3
- import Subscription from './subscription.js';
4
-
5
- export default class Subscribr {
6
- /** @type {SetMultiMap<string, ContextEventHandler>} */
7
- #subscribers;
8
-
9
- constructor() {
10
- this.#subscribers = new SetMultiMap();
11
- }
12
-
13
- /**
14
- * Subscribe to an event
15
- *
16
- * @param {string} eventName The event name to subscribe to.
17
- * @param {function(Event, *): void} eventHandler The event handler to call when the event is published.
18
- * @param {*} [context] The context to bind to the event handler.
19
- * @returns {Subscription} An object used to check if the subscription still exists and to unsubscribe from the event.
20
- */
21
- subscribe(eventName, eventHandler, context = eventHandler) {
22
- const contextEventHandler = new ContextEventHandler(context, eventHandler);
23
- this.#subscribers.set(eventName, contextEventHandler);
24
-
25
- return new Subscription(eventName, contextEventHandler);
26
- }
27
-
28
- /**
29
- * Unsubscribe from the event
30
- *
31
- * @param {Subscription} subscription The subscription to unsubscribe.
32
- * @param {string} subscription.eventName The event name to subscribe to.
33
- * @param {ContextEventHandler} subscription.contextEventHandler The event handler to call when the event is published.
34
- * @returns {boolean} true if eventListener has been removed successfully. false if the value is not found or if the value is not an object.
35
- */
36
- unsubscribe({ eventName, contextEventHandler }) {
37
- const contextEventHandlers = this.#subscribers.get(eventName);
38
- const removed = contextEventHandlers?.delete(contextEventHandler);
39
-
40
- if (removed && contextEventHandlers.size === 0) { this.#subscribers.delete(eventName) }
41
-
42
- return removed;
43
- }
44
-
45
- /**
46
- * Publish an event
47
- *
48
- * @param {string} eventName The name of the event.
49
- * @param {Event} [event=new CustomEvent(eventName)] The event to be handled.
50
- * @param {*} [data] The value to be passed to the event handler as a parameter.
51
- */
52
- publish(eventName, event = new CustomEvent(eventName), data) {
53
- if (data == null && !(event instanceof Event)) {
54
- // Swap the event and data parameters because only data was passed without an event object
55
- [data, event] = [event, new CustomEvent(eventName)];
56
- }
57
- this.#subscribers.get(eventName)?.forEach((contextEventHandler) => contextEventHandler.handle(event, data));
58
- }
59
-
60
- /**
61
- * Check if the event and handler are subscribed.
62
- *
63
- * @param {Subscription} subscription The subscription object.
64
- * @param {string} subscription.eventName The name of the event to check.
65
- * @param {ContextEventHandler} subscription.contextEventHandler The event handler to check.
66
- * @returns {boolean} true if the event name and handler are subscribed, false otherwise.
67
- */
68
- isSubscribed({ eventName, contextEventHandler }) {
69
- return this.#subscribers.get(eventName)?.has(contextEventHandler);
70
- }
71
-
72
- get [Symbol.toStringTag]() {
73
- return 'Subscribr';
74
- }
75
- }
@@ -1,37 +0,0 @@
1
- /** @typedef { import('./context-event-handler.js').default } ContextEventHandler */
2
-
3
- export default class Subscription {
4
- #eventName;
5
- #contextEventHandler;
6
-
7
- /**
8
- * @param {string} eventName The event name.
9
- * @param {ContextEventHandler} contextEventHandler Then context event handler.
10
- */
11
- constructor(eventName, contextEventHandler) {
12
- this.#eventName = eventName;
13
- this.#contextEventHandler = contextEventHandler;
14
- }
15
-
16
- /**
17
- * Gets the event name for the subscription.
18
- *
19
- * @returns {string} The event name.
20
- */
21
- get eventName() {
22
- return this.#eventName;
23
- }
24
-
25
- /**
26
- * Gets the context event handler.
27
- *
28
- * @returns {ContextEventHandler} The context event handler
29
- */
30
- get contextEventHandler() {
31
- return this.#contextEventHandler;
32
- }
33
-
34
- get [Symbol.toStringTag]() {
35
- return 'Subscription';
36
- }
37
- }