Skip to content

Commit

Permalink
Format all the Markdown in docs/
Browse files Browse the repository at this point in the history
  • Loading branch information
lawrence-forooghian committed Mar 13, 2024
1 parent 8ae753f commit 7fb2842
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 71 deletions.
25 changes: 15 additions & 10 deletions docs/react-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,47 @@ Since these hooks now return more values we've opted to change them to return ob
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 { channel, ably } = useChannel('your-channel-name', (message) => {
/* ... */
});

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

### Replacing `configureAbly` with `AblyProvider`
### 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>
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>
return (
<AblyProvider client={ably} id="foo">
{children}
</AblyProvider>
);

// in a child component:
useChannel({channelName: 'my_channel', id: 'foo'}, (msg) => {
useChannel({ channelName: 'my_channel', id: 'foo' }, (msg) => {
console.log(msg);
});
```
124 changes: 65 additions & 59 deletions docs/react.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ The hooks provide a simplified syntax for interacting with Ably, and manage the
- [useChannel](#usechannel)
- [usePresence](#usepresence)

<!-- /code_chunk_output -->
---
## <!-- /code_chunk_output -->

### Compatible React Versions

Expand All @@ -41,16 +40,16 @@ Start by connecting your app to Ably using the `AblyProvider` component. See the
The `AblyProvider` should be high in your component tree, wrapping every component which needs to access Ably.

```jsx
import { AblyProvider } from "ably/react";
import * as Ably from "ably";
import { AblyProvider } from 'ably/react';
import * as Ably from 'ably';

const client = new Ably.Realtime({ key: "your-ably-api-key", clientId: 'me' });
const client = new Ably.Realtime({ key: 'your-ably-api-key', clientId: 'me' });

root.render(
<AblyProvider client={client}>
<App />
</AblyProvider>
)
</AblyProvider>,
);
```

### Define Ably channels
Expand All @@ -66,8 +65,8 @@ Once you've set up `AblyProvider`, define Ably channels you want to use by utili
After setting up `ChannelProvider`, you can employ the provided `hooks` in your code. Here's a basic example:

```javascript
const { channel } = useChannel("your-channel-name", (message) => {
console.log(message);
const { channel } = useChannel('your-channel-name', (message) => {
console.log(message);
});
```

Expand Down Expand Up @@ -112,8 +111,8 @@ return (
The useChannel hook lets you subscribe to an [Ably Channel](https://ably.com/docs/channels) and receive messages from it.

```javascript
const { channel, ably } = useChannel("your-channel-name", (message) => {
console.log(message);
const { channel, ably } = useChannel('your-channel-name', (message) => {
console.log(message);
});
```

Expand All @@ -123,8 +122,8 @@ const { channel, ably } = useChannel("your-channel-name", (message) => {

```javascript
const [messages, updateMessages] = useState([]);
const { channel } = useChannel("your-channel-name", (message) => {
updateMessages((prev) => [...prev, message]);
const { channel } = useChannel('your-channel-name', (message) => {
updateMessages((prev) => [...prev, message]);
});

// Convert the messages to list items to render in a react component
Expand All @@ -134,8 +133,8 @@ const messagePreviews = messages.map((msg, index) => <li key={index}>{msg.data.s
`useChannel` supports all of the parameter combinations of a regular call to `channel.subscribe`, so you can filter the messages you subscribe to by providing a `message type` to the `useChannel` function:

```javascript
useChannel("your-channel-name", "test-message", (message) => {
console.log(message); // Only logs messages sent using the `test-message` message type
useChannel('your-channel-name', 'test-message', (message) => {
console.log(message); // Only logs messages sent using the `test-message` message type
});
```

Expand All @@ -144,8 +143,8 @@ useChannel("your-channel-name", "test-message", (message) => {
The `publish` function returned by `useChannel` can be used to send messages to the channel.

```javascript
const { publish } = useChannel("your-channel-name")
publish("test-message", { text: "message text" });
const { publish } = useChannel('your-channel-name');
publish('test-message', { text: 'message text' });
```

#### useChannel `channel` instance
Expand All @@ -157,13 +156,13 @@ By providing both the channel instance and the Ably SDK instance through our use
For instance, you can easily fetch the history of the channel using the following method:

```javascript
const { channel } = useChannel("your-channel-name", (message) => {
console.log(message);
const { channel } = useChannel('your-channel-name', (message) => {
console.log(message);
});

const history = channel.history((err, result) => {
var lastMessage = resultPage.items[0];
console.log('Last message: ' + lastMessage.id + ' - ' + lastMessage.data);
var lastMessage = resultPage.items[0];
console.log('Last message: ' + lastMessage.id + ' - ' + lastMessage.data);
});
```

Expand All @@ -173,60 +172,60 @@ const history = channel.history((err, result) => {

The usePresence hook lets you [subscribe to presence events on a channel](https://ably.com/docs/presence-occupancy/presence?lang=javascript#subscribe) - this will allow you to get notified when a user joins or leaves the channel. To find out more about Presence, see the [presence documentation](https://ably.com/docs/presence-occupancy/presence).

**Please note** that fetching present members is executed as an effect, so it'll load in *after* your component renders for the first time.
**Please note** that fetching present members is executed as an effect, so it'll load in _after_ your component renders for the first time.

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

// Convert presence data to list items to render
const peers = presenceData.map((msg, index) => <li key={index}>{msg.clientId}: {msg.data}</li>);
const peers = presenceData.map((msg, index) => (
<li key={index}>
{msg.clientId}: {msg.data}
</li>
));
```

`usePresence` returns an array of presence messages - again each message is a regular Ably JavaScript SDK `presenceMessage` instance.

You can optionally provide a string when you `usePresence` to set an initial `presence data` string.

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

// The `updateStatus` function can be used to update the presence data for the current client
updateStatus("new status");
updateStatus('new status');
```

The new state will be sent to the channel, and any other clients subscribed to the channel will be notified of the change immediately.

If you don't want to use the `presenceData` returned from usePresence, you can configure a callback

```javascript
const { updateStatus } = usePresence("your-channel-name", "initial state", (presenceUpdate) => {
console.log(presenceUpdate);
const { updateStatus } = usePresence('your-channel-name', 'initial state', (presenceUpdate) => {
console.log(presenceUpdate);
});
```

usePresence supports objects, as well as strings

```javascript
usePresence("your-channel-name", { foo: "bar" });
usePresence('your-channel-name', { foo: 'bar' });
```

and if you're using `TypeScript` there are type hints to make sure that updates are of the same `type` as your initial constraint, or a provided generic type parameter:

```tsx
const TypedUsePresenceComponent = () => {
// In this example MyPresenceType will be checked - if omitted, the shape of the initial
// value will be used ...and if that's omitted, `any` will be the default.
// In this example MyPresenceType will be checked - if omitted, the shape of the initial
// value will be used ...and if that's omitted, `any` will be the default.

const { val } = usePresence<MyPresenceType>("testChannelName", { foo: "bar" });
const { val } = usePresence<MyPresenceType>('testChannelName', { foo: 'bar' });

return (
<div role='presence'>
{JSON.stringify(val)}
</div>
);
}
return <div role="presence">{JSON.stringify(val)}</div>;
};

interface MyPresenceType {
foo: string;
foo: string;
}
```

Expand All @@ -238,10 +237,10 @@ The `useConnectionStateListener` hook lets you attach a listener to be notified

```javascript
useConnectionStateListener((stateChange) => {
console.log(stateChange.current) // the new connection state
console.log(stateChange.previous) // the previous connection state
console.log(stateChange.reason) // if applicable, an error indicating the reason for the connection state change
})
console.log(stateChange.current); // the new connection state
console.log(stateChange.previous); // the previous connection state
console.log(stateChange.reason); // if applicable, an error indicating the reason for the connection state change
});
```

You can also pass in a filter to only listen to a set of connection states:
Expand All @@ -257,10 +256,10 @@ The `useChannelStateListener` hook lets you attach a listener to be notified of

```javascript
useChannelStateListener((stateChange) => {
console.log(stateChange.current) // the new channel state
console.log(stateChange.previous) // the previous channel state
console.log(stateChange.reason) // if applicable, an error indicating the reason for the channel state change
})
console.log(stateChange.current); // the new channel state
console.log(stateChange.previous); // the previous channel state
console.log(stateChange.reason); // if applicable, an error indicating the reason for the channel state change
});
```

You can also pass in a filter to only listen to a set of channel states:
Expand Down Expand Up @@ -294,18 +293,25 @@ if (connectionError) {
} else if (channelError) {
// TODO: handle channel errors
} else {
return <AblyChannelComponent />
return <AblyChannelComponent />;
}
```

Alternatively, you can also pass callbacks to the hooks to be called when the client encounters an error:

```js
useChannel({
channelName: 'my_channel',
onConnectionError: (err) => { /* handle connection error */ },
onChannelError: (err) => { /* handle channel error */ },
}, messageHandler);
useChannel(
{
channelName: 'my_channel',
onConnectionError: (err) => {
/* handle connection error */
},
onChannelError: (err) => {
/* handle channel error */
},
},
messageHandler,
);
```

### Usage with multiple clients
Expand All @@ -318,8 +324,8 @@ root.render(
<AblyProvider client={client2} ablyId={'providerTwo'}>
<App />
</AblyProvider>
</AblyProvider>
)
</AblyProvider>,
);
```

This `ablyId` can then be passed in to each hook to specify which client to use.
Expand Down Expand Up @@ -370,9 +376,9 @@ module.exports = {
webpack: (config) => {
config.externals.push({
'utf-8-validate': 'commonjs utf-8-validate',
'bufferutil': 'commonjs bufferutil',
})
return config
bufferutil: 'commonjs bufferutil',
});
return config;
},
}
};
```
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"prepare": "npm run build",
"format": "prettier --write --ignore-path .gitignore --ignore-path .prettierignore src test ably.d.ts modular.d.ts webpack.config.js Gruntfile.js scripts/*.[jt]s docs/chrome-mv3.md grunt",
"format:check": "prettier --check --ignore-path .gitignore --ignore-path .prettierignore src test ably.d.ts modular.d.ts webpack.config.js Gruntfile.js scripts/*.[jt]s docs/chrome-mv3.md grunt",
"format": "prettier --write --ignore-path .gitignore --ignore-path .prettierignore src test ably.d.ts modular.d.ts webpack.config.js Gruntfile.js scripts/*.[jt]s docs/**/*.md grunt",
"format:check": "prettier --check --ignore-path .gitignore --ignore-path .prettierignore src test ably.d.ts modular.d.ts webpack.config.js Gruntfile.js scripts/*.[jt]s docs/**/*.md grunt",
"sourcemap": "source-map-explorer build/ably.min.js",
"modulereport": "tsc --noEmit --esModuleInterop scripts/moduleReport.ts && esr scripts/moduleReport.ts",
"docs": "typedoc"
Expand Down

0 comments on commit 7fb2842

Please sign in to comment.