react-native-onyx 1.0.131 → 2.0.1

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 (64) hide show
  1. package/API.md +83 -22
  2. package/README.md +3 -5
  3. package/dist/DevTools.d.ts +23 -0
  4. package/{lib → dist}/DevTools.js +16 -18
  5. package/dist/Logger.js +32 -0
  6. package/dist/MDTable.d.ts +36 -0
  7. package/{lib → dist}/MDTable.js +12 -17
  8. package/{lib → dist}/Onyx.js +278 -477
  9. package/dist/OnyxCache.d.ts +121 -0
  10. package/{lib → dist}/OnyxCache.js +16 -53
  11. package/{lib/Str.js → dist/Str.d.ts} +2 -11
  12. package/dist/Str.js +31 -0
  13. package/dist/SyncQueue.d.ts +32 -0
  14. package/{lib → dist}/SyncQueue.js +9 -11
  15. package/dist/batch.d.ts +2 -0
  16. package/dist/batch.js +4 -0
  17. package/dist/batch.native.d.ts +2 -0
  18. package/dist/batch.native.js +4 -0
  19. package/dist/compose.d.ts +19 -0
  20. package/{lib → dist}/compose.js +5 -8
  21. package/dist/createDeferredTask.d.ts +12 -0
  22. package/{lib → dist}/createDeferredTask.js +4 -2
  23. package/dist/index.d.ts +6 -0
  24. package/dist/index.js +10 -0
  25. package/dist/metrics/PerformanceUtils.d.ts +14 -0
  26. package/{lib → dist}/metrics/PerformanceUtils.js +16 -16
  27. package/dist/metrics/index.d.ts +4 -0
  28. package/dist/metrics/index.js +14 -0
  29. package/dist/metrics/index.native.d.ts +43 -0
  30. package/{lib → dist}/metrics/index.native.js +80 -102
  31. package/{lib/storage/NativeStorage.js → dist/storage/NativeStorage.d.ts} +1 -2
  32. package/dist/storage/NativeStorage.js +7 -0
  33. package/dist/storage/WebStorage.d.ts +19 -0
  34. package/{lib → dist}/storage/WebStorage.js +24 -34
  35. package/dist/storage/__mocks__/index.d.ts +23 -0
  36. package/{lib → dist}/storage/__mocks__/index.js +17 -19
  37. package/{lib/storage/index.web.js → dist/storage/index.d.ts} +1 -2
  38. package/dist/storage/index.js +7 -0
  39. package/{lib/storage/index.native.js → dist/storage/index.native.d.ts} +1 -2
  40. package/dist/storage/index.native.js +7 -0
  41. package/dist/storage/providers/IDBKeyVal.d.ts +26 -0
  42. package/{lib → dist}/storage/providers/IDBKeyVal.js +38 -52
  43. package/dist/storage/providers/SQLiteStorage.d.ts +52 -0
  44. package/{lib → dist}/storage/providers/SQLiteStorage.js +27 -42
  45. package/{lib → dist}/utils.js +14 -27
  46. package/{lib → dist}/withOnyx.js +122 -159
  47. package/package.json +23 -54
  48. package/dist/web.development.js +0 -4308
  49. package/dist/web.development.js.map +0 -1
  50. package/dist/web.min.js +0 -2
  51. package/dist/web.min.js.map +0 -1
  52. package/lib/Logger.js +0 -31
  53. package/lib/batch.js +0 -3
  54. package/lib/batch.native.js +0 -3
  55. package/lib/index.d.ts +0 -6
  56. package/lib/index.js +0 -5
  57. package/lib/metrics/index.web.js +0 -10
  58. package/native.js +0 -11
  59. package/web.js +0 -12
  60. /package/{lib → dist}/Logger.d.ts +0 -0
  61. /package/{lib → dist}/Onyx.d.ts +0 -0
  62. /package/{lib → dist}/types.d.ts +0 -0
  63. /package/{lib → dist}/utils.d.ts +0 -0
  64. /package/{lib → dist}/withOnyx.d.ts +0 -0
@@ -1,15 +1,19 @@
1
- import lodashTransform from 'lodash/transform';
2
- import _ from 'underscore';
3
-
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
+ exports.setShouldDebugSetState = exports.logSetStateCall = void 0;
7
+ const transform_1 = __importDefault(require("lodash/transform"));
8
+ const underscore_1 = __importDefault(require("underscore"));
4
9
  let debugSetState = false;
5
-
6
10
  /**
7
11
  * @param {Boolean} debug
8
12
  */
9
13
  function setShouldDebugSetState(debug) {
10
14
  debugSetState = debug;
11
15
  }
12
-
16
+ exports.setShouldDebugSetState = setShouldDebugSetState;
13
17
  /**
14
18
  * Deep diff between two objects. Useful for figuring out what changed about an object from one render to the next so
15
19
  * that state and props updates can be optimized.
@@ -20,18 +24,16 @@ function setShouldDebugSetState(debug) {
20
24
  */
21
25
  function diffObject(object, base) {
22
26
  function changes(obj, comparisonObject) {
23
- return lodashTransform(obj, (result, value, key) => {
24
- if (_.isEqual(value, comparisonObject[key])) {
27
+ return (0, transform_1.default)(obj, (result, value, key) => {
28
+ if (underscore_1.default.isEqual(value, comparisonObject[key])) {
25
29
  return;
26
30
  }
27
-
28
31
  // eslint-disable-next-line no-param-reassign
29
- result[key] = _.isObject(value) && _.isObject(comparisonObject[key]) ? changes(value, comparisonObject[key]) : value;
32
+ result[key] = underscore_1.default.isObject(value) && underscore_1.default.isObject(comparisonObject[key]) ? changes(value, comparisonObject[key]) : value;
30
33
  });
31
34
  }
32
35
  return changes(object, base);
33
36
  }
34
-
35
37
  /**
36
38
  * Provide insights into why a setState() call occurred by diffing the before and after values.
37
39
  *
@@ -45,19 +47,17 @@ function logSetStateCall(mapping, previousValue, newValue, caller, keyThatChange
45
47
  if (!debugSetState) {
46
48
  return;
47
49
  }
48
-
49
50
  const logParams = {};
50
51
  if (keyThatChanged) {
51
52
  logParams.keyThatChanged = keyThatChanged;
52
53
  }
53
- if (_.isObject(newValue) && _.isObject(previousValue)) {
54
+ if (underscore_1.default.isObject(newValue) && underscore_1.default.isObject(previousValue)) {
54
55
  logParams.difference = diffObject(previousValue, newValue);
55
- } else {
56
+ }
57
+ else {
56
58
  logParams.previousValue = previousValue;
57
59
  logParams.newValue = newValue;
58
60
  }
59
-
60
61
  console.debug(`[Onyx-Debug] ${mapping.displayName} setState() called. Subscribed to key '${mapping.key}' (${caller})`, logParams);
61
62
  }
62
-
63
- export {logSetStateCall, setShouldDebugSetState};
63
+ exports.logSetStateCall = logSetStateCall;
@@ -0,0 +1,4 @@
1
+ export function decorateWithMetrics(func: any): any;
2
+ export function getMetrics(): void;
3
+ export function resetMetrics(): void;
4
+ export function printMetrics(): void;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ // For web-only implementations of Onyx, this module will just be a no-op
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.printMetrics = exports.resetMetrics = exports.getMetrics = exports.decorateWithMetrics = void 0;
5
+ function decorateWithMetrics(func) {
6
+ return func;
7
+ }
8
+ exports.decorateWithMetrics = decorateWithMetrics;
9
+ function getMetrics() { }
10
+ exports.getMetrics = getMetrics;
11
+ function printMetrics() { }
12
+ exports.printMetrics = printMetrics;
13
+ function resetMetrics() { }
14
+ exports.resetMetrics = resetMetrics;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Wraps a function with metrics capturing logic
3
+ * @param {function} func
4
+ * @param {String} [alias]
5
+ * @returns {function} The wrapped function
6
+ */
7
+ export function decorateWithMetrics(func: Function, alias?: string | undefined): Function;
8
+ /**
9
+ * Aggregates and returns benchmark information
10
+ * @returns {{summaries: Record<string, Object>, totalTime: number, lastCompleteCall: *}}
11
+ * An object with
12
+ * - `totalTime` - total time spent by decorated methods
13
+ * - `lastCompleteCall` - millisecond since launch the last call completed at
14
+ * - `summaries` - mapping of all captured stats: summaries.methodName -> method stats
15
+ */
16
+ export function getMetrics(): {
17
+ summaries: Record<string, Object>;
18
+ totalTime: number;
19
+ lastCompleteCall: any;
20
+ };
21
+ /**
22
+ * Clears all collected metrics.
23
+ */
24
+ export function resetMetrics(): void;
25
+ /**
26
+ * Print extensive information on the dev console
27
+ * max, min, average, total time for each method
28
+ * and a table of individual calls
29
+ *
30
+ * @param {Object} [options]
31
+ * @param {boolean} [options.raw=false] - setting this to true will print raw instead of human friendly times
32
+ * Useful when you copy the printed table to excel and let excel do the number formatting
33
+ * @param {'console'|'csv'|'json'|'string'} [options.format=console] The output format of this function
34
+ * `string` is useful when __DEV__ is set to `false` as writing to the console is disabled, but the result of this
35
+ * method would still get printed as output
36
+ * @param {string[]} [options.methods] Print stats only for these method names
37
+ * @returns {string|undefined}
38
+ */
39
+ export function printMetrics({ raw, format, methods }?: {
40
+ raw?: boolean | undefined;
41
+ format?: "string" | "console" | "csv" | "json" | undefined;
42
+ methods?: string[] | undefined;
43
+ } | undefined): string | undefined;
@@ -1,9 +1,24 @@
1
- import _ from 'underscore';
2
- import performance from 'react-native-performance';
3
- import MDTable from '../MDTable';
4
-
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.printMetrics = exports.resetMetrics = exports.getMetrics = exports.decorateWithMetrics = void 0;
18
+ const underscore_1 = __importDefault(require("underscore"));
19
+ const react_native_performance_1 = __importDefault(require("react-native-performance"));
20
+ const MDTable_1 = __importDefault(require("../MDTable"));
5
21
  const decoratedAliases = new Set();
6
-
7
22
  /**
8
23
  * Capture a start mark to performance entries
9
24
  * @param {string} alias
@@ -11,22 +26,20 @@ const decoratedAliases = new Set();
11
26
  * @returns {{name: string, startTime:number, detail: {args: [], alias: string}}}
12
27
  */
13
28
  function addMark(alias, args) {
14
- return performance.mark(alias, {detail: {args, alias}});
29
+ return react_native_performance_1.default.mark(alias, { detail: { args, alias } });
15
30
  }
16
-
17
31
  /**
18
32
  * Capture a measurement between the start mark and now
19
33
  * @param {{name: string, startTime:number, detail: {args: []}}} startMark
20
34
  * @param {*} detail
21
35
  */
22
36
  function measureMarkToNow(startMark, detail) {
23
- performance.measure(`${startMark.name} [${startMark.detail.args.toString()}]`, {
37
+ react_native_performance_1.default.measure(`${startMark.name} [${startMark.detail.args.toString()}]`, {
24
38
  start: startMark.startTime,
25
- end: performance.now(),
26
- detail: {...startMark.detail, ...detail},
39
+ end: react_native_performance_1.default.now(),
40
+ detail: Object.assign(Object.assign({}, startMark.detail), detail),
27
41
  });
28
42
  }
29
-
30
43
  /**
31
44
  * Wraps a function with metrics capturing logic
32
45
  * @param {function} func
@@ -37,33 +50,27 @@ function decorateWithMetrics(func, alias = func.name) {
37
50
  if (decoratedAliases.has(alias)) {
38
51
  throw new Error(`"${alias}" is already decorated`);
39
52
  }
40
-
41
53
  decoratedAliases.add(alias);
42
-
43
54
  function decorated(...args) {
44
55
  const mark = addMark(alias, args);
45
-
46
56
  // eslint-disable-next-line no-invalid-this
47
57
  const originalPromise = func.apply(this, args);
48
-
49
58
  /*
50
59
  * Then handlers added here are not affecting the original promise
51
60
  * They create a separate chain that's not exposed (returned) to the original caller
52
61
  * */
53
62
  originalPromise
54
63
  .then((result) => {
55
- measureMarkToNow(mark, {result});
56
- })
64
+ measureMarkToNow(mark, { result });
65
+ })
57
66
  .catch((error) => {
58
- measureMarkToNow(mark, {error});
59
- });
60
-
67
+ measureMarkToNow(mark, { error });
68
+ });
61
69
  return originalPromise;
62
70
  }
63
-
64
71
  return decorated;
65
72
  }
66
-
73
+ exports.decorateWithMetrics = decorateWithMetrics;
67
74
  /**
68
75
  * Calculate the total sum of a given key in a list
69
76
  * @param {Array<Record<prop, Number>>} list
@@ -71,9 +78,8 @@ function decorateWithMetrics(func, alias = func.name) {
71
78
  * @returns {number}
72
79
  */
73
80
  function sum(list, prop) {
74
- return _.reduce(list, (memo, next) => memo + next[prop], 0);
81
+ return underscore_1.default.reduce(list, (memo, next) => memo + next[prop], 0);
75
82
  }
76
-
77
83
  /**
78
84
  * Aggregates and returns benchmark information
79
85
  * @returns {{summaries: Record<string, Object>, totalTime: number, lastCompleteCall: *}}
@@ -83,46 +89,41 @@ function sum(list, prop) {
83
89
  * - `summaries` - mapping of all captured stats: summaries.methodName -> method stats
84
90
  */
85
91
  function getMetrics() {
86
- const summaries = _.chain(performance.getEntriesByType('measure'))
92
+ const summaries = underscore_1.default.chain(react_native_performance_1.default.getEntriesByType('measure'))
87
93
  .filter((entry) => entry.detail && decoratedAliases.has(entry.detail.alias))
88
94
  .groupBy((entry) => entry.detail.alias)
89
95
  .map((calls, methodName) => {
90
- const total = sum(calls, 'duration');
91
- const avg = total / calls.length || 0;
92
- const max = _.max(calls, 'duration').duration || 0;
93
- const min = _.min(calls, 'duration').duration || 0;
94
-
95
- // Latest complete call (by end time) for all the calls made to the current method
96
- const lastCall = _.max(calls, (call) => call.startTime + call.duration);
97
-
98
- return [
96
+ const total = sum(calls, 'duration');
97
+ const avg = total / calls.length || 0;
98
+ const max = underscore_1.default.max(calls, 'duration').duration || 0;
99
+ const min = underscore_1.default.min(calls, 'duration').duration || 0;
100
+ // Latest complete call (by end time) for all the calls made to the current method
101
+ const lastCall = underscore_1.default.max(calls, (call) => call.startTime + call.duration);
102
+ return [
103
+ methodName,
104
+ {
99
105
  methodName,
100
- {
101
- methodName,
102
- total,
103
- max,
104
- min,
105
- avg,
106
- lastCall,
107
- calls,
108
- },
109
- ];
110
- })
106
+ total,
107
+ max,
108
+ min,
109
+ avg,
110
+ lastCall,
111
+ calls,
112
+ },
113
+ ];
114
+ })
111
115
  .object() // Create a map like methodName -> StatSummary
112
116
  .value();
113
-
114
- const totalTime = sum(_.values(summaries), 'total');
115
-
117
+ const totalTime = sum(underscore_1.default.values(summaries), 'total');
116
118
  // Latest complete call (by end time) of all methods up to this point
117
- const lastCompleteCall = _.max(_.values(summaries), (summary) => summary.lastCall.startTime + summary.lastCall.duration).lastCall;
118
-
119
+ const lastCompleteCall = underscore_1.default.max(underscore_1.default.values(summaries), (summary) => summary.lastCall.startTime + summary.lastCall.duration).lastCall;
119
120
  return {
120
121
  totalTime,
121
122
  summaries,
122
123
  lastCompleteCall,
123
124
  };
124
125
  }
125
-
126
+ exports.getMetrics = getMetrics;
126
127
  /**
127
128
  * Convert milliseconds to human readable time
128
129
  * @param {number} millis
@@ -133,20 +134,16 @@ function toDuration(millis, raw = false) {
133
134
  if (raw) {
134
135
  return millis;
135
136
  }
136
-
137
137
  const minute = 60 * 1000;
138
138
  if (millis > minute) {
139
139
  return `${(millis / minute).toFixed(1)}min`;
140
140
  }
141
-
142
141
  const second = 1000;
143
142
  if (millis > second) {
144
143
  return `${(millis / second).toFixed(2)}sec`;
145
144
  }
146
-
147
145
  return `${millis.toFixed(3)}ms`;
148
146
  }
149
-
150
147
  /**
151
148
  * Print extensive information on the dev console
152
149
  * max, min, average, total time for each method
@@ -161,53 +158,39 @@ function toDuration(millis, raw = false) {
161
158
  * @param {string[]} [options.methods] Print stats only for these method names
162
159
  * @returns {string|undefined}
163
160
  */
164
- function printMetrics({raw = false, format = 'console', methods} = {}) {
165
- const {totalTime, summaries, lastCompleteCall} = getMetrics();
166
-
167
- const tableSummary = MDTable.factory({
161
+ function printMetrics({ raw = false, format = 'console', methods } = {}) {
162
+ const { totalTime, summaries, lastCompleteCall } = getMetrics();
163
+ const tableSummary = MDTable_1.default.factory({
168
164
  heading: ['method', 'total time spent', 'max', 'min', 'avg', 'time last call completed', 'calls made'],
169
165
  leftAlignedCols: [0],
170
166
  });
171
-
172
167
  /* Performance marks (startTimes) are relative to system uptime
173
168
  * timeOrigin is the point at which the app started to init
174
169
  * We use timeOrigin to display times relative to app launch time
175
170
  * See: https://github.com/oblador/react-native-performance/issues/50 */
176
- const timeOrigin = performance.timeOrigin;
177
- const methodNames = _.isArray(methods) ? methods : _.keys(summaries);
178
-
179
- const methodCallTables = _.chain(methodNames)
171
+ const timeOrigin = react_native_performance_1.default.timeOrigin;
172
+ const methodNames = underscore_1.default.isArray(methods) ? methods : underscore_1.default.keys(summaries);
173
+ const methodCallTables = underscore_1.default.chain(methodNames)
180
174
  .filter((methodName) => summaries[methodName] && summaries[methodName].avg > 0)
181
175
  .map((methodName) => {
182
- const {calls, ...methodStats} = summaries[methodName];
183
- tableSummary.addRow(
184
- methodName,
185
- toDuration(methodStats.total, raw),
186
- toDuration(methodStats.max, raw),
187
- toDuration(methodStats.min, raw),
188
- toDuration(methodStats.avg, raw),
189
- toDuration(methodStats.lastCall.startTime + methodStats.lastCall.duration - timeOrigin, raw),
190
- calls.length,
191
- );
192
-
193
- return MDTable.factory({
194
- title: methodName,
195
- heading: ['start time', 'end time', 'duration', 'args'],
196
- leftAlignedCols: [3],
197
- rows: _.map(calls, (call) => [
198
- toDuration(call.startTime - performance.timeOrigin, raw),
199
- toDuration(call.startTime + call.duration - timeOrigin, raw),
200
- toDuration(call.duration, raw),
201
- _.map(call.detail.args, String).join(', ').slice(0, 60), // Restrict cell width to 60 chars max
202
- ]),
203
- });
204
- })
176
+ const _a = summaries[methodName], { calls } = _a, methodStats = __rest(_a, ["calls"]);
177
+ tableSummary.addRow(methodName, toDuration(methodStats.total, raw), toDuration(methodStats.max, raw), toDuration(methodStats.min, raw), toDuration(methodStats.avg, raw), toDuration(methodStats.lastCall.startTime + methodStats.lastCall.duration - timeOrigin, raw), calls.length);
178
+ return MDTable_1.default.factory({
179
+ title: methodName,
180
+ heading: ['start time', 'end time', 'duration', 'args'],
181
+ leftAlignedCols: [3],
182
+ rows: underscore_1.default.map(calls, (call) => [
183
+ toDuration(call.startTime - react_native_performance_1.default.timeOrigin, raw),
184
+ toDuration(call.startTime + call.duration - timeOrigin, raw),
185
+ toDuration(call.duration, raw),
186
+ underscore_1.default.map(call.detail.args, String).join(', ').slice(0, 60), // Restrict cell width to 60 chars max
187
+ ]),
188
+ });
189
+ })
205
190
  .value();
206
-
207
191
  if (/csv|json|string/i.test(format)) {
208
192
  const allTables = [tableSummary, ...methodCallTables];
209
-
210
- return _.map(allTables, (table) => {
193
+ return underscore_1.default.map(allTables, (table) => {
211
194
  switch (format.toLowerCase()) {
212
195
  case 'csv':
213
196
  return table.toCSV();
@@ -218,11 +201,8 @@ function printMetrics({raw = false, format = 'console', methods} = {}) {
218
201
  }
219
202
  }).join('\n\n');
220
203
  }
221
-
222
204
  const lastComplete = lastCompleteCall && toDuration(lastCompleteCall.startTime + lastCompleteCall.duration - timeOrigin, raw);
223
-
224
205
  const mainOutput = ['### Onyx Benchmark', ` - Total: ${toDuration(totalTime, raw)}`, ` - Last call finished at: ${lastComplete || 'N/A'}`, '', tableSummary.toString()];
225
-
226
206
  /* eslint-disable no-console */
227
207
  console.info(mainOutput.join('\n'));
228
208
  methodCallTables.forEach((table) => {
@@ -232,20 +212,18 @@ function printMetrics({raw = false, format = 'console', methods} = {}) {
232
212
  });
233
213
  /* eslint-enable */
234
214
  }
235
-
215
+ exports.printMetrics = printMetrics;
236
216
  /**
237
217
  * Clears all collected metrics.
238
218
  */
239
219
  function resetMetrics() {
240
- const {summaries} = getMetrics();
241
-
242
- _.chain(summaries)
220
+ const { summaries } = getMetrics();
221
+ underscore_1.default.chain(summaries)
243
222
  .map((summary) => summary.calls)
244
223
  .flatten()
245
224
  .each((measure) => {
246
- performance.clearMarks(measure.detail.alias);
247
- performance.clearMeasures(measure.name);
248
- });
225
+ react_native_performance_1.default.clearMarks(measure.detail.alias);
226
+ react_native_performance_1.default.clearMeasures(measure.name);
227
+ });
249
228
  }
250
-
251
- export {decorateWithMetrics, getMetrics, resetMetrics, printMetrics};
229
+ exports.resetMetrics = resetMetrics;
@@ -1,3 +1,2 @@
1
- import SQLiteStorage from './providers/SQLiteStorage';
2
-
3
1
  export default SQLiteStorage;
2
+ import SQLiteStorage from './providers/SQLiteStorage';
@@ -0,0 +1,7 @@
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
+ const SQLiteStorage_1 = __importDefault(require("./providers/SQLiteStorage"));
7
+ exports.default = SQLiteStorage_1.default;
@@ -0,0 +1,19 @@
1
+ export default webStorage;
2
+ declare const webStorage: {
3
+ /**
4
+ * @param {Function} onStorageKeyChanged Storage synchronization mechanism keeping all opened tabs in sync
5
+ */
6
+ keepInstancesSync(onStorageKeyChanged: Function): void;
7
+ setItem: (key: string, value: any) => Promise<void>;
8
+ multiGet: (keysParam: string[]) => Promise<[key, value][]>;
9
+ multiMerge: (pairs: [key, value][]) => Promise<void>;
10
+ mergeItem(key: string, _changes: any, modifiedData: any): Promise<void>;
11
+ multiSet: (pairs: [key, value][]) => Promise<void>;
12
+ clear: () => Promise<void>;
13
+ setMemoryOnlyKeys: () => void;
14
+ getAllKeys: () => Promise<string[]>;
15
+ getItem: (key: string) => Promise<any>;
16
+ removeItem: (key: string) => Promise<void>;
17
+ removeItems: (keysParam: any[]) => Promise<any>;
18
+ getDatabaseSize(): Promise<number>;
19
+ };
@@ -1,13 +1,16 @@
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 });
1
6
  /**
2
7
  * This file is here to wrap IDBKeyVal with a layer that provides data-changed events like the ones that exist
3
8
  * when using LocalStorage APIs in the browser. These events are great because multiple tabs can listen for when
4
9
  * data changes and then stay up-to-date with everything happening in Onyx.
5
10
  */
6
- import _ from 'underscore';
7
- import Storage from './providers/IDBKeyVal';
8
-
11
+ const underscore_1 = __importDefault(require("underscore"));
12
+ const IDBKeyVal_1 = __importDefault(require("./providers/IDBKeyVal"));
9
13
  const SYNC_ONYX = 'SYNC_ONYX';
10
-
11
14
  /**
12
15
  * Raise an event thorough `localStorage` to let other tabs know a value changed
13
16
  * @param {String} onyxKey
@@ -16,59 +19,46 @@ function raiseStorageSyncEvent(onyxKey) {
16
19
  global.localStorage.setItem(SYNC_ONYX, onyxKey);
17
20
  global.localStorage.removeItem(SYNC_ONYX, onyxKey);
18
21
  }
19
-
20
22
  function raiseStorageSyncManyKeysEvent(onyxKeys) {
21
- _.each(onyxKeys, (onyxKey) => {
23
+ underscore_1.default.each(onyxKeys, (onyxKey) => {
22
24
  raiseStorageSyncEvent(onyxKey);
23
25
  });
24
26
  }
25
-
26
- const webStorage = {
27
- ...Storage,
28
-
27
+ const webStorage = Object.assign(Object.assign({}, IDBKeyVal_1.default), {
29
28
  /**
30
29
  * @param {Function} onStorageKeyChanged Storage synchronization mechanism keeping all opened tabs in sync
31
30
  */
32
31
  keepInstancesSync(onStorageKeyChanged) {
33
32
  // Override set, remove and clear to raise storage events that we intercept in other tabs
34
- this.setItem = (key, value) => Storage.setItem(key, value).then(() => raiseStorageSyncEvent(key));
35
-
36
- this.removeItem = (key) => Storage.removeItem(key).then(() => raiseStorageSyncEvent(key));
37
-
38
- this.removeItems = (keys) => Storage.removeItems(keys).then(() => raiseStorageSyncManyKeysEvent(keys));
39
-
40
- this.mergeItem = (key, batchedChanges, modifiedData) => Storage.mergeItem(key, batchedChanges, modifiedData).then(() => raiseStorageSyncEvent(key));
41
-
33
+ this.setItem = (key, value) => IDBKeyVal_1.default.setItem(key, value).then(() => raiseStorageSyncEvent(key));
34
+ this.removeItem = (key) => IDBKeyVal_1.default.removeItem(key).then(() => raiseStorageSyncEvent(key));
35
+ this.removeItems = (keys) => IDBKeyVal_1.default.removeItems(keys).then(() => raiseStorageSyncManyKeysEvent(keys));
36
+ this.mergeItem = (key, batchedChanges, modifiedData) => IDBKeyVal_1.default.mergeItem(key, batchedChanges, modifiedData).then(() => raiseStorageSyncEvent(key));
42
37
  // If we just call Storage.clear other tabs will have no idea which keys were available previously
43
38
  // so that they can call keysChanged for them. That's why we iterate over every key and raise a storage sync
44
39
  // event for each one
45
40
  this.clear = () => {
46
41
  let allKeys;
47
-
48
42
  // The keys must be retrieved before storage is cleared or else the list of keys would be empty
49
- return Storage.getAllKeys()
43
+ return IDBKeyVal_1.default.getAllKeys()
50
44
  .then((keys) => {
51
- allKeys = keys;
52
- })
53
- .then(() => Storage.clear())
45
+ allKeys = keys;
46
+ })
47
+ .then(() => IDBKeyVal_1.default.clear())
54
48
  .then(() => {
55
- // Now that storage is cleared, the storage sync event can happen which is a more atomic action
56
- // for other browser tabs
57
- _.each(allKeys, raiseStorageSyncEvent);
58
- });
49
+ // Now that storage is cleared, the storage sync event can happen which is a more atomic action
50
+ // for other browser tabs
51
+ underscore_1.default.each(allKeys, raiseStorageSyncEvent);
52
+ });
59
53
  };
60
-
61
54
  // This listener will only be triggered by events coming from other tabs
62
55
  global.addEventListener('storage', (event) => {
63
56
  // Ignore events that don't originate from the SYNC_ONYX logic
64
57
  if (event.key !== SYNC_ONYX || !event.newValue) {
65
58
  return;
66
59
  }
67
-
68
60
  const onyxKey = event.newValue;
69
- Storage.getItem(onyxKey).then((value) => onStorageKeyChanged(onyxKey, value));
61
+ IDBKeyVal_1.default.getItem(onyxKey).then((value) => onStorageKeyChanged(onyxKey, value));
70
62
  });
71
- },
72
- };
73
-
74
- export default webStorage;
63
+ } });
64
+ exports.default = webStorage;
@@ -0,0 +1,23 @@
1
+ export default idbKeyvalMockSpy;
2
+ declare namespace idbKeyvalMockSpy {
3
+ export { set as idbKeyvalSet };
4
+ export let setItem: jest.Mock<Promise<any>, [key?: any, value?: any]>;
5
+ export let getItem: jest.Mock<Promise<any>, [key?: any]>;
6
+ export let removeItem: jest.Mock<Promise<void>, [key?: any]>;
7
+ export let removeItems: jest.Mock<Promise<void>, [keys?: any]>;
8
+ export let clear: jest.Mock<Promise<void>, []>;
9
+ export let getAllKeys: jest.Mock<Promise<any>, []>;
10
+ export let config: jest.Mock<void, []>;
11
+ export let multiGet: jest.Mock<Promise<any>, [keys?: any]>;
12
+ export let multiSet: jest.Mock<Promise<any>, [pairs?: any]>;
13
+ export let multiMerge: jest.Mock<Promise<{}>, [pairs?: any]>;
14
+ export let mergeItem: jest.Mock<Promise<any>, [key?: any, _changes?: any, modifiedData?: any]>;
15
+ export let getStorageMap: jest.Mock<{}, []>;
16
+ export let setInitialMockData: jest.Mock<void, [data?: any]>;
17
+ export let getDatabaseSize: jest.Mock<Promise<{
18
+ bytesRemaining: number;
19
+ bytesUsed: number;
20
+ }>, []>;
21
+ export let setMemoryOnlyKeys: jest.Mock<void, []>;
22
+ }
23
+ declare const set: jest.Mock<Promise<any>, [key?: any, value?: any]>;