joist-core 2.4.0-next.37 → 2.4.0-next.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/BaseEntity.d.cts +3 -4
- package/build/BaseEntity.d.cts.map +1 -1
- package/build/BaseEntity.d.mts +3 -4
- package/build/BaseEntity.d.mts.map +1 -1
- package/build/Entity.d.cts +3 -4
- package/build/Entity.d.cts.map +1 -1
- package/build/Entity.d.mts +3 -4
- package/build/Entity.d.mts.map +1 -1
- package/build/EntityFields.d.cts +3 -4
- package/build/EntityFields.d.cts.map +1 -1
- package/build/EntityFields.d.mts +3 -4
- package/build/EntityFields.d.mts.map +1 -1
- package/build/EntityManager.cjs +11 -3
- package/build/EntityManager.cjs.map +1 -1
- package/build/EntityManager.d.cts +47 -41
- package/build/EntityManager.d.cts.map +1 -1
- package/build/EntityManager.d.mts +47 -41
- package/build/EntityManager.d.mts.map +1 -1
- package/build/EntityManager.js +11 -3
- package/build/EntityManager.js.map +1 -1
- package/build/EntityMetadata.d.cts +31 -32
- package/build/EntityMetadata.d.cts.map +1 -1
- package/build/EntityMetadata.d.mts +31 -32
- package/build/EntityMetadata.d.mts.map +1 -1
- package/build/EnumMetadata.d.cts +1 -2
- package/build/EnumMetadata.d.cts.map +1 -1
- package/build/EnumMetadata.d.mts +1 -2
- package/build/EnumMetadata.d.mts.map +1 -1
- package/build/IndexManager.cjs.map +1 -1
- package/build/IndexManager.d.cts +2 -3
- package/build/IndexManager.d.cts.map +1 -1
- package/build/IndexManager.d.mts +2 -3
- package/build/IndexManager.d.mts.map +1 -1
- package/build/IndexManager.js.map +1 -1
- package/build/InstanceData.cjs.map +1 -1
- package/build/InstanceData.d.cts +1 -2
- package/build/InstanceData.d.cts.map +1 -1
- package/build/InstanceData.d.mts +1 -2
- package/build/InstanceData.d.mts.map +1 -1
- package/build/InstanceData.js.map +1 -1
- package/build/PluginManager.cjs.map +1 -1
- package/build/PluginManager.d.cts +4 -4
- package/build/PluginManager.d.cts.map +1 -1
- package/build/PluginManager.d.mts +4 -4
- package/build/PluginManager.d.mts.map +1 -1
- package/build/PluginManager.js.map +1 -1
- package/build/RowData.d.cts +3 -4
- package/build/RowData.d.cts.map +1 -1
- package/build/RowData.d.mts +3 -4
- package/build/RowData.d.mts.map +1 -1
- package/build/batchloaders/BatchLoader.cjs.map +1 -1
- package/build/batchloaders/BatchLoader.d.cts +1 -2
- package/build/batchloaders/BatchLoader.d.cts.map +1 -1
- package/build/batchloaders/BatchLoader.d.mts +1 -2
- package/build/batchloaders/BatchLoader.d.mts.map +1 -1
- package/build/batchloaders/BatchLoader.js.map +1 -1
- package/build/batchloaders/enumCollectionBatchLoader.d.cts +2 -3
- package/build/batchloaders/enumCollectionBatchLoader.d.cts.map +1 -1
- package/build/batchloaders/enumCollectionBatchLoader.d.mts +2 -3
- package/build/batchloaders/enumCollectionBatchLoader.d.mts.map +1 -1
- package/build/batchloaders/loadBatchLoader.d.cts +2 -3
- package/build/batchloaders/loadBatchLoader.d.cts.map +1 -1
- package/build/batchloaders/loadBatchLoader.d.mts +2 -3
- package/build/batchloaders/loadBatchLoader.d.mts.map +1 -1
- package/build/batchloaders/manyToManyBatchLoader.d.cts +2 -3
- package/build/batchloaders/manyToManyBatchLoader.d.cts.map +1 -1
- package/build/batchloaders/manyToManyBatchLoader.d.mts +2 -3
- package/build/batchloaders/manyToManyBatchLoader.d.mts.map +1 -1
- package/build/batchloaders/oneToManyBatchLoader.d.cts +2 -3
- package/build/batchloaders/oneToManyBatchLoader.d.cts.map +1 -1
- package/build/batchloaders/oneToManyBatchLoader.d.mts +2 -3
- package/build/batchloaders/oneToManyBatchLoader.d.mts.map +1 -1
- package/build/batchloaders/oneToOneBatchLoader.d.cts +2 -3
- package/build/batchloaders/oneToOneBatchLoader.d.cts.map +1 -1
- package/build/batchloaders/oneToOneBatchLoader.d.mts +2 -3
- package/build/batchloaders/oneToOneBatchLoader.d.mts.map +1 -1
- package/build/batchloaders/populateBatchLoader.d.cts +2 -3
- package/build/batchloaders/populateBatchLoader.d.cts.map +1 -1
- package/build/batchloaders/populateBatchLoader.d.mts +2 -3
- package/build/batchloaders/populateBatchLoader.d.mts.map +1 -1
- package/build/batchloaders/recursiveChildrenBatchLoader.d.cts +2 -3
- package/build/batchloaders/recursiveChildrenBatchLoader.d.cts.map +1 -1
- package/build/batchloaders/recursiveChildrenBatchLoader.d.mts +2 -3
- package/build/batchloaders/recursiveChildrenBatchLoader.d.mts.map +1 -1
- package/build/batchloaders/recursiveM2mBatchLoader.d.cts +2 -3
- package/build/batchloaders/recursiveM2mBatchLoader.d.cts.map +1 -1
- package/build/batchloaders/recursiveM2mBatchLoader.d.mts +2 -3
- package/build/batchloaders/recursiveM2mBatchLoader.d.mts.map +1 -1
- package/build/batchloaders/recursiveParentsBatchLoader.d.cts +2 -3
- package/build/batchloaders/recursiveParentsBatchLoader.d.cts.map +1 -1
- package/build/batchloaders/recursiveParentsBatchLoader.d.mts +2 -3
- package/build/batchloaders/recursiveParentsBatchLoader.d.mts.map +1 -1
- package/build/changes.cjs.map +1 -1
- package/build/changes.d.cts +9 -10
- package/build/changes.d.cts.map +1 -1
- package/build/changes.d.mts +9 -10
- package/build/changes.d.mts.map +1 -1
- package/build/changes.js.map +1 -1
- package/build/config.d.cts +17 -17
- package/build/config.d.cts.map +1 -1
- package/build/config.d.mts +17 -17
- package/build/config.d.mts.map +1 -1
- package/build/configure.d.cts +8 -9
- package/build/configure.d.cts.map +1 -1
- package/build/configure.d.mts +8 -9
- package/build/configure.d.mts.map +1 -1
- package/build/dataloaders/fastWhereFilterHash.d.cts +1 -2
- package/build/dataloaders/fastWhereFilterHash.d.cts.map +1 -1
- package/build/dataloaders/fastWhereFilterHash.d.mts +1 -2
- package/build/dataloaders/fastWhereFilterHash.d.mts.map +1 -1
- package/build/dataloaders/findByUniqueDataLoader.d.cts +2 -3
- package/build/dataloaders/findByUniqueDataLoader.d.cts.map +1 -1
- package/build/dataloaders/findByUniqueDataLoader.d.mts +2 -3
- package/build/dataloaders/findByUniqueDataLoader.d.mts.map +1 -1
- package/build/dataloaders/findCountDataLoader.d.cts +4 -5
- package/build/dataloaders/findCountDataLoader.d.cts.map +1 -1
- package/build/dataloaders/findCountDataLoader.d.mts +4 -5
- package/build/dataloaders/findCountDataLoader.d.mts.map +1 -1
- package/build/dataloaders/findDataLoader.d.cts +11 -12
- package/build/dataloaders/findDataLoader.d.cts.map +1 -1
- package/build/dataloaders/findDataLoader.d.mts +11 -12
- package/build/dataloaders/findDataLoader.d.mts.map +1 -1
- package/build/dataloaders/findIdsDataLoader.d.cts +2 -3
- package/build/dataloaders/findIdsDataLoader.d.cts.map +1 -1
- package/build/dataloaders/findIdsDataLoader.d.mts +2 -3
- package/build/dataloaders/findIdsDataLoader.d.mts.map +1 -1
- package/build/dataloaders/findOrCreateDataLoader.d.cts +3 -3
- package/build/dataloaders/findOrCreateDataLoader.d.cts.map +1 -1
- package/build/dataloaders/findOrCreateDataLoader.d.mts +3 -3
- package/build/dataloaders/findOrCreateDataLoader.d.mts.map +1 -1
- package/build/dataloaders/findPaginatedDataLoader.d.cts +1 -2
- package/build/dataloaders/findPaginatedDataLoader.d.cts.map +1 -1
- package/build/dataloaders/findPaginatedDataLoader.d.mts +1 -2
- package/build/dataloaders/findPaginatedDataLoader.d.mts.map +1 -1
- package/build/dataloaders/lensDataLoader.d.cts +2 -3
- package/build/dataloaders/lensDataLoader.d.cts.map +1 -1
- package/build/dataloaders/lensDataLoader.d.mts +2 -3
- package/build/dataloaders/lensDataLoader.d.mts.map +1 -1
- package/build/dataloaders/manyToManyFindDataLoader.d.cts +2 -3
- package/build/dataloaders/manyToManyFindDataLoader.d.cts.map +1 -1
- package/build/dataloaders/manyToManyFindDataLoader.d.mts +2 -3
- package/build/dataloaders/manyToManyFindDataLoader.d.mts.map +1 -1
- package/build/dataloaders/oneToManyFindDataLoader.d.cts +2 -3
- package/build/dataloaders/oneToManyFindDataLoader.d.cts.map +1 -1
- package/build/dataloaders/oneToManyFindDataLoader.d.mts +2 -3
- package/build/dataloaders/oneToManyFindDataLoader.d.mts.map +1 -1
- package/build/defaults.cjs.map +1 -1
- package/build/defaults.d.cts +7 -7
- package/build/defaults.d.cts.map +1 -1
- package/build/defaults.d.mts +7 -7
- package/build/defaults.d.mts.map +1 -1
- package/build/defaults.js.map +1 -1
- package/build/drivers/Driver.d.cts +2 -3
- package/build/drivers/Driver.d.cts.map +1 -1
- package/build/drivers/Driver.d.mts +2 -3
- package/build/drivers/Driver.d.mts.map +1 -1
- package/build/drivers/EntityWriter.d.cts +7 -7
- package/build/drivers/EntityWriter.d.cts.map +1 -1
- package/build/drivers/EntityWriter.d.mts +7 -7
- package/build/drivers/EntityWriter.d.mts.map +1 -1
- package/build/drivers/IdAssigner.cjs.map +1 -1
- package/build/drivers/IdAssigner.d.cts +5 -5
- package/build/drivers/IdAssigner.d.cts.map +1 -1
- package/build/drivers/IdAssigner.d.mts +5 -5
- package/build/drivers/IdAssigner.d.mts.map +1 -1
- package/build/drivers/IdAssigner.js.map +1 -1
- package/build/drivers/driverApi.d.cts +2 -3
- package/build/drivers/driverApi.d.cts.map +1 -1
- package/build/drivers/driverApi.d.mts +2 -3
- package/build/drivers/driverApi.d.mts.map +1 -1
- package/build/fields.d.cts +6 -7
- package/build/fields.d.cts.map +1 -1
- package/build/fields.d.mts +6 -7
- package/build/fields.d.mts.map +1 -1
- package/build/flush/FlushLock.cjs.map +1 -1
- package/build/flush/FlushLock.d.cts +1 -2
- package/build/flush/FlushLock.d.cts.map +1 -1
- package/build/flush/FlushLock.d.mts +1 -2
- package/build/flush/FlushLock.d.mts.map +1 -1
- package/build/flush/FlushLock.js.map +1 -1
- package/build/flush/JoinRows.cjs.map +1 -1
- package/build/flush/JoinRows.d.cts +5 -6
- package/build/flush/JoinRows.d.cts.map +1 -1
- package/build/flush/JoinRows.d.mts +5 -6
- package/build/flush/JoinRows.d.mts.map +1 -1
- package/build/flush/JoinRows.js.map +1 -1
- package/build/flush/PendingChanges.d.cts +5 -6
- package/build/flush/PendingChanges.d.cts.map +1 -1
- package/build/flush/PendingChanges.d.mts +5 -6
- package/build/flush/PendingChanges.d.mts.map +1 -1
- package/build/flush/Todo.d.cts +5 -6
- package/build/flush/Todo.d.cts.map +1 -1
- package/build/flush/Todo.d.mts +5 -6
- package/build/flush/Todo.d.mts.map +1 -1
- package/build/getProperties.d.cts +3 -4
- package/build/getProperties.d.cts.map +1 -1
- package/build/getProperties.d.mts +3 -4
- package/build/getProperties.d.mts.map +1 -1
- package/build/index.d.cts +17 -17
- package/build/index.d.cts.map +1 -1
- package/build/index.d.mts +17 -17
- package/build/index.d.mts.map +1 -1
- package/build/json.d.cts +11 -11
- package/build/json.d.cts.map +1 -1
- package/build/json.d.mts +11 -11
- package/build/json.d.mts.map +1 -1
- package/build/keys.d.cts +27 -27
- package/build/keys.d.cts.map +1 -1
- package/build/keys.d.mts +27 -27
- package/build/keys.d.mts.map +1 -1
- package/build/loading/HintTree.d.cts +3 -4
- package/build/loading/HintTree.d.cts.map +1 -1
- package/build/loading/HintTree.d.mts +3 -4
- package/build/loading/HintTree.d.mts.map +1 -1
- package/build/loading/IsLoadedCache.cjs.map +1 -1
- package/build/loading/IsLoadedCache.d.cts +2 -3
- package/build/loading/IsLoadedCache.d.cts.map +1 -1
- package/build/loading/IsLoadedCache.d.mts +2 -3
- package/build/loading/IsLoadedCache.d.mts.map +1 -1
- package/build/loading/IsLoadedCache.js.map +1 -1
- package/build/loading/loadHints.d.cts +17 -17
- package/build/loading/loadHints.d.cts.map +1 -1
- package/build/loading/loadHints.d.mts +17 -17
- package/build/loading/loadHints.d.mts.map +1 -1
- package/build/loading/loadLens.d.cts +13 -13
- package/build/loading/loadLens.d.cts.map +1 -1
- package/build/loading/loadLens.d.mts +13 -13
- package/build/loading/loadLens.d.mts.map +1 -1
- package/build/loading/withLoaded.d.cts +5 -6
- package/build/loading/withLoaded.d.cts.map +1 -1
- package/build/loading/withLoaded.d.mts +5 -6
- package/build/loading/withLoaded.d.mts.map +1 -1
- package/build/logging/FactoryLogger.d.cts +3 -4
- package/build/logging/FactoryLogger.d.cts.map +1 -1
- package/build/logging/FactoryLogger.d.mts +3 -4
- package/build/logging/FactoryLogger.d.mts.map +1 -1
- package/build/logging/FieldLogger.cjs.map +1 -1
- package/build/logging/FieldLogger.d.cts +4 -5
- package/build/logging/FieldLogger.d.cts.map +1 -1
- package/build/logging/FieldLogger.d.mts +4 -5
- package/build/logging/FieldLogger.d.mts.map +1 -1
- package/build/logging/FieldLogger.js.map +1 -1
- package/build/logging/ReactionLogger.d.cts +7 -7
- package/build/logging/ReactionLogger.d.cts.map +1 -1
- package/build/logging/ReactionLogger.d.mts +7 -7
- package/build/logging/ReactionLogger.d.mts.map +1 -1
- package/build/newEntity.cjs.map +1 -1
- package/build/newEntity.d.cts +4 -5
- package/build/newEntity.d.cts.map +1 -1
- package/build/newEntity.d.mts +4 -5
- package/build/newEntity.d.mts.map +1 -1
- package/build/newEntity.js.map +1 -1
- package/build/newTestInstance.d.cts +21 -21
- package/build/newTestInstance.d.cts.map +1 -1
- package/build/newTestInstance.d.mts +21 -21
- package/build/newTestInstance.d.mts.map +1 -1
- package/build/normalizeHints.d.cts +7 -8
- package/build/normalizeHints.d.cts.map +1 -1
- package/build/normalizeHints.d.mts +7 -8
- package/build/normalizeHints.d.mts.map +1 -1
- package/build/nowUTC.d.cts +4 -5
- package/build/nowUTC.d.cts.map +1 -1
- package/build/nowUTC.d.mts +4 -5
- package/build/nowUTC.d.mts.map +1 -1
- package/build/plugins/ImmutableEntitiesPlugin.d.cts +1 -2
- package/build/plugins/ImmutableEntitiesPlugin.d.cts.map +1 -1
- package/build/plugins/ImmutableEntitiesPlugin.d.mts +1 -2
- package/build/plugins/ImmutableEntitiesPlugin.d.mts.map +1 -1
- package/build/plugins/PreloadPlugin.d.cts +3 -4
- package/build/plugins/PreloadPlugin.d.cts.map +1 -1
- package/build/plugins/PreloadPlugin.d.mts +3 -4
- package/build/plugins/PreloadPlugin.d.mts.map +1 -1
- package/build/preloading/JsonAggregatePreloader.d.cts +1 -2
- package/build/preloading/JsonAggregatePreloader.d.cts.map +1 -1
- package/build/preloading/JsonAggregatePreloader.d.mts +1 -2
- package/build/preloading/JsonAggregatePreloader.d.mts.map +1 -1
- package/build/preloading/canPreload.d.cts +1 -2
- package/build/preloading/canPreload.d.cts.map +1 -1
- package/build/preloading/canPreload.d.mts +1 -2
- package/build/preloading/canPreload.d.mts.map +1 -1
- package/build/preloading/partitionHint.d.cts +1 -2
- package/build/preloading/partitionHint.d.cts.map +1 -1
- package/build/preloading/partitionHint.d.mts +1 -2
- package/build/preloading/partitionHint.d.mts.map +1 -1
- package/build/queries/ConditionBuilder.d.cts +2 -2
- package/build/queries/ConditionBuilder.d.cts.map +1 -1
- package/build/queries/ConditionBuilder.d.mts +2 -2
- package/build/queries/ConditionBuilder.d.mts.map +1 -1
- package/build/queries/conditions.d.cts +11 -12
- package/build/queries/conditions.d.cts.map +1 -1
- package/build/queries/conditions.d.mts +11 -12
- package/build/queries/conditions.d.mts.map +1 -1
- package/build/queries/entityQueryUtils.d.cts +4 -5
- package/build/queries/entityQueryUtils.d.cts.map +1 -1
- package/build/queries/entityQueryUtils.d.mts +4 -5
- package/build/queries/entityQueryUtils.d.mts.map +1 -1
- package/build/queries/find/Aliases.d.cts +16 -16
- package/build/queries/find/Aliases.d.cts.map +1 -1
- package/build/queries/find/Aliases.d.mts +16 -16
- package/build/queries/find/Aliases.d.mts.map +1 -1
- package/build/queries/find/DeferredAlias.d.cts +5 -6
- package/build/queries/find/DeferredAlias.d.cts.map +1 -1
- package/build/queries/find/DeferredAlias.d.mts +5 -6
- package/build/queries/find/DeferredAlias.d.mts.map +1 -1
- package/build/queries/find/EntityFilter.d.cts +12 -13
- package/build/queries/find/EntityFilter.d.cts.map +1 -1
- package/build/queries/find/EntityFilter.d.mts +12 -13
- package/build/queries/find/EntityFilter.d.mts.map +1 -1
- package/build/queries/find/EntityGraphQLFilter.d.cts +8 -9
- package/build/queries/find/EntityGraphQLFilter.d.cts.map +1 -1
- package/build/queries/find/EntityGraphQLFilter.d.mts +8 -9
- package/build/queries/find/EntityGraphQLFilter.d.mts.map +1 -1
- package/build/queries/find/QueryParser.collectionJoins.d.cts +1 -2
- package/build/queries/find/QueryParser.collectionJoins.d.cts.map +1 -1
- package/build/queries/find/QueryParser.collectionJoins.d.mts +1 -2
- package/build/queries/find/QueryParser.collectionJoins.d.mts.map +1 -1
- package/build/queries/find/QueryParser.d.cts +18 -18
- package/build/queries/find/QueryParser.d.cts.map +1 -1
- package/build/queries/find/QueryParser.d.mts +18 -18
- package/build/queries/find/QueryParser.d.mts.map +1 -1
- package/build/queries/find/QueryParser.pruning.d.cts +2 -3
- package/build/queries/find/QueryParser.pruning.d.cts.map +1 -1
- package/build/queries/find/QueryParser.pruning.d.mts +2 -3
- package/build/queries/find/QueryParser.pruning.d.mts.map +1 -1
- package/build/queries/find/QueryVisitor.d.cts +4 -4
- package/build/queries/find/QueryVisitor.d.cts.map +1 -1
- package/build/queries/find/QueryVisitor.d.mts +4 -4
- package/build/queries/find/QueryVisitor.d.mts.map +1 -1
- package/build/queries/find/buildFindQuery.d.cts +3 -3
- package/build/queries/find/buildFindQuery.d.cts.map +1 -1
- package/build/queries/find/buildFindQuery.d.mts +3 -3
- package/build/queries/find/buildFindQuery.d.mts.map +1 -1
- package/build/queries/find/scopes.cjs.map +1 -1
- package/build/queries/find/scopes.d.cts +12 -13
- package/build/queries/find/scopes.d.cts.map +1 -1
- package/build/queries/find/scopes.d.mts +12 -13
- package/build/queries/find/scopes.d.mts.map +1 -1
- package/build/queries/find/scopes.js.map +1 -1
- package/build/queries/parsedConditions.d.cts +7 -8
- package/build/queries/parsedConditions.d.cts.map +1 -1
- package/build/queries/parsedConditions.d.mts +7 -8
- package/build/queries/parsedConditions.d.mts.map +1 -1
- package/build/queries/renderConditions.d.cts +3 -4
- package/build/queries/renderConditions.d.cts.map +1 -1
- package/build/queries/renderConditions.d.mts +3 -4
- package/build/queries/renderConditions.d.mts.map +1 -1
- package/build/queries/skipCondition.d.cts +1 -2
- package/build/queries/skipCondition.d.cts.map +1 -1
- package/build/queries/skipCondition.d.mts +1 -2
- package/build/queries/skipCondition.d.mts.map +1 -1
- package/build/queries/sql/AliasAssigner.cjs.map +1 -1
- package/build/queries/sql/AliasAssigner.d.cts +1 -2
- package/build/queries/sql/AliasAssigner.d.cts.map +1 -1
- package/build/queries/sql/AliasAssigner.d.mts +1 -2
- package/build/queries/sql/AliasAssigner.d.mts.map +1 -1
- package/build/queries/sql/AliasAssigner.js.map +1 -1
- package/build/queries/sql/Expr.d.cts +26 -27
- package/build/queries/sql/Expr.d.cts.map +1 -1
- package/build/queries/sql/Expr.d.mts +26 -27
- package/build/queries/sql/Expr.d.mts.map +1 -1
- package/build/queries/sql/JoinTree.d.cts +5 -5
- package/build/queries/sql/JoinTree.d.cts.map +1 -1
- package/build/queries/sql/JoinTree.d.mts +5 -5
- package/build/queries/sql/JoinTree.d.mts.map +1 -1
- package/build/queries/sql/Tables.d.cts +39 -39
- package/build/queries/sql/Tables.d.cts.map +1 -1
- package/build/queries/sql/Tables.d.mts +39 -39
- package/build/queries/sql/Tables.d.mts.map +1 -1
- package/build/queries/sql/custom.d.cts +14 -14
- package/build/queries/sql/custom.d.cts.map +1 -1
- package/build/queries/sql/custom.d.mts +14 -14
- package/build/queries/sql/custom.d.mts.map +1 -1
- package/build/queries/sql/execute.d.cts +15 -15
- package/build/queries/sql/execute.d.cts.map +1 -1
- package/build/queries/sql/execute.d.mts +15 -15
- package/build/queries/sql/execute.d.mts.map +1 -1
- package/build/queries/sql/expressions/arrayAgg.d.cts +5 -6
- package/build/queries/sql/expressions/arrayAgg.d.cts.map +1 -1
- package/build/queries/sql/expressions/arrayAgg.d.mts +5 -6
- package/build/queries/sql/expressions/arrayAgg.d.mts.map +1 -1
- package/build/queries/sql/expressions/case.d.cts +10 -10
- package/build/queries/sql/expressions/case.d.cts.map +1 -1
- package/build/queries/sql/expressions/case.d.mts +10 -10
- package/build/queries/sql/expressions/case.d.mts.map +1 -1
- package/build/queries/sql/expressions/coalesce.d.cts +5 -6
- package/build/queries/sql/expressions/coalesce.d.cts.map +1 -1
- package/build/queries/sql/expressions/coalesce.d.mts +5 -6
- package/build/queries/sql/expressions/coalesce.d.mts.map +1 -1
- package/build/queries/sql/expressions/codecs.d.cts +1 -2
- package/build/queries/sql/expressions/codecs.d.cts.map +1 -1
- package/build/queries/sql/expressions/codecs.d.mts +1 -2
- package/build/queries/sql/expressions/codecs.d.mts.map +1 -1
- package/build/queries/sql/expressions/expression.d.cts +6 -6
- package/build/queries/sql/expressions/expression.d.cts.map +1 -1
- package/build/queries/sql/expressions/expression.d.mts +6 -6
- package/build/queries/sql/expressions/expression.d.mts.map +1 -1
- package/build/queries/sql/expressions/greatest.d.cts +5 -6
- package/build/queries/sql/expressions/greatest.d.cts.map +1 -1
- package/build/queries/sql/expressions/greatest.d.mts +5 -6
- package/build/queries/sql/expressions/greatest.d.mts.map +1 -1
- package/build/queries/sql/expressions/least.d.cts +5 -6
- package/build/queries/sql/expressions/least.d.cts.map +1 -1
- package/build/queries/sql/expressions/least.d.mts +5 -6
- package/build/queries/sql/expressions/least.d.mts.map +1 -1
- package/build/queries/sql/expressions/nullIf.d.cts +5 -6
- package/build/queries/sql/expressions/nullIf.d.cts.map +1 -1
- package/build/queries/sql/expressions/nullIf.d.mts +5 -6
- package/build/queries/sql/expressions/nullIf.d.mts.map +1 -1
- package/build/queries/sql/expressions/parseExpression.d.cts +5 -6
- package/build/queries/sql/expressions/parseExpression.d.cts.map +1 -1
- package/build/queries/sql/expressions/parseExpression.d.mts +5 -6
- package/build/queries/sql/expressions/parseExpression.d.mts.map +1 -1
- package/build/queries/sql/expressions/types.d.cts +11 -11
- package/build/queries/sql/expressions/types.d.cts.map +1 -1
- package/build/queries/sql/expressions/types.d.mts +11 -11
- package/build/queries/sql/expressions/types.d.mts.map +1 -1
- package/build/queries/sql/keywords.d.cts +4 -5
- package/build/queries/sql/keywords.d.cts.map +1 -1
- package/build/queries/sql/keywords.d.mts +4 -5
- package/build/queries/sql/keywords.d.mts.map +1 -1
- package/build/queries/sql/query.cjs.map +1 -1
- package/build/queries/sql/query.d.cts +67 -67
- package/build/queries/sql/query.d.cts.map +1 -1
- package/build/queries/sql/query.d.mts +67 -67
- package/build/queries/sql/query.d.mts.map +1 -1
- package/build/queries/sql/query.js.map +1 -1
- package/build/queries/unnest.d.cts +2 -3
- package/build/queries/unnest.d.cts.map +1 -1
- package/build/queries/unnest.d.mts +2 -3
- package/build/queries/unnest.d.mts.map +1 -1
- package/build/queries/valueFilters.d.cts +5 -6
- package/build/queries/valueFilters.d.cts.map +1 -1
- package/build/queries/valueFilters.d.mts +5 -6
- package/build/queries/valueFilters.d.mts.map +1 -1
- package/build/reactivity/ReactionsManager.cjs.map +1 -1
- package/build/reactivity/ReactionsManager.d.cts +2 -3
- package/build/reactivity/ReactionsManager.d.cts.map +1 -1
- package/build/reactivity/ReactionsManager.d.mts +2 -3
- package/build/reactivity/ReactionsManager.d.mts.map +1 -1
- package/build/reactivity/ReactionsManager.js.map +1 -1
- package/build/reactivity/reactiveHints.d.cts +18 -18
- package/build/reactivity/reactiveHints.d.cts.map +1 -1
- package/build/reactivity/reactiveHints.d.mts +18 -18
- package/build/reactivity/reactiveHints.d.mts.map +1 -1
- package/build/relations/AbstractPropertyImpl.cjs.map +1 -1
- package/build/relations/AbstractPropertyImpl.d.cts +1 -2
- package/build/relations/AbstractPropertyImpl.d.cts.map +1 -1
- package/build/relations/AbstractPropertyImpl.d.mts +1 -2
- package/build/relations/AbstractPropertyImpl.d.mts.map +1 -1
- package/build/relations/AbstractPropertyImpl.js.map +1 -1
- package/build/relations/AbstractRelationImpl.d.cts +1 -2
- package/build/relations/AbstractRelationImpl.d.cts.map +1 -1
- package/build/relations/AbstractRelationImpl.d.mts +1 -2
- package/build/relations/AbstractRelationImpl.d.mts.map +1 -1
- package/build/relations/AsyncProperty.cjs.map +1 -1
- package/build/relations/AsyncProperty.d.cts +5 -6
- package/build/relations/AsyncProperty.d.cts.map +1 -1
- package/build/relations/AsyncProperty.d.mts +5 -6
- package/build/relations/AsyncProperty.d.mts.map +1 -1
- package/build/relations/AsyncProperty.js.map +1 -1
- package/build/relations/AsyncReactiveField.cjs.map +1 -1
- package/build/relations/AsyncReactiveField.d.cts +4 -5
- package/build/relations/AsyncReactiveField.d.cts.map +1 -1
- package/build/relations/AsyncReactiveField.d.mts +4 -5
- package/build/relations/AsyncReactiveField.d.mts.map +1 -1
- package/build/relations/AsyncReactiveField.js.map +1 -1
- package/build/relations/Collection.d.cts +4 -5
- package/build/relations/Collection.d.cts.map +1 -1
- package/build/relations/Collection.d.mts +4 -5
- package/build/relations/Collection.d.mts.map +1 -1
- package/build/relations/CustomCollection.cjs.map +1 -1
- package/build/relations/CustomCollection.d.cts +3 -4
- package/build/relations/CustomCollection.d.cts.map +1 -1
- package/build/relations/CustomCollection.d.mts +3 -4
- package/build/relations/CustomCollection.d.mts.map +1 -1
- package/build/relations/CustomCollection.js.map +1 -1
- package/build/relations/CustomReference.cjs.map +1 -1
- package/build/relations/CustomReference.d.cts +3 -4
- package/build/relations/CustomReference.d.cts.map +1 -1
- package/build/relations/CustomReference.d.mts +3 -4
- package/build/relations/CustomReference.d.mts.map +1 -1
- package/build/relations/CustomReference.js.map +1 -1
- package/build/relations/EnumCollection.cjs.map +1 -1
- package/build/relations/EnumCollection.d.cts +5 -5
- package/build/relations/EnumCollection.d.cts.map +1 -1
- package/build/relations/EnumCollection.d.mts +5 -5
- package/build/relations/EnumCollection.d.mts.map +1 -1
- package/build/relations/EnumCollection.js.map +1 -1
- package/build/relations/LargeCollection.d.cts +1 -2
- package/build/relations/LargeCollection.d.cts.map +1 -1
- package/build/relations/LargeCollection.d.mts +1 -2
- package/build/relations/LargeCollection.d.mts.map +1 -1
- package/build/relations/LazyField.cjs.map +1 -1
- package/build/relations/LazyField.d.cts +7 -8
- package/build/relations/LazyField.d.cts.map +1 -1
- package/build/relations/LazyField.d.mts +7 -8
- package/build/relations/LazyField.d.mts.map +1 -1
- package/build/relations/LazyField.js.map +1 -1
- package/build/relations/ManyToManyCollection.cjs.map +1 -1
- package/build/relations/ManyToManyCollection.d.cts +2 -3
- package/build/relations/ManyToManyCollection.d.cts.map +1 -1
- package/build/relations/ManyToManyCollection.d.mts +2 -3
- package/build/relations/ManyToManyCollection.d.mts.map +1 -1
- package/build/relations/ManyToManyCollection.js.map +1 -1
- package/build/relations/ManyToManyLargeCollection.d.cts +2 -3
- package/build/relations/ManyToManyLargeCollection.d.cts.map +1 -1
- package/build/relations/ManyToManyLargeCollection.d.mts +2 -3
- package/build/relations/ManyToManyLargeCollection.d.mts.map +1 -1
- package/build/relations/ManyToOneReference.cjs.map +1 -1
- package/build/relations/ManyToOneReference.d.cts +6 -7
- package/build/relations/ManyToOneReference.d.cts.map +1 -1
- package/build/relations/ManyToOneReference.d.mts +6 -7
- package/build/relations/ManyToOneReference.d.mts.map +1 -1
- package/build/relations/ManyToOneReference.js.map +1 -1
- package/build/relations/OneToManyCollection.cjs.map +1 -1
- package/build/relations/OneToManyCollection.d.cts +2 -3
- package/build/relations/OneToManyCollection.d.cts.map +1 -1
- package/build/relations/OneToManyCollection.d.mts +2 -3
- package/build/relations/OneToManyCollection.d.mts.map +1 -1
- package/build/relations/OneToManyCollection.js.map +1 -1
- package/build/relations/OneToManyLargeCollection.cjs.map +1 -1
- package/build/relations/OneToManyLargeCollection.d.cts +2 -3
- package/build/relations/OneToManyLargeCollection.d.cts.map +1 -1
- package/build/relations/OneToManyLargeCollection.d.mts +2 -3
- package/build/relations/OneToManyLargeCollection.d.mts.map +1 -1
- package/build/relations/OneToManyLargeCollection.js.map +1 -1
- package/build/relations/OneToOneReference.cjs.map +1 -1
- package/build/relations/OneToOneReference.d.cts +7 -7
- package/build/relations/OneToOneReference.d.cts.map +1 -1
- package/build/relations/OneToOneReference.d.mts +7 -7
- package/build/relations/OneToOneReference.d.mts.map +1 -1
- package/build/relations/OneToOneReference.js.map +1 -1
- package/build/relations/PolymorphicReference.cjs.map +1 -1
- package/build/relations/PolymorphicReference.d.cts +4 -5
- package/build/relations/PolymorphicReference.d.cts.map +1 -1
- package/build/relations/PolymorphicReference.d.mts +4 -5
- package/build/relations/PolymorphicReference.d.mts.map +1 -1
- package/build/relations/PolymorphicReference.js.map +1 -1
- package/build/relations/PropertySymbols.d.cts +1 -2
- package/build/relations/PropertySymbols.d.cts.map +1 -1
- package/build/relations/PropertySymbols.d.mts +1 -2
- package/build/relations/PropertySymbols.d.mts.map +1 -1
- package/build/relations/ReactiveField.cjs.map +1 -1
- package/build/relations/ReactiveField.d.cts +4 -5
- package/build/relations/ReactiveField.d.cts.map +1 -1
- package/build/relations/ReactiveField.d.mts +4 -5
- package/build/relations/ReactiveField.d.mts.map +1 -1
- package/build/relations/ReactiveField.js.map +1 -1
- package/build/relations/ReactiveGetter.cjs.map +1 -1
- package/build/relations/ReactiveGetter.d.cts +4 -5
- package/build/relations/ReactiveGetter.d.cts.map +1 -1
- package/build/relations/ReactiveGetter.d.mts +4 -5
- package/build/relations/ReactiveGetter.d.mts.map +1 -1
- package/build/relations/ReactiveGetter.js.map +1 -1
- package/build/relations/ReactiveManyToMany.cjs.map +1 -1
- package/build/relations/ReactiveManyToMany.d.cts +4 -5
- package/build/relations/ReactiveManyToMany.d.cts.map +1 -1
- package/build/relations/ReactiveManyToMany.d.mts +4 -5
- package/build/relations/ReactiveManyToMany.d.mts.map +1 -1
- package/build/relations/ReactiveManyToMany.js.map +1 -1
- package/build/relations/ReactiveManyToManyOtherSide.cjs.map +1 -1
- package/build/relations/ReactiveManyToManyOtherSide.d.cts +4 -5
- package/build/relations/ReactiveManyToManyOtherSide.d.cts.map +1 -1
- package/build/relations/ReactiveManyToManyOtherSide.d.mts +4 -5
- package/build/relations/ReactiveManyToManyOtherSide.d.mts.map +1 -1
- package/build/relations/ReactiveManyToManyOtherSide.js.map +1 -1
- package/build/relations/ReactiveReference.cjs.map +1 -1
- package/build/relations/ReactiveReference.d.cts +5 -6
- package/build/relations/ReactiveReference.d.cts.map +1 -1
- package/build/relations/ReactiveReference.d.mts +5 -6
- package/build/relations/ReactiveReference.d.mts.map +1 -1
- package/build/relations/ReactiveReference.js.map +1 -1
- package/build/relations/ReadOnlyCollection.d.cts +4 -5
- package/build/relations/ReadOnlyCollection.d.cts.map +1 -1
- package/build/relations/ReadOnlyCollection.d.mts +4 -5
- package/build/relations/ReadOnlyCollection.d.mts.map +1 -1
- package/build/relations/RecursiveCollection.cjs.map +1 -1
- package/build/relations/RecursiveCollection.d.cts +10 -10
- package/build/relations/RecursiveCollection.d.cts.map +1 -1
- package/build/relations/RecursiveCollection.d.mts +10 -10
- package/build/relations/RecursiveCollection.d.mts.map +1 -1
- package/build/relations/RecursiveCollection.js.map +1 -1
- package/build/relations/RecursiveCycleError.d.cts +2 -2
- package/build/relations/RecursiveCycleError.d.cts.map +1 -1
- package/build/relations/RecursiveCycleError.d.mts +2 -2
- package/build/relations/RecursiveCycleError.d.mts.map +1 -1
- package/build/relations/Reference.d.cts +5 -5
- package/build/relations/Reference.d.cts.map +1 -1
- package/build/relations/Reference.d.mts +5 -5
- package/build/relations/Reference.d.mts.map +1 -1
- package/build/relations/ReferenceSymbols.d.cts +1 -2
- package/build/relations/ReferenceSymbols.d.cts.map +1 -1
- package/build/relations/ReferenceSymbols.d.mts +1 -2
- package/build/relations/ReferenceSymbols.d.mts.map +1 -1
- package/build/relations/Relation.d.cts +3 -3
- package/build/relations/Relation.d.cts.map +1 -1
- package/build/relations/Relation.d.mts +3 -3
- package/build/relations/Relation.d.mts.map +1 -1
- package/build/relations/RelationSymbols.d.cts +2 -3
- package/build/relations/RelationSymbols.d.cts.map +1 -1
- package/build/relations/RelationSymbols.d.mts +2 -3
- package/build/relations/RelationSymbols.d.mts.map +1 -1
- package/build/relations/hasAsyncMethod.cjs.map +1 -1
- package/build/relations/hasAsyncMethod.d.cts +6 -6
- package/build/relations/hasAsyncMethod.d.cts.map +1 -1
- package/build/relations/hasAsyncMethod.d.mts +6 -6
- package/build/relations/hasAsyncMethod.d.mts.map +1 -1
- package/build/relations/hasAsyncMethod.js.map +1 -1
- package/build/relations/hasManyDerived.d.cts +2 -2
- package/build/relations/hasManyDerived.d.cts.map +1 -1
- package/build/relations/hasManyDerived.d.mts +2 -2
- package/build/relations/hasManyDerived.d.mts.map +1 -1
- package/build/relations/hasManyThrough.d.cts +1 -2
- package/build/relations/hasManyThrough.d.cts.map +1 -1
- package/build/relations/hasManyThrough.d.mts +1 -2
- package/build/relations/hasManyThrough.d.mts.map +1 -1
- package/build/relations/hasOneDerived.d.cts +1 -2
- package/build/relations/hasOneDerived.d.cts.map +1 -1
- package/build/relations/hasOneDerived.d.mts +1 -2
- package/build/relations/hasOneDerived.d.mts.map +1 -1
- package/build/relations/hasOneThrough.d.cts +1 -2
- package/build/relations/hasOneThrough.d.cts.map +1 -1
- package/build/relations/hasOneThrough.d.mts +1 -2
- package/build/relations/hasOneThrough.d.mts.map +1 -1
- package/build/relations/hasProperty.cjs.map +1 -1
- package/build/relations/hasProperty.d.cts +8 -8
- package/build/relations/hasProperty.d.cts.map +1 -1
- package/build/relations/hasProperty.d.mts +8 -8
- package/build/relations/hasProperty.d.mts.map +1 -1
- package/build/relations/hasProperty.js.map +1 -1
- package/build/relations/isCascadeDelete.d.cts +1 -2
- package/build/relations/isCascadeDelete.d.cts.map +1 -1
- package/build/relations/isCascadeDelete.d.mts +1 -2
- package/build/relations/isCascadeDelete.d.mts.map +1 -1
- package/build/resurrection.d.cts +3 -4
- package/build/resurrection.d.cts.map +1 -1
- package/build/resurrection.d.mts +3 -4
- package/build/resurrection.d.mts.map +1 -1
- package/build/rules.d.cts +20 -20
- package/build/rules.d.cts.map +1 -1
- package/build/rules.d.mts +20 -20
- package/build/rules.d.mts.map +1 -1
- package/build/runtimeConfig.d.cts +4 -5
- package/build/runtimeConfig.d.cts.map +1 -1
- package/build/runtimeConfig.d.mts +4 -5
- package/build/runtimeConfig.d.mts.map +1 -1
- package/build/serde/TypeInfo.d.cts +3 -4
- package/build/serde/TypeInfo.d.cts.map +1 -1
- package/build/serde/TypeInfo.d.mts +3 -4
- package/build/serde/TypeInfo.d.mts.map +1 -1
- package/build/serde/columns.d.cts +2 -3
- package/build/serde/columns.d.cts.map +1 -1
- package/build/serde/columns.d.mts +2 -3
- package/build/serde/columns.d.mts.map +1 -1
- package/build/serde/fieldSerde.d.cts +9 -9
- package/build/serde/fieldSerde.d.cts.map +1 -1
- package/build/serde/fieldSerde.d.mts +9 -9
- package/build/serde/fieldSerde.d.mts.map +1 -1
- package/build/serde/serde.d.cts +18 -19
- package/build/serde/serde.d.cts.map +1 -1
- package/build/serde/serde.d.mts +18 -19
- package/build/serde/serde.d.mts.map +1 -1
- package/build/serde/temporal.d.cts +5 -5
- package/build/serde/temporal.d.cts.map +1 -1
- package/build/serde/temporal.d.mts +5 -5
- package/build/serde/temporal.d.mts.map +1 -1
- package/build/serde/temporalMappers.d.cts +4 -5
- package/build/serde/temporalMappers.d.cts.map +1 -1
- package/build/serde/temporalMappers.d.mts +4 -5
- package/build/serde/temporalMappers.d.mts.map +1 -1
- package/build/transitions.d.cts +17 -18
- package/build/transitions.d.cts.map +1 -1
- package/build/transitions.d.mts +17 -18
- package/build/transitions.d.mts.map +1 -1
- package/build/trusted.d.cts +2 -3
- package/build/trusted.d.cts.map +1 -1
- package/build/trusted.d.mts +2 -3
- package/build/trusted.d.mts.map +1 -1
- package/build/typeMap.d.cts +17 -17
- package/build/typeMap.d.cts.map +1 -1
- package/build/typeMap.d.mts +17 -17
- package/build/typeMap.d.mts.map +1 -1
- package/build/upsert.d.cts +4 -4
- package/build/upsert.d.cts.map +1 -1
- package/build/upsert.d.mts +4 -4
- package/build/upsert.d.mts.map +1 -1
- package/build/utils.d.cts +27 -28
- package/build/utils.d.cts.map +1 -1
- package/build/utils.d.mts +27 -28
- package/build/utils.d.mts.map +1 -1
- package/package.json +4 -4
|
@@ -7,11 +7,11 @@ import { FieldSerde, PolymorphicKeySerde } from "./serde/fieldSerde.cjs";
|
|
|
7
7
|
import { EntityManager, MaybeAbstractEntityConstructor, TimestampFields } from "./EntityManager.cjs";
|
|
8
8
|
import { Entity } from "./Entity.cjs";
|
|
9
9
|
//#region src/EntityMetadata.d.ts
|
|
10
|
-
declare function getMetadata<T extends Entity>(entity: T): EntityMetadata<T>;
|
|
11
|
-
declare function getMetadata<T extends Entity>(type: MaybeAbstractEntityConstructor<T>): EntityMetadata<T>;
|
|
12
|
-
declare function getMetadata<T extends Entity>(meta: EntityMetadata): EntityMetadata;
|
|
10
|
+
export declare function getMetadata<T extends Entity>(entity: T): EntityMetadata<T>;
|
|
11
|
+
export declare function getMetadata<T extends Entity>(type: MaybeAbstractEntityConstructor<T>): EntityMetadata<T>;
|
|
12
|
+
export declare function getMetadata<T extends Entity>(meta: EntityMetadata): EntityMetadata;
|
|
13
13
|
/** Returns the metadata layer that declares `fieldName`, i.e. `Task.tags` for `TaskOld.tags`. */
|
|
14
|
-
declare function getMetadataForField(meta: EntityMetadata, fieldName: string): EntityMetadata;
|
|
14
|
+
export declare function getMetadataForField(meta: EntityMetadata, fieldName: string): EntityMetadata;
|
|
15
15
|
/**
|
|
16
16
|
* Runtime metadata about an entity.
|
|
17
17
|
*
|
|
@@ -22,7 +22,7 @@ declare function getMetadataForField(meta: EntityMetadata, fieldName: string): E
|
|
|
22
22
|
* an unknown string/id type, causes issues when we want to generically mix `EntityMetadata`
|
|
23
23
|
* of different types, that even liberally using `EntityMetadata<any>` did not avoid.
|
|
24
24
|
*/
|
|
25
|
-
interface EntityMetadata<T extends Entity = any> {
|
|
25
|
+
export interface EntityMetadata<T extends Entity = any> {
|
|
26
26
|
cstr: MaybeAbstractEntityConstructor<T>;
|
|
27
27
|
type: string;
|
|
28
28
|
/** How the domain entity's id is represented. */
|
|
@@ -98,9 +98,9 @@ interface EntityMetadata<T extends Entity = any> {
|
|
|
98
98
|
/** If the schema is lacking deferred FKs, this is our insertion order. */
|
|
99
99
|
nonDeferredFkOrder?: number;
|
|
100
100
|
}
|
|
101
|
-
type Field = PrimaryKeyField | PrimitiveField | EnumField | OneToManyField | LargeOneToManyField | ManyToOneField | ManyToManyField | ManyToManyEnumField | OneToOneField | PolymorphicField;
|
|
102
|
-
type SerdeField = PrimaryKeyField | PrimitiveField | EnumField | ManyToOneField | PolymorphicField;
|
|
103
|
-
type PrimaryKeyField = {
|
|
101
|
+
export type Field = PrimaryKeyField | PrimitiveField | EnumField | OneToManyField | LargeOneToManyField | ManyToOneField | ManyToManyField | ManyToManyEnumField | OneToOneField | PolymorphicField;
|
|
102
|
+
export type SerdeField = PrimaryKeyField | PrimitiveField | EnumField | ManyToOneField | PolymorphicField;
|
|
103
|
+
export type PrimaryKeyField = {
|
|
104
104
|
kind: "primaryKey";
|
|
105
105
|
fieldName: string;
|
|
106
106
|
fieldIdName: undefined;
|
|
@@ -108,7 +108,7 @@ type PrimaryKeyField = {
|
|
|
108
108
|
serde: FieldSerde;
|
|
109
109
|
immutable: true;
|
|
110
110
|
};
|
|
111
|
-
type PrimitiveField = {
|
|
111
|
+
export type PrimitiveField = {
|
|
112
112
|
kind: "primitive";
|
|
113
113
|
fieldName: string;
|
|
114
114
|
fieldIdName: undefined;
|
|
@@ -124,7 +124,7 @@ type PrimitiveField = {
|
|
|
124
124
|
/** When true, this column is excluded from the entity's default SELECT and lazy-loaded via a `LazyField`. */
|
|
125
125
|
lazy?: boolean;
|
|
126
126
|
};
|
|
127
|
-
type EnumField = {
|
|
127
|
+
export type EnumField = {
|
|
128
128
|
kind: "enum";
|
|
129
129
|
fieldName: string;
|
|
130
130
|
fieldIdName: undefined;
|
|
@@ -139,7 +139,7 @@ type EnumField = {
|
|
|
139
139
|
immutable: boolean;
|
|
140
140
|
default?: "schema" | "config";
|
|
141
141
|
};
|
|
142
|
-
type OneToManyField = {
|
|
142
|
+
export type OneToManyField = {
|
|
143
143
|
kind: "o2m";
|
|
144
144
|
fieldName: string;
|
|
145
145
|
fieldIdName: string;
|
|
@@ -157,7 +157,7 @@ type OneToManyField = {
|
|
|
157
157
|
/** When `"include"`, this collection's `.get`/`.load` returns soft-deleted entities instead of hiding them. */
|
|
158
158
|
softDeletes?: "include" | "exclude";
|
|
159
159
|
};
|
|
160
|
-
type LargeOneToManyField = {
|
|
160
|
+
export type LargeOneToManyField = {
|
|
161
161
|
kind: "lo2m";
|
|
162
162
|
fieldName: string;
|
|
163
163
|
fieldIdName: string;
|
|
@@ -169,7 +169,7 @@ type LargeOneToManyField = {
|
|
|
169
169
|
serde: undefined;
|
|
170
170
|
immutable: false;
|
|
171
171
|
};
|
|
172
|
-
type ManyToOneField = {
|
|
172
|
+
export type ManyToOneField = {
|
|
173
173
|
kind: "m2o";
|
|
174
174
|
fieldName: string;
|
|
175
175
|
fieldIdName: string;
|
|
@@ -181,7 +181,7 @@ type ManyToOneField = {
|
|
|
181
181
|
derived: "async" | false;
|
|
182
182
|
default?: "schema" | "config";
|
|
183
183
|
};
|
|
184
|
-
type ManyToManyField = {
|
|
184
|
+
export type ManyToManyField = {
|
|
185
185
|
kind: "m2m";
|
|
186
186
|
fieldName: string;
|
|
187
187
|
fieldIdName: string;
|
|
@@ -205,7 +205,7 @@ type ManyToManyField = {
|
|
|
205
205
|
* To the user this looks like an array of enum codes (`Color[]`), but unlike an enum-array column it
|
|
206
206
|
* is lazy (needs a load hint) because it lives in its own join table.
|
|
207
207
|
*/
|
|
208
|
-
type ManyToManyEnumField = {
|
|
208
|
+
export type ManyToManyEnumField = {
|
|
209
209
|
kind: "m2mEnum";
|
|
210
210
|
fieldName: string;
|
|
211
211
|
fieldIdName: undefined;
|
|
@@ -221,7 +221,7 @@ type ManyToManyEnumField = {
|
|
|
221
221
|
/** Whether the join table has a surrogate `id` PK; if false the FK pair is the composite PK. */
|
|
222
222
|
hasJoinTableId: boolean;
|
|
223
223
|
};
|
|
224
|
-
type OneToOneField = {
|
|
224
|
+
export type OneToOneField = {
|
|
225
225
|
kind: "o2o";
|
|
226
226
|
fieldName: string;
|
|
227
227
|
fieldIdName: string;
|
|
@@ -233,7 +233,7 @@ type OneToOneField = {
|
|
|
233
233
|
serde: undefined;
|
|
234
234
|
immutable: false;
|
|
235
235
|
};
|
|
236
|
-
type PolymorphicField = {
|
|
236
|
+
export type PolymorphicField = {
|
|
237
237
|
kind: "poly";
|
|
238
238
|
fieldName: string;
|
|
239
239
|
fieldIdName: string;
|
|
@@ -242,25 +242,24 @@ type PolymorphicField = {
|
|
|
242
242
|
serde: PolymorphicKeySerde;
|
|
243
243
|
immutable: boolean;
|
|
244
244
|
};
|
|
245
|
-
type PolymorphicFieldComponent = {
|
|
245
|
+
export type PolymorphicFieldComponent = {
|
|
246
246
|
otherMetadata: () => EntityMetadata;
|
|
247
247
|
otherFieldName: string;
|
|
248
248
|
columnName: string;
|
|
249
249
|
column: Column;
|
|
250
250
|
};
|
|
251
|
-
declare function isOneToManyField(ormField: Field): ormField is OneToManyField;
|
|
252
|
-
declare function isManyToOneField(ormField: Field): ormField is ManyToOneField;
|
|
253
|
-
declare function isManyToManyField(ormField: Field): ormField is ManyToManyField;
|
|
254
|
-
declare function isManyToManyEnumField(ormField: Field): ormField is ManyToManyEnumField;
|
|
255
|
-
declare function isOneToOneField(ormField: Field): ormField is OneToOneField;
|
|
256
|
-
declare function isPolymorphicField(ormField: Field): ormField is PolymorphicField;
|
|
257
|
-
declare function isReferenceField(ormField: Field): ormField is ManyToOneField | OneToOneField | PolymorphicField;
|
|
258
|
-
declare function isCollectionField(ormField: Field): ormField is OneToManyField | ManyToManyField;
|
|
259
|
-
declare function getBaseAndSelfMetas(meta: EntityMetadata): EntityMetadata[];
|
|
260
|
-
declare function getBaseAndSelfMetas(entity: Entity): EntityMetadata[];
|
|
261
|
-
declare function getBaseSelfAndSubMetas(meta: EntityMetadata): EntityMetadata[];
|
|
262
|
-
declare function getSubMetas(meta: EntityMetadata): EntityMetadata[];
|
|
263
|
-
declare function getBaseMeta(meta: EntityMetadata): EntityMetadata;
|
|
251
|
+
export declare function isOneToManyField(ormField: Field): ormField is OneToManyField;
|
|
252
|
+
export declare function isManyToOneField(ormField: Field): ormField is ManyToOneField;
|
|
253
|
+
export declare function isManyToManyField(ormField: Field): ormField is ManyToManyField;
|
|
254
|
+
export declare function isManyToManyEnumField(ormField: Field): ormField is ManyToManyEnumField;
|
|
255
|
+
export declare function isOneToOneField(ormField: Field): ormField is OneToOneField;
|
|
256
|
+
export declare function isPolymorphicField(ormField: Field): ormField is PolymorphicField;
|
|
257
|
+
export declare function isReferenceField(ormField: Field): ormField is ManyToOneField | OneToOneField | PolymorphicField;
|
|
258
|
+
export declare function isCollectionField(ormField: Field): ormField is OneToManyField | ManyToManyField;
|
|
259
|
+
export declare function getBaseAndSelfMetas(meta: EntityMetadata): EntityMetadata[];
|
|
260
|
+
export declare function getBaseAndSelfMetas(entity: Entity): EntityMetadata[];
|
|
261
|
+
export declare function getBaseSelfAndSubMetas(meta: EntityMetadata): EntityMetadata[];
|
|
262
|
+
export declare function getSubMetas(meta: EntityMetadata): EntityMetadata[];
|
|
263
|
+
export declare function getBaseMeta(meta: EntityMetadata): EntityMetadata;
|
|
264
264
|
//#endregion
|
|
265
|
-
export { EntityMetadata, EnumField, Field, LargeOneToManyField, ManyToManyEnumField, ManyToManyField, ManyToOneField, OneToManyField, OneToOneField, PolymorphicField, PolymorphicFieldComponent, PrimaryKeyField, PrimitiveField, SerdeField, getBaseAndSelfMetas, getBaseMeta, getBaseSelfAndSubMetas, getMetadata, getMetadataForField, getSubMetas, isCollectionField, isManyToManyEnumField, isManyToManyField, isManyToOneField, isOneToManyField, isOneToOneField, isPolymorphicField, isReferenceField };
|
|
266
265
|
//# sourceMappingURL=EntityMetadata.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityMetadata.d.cts","names":[],"sources":["../src/EntityMetadata.ts"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"EntityMetadata.d.cts","names":[],"sources":["../src/EntityMetadata.ts"],"mappings":";;;;;;;;;wBAWgB,YAAY,UAAU,QAAQ,QAAQ,IAAI,eAAe;wBACzD,YAAY,UAAU,QAAQ,MAAM,+BAA+B,KAAK,eAAe;wBACvF,YAAY,UAAU,QAAQ,MAAM,iBAAiB;;wBAWrD,oBAAoB,MAAM,gBAAgB,oBAAoB;;;;;;;;;;;iBAoB7D,eAAe,UAAU;EACxC,MAAM,+BAA+B;EACrC;;EAEA;;EAEA;EACA;;EAEA;;EAEA;EACA;;EAEA;;EAEA;;EAEA;EACA;EACA,QAAQ,eAAe;;EAEvB,SAAS;EACT,WAAW,eAAe;IAAU;IAAqB;;;EAEzD,sBAAsB,eAAe;IAAU;;EAE/C,QAAQ;;EAER,cAAc,oBAAoB;;EAElC,aAAa;;EAEb,oBAAoB,oBAAoB;;EAExC,8BAA8B;;EAE9B,qCAAqC,oBAAoB;;EAEzD,gBAAgB;;EAEhB,sBAAsB;;EAEtB;;EAEA,iBAAiB;;EAEjB;;EAEA;EACA;;EAEA;EACA,iBAAiB;EAEjB,UAAU,IAAI,8BAA8B,eAAe,QAAQ;;EAEnE,WAAW;;EAEX,UAAU;;EAEV,gBAAgB;;EAEhB,sBAAsB;;EAEtB,iBAAiB,oBAAoB;;EAErC,qBAAqB,qBAAqB;;EAE1C;;EAEA;;YAGU,QACR,kBACA,iBACA,YACA,iBACA,sBACA,iBACA,kBACA,sBACA,gBACA;YAGQ,aAAa,kBAAkB,iBAAiB,YAAY,iBAAiB;YAE7E;EACV;EACA;EACA;EACA;EACA,OAAO;EACP;;YAGU;EACV;EACA;EACA;EACA;EACA;EACA;EACA,eAAe;EACf,OAAO;EACP;EACA;EACA;EACA;;EAEA;;YAGU;EACV;EACA;EACA;EACA;EACA;EACA,gBAAgB;IAAoB;;;EAEpC,UAAU;EACV,OAAO;EACP;EACA;;YAGU;EACV;EACA;EACA;EACA;EACA,qBAAqB;EACrB;;EAEA;EACA;EACA;EACA;IAAY;IAAe;;;EAE3B;;YAGU;EACV;EACA;EACA;EACA;EACA,qBAAqB;EACrB;;EAEA;EACA;EACA;;YAGU;EACV;EACA;EACA;EACA;EACA,qBAAqB;EACrB;EACA,OAAO;EACP;EACA;EACA;;YAGU;EACV;EACA;EACA;EACA;EACA;EACA,qBAAqB;EACrB;EACA;EACA;EACA;EACA;;EAEA;;EAEA;;;;;;;;;YAUU;EACV;EACA;EACA;EACA;EACA;;EAEA,gBAAgB;EAChB;EACA;EACA;;EAEA;;EAEA;;YAGU;EACV;EACA;EACA;EACA;EACA,qBAAqB;EACrB;;EAEA;EACA;EACA;;YAGU;EACV;EACA;EACA;EACA;EACA,YAAY;EACZ,OAAO;EACP;;YAGU;EACV,qBAAqB;EACrB;EACA;EACA,QAAQ;;wBAGM,iBAAiB,UAAU,QAAQ,YAAY;wBAI/C,iBAAiB,UAAU,QAAQ,YAAY;wBAI/C,kBAAkB,UAAU,QAAQ,YAAY;wBAIhD,sBAAsB,UAAU,QAAQ,YAAY;wBAIpD,gBAAgB,UAAU,QAAQ,YAAY;wBAI9C,mBAAmB,UAAU,QAAQ,YAAY;wBAIjD,iBAAiB,UAAU,QAAQ,YAAY,iBAAiB,gBAAgB;wBAIhF,kBAAkB,UAAU,QAAQ,YAAY,iBAAiB;wBAIjE,oBAAoB,MAAM,iBAAiB;wBAC3C,oBAAoB,QAAQ,SAAS;wBAOrC,uBAAuB,MAAM,iBAAiB;wBAI9C,YAAY,MAAM,iBAAiB;wBAKnC,YAAY,MAAM,iBAAiB"}
|
|
@@ -7,11 +7,11 @@ import { FieldSerde, PolymorphicKeySerde } from "./serde/fieldSerde.mjs";
|
|
|
7
7
|
import { EntityManager, MaybeAbstractEntityConstructor, TimestampFields } from "./EntityManager.mjs";
|
|
8
8
|
import { Entity } from "./Entity.mjs";
|
|
9
9
|
//#region src/EntityMetadata.d.ts
|
|
10
|
-
declare function getMetadata<T extends Entity>(entity: T): EntityMetadata<T>;
|
|
11
|
-
declare function getMetadata<T extends Entity>(type: MaybeAbstractEntityConstructor<T>): EntityMetadata<T>;
|
|
12
|
-
declare function getMetadata<T extends Entity>(meta: EntityMetadata): EntityMetadata;
|
|
10
|
+
export declare function getMetadata<T extends Entity>(entity: T): EntityMetadata<T>;
|
|
11
|
+
export declare function getMetadata<T extends Entity>(type: MaybeAbstractEntityConstructor<T>): EntityMetadata<T>;
|
|
12
|
+
export declare function getMetadata<T extends Entity>(meta: EntityMetadata): EntityMetadata;
|
|
13
13
|
/** Returns the metadata layer that declares `fieldName`, i.e. `Task.tags` for `TaskOld.tags`. */
|
|
14
|
-
declare function getMetadataForField(meta: EntityMetadata, fieldName: string): EntityMetadata;
|
|
14
|
+
export declare function getMetadataForField(meta: EntityMetadata, fieldName: string): EntityMetadata;
|
|
15
15
|
/**
|
|
16
16
|
* Runtime metadata about an entity.
|
|
17
17
|
*
|
|
@@ -22,7 +22,7 @@ declare function getMetadataForField(meta: EntityMetadata, fieldName: string): E
|
|
|
22
22
|
* an unknown string/id type, causes issues when we want to generically mix `EntityMetadata`
|
|
23
23
|
* of different types, that even liberally using `EntityMetadata<any>` did not avoid.
|
|
24
24
|
*/
|
|
25
|
-
interface EntityMetadata<T extends Entity = any> {
|
|
25
|
+
export interface EntityMetadata<T extends Entity = any> {
|
|
26
26
|
cstr: MaybeAbstractEntityConstructor<T>;
|
|
27
27
|
type: string;
|
|
28
28
|
/** How the domain entity's id is represented. */
|
|
@@ -98,9 +98,9 @@ interface EntityMetadata<T extends Entity = any> {
|
|
|
98
98
|
/** If the schema is lacking deferred FKs, this is our insertion order. */
|
|
99
99
|
nonDeferredFkOrder?: number;
|
|
100
100
|
}
|
|
101
|
-
type Field = PrimaryKeyField | PrimitiveField | EnumField | OneToManyField | LargeOneToManyField | ManyToOneField | ManyToManyField | ManyToManyEnumField | OneToOneField | PolymorphicField;
|
|
102
|
-
type SerdeField = PrimaryKeyField | PrimitiveField | EnumField | ManyToOneField | PolymorphicField;
|
|
103
|
-
type PrimaryKeyField = {
|
|
101
|
+
export type Field = PrimaryKeyField | PrimitiveField | EnumField | OneToManyField | LargeOneToManyField | ManyToOneField | ManyToManyField | ManyToManyEnumField | OneToOneField | PolymorphicField;
|
|
102
|
+
export type SerdeField = PrimaryKeyField | PrimitiveField | EnumField | ManyToOneField | PolymorphicField;
|
|
103
|
+
export type PrimaryKeyField = {
|
|
104
104
|
kind: "primaryKey";
|
|
105
105
|
fieldName: string;
|
|
106
106
|
fieldIdName: undefined;
|
|
@@ -108,7 +108,7 @@ type PrimaryKeyField = {
|
|
|
108
108
|
serde: FieldSerde;
|
|
109
109
|
immutable: true;
|
|
110
110
|
};
|
|
111
|
-
type PrimitiveField = {
|
|
111
|
+
export type PrimitiveField = {
|
|
112
112
|
kind: "primitive";
|
|
113
113
|
fieldName: string;
|
|
114
114
|
fieldIdName: undefined;
|
|
@@ -124,7 +124,7 @@ type PrimitiveField = {
|
|
|
124
124
|
/** When true, this column is excluded from the entity's default SELECT and lazy-loaded via a `LazyField`. */
|
|
125
125
|
lazy?: boolean;
|
|
126
126
|
};
|
|
127
|
-
type EnumField = {
|
|
127
|
+
export type EnumField = {
|
|
128
128
|
kind: "enum";
|
|
129
129
|
fieldName: string;
|
|
130
130
|
fieldIdName: undefined;
|
|
@@ -139,7 +139,7 @@ type EnumField = {
|
|
|
139
139
|
immutable: boolean;
|
|
140
140
|
default?: "schema" | "config";
|
|
141
141
|
};
|
|
142
|
-
type OneToManyField = {
|
|
142
|
+
export type OneToManyField = {
|
|
143
143
|
kind: "o2m";
|
|
144
144
|
fieldName: string;
|
|
145
145
|
fieldIdName: string;
|
|
@@ -157,7 +157,7 @@ type OneToManyField = {
|
|
|
157
157
|
/** When `"include"`, this collection's `.get`/`.load` returns soft-deleted entities instead of hiding them. */
|
|
158
158
|
softDeletes?: "include" | "exclude";
|
|
159
159
|
};
|
|
160
|
-
type LargeOneToManyField = {
|
|
160
|
+
export type LargeOneToManyField = {
|
|
161
161
|
kind: "lo2m";
|
|
162
162
|
fieldName: string;
|
|
163
163
|
fieldIdName: string;
|
|
@@ -169,7 +169,7 @@ type LargeOneToManyField = {
|
|
|
169
169
|
serde: undefined;
|
|
170
170
|
immutable: false;
|
|
171
171
|
};
|
|
172
|
-
type ManyToOneField = {
|
|
172
|
+
export type ManyToOneField = {
|
|
173
173
|
kind: "m2o";
|
|
174
174
|
fieldName: string;
|
|
175
175
|
fieldIdName: string;
|
|
@@ -181,7 +181,7 @@ type ManyToOneField = {
|
|
|
181
181
|
derived: "async" | false;
|
|
182
182
|
default?: "schema" | "config";
|
|
183
183
|
};
|
|
184
|
-
type ManyToManyField = {
|
|
184
|
+
export type ManyToManyField = {
|
|
185
185
|
kind: "m2m";
|
|
186
186
|
fieldName: string;
|
|
187
187
|
fieldIdName: string;
|
|
@@ -205,7 +205,7 @@ type ManyToManyField = {
|
|
|
205
205
|
* To the user this looks like an array of enum codes (`Color[]`), but unlike an enum-array column it
|
|
206
206
|
* is lazy (needs a load hint) because it lives in its own join table.
|
|
207
207
|
*/
|
|
208
|
-
type ManyToManyEnumField = {
|
|
208
|
+
export type ManyToManyEnumField = {
|
|
209
209
|
kind: "m2mEnum";
|
|
210
210
|
fieldName: string;
|
|
211
211
|
fieldIdName: undefined;
|
|
@@ -221,7 +221,7 @@ type ManyToManyEnumField = {
|
|
|
221
221
|
/** Whether the join table has a surrogate `id` PK; if false the FK pair is the composite PK. */
|
|
222
222
|
hasJoinTableId: boolean;
|
|
223
223
|
};
|
|
224
|
-
type OneToOneField = {
|
|
224
|
+
export type OneToOneField = {
|
|
225
225
|
kind: "o2o";
|
|
226
226
|
fieldName: string;
|
|
227
227
|
fieldIdName: string;
|
|
@@ -233,7 +233,7 @@ type OneToOneField = {
|
|
|
233
233
|
serde: undefined;
|
|
234
234
|
immutable: false;
|
|
235
235
|
};
|
|
236
|
-
type PolymorphicField = {
|
|
236
|
+
export type PolymorphicField = {
|
|
237
237
|
kind: "poly";
|
|
238
238
|
fieldName: string;
|
|
239
239
|
fieldIdName: string;
|
|
@@ -242,25 +242,24 @@ type PolymorphicField = {
|
|
|
242
242
|
serde: PolymorphicKeySerde;
|
|
243
243
|
immutable: boolean;
|
|
244
244
|
};
|
|
245
|
-
type PolymorphicFieldComponent = {
|
|
245
|
+
export type PolymorphicFieldComponent = {
|
|
246
246
|
otherMetadata: () => EntityMetadata;
|
|
247
247
|
otherFieldName: string;
|
|
248
248
|
columnName: string;
|
|
249
249
|
column: Column;
|
|
250
250
|
};
|
|
251
|
-
declare function isOneToManyField(ormField: Field): ormField is OneToManyField;
|
|
252
|
-
declare function isManyToOneField(ormField: Field): ormField is ManyToOneField;
|
|
253
|
-
declare function isManyToManyField(ormField: Field): ormField is ManyToManyField;
|
|
254
|
-
declare function isManyToManyEnumField(ormField: Field): ormField is ManyToManyEnumField;
|
|
255
|
-
declare function isOneToOneField(ormField: Field): ormField is OneToOneField;
|
|
256
|
-
declare function isPolymorphicField(ormField: Field): ormField is PolymorphicField;
|
|
257
|
-
declare function isReferenceField(ormField: Field): ormField is ManyToOneField | OneToOneField | PolymorphicField;
|
|
258
|
-
declare function isCollectionField(ormField: Field): ormField is OneToManyField | ManyToManyField;
|
|
259
|
-
declare function getBaseAndSelfMetas(meta: EntityMetadata): EntityMetadata[];
|
|
260
|
-
declare function getBaseAndSelfMetas(entity: Entity): EntityMetadata[];
|
|
261
|
-
declare function getBaseSelfAndSubMetas(meta: EntityMetadata): EntityMetadata[];
|
|
262
|
-
declare function getSubMetas(meta: EntityMetadata): EntityMetadata[];
|
|
263
|
-
declare function getBaseMeta(meta: EntityMetadata): EntityMetadata;
|
|
251
|
+
export declare function isOneToManyField(ormField: Field): ormField is OneToManyField;
|
|
252
|
+
export declare function isManyToOneField(ormField: Field): ormField is ManyToOneField;
|
|
253
|
+
export declare function isManyToManyField(ormField: Field): ormField is ManyToManyField;
|
|
254
|
+
export declare function isManyToManyEnumField(ormField: Field): ormField is ManyToManyEnumField;
|
|
255
|
+
export declare function isOneToOneField(ormField: Field): ormField is OneToOneField;
|
|
256
|
+
export declare function isPolymorphicField(ormField: Field): ormField is PolymorphicField;
|
|
257
|
+
export declare function isReferenceField(ormField: Field): ormField is ManyToOneField | OneToOneField | PolymorphicField;
|
|
258
|
+
export declare function isCollectionField(ormField: Field): ormField is OneToManyField | ManyToManyField;
|
|
259
|
+
export declare function getBaseAndSelfMetas(meta: EntityMetadata): EntityMetadata[];
|
|
260
|
+
export declare function getBaseAndSelfMetas(entity: Entity): EntityMetadata[];
|
|
261
|
+
export declare function getBaseSelfAndSubMetas(meta: EntityMetadata): EntityMetadata[];
|
|
262
|
+
export declare function getSubMetas(meta: EntityMetadata): EntityMetadata[];
|
|
263
|
+
export declare function getBaseMeta(meta: EntityMetadata): EntityMetadata;
|
|
264
264
|
//#endregion
|
|
265
|
-
export { EntityMetadata, EnumField, Field, LargeOneToManyField, ManyToManyEnumField, ManyToManyField, ManyToOneField, OneToManyField, OneToOneField, PolymorphicField, PolymorphicFieldComponent, PrimaryKeyField, PrimitiveField, SerdeField, getBaseAndSelfMetas, getBaseMeta, getBaseSelfAndSubMetas, getMetadata, getMetadataForField, getSubMetas, isCollectionField, isManyToManyEnumField, isManyToManyField, isManyToOneField, isOneToManyField, isOneToOneField, isPolymorphicField, isReferenceField };
|
|
266
265
|
//# sourceMappingURL=EntityMetadata.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityMetadata.d.mts","names":[],"sources":["../src/EntityMetadata.ts"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"EntityMetadata.d.mts","names":[],"sources":["../src/EntityMetadata.ts"],"mappings":";;;;;;;;;wBAWgB,YAAY,UAAU,QAAQ,QAAQ,IAAI,eAAe;wBACzD,YAAY,UAAU,QAAQ,MAAM,+BAA+B,KAAK,eAAe;wBACvF,YAAY,UAAU,QAAQ,MAAM,iBAAiB;;wBAWrD,oBAAoB,MAAM,gBAAgB,oBAAoB;;;;;;;;;;;iBAoB7D,eAAe,UAAU;EACxC,MAAM,+BAA+B;EACrC;;EAEA;;EAEA;EACA;;EAEA;;EAEA;EACA;;EAEA;;EAEA;;EAEA;EACA;EACA,QAAQ,eAAe;;EAEvB,SAAS;EACT,WAAW,eAAe;IAAU;IAAqB;;;EAEzD,sBAAsB,eAAe;IAAU;;EAE/C,QAAQ;;EAER,cAAc,oBAAoB;;EAElC,aAAa;;EAEb,oBAAoB,oBAAoB;;EAExC,8BAA8B;;EAE9B,qCAAqC,oBAAoB;;EAEzD,gBAAgB;;EAEhB,sBAAsB;;EAEtB;;EAEA,iBAAiB;;EAEjB;;EAEA;EACA;;EAEA;EACA,iBAAiB;EAEjB,UAAU,IAAI,8BAA8B,eAAe,QAAQ;;EAEnE,WAAW;;EAEX,UAAU;;EAEV,gBAAgB;;EAEhB,sBAAsB;;EAEtB,iBAAiB,oBAAoB;;EAErC,qBAAqB,qBAAqB;;EAE1C;;EAEA;;YAGU,QACR,kBACA,iBACA,YACA,iBACA,sBACA,iBACA,kBACA,sBACA,gBACA;YAGQ,aAAa,kBAAkB,iBAAiB,YAAY,iBAAiB;YAE7E;EACV;EACA;EACA;EACA;EACA,OAAO;EACP;;YAGU;EACV;EACA;EACA;EACA;EACA;EACA;EACA,eAAe;EACf,OAAO;EACP;EACA;EACA;EACA;;EAEA;;YAGU;EACV;EACA;EACA;EACA;EACA;EACA,gBAAgB;IAAoB;;;EAEpC,UAAU;EACV,OAAO;EACP;EACA;;YAGU;EACV;EACA;EACA;EACA;EACA,qBAAqB;EACrB;;EAEA;EACA;EACA;EACA;IAAY;IAAe;;;EAE3B;;YAGU;EACV;EACA;EACA;EACA;EACA,qBAAqB;EACrB;;EAEA;EACA;EACA;;YAGU;EACV;EACA;EACA;EACA;EACA,qBAAqB;EACrB;EACA,OAAO;EACP;EACA;EACA;;YAGU;EACV;EACA;EACA;EACA;EACA;EACA,qBAAqB;EACrB;EACA;EACA;EACA;EACA;;EAEA;;EAEA;;;;;;;;;YAUU;EACV;EACA;EACA;EACA;EACA;;EAEA,gBAAgB;EAChB;EACA;EACA;;EAEA;;EAEA;;YAGU;EACV;EACA;EACA;EACA;EACA,qBAAqB;EACrB;;EAEA;EACA;EACA;;YAGU;EACV;EACA;EACA;EACA;EACA,YAAY;EACZ,OAAO;EACP;;YAGU;EACV,qBAAqB;EACrB;EACA;EACA,QAAQ;;wBAGM,iBAAiB,UAAU,QAAQ,YAAY;wBAI/C,iBAAiB,UAAU,QAAQ,YAAY;wBAI/C,kBAAkB,UAAU,QAAQ,YAAY;wBAIhD,sBAAsB,UAAU,QAAQ,YAAY;wBAIpD,gBAAgB,UAAU,QAAQ,YAAY;wBAI9C,mBAAmB,UAAU,QAAQ,YAAY;wBAIjD,iBAAiB,UAAU,QAAQ,YAAY,iBAAiB,gBAAgB;wBAIhF,kBAAkB,UAAU,QAAQ,YAAY,iBAAiB;wBAIjE,oBAAoB,MAAM,iBAAiB;wBAC3C,oBAAoB,QAAQ,SAAS;wBAOrC,uBAAuB,MAAM,iBAAiB;wBAI9C,YAAY,MAAM,iBAAiB;wBAKnC,YAAY,MAAM,iBAAiB"}
|
package/build/EnumMetadata.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/EnumMetadata.d.ts
|
|
2
|
-
interface EnumMetadata<C, D, I extends number | string = number | string> {
|
|
2
|
+
export interface EnumMetadata<C, D, I extends number | string = number | string> {
|
|
3
3
|
/** Returns the enum type's name, i.e. `AuthorStatus`. */
|
|
4
4
|
name: string;
|
|
5
5
|
/** Gets the `code` details, i.e. `Statuses.getByCode(Status.DRAFT)`. */
|
|
@@ -14,5 +14,4 @@ interface EnumMetadata<C, D, I extends number | string = number | string> {
|
|
|
14
14
|
getDetails(): ReadonlyArray<D>;
|
|
15
15
|
}
|
|
16
16
|
//#endregion
|
|
17
|
-
export { EnumMetadata };
|
|
18
17
|
//# sourceMappingURL=EnumMetadata.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnumMetadata.d.cts","names":[],"sources":["../src/EnumMetadata.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"EnumMetadata.d.cts","names":[],"sources":["../src/EnumMetadata.ts"],"mappings":";iBAAiB,aAAa,GAAG,GAAG;;EAElC;;EAGA,UAAU,MAAM,IAAI;;EAGpB,WAAW,eAAe;;EAG1B,SAAS,IAAI,IAAI;;EAGjB,aAAa,cAAc;;EAG3B,cAAc,cAAc"}
|
package/build/EnumMetadata.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/EnumMetadata.d.ts
|
|
2
|
-
interface EnumMetadata<C, D, I extends number | string = number | string> {
|
|
2
|
+
export interface EnumMetadata<C, D, I extends number | string = number | string> {
|
|
3
3
|
/** Returns the enum type's name, i.e. `AuthorStatus`. */
|
|
4
4
|
name: string;
|
|
5
5
|
/** Gets the `code` details, i.e. `Statuses.getByCode(Status.DRAFT)`. */
|
|
@@ -14,5 +14,4 @@ interface EnumMetadata<C, D, I extends number | string = number | string> {
|
|
|
14
14
|
getDetails(): ReadonlyArray<D>;
|
|
15
15
|
}
|
|
16
16
|
//#endregion
|
|
17
|
-
export { EnumMetadata };
|
|
18
17
|
//# sourceMappingURL=EnumMetadata.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnumMetadata.d.mts","names":[],"sources":["../src/EnumMetadata.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"EnumMetadata.d.mts","names":[],"sources":["../src/EnumMetadata.ts"],"mappings":";iBAAiB,aAAa,GAAG,GAAG;;EAElC;;EAGA,UAAU,MAAM,IAAI;;EAGpB,WAAW,eAAe;;EAG1B,SAAS,IAAI,IAAI;;EAGjB,aAAa,cAAc;;EAG3B,cAAc,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IndexManager.cjs","names":["#indexes","groupBy","getMetadata","isLoadedReference","#valueToEntities","#arrayToEntities","isEntity","fastWhereFilterHash"],"sources":["../src/IndexManager.ts"],"sourcesContent":["import { fastWhereFilterHash } from \"src/dataloaders/fastWhereFilterHash.ts\";\nimport { type Entity, isEntity } from \"src/Entity.ts\";\nimport { type EntityMetadata, type Field, getMetadata } from \"src/EntityMetadata.ts\";\nimport { type ManyToOneReference, type PolymorphicReference, isLoadedReference } from \"src/relations/index.ts\";\nimport { groupBy } from \"src/utils.ts\";\n\ntype FieldValue = any;\ntype FieldName = string;\ntype EntityTag = string;\ntype FieldIndexEntry = {\n field: Field;\n index: FieldIndex;\n /** Tracks how far into the EM's list-per-tag array this field index has been lazily populated. */\n indexedCount: number;\n};\nconst emptySet = new Set<Entity>();\n\n// The test reproducing a n^2 with n=500 went from 100ms to 50ms if indexed\nexport const indexThreshold = 500;\n\n/**\n * IndexManager provides field-based indexing for entity queries to avoid O(n) linear scans of `em.entities`.\n *\n * Key features:\n * - Only indexes entity types with >1000 entities to avoid overhead for small datasets\n * - Supports dual indexing for m2o/poly fields (by ID for saved, by instance for unsaved)\n * - Automatically maintains indexes when fields are updated via setField()\n */\nexport class IndexManager {\n readonly #indexes: Map<EntityTag, Map<FieldName, FieldIndexEntry>> = new Map();\n\n /** @return if we should index entities of this type/count. */\n shouldIndexType(entityCount: number): boolean {\n return entityCount >= indexThreshold;\n }\n\n /** Visible for testing. */\n isIndexed(tagName: string): boolean {\n return this.#indexes.has(tagName);\n }\n\n /** Enables indexing for an entity type and builds indexes for the requested fields. */\n enableIndexingForType<T extends Entity>(meta: EntityMetadata<T>, entities: T[], where: object): void {\n const { tagName } = meta;\n if (!this.#indexes.has(tagName)) {\n this.#indexes.set(tagName, new Map());\n }\n\n const fieldNames = Object.keys(where);\n const fieldIndexes = this.#indexes.get(tagName)!;\n const missingFieldNames = fieldNames.filter((fieldName) => !fieldIndexes.has(fieldName));\n if (missingFieldNames.length === 0) return;\n\n // If subtypes are involved, group by each subtype\n if (meta.baseType || meta.subTypes.length > 0) {\n [...groupBy(entities, (e) => getMetadata(e)).entries()].forEach(([meta, entities]) => {\n this.addEntitiesToIndex(meta, entities, missingFieldNames);\n });\n } else {\n this.addEntitiesToIndex(meta, entities, missingFieldNames);\n }\n }\n\n /** Updates indexes when a field value changes. */\n maybeUpdateFieldIndex(entity: Entity, fieldName: string, oldValue: any, newValue: any): void {\n // Fast return for the common case, which is no indexing\n if (this.#indexes.size === 0) return;\n\n const meta = getMetadata(entity);\n const fieldIndexes = this.#indexes.get(meta.tagName);\n if (!fieldIndexes) return; // Type not indexed\n\n const fieldIndex = fieldIndexes.get(fieldName)?.index;\n if (!fieldIndex) return; // Field is not indexed\n\n fieldIndex.remove(oldValue, entity);\n fieldIndex.add(newValue, entity);\n }\n\n /**\n * Finds entities matching the given where clause using indexes.\n *\n * Returns the raw candidate set (possibly a live internal index set, so do not mutate it);\n * the caller applies its own subtype/deleted filtering while building the final array.\n */\n findMatching<T extends Entity>(meta: EntityMetadata<T>, entities: T[], where: any): ReadonlySet<T> {\n const { tagName } = meta;\n if (!this.#indexes.has(tagName)) {\n throw new Error(`${meta.type} is not indexed`);\n }\n const fieldIndexes = this.#indexes.get(tagName)!;\n // Start with all entities of the 1st condition, then intersect (AND) each subsequent field in `where`\n let candidates: Set<Entity> | undefined;\n for (const [fieldName, value] of Object.entries(where)) {\n this.indexUnindexedEntities(entities, fieldName);\n const fieldCandidates = fieldIndexes.get(fieldName)?.index.get(value);\n if (!candidates) {\n candidates = fieldCandidates ?? emptySet; // This is the 1st clause\n } else {\n candidates = fieldCandidates ? intersectSets(candidates, fieldCandidates) : emptySet;\n }\n // Early exit if no candidates remain\n if (candidates.size === 0) break;\n }\n if (candidates === undefined) {\n throw new Error(`Expected where clause with at least one condition`);\n }\n return candidates as unknown as ReadonlySet<T>;\n }\n\n // `entities` should all be of the exact same subtype\n private addEntitiesToIndex(meta: EntityMetadata, entities: Entity[], fieldNames: string[]): void {\n const { tagName } = meta;\n const indexes = this.#indexes.get(tagName)!;\n // Iterate over each field so we can do a shared fieldIndex lookup\n for (const fieldName of fieldNames) {\n const field = meta.allFields[fieldName];\n if (!field) continue;\n let entry = indexes.get(fieldName);\n if (!entry) {\n entry = { field, index: new FieldIndex(meta.columns[fieldName]?.isArray ?? false), indexedCount: 0 };\n indexes.set(fieldName, entry);\n }\n for (const entity of entities) {\n // Deleted entities never match, and reading a flushed one's relations throws\n if (entity.isDeletedEntity) continue;\n const value = getFieldValue(entity, fieldName, entry.field);\n entry.index.add(value, entity);\n }\n entry.indexedCount = entities.length;\n }\n }\n\n /** Lazily indexes newly-registered entities only for fields that are queried. */\n private indexUnindexedEntities<T extends Entity>(entities: T[], fieldName: string): void {\n const first = entities[0];\n if (first === undefined) return;\n\n const meta = getMetadata(first);\n const entry = this.#indexes.get(meta.tagName)?.get(fieldName);\n if (entry === undefined || entry.indexedCount === entities.length) return;\n\n for (let i = entry.indexedCount; i < entities.length; i++) {\n const entity = entities[i];\n if (entity.isDeletedEntity) continue;\n const value = getFieldValue(entity, fieldName, entry.field);\n entry.index.add(value, entity);\n }\n entry.indexedCount = entities.length;\n }\n}\n\n// Use the same field access pattern as entityMatches\nfunction getFieldValue(entity: Entity, fieldName: string, field: Field): any {\n const fn = fieldName as keyof Entity;\n switch (field.kind) {\n case \"primaryKey\":\n return entity.idTaggedMaybe;\n case \"enum\":\n case \"primitive\":\n return (entity as any)[fn];\n case \"m2o\":\n case \"poly\":\n const relation = (entity as any)[fn] as\n | ManyToOneReference<Entity, any, any>\n | PolymorphicReference<Entity, any, any>;\n if (isLoadedReference(relation)) {\n return relation.get;\n } else if (relation.isSet) {\n return relation.id;\n } else {\n return undefined;\n }\n default:\n return undefined;\n }\n}\n\n/**\n * For a given field, like `firstName`, holds the reverse index of value `bob` -> entities `[a1, a2]`.\n *\n * This also handles indexes `Entity` values as both instances & IDs, to handle both:\n * - new/unpersisted entities not yet having IDs, and\n * - relations not having loaded their instances yet\n */\nclass FieldIndex {\n readonly #valueToEntities = new Map<FieldValue, Set<Entity>>();\n // Keep serialized arrays separate so their keys cannot collide with scalar string values.\n readonly #arrayToEntities = new Map<string, Set<Entity>>();\n\n constructor(private readonly isArray: boolean) {}\n\n /** @return entities that have `value` as their current value for this field. */\n get(value: any): Set<Entity> | undefined {\n if (isEntity(value) && value.idTaggedMaybe) {\n // If `value` is a persisted entity like `a:1`, and entities could have indexed their `author_id=a:1` field\n // values as the unloaded \"just an a:1 string id\" value, before `a:1` was loaded into memory.\n const matchId = this.#valueToEntities.get(value.idTaggedMaybe);\n // But other entities could also have indexes `a:1` as an instance, so go ahead and check both\n const matchInstance = this.#valueToEntities.get(value);\n if (matchId && matchInstance) {\n return new Set([...matchId, ...matchInstance]);\n }\n return matchId ?? matchInstance;\n }\n // Treat null and undefined as equivalent for unset relations\n if (value === null) value = undefined;\n const arrayKey = this.maybeArrayKey(value);\n if (arrayKey !== undefined) return this.#arrayToEntities.get(arrayKey);\n return this.#valueToEntities.get(value);\n }\n\n add(value: any, entity: Entity): void {\n // If this is an entity, store both the entity itself & its ID\n if (isEntity(value) && value.idTaggedMaybe) {\n this.doAdd(value.idTaggedMaybe, entity);\n }\n this.doAdd(value, entity);\n }\n\n remove(value: any, entity: Entity): void {\n if (isEntity(value) && value.idTaggedMaybe) {\n this.doRemove(value.idTaggedMaybe, entity);\n }\n this.doRemove(value, entity);\n }\n\n private doAdd(value: any, entity: Entity): void {\n const arrayKey = this.maybeArrayKey(value);\n const index = arrayKey === undefined ? this.#valueToEntities : this.#arrayToEntities;\n const key = arrayKey ?? value;\n const set = index.get(key) ?? new Set();\n if (set.size === 0) index.set(key, set);\n set.add(entity);\n }\n\n private doRemove(value: any, entity: Entity): void {\n const arrayKey = this.maybeArrayKey(value);\n const index = arrayKey === undefined ? this.#valueToEntities : this.#arrayToEntities;\n const key = arrayKey ?? value;\n const set = index.get(key);\n if (set) {\n set.delete(entity);\n if (set.size === 0) {\n index.delete(key);\n }\n }\n }\n\n /** Preserves array order and element types, including bigint values that JSON cannot encode. */\n private maybeArrayKey(value: unknown): string | undefined {\n return this.isArray && Array.isArray(value) ? fastWhereFilterHash(value) : undefined;\n }\n}\n\nfunction intersectSets<T>(set1: Set<T>, set2: Set<T>): Set<T> {\n const [smaller, larger] = set1.size <= set2.size ? [set1, set2] : [set2, set1];\n const result = new Set<T>();\n for (const item of smaller) {\n if (larger.has(item)) {\n result.add(item);\n }\n }\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IndexManager.cjs","names":["groupBy","getMetadata","isLoadedReference","isEntity","fastWhereFilterHash"],"sources":["../src/IndexManager.ts"],"sourcesContent":["import { fastWhereFilterHash } from \"src/dataloaders/fastWhereFilterHash.ts\";\nimport { type Entity, isEntity } from \"src/Entity.ts\";\nimport { type EntityMetadata, type Field, getMetadata } from \"src/EntityMetadata.ts\";\nimport { type ManyToOneReference, type PolymorphicReference, isLoadedReference } from \"src/relations/index.ts\";\nimport { groupBy } from \"src/utils.ts\";\n\ntype FieldValue = any;\ntype FieldName = string;\ntype EntityTag = string;\ntype FieldIndexEntry = {\n field: Field;\n index: FieldIndex;\n /** Tracks how far into the EM's list-per-tag array this field index has been lazily populated. */\n indexedCount: number;\n};\nconst emptySet = new Set<Entity>();\n\n// The test reproducing a n^2 with n=500 went from 100ms to 50ms if indexed\nexport const indexThreshold = 500;\n\n/**\n * IndexManager provides field-based indexing for entity queries to avoid O(n) linear scans of `em.entities`.\n *\n * Key features:\n * - Only indexes entity types with >1000 entities to avoid overhead for small datasets\n * - Supports dual indexing for m2o/poly fields (by ID for saved, by instance for unsaved)\n * - Automatically maintains indexes when fields are updated via setField()\n */\nexport class IndexManager {\n readonly #indexes: Map<EntityTag, Map<FieldName, FieldIndexEntry>> = new Map();\n\n /** @return if we should index entities of this type/count. */\n shouldIndexType(entityCount: number): boolean {\n return entityCount >= indexThreshold;\n }\n\n /** Visible for testing. */\n isIndexed(tagName: string): boolean {\n return this.#indexes.has(tagName);\n }\n\n /** Enables indexing for an entity type and builds indexes for the requested fields. */\n enableIndexingForType<T extends Entity>(meta: EntityMetadata<T>, entities: T[], where: object): void {\n const { tagName } = meta;\n if (!this.#indexes.has(tagName)) {\n this.#indexes.set(tagName, new Map());\n }\n\n const fieldNames = Object.keys(where);\n const fieldIndexes = this.#indexes.get(tagName)!;\n const missingFieldNames = fieldNames.filter((fieldName) => !fieldIndexes.has(fieldName));\n if (missingFieldNames.length === 0) return;\n\n // If subtypes are involved, group by each subtype\n if (meta.baseType || meta.subTypes.length > 0) {\n [...groupBy(entities, (e) => getMetadata(e)).entries()].forEach(([meta, entities]) => {\n this.addEntitiesToIndex(meta, entities, missingFieldNames);\n });\n } else {\n this.addEntitiesToIndex(meta, entities, missingFieldNames);\n }\n }\n\n /** Updates indexes when a field value changes. */\n maybeUpdateFieldIndex(entity: Entity, fieldName: string, oldValue: any, newValue: any): void {\n // Fast return for the common case, which is no indexing\n if (this.#indexes.size === 0) return;\n\n const meta = getMetadata(entity);\n const fieldIndexes = this.#indexes.get(meta.tagName);\n if (!fieldIndexes) return; // Type not indexed\n\n const fieldIndex = fieldIndexes.get(fieldName)?.index;\n if (!fieldIndex) return; // Field is not indexed\n\n fieldIndex.remove(oldValue, entity);\n fieldIndex.add(newValue, entity);\n }\n\n /**\n * Finds entities matching the given where clause using indexes.\n *\n * Returns the raw candidate set (possibly a live internal index set, so do not mutate it);\n * the caller applies its own subtype/deleted filtering while building the final array.\n */\n findMatching<T extends Entity>(meta: EntityMetadata<T>, entities: T[], where: any): ReadonlySet<T> {\n const { tagName } = meta;\n if (!this.#indexes.has(tagName)) {\n throw new Error(`${meta.type} is not indexed`);\n }\n const fieldIndexes = this.#indexes.get(tagName)!;\n // Start with all entities of the 1st condition, then intersect (AND) each subsequent field in `where`\n let candidates: Set<Entity> | undefined;\n for (const [fieldName, value] of Object.entries(where)) {\n this.indexUnindexedEntities(entities, fieldName);\n const fieldCandidates = fieldIndexes.get(fieldName)?.index.get(value);\n if (!candidates) {\n candidates = fieldCandidates ?? emptySet; // This is the 1st clause\n } else {\n candidates = fieldCandidates ? intersectSets(candidates, fieldCandidates) : emptySet;\n }\n // Early exit if no candidates remain\n if (candidates.size === 0) break;\n }\n if (candidates === undefined) {\n throw new Error(`Expected where clause with at least one condition`);\n }\n return candidates as unknown as ReadonlySet<T>;\n }\n\n // `entities` should all be of the exact same subtype\n private addEntitiesToIndex(meta: EntityMetadata, entities: Entity[], fieldNames: string[]): void {\n const { tagName } = meta;\n const indexes = this.#indexes.get(tagName)!;\n // Iterate over each field so we can do a shared fieldIndex lookup\n for (const fieldName of fieldNames) {\n const field = meta.allFields[fieldName];\n if (!field) continue;\n let entry = indexes.get(fieldName);\n if (!entry) {\n entry = { field, index: new FieldIndex(meta.columns[fieldName]?.isArray ?? false), indexedCount: 0 };\n indexes.set(fieldName, entry);\n }\n for (const entity of entities) {\n // Deleted entities never match, and reading a flushed one's relations throws\n if (entity.isDeletedEntity) continue;\n const value = getFieldValue(entity, fieldName, entry.field);\n entry.index.add(value, entity);\n }\n entry.indexedCount = entities.length;\n }\n }\n\n /** Lazily indexes newly-registered entities only for fields that are queried. */\n private indexUnindexedEntities<T extends Entity>(entities: T[], fieldName: string): void {\n const first = entities[0];\n if (first === undefined) return;\n\n const meta = getMetadata(first);\n const entry = this.#indexes.get(meta.tagName)?.get(fieldName);\n if (entry === undefined || entry.indexedCount === entities.length) return;\n\n for (let i = entry.indexedCount; i < entities.length; i++) {\n const entity = entities[i];\n if (entity.isDeletedEntity) continue;\n const value = getFieldValue(entity, fieldName, entry.field);\n entry.index.add(value, entity);\n }\n entry.indexedCount = entities.length;\n }\n}\n\n// Use the same field access pattern as entityMatches\nfunction getFieldValue(entity: Entity, fieldName: string, field: Field): any {\n const fn = fieldName as keyof Entity;\n switch (field.kind) {\n case \"primaryKey\":\n return entity.idTaggedMaybe;\n case \"enum\":\n case \"primitive\":\n return (entity as any)[fn];\n case \"m2o\":\n case \"poly\":\n const relation = (entity as any)[fn] as\n | ManyToOneReference<Entity, any, any>\n | PolymorphicReference<Entity, any, any>;\n if (isLoadedReference(relation)) {\n return relation.get;\n } else if (relation.isSet) {\n return relation.id;\n } else {\n return undefined;\n }\n default:\n return undefined;\n }\n}\n\n/**\n * For a given field, like `firstName`, holds the reverse index of value `bob` -> entities `[a1, a2]`.\n *\n * This also handles indexes `Entity` values as both instances & IDs, to handle both:\n * - new/unpersisted entities not yet having IDs, and\n * - relations not having loaded their instances yet\n */\nclass FieldIndex {\n readonly #valueToEntities = new Map<FieldValue, Set<Entity>>();\n // Keep serialized arrays separate so their keys cannot collide with scalar string values.\n readonly #arrayToEntities = new Map<string, Set<Entity>>();\n\n constructor(private readonly isArray: boolean) {}\n\n /** @return entities that have `value` as their current value for this field. */\n get(value: any): Set<Entity> | undefined {\n if (isEntity(value) && value.idTaggedMaybe) {\n // If `value` is a persisted entity like `a:1`, and entities could have indexed their `author_id=a:1` field\n // values as the unloaded \"just an a:1 string id\" value, before `a:1` was loaded into memory.\n const matchId = this.#valueToEntities.get(value.idTaggedMaybe);\n // But other entities could also have indexes `a:1` as an instance, so go ahead and check both\n const matchInstance = this.#valueToEntities.get(value);\n if (matchId && matchInstance) {\n return new Set([...matchId, ...matchInstance]);\n }\n return matchId ?? matchInstance;\n }\n // Treat null and undefined as equivalent for unset relations\n if (value === null) value = undefined;\n const arrayKey = this.maybeArrayKey(value);\n if (arrayKey !== undefined) return this.#arrayToEntities.get(arrayKey);\n return this.#valueToEntities.get(value);\n }\n\n add(value: any, entity: Entity): void {\n // If this is an entity, store both the entity itself & its ID\n if (isEntity(value) && value.idTaggedMaybe) {\n this.doAdd(value.idTaggedMaybe, entity);\n }\n this.doAdd(value, entity);\n }\n\n remove(value: any, entity: Entity): void {\n if (isEntity(value) && value.idTaggedMaybe) {\n this.doRemove(value.idTaggedMaybe, entity);\n }\n this.doRemove(value, entity);\n }\n\n private doAdd(value: any, entity: Entity): void {\n const arrayKey = this.maybeArrayKey(value);\n const index = arrayKey === undefined ? this.#valueToEntities : this.#arrayToEntities;\n const key = arrayKey ?? value;\n const set = index.get(key) ?? new Set();\n if (set.size === 0) index.set(key, set);\n set.add(entity);\n }\n\n private doRemove(value: any, entity: Entity): void {\n const arrayKey = this.maybeArrayKey(value);\n const index = arrayKey === undefined ? this.#valueToEntities : this.#arrayToEntities;\n const key = arrayKey ?? value;\n const set = index.get(key);\n if (set) {\n set.delete(entity);\n if (set.size === 0) {\n index.delete(key);\n }\n }\n }\n\n /** Preserves array order and element types, including bigint values that JSON cannot encode. */\n private maybeArrayKey(value: unknown): string | undefined {\n return this.isArray && Array.isArray(value) ? fastWhereFilterHash(value) : undefined;\n }\n}\n\nfunction intersectSets<T>(set1: Set<T>, set2: Set<T>): Set<T> {\n const [smaller, larger] = set1.size <= set2.size ? [set1, set2] : [set2, set1];\n const result = new Set<T>();\n for (const item of smaller) {\n if (larger.has(item)) {\n result.add(item);\n }\n }\n return result;\n}\n"],"mappings":"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"}
|
package/build/IndexManager.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EntityMetadata } from "./EntityMetadata.cjs";
|
|
2
2
|
import { Entity } from "./Entity.cjs";
|
|
3
3
|
//#region src/IndexManager.d.ts
|
|
4
|
-
declare const indexThreshold = 500;
|
|
4
|
+
export declare const indexThreshold = 500;
|
|
5
5
|
/**
|
|
6
6
|
* IndexManager provides field-based indexing for entity queries to avoid O(n) linear scans of `em.entities`.
|
|
7
7
|
*
|
|
@@ -10,7 +10,7 @@ declare const indexThreshold = 500;
|
|
|
10
10
|
* - Supports dual indexing for m2o/poly fields (by ID for saved, by instance for unsaved)
|
|
11
11
|
* - Automatically maintains indexes when fields are updated via setField()
|
|
12
12
|
*/
|
|
13
|
-
declare class IndexManager {
|
|
13
|
+
export declare class IndexManager {
|
|
14
14
|
#private;
|
|
15
15
|
/** @return if we should index entities of this type/count. */
|
|
16
16
|
shouldIndexType(entityCount: number): boolean;
|
|
@@ -32,5 +32,4 @@ declare class IndexManager {
|
|
|
32
32
|
private indexUnindexedEntities;
|
|
33
33
|
}
|
|
34
34
|
//#endregion
|
|
35
|
-
export { IndexManager, indexThreshold };
|
|
36
35
|
//# sourceMappingURL=IndexManager.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IndexManager.d.cts","names":[],"sources":["../src/IndexManager.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"IndexManager.d.cts","names":[],"sources":["../src/IndexManager.ts"],"mappings":";;;qBAkBa;;;;;;;;;qBAUA;;;EAIX,gBAAgB;;EAKhB,UAAU;;EAKV,sBAAsB,UAAU,QAAQ,MAAM,eAAe,IAAI,UAAU,KAAK;;EAsBhF,sBAAsB,QAAQ,QAAQ,mBAAmB,eAAe;;;;;;;EAqBxE,aAAa,UAAU,QAAQ,MAAM,eAAe,IAAI,UAAU,KAAK,aAAa,YAAY;UA0BxF;;UAuBA"}
|
package/build/IndexManager.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EntityMetadata } from "./EntityMetadata.mjs";
|
|
2
2
|
import { Entity } from "./Entity.mjs";
|
|
3
3
|
//#region src/IndexManager.d.ts
|
|
4
|
-
declare const indexThreshold = 500;
|
|
4
|
+
export declare const indexThreshold = 500;
|
|
5
5
|
/**
|
|
6
6
|
* IndexManager provides field-based indexing for entity queries to avoid O(n) linear scans of `em.entities`.
|
|
7
7
|
*
|
|
@@ -10,7 +10,7 @@ declare const indexThreshold = 500;
|
|
|
10
10
|
* - Supports dual indexing for m2o/poly fields (by ID for saved, by instance for unsaved)
|
|
11
11
|
* - Automatically maintains indexes when fields are updated via setField()
|
|
12
12
|
*/
|
|
13
|
-
declare class IndexManager {
|
|
13
|
+
export declare class IndexManager {
|
|
14
14
|
#private;
|
|
15
15
|
/** @return if we should index entities of this type/count. */
|
|
16
16
|
shouldIndexType(entityCount: number): boolean;
|
|
@@ -32,5 +32,4 @@ declare class IndexManager {
|
|
|
32
32
|
private indexUnindexedEntities;
|
|
33
33
|
}
|
|
34
34
|
//#endregion
|
|
35
|
-
export { IndexManager, indexThreshold };
|
|
36
35
|
//# sourceMappingURL=IndexManager.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IndexManager.d.mts","names":[],"sources":["../src/IndexManager.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"IndexManager.d.mts","names":[],"sources":["../src/IndexManager.ts"],"mappings":";;;qBAkBa;;;;;;;;;qBAUA;;;EAIX,gBAAgB;;EAKhB,UAAU;;EAKV,sBAAsB,UAAU,QAAQ,MAAM,eAAe,IAAI,UAAU,KAAK;;EAsBhF,sBAAsB,QAAQ,QAAQ,mBAAmB,eAAe;;;;;;;EAqBxE,aAAa,UAAU,QAAQ,MAAM,eAAe,IAAI,UAAU,KAAK,aAAa,YAAY;UA0BxF;;UAuBA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IndexManager.js","names":["#indexes","#valueToEntities","#arrayToEntities"],"sources":["../src/IndexManager.ts"],"sourcesContent":["import { fastWhereFilterHash } from \"src/dataloaders/fastWhereFilterHash.ts\";\nimport { type Entity, isEntity } from \"src/Entity.ts\";\nimport { type EntityMetadata, type Field, getMetadata } from \"src/EntityMetadata.ts\";\nimport { type ManyToOneReference, type PolymorphicReference, isLoadedReference } from \"src/relations/index.ts\";\nimport { groupBy } from \"src/utils.ts\";\n\ntype FieldValue = any;\ntype FieldName = string;\ntype EntityTag = string;\ntype FieldIndexEntry = {\n field: Field;\n index: FieldIndex;\n /** Tracks how far into the EM's list-per-tag array this field index has been lazily populated. */\n indexedCount: number;\n};\nconst emptySet = new Set<Entity>();\n\n// The test reproducing a n^2 with n=500 went from 100ms to 50ms if indexed\nexport const indexThreshold = 500;\n\n/**\n * IndexManager provides field-based indexing for entity queries to avoid O(n) linear scans of `em.entities`.\n *\n * Key features:\n * - Only indexes entity types with >1000 entities to avoid overhead for small datasets\n * - Supports dual indexing for m2o/poly fields (by ID for saved, by instance for unsaved)\n * - Automatically maintains indexes when fields are updated via setField()\n */\nexport class IndexManager {\n readonly #indexes: Map<EntityTag, Map<FieldName, FieldIndexEntry>> = new Map();\n\n /** @return if we should index entities of this type/count. */\n shouldIndexType(entityCount: number): boolean {\n return entityCount >= indexThreshold;\n }\n\n /** Visible for testing. */\n isIndexed(tagName: string): boolean {\n return this.#indexes.has(tagName);\n }\n\n /** Enables indexing for an entity type and builds indexes for the requested fields. */\n enableIndexingForType<T extends Entity>(meta: EntityMetadata<T>, entities: T[], where: object): void {\n const { tagName } = meta;\n if (!this.#indexes.has(tagName)) {\n this.#indexes.set(tagName, new Map());\n }\n\n const fieldNames = Object.keys(where);\n const fieldIndexes = this.#indexes.get(tagName)!;\n const missingFieldNames = fieldNames.filter((fieldName) => !fieldIndexes.has(fieldName));\n if (missingFieldNames.length === 0) return;\n\n // If subtypes are involved, group by each subtype\n if (meta.baseType || meta.subTypes.length > 0) {\n [...groupBy(entities, (e) => getMetadata(e)).entries()].forEach(([meta, entities]) => {\n this.addEntitiesToIndex(meta, entities, missingFieldNames);\n });\n } else {\n this.addEntitiesToIndex(meta, entities, missingFieldNames);\n }\n }\n\n /** Updates indexes when a field value changes. */\n maybeUpdateFieldIndex(entity: Entity, fieldName: string, oldValue: any, newValue: any): void {\n // Fast return for the common case, which is no indexing\n if (this.#indexes.size === 0) return;\n\n const meta = getMetadata(entity);\n const fieldIndexes = this.#indexes.get(meta.tagName);\n if (!fieldIndexes) return; // Type not indexed\n\n const fieldIndex = fieldIndexes.get(fieldName)?.index;\n if (!fieldIndex) return; // Field is not indexed\n\n fieldIndex.remove(oldValue, entity);\n fieldIndex.add(newValue, entity);\n }\n\n /**\n * Finds entities matching the given where clause using indexes.\n *\n * Returns the raw candidate set (possibly a live internal index set, so do not mutate it);\n * the caller applies its own subtype/deleted filtering while building the final array.\n */\n findMatching<T extends Entity>(meta: EntityMetadata<T>, entities: T[], where: any): ReadonlySet<T> {\n const { tagName } = meta;\n if (!this.#indexes.has(tagName)) {\n throw new Error(`${meta.type} is not indexed`);\n }\n const fieldIndexes = this.#indexes.get(tagName)!;\n // Start with all entities of the 1st condition, then intersect (AND) each subsequent field in `where`\n let candidates: Set<Entity> | undefined;\n for (const [fieldName, value] of Object.entries(where)) {\n this.indexUnindexedEntities(entities, fieldName);\n const fieldCandidates = fieldIndexes.get(fieldName)?.index.get(value);\n if (!candidates) {\n candidates = fieldCandidates ?? emptySet; // This is the 1st clause\n } else {\n candidates = fieldCandidates ? intersectSets(candidates, fieldCandidates) : emptySet;\n }\n // Early exit if no candidates remain\n if (candidates.size === 0) break;\n }\n if (candidates === undefined) {\n throw new Error(`Expected where clause with at least one condition`);\n }\n return candidates as unknown as ReadonlySet<T>;\n }\n\n // `entities` should all be of the exact same subtype\n private addEntitiesToIndex(meta: EntityMetadata, entities: Entity[], fieldNames: string[]): void {\n const { tagName } = meta;\n const indexes = this.#indexes.get(tagName)!;\n // Iterate over each field so we can do a shared fieldIndex lookup\n for (const fieldName of fieldNames) {\n const field = meta.allFields[fieldName];\n if (!field) continue;\n let entry = indexes.get(fieldName);\n if (!entry) {\n entry = { field, index: new FieldIndex(meta.columns[fieldName]?.isArray ?? false), indexedCount: 0 };\n indexes.set(fieldName, entry);\n }\n for (const entity of entities) {\n // Deleted entities never match, and reading a flushed one's relations throws\n if (entity.isDeletedEntity) continue;\n const value = getFieldValue(entity, fieldName, entry.field);\n entry.index.add(value, entity);\n }\n entry.indexedCount = entities.length;\n }\n }\n\n /** Lazily indexes newly-registered entities only for fields that are queried. */\n private indexUnindexedEntities<T extends Entity>(entities: T[], fieldName: string): void {\n const first = entities[0];\n if (first === undefined) return;\n\n const meta = getMetadata(first);\n const entry = this.#indexes.get(meta.tagName)?.get(fieldName);\n if (entry === undefined || entry.indexedCount === entities.length) return;\n\n for (let i = entry.indexedCount; i < entities.length; i++) {\n const entity = entities[i];\n if (entity.isDeletedEntity) continue;\n const value = getFieldValue(entity, fieldName, entry.field);\n entry.index.add(value, entity);\n }\n entry.indexedCount = entities.length;\n }\n}\n\n// Use the same field access pattern as entityMatches\nfunction getFieldValue(entity: Entity, fieldName: string, field: Field): any {\n const fn = fieldName as keyof Entity;\n switch (field.kind) {\n case \"primaryKey\":\n return entity.idTaggedMaybe;\n case \"enum\":\n case \"primitive\":\n return (entity as any)[fn];\n case \"m2o\":\n case \"poly\":\n const relation = (entity as any)[fn] as\n | ManyToOneReference<Entity, any, any>\n | PolymorphicReference<Entity, any, any>;\n if (isLoadedReference(relation)) {\n return relation.get;\n } else if (relation.isSet) {\n return relation.id;\n } else {\n return undefined;\n }\n default:\n return undefined;\n }\n}\n\n/**\n * For a given field, like `firstName`, holds the reverse index of value `bob` -> entities `[a1, a2]`.\n *\n * This also handles indexes `Entity` values as both instances & IDs, to handle both:\n * - new/unpersisted entities not yet having IDs, and\n * - relations not having loaded their instances yet\n */\nclass FieldIndex {\n readonly #valueToEntities = new Map<FieldValue, Set<Entity>>();\n // Keep serialized arrays separate so their keys cannot collide with scalar string values.\n readonly #arrayToEntities = new Map<string, Set<Entity>>();\n\n constructor(private readonly isArray: boolean) {}\n\n /** @return entities that have `value` as their current value for this field. */\n get(value: any): Set<Entity> | undefined {\n if (isEntity(value) && value.idTaggedMaybe) {\n // If `value` is a persisted entity like `a:1`, and entities could have indexed their `author_id=a:1` field\n // values as the unloaded \"just an a:1 string id\" value, before `a:1` was loaded into memory.\n const matchId = this.#valueToEntities.get(value.idTaggedMaybe);\n // But other entities could also have indexes `a:1` as an instance, so go ahead and check both\n const matchInstance = this.#valueToEntities.get(value);\n if (matchId && matchInstance) {\n return new Set([...matchId, ...matchInstance]);\n }\n return matchId ?? matchInstance;\n }\n // Treat null and undefined as equivalent for unset relations\n if (value === null) value = undefined;\n const arrayKey = this.maybeArrayKey(value);\n if (arrayKey !== undefined) return this.#arrayToEntities.get(arrayKey);\n return this.#valueToEntities.get(value);\n }\n\n add(value: any, entity: Entity): void {\n // If this is an entity, store both the entity itself & its ID\n if (isEntity(value) && value.idTaggedMaybe) {\n this.doAdd(value.idTaggedMaybe, entity);\n }\n this.doAdd(value, entity);\n }\n\n remove(value: any, entity: Entity): void {\n if (isEntity(value) && value.idTaggedMaybe) {\n this.doRemove(value.idTaggedMaybe, entity);\n }\n this.doRemove(value, entity);\n }\n\n private doAdd(value: any, entity: Entity): void {\n const arrayKey = this.maybeArrayKey(value);\n const index = arrayKey === undefined ? this.#valueToEntities : this.#arrayToEntities;\n const key = arrayKey ?? value;\n const set = index.get(key) ?? new Set();\n if (set.size === 0) index.set(key, set);\n set.add(entity);\n }\n\n private doRemove(value: any, entity: Entity): void {\n const arrayKey = this.maybeArrayKey(value);\n const index = arrayKey === undefined ? this.#valueToEntities : this.#arrayToEntities;\n const key = arrayKey ?? value;\n const set = index.get(key);\n if (set) {\n set.delete(entity);\n if (set.size === 0) {\n index.delete(key);\n }\n }\n }\n\n /** Preserves array order and element types, including bigint values that JSON cannot encode. */\n private maybeArrayKey(value: unknown): string | undefined {\n return this.isArray && Array.isArray(value) ? fastWhereFilterHash(value) : undefined;\n }\n}\n\nfunction intersectSets<T>(set1: Set<T>, set2: Set<T>): Set<T> {\n const [smaller, larger] = set1.size <= set2.size ? [set1, set2] : [set2, set1];\n const result = new Set<T>();\n for (const item of smaller) {\n if (larger.has(item)) {\n result.add(item);\n }\n }\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IndexManager.js","names":[],"sources":["../src/IndexManager.ts"],"sourcesContent":["import { fastWhereFilterHash } from \"src/dataloaders/fastWhereFilterHash.ts\";\nimport { type Entity, isEntity } from \"src/Entity.ts\";\nimport { type EntityMetadata, type Field, getMetadata } from \"src/EntityMetadata.ts\";\nimport { type ManyToOneReference, type PolymorphicReference, isLoadedReference } from \"src/relations/index.ts\";\nimport { groupBy } from \"src/utils.ts\";\n\ntype FieldValue = any;\ntype FieldName = string;\ntype EntityTag = string;\ntype FieldIndexEntry = {\n field: Field;\n index: FieldIndex;\n /** Tracks how far into the EM's list-per-tag array this field index has been lazily populated. */\n indexedCount: number;\n};\nconst emptySet = new Set<Entity>();\n\n// The test reproducing a n^2 with n=500 went from 100ms to 50ms if indexed\nexport const indexThreshold = 500;\n\n/**\n * IndexManager provides field-based indexing for entity queries to avoid O(n) linear scans of `em.entities`.\n *\n * Key features:\n * - Only indexes entity types with >1000 entities to avoid overhead for small datasets\n * - Supports dual indexing for m2o/poly fields (by ID for saved, by instance for unsaved)\n * - Automatically maintains indexes when fields are updated via setField()\n */\nexport class IndexManager {\n readonly #indexes: Map<EntityTag, Map<FieldName, FieldIndexEntry>> = new Map();\n\n /** @return if we should index entities of this type/count. */\n shouldIndexType(entityCount: number): boolean {\n return entityCount >= indexThreshold;\n }\n\n /** Visible for testing. */\n isIndexed(tagName: string): boolean {\n return this.#indexes.has(tagName);\n }\n\n /** Enables indexing for an entity type and builds indexes for the requested fields. */\n enableIndexingForType<T extends Entity>(meta: EntityMetadata<T>, entities: T[], where: object): void {\n const { tagName } = meta;\n if (!this.#indexes.has(tagName)) {\n this.#indexes.set(tagName, new Map());\n }\n\n const fieldNames = Object.keys(where);\n const fieldIndexes = this.#indexes.get(tagName)!;\n const missingFieldNames = fieldNames.filter((fieldName) => !fieldIndexes.has(fieldName));\n if (missingFieldNames.length === 0) return;\n\n // If subtypes are involved, group by each subtype\n if (meta.baseType || meta.subTypes.length > 0) {\n [...groupBy(entities, (e) => getMetadata(e)).entries()].forEach(([meta, entities]) => {\n this.addEntitiesToIndex(meta, entities, missingFieldNames);\n });\n } else {\n this.addEntitiesToIndex(meta, entities, missingFieldNames);\n }\n }\n\n /** Updates indexes when a field value changes. */\n maybeUpdateFieldIndex(entity: Entity, fieldName: string, oldValue: any, newValue: any): void {\n // Fast return for the common case, which is no indexing\n if (this.#indexes.size === 0) return;\n\n const meta = getMetadata(entity);\n const fieldIndexes = this.#indexes.get(meta.tagName);\n if (!fieldIndexes) return; // Type not indexed\n\n const fieldIndex = fieldIndexes.get(fieldName)?.index;\n if (!fieldIndex) return; // Field is not indexed\n\n fieldIndex.remove(oldValue, entity);\n fieldIndex.add(newValue, entity);\n }\n\n /**\n * Finds entities matching the given where clause using indexes.\n *\n * Returns the raw candidate set (possibly a live internal index set, so do not mutate it);\n * the caller applies its own subtype/deleted filtering while building the final array.\n */\n findMatching<T extends Entity>(meta: EntityMetadata<T>, entities: T[], where: any): ReadonlySet<T> {\n const { tagName } = meta;\n if (!this.#indexes.has(tagName)) {\n throw new Error(`${meta.type} is not indexed`);\n }\n const fieldIndexes = this.#indexes.get(tagName)!;\n // Start with all entities of the 1st condition, then intersect (AND) each subsequent field in `where`\n let candidates: Set<Entity> | undefined;\n for (const [fieldName, value] of Object.entries(where)) {\n this.indexUnindexedEntities(entities, fieldName);\n const fieldCandidates = fieldIndexes.get(fieldName)?.index.get(value);\n if (!candidates) {\n candidates = fieldCandidates ?? emptySet; // This is the 1st clause\n } else {\n candidates = fieldCandidates ? intersectSets(candidates, fieldCandidates) : emptySet;\n }\n // Early exit if no candidates remain\n if (candidates.size === 0) break;\n }\n if (candidates === undefined) {\n throw new Error(`Expected where clause with at least one condition`);\n }\n return candidates as unknown as ReadonlySet<T>;\n }\n\n // `entities` should all be of the exact same subtype\n private addEntitiesToIndex(meta: EntityMetadata, entities: Entity[], fieldNames: string[]): void {\n const { tagName } = meta;\n const indexes = this.#indexes.get(tagName)!;\n // Iterate over each field so we can do a shared fieldIndex lookup\n for (const fieldName of fieldNames) {\n const field = meta.allFields[fieldName];\n if (!field) continue;\n let entry = indexes.get(fieldName);\n if (!entry) {\n entry = { field, index: new FieldIndex(meta.columns[fieldName]?.isArray ?? false), indexedCount: 0 };\n indexes.set(fieldName, entry);\n }\n for (const entity of entities) {\n // Deleted entities never match, and reading a flushed one's relations throws\n if (entity.isDeletedEntity) continue;\n const value = getFieldValue(entity, fieldName, entry.field);\n entry.index.add(value, entity);\n }\n entry.indexedCount = entities.length;\n }\n }\n\n /** Lazily indexes newly-registered entities only for fields that are queried. */\n private indexUnindexedEntities<T extends Entity>(entities: T[], fieldName: string): void {\n const first = entities[0];\n if (first === undefined) return;\n\n const meta = getMetadata(first);\n const entry = this.#indexes.get(meta.tagName)?.get(fieldName);\n if (entry === undefined || entry.indexedCount === entities.length) return;\n\n for (let i = entry.indexedCount; i < entities.length; i++) {\n const entity = entities[i];\n if (entity.isDeletedEntity) continue;\n const value = getFieldValue(entity, fieldName, entry.field);\n entry.index.add(value, entity);\n }\n entry.indexedCount = entities.length;\n }\n}\n\n// Use the same field access pattern as entityMatches\nfunction getFieldValue(entity: Entity, fieldName: string, field: Field): any {\n const fn = fieldName as keyof Entity;\n switch (field.kind) {\n case \"primaryKey\":\n return entity.idTaggedMaybe;\n case \"enum\":\n case \"primitive\":\n return (entity as any)[fn];\n case \"m2o\":\n case \"poly\":\n const relation = (entity as any)[fn] as\n | ManyToOneReference<Entity, any, any>\n | PolymorphicReference<Entity, any, any>;\n if (isLoadedReference(relation)) {\n return relation.get;\n } else if (relation.isSet) {\n return relation.id;\n } else {\n return undefined;\n }\n default:\n return undefined;\n }\n}\n\n/**\n * For a given field, like `firstName`, holds the reverse index of value `bob` -> entities `[a1, a2]`.\n *\n * This also handles indexes `Entity` values as both instances & IDs, to handle both:\n * - new/unpersisted entities not yet having IDs, and\n * - relations not having loaded their instances yet\n */\nclass FieldIndex {\n readonly #valueToEntities = new Map<FieldValue, Set<Entity>>();\n // Keep serialized arrays separate so their keys cannot collide with scalar string values.\n readonly #arrayToEntities = new Map<string, Set<Entity>>();\n\n constructor(private readonly isArray: boolean) {}\n\n /** @return entities that have `value` as their current value for this field. */\n get(value: any): Set<Entity> | undefined {\n if (isEntity(value) && value.idTaggedMaybe) {\n // If `value` is a persisted entity like `a:1`, and entities could have indexed their `author_id=a:1` field\n // values as the unloaded \"just an a:1 string id\" value, before `a:1` was loaded into memory.\n const matchId = this.#valueToEntities.get(value.idTaggedMaybe);\n // But other entities could also have indexes `a:1` as an instance, so go ahead and check both\n const matchInstance = this.#valueToEntities.get(value);\n if (matchId && matchInstance) {\n return new Set([...matchId, ...matchInstance]);\n }\n return matchId ?? matchInstance;\n }\n // Treat null and undefined as equivalent for unset relations\n if (value === null) value = undefined;\n const arrayKey = this.maybeArrayKey(value);\n if (arrayKey !== undefined) return this.#arrayToEntities.get(arrayKey);\n return this.#valueToEntities.get(value);\n }\n\n add(value: any, entity: Entity): void {\n // If this is an entity, store both the entity itself & its ID\n if (isEntity(value) && value.idTaggedMaybe) {\n this.doAdd(value.idTaggedMaybe, entity);\n }\n this.doAdd(value, entity);\n }\n\n remove(value: any, entity: Entity): void {\n if (isEntity(value) && value.idTaggedMaybe) {\n this.doRemove(value.idTaggedMaybe, entity);\n }\n this.doRemove(value, entity);\n }\n\n private doAdd(value: any, entity: Entity): void {\n const arrayKey = this.maybeArrayKey(value);\n const index = arrayKey === undefined ? this.#valueToEntities : this.#arrayToEntities;\n const key = arrayKey ?? value;\n const set = index.get(key) ?? new Set();\n if (set.size === 0) index.set(key, set);\n set.add(entity);\n }\n\n private doRemove(value: any, entity: Entity): void {\n const arrayKey = this.maybeArrayKey(value);\n const index = arrayKey === undefined ? this.#valueToEntities : this.#arrayToEntities;\n const key = arrayKey ?? value;\n const set = index.get(key);\n if (set) {\n set.delete(entity);\n if (set.size === 0) {\n index.delete(key);\n }\n }\n }\n\n /** Preserves array order and element types, including bigint values that JSON cannot encode. */\n private maybeArrayKey(value: unknown): string | undefined {\n return this.isArray && Array.isArray(value) ? fastWhereFilterHash(value) : undefined;\n }\n}\n\nfunction intersectSets<T>(set1: Set<T>, set2: Set<T>): Set<T> {\n const [smaller, larger] = set1.size <= set2.size ? [set1, set2] : [set2, set1];\n const result = new Set<T>();\n for (const item of smaller) {\n if (larger.has(item)) {\n result.add(item);\n }\n }\n return result;\n}\n"],"mappings":"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"}
|