@spinajs/orm 2.0.481 → 2.0.484

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 (228) hide show
  1. package/README.md +72 -3
  2. package/lib/cjs/bootstrap.js +10 -0
  3. package/lib/cjs/bootstrap.js.map +1 -1
  4. package/lib/cjs/builders.d.ts +127 -11
  5. package/lib/cjs/builders.d.ts.map +1 -1
  6. package/lib/cjs/builders.js +368 -283
  7. package/lib/cjs/builders.js.map +1 -1
  8. package/lib/cjs/converters.d.ts +9 -2
  9. package/lib/cjs/converters.d.ts.map +1 -1
  10. package/lib/cjs/converters.js +48 -8
  11. package/lib/cjs/converters.js.map +1 -1
  12. package/lib/cjs/decorators.d.ts +26 -3
  13. package/lib/cjs/decorators.d.ts.map +1 -1
  14. package/lib/cjs/decorators.js +95 -42
  15. package/lib/cjs/decorators.js.map +1 -1
  16. package/lib/cjs/dehydrators.js +1 -1
  17. package/lib/cjs/dehydrators.js.map +1 -1
  18. package/lib/cjs/descriptor.d.ts +1 -0
  19. package/lib/cjs/descriptor.d.ts.map +1 -1
  20. package/lib/cjs/descriptor.js +16 -40
  21. package/lib/cjs/descriptor.js.map +1 -1
  22. package/lib/cjs/driver.d.ts +136 -7
  23. package/lib/cjs/driver.d.ts.map +1 -1
  24. package/lib/cjs/driver.js +279 -0
  25. package/lib/cjs/driver.js.map +1 -1
  26. package/lib/cjs/existsRelationHandlers.d.ts +29 -0
  27. package/lib/cjs/existsRelationHandlers.d.ts.map +1 -0
  28. package/lib/cjs/existsRelationHandlers.js +138 -0
  29. package/lib/cjs/existsRelationHandlers.js.map +1 -0
  30. package/lib/cjs/fp.d.ts.map +1 -1
  31. package/lib/cjs/fp.js +10 -15
  32. package/lib/cjs/fp.js.map +1 -1
  33. package/lib/cjs/hydrators.d.ts.map +1 -1
  34. package/lib/cjs/hydrators.js +29 -2
  35. package/lib/cjs/hydrators.js.map +1 -1
  36. package/lib/cjs/identity-map.d.ts +60 -0
  37. package/lib/cjs/identity-map.d.ts.map +1 -0
  38. package/lib/cjs/identity-map.js +135 -0
  39. package/lib/cjs/identity-map.js.map +1 -0
  40. package/lib/cjs/index.d.ts +12 -0
  41. package/lib/cjs/index.d.ts.map +1 -1
  42. package/lib/cjs/index.js +12 -0
  43. package/lib/cjs/index.js.map +1 -1
  44. package/lib/cjs/interfaces.d.ts +300 -10
  45. package/lib/cjs/interfaces.d.ts.map +1 -1
  46. package/lib/cjs/interfaces.js +54 -1
  47. package/lib/cjs/interfaces.js.map +1 -1
  48. package/lib/cjs/metadata.d.ts.map +1 -1
  49. package/lib/cjs/metadata.js +4 -1
  50. package/lib/cjs/metadata.js.map +1 -1
  51. package/lib/cjs/metrics.d.ts +53 -0
  52. package/lib/cjs/metrics.d.ts.map +1 -0
  53. package/lib/cjs/metrics.js +82 -0
  54. package/lib/cjs/metrics.js.map +1 -0
  55. package/lib/cjs/middlewares.d.ts +13 -1
  56. package/lib/cjs/middlewares.d.ts.map +1 -1
  57. package/lib/cjs/middlewares.js +55 -15
  58. package/lib/cjs/middlewares.js.map +1 -1
  59. package/lib/cjs/model.d.ts +129 -13
  60. package/lib/cjs/model.d.ts.map +1 -1
  61. package/lib/cjs/model.js +449 -93
  62. package/lib/cjs/model.js.map +1 -1
  63. package/lib/cjs/orm.d.ts.map +1 -1
  64. package/lib/cjs/orm.js +12 -3
  65. package/lib/cjs/orm.js.map +1 -1
  66. package/lib/cjs/orphan.d.ts +27 -0
  67. package/lib/cjs/orphan.d.ts.map +1 -0
  68. package/lib/cjs/orphan.js +55 -0
  69. package/lib/cjs/orphan.js.map +1 -0
  70. package/lib/cjs/primary-keys.d.ts +60 -0
  71. package/lib/cjs/primary-keys.d.ts.map +1 -0
  72. package/lib/cjs/primary-keys.js +243 -0
  73. package/lib/cjs/primary-keys.js.map +1 -0
  74. package/lib/cjs/relation-objects.d.ts +101 -9
  75. package/lib/cjs/relation-objects.d.ts.map +1 -1
  76. package/lib/cjs/relation-objects.js +194 -43
  77. package/lib/cjs/relation-objects.js.map +1 -1
  78. package/lib/cjs/relations.d.ts +7 -1
  79. package/lib/cjs/relations.d.ts.map +1 -1
  80. package/lib/cjs/relations.js +16 -1
  81. package/lib/cjs/relations.js.map +1 -1
  82. package/lib/cjs/resilience.d.ts +50 -0
  83. package/lib/cjs/resilience.d.ts.map +1 -0
  84. package/lib/cjs/resilience.js +70 -0
  85. package/lib/cjs/resilience.js.map +1 -0
  86. package/lib/cjs/snapshot.d.ts +58 -0
  87. package/lib/cjs/snapshot.d.ts.map +1 -0
  88. package/lib/cjs/snapshot.js +125 -0
  89. package/lib/cjs/snapshot.js.map +1 -0
  90. package/lib/cjs/statements.d.ts +11 -1
  91. package/lib/cjs/statements.d.ts.map +1 -1
  92. package/lib/cjs/statements.js +13 -2
  93. package/lib/cjs/statements.js.map +1 -1
  94. package/lib/cjs/subject-builder.d.ts +79 -0
  95. package/lib/cjs/subject-builder.d.ts.map +1 -0
  96. package/lib/cjs/subject-builder.js +296 -0
  97. package/lib/cjs/subject-builder.js.map +1 -0
  98. package/lib/cjs/subject-executor.d.ts +122 -0
  99. package/lib/cjs/subject-executor.d.ts.map +1 -0
  100. package/lib/cjs/subject-executor.js +319 -0
  101. package/lib/cjs/subject-executor.js.map +1 -0
  102. package/lib/cjs/subject-sorter.d.ts +70 -0
  103. package/lib/cjs/subject-sorter.d.ts.map +1 -0
  104. package/lib/cjs/subject-sorter.js +173 -0
  105. package/lib/cjs/subject-sorter.js.map +1 -0
  106. package/lib/cjs/subject.d.ts +100 -0
  107. package/lib/cjs/subject.d.ts.map +1 -0
  108. package/lib/cjs/subject.js +89 -0
  109. package/lib/cjs/subject.js.map +1 -0
  110. package/lib/cjs/unit-of-work.d.ts +52 -0
  111. package/lib/cjs/unit-of-work.d.ts.map +1 -0
  112. package/lib/cjs/unit-of-work.js +170 -0
  113. package/lib/cjs/unit-of-work.js.map +1 -0
  114. package/lib/mjs/bootstrap.js +10 -0
  115. package/lib/mjs/bootstrap.js.map +1 -1
  116. package/lib/mjs/builders.d.ts +127 -11
  117. package/lib/mjs/builders.d.ts.map +1 -1
  118. package/lib/mjs/builders.js +370 -285
  119. package/lib/mjs/builders.js.map +1 -1
  120. package/lib/mjs/converters.d.ts +9 -2
  121. package/lib/mjs/converters.d.ts.map +1 -1
  122. package/lib/mjs/converters.js +48 -8
  123. package/lib/mjs/converters.js.map +1 -1
  124. package/lib/mjs/decorators.d.ts +26 -3
  125. package/lib/mjs/decorators.d.ts.map +1 -1
  126. package/lib/mjs/decorators.js +96 -44
  127. package/lib/mjs/decorators.js.map +1 -1
  128. package/lib/mjs/dehydrators.js +1 -1
  129. package/lib/mjs/dehydrators.js.map +1 -1
  130. package/lib/mjs/descriptor.d.ts +1 -0
  131. package/lib/mjs/descriptor.d.ts.map +1 -1
  132. package/lib/mjs/descriptor.js +17 -39
  133. package/lib/mjs/descriptor.js.map +1 -1
  134. package/lib/mjs/driver.d.ts +136 -7
  135. package/lib/mjs/driver.d.ts.map +1 -1
  136. package/lib/mjs/driver.js +279 -0
  137. package/lib/mjs/driver.js.map +1 -1
  138. package/lib/mjs/existsRelationHandlers.d.ts +29 -0
  139. package/lib/mjs/existsRelationHandlers.d.ts.map +1 -0
  140. package/lib/mjs/existsRelationHandlers.js +134 -0
  141. package/lib/mjs/existsRelationHandlers.js.map +1 -0
  142. package/lib/mjs/fp.d.ts.map +1 -1
  143. package/lib/mjs/fp.js +10 -15
  144. package/lib/mjs/fp.js.map +1 -1
  145. package/lib/mjs/hydrators.d.ts.map +1 -1
  146. package/lib/mjs/hydrators.js +29 -2
  147. package/lib/mjs/hydrators.js.map +1 -1
  148. package/lib/mjs/identity-map.d.ts +60 -0
  149. package/lib/mjs/identity-map.d.ts.map +1 -0
  150. package/lib/mjs/identity-map.js +130 -0
  151. package/lib/mjs/identity-map.js.map +1 -0
  152. package/lib/mjs/index.d.ts +12 -0
  153. package/lib/mjs/index.d.ts.map +1 -1
  154. package/lib/mjs/index.js +12 -0
  155. package/lib/mjs/index.js.map +1 -1
  156. package/lib/mjs/interfaces.d.ts +300 -10
  157. package/lib/mjs/interfaces.d.ts.map +1 -1
  158. package/lib/mjs/interfaces.js +53 -0
  159. package/lib/mjs/interfaces.js.map +1 -1
  160. package/lib/mjs/metadata.d.ts.map +1 -1
  161. package/lib/mjs/metadata.js +4 -1
  162. package/lib/mjs/metadata.js.map +1 -1
  163. package/lib/mjs/metrics.d.ts +53 -0
  164. package/lib/mjs/metrics.d.ts.map +1 -0
  165. package/lib/mjs/metrics.js +76 -0
  166. package/lib/mjs/metrics.js.map +1 -0
  167. package/lib/mjs/middlewares.d.ts +13 -1
  168. package/lib/mjs/middlewares.d.ts.map +1 -1
  169. package/lib/mjs/middlewares.js +55 -15
  170. package/lib/mjs/middlewares.js.map +1 -1
  171. package/lib/mjs/model.d.ts +129 -13
  172. package/lib/mjs/model.d.ts.map +1 -1
  173. package/lib/mjs/model.js +451 -95
  174. package/lib/mjs/model.js.map +1 -1
  175. package/lib/mjs/orm.d.ts.map +1 -1
  176. package/lib/mjs/orm.js +12 -3
  177. package/lib/mjs/orm.js.map +1 -1
  178. package/lib/mjs/orphan.d.ts +27 -0
  179. package/lib/mjs/orphan.d.ts.map +1 -0
  180. package/lib/mjs/orphan.js +52 -0
  181. package/lib/mjs/orphan.js.map +1 -0
  182. package/lib/mjs/primary-keys.d.ts +60 -0
  183. package/lib/mjs/primary-keys.d.ts.map +1 -0
  184. package/lib/mjs/primary-keys.js +223 -0
  185. package/lib/mjs/primary-keys.js.map +1 -0
  186. package/lib/mjs/relation-objects.d.ts +101 -9
  187. package/lib/mjs/relation-objects.d.ts.map +1 -1
  188. package/lib/mjs/relation-objects.js +194 -43
  189. package/lib/mjs/relation-objects.js.map +1 -1
  190. package/lib/mjs/relations.d.ts +7 -1
  191. package/lib/mjs/relations.d.ts.map +1 -1
  192. package/lib/mjs/relations.js +16 -1
  193. package/lib/mjs/relations.js.map +1 -1
  194. package/lib/mjs/resilience.d.ts +50 -0
  195. package/lib/mjs/resilience.d.ts.map +1 -0
  196. package/lib/mjs/resilience.js +64 -0
  197. package/lib/mjs/resilience.js.map +1 -0
  198. package/lib/mjs/snapshot.d.ts +58 -0
  199. package/lib/mjs/snapshot.d.ts.map +1 -0
  200. package/lib/mjs/snapshot.js +115 -0
  201. package/lib/mjs/snapshot.js.map +1 -0
  202. package/lib/mjs/statements.d.ts +11 -1
  203. package/lib/mjs/statements.d.ts.map +1 -1
  204. package/lib/mjs/statements.js +14 -3
  205. package/lib/mjs/statements.js.map +1 -1
  206. package/lib/mjs/subject-builder.d.ts +79 -0
  207. package/lib/mjs/subject-builder.d.ts.map +1 -0
  208. package/lib/mjs/subject-builder.js +292 -0
  209. package/lib/mjs/subject-builder.js.map +1 -0
  210. package/lib/mjs/subject-executor.d.ts +122 -0
  211. package/lib/mjs/subject-executor.d.ts.map +1 -0
  212. package/lib/mjs/subject-executor.js +312 -0
  213. package/lib/mjs/subject-executor.js.map +1 -0
  214. package/lib/mjs/subject-sorter.d.ts +70 -0
  215. package/lib/mjs/subject-sorter.d.ts.map +1 -0
  216. package/lib/mjs/subject-sorter.js +168 -0
  217. package/lib/mjs/subject-sorter.js.map +1 -0
  218. package/lib/mjs/subject.d.ts +100 -0
  219. package/lib/mjs/subject.d.ts.map +1 -0
  220. package/lib/mjs/subject.js +84 -0
  221. package/lib/mjs/subject.js.map +1 -0
  222. package/lib/mjs/unit-of-work.d.ts +52 -0
  223. package/lib/mjs/unit-of-work.d.ts.map +1 -0
  224. package/lib/mjs/unit-of-work.js +166 -0
  225. package/lib/mjs/unit-of-work.js.map +1 -0
  226. package/lib/tsconfig.cjs.tsbuildinfo +1 -1
  227. package/lib/tsconfig.mjs.tsbuildinfo +1 -1
  228. package/package.json +10 -7
@@ -0,0 +1,100 @@
1
+ import { IModelDescriptor, IRelationDescriptor, OrphanPolicy } from './interfaces.js';
2
+ import type { ModelBase } from './model.js';
3
+ /**
4
+ * What `save()` will do with one model instance.
5
+ *
6
+ * There is no `delete` member: every row `save()` removes is removed because it was detached
7
+ * from a relation, and that is carried by `IOrphanDelta` keyed by primary key rather than by
8
+ * a subject over a model instance the caller no longer holds.
9
+ */
10
+ export declare enum SubjectOperation {
11
+ Insert = "insert",
12
+ Update = "update",
13
+ None = "none"
14
+ }
15
+ /**
16
+ * A foreign-key column whose value is another model's primary key — which may not exist yet
17
+ * when the subject is built. Resolved by the executor immediately before the statement that
18
+ * needs it.
19
+ */
20
+ export interface IPendingForeignKey {
21
+ /** Column on this subject's own row that receives the key. */
22
+ Column: string;
23
+ /** Model whose primary key is the value. */
24
+ Target: ModelBase;
25
+ }
26
+ /**
27
+ * The membership change of one hasMany relation on one owner, as of the snapshot diff.
28
+ *
29
+ * `Added` are members with no snapshot ( never in the database ). `Kept` are members that
30
+ * were already there or were re-parented in from elsewhere. `RemovedKeys` are primary keys
31
+ * that were in the snapshot and are not in the array any more.
32
+ */
33
+ export interface IRelationDelta {
34
+ Descriptor: IRelationDescriptor;
35
+ Added: ModelBase[];
36
+ Kept: ModelBase[];
37
+ RemovedKeys: unknown[];
38
+ }
39
+ /**
40
+ * Junction rows to create and destroy for one manyToMany relation on one owner.
41
+ * `Added` holds target models because their keys may not exist yet; `RemovedKeys` holds
42
+ * plain keys because those models are gone from the array.
43
+ */
44
+ export interface IJunctionDelta {
45
+ Descriptor: IRelationDescriptor;
46
+ JunctionDescriptor: IModelDescriptor;
47
+ Owner: ModelBase;
48
+ Added: ModelBase[];
49
+ RemovedKeys: unknown[];
50
+ }
51
+ /**
52
+ * Rows detached from a relation and the policy that decides their fate.
53
+ */
54
+ export interface IOrphanDelta {
55
+ Descriptor: IRelationDescriptor;
56
+ TargetDescriptor: IModelDescriptor;
57
+ Policy: OrphanPolicy;
58
+ PrimaryKeys: unknown[];
59
+ }
60
+ /**
61
+ * One model instance and everything `save()` needs to know about it.
62
+ */
63
+ export declare class Subject {
64
+ readonly Model: ModelBase;
65
+ readonly Descriptor: IModelDescriptor;
66
+ Operation: SubjectOperation;
67
+ /** Columns that differ from the snapshot. Empty for an insert, which writes everything. */
68
+ ChangedColumns: string[];
69
+ /** Foreign keys resolved just before this subject's own statement runs. */
70
+ PendingForeignKeys: IPendingForeignKey[];
71
+ /**
72
+ * Foreign keys that cannot be resolved before this subject's INSERT — a self-referencing
73
+ * cycle — and are applied by a follow-up UPDATE in the update phase instead.
74
+ */
75
+ DeferredForeignKeys: IPendingForeignKey[];
76
+ /** hasMany membership changes owned by this subject. Read by the orphan resolver. */
77
+ RelationDeltas: IRelationDelta[];
78
+ /** `Model#key`, or `Model#<new>` before the key exists. Diagnostics only — never a map key. */
79
+ get Identity(): string;
80
+ constructor(Model: ModelBase, Descriptor: IModelDescriptor, Operation: SubjectOperation);
81
+ }
82
+ /**
83
+ * Everything one `save()` will do, before ordering.
84
+ */
85
+ export declare class SubjectSet {
86
+ readonly Subjects: Subject[];
87
+ readonly Junctions: IJunctionDelta[];
88
+ readonly Orphans: IOrphanDelta[];
89
+ private _byModel;
90
+ /**
91
+ * Registers `subject`, or returns the one already registered for the same model instance.
92
+ * Instance identity is the key — canonicalizing two instances of one row is the identity
93
+ * map's job, and it runs first.
94
+ */
95
+ add(subject: Subject): Subject;
96
+ find(model: ModelBase): Subject | undefined;
97
+ /** True when this set would emit no statements at all. */
98
+ get IsEmpty(): boolean;
99
+ }
100
+ //# sourceMappingURL=subject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subject.d.ts","sourceRoot":"","sources":["../../src/subject.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACtF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;GAMG;AACH,oBAAY,gBAAgB;IAC1B,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB,IAAI,SAAS;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,MAAM,EAAE,SAAS,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,mBAAmB,CAAC;IAChC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,WAAW,EAAE,OAAO,EAAE,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,mBAAmB,CAAC;IAChC,kBAAkB,EAAE,gBAAgB,CAAC;IACrC,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,WAAW,EAAE,OAAO,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,mBAAmB,CAAC;IAChC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,OAAO,EAAE,CAAC;CACxB;AAkBD;;GAEG;AACH,qBAAa,OAAO;aAqBU,KAAK,EAAE,SAAS;aAAkB,UAAU,EAAE,gBAAgB;IAAS,SAAS,EAAE,gBAAgB;IApB9H,2FAA2F;IACpF,cAAc,EAAE,MAAM,EAAE,CAAM;IAErC,2EAA2E;IACpE,kBAAkB,EAAE,kBAAkB,EAAE,CAAM;IAErD;;;OAGG;IACI,mBAAmB,EAAE,kBAAkB,EAAE,CAAM;IAEtD,qFAAqF;IAC9E,cAAc,EAAE,cAAc,EAAE,CAAM;IAE7C,+FAA+F;IAC/F,IAAW,QAAQ,IAAI,MAAM,CAE5B;gBAE2B,KAAK,EAAE,SAAS,EAAkB,UAAU,EAAE,gBAAgB,EAAS,SAAS,EAAE,gBAAgB;CAC/H;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,SAAgB,QAAQ,EAAE,OAAO,EAAE,CAAM;IACzC,SAAgB,SAAS,EAAE,cAAc,EAAE,CAAM;IACjD,SAAgB,OAAO,EAAE,YAAY,EAAE,CAAM;IAE7C,OAAO,CAAC,QAAQ,CAAiC;IAEjD;;;;OAIG;IACI,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAY9B,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS;IAIlD,0DAA0D;IAC1D,IAAW,OAAO,IAAI,OAAO,CAE5B;CACF"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SubjectSet = exports.Subject = exports.SubjectOperation = void 0;
4
+ /**
5
+ * What `save()` will do with one model instance.
6
+ *
7
+ * There is no `delete` member: every row `save()` removes is removed because it was detached
8
+ * from a relation, and that is carried by `IOrphanDelta` keyed by primary key rather than by
9
+ * a subject over a model instance the caller no longer holds.
10
+ */
11
+ var SubjectOperation;
12
+ (function (SubjectOperation) {
13
+ SubjectOperation["Insert"] = "insert";
14
+ SubjectOperation["Update"] = "update";
15
+ SubjectOperation["None"] = "none";
16
+ })(SubjectOperation || (exports.SubjectOperation = SubjectOperation = {}));
17
+ /**
18
+ * Renders a primary key for a diagnostic message. A composite key arrives as a tuple; a key
19
+ * with any part missing is not a key at all and reads as `<new>`, the same as an absent one.
20
+ */
21
+ function describeKey(pk) {
22
+ if (pk === null || pk === undefined) {
23
+ return '<new>';
24
+ }
25
+ if (Array.isArray(pk)) {
26
+ return pk.some((p) => p === null || p === undefined) ? '<new>' : pk.map((p) => String(p)).join(',');
27
+ }
28
+ return String(pk);
29
+ }
30
+ /**
31
+ * One model instance and everything `save()` needs to know about it.
32
+ */
33
+ class Subject {
34
+ /** `Model#key`, or `Model#<new>` before the key exists. Diagnostics only — never a map key. */
35
+ get Identity() {
36
+ return `${this.Descriptor.Name}#${describeKey(this.Model.PrimaryKeyValue)}`;
37
+ }
38
+ constructor(Model, Descriptor, Operation) {
39
+ this.Model = Model;
40
+ this.Descriptor = Descriptor;
41
+ this.Operation = Operation;
42
+ /** Columns that differ from the snapshot. Empty for an insert, which writes everything. */
43
+ this.ChangedColumns = [];
44
+ /** Foreign keys resolved just before this subject's own statement runs. */
45
+ this.PendingForeignKeys = [];
46
+ /**
47
+ * Foreign keys that cannot be resolved before this subject's INSERT — a self-referencing
48
+ * cycle — and are applied by a follow-up UPDATE in the update phase instead.
49
+ */
50
+ this.DeferredForeignKeys = [];
51
+ /** hasMany membership changes owned by this subject. Read by the orphan resolver. */
52
+ this.RelationDeltas = [];
53
+ }
54
+ }
55
+ exports.Subject = Subject;
56
+ /**
57
+ * Everything one `save()` will do, before ordering.
58
+ */
59
+ class SubjectSet {
60
+ constructor() {
61
+ this.Subjects = [];
62
+ this.Junctions = [];
63
+ this.Orphans = [];
64
+ this._byModel = new Map();
65
+ }
66
+ /**
67
+ * Registers `subject`, or returns the one already registered for the same model instance.
68
+ * Instance identity is the key — canonicalizing two instances of one row is the identity
69
+ * map's job, and it runs first.
70
+ */
71
+ add(subject) {
72
+ const existing = this._byModel.get(subject.Model);
73
+ if (existing) {
74
+ return existing;
75
+ }
76
+ this._byModel.set(subject.Model, subject);
77
+ this.Subjects.push(subject);
78
+ return subject;
79
+ }
80
+ find(model) {
81
+ return this._byModel.get(model);
82
+ }
83
+ /** True when this set would emit no statements at all. */
84
+ get IsEmpty() {
85
+ return this.Junctions.length === 0 && this.Orphans.length === 0 && this.Subjects.every((s) => s.Operation === SubjectOperation.None);
86
+ }
87
+ }
88
+ exports.SubjectSet = SubjectSet;
89
+ //# sourceMappingURL=subject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subject.js","sourceRoot":"","sources":["../../src/subject.ts"],"names":[],"mappings":";;;AAIA;;;;;;GAMG;AACH,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,qCAAiB,CAAA;IACjB,qCAAiB,CAAA;IACjB,iCAAa,CAAA;AACf,CAAC,EAJW,gBAAgB,gCAAhB,gBAAgB,QAI3B;AAmDD;;;GAGG;AACH,SAAS,WAAW,CAAC,EAAW;IAC9B,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtG,CAAC;IAED,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAa,OAAO;IAgBlB,+FAA+F;IAC/F,IAAW,QAAQ;QACjB,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;IAC9E,CAAC;IAED,YAA4B,KAAgB,EAAkB,UAA4B,EAAS,SAA2B;QAAlG,UAAK,GAAL,KAAK,CAAW;QAAkB,eAAU,GAAV,UAAU,CAAkB;QAAS,cAAS,GAAT,SAAS,CAAkB;QApB9H,2FAA2F;QACpF,mBAAc,GAAa,EAAE,CAAC;QAErC,2EAA2E;QACpE,uBAAkB,GAAyB,EAAE,CAAC;QAErD;;;WAGG;QACI,wBAAmB,GAAyB,EAAE,CAAC;QAEtD,qFAAqF;QAC9E,mBAAc,GAAqB,EAAE,CAAC;IAOoF,CAAC;CACnI;AAtBD,0BAsBC;AAED;;GAEG;AACH,MAAa,UAAU;IAAvB;QACkB,aAAQ,GAAc,EAAE,CAAC;QACzB,cAAS,GAAqB,EAAE,CAAC;QACjC,YAAO,GAAmB,EAAE,CAAC;QAErC,aAAQ,GAAG,IAAI,GAAG,EAAsB,CAAC;IA2BnD,CAAC;IAzBC;;;;OAIG;IACI,GAAG,CAAC,OAAgB;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAE5B,OAAO,OAAO,CAAC;IACjB,CAAC;IAEM,IAAI,CAAC,KAAgB;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,0DAA0D;IAC1D,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACvI,CAAC;CACF;AAhCD,gCAgCC"}
@@ -0,0 +1,52 @@
1
+ import { OrmDriver } from './driver.js';
2
+ import { IIdentityMap, IModelDescriptor, ISaveOptions, ISaveResult } from './interfaces.js';
3
+ import type { ModelBase } from './model.js';
4
+ /**
5
+ * The `save()` entry point: one transaction, one identity map, one ordered plan.
6
+ */
7
+ export declare class UnitOfWork {
8
+ /**
9
+ * Persists everything reachable from `root` atomically.
10
+ *
11
+ * @param root - the model `save()` was called on
12
+ * @param options - `reload` to diff against current database state; `chunk` to bound the row
13
+ * count of the statements that ARE batched — junction inserts and the key lists of
14
+ * orphan statements. It does not apply to model inserts: those run one statement per
15
+ * row so each generated key can be read back exactly. See {@link ISaveOptions}.
16
+ */
17
+ static save(root: ModelBase, options?: ISaveOptions): Promise<ISaveResult>;
18
+ /**
19
+ * The identity map for this save. Reused across saves inside one transaction so a row
20
+ * touched by two of them is still one object; created fresh otherwise. Nothing survives
21
+ * the transaction ( decision D7 ).
22
+ */
23
+ protected static identityMapFor(driver: OrmDriver): IIdentityMap;
24
+ /**
25
+ * A graph spanning two connections cannot be persisted atomically — the transaction only
26
+ * covers one of them. Fail loudly rather than commit half of it.
27
+ */
28
+ protected static assertSingleConnection(models: ModelBase[], root: IModelDescriptor): void;
29
+ /**
30
+ * Re-reads every already-persisted model's row and rebases it on the database's current
31
+ * values, batched one SELECT per model class.
32
+ *
33
+ * This is a three-way merge between the hydration baseline, the model, and the row as it
34
+ * stands now. A column the caller edited keeps the caller's value and is rebased so it is
35
+ * written; a column the caller did not touch is reset to the current database value on the
36
+ * model *and* in the baseline, so it drops out of the diff and is not written at all.
37
+ *
38
+ * Moving only the baseline would do the exact opposite of the intent: the model would still
39
+ * hold the stale hydration value, the diff would report `current -> stale`, and the UPDATE
40
+ * would clobber whatever another process wrote. The model has to move too.
41
+ *
42
+ * This is a last-write-wins rebase, not conflict detection: two callers editing the same
43
+ * column still race, and neither is told.
44
+ */
45
+ protected static reloadSnapshots(models: ModelBase[]): Promise<void>;
46
+ /**
47
+ * Re-records every populated relation's member keys after a successful save, so a second
48
+ * `save()` on the same graph sees no membership change and emits nothing.
49
+ */
50
+ protected static resnapshotRelations(models: ModelBase[]): void;
51
+ }
52
+ //# sourceMappingURL=unit-of-work.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unit-of-work.d.ts","sourceRoot":"","sources":["../../src/unit-of-work.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAgB,MAAM,iBAAiB,CAAC;AAC1G,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAO5C;;GAEG;AACH,qBAAa,UAAU;IACrB;;;;;;;;OAQG;WACiB,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAkCvF;;;;OAIG;IACH,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,YAAY;IAchE;;;OAGG;IACH,SAAS,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAU1F;;;;;;;;;;;;;;;OAeG;qBACoB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgE1E;;;OAGG;IACH,SAAS,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI;CAqBhE"}
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UnitOfWork = void 0;
4
+ /* eslint-disable prettier/prettier */
5
+ const di_1 = require("@spinajs/di");
6
+ const builders_js_1 = require("./builders.js");
7
+ const descriptor_js_1 = require("./descriptor.js");
8
+ const exceptions_js_1 = require("./exceptions.js");
9
+ const identity_map_js_1 = require("./identity-map.js");
10
+ const interfaces_js_1 = require("./interfaces.js");
11
+ const primary_keys_js_1 = require("./primary-keys.js");
12
+ const snapshot_js_1 = require("./snapshot.js");
13
+ const subject_builder_js_1 = require("./subject-builder.js");
14
+ const subject_executor_js_1 = require("./subject-executor.js");
15
+ const subject_sorter_js_1 = require("./subject-sorter.js");
16
+ /**
17
+ * The `save()` entry point: one transaction, one identity map, one ordered plan.
18
+ */
19
+ class UnitOfWork {
20
+ /**
21
+ * Persists everything reachable from `root` atomically.
22
+ *
23
+ * @param root - the model `save()` was called on
24
+ * @param options - `reload` to diff against current database state; `chunk` to bound the row
25
+ * count of the statements that ARE batched — junction inserts and the key lists of
26
+ * orphan statements. It does not apply to model inserts: those run one statement per
27
+ * row so each generated key can be read back exactly. See {@link ISaveOptions}.
28
+ */
29
+ static async save(root, options) {
30
+ const descriptor = (0, descriptor_js_1.extractModelDescriptor)(root.constructor);
31
+ if (!descriptor) {
32
+ throw new exceptions_js_1.OrmException(`model ${root.constructor.name} has no descriptor, use the @Model decorator`);
33
+ }
34
+ const driver = di_1.DI.resolve('OrmConnection', [descriptor.Connection]);
35
+ if (!driver) {
36
+ throw new exceptions_js_1.OrmException(`model ${descriptor.Name} has invalid connection ${descriptor.Connection}`);
37
+ }
38
+ return await driver.transaction(async () => {
39
+ const identityMap = UnitOfWork.identityMapFor(driver);
40
+ const builder = new subject_builder_js_1.SubjectBuilder(identityMap);
41
+ const models = builder.collect(root);
42
+ UnitOfWork.assertSingleConnection(models, descriptor);
43
+ if (options?.reload) {
44
+ await UnitOfWork.reloadSnapshots(models);
45
+ }
46
+ const set = builder.buildFrom(models);
47
+ const plan = new subject_sorter_js_1.SubjectSorter().sort(set);
48
+ const result = await new subject_executor_js_1.SubjectExecutor(options ?? {}).execute(plan);
49
+ UnitOfWork.resnapshotRelations(models);
50
+ return result;
51
+ });
52
+ }
53
+ /**
54
+ * The identity map for this save. Reused across saves inside one transaction so a row
55
+ * touched by two of them is still one object; created fresh otherwise. Nothing survives
56
+ * the transaction ( decision D7 ).
57
+ */
58
+ static identityMapFor(driver) {
59
+ const ctx = driver.CurrentTransaction;
60
+ if (!ctx) {
61
+ return new identity_map_js_1.IdentityMap();
62
+ }
63
+ if (!ctx.IdentityMap) {
64
+ ctx.IdentityMap = new identity_map_js_1.IdentityMap();
65
+ }
66
+ return ctx.IdentityMap;
67
+ }
68
+ /**
69
+ * A graph spanning two connections cannot be persisted atomically — the transaction only
70
+ * covers one of them. Fail loudly rather than commit half of it.
71
+ */
72
+ static assertSingleConnection(models, root) {
73
+ for (const model of models) {
74
+ const descriptor = (0, descriptor_js_1.extractModelDescriptor)(model.constructor);
75
+ if (descriptor && descriptor.Connection !== root.Connection) {
76
+ throw new exceptions_js_1.OrmException(`save() cannot span connections: ${root.Name} is on connection ${root.Connection} but ${descriptor.Name} is on ${descriptor.Connection}. Save each connection's graph separately.`);
77
+ }
78
+ }
79
+ }
80
+ /**
81
+ * Re-reads every already-persisted model's row and rebases it on the database's current
82
+ * values, batched one SELECT per model class.
83
+ *
84
+ * This is a three-way merge between the hydration baseline, the model, and the row as it
85
+ * stands now. A column the caller edited keeps the caller's value and is rebased so it is
86
+ * written; a column the caller did not touch is reset to the current database value on the
87
+ * model *and* in the baseline, so it drops out of the diff and is not written at all.
88
+ *
89
+ * Moving only the baseline would do the exact opposite of the intent: the model would still
90
+ * hold the stale hydration value, the diff would report `current -> stale`, and the UPDATE
91
+ * would clobber whatever another process wrote. The model has to move too.
92
+ *
93
+ * This is a last-write-wins rebase, not conflict detection: two callers editing the same
94
+ * column still race, and neither is told.
95
+ */
96
+ static async reloadSnapshots(models) {
97
+ const byConstructor = new Map();
98
+ for (const model of models) {
99
+ // A composite key is a tuple, and a tuple is ALWAYS truthy — check every part.
100
+ const pk = model.PrimaryKeyValue;
101
+ const missing = Array.isArray(pk) ? pk.some((v) => v === null || v === undefined) : pk === null || pk === undefined;
102
+ if (model.Snapshot === null || missing) {
103
+ continue;
104
+ }
105
+ const ctor = model.constructor;
106
+ const list = byConstructor.get(ctor) ?? [];
107
+ list.push(model);
108
+ byConstructor.set(ctor, list);
109
+ }
110
+ for (const [ctor, group] of byConstructor) {
111
+ const descriptor = (0, descriptor_js_1.extractModelDescriptor)(ctor);
112
+ const { query } = (0, builders_js_1.createQuery)(ctor, builders_js_1.SelectQueryBuilder);
113
+ const select = query.select('*');
114
+ (0, primary_keys_js_1.whereAnyPk)(select, descriptor, group.map((m) => m.PrimaryKeyValue));
115
+ const fresh = (await select.asRaw());
116
+ // Index by the flattened key so a composite key matches without a nested scan.
117
+ const byKey = new Map();
118
+ for (const row of fresh) {
119
+ byKey.set((0, primary_keys_js_1.pkKeyString)(row, descriptor), row);
120
+ }
121
+ for (const model of group) {
122
+ const row = byKey.get((0, primary_keys_js_1.pkKeyString)(model, descriptor));
123
+ if (!row) {
124
+ // The row is gone. Clearing the snapshot reclassifies the model as an INSERT,
125
+ // which re-creates it rather than emitting an UPDATE that matches nothing.
126
+ model.clearSnapshot();
127
+ continue;
128
+ }
129
+ const baseline = model.Snapshot.Columns;
130
+ const current = (0, snapshot_js_1.snapshotFromRow)(descriptor, row);
131
+ const converterOf = new Map((descriptor.Columns ?? []).map((c) => [c.Name, c.Converter]));
132
+ for (const [name, value] of current) {
133
+ // eslint-disable-next-line security/detect-object-injection
134
+ const callerEdited = !(0, snapshot_js_1.snapshotEquals)(baseline.get(name), model[name], converterOf.get(name));
135
+ if (!callerEdited) {
136
+ // Untouched by this caller: adopt the database's value so it is neither written
137
+ // back stale nor reported as a change.
138
+ // eslint-disable-next-line security/detect-object-injection
139
+ model[name] = value;
140
+ }
141
+ baseline.set(name, value);
142
+ }
143
+ }
144
+ }
145
+ }
146
+ /**
147
+ * Re-records every populated relation's member keys after a successful save, so a second
148
+ * `save()` on the same graph sees no membership change and emits nothing.
149
+ */
150
+ static resnapshotRelations(models) {
151
+ for (const model of models) {
152
+ const descriptor = (0, descriptor_js_1.extractModelDescriptor)(model.constructor);
153
+ if (!descriptor) {
154
+ continue;
155
+ }
156
+ for (const [name, relation] of descriptor.Relations) {
157
+ if (relation.Type === interfaces_js_1.RelationType.Query || relation.Type === interfaces_js_1.RelationType.Virtual) {
158
+ continue;
159
+ }
160
+ // eslint-disable-next-line security/detect-object-injection
161
+ const rel = model[name];
162
+ if (rel?.Populated === true || (relation.Type === interfaces_js_1.RelationType.One && rel?.Value)) {
163
+ model.snapshotRelation(name);
164
+ }
165
+ }
166
+ }
167
+ }
168
+ }
169
+ exports.UnitOfWork = UnitOfWork;
170
+ //# sourceMappingURL=unit-of-work.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unit-of-work.js","sourceRoot":"","sources":["../../src/unit-of-work.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,15 @@
1
1
  import { DI } from '@spinajs/di';
2
2
  import { ManyToManyRelationList, OneToManyRelationList } from './relation-objects.js';
3
+ /**
4
+ * Pool telemetry needs no registration: the ORM publishes into the `Metrics` singleton from
5
+ * `@spinajs/telemetry-common`, which self-registers via its own `@Injectable()` and owns a private
6
+ * prom-client registry. `@spinajs/telemetry` re-exports that very class, so its `/metrics`
7
+ * endpoint renders the same registry the ORM writes to.
8
+ *
9
+ * The dependency runs orm -> telemetry-common and never orm -> telemetry: the latter pulls in
10
+ * `@spinajs/http`, and putting the HTTP stack underneath every database connection inverts the
11
+ * graph. Same reason `configuration-common` and `log-common` exist.
12
+ */
3
13
  /**
4
14
  * Register default relation type factory
5
15
  * for hasMany & hasManyToMany
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,EAAE,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEtF;;;;;;;;;GASG;AACH,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAY,EAAE,IAA0B,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,mCAAmC,CAAC,CAAC;AAC3K,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAY,EAAE,IAA0B,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,2CAA2C,CAAC,CAAC"}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,EAAE,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEtF;;;;;;;;;GASG;AAEH;;;;;;;;;GASG;AACH,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAY,EAAE,IAA0B,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,mCAAmC,CAAC,CAAC;AAC3K,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAY,EAAE,IAA0B,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,2CAA2C,CAAC,CAAC"}