react-native-onyx 2.0.64 → 2.0.66
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/API.md +27 -23
- package/dist/Onyx.d.ts +31 -26
- package/dist/Onyx.js +32 -126
- package/dist/OnyxConnectionManager.d.ts +69 -0
- package/dist/OnyxConnectionManager.js +195 -0
- package/dist/OnyxUtils.d.ts +28 -37
- package/dist/OnyxUtils.js +158 -65
- package/dist/Str.d.ts +5 -1
- package/dist/Str.js +13 -1
- package/dist/createDeferredTask.d.ts +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/types.d.ts +40 -19
- package/dist/useOnyx.d.ts +2 -2
- package/dist/useOnyx.js +24 -20
- package/dist/utils.d.ts +6 -1
- package/dist/utils.js +7 -1
- package/dist/withOnyx/index.js +10 -10
- package/dist/withOnyx/types.d.ts +1 -1
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -226,29 +226,34 @@ type Collection<TKey extends CollectionKeyBase, TValue, TMap = never> = {
|
|
|
226
226
|
};
|
|
227
227
|
/** Represents the base options used in `Onyx.connect()` method. */
|
|
228
228
|
type BaseConnectOptions = {
|
|
229
|
+
/** If set to `false`, then the initial data will be only sent to the callback function if it changes. */
|
|
229
230
|
initWithStoredValues?: boolean;
|
|
231
|
+
/**
|
|
232
|
+
* If set to `false`, the connection won't be reused between other subscribers that are listening to the same Onyx key
|
|
233
|
+
* with the same connect configurations.
|
|
234
|
+
*/
|
|
235
|
+
reuseConnection?: boolean;
|
|
230
236
|
};
|
|
231
|
-
/** Represents additional options used inside withOnyx HOC */
|
|
232
|
-
type WithOnyxConnectOptions<TKey extends OnyxKey> = {
|
|
233
|
-
withOnyxInstance: WithOnyxInstance;
|
|
234
|
-
statePropertyName: string;
|
|
235
|
-
displayName: string;
|
|
236
|
-
initWithStoredValues?: boolean;
|
|
237
|
-
selector?: Selector<TKey, unknown, unknown>;
|
|
238
|
-
canEvict?: boolean;
|
|
239
|
-
};
|
|
240
|
-
type DefaultConnectCallback<TKey extends OnyxKey> = (value: OnyxEntry<KeyValueMapping[TKey]>, key: TKey) => void;
|
|
241
|
-
type CollectionConnectCallback<TKey extends OnyxKey> = (value: NonUndefined<OnyxCollection<KeyValueMapping[TKey]>>) => void;
|
|
242
237
|
/** Represents the callback function used in `Onyx.connect()` method with a regular key. */
|
|
243
|
-
type
|
|
238
|
+
type DefaultConnectCallback<TKey extends OnyxKey> = (value: OnyxEntry<KeyValueMapping[TKey]>, key: TKey) => void;
|
|
239
|
+
/** Represents the callback function used in `Onyx.connect()` method with a collection key. */
|
|
240
|
+
type CollectionConnectCallback<TKey extends OnyxKey> = (value: NonUndefined<OnyxCollection<KeyValueMapping[TKey]>>, key: TKey) => void;
|
|
241
|
+
/** Represents the options used in `Onyx.connect()` method with a regular key. */
|
|
242
|
+
type DefaultConnectOptions<TKey extends OnyxKey> = BaseConnectOptions & {
|
|
243
|
+
/** The Onyx key to subscribe to. */
|
|
244
244
|
key: TKey;
|
|
245
|
+
/** A function that will be called when the Onyx data we are subscribed changes. */
|
|
245
246
|
callback?: DefaultConnectCallback<TKey>;
|
|
247
|
+
/** If set to `true`, it will return the entire collection to the callback as a single object. */
|
|
246
248
|
waitForCollectionCallback?: false;
|
|
247
249
|
};
|
|
248
|
-
/** Represents the
|
|
249
|
-
type CollectionConnectOptions<TKey extends OnyxKey> = {
|
|
250
|
+
/** Represents the options used in `Onyx.connect()` method with a collection key. */
|
|
251
|
+
type CollectionConnectOptions<TKey extends OnyxKey> = BaseConnectOptions & {
|
|
252
|
+
/** The Onyx key to subscribe to. */
|
|
250
253
|
key: TKey extends CollectionKeyBase ? TKey : never;
|
|
254
|
+
/** A function that will be called when the Onyx data we are subscribed changes. */
|
|
251
255
|
callback?: CollectionConnectCallback<TKey>;
|
|
256
|
+
/** If set to `true`, it will return the entire collection to the callback as a single object. */
|
|
252
257
|
waitForCollectionCallback: true;
|
|
253
258
|
};
|
|
254
259
|
/**
|
|
@@ -261,12 +266,28 @@ type CollectionConnectOptions<TKey extends OnyxKey> = {
|
|
|
261
266
|
*
|
|
262
267
|
* If `waitForCollectionCallback` is `false` or not specified, the `key` can be any Onyx key and `callback` will be triggered with updates of each collection item
|
|
263
268
|
* and will pass `value` as an `OnyxEntry`.
|
|
264
|
-
*
|
|
265
|
-
* The type is also extended with `BaseConnectOptions` and `WithOnyxConnectOptions` to include additional options, depending on the context where it's used.
|
|
266
269
|
*/
|
|
267
|
-
type ConnectOptions<TKey extends OnyxKey> =
|
|
268
|
-
|
|
269
|
-
|
|
270
|
+
type ConnectOptions<TKey extends OnyxKey> = DefaultConnectOptions<TKey> | CollectionConnectOptions<TKey>;
|
|
271
|
+
/** Represents additional `Onyx.connect()` options used inside `withOnyx()` HOC. */
|
|
272
|
+
type WithOnyxConnectOptions<TKey extends OnyxKey> = ConnectOptions<TKey> & {
|
|
273
|
+
/** The `withOnyx` class instance to be internally passed. */
|
|
274
|
+
withOnyxInstance: WithOnyxInstance;
|
|
275
|
+
/** The name of the component's prop that is connected to the Onyx key. */
|
|
276
|
+
statePropertyName: string;
|
|
277
|
+
/** The component's display name. */
|
|
278
|
+
displayName: string;
|
|
279
|
+
/**
|
|
280
|
+
* This will be used to subscribe to a subset of an Onyx key's data.
|
|
281
|
+
* Using this setting on `withOnyx` can have very positive performance benefits because the component will only re-render
|
|
282
|
+
* when the subset of data changes. Otherwise, any change of data on any property would normally
|
|
283
|
+
* cause the component to re-render (and that can be expensive from a performance standpoint).
|
|
284
|
+
*/
|
|
285
|
+
selector?: Selector<TKey, unknown, unknown>;
|
|
286
|
+
/** Determines if this key in this subscription is safe to be evicted. */
|
|
287
|
+
canEvict?: boolean;
|
|
288
|
+
};
|
|
289
|
+
type Mapping<TKey extends OnyxKey> = WithOnyxConnectOptions<TKey> & {
|
|
290
|
+
subscriptionID: number;
|
|
270
291
|
};
|
|
271
292
|
/**
|
|
272
293
|
* Represents a single Onyx input value, that can be either `TOnyxValue` or `null` if the key should be deleted.
|
package/dist/useOnyx.d.ts
CHANGED
|
@@ -6,11 +6,11 @@ type BaseUseOnyxOptions = {
|
|
|
6
6
|
*/
|
|
7
7
|
canEvict?: boolean;
|
|
8
8
|
/**
|
|
9
|
-
* If set to false
|
|
9
|
+
* If set to `false`, then no data will be prefilled into the component.
|
|
10
10
|
*/
|
|
11
11
|
initWithStoredValues?: boolean;
|
|
12
12
|
/**
|
|
13
|
-
* If set to true
|
|
13
|
+
* If set to `true`, data will be retrieved from cache during the first render even if there is a pending merge for the key.
|
|
14
14
|
*/
|
|
15
15
|
allowStaleData?: boolean;
|
|
16
16
|
};
|
package/dist/useOnyx.js
CHANGED
|
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const fast_equals_1 = require("fast-equals");
|
|
7
7
|
const react_1 = require("react");
|
|
8
|
-
const Onyx_1 = __importDefault(require("./Onyx"));
|
|
9
8
|
const OnyxCache_1 = __importDefault(require("./OnyxCache"));
|
|
9
|
+
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"));
|
|
@@ -15,7 +15,7 @@ function getCachedValue(key, selector) {
|
|
|
15
15
|
return ((_a = OnyxUtils_1.default.tryGetCachedValue(key, { selector })) !== null && _a !== void 0 ? _a : undefined);
|
|
16
16
|
}
|
|
17
17
|
function useOnyx(key, options) {
|
|
18
|
-
const
|
|
18
|
+
const connectionRef = (0, react_1.useRef)(null);
|
|
19
19
|
const previousKey = (0, usePrevious_1.default)(key);
|
|
20
20
|
// Used to stabilize the selector reference and avoid unnecessary calls to `getSnapshot()`.
|
|
21
21
|
const selectorRef = (0, useLiveRef_1.default)(options === null || options === void 0 ? void 0 : options.selector);
|
|
@@ -57,6 +57,21 @@ function useOnyx(key, options) {
|
|
|
57
57
|
}
|
|
58
58
|
throw new Error(`'${previousKey}' key can't be changed to '${key}'. useOnyx() only supports dynamic keys if they are both collection member keys from the same collection e.g. from 'collection_id1' to 'collection_id2'.`);
|
|
59
59
|
}, [previousKey, key]);
|
|
60
|
+
// Mimics withOnyx's checkEvictableKeys() behavior.
|
|
61
|
+
const checkEvictableKey = (0, react_1.useCallback)(() => {
|
|
62
|
+
if ((options === null || options === void 0 ? void 0 : options.canEvict) === undefined || !connectionRef.current) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (!OnyxUtils_1.default.isSafeEvictionKey(key)) {
|
|
66
|
+
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: []}).`);
|
|
67
|
+
}
|
|
68
|
+
if (options.canEvict) {
|
|
69
|
+
OnyxConnectionManager_1.default.removeFromEvictionBlockList(connectionRef.current);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
OnyxConnectionManager_1.default.addToEvictionBlockList(connectionRef.current);
|
|
73
|
+
}
|
|
74
|
+
}, [key, options === null || options === void 0 ? void 0 : options.canEvict]);
|
|
60
75
|
const getSnapshot = (0, react_1.useCallback)(() => {
|
|
61
76
|
var _a, _b, _c;
|
|
62
77
|
// We get the value from cache while the first connection to Onyx is being made,
|
|
@@ -110,7 +125,7 @@ function useOnyx(key, options) {
|
|
|
110
125
|
return resultRef.current;
|
|
111
126
|
}, [key, selectorRef, options === null || options === void 0 ? void 0 : options.allowStaleData, options === null || options === void 0 ? void 0 : options.initialValue]);
|
|
112
127
|
const subscribe = (0, react_1.useCallback)((onStoreChange) => {
|
|
113
|
-
|
|
128
|
+
connectionRef.current = OnyxConnectionManager_1.default.connect({
|
|
114
129
|
key,
|
|
115
130
|
callback: () => {
|
|
116
131
|
// Signals that the first connection was made, so some logics in `getSnapshot()`
|
|
@@ -124,29 +139,18 @@ function useOnyx(key, options) {
|
|
|
124
139
|
initWithStoredValues: options === null || options === void 0 ? void 0 : options.initWithStoredValues,
|
|
125
140
|
waitForCollectionCallback: OnyxUtils_1.default.isCollectionKey(key),
|
|
126
141
|
});
|
|
142
|
+
checkEvictableKey();
|
|
127
143
|
return () => {
|
|
128
|
-
if (!
|
|
144
|
+
if (!connectionRef.current) {
|
|
129
145
|
return;
|
|
130
146
|
}
|
|
131
|
-
|
|
147
|
+
OnyxConnectionManager_1.default.disconnect(connectionRef.current);
|
|
132
148
|
isFirstConnectionRef.current = false;
|
|
133
149
|
};
|
|
134
|
-
}, [key, options === null || options === void 0 ? void 0 : options.initWithStoredValues]);
|
|
135
|
-
// Mimics withOnyx's checkEvictableKeys() behavior.
|
|
150
|
+
}, [key, options === null || options === void 0 ? void 0 : options.initWithStoredValues, checkEvictableKey]);
|
|
136
151
|
(0, react_1.useEffect)(() => {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
if (!OnyxUtils_1.default.isSafeEvictionKey(key)) {
|
|
141
|
-
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: []}).`);
|
|
142
|
-
}
|
|
143
|
-
if (options.canEvict) {
|
|
144
|
-
OnyxUtils_1.default.removeFromEvictionBlockList(key, connectionIDRef.current);
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
OnyxUtils_1.default.addToEvictionBlockList(key, connectionIDRef.current);
|
|
148
|
-
}
|
|
149
|
-
}, [key, options === null || options === void 0 ? void 0 : options.canEvict]);
|
|
152
|
+
checkEvictableKey();
|
|
153
|
+
}, [checkEvictableKey]);
|
|
150
154
|
const result = (0, react_1.useSyncExternalStore)(subscribe, getSnapshot);
|
|
151
155
|
return result;
|
|
152
156
|
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { OnyxInput, OnyxKey } from './types';
|
|
1
|
+
import type { ConnectOptions, OnyxInput, OnyxKey } from './types';
|
|
2
2
|
type EmptyObject = Record<string, never>;
|
|
3
3
|
type EmptyValue = EmptyObject | null | undefined;
|
|
4
4
|
/** Checks whether the given object is an object and not null/undefined. */
|
|
@@ -37,6 +37,10 @@ declare function pick<TValue>(obj: Record<string, TValue>, condition: string | s
|
|
|
37
37
|
* @returns The object containing only the remaining entries after omission.
|
|
38
38
|
*/
|
|
39
39
|
declare function omit<TValue>(obj: Record<string, TValue>, condition: string | string[] | ((entry: [string, TValue]) => boolean)): Record<string, TValue>;
|
|
40
|
+
/**
|
|
41
|
+
* Whether the connect options has the `withOnyxInstance` property defined, that is, it's used by the `withOnyx()` HOC.
|
|
42
|
+
*/
|
|
43
|
+
declare function hasWithOnyxInstance<TKey extends OnyxKey>(mapping: ConnectOptions<TKey>): unknown;
|
|
40
44
|
declare const _default: {
|
|
41
45
|
isEmptyObject: typeof isEmptyObject;
|
|
42
46
|
fastMerge: typeof fastMerge;
|
|
@@ -45,5 +49,6 @@ declare const _default: {
|
|
|
45
49
|
checkCompatibilityWithExistingValue: typeof checkCompatibilityWithExistingValue;
|
|
46
50
|
pick: typeof pick;
|
|
47
51
|
omit: typeof omit;
|
|
52
|
+
hasWithOnyxInstance: typeof hasWithOnyxInstance;
|
|
48
53
|
};
|
|
49
54
|
export default _default;
|
package/dist/utils.js
CHANGED
|
@@ -170,4 +170,10 @@ function pick(obj, condition) {
|
|
|
170
170
|
function omit(obj, condition) {
|
|
171
171
|
return filterObject(obj, condition, false);
|
|
172
172
|
}
|
|
173
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Whether the connect options has the `withOnyxInstance` property defined, that is, it's used by the `withOnyx()` HOC.
|
|
175
|
+
*/
|
|
176
|
+
function hasWithOnyxInstance(mapping) {
|
|
177
|
+
return 'withOnyxInstance' in mapping && mapping.withOnyxInstance;
|
|
178
|
+
}
|
|
179
|
+
exports.default = { isEmptyObject, fastMerge, formatActionName, removeNestedNullValues, checkCompatibilityWithExistingValue, pick, omit, hasWithOnyxInstance };
|
package/dist/withOnyx/index.js
CHANGED
|
@@ -32,11 +32,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
32
32
|
* will automatically change to reflect the new data.
|
|
33
33
|
*/
|
|
34
34
|
const react_1 = __importDefault(require("react"));
|
|
35
|
-
const Onyx_1 = __importDefault(require("../Onyx"));
|
|
36
35
|
const OnyxUtils_1 = __importDefault(require("../OnyxUtils"));
|
|
37
36
|
const Str = __importStar(require("../Str"));
|
|
38
37
|
const utils_1 = __importDefault(require("../utils"));
|
|
39
38
|
const OnyxCache_1 = __importDefault(require("../OnyxCache"));
|
|
39
|
+
const OnyxConnectionManager_1 = __importDefault(require("../OnyxConnectionManager"));
|
|
40
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
|
|
41
41
|
// if a key has changed, it's a good idea to skip looking at these properties since they would have unexpected results.
|
|
42
42
|
const mappingPropertiesToIgnoreChangesTo = ['initialValue', 'allowStaleData'];
|
|
@@ -80,9 +80,9 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
|
|
|
80
80
|
this.shouldDelayUpdates = shouldDelayUpdates;
|
|
81
81
|
this.setWithOnyxState = this.setWithOnyxState.bind(this);
|
|
82
82
|
this.flushPendingSetStates = this.flushPendingSetStates.bind(this);
|
|
83
|
-
// This stores all the Onyx
|
|
84
|
-
// disconnected. It is a key value store with the format {[mapping.key]:
|
|
85
|
-
this.
|
|
83
|
+
// This stores all the Onyx connections to be used when the component unmounts so everything can be
|
|
84
|
+
// disconnected. It is a key value store with the format {[mapping.key]: connection metadata object}.
|
|
85
|
+
this.activeConnections = {};
|
|
86
86
|
const cachedState = mapOnyxToStateEntries(mapOnyxToState).reduce((resultObj, [propName, mapping]) => {
|
|
87
87
|
const key = Str.result(mapping.key, props);
|
|
88
88
|
let value = OnyxUtils_1.default.tryGetCachedValue(key, mapping);
|
|
@@ -150,8 +150,8 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
|
|
|
150
150
|
const previousKey = isFirstTimeUpdatingAfterLoading ? mapping.previousKey : Str.result(mapping.key, Object.assign(Object.assign({}, prevProps), prevOnyxDataFromState));
|
|
151
151
|
const newKey = Str.result(mapping.key, Object.assign(Object.assign({}, this.props), onyxDataFromState));
|
|
152
152
|
if (previousKey !== newKey) {
|
|
153
|
-
|
|
154
|
-
delete this.
|
|
153
|
+
OnyxConnectionManager_1.default.disconnect(this.activeConnections[previousKey]);
|
|
154
|
+
delete this.activeConnections[previousKey];
|
|
155
155
|
this.connectMappingToOnyx(mapping, propName, newKey);
|
|
156
156
|
}
|
|
157
157
|
});
|
|
@@ -161,7 +161,7 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
|
|
|
161
161
|
// Disconnect everything from Onyx
|
|
162
162
|
mapOnyxToStateEntries(mapOnyxToState).forEach(([, mapping]) => {
|
|
163
163
|
const key = Str.result(mapping.key, Object.assign(Object.assign({}, this.props), getOnyxDataFromState(this.state, mapOnyxToState)));
|
|
164
|
-
|
|
164
|
+
OnyxConnectionManager_1.default.disconnect(this.activeConnections[key]);
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
167
|
setStateProxy(modifier) {
|
|
@@ -261,10 +261,10 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
|
|
|
261
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: []}).`);
|
|
262
262
|
}
|
|
263
263
|
if (canEvict) {
|
|
264
|
-
|
|
264
|
+
OnyxConnectionManager_1.default.removeFromEvictionBlockList(this.activeConnections[key]);
|
|
265
265
|
}
|
|
266
266
|
else {
|
|
267
|
-
|
|
267
|
+
OnyxConnectionManager_1.default.addToEvictionBlockList(this.activeConnections[key]);
|
|
268
268
|
}
|
|
269
269
|
});
|
|
270
270
|
}
|
|
@@ -285,7 +285,7 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
|
|
|
285
285
|
// eslint-disable-next-line no-param-reassign
|
|
286
286
|
onyxMapping.previousKey = key;
|
|
287
287
|
// eslint-disable-next-line rulesdir/prefer-onyx-connect-in-libs
|
|
288
|
-
this.
|
|
288
|
+
this.activeConnections[key] = OnyxConnectionManager_1.default.connect(Object.assign(Object.assign({}, mapping), { key, statePropertyName: statePropertyName, withOnyxInstance: this, displayName }));
|
|
289
289
|
}
|
|
290
290
|
flushPendingSetStates() {
|
|
291
291
|
if (!this.shouldDelayUpdates) {
|
package/dist/withOnyx/types.d.ts
CHANGED
|
@@ -92,7 +92,7 @@ type Mapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TO
|
|
|
92
92
|
* Represents a superset of `Mapping` type with internal properties included.
|
|
93
93
|
*/
|
|
94
94
|
type WithOnyxMapping<TComponentProps, TOnyxProps> = Mapping<TComponentProps, TOnyxProps, keyof TOnyxProps, OnyxKey> & {
|
|
95
|
-
|
|
95
|
+
subscriptionID: number;
|
|
96
96
|
previousKey?: OnyxKey;
|
|
97
97
|
};
|
|
98
98
|
/**
|