@nymphjs/nymph 1.0.0-beta.2 → 1.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Nymph.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Config, ConfigDefaults as defaults } from './conf';
2
- import { NymphDriver } from './driver';
2
+ import type { NymphDriver } from './driver';
3
3
  import Entity from './Entity';
4
- import { EntityConstructor, EntityData, EntityInterface } from './Entity.types';
4
+ import type { EntityConstructor, EntityInterface } from './Entity.types';
5
5
  import { ClassNotAvailableError } from './errors';
6
6
  import type {
7
7
  Selector,
@@ -12,18 +12,31 @@ import type {
12
12
  NymphBeforeGetEntitiesCallback,
13
13
  NymphBeforeSaveEntityCallback,
14
14
  NymphAfterSaveEntityCallback,
15
+ NymphFailedSaveEntityCallback,
15
16
  NymphBeforeDeleteEntityCallback,
16
17
  NymphAfterDeleteEntityCallback,
18
+ NymphFailedDeleteEntityCallback,
17
19
  NymphBeforeDeleteEntityByIDCallback,
18
20
  NymphAfterDeleteEntityByIDCallback,
21
+ NymphFailedDeleteEntityByIDCallback,
19
22
  NymphBeforeNewUIDCallback,
20
23
  NymphAfterNewUIDCallback,
24
+ NymphFailedNewUIDCallback,
21
25
  NymphBeforeSetUIDCallback,
22
26
  NymphAfterSetUIDCallback,
27
+ NymphFailedSetUIDCallback,
23
28
  NymphBeforeRenameUIDCallback,
24
29
  NymphAfterRenameUIDCallback,
30
+ NymphFailedRenameUIDCallback,
25
31
  NymphBeforeDeleteUIDCallback,
26
32
  NymphAfterDeleteUIDCallback,
33
+ NymphFailedDeleteUIDCallback,
34
+ NymphBeforeStartTransactionCallback,
35
+ NymphAfterStartTransactionCallback,
36
+ NymphBeforeCommitTransactionCallback,
37
+ NymphAfterCommitTransactionCallback,
38
+ NymphBeforeRollbackTransactionCallback,
39
+ NymphAfterRollbackTransactionCallback,
27
40
  NymphEventType,
28
41
  NymphQueryCallback,
29
42
  FormattedSelector,
@@ -41,10 +54,16 @@ import type {
41
54
  */
42
55
  export default class Nymph {
43
56
  /**
44
- * The PubSub config.
57
+ * The Nymph config.
45
58
  */
46
59
  public config: Config;
47
60
 
61
+ /**
62
+ * The Nymph instance that this one was cloned from, or null if it's not a
63
+ * clone.
64
+ */
65
+ public parent: Nymph | null;
66
+
48
67
  /**
49
68
  * The Nymph database driver.
50
69
  */
@@ -63,7 +82,7 @@ export default class Nymph {
63
82
  /**
64
83
  * The entity class for this instance of Nymph.
65
84
  */
66
- public Entity: typeof Entity = Entity;
85
+ public Entity: typeof Entity;
67
86
 
68
87
  private connectCallbacks: NymphConnectCallback[] = [];
69
88
  private disconnectCallbacks: NymphDisconnectCallback[] = [];
@@ -72,34 +91,40 @@ export default class Nymph {
72
91
  private beforeGetEntitiesCallbacks: NymphBeforeGetEntitiesCallback[] = [];
73
92
  private beforeSaveEntityCallbacks: NymphBeforeSaveEntityCallback[] = [];
74
93
  private afterSaveEntityCallbacks: NymphAfterSaveEntityCallback[] = [];
94
+ private failedSaveEntityCallbacks: NymphFailedSaveEntityCallback[] = [];
75
95
  private beforeDeleteEntityCallbacks: NymphBeforeDeleteEntityCallback[] = [];
76
96
  private afterDeleteEntityCallbacks: NymphAfterDeleteEntityCallback[] = [];
97
+ private failedDeleteEntityCallbacks: NymphFailedDeleteEntityCallback[] = [];
77
98
  private beforeDeleteEntityByIDCallbacks: NymphBeforeDeleteEntityByIDCallback[] =
78
99
  [];
79
100
  private afterDeleteEntityByIDCallbacks: NymphAfterDeleteEntityByIDCallback[] =
80
101
  [];
102
+ private failedDeleteEntityByIDCallbacks: NymphFailedDeleteEntityByIDCallback[] =
103
+ [];
81
104
  private beforeNewUIDCallbacks: NymphBeforeNewUIDCallback[] = [];
82
105
  private afterNewUIDCallbacks: NymphAfterNewUIDCallback[] = [];
106
+ private failedNewUIDCallbacks: NymphFailedNewUIDCallback[] = [];
83
107
  private beforeSetUIDCallbacks: NymphBeforeSetUIDCallback[] = [];
84
108
  private afterSetUIDCallbacks: NymphAfterSetUIDCallback[] = [];
109
+ private failedSetUIDCallbacks: NymphFailedSetUIDCallback[] = [];
85
110
  private beforeRenameUIDCallbacks: NymphBeforeRenameUIDCallback[] = [];
86
111
  private afterRenameUIDCallbacks: NymphAfterRenameUIDCallback[] = [];
112
+ private failedRenameUIDCallbacks: NymphFailedRenameUIDCallback[] = [];
87
113
  private beforeDeleteUIDCallbacks: NymphBeforeDeleteUIDCallback[] = [];
88
114
  private afterDeleteUIDCallbacks: NymphAfterDeleteUIDCallback[] = [];
89
-
90
- public addEntityClass(entityClass: EntityConstructor) {
91
- this.entityClasses[entityClass.class] = entityClass;
92
- entityClass.nymph = this;
93
- }
94
-
95
- public getEntityClass(className: string): EntityConstructor {
96
- if (className in this.entityClasses) {
97
- const EntityClass = this.entityClasses[className];
98
- EntityClass.nymph = this;
99
- return EntityClass;
100
- }
101
- throw new ClassNotAvailableError('Tried to use class: ' + className);
102
- }
115
+ private failedDeleteUIDCallbacks: NymphFailedDeleteUIDCallback[] = [];
116
+ private beforeStartTransactionCallbacks: NymphBeforeStartTransactionCallback[] =
117
+ [];
118
+ private afterStartTransactionCallbacks: NymphAfterStartTransactionCallback[] =
119
+ [];
120
+ private beforeCommitTransactionCallbacks: NymphBeforeCommitTransactionCallback[] =
121
+ [];
122
+ private afterCommitTransactionCallbacks: NymphAfterCommitTransactionCallback[] =
123
+ [];
124
+ private beforeRollbackTransactionCallbacks: NymphBeforeRollbackTransactionCallback[] =
125
+ [];
126
+ private afterRollbackTransactionCallbacks: NymphAfterRollbackTransactionCallback[] =
127
+ [];
103
128
 
104
129
  /**
105
130
  * Initialize Nymph.
@@ -115,28 +140,67 @@ export default class Nymph {
115
140
  ) {
116
141
  this.config = { ...defaults, ...config };
117
142
  this.driver = driver;
118
- if (typeof tilmeld !== 'undefined') {
143
+ this.parent = null;
144
+
145
+ this.Entity = this.addEntityClass(Entity);
146
+
147
+ if (tilmeld != null) {
119
148
  this.tilmeld = tilmeld;
120
149
  }
121
150
 
122
- class NymphEntity<T extends EntityData = EntityData> extends Entity<T> {}
123
- NymphEntity.nymph = this;
124
- this.Entity = NymphEntity;
125
- this.addEntityClass(NymphEntity);
126
-
127
151
  this.driver.init(this);
128
152
  if (this.tilmeld) {
129
153
  this.tilmeld.init(this);
130
154
  }
131
155
  }
132
156
 
157
+ /**
158
+ * Add your class to this instance.
159
+ *
160
+ * This will create a class that extends your class within this instance of
161
+ * Nymph and return it. You can then use this class's constructor and methods,
162
+ * which will use this instance of Nymph.
163
+ *
164
+ * Because this creates a subclass, don't use the class
165
+ * returned from `getEntityClass` to check with `instanceof`.
166
+ */
167
+ public addEntityClass<T extends EntityConstructor>(entityClass: T): T {
168
+ const nymph = this;
169
+ class NymphEntity extends entityClass {
170
+ static nymph: Nymph = nymph;
171
+
172
+ constructor(...args: any[]) {
173
+ super(...args);
174
+ }
175
+ }
176
+ this.entityClasses[entityClass.class] = NymphEntity;
177
+ return NymphEntity;
178
+ }
179
+
180
+ /**
181
+ * Get the class that uses the specified class name.
182
+ */
183
+ public getEntityClass(className: string): EntityConstructor {
184
+ if (className in this.entityClasses) {
185
+ return this.entityClasses[className];
186
+ }
187
+ throw new ClassNotAvailableError('Tried to use class: ' + className);
188
+ }
189
+
133
190
  /**
134
191
  * Get a clone of this instance with duplicate classes and event listeners.
135
192
  *
136
193
  * @returns A clone of this instance.
137
194
  */
138
195
  public clone() {
139
- const nymph = new Nymph(this.config, this.driver, this.tilmeld?.clone());
196
+ const nymph = new Nymph(
197
+ this.config,
198
+ this.driver.clone(),
199
+ this.tilmeld?.clone()
200
+ );
201
+
202
+ nymph.parent = this;
203
+
140
204
  for (const name in this.entityClasses) {
141
205
  if (name === 'Entity' || (this.entityClasses[name] as any).skipOnClone) {
142
206
  continue;
@@ -152,18 +216,31 @@ export default class Nymph {
152
216
  'beforeGetEntities',
153
217
  'beforeSaveEntity',
154
218
  'afterSaveEntity',
219
+ 'failedSaveEntity',
155
220
  'beforeDeleteEntity',
156
221
  'afterDeleteEntity',
222
+ 'failedDeleteEntity',
157
223
  'beforeDeleteEntityByID',
158
224
  'afterDeleteEntityByID',
225
+ 'failedDeleteEntityByID',
159
226
  'beforeNewUID',
160
227
  'afterNewUID',
228
+ 'failedNewUID',
161
229
  'beforeSetUID',
162
230
  'afterSetUID',
231
+ 'failedSetUID',
163
232
  'beforeRenameUID',
164
233
  'afterRenameUID',
234
+ 'failedRenameUID',
165
235
  'beforeDeleteUID',
166
236
  'afterDeleteUID',
237
+ 'failedDeleteUID',
238
+ 'beforeStartTransaction',
239
+ 'afterStartTransaction',
240
+ 'beforeCommitTransaction',
241
+ 'afterCommitTransaction',
242
+ 'beforeRollbackTransaction',
243
+ 'afterRollbackTransaction',
167
244
  ];
168
245
 
169
246
  for (let event of events) {
@@ -214,13 +291,10 @@ export default class Nymph {
214
291
  /**
215
292
  * Run all the query callbacks on a query.
216
293
  */
217
- public async runQueryCallbacks(
218
- options: Options,
219
- selectors: FormattedSelector[]
220
- ) {
294
+ public runQueryCallbacks(options: Options, selectors: FormattedSelector[]) {
221
295
  for (let callback of this.queryCallbacks) {
222
296
  if (callback) {
223
- await callback(this, options, selectors);
297
+ callback(this, options, selectors);
224
298
  }
225
299
  }
226
300
  }
@@ -235,28 +309,65 @@ export default class Nymph {
235
309
  * Transactions will nest as long as every name is unique. Internally, Nymph
236
310
  * uses names prefixed with "nymph-".
237
311
  *
238
- * @returns True on success, false on failure.
312
+ * @returns A new instance of Nymph that should be used for the transaction.
239
313
  */
240
314
  public async startTransaction(name: string): Promise<Nymph> {
241
- return await this.driver.startTransaction(name);
315
+ for (let callback of this.beforeStartTransactionCallbacks) {
316
+ if (callback) {
317
+ await callback(this, name);
318
+ }
319
+ }
320
+ const result = await this.driver.startTransaction(name);
321
+ for (let callback of this.afterStartTransactionCallbacks) {
322
+ if (callback) {
323
+ await callback(this, name, result);
324
+ }
325
+ }
326
+ return result;
242
327
  }
243
328
 
244
329
  /**
245
330
  * Commit the named transaction.
246
331
  *
332
+ * After this is called, the transaction instance should be discarded.
333
+ *
247
334
  * @returns True on success, false on failure.
248
335
  */
249
336
  public async commit(name: string): Promise<boolean> {
250
- return await this.driver.commit(name);
337
+ for (let callback of this.beforeCommitTransactionCallbacks) {
338
+ if (callback) {
339
+ await callback(this, name);
340
+ }
341
+ }
342
+ const result = await this.driver.commit(name);
343
+ for (let callback of this.afterCommitTransactionCallbacks) {
344
+ if (callback) {
345
+ await callback(this, name, result);
346
+ }
347
+ }
348
+ return result;
251
349
  }
252
350
 
253
351
  /**
254
352
  * Rollback the named transaction.
255
353
  *
354
+ * After this is called, the transaction instance should be discarded.
355
+ *
256
356
  * @returns True on success, false on failure.
257
357
  */
258
358
  public async rollback(name: string): Promise<boolean> {
259
- return await this.driver.rollback(name);
359
+ for (let callback of this.beforeRollbackTransactionCallbacks) {
360
+ if (callback) {
361
+ await callback(this, name);
362
+ }
363
+ }
364
+ const result = await this.driver.rollback(name);
365
+ for (let callback of this.afterRollbackTransactionCallbacks) {
366
+ if (callback) {
367
+ await callback(this, name, result);
368
+ }
369
+ }
370
+ return result;
260
371
  }
261
372
 
262
373
  /**
@@ -295,7 +406,17 @@ export default class Nymph {
295
406
  await callback(this, name);
296
407
  }
297
408
  }
298
- const result = this.driver.newUID(name);
409
+ let result: Promise<number | null>;
410
+ try {
411
+ result = this.driver.newUID(name);
412
+ } catch (e: any) {
413
+ for (let callback of this.failedNewUIDCallbacks) {
414
+ if (callback) {
415
+ await callback(this, e);
416
+ }
417
+ }
418
+ throw e;
419
+ }
299
420
  for (let callback of this.afterNewUIDCallbacks) {
300
421
  if (callback) {
301
422
  await callback(this, result);
@@ -326,7 +447,17 @@ export default class Nymph {
326
447
  await callback(this, name, value);
327
448
  }
328
449
  }
329
- const result = this.driver.setUID(name, value);
450
+ let result: Promise<boolean>;
451
+ try {
452
+ result = this.driver.setUID(name, value);
453
+ } catch (e: any) {
454
+ for (let callback of this.failedSetUIDCallbacks) {
455
+ if (callback) {
456
+ await callback(this, e);
457
+ }
458
+ }
459
+ throw e;
460
+ }
330
461
  for (let callback of this.afterSetUIDCallbacks) {
331
462
  if (callback) {
332
463
  await callback(this, result);
@@ -347,7 +478,17 @@ export default class Nymph {
347
478
  await callback(this, name);
348
479
  }
349
480
  }
350
- const result = this.driver.deleteUID(name);
481
+ let result: Promise<boolean>;
482
+ try {
483
+ result = this.driver.deleteUID(name);
484
+ } catch (e: any) {
485
+ for (let callback of this.failedDeleteUIDCallbacks) {
486
+ if (callback) {
487
+ await callback(this, e);
488
+ }
489
+ }
490
+ throw e;
491
+ }
351
492
  for (let callback of this.afterDeleteUIDCallbacks) {
352
493
  if (callback) {
353
494
  await callback(this, result);
@@ -369,7 +510,17 @@ export default class Nymph {
369
510
  await callback(this, oldName, newName);
370
511
  }
371
512
  }
372
- const result = this.driver.renameUID(oldName, newName);
513
+ let result: Promise<boolean>;
514
+ try {
515
+ result = this.driver.renameUID(oldName, newName);
516
+ } catch (e: any) {
517
+ for (let callback of this.failedRenameUIDCallbacks) {
518
+ if (callback) {
519
+ await callback(this, e);
520
+ }
521
+ }
522
+ throw e;
523
+ }
373
524
  for (let callback of this.afterRenameUIDCallbacks) {
374
525
  if (callback) {
375
526
  await callback(this, result);
@@ -395,7 +546,17 @@ export default class Nymph {
395
546
  await callback(this, entity);
396
547
  }
397
548
  }
398
- const result = this.driver.saveEntity(entity);
549
+ let result: Promise<boolean>;
550
+ try {
551
+ result = this.driver.saveEntity(entity);
552
+ } catch (e: any) {
553
+ for (let callback of this.failedSaveEntityCallbacks) {
554
+ if (callback) {
555
+ await callback(this, e);
556
+ }
557
+ }
558
+ throw e;
559
+ }
399
560
  for (let callback of this.afterSaveEntityCallbacks) {
400
561
  if (callback) {
401
562
  await callback(this, result);
@@ -414,8 +575,10 @@ export default class Nymph {
414
575
  * - offset - The offset from the oldest matching entity to start retrieving.
415
576
  * - reverse - If true, entities will be retrieved from newest to oldest.
416
577
  * Therefore, offset will be from the newest entity.
417
- * - sort - How to sort the entities. Accepts "cdate" or "mdate". Defaults to
418
- * "cdate".
578
+ * - sort - How to sort the entities. Accepts "cdate", "mdate", or the name of
579
+ * a top-level property. The method of sorting properties other than cdate
580
+ * and mdate is driver dependent. The only hard rule is that numbers should
581
+ * be sorted numerically (2 before 10). Defaults to "cdate".
419
582
  * - return - What to return. "entity", "guid", or "count". Defaults to
420
583
  * "entity".
421
584
  * - source - Will be 'client' if the query came from a REST call.
@@ -659,7 +822,17 @@ export default class Nymph {
659
822
  await callback(this, entity);
660
823
  }
661
824
  }
662
- const result = this.driver.deleteEntity(entity);
825
+ let result: Promise<boolean>;
826
+ try {
827
+ result = this.driver.deleteEntity(entity);
828
+ } catch (e: any) {
829
+ for (let callback of this.failedDeleteEntityCallbacks) {
830
+ if (callback) {
831
+ await callback(this, e);
832
+ }
833
+ }
834
+ throw e;
835
+ }
663
836
  for (let callback of this.afterDeleteEntityCallbacks) {
664
837
  if (callback) {
665
838
  await callback(this, result);
@@ -684,7 +857,17 @@ export default class Nymph {
684
857
  await callback(this, guid, className);
685
858
  }
686
859
  }
687
- const result = this.driver.deleteEntityByID(guid, className);
860
+ let result: Promise<boolean>;
861
+ try {
862
+ result = this.driver.deleteEntityByID(guid, className);
863
+ } catch (e: any) {
864
+ for (let callback of this.failedDeleteEntityByIDCallbacks) {
865
+ if (callback) {
866
+ await callback(this, e);
867
+ }
868
+ }
869
+ throw e;
870
+ }
688
871
  for (let callback of this.afterDeleteEntityByIDCallbacks) {
689
872
  if (callback) {
690
873
  await callback(this, result);
@@ -715,7 +898,7 @@ export default class Nymph {
715
898
  * # brackets ([]).
716
899
  * # Properties are stored like this:
717
900
  * # propname=JSON.stringify(value)
718
- * abilities=["system/all"]
901
+ * abilities=["system/admin"]
719
902
  * groups=[]
720
903
  * inheritAbilities=false
721
904
  * name="admin"
@@ -768,30 +951,56 @@ export default class Nymph {
768
951
  ? NymphBeforeSaveEntityCallback
769
952
  : T extends 'afterSaveEntity'
770
953
  ? NymphAfterSaveEntityCallback
954
+ : T extends 'failedSaveEntity'
955
+ ? NymphFailedSaveEntityCallback
771
956
  : T extends 'beforeDeleteEntity'
772
957
  ? NymphBeforeDeleteEntityCallback
773
958
  : T extends 'afterDeleteEntity'
774
959
  ? NymphAfterDeleteEntityCallback
960
+ : T extends 'failedDeleteEntity'
961
+ ? NymphFailedDeleteEntityCallback
775
962
  : T extends 'beforeDeleteEntityByID'
776
963
  ? NymphBeforeDeleteEntityByIDCallback
777
964
  : T extends 'afterDeleteEntityByID'
778
965
  ? NymphAfterDeleteEntityByIDCallback
966
+ : T extends 'failedDeleteEntityByID'
967
+ ? NymphFailedDeleteEntityByIDCallback
779
968
  : T extends 'beforeNewUID'
780
969
  ? NymphBeforeNewUIDCallback
781
970
  : T extends 'afterNewUID'
782
971
  ? NymphAfterNewUIDCallback
972
+ : T extends 'failedNewUID'
973
+ ? NymphFailedNewUIDCallback
783
974
  : T extends 'beforeSetUID'
784
975
  ? NymphBeforeSetUIDCallback
785
976
  : T extends 'afterSetUID'
786
977
  ? NymphAfterSetUIDCallback
978
+ : T extends 'failedSetUID'
979
+ ? NymphFailedSetUIDCallback
787
980
  : T extends 'beforeRenameUID'
788
981
  ? NymphBeforeRenameUIDCallback
789
982
  : T extends 'afterRenameUID'
790
983
  ? NymphAfterRenameUIDCallback
984
+ : T extends 'failedRenameUID'
985
+ ? NymphFailedRenameUIDCallback
791
986
  : T extends 'beforeDeleteUID'
792
987
  ? NymphBeforeDeleteUIDCallback
793
988
  : T extends 'afterDeleteUID'
794
989
  ? NymphAfterDeleteUIDCallback
990
+ : T extends 'failedDeleteUID'
991
+ ? NymphFailedDeleteUIDCallback
992
+ : T extends 'beforeStartTransaction'
993
+ ? NymphBeforeStartTransactionCallback
994
+ : T extends 'afterStartTransaction'
995
+ ? NymphAfterStartTransactionCallback
996
+ : T extends 'beforeCommitTransaction'
997
+ ? NymphBeforeCommitTransactionCallback
998
+ : T extends 'afterCommitTransaction'
999
+ ? NymphAfterCommitTransactionCallback
1000
+ : T extends 'beforeRollbackTransaction'
1001
+ ? NymphBeforeRollbackTransactionCallback
1002
+ : T extends 'afterRollbackTransaction'
1003
+ ? NymphAfterRollbackTransactionCallback
795
1004
  : never
796
1005
  ) {
797
1006
  const prop = (event + 'Callbacks') as T extends 'connect'
@@ -808,30 +1017,56 @@ export default class Nymph {
808
1017
  ? 'beforeSaveEntityCallbacks'
809
1018
  : T extends 'afterSaveEntity'
810
1019
  ? 'afterSaveEntityCallbacks'
1020
+ : T extends 'failedSaveEntity'
1021
+ ? 'failedSaveEntityCallbacks'
811
1022
  : T extends 'beforeDeleteEntity'
812
1023
  ? 'beforeDeleteEntityCallbacks'
813
1024
  : T extends 'afterDeleteEntity'
814
1025
  ? 'afterDeleteEntityCallbacks'
1026
+ : T extends 'failedDeleteEntity'
1027
+ ? 'failedDeleteEntityCallbacks'
815
1028
  : T extends 'beforeDeleteEntityByID'
816
1029
  ? 'beforeDeleteEntityByIDCallbacks'
817
1030
  : T extends 'afterDeleteEntityByID'
818
1031
  ? 'afterDeleteEntityByIDCallbacks'
1032
+ : T extends 'failedDeleteEntityByID'
1033
+ ? 'failedDeleteEntityByIDCallbacks'
819
1034
  : T extends 'beforeNewUID'
820
1035
  ? 'beforeNewUIDCallbacks'
821
1036
  : T extends 'afterNewUID'
822
1037
  ? 'afterNewUIDCallbacks'
1038
+ : T extends 'failedNewUID'
1039
+ ? 'failedNewUIDCallbacks'
823
1040
  : T extends 'beforeSetUID'
824
1041
  ? 'beforeSetUIDCallbacks'
825
1042
  : T extends 'afterSetUID'
826
1043
  ? 'afterSetUIDCallbacks'
1044
+ : T extends 'failedSetUID'
1045
+ ? 'failedSetUIDCallbacks'
827
1046
  : T extends 'beforeRenameUID'
828
1047
  ? 'beforeRenameUIDCallbacks'
829
1048
  : T extends 'afterRenameUID'
830
1049
  ? 'afterRenameUIDCallbacks'
1050
+ : T extends 'failedRenameUID'
1051
+ ? 'failedRenameUIDCallbacks'
831
1052
  : T extends 'beforeDeleteUID'
832
1053
  ? 'beforeDeleteUIDCallbacks'
833
1054
  : T extends 'afterDeleteUID'
834
1055
  ? 'afterDeleteUIDCallbacks'
1056
+ : T extends 'failedDeleteUID'
1057
+ ? 'failedDeleteUIDCallbacks'
1058
+ : T extends 'beforeStartTransaction'
1059
+ ? 'beforeStartTransactionCallbacks'
1060
+ : T extends 'afterStartTransaction'
1061
+ ? 'afterStartTransactionCallbacks'
1062
+ : T extends 'beforeCommitTransaction'
1063
+ ? 'beforeCommitTransactionCallbacks'
1064
+ : T extends 'afterCommitTransaction'
1065
+ ? 'afterCommitTransactionCallbacks'
1066
+ : T extends 'beforeRollbackTransaction'
1067
+ ? 'beforeRollbackTransactionCallbacks'
1068
+ : T extends 'afterRollbackTransaction'
1069
+ ? 'afterRollbackTransactionCallbacks'
835
1070
  : never;
836
1071
  if (!(prop in this)) {
837
1072
  throw new Error('Invalid event type.');
@@ -857,30 +1092,56 @@ export default class Nymph {
857
1092
  ? NymphBeforeSaveEntityCallback
858
1093
  : T extends 'afterSaveEntity'
859
1094
  ? NymphAfterSaveEntityCallback
1095
+ : T extends 'failedSaveEntity'
1096
+ ? NymphFailedSaveEntityCallback
860
1097
  : T extends 'beforeDeleteEntity'
861
1098
  ? NymphBeforeDeleteEntityCallback
862
1099
  : T extends 'afterDeleteEntity'
863
1100
  ? NymphAfterDeleteEntityCallback
1101
+ : T extends 'failedDeleteEntity'
1102
+ ? NymphFailedDeleteEntityCallback
864
1103
  : T extends 'beforeDeleteEntityByID'
865
1104
  ? NymphBeforeDeleteEntityByIDCallback
866
1105
  : T extends 'afterDeleteEntityByID'
867
1106
  ? NymphAfterDeleteEntityByIDCallback
1107
+ : T extends 'failedDeleteEntityByID'
1108
+ ? NymphFailedDeleteEntityByIDCallback
868
1109
  : T extends 'beforeNewUID'
869
1110
  ? NymphBeforeNewUIDCallback
870
1111
  : T extends 'afterNewUID'
871
1112
  ? NymphAfterNewUIDCallback
1113
+ : T extends 'failedNewUID'
1114
+ ? NymphFailedNewUIDCallback
872
1115
  : T extends 'beforeSetUID'
873
1116
  ? NymphBeforeSetUIDCallback
874
1117
  : T extends 'afterSetUID'
875
1118
  ? NymphAfterSetUIDCallback
1119
+ : T extends 'failedSetUID'
1120
+ ? NymphFailedSetUIDCallback
876
1121
  : T extends 'beforeRenameUID'
877
1122
  ? NymphBeforeRenameUIDCallback
878
1123
  : T extends 'afterRenameUID'
879
1124
  ? NymphAfterRenameUIDCallback
1125
+ : T extends 'failedRenameUID'
1126
+ ? NymphFailedRenameUIDCallback
880
1127
  : T extends 'beforeDeleteUID'
881
1128
  ? NymphBeforeDeleteUIDCallback
882
1129
  : T extends 'afterDeleteUID'
883
1130
  ? NymphAfterDeleteUIDCallback
1131
+ : T extends 'failedDeleteUID'
1132
+ ? NymphFailedDeleteUIDCallback
1133
+ : T extends 'beforeStartTransaction'
1134
+ ? NymphBeforeStartTransactionCallback
1135
+ : T extends 'afterStartTransaction'
1136
+ ? NymphAfterStartTransactionCallback
1137
+ : T extends 'beforeCommitTransaction'
1138
+ ? NymphBeforeCommitTransactionCallback
1139
+ : T extends 'afterCommitTransaction'
1140
+ ? NymphAfterCommitTransactionCallback
1141
+ : T extends 'beforeRollbackTransaction'
1142
+ ? NymphBeforeRollbackTransactionCallback
1143
+ : T extends 'afterRollbackTransaction'
1144
+ ? NymphAfterRollbackTransactionCallback
884
1145
  : never
885
1146
  ) {
886
1147
  const prop = (event + 'Callbacks') as T extends 'connect'
@@ -897,30 +1158,56 @@ export default class Nymph {
897
1158
  ? 'beforeGetEntitiesCallbacks'
898
1159
  : T extends 'afterSaveEntity'
899
1160
  ? 'afterSaveEntityCallbacks'
1161
+ : T extends 'failedSaveEntity'
1162
+ ? 'failedSaveEntityCallbacks'
900
1163
  : T extends 'beforeDeleteEntity'
901
1164
  ? 'beforeDeleteEntityCallbacks'
902
1165
  : T extends 'afterDeleteEntity'
903
1166
  ? 'afterDeleteEntityCallbacks'
1167
+ : T extends 'failedDeleteEntity'
1168
+ ? 'failedDeleteEntityCallbacks'
904
1169
  : T extends 'beforeDeleteEntityByID'
905
1170
  ? 'beforeDeleteEntityByIDCallbacks'
906
1171
  : T extends 'afterDeleteEntityByID'
907
1172
  ? 'afterDeleteEntityByIDCallbacks'
1173
+ : T extends 'failedDeleteEntityByID'
1174
+ ? 'failedDeleteEntityByIDCallbacks'
908
1175
  : T extends 'beforeNewUID'
909
1176
  ? 'beforeNewUIDCallbacks'
910
1177
  : T extends 'afterNewUID'
911
1178
  ? 'afterNewUIDCallbacks'
1179
+ : T extends 'failedNewUID'
1180
+ ? 'failedNewUIDCallbacks'
912
1181
  : T extends 'beforeSetUID'
913
1182
  ? 'beforeSetUIDCallbacks'
914
1183
  : T extends 'afterSetUID'
915
1184
  ? 'afterSetUIDCallbacks'
1185
+ : T extends 'failedSetUID'
1186
+ ? 'failedSetUIDCallbacks'
916
1187
  : T extends 'beforeRenameUID'
917
1188
  ? 'beforeRenameUIDCallbacks'
918
1189
  : T extends 'afterRenameUID'
919
1190
  ? 'afterRenameUIDCallbacks'
1191
+ : T extends 'failedRenameUID'
1192
+ ? 'failedRenameUIDCallbacks'
920
1193
  : T extends 'beforeDeleteUID'
921
1194
  ? 'beforeDeleteUIDCallbacks'
922
1195
  : T extends 'afterDeleteUID'
923
1196
  ? 'afterDeleteUIDCallbacks'
1197
+ : T extends 'failedDeleteUID'
1198
+ ? 'failedDeleteUIDCallbacks'
1199
+ : T extends 'beforeStartTransaction'
1200
+ ? 'beforeStartTransactionCallbacks'
1201
+ : T extends 'afterStartTransaction'
1202
+ ? 'afterStartTransactionCallbacks'
1203
+ : T extends 'beforeCommitTransaction'
1204
+ ? 'beforeCommitTransactionCallbacks'
1205
+ : T extends 'afterCommitTransaction'
1206
+ ? 'afterCommitTransactionCallbacks'
1207
+ : T extends 'beforeRollbackTransaction'
1208
+ ? 'beforeRollbackTransactionCallbacks'
1209
+ : T extends 'afterRollbackTransaction'
1210
+ ? 'afterRollbackTransactionCallbacks'
924
1211
  : never;
925
1212
  if (!(prop in this)) {
926
1213
  return false;