react-native-onyx 2.0.41 → 2.0.43

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.
@@ -31,21 +31,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
31
31
  * something in Onyx (a key/value store). That way, as soon as data in Onyx changes, the state will be set and the view
32
32
  * will automatically change to reflect the new data.
33
33
  */
34
- const prop_types_1 = __importDefault(require("prop-types"));
35
34
  const react_1 = __importDefault(require("react"));
36
- const underscore_1 = __importDefault(require("underscore"));
37
- const Onyx_1 = __importDefault(require("./Onyx"));
38
- const Str = __importStar(require("./Str"));
39
- const utils_1 = __importDefault(require("./utils"));
40
- const OnyxUtils_1 = __importDefault(require("./OnyxUtils"));
35
+ const Onyx_1 = __importDefault(require("../Onyx"));
36
+ const OnyxUtils_1 = __importDefault(require("../OnyxUtils"));
37
+ const Str = __importStar(require("../Str"));
38
+ const utils_1 = __importDefault(require("../utils"));
39
+ const OnyxCache_1 = __importDefault(require("../OnyxCache"));
41
40
  // This is a list of keys that can exist on a `mapping`, but are not directly related to loading data from Onyx. When the keys of a mapping are looped over to check
42
41
  // if a key has changed, it's a good idea to skip looking at these properties since they would have unexpected results.
43
42
  const mappingPropertiesToIgnoreChangesTo = ['initialValue', 'allowStaleData'];
44
43
  /**
45
44
  * Returns the display name of a component
46
- *
47
- * @param {object} component
48
- * @returns {string}
49
45
  */
50
46
  function getDisplayName(component) {
51
47
  return component.displayName || component.name || 'Component';
@@ -53,17 +49,28 @@ function getDisplayName(component) {
53
49
  /**
54
50
  * Removes all the keys from state that are unrelated to the onyx data being mapped to the component.
55
51
  *
56
- * @param {Object} state of the component
57
- * @param {Object} onyxToStateMapping the object holding all of the mapping configuration for the component
58
- * @returns {Object}
52
+ * @param state of the component
53
+ * @param onyxToStateMapping the object holding all of the mapping configuration for the component
54
+ */
55
+ function getOnyxDataFromState(state, onyxToStateMapping) {
56
+ return utils_1.default.pick(state, Object.keys(onyxToStateMapping));
57
+ }
58
+ /**
59
+ * Utility function to return the properly typed entries of the `withOnyx` mapping object.
60
+ */
61
+ function mapOnyxToStateEntries(mapOnyxToState) {
62
+ return Object.entries(mapOnyxToState);
63
+ }
64
+ /**
65
+ * @deprecated Use `useOnyx` instead of `withOnyx` whenever possible.
66
+ *
67
+ * This is a higher order component that provides the ability to map a state property directly to
68
+ * something in Onyx (a key/value store). That way, as soon as data in Onyx changes, the state will be set and the view
69
+ * will automatically change to reflect the new data.
59
70
  */
60
- const getOnyxDataFromState = (state, onyxToStateMapping) => underscore_1.default.pick(state, underscore_1.default.keys(onyxToStateMapping));
61
71
  function default_1(mapOnyxToState, shouldDelayUpdates = false) {
62
72
  // A list of keys that must be present in tempState before we can render the WrappedComponent
63
- const requiredKeysForInit = underscore_1.default.chain(mapOnyxToState)
64
- .omit((config) => config.initWithStoredValues === false)
65
- .keys()
66
- .value();
73
+ const requiredKeysForInit = Object.keys(utils_1.default.omit(mapOnyxToState, ([, options]) => options.initWithStoredValues === false));
67
74
  return (WrappedComponent) => {
68
75
  const displayName = getDisplayName(WrappedComponent);
69
76
  class withOnyx extends react_1.default.Component {
@@ -76,10 +83,11 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
76
83
  // This stores all the Onyx connection IDs to be used when the component unmounts so everything can be
77
84
  // disconnected. It is a key value store with the format {[mapping.key]: connectionID}.
78
85
  this.activeConnectionIDs = {};
79
- const cachedState = underscore_1.default.reduce(mapOnyxToState, (resultObj, mapping, propertyName) => {
86
+ const cachedState = mapOnyxToStateEntries(mapOnyxToState).reduce((resultObj, [propName, mapping]) => {
80
87
  const key = Str.result(mapping.key, props);
81
88
  let value = OnyxUtils_1.default.tryGetCachedValue(key, mapping);
82
- if (!value && mapping.initialValue) {
89
+ const hasCacheForKey = OnyxCache_1.default.hasCacheForKey(key);
90
+ if (!hasCacheForKey && !value && mapping.initialValue) {
83
91
  value = mapping.initialValue;
84
92
  }
85
93
  /**
@@ -93,14 +101,17 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
93
101
  * In reality, Onyx.merge() will only update the subscriber after all merges have been batched and the previous value is retrieved via a get() (returns a promise).
94
102
  * So, we won't use the cache optimization here as it will lead us to arbitrarily defer various actions in the application code.
95
103
  */
96
- if (mapping.initWithStoredValues !== false && ((value !== undefined && !OnyxUtils_1.default.hasPendingMergeForKey(key)) || mapping.allowStaleData)) {
104
+ const hasPendingMergeForKey = OnyxUtils_1.default.hasPendingMergeForKey(key);
105
+ const hasValueInCache = hasCacheForKey || value !== undefined;
106
+ const shouldSetState = mapping.initWithStoredValues !== false && ((hasValueInCache && !hasPendingMergeForKey) || !!mapping.allowStaleData);
107
+ if (shouldSetState) {
97
108
  // eslint-disable-next-line no-param-reassign
98
- resultObj[propertyName] = value;
109
+ resultObj[propName] = value;
99
110
  }
100
111
  return resultObj;
101
112
  }, {});
102
113
  // If we have all the data we need, then we can render the component immediately
103
- cachedState.loading = underscore_1.default.size(cachedState) < requiredKeysForInit.length;
114
+ cachedState.loading = Object.keys(cachedState).length < requiredKeysForInit.length;
104
115
  // Object holding the temporary initial state for the component while we load the various Onyx keys
105
116
  this.tempState = cachedState;
106
117
  this.state = cachedState;
@@ -108,12 +119,12 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
108
119
  componentDidMount() {
109
120
  const onyxDataFromState = getOnyxDataFromState(this.state, mapOnyxToState);
110
121
  // Subscribe each of the state properties to the proper Onyx key
111
- underscore_1.default.each(mapOnyxToState, (mapping, propertyName) => {
112
- if (underscore_1.default.includes(mappingPropertiesToIgnoreChangesTo, propertyName)) {
122
+ mapOnyxToStateEntries(mapOnyxToState).forEach(([propName, mapping]) => {
123
+ if (mappingPropertiesToIgnoreChangesTo.includes(propName)) {
113
124
  return;
114
125
  }
115
126
  const key = Str.result(mapping.key, Object.assign(Object.assign({}, this.props), onyxDataFromState));
116
- this.connectMappingToOnyx(mapping, propertyName, key);
127
+ this.connectMappingToOnyx(mapping, propName, key);
117
128
  });
118
129
  this.checkEvictableKeys();
119
130
  }
@@ -124,9 +135,9 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
124
135
  const isFirstTimeUpdatingAfterLoading = prevState.loading && !this.state.loading;
125
136
  const onyxDataFromState = getOnyxDataFromState(this.state, mapOnyxToState);
126
137
  const prevOnyxDataFromState = getOnyxDataFromState(prevState, mapOnyxToState);
127
- underscore_1.default.each(mapOnyxToState, (mapping, propName) => {
138
+ mapOnyxToStateEntries(mapOnyxToState).forEach(([propName, mapping]) => {
128
139
  // Some properties can be ignored because they aren't related to onyx keys and they will never change
129
- if (underscore_1.default.includes(mappingPropertiesToIgnoreChangesTo, propName)) {
140
+ if (mappingPropertiesToIgnoreChangesTo.includes(propName)) {
130
141
  return;
131
142
  }
132
143
  // The previous key comes from either:
@@ -148,7 +159,7 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
148
159
  }
149
160
  componentWillUnmount() {
150
161
  // Disconnect everything from Onyx
151
- underscore_1.default.each(mapOnyxToState, (mapping) => {
162
+ mapOnyxToStateEntries(mapOnyxToState).forEach(([, mapping]) => {
152
163
  const key = Str.result(mapping.key, Object.assign(Object.assign({}, this.props), getOnyxDataFromState(this.state, mapOnyxToState)));
153
164
  Onyx_1.default.disconnect(this.activeConnectionIDs[key], key);
154
165
  });
@@ -175,12 +186,9 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
175
186
  * We however need to workaround this issue in the HOC. The addition of initialValue makes things even more complex,
176
187
  * since you cannot be really sure if the component has been updated before or after the initial hydration. Therefore if
177
188
  * initialValue is there, we just check if the update is different than that and then try to handle it as best as we can.
178
- *
179
- * @param {String} statePropertyName
180
- * @param {*} val
181
189
  */
182
190
  setWithOnyxState(statePropertyName, val) {
183
- const prevValue = this.state[statePropertyName];
191
+ const prevVal = this.state[statePropertyName];
184
192
  // If the component is not loading (read "mounting"), then we can just update the state
185
193
  // There is a small race condition.
186
194
  // When calling setWithOnyxState we delete the tempState object that is used to hold temporary state updates while the HOC is gathering data.
@@ -190,15 +198,16 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
190
198
  // This simply bypasses the loading check if the tempState is gone and the update can be safely queued with a normal setStateProxy.
191
199
  if (!this.state.loading || !this.tempState) {
192
200
  // Performance optimization, do not trigger update with same values
193
- if (prevValue === val || (utils_1.default.isEmptyObject(prevValue) && utils_1.default.isEmptyObject(val))) {
201
+ if (prevVal === val || (utils_1.default.isEmptyObject(prevVal) && utils_1.default.isEmptyObject(val))) {
194
202
  return;
195
203
  }
196
- this.setStateProxy({ [statePropertyName]: val });
204
+ const valueWithoutNull = val === null ? undefined : val;
205
+ this.setStateProxy({ [statePropertyName]: valueWithoutNull });
197
206
  return;
198
207
  }
199
208
  this.tempState[statePropertyName] = val;
200
209
  // If some key does not have a value yet, do not update the state yet
201
- const tempStateIsMissingKey = underscore_1.default.some(requiredKeysForInit, (key) => underscore_1.default.isUndefined(this.tempState[key]));
210
+ const tempStateIsMissingKey = requiredKeysForInit.some((key) => { var _a; return ((_a = this.tempState) === null || _a === void 0 ? void 0 : _a[key]) === undefined; });
202
211
  if (tempStateIsMissingKey) {
203
212
  return;
204
213
  }
@@ -206,25 +215,26 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
206
215
  delete this.tempState;
207
216
  // Full of hacky workarounds to prevent the race condition described above.
208
217
  this.setState((prevState) => {
209
- const finalState = underscore_1.default.reduce(stateUpdate, (result, value, key) => {
218
+ const finalState = Object.keys(stateUpdate).reduce((result, _key) => {
219
+ const key = _key;
210
220
  if (key === 'loading') {
211
221
  return result;
212
222
  }
213
223
  const initialValue = mapOnyxToState[key].initialValue;
214
224
  // If initialValue is there and the state contains something different it means
215
225
  // an update has already been received and we can discard the value we are trying to hydrate
216
- if (!underscore_1.default.isUndefined(initialValue) && !underscore_1.default.isUndefined(prevState[key]) && prevState[key] !== initialValue) {
226
+ if (initialValue !== undefined && prevState[key] !== undefined && prevState[key] !== initialValue && prevState[key] !== null) {
217
227
  // eslint-disable-next-line no-param-reassign
218
228
  result[key] = prevState[key];
219
- // if value is already there (without initial value) then we can discard the value we are trying to hydrate
220
229
  }
221
- else if (!underscore_1.default.isUndefined(prevState[key])) {
230
+ else if (prevState[key] !== undefined && prevState[key] !== null) {
231
+ // if value is already there (without initial value) then we can discard the value we are trying to hydrate
222
232
  // eslint-disable-next-line no-param-reassign
223
233
  result[key] = prevState[key];
224
234
  }
225
- else {
235
+ else if (stateUpdate[key] !== null) {
226
236
  // eslint-disable-next-line no-param-reassign
227
- result[key] = value;
237
+ result[key] = stateUpdate[key];
228
238
  }
229
239
  return result;
230
240
  }, {});
@@ -241,11 +251,11 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
241
251
  // We will add this key to our list of recently accessed keys
242
252
  // if the canEvict function returns true. This is necessary criteria
243
253
  // we MUST use to specify if a key can be removed or not.
244
- underscore_1.default.each(mapOnyxToState, (mapping) => {
245
- if (underscore_1.default.isUndefined(mapping.canEvict)) {
254
+ mapOnyxToStateEntries(mapOnyxToState).forEach(([, mapping]) => {
255
+ if (mapping.canEvict === undefined) {
246
256
  return;
247
257
  }
248
- const canEvict = Str.result(mapping.canEvict, this.props);
258
+ const canEvict = !!Str.result(mapping.canEvict, this.props);
249
259
  const key = Str.result(mapping.key, this.props);
250
260
  if (!OnyxUtils_1.default.isSafeEvictionKey(key)) {
251
261
  throw new Error(`canEvict can't be used on key '${key}'. This key must explicitly be flagged as safe for removal by adding it to Onyx.init({safeEvictionKeys: []}).`);
@@ -261,22 +271,21 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
261
271
  /**
262
272
  * Takes a single mapping and binds the state of the component to the store
263
273
  *
264
- * @param {object} mapping
265
- * @param {string|function} mapping.key key to connect to. can be a string or a
274
+ * @param mapping.key key to connect to. can be a string or a
266
275
  * function that takes this.props as an argument and returns a string
267
- * @param {string} statePropertyName the name of the state property that Onyx will add the data to
268
- * @param {boolean} [mapping.initWithStoredValues] If set to false, then no data will be prefilled into the
276
+ * @param statePropertyName the name of the state property that Onyx will add the data to
277
+ * @param [mapping.initWithStoredValues] If set to false, then no data will be prefilled into the
269
278
  * component
270
- * @param {string} key to connect to Onyx with
279
+ * @param key to connect to Onyx with
271
280
  */
272
281
  connectMappingToOnyx(mapping, statePropertyName, key) {
282
+ const onyxMapping = mapOnyxToState[statePropertyName];
273
283
  // Remember what the previous key was so that key changes can be detected when data is being loaded from Onyx. This will allow
274
284
  // dependent keys to finish loading their data.
275
285
  // eslint-disable-next-line no-param-reassign
276
- mapOnyxToState[statePropertyName].previousKey = key;
286
+ onyxMapping.previousKey = key;
277
287
  // eslint-disable-next-line rulesdir/prefer-onyx-connect-in-libs
278
- this.activeConnectionIDs[key] = Onyx_1.default.connect(Object.assign(Object.assign({}, mapping), { key,
279
- statePropertyName, withOnyxInstance: this, displayName }));
288
+ this.activeConnectionIDs[key] = Onyx_1.default.connect(Object.assign(Object.assign({}, mapping), { key, statePropertyName: statePropertyName, withOnyxInstance: this, displayName }));
280
289
  }
281
290
  flushPendingSetStates() {
282
291
  if (!this.shouldDelayUpdates) {
@@ -290,29 +299,17 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
290
299
  }
291
300
  render() {
292
301
  // Remove any null values so that React replaces them with default props
293
- const propsToPass = underscore_1.default.omit(this.props, underscore_1.default.isNull);
302
+ const propsToPass = utils_1.default.omit(this.props, ([, propValue]) => propValue === null);
294
303
  if (this.state.loading) {
295
304
  return null;
296
305
  }
297
306
  // Remove any internal state properties used by withOnyx
298
307
  // that should not be passed to a wrapped component
299
- let stateToPass = underscore_1.default.omit(this.state, 'loading');
300
- stateToPass = underscore_1.default.omit(stateToPass, underscore_1.default.isNull);
301
- const stateToPassWithoutNestedNulls = utils_1.default.removeNestedNullValues(stateToPass);
308
+ const stateToPass = utils_1.default.omit(this.state, ([stateKey, stateValue]) => stateKey === 'loading' || stateValue === null);
302
309
  // Spreading props and state is necessary in an HOC where the data cannot be predicted
303
- return (react_1.default.createElement(WrappedComponent, Object.assign({ markReadyForHydration: this.flushPendingSetStates }, propsToPass, stateToPassWithoutNestedNulls, { ref: this.props.forwardedRef })));
310
+ return (react_1.default.createElement(WrappedComponent, Object.assign({ markReadyForHydration: this.flushPendingSetStates }, propsToPass, stateToPass, { ref: this.props.forwardedRef })));
304
311
  }
305
312
  }
306
- withOnyx.propTypes = {
307
- forwardedRef: prop_types_1.default.oneOfType([
308
- prop_types_1.default.func,
309
- // eslint-disable-next-line react/forbid-prop-types
310
- prop_types_1.default.shape({ current: prop_types_1.default.object }),
311
- ]),
312
- };
313
- withOnyx.defaultProps = {
314
- forwardedRef: undefined,
315
- };
316
313
  withOnyx.displayName = `withOnyx(${displayName})`;
317
314
  return react_1.default.forwardRef((props, ref) => {
318
315
  const Component = withOnyx;
@@ -1,6 +1,6 @@
1
- import {IsEqual} from 'type-fest';
2
- import {CollectionKeyBase, ExtractOnyxCollectionValue, KeyValueMapping, OnyxCollection, OnyxEntry, OnyxKey, Selector} from './types';
3
-
1
+ import type { ForwardedRef } from 'react';
2
+ import type { IsEqual } from 'type-fest';
3
+ import type { CollectionKeyBase, ExtractOnyxCollectionValue, KeyValueMapping, NullableKeyValueMapping, OnyxCollection, OnyxEntry, OnyxKey, OnyxValue, Selector } from '../types';
4
4
  /**
5
5
  * Represents the base mapping options between an Onyx key and the component's prop.
6
6
  */
@@ -9,15 +9,18 @@ type BaseMapping<TComponentProps, TOnyxProps> = {
9
9
  initWithStoredValues?: boolean;
10
10
  allowStaleData?: boolean;
11
11
  };
12
-
12
+ /**
13
+ * Represents the base mapping options when an Onyx collection key is supplied.
14
+ */
13
15
  type CollectionBaseMapping<TOnyxKey extends CollectionKeyBase> = {
14
16
  initialValue?: OnyxCollection<KeyValueMapping[TOnyxKey]>;
15
17
  };
16
-
18
+ /**
19
+ * Represents the base mapping options when an Onyx non-collection key is supplied.
20
+ */
17
21
  type EntryBaseMapping<TOnyxKey extends OnyxKey> = {
18
22
  initialValue?: OnyxEntry<KeyValueMapping[TOnyxKey]>;
19
23
  };
20
-
21
24
  /**
22
25
  * Represents the string / function `key` mapping option between an Onyx key and the component's prop.
23
26
  *
@@ -40,12 +43,9 @@ type EntryBaseMapping<TOnyxKey extends OnyxKey> = {
40
43
  * },
41
44
  * ```
42
45
  */
43
- type BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends OnyxKey, TOnyxValue> = IsEqual<TOnyxValue, TOnyxProps[TOnyxProp]> extends true
44
- ? {
45
- key: TOnyxKey | ((props: Omit<TComponentProps, keyof TOnyxProps> & Partial<TOnyxProps>) => TOnyxKey);
46
- }
47
- : never;
48
-
46
+ type BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends OnyxKey, TOnyxValue> = IsEqual<TOnyxValue, TOnyxProps[TOnyxProp]> extends true ? {
47
+ key: TOnyxKey | ((props: Omit<TComponentProps, keyof TOnyxProps> & Partial<TOnyxProps>) => TOnyxKey);
48
+ } : never;
49
49
  /**
50
50
  * Represents the string `key` and `selector` mapping options between an Onyx key and the component's prop.
51
51
  *
@@ -65,7 +65,6 @@ type BaseMappingStringKeyAndSelector<TComponentProps, TOnyxProps, TReturnType, T
65
65
  key: TOnyxKey;
66
66
  selector: Selector<TOnyxKey, TOnyxProps, TReturnType>;
67
67
  };
68
-
69
68
  /**
70
69
  * Represents the function `key` and `selector` mapping options between an Onyx key and the component's prop.
71
70
  *
@@ -85,29 +84,21 @@ type BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, TReturnType,
85
84
  key: (props: Omit<TComponentProps, keyof TOnyxProps> & Partial<TOnyxProps>) => TOnyxKey;
86
85
  selector: Selector<TOnyxKey, TOnyxProps, TReturnType>;
87
86
  };
88
-
89
87
  /**
90
88
  * Represents the mapping options between an Onyx key and the component's prop with all its possibilities.
91
89
  */
92
- type Mapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends OnyxKey> = BaseMapping<TComponentProps, TOnyxProps> &
93
- EntryBaseMapping<TOnyxKey> &
94
- (
95
- | BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey, OnyxEntry<KeyValueMapping[TOnyxKey]>>
96
- | BaseMappingStringKeyAndSelector<TComponentProps, TOnyxProps, TOnyxProps[TOnyxProp], TOnyxKey>
97
- | BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, TOnyxProps[TOnyxProp], TOnyxKey>
98
- );
99
-
90
+ type Mapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends OnyxKey> = BaseMapping<TComponentProps, TOnyxProps> & EntryBaseMapping<TOnyxKey> & (BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey, OnyxEntry<KeyValueMapping[TOnyxKey]>> | BaseMappingStringKeyAndSelector<TComponentProps, TOnyxProps, TOnyxProps[TOnyxProp], TOnyxKey> | BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, TOnyxProps[TOnyxProp], TOnyxKey>);
91
+ /**
92
+ * Represents a superset of `Mapping` type with internal properties included.
93
+ */
94
+ type WithOnyxMapping<TComponentProps, TOnyxProps> = Mapping<TComponentProps, TOnyxProps, keyof TOnyxProps, OnyxKey> & {
95
+ connectionID: number;
96
+ previousKey?: OnyxKey;
97
+ };
100
98
  /**
101
99
  * Represents the mapping options between an Onyx collection key without suffix and the component's prop with all its possibilities.
102
100
  */
103
- type CollectionMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends CollectionKeyBase> = BaseMapping<TComponentProps, TOnyxProps> &
104
- CollectionBaseMapping<TOnyxKey> &
105
- (
106
- | BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey, OnyxCollection<KeyValueMapping[TOnyxKey]>>
107
- | BaseMappingStringKeyAndSelector<TComponentProps, TOnyxProps, ExtractOnyxCollectionValue<TOnyxProps[TOnyxProp]>, TOnyxKey>
108
- | BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, ExtractOnyxCollectionValue<TOnyxProps[TOnyxProp]>, TOnyxKey>
109
- );
110
-
101
+ type CollectionMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends CollectionKeyBase> = BaseMapping<TComponentProps, TOnyxProps> & CollectionBaseMapping<TOnyxKey> & (BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey, OnyxCollection<KeyValueMapping[TOnyxKey]>> | BaseMappingStringKeyAndSelector<TComponentProps, TOnyxProps, ExtractOnyxCollectionValue<TOnyxProps[TOnyxProp]>, TOnyxKey> | BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, ExtractOnyxCollectionValue<TOnyxProps[TOnyxProp]>, TOnyxKey>);
111
102
  /**
112
103
  * Represents an union type of all the possible Onyx key mappings.
113
104
  * Each `OnyxPropMapping` will be associated with its respective Onyx key, ensuring different type-safety for each object.
@@ -115,7 +106,6 @@ type CollectionMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOny
115
106
  type OnyxPropMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps> = {
116
107
  [TOnyxKey in OnyxKey]: Mapping<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey>;
117
108
  }[OnyxKey];
118
-
119
109
  /**
120
110
  * Represents an union type of all the possible Onyx collection keys without suffix mappings.
121
111
  * Each `OnyxPropCollectionMapping` will be associated with its respective Onyx key, ensuring different type-safety for each object.
@@ -123,19 +113,29 @@ type OnyxPropMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxP
123
113
  type OnyxPropCollectionMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps> = {
124
114
  [TOnyxKey in CollectionKeyBase]: CollectionMapping<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey>;
125
115
  }[CollectionKeyBase];
126
-
127
116
  /**
128
- * @deprecated Use `useOnyx` instead of `withOnyx` whenever possible.
129
- *
130
- * This is a higher order component that provides the ability to map a state property directly to
131
- * something in Onyx (a key/value store). That way, as soon as data in Onyx changes, the state will be set and the view
132
- * will automatically change to reflect the new data.
117
+ * Represents an Onyx mapping object that connects Onyx keys to component's props.
118
+ */
119
+ type MapOnyxToState<TComponentProps, TOnyxProps> = {
120
+ [TOnyxProp in keyof TOnyxProps]: OnyxPropMapping<TComponentProps, TOnyxProps, TOnyxProp> | OnyxPropCollectionMapping<TComponentProps, TOnyxProps, TOnyxProp>;
121
+ };
122
+ /**
123
+ * Represents the `withOnyx` internal component props.
124
+ */
125
+ type WithOnyxProps<TComponentProps, TOnyxProps> = Omit<TComponentProps, keyof TOnyxProps> & {
126
+ forwardedRef?: ForwardedRef<unknown>;
127
+ };
128
+ /**
129
+ * Represents the `withOnyx` internal component state.
133
130
  */
134
- declare function withOnyx<TComponentProps, TOnyxProps>(
135
- mapping: {
136
- [TOnyxProp in keyof TOnyxProps]: OnyxPropMapping<TComponentProps, TOnyxProps, TOnyxProp> | OnyxPropCollectionMapping<TComponentProps, TOnyxProps, TOnyxProp>;
137
- },
138
- shouldDelayUpdates?: boolean,
139
- ): (component: React.ComponentType<TComponentProps>) => React.ComponentType<Omit<TComponentProps, keyof TOnyxProps>>;
140
-
141
- export default withOnyx;
131
+ type WithOnyxState<TOnyxProps> = TOnyxProps & {
132
+ loading: boolean;
133
+ };
134
+ /**
135
+ * Represents the `withOnyx` internal component instance.
136
+ */
137
+ type WithOnyxInstance = React.Component<unknown, WithOnyxState<NullableKeyValueMapping>> & {
138
+ setStateProxy: (modifier: Record<string, OnyxCollection<KeyValueMapping[OnyxKey]>> | ((state: Record<string, OnyxCollection<KeyValueMapping[OnyxKey]>>) => OnyxValue<OnyxKey>)) => void;
139
+ setWithOnyxState: (statePropertyName: OnyxKey, value: OnyxValue<OnyxKey>) => void;
140
+ };
141
+ export type { WithOnyxMapping, MapOnyxToState, WithOnyxProps, WithOnyxInstance, WithOnyxState };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-onyx",
3
- "version": "2.0.41",
3
+ "version": "2.0.43",
4
4
  "author": "Expensify, Inc.",
5
5
  "homepage": "https://expensify.com",
6
6
  "description": "State management for React Native",
@@ -31,7 +31,7 @@
31
31
  "lint": "eslint .",
32
32
  "typecheck": "tsc --noEmit",
33
33
  "test": "jest",
34
- "build": "tsc -p tsconfig.build.json && cp ./lib/*.d.ts ./dist",
34
+ "build": "tsc -p tsconfig.build.json",
35
35
  "build:watch": "nodemon --watch lib --ext js,json,ts,tsx --exec \"npm run build && npm pack\"",
36
36
  "prebuild:docs": "npm run build",
37
37
  "build:docs": "ts-node buildDocs.ts",