Repository navigation
fix(deps): update dependency react-rx to v7 - #2139
squiggler-app[bot] wants to merge 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
🦋 Changeset detectedLatest commit: 3bd7253 The changes in this PR will be included in the next version bump. This PR includes changesets to release 11 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ E2E Tests🟢 39 passed • 🟡 5 flaky • view full report • view run Studio: https://plugins-e2e-test-studio-k9i1z2pj4.sanity.dev Datasets: |
Pull request was closed
Renovate Ignore NotificationBecause you closed this PR without merging, Renovate will ignore this update. You will not get PRs for any future If you accidentally closed this PR, or if you changed your mind: rename this PR to get a fresh replacement PR. |
This PR contains the following updates:
^4.2.5→^7.0.1Release Notes
sanity-io/react-rx (react-rx)
v7.0.1Compare Source
Patch Changes
64f6fb1Thanks @breken-ai! - FixuseObservablePromiseandpreloadObservablePromiseon Hermes (React Native), where creating the promise crashed withMaximum call stack size exceeded. Hermes does not implementSymbol.species, so.then()on aPromisesubclass built another instrumented instance and recursed in the constructor. The returnedObservablePromiseno longer subclassesPromise: it is a thenable that wraps a plain promise and delegatesthen/catch/finallyto it, so derived promises are plainPromises on every engine anduse(promise.then(fn))settles instead of suspending forever. It still satisfies theObservablePromise<T>type and works withuse(),awaitand thePromisecombinators, butinstanceof Promiseis nowfalse.v7.0.0Compare Source
Major Changes
#515
8ca73bdThanks @stipsan! - v7 moves every subscription out of the render phase and removesuseObservableEvent. Requirements are unchanged from v6: React^19.2, RxJS^7.2, Node>=22.12, ESM only. The v6 to v7 migration guide has more patterns.useObservableanduseSyncObservablerequire theinitialValueargument. The initial value is what renders until the observable emits. Omitting it is a type error, and because JavaScript callers can bypass the types, the hooks also throw aTypeErrorduring render when the argument is missing. Every value is valid,undefinedincluded, but you must pass it. Functions act as initializers, likeuseState. To use a function as the initial value, pass an initializer that returns it. The deprecated single-argument overloads are gone.Call sites that already pass an
initialValuekeep their behavior. If an observable has no meaningful initial value, useuseObservablePromisewithuse()and Suspense instead.useObservableanduseSyncObservablenever subscribe during render. The render-phase warm-up is gone. Every render, the first one and every identity change alike, shows the resolvedinitialValue, or the shared cache entry's last emission when the observable is already live elsewhere. The subscription starts when the component commits, and a synchronous emission replaces theinitialValueright after that commit.initialValuewas given, soof,startWith, or aBehaviorSubjectcould render on the first pass. In v7 theinitialValuerenders first.initialValuefor one pass. The new observable's synchronous emission arrives after the swap commits.useObservablestill never renders the previous observable's value under the new identity.useMemo,useState, module scope, or React Compiler memoization. An observable rebuilt on every render is torn down and re-subscribed on every render. When such a source synchronously replays a value that differs from theinitialValue, every commit forces a re-render and React aborts with "Maximum update depth exceeded". The v6 warm-up let that pattern converge.disabled: truenow always guarantees zero subscriptions. In v6 the warm-up probe still subscribed once when noinitialValuewas given.initialValueand never subscribes.useSyncObservablecan no longer hit React's "Missing getServerSnapshot" error, and a non-deterministic synchronous emission can no longer cause a hydration mismatch.useObservablePromisenever subscribes during a mounting render. v6 started the source subscription during render unlessdisabled, so any render fetched as a side effect, hidden<Activity>pre-renders included. A fetch now has three triggers.disabledcomponent that called the hook commits, on mount or on an<Activity>reveal.disabledconsumer re-renders with a new observable identity. The hook subscribes the new source during that render, so a suspended transition can settle, retry, and commit.preloadObservablePromise.This affects callers as follows.
use(useObservablePromise(obs$))inside one component deadlocks. The component suspends on its own pending promise before the commit that would start the fetch. This was never a supported pattern and is not guarded against. Pass the promise to a child that reads it withuse(), and put a<Suspense>boundary between the hook caller and that child.<Activity>tree that calls the hook is paused. Nothing subscribes until the tree is revealed and its effects mount. To pre-render hidden content with data, call the hook in a visible parent and pass the promise into the hidden tree.of,BehaviorSubject, a replayedshareReplay) resolves at the hook caller's commit, so a cold mount shows one Suspense fallback pass. Preload the observable to skip the fallback.startTransitionor behinduseDeferredValueneeds no preload. The live consumer's swap render starts the fetch, the previous content stays visible until the new data settles, and the swap then commits.preloadObservablePromisestill lets a swap commit with no pending period, for example after a hover preload.disabledoff inside a transition starts the fetch from that render.ttl. Bound sources that may never settle with RxJStimeout, as you would forpreloadObservablePromise.preloadObservablePromiseis a no-op that returns an inert pending promise. It neither subscribes nor touches the cache. Server rendering emits the Suspense fallback and the fetch starts after hydration. For React Server Components or server-only flows, fetch withawaitor RxJSfirstValueFromand pass the promise or value as a prop.useObservableEventis removed. Replace it withuseObservableSubject, available since v6.1, which returns the event stream and a stable handler that pushes into it. Then move the pipeline to where its output is consumed. A pipeline that ended intap(setState)becomes a derived stream read withuseObservableoruseSyncObservable. A side-effect-only pipeline subscribes in an effect. A pipeline that only forwarded into aSubjectbecomes a directnextcall.The
use-effect-eventdependency existed only for this hook and is gone. react-rx has no runtime dependencies beyond itsreactandrxjspeers.v6.1.0Compare Source
Minor Changes
#585
8fed462Thanks @stipsan! - AdduseObservableSubject, a hook that returns the two halves of an event: an observable of the values pushed into it, and a referentially stable handler that pushes them. The underlying RxJSSubjectis scoped to the component instance and only its observable side is exposed.useObservableEventis removed in v7. It is now implemented on top ofuseObservableSubject, which carries over to v7 unchanged, so call sites can be migrated on v6 and need no further changes after upgrading.#582
27db7b6Thanks @stipsan! - Deprecate the APIs that react-rx v7 removes, so editors andno-deprecatedlint rules flag them ahead of the upgrade. Runtime behavior is unchanged.useObservableEventis removed in v7. Push events into aSubjectyou own and read the derived stream withuseObservableoruseSyncObservable.useObservableoruseSyncObservablewithout aninitialValueis removed in v7, where the argument is required.useObservable(observable$, undefined)keeps the v6 type and behavior.no-deprecatedlint rules also flag uncalled references such astypeof useObservable, because they read the tags of every overload. Those are false positives. Suppress them locally.See the v6 to v7 migration guide.
Patch Changes
#579
9010e04Thanks @stipsan! -initialValueinitializers are now resolved once per hook instance, like auseStateinitializer. They previously ran on every pre-emissiongetSnapshotread, so an initializer returning a fresh object (useObservable(obs$, () => ({...})), and the same onuseSyncObservable) gaveuseSyncExternalStorea new snapshot reference on every consistency check and looped until React aborted with "Maximum update depth exceeded". The resolved value is now cached per instance, which also makes the pre-emission snapshot reference stable across re-renders and fixes the equivalent hazard inuseSyncObservable's server snapshot.As with
useState, the hook reads theinitialValueargument on its first render only. A different value passed on a later render is ignored until the hook remounts, where a plain value used to be re-read on every pre-emission render. Keep initializers pure. React Strict Mode calls them twice in development and keeps one result.v6.0.1Compare Source
Patch Changes
a764dd3Thanks @squiggler-app! - fix(deps): update dependency use-effect-event to ^2.0.4v6.0.0Compare Source
Major Changes
#506
4c3025cThanks @stipsan! - Skip the render-phase warm-up subscription inuseObservable/useSyncObservablewhen aninitialValueis provided. The warm-up only exists so sync emissions (startWith,of, …) can render on the first paint — with aninitialValuethere's already a value to show, so the observable is now first subscribed on commit.Breaking: when a sync-emitting observable is paired with an
initialValue, the first paint now shows theinitialValue— the sync emission arrives right after mount (previously it won on the first render, on the client and in SSR markup).Subscribe-time side effects (e.g.
fromFetch) stay out of the render phase,disabled: truenow means zero subscriptions (even when the observable is rebuilt every render), and SSR paints theinitialValuewithout subscribing the source. Once the hook has received an emission, replacement observables on later renders are warmed during render again so components that rebuild the observable every render settle instead of looping. OmittinginitialValuebehaves exactly as before.v5.1.2Compare Source
Patch Changes
db29f9bThanks @stipsan! - perf: build with the React Compiler on oxc (oxc-transform-react, the native Rust port) instead ofbabel-plugin-react-compiler. The published output is unchanged — one compiler pass now handles React Compiler, TypeScript, and JSX natively, and babel is no longer part of the build or test pipeline.v5.1.1Compare Source
Patch Changes
0f7bce9Thanks @stipsan! - fix: makeuseObservabledeferral identity-coherent. The observable identity and its value are now deferred as one snapshot, and when the observable identity changes (e.g. it is memoized on a document id that just changed) the hook falls back to the live value — so the previous identity's value never renders under the new one.v5.1.0Compare Source
Minor Changes
4d9b613Thanks @stipsan! - AdduseObservablePromiseandpreloadObservablePromise: Suspense-ready data fetching returning ause()-compatible promise, with{disabled, ttl}options.v5.0.1Compare Source
Patch Changes
e546141Thanks @stipsan! - Restore theuse-effect-eventponyfill so effect events see the latest values inmemoandforwardRefcomponents.v5.0.0Compare Source
Major Changes
#459
7ed6b55Thanks @stipsan! - BREAKING:useObservablenow defers store updates withuseDeferredValue— urgent renders keep the previous value while a background render catches up. Mounts, remounts, and<Activity>reveals still render the current snapshot synchronously (no initial-value flash). SSR renders synchronous emissions (instead of always usinginitialValue), no longer throws wheninitialValueis omitted, and fails the server render on synchronously erroring observables.New
useSyncObservablepreserves v4's synchronous behavior and strictgetServerSnapshotcontract — use it for controlled inputs, or rename wholesale for a mechanical migration.See the v4 to v5 migration guide.
#434
08379edThanks @stipsan! - BREAKING: Require Node.js>=22.12, matchingsanity'sengines.node.#435
bdef45bThanks @stipsan! - BREAKING: Require React^19.2as a peer dependency. React 18 is no longer supported.#442
a89ec09Thanks @stipsan! - Stop publishing CommonJS builds — the package is ESM-only.#449
5e83cbeThanks @stipsan! - BREAKING: Require RxJS^7.2as a peer dependency. Import operators from'rxjs'instead of the deprecated'rxjs/operators'path.Configuration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about these updates again.
This PR has been generated by Mend Renovate using a curated preset maintained by
. View repository job log here
Note
Medium Risk
Major react-rx upgrade (v4→v7) changes subscription timing and hook semantics across several Studio plugins without accompanying code changes; regressions would show up as UI flicker, stale state, or infinite update loops if observables are unstable.
Overview
Bumps
react-rxfrom ^4.2.5 to ^7.0.1 via the workspace pnpm catalog (and explicitly in@sanity/embeddings-index-ui), withpnpm-lock.yamlrefreshed so every catalog consumer resolves 7.0.1. A changeset records patch releases for@sanity/embeddings-index-ui,@sanity/language-filter,@sanity/studio-secrets, andsanity-plugin-mux-input.There are no application source edits in the diff—only manifests, lockfile churn (including dropping the old
react-rx@4.2.5tree), and release metadata. Existing plugin usage already callsuseObservablewith aninitialValue, which aligns with v7’s required second argument, but v7 still changes when subscriptions run (post-commit vs render-phase warm-up), which can affect first paint and observable identity edge cases in Studio UI.Reviewed by Cursor Bugbot for commit 3bd7253. Bugbot is set up for automated code reviews on this repo. Configure here.