@itee/client 10.0.0

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 (61) hide show
  1. package/CHANGELOG.md +251 -0
  2. package/LICENSE.md +23 -0
  3. package/README.md +76 -0
  4. package/builds/itee-client.cjs.js +6517 -0
  5. package/builds/itee-client.cjs.js.map +1 -0
  6. package/builds/itee-client.cjs.min.js +125 -0
  7. package/builds/itee-client.esm.js +6468 -0
  8. package/builds/itee-client.esm.js.map +1 -0
  9. package/builds/itee-client.esm.min.js +124 -0
  10. package/builds/itee-client.iife.js +6524 -0
  11. package/builds/itee-client.iife.js.map +1 -0
  12. package/builds/itee-client.iife.min.js +125 -0
  13. package/package.json +87 -0
  14. package/sources/client.js +14 -0
  15. package/sources/cores/TAbstractFactory.js +42 -0
  16. package/sources/cores/TCloningFactory.js +39 -0
  17. package/sources/cores/TConstants.js +433 -0
  18. package/sources/cores/TInstancingFactory.js +41 -0
  19. package/sources/cores/TStore.js +303 -0
  20. package/sources/cores/_cores.js +13 -0
  21. package/sources/input_devices/TKeyboardController.js +158 -0
  22. package/sources/input_devices/TMouseController.js +31 -0
  23. package/sources/input_devices/_inputDevices.js +11 -0
  24. package/sources/loaders/TBinaryConverter.js +35 -0
  25. package/sources/loaders/TBinaryReader.js +1029 -0
  26. package/sources/loaders/TBinarySerializer.js +258 -0
  27. package/sources/loaders/TBinaryWriter.js +429 -0
  28. package/sources/loaders/_loaders.js +21 -0
  29. package/sources/loaders/converters/ArrayBinaryConverter.js +33 -0
  30. package/sources/loaders/converters/BooleanBinaryConverter.js +24 -0
  31. package/sources/loaders/converters/DateBinaryConverter.js +21 -0
  32. package/sources/loaders/converters/NullBinaryConverter.js +13 -0
  33. package/sources/loaders/converters/NumberBinaryConverter.js +15 -0
  34. package/sources/loaders/converters/ObjectBinaryConverter.js +101 -0
  35. package/sources/loaders/converters/RegExBinaryConverter.js +11 -0
  36. package/sources/loaders/converters/StringBinaryConverter.js +26 -0
  37. package/sources/loaders/converters/UndefinedBinaryConverter.js +13 -0
  38. package/sources/managers/TDataBaseManager.js +1649 -0
  39. package/sources/managers/_managers.js +10 -0
  40. package/sources/utils/TIdFactory.js +84 -0
  41. package/sources/utils/_utils.js +9 -0
  42. package/sources/webapis/WebAPI.js +773 -0
  43. package/sources/webapis/WebAPIOrigin.js +141 -0
  44. package/sources/webapis/_webapis.js +10 -0
  45. package/sources/webapis/messages/WebAPIMessage.js +75 -0
  46. package/sources/webapis/messages/WebAPIMessageData.js +51 -0
  47. package/sources/webapis/messages/WebAPIMessageError.js +79 -0
  48. package/sources/webapis/messages/WebAPIMessageEvent.js +58 -0
  49. package/sources/webapis/messages/WebAPIMessageProgress.js +91 -0
  50. package/sources/webapis/messages/WebAPIMessageReady.js +66 -0
  51. package/sources/webapis/messages/WebAPIMessageRequest.js +94 -0
  52. package/sources/webapis/messages/WebAPIMessageResponse.js +80 -0
  53. package/sources/webapis/messages/_messages.js +16 -0
  54. package/sources/workers/AbstractWorker.js +149 -0
  55. package/sources/workers/_workers.js +10 -0
  56. package/sources/workers/messages/WorkerMessage.js +33 -0
  57. package/sources/workers/messages/WorkerMessageData.js +30 -0
  58. package/sources/workers/messages/WorkerMessageError.js +32 -0
  59. package/sources/workers/messages/WorkerMessageMethodCall.js +60 -0
  60. package/sources/workers/messages/WorkerMessageProgress.js +67 -0
  61. package/sources/workers/messages/_messages.js +14 -0
@@ -0,0 +1,1649 @@
1
+ /**
2
+ * @author [Tristan Valcke]{@link https://github.com/Itee}
3
+ * @license [BSD-3-Clause]{@link https://opensource.org/licenses/BSD-3-Clause}
4
+ *
5
+ * @class TDataBaseManager
6
+ * @classdesc The base class of database managers. Give the basic interface about database call.
7
+ *
8
+ * @requires {@link HttpVerb}
9
+ * @requires {@link ResponseType}
10
+ * @requires {@link HttpStatusCode}
11
+ * @requires {@link TOrchestrator}
12
+ * @requires {@link TStore}
13
+ *
14
+ * @example Todo
15
+ *
16
+ */
17
+
18
+ /* eslint-env browser */
19
+
20
+ import {
21
+ DefaultLogger,
22
+ TLogger
23
+ } from '@itee/core'
24
+ import { toEnum } from '@itee/utils'
25
+ import {
26
+ isArray,
27
+ isArrayOfSingleElement,
28
+ isBlankString,
29
+ isDefined,
30
+ isEmptyObject,
31
+ isEmptyString,
32
+ isNotBlankString,
33
+ isNotDefined,
34
+ isNotEmptyArray,
35
+ isNotEmptyObject,
36
+ isNotEmptyString,
37
+ isNotNumber,
38
+ isNotObject,
39
+ isNotString,
40
+ isNull,
41
+ isNumberNegative,
42
+ isNumberPositive,
43
+ isObject,
44
+ isString,
45
+ isUndefined,
46
+ isZero
47
+ } from '@itee/validators'
48
+ import {
49
+ HttpStatusCode,
50
+ HttpVerb,
51
+ ResponseType
52
+ } from '../cores/TConstants.js'
53
+ import { TStore } from '../cores/TStore.js'
54
+
55
+
56
+ /**
57
+ * @deprecated
58
+ */
59
+ class IdGenerator {
60
+
61
+ constructor() {
62
+ this._id = 0
63
+ }
64
+
65
+ get id() {
66
+ this._id += 1
67
+ return this._id
68
+ }
69
+
70
+ }
71
+
72
+ const Generate = new IdGenerator()
73
+
74
+ /**
75
+ *
76
+ * @type {ReadonlyArray<unknown>}
77
+ */
78
+ const RequestType = /*#__PURE__*/toEnum( {
79
+ CreateOne: 0,
80
+ CreateMany: 1,
81
+ ReadOne: 2,
82
+ ReadMany: 3,
83
+ ReadWhere: 4,
84
+ ReadAll: 5,
85
+ UpdateOne: 6,
86
+ UpdateMany: 7,
87
+ UpdateWhere: 8,
88
+ UpdateAll: 9,
89
+ DeleteOne: 10,
90
+ DeleteMany: 11,
91
+ DeleteWhere: 12,
92
+ DeleteAll: 13
93
+ } )
94
+
95
+ /**
96
+ * @class
97
+ */
98
+ class TDataBaseManager {
99
+
100
+ /**
101
+ *
102
+ * @param parameters
103
+ */
104
+ constructor( parameters = {} ) {
105
+
106
+ const _parameters = {
107
+ ...{
108
+ basePath: '/',
109
+ responseType: ResponseType.Json,
110
+ bunchSize: 500,
111
+ requestAggregationTime: 200,
112
+ requestsConcurrency: 6,
113
+ logger: DefaultLogger
114
+ }, ...parameters
115
+ }
116
+
117
+ this.basePath = _parameters.basePath
118
+ this.responseType = _parameters.responseType
119
+ this.bunchSize = _parameters.bunchSize
120
+ this.requestAggregationTime = _parameters.requestAggregationTime
121
+ this.requestsConcurrency = _parameters.requestsConcurrency
122
+ this.logger = _parameters.logger
123
+
124
+ this._cache = new TStore()
125
+ this._waitingQueue = []
126
+ this._aggregateQueue = []
127
+ this._requestQueue = []
128
+ this._processQueue = []
129
+ this._aggregationTimeoutId = null
130
+
131
+ this._idToRequest = []
132
+
133
+ }
134
+ /**
135
+ *
136
+ * @returns {number}
137
+ */
138
+ static get requestId() {
139
+ TDataBaseManager._requestId++
140
+ return TDataBaseManager._requestId
141
+ }
142
+ /**
143
+ *
144
+ * @returns {*}
145
+ */
146
+ get basePath() {
147
+ return this._basePath
148
+ }
149
+
150
+ set basePath( value ) {
151
+
152
+ if ( isNull( value ) ) { throw new TypeError( 'Base path cannot be null ! Expect a non empty string.' ) }
153
+ if ( isUndefined( value ) ) { throw new TypeError( 'Base path cannot be undefined ! Expect a non empty string.' ) }
154
+ if ( isNotString( value ) ) { throw new TypeError( `Base path cannot be an instance of ${ value.constructor.name } ! Expect a non empty string.` ) }
155
+ if ( isEmptyString( value ) ) { throw new TypeError( 'Base path cannot be empty ! Expect a non empty string.' ) }
156
+ if ( isBlankString( value ) ) { throw new TypeError( 'Base path cannot contain only whitespace ! Expect a non empty string.' ) }
157
+
158
+ this._basePath = value
159
+
160
+ }
161
+
162
+ /**
163
+ *
164
+ * @returns {*}
165
+ */
166
+ get responseType() {
167
+ return this._responseType
168
+ }
169
+
170
+ set responseType( value ) {
171
+
172
+ if ( isNull( value ) ) { throw new Error( 'TDataBaseManager: responseType cannot be null !' ) }
173
+ if ( isNull( value ) ) { throw new TypeError( 'Response type cannot be null ! Expect a non empty string.' ) }
174
+ if ( isUndefined( value ) ) { throw new TypeError( 'Response type cannot be undefined ! Expect a non empty string.' ) }
175
+ // if ( !( value instanceof ResponseType ) ) { throw new TypeError( `Response type cannot be an instance of ${value.constructor.name} ! Expect a value from ResponseType enum.` ) }
176
+
177
+ this._responseType = value
178
+
179
+ }
180
+
181
+ /**
182
+ *
183
+ * @returns {*}
184
+ */
185
+ get bunchSize() {
186
+ return this._bunchSize
187
+ }
188
+
189
+ set bunchSize( value ) {
190
+
191
+ if ( isNull( value ) ) { throw new TypeError( 'Bunch size cannot be null ! Expect a positive number.' ) }
192
+ if ( isUndefined( value ) ) { throw new TypeError( 'Bunch size cannot be undefined ! Expect a positive number.' ) }
193
+ if ( isNotNumber( value ) ) { throw new TypeError( `Bunch size cannot be an instance of ${ value.constructor.name } ! Expect a positive number.` ) }
194
+ if ( !isNumberPositive( value ) ) { throw new TypeError( `Bunch size cannot be lower or equal to zero ! Expect a positive number.` ) }
195
+
196
+ this._bunchSize = value
197
+
198
+ }
199
+
200
+ /**
201
+ *
202
+ * @returns {*}
203
+ */
204
+ get requestAggregationTime() {
205
+ return this._requestAggregationTime
206
+ }
207
+
208
+ set requestAggregationTime( value ) {
209
+
210
+ if ( isNull( value ) ) {
211
+ throw new TypeError( 'Requests aggregation time cannot be null ! Expect a positive number.' )
212
+ }
213
+
214
+ if ( isUndefined( value ) ) {
215
+ throw new TypeError( 'Requests aggregation time cannot be undefined ! Expect a positive number.' )
216
+ }
217
+
218
+ if ( isNotNumber( value ) ) {
219
+ throw new TypeError( `Requests aggregation time cannot be an instance of ${ value.constructor.name } ! Expect a positive number.` )
220
+ }
221
+
222
+ if ( isNumberNegative( value ) ) {
223
+ throw new TypeError( 'Requests aggregation time cannot be lower or equal to zero ! Expect a positive number.' )
224
+ }
225
+
226
+ this._requestAggregationTime = value
227
+
228
+ }
229
+
230
+ /**
231
+ *
232
+ * @returns {*}
233
+ */
234
+ get requestsConcurrency() {
235
+ return this._requestsConcurrency
236
+ }
237
+
238
+ set requestsConcurrency( value ) {
239
+
240
+ if ( isNull( value ) ) {
241
+ throw new TypeError( 'Minimum of simultaneous request cannot be null ! Expect a positive number.' )
242
+ }
243
+
244
+ if ( isUndefined( value ) ) {
245
+ throw new TypeError( 'Minimum of simultaneous request cannot be undefined ! Expect a positive number.' )
246
+ }
247
+
248
+ if ( isNotNumber( value ) ) {
249
+ throw new TypeError( `Minimum of simultaneous request cannot be an instance of ${ value.constructor.name } ! Expect a positive number.` )
250
+ }
251
+
252
+ if ( isZero( value ) || isNumberNegative( value ) ) {
253
+ throw new TypeError( 'Minimum of simultaneous request cannot be lower or equal to zero ! Expect a positive number.' )
254
+ }
255
+
256
+ this._requestsConcurrency = value
257
+
258
+ }
259
+
260
+ /**
261
+ *
262
+ * @returns {TLogger}
263
+ */
264
+ get logger() {
265
+ return this._logger
266
+ }
267
+
268
+ set logger( value ) {
269
+
270
+ if ( isNull( value ) ) { throw new TypeError( 'Progress manager cannot be null ! Expect an instance of TProgressManager.' ) }
271
+ if ( isUndefined( value ) ) { throw new TypeError( 'Progress manager cannot be undefined ! Expect an instance of TProgressManager.' ) }
272
+ if ( !( value instanceof TLogger ) ) { throw new TypeError( `Progress manager cannot be an instance of ${ value.constructor.name } ! Expect an instance of TProgressManager.` ) }
273
+
274
+ this._logger = value
275
+
276
+ }
277
+
278
+ /**
279
+ *
280
+ * @param value
281
+ * @returns {TDataBaseManager}
282
+ */
283
+ setBasePath( value ) {
284
+
285
+ this.basePath = value
286
+ return this
287
+
288
+ }
289
+
290
+ /**
291
+ *
292
+ * @param value
293
+ * @returns {TDataBaseManager}
294
+ */
295
+ setResponseType( value ) {
296
+
297
+ this.responseType = value
298
+ return this
299
+
300
+ }
301
+
302
+ /**
303
+ *
304
+ * @param value
305
+ * @returns {TDataBaseManager}
306
+ */
307
+ setBunchSize( value ) {
308
+
309
+ this.bunchSize = value
310
+ return this
311
+
312
+ }
313
+
314
+ /**
315
+ *
316
+ * @param value
317
+ * @returns {TDataBaseManager}
318
+ */
319
+ setRequestAggregationTime( value ) {
320
+
321
+ this.requestAggregationTime = value
322
+ return this
323
+
324
+ }
325
+
326
+ /**
327
+ *
328
+ * @param value
329
+ * @returns {TDataBaseManager}
330
+ */
331
+ setRequestsConcurrency( value ) {
332
+
333
+ this.requestsConcurrency = value
334
+ return this
335
+
336
+ }
337
+
338
+ /**
339
+ *
340
+ * @param value
341
+ * @returns {TDataBaseManager}
342
+ */
343
+ setLogger( value ) {
344
+
345
+ this.logger = value
346
+ return this
347
+
348
+ }
349
+
350
+ /**
351
+ *
352
+ */
353
+ aggregateQueue() {
354
+
355
+ clearTimeout( this._aggregationTimeoutId )
356
+
357
+ this._aggregationTimeoutId = setTimeout( () => {
358
+
359
+ const datasToRequest = this._idToRequest
360
+ let idBunch = []
361
+ for ( let idIndex = datasToRequest.length - 1 ; idIndex >= 0 ; idIndex-- ) {
362
+
363
+ idBunch.push( datasToRequest.pop() )
364
+
365
+ if ( idBunch.length === this._bunchSize || idIndex === 0 ) {
366
+
367
+ this._requestQueue.push( {
368
+ _id: `readMany_${ Generate.id }`,
369
+ _timeStart: new Date(),
370
+ _type: RequestType.ReadMany,
371
+ method: HttpVerb.Read.value,
372
+ url: this._basePath,
373
+ data: {
374
+ ids: idBunch
375
+ },
376
+ responseType: this._responseType
377
+ } )
378
+
379
+ idBunch = []
380
+ }
381
+
382
+ }
383
+
384
+ this.processQueue.call( this )
385
+
386
+ }, this._requestAggregationTime )
387
+
388
+ }
389
+
390
+ /**
391
+ *
392
+ */
393
+ processQueue() {
394
+
395
+ while ( this._requestQueue.length > 0 && this._processQueue.length < this._requestsConcurrency ) {
396
+
397
+ const requestSkull = this._requestQueue.pop()
398
+ this._processQueue.push( requestSkull )
399
+
400
+ const request = new XMLHttpRequest()
401
+ request.onloadstart = _onLoadStart.bind( this )
402
+ request.onload = this._onLoad.bind(
403
+ this,
404
+ requestSkull,
405
+ this._onEnd.bind( this, requestSkull, requestSkull.onLoad ),
406
+ this._onProgress.bind( this, requestSkull.onProgress ),
407
+ this._onError.bind( this, requestSkull, requestSkull.onError )
408
+ )
409
+ request.onloadend = _onLoadEnd.bind( this )
410
+ request.onprogress = this._onProgress.bind( this, requestSkull.onProgress )
411
+ request.onreadystatechange = _onReadyStateChange.bind( this )
412
+ request.onabort = _onAbort.bind( this )
413
+ request.onerror = this._onError.bind( this, requestSkull, requestSkull.onError )
414
+ request.ontimeout = _onTimeout.bind( this )
415
+ request.open( requestSkull.method, requestSkull.url, true )
416
+ request.setRequestHeader( 'Content-Type', 'application/json' )
417
+ request.setRequestHeader( 'Accept', 'application/json' )
418
+ request.responseType = requestSkull.responseType.value
419
+
420
+ const dataToSend = ( requestSkull.data && requestSkull.responseType === ResponseType.Json ) ? JSON.stringify( requestSkull.data ) : requestSkull.data
421
+ request.send( dataToSend )
422
+
423
+ }
424
+
425
+ function _onLoadStart( loadStartEvent ) { this.logger.progress( loadStartEvent ) }
426
+
427
+ function _onLoadEnd( loadEndEvent ) { this.logger.progress( loadEndEvent ) }
428
+
429
+ function _onReadyStateChange( readyStateEvent ) { this.logger.debug( readyStateEvent ) }
430
+
431
+ function _onAbort( abortEvent ) { this.logger.error( abortEvent ) }
432
+
433
+ function _onTimeout( timeoutEvent ) { this.logger.error( timeoutEvent ) }
434
+
435
+ }
436
+
437
+ // Publics
438
+ /**
439
+ * The create method allow to create a new ressource on the server. Providing a single object that match a database schema, or an array of them.
440
+ *
441
+ * @param {object|array.<object>} data - The data to send for create new objects.
442
+ * @param {function} onLoadCallback - The onLoad callback, which is call when server respond with success to the request.
443
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
444
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
445
+ */
446
+ create( data, onLoadCallback, onProgressCallback, onErrorCallback ) {
447
+
448
+ if ( isArray( data ) && isNotEmptyArray( data ) ) {
449
+
450
+ if ( isArrayOfSingleElement( data ) ) {
451
+
452
+ this._createOne( data[ 0 ], onLoadCallback, onProgressCallback, onErrorCallback )
453
+
454
+ } else {
455
+
456
+ this._createMany( data, onLoadCallback, onProgressCallback, onErrorCallback )
457
+
458
+ }
459
+
460
+ } else if ( isObject( data ) && isNotEmptyObject( data ) ) {
461
+
462
+ this._createOne( data, onLoadCallback, onProgressCallback, onErrorCallback )
463
+
464
+ } else {
465
+
466
+ onErrorCallback( 'TDataBaseManager.create: Invalid data type, expect object or array of objects.' )
467
+
468
+ }
469
+
470
+ }
471
+
472
+ /**
473
+ * The read method allow to retrieve data from the server, using a single id or an array of them.
474
+ *
475
+ * @param {string|array.<string>} condition - The ids of objects to retrieve.
476
+ * @param {function} onLoadCallback - The onLoad callback, which is call when server respond with success to the request.
477
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
478
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
479
+ */
480
+ read( condition, projection, onLoadCallback, onProgressCallback, onErrorCallback ) {
481
+
482
+ if ( isString( condition ) && isNotEmptyString( condition ) && isNotBlankString( condition ) ) {
483
+
484
+ this._readOne( condition, projection, onLoadCallback, onProgressCallback, onErrorCallback )
485
+
486
+ } else if ( isArray( condition ) && isNotEmptyArray( condition ) ) {
487
+
488
+ if ( isArrayOfSingleElement( condition ) ) {
489
+
490
+ this._readOne( condition[ 0 ], projection, onLoadCallback, onProgressCallback, onErrorCallback )
491
+
492
+ } else {
493
+
494
+ this._readMany( condition, projection, onLoadCallback, onProgressCallback, onErrorCallback )
495
+
496
+ }
497
+
498
+ } else if ( isObject( condition ) ) {
499
+
500
+ if ( isEmptyObject( condition ) ) {
501
+
502
+ this._readAll( projection, onLoadCallback, onProgressCallback, onErrorCallback )
503
+
504
+ } else {
505
+
506
+ this._readWhere( condition, projection, onLoadCallback, onProgressCallback, onErrorCallback )
507
+
508
+ }
509
+
510
+ } else {
511
+
512
+ onErrorCallback( 'TDataBaseManager.read: Invalid data type, expect string, object or array of objects.' )
513
+
514
+ }
515
+
516
+ }
517
+
518
+ /**
519
+ * The update method allow to update data on the server, using a single id or an array of them, and a corresponding object about the data to update.
520
+ *
521
+ * @param {string|array.<string>} condition - The ids of objects to update.
522
+ * @param {object} update - The update data ( need to match the related database schema ! ). In case of multiple ids they will be updated with the same given data.
523
+ * @param {function} onLoadCallback - The onLoad callback, which is call when server respond with success to the request.
524
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
525
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
526
+ */
527
+ update( condition, update, onLoadCallback, onProgressCallback, onErrorCallback ) {
528
+
529
+ if ( isNotDefined( update ) ) {
530
+ onErrorCallback( 'TDataBaseManager.update: Update data cannot be null or undefined !' )
531
+ return
532
+ }
533
+
534
+ if ( isNotObject( update ) ) {
535
+ onErrorCallback( 'TDataBaseManager.update: Invalid update data type. Expect an object.' )
536
+ return
537
+ }
538
+
539
+ if ( isString( condition ) && isNotEmptyString( condition ) && isNotBlankString( condition ) ) {
540
+
541
+ this._updateOne( condition, update, onLoadCallback, onProgressCallback, onErrorCallback )
542
+
543
+ } else if ( isArray( condition ) && isNotEmptyArray( condition ) ) {
544
+
545
+ if ( isArrayOfSingleElement( condition ) ) {
546
+
547
+ this._updateOne( condition[ 0 ], update, onLoadCallback, onProgressCallback, onErrorCallback )
548
+
549
+ } else {
550
+
551
+ this._updateMany( condition, update, onLoadCallback, onProgressCallback, onErrorCallback )
552
+
553
+ }
554
+
555
+ } else if ( isObject( condition ) ) {
556
+
557
+ if ( isEmptyObject( condition ) ) {
558
+
559
+ this._updateAll( update, onLoadCallback, onProgressCallback, onErrorCallback )
560
+
561
+ } else {
562
+
563
+ this._updateWhere( condition, update, onLoadCallback, onProgressCallback, onErrorCallback )
564
+
565
+ }
566
+
567
+ } else {
568
+
569
+ onErrorCallback( 'TDataBaseManager.update: Invalid data type, expect string, object or array of objects.' )
570
+
571
+ }
572
+
573
+ }
574
+
575
+ /**
576
+ * The delete method allow to remove data from the server, using a single id or an array of them.
577
+ *
578
+ * @param {string|array.<string>|object|null} condition - The ids of objects to delete.
579
+ * @param {function} onLoadCallback - The onLoad callback, which is call when server respond with success to the request.
580
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
581
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
582
+ */
583
+ delete( condition, onLoadCallback, onProgressCallback, onErrorCallback ) {
584
+
585
+ if ( isString( condition ) && isNotEmptyString( condition ) && isNotBlankString( condition ) ) {
586
+
587
+ this._deleteOne( condition, onLoadCallback, onProgressCallback, onErrorCallback )
588
+
589
+ } else if ( isArray( condition ) && isNotEmptyArray( condition ) ) {
590
+
591
+ if ( isArrayOfSingleElement( condition ) ) {
592
+
593
+ this._deleteOne( condition[ 0 ], onLoadCallback, onProgressCallback, onErrorCallback )
594
+
595
+ } else {
596
+
597
+ this._deleteMany( condition, onLoadCallback, onProgressCallback, onErrorCallback )
598
+
599
+ }
600
+
601
+ } else if ( isObject( condition ) ) {
602
+
603
+ if ( isEmptyObject( condition ) ) {
604
+
605
+ this._deleteAll( onLoadCallback, onProgressCallback, onErrorCallback )
606
+
607
+ } else {
608
+
609
+ this._deleteWhere( condition, onLoadCallback, onProgressCallback, onErrorCallback )
610
+
611
+ }
612
+
613
+ } else {
614
+
615
+ onErrorCallback( 'TDataBaseManager.delete: Invalid data type, expect null, string, object or array of objects.' )
616
+
617
+ }
618
+
619
+ }
620
+
621
+ // Privates
622
+
623
+ //// Events
624
+
625
+ /**
626
+ * The private _onLoad method allow to process the server response in an abstract way to check against error and wrong status code.
627
+ * It will bind user callback on each type of returns, and dispatch in sub methods in function of the response type.
628
+ *
629
+ * @param {function} onLoadCallback - The onLoad callback, which is call when server respond with success to the request.
630
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
631
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
632
+ * @param {object} loadEvent - The server response object to parse.
633
+ * @private
634
+ */
635
+ _onLoad( request, onLoadCallback, onProgressCallback, onErrorCallback, loadEvent ) {
636
+
637
+ const target = loadEvent.target
638
+ const status = target.status
639
+ const response = target.response
640
+ const responseType = target.responseType
641
+
642
+ switch ( status ) {
643
+
644
+ // 100
645
+ // case HttpStatusCode.Continue.value:
646
+ // case HttpStatusCode.SwitchingProtocols.value:
647
+ // case HttpStatusCode.Processing.value:
648
+
649
+ // 200
650
+ case HttpStatusCode.Ok.value:
651
+ this._dispatchResponse( response, responseType, onLoadCallback, onProgressCallback, onErrorCallback )
652
+ break
653
+ // case HttpStatusCode.Created.value:
654
+ // case HttpStatusCode.Accepted.value:
655
+
656
+ case HttpStatusCode.NonAuthoritativeInformation.value:
657
+ case HttpStatusCode.NoContent.value:
658
+ case HttpStatusCode.ResetContent.value:
659
+ case HttpStatusCode.PartialContent.value:
660
+ case HttpStatusCode.MultiStatus.value:
661
+ case HttpStatusCode.AlreadyReported.value:
662
+ case HttpStatusCode.ContentDifferent.value:
663
+ case HttpStatusCode.IMUsed.value:
664
+ case HttpStatusCode.MultipleChoices.value:
665
+ case HttpStatusCode.MovedPermanently.value:
666
+ case HttpStatusCode.Found.value:
667
+ case HttpStatusCode.SeeOther.value:
668
+ case HttpStatusCode.NotModified.value:
669
+ case HttpStatusCode.UseProxy.value:
670
+ case HttpStatusCode.Unused.value:
671
+ case HttpStatusCode.TemporaryRedirect.value:
672
+ case HttpStatusCode.PermanentRedirect.value:
673
+ case HttpStatusCode.TooManyRedirects.value:
674
+ case HttpStatusCode.BadRequest.value:
675
+ case HttpStatusCode.Unauthorized.value:
676
+ case HttpStatusCode.PaymentRequired.value:
677
+ case HttpStatusCode.Forbidden.value:
678
+ case HttpStatusCode.NotFound.value:
679
+ case HttpStatusCode.MethodNotAllowed.value:
680
+ case HttpStatusCode.NotAcceptable.value:
681
+ case HttpStatusCode.ProxyAuthenticationRequired.value:
682
+ case HttpStatusCode.RequestTimeOut.value:
683
+ case HttpStatusCode.Conflict.value:
684
+ case HttpStatusCode.Gone.value:
685
+ case HttpStatusCode.LengthRequired.value:
686
+ case HttpStatusCode.PreconditionFailed.value:
687
+ case HttpStatusCode.RequestEntityTooLarge.value:
688
+ case HttpStatusCode.RequestRangeUnsatisfiable.value:
689
+ case HttpStatusCode.ExpectationFailed.value:
690
+ case HttpStatusCode.ImATeapot.value:
691
+ case HttpStatusCode.BadMapping.value:
692
+ case HttpStatusCode.UnprocessableEntity.value:
693
+ case HttpStatusCode.Locked.value:
694
+ case HttpStatusCode.MethodFailure.value:
695
+ case HttpStatusCode.UnorderedCollection.value:
696
+ case HttpStatusCode.UpgradeRequired.value:
697
+ case HttpStatusCode.PreconditionRequired.value:
698
+ case HttpStatusCode.TooManyRequests.value:
699
+ case HttpStatusCode.RequestHeaderFieldsTooLarge.value:
700
+ case HttpStatusCode.NoResponse.value:
701
+ case HttpStatusCode.RetryWith.value:
702
+ case HttpStatusCode.BlockedByWindowsParentalControls.value:
703
+ case HttpStatusCode.UnavailableForLegalReasons.value:
704
+ case HttpStatusCode.UnrecoverableError.value:
705
+ case HttpStatusCode.SSLCertificateError.value:
706
+ case HttpStatusCode.SSLCertificateRequired.value:
707
+ case HttpStatusCode.HTTPRequestSentToHTTPSPort.value:
708
+ case HttpStatusCode.ClientClosedRequest.value:
709
+ case HttpStatusCode.InternalServerError.value:
710
+ case HttpStatusCode.NotImplemented.value:
711
+ case HttpStatusCode.BadGateway.value:
712
+ case HttpStatusCode.ServiceUnavailable.value:
713
+ case HttpStatusCode.GatewayTimeOut.value:
714
+ case HttpStatusCode.HTTPVersionNotSupported.value:
715
+ case HttpStatusCode.VariantAlsoNegotiates.value:
716
+ case HttpStatusCode.InsufficientStorage.value:
717
+ case HttpStatusCode.LoopDetected.value:
718
+ case HttpStatusCode.BandwidthLimitExceeded.value:
719
+ case HttpStatusCode.NotExtended.value:
720
+ case HttpStatusCode.NetworkAuthenticationRequired.value:
721
+ case HttpStatusCode.UnknownError.value:
722
+ case HttpStatusCode.WebServerIsDown.value:
723
+ case HttpStatusCode.ConnectionTimedOut.value:
724
+ case HttpStatusCode.OriginIsUnreachable.value:
725
+ case HttpStatusCode.ATimeoutOccured.value:
726
+ case HttpStatusCode.SSLHandshakeFailed.value:
727
+ case HttpStatusCode.InvalidSSLCertificate.value:
728
+ case HttpStatusCode.RailgunError.value:
729
+ onErrorCallback( response )
730
+ break
731
+
732
+ default:
733
+ throw new RangeError( `Unmanaged HttpStatusCode: ${ status }` )
734
+
735
+ }
736
+
737
+ }
738
+
739
+ /**
740
+ * The private _onProgress method will handle all progress event from server and submit them to the logger if exist else to the user onProgressCallback
741
+ *
742
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
743
+ * @param {object} progressEvent - The server progress event.
744
+ * @private
745
+ */
746
+ _onProgress( onProgressCallback, progressEvent ) {
747
+
748
+ if ( isDefined( this.logger ) ) {
749
+
750
+ this.logger.progress( progressEvent, onProgressCallback )
751
+
752
+ } else if ( isDefined( onProgressCallback ) ) {
753
+
754
+ onProgressCallback( progressEvent )
755
+
756
+ }
757
+
758
+ }
759
+
760
+ /**
761
+ * The private _onError method will handle all error event from server and submit them to the logger if exist else to the user onErrorCallback
762
+ *
763
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
764
+ * @param {object} errorEvent - A server error event
765
+ * @private
766
+ */
767
+ _onError( request, onErrorCallback, errorEvent ) {
768
+
769
+ this._closeRequest( request )
770
+
771
+ if ( isDefined( this.logger ) ) {
772
+
773
+ this.logger.error( errorEvent, onErrorCallback )
774
+
775
+ } else if ( isDefined( onErrorCallback ) ) {
776
+
777
+ onErrorCallback( errorEvent )
778
+
779
+ }
780
+
781
+ }
782
+
783
+ /**
784
+ * The private _onEnd method is call after all other callback and perform request type checking in view to upadte cache, waitingqueue and callback if needed,
785
+ * to finally close the request
786
+ *
787
+ * @param request
788
+ * @param onLoadCallback
789
+ * @param response
790
+ * @private
791
+ */
792
+ _onEnd( request, onLoadCallback, response ) {
793
+
794
+ const type = request._type
795
+
796
+ switch ( type ) {
797
+
798
+ case RequestType.ReadOne:
799
+ case RequestType.ReadMany:
800
+ this._updateCache( response )
801
+ this._updateWaitingQueue()
802
+ break
803
+
804
+ case RequestType.ReadWhere:
805
+ case RequestType.ReadAll:
806
+ this._updateCache( response )
807
+ this._updateWaitingQueue()
808
+ onLoadCallback( response )
809
+ break
810
+
811
+ case RequestType.CreateOne:
812
+ case RequestType.CreateMany:
813
+ case RequestType.UpdateOne:
814
+ case RequestType.UpdateMany:
815
+ case RequestType.UpdateWhere:
816
+ case RequestType.UpdateAll:
817
+ case RequestType.DeleteOne:
818
+ case RequestType.DeleteMany:
819
+ case RequestType.DeleteWhere:
820
+ case RequestType.DeleteAll:
821
+ onLoadCallback( response )
822
+ break
823
+
824
+ default:
825
+ throw new RangeError( `Invalid request type: ${ type }` )
826
+
827
+ }
828
+
829
+ this._closeRequest( request )
830
+
831
+ }
832
+
833
+ //// Data parsing
834
+ // Expect that methods were reimplemented when TDataBaseManager is inherited
835
+
836
+ /**
837
+ * Dispatch response to the correct handler in function of response type
838
+ *
839
+ * @param response
840
+ * @param responseType
841
+ * @param onLoadCallback
842
+ * @param onProgressCallback
843
+ * @param onErrorCallback
844
+ * @private
845
+ */
846
+ _dispatchResponse( response, responseType, onLoadCallback, onProgressCallback, onErrorCallback ) {
847
+
848
+ switch ( responseType ) {
849
+
850
+ case ResponseType.ArrayBuffer.value:
851
+ this._onArrayBuffer(
852
+ response,
853
+ onLoadCallback,
854
+ onProgressCallback,
855
+ onErrorCallback
856
+ )
857
+ break
858
+
859
+ case ResponseType.Blob.value:
860
+ this._onBlob(
861
+ response,
862
+ onLoadCallback,
863
+ onProgressCallback,
864
+ onErrorCallback
865
+ )
866
+ break
867
+
868
+ case ResponseType.Json.value:
869
+ this._onJson(
870
+ response,
871
+ onLoadCallback,
872
+ onProgressCallback,
873
+ onErrorCallback
874
+ )
875
+ break
876
+
877
+ case ResponseType.DOMString.value:
878
+ case ResponseType.Default.value:
879
+ this._onText(
880
+ response,
881
+ onLoadCallback,
882
+ onProgressCallback,
883
+ onErrorCallback
884
+ )
885
+ break
886
+
887
+ default:
888
+ throw new Error( `Unknown response type: ${ responseType }` )
889
+
890
+ }
891
+
892
+ }
893
+
894
+ /**
895
+ * Will remove the request from the process queue
896
+ *
897
+ * @param request
898
+ * @private
899
+ */
900
+ _closeRequest( request ) {
901
+
902
+ this._processQueue.splice( this._processQueue.indexOf( request ), 1 )
903
+
904
+ if ( Window.Itee && Window.Itee.Debug ) {
905
+
906
+ const diff = new Date().valueOf() - request._timeStart.valueOf()
907
+ const message = `${ this.constructor.name } close request [${ request._id }] on ${ diff }ms.` +
908
+ `Waiting queue: ${ this._waitingQueue.length }` +
909
+ `Request queue: ${ this._requestQueue.length }` +
910
+ `Process queue: ${ this._processQueue.length }` +
911
+ `==========================`
912
+ this.logger.debug( message )
913
+
914
+ }
915
+
916
+ this.processQueue()
917
+
918
+ }
919
+
920
+ /**
921
+ *
922
+ * @param ids
923
+ * @returns {Object}
924
+ * @private
925
+ */
926
+ _retrieveCachedValues( ids ) {
927
+
928
+ let results = {}
929
+ let underRequest = []
930
+ let toRequest = []
931
+
932
+ for ( let idIndex = 0, numberOfIds = ids.length ; idIndex < numberOfIds ; idIndex++ ) {
933
+
934
+ const id = ids[ idIndex ]
935
+ const cachedValue = this._cache.get( id )
936
+
937
+ if ( isDefined( cachedValue ) ) {
938
+ results[ id ] = cachedValue
939
+ } else if ( isNull( cachedValue ) ) { // In request
940
+ underRequest.push( id )
941
+ } else {
942
+ toRequest.push( id )
943
+ }
944
+
945
+ }
946
+
947
+ return {
948
+ results,
949
+ underRequest,
950
+ toRequest
951
+ }
952
+
953
+ }
954
+
955
+ /**
956
+ *
957
+ * @param datas
958
+ * @private
959
+ */
960
+ _updateCache( datas ) {
961
+
962
+ if ( isNull( datas ) ) { throw new TypeError( 'Data cannot be null ! Expect an array of object.' ) }
963
+ if ( isUndefined( datas ) ) { throw new TypeError( 'Data cannot be undefined ! Expect an array of object.' ) }
964
+
965
+ let _datas = {}
966
+ if ( isArray( datas ) ) {
967
+
968
+ for ( let key in datas ) {
969
+ _datas[ datas[ key ]._id ] = datas[ key ]
970
+ }
971
+
972
+ } else {
973
+
974
+ _datas = datas
975
+
976
+ }
977
+
978
+ for ( let [ id, data ] of Object.entries( _datas ) ) {
979
+
980
+ const cachedResult = this._cache.get( id )
981
+
982
+ if ( isNull( cachedResult ) ) {
983
+ this._cache.add( id, data, true )
984
+ } else if ( isUndefined( cachedResult ) ) {
985
+ this.logger.warn( 'Cache was not pre-allocated with null value.' )
986
+ this._cache.add( id, data )
987
+ } else {
988
+ this.logger.error( 'Cached value already exist !' )
989
+ }
990
+
991
+ }
992
+
993
+ }
994
+
995
+ /**
996
+ *
997
+ * @private
998
+ */
999
+ _updateWaitingQueue() {
1000
+
1001
+ const haveNoRequestToProcess = ( this._requestQueue.length === 0 && this._processQueue.length === 0 )
1002
+
1003
+ for ( let requestIndex = this._waitingQueue.length - 1 ; requestIndex >= 0 ; requestIndex-- ) {
1004
+
1005
+ const demand = this._waitingQueue[ requestIndex ]
1006
+
1007
+ // Update requested datas
1008
+ for ( let dataIndex = demand.underRequest.length - 1 ; dataIndex >= 0 ; dataIndex-- ) {
1009
+
1010
+ const id = demand.underRequest[ dataIndex ]
1011
+ const cachedResult = this._cache.get( id )
1012
+
1013
+ if ( isNotDefined( cachedResult ) ) { continue }
1014
+
1015
+ // Assign the cached value
1016
+ demand.results[ id ] = cachedResult
1017
+
1018
+ // Remove the requested object that is now added
1019
+ demand.underRequest.splice( demand.underRequest.indexOf( id ), 1 )
1020
+
1021
+ }
1022
+
1023
+ // Check if request is now fullfilled
1024
+ const demandIsComplet = ( demand.underRequest.length === 0 )
1025
+ if ( demandIsComplet ) {
1026
+
1027
+ this._waitingQueue.splice( requestIndex, 1 )
1028
+ demand.onLoadCallback( demand.results )
1029
+
1030
+ } else if ( !demandIsComplet && haveNoRequestToProcess /* && haveTryAgainManyTimesButFail */ ) {
1031
+
1032
+ this.logger.warn( 'Incomplet demand but empty request/process queue' )
1033
+ this._waitingQueue.splice( requestIndex, 1 )
1034
+ demand.onLoadCallback( demand.results )
1035
+
1036
+ } else {
1037
+
1038
+ // Wait next response
1039
+
1040
+ }
1041
+
1042
+ }
1043
+
1044
+ }
1045
+
1046
+ /**
1047
+ * The abstract private _onArrayBuffer method must be overridden in case the parser expect an array buffer as input data.
1048
+ *
1049
+ * @private
1050
+ * @abstract
1051
+ * @param {ArrayBuffer} data - The retrieved data to parse.
1052
+ * @param {function} onSuccess - The onLoad callback, which is call when parser parse with success the data.
1053
+ * @param {function} onProgress - The onProgress callback, which is call during the parsing.
1054
+ * @param {function} onError - The onError callback, which is call when parser throw an error during parsing.
1055
+ */
1056
+ // eslint-disable-next-line no-unused-vars
1057
+ _onArrayBuffer( data, onSuccess, onProgress, onError ) {}
1058
+
1059
+ /**
1060
+ * The abstract private _onBlob method must be overridden in case the parser expect a blob as input data.
1061
+ *
1062
+ * @private
1063
+ * @abstract
1064
+ * @param {Blob} data - The retrieved data to parse.
1065
+ * @param {function} onSuccess - The onLoad callback, which is call when parser parse with success the data.
1066
+ * @param {function} onProgress - The onProgress callback, which is call during the parsing.
1067
+ * @param {function} onError - The onError callback, which is call when parser throw an error during parsing.
1068
+ */
1069
+ // eslint-disable-next-line no-unused-vars
1070
+ _onBlob( data, onSuccess, onProgress, onError ) {}
1071
+
1072
+ /**
1073
+ * The abstract private _onJson method must be overridden in case the parser expect json as input data.
1074
+ *
1075
+ * @private
1076
+ * @abstract
1077
+ * @param {json} data - The retrieved data to parse.
1078
+ * @param {function} onSuccess - The onLoad callback, which is call when parser parse with success the data.
1079
+ * @param {function} onProgress - The onProgress callback, which is call during the parsing.
1080
+ * @param {function} onError - The onError callback, which is call when parser throw an error during parsing.
1081
+ */
1082
+ // eslint-disable-next-line no-unused-vars
1083
+ _onJson( data, onSuccess, onProgress, onError ) {}
1084
+
1085
+ /**
1086
+ * The abstract private _onText method must be overridden in case the parser expect a string/text as input data.
1087
+ *
1088
+ * @private
1089
+ * @abstract
1090
+ * @param {string} data - The retrieved data to parse.
1091
+ * @param {function} onSuccess - The onLoad callback, which is call when parser parse with success the data.
1092
+ * @param {function} onProgress - The onProgress callback, which is call during the parsing.
1093
+ * @param {function} onError - The onError callback, which is call when parser throw an error during parsing.
1094
+ */
1095
+ // eslint-disable-next-line no-unused-vars
1096
+ _onText( data, onSuccess, onProgress, onError ) {}
1097
+
1098
+ // REST Api calls
1099
+ /**
1100
+ * The private _create method allow to format a server request to create objects with the given data and get creation result with given callbacks.
1101
+ *
1102
+ * @private
1103
+ * @param {object} data - The data to send.
1104
+ * @param {function} onLoadCallback - The onLoad callback, which is call when server respond with success to the request.
1105
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
1106
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
1107
+ */
1108
+ _createOne( data, onLoadCallback, onProgressCallback, onErrorCallback ) {
1109
+
1110
+ this._requestQueue.push( {
1111
+ _id: `createOne_${ Generate.id }`,
1112
+ _timeStart: new Date(),
1113
+ _type: RequestType.CreateOne,
1114
+ method: HttpVerb.Create.value,
1115
+ url: this._basePath,
1116
+ data: data,
1117
+ onLoad: onLoadCallback,
1118
+ onProgress: onProgressCallback,
1119
+ onError: onErrorCallback,
1120
+ responseType: this._responseType
1121
+ } )
1122
+
1123
+ this.processQueue()
1124
+
1125
+ }
1126
+
1127
+ /**
1128
+ *
1129
+ * @param datas
1130
+ * @param onLoadCallback
1131
+ * @param onProgressCallback
1132
+ * @param onErrorCallback
1133
+ * @private
1134
+ */
1135
+ _createMany( datas, onLoadCallback, onProgressCallback, onErrorCallback ) {
1136
+
1137
+ this._requestQueue.push( {
1138
+ _id: `createMany_${ Generate.id }`,
1139
+ _timeStart: new Date(),
1140
+ _type: RequestType.CreateMany,
1141
+ method: HttpVerb.Create.value,
1142
+ url: this._basePath,
1143
+ data: datas,
1144
+ onLoad: onLoadCallback,
1145
+ onProgress: onProgressCallback,
1146
+ onError: onErrorCallback,
1147
+ responseType: this._responseType
1148
+ } )
1149
+
1150
+ this.processQueue()
1151
+
1152
+ }
1153
+
1154
+ /**
1155
+ * The private _updateOne method will format a server request to get a single object with the given id.
1156
+ *
1157
+ * @private
1158
+ * @param {string} id - The object's id of the object to retrieve.
1159
+ * @param {function} onLoadCallback - The onLoad callback, which is call when server respond with success to the request.
1160
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
1161
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
1162
+ */
1163
+ _readOne( id, projection, onLoadCallback, onProgressCallback, onErrorCallback ) {
1164
+
1165
+ // Filter requested values by cached values
1166
+ const datas = this._retrieveCachedValues( [ id ] )
1167
+
1168
+ // retrieveLocalStorageValues...
1169
+
1170
+ // getDatabaseValues()
1171
+
1172
+ if ( datas.toRequest.length === 0 ) {
1173
+
1174
+ if ( datas.underRequest.length === 0 ) {
1175
+
1176
+ onLoadCallback( datas.results )
1177
+
1178
+ } else {
1179
+
1180
+ datas[ 'onLoadCallback' ] = onLoadCallback
1181
+ datas[ 'onProgressCallback' ] = onProgressCallback
1182
+ datas[ 'onErrorCallback' ] = onErrorCallback
1183
+ this._waitingQueue.push( datas )
1184
+
1185
+ }
1186
+
1187
+ } else {
1188
+
1189
+ datas[ 'onLoadCallback' ] = onLoadCallback
1190
+ datas[ 'onProgressCallback' ] = onProgressCallback
1191
+ datas[ 'onErrorCallback' ] = onErrorCallback
1192
+ this._waitingQueue.push( datas )
1193
+
1194
+ try {
1195
+ this._cache.add( id, null )
1196
+ datas.underRequest.push( id )
1197
+ datas.toRequest.splice( datas.toRequest.indexOf( id ), 1 )
1198
+ } catch ( error ) {
1199
+ this.logger.error( error )
1200
+ }
1201
+
1202
+ this._idToRequest.push( id )
1203
+ this.aggregateQueue()
1204
+
1205
+ }
1206
+
1207
+ }
1208
+
1209
+ /**
1210
+ * The private _readMany method will format a server request to get objects with id in the ids array.
1211
+ *
1212
+ * @private
1213
+ * @param {array.<string>} ids - The ids of objects to retrieve.
1214
+ * @param {function} onLoadCallback - The onLoad callback, which is call when server respond with success to the request.
1215
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
1216
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
1217
+ */
1218
+ _readMany( ids, projection, onLoadCallback, onProgressCallback, onErrorCallback ) {
1219
+
1220
+ // Filter requested values by cached values
1221
+ const datas = this._retrieveCachedValues( ids )
1222
+
1223
+ // retrieveLocalStorageValues...
1224
+
1225
+ // getDatabaseValues()
1226
+
1227
+ if ( datas.toRequest.length === 0 ) {
1228
+
1229
+ if ( datas.underRequest.length === 0 ) {
1230
+
1231
+ onLoadCallback( datas.results )
1232
+
1233
+ } else {
1234
+
1235
+ datas[ 'onLoadCallback' ] = onLoadCallback
1236
+ datas[ 'onProgressCallback' ] = onProgressCallback
1237
+ datas[ 'onErrorCallback' ] = onErrorCallback
1238
+ this._waitingQueue.push( datas )
1239
+
1240
+ }
1241
+
1242
+ } else {
1243
+
1244
+ datas[ 'onLoadCallback' ] = onLoadCallback
1245
+ datas[ 'onProgressCallback' ] = onProgressCallback
1246
+ datas[ 'onErrorCallback' ] = onErrorCallback
1247
+ this._waitingQueue.push( datas )
1248
+
1249
+ const datasToRequest = datas.toRequest
1250
+ let id = undefined
1251
+ for ( let idIndex = datasToRequest.length - 1 ; idIndex >= 0 ; idIndex-- ) {
1252
+
1253
+ id = datasToRequest[ idIndex ]
1254
+
1255
+ // Prepare entry for id to request
1256
+ try {
1257
+ this._cache.add( id, null )
1258
+ datas.underRequest.push( id )
1259
+ datas.toRequest.splice( datas.toRequest.indexOf( id ), 1 )
1260
+ } catch ( error ) {
1261
+ this.logger.error( error )
1262
+ }
1263
+
1264
+ this._idToRequest.push( id )
1265
+
1266
+ }
1267
+
1268
+ this.aggregateQueue()
1269
+
1270
+ }
1271
+
1272
+ }
1273
+
1274
+ /**
1275
+ *
1276
+ * @param query
1277
+ * @param projection
1278
+ * @param onLoadCallback
1279
+ * @param onProgressCallback
1280
+ * @param onErrorCallback
1281
+ * @private
1282
+ */
1283
+ _readWhere( query, projection, onLoadCallback, onProgressCallback, onErrorCallback ) {
1284
+
1285
+ // // Filter requested values by cached values
1286
+ // const datas = {
1287
+ // results: {},
1288
+ // underRequest: [],
1289
+ // toRequest: []
1290
+ // }
1291
+ //
1292
+ // datas[ 'onLoadCallback' ] = onLoadCallback
1293
+ // this._waitingQueue.push( datas )
1294
+
1295
+ this._requestQueue.push( {
1296
+ _id: `readWhere_${ Generate.id }`,
1297
+ _timeStart: new Date(),
1298
+ _type: RequestType.ReadWhere,
1299
+ method: HttpVerb.Read.value,
1300
+ url: this._basePath,
1301
+ data: {
1302
+ query,
1303
+ projection
1304
+ },
1305
+ onLoad: onLoadCallback,
1306
+ onProgress: onProgressCallback,
1307
+ onError: onErrorCallback,
1308
+ responseType: this._responseType
1309
+ } )
1310
+
1311
+ this.processQueue()
1312
+
1313
+ }
1314
+
1315
+ /**
1316
+ *
1317
+ * @param projection
1318
+ * @param onLoadCallback
1319
+ * @param onProgressCallback
1320
+ * @param onErrorCallback
1321
+ * @private
1322
+ */
1323
+ _readAll( projection, onLoadCallback, onProgressCallback, onErrorCallback ) {
1324
+
1325
+ // const datas = {
1326
+ // results: {},
1327
+ // underRequest: [],
1328
+ // toRequest: []
1329
+ // }
1330
+ //
1331
+ // datas[ 'onLoadCallback' ] = onLoadCallback
1332
+ // this._waitingQueue.push( datas )
1333
+
1334
+ const query = {}
1335
+
1336
+ this._requestQueue.push( {
1337
+ _id: `readAll_${ Generate.id }`,
1338
+ _timeStart: new Date(),
1339
+ _type: RequestType.ReadAll,
1340
+ method: HttpVerb.Read.value,
1341
+ url: this._basePath,
1342
+ data: {
1343
+ query,
1344
+ projection
1345
+ },
1346
+ onLoad: onLoadCallback,
1347
+ onProgress: onProgressCallback,
1348
+ onError: onErrorCallback,
1349
+ responseType: this._responseType
1350
+ } )
1351
+
1352
+ this.processQueue()
1353
+
1354
+ }
1355
+
1356
+ /**
1357
+ * The private _updateOne method will format a server request to update a single object with the given id.
1358
+ *
1359
+ * @param {string} id - The object's id of the object to update.
1360
+ * @param update
1361
+ * @param {function} onLoadCallback - The onLoad callback, which is call when server respond with success to the request.
1362
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
1363
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
1364
+ * @private
1365
+ */
1366
+ _updateOne( id, update, onLoadCallback, onProgressCallback, onErrorCallback ) {
1367
+
1368
+ this._requestQueue.push( {
1369
+ _id: `updateOne_${ Generate.id }`,
1370
+ _timeStart: new Date(),
1371
+ _type: RequestType.UpdateOne,
1372
+ method: HttpVerb.Update.value,
1373
+ url: `${ this._basePath }/${ id }`,
1374
+ data: {
1375
+ update
1376
+ },
1377
+ onLoad: onLoadCallback,
1378
+ onProgress: onProgressCallback,
1379
+ onError: onErrorCallback,
1380
+ responseType: this._responseType
1381
+ } )
1382
+
1383
+ this.processQueue()
1384
+
1385
+ }
1386
+
1387
+ /**
1388
+ * The private _updateMany method will format a server request to update objects with id in the ids array.
1389
+ *
1390
+ * @param {array.<string>} ids - The ids of objects to update.
1391
+ * @param update
1392
+ * @param {function} onLoadCallback - The onLoad callback, which is call when server respond with success to the request.
1393
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
1394
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
1395
+ * @private
1396
+ */
1397
+ _updateMany( ids, update, onLoadCallback, onProgressCallback, onErrorCallback ) {
1398
+
1399
+ this._requestQueue.push( {
1400
+ _id: `updateMany_${ Generate.id }`,
1401
+ _timeStart: new Date(),
1402
+ _type: RequestType.UpdateMany,
1403
+ method: HttpVerb.Update.value,
1404
+ url: this._basePath,
1405
+ data: {
1406
+ ids,
1407
+ update
1408
+ },
1409
+ onLoad: onLoadCallback,
1410
+ onProgress: onProgressCallback,
1411
+ onError: onErrorCallback,
1412
+ responseType: this._responseType
1413
+ } )
1414
+
1415
+ this.processQueue()
1416
+
1417
+ }
1418
+
1419
+ /**
1420
+ *
1421
+ * @param query
1422
+ * @param update
1423
+ * @param onLoadCallback
1424
+ * @param onProgressCallback
1425
+ * @param onErrorCallback
1426
+ * @private
1427
+ */
1428
+ _updateWhere( query, update, onLoadCallback, onProgressCallback, onErrorCallback ) {
1429
+
1430
+ this._requestQueue.push( {
1431
+ _id: `updateWhere_${ Generate.id }`,
1432
+ _timeStart: new Date(),
1433
+ _type: RequestType.UpdateWhere,
1434
+ method: HttpVerb.Update.value,
1435
+ url: this._basePath,
1436
+ data: {
1437
+ query,
1438
+ update
1439
+ },
1440
+ onLoad: onLoadCallback,
1441
+ onProgress: onProgressCallback,
1442
+ onError: onErrorCallback,
1443
+ responseType: this._responseType
1444
+ } )
1445
+
1446
+ this.processQueue()
1447
+
1448
+ }
1449
+
1450
+ /**
1451
+ *
1452
+ * @param update
1453
+ * @param onLoadCallback
1454
+ * @param onProgressCallback
1455
+ * @param onErrorCallback
1456
+ * @private
1457
+ */
1458
+ _updateAll( update, onLoadCallback, onProgressCallback, onErrorCallback ) {
1459
+
1460
+ const query = {}
1461
+
1462
+ this._requestQueue.push( {
1463
+ _id: `updateAll_${ Generate.id }`,
1464
+ _timeStart: new Date(),
1465
+ _type: RequestType.UpdateAll,
1466
+ method: HttpVerb.Update.value,
1467
+ url: this._basePath,
1468
+ data: {
1469
+ query,
1470
+ update
1471
+ },
1472
+ onLoad: onLoadCallback,
1473
+ onProgress: onProgressCallback,
1474
+ onError: onErrorCallback,
1475
+ responseType: this._responseType
1476
+ } )
1477
+
1478
+ this.processQueue()
1479
+
1480
+ }
1481
+
1482
+ /**
1483
+ * The private _deleteOne method will format a server request to delete a single object with the given id.
1484
+ *
1485
+ * @param {string} id - The object's id of the object to delete.
1486
+ * @param {function} onLoadCallback - The onLoad callback, which is call when server respond with success to the request.
1487
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
1488
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
1489
+ * @private
1490
+ */
1491
+ _deleteOne( id, onLoadCallback, onProgressCallback, onErrorCallback ) {
1492
+
1493
+ this._requestQueue.push( {
1494
+ _id: `deleteOne_${ Generate.id }`,
1495
+ _timeStart: new Date(),
1496
+ _type: RequestType.DeleteOne,
1497
+ method: HttpVerb.Delete.value,
1498
+ url: `${ this._basePath }/${ id }`,
1499
+ data: null,
1500
+ onLoad: onLoadCallback,
1501
+ onProgress: onProgressCallback,
1502
+ onError: onErrorCallback,
1503
+ responseType: this._responseType
1504
+ } )
1505
+
1506
+ this.processQueue()
1507
+
1508
+ }
1509
+
1510
+ /**
1511
+ * The private _deleteMany method will format a server request to delete objects with id in the ids array.
1512
+ *
1513
+ * @param {array.<string>} ids - The ids of objects to delete.
1514
+ * @param {function} onLoadCallback - The onLoad callback, which is call when server respond with success to the request.
1515
+ * @param {function} onProgressCallback - The onProgress callback, which is call during the response incoming.
1516
+ * @param {function} onErrorCallback - The onError callback, which is call when server respond with an error to the request.
1517
+ * @private
1518
+ */
1519
+ _deleteMany( ids, onLoadCallback, onProgressCallback, onErrorCallback ) {
1520
+
1521
+ this._requestQueue.push( {
1522
+ _id: `deleteMany_${ Generate.id }`,
1523
+ _timeStart: new Date(),
1524
+ _type: RequestType.DeleteMany,
1525
+ method: HttpVerb.Delete.value,
1526
+ url: this._basePath,
1527
+ data: {
1528
+ ids
1529
+ },
1530
+ onLoad: onLoadCallback,
1531
+ onProgress: onProgressCallback,
1532
+ onError: onErrorCallback,
1533
+ responseType: this._responseType
1534
+ } )
1535
+
1536
+ this.processQueue()
1537
+
1538
+ }
1539
+
1540
+ /**
1541
+ *
1542
+ * @param query
1543
+ * @param onLoadCallback
1544
+ * @param onProgressCallback
1545
+ * @param onErrorCallback
1546
+ * @private
1547
+ */
1548
+ _deleteWhere( query, onLoadCallback, onProgressCallback, onErrorCallback ) {
1549
+
1550
+ this._requestQueue.push( {
1551
+ _id: `deleteWhere_${ Generate.id }`,
1552
+ _timeStart: new Date(),
1553
+ _type: RequestType.DeleteWhere,
1554
+ method: HttpVerb.Delete.value,
1555
+ url: this._basePath,
1556
+ data: {
1557
+ query
1558
+ },
1559
+ onLoad: onLoadCallback,
1560
+ onProgress: onProgressCallback,
1561
+ onError: onErrorCallback,
1562
+ responseType: this._responseType
1563
+ } )
1564
+
1565
+ this.processQueue()
1566
+
1567
+ }
1568
+
1569
+ /**
1570
+ *
1571
+ * @param onLoadCallback
1572
+ * @param onProgressCallback
1573
+ * @param onErrorCallback
1574
+ * @private
1575
+ */
1576
+ _deleteAll( onLoadCallback, onProgressCallback, onErrorCallback ) {
1577
+
1578
+ const query = {}
1579
+
1580
+ this._requestQueue.push( {
1581
+ _id: `deleteAll_${ Generate.id }`,
1582
+ _timeStart: new Date(),
1583
+ _type: RequestType.DeleteAll,
1584
+ method: HttpVerb.Delete.value,
1585
+ url: this._basePath,
1586
+ data: {
1587
+ query
1588
+ },
1589
+ onLoad: onLoadCallback,
1590
+ onProgress: onProgressCallback,
1591
+ onError: onErrorCallback,
1592
+ responseType: this._responseType
1593
+ } )
1594
+
1595
+ this.processQueue()
1596
+
1597
+ }
1598
+
1599
+ }
1600
+
1601
+ // Static stuff
1602
+ /**
1603
+ *
1604
+ * @type {number}
1605
+ * @private
1606
+ */
1607
+ TDataBaseManager._requestId = 0
1608
+
1609
+ /**
1610
+ *
1611
+ * @type {Object}
1612
+ * @private
1613
+ */
1614
+ TDataBaseManager._requests = {
1615
+ /**
1616
+ * The global waiting queue to process
1617
+ */
1618
+ waitingQueue: {},
1619
+ /**
1620
+ * The objects not requested yet
1621
+ */
1622
+ toProcess: {
1623
+ create: {},
1624
+ read: {},
1625
+ update: {},
1626
+ delete: {}
1627
+ },
1628
+ /**
1629
+ * The object currently under request
1630
+ */
1631
+ underProcess: {
1632
+ create: {},
1633
+ read: {},
1634
+ update: {},
1635
+ delete: {}
1636
+ },
1637
+ /**
1638
+ * The objects already processed
1639
+ */
1640
+ processed: {
1641
+ create: {},
1642
+ read: {},
1643
+ update: {},
1644
+ delete: {}
1645
+ }
1646
+ }
1647
+ //TDataBaseManager._orchestrator = TOrchestrator
1648
+
1649
+ export { TDataBaseManager }