@d1g1tal/subscribr 1.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,2 +1,29 @@
1
1
  # subscribr
2
2
  JavaScript Publish/Subscribe
3
+
4
+ This simple class enables you to subscribe and publish events using the Observer pattern.
5
+
6
+ ### Installation:
7
+ ```bash
8
+ npm install @d1g1tal/subscribr --save
9
+ ```
10
+
11
+ ### Usage:
12
+ ```javascript
13
+ const subscribr = new Subscribr();
14
+ const eventName = 'myEvent';
15
+ const eventHandler = (event) => console.log(`Event: '${event.type}' published`);
16
+
17
+ // Subscribr.prototype.subscribe returns a Subscription object.
18
+ const subscription = subscribr.subscribe(eventName, eventHandler);
19
+
20
+ // Publish the event and all handlers that have subscribed are called
21
+ subscribr.publish(eventName, new Event(eventName)); // Event: 'myEvent' published
22
+
23
+ // Is the event subscribed?
24
+ const isSubscribed = subscribr.isSubscribed(subscription); // true
25
+
26
+ const isUnsubscribed = subscription.unsubscribe(); // true
27
+
28
+ const isSubscribed = subscribr.isSubscribed(subscription); // false
29
+ ```
@@ -0,0 +1,253 @@
1
+ var Subscribr = (() => {
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/subscribr.js
21
+ var subscribr_exports = {};
22
+ __export(subscribr_exports, {
23
+ default: () => Subscribr
24
+ });
25
+
26
+ // node_modules/@d1g1tal/collections/src/list.js
27
+ var List = class {
28
+ #array;
29
+ constructor(iterable = []) {
30
+ this.#array = Array.of(...iterable);
31
+ }
32
+ static from(iterable, mapper, context) {
33
+ return new List(Array.from(iterable, mapper, context));
34
+ }
35
+ static withSize(size) {
36
+ return new List(new Array(size));
37
+ }
38
+ add(element) {
39
+ this.#array.push(element);
40
+ return this;
41
+ }
42
+ addAll(iterable) {
43
+ this.#array.push(...iterable);
44
+ return this;
45
+ }
46
+ clear() {
47
+ this.#array.length = 0;
48
+ }
49
+ concat(elements) {
50
+ return this(this.#array.concat(...elements));
51
+ }
52
+ every(predicate) {
53
+ return this.#array.every((element, index) => predicate(element, index, this));
54
+ }
55
+ some(predicate) {
56
+ return this.#array.some((element, index) => predicate(element, index, this));
57
+ }
58
+ filter(predicate) {
59
+ return new List(this.#array.filter((element, index) => predicate(element, index, this)));
60
+ }
61
+ find(predicate, context) {
62
+ return this.#array.find((element, index) => predicate(element, index, this), context);
63
+ }
64
+ findIndex(predicate, context) {
65
+ return this.#array.findIndex((element, index) => predicate(element, index, this), context);
66
+ }
67
+ map(mapper) {
68
+ return new List(this.#array.map((element, index) => mapper(element, index, this)));
69
+ }
70
+ reduce(reducer, initialValue) {
71
+ return this.#array.reduce(reducer, initialValue);
72
+ }
73
+ sort(comparator) {
74
+ this.#array.sort(comparator);
75
+ return this;
76
+ }
77
+ forEach(consumer) {
78
+ this.#array.forEach((element, index) => consumer(element, index, this));
79
+ }
80
+ get(element, fromIndex = 0) {
81
+ return this.#array.at(this.#array.indexOf(element, fromIndex));
82
+ }
83
+ has(element) {
84
+ return this.#array.includes(element);
85
+ }
86
+ insert(index, element) {
87
+ this.#array.splice(index, 0, element);
88
+ }
89
+ delete(element) {
90
+ return this.#array.splice(this.#array.indexOf(element), 1).length == 1;
91
+ }
92
+ deleteAt(index) {
93
+ return this.#array.splice(index, 1).length == 1;
94
+ }
95
+ keys() {
96
+ return this.#array.keys();
97
+ }
98
+ values() {
99
+ return this[Symbol.iterator]();
100
+ }
101
+ entries() {
102
+ return this.#array.entries();
103
+ }
104
+ isEmpty() {
105
+ return this.#array.length === 0;
106
+ }
107
+ toArray() {
108
+ return [...this.#array];
109
+ }
110
+ toString() {
111
+ return this.#array.toString();
112
+ }
113
+ valueOf() {
114
+ return this.#array.valueOf();
115
+ }
116
+ get size() {
117
+ return this.#array.length;
118
+ }
119
+ [Symbol.iterator]() {
120
+ return this.#array[Symbol.iterator]();
121
+ }
122
+ get [Symbol.toStringTag]() {
123
+ return "List";
124
+ }
125
+ };
126
+
127
+ // node_modules/@d1g1tal/collections/src/multi-map.js
128
+ var MultiMap = class extends Map {
129
+ set(key, value) {
130
+ super.set(key, (this.get(key) ?? new List()).add(value));
131
+ return this;
132
+ }
133
+ [Symbol.toStringTag]() {
134
+ return "MultiMap";
135
+ }
136
+ };
137
+
138
+ // node_modules/@d1g1tal/collections/src/set-multi-map.js
139
+ var SetMultiMap = class extends Map {
140
+ set(key, value) {
141
+ super.set(key, (super.get(key) ?? /* @__PURE__ */ new Set()).add(value));
142
+ return this;
143
+ }
144
+ [Symbol.toStringTag]() {
145
+ return "SetMultiMap";
146
+ }
147
+ };
148
+
149
+ // node_modules/@d1g1tal/collections/src/node.js
150
+ var Node = class {
151
+ #value;
152
+ #next;
153
+ constructor(value) {
154
+ this.#value = value;
155
+ this.#next = null;
156
+ }
157
+ get value() {
158
+ return this.#value;
159
+ }
160
+ get next() {
161
+ return this.#next;
162
+ }
163
+ get [Symbol.toStringTag]() {
164
+ return "Node";
165
+ }
166
+ };
167
+
168
+ // node_modules/@d1g1tal/collections/src/weak-set-multi-map.js
169
+ var WeakSetMultiMap = class extends Map {
170
+ set(key, value) {
171
+ super.set(key, (super.get(key) ?? /* @__PURE__ */ new WeakSet()).add(value));
172
+ return this;
173
+ }
174
+ [Symbol.toStringTag]() {
175
+ return "WeakSetMultiMap";
176
+ }
177
+ };
178
+
179
+ // src/context-event-handler.js
180
+ var ContextEventHandler = class {
181
+ #context;
182
+ #eventHandler;
183
+ constructor(context, eventHandler) {
184
+ this.#context = context;
185
+ this.#eventHandler = eventHandler;
186
+ }
187
+ get context() {
188
+ return this.#context;
189
+ }
190
+ get eventHandler() {
191
+ return this.#eventHandler;
192
+ }
193
+ get [Symbol.toStringTag]() {
194
+ return "ContextEventHandler";
195
+ }
196
+ };
197
+
198
+ // src/subscription.js
199
+ var Subscription = class {
200
+ #eventName;
201
+ #contextEventHandler;
202
+ #unsubscribe;
203
+ constructor(eventName, contextEventHandler, unsubscribe) {
204
+ this.#eventName = eventName;
205
+ this.#contextEventHandler = contextEventHandler;
206
+ this.#unsubscribe = unsubscribe;
207
+ }
208
+ get eventName() {
209
+ return this.#eventName;
210
+ }
211
+ get context() {
212
+ return this.#contextEventHandler.context;
213
+ }
214
+ get eventHandler() {
215
+ return this.#contextEventHandler.eventHandler;
216
+ }
217
+ unsubscribe() {
218
+ return this.#unsubscribe();
219
+ }
220
+ };
221
+
222
+ // src/subscribr.js
223
+ var Subscribr = class {
224
+ #subscribers;
225
+ constructor() {
226
+ this.#subscribers = new MultiMap();
227
+ }
228
+ subscribe(eventName, eventHandler, context) {
229
+ const contextEventHandler = new ContextEventHandler(context, eventHandler);
230
+ this.#subscribers.set(eventName, contextEventHandler);
231
+ return new Subscription(eventName, contextEventHandler, () => this.#unsubscribe(eventName, contextEventHandler));
232
+ }
233
+ publish(eventName, data) {
234
+ this.#subscribers.get(eventName)?.forEach(({ context, eventHandler }) => eventHandler.call(context, data));
235
+ }
236
+ isSubscribed({ eventName, eventHandler: handler }) {
237
+ return this.#subscribers.get(eventName)?.some(({ eventHandler }) => eventHandler === handler);
238
+ }
239
+ get [Symbol.toStringTag]() {
240
+ return "Subscribr";
241
+ }
242
+ #unsubscribe(eventName, contextEventHandler) {
243
+ const contextEventHandlers = this.#subscribers.get(eventName);
244
+ const removed = contextEventHandlers?.delete(contextEventHandler);
245
+ if (removed && contextEventHandlers.size == 0) {
246
+ this.#subscribers.delete(eventName);
247
+ }
248
+ return removed;
249
+ }
250
+ };
251
+ return __toCommonJS(subscribr_exports);
252
+ })();
253
+ window.Subscribr = Subscribr.default;
@@ -0,0 +1,3 @@
1
+ var Subscribr=(()=>{var f=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var x=(n,t)=>{for(var e in t)f(n,e,{get:t[e],enumerable:!0})},S=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of g(t))!m.call(n,s)&&s!==e&&f(n,s,{get:()=>t[s],enumerable:!(r=p(t,s))||r.enumerable});return n};var b=n=>S(f({},"__esModule",{value:!0}),n);var v={};x(v,{default:()=>d});var i=class{#t;constructor(t=[]){this.#t=Array.of(...t)}static from(t,e,r){return new i(Array.from(t,e,r))}static withSize(t){return new i(new Array(t))}add(t){return this.#t.push(t),this}addAll(t){return this.#t.push(...t),this}clear(){this.#t.length=0}concat(t){return this(this.#t.concat(...t))}every(t){return this.#t.every((e,r)=>t(e,r,this))}some(t){return this.#t.some((e,r)=>t(e,r,this))}filter(t){return new i(this.#t.filter((e,r)=>t(e,r,this)))}find(t,e){return this.#t.find((r,s)=>t(r,s,this),e)}findIndex(t,e){return this.#t.findIndex((r,s)=>t(r,s,this),e)}map(t){return new i(this.#t.map((e,r)=>t(e,r,this)))}reduce(t,e){return this.#t.reduce(t,e)}sort(t){return this.#t.sort(t),this}forEach(t){this.#t.forEach((e,r)=>t(e,r,this))}get(t,e=0){return this.#t.at(this.#t.indexOf(t,e))}has(t){return this.#t.includes(t)}insert(t,e){this.#t.splice(t,0,e)}delete(t){return this.#t.splice(this.#t.indexOf(t),1).length==1}deleteAt(t){return this.#t.splice(t,1).length==1}keys(){return this.#t.keys()}values(){return this[Symbol.iterator]()}entries(){return this.#t.entries()}isEmpty(){return this.#t.length===0}toArray(){return[...this.#t]}toString(){return this.#t.toString()}valueOf(){return this.#t.valueOf()}get size(){return this.#t.length}[Symbol.iterator](){return this.#t[Symbol.iterator]()}get[Symbol.toStringTag](){return"List"}};var u=class extends Map{set(t,e){return super.set(t,(this.get(t)??new i).add(e)),this}[Symbol.toStringTag](){return"MultiMap"}};var a=class extends Map{set(t,e){return super.set(t,(super.get(t)??new Set).add(e)),this}[Symbol.toStringTag](){return"SetMultiMap"}};var l=class{#t;#e;constructor(t){this.#t=t,this.#e=null}get value(){return this.#t}get next(){return this.#e}get[Symbol.toStringTag](){return"Node"}};var c=class extends Map{set(t,e){return super.set(t,(super.get(t)??new WeakSet).add(e)),this}[Symbol.toStringTag](){return"WeakSetMultiMap"}};var h=class{#t;#e;constructor(t,e){this.#t=t,this.#e=e}get context(){return this.#t}get eventHandler(){return this.#e}get[Symbol.toStringTag](){return"ContextEventHandler"}};var o=class{#t;#e;#r;constructor(t,e,r){this.#t=t,this.#e=e,this.#r=r}get eventName(){return this.#t}get context(){return this.#e.context}get eventHandler(){return this.#e.eventHandler}unsubscribe(){return this.#r()}};var d=class{#t;constructor(){this.#t=new u}subscribe(t,e,r){let s=new h(r,e);return this.#t.set(t,s),new o(t,s,()=>this.#e(t,s))}publish(t,e){this.#t.get(t)?.forEach(({context:r,eventHandler:s})=>s.call(r,e))}isSubscribed({eventName:t,eventHandler:e}){return this.#t.get(t)?.some(({eventHandler:r})=>r===e)}get[Symbol.toStringTag](){return"Subscribr"}#e(t,e){let r=this.#t.get(t),s=r?.delete(e);return s&&r.size==0&&this.#t.delete(t),s}};return b(v);})();
2
+ window.Subscribr = Subscribr.default;
3
+ //# sourceMappingURL=subscribr.min.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/subscribr.js", "../../node_modules/@d1g1tal/collections/src/list.js", "../../node_modules/@d1g1tal/collections/src/multi-map.js", "../../node_modules/@d1g1tal/collections/src/set-multi-map.js", "../../node_modules/@d1g1tal/collections/src/node.js", "../../node_modules/@d1g1tal/collections/src/weak-set-multi-map.js", "../../src/context-event-handler.js", "../../src/subscription.js"],
4
+ "sourcesContent": ["import { MultiMap } from '@d1g1tal/collections';\nimport ContextEventHandler from './context-event-handler.js';\nimport Subscription from './subscription.js';\n\nexport default class Subscribr {\n\t/** @type {MultiMap<string, ContextEventHandler>} */\n\t#subscribers;\n\n\tconstructor() {\n\t\tthis.#subscribers = new MultiMap();\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 {function(*): void} eventHandler The event handler to call when the event is published.\n\t * @param {*} [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, eventHandler, context) {\n\t\tconst contextEventHandler = new ContextEventHandler(context, eventHandler);\n\t\tthis.#subscribers.set(eventName, contextEventHandler);\n\n\t\treturn new Subscription(eventName, contextEventHandler, () => this.#unsubscribe(eventName, contextEventHandler));\n\t}\n\n\t/**\n\t * Publish an event\n\t *\n\t * @param {string} eventName The name of the event.\n\t * @param {*} [data] The value to be passed to the event handler as a parameter.\n\t */\n\tpublish(eventName, data) {\n\t\tthis.#subscribers.get(eventName)?.forEach(({context, eventHandler}) => eventHandler.call(context, 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 * @param {string} subscription.eventName The name of the event to check.\n\t * @param {function(*)} subscription.eventHandler The event handler to check.\n\t * @returns {boolean} true if the event name and handler are subscribed, false otherwise.\n\t */\n\tisSubscribed({ eventName, eventHandler: handler}) {\n\t\treturn this.#subscribers.get(eventName)?.some(({ eventHandler }) => eventHandler === handler);\n\t}\n\n\tget [Symbol.toStringTag]() {\n\t\treturn 'Subscribr';\n\t}\n\n\t/**\n\t * Unsubscribe from the event\n\t *\n\t * @param {string} eventName The event name to subscribe to.\n\t * @param {ContextEventHandler} contextEventHandler The event handler to call when the event is published.\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\t#unsubscribe(eventName, contextEventHandler) {\n\t\tconst contextEventHandlers = this.#subscribers.get(eventName);\n\t\tconst removed = contextEventHandlers?.delete(contextEventHandler);\n\n\t\tif (removed && contextEventHandlers.size == 0) {\n\t\t\tthis.#subscribers.delete(eventName);\n\t\t}\n\n\t\treturn removed;\n\t}\n}", "\n/**\n *\n * @template E\n * @typedef {Iterable<E>} List<E>\n */\n\n/**\n * @template E\n * @type {List<E>}\n */\nexport default class List {\n\t/** @type {Array<E>} */\n\t#array;\n\n\t/**\n\t *\n\t * @param {Iterable<E>} [iterable]\n\t */\n\tconstructor(iterable = []) {\n\t\tthis.#array = Array.of(...iterable);\n\t}\n\n\t/**\n\t *\n\t * @param {Iterable<E>} iterable\n\t * @param {function(E, number?)} mapper\n\t * @param {*} context\n\t * @returns {List<E>}\n\t */\n\tstatic from(iterable, mapper, context) {\n\t\treturn new List(Array.from(iterable, mapper, context));\n\t}\n\n\tstatic withSize(size) {\n\t\treturn new List(new Array(size));\n\t}\n\n\t/**\n\t *\n\t * @param {E} element\n\t * @returns {List<E>} The updated list\n\t */\n\tadd(element) {\n\t\tthis.#array.push(element);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t *\n\t * @param {Iterable<E>} iterable\n\t * @returns {List<E>} The updated list\n\t */\n\taddAll(iterable) {\n\t\tthis.#array.push(...iterable);\n\n\t\treturn this;\n\t}\n\n\tclear() {\n\t\tthis.#array.length = 0;\n\t}\n\n\t/**\n\t *\n\t * @param {E} elements\n\t * @returns {List<E>}\n\t */\n\tconcat(elements) {\n\t\treturn this(this.#array.concat(...elements));\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?): boolean} predicate\n\t * @returns {boolean}\n\t */\n\tevery(predicate) {\n\t\treturn this.#array.every((element, index) => predicate(element, index, this));\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?): boolean} predicate\n\t * @returns {boolean}\n\t */\n\tsome(predicate) {\n\t\treturn this.#array.some((element, index) => predicate(element, index, this));\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?): boolean} predicate\n\t * @returns {List<E>}\n\t */\n\tfilter(predicate) {\n\t\treturn new List(this.#array.filter((element, index) => predicate(element, index, this)));\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?): boolean} predicate\n\t * @param {*} [context] Optional object to use as this when calling the predicate function\n\t * @returns {E}\n\t */\n\tfind(predicate, context) {\n\t\treturn this.#array.find((element, index) => predicate(element, index, this), context);\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?): boolean} predicate\n\t * @param {*} [context] Optional object to use as this when calling the predicate function\n\t * @returns {number}\n\t */\n\tfindIndex(predicate, context) {\n\t\treturn this.#array.findIndex((element, index) => predicate(element, index, this), context);\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?)} mapper\n\t * @returns {List<E>}\n\t */\n\tmap(mapper) {\n\t\treturn new List(this.#array.map((element, index) => mapper(element, index, this)));\n\t}\n\n\t/**\n\t * Executes a user-supplied \"reducer\" callback function on each element of the list, in order,\n\t * passing in the return value from the calculation on the preceding element. The final result\n\t * of running the reducer across all elements of the array is a single value.\n\t *\n\t * @param {function(E, E, *)} reducer\n\t * @param {*} [initialValue]\n\t * @returns {*}\n\t */\n\treduce(reducer, initialValue) {\n\t\treturn this.#array.reduce(reducer, initialValue);\n\t}\n\n\t/**\n\t * Sorts the elements of a list in place and returns the reference to the same list, now sorted.\n\t * The default sort order is ascending, built upon converting the elements into strings,\n\t * then comparing their sequences of UTF-16 code units values.\n\t *\n\t * The sort() method preserves empty slots. If the source list is sparse, the empty slots are moved to the end of the list, and always come after all the undefined values.\n\t *\n\t * @example\n\t * // returns\n\t * new List([50, 3, 20, 33, 9, 1]).sort();\n\t * @param {function(E, E): number} [comparator] A function that defines the sort order. If omitted, the list elements are converted to strings, then sorted according to each character's Unicode code point value.\n\t * @returns {List<E>} The reference to the original list, now sorted. Note that the list is sorted in place, and no copy is made.\n\t */\n\tsort(comparator) {\n\t\tthis.#array.sort(comparator);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?): boolean} consumer\n\t */\n\tforEach(consumer) {\n\t\tthis.#array.forEach((element, index) => consumer(element, index, this));\n\t}\n\n\t/**\n\t *\n\t * @param {E} element\n\t * @param {number} [fromIndex]\n\t * @returns {E}\n\t */\n\tget(element, fromIndex = 0) {\n\t\treturn this.#array.at(this.#array.indexOf(element, fromIndex));\n\t}\n\n\t/**\n\t *\n\t * @param {E} element\n\t * @returns {boolean}\n\t */\n\thas(element) {\n\t\treturn this.#array.includes(element);\n\t}\n\n\t/**\n\t * Inserts the entry in a sorted list in the correct position.\n\t * The list must be sorted in ascending order to work.\n\t *\n\t * @param {number} index\n\t * @param {E} element The entry to add to the list.\n\t */\n\tinsert(index, element) {\n\t\tthis.#array.splice(index, 0, element);\n\t}\n\n\t/**\n\t * Removes the element associated to the value and returns a boolean asserting whether an element was successfully removed or not.\n\t *\n\t * @param {E} element The element to remove\n\t * @returns {boolean} true if element was already in {@link List}; otherwise false.\n\t */\n\tdelete(element) {\n\t\treturn this.#array.splice(this.#array.indexOf(element), 1).length == 1;\n\t}\n\n\t/**\n\t * Removes the element at the specified index and returns a boolean asserting whether an element was successfully removed or not.\n\t *\n\t * @param {number} index The element to remove\n\t * @returns {boolean} true if element was already in {@link List}; otherwise false.\n\t */\n\tdeleteAt(index) {\n\t\treturn this.#array.splice(index, 1).length == 1;\n\t}\n\n\tkeys() {\n\t\treturn this.#array.keys();\n\t}\n\n\t/**\n\t *\n\t * @returns {IterableIterator<E>}\n\t */\n\tvalues() {\n\t\treturn this[Symbol.iterator]();\n\t}\n\n\t/**\n\t *\n\t * @returns {IterableIterator<number, E>}\n\t */\n\tentries() {\n\t\treturn this.#array.entries();\n\t}\n\n\t/**\n\t * Checks to see if the list is empty\n\t *\n\t * @returns {boolean} true if the list is empty, false otherwise.\n\t */\n\tisEmpty() {\n\t\treturn this.#array.length === 0;\n\t}\n\n\ttoArray() {\n\t\treturn [...this.#array];\n\t}\n\n\ttoString() {\n\t\treturn this.#array.toString();\n\t}\n\n\tvalueOf() {\n\t\treturn this.#array.valueOf();\n\t}\n\n\tget size() {\n\t\treturn this.#array.length;\n\t}\n\n\t[Symbol.iterator]() {\n\t\treturn this.#array[Symbol.iterator]();\n\t}\n\n\tget [Symbol.toStringTag]() {\n\t\treturn 'List';\n\t}\n}", "import List from './list.js';\n\n/**\n *\n * @template K\n * @template V\n * @typedef {Map<K, V>} MultiMap\n * @extends Map\n */\nexport default class MultiMap extends Map {\n\t/**\n\t * Adds a new element with a specified key and value to the MultiMap.\n\t * If an element with the same key already exists, the value will be added to the underlying {@link List}.\n\t *\n\t * @override\n\t * @template K\n\t * @template V\n\t * @param {K} key The key to set.\n\t * @param {V} value The value to add to the MultiMap\n\t * @returns {MultiMap<K, V>} The MultiMap with the updated key and value.\n\t */\n\tset(key, value) {\n\t\tsuper.set(key, (this.get(key) ?? new List()).add(value));\n\n\t\treturn this;\n\t}\n\n\t[Symbol.toStringTag]() {\n\t\treturn 'MultiMap';\n\t}\n}", "/**\n *\n * @typedef {Map<*, *>} MultiMap\n * @extends Map\n */\nexport default class SetMultiMap extends Map {\n\t/**\n\t * Adds a new element with a specified key and value to the MultiMap. If an element with the same key already exists, the value will be added to the underlying {@link Set}.\n\t *\n\t * @param {*} key The key to set.\n\t * @param {*} value The value to add to the MultiMap\n\t * @returns {MultiMap} The MultiMap with the updated key and value.\n\t */\n\tset(key, value) {\n\t\tsuper.set(key, (super.get(key) ?? new Set()).add(value));\n\n\t\treturn this;\n\t}\n\n\t[Symbol.toStringTag]() {\n\t\treturn 'SetMultiMap';\n\t}\n}", "export default class Node {\n\t#value;\n\t#next;\n\n\tconstructor(value) {\n\t\tthis.#value = value;\n\t\tthis.#next = null;\n\t}\n\n\tget value() {\n\t\treturn this.#value;\n\t}\n\n\tget next() {\n\t\treturn this.#next;\n\t}\n\n\tget [Symbol.toStringTag]() {\n\t\treturn 'Node';\n\t}\n}", "/**\n *\n * @typedef {Map<*, *>} MultiMap\n * @extends Map\n */\nexport default class WeakSetMultiMap extends Map {\n\t/**\n\t * Adds a new element with a specified key and value to the MultiMap. If an element with the same key already exists, the value will be added to the underlying {@link Set}.\n\t *\n\t * @param {*} key The key to set.\n\t * @param {*} value The value to add to the MultiMap\n\t * @returns {MultiMap} The MultiMap with the updated key and value.\n\t */\n\tset(key, value) {\n\t\tsuper.set(key, (super.get(key) ?? new WeakSet()).add(value));\n\n\t\treturn this;\n\t}\n\n\t[Symbol.toStringTag]() {\n\t\treturn 'WeakSetMultiMap';\n\t}\n}", "export default class ContextEventHandler {\n\t#context;\n\t#eventHandler;\n\n\t/**\n\t *\n\t * @param {*} context The context to bind to the event handler.\n\t * @param {function(*): void} eventHandler The event handler to call when the event is published.\n\t */\n\tconstructor(context, eventHandler) {\n\t\tthis.#context = context;\n\t\tthis.#eventHandler = eventHandler;\n\t}\n\n\tget context() {\n\t\treturn this.#context;\n\t}\n\n\tget eventHandler() {\n\t\treturn this.#eventHandler;\n\t}\n\n\tget [Symbol.toStringTag]() {\n\t\treturn 'ContextEventHandler';\n\t}\n}", "export default class Subscription {\n\t#eventName;\n\t#contextEventHandler;\n\t#unsubscribe;\n\n\t/**\n\t *\n\t * @param {string} eventName\n\t * @param {import('./context-event-handler.js').default} contextEventHandler\n\t * @param {function(string, function(*): void): boolean} unsubscribe\n\t */\n\tconstructor(eventName, contextEventHandler, unsubscribe) {\n\t\tthis.#eventName = eventName;\n\t\tthis.#contextEventHandler = contextEventHandler;\n\t\tthis.#unsubscribe = unsubscribe;\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() {\n\t\treturn this.#eventName;\n\t}\n\n\t/**\n\t * Gets the context which will be bound to the event handler when it is called.\n\t *\n\t * @returns {*} The event handler context.\n\t */\n\tget context() {\n\t\treturn this.#contextEventHandler.context;\n\t}\n\n\t/**\n\t * Gets the event handler for the subscription.\n\t *\n\t * @returns {function(*): void} The event handler.\n\t */\n\tget eventHandler() {\n\t\treturn this.#contextEventHandler.eventHandler;\n\t}\n\n\t/**\n\t * Unsubscribes from the event.\n\t *\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() {\n\t\treturn this.#unsubscribe();\n\t}\n}"],
5
+ "mappings": "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",
6
+ "names": ["subscribr_exports", "__export", "Subscribr", "List", "#array", "iterable", "mapper", "context", "size", "element", "elements", "predicate", "index", "reducer", "initialValue", "comparator", "consumer", "fromIndex", "MultiMap", "key", "value", "List", "SetMultiMap", "key", "value", "Node", "#value", "#next", "value", "WeakSetMultiMap", "key", "value", "ContextEventHandler", "#context", "#eventHandler", "context", "eventHandler", "Subscription", "#eventName", "#contextEventHandler", "#unsubscribe", "eventName", "contextEventHandler", "unsubscribe", "Subscribr", "#subscribers", "MultiMap", "eventName", "eventHandler", "context", "contextEventHandler", "ContextEventHandler", "Subscription", "#unsubscribe", "data", "handler", "contextEventHandlers", "removed"]
7
+ }
@@ -0,0 +1,228 @@
1
+ // node_modules/@d1g1tal/collections/src/list.js
2
+ var List = class {
3
+ #array;
4
+ constructor(iterable = []) {
5
+ this.#array = Array.of(...iterable);
6
+ }
7
+ static from(iterable, mapper, context) {
8
+ return new List(Array.from(iterable, mapper, context));
9
+ }
10
+ static withSize(size) {
11
+ return new List(new Array(size));
12
+ }
13
+ add(element) {
14
+ this.#array.push(element);
15
+ return this;
16
+ }
17
+ addAll(iterable) {
18
+ this.#array.push(...iterable);
19
+ return this;
20
+ }
21
+ clear() {
22
+ this.#array.length = 0;
23
+ }
24
+ concat(elements) {
25
+ return this(this.#array.concat(...elements));
26
+ }
27
+ every(predicate) {
28
+ return this.#array.every((element, index) => predicate(element, index, this));
29
+ }
30
+ some(predicate) {
31
+ return this.#array.some((element, index) => predicate(element, index, this));
32
+ }
33
+ filter(predicate) {
34
+ return new List(this.#array.filter((element, index) => predicate(element, index, this)));
35
+ }
36
+ find(predicate, context) {
37
+ return this.#array.find((element, index) => predicate(element, index, this), context);
38
+ }
39
+ findIndex(predicate, context) {
40
+ return this.#array.findIndex((element, index) => predicate(element, index, this), context);
41
+ }
42
+ map(mapper) {
43
+ return new List(this.#array.map((element, index) => mapper(element, index, this)));
44
+ }
45
+ reduce(reducer, initialValue) {
46
+ return this.#array.reduce(reducer, initialValue);
47
+ }
48
+ sort(comparator) {
49
+ this.#array.sort(comparator);
50
+ return this;
51
+ }
52
+ forEach(consumer) {
53
+ this.#array.forEach((element, index) => consumer(element, index, this));
54
+ }
55
+ get(element, fromIndex = 0) {
56
+ return this.#array.at(this.#array.indexOf(element, fromIndex));
57
+ }
58
+ has(element) {
59
+ return this.#array.includes(element);
60
+ }
61
+ insert(index, element) {
62
+ this.#array.splice(index, 0, element);
63
+ }
64
+ delete(element) {
65
+ return this.#array.splice(this.#array.indexOf(element), 1).length == 1;
66
+ }
67
+ deleteAt(index) {
68
+ return this.#array.splice(index, 1).length == 1;
69
+ }
70
+ keys() {
71
+ return this.#array.keys();
72
+ }
73
+ values() {
74
+ return this[Symbol.iterator]();
75
+ }
76
+ entries() {
77
+ return this.#array.entries();
78
+ }
79
+ isEmpty() {
80
+ return this.#array.length === 0;
81
+ }
82
+ toArray() {
83
+ return [...this.#array];
84
+ }
85
+ toString() {
86
+ return this.#array.toString();
87
+ }
88
+ valueOf() {
89
+ return this.#array.valueOf();
90
+ }
91
+ get size() {
92
+ return this.#array.length;
93
+ }
94
+ [Symbol.iterator]() {
95
+ return this.#array[Symbol.iterator]();
96
+ }
97
+ get [Symbol.toStringTag]() {
98
+ return "List";
99
+ }
100
+ };
101
+
102
+ // node_modules/@d1g1tal/collections/src/multi-map.js
103
+ var MultiMap = class extends Map {
104
+ set(key, value) {
105
+ super.set(key, (this.get(key) ?? new List()).add(value));
106
+ return this;
107
+ }
108
+ [Symbol.toStringTag]() {
109
+ return "MultiMap";
110
+ }
111
+ };
112
+
113
+ // node_modules/@d1g1tal/collections/src/set-multi-map.js
114
+ var SetMultiMap = class extends Map {
115
+ set(key, value) {
116
+ super.set(key, (super.get(key) ?? /* @__PURE__ */ new Set()).add(value));
117
+ return this;
118
+ }
119
+ [Symbol.toStringTag]() {
120
+ return "SetMultiMap";
121
+ }
122
+ };
123
+
124
+ // node_modules/@d1g1tal/collections/src/node.js
125
+ var Node = class {
126
+ #value;
127
+ #next;
128
+ constructor(value) {
129
+ this.#value = value;
130
+ this.#next = null;
131
+ }
132
+ get value() {
133
+ return this.#value;
134
+ }
135
+ get next() {
136
+ return this.#next;
137
+ }
138
+ get [Symbol.toStringTag]() {
139
+ return "Node";
140
+ }
141
+ };
142
+
143
+ // node_modules/@d1g1tal/collections/src/weak-set-multi-map.js
144
+ var WeakSetMultiMap = class extends Map {
145
+ set(key, value) {
146
+ super.set(key, (super.get(key) ?? /* @__PURE__ */ new WeakSet()).add(value));
147
+ return this;
148
+ }
149
+ [Symbol.toStringTag]() {
150
+ return "WeakSetMultiMap";
151
+ }
152
+ };
153
+
154
+ // src/context-event-handler.js
155
+ var ContextEventHandler = class {
156
+ #context;
157
+ #eventHandler;
158
+ constructor(context, eventHandler) {
159
+ this.#context = context;
160
+ this.#eventHandler = eventHandler;
161
+ }
162
+ get context() {
163
+ return this.#context;
164
+ }
165
+ get eventHandler() {
166
+ return this.#eventHandler;
167
+ }
168
+ get [Symbol.toStringTag]() {
169
+ return "ContextEventHandler";
170
+ }
171
+ };
172
+
173
+ // src/subscription.js
174
+ var Subscription = class {
175
+ #eventName;
176
+ #contextEventHandler;
177
+ #unsubscribe;
178
+ constructor(eventName, contextEventHandler, unsubscribe) {
179
+ this.#eventName = eventName;
180
+ this.#contextEventHandler = contextEventHandler;
181
+ this.#unsubscribe = unsubscribe;
182
+ }
183
+ get eventName() {
184
+ return this.#eventName;
185
+ }
186
+ get context() {
187
+ return this.#contextEventHandler.context;
188
+ }
189
+ get eventHandler() {
190
+ return this.#contextEventHandler.eventHandler;
191
+ }
192
+ unsubscribe() {
193
+ return this.#unsubscribe();
194
+ }
195
+ };
196
+
197
+ // src/subscribr.js
198
+ var Subscribr = class {
199
+ #subscribers;
200
+ constructor() {
201
+ this.#subscribers = new MultiMap();
202
+ }
203
+ subscribe(eventName, eventHandler, context) {
204
+ const contextEventHandler = new ContextEventHandler(context, eventHandler);
205
+ this.#subscribers.set(eventName, contextEventHandler);
206
+ return new Subscription(eventName, contextEventHandler, () => this.#unsubscribe(eventName, contextEventHandler));
207
+ }
208
+ publish(eventName, data) {
209
+ this.#subscribers.get(eventName)?.forEach(({ context, eventHandler }) => eventHandler.call(context, data));
210
+ }
211
+ isSubscribed({ eventName, eventHandler: handler }) {
212
+ return this.#subscribers.get(eventName)?.some(({ eventHandler }) => eventHandler === handler);
213
+ }
214
+ get [Symbol.toStringTag]() {
215
+ return "Subscribr";
216
+ }
217
+ #unsubscribe(eventName, contextEventHandler) {
218
+ const contextEventHandlers = this.#subscribers.get(eventName);
219
+ const removed = contextEventHandlers?.delete(contextEventHandler);
220
+ if (removed && contextEventHandlers.size == 0) {
221
+ this.#subscribers.delete(eventName);
222
+ }
223
+ return removed;
224
+ }
225
+ };
226
+ export {
227
+ Subscribr as default
228
+ };
@@ -0,0 +1,2 @@
1
+ var n=class{#t;constructor(t=[]){this.#t=Array.of(...t)}static from(t,e,r){return new n(Array.from(t,e,r))}static withSize(t){return new n(new Array(t))}add(t){return this.#t.push(t),this}addAll(t){return this.#t.push(...t),this}clear(){this.#t.length=0}concat(t){return this(this.#t.concat(...t))}every(t){return this.#t.every((e,r)=>t(e,r,this))}some(t){return this.#t.some((e,r)=>t(e,r,this))}filter(t){return new n(this.#t.filter((e,r)=>t(e,r,this)))}find(t,e){return this.#t.find((r,s)=>t(r,s,this),e)}findIndex(t,e){return this.#t.findIndex((r,s)=>t(r,s,this),e)}map(t){return new n(this.#t.map((e,r)=>t(e,r,this)))}reduce(t,e){return this.#t.reduce(t,e)}sort(t){return this.#t.sort(t),this}forEach(t){this.#t.forEach((e,r)=>t(e,r,this))}get(t,e=0){return this.#t.at(this.#t.indexOf(t,e))}has(t){return this.#t.includes(t)}insert(t,e){this.#t.splice(t,0,e)}delete(t){return this.#t.splice(this.#t.indexOf(t),1).length==1}deleteAt(t){return this.#t.splice(t,1).length==1}keys(){return this.#t.keys()}values(){return this[Symbol.iterator]()}entries(){return this.#t.entries()}isEmpty(){return this.#t.length===0}toArray(){return[...this.#t]}toString(){return this.#t.toString()}valueOf(){return this.#t.valueOf()}get size(){return this.#t.length}[Symbol.iterator](){return this.#t[Symbol.iterator]()}get[Symbol.toStringTag](){return"List"}};var u=class extends Map{set(t,e){return super.set(t,(this.get(t)??new n).add(e)),this}[Symbol.toStringTag](){return"MultiMap"}};var a=class extends Map{set(t,e){return super.set(t,(super.get(t)??new Set).add(e)),this}[Symbol.toStringTag](){return"SetMultiMap"}};var l=class{#t;#e;constructor(t){this.#t=t,this.#e=null}get value(){return this.#t}get next(){return this.#e}get[Symbol.toStringTag](){return"Node"}};var c=class extends Map{set(t,e){return super.set(t,(super.get(t)??new WeakSet).add(e)),this}[Symbol.toStringTag](){return"WeakSetMultiMap"}};var h=class{#t;#e;constructor(t,e){this.#t=t,this.#e=e}get context(){return this.#t}get eventHandler(){return this.#e}get[Symbol.toStringTag](){return"ContextEventHandler"}};var o=class{#t;#e;#r;constructor(t,e,r){this.#t=t,this.#e=e,this.#r=r}get eventName(){return this.#t}get context(){return this.#e.context}get eventHandler(){return this.#e.eventHandler}unsubscribe(){return this.#r()}};var d=class{#t;constructor(){this.#t=new u}subscribe(t,e,r){let s=new h(r,e);return this.#t.set(t,s),new o(t,s,()=>this.#e(t,s))}publish(t,e){this.#t.get(t)?.forEach(({context:r,eventHandler:s})=>s.call(r,e))}isSubscribed({eventName:t,eventHandler:e}){return this.#t.get(t)?.some(({eventHandler:r})=>r===e)}get[Symbol.toStringTag](){return"Subscribr"}#e(t,e){let r=this.#t.get(t),s=r?.delete(e);return s&&r.size==0&&this.#t.delete(t),s}};export{d as default};
2
+ //# sourceMappingURL=subscribr.min.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../node_modules/@d1g1tal/collections/src/list.js", "../../node_modules/@d1g1tal/collections/src/multi-map.js", "../../node_modules/@d1g1tal/collections/src/set-multi-map.js", "../../node_modules/@d1g1tal/collections/src/node.js", "../../node_modules/@d1g1tal/collections/src/weak-set-multi-map.js", "../../src/context-event-handler.js", "../../src/subscription.js", "../../src/subscribr.js"],
4
+ "sourcesContent": ["\n/**\n *\n * @template E\n * @typedef {Iterable<E>} List<E>\n */\n\n/**\n * @template E\n * @type {List<E>}\n */\nexport default class List {\n\t/** @type {Array<E>} */\n\t#array;\n\n\t/**\n\t *\n\t * @param {Iterable<E>} [iterable]\n\t */\n\tconstructor(iterable = []) {\n\t\tthis.#array = Array.of(...iterable);\n\t}\n\n\t/**\n\t *\n\t * @param {Iterable<E>} iterable\n\t * @param {function(E, number?)} mapper\n\t * @param {*} context\n\t * @returns {List<E>}\n\t */\n\tstatic from(iterable, mapper, context) {\n\t\treturn new List(Array.from(iterable, mapper, context));\n\t}\n\n\tstatic withSize(size) {\n\t\treturn new List(new Array(size));\n\t}\n\n\t/**\n\t *\n\t * @param {E} element\n\t * @returns {List<E>} The updated list\n\t */\n\tadd(element) {\n\t\tthis.#array.push(element);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t *\n\t * @param {Iterable<E>} iterable\n\t * @returns {List<E>} The updated list\n\t */\n\taddAll(iterable) {\n\t\tthis.#array.push(...iterable);\n\n\t\treturn this;\n\t}\n\n\tclear() {\n\t\tthis.#array.length = 0;\n\t}\n\n\t/**\n\t *\n\t * @param {E} elements\n\t * @returns {List<E>}\n\t */\n\tconcat(elements) {\n\t\treturn this(this.#array.concat(...elements));\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?): boolean} predicate\n\t * @returns {boolean}\n\t */\n\tevery(predicate) {\n\t\treturn this.#array.every((element, index) => predicate(element, index, this));\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?): boolean} predicate\n\t * @returns {boolean}\n\t */\n\tsome(predicate) {\n\t\treturn this.#array.some((element, index) => predicate(element, index, this));\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?): boolean} predicate\n\t * @returns {List<E>}\n\t */\n\tfilter(predicate) {\n\t\treturn new List(this.#array.filter((element, index) => predicate(element, index, this)));\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?): boolean} predicate\n\t * @param {*} [context] Optional object to use as this when calling the predicate function\n\t * @returns {E}\n\t */\n\tfind(predicate, context) {\n\t\treturn this.#array.find((element, index) => predicate(element, index, this), context);\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?): boolean} predicate\n\t * @param {*} [context] Optional object to use as this when calling the predicate function\n\t * @returns {number}\n\t */\n\tfindIndex(predicate, context) {\n\t\treturn this.#array.findIndex((element, index) => predicate(element, index, this), context);\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?)} mapper\n\t * @returns {List<E>}\n\t */\n\tmap(mapper) {\n\t\treturn new List(this.#array.map((element, index) => mapper(element, index, this)));\n\t}\n\n\t/**\n\t * Executes a user-supplied \"reducer\" callback function on each element of the list, in order,\n\t * passing in the return value from the calculation on the preceding element. The final result\n\t * of running the reducer across all elements of the array is a single value.\n\t *\n\t * @param {function(E, E, *)} reducer\n\t * @param {*} [initialValue]\n\t * @returns {*}\n\t */\n\treduce(reducer, initialValue) {\n\t\treturn this.#array.reduce(reducer, initialValue);\n\t}\n\n\t/**\n\t * Sorts the elements of a list in place and returns the reference to the same list, now sorted.\n\t * The default sort order is ascending, built upon converting the elements into strings,\n\t * then comparing their sequences of UTF-16 code units values.\n\t *\n\t * The sort() method preserves empty slots. If the source list is sparse, the empty slots are moved to the end of the list, and always come after all the undefined values.\n\t *\n\t * @example\n\t * // returns\n\t * new List([50, 3, 20, 33, 9, 1]).sort();\n\t * @param {function(E, E): number} [comparator] A function that defines the sort order. If omitted, the list elements are converted to strings, then sorted according to each character's Unicode code point value.\n\t * @returns {List<E>} The reference to the original list, now sorted. Note that the list is sorted in place, and no copy is made.\n\t */\n\tsort(comparator) {\n\t\tthis.#array.sort(comparator);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t *\n\t * @param {function(E, number?, List<E>?): boolean} consumer\n\t */\n\tforEach(consumer) {\n\t\tthis.#array.forEach((element, index) => consumer(element, index, this));\n\t}\n\n\t/**\n\t *\n\t * @param {E} element\n\t * @param {number} [fromIndex]\n\t * @returns {E}\n\t */\n\tget(element, fromIndex = 0) {\n\t\treturn this.#array.at(this.#array.indexOf(element, fromIndex));\n\t}\n\n\t/**\n\t *\n\t * @param {E} element\n\t * @returns {boolean}\n\t */\n\thas(element) {\n\t\treturn this.#array.includes(element);\n\t}\n\n\t/**\n\t * Inserts the entry in a sorted list in the correct position.\n\t * The list must be sorted in ascending order to work.\n\t *\n\t * @param {number} index\n\t * @param {E} element The entry to add to the list.\n\t */\n\tinsert(index, element) {\n\t\tthis.#array.splice(index, 0, element);\n\t}\n\n\t/**\n\t * Removes the element associated to the value and returns a boolean asserting whether an element was successfully removed or not.\n\t *\n\t * @param {E} element The element to remove\n\t * @returns {boolean} true if element was already in {@link List}; otherwise false.\n\t */\n\tdelete(element) {\n\t\treturn this.#array.splice(this.#array.indexOf(element), 1).length == 1;\n\t}\n\n\t/**\n\t * Removes the element at the specified index and returns a boolean asserting whether an element was successfully removed or not.\n\t *\n\t * @param {number} index The element to remove\n\t * @returns {boolean} true if element was already in {@link List}; otherwise false.\n\t */\n\tdeleteAt(index) {\n\t\treturn this.#array.splice(index, 1).length == 1;\n\t}\n\n\tkeys() {\n\t\treturn this.#array.keys();\n\t}\n\n\t/**\n\t *\n\t * @returns {IterableIterator<E>}\n\t */\n\tvalues() {\n\t\treturn this[Symbol.iterator]();\n\t}\n\n\t/**\n\t *\n\t * @returns {IterableIterator<number, E>}\n\t */\n\tentries() {\n\t\treturn this.#array.entries();\n\t}\n\n\t/**\n\t * Checks to see if the list is empty\n\t *\n\t * @returns {boolean} true if the list is empty, false otherwise.\n\t */\n\tisEmpty() {\n\t\treturn this.#array.length === 0;\n\t}\n\n\ttoArray() {\n\t\treturn [...this.#array];\n\t}\n\n\ttoString() {\n\t\treturn this.#array.toString();\n\t}\n\n\tvalueOf() {\n\t\treturn this.#array.valueOf();\n\t}\n\n\tget size() {\n\t\treturn this.#array.length;\n\t}\n\n\t[Symbol.iterator]() {\n\t\treturn this.#array[Symbol.iterator]();\n\t}\n\n\tget [Symbol.toStringTag]() {\n\t\treturn 'List';\n\t}\n}", "import List from './list.js';\n\n/**\n *\n * @template K\n * @template V\n * @typedef {Map<K, V>} MultiMap\n * @extends Map\n */\nexport default class MultiMap extends Map {\n\t/**\n\t * Adds a new element with a specified key and value to the MultiMap.\n\t * If an element with the same key already exists, the value will be added to the underlying {@link List}.\n\t *\n\t * @override\n\t * @template K\n\t * @template V\n\t * @param {K} key The key to set.\n\t * @param {V} value The value to add to the MultiMap\n\t * @returns {MultiMap<K, V>} The MultiMap with the updated key and value.\n\t */\n\tset(key, value) {\n\t\tsuper.set(key, (this.get(key) ?? new List()).add(value));\n\n\t\treturn this;\n\t}\n\n\t[Symbol.toStringTag]() {\n\t\treturn 'MultiMap';\n\t}\n}", "/**\n *\n * @typedef {Map<*, *>} MultiMap\n * @extends Map\n */\nexport default class SetMultiMap extends Map {\n\t/**\n\t * Adds a new element with a specified key and value to the MultiMap. If an element with the same key already exists, the value will be added to the underlying {@link Set}.\n\t *\n\t * @param {*} key The key to set.\n\t * @param {*} value The value to add to the MultiMap\n\t * @returns {MultiMap} The MultiMap with the updated key and value.\n\t */\n\tset(key, value) {\n\t\tsuper.set(key, (super.get(key) ?? new Set()).add(value));\n\n\t\treturn this;\n\t}\n\n\t[Symbol.toStringTag]() {\n\t\treturn 'SetMultiMap';\n\t}\n}", "export default class Node {\n\t#value;\n\t#next;\n\n\tconstructor(value) {\n\t\tthis.#value = value;\n\t\tthis.#next = null;\n\t}\n\n\tget value() {\n\t\treturn this.#value;\n\t}\n\n\tget next() {\n\t\treturn this.#next;\n\t}\n\n\tget [Symbol.toStringTag]() {\n\t\treturn 'Node';\n\t}\n}", "/**\n *\n * @typedef {Map<*, *>} MultiMap\n * @extends Map\n */\nexport default class WeakSetMultiMap extends Map {\n\t/**\n\t * Adds a new element with a specified key and value to the MultiMap. If an element with the same key already exists, the value will be added to the underlying {@link Set}.\n\t *\n\t * @param {*} key The key to set.\n\t * @param {*} value The value to add to the MultiMap\n\t * @returns {MultiMap} The MultiMap with the updated key and value.\n\t */\n\tset(key, value) {\n\t\tsuper.set(key, (super.get(key) ?? new WeakSet()).add(value));\n\n\t\treturn this;\n\t}\n\n\t[Symbol.toStringTag]() {\n\t\treturn 'WeakSetMultiMap';\n\t}\n}", "export default class ContextEventHandler {\n\t#context;\n\t#eventHandler;\n\n\t/**\n\t *\n\t * @param {*} context The context to bind to the event handler.\n\t * @param {function(*): void} eventHandler The event handler to call when the event is published.\n\t */\n\tconstructor(context, eventHandler) {\n\t\tthis.#context = context;\n\t\tthis.#eventHandler = eventHandler;\n\t}\n\n\tget context() {\n\t\treturn this.#context;\n\t}\n\n\tget eventHandler() {\n\t\treturn this.#eventHandler;\n\t}\n\n\tget [Symbol.toStringTag]() {\n\t\treturn 'ContextEventHandler';\n\t}\n}", "export default class Subscription {\n\t#eventName;\n\t#contextEventHandler;\n\t#unsubscribe;\n\n\t/**\n\t *\n\t * @param {string} eventName\n\t * @param {import('./context-event-handler.js').default} contextEventHandler\n\t * @param {function(string, function(*): void): boolean} unsubscribe\n\t */\n\tconstructor(eventName, contextEventHandler, unsubscribe) {\n\t\tthis.#eventName = eventName;\n\t\tthis.#contextEventHandler = contextEventHandler;\n\t\tthis.#unsubscribe = unsubscribe;\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() {\n\t\treturn this.#eventName;\n\t}\n\n\t/**\n\t * Gets the context which will be bound to the event handler when it is called.\n\t *\n\t * @returns {*} The event handler context.\n\t */\n\tget context() {\n\t\treturn this.#contextEventHandler.context;\n\t}\n\n\t/**\n\t * Gets the event handler for the subscription.\n\t *\n\t * @returns {function(*): void} The event handler.\n\t */\n\tget eventHandler() {\n\t\treturn this.#contextEventHandler.eventHandler;\n\t}\n\n\t/**\n\t * Unsubscribes from the event.\n\t *\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() {\n\t\treturn this.#unsubscribe();\n\t}\n}", "import { MultiMap } from '@d1g1tal/collections';\nimport ContextEventHandler from './context-event-handler.js';\nimport Subscription from './subscription.js';\n\nexport default class Subscribr {\n\t/** @type {MultiMap<string, ContextEventHandler>} */\n\t#subscribers;\n\n\tconstructor() {\n\t\tthis.#subscribers = new MultiMap();\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 {function(*): void} eventHandler The event handler to call when the event is published.\n\t * @param {*} [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, eventHandler, context) {\n\t\tconst contextEventHandler = new ContextEventHandler(context, eventHandler);\n\t\tthis.#subscribers.set(eventName, contextEventHandler);\n\n\t\treturn new Subscription(eventName, contextEventHandler, () => this.#unsubscribe(eventName, contextEventHandler));\n\t}\n\n\t/**\n\t * Publish an event\n\t *\n\t * @param {string} eventName The name of the event.\n\t * @param {*} [data] The value to be passed to the event handler as a parameter.\n\t */\n\tpublish(eventName, data) {\n\t\tthis.#subscribers.get(eventName)?.forEach(({context, eventHandler}) => eventHandler.call(context, 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 * @param {string} subscription.eventName The name of the event to check.\n\t * @param {function(*)} subscription.eventHandler The event handler to check.\n\t * @returns {boolean} true if the event name and handler are subscribed, false otherwise.\n\t */\n\tisSubscribed({ eventName, eventHandler: handler}) {\n\t\treturn this.#subscribers.get(eventName)?.some(({ eventHandler }) => eventHandler === handler);\n\t}\n\n\tget [Symbol.toStringTag]() {\n\t\treturn 'Subscribr';\n\t}\n\n\t/**\n\t * Unsubscribe from the event\n\t *\n\t * @param {string} eventName The event name to subscribe to.\n\t * @param {ContextEventHandler} contextEventHandler The event handler to call when the event is published.\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\t#unsubscribe(eventName, contextEventHandler) {\n\t\tconst contextEventHandlers = this.#subscribers.get(eventName);\n\t\tconst removed = contextEventHandlers?.delete(contextEventHandler);\n\n\t\tif (removed && contextEventHandlers.size == 0) {\n\t\t\tthis.#subscribers.delete(eventName);\n\t\t}\n\n\t\treturn removed;\n\t}\n}"],
5
+ "mappings": "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",
6
+ "names": ["List", "#array", "iterable", "mapper", "context", "size", "element", "elements", "predicate", "index", "reducer", "initialValue", "comparator", "consumer", "fromIndex", "MultiMap", "key", "value", "List", "SetMultiMap", "key", "value", "Node", "#value", "#next", "value", "WeakSetMultiMap", "key", "value", "ContextEventHandler", "#context", "#eventHandler", "context", "eventHandler", "Subscription", "#eventName", "#contextEventHandler", "#unsubscribe", "eventName", "contextEventHandler", "unsubscribe", "Subscribr", "#subscribers", "MultiMap", "eventName", "eventHandler", "context", "contextEventHandler", "ContextEventHandler", "Subscription", "#unsubscribe", "data", "handler", "contextEventHandlers", "removed"]
7
+ }
package/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { default as ContextEventHandler } from "./src/context-event-handler.js";
2
+ export { default as Subscribr } from "./src/subscribr.js";
3
+ export { default as Subscription } from "./src/subscription.js";
package/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export {default as ContextEventHandler} from './src/context-event-handler.js';
2
+ export {default as Subscribr} from './src/subscribr.js';
3
+ export {default as Subscription} from './src/subscription.js';
package/package.json CHANGED
@@ -1,16 +1,30 @@
1
1
  {
2
2
  "name": "@d1g1tal/subscribr",
3
- "version": "1.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "JavaScript Publish/Subscribe Library",
5
5
  "type": "module",
6
- "main": "./src/subscribr.js",
7
- "module": "./src/subscribr.js",
8
- "publishConfig": {
6
+ "exports": {
7
+ ".": {
8
+ "import": "./src/subscribr.js",
9
+ "default": "./dist/browser/subscribr.min.js"
10
+ }
11
+ },
12
+ "types": "index.d.js",
13
+ "publishConfig": {
9
14
  "access": "public"
10
15
  },
16
+ "files": [
17
+ "/src",
18
+ "/dist",
19
+ "index.js",
20
+ "index.d.ts"
21
+ ],
11
22
  "scripts": {
12
- "build": "rimraf dist && esbuild src/subscribr.js --bundle --sourcemap --minify --target=es2022 --format=esm --outfile=dist/esm/subscribr.min.js && esbuild src/subscribr.js --bundle --sourcemap --minify --target=es2022 --platform=browser --global-name=Subscribr --outfile=dist/browser/subscribr.min.js",
13
- "test": "echo \"Error: no test specified\" && exit 1"
23
+ "build": "npm run build:esm && npm run build:browser",
24
+ "build:esm": "rimraf dist/esm && esbuild src/subscribr.js --bundle --target=es2022 --format=esm --outfile=dist/esm/subscribr.js && esbuild src/subscribr.js --bundle --sourcemap --minify --target=es2022 --format=esm --outfile=dist/esm/subscribr.min.js",
25
+ "build:browser": "rimraf dist/browser && esbuild src/subscribr.js --bundle --target=es2022 --platform=browser --global-name=Subscribr --footer:js='window.Subscribr = Subscribr.default;' --outfile=dist/browser/subscribr.js && esbuild src/subscribr.js --bundle --sourcemap --minify --target=es2022 --platform=browser --global-name=Subscribr --footer:js='window.Subscribr = Subscribr.default;' --outfile=dist/browser/subscribr.min.js",
26
+ "lint": "eslint --ext .js --fix --ignore-path .gitignore .",
27
+ "test": "node --no-warnings --experimental-vm-modules node_modules/jest/bin/jest.js"
14
28
  },
15
29
  "repository": {
16
30
  "type": "git",
@@ -28,8 +42,31 @@
28
42
  },
29
43
  "homepage": "https://github.com/D1g1talEntr0py/subscribr#readme",
30
44
  "devDependencies": {
31
- "esbuild": "^0.15.7",
32
- "eslint": "^8.23.1",
45
+ "@d1g1tal/chrysalis": "^1.1.7",
46
+ "@skypack/package-check": "^0.2.2",
47
+ "esbuild": "^0.15.11",
48
+ "eslint": "^8.25.0",
49
+ "eslint-plugin-compat": "^4.0.2",
50
+ "eslint-plugin-jsdoc": "^39.3.6",
51
+ "jest": "^29.2.0",
33
52
  "rimraf": "^3.0.2"
53
+ },
54
+ "jest": {
55
+ "verbose": true,
56
+ "transform": {},
57
+ "coverageDirectory": "./tests/coverage/",
58
+ "coveragePathIgnorePatterns": [
59
+ "/node_modules/"
60
+ ],
61
+ "collectCoverage": true,
62
+ "collectCoverageFrom": [
63
+ "src/**/*.js"
64
+ ]
65
+ },
66
+ "browserslist": [
67
+ "defaults"
68
+ ],
69
+ "dependencies": {
70
+ "@d1g1tal/collections": "^0.0.3"
34
71
  }
35
72
  }
@@ -0,0 +1,12 @@
1
+ export default class ContextEventHandler {
2
+ /**
3
+ *
4
+ * @param {*} context The context to bind to the event handler.
5
+ * @param {function(*): void} eventHandler The event handler to call when the event is published.
6
+ */
7
+ constructor(context: any, eventHandler: (arg0: any) => void);
8
+ get context(): any;
9
+ get eventHandler(): (arg0: any) => void;
10
+ get [Symbol.toStringTag](): string;
11
+ #private;
12
+ }
@@ -0,0 +1,26 @@
1
+ export default class ContextEventHandler {
2
+ #context;
3
+ #eventHandler;
4
+
5
+ /**
6
+ *
7
+ * @param {*} context The context to bind to the event handler.
8
+ * @param {function(*): void} eventHandler The event handler to call when the event is published.
9
+ */
10
+ constructor(context, eventHandler) {
11
+ this.#context = context;
12
+ this.#eventHandler = eventHandler;
13
+ }
14
+
15
+ get context() {
16
+ return this.#context;
17
+ }
18
+
19
+ get eventHandler() {
20
+ return this.#eventHandler;
21
+ }
22
+
23
+ get [Symbol.toStringTag]() {
24
+ return 'ContextEventHandler';
25
+ }
26
+ }
@@ -0,0 +1,30 @@
1
+ export default class Subscribr {
2
+ /**
3
+ * Subscribe to an event
4
+ *
5
+ * @param {string} eventName The event name to subscribe to.
6
+ * @param {function(*): void} eventHandler The event handler to call when the event is published.
7
+ * @param {*} [context] The context to bind to the event handler.
8
+ * @returns {Subscription} An object used to check if the subscription still exists and to unsubscribe from the event.
9
+ */
10
+ subscribe(eventName: string, eventHandler: (arg0: any) => void, context?: any): Subscription;
11
+ /**
12
+ * Publish an event
13
+ *
14
+ * @param {string} eventName The name of the event.
15
+ * @param {*} [data] The value to be passed to the event handler as a parameter.
16
+ */
17
+ publish(eventName: string, data?: any): void;
18
+ /**
19
+ * Check if the event and handler are subscribed.
20
+ *
21
+ * @param {Subscription} subscription The subscription object.
22
+ * @param {string} subscription.eventName The name of the event to check.
23
+ * @param {function(*)} subscription.eventHandler The event handler to check.
24
+ * @returns {boolean} true if the event name and handler are subscribed, false otherwise.
25
+ */
26
+ isSubscribed({ eventName, eventHandler: handler }: Subscription): boolean;
27
+ get [Symbol.toStringTag](): string;
28
+ #private;
29
+ }
30
+ import Subscription from "./subscription.js";
package/src/subscribr.js CHANGED
@@ -1,48 +1,71 @@
1
+ import { SetMultiMap } from '@d1g1tal/collections';
2
+ import ContextEventHandler from './context-event-handler.js';
3
+ import Subscription from './subscription.js';
4
+
1
5
  export default class Subscribr {
2
- /** @type {Map.<string, Array.<function(Event, Object):undefined>>} */
3
- #subscribers;
6
+ /** @type {SetMultiMap<string, ContextEventHandler>} */
7
+ #subscribers;
4
8
 
5
- constructor() {
6
- this.#subscribers = new Map();
7
- }
9
+ constructor() {
10
+ this.#subscribers = new SetMultiMap();
11
+ }
8
12
 
9
13
  /**
10
14
  * Subscribe to an event
11
15
  *
12
- * @param {string} eventType
13
- * @param {function(Event, Object):undefined} eventListener
14
- * @return {{unsubscribe: function()}}
16
+ * @param {string} eventName The event name to subscribe to.
17
+ * @param {function(*): 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.
15
20
  */
16
- subscribe(eventType, eventListener) {
17
- if (!this.#subscribers.has(eventType)) {
18
- this.#subscribers.set(eventType, []);
19
- }
21
+ subscribe(eventName, eventHandler, context) {
22
+ const contextEventHandler = new ContextEventHandler(context, eventHandler);
23
+ this.#subscribers.set(eventName, contextEventHandler);
20
24
 
21
- const subscribr = this;
22
- const index = this.#subscribers.get(eventType).push(eventListener) - 1;
23
-
24
- return {
25
- /**
26
- * Unsubscribe from the event
27
- */
28
- unsubscribe: () => subscribr.#subscribers.get(eventType).splice(index, 1)
29
- };
25
+ return new Subscription(eventName, contextEventHandler, () => this.#unsubscribe(eventName, contextEventHandler));
30
26
  }
31
27
 
32
28
  /**
33
29
  * Publish an event
34
30
  *
35
- * @param {string} eventType
36
- * @param {Event} [event=new CustomEvent(eventType)]
37
- * @param {Object} [data]
31
+ * @param {string} eventName The name of the event.
32
+ * @param {*} [data] The value to be passed to the event handler as a parameter.
33
+ */
34
+ publish(eventName, data) {
35
+ this.#subscribers.get(eventName)?.forEach(({context, eventHandler}) => eventHandler.call(context, data));
36
+ }
37
+
38
+ /**
39
+ * Check if the event and handler are subscribed.
40
+ *
41
+ * @param {Subscription} subscription The subscription object.
42
+ * @param {string} subscription.eventName The name of the event to check.
43
+ * @param {function(*)} subscription.eventHandler The event handler to check.
44
+ * @returns {boolean} true if the event name and handler are subscribed, false otherwise.
38
45
  */
39
- publish(eventType, event = new CustomEvent(eventType), data) {
40
- if (!this.#subscribers.has(eventType)) {
41
- return;
46
+ isSubscribed({ eventName, eventHandler: handler}) {
47
+ return Array.from(this.#subscribers.get(eventName))?.some(({ eventHandler }) => eventHandler === handler);
48
+ }
49
+
50
+ get [Symbol.toStringTag]() {
51
+ return 'Subscribr';
52
+ }
53
+
54
+ /**
55
+ * Unsubscribe from the event
56
+ *
57
+ * @param {string} eventName The event name to subscribe to.
58
+ * @param {ContextEventHandler} contextEventHandler The event handler to call when the event is published.
59
+ * @returns {boolean} true if eventListener has been removed successfully. false if the value is not found or if the value is not an object.
60
+ */
61
+ #unsubscribe(eventName, contextEventHandler) {
62
+ const contextEventHandlers = this.#subscribers.get(eventName);
63
+ const removed = contextEventHandlers?.delete(contextEventHandler);
64
+
65
+ if (removed && contextEventHandlers.size == 0) {
66
+ this.#subscribers.delete(eventName);
42
67
  }
43
68
 
44
- this.#subscribers.get(eventType).forEach(function(eventListener) {
45
- eventListener.call(this, event, data);
46
- });
69
+ return removed;
47
70
  }
48
71
  }
@@ -0,0 +1,34 @@
1
+ export default class Subscription {
2
+ /**
3
+ *
4
+ * @param {string} eventName
5
+ * @param {import('./context-event-handler.js').default} contextEventHandler
6
+ * @param {function(string, function(*): void): boolean} unsubscribe
7
+ */
8
+ constructor(eventName: string, contextEventHandler: import('./context-event-handler.js').default, unsubscribe: (arg0: string, arg1: (arg0: any) => void) => boolean);
9
+ /**
10
+ * Gets the event name for the subscription.
11
+ *
12
+ * @returns {string} The event name.
13
+ */
14
+ get eventName(): string;
15
+ /**
16
+ * Gets the context which will be bound to the event handler when it is called.
17
+ *
18
+ * @returns {*} The event handler context.
19
+ */
20
+ get context(): any;
21
+ /**
22
+ * Gets the event handler for the subscription.
23
+ *
24
+ * @returns {function(*): void} The event handler.
25
+ */
26
+ get eventHandler(): (arg0: any) => void;
27
+ /**
28
+ * Unsubscribes from the event.
29
+ *
30
+ * @returns {boolean} true if eventListener has been removed successfully. false if the value is not found or if the value is not an object.
31
+ */
32
+ unsubscribe(): boolean;
33
+ #private;
34
+ }
@@ -0,0 +1,53 @@
1
+ export default class Subscription {
2
+ #eventName;
3
+ #contextEventHandler;
4
+ #unsubscribe;
5
+
6
+ /**
7
+ *
8
+ * @param {string} eventName
9
+ * @param {import('./context-event-handler.js').default} contextEventHandler
10
+ * @param {function(string, function(*): void): boolean} unsubscribe
11
+ */
12
+ constructor(eventName, contextEventHandler, unsubscribe) {
13
+ this.#eventName = eventName;
14
+ this.#contextEventHandler = contextEventHandler;
15
+ this.#unsubscribe = unsubscribe;
16
+ }
17
+
18
+ /**
19
+ * Gets the event name for the subscription.
20
+ *
21
+ * @returns {string} The event name.
22
+ */
23
+ get eventName() {
24
+ return this.#eventName;
25
+ }
26
+
27
+ /**
28
+ * Gets the context which will be bound to the event handler when it is called.
29
+ *
30
+ * @returns {*} The event handler context.
31
+ */
32
+ get context() {
33
+ return this.#contextEventHandler.context;
34
+ }
35
+
36
+ /**
37
+ * Gets the event handler for the subscription.
38
+ *
39
+ * @returns {function(*): void} The event handler.
40
+ */
41
+ get eventHandler() {
42
+ return this.#contextEventHandler.eventHandler;
43
+ }
44
+
45
+ /**
46
+ * Unsubscribes from the event.
47
+ *
48
+ * @returns {boolean} true if eventListener has been removed successfully. false if the value is not found or if the value is not an object.
49
+ */
50
+ unsubscribe() {
51
+ return this.#unsubscribe();
52
+ }
53
+ }
package/.eslintrc.js DELETED
@@ -1,16 +0,0 @@
1
- export default {
2
- "env": {
3
- "browser": true,
4
- "es2021": true,
5
- "node": true
6
- },
7
- "extends": "eslint:recommended",
8
- "overrides": [
9
- ],
10
- "parserOptions": {
11
- "ecmaVersion": "latest",
12
- "sourceType": "module"
13
- },
14
- "rules": {
15
- }
16
- }
@@ -1,6 +0,0 @@
1
- {
2
- "cSpell.words": [
3
- "esbuild",
4
- "Subscribr"
5
- ]
6
- }
package/esbuild.js DELETED
File without changes
package/jsconfig.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "baseUrl": ".",
4
- "module": "es2020",
5
- "target": "es2020",
6
- "checkJs": true
7
- },
8
- "include": [ "./*", "src/**/*", "tests/*.js" ],
9
- "exclude": [ "node_modules", "dist" ]
10
- }