react-native-onyx 1.0.59 → 1.0.60
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/lib/Logger.d.ts +13 -0
- package/lib/Onyx.d.ts +326 -0
- package/lib/index.d.ts +6 -0
- package/lib/types.d.ts +196 -0
- package/lib/withOnyx.d.ts +153 -0
- package/package.json +4 -1
package/lib/Logger.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare type LogData = {
|
|
2
|
+
message: string;
|
|
3
|
+
level: 'alert' | 'info';
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Register the logging callback
|
|
8
|
+
*
|
|
9
|
+
* @param callback
|
|
10
|
+
*/
|
|
11
|
+
declare function registerLogger(callback: (data: LogData) => void): void;
|
|
12
|
+
|
|
13
|
+
export {registerLogger};
|
package/lib/Onyx.d.ts
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import {Component} from 'react';
|
|
2
|
+
import {PartialDeep} from 'type-fest';
|
|
3
|
+
import * as Logger from './Logger';
|
|
4
|
+
import {
|
|
5
|
+
CollectionKey,
|
|
6
|
+
CollectionKeyBase,
|
|
7
|
+
DeepRecord,
|
|
8
|
+
KeyValueMapping,
|
|
9
|
+
OnyxCollection,
|
|
10
|
+
OnyxEntry,
|
|
11
|
+
OnyxKey,
|
|
12
|
+
} from './types';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Represents a mapping object where each `OnyxKey` maps to either a value of its corresponding type in `KeyValueMapping` or `null`.
|
|
16
|
+
*
|
|
17
|
+
* It's very similar to `KeyValueMapping` but this type accepts using `null` as well.
|
|
18
|
+
*/
|
|
19
|
+
type NullableKeyValueMapping = {
|
|
20
|
+
[TKey in OnyxKey]: OnyxEntry<KeyValueMapping[TKey]>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Represents the base options used in `Onyx.connect()` method.
|
|
25
|
+
*/
|
|
26
|
+
type BaseConnectOptions = {
|
|
27
|
+
statePropertyName?: string;
|
|
28
|
+
withOnyxInstance?: Component;
|
|
29
|
+
initWithStoredValues?: boolean;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Represents the options used in `Onyx.connect()` method.
|
|
34
|
+
* The type is built from `BaseConnectOptions` and extended to handle key/callback related options.
|
|
35
|
+
* It includes two different forms, depending on whether we are waiting for a collection callback or not.
|
|
36
|
+
*
|
|
37
|
+
* If `waitForCollectionCallback` is `true`, it expects `key` to be a Onyx collection key and `callback` will be triggered with the whole collection
|
|
38
|
+
* and will pass `value` as an `OnyxCollection`.
|
|
39
|
+
*
|
|
40
|
+
*
|
|
41
|
+
* 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
|
|
42
|
+
* and will pass `value` as an `OnyxEntry`.
|
|
43
|
+
*/
|
|
44
|
+
type ConnectOptions<TKey extends OnyxKey> = BaseConnectOptions &
|
|
45
|
+
(
|
|
46
|
+
| {
|
|
47
|
+
key: TKey extends CollectionKey ? TKey : never;
|
|
48
|
+
callback?: (value: OnyxCollection<KeyValueMapping[TKey]>, key?: TKey) => void;
|
|
49
|
+
waitForCollectionCallback: true;
|
|
50
|
+
}
|
|
51
|
+
| {
|
|
52
|
+
key: TKey;
|
|
53
|
+
callback?: (value: OnyxEntry<KeyValueMapping[TKey]>, key?: TKey) => void;
|
|
54
|
+
waitForCollectionCallback?: false;
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Represents a mapping between Onyx collection keys and their respective values.
|
|
60
|
+
*
|
|
61
|
+
* It helps to enforce that a Onyx collection key should not be without suffix (e.g. should always be of the form `${TKey}${string}`),
|
|
62
|
+
* and to map each Onyx collection key with suffix to a value of type `TValue`.
|
|
63
|
+
*
|
|
64
|
+
* Also, the `TMap` type is inferred automatically in `mergeCollection()` method and represents
|
|
65
|
+
* the object of collection keys/values specified in the second parameter of the method.
|
|
66
|
+
*/
|
|
67
|
+
type Collection<TKey extends CollectionKeyBase, TMap, TValue> = {
|
|
68
|
+
[MapK in keyof TMap]: MapK extends `${TKey}${string}`
|
|
69
|
+
? MapK extends `${TKey}`
|
|
70
|
+
? never // forbids empty id
|
|
71
|
+
: TValue
|
|
72
|
+
: never;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Represents different kinds of updates that can be passed to `Onyx.update()` method. It is a discriminated union of
|
|
77
|
+
* different update methods (`SET`, `MERGE`, `MERGE_COLLECTION`), each with their own key and value structure.
|
|
78
|
+
*/
|
|
79
|
+
type OnyxUpdate =
|
|
80
|
+
| {
|
|
81
|
+
[TKey in OnyxKey]:
|
|
82
|
+
| {
|
|
83
|
+
onyxMethod: typeof METHOD.SET;
|
|
84
|
+
key: TKey;
|
|
85
|
+
value: OnyxEntry<KeyValueMapping[TKey]>;
|
|
86
|
+
}
|
|
87
|
+
| {
|
|
88
|
+
onyxMethod: typeof METHOD.MERGE;
|
|
89
|
+
key: TKey;
|
|
90
|
+
value: PartialDeep<KeyValueMapping[TKey]>;
|
|
91
|
+
};
|
|
92
|
+
}[OnyxKey]
|
|
93
|
+
| {
|
|
94
|
+
[TKey in CollectionKeyBase]: {
|
|
95
|
+
onyxMethod: typeof METHOD.MERGE_COLLECTION;
|
|
96
|
+
key: TKey;
|
|
97
|
+
value: Record<`${TKey}${string}`, PartialDeep<KeyValueMapping[TKey]>>;
|
|
98
|
+
};
|
|
99
|
+
}[CollectionKeyBase];
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Represents the options used in `Onyx.init()` method.
|
|
103
|
+
*/
|
|
104
|
+
type InitOptions = {
|
|
105
|
+
keys?: DeepRecord<string, OnyxKey>;
|
|
106
|
+
initialKeyStates?: Partial<NullableKeyValueMapping>;
|
|
107
|
+
safeEvictionKeys?: OnyxKey[];
|
|
108
|
+
maxCachedKeysCount?: number;
|
|
109
|
+
captureMetrics?: boolean;
|
|
110
|
+
shouldSyncMultipleInstances?: boolean;
|
|
111
|
+
debugSetState?: boolean;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
declare const METHOD: {
|
|
115
|
+
readonly SET: 'set';
|
|
116
|
+
readonly MERGE: 'merge';
|
|
117
|
+
readonly MERGE_COLLECTION: 'mergecollection';
|
|
118
|
+
readonly CLEAR: 'clear';
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Returns current key names stored in persisted storage
|
|
123
|
+
*/
|
|
124
|
+
declare function getAllKeys(): Promise<Array<OnyxKey>>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Checks to see if this key has been flagged as
|
|
128
|
+
* safe for removal.
|
|
129
|
+
*/
|
|
130
|
+
declare function isSafeEvictionKey(testKey: OnyxKey): boolean;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Removes a key previously added to this list
|
|
134
|
+
* which will enable it to be deleted again.
|
|
135
|
+
*/
|
|
136
|
+
declare function removeFromEvictionBlockList(key: OnyxKey, connectionID: number): void;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Keys added to this list can never be deleted.
|
|
140
|
+
*/
|
|
141
|
+
declare function addToEvictionBlockList(key: OnyxKey, connectionID: number): void;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Subscribes a react component's state directly to a store key
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* const connectionID = Onyx.connect({
|
|
148
|
+
* key: ONYXKEYS.SESSION,
|
|
149
|
+
* callback: onSessionChange,
|
|
150
|
+
* });
|
|
151
|
+
*
|
|
152
|
+
* @param mapping the mapping information to connect Onyx to the components state
|
|
153
|
+
* @param mapping.key ONYXKEY to subscribe to
|
|
154
|
+
* @param [mapping.statePropertyName] the name of the property in the state to connect the data to
|
|
155
|
+
* @param [mapping.withOnyxInstance] whose setState() method will be called with any changed data
|
|
156
|
+
* This is used by React components to connect to Onyx
|
|
157
|
+
* @param [mapping.callback] a method that will be called with changed data
|
|
158
|
+
* This is used by any non-React code to connect to Onyx
|
|
159
|
+
* @param [mapping.initWithStoredValues] If set to false, then no data will be prefilled into the
|
|
160
|
+
* component
|
|
161
|
+
* @param [mapping.waitForCollectionCallback] If set to true, it will return the entire collection to the callback as a single object
|
|
162
|
+
* @returns an ID to use when calling disconnect
|
|
163
|
+
*/
|
|
164
|
+
declare function connect<TKey extends OnyxKey>(mapping: ConnectOptions<TKey>): number;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Remove the listener for a react component
|
|
168
|
+
* @example
|
|
169
|
+
* Onyx.disconnect(connectionID);
|
|
170
|
+
*
|
|
171
|
+
* @param connectionID unique id returned by call to Onyx.connect()
|
|
172
|
+
*/
|
|
173
|
+
declare function disconnect(connectionID: number, keyToRemoveFromEvictionBlocklist?: OnyxKey): void;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Write a value to our store with the given key
|
|
177
|
+
*
|
|
178
|
+
* @param key ONYXKEY to set
|
|
179
|
+
* @param value value to store
|
|
180
|
+
*/
|
|
181
|
+
declare function set<TKey extends OnyxKey>(key: TKey, value: OnyxEntry<KeyValueMapping[TKey]>): Promise<void>;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Sets multiple keys and values
|
|
185
|
+
*
|
|
186
|
+
* @example Onyx.multiSet({'key1': 'a', 'key2': 'b'});
|
|
187
|
+
*
|
|
188
|
+
* @param data object keyed by ONYXKEYS and the values to set
|
|
189
|
+
*/
|
|
190
|
+
declare function multiSet(data: Partial<NullableKeyValueMapping>): Promise<void>;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Merge a new value into an existing value at a key.
|
|
194
|
+
*
|
|
195
|
+
* The types of values that can be merged are `Object` and `Array`. To set another type of value use `Onyx.set()`. Merge
|
|
196
|
+
* behavior uses lodash/merge under the hood for `Object` and simple concatenation for `Array`. However, it's important
|
|
197
|
+
* to note that if you have an array value property on an `Object` that the default behavior of lodash/merge is not to
|
|
198
|
+
* concatenate. See here: https://github.com/lodash/lodash/issues/2872
|
|
199
|
+
*
|
|
200
|
+
* Calls to `Onyx.merge()` are batched so that any calls performed in a single tick will stack in a queue and get
|
|
201
|
+
* applied in the order they were called. Note: `Onyx.set()` calls do not work this way so use caution when mixing
|
|
202
|
+
* `Onyx.merge()` and `Onyx.set()`.
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* Onyx.merge(ONYXKEYS.EMPLOYEE_LIST, ['Joe']); // -> ['Joe']
|
|
206
|
+
* Onyx.merge(ONYXKEYS.EMPLOYEE_LIST, ['Jack']); // -> ['Joe', 'Jack']
|
|
207
|
+
* Onyx.merge(ONYXKEYS.POLICY, {id: 1}); // -> {id: 1}
|
|
208
|
+
* Onyx.merge(ONYXKEYS.POLICY, {name: 'My Workspace'}); // -> {id: 1, name: 'My Workspace'}
|
|
209
|
+
*
|
|
210
|
+
* @param key ONYXKEYS key
|
|
211
|
+
* @param value Object or Array value to merge
|
|
212
|
+
*/
|
|
213
|
+
declare function merge<TKey extends OnyxKey>(key: TKey, value: PartialDeep<KeyValueMapping[TKey]>): Promise<void>;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Clear out all the data in the store
|
|
217
|
+
*
|
|
218
|
+
* Note that calling Onyx.clear() and then Onyx.set() on a key with a default
|
|
219
|
+
* key state may store an unexpected value in Storage.
|
|
220
|
+
*
|
|
221
|
+
* E.g.
|
|
222
|
+
* Onyx.clear();
|
|
223
|
+
* Onyx.set(ONYXKEYS.DEFAULT_KEY, 'default');
|
|
224
|
+
* Storage.getItem(ONYXKEYS.DEFAULT_KEY)
|
|
225
|
+
* .then((storedValue) => console.log(storedValue));
|
|
226
|
+
* null is logged instead of the expected 'default'
|
|
227
|
+
*
|
|
228
|
+
* Onyx.set() might call Storage.setItem() before Onyx.clear() calls
|
|
229
|
+
* Storage.setItem(). Use Onyx.merge() instead if possible. Onyx.merge() calls
|
|
230
|
+
* Onyx.get(key) before calling Storage.setItem() via Onyx.set().
|
|
231
|
+
* Storage.setItem() from Onyx.clear() will have already finished and the merged
|
|
232
|
+
* value will be saved to storage after the default value.
|
|
233
|
+
*
|
|
234
|
+
* @param keysToPreserve is a list of ONYXKEYS that should not be cleared with the rest of the data
|
|
235
|
+
*/
|
|
236
|
+
declare function clear(keysToPreserve?: OnyxKey[]): Promise<void>;
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Merges a collection based on their keys
|
|
240
|
+
*
|
|
241
|
+
* Note that both `TKey` and `TMap` types are inferred automatically, `TKey` being the
|
|
242
|
+
* collection key specified in the first parameter and `TMap` being the object of
|
|
243
|
+
* collection keys/values specified in the second parameter.
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
*
|
|
247
|
+
* Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT, {
|
|
248
|
+
* [`${ONYXKEYS.COLLECTION.REPORT}1`]: report1,
|
|
249
|
+
* [`${ONYXKEYS.COLLECTION.REPORT}2`]: report2,
|
|
250
|
+
* });
|
|
251
|
+
*
|
|
252
|
+
* @param collectionKey e.g. `ONYXKEYS.COLLECTION.REPORT`
|
|
253
|
+
* @param collection Object collection keyed by individual collection member keys and values
|
|
254
|
+
*/
|
|
255
|
+
declare function mergeCollection<TKey extends CollectionKeyBase, TMap>(
|
|
256
|
+
collectionKey: TKey,
|
|
257
|
+
collection: Collection<TKey, TMap, PartialDeep<KeyValueMapping[TKey]>>,
|
|
258
|
+
): Promise<void>;
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Insert API responses and lifecycle data into Onyx
|
|
262
|
+
*
|
|
263
|
+
* @param data An array of update objects
|
|
264
|
+
* @returns resolves when all operations are complete
|
|
265
|
+
*/
|
|
266
|
+
declare function update(data: OnyxUpdate[]): Promise<void>;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Initialize the store with actions and listening for storage events
|
|
270
|
+
*
|
|
271
|
+
* @param [options={}] config object
|
|
272
|
+
* @param [options.keys={}] `ONYXKEYS` constants object
|
|
273
|
+
* @param [options.initialKeyStates={}] initial data to set when `init()` and `clear()` is called
|
|
274
|
+
* @param [options.safeEvictionKeys=[]] This is an array of keys
|
|
275
|
+
* (individual or collection patterns) that when provided to Onyx are flagged
|
|
276
|
+
* as "safe" for removal. Any components subscribing to these keys must also
|
|
277
|
+
* implement a canEvict option. See the README for more info.
|
|
278
|
+
* @param [options.maxCachedKeysCount=55] Sets how many recent keys should we try to keep in cache
|
|
279
|
+
* Setting this to 0 would practically mean no cache
|
|
280
|
+
* We try to free cache when we connect to a safe eviction key
|
|
281
|
+
* @param [options.captureMetrics] Enables Onyx benchmarking and exposes the get/print/reset functions
|
|
282
|
+
* @param [options.shouldSyncMultipleInstances] Auto synchronize storage events between multiple instances
|
|
283
|
+
* of Onyx running in different tabs/windows. Defaults to true for platforms that support local storage (web/desktop)
|
|
284
|
+
* @param [options.debugSetState] Enables debugging setState() calls to connected components.
|
|
285
|
+
* @example
|
|
286
|
+
* Onyx.init({
|
|
287
|
+
* keys: ONYXKEYS,
|
|
288
|
+
* initialKeyStates: {
|
|
289
|
+
* [ONYXKEYS.SESSION]: {loading: false},
|
|
290
|
+
* },
|
|
291
|
+
* });
|
|
292
|
+
*/
|
|
293
|
+
declare function init(config?: InitOptions): void;
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* @private
|
|
297
|
+
*/
|
|
298
|
+
declare function hasPendingMergeForKey(key: OnyxKey): boolean;
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* When set these keys will not be persisted to storage
|
|
302
|
+
*/
|
|
303
|
+
declare function setMemoryOnlyKeys(keyList: OnyxKey[]): void;
|
|
304
|
+
|
|
305
|
+
declare const Onyx: {
|
|
306
|
+
connect: typeof connect;
|
|
307
|
+
disconnect: typeof disconnect;
|
|
308
|
+
set: typeof set;
|
|
309
|
+
multiSet: typeof multiSet;
|
|
310
|
+
merge: typeof merge;
|
|
311
|
+
mergeCollection: typeof mergeCollection;
|
|
312
|
+
hasPendingMergeForKey: typeof hasPendingMergeForKey;
|
|
313
|
+
update: typeof update;
|
|
314
|
+
clear: typeof clear;
|
|
315
|
+
getAllKeys: typeof getAllKeys;
|
|
316
|
+
init: typeof init;
|
|
317
|
+
registerLogger: typeof Logger.registerLogger;
|
|
318
|
+
addToEvictionBlockList: typeof addToEvictionBlockList;
|
|
319
|
+
removeFromEvictionBlockList: typeof removeFromEvictionBlockList;
|
|
320
|
+
isSafeEvictionKey: typeof isSafeEvictionKey;
|
|
321
|
+
METHOD: typeof METHOD;
|
|
322
|
+
setMemoryOnlyKeys: typeof setMemoryOnlyKeys;
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
export default Onyx;
|
|
326
|
+
export {OnyxUpdate};
|
package/lib/index.d.ts
ADDED
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import {IsEqual, Merge} from 'type-fest';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a deeply nested record. It maps keys to values,
|
|
5
|
+
* and those values can either be of type `TValue` or further nested `DeepRecord` instances.
|
|
6
|
+
*/
|
|
7
|
+
type DeepRecord<TKey extends string | number | symbol, TValue> = {[key: string]: TValue | DeepRecord<TKey, TValue>};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Represents type options to configure all Onyx methods.
|
|
11
|
+
* It's a combination of predefined options with user-provided options (CustomTypeOptions).
|
|
12
|
+
*
|
|
13
|
+
* The options are:
|
|
14
|
+
* - `keys`: Represents a string union of all Onyx normal keys.
|
|
15
|
+
* - `collectionKeys`: Represents a string union of all Onyx collection keys.
|
|
16
|
+
* - `values`: Represents a Record where each key is an Onyx key and each value is its corresponding Onyx value type.
|
|
17
|
+
*
|
|
18
|
+
* The user-defined options (CustomTypeOptions) are merged into these predefined options.
|
|
19
|
+
* In case of conflicting properties, the ones from CustomTypeOptions are prioritized.
|
|
20
|
+
*/
|
|
21
|
+
type TypeOptions = Merge<
|
|
22
|
+
{
|
|
23
|
+
keys: string;
|
|
24
|
+
collectionKeys: string;
|
|
25
|
+
values: Record<string, unknown>;
|
|
26
|
+
},
|
|
27
|
+
CustomTypeOptions
|
|
28
|
+
>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Represents the user-defined options to configure all Onyx methods.
|
|
32
|
+
*
|
|
33
|
+
* The developer can configure Onyx methods by augmenting this library and overriding CustomTypeOptions.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* // ONYXKEYS.ts
|
|
38
|
+
* import {ValueOf} from 'type-fest';
|
|
39
|
+
* import { Account, Report } from './types';
|
|
40
|
+
*
|
|
41
|
+
* const ONYXKEYS = {
|
|
42
|
+
* ACCOUNT: 'account',
|
|
43
|
+
* IS_SIDEBAR_LOADED: 'isSidebarLoaded',
|
|
44
|
+
*
|
|
45
|
+
* // Collection Keys
|
|
46
|
+
* COLLECTION: {
|
|
47
|
+
* REPORT: 'report_',
|
|
48
|
+
* },
|
|
49
|
+
* } as const;
|
|
50
|
+
*
|
|
51
|
+
* type OnyxKeysMap = typeof ONYXKEYS;
|
|
52
|
+
* type OnyxCollectionKey = ValueOf<OnyxKeysMap['COLLECTION']>;
|
|
53
|
+
* type OnyxKey = DeepValueOf<Omit<OnyxKeysMap, 'COLLECTION'>>;
|
|
54
|
+
*
|
|
55
|
+
* type OnyxValues = {
|
|
56
|
+
* [ONYXKEYS.ACCOUNT]: Account;
|
|
57
|
+
* [ONYXKEYS.IS_SIDEBAR_LOADED]: boolean;
|
|
58
|
+
* [ONYXKEYS.COLLECTION.REPORT]: Report;
|
|
59
|
+
* };
|
|
60
|
+
*
|
|
61
|
+
* export default ONYXKEYS;
|
|
62
|
+
* export type {OnyxKey, OnyxCollectionKey, OnyxValues};
|
|
63
|
+
*
|
|
64
|
+
* // global.d.ts
|
|
65
|
+
* import {OnyxKey, OnyxCollectionKey, OnyxValues} from './ONYXKEYS';
|
|
66
|
+
*
|
|
67
|
+
* declare module 'react-native-onyx' {
|
|
68
|
+
* interface CustomTypeOptions {
|
|
69
|
+
* keys: OnyxKey;
|
|
70
|
+
* collectionKeys: OnyxCollectionKey;
|
|
71
|
+
* values: OnyxValues;
|
|
72
|
+
* }
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
interface CustomTypeOptions {}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Represents a string union of all Onyx normal keys.
|
|
80
|
+
*/
|
|
81
|
+
type Key = TypeOptions['keys'];
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Represents a string union of all Onyx collection keys.
|
|
85
|
+
*/
|
|
86
|
+
type CollectionKeyBase = TypeOptions['collectionKeys'];
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Represents a literal string union of all Onyx collection keys.
|
|
90
|
+
* It allows appending a string after each collection key e.g. `report_some-id`.
|
|
91
|
+
*/
|
|
92
|
+
type CollectionKey = `${CollectionKeyBase}${string}`;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Represents a string union of all Onyx normal and collection keys.
|
|
96
|
+
*/
|
|
97
|
+
type OnyxKey = Key | CollectionKey;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Represents a mapping of Onyx keys to values, where keys are either normal or collection Onyx keys
|
|
101
|
+
* and values are the corresponding values in Onyx's state.
|
|
102
|
+
*
|
|
103
|
+
* For collection keys, `KeyValueMapping` allows any string to be appended
|
|
104
|
+
* to the key (e.g., 'report_some-id', 'download_some-id').
|
|
105
|
+
*
|
|
106
|
+
* The mapping is derived from the `values` property of the `TypeOptions` type.
|
|
107
|
+
*/
|
|
108
|
+
type KeyValueMapping = {
|
|
109
|
+
[TKey in keyof TypeOptions['values'] as TKey extends CollectionKeyBase
|
|
110
|
+
? `${TKey}${string}`
|
|
111
|
+
: TKey]: TypeOptions['values'][TKey];
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Represents a selector function type which operates based on the provided `TKey` and `ReturnType`.
|
|
116
|
+
*
|
|
117
|
+
* A `Selector` is a function that accepts a value and returns a processed value.
|
|
118
|
+
* This type accepts two type parameters: `TKey` and `TReturnType`.
|
|
119
|
+
*
|
|
120
|
+
* The type `TKey` extends `OnyxKey` and it is the key used to access a value in `KeyValueMapping`.
|
|
121
|
+
* `TReturnType` is the type of the returned value from the selector function.
|
|
122
|
+
*/
|
|
123
|
+
type Selector<TKey extends OnyxKey, TReturnType> = (value: OnyxEntry<KeyValueMapping[TKey]>) => TReturnType;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Represents a single Onyx entry, that can be either `TOnyxValue` or `null` if it doesn't exist.
|
|
127
|
+
*
|
|
128
|
+
* It can be used to specify data retrieved from Onyx e.g. `withOnyx` HOC mappings.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* import Onyx, {OnyxEntry, withOnyx} from 'react-native-onyx';
|
|
133
|
+
*
|
|
134
|
+
* type OnyxProps = {
|
|
135
|
+
* userAccount: OnyxEntry<Account>;
|
|
136
|
+
* };
|
|
137
|
+
*
|
|
138
|
+
* type Props = OnyxProps & {
|
|
139
|
+
* prop1: string;
|
|
140
|
+
* };
|
|
141
|
+
*
|
|
142
|
+
* function Component({prop1, userAccount}: Props) {
|
|
143
|
+
* // ...
|
|
144
|
+
* }
|
|
145
|
+
*
|
|
146
|
+
* export default withOnyx<Props, OnyxProps>({
|
|
147
|
+
* userAccount: {
|
|
148
|
+
* key: ONYXKEYS.ACCOUNT,
|
|
149
|
+
* },
|
|
150
|
+
* })(Component);
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
type OnyxEntry<TOnyxValue> = TOnyxValue | null;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Represents an Onyx collection of entries, that can be either a record of `TOnyxValue`s or `null` if it is empty or doesn't exist.
|
|
157
|
+
*
|
|
158
|
+
* It can be used to specify collection data retrieved from Onyx e.g. `withOnyx` HOC mappings.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* import Onyx, {OnyxCollection, withOnyx} from 'react-native-onyx';
|
|
163
|
+
*
|
|
164
|
+
* type OnyxProps = {
|
|
165
|
+
* reports: OnyxCollection<Report>;
|
|
166
|
+
* };
|
|
167
|
+
*
|
|
168
|
+
* type Props = OnyxProps & {
|
|
169
|
+
* prop1: string;
|
|
170
|
+
* };
|
|
171
|
+
*
|
|
172
|
+
* function Component({prop1, reports}: Props) {
|
|
173
|
+
* // ...
|
|
174
|
+
* }
|
|
175
|
+
*
|
|
176
|
+
* export default withOnyx<Props, OnyxProps>({
|
|
177
|
+
* reports: {
|
|
178
|
+
* key: ONYXKEYS.COLLECTION.REPORT,
|
|
179
|
+
* },
|
|
180
|
+
* })(Component);
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
type OnyxCollection<TOnyxValue> = OnyxEntry<Record<string, TOnyxValue | null>>;
|
|
184
|
+
|
|
185
|
+
export {
|
|
186
|
+
CollectionKey,
|
|
187
|
+
CollectionKeyBase,
|
|
188
|
+
CustomTypeOptions,
|
|
189
|
+
DeepRecord,
|
|
190
|
+
Key,
|
|
191
|
+
KeyValueMapping,
|
|
192
|
+
OnyxCollection,
|
|
193
|
+
OnyxEntry,
|
|
194
|
+
OnyxKey,
|
|
195
|
+
Selector,
|
|
196
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import {IsEqual} from 'type-fest';
|
|
2
|
+
import {CollectionKeyBase, KeyValueMapping, OnyxCollection, OnyxEntry, OnyxKey, Selector} from './types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Represents the base mapping options between an Onyx key and the component's prop.
|
|
6
|
+
*/
|
|
7
|
+
type BaseMapping<TComponentProps, TOnyxProps> = {
|
|
8
|
+
canEvict?: boolean | ((props: Omit<TComponentProps, keyof TOnyxProps>) => boolean);
|
|
9
|
+
initWithStoredValues?: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Represents the string / function `key` mapping option between an Onyx key and the component's prop.
|
|
14
|
+
*
|
|
15
|
+
* If `key` is `string`, the type of the Onyx value that is associated with `key` must match with the type of the component's prop,
|
|
16
|
+
* otherwise an error will be thrown.
|
|
17
|
+
*
|
|
18
|
+
* If `key` is `function`, the return type of `key` function must be a valid Onyx key and the type of the Onyx value associated
|
|
19
|
+
* with `key` must match with the type of the component's prop, otherwise an error will be thrown.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* // Onyx prop with `string` key
|
|
24
|
+
* onyxProp: {
|
|
25
|
+
* key: ONYXKEYS.ACCOUNT,
|
|
26
|
+
* },
|
|
27
|
+
*
|
|
28
|
+
* // Onyx prop with `function` key
|
|
29
|
+
* onyxProp: {
|
|
30
|
+
* key: ({reportId}) => ONYXKEYS.ACCOUNT,
|
|
31
|
+
* },
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
type BaseMappingKey<
|
|
35
|
+
TComponentProps,
|
|
36
|
+
TOnyxProps,
|
|
37
|
+
TOnyxProp extends keyof TOnyxProps,
|
|
38
|
+
TOnyxKey extends OnyxKey,
|
|
39
|
+
TOnyxValue
|
|
40
|
+
> = IsEqual<TOnyxValue, TOnyxProps[TOnyxProp]> extends true
|
|
41
|
+
? {
|
|
42
|
+
key: TOnyxKey | ((props: Omit<TComponentProps, keyof TOnyxProps>) => TOnyxKey);
|
|
43
|
+
}
|
|
44
|
+
: never;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Represents the string `key` and `selector` mapping options between an Onyx key and the component's prop.
|
|
48
|
+
*
|
|
49
|
+
* The function signature and return type of `selector` must match with the type of the component's prop,
|
|
50
|
+
* otherwise an error will be thrown.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* // Onyx prop with `string` key and selector
|
|
55
|
+
* onyxProp: {
|
|
56
|
+
* key: ONYXKEYS.ACCOUNT,
|
|
57
|
+
* selector: (value: Account | null): string => value?.id ?? '',
|
|
58
|
+
* },
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
type BaseMappingStringKeyAndSelector<
|
|
62
|
+
TComponentProps,
|
|
63
|
+
TOnyxProps,
|
|
64
|
+
TOnyxProp extends keyof TOnyxProps,
|
|
65
|
+
TOnyxKey extends OnyxKey
|
|
66
|
+
> = {
|
|
67
|
+
key: TOnyxKey;
|
|
68
|
+
selector: Selector<TOnyxKey, TOnyxProps[TOnyxProp]>;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Represents the function `key` and `selector` mapping options between an Onyx key and the component's prop.
|
|
73
|
+
*
|
|
74
|
+
* The function signature and return type of `selector` must match with the type of the component's prop,
|
|
75
|
+
* otherwise an error will be thrown.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* // Onyx prop with `function` key and selector
|
|
80
|
+
* onyxProp: {
|
|
81
|
+
* key: ({reportId}) => ONYXKEYS.ACCOUNT,
|
|
82
|
+
* selector: (value: Account | null) => value?.id ?? '',
|
|
83
|
+
* },
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
type BaseMappingFunctionKeyAndSelector<
|
|
87
|
+
TComponentProps,
|
|
88
|
+
TOnyxProps,
|
|
89
|
+
TOnyxProp extends keyof TOnyxProps,
|
|
90
|
+
TOnyxKey extends OnyxKey
|
|
91
|
+
> = {
|
|
92
|
+
key: (props: Omit<TComponentProps, keyof TOnyxProps>) => TOnyxKey;
|
|
93
|
+
selector: Selector<TOnyxKey, TOnyxProps[TOnyxProp]>;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Represents the mapping options between an Onyx key and the component's prop with all its possibilities.
|
|
98
|
+
*/
|
|
99
|
+
type Mapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends OnyxKey> = BaseMapping<
|
|
100
|
+
TComponentProps,
|
|
101
|
+
TOnyxProps
|
|
102
|
+
> &
|
|
103
|
+
(
|
|
104
|
+
| BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey, OnyxEntry<KeyValueMapping[TOnyxKey]>>
|
|
105
|
+
| BaseMappingStringKeyAndSelector<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey>
|
|
106
|
+
| BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey>
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Represents the mapping options between an Onyx collection key without suffix and the component's prop with all its possibilities.
|
|
111
|
+
*/
|
|
112
|
+
type CollectionMapping<
|
|
113
|
+
TComponentProps,
|
|
114
|
+
TOnyxProps,
|
|
115
|
+
TOnyxProp extends keyof TOnyxProps,
|
|
116
|
+
TOnyxKey extends CollectionKeyBase
|
|
117
|
+
> = BaseMapping<TComponentProps, TOnyxProps> &
|
|
118
|
+
(
|
|
119
|
+
| BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey, OnyxCollection<KeyValueMapping[TOnyxKey]>>
|
|
120
|
+
| BaseMappingStringKeyAndSelector<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey>
|
|
121
|
+
| BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey>
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Represents an union type of all the possible Onyx key mappings.
|
|
126
|
+
* Each `OnyxPropMapping` will be associated with its respective Onyx key, ensuring different type-safety for each object.
|
|
127
|
+
*/
|
|
128
|
+
type OnyxPropMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps> = {
|
|
129
|
+
[TOnyxKey in OnyxKey]: Mapping<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey>;
|
|
130
|
+
}[OnyxKey];
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Represents an union type of all the possible Onyx collection keys without suffix mappings.
|
|
134
|
+
* Each `OnyxPropCollectionMapping` will be associated with its respective Onyx key, ensuring different type-safety for each object.
|
|
135
|
+
*/
|
|
136
|
+
type OnyxPropCollectionMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps> = {
|
|
137
|
+
[TOnyxKey in CollectionKeyBase]: CollectionMapping<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey>;
|
|
138
|
+
}[CollectionKeyBase];
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* This is a higher order component that provides the ability to map a state property directly to
|
|
142
|
+
* something in Onyx (a key/value store). That way, as soon as data in Onyx changes, the state will be set and the view
|
|
143
|
+
* will automatically change to reflect the new data.
|
|
144
|
+
*/
|
|
145
|
+
declare function withOnyx<TComponentProps, TOnyxProps>(
|
|
146
|
+
mapping: {
|
|
147
|
+
[TOnyxProp in keyof TOnyxProps]:
|
|
148
|
+
| OnyxPropMapping<TComponentProps, TOnyxProps, TOnyxProp>
|
|
149
|
+
| OnyxPropCollectionMapping<TComponentProps, TOnyxProps, TOnyxProp>;
|
|
150
|
+
},
|
|
151
|
+
): (component: React.ComponentType<TComponentProps>) => React.ComponentType<Omit<TComponentProps, keyof TOnyxProps>>;
|
|
152
|
+
|
|
153
|
+
export default withOnyx;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-onyx",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.60",
|
|
4
4
|
"author": "Expensify, Inc.",
|
|
5
5
|
"homepage": "https://expensify.com",
|
|
6
6
|
"description": "State management for React Native",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"react-native": "native.js",
|
|
32
32
|
"main": "native.js",
|
|
33
33
|
"browser": "web.js",
|
|
34
|
+
"types": "lib/index.d.ts",
|
|
34
35
|
"scripts": {
|
|
35
36
|
"lint": "eslint .",
|
|
36
37
|
"lint-tests": "eslint tests/**",
|
|
@@ -50,6 +51,7 @@
|
|
|
50
51
|
"@react-native-community/eslint-config": "^2.0.0",
|
|
51
52
|
"@testing-library/jest-native": "^3.4.2",
|
|
52
53
|
"@testing-library/react-native": "^7.0.2",
|
|
54
|
+
"@types/react": "^18.2.14",
|
|
53
55
|
"babel-eslint": "^10.1.0",
|
|
54
56
|
"babel-jest": "^26.2.2",
|
|
55
57
|
"babel-loader": "^8.2.5",
|
|
@@ -68,6 +70,7 @@
|
|
|
68
70
|
"react-native-performance": "^2.0.0",
|
|
69
71
|
"react-native-quick-sqlite": "^8.0.0-beta.2",
|
|
70
72
|
"react-test-renderer": "18.1.0",
|
|
73
|
+
"type-fest": "^3.12.0",
|
|
71
74
|
"webpack": "^5.72.1",
|
|
72
75
|
"webpack-cli": "^4.9.2",
|
|
73
76
|
"webpack-merge": "^5.8.0"
|