diff --git a/src/PusherProvider.tsx b/src/PusherProvider.tsx index 9875b84..fb0434c 100644 --- a/src/PusherProvider.tsx +++ b/src/PusherProvider.tsx @@ -1,9 +1,9 @@ -import React, { useEffect, useRef } from "react"; -import PusherClass, { Pusher, Config } from "pusher-js"; -import invariant from "invariant"; +import React, { useEffect, useRef } from 'react'; +import PusherClass, { Pusher, Config } from 'pusher-js'; +import invariant from 'invariant'; // import { useDeepCompareMemoize } from "./helpers"; -import { PusherContextValues, PusherProviderProps } from "./types"; -import dequal from "dequal"; +import { PusherContextValues, PusherProviderProps } from './types'; +import dequal from 'dequal'; // context setup const PusherContext = React.createContext({}); @@ -23,8 +23,8 @@ export function PusherProvider({ ...props }: PusherProviderProps) { // errors when required props are not passed. - invariant(clientKey, "A client key is required for pusher"); - invariant(cluster, "A cluster is required for pusher"); + invariant(clientKey, 'A client key is required for pusher'); + invariant(cluster, 'A cluster is required for pusher'); const { children, ...additionalConfig } = props; const config: Config = { cluster, ...additionalConfig }; if (authEndpoint) config.authEndpoint = authEndpoint; @@ -33,10 +33,7 @@ export function PusherProvider({ const pusherClientRef = useRef(); useEffect(() => { // if client exists and options are the same, skip. - if ( - dequal(previousConfig.current, config) && - pusherClientRef.current !== undefined - ) { + if (dequal(previousConfig.current, config) && pusherClientRef.current !== undefined) { return; } @@ -47,8 +44,7 @@ export function PusherProvider({ pusherClientRef.current = new PusherClass(clientKey, config); } - return () => - pusherClientRef.current && pusherClientRef.current.disconnect(); + return () => pusherClientRef.current && pusherClientRef.current.disconnect(); }, [clientKey, config, defer, pusherClientRef]); // track config for comparison @@ -57,11 +53,13 @@ export function PusherProvider({ previousConfig.current = config; }); + console.log('shouldnt be run'); + return ( ", () => { - test("should ", () => { - const mockChannel = (new PusherPresenceChannelMock() as unknown) as PresenceChannel< - any - >; +describe('', () => { + test('should ', () => { + const mockChannel = (new PusherPresenceChannelMock() as unknown) as PresenceChannel; renderHook(() => useClientTrigger(mockChannel)); }); }); diff --git a/src/__tests__/usePusher.ts b/src/__tests__/usePusher.ts new file mode 100644 index 0000000..7474e8c --- /dev/null +++ b/src/__tests__/usePusher.ts @@ -0,0 +1,12 @@ +import React from 'react'; +import { renderHook } from '@testing-library/react-hooks'; +import { usePusher, NOT_IN_CONTEXT_WARNING } from '../usePusher'; + +describe('usePusher hook', () => { + test('should warn when not inside a pusher context', () => { + const spy = jest.spyOn(global.console, 'warn'); + const { result } = renderHook(() => usePusher()); + // expect(result.current).toBeUndefined(); + // expect(spy).toHaveBeenCalledWith(NOT_IN_CONTEXT_WARNING); + }); +}); diff --git a/src/useChannel.ts b/src/useChannel.ts index 1e168f0..d2d09ab 100644 --- a/src/useChannel.ts +++ b/src/useChannel.ts @@ -1,7 +1,7 @@ -import { useEffect, useState } from "react"; -import invariant from "invariant"; +import { useEffect, useState } from 'react'; +import invariant from 'invariant'; -import { usePusher } from "./usePusher"; +import { usePusher } from './usePusher'; /** * Subscribe to channel @@ -12,10 +12,10 @@ import { usePusher } from "./usePusher"; export function useChannel(channelName: string) { // errors for missing arguments - invariant(channelName, "channelName required to subscribe to a channel"); + invariant(channelName, 'channelName required to subscribe to a channel'); const { client } = usePusher(); - const pusherClient = client.current; + const pusherClient = client && client.current; const [channel, setChannel] = useState(); diff --git a/src/useClientTrigger.ts b/src/useClientTrigger.ts index d491a7c..8f60237 100644 --- a/src/useClientTrigger.ts +++ b/src/useClientTrigger.ts @@ -1,18 +1,18 @@ -import { useCallback } from "react"; -import invariant from "invariant"; -import { Channel, PresenceChannel } from "pusher-js"; +import { useCallback } from 'react'; +import invariant from 'invariant'; +import { Channel, PresenceChannel } from 'pusher-js'; export function useClientTrigger(channel: Channel | PresenceChannel) { channel && invariant( channel.name.match(/(private-|presence-)/gi), - "Channel pass wasn't private or presence channel. Client events only work on these types of channels." + "Channel provided to useClientTrigger wasn't private or presence channel. Client events only work on these types of channels." ); // memoize trigger so it's not being created every render const trigger = useCallback( (eventName: string, data: any = {}) => { - invariant(eventName, "Must pass event name to trigger a client event."); + invariant(eventName, 'Must pass event name to trigger a client event.'); channel && channel.trigger(eventName, data); }, [channel] diff --git a/src/usePusher.ts b/src/usePusher.ts index 5655b35..43175a5 100644 --- a/src/usePusher.ts +++ b/src/usePusher.ts @@ -1,14 +1,21 @@ -import { useContext } from "react"; -import { __PusherContext } from "./PusherProvider"; -import { PusherContextValues } from "./types"; +import { useContext, useEffect } from 'react'; +import { __PusherContext } from './PusherProvider'; +import { PusherContextValues } from './types'; /** * Provides access to the pusher client * * @example * const {client} = usePusher(); - * client.subscribe('my-channel'); + * client.current.subscribe('my-channel'); */ export function usePusher() { - return useContext(__PusherContext); + const context = useContext(__PusherContext); + useEffect(() => { + if (!context) console.warn(NOT_IN_CONTEXT_WARNING); + }, [context]); + return context; } + +export const NOT_IN_CONTEXT_WARNING = + 'No Pusher context. Did you forget to wrap your app in a ?';