npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rocket-io

v1.1.0

Published

Wrapper for socket.io-client in ReactJs - works for React Native

Downloads

114

Readme

rocket-io

Wrapper for socket.io-client in ReactJs - works for React Native.

This package is using lbundle as bundler ✨

Install

NPM registry

# npm
npm i socket.io-client rocket-io

# yarn
yarn add socket.io-client rocket-io

# bun
bun install socket.io-client rocket-io

# pnpm
pnpm i socket.io-client rocket-io

JSR registry

# deno
deno add @mrii/rocket-io

# jsr
npx jsr add @mrii/rocket-io

Usage

Initialization

Call the createSocketHooks to get an instance of the hooks with the socket:

socket.io-hooks.ts

import { io } from 'socket.io-client';
import { createSocketHooks } from 'rocket-io';

const socketInstance = io(/* ... */);

// exports the hooks
export const {
  socket,
  useDisconnectOnUnmount,
  useSocket,
  useOn,
  useOnce,
  useEmit,
  useImmediateEmit,
  useEmitEffect,
} = createSocketHooks(socketInstance);

Alternative without io

you can pass io arguments to createSocketHooks and it will create the socket internally:

socket.io-hooks.ts

export const {
  /* ... */
} = createSocketHooks(url, options);

// or with only options
export const {
  /* ... */
} = createSocketHooks(options);

Alternative without initial socket - Lazy Initialization

you can delay the creating of the socket if you need information from the react tree, use useInitSocket to initialize it:

socket.io-hooks.ts

export const {
  useInitSocket,
  /* ... */
} = createSocketHooks();

Later on in the App

app.tsx

/* ... */

const App: React.FC = () => {
  /* ... */

  useInitSocket('<url>', { auth: { token } });

  // if the token isn't ready, or you don't want to initialize the socket yet, pass the `ready` arg

  useInitSocket('<url>', { auth: { token } }, isReady);

  /* ... */
};

Using the hooks

component.tsx

/* ... */

export const Component: React.FC = () => {
  /* ... */

  useOn('event', data => {
    console.log('[event] fired with: ', data);
  });

  useImmediateEmit('event-2', 'event-2 fired immediately');

  const emit = useEmit();
  /* ... */

  return <button onClick={() => emit('event', 'event data')}>emit event</button>;
};

TypeScript Support

You can pass your events map to createSocketHooks to provide you with safe listeners and emission events:

socket.io-hooks.ts

export type EmitEvents = {
  send_message: (message: string) => void;
};

export type ListenEvents = {
  message: (message: string) => void;
};

export const {
  /* ... */
} = createSocketHooks<EmitEvents, ListenEvents>();

component.tsx

/* ... */

export const Component: React.FC = () => {
  /* ... */

  useOn(
    /* typed! */
    'message',

    /* data type is provided! */
    data => {
      console.log('[message] fired with: ', data);
    }
  );

  useImmediateEmit(
    /* typed! */
    'send_message',

    /* emit arguments type is provided! */
    'message'
  );
};

Examples

Eager Initialization - casual applications

create and export the hooks:

socket.io-hooks.ts

import { createSocketHooks } from 'rocket-io';

// exports the hooks
export const {
  socket,
  useDisconnectOnUnmount,
  useSocket,
  useOn,
  useOnce,
  useEmit,
  useImmediateEmit,
  useEmitEffect,
} = createSocketHooks('<url>', {
  /* options */
});

disconnect on application unmount:

app.tsx

/* ... */

const App: React.FC = () => {
  /* ... */

  useDisconnectOnUnmount();

  /* ... */
};

use the hooks:

component.tsx

/* ... */

export const Component: React.FC = () => {
  /* ... */

  // listen to event
  useOn('event', data => {
    console.log('[event] fired with: ', data);
  });

  // listen to event once
  useOn('ready', () => {
    console.log('[ready] event fired');
  });

  // emit event when `Component` mounts
  useImmediateEmit('event-2', 'event-2 fired immediately');

  // emit event when dependencies array changes - similar to `useEffect(, deps)`
  useEmitEffect([message], 'event-3', 'event-3 fired with new message: ' + message);

  // get emit function
  const emit = useEmit();

  /* ... */

  return <button onClick={() => emit('event', 'event data')}>emit event</button>;
};

Lazy Initialization - authorized sockets

create and export the hooks:

socket.io-hooks.ts

import { createSocketHooks } from 'rocket-io';

// exports the hooks
export const {
  useInitSocket,
  useDisconnectOnUnmount,
  useSocket,
  useOn,
  useOnce,
  useEmit,
  useImmediateEmit,
  useEmitEffect,
} = createSocketHooks();

initialize the socket once args is ready:

app.tsx

/* ... */

const App: React.FC = () => {
  /* ... */

  useInitSocket('<url>', { auth: { token } }, typeof token === 'string');

  useDisconnectOnUnmount();

  /* ... */
};

and then use the hooks normally

Multiple Sockets

you can create two socket hooks by calling createSocketHooks:

admin-socket-hooks.ts

import { createSocketHooks } from 'rocket-io';

export const adminSocketHooks = createSocketHooks('<admin-url>', {
  /* admin options */
});

products-socket-hooks.ts

import { createSocketHooks } from 'rocket-io';

export const productsSocketHooks = createSocketHooks('<products-url>', {
  /* products options */
});

API

socket

the socket in case you initialized it using createSocketHooks.

type Socket<TListenEvents, TEmitEvents>.

it will be undefined in case of Lazy Initialization.


useInitSocket

hook to init your socket in the app in case of Lazy Initialization.

| Property | Type | Default | Description | Version | | ------------ | ------------------------------------------ | ----------- | -------------------------------- | ------- | | arg0:uri | string | undefined | socket uri (io(uri)) | 0.0.1 | | arg1:options | Partial<ManagerOptions & SocketOptions>? | undefined | socket options (io(, options)) | 0.0.1 | | arg2:start | boolean? | true | start initializing the socket | 0.0.1 |

return: void


useDisconnectOnUnmount

hook to disconnect and destroy the socket instance on unmounting, use in your root app if needed.

take no args

return: void


useSocket

hook that returns the instance of the socket.

take no args

return: Socket<TListenEvents, TEmitEvents>

it might return undefined in case of Lazy Initialization


useOn

hook to listen on every event emission.

| Property | Type | Default | Description | Version | | ------------- | ---------- | ----------- | -------------------------------------------------------------------------------- | ------- | | arg0:key | string | undefined | event key to listen on (socket.on(key)) | 0.0.1 | | arg1:listener | Function | undefined | listener that will will be called when the event fires (socket.on(, listener)) | 0.0.1 |

return: void


useOnce

hook to listen once on event emission.

| Property | Type | Default | Description | Version | | ------------- | ---------- | ----------- | ---------------------------------------------------------------------------------- | ------- | | arg0:key | string | undefined | event key to listen on (socket.once(key)) | 0.0.1 | | arg1:listener | Function | undefined | listener that will will be called when the event fires (socket.once(, listener)) | 0.0.1 |

return: void


useEmit

hook that return the socket.emit function, or a lazy emission function in case of Lazy Initialization,

lazy emission function will emit if socket is available, or record event until the socket is available.

take no args.

return: socket.emit function.


useImmediateEmit

hook to emit an event once.

| Property | Type | Default | Description | Version | | -------- | ----------- | ----------- | ------------------------------------------------------- | ------- | | arg0:key | string | undefined | event key to emit (socket.emit(key)) | 0.0.1 | | ...args | unknown[] | undefined | extra arguments to emit them (socket.emit(, ...args)) | 0.0.1 |

return: void


useEmitEffect

hook to emit an event on mount and once the dependency array changes.

| Property | Type | Default | Description | Version | | --------- | ----------- | ----------- | -------------------------------------------------------- | ------- | | arg0:deps | unknown[] | undefined | dependency array to listen on (like useEffect(, deps)) | 0.0.1 | | arg1:key | string | undefined | event key to emit (socket.emit(key)) | 0.0.1 | | ...args | unknown[] | undefined | extra arguments to emit them (socket.emit(, ...args)) | 0.0.1 |

return: void

NOTES

  • try to use the hooks (useEmit, useOn, ...) instead of getting the socket from useSocket and use it, because there some extra cases handled in those hooks.

  • useInitSocket will not reinitialize the socket in case it's already initialized, utilize the third argument ready to indicate when you have all of the required properties to start initializing.

  • no need to use useCallback with useOn(, cb) or useOnce(, cb) because it's handled internally.

  • changing the event name during renders will not affect useImmediateEmit(ev) or useEmitEffect(, ev), so if you want such behavior make sure to add it to the deps array using useEmitEffect([ev], ev).