@mikro-orm/core 7.0.0-dev.57 → 7.0.0-dev.59

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.
@@ -1,5 +1,4 @@
1
1
  import { inspect } from 'node:util';
2
- import DataLoader from 'dataloader';
3
2
  import { type Configuration } from './utils/Configuration.js';
4
3
  import { Cursor } from './utils/Cursor.js';
5
4
  import { EntityFactory } from './entity/EntityFactory.js';
@@ -33,9 +32,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
33
32
  readonly _id: number;
34
33
  readonly global = false;
35
34
  readonly name: string;
36
- protected readonly refLoader: DataLoader<[Reference<any>, (Omit<import("./entity/Reference.js").LoadReferenceOptions<any, any, "*", never>, "dataloader"> | undefined)?], any, [Reference<any>, (Omit<import("./entity/Reference.js").LoadReferenceOptions<any, any, "*", never>, "dataloader"> | undefined)?]>;
37
- protected readonly colLoader: DataLoader<[import("./index.js").Collection<any, object>, (Omit<import("./index.js").InitCollectionOptions<any, any, "*", never>, "dataloader"> | undefined)?], any, [import("./index.js").Collection<any, object>, (Omit<import("./index.js").InitCollectionOptions<any, any, "*", never>, "dataloader"> | undefined)?]>;
38
- protected readonly colLoaderMtoN: DataLoader<[import("./index.js").Collection<any, object>, (Omit<import("./index.js").InitCollectionOptions<any, any, "*", never>, "dataloader"> | undefined)?], any, [import("./index.js").Collection<any, object>, (Omit<import("./index.js").InitCollectionOptions<any, any, "*", never>, "dataloader"> | undefined)?]>;
35
+ private readonly loaders;
39
36
  private readonly validator;
40
37
  private readonly repositoryMap;
41
38
  private readonly entityLoader;
@@ -565,6 +562,8 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
565
562
  * if executed inside request context handler.
566
563
  */
567
564
  set schema(schema: string | null | undefined);
565
+ /** @internal */
566
+ getDataLoader(type: 'ref' | '1:m' | 'm:n'): Promise<any>;
568
567
  /**
569
568
  * Returns the ID of this EntityManager. Respects the context, so global EM will give you the contextual ID
570
569
  * if executed inside request context handler.
package/EntityManager.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { inspect } from 'node:util';
2
- import DataLoader from 'dataloader';
3
2
  import { getOnConflictReturningFields, getWhereCondition } from './utils/upsert-utils.js';
4
3
  import { Utils } from './utils/Utils.js';
5
4
  import { Cursor } from './utils/Cursor.js';
@@ -36,9 +35,7 @@ export class EntityManager {
36
35
  _id = EntityManager.counter++;
37
36
  global = false;
38
37
  name;
39
- refLoader = new DataLoader(DataloaderUtils.getRefBatchLoadFn(this));
40
- colLoader = new DataLoader(DataloaderUtils.getColBatchLoadFn(this));
41
- colLoaderMtoN = new DataLoader(DataloaderUtils.getManyToManyColBatchLoadFn(this));
38
+ loaders = {};
42
39
  validator;
43
40
  repositoryMap = {};
44
41
  entityLoader;
@@ -1854,6 +1851,19 @@ export class EntityManager {
1854
1851
  set schema(schema) {
1855
1852
  this.getContext(false)._schema = schema ?? undefined;
1856
1853
  }
1854
+ /** @internal */
1855
+ async getDataLoader(type) {
1856
+ const em = this.getContext();
1857
+ if (em.loaders[type]) {
1858
+ return em.loaders[type];
1859
+ }
1860
+ const DataLoader = await DataloaderUtils.getDataLoader();
1861
+ switch (type) {
1862
+ case 'ref': return (em.loaders[type] ??= new DataLoader(DataloaderUtils.getRefBatchLoadFn(em)));
1863
+ case '1:m': return (em.loaders[type] ??= new DataLoader(DataloaderUtils.getColBatchLoadFn(em)));
1864
+ case 'm:n': return (em.loaders[type] ??= new DataLoader(DataloaderUtils.getManyToManyColBatchLoadFn(em)));
1865
+ }
1866
+ }
1857
1867
  /**
1858
1868
  * Returns the ID of this EntityManager. Respects the context, so global EM will give you the contextual ID
1859
1869
  * if executed inside request context handler.
@@ -228,11 +228,8 @@ export class Collection extends ArrayCollection {
228
228
  const orderBy = this.createOrderBy(options.orderBy);
229
229
  const customOrder = orderBy.length > 0;
230
230
  const pivotTable = this.property.kind === ReferenceKind.MANY_TO_MANY && em.getPlatform().usesPivotTable();
231
- const loader = pivotTable ? 'colLoaderMtoN' : 'colLoader';
232
- const items = await em[loader].load([
233
- this,
234
- { ...options, orderBy },
235
- ]);
231
+ const loader = await em.getDataLoader(pivotTable ? 'm:n' : '1:m');
232
+ const items = await loader.load([this, { ...options, orderBy }]);
236
233
  if (this.property.kind === ReferenceKind.MANY_TO_MANY) {
237
234
  this.initialized = true;
238
235
  this.dirty = false;
@@ -94,8 +94,8 @@ export class Reference {
94
94
  }
95
95
  if (!this.isInitialized() || options.refresh) {
96
96
  if (options.dataloader ?? [DataloaderType.ALL, DataloaderType.REFERENCE].includes(wrapped.__em.config.getDataloaderType())) {
97
- // eslint-disable-next-line dot-notation
98
- return wrapped.__em['refLoader'].load([this, options]);
97
+ const dataLoader = await wrapped.__em.getDataLoader('ref');
98
+ return dataLoader.load([this, options]);
99
99
  }
100
100
  return wrapped.init(options);
101
101
  }
@@ -165,7 +165,7 @@ export class MetadataDiscovery {
165
165
  if (this.config.get('discovery').requireEntitiesArray) {
166
166
  throw new Error(`[requireEntitiesArray] Explicit list of entities is required, please use the 'entities' option.`);
167
167
  }
168
- const { discoverEntities } = await Utils.dynamicImport('@mikro-orm/core/file-discovery');
168
+ const { discoverEntities } = await import('@mikro-orm/core/file-discovery' + '');
169
169
  processed.push(...await discoverEntities(entity, { baseDir }));
170
170
  }
171
171
  else {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
3
  "type": "module",
4
- "version": "7.0.0-dev.57",
4
+ "version": "7.0.0-dev.59",
5
5
  "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.",
6
6
  "exports": {
7
7
  "./package.json": "./package.json",
@@ -52,11 +52,18 @@
52
52
  "access": "public"
53
53
  },
54
54
  "dependencies": {
55
- "dataloader": "2.2.3",
56
55
  "dotenv": "17.2.3",
57
56
  "esprima": "4.0.1",
58
- "mikro-orm": "7.0.0-dev.57",
57
+ "mikro-orm": "7.0.0-dev.59",
59
58
  "reflect-metadata": "0.2.2",
60
59
  "tinyglobby": "0.2.13"
60
+ },
61
+ "peerDependencies": {
62
+ "dataloader": "2.2.3"
63
+ },
64
+ "peerDependenciesMeta": {
65
+ "dataloader": {
66
+ "optional": true
67
+ }
61
68
  }
62
69
  }
@@ -1,8 +1,8 @@
1
1
  import type { NamingStrategy } from '../naming-strategy/NamingStrategy.js';
2
2
  import { FileCacheAdapter } from '../cache/FileCacheAdapter.js';
3
- import { type SyncCacheAdapter, type CacheAdapter } from '../cache/CacheAdapter.js';
3
+ import { type CacheAdapter, type SyncCacheAdapter } from '../cache/CacheAdapter.js';
4
4
  import type { EntityRepository } from '../entity/EntityRepository.js';
5
- import type { AnyEntity, Constructor, Dictionary, EntityClass, FilterDef, Highlighter, HydratorConstructor, IHydrator, IMigrationGenerator, IPrimaryKey, MaybePromise, MigrationObject, EntityMetadata, EnsureDatabaseOptions, GenerateOptions, Migration } from '../typings.js';
5
+ import type { AnyEntity, Constructor, Dictionary, EnsureDatabaseOptions, EntityClass, EntityMetadata, FilterDef, GenerateOptions, Highlighter, HydratorConstructor, IHydrator, IMigrationGenerator, IPrimaryKey, MaybePromise, Migration, MigrationObject } from '../typings.js';
6
6
  import { ObjectHydrator } from '../hydration/ObjectHydrator.js';
7
7
  import { NullHighlighter } from '../utils/NullHighlighter.js';
8
8
  import { type Logger, type LoggerNamespace, type LoggerOptions } from '../logging/Logger.js';
@@ -289,8 +289,7 @@ export class Configuration {
289
289
  */
290
290
  getCachedService(cls, ...args) {
291
291
  if (!this.cache.has(cls.name)) {
292
- const Class = cls;
293
- this.cache.set(cls.name, new Class(...args));
292
+ this.cache.set(cls.name, new cls(...args));
294
293
  }
295
294
  return this.cache.get(cls.name);
296
295
  }
@@ -1,9 +1,10 @@
1
- import type DataLoader from 'dataloader';
2
- import type { Primary, Ref } from '../typings.js';
1
+ import type { Constructor, Primary, Ref } from '../typings.js';
3
2
  import { Collection, type InitCollectionOptions } from '../entity/Collection.js';
4
3
  import { type EntityManager } from '../EntityManager.js';
5
4
  import { type LoadReferenceOptions } from '../entity/Reference.js';
5
+ type BatchLoadFn<K, V> = (keys: readonly K[]) => PromiseLike<ArrayLike<V | Error>>;
6
6
  export declare class DataloaderUtils {
7
+ private static DataLoader?;
7
8
  /**
8
9
  * Groups identified references by entity and returns a Map with the
9
10
  * class name as the index and the corresponding primary keys as the value.
@@ -13,7 +14,7 @@ export declare class DataloaderUtils {
13
14
  * Returns the reference dataloader batchLoadFn, which aggregates references by entity,
14
15
  * makes one query per entity and maps each input reference to the corresponding result.
15
16
  */
16
- static getRefBatchLoadFn(em: EntityManager): DataLoader.BatchLoadFn<[Ref<any>, Omit<LoadReferenceOptions<any, any>, 'dataloader'>?], any>;
17
+ static getRefBatchLoadFn(em: EntityManager): BatchLoadFn<[Ref<any>, Omit<LoadReferenceOptions<any, any>, 'dataloader'>?], any>;
17
18
  /**
18
19
  * Groups collections by entity and returns a Map whose keys are the entity names and whose values are filter Maps
19
20
  * which we can use to narrow down the find query to return just the items of the collections that have been dataloaded.
@@ -37,10 +38,14 @@ export declare class DataloaderUtils {
37
38
  * Returns the 1:M collection dataloader batchLoadFn, which aggregates collections by entity,
38
39
  * makes one query per entity and maps each input collection to the corresponding result.
39
40
  */
40
- static getColBatchLoadFn(em: EntityManager): DataLoader.BatchLoadFn<[Collection<any>, Omit<InitCollectionOptions<any, any>, 'dataloader'>?], any>;
41
+ static getColBatchLoadFn(em: EntityManager): BatchLoadFn<[Collection<any>, Omit<InitCollectionOptions<any, any>, 'dataloader'>?], any>;
41
42
  /**
42
43
  * Returns the M:N collection dataloader batchLoadFn, which aggregates collections by entity,
43
44
  * makes one query per entity and maps each input collection to the corresponding result.
44
45
  */
45
- static getManyToManyColBatchLoadFn(em: EntityManager): DataLoader.BatchLoadFn<[Collection<any>, Omit<InitCollectionOptions<any, any>, 'dataloader'>?], any>;
46
+ static getManyToManyColBatchLoadFn(em: EntityManager): BatchLoadFn<[Collection<any>, Omit<InitCollectionOptions<any, any>, 'dataloader'>?], any>;
47
+ static getDataLoader(): Promise<Constructor<{
48
+ load: (...args: unknown[]) => Promise<unknown>;
49
+ }>>;
46
50
  }
51
+ export {};
@@ -3,6 +3,7 @@ import { helper } from '../entity/wrap.js';
3
3
  import { Reference } from '../entity/Reference.js';
4
4
  import { Utils } from './Utils.js';
5
5
  export class DataloaderUtils {
6
+ static DataLoader;
6
7
  /**
7
8
  * Groups identified references by entity and returns a Map with the
8
9
  * class name as the index and the corresponding primary keys as the value.
@@ -210,4 +211,18 @@ export class DataloaderUtils {
210
211
  return ret;
211
212
  };
212
213
  }
214
+ static async getDataLoader() {
215
+ if (this.DataLoader) {
216
+ return this.DataLoader;
217
+ }
218
+ try {
219
+ const mod = await import('dataloader' + '');
220
+ const DataLoader = mod.default;
221
+ return (this.DataLoader ??= DataLoader);
222
+ }
223
+ catch {
224
+ /* v8 ignore next 2 */
225
+ throw new Error('DataLoader is not found, make sure `dataloader` package is installed in your project\'s dependencies.');
226
+ }
227
+ }
213
228
  }