1 | /**
|
---|
2 | * @license React
|
---|
3 | * use-sync-external-store-shim.native.development.js
|
---|
4 | *
|
---|
5 | * Copyright (c) Facebook, Inc. and its affiliates.
|
---|
6 | *
|
---|
7 | * This source code is licensed under the MIT license found in the
|
---|
8 | * LICENSE file in the root directory of this source tree.
|
---|
9 | */
|
---|
10 |
|
---|
11 | 'use strict';
|
---|
12 |
|
---|
13 | if (process.env.NODE_ENV !== "production") {
|
---|
14 | (function() {
|
---|
15 |
|
---|
16 | 'use strict';
|
---|
17 |
|
---|
18 | /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
|
---|
19 | if (
|
---|
20 | typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
|
---|
21 | typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart ===
|
---|
22 | 'function'
|
---|
23 | ) {
|
---|
24 | __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
|
---|
25 | }
|
---|
26 | var React = require('react');
|
---|
27 |
|
---|
28 | var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
---|
29 |
|
---|
30 | function error(format) {
|
---|
31 | {
|
---|
32 | {
|
---|
33 | for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
---|
34 | args[_key2 - 1] = arguments[_key2];
|
---|
35 | }
|
---|
36 |
|
---|
37 | printWarning('error', format, args);
|
---|
38 | }
|
---|
39 | }
|
---|
40 | }
|
---|
41 |
|
---|
42 | function printWarning(level, format, args) {
|
---|
43 | // When changing this logic, you might want to also
|
---|
44 | // update consoleWithStackDev.www.js as well.
|
---|
45 | {
|
---|
46 | var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
|
---|
47 | var stack = ReactDebugCurrentFrame.getStackAddendum();
|
---|
48 |
|
---|
49 | if (stack !== '') {
|
---|
50 | format += '%s';
|
---|
51 | args = args.concat([stack]);
|
---|
52 | } // eslint-disable-next-line react-internal/safe-string-coercion
|
---|
53 |
|
---|
54 |
|
---|
55 | var argsWithFormat = args.map(function (item) {
|
---|
56 | return String(item);
|
---|
57 | }); // Careful: RN currently depends on this prefix
|
---|
58 |
|
---|
59 | argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
|
---|
60 | // breaks IE9: https://github.com/facebook/react/issues/13610
|
---|
61 | // eslint-disable-next-line react-internal/no-production-logging
|
---|
62 |
|
---|
63 | Function.prototype.apply.call(console[level], console, argsWithFormat);
|
---|
64 | }
|
---|
65 | }
|
---|
66 |
|
---|
67 | /**
|
---|
68 | * inlined Object.is polyfill to avoid requiring consumers ship their own
|
---|
69 | * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
|
---|
70 | */
|
---|
71 | function is(x, y) {
|
---|
72 | return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
|
---|
73 | ;
|
---|
74 | }
|
---|
75 |
|
---|
76 | var objectIs = typeof Object.is === 'function' ? Object.is : is;
|
---|
77 |
|
---|
78 | // dispatch for CommonJS interop named imports.
|
---|
79 |
|
---|
80 | var useState = React.useState,
|
---|
81 | useEffect = React.useEffect,
|
---|
82 | useLayoutEffect = React.useLayoutEffect,
|
---|
83 | useDebugValue = React.useDebugValue;
|
---|
84 | var didWarnOld18Alpha = false;
|
---|
85 | var didWarnUncachedGetSnapshot = false; // Disclaimer: This shim breaks many of the rules of React, and only works
|
---|
86 | // because of a very particular set of implementation details and assumptions
|
---|
87 | // -- change any one of them and it will break. The most important assumption
|
---|
88 | // is that updates are always synchronous, because concurrent rendering is
|
---|
89 | // only available in versions of React that also have a built-in
|
---|
90 | // useSyncExternalStore API. And we only use this shim when the built-in API
|
---|
91 | // does not exist.
|
---|
92 | //
|
---|
93 | // Do not assume that the clever hacks used by this hook also work in general.
|
---|
94 | // The point of this shim is to replace the need for hacks by other libraries.
|
---|
95 |
|
---|
96 | function useSyncExternalStore(subscribe, getSnapshot, // Note: The shim does not use getServerSnapshot, because pre-18 versions of
|
---|
97 | // React do not expose a way to check if we're hydrating. So users of the shim
|
---|
98 | // will need to track that themselves and return the correct value
|
---|
99 | // from `getSnapshot`.
|
---|
100 | getServerSnapshot) {
|
---|
101 | {
|
---|
102 | if (!didWarnOld18Alpha) {
|
---|
103 | if (React.startTransition !== undefined) {
|
---|
104 | didWarnOld18Alpha = true;
|
---|
105 |
|
---|
106 | error('You are using an outdated, pre-release alpha of React 18 that ' + 'does not support useSyncExternalStore. The ' + 'use-sync-external-store shim will not work correctly. Upgrade ' + 'to a newer pre-release.');
|
---|
107 | }
|
---|
108 | }
|
---|
109 | } // Read the current snapshot from the store on every render. Again, this
|
---|
110 | // breaks the rules of React, and only works here because of specific
|
---|
111 | // implementation details, most importantly that updates are
|
---|
112 | // always synchronous.
|
---|
113 |
|
---|
114 |
|
---|
115 | var value = getSnapshot();
|
---|
116 |
|
---|
117 | {
|
---|
118 | if (!didWarnUncachedGetSnapshot) {
|
---|
119 | var cachedValue = getSnapshot();
|
---|
120 |
|
---|
121 | if (!objectIs(value, cachedValue)) {
|
---|
122 | error('The result of getSnapshot should be cached to avoid an infinite loop');
|
---|
123 |
|
---|
124 | didWarnUncachedGetSnapshot = true;
|
---|
125 | }
|
---|
126 | }
|
---|
127 | } // Because updates are synchronous, we don't queue them. Instead we force a
|
---|
128 | // re-render whenever the subscribed state changes by updating an some
|
---|
129 | // arbitrary useState hook. Then, during render, we call getSnapshot to read
|
---|
130 | // the current value.
|
---|
131 | //
|
---|
132 | // Because we don't actually use the state returned by the useState hook, we
|
---|
133 | // can save a bit of memory by storing other stuff in that slot.
|
---|
134 | //
|
---|
135 | // To implement the early bailout, we need to track some things on a mutable
|
---|
136 | // object. Usually, we would put that in a useRef hook, but we can stash it in
|
---|
137 | // our useState hook instead.
|
---|
138 | //
|
---|
139 | // To force a re-render, we call forceUpdate({inst}). That works because the
|
---|
140 | // new object always fails an equality check.
|
---|
141 |
|
---|
142 |
|
---|
143 | var _useState = useState({
|
---|
144 | inst: {
|
---|
145 | value: value,
|
---|
146 | getSnapshot: getSnapshot
|
---|
147 | }
|
---|
148 | }),
|
---|
149 | inst = _useState[0].inst,
|
---|
150 | forceUpdate = _useState[1]; // Track the latest getSnapshot function with a ref. This needs to be updated
|
---|
151 | // in the layout phase so we can access it during the tearing check that
|
---|
152 | // happens on subscribe.
|
---|
153 |
|
---|
154 |
|
---|
155 | useLayoutEffect(function () {
|
---|
156 | inst.value = value;
|
---|
157 | inst.getSnapshot = getSnapshot; // Whenever getSnapshot or subscribe changes, we need to check in the
|
---|
158 | // commit phase if there was an interleaved mutation. In concurrent mode
|
---|
159 | // this can happen all the time, but even in synchronous mode, an earlier
|
---|
160 | // effect may have mutated the store.
|
---|
161 |
|
---|
162 | if (checkIfSnapshotChanged(inst)) {
|
---|
163 | // Force a re-render.
|
---|
164 | forceUpdate({
|
---|
165 | inst: inst
|
---|
166 | });
|
---|
167 | }
|
---|
168 | }, [subscribe, value, getSnapshot]);
|
---|
169 | useEffect(function () {
|
---|
170 | // Check for changes right before subscribing. Subsequent changes will be
|
---|
171 | // detected in the subscription handler.
|
---|
172 | if (checkIfSnapshotChanged(inst)) {
|
---|
173 | // Force a re-render.
|
---|
174 | forceUpdate({
|
---|
175 | inst: inst
|
---|
176 | });
|
---|
177 | }
|
---|
178 |
|
---|
179 | var handleStoreChange = function () {
|
---|
180 | // TODO: Because there is no cross-renderer API for batching updates, it's
|
---|
181 | // up to the consumer of this library to wrap their subscription event
|
---|
182 | // with unstable_batchedUpdates. Should we try to detect when this isn't
|
---|
183 | // the case and print a warning in development?
|
---|
184 | // The store changed. Check if the snapshot changed since the last time we
|
---|
185 | // read from the store.
|
---|
186 | if (checkIfSnapshotChanged(inst)) {
|
---|
187 | // Force a re-render.
|
---|
188 | forceUpdate({
|
---|
189 | inst: inst
|
---|
190 | });
|
---|
191 | }
|
---|
192 | }; // Subscribe to the store and return a clean-up function.
|
---|
193 |
|
---|
194 |
|
---|
195 | return subscribe(handleStoreChange);
|
---|
196 | }, [subscribe]);
|
---|
197 | useDebugValue(value);
|
---|
198 | return value;
|
---|
199 | }
|
---|
200 |
|
---|
201 | function checkIfSnapshotChanged(inst) {
|
---|
202 | var latestGetSnapshot = inst.getSnapshot;
|
---|
203 | var prevValue = inst.value;
|
---|
204 |
|
---|
205 | try {
|
---|
206 | var nextValue = latestGetSnapshot();
|
---|
207 | return !objectIs(prevValue, nextValue);
|
---|
208 | } catch (error) {
|
---|
209 | return true;
|
---|
210 | }
|
---|
211 | }
|
---|
212 |
|
---|
213 | var shim = useSyncExternalStore;
|
---|
214 | var useSyncExternalStore$1 = React.useSyncExternalStore !== undefined ? React.useSyncExternalStore : shim;
|
---|
215 |
|
---|
216 | exports.useSyncExternalStore = useSyncExternalStore$1;
|
---|
217 | /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
|
---|
218 | if (
|
---|
219 | typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
|
---|
220 | typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop ===
|
---|
221 | 'function'
|
---|
222 | ) {
|
---|
223 | __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
|
---|
224 | }
|
---|
225 |
|
---|
226 | })();
|
---|
227 | }
|
---|