Home

Awesome

<br /> <p align="center"> <a href="https://supabase.io"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--dark.svg"> <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--light.svg"> <img alt="Supabase Logo" width="300" src="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/logo-preview.jpg"> </picture> </a> <h1 align="center">Supabase Realtime Client</h1> <h3 align="center">Send ephemeral messages with <b>Broadcast</b>, track and synchronize state with <b>Presence</b>, and listen to database changes with <b>Postgres Change Data Capture (CDC)</b>.</h3> <p align="center"> <a href="https://supabase.com/docs/guides/realtime">Guides</a> · <a href="https://supabase.com/docs/reference/javascript">Reference Docs</a> · <a href="https://multiplayer.dev">Multiplayer Demo</a> </p> </p>

Overview

This client enables you to use the following Supabase Realtime's features:

Usage

Installing the Package

npm install @supabase/realtime-js

Creating a Channel

import { RealtimeClient } from '@supabase/realtime-js'

const client = new RealtimeClient(REALTIME_URL, {
  params: {
    apikey: API_KEY
  },
})

const channel = client.channel('test-channel', {})

channel.subscribe((status, err) => {
  if (status === 'SUBSCRIBED') {
    console.log('Connected!')
  }

  if (status === 'CHANNEL_ERROR') {
    console.log(`There was an error subscribing to channel: ${err.message}`)
  }

  if (status === 'TIMED_OUT') {
    console.log('Realtime server did not respond in time.')
  }

  if (status === 'CLOSED') {
    console.log('Realtime channel was unexpectedly closed.')
  }
})

Notes:

Broadcast

Your client can send and receive messages based on the event.

// Setup...

const channel = client.channel('broadcast-test', { broadcast: { ack: false, self: false } })

channel.on('broadcast', { event: 'some-event' }, (payload) =>
  console.log(payload)
)

channel.subscribe(async (status) => {
  if (status === 'SUBSCRIBED') {
    // Send message to other clients listening to 'broadcast-test' channel
    await channel.send({
      type: 'broadcast',
      event: 'some-event',
      payload: { hello: 'world' },
    })
  }
})

Notes:

Presence

Your client can track and sync state that's stored in the channel.

// Setup...

const channel = client.channel(
  'presence-test',
  {
    config: {
      presence: {
        key: ''
      }
    }
  }
)

channel.on('presence', { event: 'sync' }, () => {
  console.log('Online users: ', channel.presenceState())
})

channel.on('presence', { event: 'join' }, ({ newPresences }) => {
  console.log('New users have joined: ', newPresences)
})

channel.on('presence', { event: 'leave' }, ({ leftPresences }) => {
  console.log('Users have left: ', leftPresences)
})

channel.subscribe(async (status) => {
  if (status === 'SUBSCRIBED') {
    const status = await channel.track({ 'user_id': 1 })
    console.log(status)
  }
})

Postgres CDC

Receive database changes on the client.

// Setup...

const channel = client.channel('db-changes')

channel.on('postgres_changes', { event: '*', schema: 'public' }, (payload) => {
  console.log('All changes in public schema: ', payload)
})

channel.on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'messages' }, (payload) => {
  console.log('All inserts in messages table: ', payload)
})

channel.on('postgres_changes', { event: 'UPDATE', schema: 'public', table: 'users', filter: 'username=eq.Realtime' }, (payload) => {
  console.log('All updates on users table when username is Realtime: ', payload)
})

channel.subscribe(async (status) => {
  if (status === 'SUBSCRIBED') {
    console.log('Ready to receive database changes!')
  }
})

Get All Channels

You can see all the channels that your client has instantiatied.

// Setup...

client.getChannels()

Cleanup

It is highly recommended that you clean up your channels after you're done with them.

// Setup...

const channel = client.channel('some-channel-to-remove')

channel.subscribe()

client.removeChannel(channel)
// Setup...

const channel1 = client.channel('a-channel-to-remove')
const channel2 = client.channel('another-channel-to-remove')

channel1.subscribe()
channel2.subscribe()

client.removeAllChannels()

Credits

This repo draws heavily from phoenix-js.

License

MIT.