UNPKG

133 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
7var react = _interopDefault(require('react'));
8var reactDom = _interopDefault(require('react-dom'));
9
10/**
11 * Copyright (c) Facebook, Inc. and its affiliates.
12 *
13 * This source code is licensed under the MIT license found in the
14 * LICENSE file in the root directory of this source tree.
15 *
16 * @emails oncall+recoil
17 *
18 * @format
19 */
20
21function sprintf(format, ...args) {
22 let index = 0;
23 return format.replace(/%s/g, () => String(args[index++]));
24}
25
26var sprintf_1 = sprintf;
27
28function expectationViolation(format, ...args) {
29 if (process.env.NODE_ENV !== "production") {
30 const message = sprintf_1.call(null, format, ...args);
31 const error = new Error(message);
32 error.name = 'Expectation Violation';
33 console.error(error);
34 }
35}
36
37var expectationViolation_1 = expectationViolation;
38
39// @oss-only
40
41
42var Recoil_expectationViolation = expectationViolation_1;
43
44/**
45 * Copyright (c) Facebook, Inc. and its affiliates.
46 *
47 * This source code is licensed under the MIT license found in the
48 * LICENSE file in the root directory of this source tree.
49 *
50 * @emails oncall+recoil
51 *
52 * @format
53 */
54
55function recoverableViolation(message, projectName, {
56 error
57} = {}) {
58 if (process.env.NODE_ENV !== "production") {
59 console.error(message, error);
60 }
61
62 return null;
63}
64
65var recoverableViolation_1 = recoverableViolation;
66
67// @oss-only
68
69
70var Recoil_recoverableViolation = recoverableViolation_1;
71
72function _defineProperty(obj, key, value) {
73 if (key in obj) {
74 Object.defineProperty(obj, key, {
75 value: value,
76 enumerable: true,
77 configurable: true,
78 writable: true
79 });
80 } else {
81 obj[key] = value;
82 }
83
84 return obj;
85}
86
87/**
88 * Copyright (c) Facebook, Inc. and its affiliates.
89 *
90 * This source code is licensed under the MIT license found in the
91 * LICENSE file in the root directory of this source tree.
92 *
93 * @emails oncall+recoil
94 *
95 * @format
96 */
97
98// eslint-disable-next-line no-unused-vars
99class AbstractRecoilValue {
100 constructor(newKey) {
101 _defineProperty(this, "key", void 0);
102
103 this.key = newKey;
104 }
105
106}
107
108class RecoilState extends AbstractRecoilValue {}
109
110class RecoilValueReadOnly extends AbstractRecoilValue {}
111
112function isRecoilValue(x) {
113 return x instanceof RecoilState || x instanceof RecoilValueReadOnly;
114}
115
116var Recoil_RecoilValue = {
117 AbstractRecoilValue,
118 RecoilState,
119 RecoilValueReadOnly,
120 isRecoilValue
121};
122
123var Recoil_RecoilValue_1 = Recoil_RecoilValue.AbstractRecoilValue;
124var Recoil_RecoilValue_2 = Recoil_RecoilValue.RecoilState;
125var Recoil_RecoilValue_3 = Recoil_RecoilValue.RecoilValueReadOnly;
126var Recoil_RecoilValue_4 = Recoil_RecoilValue.isRecoilValue;
127
128var Recoil_RecoilValue$1 = /*#__PURE__*/Object.freeze({
129 __proto__: null,
130 AbstractRecoilValue: Recoil_RecoilValue_1,
131 RecoilState: Recoil_RecoilValue_2,
132 RecoilValueReadOnly: Recoil_RecoilValue_3,
133 isRecoilValue: Recoil_RecoilValue_4
134});
135
136class DefaultValue {}
137
138const DEFAULT_VALUE = new DefaultValue();
139
140class RecoilValueNotReady extends Error {
141 constructor(key) {
142 super(`Tried to set the value of Recoil selector ${key} using an updater function, but it is an async selector in a pending or error state; this is not supported.`);
143 }
144
145}
146
147// flowlint-next-line unclear-type:off
148const nodes = new Map(); // flowlint-next-line unclear-type:off
149
150const recoilValues = new Map();
151/* eslint-disable no-redeclare */
152
153function registerNode(node) {
154 if (nodes.has(node.key)) {
155 const message = `Duplicate atom key "${node.key}". This is a FATAL ERROR in
156 production. But it is safe to ignore this warning if it occurred because of
157 hot module replacement.`; // TODO Need to figure out if there is a standard/open-source equivalent to see if hot module replacement is happening:
158 // prettier-ignore
159 // @fb-only: if (__DEV__) {
160 // @fb-only: const isAcceptingUpdate = require('__debug').isAcceptingUpdate;
161 // prettier-ignore
162 // @fb-only: if (typeof isAcceptingUpdate !== 'function' || !isAcceptingUpdate()) {
163 // @fb-only: expectationViolation(message, 'recoil');
164 // @fb-only: }
165 // prettier-ignore
166 // @fb-only: } else {
167
168 Recoil_recoverableViolation(message); // @fb-only: }
169 }
170
171 nodes.set(node.key, node);
172 const recoilValue = node.set == null ? new Recoil_RecoilValue$1.RecoilValueReadOnly(node.key) : new Recoil_RecoilValue$1.RecoilState(node.key);
173 recoilValues.set(node.key, recoilValue);
174 return recoilValue;
175}
176/* eslint-enable no-redeclare */
177
178
179class NodeMissingError extends Error {} // flowlint-next-line unclear-type:off
180
181
182function getNode(key) {
183 const node = nodes.get(key);
184
185 if (node == null) {
186 throw new NodeMissingError(`Missing definition for RecoilValue: "${key}""`);
187 }
188
189 return node;
190} // flowlint-next-line unclear-type:off
191
192
193function getNodeMaybe(key) {
194 return nodes.get(key);
195}
196
197var Recoil_Node = {
198 nodes,
199 recoilValues,
200 registerNode,
201 getNode,
202 getNodeMaybe,
203 NodeMissingError,
204 DefaultValue,
205 DEFAULT_VALUE,
206 RecoilValueNotReady
207};
208
209/**
210 * Copyright (c) Facebook, Inc. and its affiliates.
211 *
212 * This source code is licensed under the MIT license found in the
213 * LICENSE file in the root directory of this source tree.
214 *
215 * @emails oncall+recoil
216 *
217 * @format
218 */
219
220function enqueueExecution(s, f) {
221 f();
222}
223
224var Recoil_Queue = {
225 enqueueExecution
226};
227
228/**
229 * Copyright (c) Facebook, Inc. and its affiliates.
230 *
231 * This source code is licensed under the MIT license found in the
232 * LICENSE file in the root directory of this source tree.
233 *
234 * Utilities for working with built-in Maps and Sets without mutating them.
235 *
236 * @emails oncall+recoil
237 *
238 * @format
239 */
240
241function setByAddingToSet(set, v) {
242 const next = new Set(set);
243 next.add(v);
244 return next;
245}
246
247function setByDeletingFromSet(set, v) {
248 const next = new Set(set);
249 next.delete(v);
250 return next;
251}
252
253function mapBySettingInMap(map, k, v) {
254 const next = new Map(map);
255 next.set(k, v);
256 return next;
257}
258
259function mapByUpdatingInMap(map, k, updater) {
260 const next = new Map(map);
261 next.set(k, updater(next.get(k)));
262 return next;
263}
264
265function mapByDeletingFromMap(map, k) {
266 const next = new Map(map);
267 next.delete(k);
268 return next;
269}
270
271function mapByDeletingMultipleFromMap(map, ks) {
272 const next = new Map(map);
273 ks.forEach(k => next.delete(k));
274 return next;
275}
276
277var Recoil_CopyOnWrite = {
278 setByAddingToSet,
279 setByDeletingFromSet,
280 mapBySettingInMap,
281 mapByUpdatingInMap,
282 mapByDeletingFromMap,
283 mapByDeletingMultipleFromMap
284};
285
286const {
287 mapByDeletingFromMap: mapByDeletingFromMap$1,
288 mapBySettingInMap: mapBySettingInMap$1,
289 setByAddingToSet: setByAddingToSet$1
290} = Recoil_CopyOnWrite;
291
292const {
293 getNode: getNode$1,
294 getNodeMaybe: getNodeMaybe$1
295} = Recoil_Node; // flowlint-next-line unclear-type:off
296
297
298const emptySet = Object.freeze(new Set());
299
300class ReadOnlyRecoilValueError extends Error {} // Get the current value loadable of a node and update the state.
301// Update dependencies and subscriptions for selectors.
302// Update saved value validation for atoms.
303
304
305function getNodeLoadable(store, state, key) {
306 return getNode$1(key).get(store, state);
307} // Peek at the current value loadable for a node without any evaluation or state change
308
309
310function peekNodeLoadable(store, state, key) {
311 return getNode$1(key).peek(store, state);
312} // Write value directly to state bypassing the Node interface as the node
313// definitions may not have been loaded yet when processing the initial snapshot.
314
315
316function setUnvalidatedAtomValue(state, key, newValue) {
317 var _node$invalidate;
318
319 const node = getNodeMaybe$1(key);
320 node === null || node === void 0 ? void 0 : (_node$invalidate = node.invalidate) === null || _node$invalidate === void 0 ? void 0 : _node$invalidate.call(node);
321 return { ...state,
322 atomValues: mapByDeletingFromMap$1(state.atomValues, key),
323 nonvalidatedAtoms: mapBySettingInMap$1(state.nonvalidatedAtoms, key, newValue),
324 dirtyAtoms: setByAddingToSet$1(state.dirtyAtoms, key)
325 };
326} // Return the discovered dependencies and values to be written by setting
327// a node value. (Multiple values may be written due to selectors getting to
328// set upstreams; deps may be discovered because of reads in updater functions.)
329
330
331function setNodeValue(store, state, key, newValue) {
332 const node = getNode$1(key);
333
334 if (node.set == null) {
335 throw new ReadOnlyRecoilValueError(`Attempt to set read-only RecoilValue: ${key}`);
336 }
337
338 return node.set(store, state, newValue);
339} // Find all of the recursively dependent nodes
340
341
342function getDownstreamNodes(store, state, keys) {
343 const visitedNodes = new Set();
344 const visitingNodes = Array.from(keys);
345 const graph = store.getGraph(state.version);
346
347 for (let key = visitingNodes.pop(); key; key = visitingNodes.pop()) {
348 var _graph$nodeToNodeSubs;
349
350 visitedNodes.add(key);
351 const subscribedNodes = (_graph$nodeToNodeSubs = graph.nodeToNodeSubscriptions.get(key)) !== null && _graph$nodeToNodeSubs !== void 0 ? _graph$nodeToNodeSubs : emptySet;
352
353 for (const downstreamNode of subscribedNodes) {
354 if (!visitedNodes.has(downstreamNode)) {
355 visitingNodes.push(downstreamNode);
356 }
357 }
358 }
359
360 return visitedNodes;
361}
362
363var Recoil_FunctionalCore = {
364 getNodeLoadable,
365 peekNodeLoadable,
366 setNodeValue,
367 setUnvalidatedAtomValue,
368 getDownstreamNodes
369};
370
371/**
372 * Copyright (c) Facebook, Inc. and its affiliates.
373 *
374 * This source code is licensed under the MIT license found in the
375 * LICENSE file in the root directory of this source tree.
376 *
377 * @emails oncall+recoil
378 *
379 * @format
380 */
381/**
382 * Returns a set containing all of the values from the first set that are not
383 * present in any of the subsequent sets.
384 *
385 * Note: this is written procedurally (i.e., without filterSet) for performant
386 * use in tight loops.
387 */
388
389function differenceSets(set, ...setsWithValuesToRemove) {
390 const ret = new Set();
391
392 FIRST: for (const value of set) {
393 for (const otherSet of setsWithValuesToRemove) {
394 if (otherSet.has(value)) {
395 continue FIRST;
396 }
397 }
398
399 ret.add(value);
400 }
401
402 return ret;
403}
404
405var Recoil_differenceSets = differenceSets;
406
407/**
408 * Copyright (c) Facebook, Inc. and its affiliates.
409 *
410 * This source code is licensed under the MIT license found in the
411 * LICENSE file in the root directory of this source tree.
412 *
413 * @emails oncall+recoil
414 *
415 * @format
416 */
417/**
418 * Returns a new Map object with the same keys as the original, but with the
419 * values replaced with the output of the given callback function.
420 */
421
422function mapMap(map, callback) {
423 const result = new Map();
424 map.forEach((value, key) => {
425 result.set(key, callback(value, key));
426 });
427 return result;
428}
429
430var Recoil_mapMap = mapMap;
431
432/**
433 * Copyright (c) Facebook, Inc. and its affiliates.
434 *
435 * This source code is licensed under the MIT license found in the
436 * LICENSE file in the root directory of this source tree.
437 *
438 * @emails oncall+recoil
439 *
440 * @format
441 */
442
443function nullthrows(x, message) {
444 if (x != null) {
445 return x;
446 }
447
448 throw new Error(message !== null && message !== void 0 ? message : 'Got unexpected null or undefined');
449}
450
451var Recoil_nullthrows = nullthrows;
452
453function graph() {
454 return {
455 nodeDeps: new Map(),
456 nodeToNodeSubscriptions: new Map()
457 };
458}
459
460function cloneGraph(graph) {
461 return {
462 nodeDeps: Recoil_mapMap(graph.nodeDeps, s => new Set(s)),
463 nodeToNodeSubscriptions: Recoil_mapMap(graph.nodeToNodeSubscriptions, s => new Set(s))
464 };
465} // Note that this overwrites the deps of existing nodes, rather than unioning
466// the new deps with the old deps.
467
468
469function mergeDependencyMapIntoGraph(deps, graph, // If olderGraph is given then we will not overwrite changes made to the given
470// graph compared with olderGraph:
471olderGraph) {
472 const {
473 nodeDeps,
474 nodeToNodeSubscriptions
475 } = graph;
476 deps.forEach((upstreams, downstream) => {
477 const existingUpstreams = nodeDeps.get(downstream);
478
479 if (existingUpstreams && olderGraph && existingUpstreams !== olderGraph.nodeDeps.get(downstream)) {
480 return;
481 } // Update nodeDeps:
482
483
484 nodeDeps.set(downstream, new Set(upstreams)); // Add new deps to nodeToNodeSubscriptions:
485
486 const addedUpstreams = existingUpstreams == null ? upstreams : Recoil_differenceSets(upstreams, existingUpstreams);
487 addedUpstreams.forEach(upstream => {
488 if (!nodeToNodeSubscriptions.has(upstream)) {
489 nodeToNodeSubscriptions.set(upstream, new Set());
490 }
491
492 const existing = Recoil_nullthrows(nodeToNodeSubscriptions.get(upstream));
493 existing.add(downstream);
494 }); // Remove removed deps from nodeToNodeSubscriptions:
495
496 if (existingUpstreams) {
497 const removedUpstreams = Recoil_differenceSets(existingUpstreams, upstreams);
498 removedUpstreams.forEach(upstream => {
499 if (!nodeToNodeSubscriptions.has(upstream)) {
500 return;
501 }
502
503 const existing = Recoil_nullthrows(nodeToNodeSubscriptions.get(upstream));
504 existing.delete(downstream);
505
506 if (existing.size === 0) {
507 nodeToNodeSubscriptions.delete(upstream);
508 }
509 });
510 }
511 });
512}
513
514function saveDependencyMapToStore(dependencyMap, store, version) {
515 var _storeState$nextTree, _storeState$previousT, _storeState$previousT2, _storeState$previousT3;
516
517 const storeState = store.getState();
518
519 if (!(version === storeState.currentTree.version || version === ((_storeState$nextTree = storeState.nextTree) === null || _storeState$nextTree === void 0 ? void 0 : _storeState$nextTree.version) || version === ((_storeState$previousT = storeState.previousTree) === null || _storeState$previousT === void 0 ? void 0 : _storeState$previousT.version))) {
520 Recoil_recoverableViolation('Tried to save dependencies to a discarded tree');
521 } // Merge the dependencies discovered into the store's dependency map
522 // for the version that was read:
523
524
525 const graph = store.getGraph(version);
526 mergeDependencyMapIntoGraph(dependencyMap, graph); // If this version is not the latest version, also write these dependencies
527 // into later versions if they don't already have their own:
528
529 if (version === ((_storeState$previousT2 = storeState.previousTree) === null || _storeState$previousT2 === void 0 ? void 0 : _storeState$previousT2.version)) {
530 const currentGraph = store.getGraph(storeState.currentTree.version);
531 mergeDependencyMapIntoGraph(dependencyMap, currentGraph, graph);
532 }
533
534 if (version === ((_storeState$previousT3 = storeState.previousTree) === null || _storeState$previousT3 === void 0 ? void 0 : _storeState$previousT3.version) || version === storeState.currentTree.version) {
535 var _storeState$nextTree2;
536
537 const nextVersion = (_storeState$nextTree2 = storeState.nextTree) === null || _storeState$nextTree2 === void 0 ? void 0 : _storeState$nextTree2.version;
538
539 if (nextVersion !== undefined) {
540 const nextGraph = store.getGraph(nextVersion);
541 mergeDependencyMapIntoGraph(dependencyMap, nextGraph, graph);
542 }
543 }
544}
545
546function mergeDepsIntoDependencyMap(from, into) {
547 from.forEach((upstreamDeps, downstreamNode) => {
548 if (!into.has(downstreamNode)) {
549 into.set(downstreamNode, new Set());
550 }
551
552 const deps = Recoil_nullthrows(into.get(downstreamNode));
553 upstreamDeps.forEach(dep => deps.add(dep));
554 });
555}
556
557function addToDependencyMap(downstream, upstream, dependencyMap) {
558 if (!dependencyMap.has(downstream)) {
559 dependencyMap.set(downstream, new Set());
560 }
561
562 Recoil_nullthrows(dependencyMap.get(downstream)).add(upstream);
563}
564
565var Recoil_Graph = {
566 addToDependencyMap,
567 cloneGraph,
568 graph,
569 mergeDepsIntoDependencyMap,
570 saveDependencyMapToStore
571};
572
573/**
574 * Copyright (c) Facebook, Inc. and its affiliates.
575 *
576 * This source code is licensed under the MIT license found in the
577 * LICENSE file in the root directory of this source tree.
578 *
579 * Interface for `scheduler/tracing` to aid in profiling Recoil and Recoil apps.
580 *
581 * @emails oncall+recoil
582 *
583 * @format
584 */
585
586// flowlint-next-line untyped-import:off
587// @fb-only: const SchedulerTracing = require('SchedulerTracing');
588function trace(message, node, fn) {
589 // prettier-ignore
590 // @fb-only: if (__DEV__) {
591 // prettier-ignore
592 // @fb-only: if (
593 // prettier-ignore
594 // @fb-only: SchedulerTracing.unstable_trace !== undefined &&
595 // prettier-ignore
596 // @fb-only: window.performance !== undefined
597 // prettier-ignore
598 // @fb-only: ) {
599 // prettier-ignore
600 // @fb-only: return SchedulerTracing.unstable_trace(
601 // prettier-ignore
602 // @fb-only: `Recoil: ${message} for node: ${
603 // prettier-ignore
604 // @fb-only: typeof node === 'string' ? node : node.key
605 // prettier-ignore
606 // @fb-only: }`,
607 // prettier-ignore
608 // @fb-only: window.performance.now(),
609 // prettier-ignore
610 // @fb-only: fn,
611 // prettier-ignore
612 // @fb-only: );
613 // prettier-ignore
614 // @fb-only: }
615 // prettier-ignore
616 // @fb-only: }
617 return fn();
618}
619
620function wrap(fn) {
621 // prettier-ignore
622 // @fb-only: if (__DEV__) {
623 // prettier-ignore
624 // @fb-only: if (SchedulerTracing.unstable_wrap !== undefined) {
625 // prettier-ignore
626 // @fb-only: return SchedulerTracing.unstable_wrap(fn);
627 // prettier-ignore
628 // @fb-only: }
629 // prettier-ignore
630 // @fb-only: }
631 return fn;
632}
633
634var Recoil_Tracing = {
635 trace,
636 wrap
637};
638
639/**
640 * Copyright (c) Facebook, Inc. and its affiliates.
641 *
642 * This source code is licensed under the MIT license found in the
643 * LICENSE file in the root directory of this source tree.
644 *
645 * @emails oncall+recoil
646 *
647 * @format
648 */
649
650function unionSets(...sets) {
651 const result = new Set();
652
653 for (const set of sets) {
654 for (const value of set) {
655 result.add(value);
656 }
657 }
658
659 return result;
660}
661
662var Recoil_unionSets = unionSets;
663
664const {
665 mapByDeletingFromMap: mapByDeletingFromMap$2,
666 mapByDeletingMultipleFromMap: mapByDeletingMultipleFromMap$1
667} = Recoil_CopyOnWrite;
668
669
670
671
672
673
674
675
676
677
678
679const {
680 getNodeLoadable: getNodeLoadable$1,
681 setNodeValue: setNodeValue$1,
682 setUnvalidatedAtomValue: setUnvalidatedAtomValue$1
683} = Recoil_FunctionalCore;
684
685const {
686 saveDependencyMapToStore: saveDependencyMapToStore$1
687} = Recoil_Graph;
688
689const {
690 DefaultValue: DefaultValue$1,
691 RecoilValueNotReady: RecoilValueNotReady$1
692} = Recoil_Node;
693
694const {
695 AbstractRecoilValue: AbstractRecoilValue$1,
696 RecoilState: RecoilState$1,
697 RecoilValueReadOnly: RecoilValueReadOnly$1,
698 isRecoilValue: isRecoilValue$1
699} = Recoil_RecoilValue$1;
700
701function getRecoilValueAsLoadable(store, {
702 key
703}, treeState = store.getState().currentTree) {
704 var _storeState$nextTree, _storeState$previousT;
705
706 // Reading from an older tree can cause bugs because the dependencies that we
707 // discover during the read are lost.
708 const storeState = store.getState();
709
710 if (!(treeState.version === storeState.currentTree.version || treeState.version === ((_storeState$nextTree = storeState.nextTree) === null || _storeState$nextTree === void 0 ? void 0 : _storeState$nextTree.version) || treeState.version === ((_storeState$previousT = storeState.previousTree) === null || _storeState$previousT === void 0 ? void 0 : _storeState$previousT.version))) {
711 Recoil_recoverableViolation('Tried to read from a discarded tree');
712 }
713
714 const [dependencyMap, loadable] = getNodeLoadable$1(store, treeState, key);
715 saveDependencyMapToStore$1(dependencyMap, store, treeState.version);
716 return loadable;
717}
718
719function applyAtomValueWrites(atomValues, writes) {
720 const result = Recoil_mapMap(atomValues, v => v);
721 writes.forEach((v, k) => {
722 if (v.state === 'hasValue' && v.contents instanceof DefaultValue$1) {
723 result.delete(k);
724 } else {
725 result.set(k, v);
726 }
727 });
728 return result;
729}
730
731function valueFromValueOrUpdater(store, {
732 key
733}, valueOrUpdater) {
734 if (typeof valueOrUpdater === 'function') {
735 var _storeState$nextTree2;
736
737 // Updater form: pass in the current value. Throw if the current value
738 // is unavailable (namely when updating an async selector that's
739 // pending or errored):
740 const storeState = store.getState();
741 const state = (_storeState$nextTree2 = storeState.nextTree) !== null && _storeState$nextTree2 !== void 0 ? _storeState$nextTree2 : storeState.currentTree; // NOTE: This will evaluate node, but not update state with node subscriptions!
742
743 const current = getNodeLoadable$1(store, state, key)[1];
744
745 if (current.state === 'loading') {
746 throw new RecoilValueNotReady$1(key);
747 } else if (current.state === 'hasError') {
748 throw current.contents;
749 } // T itself may be a function, so our refinement is not sufficient:
750
751
752 return valueOrUpdater(current.contents); // flowlint-line unclear-type:off
753 } else {
754 return valueOrUpdater;
755 }
756}
757
758function setRecoilValue(store, recoilValue, valueOrUpdater) {
759 const {
760 key
761 } = recoilValue;
762 Recoil_Tracing.trace('set RecoilValue', key, () => store.replaceState(Recoil_Tracing.wrap(state => {
763 const newValue = valueFromValueOrUpdater(store, recoilValue, valueOrUpdater);
764 const [depMap, writes] = setNodeValue$1(store, state, key, newValue);
765 const writtenNodes = new Set(writes.keys());
766 saveDependencyMapToStore$1(depMap, store, state.version);
767 return { ...state,
768 dirtyAtoms: Recoil_unionSets(state.dirtyAtoms, writtenNodes),
769 atomValues: applyAtomValueWrites(state.atomValues, writes),
770 nonvalidatedAtoms: mapByDeletingMultipleFromMap$1(state.nonvalidatedAtoms, writtenNodes)
771 };
772 })));
773}
774
775function setRecoilValueLoadable(store, recoilValue, loadable) {
776 if (loadable instanceof DefaultValue$1) {
777 return setRecoilValue(store, recoilValue, loadable);
778 }
779
780 const {
781 key
782 } = recoilValue;
783 Recoil_Tracing.trace('set RecoilValue', key, () => store.replaceState(Recoil_Tracing.wrap(state => {
784 const writtenNode = new Set([key]);
785 return { ...state,
786 dirtyAtoms: Recoil_unionSets(state.dirtyAtoms, writtenNode),
787 atomValues: applyAtomValueWrites(state.atomValues, new Map([[key, loadable]])),
788 nonvalidatedAtoms: mapByDeletingFromMap$2(state.nonvalidatedAtoms, key)
789 };
790 })));
791}
792
793function markRecoilValueModified(store, {
794 key
795}) {
796 Recoil_Tracing.trace('mark RecoilValue modified', key, () => store.replaceState(Recoil_Tracing.wrap(state => ({ ...state,
797 dirtyAtoms: Recoil_unionSets(state.dirtyAtoms, new Set([key]))
798 }))));
799}
800
801function setUnvalidatedRecoilValue(store, {
802 key
803}, newValue) {
804 Recoil_Tracing.trace('set unvalidated persisted atom', key, () => store.replaceState(Recoil_Tracing.wrap(state => {
805 const newState = setUnvalidatedAtomValue$1(state, key, newValue);
806 return newState;
807 })));
808}
809
810let subscriptionID = 0;
811
812function subscribeToRecoilValue(store, {
813 key
814}, callback) {
815 const subID = subscriptionID++;
816 const storeState = store.getState();
817
818 if (!storeState.nodeToComponentSubscriptions.has(key)) {
819 storeState.nodeToComponentSubscriptions.set(key, new Map());
820 }
821
822 Recoil_nullthrows(storeState.nodeToComponentSubscriptions.get(key)).set(subID, ['TODO debug name', callback]);
823 return {
824 release: () => {
825 const storeState = store.getState();
826 const subs = storeState.nodeToComponentSubscriptions.get(key);
827
828 if (subs === undefined || !subs.has(subID)) {
829 Recoil_recoverableViolation(`Subscription missing at release time for atom ${key}. This is a bug in Recoil.`);
830 return;
831 }
832
833 subs.delete(subID);
834
835 if (subs.size === 0) {
836 storeState.nodeToComponentSubscriptions.delete(key);
837 }
838 }
839 };
840}
841
842var Recoil_RecoilValueInterface = {
843 RecoilValueReadOnly: RecoilValueReadOnly$1,
844 AbstractRecoilValue: AbstractRecoilValue$1,
845 RecoilState: RecoilState$1,
846 getRecoilValueAsLoadable,
847 setRecoilValue,
848 setRecoilValueLoadable,
849 markRecoilValueModified,
850 setUnvalidatedRecoilValue,
851 subscribeToRecoilValue,
852 isRecoilValue: isRecoilValue$1,
853 applyAtomValueWrites // TODO Remove export when deprecating initialStoreState_DEPRECATED in RecoilRoot
854
855};
856
857/**
858 * Copyright (c) Facebook, Inc. and its affiliates.
859 *
860 * This source code is licensed under the MIT license found in the
861 * LICENSE file in the root directory of this source tree.
862 *
863 * @emails oncall+recoil
864 *
865 * @format
866 */
867/**
868 * Combines multiple Iterables into a single Iterable.
869 * Traverses the input Iterables in the order provided and maintains the order
870 * of their elements.
871 *
872 * Example:
873 * ```
874 * const r = Array.from(concatIterables(['a', 'b'], ['c'], ['d', 'e', 'f']));
875 * r == ['a', 'b', 'c', 'd', 'e', 'f'];
876 * ```
877 */
878
879function* concatIterables(iters) {
880 for (const iter of iters) {
881 for (const val of iter) {
882 yield val;
883 }
884 }
885}
886
887var Recoil_concatIterables = concatIterables;
888
889/**
890 * Copyright (c) Facebook, Inc. and its affiliates.
891 *
892 * This source code is licensed under the MIT license found in the
893 * LICENSE file in the root directory of this source tree.
894 *
895 * @emails oncall+recoil
896 *
897 * @format
898 */
899/**
900 * Creates a new iterable whose output is generated by passing the input
901 * iterable's values through the filter function.
902 */
903
904function* filterIterable(iterable, predicate) {
905 // Use generator to create iterable/iterator
906 let index = 0;
907
908 for (const value of iterable) {
909 if (predicate(value, index++)) {
910 yield value;
911 }
912 }
913}
914
915var Recoil_filterIterable = filterIterable;
916
917/**
918 * Copyright (c) Facebook, Inc. and its affiliates.
919 *
920 * This source code is licensed under the MIT license found in the
921 * LICENSE file in the root directory of this source tree.
922 *
923 * @emails oncall+recoil
924 *
925 * @format
926 */
927
928const gks = new Map();
929
930function Recoil_gkx(gk) {
931 var _gks$get;
932
933 return (_gks$get = gks.get(gk)) !== null && _gks$get !== void 0 ? _gks$get : false;
934}
935
936Recoil_gkx.setPass = gk => {
937 gks.set(gk, true);
938};
939
940Recoil_gkx.setFail = gk => {
941 gks.set(gk, false);
942};
943
944var Recoil_gkx_1 = Recoil_gkx;
945
946/**
947 * Copyright (c) Facebook, Inc. and its affiliates.
948 *
949 * This source code is licensed under the MIT license found in the
950 * LICENSE file in the root directory of this source tree.
951 *
952 * @emails oncall+recoil
953 *
954 * @format
955 */
956/**
957 * Creates a new iterable whose output is generated by passing the input
958 * iterable's values through the mapper function.
959 */
960
961function mapIterable(iterable, callback) {
962 // Use generator to create iterable/iterator
963 return function* () {
964 let index = 0;
965
966 for (const value of iterable) {
967 yield callback(value, index++);
968 }
969 }();
970}
971
972var Recoil_mapIterable = mapIterable;
973
974const {
975 graph: graph$1
976} = Recoil_Graph; // flowlint-next-line unclear-type:off
977
978
979let nextTreeStateVersion = 0;
980
981const getNextTreeStateVersion = () => nextTreeStateVersion++;
982
983function makeEmptyTreeState() {
984 const version = getNextTreeStateVersion();
985 return {
986 version,
987 stateID: version,
988 transactionMetadata: {},
989 dirtyAtoms: new Set(),
990 atomValues: new Map(),
991 nonvalidatedAtoms: new Map()
992 };
993}
994
995function makeEmptyStoreState() {
996 const currentTree = makeEmptyTreeState();
997 return {
998 currentTree,
999 nextTree: null,
1000 previousTree: null,
1001 knownAtoms: new Set(),
1002 knownSelectors: new Set(),
1003 transactionSubscriptions: new Map(),
1004 nodeTransactionSubscriptions: new Map(),
1005 nodeToComponentSubscriptions: new Map(),
1006 queuedComponentCallbacks_DEPRECATED: [],
1007 suspendedComponentResolvers: new Set(),
1008 graphsByVersion: new Map().set(currentTree.version, graph$1()),
1009 versionsUsedByComponent: new Map()
1010 };
1011}
1012
1013var Recoil_State = {
1014 makeEmptyTreeState,
1015 makeEmptyStoreState,
1016 getNextTreeStateVersion
1017};
1018
1019const {
1020 getDownstreamNodes: getDownstreamNodes$1,
1021 peekNodeLoadable: peekNodeLoadable$1
1022} = Recoil_FunctionalCore;
1023
1024const {
1025 graph: graph$2
1026} = Recoil_Graph;
1027
1028const {
1029 DEFAULT_VALUE: DEFAULT_VALUE$1,
1030 recoilValues: recoilValues$1
1031} = Recoil_Node;
1032
1033const {
1034 getRecoilValueAsLoadable: getRecoilValueAsLoadable$1,
1035 setRecoilValue: setRecoilValue$1
1036} = Recoil_RecoilValueInterface;
1037
1038const {
1039 getNextTreeStateVersion: getNextTreeStateVersion$1,
1040 makeEmptyStoreState: makeEmptyStoreState$1
1041} = Recoil_State; // Opaque at this surface because it's part of the public API from here.
1042
1043
1044function recoilValuesForKeys(keys) {
1045 return Recoil_mapIterable(keys, key => Recoil_nullthrows(recoilValues$1.get(key)));
1046} // A "Snapshot" is "read-only" and captures a specific set of values of atoms.
1047// However, the data-flow-graph and selector values may evolve as selector
1048// evaluation functions are executed and async selectors resolve.
1049
1050
1051class Snapshot {
1052 constructor(storeState) {
1053 _defineProperty(this, "_store", void 0);
1054
1055 _defineProperty(this, "getLoadable", recoilValue => getRecoilValueAsLoadable$1(this._store, recoilValue));
1056
1057 _defineProperty(this, "getPromise", recoilValue => Recoil_gkx_1('recoil_async_selector_refactor') ? this.getLoadable(recoilValue).toPromise().then(({
1058 value
1059 }) => value) : this.getLoadable(recoilValue).toPromise());
1060
1061 _defineProperty(this, "getNodes_UNSTABLE", opt => {
1062 // TODO Deal with modified selectors
1063 if ((opt === null || opt === void 0 ? void 0 : opt.isModified) === true) {
1064 if ((opt === null || opt === void 0 ? void 0 : opt.isInitialized) === false) {
1065 return [];
1066 }
1067
1068 const state = this._store.getState().currentTree;
1069
1070 return recoilValuesForKeys(state.dirtyAtoms);
1071 }
1072
1073 const knownAtoms = this._store.getState().knownAtoms;
1074
1075 const knownSelectors = this._store.getState().knownSelectors;
1076
1077 return (opt === null || opt === void 0 ? void 0 : opt.isInitialized) == null ? recoilValues$1.values() : opt.isInitialized === true ? recoilValuesForKeys(Recoil_concatIterables([this._store.getState().knownAtoms, this._store.getState().knownSelectors])) : Recoil_filterIterable(recoilValues$1.values(), ({
1078 key
1079 }) => !knownAtoms.has(key) && !knownSelectors.has(key));
1080 });
1081
1082 _defineProperty(this, "getDeps_UNSTABLE", recoilValue => {
1083 this.getLoadable(recoilValue); // Evaluate node to ensure deps are up-to-date
1084
1085 const deps = this._store.getGraph(this._store.getState().currentTree.version).nodeDeps.get(recoilValue.key);
1086
1087 return recoilValuesForKeys(deps !== null && deps !== void 0 ? deps : []);
1088 });
1089
1090 _defineProperty(this, "getSubscribers_UNSTABLE", ({
1091 key
1092 }) => {
1093 const state = this._store.getState().currentTree;
1094
1095 const downstreamNodes = Recoil_filterIterable(getDownstreamNodes$1(this._store, state, new Set([key])), nodeKey => nodeKey !== key);
1096 return {
1097 nodes: recoilValuesForKeys(downstreamNodes)
1098 };
1099 });
1100
1101 _defineProperty(this, "getInfo_UNSTABLE", recoilValue => {
1102 var _graph$nodeDeps$get;
1103
1104 const {
1105 key
1106 } = recoilValue;
1107
1108 const state = this._store.getState().currentTree;
1109
1110 const graph = this._store.getGraph(state.version);
1111
1112 return {
1113 loadable: peekNodeLoadable$1(this._store, state, key),
1114 isActive: this._store.getState().knownAtoms.has(key) || this._store.getState().knownSelectors.has(key),
1115 isSet: state.atomValues.has(key),
1116 isModified: state.dirtyAtoms.has(key),
1117 type: this._store.getState().knownAtoms.has(key) ? 'atom' : this._store.getState().knownSelectors.has(key) ? 'selector' : undefined,
1118 // Don't use this.getDeps() as it will evaluate the node and we are only peeking
1119 deps: recoilValuesForKeys((_graph$nodeDeps$get = graph.nodeDeps.get(key)) !== null && _graph$nodeDeps$get !== void 0 ? _graph$nodeDeps$get : []),
1120 subscribers: this.getSubscribers_UNSTABLE(recoilValue)
1121 };
1122 });
1123
1124 _defineProperty(this, "map", mapper => {
1125 const mutableSnapshot = new MutableSnapshot(this);
1126 mapper(mutableSnapshot);
1127 return cloneSnapshot(mutableSnapshot.getStore_INTERNAL());
1128 });
1129
1130 _defineProperty(this, "asyncMap", async mapper => {
1131 const mutableSnapshot = new MutableSnapshot(this);
1132 await mapper(mutableSnapshot);
1133 return cloneSnapshot(mutableSnapshot.getStore_INTERNAL());
1134 });
1135
1136 this._store = {
1137 getState: () => storeState,
1138 replaceState: replacer => {
1139 storeState.currentTree = replacer(storeState.currentTree); // no batching so nextTree is never active
1140 },
1141 getGraph: version => {
1142 const graphs = storeState.graphsByVersion;
1143
1144 if (graphs.has(version)) {
1145 return Recoil_nullthrows(graphs.get(version));
1146 }
1147
1148 const newGraph = graph$2();
1149 graphs.set(version, newGraph);
1150 return newGraph;
1151 },
1152 subscribeToTransactions: () => ({
1153 release: () => {}
1154 }),
1155 addTransactionMetadata: () => {
1156 throw new Error('Cannot subscribe to Snapshots');
1157 }
1158 };
1159 }
1160
1161 getStore_INTERNAL() {
1162 return this._store;
1163 }
1164
1165 getID() {
1166 return this.getID_INTERNAL();
1167 }
1168
1169 getID_INTERNAL() {
1170 return this._store.getState().currentTree.stateID;
1171 }
1172
1173}
1174
1175function cloneStoreState(store, treeState, bumpVersion = false) {
1176 const storeState = store.getState();
1177 const version = bumpVersion ? getNextTreeStateVersion$1() : treeState.version;
1178 return {
1179 currentTree: bumpVersion ? {
1180 // TODO snapshots shouldn't really have versions because a new version number
1181 // is always assigned when the snapshot is gone to.
1182 version,
1183 stateID: version,
1184 transactionMetadata: { ...treeState.transactionMetadata
1185 },
1186 dirtyAtoms: new Set(treeState.dirtyAtoms),
1187 atomValues: new Map(treeState.atomValues),
1188 nonvalidatedAtoms: new Map(treeState.nonvalidatedAtoms)
1189 } : treeState,
1190 nextTree: null,
1191 previousTree: null,
1192 knownAtoms: new Set(storeState.knownAtoms),
1193 knownSelectors: new Set(storeState.knownSelectors),
1194 transactionSubscriptions: new Map(),
1195 nodeTransactionSubscriptions: new Map(),
1196 nodeToComponentSubscriptions: new Map(),
1197 queuedComponentCallbacks_DEPRECATED: [],
1198 suspendedComponentResolvers: new Set(),
1199 graphsByVersion: new Map().set(version, store.getGraph(treeState.version)),
1200 versionsUsedByComponent: new Map()
1201 };
1202} // Factory to build a fresh snapshot
1203
1204
1205function freshSnapshot() {
1206 return new Snapshot(makeEmptyStoreState$1());
1207} // Factory to clone a snapahot state
1208
1209
1210function cloneSnapshot(store, version = 'current') {
1211 const storeState = store.getState();
1212 const treeState = version === 'current' ? storeState.currentTree : Recoil_nullthrows(storeState.previousTree);
1213 return new Snapshot(cloneStoreState(store, treeState));
1214}
1215
1216class MutableSnapshot extends Snapshot {
1217 constructor(snapshot) {
1218 super(cloneStoreState(snapshot.getStore_INTERNAL(), snapshot.getStore_INTERNAL().getState().currentTree, true));
1219
1220 _defineProperty(this, "set", (recoilState, newValueOrUpdater) => {
1221 const store = this.getStore_INTERNAL();
1222 setRecoilValue$1(store, recoilState, newValueOrUpdater);
1223 });
1224
1225 _defineProperty(this, "reset", recoilState => setRecoilValue$1(this.getStore_INTERNAL(), recoilState, DEFAULT_VALUE$1));
1226 } // We want to allow the methods to be destructured and used as accessors
1227 // eslint-disable-next-line fb-www/extra-arrow-initializer
1228
1229
1230}
1231
1232var Recoil_Snapshot = {
1233 Snapshot,
1234 MutableSnapshot,
1235 freshSnapshot,
1236 cloneSnapshot
1237};
1238
1239var Recoil_Snapshot_1 = Recoil_Snapshot.Snapshot;
1240var Recoil_Snapshot_2 = Recoil_Snapshot.MutableSnapshot;
1241var Recoil_Snapshot_3 = Recoil_Snapshot.freshSnapshot;
1242var Recoil_Snapshot_4 = Recoil_Snapshot.cloneSnapshot;
1243
1244var Recoil_Snapshot$1 = /*#__PURE__*/Object.freeze({
1245 __proto__: null,
1246 Snapshot: Recoil_Snapshot_1,
1247 MutableSnapshot: Recoil_Snapshot_2,
1248 freshSnapshot: Recoil_Snapshot_3,
1249 cloneSnapshot: Recoil_Snapshot_4
1250});
1251
1252const {
1253 useContext,
1254 useEffect,
1255 useMemo,
1256 useRef,
1257 useState
1258} = react; // @fb-only: const RecoilusagelogEvent = require('RecoilusagelogEvent');
1259// @fb-only: const RecoilUsageLogFalcoEvent = require('RecoilUsageLogFalcoEvent');
1260// @fb-only: const URI = require('URI');
1261
1262
1263
1264
1265const {
1266 getDownstreamNodes: getDownstreamNodes$2,
1267 setNodeValue: setNodeValue$2,
1268 setUnvalidatedAtomValue: setUnvalidatedAtomValue$2
1269} = Recoil_FunctionalCore;
1270
1271const {
1272 graph: graph$3,
1273 saveDependencyMapToStore: saveDependencyMapToStore$2
1274} = Recoil_Graph;
1275
1276const {
1277 cloneGraph: cloneGraph$1
1278} = Recoil_Graph;
1279
1280const {
1281 applyAtomValueWrites: applyAtomValueWrites$1
1282} = Recoil_RecoilValueInterface;
1283
1284const {
1285 freshSnapshot: freshSnapshot$1
1286} = Recoil_Snapshot$1;
1287
1288const {
1289 getNextTreeStateVersion: getNextTreeStateVersion$2,
1290 makeEmptyStoreState: makeEmptyStoreState$2
1291} = Recoil_State;
1292
1293const {
1294 mapByDeletingMultipleFromMap: mapByDeletingMultipleFromMap$2
1295} = Recoil_CopyOnWrite;
1296
1297 // @fb-only: const recoverableViolation = require('../util/Recoil_recoverableViolation');
1298
1299
1300
1301
1302 // @fb-only: const gkx = require('gkx');
1303
1304
1305function notInAContext() {
1306 throw new Error('This component must be used inside a <RecoilRoot> component.');
1307}
1308
1309const defaultStore = Object.freeze({
1310 getState: notInAContext,
1311 replaceState: notInAContext,
1312 getGraph: notInAContext,
1313 subscribeToTransactions: notInAContext,
1314 addTransactionMetadata: notInAContext
1315});
1316let stateReplacerIsBeingExecuted = false;
1317
1318function startNextTreeIfNeeded(storeState) {
1319 if (stateReplacerIsBeingExecuted) {
1320 throw new Error('An atom update was triggered within the execution of a state updater function. State updater functions provided to Recoil must be pure functions.');
1321 }
1322
1323 if (storeState.nextTree === null) {
1324 const version = storeState.currentTree.version;
1325 const nextVersion = getNextTreeStateVersion$2();
1326 storeState.nextTree = { ...storeState.currentTree,
1327 version: nextVersion,
1328 stateID: nextVersion,
1329 dirtyAtoms: new Set(),
1330 transactionMetadata: {}
1331 };
1332 storeState.graphsByVersion.set(nextVersion, cloneGraph$1(Recoil_nullthrows(storeState.graphsByVersion.get(version))));
1333 }
1334}
1335
1336const AppContext = react.createContext({
1337 current: defaultStore
1338});
1339
1340const useStoreRef = () => useContext(AppContext);
1341
1342const MutableSourceContext = react.createContext(null); // TODO T2710559282599660
1343
1344const useRecoilMutableSource = () => useContext(MutableSourceContext);
1345
1346function sendEndOfBatchNotifications(store) {
1347 const storeState = store.getState();
1348 const treeState = storeState.currentTree; // Inform transaction subscribers of the transaction:
1349
1350 const dirtyAtoms = treeState.dirtyAtoms;
1351
1352 if (dirtyAtoms.size) {
1353 // Execute Node-specific subscribers before global subscribers
1354 for (const [key, subscriptions] of storeState.nodeTransactionSubscriptions) {
1355 if (dirtyAtoms.has(key)) {
1356 for (const [_, subscription] of subscriptions) {
1357 subscription(store);
1358 }
1359 }
1360 }
1361
1362 for (const [_, subscription] of storeState.transactionSubscriptions) {
1363 subscription(store);
1364 } // Components that are subscribed to the dirty atom:
1365
1366
1367 const dependentNodes = getDownstreamNodes$2(store, treeState, dirtyAtoms);
1368
1369 for (const key of dependentNodes) {
1370 const comps = storeState.nodeToComponentSubscriptions.get(key);
1371
1372 if (comps) {
1373 for (const [_subID, [_debugName, callback]] of comps) {
1374 callback(treeState);
1375 }
1376 }
1377 } // Wake all suspended components so the right one(s) can try to re-render.
1378 // We need to wake up components not just when some asynchronous selector
1379 // resolved, but also when changing synchronous values because this may cause
1380 // a selector to change from asynchronous to synchronous, in which case there
1381 // would be no follow-up asynchronous resolution to wake us up.
1382 // TODO OPTIMIZATION Only wake up related downstream components
1383
1384
1385 let nodeNames = '[available in dev build]';
1386
1387 if (process.env.NODE_ENV !== "production") {
1388 nodeNames = Array.from(dirtyAtoms).join(', ');
1389 }
1390
1391 storeState.suspendedComponentResolvers.forEach(cb => Recoil_Tracing.trace('value became available, waking components', nodeNames, cb));
1392 } // Special behavior ONLY invoked by useInterface.
1393 // FIXME delete queuedComponentCallbacks_DEPRECATED when deleting useInterface.
1394
1395
1396 storeState.queuedComponentCallbacks_DEPRECATED.forEach(cb => cb(treeState));
1397 storeState.queuedComponentCallbacks_DEPRECATED.splice(0, storeState.queuedComponentCallbacks_DEPRECATED.length);
1398}
1399/*
1400 * The purpose of the Batcher is to observe when React batches end so that
1401 * Recoil state changes can be batched. Whenever Recoil state changes, we call
1402 * setState on the batcher. Then we wait for that change to be committed, which
1403 * signifies the end of the batch. That's when we respond to the Recoil change.
1404 */
1405
1406
1407function Batcher(props) {
1408 const storeRef = useStoreRef();
1409 const [_, setState] = useState([]);
1410 props.setNotifyBatcherOfChange(() => setState({}));
1411 useEffect(() => {
1412 // enqueueExecution runs this function immediately; it is only used to
1413 // manipulate the order of useEffects during tests, since React seems to
1414 // call useEffect in an unpredictable order sometimes.
1415 Recoil_Queue.enqueueExecution('Batcher', () => {
1416 const storeState = storeRef.current.getState();
1417 const {
1418 nextTree
1419 } = storeState; // Ignore commits that are not because of Recoil transactions -- namely,
1420 // because something above RecoilRoot re-rendered:
1421
1422 if (nextTree === null) {
1423 return;
1424 } // nextTree is now committed -- note that copying and reset occurs when
1425 // a transaction begins, in startNextTreeIfNeeded:
1426
1427
1428 storeState.previousTree = storeState.currentTree;
1429 storeState.currentTree = nextTree;
1430 storeState.nextTree = null;
1431 sendEndOfBatchNotifications(storeRef.current);
1432 const discardedVersion = Recoil_nullthrows(storeState.previousTree).version;
1433 storeState.graphsByVersion.delete(discardedVersion);
1434 storeState.previousTree = null;
1435 });
1436 });
1437 return null;
1438}
1439
1440if (process.env.NODE_ENV !== "production") {
1441 if (typeof window !== 'undefined' && !window.$recoilDebugStates) {
1442 window.$recoilDebugStates = [];
1443 }
1444} // When removing this deprecated function, remove stateBySettingRecoilValue
1445// which will no longer be needed.
1446
1447
1448function initialStoreState_DEPRECATED(store, initializeState) {
1449 const initial = makeEmptyStoreState$2();
1450 initializeState({
1451 set: (atom, value) => {
1452 const state = initial.currentTree;
1453 const [depMap, writes] = setNodeValue$2(store, state, atom.key, value);
1454 const writtenNodes = new Set(writes.keys());
1455 saveDependencyMapToStore$2(depMap, store, state.version);
1456 const nonvalidatedAtoms = mapByDeletingMultipleFromMap$2(state.nonvalidatedAtoms, writtenNodes);
1457 initial.currentTree = { ...state,
1458 dirtyAtoms: Recoil_unionSets(state.dirtyAtoms, writtenNodes),
1459 atomValues: applyAtomValueWrites$1(state.atomValues, writes),
1460 // NB: PLEASE un-export applyAtomValueWrites when deleting this code
1461 nonvalidatedAtoms
1462 };
1463 },
1464 setUnvalidatedAtomValues: atomValues => {
1465 atomValues.forEach((v, k) => {
1466 initial.currentTree = setUnvalidatedAtomValue$2(initial.currentTree, k, v);
1467 });
1468 }
1469 });
1470 return initial;
1471}
1472
1473function initialStoreState(initializeState) {
1474 const snapshot = freshSnapshot$1().map(initializeState);
1475 return snapshot.getStore_INTERNAL().getState();
1476}
1477
1478let nextID = 0;
1479
1480function RecoilRoot({
1481 initializeState_DEPRECATED,
1482 initializeState,
1483 store_INTERNAL: storeProp,
1484 // For use with React "context bridging"
1485 children
1486}) {
1487 var _createMutableSource;
1488
1489 // prettier-ignore
1490 // @fb-only: useEffect(() => {
1491 // @fb-only: if (gkx('recoil_usage_logging')) {
1492 // @fb-only: try {
1493 // @fb-only: RecoilUsageLogFalcoEvent.log(() => ({
1494 // @fb-only: type: RecoilusagelogEvent.RECOIL_ROOT_MOUNTED,
1495 // @fb-only: path: URI.getRequestURI().getPath(),
1496 // @fb-only: }));
1497 // @fb-only: } catch {
1498 // @fb-only: recoverableViolation(
1499 // @fb-only: 'Error when logging Recoil Usage event',
1500 // @fb-only: 'recoil',
1501 // @fb-only: );
1502 // @fb-only: }
1503 // @fb-only: }
1504 // @fb-only: }, []);
1505 let storeState; // eslint-disable-line prefer-const
1506
1507 const getGraph = version => {
1508 const graphs = storeState.current.graphsByVersion;
1509
1510 if (graphs.has(version)) {
1511 return Recoil_nullthrows(graphs.get(version));
1512 }
1513
1514 const newGraph = graph$3();
1515 graphs.set(version, newGraph);
1516 return newGraph;
1517 };
1518
1519 const subscribeToTransactions = (callback, key) => {
1520 if (key == null) {
1521 // Global transaction subscriptions
1522 const {
1523 transactionSubscriptions
1524 } = storeRef.current.getState();
1525 const id = nextID++;
1526 transactionSubscriptions.set(id, callback);
1527 return {
1528 release: () => {
1529 transactionSubscriptions.delete(id);
1530 }
1531 };
1532 } else {
1533 // Node-specific transaction subscriptions:
1534 const {
1535 nodeTransactionSubscriptions
1536 } = storeRef.current.getState();
1537
1538 if (!nodeTransactionSubscriptions.has(key)) {
1539 nodeTransactionSubscriptions.set(key, new Map());
1540 }
1541
1542 const id = nextID++;
1543 Recoil_nullthrows(nodeTransactionSubscriptions.get(key)).set(id, callback);
1544 return {
1545 release: () => {
1546 const subs = nodeTransactionSubscriptions.get(key);
1547
1548 if (subs) {
1549 subs.delete(id);
1550
1551 if (subs.size === 0) {
1552 nodeTransactionSubscriptions.delete(key);
1553 }
1554 }
1555 }
1556 };
1557 }
1558 };
1559
1560 const addTransactionMetadata = metadata => {
1561 startNextTreeIfNeeded(storeRef.current.getState());
1562
1563 for (const k of Object.keys(metadata)) {
1564 Recoil_nullthrows(storeRef.current.getState().nextTree).transactionMetadata[k] = metadata[k];
1565 }
1566 };
1567
1568 const replaceState = replacer => {
1569 const storeState = storeRef.current.getState();
1570 startNextTreeIfNeeded(storeState); // Use replacer to get the next state:
1571
1572 const nextTree = Recoil_nullthrows(storeState.nextTree);
1573 let replaced;
1574
1575 try {
1576 stateReplacerIsBeingExecuted = true;
1577 replaced = replacer(nextTree);
1578 } finally {
1579 stateReplacerIsBeingExecuted = false;
1580 }
1581
1582 if (replaced === nextTree) {
1583 return;
1584 }
1585
1586 if (process.env.NODE_ENV !== "production") {
1587 if (typeof window !== 'undefined') {
1588 window.$recoilDebugStates.push(replaced); // TODO this shouldn't happen here because it's not batched
1589 }
1590 } // Save changes to nextTree and schedule a React update:
1591
1592
1593 storeState.nextTree = replaced;
1594 Recoil_nullthrows(notifyBatcherOfChange.current)();
1595 };
1596
1597 const notifyBatcherOfChange = useRef(null);
1598
1599 function setNotifyBatcherOfChange(x) {
1600 notifyBatcherOfChange.current = x;
1601 } // FIXME T2710559282599660
1602
1603
1604 const createMutableSource = (_createMutableSource = react.createMutableSource) !== null && _createMutableSource !== void 0 ? _createMutableSource : // flowlint-line unclear-type:off
1605 react.unstable_createMutableSource; // flowlint-line unclear-type:off
1606
1607 const store = storeProp !== null && storeProp !== void 0 ? storeProp : {
1608 getState: () => storeState.current,
1609 replaceState,
1610 getGraph,
1611 subscribeToTransactions,
1612 addTransactionMetadata
1613 };
1614 const storeRef = useRef(store);
1615 storeState = useRef(initializeState_DEPRECATED != null ? initialStoreState_DEPRECATED(store, initializeState_DEPRECATED) : initializeState != null ? initialStoreState(initializeState) : makeEmptyStoreState$2());
1616 const mutableSource = useMemo(() => createMutableSource ? createMutableSource(storeState, () => storeState.current.currentTree.version) : null, [createMutableSource, storeState]);
1617 return /*#__PURE__*/react.createElement(AppContext.Provider, {
1618 value: storeRef
1619 }, /*#__PURE__*/react.createElement(MutableSourceContext.Provider, {
1620 value: mutableSource
1621 }, /*#__PURE__*/react.createElement(Batcher, {
1622 setNotifyBatcherOfChange: setNotifyBatcherOfChange
1623 }), children));
1624}
1625
1626var Recoil_RecoilRoot_react = {
1627 useStoreRef,
1628 useRecoilMutableSource,
1629 RecoilRoot,
1630 sendEndOfBatchNotifications_FOR_TESTING: sendEndOfBatchNotifications
1631};
1632
1633/**
1634 * Copyright (c) Facebook, Inc. and its affiliates.
1635 *
1636 * This source code is licensed under the MIT license found in the
1637 * LICENSE file in the root directory of this source tree.
1638 *
1639 * @emails oncall+recoil
1640 *
1641 * @format
1642 */
1643/**
1644 * Returns a map containing all of the keys + values from the original map where
1645 * the given callback returned true.
1646 */
1647
1648function filterMap(map, callback) {
1649 const result = new Map();
1650
1651 for (const [key, value] of map) {
1652 if (callback(value, key)) {
1653 result.set(key, value);
1654 }
1655 }
1656
1657 return result;
1658}
1659
1660var Recoil_filterMap = filterMap;
1661
1662/**
1663 * Copyright (c) Facebook, Inc. and its affiliates.
1664 *
1665 * This source code is licensed under the MIT license found in the
1666 * LICENSE file in the root directory of this source tree.
1667 *
1668 * @emails oncall+recoil
1669 *
1670 * @format
1671 */
1672/**
1673 * Returns a set containing all of the values from the original set where
1674 * the given callback returned true.
1675 */
1676
1677function filterSet(set, callback) {
1678 const result = new Set();
1679
1680 for (const value of set) {
1681 if (callback(value)) {
1682 result.add(value);
1683 }
1684 }
1685
1686 return result;
1687}
1688
1689var Recoil_filterSet = filterSet;
1690
1691/**
1692 * Copyright (c) Facebook, Inc. and its affiliates.
1693 *
1694 * This source code is licensed under the MIT license found in the
1695 * LICENSE file in the root directory of this source tree.
1696 *
1697 * @emails oncall+recoil
1698 *
1699 * @format
1700 */
1701
1702function invariant(condition, message) {
1703 if (!condition) {
1704 throw new Error(message);
1705 }
1706}
1707
1708var invariant_1 = invariant;
1709
1710// @oss-only
1711
1712
1713var Recoil_invariant = invariant_1;
1714
1715/**
1716 * Copyright (c) Facebook, Inc. and its affiliates.
1717 *
1718 * This source code is licensed under the MIT license found in the
1719 * LICENSE file in the root directory of this source tree.
1720 *
1721 * @emails oncall+recoil
1722 *
1723 * @format
1724 */
1725
1726function mergeMaps(...maps) {
1727 const result = new Map();
1728
1729 for (let i = 0; i < maps.length; i++) {
1730 const iterator = maps[i].keys();
1731 let nextKey;
1732
1733 while (!(nextKey = iterator.next()).done) {
1734 // $FlowFixMe[incompatible-call] - map/iterator knows nothing about flow types
1735 result.set(nextKey.value, maps[i].get(nextKey.value));
1736 }
1737 }
1738 /* $FlowFixMe[incompatible-return] (>=0.66.0 site=www,mobile) This comment
1739 * suppresses an error found when Flow v0.66 was deployed. To see the error
1740 * delete this comment and run Flow. */
1741
1742
1743 return result;
1744}
1745
1746var Recoil_mergeMaps = mergeMaps;
1747
1748var _useMutableSource;
1749
1750
1751
1752const {
1753 useCallback,
1754 useEffect: useEffect$1,
1755 useMemo: useMemo$1,
1756 useRef: useRef$1,
1757 useState: useState$1
1758} = react;
1759
1760
1761
1762const {
1763 DEFAULT_VALUE: DEFAULT_VALUE$2,
1764 getNode: getNode$2,
1765 nodes: nodes$1
1766} = Recoil_Node;
1767
1768const {
1769 useRecoilMutableSource: useRecoilMutableSource$1,
1770 useStoreRef: useStoreRef$1
1771} = Recoil_RecoilRoot_react;
1772
1773const {
1774 isRecoilValue: isRecoilValue$2
1775} = Recoil_RecoilValue$1;
1776
1777const {
1778 AbstractRecoilValue: AbstractRecoilValue$2,
1779 getRecoilValueAsLoadable: getRecoilValueAsLoadable$2,
1780 setRecoilValue: setRecoilValue$2,
1781 setRecoilValueLoadable: setRecoilValueLoadable$1,
1782 setUnvalidatedRecoilValue: setUnvalidatedRecoilValue$1,
1783 subscribeToRecoilValue: subscribeToRecoilValue$1
1784} = Recoil_RecoilValueInterface;
1785
1786const {
1787 Snapshot: Snapshot$1,
1788 cloneSnapshot: cloneSnapshot$1
1789} = Recoil_Snapshot$1;
1790
1791const {
1792 setByAddingToSet: setByAddingToSet$2
1793} = Recoil_CopyOnWrite;
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815function handleLoadable(loadable, atom, storeRef) {
1816 // We can't just throw the promise we are waiting on to Suspense. If the
1817 // upstream dependencies change it may produce a state in which the component
1818 // can render, but it would still be suspended on a Promise that may never resolve.
1819 if (loadable.state === 'hasValue') {
1820 return loadable.contents;
1821 } else if (loadable.state === 'loading') {
1822 const promise = new Promise(resolve => {
1823 storeRef.current.getState().suspendedComponentResolvers.add(resolve);
1824 });
1825 throw promise;
1826 } else if (loadable.state === 'hasError') {
1827 throw loadable.contents;
1828 } else {
1829 throw new Error(`Invalid value of loadable atom "${atom.key}"`);
1830 }
1831}
1832
1833function validateRecoilValue(recoilValue, hookName) {
1834 if (!isRecoilValue$2(recoilValue)) {
1835 throw new Error(`Invalid argument to ${hookName}: expected an atom or selector but got ${String(recoilValue)}`);
1836 }
1837}
1838
1839function useRecoilInterface_DEPRECATED() {
1840 const storeRef = useStoreRef$1();
1841 const [_, forceUpdate] = useState$1([]);
1842 const recoilValuesUsed = useRef$1(new Set());
1843 recoilValuesUsed.current = new Set(); // Track the RecoilValues used just during this render
1844
1845 const previousSubscriptions = useRef$1(new Set());
1846 const subscriptions = useRef$1(new Map());
1847 const unsubscribeFrom = useCallback(key => {
1848 const sub = subscriptions.current.get(key);
1849
1850 if (sub) {
1851 sub.release(storeRef.current);
1852 subscriptions.current.delete(key);
1853 }
1854 }, [storeRef, subscriptions]);
1855 useEffect$1(() => {
1856 const store = storeRef.current;
1857
1858 function updateState(_state, key) {
1859 if (!subscriptions.current.has(key)) {
1860 return;
1861 }
1862
1863 forceUpdate([]);
1864 }
1865
1866 Recoil_differenceSets(recoilValuesUsed.current, previousSubscriptions.current).forEach(key => {
1867 if (subscriptions.current.has(key)) {
1868 Recoil_expectationViolation(`Double subscription to RecoilValue "${key}"`);
1869 return;
1870 }
1871
1872 const sub = subscribeToRecoilValue$1(store, new AbstractRecoilValue$2(key), state => {
1873 Recoil_Tracing.trace('RecoilValue subscription fired', key, () => {
1874 updateState(state, key);
1875 });
1876 });
1877 subscriptions.current.set(key, sub);
1878 Recoil_Tracing.trace('initial update on subscribing', key, () => {
1879 /**
1880 * Since we're subscribing in an effect we need to update to the latest
1881 * value of the atom since it may have changed since we rendered. We can
1882 * go ahead and do that now, unless we're in the middle of a batch --
1883 * in which case we should do it at the end of the batch, due to the
1884 * following edge case: Suppose an atom is updated in another useEffect
1885 * of this same component. Then the following sequence of events occur:
1886 * 1. Atom is updated and subs fired (but we may not be subscribed
1887 * yet depending on order of effects, so we miss this) Updated value
1888 * is now in nextTree, but not currentTree.
1889 * 2. This effect happens. We subscribe and update.
1890 * 3. From the update we re-render and read currentTree, with old value.
1891 * 4. Batcher's effect sets currentTree to nextTree.
1892 * In this sequence we miss the update. To avoid that, add the update
1893 * to queuedComponentCallback if a batch is in progress.
1894 */
1895 // FIXME delete queuedComponentCallbacks_DEPRECATED when deleting useInterface.
1896 const state = store.getState();
1897
1898 if (state.nextTree) {
1899 store.getState().queuedComponentCallbacks_DEPRECATED.push(Recoil_Tracing.wrap(() => {
1900 updateState(store.getState(), key);
1901 }));
1902 } else {
1903 updateState(store.getState(), key);
1904 }
1905 });
1906 });
1907 Recoil_differenceSets(previousSubscriptions.current, recoilValuesUsed.current).forEach(key => {
1908 unsubscribeFrom(key);
1909 });
1910 previousSubscriptions.current = recoilValuesUsed.current;
1911 });
1912 useEffect$1(() => {
1913 const subs = subscriptions.current;
1914 return () => subs.forEach((_, key) => unsubscribeFrom(key));
1915 }, [unsubscribeFrom]);
1916 return useMemo$1(() => {
1917 function useSetRecoilState(recoilState) {
1918 if (process.env.NODE_ENV !== "production") {
1919 validateRecoilValue(recoilState, 'useSetRecoilState');
1920 }
1921
1922 return newValueOrUpdater => {
1923 setRecoilValue$2(storeRef.current, recoilState, newValueOrUpdater);
1924 };
1925 }
1926
1927 function useResetRecoilState(recoilState) {
1928 if (process.env.NODE_ENV !== "production") {
1929 validateRecoilValue(recoilState, 'useResetRecoilState');
1930 }
1931
1932 return () => setRecoilValue$2(storeRef.current, recoilState, DEFAULT_VALUE$2);
1933 }
1934
1935 function useRecoilValueLoadable(recoilValue) {
1936 if (process.env.NODE_ENV !== "production") {
1937 validateRecoilValue(recoilValue, 'useRecoilValueLoadable');
1938 }
1939
1940 if (!recoilValuesUsed.current.has(recoilValue.key)) {
1941 recoilValuesUsed.current = setByAddingToSet$2(recoilValuesUsed.current, recoilValue.key);
1942 } // TODO Restore optimization to memoize lookup
1943
1944
1945 return getRecoilValueAsLoadable$2(storeRef.current, recoilValue);
1946 }
1947
1948 function useRecoilValue(recoilValue) {
1949 if (process.env.NODE_ENV !== "production") {
1950 validateRecoilValue(recoilValue, 'useRecoilValue');
1951 }
1952
1953 const loadable = useRecoilValueLoadable(recoilValue);
1954 return handleLoadable(loadable, recoilValue, storeRef);
1955 }
1956
1957 function useRecoilState(recoilState) {
1958 if (process.env.NODE_ENV !== "production") {
1959 validateRecoilValue(recoilState, 'useRecoilState');
1960 }
1961
1962 return [useRecoilValue(recoilState), useSetRecoilState(recoilState)];
1963 }
1964
1965 function useRecoilStateLoadable(recoilState) {
1966 if (process.env.NODE_ENV !== "production") {
1967 validateRecoilValue(recoilState, 'useRecoilStateLoadable');
1968 }
1969
1970 return [useRecoilValueLoadable(recoilState), useSetRecoilState(recoilState)];
1971 }
1972
1973 return {
1974 getRecoilValue: useRecoilValue,
1975 getRecoilValueLoadable: useRecoilValueLoadable,
1976 getRecoilState: useRecoilState,
1977 getRecoilStateLoadable: useRecoilStateLoadable,
1978 getSetRecoilState: useSetRecoilState,
1979 getResetRecoilState: useResetRecoilState
1980 };
1981 }, [recoilValuesUsed, storeRef]);
1982}
1983
1984if (process.env.NODE_ENV !== "production") {
1985 window.$recoilComponentGetRecoilValueCount_FOR_TESTING = 0;
1986}
1987
1988function useRecoilValueLoadable_MUTABLESOURCE(recoilValue) {
1989 if (process.env.NODE_ENV !== "production") {
1990 validateRecoilValue(recoilValue, 'useRecoilValueLoadable');
1991 }
1992
1993 const storeRef = useStoreRef$1();
1994 const getValue = useCallback(() => {
1995 if (process.env.NODE_ENV !== "production") {
1996 window.$recoilComponentGetRecoilValueCount_FOR_TESTING++;
1997 }
1998
1999 return getRecoilValueAsLoadable$2(storeRef.current, recoilValue, storeRef.current.getState().currentTree);
2000 }, [storeRef, recoilValue]);
2001 const subscribe = useCallback((_something, callback) => {
2002 const store = storeRef.current;
2003 const sub = subscribeToRecoilValue$1(store, recoilValue, () => {
2004 Recoil_Tracing.trace('RecoilValue subscription fired', recoilValue.key, () => {
2005 callback();
2006 });
2007 });
2008 return () => sub.release(store);
2009 }, [recoilValue, storeRef]);
2010 return useMutableSource(useRecoilMutableSource$1(), getValue, subscribe);
2011}
2012
2013function useRecoilValueLoadable_LEGACY(recoilValue) {
2014 if (process.env.NODE_ENV !== "production") {
2015 validateRecoilValue(recoilValue, 'useRecoilValueLoadable');
2016 }
2017
2018 const storeRef = useStoreRef$1();
2019 const [_, forceUpdate] = useState$1([]);
2020 useEffect$1(() => {
2021 const store = storeRef.current;
2022 const sub = subscribeToRecoilValue$1(store, recoilValue, _state => {
2023 Recoil_Tracing.trace('RecoilValue subscription fired', recoilValue.key, () => {
2024 forceUpdate([]);
2025 });
2026 });
2027 Recoil_Tracing.trace('initial update on subscribing', recoilValue.key, () => {
2028 /**
2029 * Since we're subscribing in an effect we need to update to the latest
2030 * value of the atom since it may have changed since we rendered. We can
2031 * go ahead and do that now, unless we're in the middle of a batch --
2032 * in which case we should do it at the end of the batch, due to the
2033 * following edge case: Suppose an atom is updated in another useEffect
2034 * of this same component. Then the following sequence of events occur:
2035 * 1. Atom is updated and subs fired (but we may not be subscribed
2036 * yet depending on order of effects, so we miss this) Updated value
2037 * is now in nextTree, but not currentTree.
2038 * 2. This effect happens. We subscribe and update.
2039 * 3. From the update we re-render and read currentTree, with old value.
2040 * 4. Batcher's effect sets currentTree to nextTree.
2041 * In this sequence we miss the update. To avoid that, add the update
2042 * to queuedComponentCallback if a batch is in progress.
2043 */
2044 const state = store.getState();
2045
2046 if (state.nextTree) {
2047 store.getState().queuedComponentCallbacks_DEPRECATED.push(Recoil_Tracing.wrap(() => {
2048 forceUpdate([]);
2049 }));
2050 } else {
2051 forceUpdate([]);
2052 }
2053 });
2054 return () => sub.release(store);
2055 }, [recoilValue, storeRef]);
2056 return getRecoilValueAsLoadable$2(storeRef.current, recoilValue);
2057} // FIXME T2710559282599660
2058
2059
2060const useMutableSource = (_useMutableSource = react.useMutableSource) !== null && _useMutableSource !== void 0 ? _useMutableSource : react.unstable_useMutableSource; // flowlint-line unclear-type:off
2061
2062/**
2063 Like useRecoilValue(), but either returns the value if available or
2064 just undefined if not available for any reason, such as pending or error.
2065*/
2066
2067function useRecoilValueLoadable(recoilValue) {
2068 if (useMutableSource && !window.disableRecoilValueMutableSource) {
2069 // eslint-disable-next-line fb-www/react-hooks
2070 return useRecoilValueLoadable_MUTABLESOURCE(recoilValue);
2071 } else {
2072 // eslint-disable-next-line fb-www/react-hooks
2073 return useRecoilValueLoadable_LEGACY(recoilValue);
2074 }
2075}
2076/**
2077 Returns the value represented by the RecoilValue.
2078 If the value is pending, it will throw a Promise to suspend the component,
2079 if the value is an error it will throw it for the nearest React error boundary.
2080 This will also subscribe the component for any updates in the value.
2081 */
2082
2083
2084function useRecoilValue(recoilValue) {
2085 if (process.env.NODE_ENV !== "production") {
2086 validateRecoilValue(recoilValue, 'useRecoilValue');
2087 }
2088
2089 const storeRef = useStoreRef$1();
2090 const loadable = useRecoilValueLoadable(recoilValue);
2091 return handleLoadable(loadable, recoilValue, storeRef);
2092}
2093/**
2094 Returns a function that allows the value of a RecoilState to be updated, but does
2095 not subscribe the component to changes to that RecoilState.
2096*/
2097
2098
2099function useSetRecoilState(recoilState) {
2100 if (process.env.NODE_ENV !== "production") {
2101 validateRecoilValue(recoilState, 'useSetRecoilState');
2102 }
2103
2104 const storeRef = useStoreRef$1();
2105 return useCallback(newValueOrUpdater => {
2106 setRecoilValue$2(storeRef.current, recoilState, newValueOrUpdater);
2107 }, [storeRef, recoilState]);
2108}
2109/**
2110 Returns a function that will reset the value of a RecoilState to its default
2111*/
2112
2113
2114function useResetRecoilState(recoilState) {
2115 if (process.env.NODE_ENV !== "production") {
2116 validateRecoilValue(recoilState, 'useResetRecoilState');
2117 }
2118
2119 const storeRef = useStoreRef$1();
2120 return useCallback(() => {
2121 setRecoilValue$2(storeRef.current, recoilState, DEFAULT_VALUE$2);
2122 }, [storeRef, recoilState]);
2123}
2124/**
2125 Equivalent to useState(). Allows the value of the RecoilState to be read and written.
2126 Subsequent updates to the RecoilState will cause the component to re-render. If the
2127 RecoilState is pending, this will suspend the component and initiate the
2128 retrieval of the value. If evaluating the RecoilState resulted in an error, this will
2129 throw the error so that the nearest React error boundary can catch it.
2130*/
2131
2132
2133function useRecoilState(recoilState) {
2134 if (process.env.NODE_ENV !== "production") {
2135 validateRecoilValue(recoilState, 'useRecoilState');
2136 }
2137
2138 return [useRecoilValue(recoilState), useSetRecoilState(recoilState)];
2139}
2140/**
2141 Like useRecoilState(), but does not cause Suspense or React error handling. Returns
2142 an object that indicates whether the RecoilState is available, pending, or
2143 unavailable due to an error.
2144*/
2145
2146
2147function useRecoilStateLoadable(recoilState) {
2148 if (process.env.NODE_ENV !== "production") {
2149 validateRecoilValue(recoilState, 'useRecoilStateLoadable');
2150 }
2151
2152 return [useRecoilValueLoadable(recoilState), useSetRecoilState(recoilState)];
2153}
2154
2155function useTransactionSubscription(callback) {
2156 const storeRef = useStoreRef$1();
2157 useEffect$1(() => {
2158 const sub = storeRef.current.subscribeToTransactions(callback);
2159 return sub.release;
2160 }, [callback, storeRef]);
2161}
2162
2163function externallyVisibleAtomValuesInState(state) {
2164 const atomValues = state.atomValues;
2165 const persistedAtomContentsValues = Recoil_mapMap(Recoil_filterMap(atomValues, (v, k) => {
2166 const node = getNode$2(k);
2167 const persistence = node.persistence_UNSTABLE;
2168 return persistence != null && persistence.type !== 'none' && v.state === 'hasValue';
2169 }), v => v.contents); // Merge in nonvalidated atoms; we may not have defs for them but they will
2170 // all have persistence on or they wouldn't be there in the first place.
2171
2172 return Recoil_mergeMaps(state.nonvalidatedAtoms, persistedAtomContentsValues);
2173}
2174
2175/**
2176 Calls the given callback after any atoms have been modified and the consequent
2177 component re-renders have been committed. This is intended for persisting
2178 the values of the atoms to storage. The stored values can then be restored
2179 using the useSetUnvalidatedAtomValues hook.
2180
2181 The callback receives the following info:
2182
2183 atomValues: The current value of every atom that is both persistable (persistence
2184 type not set to 'none') and whose value is available (not in an
2185 error or loading state).
2186
2187 previousAtomValues: The value of every persistable and available atom before
2188 the transaction began.
2189
2190 atomInfo: A map containing the persistence settings for each atom. Every key
2191 that exists in atomValues will also exist in atomInfo.
2192
2193 modifiedAtoms: The set of atoms that were written to during the transaction.
2194
2195 transactionMetadata: Arbitrary information that was added via the
2196 useSetUnvalidatedAtomValues hook. Useful for ignoring the useSetUnvalidatedAtomValues
2197 transaction, to avoid loops.
2198*/
2199function useTransactionObservation_DEPRECATED(callback) {
2200 useTransactionSubscription(useCallback(store => {
2201 let previousTree = store.getState().previousTree;
2202 const currentTree = store.getState().currentTree;
2203
2204 if (!previousTree) {
2205 Recoil_recoverableViolation('Transaction subscribers notified without a previous tree being present -- this is a bug in Recoil');
2206 previousTree = store.getState().currentTree; // attempt to trundle on
2207 }
2208
2209 const atomValues = externallyVisibleAtomValuesInState(currentTree);
2210 const previousAtomValues = externallyVisibleAtomValuesInState(previousTree);
2211 const atomInfo = Recoil_mapMap(nodes$1, node => {
2212 var _node$persistence_UNS, _node$persistence_UNS2, _node$persistence_UNS3, _node$persistence_UNS4;
2213
2214 return {
2215 persistence_UNSTABLE: {
2216 type: (_node$persistence_UNS = (_node$persistence_UNS2 = node.persistence_UNSTABLE) === null || _node$persistence_UNS2 === void 0 ? void 0 : _node$persistence_UNS2.type) !== null && _node$persistence_UNS !== void 0 ? _node$persistence_UNS : 'none',
2217 backButton: (_node$persistence_UNS3 = (_node$persistence_UNS4 = node.persistence_UNSTABLE) === null || _node$persistence_UNS4 === void 0 ? void 0 : _node$persistence_UNS4.backButton) !== null && _node$persistence_UNS3 !== void 0 ? _node$persistence_UNS3 : false
2218 }
2219 };
2220 }); // Filter on existance in atomValues so that externally-visible rules
2221 // are also applied to modified atoms (specifically exclude selectors):
2222
2223 const modifiedAtoms = Recoil_filterSet(currentTree.dirtyAtoms, k => atomValues.has(k) || previousAtomValues.has(k));
2224 callback({
2225 atomValues,
2226 previousAtomValues,
2227 atomInfo,
2228 modifiedAtoms,
2229 transactionMetadata: { ...currentTree.transactionMetadata
2230 }
2231 });
2232 }, [callback]));
2233}
2234
2235function useRecoilTransactionObserver(callback) {
2236 useTransactionSubscription(useCallback(store => {
2237 callback({
2238 snapshot: cloneSnapshot$1(store, 'current'),
2239 previousSnapshot: cloneSnapshot$1(store, 'previous')
2240 });
2241 }, [callback]));
2242} // Return a snapshot of the current state and subscribe to all state changes
2243
2244
2245function useRecoilSnapshot() {
2246 const storeRef = useStoreRef$1();
2247 const [snapshot, setSnapshot] = useState$1(() => cloneSnapshot$1(storeRef.current));
2248 useTransactionSubscription(useCallback(store => setSnapshot(cloneSnapshot$1(store)), []));
2249 return snapshot;
2250}
2251
2252function useGotoRecoilSnapshot() {
2253 const storeRef = useStoreRef$1();
2254 return useCallback(snapshot => {
2255 var _storeState$nextTree;
2256
2257 const storeState = storeRef.current.getState();
2258 const prev = (_storeState$nextTree = storeState.nextTree) !== null && _storeState$nextTree !== void 0 ? _storeState$nextTree : storeState.currentTree;
2259 const next = snapshot.getStore_INTERNAL().getState().currentTree;
2260 reactDom.unstable_batchedUpdates(() => {
2261 const keysToUpdate = new Set();
2262
2263 for (const keys of [prev.atomValues.keys(), next.atomValues.keys()]) {
2264 for (const key of keys) {
2265 var _prev$atomValues$get, _next$atomValues$get;
2266
2267 if (((_prev$atomValues$get = prev.atomValues.get(key)) === null || _prev$atomValues$get === void 0 ? void 0 : _prev$atomValues$get.contents) !== ((_next$atomValues$get = next.atomValues.get(key)) === null || _next$atomValues$get === void 0 ? void 0 : _next$atomValues$get.contents) && getNode$2(key).shouldRestoreFromSnapshots) {
2268 keysToUpdate.add(key);
2269 }
2270 }
2271 }
2272
2273 keysToUpdate.forEach(key => {
2274 setRecoilValueLoadable$1(storeRef.current, new AbstractRecoilValue$2(key), next.atomValues.has(key) ? Recoil_nullthrows(next.atomValues.get(key)) : DEFAULT_VALUE$2);
2275 });
2276 storeRef.current.replaceState(state => {
2277 return { ...state,
2278 stateID: snapshot.getID_INTERNAL()
2279 };
2280 });
2281 });
2282 }, [storeRef]);
2283}
2284
2285function useSetUnvalidatedAtomValues() {
2286 const storeRef = useStoreRef$1();
2287 return (values, transactionMetadata = {}) => {
2288 reactDom.unstable_batchedUpdates(() => {
2289 storeRef.current.addTransactionMetadata(transactionMetadata);
2290 values.forEach((value, key) => setUnvalidatedRecoilValue$1(storeRef.current, new AbstractRecoilValue$2(key), value));
2291 });
2292 };
2293}
2294
2295class Sentinel {}
2296
2297const SENTINEL = new Sentinel();
2298
2299function useRecoilCallback(fn, deps) {
2300 const storeRef = useStoreRef$1();
2301 const gotoSnapshot = useGotoRecoilSnapshot();
2302 return useCallback((...args) => {
2303 // Use currentTree for the snapshot to show the currently committed state
2304 const snapshot = cloneSnapshot$1(storeRef.current);
2305
2306 function set(recoilState, newValueOrUpdater) {
2307 setRecoilValue$2(storeRef.current, recoilState, newValueOrUpdater);
2308 }
2309
2310 function reset(recoilState) {
2311 setRecoilValue$2(storeRef.current, recoilState, DEFAULT_VALUE$2);
2312 }
2313
2314 let ret = SENTINEL;
2315 reactDom.unstable_batchedUpdates(() => {
2316 // flowlint-next-line unclear-type:off
2317 ret = fn({
2318 set,
2319 reset,
2320 snapshot,
2321 gotoSnapshot
2322 })(...args);
2323 });
2324 !!(ret instanceof Sentinel) ? process.env.NODE_ENV !== "production" ? Recoil_invariant(false, 'unstable_batchedUpdates should return immediately') : Recoil_invariant(false) : void 0;
2325 return ret;
2326 }, deps != null ? [...deps, storeRef] : undefined // eslint-disable-line fb-www/react-hooks-deps
2327 );
2328}
2329
2330var Recoil_Hooks = {
2331 useRecoilCallback,
2332 useRecoilValue,
2333 useRecoilValueLoadable,
2334 useRecoilState,
2335 useRecoilStateLoadable,
2336 useSetRecoilState,
2337 useResetRecoilState,
2338 useRecoilInterface: useRecoilInterface_DEPRECATED,
2339 useTransactionSubscription_DEPRECATED: useTransactionSubscription,
2340 useTransactionObservation_DEPRECATED,
2341 useRecoilTransactionObserver,
2342 useRecoilSnapshot,
2343 useGotoRecoilSnapshot,
2344 useSetUnvalidatedAtomValues
2345};
2346
2347const {
2348 useMemo: useMemo$2
2349} = react;
2350
2351const {
2352 RecoilRoot: RecoilRoot$1,
2353 useStoreRef: useStoreRef$2
2354} = Recoil_RecoilRoot_react;
2355
2356function useRecoilBridgeAcrossReactRoots() {
2357 const store = useStoreRef$2().current;
2358 return useMemo$2(() => {
2359 function RecoilBridge({
2360 children
2361 }) {
2362 return /*#__PURE__*/react.createElement(RecoilRoot$1, {
2363 store_INTERNAL: store
2364 }, children);
2365 }
2366
2367 return RecoilBridge;
2368 }, [store]);
2369}
2370
2371var Recoil_useRecoilBridgeAcrossReactRoots = useRecoilBridgeAcrossReactRoots;
2372
2373/**
2374 * Copyright (c) Facebook, Inc. and its affiliates.
2375 *
2376 * This source code is licensed under the MIT license found in the
2377 * LICENSE file in the root directory of this source tree.
2378 *
2379 * @emails oncall+recoil
2380 *
2381 * @format
2382 */
2383
2384// Split declaration and implementation to allow this function to pretend to
2385// check for actual instance of Promise instead of something with a `then`
2386// method.
2387// eslint-disable-next-line no-redeclare
2388function isPromise(p) {
2389 return !!p && typeof p.then === 'function';
2390}
2391
2392var Recoil_isPromise = isPromise;
2393
2394// TODO Convert Loadable to a Class to allow for runtime type detection.
2395// Containing static factories of withValue(), withError(), withPromise(), and all()
2396
2397
2398const loadableAccessors = {
2399 getValue() {
2400 if (this.state !== 'hasValue') {
2401 throw this.contents; // Throw Error, or Promise for the loading state
2402 }
2403
2404 return this.contents;
2405 },
2406
2407 toPromise() {
2408 return this.state === 'hasValue' ? Promise.resolve(this.contents) : this.state === 'hasError' ? Promise.reject(this.contents) : this.contents;
2409 },
2410
2411 valueMaybe() {
2412 return this.state === 'hasValue' ? this.contents : undefined;
2413 },
2414
2415 valueOrThrow() {
2416 if (this.state !== 'hasValue') {
2417 throw new Error(`Loadable expected value, but in "${this.state}" state`);
2418 }
2419
2420 return this.contents;
2421 },
2422
2423 errorMaybe() {
2424 return this.state === 'hasError' ? this.contents : undefined;
2425 },
2426
2427 errorOrThrow() {
2428 if (this.state !== 'hasError') {
2429 throw new Error(`Loadable expected error, but in "${this.state}" state`);
2430 }
2431
2432 return this.contents;
2433 },
2434
2435 promiseMaybe() {
2436 return this.state === 'loading' ? this.contents : undefined;
2437 },
2438
2439 promiseOrThrow() {
2440 if (this.state !== 'loading') {
2441 throw new Error(`Loadable expected promise, but in "${this.state}" state`);
2442 }
2443
2444 return this.contents;
2445 },
2446
2447 // TODO Unit tests
2448 // TODO Convert Loadable to a Class to better support chaining
2449 // by returning a Loadable from a map function
2450 map(map) {
2451 if (this.state === 'hasError') {
2452 return this;
2453 }
2454
2455 if (this.state === 'hasValue') {
2456 try {
2457 const next = map(this.contents); // TODO if next instanceof Loadable, then return next
2458
2459 return Recoil_isPromise(next) ? loadableWithPromise(next) : loadableWithValue(next);
2460 } catch (e) {
2461 return Recoil_isPromise(e) ? // If we "suspended", then try again.
2462 // errors and subsequent retries will be handled in 'loading' case
2463 loadableWithPromise(e.next(() => map(this.contents))) : loadableWithError(e);
2464 }
2465 }
2466
2467 if (this.state === 'loading') {
2468 return loadableWithPromise(this.contents // TODO if map returns a loadable, then return the value or promise or throw the error
2469 .then(map).catch(e => {
2470 if (Recoil_isPromise(e)) {
2471 // we were "suspended," try again
2472 return e.then(() => map(this.contents));
2473 }
2474
2475 throw e;
2476 }));
2477 }
2478
2479 throw new Error('Invalid Loadable state');
2480 }
2481
2482};
2483
2484function loadableWithValue(value) {
2485 // Build objects this way since Flow doesn't support disjoint unions for class properties
2486 return Object.freeze({
2487 state: 'hasValue',
2488 contents: value,
2489 ...loadableAccessors
2490 });
2491}
2492
2493function loadableWithError(error) {
2494 return Object.freeze({
2495 state: 'hasError',
2496 contents: error,
2497 ...loadableAccessors
2498 });
2499}
2500
2501function loadableWithPromise(promise) {
2502 return Object.freeze({
2503 state: 'loading',
2504 contents: promise,
2505 ...loadableAccessors
2506 });
2507}
2508
2509function loadableLoading() {
2510 return loadableWithPromise(new Promise(() => {}));
2511}
2512
2513function loadableAll(inputs) {
2514 return inputs.every(i => i.state === 'hasValue') ? loadableWithValue(inputs.map(i => i.contents)) : inputs.some(i => i.state === 'hasError') ? loadableWithError( // $FlowIssue[incompatible-call] #44070740 Array.find should refine parameter
2515 Recoil_nullthrows(inputs.find(i => i.state === 'hasError'), 'Invalid loadable passed to loadableAll').contents) : loadableWithPromise(Recoil_gkx_1('recoil_async_selector_refactor') ? Promise.all(inputs.map(i => i.contents)).then(value => ({
2516 value
2517 })) : Promise.all(inputs.map(i => i.contents)));
2518}
2519
2520var Recoil_Loadable = {
2521 loadableWithValue,
2522 loadableWithError,
2523 loadableWithPromise,
2524 loadableLoading,
2525 loadableAll
2526};
2527
2528/**
2529 * Copyright (c) Facebook, Inc. and its affiliates.
2530 *
2531 * This source code is licensed under the MIT license found in the
2532 * LICENSE file in the root directory of this source tree.
2533 *
2534 * @emails oncall+recoil
2535 *
2536 * @format
2537 */
2538
2539function isNode(object) {
2540 var _ownerDocument, _doc$defaultView;
2541
2542 if (typeof window === 'undefined') {
2543 return false;
2544 }
2545
2546 const doc = object != null ? (_ownerDocument = object.ownerDocument) !== null && _ownerDocument !== void 0 ? _ownerDocument : object : document;
2547 const defaultView = (_doc$defaultView = doc.defaultView) !== null && _doc$defaultView !== void 0 ? _doc$defaultView : window;
2548 return !!(object != null && (typeof defaultView.Node === 'function' ? object instanceof defaultView.Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'));
2549}
2550
2551var Recoil_isNode = isNode;
2552
2553function shouldNotBeFrozen(value) {
2554 // Primitives and functions:
2555 if (value === null || typeof value !== 'object') {
2556 return true;
2557 } // React elements:
2558
2559
2560 switch (typeof value.$$typeof) {
2561 case 'symbol':
2562 return true;
2563
2564 case 'number':
2565 return true;
2566 } // Immutable structures:
2567
2568
2569 if (value['@@__IMMUTABLE_ITERABLE__@@'] != null || value['@@__IMMUTABLE_KEYED__@@'] != null || value['@@__IMMUTABLE_INDEXED__@@'] != null || value['@@__IMMUTABLE_ORDERED__@@'] != null || value['@@__IMMUTABLE_RECORD__@@'] != null) {
2570 return true;
2571 } // DOM nodes:
2572
2573
2574 if (Recoil_isNode(value)) {
2575 return true;
2576 }
2577
2578 if (Recoil_isPromise(value)) {
2579 return true;
2580 }
2581
2582 return false;
2583} // Recursively freeze a value to enforce it is read-only.
2584// This may also have minimal performance improvements for enumerating
2585// objects (based on browser implementations, of course)
2586
2587
2588function deepFreezeValue(value) {
2589 if (typeof value !== 'object' || shouldNotBeFrozen(value)) {
2590 return;
2591 }
2592
2593 Object.freeze(value); // Make all properties read-only
2594
2595 for (const key in value) {
2596 if (Object.prototype.hasOwnProperty.call(value, key)) {
2597 const prop = value[key]; // Prevent infinite recurssion for circular references.
2598
2599 if (typeof prop === 'object' && prop != null && !Object.isFrozen(prop)) {
2600 deepFreezeValue(prop);
2601 }
2602 }
2603 }
2604
2605 Object.seal(value); // This also makes existing properties non-configurable.
2606}
2607
2608var Recoil_deepFreezeValue = deepFreezeValue;
2609
2610/**
2611 * Copyright (c) Facebook, Inc. and its affiliates.
2612 *
2613 * This source code is licensed under the MIT license found in the
2614 * LICENSE file in the root directory of this source tree.
2615 *
2616 * Implements (a subset of) the interface of built-in Map but supports arrays as
2617 * keys. Two keys are equal if corresponding elements are equal according to the
2618 * equality semantics of built-in Map. Operations are at worst O(n*b) where n is
2619 * the array length and b is the complexity of the built-in operation.
2620 *
2621 * @emails oncall+recoil
2622 *
2623 * @format
2624 */
2625
2626const LEAF = Symbol('ArrayKeyedMap');
2627const emptyMap = new Map();
2628
2629class ArrayKeyedMap {
2630 // @fb-only: _base: Map<any, any> = new Map();
2631 constructor(existing) {
2632 // $FlowOSSFixMe
2633 this._base = new Map(); // @oss-only
2634
2635 if (existing instanceof ArrayKeyedMap) {
2636 for (const [k, v] of existing.entries()) {
2637 this.set(k, v);
2638 }
2639 } else if (existing) {
2640 for (const [k, v] of existing) {
2641 this.set(k, v);
2642 }
2643 }
2644
2645 return this;
2646 }
2647
2648 get(key) {
2649 const ks = Array.isArray(key) ? key : [key]; // $FlowOSSFixMe
2650
2651 let map = this._base;
2652 ks.forEach(k => {
2653 var _map$get;
2654
2655 map = (_map$get = map.get(k)) !== null && _map$get !== void 0 ? _map$get : emptyMap;
2656 });
2657 return map === undefined ? undefined : map.get(LEAF);
2658 }
2659
2660 set(key, value) {
2661 const ks = Array.isArray(key) ? key : [key]; // $FlowOSSFixMe
2662
2663 let map = this._base;
2664 let next = map;
2665 ks.forEach(k => {
2666 next = map.get(k);
2667
2668 if (!next) {
2669 next = new Map();
2670 map.set(k, next);
2671 }
2672
2673 map = next;
2674 });
2675 next.set(LEAF, value);
2676 return this;
2677 }
2678
2679 delete(key) {
2680 const ks = Array.isArray(key) ? key : [key]; // $FlowOSSFixMe
2681
2682 let map = this._base;
2683 let next = map;
2684 ks.forEach(k => {
2685 next = map.get(k);
2686
2687 if (!next) {
2688 next = new Map();
2689 map.set(k, next);
2690 }
2691
2692 map = next;
2693 });
2694 next.delete(LEAF); // TODO We could cleanup empty maps
2695
2696 return this;
2697 }
2698
2699 entries() {
2700 const answer = [];
2701
2702 function recurse(level, prefix) {
2703 level.forEach((v, k) => {
2704 if (k === LEAF) {
2705 answer.push([prefix, v]);
2706 } else {
2707 recurse(v, prefix.concat(k));
2708 }
2709 });
2710 } // $FlowOSSFixMe
2711
2712
2713 recurse(this._base, []);
2714 return answer.values();
2715 }
2716
2717 toBuiltInMap() {
2718 return new Map(this.entries());
2719 }
2720
2721}
2722
2723var Recoil_ArrayKeyedMap = ArrayKeyedMap;
2724
2725function cacheWithReferenceEquality() {
2726 return new Recoil_ArrayKeyedMap();
2727}
2728
2729var Recoil_cacheWithReferenceEquality = cacheWithReferenceEquality;
2730
2731/**
2732 * Copyright (c) Facebook, Inc. and its affiliates.
2733 *
2734 * This source code is licensed under the MIT license found in the
2735 * LICENSE file in the root directory of this source tree.
2736 *
2737 * @emails oncall+recoil
2738 *
2739 * @format
2740 *
2741 * This is a stub for some integration into FB internal stuff
2742 */
2743function startPerfBlock(_id) {
2744 return () => null;
2745}
2746
2747var Recoil_PerformanceTimings = {
2748 startPerfBlock
2749};
2750
2751const {
2752 loadableWithError: loadableWithError$1,
2753 loadableWithPromise: loadableWithPromise$1,
2754 loadableWithValue: loadableWithValue$1
2755} = Recoil_Loadable;
2756
2757
2758
2759const {
2760 getNodeLoadable: getNodeLoadable$2,
2761 peekNodeLoadable: peekNodeLoadable$2,
2762 setNodeValue: setNodeValue$3
2763} = Recoil_FunctionalCore;
2764
2765const {
2766 addToDependencyMap: addToDependencyMap$1,
2767 mergeDepsIntoDependencyMap: mergeDepsIntoDependencyMap$1,
2768 saveDependencyMapToStore: saveDependencyMapToStore$3
2769} = Recoil_Graph;
2770
2771const {
2772 DEFAULT_VALUE: DEFAULT_VALUE$3,
2773 RecoilValueNotReady: RecoilValueNotReady$2,
2774 registerNode: registerNode$1
2775} = Recoil_Node;
2776
2777const {
2778 AbstractRecoilValue: AbstractRecoilValue$3
2779} = Recoil_RecoilValue$1;
2780
2781const {
2782 getRecoilValueAsLoadable: getRecoilValueAsLoadable$3,
2783 isRecoilValue: isRecoilValue$3,
2784 setRecoilValueLoadable: setRecoilValueLoadable$2
2785} = Recoil_RecoilValueInterface;
2786
2787
2788
2789
2790
2791
2792
2793const {
2794 startPerfBlock: startPerfBlock$1
2795} = Recoil_PerformanceTimings;
2796
2797// flowlint-next-line unclear-type:off
2798const emptySet$1 = Object.freeze(new Set());
2799
2800function cacheKeyFromDepValues(depValues) {
2801 const answer = [];
2802
2803 for (const key of Array.from(depValues.keys()).sort()) {
2804 const loadable = Recoil_nullthrows(depValues.get(key));
2805 answer.push(key);
2806 answer.push(loadable.state);
2807 answer.push(loadable.contents);
2808 }
2809
2810 return answer;
2811}
2812
2813const dependencyStack = []; // for detecting circular dependencies.
2814
2815const waitingStores = new Map();
2816/* eslint-disable no-redeclare */
2817
2818function selector(options) {
2819 const {
2820 key,
2821 get,
2822 cacheImplementation_UNSTABLE: cacheImplementation
2823 } = options;
2824 const set = options.set != null ? options.set : undefined; // flow
2825
2826 let cache = cacheImplementation !== null && cacheImplementation !== void 0 ? cacheImplementation : Recoil_cacheWithReferenceEquality();
2827
2828 function initSelector(store) {
2829 store.getState().knownSelectors.add(key);
2830 }
2831
2832 function letStoreBeNotifiedWhenAsyncSettles(store, loadable) {
2833 if (loadable.state === 'loading') {
2834 let stores = waitingStores.get(loadable);
2835
2836 if (stores === undefined) {
2837 waitingStores.set(loadable, stores = new Set());
2838 }
2839
2840 stores.add(store);
2841 }
2842 }
2843
2844 function notifyStoresOfSettledAsync(originalLoadable, newLoadable) {
2845 const stores = waitingStores.get(originalLoadable);
2846
2847 if (stores !== undefined) {
2848 for (const store of stores) {
2849 setRecoilValueLoadable$2(store, new AbstractRecoilValue$3(key), newLoadable);
2850 }
2851
2852 waitingStores.delete(originalLoadable);
2853 }
2854 }
2855
2856 function putIntoCache(cacheKey, loadable) {
2857 if (loadable.state !== 'loading') {
2858 // Synchronous result
2859 if (process.env.NODE_ENV !== "production") {
2860 if (!options.dangerouslyAllowMutability === true) {
2861 Recoil_deepFreezeValue(loadable.contents);
2862 }
2863 }
2864 } else {
2865 // Asynchronous result
2866 // When the promise resolves, we need to replace the loading state in the
2867 // cache and fire any external subscriptions to re-render with the new value.
2868 loadable.contents.then(result => {
2869 if (process.env.NODE_ENV !== "production") {
2870 if (!options.dangerouslyAllowMutability === true) {
2871 Recoil_deepFreezeValue(result);
2872 }
2873 }
2874
2875 const newLoadable = loadableWithValue$1(result); // If the value is now resolved, then update the cache with the new value
2876
2877 cache = cache.set(cacheKey, newLoadable); // TODO Potential optimization: I think this is updating the cache
2878 // with a cacheKey of the dep when it wasn't ready yet. We could also
2879 // theoretically put the result in the cache for a cacheKey with the
2880 // dep resolved. If we had some way of figuring out what that cacheKey was..
2881 // Note that this optimization would change the user visible behavior slightly,
2882 // see the unit test "useRecoilState - selector catching promise 2".
2883 // If the user catches and handles pending async dependencies, then returns
2884 // a promise that resolves when they are available there is a question if
2885 // the result of that promise should be the value of the selector, or if
2886 // the selector should re-evaluate when the dependency is available.
2887 // If the promise returned and the pending dependency resolve at different
2888 // times, then the behaviour is better defined, as in the unit test,
2889 // "useRecoilState - selector catching promise and resolving asynchronously"
2890 // Fire subscriptions to re-render any subscribed components with the new value.
2891 // The store uses the CURRENT state, not the old state from which
2892 // this was called. That state likely doesn't have the subscriptions saved yet.
2893 // Note that we have to set the value for this key, not just notify
2894 // components, so that there will be a new version for useMutableSource.
2895
2896 notifyStoresOfSettledAsync(loadable, newLoadable);
2897 return result;
2898 }).catch(error => {
2899 // TODO Figure out why we are catching promises here versus evaluateSelectorFunction
2900 // OH, I see why. Ok, work on this.
2901 if (Recoil_isPromise(error)) {
2902 return error;
2903 }
2904
2905 if (process.env.NODE_ENV !== "production") {
2906 if (!options.dangerouslyAllowMutability === true) {
2907 Recoil_deepFreezeValue(error);
2908 }
2909 } // The async value was rejected with an error. Update the cache with
2910 // the error and fire subscriptions to re-render.
2911
2912
2913 const newLoadable = loadableWithError$1(error);
2914 cache = cache.set(cacheKey, newLoadable);
2915 notifyStoresOfSettledAsync(loadable, newLoadable);
2916 return error;
2917 });
2918 }
2919
2920 cache = cache.set(cacheKey, loadable);
2921 }
2922
2923 function getFromCacheOrEvaluate(store, state) {
2924 var _store$getGraph$nodeD;
2925
2926 const dependencyMap = new Map(); // First, get the current deps for this selector
2927
2928 const currentDeps = (_store$getGraph$nodeD = store.getGraph(state.version).nodeDeps.get(key)) !== null && _store$getGraph$nodeD !== void 0 ? _store$getGraph$nodeD : emptySet$1;
2929 const depValues = new Map(Array.from(currentDeps).sort().map(depKey => {
2930 const [deps, loadable] = getNodeLoadable$2(store, state, depKey);
2931 mergeDepsIntoDependencyMap$1(deps, dependencyMap);
2932 saveDependencyMapToStore$3(dependencyMap, store, state.version);
2933 return [depKey, loadable];
2934 })); // Always cache and evaluate a selector
2935 // It may provide a result even when not all deps are available.
2936
2937 const cacheKey = cacheKeyFromDepValues(depValues);
2938 const cached = cache.get(cacheKey);
2939
2940 if (cached != null) {
2941 letStoreBeNotifiedWhenAsyncSettles(store, cached);
2942 return [dependencyMap, cached];
2943 } // Cache miss, compute the value
2944
2945
2946 const [deps, loadable, newDepValues] = evaluateSelectorFunction(store, state);
2947 mergeDepsIntoDependencyMap$1(deps, dependencyMap);
2948 saveDependencyMapToStore$3(dependencyMap, store, state.version); // Save result in cache
2949
2950 const newCacheKey = cacheKeyFromDepValues(newDepValues);
2951 letStoreBeNotifiedWhenAsyncSettles(store, loadable);
2952 putIntoCache(newCacheKey, loadable);
2953 return [dependencyMap, loadable];
2954 }
2955
2956 function evaluateSelectorFunction(store, state) {
2957 const endPerfBlock = startPerfBlock$1(key);
2958 const depValues = new Map(); // key -> value for our deps
2959
2960 const dependencyMap = new Map(); // node -> nodes, part of overall dep map.
2961
2962 function getRecoilValue({
2963 key: depKey
2964 }) {
2965 addToDependencyMap$1(key, depKey, dependencyMap);
2966 const [deps, loadable] = getNodeLoadable$2(store, state, depKey);
2967 depValues.set(depKey, loadable);
2968 mergeDepsIntoDependencyMap$1(deps, dependencyMap);
2969 saveDependencyMapToStore$3(dependencyMap, store, state.version);
2970
2971 if (loadable.state === 'hasValue') {
2972 return loadable.contents;
2973 } else {
2974 throw loadable.contents; // Promise or error
2975 }
2976 }
2977
2978 try {
2979 // The big moment!
2980 const output = get({
2981 get: getRecoilValue
2982 }); // TODO Allow user to also return Loadables for improved composability
2983
2984 const result = isRecoilValue$3(output) ? getRecoilValue(output) : output;
2985 let loadable;
2986
2987 if (!Recoil_isPromise(result)) {
2988 // The selector returned a simple synchronous value, so let's use it!
2989 endPerfBlock();
2990 loadable = loadableWithValue$1(result);
2991 } else {
2992 // The user returned a promise for an asynchronous selector. This will
2993 // resolve to the proper value of the selector when available.
2994 loadable = loadableWithPromise$1(result.finally(endPerfBlock));
2995 }
2996
2997 return [dependencyMap, loadable, depValues];
2998 } catch (errorOrDepPromise) {
2999 // XXX why was this changed to not use isPromise?
3000 const isP = errorOrDepPromise.then !== undefined;
3001 let loadable;
3002
3003 if (!isP) {
3004 // There was a synchronous error in the evaluation
3005 endPerfBlock();
3006 loadable = loadableWithError$1(errorOrDepPromise);
3007 } else {
3008 // If an asynchronous dependency was not ready, then return a promise that
3009 // will resolve when we finally do have a real value or error for the selector.
3010 loadable = loadableWithPromise$1(errorOrDepPromise.then(() => {
3011 // Now that its deps are ready, re-evaluate the selector (and
3012 // record any newly-discovered dependencies in the Store):
3013 const loadable = getRecoilValueAsLoadable$3(store, new AbstractRecoilValue$3(key));
3014
3015 if (loadable.state === 'hasError') {
3016 throw loadable.contents;
3017 } // Either the re-try provided a value, which we will use, or it
3018 // got blocked again. In that case this is a promise and we'll try again.
3019
3020
3021 return loadable.contents;
3022 }).finally(endPerfBlock));
3023 }
3024
3025 return [dependencyMap, loadable, depValues];
3026 }
3027 }
3028
3029 function detectCircularDependencies(fn) {
3030 if (dependencyStack.includes(key)) {
3031 const message = `Recoil selector has circular dependencies: ${dependencyStack.slice(dependencyStack.indexOf(key)).join(' \u2192 ')}`;
3032 return [new Map(), loadableWithError$1(new Error(message))];
3033 }
3034
3035 dependencyStack.push(key);
3036
3037 try {
3038 return fn();
3039 } finally {
3040 dependencyStack.pop();
3041 }
3042 }
3043
3044 function myPeek(store, state) {
3045 var _store$getGraph$nodeD2;
3046
3047 // First, get the current deps for this selector
3048 const currentDeps = (_store$getGraph$nodeD2 = store.getGraph(state.version).nodeDeps.get(key)) !== null && _store$getGraph$nodeD2 !== void 0 ? _store$getGraph$nodeD2 : emptySet$1;
3049 const depValues = new Map(Array.from(currentDeps).sort().map(depKey => [depKey, peekNodeLoadable$2(store, state, depKey)]));
3050 const cacheDepValues = new Map();
3051
3052 for (const [depKey, depValue] of depValues.entries()) {
3053 if (depValue == null) {
3054 return undefined;
3055 }
3056
3057 cacheDepValues.set(depKey, depValue);
3058 } // Always cache and evaluate a selector
3059 // It may provide a result even when not all deps are available.
3060
3061
3062 const cacheKey = cacheKeyFromDepValues(cacheDepValues);
3063 return cache.get(cacheKey);
3064 }
3065
3066 function myGet(store, state) {
3067 initSelector(store); // TODO memoize a value if no deps have changed to avoid a cache lookup
3068 // Lookup the node value in the cache. If not there, then compute
3069 // the value and update the state with any changed node subscriptions.
3070
3071 if (process.env.NODE_ENV !== "production") {
3072 return detectCircularDependencies(() => getFromCacheOrEvaluate(store, state));
3073 } else {
3074 return getFromCacheOrEvaluate(store, state);
3075 }
3076 }
3077
3078 if (set != null) {
3079 function mySet(store, state, newValue) {
3080 initSelector(store);
3081 const dependencyMap = new Map();
3082 const writes = new Map();
3083
3084 function getRecoilValue({
3085 key
3086 }) {
3087 const [deps, loadable] = getNodeLoadable$2(store, state, key);
3088 mergeDepsIntoDependencyMap$1(deps, dependencyMap);
3089
3090 if (loadable.state === 'hasValue') {
3091 return loadable.contents;
3092 } else if (loadable.state === 'loading') {
3093 throw new RecoilValueNotReady$2(key);
3094 } else {
3095 throw loadable.contents;
3096 }
3097 }
3098
3099 function setRecoilState(recoilState, valueOrUpdater) {
3100 const newValue = typeof valueOrUpdater === 'function' ? // cast to any because we can't restrict type S from being a function itself without losing support for opaque types
3101 // flowlint-next-line unclear-type:off
3102 valueOrUpdater(getRecoilValue(recoilState)) : valueOrUpdater;
3103 const [deps, upstreamWrites] = setNodeValue$3(store, state, recoilState.key, newValue);
3104 mergeDepsIntoDependencyMap$1(deps, dependencyMap);
3105 upstreamWrites.forEach((v, k) => writes.set(k, v));
3106 }
3107
3108 function resetRecoilState(recoilState) {
3109 setRecoilState(recoilState, DEFAULT_VALUE$3);
3110 }
3111
3112 set({
3113 set: setRecoilState,
3114 get: getRecoilValue,
3115 reset: resetRecoilState
3116 }, newValue);
3117 return [dependencyMap, writes];
3118 }
3119
3120 return registerNode$1({
3121 key,
3122 peek: myPeek,
3123 get: myGet,
3124 set: mySet,
3125 dangerouslyAllowMutability: options.dangerouslyAllowMutability,
3126 shouldRestoreFromSnapshots: false
3127 });
3128 } else {
3129 return registerNode$1({
3130 key,
3131 peek: myPeek,
3132 get: myGet,
3133 dangerouslyAllowMutability: options.dangerouslyAllowMutability,
3134 shouldRestoreFromSnapshots: false
3135 });
3136 }
3137}
3138/* eslint-enable no-redeclare */
3139
3140
3141var Recoil_selector_OLD = selector;
3142
3143// const newSelector = require('./Recoil_selector_NEW');
3144
3145
3146
3147// type Selector = typeof newSelector;
3148// const selector: Selector = gkx('recoil_async_selector_refactor')
3149// ? newSelector
3150// : oldSelector;
3151var Recoil_selector = Recoil_selector_OLD;
3152
3153// @fb-only: const {scopedAtom} = require('Recoil_ScopedAtom');
3154const {
3155 loadableWithError: loadableWithError$2,
3156 loadableWithPromise: loadableWithPromise$2,
3157 loadableWithValue: loadableWithValue$2
3158} = Recoil_Loadable;
3159
3160const {
3161 DEFAULT_VALUE: DEFAULT_VALUE$4,
3162 DefaultValue: DefaultValue$2,
3163 registerNode: registerNode$2
3164} = Recoil_Node;
3165
3166const {
3167 isRecoilValue: isRecoilValue$4
3168} = Recoil_RecoilValue$1;
3169
3170const {
3171 markRecoilValueModified: markRecoilValueModified$1,
3172 setRecoilValue: setRecoilValue$3,
3173 setRecoilValueLoadable: setRecoilValueLoadable$3
3174} = Recoil_RecoilValueInterface;
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188function baseAtom(options) {
3189 const {
3190 key,
3191 persistence_UNSTABLE: persistence
3192 } = options;
3193 let defaultLoadable = Recoil_isPromise(options.default) ? loadableWithPromise$2(options.default.then(value => {
3194 defaultLoadable = loadableWithValue$2(value); // TODO Temporary disable Flow due to pending selector_NEW refactor
3195
3196 return value;
3197 }).catch(error => {
3198 defaultLoadable = loadableWithError$2(error);
3199 throw error;
3200 })) : loadableWithValue$2(options.default);
3201 let cachedAnswerForUnvalidatedValue = undefined;
3202
3203 function wrapPendingPromise(store, promise) {
3204 const wrappedPromise = promise.then(value => {
3205 var _store$getState$nextT, _state$atomValues$get;
3206
3207 const state = (_store$getState$nextT = store.getState().nextTree) !== null && _store$getState$nextT !== void 0 ? _store$getState$nextT : store.getState().currentTree;
3208
3209 if (((_state$atomValues$get = state.atomValues.get(key)) === null || _state$atomValues$get === void 0 ? void 0 : _state$atomValues$get.contents) === wrappedPromise) {
3210 setRecoilValue$3(store, node, value);
3211 }
3212
3213 return value;
3214 }).catch(error => {
3215 var _store$getState$nextT2, _state$atomValues$get2;
3216
3217 const state = (_store$getState$nextT2 = store.getState().nextTree) !== null && _store$getState$nextT2 !== void 0 ? _store$getState$nextT2 : store.getState().currentTree;
3218
3219 if (((_state$atomValues$get2 = state.atomValues.get(key)) === null || _state$atomValues$get2 === void 0 ? void 0 : _state$atomValues$get2.contents) === wrappedPromise) {
3220 setRecoilValueLoadable$3(store, node, loadableWithError$2(error));
3221 }
3222
3223 throw error;
3224 });
3225 return wrappedPromise;
3226 }
3227
3228 function initAtom(store, initState, trigger) {
3229 if (store.getState().knownAtoms.has(key)) {
3230 return;
3231 }
3232
3233 store.getState().knownAtoms.add(key); // Setup async defaults to notify subscribers when they resolve
3234
3235 if (defaultLoadable.state === 'loading') {
3236 function notifyDefaultSubscribers() {
3237 var _store$getState$nextT3;
3238
3239 const state = (_store$getState$nextT3 = store.getState().nextTree) !== null && _store$getState$nextT3 !== void 0 ? _store$getState$nextT3 : store.getState().currentTree;
3240
3241 if (!state.atomValues.has(key)) {
3242 markRecoilValueModified$1(store, node);
3243 }
3244 }
3245
3246 defaultLoadable.contents.then(notifyDefaultSubscribers).catch(notifyDefaultSubscribers);
3247 } // Run Atom Effects
3248
3249
3250 let initValue = DEFAULT_VALUE$4;
3251
3252 if (options.effects_UNSTABLE != null) {
3253 let duringInit = true;
3254
3255 function setSelf(valueOrUpdater) {
3256 if (duringInit) {
3257 const currentValue = initValue instanceof DefaultValue$2 || Recoil_isPromise(initValue) ? defaultLoadable.state === 'hasValue' ? defaultLoadable.contents : DEFAULT_VALUE$4 : initValue;
3258 initValue = typeof valueOrUpdater === 'function' ? // cast to any because we can't restrict type from being a function itself without losing support for opaque types
3259 // flowlint-next-line unclear-type:off
3260 valueOrUpdater(currentValue) : valueOrUpdater;
3261 } else {
3262 if (Recoil_isPromise(valueOrUpdater)) {
3263 throw new Error('Setting atoms to async values is not implemented.');
3264 }
3265
3266 setRecoilValue$3(store, node, valueOrUpdater);
3267 }
3268 }
3269
3270 const resetSelf = () => setSelf(DEFAULT_VALUE$4);
3271
3272 function onSet(handler) {
3273 store.subscribeToTransactions(currentStore => {
3274 let {
3275 currentTree,
3276 previousTree
3277 } = currentStore.getState();
3278
3279 if (!previousTree) {
3280 Recoil_recoverableViolation('Transaction subscribers notified without a next tree being present -- this is a bug in Recoil');
3281 previousTree = currentTree; // attempt to trundle on
3282 }
3283
3284 const newLoadable = currentTree.atomValues.get(key);
3285
3286 if (newLoadable == null || newLoadable.state === 'hasValue') {
3287 var _previousTree$atomVal;
3288
3289 const newValue = newLoadable != null ? newLoadable.contents : DEFAULT_VALUE$4;
3290 const oldLoadable = (_previousTree$atomVal = previousTree.atomValues.get(key)) !== null && _previousTree$atomVal !== void 0 ? _previousTree$atomVal : defaultLoadable;
3291 const oldValue = oldLoadable.state === 'hasValue' ? oldLoadable.contents : DEFAULT_VALUE$4; // TODO This isn't actually valid, use as a placeholder for now.
3292
3293 handler(newValue, oldValue);
3294 }
3295 }, key);
3296 }
3297
3298 for (const effect of (_options$effects_UNST = options.effects_UNSTABLE) !== null && _options$effects_UNST !== void 0 ? _options$effects_UNST : []) {
3299 var _options$effects_UNST;
3300
3301 effect({
3302 node,
3303 trigger,
3304 setSelf,
3305 resetSelf,
3306 onSet
3307 });
3308 }
3309
3310 duringInit = false;
3311 } // Mutate initial state in place since we know there are no other subscribers
3312 // since we are the ones initializing on first use.
3313
3314
3315 if (!(initValue instanceof DefaultValue$2)) {
3316 initState.atomValues.set(key, Recoil_isPromise(initValue) ? // TODO Temp disable Flow due to pending selector_NEW refactor using LoadablePromise
3317 loadableWithPromise$2(wrapPendingPromise(store, initValue)) : loadableWithValue$2(initValue));
3318 }
3319 }
3320
3321 function myPeek(_store, state) {
3322 var _ref, _state$atomValues$get3, _cachedAnswerForUnval;
3323
3324 return (_ref = (_state$atomValues$get3 = state.atomValues.get(key)) !== null && _state$atomValues$get3 !== void 0 ? _state$atomValues$get3 : (_cachedAnswerForUnval = cachedAnswerForUnvalidatedValue) === null || _cachedAnswerForUnval === void 0 ? void 0 : _cachedAnswerForUnval[1]) !== null && _ref !== void 0 ? _ref : defaultLoadable;
3325 }
3326
3327 function myGet(store, state) {
3328 initAtom(store, state, 'get');
3329
3330 if (state.atomValues.has(key)) {
3331 // Atom value is stored in state:
3332 return [new Map(), Recoil_nullthrows(state.atomValues.get(key))];
3333 } else if (state.nonvalidatedAtoms.has(key)) {
3334 // Atom value is stored but needs validation before use.
3335 // We might have already validated it and have a cached validated value:
3336 if (cachedAnswerForUnvalidatedValue != null) {
3337 return cachedAnswerForUnvalidatedValue;
3338 }
3339
3340 if (persistence == null) {
3341 Recoil_expectationViolation(`Tried to restore a persisted value for atom ${key} but it has no persistence settings.`);
3342 return [new Map(), defaultLoadable];
3343 }
3344
3345 const nonvalidatedValue = state.nonvalidatedAtoms.get(key);
3346 const validatorResult = persistence.validator(nonvalidatedValue, DEFAULT_VALUE$4);
3347 const validatedValueLoadable = validatorResult instanceof DefaultValue$2 ? defaultLoadable : loadableWithValue$2(validatorResult);
3348 cachedAnswerForUnvalidatedValue = [new Map(), validatedValueLoadable];
3349 return cachedAnswerForUnvalidatedValue;
3350 } else {
3351 return [new Map(), defaultLoadable];
3352 }
3353 }
3354
3355 function invalidate() {
3356 cachedAnswerForUnvalidatedValue = undefined;
3357 }
3358
3359 function mySet(store, state, newValue) {
3360 initAtom(store, state, 'set'); // Bail out if we're being set to the existing value, or if we're being
3361 // reset but have no stored value (validated or unvalidated) to reset from:
3362
3363 if (state.atomValues.has(key)) {
3364 const existing = Recoil_nullthrows(state.atomValues.get(key));
3365
3366 if (existing.state === 'hasValue' && newValue === existing.contents) {
3367 return [new Map(), new Map()];
3368 }
3369 } else if (!state.nonvalidatedAtoms.has(key) && newValue instanceof DefaultValue$2) {
3370 return [new Map(), new Map()];
3371 }
3372
3373 if (process.env.NODE_ENV !== "production") {
3374 if (options.dangerouslyAllowMutability !== true) {
3375 Recoil_deepFreezeValue(newValue);
3376 }
3377 }
3378
3379 cachedAnswerForUnvalidatedValue = undefined; // can be released now if it was previously in use
3380
3381 return [new Map(), new Map().set(key, loadableWithValue$2(newValue))];
3382 }
3383
3384 const node = registerNode$2({
3385 key,
3386 peek: myPeek,
3387 get: myGet,
3388 set: mySet,
3389 invalidate,
3390 dangerouslyAllowMutability: options.dangerouslyAllowMutability,
3391 persistence_UNSTABLE: options.persistence_UNSTABLE ? {
3392 type: options.persistence_UNSTABLE.type,
3393 backButton: options.persistence_UNSTABLE.backButton
3394 } : undefined,
3395 shouldRestoreFromSnapshots: true
3396 });
3397 return node;
3398} // prettier-ignore
3399
3400
3401function atom(options) {
3402 const {
3403 default: optionsDefault,
3404 // @fb-only: scopeRules_APPEND_ONLY_READ_THE_DOCS,
3405 ...restOptions
3406 } = options;
3407
3408 if (isRecoilValue$4(optionsDefault) // Continue to use atomWithFallback for promise defaults for scoped atoms
3409 // for now, since scoped atoms don't support async defaults
3410 // @fb-only: || (isPromise(optionsDefault) && scopeRules_APPEND_ONLY_READ_THE_DOCS)
3411 ) {
3412 return atomWithFallback({ ...restOptions,
3413 default: optionsDefault // @fb-only: scopeRules_APPEND_ONLY_READ_THE_DOCS,
3414
3415 }); // @fb-only: } else if (scopeRules_APPEND_ONLY_READ_THE_DOCS && !isPromise(optionsDefault)) {
3416 // @fb-only: return scopedAtom<T>({
3417 // @fb-only: ...restOptions,
3418 // @fb-only: default: optionsDefault,
3419 // @fb-only: scopeRules_APPEND_ONLY_READ_THE_DOCS,
3420 // @fb-only: });
3421 } else {
3422 return baseAtom({ ...restOptions,
3423 default: optionsDefault
3424 });
3425 }
3426}
3427
3428function atomWithFallback(options) {
3429 const base = atom({ ...options,
3430 default: DEFAULT_VALUE$4,
3431 persistence_UNSTABLE: options.persistence_UNSTABLE === undefined ? undefined : { ...options.persistence_UNSTABLE,
3432 validator: storedValue => storedValue instanceof DefaultValue$2 ? storedValue : Recoil_nullthrows(options.persistence_UNSTABLE).validator(storedValue, DEFAULT_VALUE$4)
3433 },
3434 // TODO Hack for now.
3435 // flowlint-next-line unclear-type: off
3436 effects_UNSTABLE: options.effects_UNSTABLE
3437 });
3438 return Recoil_selector({
3439 key: `${options.key}__withFallback`,
3440 get: ({
3441 get
3442 }) => {
3443 const baseValue = get(base);
3444 return baseValue instanceof DefaultValue$2 ? options.default : baseValue;
3445 },
3446 set: ({
3447 set
3448 }, newValue) => set(base, newValue),
3449 dangerouslyAllowMutability: options.dangerouslyAllowMutability
3450 });
3451}
3452
3453var Recoil_atom = atom;
3454
3455const TIME_WARNING_THRESHOLD_MS = 15;
3456
3457function stringify(x, opt, key) {
3458 // A optimization to avoid the more expensive JSON.stringify() for simple strings
3459 // This may lose protection for u2028 and u2029, though.
3460 if (typeof x === 'string' && !x.includes('"') && !x.includes('\\')) {
3461 return `"${x}"`;
3462 } // Handle primitive types
3463
3464
3465 switch (typeof x) {
3466 case 'undefined':
3467 return '';
3468 // JSON.stringify(undefined) returns undefined, but we always want to return a string
3469
3470 case 'boolean':
3471 return x ? 'true' : 'false';
3472
3473 case 'number':
3474 case 'symbol':
3475 // case 'bigint': // BigInt is not supported in www
3476 return String(x);
3477
3478 case 'string':
3479 // Add surrounding quotes and escape internal quotes
3480 return JSON.stringify(x);
3481
3482 case 'function':
3483 if ((opt === null || opt === void 0 ? void 0 : opt.allowFunctions) !== true) {
3484 throw new Error('Attempt to serialize function in a Recoil cache key');
3485 }
3486
3487 return `__FUNCTION(${x.name})__`;
3488 }
3489
3490 if (x === null) {
3491 return 'null';
3492 } // Fallback case for unknown types
3493
3494
3495 if (typeof x !== 'object') {
3496 var _JSON$stringify;
3497
3498 return (_JSON$stringify = JSON.stringify(x)) !== null && _JSON$stringify !== void 0 ? _JSON$stringify : '';
3499 } // Deal with all promises as equivalent for now.
3500
3501
3502 if (Recoil_isPromise(x)) {
3503 return '__PROMISE__';
3504 } // Arrays handle recursive stringification
3505
3506
3507 if (Array.isArray(x)) {
3508 return `[${x.map((v, i) => stringify(v, opt, i.toString()))}]`;
3509 } // If an object defines a toJSON() method, then use that to override the
3510 // serialization. This matches the behavior of JSON.stringify().
3511 // Pass the key for compatibility.
3512 // Immutable.js collections define this method to allow us to serialize them.
3513
3514
3515 if (typeof x.toJSON === 'function') {
3516 // flowlint-next-line unclear-type: off
3517 return stringify(x.toJSON(key), opt, key);
3518 } // For built-in Maps, sort the keys in a stable order instead of the
3519 // default insertion order. Support non-string keys.
3520
3521
3522 if (x instanceof Map) {
3523 const obj = {};
3524
3525 for (const [k, v] of x) {
3526 // Stringify will escape any nested quotes
3527 obj[typeof k === 'string' ? k : stringify(k, opt)] = v;
3528 }
3529
3530 return stringify(obj, opt, key);
3531 } // For built-in Sets, sort the keys in a stable order instead of the
3532 // default insertion order.
3533
3534
3535 if (x instanceof Set) {
3536 return stringify(Array.from(x).sort((a, b) => stringify(a, opt).localeCompare(stringify(b, opt))), opt, key);
3537 } // Anything else that is iterable serialize as an Array.
3538
3539
3540 if (x[Symbol.iterator] != null && typeof x[Symbol.iterator] === 'function') {
3541 // flowlint-next-line unclear-type: off
3542 return stringify(Array.from(x), opt, key);
3543 } // For all other Objects, sort the keys in a stable order.
3544
3545
3546 return `{${Object.keys(x).filter(key => x[key] !== undefined).sort() // stringify the key to add quotes and escape any nested slashes or quotes.
3547 .map(key => `${stringify(key, opt)}:${stringify(x[key], opt, key)}`).join(',')}}`;
3548} // Utility similar to JSON.stringify() except:
3549// * Serialize built-in Sets as an Array
3550// * Serialize built-in Maps as an Object. Supports non-string keys.
3551// * Serialize other iterables as arrays
3552// * Sort the keys of Objects and Maps to have a stable order based on string conversion.
3553// This overrides their default insertion order.
3554// * Still uses toJSON() of any object to override serialization
3555// * Support Symbols (though don't guarantee uniqueness)
3556// * We could support BigInt, but Flow doesn't seem to like it.
3557// See Recoil_stableStringify-test.js for examples
3558
3559
3560function stableStringify(x, opt = {
3561 allowFunctions: false
3562}) {
3563 if (process.env.NODE_ENV !== "production") {
3564 if (typeof window !== 'undefined') {
3565 const startTime = window.performance ? window.performance.now() : 0;
3566 const str = stringify(x, opt);
3567 const endTime = window.performance ? window.performance.now() : 0;
3568
3569 if (endTime - startTime > TIME_WARNING_THRESHOLD_MS) {
3570 /* eslint-disable fb-www/no-console */
3571 console.groupCollapsed(`Recoil: Spent ${endTime - startTime}ms computing a cache key`);
3572 console.warn(x, str);
3573 console.groupEnd();
3574 /* eslint-enable fb-www/no-console */
3575 }
3576
3577 return str;
3578 }
3579 }
3580
3581 return stringify(x, opt);
3582}
3583
3584var Recoil_stableStringify = stableStringify;
3585
3586// If we do profile and find the key equality check is expensive,
3587// we could always try to optimize.. Something that comes to mind is having
3588// each check assign an incrementing index to each reference that maps to the
3589// value equivalency. Then, if an object already has an index, the comparison
3590// check/lookup would be trivial and the string serialization would only need
3591// to be done once per object instance. Just a thought..
3592// Cache implementation to use value equality for keys instead of the default
3593// reference equality. This allows different instances of dependency values to
3594// be used. Normally this is not needed, as dependent atoms/selectors will
3595// themselves be cached and always return the same instance. However, if
3596// different params or upstream values for those dependencies could produce
3597// equivalent values or they have a custom cache implementation, then this
3598// implementation may be needed. The downside with this approach is that it
3599// takes longer to compute the value equivalence vs simple reference equality.
3600
3601
3602function cacheWithValueEquality() {
3603 const map = new Map();
3604 const cache = {
3605 get: key => map.get(Recoil_stableStringify(key)),
3606 set: (key, value) => {
3607 map.set(Recoil_stableStringify(key), value);
3608 return cache;
3609 },
3610 map // For debugging
3611
3612 };
3613 return cache;
3614}
3615
3616var Recoil_cacheWithValueEquality = cacheWithValueEquality;
3617
3618// Keep in mind the parameter needs to be serializable as a cahche key
3619// using Recoil_stableStringify
3620
3621
3622// Add a unique index to each selector in case the cache implementation allows
3623// duplicate keys based on equivalent stringified parameters
3624let nextIndex = 0;
3625/* eslint-disable no-redeclare */
3626
3627// Return a function that returns members of a family of selectors of the same type
3628// E.g.,
3629//
3630// const s = selectorFamily(...);
3631// s({a: 1}) => a selector
3632// s({a: 2}) => a different selector
3633//
3634// By default, the selectors are distinguished by distinct values of the
3635// parameter based on value equality, not reference equality. This allows using
3636// object literals or other equivalent objects at callsites to not create
3637// duplicate cache entries. This behavior may be overridden with the
3638// cacheImplementationForParams option.
3639function selectorFamily(options) {
3640 var _options$cacheImpleme, _options$cacheImpleme2;
3641
3642 let selectorCache = (_options$cacheImpleme = (_options$cacheImpleme2 = options.cacheImplementationForParams_UNSTABLE) === null || _options$cacheImpleme2 === void 0 ? void 0 : _options$cacheImpleme2.call(options)) !== null && _options$cacheImpleme !== void 0 ? _options$cacheImpleme : Recoil_cacheWithValueEquality();
3643 return params => {
3644 var _stableStringify, _options$cacheImpleme3;
3645
3646 const cachedSelector = selectorCache.get(params);
3647
3648 if (cachedSelector != null) {
3649 return cachedSelector;
3650 }
3651
3652 const myKey = `${options.key}__selectorFamily/${(_stableStringify = Recoil_stableStringify(params, {
3653 // It is possible to use functions in parameters if the user uses
3654 // a cache with reference equality thanks to the incrementing index.
3655 allowFunctions: true
3656 })) !== null && _stableStringify !== void 0 ? _stableStringify : 'void'}/${nextIndex++}`; // Append index in case values serialize to the same key string
3657
3658 const myGet = callbacks => options.get(params)(callbacks);
3659
3660 const myCacheImplementation = (_options$cacheImpleme3 = options.cacheImplementation_UNSTABLE) === null || _options$cacheImpleme3 === void 0 ? void 0 : _options$cacheImpleme3.call(options);
3661 let newSelector;
3662
3663 if (options.set != null) {
3664 const set = options.set;
3665
3666 const mySet = (callbacks, newValue) => set(params)(callbacks, newValue);
3667
3668 newSelector = Recoil_selector({
3669 key: myKey,
3670 get: myGet,
3671 set: mySet,
3672 cacheImplementation_UNSTABLE: myCacheImplementation,
3673 dangerouslyAllowMutability: options.dangerouslyAllowMutability
3674 });
3675 } else {
3676 newSelector = Recoil_selector({
3677 key: myKey,
3678 get: myGet,
3679 cacheImplementation_UNSTABLE: myCacheImplementation,
3680 dangerouslyAllowMutability: options.dangerouslyAllowMutability
3681 });
3682 }
3683
3684 selectorCache = selectorCache.set(params, newSelector);
3685 return newSelector;
3686 };
3687}
3688/* eslint-enable no-redeclare */
3689
3690
3691var Recoil_selectorFamily = selectorFamily;
3692
3693// @fb-only: const {parameterizedScopedAtomLegacy} = require('Recoil_ScopedAtom');
3694
3695
3696const {
3697 DEFAULT_VALUE: DEFAULT_VALUE$5,
3698 DefaultValue: DefaultValue$3
3699} = Recoil_Node;
3700/*
3701A function which returns an atom based on the input parameter.
3702
3703Each unique parameter returns a unique atom. E.g.,
3704
3705 const f = atomFamily(...);
3706 f({a: 1}) => an atom
3707 f({a: 2}) => a different atom
3708
3709This allows components to persist local, private state using atoms. Each
3710instance of the component may have a different key, which it uses as the
3711parameter for a family of atoms; in this way, each component will have
3712its own atom not shared by other instances. These state keys may be composed
3713into children's state keys as well.
3714*/
3715
3716
3717function atomFamily(options) {
3718 let atomCache = Recoil_cacheWithValueEquality(); // An atom to represent any legacy atoms that we can upgrade to an atomFamily
3719
3720 const legacyAtomOptions = {
3721 key: options.key,
3722 // Legacy atoms just used the plain key directly
3723 default: DEFAULT_VALUE$5,
3724 persistence_UNSTABLE: options.persistence_UNSTABLE
3725 };
3726 let legacyAtom; // prettier-ignore
3727 // @fb-only: if (
3728 // @fb-only: options.scopeRules_APPEND_ONLY_READ_THE_DOCS
3729 // @fb-only: ) {
3730 // @fb-only: legacyAtom = parameterizedScopedAtomLegacy<T | DefaultValue, P>({
3731 // @fb-only: ...legacyAtomOptions,
3732 // @fb-only: scopeRules_APPEND_ONLY_READ_THE_DOCS:
3733 // @fb-only: options.scopeRules_APPEND_ONLY_READ_THE_DOCS,
3734 // @fb-only: });
3735 // @fb-only: } else {
3736
3737 legacyAtom = Recoil_atom(legacyAtomOptions); // @fb-only: }
3738 // Selector to calculate the default value based on any persisted legacy atoms
3739 // that were upgraded to a atomFamily
3740
3741 const atomFamilyDefault = Recoil_selectorFamily({
3742 key: `${options.key}__atomFamily/Default`,
3743 get: param => ({
3744 get
3745 }) => {
3746 const legacyValue = get(typeof legacyAtom === 'function' ? legacyAtom(param) : legacyAtom); // Atom was upgraded from a non-parameterized atom
3747
3748 if (!(legacyValue instanceof DefaultValue$3)) {
3749 return legacyValue;
3750 } // There's no legacy atom value, so use the user-specified default
3751
3752
3753 return typeof options.default === 'function' ? // The default was parameterized
3754 // Flow doesn't know that T isn't a function, so we need to case to any
3755 options.default(param) // flowlint-line unclear-type:off
3756 : // Default may be a static value, promise, or RecoilValue
3757 options.default;
3758 },
3759 dangerouslyAllowMutability: options.dangerouslyAllowMutability
3760 }); // Simple atomFamily implementation to cache individual atoms based
3761 // on the parameter value equality.
3762
3763 return params => {
3764 var _stableStringify;
3765
3766 const cachedAtom = atomCache.get(params);
3767
3768 if (cachedAtom != null) {
3769 return cachedAtom;
3770 }
3771
3772 const newAtom = Recoil_atom({ ...options,
3773 key: `${options.key}__${(_stableStringify = Recoil_stableStringify(params)) !== null && _stableStringify !== void 0 ? _stableStringify : 'void'}`,
3774 default: atomFamilyDefault(params),
3775 effects_UNSTABLE: typeof options.effects_UNSTABLE === 'function' ? options.effects_UNSTABLE(params) : options.effects_UNSTABLE // prettier-ignore
3776 // @fb-only: scopeRules_APPEND_ONLY_READ_THE_DOCS: mapScopeRules(
3777 // @fb-only: options.scopeRules_APPEND_ONLY_READ_THE_DOCS,
3778 // @fb-only: params,
3779 // @fb-only: )
3780
3781 });
3782 atomCache = atomCache.set(params, newAtom);
3783 return newAtom;
3784 };
3785}
3786
3787var Recoil_atomFamily = atomFamily;
3788
3789// flowlint-next-line unclear-type:off
3790
3791
3792const constantSelector = Recoil_selectorFamily({
3793 key: '__constant',
3794 get: constant => () => constant,
3795 cacheImplementationForParams_UNSTABLE: Recoil_cacheWithReferenceEquality
3796}); // Function that returns a selector which always produces the
3797// same constant value. It may be called multiple times with the
3798// same value, based on reference equality, and will provide the
3799// same selector.
3800
3801function constSelector(constant) {
3802 return constantSelector(constant);
3803}
3804
3805var Recoil_constSelector = constSelector;
3806
3807// flowlint-next-line unclear-type:off
3808
3809
3810const throwingSelector = Recoil_selectorFamily({
3811 key: '__error',
3812 get: message => () => {
3813 throw new Error(message);
3814 },
3815 cacheImplementationForParams_UNSTABLE: Recoil_cacheWithReferenceEquality
3816}); // Function that returns a selector which always throws an error
3817// with the provided message.
3818
3819function errorSelector(message) {
3820 return throwingSelector(message);
3821}
3822
3823var Recoil_errorSelector = errorSelector;
3824
3825/**
3826 * Copyright (c) Facebook, Inc. and its affiliates.
3827 *
3828 * This source code is licensed under the MIT license found in the
3829 * LICENSE file in the root directory of this source tree.
3830 *
3831 * Wraps another recoil value and prevents writing to it.
3832 *
3833 * @emails oncall+recoil
3834 *
3835 * @format
3836 */
3837
3838function readOnlySelector(atom) {
3839 // flowlint-next-line unclear-type: off
3840 return atom;
3841}
3842
3843var Recoil_readOnlySelector = readOnlySelector;
3844
3845const {
3846 loadableWithError: loadableWithError$3,
3847 loadableWithPromise: loadableWithPromise$3,
3848 loadableWithValue: loadableWithValue$3
3849} = Recoil_Loadable;
3850
3851
3852
3853
3854
3855 /////////////////
3856// TRUTH TABLE
3857/////////////////
3858// Dependencies waitForNone waitForAny waitForAll
3859// [loading, loading] [Promise, Promise] Promise Promise
3860// [value, loading] [value, Promise] [value, Promise] Promise
3861// [value, value] [value, value] [value, value] [value, value]
3862//
3863// [error, loading] [Error, Promise] Promise Error
3864// [error, error] [Error, Error] Error Error
3865// [value, error] [value, Error] [value, Error] Error
3866// Issue parallel requests for all dependencies and return the current
3867// status if they have results, have some error, or are still pending.
3868
3869
3870function concurrentRequests(getRecoilValue, deps) {
3871 const results = Array(deps.length).fill(undefined);
3872 const exceptions = Array(deps.length).fill(undefined);
3873
3874 for (const [i, dep] of deps.entries()) {
3875 try {
3876 results[i] = getRecoilValue(dep);
3877 } catch (e) {
3878 // exceptions can either be Promises of pending results or real errors
3879 exceptions[i] = e;
3880 }
3881 }
3882
3883 return [results, exceptions];
3884}
3885
3886function isError(exp) {
3887 return exp != null && !Recoil_isPromise(exp);
3888}
3889
3890function unwrapDependencies(dependencies) {
3891 return Array.isArray(dependencies) ? dependencies : Object.getOwnPropertyNames(dependencies).map(key => dependencies[key]);
3892}
3893
3894function getValueFromLoadablePromiseResult(result) {
3895 if (result.hasOwnProperty('value')) {
3896 return result.value;
3897 }
3898
3899 return result;
3900}
3901
3902function wrapResults(dependencies, results) {
3903 return Array.isArray(dependencies) ? results : // Object.getOwnPropertyNames() has consistent key ordering with ES6
3904 Object.getOwnPropertyNames(dependencies).reduce((out, key, idx) => ({ ...out,
3905 [key]: results[idx]
3906 }), {});
3907}
3908
3909function wrapLoadables(dependencies, results, exceptions) {
3910 const output = exceptions.map((exception, idx) => exception == null ? loadableWithValue$3(results[idx]) : Recoil_isPromise(exception) ? loadableWithPromise$3(exception) : loadableWithError$3(exception));
3911 return wrapResults(dependencies, output);
3912} // Selector that requests all dependencies in parallel and immediately returns
3913// current results without waiting.
3914
3915
3916const waitForNone = Recoil_selectorFamily({
3917 key: '__waitForNone',
3918 get: dependencies => ({
3919 get
3920 }) => {
3921 // Issue requests for all dependencies in parallel.
3922 const deps = unwrapDependencies(dependencies);
3923 const [results, exceptions] = concurrentRequests(get, deps); // Always return the current status of the results; never block.
3924
3925 return wrapLoadables(dependencies, results, exceptions);
3926 }
3927}); // Selector that requests all dependencies in parallel and waits for at least
3928// one to be available before returning results. It will only error if all
3929// dependencies have errors.
3930
3931const waitForAny = Recoil_selectorFamily({
3932 key: '__waitForAny',
3933 get: dependencies => ({
3934 get
3935 }) => {
3936 // Issue requests for all dependencies in parallel.
3937 // Exceptions can either be Promises of pending results or real errors
3938 const deps = unwrapDependencies(dependencies);
3939 const [results, exceptions] = concurrentRequests(get, deps); // If any results are available, return the current status
3940
3941 if (exceptions.some(exp => exp == null)) {
3942 return wrapLoadables(dependencies, results, exceptions);
3943 } // Since we are waiting for any results, only throw an error if all
3944 // dependencies have an error. Then, throw the first one.
3945
3946
3947 if (exceptions.every(isError)) {
3948 throw exceptions.find(isError);
3949 }
3950
3951 if (Recoil_gkx_1('recoil_async_selector_refactor')) {
3952 // Otherwise, return a promise that will resolve when the next result is
3953 // available, whichever one happens to be next. But, if all pending
3954 // dependencies end up with errors, then reject the promise.
3955 return new Promise((resolve, reject) => {
3956 for (const [i, exp] of exceptions.entries()) {
3957 if (Recoil_isPromise(exp)) {
3958 exp.then(result => {
3959 results[i] = getValueFromLoadablePromiseResult(result);
3960 exceptions[i] = null;
3961 resolve(wrapLoadables(dependencies, results, exceptions));
3962 }).catch(error => {
3963 exceptions[i] = error;
3964
3965 if (exceptions.every(isError)) {
3966 reject(exceptions[0]);
3967 }
3968 });
3969 }
3970 }
3971 });
3972 } else {
3973 throw new Promise((resolve, reject) => {
3974 for (const [i, exp] of exceptions.entries()) {
3975 if (Recoil_isPromise(exp)) {
3976 exp.then(result => {
3977 results[i] = result;
3978 exceptions[i] = null;
3979 resolve(wrapLoadables(dependencies, results, exceptions));
3980 }).catch(error => {
3981 exceptions[i] = error;
3982
3983 if (exceptions.every(isError)) {
3984 reject(exceptions[0]);
3985 }
3986 });
3987 }
3988 }
3989 });
3990 }
3991 }
3992}); // Selector that requests all dependencies in parallel and waits for all to be
3993// available before returning a value. It will error if any dependencies error.
3994
3995const waitForAll = Recoil_selectorFamily({
3996 key: '__waitForAll',
3997 get: dependencies => ({
3998 get
3999 }) => {
4000 // Issue requests for all dependencies in parallel.
4001 // Exceptions can either be Promises of pending results or real errors
4002 const deps = unwrapDependencies(dependencies);
4003 const [results, exceptions] = concurrentRequests(get, deps); // If all results are available, return the results
4004
4005 if (exceptions.every(exp => exp == null)) {
4006 return wrapResults(dependencies, results);
4007 } // If we have any errors, throw the first error
4008
4009
4010 const error = exceptions.find(isError);
4011
4012 if (error != null) {
4013 throw error;
4014 }
4015
4016 if (Recoil_gkx_1('recoil_async_selector_refactor')) {
4017 // Otherwise, return a promise that will resolve when all results are available
4018 return Promise.all(exceptions).then(results => wrapResults(dependencies, results.map(getValueFromLoadablePromiseResult)));
4019 } else {
4020 throw Promise.all(exceptions).then(results => wrapResults(dependencies, results));
4021 }
4022 }
4023});
4024const noWait = Recoil_selectorFamily({
4025 key: '__noWait',
4026 get: dependency => ({
4027 get
4028 }) => {
4029 try {
4030 return loadableWithValue$3(get(dependency));
4031 } catch (exception) {
4032 return Recoil_isPromise(exception) ? loadableWithPromise$3(exception) : loadableWithError$3(exception);
4033 }
4034 }
4035});
4036var Recoil_WaitFor = {
4037 waitForNone,
4038 waitForAny,
4039 waitForAll,
4040 noWait
4041};
4042
4043const {
4044 DefaultValue: DefaultValue$4
4045} = Recoil_Node;
4046
4047const {
4048 RecoilRoot: RecoilRoot$2
4049} = Recoil_RecoilRoot_react;
4050
4051const {
4052 isRecoilValue: isRecoilValue$5
4053} = Recoil_RecoilValue$1;
4054
4055const {
4056 useGotoRecoilSnapshot: useGotoRecoilSnapshot$1,
4057 useRecoilCallback: useRecoilCallback$1,
4058 useRecoilSnapshot: useRecoilSnapshot$1,
4059 useRecoilState: useRecoilState$1,
4060 useRecoilStateLoadable: useRecoilStateLoadable$1,
4061 useRecoilTransactionObserver: useRecoilTransactionObserver$1,
4062 useRecoilValue: useRecoilValue$1,
4063 useRecoilValueLoadable: useRecoilValueLoadable$1,
4064 useResetRecoilState: useResetRecoilState$1,
4065 useSetRecoilState: useSetRecoilState$1,
4066 useSetUnvalidatedAtomValues: useSetUnvalidatedAtomValues$1,
4067 useTransactionObservation_DEPRECATED: useTransactionObservation_DEPRECATED$1
4068} = Recoil_Hooks;
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086const {
4087 noWait: noWait$1,
4088 waitForAll: waitForAll$1,
4089 waitForAny: waitForAny$1,
4090 waitForNone: waitForNone$1
4091} = Recoil_WaitFor;
4092
4093var Recoil_index = {
4094 // Types
4095 DefaultValue: DefaultValue$4,
4096 // Components
4097 RecoilRoot: RecoilRoot$2,
4098 useRecoilBridgeAcrossReactRoots_UNSTABLE: Recoil_useRecoilBridgeAcrossReactRoots,
4099 // RecoilValues
4100 atom: Recoil_atom,
4101 selector: Recoil_selector,
4102 // Convenience RecoilValues
4103 atomFamily: Recoil_atomFamily,
4104 selectorFamily: Recoil_selectorFamily,
4105 constSelector: Recoil_constSelector,
4106 errorSelector: Recoil_errorSelector,
4107 readOnlySelector: Recoil_readOnlySelector,
4108 // Hooks that accept RecoilValues
4109 useRecoilValue: useRecoilValue$1,
4110 useRecoilValueLoadable: useRecoilValueLoadable$1,
4111 useRecoilState: useRecoilState$1,
4112 useRecoilStateLoadable: useRecoilStateLoadable$1,
4113 useSetRecoilState: useSetRecoilState$1,
4114 useResetRecoilState: useResetRecoilState$1,
4115 // Hooks for asynchronous Recoil
4116 useRecoilCallback: useRecoilCallback$1,
4117 // Hooks for Snapshots
4118 useGotoRecoilSnapshot: useGotoRecoilSnapshot$1,
4119 useRecoilSnapshot: useRecoilSnapshot$1,
4120 useRecoilTransactionObserver_UNSTABLE: useRecoilTransactionObserver$1,
4121 useTransactionObservation_UNSTABLE: useTransactionObservation_DEPRECATED$1,
4122 useSetUnvalidatedAtomValues_UNSTABLE: useSetUnvalidatedAtomValues$1,
4123 // Concurrency Helpers
4124 noWait: noWait$1,
4125 waitForNone: waitForNone$1,
4126 waitForAny: waitForAny$1,
4127 waitForAll: waitForAll$1,
4128 // Other functions
4129 isRecoilValue: isRecoilValue$5
4130};
4131var Recoil_index_1 = Recoil_index.DefaultValue;
4132var Recoil_index_2 = Recoil_index.RecoilRoot;
4133var Recoil_index_3 = Recoil_index.useRecoilBridgeAcrossReactRoots_UNSTABLE;
4134var Recoil_index_4 = Recoil_index.atom;
4135var Recoil_index_5 = Recoil_index.selector;
4136var Recoil_index_6 = Recoil_index.atomFamily;
4137var Recoil_index_7 = Recoil_index.selectorFamily;
4138var Recoil_index_8 = Recoil_index.constSelector;
4139var Recoil_index_9 = Recoil_index.errorSelector;
4140var Recoil_index_10 = Recoil_index.readOnlySelector;
4141var Recoil_index_11 = Recoil_index.useRecoilValue;
4142var Recoil_index_12 = Recoil_index.useRecoilValueLoadable;
4143var Recoil_index_13 = Recoil_index.useRecoilState;
4144var Recoil_index_14 = Recoil_index.useRecoilStateLoadable;
4145var Recoil_index_15 = Recoil_index.useSetRecoilState;
4146var Recoil_index_16 = Recoil_index.useResetRecoilState;
4147var Recoil_index_17 = Recoil_index.useRecoilCallback;
4148var Recoil_index_18 = Recoil_index.useGotoRecoilSnapshot;
4149var Recoil_index_19 = Recoil_index.useRecoilSnapshot;
4150var Recoil_index_20 = Recoil_index.useRecoilTransactionObserver_UNSTABLE;
4151var Recoil_index_21 = Recoil_index.useTransactionObservation_UNSTABLE;
4152var Recoil_index_22 = Recoil_index.useSetUnvalidatedAtomValues_UNSTABLE;
4153var Recoil_index_23 = Recoil_index.noWait;
4154var Recoil_index_24 = Recoil_index.waitForNone;
4155var Recoil_index_25 = Recoil_index.waitForAny;
4156var Recoil_index_26 = Recoil_index.waitForAll;
4157var Recoil_index_27 = Recoil_index.isRecoilValue;
4158
4159exports.DefaultValue = Recoil_index_1;
4160exports.RecoilRoot = Recoil_index_2;
4161exports.atom = Recoil_index_4;
4162exports.atomFamily = Recoil_index_6;
4163exports.constSelector = Recoil_index_8;
4164exports.default = Recoil_index;
4165exports.errorSelector = Recoil_index_9;
4166exports.isRecoilValue = Recoil_index_27;
4167exports.noWait = Recoil_index_23;
4168exports.readOnlySelector = Recoil_index_10;
4169exports.selector = Recoil_index_5;
4170exports.selectorFamily = Recoil_index_7;
4171exports.useGotoRecoilSnapshot = Recoil_index_18;
4172exports.useRecoilBridgeAcrossReactRoots_UNSTABLE = Recoil_index_3;
4173exports.useRecoilCallback = Recoil_index_17;
4174exports.useRecoilSnapshot = Recoil_index_19;
4175exports.useRecoilState = Recoil_index_13;
4176exports.useRecoilStateLoadable = Recoil_index_14;
4177exports.useRecoilTransactionObserver_UNSTABLE = Recoil_index_20;
4178exports.useRecoilValue = Recoil_index_11;
4179exports.useRecoilValueLoadable = Recoil_index_12;
4180exports.useResetRecoilState = Recoil_index_16;
4181exports.useSetRecoilState = Recoil_index_15;
4182exports.useSetUnvalidatedAtomValues_UNSTABLE = Recoil_index_22;
4183exports.useTransactionObservation_UNSTABLE = Recoil_index_21;
4184exports.waitForAll = Recoil_index_26;
4185exports.waitForAny = Recoil_index_25;
4186exports.waitForNone = Recoil_index_24;