Skip to content

Commit b9fb575

Browse files
authored
Merge branch 'laravel:2.x' into 2.x
2 parents a099e99 + fb3253e commit b9fb575

File tree

14 files changed

+843
-13
lines changed

14 files changed

+843
-13
lines changed

CHANGELOG.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
# Release Notes
22

3-
## [Unreleased](https://github.com/laravel/echo/compare/v2.1.4...2.x)
3+
## [Unreleased](https://github.com/laravel/echo/compare/v2.1.6...2.x)
4+
5+
## [v2.1.6](https://github.com/laravel/echo/compare/v2.1.5...v2.1.6) - 2025-06-17
6+
7+
* Fix subscriptions not being restored on reconnect by [@electron93](https://github.com/electron93) in https://github.com/laravel/echo/pull/446
8+
9+
## [v2.1.5](https://github.com/laravel/echo/compare/v2.1.4...v2.1.5) - 2025-06-03
10+
11+
### What's Changed
12+
13+
* Revert CSRF logic by [@joetannenbaum](https://github.com/joetannenbaum) in https://github.com/laravel/echo/pull/442
14+
* Added useEchoNotification hook by [@joetannenbaum](https://github.com/joetannenbaum) in https://github.com/laravel/echo/pull/443
15+
16+
**Full Changelog**: https://github.com/laravel/echo/compare/v2.1.4...v2.1.5
417

518
## [v2.1.4](https://github.com/laravel/echo/compare/v2.1.3...v2.1.4) - 2025-05-15
619

packages/laravel-echo/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "laravel-echo",
3-
"version": "2.1.4",
3+
"version": "2.1.6",
44
"description": "Laravel Echo library for beautiful Pusher and Socket.IO integration",
55
"keywords": [
66
"laravel",

packages/laravel-echo/src/connector/connector.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,26 @@ export abstract class Connector<
9090
* Extract the CSRF token from the page.
9191
*/
9292
protected csrfToken(): null | string {
93-
return (
94-
window?.Laravel?.csrfToken ??
95-
this.options.csrfToken ??
96-
document
97-
?.querySelector('meta[name="csrf-token"]')
98-
?.getAttribute("content") ??
99-
null
100-
);
93+
if (typeof window !== "undefined" && window.Laravel?.csrfToken) {
94+
return window.Laravel.csrfToken;
95+
}
96+
97+
if (this.options.csrfToken) {
98+
return this.options.csrfToken;
99+
}
100+
101+
if (
102+
typeof document !== "undefined" &&
103+
typeof document.querySelector === "function"
104+
) {
105+
return (
106+
document
107+
.querySelector('meta[name="csrf-token"]')
108+
?.getAttribute("content") ?? null
109+
);
110+
}
111+
112+
return null;
101113
}
102114

103115
/**

packages/laravel-echo/src/connector/socketio-connector.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class SocketIoConnector extends Connector<
4646
this.options as Partial<ManagerOptions & SocketOptions>,
4747
);
4848

49-
this.socket.on("reconnect", () => {
49+
this.socket.io.on("reconnect", () => {
5050
Object.values(this.channels).forEach((channel) => {
5151
channel.subscribe();
5252
});

packages/react/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@laravel/echo-react",
3-
"version": "2.1.4",
3+
"version": "2.1.6",
44
"description": "React hooks for seamless integration with Laravel Echo.",
55
"keywords": [
66
"laravel",

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

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { type BroadcastDriver } from "laravel-echo";
22
import { useCallback, useEffect, useRef } from "react";
33
import { echo } from "../config";
44
import type {
5+
BroadcastNotification,
56
Channel,
67
ChannelData,
78
ChannelReturnType,
@@ -167,6 +168,91 @@ export const useEcho = <
167168
};
168169
};
169170

171+
export const useEchoNotification = <
172+
TPayload,
173+
TDriver extends BroadcastDriver = BroadcastDriver,
174+
>(
175+
channelName: string,
176+
callback: (payload: BroadcastNotification<TPayload>) => void = () => {},
177+
event: string | string[] = [],
178+
dependencies: any[] = [],
179+
) => {
180+
const result = useEcho<BroadcastNotification<TPayload>, TDriver, "private">(
181+
channelName,
182+
[],
183+
callback,
184+
dependencies,
185+
"private",
186+
);
187+
188+
const events = useRef(
189+
toArray(event)
190+
.map((e) => {
191+
if (e.includes(".")) {
192+
return [e, e.replace(/\./g, "\\")];
193+
}
194+
195+
return [e, e.replace(/\\/g, ".")];
196+
})
197+
.flat(),
198+
);
199+
const listening = useRef(false);
200+
const initialized = useRef(false);
201+
202+
const cb = useCallback(
203+
(notification: BroadcastNotification<TPayload>) => {
204+
if (!listening.current) {
205+
return;
206+
}
207+
208+
if (
209+
events.current.length === 0 ||
210+
events.current.includes(notification.type)
211+
) {
212+
callback(notification);
213+
}
214+
},
215+
dependencies.concat(events.current).concat([callback]),
216+
);
217+
218+
const listen = useCallback(() => {
219+
if (listening.current) {
220+
return;
221+
}
222+
223+
if (!initialized.current) {
224+
result.channel().notification(cb);
225+
}
226+
227+
listening.current = true;
228+
initialized.current = true;
229+
}, [cb]);
230+
231+
const stopListening = useCallback(() => {
232+
if (!listening.current) {
233+
return;
234+
}
235+
236+
listening.current = false;
237+
}, [cb]);
238+
239+
useEffect(() => {
240+
listen();
241+
}, dependencies.concat(events.current));
242+
243+
return {
244+
...result,
245+
/**
246+
* Stop listening for notification events
247+
*/
248+
stopListening,
249+
/**
250+
* Listen for notification events
251+
*/
252+
listen,
253+
};
254+
};
255+
170256
export const useEchoPresence = <
171257
TPayload,
172258
TDriver extends BroadcastDriver = BroadcastDriver,

packages/react/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export { configureEcho, echo } from "./config/index";
22
export {
33
useEcho,
44
useEchoModel,
5+
useEchoNotification,
56
useEchoPresence,
67
useEchoPublic,
78
} from "./hooks/use-echo";

packages/react/src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ export type Channel = {
1616
visibility: "private" | "public" | "presence";
1717
};
1818

19+
export type BroadcastNotification<TPayload> = TPayload & {
20+
id: string;
21+
type: string;
22+
};
23+
1924
export type ChannelReturnType<
2025
T extends BroadcastDriver,
2126
V extends Channel["visibility"],

0 commit comments

Comments
 (0)