@mikro-orm/core 6.4.17-dev.38 → 6.4.17-dev.39

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.
@@ -6,6 +6,7 @@ export declare class ArrayCollection<T extends object, O extends object> {
6
6
  protected readonly items: Set<T>;
7
7
  protected initialized: boolean;
8
8
  protected dirty: boolean;
9
+ protected partial: boolean;
9
10
  protected snapshot: T[] | undefined;
10
11
  protected _count?: number;
11
12
  private _property?;
@@ -25,7 +26,7 @@ export declare class ArrayCollection<T extends object, O extends object> {
25
26
  /**
26
27
  * @internal
27
28
  */
28
- hydrate(items: T[], forcePropagate?: boolean): void;
29
+ hydrate(items: T[], forcePropagate?: boolean, partial?: boolean): void;
29
30
  /**
30
31
  * Remove specified item(s) from the collection. Note that removing item from collection does not necessarily imply deleting the target entity,
31
32
  * it means we are disconnecting the relation - removing items from collection, not removing entities from database - `Collection.remove()`
@@ -83,6 +84,7 @@ export declare class ArrayCollection<T extends object, O extends object> {
83
84
  count(): number;
84
85
  isInitialized(fully?: boolean): boolean;
85
86
  isDirty(): boolean;
87
+ isPartial(): boolean;
86
88
  isEmpty(): boolean;
87
89
  setDirty(dirty?: boolean): void;
88
90
  get length(): number;
@@ -12,6 +12,7 @@ class ArrayCollection {
12
12
  items = new Set();
13
13
  initialized = true;
14
14
  dirty = false;
15
+ partial = false; // mark partially loaded collections, propagation is disabled for those
15
16
  snapshot = []; // used to create a diff of the collection at commit time, undefined marks overridden values so we need to wipe when flushing
16
17
  _count;
17
18
  _property;
@@ -110,11 +111,12 @@ class ArrayCollection {
110
111
  /**
111
112
  * @internal
112
113
  */
113
- hydrate(items, forcePropagate) {
114
+ hydrate(items, forcePropagate, partial) {
114
115
  for (let i = 0; i < this.items.size; i++) {
115
116
  delete this[i];
116
117
  }
117
118
  this.initialized = true;
119
+ this.partial = !!partial;
118
120
  this.items.clear();
119
121
  this._count = 0;
120
122
  this.add(items);
@@ -277,6 +279,9 @@ class ArrayCollection {
277
279
  isDirty() {
278
280
  return this.dirty;
279
281
  }
282
+ isPartial() {
283
+ return this.partial;
284
+ }
280
285
  isEmpty() {
281
286
  return this.count() === 0;
282
287
  }
@@ -393,7 +398,7 @@ class ArrayCollection {
393
398
  /** @ignore */
394
399
  [node_util_1.inspect.custom](depth = 2) {
395
400
  const object = { ...this };
396
- const hidden = ['items', 'owner', '_property', '_count', 'snapshot', '_populated', '_snapshot', '_lazyInitialized', '_em', 'readonly'];
401
+ const hidden = ['items', 'owner', '_property', '_count', 'snapshot', '_populated', '_snapshot', '_lazyInitialized', '_em', 'readonly', 'partial'];
397
402
  hidden.forEach(k => delete object[k]);
398
403
  const ret = (0, node_util_1.inspect)(object, { depth });
399
404
  const name = `${this.constructor.name}<${this.property?.type ?? 'unknown'}>`;
@@ -175,6 +175,9 @@ class EntityHelper {
175
175
  continue;
176
176
  }
177
177
  const inverse = value?.[prop2.name];
178
+ if (Utils_1.Utils.isCollection(inverse) && inverse.isPartial()) {
179
+ continue;
180
+ }
178
181
  if (prop.kind === enums_1.ReferenceKind.MANY_TO_ONE && Utils_1.Utils.isCollection(inverse) && inverse.isInitialized()) {
179
182
  inverse.addWithoutPropagation(owner);
180
183
  (0, wrap_1.helper)(owner).__em?.getUnitOfWork().cancelOrphanRemoval(owner);
@@ -148,9 +148,9 @@ class EntityLoader {
148
148
  return Utils_1.Utils.flatten(res);
149
149
  }
150
150
  const where = await this.extractChildCondition(options, prop);
151
- const data = await this.findChildren(entities, prop, populate, { ...options, where, orderBy: innerOrderBy }, !!(ref || prop.mapToPk));
152
- this.initializeCollections(filtered, prop, field, data, innerOrderBy.length > 0);
153
- return data;
151
+ const { items, partial } = await this.findChildren(entities, prop, populate, { ...options, where, orderBy: innerOrderBy }, !!(ref || prop.mapToPk));
152
+ this.initializeCollections(filtered, prop, field, items, innerOrderBy.length > 0, partial);
153
+ return items;
154
154
  }
155
155
  async populateScalar(meta, filtered, options) {
156
156
  const pk = Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
@@ -163,15 +163,15 @@ class EntityLoader {
163
163
  populate: [],
164
164
  });
165
165
  }
166
- initializeCollections(filtered, prop, field, children, customOrder) {
166
+ initializeCollections(filtered, prop, field, children, customOrder, partial) {
167
167
  if (prop.kind === enums_1.ReferenceKind.ONE_TO_MANY) {
168
- this.initializeOneToMany(filtered, children, prop, field);
168
+ this.initializeOneToMany(filtered, children, prop, field, partial);
169
169
  }
170
170
  if (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY && !this.driver.getPlatform().usesPivotTable()) {
171
- this.initializeManyToMany(filtered, children, prop, field, customOrder);
171
+ this.initializeManyToMany(filtered, children, prop, field, customOrder, partial);
172
172
  }
173
173
  }
174
- initializeOneToMany(filtered, children, prop, field) {
174
+ initializeOneToMany(filtered, children, prop, field, partial) {
175
175
  const mapToPk = prop.targetMeta.properties[prop.mappedBy].mapToPk;
176
176
  const map = {};
177
177
  for (const entity of filtered) {
@@ -187,14 +187,14 @@ class EntityLoader {
187
187
  }
188
188
  for (const entity of filtered) {
189
189
  const key = (0, wrap_1.helper)(entity).getSerializedPrimaryKey();
190
- entity[field].hydrate(map[key]);
190
+ entity[field].hydrate(map[key], undefined, partial);
191
191
  }
192
192
  }
193
- initializeManyToMany(filtered, children, prop, field, customOrder) {
193
+ initializeManyToMany(filtered, children, prop, field, customOrder, partial) {
194
194
  if (prop.mappedBy) {
195
195
  for (const entity of filtered) {
196
196
  const items = children.filter(child => child[prop.mappedBy].contains(entity, false));
197
- entity[field].hydrate(items, true);
197
+ entity[field].hydrate(items, true, partial);
198
198
  }
199
199
  }
200
200
  else { // owning side of M:N without pivot table needs to be reordered
@@ -204,7 +204,7 @@ class EntityLoader {
204
204
  if (!customOrder) {
205
205
  items.sort((a, b) => order.indexOf(a) - order.indexOf(b));
206
206
  }
207
- entity[field].hydrate(items, true);
207
+ entity[field].hydrate(items, true, partial);
208
208
  }
209
209
  }
210
210
  }
@@ -213,6 +213,7 @@ class EntityLoader {
213
213
  const meta = prop.targetMeta;
214
214
  let fk = Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
215
215
  let schema = options.schema;
216
+ let partial = !Utils_1.Utils.isEmpty(prop.where);
216
217
  if (prop.kind === enums_1.ReferenceKind.ONE_TO_MANY || (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY && !prop.owner)) {
217
218
  fk = meta.properties[prop.mappedBy].name;
218
219
  }
@@ -222,7 +223,7 @@ class EntityLoader {
222
223
  children.push(...this.filterByReferences(entities, prop.name, options.refresh));
223
224
  }
224
225
  if (children.length === 0) {
225
- return [];
226
+ return { items: [], partial };
226
227
  }
227
228
  if (!schema && [enums_1.ReferenceKind.ONE_TO_ONE, enums_1.ReferenceKind.MANY_TO_ONE].includes(prop.kind)) {
228
229
  schema = children.find(e => e.__helper.__schema)?.__helper.__schema;
@@ -253,6 +254,7 @@ class EntityLoader {
253
254
  }
254
255
  }
255
256
  }
257
+ partial = !Utils_1.Utils.isEmpty(where);
256
258
  const items = await this.em.find(prop.type, where, {
257
259
  filters, convertCustomTypes, lockMode, populateWhere, logging,
258
260
  orderBy: [...Utils_1.Utils.asArray(options.orderBy), ...propOrderBy],
@@ -271,7 +273,7 @@ class EntityLoader {
271
273
  this.em.getUnitOfWork()['loadedEntities'].delete(item);
272
274
  }
273
275
  }
274
- return items;
276
+ return { items, partial };
275
277
  }
276
278
  mergePrimaryCondition(ids, pk, options, meta, metadata, platform) {
277
279
  const cond1 = QueryHelper_1.QueryHelper.processWhere({ where: { [pk]: { $in: ids } }, entityName: meta.className, metadata, platform, convertCustomTypes: !options.convertCustomTypes });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "6.4.17-dev.38",
3
+ "version": "6.4.17-dev.39",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -64,7 +64,7 @@
64
64
  "esprima": "4.0.1",
65
65
  "fs-extra": "11.3.0",
66
66
  "globby": "11.1.0",
67
- "mikro-orm": "6.4.17-dev.38",
67
+ "mikro-orm": "6.4.17-dev.39",
68
68
  "reflect-metadata": "0.2.2"
69
69
  }
70
70
  }