react-native-onyx 2.0.71 → 2.0.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/useOnyx.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import type { IsEqual } from 'type-fest';
2
- import type { CollectionKeyBase, OnyxCollection, OnyxEntry, OnyxKey, OnyxValue, Selector } from './types';
1
+ import type { OnyxKey, OnyxValue } from './types';
3
2
  type BaseUseOnyxOptions = {
4
3
  /**
5
4
  * Determines if this key in this subscription is safe to be evicted.
@@ -20,23 +19,23 @@ type UseOnyxInitialValueOption<TInitialValue> = {
20
19
  */
21
20
  initialValue?: TInitialValue;
22
21
  };
22
+ type UseOnyxSelector<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>> = (data: OnyxValue<TKey> | undefined) => TReturnValue;
23
23
  type UseOnyxSelectorOption<TKey extends OnyxKey, TReturnValue> = {
24
24
  /**
25
25
  * This will be used to subscribe to a subset of an Onyx key's data.
26
26
  * Using this setting on `useOnyx` can have very positive performance benefits because the component will only re-render
27
27
  * when the subset of data changes. Otherwise, any change of data on any property would normally
28
28
  * cause the component to re-render (and that can be expensive from a performance standpoint).
29
+ * @see `useOnyx` cannot return `null` and so selector will replace `null` with `undefined` to maintain compatibility.
29
30
  */
30
- selector?: Selector<TKey, unknown, TReturnValue>;
31
+ selector?: UseOnyxSelector<TKey, TReturnValue>;
31
32
  };
32
33
  type FetchStatus = 'loading' | 'loaded';
33
- type SelectedValue<TKey, TValue> = TKey extends CollectionKeyBase ? OnyxCollection<TValue> : OnyxEntry<TValue>;
34
- type CachedValue<TKey extends OnyxKey, TValue> = IsEqual<TValue, OnyxValue<TKey>> extends true ? TValue : SelectedValue<TKey, TValue>;
35
34
  type ResultMetadata = {
36
35
  status: FetchStatus;
37
36
  };
38
- type UseOnyxResult<TKey extends OnyxKey, TValue> = [CachedValue<TKey, TValue>, ResultMetadata];
39
- declare function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(key: TKey, options?: BaseUseOnyxOptions & UseOnyxInitialValueOption<TReturnValue> & Required<UseOnyxSelectorOption<TKey, TReturnValue>>): UseOnyxResult<TKey, TReturnValue>;
40
- declare function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(key: TKey, options?: BaseUseOnyxOptions & UseOnyxInitialValueOption<NoInfer<TReturnValue>>): UseOnyxResult<TKey, TReturnValue>;
37
+ type UseOnyxResult<TValue> = [NonNullable<TValue> | undefined, ResultMetadata];
38
+ declare function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(key: TKey, options?: BaseUseOnyxOptions & UseOnyxInitialValueOption<TReturnValue> & Required<UseOnyxSelectorOption<TKey, TReturnValue>>): UseOnyxResult<TReturnValue>;
39
+ declare function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(key: TKey, options?: BaseUseOnyxOptions & UseOnyxInitialValueOption<NoInfer<TReturnValue>>): UseOnyxResult<TReturnValue>;
41
40
  export default useOnyx;
42
41
  export type { FetchStatus, ResultMetadata, UseOnyxResult };
package/dist/useOnyx.js CHANGED
@@ -10,9 +10,36 @@ const OnyxConnectionManager_1 = __importDefault(require("./OnyxConnectionManager
10
10
  const OnyxUtils_1 = __importDefault(require("./OnyxUtils"));
11
11
  const useLiveRef_1 = __importDefault(require("./useLiveRef"));
12
12
  const usePrevious_1 = __importDefault(require("./usePrevious"));
13
+ /**
14
+ * Gets the cached value from the Onyx cache. If the key is a collection key, it will return all the values in the collection.
15
+ * It is a fork of `tryGetCachedValue` from `OnyxUtils` caused by different selector logic in `useOnyx`. It should be unified in the future, when `withOnyx` is removed.
16
+ */
17
+ function tryGetCachedValue(key) {
18
+ if (!OnyxUtils_1.default.isCollectionKey(key)) {
19
+ return OnyxCache_1.default.get(key);
20
+ }
21
+ const allCacheKeys = OnyxCache_1.default.getAllKeys();
22
+ // It is possible we haven't loaded all keys yet so we do not know if the
23
+ // collection actually exists.
24
+ if (allCacheKeys.size === 0) {
25
+ return;
26
+ }
27
+ const values = {};
28
+ allCacheKeys.forEach((cacheKey) => {
29
+ if (!cacheKey.startsWith(key)) {
30
+ return;
31
+ }
32
+ values[cacheKey] = OnyxCache_1.default.get(cacheKey);
33
+ });
34
+ return values;
35
+ }
36
+ /**
37
+ * Gets the value from cache and maps it with selector. It changes `null` to `undefined` for `useOnyx` compatibility.
38
+ */
13
39
  function getCachedValue(key, selector) {
14
- var _a;
15
- return ((_a = OnyxUtils_1.default.tryGetCachedValue(key, { selector })) !== null && _a !== void 0 ? _a : undefined);
40
+ const value = tryGetCachedValue(key);
41
+ const selectedValue = selector ? selector(value) : value;
42
+ return selectedValue !== null && selectedValue !== void 0 ? selectedValue : undefined;
16
43
  }
17
44
  function useOnyx(key, options) {
18
45
  const connectionRef = (0, react_1.useRef)(null);
@@ -73,7 +100,7 @@ function useOnyx(key, options) {
73
100
  }
74
101
  }, [key, options === null || options === void 0 ? void 0 : options.canEvict]);
75
102
  const getSnapshot = (0, react_1.useCallback)(() => {
76
- var _a, _b, _c;
103
+ var _a, _b, _c, _d;
77
104
  // We return the initial result right away during the first connection if `initWithStoredValues` is set to `false`.
78
105
  if (isFirstConnectionRef.current && (options === null || options === void 0 ? void 0 : options.initWithStoredValues) === false) {
79
106
  return resultRef.current;
@@ -107,7 +134,7 @@ function useOnyx(key, options) {
107
134
  newValueRef.current = ((_a = options === null || options === void 0 ? void 0 : options.initialValue) !== null && _a !== void 0 ? _a : undefined);
108
135
  newFetchStatus = 'loaded';
109
136
  }
110
- // We do a deep equality check if `selector` is defined, since each `OnyxUtils.tryGetCachedValue()` call will
137
+ // We do a deep equality check if `selector` is defined, since each `tryGetCachedValue()` call will
111
138
  // generate a plain new primitive/object/array that was created using the `selector` function.
112
139
  // For the other cases we will only deal with object reference checks, so just a shallow equality check is enough.
113
140
  let areValuesEqual;
@@ -124,10 +151,10 @@ function useOnyx(key, options) {
124
151
  if (isCacheSetFirstTime || !areValuesEqual) {
125
152
  previousValueRef.current = newValueRef.current;
126
153
  // If the new value is `null` we default it to `undefined` to ensure the consumer gets a consistent result from the hook.
127
- resultRef.current = [previousValueRef.current, { status: newFetchStatus !== null && newFetchStatus !== void 0 ? newFetchStatus : 'loaded' }];
154
+ resultRef.current = [(_d = previousValueRef.current) !== null && _d !== void 0 ? _d : undefined, { status: newFetchStatus !== null && newFetchStatus !== void 0 ? newFetchStatus : 'loaded' }];
128
155
  }
129
156
  return resultRef.current;
130
- }, [key, selectorRef, options === null || options === void 0 ? void 0 : options.initWithStoredValues, options === null || options === void 0 ? void 0 : options.allowStaleData, options === null || options === void 0 ? void 0 : options.initialValue]);
157
+ }, [options === null || options === void 0 ? void 0 : options.initWithStoredValues, options === null || options === void 0 ? void 0 : options.allowStaleData, options === null || options === void 0 ? void 0 : options.initialValue, key, selectorRef]);
131
158
  const subscribe = (0, react_1.useCallback)((onStoreChange) => {
132
159
  connectionRef.current = OnyxConnectionManager_1.default.connect({
133
160
  key,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-onyx",
3
- "version": "2.0.71",
3
+ "version": "2.0.73",
4
4
  "author": "Expensify, Inc.",
5
5
  "homepage": "https://expensify.com",
6
6
  "description": "State management for React Native",