@vanillaspa/event-bus 1.0.0 → 1.1.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/eventbusWorker.js +31 -0
- package/index.js +51 -39
- package/package.json +1 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const listeners = new Map();
|
|
2
|
+
|
|
3
|
+
onconnect = function ({ ports }) {
|
|
4
|
+
const port = ports[0];
|
|
5
|
+
|
|
6
|
+
port.onmessage = ({ data }) => {
|
|
7
|
+
const { action, type, detail } = data;
|
|
8
|
+
switch (action) {
|
|
9
|
+
case 'addEventListener':
|
|
10
|
+
if (!listeners.has(type)) listeners.set(type, new Set());
|
|
11
|
+
listeners.get(type).add(port);
|
|
12
|
+
break;
|
|
13
|
+
case 'removeEventListener':
|
|
14
|
+
listeners.get(type)?.delete(port);
|
|
15
|
+
break;
|
|
16
|
+
case 'dispatchEvent':
|
|
17
|
+
listeners.get(type)?.forEach(p => {
|
|
18
|
+
if (p !== port) p.postMessage({ type, detail });
|
|
19
|
+
});
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
port.onmessageerror = () => {
|
|
25
|
+
for (const ports of listeners.values()) {
|
|
26
|
+
ports.delete(port);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
port.start();
|
|
31
|
+
}
|
package/index.js
CHANGED
|
@@ -1,54 +1,66 @@
|
|
|
1
|
-
export const name = "eventbus";
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
export const name = "eventbus";
|
|
2
|
+
const worker = new SharedWorker(new URL('./eventbusWorker.js', import.meta.url), { type: 'module' });
|
|
3
|
+
worker.port.start();
|
|
4
|
+
|
|
5
|
+
const contextListeners = new WeakMap(); // WeakMap to store listeners per object. Keep it private unless you know what you do.
|
|
6
|
+
|
|
7
|
+
worker.port.onmessage = ({ data }) => {
|
|
8
|
+
const { type, detail } = data;
|
|
9
|
+
dispatchEvent(new CustomEvent(type, { detail }));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
worker.port.onmessageerror = (e) => {
|
|
13
|
+
console.error('eventbus deserialization error:', e);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function addEventListener(type, listener, context = undefined) {
|
|
6
17
|
if (context && typeof context === 'object') { // context is well defined, should be a WebComponent
|
|
7
|
-
if (!
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
const contextListeners = listeners.get(context);
|
|
11
|
-
if (!contextListeners.has(type)) { // type is not yet registered
|
|
12
|
-
contextListeners.set(type, []);
|
|
13
|
-
} // next push the handler to the WeakMap for the given context
|
|
14
|
-
contextListeners.get(type).push(listener);
|
|
15
|
-
} else { // default
|
|
16
|
-
if (context) { // illegal context
|
|
17
|
-
throw new Error("Syntax error.");
|
|
18
|
+
if (!contextListeners.has(context)) { // context is yet unknown to the listeners
|
|
19
|
+
contextListeners.set(context, new Map()); // will be stored here
|
|
18
20
|
}
|
|
21
|
+
const byType = contextListeners.get(context);
|
|
22
|
+
if (!byType.has(type)) byType.set(type, []);
|
|
23
|
+
byType.get(type).push(listener);
|
|
24
|
+
} else {
|
|
25
|
+
if (context) throw new Error("Syntax error: context must be an object.");
|
|
19
26
|
window.addEventListener(type, listener);
|
|
20
27
|
}
|
|
28
|
+
|
|
29
|
+
worker.port.postMessage({ action: 'addEventListener', type });
|
|
21
30
|
}
|
|
22
31
|
|
|
23
|
-
export function removeEventListener(type, listener, context = undefined) {
|
|
32
|
+
export function removeEventListener(type, listener, context = undefined, options) {
|
|
24
33
|
if (context && typeof context === 'object') {
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
const byType = contextListeners.get(context);
|
|
35
|
+
if (!byType?.has(type)) return;
|
|
36
|
+
|
|
37
|
+
const handlers = byType.get(type)
|
|
38
|
+
const index = handlers.indexOf(listener);
|
|
39
|
+
if (index > -1) handlers.splice(index, 1);
|
|
40
|
+
if (handlers.length === 0) {
|
|
41
|
+
byType.delete(type);
|
|
42
|
+
worker.port.postMessage({ action: 'removeEventListener', type });
|
|
32
43
|
}
|
|
33
|
-
} else {
|
|
34
|
-
window.removeEventListener(type);
|
|
44
|
+
} else {
|
|
45
|
+
window.removeEventListener(type, listener);
|
|
46
|
+
worker.port.postMessage({ ction: 'removeEventListener', type });
|
|
35
47
|
}
|
|
36
48
|
}
|
|
37
49
|
|
|
38
|
-
export function dispatchEvent(event
|
|
50
|
+
export function dispatchEvent(event) {
|
|
39
51
|
if (!context) {
|
|
40
|
-
if (event instanceof CustomEvent)
|
|
41
|
-
|
|
42
|
-
} else {
|
|
43
|
-
context = event.target;
|
|
44
|
-
}
|
|
52
|
+
if (event instanceof CustomEvent) context = event.detail?.target;
|
|
53
|
+
else context = event.target;
|
|
45
54
|
}
|
|
46
|
-
if (context &&
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
if (context && contextListeners.has(context)) {
|
|
56
|
+
const byType = contextListeners.get(context);
|
|
57
|
+
byType.get(event.type)?.forEach(handler => handler(event));
|
|
58
|
+
} else {
|
|
59
|
+
if (typeof window !== 'undefined') window.dispatchEvent(event);
|
|
60
|
+
worker.port.postMessage({
|
|
61
|
+
action: 'dispatchEvent',
|
|
62
|
+
type: event.type,
|
|
63
|
+
detail: event instanceof CustomEvent ? event.detail : {}
|
|
64
|
+
});
|
|
53
65
|
}
|
|
54
66
|
}
|
package/package.json
CHANGED