Skip to content

Commit 3f8abf8

Browse files
committed
Expose cacheSignal() alongside cache() (#33557)
This was really meant to be there from the beginning. A `cache()`:ed entry has a life time. On the server this ends when the render finishes. On the client this ends when the cache of that scope gets refreshed. When a cache is no longer needed, it should be possible to abort any outstanding network requests or other resources. That's what `cacheSignal()` gives you. It returns an `AbortSignal` which aborts when the cache lifetime is done based on the same execution scope as a `cache()`ed function - i.e. `AsyncLocalStorage` on the server or the render scope on the client. ```js import {cacheSignal} from 'react'; async function Component() { await fetch(url, { signal: cacheSignal() }); } ``` For `fetch` in particular, a patch should really just do this automatically for you. But it's useful for other resources like database connections. Another reason it's useful to have a `cacheSignal()` is to ignore any errors that might have triggered from the act of being aborted. This is just a general useful JavaScript pattern if you have access to a signal: ```js async function getData(id, signal) { try { await queryDatabase(id, { signal }); } catch (x) { if (!signal.aborted) { logError(x); // only log if it's a real error and not due to cancellation } return null; } } ``` This just gets you a convenient way to get to it without drilling through so a more idiomatic code in React might look something like. ```js import {cacheSignal} from "react"; async function getData(id) { try { await queryDatabase(id); } catch (x) { if (!cacheSignal()?.aborted) { logError(x); } return null; } } ``` If it's called outside of a React render, we normally treat any cached functions as uncached. They're not an error call. They can still load data. It's just not cached. This is not like an aborted signal because then you couldn't issue any requests. It's also not like an infinite abort signal because it's not actually cached forever. Therefore, `cacheSignal()` returns `null` when called outside of a React render scope. Notably the `signal` option passed to `renderToReadableStream` in both SSR (Fizz) and RSC (Flight Server) is not the same instance that comes out of `cacheSignal()`. If you abort the `signal` passed in, then the `cacheSignal()` is also aborted with the same reason. However, the `cacheSignal()` can also get aborted if the render completes successfully or fatally errors during render - allowing any outstanding work that wasn't used to clean up. In the future we might also expand on this to give different [`TaskSignal`](https://developer.mozilla.org/en-US/docs/Web/API/TaskSignal) to different scopes to pass different render or network priorities. On the client version of `"react"` this exposes a noop (both for Fiber/Fizz) due to `disableClientCache` flag but it's exposed so that you can write shared code. DiffTrain build for [e1dc034](e1dc034)
1 parent 15a6dc7 commit 3f8abf8

26 files changed

+255
-197
lines changed

compiled-rn/VERSION_NATIVE_FB

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
19.2.0-native-fb-75e78d24-20250616
1+
19.2.0-native-fb-e1dc0349-20250617

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOM-dev.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<630c960e90cfb49f53ce703b43fc5058>>
10+
* @generated SignedSource<<81a28e2329322fca2be4855eed4d24f8>>
1111
*/
1212

1313
"use strict";
@@ -404,5 +404,5 @@ __DEV__ &&
404404
exports.useFormStatus = function () {
405405
return resolveDispatcher().useHostTransitionStatus();
406406
};
407-
exports.version = "19.2.0-native-fb-75e78d24-20250616";
407+
exports.version = "19.2.0-native-fb-e1dc0349-20250617";
408408
})();

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOM-prod.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<b9a3377d38a49313fb0fea5bdd9be663>>
10+
* @generated SignedSource<<95769ab918352fbbe251a5972deb853d>>
1111
*/
1212

1313
"use strict";
@@ -203,4 +203,4 @@ exports.useFormState = function (action, initialState, permalink) {
203203
exports.useFormStatus = function () {
204204
return ReactSharedInternals.H.useHostTransitionStatus();
205205
};
206-
exports.version = "19.2.0-native-fb-75e78d24-20250616";
206+
exports.version = "19.2.0-native-fb-e1dc0349-20250617";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOM-profiling.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<b9a3377d38a49313fb0fea5bdd9be663>>
10+
* @generated SignedSource<<95769ab918352fbbe251a5972deb853d>>
1111
*/
1212

1313
"use strict";
@@ -203,4 +203,4 @@ exports.useFormState = function (action, initialState, permalink) {
203203
exports.useFormStatus = function () {
204204
return ReactSharedInternals.H.useHostTransitionStatus();
205205
};
206-
exports.version = "19.2.0-native-fb-75e78d24-20250616";
206+
exports.version = "19.2.0-native-fb-e1dc0349-20250617";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOMClient-dev.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<109ba2365c1b7fa46fc043010b6feb5f>>
10+
* @generated SignedSource<<64c42466af3e6a72d9d65af3964750a6>>
1111
*/
1212

1313
/*
@@ -26195,6 +26195,9 @@ __DEV__ &&
2619526195
cache.data.set(resourceType, cacheForType));
2619626196
return cacheForType;
2619726197
},
26198+
cacheSignal: function () {
26199+
return readContext(CacheContext).controller.signal;
26200+
},
2619826201
getOwner: function () {
2619926202
return current;
2620026203
}
@@ -27061,11 +27064,11 @@ __DEV__ &&
2706127064
};
2706227065
(function () {
2706327066
var isomorphicReactPackageVersion = React.version;
27064-
if ("19.2.0-native-fb-75e78d24-20250616" !== isomorphicReactPackageVersion)
27067+
if ("19.2.0-native-fb-e1dc0349-20250617" !== isomorphicReactPackageVersion)
2706527068
throw Error(
2706627069
'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' +
2706727070
(isomorphicReactPackageVersion +
27068-
"\n - react-dom: 19.2.0-native-fb-75e78d24-20250616\nLearn more: https://react.dev/warnings/version-mismatch")
27071+
"\n - react-dom: 19.2.0-native-fb-e1dc0349-20250617\nLearn more: https://react.dev/warnings/version-mismatch")
2706927072
);
2707027073
})();
2707127074
("function" === typeof Map &&
@@ -27102,10 +27105,10 @@ __DEV__ &&
2710227105
!(function () {
2710327106
var internals = {
2710427107
bundleType: 1,
27105-
version: "19.2.0-native-fb-75e78d24-20250616",
27108+
version: "19.2.0-native-fb-e1dc0349-20250617",
2710627109
rendererPackageName: "react-dom",
2710727110
currentDispatcherRef: ReactSharedInternals,
27108-
reconcilerVersion: "19.2.0-native-fb-75e78d24-20250616"
27111+
reconcilerVersion: "19.2.0-native-fb-e1dc0349-20250617"
2710927112
};
2711027113
internals.overrideHookState = overrideHookState;
2711127114
internals.overrideHookStateDeletePath = overrideHookStateDeletePath;
@@ -27243,5 +27246,5 @@ __DEV__ &&
2724327246
listenToAllSupportedEvents(container);
2724427247
return new ReactDOMHydrationRoot(initialChildren);
2724527248
};
27246-
exports.version = "19.2.0-native-fb-75e78d24-20250616";
27249+
exports.version = "19.2.0-native-fb-e1dc0349-20250617";
2724727250
})();

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOMClient-prod.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<d04189e38310f6ee8c3a98a1b2bed36b>>
10+
* @generated SignedSource<<b77d95e8151632567305939d0be77748>>
1111
*/
1212

1313
/*
@@ -11333,6 +11333,9 @@ var DefaultAsyncDispatcher = {
1133311333
((cacheForType = resourceType()),
1133411334
cache.data.set(resourceType, cacheForType));
1133511335
return cacheForType;
11336+
},
11337+
cacheSignal: function () {
11338+
return readContext(CacheContext).controller.signal;
1133611339
}
1133711340
},
1133811341
PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map,
@@ -17118,14 +17121,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) {
1711817121
};
1711917122
var isomorphicReactPackageVersion$jscomp$inline_2017 = React.version;
1712017123
if (
17121-
"19.2.0-native-fb-75e78d24-20250616" !==
17124+
"19.2.0-native-fb-e1dc0349-20250617" !==
1712217125
isomorphicReactPackageVersion$jscomp$inline_2017
1712317126
)
1712417127
throw Error(
1712517128
formatProdErrorMessage(
1712617129
527,
1712717130
isomorphicReactPackageVersion$jscomp$inline_2017,
17128-
"19.2.0-native-fb-75e78d24-20250616"
17131+
"19.2.0-native-fb-e1dc0349-20250617"
1712917132
)
1713017133
);
1713117134
ReactDOMSharedInternals.findDOMNode = function (componentOrElement) {
@@ -17147,10 +17150,10 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) {
1714717150
};
1714817151
var internals$jscomp$inline_2536 = {
1714917152
bundleType: 0,
17150-
version: "19.2.0-native-fb-75e78d24-20250616",
17153+
version: "19.2.0-native-fb-e1dc0349-20250617",
1715117154
rendererPackageName: "react-dom",
1715217155
currentDispatcherRef: ReactSharedInternals,
17153-
reconcilerVersion: "19.2.0-native-fb-75e78d24-20250616"
17156+
reconcilerVersion: "19.2.0-native-fb-e1dc0349-20250617"
1715417157
};
1715517158
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
1715617159
var hook$jscomp$inline_2537 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -17248,4 +17251,4 @@ exports.hydrateRoot = function (container, initialChildren, options) {
1724817251
listenToAllSupportedEvents(container);
1724917252
return new ReactDOMHydrationRoot(initialChildren);
1725017253
};
17251-
exports.version = "19.2.0-native-fb-75e78d24-20250616";
17254+
exports.version = "19.2.0-native-fb-e1dc0349-20250617";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOMClient-profiling.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<5fd386cdd936654f6c3f872ef12e82dd>>
10+
* @generated SignedSource<<111b97dd282b06a774640f89b8523600>>
1111
*/
1212

1313
/*
@@ -11894,6 +11894,9 @@ var DefaultAsyncDispatcher = {
1189411894
((cacheForType = resourceType()),
1189511895
cache.data.set(resourceType, cacheForType));
1189611896
return cacheForType;
11897+
},
11898+
cacheSignal: function () {
11899+
return readContext(CacheContext).controller.signal;
1189711900
}
1189811901
},
1189911902
PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map,
@@ -17828,14 +17831,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) {
1782817831
};
1782917832
var isomorphicReactPackageVersion$jscomp$inline_2120 = React.version;
1783017833
if (
17831-
"19.2.0-native-fb-75e78d24-20250616" !==
17834+
"19.2.0-native-fb-e1dc0349-20250617" !==
1783217835
isomorphicReactPackageVersion$jscomp$inline_2120
1783317836
)
1783417837
throw Error(
1783517838
formatProdErrorMessage(
1783617839
527,
1783717840
isomorphicReactPackageVersion$jscomp$inline_2120,
17838-
"19.2.0-native-fb-75e78d24-20250616"
17841+
"19.2.0-native-fb-e1dc0349-20250617"
1783917842
)
1784017843
);
1784117844
ReactDOMSharedInternals.findDOMNode = function (componentOrElement) {
@@ -17857,10 +17860,10 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) {
1785717860
};
1785817861
var internals$jscomp$inline_2127 = {
1785917862
bundleType: 0,
17860-
version: "19.2.0-native-fb-75e78d24-20250616",
17863+
version: "19.2.0-native-fb-e1dc0349-20250617",
1786117864
rendererPackageName: "react-dom",
1786217865
currentDispatcherRef: ReactSharedInternals,
17863-
reconcilerVersion: "19.2.0-native-fb-75e78d24-20250616",
17866+
reconcilerVersion: "19.2.0-native-fb-e1dc0349-20250617",
1786417867
getLaneLabelMap: function () {
1786517868
for (
1786617869
var map = new Map(), lane = 1, index$313 = 0;
@@ -17973,4 +17976,4 @@ exports.hydrateRoot = function (container, initialChildren, options) {
1797317976
listenToAllSupportedEvents(container);
1797417977
return new ReactDOMHydrationRoot(initialChildren);
1797517978
};
17976-
exports.version = "19.2.0-native-fb-75e78d24-20250616";
17979+
exports.version = "19.2.0-native-fb-e1dc0349-20250617";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOMProfiling-dev.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<b06f747feceac8be51047297e0488527>>
10+
* @generated SignedSource<<323c0c817c416c5c3d9afafbc844fc15>>
1111
*/
1212

1313
/*
@@ -26251,6 +26251,9 @@ __DEV__ &&
2625126251
cache.data.set(resourceType, cacheForType));
2625226252
return cacheForType;
2625326253
},
26254+
cacheSignal: function () {
26255+
return readContext(CacheContext).controller.signal;
26256+
},
2625426257
getOwner: function () {
2625526258
return current;
2625626259
}
@@ -27117,11 +27120,11 @@ __DEV__ &&
2711727120
};
2711827121
(function () {
2711927122
var isomorphicReactPackageVersion = React.version;
27120-
if ("19.2.0-native-fb-75e78d24-20250616" !== isomorphicReactPackageVersion)
27123+
if ("19.2.0-native-fb-e1dc0349-20250617" !== isomorphicReactPackageVersion)
2712127124
throw Error(
2712227125
'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' +
2712327126
(isomorphicReactPackageVersion +
27124-
"\n - react-dom: 19.2.0-native-fb-75e78d24-20250616\nLearn more: https://react.dev/warnings/version-mismatch")
27127+
"\n - react-dom: 19.2.0-native-fb-e1dc0349-20250617\nLearn more: https://react.dev/warnings/version-mismatch")
2712527128
);
2712627129
})();
2712727130
("function" === typeof Map &&
@@ -27158,10 +27161,10 @@ __DEV__ &&
2715827161
!(function () {
2715927162
var internals = {
2716027163
bundleType: 1,
27161-
version: "19.2.0-native-fb-75e78d24-20250616",
27164+
version: "19.2.0-native-fb-e1dc0349-20250617",
2716227165
rendererPackageName: "react-dom",
2716327166
currentDispatcherRef: ReactSharedInternals,
27164-
reconcilerVersion: "19.2.0-native-fb-75e78d24-20250616"
27167+
reconcilerVersion: "19.2.0-native-fb-e1dc0349-20250617"
2716527168
};
2716627169
internals.overrideHookState = overrideHookState;
2716727170
internals.overrideHookStateDeletePath = overrideHookStateDeletePath;
@@ -27615,7 +27618,7 @@ __DEV__ &&
2761527618
exports.useFormStatus = function () {
2761627619
return resolveDispatcher().useHostTransitionStatus();
2761727620
};
27618-
exports.version = "19.2.0-native-fb-75e78d24-20250616";
27621+
exports.version = "19.2.0-native-fb-e1dc0349-20250617";
2761927622
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
2762027623
"function" ===
2762127624
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOMProfiling-prod.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<a13cc681f4444fb472ffa96a00f80894>>
10+
* @generated SignedSource<<df7e8e78c8a62b1b35c75abeaf139b06>>
1111
*/
1212

1313
/*
@@ -11333,6 +11333,9 @@ var DefaultAsyncDispatcher = {
1133311333
((cacheForType = resourceType()),
1133411334
cache.data.set(resourceType, cacheForType));
1133511335
return cacheForType;
11336+
},
11337+
cacheSignal: function () {
11338+
return readContext(CacheContext).controller.signal;
1133611339
}
1133711340
},
1133811341
PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map,
@@ -17129,14 +17132,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) {
1712917132
};
1713017133
var isomorphicReactPackageVersion$jscomp$inline_2018 = React.version;
1713117134
if (
17132-
"19.2.0-native-fb-75e78d24-20250616" !==
17135+
"19.2.0-native-fb-e1dc0349-20250617" !==
1713317136
isomorphicReactPackageVersion$jscomp$inline_2018
1713417137
)
1713517138
throw Error(
1713617139
formatProdErrorMessage(
1713717140
527,
1713817141
isomorphicReactPackageVersion$jscomp$inline_2018,
17139-
"19.2.0-native-fb-75e78d24-20250616"
17142+
"19.2.0-native-fb-e1dc0349-20250617"
1714017143
)
1714117144
);
1714217145
ReactDOMSharedInternals.findDOMNode = function (componentOrElement) {
@@ -17158,10 +17161,10 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) {
1715817161
};
1715917162
var internals$jscomp$inline_2539 = {
1716017163
bundleType: 0,
17161-
version: "19.2.0-native-fb-75e78d24-20250616",
17164+
version: "19.2.0-native-fb-e1dc0349-20250617",
1716217165
rendererPackageName: "react-dom",
1716317166
currentDispatcherRef: ReactSharedInternals,
17164-
reconcilerVersion: "19.2.0-native-fb-75e78d24-20250616"
17167+
reconcilerVersion: "19.2.0-native-fb-e1dc0349-20250617"
1716517168
};
1716617169
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
1716717170
var hook$jscomp$inline_2540 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -17412,4 +17415,4 @@ exports.useFormState = function (action, initialState, permalink) {
1741217415
exports.useFormStatus = function () {
1741317416
return ReactSharedInternals.H.useHostTransitionStatus();
1741417417
};
17415-
exports.version = "19.2.0-native-fb-75e78d24-20250616";
17418+
exports.version = "19.2.0-native-fb-e1dc0349-20250617";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-dom/cjs/ReactDOMProfiling-profiling.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<cf408fad07f798041c15fc74734d89c5>>
10+
* @generated SignedSource<<fac43c09363a9138535d5da8fb04d68d>>
1111
*/
1212

1313
/*
@@ -11898,6 +11898,9 @@ var DefaultAsyncDispatcher = {
1189811898
((cacheForType = resourceType()),
1189911899
cache.data.set(resourceType, cacheForType));
1190011900
return cacheForType;
11901+
},
11902+
cacheSignal: function () {
11903+
return readContext(CacheContext).controller.signal;
1190111904
}
1190211905
},
1190311906
PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map,
@@ -17843,14 +17846,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) {
1784317846
};
1784417847
var isomorphicReactPackageVersion$jscomp$inline_2121 = React.version;
1784517848
if (
17846-
"19.2.0-native-fb-75e78d24-20250616" !==
17849+
"19.2.0-native-fb-e1dc0349-20250617" !==
1784717850
isomorphicReactPackageVersion$jscomp$inline_2121
1784817851
)
1784917852
throw Error(
1785017853
formatProdErrorMessage(
1785117854
527,
1785217855
isomorphicReactPackageVersion$jscomp$inline_2121,
17853-
"19.2.0-native-fb-75e78d24-20250616"
17856+
"19.2.0-native-fb-e1dc0349-20250617"
1785417857
)
1785517858
);
1785617859
ReactDOMSharedInternals.findDOMNode = function (componentOrElement) {
@@ -17872,10 +17875,10 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) {
1787217875
};
1787317876
var internals$jscomp$inline_2128 = {
1787417877
bundleType: 0,
17875-
version: "19.2.0-native-fb-75e78d24-20250616",
17878+
version: "19.2.0-native-fb-e1dc0349-20250617",
1787617879
rendererPackageName: "react-dom",
1787717880
currentDispatcherRef: ReactSharedInternals,
17878-
reconcilerVersion: "19.2.0-native-fb-75e78d24-20250616",
17881+
reconcilerVersion: "19.2.0-native-fb-e1dc0349-20250617",
1787917882
getLaneLabelMap: function () {
1788017883
for (
1788117884
var map = new Map(), lane = 1, index$313 = 0;
@@ -18141,7 +18144,7 @@ exports.useFormState = function (action, initialState, permalink) {
1814118144
exports.useFormStatus = function () {
1814218145
return ReactSharedInternals.H.useHostTransitionStatus();
1814318146
};
18144-
exports.version = "19.2.0-native-fb-75e78d24-20250616";
18147+
exports.version = "19.2.0-native-fb-e1dc0349-20250617";
1814518148
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
1814618149
"function" ===
1814718150
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

0 commit comments

Comments
 (0)