@onehat/data 1.21.14 → 1.21.16
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.
|
@@ -147,6 +147,64 @@ describe('Repository Base', function() {
|
|
|
147
147
|
expect(this.repository.isAutoSave).to.be.false;
|
|
148
148
|
});
|
|
149
149
|
|
|
150
|
+
it('markLoaded', function() {
|
|
151
|
+
|
|
152
|
+
const repository = new this.Repository({
|
|
153
|
+
id: 'foo',
|
|
154
|
+
schema: this.schema,
|
|
155
|
+
isAutoLoad: false,
|
|
156
|
+
isAutoSave: true,
|
|
157
|
+
isPaginated: true,
|
|
158
|
+
data: [
|
|
159
|
+
{ key: 1, value: 'one', },
|
|
160
|
+
{ key: 2, value: 'two', },
|
|
161
|
+
{ key: 3, value: 'three', },
|
|
162
|
+
{ key: 4, value: 'four', },
|
|
163
|
+
{ key: 5, value: 'five', },
|
|
164
|
+
],
|
|
165
|
+
});
|
|
166
|
+
repository.initialize();
|
|
167
|
+
|
|
168
|
+
expect(repository.isLoading).to.be.false;
|
|
169
|
+
expect(repository.isLoaded).to.be.false;
|
|
170
|
+
expect(repository.lastLoaded).to.be.null;
|
|
171
|
+
|
|
172
|
+
repository.markLoaded();
|
|
173
|
+
|
|
174
|
+
expect(repository.isLoading).to.be.false;
|
|
175
|
+
expect(repository.isLoaded).to.be.true;
|
|
176
|
+
expect(repository.lastLoaded).to.be.not.null;
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('markUnloaded', function() {
|
|
180
|
+
|
|
181
|
+
const repository = new this.Repository({
|
|
182
|
+
id: 'foo',
|
|
183
|
+
schema: this.schema,
|
|
184
|
+
isAutoLoad: false,
|
|
185
|
+
isAutoSave: true,
|
|
186
|
+
isPaginated: true,
|
|
187
|
+
data: [
|
|
188
|
+
{ key: 1, value: 'one', },
|
|
189
|
+
{ key: 2, value: 'two', },
|
|
190
|
+
{ key: 3, value: 'three', },
|
|
191
|
+
{ key: 4, value: 'four', },
|
|
192
|
+
{ key: 5, value: 'five', },
|
|
193
|
+
],
|
|
194
|
+
});
|
|
195
|
+
repository.initialize();
|
|
196
|
+
|
|
197
|
+
repository.isLoading = true;
|
|
198
|
+
repository.isLoaded = true;
|
|
199
|
+
repository.lastLoaded = true;
|
|
200
|
+
|
|
201
|
+
repository.markUnloaded();
|
|
202
|
+
|
|
203
|
+
expect(repository.isLoading).to.be.false;
|
|
204
|
+
expect(repository.isLoaded).to.be.false;
|
|
205
|
+
expect(repository.lastLoaded).to.be.null;
|
|
206
|
+
});
|
|
207
|
+
|
|
150
208
|
});
|
|
151
209
|
|
|
152
210
|
describe('sorting', function() {
|
|
@@ -325,7 +383,7 @@ describe('Repository Base', function() {
|
|
|
325
383
|
expect(filter.value).to.be.eq('1');
|
|
326
384
|
});
|
|
327
385
|
|
|
328
|
-
it
|
|
386
|
+
it('filter - object', function() {
|
|
329
387
|
// two possible ways to call filter with an object
|
|
330
388
|
// 1. filter({ name: 'key', value: '1' });
|
|
331
389
|
this.repository.filter({
|
package/package.json
CHANGED
package/src/Repository/Ajax.js
CHANGED
|
@@ -1097,6 +1097,18 @@ class AjaxRepository extends Repository {
|
|
|
1097
1097
|
}));
|
|
1098
1098
|
}
|
|
1099
1099
|
|
|
1100
|
+
/**
|
|
1101
|
+
* Clears all state and storage of entities, as though nothing was ever loaded.
|
|
1102
|
+
*/
|
|
1103
|
+
clearAll() {
|
|
1104
|
+
this._destroyEntities();
|
|
1105
|
+
this.entities = [];
|
|
1106
|
+
this.total = 0;
|
|
1107
|
+
this._setPaginationVars();
|
|
1108
|
+
this.markUnloaded();
|
|
1109
|
+
this.emit('changeData', this.entities);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1100
1112
|
setIsOnline(isOnline) {
|
|
1101
1113
|
this.isOnline = !!isOnline; // force convert type to boolean
|
|
1102
1114
|
}
|
|
@@ -21,12 +21,14 @@ export const MODE_REMOTE_WITH_OFFLINE = 'MODE_REMOTE_WITH_OFFLINE';
|
|
|
21
21
|
* an AjaxRepository.
|
|
22
22
|
*
|
|
23
23
|
* Note: This is not a true subclass of Repository. Instead, its properties
|
|
24
|
-
* and methods are
|
|
24
|
+
* and methods are Proxied from the "ActiveRepository", either the local or remote,
|
|
25
25
|
* depending upon operating mode.
|
|
26
26
|
*
|
|
27
27
|
* Multiple operating modes:
|
|
28
|
-
* - MODE_LOCAL_MIRROR
|
|
29
|
-
* - This mode is for keeping local copies of data that
|
|
28
|
+
* - MODE_LOCAL_MIRROR (default mode)
|
|
29
|
+
* - This mode is for keeping local copies of data that don't change very often.
|
|
30
|
+
* - It's often used in apps for offline functionality--the app reads from this repository,
|
|
31
|
+
* and saves its commands to a CommandQueue repository.
|
|
30
32
|
* - *Add/Edit/Delete operations are disabled.*
|
|
31
33
|
* - First time in use, it loads its data from remote.
|
|
32
34
|
* - From then on, it primarily depends upon local.
|
|
@@ -54,7 +56,7 @@ export const MODE_REMOTE_WITH_OFFLINE = 'MODE_REMOTE_WITH_OFFLINE';
|
|
|
54
56
|
* Repository's remote repository type to be a CommandRepository.
|
|
55
57
|
*
|
|
56
58
|
*
|
|
57
|
-
* - MODE_REMOTE_WITH_OFFLINE
|
|
59
|
+
* - MODE_REMOTE_WITH_OFFLINE (not currently implemented)
|
|
58
60
|
* - This mode provides an offline backup to the normal operation of remote.
|
|
59
61
|
* - Normally uses remote, but automatically switches to local if necessary (i.e. if offline).
|
|
60
62
|
* - Any changes made while offline will be saved to a queue, and then replayed to remote
|
|
@@ -67,6 +69,8 @@ class LocalFromRemoteRepository extends EventEmitter {
|
|
|
67
69
|
constructor(config = {}) {
|
|
68
70
|
super(...arguments);
|
|
69
71
|
|
|
72
|
+
// OneHatData._createRepository has already created the local and remote repositories
|
|
73
|
+
|
|
70
74
|
if (!config.local || !(config.local instanceof Repository)) {
|
|
71
75
|
this.throwError('No local repository defined.');
|
|
72
76
|
return;
|
|
@@ -138,7 +142,6 @@ class LocalFromRemoteRepository extends EventEmitter {
|
|
|
138
142
|
|
|
139
143
|
};
|
|
140
144
|
_.merge(this, defaults, config);
|
|
141
|
-
|
|
142
145
|
|
|
143
146
|
if (this.mode !== MODE_LOCAL_MIRROR &&
|
|
144
147
|
this.mode !== MODE_REMOTE_WITH_OFFLINE &&
|
|
@@ -166,9 +169,9 @@ class LocalFromRemoteRepository extends EventEmitter {
|
|
|
166
169
|
*/
|
|
167
170
|
this.lastSync = null;
|
|
168
171
|
|
|
169
|
-
|
|
170
|
-
//
|
|
171
|
-
//
|
|
172
|
+
// This ES6 Proxy allows us to create magic getters and setters for all properties and methods
|
|
173
|
+
// of the active Repository (local or remote). If they exist on the LocalFromRemote, those are used.
|
|
174
|
+
// Otherwise, the Proxy will pass the getter or setter to the active Repository.
|
|
172
175
|
const oThis = this;
|
|
173
176
|
this._proxy = new Proxy(this, {
|
|
174
177
|
get (target, name, receiver) {
|
|
@@ -181,6 +184,14 @@ class LocalFromRemoteRepository extends EventEmitter {
|
|
|
181
184
|
}
|
|
182
185
|
return Reflect.get(target, name, receiver);
|
|
183
186
|
},
|
|
187
|
+
set(target, name, value, receiver) {
|
|
188
|
+
if (Reflect.has(target, name)) {
|
|
189
|
+
return Reflect.set(target, name, value, receiver);
|
|
190
|
+
} else {
|
|
191
|
+
const activeRepo = oThis._getActiveRepository();
|
|
192
|
+
return Reflect.set(activeRepo, name, value);
|
|
193
|
+
}
|
|
194
|
+
},
|
|
184
195
|
});
|
|
185
196
|
|
|
186
197
|
return this._proxy; // Return the Proxy, not 'this'
|
|
@@ -191,12 +202,14 @@ class LocalFromRemoteRepository extends EventEmitter {
|
|
|
191
202
|
* - Relays all events from sub-repositories
|
|
192
203
|
*/
|
|
193
204
|
async initialize() {
|
|
194
|
-
this.relayEventsFrom(this.remote, this.remote.getRegisteredEvents(), 'remote_');
|
|
195
|
-
this.relayEventsFrom(this.local, this.local.getRegisteredEvents(), 'local_');
|
|
196
205
|
|
|
197
|
-
//
|
|
198
|
-
|
|
199
|
-
this.relayEventsFrom(
|
|
206
|
+
// // This is going to relay the events, but add a prefix to each
|
|
207
|
+
// this.relayEventsFrom(this.remote, this.remote.getRegisteredEvents(), 'remote_');
|
|
208
|
+
// this.relayEventsFrom(this.local, this.local.getRegisteredEvents(), 'local_');
|
|
209
|
+
|
|
210
|
+
// // Relay events from activeRepository directly, without prefix
|
|
211
|
+
// const activeRepository = this._getActiveRepository();
|
|
212
|
+
// this.relayEventsFrom(activeRepository, activeRepository.getRegisteredEvents());
|
|
200
213
|
|
|
201
214
|
// Set up and initialize commands
|
|
202
215
|
if (this.mode === MODE_COMMAND_QUEUE) {
|
|
@@ -211,6 +224,96 @@ class LocalFromRemoteRepository extends EventEmitter {
|
|
|
211
224
|
}
|
|
212
225
|
}
|
|
213
226
|
|
|
227
|
+
// ____ __ __
|
|
228
|
+
// / __ \_ _____ _____/ /___ ____ _____/ /____
|
|
229
|
+
// / / / / | / / _ \/ ___/ / __ \/ __ `/ __ / ___/
|
|
230
|
+
// / /_/ /| |/ / __/ / / / /_/ / /_/ / /_/ (__ )
|
|
231
|
+
// \____/ |___/\___/_/ /_/\____/\__,_/\__,_/____/
|
|
232
|
+
|
|
233
|
+
// The following methods are all overloads of EventEmitter methods.
|
|
234
|
+
// They determine whether the events they pertain to are registered on this
|
|
235
|
+
// LocalFromRemote class, or if they should be relayed to the active repository.
|
|
236
|
+
|
|
237
|
+
emit(name) { // NOTE: Purposefully do not use an arrow-function, so we have access to arguments
|
|
238
|
+
if (_.indexOf(this._registeredEvents, name) === -1) {
|
|
239
|
+
return this._getActiveRepository().emit(...arguments);
|
|
240
|
+
}
|
|
241
|
+
return super.emit(...arguments);
|
|
242
|
+
}
|
|
243
|
+
_emitAlt(name) {
|
|
244
|
+
if (_.indexOf(this._registeredEvents, name) === -1) {
|
|
245
|
+
return this._getActiveRepository()._emitAlt(...arguments);
|
|
246
|
+
}
|
|
247
|
+
return super._emitAlt(...arguments);
|
|
248
|
+
}
|
|
249
|
+
addListeners(names) {
|
|
250
|
+
const
|
|
251
|
+
registeredEvents = this._registeredEvents,
|
|
252
|
+
activeRepository = this._getActiveRepository();
|
|
253
|
+
_.each(names, (name) => {
|
|
254
|
+
if (_.indexOf(registeredEvents, name) === -1) {
|
|
255
|
+
activeRepository.on(...arguments);
|
|
256
|
+
} else {
|
|
257
|
+
super.on(...arguments);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
addListener(name) {
|
|
262
|
+
if (_.indexOf(this._registeredEvents, name) === -1) {
|
|
263
|
+
return this._getActiveRepository().addListener(...arguments);
|
|
264
|
+
}
|
|
265
|
+
return super.addListener(...arguments);
|
|
266
|
+
}
|
|
267
|
+
on(name) {
|
|
268
|
+
if (_.indexOf(this._registeredEvents, name) === -1) {
|
|
269
|
+
return this._getActiveRepository().on(...arguments);
|
|
270
|
+
}
|
|
271
|
+
return super.on(...arguments);
|
|
272
|
+
}
|
|
273
|
+
once(name) {
|
|
274
|
+
if (_.indexOf(this._registeredEvents, name) === -1) {
|
|
275
|
+
return this._getActiveRepository().once(...arguments);
|
|
276
|
+
}
|
|
277
|
+
return super.once(...arguments);
|
|
278
|
+
}
|
|
279
|
+
removeListener(name) {
|
|
280
|
+
if (_.indexOf(this._registeredEvents, name) === -1) {
|
|
281
|
+
return this._getActiveRepository().removeListener(...arguments);
|
|
282
|
+
}
|
|
283
|
+
return super.removeListener(...arguments);
|
|
284
|
+
}
|
|
285
|
+
off(name) {
|
|
286
|
+
if (_.indexOf(this._registeredEvents, name) === -1) {
|
|
287
|
+
return this._getActiveRepository().off(...arguments);
|
|
288
|
+
}
|
|
289
|
+
return super.off(...arguments);
|
|
290
|
+
}
|
|
291
|
+
removeListeners(names) {
|
|
292
|
+
const
|
|
293
|
+
registeredEvents = this._registeredEvents,
|
|
294
|
+
activeRepository = this._getActiveRepository();
|
|
295
|
+
_.each(names, (name) => {
|
|
296
|
+
if (_.indexOf(registeredEvents, name) === -1) {
|
|
297
|
+
activeRepository.off(...arguments);
|
|
298
|
+
} else {
|
|
299
|
+
super.off(...arguments);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
isRegisteredEvent(name) {
|
|
304
|
+
if (_.indexOf(this._registeredEvents, name) === -1) {
|
|
305
|
+
return this._getActiveRepository().isRegisteredEvent(...arguments);
|
|
306
|
+
}
|
|
307
|
+
return super.isRegisteredEvent(...arguments);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
// ________ __ ___ __ __ __
|
|
312
|
+
// / ____/ /___ ___________ / |/ /__ / /_/ /_ ____ ____/ /____
|
|
313
|
+
// / / / / __ `/ ___/ ___/ / /|_/ / _ \/ __/ __ \/ __ \/ __ / ___/
|
|
314
|
+
// / /___/ / /_/ (__ |__ ) / / / / __/ /_/ / / / /_/ / /_/ (__ )
|
|
315
|
+
// \____/_/\__,_/____/____/ /_/ /_/\___/\__/_/ /_/\____/\__,_/____/
|
|
316
|
+
|
|
214
317
|
/**
|
|
215
318
|
* Registers multiple commands for when syncing in MODE_COMMAND_QUEUE mode.
|
|
216
319
|
*/
|
|
@@ -279,9 +382,8 @@ class LocalFromRemoteRepository extends EventEmitter {
|
|
|
279
382
|
* so we can sync immediately after add for MODE_COMMAND_QUEUE mode.
|
|
280
383
|
*/
|
|
281
384
|
async add(data) {
|
|
282
|
-
// NORMAL PROCESS
|
|
283
|
-
// This adds to the local repository, so we can sync later,
|
|
284
|
-
// if needed.
|
|
385
|
+
// NORMAL PROCESS
|
|
386
|
+
// This adds to the local repository, so we can sync later, if needed.
|
|
285
387
|
const normalAdd = await this._getActiveRepository().add(data);
|
|
286
388
|
if (this.mode !== MODE_COMMAND_QUEUE || !this.isOnline) {
|
|
287
389
|
return normalAdd;
|
|
@@ -431,6 +431,15 @@ export default class Repository extends EventEmitter {
|
|
|
431
431
|
await waitUntil(() => !this.isLoading, { timeout });
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
+
/**
|
|
435
|
+
* Marks this repository as unloaded
|
|
436
|
+
*/
|
|
437
|
+
markUnloaded() {
|
|
438
|
+
this.markLoading(false);
|
|
439
|
+
this.isLoaded = false;
|
|
440
|
+
this.lastLoaded = null;
|
|
441
|
+
}
|
|
442
|
+
|
|
434
443
|
/**
|
|
435
444
|
* Marks this repository as loaded
|
|
436
445
|
*/
|
|
@@ -833,9 +842,7 @@ export default class Repository extends EventEmitter {
|
|
|
833
842
|
this.throwError('this._setFilters is no longer valid. Repository has been destroyed.');
|
|
834
843
|
return;
|
|
835
844
|
}
|
|
836
|
-
let isChanged = false;
|
|
837
845
|
if (!_.isEqual(this.filters, filters)) {
|
|
838
|
-
isChanged = true;
|
|
839
846
|
this.filters = filters;
|
|
840
847
|
this.resetPagination();
|
|
841
848
|
let ret;
|
|
@@ -845,7 +852,7 @@ export default class Repository extends EventEmitter {
|
|
|
845
852
|
this.emit('changeFilters');
|
|
846
853
|
return ret;
|
|
847
854
|
}
|
|
848
|
-
return
|
|
855
|
+
return false; // no filters changed
|
|
849
856
|
}
|
|
850
857
|
|
|
851
858
|
|