react-native-onyx 2.0.141 → 3.0.2
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 +2 -8
- package/README.md +2 -62
- package/dist/Onyx.d.ts +7 -13
- package/dist/Onyx.js +8 -20
- package/dist/OnyxConnectionManager.d.ts +1 -1
- package/dist/OnyxConnectionManager.js +14 -22
- package/dist/OnyxUtils.d.ts +10 -13
- package/dist/OnyxUtils.js +28 -247
- package/dist/index.d.ts +2 -4
- package/dist/index.js +1 -3
- package/dist/storage/providers/IDBKeyValProvider/createStore.d.ts +3 -0
- package/dist/storage/providers/IDBKeyValProvider/createStore.js +52 -0
- package/dist/storage/providers/{IDBKeyValProvider.d.ts → IDBKeyValProvider/index.d.ts} +1 -1
- package/dist/storage/providers/{IDBKeyValProvider.js → IDBKeyValProvider/index.js} +7 -3
- package/dist/types.d.ts +6 -75
- package/dist/useOnyx.js +0 -1
- package/dist/utils.d.ts +1 -6
- package/dist/utils.js +0 -7
- package/package.json +1 -1
- package/dist/PerformanceUtils.d.ts +0 -8
- package/dist/PerformanceUtils.js +0 -52
- package/dist/withOnyx/index.d.ts +0 -15
- package/dist/withOnyx/index.js +0 -322
- package/dist/withOnyx/types.d.ts +0 -129
- package/dist/withOnyx/types.js +0 -2
package/API.md
CHANGED
|
@@ -81,10 +81,7 @@ This method will be deprecated soon. Please use `Onyx.connectWithoutView()` inst
|
|
|
81
81
|
| connectOptions.key | The Onyx key to subscribe to. |
|
|
82
82
|
| connectOptions.callback | A function that will be called when the Onyx data we are subscribed changes. |
|
|
83
83
|
| connectOptions.waitForCollectionCallback | If set to `true`, it will return the entire collection to the callback as a single object. |
|
|
84
|
-
| connectOptions.
|
|
85
|
-
| connectOptions.statePropertyName | The name of the component's prop that is connected to the Onyx key. **Only used inside `withOnyx()` HOC.** |
|
|
86
|
-
| connectOptions.displayName | The component's display name. **Only used inside `withOnyx()` HOC.** |
|
|
87
|
-
| connectOptions.selector | This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook or `withOnyx()` HOC.** Using this setting on `useOnyx()` or `withOnyx()` can have very positive performance benefits because the component will only re-render when the subset of data changes. Otherwise, any change of data on any property would normally cause the component to re-render (and that can be expensive from a performance standpoint). |
|
|
84
|
+
| connectOptions.selector | This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook.** Using this setting on `useOnyx()` can have very positive performance benefits because the component will only re-render when the subset of data changes. Otherwise, any change of data on any property would normally cause the component to re-render (and that can be expensive from a performance standpoint). |
|
|
88
85
|
|
|
89
86
|
**Example**
|
|
90
87
|
```ts
|
|
@@ -107,10 +104,7 @@ Connects to an Onyx key given the options passed and listens to its changes.
|
|
|
107
104
|
| connectOptions.key | The Onyx key to subscribe to. |
|
|
108
105
|
| connectOptions.callback | A function that will be called when the Onyx data we are subscribed changes. |
|
|
109
106
|
| connectOptions.waitForCollectionCallback | If set to `true`, it will return the entire collection to the callback as a single object. |
|
|
110
|
-
| connectOptions.
|
|
111
|
-
| connectOptions.statePropertyName | The name of the component's prop that is connected to the Onyx key. **Only used inside `withOnyx()` HOC.** |
|
|
112
|
-
| connectOptions.displayName | The component's display name. **Only used inside `withOnyx()` HOC.** |
|
|
113
|
-
| connectOptions.selector | This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook or `withOnyx()` HOC.** Using this setting on `useOnyx()` or `withOnyx()` can have very positive performance benefits because the component will only re-render when the subset of data changes. Otherwise, any change of data on any property would normally cause the component to re-render (and that can be expensive from a performance standpoint). |
|
|
107
|
+
| connectOptions.selector | This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook.** Using this setting on `useOnyx()` can have very positive performance benefits because the component will only re-render when the subset of data changes. Otherwise, any change of data on any property would normally cause the component to re-render (and that can be expensive from a performance standpoint). |
|
|
114
108
|
|
|
115
109
|
**Example**
|
|
116
110
|
```ts
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Awesome persistent storage solution wrapped in a Pub/Sub library.
|
|
|
9
9
|
- Onyx allows other code to subscribe to changes in data, and then publishes change events whenever data is changed
|
|
10
10
|
- Anything needing to read Onyx data needs to:
|
|
11
11
|
1. Know what key the data is stored in (for web, you can find this by looking in the JS console > Application > local storage)
|
|
12
|
-
2. Subscribe to changes of the data for a particular key or set of keys. React function components use the `useOnyx()` hook
|
|
12
|
+
2. Subscribe to changes of the data for a particular key or set of keys. React function components use the `useOnyx()` hook and non-React libs use `Onyx.connect()`.
|
|
13
13
|
3. Get initialized with the current value of that key from persistent storage (Onyx does this by calling `setState()` or triggering the `callback` with the values currently on disk as part of the connection process)
|
|
14
14
|
- Subscribing to Onyx keys is done using a constant defined in `ONYXKEYS`. Each Onyx key represents either a collection of items or a specific entry in storage. For example, since all reports are stored as individual keys like `report_1234`, if code needs to know about all the reports (e.g. display a list of them in the nav menu), then it would subscribe to the key `ONYXKEYS.COLLECTION.REPORT`.
|
|
15
15
|
|
|
@@ -136,7 +136,7 @@ To teardown the subscription call `Onyx.disconnect()` with the `connectionID` re
|
|
|
136
136
|
Onyx.disconnect(connectionID);
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
We can also access values inside React function components via the `useOnyx()` [hook](https://react.dev/reference/react/hooks)
|
|
139
|
+
We can also access values inside React function components via the `useOnyx()` [hook](https://react.dev/reference/react/hooks). When the data changes the component will re-render.
|
|
140
140
|
|
|
141
141
|
```javascript
|
|
142
142
|
import React from 'react';
|
|
@@ -168,48 +168,6 @@ if (reportsResult.status === 'loading' || sessionResult.status === 'loading') {
|
|
|
168
168
|
// rest of the component's code.
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
-
> [!warning]
|
|
172
|
-
> ## Deprecated Note
|
|
173
|
-
> Please note that the `withOnyx()` Higher Order Component (HOC) is now considered deprecated. Use `useOnyx()` hook instead.
|
|
174
|
-
|
|
175
|
-
```javascript
|
|
176
|
-
import React from 'react';
|
|
177
|
-
import {withOnyx} from 'react-native-onyx';
|
|
178
|
-
|
|
179
|
-
const App = ({session}) => (
|
|
180
|
-
<View>
|
|
181
|
-
{session.token ? <Text>Logged in</Text> : <Text>Logged out</Text> }
|
|
182
|
-
</View>
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
export default withOnyx({
|
|
186
|
-
session: {
|
|
187
|
-
key: ONYXKEYS.SESSION,
|
|
188
|
-
},
|
|
189
|
-
})(App);
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
Differently from `useOnyx()`, `withOnyx()` will delay the rendering of the wrapped component until all keys/entities have been fetched and passed to the component, this can be convenient for simple cases. This however, can really delay your application if many entities are connected to the same component.
|
|
193
|
-
|
|
194
|
-
Additionally, if your component has many keys/entities when your component will mount but will receive many updates as data is fetched from DB and passed down to it, as every key that gets fetched will trigger a `setState` on the `withOnyx` HOC. This might cause re-renders on the initial mounting, preventing the component from mounting/rendering in reasonable time, making your app feel slow and even delaying animations.
|
|
195
|
-
|
|
196
|
-
You can workaround this by passing an additional object with the `shouldDelayUpdates` property set to true. Onyx will then put all the updates in a queue until you decide when then should be applied, the component will receive a function `markReadyForHydration`. A good place to call this function is on the `onLayout` method, which gets triggered after your component has been rendered.
|
|
197
|
-
|
|
198
|
-
```javascript
|
|
199
|
-
const App = ({session, markReadyForHydration}) => (
|
|
200
|
-
<View onLayout={() => markReadyForHydration()}>
|
|
201
|
-
{session.token ? <Text>Logged in</Text> : <Text>Logged out</Text> }
|
|
202
|
-
</View>
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
// Second argument to funciton is `shouldDelayUpdates`
|
|
206
|
-
export default withOnyx({
|
|
207
|
-
session: {
|
|
208
|
-
key: ONYXKEYS.SESSION
|
|
209
|
-
},
|
|
210
|
-
}, true)(App);
|
|
211
|
-
```
|
|
212
|
-
|
|
213
171
|
### Dependent Onyx Keys and useOnyx()
|
|
214
172
|
Some components need to subscribe to multiple Onyx keys at once and sometimes, one key might rely on the data from another key. This is similar to a JOIN in SQL.
|
|
215
173
|
|
|
@@ -246,24 +204,6 @@ export default App;
|
|
|
246
204
|
|
|
247
205
|
* It is VERY important to NOT use empty string default values like `report.policyID || ''`. This results in the key returned to `useOnyx` as `policies_`, which subscribes to the ENTIRE POLICY COLLECTION and is most assuredly not what you were intending. You can use a default of `0` (as long as you are reasonably sure that there is never a policyID=0). This allows Onyx to return `undefined` as the value of the policy key, which is handled by `useOnyx` appropriately.
|
|
248
206
|
|
|
249
|
-
**Detailed explanation of how this is handled and rendered with `withOnyx` HOC:**
|
|
250
|
-
1. The component mounts with a `reportID={1234}` prop
|
|
251
|
-
2. `withOnyx` evaluates the mapping
|
|
252
|
-
3. `withOnyx` connects to the key `reports_1234` because of the prop passed to the component
|
|
253
|
-
3. `withOnyx` connects to the key `policies_undefined` because `report` doesn't exist in the props yet, so the `policyID` defaults to `undefined`. * (see note below)
|
|
254
|
-
4. Onyx reads the data and updates the state of `withOnyx` with:
|
|
255
|
-
- `report={{reportID: 1234, policyID: 1, ... the rest of the object ...}}`
|
|
256
|
-
- `policy={undefined}` (since there is no policy with ID `undefined`)
|
|
257
|
-
5. There is still an `undefined` key in the mapping, so Onyx reads the data again
|
|
258
|
-
6. This time `withOnyx` connects to the key `policies_1` because the `report` object exists in the component's state and it has a `policyID: 1`
|
|
259
|
-
7. Onyx reads the data and updates the state of withOnyx with:
|
|
260
|
-
- `policy={{policyID: 1, ... the rest of the object ...}`
|
|
261
|
-
8. Now all mappings have values that are defined (not undefined) and the component is rendered with all necessary data
|
|
262
|
-
|
|
263
|
-
* It is VERY important to NOT use empty string default values like `report.policyID || ''`. This results in the key returned to `withOnyx` as `policies_` which subscribes to the ENTIRE POLICY COLLECTION and is most assuredly not what you were intending. You can use a default of `0` (as long as you are reasonably sure that there is never a policyID=0). This allows Onyx to return `undefined` as the value of the policy key, which is handled by `withOnyx` appropriately.
|
|
264
|
-
|
|
265
|
-
DO NOT use more than one `withOnyx` component at a time. It adds overhead and prevents some optimizations like batched rendering from working to its full potential.
|
|
266
|
-
|
|
267
207
|
It's also beneficial to use a [selector](https://github.com/Expensify/react-native-onyx/blob/main/API.md#connectmapping--number) with the mapping in case you need to grab a single item in a collection (like a single report action).
|
|
268
208
|
|
|
269
209
|
### useOnyx()'s `canBeMissing` option
|
package/dist/Onyx.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as Logger from './Logger';
|
|
2
|
-
import type { CollectionKeyBase, ConnectOptions, InitOptions,
|
|
2
|
+
import type { CollectionKeyBase, ConnectOptions, InitOptions, OnyxKey, OnyxMergeCollectionInput, OnyxMergeInput, OnyxMultiSetInput, OnyxSetInput, OnyxUpdate, SetOptions } from './types';
|
|
3
3
|
import type { Connection } from './OnyxConnectionManager';
|
|
4
4
|
/** Initialize the store with actions and listening for storage events */
|
|
5
|
-
declare function init({ keys, initialKeyStates, evictableKeys, maxCachedKeysCount, shouldSyncMultipleInstances,
|
|
5
|
+
declare function init({ keys, initialKeyStates, evictableKeys, maxCachedKeysCount, shouldSyncMultipleInstances, enablePerformanceMetrics, skippableCollectionMemberIDs, }: InitOptions): void;
|
|
6
6
|
/**
|
|
7
7
|
* Connects to an Onyx key given the options passed and listens to its changes.
|
|
8
8
|
* This method will be deprecated soon. Please use `Onyx.connectWithoutView()` instead.
|
|
@@ -19,11 +19,8 @@ declare function init({ keys, initialKeyStates, evictableKeys, maxCachedKeysCoun
|
|
|
19
19
|
* @param connectOptions.key The Onyx key to subscribe to.
|
|
20
20
|
* @param connectOptions.callback A function that will be called when the Onyx data we are subscribed changes.
|
|
21
21
|
* @param connectOptions.waitForCollectionCallback If set to `true`, it will return the entire collection to the callback as a single object.
|
|
22
|
-
* @param connectOptions.
|
|
23
|
-
*
|
|
24
|
-
* @param connectOptions.displayName The component's display name. **Only used inside `withOnyx()` HOC.**
|
|
25
|
-
* @param connectOptions.selector This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook or `withOnyx()` HOC.**
|
|
26
|
-
* Using this setting on `useOnyx()` or `withOnyx()` can have very positive performance benefits because the component will only re-render
|
|
22
|
+
* @param connectOptions.selector This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook.**
|
|
23
|
+
* Using this setting on `useOnyx()` can have very positive performance benefits because the component will only re-render
|
|
27
24
|
* when the subset of data changes. Otherwise, any change of data on any property would normally
|
|
28
25
|
* cause the component to re-render (and that can be expensive from a performance standpoint).
|
|
29
26
|
* @returns The connection object to use when calling `Onyx.disconnect()`.
|
|
@@ -44,11 +41,8 @@ declare function connect<TKey extends OnyxKey>(connectOptions: ConnectOptions<TK
|
|
|
44
41
|
* @param connectOptions.key The Onyx key to subscribe to.
|
|
45
42
|
* @param connectOptions.callback A function that will be called when the Onyx data we are subscribed changes.
|
|
46
43
|
* @param connectOptions.waitForCollectionCallback If set to `true`, it will return the entire collection to the callback as a single object.
|
|
47
|
-
* @param connectOptions.
|
|
48
|
-
*
|
|
49
|
-
* @param connectOptions.displayName The component's display name. **Only used inside `withOnyx()` HOC.**
|
|
50
|
-
* @param connectOptions.selector This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook or `withOnyx()` HOC.**
|
|
51
|
-
* Using this setting on `useOnyx()` or `withOnyx()` can have very positive performance benefits because the component will only re-render
|
|
44
|
+
* @param connectOptions.selector This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook.**
|
|
45
|
+
* Using this setting on `useOnyx()` can have very positive performance benefits because the component will only re-render
|
|
52
46
|
* when the subset of data changes. Otherwise, any change of data on any property would normally
|
|
53
47
|
* cause the component to re-render (and that can be expensive from a performance standpoint).
|
|
54
48
|
* @returns The connection object to use when calling `Onyx.disconnect()`.
|
|
@@ -183,4 +177,4 @@ declare const Onyx: {
|
|
|
183
177
|
registerLogger: typeof Logger.registerLogger;
|
|
184
178
|
};
|
|
185
179
|
export default Onyx;
|
|
186
|
-
export type { OnyxUpdate,
|
|
180
|
+
export type { OnyxUpdate, ConnectOptions, SetOptions };
|
package/dist/Onyx.js
CHANGED
|
@@ -38,7 +38,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
const Logger = __importStar(require("./Logger"));
|
|
40
40
|
const OnyxCache_1 = __importStar(require("./OnyxCache"));
|
|
41
|
-
const PerformanceUtils = __importStar(require("./PerformanceUtils"));
|
|
42
41
|
const storage_1 = __importDefault(require("./storage"));
|
|
43
42
|
const utils_1 = __importDefault(require("./utils"));
|
|
44
43
|
const DevTools_1 = __importDefault(require("./DevTools"));
|
|
@@ -49,7 +48,7 @@ const GlobalSettings = __importStar(require("./GlobalSettings"));
|
|
|
49
48
|
const metrics_1 = __importDefault(require("./metrics"));
|
|
50
49
|
const OnyxMerge_1 = __importDefault(require("./OnyxMerge"));
|
|
51
50
|
/** Initialize the store with actions and listening for storage events */
|
|
52
|
-
function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedKeysCount = 1000, shouldSyncMultipleInstances = !!global.localStorage,
|
|
51
|
+
function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedKeysCount = 1000, shouldSyncMultipleInstances = !!global.localStorage, enablePerformanceMetrics = false, skippableCollectionMemberIDs = [], }) {
|
|
53
52
|
var _a;
|
|
54
53
|
if (enablePerformanceMetrics) {
|
|
55
54
|
GlobalSettings.setPerformanceMetricsEnabled(true);
|
|
@@ -59,14 +58,10 @@ function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedK
|
|
|
59
58
|
OnyxUtils_1.default.setSkippableCollectionMemberIDs(new Set(skippableCollectionMemberIDs));
|
|
60
59
|
if (shouldSyncMultipleInstances) {
|
|
61
60
|
(_a = storage_1.default.keepInstancesSync) === null || _a === void 0 ? void 0 : _a.call(storage_1.default, (key, value) => {
|
|
62
|
-
const prevValue = OnyxCache_1.default.get(key, false);
|
|
63
61
|
OnyxCache_1.default.set(key, value);
|
|
64
|
-
OnyxUtils_1.default.keyChanged(key, value
|
|
62
|
+
OnyxUtils_1.default.keyChanged(key, value);
|
|
65
63
|
});
|
|
66
64
|
}
|
|
67
|
-
if (debugSetState) {
|
|
68
|
-
PerformanceUtils.setShouldDebugSetState(true);
|
|
69
|
-
}
|
|
70
65
|
if (maxCachedKeysCount > 0) {
|
|
71
66
|
OnyxCache_1.default.setRecentKeysLimit(maxCachedKeysCount);
|
|
72
67
|
}
|
|
@@ -90,11 +85,8 @@ function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedK
|
|
|
90
85
|
* @param connectOptions.key The Onyx key to subscribe to.
|
|
91
86
|
* @param connectOptions.callback A function that will be called when the Onyx data we are subscribed changes.
|
|
92
87
|
* @param connectOptions.waitForCollectionCallback If set to `true`, it will return the entire collection to the callback as a single object.
|
|
93
|
-
* @param connectOptions.
|
|
94
|
-
*
|
|
95
|
-
* @param connectOptions.displayName The component's display name. **Only used inside `withOnyx()` HOC.**
|
|
96
|
-
* @param connectOptions.selector This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook or `withOnyx()` HOC.**
|
|
97
|
-
* Using this setting on `useOnyx()` or `withOnyx()` can have very positive performance benefits because the component will only re-render
|
|
88
|
+
* @param connectOptions.selector This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook.**
|
|
89
|
+
* Using this setting on `useOnyx()` can have very positive performance benefits because the component will only re-render
|
|
98
90
|
* when the subset of data changes. Otherwise, any change of data on any property would normally
|
|
99
91
|
* cause the component to re-render (and that can be expensive from a performance standpoint).
|
|
100
92
|
* @returns The connection object to use when calling `Onyx.disconnect()`.
|
|
@@ -117,11 +109,8 @@ function connect(connectOptions) {
|
|
|
117
109
|
* @param connectOptions.key The Onyx key to subscribe to.
|
|
118
110
|
* @param connectOptions.callback A function that will be called when the Onyx data we are subscribed changes.
|
|
119
111
|
* @param connectOptions.waitForCollectionCallback If set to `true`, it will return the entire collection to the callback as a single object.
|
|
120
|
-
* @param connectOptions.
|
|
121
|
-
*
|
|
122
|
-
* @param connectOptions.displayName The component's display name. **Only used inside `withOnyx()` HOC.**
|
|
123
|
-
* @param connectOptions.selector This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook or `withOnyx()` HOC.**
|
|
124
|
-
* Using this setting on `useOnyx()` or `withOnyx()` can have very positive performance benefits because the component will only re-render
|
|
112
|
+
* @param connectOptions.selector This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook.**
|
|
113
|
+
* Using this setting on `useOnyx()` can have very positive performance benefits because the component will only re-render
|
|
125
114
|
* when the subset of data changes. Otherwise, any change of data on any property would normally
|
|
126
115
|
* cause the component to re-render (and that can be expensive from a performance standpoint).
|
|
127
116
|
* @returns The connection object to use when calling `Onyx.disconnect()`.
|
|
@@ -240,7 +229,6 @@ function multiSet(data) {
|
|
|
240
229
|
}
|
|
241
230
|
const keyValuePairsToSet = OnyxUtils_1.default.prepareKeyValuePairsForStorage(newData, true);
|
|
242
231
|
const updatePromises = keyValuePairsToSet.map(([key, value]) => {
|
|
243
|
-
const prevValue = OnyxCache_1.default.get(key, false);
|
|
244
232
|
// When we use multiSet to set a key we want to clear the current delta changes from Onyx.merge that were queued
|
|
245
233
|
// before the value was set. If Onyx.merge is currently reading the old value from storage, it will then not apply the changes.
|
|
246
234
|
if (OnyxUtils_1.default.hasPendingMergeForKey(key)) {
|
|
@@ -248,7 +236,7 @@ function multiSet(data) {
|
|
|
248
236
|
}
|
|
249
237
|
// Update cache and optimistically inform subscribers on the next tick
|
|
250
238
|
OnyxCache_1.default.set(key, value);
|
|
251
|
-
return OnyxUtils_1.default.scheduleSubscriberUpdate(key, value
|
|
239
|
+
return OnyxUtils_1.default.scheduleSubscriberUpdate(key, value);
|
|
252
240
|
});
|
|
253
241
|
return storage_1.default.multiSet(keyValuePairsToSet)
|
|
254
242
|
.catch((error) => OnyxUtils_1.default.evictStorageAndRetry(error, multiSet, newData))
|
|
@@ -435,7 +423,7 @@ function clear(keysToPreserve = []) {
|
|
|
435
423
|
const updatePromises = [];
|
|
436
424
|
// Notify the subscribers for each key/value group so they can receive the new values
|
|
437
425
|
Object.entries(keyValuesToResetIndividually).forEach(([key, value]) => {
|
|
438
|
-
updatePromises.push(OnyxUtils_1.default.scheduleSubscriberUpdate(key, value
|
|
426
|
+
updatePromises.push(OnyxUtils_1.default.scheduleSubscriberUpdate(key, value));
|
|
439
427
|
});
|
|
440
428
|
Object.entries(keyValuesToResetAsCollection).forEach(([key, value]) => {
|
|
441
429
|
updatePromises.push(OnyxUtils_1.default.scheduleNotifyCollectionSubscribers(key, value));
|
|
@@ -14,7 +14,7 @@ type Connection = {
|
|
|
14
14
|
callbackID: string;
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
|
-
* Manages Onyx connections of `Onyx.connect()
|
|
17
|
+
* Manages Onyx connections of `Onyx.connect()` and `useOnyx()` subscribers.
|
|
18
18
|
*/
|
|
19
19
|
declare class OnyxConnectionManager {
|
|
20
20
|
/**
|
|
@@ -40,11 +40,10 @@ const bindAll_1 = __importDefault(require("lodash/bindAll"));
|
|
|
40
40
|
const Logger = __importStar(require("./Logger"));
|
|
41
41
|
const OnyxUtils_1 = __importDefault(require("./OnyxUtils"));
|
|
42
42
|
const Str = __importStar(require("./Str"));
|
|
43
|
-
const utils_1 = __importDefault(require("./utils"));
|
|
44
43
|
const OnyxCache_1 = __importDefault(require("./OnyxCache"));
|
|
45
44
|
const OnyxSnapshotCache_1 = __importDefault(require("./OnyxSnapshotCache"));
|
|
46
45
|
/**
|
|
47
|
-
* Manages Onyx connections of `Onyx.connect()
|
|
46
|
+
* Manages Onyx connections of `Onyx.connect()` and `useOnyx()` subscribers.
|
|
48
47
|
*/
|
|
49
48
|
class OnyxConnectionManager {
|
|
50
49
|
constructor() {
|
|
@@ -70,11 +69,9 @@ class OnyxConnectionManager {
|
|
|
70
69
|
// - `initWithStoredValues` is `false`. This flag changes the subscription flow when set to `false`, so the connection can't be reused.
|
|
71
70
|
// - `key` is a collection key AND `waitForCollectionCallback` is `undefined/false`. This combination needs a new connection at every subscription
|
|
72
71
|
// in order to send all the collection entries, so the connection can't be reused.
|
|
73
|
-
// - `withOnyxInstance` is defined inside `connectOptions`. That means the subscriber is a `withOnyx` HOC and therefore doesn't support connection reuse.
|
|
74
72
|
if (reuseConnection === false ||
|
|
75
73
|
initWithStoredValues === false ||
|
|
76
|
-
(
|
|
77
|
-
utils_1.default.hasWithOnyxInstance(connectOptions)) {
|
|
74
|
+
(OnyxUtils_1.default.isCollectionKey(key) && (waitForCollectionCallback === undefined || waitForCollectionCallback === false))) {
|
|
78
75
|
suffix += `,uniqueID=${Str.guid()}`;
|
|
79
76
|
}
|
|
80
77
|
return `onyxKey=${key},initWithStoredValues=${initWithStoredValues !== null && initWithStoredValues !== void 0 ? initWithStoredValues : true},waitForCollectionCallback=${waitForCollectionCallback !== null && waitForCollectionCallback !== void 0 ? waitForCollectionCallback : false}${suffix}`;
|
|
@@ -106,23 +103,18 @@ class OnyxConnectionManager {
|
|
|
106
103
|
const callbackID = String(this.lastCallbackID++);
|
|
107
104
|
// If there is no connection yet for that connection ID, we create a new one.
|
|
108
105
|
if (!connectionMetadata) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
createdConnection.sourceValue = sourceValue;
|
|
122
|
-
this.fireCallbacks(connectionID);
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
}
|
|
106
|
+
const callback = (value, key, sourceValue) => {
|
|
107
|
+
const createdConnection = this.connectionsMap.get(connectionID);
|
|
108
|
+
if (createdConnection) {
|
|
109
|
+
// We signal that the first connection was made and now any new subscribers
|
|
110
|
+
// can fire their callbacks immediately with the cached value when connecting.
|
|
111
|
+
createdConnection.isConnectionMade = true;
|
|
112
|
+
createdConnection.cachedCallbackValue = value;
|
|
113
|
+
createdConnection.cachedCallbackKey = key;
|
|
114
|
+
createdConnection.sourceValue = sourceValue;
|
|
115
|
+
this.fireCallbacks(connectionID);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
126
118
|
subscriptionID = OnyxUtils_1.default.subscribeToKey(Object.assign(Object.assign({}, connectOptions), { callback: callback }));
|
|
127
119
|
connectionMetadata = {
|
|
128
120
|
subscriptionID,
|
package/dist/OnyxUtils.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { ValueOf } from 'type-fest';
|
|
2
2
|
import type Onyx from './Onyx';
|
|
3
|
-
import type { CollectionKey, CollectionKeyBase, ConnectOptions, DeepRecord, KeyValueMapping,
|
|
3
|
+
import type { CollectionKey, CollectionKeyBase, ConnectOptions, DeepRecord, KeyValueMapping, CallbackToStateMapping, MultiMergeReplaceNullPatches, OnyxCollection, OnyxEntry, OnyxInput, OnyxKey, OnyxMergeCollectionInput, OnyxUpdate, OnyxValue, Selector } from './types';
|
|
4
4
|
import type { FastMergeResult } from './utils';
|
|
5
|
-
import type { WithOnyxState } from './withOnyx/types';
|
|
6
5
|
import type { DeferredTask } from './createDeferredTask';
|
|
7
6
|
import type { StorageKeyValuePair } from './storage/providers/types';
|
|
8
7
|
declare const METHOD: {
|
|
@@ -70,7 +69,7 @@ declare function batchUpdates(updates: () => void): Promise<void>;
|
|
|
70
69
|
* and runs it through a reducer function to return a subset of the data according to a selector.
|
|
71
70
|
* The resulting collection will only contain items that are returned by the selector.
|
|
72
71
|
*/
|
|
73
|
-
declare function reduceCollectionWithSelector<TKey extends CollectionKeyBase,
|
|
72
|
+
declare function reduceCollectionWithSelector<TKey extends CollectionKeyBase, TReturn>(collection: OnyxCollection<KeyValueMapping[TKey]>, selector: Selector<TKey, TReturn>): Record<string, TReturn>;
|
|
74
73
|
/** Get some data from the store */
|
|
75
74
|
declare function get<TKey extends OnyxKey, TValue extends OnyxValue<TKey>>(key: TKey): Promise<TValue>;
|
|
76
75
|
declare function multiGet<TKey extends OnyxKey>(keys: CollectionKeyBase[]): Promise<Map<OnyxKey, OnyxValue<TKey>>>;
|
|
@@ -138,41 +137,39 @@ declare function getCollectionKey(key: CollectionKey): string;
|
|
|
138
137
|
* Tries to get a value from the cache. If the value is not present in cache it will return the default value or undefined.
|
|
139
138
|
* If the requested key is a collection, it will return an object with all the collection members.
|
|
140
139
|
*/
|
|
141
|
-
declare function tryGetCachedValue<TKey extends OnyxKey>(key: TKey
|
|
140
|
+
declare function tryGetCachedValue<TKey extends OnyxKey>(key: TKey): OnyxValue<OnyxKey>;
|
|
142
141
|
declare function getCachedCollection<TKey extends CollectionKeyBase>(collectionKey: TKey, collectionMemberKeys?: string[]): NonNullable<OnyxCollection<KeyValueMapping[TKey]>>;
|
|
143
142
|
/**
|
|
144
143
|
* When a collection of keys change, search for any callbacks matching the collection key and trigger those callbacks
|
|
145
144
|
*/
|
|
146
|
-
declare function keysChanged<TKey extends CollectionKeyBase>(collectionKey: TKey, partialCollection: OnyxCollection<KeyValueMapping[TKey]>, partialPreviousCollection: OnyxCollection<KeyValueMapping[TKey]> | undefined, notifyConnectSubscribers?: boolean
|
|
145
|
+
declare function keysChanged<TKey extends CollectionKeyBase>(collectionKey: TKey, partialCollection: OnyxCollection<KeyValueMapping[TKey]>, partialPreviousCollection: OnyxCollection<KeyValueMapping[TKey]> | undefined, notifyConnectSubscribers?: boolean): void;
|
|
147
146
|
/**
|
|
148
147
|
* When a key change happens, search for any callbacks matching the key or collection key and trigger those callbacks
|
|
149
148
|
*
|
|
150
149
|
* @example
|
|
151
150
|
* keyChanged(key, value, subscriber => subscriber.initWithStoredValues === false)
|
|
152
151
|
*/
|
|
153
|
-
declare function keyChanged<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>,
|
|
152
|
+
declare function keyChanged<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, canUpdateSubscriber?: (subscriber?: CallbackToStateMapping<OnyxKey>) => boolean, notifyConnectSubscribers?: boolean): void;
|
|
154
153
|
/**
|
|
155
|
-
* Sends the data obtained from the keys to the connection.
|
|
156
|
-
* - sets state on the withOnyxInstances
|
|
157
|
-
* - triggers the callback function
|
|
154
|
+
* Sends the data obtained from the keys to the connection.
|
|
158
155
|
*/
|
|
159
|
-
declare function sendDataToConnection<TKey extends OnyxKey>(mapping:
|
|
156
|
+
declare function sendDataToConnection<TKey extends OnyxKey>(mapping: CallbackToStateMapping<TKey>, value: OnyxValue<TKey> | null, matchedKey: TKey | undefined): void;
|
|
160
157
|
/**
|
|
161
158
|
* We check to see if this key is flagged as safe for eviction and add it to the recentlyAccessedKeys list so that when we
|
|
162
159
|
* run out of storage the least recently accessed key can be removed.
|
|
163
160
|
*/
|
|
164
|
-
declare function addKeyToRecentlyAccessedIfNeeded<TKey extends OnyxKey>(
|
|
161
|
+
declare function addKeyToRecentlyAccessedIfNeeded<TKey extends OnyxKey>(key: TKey): void;
|
|
165
162
|
/**
|
|
166
163
|
* Gets the data for a given an array of matching keys, combines them into an object, and sends the result back to the subscriber.
|
|
167
164
|
*/
|
|
168
|
-
declare function getCollectionDataAndSendAsObject<TKey extends OnyxKey>(matchingKeys: CollectionKeyBase[], mapping:
|
|
165
|
+
declare function getCollectionDataAndSendAsObject<TKey extends OnyxKey>(matchingKeys: CollectionKeyBase[], mapping: CallbackToStateMapping<TKey>): void;
|
|
169
166
|
/**
|
|
170
167
|
* Schedules an update that will be appended to the macro task queue (so it doesn't update the subscribers immediately).
|
|
171
168
|
*
|
|
172
169
|
* @example
|
|
173
170
|
* scheduleSubscriberUpdate(key, value, subscriber => subscriber.initWithStoredValues === false)
|
|
174
171
|
*/
|
|
175
|
-
declare function scheduleSubscriberUpdate<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>,
|
|
172
|
+
declare function scheduleSubscriberUpdate<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, canUpdateSubscriber?: (subscriber?: CallbackToStateMapping<OnyxKey>) => boolean): Promise<void>;
|
|
176
173
|
/**
|
|
177
174
|
* This method is similar to notifySubscribersOnNextTick but it is built for working specifically with collections
|
|
178
175
|
* so that keysChanged() is triggered for the collection and not keyChanged(). If this was not done, then the
|