Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into 2023-11-01-merge-main…
Browse files Browse the repository at this point in the history
…-into-v2

Other than fixing merge conflicts, the notable changes which bring the
recently-added stuff in `main` in line with the changes from v2 are:

- Removing mentions of the `ably/promises` and `Realtime.Promise` API
  from the React hooks code and documentation

- Updating presence message extras test to use the promise-based API

- Fixing a newly-introduced compilation error calling
  `wsConnection.send` in WebSocketTransport (not sure exactly why, but
  I’m guessing something to do with the upgrade to the `ws` library in
  `main`) — the fix, which uses a type assertion to always pretend we’re
  always in the Node case, is a bit dodgy but that’s because the signature
  of `ProtocolMessage.serialize` is also a bit dodgy (it refers to Buffer
  even though the code that uses it is also called on web).

The package-lock.json merge conflicts were handled by fixing the
package.json merge conflicts then running `npm install --lockfile-version 2`
using Node 16.20.0. Using Node 18.18.2 seemed to lead to a lockfile that
caused an error "@esbuild/android-arm not accessible from esbuild" when
running `npm ci` in the Node 12 and 14 CI jobs.
  • Loading branch information
lawrence-forooghian committed Nov 3, 2023
2 parents 1b49159 + e3e6781 commit 304be22
Show file tree
Hide file tree
Showing 63 changed files with 12,378 additions and 4,867 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ module.exports = {
"tools",
"scripts",
"docs",
"react",
"Gruntfile.js",
],
settings: {
Expand Down
22 changes: 1 addition & 21 deletions .github/workflows/publish-cdn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,6 @@ on:

jobs:
publish:
runs-on: ubuntu-latest
# These permissions are necessary to run the configure-aws-credentials action
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.inputs.version }}
- uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: arn:aws:iam::${{ secrets.ABLY_AWS_ACCOUNT_ID_PRODUCTION }}:role/github-actions-sdk
aws-region: us-east-1
- name: Use Node.js 14.x
uses: actions/setup-node@v1
with:
node-version: 14.x
- run: npm ci
- run: node scripts/cdn_deploy.js --skipCheckout --tag=${{ github.event.inputs.version }}
publish_sdk:
runs-on: ubuntu-latest
# These permissions are necessary to run the configure-aws-credentials action
permissions:
Expand All @@ -48,4 +28,4 @@ jobs:
with:
node-version: 14.x
- run: npm ci
- run: node scripts/cdn_deploy.js --bucket prod-cdn.ably.com --skipCheckout --tag=${{ github.event.inputs.version }}
- run: node scripts/cdn_deploy.js --skipCheckout --tag=${{ github.event.inputs.version }}
20 changes: 20 additions & 0 deletions .github/workflows/react.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Test (react hooks)

on:
workflow_dispatch:
pull_request:
push:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 16
- run: npm ci
- run: npm run format:check
- run: npm run test:react
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ node_modules
npm-debug.log
.tool-versions
build/
react/
docs/generated/
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@

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

## [1.2.46](https://github.com/ably/ably-js/tree/1.2.46) (2023-10-24)

- fix: avoid directly exporting Ably.ErrorInfo from promises.js [\#1463](https://github.com/ably/ably-js/pull/1463)
- fix(react): add missing id param for `useStateErrors` call to `useChannelStateListener` [\#1455](https://github.com/ably/ably-js/pull/1455)
- fix: allow `RealtimePresence#leave` to take `PresenceMessage` as argument [\#1466](https://github.com/ably/ably-js/pull/1466)
- deps: bump ws to 8.14.2 [\#1467](https://github.com/ably/ably-js/pull/1467)

## [1.2.45](https://github.com/ably/ably-js/tree/1.2.45) (2023-09-25)

- remove `AblyProvider` options prop [\#1446](https://github.com/ably/ably-js/pull/1446)
- fix: throw descriptive error when callbacks used with react [\#1450](https://github.com/ably/ably-js/pull/1450)

## [1.2.44](https://github.com/ably/ably-js/tree/1.2.44) (2023-09-04)

- Add new experimental react hooks and context provider [\#1433](https://github.com/ably/ably-js/pull/1433)
- Export the `ErrorInfo` class [\#1430](https://github.com/ably/ably-js/pull/1430)

## [1.2.43](https://github.com/ably/ably-js/tree/1.2.43) (2023-08-10)

- Add REST APIs for batch publishing, batch presence, and token revocation [\#1410](https://github.com/ably/ably-js/pull/1410)
- Add support for presence message extras [\#1418](https://github.com/ably/ably-js/pull/1418)

## [1.2.42](https://github.com/ably/ably-js/tree/1.2.42) (2023-07-24)

- Auth: remain connected upon failed authorize unless returning explicit 403 [\#1385](https://github.com/ably/ably-js/pull/1385)
Expand Down
37 changes: 29 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@
2. Create a new branch for the release, for example `release/1.2.3`
3. Update the CHANGELOG.md with any customer-affecting changes since the last release and add this to the git index
4. Run `npm version <VERSION_NUMBER> --no-git-tag-version` with the new version and add the changes to the git index
5. Create a PR for the release branch
6. Once the release PR is landed to the `main` branch, checkout the `main` branch locally (remember to pull the remote changes) and run `npm run build`
7. Run `git tag <VERSION_NUMBER>` with the new version and push the tag to git
8. Run `npm publish .` (should require OTP) - publishes to NPM
9. Run the GitHub action "Publish to CDN" with the new tag name
10. Visit https://github.com/ably/ably-js/tags and add release notes to the release (generally you can just copy the notes you added to the CHANGELOG)
11. For nontrivial releases: update the ably-js submodule ref in the realtime repo
12. Update the [Ably Changelog](https://changelog.ably.com/) (via [headwayapp](https://headwayapp.co/)) with these changes (again, you can just copy the notes you added to the CHANGELOG)
5. Update the version number to the new version in `src/platform/react-hooks/src/AblyReactHooks.ts`
6. Create a PR for the release branch
7. Once the release PR is landed to the `main` branch, checkout the `main` branch locally (remember to pull the remote changes) and run `npm run build`
8. Run `git tag <VERSION_NUMBER>` with the new version and push the tag to git
9. Run `npm publish .` (should require OTP) - publishes to NPM
10. Run the GitHub action "Publish to CDN" with the new tag name
11. Visit https://github.com/ably/ably-js/tags and add release notes to the release (generally you can just copy the notes you added to the CHANGELOG)
12. For nontrivial releases: update the ably-js submodule ref in the realtime repo
13. Update the [Ably Changelog](https://changelog.ably.com/) (via [headwayapp](https://headwayapp.co/)) with these changes (again, you can just copy the notes you added to the CHANGELOG)

## Building the library

Expand Down Expand Up @@ -107,3 +108,23 @@ When using the test webserver `npm run test:webserver` the following test variab
- `tls_port` - TLS port to use for the tests, defaults to 443
- `tls` - true or false to enable/disable use of TLS respectively
- `log_level` - Log level for the client libraries, defaults to 2, 4 is `MICRO`

## React hooks

The react sample application is configured to execute using Vite - which will load a sample web app that acts as a simple test harness for the hooks.

You can run the dev server from the terminal using:

```bash
npm run start:react
```

You'll need to provide an API key for the sample to work (or you'll just get a white page and some errors in the console). To do this, create the file `./src/platform/react-hooks/sample-app/.env` and add the following line:

```.env
VITE_ABLY_API_KEY=<your-api-key>
```

This API key will be loaded by the vite dev server at build time.

You can run the unit tests by running `npm run test:react` in the terminal.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@ This SDK supports the following platforms:

**Node.js:** version 8.17 or newer. (1.1.x versions work on Node.js 4.5 or newer). We do not currently provide an ESM bundle, please [contact us](https://www.ably.com/contact) if you would would like to use ably-js in a NodeJS ESM project.

**React (release candidate)** We offer a set of React Hooks which make it seamless to use ably-js in your React application. See the [React Hooks documentation](./docs/react.md) for more details.

**React Native:** We aim to support all platforms supported by React Native. If you find any issues please raise an issue or [contact us](https://www.ably.com/contact).

**NativeScript:** see [ably-js-nativescript](https://github.com/ably/ably-js-nativescript)

**TypeScript:** see [below](#typescript)

**WebWorkers**: We build a separate bundle which supports running in a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) context. You can import it like this:

```js
import Ably from 'ably/build/ably-webworker.min';
```
Expand Down Expand Up @@ -231,7 +234,7 @@ can use

```javascript
await channel.presence.enterClient('myClientId', 'status');
// and similiarly, updateClient and leaveClient
// and similarly, updateClient and leaveClient
```

### Querying the Presence History
Expand Down
33 changes: 32 additions & 1 deletion ably.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ declare namespace Types {
/**
* A generic Ably error object that contains an Ably-specific status code, and a generic status code. Errors returned from the Ably server are compatible with the `ErrorInfo` structure and should result in errors that inherit from `ErrorInfo`.
*/
interface ErrorInfo extends Error {
class ErrorInfo extends Error {
/**
* Ably [error code](https://github.com/ably/ably-common/blob/main/protocol/errors.json).
*/
Expand All @@ -745,6 +745,20 @@ declare namespace Types {
* HTTP Status Code corresponding to this error, where applicable.
*/
statusCode: number;
/**
* The underlying cause of the error, where applicable.
*/
cause?: string | Error | ErrorInfo;

/**
* Construct an ErrorInfo object.
*
* @param message - A string describing the error.
* @param code - Ably [error code](https://github.com/ably/ably-common/blob/main/protocol/errors.json).
* @param statusCode - HTTP Status Code corresponding to this error.
* @param cause - The underlying cause of the error.
*/
constructor(message: string, code: number, statusCode: number, cause?: string | Error | ErrorInfo);
}

/**
Expand Down Expand Up @@ -2495,6 +2509,10 @@ declare namespace Types {
* This will typically be empty as all presence messages received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the data payload.
*/
encoding: string;
/**
* A JSON object of arbitrary key-value pairs that may contain metadata, and/or ancillary payloads. Valid payloads include `headers`.
*/
extras: any;
/**
* A unique ID assigned to each `PresenceMessage` by Ably.
*/
Expand Down Expand Up @@ -2523,6 +2541,14 @@ declare namespace Types {
* @param channelOptions - A {@link ChannelOptions} object containing the cipher.
*/
fromEncodedArray: (JsonArray: any[], channelOptions?: ChannelOptions) => Promise<PresenceMessage[]>;

/**
* Initialises a `PresenceMessage` from a `PresenceMessage`-like object.
*
* @param values - The values to intialise the `PresenceMessage` from.
* @param stringifyAction - Whether to convert the `action` field from a number to a string.
*/
fromValues(values: PresenceMessage | Record<string, unknown>, stringifyAction?: boolean): PresenceMessage;
}

/**
Expand Down Expand Up @@ -2871,3 +2897,8 @@ export declare class Rest extends Types.Rest {}
* A client that extends the functionality of {@link Rest} and provides additional realtime-specific features.
*/
export declare class Realtime extends Types.Realtime {}

/**
* A generic Ably error object that contains an Ably-specific status code, and a generic status code. Errors returned from the Ably server are compatible with the `ErrorInfo` structure and should result in errors that inherit from `ErrorInfo`.
*/
export declare class ErrorInfo extends Types.ErrorInfo {}
50 changes: 50 additions & 0 deletions docs/react-migration-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# React hooks upgrade / migration guide

## Version 2.x to 3.x

### Hooks now return object

In previous versions of our react hooks, the `useChannel` and `usePresence` hooks returned arrays.
Since these hooks now return more values we've opted to change them to return objects.
You can still access the return values using simple destructuring syntax like in the below example:

```jsx
const { channel, ably } = useChannel("your-channel-name", (message) => { /* ... */ });

const { presenceData, updateStatus } = usePresence("your-channel-name");
```

### Replacing `configureAbly` with `AblyProvider`

In versions 1 and 2 of our react-hooks, we exported a function called `configureAbly` which was used to register an Ably client instance to global state.
This caused a few issues (most notably it made the hooks difficult to use with hot module reloading), so we have replaced the global configuration function with a context provider (`AblyProvider`)
The simplest way to use the context provider is to create your own ably-js client outside and then pass it as a prop to the `AblyProvider`.
All child components of the `AblyProvider` will then be able to use the hooks, making use of the provided Ably client instance. For this reason, we recommend putting the `AblyProvider` high up in your component tree, surrounding all components which may need to use Ably hooks.

For example, replace this:
```jsx
configureAbly(options);
```

With this:
```jsx
const client = new Ably.Realtime(options);

return <AblyProvider client={ably}>
{children}
</AblyProvider>
```

If you were already using multiple Ably clients in the same react application, you may pass in an optional `id` prop to the provider, which you can then pass to the hooks to specify which Ably client instance the hook should use:
```jsx
const client = new Ably.Realtime(options);

return <AblyProvider client={ably} id="foo">
{children}
</AblyProvider>

// in a child component:
useChannel({channelName: 'my_channel', id: 'foo'}, (msg) => {
console.log(msg);
});
```
Loading

0 comments on commit 304be22

Please sign in to comment.