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.
- package/dist/Onyx.js +61 -26
- package/dist/OnyxCache.d.ts +24 -18
- package/dist/OnyxCache.js +53 -31
- package/dist/OnyxUtils.d.ts +7 -7
- package/dist/OnyxUtils.js +43 -37
- package/dist/index.d.ts +6 -5
- package/dist/index.js +1 -1
- package/dist/storage/providers/IDBKeyValProvider.js +24 -3
- package/dist/types.d.ts +6 -15
- package/dist/utils.d.ts +20 -2
- package/dist/utils.js +52 -2
- package/dist/withOnyx/index.d.ts +15 -0
- package/dist/{withOnyx.js → withOnyx/index.js} +64 -67
- package/dist/{withOnyx.d.ts → withOnyx/types.d.ts} +45 -45
- package/dist/withOnyx/types.js +2 -0
- package/package.json +2 -2
|
@@ -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
|
|
37
|
-
const
|
|
38
|
-
const Str = __importStar(require("
|
|
39
|
-
const utils_1 = __importDefault(require("
|
|
40
|
-
const
|
|
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
|
|
57
|
-
* @param
|
|
58
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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[
|
|
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 =
|
|
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
|
-
|
|
112
|
-
if (
|
|
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,
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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 (
|
|
201
|
+
if (prevVal === val || (utils_1.default.isEmptyObject(prevVal) && utils_1.default.isEmptyObject(val))) {
|
|
194
202
|
return;
|
|
195
203
|
}
|
|
196
|
-
|
|
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 =
|
|
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 =
|
|
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 (
|
|
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 (
|
|
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] =
|
|
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
|
-
|
|
245
|
-
if (
|
|
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
|
|
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
|
|
268
|
-
* @param
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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,
|
|
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 {
|
|
2
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
*
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-onyx",
|
|
3
|
-
"version": "2.0.
|
|
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
|
|
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",
|