@nymphjs/nymph 1.0.0-beta.120 → 1.0.0-beta.122

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 (54) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +12 -4
  3. package/dist/Entity.d.ts +4 -3
  4. package/dist/Entity.js +33 -6
  5. package/dist/Entity.js.map +1 -1
  6. package/dist/Entity.test.js +19 -12
  7. package/dist/Entity.test.js.map +1 -1
  8. package/dist/Entity.types.d.ts +19 -15
  9. package/dist/decorators/index.d.ts +1 -0
  10. package/dist/decorators/index.js +2 -0
  11. package/dist/decorators/index.js.map +1 -0
  12. package/dist/decorators/transactional.d.ts +12 -0
  13. package/dist/decorators/transactional.js +45 -0
  14. package/dist/decorators/transactional.js.map +1 -0
  15. package/dist/driver/NymphDriver.js +14 -6
  16. package/dist/driver/NymphDriver.js.map +1 -1
  17. package/dist/driver/testArtifacts.d.ts +3 -3
  18. package/dist/driver/testArtifacts.js +1818 -1723
  19. package/dist/driver/testArtifacts.js.map +1 -1
  20. package/dist/errors/MethodFailedError.d.ts +3 -0
  21. package/dist/errors/MethodFailedError.js +7 -0
  22. package/dist/errors/MethodFailedError.js.map +1 -0
  23. package/dist/errors/index.d.ts +1 -0
  24. package/dist/errors/index.js +1 -0
  25. package/dist/errors/index.js.map +1 -1
  26. package/dist/helpers/index.d.ts +1 -0
  27. package/dist/helpers/index.js +2 -0
  28. package/dist/helpers/index.js.map +1 -0
  29. package/dist/helpers/transaction.d.ts +15 -0
  30. package/dist/helpers/transaction.js +47 -0
  31. package/dist/helpers/transaction.js.map +1 -0
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.js +2 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/testArtifacts.d.ts +2 -0
  36. package/dist/testArtifacts.js +113 -34
  37. package/dist/testArtifacts.js.map +1 -1
  38. package/dist/testMocks.js +2 -2
  39. package/dist/testMocks.js.map +1 -1
  40. package/package.json +14 -5
  41. package/src/Entity.test.ts +19 -12
  42. package/src/Entity.ts +34 -9
  43. package/src/Entity.types.ts +19 -15
  44. package/src/decorators/index.ts +1 -0
  45. package/src/decorators/transactional.ts +63 -0
  46. package/src/driver/NymphDriver.ts +18 -6
  47. package/src/driver/testArtifacts.ts +2447 -2317
  48. package/src/errors/MethodFailedError.ts +6 -0
  49. package/src/errors/index.ts +2 -0
  50. package/src/helpers/index.ts +1 -0
  51. package/src/helpers/transaction.ts +65 -0
  52. package/src/index.ts +2 -0
  53. package/src/testArtifacts.ts +49 -0
  54. package/src/testMocks.ts +4 -2
@@ -0,0 +1,6 @@
1
+ export class MethodFailedError extends Error {
2
+ constructor(message: string) {
3
+ super(message);
4
+ this.name = 'MethodFailedError';
5
+ }
6
+ }
@@ -14,6 +14,8 @@ export * from './InvalidParametersError.js';
14
14
 
15
15
  export * from './InvalidStateError.js';
16
16
 
17
+ export * from './MethodFailedError.js';
18
+
17
19
  export * from './NotConfiguredError.js';
18
20
 
19
21
  export * from './QueryFailedError.js';
@@ -0,0 +1 @@
1
+ export * from './transaction.js';
@@ -0,0 +1,65 @@
1
+ import Nymph from '../Nymph.js';
2
+
3
+ /**
4
+ * Run a function inside of a transaction.
5
+ *
6
+ * @param nymph The instance of Nymph to start the transaction on.
7
+ * @param name The name of the transaction.
8
+ * @param fn The function that runs inside the transaction. It is passed the
9
+ * transactional instance of Nymph. If it resolves, the transaction is
10
+ * committed, and if it throws, the transaction is rolled back.
11
+ * @param finallyFn An optional function to run after the transaction is
12
+ * committed or rolled back. It is passed the original instance
13
+ * of Nymph. It SHOULD NOT throw.
14
+ * @returns The return value of the function.
15
+ */
16
+ export async function transaction<T>(
17
+ nymph: Nymph,
18
+ name: string,
19
+ fn: (nymph: Nymph) => Promise<T>,
20
+ finallyFn?: (nymph: Nymph) => Promise<void>,
21
+ ): Promise<T> {
22
+ nymph.config.debugInfo('nymph:transaction', `Starting transaction ${name}`);
23
+ const tnymph = await nymph.startTransaction(name);
24
+ try {
25
+ const result = await fn(tnymph);
26
+
27
+ nymph.config.debugInfo(
28
+ 'nymph:transaction',
29
+ `Committing transaction ${name}`,
30
+ );
31
+ if (!(await tnymph.commit(name))) {
32
+ throw new Error('Transaction could not be committed.');
33
+ }
34
+
35
+ if (finallyFn) {
36
+ await finallyFn(nymph);
37
+ }
38
+
39
+ return result;
40
+ } catch (e: any) {
41
+ try {
42
+ nymph.config.debugInfo(
43
+ 'nymph:transaction',
44
+ `Rolling back transaction ${name}, reason: ${e.message}`,
45
+ );
46
+ await tnymph.rollback(name);
47
+ } catch (e: any) {
48
+ nymph.config.debugError(
49
+ 'nymph:transaction',
50
+ `Rollback of transaction ${name} failed, reason: ${e.message}`,
51
+ );
52
+ }
53
+ if (finallyFn) {
54
+ try {
55
+ await finallyFn(nymph);
56
+ } catch (e: any) {
57
+ nymph.config.debugError(
58
+ 'nymph:transaction',
59
+ `Finally function of transaction ${name} threw error: ${e.message}, this is a mistake and should be fixed, finally functions should never throw`,
60
+ );
61
+ }
62
+ }
63
+ throw e;
64
+ }
65
+ }
package/src/index.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export * from './conf/index.js';
2
2
  export * from './driver/index.js';
3
3
  export * from './errors/index.js';
4
+ export * from './decorators/index.js';
5
+ export * from './helpers/index.js';
4
6
 
5
7
  export * from './Entity.types.js';
6
8
 
@@ -1,4 +1,6 @@
1
1
  import Entity from './Entity.js';
2
+ import { transactional } from './decorators/index.js';
3
+ import { transaction } from './helpers/index.js';
2
4
 
3
5
  export type TestModelData = {
4
6
  name?: string;
@@ -67,6 +69,53 @@ export class TestModel extends Entity<TestModelData> {
67
69
  this.$protectedTags = $protectedTags;
68
70
  };
69
71
  }
72
+
73
+ @transactional
74
+ public async $testTransactionalDecorator(throwError: boolean) {
75
+ this.$data.string = 'this has been changed';
76
+
77
+ if (this.$data.reference) {
78
+ await this.$data.reference.$wake();
79
+ this.$data.reference.string = 'this has been changed too';
80
+ await this.$data.reference.$save();
81
+ }
82
+
83
+ await this.$save();
84
+
85
+ if (throwError) {
86
+ throw Error('An error.');
87
+ }
88
+
89
+ return 'Success.';
90
+ }
91
+
92
+ public async $testTransactionHelper(throwError: boolean) {
93
+ return await transaction(
94
+ this.$nymph,
95
+ 'test-transaction',
96
+ async (nymph) => {
97
+ this.$setNymph(nymph);
98
+ this.$data.string = 'this has been changed';
99
+
100
+ if (this.$data.reference) {
101
+ await this.$data.reference.$wake();
102
+ this.$data.reference.string = 'this has been changed too';
103
+ await this.$data.reference.$save();
104
+ }
105
+
106
+ await this.$save();
107
+
108
+ if (throwError) {
109
+ throw Error('An error.');
110
+ }
111
+
112
+ return 'Success.';
113
+ },
114
+ async (nymph) => {
115
+ this.$setNymph(nymph);
116
+ },
117
+ );
118
+ }
70
119
  }
71
120
 
72
121
  /**
package/src/testMocks.ts CHANGED
@@ -8,7 +8,7 @@ import type {
8
8
  EntityJson,
9
9
  } from './Entity.types.js';
10
10
  import { Options, Selector } from './Nymph.types.js';
11
- import { ClassNotAvailableError } from './errors/index.js';
11
+ import { ClassNotAvailableError, EntityConflictError } from './errors/index.js';
12
12
  import Entity from './Entity.js';
13
13
 
14
14
  const entities: { [k: string]: EntityJson } = {};
@@ -163,7 +163,9 @@ export class MockNymph {
163
163
  entity.guid in entities &&
164
164
  (entity.mdate ?? 0) < (entities[entity.guid].mdate ?? 0)
165
165
  ) {
166
- return false;
166
+ throw new EntityConflictError(
167
+ "Entity either doesn't exist or is newer in the DB.",
168
+ );
167
169
  }
168
170
 
169
171
  entity.mdate = Date.now();