react-native-onyx 1.0.2 → 1.0.5

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 CHANGED
@@ -11,6 +11,12 @@
11
11
  <dt><a href="#disconnect">disconnect(connectionID, [keyToRemoveFromEvictionBlocklist])</a></dt>
12
12
  <dd><p>Remove the listener for a react component</p>
13
13
  </dd>
14
+ <dt><a href="#notifySubscribersOnNextTick">notifySubscribersOnNextTick(key, value)</a></dt>
15
+ <dd><p>This method mostly exists for historical reasons as this library was initially designed without a memory cache and one was added later.
16
+ For this reason, Onyx works more similar to what you might expect from a native AsyncStorage with reads, writes, etc all becoming
17
+ available async. Since we have code in our main applications that might expect things to work this way it&#39;s not safe to change this
18
+ behavior just yet.</p>
19
+ </dd>
14
20
  <dt><a href="#set">set(key, value)</a> ⇒ <code>Promise</code></dt>
15
21
  <dd><p>Write a value to our store with the given key</p>
16
22
  </dd>
@@ -29,6 +35,19 @@ applied in the order they were called. Note: <code>Onyx.set()</code> calls do no
29
35
  </dd>
30
36
  <dt><a href="#clear">clear()</a> ⇒ <code>Promise.&lt;void&gt;</code></dt>
31
37
  <dd><p>Clear out all the data in the store</p>
38
+ <p>Note that calling Onyx.clear() and then Onyx.set() on a key with a default
39
+ key state may store an unexpected value in Storage.</p>
40
+ <p>E.g.
41
+ Onyx.clear();
42
+ Onyx.set(ONYXKEYS.DEFAULT_KEY, &#39;default&#39;);
43
+ Storage.getItem(ONYXKEYS.DEFAULT_KEY)
44
+ .then((storedValue) =&gt; console.log(storedValue));
45
+ null is logged instead of the expected &#39;default&#39;</p>
46
+ <p>Onyx.set() might call Storage.setItem() before Onyx.clear() calls
47
+ Storage.setItem(). Use Onyx.merge() instead if possible. Onyx.merge() calls
48
+ Onyx.get(key) before calling Storage.setItem() via Onyx.set().
49
+ Storage.setItem() from Onyx.clear() will have already finished and the merged
50
+ value will be saved to storage after the default value.</p>
32
51
  </dd>
33
52
  <dt><a href="#mergeCollection">mergeCollection(collectionKey, collection)</a> ⇒ <code>Promise</code></dt>
34
53
  <dd><p>Merges a collection based on their keys</p>
@@ -46,8 +65,8 @@ applied in the order they were called. Note: <code>Onyx.set()</code> calls do no
46
65
  ## connect(mapping) ⇒ <code>Number</code>
47
66
  Subscribes a react component's state directly to a store key
48
67
 
49
- **Kind**: global function
50
- **Returns**: <code>Number</code> - an ID to use when calling disconnect
68
+ **Kind**: global function
69
+ **Returns**: <code>Number</code> - an ID to use when calling disconnect
51
70
 
52
71
  | Param | Type | Description |
53
72
  | --- | --- | --- |
@@ -58,7 +77,7 @@ Subscribes a react component's state directly to a store key
58
77
  | [mapping.callback] | <code>function</code> | a method that will be called with changed data This is used by any non-React code to connect to Onyx |
59
78
  | [mapping.initWithStoredValues] | <code>Boolean</code> | If set to false, then no data will be prefilled into the component |
60
79
 
61
- **Example**
80
+ **Example**
62
81
  ```js
63
82
  const connectionID = Onyx.connect({
64
83
  key: ONYXKEYS.SESSION,
@@ -70,23 +89,38 @@ const connectionID = Onyx.connect({
70
89
  ## disconnect(connectionID, [keyToRemoveFromEvictionBlocklist])
71
90
  Remove the listener for a react component
72
91
 
73
- **Kind**: global function
92
+ **Kind**: global function
74
93
 
75
94
  | Param | Type | Description |
76
95
  | --- | --- | --- |
77
96
  | connectionID | <code>Number</code> | unique id returned by call to Onyx.connect() |
78
97
  | [keyToRemoveFromEvictionBlocklist] | <code>String</code> | |
79
98
 
80
- **Example**
99
+ **Example**
81
100
  ```js
82
101
  Onyx.disconnect(connectionID);
83
102
  ```
103
+ <a name="notifySubscribersOnNextTick"></a>
104
+
105
+ ## notifySubscribersOnNextTick(key, value)
106
+ This method mostly exists for historical reasons as this library was initially designed without a memory cache and one was added later.
107
+ For this reason, Onyx works more similar to what you might expect from a native AsyncStorage with reads, writes, etc all becoming
108
+ available async. Since we have code in our main applications that might expect things to work this way it's not safe to change this
109
+ behavior just yet.
110
+
111
+ **Kind**: global function
112
+
113
+ | Param | Type |
114
+ | --- | --- |
115
+ | key | <code>String</code> |
116
+ | value | <code>\*</code> |
117
+
84
118
  <a name="set"></a>
85
119
 
86
120
  ## set(key, value) ⇒ <code>Promise</code>
87
121
  Write a value to our store with the given key
88
122
 
89
- **Kind**: global function
123
+ **Kind**: global function
90
124
 
91
125
  | Param | Type | Description |
92
126
  | --- | --- | --- |
@@ -98,13 +132,13 @@ Write a value to our store with the given key
98
132
  ## multiSet(data) ⇒ <code>Promise</code>
99
133
  Sets multiple keys and values
100
134
 
101
- **Kind**: global function
135
+ **Kind**: global function
102
136
 
103
137
  | Param | Type | Description |
104
138
  | --- | --- | --- |
105
139
  | data | <code>Object</code> | object keyed by ONYXKEYS and the values to set |
106
140
 
107
- **Example**
141
+ **Example**
108
142
  ```js
109
143
  Onyx.multiSet({'key1': 'a', 'key2': 'b'});
110
144
  ```
@@ -122,14 +156,14 @@ Calls to `Onyx.merge()` are batched so that any calls performed in a single tick
122
156
  applied in the order they were called. Note: `Onyx.set()` calls do not work this way so use caution when mixing
123
157
  `Onyx.merge()` and `Onyx.set()`.
124
158
 
125
- **Kind**: global function
159
+ **Kind**: global function
126
160
 
127
161
  | Param | Type | Description |
128
162
  | --- | --- | --- |
129
163
  | key | <code>String</code> | ONYXKEYS key |
130
164
  | value | <code>Object</code> \| <code>Array</code> | Object or Array value to merge |
131
165
 
132
- **Example**
166
+ **Example**
133
167
  ```js
134
168
  Onyx.merge(ONYXKEYS.EMPLOYEE_LIST, ['Joe']); // -> ['Joe']
135
169
  Onyx.merge(ONYXKEYS.EMPLOYEE_LIST, ['Jack']); // -> ['Joe', 'Jack']
@@ -141,20 +175,36 @@ Onyx.merge(ONYXKEYS.POLICY, {name: 'My Workspace'}); // -> {id: 1, name: 'My Wor
141
175
  ## clear() ⇒ <code>Promise.&lt;void&gt;</code>
142
176
  Clear out all the data in the store
143
177
 
144
- **Kind**: global function
178
+ Note that calling Onyx.clear() and then Onyx.set() on a key with a default
179
+ key state may store an unexpected value in Storage.
180
+
181
+ E.g.
182
+ Onyx.clear();
183
+ Onyx.set(ONYXKEYS.DEFAULT_KEY, 'default');
184
+ Storage.getItem(ONYXKEYS.DEFAULT_KEY)
185
+ .then((storedValue) => console.log(storedValue));
186
+ null is logged instead of the expected 'default'
187
+
188
+ Onyx.set() might call Storage.setItem() before Onyx.clear() calls
189
+ Storage.setItem(). Use Onyx.merge() instead if possible. Onyx.merge() calls
190
+ Onyx.get(key) before calling Storage.setItem() via Onyx.set().
191
+ Storage.setItem() from Onyx.clear() will have already finished and the merged
192
+ value will be saved to storage after the default value.
193
+
194
+ **Kind**: global function
145
195
  <a name="mergeCollection"></a>
146
196
 
147
197
  ## mergeCollection(collectionKey, collection) ⇒ <code>Promise</code>
148
198
  Merges a collection based on their keys
149
199
 
150
- **Kind**: global function
200
+ **Kind**: global function
151
201
 
152
202
  | Param | Type | Description |
153
203
  | --- | --- | --- |
154
204
  | collectionKey | <code>String</code> | e.g. `ONYXKEYS.COLLECTION.REPORT` |
155
205
  | collection | <code>Object</code> | Object collection keyed by individual collection member keys and values |
156
206
 
157
- **Example**
207
+ **Example**
158
208
  ```js
159
209
  Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT, {
160
210
  [`${ONYXKEYS.COLLECTION.REPORT}1`]: report1,
@@ -166,7 +216,7 @@ Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT, {
166
216
  ## update(data)
167
217
  Insert API responses and lifecycle data into Onyx
168
218
 
169
- **Kind**: global function
219
+ **Kind**: global function
170
220
 
171
221
  | Param | Type | Description |
172
222
  | --- | --- | --- |
@@ -177,7 +227,7 @@ Insert API responses and lifecycle data into Onyx
177
227
  ## init([options])
178
228
  Initialize the store with actions and listening for storage events
179
229
 
180
- **Kind**: global function
230
+ **Kind**: global function
181
231
 
182
232
  | Param | Type | Default | Description |
183
233
  | --- | --- | --- | --- |
@@ -190,7 +240,7 @@ Initialize the store with actions and listening for storage events
190
240
  | [options.shouldSyncMultipleInstances] | <code>Boolean</code> | | Auto synchronize storage events between multiple instances of Onyx running in different tabs/windows. Defaults to true for platforms that support local storage (web/desktop) |
191
241
  | [option.keysToDisableSyncEvents] | <code>Array.&lt;String&gt;</code> | <code>[]</code> | Contains keys for which we want to disable sync event across tabs. |
192
242
 
193
- **Example**
243
+ **Example**
194
244
  ```js
195
245
  Onyx.init({
196
246
  keys: ONYXKEYS,
package/README.md CHANGED
@@ -20,7 +20,7 @@ Persistent storage solution wrapped in a Pub/Sub library.
20
20
  Onyx is published to [`npm`](https://www.npmjs.com/package/react-native-onyx)
21
21
 
22
22
  ```shell
23
- npm install react-native-onyx --save
23
+ npm install react-native-onyx --save
24
24
  ```
25
25
 
26
26
  ## Initialization
@@ -42,8 +42,8 @@ Onyx.init(config);
42
42
  ```
43
43
 
44
44
  ### Usage in non react-native projects
45
- Onyx can be used in non react-native projects, by leveraging the `browser` field in `package.json`
46
- Bundlers like Webpack respect that field and import code from the specified path
45
+ Onyx can be used in non react-native projects, by leveraging the `browser` field in `package.json`
46
+ Bundlers like Webpack respect that field and import code from the specified path
47
47
  We import Onyx the same way shown above - `import Onyx from 'react-native-onyx'`
48
48
 
49
49
  ## Setting data
@@ -148,7 +148,7 @@ Under the hood storage access calls are delegated to a [`StorageProvider`](lib/s
148
148
  Some platforms (like web and desktop) might use the same storage provider
149
149
 
150
150
  If a platform needs to use a separate library (like using MMVK for react-native) it should be added in the following way:
151
- 1. Create a `StorageProvider.js` at [lib/storage/providers](lib/storage/providers)
151
+ 1. Create a `StorageProvider.js` at [lib/storage/providers](lib/storage/providers)
152
152
  Reference an existing [StorageProvider](lib/storage/providers/AsyncStorage.js) for the interface that has to be implemented
153
153
  2. Update the factory at [lib/storage/index.web.js](lib/storage/index.web.js) and [lib/storage/index.native.js](lib/storage/index.native.js) to return the newly created Provider for the desired Platform(s)
154
154
 
@@ -1,13 +1,13 @@
1
1
  (function webpackUniversalModuleDefinition(root, factory) {
2
2
  if(typeof exports === 'object' && typeof module === 'object')
3
- module.exports = factory(require("underscore"), require("expensify-common/lib/str"), require("lodash/merge"), require("localforage"), require("react"));
3
+ module.exports = factory(require("underscore"), require("expensify-common/lib/str"), require("lodash/merge"), require("lodash/get"), require("localforage"), require("react"));
4
4
  else if(typeof define === 'function' && define.amd)
5
- define(["underscore", "expensify-common/lib/str", "lodash/merge", "localforage", "react"], factory);
5
+ define(["underscore", "expensify-common/lib/str", "lodash/merge", "lodash/get", "localforage", "react"], factory);
6
6
  else if(typeof exports === 'object')
7
- exports["react-native-onyx/web"] = factory(require("underscore"), require("expensify-common/lib/str"), require("lodash/merge"), require("localforage"), require("react"));
7
+ exports["react-native-onyx/web"] = factory(require("underscore"), require("expensify-common/lib/str"), require("lodash/merge"), require("lodash/get"), require("localforage"), require("react"));
8
8
  else
9
- root["react-native-onyx/web"] = factory(root["underscore"], root["expensify-common/lib/str"], root["lodash/merge"], root["localforage"], root["react"]);
10
- })(self, (__WEBPACK_EXTERNAL_MODULE_underscore__, __WEBPACK_EXTERNAL_MODULE_expensify_common_lib_str__, __WEBPACK_EXTERNAL_MODULE_lodash_merge__, __WEBPACK_EXTERNAL_MODULE_localforage__, __WEBPACK_EXTERNAL_MODULE_react__) => {
9
+ root["react-native-onyx/web"] = factory(root["underscore"], root["expensify-common/lib/str"], root["lodash/merge"], root["lodash/get"], root["localforage"], root["react"]);
10
+ })(self, (__WEBPACK_EXTERNAL_MODULE_underscore__, __WEBPACK_EXTERNAL_MODULE_expensify_common_lib_str__, __WEBPACK_EXTERNAL_MODULE_lodash_merge__, __WEBPACK_EXTERNAL_MODULE_lodash_get__, __WEBPACK_EXTERNAL_MODULE_localforage__, __WEBPACK_EXTERNAL_MODULE_react__) => {
11
11
  return /******/ (() => { // webpackBootstrap
12
12
  /******/ var __webpack_modules__ = ({
13
13
 
@@ -492,6 +492,7 @@ function logInfo(message) {
492
492
  var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "./node_modules/@babel/runtime/helpers/interopRequireDefault.js");Object.defineProperty(exports, "__esModule", ({ value: true }));exports["default"] = void 0;var _slicedToArray2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/slicedToArray */ "./node_modules/@babel/runtime/helpers/slicedToArray.js"));var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ "./node_modules/@babel/runtime/helpers/toConsumableArray.js"));var _defineProperty2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "./node_modules/@babel/runtime/helpers/defineProperty.js"));var _extends4 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "./node_modules/@babel/runtime/helpers/extends.js"));var _underscore = _interopRequireDefault(__webpack_require__(/*! underscore */ "underscore"));
493
493
  var _str = _interopRequireDefault(__webpack_require__(/*! expensify-common/lib/str */ "expensify-common/lib/str"));
494
494
  var _merge = _interopRequireDefault(__webpack_require__(/*! lodash/merge */ "lodash/merge"));
495
+ var _get = _interopRequireDefault(__webpack_require__(/*! lodash/get */ "lodash/get"));
495
496
  var _storage = _interopRequireDefault(__webpack_require__(/*! ./storage */ "./lib/storage/index.web.js"));
496
497
  var Logger = _interopRequireWildcard(__webpack_require__(/*! ./Logger */ "./lib/Logger.js"));
497
498
  var _OnyxCache = _interopRequireDefault(__webpack_require__(/*! ./OnyxCache */ "./lib/OnyxCache.js"));
@@ -970,6 +971,20 @@ function disconnect(connectionID, keyToRemoveFromEvictionBlocklist) {
970
971
  delete callbackToStateMapping[connectionID];
971
972
  }
972
973
 
974
+ /**
975
+ * This method mostly exists for historical reasons as this library was initially designed without a memory cache and one was added later.
976
+ * For this reason, Onyx works more similar to what you might expect from a native AsyncStorage with reads, writes, etc all becoming
977
+ * available async. Since we have code in our main applications that might expect things to work this way it's not safe to change this
978
+ * behavior just yet.
979
+ *
980
+ * @param {String} key
981
+ * @param {*} value
982
+ */
983
+ // eslint-disable-next-line rulesdir/no-negated-variables
984
+ function notifySubscribersOnNextTick(key, value) {
985
+ Promise.resolve().then(function () {return keyChanged(key, value);});
986
+ }
987
+
973
988
  /**
974
989
  * Remove a key from Onyx and update the subscribers
975
990
  *
@@ -980,10 +995,7 @@ function disconnect(connectionID, keyToRemoveFromEvictionBlocklist) {
980
995
  function remove(key) {
981
996
  // Cache the fact that the value was removed
982
997
  _OnyxCache.default.set(key, null);
983
-
984
- // Optimistically inform subscribers on the next tick
985
- Promise.resolve().then(function () {return keyChanged(key, null);});
986
-
998
+ notifySubscribersOnNextTick(key, null);
987
999
  return _storage.default.removeItem(key);
988
1000
  }
989
1001
 
@@ -1039,9 +1051,7 @@ function set(key, value) {
1039
1051
 
1040
1052
  // Adds the key to cache when it's not available
1041
1053
  _OnyxCache.default.set(key, value);
1042
-
1043
- // Optimistically inform subscribers on the next tick
1044
- Promise.resolve().then(function () {return keyChanged(key, value);});
1054
+ notifySubscribersOnNextTick(key, value);
1045
1055
 
1046
1056
  // Write the thing to persistent storage, which will trigger a storage event for any other tabs open on this domain
1047
1057
  return _storage.default.setItem(key, value).
@@ -1074,7 +1084,7 @@ function multiSet(data) {
1074
1084
  _underscore.default.each(data, function (val, key) {
1075
1085
  // Update cache and optimistically inform subscribers on the next tick
1076
1086
  _OnyxCache.default.set(key, val);
1077
- Promise.resolve().then(function () {return keyChanged(key, val);});
1087
+ notifySubscribersOnNextTick(key, val);
1078
1088
  });
1079
1089
 
1080
1090
  return _storage.default.multiSet(keyValuePairs).
@@ -1199,18 +1209,34 @@ function initializeWithDefaultKeyStates() {
1199
1209
  /**
1200
1210
  * Clear out all the data in the store
1201
1211
  *
1212
+ * Note that calling Onyx.clear() and then Onyx.set() on a key with a default
1213
+ * key state may store an unexpected value in Storage.
1214
+ *
1215
+ * E.g.
1216
+ * Onyx.clear();
1217
+ * Onyx.set(ONYXKEYS.DEFAULT_KEY, 'default');
1218
+ * Storage.getItem(ONYXKEYS.DEFAULT_KEY)
1219
+ * .then((storedValue) => console.log(storedValue));
1220
+ * null is logged instead of the expected 'default'
1221
+ *
1222
+ * Onyx.set() might call Storage.setItem() before Onyx.clear() calls
1223
+ * Storage.setItem(). Use Onyx.merge() instead if possible. Onyx.merge() calls
1224
+ * Onyx.get(key) before calling Storage.setItem() via Onyx.set().
1225
+ * Storage.setItem() from Onyx.clear() will have already finished and the merged
1226
+ * value will be saved to storage after the default value.
1227
+ *
1202
1228
  * @returns {Promise<void>}
1203
1229
  */
1204
1230
  function clear() {
1205
1231
  return getAllKeys().
1206
1232
  then(function (keys) {
1207
1233
  _underscore.default.each(keys, function (key) {
1208
- keyChanged(key, null);
1209
- _OnyxCache.default.set(key, null);
1234
+ var resetValue = (0, _get.default)(defaultKeyStates, key, null);
1235
+ _OnyxCache.default.set(key, resetValue);
1236
+ notifySubscribersOnNextTick(key, resetValue);
1210
1237
  });
1211
- }).
1212
- then(_storage.default.clear).
1213
- then(initializeWithDefaultKeyStates);
1238
+ return _storage.default.clear();
1239
+ });
1214
1240
  }
1215
1241
 
1216
1242
  /**
@@ -3235,6 +3261,17 @@ module.exports = __WEBPACK_EXTERNAL_MODULE_localforage__;
3235
3261
 
3236
3262
  /***/ }),
3237
3263
 
3264
+ /***/ "lodash/get":
3265
+ /*!*****************************!*\
3266
+ !*** external "lodash/get" ***!
3267
+ \*****************************/
3268
+ /***/ ((module) => {
3269
+
3270
+ "use strict";
3271
+ module.exports = __WEBPACK_EXTERNAL_MODULE_lodash_get__;
3272
+
3273
+ /***/ }),
3274
+
3238
3275
  /***/ "lodash/merge":
3239
3276
  /*!*******************************!*\
3240
3277
  !*** external "lodash/merge" ***!