Skip to content

Commit

Permalink
Merge branch 'main' into liveobjects/2024-11-29-merge-main
Browse files Browse the repository at this point in the history
  • Loading branch information
VeskeR committed Nov 29, 2024
2 parents 3adafa5 + 416c9b0 commit 0575e5e
Show file tree
Hide file tree
Showing 24 changed files with 749 additions and 422 deletions.
2 changes: 1 addition & 1 deletion .mocharc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const config = {
// if you've defined specs in your config. therefore we work around it by only adding specs to the
// config if none are passed as arguments
if (!process.argv.slice(2).some(isTestFile)) {
config.spec = ['test/realtime/*.test.js', 'test/rest/*.test.js'];
config.spec = ['test/realtime/*.test.js', 'test/rest/*.test.js', 'test/unit/*.test.js'];
}

function isTestFile(arg) {
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

This contains only the most important and/or user-facing changes; for a full changelog, see the commit history.

## [2.5.0](https://github.com/ably/ably-js/tree/2.5.0) (2024-11-06)

With this release, ably-js will now expose the new `Message` attributes needed to support upcoming features,
such as updates, deletions and annotations in the Ably service.

- Added support for new `Message` attributes. [\#1888](https://github.com/ably/ably-js/pull/1888)

## [2.4.1](https://github.com/ably/ably-js/tree/2.4.1) (2024-10-04)

- Fix `usePresence` hook wasn't leaving presence if component unmounted during channel attaching state [\#1884](https://github.com/ably/ably-js/pull/1884)

## [2.4.0](https://github.com/ably/ably-js/tree/2.4.0) (2024-09-11)

- Add `wsConnectivityCheckUrl` client option [\#1862](https://github.com/ably/ably-js/pull/1862)
Expand Down
9 changes: 1 addition & 8 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,7 @@ module.exports = function (grunt) {
});
});

grunt.registerTask('build', [
'checkGitSubmodules',
'webpack:all',
'build:browser',
'build:node',
'build:push',
'build:liveobjects',
]);
grunt.registerTask('build', ['webpack:all', 'build:browser', 'build:node', 'build:push', 'build:liveobjects']);

grunt.registerTask('all', ['build', 'requirejs']);

Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,26 @@ The issue is coming from the fact that when using App Router specifically depend
Using `serverComponentsExternalPackages` opt-outs from using Next.js bundling for specific packages and uses native Node.js `require` instead.
This is a common problem in App Router for a number of packages (for example, see next.js issue [vercel/next.js#52876](https://github.com/vercel/next.js/issues/52876)), and using `serverComponentsExternalPackages` is the recommended approach here.
#### "Connection limit exceeded" error during development
If you're encountering a "Connection limit exceeded" error when trying to connect to Ably servers during the development of your application, and you notice spikes or linear increases in the connection count on the Ably dashboard for your app, this may be due to one of the following reasons:
- If you're using Next.js, your `Ably.Realtime` client instance may be created multiple times on the server side (i.e., in a Node.js process) as you're developing your app, due to Next.js server side rendering your components. Note that even for "Client Components" (i.e., components with the 'use client' directive), [Next.js may still run the component code on the server in order to pre-render HTML](https://nextjs.org/docs/app/building-your-application/rendering/client-components#how-are-client-components-rendered). Depending on your client configuration options, those clients may also successfully open a connection to Ably servers from that Node.js process, which won't close until you restart your development server.
The simplest fix is to use the `autoConnect` client option and check if the client is created on the server side with a simple window object check, like this:
```typescript
const client = new Ably.Realtime({ key: 'your-ably-api-key', autoConnect: typeof window !== 'undefined' });
```
This will prevent the client from connecting to Ably servers if it is created on the server side, while not affecting your client side components.
- If you're using any React-based framework, you may be recreating the `Ably.Realtime` client instance on every component re-render. To avoid this, and to prevent potentially reaching the maximum connections limit on your account, move the client instantiation (`new Ably.Realtime`) outside of your components. You can find an example in our [React docs](./docs/react.md#Usage).
- The connection limit error can be caused by the Hot Reloading mechanism of your development environment (called Fast Refresh in newer Next.js versions, or more generally, Hot Module Replacement - HMR). When you edit and save a file that contains a `new Ably.Realtime()` call in an environment that supports HMR (such as React, Vite, or Next.js apps), the file gets refreshed and creates a new `Ably.Realtime` client instance. However, the previous client remains in memory, unaware of the replacement, and stays connected to Ably's realtime systems. As a result, your connection count will keep increasing with each file edit as new clients are created. This only resets when you manually refresh the browser page, which closes all clients. This behavior applies to any development environment with an HMR mechanism implemented.
The solution is simple: move the `new Ably.Realtime()` call to a separate file, such as `ably-client.js`, and export the client instance from there. This way, the client instance will only be recreated when you specifically make changes to the `ably-client.js` file, which should be far less frequent than changes in the rest of the codebase.
## Contributing
For guidance on how to contribute to this project, see the [CONTRIBUTING.md](CONTRIBUTING.md).
Expand Down
95 changes: 93 additions & 2 deletions ably.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2308,7 +2308,6 @@ export declare interface Channels<T> {
* This experimental method allows you to create custom realtime data feeds by selectively subscribing
* to receive only part of the data from the channel.
* See the [announcement post](https://pages.ably.com/subscription-filters-preview) for more information.
*
* @param name - The channel name.
* @param deriveOptions - A {@link DeriveOptions} object.
* @param channelOptions - A {@link ChannelOptions} object.
Expand Down Expand Up @@ -2359,12 +2358,104 @@ export interface Message {
* Timestamp of when the message was received by Ably, as milliseconds since the Unix epoch.
*/
timestamp?: number;
/**
* The action type of the message, one of the {@link MessageAction} enum values.
*/
action?: MessageAction;
/**
* This message's unique serial.
*/
serial?: string;
/**
* The serial of the message that this message is a reference to.
*/
refSerial?: string;
/**
* The type of reference this message is, in relation to the message it references.
*/
refType?: string;
/**
* If an `update` operation was applied to this message, this will be the timestamp the update occurred.
*/
updatedAt?: number;
/**
* The serial of the operation that updated this message.
*/
updateSerial?: string;
/**
* If this message resulted from an operation, this will contain the operation details.
*/
operation?: Operation;
}

/**
* Contains the details of an operation, such as update or deletion, supplied by the actioning client.
*/
export interface Operation {
/**
* The client ID of the client that initiated the operation.
*/
clientId?: string;
/**
* The description provided by the client that initiated the operation.
*/
description?: string;
/**
* A JSON object of string key-value pairs that may contain metadata associated with the operation.
*/
metadata?: Record<string, string>;
}

/**
* The namespace containing the different types of message actions.
*/
declare namespace MessageActions {
/**
* Message action has not been set.
*/
type MESSAGE_UNSET = 'message.unset';
/**
* Message action for a newly created message.
*/
type MESSAGE_CREATE = 'message.create';
/**
* Message action for an updated message.
*/
type MESSAGE_UPDATE = 'message.update';
/**
* Message action for a deleted message.
*/
type MESSAGE_DELETE = 'message.delete';
/**
* Message action for a newly created annotation.
*/
type ANNOTATION_CREATE = 'annotation.create';
/**
* Message action for a deleted annotation.
*/
type ANNOTATION_DELETE = 'annotation.delete';
/**
* Message action for a meta-message that contains channel occupancy information.
*/
type META_OCCUPANCY = 'meta.occupancy';
}

/**
* Describes the possible action types used on an {@link Message}.
*/
export type MessageAction =
| MessageActions.MESSAGE_UNSET
| MessageActions.MESSAGE_CREATE
| MessageActions.MESSAGE_UPDATE
| MessageActions.MESSAGE_DELETE
| MessageActions.ANNOTATION_CREATE
| MessageActions.ANNOTATION_DELETE
| MessageActions.META_OCCUPANCY;

/**
* A message received from Ably.
*/
export type InboundMessage = Message & Required<Pick<Message, 'id' | 'timestamp'>>;
export type InboundMessage = Message & Required<Pick<Message, 'id' | 'timestamp' | 'serial' | 'action'>>;

/**
* Static utilities related to messages.
Expand Down
1 change: 1 addition & 0 deletions docs/react.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ The hooks are compatible with all versions of React above 16.8.0
Start by connecting your app to Ably using the `AblyProvider` component. See the [`ClientOptions` documentation](https://ably.com/docs/api/realtime-sdk/types?lang=javascript) for information about what options are available when creating an Ably client. If you want to use the `usePresence` or `usePresenceListener` hooks, you'll need to explicitly provide a `clientId`.

The `AblyProvider` should be high in your component tree, wrapping every component which needs to access Ably.
Also, ensure that the `Ably.Realtime` instance is created outside of components to prevent it from being recreated on component re-renders. This will help avoid opening extra unnecessary connections to the Ably servers and potentially reaching the maximum connections limit on your account.

```jsx
import { AblyProvider } from 'ably/react';
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ably",
"description": "Realtime client library for Ably, the realtime messaging service",
"version": "2.4.0",
"version": "2.5.0",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/ably/ably-js/issues",
Expand Down Expand Up @@ -146,6 +146,7 @@
"grunt": "grunt",
"test": "npm run test:node",
"test:node": "npm run build:node && npm run build:push && npm run build:liveobjects && mocha",
"test:grep": "npm run build:node && npm run build:push && npm run build:liveobjects && mocha --grep",
"test:node:skip-build": "mocha",
"test:webserver": "grunt test:webserver",
"test:playwright": "node test/support/runPlaywrightTests.js",
Expand Down
2 changes: 2 additions & 0 deletions src/common/lib/client/defaultrealtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import RealtimePresence from './realtimepresence';
import { DefaultPresenceMessage } from '../types/defaultpresencemessage';
import WebSocketTransport from '../transport/websockettransport';
import { FilteredSubscriptions } from './filteredsubscriptions';
import { PresenceMap } from './presencemap';
import {
fromValues as presenceMessageFromValues,
fromValuesArray as presenceMessagesFromValuesArray,
Expand Down Expand Up @@ -69,4 +70,5 @@ export class DefaultRealtime extends BaseRealtime {

// Used by tests
static _Http = Http;
static _PresenceMap = PresenceMap;
}
Loading

0 comments on commit 0575e5e

Please sign in to comment.