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.
- package/API.md +83 -22
- package/README.md +3 -5
- package/dist/DevTools.d.ts +23 -0
- package/{lib → dist}/DevTools.js +16 -18
- package/dist/Logger.js +32 -0
- package/dist/MDTable.d.ts +36 -0
- package/{lib → dist}/MDTable.js +12 -17
- package/{lib → dist}/Onyx.js +278 -477
- package/dist/OnyxCache.d.ts +121 -0
- package/{lib → dist}/OnyxCache.js +16 -53
- package/{lib/Str.js → dist/Str.d.ts} +2 -11
- package/dist/Str.js +31 -0
- package/dist/SyncQueue.d.ts +32 -0
- package/{lib → dist}/SyncQueue.js +9 -11
- package/dist/batch.d.ts +2 -0
- package/dist/batch.js +4 -0
- package/dist/batch.native.d.ts +2 -0
- package/dist/batch.native.js +4 -0
- package/dist/compose.d.ts +19 -0
- package/{lib → dist}/compose.js +5 -8
- package/dist/createDeferredTask.d.ts +12 -0
- package/{lib → dist}/createDeferredTask.js +4 -2
- package/dist/index.d.ts +6 -0
- package/dist/index.js +10 -0
- package/dist/metrics/PerformanceUtils.d.ts +14 -0
- package/{lib → dist}/metrics/PerformanceUtils.js +16 -16
- package/dist/metrics/index.d.ts +4 -0
- package/dist/metrics/index.js +14 -0
- package/dist/metrics/index.native.d.ts +43 -0
- package/{lib → dist}/metrics/index.native.js +80 -102
- package/{lib/storage/NativeStorage.js → dist/storage/NativeStorage.d.ts} +1 -2
- package/dist/storage/NativeStorage.js +7 -0
- package/dist/storage/WebStorage.d.ts +19 -0
- package/{lib → dist}/storage/WebStorage.js +24 -34
- package/dist/storage/__mocks__/index.d.ts +23 -0
- package/{lib → dist}/storage/__mocks__/index.js +17 -19
- package/{lib/storage/index.web.js → dist/storage/index.d.ts} +1 -2
- package/dist/storage/index.js +7 -0
- package/{lib/storage/index.native.js → dist/storage/index.native.d.ts} +1 -2
- package/dist/storage/index.native.js +7 -0
- package/dist/storage/providers/IDBKeyVal.d.ts +26 -0
- package/{lib → dist}/storage/providers/IDBKeyVal.js +38 -52
- package/dist/storage/providers/SQLiteStorage.d.ts +52 -0
- package/{lib → dist}/storage/providers/SQLiteStorage.js +27 -42
- package/{lib → dist}/utils.js +14 -27
- package/{lib → dist}/withOnyx.js +122 -159
- package/package.json +23 -54
- package/dist/web.development.js +0 -4308
- package/dist/web.development.js.map +0 -1
- package/dist/web.min.js +0 -2
- package/dist/web.min.js.map +0 -1
- package/lib/Logger.js +0 -31
- package/lib/batch.js +0 -3
- package/lib/batch.native.js +0 -3
- package/lib/index.d.ts +0 -6
- package/lib/index.js +0 -5
- package/lib/metrics/index.web.js +0 -10
- package/native.js +0 -11
- package/web.js +0 -12
- /package/{lib → dist}/Logger.d.ts +0 -0
- /package/{lib → dist}/Onyx.d.ts +0 -0
- /package/{lib → dist}/types.d.ts +0 -0
- /package/{lib → dist}/utils.d.ts +0 -0
- /package/{lib → dist}/withOnyx.d.ts +0 -0
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
+
const underscore_1 = __importDefault(require("underscore"));
|
|
7
|
+
const utils_1 = __importDefault(require("../../utils"));
|
|
4
8
|
let storageMapInternal = {};
|
|
5
|
-
|
|
6
9
|
const set = jest.fn((key, value) => {
|
|
7
10
|
storageMapInternal[key] = value;
|
|
8
11
|
return Promise.resolve(value);
|
|
9
12
|
});
|
|
10
|
-
|
|
11
13
|
const idbKeyvalMock = {
|
|
12
14
|
setItem(key, value) {
|
|
13
15
|
return set(key, value);
|
|
14
16
|
},
|
|
15
17
|
multiSet(pairs) {
|
|
16
|
-
const setPromises =
|
|
18
|
+
const setPromises = underscore_1.default.map(pairs, ([key, value]) => this.setItem(key, value));
|
|
17
19
|
return new Promise((resolve) => Promise.all(setPromises).then(() => resolve(storageMapInternal)));
|
|
18
20
|
},
|
|
19
21
|
getItem(key) {
|
|
20
22
|
return Promise.resolve(storageMapInternal[key]);
|
|
21
23
|
},
|
|
22
24
|
multiGet(keys) {
|
|
23
|
-
const getPromises =
|
|
25
|
+
const getPromises = underscore_1.default.map(keys, (key) => new Promise((resolve) => this.getItem(key).then((value) => resolve([key, value]))));
|
|
24
26
|
return Promise.all(getPromises);
|
|
25
27
|
},
|
|
26
28
|
multiMerge(pairs) {
|
|
27
|
-
|
|
29
|
+
underscore_1.default.forEach(pairs, ([key, value]) => {
|
|
28
30
|
const existingValue = storageMapInternal[key];
|
|
29
|
-
const newValue =
|
|
30
|
-
|
|
31
|
+
const newValue = utils_1.default.fastMerge(existingValue, value);
|
|
31
32
|
set(key, newValue);
|
|
32
33
|
});
|
|
33
|
-
|
|
34
34
|
return Promise.resolve(storageMapInternal);
|
|
35
35
|
},
|
|
36
36
|
mergeItem(key, _changes, modifiedData) {
|
|
@@ -41,7 +41,7 @@ const idbKeyvalMock = {
|
|
|
41
41
|
return Promise.resolve();
|
|
42
42
|
},
|
|
43
43
|
removeItems(keys) {
|
|
44
|
-
|
|
44
|
+
underscore_1.default.each(keys, (key) => {
|
|
45
45
|
delete storageMapInternal[key];
|
|
46
46
|
});
|
|
47
47
|
return Promise.resolve();
|
|
@@ -51,15 +51,14 @@ const idbKeyvalMock = {
|
|
|
51
51
|
return Promise.resolve();
|
|
52
52
|
},
|
|
53
53
|
getAllKeys() {
|
|
54
|
-
return Promise.resolve(
|
|
54
|
+
return Promise.resolve(underscore_1.default.keys(storageMapInternal));
|
|
55
55
|
},
|
|
56
|
-
config() {},
|
|
56
|
+
config() { },
|
|
57
57
|
getDatabaseSize() {
|
|
58
|
-
return Promise.resolve({bytesRemaining: 0, bytesUsed: 99999});
|
|
58
|
+
return Promise.resolve({ bytesRemaining: 0, bytesUsed: 99999 });
|
|
59
59
|
},
|
|
60
|
-
setMemoryOnlyKeys() {},
|
|
60
|
+
setMemoryOnlyKeys() { },
|
|
61
61
|
};
|
|
62
|
-
|
|
63
62
|
const idbKeyvalMockSpy = {
|
|
64
63
|
idbKeyvalSet: set,
|
|
65
64
|
setItem: jest.fn(idbKeyvalMock.setItem),
|
|
@@ -80,5 +79,4 @@ const idbKeyvalMockSpy = {
|
|
|
80
79
|
getDatabaseSize: jest.fn(idbKeyvalMock.getDatabaseSize),
|
|
81
80
|
setMemoryOnlyKeys: jest.fn(idbKeyvalMock.setMemoryOnlyKeys),
|
|
82
81
|
};
|
|
83
|
-
|
|
84
|
-
export default idbKeyvalMockSpy;
|
|
82
|
+
exports.default = idbKeyvalMockSpy;
|
|
@@ -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 WebStorage_1 = __importDefault(require("./WebStorage"));
|
|
7
|
+
exports.default = WebStorage_1.default;
|
|
@@ -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 NativeStorage_1 = __importDefault(require("./NativeStorage"));
|
|
7
|
+
exports.default = NativeStorage_1.default;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export default provider;
|
|
2
|
+
declare namespace provider {
|
|
3
|
+
function setItem(key: string, value: any): Promise<void>;
|
|
4
|
+
function multiGet(keysParam: string[]): Promise<[key, value][]>;
|
|
5
|
+
function multiMerge(pairs: [key, value][]): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Merging an existing value with a new one
|
|
8
|
+
* @param {String} key
|
|
9
|
+
* @param {any} _changes - not used, as we rely on the pre-merged data from the `modifiedData`
|
|
10
|
+
* @param {any} modifiedData - the pre-merged data from `Onyx.applyMerge`
|
|
11
|
+
* @return {Promise<void>}
|
|
12
|
+
*/
|
|
13
|
+
function mergeItem(key: string, _changes: any, modifiedData: any): Promise<void>;
|
|
14
|
+
function multiSet(pairs: [key, value][]): Promise<void>;
|
|
15
|
+
function clear(): Promise<void>;
|
|
16
|
+
function setMemoryOnlyKeys(): void;
|
|
17
|
+
function getAllKeys(): Promise<string[]>;
|
|
18
|
+
function getItem(key: string): Promise<any>;
|
|
19
|
+
function removeItem(key: string): Promise<void>;
|
|
20
|
+
function removeItems(keysParam: any[]): Promise<any>;
|
|
21
|
+
/**
|
|
22
|
+
* Gets the total bytes of the database file
|
|
23
|
+
* @returns {Promise<number>}
|
|
24
|
+
*/
|
|
25
|
+
function getDatabaseSize(): Promise<number>;
|
|
26
|
+
}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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 idb_keyval_1 = require("idb-keyval");
|
|
7
|
+
const underscore_1 = __importDefault(require("underscore"));
|
|
8
|
+
const utils_1 = __importDefault(require("../../utils"));
|
|
5
9
|
// We don't want to initialize the store while the JS bundle loads as idb-keyval will try to use global.indexedDB
|
|
6
10
|
// which might not be available in certain environments that load the bundle (e.g. electron main process).
|
|
7
11
|
let customStoreInstance;
|
|
8
12
|
const getCustomStore = () => {
|
|
9
13
|
if (!customStoreInstance) {
|
|
10
|
-
customStoreInstance = createStore('OnyxDB', 'keyvaluepairs');
|
|
14
|
+
customStoreInstance = (0, idb_keyval_1.createStore)('OnyxDB', 'keyvaluepairs');
|
|
11
15
|
}
|
|
12
16
|
return customStoreInstance;
|
|
13
17
|
};
|
|
14
|
-
|
|
15
18
|
const provider = {
|
|
16
19
|
/**
|
|
17
20
|
* Sets the value for a given key. The only requirement is that the value should be serializable to JSON string
|
|
@@ -19,39 +22,33 @@ const provider = {
|
|
|
19
22
|
* @param {*} value
|
|
20
23
|
* @return {Promise<void>}
|
|
21
24
|
*/
|
|
22
|
-
setItem: (key, value) => set(key, value, getCustomStore()),
|
|
23
|
-
|
|
25
|
+
setItem: (key, value) => (0, idb_keyval_1.set)(key, value, getCustomStore()),
|
|
24
26
|
/**
|
|
25
27
|
* Get multiple key-value pairs for the give array of keys in a batch.
|
|
26
28
|
* This is optimized to use only one database transaction.
|
|
27
29
|
* @param {String[]} keysParam
|
|
28
30
|
* @return {Promise<Array<[key, value]>>}
|
|
29
31
|
*/
|
|
30
|
-
multiGet: (keysParam) => getMany(keysParam, getCustomStore()).then((values) =>
|
|
31
|
-
|
|
32
|
+
multiGet: (keysParam) => (0, idb_keyval_1.getMany)(keysParam, getCustomStore()).then((values) => underscore_1.default.map(values, (value, index) => [keysParam[index], value])),
|
|
32
33
|
/**
|
|
33
34
|
* Multiple merging of existing and new values in a batch
|
|
34
35
|
* @param {Array<[key, value]>} pairs
|
|
35
36
|
* This function also removes all nested null values from an object.
|
|
36
37
|
* @return {Promise<void>}
|
|
37
38
|
*/
|
|
38
|
-
multiMerge: (pairs) =>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const prev = values[index];
|
|
48
|
-
const newValue = utils.fastMerge(prev, value);
|
|
49
|
-
return promisifyRequest(store.put(newValue, key));
|
|
50
|
-
});
|
|
51
|
-
return Promise.all(upsertMany);
|
|
39
|
+
multiMerge: (pairs) => getCustomStore()('readwrite', (store) => {
|
|
40
|
+
// Note: we are using the manual store transaction here, to fit the read and update
|
|
41
|
+
// of the items in one transaction to achieve best performance.
|
|
42
|
+
const getValues = Promise.all(underscore_1.default.map(pairs, ([key]) => (0, idb_keyval_1.promisifyRequest)(store.get(key))));
|
|
43
|
+
return getValues.then((values) => {
|
|
44
|
+
const upsertMany = underscore_1.default.map(pairs, ([key, value], index) => {
|
|
45
|
+
const prev = values[index];
|
|
46
|
+
const newValue = utils_1.default.fastMerge(prev, value);
|
|
47
|
+
return (0, idb_keyval_1.promisifyRequest)(store.put(newValue, key));
|
|
52
48
|
});
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
return Promise.all(upsertMany);
|
|
50
|
+
});
|
|
51
|
+
}),
|
|
55
52
|
/**
|
|
56
53
|
* Merging an existing value with a new one
|
|
57
54
|
* @param {String} key
|
|
@@ -63,54 +60,45 @@ const provider = {
|
|
|
63
60
|
// Since Onyx also merged the existing value with the changes, we can just set the value directly
|
|
64
61
|
return provider.setItem(key, modifiedData);
|
|
65
62
|
},
|
|
66
|
-
|
|
67
63
|
/**
|
|
68
64
|
* Stores multiple key-value pairs in a batch
|
|
69
65
|
* @param {Array<[key, value]>} pairs
|
|
70
66
|
* @return {Promise<void>}
|
|
71
67
|
*/
|
|
72
|
-
multiSet: (pairs) => setMany(pairs, getCustomStore()),
|
|
73
|
-
|
|
68
|
+
multiSet: (pairs) => (0, idb_keyval_1.setMany)(pairs, getCustomStore()),
|
|
74
69
|
/**
|
|
75
70
|
* Clear everything from storage and also stops the SyncQueue from adding anything more to storage
|
|
76
71
|
* @returns {Promise<void>}
|
|
77
72
|
*/
|
|
78
|
-
clear: () => clear(getCustomStore()),
|
|
79
|
-
|
|
73
|
+
clear: () => (0, idb_keyval_1.clear)(getCustomStore()),
|
|
80
74
|
// This is a noop for now in order to keep clients from crashing see https://github.com/Expensify/Expensify/issues/312438
|
|
81
|
-
setMemoryOnlyKeys: () => {},
|
|
82
|
-
|
|
75
|
+
setMemoryOnlyKeys: () => { },
|
|
83
76
|
/**
|
|
84
77
|
* Returns all keys available in storage
|
|
85
78
|
* @returns {Promise<String[]>}
|
|
86
79
|
*/
|
|
87
|
-
getAllKeys: () => keys(getCustomStore()),
|
|
88
|
-
|
|
80
|
+
getAllKeys: () => (0, idb_keyval_1.keys)(getCustomStore()),
|
|
89
81
|
/**
|
|
90
82
|
* Get the value of a given key or return `null` if it's not available in storage
|
|
91
83
|
* @param {String} key
|
|
92
84
|
* @return {Promise<*>}
|
|
93
85
|
*/
|
|
94
|
-
getItem: (key) =>
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
.then((val) => (val === undefined ? null : val)),
|
|
98
|
-
|
|
86
|
+
getItem: (key) => (0, idb_keyval_1.get)(key, getCustomStore())
|
|
87
|
+
// idb-keyval returns undefined for missing items, but this needs to return null so that idb-keyval does the same thing as SQLiteStorage.
|
|
88
|
+
.then((val) => (val === undefined ? null : val)),
|
|
99
89
|
/**
|
|
100
90
|
* Remove given key and it's value from storage
|
|
101
91
|
* @param {String} key
|
|
102
92
|
* @returns {Promise<void>}
|
|
103
93
|
*/
|
|
104
|
-
removeItem: (key) => del(key, getCustomStore()),
|
|
105
|
-
|
|
94
|
+
removeItem: (key) => (0, idb_keyval_1.del)(key, getCustomStore()),
|
|
106
95
|
/**
|
|
107
96
|
* Remove given keys and their values from storage
|
|
108
97
|
*
|
|
109
98
|
* @param {Array} keysParam
|
|
110
99
|
* @returns {Promise}
|
|
111
100
|
*/
|
|
112
|
-
removeItems: (keysParam) => delMany(keysParam, getCustomStore()),
|
|
113
|
-
|
|
101
|
+
removeItems: (keysParam) => (0, idb_keyval_1.delMany)(keysParam, getCustomStore()),
|
|
114
102
|
/**
|
|
115
103
|
* Gets the total bytes of the database file
|
|
116
104
|
* @returns {Promise<number>}
|
|
@@ -119,17 +107,15 @@ const provider = {
|
|
|
119
107
|
if (!window.navigator || !window.navigator.storage) {
|
|
120
108
|
throw new Error('StorageManager browser API unavailable');
|
|
121
109
|
}
|
|
122
|
-
|
|
123
110
|
return window.navigator.storage
|
|
124
111
|
.estimate()
|
|
125
112
|
.then((value) => ({
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
113
|
+
bytesUsed: value.usage,
|
|
114
|
+
bytesRemaining: value.quota - value.usage,
|
|
115
|
+
}))
|
|
129
116
|
.catch((error) => {
|
|
130
|
-
|
|
131
|
-
|
|
117
|
+
throw new Error(`Unable to estimate web storage quota. Original error: ${error}`);
|
|
118
|
+
});
|
|
132
119
|
},
|
|
133
120
|
};
|
|
134
|
-
|
|
135
|
-
export default provider;
|
|
121
|
+
exports.default = provider;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export default provider;
|
|
2
|
+
declare namespace provider {
|
|
3
|
+
/**
|
|
4
|
+
* Get the value of a given key or return `null` if it's not available in storage
|
|
5
|
+
* @param {String} key
|
|
6
|
+
* @return {Promise<*>}
|
|
7
|
+
*/
|
|
8
|
+
function getItem(key: string): Promise<any>;
|
|
9
|
+
/**
|
|
10
|
+
* Get multiple key-value pairs for the given array of keys in a batch
|
|
11
|
+
* @param {String[]} keys
|
|
12
|
+
* @return {Promise<Array<[key, value]>>}
|
|
13
|
+
*/
|
|
14
|
+
function multiGet(keys: string[]): Promise<[key, value][]>;
|
|
15
|
+
/**
|
|
16
|
+
* Sets the value for a given key. The only requirement is that the value should be serializable to JSON string
|
|
17
|
+
* @param {String} key
|
|
18
|
+
* @param {*} value
|
|
19
|
+
* @return {Promise<void>}
|
|
20
|
+
*/
|
|
21
|
+
function setItem(key: string, value: any): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Stores multiple key-value pairs in a batch
|
|
24
|
+
* @param {Array<[key, value]>} pairs
|
|
25
|
+
* @return {Promise<void>}
|
|
26
|
+
*/
|
|
27
|
+
function multiSet(pairs: [key, value][]): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Multiple merging of existing and new values in a batch
|
|
30
|
+
* @param {Array<[key, value]>} pairs
|
|
31
|
+
* @return {Promise<void>}
|
|
32
|
+
*/
|
|
33
|
+
function multiMerge(pairs: [key, value][]): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Merges an existing value with a new one by leveraging JSON_PATCH
|
|
36
|
+
* @param {String} key
|
|
37
|
+
* @param {*} changes - the delta for a specific key
|
|
38
|
+
* @return {Promise<void>}
|
|
39
|
+
*/
|
|
40
|
+
function mergeItem(key: string, changes: any): Promise<void>;
|
|
41
|
+
function getAllKeys(): Promise<string[]>;
|
|
42
|
+
function removeItem(key: string): Promise<void>;
|
|
43
|
+
function removeItems(keys: string[]): Promise<void>;
|
|
44
|
+
function clear(): Promise<void>;
|
|
45
|
+
function setMemoryOnlyKeys(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Gets the total bytes of the database file
|
|
48
|
+
* @returns {Promise}
|
|
49
|
+
*/
|
|
50
|
+
function getDatabaseSize(): Promise<any>;
|
|
51
|
+
function keepInstancesSync(): void;
|
|
52
|
+
}
|
|
@@ -1,22 +1,23 @@
|
|
|
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
|
* The SQLiteStorage provider stores everything in a key/value store by
|
|
3
8
|
* converting the value to a JSON string
|
|
4
9
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
const react_native_quick_sqlite_1 = require("react-native-quick-sqlite");
|
|
11
|
+
const react_native_device_info_1 = require("react-native-device-info");
|
|
12
|
+
const underscore_1 = __importDefault(require("underscore"));
|
|
9
13
|
const DB_NAME = 'OnyxDB';
|
|
10
|
-
const db = open({name: DB_NAME});
|
|
11
|
-
|
|
14
|
+
const db = (0, react_native_quick_sqlite_1.open)({ name: DB_NAME });
|
|
12
15
|
db.execute('CREATE TABLE IF NOT EXISTS keyvaluepairs (record_key TEXT NOT NULL PRIMARY KEY , valueJSON JSON NOT NULL) WITHOUT ROWID;');
|
|
13
|
-
|
|
14
16
|
// All of the 3 pragmas below were suggested by SQLite team.
|
|
15
17
|
// You can find more info about them here: https://www.sqlite.org/pragma.html
|
|
16
18
|
db.execute('PRAGMA CACHE_SIZE=-20000;');
|
|
17
19
|
db.execute('PRAGMA synchronous=NORMAL;');
|
|
18
20
|
db.execute('PRAGMA journal_mode=WAL;');
|
|
19
|
-
|
|
20
21
|
const provider = {
|
|
21
22
|
/**
|
|
22
23
|
* Get the value of a given key or return `null` if it's not available in storage
|
|
@@ -24,7 +25,7 @@ const provider = {
|
|
|
24
25
|
* @return {Promise<*>}
|
|
25
26
|
*/
|
|
26
27
|
getItem(key) {
|
|
27
|
-
return db.executeAsync('SELECT record_key, valueJSON FROM keyvaluepairs WHERE record_key = ?;', [key]).then(({rows}) => {
|
|
28
|
+
return db.executeAsync('SELECT record_key, valueJSON FROM keyvaluepairs WHERE record_key = ?;', [key]).then(({ rows }) => {
|
|
28
29
|
if (rows.length === 0) {
|
|
29
30
|
return null;
|
|
30
31
|
}
|
|
@@ -32,22 +33,20 @@ const provider = {
|
|
|
32
33
|
return JSON.parse(result.valueJSON);
|
|
33
34
|
});
|
|
34
35
|
},
|
|
35
|
-
|
|
36
36
|
/**
|
|
37
37
|
* Get multiple key-value pairs for the given array of keys in a batch
|
|
38
38
|
* @param {String[]} keys
|
|
39
39
|
* @return {Promise<Array<[key, value]>>}
|
|
40
40
|
*/
|
|
41
41
|
multiGet(keys) {
|
|
42
|
-
const placeholders =
|
|
42
|
+
const placeholders = underscore_1.default.map(keys, () => '?').join(',');
|
|
43
43
|
const command = `SELECT record_key, valueJSON FROM keyvaluepairs WHERE record_key IN (${placeholders});`;
|
|
44
|
-
return db.executeAsync(command, keys).then(({rows}) => {
|
|
44
|
+
return db.executeAsync(command, keys).then(({ rows }) => {
|
|
45
45
|
// eslint-disable-next-line no-underscore-dangle
|
|
46
|
-
const result =
|
|
46
|
+
const result = underscore_1.default.map(rows._array, (row) => [row.record_key, JSON.parse(row.valueJSON)]);
|
|
47
47
|
return result;
|
|
48
48
|
});
|
|
49
49
|
},
|
|
50
|
-
|
|
51
50
|
/**
|
|
52
51
|
* Sets the value for a given key. The only requirement is that the value should be serializable to JSON string
|
|
53
52
|
* @param {String} key
|
|
@@ -57,20 +56,18 @@ const provider = {
|
|
|
57
56
|
setItem(key, value) {
|
|
58
57
|
return db.executeAsync('REPLACE INTO keyvaluepairs (record_key, valueJSON) VALUES (?, ?);', [key, JSON.stringify(value)]);
|
|
59
58
|
},
|
|
60
|
-
|
|
61
59
|
/**
|
|
62
60
|
* Stores multiple key-value pairs in a batch
|
|
63
61
|
* @param {Array<[key, value]>} pairs
|
|
64
62
|
* @return {Promise<void>}
|
|
65
63
|
*/
|
|
66
64
|
multiSet(pairs) {
|
|
67
|
-
const stringifiedPairs =
|
|
68
|
-
if (
|
|
65
|
+
const stringifiedPairs = underscore_1.default.map(pairs, (pair) => [pair[0], JSON.stringify(underscore_1.default.isUndefined(pair[1]) ? null : pair[1])]);
|
|
66
|
+
if (underscore_1.default.isEmpty(stringifiedPairs)) {
|
|
69
67
|
return Promise.resolve();
|
|
70
68
|
}
|
|
71
69
|
return db.executeBatchAsync([['REPLACE INTO keyvaluepairs (record_key, valueJSON) VALUES (?, json(?));', stringifiedPairs]]);
|
|
72
70
|
},
|
|
73
|
-
|
|
74
71
|
/**
|
|
75
72
|
* Multiple merging of existing and new values in a batch
|
|
76
73
|
* @param {Array<[key, value]>} pairs
|
|
@@ -84,16 +81,13 @@ const provider = {
|
|
|
84
81
|
ON CONFLICT DO UPDATE
|
|
85
82
|
SET valueJSON = JSON_PATCH(valueJSON, JSON(:value));
|
|
86
83
|
`;
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
const queryArguments = _.map(nonNullishPairs, (pair) => {
|
|
84
|
+
const nonNullishPairs = underscore_1.default.filter(pairs, (pair) => !underscore_1.default.isUndefined(pair[1]));
|
|
85
|
+
const queryArguments = underscore_1.default.map(nonNullishPairs, (pair) => {
|
|
90
86
|
const value = JSON.stringify(pair[1]);
|
|
91
87
|
return [pair[0], value];
|
|
92
88
|
});
|
|
93
|
-
|
|
94
89
|
return db.executeBatchAsync([[query, queryArguments]]);
|
|
95
90
|
},
|
|
96
|
-
|
|
97
91
|
/**
|
|
98
92
|
* Merges an existing value with a new one by leveraging JSON_PATCH
|
|
99
93
|
* @param {String} key
|
|
@@ -103,25 +97,21 @@ const provider = {
|
|
|
103
97
|
mergeItem(key, changes) {
|
|
104
98
|
return this.multiMerge([[key, changes]]);
|
|
105
99
|
},
|
|
106
|
-
|
|
107
100
|
/**
|
|
108
101
|
* Returns all keys available in storage
|
|
109
102
|
* @returns {Promise<String[]>}
|
|
110
103
|
*/
|
|
111
|
-
getAllKeys: () =>
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}),
|
|
117
|
-
|
|
104
|
+
getAllKeys: () => db.executeAsync('SELECT record_key FROM keyvaluepairs;').then(({ rows }) => {
|
|
105
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
106
|
+
const result = underscore_1.default.map(rows._array, (row) => row.record_key);
|
|
107
|
+
return result;
|
|
108
|
+
}),
|
|
118
109
|
/**
|
|
119
110
|
* Removes given key and it's value from storage
|
|
120
111
|
* @param {String} key
|
|
121
112
|
* @returns {Promise<void>}
|
|
122
113
|
*/
|
|
123
114
|
removeItem: (key) => db.executeAsync('DELETE FROM keyvaluepairs WHERE record_key = ?;', [key]),
|
|
124
|
-
|
|
125
115
|
/**
|
|
126
116
|
* Removes given keys and their values from storage
|
|
127
117
|
*
|
|
@@ -129,28 +119,25 @@ const provider = {
|
|
|
129
119
|
* @returns {Promise<void>}
|
|
130
120
|
*/
|
|
131
121
|
removeItems: (keys) => {
|
|
132
|
-
const placeholders =
|
|
122
|
+
const placeholders = underscore_1.default.map(keys, () => '?').join(',');
|
|
133
123
|
const query = `DELETE FROM keyvaluepairs WHERE record_key IN (${placeholders});`;
|
|
134
124
|
return db.executeAsync(query, keys);
|
|
135
125
|
},
|
|
136
|
-
|
|
137
126
|
/**
|
|
138
127
|
* Clears absolutely everything from storage
|
|
139
128
|
* @returns {Promise<void>}
|
|
140
129
|
*/
|
|
141
130
|
clear: () => db.executeAsync('DELETE FROM keyvaluepairs;', []),
|
|
142
|
-
|
|
143
131
|
/**
|
|
144
132
|
* Noop on mobile for now.
|
|
145
133
|
*/
|
|
146
|
-
setMemoryOnlyKeys: () => {},
|
|
147
|
-
|
|
134
|
+
setMemoryOnlyKeys: () => { },
|
|
148
135
|
/**
|
|
149
136
|
* Gets the total bytes of the database file
|
|
150
137
|
* @returns {Promise}
|
|
151
138
|
*/
|
|
152
139
|
getDatabaseSize() {
|
|
153
|
-
return Promise.all([db.executeAsync('PRAGMA page_size;'), db.executeAsync('PRAGMA page_count;'), getFreeDiskStorage()]).then(([pageSizeResult, pageCountResult, bytesRemaining]) => {
|
|
140
|
+
return Promise.all([db.executeAsync('PRAGMA page_size;'), db.executeAsync('PRAGMA page_count;'), (0, react_native_device_info_1.getFreeDiskStorage)()]).then(([pageSizeResult, pageCountResult, bytesRemaining]) => {
|
|
154
141
|
const pageSize = pageSizeResult.rows.item(0).page_size;
|
|
155
142
|
const pageCount = pageCountResult.rows.item(0).page_count;
|
|
156
143
|
return {
|
|
@@ -159,11 +146,9 @@ const provider = {
|
|
|
159
146
|
};
|
|
160
147
|
});
|
|
161
148
|
},
|
|
162
|
-
|
|
163
149
|
/**
|
|
164
150
|
* Noop on native
|
|
165
151
|
*/
|
|
166
|
-
keepInstancesSync: () => {},
|
|
152
|
+
keepInstancesSync: () => { },
|
|
167
153
|
};
|
|
168
|
-
|
|
169
|
-
export default provider;
|
|
154
|
+
exports.default = provider;
|
package/{lib → dist}/utils.js
RENAMED
|
@@ -1,26 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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 underscore_1 = __importDefault(require("underscore"));
|
|
3
7
|
function areObjectsEmpty(a, b) {
|
|
4
|
-
return typeof a === 'object' && typeof b === 'object' &&
|
|
8
|
+
return typeof a === 'object' && typeof b === 'object' && underscore_1.default.isEmpty(a) && underscore_1.default.isEmpty(b);
|
|
5
9
|
}
|
|
6
|
-
|
|
7
10
|
// Mostly copied from https://medium.com/@lubaka.a/how-to-remove-lodash-performance-improvement-b306669ad0e1
|
|
8
|
-
|
|
9
11
|
/**
|
|
10
12
|
* @param {mixed} val
|
|
11
13
|
* @returns {boolean}
|
|
12
14
|
*/
|
|
13
15
|
function isMergeableObject(val) {
|
|
14
16
|
const nonNullObject = val != null ? typeof val === 'object' : false;
|
|
15
|
-
return (
|
|
16
|
-
nonNullObject &&
|
|
17
|
+
return (nonNullObject &&
|
|
17
18
|
Object.prototype.toString.call(val) !== '[object RegExp]' &&
|
|
18
19
|
Object.prototype.toString.call(val) !== '[object Date]' &&
|
|
19
20
|
// eslint-disable-next-line rulesdir/prefer-underscore-method
|
|
20
|
-
!Array.isArray(val)
|
|
21
|
-
);
|
|
21
|
+
!Array.isArray(val));
|
|
22
22
|
}
|
|
23
|
-
|
|
24
23
|
/**
|
|
25
24
|
* @param {Object} target
|
|
26
25
|
* @param {Object} source
|
|
@@ -35,46 +34,38 @@ function mergeObject(target, source, shouldRemoveNullObjectValues = true) {
|
|
|
35
34
|
const targetKeys = Object.keys(target);
|
|
36
35
|
for (let i = 0; i < targetKeys.length; ++i) {
|
|
37
36
|
const key = targetKeys[i];
|
|
38
|
-
|
|
39
37
|
// If shouldRemoveNullObjectValues is true, we want to remove null values from the merged object
|
|
40
38
|
const isSourceOrTargetNull = target[key] === null || source[key] === null;
|
|
41
39
|
const shouldOmitSourceKey = shouldRemoveNullObjectValues && isSourceOrTargetNull;
|
|
42
|
-
|
|
43
40
|
if (!shouldOmitSourceKey) {
|
|
44
41
|
destination[key] = target[key];
|
|
45
42
|
}
|
|
46
43
|
}
|
|
47
44
|
}
|
|
48
|
-
|
|
49
45
|
// lodash adds a small overhead so we don't use it here
|
|
50
46
|
// eslint-disable-next-line rulesdir/prefer-underscore-method
|
|
51
47
|
const sourceKeys = Object.keys(source);
|
|
52
48
|
for (let i = 0; i < sourceKeys.length; ++i) {
|
|
53
49
|
const key = sourceKeys[i];
|
|
54
|
-
|
|
55
50
|
// If shouldRemoveNullObjectValues is true, we want to remove null values from the merged object
|
|
56
51
|
const shouldOmitSourceKey = shouldRemoveNullObjectValues && source[key] === null;
|
|
57
|
-
|
|
58
52
|
// If we pass undefined as the updated value for a key, we want to generally ignore it
|
|
59
53
|
const isSourceKeyUndefined = source[key] === undefined;
|
|
60
|
-
|
|
61
54
|
if (!isSourceKeyUndefined && !shouldOmitSourceKey) {
|
|
62
55
|
const isSourceKeyMergable = isMergeableObject(source[key]);
|
|
63
|
-
|
|
64
56
|
if (isSourceKeyMergable && target[key]) {
|
|
65
57
|
if (!shouldRemoveNullObjectValues || isSourceKeyMergable) {
|
|
66
58
|
// eslint-disable-next-line no-use-before-define
|
|
67
59
|
destination[key] = fastMerge(target[key], source[key], shouldRemoveNullObjectValues);
|
|
68
60
|
}
|
|
69
|
-
}
|
|
61
|
+
}
|
|
62
|
+
else if (!shouldRemoveNullObjectValues || source[key] !== null) {
|
|
70
63
|
destination[key] = source[key];
|
|
71
64
|
}
|
|
72
65
|
}
|
|
73
66
|
}
|
|
74
|
-
|
|
75
67
|
return destination;
|
|
76
68
|
}
|
|
77
|
-
|
|
78
69
|
/**
|
|
79
70
|
* Merges two objects and removes null values if "shouldRemoveNullObjectValues" is set to true
|
|
80
71
|
*
|
|
@@ -91,22 +82,18 @@ function fastMerge(target, source, shouldRemoveNullObjectValues = true) {
|
|
|
91
82
|
// We have to ignore arrays and nullish values here,
|
|
92
83
|
// otherwise "mergeObject" will throw an error,
|
|
93
84
|
// because it expects an object as "source"
|
|
94
|
-
if (
|
|
85
|
+
if (underscore_1.default.isArray(source) || source === null || source === undefined) {
|
|
95
86
|
return source;
|
|
96
87
|
}
|
|
97
88
|
return mergeObject(target, source, shouldRemoveNullObjectValues);
|
|
98
89
|
}
|
|
99
|
-
|
|
100
90
|
function removeNestedNullValues(value) {
|
|
101
|
-
if (typeof value === 'object' && !
|
|
91
|
+
if (typeof value === 'object' && !underscore_1.default.isArray(value)) {
|
|
102
92
|
return fastMerge(value, value);
|
|
103
93
|
}
|
|
104
|
-
|
|
105
94
|
return value;
|
|
106
95
|
}
|
|
107
|
-
|
|
108
96
|
function formatActionName(method, key) {
|
|
109
97
|
return key ? `${method.toUpperCase()}/${key}` : method.toUpperCase();
|
|
110
98
|
}
|
|
111
|
-
|
|
112
|
-
export default {areObjectsEmpty, fastMerge, formatActionName, removeNestedNullValues};
|
|
99
|
+
exports.default = { areObjectsEmpty, fastMerge, formatActionName, removeNestedNullValues };
|