react-native-onyx 2.0.26 → 2.0.28

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.
@@ -48,6 +48,6 @@ function logSetStateCall(mapping, previousValue, newValue, caller, keyThatChange
48
48
  logParams.previousValue = previousValue;
49
49
  logParams.newValue = newValue;
50
50
  }
51
- console.debug(`[Onyx-Debug] ${mapping.displayName} setState() called. Subscribed to key '${mapping.key}' (${caller})`, logParams);
51
+ console.debug(`[Onyx-Debug] ${'displayName' in mapping && mapping.displayName} setState() called. Subscribed to key '${mapping.key}' (${caller})`, logParams);
52
52
  }
53
53
  exports.logSetStateCall = logSetStateCall;
@@ -5,7 +5,7 @@ declare const StorageMock: {
5
5
  multiGet: jest.Mock<Promise<import("../providers/types").KeyValuePairList>, [keys: import("../providers/types").KeyList]>;
6
6
  setItem: jest.Mock<Promise<void | import("react-native-quick-sqlite").QueryResult>, [key: any, value: unknown]>;
7
7
  multiSet: jest.Mock<Promise<void | import("react-native-quick-sqlite").BatchQueryResult>, [pairs: import("../providers/types").KeyValuePairList]>;
8
- mergeItem: jest.Mock<Promise<void | import("react-native-quick-sqlite").BatchQueryResult>, [key: any, changes: unknown, modifiedData: unknown]>;
8
+ mergeItem: jest.Mock<Promise<void | import("react-native-quick-sqlite").BatchQueryResult>, [key: any, deltaChanges: unknown, preMergedValue: unknown, shouldSetValue?: boolean | undefined]>;
9
9
  multiMerge: jest.Mock<Promise<void | import("react-native-quick-sqlite").BatchQueryResult | IDBValidKey[]>, [pairs: import("../providers/types").KeyValuePairList]>;
10
10
  removeItem: jest.Mock<Promise<void | import("react-native-quick-sqlite").QueryResult>, [key: string]>;
11
11
  removeItems: jest.Mock<Promise<void | import("react-native-quick-sqlite").QueryResult>, [keys: import("../providers/types").KeyList]>;
@@ -118,8 +118,8 @@ const Storage = {
118
118
  /**
119
119
  * Merging an existing value with a new one
120
120
  */
121
- mergeItem: (key, changes, modifiedData) => tryOrDegradePerformance(() => {
122
- const promise = provider.mergeItem(key, changes, modifiedData);
121
+ mergeItem: (key, deltaChanges, preMergedValue, shouldSetValue = false) => tryOrDegradePerformance(() => {
122
+ const promise = provider.mergeItem(key, deltaChanges, preMergedValue, shouldSetValue);
123
123
  if (shouldKeepInstancesSync) {
124
124
  return promise.then(() => InstanceSync_1.default.mergeItem(key));
125
125
  }
@@ -37,9 +37,9 @@ const provider = {
37
37
  return Promise.all(upsertMany);
38
38
  });
39
39
  }),
40
- mergeItem(key, _changes, modifiedData) {
40
+ mergeItem(key, _deltaChanges, preMergedValue) {
41
41
  // Since Onyx also merged the existing value with the changes, we can just set the value directly
42
- return provider.setItem(key, modifiedData);
42
+ return provider.setItem(key, preMergedValue);
43
43
  },
44
44
  multiSet: (pairs) => (0, idb_keyval_1.setMany)(pairs, idbKeyValStore),
45
45
  clear: () => (0, idb_keyval_1.clear)(idbKeyValStore),
@@ -64,9 +64,9 @@ const provider = {
64
64
  /**
65
65
  * Merging an existing value with a new one
66
66
  */
67
- mergeItem(key, _changes, modifiedData) {
67
+ mergeItem(key, _deltaChanges, preMergedValue) {
68
68
  // Since Onyx already merged the existing value with the changes, we can just set the value directly
69
- return this.setItem(key, modifiedData);
69
+ return this.setItem(key, preMergedValue);
70
70
  },
71
71
  /**
72
72
  * Multiple merging of existing and new values in a batch
@@ -13,10 +13,8 @@ const provider = {
13
13
  },
14
14
  /**
15
15
  * Get the value of a given key or return `null` if it's not available in memory
16
- * @param {String} key
17
- * @return {Promise<*>}
18
16
  */
19
- getItem() {
17
+ getItem(key) {
20
18
  return Promise.resolve(null);
21
19
  },
22
20
  /**
@@ -68,8 +68,11 @@ const provider = {
68
68
  });
69
69
  return db.executeBatchAsync([[query, queryArguments]]);
70
70
  },
71
- mergeItem(key, changes) {
72
- return this.multiMerge([[key, changes]]);
71
+ mergeItem(key, deltaChanges, preMergedValue, shouldSetValue) {
72
+ if (shouldSetValue) {
73
+ return this.setItem(key, preMergedValue);
74
+ }
75
+ return this.multiMerge([[key, deltaChanges]]);
73
76
  },
74
77
  getAllKeys: () => db.executeAsync('SELECT record_key FROM keyvaluepairs;').then(({ rows }) => {
75
78
  // eslint-disable-next-line no-underscore-dangle
@@ -3,7 +3,7 @@ import type { OnyxKey, OnyxValue } from '../../types';
3
3
  type KeyValuePair = [OnyxKey, OnyxValue<OnyxKey>];
4
4
  type KeyList = OnyxKey[];
5
5
  type KeyValuePairList = KeyValuePair[];
6
- type OnStorageKeyChanged = <TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey> | null) => void;
6
+ type OnStorageKeyChanged = <TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>) => void;
7
7
  type StorageProvider = {
8
8
  /**
9
9
  * The name of the provider that can be printed to the logs
@@ -16,7 +16,7 @@ type StorageProvider = {
16
16
  /**
17
17
  * Gets the value of a given key or return `null` if it's not available in storage
18
18
  */
19
- getItem: <TKey extends OnyxKey>(key: TKey) => Promise<OnyxValue<TKey> | null>;
19
+ getItem: <TKey extends OnyxKey>(key: TKey) => Promise<OnyxValue<TKey>>;
20
20
  /**
21
21
  * Get multiple key-value pairs for the given array of keys in a batch
22
22
  */
@@ -35,10 +35,11 @@ type StorageProvider = {
35
35
  multiMerge: (pairs: KeyValuePairList) => Promise<BatchQueryResult | IDBValidKey[] | void>;
36
36
  /**
37
37
  * Merges an existing value with a new one by leveraging JSON_PATCH
38
- * @param changes - the delta for a specific key
39
- * @param modifiedData - the pre-merged data from `Onyx.applyMerge`
38
+ * @param deltaChanges - the delta for a specific key
39
+ * @param preMergedValue - the pre-merged data from `Onyx.applyMerge`
40
+ * @param shouldSetValue - whether the data should be set instead of merged
40
41
  */
41
- mergeItem: <TKey extends OnyxKey>(key: TKey, changes: OnyxValue<TKey>, modifiedData: OnyxValue<TKey>) => Promise<BatchQueryResult | void>;
42
+ mergeItem: <TKey extends OnyxKey>(key: TKey, deltaChanges: OnyxValue<TKey>, preMergedValue: OnyxValue<TKey>, shouldSetValue?: boolean) => Promise<BatchQueryResult | void>;
42
43
  /**
43
44
  * Returns all keys available in storage
44
45
  */
package/dist/types.d.ts CHANGED
@@ -231,40 +231,52 @@ type Collection<TKey extends CollectionKeyBase, TMap, TValue> = {
231
231
  [MapK in keyof TMap]: MapK extends `${TKey}${string}` ? MapK extends `${TKey}` ? never : TValue : never;
232
232
  };
233
233
  type WithOnyxInstance = Component<unknown, WithOnyxInstanceState<NullableKeyValueMapping>> & {
234
- setStateProxy: (cb: (state: NullableKeyValueMapping) => OnyxValue<OnyxKey>) => void;
234
+ setStateProxy: (cb: (state: Record<string, OnyxCollection<KeyValueMapping[OnyxKey]>>) => OnyxValue<OnyxKey>) => void;
235
235
  setWithOnyxState: (statePropertyName: OnyxKey, value: OnyxValue<OnyxKey>) => void;
236
236
  };
237
237
  /** Represents the base options used in `Onyx.connect()` method. */
238
238
  type BaseConnectOptions = {
239
- statePropertyName?: string;
240
- withOnyxInstance?: Component;
241
239
  initWithStoredValues?: boolean;
242
240
  };
241
+ /** Represents additional options used inside withOnyx HOC */
242
+ type WithOnyxConnectOptions<TKey extends OnyxKey> = {
243
+ withOnyxInstance: WithOnyxInstance;
244
+ statePropertyName: string;
245
+ displayName: string;
246
+ initWithStoredValues?: boolean;
247
+ selector?: Selector<TKey, unknown, unknown>;
248
+ canEvict?: boolean;
249
+ };
250
+ type DefaultConnectCallback<TKey extends OnyxKey> = (value: OnyxEntry<KeyValueMapping[TKey]>, key: TKey) => void;
251
+ type CollectionConnectCallback<TKey extends OnyxKey> = (value: OnyxCollection<KeyValueMapping[TKey]>) => void;
252
+ /** Represents the callback function used in `Onyx.connect()` method with a regular key. */
253
+ type DefaultConnectOptions<TKey extends OnyxKey> = {
254
+ key: TKey;
255
+ callback?: DefaultConnectCallback<TKey>;
256
+ waitForCollectionCallback?: false;
257
+ };
258
+ /** Represents the callback function used in `Onyx.connect()` method with a collection key. */
259
+ type CollectionConnectOptions<TKey extends OnyxKey> = {
260
+ key: TKey extends CollectionKeyBase ? TKey : never;
261
+ callback?: CollectionConnectCallback<TKey>;
262
+ waitForCollectionCallback: true;
263
+ };
243
264
  /**
244
265
  * Represents the options used in `Onyx.connect()` method.
245
- * The type is built from `BaseConnectOptions` and extended to handle key/callback related options.
266
+ * The type is built from `DefaultConnectOptions`/`CollectionConnectOptions` depending on the `waitForCollectionCallback` property.
246
267
  * It includes two different forms, depending on whether we are waiting for a collection callback or not.
247
268
  *
248
269
  * If `waitForCollectionCallback` is `true`, it expects `key` to be a Onyx collection key and `callback` will be triggered with the whole collection
249
270
  * and will pass `value` as an `OnyxCollection`.
250
271
  *
251
- *
252
272
  * 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
253
273
  * and will pass `value` as an `OnyxEntry`.
274
+ *
275
+ * The type is also extended with `BaseConnectOptions` and `WithOnyxConnectOptions` to include additional options, depending on the context where it's used.
254
276
  */
255
- type ConnectOptions<TKey extends OnyxKey> = BaseConnectOptions & ({
256
- key: TKey extends CollectionKeyBase ? TKey : never;
257
- callback?: (value: OnyxCollection<KeyValueMapping[TKey]>) => void;
258
- waitForCollectionCallback: true;
259
- } | {
260
- key: TKey;
261
- callback?: (value: OnyxEntry<KeyValueMapping[TKey]>, key: TKey) => void;
262
- waitForCollectionCallback?: false;
263
- });
277
+ type ConnectOptions<TKey extends OnyxKey> = (CollectionConnectOptions<TKey> | DefaultConnectOptions<TKey>) & (BaseConnectOptions | WithOnyxConnectOptions<TKey>);
264
278
  type Mapping<TKey extends OnyxKey> = ConnectOptions<TKey> & {
265
279
  connectionID: number;
266
- statePropertyName: string;
267
- displayName: string;
268
280
  };
269
281
  /**
270
282
  * Represents different kinds of updates that can be passed to `Onyx.update()` method. It is a discriminated union of
@@ -322,4 +334,4 @@ type InitOptions = {
322
334
  /** Enables debugging setState() calls to connected components */
323
335
  debugSetState?: boolean;
324
336
  };
325
- export type { CollectionKey, CollectionKeyBase, CustomTypeOptions, DeepRecord, Key, KeyValueMapping, NullableKeyValueMapping, OnyxCollection, OnyxEntry, OnyxKey, OnyxValue, Selector, NullishDeep, WithOnyxInstanceState, ExtractOnyxCollectionValue, Collection, WithOnyxInstance, BaseConnectOptions, ConnectOptions, Mapping, OnyxUpdate, InitOptions, };
337
+ export type { CollectionKey, CollectionKeyBase, CustomTypeOptions, DeepRecord, Key, KeyValueMapping, NullableKeyValueMapping, OnyxCollection, OnyxEntry, OnyxKey, OnyxValue, Selector, NullishDeep, WithOnyxInstanceState, ExtractOnyxCollectionValue, Collection, WithOnyxInstance, BaseConnectOptions, WithOnyxConnectOptions, DefaultConnectCallback, CollectionConnectCallback, DefaultConnectOptions, CollectionConnectOptions, ConnectOptions, Mapping, OnyxUpdate, InitOptions, };
package/dist/useOnyx.js CHANGED
@@ -83,7 +83,7 @@ function useOnyx(key, options) {
83
83
  }, [key, selectorRef, options === null || options === void 0 ? void 0 : options.allowStaleData, options === null || options === void 0 ? void 0 : options.initialValue]);
84
84
  const subscribe = (0, react_1.useCallback)((onStoreChange) => {
85
85
  connectionIDRef.current = Onyx_1.default.connect({
86
- key: key,
86
+ key,
87
87
  callback: () => {
88
88
  // We don't need to update the Onyx cache again here, when `callback` is called the cache is already
89
89
  // expected to be updated, so we just signal that the store changed and `getSnapshot()` can be called again.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-onyx",
3
- "version": "2.0.26",
3
+ "version": "2.0.28",
4
4
  "author": "Expensify, Inc.",
5
5
  "homepage": "https://expensify.com",
6
6
  "description": "State management for React Native",
@@ -33,7 +33,8 @@
33
33
  "test": "jest",
34
34
  "build": "tsc -p tsconfig.build.json && cp ./lib/*.d.ts ./dist",
35
35
  "build:watch": "nodemon --watch lib --ext js,json,ts,tsx --exec \"npm run build && npm pack\"",
36
- "build:docs": "node buildDocs.js",
36
+ "prebuild:docs": "npm run build",
37
+ "build:docs": "ts-node buildDocs.ts",
37
38
  "lint-tests": "eslint tests/**",
38
39
  "prettier": "prettier --write ."
39
40
  },
@@ -49,6 +50,7 @@
49
50
  "@testing-library/jest-native": "^3.4.2",
50
51
  "@testing-library/react-native": "^10.0.0",
51
52
  "@types/jest": "^28.1.8",
53
+ "@types/jsdoc-to-markdown": "^7.0.6",
52
54
  "@types/lodash": "^4.14.202",
53
55
  "@types/node": "^20.11.5",
54
56
  "@types/react": "^18.2.14",
@@ -78,6 +80,7 @@
78
80
  "react-native-performance": "^2.0.0",
79
81
  "react-native-quick-sqlite": "^8.0.6",
80
82
  "react-test-renderer": "18.1.0",
83
+ "ts-node": "^10.9.2",
81
84
  "type-fest": "^3.12.0",
82
85
  "typescript": "^5.3.3"
83
86
  },