@autoafleveren/ui 1.8.4 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/icons.cjs +1 -1
- package/dist/icons.js +146 -146
- package/dist/types/composables/useEcho/index.d.ts +15 -16
- package/dist/ui.cjs +21 -21
- package/dist/ui.js +346 -335
- package/package.json +1 -1
- package/src/modules/composables/useEcho/index.ts +108 -62
package/package.json
CHANGED
|
@@ -6,6 +6,9 @@ import mitt from 'mitt';
|
|
|
6
6
|
|
|
7
7
|
import type { Authorizer, Channel } from 'pusher-js';
|
|
8
8
|
|
|
9
|
+
type EventHandler<T = any> = (data: T) => unknown;
|
|
10
|
+
type WrappedEventHandler<T = any> = (data: T) => Promise<void>;
|
|
11
|
+
|
|
9
12
|
interface Listener {
|
|
10
13
|
name: string;
|
|
11
14
|
isListening: boolean;
|
|
@@ -16,31 +19,48 @@ interface Caster {
|
|
|
16
19
|
joining: (callback: CallableFunction) => this;
|
|
17
20
|
whisper: (eventName: string, data: Record<any, any>) => this;
|
|
18
21
|
leaving: (callback: CallableFunction) => this;
|
|
22
|
+
listenForWhisper?: (event: string, callback: CallableFunction) => void;
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
const state = {
|
|
22
26
|
listeners: ref<Listener[]>([]),
|
|
27
|
+
|
|
23
28
|
echo: null as Echo<'pusher'> | null,
|
|
24
|
-
|
|
25
|
-
authorizer: null as ((channel: Channel) => Authorizer) | null,
|
|
29
|
+
|
|
26
30
|
emitter: mitt(),
|
|
27
|
-
|
|
31
|
+
|
|
32
|
+
casters: {} as Record<string, Caster>,
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Tracks which Echo listeners are already registered.
|
|
36
|
+
*/
|
|
37
|
+
subscriptions: new Set<string>(),
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Maps original handler -> wrapped handler.
|
|
41
|
+
*/
|
|
42
|
+
wrappedHandlers: new WeakMap<EventHandler, WrappedEventHandler>(),
|
|
28
43
|
};
|
|
29
44
|
|
|
30
|
-
export function getOrCreateListener(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
45
|
+
export function getOrCreateListener(listenerName = 'unique'): Listener {
|
|
46
|
+
let listener = state.listeners.value.find(stateListener => stateListener.name === listenerName);
|
|
47
|
+
|
|
48
|
+
if (!listener) {
|
|
49
|
+
listener = {
|
|
50
|
+
name: listenerName,
|
|
51
|
+
isListening: false,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
state.listeners.value.push(listener);
|
|
37
55
|
}
|
|
38
56
|
|
|
39
|
-
|
|
40
|
-
return state.listeners.value.find(listener => listener.name === listerName);
|
|
57
|
+
return listener;
|
|
41
58
|
}
|
|
42
59
|
|
|
43
|
-
export function registerEcho(
|
|
60
|
+
export function registerEcho(
|
|
61
|
+
key: string,
|
|
62
|
+
authorizer: (channel: Channel) => Authorizer,
|
|
63
|
+
): void {
|
|
44
64
|
state.echo = new Echo({
|
|
45
65
|
broadcaster: 'pusher',
|
|
46
66
|
client: ConnectionManager,
|
|
@@ -54,41 +74,52 @@ export function registerEcho(key: string, authorizer: (channel: Channel) => Auth
|
|
|
54
74
|
}
|
|
55
75
|
|
|
56
76
|
export function useEcho(listenerName: string | null = null) {
|
|
57
|
-
const listener
|
|
77
|
+
const listener = getOrCreateListener(listenerName ?? undefined);
|
|
58
78
|
|
|
59
79
|
function join(channel: string): Caster {
|
|
60
|
-
if (state.echo
|
|
80
|
+
if (!state.echo) {
|
|
61
81
|
throw new Error('Echo is not initialized');
|
|
62
82
|
}
|
|
63
83
|
|
|
64
|
-
state.casters[channel]
|
|
84
|
+
if (!state.casters[channel]) {
|
|
85
|
+
state.casters[channel] = state.echo.join(channel) as Caster;
|
|
86
|
+
}
|
|
65
87
|
|
|
66
|
-
return state.casters[channel]
|
|
88
|
+
return state.casters[channel];
|
|
67
89
|
}
|
|
68
90
|
|
|
69
|
-
function
|
|
70
|
-
if (state.echo
|
|
91
|
+
function leave(channel: string): void {
|
|
92
|
+
if (!state.echo) {
|
|
71
93
|
throw new Error('Echo is not initialized');
|
|
72
94
|
}
|
|
73
95
|
|
|
96
|
+
state.echo.leave(channel);
|
|
97
|
+
delete state.casters[channel];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function whisper<T = unknown>(
|
|
101
|
+
event: string,
|
|
102
|
+
data: T,
|
|
103
|
+
channel?: string,
|
|
104
|
+
): void {
|
|
74
105
|
const channelName = channel ?? Object.keys(state.casters)[0];
|
|
75
106
|
|
|
76
107
|
try {
|
|
77
|
-
state.casters[channelName]?.whisper?.(event, data);
|
|
108
|
+
state.casters[channelName]?.whisper?.(event, data as any);
|
|
78
109
|
} catch {
|
|
79
110
|
//
|
|
80
111
|
}
|
|
81
112
|
}
|
|
82
113
|
|
|
83
|
-
function listen<T = unknown>(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
114
|
+
function listen<T = unknown>(
|
|
115
|
+
event: string,
|
|
116
|
+
callback: (data: T) => void,
|
|
117
|
+
channel?: string,
|
|
118
|
+
): void {
|
|
88
119
|
const channelName = channel ?? Object.keys(state.casters)[0];
|
|
89
120
|
|
|
90
121
|
if (typeof state.casters[channelName]?.listenForWhisper === 'function') {
|
|
91
|
-
state.casters[channelName]
|
|
122
|
+
state.casters[channelName].listenForWhisper?.(event, callback);
|
|
92
123
|
|
|
93
124
|
return;
|
|
94
125
|
}
|
|
@@ -96,64 +127,79 @@ export function useEcho(listenerName: string | null = null) {
|
|
|
96
127
|
throw new Error(`Nothing to whisper to on this channel ${event}-${channelName}`);
|
|
97
128
|
}
|
|
98
129
|
|
|
99
|
-
function
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
function on(channel: string, event: string, handler: (data: any) => unknown, privateChannel = true, unique = false): void {
|
|
110
|
-
if (state.echo === null) {
|
|
130
|
+
function on(
|
|
131
|
+
channel: string,
|
|
132
|
+
event: string,
|
|
133
|
+
handler: EventHandler,
|
|
134
|
+
privateChannel = true,
|
|
135
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/naming-convention
|
|
136
|
+
_unique = false,
|
|
137
|
+
): void {
|
|
138
|
+
if (!state.echo) {
|
|
111
139
|
throw new Error('Echo is not initialized');
|
|
112
140
|
}
|
|
113
141
|
|
|
114
|
-
const
|
|
115
|
-
const isSubscribed = state.emitter.all.has(channelEventKey);
|
|
142
|
+
const key = `${channel}.${event}`;
|
|
116
143
|
|
|
117
|
-
|
|
118
|
-
listener.isListening = true;
|
|
119
|
-
}
|
|
144
|
+
listener.isListening = true;
|
|
120
145
|
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
}
|
|
146
|
+
if (!state.subscriptions.has(key)) {
|
|
147
|
+
state.subscriptions.add(key);
|
|
124
148
|
|
|
125
|
-
|
|
126
|
-
const channelConnection = privateChannel
|
|
149
|
+
const connection = privateChannel
|
|
127
150
|
? state.echo.private(channel)
|
|
128
151
|
: state.echo.channel(channel);
|
|
129
152
|
|
|
130
|
-
|
|
131
|
-
state.emitter.emit(
|
|
153
|
+
connection.listen(`.${event}`, (data: any) => {
|
|
154
|
+
state.emitter.emit(key, data);
|
|
132
155
|
});
|
|
133
156
|
}
|
|
134
157
|
|
|
135
|
-
|
|
136
|
-
const closeOnCompletion = await handler(data) ?? false;
|
|
158
|
+
const wrappedHandler: WrappedEventHandler = async (data): Promise<void> => {
|
|
159
|
+
const closeOnCompletion = (await handler(data)) ?? false;
|
|
137
160
|
|
|
138
|
-
|
|
139
|
-
listener.isListening = false;
|
|
140
|
-
}
|
|
161
|
+
listener.isListening = false;
|
|
141
162
|
|
|
142
163
|
if (closeOnCompletion) {
|
|
143
|
-
off(channel, event);
|
|
164
|
+
off(channel, event, handler);
|
|
144
165
|
}
|
|
145
|
-
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
state.wrappedHandlers.set(handler, wrappedHandler);
|
|
169
|
+
state.emitter.on(key, wrappedHandler);
|
|
146
170
|
}
|
|
147
171
|
|
|
148
|
-
function off(
|
|
149
|
-
|
|
172
|
+
function off(
|
|
173
|
+
channel: string,
|
|
174
|
+
event: string,
|
|
175
|
+
handler?: EventHandler,
|
|
176
|
+
): void {
|
|
177
|
+
if (!state.echo) {
|
|
150
178
|
throw new Error('Echo is not initialized');
|
|
151
179
|
}
|
|
152
180
|
|
|
153
|
-
|
|
154
|
-
state.emitter.all.delete(`${channel}.${event}`);
|
|
181
|
+
const key = `${channel}.${event}`;
|
|
155
182
|
|
|
156
|
-
|
|
183
|
+
if (handler) {
|
|
184
|
+
const wrapped = state.wrappedHandlers.get(handler);
|
|
185
|
+
|
|
186
|
+
if (wrapped) {
|
|
187
|
+
state.emitter.off(key, wrapped as any);
|
|
188
|
+
state.wrappedHandlers.delete(handler);
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
state.emitter.off(key);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const remainingHandlers = state.emitter.all.get(key);
|
|
195
|
+
|
|
196
|
+
if (!remainingHandlers || remainingHandlers.length === 0) {
|
|
197
|
+
state.subscriptions.delete(key);
|
|
198
|
+
|
|
199
|
+
state.emitter.all.delete(key);
|
|
200
|
+
|
|
201
|
+
state.echo.leave(channel);
|
|
202
|
+
}
|
|
157
203
|
|
|
158
204
|
listener.isListening = false;
|
|
159
205
|
}
|