Skip to content

Commit 002dc5a

Browse files
committed
Add composable onSocketEvent()
This will subscribe to a socket.io event before the component is mounted and will unsubscribe before the component is unmounted. Usage: setup() { onSocketEvent('my-event', (data) => { ... }) }
1 parent 3d71cc3 commit 002dc5a

File tree

6 files changed

+64
-21
lines changed

6 files changed

+64
-21
lines changed

src/__tests__/composables.spec.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { mount } from '@vue/test-utils';
2+
import { useSocket, onSocketEvent } from '../composables';
3+
import Main from '../plugin';
4+
import io from '../__mocks__/socket.io-client';
5+
6+
it('useSocket() injects $socket', () => {
7+
let injectedSocketExtension;
8+
const wrapper = mount({
9+
render: () => null,
10+
setup() {
11+
injectedSocketExtension = useSocket();
12+
},
13+
}, { global: { plugins: [[Main, io('ws://localhost')]] } });
14+
expect(injectedSocketExtension).toBe(wrapper.vm.$socket);
15+
});
16+
17+
describe('onSocketEvent()', () => {
18+
it('subscribes to the event', () => {
19+
const spy = jest.fn();
20+
const socket = io('ws://localhost');
21+
mount({
22+
render: () => null,
23+
setup() {
24+
onSocketEvent('event', spy);
25+
},
26+
}, { global: { plugins: [[Main, socket]] } });
27+
socket.fireServerEvent('event', 'data');
28+
expect(spy).toHaveBeenCalledWith('data');
29+
});
30+
31+
it('unsubscribes before unmounted', () => {
32+
const spy = jest.fn();
33+
const socket = io('ws://localhost');
34+
const wrapper = mount({
35+
render: () => null,
36+
setup() {
37+
onSocketEvent('event', spy);
38+
},
39+
}, { global: { plugins: [[Main, socket]] } });
40+
wrapper.unmount();
41+
socket.fireServerEvent('event', 'data');
42+
expect(spy).not.toHaveBeenCalled();
43+
});
44+
});

src/__tests__/plugin.spec.js

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { mount } from '@vue/test-utils';
22
import { createApp, inject } from 'vue';
33
import { SocketExtensionKey } from '..';
4-
import Main, { useSocket } from '../plugin';
4+
import Main from '../plugin';
55
import io from '../__mocks__/socket.io-client';
66

77
it('should be vue plugin (is an object with `install` method)', () => {
@@ -108,17 +108,6 @@ describe('.install()', () => {
108108
}, { global: { plugins: [[Main, io('ws://localhost')]] } });
109109
expect(injectedSocketExtension).toBe(wrapper.vm.$socket);
110110
});
111-
112-
it('provides a useSocket() helper function to inject $socket', () => {
113-
let injectedSocketExtension;
114-
const wrapper = mount({
115-
render: () => null,
116-
setup() {
117-
injectedSocketExtension = useSocket();
118-
},
119-
}, { global: { plugins: [[Main, io('ws://localhost')]] } });
120-
expect(injectedSocketExtension).toBe(wrapper.vm.$socket);
121-
});
122111
});
123112

124113
describe('.defaults', () => {

src/composables.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// eslint-disable-next-line import/no-extraneous-dependencies
2+
import { inject, onBeforeMount, onBeforeUnmount } from 'vue';
3+
4+
const SocketExtensionKey = Symbol('$socket');
5+
6+
const useSocket = () => inject(SocketExtensionKey);
7+
8+
function onSocketEvent(event, callback) {
9+
const socket = useSocket();
10+
onBeforeMount(() => socket.$subscribe(event, callback));
11+
onBeforeUnmount(() => socket.$unsubscribe(event));
12+
}
13+
14+
export { SocketExtensionKey, useSocket, onSocketEvent };

src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import plugin, { useSocket, SocketExtensionKey } from './plugin';
1+
import plugin from './plugin';
2+
import { useSocket, SocketExtensionKey } from './composables';
23

34
export default plugin;
45
export { useSocket, SocketExtensionKey };

src/plugin.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// eslint-disable-next-line import/no-extraneous-dependencies
2-
import { ref, inject } from 'vue';
2+
import { ref } from 'vue';
33
import Observe from './Observe';
44
import GlobalEmitter from './GlobalEmitter';
55
import createMixin from './createMixin';
66
import { isSocketIo } from './utils';
77
import defaults from './defaults';
8+
import { SocketExtensionKey } from './composables';
89

910
/**
1011
* @param {Vue} app
@@ -53,8 +54,6 @@ function defineSocketIoClient(socket, obj) {
5354
});
5455
}
5556

56-
const SocketExtensionKey = Symbol('$socket');
57-
5857
function install(app, socket, options) {
5958
if (!isSocketIo(socket)) {
6059
throw new Error('[vue-socket.io-ext] you have to pass `socket.io-client` instance to the plugin');
@@ -72,8 +71,4 @@ function install(app, socket, options) {
7271
app.provide(SocketExtensionKey, $socket);
7372
}
7473

75-
const useSocket = () => inject(SocketExtensionKey);
76-
7774
export default { defaults, install };
78-
79-
export { useSocket, SocketExtensionKey };

types/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ export interface SocketExtension {
3434

3535
export declare const SocketExtensionKey: InjectionKey<SocketExtension>
3636
export declare const useSocket: () => SocketExtension
37-
37+
export declare const onSocketEvent: (event: string, fn: Function) => void

0 commit comments

Comments
 (0)