source: node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 8.2 KB
Line 
1/**
2 * @license React
3 * use-sync-external-store-shim.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
13if (process.env.NODE_ENV !== "production") {
14 (function() {
15
16 'use strict';
17
18/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
19if (
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
28var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
29
30function 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
42function 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 */
71function 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
76var objectIs = typeof Object.is === 'function' ? Object.is : is;
77
78// dispatch for CommonJS interop named imports.
79
80var useState = React.useState,
81 useEffect = React.useEffect,
82 useLayoutEffect = React.useLayoutEffect,
83 useDebugValue = React.useDebugValue;
84var didWarnOld18Alpha = false;
85var 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
96function 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`.
100getServerSnapshot) {
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
201function 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
213function useSyncExternalStore$1(subscribe, getSnapshot, getServerSnapshot) {
214 // Note: The shim does not use getServerSnapshot, because pre-18 versions of
215 // React do not expose a way to check if we're hydrating. So users of the shim
216 // will need to track that themselves and return the correct value
217 // from `getSnapshot`.
218 return getSnapshot();
219}
220
221var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
222
223var isServerEnvironment = !canUseDOM;
224
225var shim = isServerEnvironment ? useSyncExternalStore$1 : useSyncExternalStore;
226var useSyncExternalStore$2 = React.useSyncExternalStore !== undefined ? React.useSyncExternalStore : shim;
227
228exports.useSyncExternalStore = useSyncExternalStore$2;
229 /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
230if (
231 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
232 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop ===
233 'function'
234) {
235 __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
236}
237
238 })();
239}
Note: See TracBrowser for help on using the repository browser.