joist-core 2.3.0-next.86 → 2.3.0-next.88

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 (93) hide show
  1. package/build/EntityManager.cjs.map +1 -1
  2. package/build/EntityManager.d.cts +3 -3
  3. package/build/EntityManager.d.cts.map +1 -1
  4. package/build/EntityManager.d.mts +3 -3
  5. package/build/EntityManager.d.mts.map +1 -1
  6. package/build/EntityManager.js.map +1 -1
  7. package/build/expressions/case.cjs +71 -0
  8. package/build/expressions/case.cjs.map +1 -0
  9. package/build/expressions/case.d.cts +57 -0
  10. package/build/expressions/case.d.cts.map +1 -0
  11. package/build/expressions/case.d.mts +57 -0
  12. package/build/expressions/case.d.mts.map +1 -0
  13. package/build/expressions/case.js +68 -0
  14. package/build/expressions/case.js.map +1 -0
  15. package/build/expressions/coalesce.cjs +25 -0
  16. package/build/expressions/coalesce.cjs.map +1 -0
  17. package/build/expressions/coalesce.d.cts +21 -0
  18. package/build/expressions/coalesce.d.cts.map +1 -0
  19. package/build/expressions/coalesce.d.mts +21 -0
  20. package/build/expressions/coalesce.d.mts.map +1 -0
  21. package/build/expressions/coalesce.js +22 -0
  22. package/build/expressions/coalesce.js.map +1 -0
  23. package/build/expressions/codecs.cjs +112 -0
  24. package/build/expressions/codecs.cjs.map +1 -0
  25. package/build/expressions/codecs.d.cts +11 -0
  26. package/build/expressions/codecs.d.cts.map +1 -0
  27. package/build/expressions/codecs.d.mts +11 -0
  28. package/build/expressions/codecs.d.mts.map +1 -0
  29. package/build/expressions/codecs.js +111 -0
  30. package/build/expressions/codecs.js.map +1 -0
  31. package/build/expressions/expression.cjs +99 -0
  32. package/build/expressions/expression.cjs.map +1 -0
  33. package/build/expressions/expression.d.cts +23 -0
  34. package/build/expressions/expression.d.cts.map +1 -0
  35. package/build/expressions/expression.d.mts +23 -0
  36. package/build/expressions/expression.d.mts.map +1 -0
  37. package/build/expressions/expression.js +94 -0
  38. package/build/expressions/expression.js.map +1 -0
  39. package/build/expressions/greatest.cjs +25 -0
  40. package/build/expressions/greatest.cjs.map +1 -0
  41. package/build/expressions/greatest.d.cts +21 -0
  42. package/build/expressions/greatest.d.cts.map +1 -0
  43. package/build/expressions/greatest.d.mts +21 -0
  44. package/build/expressions/greatest.d.mts.map +1 -0
  45. package/build/expressions/greatest.js +22 -0
  46. package/build/expressions/greatest.js.map +1 -0
  47. package/build/expressions/least.cjs +25 -0
  48. package/build/expressions/least.cjs.map +1 -0
  49. package/build/expressions/least.d.cts +21 -0
  50. package/build/expressions/least.d.cts.map +1 -0
  51. package/build/expressions/least.d.mts +21 -0
  52. package/build/expressions/least.d.mts.map +1 -0
  53. package/build/expressions/least.js +22 -0
  54. package/build/expressions/least.js.map +1 -0
  55. package/build/expressions/nullIf.cjs +27 -0
  56. package/build/expressions/nullIf.cjs.map +1 -0
  57. package/build/expressions/nullIf.d.cts +22 -0
  58. package/build/expressions/nullIf.d.cts.map +1 -0
  59. package/build/expressions/nullIf.d.mts +22 -0
  60. package/build/expressions/nullIf.d.mts.map +1 -0
  61. package/build/expressions/nullIf.js +24 -0
  62. package/build/expressions/nullIf.js.map +1 -0
  63. package/build/expressions/parseExpression.cjs +70 -0
  64. package/build/expressions/parseExpression.cjs.map +1 -0
  65. package/build/expressions/parseExpression.d.cts +19 -0
  66. package/build/expressions/parseExpression.d.cts.map +1 -0
  67. package/build/expressions/parseExpression.d.mts +19 -0
  68. package/build/expressions/parseExpression.d.mts.map +1 -0
  69. package/build/expressions/parseExpression.js +65 -0
  70. package/build/expressions/parseExpression.js.map +1 -0
  71. package/build/expressions/types.cjs +1 -0
  72. package/build/expressions/types.d.cts +94 -0
  73. package/build/expressions/types.d.cts.map +1 -0
  74. package/build/expressions/types.d.mts +94 -0
  75. package/build/expressions/types.d.mts.map +1 -0
  76. package/build/expressions/types.js +1 -0
  77. package/build/index.cjs +2 -0
  78. package/build/index.cjs.map +1 -1
  79. package/build/index.d.cts +4 -1
  80. package/build/index.d.cts.map +1 -1
  81. package/build/index.d.mts +4 -1
  82. package/build/index.d.mts.map +1 -1
  83. package/build/index.js +2 -1
  84. package/build/index.js.map +1 -1
  85. package/build/query.cjs +8 -1
  86. package/build/query.cjs.map +1 -1
  87. package/build/query.d.cts +26 -26
  88. package/build/query.d.cts.map +1 -1
  89. package/build/query.d.mts +26 -26
  90. package/build/query.d.mts.map +1 -1
  91. package/build/query.js +8 -1
  92. package/build/query.js.map +1 -1
  93. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"EntityManager.cjs","names":["#entitiesArray","#maybePendingFlushEntities","#entitiesById","#entitiesByTag","#indexManager","IndexManager","#pendingPercolate","#joinRows","#rm","ReactionsManager","#fl","FlushLock","#hooks","#preloader","noopFieldLogger","IsLoadedCache","PluginManager","#isLoadedCache","#hasAnyDeletes","#pendingDeletes","keyToNumber","getMetadata","#merging","getOrSet","JoinRows","#preloadedRelations","#isValidating","#fieldLogger","#dataloaders","#batchLoaders","#isRefreshing","getInstanceData","#assertFindAllowed","mergeFindOptions","findPaginatedDataLoader","findDataLoader","parseUserQuery","isMutation","parseStatement","decodeStatementResult","#findRestricted","PojoRowData","findByUniqueDataLoader","mergeCountOptions","findCountDataLoader","isSelectAllFilter","findIdsDataLoader","findOrCreateDataLoader","#doCreate","upsert","getField","isEntity","asConcreteCstr","ManyToOneReferenceImpl","PolymorphicReferenceImpl","ReactiveReferenceImpl","fail","getConstructorFromTaggedId","toTaggedId","loadBatchLoader","tagId","loadLens","AsyncMethodPopulateSecret","toArray","isLoadedForPopulate","populateBatchLoader","createTodos","runInTrustedContext","groupBy","setAsyncDefaults","#flush","Todo","combineJoinRows","AsyncPropertyImpl","LazyFieldImpl","RecursiveCycleError","getBaseAndSelfMetas","ValidationErrors","constraintNameToValidationError","getRelationEntries","partition","getRelations","keyToTaggedId","newEntity","#doRegister","failIfAnyRejected","NoIdError","DataLoader","BatchLoader","ReactionLogger","FieldLogger","getMetadataForType","hasAnyKey","entityMatches","getConstructorFromTag","deepNormalizeHint","getBaseMeta","#createCounter","#assignTimestamps","isLoadedReference","followReverseHint","getBaseSelfAndSubMetas","OneToManyCollection","OneToOneReferenceImpl","CustomCollection","CustomReference"],"sources":["../src/EntityManager.ts"],"sourcesContent":["import DataLoader, { type BatchLoadFn, type Options } from \"dataloader\";\n\nimport { getInstanceData } from \"./BaseEntity.ts\";\nimport { BatchLoader } from \"./batchloaders/BatchLoader.ts\";\nimport { type enumCollectionLoadOperation } from \"./batchloaders/enumCollectionBatchLoader.ts\";\nimport { loadBatchLoader, type loadOperation } from \"./batchloaders/loadBatchLoader.ts\";\nimport { type manyToManyLoadOperation } from \"./batchloaders/manyToManyBatchLoader.ts\";\nimport { type oneToManyLoadOperation } from \"./batchloaders/oneToManyBatchLoader.ts\";\nimport { type oneToOneLoadOperation } from \"./batchloaders/oneToOneBatchLoader.ts\";\nimport { populateBatchLoader, type populateOperation } from \"./batchloaders/populateBatchLoader.ts\";\nimport { type recursiveChildrenOperation } from \"./batchloaders/recursiveChildrenBatchLoader.ts\";\nimport { type recursiveM2mOperation } from \"./batchloaders/recursiveM2mBatchLoader.ts\";\nimport { type recursiveParentsOperation } from \"./batchloaders/recursiveParentsBatchLoader.ts\";\nimport { type ConfigData, type ReactiveRule, constraintNameToValidationError } from \"./config.ts\";\nimport { getConstructorFromTag, getMetadataForType } from \"./configure.ts\";\nimport { findByUniqueDataLoader, type findByUniqueOperation } from \"./dataloaders/findByUniqueDataLoader.ts\";\nimport { findCountDataLoader, type findCountOperation, mergeCountOptions } from \"./dataloaders/findCountDataLoader.ts\";\nimport { findDataLoader, type findOperation } from \"./dataloaders/findDataLoader.ts\";\nimport { findIdsDataLoader, type findIdsOperation } from \"./dataloaders/findIdsDataLoader.ts\";\nimport { entityMatches, findOrCreateDataLoader } from \"./dataloaders/findOrCreateDataLoader.ts\";\nimport { findPaginatedDataLoader } from \"./dataloaders/findPaginatedDataLoader.ts\";\nimport { type lensOperation } from \"./dataloaders/lensDataLoader.ts\";\nimport { type manyToManyFindOperation } from \"./dataloaders/manyToManyFindDataLoader.ts\";\nimport { type oneToManyFindOperation } from \"./dataloaders/oneToManyFindDataLoader.ts\";\nimport { setAsyncDefaults, setSyncDefaults } from \"./defaults.ts\";\nimport { type Driver } from \"./drivers/index.ts\";\n// We alias `Entity => EntityW` to denote \"Entity wide\" i.e. the non-narrowed Entity\nimport { type Entity, type Entity as EntityW, type IdType, isEntity } from \"./Entity.ts\";\nimport {\n type CheckMutation,\n type ExecuteResult,\n type MutationInput,\n type MutationRow,\n decodeStatementResult,\n isMutation,\n parseStatement,\n} from \"./execute.ts\";\nimport { getField, setField } from \"./fields.ts\";\nimport { FlushLock } from \"./FlushLock.ts\";\nimport {\n CustomCollection,\n CustomReference,\n type DeepPartialOrNull,\n type EntityHook,\n type EntityMetadata,\n type EnumField,\n type ExpressionFilter,\n type Field,\n type FieldColumn,\n FieldLogger,\n type FieldLoggerWatch,\n type FindFilter,\n type GraphQLFilterOf,\n type GraphQLFilterWithAlias,\n type InstanceData,\n type Lens,\n NoIdError,\n OneToManyCollection,\n type ParsedFindQuery,\n type PartialOrNull,\n type Plugin,\n PolymorphicReferenceImpl,\n ReactionLogger,\n type ReactiveHint,\n type Reference,\n type TimestampSerde,\n type UniqueFilter,\n type ValidationError,\n ValidationErrors,\n type ValidationRule,\n type ValidationRuleInternal,\n type ValidationRuleResult,\n asConcreteCstr,\n assertLoaded,\n deepNormalizeHint,\n getBaseAndSelfMetas,\n getBaseMeta,\n getBaseSelfAndSubMetas,\n getConstructorFromTaggedId,\n getMetadata,\n getRelationEntries,\n getRelations,\n isLoadedReference,\n keyToNumber,\n keyToTaggedId,\n loadLens,\n mergeFindOptions,\n optimizeCollectionJoins,\n setOpts,\n tagId,\n toTaggedId,\n} from \"./index.ts\";\nimport { IndexManager } from \"./IndexManager.ts\";\nimport { IsLoadedCache } from \"./IsLoadedCache.ts\";\nimport { JoinRows, type ManyToManyLike } from \"./JoinRows.ts\";\nimport {\n type LoadHint,\n type Loaded,\n type NestedLoadHint,\n type New,\n type RelationsIn,\n isLoadedForPopulate,\n} from \"./loadHints.ts\";\nimport { type WriteFn } from \"./logging/FactoryLogger.ts\";\nimport { noopFieldLogger } from \"./logging/FieldLogger.ts\";\nimport { type ReactionWalk } from \"./logging/ReactionLogger.ts\";\nimport { newEntity } from \"./newEntity.ts\";\nimport { resetFactoryCreated } from \"./newTestInstance.ts\";\nimport { type PendingChange } from \"./PendingChanges.ts\";\nimport { PluginManager } from \"./PluginManager.ts\";\nimport { type PreloadPlugin } from \"./plugins/PreloadPlugin.ts\";\nimport {\n type CheckSetQuery,\n type EntityQuery,\n type QueryArg,\n type QueryJoins,\n type QueryRow,\n type QuerySelect,\n type QuerySource,\n type SetOperand,\n type SetQuery,\n type SetQueryRow,\n type Subquery,\n parseUserQuery,\n} from \"./query.ts\";\nimport { ReactionsManager } from \"./ReactionsManager.ts\";\nimport { followReverseHint } from \"./reactiveHints.ts\";\nimport { type AbstractRelationImpl } from \"./relations/AbstractRelationImpl.ts\";\nimport { AsyncPropertyImpl } from \"./relations/AsyncProperty.ts\";\nimport { type Collection } from \"./relations/Collection.ts\";\nimport { AsyncMethodPopulateSecret } from \"./relations/hasAsyncMethod.ts\";\nimport { ManyToOneReferenceImpl, OneToOneReferenceImpl, ReactiveReferenceImpl } from \"./relations/index.ts\";\nimport { LazyFieldImpl, type lazyColumnLoadOperation } from \"./relations/LazyField.ts\";\nimport { RecursiveCycleError } from \"./relations/RecursiveCollection.ts\";\nimport { PojoRowData, type RowData } from \"./RowData.ts\";\nimport { isSelectAllFilter } from \"./scopes.ts\";\nimport { type JoinRowTodo, Todo, combineJoinRows, createTodos, getTodo } from \"./Todo.ts\";\nimport { runInTrustedContext } from \"./trusted.ts\";\nimport { type OptsOf, type OrderOf } from \"./typeMap.ts\";\nimport { upsert } from \"./upsert.ts\";\nimport {\n type MaybePromise,\n assertNever,\n fail,\n failIfAnyRejected,\n getOrSet,\n groupBy,\n hasAnyKey,\n partition,\n toArray,\n} from \"./utils.ts\";\n\n// polyfill\n(Symbol as any).asyncDispose ??= Symbol(\"Symbol.asyncDispose\");\n\n/**\n * The constructor for concrete entity types.\n *\n * Abstract entity types, like a base `Publisher` class that is marked `abstract`, cannot\n * implement this and instead only have the `AbsEntityConstructor` type.\n */\nexport interface EntityConstructor<T> {\n /** The pseudo-public constructor for entities; only the `EntityManager` should actually instantiate entities. */\n new (em: EntityManager<any, any, any>): T;\n\n // Use any for now to pass the `.includes` test in `EntityConstructor.test.ts`. We could\n // probably do some sort of `tagOf(T)` look up, similar to filter types, which would return\n // either the string literal for a real `T`, or `any` if using `EntityConstructor<any>`.\n tagName: any;\n metadata: EntityMetadata;\n /** Returns the private `InstanceData` for the given entity. */\n // This isn't really necessary but prevents type errors with unions like `Author | Book`\n getInstanceData(entity: Entity): InstanceData;\n}\n\n/** Options for the auto-batchable `em.find` queries. */\nexport interface FindFilterOptions<T extends Entity> {\n conditions?: ExpressionFilter;\n orderBy?: OrderOf<T> | OrderOf<T>[];\n limit?: number | undefined;\n offset?: number | undefined;\n softDeletes?: \"include\" | \"exclude\";\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n}\n\nexport interface FindGqlFilterOptions<T extends Entity> extends Omit<FindFilterOptions<T>, \"limit\" | \"offset\"> {\n limit?: number | null | undefined;\n offset?: number | null | undefined;\n}\n\n/** Options for the `findCount`. */\nexport interface FindCountFilterOptions<T extends Entity> {\n conditions?: ExpressionFilter;\n softDeletes?: \"include\" | \"exclude\";\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n}\n\n/**\n * Constructors for either concrete or abstract entity types.\n *\n * I.e. this is more like \"MaybeAbstractEntityConstructor\".\n */\nexport type MaybeAbstractEntityConstructor<T> = abstract new (em: EntityManager<any, any, any>, opts: any) => T;\n\n/** Pulls the entity's id type out of a given entity type T. */\nexport type IdOf<T> = T extends { id: infer I } ? I : never;\n\nexport type TaggedId = string;\n\nexport function isId(value: any): value is IdOf<unknown> {\n return value && typeof value === \"string\";\n}\n\nexport type EntityManagerHook = \"beforeBegin\" | \"afterBegin\" | \"beforeCommit\" | \"afterCommit\";\n\ntype HookFn<TX> = (em: EntityManager, txn: TX) => MaybePromise<any>;\n\nexport type LoaderCache = Record<string, DataLoader<any, any>>;\n\nexport interface TimestampFields {\n updatedAt: string | undefined;\n createdAt: string | undefined;\n deletedAt: string | undefined;\n}\n\nexport type EntityManagerOpts<TX = unknown> = (\n | { driver: Driver<TX>; em?: undefined }\n | { driver?: undefined; em: EntityManager<any, any, any> }\n) & { preloadPlugin?: PreloadPlugin };\n\nexport interface FlushOptions {\n /** Skip all validations, including reactive validations, when flushing */\n skipValidation?: boolean;\n}\n\n/**\n * Describes the EntityManager read/write mode.\n *\n * - `read-only` -- any entity mutations or `em.flush` calls will fail fast\n * - `in-memory-writes` -- allows entity mutations and `em.flush` w/o a `COMMIT`\n * - `writes` -- allows entity mutations and `em.flush` will `COMMIT` writes\n */\nexport type EntityManagerMode = \"read-only\" | \"in-memory-writes\" | \"writes\";\n\nexport type FindOperation =\n | typeof findOperation\n | typeof findByUniqueOperation\n | typeof findCountOperation\n | typeof findIdsOperation\n | typeof lensOperation\n | typeof loadOperation\n | typeof manyToManyLoadOperation\n | typeof manyToManyFindOperation\n | typeof enumCollectionLoadOperation\n | typeof oneToManyLoadOperation\n | typeof oneToManyFindOperation\n | typeof oneToOneLoadOperation\n | typeof populateOperation\n | typeof recursiveChildrenOperation\n | typeof recursiveM2mOperation\n | typeof recursiveParentsOperation\n | typeof lazyColumnLoadOperation;\n\n/**\n * The EntityManager is the primary way nearly all code, i.e. anything that finds/creates/updates/deletes entities,\n * will interact with the database.\n *\n * It acts both an Identity Cache (preventing loading the same row twice into memory as separate entities, and then\n * having drift between the two instances) and as a Unit of Work (tracking all changes to entities and then batch\n * flushing only the entities that have changed).\n *\n * Note that the type parameters (C, I, and Entity) will be filled in by codegen with the values specific to your\n * application, so you can import your app-specific EntityManager like:\n *\n * ```ts\n * import { EntityManager } from \"src/entities\";\n * ```\n *\n * @param C The type of your application-specific app-wide/request-wide Context object that will be passed to hooks\n * @typeParam C - the application-specific context (typically the request-level context)\n * @typeParam Entity - the application's based entity type (i.e. with number ids or string ids)\n * @typeParamTX - the application's Transaction type, i.e. `Knex`\n */\nexport class EntityManager<C = unknown, Entity extends EntityW = EntityW, TX extends unknown = unknown> {\n public readonly ctx: C;\n public driver: Driver<TX>;\n /** When we're flushing, the connection/transaction. */\n public txn: TX | undefined;\n public entityLimit: number = defaultEntityLimit;\n readonly #entitiesArray: Entity[] = [];\n // Incrementally track dirty entities so we don't have to scan `#entityArray` during flush\n readonly #maybePendingFlushEntities: Set<Entity> = new Set();\n // Indexes the currently loaded entities by their tagged ids and `toTaggedString` ids (i.e. `a#`). This fixes\n // real-world performance issues where `findExistingInstance` scanning `#entities` was an `O(n^2)`.\n readonly #entitiesById: Map<string, Entity> = new Map();\n readonly #entitiesByTag: Map<string, Entity[]> = new Map();\n // Provides field-based indexing for entity types with >1000 entities to optimize findWithNewOrChanged\n readonly #indexManager = new IndexManager();\n #isValidating: boolean = false;\n // Set while regular (pre-flush) validation rules run, so `em.find*` can fail fast (see #assertFindAllowed)\n #findRestricted: boolean = false;\n readonly #pendingPercolate: Map<string, Map<string, { adds: Entity[]; removes: Entity[] }>> = new Map();\n #preloadedRelations: Map<string, Map<string, Entity[]>> = new Map();\n /**\n * Tracks cascade deletes.\n *\n * We originally used a beforeDelete lifecycle hook to implement this, but tracking this\n * individually allows us to a) recursively cascade deletes even during the 1st iteration\n * of our `flush` loop, and b) cascade deletions before we recalc fields & run user hooks,\n * so that both see the most accurate state.\n */\n #pendingDeletes: Entity[] = [];\n #hasAnyDeletes = false;\n #dataloaders: Record<string, LoaderCache> = {};\n #batchLoaders: Record<string, Record<string, BatchLoader<any>>> = {};\n readonly #joinRows: Record<string, JoinRows> = {};\n /** Stores any `source -> downstream` reactions to recalc during `em.flush`. */\n readonly #rm = new ReactionsManager(this);\n /** Ensures our `em.flush` method is not interrupted. */\n readonly #fl = new FlushLock();\n readonly #hooks: Record<EntityManagerHook, HookFn<any>[]> = {\n beforeBegin: [],\n afterBegin: [],\n beforeCommit: [],\n afterCommit: [],\n };\n readonly #preloader: PreloadPlugin | undefined;\n #fieldLogger: FieldLogger = noopFieldLogger;\n #isLoadedCache = new IsLoadedCache();\n #merging: Set<EntityW> | undefined;\n /** Track `a#1`, `a#2`, etc indexes for `em.create`-d entities. */\n #createCounter: Map<string, number> | undefined = undefined;\n private __api: EntityManagerInternalApi;\n #isRefreshing = false;\n mode: EntityManagerMode = \"writes\";\n\n constructor(ctx: C, opts: EntityManagerOpts<TX>);\n constructor(ctx: C, driver: Driver<TX>);\n constructor(ctx: C, driverOrOpts: EntityManagerOpts<TX> | Driver<TX>) {\n const opts = (\n driverOrOpts.constructor === Object ? driverOrOpts : { driver: driverOrOpts }\n ) as EntityManagerOpts<TX>;\n this.ctx = ctx;\n this.driver = opts.driver ?? opts.em!.driver;\n this.#preloader = opts.preloadPlugin ?? (opts.em ? opts.em.#preloader : this.driver.defaultPlugins.preloadPlugin);\n\n const pluginManager = new PluginManager(this);\n\n if (opts.em) {\n this.#hooks = {\n beforeBegin: [...opts.em.#hooks.beforeBegin],\n afterBegin: [...opts.em.#hooks.afterBegin],\n beforeCommit: [...opts.em.#hooks.beforeCommit],\n afterCommit: [...opts.em.#hooks.afterCommit],\n };\n opts.em.__api.pluginManager.cloneTo(pluginManager);\n }\n\n // Expose some of our private fields as the EntityManagerInternalApi\n const em = this;\n\n this.__api = {\n preloader: this.#preloader,\n pendingPercolate: this.#pendingPercolate,\n mutatedCollections: new Set(),\n pendingLoads: new Set(),\n hooks: this.#hooks,\n rm: this.#rm,\n indexManager: this.#indexManager,\n isLoadedCache: this.#isLoadedCache,\n pluginManager,\n\n markMaybePending(entity: EntityW): void {\n em.#maybePendingFlushEntities.add(entity as Entity);\n },\n\n unmarkMaybePending(entity: EntityW): void {\n em.#maybePendingFlushEntities.delete(entity as Entity);\n },\n\n hasAnyDeletes(): boolean {\n return em.#hasAnyDeletes;\n },\n\n pendingDeleteIds(type: MaybeAbstractEntityConstructor<Entity>): readonly IdType[] {\n return em.#pendingDeletes\n .filter((entity) => entity instanceof type && entity.idMaybe !== undefined)\n .map((entity) => keyToNumber(getMetadata(entity), entity.id));\n },\n\n isMerging(entity: EntityW): boolean {\n return em.#merging?.has(entity) ?? false;\n },\n\n joinRows(m2m: ManyToManyLike): JoinRows {\n return getOrSet(em.#joinRows, m2m.joinTableName, () => new JoinRows(m2m, em.#rm));\n },\n\n /** Returns `a:1.books` if it's in our preload cache. */\n getPreloadedRelation<U>(taggedId: string, fieldName: string): U[] | undefined {\n return em.#preloadedRelations.get(taggedId)?.get(fieldName) as U[] | undefined;\n },\n\n /** Stores `a:1.books` in our preload cache. */\n setPreloadedRelation<U>(taggedId: string, fieldName: string, children: U[]): void {\n let map = em.#preloadedRelations.get(taggedId);\n if (!map) {\n map = new Map();\n em.#preloadedRelations.set(taggedId, map);\n }\n map.set(fieldName, children as any);\n },\n\n get isValidating() {\n return em.#isValidating;\n },\n\n checkWritesAllowed(): void {\n if (em.mode === \"read-only\") throw new ReadOnlyError();\n return em.#fl.checkWritesAllowed();\n },\n\n get fieldLogger() {\n return em.#fieldLogger;\n },\n\n clearDataloaders() {\n em.#dataloaders = {};\n em.#batchLoaders = {};\n },\n\n clearPreloadedRelations() {\n em.#preloadedRelations = new Map();\n },\n\n setIsRefreshing(isRefreshing: boolean) {\n em.#isRefreshing = isRefreshing;\n },\n };\n }\n\n /** Returns a read-only shallow copy of the currently-loaded entities. */\n get entities(): ReadonlyArray<Entity> {\n return [...this.#entitiesArray];\n }\n\n /** Returns a list of all pending creates, updates, deletes, and m2m changes that would be flushed. */\n get pendingChanges(): PendingChange[] {\n const changes: PendingChange[] = [];\n for (const entity of this.#entitiesArray) {\n const op = getInstanceData(entity).pendingOperation;\n switch (op) {\n case \"insert\":\n changes.push({ kind: \"create\", entity });\n break;\n case \"update\":\n changes.push({ kind: \"update\", entity });\n break;\n case \"delete\":\n changes.push({ kind: \"delete\", entity });\n break;\n }\n }\n for (const joinRows of Object.values(this.#joinRows)) {\n const todo = joinRows.toTodo();\n // Enum m2ms (EnumCollections) aren't entity-to-entity, so skip them here.\n if (todo && !todo.m2m.otherEnum) {\n for (const row of todo.newRows) {\n const entities = Object.values(row.columns) as [Entity, Entity];\n changes.push({ kind: \"m2m\", op: \"add\", joinTableName: todo.m2m.joinTableName, entities });\n }\n for (const row of todo.deletedRows) {\n const entities = Object.values(row.columns) as [Entity, Entity];\n changes.push({ kind: \"m2m\", op: \"remove\", joinTableName: todo.m2m.joinTableName, entities });\n }\n }\n }\n return changes;\n }\n\n /** Returns a read-only list of the currently-loaded entities of `type`. */\n getEntities<T extends Entity>(type: MaybeAbstractEntityConstructor<T>): ReadonlyArray<T> {\n const meta = getMetadata(type);\n const entities = this.#entitiesByTag.get(meta.tagName) ?? [];\n // If we're a subtype, `entities` might have base/other subtypes\n return (meta.baseType ? entities.filter((e) => e instanceof type) : entities) as T[];\n }\n\n /** Looks up `id` in the list of already-loaded entities. */\n getEntity<T extends Entity & { id: string }>(id: IdOf<T>): T | undefined;\n getEntity(id: TaggedId): Entity | undefined;\n getEntity(id: TaggedId): Entity | undefined {\n // Skip this both for performance + we allow toTaggedString-style `a#1` ids\n // assertIdIsTagged(id);\n return this.#entitiesById.get(id);\n }\n\n /**\n * Finds entities of `type` with the `where` filter, with auto-batching, so this method\n * will not cause N+1s if called in a loop.\n *\n * The `where` filter is one of Joist's \"join literals\", which can combine both joining into\n * related entities and simple column conditions in a single literal. All conditions are ANDed.\n * For more complex conditions, use the `find` overload that has a `conditions` option.\n *\n * This method is batch-friendly, i.e. if called in a loop, it will be automatically batched\n * to avoid N+1s, including queries that use `LIMIT` or `OFFSET`.\n */\n public async find<T extends EntityW>(type: MaybeAbstractEntityConstructor<T>, where: FindFilter<T>): Promise<T[]>;\n public async find<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options?: FindFilterOptions<T> & { populate?: H },\n ): Promise<Loaded<T, H>[]>;\n async find<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options?: FindFilterOptions<T> & { populate?: any },\n ): Promise<T[]> {\n this.#assertFindAllowed(\"find\");\n const { populate, ...rest } = options || {};\n const normalized = mergeFindOptions(where, rest);\n const settings = { where: normalized.where, ...normalized.options };\n const result = await (\n hasPaginationSettings(normalized.options)\n ? findPaginatedDataLoader(this, type, settings, populate)\n : findDataLoader(this, type, settings, populate)\n ).catch(function find(err) {\n throw appendStack(err, new Error());\n });\n if (populate) {\n await this.populate(result, populate);\n }\n return result;\n }\n\n /**\n * Runs a SQL-shaped query written as an object literal, and returns typed rows.\n *\n * ```ts\n * const [a, b] = tables(Author, Book);\n * const rows = await em.query({\n * from: a,\n * join: [{ left: b, on: b.author_id.eq(a.id) }],\n * where: { and: [a.age.gte(minAge)] },\n * groupBy: [a.first_name],\n * select: { name: a.first_name, bookCount: b.id.count() },\n * orderBy: { bookCount: \"DESC\" },\n * });\n * // → { name: string; bookCount: number }[]\n * ```\n *\n * `select` decides the row type: a bare table (`select: a`) returns entities through the identity\n * map, a `{ key: expr }` object returns typed POJOs, and a `query(...)` value returns its rows. Joins\n * are pruned like `em.find`: an `undefined` condition drops out, and a join nothing references\n * anymore drops with it. See `query.ts` for the full DSL, and `query()` for composing subqueries.\n *\n * Entity selections accept a second argument, `{ populate: hint }`, and return `Loaded` entities.\n * Population runs after the query, using the same relation loaders as `em.populate`.\n * This method is not batched: these are custom queries, too unique to batch.\n */\n public query<R>(q: Subquery<R, any>): Promise<R[]>;\n public query<T extends Entity>(q: EntityQuery<T>): Promise<T[]>;\n public query<T extends Entity, const H extends LoadHint<T>>(\n q: EntityQuery<T>,\n options: { populate: H },\n ): Promise<Loaded<T, H>[]>;\n public query<const Q extends SetQuery<readonly SetOperand[]>>(q: Q & CheckSetQuery<Q>): Promise<SetQueryRow<Q>[]>;\n public query<F extends QuerySource, S extends QuerySelect = never, J extends QueryJoins = []>(\n q: QueryArg<F, S, J, never>,\n ): Promise<QueryRow<S, J>[]>;\n public query<\n F extends QuerySource,\n S extends QuerySelect,\n const H extends LoadHint<Extract<QueryRow<S, J>, EntityW>>,\n J extends QueryJoins = [],\n >(\n q: QueryArg<F, S, J, never>,\n options: QueryRow<S, J> extends EntityW ? { populate: H } : never,\n ): Promise<Loaded<Extract<QueryRow<S, J>, EntityW>, H>[]>;\n public query(q: unknown, options?: { populate: LoadHint<EntityW> }): Promise<any[]> {\n this.#assertFindAllowed(\"query\");\n const em = this;\n return (async function query() {\n const plan = parseUserQuery(q);\n if (options?.populate && plan.output.kind !== \"entity\") {\n fail(\"em.query populate requires an entity selection\");\n }\n const { rows } = await em.driver.executeQuery(em, plan.sql, plan.bindings);\n const result = plan.decodeRows(em, rows);\n if (options?.populate) {\n await em.populate(result, options.populate);\n }\n return result;\n })().catch(function query(err) {\n throw appendStack(err, new Error());\n });\n }\n\n /**\n * Executes immediate SQL with a native command count. Mutations bypass the entity unit of work;\n * reads retain query's decoding and permissions. Neither path flushes or repairs cached entities.\n */\n public execute<const M extends MutationInput>(\n statement: M & CheckMutation<M>,\n ): Promise<ExecuteResult<MutationRow<M>>>;\n public execute<R>(statement: Subquery<R, any>): Promise<ExecuteResult<R>>;\n public execute<T extends Entity>(statement: EntityQuery<T>): Promise<ExecuteResult<T>>;\n public execute<const Q extends SetQuery<readonly SetOperand[]>>(\n statement: Q & CheckSetQuery<Q>,\n ): Promise<ExecuteResult<SetQueryRow<Q>>>;\n public execute<F extends QuerySource, S extends QuerySelect = never, J extends QueryJoins = []>(\n statement: QueryArg<F, S, J, never>,\n ): Promise<ExecuteResult<QueryRow<S, J>>>;\n public execute(statement: unknown): Promise<ExecuteResult<unknown>> {\n const em = this;\n return (async function execute() {\n if (isMutation(statement)) {\n em.__api.checkWritesAllowed();\n if (em.mode === \"in-memory-writes\") fail(\"SQL mutations do not support in-memory-writes mode\");\n } else {\n em.#assertFindAllowed(\"execute\");\n }\n const plan = parseStatement(statement);\n if (!plan) return { rowCount: 0, rows: [] };\n const result = await em.driver.executeQuery(em, plan.sql, plan.bindings);\n return decodeStatementResult(em, plan, result);\n })().catch(function execute(err) {\n throw appendStack(err, new Error());\n });\n }\n\n /** Fails fast if `em.${method}` is called from a regular validation rule, i.e. steers to `config.addCommitRule`. */\n #assertFindAllowed(method: string): void {\n if (this.#findRestricted) {\n throw new Error(\n `em.${method} cannot be called from a validation rule (added via config.addRule), because rules run ` +\n `before the flush and would query stale, pre-flush data. Use config.addCommitRule instead, which runs ` +\n `after the INSERT/UPDATE/DELETEs are flushed (within the same transaction) and so sees the changed state.`,\n );\n }\n }\n\n /** Runs the post-parse find pipeline: plugins mutate the logical AST, then Joist optimizes/prunes before SQL. */\n private async executeFind(\n meta: EntityMetadata,\n operation: FindOperation,\n parsed: ParsedFindQuery,\n settings: {\n limit?: number;\n offset?: number;\n checkLimit?: boolean;\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n pruneJoins?: boolean;\n keepAliases?: string[];\n },\n ) {\n const { checkLimit, findSettings } = this.prepareFind(meta, operation, parsed, settings);\n return this.executePreparedFind(meta, operation, parsed, findSettings, checkLimit);\n }\n\n /** Like {@link executeFind}, but returns a {@link RowData}; see {@link executePreparedFindRowData}. */\n private async executeFindRowData(\n meta: EntityMetadata,\n operation: FindOperation,\n parsed: ParsedFindQuery,\n settings: {\n limit?: number;\n offset?: number;\n checkLimit?: boolean;\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n pruneJoins?: boolean;\n keepAliases?: string[];\n },\n ): Promise<RowData> {\n const { checkLimit, findSettings } = this.prepareFind(meta, operation, parsed, settings);\n return this.executePreparedFindRowData(meta, operation, parsed, findSettings, checkLimit);\n }\n\n /** Executes a query that has already had find hooks and optimizations applied. */\n private async executePreparedFind(\n meta: EntityMetadata,\n operation: FindOperation,\n parsed: ParsedFindQuery,\n findSettings: {\n limit?: number;\n offset?: number;\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n pruneJoins?: boolean;\n keepAliases?: string[];\n },\n checkLimit: boolean | undefined,\n ) {\n const { pluginManager } = getEmInternalApi(this);\n const rows = await this.driver.executeFind(this, parsed, findSettings);\n // Check by default unless explicitly disabled or the caller removed the LIMIT via `limit: undefined`\n const shouldCheck = checkLimit ?? !(\"limit\" in findSettings && findSettings.limit === undefined);\n if (shouldCheck && rows.length >= this.entityLimit) {\n throw new Error(`Query returned more than ${this.entityLimit} entityLimit rows`);\n }\n if (pluginManager.hasHook(\"afterFind\")) {\n pluginManager.afterFind(meta, operation, new PojoRowData(rows));\n }\n return rows;\n }\n\n /**\n * Like {@link executePreparedFind}, but returns a {@link RowData}: lazy wire rows when the\n * driver has `lazyRows` enabled, else classic POJO rows wrapped in a `PojoRowData` — so\n * loaders can hydrate from one shape without caring which the driver provides.\n */\n private async executePreparedFindRowData(\n meta: EntityMetadata,\n operation: FindOperation,\n parsed: ParsedFindQuery,\n findSettings: {\n limit?: number;\n offset?: number;\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n pruneJoins?: boolean;\n keepAliases?: string[];\n },\n checkLimit: boolean | undefined,\n ): Promise<RowData> {\n const { executeFindRowData } = this.driver;\n if (executeFindRowData === undefined) {\n return new PojoRowData(await this.executePreparedFind(meta, operation, parsed, findSettings, checkLimit));\n }\n const { pluginManager } = getEmInternalApi(this);\n const rowData = await executeFindRowData.call(this.driver, this, parsed, findSettings);\n // Check by default unless explicitly disabled or the caller removed the LIMIT via `limit: undefined`\n const shouldCheck = checkLimit ?? !(\"limit\" in findSettings && findSettings.limit === undefined);\n if (shouldCheck && rowData.rowCount >= this.entityLimit) {\n throw new Error(`Query returned more than ${this.entityLimit} entityLimit rows`);\n }\n // The hook receives the lazy RowData view directly, so observe-only hooks (i.e. metrics\n // reading `rowCount`) never materialize cells; hooks call `toRows()` if they want POJOs\n pluginManager.afterFind(meta, operation, rowData);\n return rowData;\n }\n\n /**\n * Runs pre-SQL find hooks and optimizations against a parsed query.\n *\n * This allows plugins to see \"pre-batched\" / \"logical\" query ASTs, instead of our\n * more complicated `_find` batched queries. The flow would be:\n *\n * - A loader calls `prepareFind(originalQuery)`\n * - Plugins inspect/modify the query as/if needed\n * - The loader crafts a new, more complicated query that embeds the originalQuery\n * - The loader calls `executePreparedFind` with the 2nd query\n */\n private prepareFind(\n meta: EntityMetadata,\n operation: FindOperation,\n parsed: ParsedFindQuery,\n settings: {\n limit?: number;\n offset?: number;\n checkLimit?: boolean;\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n pruneJoins?: boolean;\n keepAliases?: string[];\n },\n ) {\n const { checkLimit, ...findSettings } = settings;\n const { pluginManager } = getEmInternalApi(this);\n // Plugins may mutate the settings object, so return the post-hook version that loaders must reuse.\n pluginManager.beforeFind(meta, operation, parsed, findSettings);\n optimizeCollectionJoins(parsed, settings);\n return { checkLimit, findSettings };\n }\n\n /**\n * Works exactly like `find` but accepts \"less than greatly typed\" GraphQL filters.\n *\n * I.e. filtering by `null` on fields that are non-`nullable`.\n */\n public async findGql<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: GraphQLFilterWithAlias<T>,\n ): Promise<T[]>;\n public async findGql<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n where: GraphQLFilterWithAlias<T>,\n options?: FindGqlFilterOptions<T> & { populate?: H },\n ): Promise<Loaded<T, H>[]>;\n async findGql<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: GraphQLFilterOf<T>,\n options?: FindGqlFilterOptions<T> & { populate?: any },\n ): Promise<T[]> {\n if (!options) {\n return this.find(type, where as any);\n }\n const normalized = { ...options };\n if (\"limit\" in normalized) normalized.limit = normalized.limit ?? undefined;\n if (\"offset\" in normalized) normalized.offset = normalized.offset ?? undefined;\n return this.find(type, where as any, normalized as any);\n }\n\n public async findOne<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n ): Promise<T | undefined>;\n public async findOne<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options?: FindFilterOptions<T> & { populate?: H },\n ): Promise<Loaded<T, H> | undefined>;\n async findOne<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options?: FindFilterOptions<T> & { populate?: any },\n ): Promise<T | undefined> {\n const list = await this.find(type, where, options);\n if (list.length === 0) {\n return undefined;\n } else if (list.length === 1) {\n return list[0];\n } else {\n throw new TooManyError(`Found more than one: ${list.map((e) => e.toString()).join(\", \")}`);\n }\n }\n\n /** Executes a given query filter and returns exactly one result, otherwise throws `NotFoundError` or `TooManyError`. */\n public async findOneOrFail<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n ): Promise<T>;\n public async findOneOrFail<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options: FindFilterOptions<T> & { populate?: H },\n ): Promise<Loaded<T, H>>;\n async findOneOrFail<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options?: FindFilterOptions<T> & { populate?: any },\n ): Promise<T> {\n const list = await this.find(type, where, options);\n if (list.length === 0) {\n throw new NotFoundError(`Did not find ${type.name} for given query`);\n } else if (list.length > 1) {\n throw new TooManyError(`Found more than one: ${list.map((e) => e.toString()).join(\", \")}`);\n }\n return list[0];\n }\n\n public async findByUnique<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: UniqueFilter<T>,\n ): Promise<T | undefined>;\n public async findByUnique<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n where: UniqueFilter<T>,\n options?: { populate?: H; softDeletes?: \"include\" | \"exclude\" },\n ): Promise<Loaded<T, H> | undefined>;\n async findByUnique<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: UniqueFilter<T>,\n options: { populate?: any; softDeletes?: \"include\" | \"exclude\" } = {},\n ): Promise<T | undefined> {\n this.#assertFindAllowed(\"findByUnique\");\n const { populate, softDeletes = \"exclude\" } = options;\n const entries = Object.entries(where);\n if (entries.length !== 1) {\n throw new Error(\"findByUnique only accepts a single field\");\n }\n const [fieldName, value] = entries[0];\n const field = getMetadata(type).allFields[fieldName];\n const row = await findByUniqueDataLoader(this, type, field, softDeletes)\n .load(value)\n .catch(function findByUnique(err) {\n throw appendStack(err, new Error());\n });\n if (!row) {\n return undefined;\n } else {\n const [entity] = this.hydrate(type, [row]);\n if (this.#hasAnyDeletes && entity.isDeletedEntity) {\n return undefined;\n }\n if (populate) {\n await this.populate(entity, populate);\n }\n return entity;\n }\n }\n\n /**\n * Returns the count of entities that match the `where` clause.\n *\n * The `where` clause, and any options.conditions, matches the same syntax\n * as `em.find`.\n *\n * Note: this method is not currently auto-batched, so it will cause N+1s if called in a loop.\n */\n async findCount<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T> | GraphQLFilterWithAlias<T>,\n options: FindCountFilterOptions<T> = {},\n ): Promise<number> {\n this.#assertFindAllowed(\"findCount\");\n const normalized = mergeCountOptions(where, options);\n const settings = { where: normalized.where, ...normalized.options } as any;\n let count = await findCountDataLoader(this, type, settings).catch(function findCount(err) {\n throw appendStack(err, new Error());\n });\n // If the user is do \"count all\", we can adjust the number up/down based on\n // WIP creates/deletes. We can't do this if the WHERE clause is populated b/c\n // then we'd also have to eval each created/deleted entity against the WHERE\n // clause before knowing if it should adjust teh amount.\n const isSelectAll = isSelectAllFilter(where, options.conditions);\n if (isSelectAll) {\n const tagged = this.#entitiesByTag.get(getMetadata(type).tagName) ?? [];\n for (const entity of tagged) {\n // Still do an `instanceof` to handle subtypes\n if (entity instanceof type) {\n if (entity.isNewEntity) {\n count++;\n } else if (entity.isDeletedEntity) {\n count--;\n }\n }\n }\n }\n\n return count;\n }\n\n /**\n * Returns the IDs of entities that match the `where` clause.\n *\n * The `where` clause, and any options.conditions, matches the same syntax\n * as `em.find`.\n */\n async findIds<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options: FindCountFilterOptions<T> = {},\n ): Promise<string[]> {\n this.#assertFindAllowed(\"findIds\");\n const normalized = mergeCountOptions(where, options);\n const settings = { where: normalized.where, ...normalized.options };\n return findIdsDataLoader(this, type, settings).catch(function findIds(err) {\n throw appendStack(err, new Error());\n });\n }\n\n /**\n * Looks for entities that match `where`, both in the database and any just-created or just-changed entities.\n *\n * Because we evaluate this `where` clause in memory (against any WIP changes made to entities\n * that have not yet been `em.flush`ed to the database), the `where` clause is limited to fields\n * immediately available on the entity, i.e. primitives, enums, and many-to-ones, without any\n * nested, cross-table joins/conditions.\n *\n * For `m2o` fields, `undefined` will be pruned, just like `em.find`s. I.e. `{ publisher: undefined }` will\n * be pruned and not filter on `publisher` at all, where as `{ publisher: null }` will filter for `publisher`\n * is unset.\n *\n * @param type the entity type to find\n * @param where the fields to look up the existing entity by\n */\n async findWithNewOrChanged<T extends Entity, F extends Partial<OptsOf<T>>>(\n type: EntityConstructor<T>,\n where: F,\n ): Promise<T[]>;\n async findWithNewOrChanged<T extends Entity, F extends Partial<OptsOf<T>>, const H extends LoadHint<T>>(\n type: EntityConstructor<T>,\n where: F,\n options?: { populate?: H; softDeletes?: \"include\" | \"exclude\" },\n ): Promise<Loaded<T, H>[]>;\n async findWithNewOrChanged<T extends Entity, F extends Partial<OptsOf<T>>, const H extends LoadHint<T>>(\n type: EntityConstructor<T>,\n where: F,\n options?: { populate?: H; softDeletes?: \"include\" | \"exclude\" },\n ): Promise<T[]> {\n const { softDeletes = \"exclude\", populate } = options ?? {};\n // Make a copy of `where` because `em.find` will re-write new entities to `-1`, that our `entityMatches` could still match\n // ...and also prune `undefined` here, since `em.find` will do it anyway, but `entityMatches` does not.\n const copy: any = Object.fromEntries(Object.entries(where).filter(([, v]) => v !== undefined));\n const persisted = await this.find(type, copy, { softDeletes });\n const unchanged = persisted.filter((e) => !e.isNewEntity && !e.isDirtyEntity && !e.isDeletedEntity);\n const maybeNew = this.filterEntities<T>(type, where).filter(\n (e) => (e.isNewEntity || e.isDirtyEntity) && !e.isDeletedEntity,\n );\n const found = [...unchanged, ...maybeNew];\n if (populate) {\n await this.populate(found, populate as any);\n }\n return found as unknown as T[];\n }\n\n /**\n * Conditionally finds or creates (or upserts) an Entity.\n *\n * The `where` param is used to find the existing/if any entity; if not found,\n * then one will be created.\n *\n * The `ifNew` param will be used, if no entity is found, for the `em.create` call;\n * it is typed such that it will require all opts necessary for the `em.create` to\n * be valid, _unless_ those opts are already included in either the `where` or\n * `upsert` params.\n *\n * The optional `upsert` param are fields to always set/update, regardless of whether\n * the entity is created or not.\n *\n * @param type the entity type to find/create\n * @param where the fields to look up the existing entity by\n * @param ifNew the fields to set if the entity is new\n * @param upsert the fields to update if the entity is either existing or new\n */\n async findOrCreate<\n T extends EntityW,\n F extends Partial<OptsOf<T>>,\n U extends Partial<OptsOf<T>> | {},\n N extends Omit<OptsOf<T>, keyof F | keyof U>,\n >(type: EntityConstructor<T>, where: F, ifNew: N, upsert?: U): Promise<T>;\n async findOrCreate<\n T extends EntityW,\n F extends Partial<OptsOf<T>>,\n U extends Partial<OptsOf<T>> | {},\n N extends Omit<OptsOf<T>, keyof F | keyof U>,\n const H extends LoadHint<T>,\n >(\n type: EntityConstructor<T>,\n where: F,\n ifNew: N,\n upsert?: U,\n options?: { populate?: H; softDeletes?: \"include\" | \"exclude\" },\n ): Promise<Loaded<T, H>>;\n async findOrCreate<\n T extends EntityW,\n F extends Partial<OptsOf<T>>,\n U extends Partial<OptsOf<T>> | {},\n N extends Omit<OptsOf<T>, keyof F | keyof U>,\n const H extends LoadHint<T>,\n >(\n type: EntityConstructor<T>,\n where: F,\n ifNew: N,\n upsert?: U,\n options?: { populate?: H; softDeletes?: \"include\" | \"exclude\" },\n ): Promise<T> {\n const { softDeletes = \"exclude\", populate } = options ?? {};\n const entity = await findOrCreateDataLoader(this, type, where, softDeletes)\n .load({ ifNew: ifNew as OptsOf<T>, upsert })\n .catch(function findOrCreate(err) {\n throw appendStack(err, new Error());\n });\n if (populate) {\n await this.populate(entity, populate);\n }\n return entity;\n }\n\n /** Creates a new `type` and marks it as loaded, i.e. we know its collections are all safe to access in memory. */\n public create<T extends EntityW, O extends OptsOf<T>>(type: EntityConstructor<T>, opts: O): New<T, O> {\n return this.#doCreate(type, opts, false) as New<T, O>;\n }\n\n /**\n * Creates a new `type` but with `opts` that are nullable, to accept partial-update-style input.\n *\n * Note that `createPartial` doesn't support the full upsert behavior, i.e. this method:\n *\n * - always creates,\n * - does not support relation markers like `op`, `delete`, and `remove`,\n * - does not accept deep input, but\n * - fields set to `undefined` will be skipped instead of unset\n *\n * See `upsert` for the upsert/deep upsert behavior.\n */\n public createPartial<T extends EntityW>(type: EntityConstructor<T>, opts: PartialOrNull<OptsOf<T>>): T {\n return this.#doCreate(type, opts, true);\n }\n\n /**\n * Create or updates `type` based on partial-update-style `input`.\n *\n * This supports upsert behavior, i.e.:\n *\n * - findOrCreate the primary entity being updated (based on the `id` key being provided),\n * - upsert relation markers like `op`, `delete`, and `remove` are supported,\n * - deep input is supported, i.e. `{ firstName: \"Bob\", books: [{ title: \"b1\" } ] }`, and\n * - fields set to `undefined` will be skipped instead of unset\n */\n public upsert<T extends EntityW>(type: EntityConstructor<T>, input: DeepPartialOrNull<T>): Promise<T> {\n return upsert(this, type, input);\n }\n\n /**\n * Utility to clone an entity and its nested relations, as determined by a populate hint\n *\n * @param entity - Any entity\n * @param opts - Options to control the clone behaviour\n * @param deep - Populate hint of the nested tree of objects to clone\n * @param skip - Keys that will be skipped in the clone\n * @param skipIf - Predicate for determining if a specific entity should be skipped (and any entities beneath it\n * @param postClone - Function to be called for each original/clone entity for any post-processing needed\n * @returns The `Loaded` cloned entity or fails if the clone could not be made\n *\n * @example\n * // This will duplicate the author\n * const duplicatedAuthor = await em.clone(author)\n *\n * @example\n * // This will duplicate the author and all their related book entities\n * const duplicatedAuthorAndBooks = await em.clone(author, { deep: \"books\" })\n *\n * @example\n * // This will duplicate the author, all their books, and the images for those books\n * const duplicatedAuthorAndBooksAndImages = await em.clone(author, { deep: { books: \"image\" } })\n *\n * @example\n * // This will duplicate the author, and rename\n * const duplicatedAuthor = await em.clone(author, { postClone: (_original, clone) => clone.firstName = clone.firstName + \" COPY\" })\n *\n * @example\n * // This will duplicate the author, but skip any book where the title includes `sea`\n * const duplicatedAuthor = await em.clone(author, { skipIf: (original) => original.title?.includes(\"sea\") })\n */\n public async clone<T extends Entity, H extends LoadHint<T>, const K = ReactiveHint<T>>(\n entity: T,\n opts?: {\n deep?: H;\n skip?: K;\n skipIf?: (entity: Entity) => boolean;\n postClone?: (original: Entity, clone: Entity) => void;\n },\n ): Promise<Loaded<T, H>>;\n\n /**\n * Utility to clone an entity and its nested relations, as determined by a populate hint.\n *\n * @param entities - Any homogeneous list of entities\n * @param opts - Options to control the clone behaviour\n * @param deep - Populate hint of the nested tree of objects to clone\n * @param skip - Keys that will be skipped in the clone\n * @param skipIf - Predicate for determining if a specific entity should be skipped (and any entities beneath it\n * @param postClone - Function to be called for each original/clone entity for any post-processing needed\n * @returns Array of `Loaded` cloned entities from the provided list or empty array if all are skipped\n *\n * @example\n * // This will duplicate the author's books\n * const duplicatedBooks = await em.clone(author.books.get)\n *\n * @example\n * // This will duplicate the author's books, all their books, and the images for those books\n * const duplicatedBooksAndImages = await em.clone(author.books.get, { deep: { books: \"image\" } })\n *\n * @example\n * // This will duplicate the author's books, and assign them to a different author\n * const duplicatedBooks = await em.clone(author.books.get, { postClone: (_original, clone) => clone.author.set(author2) })\n *\n * @example\n * // This will duplicate the author's books, but skip any book where the title includes `sea`\n * const duplicatedBooks = await em.clone(author.books.get, { skipIf: (original) => original.title.includes(\"sea\") })\n */\n public async clone<T extends Entity, H extends LoadHint<T>, const K = ReactiveHint<T>>(\n entities: readonly T[],\n opts?: {\n deep?: H;\n skip?: K;\n skipIf?: (entity: Entity) => boolean;\n postClone?: (original: Entity, clone: Entity) => void;\n },\n ): Promise<Loaded<T, H>[]>;\n\n public async clone<T extends Entity, H extends LoadHint<T>>(\n entityOrArray: T | readonly T[],\n opts?: {\n deep?: H;\n skip?: object;\n skipIf?: (entity: Entity) => boolean;\n postClone?: (original: Entity, clone: Entity) => void;\n },\n ): Promise<Loaded<T, H> | Loaded<T, H>[]> {\n const { deep = {}, skipIf, skip = {}, postClone } = opts ?? {};\n // Keep a list that we can work against synchronously after doing the async find/crawl\n const todo = new Set<Entity>();\n const skipMap = new WeakMap<Entity, string[]>();\n\n // 1. Find all entities w/o mutating them yet\n await crawl(todo, skipMap, Array.isArray(entityOrArray) ? entityOrArray : [entityOrArray], deep, {\n skipIf: skipIf as any,\n skip,\n });\n\n // 2. Clone each found entity\n const deferredRelations: [Entity, string, Entity][] = [];\n const clones = [...todo].map((entity) => {\n const skip = skipMap.get(entity) ?? [];\n // Use meta.fields to see which fields are derived (i.e. createdAt, updatedAt, initials)\n // that only have getters, and so we shouldn't set (createdAt/updatedAt will be initialized\n // by `em.register`).\n const meta = getMetadata(entity);\n const copy = Object.fromEntries(\n Object.values(meta.allFields)\n .map((f) => {\n if (skip.includes(f.fieldName)) return undefined;\n switch (f.kind) {\n case \"primitive\":\n if (!f.derived && !f.protected) {\n return [f.fieldName, getField(entity, f.fieldName)];\n } else {\n return undefined;\n }\n case \"enum\":\n if (f.derived) {\n return undefined;\n } else {\n return [f.fieldName, getField(entity, f.fieldName)];\n }\n case \"m2o\":\n case \"poly\": {\n if (f.kind === \"m2o\" && f.derived) return undefined;\n const existingIdOrEntity = getField(entity, f.fieldName);\n const target = (\n isEntity(existingIdOrEntity) ? existingIdOrEntity : this.getEntity(existingIdOrEntity)\n ) as Entity | undefined;\n // Defer relations within the cloned subgraph because setting a clone field before remapping can update\n // its other side, and that update is not fixed up later.\n if (target && todo.has(target)) {\n deferredRelations.push([entity, f.fieldName, target]);\n return [f.fieldName, undefined];\n } else {\n return [f.fieldName, existingIdOrEntity];\n }\n }\n case \"primaryKey\":\n case \"o2m\":\n case \"m2m\":\n case \"m2mEnum\":\n case \"o2o\":\n case \"lo2m\":\n return undefined;\n default:\n assertNever(f);\n }\n })\n .filter(isDefined),\n );\n\n // Call `new` just like the user would do\n // The `asConcreteCstr` is safe b/c we got meta from a concrete/already-instantiated entity\n const clone = this.create(asConcreteCstr(meta.cstr), copy);\n\n return [entity, clone] as const;\n });\n const entityToClone: Map<EntityW, EntityW> = new Map(clones);\n\n // 3. Now mutate the m2o relations. We focus on only m2o's because they \"own\" the field/column,\n // and will drive percolation to keep the other-side o2m & o2o updated.\n clones.forEach(([, clone]) => {\n getRelationEntries(clone).forEach(([fieldName, value]) => {\n if (\n value instanceof ManyToOneReferenceImpl ||\n value instanceof PolymorphicReferenceImpl ||\n value instanceof ReactiveReferenceImpl\n ) {\n // What's the existing entity? Have we cloned it?\n const existingIdOrEntity = getField(clone, fieldName);\n // Use O(1) lookup via #entitiesById Map instead of O(N) .find() scan\n const existing = isEntity(existingIdOrEntity) ? existingIdOrEntity : this.getEntity(existingIdOrEntity);\n // If we didn't find a loaded entity for this value, assume that it a) itself is not being cloned,\n // and b) we don't need to bother telling it about the newly cloned entity\n if (existing) {\n ((clone as any)[fieldName] as any).set(entityToClone.get(existing) ?? existing);\n }\n }\n });\n });\n\n deferredRelations.forEach(([source, fieldName, target]) => {\n const clone = entityToClone.get(source)!;\n ((clone as any)[fieldName] as any).set(entityToClone.get(target)!);\n });\n\n if (postClone) {\n await Promise.all(clones.map(([original, clone]) => postClone(original, clone)));\n }\n\n return Array.isArray(entityOrArray)\n ? entityOrArray\n .filter((original) => entityToClone.has(original))\n .map((original) => entityToClone.get(original) as unknown as Loaded<T, H>)\n : clones[0]\n ? (clones[0][1] as unknown as Loaded<T, H>)\n : fail(\"no entities were cloned given the provided options\");\n }\n\n /**\n * Merges multiple source entities into a target entity by updating all references that point\n * to the source entities to instead point to the target entity.\n *\n * This method loads all relations from the source entities, updates any entity that\n * references a source entity to reference the target entity instead, and then automatically\n * deletes the source entities.\n *\n * @param target - The entity that will become the target of all merged references\n * @param sources - Array of entities whose references will be redirected to the target\n * @param opts - Options to control merge behavior\n * @param autoDelete - Whether to automatically delete source entities (default: true)\n * @returns Promise that resolves when all references have been updated and sources deleted\n *\n * @example\n * // Merge duplicate authors - all books pointing to author2 will now point to author1\n * // author2 will be automatically deleted\n * await em.merge(author1, [author2]);\n *\n * @example\n * // Merge multiple duplicate publishers into one\n * // publisher2 and publisher3 will be automatically deleted\n * await em.merge(publisher1, [publisher2, publisher3]);\n *\n * @example\n * // Merge without auto-deleting sources (for custom cleanup logic)\n * await em.merge(author1, [author2], { autoDelete: false });\n * // Custom logic here...\n * em.delete(author2);\n */\n public async merge<T extends Entity>(target: T, sources: T[], opts?: { autoDelete?: boolean }): Promise<Entity[]> {\n const autoDelete = opts?.autoDelete ?? true;\n if (sources.length === 0) return [];\n\n this.#merging ??= new Set();\n // Allow cannotBeUpdated to see that anyone pointed to the new target is allowed to change\n this.#merging.add(target);\n\n // Make sure source and target are the same type (Before we call `populate` below which will fail on invalid load hints)\n const targetMeta = getMetadata(target);\n for (const source of sources) {\n const sourceMeta = getMetadata(source);\n if (sourceMeta.type !== targetMeta.type) {\n throw new Error(`Cannot merge entities of different types: ${targetMeta.type} and ${sourceMeta.type}`);\n }\n }\n\n const fields = Object.values(targetMeta.allFields)\n .filter((field) => [\"o2m\", \"m2o\", \"m2m\", \"o2o\"].includes(field.kind))\n .map((field) => field.fieldName);\n await this.populate(sources, fields as any as LoadHint<T>);\n\n const changedEntities: Entity[] = [];\n for (const source of sources) {\n // Find all reverse relations (things that point to this entity)\n for (const field of Object.values(targetMeta.allFields)) {\n const { kind } = field;\n if (kind === \"o2m\") {\n for (const other of (source as any)[field.fieldName].get) {\n this.#merging.add(other); // Tell ReactionsManager to react to normally-read-only fields\n (other as any)[field.otherFieldName].set(target);\n changedEntities.push(other);\n }\n } else if (kind === \"o2o\") {\n const otherField = field.otherMetadata().allFields[field.otherFieldName];\n if (otherField.kind === \"m2o\" && otherField.derived) continue;\n const other = (source as any)[field.fieldName].get;\n if (other) {\n this.#merging.add(other); // Tell ReactionsManager to react to normally-read-only fields\n (other as any)[field.otherFieldName].set(target);\n changedEntities.push(other);\n }\n } else if (kind === \"m2m\") {\n for (const other of (source as any)[field.fieldName].get) {\n this.#merging.add(other); // Tell ReactionsManager to react to normally-read-only fields\n const collection = (other as any)[field.otherFieldName];\n collection.remove(source);\n collection.add(target);\n changedEntities.push(other);\n }\n } else if (\n kind === \"primitive\" ||\n kind === \"primaryKey\" ||\n kind === \"enum\" ||\n kind === \"m2mEnum\" ||\n kind === \"poly\" ||\n kind === \"m2o\" ||\n kind === \"lo2m\"\n ) {\n // These field types don't need merge handling - they're either:\n // - primitive values that don't create references (primitive, enum)\n // - primary keys that shouldn't be merged\n // - forward references that we handle from the reverse side (m2o)\n // - large collections that are handled separately (lo2m)\n } else {\n assertNever(kind);\n }\n }\n }\n\n // Auto-delete source entities if requested\n if (autoDelete) {\n for (const source of sources) this.delete(source);\n }\n\n return changedEntities;\n }\n\n /** Returns an instance of `type` for the given `id`, resolving to an existing instance if in our Unit of Work. */\n public async load<T extends EntityW & { id: string }>(id: IdOf<T>): Promise<T>;\n public async load(id: TaggedId): Promise<Entity>;\n public async load<T extends EntityW>(type: MaybeAbstractEntityConstructor<T>, id: IdOf<T> | TaggedId): Promise<T>;\n public async load<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n id: IdOf<T> | TaggedId,\n populate: H,\n ): Promise<Loaded<T, H>>;\n async load<T extends EntityW>(\n typeOrId: MaybeAbstractEntityConstructor<T> | string,\n id?: IdType,\n hint?: any,\n ): Promise<T> {\n // Handle the `typeOrId` overload\n let type: MaybeAbstractEntityConstructor<T>;\n if (typeof typeOrId === \"string\") {\n // This must be a tagged id for the 1st overload to work\n type = getConstructorFromTaggedId(typeOrId);\n id = typeOrId;\n } else {\n type = typeOrId;\n id = id || fail(`Invalid ${typeOrId.name} id: ${id}`);\n }\n const meta = getMetadata(type);\n const taggedId = toTaggedId(meta, id);\n let entity = this.findExistingInstance<T>(taggedId);\n if (!entity) {\n await loadBatchLoader(this, meta)\n .load({ taggedId, hint })\n .catch(function load(err) {\n throw appendStack(err, new Error());\n });\n entity = this.findExistingInstance<T>(taggedId);\n }\n if (!entity) {\n throw new NotFoundError(`${taggedId} was not found`);\n }\n if (hint) {\n await this.populate(entity, hint);\n }\n if (meta.inheritanceType === \"sti\" && !(entity instanceof type)) {\n throw new Error(`${entity} is ${entity.constructor.name} but should be ${type.name}`);\n }\n return entity as T;\n }\n\n /** Returns instances of `type` for the given `ids`, resolving to an existing instance if in our Unit of Work. */\n public async loadAll<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n ids: readonly string[],\n ): Promise<T[]>;\n public async loadAll<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n ids: readonly string[],\n populate: H,\n ): Promise<Loaded<T, H>[]>;\n async loadAll<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n _ids: readonly string[],\n hint?: any,\n ): Promise<T[]> {\n const meta = getMetadata(type);\n\n // Use pre-allocated arrays/for loops instead of `.filter`s since this can be a hot spot;\n // misses remember their tagged id + position so the all-hit path skips the `ids` copy entirely\n const entities = new Array<T | undefined>(_ids.length);\n let idsToLoad: string[] | undefined;\n let positionsToLoad: number[] | undefined;\n\n for (let i = 0; i < _ids.length; i++) {\n const id = tagId(meta, _ids[i]);\n const entity = this.findExistingInstance<T>(id);\n if (entity) {\n entities[i] = entity;\n } else {\n (idsToLoad ??= []).push(id);\n (positionsToLoad ??= []).push(i);\n }\n }\n\n if (idsToLoad) {\n await loadBatchLoader(this, meta)\n .loadAll(idsToLoad.map((id) => ({ taggedId: id, hint })))\n .catch(function loadAll(err) {\n throw appendStack(err, new Error());\n });\n let idsNotFound: string[] | undefined;\n for (let j = 0; j < positionsToLoad!.length; j++) {\n const entity = this.findExistingInstance<T>(idsToLoad[j]);\n entities[positionsToLoad![j]] = entity;\n if (entity === undefined) (idsNotFound ??= []).push(idsToLoad[j]);\n }\n if (idsNotFound) {\n throw new NotFoundError(`${idsNotFound.join(\",\")} were not found`);\n }\n }\n const loadedEntities = entities as T[];\n if (hint) {\n await this.populate(loadedEntities, hint);\n }\n if (meta.inheritanceType === \"sti\" && meta.baseType) {\n const wrongType = loadedEntities.filter((e) => !(e instanceof meta.cstr));\n if (wrongType.length > 0) {\n throw new Error(`${wrongType.join(\", \")} were not of type ${meta.cstr.name}`);\n }\n }\n return loadedEntities;\n }\n\n /**\n * Returns instances of `type` for the given `ids`, resolving to an existing instance if in our Unit of Work. Ignores\n * IDs that are not found.\n */\n public async loadAllIfExists<T extends EntityW>(type: EntityConstructor<T>, ids: readonly string[]): Promise<T[]>;\n public async loadAllIfExists<T extends EntityW, const H extends LoadHint<T>>(\n type: EntityConstructor<T>,\n ids: readonly string[],\n populate: H,\n ): Promise<Loaded<T, H>[]>;\n async loadAllIfExists<T extends EntityW>(\n type: EntityConstructor<T>,\n _ids: readonly string[],\n hint?: any,\n ): Promise<T[]> {\n const meta = getMetadata(type);\n\n // Use pre-allocated arrays/for loops instead of `.filter`s since this can be a hot spot;\n // the all-hit path returns the single pre-sized array without any id copies or rebuilds\n const maybeEntities = new Array<T | undefined>(_ids.length);\n let idsToLoad: string[] | undefined;\n let positionsToLoad: number[] | undefined;\n\n // Ensure the ids are tagged, and find any not-yet-loaded\n for (let i = 0; i < _ids.length; i++) {\n const id = tagId(meta, _ids[i]);\n const entity = this.findExistingInstance<T>(id);\n if (entity) {\n maybeEntities[i] = entity;\n } else {\n (idsToLoad ??= []).push(id);\n (positionsToLoad ??= []).push(i);\n }\n }\n\n let entities: T[];\n if (idsToLoad) {\n await loadBatchLoader(this, meta)\n .loadAll(idsToLoad.map((id) => ({ taggedId: id, hint })))\n .catch(function loadAllIfExists(err) {\n throw appendStack(err, new Error());\n });\n // Fill in whichever missed ids actually exist, then compact out the not-founds\n for (let j = 0; j < positionsToLoad!.length; j++) {\n maybeEntities[positionsToLoad![j]] = this.findExistingInstance<T>(idsToLoad[j]);\n }\n entities = [];\n for (const entity of maybeEntities) {\n if (entity !== undefined) entities.push(entity);\n }\n } else {\n entities = maybeEntities as T[];\n }\n if (hint) {\n await this.populate(entities, hint);\n }\n return entities;\n }\n\n /**\n * Loads entities found, when starting at `entities`, via the \"path\" given by the `fn` lens function.\n *\n * Results are unique, i.e. if doing `em.loadLens([b1, b2], b => b.author.publisher)` point to the\n * same `Publisher`, it will only be returned as a single value.\n */\n public async loadLens<T extends EntityW, U, V>(\n entities: readonly T[],\n fn: (lens: Lens<T>) => Lens<U, V>,\n ): Promise<U[]>;\n public async loadLens<T extends EntityW, U extends EntityW, V, const H extends LoadHint<U>>(\n entities: readonly T[],\n fn: (lens: Lens<T>) => Lens<U, V>,\n populate: H,\n ): Promise<Loaded<U, H>[]>;\n public async loadLens<T extends EntityW, U, V>(\n entities: readonly T[],\n fn: (lens: Lens<T>) => Lens<U, V>,\n populate?: any,\n ): Promise<V> {\n const result = await loadLens(entities, fn);\n if (populate) {\n await this.populate(result as any as Entity[], populate);\n }\n return result;\n }\n\n /**\n * Loads entities from database rows that were queried directly using a query builder.\n *\n * This overload is synchronous since there is no population/querying to do.\n */\n public loadFromQuery<T extends EntityW>(type: MaybeAbstractEntityConstructor<T>, rows: readonly unknown[]): T[];\n /**\n * Loads entities from database rows from a Knex-ish query builder that needs an `await`.\n *\n * This overload is async because it triggers the `rows` query.\n */\n public loadFromQuery<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: PromiseLike<readonly unknown[]>,\n ): Promise<T[]>;\n /**\n * Loads & populates entities from database rows that were queried directly using a query builder.\n */\n public loadFromQuery<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: readonly unknown[],\n populate: H,\n ): Promise<Loaded<T, H>[]>;\n /**\n * Loads & populates entities from database rows from a Knex-ish query builder that needs an `await`.\n */\n public loadFromQuery<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: PromiseLike<readonly unknown[]>,\n populate: H,\n ): Promise<Loaded<T, H>[]>;\n public loadFromQuery<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: readonly unknown[] | PromiseLike<readonly unknown[]>,\n populate?: any,\n ): PromiseLike<T[]> | T[] {\n if (Array.isArray(rows)) {\n const entities = this.hydrate(type, rows);\n if (populate) return this.populate(entities, populate);\n return entities;\n } else {\n return (rows as Promise<unknown[]>).then((rows) => {\n const entities = this.hydrate(type, rows);\n if (populate) return this.populate(entities, populate);\n return entities;\n });\n }\n }\n\n /** Loads entities from rows. */\n public async loadFromRows<T extends EntityW>(type: MaybeAbstractEntityConstructor<T>, rows: unknown[]): Promise<T[]>;\n public async loadFromRows<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: unknown[],\n populate: H,\n ): Promise<Loaded<T, H>[]>;\n public async loadFromRows<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: unknown[],\n populate?: any,\n ): Promise<T[]> {\n const entities = this.hydrate(type, rows);\n if (populate) {\n await this.populate(entities, populate);\n }\n return entities;\n }\n\n /** Given a hint `H` (a field, array of fields, or nested hash), pre-load that data into `entity` for sync access. */\n public async populate<T extends EntityW, const H extends LoadHint<T>, V = Loaded<T, H>>(\n entity: T,\n hint: H,\n fn?: (entity: Loaded<T, H>) => V,\n ): Promise<V>;\n public async populate<T extends EntityW, const H extends LoadHint<T>, V = Loaded<T, H>>(\n entity: T,\n opts: { hint: H; forceReload?: boolean },\n fn?: (entity: Loaded<T, H>) => V,\n ): Promise<V>;\n public async populate<T extends EntityW, const H extends LoadHint<T>>(\n entities: ReadonlyArray<T>,\n hint: H,\n ): Promise<Loaded<T, H>[]>;\n public async populate<T extends EntityW, const H extends LoadHint<T>>(\n entities: ReadonlyArray<T>,\n opts: { hint: H; forceReload?: boolean },\n ): Promise<Loaded<T, H>[]>;\n async populate<T extends EntityW, H extends LoadHint<T>, V>(\n entityOrList: T | T[],\n hintOrOpts: { hint: H; forceReload?: boolean } | H,\n fn?: (entity: Loaded<T, H>) => V,\n ): Promise<Loaded<T, H> | Array<Loaded<T, H>> | V> {\n const { hint: hintOpt, ...opts } =\n typeof hintOrOpts === \"object\" && \"hint\" in hintOrOpts ? hintOrOpts : { hint: hintOrOpts };\n\n // Tell `AsyncMethodImpl.load` to not invoke its function\n (opts as any)[AsyncMethodPopulateSecret] = true;\n\n // I'm tempted to throw an error here, because at least internal callers should ideally pre-check\n // that `list > 0` and `Object.keys(hint).length > 0` before calling `populate`, just as an optimization.\n // But since it's a public API, we should just early exit.\n const list = toArray(entityOrList).filter((e) => {\n // Check `isDeletedAndFlushed` so that pending-delete entities are still populated,\n // because their hooks might do `getWithDeleted` calls and expect them to be loaded.\n return e !== undefined && !getInstanceData(e).isDeletedAndFlushed;\n });\n if (list.length === 0) {\n return !fn ? (entityOrList as any) : fn(entityOrList as any);\n }\n\n // Avoid building a HintTree/batchloader for persisted entities when everything is already loaded; in the phase 9\n // benchmark this moved already-loaded populates from ~1.10ms to ~0.89ms, and nested already-loaded populates from\n // ~2.39ms to ~1.94ms.\n if (!opts.forceReload && list.every((entity) => !entity.isNewEntity && isLoadedForPopulate(entity, hintOpt as H))) {\n return fn ? fn(entityOrList as any) : (entityOrList as any);\n }\n\n const meta = getMetadata(list[0]);\n\n if (this.#preloader) {\n // If we can preload, prevent promise deadlocking by one large-batch preload populate (which can't have\n // intra dependencies), then a 2nd small-batch non-preload populate.\n const [preload, non] = this.#preloader.partitionHint(meta, hintOpt);\n if (preload) {\n const loader = populateBatchLoader(this, meta, preload, \"preload\", opts);\n await loader.loadAll(list.map((entity) => ({ entity, hint: preload }))).catch(function populate(err: any) {\n throw appendStack(err, new Error());\n });\n }\n if (non) {\n const loader = populateBatchLoader(this, meta, non, \"intermixed\", opts);\n await loader.loadAll(list.map((entity) => ({ entity, hint: non }))).catch(function populate(err: any) {\n throw appendStack(err, new Error());\n });\n }\n } else {\n const loader = populateBatchLoader(this, meta, hintOpt, \"intermixed\", opts);\n await loader.loadAll(list.map((entity) => ({ entity, hint: hintOpt }))).catch(function populate(err: any) {\n throw appendStack(err, new Error());\n });\n }\n\n return fn ? fn(entityOrList as any) : (entityOrList as any);\n }\n\n // For debugging EntityManager.populate.test.ts's \"can be huge\"\n // populates: Record<string, number> = {};\n\n /**\n * Executes `fn` with a transaction, and automatically calls `flush`/`commit` at the end.\n *\n * This ensures both any `.find` and `.flush` operations happen within the same\n * transaction, which is useful for enforcing cross-table/application-level invariants that\n * cannot be enforced with database-level constraints.\n */\n public async transaction<T>(fn: (txn: TX) => Promise<T>): Promise<T> {\n return this.driver.transaction(this, async (txn) => {\n const result = await fn(txn);\n // The lambda may have done some interstitial flushes (that would not\n // have committed the transaction), but go ahead and do a final one\n // in case they didn't explicitly call flush.\n await this.flush();\n return result;\n });\n }\n\n /**\n * Marks an instance to be deleted.\n *\n * Any loaded collections that are currently \"pointing to\" this entity will be updated to\n * no longer include this entity, i.e. if you `em.delete(b1)`, then `author.books` will have\n * `b1` removed (if needed).\n *\n * This is done for all currently-loaded collections; i.e. technically unloaded collections\n * may still point to this entity. We defer unsetting these not-currently-loaded references\n * until `EntityManager.flush`, when we can make the async calls to load-and-unset them.\n */\n delete(entity: Entity): void;\n /**\n * Marks entities to be deleted.\n *\n * Any loaded collections that are currently \"pointing to\" this entity will be updated to\n * no longer include this entity, i.e. if you `em.delete(b1)`, then `author.books` will have\n * `b1` removed (if needed).\n *\n * This is done for all currently-loaded collections; i.e. technically unloaded collections\n * may still point to this entity. We defer unsetting these not-currently-loaded references\n * until `EntityManager.flush`, when we can make the async calls to load-and-unset them.\n */\n delete(entities: Entity[]): void;\n delete(entityOrArray: Entity | Entity[]): void {\n for (const entity of toArray(entityOrArray)) {\n // Early return if already deleted.\n const alreadyMarked = getInstanceData(entity).markDeleted();\n if (!alreadyMarked) continue;\n // This monotonic flag lets find hot paths skip scanning results until a delete has ever happened in this EM.\n this.#hasAnyDeletes = true;\n // Any derived fields that read this entity will need recalc-d\n this.#rm.queueAllDownstreamFields(entity, \"deleted\");\n // Synchronously unhook the entity if the relations are loaded\n getCascadeDeleteRelations(entity).forEach((r) => r.maybeCascadeDelete());\n // And queue the cascade deletes\n this.#pendingDeletes.push(entity);\n }\n }\n\n async assignNewIds() {\n let pendingEntities = this.entities.filter((e) => e.isNewEntity && !e.isDeletedEntity && !e.idTaggedMaybe);\n await this.getLoader<Entity, Entity>(\"assign-new-ids\", \"global\", async (entities) => {\n let todos = createTodos(entities);\n await this.driver.assignNewIds(this, todos);\n for (const e of entities) this.#entitiesById.set(e.idTagged, e);\n return entities;\n })\n .loadMany(pendingEntities)\n .catch(function assignNewIds(err) {\n throw appendStack(err, new Error());\n });\n }\n\n /**\n * Immediately assigns async defaults to `entities`.\n *\n * Normally async defaults wait until `em.flush` to run, because their async nature requires\n * an `await` / `Promise` to be evaluated, and `em.create` is synchronous.\n *\n * This `assignDefaults` methods like you move that up, and immediately invoke\n * any default logic against the `entities`.\n */\n async setDefaults(entities: Entity[]): Promise<void> {\n return runInTrustedContext(async () => {\n const suppressedTypeErrors: Error[] = [];\n const entitiesByType = groupBy(\n entities.filter((e) => e.isNewEntity),\n (e) => getMetadata(e),\n );\n await setAsyncDefaults(suppressedTypeErrors, this.ctx, entitiesByType);\n });\n }\n\n /**\n * Flushes the SQL for any changed entities to the database.\n *\n * If this is run outside of an existing transaction, it will `BEGIN` and `COMMIT`\n * a new transaction on every `.flush()` call so that all of the `INSERT`s/etc.\n * happen atomically.\n *\n * If this is run within an existing transaction, i.e. `EntityManager.transaction`,\n * then it will only issue `INSERT`s/etc. and defer to the caller to `COMMIT`\n * the transaction.\n *\n * It returns entities that have changed (an entity is considered changed if it has been deleted, inserted, or updated)\n */\n async flush(flushOptions: FlushOptions = {}): Promise<Entity[]> {\n return runInTrustedContext(() => this.#flush(flushOptions));\n }\n\n async #flush(flushOptions: FlushOptions = {}): Promise<Entity[]> {\n if (this.mode === \"read-only\") throw new ReadOnlyError();\n\n const { skipValidation = false } = flushOptions;\n\n this.#fl.startLock();\n\n const allFlushedEntities: Set<Entity> = new Set();\n\n try {\n await this.#fl.allowWrites(async () => {\n // Cascade deletes now that we're async (i.e. to keep `em.delete` synchronous).\n // Also do this before calling `recalcPendingReactables` to avoid recalculating\n // fields on entities that will be deleted (and probably have unset/invalid FKs\n // that would NPE their logic anyway).\n await this.flushDeletes();\n // Recalc before we run hooks, so the hooks will see the latest calculated values.\n await this.#rm.recalcPendingReactables(\"reactables\");\n });\n\n const createdThenDeleted: Set<Entity> = new Set();\n // We'll only invoke hooks once/entity (the 1st time that entity goes through runHooksOnPendingEntities)\n const hooksInvoked: Set<Entity> = new Set();\n // Make sure two AsyncReactiveFields don't ping-pong each other forever\n let hookLoops = 0;\n let now = getNow();\n const suppressedDefaultTypeErrors: Error[] = [];\n\n // Make a lambda that we can invoke multiple times, if we loop for AsyncReactiveFields\n const runHooksOnPendingEntities = async (): Promise<Entity[]> => {\n if (hookLoops++ >= 10) throw new Error(\"runHooksOnPendingEntities has ran 10 iterations, aborting\");\n\n // Resolve any pending o2m/m2m sets (set() called before load — need to load from DB to diff)\n const pendingLoads = [...getEmInternalApi(this).pendingLoads];\n if (pendingLoads.length > 0) {\n getEmInternalApi(this).pendingLoads.clear();\n await Promise.all(pendingLoads.map((collection) => collection.load()));\n }\n\n // Any dirty entities we find, even if we skipped firing their hooks on this loop\n const pendingFlush: Set<Entity> = new Set();\n // Subset of pendingFlush entities that we will run hooks on\n const pendingHooks: Set<Entity> = new Set();\n // Subset of pendingFlush entities that had hooks invoked in a prior `runHooksOnPendingEntities`\n const alreadyRanHooks = new Set<Entity>();\n\n findPendingFlushEntities(\n this.#maybePendingFlushEntities,\n hooksInvoked,\n pendingFlush,\n pendingHooks,\n alreadyRanHooks,\n );\n\n // If we're re-looping for AsyncReactiveField, make sure to bump updatedAt\n // each time, so that for an INSERT-then-UPDATE the triggers don't think the\n // UPDATE forgot to self-bump updatedAt, and then \"helpfully\" bump it for us.\n if (alreadyRanHooks.size > 0) {\n maybeBumpUpdatedAt(this.#rm, createTodos(alreadyRanHooks), now);\n }\n\n // Run hooks in a series of loops until things \"settle down\"\n while (pendingHooks.size > 0) {\n await this.#fl.allowWrites(async () => {\n let todos = createTodos(pendingHooks);\n\n await setAsyncDefaults(suppressedDefaultTypeErrors, this.ctx, Todo.groupInsertsByTypeAndSubType(todos));\n maybeBumpUpdatedAt(this.#rm, todos, now);\n\n // Run our hooks\n for (const group of maybeSetupHookOrdering(todos)) {\n await beforeCreate(this.ctx, group);\n await beforeUpdate(this.ctx, group);\n await beforeFlush(this.ctx, group);\n }\n\n // Call `setField` just to get the column marked as dirty if needed.\n // This can come after the hooks, b/c if the hooks read any of these\n // fields, they'd be via the synchronous getter and would not be stale.\n recalcSynchronousDerivedFields(todos);\n\n // The hooks could have deleted this-loop or prior-loop entities, so re-cascade again.\n // Reactions (the recalc below) can themselves `em.delete` entities, so keep draining\n // until both deletes and recalcs have settled.\n do {\n await this.flushDeletes();\n // The hooks could have changed fields, so recalc again.\n await this.#rm.recalcPendingReactables(\"reactables\");\n } while (this.#pendingDeletes.length > 0);\n // We may have reactables that failed earlier, but will succeed now that hooks have been run and cascade\n // deletes have been processed\n if (this.#rm.hasPendingTypeErrors) {\n await this.#rm.recalcPendingTypeErrors();\n // We need to re-run reactables again if we dirtied something while retrying type errors\n if (this.#rm.needsRecalc(\"reactables\")) await this.#rm.recalcPendingReactables(\"reactables\");\n }\n\n for (const e of pendingHooks) hooksInvoked.add(e);\n pendingHooks.clear();\n // See if the hooks mutated any new, not-yet-hooksInvoked entities\n findPendingFlushEntities(\n this.#maybePendingFlushEntities,\n hooksInvoked,\n pendingFlush,\n pendingHooks,\n alreadyRanHooks,\n );\n // The final run of recalcPendingReactables could have left us with pending type errors and no entities in\n // pendingHooks. If so, we need to re-run recalcPendingTypeErrors to get those errors to transition into\n // suppressed errors so that we will fail after simpleValidation.\n if (pendingHooks.size === 0 && this.#rm.hasPendingTypeErrors) await this.#rm.recalcPendingTypeErrors();\n });\n }\n // We might have invoked hooks that immediately deleted a new entity (weird but allowed);\n // if so, filter it out so that we don't flush it, but keep track for later fixing up\n // it's `#orm.deleted` field.\n return [...pendingFlush].filter((e) => {\n const createThenDelete = e.isDeletedEntity && e.isNewEntity;\n if (createThenDelete) createdThenDeleted.add(e);\n return !createThenDelete;\n });\n };\n\n const { pluginManager } = getEmInternalApi(this);\n\n const runValidation = async (\n entityTodos: Record<string, Todo>,\n joinRowTodos: Record<string, JoinRowTodo>,\n validate: boolean,\n ) => {\n const changedEntities = entitiesFromTodos(entityTodos, joinRowTodos);\n try {\n this.#isValidating = true;\n await pluginManager.beforeValidate(changedEntities);\n if (validate) {\n // Regular rules run pre-flush, so `em.find*` would query stale data; block it and steer\n // users to `config.addCommitRule` (which runs post-flush). Only rules are restricted —\n // `afterValidation` hooks & plugins below are left free to query.\n this.#findRestricted = true;\n try {\n // Run simple rules first b/c it includes not-null/required rules, so that then when we run\n // `validateReactiveRules` next, the app's lambdas won't see fundamentally invalid entities & NPE.\n await validateSimpleRules(entityTodos);\n // After we've let any \"author is not set\" simple rules fail before prematurely throwing\n // the \"of course that caused an NPE\" `TypeError`s, if all the authors *were* valid/set,\n // and we still have TypeErrors (from derived valeus), they were real, unrelated errors\n // that the user should see.\n if (suppressedDefaultTypeErrors.length > 0) throw suppressedDefaultTypeErrors[0];\n await validateReactiveRules(this, this.#rm.logger, entityTodos, joinRowTodos);\n } finally {\n this.#findRestricted = false;\n }\n await afterValidation(this.ctx, entityTodos);\n }\n await pluginManager.afterValidate(changedEntities);\n } finally {\n this.#isValidating = false;\n }\n };\n\n // Runs `addCommitRule`s, which look exactly like regular validation rules but fire here,\n // after the INSERT/UPDATE/DELETEs have hit the db (but before COMMIT), so that any\n // `em.find`s they make query the just-flushed/changed state within the transaction.\n const runCommitValidation = async (\n entityTodos: Record<string, Todo>,\n joinRowTodos: Record<string, JoinRowTodo>,\n ) => {\n // Drop the pre-flush find/query caches so commit rules' `em.find`s re-query and see the\n // just-flushed rows, instead of stale results cached earlier in this same flush.\n this.#dataloaders = {};\n this.#batchLoaders = {};\n this.#preloadedRelations = new Map();\n try {\n // `isValidating` keeps derived-field reads from creating (now-unflushable) dirty state.\n this.#isValidating = true;\n await validateSimpleRules(entityTodos, (config) => config.commitRules);\n await validateReactiveRules(\n this,\n this.#rm.logger,\n entityTodos,\n joinRowTodos,\n (meta) => meta.reactiveCommitRules!,\n );\n } finally {\n this.#isValidating = false;\n }\n };\n\n // Commit rules run once, at the end, over just the flushed entities/join-rows whose type has\n // commit rules (see `meta.hasCommitRules`). We accumulate that subset here as we flush — deduping\n // across the RQF loop below (which resets entity dirty-state) — so we neither keep every todo\n // nor re-scan/merge them afterwards; apps without commit rules leave these empty and pay ~nothing.\n const commitRuleTodos: Record<string, Todo> = {};\n const commitRuleJoinRowTodos: Record<string, JoinRowTodo> = {};\n const commitRuleSeen = new Set<unknown>();\n function collectCommitRuleTodos(\n entityTodos: Record<string, Todo>,\n joinRowTodos: Record<string, JoinRowTodo>,\n ): void {\n if (skipValidation) return;\n for (const todo of Object.values(entityTodos)) {\n if (!todo.metadata.hasCommitRules) continue;\n for (const key of [\"inserts\", \"updates\", \"deletes\"] as const) {\n for (const e of todo[key]) {\n if (!commitRuleSeen.has(e)) {\n commitRuleSeen.add(e);\n getTodo(commitRuleTodos, e)[key].push(e);\n }\n }\n }\n }\n for (const [table, todo] of Object.entries(joinRowTodos)) {\n if (!todo.m2m.meta.hasCommitRules && !todo.m2m.otherMeta?.hasCommitRules) continue;\n const into = (commitRuleJoinRowTodos[table] ??= { ...todo, newRows: [], deletedRows: [] });\n for (const key of [\"newRows\", \"deletedRows\"] as const) {\n for (const r of todo[key]) {\n if (!commitRuleSeen.has(r)) {\n commitRuleSeen.add(r);\n into[key].push(r);\n }\n }\n }\n }\n }\n\n // Run hooks (in iterative loops if hooks mutate new entities) on pending entities\n let entitiesToFlush = await runHooksOnPendingEntities();\n for (const e of entitiesToFlush) allFlushedEntities.add(e);\n\n // Recreate todos now that we've run hooks and recalculated fields so know\n // the full set of entities that will be INSERT/UPDATE/DELETE-d in the database.\n let entityTodos = createTodos(entitiesToFlush);\n let joinRowTodos = combineJoinRows(this.#joinRows);\n\n await runValidation(entityTodos, joinRowTodos, !skipValidation);\n this.#rm.throwIfAnySuppressedTypeErrors();\n if (suppressedDefaultTypeErrors.length > 0) throw suppressedDefaultTypeErrors[0];\n\n if (Object.keys(entityTodos).length > 0 || Object.keys(joinRowTodos).length > 0) {\n // The driver will handle the right thing if we're already in an existing transaction.\n await this.driver.transaction(this, async () => {\n do {\n if (Object.keys(entityTodos).length > 0 || Object.keys(joinRowTodos).length > 0) {\n await this.driver.flush(this, entityTodos, joinRowTodos);\n // Accumulate the commit-rule-relevant subset before the RQF loop clobbers/resets these\n collectCommitRuleTodos(entityTodos, joinRowTodos);\n }\n // Now that we've flushed, we can let plugins know what we've done.\n pluginManager.afterWrite(entityTodos, joinRowTodos);\n // And we can look for ReactiveQueries that need to be recalculated\n if (this.#rm.hasPendingReactiveQueries()) {\n // Reset all flushed entities to we only flush net-new changes\n for (const e of entitiesToFlush) {\n if (e.isNewEntity && !e.isDeletedEntity) this.#entitiesById.set(e.idTagged, e);\n getInstanceData(e).resetForRqfLoop();\n }\n // Actually do the recalc\n await this.#fl.allowWrites(async () => {\n await this.#rm.recalcPendingReactables(\"reactiveQueries\");\n // If any ReactiveFields depended on AsyncReactiveFields, go ahead and calc those now\n await this.#rm.recalcPendingReactables(\"reactables\");\n });\n // Advance `now` so that our triggers don't think our UPDATEs are forgetting to self-bump\n // updated_at, and bump it themselves, which could cause a subsequent error.\n now = getNow();\n // See if any RQFs actually changed any entities. If they did, run the hooks on them.\n entitiesToFlush = await runHooksOnPendingEntities();\n for (const e of entitiesToFlush) allFlushedEntities.add(e);\n // Recreate `entityTodos` against the only-the-just-changed entities\n entityTodos = createTodos(entitiesToFlush);\n joinRowTodos = combineJoinRows(this.#joinRows);\n await runValidation(entityTodos, joinRowTodos, true);\n this.#rm.throwIfAnySuppressedTypeErrors();\n } else {\n // Exit the loop\n entityTodos = {};\n }\n } while (Object.keys(entityTodos).length > 0);\n // Now that all SQL has hit the db (but before COMMIT), run any `addCommitRule`s so their\n // `em.find`s see the changed state. `commitRuleTodos` is only non-empty if a flushed entity\n // actually has commit rules, so apps without them skip this (and its logging) entirely.\n if (Object.keys(commitRuleTodos).length > 0 || Object.keys(commitRuleJoinRowTodos).length > 0) {\n // Make just-inserted entities findable by id (like the RQF loop does) so commit rules'\n // `em.find`s return these same instances rather than hydrating duplicate ones.\n for (const e of allFlushedEntities) {\n if (e.isNewEntity && !e.isDeletedEntity) this.#entitiesById.set(e.idTagged, e);\n }\n await runCommitValidation(commitRuleTodos, commitRuleJoinRowTodos);\n }\n // Run `beforeCommit once right before COMMIT\n await beforeCommit(this.ctx, allFlushedEntities);\n if (this.mode === \"in-memory-writes\") {\n throw new InMemoryRollbackError();\n }\n });\n\n // TODO: This is really \"after flush\" if we're being called from a transaction that\n // is going to make multiple `em.flush()` calls?\n await afterCommit(this.ctx, allFlushedEntities);\n\n // Update the `#orm` field to reflect the new state\n for (const e of allFlushedEntities) {\n const instanceData = getInstanceData(e);\n if (e.isNewEntity && !e.isDeletedEntity) this.#entitiesById.set(e.idTagged, e);\n instanceData.resetAfterFlushed();\n // Reset AsyncQueryProperties & LazyFields since DB state may have changed\n const { relations } = instanceData;\n if (relations) {\n for (const rel of Object.values(relations)) {\n if (rel instanceof AsyncPropertyImpl || rel instanceof LazyFieldImpl) rel.resetAfterFlush();\n }\n }\n }\n // Update the joinRows refs to reflect the new state\n for (const joinRow of Object.values(joinRowTodos)) {\n joinRow.resetAfterFlushed();\n }\n const { mutatedCollections } = getEmInternalApi(this);\n for (const o2m of mutatedCollections.values()) {\n o2m.resetAddedRemoved();\n }\n mutatedCollections.clear();\n\n // Reset the find/preload caches b/c data will have changed in the db\n this.#dataloaders = {};\n this.#batchLoaders = {};\n this.#preloadedRelations = new Map();\n this.#rm.clear();\n }\n\n // Fixup the `deleted` field on entities that were created then immediately deleted\n for (const e of createdThenDeleted) getInstanceData(e).fixupCreatedThenDeleted();\n this.#merging?.clear();\n\n return [...allFlushedEntities].sort((a, b) => getInstanceData(a).entityIndex - getInstanceData(b).entityIndex);\n } catch (e) {\n if (e instanceof RecursiveCycleError) {\n const entity = e.entities[0];\n // Look up a custom cycle message — check both the exact field name and its opposite\n // direction, since the cycle may be detected from either side (e.g. walking\n // childrenRecursive during reactive hint reversal when parentsRecursive was configured).\n for (const meta of getBaseAndSelfMetas(getMetadata(entity))) {\n const messageFn =\n meta.config.__data.cycleMessages[e.fieldName] ??\n meta.config.__data.cycleMessages[((entity as any)[e.fieldName] as any)?.otherFieldName];\n if (messageFn) {\n throw new ValidationErrors([{ entity, message: messageFn(entity, e.entities) }]);\n }\n }\n }\n // node-pg keeps the DETAIL line (i.e. \"Key (identity_id, final_id)=(102591, null) already exists\")\n // on a separate `detail` field, so keep it to suffix onto messages to help debugging.\n const detail = e && typeof e === \"object\" && \"detail\" in e && typeof e.detail === \"string\" ? e.detail : undefined;\n if (e && typeof e === \"object\" && \"constraint\" in e && typeof e.constraint === \"string\") {\n // node-pg errors use `constraint` to indicate the constraint name\n const message = constraintNameToValidationError[e.constraint];\n if (message) {\n const errors = new ValidationErrors(message);\n // Keep the user-facing `errors[].message` pretty, but suffix the DETAIL onto the top-level\n // `message` so the debugging context survives into logs/stack traces.\n if (detail) errors.message = `${message} — ${detail}`;\n throw errors;\n }\n }\n if (e instanceof InMemoryRollbackError) {\n return [...allFlushedEntities].sort((a, b) => getInstanceData(a).entityIndex - getInstanceData(b).entityIndex);\n }\n // For raw (non-pretty) pg errors, fold the DETAIL into `message` so it survives into logs.\n if (detail && e instanceof Error) {\n e.message = `${e.message} — ${detail}`;\n }\n throw e;\n } finally {\n this.#rm.clearSuppressedTypeErrors();\n this.#fl.releaseLock();\n resetFactoryCreated();\n }\n }\n\n /**\n * A very simple toJSON.\n *\n * This is not really meant to be useful, it's to prevent huge/circular output if\n * an EntityManager accidentally ends up getting logged to something like pino that\n * over-zealous toJSONs anything it touches.\n */\n public toJSON(): string {\n return `<EntityManager ${this.entities.length}>`;\n }\n\n /**\n * For all entities in the current `EntityManager`, load their latest data from the database.\n *\n * This is primarily useful in tests, i.e. having 1 `EntityManager` with some test data, running business\n * logic in a dedicated `EntityManager`, and then `refresh`-ing the test data `EntityManager` to assert\n * against the latest values.\n *\n * This works with primitive fields as well as references and collections.\n *\n * TODO Newly-found collection entries will not have prior load hints applied to this, unless using\n * `deepLoad` which should only be used by tests to avoid loading your entire database in memory.\n */\n async refresh(opts?: { deepLoad?: boolean }): Promise<void>;\n async refresh(entity: EntityW): Promise<void>;\n async refresh(entities: ReadonlyArray<EntityW>): Promise<void>;\n async refresh(param?: EntityW | ReadonlyArray<EntityW> | { deepLoad?: boolean }): Promise<void> {\n this.#isRefreshing = true;\n this.#dataloaders = {};\n this.#batchLoaders = {};\n this.#preloadedRelations = new Map();\n const deepLoad = param && \"deepLoad\" in param && param.deepLoad;\n let todo =\n param === undefined\n ? this.#entitiesArray\n : Array.isArray(param)\n ? param\n : isEntity(param)\n ? [param]\n : this.#entitiesArray;\n const done = new Set<Entity>();\n while (todo.length > 0) {\n const copy = [...todo];\n copy.forEach((e) => done.add(e));\n todo = [];\n\n // For any non-deleted entity with an id, get its latest data + relations from the database\n const entitiesToRefresh = copy.filter((e) => e.idTaggedMaybe && !e.isDeletedEntity);\n await Promise.all(\n entitiesToRefresh.map((entity) => {\n // Pass loaded/all relation names as a hint so the preloader can inject JOINs\n const hint = getRelationEntries(entity)\n .filter(([_, r]) => deepLoad || r.isLoaded)\n .map(([k]) => k);\n return loadBatchLoader(this, getMetadata(entity), true)\n .load({ taggedId: entity.idTagged, hint })\n .catch(function refresh(err) {\n throw appendStack(err, new Error());\n });\n }),\n );\n\n // Then refresh any loaded relations (the loadBatchLoader only hydrates the entity\n // data, it doesn't get each relation into a loaded state.)\n const [custom, builtin] = partition(\n entitiesToRefresh\n .filter((e) => !getInstanceData(e).isDeletedEntity)\n .flatMap((entity) => getRelations(entity).filter((r) => deepLoad || r.isLoaded)),\n isCustomRelation,\n );\n // Call `.load` on builtin relations first, because if we hit an already-loaded custom relation\n // first, it will call `.get` internally, and might access built-in relations that we've not had a\n // chance to `.load()` yet.\n await Promise.all(\n builtin.map((r) => {\n // If the relation is already loaded, we need to go through .load({ forceReload }), otherwise\n // use preload to avoid the promise.\n if (r.isPreloaded && !r.isLoaded) {\n r.preload();\n return undefined;\n } else {\n return r.load({ forceReload: true });\n }\n }),\n );\n await Promise.all(custom.map((r) => r.load({ forceReload: true })));\n\n // If deep loading, get all entity/entities in the relation and push them on the list\n if (deepLoad) {\n todo.push(\n // We skip recursing into CustomCollections and CustomReferences and PersistedAsyncReferencesImpl for two reasons:\n // 1. It can be tricky to ensure `{ forceReload: true }` is passed all the way through their custom load\n // implementations, and so it's easy to have `.get` accidentally come across a not-yet-loaded collection, and\n // 2. Any custom load functions should use the underlying o2m/m2o/etc relations anyway, so if we crawl/refresh\n // those, then when the user calls `.get` on custom collections/references, they should be talking to always-loaded\n // relations, w/o us having to tackle the tricky bookkeeping problem passing `forceReload` all through their\n // custom load function + any other collections they call.\n ...builtin\n .filter((r) => \"get\" in r)\n .map((r) => (r as any).get)\n .flatMap((value) => (Array.isArray(value) ? value : [value]))\n .filter((value) => isEntity(value) && !done.has(value as Entity)),\n );\n }\n }\n this.#isRefreshing = false;\n }\n\n public get numberOfEntities(): number {\n return this.entities.length;\n }\n\n // Handles our Unit of Work-style look up / deduplication of entity instances.\n // Currently only public for the driver impls\n public findExistingInstance<T extends EntityW>(id: string): T | undefined {\n return this.#entitiesById.get(id) as T | undefined;\n }\n\n /**\n * Takes a result `row` from a custom query and maps the db values into a new-or-existing domain object for that row.\n *\n * The `overwriteExisting` controls whether `row`'s values should overwrite the existing fields on\n * an entity. By default this is true, as we assume the user calling this means they know the DB has\n * updated values that should be put into the entities. A few internal callers set this to false,\n * i.e. when we're loading collections and have db results that are potentially stale compared to\n * the WIP entity state.\n */\n public hydrate<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: readonly any[],\n options?: { overwriteExisting?: boolean },\n ): T[] {\n return this.hydrateFromRowData(type, new PojoRowData(rows), options);\n }\n\n /**\n * Hydrates a query's `RowData`, running any sidecar reads, and always `finalize`s the result.\n *\n * This is the internal API for Joist's find/load loaders: `sidecars` is where reads of\n * non-entity columns (preload aggregates, `_tags`, found-id checks) belong — they must run\n * before `finalize`, because compaction drops unretained rows — and the `try/finally`\n * guarantees a failed hydration or sidecar read still releases the result's unretained\n * buffers instead of pinning them.\n */\n private hydrateAndFinalize<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n rowData: RowData,\n opts?: { overwriteExisting?: boolean; sidecars?: (entities: T[]) => void },\n ): T[] {\n try {\n const entities = this.hydrateFromRowData(type, rowData, opts);\n opts?.sidecars?.(entities);\n return entities;\n } finally {\n rowData.finalize?.();\n }\n }\n\n /**\n * Like {@link hydrate}, but reads rows from a {@link RowData}, i.e. a driver-produced\n * lazy query result, instead of an array of POJO rows.\n *\n * This is an internal API used by Joist's own find loaders (usually via\n * {@link hydrateAndFinalize}); rows whose entities are kept (newly created or\n * overwrite-refreshed) are `retain`-ed on the `RowData` so the caller can later `finalize`\n * (trim/compact) the result.\n */\n public hydrateFromRowData<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n rowData: RowData,\n options?: { overwriteExisting?: boolean },\n ): T[] {\n const maybeBaseMeta = getMetadata(type);\n const overwriteExisting = options?.overwriteExisting === true;\n\n const count = rowData.rowCount;\n const entities = new Array(count);\n for (let i = 0; i < count; i++) {\n const id = rowData.get(i, \"id\");\n const taggedId =\n id === undefined || id === null ? fail(\"No id column was available\") : keyToTaggedId(maybeBaseMeta, id)!;\n // See if this is already in our UoW\n let entity = this.findExistingInstance(taggedId) as T;\n if (!entity) {\n // Look for __class from the driver telling us which subtype to instantiate\n const meta = findConcreteMeta(maybeBaseMeta, rowData, i);\n // Pass id as a hint that we're in hydrate mode\n entity = newEntity(this, asConcreteCstr(meta.cstr), false) as T;\n const instanceData = getInstanceData(entity);\n instanceData.rowData = rowData;\n instanceData.rowIndex = i;\n rowData.retain?.(i);\n // Seed the id to share the identity-map key string and skip the id serde on first read\n instanceData.data[\"id\"] = taggedId;\n this.#doRegister(entity as any, taggedId, meta, true);\n } else if (overwriteExisting) {\n // Usually if the entity already exists, we don't write over it, but in this case we assume that\n // `EntityManager.refresh` is telling us to explicitly load the latest data.\n // First swap out the old row with the new row\n const instanceData = getInstanceData(entity);\n instanceData.rowData = rowData;\n instanceData.rowIndex = i;\n rowData.retain?.(i);\n // And then only refresh the data keys that have already been serde-d from rows\n // (this keeps us from deserializing data out of rows that we don't need).\n const { data } = instanceData;\n const dataKeys = Object.keys(data);\n // `id` is seeded at hydrate and can never change, so it never needs refreshing\n if (dataKeys.length > (\"id\" in data ? 1 : 0)) {\n const allFields = getMetadata(entity).allFields;\n // For existing entities this is exactly `changes.fieldsWithoutRelations`, minus the proxy allocation\n const changedFields: string[] = instanceData.isNewEntity\n ? (entity as any).changes.fieldsWithoutRelations\n : Object.keys(instanceData.originalData);\n for (const fieldName of dataKeys) {\n if (fieldName === \"id\") continue;\n const field = allFields[fieldName];\n const serde = field.serde ?? fail(`Missing serde for ${fieldName}`);\n data[fieldName] = serde.fromRow(rowData, i);\n // Make the field look not-dirty\n if (changedFields.includes(fieldName)) {\n instanceData.markFieldClean(fieldName);\n }\n }\n }\n }\n entities[i] = entity;\n }\n\n return entities;\n }\n\n /**\n * Mark an entity as needing to be flushed regardless of its state.\n *\n * This will:\n *\n * - Bump the entity's `updated_at` timestamp (if available),\n * - Run `beforeUpdate` and `beforeFlush` hooks.\n */\n public touch(entity: EntityW): void;\n public touch(entities: EntityW[]): void;\n public touch(entityOrEntities: EntityW | EntityW[]): void {\n for (const entity of toArray(entityOrEntities)) {\n getInstanceData(entity).markTouched();\n }\n }\n\n /**\n * Recalculates an entity's reactive fields or explicitly runs a named reaction.\n *\n * You shouldn't need to call this unless the derived fields have drifted from the underlying data, which\n * should only happen if:\n *\n * - The underlying data was changed by a raw SQL query, or\n * - You've changed the field's business logic and want to update the database to the latest value.\n *\n * Pass `reactionName` to run only that named reaction on each entity. You can also trigger a recalc for\n * specific fields by calling `.load()` on the property, i.e.\n * `author.numberOfBooks.load()`. This `recalc` method is just a helper method to call `load` for\n * all derived fields on the given entity/entities.\n */\n public recalc(entity: EntityW): Promise<void>;\n public recalc(entities: EntityW[]): Promise<void>;\n public recalc(entity: EntityW, reactionName: string): Promise<void>;\n public recalc(entities: EntityW[], reactionName: string): Promise<void>;\n public async recalc(entityOrEntities: EntityW | EntityW[], reactionName?: string): Promise<void> {\n const entities = toArray(entityOrEntities).filter((entity) => !entity.isDeletedEntity);\n if (reactionName !== undefined) {\n // Resolve every reaction before invoking any of them so a mixed list cannot partially run.\n const reactions = entities.map((entity) => {\n const reaction = getBaseAndSelfMetas(getMetadata(entity))\n .flatMap((meta) => meta.config.__data.reactions)\n .find((reaction) => reaction.name === reactionName);\n return reaction ?? fail(`Reaction '${reactionName}' not found on ${getMetadata(entity).type}`);\n });\n await runInTrustedContext(() =>\n Promise.allSettled(reactions.map((reaction, i) => reaction.fn(entities[i], this.ctx))).then(failIfAnyRejected),\n );\n await this.#rm.recalcPendingReactables(\"reactables\");\n return;\n }\n\n // Look for async reactive fields\n const relations = entities.flatMap((entity) =>\n Object.values(getMetadata(entity).allFields)\n .filter((f) => \"derived\" in f && f.derived === \"async\")\n .map((field) => (entity as any)[field.fieldName]),\n );\n // Use forceReload: true to tell ReactiveReferences to recalc against their full graph\n // This intentionally mirrors ReactionsManager.recalcPendingReactables's NoIdError retry. These direct relations\n // are not ReactiveActions, and all failures except NoIdError are returned directly to the caller.\n const results = await Promise.allSettled(relations.map((r: any) => r.load({ forceReload: true })));\n const relationsPendingAssignedIds: any[] = [];\n const failures: any[] = [];\n results.forEach((result, i) => {\n if (result.status === \"rejected\") {\n if (result.reason instanceof NoIdError) {\n relationsPendingAssignedIds.push(relations[i]);\n } else {\n failures.push(result.reason);\n }\n }\n });\n if (relationsPendingAssignedIds.length > 0) {\n await this.assignNewIds();\n const retryResults = await Promise.allSettled(\n relationsPendingAssignedIds.map((r: any) => r.load({ forceReload: true })),\n );\n retryResults.forEach((result) => {\n if (result.status === \"rejected\") {\n failures.push(result.reason);\n }\n });\n }\n if (failures.length > 0) throw failures[0];\n\n // And also sync reactive fields\n entities.flatMap((entity) =>\n Object.values(getMetadata(entity).allFields)\n .filter((f) => \"derived\" in f && f.derived === \"sync\")\n .forEach((field) => {\n // This will be a noop if the value is the same\n setField(entity, field.fieldName, (entity as any)[field.fieldName]);\n }),\n );\n\n // `.load()` recalculated the immediate relations, go ahead and recalc any downstream reactables.\n // We'll still defer AsyncReactiveFields to the em.flush loop.\n await this.#rm.recalcPendingReactables(\"reactables\");\n }\n\n public beforeBegin(fn: HookFn<TX>) {\n this.#hooks.beforeBegin.push(fn);\n }\n\n public afterBegin(fn: HookFn<TX>) {\n this.#hooks.afterBegin.push(fn);\n }\n\n public beforeCommit(fn: HookFn<TX>) {\n this.#hooks.beforeCommit.push(fn);\n }\n\n public afterCommit(fn: HookFn<TX>) {\n this.#hooks.afterCommit.push(fn);\n }\n /**\n * Returns an EntityManager-scoped (i.e. request scoped) data loader.\n *\n * @param operation the operation being batched, i.e. `load` or `o2m-load`, to avoid clashing batch keys\n * across fundamentally different operations\n * @param batchKey for a given operation, i.e. `load`, a batch key `Author` to batch all Author loads together\n * @param fn the batch load function, i.e. that will accept all `.load(...)`-d Author ids to load as a single db call\n * @param opts optional DataLoader options\n * @returns a DataLoader scoped to the `operation` + `batchKey` combination\n */\n public getLoader<K, V>(\n operation: string,\n batchKey: string,\n fn: BatchLoadFn<K, V>,\n opts?: Options<K, V>,\n ): DataLoader<K, V> {\n // If we wanted to, if not in a transaction, we could potentially do lookups against a global cache,\n // to achieve cross-request batching. Granted we'd need all DataLoaders to have caching disabled, see:\n // https://github.com/joist-orm/joist-orm/issues/629\n const loadersForKind = (this.#dataloaders[operation] ??= {});\n return getOrSet(loadersForKind, batchKey, () => new DataLoader(fn, opts));\n }\n\n /**\n * Like `getLoader`, but returns a `BatchLoader` where all callers in the same tick\n * share a single `Promise<void>` instead of getting per-key promises.\n *\n * The batch function should write results via side channels (e.g. `setPreloadedRelation`).\n */\n public getBatchLoader<K>(operation: string, batchKey: string, fn: (keys: K[]) => Promise<void>): BatchLoader<K> {\n const loadersForKind = (this.#batchLoaders[operation] ??= {});\n return getOrSet(loadersForKind, batchKey, () => new BatchLoader(fn));\n }\n\n public toString(): string {\n return \"EntityManager\";\n }\n\n /** Recursively cascades any pending deletions. */\n private async flushDeletes(): Promise<void> {\n let entities = this.#pendingDeletes;\n if (entities.length === 0) return;\n this.#pendingDeletes = [];\n let relationsToCleanup: AbstractRelationImpl<unknown, unknown>[] = [];\n // Loop if our deletes cascade to other deletes\n while (entities.length > 0) {\n // For cascade delete relations, cascade the delete...\n const p = entities.flatMap(getCascadeDeleteRelations).map((r) => r.load().then(() => r.maybeCascadeDelete()));\n await Promise.all(p);\n // Run the beforeDelete hook before we unhook the entity\n const todos = createTodos(entities);\n await beforeDelete(this.ctx, todos);\n // For all relations, unhook the entity from the other side; this append path is optimized for\n // large deletes with ~100k relations by avoiding `flatMap` intermediates and `concat` copies.\n for (const entity of entities) {\n const relations = getRelations(entity);\n const start = relationsToCleanup.length;\n relationsToCleanup.length += relations.length;\n for (let i = 0; i < relations.length; i++) {\n relationsToCleanup[start + i] = relations[i];\n }\n }\n entities = this.#pendingDeletes;\n this.#pendingDeletes = [];\n }\n // For all relations, unhook the entity from the other side\n await Promise.all(relationsToCleanup.map((r) => r.cleanupOnEntityDeleted()));\n }\n\n setReactionLogging(logger: ReactionLogger): void;\n setReactionLogging(enabled: boolean): void;\n setReactionLogging(arg: boolean | ReactionLogger): void {\n this.#rm.setLogger(typeof arg === \"boolean\" ? (arg ? new ReactionLogger() : undefined) : arg);\n }\n\n /** Accepts `Author` or `Author.firstName,lastName` or `Author.lastName!`. */\n setFieldLogging(spec: string): void;\n /** Accepts `[\"Author.firstName,lastName\", \"Book.title\"]`. */\n setFieldLogging(spec: string[]): void;\n /** Sets this EntityManager's field logger. */\n setFieldLogging(logger: FieldLogger): void;\n /** Enables/disables field logging for all fields. */\n setFieldLogging(enabled: boolean): void;\n setFieldLogging(arg: FieldLogger | string | string[] | boolean): void {\n if (arg instanceof FieldLogger) {\n this.#fieldLogger = arg;\n return;\n }\n const writeFn = getDefaultWriteFn(this.ctx);\n if (typeof arg === \"boolean\") {\n this.#fieldLogger = arg ? new FieldLogger([], writeFn) : noopFieldLogger;\n } else if (typeof arg === \"string\" || Array.isArray(arg)) {\n const specs = Array.isArray(arg) ? arg : [arg];\n const watching: FieldLoggerWatch[] = specs.map((spec) => {\n // Regex to match Author.firstName,lastName! pattern\n const regex = /^([^.!]+)(?:\\.([^!]*))?(!)?$/;\n const [_, entity, fields, breakpoint] = spec.match(regex) ?? fail(`Unsupported spec ${spec}`);\n const fieldNames = fields?.split(\",\");\n // Ensure entity is valid, to avoid failing silently\n const meta = getMetadataForType(entity);\n // Ensure the field names are valid, to avoid failing silently\n fieldNames?.forEach((field) => {\n // We could probably check the `kind`, b/c things like o2o/o2m are not supported atm\n if (!meta.allFields[field]) {\n throw new Error(`Field ${field} not found on ${entity}`);\n }\n });\n return { entity, fieldNames, breakpoint: !!breakpoint };\n });\n this.#fieldLogger = new FieldLogger(watching, writeFn);\n } else {\n throw new Error(\"Unsupported override for setFieldLogging\");\n }\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.flush();\n }\n\n /** Returns entities matching the filter using indexed search when available. */\n filterEntities<T extends Entity>(cstr: EntityConstructor<T>, where: Partial<OptsOf<T>>): T[] {\n const meta = getMetadata(cstr);\n const entities = (this.#entitiesByTag.get(meta.tagName) as T[]) ?? [];\n // Don't bother filtering if there's no where clause (particularly b/c IndexManager.findMatching\n // really expects there to be at least 1 condition)\n if (!hasAnyKey(where)) {\n return entities.filter((e) => e instanceof cstr && !e.isDeletedEntity);\n }\n if (this.#indexManager.shouldIndexType(entities.length)) {\n this.#indexManager.enableIndexingForType(meta, entities, where);\n // Build the final array in one pass, still filtering `instanceof cstr` to handle subtyping\n const result: T[] = [];\n for (const e of this.#indexManager.findMatching(meta, entities, where)) {\n if (e instanceof cstr && !e.isDeletedEntity) result.push(e);\n }\n return result;\n } else {\n return (\n entities\n // Still filter by `instanceof cstr` to handle subtyping\n .filter((e) => e instanceof cstr && !e.isDeletedEntity && entityMatches(e, where)) as T[]\n );\n }\n }\n\n /**\n * Creates a new EntityManager that shares the same entities as the current one but allows independent changes.\n *\n * This is useful for scenarios where you want to:\n *\n * - Preload data for use as a cache\n * - Make speculative changes that may or may not be committed\n * - Escape a transaction scope\n *\n * The fork will:\n *\n * - Copy all currently loaded entities to the new EntityManager\n * - Copy any loaded relation data to keep `.isLoaded` / `.get` state consistent\n * - Copy and update references to the EntityManager and its entities in the context, which is itself shallowly copied\n *\n * The fork will NOT:\n *\n * - Copy any pending changes (must call .flush() first)\n * - Share any changes made in either EntityManager with the other\n *\n * @param opts options to control the fork behavior\n * - allowPendingChanges - allows the em being forked to have pending changes and forces the resulting em to have\n * `mode` set to \"in-memory-writes\". Changes to entities in the original em will be copied to the resulting em.\n * Optional. default: false\n *\n * @throws {Error} If called on an EntityManager with pending changes\n * @returns A new EntityManager with copied entity state\n */\n fork(opts: { allowPendingChanges?: boolean } = {}): EntityManager<C, Entity, TX> {\n const { allowPendingChanges = false } = opts;\n const oldEm = this;\n // copy the context so that it's distinct between the two ems, and so we can update any references from the old em\n // to the new one later\n const ctx = { ...oldEm.ctx } as Record<string, any>;\n const newEm = new EntityManager<C, Entity, TX>(ctx as C, { em: oldEm });\n if (allowPendingChanges) newEm.mode = \"in-memory-writes\";\n // hydrate (ie, create) each entity from the oldEm in the newEm\n for (const [tag, entities] of oldEm.#entitiesByTag.entries()) {\n // tags are always defined by the base constructor, so we use that as hydrate expects the base class as its argument\n const baseCstr = getConstructorFromTag(tag);\n let rows = new Array<any>(entities.length);\n let i = 0;\n for (const entity of entities) {\n const instanceData = (entity as any).__data as InstanceData;\n if (!allowPendingChanges && instanceData.pendingOperation !== \"none\") {\n fail(\"Cannot fork an EntityManager with pending changes\");\n } else if (instanceData.isNewEntity) {\n // Create blank entities in newEm for each unpersisted entity from oldEm. They will be populated later in the\n // allowPendingChanges step as they should not be present otherwise.\n // (I'd thought we should copy over `InstanceData.createId`, but since we're iterating over `oldEm.#entitiesByTag`\n // in stable as-created order, the `newEm.create` will assign the same/incrementing `createId`s as in oldEm.)\n newEm.create(entity.constructor as EntityConstructor<Entity>, {} as any);\n } else {\n // We copy the raw row data for each entity to avoid any potential conflict. Then we ensure the correct concrete\n // __class key is set for hydrate to use, if necessary (ie, cti), to actually instantiate the entity.\n rows[i] = createRowFromEntityData(entity);\n i++;\n }\n }\n if (rows.length !== i) rows = rows.slice(0, i);\n newEm.hydrate(baseCstr, rows);\n }\n\n function mapEntity(oldEntity: Entity): Entity {\n if (oldEntity.isNewEntity) {\n return newEm.#entitiesById.get(oldEntity.toTaggedString())!;\n } else {\n return newEm.#entitiesById.get(oldEntity.idTagged)!;\n }\n }\n\n function mapEntities<U extends Entity>(v: U[] | undefined): U[] | undefined {\n if (v === undefined) return undefined;\n const result = new Array<U>(v.length);\n for (let i = 0; i < v.length; i++) result[i] = mapEntity(v[i]) as U;\n return result;\n }\n\n // If we are allowing pending changes, then we need to copy any changes across to newEm\n if (allowPendingChanges) {\n for (const oldEntity of oldEm.entities) {\n const oldInstanceData = (oldEntity as any).__data as InstanceData;\n if (!(oldInstanceData.isNewEntity || oldInstanceData.isDirtyEntity)) continue;\n const { originalData: oldOriginalData, data: oldData } = oldInstanceData;\n const newEntity = mapEntity(oldEntity);\n const newInstanceData = (newEntity as any).__data as InstanceData;\n const { data: newData } = newInstanceData;\n // for new entities, anything in `data` is changed and should be copied across. for existing entities, we\n // only care about changed fields, which are enumerated by originalData\n const maybeEntity = (value: any) => (isEntity(value) ? mapEntity(value as Entity) : value);\n const fields = Object.keys(oldEntity.isNewEntity ? oldData : oldOriginalData);\n for (const field of fields) {\n // copy over originalData so .changes is consistent across ems\n if (field in oldOriginalData) newInstanceData.markFieldDirty(field, maybeEntity(oldOriginalData[field]));\n newData[field] = maybeEntity(oldData[field]);\n }\n }\n }\n\n // import every loaded concrete (ie, not custom) relation into the new em\n for (const oldEntity of oldEm.entities) {\n const newEntity = mapEntity(oldEntity);\n if (oldEntity.isDeletedEntity) {\n // If the old entity was deleted, that should be persisted in the new em\n ((newEntity as any).__data as InstanceData).markDeleted();\n // deleted entities will fail if you try to `get` their relations, so skip them since they should be cleared\n // out regardless\n continue;\n }\n\n const { relations } = (oldEntity as any).__data as InstanceData;\n if (!relations) continue;\n for (const [field, relation] of Object.entries(relations)) {\n // With lazyRelation, custom relations are inserted into the `relations` map. Custom relations don't\n // store any data, so we can ignore them by checking if the relation implements `import`\n // TODO: add `import` to recursiveCollection\n if (!(\"import\" in relation)) continue;\n if (oldEntity.isNewEntity) {\n // every relation should be loaded on a new entity, so calling get should be safe\n const oldValue = relation.get;\n if (oldValue === undefined) continue;\n if (Array.isArray(oldValue) && oldValue.length === 0) continue;\n const newValue = Array.isArray(oldValue) ? mapEntities(oldValue) : mapEntity(oldValue);\n // we may have already copied over the instance data, in which case `setFromOpts` would detect this as\n // the same entity that's already set in data and early exit, so delete ourselves from data first\n delete ((newEntity as any).__data as InstanceData).data[field];\n (newEntity as any)[field].setFromOpts(newValue);\n } else {\n const isLoaded = \"_isLoaded\" in relation ? relation._isLoaded : relation.isLoaded;\n if (isLoaded) (newEntity as any)[field].import(relation, mapEntity, mapEntities);\n }\n }\n }\n // Inspect the top level keys in the context and replace any references from oldEm with newEm (ie, ctx.em === newEm)\n // while also replacing any entities from oldEm with their version in newEm (eg, if the user is stored in the\n // context, then `ctx.user.em === newEm`).\n for (const [key, value] of Object.entries(ctx)) {\n if (isEntity(value) && value.em === oldEm) {\n ctx[key] = mapEntity(value as Entity);\n } else if (value === oldEm) {\n ctx[key] = newEm;\n }\n }\n return newEm;\n }\n\n /**\n * Copies an entity from one EntityManager to another, ensuring all relations specified in the hint are\n * also copied.\n *\n * This method is primarily used when you need to move entities between different EntityManager instances\n * while preserving their loaded state and relationships. This is useful for scenarios like:\n *\n * - Moving entities between transaction boundaries\n * - Creating test fixtures that reference entities from a different EntityManager\n * - Sharing entities between different parts of your application\n *\n * The migration process:\n * 1. If the entity already exists in this EntityManager, returns it\n * 2. Otherwise, creates a new instance with the same data\n * 3. Recursively migrates any loaded relations specified in the hint\n *\n * @param source - The entity to migrate from another EntityManager\n * @param hint - The load hint specifying which relations to migrate\n * @returns The migrated entity with all specified relations loaded\n */\n importEntity<T extends Entity>(original: T): T;\n importEntity<T extends Entity, H extends LoadHint<T>, L extends Loaded<T, H>>(original: L, hint: H): L;\n importEntity<T extends Entity, H extends LoadHint<T>, L extends Loaded<T, H>>(\n source: L,\n hint?: H,\n normalizedHint?: H,\n ): L {\n if (source.isNewEntity) fail(\"cannot import new entities\");\n if (source.isDeletedEntity) fail(\"cannot import deleted entities\");\n if (source.isDirtyEntity) fail(\"cannot import dirty entities\");\n\n hint ??= {} as H;\n if (!normalizedHint) {\n assertLoaded(source, hint);\n normalizedHint = deepNormalizeHint(hint) as H;\n }\n\n if (source.em === this) return source as any;\n\n const meta = getMetadata(source);\n\n let result = this.#entitiesById.get(source.idTagged) as T | undefined;\n\n if (!result) {\n const meta = getMetadata(source);\n const row = createRowFromEntityData(source);\n result = this.hydrate(getBaseMeta(meta).cstr, [row])[0]!;\n }\n\n for (const [fieldName, subHint] of Object.entries(normalizedHint)) {\n const field = meta.allFields[fieldName];\n const relationOrProp = (result as any)[fieldName];\n if (!field) {\n let loadHint: H =\n (relationOrProp as any).loadHint ?? fail(`${source}.${fieldName} cannot be imported as it has no loadHint`);\n this.importEntity<T, H, L>(source, loadHint);\n } else if (\"import\" in relationOrProp) {\n // Tell our version of the entity (result) to accept/copy the relation state of the source\n relationOrProp.import(\n (source as any)[fieldName],\n (e: Entity) => (this.importEntity as any)(e, subHint, subHint) as Entity,\n (entities: Entity[]) => {\n if (entities === undefined) return undefined;\n const result = new Array(entities.length);\n for (let i = 0; i < entities.length; i++) {\n result[i] = (this.importEntity as any)(entities[i], subHint, subHint) as Entity;\n }\n return result;\n },\n );\n }\n }\n\n return result as any;\n }\n\n addPlugin(plugin: Plugin): void {\n getEmInternalApi(this).pluginManager.addPlugin(plugin);\n }\n\n getPlugins(): readonly Plugin[] {\n return getEmInternalApi(this).pluginManager.plugins;\n }\n\n get isRefreshing() {\n return this.#isRefreshing;\n }\n\n get isFlushing() {\n return this.#fl.isFlushing;\n }\n\n /** Creates a new `type` and marks it as loaded, i.e. we know its collections are all safe to access in memory. */\n #doCreate<T extends EntityW>(type: EntityConstructor<T>, opts: any, partial: boolean): T {\n const entity = newEntity(this, type, true);\n\n // Assign the next `a#1`, `a#2`, etc. id\n const meta = getMetadata(type);\n const counter = (this.#createCounter ??= new Map<string, number>());\n const i = (counter.get(meta.tagName) ?? 0) + 1;\n counter.set(meta.tagName, i);\n getInstanceData(entity).createId = String(i);\n\n // Check opts.id for an explicitly-set id\n this.#doRegister(entity as any, opts.id);\n\n // Set a default createdAt/updatedAt\n const baseMeta = getBaseMeta(getMetadata(entity));\n if (baseMeta.timestampFields) {\n this.#assignTimestamps(entity, baseMeta);\n }\n\n // Set the discriminator for STI\n if (baseMeta.inheritanceType === \"sti\") {\n setStiDiscriminatorValue(baseMeta, entity);\n }\n\n // api will be undefined during getFakeInstance\n const api = getEmInternalApi(this);\n api?.fieldLogger.logCreate(entity);\n\n setOpts(entity, opts, { partial, calledFromConstructor: true });\n\n // Apply any synchronous defaults, after the opts have been applied\n if (!(this as any).fakeInstance) {\n setSyncDefaults(entity);\n }\n\n this.#rm.queueAllDownstreamFields(entity, \"created\");\n\n return entity;\n }\n\n #assignTimestamps(entity: EntityW, baseMeta: EntityMetadata): void {\n const { createdAt, updatedAt } = baseMeta.timestampFields ?? {};\n const { data } = getInstanceData(entity);\n const now = new Date();\n if (createdAt) {\n const serde = baseMeta.fields[createdAt].serde as TimestampSerde<unknown>;\n data[createdAt] = serde.mapFromNow(now);\n }\n if (updatedAt) {\n const serde = baseMeta.fields[updatedAt].serde as TimestampSerde<unknown>;\n data[updatedAt] = serde.mapFromNow(now);\n }\n }\n\n /** Registers a newly-instantiated entity with our EntityManager; only called by #doCreate and hydrate. */\n #doRegister(entity: Entity, id?: string, meta?: EntityMetadata, skipDuplicateCheck: boolean = false): void {\n // Keep our indexes up to date...\n const maybeId = id ?? entity.idTaggedMaybe;\n if (maybeId) {\n if (!skipDuplicateCheck && this.findExistingInstance(maybeId) !== undefined) {\n throw new Error(`Entity ${entity} has a duplicate instance already loaded`);\n }\n this.#entitiesById.set(maybeId, entity);\n } else {\n // Also register by the `a#1` style tagged string for new entities\n this.#entitiesById.set(entity.toTaggedString(), entity);\n }\n getInstanceData(entity).entityIndex = this.#entitiesArray.length;\n this.#entitiesArray.push(entity);\n\n meta ??= getMetadata(entity);\n const set = this.#entitiesByTag.get(meta.tagName) ?? [];\n if (set.length === 0) this.#entitiesByTag.set(meta.tagName, set);\n set.push(entity);\n if (this.#entitiesArray.length >= this.entityLimit) {\n const topTypes = [...this.#entitiesByTag.entries()]\n .map(([tag, entities]) => ({ tag, count: entities.length }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 3)\n .map(({ tag, count }) => `${tag}=${count}`)\n .join(\", \");\n throw new Error(`More than ${this.entityLimit} entities have been instantiated (top entities: ${topTypes})`);\n }\n }\n}\n\n/** Provides an internal API to the `EntityManager`. */\nexport interface EntityManagerInternalApi {\n joinRows: (m2m: ManyToManyLike) => JoinRows;\n\n /** Map of taggedId -> fieldName -> pending children, i.e. when `a1.books` later loads, add/remove b1. */\n pendingPercolate: Map<string, Map<string, { adds: Entity[]; removes: Entity[] }>>;\n\n /** List of mutated o2m collections to reset added/removed post-flush. */\n mutatedCollections: Set<OneToManyCollection<any, any>>;\n\n /** O2M/M2M collections with pending set() calls that need resolution before flush. */\n pendingLoads: Set<Collection<any, any>>;\n\n /** Map of taggedId -> fieldName -> join-loaded data. */\n getPreloadedRelation<U>(taggedId: string, fieldName: string): U[] | undefined;\n setPreloadedRelation<U>(taggedId: string, fieldName: string, children: U[]): void;\n\n hooks: Record<EntityManagerHook, HookFn<any>[]>;\n rm: ReactionsManager;\n indexManager: IndexManager;\n preloader: PreloadPlugin | undefined;\n isValidating: boolean;\n checkWritesAllowed: () => void;\n isMerging: (entity: Entity) => boolean;\n get fieldLogger(): FieldLogger;\n get isLoadedCache(): IsLoadedCache;\n pluginManager: PluginManager;\n clearDataloaders(): void;\n clearPreloadedRelations(): void;\n markMaybePending(entity: EntityW): void;\n unmarkMaybePending(entity: EntityW): void;\n hasAnyDeletes(): boolean;\n pendingDeleteIds(type: MaybeAbstractEntityConstructor<Entity>): readonly IdType[];\n setIsRefreshing(isRefreshing: boolean): void;\n}\n\nexport function getEmInternalApi(em: EntityManager): EntityManagerInternalApi {\n return (em as any)[\"__api\"];\n}\n\nlet defaultEntityLimit = 50_000;\n\nexport function getDefaultEntityLimit() {\n return defaultEntityLimit;\n}\n\nexport function setDefaultEntityLimit(limit: number) {\n defaultEntityLimit = limit;\n}\n\nexport function resetDefaultEntityLimit() {\n defaultEntityLimit = 50_000;\n}\n\nexport function isKey(k: any): k is string {\n return typeof k === \"string\";\n}\n\n/** Compares `a` to `b`, where `b` might be an id. */\nexport function sameEntity(a: Entity | string | number | undefined, b: Entity | string | number | undefined): boolean {\n if (a === b) {\n return true;\n }\n // Throw in null handling for findWithNewOrChanged ambivalence\n if (a === undefined || b === undefined || a === null || b === null) {\n return (a === undefined || a === null) && (b === undefined || b === null);\n }\n // If both are entities, return if they are the same reference\n if (isEntity(a) && isEntity(b)) {\n return a === b;\n }\n // Otherwise check by ID\n const aId = isEntity(a) ? a.idTaggedMaybe : a;\n const bId = isEntity(b) ? b.idTaggedMaybe : b;\n return aId === bId;\n}\n\n/** Compares the value `a` to `b`, with handling of new entities w/o ids assigned yet. */\nexport function sameReference<T extends Entity>(a: Reference<any, T, any>, b: Reference<any, T, any>): boolean {\n return sameEntity(isLoadedReference(a) ? a.get : a.idTaggedMaybe, isLoadedReference(b) ? b.get : b.idTaggedMaybe);\n}\n\n/** Thrown by `findOneOrFail`, 'load' & 'loadAll' if an entity is not found. */\nexport class NotFoundError extends Error {}\n\n/** Thrown by `findOne` and `findOneOrFail` if more than one entity is found. */\nexport class TooManyError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * For the entities currently in `todos`, find any reactive validation rules that point\n * from the currently-changed entities back to each rule's originally-defined-in entity,\n * and ensure those entities are added to `todos`.\n */\nasync function validateReactiveRules(\n em: EntityManager,\n logger: ReactionLogger,\n todos: Record<string, Todo>,\n joinRowTodos: Record<string, JoinRowTodo>,\n // Which list of reactive rules to run, i.e. the pre-flush `reactiveRules` or the post-flush `reactiveCommitRules`\n getRules: (meta: EntityMetadata) => ReactiveRule[] = (meta) => meta.reactiveRules!,\n): Promise<void> {\n logger.logStartingValidate(em, todos);\n\n // Use a map of rule -> Set<Entity> so that we only invoke a rule once per entity,\n // even if it was triggered by multiple changed fields.\n const fns: Map<ValidationRule<any>, Set<Entity>> = new Map();\n // Concurrent walks finish in query-timing order, so the logger sorts them before writing deterministic output.\n const walks: ReactionWalk[] = [];\n\n // From the given triggered entities, follow the entity's ReactiveRule back\n // to the reactive rules that need ran, and queue them in the `fn` map\n async function followAndQueue(triggered: Entity[], rule: ReactiveRule): Promise<void> {\n if (triggered.length === 0) return;\n const found = (await followReverseHint(rule.name, triggered, rule.path))\n .filter((entity) => !entity.isDeletedEntity)\n .filter((e) => e instanceof rule.cstr);\n let entities = fns.get(rule.fn);\n if (!entities) {\n entities = new Set();\n fns.set(rule.fn, entities);\n }\n walks.push({ todo: triggered, r: rule, entities: found });\n found.forEach((entity) => {\n entities.add(entity);\n });\n }\n\n const p1 = Object.values(todos).flatMap((todo) => {\n // Find each statically-declared reactive rule for the given entity type\n const rules = getRules(todo.metadata);\n // Skip the entities spread for rule-less types\n if (rules.length === 0) return [];\n const entities = [...todo.inserts, ...todo.updates, ...todo.deletes];\n return rules.map((rule) => {\n // Of all changed entities of this type, how many specifically trigger this rule?\n const triggered = entities.filter((e) => {\n // If the rule is for a different subtype, skip it\n if (!(e instanceof rule.source)) return false;\n // Any new-or-deleted entity fires every rule (reactiveRules has already filtered out read-only)\n if (e.isNewEntity || e.isDeletedEntity) return true;\n // Otherwise see if the changed fields overlap with the rule's fields; for existing entities\n // `changes.fieldsWithoutRelations` is exactly `Object.keys(originalData)`, so probe originalData\n // directly instead of allocating a proxy + keys array per entity per rule.\n const { originalData } = getInstanceData(e);\n for (const field of rule.fields) {\n if (field in originalData) return true;\n }\n return false;\n });\n // From these \"triggered\" entities, queue the \"found\"/owner entity to rerun this rule\n return followAndQueue(triggered, rule);\n });\n });\n\n const p2 = Object.values(joinRowTodos).flatMap((todo) => {\n // For enum m2ms the columns include the enum's numeric id, so keep only the entity values.\n const entities = [...todo.newRows, ...todo.deletedRows].flatMap((jr) => Object.values(jr.columns)).filter(isEntity);\n // The owning-entity side (applies to both entity-to-entity and entity-to-enum m2ms).\n const a = getRules(todo.m2m.meta)\n .filter((rule) => rule.fields.includes(todo.m2m.fieldName))\n .map((rule) => {\n const triggered = entities.filter((e) => e instanceof todo.m2m.meta.cstr);\n return followAndQueue(triggered, rule);\n });\n // The \"other\" side only exists for entity-to-entity m2ms; enums have no reverse field.\n const { otherMeta, otherFieldName } = todo.m2m;\n const b = otherMeta\n ? getRules(otherMeta)\n .filter((rule) => rule.fields.includes(otherFieldName!))\n .map((rule) => {\n const triggered = entities.filter((e) => e instanceof otherMeta.cstr);\n return followAndQueue(triggered, rule);\n })\n : [];\n return [...a, ...b];\n });\n\n failIfAnyRejected(await Promise.allSettled([...p1, ...p2]));\n logger.logWalks(walks, \"validate\");\n\n // Now that we've found the fn+entities to run, run them and collect any errors\n const p3 = [...fns.entries()].flatMap(([fn, entities]) =>\n [...entities].map(async (entity) => coerceError(entity, await fn(entity))),\n );\n const errors = failIfAnyRejected(await Promise.allSettled(p3)).flat();\n if (errors.length > 0) {\n throw new ValidationErrors(errors);\n }\n}\n\n// Run *non-reactive* (those with `fields: undefined`) rules of explicitly mutated entities,\n// because even for reactive validations on mutated entities, we defer to addReactiveValidations\n// to mark only the rules that need to run.\nasync function validateSimpleRules(\n todos: Record<string, Todo>,\n // Which config list to pull rules from, i.e. the pre-flush `rules` or the post-flush `commitRules`\n getRules: (config: ConfigData<any, any>) => ValidationRuleInternal<any>[] = (config) => config.rules,\n): Promise<void> {\n let p: Promise<ValidationError[]>[] | undefined = undefined;\n for (const todoKey in todos) {\n const { inserts, updates } = todos[todoKey];\n for (const entities of [inserts, updates]) {\n for (const entity of entities) {\n if (entity.isDeletedEntity) continue;\n for (const m of getBaseAndSelfMetas(getMetadata(entity))) {\n for (const rule of getRules(m.config.__data)) {\n if (rule.hint !== undefined) continue;\n (p ??= []).push(invokeRule(entity, rule.fn));\n }\n }\n }\n }\n }\n if (!p) return;\n const errors = failIfAnyRejected(await Promise.allSettled(p)).flat();\n if (errors.length > 0) {\n throw new ValidationErrors(errors);\n }\n}\n\n/** Invokes a single validation rule, coercing its result/sync throws into a promise. */\nasync function invokeRule(\n entity: Entity,\n fn: (entity: any) => MaybePromise<ValidationRuleResult>,\n): Promise<ValidationError[]> {\n return coerceError(entity, await fn(entity));\n}\n\nexport function driverBeforeBegin<TXN>(em: EntityManager<any, any, TXN>, txn: TXN): Promise<unknown> {\n return Promise.all(getEmInternalApi(em).hooks.beforeBegin.map((fn) => fn(em, txn)));\n}\n\nexport function driverAfterBegin<TXN>(em: EntityManager<any, any, TXN>, txn: TXN): Promise<unknown> {\n return Promise.all(getEmInternalApi(em).hooks.afterBegin.map((fn) => fn(em, txn)));\n}\n\nexport function driverBeforeCommit<TXN>(em: EntityManager<any, any, TXN>, txn: TXN): Promise<unknown> {\n return Promise.all(getEmInternalApi(em).hooks.beforeCommit.map((fn) => fn(em, txn)));\n}\n\nexport function driverAfterCommit<TXN>(em: EntityManager<any, any, TXN>, txn: TXN): Promise<unknown> {\n return Promise.all(getEmInternalApi(em).hooks.afterCommit.map((fn) => fn(em, txn)));\n}\n\nasync function runHookOnTodos(\n ctx: unknown,\n hook: EntityHook,\n todos: Record<string, Todo>,\n keys: (\"inserts\" | \"deletes\" | \"updates\")[],\n): Promise<void> {\n // Only collect entities for todos whose type hierarchy actually has this hook, so that\n // hook-less bulk flushes skip the per-entity array building entirely.\n let entities: EntityW[] | undefined = undefined;\n for (const todoKey in todos) {\n const todo = todos[todoKey];\n if (!metaHasHook(todo.metadata, hook)) continue;\n for (const k of keys) {\n for (const e of todo[k]) {\n if (k !== \"deletes\" && e.isDeletedEntity) continue;\n (entities ??= []).push(e);\n }\n }\n }\n if (entities) return runHook(ctx, hook, entities);\n}\n\n/** Returns whether `meta`'s base/self/sub hierarchy has any `hook` functions registered. */\nfunction metaHasHook(meta: EntityMetadata, hook: EntityHook): boolean {\n for (const m of getBaseSelfAndSubMetas(meta)) {\n if (m.config.__data.hooks[hook].length > 0) return true;\n }\n return false;\n}\n\nasync function runHook(ctx: unknown, hook: EntityHook, entities: EntityW[]): Promise<void> {\n let p: Promise<unknown>[] | undefined = undefined;\n for (const entity of entities) {\n for (const m of getBaseAndSelfMetas(getMetadata(entity))) {\n for (const fn of m.config.__data.hooks[hook]) {\n // Use an explicit `async` invoke to ensure all hooks are promises, i.e. so that a\n // non-promise hook blowing up doesn't orphan the others.\n (p ??= []).push(invokeHook(fn, entity, ctx));\n }\n }\n }\n if (!p) return;\n // Use `allSettled` so that even if 1 hook blows up, we don't orphan other hooks mid-flush\n // (causes weird errors when/if they try to access the EntityManager that has \"moved on\")\n const results = await Promise.allSettled(p);\n failIfAnyRejected(results);\n}\n\n/** Invokes a single hook fn, coercing sync throws into rejections. */\nasync function invokeHook(fn: (entity: any, ctx: any) => unknown, entity: EntityW, ctx: unknown): Promise<unknown> {\n return fn(entity, ctx);\n}\n\nfunction beforeDelete(ctx: unknown, todos: Record<string, Todo>): Promise<unknown> {\n return runHookOnTodos(ctx, \"beforeDelete\", todos, [\"deletes\"]);\n}\n\nfunction beforeFlush(ctx: unknown, todos: Record<string, Todo>): Promise<unknown> {\n return runHookOnTodos(ctx, \"beforeFlush\", todos, [\"inserts\", \"updates\"]);\n}\n\nfunction beforeCreate(ctx: unknown, todos: Record<string, Todo>): Promise<unknown> {\n return runHookOnTodos(ctx, \"beforeCreate\", todos, [\"inserts\"]);\n}\n\nfunction beforeUpdate(ctx: unknown, todos: Record<string, Todo>): Promise<unknown> {\n return runHookOnTodos(ctx, \"beforeUpdate\", todos, [\"updates\"]);\n}\n\nfunction afterValidation(ctx: unknown, todos: Record<string, Todo>): Promise<unknown> {\n return runHookOnTodos(ctx, \"afterValidation\", todos, [\"inserts\", \"updates\"]);\n}\n\n/** Collects changed entities from flush todos, i.e. m2m endpoint entities. */\nfunction entitiesFromTodos(\n entityTodos: Record<string, Todo>,\n joinRowTodos: Record<string, JoinRowTodo>,\n): readonly Entity[] {\n const entities = new Set<Entity>();\n for (const todo of Object.values(entityTodos)) {\n for (const list of [todo.inserts, todo.updates, todo.deletes]) {\n for (const entity of list) entities.add(entity);\n }\n }\n for (const todo of Object.values(joinRowTodos)) {\n for (const rows of [todo.newRows, todo.deletedRows]) {\n for (const row of rows) {\n // For enum m2ms, a column value is the enum's numeric id rather than an entity.\n for (const value of Object.values(row.columns)) {\n if (isEntity(value)) entities.add(value);\n }\n }\n }\n }\n return [...entities];\n}\n\nfunction beforeCommit(ctx: unknown, entities: Set<EntityW>): Promise<unknown> {\n return runHook(ctx, \"beforeCommit\", [...entities]);\n}\n\nfunction afterCommit(ctx: unknown, entities: Set<EntityW>): Promise<unknown> {\n return runHook(ctx, \"afterCommit\", [...entities]);\n}\n\n/** Given a validation rule result `maybeError`, returns a canonical `ValidationError[]`. */\nfunction coerceError(entity: Entity, maybeError: ValidationRuleResult): ValidationError[] {\n if (maybeError === undefined) {\n return [];\n } else if (typeof maybeError === \"string\") {\n return [{ entity, message: maybeError }];\n } else if (Array.isArray(maybeError)) {\n return maybeError.map((e) => {\n if (typeof e === \"string\") {\n return { entity, message: e };\n } else {\n return { entity, ...e };\n }\n });\n } else {\n return [{ entity, ...maybeError }];\n }\n}\n\n/** Evaluates each (non-async) derived field to see if it's value has changed. */\nfunction recalcSynchronousDerivedFields(todos: Record<string, Todo>) {\n for (const todoKey in todos) {\n const todo = todos[todoKey];\n for (const entities of [todo.inserts, todo.updates]) {\n for (const entity of entities) {\n if (entity.isDeletedEntity) continue;\n // Use the per-meta cached field list instead of rebuilding a map per hook loop\n for (const fieldName of getMetadata(entity).syncDerivedFields!) {\n // setField will intelligently mark/not mark the field as dirty.\n setField(entity, fieldName as any, (entity as any)[fieldName]);\n }\n }\n }\n }\n}\n\n/** Recursively crawls through `entity`, with the given populate `deep` hint, and adds anything found to `found`. */\nasync function crawl<T extends Entity>(\n found: Set<Entity>,\n // We keep skipMap separated out, instead of tuple-izing `found`, so that `found`\n // can be a set that is cheap to insert & check for duplicates.\n skipMap: WeakMap<Entity, string[]>,\n entities: readonly T[],\n deep: LoadHint<T>,\n opts: { skipIf?: (entity: Entity) => boolean; skip?: object } = {},\n): Promise<void> {\n const { skipIf = () => false } = opts ?? {};\n\n const skip = deepNormalizeHint(opts.skip ?? {});\n // If we're passed `skip = { author: \"publisher\" }`, which is asking to \"don't set `author.publisher`\", then\n // `author` will technically be a key in the \"skip hint\", but it's only there for us to hop down into.\n // So we actually _don't_ skip any fields that have sub-hints, b/c it's the sub-hints themselves we want to skip.\n const skipFields = Object.keys(skip).filter((key) => Object.keys((skip as any)[key]).length === 0);\n\n // It's tempting to check `!found.has(entity)` here, but that would short-circuit later crawling the\n // entity at a potentially different point in the graph, i.e. a deep hint like:\n //\n // `{ comment: parent, books: { author: \"publisher\" } }`\n //\n // If the `comment.parent` was the same `Author` as a `books.author`, but we \"crawled it first\", we'd miss\n // crawling through the author a 2nd time and cloning the publisher.\n const entitiesToClone = entities.filter((e) => !skipIf(e));\n for (const entity of entitiesToClone) {\n found.add(entity);\n skipMap.set(entity, skipFields);\n }\n await Promise.all(\n entitiesToClone.flatMap((entity) =>\n (Object.entries(adaptHint(deep)) as [keyof RelationsIn<T> & string, LoadHint<any>][]).map(\n async ([relationName, nested]) => {\n const relation = entity[relationName];\n // If we're using a deep `skip` hint, drill in to it\n const _opts = { ...opts, skip: (skip as any)[relationName] };\n if (relation instanceof OneToManyCollection) {\n const relatedEntities: readonly Entity[] = await relation.load();\n await crawl(found, skipMap, relatedEntities, nested, _opts);\n } else if (relation instanceof OneToOneReferenceImpl) {\n const related: Entity | undefined = await relation.load();\n if (related) {\n await crawl(found, skipMap, [related], nested, _opts);\n }\n } else if (relation instanceof ManyToOneReferenceImpl) {\n const related: Entity | undefined = await relation.load();\n if (related) {\n await crawl(found, skipMap, [related], nested, _opts);\n }\n } else if (relation instanceof ReactiveReferenceImpl) {\n const relatedEntities: readonly Entity[] = await relation.load();\n await crawl(found, skipMap, relatedEntities, nested, _opts);\n } else {\n fail(`Uncloneable relation: ${relationName}`);\n }\n },\n ),\n ),\n );\n}\n\n/** Takes our flexible string or array or hash load hint and makes it always a hash. */\nfunction adaptHint<T extends Entity>(hint: LoadHint<T> | undefined): NestedLoadHint<T> {\n if ((typeof hint as any) === \"string\") {\n return { [hint as any]: {} } as any;\n } else if (Array.isArray(hint)) {\n return Object.fromEntries(hint.map((relation) => [relation, {}]));\n } else if (hint) {\n return hint as NestedLoadHint<T>;\n } else {\n return {};\n }\n}\n\nexport function isDefined<T extends any>(param: T | undefined | null): param is T {\n return param !== null && param !== undefined;\n}\n\nfunction getCascadeDeleteRelations(entity: Entity): AbstractRelationImpl<any, any>[] {\n return getBaseAndSelfMetas(getMetadata(entity)).flatMap((meta) => {\n return meta.config.__data.cascadeDeleteFields.map((fieldName) => (entity as any)[fieldName]);\n });\n}\n\nfunction isCustomRelation(r: AbstractRelationImpl<any, any>): boolean {\n return r instanceof CustomCollection || r instanceof CustomReference || r instanceof ReactiveReferenceImpl;\n}\n\nfunction maybeBumpUpdatedAt(rm: ReactionsManager, todos: Record<string, Todo>, now: Date): void {\n for (const todo of Object.values(todos)) {\n const { updatedAt } = todo.metadata.timestampFields ?? {};\n if (updatedAt) {\n for (const e of todo.updates) {\n // We avoid going through `setField` because in unit tests, it might detect that our\n // bump's timestamp isn't actually different from the current value, and skip treating\n // it has changed. This is technically true, but this will break the oplock SQL generation,\n // so force the field to be dirty.\n const orm = getInstanceData(e);\n orm.markFieldDirty(updatedAt, getField(e, updatedAt));\n const serde = todo.metadata.fields[updatedAt].serde as TimestampSerde<unknown>;\n orm.data[updatedAt] = serde.mapFromNow(now);\n rm.queueDownstreamReactables(e, updatedAt);\n }\n }\n }\n}\n\nlet lastNow = undefined as Date | undefined;\n\n// exposed so tests that do their own time management can override lastNow to get correct updatedAt values\nexport function setLastNow(now: Date | undefined) {\n lastNow = now;\n}\n\nfunction getNow(): Date {\n let now = new Date();\n // If we detect time has not progressed (or went backwards), we're probably in test that\n // has frozen time, which can throw off our oplocks b/c if Joist issues multiple `UPDATE`s\n // with exactly the same `updated_at`, the `updated_at` SQL trigger fallback will think \"the caller\n // didn't self-manage `updated_at`\" and so bump it for them. Which is fine, but now\n // Joist doesn't know about the bumped time, and the 2nd `UPDATE` will fail.\n if (lastNow && (lastNow.getTime() === now.getTime() || now.getTime() < lastNow.getTime())) {\n now = new Date(lastNow.getTime() + 1);\n }\n lastNow = now;\n return now;\n}\n\n/** Given a `row` from the db, resolves the CTI/STI subtype, if applicable. */\nfunction findConcreteMeta(maybeBaseMeta: EntityMetadata, rowData: RowData, rowIndex: number): EntityMetadata {\n // Common case of no CTI or STI inheritance; only probe __class for CTI metas so that\n // lazy/columnar stores don't pay a missing-column lookup per row for regular entities\n if (maybeBaseMeta.inheritanceType === undefined) {\n return maybeBaseMeta;\n }\n const __class = rowData.get(rowIndex, \"__class\");\n if (!__class && maybeBaseMeta.inheritanceType !== \"sti\") {\n return maybeBaseMeta;\n }\n if (__class) {\n if (__class === \"_\" && maybeBaseMeta.ctiAbstract) {\n const id = rowData.get(rowIndex, \"id\");\n throw new Error(`${maybeBaseMeta.type} ${tagId(maybeBaseMeta, id)} must be instantiated via a subtype`);\n }\n // Look for the CTI __class from the driver telling us which subtype to instantiate\n return maybeBaseMeta.subTypesByType!.get(__class) ?? maybeBaseMeta;\n } else if (maybeBaseMeta.inheritanceType === \"sti\") {\n // Look for the STI discriminator value\n const baseMeta = getBaseMeta(maybeBaseMeta);\n const value = rowData.get(rowIndex, baseMeta.stiDiscriminatorColumnName!);\n return baseMeta.subTypesByStiValue!.get(value) ?? baseMeta;\n } else {\n throw new Error(\"Unknown inheritance type\");\n }\n}\n\n/** Sets the `Animal.type` enum to the right subtype value. */\nfunction setStiDiscriminatorValue(baseMeta: EntityMetadata, entity: Entity): void {\n const typeName = entity.constructor.name;\n const st = baseMeta.subTypesByType!.get(typeName);\n if (st) {\n const field = baseMeta.fields[baseMeta.stiDiscriminatorField!] as EnumField;\n const code = (field.enumDetailType.findById(st.stiDiscriminatorValue!) as any).code;\n (entity as any)[baseMeta.stiDiscriminatorField!] = code;\n } else {\n (entity as any)[baseMeta.stiDiscriminatorField!] = undefined;\n }\n}\n\nfunction findPendingFlushEntities<Entity extends EntityW>(\n maybePendingFlushEntities: Set<Entity>,\n hooksInvoked: Set<Entity>,\n pendingFlush: Set<Entity>,\n pendingHooks: Set<Entity>,\n alreadyRanHooks: Set<Entity>,\n): void {\n for (const e of maybePendingFlushEntities) {\n if (getInstanceData(e).pendingOperation === \"none\") {\n maybePendingFlushEntities.delete(e);\n continue;\n }\n if (!hooksInvoked.has(e)) {\n pendingHooks.add(e);\n } else {\n alreadyRanHooks.add(e);\n }\n pendingFlush.add(e);\n }\n}\n\n/** Returns true if the caller explicitly asked `find` to use SQL pagination. */\nfunction hasPaginationSettings(options: object): boolean {\n return \"limit\" in options || \"offset\" in options;\n}\n\n/** An error we throw to get knex to `ROLLBACK`, but then catch. */\nclass InMemoryRollbackError extends Error {}\n\n/** An error thrown when `em.mode === \"read-only\"` but entities are mutated/flushed. */\nexport class ReadOnlyError extends Error {\n constructor() {\n super(\"EntityManager is read-only\");\n }\n}\n\nfunction maybeSetupHookOrdering(todos: Record<string, Todo>): Record<string, Todo>[] {\n // I'm too rushed to use a topo sort\n const group1: Record<string, Todo> = {};\n const group2: Record<string, Todo> = {};\n for (const todo of Object.values(todos)) {\n // If I should run before `cstr`, I go in group1\n const shouldRunBeforeAnotherGroup = todo.metadata.config.__data.runHooksBefore.some(\n (cstr) => getBaseMeta(getMetadata(cstr)).type in todos,\n );\n const group = shouldRunBeforeAnotherGroup ? group1 : group2;\n group[todo.metadata.type] = todo;\n }\n return Object.keys(group1).length ? [group1, group2] : [group2];\n}\n\n/**\n * Given an `err` thrown in \"a different context\", i.e. a database error or dataloader error\n * that doesn't include our stack trace, append our stack for better debugging.\n *\n * See https://github.com/brianc/node-postgres/pull/2983\n */\nexport function appendStack(err: unknown, dummy: Error): unknown {\n if (err && typeof err === \"object\" && \"stack\" in err) {\n err.stack += dummy.stack!.replace(/.*\\n/, \"\\n\");\n }\n return err;\n}\n\n/** Probe for `ctx.logger.debug` if it exists, otherwise fallback on `console.log`. */\nfunction getDefaultWriteFn(ctx: unknown): WriteFn {\n return ctx &&\n typeof ctx === \"object\" &&\n \"logger\" in ctx &&\n ctx.logger &&\n typeof ctx.logger === \"object\" &&\n \"debug\" in ctx.logger &&\n ctx.logger.debug instanceof Function\n ? ctx.logger.debug.bind(ctx.logger)\n : console.log;\n}\n\nconst fieldMap: Record<string, [Field, FieldColumn][]> = {};\n// Generates what a row from the db would look like for a given entity\nexport function createRowFromEntityData(e: Entity, opts: { preferOriginalData?: boolean } = {}) {\n const { preferOriginalData = true } = opts;\n const { rowData, rowIndex, data, originalData } = (e as any).__data as InstanceData;\n const __class = e.constructor.name;\n const { metadata: meta } = (e as any).__data as InstanceData;\n if (!fieldMap[__class]) {\n fieldMap[__class] = [];\n for (const field of Object.values(meta.allFields)) {\n if (!field.serde) continue;\n for (const column of field.serde.columns) {\n fieldMap[__class].push([field, column]);\n }\n }\n }\n\n const row: Record<string, any> = meta.inheritanceType === \"cti\" ? { __class } : {};\n\n for (const [field, column] of fieldMap[__class]) {\n const value: any =\n // Ideally, we could only go through the serde for data that has actually changed since the last time it was\n // fetched from the db and just use the row value for everything else. Unfortunately, we lose track of which\n // fields are modified on flush. So we have to assume that anything present in `data` is a change and push it\n // through the serde.\n field.fieldName in originalData || field.fieldName in data\n ? // If our field is in originalData, then the field has been changed since flush. Our `row` should\n // reflect what would come from the db if we queried it right now, so use originalData when present\n column.rowValue(preferOriginalData && field.fieldName in originalData ? originalData : data)\n : // `data` is lazy and isn't set until it's accessed, so if the field isn't present there, then we should\n // be safe to pull the raw data out of the as-loaded RowData\n rowData.get(rowIndex, column.columnName);\n row[column.columnName] = value ?? null;\n }\n return row;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EntityManager.cjs","names":["#entitiesArray","#maybePendingFlushEntities","#entitiesById","#entitiesByTag","#indexManager","IndexManager","#pendingPercolate","#joinRows","#rm","ReactionsManager","#fl","FlushLock","#hooks","#preloader","noopFieldLogger","IsLoadedCache","PluginManager","#isLoadedCache","#hasAnyDeletes","#pendingDeletes","keyToNumber","getMetadata","#merging","getOrSet","JoinRows","#preloadedRelations","#isValidating","#fieldLogger","#dataloaders","#batchLoaders","#isRefreshing","getInstanceData","#assertFindAllowed","mergeFindOptions","findPaginatedDataLoader","findDataLoader","parseUserQuery","isMutation","parseStatement","decodeStatementResult","#findRestricted","PojoRowData","findByUniqueDataLoader","mergeCountOptions","findCountDataLoader","isSelectAllFilter","findIdsDataLoader","findOrCreateDataLoader","#doCreate","upsert","getField","isEntity","asConcreteCstr","ManyToOneReferenceImpl","PolymorphicReferenceImpl","ReactiveReferenceImpl","fail","getConstructorFromTaggedId","toTaggedId","loadBatchLoader","tagId","loadLens","AsyncMethodPopulateSecret","toArray","isLoadedForPopulate","populateBatchLoader","createTodos","runInTrustedContext","groupBy","setAsyncDefaults","#flush","Todo","combineJoinRows","AsyncPropertyImpl","LazyFieldImpl","RecursiveCycleError","getBaseAndSelfMetas","ValidationErrors","constraintNameToValidationError","getRelationEntries","partition","getRelations","keyToTaggedId","newEntity","#doRegister","failIfAnyRejected","NoIdError","DataLoader","BatchLoader","ReactionLogger","FieldLogger","getMetadataForType","hasAnyKey","entityMatches","getConstructorFromTag","deepNormalizeHint","getBaseMeta","#createCounter","#assignTimestamps","isLoadedReference","followReverseHint","getBaseSelfAndSubMetas","OneToManyCollection","OneToOneReferenceImpl","CustomCollection","CustomReference"],"sources":["../src/EntityManager.ts"],"sourcesContent":["import DataLoader, { type BatchLoadFn, type Options } from \"dataloader\";\n\nimport { getInstanceData } from \"./BaseEntity.ts\";\nimport { BatchLoader } from \"./batchloaders/BatchLoader.ts\";\nimport { type enumCollectionLoadOperation } from \"./batchloaders/enumCollectionBatchLoader.ts\";\nimport { loadBatchLoader, type loadOperation } from \"./batchloaders/loadBatchLoader.ts\";\nimport { type manyToManyLoadOperation } from \"./batchloaders/manyToManyBatchLoader.ts\";\nimport { type oneToManyLoadOperation } from \"./batchloaders/oneToManyBatchLoader.ts\";\nimport { type oneToOneLoadOperation } from \"./batchloaders/oneToOneBatchLoader.ts\";\nimport { populateBatchLoader, type populateOperation } from \"./batchloaders/populateBatchLoader.ts\";\nimport { type recursiveChildrenOperation } from \"./batchloaders/recursiveChildrenBatchLoader.ts\";\nimport { type recursiveM2mOperation } from \"./batchloaders/recursiveM2mBatchLoader.ts\";\nimport { type recursiveParentsOperation } from \"./batchloaders/recursiveParentsBatchLoader.ts\";\nimport { type ConfigData, type ReactiveRule, constraintNameToValidationError } from \"./config.ts\";\nimport { getConstructorFromTag, getMetadataForType } from \"./configure.ts\";\nimport { findByUniqueDataLoader, type findByUniqueOperation } from \"./dataloaders/findByUniqueDataLoader.ts\";\nimport { findCountDataLoader, type findCountOperation, mergeCountOptions } from \"./dataloaders/findCountDataLoader.ts\";\nimport { findDataLoader, type findOperation } from \"./dataloaders/findDataLoader.ts\";\nimport { findIdsDataLoader, type findIdsOperation } from \"./dataloaders/findIdsDataLoader.ts\";\nimport { entityMatches, findOrCreateDataLoader } from \"./dataloaders/findOrCreateDataLoader.ts\";\nimport { findPaginatedDataLoader } from \"./dataloaders/findPaginatedDataLoader.ts\";\nimport { type lensOperation } from \"./dataloaders/lensDataLoader.ts\";\nimport { type manyToManyFindOperation } from \"./dataloaders/manyToManyFindDataLoader.ts\";\nimport { type oneToManyFindOperation } from \"./dataloaders/oneToManyFindDataLoader.ts\";\nimport { setAsyncDefaults, setSyncDefaults } from \"./defaults.ts\";\nimport { type Driver } from \"./drivers/index.ts\";\n// We alias `Entity => EntityW` to denote \"Entity wide\" i.e. the non-narrowed Entity\nimport { type Entity, type Entity as EntityW, type IdType, isEntity } from \"./Entity.ts\";\nimport {\n type CheckMutation,\n type ExecuteResult,\n type MutationInput,\n type MutationRow,\n decodeStatementResult,\n isMutation,\n parseStatement,\n} from \"./execute.ts\";\nimport { getField, setField } from \"./fields.ts\";\nimport { FlushLock } from \"./FlushLock.ts\";\nimport {\n CustomCollection,\n CustomReference,\n type DeepPartialOrNull,\n type EntityHook,\n type EntityMetadata,\n type EnumField,\n type ExpressionFilter,\n type Field,\n type FieldColumn,\n FieldLogger,\n type FieldLoggerWatch,\n type FindFilter,\n type GraphQLFilterOf,\n type GraphQLFilterWithAlias,\n type InstanceData,\n type Lens,\n NoIdError,\n OneToManyCollection,\n type ParsedFindQuery,\n type PartialOrNull,\n type Plugin,\n PolymorphicReferenceImpl,\n ReactionLogger,\n type ReactiveHint,\n type Reference,\n type TimestampSerde,\n type UniqueFilter,\n type ValidationError,\n ValidationErrors,\n type ValidationRule,\n type ValidationRuleInternal,\n type ValidationRuleResult,\n asConcreteCstr,\n assertLoaded,\n deepNormalizeHint,\n getBaseAndSelfMetas,\n getBaseMeta,\n getBaseSelfAndSubMetas,\n getConstructorFromTaggedId,\n getMetadata,\n getRelationEntries,\n getRelations,\n isLoadedReference,\n keyToNumber,\n keyToTaggedId,\n loadLens,\n mergeFindOptions,\n optimizeCollectionJoins,\n setOpts,\n tagId,\n toTaggedId,\n} from \"./index.ts\";\nimport { IndexManager } from \"./IndexManager.ts\";\nimport { IsLoadedCache } from \"./IsLoadedCache.ts\";\nimport { JoinRows, type ManyToManyLike } from \"./JoinRows.ts\";\nimport {\n type LoadHint,\n type Loaded,\n type NestedLoadHint,\n type New,\n type RelationsIn,\n isLoadedForPopulate,\n} from \"./loadHints.ts\";\nimport { type WriteFn } from \"./logging/FactoryLogger.ts\";\nimport { noopFieldLogger } from \"./logging/FieldLogger.ts\";\nimport { type ReactionWalk } from \"./logging/ReactionLogger.ts\";\nimport { newEntity } from \"./newEntity.ts\";\nimport { resetFactoryCreated } from \"./newTestInstance.ts\";\nimport { type PendingChange } from \"./PendingChanges.ts\";\nimport { PluginManager } from \"./PluginManager.ts\";\nimport { type PreloadPlugin } from \"./plugins/PreloadPlugin.ts\";\nimport {\n type CheckSetQuery,\n type EntityQuery,\n type QueryArg,\n type QueryJoins,\n type QueryRow,\n type QuerySelect,\n type QuerySource,\n type SetOperand,\n type SetQuery,\n type SetQueryRow,\n type Subquery,\n parseUserQuery,\n} from \"./query.ts\";\nimport { ReactionsManager } from \"./ReactionsManager.ts\";\nimport { followReverseHint } from \"./reactiveHints.ts\";\nimport { type AbstractRelationImpl } from \"./relations/AbstractRelationImpl.ts\";\nimport { AsyncPropertyImpl } from \"./relations/AsyncProperty.ts\";\nimport { type Collection } from \"./relations/Collection.ts\";\nimport { AsyncMethodPopulateSecret } from \"./relations/hasAsyncMethod.ts\";\nimport { ManyToOneReferenceImpl, OneToOneReferenceImpl, ReactiveReferenceImpl } from \"./relations/index.ts\";\nimport { LazyFieldImpl, type lazyColumnLoadOperation } from \"./relations/LazyField.ts\";\nimport { RecursiveCycleError } from \"./relations/RecursiveCollection.ts\";\nimport { PojoRowData, type RowData } from \"./RowData.ts\";\nimport { isSelectAllFilter } from \"./scopes.ts\";\nimport { type JoinRowTodo, Todo, combineJoinRows, createTodos, getTodo } from \"./Todo.ts\";\nimport { runInTrustedContext } from \"./trusted.ts\";\nimport { type OptsOf, type OrderOf } from \"./typeMap.ts\";\nimport { upsert } from \"./upsert.ts\";\nimport {\n type MaybePromise,\n assertNever,\n fail,\n failIfAnyRejected,\n getOrSet,\n groupBy,\n hasAnyKey,\n partition,\n toArray,\n} from \"./utils.ts\";\n\n// polyfill\n(Symbol as any).asyncDispose ??= Symbol(\"Symbol.asyncDispose\");\n\n/**\n * The constructor for concrete entity types.\n *\n * Abstract entity types, like a base `Publisher` class that is marked `abstract`, cannot\n * implement this and instead only have the `AbsEntityConstructor` type.\n */\nexport interface EntityConstructor<T> {\n /** The pseudo-public constructor for entities; only the `EntityManager` should actually instantiate entities. */\n new (em: EntityManager<any, any, any>): T;\n\n // Use any for now to pass the `.includes` test in `EntityConstructor.test.ts`. We could\n // probably do some sort of `tagOf(T)` look up, similar to filter types, which would return\n // either the string literal for a real `T`, or `any` if using `EntityConstructor<any>`.\n tagName: any;\n metadata: EntityMetadata;\n /** Returns the private `InstanceData` for the given entity. */\n // This isn't really necessary but prevents type errors with unions like `Author | Book`\n getInstanceData(entity: Entity): InstanceData;\n}\n\n/** Options for the auto-batchable `em.find` queries. */\nexport interface FindFilterOptions<T extends Entity> {\n conditions?: ExpressionFilter;\n orderBy?: OrderOf<T> | OrderOf<T>[];\n limit?: number | undefined;\n offset?: number | undefined;\n softDeletes?: \"include\" | \"exclude\";\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n}\n\nexport interface FindGqlFilterOptions<T extends Entity> extends Omit<FindFilterOptions<T>, \"limit\" | \"offset\"> {\n limit?: number | null | undefined;\n offset?: number | null | undefined;\n}\n\n/** Options for the `findCount`. */\nexport interface FindCountFilterOptions<T extends Entity> {\n conditions?: ExpressionFilter;\n softDeletes?: \"include\" | \"exclude\";\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n}\n\n/**\n * Constructors for either concrete or abstract entity types.\n *\n * I.e. this is more like \"MaybeAbstractEntityConstructor\".\n */\nexport type MaybeAbstractEntityConstructor<T> = abstract new (em: EntityManager<any, any, any>, opts: any) => T;\n\n/** Pulls the entity's id type out of a given entity type T. */\nexport type IdOf<T> = T extends { id: infer I } ? I : never;\n\nexport type TaggedId = string;\n\nexport function isId(value: any): value is IdOf<unknown> {\n return value && typeof value === \"string\";\n}\n\nexport type EntityManagerHook = \"beforeBegin\" | \"afterBegin\" | \"beforeCommit\" | \"afterCommit\";\n\ntype HookFn<TX> = (em: EntityManager, txn: TX) => MaybePromise<any>;\n\nexport type LoaderCache = Record<string, DataLoader<any, any>>;\n\nexport interface TimestampFields {\n updatedAt: string | undefined;\n createdAt: string | undefined;\n deletedAt: string | undefined;\n}\n\nexport type EntityManagerOpts<TX = unknown> = (\n | { driver: Driver<TX>; em?: undefined }\n | { driver?: undefined; em: EntityManager<any, any, any> }\n) & { preloadPlugin?: PreloadPlugin };\n\nexport interface FlushOptions {\n /** Skip all validations, including reactive validations, when flushing */\n skipValidation?: boolean;\n}\n\n/**\n * Describes the EntityManager read/write mode.\n *\n * - `read-only` -- any entity mutations or `em.flush` calls will fail fast\n * - `in-memory-writes` -- allows entity mutations and `em.flush` w/o a `COMMIT`\n * - `writes` -- allows entity mutations and `em.flush` will `COMMIT` writes\n */\nexport type EntityManagerMode = \"read-only\" | \"in-memory-writes\" | \"writes\";\n\nexport type FindOperation =\n | typeof findOperation\n | typeof findByUniqueOperation\n | typeof findCountOperation\n | typeof findIdsOperation\n | typeof lensOperation\n | typeof loadOperation\n | typeof manyToManyLoadOperation\n | typeof manyToManyFindOperation\n | typeof enumCollectionLoadOperation\n | typeof oneToManyLoadOperation\n | typeof oneToManyFindOperation\n | typeof oneToOneLoadOperation\n | typeof populateOperation\n | typeof recursiveChildrenOperation\n | typeof recursiveM2mOperation\n | typeof recursiveParentsOperation\n | typeof lazyColumnLoadOperation;\n\n/**\n * The EntityManager is the primary way nearly all code, i.e. anything that finds/creates/updates/deletes entities,\n * will interact with the database.\n *\n * It acts both an Identity Cache (preventing loading the same row twice into memory as separate entities, and then\n * having drift between the two instances) and as a Unit of Work (tracking all changes to entities and then batch\n * flushing only the entities that have changed).\n *\n * Note that the type parameters (C, I, and Entity) will be filled in by codegen with the values specific to your\n * application, so you can import your app-specific EntityManager like:\n *\n * ```ts\n * import { EntityManager } from \"src/entities\";\n * ```\n *\n * @param C The type of your application-specific app-wide/request-wide Context object that will be passed to hooks\n * @typeParam C - the application-specific context (typically the request-level context)\n * @typeParam Entity - the application's based entity type (i.e. with number ids or string ids)\n * @typeParamTX - the application's Transaction type, i.e. `Knex`\n */\nexport class EntityManager<C = unknown, Entity extends EntityW = EntityW, TX extends unknown = unknown> {\n public readonly ctx: C;\n public driver: Driver<TX>;\n /** When we're flushing, the connection/transaction. */\n public txn: TX | undefined;\n public entityLimit: number = defaultEntityLimit;\n readonly #entitiesArray: Entity[] = [];\n // Incrementally track dirty entities so we don't have to scan `#entityArray` during flush\n readonly #maybePendingFlushEntities: Set<Entity> = new Set();\n // Indexes the currently loaded entities by their tagged ids and `toTaggedString` ids (i.e. `a#`). This fixes\n // real-world performance issues where `findExistingInstance` scanning `#entities` was an `O(n^2)`.\n readonly #entitiesById: Map<string, Entity> = new Map();\n readonly #entitiesByTag: Map<string, Entity[]> = new Map();\n // Provides field-based indexing for entity types with >1000 entities to optimize findWithNewOrChanged\n readonly #indexManager = new IndexManager();\n #isValidating: boolean = false;\n // Set while regular (pre-flush) validation rules run, so `em.find*` can fail fast (see #assertFindAllowed)\n #findRestricted: boolean = false;\n readonly #pendingPercolate: Map<string, Map<string, { adds: Entity[]; removes: Entity[] }>> = new Map();\n #preloadedRelations: Map<string, Map<string, Entity[]>> = new Map();\n /**\n * Tracks cascade deletes.\n *\n * We originally used a beforeDelete lifecycle hook to implement this, but tracking this\n * individually allows us to a) recursively cascade deletes even during the 1st iteration\n * of our `flush` loop, and b) cascade deletions before we recalc fields & run user hooks,\n * so that both see the most accurate state.\n */\n #pendingDeletes: Entity[] = [];\n #hasAnyDeletes = false;\n #dataloaders: Record<string, LoaderCache> = {};\n #batchLoaders: Record<string, Record<string, BatchLoader<any>>> = {};\n readonly #joinRows: Record<string, JoinRows> = {};\n /** Stores any `source -> downstream` reactions to recalc during `em.flush`. */\n readonly #rm = new ReactionsManager(this);\n /** Ensures our `em.flush` method is not interrupted. */\n readonly #fl = new FlushLock();\n readonly #hooks: Record<EntityManagerHook, HookFn<any>[]> = {\n beforeBegin: [],\n afterBegin: [],\n beforeCommit: [],\n afterCommit: [],\n };\n readonly #preloader: PreloadPlugin | undefined;\n #fieldLogger: FieldLogger = noopFieldLogger;\n #isLoadedCache = new IsLoadedCache();\n #merging: Set<EntityW> | undefined;\n /** Track `a#1`, `a#2`, etc indexes for `em.create`-d entities. */\n #createCounter: Map<string, number> | undefined = undefined;\n private __api: EntityManagerInternalApi;\n #isRefreshing = false;\n mode: EntityManagerMode = \"writes\";\n\n constructor(ctx: C, opts: EntityManagerOpts<TX>);\n constructor(ctx: C, driver: Driver<TX>);\n constructor(ctx: C, driverOrOpts: EntityManagerOpts<TX> | Driver<TX>) {\n const opts = (\n driverOrOpts.constructor === Object ? driverOrOpts : { driver: driverOrOpts }\n ) as EntityManagerOpts<TX>;\n this.ctx = ctx;\n this.driver = opts.driver ?? opts.em!.driver;\n this.#preloader = opts.preloadPlugin ?? (opts.em ? opts.em.#preloader : this.driver.defaultPlugins.preloadPlugin);\n\n const pluginManager = new PluginManager(this);\n\n if (opts.em) {\n this.#hooks = {\n beforeBegin: [...opts.em.#hooks.beforeBegin],\n afterBegin: [...opts.em.#hooks.afterBegin],\n beforeCommit: [...opts.em.#hooks.beforeCommit],\n afterCommit: [...opts.em.#hooks.afterCommit],\n };\n opts.em.__api.pluginManager.cloneTo(pluginManager);\n }\n\n // Expose some of our private fields as the EntityManagerInternalApi\n const em = this;\n\n this.__api = {\n preloader: this.#preloader,\n pendingPercolate: this.#pendingPercolate,\n mutatedCollections: new Set(),\n pendingLoads: new Set(),\n hooks: this.#hooks,\n rm: this.#rm,\n indexManager: this.#indexManager,\n isLoadedCache: this.#isLoadedCache,\n pluginManager,\n\n markMaybePending(entity: EntityW): void {\n em.#maybePendingFlushEntities.add(entity as Entity);\n },\n\n unmarkMaybePending(entity: EntityW): void {\n em.#maybePendingFlushEntities.delete(entity as Entity);\n },\n\n hasAnyDeletes(): boolean {\n return em.#hasAnyDeletes;\n },\n\n pendingDeleteIds(type: MaybeAbstractEntityConstructor<Entity>): readonly IdType[] {\n return em.#pendingDeletes\n .filter((entity) => entity instanceof type && entity.idMaybe !== undefined)\n .map((entity) => keyToNumber(getMetadata(entity), entity.id));\n },\n\n isMerging(entity: EntityW): boolean {\n return em.#merging?.has(entity) ?? false;\n },\n\n joinRows(m2m: ManyToManyLike): JoinRows {\n return getOrSet(em.#joinRows, m2m.joinTableName, () => new JoinRows(m2m, em.#rm));\n },\n\n /** Returns `a:1.books` if it's in our preload cache. */\n getPreloadedRelation<U>(taggedId: string, fieldName: string): U[] | undefined {\n return em.#preloadedRelations.get(taggedId)?.get(fieldName) as U[] | undefined;\n },\n\n /** Stores `a:1.books` in our preload cache. */\n setPreloadedRelation<U>(taggedId: string, fieldName: string, children: U[]): void {\n let map = em.#preloadedRelations.get(taggedId);\n if (!map) {\n map = new Map();\n em.#preloadedRelations.set(taggedId, map);\n }\n map.set(fieldName, children as any);\n },\n\n get isValidating() {\n return em.#isValidating;\n },\n\n checkWritesAllowed(): void {\n if (em.mode === \"read-only\") throw new ReadOnlyError();\n return em.#fl.checkWritesAllowed();\n },\n\n get fieldLogger() {\n return em.#fieldLogger;\n },\n\n clearDataloaders() {\n em.#dataloaders = {};\n em.#batchLoaders = {};\n },\n\n clearPreloadedRelations() {\n em.#preloadedRelations = new Map();\n },\n\n setIsRefreshing(isRefreshing: boolean) {\n em.#isRefreshing = isRefreshing;\n },\n };\n }\n\n /** Returns a read-only shallow copy of the currently-loaded entities. */\n get entities(): ReadonlyArray<Entity> {\n return [...this.#entitiesArray];\n }\n\n /** Returns a list of all pending creates, updates, deletes, and m2m changes that would be flushed. */\n get pendingChanges(): PendingChange[] {\n const changes: PendingChange[] = [];\n for (const entity of this.#entitiesArray) {\n const op = getInstanceData(entity).pendingOperation;\n switch (op) {\n case \"insert\":\n changes.push({ kind: \"create\", entity });\n break;\n case \"update\":\n changes.push({ kind: \"update\", entity });\n break;\n case \"delete\":\n changes.push({ kind: \"delete\", entity });\n break;\n }\n }\n for (const joinRows of Object.values(this.#joinRows)) {\n const todo = joinRows.toTodo();\n // Enum m2ms (EnumCollections) aren't entity-to-entity, so skip them here.\n if (todo && !todo.m2m.otherEnum) {\n for (const row of todo.newRows) {\n const entities = Object.values(row.columns) as [Entity, Entity];\n changes.push({ kind: \"m2m\", op: \"add\", joinTableName: todo.m2m.joinTableName, entities });\n }\n for (const row of todo.deletedRows) {\n const entities = Object.values(row.columns) as [Entity, Entity];\n changes.push({ kind: \"m2m\", op: \"remove\", joinTableName: todo.m2m.joinTableName, entities });\n }\n }\n }\n return changes;\n }\n\n /** Returns a read-only list of the currently-loaded entities of `type`. */\n getEntities<T extends Entity>(type: MaybeAbstractEntityConstructor<T>): ReadonlyArray<T> {\n const meta = getMetadata(type);\n const entities = this.#entitiesByTag.get(meta.tagName) ?? [];\n // If we're a subtype, `entities` might have base/other subtypes\n return (meta.baseType ? entities.filter((e) => e instanceof type) : entities) as T[];\n }\n\n /** Looks up `id` in the list of already-loaded entities. */\n getEntity<T extends Entity & { id: string }>(id: IdOf<T>): T | undefined;\n getEntity(id: TaggedId): Entity | undefined;\n getEntity(id: TaggedId): Entity | undefined {\n // Skip this both for performance + we allow toTaggedString-style `a#1` ids\n // assertIdIsTagged(id);\n return this.#entitiesById.get(id);\n }\n\n /**\n * Finds entities of `type` with the `where` filter, with auto-batching, so this method\n * will not cause N+1s if called in a loop.\n *\n * The `where` filter is one of Joist's \"join literals\", which can combine both joining into\n * related entities and simple column conditions in a single literal. All conditions are ANDed.\n * For more complex conditions, use the `find` overload that has a `conditions` option.\n *\n * This method is batch-friendly, i.e. if called in a loop, it will be automatically batched\n * to avoid N+1s, including queries that use `LIMIT` or `OFFSET`.\n */\n public async find<T extends EntityW>(type: MaybeAbstractEntityConstructor<T>, where: FindFilter<T>): Promise<T[]>;\n public async find<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options?: FindFilterOptions<T> & { populate?: H },\n ): Promise<Loaded<T, H>[]>;\n async find<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options?: FindFilterOptions<T> & { populate?: any },\n ): Promise<T[]> {\n this.#assertFindAllowed(\"find\");\n const { populate, ...rest } = options || {};\n const normalized = mergeFindOptions(where, rest);\n const settings = { where: normalized.where, ...normalized.options };\n const result = await (\n hasPaginationSettings(normalized.options)\n ? findPaginatedDataLoader(this, type, settings, populate)\n : findDataLoader(this, type, settings, populate)\n ).catch(function find(err) {\n throw appendStack(err, new Error());\n });\n if (populate) {\n await this.populate(result, populate);\n }\n return result;\n }\n\n /**\n * Runs a SQL-shaped query written as an object literal, and returns typed rows.\n *\n * ```ts\n * const [a, b] = tables(Author, Book);\n * const rows = await em.query({\n * from: a,\n * join: [{ left: b, on: b.author_id.eq(a.id) }],\n * where: { and: [a.age.gte(minAge)] },\n * groupBy: [a.first_name],\n * select: { name: a.first_name, bookCount: b.id.count() },\n * orderBy: { bookCount: \"DESC\" },\n * });\n * // → { name: string; bookCount: number }[]\n * ```\n *\n * `select` decides the row type: a bare table (`select: a`) returns entities through the identity\n * map, a `{ key: expr }` object returns typed POJOs, and a `query(...)` value returns its rows. Joins\n * are pruned like `em.find`: an `undefined` condition drops out, and a join nothing references\n * anymore drops with it. See `query.ts` for the full DSL, and `query()` for composing subqueries.\n *\n * Entity selections accept a second argument, `{ populate: hint }`, and return `Loaded` entities.\n * Population runs after the query, using the same relation loaders as `em.populate`.\n * This method is not batched: these are custom queries, too unique to batch.\n */\n public query<R>(q: Subquery<R, any>): Promise<R[]>;\n public query<T extends Entity>(q: EntityQuery<T>): Promise<T[]>;\n public query<T extends Entity, const H extends LoadHint<T>>(\n q: EntityQuery<T>,\n options: { populate: H },\n ): Promise<Loaded<T, H>[]>;\n public query<const Q extends SetQuery<readonly SetOperand[]>>(q: Q & CheckSetQuery<Q>): Promise<SetQueryRow<Q>[]>;\n public query<F extends QuerySource, const S extends QuerySelect = never, J extends QueryJoins = []>(\n q: QueryArg<F, S, J, never>,\n ): Promise<QueryRow<S, J>[]>;\n public query<\n F extends QuerySource,\n const S extends QuerySelect,\n const H extends LoadHint<Extract<QueryRow<S, J>, EntityW>>,\n J extends QueryJoins = [],\n >(\n q: QueryArg<F, S, J, never>,\n options: QueryRow<S, J> extends EntityW ? { populate: H } : never,\n ): Promise<Loaded<Extract<QueryRow<S, J>, EntityW>, H>[]>;\n public query(q: unknown, options?: { populate: LoadHint<EntityW> }): Promise<any[]> {\n this.#assertFindAllowed(\"query\");\n const em = this;\n return (async function query() {\n const plan = parseUserQuery(q);\n if (options?.populate && plan.output.kind !== \"entity\") {\n fail(\"em.query populate requires an entity selection\");\n }\n const { rows } = await em.driver.executeQuery(em, plan.sql, plan.bindings);\n const result = plan.decodeRows(em, rows);\n if (options?.populate) {\n await em.populate(result, options.populate);\n }\n return result;\n })().catch(function query(err) {\n throw appendStack(err, new Error());\n });\n }\n\n /**\n * Executes immediate SQL with a native command count. Mutations bypass the entity unit of work;\n * reads retain query's decoding and permissions. Neither path flushes or repairs cached entities.\n */\n public execute<const M extends MutationInput>(\n statement: M & CheckMutation<M>,\n ): Promise<ExecuteResult<MutationRow<M>>>;\n public execute<R>(statement: Subquery<R, any>): Promise<ExecuteResult<R>>;\n public execute<T extends Entity>(statement: EntityQuery<T>): Promise<ExecuteResult<T>>;\n public execute<const Q extends SetQuery<readonly SetOperand[]>>(\n statement: Q & CheckSetQuery<Q>,\n ): Promise<ExecuteResult<SetQueryRow<Q>>>;\n public execute<F extends QuerySource, const S extends QuerySelect = never, J extends QueryJoins = []>(\n statement: QueryArg<F, S, J, never>,\n ): Promise<ExecuteResult<QueryRow<S, J>>>;\n public execute(statement: unknown): Promise<ExecuteResult<unknown>> {\n const em = this;\n return (async function execute() {\n if (isMutation(statement)) {\n em.__api.checkWritesAllowed();\n if (em.mode === \"in-memory-writes\") fail(\"SQL mutations do not support in-memory-writes mode\");\n } else {\n em.#assertFindAllowed(\"execute\");\n }\n const plan = parseStatement(statement);\n if (!plan) return { rowCount: 0, rows: [] };\n const result = await em.driver.executeQuery(em, plan.sql, plan.bindings);\n return decodeStatementResult(em, plan, result);\n })().catch(function execute(err) {\n throw appendStack(err, new Error());\n });\n }\n\n /** Fails fast if `em.${method}` is called from a regular validation rule, i.e. steers to `config.addCommitRule`. */\n #assertFindAllowed(method: string): void {\n if (this.#findRestricted) {\n throw new Error(\n `em.${method} cannot be called from a validation rule (added via config.addRule), because rules run ` +\n `before the flush and would query stale, pre-flush data. Use config.addCommitRule instead, which runs ` +\n `after the INSERT/UPDATE/DELETEs are flushed (within the same transaction) and so sees the changed state.`,\n );\n }\n }\n\n /** Runs the post-parse find pipeline: plugins mutate the logical AST, then Joist optimizes/prunes before SQL. */\n private async executeFind(\n meta: EntityMetadata,\n operation: FindOperation,\n parsed: ParsedFindQuery,\n settings: {\n limit?: number;\n offset?: number;\n checkLimit?: boolean;\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n pruneJoins?: boolean;\n keepAliases?: string[];\n },\n ) {\n const { checkLimit, findSettings } = this.prepareFind(meta, operation, parsed, settings);\n return this.executePreparedFind(meta, operation, parsed, findSettings, checkLimit);\n }\n\n /** Like {@link executeFind}, but returns a {@link RowData}; see {@link executePreparedFindRowData}. */\n private async executeFindRowData(\n meta: EntityMetadata,\n operation: FindOperation,\n parsed: ParsedFindQuery,\n settings: {\n limit?: number;\n offset?: number;\n checkLimit?: boolean;\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n pruneJoins?: boolean;\n keepAliases?: string[];\n },\n ): Promise<RowData> {\n const { checkLimit, findSettings } = this.prepareFind(meta, operation, parsed, settings);\n return this.executePreparedFindRowData(meta, operation, parsed, findSettings, checkLimit);\n }\n\n /** Executes a query that has already had find hooks and optimizations applied. */\n private async executePreparedFind(\n meta: EntityMetadata,\n operation: FindOperation,\n parsed: ParsedFindQuery,\n findSettings: {\n limit?: number;\n offset?: number;\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n pruneJoins?: boolean;\n keepAliases?: string[];\n },\n checkLimit: boolean | undefined,\n ) {\n const { pluginManager } = getEmInternalApi(this);\n const rows = await this.driver.executeFind(this, parsed, findSettings);\n // Check by default unless explicitly disabled or the caller removed the LIMIT via `limit: undefined`\n const shouldCheck = checkLimit ?? !(\"limit\" in findSettings && findSettings.limit === undefined);\n if (shouldCheck && rows.length >= this.entityLimit) {\n throw new Error(`Query returned more than ${this.entityLimit} entityLimit rows`);\n }\n if (pluginManager.hasHook(\"afterFind\")) {\n pluginManager.afterFind(meta, operation, new PojoRowData(rows));\n }\n return rows;\n }\n\n /**\n * Like {@link executePreparedFind}, but returns a {@link RowData}: lazy wire rows when the\n * driver has `lazyRows` enabled, else classic POJO rows wrapped in a `PojoRowData` — so\n * loaders can hydrate from one shape without caring which the driver provides.\n */\n private async executePreparedFindRowData(\n meta: EntityMetadata,\n operation: FindOperation,\n parsed: ParsedFindQuery,\n findSettings: {\n limit?: number;\n offset?: number;\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n pruneJoins?: boolean;\n keepAliases?: string[];\n },\n checkLimit: boolean | undefined,\n ): Promise<RowData> {\n const { executeFindRowData } = this.driver;\n if (executeFindRowData === undefined) {\n return new PojoRowData(await this.executePreparedFind(meta, operation, parsed, findSettings, checkLimit));\n }\n const { pluginManager } = getEmInternalApi(this);\n const rowData = await executeFindRowData.call(this.driver, this, parsed, findSettings);\n // Check by default unless explicitly disabled or the caller removed the LIMIT via `limit: undefined`\n const shouldCheck = checkLimit ?? !(\"limit\" in findSettings && findSettings.limit === undefined);\n if (shouldCheck && rowData.rowCount >= this.entityLimit) {\n throw new Error(`Query returned more than ${this.entityLimit} entityLimit rows`);\n }\n // The hook receives the lazy RowData view directly, so observe-only hooks (i.e. metrics\n // reading `rowCount`) never materialize cells; hooks call `toRows()` if they want POJOs\n pluginManager.afterFind(meta, operation, rowData);\n return rowData;\n }\n\n /**\n * Runs pre-SQL find hooks and optimizations against a parsed query.\n *\n * This allows plugins to see \"pre-batched\" / \"logical\" query ASTs, instead of our\n * more complicated `_find` batched queries. The flow would be:\n *\n * - A loader calls `prepareFind(originalQuery)`\n * - Plugins inspect/modify the query as/if needed\n * - The loader crafts a new, more complicated query that embeds the originalQuery\n * - The loader calls `executePreparedFind` with the 2nd query\n */\n private prepareFind(\n meta: EntityMetadata,\n operation: FindOperation,\n parsed: ParsedFindQuery,\n settings: {\n limit?: number;\n offset?: number;\n checkLimit?: boolean;\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n pruneJoins?: boolean;\n keepAliases?: string[];\n },\n ) {\n const { checkLimit, ...findSettings } = settings;\n const { pluginManager } = getEmInternalApi(this);\n // Plugins may mutate the settings object, so return the post-hook version that loaders must reuse.\n pluginManager.beforeFind(meta, operation, parsed, findSettings);\n optimizeCollectionJoins(parsed, settings);\n return { checkLimit, findSettings };\n }\n\n /**\n * Works exactly like `find` but accepts \"less than greatly typed\" GraphQL filters.\n *\n * I.e. filtering by `null` on fields that are non-`nullable`.\n */\n public async findGql<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: GraphQLFilterWithAlias<T>,\n ): Promise<T[]>;\n public async findGql<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n where: GraphQLFilterWithAlias<T>,\n options?: FindGqlFilterOptions<T> & { populate?: H },\n ): Promise<Loaded<T, H>[]>;\n async findGql<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: GraphQLFilterOf<T>,\n options?: FindGqlFilterOptions<T> & { populate?: any },\n ): Promise<T[]> {\n if (!options) {\n return this.find(type, where as any);\n }\n const normalized = { ...options };\n if (\"limit\" in normalized) normalized.limit = normalized.limit ?? undefined;\n if (\"offset\" in normalized) normalized.offset = normalized.offset ?? undefined;\n return this.find(type, where as any, normalized as any);\n }\n\n public async findOne<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n ): Promise<T | undefined>;\n public async findOne<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options?: FindFilterOptions<T> & { populate?: H },\n ): Promise<Loaded<T, H> | undefined>;\n async findOne<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options?: FindFilterOptions<T> & { populate?: any },\n ): Promise<T | undefined> {\n const list = await this.find(type, where, options);\n if (list.length === 0) {\n return undefined;\n } else if (list.length === 1) {\n return list[0];\n } else {\n throw new TooManyError(`Found more than one: ${list.map((e) => e.toString()).join(\", \")}`);\n }\n }\n\n /** Executes a given query filter and returns exactly one result, otherwise throws `NotFoundError` or `TooManyError`. */\n public async findOneOrFail<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n ): Promise<T>;\n public async findOneOrFail<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options: FindFilterOptions<T> & { populate?: H },\n ): Promise<Loaded<T, H>>;\n async findOneOrFail<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options?: FindFilterOptions<T> & { populate?: any },\n ): Promise<T> {\n const list = await this.find(type, where, options);\n if (list.length === 0) {\n throw new NotFoundError(`Did not find ${type.name} for given query`);\n } else if (list.length > 1) {\n throw new TooManyError(`Found more than one: ${list.map((e) => e.toString()).join(\", \")}`);\n }\n return list[0];\n }\n\n public async findByUnique<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: UniqueFilter<T>,\n ): Promise<T | undefined>;\n public async findByUnique<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n where: UniqueFilter<T>,\n options?: { populate?: H; softDeletes?: \"include\" | \"exclude\" },\n ): Promise<Loaded<T, H> | undefined>;\n async findByUnique<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: UniqueFilter<T>,\n options: { populate?: any; softDeletes?: \"include\" | \"exclude\" } = {},\n ): Promise<T | undefined> {\n this.#assertFindAllowed(\"findByUnique\");\n const { populate, softDeletes = \"exclude\" } = options;\n const entries = Object.entries(where);\n if (entries.length !== 1) {\n throw new Error(\"findByUnique only accepts a single field\");\n }\n const [fieldName, value] = entries[0];\n const field = getMetadata(type).allFields[fieldName];\n const row = await findByUniqueDataLoader(this, type, field, softDeletes)\n .load(value)\n .catch(function findByUnique(err) {\n throw appendStack(err, new Error());\n });\n if (!row) {\n return undefined;\n } else {\n const [entity] = this.hydrate(type, [row]);\n if (this.#hasAnyDeletes && entity.isDeletedEntity) {\n return undefined;\n }\n if (populate) {\n await this.populate(entity, populate);\n }\n return entity;\n }\n }\n\n /**\n * Returns the count of entities that match the `where` clause.\n *\n * The `where` clause, and any options.conditions, matches the same syntax\n * as `em.find`.\n *\n * Note: this method is not currently auto-batched, so it will cause N+1s if called in a loop.\n */\n async findCount<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T> | GraphQLFilterWithAlias<T>,\n options: FindCountFilterOptions<T> = {},\n ): Promise<number> {\n this.#assertFindAllowed(\"findCount\");\n const normalized = mergeCountOptions(where, options);\n const settings = { where: normalized.where, ...normalized.options } as any;\n let count = await findCountDataLoader(this, type, settings).catch(function findCount(err) {\n throw appendStack(err, new Error());\n });\n // If the user is do \"count all\", we can adjust the number up/down based on\n // WIP creates/deletes. We can't do this if the WHERE clause is populated b/c\n // then we'd also have to eval each created/deleted entity against the WHERE\n // clause before knowing if it should adjust teh amount.\n const isSelectAll = isSelectAllFilter(where, options.conditions);\n if (isSelectAll) {\n const tagged = this.#entitiesByTag.get(getMetadata(type).tagName) ?? [];\n for (const entity of tagged) {\n // Still do an `instanceof` to handle subtypes\n if (entity instanceof type) {\n if (entity.isNewEntity) {\n count++;\n } else if (entity.isDeletedEntity) {\n count--;\n }\n }\n }\n }\n\n return count;\n }\n\n /**\n * Returns the IDs of entities that match the `where` clause.\n *\n * The `where` clause, and any options.conditions, matches the same syntax\n * as `em.find`.\n */\n async findIds<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n where: FindFilter<T>,\n options: FindCountFilterOptions<T> = {},\n ): Promise<string[]> {\n this.#assertFindAllowed(\"findIds\");\n const normalized = mergeCountOptions(where, options);\n const settings = { where: normalized.where, ...normalized.options };\n return findIdsDataLoader(this, type, settings).catch(function findIds(err) {\n throw appendStack(err, new Error());\n });\n }\n\n /**\n * Looks for entities that match `where`, both in the database and any just-created or just-changed entities.\n *\n * Because we evaluate this `where` clause in memory (against any WIP changes made to entities\n * that have not yet been `em.flush`ed to the database), the `where` clause is limited to fields\n * immediately available on the entity, i.e. primitives, enums, and many-to-ones, without any\n * nested, cross-table joins/conditions.\n *\n * For `m2o` fields, `undefined` will be pruned, just like `em.find`s. I.e. `{ publisher: undefined }` will\n * be pruned and not filter on `publisher` at all, where as `{ publisher: null }` will filter for `publisher`\n * is unset.\n *\n * @param type the entity type to find\n * @param where the fields to look up the existing entity by\n */\n async findWithNewOrChanged<T extends Entity, F extends Partial<OptsOf<T>>>(\n type: EntityConstructor<T>,\n where: F,\n ): Promise<T[]>;\n async findWithNewOrChanged<T extends Entity, F extends Partial<OptsOf<T>>, const H extends LoadHint<T>>(\n type: EntityConstructor<T>,\n where: F,\n options?: { populate?: H; softDeletes?: \"include\" | \"exclude\" },\n ): Promise<Loaded<T, H>[]>;\n async findWithNewOrChanged<T extends Entity, F extends Partial<OptsOf<T>>, const H extends LoadHint<T>>(\n type: EntityConstructor<T>,\n where: F,\n options?: { populate?: H; softDeletes?: \"include\" | \"exclude\" },\n ): Promise<T[]> {\n const { softDeletes = \"exclude\", populate } = options ?? {};\n // Make a copy of `where` because `em.find` will re-write new entities to `-1`, that our `entityMatches` could still match\n // ...and also prune `undefined` here, since `em.find` will do it anyway, but `entityMatches` does not.\n const copy: any = Object.fromEntries(Object.entries(where).filter(([, v]) => v !== undefined));\n const persisted = await this.find(type, copy, { softDeletes });\n const unchanged = persisted.filter((e) => !e.isNewEntity && !e.isDirtyEntity && !e.isDeletedEntity);\n const maybeNew = this.filterEntities<T>(type, where).filter(\n (e) => (e.isNewEntity || e.isDirtyEntity) && !e.isDeletedEntity,\n );\n const found = [...unchanged, ...maybeNew];\n if (populate) {\n await this.populate(found, populate as any);\n }\n return found as unknown as T[];\n }\n\n /**\n * Conditionally finds or creates (or upserts) an Entity.\n *\n * The `where` param is used to find the existing/if any entity; if not found,\n * then one will be created.\n *\n * The `ifNew` param will be used, if no entity is found, for the `em.create` call;\n * it is typed such that it will require all opts necessary for the `em.create` to\n * be valid, _unless_ those opts are already included in either the `where` or\n * `upsert` params.\n *\n * The optional `upsert` param are fields to always set/update, regardless of whether\n * the entity is created or not.\n *\n * @param type the entity type to find/create\n * @param where the fields to look up the existing entity by\n * @param ifNew the fields to set if the entity is new\n * @param upsert the fields to update if the entity is either existing or new\n */\n async findOrCreate<\n T extends EntityW,\n F extends Partial<OptsOf<T>>,\n U extends Partial<OptsOf<T>> | {},\n N extends Omit<OptsOf<T>, keyof F | keyof U>,\n >(type: EntityConstructor<T>, where: F, ifNew: N, upsert?: U): Promise<T>;\n async findOrCreate<\n T extends EntityW,\n F extends Partial<OptsOf<T>>,\n U extends Partial<OptsOf<T>> | {},\n N extends Omit<OptsOf<T>, keyof F | keyof U>,\n const H extends LoadHint<T>,\n >(\n type: EntityConstructor<T>,\n where: F,\n ifNew: N,\n upsert?: U,\n options?: { populate?: H; softDeletes?: \"include\" | \"exclude\" },\n ): Promise<Loaded<T, H>>;\n async findOrCreate<\n T extends EntityW,\n F extends Partial<OptsOf<T>>,\n U extends Partial<OptsOf<T>> | {},\n N extends Omit<OptsOf<T>, keyof F | keyof U>,\n const H extends LoadHint<T>,\n >(\n type: EntityConstructor<T>,\n where: F,\n ifNew: N,\n upsert?: U,\n options?: { populate?: H; softDeletes?: \"include\" | \"exclude\" },\n ): Promise<T> {\n const { softDeletes = \"exclude\", populate } = options ?? {};\n const entity = await findOrCreateDataLoader(this, type, where, softDeletes)\n .load({ ifNew: ifNew as OptsOf<T>, upsert })\n .catch(function findOrCreate(err) {\n throw appendStack(err, new Error());\n });\n if (populate) {\n await this.populate(entity, populate);\n }\n return entity;\n }\n\n /** Creates a new `type` and marks it as loaded, i.e. we know its collections are all safe to access in memory. */\n public create<T extends EntityW, O extends OptsOf<T>>(type: EntityConstructor<T>, opts: O): New<T, O> {\n return this.#doCreate(type, opts, false) as New<T, O>;\n }\n\n /**\n * Creates a new `type` but with `opts` that are nullable, to accept partial-update-style input.\n *\n * Note that `createPartial` doesn't support the full upsert behavior, i.e. this method:\n *\n * - always creates,\n * - does not support relation markers like `op`, `delete`, and `remove`,\n * - does not accept deep input, but\n * - fields set to `undefined` will be skipped instead of unset\n *\n * See `upsert` for the upsert/deep upsert behavior.\n */\n public createPartial<T extends EntityW>(type: EntityConstructor<T>, opts: PartialOrNull<OptsOf<T>>): T {\n return this.#doCreate(type, opts, true);\n }\n\n /**\n * Create or updates `type` based on partial-update-style `input`.\n *\n * This supports upsert behavior, i.e.:\n *\n * - findOrCreate the primary entity being updated (based on the `id` key being provided),\n * - upsert relation markers like `op`, `delete`, and `remove` are supported,\n * - deep input is supported, i.e. `{ firstName: \"Bob\", books: [{ title: \"b1\" } ] }`, and\n * - fields set to `undefined` will be skipped instead of unset\n */\n public upsert<T extends EntityW>(type: EntityConstructor<T>, input: DeepPartialOrNull<T>): Promise<T> {\n return upsert(this, type, input);\n }\n\n /**\n * Utility to clone an entity and its nested relations, as determined by a populate hint\n *\n * @param entity - Any entity\n * @param opts - Options to control the clone behaviour\n * @param deep - Populate hint of the nested tree of objects to clone\n * @param skip - Keys that will be skipped in the clone\n * @param skipIf - Predicate for determining if a specific entity should be skipped (and any entities beneath it\n * @param postClone - Function to be called for each original/clone entity for any post-processing needed\n * @returns The `Loaded` cloned entity or fails if the clone could not be made\n *\n * @example\n * // This will duplicate the author\n * const duplicatedAuthor = await em.clone(author)\n *\n * @example\n * // This will duplicate the author and all their related book entities\n * const duplicatedAuthorAndBooks = await em.clone(author, { deep: \"books\" })\n *\n * @example\n * // This will duplicate the author, all their books, and the images for those books\n * const duplicatedAuthorAndBooksAndImages = await em.clone(author, { deep: { books: \"image\" } })\n *\n * @example\n * // This will duplicate the author, and rename\n * const duplicatedAuthor = await em.clone(author, { postClone: (_original, clone) => clone.firstName = clone.firstName + \" COPY\" })\n *\n * @example\n * // This will duplicate the author, but skip any book where the title includes `sea`\n * const duplicatedAuthor = await em.clone(author, { skipIf: (original) => original.title?.includes(\"sea\") })\n */\n public async clone<T extends Entity, H extends LoadHint<T>, const K = ReactiveHint<T>>(\n entity: T,\n opts?: {\n deep?: H;\n skip?: K;\n skipIf?: (entity: Entity) => boolean;\n postClone?: (original: Entity, clone: Entity) => void;\n },\n ): Promise<Loaded<T, H>>;\n\n /**\n * Utility to clone an entity and its nested relations, as determined by a populate hint.\n *\n * @param entities - Any homogeneous list of entities\n * @param opts - Options to control the clone behaviour\n * @param deep - Populate hint of the nested tree of objects to clone\n * @param skip - Keys that will be skipped in the clone\n * @param skipIf - Predicate for determining if a specific entity should be skipped (and any entities beneath it\n * @param postClone - Function to be called for each original/clone entity for any post-processing needed\n * @returns Array of `Loaded` cloned entities from the provided list or empty array if all are skipped\n *\n * @example\n * // This will duplicate the author's books\n * const duplicatedBooks = await em.clone(author.books.get)\n *\n * @example\n * // This will duplicate the author's books, all their books, and the images for those books\n * const duplicatedBooksAndImages = await em.clone(author.books.get, { deep: { books: \"image\" } })\n *\n * @example\n * // This will duplicate the author's books, and assign them to a different author\n * const duplicatedBooks = await em.clone(author.books.get, { postClone: (_original, clone) => clone.author.set(author2) })\n *\n * @example\n * // This will duplicate the author's books, but skip any book where the title includes `sea`\n * const duplicatedBooks = await em.clone(author.books.get, { skipIf: (original) => original.title.includes(\"sea\") })\n */\n public async clone<T extends Entity, H extends LoadHint<T>, const K = ReactiveHint<T>>(\n entities: readonly T[],\n opts?: {\n deep?: H;\n skip?: K;\n skipIf?: (entity: Entity) => boolean;\n postClone?: (original: Entity, clone: Entity) => void;\n },\n ): Promise<Loaded<T, H>[]>;\n\n public async clone<T extends Entity, H extends LoadHint<T>>(\n entityOrArray: T | readonly T[],\n opts?: {\n deep?: H;\n skip?: object;\n skipIf?: (entity: Entity) => boolean;\n postClone?: (original: Entity, clone: Entity) => void;\n },\n ): Promise<Loaded<T, H> | Loaded<T, H>[]> {\n const { deep = {}, skipIf, skip = {}, postClone } = opts ?? {};\n // Keep a list that we can work against synchronously after doing the async find/crawl\n const todo = new Set<Entity>();\n const skipMap = new WeakMap<Entity, string[]>();\n\n // 1. Find all entities w/o mutating them yet\n await crawl(todo, skipMap, Array.isArray(entityOrArray) ? entityOrArray : [entityOrArray], deep, {\n skipIf: skipIf as any,\n skip,\n });\n\n // 2. Clone each found entity\n const deferredRelations: [Entity, string, Entity][] = [];\n const clones = [...todo].map((entity) => {\n const skip = skipMap.get(entity) ?? [];\n // Use meta.fields to see which fields are derived (i.e. createdAt, updatedAt, initials)\n // that only have getters, and so we shouldn't set (createdAt/updatedAt will be initialized\n // by `em.register`).\n const meta = getMetadata(entity);\n const copy = Object.fromEntries(\n Object.values(meta.allFields)\n .map((f) => {\n if (skip.includes(f.fieldName)) return undefined;\n switch (f.kind) {\n case \"primitive\":\n if (!f.derived && !f.protected) {\n return [f.fieldName, getField(entity, f.fieldName)];\n } else {\n return undefined;\n }\n case \"enum\":\n if (f.derived) {\n return undefined;\n } else {\n return [f.fieldName, getField(entity, f.fieldName)];\n }\n case \"m2o\":\n case \"poly\": {\n if (f.kind === \"m2o\" && f.derived) return undefined;\n const existingIdOrEntity = getField(entity, f.fieldName);\n const target = (\n isEntity(existingIdOrEntity) ? existingIdOrEntity : this.getEntity(existingIdOrEntity)\n ) as Entity | undefined;\n // Defer relations within the cloned subgraph because setting a clone field before remapping can update\n // its other side, and that update is not fixed up later.\n if (target && todo.has(target)) {\n deferredRelations.push([entity, f.fieldName, target]);\n return [f.fieldName, undefined];\n } else {\n return [f.fieldName, existingIdOrEntity];\n }\n }\n case \"primaryKey\":\n case \"o2m\":\n case \"m2m\":\n case \"m2mEnum\":\n case \"o2o\":\n case \"lo2m\":\n return undefined;\n default:\n assertNever(f);\n }\n })\n .filter(isDefined),\n );\n\n // Call `new` just like the user would do\n // The `asConcreteCstr` is safe b/c we got meta from a concrete/already-instantiated entity\n const clone = this.create(asConcreteCstr(meta.cstr), copy);\n\n return [entity, clone] as const;\n });\n const entityToClone: Map<EntityW, EntityW> = new Map(clones);\n\n // 3. Now mutate the m2o relations. We focus on only m2o's because they \"own\" the field/column,\n // and will drive percolation to keep the other-side o2m & o2o updated.\n clones.forEach(([, clone]) => {\n getRelationEntries(clone).forEach(([fieldName, value]) => {\n if (\n value instanceof ManyToOneReferenceImpl ||\n value instanceof PolymorphicReferenceImpl ||\n value instanceof ReactiveReferenceImpl\n ) {\n // What's the existing entity? Have we cloned it?\n const existingIdOrEntity = getField(clone, fieldName);\n // Use O(1) lookup via #entitiesById Map instead of O(N) .find() scan\n const existing = isEntity(existingIdOrEntity) ? existingIdOrEntity : this.getEntity(existingIdOrEntity);\n // If we didn't find a loaded entity for this value, assume that it a) itself is not being cloned,\n // and b) we don't need to bother telling it about the newly cloned entity\n if (existing) {\n ((clone as any)[fieldName] as any).set(entityToClone.get(existing) ?? existing);\n }\n }\n });\n });\n\n deferredRelations.forEach(([source, fieldName, target]) => {\n const clone = entityToClone.get(source)!;\n ((clone as any)[fieldName] as any).set(entityToClone.get(target)!);\n });\n\n if (postClone) {\n await Promise.all(clones.map(([original, clone]) => postClone(original, clone)));\n }\n\n return Array.isArray(entityOrArray)\n ? entityOrArray\n .filter((original) => entityToClone.has(original))\n .map((original) => entityToClone.get(original) as unknown as Loaded<T, H>)\n : clones[0]\n ? (clones[0][1] as unknown as Loaded<T, H>)\n : fail(\"no entities were cloned given the provided options\");\n }\n\n /**\n * Merges multiple source entities into a target entity by updating all references that point\n * to the source entities to instead point to the target entity.\n *\n * This method loads all relations from the source entities, updates any entity that\n * references a source entity to reference the target entity instead, and then automatically\n * deletes the source entities.\n *\n * @param target - The entity that will become the target of all merged references\n * @param sources - Array of entities whose references will be redirected to the target\n * @param opts - Options to control merge behavior\n * @param autoDelete - Whether to automatically delete source entities (default: true)\n * @returns Promise that resolves when all references have been updated and sources deleted\n *\n * @example\n * // Merge duplicate authors - all books pointing to author2 will now point to author1\n * // author2 will be automatically deleted\n * await em.merge(author1, [author2]);\n *\n * @example\n * // Merge multiple duplicate publishers into one\n * // publisher2 and publisher3 will be automatically deleted\n * await em.merge(publisher1, [publisher2, publisher3]);\n *\n * @example\n * // Merge without auto-deleting sources (for custom cleanup logic)\n * await em.merge(author1, [author2], { autoDelete: false });\n * // Custom logic here...\n * em.delete(author2);\n */\n public async merge<T extends Entity>(target: T, sources: T[], opts?: { autoDelete?: boolean }): Promise<Entity[]> {\n const autoDelete = opts?.autoDelete ?? true;\n if (sources.length === 0) return [];\n\n this.#merging ??= new Set();\n // Allow cannotBeUpdated to see that anyone pointed to the new target is allowed to change\n this.#merging.add(target);\n\n // Make sure source and target are the same type (Before we call `populate` below which will fail on invalid load hints)\n const targetMeta = getMetadata(target);\n for (const source of sources) {\n const sourceMeta = getMetadata(source);\n if (sourceMeta.type !== targetMeta.type) {\n throw new Error(`Cannot merge entities of different types: ${targetMeta.type} and ${sourceMeta.type}`);\n }\n }\n\n const fields = Object.values(targetMeta.allFields)\n .filter((field) => [\"o2m\", \"m2o\", \"m2m\", \"o2o\"].includes(field.kind))\n .map((field) => field.fieldName);\n await this.populate(sources, fields as any as LoadHint<T>);\n\n const changedEntities: Entity[] = [];\n for (const source of sources) {\n // Find all reverse relations (things that point to this entity)\n for (const field of Object.values(targetMeta.allFields)) {\n const { kind } = field;\n if (kind === \"o2m\") {\n for (const other of (source as any)[field.fieldName].get) {\n this.#merging.add(other); // Tell ReactionsManager to react to normally-read-only fields\n (other as any)[field.otherFieldName].set(target);\n changedEntities.push(other);\n }\n } else if (kind === \"o2o\") {\n const otherField = field.otherMetadata().allFields[field.otherFieldName];\n if (otherField.kind === \"m2o\" && otherField.derived) continue;\n const other = (source as any)[field.fieldName].get;\n if (other) {\n this.#merging.add(other); // Tell ReactionsManager to react to normally-read-only fields\n (other as any)[field.otherFieldName].set(target);\n changedEntities.push(other);\n }\n } else if (kind === \"m2m\") {\n for (const other of (source as any)[field.fieldName].get) {\n this.#merging.add(other); // Tell ReactionsManager to react to normally-read-only fields\n const collection = (other as any)[field.otherFieldName];\n collection.remove(source);\n collection.add(target);\n changedEntities.push(other);\n }\n } else if (\n kind === \"primitive\" ||\n kind === \"primaryKey\" ||\n kind === \"enum\" ||\n kind === \"m2mEnum\" ||\n kind === \"poly\" ||\n kind === \"m2o\" ||\n kind === \"lo2m\"\n ) {\n // These field types don't need merge handling - they're either:\n // - primitive values that don't create references (primitive, enum)\n // - primary keys that shouldn't be merged\n // - forward references that we handle from the reverse side (m2o)\n // - large collections that are handled separately (lo2m)\n } else {\n assertNever(kind);\n }\n }\n }\n\n // Auto-delete source entities if requested\n if (autoDelete) {\n for (const source of sources) this.delete(source);\n }\n\n return changedEntities;\n }\n\n /** Returns an instance of `type` for the given `id`, resolving to an existing instance if in our Unit of Work. */\n public async load<T extends EntityW & { id: string }>(id: IdOf<T>): Promise<T>;\n public async load(id: TaggedId): Promise<Entity>;\n public async load<T extends EntityW>(type: MaybeAbstractEntityConstructor<T>, id: IdOf<T> | TaggedId): Promise<T>;\n public async load<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n id: IdOf<T> | TaggedId,\n populate: H,\n ): Promise<Loaded<T, H>>;\n async load<T extends EntityW>(\n typeOrId: MaybeAbstractEntityConstructor<T> | string,\n id?: IdType,\n hint?: any,\n ): Promise<T> {\n // Handle the `typeOrId` overload\n let type: MaybeAbstractEntityConstructor<T>;\n if (typeof typeOrId === \"string\") {\n // This must be a tagged id for the 1st overload to work\n type = getConstructorFromTaggedId(typeOrId);\n id = typeOrId;\n } else {\n type = typeOrId;\n id = id || fail(`Invalid ${typeOrId.name} id: ${id}`);\n }\n const meta = getMetadata(type);\n const taggedId = toTaggedId(meta, id);\n let entity = this.findExistingInstance<T>(taggedId);\n if (!entity) {\n await loadBatchLoader(this, meta)\n .load({ taggedId, hint })\n .catch(function load(err) {\n throw appendStack(err, new Error());\n });\n entity = this.findExistingInstance<T>(taggedId);\n }\n if (!entity) {\n throw new NotFoundError(`${taggedId} was not found`);\n }\n if (hint) {\n await this.populate(entity, hint);\n }\n if (meta.inheritanceType === \"sti\" && !(entity instanceof type)) {\n throw new Error(`${entity} is ${entity.constructor.name} but should be ${type.name}`);\n }\n return entity as T;\n }\n\n /** Returns instances of `type` for the given `ids`, resolving to an existing instance if in our Unit of Work. */\n public async loadAll<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n ids: readonly string[],\n ): Promise<T[]>;\n public async loadAll<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n ids: readonly string[],\n populate: H,\n ): Promise<Loaded<T, H>[]>;\n async loadAll<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n _ids: readonly string[],\n hint?: any,\n ): Promise<T[]> {\n const meta = getMetadata(type);\n\n // Use pre-allocated arrays/for loops instead of `.filter`s since this can be a hot spot;\n // misses remember their tagged id + position so the all-hit path skips the `ids` copy entirely\n const entities = new Array<T | undefined>(_ids.length);\n let idsToLoad: string[] | undefined;\n let positionsToLoad: number[] | undefined;\n\n for (let i = 0; i < _ids.length; i++) {\n const id = tagId(meta, _ids[i]);\n const entity = this.findExistingInstance<T>(id);\n if (entity) {\n entities[i] = entity;\n } else {\n (idsToLoad ??= []).push(id);\n (positionsToLoad ??= []).push(i);\n }\n }\n\n if (idsToLoad) {\n await loadBatchLoader(this, meta)\n .loadAll(idsToLoad.map((id) => ({ taggedId: id, hint })))\n .catch(function loadAll(err) {\n throw appendStack(err, new Error());\n });\n let idsNotFound: string[] | undefined;\n for (let j = 0; j < positionsToLoad!.length; j++) {\n const entity = this.findExistingInstance<T>(idsToLoad[j]);\n entities[positionsToLoad![j]] = entity;\n if (entity === undefined) (idsNotFound ??= []).push(idsToLoad[j]);\n }\n if (idsNotFound) {\n throw new NotFoundError(`${idsNotFound.join(\",\")} were not found`);\n }\n }\n const loadedEntities = entities as T[];\n if (hint) {\n await this.populate(loadedEntities, hint);\n }\n if (meta.inheritanceType === \"sti\" && meta.baseType) {\n const wrongType = loadedEntities.filter((e) => !(e instanceof meta.cstr));\n if (wrongType.length > 0) {\n throw new Error(`${wrongType.join(\", \")} were not of type ${meta.cstr.name}`);\n }\n }\n return loadedEntities;\n }\n\n /**\n * Returns instances of `type` for the given `ids`, resolving to an existing instance if in our Unit of Work. Ignores\n * IDs that are not found.\n */\n public async loadAllIfExists<T extends EntityW>(type: EntityConstructor<T>, ids: readonly string[]): Promise<T[]>;\n public async loadAllIfExists<T extends EntityW, const H extends LoadHint<T>>(\n type: EntityConstructor<T>,\n ids: readonly string[],\n populate: H,\n ): Promise<Loaded<T, H>[]>;\n async loadAllIfExists<T extends EntityW>(\n type: EntityConstructor<T>,\n _ids: readonly string[],\n hint?: any,\n ): Promise<T[]> {\n const meta = getMetadata(type);\n\n // Use pre-allocated arrays/for loops instead of `.filter`s since this can be a hot spot;\n // the all-hit path returns the single pre-sized array without any id copies or rebuilds\n const maybeEntities = new Array<T | undefined>(_ids.length);\n let idsToLoad: string[] | undefined;\n let positionsToLoad: number[] | undefined;\n\n // Ensure the ids are tagged, and find any not-yet-loaded\n for (let i = 0; i < _ids.length; i++) {\n const id = tagId(meta, _ids[i]);\n const entity = this.findExistingInstance<T>(id);\n if (entity) {\n maybeEntities[i] = entity;\n } else {\n (idsToLoad ??= []).push(id);\n (positionsToLoad ??= []).push(i);\n }\n }\n\n let entities: T[];\n if (idsToLoad) {\n await loadBatchLoader(this, meta)\n .loadAll(idsToLoad.map((id) => ({ taggedId: id, hint })))\n .catch(function loadAllIfExists(err) {\n throw appendStack(err, new Error());\n });\n // Fill in whichever missed ids actually exist, then compact out the not-founds\n for (let j = 0; j < positionsToLoad!.length; j++) {\n maybeEntities[positionsToLoad![j]] = this.findExistingInstance<T>(idsToLoad[j]);\n }\n entities = [];\n for (const entity of maybeEntities) {\n if (entity !== undefined) entities.push(entity);\n }\n } else {\n entities = maybeEntities as T[];\n }\n if (hint) {\n await this.populate(entities, hint);\n }\n return entities;\n }\n\n /**\n * Loads entities found, when starting at `entities`, via the \"path\" given by the `fn` lens function.\n *\n * Results are unique, i.e. if doing `em.loadLens([b1, b2], b => b.author.publisher)` point to the\n * same `Publisher`, it will only be returned as a single value.\n */\n public async loadLens<T extends EntityW, U, V>(\n entities: readonly T[],\n fn: (lens: Lens<T>) => Lens<U, V>,\n ): Promise<U[]>;\n public async loadLens<T extends EntityW, U extends EntityW, V, const H extends LoadHint<U>>(\n entities: readonly T[],\n fn: (lens: Lens<T>) => Lens<U, V>,\n populate: H,\n ): Promise<Loaded<U, H>[]>;\n public async loadLens<T extends EntityW, U, V>(\n entities: readonly T[],\n fn: (lens: Lens<T>) => Lens<U, V>,\n populate?: any,\n ): Promise<V> {\n const result = await loadLens(entities, fn);\n if (populate) {\n await this.populate(result as any as Entity[], populate);\n }\n return result;\n }\n\n /**\n * Loads entities from database rows that were queried directly using a query builder.\n *\n * This overload is synchronous since there is no population/querying to do.\n */\n public loadFromQuery<T extends EntityW>(type: MaybeAbstractEntityConstructor<T>, rows: readonly unknown[]): T[];\n /**\n * Loads entities from database rows from a Knex-ish query builder that needs an `await`.\n *\n * This overload is async because it triggers the `rows` query.\n */\n public loadFromQuery<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: PromiseLike<readonly unknown[]>,\n ): Promise<T[]>;\n /**\n * Loads & populates entities from database rows that were queried directly using a query builder.\n */\n public loadFromQuery<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: readonly unknown[],\n populate: H,\n ): Promise<Loaded<T, H>[]>;\n /**\n * Loads & populates entities from database rows from a Knex-ish query builder that needs an `await`.\n */\n public loadFromQuery<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: PromiseLike<readonly unknown[]>,\n populate: H,\n ): Promise<Loaded<T, H>[]>;\n public loadFromQuery<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: readonly unknown[] | PromiseLike<readonly unknown[]>,\n populate?: any,\n ): PromiseLike<T[]> | T[] {\n if (Array.isArray(rows)) {\n const entities = this.hydrate(type, rows);\n if (populate) return this.populate(entities, populate);\n return entities;\n } else {\n return (rows as Promise<unknown[]>).then((rows) => {\n const entities = this.hydrate(type, rows);\n if (populate) return this.populate(entities, populate);\n return entities;\n });\n }\n }\n\n /** Loads entities from rows. */\n public async loadFromRows<T extends EntityW>(type: MaybeAbstractEntityConstructor<T>, rows: unknown[]): Promise<T[]>;\n public async loadFromRows<T extends EntityW, const H extends LoadHint<T>>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: unknown[],\n populate: H,\n ): Promise<Loaded<T, H>[]>;\n public async loadFromRows<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: unknown[],\n populate?: any,\n ): Promise<T[]> {\n const entities = this.hydrate(type, rows);\n if (populate) {\n await this.populate(entities, populate);\n }\n return entities;\n }\n\n /** Given a hint `H` (a field, array of fields, or nested hash), pre-load that data into `entity` for sync access. */\n public async populate<T extends EntityW, const H extends LoadHint<T>, V = Loaded<T, H>>(\n entity: T,\n hint: H,\n fn?: (entity: Loaded<T, H>) => V,\n ): Promise<V>;\n public async populate<T extends EntityW, const H extends LoadHint<T>, V = Loaded<T, H>>(\n entity: T,\n opts: { hint: H; forceReload?: boolean },\n fn?: (entity: Loaded<T, H>) => V,\n ): Promise<V>;\n public async populate<T extends EntityW, const H extends LoadHint<T>>(\n entities: ReadonlyArray<T>,\n hint: H,\n ): Promise<Loaded<T, H>[]>;\n public async populate<T extends EntityW, const H extends LoadHint<T>>(\n entities: ReadonlyArray<T>,\n opts: { hint: H; forceReload?: boolean },\n ): Promise<Loaded<T, H>[]>;\n async populate<T extends EntityW, H extends LoadHint<T>, V>(\n entityOrList: T | T[],\n hintOrOpts: { hint: H; forceReload?: boolean } | H,\n fn?: (entity: Loaded<T, H>) => V,\n ): Promise<Loaded<T, H> | Array<Loaded<T, H>> | V> {\n const { hint: hintOpt, ...opts } =\n typeof hintOrOpts === \"object\" && \"hint\" in hintOrOpts ? hintOrOpts : { hint: hintOrOpts };\n\n // Tell `AsyncMethodImpl.load` to not invoke its function\n (opts as any)[AsyncMethodPopulateSecret] = true;\n\n // I'm tempted to throw an error here, because at least internal callers should ideally pre-check\n // that `list > 0` and `Object.keys(hint).length > 0` before calling `populate`, just as an optimization.\n // But since it's a public API, we should just early exit.\n const list = toArray(entityOrList).filter((e) => {\n // Check `isDeletedAndFlushed` so that pending-delete entities are still populated,\n // because their hooks might do `getWithDeleted` calls and expect them to be loaded.\n return e !== undefined && !getInstanceData(e).isDeletedAndFlushed;\n });\n if (list.length === 0) {\n return !fn ? (entityOrList as any) : fn(entityOrList as any);\n }\n\n // Avoid building a HintTree/batchloader for persisted entities when everything is already loaded; in the phase 9\n // benchmark this moved already-loaded populates from ~1.10ms to ~0.89ms, and nested already-loaded populates from\n // ~2.39ms to ~1.94ms.\n if (!opts.forceReload && list.every((entity) => !entity.isNewEntity && isLoadedForPopulate(entity, hintOpt as H))) {\n return fn ? fn(entityOrList as any) : (entityOrList as any);\n }\n\n const meta = getMetadata(list[0]);\n\n if (this.#preloader) {\n // If we can preload, prevent promise deadlocking by one large-batch preload populate (which can't have\n // intra dependencies), then a 2nd small-batch non-preload populate.\n const [preload, non] = this.#preloader.partitionHint(meta, hintOpt);\n if (preload) {\n const loader = populateBatchLoader(this, meta, preload, \"preload\", opts);\n await loader.loadAll(list.map((entity) => ({ entity, hint: preload }))).catch(function populate(err: any) {\n throw appendStack(err, new Error());\n });\n }\n if (non) {\n const loader = populateBatchLoader(this, meta, non, \"intermixed\", opts);\n await loader.loadAll(list.map((entity) => ({ entity, hint: non }))).catch(function populate(err: any) {\n throw appendStack(err, new Error());\n });\n }\n } else {\n const loader = populateBatchLoader(this, meta, hintOpt, \"intermixed\", opts);\n await loader.loadAll(list.map((entity) => ({ entity, hint: hintOpt }))).catch(function populate(err: any) {\n throw appendStack(err, new Error());\n });\n }\n\n return fn ? fn(entityOrList as any) : (entityOrList as any);\n }\n\n // For debugging EntityManager.populate.test.ts's \"can be huge\"\n // populates: Record<string, number> = {};\n\n /**\n * Executes `fn` with a transaction, and automatically calls `flush`/`commit` at the end.\n *\n * This ensures both any `.find` and `.flush` operations happen within the same\n * transaction, which is useful for enforcing cross-table/application-level invariants that\n * cannot be enforced with database-level constraints.\n */\n public async transaction<T>(fn: (txn: TX) => Promise<T>): Promise<T> {\n return this.driver.transaction(this, async (txn) => {\n const result = await fn(txn);\n // The lambda may have done some interstitial flushes (that would not\n // have committed the transaction), but go ahead and do a final one\n // in case they didn't explicitly call flush.\n await this.flush();\n return result;\n });\n }\n\n /**\n * Marks an instance to be deleted.\n *\n * Any loaded collections that are currently \"pointing to\" this entity will be updated to\n * no longer include this entity, i.e. if you `em.delete(b1)`, then `author.books` will have\n * `b1` removed (if needed).\n *\n * This is done for all currently-loaded collections; i.e. technically unloaded collections\n * may still point to this entity. We defer unsetting these not-currently-loaded references\n * until `EntityManager.flush`, when we can make the async calls to load-and-unset them.\n */\n delete(entity: Entity): void;\n /**\n * Marks entities to be deleted.\n *\n * Any loaded collections that are currently \"pointing to\" this entity will be updated to\n * no longer include this entity, i.e. if you `em.delete(b1)`, then `author.books` will have\n * `b1` removed (if needed).\n *\n * This is done for all currently-loaded collections; i.e. technically unloaded collections\n * may still point to this entity. We defer unsetting these not-currently-loaded references\n * until `EntityManager.flush`, when we can make the async calls to load-and-unset them.\n */\n delete(entities: Entity[]): void;\n delete(entityOrArray: Entity | Entity[]): void {\n for (const entity of toArray(entityOrArray)) {\n // Early return if already deleted.\n const alreadyMarked = getInstanceData(entity).markDeleted();\n if (!alreadyMarked) continue;\n // This monotonic flag lets find hot paths skip scanning results until a delete has ever happened in this EM.\n this.#hasAnyDeletes = true;\n // Any derived fields that read this entity will need recalc-d\n this.#rm.queueAllDownstreamFields(entity, \"deleted\");\n // Synchronously unhook the entity if the relations are loaded\n getCascadeDeleteRelations(entity).forEach((r) => r.maybeCascadeDelete());\n // And queue the cascade deletes\n this.#pendingDeletes.push(entity);\n }\n }\n\n async assignNewIds() {\n let pendingEntities = this.entities.filter((e) => e.isNewEntity && !e.isDeletedEntity && !e.idTaggedMaybe);\n await this.getLoader<Entity, Entity>(\"assign-new-ids\", \"global\", async (entities) => {\n let todos = createTodos(entities);\n await this.driver.assignNewIds(this, todos);\n for (const e of entities) this.#entitiesById.set(e.idTagged, e);\n return entities;\n })\n .loadMany(pendingEntities)\n .catch(function assignNewIds(err) {\n throw appendStack(err, new Error());\n });\n }\n\n /**\n * Immediately assigns async defaults to `entities`.\n *\n * Normally async defaults wait until `em.flush` to run, because their async nature requires\n * an `await` / `Promise` to be evaluated, and `em.create` is synchronous.\n *\n * This `assignDefaults` methods like you move that up, and immediately invoke\n * any default logic against the `entities`.\n */\n async setDefaults(entities: Entity[]): Promise<void> {\n return runInTrustedContext(async () => {\n const suppressedTypeErrors: Error[] = [];\n const entitiesByType = groupBy(\n entities.filter((e) => e.isNewEntity),\n (e) => getMetadata(e),\n );\n await setAsyncDefaults(suppressedTypeErrors, this.ctx, entitiesByType);\n });\n }\n\n /**\n * Flushes the SQL for any changed entities to the database.\n *\n * If this is run outside of an existing transaction, it will `BEGIN` and `COMMIT`\n * a new transaction on every `.flush()` call so that all of the `INSERT`s/etc.\n * happen atomically.\n *\n * If this is run within an existing transaction, i.e. `EntityManager.transaction`,\n * then it will only issue `INSERT`s/etc. and defer to the caller to `COMMIT`\n * the transaction.\n *\n * It returns entities that have changed (an entity is considered changed if it has been deleted, inserted, or updated)\n */\n async flush(flushOptions: FlushOptions = {}): Promise<Entity[]> {\n return runInTrustedContext(() => this.#flush(flushOptions));\n }\n\n async #flush(flushOptions: FlushOptions = {}): Promise<Entity[]> {\n if (this.mode === \"read-only\") throw new ReadOnlyError();\n\n const { skipValidation = false } = flushOptions;\n\n this.#fl.startLock();\n\n const allFlushedEntities: Set<Entity> = new Set();\n\n try {\n await this.#fl.allowWrites(async () => {\n // Cascade deletes now that we're async (i.e. to keep `em.delete` synchronous).\n // Also do this before calling `recalcPendingReactables` to avoid recalculating\n // fields on entities that will be deleted (and probably have unset/invalid FKs\n // that would NPE their logic anyway).\n await this.flushDeletes();\n // Recalc before we run hooks, so the hooks will see the latest calculated values.\n await this.#rm.recalcPendingReactables(\"reactables\");\n });\n\n const createdThenDeleted: Set<Entity> = new Set();\n // We'll only invoke hooks once/entity (the 1st time that entity goes through runHooksOnPendingEntities)\n const hooksInvoked: Set<Entity> = new Set();\n // Make sure two AsyncReactiveFields don't ping-pong each other forever\n let hookLoops = 0;\n let now = getNow();\n const suppressedDefaultTypeErrors: Error[] = [];\n\n // Make a lambda that we can invoke multiple times, if we loop for AsyncReactiveFields\n const runHooksOnPendingEntities = async (): Promise<Entity[]> => {\n if (hookLoops++ >= 10) throw new Error(\"runHooksOnPendingEntities has ran 10 iterations, aborting\");\n\n // Resolve any pending o2m/m2m sets (set() called before load — need to load from DB to diff)\n const pendingLoads = [...getEmInternalApi(this).pendingLoads];\n if (pendingLoads.length > 0) {\n getEmInternalApi(this).pendingLoads.clear();\n await Promise.all(pendingLoads.map((collection) => collection.load()));\n }\n\n // Any dirty entities we find, even if we skipped firing their hooks on this loop\n const pendingFlush: Set<Entity> = new Set();\n // Subset of pendingFlush entities that we will run hooks on\n const pendingHooks: Set<Entity> = new Set();\n // Subset of pendingFlush entities that had hooks invoked in a prior `runHooksOnPendingEntities`\n const alreadyRanHooks = new Set<Entity>();\n\n findPendingFlushEntities(\n this.#maybePendingFlushEntities,\n hooksInvoked,\n pendingFlush,\n pendingHooks,\n alreadyRanHooks,\n );\n\n // If we're re-looping for AsyncReactiveField, make sure to bump updatedAt\n // each time, so that for an INSERT-then-UPDATE the triggers don't think the\n // UPDATE forgot to self-bump updatedAt, and then \"helpfully\" bump it for us.\n if (alreadyRanHooks.size > 0) {\n maybeBumpUpdatedAt(this.#rm, createTodos(alreadyRanHooks), now);\n }\n\n // Run hooks in a series of loops until things \"settle down\"\n while (pendingHooks.size > 0) {\n await this.#fl.allowWrites(async () => {\n let todos = createTodos(pendingHooks);\n\n await setAsyncDefaults(suppressedDefaultTypeErrors, this.ctx, Todo.groupInsertsByTypeAndSubType(todos));\n maybeBumpUpdatedAt(this.#rm, todos, now);\n\n // Run our hooks\n for (const group of maybeSetupHookOrdering(todos)) {\n await beforeCreate(this.ctx, group);\n await beforeUpdate(this.ctx, group);\n await beforeFlush(this.ctx, group);\n }\n\n // Call `setField` just to get the column marked as dirty if needed.\n // This can come after the hooks, b/c if the hooks read any of these\n // fields, they'd be via the synchronous getter and would not be stale.\n recalcSynchronousDerivedFields(todos);\n\n // The hooks could have deleted this-loop or prior-loop entities, so re-cascade again.\n // Reactions (the recalc below) can themselves `em.delete` entities, so keep draining\n // until both deletes and recalcs have settled.\n do {\n await this.flushDeletes();\n // The hooks could have changed fields, so recalc again.\n await this.#rm.recalcPendingReactables(\"reactables\");\n } while (this.#pendingDeletes.length > 0);\n // We may have reactables that failed earlier, but will succeed now that hooks have been run and cascade\n // deletes have been processed\n if (this.#rm.hasPendingTypeErrors) {\n await this.#rm.recalcPendingTypeErrors();\n // We need to re-run reactables again if we dirtied something while retrying type errors\n if (this.#rm.needsRecalc(\"reactables\")) await this.#rm.recalcPendingReactables(\"reactables\");\n }\n\n for (const e of pendingHooks) hooksInvoked.add(e);\n pendingHooks.clear();\n // See if the hooks mutated any new, not-yet-hooksInvoked entities\n findPendingFlushEntities(\n this.#maybePendingFlushEntities,\n hooksInvoked,\n pendingFlush,\n pendingHooks,\n alreadyRanHooks,\n );\n // The final run of recalcPendingReactables could have left us with pending type errors and no entities in\n // pendingHooks. If so, we need to re-run recalcPendingTypeErrors to get those errors to transition into\n // suppressed errors so that we will fail after simpleValidation.\n if (pendingHooks.size === 0 && this.#rm.hasPendingTypeErrors) await this.#rm.recalcPendingTypeErrors();\n });\n }\n // We might have invoked hooks that immediately deleted a new entity (weird but allowed);\n // if so, filter it out so that we don't flush it, but keep track for later fixing up\n // it's `#orm.deleted` field.\n return [...pendingFlush].filter((e) => {\n const createThenDelete = e.isDeletedEntity && e.isNewEntity;\n if (createThenDelete) createdThenDeleted.add(e);\n return !createThenDelete;\n });\n };\n\n const { pluginManager } = getEmInternalApi(this);\n\n const runValidation = async (\n entityTodos: Record<string, Todo>,\n joinRowTodos: Record<string, JoinRowTodo>,\n validate: boolean,\n ) => {\n const changedEntities = entitiesFromTodos(entityTodos, joinRowTodos);\n try {\n this.#isValidating = true;\n await pluginManager.beforeValidate(changedEntities);\n if (validate) {\n // Regular rules run pre-flush, so `em.find*` would query stale data; block it and steer\n // users to `config.addCommitRule` (which runs post-flush). Only rules are restricted —\n // `afterValidation` hooks & plugins below are left free to query.\n this.#findRestricted = true;\n try {\n // Run simple rules first b/c it includes not-null/required rules, so that then when we run\n // `validateReactiveRules` next, the app's lambdas won't see fundamentally invalid entities & NPE.\n await validateSimpleRules(entityTodos);\n // After we've let any \"author is not set\" simple rules fail before prematurely throwing\n // the \"of course that caused an NPE\" `TypeError`s, if all the authors *were* valid/set,\n // and we still have TypeErrors (from derived valeus), they were real, unrelated errors\n // that the user should see.\n if (suppressedDefaultTypeErrors.length > 0) throw suppressedDefaultTypeErrors[0];\n await validateReactiveRules(this, this.#rm.logger, entityTodos, joinRowTodos);\n } finally {\n this.#findRestricted = false;\n }\n await afterValidation(this.ctx, entityTodos);\n }\n await pluginManager.afterValidate(changedEntities);\n } finally {\n this.#isValidating = false;\n }\n };\n\n // Runs `addCommitRule`s, which look exactly like regular validation rules but fire here,\n // after the INSERT/UPDATE/DELETEs have hit the db (but before COMMIT), so that any\n // `em.find`s they make query the just-flushed/changed state within the transaction.\n const runCommitValidation = async (\n entityTodos: Record<string, Todo>,\n joinRowTodos: Record<string, JoinRowTodo>,\n ) => {\n // Drop the pre-flush find/query caches so commit rules' `em.find`s re-query and see the\n // just-flushed rows, instead of stale results cached earlier in this same flush.\n this.#dataloaders = {};\n this.#batchLoaders = {};\n this.#preloadedRelations = new Map();\n try {\n // `isValidating` keeps derived-field reads from creating (now-unflushable) dirty state.\n this.#isValidating = true;\n await validateSimpleRules(entityTodos, (config) => config.commitRules);\n await validateReactiveRules(\n this,\n this.#rm.logger,\n entityTodos,\n joinRowTodos,\n (meta) => meta.reactiveCommitRules!,\n );\n } finally {\n this.#isValidating = false;\n }\n };\n\n // Commit rules run once, at the end, over just the flushed entities/join-rows whose type has\n // commit rules (see `meta.hasCommitRules`). We accumulate that subset here as we flush — deduping\n // across the RQF loop below (which resets entity dirty-state) — so we neither keep every todo\n // nor re-scan/merge them afterwards; apps without commit rules leave these empty and pay ~nothing.\n const commitRuleTodos: Record<string, Todo> = {};\n const commitRuleJoinRowTodos: Record<string, JoinRowTodo> = {};\n const commitRuleSeen = new Set<unknown>();\n function collectCommitRuleTodos(\n entityTodos: Record<string, Todo>,\n joinRowTodos: Record<string, JoinRowTodo>,\n ): void {\n if (skipValidation) return;\n for (const todo of Object.values(entityTodos)) {\n if (!todo.metadata.hasCommitRules) continue;\n for (const key of [\"inserts\", \"updates\", \"deletes\"] as const) {\n for (const e of todo[key]) {\n if (!commitRuleSeen.has(e)) {\n commitRuleSeen.add(e);\n getTodo(commitRuleTodos, e)[key].push(e);\n }\n }\n }\n }\n for (const [table, todo] of Object.entries(joinRowTodos)) {\n if (!todo.m2m.meta.hasCommitRules && !todo.m2m.otherMeta?.hasCommitRules) continue;\n const into = (commitRuleJoinRowTodos[table] ??= { ...todo, newRows: [], deletedRows: [] });\n for (const key of [\"newRows\", \"deletedRows\"] as const) {\n for (const r of todo[key]) {\n if (!commitRuleSeen.has(r)) {\n commitRuleSeen.add(r);\n into[key].push(r);\n }\n }\n }\n }\n }\n\n // Run hooks (in iterative loops if hooks mutate new entities) on pending entities\n let entitiesToFlush = await runHooksOnPendingEntities();\n for (const e of entitiesToFlush) allFlushedEntities.add(e);\n\n // Recreate todos now that we've run hooks and recalculated fields so know\n // the full set of entities that will be INSERT/UPDATE/DELETE-d in the database.\n let entityTodos = createTodos(entitiesToFlush);\n let joinRowTodos = combineJoinRows(this.#joinRows);\n\n await runValidation(entityTodos, joinRowTodos, !skipValidation);\n this.#rm.throwIfAnySuppressedTypeErrors();\n if (suppressedDefaultTypeErrors.length > 0) throw suppressedDefaultTypeErrors[0];\n\n if (Object.keys(entityTodos).length > 0 || Object.keys(joinRowTodos).length > 0) {\n // The driver will handle the right thing if we're already in an existing transaction.\n await this.driver.transaction(this, async () => {\n do {\n if (Object.keys(entityTodos).length > 0 || Object.keys(joinRowTodos).length > 0) {\n await this.driver.flush(this, entityTodos, joinRowTodos);\n // Accumulate the commit-rule-relevant subset before the RQF loop clobbers/resets these\n collectCommitRuleTodos(entityTodos, joinRowTodos);\n }\n // Now that we've flushed, we can let plugins know what we've done.\n pluginManager.afterWrite(entityTodos, joinRowTodos);\n // And we can look for ReactiveQueries that need to be recalculated\n if (this.#rm.hasPendingReactiveQueries()) {\n // Reset all flushed entities to we only flush net-new changes\n for (const e of entitiesToFlush) {\n if (e.isNewEntity && !e.isDeletedEntity) this.#entitiesById.set(e.idTagged, e);\n getInstanceData(e).resetForRqfLoop();\n }\n // Actually do the recalc\n await this.#fl.allowWrites(async () => {\n await this.#rm.recalcPendingReactables(\"reactiveQueries\");\n // If any ReactiveFields depended on AsyncReactiveFields, go ahead and calc those now\n await this.#rm.recalcPendingReactables(\"reactables\");\n });\n // Advance `now` so that our triggers don't think our UPDATEs are forgetting to self-bump\n // updated_at, and bump it themselves, which could cause a subsequent error.\n now = getNow();\n // See if any RQFs actually changed any entities. If they did, run the hooks on them.\n entitiesToFlush = await runHooksOnPendingEntities();\n for (const e of entitiesToFlush) allFlushedEntities.add(e);\n // Recreate `entityTodos` against the only-the-just-changed entities\n entityTodos = createTodos(entitiesToFlush);\n joinRowTodos = combineJoinRows(this.#joinRows);\n await runValidation(entityTodos, joinRowTodos, true);\n this.#rm.throwIfAnySuppressedTypeErrors();\n } else {\n // Exit the loop\n entityTodos = {};\n }\n } while (Object.keys(entityTodos).length > 0);\n // Now that all SQL has hit the db (but before COMMIT), run any `addCommitRule`s so their\n // `em.find`s see the changed state. `commitRuleTodos` is only non-empty if a flushed entity\n // actually has commit rules, so apps without them skip this (and its logging) entirely.\n if (Object.keys(commitRuleTodos).length > 0 || Object.keys(commitRuleJoinRowTodos).length > 0) {\n // Make just-inserted entities findable by id (like the RQF loop does) so commit rules'\n // `em.find`s return these same instances rather than hydrating duplicate ones.\n for (const e of allFlushedEntities) {\n if (e.isNewEntity && !e.isDeletedEntity) this.#entitiesById.set(e.idTagged, e);\n }\n await runCommitValidation(commitRuleTodos, commitRuleJoinRowTodos);\n }\n // Run `beforeCommit once right before COMMIT\n await beforeCommit(this.ctx, allFlushedEntities);\n if (this.mode === \"in-memory-writes\") {\n throw new InMemoryRollbackError();\n }\n });\n\n // TODO: This is really \"after flush\" if we're being called from a transaction that\n // is going to make multiple `em.flush()` calls?\n await afterCommit(this.ctx, allFlushedEntities);\n\n // Update the `#orm` field to reflect the new state\n for (const e of allFlushedEntities) {\n const instanceData = getInstanceData(e);\n if (e.isNewEntity && !e.isDeletedEntity) this.#entitiesById.set(e.idTagged, e);\n instanceData.resetAfterFlushed();\n // Reset AsyncQueryProperties & LazyFields since DB state may have changed\n const { relations } = instanceData;\n if (relations) {\n for (const rel of Object.values(relations)) {\n if (rel instanceof AsyncPropertyImpl || rel instanceof LazyFieldImpl) rel.resetAfterFlush();\n }\n }\n }\n // Update the joinRows refs to reflect the new state\n for (const joinRow of Object.values(joinRowTodos)) {\n joinRow.resetAfterFlushed();\n }\n const { mutatedCollections } = getEmInternalApi(this);\n for (const o2m of mutatedCollections.values()) {\n o2m.resetAddedRemoved();\n }\n mutatedCollections.clear();\n\n // Reset the find/preload caches b/c data will have changed in the db\n this.#dataloaders = {};\n this.#batchLoaders = {};\n this.#preloadedRelations = new Map();\n this.#rm.clear();\n }\n\n // Fixup the `deleted` field on entities that were created then immediately deleted\n for (const e of createdThenDeleted) getInstanceData(e).fixupCreatedThenDeleted();\n this.#merging?.clear();\n\n return [...allFlushedEntities].sort((a, b) => getInstanceData(a).entityIndex - getInstanceData(b).entityIndex);\n } catch (e) {\n if (e instanceof RecursiveCycleError) {\n const entity = e.entities[0];\n // Look up a custom cycle message — check both the exact field name and its opposite\n // direction, since the cycle may be detected from either side (e.g. walking\n // childrenRecursive during reactive hint reversal when parentsRecursive was configured).\n for (const meta of getBaseAndSelfMetas(getMetadata(entity))) {\n const messageFn =\n meta.config.__data.cycleMessages[e.fieldName] ??\n meta.config.__data.cycleMessages[((entity as any)[e.fieldName] as any)?.otherFieldName];\n if (messageFn) {\n throw new ValidationErrors([{ entity, message: messageFn(entity, e.entities) }]);\n }\n }\n }\n // node-pg keeps the DETAIL line (i.e. \"Key (identity_id, final_id)=(102591, null) already exists\")\n // on a separate `detail` field, so keep it to suffix onto messages to help debugging.\n const detail = e && typeof e === \"object\" && \"detail\" in e && typeof e.detail === \"string\" ? e.detail : undefined;\n if (e && typeof e === \"object\" && \"constraint\" in e && typeof e.constraint === \"string\") {\n // node-pg errors use `constraint` to indicate the constraint name\n const message = constraintNameToValidationError[e.constraint];\n if (message) {\n const errors = new ValidationErrors(message);\n // Keep the user-facing `errors[].message` pretty, but suffix the DETAIL onto the top-level\n // `message` so the debugging context survives into logs/stack traces.\n if (detail) errors.message = `${message} — ${detail}`;\n throw errors;\n }\n }\n if (e instanceof InMemoryRollbackError) {\n return [...allFlushedEntities].sort((a, b) => getInstanceData(a).entityIndex - getInstanceData(b).entityIndex);\n }\n // For raw (non-pretty) pg errors, fold the DETAIL into `message` so it survives into logs.\n if (detail && e instanceof Error) {\n e.message = `${e.message} — ${detail}`;\n }\n throw e;\n } finally {\n this.#rm.clearSuppressedTypeErrors();\n this.#fl.releaseLock();\n resetFactoryCreated();\n }\n }\n\n /**\n * A very simple toJSON.\n *\n * This is not really meant to be useful, it's to prevent huge/circular output if\n * an EntityManager accidentally ends up getting logged to something like pino that\n * over-zealous toJSONs anything it touches.\n */\n public toJSON(): string {\n return `<EntityManager ${this.entities.length}>`;\n }\n\n /**\n * For all entities in the current `EntityManager`, load their latest data from the database.\n *\n * This is primarily useful in tests, i.e. having 1 `EntityManager` with some test data, running business\n * logic in a dedicated `EntityManager`, and then `refresh`-ing the test data `EntityManager` to assert\n * against the latest values.\n *\n * This works with primitive fields as well as references and collections.\n *\n * TODO Newly-found collection entries will not have prior load hints applied to this, unless using\n * `deepLoad` which should only be used by tests to avoid loading your entire database in memory.\n */\n async refresh(opts?: { deepLoad?: boolean }): Promise<void>;\n async refresh(entity: EntityW): Promise<void>;\n async refresh(entities: ReadonlyArray<EntityW>): Promise<void>;\n async refresh(param?: EntityW | ReadonlyArray<EntityW> | { deepLoad?: boolean }): Promise<void> {\n this.#isRefreshing = true;\n this.#dataloaders = {};\n this.#batchLoaders = {};\n this.#preloadedRelations = new Map();\n const deepLoad = param && \"deepLoad\" in param && param.deepLoad;\n let todo =\n param === undefined\n ? this.#entitiesArray\n : Array.isArray(param)\n ? param\n : isEntity(param)\n ? [param]\n : this.#entitiesArray;\n const done = new Set<Entity>();\n while (todo.length > 0) {\n const copy = [...todo];\n copy.forEach((e) => done.add(e));\n todo = [];\n\n // For any non-deleted entity with an id, get its latest data + relations from the database\n const entitiesToRefresh = copy.filter((e) => e.idTaggedMaybe && !e.isDeletedEntity);\n await Promise.all(\n entitiesToRefresh.map((entity) => {\n // Pass loaded/all relation names as a hint so the preloader can inject JOINs\n const hint = getRelationEntries(entity)\n .filter(([_, r]) => deepLoad || r.isLoaded)\n .map(([k]) => k);\n return loadBatchLoader(this, getMetadata(entity), true)\n .load({ taggedId: entity.idTagged, hint })\n .catch(function refresh(err) {\n throw appendStack(err, new Error());\n });\n }),\n );\n\n // Then refresh any loaded relations (the loadBatchLoader only hydrates the entity\n // data, it doesn't get each relation into a loaded state.)\n const [custom, builtin] = partition(\n entitiesToRefresh\n .filter((e) => !getInstanceData(e).isDeletedEntity)\n .flatMap((entity) => getRelations(entity).filter((r) => deepLoad || r.isLoaded)),\n isCustomRelation,\n );\n // Call `.load` on builtin relations first, because if we hit an already-loaded custom relation\n // first, it will call `.get` internally, and might access built-in relations that we've not had a\n // chance to `.load()` yet.\n await Promise.all(\n builtin.map((r) => {\n // If the relation is already loaded, we need to go through .load({ forceReload }), otherwise\n // use preload to avoid the promise.\n if (r.isPreloaded && !r.isLoaded) {\n r.preload();\n return undefined;\n } else {\n return r.load({ forceReload: true });\n }\n }),\n );\n await Promise.all(custom.map((r) => r.load({ forceReload: true })));\n\n // If deep loading, get all entity/entities in the relation and push them on the list\n if (deepLoad) {\n todo.push(\n // We skip recursing into CustomCollections and CustomReferences and PersistedAsyncReferencesImpl for two reasons:\n // 1. It can be tricky to ensure `{ forceReload: true }` is passed all the way through their custom load\n // implementations, and so it's easy to have `.get` accidentally come across a not-yet-loaded collection, and\n // 2. Any custom load functions should use the underlying o2m/m2o/etc relations anyway, so if we crawl/refresh\n // those, then when the user calls `.get` on custom collections/references, they should be talking to always-loaded\n // relations, w/o us having to tackle the tricky bookkeeping problem passing `forceReload` all through their\n // custom load function + any other collections they call.\n ...builtin\n .filter((r) => \"get\" in r)\n .map((r) => (r as any).get)\n .flatMap((value) => (Array.isArray(value) ? value : [value]))\n .filter((value) => isEntity(value) && !done.has(value as Entity)),\n );\n }\n }\n this.#isRefreshing = false;\n }\n\n public get numberOfEntities(): number {\n return this.entities.length;\n }\n\n // Handles our Unit of Work-style look up / deduplication of entity instances.\n // Currently only public for the driver impls\n public findExistingInstance<T extends EntityW>(id: string): T | undefined {\n return this.#entitiesById.get(id) as T | undefined;\n }\n\n /**\n * Takes a result `row` from a custom query and maps the db values into a new-or-existing domain object for that row.\n *\n * The `overwriteExisting` controls whether `row`'s values should overwrite the existing fields on\n * an entity. By default this is true, as we assume the user calling this means they know the DB has\n * updated values that should be put into the entities. A few internal callers set this to false,\n * i.e. when we're loading collections and have db results that are potentially stale compared to\n * the WIP entity state.\n */\n public hydrate<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n rows: readonly any[],\n options?: { overwriteExisting?: boolean },\n ): T[] {\n return this.hydrateFromRowData(type, new PojoRowData(rows), options);\n }\n\n /**\n * Hydrates a query's `RowData`, running any sidecar reads, and always `finalize`s the result.\n *\n * This is the internal API for Joist's find/load loaders: `sidecars` is where reads of\n * non-entity columns (preload aggregates, `_tags`, found-id checks) belong — they must run\n * before `finalize`, because compaction drops unretained rows — and the `try/finally`\n * guarantees a failed hydration or sidecar read still releases the result's unretained\n * buffers instead of pinning them.\n */\n private hydrateAndFinalize<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n rowData: RowData,\n opts?: { overwriteExisting?: boolean; sidecars?: (entities: T[]) => void },\n ): T[] {\n try {\n const entities = this.hydrateFromRowData(type, rowData, opts);\n opts?.sidecars?.(entities);\n return entities;\n } finally {\n rowData.finalize?.();\n }\n }\n\n /**\n * Like {@link hydrate}, but reads rows from a {@link RowData}, i.e. a driver-produced\n * lazy query result, instead of an array of POJO rows.\n *\n * This is an internal API used by Joist's own find loaders (usually via\n * {@link hydrateAndFinalize}); rows whose entities are kept (newly created or\n * overwrite-refreshed) are `retain`-ed on the `RowData` so the caller can later `finalize`\n * (trim/compact) the result.\n */\n public hydrateFromRowData<T extends EntityW>(\n type: MaybeAbstractEntityConstructor<T>,\n rowData: RowData,\n options?: { overwriteExisting?: boolean },\n ): T[] {\n const maybeBaseMeta = getMetadata(type);\n const overwriteExisting = options?.overwriteExisting === true;\n\n const count = rowData.rowCount;\n const entities = new Array(count);\n for (let i = 0; i < count; i++) {\n const id = rowData.get(i, \"id\");\n const taggedId =\n id === undefined || id === null ? fail(\"No id column was available\") : keyToTaggedId(maybeBaseMeta, id)!;\n // See if this is already in our UoW\n let entity = this.findExistingInstance(taggedId) as T;\n if (!entity) {\n // Look for __class from the driver telling us which subtype to instantiate\n const meta = findConcreteMeta(maybeBaseMeta, rowData, i);\n // Pass id as a hint that we're in hydrate mode\n entity = newEntity(this, asConcreteCstr(meta.cstr), false) as T;\n const instanceData = getInstanceData(entity);\n instanceData.rowData = rowData;\n instanceData.rowIndex = i;\n rowData.retain?.(i);\n // Seed the id to share the identity-map key string and skip the id serde on first read\n instanceData.data[\"id\"] = taggedId;\n this.#doRegister(entity as any, taggedId, meta, true);\n } else if (overwriteExisting) {\n // Usually if the entity already exists, we don't write over it, but in this case we assume that\n // `EntityManager.refresh` is telling us to explicitly load the latest data.\n // First swap out the old row with the new row\n const instanceData = getInstanceData(entity);\n instanceData.rowData = rowData;\n instanceData.rowIndex = i;\n rowData.retain?.(i);\n // And then only refresh the data keys that have already been serde-d from rows\n // (this keeps us from deserializing data out of rows that we don't need).\n const { data } = instanceData;\n const dataKeys = Object.keys(data);\n // `id` is seeded at hydrate and can never change, so it never needs refreshing\n if (dataKeys.length > (\"id\" in data ? 1 : 0)) {\n const allFields = getMetadata(entity).allFields;\n // For existing entities this is exactly `changes.fieldsWithoutRelations`, minus the proxy allocation\n const changedFields: string[] = instanceData.isNewEntity\n ? (entity as any).changes.fieldsWithoutRelations\n : Object.keys(instanceData.originalData);\n for (const fieldName of dataKeys) {\n if (fieldName === \"id\") continue;\n const field = allFields[fieldName];\n const serde = field.serde ?? fail(`Missing serde for ${fieldName}`);\n data[fieldName] = serde.fromRow(rowData, i);\n // Make the field look not-dirty\n if (changedFields.includes(fieldName)) {\n instanceData.markFieldClean(fieldName);\n }\n }\n }\n }\n entities[i] = entity;\n }\n\n return entities;\n }\n\n /**\n * Mark an entity as needing to be flushed regardless of its state.\n *\n * This will:\n *\n * - Bump the entity's `updated_at` timestamp (if available),\n * - Run `beforeUpdate` and `beforeFlush` hooks.\n */\n public touch(entity: EntityW): void;\n public touch(entities: EntityW[]): void;\n public touch(entityOrEntities: EntityW | EntityW[]): void {\n for (const entity of toArray(entityOrEntities)) {\n getInstanceData(entity).markTouched();\n }\n }\n\n /**\n * Recalculates an entity's reactive fields or explicitly runs a named reaction.\n *\n * You shouldn't need to call this unless the derived fields have drifted from the underlying data, which\n * should only happen if:\n *\n * - The underlying data was changed by a raw SQL query, or\n * - You've changed the field's business logic and want to update the database to the latest value.\n *\n * Pass `reactionName` to run only that named reaction on each entity. You can also trigger a recalc for\n * specific fields by calling `.load()` on the property, i.e.\n * `author.numberOfBooks.load()`. This `recalc` method is just a helper method to call `load` for\n * all derived fields on the given entity/entities.\n */\n public recalc(entity: EntityW): Promise<void>;\n public recalc(entities: EntityW[]): Promise<void>;\n public recalc(entity: EntityW, reactionName: string): Promise<void>;\n public recalc(entities: EntityW[], reactionName: string): Promise<void>;\n public async recalc(entityOrEntities: EntityW | EntityW[], reactionName?: string): Promise<void> {\n const entities = toArray(entityOrEntities).filter((entity) => !entity.isDeletedEntity);\n if (reactionName !== undefined) {\n // Resolve every reaction before invoking any of them so a mixed list cannot partially run.\n const reactions = entities.map((entity) => {\n const reaction = getBaseAndSelfMetas(getMetadata(entity))\n .flatMap((meta) => meta.config.__data.reactions)\n .find((reaction) => reaction.name === reactionName);\n return reaction ?? fail(`Reaction '${reactionName}' not found on ${getMetadata(entity).type}`);\n });\n await runInTrustedContext(() =>\n Promise.allSettled(reactions.map((reaction, i) => reaction.fn(entities[i], this.ctx))).then(failIfAnyRejected),\n );\n await this.#rm.recalcPendingReactables(\"reactables\");\n return;\n }\n\n // Look for async reactive fields\n const relations = entities.flatMap((entity) =>\n Object.values(getMetadata(entity).allFields)\n .filter((f) => \"derived\" in f && f.derived === \"async\")\n .map((field) => (entity as any)[field.fieldName]),\n );\n // Use forceReload: true to tell ReactiveReferences to recalc against their full graph\n // This intentionally mirrors ReactionsManager.recalcPendingReactables's NoIdError retry. These direct relations\n // are not ReactiveActions, and all failures except NoIdError are returned directly to the caller.\n const results = await Promise.allSettled(relations.map((r: any) => r.load({ forceReload: true })));\n const relationsPendingAssignedIds: any[] = [];\n const failures: any[] = [];\n results.forEach((result, i) => {\n if (result.status === \"rejected\") {\n if (result.reason instanceof NoIdError) {\n relationsPendingAssignedIds.push(relations[i]);\n } else {\n failures.push(result.reason);\n }\n }\n });\n if (relationsPendingAssignedIds.length > 0) {\n await this.assignNewIds();\n const retryResults = await Promise.allSettled(\n relationsPendingAssignedIds.map((r: any) => r.load({ forceReload: true })),\n );\n retryResults.forEach((result) => {\n if (result.status === \"rejected\") {\n failures.push(result.reason);\n }\n });\n }\n if (failures.length > 0) throw failures[0];\n\n // And also sync reactive fields\n entities.flatMap((entity) =>\n Object.values(getMetadata(entity).allFields)\n .filter((f) => \"derived\" in f && f.derived === \"sync\")\n .forEach((field) => {\n // This will be a noop if the value is the same\n setField(entity, field.fieldName, (entity as any)[field.fieldName]);\n }),\n );\n\n // `.load()` recalculated the immediate relations, go ahead and recalc any downstream reactables.\n // We'll still defer AsyncReactiveFields to the em.flush loop.\n await this.#rm.recalcPendingReactables(\"reactables\");\n }\n\n public beforeBegin(fn: HookFn<TX>) {\n this.#hooks.beforeBegin.push(fn);\n }\n\n public afterBegin(fn: HookFn<TX>) {\n this.#hooks.afterBegin.push(fn);\n }\n\n public beforeCommit(fn: HookFn<TX>) {\n this.#hooks.beforeCommit.push(fn);\n }\n\n public afterCommit(fn: HookFn<TX>) {\n this.#hooks.afterCommit.push(fn);\n }\n /**\n * Returns an EntityManager-scoped (i.e. request scoped) data loader.\n *\n * @param operation the operation being batched, i.e. `load` or `o2m-load`, to avoid clashing batch keys\n * across fundamentally different operations\n * @param batchKey for a given operation, i.e. `load`, a batch key `Author` to batch all Author loads together\n * @param fn the batch load function, i.e. that will accept all `.load(...)`-d Author ids to load as a single db call\n * @param opts optional DataLoader options\n * @returns a DataLoader scoped to the `operation` + `batchKey` combination\n */\n public getLoader<K, V>(\n operation: string,\n batchKey: string,\n fn: BatchLoadFn<K, V>,\n opts?: Options<K, V>,\n ): DataLoader<K, V> {\n // If we wanted to, if not in a transaction, we could potentially do lookups against a global cache,\n // to achieve cross-request batching. Granted we'd need all DataLoaders to have caching disabled, see:\n // https://github.com/joist-orm/joist-orm/issues/629\n const loadersForKind = (this.#dataloaders[operation] ??= {});\n return getOrSet(loadersForKind, batchKey, () => new DataLoader(fn, opts));\n }\n\n /**\n * Like `getLoader`, but returns a `BatchLoader` where all callers in the same tick\n * share a single `Promise<void>` instead of getting per-key promises.\n *\n * The batch function should write results via side channels (e.g. `setPreloadedRelation`).\n */\n public getBatchLoader<K>(operation: string, batchKey: string, fn: (keys: K[]) => Promise<void>): BatchLoader<K> {\n const loadersForKind = (this.#batchLoaders[operation] ??= {});\n return getOrSet(loadersForKind, batchKey, () => new BatchLoader(fn));\n }\n\n public toString(): string {\n return \"EntityManager\";\n }\n\n /** Recursively cascades any pending deletions. */\n private async flushDeletes(): Promise<void> {\n let entities = this.#pendingDeletes;\n if (entities.length === 0) return;\n this.#pendingDeletes = [];\n let relationsToCleanup: AbstractRelationImpl<unknown, unknown>[] = [];\n // Loop if our deletes cascade to other deletes\n while (entities.length > 0) {\n // For cascade delete relations, cascade the delete...\n const p = entities.flatMap(getCascadeDeleteRelations).map((r) => r.load().then(() => r.maybeCascadeDelete()));\n await Promise.all(p);\n // Run the beforeDelete hook before we unhook the entity\n const todos = createTodos(entities);\n await beforeDelete(this.ctx, todos);\n // For all relations, unhook the entity from the other side; this append path is optimized for\n // large deletes with ~100k relations by avoiding `flatMap` intermediates and `concat` copies.\n for (const entity of entities) {\n const relations = getRelations(entity);\n const start = relationsToCleanup.length;\n relationsToCleanup.length += relations.length;\n for (let i = 0; i < relations.length; i++) {\n relationsToCleanup[start + i] = relations[i];\n }\n }\n entities = this.#pendingDeletes;\n this.#pendingDeletes = [];\n }\n // For all relations, unhook the entity from the other side\n await Promise.all(relationsToCleanup.map((r) => r.cleanupOnEntityDeleted()));\n }\n\n setReactionLogging(logger: ReactionLogger): void;\n setReactionLogging(enabled: boolean): void;\n setReactionLogging(arg: boolean | ReactionLogger): void {\n this.#rm.setLogger(typeof arg === \"boolean\" ? (arg ? new ReactionLogger() : undefined) : arg);\n }\n\n /** Accepts `Author` or `Author.firstName,lastName` or `Author.lastName!`. */\n setFieldLogging(spec: string): void;\n /** Accepts `[\"Author.firstName,lastName\", \"Book.title\"]`. */\n setFieldLogging(spec: string[]): void;\n /** Sets this EntityManager's field logger. */\n setFieldLogging(logger: FieldLogger): void;\n /** Enables/disables field logging for all fields. */\n setFieldLogging(enabled: boolean): void;\n setFieldLogging(arg: FieldLogger | string | string[] | boolean): void {\n if (arg instanceof FieldLogger) {\n this.#fieldLogger = arg;\n return;\n }\n const writeFn = getDefaultWriteFn(this.ctx);\n if (typeof arg === \"boolean\") {\n this.#fieldLogger = arg ? new FieldLogger([], writeFn) : noopFieldLogger;\n } else if (typeof arg === \"string\" || Array.isArray(arg)) {\n const specs = Array.isArray(arg) ? arg : [arg];\n const watching: FieldLoggerWatch[] = specs.map((spec) => {\n // Regex to match Author.firstName,lastName! pattern\n const regex = /^([^.!]+)(?:\\.([^!]*))?(!)?$/;\n const [_, entity, fields, breakpoint] = spec.match(regex) ?? fail(`Unsupported spec ${spec}`);\n const fieldNames = fields?.split(\",\");\n // Ensure entity is valid, to avoid failing silently\n const meta = getMetadataForType(entity);\n // Ensure the field names are valid, to avoid failing silently\n fieldNames?.forEach((field) => {\n // We could probably check the `kind`, b/c things like o2o/o2m are not supported atm\n if (!meta.allFields[field]) {\n throw new Error(`Field ${field} not found on ${entity}`);\n }\n });\n return { entity, fieldNames, breakpoint: !!breakpoint };\n });\n this.#fieldLogger = new FieldLogger(watching, writeFn);\n } else {\n throw new Error(\"Unsupported override for setFieldLogging\");\n }\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.flush();\n }\n\n /** Returns entities matching the filter using indexed search when available. */\n filterEntities<T extends Entity>(cstr: EntityConstructor<T>, where: Partial<OptsOf<T>>): T[] {\n const meta = getMetadata(cstr);\n const entities = (this.#entitiesByTag.get(meta.tagName) as T[]) ?? [];\n // Don't bother filtering if there's no where clause (particularly b/c IndexManager.findMatching\n // really expects there to be at least 1 condition)\n if (!hasAnyKey(where)) {\n return entities.filter((e) => e instanceof cstr && !e.isDeletedEntity);\n }\n if (this.#indexManager.shouldIndexType(entities.length)) {\n this.#indexManager.enableIndexingForType(meta, entities, where);\n // Build the final array in one pass, still filtering `instanceof cstr` to handle subtyping\n const result: T[] = [];\n for (const e of this.#indexManager.findMatching(meta, entities, where)) {\n if (e instanceof cstr && !e.isDeletedEntity) result.push(e);\n }\n return result;\n } else {\n return (\n entities\n // Still filter by `instanceof cstr` to handle subtyping\n .filter((e) => e instanceof cstr && !e.isDeletedEntity && entityMatches(e, where)) as T[]\n );\n }\n }\n\n /**\n * Creates a new EntityManager that shares the same entities as the current one but allows independent changes.\n *\n * This is useful for scenarios where you want to:\n *\n * - Preload data for use as a cache\n * - Make speculative changes that may or may not be committed\n * - Escape a transaction scope\n *\n * The fork will:\n *\n * - Copy all currently loaded entities to the new EntityManager\n * - Copy any loaded relation data to keep `.isLoaded` / `.get` state consistent\n * - Copy and update references to the EntityManager and its entities in the context, which is itself shallowly copied\n *\n * The fork will NOT:\n *\n * - Copy any pending changes (must call .flush() first)\n * - Share any changes made in either EntityManager with the other\n *\n * @param opts options to control the fork behavior\n * - allowPendingChanges - allows the em being forked to have pending changes and forces the resulting em to have\n * `mode` set to \"in-memory-writes\". Changes to entities in the original em will be copied to the resulting em.\n * Optional. default: false\n *\n * @throws {Error} If called on an EntityManager with pending changes\n * @returns A new EntityManager with copied entity state\n */\n fork(opts: { allowPendingChanges?: boolean } = {}): EntityManager<C, Entity, TX> {\n const { allowPendingChanges = false } = opts;\n const oldEm = this;\n // copy the context so that it's distinct between the two ems, and so we can update any references from the old em\n // to the new one later\n const ctx = { ...oldEm.ctx } as Record<string, any>;\n const newEm = new EntityManager<C, Entity, TX>(ctx as C, { em: oldEm });\n if (allowPendingChanges) newEm.mode = \"in-memory-writes\";\n // hydrate (ie, create) each entity from the oldEm in the newEm\n for (const [tag, entities] of oldEm.#entitiesByTag.entries()) {\n // tags are always defined by the base constructor, so we use that as hydrate expects the base class as its argument\n const baseCstr = getConstructorFromTag(tag);\n let rows = new Array<any>(entities.length);\n let i = 0;\n for (const entity of entities) {\n const instanceData = (entity as any).__data as InstanceData;\n if (!allowPendingChanges && instanceData.pendingOperation !== \"none\") {\n fail(\"Cannot fork an EntityManager with pending changes\");\n } else if (instanceData.isNewEntity) {\n // Create blank entities in newEm for each unpersisted entity from oldEm. They will be populated later in the\n // allowPendingChanges step as they should not be present otherwise.\n // (I'd thought we should copy over `InstanceData.createId`, but since we're iterating over `oldEm.#entitiesByTag`\n // in stable as-created order, the `newEm.create` will assign the same/incrementing `createId`s as in oldEm.)\n newEm.create(entity.constructor as EntityConstructor<Entity>, {} as any);\n } else {\n // We copy the raw row data for each entity to avoid any potential conflict. Then we ensure the correct concrete\n // __class key is set for hydrate to use, if necessary (ie, cti), to actually instantiate the entity.\n rows[i] = createRowFromEntityData(entity);\n i++;\n }\n }\n if (rows.length !== i) rows = rows.slice(0, i);\n newEm.hydrate(baseCstr, rows);\n }\n\n function mapEntity(oldEntity: Entity): Entity {\n if (oldEntity.isNewEntity) {\n return newEm.#entitiesById.get(oldEntity.toTaggedString())!;\n } else {\n return newEm.#entitiesById.get(oldEntity.idTagged)!;\n }\n }\n\n function mapEntities<U extends Entity>(v: U[] | undefined): U[] | undefined {\n if (v === undefined) return undefined;\n const result = new Array<U>(v.length);\n for (let i = 0; i < v.length; i++) result[i] = mapEntity(v[i]) as U;\n return result;\n }\n\n // If we are allowing pending changes, then we need to copy any changes across to newEm\n if (allowPendingChanges) {\n for (const oldEntity of oldEm.entities) {\n const oldInstanceData = (oldEntity as any).__data as InstanceData;\n if (!(oldInstanceData.isNewEntity || oldInstanceData.isDirtyEntity)) continue;\n const { originalData: oldOriginalData, data: oldData } = oldInstanceData;\n const newEntity = mapEntity(oldEntity);\n const newInstanceData = (newEntity as any).__data as InstanceData;\n const { data: newData } = newInstanceData;\n // for new entities, anything in `data` is changed and should be copied across. for existing entities, we\n // only care about changed fields, which are enumerated by originalData\n const maybeEntity = (value: any) => (isEntity(value) ? mapEntity(value as Entity) : value);\n const fields = Object.keys(oldEntity.isNewEntity ? oldData : oldOriginalData);\n for (const field of fields) {\n // copy over originalData so .changes is consistent across ems\n if (field in oldOriginalData) newInstanceData.markFieldDirty(field, maybeEntity(oldOriginalData[field]));\n newData[field] = maybeEntity(oldData[field]);\n }\n }\n }\n\n // import every loaded concrete (ie, not custom) relation into the new em\n for (const oldEntity of oldEm.entities) {\n const newEntity = mapEntity(oldEntity);\n if (oldEntity.isDeletedEntity) {\n // If the old entity was deleted, that should be persisted in the new em\n ((newEntity as any).__data as InstanceData).markDeleted();\n // deleted entities will fail if you try to `get` their relations, so skip them since they should be cleared\n // out regardless\n continue;\n }\n\n const { relations } = (oldEntity as any).__data as InstanceData;\n if (!relations) continue;\n for (const [field, relation] of Object.entries(relations)) {\n // With lazyRelation, custom relations are inserted into the `relations` map. Custom relations don't\n // store any data, so we can ignore them by checking if the relation implements `import`\n // TODO: add `import` to recursiveCollection\n if (!(\"import\" in relation)) continue;\n if (oldEntity.isNewEntity) {\n // every relation should be loaded on a new entity, so calling get should be safe\n const oldValue = relation.get;\n if (oldValue === undefined) continue;\n if (Array.isArray(oldValue) && oldValue.length === 0) continue;\n const newValue = Array.isArray(oldValue) ? mapEntities(oldValue) : mapEntity(oldValue);\n // we may have already copied over the instance data, in which case `setFromOpts` would detect this as\n // the same entity that's already set in data and early exit, so delete ourselves from data first\n delete ((newEntity as any).__data as InstanceData).data[field];\n (newEntity as any)[field].setFromOpts(newValue);\n } else {\n const isLoaded = \"_isLoaded\" in relation ? relation._isLoaded : relation.isLoaded;\n if (isLoaded) (newEntity as any)[field].import(relation, mapEntity, mapEntities);\n }\n }\n }\n // Inspect the top level keys in the context and replace any references from oldEm with newEm (ie, ctx.em === newEm)\n // while also replacing any entities from oldEm with their version in newEm (eg, if the user is stored in the\n // context, then `ctx.user.em === newEm`).\n for (const [key, value] of Object.entries(ctx)) {\n if (isEntity(value) && value.em === oldEm) {\n ctx[key] = mapEntity(value as Entity);\n } else if (value === oldEm) {\n ctx[key] = newEm;\n }\n }\n return newEm;\n }\n\n /**\n * Copies an entity from one EntityManager to another, ensuring all relations specified in the hint are\n * also copied.\n *\n * This method is primarily used when you need to move entities between different EntityManager instances\n * while preserving their loaded state and relationships. This is useful for scenarios like:\n *\n * - Moving entities between transaction boundaries\n * - Creating test fixtures that reference entities from a different EntityManager\n * - Sharing entities between different parts of your application\n *\n * The migration process:\n * 1. If the entity already exists in this EntityManager, returns it\n * 2. Otherwise, creates a new instance with the same data\n * 3. Recursively migrates any loaded relations specified in the hint\n *\n * @param source - The entity to migrate from another EntityManager\n * @param hint - The load hint specifying which relations to migrate\n * @returns The migrated entity with all specified relations loaded\n */\n importEntity<T extends Entity>(original: T): T;\n importEntity<T extends Entity, H extends LoadHint<T>, L extends Loaded<T, H>>(original: L, hint: H): L;\n importEntity<T extends Entity, H extends LoadHint<T>, L extends Loaded<T, H>>(\n source: L,\n hint?: H,\n normalizedHint?: H,\n ): L {\n if (source.isNewEntity) fail(\"cannot import new entities\");\n if (source.isDeletedEntity) fail(\"cannot import deleted entities\");\n if (source.isDirtyEntity) fail(\"cannot import dirty entities\");\n\n hint ??= {} as H;\n if (!normalizedHint) {\n assertLoaded(source, hint);\n normalizedHint = deepNormalizeHint(hint) as H;\n }\n\n if (source.em === this) return source as any;\n\n const meta = getMetadata(source);\n\n let result = this.#entitiesById.get(source.idTagged) as T | undefined;\n\n if (!result) {\n const meta = getMetadata(source);\n const row = createRowFromEntityData(source);\n result = this.hydrate(getBaseMeta(meta).cstr, [row])[0]!;\n }\n\n for (const [fieldName, subHint] of Object.entries(normalizedHint)) {\n const field = meta.allFields[fieldName];\n const relationOrProp = (result as any)[fieldName];\n if (!field) {\n let loadHint: H =\n (relationOrProp as any).loadHint ?? fail(`${source}.${fieldName} cannot be imported as it has no loadHint`);\n this.importEntity<T, H, L>(source, loadHint);\n } else if (\"import\" in relationOrProp) {\n // Tell our version of the entity (result) to accept/copy the relation state of the source\n relationOrProp.import(\n (source as any)[fieldName],\n (e: Entity) => (this.importEntity as any)(e, subHint, subHint) as Entity,\n (entities: Entity[]) => {\n if (entities === undefined) return undefined;\n const result = new Array(entities.length);\n for (let i = 0; i < entities.length; i++) {\n result[i] = (this.importEntity as any)(entities[i], subHint, subHint) as Entity;\n }\n return result;\n },\n );\n }\n }\n\n return result as any;\n }\n\n addPlugin(plugin: Plugin): void {\n getEmInternalApi(this).pluginManager.addPlugin(plugin);\n }\n\n getPlugins(): readonly Plugin[] {\n return getEmInternalApi(this).pluginManager.plugins;\n }\n\n get isRefreshing() {\n return this.#isRefreshing;\n }\n\n get isFlushing() {\n return this.#fl.isFlushing;\n }\n\n /** Creates a new `type` and marks it as loaded, i.e. we know its collections are all safe to access in memory. */\n #doCreate<T extends EntityW>(type: EntityConstructor<T>, opts: any, partial: boolean): T {\n const entity = newEntity(this, type, true);\n\n // Assign the next `a#1`, `a#2`, etc. id\n const meta = getMetadata(type);\n const counter = (this.#createCounter ??= new Map<string, number>());\n const i = (counter.get(meta.tagName) ?? 0) + 1;\n counter.set(meta.tagName, i);\n getInstanceData(entity).createId = String(i);\n\n // Check opts.id for an explicitly-set id\n this.#doRegister(entity as any, opts.id);\n\n // Set a default createdAt/updatedAt\n const baseMeta = getBaseMeta(getMetadata(entity));\n if (baseMeta.timestampFields) {\n this.#assignTimestamps(entity, baseMeta);\n }\n\n // Set the discriminator for STI\n if (baseMeta.inheritanceType === \"sti\") {\n setStiDiscriminatorValue(baseMeta, entity);\n }\n\n // api will be undefined during getFakeInstance\n const api = getEmInternalApi(this);\n api?.fieldLogger.logCreate(entity);\n\n setOpts(entity, opts, { partial, calledFromConstructor: true });\n\n // Apply any synchronous defaults, after the opts have been applied\n if (!(this as any).fakeInstance) {\n setSyncDefaults(entity);\n }\n\n this.#rm.queueAllDownstreamFields(entity, \"created\");\n\n return entity;\n }\n\n #assignTimestamps(entity: EntityW, baseMeta: EntityMetadata): void {\n const { createdAt, updatedAt } = baseMeta.timestampFields ?? {};\n const { data } = getInstanceData(entity);\n const now = new Date();\n if (createdAt) {\n const serde = baseMeta.fields[createdAt].serde as TimestampSerde<unknown>;\n data[createdAt] = serde.mapFromNow(now);\n }\n if (updatedAt) {\n const serde = baseMeta.fields[updatedAt].serde as TimestampSerde<unknown>;\n data[updatedAt] = serde.mapFromNow(now);\n }\n }\n\n /** Registers a newly-instantiated entity with our EntityManager; only called by #doCreate and hydrate. */\n #doRegister(entity: Entity, id?: string, meta?: EntityMetadata, skipDuplicateCheck: boolean = false): void {\n // Keep our indexes up to date...\n const maybeId = id ?? entity.idTaggedMaybe;\n if (maybeId) {\n if (!skipDuplicateCheck && this.findExistingInstance(maybeId) !== undefined) {\n throw new Error(`Entity ${entity} has a duplicate instance already loaded`);\n }\n this.#entitiesById.set(maybeId, entity);\n } else {\n // Also register by the `a#1` style tagged string for new entities\n this.#entitiesById.set(entity.toTaggedString(), entity);\n }\n getInstanceData(entity).entityIndex = this.#entitiesArray.length;\n this.#entitiesArray.push(entity);\n\n meta ??= getMetadata(entity);\n const set = this.#entitiesByTag.get(meta.tagName) ?? [];\n if (set.length === 0) this.#entitiesByTag.set(meta.tagName, set);\n set.push(entity);\n if (this.#entitiesArray.length >= this.entityLimit) {\n const topTypes = [...this.#entitiesByTag.entries()]\n .map(([tag, entities]) => ({ tag, count: entities.length }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 3)\n .map(({ tag, count }) => `${tag}=${count}`)\n .join(\", \");\n throw new Error(`More than ${this.entityLimit} entities have been instantiated (top entities: ${topTypes})`);\n }\n }\n}\n\n/** Provides an internal API to the `EntityManager`. */\nexport interface EntityManagerInternalApi {\n joinRows: (m2m: ManyToManyLike) => JoinRows;\n\n /** Map of taggedId -> fieldName -> pending children, i.e. when `a1.books` later loads, add/remove b1. */\n pendingPercolate: Map<string, Map<string, { adds: Entity[]; removes: Entity[] }>>;\n\n /** List of mutated o2m collections to reset added/removed post-flush. */\n mutatedCollections: Set<OneToManyCollection<any, any>>;\n\n /** O2M/M2M collections with pending set() calls that need resolution before flush. */\n pendingLoads: Set<Collection<any, any>>;\n\n /** Map of taggedId -> fieldName -> join-loaded data. */\n getPreloadedRelation<U>(taggedId: string, fieldName: string): U[] | undefined;\n setPreloadedRelation<U>(taggedId: string, fieldName: string, children: U[]): void;\n\n hooks: Record<EntityManagerHook, HookFn<any>[]>;\n rm: ReactionsManager;\n indexManager: IndexManager;\n preloader: PreloadPlugin | undefined;\n isValidating: boolean;\n checkWritesAllowed: () => void;\n isMerging: (entity: Entity) => boolean;\n get fieldLogger(): FieldLogger;\n get isLoadedCache(): IsLoadedCache;\n pluginManager: PluginManager;\n clearDataloaders(): void;\n clearPreloadedRelations(): void;\n markMaybePending(entity: EntityW): void;\n unmarkMaybePending(entity: EntityW): void;\n hasAnyDeletes(): boolean;\n pendingDeleteIds(type: MaybeAbstractEntityConstructor<Entity>): readonly IdType[];\n setIsRefreshing(isRefreshing: boolean): void;\n}\n\nexport function getEmInternalApi(em: EntityManager): EntityManagerInternalApi {\n return (em as any)[\"__api\"];\n}\n\nlet defaultEntityLimit = 50_000;\n\nexport function getDefaultEntityLimit() {\n return defaultEntityLimit;\n}\n\nexport function setDefaultEntityLimit(limit: number) {\n defaultEntityLimit = limit;\n}\n\nexport function resetDefaultEntityLimit() {\n defaultEntityLimit = 50_000;\n}\n\nexport function isKey(k: any): k is string {\n return typeof k === \"string\";\n}\n\n/** Compares `a` to `b`, where `b` might be an id. */\nexport function sameEntity(a: Entity | string | number | undefined, b: Entity | string | number | undefined): boolean {\n if (a === b) {\n return true;\n }\n // Throw in null handling for findWithNewOrChanged ambivalence\n if (a === undefined || b === undefined || a === null || b === null) {\n return (a === undefined || a === null) && (b === undefined || b === null);\n }\n // If both are entities, return if they are the same reference\n if (isEntity(a) && isEntity(b)) {\n return a === b;\n }\n // Otherwise check by ID\n const aId = isEntity(a) ? a.idTaggedMaybe : a;\n const bId = isEntity(b) ? b.idTaggedMaybe : b;\n return aId === bId;\n}\n\n/** Compares the value `a` to `b`, with handling of new entities w/o ids assigned yet. */\nexport function sameReference<T extends Entity>(a: Reference<any, T, any>, b: Reference<any, T, any>): boolean {\n return sameEntity(isLoadedReference(a) ? a.get : a.idTaggedMaybe, isLoadedReference(b) ? b.get : b.idTaggedMaybe);\n}\n\n/** Thrown by `findOneOrFail`, 'load' & 'loadAll' if an entity is not found. */\nexport class NotFoundError extends Error {}\n\n/** Thrown by `findOne` and `findOneOrFail` if more than one entity is found. */\nexport class TooManyError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * For the entities currently in `todos`, find any reactive validation rules that point\n * from the currently-changed entities back to each rule's originally-defined-in entity,\n * and ensure those entities are added to `todos`.\n */\nasync function validateReactiveRules(\n em: EntityManager,\n logger: ReactionLogger,\n todos: Record<string, Todo>,\n joinRowTodos: Record<string, JoinRowTodo>,\n // Which list of reactive rules to run, i.e. the pre-flush `reactiveRules` or the post-flush `reactiveCommitRules`\n getRules: (meta: EntityMetadata) => ReactiveRule[] = (meta) => meta.reactiveRules!,\n): Promise<void> {\n logger.logStartingValidate(em, todos);\n\n // Use a map of rule -> Set<Entity> so that we only invoke a rule once per entity,\n // even if it was triggered by multiple changed fields.\n const fns: Map<ValidationRule<any>, Set<Entity>> = new Map();\n // Concurrent walks finish in query-timing order, so the logger sorts them before writing deterministic output.\n const walks: ReactionWalk[] = [];\n\n // From the given triggered entities, follow the entity's ReactiveRule back\n // to the reactive rules that need ran, and queue them in the `fn` map\n async function followAndQueue(triggered: Entity[], rule: ReactiveRule): Promise<void> {\n if (triggered.length === 0) return;\n const found = (await followReverseHint(rule.name, triggered, rule.path))\n .filter((entity) => !entity.isDeletedEntity)\n .filter((e) => e instanceof rule.cstr);\n let entities = fns.get(rule.fn);\n if (!entities) {\n entities = new Set();\n fns.set(rule.fn, entities);\n }\n walks.push({ todo: triggered, r: rule, entities: found });\n found.forEach((entity) => {\n entities.add(entity);\n });\n }\n\n const p1 = Object.values(todos).flatMap((todo) => {\n // Find each statically-declared reactive rule for the given entity type\n const rules = getRules(todo.metadata);\n // Skip the entities spread for rule-less types\n if (rules.length === 0) return [];\n const entities = [...todo.inserts, ...todo.updates, ...todo.deletes];\n return rules.map((rule) => {\n // Of all changed entities of this type, how many specifically trigger this rule?\n const triggered = entities.filter((e) => {\n // If the rule is for a different subtype, skip it\n if (!(e instanceof rule.source)) return false;\n // Any new-or-deleted entity fires every rule (reactiveRules has already filtered out read-only)\n if (e.isNewEntity || e.isDeletedEntity) return true;\n // Otherwise see if the changed fields overlap with the rule's fields; for existing entities\n // `changes.fieldsWithoutRelations` is exactly `Object.keys(originalData)`, so probe originalData\n // directly instead of allocating a proxy + keys array per entity per rule.\n const { originalData } = getInstanceData(e);\n for (const field of rule.fields) {\n if (field in originalData) return true;\n }\n return false;\n });\n // From these \"triggered\" entities, queue the \"found\"/owner entity to rerun this rule\n return followAndQueue(triggered, rule);\n });\n });\n\n const p2 = Object.values(joinRowTodos).flatMap((todo) => {\n // For enum m2ms the columns include the enum's numeric id, so keep only the entity values.\n const entities = [...todo.newRows, ...todo.deletedRows].flatMap((jr) => Object.values(jr.columns)).filter(isEntity);\n // The owning-entity side (applies to both entity-to-entity and entity-to-enum m2ms).\n const a = getRules(todo.m2m.meta)\n .filter((rule) => rule.fields.includes(todo.m2m.fieldName))\n .map((rule) => {\n const triggered = entities.filter((e) => e instanceof todo.m2m.meta.cstr);\n return followAndQueue(triggered, rule);\n });\n // The \"other\" side only exists for entity-to-entity m2ms; enums have no reverse field.\n const { otherMeta, otherFieldName } = todo.m2m;\n const b = otherMeta\n ? getRules(otherMeta)\n .filter((rule) => rule.fields.includes(otherFieldName!))\n .map((rule) => {\n const triggered = entities.filter((e) => e instanceof otherMeta.cstr);\n return followAndQueue(triggered, rule);\n })\n : [];\n return [...a, ...b];\n });\n\n failIfAnyRejected(await Promise.allSettled([...p1, ...p2]));\n logger.logWalks(walks, \"validate\");\n\n // Now that we've found the fn+entities to run, run them and collect any errors\n const p3 = [...fns.entries()].flatMap(([fn, entities]) =>\n [...entities].map(async (entity) => coerceError(entity, await fn(entity))),\n );\n const errors = failIfAnyRejected(await Promise.allSettled(p3)).flat();\n if (errors.length > 0) {\n throw new ValidationErrors(errors);\n }\n}\n\n// Run *non-reactive* (those with `fields: undefined`) rules of explicitly mutated entities,\n// because even for reactive validations on mutated entities, we defer to addReactiveValidations\n// to mark only the rules that need to run.\nasync function validateSimpleRules(\n todos: Record<string, Todo>,\n // Which config list to pull rules from, i.e. the pre-flush `rules` or the post-flush `commitRules`\n getRules: (config: ConfigData<any, any>) => ValidationRuleInternal<any>[] = (config) => config.rules,\n): Promise<void> {\n let p: Promise<ValidationError[]>[] | undefined = undefined;\n for (const todoKey in todos) {\n const { inserts, updates } = todos[todoKey];\n for (const entities of [inserts, updates]) {\n for (const entity of entities) {\n if (entity.isDeletedEntity) continue;\n for (const m of getBaseAndSelfMetas(getMetadata(entity))) {\n for (const rule of getRules(m.config.__data)) {\n if (rule.hint !== undefined) continue;\n (p ??= []).push(invokeRule(entity, rule.fn));\n }\n }\n }\n }\n }\n if (!p) return;\n const errors = failIfAnyRejected(await Promise.allSettled(p)).flat();\n if (errors.length > 0) {\n throw new ValidationErrors(errors);\n }\n}\n\n/** Invokes a single validation rule, coercing its result/sync throws into a promise. */\nasync function invokeRule(\n entity: Entity,\n fn: (entity: any) => MaybePromise<ValidationRuleResult>,\n): Promise<ValidationError[]> {\n return coerceError(entity, await fn(entity));\n}\n\nexport function driverBeforeBegin<TXN>(em: EntityManager<any, any, TXN>, txn: TXN): Promise<unknown> {\n return Promise.all(getEmInternalApi(em).hooks.beforeBegin.map((fn) => fn(em, txn)));\n}\n\nexport function driverAfterBegin<TXN>(em: EntityManager<any, any, TXN>, txn: TXN): Promise<unknown> {\n return Promise.all(getEmInternalApi(em).hooks.afterBegin.map((fn) => fn(em, txn)));\n}\n\nexport function driverBeforeCommit<TXN>(em: EntityManager<any, any, TXN>, txn: TXN): Promise<unknown> {\n return Promise.all(getEmInternalApi(em).hooks.beforeCommit.map((fn) => fn(em, txn)));\n}\n\nexport function driverAfterCommit<TXN>(em: EntityManager<any, any, TXN>, txn: TXN): Promise<unknown> {\n return Promise.all(getEmInternalApi(em).hooks.afterCommit.map((fn) => fn(em, txn)));\n}\n\nasync function runHookOnTodos(\n ctx: unknown,\n hook: EntityHook,\n todos: Record<string, Todo>,\n keys: (\"inserts\" | \"deletes\" | \"updates\")[],\n): Promise<void> {\n // Only collect entities for todos whose type hierarchy actually has this hook, so that\n // hook-less bulk flushes skip the per-entity array building entirely.\n let entities: EntityW[] | undefined = undefined;\n for (const todoKey in todos) {\n const todo = todos[todoKey];\n if (!metaHasHook(todo.metadata, hook)) continue;\n for (const k of keys) {\n for (const e of todo[k]) {\n if (k !== \"deletes\" && e.isDeletedEntity) continue;\n (entities ??= []).push(e);\n }\n }\n }\n if (entities) return runHook(ctx, hook, entities);\n}\n\n/** Returns whether `meta`'s base/self/sub hierarchy has any `hook` functions registered. */\nfunction metaHasHook(meta: EntityMetadata, hook: EntityHook): boolean {\n for (const m of getBaseSelfAndSubMetas(meta)) {\n if (m.config.__data.hooks[hook].length > 0) return true;\n }\n return false;\n}\n\nasync function runHook(ctx: unknown, hook: EntityHook, entities: EntityW[]): Promise<void> {\n let p: Promise<unknown>[] | undefined = undefined;\n for (const entity of entities) {\n for (const m of getBaseAndSelfMetas(getMetadata(entity))) {\n for (const fn of m.config.__data.hooks[hook]) {\n // Use an explicit `async` invoke to ensure all hooks are promises, i.e. so that a\n // non-promise hook blowing up doesn't orphan the others.\n (p ??= []).push(invokeHook(fn, entity, ctx));\n }\n }\n }\n if (!p) return;\n // Use `allSettled` so that even if 1 hook blows up, we don't orphan other hooks mid-flush\n // (causes weird errors when/if they try to access the EntityManager that has \"moved on\")\n const results = await Promise.allSettled(p);\n failIfAnyRejected(results);\n}\n\n/** Invokes a single hook fn, coercing sync throws into rejections. */\nasync function invokeHook(fn: (entity: any, ctx: any) => unknown, entity: EntityW, ctx: unknown): Promise<unknown> {\n return fn(entity, ctx);\n}\n\nfunction beforeDelete(ctx: unknown, todos: Record<string, Todo>): Promise<unknown> {\n return runHookOnTodos(ctx, \"beforeDelete\", todos, [\"deletes\"]);\n}\n\nfunction beforeFlush(ctx: unknown, todos: Record<string, Todo>): Promise<unknown> {\n return runHookOnTodos(ctx, \"beforeFlush\", todos, [\"inserts\", \"updates\"]);\n}\n\nfunction beforeCreate(ctx: unknown, todos: Record<string, Todo>): Promise<unknown> {\n return runHookOnTodos(ctx, \"beforeCreate\", todos, [\"inserts\"]);\n}\n\nfunction beforeUpdate(ctx: unknown, todos: Record<string, Todo>): Promise<unknown> {\n return runHookOnTodos(ctx, \"beforeUpdate\", todos, [\"updates\"]);\n}\n\nfunction afterValidation(ctx: unknown, todos: Record<string, Todo>): Promise<unknown> {\n return runHookOnTodos(ctx, \"afterValidation\", todos, [\"inserts\", \"updates\"]);\n}\n\n/** Collects changed entities from flush todos, i.e. m2m endpoint entities. */\nfunction entitiesFromTodos(\n entityTodos: Record<string, Todo>,\n joinRowTodos: Record<string, JoinRowTodo>,\n): readonly Entity[] {\n const entities = new Set<Entity>();\n for (const todo of Object.values(entityTodos)) {\n for (const list of [todo.inserts, todo.updates, todo.deletes]) {\n for (const entity of list) entities.add(entity);\n }\n }\n for (const todo of Object.values(joinRowTodos)) {\n for (const rows of [todo.newRows, todo.deletedRows]) {\n for (const row of rows) {\n // For enum m2ms, a column value is the enum's numeric id rather than an entity.\n for (const value of Object.values(row.columns)) {\n if (isEntity(value)) entities.add(value);\n }\n }\n }\n }\n return [...entities];\n}\n\nfunction beforeCommit(ctx: unknown, entities: Set<EntityW>): Promise<unknown> {\n return runHook(ctx, \"beforeCommit\", [...entities]);\n}\n\nfunction afterCommit(ctx: unknown, entities: Set<EntityW>): Promise<unknown> {\n return runHook(ctx, \"afterCommit\", [...entities]);\n}\n\n/** Given a validation rule result `maybeError`, returns a canonical `ValidationError[]`. */\nfunction coerceError(entity: Entity, maybeError: ValidationRuleResult): ValidationError[] {\n if (maybeError === undefined) {\n return [];\n } else if (typeof maybeError === \"string\") {\n return [{ entity, message: maybeError }];\n } else if (Array.isArray(maybeError)) {\n return maybeError.map((e) => {\n if (typeof e === \"string\") {\n return { entity, message: e };\n } else {\n return { entity, ...e };\n }\n });\n } else {\n return [{ entity, ...maybeError }];\n }\n}\n\n/** Evaluates each (non-async) derived field to see if it's value has changed. */\nfunction recalcSynchronousDerivedFields(todos: Record<string, Todo>) {\n for (const todoKey in todos) {\n const todo = todos[todoKey];\n for (const entities of [todo.inserts, todo.updates]) {\n for (const entity of entities) {\n if (entity.isDeletedEntity) continue;\n // Use the per-meta cached field list instead of rebuilding a map per hook loop\n for (const fieldName of getMetadata(entity).syncDerivedFields!) {\n // setField will intelligently mark/not mark the field as dirty.\n setField(entity, fieldName as any, (entity as any)[fieldName]);\n }\n }\n }\n }\n}\n\n/** Recursively crawls through `entity`, with the given populate `deep` hint, and adds anything found to `found`. */\nasync function crawl<T extends Entity>(\n found: Set<Entity>,\n // We keep skipMap separated out, instead of tuple-izing `found`, so that `found`\n // can be a set that is cheap to insert & check for duplicates.\n skipMap: WeakMap<Entity, string[]>,\n entities: readonly T[],\n deep: LoadHint<T>,\n opts: { skipIf?: (entity: Entity) => boolean; skip?: object } = {},\n): Promise<void> {\n const { skipIf = () => false } = opts ?? {};\n\n const skip = deepNormalizeHint(opts.skip ?? {});\n // If we're passed `skip = { author: \"publisher\" }`, which is asking to \"don't set `author.publisher`\", then\n // `author` will technically be a key in the \"skip hint\", but it's only there for us to hop down into.\n // So we actually _don't_ skip any fields that have sub-hints, b/c it's the sub-hints themselves we want to skip.\n const skipFields = Object.keys(skip).filter((key) => Object.keys((skip as any)[key]).length === 0);\n\n // It's tempting to check `!found.has(entity)` here, but that would short-circuit later crawling the\n // entity at a potentially different point in the graph, i.e. a deep hint like:\n //\n // `{ comment: parent, books: { author: \"publisher\" } }`\n //\n // If the `comment.parent` was the same `Author` as a `books.author`, but we \"crawled it first\", we'd miss\n // crawling through the author a 2nd time and cloning the publisher.\n const entitiesToClone = entities.filter((e) => !skipIf(e));\n for (const entity of entitiesToClone) {\n found.add(entity);\n skipMap.set(entity, skipFields);\n }\n await Promise.all(\n entitiesToClone.flatMap((entity) =>\n (Object.entries(adaptHint(deep)) as [keyof RelationsIn<T> & string, LoadHint<any>][]).map(\n async ([relationName, nested]) => {\n const relation = entity[relationName];\n // If we're using a deep `skip` hint, drill in to it\n const _opts = { ...opts, skip: (skip as any)[relationName] };\n if (relation instanceof OneToManyCollection) {\n const relatedEntities: readonly Entity[] = await relation.load();\n await crawl(found, skipMap, relatedEntities, nested, _opts);\n } else if (relation instanceof OneToOneReferenceImpl) {\n const related: Entity | undefined = await relation.load();\n if (related) {\n await crawl(found, skipMap, [related], nested, _opts);\n }\n } else if (relation instanceof ManyToOneReferenceImpl) {\n const related: Entity | undefined = await relation.load();\n if (related) {\n await crawl(found, skipMap, [related], nested, _opts);\n }\n } else if (relation instanceof ReactiveReferenceImpl) {\n const relatedEntities: readonly Entity[] = await relation.load();\n await crawl(found, skipMap, relatedEntities, nested, _opts);\n } else {\n fail(`Uncloneable relation: ${relationName}`);\n }\n },\n ),\n ),\n );\n}\n\n/** Takes our flexible string or array or hash load hint and makes it always a hash. */\nfunction adaptHint<T extends Entity>(hint: LoadHint<T> | undefined): NestedLoadHint<T> {\n if ((typeof hint as any) === \"string\") {\n return { [hint as any]: {} } as any;\n } else if (Array.isArray(hint)) {\n return Object.fromEntries(hint.map((relation) => [relation, {}]));\n } else if (hint) {\n return hint as NestedLoadHint<T>;\n } else {\n return {};\n }\n}\n\nexport function isDefined<T extends any>(param: T | undefined | null): param is T {\n return param !== null && param !== undefined;\n}\n\nfunction getCascadeDeleteRelations(entity: Entity): AbstractRelationImpl<any, any>[] {\n return getBaseAndSelfMetas(getMetadata(entity)).flatMap((meta) => {\n return meta.config.__data.cascadeDeleteFields.map((fieldName) => (entity as any)[fieldName]);\n });\n}\n\nfunction isCustomRelation(r: AbstractRelationImpl<any, any>): boolean {\n return r instanceof CustomCollection || r instanceof CustomReference || r instanceof ReactiveReferenceImpl;\n}\n\nfunction maybeBumpUpdatedAt(rm: ReactionsManager, todos: Record<string, Todo>, now: Date): void {\n for (const todo of Object.values(todos)) {\n const { updatedAt } = todo.metadata.timestampFields ?? {};\n if (updatedAt) {\n for (const e of todo.updates) {\n // We avoid going through `setField` because in unit tests, it might detect that our\n // bump's timestamp isn't actually different from the current value, and skip treating\n // it has changed. This is technically true, but this will break the oplock SQL generation,\n // so force the field to be dirty.\n const orm = getInstanceData(e);\n orm.markFieldDirty(updatedAt, getField(e, updatedAt));\n const serde = todo.metadata.fields[updatedAt].serde as TimestampSerde<unknown>;\n orm.data[updatedAt] = serde.mapFromNow(now);\n rm.queueDownstreamReactables(e, updatedAt);\n }\n }\n }\n}\n\nlet lastNow = undefined as Date | undefined;\n\n// exposed so tests that do their own time management can override lastNow to get correct updatedAt values\nexport function setLastNow(now: Date | undefined) {\n lastNow = now;\n}\n\nfunction getNow(): Date {\n let now = new Date();\n // If we detect time has not progressed (or went backwards), we're probably in test that\n // has frozen time, which can throw off our oplocks b/c if Joist issues multiple `UPDATE`s\n // with exactly the same `updated_at`, the `updated_at` SQL trigger fallback will think \"the caller\n // didn't self-manage `updated_at`\" and so bump it for them. Which is fine, but now\n // Joist doesn't know about the bumped time, and the 2nd `UPDATE` will fail.\n if (lastNow && (lastNow.getTime() === now.getTime() || now.getTime() < lastNow.getTime())) {\n now = new Date(lastNow.getTime() + 1);\n }\n lastNow = now;\n return now;\n}\n\n/** Given a `row` from the db, resolves the CTI/STI subtype, if applicable. */\nfunction findConcreteMeta(maybeBaseMeta: EntityMetadata, rowData: RowData, rowIndex: number): EntityMetadata {\n // Common case of no CTI or STI inheritance; only probe __class for CTI metas so that\n // lazy/columnar stores don't pay a missing-column lookup per row for regular entities\n if (maybeBaseMeta.inheritanceType === undefined) {\n return maybeBaseMeta;\n }\n const __class = rowData.get(rowIndex, \"__class\");\n if (!__class && maybeBaseMeta.inheritanceType !== \"sti\") {\n return maybeBaseMeta;\n }\n if (__class) {\n if (__class === \"_\" && maybeBaseMeta.ctiAbstract) {\n const id = rowData.get(rowIndex, \"id\");\n throw new Error(`${maybeBaseMeta.type} ${tagId(maybeBaseMeta, id)} must be instantiated via a subtype`);\n }\n // Look for the CTI __class from the driver telling us which subtype to instantiate\n return maybeBaseMeta.subTypesByType!.get(__class) ?? maybeBaseMeta;\n } else if (maybeBaseMeta.inheritanceType === \"sti\") {\n // Look for the STI discriminator value\n const baseMeta = getBaseMeta(maybeBaseMeta);\n const value = rowData.get(rowIndex, baseMeta.stiDiscriminatorColumnName!);\n return baseMeta.subTypesByStiValue!.get(value) ?? baseMeta;\n } else {\n throw new Error(\"Unknown inheritance type\");\n }\n}\n\n/** Sets the `Animal.type` enum to the right subtype value. */\nfunction setStiDiscriminatorValue(baseMeta: EntityMetadata, entity: Entity): void {\n const typeName = entity.constructor.name;\n const st = baseMeta.subTypesByType!.get(typeName);\n if (st) {\n const field = baseMeta.fields[baseMeta.stiDiscriminatorField!] as EnumField;\n const code = (field.enumDetailType.findById(st.stiDiscriminatorValue!) as any).code;\n (entity as any)[baseMeta.stiDiscriminatorField!] = code;\n } else {\n (entity as any)[baseMeta.stiDiscriminatorField!] = undefined;\n }\n}\n\nfunction findPendingFlushEntities<Entity extends EntityW>(\n maybePendingFlushEntities: Set<Entity>,\n hooksInvoked: Set<Entity>,\n pendingFlush: Set<Entity>,\n pendingHooks: Set<Entity>,\n alreadyRanHooks: Set<Entity>,\n): void {\n for (const e of maybePendingFlushEntities) {\n if (getInstanceData(e).pendingOperation === \"none\") {\n maybePendingFlushEntities.delete(e);\n continue;\n }\n if (!hooksInvoked.has(e)) {\n pendingHooks.add(e);\n } else {\n alreadyRanHooks.add(e);\n }\n pendingFlush.add(e);\n }\n}\n\n/** Returns true if the caller explicitly asked `find` to use SQL pagination. */\nfunction hasPaginationSettings(options: object): boolean {\n return \"limit\" in options || \"offset\" in options;\n}\n\n/** An error we throw to get knex to `ROLLBACK`, but then catch. */\nclass InMemoryRollbackError extends Error {}\n\n/** An error thrown when `em.mode === \"read-only\"` but entities are mutated/flushed. */\nexport class ReadOnlyError extends Error {\n constructor() {\n super(\"EntityManager is read-only\");\n }\n}\n\nfunction maybeSetupHookOrdering(todos: Record<string, Todo>): Record<string, Todo>[] {\n // I'm too rushed to use a topo sort\n const group1: Record<string, Todo> = {};\n const group2: Record<string, Todo> = {};\n for (const todo of Object.values(todos)) {\n // If I should run before `cstr`, I go in group1\n const shouldRunBeforeAnotherGroup = todo.metadata.config.__data.runHooksBefore.some(\n (cstr) => getBaseMeta(getMetadata(cstr)).type in todos,\n );\n const group = shouldRunBeforeAnotherGroup ? group1 : group2;\n group[todo.metadata.type] = todo;\n }\n return Object.keys(group1).length ? [group1, group2] : [group2];\n}\n\n/**\n * Given an `err` thrown in \"a different context\", i.e. a database error or dataloader error\n * that doesn't include our stack trace, append our stack for better debugging.\n *\n * See https://github.com/brianc/node-postgres/pull/2983\n */\nexport function appendStack(err: unknown, dummy: Error): unknown {\n if (err && typeof err === \"object\" && \"stack\" in err) {\n err.stack += dummy.stack!.replace(/.*\\n/, \"\\n\");\n }\n return err;\n}\n\n/** Probe for `ctx.logger.debug` if it exists, otherwise fallback on `console.log`. */\nfunction getDefaultWriteFn(ctx: unknown): WriteFn {\n return ctx &&\n typeof ctx === \"object\" &&\n \"logger\" in ctx &&\n ctx.logger &&\n typeof ctx.logger === \"object\" &&\n \"debug\" in ctx.logger &&\n ctx.logger.debug instanceof Function\n ? ctx.logger.debug.bind(ctx.logger)\n : console.log;\n}\n\nconst fieldMap: Record<string, [Field, FieldColumn][]> = {};\n// Generates what a row from the db would look like for a given entity\nexport function createRowFromEntityData(e: Entity, opts: { preferOriginalData?: boolean } = {}) {\n const { preferOriginalData = true } = opts;\n const { rowData, rowIndex, data, originalData } = (e as any).__data as InstanceData;\n const __class = e.constructor.name;\n const { metadata: meta } = (e as any).__data as InstanceData;\n if (!fieldMap[__class]) {\n fieldMap[__class] = [];\n for (const field of Object.values(meta.allFields)) {\n if (!field.serde) continue;\n for (const column of field.serde.columns) {\n fieldMap[__class].push([field, column]);\n }\n }\n }\n\n const row: Record<string, any> = meta.inheritanceType === \"cti\" ? { __class } : {};\n\n for (const [field, column] of fieldMap[__class]) {\n const value: any =\n // Ideally, we could only go through the serde for data that has actually changed since the last time it was\n // fetched from the db and just use the row value for everything else. Unfortunately, we lose track of which\n // fields are modified on flush. So we have to assume that anything present in `data` is a change and push it\n // through the serde.\n field.fieldName in originalData || field.fieldName in data\n ? // If our field is in originalData, then the field has been changed since flush. Our `row` should\n // reflect what would come from the db if we queried it right now, so use originalData when present\n column.rowValue(preferOriginalData && field.fieldName in originalData ? originalData : data)\n : // `data` is lazy and isn't set until it's accessed, so if the field isn't present there, then we should\n // be safe to pull the raw data out of the as-loaded RowData\n rowData.get(rowIndex, column.columnName);\n row[column.columnName] = value ?? null;\n }\n return row;\n}\n"],"mappings":"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"}