From 8cb26c601f7bb2358cb6dfa4a52e6d3c0256d047 Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 17 Sep 2026 12:08:50 +0100 Subject: [PATCH 1/2] feat!: build the SDK against @ably/pubsub-core ably-js v3 splits the `ably` package into a shared core plus a per-runtime client. The Spaces SDK is a library, not an end-user client, so it takes the core: `@ably/pubsub-core` replaces `ably` as the peer dependency, pinned to the exact canary 3.0.0-canary.20260917T1031.521a3374 because canary tags move and no semver range will resolve to a pre-release. Every `ably` type import becomes `@ably/pubsub-core`, and the IIFE bundle externalises the new specifier onto the same `Ably` global, so the CDN build keeps working unchanged. Two v3 renames reach the test harness: - `Rest` is now `Http`, so the vitest manual mock takes `Http.PresenceMessage` for the `fromValues` helper. The mock directory moves to `__mocks__/@ably/pubsub-core` to match the scoped specifier vitest now resolves. - `ClientOptions.environment` is gone, replaced by `endpoint` and its routing policies. The integration tests and the CDN bundle test therefore ask for `nonprod:sandbox`, and sandbox app provisioning moves to sandbox.realtime.ably-nonprod.net to match, which is what ably-js itself now does. Without both, a sandbox key is offered to production and every connection fails with a 40400. The integration tests construct their clients with `createClient` from `@ably/pubsub-device` rather than the now-deprecated `Realtime` constructor, since they stand in for device-side consumers; it is a dev dependency only and never reaches the published package. Co-Authored-By: Claude Opus 5 (1M context) --- .../{ably => @ably/pubsub-core}/index.ts | 4 +- package-lock.json | 128 +++++++++--------- package.json | 3 +- rollup.config.mjs | 4 +- src/CursorBatching.ts | 2 +- src/CursorHistory.ts | 2 +- src/Cursors.test.ts | 4 +- src/Cursors.ts | 2 +- src/Errors.ts | 2 +- src/Locations.test.ts | 4 +- src/Locks.test.ts | 4 +- src/Locks.ts | 2 +- src/Members.test.ts | 4 +- src/Space.test.ts | 4 +- src/Space.ts | 2 +- src/SpaceUpdate.ts | 2 +- src/Spaces.test.ts | 4 +- src/Spaces.ts | 2 +- src/react/useChannelState.ts | 4 +- src/react/useConnectionState.ts | 2 +- src/react/useCursors.test.tsx | 6 +- src/react/useCursors.ts | 2 +- src/react/useEventListener.ts | 10 +- src/react/useLocations.test.tsx | 6 +- src/react/useLocks.test.tsx | 6 +- src/react/useMembers.test.tsx | 6 +- src/react/useMembers.ts | 2 +- src/react/useSpace.test.tsx | 4 +- src/react/useSpace.ts | 2 +- src/types.ts | 2 +- src/utilities/test/fakes.ts | 2 +- src/utilities/types.ts | 2 +- test/cdn-bundle/resources/test.html | 4 +- test/integration/utilities/setup.ts | 6 +- test/lib/ablySandbox.ts | 2 +- 35 files changed, 124 insertions(+), 123 deletions(-) rename __mocks__/{ably => @ably/pubsub-core}/index.ts (94%) diff --git a/__mocks__/ably/index.ts b/__mocks__/@ably/pubsub-core/index.ts similarity index 94% rename from __mocks__/ably/index.ts rename to __mocks__/@ably/pubsub-core/index.ts index a3c455ba..3622fd34 100644 --- a/__mocks__/ably/index.ts +++ b/__mocks__/@ably/pubsub-core/index.ts @@ -1,4 +1,4 @@ -import { PresenceMessage, Rest, ErrorInfo } from 'ably'; +import { PresenceMessage, Http, ErrorInfo } from '@ably/pubsub-core'; const MOCK_CLIENT_ID = 'MOCK_CLIENT_ID'; @@ -95,6 +95,6 @@ class MockErrorInfo extends ErrorInfo {} // maintain the PresenceMessage class so tests can initialise it directly using // PresenceMessage.fromValues. -MockRealtime.PresenceMessage = Rest.PresenceMessage; +MockRealtime.PresenceMessage = Http.PresenceMessage; export { MockRealtime as Realtime, MockErrorInfo as ErrorInfo }; diff --git a/package-lock.json b/package-lock.json index 0416a14c..c1e1b551 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "nanoid": "^3.3.11" }, "devDependencies": { + "@ably/pubsub-device": "3.0.0-canary.20260917T1031.521a3374", "@playwright/test": "^1.53.0", "@rollup/plugin-node-resolve": "^15.3.1", "@rollup/plugin-terser": "^1.0.0", @@ -38,7 +39,7 @@ "vitest": "^3.2.3" }, "peerDependencies": { - "ably": "^2.3.0", + "@ably/pubsub-core": "3.0.0-canary.20260917T1031.521a3374", "react": ">=16.8.0", "react-dom": ">=16.8.0" }, @@ -55,11 +56,64 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/@ably/msgpack-js/-/msgpack-js-0.4.0.tgz", "integrity": "sha512-IPt/BoiQwCWubqoNik1aw/6M/DleMdrxJOUpSja6xmMRbT2p1TA8oqKWgfZabqzrq8emRNeSl/+4XABPNnW5pQ==", - "peer": true, "dependencies": { "bops": "^1.0.1" } }, + "node_modules/@ably/pubsub-core": { + "version": "3.0.0-canary.20260917T1031.521a3374", + "resolved": "https://registry.npmjs.org/@ably/pubsub-core/-/pubsub-core-3.0.0-canary.20260917T1031.521a3374.tgz", + "integrity": "sha512-9ZaMCA3ID1Xw7AtkiB/TeytffbXeTVetpPQtWkH7IvyU62w8d+T3MQHAVb1bIgo6HrvFBooKrzQx0e89ZE5R7w==", + "license": "Apache-2.0", + "dependencies": { + "@ably/msgpack-js": "^0.4.0", + "dequal": "^2.0.3", + "fastestsmallesttextencoderdecoder": "^1.0.22", + "got": "^11.8.5", + "ulid": "^2.3.0", + "ws": "^8.17.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/@ably/pubsub-device": { + "version": "3.0.0-canary.20260917T1031.521a3374", + "resolved": "https://registry.npmjs.org/@ably/pubsub-device/-/pubsub-device-3.0.0-canary.20260917T1031.521a3374.tgz", + "integrity": "sha512-lGmu5B9ncJRb2YH5SyVOeMDBui+ouiyiZe/67bqsgqsVAM2N0Ra+CoMhp5PfVspsZpy/c95zg1Q2XhNtAt5PmA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@ably/pubsub-core": "3.0.0-canary.20260917T1031.521a3374" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -1440,7 +1494,6 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "peer": true, "engines": { "node": ">=10" }, @@ -1452,7 +1505,6 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "peer": true, "dependencies": { "defer-to-connect": "^2.0.0" }, @@ -1551,7 +1603,6 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "peer": true, "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", @@ -1629,8 +1680,7 @@ "node_modules/@types/http-cache-semantics": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "peer": true + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" }, "node_modules/@types/http-errors": { "version": "2.0.5", @@ -1648,7 +1698,6 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "peer": true, "dependencies": { "@types/node": "*" } @@ -1714,7 +1763,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", - "peer": true, "dependencies": { "@types/node": "*" } @@ -2141,35 +2189,6 @@ "deprecated": "Use your platform's native atob() and btoa() methods instead", "dev": true }, - "node_modules/ably": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/ably/-/ably-2.9.0.tgz", - "integrity": "sha512-ddaurgvYHGmVVZkd5U2xJgLrbVdtAIw1RunfuZroE/ZTsmK2+vUnAZ7aKhR20cwOFP3QyLFYs6IfvwaijnIPlA==", - "peer": true, - "dependencies": { - "@ably/msgpack-js": "^0.4.0", - "dequal": "^2.0.3", - "fastestsmallesttextencoderdecoder": "^1.0.22", - "got": "^11.8.5", - "ulid": "^2.3.0", - "ws": "^8.17.1" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -2497,7 +2516,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.0.2.tgz", "integrity": "sha512-ZXBDPMt/v/8fsIqn+Z5VwrhdR6jVka0bYobHdGia0Nxi7BJ9i/Uvml3AocHIBtIIBhZjBw5MR0aR4ROs/8+SNg==", - "peer": true, "engines": { "node": ">= 0.4" } @@ -2579,7 +2597,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/bops/-/bops-1.0.1.tgz", "integrity": "sha512-qCMBuZKP36tELrrgXpAfM+gHzqa0nLsWZ+L37ncsb8txYlnAoxOPpVp+g7fK0sGkMXfA0wl8uQkESqw3v4HNag==", - "peer": true, "dependencies": { "base64-js": "1.0.2", "to-utf8": "0.0.1" @@ -2637,7 +2654,6 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "peer": true, "engines": { "node": ">=10.6.0" } @@ -2646,7 +2662,6 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "peer": true, "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -2763,7 +2778,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "peer": true, "dependencies": { "mimic-response": "^1.0.0" }, @@ -2989,7 +3003,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "peer": true, "dependencies": { "mimic-response": "^3.1.0" }, @@ -3004,7 +3017,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "peer": true, "engines": { "node": ">=10" }, @@ -3073,7 +3085,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "peer": true, "engines": { "node": ">=10" } @@ -3134,7 +3145,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "peer": true, "engines": { "node": ">=6" } @@ -3235,7 +3245,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "peer": true, "dependencies": { "once": "^1.4.0" } @@ -3999,8 +4008,7 @@ "node_modules/fastestsmallesttextencoderdecoder": { "version": "1.0.22", "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", - "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==", - "peer": true + "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==" }, "node_modules/fastq": { "version": "1.19.1", @@ -4288,7 +4296,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -4397,7 +4404,6 @@ "version": "11.8.6", "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "peer": true, "dependencies": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", @@ -4533,8 +4539,7 @@ "node_modules/http-cache-semantics": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", - "peer": true + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==" }, "node_modules/http-errors": { "version": "2.0.0", @@ -4570,7 +4575,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "peer": true, "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" @@ -5362,7 +5366,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "peer": true, "engines": { "node": ">=8" } @@ -5584,7 +5587,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "peer": true, "engines": { "node": ">=4" } @@ -5666,7 +5668,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "peer": true, "engines": { "node": ">=10" }, @@ -5845,7 +5846,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "peer": true, "engines": { "node": ">=8" } @@ -6173,7 +6173,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "peer": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -6244,7 +6243,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "peer": true, "engines": { "node": ">=10" }, @@ -6419,8 +6417,7 @@ "node_modules/resolve-alpn": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "peer": true + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" }, "node_modules/resolve-from": { "version": "4.0.0", @@ -6435,7 +6432,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "peer": true, "dependencies": { "lowercase-keys": "^2.0.0" }, @@ -7386,8 +7382,7 @@ "node_modules/to-utf8": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/to-utf8/-/to-utf8-0.0.1.tgz", - "integrity": "sha512-zks18/TWT1iHO3v0vFp5qLKOG27m67ycq/Y7a7cTiRuUNlc4gf3HGnkRgMv0NyhnfTamtkYBJl+YeD1/j07gBQ==", - "peer": true + "integrity": "sha512-zks18/TWT1iHO3v0vFp5qLKOG27m67ycq/Y7a7cTiRuUNlc4gf3HGnkRgMv0NyhnfTamtkYBJl+YeD1/j07gBQ==" }, "node_modules/toidentifier": { "version": "1.0.1", @@ -7656,7 +7651,6 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/ulid/-/ulid-2.4.0.tgz", "integrity": "sha512-fIRiVTJNcSRmXKPZtGzFQv9WRrZ3M9eoptl/teFJvjOzmpU+/K/JH6HZ8deBfb5vMEpicJcLn7JmvdknlMq7Zg==", - "peer": true, "bin": { "ulid": "bin/cli.js" } diff --git a/package.json b/package.json index 6082e924..1cb778c9 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ }, "keywords": [], "devDependencies": { + "@ably/pubsub-device": "3.0.0-canary.20260917T1031.521a3374", "@playwright/test": "^1.53.0", "@rollup/plugin-node-resolve": "^15.3.1", "@rollup/plugin-terser": "^1.0.0", @@ -67,7 +68,7 @@ "nanoid": "^3.3.11" }, "peerDependencies": { - "ably": "^2.3.0", + "@ably/pubsub-core": "3.0.0-canary.20260917T1031.521a3374", "react": ">=16.8.0", "react-dom": ">=16.8.0" }, diff --git a/rollup.config.mjs b/rollup.config.mjs index 313b7b5e..f846a53a 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -8,11 +8,11 @@ export default { name: 'Spaces', file: 'dist/iife/index.bundle.js', globals: { - ably: 'Ably', + '@ably/pubsub-core': 'Ably', }, compact: true, plugins: [terser()], }, - external: ['ably'], + external: ['@ably/pubsub-core'], plugins: [nodeResolve({ browser: true })], }; diff --git a/src/CursorBatching.ts b/src/CursorBatching.ts index d782b786..649fc0b2 100644 --- a/src/CursorBatching.ts +++ b/src/CursorBatching.ts @@ -1,4 +1,4 @@ -import { RealtimeChannel } from 'ably'; +import { RealtimeChannel } from '@ably/pubsub-core'; import { CURSOR_UPDATE } from './CursorConstants.js'; import type { CursorUpdate } from './types.js'; diff --git a/src/CursorHistory.ts b/src/CursorHistory.ts index 580226d1..ac644036 100644 --- a/src/CursorHistory.ts +++ b/src/CursorHistory.ts @@ -1,4 +1,4 @@ -import { InboundMessage, PaginatedResult, RealtimeChannel } from 'ably'; +import { InboundMessage, PaginatedResult, RealtimeChannel } from '@ably/pubsub-core'; import type { CursorUpdate } from './types.js'; import type { CursorsOptions } from './types.js'; diff --git a/src/Cursors.test.ts b/src/Cursors.test.ts index 383f4ae8..f4d68515 100644 --- a/src/Cursors.test.ts +++ b/src/Cursors.test.ts @@ -1,5 +1,5 @@ import { it, describe, expect, vi, beforeEach, vitest, afterEach } from 'vitest'; -import { Realtime, RealtimeClient, RealtimeChannel } from 'ably'; +import { Realtime, RealtimeClient, RealtimeChannel } from '@ably/pubsub-core'; import Space from './Space.js'; import Cursors from './Cursors.js'; @@ -25,7 +25,7 @@ interface CursorsTestContext { fakeMessageStub: RealtimeInboundMessage; } -vi.mock('ably'); +vi.mock('@ably/pubsub-core'); function createPresenceCount(length: number) { return async () => Array.from({ length }, (_, i) => createPresenceMessage('enter', { clientId: '' + i })); diff --git a/src/Cursors.ts b/src/Cursors.ts index 8cf17a16..106e815b 100644 --- a/src/Cursors.ts +++ b/src/Cursors.ts @@ -1,4 +1,4 @@ -import { RealtimeChannel } from 'ably'; +import { RealtimeChannel } from '@ably/pubsub-core'; import Space from './Space.js'; import CursorBatching from './CursorBatching.js'; diff --git a/src/Errors.ts b/src/Errors.ts index 5572191b..fb2d8a8c 100644 --- a/src/Errors.ts +++ b/src/Errors.ts @@ -1,4 +1,4 @@ -import { ErrorInfo } from 'ably'; +import { ErrorInfo } from '@ably/pubsub-core'; export const ERR_SPACE_NAME_MISSING = () => new ErrorInfo('must have a non-empty name for the space', 101000, 400); diff --git a/src/Locations.test.ts b/src/Locations.test.ts index c5509e3d..1a2c61f1 100644 --- a/src/Locations.test.ts +++ b/src/Locations.test.ts @@ -1,5 +1,5 @@ import { it, describe, expect, vi, beforeEach } from 'vitest'; -import { PresenceMessage, Realtime, RealtimeClient, RealtimePresence } from 'ably'; +import { PresenceMessage, Realtime, RealtimeClient, RealtimePresence } from '@ably/pubsub-core'; import Space from './Space.js'; @@ -17,7 +17,7 @@ interface SpaceTestContext { presenceMap: Map; } -vi.mock('ably'); +vi.mock('@ably/pubsub-core'); vi.mock('nanoid'); describe('Locations', () => { diff --git a/src/Locks.test.ts b/src/Locks.test.ts index 409bf00a..76c847d3 100644 --- a/src/Locks.test.ts +++ b/src/Locks.test.ts @@ -1,5 +1,5 @@ import { it, describe, expect, vi, beforeEach } from 'vitest'; -import { PresenceMessage, Realtime, RealtimeClient, RealtimePresence } from 'ably'; +import { PresenceMessage, Realtime, RealtimeClient, RealtimePresence } from '@ably/pubsub-core'; import Space from './Space.js'; import type { SpaceMember, LockStatus } from './types.js'; @@ -12,7 +12,7 @@ interface SpaceTestContext { presenceMap: Map; } -vi.mock('ably'); +vi.mock('@ably/pubsub-core'); describe('Locks', () => { beforeEach((context) => { diff --git a/src/Locks.ts b/src/Locks.ts index 8d73a21f..45b77702 100644 --- a/src/Locks.ts +++ b/src/Locks.ts @@ -1,4 +1,4 @@ -import { PresenceMessage } from 'ably'; +import { PresenceMessage } from '@ably/pubsub-core'; import Space from './Space.js'; import type { Lock, SpaceMember } from './types.js'; diff --git a/src/Members.test.ts b/src/Members.test.ts index 2cb1b853..94f0eb2f 100644 --- a/src/Members.test.ts +++ b/src/Members.test.ts @@ -1,5 +1,5 @@ import { it, describe, expect, vi, beforeEach, afterEach } from 'vitest'; -import { PresenceMessage, Realtime, RealtimeClient, RealtimePresence } from 'ably'; +import { PresenceMessage, Realtime, RealtimeClient, RealtimePresence } from '@ably/pubsub-core'; import Space from './Space.js'; @@ -12,7 +12,7 @@ interface SpaceTestContext { presenceMap: Map; } -vi.mock('ably'); +vi.mock('@ably/pubsub-core'); vi.mock('nanoid'); describe('Members', () => { diff --git a/src/Space.test.ts b/src/Space.test.ts index b6adfaa3..ecb8a88e 100644 --- a/src/Space.test.ts +++ b/src/Space.test.ts @@ -1,5 +1,5 @@ import { it, describe, expect, vi, beforeEach, expectTypeOf } from 'vitest'; -import { PresenceMessage, Realtime, RealtimeClient, RealtimePresence } from 'ably'; +import { PresenceMessage, Realtime, RealtimeClient, RealtimePresence } from '@ably/pubsub-core'; import Space from './Space.js'; import Locations from './Locations.js'; @@ -20,7 +20,7 @@ interface SpaceTestContext { presenceMap: Map; } -vi.mock('ably'); +vi.mock('@ably/pubsub-core'); vi.mock('nanoid'); describe('Space', () => { diff --git a/src/Space.ts b/src/Space.ts index 2e505dee..89096e82 100644 --- a/src/Space.ts +++ b/src/Space.ts @@ -1,4 +1,4 @@ -import { PresenceMessage, Realtime, RealtimeClient, RealtimeChannel } from 'ably'; +import { PresenceMessage, Realtime, RealtimeClient, RealtimeChannel } from '@ably/pubsub-core'; import EventEmitter, { InvalidArgumentError, inspect, type EventListener } from './utilities/EventEmitter.js'; import Locations from './Locations.js'; diff --git a/src/SpaceUpdate.ts b/src/SpaceUpdate.ts index 91e646a8..9a7ab353 100644 --- a/src/SpaceUpdate.ts +++ b/src/SpaceUpdate.ts @@ -1,5 +1,5 @@ import { nanoid } from 'nanoid'; -import { PresenceMessage } from 'ably'; +import { PresenceMessage } from '@ably/pubsub-core'; import type { SpaceMember, ProfileData } from './types.js'; import type { PresenceMember } from './utilities/types.js'; diff --git a/src/Spaces.test.ts b/src/Spaces.test.ts index 326fa4c8..a73b21a9 100644 --- a/src/Spaces.test.ts +++ b/src/Spaces.test.ts @@ -1,5 +1,5 @@ import { it, describe, expect, expectTypeOf, vi, beforeEach } from 'vitest'; -import { Realtime, RealtimeClient } from 'ably'; +import { Realtime, RealtimeClient } from '@ably/pubsub-core'; import Spaces, { type ClientWithOptions } from './Spaces.js'; @@ -7,7 +7,7 @@ interface SpacesTestContext { client: ClientWithOptions; } -vi.mock('ably'); +vi.mock('@ably/pubsub-core'); describe('Spaces', () => { beforeEach((context) => { diff --git a/src/Spaces.ts b/src/Spaces.ts index 1ffe3bef..bda4e3fb 100644 --- a/src/Spaces.ts +++ b/src/Spaces.ts @@ -1,4 +1,4 @@ -import { RealtimeClient, Connection } from 'ably'; +import { RealtimeClient, Connection } from '@ably/pubsub-core'; import { ERR_SPACE_NAME_MISSING } from './Errors.js'; import Space from './Space.js'; diff --git a/src/react/useChannelState.ts b/src/react/useChannelState.ts index 44c1bdf0..7a44f2a3 100644 --- a/src/react/useChannelState.ts +++ b/src/react/useChannelState.ts @@ -1,7 +1,7 @@ import { useState } from 'react'; import { useEventListener } from './useEventListener.js'; -import type { ChannelState, ChannelStateChange, ErrorInfo, EventEmitter } from 'ably'; +import type { ChannelState, ChannelStateChange, ErrorInfo, EventEmitter } from '@ably/pubsub-core'; type ChannelStateListener = (stateChange: ChannelStateChange) => void; @@ -9,7 +9,7 @@ const failedStateEvents: ChannelState[] = ['suspended', 'failed', 'detached']; const successStateEvents: ChannelState[] = ['attached']; /** - * todo use `ably/react` hooks instead + * todo use `@ably/pubsub-core/react` hooks instead */ export const useChannelState = ( emitter?: EventEmitter, diff --git a/src/react/useConnectionState.ts b/src/react/useConnectionState.ts index 4b5315b9..ab2c5230 100644 --- a/src/react/useConnectionState.ts +++ b/src/react/useConnectionState.ts @@ -1,7 +1,7 @@ import { useState } from 'react'; import { useEventListener } from './useEventListener.js'; -import type { ConnectionState, ConnectionStateChange, ErrorInfo, EventEmitter } from 'ably'; +import type { ConnectionState, ConnectionStateChange, ErrorInfo, EventEmitter } from '@ably/pubsub-core'; type ConnectionStateListener = (stateChange: ConnectionStateChange) => void; diff --git a/src/react/useCursors.test.tsx b/src/react/useCursors.test.tsx index 766df2af..e292709f 100644 --- a/src/react/useCursors.test.tsx +++ b/src/react/useCursors.test.tsx @@ -3,7 +3,7 @@ */ import React from 'react'; -import { Realtime } from 'ably'; +import { Realtime } from '@ably/pubsub-core'; import { it, beforeEach, describe, expect, vi } from 'vitest'; import { waitFor, renderHook, act } from '@testing-library/react'; import { SpacesProvider } from './contexts/SpacesContext.js'; @@ -12,7 +12,7 @@ import Spaces from '../index.js'; import Space from '../Space.js'; import { createPresenceEvent } from '../utilities/test/fakes.js'; import { useCursors } from './useCursors.js'; -import type { PresenceMessage } from 'ably'; +import type { PresenceMessage } from '@ably/pubsub-core'; interface SpaceTestContext { spaces: Spaces; @@ -20,7 +20,7 @@ interface SpaceTestContext { presenceMap: Map; } -vi.mock('ably'); +vi.mock('@ably/pubsub-core'); vi.mock('nanoid'); describe('useCursors', () => { diff --git a/src/react/useCursors.ts b/src/react/useCursors.ts index 72fd9b28..2d36feaf 100644 --- a/src/react/useCursors.ts +++ b/src/react/useCursors.ts @@ -6,7 +6,7 @@ import { useConnectionState } from './useConnectionState.js'; import { isFunction } from '../utilities/is.js'; import type { CursorUpdate, SpaceMember } from '../types.js'; -import type { ErrorInfo } from 'ably'; +import type { ErrorInfo } from '@ably/pubsub-core'; import type Cursors from '../Cursors.js'; import type { UseSpaceOptions } from './types.js'; import type { Space } from '..'; diff --git a/src/react/useEventListener.ts b/src/react/useEventListener.ts index d999e9b8..5cbe0ded 100644 --- a/src/react/useEventListener.ts +++ b/src/react/useEventListener.ts @@ -1,11 +1,17 @@ import { useEffect, useRef } from 'react'; -import type { ChannelState, ChannelStateChange, ConnectionState, ConnectionStateChange, EventEmitter } from 'ably'; +import type { + ChannelState, + ChannelStateChange, + ConnectionState, + ConnectionStateChange, + EventEmitter, +} from '@ably/pubsub-core'; type EventListener = (stateChange: T) => void; /** - * todo use `ably/react` hooks instead + * todo use `@ably/pubsub-core/react` hooks instead */ export const useEventListener = < S extends ConnectionState | ChannelState, diff --git a/src/react/useLocations.test.tsx b/src/react/useLocations.test.tsx index 2167571e..6f895721 100644 --- a/src/react/useLocations.test.tsx +++ b/src/react/useLocations.test.tsx @@ -3,12 +3,12 @@ */ import React from 'react'; -import { Realtime } from 'ably'; +import { Realtime } from '@ably/pubsub-core'; import { it, beforeEach, describe, expect, vi } from 'vitest'; import { waitFor, renderHook } from '@testing-library/react'; import { SpacesProvider } from './contexts/SpacesContext.js'; import { SpaceProvider } from './contexts/SpaceContext.js'; -import type { PresenceMessage } from 'ably'; +import type { PresenceMessage } from '@ably/pubsub-core'; import Spaces from '../index.js'; import { createLocationUpdate, createPresenceEvent } from '../utilities/test/fakes.js'; import Space from '../Space.js'; @@ -20,7 +20,7 @@ interface SpaceTestContext { presenceMap: Map; } -vi.mock('ably'); +vi.mock('@ably/pubsub-core'); vi.mock('nanoid'); describe('useLocations', () => { diff --git a/src/react/useLocks.test.tsx b/src/react/useLocks.test.tsx index ba27abfd..e8dcbc4a 100644 --- a/src/react/useLocks.test.tsx +++ b/src/react/useLocks.test.tsx @@ -3,12 +3,12 @@ */ import React from 'react'; -import { Realtime } from 'ably'; +import { Realtime } from '@ably/pubsub-core'; import { it, beforeEach, describe, expect, vi } from 'vitest'; import { waitFor, renderHook } from '@testing-library/react'; import { SpacesProvider } from './contexts/SpacesContext.js'; import { SpaceProvider } from './contexts/SpaceContext.js'; -import type { PresenceMessage } from 'ably'; +import type { PresenceMessage } from '@ably/pubsub-core'; import Spaces from '../index.js'; import { createPresenceEvent } from '../utilities/test/fakes.js'; import Space from '../Space.js'; @@ -20,7 +20,7 @@ interface SpaceTestContext { presenceMap: Map; } -vi.mock('ably'); +vi.mock('@ably/pubsub-core'); vi.mock('nanoid'); describe('useLocks', () => { diff --git a/src/react/useMembers.test.tsx b/src/react/useMembers.test.tsx index 44cf7cc7..541b2c4d 100644 --- a/src/react/useMembers.test.tsx +++ b/src/react/useMembers.test.tsx @@ -3,12 +3,12 @@ */ import React from 'react'; -import { Realtime } from 'ably'; +import { Realtime } from '@ably/pubsub-core'; import { it, beforeEach, describe, expect, vi } from 'vitest'; import { waitFor, renderHook } from '@testing-library/react'; import { SpacesProvider } from './contexts/SpacesContext.js'; import { SpaceProvider } from './contexts/SpaceContext.js'; -import type { PresenceMessage } from 'ably'; +import type { PresenceMessage } from '@ably/pubsub-core'; import Spaces from '../index.js'; import { useMembers } from './useMembers.js'; import { createLocationUpdate, createPresenceEvent } from '../utilities/test/fakes.js'; @@ -20,7 +20,7 @@ interface SpaceTestContext { presenceMap: Map; } -vi.mock('ably'); +vi.mock('@ably/pubsub-core'); vi.mock('nanoid'); describe('useMembers', () => { diff --git a/src/react/useMembers.ts b/src/react/useMembers.ts index 43da8b34..2a2eb96a 100644 --- a/src/react/useMembers.ts +++ b/src/react/useMembers.ts @@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from 'react'; import { useSpace } from './useSpace.js'; import { isArray, isFunction, isString } from '../utilities/is.js'; -import type { ErrorInfo } from 'ably'; +import type { ErrorInfo } from '@ably/pubsub-core'; import type { Space, SpaceMember } from '..'; import type { UseSpaceOptions } from './types.js'; import type { MembersEventMap } from '../Members.js'; diff --git a/src/react/useSpace.test.tsx b/src/react/useSpace.test.tsx index af12bd6a..b50be18c 100644 --- a/src/react/useSpace.test.tsx +++ b/src/react/useSpace.test.tsx @@ -3,7 +3,7 @@ */ import React from 'react'; -import { Realtime } from 'ably'; +import { Realtime } from '@ably/pubsub-core'; import { it, beforeEach, describe, expect, vi } from 'vitest'; import { waitFor, renderHook } from '@testing-library/react'; import { SpacesProvider } from './contexts/SpacesContext.js'; @@ -15,7 +15,7 @@ interface SpaceTestContext { spaces: Spaces; } -vi.mock('ably'); +vi.mock('@ably/pubsub-core'); vi.mock('nanoid'); describe('useSpace', () => { diff --git a/src/react/useSpace.ts b/src/react/useSpace.ts index edc34135..c655c0e5 100644 --- a/src/react/useSpace.ts +++ b/src/react/useSpace.ts @@ -3,7 +3,7 @@ import { SpaceContext } from './contexts/SpaceContext.js'; import { useChannelState } from './useChannelState.js'; import { useConnectionState } from './useConnectionState.js'; -import type { ErrorInfo } from 'ably'; +import type { ErrorInfo } from '@ably/pubsub-core'; import type { Space } from '..'; import type { UseSpaceCallback, UseSpaceOptions } from './types.js'; diff --git a/src/types.ts b/src/types.ts index e5866a48..f6928a0a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import { ErrorInfo, PresenceAction } from 'ably'; +import { ErrorInfo, PresenceAction } from '@ably/pubsub-core'; import type { LockAttributes } from './Locks.js'; /** diff --git a/src/utilities/test/fakes.ts b/src/utilities/test/fakes.ts index 789ec52d..8708a401 100644 --- a/src/utilities/test/fakes.ts +++ b/src/utilities/test/fakes.ts @@ -1,4 +1,4 @@ -import { PresenceMessage } from 'ably'; +import { PresenceMessage } from '@ably/pubsub-core'; import Space from '../../Space.js'; diff --git a/src/utilities/types.ts b/src/utilities/types.ts index 22eada31..f58df5ac 100644 --- a/src/utilities/types.ts +++ b/src/utilities/types.ts @@ -1,4 +1,4 @@ -import type { InboundMessage, PresenceMessage } from 'ably'; +import type { InboundMessage, PresenceMessage } from '@ably/pubsub-core'; import type { ProfileData, Lock } from '../types.js'; diff --git a/test/cdn-bundle/resources/test.html b/test/cdn-bundle/resources/test.html index 556d75f5..005ad672 100644 --- a/test/cdn-bundle/resources/test.html +++ b/test/cdn-bundle/resources/test.html @@ -7,7 +7,7 @@