react-native-onyx 3.0.32 → 3.0.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Onyx.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as Logger from './Logger';
2
2
  import type { CollectionKeyBase, ConnectOptions, InitOptions, OnyxKey, OnyxMergeCollectionInput, OnyxSetCollectionInput, 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, enablePerformanceMetrics, enableDevTools, skippableCollectionMemberIDs, }: InitOptions): void;
5
+ declare function init({ keys, initialKeyStates, evictableKeys, maxCachedKeysCount, shouldSyncMultipleInstances, enablePerformanceMetrics, enableDevTools, skippableCollectionMemberIDs, snapshotMergeKeys, }: 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.
package/dist/Onyx.js CHANGED
@@ -48,7 +48,7 @@ const GlobalSettings = __importStar(require("./GlobalSettings"));
48
48
  const metrics_1 = __importDefault(require("./metrics"));
49
49
  const OnyxMerge_1 = __importDefault(require("./OnyxMerge"));
50
50
  /** Initialize the store with actions and listening for storage events */
51
- function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedKeysCount = 1000, shouldSyncMultipleInstances = !!global.localStorage, enablePerformanceMetrics = false, enableDevTools = true, skippableCollectionMemberIDs = [], }) {
51
+ function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedKeysCount = 1000, shouldSyncMultipleInstances = !!global.localStorage, enablePerformanceMetrics = false, enableDevTools = true, skippableCollectionMemberIDs = [], snapshotMergeKeys = [], }) {
52
52
  var _a;
53
53
  if (enablePerformanceMetrics) {
54
54
  GlobalSettings.setPerformanceMetricsEnabled(true);
@@ -57,6 +57,7 @@ function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedK
57
57
  (0, DevTools_1.initDevTools)(enableDevTools);
58
58
  storage_1.default.init();
59
59
  OnyxUtils_1.default.setSkippableCollectionMemberIDs(new Set(skippableCollectionMemberIDs));
60
+ OnyxUtils_1.default.setSnapshotMergeKeys(new Set(snapshotMergeKeys));
60
61
  if (shouldSyncMultipleInstances) {
61
62
  (_a = storage_1.default.keepInstancesSync) === null || _a === void 0 ? void 0 : _a.call(storage_1.default, (key, value) => {
62
63
  OnyxCache_1.default.set(key, value);
@@ -34,10 +34,18 @@ declare function getDeferredInitTask(): DeferredTask;
34
34
  * Getter - returns the skippable collection member IDs.
35
35
  */
36
36
  declare function getSkippableCollectionMemberIDs(): Set<string>;
37
+ /**
38
+ * Getter - returns the snapshot merge keys allowlist.
39
+ */
40
+ declare function getSnapshotMergeKeys(): Set<string>;
37
41
  /**
38
42
  * Setter - sets the skippable collection member IDs.
39
43
  */
40
44
  declare function setSkippableCollectionMemberIDs(ids: Set<string>): void;
45
+ /**
46
+ * Setter - sets the snapshot merge keys allowlist.
47
+ */
48
+ declare function setSnapshotMergeKeys(keys: Set<string>): void;
41
49
  /**
42
50
  * Sets the initial values for the Onyx store
43
51
  *
@@ -354,6 +362,8 @@ declare const OnyxUtils: {
354
362
  unsubscribeFromKey: typeof unsubscribeFromKey;
355
363
  getSkippableCollectionMemberIDs: typeof getSkippableCollectionMemberIDs;
356
364
  setSkippableCollectionMemberIDs: typeof setSkippableCollectionMemberIDs;
365
+ getSnapshotMergeKeys: typeof getSnapshotMergeKeys;
366
+ setSnapshotMergeKeys: typeof setSnapshotMergeKeys;
357
367
  storeKeyBySubscriptions: typeof storeKeyBySubscriptions;
358
368
  deleteKeyBySubscriptions: typeof deleteKeyBySubscriptions;
359
369
  addKeyToRecentlyAccessedIfNeeded: typeof addKeyToRecentlyAccessedIfNeeded;
package/dist/OnyxUtils.js CHANGED
@@ -38,7 +38,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.clearOnyxUtilsInternals = clearOnyxUtilsInternals;
40
40
  const fast_equals_1 = require("fast-equals");
41
- const pick_1 = __importDefault(require("lodash/pick"));
42
41
  const underscore_1 = __importDefault(require("underscore"));
43
42
  const DevTools_1 = __importDefault(require("./DevTools"));
44
43
  const Logger = __importStar(require("./Logger"));
@@ -94,6 +93,8 @@ let lastSubscriptionID = 0;
94
93
  const deferredInitTask = (0, createDeferredTask_1.default)();
95
94
  // Holds a set of collection member IDs which updates will be ignored when using Onyx methods.
96
95
  let skippableCollectionMemberIDs = new Set();
96
+ // Holds a set of keys that should always be merged into snapshot entries.
97
+ let snapshotMergeKeys = new Set();
97
98
  function getSnapshotKey() {
98
99
  return snapshotKey;
99
100
  }
@@ -127,12 +128,24 @@ function getDeferredInitTask() {
127
128
  function getSkippableCollectionMemberIDs() {
128
129
  return skippableCollectionMemberIDs;
129
130
  }
131
+ /**
132
+ * Getter - returns the snapshot merge keys allowlist.
133
+ */
134
+ function getSnapshotMergeKeys() {
135
+ return snapshotMergeKeys;
136
+ }
130
137
  /**
131
138
  * Setter - sets the skippable collection member IDs.
132
139
  */
133
140
  function setSkippableCollectionMemberIDs(ids) {
134
141
  skippableCollectionMemberIDs = ids;
135
142
  }
143
+ /**
144
+ * Setter - sets the snapshot merge keys allowlist.
145
+ */
146
+ function setSnapshotMergeKeys(keys) {
147
+ snapshotMergeKeys = keys;
148
+ }
136
149
  /**
137
150
  * Sets the initial values for the Onyx store
138
151
  *
@@ -1011,7 +1024,14 @@ function updateSnapshots(data, mergeFn) {
1011
1024
  continue;
1012
1025
  }
1013
1026
  const oldValue = updatedData[key] || {};
1014
- const newValue = (0, pick_1.default)(value, Object.keys(snapshotData[key]));
1027
+ // Snapshot entries are stored as a "shape" of the last known data per key, so by default we only
1028
+ // merge fields that already exist in the snapshot to avoid unintentionally bloating snapshot data.
1029
+ // Some clients need specific fields (like pending status) even when they are missing in the snapshot,
1030
+ // so we allow an explicit, opt-in list of keys to always include during snapshot merges.
1031
+ const snapshotExistingKeys = Object.keys(snapshotData[key] || {});
1032
+ const allowedNewKeys = getSnapshotMergeKeys();
1033
+ const keysToCopy = new Set([...snapshotExistingKeys, ...allowedNewKeys]);
1034
+ const newValue = typeof value === 'object' && value !== null ? utils_1.default.pick(value, [...keysToCopy]) : {};
1015
1035
  updatedData = Object.assign(Object.assign({}, updatedData), { [key]: Object.assign(oldValue, newValue) });
1016
1036
  }
1017
1037
  // Skip the update if there's no data to be merged
@@ -1411,6 +1431,8 @@ const OnyxUtils = {
1411
1431
  unsubscribeFromKey,
1412
1432
  getSkippableCollectionMemberIDs,
1413
1433
  setSkippableCollectionMemberIDs,
1434
+ getSnapshotMergeKeys,
1435
+ setSnapshotMergeKeys,
1414
1436
  storeKeyBySubscriptions,
1415
1437
  deleteKeyBySubscriptions,
1416
1438
  addKeyToRecentlyAccessedIfNeeded,
package/dist/types.d.ts CHANGED
@@ -364,6 +364,14 @@ type InitOptions = {
364
364
  * Additionally, any subscribers from these keys to won't receive any data from Onyx.
365
365
  */
366
366
  skippableCollectionMemberIDs?: string[];
367
+ /**
368
+ * A list of field names that should always be merged into snapshot entries even if those fields are
369
+ * missing in the snapshot. Snapshots are saved "views" of a key's data used to populate read-only
370
+ * or cached lists, and by default Onyx only merges fields that already exist in that saved view.
371
+ * Use this to opt-in to additional fields that must appear in snapshots (for example, pending flags)
372
+ * without hardcoding app-specific logic inside Onyx.
373
+ */
374
+ snapshotMergeKeys?: string[];
367
375
  };
368
376
  type GenericFunction = (...args: any[]) => any;
369
377
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-onyx",
3
- "version": "3.0.32",
3
+ "version": "3.0.33",
4
4
  "author": "Expensify, Inc.",
5
5
  "homepage": "https://expensify.com",
6
6
  "description": "State management for React Native",