@onehat/data 1.7.14 → 1.7.15

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.
@@ -580,6 +580,21 @@ describe('Entity', function() {
580
580
  this.entity.markStaged(false);
581
581
  expect(this.entity.isStaged).to.be.false;
582
582
  });
583
+
584
+ it('setValue changed lastModified', function() {
585
+ let earlyLastModified,
586
+ lateLastModified;
587
+
588
+ earlyLastModified = this.entity.lastModified;
589
+ this.entity.setValue('foo', '125');
590
+ lateLastModified = this.entity.lastModified;
591
+ expect(earlyLastModified < lateLastModified).to.be.true;
592
+
593
+ earlyLastModified = this.entity.lastModified;
594
+ this.entity.foo = '126';
595
+ lateLastModified = this.entity.lastModified;
596
+ expect(earlyLastModified < lateLastModified).to.be.true;
597
+ });
583
598
  });
584
599
 
585
600
  describe('events', function() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onehat/data",
3
- "version": "1.7.14",
3
+ "version": "1.7.15",
4
4
  "description": "JS data modeling package with adapters for many storage mediums.",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/Entity.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import EventEmitter from '@onehat/events';
4
4
  import PropertyTypes from './Property';
5
+ import moment from 'moment';
5
6
  import _ from 'lodash';
6
7
 
7
8
  /**
@@ -129,6 +130,11 @@ class Entity extends EventEmitter {
129
130
  */
130
131
  this.isDestroyed = false;
131
132
 
133
+ /**
134
+ * @member {string} lastModified - Last time this entity was modified
135
+ */
136
+ this.lastModified = null;
137
+
132
138
  // This ES6 Proxy allows us to create magic getters and setters for all property values.
133
139
  // However, these getters and setters are *not* available within the Entity itself.
134
140
  this._proxy = new Proxy(this, {
@@ -325,6 +331,7 @@ class Entity extends EventEmitter {
325
331
  if (this.isDeleted) {
326
332
  this.undelete();
327
333
  }
334
+ this.setLastModified();
328
335
 
329
336
  this.emit('reset', this._proxy);
330
337
  }
@@ -399,6 +406,10 @@ class Entity extends EventEmitter {
399
406
  }
400
407
  return value;
401
408
  }
409
+
410
+ setLastModified = () => {
411
+ this.lastModified = moment(new Date()).format('YYYY-MM-DD HH:mm:ss.SSSS');
412
+ }
402
413
 
403
414
 
404
415
  // ______ __ __
@@ -990,6 +1001,7 @@ class Entity extends EventEmitter {
990
1001
  }
991
1002
 
992
1003
  idProperty.isTempId = false;
1004
+ this.setLastModified();
993
1005
 
994
1006
  return isChanged;
995
1007
  }
@@ -1034,6 +1046,7 @@ class Entity extends EventEmitter {
1034
1046
  }
1035
1047
  property.resumeEvents();
1036
1048
  });
1049
+ this.setLastModified();
1037
1050
 
1038
1051
  if (isChanged) {
1039
1052
  this._recalculateDependentProperties();
@@ -362,7 +362,7 @@ class AjaxRepository extends Repository {
362
362
  throw new Error('No "get" api endpoint defined.');
363
363
  }
364
364
  this.emit('beforeLoad'); // TODO: canceling beforeLoad will cancel the load operation
365
- this.isLoading = true;
365
+ this.markLoading();
366
366
 
367
367
 
368
368
  if (!_.isNil(params) && _.isObject(params)) {
@@ -407,9 +407,9 @@ class AjaxRepository extends Repository {
407
407
  // Set the total records that pass filter
408
408
  this.total = total;
409
409
  this._setPaginationVars();
410
-
411
- this.isLoading = false;
412
- this.isLoaded = true;
410
+
411
+ this.markLoaded();
412
+
413
413
  this.emit('changeData', this.entities);
414
414
  this.emit('load', this);
415
415
  })
@@ -432,7 +432,7 @@ class AjaxRepository extends Repository {
432
432
  throw new Error('No "get" api endpoint defined.');
433
433
  }
434
434
  this.emit('beforeLoad'); // TODO: canceling beforeLoad will cancel the load operation
435
- this.isLoading = true;
435
+ this.markLoading();
436
436
 
437
437
  const params = this._getReloadEntityParams(entity);
438
438
  if (this.debugMode) {
@@ -460,8 +460,8 @@ class AjaxRepository extends Repository {
460
460
  entity.loadOriginalData(updatedData, true);
461
461
  entity.emit('reload', entity);
462
462
 
463
- this.isLoading = false;
464
- this.isLoaded = true;
463
+ this.markLoaded();
464
+
465
465
  this.emit('changeData', this.entities);
466
466
  this.emit('load', this);
467
467
  this.emit('reloadEntity', entity);
@@ -95,7 +95,7 @@ class MemoryRepository extends Repository {
95
95
  }
96
96
 
97
97
  this.emit('beforeLoad');
98
- this.isLoading = true;
98
+ this.markLoading();
99
99
 
100
100
 
101
101
  const isDirectLoad = !_.isNil(data);
@@ -143,8 +143,7 @@ class MemoryRepository extends Repository {
143
143
  await this._saveToStorage(entities);
144
144
  }
145
145
 
146
- this.isLoading = false;
147
- this.isLoaded = true;
146
+ this.markLoaded();
148
147
  this._recalculate(); // fires changeData if needed
149
148
  this.emit('load', entities, this);
150
149
  return entities;
@@ -444,6 +443,21 @@ class MemoryRepository extends Repository {
444
443
  })
445
444
  }
446
445
  /* */
446
+
447
+ removeEntity(entity) { // standard function notation
448
+ const id = entity.id;
449
+
450
+ super.removeEntity(entity);
451
+
452
+ if (this.hasSorters) {
453
+ this._applySorters();
454
+ }
455
+ if (this.hasFilters) {
456
+ this._applyFilters();
457
+ }
458
+ delete this._keyedEntities[id];
459
+ }
460
+
447
461
 
448
462
 
449
463
 
@@ -46,7 +46,7 @@ class NullRepository extends Repository {
46
46
  throw Error('this.load is no longer valid. Repository has been destroyed.');
47
47
  }
48
48
  this.emit('beforeLoad');
49
- this.isLoading = true;
49
+ this.markLoading();
50
50
 
51
51
  if (data) {
52
52
  let entities = data;
@@ -65,8 +65,7 @@ class NullRepository extends Repository {
65
65
 
66
66
  this._updateSize();
67
67
 
68
- this.isLoading = false;
69
- this.isLoaded = true;
68
+ this.markLoaded();
70
69
  this.emit('changeData', this.entities);
71
70
  this.emit('load', this);
72
71
  }
@@ -5,6 +5,7 @@ import Entity from '../Entity';
5
5
  import {
6
6
  v4 as uuid,
7
7
  } from 'uuid';
8
+ import moment from 'moment';
8
9
  import _ from 'lodash';
9
10
 
10
11
  /**
@@ -194,6 +195,11 @@ export default class Repository extends EventEmitter {
194
195
  */
195
196
  this.isLoading = false;
196
197
 
198
+ /**
199
+ * @member {string} lastLoaded - Last time this repository was loaded
200
+ */
201
+ this.lastLoaded = null;
202
+
197
203
  /**
198
204
  * @member {Boolean} isSaving - State: whether or not entities are currently being saved
199
205
  */
@@ -323,6 +329,22 @@ export default class Repository extends EventEmitter {
323
329
  throw new Error('load must be implemented by Repository subclass');
324
330
  }
325
331
 
332
+ /**
333
+ * Marks this repository as loading
334
+ */
335
+ markLoading = () => {
336
+ this.isLoading = true;
337
+ }
338
+
339
+ /**
340
+ * Marks this repository as loaded
341
+ */
342
+ markLoaded = () => {
343
+ this.isLoading = false;
344
+ this.isLoaded = true;
345
+ this.lastLoaded = moment(new Date()).format('YYYY-MM-DD HH:mm:ss.SSSS');
346
+ }
347
+
326
348
  /**
327
349
  * Reload data from storage medium, using previous settings.
328
350
  * Subclasses may override this to provide additional
@@ -1595,7 +1617,7 @@ export default class Repository extends EventEmitter {
1595
1617
  * Mainly used for phantom Entities
1596
1618
  * Helper for delete()
1597
1619
  */
1598
- removeEntity = async (entity) => {
1620
+ removeEntity(entity) { // standard function notation so it can be called by child class
1599
1621
  this.entities = _.filter(this.entities, e => e !== entity);
1600
1622
  entity.destroy();
1601
1623
  }