Skip to content

Commit 67ffc12

Browse files
Merge pull request #427 from laravel/listen-to-all
Added listen to `*`, stronger typing
2 parents 7c98015 + 5df2ec6 commit 67ffc12

File tree

7 files changed

+370
-143
lines changed

7 files changed

+370
-143
lines changed

.vscode/tasks.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
{
55
"type": "npm",
66
"script": "build",
7-
"path": "packages/react",
7+
"path": ".",
88
"group": {
99
"kind": "build",
1010
"isDefault": true
1111
},
1212
"problemMatcher": [],
13-
"label": "npm: build - packages/react",
13+
"label": "pnpm: build all packages",
1414
"detail": "vite build && FORMAT=iife vite build"
1515
}
1616
]

packages/react/src/hooks/use-echo.ts

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,36 @@ export const useEcho = <
7878
TPayload,
7979
TDriver extends BroadcastDriver = BroadcastDriver,
8080
TVisibility extends Channel["visibility"] = "private",
81+
TEvent extends string = string,
8182
>(
8283
channelName: string,
83-
event: string | string[],
84-
callback: (payload: TPayload) => void,
84+
event: TEvent | TEvent[],
85+
callback: (payload: TPayload, eventName: TEvent) => void,
8586
dependencies: any[] = [],
8687
visibility: TVisibility = "private" as TVisibility,
8788
) => {
88-
const callbackFunc = useCallback(callback, dependencies);
89+
const events = toArray(event);
90+
const callbacks = useRef<
91+
Record<TEvent, (payload: TPayload, eventName: TEvent) => void>
92+
>(
93+
events.reduce(
94+
(acc, e) => {
95+
acc[e] = (payload: TPayload) => callback(payload, e);
96+
return acc;
97+
},
98+
{} as Record<
99+
TEvent,
100+
(payload: TPayload, eventName: TEvent) => void
101+
>,
102+
),
103+
);
104+
const allCallbackFunc = useCallback(
105+
(eventName: TEvent, payload: TPayload) => callback(payload, eventName),
106+
dependencies,
107+
);
89108
const subscription = useRef<Connection<TDriver> | null>(null);
90109
const listening = useRef(false);
91110

92-
const events = toArray(event);
93111
const channel: Channel = {
94112
name: channelName,
95113
id: ["private", "presence"].includes(visibility)
@@ -104,7 +122,11 @@ export const useEcho = <
104122
}
105123

106124
events.forEach((e) => {
107-
subscription.current!.stopListening(e, callbackFunc);
125+
if (e !== "*") {
126+
subscription.current!.stopListening(e, callbacks.current[e]);
127+
} else if ("stopListeningToAll" in subscription.current!) {
128+
subscription.current.stopListeningToAll(allCallbackFunc);
129+
}
108130
});
109131

110132
listening.current = false;
@@ -116,7 +138,16 @@ export const useEcho = <
116138
}
117139

118140
events.forEach((e) => {
119-
subscription.current!.listen(e, callbackFunc);
141+
if (e !== "*") {
142+
subscription.current!.listen(e, callbacks.current[e]);
143+
} else if ("listenToAll" in subscription.current!) {
144+
subscription.current.listenToAll(allCallbackFunc);
145+
} else {
146+
// eslint-disable-next-line no-console
147+
console.warn(
148+
"listenToAll is not supported for this channel type",
149+
);
150+
}
120151
});
121152

122153
listening.current = true;
@@ -171,13 +202,14 @@ export const useEcho = <
171202
export const useEchoPresence = <
172203
TPayload,
173204
TDriver extends BroadcastDriver = BroadcastDriver,
205+
TEvent extends string = string,
174206
>(
175207
channelName: string,
176-
event: string | string[],
177-
callback: (payload: TPayload) => void,
208+
event: TEvent | TEvent[],
209+
callback: (payload: TPayload, eventName: TEvent) => void,
178210
dependencies: any[] = [],
179211
) => {
180-
return useEcho<TPayload, TDriver, "presence">(
212+
return useEcho<TPayload, TDriver, "presence", TEvent>(
181213
channelName,
182214
event,
183215
callback,
@@ -189,13 +221,14 @@ export const useEchoPresence = <
189221
export const useEchoPublic = <
190222
TPayload,
191223
TDriver extends BroadcastDriver = BroadcastDriver,
224+
TEvent extends string = string,
192225
>(
193226
channelName: string,
194-
event: string | string[],
195-
callback: (payload: TPayload) => void,
227+
event: TEvent | TEvent[],
228+
callback: (payload: TPayload, eventName: TEvent) => void,
196229
dependencies: any[] = [],
197230
) => {
198-
return useEcho<TPayload, TDriver, "public">(
231+
return useEcho<TPayload, TDriver, "public", TEvent>(
199232
channelName,
200233
event,
201234
callback,
@@ -208,16 +241,19 @@ export const useEchoModel = <
208241
TPayload,
209242
TModel extends string,
210243
TDriver extends BroadcastDriver = BroadcastDriver,
244+
TEvent extends ModelEvents<TModel> = ModelEvents<TModel>,
211245
>(
212246
model: TModel,
213247
identifier: string | number,
214-
event: ModelEvents<TModel> | ModelEvents<TModel>[],
215-
callback: (payload: ModelPayload<TPayload>) => void,
248+
event: TEvent | TEvent[],
249+
callback: (payload: ModelPayload<TPayload>, eventName: TEvent) => void,
216250
dependencies: any[] = [],
217251
) => {
218-
return useEcho<ModelPayload<TPayload>, TDriver, "private">(
252+
return useEcho<ModelPayload<TPayload>, TDriver, "private", TEvent>(
219253
`${model}.${identifier}`,
220-
toArray(event).map((e) => (e.startsWith(".") ? e : `.${e}`)),
254+
toArray(event).map((e) =>
255+
e.startsWith(".") ? e : `.${e}`,
256+
) as TEvent[],
221257
callback,
222258
dependencies,
223259
"private",

packages/react/src/types.ts

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ export type ConfigDefaults<O extends BroadcastDriver> = Record<
2323

2424
export type ModelPayload<T> = {
2525
model: T;
26+
connection: string | null;
27+
queue: string | null;
28+
afterCommit: boolean;
2629
};
2730

2831
export type ChannelReturnType<
@@ -40,18 +43,18 @@ export type ModelName<T extends string> = T extends `${infer _}.${infer U}`
4043
: T;
4144

4245
export type ModelEvents<T extends string> =
43-
| `${ModelName<T>}Retrieved`
44-
| `${ModelName<T>}Creating`
45-
| `${ModelName<T>}Created`
46-
| `${ModelName<T>}Updating`
47-
| `${ModelName<T>}Updated`
48-
| `${ModelName<T>}Saving`
49-
| `${ModelName<T>}Saved`
50-
| `${ModelName<T>}Deleting`
51-
| `${ModelName<T>}Deleted`
52-
| `${ModelName<T>}Trashed`
53-
| `${ModelName<T>}ForceDeleting`
54-
| `${ModelName<T>}ForceDeleted`
55-
| `${ModelName<T>}Restoring`
56-
| `${ModelName<T>}Restored`
57-
| `${ModelName<T>}Replicating`;
46+
| `.${ModelName<T>}Retrieved`
47+
| `.${ModelName<T>}Creating`
48+
| `.${ModelName<T>}Created`
49+
| `.${ModelName<T>}Updating`
50+
| `.${ModelName<T>}Updated`
51+
| `.${ModelName<T>}Saving`
52+
| `.${ModelName<T>}Saved`
53+
| `.${ModelName<T>}Deleting`
54+
| `.${ModelName<T>}Deleted`
55+
| `.${ModelName<T>}Trashed`
56+
| `.${ModelName<T>}ForceDeleting`
57+
| `.${ModelName<T>}ForceDeleted`
58+
| `.${ModelName<T>}Restoring`
59+
| `.${ModelName<T>}Restored`
60+
| `.${ModelName<T>}Replicating`;

0 commit comments

Comments
 (0)