react-native-onyx 2.0.21 → 2.0.23

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.
Files changed (41) hide show
  1. package/API.md +49 -64
  2. package/dist/DevTools.js +0 -1
  3. package/dist/Onyx.d.ts +49 -258
  4. package/dist/Onyx.js +192 -1165
  5. package/dist/OnyxCache.d.ts +14 -15
  6. package/dist/OnyxUtils.d.ts +320 -0
  7. package/dist/OnyxUtils.js +1061 -0
  8. package/dist/PerformanceUtils.d.ts +3 -5
  9. package/dist/index.d.ts +3 -2
  10. package/dist/storage/InstanceSync/index.d.ts +14 -0
  11. package/dist/storage/InstanceSync/index.js +20 -0
  12. package/dist/storage/InstanceSync/index.web.d.ts +27 -0
  13. package/dist/storage/InstanceSync/index.web.js +59 -0
  14. package/dist/storage/__mocks__/index.d.ts +15 -13
  15. package/dist/storage/__mocks__/index.js +43 -81
  16. package/dist/storage/index.d.ts +6 -2
  17. package/dist/storage/index.js +170 -2
  18. package/dist/storage/platforms/index.d.ts +2 -0
  19. package/dist/storage/{NativeStorage.js → platforms/index.js} +2 -2
  20. package/dist/storage/platforms/index.native.d.ts +2 -0
  21. package/dist/storage/{index.native.js → platforms/index.native.js} +2 -2
  22. package/dist/storage/providers/{IDBKeyVal.js → IDBKeyValProvider.js} +23 -19
  23. package/dist/storage/providers/MemoryOnlyProvider.d.ts +9 -0
  24. package/dist/storage/providers/MemoryOnlyProvider.js +124 -0
  25. package/dist/storage/providers/NoopProvider.js +85 -0
  26. package/dist/storage/providers/SQLiteProvider.d.ts +3 -0
  27. package/dist/storage/providers/{SQLiteStorage.js → SQLiteProvider.js} +17 -11
  28. package/dist/storage/providers/types.d.ts +17 -14
  29. package/dist/types.d.ts +128 -55
  30. package/dist/types.js +2 -0
  31. package/dist/useOnyx.js +11 -10
  32. package/dist/utils.d.ts +2 -2
  33. package/dist/utils.js +29 -16
  34. package/dist/withOnyx.js +6 -5
  35. package/package.json +1 -1
  36. package/dist/storage/NativeStorage.d.ts +0 -2
  37. package/dist/storage/WebStorage.d.ts +0 -3
  38. package/dist/storage/WebStorage.js +0 -62
  39. package/dist/storage/index.native.d.ts +0 -2
  40. /package/dist/storage/providers/{IDBKeyVal.d.ts → IDBKeyValProvider.d.ts} +0 -0
  41. /package/dist/storage/providers/{SQLiteStorage.d.ts → NoopProvider.d.ts} +0 -0
package/dist/utils.js CHANGED
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ /* eslint-disable @typescript-eslint/prefer-for-of */
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  /** Checks whether the given object is an object and not null/undefined. */
4
5
  function isEmptyObject(obj) {
@@ -9,8 +10,8 @@ function isEmptyObject(obj) {
9
10
  * Checks whether the given value can be merged. It has to be an object, but not an array, RegExp or Date.
10
11
  */
11
12
  function isMergeableObject(value) {
12
- const nonNullObject = value != null ? typeof value === 'object' : false;
13
- return nonNullObject && Object.prototype.toString.call(value) !== '[object RegExp]' && Object.prototype.toString.call(value) !== '[object Date]' && !Array.isArray(value);
13
+ const isNonNullObject = value != null ? typeof value === 'object' : false;
14
+ return isNonNullObject && Object.prototype.toString.call(value) !== '[object RegExp]' && Object.prototype.toString.call(value) !== '[object Date]' && !Array.isArray(value);
14
15
  }
15
16
  /**
16
17
  * Merges the source object into the target object.
@@ -21,37 +22,49 @@ function isMergeableObject(value) {
21
22
  */
22
23
  function mergeObject(target, source, shouldRemoveNullObjectValues = true) {
23
24
  const destination = {};
25
+ // First we want to copy over all keys from the target into the destination object,
26
+ // in case "target" is a mergable object.
27
+ // If "shouldRemoveNullObjectValues" is true, we want to remove null values from the merged object
28
+ // and therefore we need to omit keys where either the source or target value is null.
24
29
  if (isMergeableObject(target)) {
25
- // lodash adds a small overhead so we don't use it here
26
30
  const targetKeys = Object.keys(target);
27
31
  for (let i = 0; i < targetKeys.length; ++i) {
28
32
  const key = targetKeys[i];
29
33
  const sourceValue = source === null || source === void 0 ? void 0 : source[key];
30
34
  const targetValue = target === null || target === void 0 ? void 0 : target[key];
31
- // If shouldRemoveNullObjectValues is true, we want to remove null values from the merged object
35
+ // If "shouldRemoveNullObjectValues" is true, we want to remove null values from the merged object.
36
+ // Therefore, if either target or source value is null, we want to prevent the key from being set.
32
37
  const isSourceOrTargetNull = targetValue === null || sourceValue === null;
33
- const shouldOmitSourceKey = shouldRemoveNullObjectValues && isSourceOrTargetNull;
34
- if (!shouldOmitSourceKey) {
38
+ const shouldOmitTargetKey = shouldRemoveNullObjectValues && isSourceOrTargetNull;
39
+ if (!shouldOmitTargetKey) {
35
40
  destination[key] = targetValue;
36
41
  }
37
42
  }
38
43
  }
44
+ // After copying over all keys from the target object, we want to merge the source object into the destination object.
39
45
  const sourceKeys = Object.keys(source);
40
46
  for (let i = 0; i < sourceKeys.length; ++i) {
41
47
  const key = sourceKeys[i];
42
48
  const sourceValue = source === null || source === void 0 ? void 0 : source[key];
43
49
  const targetValue = target === null || target === void 0 ? void 0 : target[key];
44
- // If shouldRemoveNullObjectValues is true, we want to remove null values from the merged object
45
- const shouldOmitSourceKey = shouldRemoveNullObjectValues && sourceValue === null;
46
- // If we pass undefined as the updated value for a key, we want to generally ignore it
47
- const isSourceKeyUndefined = sourceValue === undefined;
48
- if (!isSourceKeyUndefined && !shouldOmitSourceKey) {
49
- const isSourceKeyMergable = isMergeableObject(sourceValue);
50
- if (isSourceKeyMergable && targetValue) {
51
- // eslint-disable-next-line no-use-before-define
52
- destination[key] = fastMerge(targetValue, sourceValue, shouldRemoveNullObjectValues);
50
+ // If undefined is passed as the source value for a key, we want to generally ignore it.
51
+ // If "shouldRemoveNullObjectValues" is set to true and the source value is null,
52
+ // we don't want to set/merge the source value into the merged object.
53
+ const shouldIgnoreNullSourceValue = shouldRemoveNullObjectValues && sourceValue === null;
54
+ const shouldOmitSourceKey = sourceValue === undefined || shouldIgnoreNullSourceValue;
55
+ if (!shouldOmitSourceKey) {
56
+ // If the source value is a mergable object, we want to merge it into the target value.
57
+ // If "shouldRemoveNullObjectValues" is true, "fastMerge" will recursively
58
+ // remove nested null values from the merged object.
59
+ // If source value is any other value we need to set the source value it directly.
60
+ if (isMergeableObject(sourceValue)) {
61
+ // If the target value is null or undefined, we need to fallback to an empty object,
62
+ // so that we can still use "fastMerge" to merge the source value,
63
+ // to ensure that nested null values are removed from the merged object.
64
+ const targetValueWithFallback = (targetValue !== null && targetValue !== void 0 ? targetValue : {});
65
+ destination[key] = fastMerge(targetValueWithFallback, sourceValue, shouldRemoveNullObjectValues);
53
66
  }
54
- else if (!shouldRemoveNullObjectValues || sourceValue !== null) {
67
+ else {
55
68
  destination[key] = sourceValue;
56
69
  }
57
70
  }
package/dist/withOnyx.js CHANGED
@@ -37,6 +37,7 @@ const underscore_1 = __importDefault(require("underscore"));
37
37
  const Onyx_1 = __importDefault(require("./Onyx"));
38
38
  const Str = __importStar(require("./Str"));
39
39
  const utils_1 = __importDefault(require("./utils"));
40
+ const OnyxUtils_1 = __importDefault(require("./OnyxUtils"));
40
41
  // 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
42
  // if a key has changed, it's a good idea to skip looking at these properties since they would have unexpected results.
42
43
  const mappingPropertiesToIgnoreChangesTo = ['initialValue', 'allowStaleData'];
@@ -77,7 +78,7 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
77
78
  this.activeConnectionIDs = {};
78
79
  const cachedState = underscore_1.default.reduce(mapOnyxToState, (resultObj, mapping, propertyName) => {
79
80
  const key = Str.result(mapping.key, props);
80
- let value = Onyx_1.default.tryGetCachedValue(key, mapping);
81
+ let value = OnyxUtils_1.default.tryGetCachedValue(key, mapping);
81
82
  if (!value && mapping.initialValue) {
82
83
  value = mapping.initialValue;
83
84
  }
@@ -92,7 +93,7 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
92
93
  * In reality, Onyx.merge() will only update the subscriber after all merges have been batched and the previous value is retrieved via a get() (returns a promise).
93
94
  * So, we won't use the cache optimization here as it will lead us to arbitrarily defer various actions in the application code.
94
95
  */
95
- if ((value !== undefined && !Onyx_1.default.hasPendingMergeForKey(key)) || mapping.allowStaleData) {
96
+ if ((value !== undefined && !OnyxUtils_1.default.hasPendingMergeForKey(key)) || mapping.allowStaleData) {
96
97
  // eslint-disable-next-line no-param-reassign
97
98
  resultObj[propertyName] = value;
98
99
  }
@@ -246,14 +247,14 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
246
247
  }
247
248
  const canEvict = Str.result(mapping.canEvict, this.props);
248
249
  const key = Str.result(mapping.key, this.props);
249
- if (!Onyx_1.default.isSafeEvictionKey(key)) {
250
+ if (!OnyxUtils_1.default.isSafeEvictionKey(key)) {
250
251
  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: []}).`);
251
252
  }
252
253
  if (canEvict) {
253
- Onyx_1.default.removeFromEvictionBlockList(key, mapping.connectionID);
254
+ OnyxUtils_1.default.removeFromEvictionBlockList(key, mapping.connectionID);
254
255
  }
255
256
  else {
256
- Onyx_1.default.addToEvictionBlockList(key, mapping.connectionID);
257
+ OnyxUtils_1.default.addToEvictionBlockList(key, mapping.connectionID);
257
258
  }
258
259
  });
259
260
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-onyx",
3
- "version": "2.0.21",
3
+ "version": "2.0.23",
4
4
  "author": "Expensify, Inc.",
5
5
  "homepage": "https://expensify.com",
6
6
  "description": "State management for React Native",
@@ -1,2 +0,0 @@
1
- import SQLiteStorage from './providers/SQLiteStorage';
2
- export default SQLiteStorage;
@@ -1,3 +0,0 @@
1
- import type StorageProvider from './providers/types';
2
- declare const webStorage: StorageProvider;
3
- export default webStorage;
@@ -1,62 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- /**
7
- * This file is here to wrap IDBKeyVal with a layer that provides data-changed events like the ones that exist
8
- * when using LocalStorage APIs in the browser. These events are great because multiple tabs can listen for when
9
- * data changes and then stay up-to-date with everything happening in Onyx.
10
- */
11
- const IDBKeyVal_1 = __importDefault(require("./providers/IDBKeyVal"));
12
- const SYNC_ONYX = 'SYNC_ONYX';
13
- /**
14
- * Raise an event thorough `localStorage` to let other tabs know a value changed
15
- */
16
- function raiseStorageSyncEvent(onyxKey) {
17
- global.localStorage.setItem(SYNC_ONYX, onyxKey);
18
- global.localStorage.removeItem(SYNC_ONYX);
19
- }
20
- function raiseStorageSyncManyKeysEvent(onyxKeys) {
21
- onyxKeys.forEach((onyxKey) => {
22
- raiseStorageSyncEvent(onyxKey);
23
- });
24
- }
25
- const webStorage = Object.assign(Object.assign({}, IDBKeyVal_1.default), {
26
- /**
27
- * @param onStorageKeyChanged Storage synchronization mechanism keeping all opened tabs in sync
28
- */
29
- keepInstancesSync(onStorageKeyChanged) {
30
- // Override set, remove and clear to raise storage events that we intercept in other tabs
31
- this.setItem = (key, value) => IDBKeyVal_1.default.setItem(key, value).then(() => raiseStorageSyncEvent(key));
32
- this.removeItem = (key) => IDBKeyVal_1.default.removeItem(key).then(() => raiseStorageSyncEvent(key));
33
- this.removeItems = (keys) => IDBKeyVal_1.default.removeItems(keys).then(() => raiseStorageSyncManyKeysEvent(keys));
34
- this.mergeItem = (key, batchedChanges, modifiedData) => IDBKeyVal_1.default.mergeItem(key, batchedChanges, modifiedData).then(() => raiseStorageSyncEvent(key));
35
- // If we just call Storage.clear other tabs will have no idea which keys were available previously
36
- // so that they can call keysChanged for them. That's why we iterate over every key and raise a storage sync
37
- // event for each one
38
- this.clear = () => {
39
- let allKeys;
40
- // The keys must be retrieved before storage is cleared or else the list of keys would be empty
41
- return IDBKeyVal_1.default.getAllKeys()
42
- .then((keys) => {
43
- allKeys = keys;
44
- })
45
- .then(() => IDBKeyVal_1.default.clear())
46
- .then(() => {
47
- // Now that storage is cleared, the storage sync event can happen which is a more atomic action
48
- // for other browser tabs
49
- allKeys.forEach(raiseStorageSyncEvent);
50
- });
51
- };
52
- // This listener will only be triggered by events coming from other tabs
53
- global.addEventListener('storage', (event) => {
54
- // Ignore events that don't originate from the SYNC_ONYX logic
55
- if (event.key !== SYNC_ONYX || !event.newValue) {
56
- return;
57
- }
58
- const onyxKey = event.newValue;
59
- IDBKeyVal_1.default.getItem(onyxKey).then((value) => onStorageKeyChanged(onyxKey, value));
60
- });
61
- } });
62
- exports.default = webStorage;
@@ -1,2 +0,0 @@
1
- import NativeStorage from './NativeStorage';
2
- export default NativeStorage;