diff --git a/test/package/browser/template/README.md b/test/package/browser/template/README.md
index 8bf44061b..38f2e248d 100644
--- a/test/package/browser/template/README.md
+++ b/test/package/browser/template/README.md
@@ -8,6 +8,7 @@ This directory is intended to be used for testing the following aspects of the a
It contains three files, each of which import ably-js in different manners, and provide a way to briefly exercise its functionality:
- `src/index-default.ts` imports the default ably-js package (`import { Realtime } from 'ably'`).
+- `src/index-liveobjects.ts` imports the LiveObjects ably-js plugin (`import LiveObjects from 'ably/liveobjects'`).
- `src/index-modular.ts` imports the tree-shakable ably-js package (`import { BaseRealtime, WebSocketTransport, FetchRequest } from 'ably/modular'`).
- `src/ReactApp.tsx` imports React hooks from the ably-js package (`import { useChannel } from 'ably/react'`).
@@ -25,6 +26,7 @@ This directory exposes three package scripts that are to be used for testing:
- `build`: Uses esbuild to create:
1. a bundle containing `src/index-default.ts` and ably-js;
- 2. a bundle containing `src/index-modular.ts` and ably-js.
+ 2. a bundle containing `src/index-liveobjects.ts` and ably-js.
+ 3. a bundle containing `src/index-modular.ts` and ably-js.
- `test`: Using the bundles created by `build` and playwright components setup, tests that the code that exercises ably-js’s functionality is working correctly in a browser.
- `typecheck`: Type-checks the code that imports ably-js.
diff --git a/test/package/browser/template/package.json b/test/package/browser/template/package.json
index a05aa0497..f2c023b6e 100644
--- a/test/package/browser/template/package.json
+++ b/test/package/browser/template/package.json
@@ -4,7 +4,7 @@
"description": "",
"main": "index.js",
"scripts": {
- "build": "esbuild --bundle src/index-default.ts --outdir=dist && esbuild --bundle src/index-modular.ts --outdir=dist",
+ "build": "esbuild --bundle src/index-default.ts --outdir=dist && esbuild --bundle src/index-liveobjects.ts --outdir=dist && esbuild --bundle src/index-modular.ts --outdir=dist",
"typecheck": "tsc --project src -noEmit",
"test-support:server": "ts-node server/server.ts",
"test": "npm run test:lib && npm run test:hooks",
diff --git a/test/package/browser/template/server/resources/index-liveobjects.html b/test/package/browser/template/server/resources/index-liveobjects.html
new file mode 100644
index 000000000..b7f284af5
--- /dev/null
+++ b/test/package/browser/template/server/resources/index-liveobjects.html
@@ -0,0 +1,11 @@
+
+
+
+
+ Ably NPM package test (LiveObjects plugin export)
+
+
+
+
+
+
diff --git a/test/package/browser/template/server/server.ts b/test/package/browser/template/server/server.ts
index 2409fc30c..faa1399f7 100644
--- a/test/package/browser/template/server/server.ts
+++ b/test/package/browser/template/server/server.ts
@@ -5,7 +5,7 @@ async function startWebServer(listenPort: number) {
const server = express();
server.get('/', (req, res) => res.send('OK'));
server.use(express.static(path.join(__dirname, '/resources')));
- for (const filename of ['index-default.js', 'index-modular.js']) {
+ for (const filename of ['index-default.js', 'index-liveobjects.js', 'index-modular.js']) {
server.use(`/${filename}`, express.static(path.join(__dirname, '..', 'dist', filename)));
}
diff --git a/test/package/browser/template/src/index-liveobjects.ts b/test/package/browser/template/src/index-liveobjects.ts
new file mode 100644
index 000000000..9334aadf4
--- /dev/null
+++ b/test/package/browser/template/src/index-liveobjects.ts
@@ -0,0 +1,43 @@
+import * as Ably from 'ably';
+import LiveObjects from 'ably/liveobjects';
+import { createSandboxAblyAPIKey } from './sandbox';
+
+globalThis.testAblyPackage = async function () {
+ const key = await createSandboxAblyAPIKey({ featureFlags: ['enableChannelState'] });
+
+ const realtime = new Ably.Realtime({ key, environment: 'sandbox', plugins: { LiveObjects } });
+
+ const channel = realtime.channels.get('channel', { modes: ['STATE_SUBSCRIBE', 'STATE_PUBLISH'] });
+ // check liveObjects can be accessed
+ const liveObjects = channel.liveObjects;
+ await channel.attach();
+ // root should be a LiveMap object
+ const root: Ably.LiveMap = await liveObjects.getRoot();
+
+ // check root is recognized as LiveMap TypeScript type
+ root.get('someKey');
+ root.size();
+
+ // check LiveMap subscription callback has correct TypeScript types
+ const { unsubscribe } = root.subscribe(({ update }) => {
+ switch (update.someKey) {
+ case 'removed':
+ case 'updated':
+ break;
+ default:
+ // check all possible types are exhausted
+ const shouldExhaustAllTypes: never = update.someKey;
+ }
+ });
+ unsubscribe();
+
+ // check LiveCounter types also behave as expected
+ const counter = root.get('randomKey') as Ably.LiveCounter | undefined;
+ // use nullish coalescing as we didn't actually create a counter object on the root,
+ // so the next calls would fail. we only need to check that TypeScript types work
+ const value: number = counter?.value();
+ const counterSubscribeResponse = counter?.subscribe(({ update }) => {
+ const shouldBeANumber: number = update.inc;
+ });
+ counterSubscribeResponse?.unsubscribe();
+};
diff --git a/test/package/browser/template/src/sandbox.ts b/test/package/browser/template/src/sandbox.ts
index 100ab22f0..54c5f2e64 100644
--- a/test/package/browser/template/src/sandbox.ts
+++ b/test/package/browser/template/src/sandbox.ts
@@ -1,10 +1,14 @@
import testAppSetup from '../../../../common/ably-common/test-resources/test-app-setup.json';
-export async function createSandboxAblyAPIKey() {
+export async function createSandboxAblyAPIKey(withOptions?: object) {
+ const postData = {
+ ...testAppSetup.post_apps,
+ ...(withOptions ?? {}),
+ };
const response = await fetch('https://sandbox-rest.ably.io/apps', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(testAppSetup.post_apps),
+ body: JSON.stringify(postData),
});
if (!response.ok) {
diff --git a/test/package/browser/template/src/tsconfig.json b/test/package/browser/template/src/tsconfig.json
index e280baa6d..b206a6399 100644
--- a/test/package/browser/template/src/tsconfig.json
+++ b/test/package/browser/template/src/tsconfig.json
@@ -4,7 +4,7 @@
"resolveJsonModule": true,
"esModuleInterop": true,
"module": "esnext",
- "moduleResolution": "bundler",
+ "moduleResolution": "node",
"jsx": "react-jsx"
}
}
diff --git a/test/package/browser/template/test/lib/package.test.ts b/test/package/browser/template/test/lib/package.test.ts
index fc73006f3..8554dd762 100644
--- a/test/package/browser/template/test/lib/package.test.ts
+++ b/test/package/browser/template/test/lib/package.test.ts
@@ -3,6 +3,7 @@ import { test, expect } from '@playwright/test';
test.describe('NPM package', () => {
for (const scenario of [
{ name: 'default export', path: '/index-default.html' },
+ { name: 'LiveObjects plugin export', path: '/index-liveobjects.html' },
{ name: 'modular export', path: '/index-modular.html' },
]) {
test.describe(scenario.name, () => {