@expo/entity 0.35.0 → 0.37.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/AuthorizationResultBasedEntityLoader.d.ts +128 -0
- package/build/AuthorizationResultBasedEntityLoader.js +196 -0
- package/build/AuthorizationResultBasedEntityLoader.js.map +1 -0
- package/build/ComposedEntityCacheAdapter.js +1 -0
- package/build/ComposedEntityCacheAdapter.js.map +1 -1
- package/build/ComposedSecondaryEntityCache.js +1 -0
- package/build/ComposedSecondaryEntityCache.js.map +1 -1
- package/build/EnforcingEntityLoader.d.ts +5 -4
- package/build/EnforcingEntityLoader.js +4 -2
- package/build/EnforcingEntityLoader.js.map +1 -1
- package/build/Entity.d.ts +0 -27
- package/build/Entity.js +0 -50
- package/build/Entity.js.map +1 -1
- package/build/EntityAssociationLoader.d.ts +1 -1
- package/build/EntityAssociationLoader.js +17 -8
- package/build/EntityAssociationLoader.js.map +1 -1
- package/build/EntityCompanion.js +9 -1
- package/build/EntityCompanion.js.map +1 -1
- package/build/EntityCompanionProvider.d.ts +3 -1
- package/build/EntityCompanionProvider.js +10 -4
- package/build/EntityCompanionProvider.js.map +1 -1
- package/build/EntityConfiguration.d.ts +2 -1
- package/build/EntityConfiguration.js +19 -1
- package/build/EntityConfiguration.js.map +1 -1
- package/build/EntityDatabaseAdapter.d.ts +2 -2
- package/build/EntityDatabaseAdapter.js +5 -3
- package/build/EntityDatabaseAdapter.js.map +1 -1
- package/build/EntityFieldDefinition.d.ts +21 -10
- package/build/EntityFieldDefinition.js +8 -9
- package/build/EntityFieldDefinition.js.map +1 -1
- package/build/EntityFields.d.ts +10 -0
- package/build/EntityFields.js +15 -1
- package/build/EntityFields.js.map +1 -1
- package/build/EntityLoader.d.ts +12 -125
- package/build/EntityLoader.js +24 -239
- package/build/EntityLoader.js.map +1 -1
- package/build/EntityLoaderFactory.d.ts +1 -1
- package/build/EntityLoaderFactory.js +3 -0
- package/build/EntityLoaderFactory.js.map +1 -1
- package/build/EntityLoaderUtils.d.ts +58 -0
- package/build/EntityLoaderUtils.js +109 -0
- package/build/EntityLoaderUtils.js.map +1 -0
- package/build/EntityMutator.d.ts +1 -0
- package/build/EntityMutator.js +71 -56
- package/build/EntityMutator.js.map +1 -1
- package/build/EntityMutatorFactory.js +9 -0
- package/build/EntityMutatorFactory.js.map +1 -1
- package/build/EntityPrivacyPolicy.d.ts +11 -5
- package/build/EntityPrivacyPolicy.js +5 -7
- package/build/EntityPrivacyPolicy.js.map +1 -1
- package/build/EntityQueryContext.d.ts +2 -1
- package/build/EntityQueryContext.js +11 -6
- package/build/EntityQueryContext.js.map +1 -1
- package/build/EntitySecondaryCacheLoader.js +5 -1
- package/build/EntitySecondaryCacheLoader.js.map +1 -1
- package/build/GenericEntityCacheAdapter.js +1 -0
- package/build/GenericEntityCacheAdapter.js.map +1 -1
- package/build/GenericSecondaryEntityCache.js +2 -0
- package/build/GenericSecondaryEntityCache.js.map +1 -1
- package/build/IEntityCacheAdapterProvider.d.ts +1 -1
- package/build/IEntityDatabaseAdapterProvider.d.ts +1 -1
- package/build/ReadonlyEntity.js +5 -1
- package/build/ReadonlyEntity.js.map +1 -1
- package/build/ViewerContext.js +2 -0
- package/build/ViewerContext.js.map +1 -1
- package/build/ViewerScopedEntityCompanion.js +2 -0
- package/build/ViewerScopedEntityCompanion.js.map +1 -1
- package/build/ViewerScopedEntityCompanionProvider.d.ts +0 -1
- package/build/ViewerScopedEntityCompanionProvider.js +2 -1
- package/build/ViewerScopedEntityCompanionProvider.js.map +1 -1
- package/build/ViewerScopedEntityLoaderFactory.d.ts +1 -1
- package/build/ViewerScopedEntityLoaderFactory.js +2 -0
- package/build/ViewerScopedEntityLoaderFactory.js.map +1 -1
- package/build/ViewerScopedEntityMutatorFactory.js +2 -0
- package/build/ViewerScopedEntityMutatorFactory.js.map +1 -1
- package/build/__tests__/ComposedCacheAdapter-test.js +2 -0
- package/build/__tests__/ComposedCacheAdapter-test.js.map +1 -1
- package/build/__tests__/ComposedSecondaryEntityCache-test.js +1 -0
- package/build/__tests__/ComposedSecondaryEntityCache-test.js.map +1 -1
- package/build/__tests__/EnforcingEntityLoader-test.js +101 -113
- package/build/__tests__/EnforcingEntityLoader-test.js.map +1 -1
- package/build/__tests__/Entity-test.js +0 -132
- package/build/__tests__/Entity-test.js.map +1 -1
- package/build/__tests__/EntityAssociationLoader-test.js +6 -2
- package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
- package/build/__tests__/EntityCommonUseCases-test.js +24 -22
- package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
- package/build/__tests__/EntityCompanion-test.js +26 -3
- package/build/__tests__/EntityCompanion-test.js.map +1 -1
- package/build/__tests__/EntityConfiguration-test.js +103 -0
- package/build/__tests__/EntityConfiguration-test.js.map +1 -0
- package/build/__tests__/EntityDatabaseAdapter-test.js +6 -0
- package/build/__tests__/EntityDatabaseAdapter-test.js.map +1 -1
- package/build/__tests__/EntityEdges-test.js +61 -20
- package/build/__tests__/EntityEdges-test.js.map +1 -1
- package/build/__tests__/EntityFields-test.js +6 -0
- package/build/__tests__/EntityFields-test.js.map +1 -1
- package/build/__tests__/EntityLoader-constructor-test.js +16 -17
- package/build/__tests__/EntityLoader-constructor-test.js.map +1 -1
- package/build/__tests__/EntityLoader-test.js +74 -22
- package/build/__tests__/EntityLoader-test.js.map +1 -1
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +12 -15
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
- package/build/__tests__/EntityMutator-test.js +54 -9
- package/build/__tests__/EntityMutator-test.js.map +1 -1
- package/build/__tests__/EntityPrivacyPolicy-test.js +77 -59
- package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
- package/build/__tests__/EntityQueryContext-test.js +9 -0
- package/build/__tests__/EntityQueryContext-test.js.map +1 -1
- package/build/__tests__/EntitySelfReferentialEdges-test.js +42 -25
- package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
- package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +20 -18
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +12 -15
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
- package/build/entityUtils.d.ts +1 -1
- package/build/entityUtils.js.map +1 -1
- package/build/errors/EntityCacheAdapterError.js +2 -5
- package/build/errors/EntityCacheAdapterError.js.map +1 -1
- package/build/errors/EntityDatabaseAdapterError.js +14 -35
- package/build/errors/EntityDatabaseAdapterError.js.map +1 -1
- package/build/errors/EntityError.js +1 -0
- package/build/errors/EntityError.js.map +1 -1
- package/build/errors/EntityInvalidFieldValueError.js +2 -2
- package/build/errors/EntityInvalidFieldValueError.js.map +1 -1
- package/build/errors/EntityNotAuthorizedError.js +3 -2
- package/build/errors/EntityNotAuthorizedError.js.map +1 -1
- package/build/errors/EntityNotFoundError.js +2 -2
- package/build/errors/EntityNotFoundError.js.map +1 -1
- package/build/index.d.ts +26 -20
- package/build/index.js +38 -28
- package/build/index.js.map +1 -1
- package/build/internal/EntityDataManager.d.ts +1 -1
- package/build/internal/EntityDataManager.js +6 -1
- package/build/internal/EntityDataManager.js.map +1 -1
- package/build/internal/EntityFieldTransformationUtils.d.ts +5 -5
- package/build/internal/EntityFieldTransformationUtils.js +5 -8
- package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
- package/build/internal/EntityTableDataCoordinator.d.ts +1 -1
- package/build/internal/EntityTableDataCoordinator.js +5 -0
- package/build/internal/EntityTableDataCoordinator.js.map +1 -1
- package/build/internal/ReadThroughEntityCache.d.ts +1 -1
- package/build/internal/ReadThroughEntityCache.js +2 -0
- package/build/internal/ReadThroughEntityCache.js.map +1 -1
- package/build/internal/__tests__/EntityFieldTransformationUtils-test.js +6 -2
- package/build/internal/__tests__/EntityFieldTransformationUtils-test.js.map +1 -1
- package/build/internal/__tests__/ReadThroughEntityCache-test.js +33 -0
- package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
- package/build/metrics/IEntityMetricsAdapter.d.ts +1 -1
- package/build/rules/AlwaysAllowPrivacyPolicyRule.d.ts +1 -1
- package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysDenyPrivacyPolicyRule.d.ts +1 -1
- package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysSkipPrivacyPolicyRule.d.ts +1 -1
- package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
- package/build/rules/PrivacyPolicyRule.d.ts +1 -1
- package/build/rules/PrivacyPolicyRule.js.map +1 -1
- package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js.map +1 -1
- package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js.map +1 -1
- package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js.map +1 -1
- package/build/testfixtures/DateIDTestEntity.js +12 -15
- package/build/testfixtures/DateIDTestEntity.js.map +1 -1
- package/build/testfixtures/SimpleTestEntity.js +12 -15
- package/build/testfixtures/SimpleTestEntity.js.map +1 -1
- package/build/testfixtures/TestEntity.js +12 -15
- package/build/testfixtures/TestEntity.js.map +1 -1
- package/build/testfixtures/TestEntity2.js +12 -15
- package/build/testfixtures/TestEntity2.js.map +1 -1
- package/build/testfixtures/TestEntityNumberKey.js +12 -15
- package/build/testfixtures/TestEntityNumberKey.js.map +1 -1
- package/build/testfixtures/TestEntityWithMutationTriggers.d.ts +36 -0
- package/build/testfixtures/TestEntityWithMutationTriggers.js +82 -0
- package/build/testfixtures/TestEntityWithMutationTriggers.js.map +1 -0
- package/build/utils/EntityPrivacyUtils.d.ts +34 -0
- package/build/utils/EntityPrivacyUtils.js +160 -0
- package/build/utils/EntityPrivacyUtils.js.map +1 -0
- package/build/utils/__tests__/EntityPrivacyUtils-test.d.ts +1 -0
- package/build/utils/__tests__/EntityPrivacyUtils-test.js +395 -0
- package/build/utils/__tests__/EntityPrivacyUtils-test.js.map +1 -0
- package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.d.ts +1 -0
- package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js +26 -0
- package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js.map +1 -0
- package/build/utils/collections/maps.js.map +1 -1
- package/build/utils/mergeEntityMutationTriggerConfigurations.d.ts +4 -0
- package/build/utils/mergeEntityMutationTriggerConfigurations.js +28 -0
- package/build/utils/mergeEntityMutationTriggerConfigurations.js.map +1 -0
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.d.ts +1 -1
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +1 -1
- package/build/utils/testing/StubCacheAdapter.d.ts +3 -3
- package/build/utils/testing/StubCacheAdapter.js +3 -3
- package/build/utils/testing/StubCacheAdapter.js.map +1 -1
- package/build/utils/testing/StubDatabaseAdapter.d.ts +2 -2
- package/build/utils/testing/StubDatabaseAdapter.js +4 -2
- package/build/utils/testing/StubDatabaseAdapter.js.map +1 -1
- package/build/utils/testing/StubDatabaseAdapterProvider.d.ts +1 -1
- package/build/utils/testing/StubDatabaseAdapterProvider.js +1 -3
- package/build/utils/testing/StubDatabaseAdapterProvider.js.map +1 -1
- package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.d.ts +1 -0
- package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js +42 -0
- package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js.map +1 -0
- package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js +53 -0
- package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js.map +1 -1
- package/build/utils/testing/describeFieldTestCase.js.map +1 -1
- package/package.json +5 -4
- package/src/AuthorizationResultBasedEntityLoader.ts +297 -0
- package/src/ComposedEntityCacheAdapter.ts +6 -6
- package/src/ComposedSecondaryEntityCache.ts +8 -8
- package/src/EnforcingEntityLoader.ts +20 -19
- package/src/Entity.ts +11 -126
- package/src/EntityAssociationLoader.ts +40 -41
- package/src/EntityCompanion.ts +8 -4
- package/src/EntityCompanionProvider.ts +24 -16
- package/src/EntityConfiguration.ts +18 -7
- package/src/EntityDatabaseAdapter.ts +41 -41
- package/src/EntityFieldDefinition.ts +28 -18
- package/src/EntityFields.ts +15 -0
- package/src/EntityLoader.ts +63 -357
- package/src/EntityLoaderFactory.ts +10 -4
- package/src/EntityLoaderUtils.ts +149 -0
- package/src/EntityMutationInfo.ts +2 -2
- package/src/EntityMutationTriggerConfiguration.ts +5 -5
- package/src/EntityMutationValidator.ts +2 -2
- package/src/EntityMutator.ts +146 -144
- package/src/EntityMutatorFactory.ts +8 -8
- package/src/EntityPrivacyPolicy.ts +78 -28
- package/src/EntityQueryContext.ts +14 -13
- package/src/EntityQueryContextProvider.ts +5 -5
- package/src/EntitySecondaryCacheLoader.ts +13 -11
- package/src/GenericEntityCacheAdapter.ts +10 -10
- package/src/GenericSecondaryEntityCache.ts +6 -6
- package/src/IEntityCacheAdapter.ts +4 -4
- package/src/IEntityCacheAdapterProvider.ts +2 -2
- package/src/IEntityDatabaseAdapterProvider.ts +2 -2
- package/src/ReadonlyEntity.ts +5 -5
- package/src/ViewerContext.ts +5 -5
- package/src/ViewerScopedEntityCompanion.ts +4 -4
- package/src/ViewerScopedEntityCompanionProvider.ts +4 -5
- package/src/ViewerScopedEntityLoaderFactory.ts +10 -4
- package/src/ViewerScopedEntityMutatorFactory.ts +5 -5
- package/src/__tests__/ComposedCacheAdapter-test.ts +12 -10
- package/src/__tests__/ComposedSecondaryEntityCache-test.ts +8 -8
- package/src/__tests__/EnforcingEntityLoader-test.ts +236 -159
- package/src/__tests__/Entity-test.ts +0 -202
- package/src/__tests__/EntityAssociationLoader-test.ts +29 -25
- package/src/__tests__/EntityCommonUseCases-test.ts +29 -13
- package/src/__tests__/EntityCompanion-test.ts +57 -5
- package/src/__tests__/EntityConfiguration-test.ts +118 -0
- package/src/__tests__/EntityDatabaseAdapter-test.ts +11 -11
- package/src/__tests__/EntityEdges-test.ts +108 -36
- package/src/__tests__/EntityFields-test.ts +14 -2
- package/src/__tests__/EntityLoader-constructor-test.ts +20 -7
- package/src/__tests__/EntityLoader-test.ts +214 -86
- package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +2 -2
- package/src/__tests__/EntityMutator-test.ts +281 -96
- package/src/__tests__/EntityPrivacyPolicy-test.ts +166 -53
- package/src/__tests__/EntityQueryContext-test.ts +30 -12
- package/src/__tests__/EntitySecondaryCacheLoader-test.ts +7 -7
- package/src/__tests__/EntitySelfReferentialEdges-test.ts +46 -26
- package/src/__tests__/GenericEntityCacheAdapter-test.ts +2 -2
- package/src/__tests__/ViewerContext-test.ts +1 -1
- package/src/__tests__/ViewerScopedEntityCompanion-test.ts +2 -2
- package/src/__tests__/ViewerScopedEntityCompanionProvider-test.ts +2 -2
- package/src/__tests__/ViewerScopedEntityLoaderFactory-test.ts +2 -1
- package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +19 -19
- package/src/__tests__/entityUtils-test.ts +2 -2
- package/src/entityUtils.ts +4 -4
- package/src/errors/EntityError.ts +4 -1
- package/src/errors/EntityInvalidFieldValueError.ts +2 -2
- package/src/errors/EntityNotAuthorizedError.ts +3 -3
- package/src/errors/EntityNotFoundError.ts +2 -2
- package/src/index.ts +26 -20
- package/src/internal/EntityDataManager.ts +24 -24
- package/src/internal/EntityFieldTransformationUtils.ts +39 -32
- package/src/internal/EntityTableDataCoordinator.ts +3 -3
- package/src/internal/ReadThroughEntityCache.ts +9 -9
- package/src/internal/__tests__/EntityDataManager-test.ts +51 -51
- package/src/internal/__tests__/EntityFieldTransformationUtils-test.ts +14 -10
- package/src/internal/__tests__/ReadThroughEntityCache-test.ts +74 -18
- package/src/metrics/EntityMetricsUtils.ts +4 -4
- package/src/metrics/IEntityMetricsAdapter.ts +1 -1
- package/src/rules/AlwaysAllowPrivacyPolicyRule.ts +9 -3
- package/src/rules/AlwaysDenyPrivacyPolicyRule.ts +9 -3
- package/src/rules/AlwaysSkipPrivacyPolicyRule.ts +9 -3
- package/src/rules/PrivacyPolicyRule.ts +9 -3
- package/src/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.ts +2 -1
- package/src/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.ts +2 -1
- package/src/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.ts +2 -1
- package/src/testfixtures/TestEntity.ts +1 -1
- package/src/testfixtures/TestEntityWithMutationTriggers.ts +156 -0
- package/src/utils/EntityPrivacyUtils.ts +325 -0
- package/src/utils/__tests__/EntityPrivacyUtils-test.ts +570 -0
- package/src/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.ts +29 -0
- package/src/utils/collections/__tests__/maps-test.ts +2 -2
- package/src/utils/collections/maps.ts +11 -11
- package/src/utils/mergeEntityMutationTriggerConfigurations.ts +44 -0
- package/src/utils/testing/PrivacyPolicyRuleTestUtils.ts +25 -22
- package/src/utils/testing/StubCacheAdapter.ts +17 -15
- package/src/utils/testing/StubDatabaseAdapter.ts +35 -30
- package/src/utils/testing/StubDatabaseAdapterProvider.ts +2 -2
- package/src/utils/testing/StubQueryContextProvider.ts +2 -2
- package/src/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.ts +42 -0
- package/src/utils/testing/__tests__/StubDatabaseAdapter-test.ts +111 -29
- package/src/utils/testing/createUnitTestEntityCompanionProvider.ts +2 -2
- package/src/utils/testing/describeFieldTestCase.ts +1 -1
- package/build/__tests__/EntityDataConfiguration-test.js +0 -68
- package/build/__tests__/EntityDataConfiguration-test.js.map +0 -1
- package/src/__tests__/EntityDataConfiguration-test.ts +0 -77
- /package/build/__tests__/{EntityDataConfiguration-test.d.ts → EntityConfiguration-test.d.ts} +0 -0
|
@@ -25,7 +25,7 @@ import { computeIfAbsent, zipToMap } from '../utils/collections/maps';
|
|
|
25
25
|
*
|
|
26
26
|
* It is also responsible for invalidating all sources of data when mutated using EntityMutator.
|
|
27
27
|
*/
|
|
28
|
-
export default class EntityDataManager<TFields
|
|
28
|
+
export default class EntityDataManager<TFields extends Record<string, any>> {
|
|
29
29
|
private readonly fieldDataLoaders: Map<
|
|
30
30
|
keyof TFields,
|
|
31
31
|
DataLoader<NonNullable<TFields[keyof TFields]>, readonly Readonly<TFields>[]>
|
|
@@ -36,30 +36,30 @@ export default class EntityDataManager<TFields> {
|
|
|
36
36
|
private readonly entityCache: ReadThroughEntityCache<TFields>,
|
|
37
37
|
private readonly queryContextProvider: EntityQueryContextProvider,
|
|
38
38
|
private readonly metricsAdapter: IEntityMetricsAdapter,
|
|
39
|
-
private readonly entityClassName: string
|
|
39
|
+
private readonly entityClassName: string,
|
|
40
40
|
) {}
|
|
41
41
|
|
|
42
42
|
private getFieldDataLoaderForFieldName<N extends keyof TFields>(
|
|
43
|
-
fieldName: N
|
|
43
|
+
fieldName: N,
|
|
44
44
|
): DataLoader<NonNullable<TFields[N]>, readonly Readonly<TFields>[]> {
|
|
45
45
|
return computeIfAbsent(this.fieldDataLoaders, fieldName, () => {
|
|
46
46
|
return new DataLoader(
|
|
47
47
|
async (
|
|
48
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
48
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
49
49
|
): Promise<readonly (readonly TFields[])[]> => {
|
|
50
50
|
const objectMap = await this.loadManyForDataLoaderByFieldEqualingAsync(
|
|
51
51
|
fieldName,
|
|
52
|
-
fieldValues
|
|
52
|
+
fieldValues,
|
|
53
53
|
);
|
|
54
54
|
return fieldValues.map((fv) => objectMap.get(fv) ?? []);
|
|
55
|
-
}
|
|
55
|
+
},
|
|
56
56
|
);
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
private async loadManyForDataLoaderByFieldEqualingAsync<N extends keyof TFields>(
|
|
61
61
|
fieldName: N,
|
|
62
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
62
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
63
63
|
): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>> {
|
|
64
64
|
this.metricsAdapter.incrementDataManagerLoadCount({
|
|
65
65
|
type: IncrementLoadCountEventType.CACHE,
|
|
@@ -78,9 +78,9 @@ export default class EntityDataManager<TFields> {
|
|
|
78
78
|
return await this.databaseAdapter.fetchManyWhereAsync(
|
|
79
79
|
this.queryContextProvider.getQueryContext(),
|
|
80
80
|
fieldName,
|
|
81
|
-
fetcherValues
|
|
81
|
+
fetcherValues,
|
|
82
82
|
);
|
|
83
|
-
}
|
|
83
|
+
},
|
|
84
84
|
);
|
|
85
85
|
}
|
|
86
86
|
|
|
@@ -95,28 +95,28 @@ export default class EntityDataManager<TFields> {
|
|
|
95
95
|
async loadManyByFieldEqualingAsync<N extends keyof TFields>(
|
|
96
96
|
queryContext: EntityQueryContext,
|
|
97
97
|
fieldName: N,
|
|
98
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
98
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
99
99
|
): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>> {
|
|
100
100
|
return await timeAndLogLoadMapEventAsync(
|
|
101
101
|
this.metricsAdapter,
|
|
102
102
|
EntityMetricsLoadType.LOAD_MANY,
|
|
103
|
-
this.entityClassName
|
|
103
|
+
this.entityClassName,
|
|
104
104
|
)(this.loadManyByFieldEqualingInternalAsync(queryContext, fieldName, fieldValues));
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
private async loadManyByFieldEqualingInternalAsync<N extends keyof TFields>(
|
|
108
108
|
queryContext: EntityQueryContext,
|
|
109
109
|
fieldName: N,
|
|
110
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
110
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
111
111
|
): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>> {
|
|
112
112
|
const nullOrUndefinedValueIndex = fieldValues.findIndex(
|
|
113
|
-
(value) => value === null || value === undefined
|
|
113
|
+
(value) => value === null || value === undefined,
|
|
114
114
|
);
|
|
115
115
|
if (nullOrUndefinedValueIndex >= 0) {
|
|
116
116
|
throw new Error(
|
|
117
117
|
`Invalid load: ${this.entityClassName} (${String(fieldName)} = ${
|
|
118
118
|
fieldValues[nullOrUndefinedValueIndex]
|
|
119
|
-
})
|
|
119
|
+
})`,
|
|
120
120
|
);
|
|
121
121
|
}
|
|
122
122
|
|
|
@@ -153,18 +153,18 @@ export default class EntityDataManager<TFields> {
|
|
|
153
153
|
async loadManyByFieldEqualityConjunctionAsync<N extends keyof TFields>(
|
|
154
154
|
queryContext: EntityQueryContext,
|
|
155
155
|
fieldEqualityOperands: FieldEqualityCondition<TFields, N>[],
|
|
156
|
-
querySelectionModifiers: QuerySelectionModifiers<TFields
|
|
156
|
+
querySelectionModifiers: QuerySelectionModifiers<TFields>,
|
|
157
157
|
): Promise<readonly Readonly<TFields>[]> {
|
|
158
158
|
return await timeAndLogLoadEventAsync(
|
|
159
159
|
this.metricsAdapter,
|
|
160
160
|
EntityMetricsLoadType.LOAD_MANY_EQUALITY_CONJUNCTION,
|
|
161
|
-
this.entityClassName
|
|
161
|
+
this.entityClassName,
|
|
162
162
|
)(
|
|
163
163
|
this.databaseAdapter.fetchManyByFieldEqualityConjunctionAsync(
|
|
164
164
|
queryContext,
|
|
165
165
|
fieldEqualityOperands,
|
|
166
|
-
querySelectionModifiers
|
|
167
|
-
)
|
|
166
|
+
querySelectionModifiers,
|
|
167
|
+
),
|
|
168
168
|
);
|
|
169
169
|
}
|
|
170
170
|
|
|
@@ -181,25 +181,25 @@ export default class EntityDataManager<TFields> {
|
|
|
181
181
|
queryContext: EntityQueryContext,
|
|
182
182
|
rawWhereClause: string,
|
|
183
183
|
bindings: any[] | object,
|
|
184
|
-
querySelectionModifiers: QuerySelectionModifiersWithOrderByRaw<TFields
|
|
184
|
+
querySelectionModifiers: QuerySelectionModifiersWithOrderByRaw<TFields>,
|
|
185
185
|
): Promise<readonly Readonly<TFields>[]> {
|
|
186
186
|
return await timeAndLogLoadEventAsync(
|
|
187
187
|
this.metricsAdapter,
|
|
188
188
|
EntityMetricsLoadType.LOAD_MANY_RAW,
|
|
189
|
-
this.entityClassName
|
|
189
|
+
this.entityClassName,
|
|
190
190
|
)(
|
|
191
191
|
this.databaseAdapter.fetchManyByRawWhereClauseAsync(
|
|
192
192
|
queryContext,
|
|
193
193
|
rawWhereClause,
|
|
194
194
|
bindings,
|
|
195
|
-
querySelectionModifiers
|
|
196
|
-
)
|
|
195
|
+
querySelectionModifiers,
|
|
196
|
+
),
|
|
197
197
|
);
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
private async invalidateManyByFieldEqualingAsync<N extends keyof TFields>(
|
|
201
201
|
fieldName: N,
|
|
202
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
202
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
203
203
|
): Promise<void> {
|
|
204
204
|
await this.entityCache.invalidateManyAsync(fieldName, fieldValues);
|
|
205
205
|
const dataLoader = this.getFieldDataLoaderForFieldName(fieldName);
|
|
@@ -222,7 +222,7 @@ export default class EntityDataManager<TFields> {
|
|
|
222
222
|
value as NonNullable<TFields[keyof TFields]>,
|
|
223
223
|
]);
|
|
224
224
|
}
|
|
225
|
-
})
|
|
225
|
+
}),
|
|
226
226
|
);
|
|
227
227
|
}
|
|
228
228
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import invariant from 'invariant';
|
|
2
|
+
import nullthrows from 'nullthrows';
|
|
2
3
|
|
|
3
4
|
import EntityConfiguration from '../EntityConfiguration';
|
|
4
5
|
|
|
@@ -19,19 +20,19 @@ export interface FieldTransformer<T> {
|
|
|
19
20
|
*/
|
|
20
21
|
export type FieldTransformerMap = Map<string, FieldTransformer<any>>;
|
|
21
22
|
|
|
22
|
-
export const getDatabaseFieldForEntityField = <TFields
|
|
23
|
+
export const getDatabaseFieldForEntityField = <TFields extends Record<string, any>>(
|
|
23
24
|
entityConfiguration: EntityConfiguration<TFields>,
|
|
24
|
-
entityField: keyof TFields
|
|
25
|
+
entityField: keyof TFields,
|
|
25
26
|
): string => {
|
|
26
27
|
const databaseField = entityConfiguration.entityToDBFieldsKeyMapping.get(entityField);
|
|
27
28
|
invariant(databaseField, `database field mapping missing for ${String(entityField)}`);
|
|
28
29
|
return databaseField!;
|
|
29
30
|
};
|
|
30
31
|
|
|
31
|
-
export const transformDatabaseObjectToFields = <TFields
|
|
32
|
+
export const transformDatabaseObjectToFields = <TFields extends Record<string, any>>(
|
|
32
33
|
entityConfiguration: EntityConfiguration<TFields>,
|
|
33
34
|
fieldTransformerMap: FieldTransformerMap,
|
|
34
|
-
databaseObject: { [key: string]: any }
|
|
35
|
+
databaseObject: { [key: string]: any },
|
|
35
36
|
): Readonly<TFields> => {
|
|
36
37
|
const fields: TFields = {} as any;
|
|
37
38
|
for (const k in databaseObject) {
|
|
@@ -42,17 +43,17 @@ export const transformDatabaseObjectToFields = <TFields>(
|
|
|
42
43
|
entityConfiguration,
|
|
43
44
|
fieldTransformerMap,
|
|
44
45
|
fieldsKey,
|
|
45
|
-
val
|
|
46
|
+
val,
|
|
46
47
|
);
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
return fields;
|
|
50
51
|
};
|
|
51
52
|
|
|
52
|
-
export const transformFieldsToDatabaseObject = <TFields
|
|
53
|
+
export const transformFieldsToDatabaseObject = <TFields extends Record<string, any>>(
|
|
53
54
|
entityConfiguration: EntityConfiguration<TFields>,
|
|
54
55
|
fieldTransformerMap: FieldTransformerMap,
|
|
55
|
-
fields: Readonly<Partial<TFields
|
|
56
|
+
fields: Readonly<Partial<TFields>>,
|
|
56
57
|
): object => {
|
|
57
58
|
const databaseObject: { [key: string]: any } = {};
|
|
58
59
|
for (const k in fields) {
|
|
@@ -63,16 +64,16 @@ export const transformFieldsToDatabaseObject = <TFields>(
|
|
|
63
64
|
entityConfiguration,
|
|
64
65
|
fieldTransformerMap,
|
|
65
66
|
k,
|
|
66
|
-
val
|
|
67
|
+
val,
|
|
67
68
|
);
|
|
68
69
|
}
|
|
69
70
|
return databaseObject;
|
|
70
71
|
};
|
|
71
72
|
|
|
72
|
-
export const transformCacheObjectToFields = <TFields
|
|
73
|
+
export const transformCacheObjectToFields = <TFields extends Record<string, any>>(
|
|
73
74
|
entityConfiguration: EntityConfiguration<TFields>,
|
|
74
75
|
fieldTransformerMap: FieldTransformerMap,
|
|
75
|
-
cacheObject: { [key: string]: any }
|
|
76
|
+
cacheObject: { [key: string]: any },
|
|
76
77
|
): Readonly<TFields> => {
|
|
77
78
|
const fields: TFields = {} as any;
|
|
78
79
|
for (const fieldsKey in cacheObject) {
|
|
@@ -81,16 +82,16 @@ export const transformCacheObjectToFields = <TFields>(
|
|
|
81
82
|
entityConfiguration,
|
|
82
83
|
fieldTransformerMap,
|
|
83
84
|
fieldsKey as keyof TFields,
|
|
84
|
-
val
|
|
85
|
+
val,
|
|
85
86
|
);
|
|
86
87
|
}
|
|
87
88
|
return fields;
|
|
88
89
|
};
|
|
89
90
|
|
|
90
|
-
export const transformFieldsToCacheObject = <TFields
|
|
91
|
+
export const transformFieldsToCacheObject = <TFields extends Record<string, any>>(
|
|
91
92
|
entityConfiguration: EntityConfiguration<TFields>,
|
|
92
93
|
fieldTransformerMap: FieldTransformerMap,
|
|
93
|
-
fields: Readonly<Partial<TFields
|
|
94
|
+
fields: Readonly<Partial<TFields>>,
|
|
94
95
|
): object => {
|
|
95
96
|
const cacheObject: { [key: string]: any } = {};
|
|
96
97
|
for (const fieldsKey in fields) {
|
|
@@ -99,49 +100,52 @@ export const transformFieldsToCacheObject = <TFields>(
|
|
|
99
100
|
entityConfiguration,
|
|
100
101
|
fieldTransformerMap,
|
|
101
102
|
fieldsKey,
|
|
102
|
-
val
|
|
103
|
+
val,
|
|
103
104
|
);
|
|
104
105
|
}
|
|
105
106
|
return cacheObject;
|
|
106
107
|
};
|
|
107
108
|
|
|
108
|
-
const maybeTransformDatabaseValueToFieldValue = <
|
|
109
|
+
const maybeTransformDatabaseValueToFieldValue = <
|
|
110
|
+
TFields extends Record<string, any>,
|
|
111
|
+
N extends keyof TFields,
|
|
112
|
+
>(
|
|
109
113
|
entityConfiguration: EntityConfiguration<TFields>,
|
|
110
114
|
fieldTransformerMap: FieldTransformerMap,
|
|
111
115
|
fieldName: N,
|
|
112
|
-
value: any
|
|
116
|
+
value: any,
|
|
113
117
|
): TFields[N] => {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
118
|
+
// this will always be non-null due to the way the dbToEntityFieldsKeyMapping is computed and this
|
|
119
|
+
// function is called conditionally
|
|
120
|
+
const fieldDefinition = nullthrows(entityConfiguration.schema.get(fieldName));
|
|
119
121
|
const transformer = fieldTransformerMap.get(fieldDefinition.constructor.name);
|
|
120
122
|
const readTransformer = transformer?.read;
|
|
121
123
|
return readTransformer ? readTransformer(value) : value;
|
|
122
124
|
};
|
|
123
125
|
|
|
124
|
-
const maybeTransformFieldValueToDatabaseValue = <
|
|
126
|
+
const maybeTransformFieldValueToDatabaseValue = <
|
|
127
|
+
TFields extends Record<string, any>,
|
|
128
|
+
N extends keyof TFields,
|
|
129
|
+
>(
|
|
125
130
|
entityConfiguration: EntityConfiguration<TFields>,
|
|
126
131
|
fieldTransformerMap: FieldTransformerMap,
|
|
127
132
|
fieldName: N,
|
|
128
|
-
value: TFields[N]
|
|
133
|
+
value: TFields[N],
|
|
129
134
|
): any => {
|
|
130
|
-
const fieldDefinition = entityConfiguration.schema.get(fieldName);
|
|
131
|
-
if (!fieldDefinition) {
|
|
132
|
-
return value;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
+
const fieldDefinition = nullthrows(entityConfiguration.schema.get(fieldName));
|
|
135
136
|
const transformer = fieldTransformerMap.get(fieldDefinition.constructor.name);
|
|
136
137
|
const writeTransformer = transformer?.write;
|
|
137
138
|
return writeTransformer ? writeTransformer(value) : value;
|
|
138
139
|
};
|
|
139
140
|
|
|
140
|
-
const maybeTransformCacheValueToFieldValue = <
|
|
141
|
+
const maybeTransformCacheValueToFieldValue = <
|
|
142
|
+
TFields extends Record<string, any>,
|
|
143
|
+
N extends keyof TFields,
|
|
144
|
+
>(
|
|
141
145
|
entityConfiguration: EntityConfiguration<TFields>,
|
|
142
146
|
fieldTransformerMap: FieldTransformerMap,
|
|
143
147
|
fieldName: N,
|
|
144
|
-
value: any
|
|
148
|
+
value: any,
|
|
145
149
|
): TFields[N] => {
|
|
146
150
|
const fieldDefinition = entityConfiguration.schema.get(fieldName);
|
|
147
151
|
if (!fieldDefinition) {
|
|
@@ -153,11 +157,14 @@ const maybeTransformCacheValueToFieldValue = <TFields, N extends keyof TFields>(
|
|
|
153
157
|
return readTransformer ? readTransformer(value) : value;
|
|
154
158
|
};
|
|
155
159
|
|
|
156
|
-
const maybeTransformFieldValueToCacheValue = <
|
|
160
|
+
const maybeTransformFieldValueToCacheValue = <
|
|
161
|
+
TFields extends Record<string, any>,
|
|
162
|
+
N extends keyof TFields,
|
|
163
|
+
>(
|
|
157
164
|
entityConfiguration: EntityConfiguration<TFields>,
|
|
158
165
|
fieldTransformerMap: FieldTransformerMap,
|
|
159
166
|
fieldName: N,
|
|
160
|
-
value: TFields[N]
|
|
167
|
+
value: TFields[N],
|
|
161
168
|
): any => {
|
|
162
169
|
const fieldDefinition = entityConfiguration.schema.get(fieldName);
|
|
163
170
|
if (!fieldDefinition) {
|
|
@@ -13,7 +13,7 @@ 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<TFields
|
|
16
|
+
export default class EntityTableDataCoordinator<TFields extends Record<string, any>> {
|
|
17
17
|
readonly databaseAdapter: EntityDatabaseAdapter<TFields>;
|
|
18
18
|
readonly cacheAdapter: IEntityCacheAdapter<TFields>;
|
|
19
19
|
readonly dataManager: EntityDataManager<TFields>;
|
|
@@ -24,7 +24,7 @@ export default class EntityTableDataCoordinator<TFields> {
|
|
|
24
24
|
cacheAdapterProvider: IEntityCacheAdapterProvider,
|
|
25
25
|
private readonly queryContextProvider: EntityQueryContextProvider,
|
|
26
26
|
metricsAdapter: IEntityMetricsAdapter,
|
|
27
|
-
entityClassName: string
|
|
27
|
+
entityClassName: string,
|
|
28
28
|
) {
|
|
29
29
|
this.databaseAdapter = databaseAdapterProvider.getDatabaseAdapter(entityConfiguration);
|
|
30
30
|
this.cacheAdapter = cacheAdapterProvider.getCacheAdapter(entityConfiguration);
|
|
@@ -33,7 +33,7 @@ export default class EntityTableDataCoordinator<TFields> {
|
|
|
33
33
|
new ReadThroughEntityCache(entityConfiguration, this.cacheAdapter),
|
|
34
34
|
queryContextProvider,
|
|
35
35
|
metricsAdapter,
|
|
36
|
-
entityClassName
|
|
36
|
+
entityClassName,
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -26,10 +26,10 @@ export type CacheLoadResult<TFields> =
|
|
|
26
26
|
* A read-through entity cache is responsible for coordinating EntityDatabaseAdapter and
|
|
27
27
|
* EntityCacheAdapter within the EntityDataManager.
|
|
28
28
|
*/
|
|
29
|
-
export default class ReadThroughEntityCache<TFields
|
|
29
|
+
export default class ReadThroughEntityCache<TFields extends Record<string, any>> {
|
|
30
30
|
constructor(
|
|
31
31
|
private readonly entityConfiguration: EntityConfiguration<TFields>,
|
|
32
|
-
private readonly entityCacheAdapter: IEntityCacheAdapter<TFields
|
|
32
|
+
private readonly entityCacheAdapter: IEntityCacheAdapter<TFields>,
|
|
33
33
|
) {}
|
|
34
34
|
|
|
35
35
|
private isFieldCacheable<N extends keyof TFields>(fieldName: N): boolean {
|
|
@@ -56,8 +56,8 @@ export default class ReadThroughEntityCache<TFields> {
|
|
|
56
56
|
fieldName: N,
|
|
57
57
|
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
58
58
|
fetcher: (
|
|
59
|
-
fetcherFieldValues: readonly NonNullable<TFields[N]>[]
|
|
60
|
-
) => Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]
|
|
59
|
+
fetcherFieldValues: readonly NonNullable<TFields[N]>[],
|
|
60
|
+
) => Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>>,
|
|
61
61
|
): Promise<ReadonlyMap<NonNullable<TFields[N]>, readonly Readonly<TFields>[]>> {
|
|
62
62
|
// return normal fetch when cache by fieldName not supported
|
|
63
63
|
if (!this.isFieldCacheable(fieldName)) {
|
|
@@ -68,14 +68,14 @@ export default class ReadThroughEntityCache<TFields> {
|
|
|
68
68
|
|
|
69
69
|
invariant(
|
|
70
70
|
cacheLoadResults.size === fieldValues.length,
|
|
71
|
-
`${this.constructor.name} loadMany should return a result for each fieldValue
|
|
71
|
+
`${this.constructor.name} loadMany should return a result for each fieldValue`,
|
|
72
72
|
);
|
|
73
73
|
|
|
74
74
|
const fieldValuesToFetchFromDB = Array.from(
|
|
75
75
|
filterMap(
|
|
76
76
|
cacheLoadResults,
|
|
77
|
-
(cacheLoadResult) => cacheLoadResult.status === CacheStatus.MISS
|
|
78
|
-
).keys()
|
|
77
|
+
(cacheLoadResult) => cacheLoadResult.status === CacheStatus.MISS,
|
|
78
|
+
).keys(),
|
|
79
79
|
);
|
|
80
80
|
|
|
81
81
|
// put transformed cache hits in result map
|
|
@@ -104,7 +104,7 @@ export default class ReadThroughEntityCache<TFields> {
|
|
|
104
104
|
console.warn(
|
|
105
105
|
`unique key ${String(fieldName)} in ${
|
|
106
106
|
this.entityConfiguration.tableName
|
|
107
|
-
} returned multiple rows for ${fieldValue}
|
|
107
|
+
} returned multiple rows for ${fieldValue}`,
|
|
108
108
|
);
|
|
109
109
|
continue;
|
|
110
110
|
}
|
|
@@ -132,7 +132,7 @@ export default class ReadThroughEntityCache<TFields> {
|
|
|
132
132
|
*/
|
|
133
133
|
public async invalidateManyAsync<N extends keyof TFields>(
|
|
134
134
|
fieldName: N,
|
|
135
|
-
fieldValues: readonly NonNullable<TFields[N]>[]
|
|
135
|
+
fieldValues: readonly NonNullable<TFields[N]>[],
|
|
136
136
|
): Promise<void> {
|
|
137
137
|
// no-op when cache by fieldName not supported
|
|
138
138
|
if (!this.isFieldCacheable(fieldName)) {
|