1.0.3 • Published 7 months ago

@isreeks/chat-sdk v1.0.3

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

@isreeks/socket-chat-sdk

A Socket.io-based chat SDK designed for Next.js 14 applications, providing real-time chat functionality with server-side API integration for room management. This package includes client-side hooks and a context provider for managing chat rooms and messages, along with server-side utilities for secure API calls.

Table of Contents

Features

  • Real-time chat functionality using Socket.io.
  • Client-side hooks (useSocket, useChatRoom) for managing rooms and messages.
  • Server-side API client for secure room management (create, join, add participants).
  • TypeScript support with type definitions.
  • Integration with Next.js 14 App Router.

Installation

Install the package via npm:

npm install @isreeks/socket-chat-sdk

Peer Dependencies

Ensure the following peer dependencies are installed in your project:

  • next@^14.0.0
  • react@^18.2.0
  • socket.io-client@^4.7.0

Additional Dependencies

  • react-hot-toast@^2.4.1 (included as a dependency for notifications)

Usage

Client-Side Setup

Wrap your application with SocketProvider in your root layout or _app file to enable chat functionality.

Example: app/layout.tsx

"use client";

import { SocketProvider } from '@isreeks/socket-chat-sdk';
import { Toaster } from 'react-hot-toast';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  // Replace with your actual authentication logic
  const authToken = { userId: 'your-user-id', token: 'your-auth-token' };

  return (
    <html lang="en">
      <body>
        <SocketProvider
          socketUrl={process.env.NEXT_PUBLIC_SOCKET_URL!}
          authToken={authToken}
        >
          <Toaster />
          {children}
        </SocketProvider>
      </body>
    </html>
  );
}

Example Component: components/ChatRoom.tsx

"use client";

import { useSocket, useChatRoom } from '@isreeks/socket-chat-sdk';
import { useEffect, useState } from 'react';

export default function ChatRoom({ roomId, userId }) {
  const { createRoom, addParticipants, rooms } = useSocket();
  const [selectedRoomId, setSelectedRoomId] = useState(roomId);
  const { messages, joinRoom, sendMessage, setTyping } = useChatRoom(selectedRoomId);

  useEffect(() => {
    if (roomId) joinRoom(roomId);
  }, [roomId, joinRoom]);

  const handleCreateRoom = async () => {
    const newRoom = await createRoom('New Room', [userId, 'anotherUserId']);
    joinRoom(newRoom._id);
    setSelectedRoomId(newRoom._id);
  };

  const handleSend = (content) => {
    sendMessage(content, undefined, userId);
  };

  return (
    <div>
      <button onClick={handleCreateRoom}>Create Room</button>
      <ul>
        {rooms.map((room) => (
          <li key={room._id} onClick={() => joinRoom(room._id)}>
            {room.name}
          </li>
        ))}
      </ul>
      <div>
        {messages.map((msg) => (
          <p key={msg._id}>{msg.content}</p>
        ))}
      </div>
      <input onChange={() => setTyping(true, userId, 'username')} />
      <button onClick={() => handleSend('Hello!')}>Send</button>
    </div>
  );
}

Server-Side Setup

Create an API route to proxy client requests to your hosted room management API securely.

Example: app/api/rooms/[[...slug]]/route.ts

import { NextRequest, NextResponse } from 'next/server';
import { RoomsApiClient } from '@isreeks/socket-chat-sdk/server';
import { Room } from '@isreeks/socket-chat-sdk/types';

const apiClient = new RoomsApiClient(process.env.API_URL!, process.env.API_KEY!);

export async function POST(request: NextRequest, { params }: { params: { slug: string[] } }) {
  const authToken = request.headers.get('authorization')?.split('Bearer ')[1];
  if (!authToken) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });

  const slug = params.slug || [];
  const url = `/api/rooms/${slug.join('/')}`;

  try {
    if (url === '/api/rooms') {
      const { name, participants } = await request.json();
      const room = await apiClient.createRoom({ name, participants });
      return NextResponse.json(room, { status: 201 });
    }
    if (url.match(/\/api\/rooms\/[^/]+\/participants/)) {
      const roomId = slug[0];
      const { participants } = await request.json();
      const room = await apiClient.addParticipants(roomId, participants);
      return NextResponse.json(room);
    }
    return NextResponse.json({ error: 'Method not allowed' }, { status: 405 });
  } catch (error) {
    return NextResponse.json({ error: (error as Error).message || 'Internal server error' }, { status: 500 });
  }
}

export async function GET(request: NextRequest, { params }: { params: { slug: string[] } }) {
  const authToken = request.headers.get('authorization')?.split('Bearer ')[1];
  if (!authToken) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });

  const slug = params.slug || [];
  const url = `/api/rooms/${slug.join('/')}`;

  try {
    if (url.match(/\/api/rooms\/user\/[^/]+/)) {
      const userId = slug[2];
      const rooms = await apiClient.getUserRooms(userId);
      return NextResponse.json(rooms);
    }
    if (url.match(/\/api/rooms\/[^/]+/)) {
      const roomId = slug[0];
      const room = await apiClient.getRoom(roomId);
      return NextResponse.json(room);
    }
    return NextResponse.json({ error: 'Not found' }, { status: 404 });
  } catch (error) {
    return NextResponse.json({ error: (error as Error).message || 'Internal server error' }, { status: 500 });
  }
}

Configuration

Add the following environment variables to your .env.local file:

NEXT_PUBLIC_SOCKET_URL=https://your-socket-server.com
API_URL=https://your-api-server.com
API_KEY=your-secret-api-key
  • NEXT_PUBLIC_SOCKET_URL: The public URL of your Socket.io server.
  • API_URL: The base URL of your hosted room management API (kept secret on the server).
  • API_KEY: The secret API key for authenticating API requests (kept secret on the server).

API Reference

Client-Side API

SocketProvider

Props:

  • socketUrl (string): URL of the Socket.io server.
  • authToken (object): Authentication token (e.g., { userId: string, token?: string }).

Usage: Wraps your app to provide chat context.

useSocket

Returns: Object with:

  • createRoom(name: string, participants: string[]): Promise<Room>
  • addParticipants(roomId: string, participants: string[]): Promise<Room>
  • getRoom(roomId: string): Promise<Room>
  • getUserRooms(userId: string): Promise<Room[]>
  • rooms: Room[]

useChatRoom(roomId: string)

Returns: Object with:

  • messages: Message[]
  • joinRoom(roomId: string): void
  • sendMessage(content: string, replyToId?: string, userId?: string): void
  • setTyping(isTyping: boolean, userId: string, username: string): void

Server-Side API

RoomsApiClient

Constructor: new RoomsApiClient(baseUrl: string, apiKey: string)

Methods:

  • createRoom({ name, participants }): Promise<Room>
  • addParticipants(roomId: string, participants: string[]): Promise<Room>
  • getRoom(roomId: string): Promise<Room>
  • getUserRooms(userId: string): Promise<Room[]>

Contributing

  1. Fork the repository.
  2. Create a new branch: git checkout -b feature-name
  3. Make your changes and commit: git commit -m "Add feature-name"
  4. Push to the branch: git push origin feature-name
  5. Submit a pull request.

Development

  • Install dependencies: npm install
  • Build the package: npm run build
  • Test locally: Use npm link in the package directory, then npm link @isreeks/socket-chat-sdk in your Next.js app.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Notes

  • Customization: Adjust the examples to match your authentication system (e.g., NextAuth.js) and styling preferences.
  • Documentation: Add more details to the API reference or include a changelog if you plan multiple releases.
1.0.3

7 months ago

1.0.2

7 months ago

1.0.1

8 months ago

1.0.0

8 months ago