Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDK-3858] Add documentation for modular variant of library #1502

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ module.exports = {
"test",
"tools",
"scripts",
"docs",
"typedoc/generated",
"react",
"Gruntfile.js",
],
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ jobs:
- name: Upload Documentation
uses: ably/sdk-upload-action@v1
with:
sourcePath: docs/generated
sourcePath: typedoc/generated
githubToken: ${{ secrets.GITHUB_TOKEN }}
artifactName: typedoc
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ npm-debug.log
.tool-versions
build/
react/
docs/generated/
typedoc/generated/
lawrence-forooghian marked this conversation as resolved.
Show resolved Hide resolved
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,37 @@ WebPack will search your `node_modules` folder by default, so if you include `ab

If that doesn't work for some reason (e.g. you are using a custom webpack target), you can reference the `ably.js` static file directly: `require('ably/build/ably.js');` (or `import * as Ably from 'ably/build/ably.js'` for typescript / ES6 modules).

#### Modular (tree-shakable) variant

Aimed at those who are concerned about their app’s bundle size, the modular variant of the library allows you to create a client which has only the functionality that you choose. Unused functionality can then be tree-shaken by your module bundler.
owenpearson marked this conversation as resolved.
Show resolved Hide resolved

The modular variant of the library provides:

- a `BaseRealtime` class;
- various modules that add functionality to a `BaseRealtime` instance, such as `Rest`, `RealtimePresence`, etc.

To use this variant of the library, import the `BaseRealtime` class from `ably/modules`, along with the modules that you wish to use. Then, pass these modules to the `BaseRealtime` constructor as shown in the example below:

```javascript
import { BaseRealtime, WebSocketTransport, FetchRequest, RealtimePresence } from 'ably/modules';

const options = { key: 'YOUR_ABLY_API_KEY' /* Replace with a real key from the Ably dashboard */ };
const client = new BaseRealtime(options, {
WebSocketTransport,
FetchRequest,
RealtimePresence
});
```

You must provide:

- at least one HTTP request implementation; that is, one of `FetchRequest` or `XHRRequest`;
- at least one realtime transport implementation; that is, one of `WebSocketTransport`, `XHRStreaming`, or `XHRPolling`.

`BaseRealtime` offers the same API as the `Realtime` class described in the rest of this `README`. This means that you can develop an application using the default variant of the SDK and switch to the modular version when you wish to optimize your bundle size.

For more information, see the [generated documentation](https://sdk.ably.com/builds/ably/ably-js/main/typedoc/modules/index.html) (this link points to the documentation for the `main` branch).

### TypeScript

The TypeScript typings are included in the package and so all you have to do is:
Expand Down
2 changes: 2 additions & 0 deletions ably.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2219,6 +2219,8 @@
*/
subscribe(events: Array<string>, listener?: messageCallback<Message>): Promise<ChannelStateChange | null>;
/**
* {@label WITH_MESSAGE_FILTER}
*
* Registers a listener for messages on this channel that match the supplied filter.
*
* @param filter - A {@link MessageFilter}.
Expand Down Expand Up @@ -2312,8 +2314,8 @@
*/
get(name: string, channelOptions?: ChannelOptions): T;
/**
* @experimental This is a preview feature and may change in a future non-major release.

Check warning on line 2317 in ably.d.ts

View workflow job for this annotation

GitHub Actions / lint

Invalid JSDoc tag name "experimental"
* This experimental method allows you to create custom realtime data feeds by selectively subscribing

Check warning on line 2318 in ably.d.ts

View workflow job for this annotation

GitHub Actions / lint

Expected no lines between tags
* to receive only part of the data from the channel.
* See the [announcement post](https://pages.ably.com/subscription-filters-preview) for more information.
*
Expand Down
7 changes: 0 additions & 7 deletions docs/landing-page.md

This file was deleted.

214 changes: 214 additions & 0 deletions modules.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,249 @@ export declare const decodePresenceMessage: Types.PresenceMessageStatic['fromEnc
export declare const decodePresenceMessages: Types.PresenceMessageStatic['fromEncodedArray'];
export declare const constructPresenceMessage: Types.PresenceMessageStatic['fromValues'];

/**
* Provides REST-related functionality to a {@link BaseRealtime} client.
*
* To create a client that includes this module, include it in the `ModulesMap` that you pass to the {@link BaseRealtime.constructor}:
*
* ```javascript
* import { BaseRealtime, WebSocketTransport, FetchRequest, Rest } from 'ably/modules';
* const realtime = new BaseRealtime(options, { WebSocketTransport, FetchRequest, Rest });
* ```
*
* When provided, the following functionality becomes available:
*
* - { @link Types.Push | push admin }
* - { @link BaseRealtime.time | retrieving Ably service time }
* - { @link BaseRealtime.request | making arbitrary REST requests }
* - { @link BaseRealtime.batchPublish | batch publishing of messages }
* - { @link BaseRealtime.batchPresence | batch retrieval of channel presence state }
* - { @link Types.Auth.revokeTokens | requesting the revocation of tokens }
* - { @link Types.RealtimeChannel.history | retrieving the message history of a channel }
* - { @link Types.RealtimePresence.history | retrieving the presence history of a channel }
*
* If this module is not provided, then trying to use the above functionality will cause a runtime error.
*/
export declare const Rest: unknown;

/**
* Provides a {@link BaseRest} or {@link BaseRealtime} instance with the ability to encrypt and decrypt {@link Types.Message} payloads.
*
* To create a client that includes this module, include it in the `ModulesMap` that you pass to the {@link BaseRealtime.constructor}:
*
* ```javascript
* import { BaseRealtime, WebSocketTransport, FetchRequest, Crypto } from 'ably/modules';
* const realtime = new BaseRealtime(options, { WebSocketTransport, FetchRequest, Crypto });
* ```
*
* When provided, you can configure message encryption on a channel via the {@link Types.ChannelOptions.cipher} property of the `ChannelOptions` that you pass when {@link Types.Channels.get | fetching a channel}. If this module is not provided, then passing a `ChannelOptions` with a `cipher` property will cause a runtime error.
*/
export declare const Crypto: unknown;

/**
* Provides a {@link BaseRest} or {@link BaseRealtime} instance with the ability to communicate with the Ably service using the more space-efficient [MessagePack](https://msgpack.org/index.html) format.
*
* To create a client that includes this module, include it in the `ModulesMap` that you pass to the {@link BaseRealtime.constructor}:
*
* ```javascript
* import { BaseRealtime, WebSocketTransport, FetchRequest, MsgPack } from 'ably/modules';
* const realtime = new BaseRealtime(options, { WebSocketTransport, FetchRequest, MsgPack });
* ```
*
* When provided, you can control whether the client uses MessagePack via the {@link Types.ClientOptions.useBinaryProtocol} client option. If you do not provide this module, then the library will always JSON format for encoding messages.
*/
export declare const MsgPack: unknown;

/**
* Provides a {@link BaseRealtime} instance with the ability to interact with a channel’s presence set.
*
* To create a client that includes this module, include it in the `ModulesMap` that you pass to the {@link BaseRealtime.constructor}:
*
* ```javascript
* import { BaseRealtime, WebSocketTransport, FetchRequest, RealtimePresence } from 'ably/modules';
* const realtime = new BaseRealtime(options, { WebSocketTransport, FetchRequest, RealtimePresence });
* ```
*
* If you do not provide this module, then attempting to access a channel’s {@link Types.RealtimeChannel.presence} property will cause a runtime error.
*/
export declare const RealtimePresence: unknown;

/**
* Provides a {@link BaseRealtime} instance with the ability to establish a connection with the Ably realtime service using a [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) connection.
*
* To create a client that includes this module, include it in the `ModulesMap` that you pass to the {@link BaseRealtime.constructor}:
*
* ```javascript
* import { BaseRealtime, WebSocketTransport, FetchRequest } from 'ably/modules';
* const realtime = new BaseRealtime(options, { WebSocketTransport, FetchRequest });
* ```
*
* Note that network conditions, such as firewalls or proxies, might prevent the client from establishing a WebSocket connection. For this reason, you may wish to provide the `BaseRealtime` instance with the ability to alternatively establish a connection using a transport that is less susceptible to these external conditions. You do this by passing one or more alternative transport modules, namely {@link XHRStreaming} and/or {@link XHRPolling}, alongside `WebSocketTransport`:
*
* ```javascript
* import { BaseRealtime, WebSocketTransport, FetchRequest } from 'ably/modules';
* const realtime = new BaseRealtime(options, { WebSocketTransport, XHRStreaming, FetchRequest });
* ```
*/
export declare const WebSocketTransport: unknown;

/**
* Provides a {@link BaseRealtime} instance with the ability to establish a connection with the Ably realtime service using the browser’s [XMLHttpRequest API](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest).
*
* `XHRPolling` uses HTTP long polling; that is, it will make a new HTTP request each time a message is received from Ably. This is less efficient than {@link XHRStreaming}, but is also more likely to succeed in the presence of certain network conditions such as firewalls or proxies.
*
* ```javascript
* import { BaseRealtime, WebSocketTransport, FetchRequest } from 'ably/modules';
* const realtime = new BaseRealtime(options, { XHRPolling, FetchRequest });
* ```
*
* Provide this module if, for example, you wish the client to have an alternative mechanism for connecting to Ably if it’s unable to establish a WebSocket connection.
*/
export declare const XHRPolling: unknown;

/**
* Provides a {@link BaseRealtime} instance with the ability to establish a connection with the Ably realtime service using the browser’s [XMLHttpRequest API](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest).
*
* `XHRStreaming` uses HTTP streaming; that is, in contrast to {@link XHRPolling}, it does not need to make a new HTTP request each time a message is received from Ably. This is more efficient than `XHRPolling`, but is more likely to be blocked by certain network conditions such as firewalls or proxies.
*
* ```javascript
* import { BaseRealtime, WebSocketTransport, FetchRequest } from 'ably/modules';
* const realtime = new BaseRealtime(options, { XHRStreaming, FetchRequest });
* ```
*
* Provide this module if, for example, you wish the client to have an alternative mechanism for connecting to Ably if it’s unable to establish a WebSocket connection.
*/
export declare const XHRStreaming: unknown;

/**
* Provides a {@link BaseRest} or {@link BaseRealtime} instance with the ability to make HTTP requests using the browser’s [XMLHttpRequest API](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest).
*
* To create a client that includes this module, include it in the `ModulesMap` that you pass to the {@link BaseRealtime.constructor}:
*
* ```javascript
* import { BaseRealtime, WebSocketTransport, XHRRequest } from 'ably/modules';
* const realtime = new BaseRealtime(options, { WebSocketTransport, XHRRequest });
* ```
*/
export declare const XHRRequest: unknown;

/**
* Provides a {@link BaseRest} or {@link BaseRealtime} instance with the ability to make HTTP requests using the browser’s [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
*
* To create a client that includes this module, include it in the `ModulesMap` that you pass to the {@link BaseRealtime.constructor}:
*
* ```javascript
* import { BaseRealtime, WebSocketTransport, FetchRequest } from 'ably/modules';
* const realtime = new BaseRealtime(options, { WebSocketTransport, FetchRequest });
* ```
*/
export declare const FetchRequest: unknown;

/**
* Provides a {@link BaseRealtime} instance with the ability to filter channel subscriptions at runtime using { @link Types.RealtimeChannel.subscribe:WITH_MESSAGE_FILTER | the overload of `subscribe()` that accepts a `MessageFilter` }.
*
* To create a client that includes this module, include it in the `ModulesMap` that you pass to the {@link BaseRealtime.constructor}:
*
* ```javascript
* import { BaseRealtime, WebSocketTransport, FetchRequest, MessageInteractions } from 'ably/modules';
* const realtime = new BaseRealtime(options, { WebSocketTransport, FetchRequest, MessageInteractions });
* ```
*
* If you do not provide this module, then attempting to use this overload of `subscribe()` will cause a runtime error.
*/
export declare const MessageInteractions: unknown;

/**
* Pass a `ModulesMap` to { @link BaseRest.constructor | the constructor of BaseRest } or {@link BaseRealtime.constructor | that of BaseRealtime} to specify which functionality should be made available to that client.
*/
export interface ModulesMap {
/**
* See {@link Rest | documentation for the `Rest` module}.
*/
Rest?: typeof Rest;

/**
* See {@link Crypto | documentation for the `Crypto` module}.
*/
Crypto?: typeof Crypto;

/**
* See {@link MsgPack | documentation for the `MsgPack` module}.
*/
MsgPack?: typeof MsgPack;

/**
* See {@link RealtimePresence | documentation for the `RealtimePresence` module}.
*/
RealtimePresence?: typeof RealtimePresence;

/**
* See {@link WebSocketTransport | documentation for the `WebSocketTransport` module}.
*/
WebSocketTransport?: typeof WebSocketTransport;

/**
* See {@link XHRPolling | documentation for the `XHRPolling` module}.
*/
XHRPolling?: typeof XHRPolling;

/**
* See {@link XHRStreaming | documentation for the `XHRStreaming` module}.
*/
XHRStreaming?: typeof XHRStreaming;

/**
* See {@link XHRRequest | documentation for the `XHRRequest` module}.
*/
XHRRequest?: typeof XHRRequest;

/**
* See {@link FetchRequest | documentation for the `FetchRequest` module}.
*/
FetchRequest?: typeof FetchRequest;

/**
* See {@link MessageInteractions | documentation for the `MessageInteractions` module}.
*/
MessageInteractions?: typeof MessageInteractions;
}

/**
* A client that offers a simple stateless API to interact directly with Ably's REST API.
*
* `BaseRest` is the equivalent, in the modular variant of the Ably Client Library SDK, of the [`Rest`](../../default/classes/Rest.html) class in the default variant of the SDK. The difference is that its constructor allows you to decide exactly which functionality the client should include. This allows unused functionality to be tree-shaken, reducing bundle size.
*/
export declare class BaseRest extends Types.Rest {
/**
* Construct a client object using an Ably {@link Types.ClientOptions} object.
*
* @param options - A {@link Types.ClientOptions} object to configure the client connection to Ably.
* @param modules - An object which describes which functionality the client should offer. See the documentation for {@link ModulesMap}.
*
* You must provide at least one HTTP request implementation; that is, one of {@link FetchRequest} or {@link XHRRequest}. For minimum bundle size, favour `FetchRequest`.
*
* The {@link Rest} module is always implicitly included.
*/
constructor(options: Types.ClientOptions, modules: ModulesMap);
}

/**
* A client that extends the functionality of {@link BaseRest} and provides additional realtime-specific features.
*
* `BaseRealtime` is the equivalent, in the modular variant of the Ably Client Library SDK, of the [`Realtime`](../../default/classes/Realtime.html) class in the default variant of the SDK. The difference is that its constructor allows you to decide exactly which functionality the client should include. This allows unused functionality to be tree-shaken, reducing bundle size.
*/
export declare class BaseRealtime extends Types.Realtime {
/**
* Construct a client object using an Ably {@link Types.ClientOptions} object.
*
* @param options - A {@link Types.ClientOptions} object to configure the client connection to Ably.
* @param modules - An object which describes which functionality the client should offer. See the documentation for {@link ModulesMap}.
*
* You must provide:
*
* - at least one HTTP request implementation; that is, one of {@link FetchRequest} or {@link XHRRequest} — for minimum bundle size, favour `FetchRequest`;
* - at least one realtime transport implementation; that is, one of {@link WebSocketTransport}, {@link XHRStreaming}, or {@link XHRPolling} — for minimum bundle size, favour `WebSocketTransport`.
*/
constructor(options: Types.ClientOptions, modules: ModulesMap);
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,6 @@
"format:check": "prettier --check --ignore-path .gitignore --ignore-path .prettierignore src test ably.d.ts modules.d.ts webpack.config.js Gruntfile.js scripts/*.js",
"sourcemap": "source-map-explorer build/ably.min.js",
"modulereport": "node scripts/moduleReport.js",
"docs": "typedoc --entryPoints ably.d.ts --out docs/generated --readme docs/landing-page.md"
"docs": "typedoc --entryPoints ably.d.ts --out typedoc/generated/default --readme typedoc/landing-pages/default.md && typedoc --entryPoints modules.d.ts --out typedoc/generated/modules --name \"ably (modular version)\" --readme typedoc/landing-pages/modules.md && cp typedoc/landing-pages/choose-library.html typedoc/generated/index.html"
}
}
31 changes: 31 additions & 0 deletions typedoc/landing-pages/choose-library.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>Ably JavaScript Client Library SDK API Reference</title>
</head>
<body>
<h1>Ably JavaScript Client Library SDK API Reference</h1>

<p>
The JavaScript Client Library SDK supports a realtime and a REST interface. The JavaScript API references are generated from the <a href="https://github.com/ably/ably-js/">Ably JavaScript Client Library SDK source code</a> using <a href="https://typedoc.org">TypeDoc</a> and structured by classes.
</p>

<p>
The realtime interface enables a client to maintain a persistent connection to Ably and publish, subscribe and be present on channels. The REST interface is stateless and typically implemented server-side. It is used to make requests such as retrieving statistics, token authentication and publishing to a channel.
</p>

<p>
There are two variants of the Ably JavaScript Client Library SDK:

<ul>
<li><a href="default/index.html">Default variant</a>: This variant of the SDK always creates a fully-featured Ably client.</li>
<li><a href="modules/index.html">Modular (tree-shakable) variant</a>: Aimed at those who are concerned about their app’s bundle size, this allows you to create a client which has only the functionality that you choose.</li>
</ul>
</p>

<p>
View the <a href="https://ably.com/docs/">Ably docs</a> for conceptual information on using Ably, and for API references featuring all languages. The combined <a href="https://ably.com/docs/api/">API references</a> are organized by features and split between the <a href="https://ably.com/docs/api/realtime-sdk">realtime</a> and <a href="https://ably.com/docs/api/rest-sdk">REST</a> interfaces.
</p>
</body>
</html>
Loading
Loading