joist-test-utils 2.3.0-next.7 → 2.3.0-next.71
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/build/RunPlugin.cjs +219 -0
- package/build/RunPlugin.cjs.map +1 -0
- package/build/RunPlugin.d.cts +12 -0
- package/build/RunPlugin.d.cts.map +1 -0
- package/build/RunPlugin.d.mts +12 -0
- package/build/RunPlugin.d.mts.map +1 -0
- package/build/RunPlugin.js +203 -341
- package/build/RunPlugin.js.map +1 -1
- package/build/_virtual/_rolldown/runtime.cjs +23 -0
- package/build/context.cjs +2 -0
- package/build/context.d.cts +9 -0
- package/build/context.d.cts.map +1 -0
- package/build/context.d.mts +9 -0
- package/build/context.d.mts.map +1 -0
- package/build/context.js +2 -3
- package/build/index.cjs +38 -0
- package/build/index.cjs.map +1 -0
- package/build/index.d.cts +52 -0
- package/build/index.d.cts.map +1 -0
- package/build/index.d.mts +52 -0
- package/build/index.d.mts.map +1 -0
- package/build/index.js +25 -41
- package/build/index.js.map +1 -1
- package/build/run.cjs +77 -0
- package/build/run.cjs.map +1 -0
- package/build/run.d.cts +17 -0
- package/build/run.d.cts.map +1 -0
- package/build/run.d.mts +17 -0
- package/build/run.d.mts.map +1 -0
- package/build/run.js +52 -76
- package/build/run.js.map +1 -1
- package/build/seed.cjs +54 -0
- package/build/seed.cjs.map +1 -0
- package/build/{seed.d.ts → seed.d.cts} +9 -6
- package/build/seed.d.cts.map +1 -0
- package/build/seed.d.mts +35 -0
- package/build/seed.d.mts.map +1 -0
- package/build/seed.js +47 -53
- package/build/seed.js.map +1 -1
- package/build/toMatchEntity.cjs +94 -0
- package/build/toMatchEntity.cjs.map +1 -0
- package/build/toMatchEntity.d.cts +28 -0
- package/build/toMatchEntity.d.cts.map +1 -0
- package/build/toMatchEntity.d.mts +28 -0
- package/build/toMatchEntity.d.mts.map +1 -0
- package/build/toMatchEntity.js +72 -129
- package/build/toMatchEntity.js.map +1 -1
- package/package.json +33 -13
- package/build/RunPlugin.d.ts +0 -9
- package/build/RunPlugin.d.ts.map +0 -1
- package/build/context.d.ts +0 -6
- package/build/context.d.ts.map +0 -1
- package/build/context.js.map +0 -1
- package/build/index.d.ts +0 -50
- package/build/index.d.ts.map +0 -1
- package/build/run.d.ts +0 -15
- package/build/run.d.ts.map +0 -1
- package/build/seed.d.ts.map +0 -1
- package/build/toMatchEntity.d.ts +0 -27
- package/build/toMatchEntity.d.ts.map +0 -1
package/build/RunPlugin.js
CHANGED
|
@@ -1,356 +1,218 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
processJoinRows(em, joinTable, todo.newRows, preloads, (oldEntity, entities) => entities.push(oldEntity));
|
|
153
|
-
processJoinRows(em, joinTable, todo.deletedRows, preloads, (oldEntity, entities) => entities.splice(entities.indexOf(oldEntity), 1));
|
|
154
|
-
// Since multiple join rows could reference the same m2m, our processJoinRows doesn't actually call preload() so
|
|
155
|
-
// we need to do it now
|
|
156
|
-
preloads.values().forEach((r) => {
|
|
157
|
-
const id = r.entity.idTagged;
|
|
158
|
-
const entities = api.getPreloadedRelation(id, r.fieldName);
|
|
159
|
-
// unique our entities in case somehow an entity was inserted by multiple join rows
|
|
160
|
-
api.setPreloadedRelation(id, r.fieldName, [...new Set(entities)]);
|
|
161
|
-
r.preload();
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
// Ensure enum m2m (EnumCollection) membership changes are propagated from the new em to the original em
|
|
166
|
-
#syncEnumCollections(joinRowTodos) {
|
|
167
|
-
const { em } = this;
|
|
168
|
-
const api = (0, joist_core_1.getEmInternalApi)(em);
|
|
169
|
-
const touched = new Set();
|
|
170
|
-
Object.values(joinRowTodos).forEach((todo) => {
|
|
171
|
-
// Only enum m2ms; entity-to-entity m2ms are handled by `#syncManyToManys`.
|
|
172
|
-
if (!todo.m2m.otherEnum)
|
|
173
|
-
return;
|
|
174
|
-
const { columnName, otherColumnName, fieldName } = todo.m2m;
|
|
175
|
-
const sync = (rows, add) => {
|
|
176
|
-
rows.forEach((row) => {
|
|
177
|
-
const newEntity = row.columns[columnName];
|
|
178
|
-
const enumId = row.columns[otherColumnName];
|
|
179
|
-
const oldEntity = em.findExistingInstance(newEntity.idTagged);
|
|
180
|
-
if (!oldEntity || oldEntity.isDeletedEntity)
|
|
181
|
-
return;
|
|
182
|
-
const oldCollection = oldEntity[fieldName];
|
|
183
|
-
// Only mirror collections the original em has loaded (or new entities, whose rows are all
|
|
184
|
-
// adds); otherwise a later `.load()` will read the (same-txn) db and see the change itself.
|
|
185
|
-
if (!oldCollection.isLoaded && !newEntity.isNewEntity)
|
|
186
|
-
return;
|
|
187
|
-
const joinRows = api.joinRows(oldCollection);
|
|
188
|
-
if (add) {
|
|
189
|
-
joinRows.addPreloadedRow(oldCollection, undefined, oldEntity, enumId);
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
joinRows.removePreloadedRow(oldCollection, oldEntity, enumId);
|
|
193
|
-
}
|
|
194
|
-
touched.add(oldCollection);
|
|
195
|
-
});
|
|
196
|
-
};
|
|
197
|
-
sync(todo.newRows, true);
|
|
198
|
-
sync(todo.deletedRows, false);
|
|
199
|
-
});
|
|
200
|
-
// Re-publish each touched collection's codes and mark it loaded.
|
|
201
|
-
touched.forEach((oldCollection) => {
|
|
202
|
-
const joinRows = api.joinRows(oldCollection);
|
|
203
|
-
const codes = joinRows.getOthers(oldCollection.columnName, oldCollection.entity).map((id) => oldCollection.otherEnum.findById(id).code);
|
|
204
|
-
api.setPreloadedRelation(oldCollection.entity.idTagged, oldCollection.fieldName, codes);
|
|
205
|
-
oldCollection.preload();
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
// Make sure any unloaded relations on net new entities are marked as loaded. We should have already preloaded all
|
|
209
|
-
// concrete references in a previous step. So we just need to load collections (plus o2os) if they haven't already
|
|
210
|
-
// been preloaded by another step. Since nothing else preloaded them, they must have no data so we can just set
|
|
211
|
-
// them to an empty array.
|
|
212
|
-
#preloadUnloadedRelations(entityTodos) {
|
|
213
|
-
const { em } = this;
|
|
214
|
-
Object.entries(entityTodos).forEach(([, todo]) => {
|
|
215
|
-
todo.inserts.forEach((newEntity) => {
|
|
216
|
-
const oldEntity = em.findExistingInstance(newEntity.idTagged);
|
|
217
|
-
getCollections(oldEntity)
|
|
218
|
-
.filter((r) => !r.isPreloaded)
|
|
219
|
-
.forEach((r) => {
|
|
220
|
-
(0, joist_core_1.getEmInternalApi)(em).setPreloadedRelation(oldEntity.idTagged, r.fieldName, []);
|
|
221
|
-
r.preload();
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
exports.RunPlugin = RunPlugin;
|
|
1
|
+
import { EnumCollectionImpl, ManyToManyCollection, ManyToOneReferenceImpl, OneToManyCollection, OneToOneReferenceImpl, Plugin, PojoRowData, PolymorphicKeySerde, PolymorphicReferenceImpl, ReactiveManyToManyImpl, ReactiveManyToManyOtherSideImpl, ReactiveReferenceImpl, assertNever, createRowFromEntityData, getEmInternalApi, getInstanceData, getMetadata, getRelations, isEntity } from "joist-core";
|
|
2
|
+
//#region src/RunPlugin.ts
|
|
3
|
+
var RunPlugin = class extends Plugin {
|
|
4
|
+
em;
|
|
5
|
+
constructor(em) {
|
|
6
|
+
super();
|
|
7
|
+
this.em = em;
|
|
8
|
+
}
|
|
9
|
+
maybeCloneForNewEm() {
|
|
10
|
+
return this;
|
|
11
|
+
}
|
|
12
|
+
afterWrite(entityTodos, joinRowTodos) {
|
|
13
|
+
const api = getEmInternalApi(this.em);
|
|
14
|
+
api.clearPreloadedRelations();
|
|
15
|
+
api.clearDataloaders();
|
|
16
|
+
this.#syncEntityData(entityTodos);
|
|
17
|
+
this.#syncReferences(entityTodos);
|
|
18
|
+
this.#syncManyToManys(joinRowTodos);
|
|
19
|
+
this.#syncEnumCollections(joinRowTodos);
|
|
20
|
+
this.#preloadUnloadedRelations(entityTodos);
|
|
21
|
+
}
|
|
22
|
+
#syncEntityData(entityTodos) {
|
|
23
|
+
const { em } = this;
|
|
24
|
+
Object.values(entityTodos).forEach((todo) => {
|
|
25
|
+
todo.inserts.forEach((newEntity) => {
|
|
26
|
+
const row = createRowFromEntityData(newEntity, { preferOriginalData: false });
|
|
27
|
+
em.hydrate(newEntity.constructor, [row]);
|
|
28
|
+
});
|
|
29
|
+
todo.updates.forEach((newEntity) => {
|
|
30
|
+
const oldEntity = em.findExistingInstance(newEntity.idTagged);
|
|
31
|
+
if (!oldEntity) fail(`Expected to find existing entity for $ {e.idTagged}`);
|
|
32
|
+
const { data: newData } = getInstanceData(newEntity);
|
|
33
|
+
const { data: oldData } = getInstanceData(oldEntity);
|
|
34
|
+
const meta = getMetadata(newEntity);
|
|
35
|
+
newEntity.changes.fields.values().filter((fieldName) => fieldName in newData).filter((fieldName) => !!meta.allFields[fieldName].serde).forEach((fieldName) => {
|
|
36
|
+
const serde = meta.allFields[fieldName].serde;
|
|
37
|
+
let column;
|
|
38
|
+
let value;
|
|
39
|
+
if (serde instanceof PolymorphicKeySerde) [column, value] = serde.columns.values().map((c) => [c, c.rowValue(newData)]).find(([, v]) => v !== void 0) ?? [];
|
|
40
|
+
else {
|
|
41
|
+
[column] = serde.columns;
|
|
42
|
+
value = column.rowValue(newData);
|
|
43
|
+
}
|
|
44
|
+
oldData[fieldName] = serde.fromRow(new PojoRowData([column ? { [column.columnName]: value } : {}]), 0);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
todo.deletes.forEach((newEntity) => {
|
|
48
|
+
const existing = em.findExistingInstance(newEntity.idTagged);
|
|
49
|
+
if (!existing) fail(`Expected to find existing entity for $ {e.idTagged}`);
|
|
50
|
+
getInstanceData(existing).markDeletedBecauseNotFound();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
#syncReferences(entityTodos) {
|
|
55
|
+
const { em } = this;
|
|
56
|
+
Object.values(entityTodos).forEach((todo) => {
|
|
57
|
+
todo.inserts.forEach((newEntity) => {
|
|
58
|
+
const oldEntity = em.findExistingInstance(newEntity.idTagged);
|
|
59
|
+
getReferences(newEntity).forEach((r) => {
|
|
60
|
+
const other = r.isSet ? em.findExistingInstance(r.idTaggedMaybe) : void 0;
|
|
61
|
+
preloadReference(em, r.fieldName, oldEntity, other);
|
|
62
|
+
if (other) maybePreloadOtherSide(em, r.fieldName, oldEntity, other);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
todo.updates.forEach((newEntity) => {
|
|
66
|
+
const oldEntity = em.findExistingInstance(newEntity.idTagged);
|
|
67
|
+
getReferences(newEntity).filter((r) => newEntity.changes[r.fieldName].hasChanged).forEach((r) => {
|
|
68
|
+
const other = r.isSet ? em.findExistingInstance(r.idTaggedMaybe) : void 0;
|
|
69
|
+
preloadReference(em, r.fieldName, oldEntity, other);
|
|
70
|
+
if (other) maybePreloadOtherSide(em, r.fieldName, oldEntity, other);
|
|
71
|
+
const originalId = newEntity.changes[r.fieldName].originalValue;
|
|
72
|
+
const originalOther = originalId ? em.findExistingInstance(originalId) : void 0;
|
|
73
|
+
if (originalOther) maybePreloadOtherSide(em, r.fieldName, oldEntity, originalOther, true);
|
|
74
|
+
});
|
|
75
|
+
if ("deletedAt" in newEntity && newEntity.changes.deletedAt.hasChanged) getReferences(oldEntity).forEach((r) => {
|
|
76
|
+
const other = r.isSet ? em.findExistingInstance(r.idTaggedMaybe) : void 0;
|
|
77
|
+
if (other) {
|
|
78
|
+
const otherSide = getOtherSide(r.fieldName, oldEntity, other);
|
|
79
|
+
if (otherSide instanceof OneToManyCollection) otherSide.resetIsLoaded();
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
todo.deletes.forEach((newEntity) => {
|
|
84
|
+
const oldEntity = em.findExistingInstance(newEntity.idTagged);
|
|
85
|
+
getReferences(newEntity).forEach((r) => {
|
|
86
|
+
const entityOrId = getInstanceData(oldEntity).data[r.fieldName];
|
|
87
|
+
const originalOther = entityOrId ? em.findExistingInstance(isEntity(entityOrId) ? entityOrId.idTagged : entityOrId) : void 0;
|
|
88
|
+
if (originalOther) maybePreloadOtherSide(em, r.fieldName, oldEntity, originalOther, true);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
#syncManyToManys(joinRowTodos) {
|
|
94
|
+
const { em } = this;
|
|
95
|
+
const api = getEmInternalApi(em);
|
|
96
|
+
Object.entries(joinRowTodos).forEach(([joinTable, todo]) => {
|
|
97
|
+
if (todo.m2m.otherEnum) return;
|
|
98
|
+
const preloads = /* @__PURE__ */ new Set();
|
|
99
|
+
processJoinRows(em, joinTable, todo.newRows, preloads, (oldEntity, entities) => entities.push(oldEntity));
|
|
100
|
+
processJoinRows(em, joinTable, todo.deletedRows, preloads, (oldEntity, entities) => entities.splice(entities.indexOf(oldEntity), 1));
|
|
101
|
+
preloads.values().forEach((r) => {
|
|
102
|
+
const id = r.entity.idTagged;
|
|
103
|
+
const entities = api.getPreloadedRelation(id, r.fieldName);
|
|
104
|
+
api.setPreloadedRelation(id, r.fieldName, [...new Set(entities)]);
|
|
105
|
+
r.preload();
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
#syncEnumCollections(joinRowTodos) {
|
|
110
|
+
const { em } = this;
|
|
111
|
+
const api = getEmInternalApi(em);
|
|
112
|
+
const touched = /* @__PURE__ */ new Set();
|
|
113
|
+
Object.values(joinRowTodos).forEach((todo) => {
|
|
114
|
+
if (!todo.m2m.otherEnum) return;
|
|
115
|
+
const { columnName, otherColumnName, fieldName } = todo.m2m;
|
|
116
|
+
const sync = (rows, add) => {
|
|
117
|
+
rows.forEach((row) => {
|
|
118
|
+
const newEntity = row.columns[columnName];
|
|
119
|
+
const enumId = row.columns[otherColumnName];
|
|
120
|
+
const oldEntity = em.findExistingInstance(newEntity.idTagged);
|
|
121
|
+
if (!oldEntity || oldEntity.isDeletedEntity) return;
|
|
122
|
+
const oldCollection = oldEntity[fieldName];
|
|
123
|
+
if (!oldCollection.isLoaded && !newEntity.isNewEntity) return;
|
|
124
|
+
const joinRows = api.joinRows(oldCollection);
|
|
125
|
+
if (add) joinRows.addPreloadedRow(oldCollection, void 0, oldEntity, enumId);
|
|
126
|
+
else joinRows.removePreloadedRow(oldCollection, oldEntity, enumId);
|
|
127
|
+
touched.add(oldCollection);
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
sync(todo.newRows, true);
|
|
131
|
+
sync(todo.deletedRows, false);
|
|
132
|
+
});
|
|
133
|
+
touched.forEach((oldCollection) => {
|
|
134
|
+
const codes = api.joinRows(oldCollection).getOthers(oldCollection.columnName, oldCollection.entity).map((id) => oldCollection.otherEnum.findById(id).code);
|
|
135
|
+
api.setPreloadedRelation(oldCollection.entity.idTagged, oldCollection.fieldName, codes);
|
|
136
|
+
oldCollection.preload();
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
#preloadUnloadedRelations(entityTodos) {
|
|
140
|
+
const { em } = this;
|
|
141
|
+
Object.entries(entityTodos).forEach(([, todo]) => {
|
|
142
|
+
todo.inserts.forEach((newEntity) => {
|
|
143
|
+
const oldEntity = em.findExistingInstance(newEntity.idTagged);
|
|
144
|
+
getCollections(oldEntity).filter((r) => !r.isPreloaded).forEach((r) => {
|
|
145
|
+
getEmInternalApi(em).setPreloadedRelation(oldEntity.idTagged, r.fieldName, []);
|
|
146
|
+
r.preload();
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
};
|
|
228
152
|
function preloadReference(em, fieldName, entity, other) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
reference.unload();
|
|
235
|
-
const { data } = (0, joist_core_1.getInstanceData)(entity);
|
|
236
|
-
data[fieldName] = other?.idTagged;
|
|
237
|
-
if (!entity.isDeletedEntity)
|
|
238
|
-
reference.preload();
|
|
153
|
+
const reference = entity[fieldName];
|
|
154
|
+
reference.unload();
|
|
155
|
+
const { data } = getInstanceData(entity);
|
|
156
|
+
data[fieldName] = other?.idTagged;
|
|
157
|
+
if (!entity.isDeletedEntity) reference.preload();
|
|
239
158
|
}
|
|
240
159
|
function getOtherSide(fieldName, entity, other) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
.values()
|
|
245
|
-
.filter((r) => r instanceof joist_core_1.OneToOneReferenceImpl || r instanceof joist_core_1.OneToManyCollection)
|
|
246
|
-
.find((r) => metas.has(r.otherMeta) && r.otherFieldName === fieldName);
|
|
160
|
+
const meta = getMetadata(entity);
|
|
161
|
+
const metas = /* @__PURE__ */ new Set([meta, ...meta.baseTypes]);
|
|
162
|
+
return getRelations(other).values().filter((r) => r instanceof OneToOneReferenceImpl || r instanceof OneToManyCollection).find((r) => metas.has(r.otherMeta) && r.otherFieldName === fieldName);
|
|
247
163
|
}
|
|
248
164
|
function maybePreloadOtherSide(em, fieldName, entity, other, remove = false) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
otherEntities = remove ? [] : [entity];
|
|
261
|
-
}
|
|
262
|
-
else if (otherSide instanceof joist_core_1.OneToManyCollection) {
|
|
263
|
-
// Scan the entire em for (non-deleted) entities of our type that reference the other side
|
|
264
|
-
otherEntities = em
|
|
265
|
-
.getEntities(meta.cstr)
|
|
266
|
-
.values()
|
|
267
|
-
.filter((e) => !e.isDeletedEntity)
|
|
268
|
-
.filter((e) => e[otherSide.otherFieldName].idTaggedMaybe === other.idTagged)
|
|
269
|
-
.toArray();
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
(0, joist_core_1.assertNever)(otherSide);
|
|
273
|
-
}
|
|
274
|
-
// We don't need to worry about order here because o2ms do their own sorting internally and o2os are inherently
|
|
275
|
-
// unordered (since it's just a single entity)
|
|
276
|
-
(0, joist_core_1.getEmInternalApi)(em).setPreloadedRelation(other.idTagged, otherSide.fieldName, otherEntities);
|
|
277
|
-
otherSide.preload();
|
|
278
|
-
// This method is confusingly name, what it actually does is clear out the sorted caches that m2m uses to avoid
|
|
279
|
-
// sorting on every `.get` call. Since we just preloaded the collection with new data, we know these caches need to
|
|
280
|
-
// be cleared
|
|
281
|
-
if (otherSide instanceof joist_core_1.OneToManyCollection)
|
|
282
|
-
otherSide.resetIsLoaded();
|
|
165
|
+
const meta = getMetadata(entity);
|
|
166
|
+
const otherSide = getOtherSide(fieldName, entity, other);
|
|
167
|
+
if (!otherSide) return;
|
|
168
|
+
if (otherSide.isPreloaded) return;
|
|
169
|
+
let otherEntities;
|
|
170
|
+
if (otherSide instanceof OneToOneReferenceImpl) otherEntities = remove ? [] : [entity];
|
|
171
|
+
else if (otherSide instanceof OneToManyCollection) otherEntities = em.getEntities(meta.cstr).values().filter((e) => !e.isDeletedEntity).filter((e) => e[otherSide.otherFieldName].idTaggedMaybe === other.idTagged).toArray();
|
|
172
|
+
else assertNever(otherSide);
|
|
173
|
+
getEmInternalApi(em).setPreloadedRelation(other.idTagged, otherSide.fieldName, otherEntities);
|
|
174
|
+
otherSide.preload();
|
|
175
|
+
if (otherSide instanceof OneToManyCollection) otherSide.resetIsLoaded();
|
|
283
176
|
}
|
|
284
177
|
function processJoinRows(em, joinTable, rows, preloads, callback) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
// in order from there. Removals are fine since they'll modify the array in place and the correct order will
|
|
313
|
-
// be preserved.
|
|
314
|
-
entities = oldM2m.get;
|
|
315
|
-
}
|
|
316
|
-
else if (newEntity.isNewEntity) {
|
|
317
|
-
// If this is a new entity, then all the join rows referencing it must also be inserts. So we can just use an
|
|
318
|
-
// empty array initially and inserts will be appended to it.
|
|
319
|
-
entities = [];
|
|
320
|
-
}
|
|
321
|
-
else {
|
|
322
|
-
fail(`Expected ${fieldName} to be loaded`);
|
|
323
|
-
}
|
|
324
|
-
callback(em.findExistingInstance(newOther.idTagged), entities);
|
|
325
|
-
api.setPreloadedRelation(id, fieldName, entities);
|
|
326
|
-
// We only need to preload the m2m once, but multiple join rows could reference it, so we keep track of which m2ms
|
|
327
|
-
// need to be preloaded as we work, then actually call preload() at the end once we're done.
|
|
328
|
-
preloads.add(oldM2m);
|
|
329
|
-
});
|
|
330
|
-
});
|
|
178
|
+
const api = getEmInternalApi(em);
|
|
179
|
+
rows.forEach((row) => {
|
|
180
|
+
const [[col1, e1], [col2, e2]] = Object.entries(row.columns);
|
|
181
|
+
[[
|
|
182
|
+
col1,
|
|
183
|
+
e1,
|
|
184
|
+
e2
|
|
185
|
+
], [
|
|
186
|
+
col2,
|
|
187
|
+
e2,
|
|
188
|
+
e1
|
|
189
|
+
]].forEach(([column, newEntity, newOther]) => {
|
|
190
|
+
const { idTagged: id } = newEntity;
|
|
191
|
+
const oldEntity = em.findExistingInstance(id);
|
|
192
|
+
if (oldEntity.isDeletedEntity) return;
|
|
193
|
+
const { fieldName } = getManyToManys(newEntity).find((r) => r.joinTableName === joinTable && r.columnName === column);
|
|
194
|
+
const oldM2m = oldEntity[fieldName];
|
|
195
|
+
let entities;
|
|
196
|
+
if (preloads.has(oldM2m)) entities = api.getPreloadedRelation(id, fieldName);
|
|
197
|
+
else if (oldM2m.isLoaded) entities = oldM2m.get;
|
|
198
|
+
else if (newEntity.isNewEntity) entities = [];
|
|
199
|
+
else fail(`Expected ${fieldName} to be loaded`);
|
|
200
|
+
callback(em.findExistingInstance(newOther.idTagged), entities);
|
|
201
|
+
api.setPreloadedRelation(id, fieldName, entities);
|
|
202
|
+
preloads.add(oldM2m);
|
|
203
|
+
});
|
|
204
|
+
});
|
|
331
205
|
}
|
|
332
206
|
function getReferences(entity) {
|
|
333
|
-
|
|
334
|
-
.values()
|
|
335
|
-
.filter((r) => r instanceof joist_core_1.ManyToOneReferenceImpl ||
|
|
336
|
-
r instanceof joist_core_1.ReactiveReferenceImpl ||
|
|
337
|
-
r instanceof joist_core_1.PolymorphicReferenceImpl);
|
|
207
|
+
return getRelations(entity).values().filter((r) => r instanceof ManyToOneReferenceImpl || r instanceof ReactiveReferenceImpl || r instanceof PolymorphicReferenceImpl);
|
|
338
208
|
}
|
|
339
209
|
function getManyToManys(entity) {
|
|
340
|
-
|
|
341
|
-
.values()
|
|
342
|
-
.filter((r) => r instanceof joist_core_1.ManyToManyCollection ||
|
|
343
|
-
r instanceof joist_core_1.ReactiveManyToManyImpl ||
|
|
344
|
-
r instanceof joist_core_1.ReactiveManyToManyOtherSideImpl);
|
|
210
|
+
return getRelations(entity).values().filter((r) => r instanceof ManyToManyCollection || r instanceof ReactiveManyToManyImpl || r instanceof ReactiveManyToManyOtherSideImpl);
|
|
345
211
|
}
|
|
346
212
|
function getCollections(entity) {
|
|
347
|
-
|
|
348
|
-
.values()
|
|
349
|
-
.filter((r) => r instanceof joist_core_1.ManyToManyCollection ||
|
|
350
|
-
r instanceof joist_core_1.OneToManyCollection ||
|
|
351
|
-
r instanceof joist_core_1.OneToOneReferenceImpl ||
|
|
352
|
-
r instanceof joist_core_1.ReactiveManyToManyImpl ||
|
|
353
|
-
r instanceof joist_core_1.ReactiveManyToManyOtherSideImpl ||
|
|
354
|
-
r instanceof joist_core_1.EnumCollectionImpl);
|
|
213
|
+
return getRelations(entity).values().filter((r) => r instanceof ManyToManyCollection || r instanceof OneToManyCollection || r instanceof OneToOneReferenceImpl || r instanceof ReactiveManyToManyImpl || r instanceof ReactiveManyToManyOtherSideImpl || r instanceof EnumCollectionImpl);
|
|
355
214
|
}
|
|
215
|
+
//#endregion
|
|
216
|
+
export { RunPlugin };
|
|
217
|
+
|
|
356
218
|
//# sourceMappingURL=RunPlugin.js.map
|