# TalkJS Core

The `@talkjs/core` package lets you connect to your [TalkJS](https://talkjs.com) chat as a user and read, subscribe to, and update your chat data.

[See our docs](https://talkjs.com/docs/JavaScript_Data_API/) for more information.

## Prerequisites

To use this package, you will need a [TalkJS account](https://talkjs.com/dashboard/login). TalkJS provides a ready-to-use chat client for your application. Your account gives you access to TalkJS's free development environment.

## Example

This example demonstrates how to create a TalkJS session and then create two users and conversation between them.

Install the `@talkjs/core` package:

```sh
npm install @talkjs/core
# or
yarn add @talkjs/core
```

Import it into the component where you want to use it:

```js
import { getTalkSession } from "@talkjs/core";
```

Then add the following code to create the session, users and conversation:

```js
// Replace with your own app ID
const appId = "<APP_ID>";
const userId = "alice";

const session = getTalkSession({ appId, userId });
session.currentUser.createIfNotExists({ name: "Alice" });

const conversation = session.conversation("my_conversation");
conversation.createIfNotExists();

conversation.subscribeMessages((messages) => {
  console.log(messages);
});
```

For example, if you are using React, add this code inside a `useEffect` hook.

## Node.js compatibility

This package is primarily intended to be used in the browser because it only connects as a single user. However, it also works in Node.js.

The `@talkjs/core` package uses `WebSocket`s to create a connection to the TalkJS servers. If you use `@talkjs/core` in the browser or in Node.js version 22, it will use the built-in `WebSocket` implementation automatically. Node.js version 21 will also use the built-in implementation if the `--experimental-websocket` flag is enabled.

If you are using an older version of Node.js without built-in support for `WebSocket`s, you will need to add support with a library. We recommend installing the [ws](https://www.npmjs.com/package/ws) package. Then tell `@talkjs/core` to use `WebSocket` from the library:

```js
import { getTalkSession, registerPolyfills } from "@talkjs/core";
import { WebSocket } from "ws";

registerPolyfills({ WebSocket: WebSocket });

const session = getTalkSession(...);
```

## Support

If you encounter any problems with `@talkjs/core`, please open a [chat with support](https://talkjs.com/?chat). TalkJS support is staffed by engineers.

## Changelog

### 1.11.1

- Fixed a bug where doing a search while a `conversationFilter` was specified would still return results that are outside of that filter's scope.

### 1.11.0

- Exposed `appId` property of `TalkSession`
- Removed `options` property from `ConversationRef.subscribeMessages`. This was not meant to be released and was not actually implemented yet.

### 1.10.0

- Added support for filtering the list of conversations in `TalkSession.subscribeConversations`
  - Added filter types, `ConversationFilter`, `SimpleConversationFilter`, `CompoundFilter`, `StringFilter`, `NumberFilter`, and `CustomFilter`.

### 1.9.1

- Fixed a bug where we assumed all "participant edited" events were about the current user. This meant if you did `ConversationRef.subscribe` and `ConversationRef.subscribeParticipants` at the same time, changes to any participant's `access` or `notify` triggered the conversation subscription to emit as if your `access` / `notify` had changed.

### 1.9.0

- Renamed multiple classes and methods:
  - `ReactionRef` -> `ReactionsRef`
  - `MessageRef.reaction` -> `MessageRef.reactions`
  - `ReactionSnapshot` -> `ReactionsSummarySnapshot`
  - The old names will continue to be available as aliases, for back-compat.
- Added `ReactionsRef.subscribe` which subscribes to the list of users who added a specific reaction onto a message
  - Added `SingleReactionSnapshot`, `ReactionsSubscription`, and `ReactionsActiveState`
- Added `ReactionRef.getFirstReactions` which is a simpler way to just fetch the first page of users who reacted with an emoji

### 1.8.3

- Fix an issue where year ranges such as `2010-2018` were being treated as phone numbers when content suppression was enabled

### 1.8.2

- Fix `Uncaught (in promise)` being logged, especially with react strict mode

### 1.8.1

- Calling `loadMore` on one subscription no longer affects other subscriptions
- While a `loadMore` request is in progress, you can now call `loadMore` again with a higher `count` to fetch a bigger page

### 1.8.0

- Added `ParticipantRef.subscribe` which lets you subscribe to a specific participant in a conversation
- Optimised `TalkSession.uploadFile` (and other upload methods) to check that a file will be accepted before uploading it. Previously it fully uploaded the file, then received the error.

### 1.7.0

- Added support for global message and conversation searching:
  - Added `SearchMessageSnapshot`, `MessageSearch`, `MessageSearchState`, `ConversationSearch`, and `ConversationSearchState`
  - Added `TalkSession.searchMessages(onResults: (results: SearchMessageSnapshot[], loadedAll: boolean) => void): MessageSearch`
  - Added `TalkSession.searchConversations(onResults: (results: ConversationSnapshot[], loadedAll: boolean) => void): ConversationSearch`

### 1.6.3

- "Ref" objects now maintain referential integrity. If you call `Session.conversation("123")` twice, in two different parts of your app, the same object will be reused both times.

### 1.6.2

- Made `locale` in `SetUserParams` nullable. Setting locale to `null` means the user will fall-back to the default locale set on the dashboard.
- Improved performance when repeatedly calling `ConversationRef.get()`.

### 1.6.1

- Fixed a bug where two authentication methods could be active at the same time, causing race conditions.
- Prevented switching to JWT authentication once connected to TalkJS servers. Your initial `setToken` or `onNeedToken` configuration must happen before the first requests / before mounting any UI components.
- Optimised initial WebSocket connection to happen in parallel with fetching token, to improve startup speed.

To use JWTs, call `setToken` or set `onNeedToken` before triggering any requests or mounting any components. We recommend setting up authentication in your app's entry point (App.jsx, main.js, or similar) so it runs first.

### 1.6.0

- Added `TalkSession.setToken(token: string)` which reauthenticates the session with a new token.
- Added `TalkSession.onNeedToken: () => void` which gets called whenever a new auth token is needed. To use refreshable auth tokens, set a callback that fetches a new auth token and passes it to `setToken`.
- Deprecated `token` and `tokenFetcher` options in `getTalkSession` in favour of those two properties.
- Removed some duplicate logging on auth-related errors.
- Sessions no longer get garbage collected under any circumstances (to enable persistence of `.setToken`).
- Initial token fetch is now delayed until you actually use the session to send a request, rather than happening as soon as you call `getTalkSession`.

### 1.5.9

- Fixed a bug that would make the library crash under certain conditions.

### 1.5.8

- Bugfix for React Native.

### 1.5.7

- Fixed a bug that would cause a crash in React Native.

### 1.5.6

- Bugfix for on-prem deployments, no impact on the SAAS offering.

### 1.5.5

- Marked snapshot properties as readonly and applied Object.freeze to snapshots. These were never intended to be editable, as the snapshots are reused and shared between sessions.
- Improved docs for `ConversationRef` to better explain the reason why `ConversationRef.set` adds you to the conversation.

### 1.5.4

- Fixed a bug that prevented the websocket from disconnecting when idle after unsubscribing.

### 1.5.3

- Fixed a bug where subscribing to a conversation's messages after previously subscribing to that conversation, could cause an error related to sequence numbers being out-of-order.

### 1.5.2

- Added `browser` field to `package.json`.

### 1.5.1

- When passing markup text to `ConversationRef.send`, it now ignores formatted links and action buttons/links. Previously it parsed those nodes and tried to send them, which caused an error because users do not have permission to send those nodes.

### 1.5.0

- Fixed a bug where `MessageRef.get()` would always set `MessageSnapshot.referencedMessage` to null
- Added support for getting and setting emoji reactions on messages.
  - Added `ReactionRef` which is created via `MessageRef.reaction`.
  - Added `ReactionSnapshot` which is available in `MessageSnapshot.reactions`.
- `Session.user`, `Session.conversation`, `ConversationRef.message`, `ConversationRef.participant`, and `MessageRef.reaction` now all perform type validation on the argument and will throw an error if you use an invalid type or an empty string.

### 1.4.2

- Changed `GenericFileBlock` from `subtype?: undefined` to `subtype?: never` so that type narrowing works consistently when you check `subtype === "<type>"`.

### 1.4.1

- Fixed an error when subscribing to a conversation while already subscribed to all conversations, or vice-versa.

### 1.4.0

- Added `UserRef.subscribeOnline` which subscribes to a user's online status.
  - Added `UserOnlineSnapshot`, `UserOnlineSubscription`, and `UserOnlineActiveState`.

### 1.3.0

- Added `TalkSession.subscribeConversations` which returns a windowed subscription to your most recently active conversations.
  - Added `ConversationListSubscription` and `ConversationListActiveState`.

### 1.2.0

- Added `ConversationRef.subscribeParticipants` which returns a windowed subscription to the participants in the conversation.
  - Added `ParticipantSubscription` and `ParticipantActiveState`.
- Improved startup time by sending queued requests faster when you first open the connection.

### 1.1.1

- Added `ConversationSnapshot.everyoneReadUntil` which is the minimum of all the participants' `readUntil` values.

### 1.1.0

- Added `ConversationRef.subscribeTyping` which lets you subscribe to typing indicators in a conversation.
  - Added `TypingSubscription`, `TypingSnapshot`, `ManyTypingSnapshot`, `FewTypingSnapshot`

### 1.0.1

- Fixed a bug with `ConversationRef.subscribe` where it would emit the same snapshot multiple times in a row, when old messages were edited or deleted.
- Exported types for `GenericFileMetadata`, `AudioFileMetadata`, `ImageFileMetadata`, `VideoFileMetadata`, and `VoiceRecordingFileMetadata`.

### 1.0.0

- Initial Release
