Skip to content

Commit

Permalink
refactor: align types to remove casting
Browse files Browse the repository at this point in the history
This was a coderabbit suggestion - to remove our instances of `as unknown as ChatClient`.

This was do-able by making sure that typescript only emits declarations for properties that aren't
marked as internal.
AndyTWF committed Nov 6, 2024
1 parent 5b16ff7 commit baed485
Showing 16 changed files with 60 additions and 73 deletions.
1 change: 1 addition & 0 deletions src/core/tsconfig.json
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
"noImplicitThis": true,
"esModuleInterop": true,
"declaration": true,
"stripInternal": true,
"moduleResolution": "Node",
"skipLibCheck": true,
"allowJs": true,
16 changes: 9 additions & 7 deletions src/react/hooks/use-chat-connection.ts
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ import { useEffect, useState } from 'react';

import { useEventListenerRef } from '../helper/use-event-listener-ref.js';
import { useChatClient } from './use-chat-client.js';
import { useLogger } from './use-logger.js';

/**
* The options for the {@link useChatConnection} hook.
@@ -44,7 +45,8 @@ export interface UseChatConnectionResponse {
*/
export const useChatConnection = (options?: UseChatConnectionOptions): UseChatConnectionResponse => {
const chatClient = useChatClient();
chatClient.logger.trace('useChatConnection();', options);
const logger = useLogger();
logger.trace('useChatConnection();', options);

// Initialize states with the current values from chatClient
const [currentStatus, setCurrentStatus] = useState<ConnectionStatus>(chatClient.connection.status);
@@ -63,30 +65,30 @@ export const useChatConnection = (options?: UseChatConnectionOptions): UseChatCo

// Apply the listener to the chatClient's connection status changes to keep the state update across re-renders
useEffect(() => {
chatClient.logger.debug('useChatConnection(); applying internal listener');
logger.debug('useChatConnection(); applying internal listener');
const { off } = chatClient.connection.onStatusChange((change: ConnectionStatusChange) => {
// Update states with new values
setCurrentStatus(change.current);
setError(change.error);
});
// Cleanup listener on un-mount
return () => {
chatClient.logger.debug('useChatConnection(); cleaning up listener');
logger.debug('useChatConnection(); cleaning up listener');
off();
};
}, [chatClient.connection, chatClient.logger]);
}, [chatClient.connection, logger]);

// Register the listener for the user-provided onStatusChange callback
useEffect(() => {
if (!onStatusChangeRef) return;
chatClient.logger.debug('useChatConnection(); applying client listener');
logger.debug('useChatConnection(); applying client listener');
const { off } = chatClient.connection.onStatusChange(onStatusChangeRef);

return () => {
chatClient.logger.debug('useChatConnection(); cleaning up client listener');
logger.debug('useChatConnection(); cleaning up client listener');
off();
};
}, [chatClient.connection, chatClient.logger, onStatusChangeRef]);
}, [chatClient.connection, logger, onStatusChangeRef]);

return {
currentStatus,
2 changes: 1 addition & 1 deletion src/react/hooks/use-logger.ts
Original file line number Diff line number Diff line change
@@ -12,5 +12,5 @@ import { useChatClient } from './use-chat-client.js';
*/
export const useLogger = (): Logger => {
const chatClient = useChatClient();
return useMemo(() => chatClient.logger, [chatClient]);
return useMemo(() => (chatClient as unknown as { logger: Logger }).logger, [chatClient]);
};
2 changes: 1 addition & 1 deletion src/react/providers/chat-client-provider.tsx
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@ export const ChatClientProvider = ({ children, client }: ChatClientProviderProps
const context = React.useContext(ChatClientContext);
const value: ChatClientContextValue = React.useMemo(() => {
// Set the internal useReact option to true to enable React-specific agent.
client.addReactAgent();
(client as unknown as { addReactAgent(): void }).addReactAgent();
return { ...context, [DEFAULT_CHAT_CLIENT_ID]: { client: client } };
}, [client, context]);

8 changes: 2 additions & 6 deletions test/react/helper/use-room-context.test.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { ChatClient, RoomOptionsDefaults } from '@ably/chat';
import { RoomOptionsDefaults } from '@ably/chat';
import { cleanup, render } from '@testing-library/react';
import { afterEach, describe, expect, it } from 'vitest';

import { useRoomContext } from '../../../src/react/helper/use-room-context.ts';
import { ChatRoomProvider } from '../../../src/react/index.ts';
import { ChatClientProvider } from '../../../src/react/providers/chat-client-provider.tsx';
import { newChatClient as newChatClientLib } from '../../helper/chat.ts';

function newChatClient() {
return newChatClientLib() as unknown as ChatClient;
}
import { newChatClient } from '../../helper/chat.ts';

describe('useRoom', () => {
afterEach(() => {
14 changes: 7 additions & 7 deletions test/react/hooks/use-chat-client.test.tsx
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ describe('useChatClient', () => {
});

it('should get the chat client from the context without error and with the correct agent', () => {
const chatClient = newChatClient() as unknown as ChatClient;
const chatClient = newChatClient();
const TestProvider = () => (
<ChatClientProvider client={chatClient}>
<TestComponent
@@ -63,7 +63,7 @@ describe('useChatClient', () => {
return <TestComponentInner />;
};

const chatClient = newChatClient() as unknown as ChatClient;
const chatClient = newChatClient();
render(
<ChatClientProvider client={chatClient}>
<TestComponentOuter />
@@ -77,8 +77,8 @@ describe('useChatClient', () => {
expect(client1).toEqual(client2);
});
it('should handle context updates correctly', () => {
const client1 = newChatClient() as unknown as ChatClient;
const client2 = newChatClient() as unknown as ChatClient;
const client1 = newChatClient();
const client2 = newChatClient();
const { rerender } = render(
<ChatClientProvider client={client1}>
<TestComponent
@@ -113,7 +113,7 @@ describe('useChatClient', () => {
return <TestComponentInner />;
};

const chatClient = newChatClient() as unknown as ChatClient;
const chatClient = newChatClient();
render(
<ChatClientProvider client={chatClient}>
<div>
@@ -145,8 +145,8 @@ describe('useChatClient', () => {
return <div />;
};

const chatClientInner = newChatClient() as unknown as ChatClient;
const chatClientOuter = newChatClient() as unknown as ChatClient;
const chatClientInner = newChatClient();
const chatClientOuter = newChatClient();

render(
<ChatClientProvider client={chatClientOuter}>
18 changes: 9 additions & 9 deletions test/react/hooks/use-messages.integration.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChatClient, Message, MessageListener, RoomOptionsDefaults, RoomStatus } from '@ably/chat';
import { Message, MessageListener, RoomOptionsDefaults, RoomStatus } from '@ably/chat';
import { cleanup, render, waitFor } from '@testing-library/react';
import React, { useEffect } from 'react';
import { afterEach, describe, expect, it, vi } from 'vitest';
@@ -31,8 +31,8 @@ describe('useMessages', () => {

it('should send messages correctly', async () => {
// create new clients
const chatClientOne = newChatClient() as unknown as ChatClient;
const chatClientTwo = newChatClient() as unknown as ChatClient;
const chatClientOne = newChatClient();
const chatClientTwo = newChatClient();

// create a second room and attach it, so we can listen for messages
const roomId = randomRoomId();
@@ -75,8 +75,8 @@ describe('useMessages', () => {

it('should receive messages on a subscribed listener', async () => {
// create new clients
const chatClientOne = newChatClient() as unknown as ChatClient;
const chatClientTwo = newChatClient() as unknown as ChatClient;
const chatClientOne = newChatClient();
const chatClientTwo = newChatClient();

// create a second room so we can send messages from it
const roomId = randomRoomId();
@@ -130,8 +130,8 @@ describe('useMessages', () => {

it('should receive previous messages for a subscribed listener', async () => {
// create new clients
const chatClientOne = newChatClient() as unknown as ChatClient;
const chatClientTwo = newChatClient() as unknown as ChatClient;
const chatClientOne = newChatClient();
const chatClientTwo = newChatClient();

// create a second room instance so we can send messages from it
const roomId = randomRoomId();
@@ -194,7 +194,7 @@ describe('useMessages', () => {
}, 10000);

it('should reset getPreviousMessages if the listener becomes undefined then redefined', async () => {
const chatClient = newChatClient() as unknown as ChatClient;
const chatClient = newChatClient();

// create a second room instance so we can send messages from it
const roomId = randomRoomId();
@@ -328,7 +328,7 @@ describe('useMessages', () => {
}, 20000);

it('should persist the getPreviousMessages subscription point across renders, if listener remains defined', async () => {
const chatClient = newChatClient() as unknown as ChatClient;
const chatClient = newChatClient();

// create a second room instance so we can send messages from it
const roomId = randomRoomId();
8 changes: 4 additions & 4 deletions test/react/hooks/use-occupancy.integration.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChatClient, OccupancyEvent, OccupancyListener, RoomOptionsDefaults } from '@ably/chat';
import { OccupancyEvent, OccupancyListener, RoomOptionsDefaults } from '@ably/chat';
import { cleanup, render } from '@testing-library/react';
import { dequal } from 'dequal';
import React from 'react';
@@ -18,9 +18,9 @@ describe('useOccupancy', () => {

it('should receive occupancy updates', { timeout: 20000 }, async () => {
// create new clients
const chatClient = newChatClient() as unknown as ChatClient;
const chatClientTwo = newChatClient() as unknown as ChatClient;
const chatClientThree = newChatClient() as unknown as ChatClient;
const chatClient = newChatClient();
const chatClientTwo = newChatClient();
const chatClientThree = newChatClient();

// create two more rooms and attach to contribute towards occupancy metrics
const roomId = randomRoomId();
13 changes: 3 additions & 10 deletions test/react/hooks/use-presence-listener.integration.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import {
ChatClient,
PresenceEvent,
PresenceListener,
PresenceMember,
RoomOptionsDefaults,
RoomStatus,
} from '@ably/chat';
import { PresenceEvent, PresenceListener, PresenceMember, RoomOptionsDefaults, RoomStatus } from '@ably/chat';
import { cleanup, render, waitFor } from '@testing-library/react';
import React, { useEffect } from 'react';
import { afterEach, describe, expect, it } from 'vitest';
@@ -38,8 +31,8 @@ describe('usePresenceListener', () => {

it('should correctly listen to presence events', async () => {
// create new clients
const chatClientOne = newChatClient() as unknown as ChatClient;
const chatClientTwo = newChatClient() as unknown as ChatClient;
const chatClientOne = newChatClient();
const chatClientTwo = newChatClient();

// create a second room and attach it, so we can send presence events with it
const roomId = randomRoomId();
6 changes: 3 additions & 3 deletions test/react/hooks/use-presence.integration.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChatClient, PresenceData, PresenceEvent, PresenceEvents, RoomOptionsDefaults } from '@ably/chat';
import { PresenceData, PresenceEvent, PresenceEvents, RoomOptionsDefaults } from '@ably/chat';
import { cleanup, render, waitFor } from '@testing-library/react';
import { useEffect } from 'react';
import { afterEach, describe, expect, it } from 'vitest';
@@ -43,8 +43,8 @@ describe('usePresence', () => {

it('should send presence events', async () => {
// create new clients
const chatClientOne = newChatClient() as unknown as ChatClient;
const chatClientTwo = newChatClient() as unknown as ChatClient;
const chatClientOne = newChatClient();
const chatClientTwo = newChatClient();

// create a second room and attach it, so we can listen for presence events
const roomId = randomRoomId();
10 changes: 5 additions & 5 deletions test/react/hooks/use-room-reactions.integration.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChatClient, Reaction, RoomOptionsDefaults, RoomReactionListener, RoomStatus } from '@ably/chat';
import { Reaction, RoomOptionsDefaults, RoomReactionListener, RoomStatus } from '@ably/chat';
import { cleanup, render, waitFor } from '@testing-library/react';
import React, { useEffect } from 'react';
import { afterEach, describe, expect, it } from 'vitest';
@@ -31,8 +31,8 @@ describe('useRoomReactions', () => {

it('should send a room reaction', async () => {
// create new clients
const chatClientOne = newChatClient() as unknown as ChatClient;
const chatClientTwo = newChatClient() as unknown as ChatClient;
const chatClientOne = newChatClient();
const chatClientTwo = newChatClient();

// create a second room and attach it, so we can receive reactions
const roomId = randomRoomId();
@@ -82,8 +82,8 @@ describe('useRoomReactions', () => {

it('should receive room reactions', async () => {
// create new clients
const chatClientOne = newChatClient() as unknown as ChatClient;
const chatClientTwo = newChatClient() as unknown as ChatClient;
const chatClientOne = newChatClient();
const chatClientTwo = newChatClient();

// create a second room and attach it, so we can send a reaction
const roomId = randomRoomId();
8 changes: 2 additions & 6 deletions test/react/hooks/use-room.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { ChatClient, RoomOptionsDefaults, RoomStatus, RoomStatusListener } from '@ably/chat';
import { RoomOptionsDefaults, RoomStatus, RoomStatusListener } from '@ably/chat';
import { act, cleanup, render, renderHook } from '@testing-library/react';
import * as Ably from 'ably';
import React from 'react';
import { afterEach, describe, expect, it, vi } from 'vitest';

import { ChatRoomProvider, useRoom, UseRoomResponse } from '../../../src/react/index.ts';
import { ChatClientProvider } from '../../../src/react/providers/chat-client-provider.tsx';
import { newChatClient as newChatClientLib } from '../../helper/chat.ts';
import { newChatClient } from '../../helper/chat.ts';
import { randomRoomId } from '../../helper/identifier.ts';

const TestComponent: React.FC<{ callback?: (room: UseRoomResponse) => void }> = ({ callback }) => {
@@ -17,10 +17,6 @@ const TestComponent: React.FC<{ callback?: (room: UseRoomResponse) => void }> =

vi.mock('ably');

function newChatClient() {
return newChatClientLib() as unknown as ChatClient;
}

describe('useRoom', () => {
afterEach(() => {
cleanup();
10 changes: 5 additions & 5 deletions test/react/hooks/use-typing.integration.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChatClient, RoomOptionsDefaults, RoomStatus, TypingEvent, TypingListener } from '@ably/chat';
import { RoomOptionsDefaults, RoomStatus, TypingEvent, TypingListener } from '@ably/chat';
import { cleanup, render } from '@testing-library/react';
import React, { useEffect } from 'react';
import { afterEach, describe, expect, it } from 'vitest';
@@ -31,8 +31,8 @@ describe('useTyping', () => {

it('should send typing events', async () => {
// create new clients
const chatClientOne = newChatClient() as unknown as ChatClient;
const chatClientTwo = newChatClient() as unknown as ChatClient;
const chatClientOne = newChatClient();
const chatClientTwo = newChatClient();

// create a second room and attach it, so we can listen for typing events
const roomId = randomRoomId();
@@ -78,8 +78,8 @@ describe('useTyping', () => {
}, 10000);
it('should subscribe and correctly listen for typing events', async () => {
// create new clients
const chatClientOne = newChatClient() as unknown as ChatClient;
const chatClientTwo = newChatClient() as unknown as ChatClient;
const chatClientOne = newChatClient();
const chatClientTwo = newChatClient();

// create a second room and attach it, so we can send typing events
const roomId = randomRoomId();
3 changes: 1 addition & 2 deletions test/react/providers/chat-client-provider.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ChatClient } from '@ably/chat';
import { cleanup, render } from '@testing-library/react';
import React from 'react';
import { afterEach, describe, it, vi } from 'vitest';
@@ -14,7 +13,7 @@ describe('useChatClient', () => {
});

it('should create a provider without error', () => {
const chatClient = newChatClient() as unknown as ChatClient;
const chatClient = newChatClient();
const TestComponent = () => {
return <div />;
};
4 changes: 2 additions & 2 deletions test/react/providers/chat-room-provider.integration.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChatClient, RoomOptionsDefaults, RoomStatus } from '@ably/chat';
import { RoomOptionsDefaults, RoomStatus } from '@ably/chat';
import { cleanup, configure, render } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

@@ -19,7 +19,7 @@ describe('ChatRoomProvider', () => {

// This check ensures that a chat room is valid when being used in strict mode
it('should attach the room in strict mode', async () => {
const chatClient = newChatClient() as unknown as ChatClient;
const chatClient = newChatClient();
const TestComponent = () => {
return <div />;
};
10 changes: 5 additions & 5 deletions test/react/providers/room-provider.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChatClient, RoomOptionsDefaults } from '@ably/chat';
import { RoomOptionsDefaults } from '@ably/chat';
import { cleanup, render } from '@testing-library/react';
import React from 'react';
import { afterEach, describe, expect, it, vi } from 'vitest';
@@ -17,7 +17,7 @@ describe('ChatRoomProvider', () => {
});

it('should create a provider without error', async () => {
const chatClient = newChatClient() as unknown as ChatClient;
const chatClient = newChatClient();
let roomResolved = false;
const TestComponent = () => {
const { room } = useRoom();
@@ -54,7 +54,7 @@ describe('ChatRoomProvider', () => {
});

it('should correctly release rooms', async () => {
const chatClient = newChatClient() as unknown as ChatClient;
const chatClient = newChatClient();
const TestComponent = () => {
return <div />;
};
@@ -90,7 +90,7 @@ describe('ChatRoomProvider', () => {
});

it('should attach and detach correctly', async () => {
const chatClient = newChatClient() as unknown as ChatClient;
const chatClient = newChatClient();
const TestComponent = () => {
return <div />;
};
@@ -134,7 +134,7 @@ describe('ChatRoomProvider', () => {
});

it('should not attach, detach, or release when not configured to do so', async () => {
const chatClient = newChatClient() as unknown as ChatClient;
const chatClient = newChatClient();
const TestComponent = () => {
return <div />;
};

0 comments on commit baed485

Please sign in to comment.