useTransportStatus

The useTransportStatus hook reports whether the transport has seen a discontinuity, and the latest error it reported that has no caller to reject. A discontinuity is a channel state change after which messages may have been missed.

JavaScript

1

2

3

4

5

6

7

8

9

import { useTransportStatus } from '@ably/ai-transport/react';

function Status() {
  const { discontinuity, error } = useTransportStatus();

  if (error) return <p>Something went wrong: {error.message}</p>;
  if (discontinuity) return <p>Reconnected. Catching up.</p>;
  return null;
}

This hook must be used within a TransportProvider.

To read whether the channel is attached, use useChannelStateListener from ably/react, which works inside the provider.

discontinuity stays true once it is set. To recover after every discontinuity, listen with transport.on('discontinuity') and subscribe again from the serial of the last message you received, as the example shows.

Parameters

channelNameoptionalString
The channel name of the provider to read. Omit it to read the nearest provider.

The hook throws an ErrorInfo with InvalidArgument when no matching TransportProvider encloses the component.

Returns

discontinuityBoolean
true once the transport has reported a discontinuity. It resets when the provider creates a new transport.
errorErrorInfo or undefined
The latest error the transport reported with no caller to reject, such as a failed attach or a codec that threw while decoding, or undefined.

Example

A component replays the conversation from the stored serial when it loads. After each discontinuity, it subscribes again from the serial of the last message it received.

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

import { useEffect, useRef } from 'react';
import { fromSerial } from '@ably/ai-transport';
import { useTransport, useTransportStatus } from '@ably/ai-transport/react';

function Conversation({ storedSerial, render }) {
  const { transport } = useTransport();
  const { discontinuity } = useTransportStatus();
  const lastSeen = useRef(storedSerial);

  useEffect(() => {
    if (!transport) return;
    const apply = (delivery) => {
      render(delivery);
      if (delivery.message.serial > lastSeen.current) lastSeen.current = delivery.message.serial;
    };
    const subscribeFrom = (serial) => transport.subscribe(apply, serial ? { history: { replay: fromSerial(serial) } } : undefined);

    let unsubscribe = subscribeFrom(lastSeen.current);
    const off = transport.on('discontinuity', () => {
      unsubscribe();
      unsubscribe = subscribeFrom(lastSeen.current);
    });
    return () => {
      off();
      unsubscribe();
    };
  }, [transport, render]);

  return discontinuity ? <p>Reconnected.</p> : null;
}