Skip to content

chore: bump @ably/ui from 17.14.0 to 18.3.1#3418

Open
kennethkalmer wants to merge 2 commits into
mainfrom
chore/bump-ably-ui-18.3.1
Open

chore: bump @ably/ui from 17.14.0 to 18.3.1#3418
kennethkalmer wants to merge 2 commits into
mainfrom
chore/bump-ably-ui-18.3.1

Conversation

@kennethkalmer

@kennethkalmer kennethkalmer commented Jun 17, 2026

Copy link
Copy Markdown
Member

Motivation

Catch docs up to the @ably/ui line shipped on the other public surfaces. The headline reason for moving now is the Mixpanel EU-ingestion default that landed in 18.3.1: Mixpanel sunsets its US→EU forwarding bridge on 2026-07-01, and 18.3.1 defaults mixpanel.init to api_host: https://api-eu.mixpanel.com so docs routes directly to the EU project instead of relying on the soon-to-be-removed forwarder.

This crosses a major version boundary (17 → 18), and the major dropped the Redux scaffolding the package used to expose. This PR does both the version bump and the migration off those removed APIs.

What changed

Commit 1 — chore: bump @ably/ui from 17.14.0 to 18.3.1

  • package.json: @ably/ui 17.14.0 → 18.3.1
  • yarn.lock regenerated via yarn install

Commit 2 — refactor: migrate session/api-key bootstrap off @ably/ui Redux APIs

@ably/ui 18 removed connectState / selectSessionData / fetchSessionData / getRemoteDataStore / createRemoteDataStore / reducerSessionData / reducerApiKeyData / reducerBlogPosts / reducerFlashes / attachStoreToWindow and replaced them with a Context + SWR pattern (SessionDataProvider, useSessionData, FlashProvider, useFlashContext).

This repo's bootstrap is ported across:

  • src/contexts/user-context/wrap-with-provider.tsx now reads session data from useSessionData() (provided by SessionDataProvider at the root) and runs the api-key fetch through a plain async function inside useEffect. The component still publishes the same UserContext shape (sessionState, apps), so every downstream consumer keeps working unchanged.
  • src/contexts/user-context/api-keys.ts (new) holds the WEB_API endpoint constants and the fetchApps() async helper. The demo-key + real-key flow is preserved, including the window.ably.docs.DOCS_API_KEY side effect needed by ad hoc scripts.
  • gatsby-browser.tsx loses the createRemoteDataStore / attachStoreToWindow bootstrap; onClientEntry is now just setupObserver().
  • gatsby-ssr.tsx keeps the same default-export wiring — wrap-with-provider.tsx's default now carries SessionDataProvider in addition to UserContextWrapper, so SSR inherits the new provider without any SSR-side edits.
  • src/components/GlobalLoading/GlobalLoading.tsx drops import '@ably/ui/core/scripts'; that side-effect import existed to register Redux store side effects that no longer exist.
  • src/redux/ deleted in its entirety. The constants that used to live there (WEB_API_USER_DATA_ENDPOINT, WEB_API_KEYS_DATA_ENDPOINT, WEB_API_TEMP_KEY_ENDPOINT) now live next to the fetcher that consumes them, in src/contexts/user-context/api-keys.ts.
  • src/types/ably-ui-core-scripts/index.d.ts deleted — the local TS shim describing the removed Redux types was lying about the module's surface.
  • mocks/handlers.js, src/contexts/user-context.test.tsx point at the new module surface. The msw-blocked test stays skipped (TypeError: The "eventTargets" argument must be an instance of EventEmitter or EventTarget mswjs/msw#1785).

No new dependencies are added. SWR is transitively present via @ably/ui.

Things to be cautious about in review

  • SessionDataProvider types vs docs SessionState. useSessionData() is typed by @ably/ui as { user?: { firstName?, lastName?, email? } } | null, but at runtime the /api/me endpoint returns the rich shape docs has always read. The wrapper casts via as unknown as SessionState to keep the existing UserContext consumers happy. If /api/me ever stops returning a superset of what the consumers expect, the cast will hide it — worth keeping in mind.
  • window.ably.docs.DOCS_API_KEY side effect. Preserved verbatim from the previous code path so ad hoc scripts that read this global don't break. The comment that flagged this as "remove when ad hoc scripts are removed" is also preserved.
  • Flash is no longer wired. The old bootstrap registered reducerFlashes into the Redux store, but no Flash component is rendered anywhere in this repo. FlashProvider is intentionally not added. The @ably/ui/core/Flash/component.css import in src/styles/global.css stays — it's pure CSS and harmless.
  • React peer dep. @ably/ui 18 peers on React 18; this repo already uses React 18, so no change needed there.
  • Type errors in tsc. yarn tsc --noEmit on this branch produces the same set of pre-existing errors as origin/main — none of the new files contribute additional errors. Worth confirming the repo's CI doesn't block on tsc (it currently doesn't appear to).
  • Local verification done. yarn lint, yarn test (303 pass, 1 skipped — the pre-existing msw-blocked test), and yarn tsc --noEmit (no new errors from the changed files) all green locally. yarn build not run locally due to its cost; CI on the PR will exercise it.

What 17.14 → 18.3.1 brings (consumer-facing)

  • 18.0.0 — Redux removed; SessionDataProvider + FlashProvider replace the old store. (Breaking — migrated in this PR.)
  • 18.0.1 — patch bumps, build pipeline, browserslist; no API change.
  • 18.1.0 — meganav customer-logo swap, Storybook group bumps.
  • 18.2.0 — sanitize-html primitives + react/no-danger lint rule; PostHog session-recording plumbing removed from insights; vitest 4, posthog-js bumps.
  • 18.3.0 — superseded (build failed before publish).
  • 18.3.1mixpanel.init defaults to EU api_host; tsconfig lib bumped to ES2020; CI runs pnpm build on PRs.

How do you manually test this?

yarn install
yarn develop
  • Open the docs site. Confirm session/user data still loads — signed-in state should be reflected in the header, demo + real api keys should appear in code blocks that surface them.
  • DevTools Network panel: confirm mixpanel.com requests target api-eu.mixpanel.com (not api-js.mixpanel.com).
  • Hit /api/me and /api/api_keys (proxied through GATSBY_ABLY_MAIN_WEBSITE); confirm the calls fire from the new provider/effect rather than the old Redux dispatch.
  • yarn build — must complete with no missing-export errors from @ably/ui/core/scripts.

Follow-ups (after this lands)

  • Confirm Mixpanel Insights shows api-eu.mixpanel.com for incoming docs events.
  • If yarn build (or another equivalent type-checking gate) isn't currently in CI for this repo, consider adding it — pure runtime tests won't catch missing-export breakages of this kind.
  • The window.ably.docs.DOCS_API_KEY ad hoc script support can be deleted as soon as those external scripts are gone (carried over comment from the previous implementation).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Dependencies
    • Updated @ably/ui library from version 17.14.0 to 18.3.1, providing enhanced functionality and improved stability

Catches docs up to the @ably/ui line shipped on the main marketing
site and Voltaire. The headline reason for moving now is the
Mixpanel EU-ingestion default that landed in 18.3.1: Mixpanel
sunsets its US→EU forwarding bridge on 2026-07-01, and 18.3.1
defaults `mixpanel.init` to `api_host: https://api-eu.mixpanel.com`
so we route directly to the EU project instead of relying on the
soon-to-be-removed forwarder.

This crosses a major boundary (17 → 18), so the design system
surface this app consumes (typography utilities, layout primitives,
nav/footer components, palette names) should be smoke-checked
against the docs site's rendered output before this lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c28f8a78-cab6-4454-86aa-28c872a931ce

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/bump-ably-ui-18.3.1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the docs site to @ably/ui@18.3.1 (crossing the 17→18 breaking change) and migrates the client-side session/API-key bootstrap away from the removed Redux-based APIs to the new Context + SWR (SessionDataProvider / useSessionData) pattern.

Changes:

  • Bump @ably/ui from 17.14.0 to 18.3.1 (lockfile regenerated).
  • Replace Redux store/session/api-key bootstrapping with SessionDataProvider + a local async fetchApps() helper.
  • Remove obsolete Redux scaffolding/types and update mocks/tests to the new surface.

Reviewed changes

Copilot reviewed 13 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
package.json Bumps @ably/ui dependency to 18.3.1.
yarn.lock Updates lockfile entries for @ably/ui and transitive deps (Redux removed from @ably/ui deps).
gatsby-browser.tsx Removes Redux store bootstrap; keeps setupObserver() and insights wiring.
src/components/GlobalLoading/GlobalLoading.tsx Removes @ably/ui/core/scripts side-effect import tied to the old Redux setup.
src/contexts/user-context/wrap-with-provider.tsx Wraps root with SessionDataProvider and switches user context session/apps sourcing to hooks + async fetch.
src/contexts/user-context/api-keys.ts Adds docs-specific API key fetching helpers and endpoint constants (including global window.ably.docs.DOCS_API_KEY side effect).
mocks/handlers.js Updates mock endpoint constant imports to the new module.
src/contexts/user-context.test.tsx Updates the (skipped) test to use SessionDataProvider and the new apps data.
src/types/ably-ui-core-scripts/index.d.ts Deletes now-invalid local typing shim for removed @ably/ui Redux exports.
src/redux/select-data.ts Deletes unused Redux selector helper.
src/redux/fetch-and-add-to-store.ts Deletes Redux data fetch/dispatch helper.
src/redux/api-key/remote-api-key-data.ts Deletes Redux API-key retrieval logic now replaced by fetchApps().
src/redux/api-key/index.ts Deletes Redux API-key barrel.
src/redux/api-key/constants.ts Deletes Redux endpoint/constants module (moved to api-keys.ts).
src/redux/api-key/api-key-reducer.ts Deletes Redux reducer for API keys (store removed).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/contexts/user-context/wrap-with-provider.tsx
Comment thread src/contexts/user-context/api-keys.ts
Comment thread src/contexts/user-context/api-keys.ts Outdated
Comment thread src/contexts/user-context.test.tsx Outdated
@kennethkalmer kennethkalmer force-pushed the chore/bump-ably-ui-18.3.1 branch from b9ce79b to 3b0fd5a Compare June 17, 2026 20:51
@kennethkalmer kennethkalmer requested a review from Copilot June 17, 2026 20:59
@kennethkalmer kennethkalmer added the review-app Create a Heroku review app label Jun 17, 2026
@ably-ci ably-ci temporarily deployed to ably-docs-chore-bump-ab-ukvkkp June 17, 2026 21:01 Inactive

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 16 changed files in this pull request and generated 2 comments.

Comment thread src/contexts/user-context/api-keys.ts
Comment thread src/contexts/user-context.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 17 changed files in this pull request and generated 1 comment.

Comment thread src/contexts/user-context/api-keys.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/contexts/user-context.ts (1)

56-59: ⚡ Quick win

Use interface for AppApiKey to match the TS object-shape guideline.

This keeps object-shape declarations consistent across the TS surface.

As per coding guidelines, "Use interface for defining object shapes in TypeScript."

Proposed change
-export type AppApiKey = {
+export interface AppApiKey {
   name: string;
   whole_key: string;
-};
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/contexts/user-context.ts` around lines 56 - 59, The AppApiKey definition
uses a type declaration instead of an interface, which is inconsistent with the
project's TypeScript guideline that requires interfaces for object-shape
definitions. Convert the AppApiKey type declaration to an interface by replacing
the export type keyword with export interface and adjusting the syntax
accordingly (remove the equals sign and semicolon, keeping the object shape
properties intact). This ensures consistency across the TypeScript codebase for
all object-shape declarations.

Source: Coding guidelines

src/contexts/user-context/wrap-with-provider.tsx (1)

17-27: ⚡ Quick win

Use async/await inside the effect instead of chaining .then() / .catch().

This keeps promise handling consistent with the TS guideline and improves readability in the cancellation flow.

As per coding guidelines, "Use async/await instead of .then() for promise handling in TypeScript."

Proposed change
   useEffect(() => {
     let cancelled = false;
-    fetchApps()
-      .then((next) => {
-        if (!cancelled) {
-          setApps(next);
-        }
-      })
-      .catch((e) => {
-        console.warn('Could not load api keys:', e);
-      });
+    const loadApps = async () => {
+      try {
+        const next = await fetchApps();
+        if (!cancelled) {
+          setApps(next);
+        }
+      } catch (e) {
+        console.warn('Could not load api keys:', e);
+      }
+    };
+    void loadApps();
     return () => {
       cancelled = true;
     };
   }, []);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/contexts/user-context/wrap-with-provider.tsx` around lines 17 - 27, The
useEffect hook in wrap-with-provider.tsx is using promise chaining with .then()
and .catch() to handle the fetchApps() call. Refactor this to use async/await
syntax instead. Create an async IIFE (immediately invoked function expression)
inside the effect, use try/catch for error handling, preserve the cancelled flag
check before calling setApps, and maintain the console.warn logging in the catch
block with the error details.

Source: Coding guidelines

src/contexts/user-context/api-keys.ts (1)

23-31: ⚡ Quick win

Prefer interface for payload object shapes in this TS module.

As per coding guidelines, "Use interface for defining object shapes in TypeScript."

Proposed change
-type ApiKeyValue = {
+interface ApiKeyValue {
   name: string;
   url: string;
-};
+}

-type ApiKeysPayload = {
+interface ApiKeysPayload {
   data?: ApiKeyValue[];
   error?: unknown;
-};
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/contexts/user-context/api-keys.ts` around lines 23 - 31, Replace the
`type` keyword with `interface` keyword for the object shape definitions
ApiKeyValue and ApiKeysPayload. Convert both type aliases to interfaces by
changing `type ApiKeyValue = {` to `interface ApiKeyValue {` and `type
ApiKeysPayload = {` to `interface ApiKeysPayload {`, removing the equals sign
and adjusting the syntax accordingly. This aligns with the coding guidelines
that prefer interfaces for defining object shapes in TypeScript.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/contexts/user-context.test.tsx`:
- Around line 17-34: The test for UserContextWrapper is currently skipped with
test.skip and needs to be re-enabled to provide coverage for this critical
integration path. Remove the .skip from the test function call to enable it, and
rename the test title from a generic component-based description to a
behavior-based description that clearly explains what is being tested (for
example, describing that it validates the session data and apps are properly
fetched and rendered). If MSW mocking prevents the integration test from
running, consider adding focused unit tests for the fetchApps function and its
branches instead of skipping the entire flow.

In `@src/contexts/user-context/api-keys.ts`:
- Around line 74-83: The fetchApps function currently awaits fetchDemoApp()
without error handling at the beginning, causing the entire function to fail if
that endpoint goes down and preventing the real API keys from being fetched.
Wrap the fetchDemoApp() call in its own try-catch block so that even if it
fails, the function continues to attempt fetching real API keys via the
fetchJson call to WEB_API_KEYS_DATA_ENDPOINT. If fetchDemoApp() fails, fall back
to an empty array or null value for the demoApp, then proceed with fetching and
returning the real apps so callers aren't left with no apps during a partial
outage.

---

Nitpick comments:
In `@src/contexts/user-context.ts`:
- Around line 56-59: The AppApiKey definition uses a type declaration instead of
an interface, which is inconsistent with the project's TypeScript guideline that
requires interfaces for object-shape definitions. Convert the AppApiKey type
declaration to an interface by replacing the export type keyword with export
interface and adjusting the syntax accordingly (remove the equals sign and
semicolon, keeping the object shape properties intact). This ensures consistency
across the TypeScript codebase for all object-shape declarations.

In `@src/contexts/user-context/api-keys.ts`:
- Around line 23-31: Replace the `type` keyword with `interface` keyword for the
object shape definitions ApiKeyValue and ApiKeysPayload. Convert both type
aliases to interfaces by changing `type ApiKeyValue = {` to `interface
ApiKeyValue {` and `type ApiKeysPayload = {` to `interface ApiKeysPayload {`,
removing the equals sign and adjusting the syntax accordingly. This aligns with
the coding guidelines that prefer interfaces for defining object shapes in
TypeScript.

In `@src/contexts/user-context/wrap-with-provider.tsx`:
- Around line 17-27: The useEffect hook in wrap-with-provider.tsx is using
promise chaining with .then() and .catch() to handle the fetchApps() call.
Refactor this to use async/await syntax instead. Create an async IIFE
(immediately invoked function expression) inside the effect, use try/catch for
error handling, preserve the cancelled flag check before calling setApps, and
maintain the console.warn logging in the catch block with the error details.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a9f4657a-2fd0-4f15-bc70-736f2f600de7

📥 Commits

Reviewing files that changed from the base of the PR and between 0e7da73 and 5118095.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (16)
  • gatsby-browser.tsx
  • mocks/handlers.js
  • package.json
  • src/components/GlobalLoading/GlobalLoading.tsx
  • src/contexts/user-context.test.tsx
  • src/contexts/user-context.ts
  • src/contexts/user-context/api-keys.ts
  • src/contexts/user-context/wrap-with-provider.tsx
  • src/redux/api-key/api-key-reducer.ts
  • src/redux/api-key/constants.ts
  • src/redux/api-key/index.ts
  • src/redux/api-key/remote-api-key-data.ts
  • src/redux/fetch-and-add-to-store.ts
  • src/redux/select-data.ts
  • src/types/ably-ui-core-scripts/index.d.ts
  • src/utilities/update-ably-connection-keys.test.ts
💤 Files with no reviewable changes (10)
  • src/redux/api-key/constants.ts
  • src/redux/api-key/api-key-reducer.ts
  • gatsby-browser.tsx
  • src/redux/select-data.ts
  • src/types/ably-ui-core-scripts/index.d.ts
  • src/redux/api-key/index.ts
  • src/redux/fetch-and-add-to-store.ts
  • src/redux/api-key/remote-api-key-data.ts
  • src/components/GlobalLoading/GlobalLoading.tsx
  • src/utilities/update-ably-connection-keys.test.ts

Comment thread src/contexts/user-context.test.tsx Outdated
Comment thread src/contexts/user-context/api-keys.ts
@ably/ui 18 removed the Redux scaffolding that this repo depended on
(connectState, selectSessionData, fetchSessionData, getRemoteDataStore,
createRemoteDataStore, reducerSessionData, reducerApiKeyData,
reducerBlogPosts, reducerFlashes, attachStoreToWindow). Replaced with
the Context + SWR pattern @ably/ui now exposes:

- SessionDataProvider (SWR-backed) wraps the app at the root and
  fetches /api/me. UserContextWrapper reads from it via useSessionData
  and surfaces the result through the existing UserContext as
  sessionState, so downstream callers don't change.
- API-key loading moved to a plain async fetch (src/contexts/user-
  context/api-keys.ts) driven by useEffect inside UserContextWrapper.
  This preserves the existing demo-key + real-key flow and the
  window.ably.docs.DOCS_API_KEY side effect for ad hoc scripts, while
  dropping the dispatch/reducer indirection.
- gatsby-browser drops the createRemoteDataStore / attachStoreToWindow
  bootstrap; gatsby-ssr keeps the same default-export wiring, which
  now carries SessionDataProvider in addition to UserContext.
- Side-effect import of @ably/ui/core/scripts in GlobalLoading is
  removed; that import existed to register the Redux store side
  effects, which no longer exist.
- src/redux/ deleted in its entirety; constants live next to the
  fetcher that uses them. The stale type shim under src/types/
  ably-ui-core-scripts is removed.
- mocks/handlers.js, user-context.test.tsx point at the new module
  surface. The msw-blocked test stays skipped.

No new dependencies; uses SWR transitively through @ably/ui.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@kennethkalmer

Copy link
Copy Markdown
Member Author

Picked up the three nitpicks in CodeRabbit's review body alongside the actionable comments:

  • AppApiKeyinterface in user-context.ts.
  • ApiKeyValue and ApiKeysPayloadinterface in api-keys.ts.
  • wrap-with-provider.tsx useEffect switched to async/await with a try/catch (no more .then().catch() chain).

All in 8f978c8ae along with the other fixes.

~ 𝒞𝓁𝒶𝓊𝒹𝑒

@kennethkalmer kennethkalmer marked this pull request as ready for review June 17, 2026 21:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-app Create a Heroku review app

Development

Successfully merging this pull request may close these issues.

3 participants