@expo/entity 0.41.0 → 0.43.0
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/AuthorizationResultBasedEntityAssociationLoader.d.ts +16 -16
- package/build/AuthorizationResultBasedEntityAssociationLoader.js.map +1 -1
- package/build/AuthorizationResultBasedEntityLoader.d.ts +39 -67
- package/build/AuthorizationResultBasedEntityLoader.js +85 -62
- package/build/AuthorizationResultBasedEntityLoader.js.map +1 -1
- package/build/AuthorizationResultBasedEntityMutator.d.ts +16 -16
- package/build/AuthorizationResultBasedEntityMutator.js.map +1 -1
- package/build/ComposedEntityCacheAdapter.d.ts +7 -6
- package/build/ComposedEntityCacheAdapter.js +28 -28
- package/build/ComposedEntityCacheAdapter.js.map +1 -1
- package/build/ComposedSecondaryEntityCache.d.ts +1 -1
- package/build/ComposedSecondaryEntityCache.js.map +1 -1
- package/build/EnforcingEntityAssociationLoader.d.ts +15 -15
- package/build/EnforcingEntityAssociationLoader.js.map +1 -1
- package/build/EnforcingEntityCreator.d.ts +2 -2
- package/build/EnforcingEntityDeleter.d.ts +2 -2
- package/build/EnforcingEntityLoader.d.ts +104 -18
- package/build/EnforcingEntityLoader.js +113 -12
- package/build/EnforcingEntityLoader.js.map +1 -1
- package/build/EnforcingEntityUpdater.d.ts +2 -2
- package/build/Entity.d.ts +10 -10
- package/build/Entity.js.map +1 -1
- package/build/EntityAssociationLoader.d.ts +3 -3
- package/build/EntityCompanion.d.ts +5 -5
- package/build/EntityCompanion.js.map +1 -1
- package/build/EntityCompanionProvider.d.ts +6 -6
- package/build/EntityCompanionProvider.js.map +1 -1
- package/build/EntityConfiguration.d.ts +46 -5
- package/build/EntityConfiguration.js +39 -1
- package/build/EntityConfiguration.js.map +1 -1
- package/build/EntityCreator.d.ts +4 -4
- package/build/EntityDatabaseAdapter.d.ts +15 -14
- package/build/EntityDatabaseAdapter.js +20 -12
- package/build/EntityDatabaseAdapter.js.map +1 -1
- package/build/EntityDeleter.d.ts +4 -4
- package/build/EntityFieldDefinition.d.ts +20 -10
- package/build/EntityFieldDefinition.js +3 -1
- package/build/EntityFieldDefinition.js.map +1 -1
- package/build/EntityFields.d.ts +14 -12
- package/build/EntityFields.js.map +1 -1
- package/build/EntityLoader.d.ts +5 -5
- package/build/EntityLoaderFactory.d.ts +3 -3
- package/build/EntityLoaderFactory.js.map +1 -1
- package/build/EntityLoaderUtils.d.ts +2 -2
- package/build/EntityLoaderUtils.js +27 -1
- package/build/EntityLoaderUtils.js.map +1 -1
- package/build/EntityMutationInfo.d.ts +2 -2
- package/build/EntityMutationTriggerConfiguration.d.ts +14 -14
- package/build/EntityMutationTriggerConfiguration.js.map +1 -1
- package/build/EntityMutationValidator.d.ts +2 -2
- package/build/EntityMutatorFactory.d.ts +5 -5
- package/build/EntityMutatorFactory.js.map +1 -1
- package/build/EntityPrivacyPolicy.d.ts +14 -14
- package/build/EntityPrivacyPolicy.js.map +1 -1
- package/build/EntitySecondaryCacheLoader.d.ts +4 -4
- package/build/EntityUpdater.d.ts +4 -4
- package/build/GenericEntityCacheAdapter.d.ts +7 -6
- package/build/GenericEntityCacheAdapter.js +13 -14
- package/build/GenericEntityCacheAdapter.js.map +1 -1
- package/build/GenericSecondaryEntityCache.d.ts +3 -3
- package/build/GenericSecondaryEntityCache.js.map +1 -1
- package/build/IEntityCacheAdapter.d.ts +17 -16
- package/build/IEntityCacheAdapterProvider.d.ts +1 -1
- package/build/IEntityDatabaseAdapterProvider.d.ts +1 -1
- package/build/IEntityGenericCacher.d.ts +15 -5
- package/build/ReadonlyEntity.d.ts +8 -8
- package/build/ReadonlyEntity.js.map +1 -1
- package/build/ViewerContext.d.ts +1 -1
- package/build/ViewerScopedEntityCompanion.d.ts +5 -5
- package/build/ViewerScopedEntityCompanionProvider.d.ts +1 -1
- package/build/ViewerScopedEntityLoaderFactory.d.ts +3 -3
- package/build/ViewerScopedEntityMutatorFactory.d.ts +5 -5
- package/build/entityUtils.d.ts +1 -1
- package/build/entityUtils.js.map +1 -1
- package/build/errors/EntityInvalidFieldValueError.d.ts +2 -2
- package/build/errors/EntityNotAuthorizedError.d.ts +1 -1
- package/build/errors/EntityNotFoundError.d.ts +2 -2
- package/build/index.d.ts +7 -7
- package/build/index.js +8 -13
- package/build/index.js.map +1 -1
- package/build/internal/CompositeFieldHolder.d.ts +48 -0
- package/build/internal/CompositeFieldHolder.js +116 -0
- package/build/internal/CompositeFieldHolder.js.map +1 -0
- package/build/internal/CompositeFieldValueMap.d.ts +15 -0
- package/build/internal/CompositeFieldValueMap.js +51 -0
- package/build/internal/CompositeFieldValueMap.js.map +1 -0
- package/build/internal/EntityDataManager.d.ts +16 -16
- package/build/internal/EntityDataManager.js +42 -45
- package/build/internal/EntityDataManager.js.map +1 -1
- package/build/internal/EntityFieldTransformationUtils.d.ts +5 -5
- package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
- package/build/internal/EntityLoadInterfaces.d.ts +104 -0
- package/build/internal/EntityLoadInterfaces.js +25 -0
- package/build/internal/EntityLoadInterfaces.js.map +1 -0
- package/build/internal/EntityTableDataCoordinator.d.ts +6 -6
- package/build/internal/EntityTableDataCoordinator.js.map +1 -1
- package/build/internal/ReadThroughEntityCache.d.ts +17 -16
- package/build/internal/ReadThroughEntityCache.js +36 -36
- package/build/internal/ReadThroughEntityCache.js.map +1 -1
- package/build/internal/SingleFieldHolder.d.ts +34 -0
- package/build/internal/SingleFieldHolder.js +90 -0
- package/build/internal/SingleFieldHolder.js.map +1 -0
- package/build/metrics/EntityMetricsUtils.d.ts +2 -1
- package/build/metrics/EntityMetricsUtils.js.map +1 -1
- package/build/metrics/IEntityMetricsAdapter.d.ts +5 -0
- package/build/metrics/IEntityMetricsAdapter.js.map +1 -1
- package/build/rules/AlwaysAllowPrivacyPolicyRule.d.ts +2 -2
- package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysDenyPrivacyPolicyRule.d.ts +2 -2
- package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysSkipPrivacyPolicyRule.d.ts +2 -2
- package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
- package/build/rules/PrivacyPolicyRule.d.ts +2 -2
- package/build/tsconfig.build.tsbuildinfo +1 -0
- package/build/utils/EntityPrivacyUtils.d.ts +4 -4
- package/build/utils/EntityPrivacyUtils.js.map +1 -1
- package/build/utils/collections/SerializableKeyMap.d.ts +27 -0
- package/build/utils/collections/SerializableKeyMap.js +60 -0
- package/build/utils/collections/SerializableKeyMap.js.map +1 -0
- package/build/utils/collections/maps.js +1 -2
- package/build/utils/collections/maps.js.map +1 -1
- package/build/utils/collections/sets.d.ts +1 -0
- package/build/utils/collections/sets.js +7 -0
- package/build/utils/collections/sets.js.map +1 -0
- package/build/utils/mergeEntityMutationTriggerConfigurations.d.ts +1 -1
- package/package.json +8 -5
- package/src/AuthorizationResultBasedEntityAssociationLoader.ts +56 -49
- package/src/AuthorizationResultBasedEntityLoader.ts +194 -81
- package/src/AuthorizationResultBasedEntityMutator.ts +71 -45
- package/src/ComposedEntityCacheAdapter.ts +55 -46
- package/src/ComposedSecondaryEntityCache.ts +5 -2
- package/src/EnforcingEntityAssociationLoader.ts +52 -44
- package/src/EnforcingEntityCreator.ts +5 -5
- package/src/EnforcingEntityDeleter.ts +5 -5
- package/src/EnforcingEntityLoader.ts +158 -21
- package/src/EnforcingEntityUpdater.ts +5 -5
- package/src/Entity.ts +39 -39
- package/src/EntityAssociationLoader.ts +6 -6
- package/src/EntityCompanion.ts +11 -11
- package/src/EntityCompanionProvider.ts +21 -18
- package/src/EntityConfiguration.ts +123 -9
- package/src/EntityCreator.ts +7 -7
- package/src/EntityDatabaseAdapter.ts +51 -28
- package/src/EntityDeleter.ts +7 -7
- package/src/EntityFieldDefinition.ts +32 -12
- package/src/EntityFields.ts +49 -12
- package/src/EntityLoader.ts +8 -8
- package/src/EntityLoaderFactory.ts +8 -8
- package/src/EntityLoaderUtils.ts +39 -10
- package/src/EntityMutationInfo.ts +6 -6
- package/src/EntityMutationTriggerConfiguration.ts +68 -20
- package/src/EntityMutationValidator.ts +4 -4
- package/src/EntityMutatorFactory.ts +13 -13
- package/src/EntityPrivacyPolicy.ts +50 -26
- package/src/EntitySecondaryCacheLoader.ts +6 -6
- package/src/EntityUpdater.ts +7 -7
- package/src/GenericEntityCacheAdapter.ts +39 -28
- package/src/GenericSecondaryEntityCache.ts +6 -3
- package/src/IEntityCacheAdapter.ts +45 -25
- package/src/IEntityCacheAdapterProvider.ts +3 -3
- package/src/IEntityDatabaseAdapterProvider.ts +3 -3
- package/src/IEntityGenericCacher.ts +33 -5
- package/src/ReadonlyEntity.ts +24 -24
- package/src/ViewerContext.ts +5 -5
- package/src/ViewerScopedEntityCompanion.ts +7 -7
- package/src/ViewerScopedEntityCompanionProvider.ts +6 -6
- package/src/ViewerScopedEntityLoaderFactory.ts +7 -7
- package/src/ViewerScopedEntityMutatorFactory.ts +8 -8
- package/src/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.ts +4 -4
- package/src/__tests__/AuthorizationResultBasedEntityLoader-constructor-test.ts +14 -13
- package/src/__tests__/AuthorizationResultBasedEntityLoader-test.ts +367 -69
- package/src/__tests__/ComposedCacheAdapter-test.ts +235 -117
- package/src/__tests__/EnforcingEntityLoader-test.ts +135 -1
- package/src/__tests__/Entity-test.ts +2 -2
- package/src/__tests__/EntityAssociationLoader-test.ts +2 -2
- package/src/__tests__/EntityCommonUseCases-test.ts +11 -11
- package/src/__tests__/EntityCompanion-test.ts +4 -4
- package/src/__tests__/EntityCompanionProvider-test.ts +9 -8
- package/src/__tests__/EntityConfiguration-test.ts +85 -6
- package/src/__tests__/EntityDatabaseAdapter-test.ts +113 -17
- package/src/__tests__/EntityEdges-test.ts +97 -72
- package/src/__tests__/EntityFields-test.ts +2 -2
- package/src/__tests__/EntityLoader-test.ts +2 -2
- package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +11 -11
- package/src/__tests__/EntityMutator-SingleCompositeFieldCacheConsistency-test.ts +73 -0
- package/src/__tests__/EntityMutator-test.ts +74 -46
- package/src/__tests__/EntityPrivacyPolicy-test.ts +51 -74
- package/src/__tests__/EntityQueryContext-test.ts +1 -1
- package/src/__tests__/EntitySecondaryCacheLoader-test.ts +3 -3
- package/src/__tests__/EntitySelfReferentialEdges-test.ts +64 -39
- package/src/__tests__/GenericEntityCacheAdapter-test.ts +83 -28
- package/src/__tests__/ReadonlyEntity-test.ts +3 -3
- package/src/__tests__/ViewerContext-test.ts +1 -1
- package/src/__tests__/ViewerScopedEntityCompanion-test.ts +5 -2
- package/src/__tests__/ViewerScopedEntityCompanionProvider-test.ts +1 -1
- package/src/__tests__/ViewerScopedEntityMutatorFactory-test.ts +12 -3
- package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +12 -12
- package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +12 -12
- package/src/entityUtils.ts +4 -1
- package/src/errors/EntityInvalidFieldValueError.ts +5 -5
- package/src/errors/EntityNotAuthorizedError.ts +3 -3
- package/src/errors/EntityNotFoundError.ts +5 -5
- package/src/index.ts +7 -7
- package/src/internal/CompositeFieldHolder.ts +218 -0
- package/src/internal/CompositeFieldValueMap.ts +78 -0
- package/src/internal/EntityDataManager.ts +107 -96
- package/src/internal/EntityFieldTransformationUtils.ts +33 -14
- package/src/internal/EntityLoadInterfaces.ts +143 -0
- package/src/internal/EntityTableDataCoordinator.ts +8 -5
- package/src/internal/ReadThroughEntityCache.ts +63 -50
- package/src/internal/SingleFieldHolder.ts +131 -0
- package/src/internal/__tests__/CompositeFieldHolder-test.ts +25 -0
- package/src/internal/__tests__/CompositeFieldValueMap-test.ts +43 -0
- package/src/internal/__tests__/EntityDataManager-test.ts +308 -91
- package/src/internal/__tests__/EntityFieldTransformationUtils-test.ts +3 -2
- package/src/internal/__tests__/ReadThroughEntityCache-test.ts +315 -107
- package/src/metrics/EntityMetricsUtils.ts +7 -2
- package/src/metrics/IEntityMetricsAdapter.ts +6 -0
- package/src/rules/AlwaysAllowPrivacyPolicyRule.ts +5 -5
- package/src/rules/AlwaysDenyPrivacyPolicyRule.ts +5 -5
- package/src/rules/AlwaysSkipPrivacyPolicyRule.ts +5 -5
- package/src/rules/PrivacyPolicyRule.ts +4 -4
- package/src/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.ts +1 -1
- package/src/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.ts +1 -1
- package/src/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.ts +1 -1
- package/src/utils/EntityPrivacyUtils.ts +72 -30
- package/src/utils/{testing → __testfixtures__}/PrivacyPolicyRuleTestUtils.ts +26 -26
- package/src/{testfixtures → utils/__testfixtures__}/SimpleTestEntity.ts +16 -15
- package/src/utils/__testfixtures__/StubCacheAdapter.ts +164 -0
- package/src/utils/{testing → __testfixtures__}/StubDatabaseAdapter.ts +19 -12
- package/src/utils/{testing → __testfixtures__}/StubDatabaseAdapterProvider.ts +4 -4
- package/src/utils/__testfixtures__/TSMockitoExtensions.ts +69 -0
- package/src/{testfixtures → utils/__testfixtures__}/TestEntity.ts +21 -15
- package/src/{testfixtures → utils/__testfixtures__}/TestEntity2.ts +16 -15
- package/src/{testfixtures → utils/__testfixtures__}/TestEntityWithMutationTriggers.ts +23 -22
- package/src/{testfixtures → utils/__testfixtures__}/TestViewerContext.ts +1 -1
- package/src/utils/{testing → __testfixtures__}/describeFieldTestCase.ts +1 -1
- package/src/utils/__tests__/EntityPrivacyUtils-test.ts +62 -66
- package/src/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.ts +29 -25
- package/src/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.ts +1 -1
- package/src/utils/collections/SerializableKeyMap.ts +84 -0
- package/src/utils/collections/__tests__/SerializableKeyMap-test.ts +119 -0
- package/src/utils/collections/__tests__/sets-test.ts +17 -0
- package/src/utils/collections/maps.ts +7 -8
- package/src/utils/collections/sets.ts +3 -0
- package/src/utils/mergeEntityMutationTriggerConfigurations.ts +5 -5
- package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.d.ts +0 -1
- package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.js +0 -242
- package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.js.map +0 -1
- package/build/__tests__/AuthorizationResultBasedEntityLoader-constructor-test.d.ts +0 -26
- package/build/__tests__/AuthorizationResultBasedEntityLoader-constructor-test.js +0 -110
- package/build/__tests__/AuthorizationResultBasedEntityLoader-constructor-test.js.map +0 -1
- package/build/__tests__/AuthorizationResultBasedEntityLoader-test.d.ts +0 -1
- package/build/__tests__/AuthorizationResultBasedEntityLoader-test.js +0 -401
- package/build/__tests__/AuthorizationResultBasedEntityLoader-test.js.map +0 -1
- package/build/__tests__/ComposedCacheAdapter-test.d.ts +0 -1
- package/build/__tests__/ComposedCacheAdapter-test.js +0 -229
- package/build/__tests__/ComposedCacheAdapter-test.js.map +0 -1
- package/build/__tests__/ComposedSecondaryEntityCache-test.d.ts +0 -1
- package/build/__tests__/ComposedSecondaryEntityCache-test.js +0 -66
- package/build/__tests__/ComposedSecondaryEntityCache-test.js.map +0 -1
- package/build/__tests__/EnforcingEntityAssociationLoader-test.d.ts +0 -1
- package/build/__tests__/EnforcingEntityAssociationLoader-test.js +0 -115
- package/build/__tests__/EnforcingEntityAssociationLoader-test.js.map +0 -1
- package/build/__tests__/EnforcingEntityLoader-test.d.ts +0 -1
- package/build/__tests__/EnforcingEntityLoader-test.js +0 -253
- package/build/__tests__/EnforcingEntityLoader-test.js.map +0 -1
- package/build/__tests__/Entity-test.d.ts +0 -1
- package/build/__tests__/Entity-test.js +0 -94
- package/build/__tests__/Entity-test.js.map +0 -1
- package/build/__tests__/EntityAssociationLoader-test.d.ts +0 -1
- package/build/__tests__/EntityAssociationLoader-test.js +0 -30
- package/build/__tests__/EntityAssociationLoader-test.js.map +0 -1
- package/build/__tests__/EntityCommonUseCases-test.d.ts +0 -1
- package/build/__tests__/EntityCommonUseCases-test.js +0 -146
- package/build/__tests__/EntityCommonUseCases-test.js.map +0 -1
- package/build/__tests__/EntityCompanion-test.d.ts +0 -1
- package/build/__tests__/EntityCompanion-test.js +0 -77
- package/build/__tests__/EntityCompanion-test.js.map +0 -1
- package/build/__tests__/EntityCompanionProvider-test.d.ts +0 -1
- package/build/__tests__/EntityCompanionProvider-test.js +0 -54
- package/build/__tests__/EntityCompanionProvider-test.js.map +0 -1
- package/build/__tests__/EntityConfiguration-test.d.ts +0 -1
- package/build/__tests__/EntityConfiguration-test.js +0 -103
- package/build/__tests__/EntityConfiguration-test.js.map +0 -1
- package/build/__tests__/EntityDatabaseAdapter-test.d.ts +0 -1
- package/build/__tests__/EntityDatabaseAdapter-test.js +0 -146
- package/build/__tests__/EntityDatabaseAdapter-test.js.map +0 -1
- package/build/__tests__/EntityEdges-test.d.ts +0 -1
- package/build/__tests__/EntityEdges-test.js +0 -723
- package/build/__tests__/EntityEdges-test.js.map +0 -1
- package/build/__tests__/EntityFields-test.d.ts +0 -1
- package/build/__tests__/EntityFields-test.js +0 -63
- package/build/__tests__/EntityFields-test.js.map +0 -1
- package/build/__tests__/EntityLoader-test.d.ts +0 -1
- package/build/__tests__/EntityLoader-test.js +0 -36
- package/build/__tests__/EntityLoader-test.js.map +0 -1
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.d.ts +0 -1
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +0 -73
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +0 -1
- package/build/__tests__/EntityMutator-test.d.ts +0 -1
- package/build/__tests__/EntityMutator-test.js +0 -741
- package/build/__tests__/EntityMutator-test.js.map +0 -1
- package/build/__tests__/EntityPrivacyPolicy-test.d.ts +0 -1
- package/build/__tests__/EntityPrivacyPolicy-test.js +0 -463
- package/build/__tests__/EntityPrivacyPolicy-test.js.map +0 -1
- package/build/__tests__/EntityQueryContext-test.d.ts +0 -1
- package/build/__tests__/EntityQueryContext-test.js +0 -116
- package/build/__tests__/EntityQueryContext-test.js.map +0 -1
- package/build/__tests__/EntitySecondaryCacheLoader-test.d.ts +0 -1
- package/build/__tests__/EntitySecondaryCacheLoader-test.js +0 -60
- package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +0 -1
- package/build/__tests__/EntitySelfReferentialEdges-test.d.ts +0 -1
- package/build/__tests__/EntitySelfReferentialEdges-test.js +0 -201
- package/build/__tests__/EntitySelfReferentialEdges-test.js.map +0 -1
- package/build/__tests__/GenericEntityCacheAdapter-test.d.ts +0 -1
- package/build/__tests__/GenericEntityCacheAdapter-test.js +0 -80
- package/build/__tests__/GenericEntityCacheAdapter-test.js.map +0 -1
- package/build/__tests__/ReadonlyEntity-test.d.ts +0 -1
- package/build/__tests__/ReadonlyEntity-test.js +0 -211
- package/build/__tests__/ReadonlyEntity-test.js.map +0 -1
- package/build/__tests__/ViewerContext-test.d.ts +0 -1
- package/build/__tests__/ViewerContext-test.js +0 -30
- package/build/__tests__/ViewerContext-test.js.map +0 -1
- package/build/__tests__/ViewerScopedEntityCompanion-test.d.ts +0 -1
- package/build/__tests__/ViewerScopedEntityCompanion-test.js +0 -20
- package/build/__tests__/ViewerScopedEntityCompanion-test.js.map +0 -1
- package/build/__tests__/ViewerScopedEntityCompanionProvider-test.d.ts +0 -1
- package/build/__tests__/ViewerScopedEntityCompanionProvider-test.js +0 -20
- package/build/__tests__/ViewerScopedEntityCompanionProvider-test.js.map +0 -1
- package/build/__tests__/ViewerScopedEntityLoaderFactory-test.d.ts +0 -1
- package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js +0 -23
- package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js.map +0 -1
- package/build/__tests__/ViewerScopedEntityMutatorFactory-test.d.ts +0 -1
- package/build/__tests__/ViewerScopedEntityMutatorFactory-test.js +0 -22
- package/build/__tests__/ViewerScopedEntityMutatorFactory-test.js.map +0 -1
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.d.ts +0 -1
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +0 -123
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +0 -1
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.d.ts +0 -1
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +0 -121
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +0 -1
- package/build/__tests__/entityUtils-test.d.ts +0 -1
- package/build/__tests__/entityUtils-test.js +0 -87
- package/build/__tests__/entityUtils-test.js.map +0 -1
- package/build/internal/__tests__/EntityDataManager-test.d.ts +0 -1
- package/build/internal/__tests__/EntityDataManager-test.js +0 -373
- package/build/internal/__tests__/EntityDataManager-test.js.map +0 -1
- package/build/internal/__tests__/EntityFieldTransformationUtils-test.d.ts +0 -1
- package/build/internal/__tests__/EntityFieldTransformationUtils-test.js +0 -136
- package/build/internal/__tests__/EntityFieldTransformationUtils-test.js.map +0 -1
- package/build/internal/__tests__/ReadThroughEntityCache-test.d.ts +0 -1
- package/build/internal/__tests__/ReadThroughEntityCache-test.js +0 -206
- package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +0 -1
- package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.d.ts +0 -1
- package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js +0 -21
- package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js.map +0 -1
- package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.d.ts +0 -1
- package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js +0 -21
- package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js.map +0 -1
- package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.d.ts +0 -1
- package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js +0 -21
- package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js.map +0 -1
- package/build/testfixtures/DateIDTestEntity.d.ts +0 -19
- package/build/testfixtures/DateIDTestEntity.js +0 -48
- package/build/testfixtures/DateIDTestEntity.js.map +0 -1
- package/build/testfixtures/SimpleTestEntity.d.ts +0 -20
- package/build/testfixtures/SimpleTestEntity.js +0 -48
- package/build/testfixtures/SimpleTestEntity.js.map +0 -1
- package/build/testfixtures/TestEntity.d.ts +0 -30
- package/build/testfixtures/TestEntity.js +0 -93
- package/build/testfixtures/TestEntity.js.map +0 -1
- package/build/testfixtures/TestEntity2.d.ts +0 -20
- package/build/testfixtures/TestEntity2.js +0 -51
- package/build/testfixtures/TestEntity2.js.map +0 -1
- package/build/testfixtures/TestEntityNumberKey.d.ts +0 -19
- package/build/testfixtures/TestEntityNumberKey.js +0 -48
- package/build/testfixtures/TestEntityNumberKey.js.map +0 -1
- package/build/testfixtures/TestEntityWithMutationTriggers.d.ts +0 -36
- package/build/testfixtures/TestEntityWithMutationTriggers.js +0 -82
- package/build/testfixtures/TestEntityWithMutationTriggers.js.map +0 -1
- package/build/testfixtures/TestViewerContext.d.ts +0 -3
- package/build/testfixtures/TestViewerContext.js +0 -10
- package/build/testfixtures/TestViewerContext.js.map +0 -1
- package/build/utils/__tests__/EntityPrivacyUtils-test.d.ts +0 -1
- package/build/utils/__tests__/EntityPrivacyUtils-test.js +0 -486
- package/build/utils/__tests__/EntityPrivacyUtils-test.js.map +0 -1
- package/build/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.d.ts +0 -1
- package/build/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.js +0 -178
- package/build/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.js.map +0 -1
- package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.d.ts +0 -1
- package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js +0 -26
- package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js.map +0 -1
- package/build/utils/collections/__tests__/maps-test.d.ts +0 -1
- package/build/utils/collections/__tests__/maps-test.js +0 -120
- package/build/utils/collections/__tests__/maps-test.js.map +0 -1
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.d.ts +0 -28
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.js +0 -52
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +0 -1
- package/build/utils/testing/StubCacheAdapter.d.ts +0 -27
- package/build/utils/testing/StubCacheAdapter.js +0 -86
- package/build/utils/testing/StubCacheAdapter.js.map +0 -1
- package/build/utils/testing/StubDatabaseAdapter.d.ts +0 -25
- package/build/utils/testing/StubDatabaseAdapter.js +0 -191
- package/build/utils/testing/StubDatabaseAdapter.js.map +0 -1
- package/build/utils/testing/StubDatabaseAdapterProvider.d.ts +0 -7
- package/build/utils/testing/StubDatabaseAdapterProvider.js +0 -14
- package/build/utils/testing/StubDatabaseAdapterProvider.js.map +0 -1
- package/build/utils/testing/StubQueryContextProvider.d.ts +0 -7
- package/build/utils/testing/StubQueryContextProvider.js +0 -19
- package/build/utils/testing/StubQueryContextProvider.js.map +0 -1
- package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.d.ts +0 -1
- package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js +0 -42
- package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js.map +0 -1
- package/build/utils/testing/__tests__/StubDatabaseAdapter-test.d.ts +0 -1
- package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js +0 -402
- package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js.map +0 -1
- package/build/utils/testing/createUnitTestEntityCompanionProvider.d.ts +0 -7
- package/build/utils/testing/createUnitTestEntityCompanionProvider.js +0 -36
- package/build/utils/testing/createUnitTestEntityCompanionProvider.js.map +0 -1
- package/build/utils/testing/describeFieldTestCase.d.ts +0 -2
- package/build/utils/testing/describeFieldTestCase.js +0 -18
- package/build/utils/testing/describeFieldTestCase.js.map +0 -1
- package/src/testfixtures/DateIDTestEntity.ts +0 -59
- package/src/testfixtures/TestEntityNumberKey.ts +0 -59
- package/src/utils/testing/StubCacheAdapter.ts +0 -122
- package/src/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.ts +0 -42
- package/src/utils/testing/__tests__/StubDatabaseAdapter-test.ts +0 -548
- /package/src/utils/{testing → __testfixtures__}/StubQueryContextProvider.ts +0 -0
- /package/src/utils/{testing → __testfixtures__}/createUnitTestEntityCompanionProvider.ts +0 -0
|
@@ -20,8 +20,11 @@ export interface FieldTransformer<T> {
|
|
|
20
20
|
*/
|
|
21
21
|
export type FieldTransformerMap = Map<string, FieldTransformer<any>>;
|
|
22
22
|
|
|
23
|
-
export const getDatabaseFieldForEntityField = <
|
|
24
|
-
|
|
23
|
+
export const getDatabaseFieldForEntityField = <
|
|
24
|
+
TFields extends Record<string, any>,
|
|
25
|
+
TIDField extends keyof TFields,
|
|
26
|
+
>(
|
|
27
|
+
entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
25
28
|
entityField: keyof TFields,
|
|
26
29
|
): string => {
|
|
27
30
|
const databaseField = entityConfiguration.entityToDBFieldsKeyMapping.get(entityField);
|
|
@@ -29,8 +32,11 @@ export const getDatabaseFieldForEntityField = <TFields extends Record<string, an
|
|
|
29
32
|
return databaseField;
|
|
30
33
|
};
|
|
31
34
|
|
|
32
|
-
export const transformDatabaseObjectToFields = <
|
|
33
|
-
|
|
35
|
+
export const transformDatabaseObjectToFields = <
|
|
36
|
+
TFields extends Record<string, any>,
|
|
37
|
+
TIDField extends keyof TFields,
|
|
38
|
+
>(
|
|
39
|
+
entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
34
40
|
fieldTransformerMap: FieldTransformerMap,
|
|
35
41
|
databaseObject: { [key: string]: any },
|
|
36
42
|
): Readonly<TFields> => {
|
|
@@ -50,8 +56,11 @@ export const transformDatabaseObjectToFields = <TFields extends Record<string, a
|
|
|
50
56
|
return fields;
|
|
51
57
|
};
|
|
52
58
|
|
|
53
|
-
export const transformFieldsToDatabaseObject = <
|
|
54
|
-
|
|
59
|
+
export const transformFieldsToDatabaseObject = <
|
|
60
|
+
TFields extends Record<string, any>,
|
|
61
|
+
TIDField extends keyof TFields,
|
|
62
|
+
>(
|
|
63
|
+
entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
55
64
|
fieldTransformerMap: FieldTransformerMap,
|
|
56
65
|
fields: Readonly<Partial<TFields>>,
|
|
57
66
|
): object => {
|
|
@@ -70,8 +79,11 @@ export const transformFieldsToDatabaseObject = <TFields extends Record<string, a
|
|
|
70
79
|
return databaseObject;
|
|
71
80
|
};
|
|
72
81
|
|
|
73
|
-
export const transformCacheObjectToFields = <
|
|
74
|
-
|
|
82
|
+
export const transformCacheObjectToFields = <
|
|
83
|
+
TFields extends Record<string, any>,
|
|
84
|
+
TIDField extends keyof TFields,
|
|
85
|
+
>(
|
|
86
|
+
entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
75
87
|
fieldTransformerMap: FieldTransformerMap,
|
|
76
88
|
cacheObject: { [key: string]: any },
|
|
77
89
|
): Readonly<TFields> => {
|
|
@@ -88,8 +100,11 @@ export const transformCacheObjectToFields = <TFields extends Record<string, any>
|
|
|
88
100
|
return fields;
|
|
89
101
|
};
|
|
90
102
|
|
|
91
|
-
export const transformFieldsToCacheObject = <
|
|
92
|
-
|
|
103
|
+
export const transformFieldsToCacheObject = <
|
|
104
|
+
TFields extends Record<string, any>,
|
|
105
|
+
TIDField extends keyof TFields,
|
|
106
|
+
>(
|
|
107
|
+
entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
93
108
|
fieldTransformerMap: FieldTransformerMap,
|
|
94
109
|
fields: Readonly<Partial<TFields>>,
|
|
95
110
|
): object => {
|
|
@@ -109,8 +124,9 @@ export const transformFieldsToCacheObject = <TFields extends Record<string, any>
|
|
|
109
124
|
const maybeTransformDatabaseValueToFieldValue = <
|
|
110
125
|
TFields extends Record<string, any>,
|
|
111
126
|
N extends keyof TFields,
|
|
127
|
+
TIDField extends keyof TFields,
|
|
112
128
|
>(
|
|
113
|
-
entityConfiguration: EntityConfiguration<TFields>,
|
|
129
|
+
entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
114
130
|
fieldTransformerMap: FieldTransformerMap,
|
|
115
131
|
fieldName: N,
|
|
116
132
|
value: any,
|
|
@@ -126,8 +142,9 @@ const maybeTransformDatabaseValueToFieldValue = <
|
|
|
126
142
|
const maybeTransformFieldValueToDatabaseValue = <
|
|
127
143
|
TFields extends Record<string, any>,
|
|
128
144
|
N extends keyof TFields,
|
|
145
|
+
TIDField extends keyof TFields,
|
|
129
146
|
>(
|
|
130
|
-
entityConfiguration: EntityConfiguration<TFields>,
|
|
147
|
+
entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
131
148
|
fieldTransformerMap: FieldTransformerMap,
|
|
132
149
|
fieldName: N,
|
|
133
150
|
value: TFields[N],
|
|
@@ -141,8 +158,9 @@ const maybeTransformFieldValueToDatabaseValue = <
|
|
|
141
158
|
const maybeTransformCacheValueToFieldValue = <
|
|
142
159
|
TFields extends Record<string, any>,
|
|
143
160
|
N extends keyof TFields,
|
|
161
|
+
TIDField extends keyof TFields,
|
|
144
162
|
>(
|
|
145
|
-
entityConfiguration: EntityConfiguration<TFields>,
|
|
163
|
+
entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
146
164
|
fieldTransformerMap: FieldTransformerMap,
|
|
147
165
|
fieldName: N,
|
|
148
166
|
value: any,
|
|
@@ -160,8 +178,9 @@ const maybeTransformCacheValueToFieldValue = <
|
|
|
160
178
|
const maybeTransformFieldValueToCacheValue = <
|
|
161
179
|
TFields extends Record<string, any>,
|
|
162
180
|
N extends keyof TFields,
|
|
181
|
+
TIDField extends keyof TFields,
|
|
163
182
|
>(
|
|
164
|
-
entityConfiguration: EntityConfiguration<TFields>,
|
|
183
|
+
entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
165
184
|
fieldTransformerMap: FieldTransformerMap,
|
|
166
185
|
fieldName: N,
|
|
167
186
|
value: TFields[N],
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import EntityConfiguration from '../EntityConfiguration';
|
|
2
|
+
import { ISerializable, SerializableKeyMap } from '../utils/collections/SerializableKeyMap';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Load method type identifier of a load key. Used for keying data loaders and identification in metrics.
|
|
6
|
+
*/
|
|
7
|
+
export enum EntityLoadMethodType {
|
|
8
|
+
/**
|
|
9
|
+
* Load method type for loading entities by single fieldName and fieldValue(s).
|
|
10
|
+
*/
|
|
11
|
+
SINGLE = 'single',
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Load method type for loading entities by composite field.
|
|
15
|
+
*/
|
|
16
|
+
COMPOSITE = 'composite',
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Interface responsible for defining how the key and corresponding load values behave in the data manager, cache adapter,
|
|
21
|
+
* and database adapter during entity field loading.
|
|
22
|
+
*/
|
|
23
|
+
export interface IEntityLoadKey<
|
|
24
|
+
TFields extends Record<string, any>,
|
|
25
|
+
TIDField extends keyof TFields,
|
|
26
|
+
TSerializedLoadValue,
|
|
27
|
+
TLoadValue extends IEntityLoadValue<TSerializedLoadValue>,
|
|
28
|
+
> {
|
|
29
|
+
toString(): string;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Vends a new empty load value map with a key type corresponding to the load value type of this load key.
|
|
33
|
+
*
|
|
34
|
+
* @returns A new empty load value map.
|
|
35
|
+
*/
|
|
36
|
+
vendNewLoadValueMap<V>(): LoadValueMap<TSerializedLoadValue, TLoadValue, V>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Determines if this key is cacheable in cache adapters according to the entity configuration.
|
|
40
|
+
*
|
|
41
|
+
* @param entityConfiguration - The entity configuration to check.
|
|
42
|
+
* @returns Boolean indicating whether this key is cacheable.
|
|
43
|
+
*/
|
|
44
|
+
isCacheable(entityConfiguration: EntityConfiguration<TFields, TIDField>): boolean;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Creates cache key parts for this key and a load value given an entity configuration.
|
|
48
|
+
* These parts will be included as part of the cache key.
|
|
49
|
+
*
|
|
50
|
+
* @param entityConfiguration - The entity configuration used to derive cache key parts.
|
|
51
|
+
* @param value - The load value for which to create cache key parts for.
|
|
52
|
+
* @returns An object containing the cache key type and parts.
|
|
53
|
+
*/
|
|
54
|
+
createCacheKeyPartsForLoadValue(
|
|
55
|
+
entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
56
|
+
value: TLoadValue,
|
|
57
|
+
): readonly string[];
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Gets the load method type of this key. Used as part of cache keys and data loader keys.
|
|
61
|
+
*/
|
|
62
|
+
getLoadMethodType(): EntityLoadMethodType;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Gets the data loader key for this key. For single field keys, this is the field name. For composite keys, this is a
|
|
66
|
+
* unique identifier for the composite key.
|
|
67
|
+
*/
|
|
68
|
+
getDataManagerDataLoaderKey(): string;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Serialize a load value for use in the data manager data loader as the dataloader value key.
|
|
72
|
+
*/
|
|
73
|
+
serializeLoadValue(value: TLoadValue): TSerializedLoadValue;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Deserialize a load value for use in the data manager data loader as the dataloader value key.
|
|
77
|
+
*/
|
|
78
|
+
deserializeLoadValue(value: TSerializedLoadValue): TLoadValue;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Validate that that the load values adhere to the typescript types at runtime in order to
|
|
82
|
+
* prevent inadvertently passing invalid values to the data loader, cache adapter, or database adapter.
|
|
83
|
+
* @param values - The load values to validate.
|
|
84
|
+
* @param entityClassName - The name of the entity class to which the load values belong (for error message only).
|
|
85
|
+
*/
|
|
86
|
+
validateRuntimeLoadValuesForDataManagerDataLoader(
|
|
87
|
+
values: readonly TLoadValue[],
|
|
88
|
+
entityClassName: string,
|
|
89
|
+
): void;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get the database columns for this key given an entity configuration.
|
|
93
|
+
*
|
|
94
|
+
* @param entityConfiguration - The entity configuration.
|
|
95
|
+
* @returns An array of database column names.
|
|
96
|
+
*/
|
|
97
|
+
getDatabaseColumns(
|
|
98
|
+
entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
99
|
+
): readonly string[];
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Get the database values corresponding to the database columns for this key for a load value.
|
|
103
|
+
*
|
|
104
|
+
* @param value - The load value.
|
|
105
|
+
* @returns An array of database values.
|
|
106
|
+
*/
|
|
107
|
+
getDatabaseValues(value: TLoadValue): readonly any[];
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get the load value for an entity fields object from the database.
|
|
111
|
+
*
|
|
112
|
+
* @param object - The entity fields object.
|
|
113
|
+
* @returns The load value for the object or null if the load value would be invalid for the object (for example, if the value is null).
|
|
114
|
+
*/
|
|
115
|
+
getLoadValueForObject(object: Readonly<TFields>): TLoadValue | null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Interface for a load value corresponding to a load key.
|
|
120
|
+
*/
|
|
121
|
+
export interface IEntityLoadValue<TSerialized> extends ISerializable<TSerialized> {
|
|
122
|
+
toString(): string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Map from load value interface to value.
|
|
127
|
+
*/
|
|
128
|
+
export abstract class LoadValueMap<
|
|
129
|
+
TSerialized,
|
|
130
|
+
TLoadValue extends IEntityLoadValue<TSerialized>,
|
|
131
|
+
V,
|
|
132
|
+
> extends SerializableKeyMap<TSerialized, TLoadValue, V> {}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Load pair type for a load key and load value.
|
|
136
|
+
*/
|
|
137
|
+
export type LoadPair<
|
|
138
|
+
TFields extends Record<string, any>,
|
|
139
|
+
TIDField extends keyof TFields,
|
|
140
|
+
TLoadKey extends IEntityLoadKey<TFields, TIDField, TSerializedLoadValue, TLoadValue>,
|
|
141
|
+
TSerializedLoadValue,
|
|
142
|
+
TLoadValue extends IEntityLoadValue<TSerializedLoadValue>,
|
|
143
|
+
> = readonly [TLoadKey, TLoadValue];
|
|
@@ -13,13 +13,16 @@ import IEntityMetricsAdapter from '../metrics/IEntityMetricsAdapter';
|
|
|
13
13
|
* table. Note that one instance is shared amongst all entities that read from
|
|
14
14
|
* the table to ensure cross-entity data consistency.
|
|
15
15
|
*/
|
|
16
|
-
export default class EntityTableDataCoordinator<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
export default class EntityTableDataCoordinator<
|
|
17
|
+
TFields extends Record<string, any>,
|
|
18
|
+
TIDField extends keyof TFields,
|
|
19
|
+
> {
|
|
20
|
+
readonly databaseAdapter: EntityDatabaseAdapter<TFields, TIDField>;
|
|
21
|
+
readonly cacheAdapter: IEntityCacheAdapter<TFields, TIDField>;
|
|
22
|
+
readonly dataManager: EntityDataManager<TFields, TIDField>;
|
|
20
23
|
|
|
21
24
|
constructor(
|
|
22
|
-
readonly entityConfiguration: EntityConfiguration<TFields>,
|
|
25
|
+
readonly entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
23
26
|
databaseAdapterProvider: IEntityDatabaseAdapterProvider,
|
|
24
27
|
cacheAdapterProvider: IEntityCacheAdapterProvider,
|
|
25
28
|
private readonly queryContextProvider: EntityQueryContextProvider,
|
|
@@ -2,6 +2,7 @@ import invariant from 'invariant';
|
|
|
2
2
|
|
|
3
3
|
import EntityConfiguration from '../EntityConfiguration';
|
|
4
4
|
import IEntityCacheAdapter from '../IEntityCacheAdapter';
|
|
5
|
+
import { IEntityLoadKey, IEntityLoadValue } from './EntityLoadInterfaces';
|
|
5
6
|
import { filterMap } from '../utils/collections/maps';
|
|
6
7
|
|
|
7
8
|
export enum CacheStatus {
|
|
@@ -10,7 +11,7 @@ export enum CacheStatus {
|
|
|
10
11
|
NEGATIVE,
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
export type CacheLoadResult<TFields
|
|
14
|
+
export type CacheLoadResult<TFields extends Record<string, any>> =
|
|
14
15
|
| {
|
|
15
16
|
status: CacheStatus.HIT;
|
|
16
17
|
item: Readonly<TFields>;
|
|
@@ -26,52 +27,63 @@ export type CacheLoadResult<TFields> =
|
|
|
26
27
|
* A read-through entity cache is responsible for coordinating EntityDatabaseAdapter and
|
|
27
28
|
* EntityCacheAdapter within the EntityDataManager.
|
|
28
29
|
*/
|
|
29
|
-
export default class ReadThroughEntityCache<
|
|
30
|
+
export default class ReadThroughEntityCache<
|
|
31
|
+
TFields extends Record<string, any>,
|
|
32
|
+
TIDField extends keyof TFields,
|
|
33
|
+
> {
|
|
30
34
|
constructor(
|
|
31
|
-
private readonly entityConfiguration: EntityConfiguration<TFields>,
|
|
32
|
-
private readonly entityCacheAdapter: IEntityCacheAdapter<TFields>,
|
|
35
|
+
private readonly entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
36
|
+
private readonly entityCacheAdapter: IEntityCacheAdapter<TFields, TIDField>,
|
|
33
37
|
) {}
|
|
34
38
|
|
|
35
|
-
private
|
|
36
|
-
|
|
39
|
+
private isLoadKeyCacheable<
|
|
40
|
+
TLoadKey extends IEntityLoadKey<TFields, TIDField, TSerializedLoadValue, TLoadValue>,
|
|
41
|
+
TSerializedLoadValue,
|
|
42
|
+
TLoadValue extends IEntityLoadValue<TSerializedLoadValue>,
|
|
43
|
+
>(key: TLoadKey): boolean {
|
|
44
|
+
return key.isCacheable(this.entityConfiguration);
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
/**
|
|
40
48
|
* Read-through cache function. Steps:
|
|
41
49
|
*
|
|
42
|
-
* 1. Check for cached (
|
|
43
|
-
* 2. Query the fetcher for
|
|
50
|
+
* 1. Check for cached (key, value) objects
|
|
51
|
+
* 2. Query the fetcher for values not in the cache
|
|
44
52
|
* 3. Cache the results from the fetcher
|
|
45
53
|
* 4. Negatively cache anything missing from the fetcher
|
|
46
54
|
* 5. Return the full set of data for the query.
|
|
47
55
|
*
|
|
48
|
-
* If cache is not applicable for
|
|
56
|
+
* If cache is not applicable for key, return results from fetcher.
|
|
49
57
|
*
|
|
50
|
-
* @param
|
|
51
|
-
* @param
|
|
52
|
-
* @param fetcher - closure used to provide underlying data source objects for
|
|
53
|
-
* @returns map from
|
|
58
|
+
* @param key - load key being queried
|
|
59
|
+
* @param values - load values being queried
|
|
60
|
+
* @param fetcher - closure used to provide underlying data source objects for key and fetcherValues
|
|
61
|
+
* @returns map from value to objects that match the query for that value
|
|
54
62
|
*/
|
|
55
|
-
public async readManyThroughAsync<
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
public async readManyThroughAsync<
|
|
64
|
+
TLoadKey extends IEntityLoadKey<TFields, TIDField, TSerializedLoadValue, TLoadValue>,
|
|
65
|
+
TSerializedLoadValue,
|
|
66
|
+
TLoadValue extends IEntityLoadValue<TSerializedLoadValue>,
|
|
67
|
+
>(
|
|
68
|
+
key: TLoadKey,
|
|
69
|
+
values: readonly TLoadValue[],
|
|
58
70
|
fetcher: (
|
|
59
|
-
|
|
60
|
-
) => Promise<ReadonlyMap<
|
|
61
|
-
): Promise<ReadonlyMap<
|
|
62
|
-
// return normal fetch when cache by
|
|
63
|
-
if (!this.
|
|
64
|
-
return await fetcher(
|
|
71
|
+
fetcherValues: readonly TLoadValue[],
|
|
72
|
+
) => Promise<ReadonlyMap<TLoadValue, readonly Readonly<TFields>[]>>,
|
|
73
|
+
): Promise<ReadonlyMap<TLoadValue, readonly Readonly<TFields>[]>> {
|
|
74
|
+
// return normal fetch when cache by key not supported
|
|
75
|
+
if (!this.isLoadKeyCacheable(key)) {
|
|
76
|
+
return await fetcher(values);
|
|
65
77
|
}
|
|
66
78
|
|
|
67
|
-
const cacheLoadResults = await this.entityCacheAdapter.loadManyAsync(
|
|
79
|
+
const cacheLoadResults = await this.entityCacheAdapter.loadManyAsync(key, values);
|
|
68
80
|
|
|
69
81
|
invariant(
|
|
70
|
-
cacheLoadResults.size ===
|
|
71
|
-
`${this.constructor.name} loadMany should return a result for each
|
|
82
|
+
cacheLoadResults.size === values.length,
|
|
83
|
+
`${this.constructor.name} loadMany should return a result for each value`,
|
|
72
84
|
);
|
|
73
85
|
|
|
74
|
-
const
|
|
86
|
+
const valuesToFetchFromDB = Array.from(
|
|
75
87
|
filterMap(
|
|
76
88
|
cacheLoadResults,
|
|
77
89
|
(cacheLoadResult) => cacheLoadResult.status === CacheStatus.MISS,
|
|
@@ -79,45 +91,45 @@ export default class ReadThroughEntityCache<TFields extends Record<string, any>>
|
|
|
79
91
|
);
|
|
80
92
|
|
|
81
93
|
// put transformed cache hits in result map
|
|
82
|
-
const results
|
|
83
|
-
cacheLoadResults.forEach((cacheLoadResult,
|
|
94
|
+
const results = key.vendNewLoadValueMap<readonly Readonly<TFields>[]>();
|
|
95
|
+
cacheLoadResults.forEach((cacheLoadResult, value) => {
|
|
84
96
|
if (cacheLoadResult.status === CacheStatus.HIT) {
|
|
85
|
-
results.set(
|
|
97
|
+
results.set(value, [cacheLoadResult.item]);
|
|
86
98
|
}
|
|
87
99
|
});
|
|
88
100
|
|
|
89
101
|
// fetch any misses from DB, add DB objects to results, cache DB results, inform cache of any missing DB results
|
|
90
|
-
if (
|
|
91
|
-
const dbFetchResults = await fetcher(
|
|
102
|
+
if (valuesToFetchFromDB.length > 0) {
|
|
103
|
+
const dbFetchResults = await fetcher(valuesToFetchFromDB);
|
|
92
104
|
|
|
93
|
-
const
|
|
105
|
+
const valueDBMisses = valuesToFetchFromDB.filter((fv) => {
|
|
94
106
|
const objectsFromFulfillerForFv = dbFetchResults.get(fv);
|
|
95
107
|
return !objectsFromFulfillerForFv || objectsFromFulfillerForFv.length === 0;
|
|
96
108
|
});
|
|
97
109
|
|
|
98
|
-
const objectsToCache
|
|
99
|
-
for (const [
|
|
110
|
+
const objectsToCache = key.vendNewLoadValueMap<Readonly<TFields>>();
|
|
111
|
+
for (const [value, objects] of dbFetchResults.entries()) {
|
|
100
112
|
if (objects.length > 1) {
|
|
101
113
|
// multiple objects received for what was supposed to be a unique query, don't add to return map nor cache
|
|
102
114
|
// TODO(wschurman): emit or throw here since console may not be available
|
|
103
115
|
// eslint-disable-next-line no-console
|
|
104
116
|
console.warn(
|
|
105
|
-
`unique key ${
|
|
117
|
+
`unique key ${key} in table ${
|
|
106
118
|
this.entityConfiguration.tableName
|
|
107
|
-
} returned multiple rows for ${
|
|
119
|
+
} returned multiple rows for ${value}`,
|
|
108
120
|
);
|
|
109
121
|
continue;
|
|
110
122
|
}
|
|
111
123
|
const uniqueObject = objects[0];
|
|
112
124
|
if (uniqueObject) {
|
|
113
|
-
objectsToCache.set(
|
|
114
|
-
results.set(
|
|
125
|
+
objectsToCache.set(value, uniqueObject);
|
|
126
|
+
results.set(value, [uniqueObject]);
|
|
115
127
|
}
|
|
116
128
|
}
|
|
117
129
|
|
|
118
130
|
await Promise.all([
|
|
119
|
-
this.entityCacheAdapter.cacheManyAsync(
|
|
120
|
-
this.entityCacheAdapter.cacheDBMissesAsync(
|
|
131
|
+
this.entityCacheAdapter.cacheManyAsync(key, objectsToCache),
|
|
132
|
+
this.entityCacheAdapter.cacheDBMissesAsync(key, valueDBMisses),
|
|
121
133
|
]);
|
|
122
134
|
}
|
|
123
135
|
|
|
@@ -125,20 +137,21 @@ export default class ReadThroughEntityCache<TFields extends Record<string, any>>
|
|
|
125
137
|
}
|
|
126
138
|
|
|
127
139
|
/**
|
|
128
|
-
* Invalidate the cache for objects cached by (
|
|
140
|
+
* Invalidate the cache for objects cached by (key, value).
|
|
129
141
|
*
|
|
130
|
-
* @param
|
|
131
|
-
* @param
|
|
142
|
+
* @param key - load key to be invalidated
|
|
143
|
+
* @param values - load values to be invalidated for key
|
|
132
144
|
*/
|
|
133
|
-
public async invalidateManyAsync<
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
145
|
+
public async invalidateManyAsync<
|
|
146
|
+
TLoadKey extends IEntityLoadKey<TFields, TIDField, TSerializedLoadValue, TLoadValue>,
|
|
147
|
+
TSerializedLoadValue,
|
|
148
|
+
TLoadValue extends IEntityLoadValue<TSerializedLoadValue>,
|
|
149
|
+
>(key: TLoadKey, values: readonly TLoadValue[]): Promise<void> {
|
|
150
|
+
// no-op when cache by key not supported
|
|
151
|
+
if (!this.isLoadKeyCacheable(key)) {
|
|
139
152
|
return;
|
|
140
153
|
}
|
|
141
154
|
|
|
142
|
-
await this.entityCacheAdapter.invalidateManyAsync(
|
|
155
|
+
await this.entityCacheAdapter.invalidateManyAsync(key, values);
|
|
143
156
|
}
|
|
144
157
|
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import invariant from 'invariant';
|
|
2
|
+
|
|
3
|
+
import EntityConfiguration from '../EntityConfiguration';
|
|
4
|
+
import { getDatabaseFieldForEntityField } from './EntityFieldTransformationUtils';
|
|
5
|
+
import {
|
|
6
|
+
EntityLoadMethodType,
|
|
7
|
+
IEntityLoadKey,
|
|
8
|
+
IEntityLoadValue,
|
|
9
|
+
LoadValueMap,
|
|
10
|
+
} from './EntityLoadInterfaces';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A load key that represents a single field (fieldName) on an entity.
|
|
14
|
+
*/
|
|
15
|
+
export class SingleFieldHolder<
|
|
16
|
+
TFields extends Record<string, any>,
|
|
17
|
+
TIDField extends keyof TFields,
|
|
18
|
+
N extends keyof TFields,
|
|
19
|
+
> implements
|
|
20
|
+
IEntityLoadKey<TFields, TIDField, NonNullable<TFields[N]>, SingleFieldValueHolder<TFields, N>>
|
|
21
|
+
{
|
|
22
|
+
constructor(public readonly fieldName: N) {}
|
|
23
|
+
|
|
24
|
+
toString(): string {
|
|
25
|
+
return `SingleField(${String(this.fieldName)})`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public isCacheable(entityConfiguration: EntityConfiguration<TFields, TIDField>): boolean {
|
|
29
|
+
return entityConfiguration.cacheableKeys.has(this.fieldName);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public getDatabaseColumns(entityConfiguration: EntityConfiguration<TFields, TIDField>): string[] {
|
|
33
|
+
return [getDatabaseFieldForEntityField(entityConfiguration, this.fieldName)];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getDatabaseValues(value: SingleFieldValueHolder<TFields, N>): readonly any[] {
|
|
37
|
+
return [value.fieldValue];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
getLoadValueForObject(object: Readonly<TFields>): SingleFieldValueHolder<TFields, N> | null {
|
|
41
|
+
const value = object[this.fieldName];
|
|
42
|
+
if (value === null || value === undefined) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return new SingleFieldValueHolder(value);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
createCacheKeyPartsForLoadValue(
|
|
49
|
+
entityConfiguration: EntityConfiguration<TFields, TIDField>,
|
|
50
|
+
value: SingleFieldValueHolder<TFields, N>,
|
|
51
|
+
): readonly string[] {
|
|
52
|
+
const columnName = entityConfiguration.entityToDBFieldsKeyMapping.get(this.fieldName);
|
|
53
|
+
invariant(columnName, `database field mapping missing for ${String(this.fieldName)}`);
|
|
54
|
+
return [columnName, String(value.fieldValue)];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
getLoadMethodType(): EntityLoadMethodType {
|
|
58
|
+
return EntityLoadMethodType.SINGLE;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
getDataManagerDataLoaderKey(): string {
|
|
62
|
+
return this.fieldName as string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
serializeLoadValue(value: SingleFieldValueHolder<TFields, N>): NonNullable<TFields[N]> {
|
|
66
|
+
return value.serialize();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
deserializeLoadValue(value: NonNullable<TFields[N]>): SingleFieldValueHolder<TFields, N> {
|
|
70
|
+
return SingleFieldValueHolder.deserialize(value);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
validateRuntimeLoadValuesForDataManagerDataLoader(
|
|
74
|
+
values: readonly SingleFieldValueHolder<TFields, N>[],
|
|
75
|
+
entityClassName: string,
|
|
76
|
+
): void {
|
|
77
|
+
const nullOrUndefinedValueIndex = values.findIndex(
|
|
78
|
+
(value) => value.fieldValue === null || value.fieldValue === undefined,
|
|
79
|
+
);
|
|
80
|
+
if (nullOrUndefinedValueIndex >= 0) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`Invalid load: ${entityClassName} (${String(this.fieldName)} = ${
|
|
83
|
+
values[nullOrUndefinedValueIndex]?.fieldValue
|
|
84
|
+
})`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
vendNewLoadValueMap<V>(): LoadValueMap<
|
|
90
|
+
NonNullable<TFields[N]>,
|
|
91
|
+
SingleFieldValueHolder<TFields, N>,
|
|
92
|
+
V
|
|
93
|
+
> {
|
|
94
|
+
return new SingleFieldValueHolderMap();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* A load value for a SingleFieldHolder.
|
|
100
|
+
*/
|
|
101
|
+
export class SingleFieldValueHolder<TFields extends Record<string, any>, N extends keyof TFields>
|
|
102
|
+
implements IEntityLoadValue<NonNullable<TFields[N]>>
|
|
103
|
+
{
|
|
104
|
+
constructor(public readonly fieldValue: NonNullable<TFields[N]>) {}
|
|
105
|
+
|
|
106
|
+
toString(): string {
|
|
107
|
+
return `SingleFieldValue(${String(this.fieldValue)})`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
serialize(): NonNullable<TFields[N]> {
|
|
111
|
+
return this.fieldValue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
static deserialize<TFields extends Record<string, any>, N extends keyof TFields>(
|
|
115
|
+
fieldValue: NonNullable<TFields[N]>,
|
|
116
|
+
): SingleFieldValueHolder<TFields, N> {
|
|
117
|
+
return new SingleFieldValueHolder(fieldValue);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export class SingleFieldValueHolderMap<
|
|
122
|
+
TFields extends Record<string, any>,
|
|
123
|
+
N extends keyof TFields,
|
|
124
|
+
V,
|
|
125
|
+
> extends LoadValueMap<NonNullable<TFields[N]>, SingleFieldValueHolder<TFields, N>, V> {
|
|
126
|
+
protected override deserializeKey(
|
|
127
|
+
serializedKey: NonNullable<TFields[N]>,
|
|
128
|
+
): SingleFieldValueHolder<TFields, N> {
|
|
129
|
+
return SingleFieldValueHolder.deserialize(serializedKey);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CompositeFieldHolder, CompositeFieldValueHolder } from '../CompositeFieldHolder';
|
|
2
|
+
|
|
3
|
+
describe(CompositeFieldHolder, () => {
|
|
4
|
+
it('is order-agnostic for serialization', () => {
|
|
5
|
+
const compositeFieldHolder = new CompositeFieldHolder(['field1', 'field2']);
|
|
6
|
+
const compositeFieldHolder2 = new CompositeFieldHolder(['field2', 'field1']);
|
|
7
|
+
|
|
8
|
+
expect(compositeFieldHolder.serialize()).toEqual(compositeFieldHolder2.serialize());
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
describe(CompositeFieldValueHolder, () => {
|
|
13
|
+
it('is order-agnostic for serialization', () => {
|
|
14
|
+
const compositeFieldValueHolder = new CompositeFieldValueHolder({
|
|
15
|
+
field1: 'value1',
|
|
16
|
+
field2: 'value2',
|
|
17
|
+
});
|
|
18
|
+
const compositeFieldValueHolder2 = new CompositeFieldValueHolder({
|
|
19
|
+
field2: 'value2',
|
|
20
|
+
field1: 'value1',
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(compositeFieldValueHolder.serialize()).toEqual(compositeFieldValueHolder2.serialize());
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { EntityCompositeFieldValue } from '../../EntityConfiguration';
|
|
2
|
+
import { CompositeFieldValueHolder } from '../CompositeFieldHolder';
|
|
3
|
+
import { CompositeFieldValueMap } from '../CompositeFieldValueMap';
|
|
4
|
+
|
|
5
|
+
describe(CompositeFieldValueMap, () => {
|
|
6
|
+
it('behaves like a ReadonlyMap', () => {
|
|
7
|
+
const map = new CompositeFieldValueMap([
|
|
8
|
+
[new CompositeFieldValueHolder({ a: 1, b: 'foo' }), 'foo'],
|
|
9
|
+
[new CompositeFieldValueHolder({ a: 2, b: 'bar' }), 'bar'],
|
|
10
|
+
]);
|
|
11
|
+
|
|
12
|
+
expect(map.size).toBe(2);
|
|
13
|
+
expect(map.get({ a: 1, b: 'foo' })).toBe('foo');
|
|
14
|
+
expect(map.get({ a: 2, b: 'bar' })).toBe('bar');
|
|
15
|
+
expect(map.get({ a: 3, b: 'baz' })).toBeUndefined();
|
|
16
|
+
expect(map.has({ a: 1, b: 'foo' })).toBe(true);
|
|
17
|
+
expect(map.has({ a: 3, b: 'baz' })).toBe(false);
|
|
18
|
+
|
|
19
|
+
const keys = Array.from(map.keys());
|
|
20
|
+
expect(keys).toEqual([
|
|
21
|
+
{ a: 1, b: 'foo' },
|
|
22
|
+
{ a: 2, b: 'bar' },
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
const values = Array.from(map.values());
|
|
26
|
+
expect(values).toEqual(['foo', 'bar']);
|
|
27
|
+
|
|
28
|
+
const entries2 = Array.from(map.entries());
|
|
29
|
+
expect(entries2).toEqual([
|
|
30
|
+
[{ a: 1, b: 'foo' }, 'foo'],
|
|
31
|
+
[{ a: 2, b: 'bar' }, 'bar'],
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
const forEachEntries: [EntityCompositeFieldValue<any, any>, string, typeof map][] = [];
|
|
35
|
+
map.forEach((value, key, map) => {
|
|
36
|
+
forEachEntries.push([key, value, map]);
|
|
37
|
+
});
|
|
38
|
+
expect(forEachEntries).toEqual([
|
|
39
|
+
[{ a: 1, b: 'foo' }, 'foo', map],
|
|
40
|
+
[{ a: 2, b: 'bar' }, 'bar', map],
|
|
41
|
+
]);
|
|
42
|
+
});
|
|
43
|
+
});
|