Socket
Socket
Sign inDemoInstall

@ably/chat

Package Overview
Dependencies
Maintainers
0
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ably/chat - npm Package Compare versions

Comparing version 0.2.0 to 0.2.1

9

dist/chat/errors.d.ts

@@ -0,1 +1,2 @@

import * as Ably from 'ably';
/**

@@ -70,1 +71,9 @@ * Error codes for the Chat SDK.

}
/**
* Returns true if the {@link Ably.ErrorInfo} code matches the provided ErrorCodes value.
*
* @param errorInfo The error info to check.
* @param error The error code to compare against.
* @returns true if the error code matches, false otherwise.
*/
export declare const errorInfoIs: (errorInfo: Ably.ErrorInfo, error: ErrorCodes) => boolean;

2

dist/chat/index.d.ts

@@ -10,3 +10,3 @@ /**

export type { DiscontinuityListener, OnDiscontinuitySubscriptionResponse } from './discontinuity.js';
export type { ErrorCodes } from './errors.js';
export { ErrorCodes, errorInfoIs } from './errors.js';
export { MessageEvents, PresenceEvents } from './events.js';

@@ -13,0 +13,0 @@ export type { Headers } from './headers.js';

@@ -1,3 +0,3 @@

export declare const VERSION = "0.2.0";
export declare const CHANNEL_OPTIONS_AGENT_STRING = "chat-js/0.2.0";
export declare const VERSION = "0.2.1";
export declare const CHANNEL_OPTIONS_AGENT_STRING = "chat-js/0.2.1";
export declare const DEFAULT_CHANNEL_OPTIONS: {

@@ -4,0 +4,0 @@ params: {

import * as j from "react";
import W, { createContext as q, useRef as E, useEffect as g, useCallback as a, useState as C, useMemo as Q, useContext as Z } from "react";
import W, { createContext as Z, useRef as P, useEffect as g, useCallback as a, useState as y, useMemo as $, useContext as p } from "react";
import * as F from "ably";
import { jsx as z } from "react/jsx-runtime";
import { ConnectionLifecycle as X, RoomLifecycle as Y } from "@ably/chat";
const J = q(void 0), k = Symbol.for("__ABLY_CHAT_CLIENT_CONTEXT__"), B = typeof globalThis > "u" ? {} : globalThis;
function $() {
import { ConnectionLifecycle as X, RoomLifecycle as Y, errorInfoIs as J, ErrorCodes as K } from "@ably/chat";
const U = Z(void 0), k = Symbol.for("__ABLY_CHAT_CLIENT_CONTEXT__"), B = typeof globalThis > "u" ? {} : globalThis;
function ee() {
let t = B[k];
return t || (t = B[k] = W.createContext({})), t;
}
const O = $(), K = "default", se = ({ children: t, client: n }) => {
const u = j.useContext(O), e = j.useMemo(() => (n.addReactAgent(), { ...u, [K]: { client: n } }), [n, u]);
const O = ee(), q = "default", ue = ({ children: t, client: n }) => {
const u = j.useContext(O), e = j.useMemo(() => (n.addReactAgent(), { ...u, [q]: { client: n } }), [n, u]);
return /* @__PURE__ */ z(O.Provider, { value: e, children: t });
}, V = () => {
const t = W.useContext(O)[K];
const t = W.useContext(O)[q];
if (!t)

@@ -20,3 +20,3 @@ throw new F.ErrorInfo("useChatClient hook must be used within a chat client provider", 4e4, 400);

}, h = (t) => {
const n = E(t);
const n = P(t);
g(() => {

@@ -29,6 +29,6 @@ n.current = t;

return t ? u : void 0;
}, L = (t) => {
}, M = (t) => {
const n = V();
n.logger.trace("useChatConnection();", t);
const [u, e] = C(n.connection.status.current), [m, r] = C(n.connection.status.error), [o, d] = C(n.connection);
const [u, e] = y(n.connection.status.current), [m, r] = y(n.connection.status.error), [o, d] = y(n.connection);
g(() => {

@@ -58,5 +58,5 @@ d(n.connection), r(n.connection.status.error), e(n.connection.status.current);

};
}, D = () => {
}, T = () => {
const t = V();
return Q(() => t.logger, [t]);
return $(() => t.logger, [t]);
};

@@ -69,9 +69,9 @@ function N(t) {

}
const M = (t) => {
const n = Z(J), u = D();
const x = (t) => {
const n = p(U), u = T();
if (u.trace("useRoom();", { roomId: n == null ? void 0 : n.room.roomId }), !n)
throw u.error("useRoom(); must be used within a ChatRoomProvider"), new F.ErrorInfo("useRoom hook must be used within a ChatRoomProvider", 4e4, 400);
const { currentStatus: e, error: m } = L({
const { currentStatus: e, error: m } = M({
onStatusChange: t == null ? void 0 : t.onConnectionStatusChange
}), r = n.room, [o, d] = C(N(r.status)), i = h(t == null ? void 0 : t.onStatusChange);
}), r = n.room, [o, d] = y(N(r.status)), i = h(t == null ? void 0 : t.onStatusChange);
g(() => {

@@ -103,10 +103,10 @@ u.debug("useRoom(); setting up room status listener", { roomId: r.roomId });

};
}, ce = (t) => {
const { currentStatus: n, error: u } = L({
}, ie = (t) => {
const { currentStatus: n, error: u } = M({
onStatusChange: t == null ? void 0 : t.onConnectionStatusChange
}), { room: e, roomError: m, roomStatus: r } = M({
}), { room: e, roomError: m, roomStatus: r } = x({
onStatusChange: t == null ? void 0 : t.onRoomStatusChange
}), o = D();
}), o = T();
o.trace("useMessages();", { params: t, roomId: e.roomId });
const d = h(t == null ? void 0 : t.listener), i = h(t == null ? void 0 : t.onDiscontinuity), c = a((b) => e.messages.send(b), [e]), s = a((b) => e.messages.get(b), [e]), [l, f] = C();
const d = h(t == null ? void 0 : t.listener), i = h(t == null ? void 0 : t.onDiscontinuity), c = a((b) => e.messages.send(b), [e]), s = a((b) => e.messages.get(b), [e]), [l, f] = y();
return g(() => {

@@ -117,3 +117,3 @@ if (!d) return;

const S = e.messages.subscribe(d);
return f(() => (o.debug("useMessages(); setting getPreviousMessages state", { roomId: e.roomId }), (y) => b ? (o.debug("useMessages(); getPreviousMessages called after unmount", { roomId: e.roomId }), Promise.resolve({
return f(() => (o.debug("useMessages(); setting getPreviousMessages state", { roomId: e.roomId }), (C) => b ? (o.debug("useMessages(); getPreviousMessages called after unmount", { roomId: e.roomId }), Promise.resolve({
items: [],

@@ -130,3 +130,3 @@ hasNext: () => !1,

}
})) : S.getPreviousMessages(y))), () => {
})) : S.getPreviousMessages(C))), () => {
o.debug("useMessages(); removing listener and getPreviousMessages state", { roomId: e.roomId }), b = !0, S.unsubscribe(), f(void 0);

@@ -151,10 +151,10 @@ };

};
}, ue = (t) => {
const { currentStatus: n, error: u } = L({
}, de = (t) => {
const { currentStatus: n, error: u } = M({
onStatusChange: t == null ? void 0 : t.onConnectionStatusChange
}), { room: e, roomError: m, roomStatus: r } = M({
}), { room: e, roomError: m, roomStatus: r } = x({
onStatusChange: t == null ? void 0 : t.onRoomStatusChange
}), o = D();
}), o = T();
o.trace("useOccupancy();", { params: t, roomId: e.roomId });
const [d, i] = C({
const [d, i] = y({
connections: 0,

@@ -200,10 +200,10 @@ presenceMembers: 0

X.Failed
]), ie = (t) => {
const { currentStatus: n, error: u } = L({
]), ge = (t) => {
const { currentStatus: n, error: u } = M({
onStatusChange: t == null ? void 0 : t.onConnectionStatusChange
}), { room: e, roomError: m, roomStatus: r } = M({
}), { room: e, roomError: m, roomStatus: r } = x({
onStatusChange: t == null ? void 0 : t.onRoomStatusChange
}), o = D();
}), o = T();
o.trace("usePresence();", { params: t, roomId: e.roomId });
const [d, i] = C(!1), [c, s] = C(), l = E({ roomStatus: r, connectionStatus: n }), f = h(t == null ? void 0 : t.onDiscontinuity), b = E(t);
const [d, i] = y(!1), [c, s] = y(), l = P({ roomStatus: r, connectionStatus: n }), f = h(t == null ? void 0 : t.onDiscontinuity), b = P(t);
g(() => {

@@ -214,6 +214,6 @@ b.current = t;

}, [r, n]), g(() => {
var P;
const y = r === Y.Attached && !H.has(n), T = l.current.roomStatus === Y.Attached && !H.has(l.current.connectionStatus);
if (y)
return e.presence.enter((P = b.current) == null ? void 0 : P.enterWithData).then(() => {
var D;
const C = r === Y.Attached && !H.has(n), L = l.current.roomStatus === Y.Attached && !H.has(l.current.connectionStatus);
if (C)
return e.presence.enter((D = b.current) == null ? void 0 : D.enterWithData).then(() => {
o.debug("usePresence(); entered room", { roomId: e.roomId }), i(!0), s(void 0);

@@ -224,6 +224,6 @@ }).catch((I) => {

var I;
T && e.presence.leave((I = b.current) == null ? void 0 : I.leaveWithData).then(() => {
L && e.presence.leave((I = b.current) == null ? void 0 : I.leaveWithData).then(() => {
o.debug("usePresence(); left room", { roomId: e.roomId }), i(!1), s(void 0);
}).catch((_) => {
o.error("usePresence(); error leaving room", { error: _, roomId: e.roomId }), s(_);
}).catch((v) => {
o.error("usePresence(); error leaving room", { error: v, roomId: e.roomId }), s(v);
});

@@ -234,9 +234,9 @@ };

o.debug("usePresence(); applying onDiscontinuity listener", { roomId: e.roomId });
const { off: y } = e.presence.onDiscontinuity(f);
const { off: C } = e.presence.onDiscontinuity(f);
return () => {
o.debug("usePresence(); removing onDiscontinuity listener", { roomId: e.roomId }), y();
o.debug("usePresence(); removing onDiscontinuity listener", { roomId: e.roomId }), C();
};
}, [e, f, o]);
const S = a(
(y) => e.presence.update(y).then(() => {
(C) => e.presence.update(C).then(() => {
i(!0), s(void 0);

@@ -256,28 +256,28 @@ }),

};
}, p = 1500, ee = 3e4, te = 5, de = (t) => {
const { currentStatus: n, error: u } = L({
}, te = 1500, oe = 3e4, ne = 5, le = (t) => {
const { currentStatus: n, error: u } = M({
onStatusChange: t == null ? void 0 : t.onConnectionStatusChange
}), { room: e, roomError: m, roomStatus: r } = M({
}), { room: e, roomError: m, roomStatus: r } = x({
onStatusChange: t == null ? void 0 : t.onRoomStatusChange
}), o = D();
}), o = T();
o.trace("usePresenceListener();", { roomId: e.roomId });
const d = E(0), i = E(0), c = E(), s = E(0), l = E([]), [f, b] = C([]), S = E(), [y, T] = C(), P = h(t == null ? void 0 : t.listener), I = h(t == null ? void 0 : t.onDiscontinuity), _ = a(
(v) => {
o.debug("usePresenceListener(); setting error state", { error: v, roomId: e.roomId }), S.current = v, T(v);
const d = P(0), i = P(0), c = P(), s = P(0), l = P([]), [f, b] = y([]), S = P(), [C, L] = y(), D = h(t == null ? void 0 : t.listener), I = h(t == null ? void 0 : t.onDiscontinuity), v = a(
(E) => {
o.debug("usePresenceListener(); setting error state", { error: E, roomId: e.roomId }), S.current = E, L(E);
},
[o, e.roomId]
), w = a(() => {
o.debug("usePresenceListener(); clearing error state", { roomId: e.roomId }), S.current = void 0, T(void 0);
o.debug("usePresenceListener(); clearing error state", { roomId: e.roomId }), S.current = void 0, L(void 0);
}, [o, e.roomId]);
return g(() => {
const v = () => {
const E = () => {
d.current += 1, c.current && (clearTimeout(c.current), c.current = void 0, s.current = 0), G(d.current);
}, G = (R) => {
e.presence.get({ waitForSync: !0 }).then((x) => {
o.debug("usePresenceListener(); fetched presence data", { presenceMembers: x, roomId: e.roomId }), c.current && (clearTimeout(c.current), c.current = void 0, s.current = 0), !(i.current >= R) && (i.current = R, l.current = x, b(x), S.current && w());
e.presence.get({ waitForSync: !0 }).then((_) => {
o.debug("usePresenceListener(); fetched presence data", { presenceMembers: _, roomId: e.roomId }), c.current && (clearTimeout(c.current), c.current = void 0, s.current = 0), !(i.current >= R) && (i.current = R, l.current = _, b(_), S.current && w());
}).catch(() => {
if (!(s.current < te)) {
if (!(s.current < ne)) {
o.error("usePresenceListener(); failed to fetch presence data after max retries", {
roomId: e.roomId
}), _(new F.ErrorInfo("failed to fetch presence data after max retries", 5e4, 500));
}), v(new F.ErrorInfo("failed to fetch presence data after max retries", 5e4, 500));
return;

@@ -289,5 +289,5 @@ }

}
const U = Math.min(
ee,
p * Math.pow(2, s.current)
const Q = Math.min(
oe,
te * Math.pow(2, s.current)
);

@@ -299,3 +299,3 @@ s.current += 1, o.debug("usePresenceListener(); retrying to fetch presence data", {

c.current = void 0, d.current += 1, G(d.current);
}, U);
}, Q);
});

@@ -307,3 +307,7 @@ };

}).catch((R) => {
o.error("usePresenceListener(); error fetching initial presence data", { error: R, roomId: e.roomId }), _(R);
const _ = R;
J(_, K.RoomIsReleased) || (o.error("usePresenceListener(); error fetching initial presence data", {
error: R,
roomId: e.roomId
}), v(_));
}).finally(() => {

@@ -313,3 +317,3 @@ o.debug("usePresenceListener(); subscribing internal listener to presence events", {

}), A = e.presence.subscribe(() => {
v();
E();
}).unsubscribe;

@@ -319,14 +323,14 @@ }), () => {

};
}, [e, _, w, o]), g(() => {
if (!P) return;
const { unsubscribe: v } = e.presence.subscribe(P);
}, [e, v, w, o]), g(() => {
if (!D) return;
const { unsubscribe: E } = e.presence.subscribe(D);
return o.debug("usePresenceListener(); applying external listener", { roomId: e.roomId }), () => {
o.debug("usePresenceListener(); cleaning up external listener", { roomId: e.roomId }), v();
o.debug("usePresenceListener(); cleaning up external listener", { roomId: e.roomId }), E();
};
}, [e, P, o]), g(() => {
}, [e, D, o]), g(() => {
if (!I) return;
o.debug("usePresenceListener(); applying onDiscontinuity listener", { roomId: e.roomId });
const { off: v } = e.presence.onDiscontinuity(I);
const { off: E } = e.presence.onDiscontinuity(I);
return () => {
o.debug("usePresenceListener(); removing onDiscontinuity listener", { roomId: e.roomId }), v();
o.debug("usePresenceListener(); removing onDiscontinuity listener", { roomId: e.roomId }), E();
};

@@ -338,12 +342,12 @@ }, [e, I, o]), {

roomError: m,
error: y,
error: C,
presenceData: f,
presence: e.presence
};
}, ge = (t) => {
const { currentStatus: n, error: u } = L({
}, Ie = (t) => {
const { currentStatus: n, error: u } = M({
onStatusChange: t == null ? void 0 : t.onConnectionStatusChange
}), { room: e, roomError: m, roomStatus: r } = M({
}), { room: e, roomError: m, roomStatus: r } = x({
onStatusChange: t == null ? void 0 : t.onRoomStatusChange
}), o = D();
}), o = T();
o.trace("useRoomReactions();", { params: t, roomId: e.roomId });

@@ -375,26 +379,27 @@ const d = h(t == null ? void 0 : t.listener), i = h(t == null ? void 0 : t.onDiscontinuity);

};
}, le = (t) => {
const { currentStatus: n, error: u } = L({
}, fe = (t) => {
const { currentStatus: n, error: u } = M({
onStatusChange: t == null ? void 0 : t.onConnectionStatusChange
}), { room: e, roomError: m, roomStatus: r } = M({
}), { room: e, roomError: m, roomStatus: r } = x({
onStatusChange: t == null ? void 0 : t.onRoomStatusChange
}), o = D();
}), o = T();
o.trace("useTyping();", { roomId: e.roomId });
const [d, i] = C(/* @__PURE__ */ new Set()), [c, s] = C(), l = h(t == null ? void 0 : t.listener), f = h(t == null ? void 0 : t.onDiscontinuity);
const [d, i] = y(/* @__PURE__ */ new Set()), [c, s] = y(), l = h(t == null ? void 0 : t.listener), f = h(t == null ? void 0 : t.onDiscontinuity);
g(() => {
s(void 0), i((I) => I.size === 0 ? I : /* @__PURE__ */ new Set());
let y = !0;
const T = (I) => {
let C = !0;
const L = (I) => {
I === void 0 ? o.debug("useTyping(); clearing error state", { roomId: e.roomId }) : o.error("useTyping(); setting error state", { error: I, roomId: e.roomId }), s(I);
};
e.typing.get().then((I) => {
y && i(I);
C && i(I);
}).catch((I) => {
y && T(I);
const v = I;
!C || J(v, K.RoomIsReleased) || L(v);
});
const P = e.typing.subscribe((I) => {
T(void 0), i(I.currentlyTyping);
const D = e.typing.subscribe((I) => {
L(void 0), i(I.currentlyTyping);
});
return () => {
o.debug("useTyping(); unsubscribing from typing events", { roomId: e.roomId }), y = !1, P.unsubscribe();
o.debug("useTyping(); unsubscribing from typing events", { roomId: e.roomId }), C = !1, D.unsubscribe();
};

@@ -404,5 +409,5 @@ }, [e, o]), g(() => {

o.debug("useTyping(); applying onDiscontinuity listener", { roomId: e.roomId });
const { off: y } = e.typing.onDiscontinuity(f);
const { off: C } = e.typing.onDiscontinuity(f);
return () => {
o.debug("useTyping(); removing onDiscontinuity listener", { roomId: e.roomId }), y();
o.debug("useTyping(); removing onDiscontinuity listener", { roomId: e.roomId }), C();
};

@@ -412,5 +417,5 @@ }, [e, f, o]), g(() => {

o.debug("useTyping(); applying listener", { roomId: e.roomId });
const { unsubscribe: y } = e.typing.subscribe(l);
const { unsubscribe: C } = e.typing.subscribe(l);
return () => {
o.debug("useTyping(); removing listener", { roomId: e.roomId }), y();
o.debug("useTyping(); removing listener", { roomId: e.roomId }), C();
};

@@ -430,3 +435,3 @@ }, [e, l, o]);

};
}, Ie = ({
}, me = ({
id: t,

@@ -438,26 +443,28 @@ options: n,

}) => {
const r = V(), o = D();
const r = V(), o = T();
o.trace("ChatRoomProvider();", { roomId: t, options: n, release: u, attach: e });
const [d, i] = C({ room: r.rooms.get(t, n) });
const [d, i] = y({ room: r.rooms.get(t, n) });
return g(() => {
const c = r.rooms.get(t, n);
return i((s) => s.room === c ? s : { room: c }), e && (o.debug("ChatRoomProvider(); attaching room", { roomId: t }), c.attach()), () => {
u ? (o.debug("ChatRoomProvider(); releasing room", { roomId: t }), r.rooms.release(t)) : e && (o.debug("ChatRoomProvider(); detaching room", { roomId: t }), c.detach());
return i((s) => s.room === c ? s : { room: c }), e && (o.debug("ChatRoomProvider(); attaching room", { roomId: t }), c.attach().catch(() => {
})), () => {
u ? (o.debug("ChatRoomProvider(); releasing room", { roomId: t }), r.rooms.release(t)) : e && (o.debug("ChatRoomProvider(); detaching room", { roomId: t }), c.detach().catch(() => {
}));
};
}, [r, t, n, u, e, o]), /* @__PURE__ */ z(J.Provider, { value: d, children: m });
}, [r, t, n, u, e, o]), /* @__PURE__ */ z(U.Provider, { value: d, children: m });
};
export {
se as ChatClientProvider,
J as ChatRoomContext,
Ie as ChatRoomProvider,
ue as ChatClientProvider,
U as ChatRoomContext,
me as ChatRoomProvider,
V as useChatClient,
L as useChatConnection,
ce as useMessages,
ue as useOccupancy,
ie as usePresence,
de as usePresenceListener,
M as useRoom,
ge as useRoomReactions,
le as useTyping
M as useChatConnection,
ie as useMessages,
de as useOccupancy,
ge as usePresence,
le as usePresenceListener,
x as useRoom,
Ie as useRoomReactions,
fe as useTyping
};
//# sourceMappingURL=ably-chat-react.js.map

@@ -23,2 +23,5 @@ import { RoomOptions } from '@ably/chat';

* ```
*
* NOTE: This value is not memoized by the provider. It must be memoized in your component to prevent
* re-renders of a parent component from causing the room to be recreated.
*/

@@ -25,0 +28,0 @@ options: RoomOptions;

{
"name": "@ably/chat",
"version": "0.2.0",
"version": "0.2.1",
"description": "Ably Chat is a set of purpose-built APIs for a host of chat features enabling you to create 1:1, 1:Many, Many:1 and Many:Many chat rooms for any scale. It is designed to meet a wide range of chat use cases, such as livestreams, in-game communication, customer support, or social interactions in SaaS products.",

@@ -70,2 +70,3 @@ "type": "module",

"@types/jsonwebtoken": "^9.0.6",
"@types/lodash.clonedeep": "^4.5.9",
"@types/react": "^18.3.3",

@@ -84,2 +85,3 @@ "@typescript-eslint/eslint-plugin": "^7.14.1",

"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-native": "^4.1.0",
"eslint-plugin-react-refresh": "^0.4.7",

@@ -104,3 +106,4 @@ "eslint-plugin-security": "^3.0.1",

"async-mutex": "^0.5.0",
"dequal": "^2.0.3"
"dequal": "^2.0.3",
"lodash.clonedeep": "^4.5.0"
},

@@ -107,0 +110,0 @@ "optionalDependencies": {

@@ -32,4 +32,2 @@ # Ably Chat SDK for TypeScript and React

There is a known caveat in the current version of the library in environments where `structuredClone` is not defined. To address this, you can use a polyfill such as [@ungap/structured-clone](https://www.npmjs.com/package/@ungap/structured-clone).
## Supported chat features

@@ -36,0 +34,0 @@

@@ -0,1 +1,3 @@

import * as Ably from 'ably';
/**

@@ -89,1 +91,11 @@ * Error codes for the Chat SDK.

}
/**
* Returns true if the {@link Ably.ErrorInfo} code matches the provided ErrorCodes value.
*
* @param errorInfo The error info to check.
* @param error The error code to compare against.
* @returns true if the error code matches, false otherwise.
*/
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
export const errorInfoIs = (errorInfo: Ably.ErrorInfo, error: ErrorCodes): boolean => errorInfo.code === error;

@@ -16,3 +16,3 @@ /**

export type { DiscontinuityListener, OnDiscontinuitySubscriptionResponse } from './discontinuity.js';
export type { ErrorCodes } from './errors.js';
export { ErrorCodes, errorInfoIs } from './errors.js';
export { MessageEvents, PresenceEvents } from './events.js';

@@ -19,0 +19,0 @@ export type { Headers } from './headers.js';

@@ -485,4 +485,13 @@ import * as Ably from 'ably';

// Set the subscription point to a promise that resolves when the channel attaches or with the latest message
this._listenerSubscriptionPoints.set(listener, this._resolveSubscriptionStart());
const resolvedSubscriptionStart = this._resolveSubscriptionStart();
// Add a handler for unhandled rejections incase the room is released before the subscription point is resolved
resolvedSubscriptionStart.catch(() => {
this._logger.debug('Messages.subscribe(); subscription point was not resolved before the room was released', {
roomId: this._roomId,
});
});
this._listenerSubscriptionPoints.set(listener, resolvedSubscriptionStart);
return {

@@ -489,0 +498,0 @@ unsubscribe: () => {

import * as Ably from 'ably';
import cloneDeep from 'lodash.clonedeep';
import { ChatApi } from './chat-api.js';
import { ErrorCodes } from './errors.js';
import { Logger } from './logger.js';

@@ -188,7 +190,9 @@ import { DefaultMessages, Messages } from './messages.js';

// Room initialization: handle the state before features start to be initialized
// We don't need to catch it here as we immediately go into _asyncOpsAfter where we catch it
const rejectablePromise = makeRejectablePromise(makeAlwaysResolves(initAfter));
const initFeaturesAfter = rejectablePromise.promise;
this._finalizer = () => {
const rejectedNow = rejectablePromise.reject(
new Ably.ErrorInfo('Room released before initialization started.', 40000, 400),
new Ably.ErrorInfo('Room released before initialization started', ErrorCodes.RoomIsReleased, 400),
);

@@ -202,10 +206,2 @@ if (rejectedNow) {

// Catch to prevent global errors and print a debug log
initFeaturesAfter.catch((error: unknown) => {
this._logger.debug('Room initialization was prevented before initializing features', {
error: error,
roomId: roomId,
});
});
// Setup features

@@ -264,2 +260,4 @@ this._messages = new DefaultMessages(

// Catch errors from asyncOpsAfter to prevent unhandled promise rejection error and print a debug log
// This only prevents the base promise from erroring - calls to attach, detach etc that depend on _asyncOpsAfter
// will need to specify their own error handling.
this._asyncOpsAfter.catch((error: unknown) => {

@@ -303,3 +301,3 @@ this._logger.debug('Room initialization was prevented before finishing', { error: error, roomId: roomId });

rejectableAsyncOpsAfter.reject(
new Ably.ErrorInfo('Room released before initialization finished', 40000, 400),
new Ably.ErrorInfo('Room released before initialization finished', ErrorCodes.RoomIsReleased, 400),
);

@@ -377,3 +375,3 @@ return finalizerFuncPromise.then((f) => {

options(): RoomOptions {
return structuredClone(this._options);
return cloneDeep(this._options);
}

@@ -380,0 +378,0 @@

// Update this when you release a new version
export const VERSION = '0.2.0';
export const VERSION = '0.2.1';
export const CHANNEL_OPTIONS_AGENT_STRING = `chat-js/${VERSION}`;
export const DEFAULT_CHANNEL_OPTIONS = { params: { agent: CHANNEL_OPTIONS_AGENT_STRING } };

@@ -1,2 +0,2 @@

import { Presence, PresenceListener, PresenceMember } from '@ably/chat';
import { ErrorCodes, errorInfoIs, Presence, PresenceListener, PresenceMember } from '@ably/chat';
import * as Ably from 'ably';

@@ -204,4 +204,10 @@ import { useCallback, useEffect, useRef, useState } from 'react';

.catch((error: unknown) => {
logger.error('usePresenceListener(); error fetching initial presence data', { error, roomId: room.roomId });
setErrorState(error as Ably.ErrorInfo);
const errorInfo = error as Ably.ErrorInfo;
if (errorInfoIs(errorInfo, ErrorCodes.RoomIsReleased)) return;
logger.error('usePresenceListener(); error fetching initial presence data', {
error,
roomId: room.roomId,
});
setErrorState(errorInfo);
})

@@ -208,0 +214,0 @@ .finally(() => {

@@ -1,2 +0,2 @@

import { Typing, TypingEvent, TypingListener } from '@ably/chat';
import { ErrorCodes, errorInfoIs, Typing, TypingEvent, TypingListener } from '@ably/chat';
import * as Ably from 'ably';

@@ -106,4 +106,6 @@ import { useCallback, useEffect, useState } from 'react';

.catch((error: unknown) => {
if (!mounted) return;
setErrorState(error as Ably.ErrorInfo);
const errorInfo = error as Ably.ErrorInfo;
if (!mounted || errorInfoIs(errorInfo, ErrorCodes.RoomIsReleased)) return;
setErrorState(errorInfo);
});

@@ -110,0 +112,0 @@

@@ -147,2 +147,3 @@ # Chat React Usage Guide

id="my-room-id"
// The value passed to options should be memoized, or use the defaults.
options={RoomOptionsDefaults}

@@ -159,2 +160,5 @@ >

> [!IMPORTANT]
> The `ChatClientProvider` does **not** memoize the value passed in to the `options` parameter. If the value changes between re-renders, then the chat room will be discarded and recreated with the new options. To prevent a parent component re-render causing the `ChatRoomProvider` to re-render, be sure to memoize / provide a stable reference to, your desired room options.
To use the room-level hooks below, you **must** wrap any components utilizing the hooks inside a `ChatRoomProvider`.

@@ -161,0 +165,0 @@

Sorry, the diff of this file is too big to display

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc