@onehat/data 1.4.6 → 1.4.10

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.
@@ -30,6 +30,43 @@ describe('OneBuildRepository', function() {
30
30
  });
31
31
 
32
32
  describe('Params', function() {
33
+
34
+ it('setParam', function() {
35
+ const r = this.repository;
36
+ r.setParam('test', 1);
37
+
38
+ expect(r._params.test).to.be.eq(1);
39
+ });
40
+
41
+ it('setParams', function() {
42
+ const r = this.repository;
43
+ r.setParams({
44
+ test1: 1,
45
+ test2: 2,
46
+ });
47
+
48
+ expect(r._params.test1).to.be.eq(1);
49
+ expect(r._params.test2).to.be.eq(2);
50
+ });
51
+
52
+ it('setBaseParam', function() {
53
+ const r = this.repository;
54
+ r.setBaseParam('test', 1);
55
+
56
+ expect(r._baseParams.test).to.be.eq(1);
57
+ });
58
+
59
+ it('setBaseParams', function() {
60
+ const r = this.repository;
61
+ r.setBaseParams({
62
+ test1: 1,
63
+ test2: 2,
64
+ });
65
+
66
+ expect(r._baseParams.test1).to.be.eq(1);
67
+ expect(r._baseParams.test2).to.be.eq(2);
68
+ });
69
+
33
70
  it('setValuelessParam', function() {
34
71
  const r = this.repository;
35
72
  r.setParam('conditions[field]', 1);
@@ -38,6 +75,24 @@ describe('OneBuildRepository', function() {
38
75
  expect(r._params.conditions.field).to.be.eq(1);
39
76
  expect(r._params.conditions[0]).to.be.eq('field IS NOT NULL');
40
77
  });
78
+
79
+ it('clearParams', function() {
80
+ const r = this.repository;
81
+ r.setParams({
82
+ test1: 1,
83
+ test2: 2,
84
+ });
85
+ r.setBaseParams({
86
+ test1: 1,
87
+ test2: 2,
88
+ });
89
+
90
+ r.clearParams(false, true);
91
+
92
+ expect(r._params).to.be.empty;
93
+ expect(r._baseParams).to.be.empty;
94
+ });
95
+
41
96
  });
42
97
 
43
98
  describe('custom', function() {
@@ -372,6 +372,19 @@ describe('Repository Base', function() {
372
372
  expect(didFireChangeFilters).to.be.true;
373
373
  });
374
374
 
375
+ it('changing filters resets pagination', function() {
376
+ this.repository.isPaginated = true;
377
+ this.repository.setPageSize(1);
378
+ this.repository.setPage(3);
379
+
380
+ this.repository.setFilters({
381
+ b: '1',
382
+ c: '2',
383
+ });
384
+
385
+ expect(this.repository.page).to.be.eq(1);
386
+ });
387
+
375
388
  });
376
389
 
377
390
  describe('pagination', function() {
@@ -471,6 +484,18 @@ describe('Repository Base', function() {
471
484
  expect(results.pageTotal).to.be.eq(1);
472
485
  });
473
486
 
487
+ it('reset pagination', function() {
488
+ expect(this.repository.page).to.be.eq(1);
489
+
490
+ this.repository.isPaginated = true;
491
+ this.repository.setPageSize(1);
492
+ this.repository.setPage(3);
493
+ expect(this.repository.page).to.be.eq(3);
494
+
495
+ this.repository.resetPagination();
496
+ expect(this.repository.page).to.be.eq(1);
497
+ });
498
+
474
499
  });
475
500
 
476
501
  describe('creating', function() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onehat/data",
3
- "version": "1.4.6",
3
+ "version": "1.4.10",
4
4
  "description": "JS data modeling package with adapters for many storage mediums.",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -1,7 +1,12 @@
1
+ /**
2
+ * This file is categorized as "Proprietary Framework Code"
3
+ * and is subject to the terms and conditions defined in
4
+ * file 'LICENSE.txt', which is part of this source code package.
5
+ */
1
6
  /** @module Repository */
2
7
 
3
8
  import OfflineRepository from '@onehat/data/src/Repository/Offline.js';
4
- import AsyncStorage from '@react-native-community/async-storage';
9
+ import AsyncStorage from '@react-native-async-storage/async-storage';
5
10
  import _ from 'lodash';
6
11
 
7
12
  /**
@@ -37,10 +42,12 @@ class AsyncStorageRepository extends OfflineRepository {
37
42
  value = result; // Invalid JSON, just return raw result
38
43
  }
39
44
  }
45
+
40
46
  return value;
41
47
  } catch (error) {
42
48
  if (this.debugMode) {
43
49
  const msg = error && error.message;
50
+ console.log('_storageGetValue error', msg);
44
51
  debugger;
45
52
  }
46
53
  }
@@ -60,7 +67,7 @@ class AsyncStorageRepository extends OfflineRepository {
60
67
  const results = await AsyncStorage.multiGet(this._namespace(keys));
61
68
 
62
69
  if (this.debugMode) {
63
- console.log(this.name, 'AsyncStorage.multiGet results', name, results);
70
+ console.log(this.name, 'AsyncStorage.multiGet results', results);
64
71
  }
65
72
 
66
73
  let values = [];
@@ -72,7 +79,17 @@ class AsyncStorageRepository extends OfflineRepository {
72
79
  } catch (e) {
73
80
  parsed = value; // Invalid JSON, just return raw result
74
81
  }
75
- values.push(parsed);
82
+ if (parsed === null) {
83
+ // Values should be stored as JSON, so it should be either {} or []. If it's null, that means the AsyncStorage can't find the record
84
+ // Delete the index to this record
85
+ const re = new RegExp('^' + this.name + '\-' + '(.*)'),
86
+ matches = key.match(re);
87
+ debugger;
88
+ const id = parseInt(matches, 10);
89
+ this._deleteFromIndex(id);
90
+ } else {
91
+ values.push(parsed);
92
+ }
76
93
  })
77
94
  }
78
95
 
@@ -84,6 +101,7 @@ class AsyncStorageRepository extends OfflineRepository {
84
101
  } catch (error) {
85
102
  if (this.debugMode) {
86
103
  const msg = error && error.message;
104
+ console.log('_storageGetMultiple error', msg);
87
105
  debugger;
88
106
  }
89
107
  }
@@ -103,6 +121,7 @@ class AsyncStorageRepository extends OfflineRepository {
103
121
  } catch (error) {
104
122
  if (this.debugMode) {
105
123
  const msg = error && error.message;
124
+ console.log('_storageSetValue error', msg);
106
125
  debugger;
107
126
  }
108
127
  }
@@ -126,11 +145,16 @@ class AsyncStorageRepository extends OfflineRepository {
126
145
  console.log(this.name, 'AsyncStorage.multiSet', keys);
127
146
  }
128
147
 
148
+ if (_.isEmpty(converted)) {
149
+ return;
150
+ }
151
+
129
152
  return await AsyncStorage.multiSet(converted);
130
153
 
131
154
  } catch (error) {
132
155
  if (this.debugMode) {
133
156
  const msg = error && error.message;
157
+ console.log('_storageSetMultiple error', msg);
134
158
  debugger;
135
159
  }
136
160
  }
@@ -151,6 +175,7 @@ class AsyncStorageRepository extends OfflineRepository {
151
175
  } catch (error) {
152
176
  if (this.debugMode) {
153
177
  const msg = error && error.message;
178
+ console.log('_storageDeleteValue error', msg);
154
179
  debugger;
155
180
  }
156
181
  }
@@ -171,6 +196,7 @@ class AsyncStorageRepository extends OfflineRepository {
171
196
  } catch (error) {
172
197
  if (this.debugMode) {
173
198
  const msg = error && error.message;
199
+ console.log('_storageDeleteMultiple error', msg);
174
200
  debugger;
175
201
  }
176
202
  }
@@ -1,94 +1,99 @@
1
- import OfflineRepository from '@onehat/data/src/Repository/Offline';
2
- import * as SecureStore from 'expo-secure-store'; // see: https://docs.expo.io/versions/latest/sdk/securestore/
3
- import _ from 'lodash';
4
-
5
1
  /**
6
- * Repository representing Expo's SecureStore
7
- * Uses expo-secure-store package
2
+ * This file is categorized as "Proprietary Framework Code"
3
+ * and is subject to the terms and conditions defined in
4
+ * file 'LICENSE.txt', which is part of this source code package.
8
5
  */
9
- class SecureStoreRepository extends OfflineRepository {
10
-
11
- constructor(config = {}) {
12
- super(...arguments);
13
- _.merge(this, config);
14
- }
15
-
16
- _storageGetValue = async (name) => {
17
- try {
18
-
19
- if (this.debugMode) {
20
- console.log(this.name, 'SecureStore.get', name);
21
- }
22
-
23
- const result = await SecureStore.getItemAsync(this._namespace(name));
24
-
25
- if (this.debugMode) {
26
- console.log(this.name, 'SecureStore.get results', name, result);
27
- }
28
-
29
- let value;
30
- if (!_.isNil(result)) {
31
- try {
32
- value = JSON.parse(result);
33
- } catch (e) {
34
- value = result; // Invalid JSON, just return raw result
35
- }
36
- }
37
- return value;
38
- } catch (error) {
39
- if (this.debugMode) {
40
- const msg = error && error.message;
41
- debugger;
42
- }
43
- }
44
- }
45
-
46
- _storageSetValue = async (name, value) => {
47
- try {
48
- if (!_.isString(value)) {
49
- value = JSON.stringify(value);
50
- }
51
- if (this.debugMode) {
52
- console.log(this.name, 'SecureStore.set', name, value);
53
- }
54
-
55
- const result = await SecureStore.setItemAsync(this._namespace(name), value);
56
-
57
- // if (this.debugMode) {
58
- // console.log(this.name, 'SecureStore.set results', name, result);
59
- // }
60
- return result;
61
- } catch (error) {
62
- if (this.debugMode) {
63
- const msg = error && error.message;
64
- debugger;
65
- }
66
- }
67
- }
68
-
69
- _storageDeleteValue = async (name) => {
70
- try {
71
- if (this.debugMode) {
72
- console.log(this.name, 'SecureStore.delete', name);
73
- }
74
-
75
- const result = await SecureStore.deleteItemAsync(this._namespace(name));
76
-
77
- // if (this.debugMode) {
78
- // console.log(this.name, 'SecureStore.delete results', name, result);
79
- // }
80
- return result;
81
- } catch (error) {
82
- if (this.debugMode) {
83
- const msg = error && error.message;
84
- debugger;
85
- }
86
- }
87
- }
88
-
89
- };
90
-
91
- SecureStoreRepository.className = 'SecureStore';
92
- SecureStoreRepository.type = 'secure';
93
-
94
- export default SecureStoreRepository;
6
+ import OfflineRepository from '@onehat/data/src/Repository/Offline.js';
7
+ import * as SecureStore from 'expo-secure-store'; // see: https://docs.expo.io/versions/latest/sdk/securestore/
8
+ import _ from 'lodash';
9
+
10
+ /**
11
+ * Repository representing Expo's SecureStore
12
+ * Uses expo-secure-store package
13
+ */
14
+ class SecureStoreRepository extends OfflineRepository {
15
+
16
+ constructor(config = {}) {
17
+ super(...arguments);
18
+ _.merge(this, config);
19
+ }
20
+
21
+ _storageGetValue = async (name) => {
22
+ try {
23
+
24
+ if (this.debugMode) {
25
+ console.log(this.name, 'SecureStore.get', name);
26
+ }
27
+
28
+ const result = await SecureStore.getItemAsync(this._namespace(name));
29
+
30
+ if (this.debugMode) {
31
+ console.log(this.name, 'SecureStore.get results', name, result);
32
+ }
33
+
34
+ let value;
35
+ if (!_.isNil(result)) {
36
+ try {
37
+ value = JSON.parse(result);
38
+ } catch (e) {
39
+ value = result; // Invalid JSON, just return raw result
40
+ }
41
+ }
42
+ return value;
43
+ } catch (error) {
44
+ if (this.debugMode) {
45
+ const msg = error && error.message;
46
+ debugger;
47
+ }
48
+ }
49
+ }
50
+
51
+ _storageSetValue = async (name, value) => {
52
+ try {
53
+ if (!_.isString(value)) {
54
+ value = JSON.stringify(value);
55
+ }
56
+ if (this.debugMode) {
57
+ console.log(this.name, 'SecureStore.set', name, value);
58
+ }
59
+
60
+ const result = await SecureStore.setItemAsync(this._namespace(name), value);
61
+
62
+ // if (this.debugMode) {
63
+ // console.log(this.name, 'SecureStore.set results', name, result);
64
+ // }
65
+ return result;
66
+ } catch (error) {
67
+ if (this.debugMode) {
68
+ const msg = error && error.message;
69
+ debugger;
70
+ }
71
+ }
72
+ }
73
+
74
+ _storageDeleteValue = async (name) => {
75
+ try {
76
+ if (this.debugMode) {
77
+ console.log(this.name, 'SecureStore.delete', name);
78
+ }
79
+
80
+ const result = await SecureStore.deleteItemAsync(this._namespace(name));
81
+
82
+ // if (this.debugMode) {
83
+ // console.log(this.name, 'SecureStore.delete results', name, result);
84
+ // }
85
+ return result;
86
+ } catch (error) {
87
+ if (this.debugMode) {
88
+ const msg = error && error.message;
89
+ debugger;
90
+ }
91
+ }
92
+ }
93
+
94
+ };
95
+
96
+ SecureStoreRepository.className = 'SecureStore';
97
+ SecureStoreRepository.type = 'secure';
98
+
99
+ export default SecureStoreRepository;
@@ -87,9 +87,9 @@ class AjaxRepository extends Repository {
87
87
  headers: {},
88
88
 
89
89
  /**
90
- * @member {object} baseParams - Params that will be applied to every request
90
+ * @member {object} _baseParams - Params that will be applied to every request
91
91
  */
92
- baseParams: {},
92
+ _baseParams: {},
93
93
 
94
94
  };
95
95
  _.merge(this, defaults, config);
@@ -202,8 +202,7 @@ class AjaxRepository extends Repository {
202
202
  setParam = (name, value, isBaseParam = false) => {
203
203
  const re = /^([^\[]+)\[([^\]]+)\](.*)$/,
204
204
  matches = name.match(re),
205
- paramsToChange = isBaseParam ? this.baseParams : this._params;
206
-
205
+ paramsToChange = isBaseParam ? this._baseParams : this._params;
207
206
 
208
207
  if (matches) { // name has array notation like 'conditions[username]'
209
208
  const first = matches[1],
@@ -234,7 +233,7 @@ class AjaxRepository extends Repository {
234
233
  setValuelessParam = (name, isBaseParam = false) => {
235
234
  const re = /^([^\[]+)\[([^\]]+)\](.*)$/,
236
235
  matches = name.match(re),
237
- paramsToChange = isBaseParam ? this.baseParams : this._params;
236
+ paramsToChange = isBaseParam ? this._baseParams : this._params;
238
237
 
239
238
  if (matches) { // name has array notation like 'conditions[username]'
240
239
  const first = matches[1],
@@ -262,24 +261,35 @@ class AjaxRepository extends Repository {
262
261
  });
263
262
  }
264
263
 
264
+ /**
265
+ * Sets base query param
266
+ * @param {string} name - Param name to set.
267
+ * @param {any} value - Param value to set.
268
+ */
269
+ setBaseParam = (name, value) => {
270
+ this.setParam(name, value, true);
271
+ }
272
+
265
273
  /**
266
274
  * Sets base query params. These params are sent on every request.
267
275
  * @param {object} params - Base params to set. Key is parameter name, value is parameter value
268
276
  */
269
277
  setBaseParams = (params) => {
270
278
  _.each(params, (value, name) => {
271
- this.setParam(name, value, true);
279
+ this.setBaseParam(name, value);
272
280
  });
273
281
  }
274
282
 
275
283
  /**
276
- * Manually clears all existing (non-base) params
277
- * including sorting, filtering, and pagination.
284
+ * Manually clears all (non-base) params including filtering.
278
285
  * *Not intended for normal usage,* but rather for testing.
279
286
  * @param {boolean} reload - Whether to reload repository. Defaults to false.
280
287
  */
281
- clearParams = (reload = false) => {
288
+ clearParams = (reload = false, clearBase = false) => {
282
289
  this._params = {};
290
+ if (clearBase) {
291
+ this._baseParams = {};
292
+ }
283
293
  if (reload && this.isLoaded) {
284
294
  return this.reload();
285
295
  }
@@ -292,8 +302,8 @@ class AjaxRepository extends Repository {
292
302
  */
293
303
  _onChangeSorters = () => {
294
304
  const sorter = this.sorters[0];
295
- this.setParam(this.paramSort, sorter.name);
296
- this.setParam(this.paramDirection, sorter.direction);
305
+ this.setBaseParam(this.paramSort, sorter.name);
306
+ this.setBaseParam(this.paramDirection, sorter.direction);
297
307
 
298
308
  if (this.isLoaded) {
299
309
  return this.reload();
@@ -319,8 +329,8 @@ class AjaxRepository extends Repository {
319
329
  * Refreshes entities.
320
330
  */
321
331
  _onChangePagination = () => {
322
- this.setParam(this.paramPageNum, this.page);
323
- this.setParam(this.paramPageSize, this.pageSize);
332
+ this.setBaseParam(this.paramPageNum, this.page);
333
+ this.setBaseParam(this.paramPageSize, this.pageSize);
324
334
 
325
335
  if (this.isLoaded) {
326
336
  return this.reload();
@@ -360,7 +370,7 @@ class AjaxRepository extends Repository {
360
370
  }
361
371
 
362
372
  const repository = this;
363
- const data = _.assign({}, this.baseParams, this._params);
373
+ const data = _.assign({}, this._baseParams, this._params);
364
374
 
365
375
  return this._send(this.methods.get, this.api.get, data)
366
376
  .then(result => {
@@ -462,7 +472,7 @@ class AjaxRepository extends Repository {
462
472
  const params = {
463
473
  id: entity.id,
464
474
  };
465
- return _.assign({}, this.baseParams, params);
475
+ return _.assign({}, this._baseParams, params);
466
476
  }
467
477
 
468
478
  /**
@@ -23,13 +23,8 @@ class OfflineRepository extends MemoryRepository {
23
23
 
24
24
  async initialize() {
25
25
  this.pauseEvents(); // Queue 'initialize' event from super
26
- await super.initialize();
27
26
 
28
- this._index = await this._getIndex();
29
- if (!this._index) {
30
- await this._setIndex([]);
31
- this._index = [];
32
- }
27
+ await super.initialize(); // Initializes index in _loadFromStorage()
33
28
 
34
29
  this.resumeEvents(true); // Now fire it!
35
30
  }
@@ -80,7 +75,14 @@ class OfflineRepository extends MemoryRepository {
80
75
  */
81
76
  _loadFromStorage = async () => {
82
77
  try {
83
- const ids = await this._getIndex(),
78
+
79
+ this._index = await this._getIndex();
80
+ if (!this._index) {
81
+ await this._setIndex([]);
82
+ this._index = [];
83
+ }
84
+
85
+ const ids = this._index,
84
86
  total = ids && ids.length ? ids.length : 0,
85
87
  results = [];
86
88
 
@@ -648,6 +648,7 @@ export default class Repository extends EventEmitter {
648
648
  if (!_.isEqual(this.filters, filters)) {
649
649
  isChanged = true;
650
650
  this.filters = filters;
651
+ this.resetPagination();
651
652
  this.emit('changeFilters');
652
653
  if (this._onChangeFilters) {
653
654
  return this._onChangeFilters();
@@ -666,6 +667,17 @@ export default class Repository extends EventEmitter {
666
667
  // /_/ \__,_/\__, /_/_/ /_/\__,_/\__/\___/
667
668
  // /____/
668
669
 
670
+ /**
671
+ * Resets the pagination to page one
672
+ * @fires changePageSize
673
+ */
674
+ resetPagination = (pageSize) => {
675
+ if (this.isDestroyed) {
676
+ throw Error('this.resetPagination is no longer valid. Repository has been destroyed.');
677
+ }
678
+ this.setPage(1);
679
+ }
680
+
669
681
  /**
670
682
  * Sets the pageSize
671
683
  * @fires changePageSize
@@ -1328,6 +1340,9 @@ export default class Repository extends EventEmitter {
1328
1340
  if (!_.isArray(entities)) {
1329
1341
  entities = [entities];
1330
1342
  }
1343
+ if (!entities.length) {
1344
+ return;
1345
+ }
1331
1346
  _.each(entities, (entity) => {
1332
1347
  entity.markDeleted(); // Entity is still there, it's just marked for deletion
1333
1348
  });