Skip to content

Commit 3c0c6d1

Browse files
Merge pull request #435 from laravel/null-channel-fix
`channel` is now immediately available
2 parents 61bbfa6 + 5750f66 commit 3c0c6d1

File tree

4 files changed

+26
-62
lines changed

4 files changed

+26
-62
lines changed

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

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { echo } from "../config";
44
import type {
55
Channel,
66
ChannelData,
7-
ChannelReturnType,
87
Connection,
98
ModelEvents,
109
ModelPayload,
@@ -51,7 +50,7 @@ const leaveChannel = (channel: Channel, leaveAll: boolean): void => {
5150

5251
const resolveChannelSubscription = <T extends BroadcastDriver>(
5352
channel: Channel,
54-
): Connection<T> | void => {
53+
): Connection<T> => {
5554
if (channels[channel.id]) {
5655
channels[channel.id].count += 1;
5756

@@ -60,12 +59,6 @@ const resolveChannelSubscription = <T extends BroadcastDriver>(
6059

6160
const channelSubscription = subscribeToChannel<T>(channel);
6261

63-
if (!channelSubscription) {
64-
// eslint-disable-next-line no-console
65-
console.warn(`Failed to subscribe to channel: ${channel.id}`);
66-
return;
67-
}
68-
6962
channels[channel.id] = {
7063
count: 1,
7164
connection: channelSubscription,
@@ -85,11 +78,6 @@ export const useEcho = <
8578
dependencies: any[] = [],
8679
visibility: TVisibility = "private" as TVisibility,
8780
) => {
88-
const callbackFunc = useCallback(callback, dependencies);
89-
const subscription = useRef<Connection<TDriver> | null>(null);
90-
const listening = useRef(false);
91-
92-
const events = toArray(event);
9381
const channel: Channel = {
9482
name: channelName,
9583
id: ["private", "presence"].includes(visibility)
@@ -98,13 +86,22 @@ export const useEcho = <
9886
visibility,
9987
};
10088

89+
const callbackFunc = useCallback(callback, dependencies);
90+
const listening = useRef(false);
91+
const initialized = useRef(false);
92+
const subscription = useRef<Connection<TDriver>>(
93+
resolveChannelSubscription<TDriver>(channel),
94+
);
95+
96+
const events = toArray(event);
97+
10198
const stopListening = useCallback(() => {
10299
if (!listening.current) {
103100
return;
104101
}
105102

106103
events.forEach((e) => {
107-
subscription.current!.stopListening(e, callbackFunc);
104+
subscription.current.stopListening(e, callbackFunc);
108105
});
109106

110107
listening.current = false;
@@ -116,7 +113,7 @@ export const useEcho = <
116113
}
117114

118115
events.forEach((e) => {
119-
subscription.current!.listen(e, callbackFunc);
116+
subscription.current.listen(e, callbackFunc);
120117
});
121118

122119
listening.current = true;
@@ -129,14 +126,11 @@ export const useEcho = <
129126
}, dependencies);
130127

131128
useEffect(() => {
132-
const channelSubscription =
133-
resolveChannelSubscription<TDriver>(channel);
134-
135-
if (!channelSubscription) {
136-
return;
129+
if (initialized.current) {
130+
subscription.current = resolveChannelSubscription<TDriver>(channel);
137131
}
138132

139-
subscription.current = channelSubscription;
133+
initialized.current = true;
140134

141135
listen();
142136

@@ -163,8 +157,7 @@ export const useEcho = <
163157
/**
164158
* Channel instance
165159
*/
166-
channel: () =>
167-
subscription.current as ChannelReturnType<TDriver, TVisibility>,
160+
channel: () => subscription.current,
168161
};
169162
};
170163

packages/react/src/types.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,6 @@ export type ModelPayload<T> = {
2828
afterCommit: boolean;
2929
};
3030

31-
export type ChannelReturnType<
32-
T extends BroadcastDriver,
33-
V extends Channel["visibility"],
34-
> = V extends "presence"
35-
? Broadcaster[T]["presence"]
36-
: V extends "private"
37-
? Broadcaster[T]["private"]
38-
: Broadcaster[T]["public"];
39-
4031
// eslint-disable-next-line @typescript-eslint/no-unused-vars
4132
export type ModelName<T extends string> = T extends `${infer _}.${infer U}`
4233
? ModelName<U>

packages/vue/src/composables/useEcho.ts

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { echo } from "../config";
44
import type {
55
Channel,
66
ChannelData,
7-
ChannelReturnType,
87
Connection,
98
ModelEvents,
109
ModelPayload,
@@ -15,7 +14,7 @@ const channels: Record<string, ChannelData<BroadcastDriver>> = {};
1514

1615
const resolveChannelSubscription = <T extends BroadcastDriver>(
1716
channel: Channel,
18-
): Connection<T> | null => {
17+
): Connection<T> => {
1918
if (channels[channel.id]) {
2019
channels[channel.id].count += 1;
2120

@@ -24,12 +23,6 @@ const resolveChannelSubscription = <T extends BroadcastDriver>(
2423

2524
const channelSubscription = subscribeToChannel<T>(channel);
2625

27-
if (!channelSubscription) {
28-
// eslint-disable-next-line no-console
29-
console.warn(`Failed to subscribe to channel: ${channel.id}`);
30-
return null;
31-
}
32-
3326
channels[channel.id] = {
3427
count: 1,
3528
connection: channelSubscription,
@@ -95,8 +88,6 @@ export const useEcho = <
9588
},
9689
);
9790

98-
let subscription: Connection<TDriver> | null = null;
99-
const events = Array.isArray(event) ? event : [event];
10091
const channel: Channel = {
10192
name: channelName,
10293
id: ["private", "presence"].includes(visibility)
@@ -105,13 +96,11 @@ export const useEcho = <
10596
visibility,
10697
};
10798

108-
const setupSubscription = () => {
109-
subscription = resolveChannelSubscription<TDriver>(channel);
110-
111-
if (!subscription) {
112-
return;
113-
}
99+
const subscription: Connection<TDriver> =
100+
resolveChannelSubscription<TDriver>(channel);
101+
const events = Array.isArray(event) ? event : [event];
114102

103+
const setupSubscription = () => {
115104
listen();
116105
};
117106

@@ -121,7 +110,7 @@ export const useEcho = <
121110
}
122111

123112
events.forEach((e) => {
124-
subscription!.listen(e, eventCallback.value);
113+
subscription.listen(e, eventCallback.value);
125114
});
126115

127116
listening.value = true;
@@ -133,7 +122,7 @@ export const useEcho = <
133122
}
134123

135124
events.forEach((e) => {
136-
subscription!.stopListening(e, eventCallback.value);
125+
subscription.stopListening(e, eventCallback.value);
137126
});
138127

139128
listening.value = false;
@@ -184,7 +173,7 @@ export const useEcho = <
184173
/**
185174
* Channel instance
186175
*/
187-
channel: () => subscription! as ChannelReturnType<TDriver, TVisibility>,
176+
channel: () => subscription,
188177
};
189178
};
190179

@@ -231,8 +220,8 @@ export const useEchoModel = <
231220
>(
232221
model: TModel,
233222
identifier: string | number,
234-
event: ModelEvents<TModel> | ModelEvents<TModel>[],
235-
callback: (payload: ModelPayload<TPayload>) => void,
223+
event: ModelEvents<TModel> | ModelEvents<TModel>[] = [],
224+
callback: (payload: ModelPayload<TPayload>) => void = () => {},
236225
dependencies: any[] = [],
237226
) => {
238227
return useEcho<ModelPayload<TPayload>, TDriver, "private">(

packages/vue/src/types.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,6 @@ export type ModelPayload<T> = {
2828
afterCommit: boolean;
2929
};
3030

31-
export type ChannelReturnType<
32-
T extends BroadcastDriver,
33-
V extends Channel["visibility"],
34-
> = V extends "presence"
35-
? Broadcaster[T]["presence"]
36-
: V extends "private"
37-
? Broadcaster[T]["private"]
38-
: Broadcaster[T]["public"];
39-
4031
// eslint-disable-next-line @typescript-eslint/no-unused-vars
4132
export type ModelName<T extends string> = T extends `${infer _}.${infer U}`
4233
? ModelName<U>

0 commit comments

Comments
 (0)