@supabase/realtime-js
Advanced tools
Comparing version 2.1.0 to 2.2.0
@@ -1,2 +0,2 @@ | ||
export declare const version = "2.1.0"; | ||
export declare const version = "2.2.0"; | ||
//# sourceMappingURL=version.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.version = void 0; | ||
exports.version = '2.1.0'; | ||
exports.version = '2.2.0'; | ||
//# sourceMappingURL=version.js.map |
@@ -10,3 +10,3 @@ import { CHANNEL_STATES } from './lib/constants'; | ||
* self option enables client to receive message it broadcast | ||
* ack option instructs server to acknowlege that broadcast message was received | ||
* ack option instructs server to acknowledge that broadcast message was received | ||
*/ | ||
@@ -120,3 +120,15 @@ broadcast?: { | ||
}): Promise<RealtimeChannelSendResponse>; | ||
/** Listen to messages. */ | ||
/** | ||
* Creates an event handler that listens to changes | ||
* @param type Realtime feature (broadcast, presence, or postgres_changes) | ||
* @param filter Pre-defined and custom values specific to the Realtime feature | ||
* @param filter.schema Database schema | ||
* @param filter.event Event to listen to. If listening to postgres_changes type | ||
* then this value is one of INSERT, UPDATE, DELETE, * | ||
* @param filter.filter If listening to postgres_changes type then this value is used to specify | ||
* the Postgres Changes filter (eq, neq, lt, lte, gt, or gte) and value to listen to | ||
* @param filter.table If listening to postgres_changes type then this value is used to specify | ||
* the database table to listen to | ||
* @param callback Function to be invoked when event handler is triggered | ||
*/ | ||
on(type: `${REALTIME_LISTEN_TYPES.BROADCAST}`, filter: { | ||
@@ -132,8 +144,12 @@ event: string; | ||
}, callback: () => void): RealtimeChannel; | ||
on(type: `${REALTIME_LISTEN_TYPES.PRESENCE}`, filter: { | ||
on<T extends { | ||
[key: string]: any; | ||
}>(type: `${REALTIME_LISTEN_TYPES.PRESENCE}`, filter: { | ||
event: `${REALTIME_PRESENCE_LISTEN_EVENTS.JOIN}`; | ||
}, callback: (payload: RealtimePresenceJoinPayload) => void): RealtimeChannel; | ||
on(type: `${REALTIME_LISTEN_TYPES.PRESENCE}`, filter: { | ||
}, callback: (payload: RealtimePresenceJoinPayload<T>) => void): RealtimeChannel; | ||
on<T extends { | ||
[key: string]: any; | ||
}>(type: `${REALTIME_LISTEN_TYPES.PRESENCE}`, filter: { | ||
event: `${REALTIME_PRESENCE_LISTEN_EVENTS.LEAVE}`; | ||
}, callback: (payload: RealtimePresenceLeavePayload) => void): RealtimeChannel; | ||
}, callback: (payload: RealtimePresenceLeavePayload<T>) => void): RealtimeChannel; | ||
on<T extends { | ||
@@ -140,0 +156,0 @@ [key: string]: any; |
@@ -86,4 +86,14 @@ import { CONNECTION_STATE } from './lib/constants'; | ||
disconnect(code?: number, reason?: string): void; | ||
/** | ||
* Returns all created channels | ||
*/ | ||
getChannels(): RealtimeChannel[]; | ||
/** | ||
* Unsubscribes and removes a single channel | ||
* @param channel A RealtimeChannel instance | ||
*/ | ||
removeChannel(channel: RealtimeChannel): Promise<RealtimeRemoveChannelResponse>; | ||
/** | ||
* Unsubscribes and removes all channels | ||
*/ | ||
removeAllChannels(): Promise<RealtimeRemoveChannelResponse[]>; | ||
@@ -93,3 +103,3 @@ /** | ||
* | ||
* For customized logging, `this.logger` can be overriden. | ||
* For customized logging, `this.logger` can be overridden. | ||
*/ | ||
@@ -102,3 +112,3 @@ log(kind: string, msg: string, data?: any): void; | ||
/** | ||
* Retuns `true` is the connection is open. | ||
* Returns `true` is the connection is open. | ||
*/ | ||
@@ -105,0 +115,0 @@ isConnected(): boolean; |
@@ -132,5 +132,12 @@ "use strict"; | ||
} | ||
/** | ||
* Returns all created channels | ||
*/ | ||
getChannels() { | ||
return this.channels; | ||
} | ||
/** | ||
* Unsubscribes and removes a single channel | ||
* @param channel A RealtimeChannel instance | ||
*/ | ||
removeChannel(channel) { | ||
@@ -144,2 +151,5 @@ return channel.unsubscribe().then((status) => { | ||
} | ||
/** | ||
* Unsubscribes and removes all channels | ||
*/ | ||
removeAllChannels() { | ||
@@ -154,3 +164,3 @@ return Promise.all(this.channels.map((channel) => channel.unsubscribe())).then((values) => { | ||
* | ||
* For customized logging, `this.logger` can be overriden. | ||
* For customized logging, `this.logger` can be overridden. | ||
*/ | ||
@@ -176,3 +186,3 @@ log(kind, msg, data) { | ||
/** | ||
* Retuns `true` is the connection is open. | ||
* Returns `true` is the connection is open. | ||
*/ | ||
@@ -179,0 +189,0 @@ isConnected() { |
import { PresenceOpts, PresenceOnJoinCallback, PresenceOnLeaveCallback } from 'phoenix'; | ||
import RealtimeChannel from './RealtimeChannel'; | ||
declare type Presence = { | ||
declare type Presence<T extends { | ||
[key: string]: any; | ||
} = {}> = { | ||
presence_ref: string; | ||
[key: string]: any; | ||
}; | ||
} & T; | ||
export declare type RealtimePresenceState = { | ||
[key: string]: Presence[]; | ||
}; | ||
export declare type RealtimePresenceJoinPayload = { | ||
export declare type RealtimePresenceJoinPayload<T extends { | ||
[key: string]: any; | ||
}> = { | ||
event: `${REALTIME_PRESENCE_LISTEN_EVENTS.JOIN}`; | ||
key: string; | ||
currentPresences: Presence[]; | ||
newPresences: Presence[]; | ||
currentPresences: Presence<T>[]; | ||
newPresences: Presence<T>[]; | ||
}; | ||
export declare type RealtimePresenceLeavePayload = { | ||
export declare type RealtimePresenceLeavePayload<T extends { | ||
[key: string]: any; | ||
}> = { | ||
event: `${REALTIME_PRESENCE_LISTEN_EVENTS.LEAVE}`; | ||
key: string; | ||
currentPresences: Presence[]; | ||
leftPresences: Presence[]; | ||
currentPresences: Presence<T>[]; | ||
leftPresences: Presence<T>[]; | ||
}; | ||
@@ -22,0 +27,0 @@ export declare enum REALTIME_PRESENCE_LISTEN_EVENTS { |
@@ -1,2 +0,2 @@ | ||
export declare const version = "2.1.0"; | ||
export declare const version = "2.2.0"; | ||
//# sourceMappingURL=version.d.ts.map |
@@ -1,2 +0,2 @@ | ||
export const version = '2.1.0'; | ||
export const version = '2.2.0'; | ||
//# sourceMappingURL=version.js.map |
@@ -10,3 +10,3 @@ import { CHANNEL_STATES } from './lib/constants'; | ||
* self option enables client to receive message it broadcast | ||
* ack option instructs server to acknowlege that broadcast message was received | ||
* ack option instructs server to acknowledge that broadcast message was received | ||
*/ | ||
@@ -120,3 +120,15 @@ broadcast?: { | ||
}): Promise<RealtimeChannelSendResponse>; | ||
/** Listen to messages. */ | ||
/** | ||
* Creates an event handler that listens to changes | ||
* @param type Realtime feature (broadcast, presence, or postgres_changes) | ||
* @param filter Pre-defined and custom values specific to the Realtime feature | ||
* @param filter.schema Database schema | ||
* @param filter.event Event to listen to. If listening to postgres_changes type | ||
* then this value is one of INSERT, UPDATE, DELETE, * | ||
* @param filter.filter If listening to postgres_changes type then this value is used to specify | ||
* the Postgres Changes filter (eq, neq, lt, lte, gt, or gte) and value to listen to | ||
* @param filter.table If listening to postgres_changes type then this value is used to specify | ||
* the database table to listen to | ||
* @param callback Function to be invoked when event handler is triggered | ||
*/ | ||
on(type: `${REALTIME_LISTEN_TYPES.BROADCAST}`, filter: { | ||
@@ -132,8 +144,12 @@ event: string; | ||
}, callback: () => void): RealtimeChannel; | ||
on(type: `${REALTIME_LISTEN_TYPES.PRESENCE}`, filter: { | ||
on<T extends { | ||
[key: string]: any; | ||
}>(type: `${REALTIME_LISTEN_TYPES.PRESENCE}`, filter: { | ||
event: `${REALTIME_PRESENCE_LISTEN_EVENTS.JOIN}`; | ||
}, callback: (payload: RealtimePresenceJoinPayload) => void): RealtimeChannel; | ||
on(type: `${REALTIME_LISTEN_TYPES.PRESENCE}`, filter: { | ||
}, callback: (payload: RealtimePresenceJoinPayload<T>) => void): RealtimeChannel; | ||
on<T extends { | ||
[key: string]: any; | ||
}>(type: `${REALTIME_LISTEN_TYPES.PRESENCE}`, filter: { | ||
event: `${REALTIME_PRESENCE_LISTEN_EVENTS.LEAVE}`; | ||
}, callback: (payload: RealtimePresenceLeavePayload) => void): RealtimeChannel; | ||
}, callback: (payload: RealtimePresenceLeavePayload<T>) => void): RealtimeChannel; | ||
on<T extends { | ||
@@ -140,0 +156,0 @@ [key: string]: any; |
@@ -86,4 +86,14 @@ import { CONNECTION_STATE } from './lib/constants'; | ||
disconnect(code?: number, reason?: string): void; | ||
/** | ||
* Returns all created channels | ||
*/ | ||
getChannels(): RealtimeChannel[]; | ||
/** | ||
* Unsubscribes and removes a single channel | ||
* @param channel A RealtimeChannel instance | ||
*/ | ||
removeChannel(channel: RealtimeChannel): Promise<RealtimeRemoveChannelResponse>; | ||
/** | ||
* Unsubscribes and removes all channels | ||
*/ | ||
removeAllChannels(): Promise<RealtimeRemoveChannelResponse[]>; | ||
@@ -93,3 +103,3 @@ /** | ||
* | ||
* For customized logging, `this.logger` can be overriden. | ||
* For customized logging, `this.logger` can be overridden. | ||
*/ | ||
@@ -102,3 +112,3 @@ log(kind: string, msg: string, data?: any): void; | ||
/** | ||
* Retuns `true` is the connection is open. | ||
* Returns `true` is the connection is open. | ||
*/ | ||
@@ -105,0 +115,0 @@ isConnected(): boolean; |
@@ -127,5 +127,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
} | ||
/** | ||
* Returns all created channels | ||
*/ | ||
getChannels() { | ||
return this.channels; | ||
} | ||
/** | ||
* Unsubscribes and removes a single channel | ||
* @param channel A RealtimeChannel instance | ||
*/ | ||
removeChannel(channel) { | ||
@@ -139,2 +146,5 @@ return channel.unsubscribe().then((status) => { | ||
} | ||
/** | ||
* Unsubscribes and removes all channels | ||
*/ | ||
removeAllChannels() { | ||
@@ -149,3 +159,3 @@ return Promise.all(this.channels.map((channel) => channel.unsubscribe())).then((values) => { | ||
* | ||
* For customized logging, `this.logger` can be overriden. | ||
* For customized logging, `this.logger` can be overridden. | ||
*/ | ||
@@ -171,3 +181,3 @@ log(kind, msg, data) { | ||
/** | ||
* Retuns `true` is the connection is open. | ||
* Returns `true` is the connection is open. | ||
*/ | ||
@@ -174,0 +184,0 @@ isConnected() { |
import { PresenceOpts, PresenceOnJoinCallback, PresenceOnLeaveCallback } from 'phoenix'; | ||
import RealtimeChannel from './RealtimeChannel'; | ||
declare type Presence = { | ||
declare type Presence<T extends { | ||
[key: string]: any; | ||
} = {}> = { | ||
presence_ref: string; | ||
[key: string]: any; | ||
}; | ||
} & T; | ||
export declare type RealtimePresenceState = { | ||
[key: string]: Presence[]; | ||
}; | ||
export declare type RealtimePresenceJoinPayload = { | ||
export declare type RealtimePresenceJoinPayload<T extends { | ||
[key: string]: any; | ||
}> = { | ||
event: `${REALTIME_PRESENCE_LISTEN_EVENTS.JOIN}`; | ||
key: string; | ||
currentPresences: Presence[]; | ||
newPresences: Presence[]; | ||
currentPresences: Presence<T>[]; | ||
newPresences: Presence<T>[]; | ||
}; | ||
export declare type RealtimePresenceLeavePayload = { | ||
export declare type RealtimePresenceLeavePayload<T extends { | ||
[key: string]: any; | ||
}> = { | ||
event: `${REALTIME_PRESENCE_LISTEN_EVENTS.LEAVE}`; | ||
key: string; | ||
currentPresences: Presence[]; | ||
leftPresences: Presence[]; | ||
currentPresences: Presence<T>[]; | ||
leftPresences: Presence<T>[]; | ||
}; | ||
@@ -22,0 +27,0 @@ export declare enum REALTIME_PRESENCE_LISTEN_EVENTS { |
{ | ||
"name": "@supabase/realtime-js", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"description": "Listen to realtime updates to your PostgreSQL database", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
237
README.md
@@ -1,119 +0,205 @@ | ||
# Realtime Client | ||
<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> | ||
Listens to changes in a PostgreSQL Database and via websockets. | ||
<h1 align="center">Supabase Realtime Client</h1> | ||
This is for usage with Supabase [Realtime](https://github.com/supabase/realtime) server. | ||
<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> | ||
## Usage | ||
<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> | ||
### Creating a Socket connection | ||
# Overview | ||
You can set up one connection to be used across the whole app. | ||
This client enables you to use the following Supabase Realtime's features: | ||
- **Broadcast**: send ephemeral messages from client to clients with minimal latency. Use cases include sharing cursor positions between users. | ||
- **Presence**: track and synchronize shared state across clients with the help of CRDTs. Use cases include tracking which users are currently viewing a specific webpage. | ||
- **Postgres Change Data Capture (CDC)**: listen for changes in your PostgreSQL database and send them to clients. | ||
# Usage | ||
## Installing the Package | ||
```bash | ||
npm install @supabase/realtime-js | ||
``` | ||
## Creating a Channel | ||
```js | ||
import { RealtimeClient } from '@supabase/realtime-js' | ||
var client = new RealtimeClient(process.env.REALTIME_URL) | ||
client.connect() | ||
const client = new RealtimeClient(REALTIME_URL, { | ||
params: { | ||
apikey: API_KEY, | ||
eventsPerSecond: 10, | ||
}, | ||
}) | ||
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.') | ||
} | ||
}) | ||
``` | ||
REALTIME_URL is `'ws://localhost:4000/socket'` when developing locally and `'wss://<project_ref>.supabase.co/realtime/v1'` when connecting to your Supabase project. | ||
### Notes: | ||
You can pass in your JWT If you have enabled JWT authorization in Supabase [Realtime](https://github.com/supabase/realtime) server. | ||
- `REALTIME_URL` is `'ws://localhost:4000/socket'` when developing locally and `'wss://<project_ref>.supabase.co/realtime/v1'` when connecting to your Supabase project. | ||
- `API_KEY` is a JWT whose claims must contain `exp` and `role` (existing database role). | ||
- Channel name can be any `string`. | ||
- `eventsPerSecond`, or client-side rate limiting, enforces the number of events sent to the Realtime server uniformly spread across a second. The default is 10, which means that the client can send one event, whether that's **Broadcast**/**Presence**/**Postgres CDC**, every 100 milliseconds. You may change this as you see fit but note that the server's rate limiting will need to be updated accordingly. You can learn more about Realtime's rate limits here: https://supabase.com/docs/guides/realtime/rate-limits. | ||
## Broadcast | ||
Your client can send and receive messages based on the `event`. | ||
```js | ||
import { RealtimeClient } from '@supabase/realtime-js' | ||
// Setup... | ||
var client = new RealtimeClient(process.env.REALTIME_URL, { | ||
params: { apikey: 'token123' }, | ||
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' }, | ||
}) | ||
} | ||
}) | ||
client.connect() | ||
``` | ||
See [Realtime: Websocket Connection Authorization](https://github.com/supabase/realtime#websocket-connection-authorization) for more information. | ||
### Notes: | ||
### Subscribing to events | ||
- Setting `ack` to `true` means that the `channel.send` promise will resolve once server replies with acknowledgement that it received the broadcast message request. | ||
- Setting `self` to `true` means that the client will receive the broadcast message it sent out. | ||
You can listen to `INSERT`, `UPDATE`, `DELETE`, or all `*` events. | ||
## Presence | ||
You can subscribe to events on the whole database, schema, table, or individual columns using `channel()`. Channels are multiplexed over the Socket connection. | ||
Your client can track and sync state that's stored in the channel. | ||
To join a channel, you must provide the `topic`, where a topic is either: | ||
```js | ||
// Setup... | ||
- `realtime` - entire database | ||
- `realtime:{schema}` - where `{schema}` is the Postgres Schema | ||
- `realtime:{schema}:{table}` - where `{table}` is the Postgres table name | ||
- `realtime:{schema}:{table}:{col}=eq.{val}` - where `{col}` is the column name, and `{val}` is the value which you want to match | ||
const channel = client.channel('presence-test', { presence: { key: '' } }) | ||
**Examples** | ||
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: ', newPresences) | ||
}) | ||
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. | ||
```js | ||
// Listen to events on the entire database. | ||
var databaseChanges = client.channel('realtime:*') | ||
databaseChanges.on('*', (e) => console.log(e)) | ||
databaseChanges.on('INSERT', (e) => console.log(e)) | ||
databaseChanges.on('UPDATE', (e) => console.log(e)) | ||
databaseChanges.on('DELETE', (e) => console.log(e)) | ||
databaseChanges.subscribe() | ||
// Setup... | ||
// Listen to events on a schema, using the format `realtime:{SCHEMA}` | ||
var publicSchema = client.channel('realtime:public') | ||
publicSchema.on('*', (e) => console.log(e)) | ||
publicSchema.on('INSERT', (e) => console.log(e)) | ||
publicSchema.on('UPDATE', (e) => console.log(e)) | ||
publicSchema.on('DELETE', (e) => console.log(e)) | ||
publicSchema.subscribe() | ||
const channel = client.channel('db-changes') | ||
// Listen to events on a table, using the format `realtime:{SCHEMA}:{TABLE}` | ||
var usersTable = client.channel('realtime:public:users') | ||
usersTable.on('*', (e) => console.log(e)) | ||
usersTable.on('INSERT', (e) => console.log(e)) | ||
usersTable.on('UPDATE', (e) => console.log(e)) | ||
usersTable.on('DELETE', (e) => console.log(e)) | ||
usersTable.subscribe() | ||
channel.on('postgres_changes', { event: '*', schema: 'public' }, (payload) => { | ||
console.log('All changes in public schema: ', payload) | ||
}) | ||
// Listen to events on a row, using the format `realtime:{SCHEMA}:{TABLE}:{COL}=eq.{VAL}` | ||
var rowChanges = client.channel('realtime:public:users:id=eq.1') | ||
rowChanges.on('*', (e) => console.log(e)) | ||
rowChanges.on('INSERT', (e) => console.log(e)) | ||
rowChanges.on('UPDATE', (e) => console.log(e)) | ||
rowChanges.on('DELETE', (e) => console.log(e)) | ||
rowChanges.subscribe() | ||
``` | ||
channel.on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'messages' }, (payload) => { | ||
console.log('All inserts in messages table: ', payload) | ||
}) | ||
**Removing a subscription** | ||
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) | ||
}) | ||
You can unsubscribe from a topic using `channel.unsubscribe()`. | ||
channel.subscribe(async (status) => { | ||
if (status === 'SUBSCRIBED') { | ||
console.log('Ready to receive database changes!') | ||
} | ||
}) | ||
``` | ||
**Disconnect the socket** | ||
## Get All Channels | ||
Call `disconnect()` on the socket: | ||
You can see all the channels that your client has instantiatied. | ||
```js | ||
let { error, data } = await client.disconnect() | ||
// Setup... | ||
client.getChannels() | ||
``` | ||
**Duplicate Join Subscriptions** | ||
## Cleanup | ||
While the client may join any number of topics on any number of channels, the client may only hold a single subscription for each unique topic at any given time. When attempting to create a duplicate subscription, the server will close the existing channel, log a warning, and spawn a new channel for the topic. The client will have their `channel.onClose` callbacks fired for the existing channel, and the new | ||
channel join will have its receive hooks processed as normal. | ||
It is highly recommended that you clean up your channels after you're done with them. | ||
**Channel Hooks** | ||
- Remove a single channel | ||
```js | ||
channel._onError(() => console.log('there was an error!')) | ||
channel._onClose(() => console.log('the channel has gone away gracefully')) | ||
// Setup... | ||
const channel = client.channel('some-channel-to-remove') | ||
channel.subscribe() | ||
client.removeChannel(channel) | ||
``` | ||
- `onError` hooks are invoked if the socket connection drops, or the channel crashes on the server. In either case, a channel rejoin is attempted automatically in an exponential backoff manner. | ||
- `onClose` hooks are invoked only in two cases. 1) the channel explicitly closed on the server, or 2). The client explicitly closed, by calling `channel.unsubscribe()` | ||
- Remove all channels | ||
**Subscription Hooks** | ||
```js | ||
// Setup... | ||
```js | ||
publicSchema | ||
.subscribe() | ||
.receive('ok', () => console.log('Connected.')) | ||
.receive('error', () => console.log('Failed.')) | ||
.receive('timeout', () => console.log('Timed out, retrying.')) | ||
const channel1 = client.channel('a-channel-to-remove') | ||
const channel2 = client.channel('another-channel-to-remove') | ||
channel1.subscribe() | ||
channel2.subscribe() | ||
client.removeAllChannels() | ||
``` | ||
@@ -123,7 +209,6 @@ | ||
- Original Node.js client was made by Mario Campa of [phoenix-channels](github.com/mcampa/phoenix-client). | ||
- API was made by authors of the [Phoenix Framework](http://www.phoenixframework.org/). See their website for complete list of authors. | ||
This repo draws heavily from [phoenix-js](https://github.com/phoenixframework/phoenix/tree/master/assets/js/phoenix). | ||
## License | ||
MIT. License is the same as [phoenix-channels](https://github.com/mcampa/phoenix-client) and [Phoenix Framework](https://phoenixframework.org/). | ||
MIT. |
@@ -1,1 +0,1 @@ | ||
export const version = '2.1.0' | ||
export const version = '2.2.0' |
@@ -17,3 +17,3 @@ import { CHANNEL_EVENTS, CHANNEL_STATES } from './lib/constants' | ||
* self option enables client to receive message it broadcast | ||
* ack option instructs server to acknowlege that broadcast message was received | ||
* ack option instructs server to acknowledge that broadcast message was received | ||
*/ | ||
@@ -315,3 +315,15 @@ broadcast?: { self?: boolean; ack?: boolean } | ||
/** Listen to messages. */ | ||
/** | ||
* Creates an event handler that listens to changes | ||
* @param type Realtime feature (broadcast, presence, or postgres_changes) | ||
* @param filter Pre-defined and custom values specific to the Realtime feature | ||
* @param filter.schema Database schema | ||
* @param filter.event Event to listen to. If listening to postgres_changes type | ||
* then this value is one of INSERT, UPDATE, DELETE, * | ||
* @param filter.filter If listening to postgres_changes type then this value is used to specify | ||
* the Postgres Changes filter (eq, neq, lt, lte, gt, or gte) and value to listen to | ||
* @param filter.table If listening to postgres_changes type then this value is used to specify | ||
* the database table to listen to | ||
* @param callback Function to be invoked when event handler is triggered | ||
*/ | ||
on( | ||
@@ -331,11 +343,11 @@ type: `${REALTIME_LISTEN_TYPES.BROADCAST}`, | ||
): RealtimeChannel | ||
on( | ||
on<T extends { [key: string]: any }>( | ||
type: `${REALTIME_LISTEN_TYPES.PRESENCE}`, | ||
filter: { event: `${REALTIME_PRESENCE_LISTEN_EVENTS.JOIN}` }, | ||
callback: (payload: RealtimePresenceJoinPayload) => void | ||
callback: (payload: RealtimePresenceJoinPayload<T>) => void | ||
): RealtimeChannel | ||
on( | ||
on<T extends { [key: string]: any }>( | ||
type: `${REALTIME_LISTEN_TYPES.PRESENCE}`, | ||
filter: { event: `${REALTIME_PRESENCE_LISTEN_EVENTS.LEAVE}` }, | ||
callback: (payload: RealtimePresenceLeavePayload) => void | ||
callback: (payload: RealtimePresenceLeavePayload<T>) => void | ||
): RealtimeChannel | ||
@@ -342,0 +354,0 @@ on<T extends { [key: string]: any }>( |
@@ -162,2 +162,5 @@ import { w3cwebsocket } from 'websocket' | ||
/** | ||
* Returns all created channels | ||
*/ | ||
getChannels(): RealtimeChannel[] { | ||
@@ -167,2 +170,6 @@ return this.channels | ||
/** | ||
* Unsubscribes and removes a single channel | ||
* @param channel A RealtimeChannel instance | ||
*/ | ||
removeChannel( | ||
@@ -179,2 +186,5 @@ channel: RealtimeChannel | ||
/** | ||
* Unsubscribes and removes all channels | ||
*/ | ||
removeAllChannels(): Promise<RealtimeRemoveChannelResponse[]> { | ||
@@ -192,3 +202,3 @@ return Promise.all( | ||
* | ||
* For customized logging, `this.logger` can be overriden. | ||
* For customized logging, `this.logger` can be overridden. | ||
*/ | ||
@@ -216,3 +226,3 @@ log(kind: string, msg: string, data?: any) { | ||
/** | ||
* Retuns `true` is the connection is open. | ||
* Returns `true` is the connection is open. | ||
*/ | ||
@@ -219,0 +229,0 @@ isConnected(): boolean { |
@@ -13,21 +13,20 @@ /* | ||
type Presence = { | ||
type Presence<T extends { [key: string]: any } = {}> = { | ||
presence_ref: string | ||
[key: string]: any | ||
} | ||
} & T | ||
export type RealtimePresenceState = { [key: string]: Presence[] } | ||
export type RealtimePresenceJoinPayload = { | ||
export type RealtimePresenceJoinPayload<T extends { [key: string]: any }> = { | ||
event: `${REALTIME_PRESENCE_LISTEN_EVENTS.JOIN}` | ||
key: string | ||
currentPresences: Presence[] | ||
newPresences: Presence[] | ||
currentPresences: Presence<T>[] | ||
newPresences: Presence<T>[] | ||
} | ||
export type RealtimePresenceLeavePayload = { | ||
export type RealtimePresenceLeavePayload<T extends { [key: string]: any }> = { | ||
event: `${REALTIME_PRESENCE_LISTEN_EVENTS.LEAVE}` | ||
key: string | ||
currentPresences: Presence[] | ||
leftPresences: Presence[] | ||
currentPresences: Presence<T>[] | ||
leftPresences: Presence<T>[] | ||
} | ||
@@ -34,0 +33,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
344478
6099
214