@adtrackify/at-service-common 4.0.5 → 4.0.6
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/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.d.ts +1 -0
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js +646 -0
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js.map +1 -0
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.d.ts +1 -0
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js +327 -0
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js.map +1 -0
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js +250 -108
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js.map +1 -1
- package/dist/cjs/__tests__/identity-cache/identity-cache-tier-routing.spec.js +37 -36
- package/dist/cjs/__tests__/identity-cache/identity-cache-tier-routing.spec.js.map +1 -1
- package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.d.ts +1 -0
- package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.js +567 -0
- package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/constants.d.ts +3 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/constants.js +7 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/constants.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.d.ts +14 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.js +251 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.d.ts +24 -0
- package/dist/cjs/services/db/{identity-cache-dynamodb-service.js → identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js} +221 -343
- package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.d.ts +22 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.js +375 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/index.d.ts +4 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/index.js +21 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/index.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/key-builders.d.ts +12 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/key-builders.js +32 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/key-builders.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/types.d.ts +205 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/types.js +35 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/types.js.map +1 -0
- package/dist/cjs/services/db/index.d.ts +4 -1
- package/dist/cjs/services/db/index.js +4 -1
- package/dist/cjs/services/db/index.js.map +1 -1
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.d.ts +1 -0
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js +644 -0
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js.map +1 -0
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.d.ts +1 -0
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js +325 -0
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js.map +1 -0
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js +250 -108
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js.map +1 -1
- package/dist/esm/__tests__/identity-cache/identity-cache-tier-routing.spec.js +37 -36
- package/dist/esm/__tests__/identity-cache/identity-cache-tier-routing.spec.js.map +1 -1
- package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.d.ts +1 -0
- package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.js +565 -0
- package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/constants.d.ts +3 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/constants.js +4 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/constants.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.d.ts +14 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.js +234 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.d.ts +24 -0
- package/dist/esm/services/db/{identity-cache-dynamodb-service.js → identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js} +199 -321
- package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.d.ts +22 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.js +368 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/index.d.ts +4 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/index.js +5 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/index.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/key-builders.d.ts +12 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/key-builders.js +24 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/key-builders.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/types.d.ts +205 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/types.js +32 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/types.js.map +1 -0
- package/dist/esm/services/db/index.d.ts +4 -1
- package/dist/esm/services/db/index.js +4 -1
- package/dist/esm/services/db/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/cjs/services/db/identity-cache-dynamodb-service.d.ts +0 -44
- package/dist/cjs/services/db/identity-cache-dynamodb-service.js.map +0 -1
- package/dist/esm/services/db/identity-cache-dynamodb-service.d.ts +0 -44
- package/dist/esm/services/db/identity-cache-dynamodb-service.js.map +0 -1
|
@@ -1,164 +1,15 @@
|
|
|
1
|
-
import { buildIdentityPk, buildEmailPk, buildIdentityMapPk, buildForcePurgePk, } from '@adtrackify/at-tracking-event-types';
|
|
2
1
|
import { mergeIdentityTraits } from '@adtrackify/at-shared-utils';
|
|
3
2
|
import fastDeepEqual from 'fast-deep-equal';
|
|
4
3
|
import { DateTime } from 'luxon';
|
|
5
|
-
import { DynamoDbClient
|
|
6
|
-
import { Logger } from '
|
|
7
|
-
import { isIdentityCacheStale, IDENTITY_CACHE_STALENESS_TIER, } from '
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
CACHE_WRITE_REASON["STALE_TRAITS"] = "stale_traits";
|
|
15
|
-
CACHE_WRITE_REASON["EMAIL_POINTER_DISCOVERY"] = "email_pointer_discovery";
|
|
16
|
-
CACHE_WRITE_REASON["ADDRESS_UPDATE"] = "address_update";
|
|
17
|
-
})(CACHE_WRITE_REASON || (CACHE_WRITE_REASON = {}));
|
|
18
|
-
export class IdentityCacheDynamoDbService {
|
|
19
|
-
static lambdaInvokeClient;
|
|
20
|
-
static getLambdaInvokeClient() {
|
|
21
|
-
if (!this.lambdaInvokeClient) {
|
|
22
|
-
this.lambdaInvokeClient = new LambdaInvokeClient();
|
|
23
|
-
}
|
|
24
|
-
return this.lambdaInvokeClient;
|
|
25
|
-
}
|
|
26
|
-
static getIdentityWithCaching = async (pixelId, incomingIdentity, identifyPrivateLambdaArn) => {
|
|
27
|
-
try {
|
|
28
|
-
if (!pixelId || !incomingIdentity) {
|
|
29
|
-
Logger.error('IdentityCache - missing required params', { pixelId, incomingIdentity });
|
|
30
|
-
return undefined;
|
|
31
|
-
}
|
|
32
|
-
const cacheResponse = await this.readFromCache(pixelId, incomingIdentity);
|
|
33
|
-
let resolvedIdentity = cacheResponse.resolvedIdentity;
|
|
34
|
-
const isCacheStale = cacheResponse.isCacheStale;
|
|
35
|
-
const cachedIdentity = cacheResponse.cachedIdentity;
|
|
36
|
-
const staleTracker = cacheResponse.staleTracker;
|
|
37
|
-
const writeReason = cacheResponse.writeReason;
|
|
38
|
-
const staleTier = cacheResponse.staleTier;
|
|
39
|
-
const skipNeptune = cacheResponse.skipNeptune;
|
|
40
|
-
if (resolvedIdentity && !isCacheStale) {
|
|
41
|
-
const tierLabel = staleTier === IDENTITY_CACHE_STALENESS_TIER.VOLATILE_ONLY ? 'volatile_traits_only' : 'fresh';
|
|
42
|
-
Logger.debug(`IdentityCache - identity cache hit - ${tierLabel}`, {
|
|
43
|
-
pixelId,
|
|
44
|
-
identityId: resolvedIdentity.identityId,
|
|
45
|
-
staleTier,
|
|
46
|
-
cachedIdentity: cachedIdentity ?? null,
|
|
47
|
-
incomingIdentity,
|
|
48
|
-
resolvedIdentity,
|
|
49
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
50
|
-
cachedClick: cachedIdentity?.traits?.click ?? null,
|
|
51
|
-
resolvedClick: resolvedIdentity?.traits?.click ?? null,
|
|
52
|
-
});
|
|
53
|
-
return resolvedIdentity;
|
|
54
|
-
}
|
|
55
|
-
if (resolvedIdentity && skipNeptune && writeReason === CACHE_WRITE_REASON.ADDRESS_UPDATE) {
|
|
56
|
-
const staleTraits = staleTracker ? this.extractStaleTraitNames(staleTracker) : [];
|
|
57
|
-
Logger.info('IdentityCache - identity cache write: address update only (skipping Neptune)', {
|
|
58
|
-
pixelId,
|
|
59
|
-
identityId: resolvedIdentity.identityId,
|
|
60
|
-
writeReason,
|
|
61
|
-
staleTier,
|
|
62
|
-
staleTraits,
|
|
63
|
-
cachedIdentity: cachedIdentity ?? null,
|
|
64
|
-
incomingIdentity,
|
|
65
|
-
resolvedIdentity,
|
|
66
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
67
|
-
cachedClick: cachedIdentity?.traits?.click ?? null,
|
|
68
|
-
resolvedClick: resolvedIdentity?.traits?.click ?? null,
|
|
69
|
-
traitChanges: cachedIdentity ? this.computeTraitChanges(cachedIdentity, resolvedIdentity) : { reason: 'no cached identity' },
|
|
70
|
-
});
|
|
71
|
-
await this.safeWriteBackToCache(pixelId, resolvedIdentity, 'address update');
|
|
72
|
-
return resolvedIdentity;
|
|
73
|
-
}
|
|
74
|
-
const identityForNeptune = resolvedIdentity ?? incomingIdentity;
|
|
75
|
-
Logger.info('IdentityCache - identity cache stale - fetching from Neptune', {
|
|
76
|
-
pixelId,
|
|
77
|
-
identityId: identityForNeptune?.identityId,
|
|
78
|
-
staleTier,
|
|
79
|
-
writeReason,
|
|
80
|
-
staleTraits: staleTracker ? this.extractStaleTraitNames(staleTracker) : [],
|
|
81
|
-
cachedIdentity: cachedIdentity ?? null,
|
|
82
|
-
incomingIdentity,
|
|
83
|
-
identityForNeptune,
|
|
84
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
85
|
-
cachedClick: cachedIdentity?.traits?.click ?? null,
|
|
86
|
-
hasDiscoveredIdentityId: !!resolvedIdentity?.identityId,
|
|
87
|
-
});
|
|
88
|
-
const neptuneIdentity = await this.resolveFromNeptune(pixelId, identityForNeptune, identifyPrivateLambdaArn);
|
|
89
|
-
if (neptuneIdentity) {
|
|
90
|
-
resolvedIdentity = neptuneIdentity;
|
|
91
|
-
const cachedForComparison = cachedIdentity ? this.stripAddressTimestamps(cachedIdentity) : undefined;
|
|
92
|
-
const neptuneForComparison = this.stripAddressTimestamps(neptuneIdentity);
|
|
93
|
-
const shouldWrite = !cachedForComparison || !fastDeepEqual(cachedForComparison, neptuneForComparison);
|
|
94
|
-
if (shouldWrite) {
|
|
95
|
-
const staleTraits = staleTracker ? this.extractStaleTraitNames(staleTracker) : [];
|
|
96
|
-
const isNewIdentity = writeReason === CACHE_WRITE_REASON.CACHE_MISS || writeReason === CACHE_WRITE_REASON.EMAIL_POINTER_DISCOVERY;
|
|
97
|
-
const writeType = isNewIdentity ? 'new_identity' : 'stale_traits_update';
|
|
98
|
-
Logger.info(`IdentityCache - identity cache write: ${writeType}`, {
|
|
99
|
-
pixelId,
|
|
100
|
-
identityId: neptuneIdentity.identityId,
|
|
101
|
-
writeReason,
|
|
102
|
-
staleTier,
|
|
103
|
-
staleTraits,
|
|
104
|
-
cachedIdentity: cachedIdentity ?? null,
|
|
105
|
-
incomingIdentity,
|
|
106
|
-
neptuneIdentity,
|
|
107
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
108
|
-
cachedClick: cachedIdentity?.traits?.click ?? null,
|
|
109
|
-
neptuneClick: neptuneIdentity?.traits?.click ?? null,
|
|
110
|
-
traitChanges: cachedIdentity
|
|
111
|
-
? this.computeTraitChanges(cachedIdentity, neptuneIdentity)
|
|
112
|
-
: { reason: 'no cached identity' },
|
|
113
|
-
});
|
|
114
|
-
await this.safeWriteBackToCache(pixelId, resolvedIdentity, 'neptune write-back');
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
Logger.info('IdentityCache - identity cache skip write - Neptune matches cached', {
|
|
118
|
-
pixelId,
|
|
119
|
-
identityId: neptuneIdentity.identityId,
|
|
120
|
-
staleTier,
|
|
121
|
-
cachedIdentity: cachedIdentity ?? null,
|
|
122
|
-
incomingIdentity,
|
|
123
|
-
neptuneIdentity,
|
|
124
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
125
|
-
cachedClick: cachedIdentity?.traits?.click ?? null,
|
|
126
|
-
neptuneClick: neptuneIdentity?.traits?.click ?? null,
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
Logger.error('IdentityCache - Neptune resolution failed', {
|
|
132
|
-
pixelId,
|
|
133
|
-
staleTier,
|
|
134
|
-
writeReason,
|
|
135
|
-
cachedIdentity: cachedIdentity ?? null,
|
|
136
|
-
incomingIdentity,
|
|
137
|
-
identityForNeptune,
|
|
138
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
if (!resolvedIdentity) {
|
|
142
|
-
Logger.error('IdentityCache - no identity found, using incoming', {
|
|
143
|
-
pixelId,
|
|
144
|
-
incomingIdentity,
|
|
145
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
146
|
-
});
|
|
147
|
-
resolvedIdentity = incomingIdentity;
|
|
148
|
-
}
|
|
149
|
-
return resolvedIdentity;
|
|
150
|
-
}
|
|
151
|
-
catch (error) {
|
|
152
|
-
Logger.error('IdentityCache - getIdentityWithCaching failed', {
|
|
153
|
-
error,
|
|
154
|
-
errorMessage: error instanceof Error ? error.message : String(error),
|
|
155
|
-
pixelId,
|
|
156
|
-
incomingIdentity,
|
|
157
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
158
|
-
});
|
|
159
|
-
return undefined;
|
|
160
|
-
}
|
|
161
|
-
};
|
|
4
|
+
import { DynamoDbClient } from '../../../clients/index.js';
|
|
5
|
+
import { Logger } from '../../../helpers/index.js';
|
|
6
|
+
import { isIdentityCacheStale, IDENTITY_CACHE_STALENESS_TIER, } from '../../../helpers/identity-cache-helper.js';
|
|
7
|
+
import { FORCE_PURGE_TTL_SECONDS, IDENTITY_CACHE_GSI1_NAME, IDENTITY_CACHE_TABLE_NAME } from './constants.js';
|
|
8
|
+
import { buildEmailPk, buildForcePurgePk, buildIdentityMapPk, buildIdentityPk, } from './key-builders.js';
|
|
9
|
+
import { CACHE_WRITE_REASON } from './types.js';
|
|
10
|
+
import { createCacheMissLookupResult, createIdentityCacheLookupResultFromState, createIdentityCacheLookupState, extractStaleTraitNames, stripAddressTimestamps, } from './helpers.js';
|
|
11
|
+
import { IDENTITY_CACHE_LOOKUP_OUTCOME, } from './types.js';
|
|
12
|
+
export class IdentityCacheDynamoDbDbService {
|
|
162
13
|
static getIdentityFromCache = async (pixelId, incomingIdentity) => {
|
|
163
14
|
try {
|
|
164
15
|
if (!pixelId || !incomingIdentity) {
|
|
@@ -177,6 +28,15 @@ export class IdentityCacheDynamoDbService {
|
|
|
177
28
|
});
|
|
178
29
|
return { resolvedIdentity: undefined, isCacheStale: true, writeReason: CACHE_WRITE_REASON.CACHE_MISS };
|
|
179
30
|
}
|
|
31
|
+
if (!cachedIdentityResponse?.response) {
|
|
32
|
+
Logger.debug('IdentityCache - found cached identity but no response', {
|
|
33
|
+
pixelId,
|
|
34
|
+
identityId: incomingIdentity.identityId,
|
|
35
|
+
incomingIdentity,
|
|
36
|
+
cachedIdentityResponse,
|
|
37
|
+
});
|
|
38
|
+
return { resolvedIdentity: undefined, isCacheStale: true, writeReason: CACHE_WRITE_REASON.CACHE_MISS };
|
|
39
|
+
}
|
|
180
40
|
Logger.debug('IdentityCache - found cached identity', {
|
|
181
41
|
pixelId,
|
|
182
42
|
identityId: incomingIdentity.identityId,
|
|
@@ -186,8 +46,8 @@ export class IdentityCacheDynamoDbService {
|
|
|
186
46
|
const mergedTraits = mergeIdentityTraits(incomingIdentity.traits, cachedIdentityResponse.response.traits);
|
|
187
47
|
const mergedIdentity = { ...incomingIdentity, traits: mergedTraits };
|
|
188
48
|
const identityStaleCacheTracker = isIdentityCacheStale(cachedIdentityResponse.response, mergedIdentity);
|
|
189
|
-
const cachedForComparison =
|
|
190
|
-
const mergedForComparison =
|
|
49
|
+
const cachedForComparison = stripAddressTimestamps(cachedIdentityResponse.response);
|
|
50
|
+
const mergedForComparison = stripAddressTimestamps(mergedIdentity);
|
|
191
51
|
const isDeepEqual = fastDeepEqual(cachedForComparison, mergedForComparison);
|
|
192
52
|
const staleTier = identityStaleCacheTracker.staleTier;
|
|
193
53
|
let isCacheStale = identityStaleCacheTracker.isCacheStale;
|
|
@@ -281,13 +141,180 @@ export class IdentityCacheDynamoDbService {
|
|
|
281
141
|
return { resolvedIdentity: undefined, isCacheStale: true, writeReason: CACHE_WRITE_REASON.CACHE_MISS };
|
|
282
142
|
}
|
|
283
143
|
};
|
|
144
|
+
static getIdentityFromCacheV2 = async (pixelId, incomingIdentity) => {
|
|
145
|
+
const state = createIdentityCacheLookupState(pixelId, incomingIdentity);
|
|
146
|
+
try {
|
|
147
|
+
if (!pixelId || !incomingIdentity) {
|
|
148
|
+
state.isCacheStale = true;
|
|
149
|
+
state.writeReason = CACHE_WRITE_REASON.CACHE_MISS;
|
|
150
|
+
return createCacheMissLookupResult(state, IDENTITY_CACHE_LOOKUP_OUTCOME.INVALID_INPUT);
|
|
151
|
+
}
|
|
152
|
+
if (incomingIdentity.identityId) {
|
|
153
|
+
return await this.resolveCacheByIdentityIdV2(state);
|
|
154
|
+
}
|
|
155
|
+
return await this.resolveCacheByEmailPointerV2(state);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
Logger.error('IdentityCache - getIdentityFromCache failed', {
|
|
159
|
+
error,
|
|
160
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
161
|
+
pixelId,
|
|
162
|
+
incomingIdentity,
|
|
163
|
+
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
164
|
+
});
|
|
165
|
+
state.isCacheStale = true;
|
|
166
|
+
state.writeReason = CACHE_WRITE_REASON.CACHE_MISS;
|
|
167
|
+
return createCacheMissLookupResult(state, IDENTITY_CACHE_LOOKUP_OUTCOME.FAILED, {
|
|
168
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
static resolveCacheByIdentityIdV2 = async (state) => {
|
|
173
|
+
const incomingIdentity = state.incomingIdentity;
|
|
174
|
+
const identityId = incomingIdentity.identityId;
|
|
175
|
+
state.didLookupByIdentityId = true;
|
|
176
|
+
const pk = buildIdentityPk(state.pixelId, identityId);
|
|
177
|
+
Logger.debug('IdentityCache - lookup by identityId', { pixelId: state.pixelId, pk, incomingIdentity });
|
|
178
|
+
const cachedIdentityResponse = await this.getItemByPk(pk);
|
|
179
|
+
if (!cachedIdentityResponse) {
|
|
180
|
+
Logger.debug('IdentityCache - identity cache miss - no cached identity found', {
|
|
181
|
+
pixelId: state.pixelId,
|
|
182
|
+
identityId,
|
|
183
|
+
incomingIdentity,
|
|
184
|
+
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
185
|
+
});
|
|
186
|
+
state.isCacheStale = true;
|
|
187
|
+
state.writeReason = CACHE_WRITE_REASON.CACHE_MISS;
|
|
188
|
+
return createCacheMissLookupResult(state, IDENTITY_CACHE_LOOKUP_OUTCOME.PRIMARY_CACHE_MISS);
|
|
189
|
+
}
|
|
190
|
+
state.cachedIdentityResponse = cachedIdentityResponse;
|
|
191
|
+
if (!cachedIdentityResponse?.response) {
|
|
192
|
+
Logger.debug('IdentityCache - found cached identity but no response', {
|
|
193
|
+
pixelId: state.pixelId,
|
|
194
|
+
identityId,
|
|
195
|
+
incomingIdentity,
|
|
196
|
+
cachedIdentityResponse,
|
|
197
|
+
});
|
|
198
|
+
state.isCacheStale = true;
|
|
199
|
+
state.writeReason = CACHE_WRITE_REASON.CACHE_MISS;
|
|
200
|
+
return createCacheMissLookupResult(state, IDENTITY_CACHE_LOOKUP_OUTCOME.PRIMARY_CACHE_MISS_NO_RESPONSE);
|
|
201
|
+
}
|
|
202
|
+
this.applyPrimaryCacheHitState(state, cachedIdentityResponse);
|
|
203
|
+
return this.createPrimaryCacheLookupResult(state);
|
|
204
|
+
};
|
|
205
|
+
static applyPrimaryCacheHitState(state, cachedIdentityResponse) {
|
|
206
|
+
const incomingIdentity = state.incomingIdentity;
|
|
207
|
+
const identityId = incomingIdentity.identityId;
|
|
208
|
+
Logger.debug('IdentityCache - found cached identity', {
|
|
209
|
+
pixelId: state.pixelId,
|
|
210
|
+
identityId,
|
|
211
|
+
cachedIdentity: cachedIdentityResponse.response,
|
|
212
|
+
cachedClick: cachedIdentityResponse.response?.traits?.click ?? null,
|
|
213
|
+
});
|
|
214
|
+
state.cachedIdentity = cachedIdentityResponse.response;
|
|
215
|
+
const mergedTraits = mergeIdentityTraits(incomingIdentity.traits, cachedIdentityResponse.response.traits);
|
|
216
|
+
state.mergedIdentity = { ...incomingIdentity, traits: mergedTraits };
|
|
217
|
+
state.resolvedIdentity = state.mergedIdentity;
|
|
218
|
+
state.identityStaleCacheTracker = isIdentityCacheStale(cachedIdentityResponse.response, state.mergedIdentity);
|
|
219
|
+
const cachedForComparison = stripAddressTimestamps(cachedIdentityResponse.response);
|
|
220
|
+
const mergedForComparison = stripAddressTimestamps(state.mergedIdentity);
|
|
221
|
+
state.isDeepEqual = fastDeepEqual(cachedForComparison, mergedForComparison);
|
|
222
|
+
state.staleTier = state.identityStaleCacheTracker.staleTier;
|
|
223
|
+
state.isCacheStale = state.identityStaleCacheTracker.isCacheStale;
|
|
224
|
+
if (state.isDeepEqual) {
|
|
225
|
+
Logger.debug('IdentityCache - deep equal (after stripping timestamps)', {
|
|
226
|
+
pixelId: state.pixelId,
|
|
227
|
+
identityId,
|
|
228
|
+
staleTier: state.staleTier,
|
|
229
|
+
});
|
|
230
|
+
state.isCacheStale = false;
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
Logger.debug('IdentityCache - not deep equal', {
|
|
234
|
+
pixelId: state.pixelId,
|
|
235
|
+
identityId,
|
|
236
|
+
staleTier: state.staleTier,
|
|
237
|
+
identityStaleCacheTracker: state.identityStaleCacheTracker,
|
|
238
|
+
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
239
|
+
cachedClick: cachedIdentityResponse.response?.traits?.click ?? null,
|
|
240
|
+
mergedClick: state.mergedIdentity?.traits?.click ?? null,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
const isVolatileOnly = state.staleTier === IDENTITY_CACHE_STALENESS_TIER.VOLATILE_ONLY;
|
|
244
|
+
const isAddressUpdateOnly = state.staleTier === IDENTITY_CACHE_STALENESS_TIER.ADDRESS_UPDATE;
|
|
245
|
+
const skipNeptune = isVolatileOnly || isAddressUpdateOnly;
|
|
246
|
+
if (isVolatileOnly && !state.isDeepEqual) {
|
|
247
|
+
Logger.debug('IdentityCache - volatile only - treating as cache hit', {
|
|
248
|
+
pixelId: state.pixelId,
|
|
249
|
+
identityId,
|
|
250
|
+
staleTier: state.staleTier,
|
|
251
|
+
});
|
|
252
|
+
state.isCacheStale = false;
|
|
253
|
+
}
|
|
254
|
+
if (state.isCacheStale) {
|
|
255
|
+
state.writeReason = isAddressUpdateOnly ? CACHE_WRITE_REASON.ADDRESS_UPDATE : CACHE_WRITE_REASON.STALE_TRAITS;
|
|
256
|
+
state.skipNeptune = skipNeptune;
|
|
257
|
+
state.staleTraits = extractStaleTraitNames(state.identityStaleCacheTracker);
|
|
258
|
+
Logger.debug('IdentityCache - stale detected', {
|
|
259
|
+
pixelId: state.pixelId,
|
|
260
|
+
identityId,
|
|
261
|
+
isCacheStale: state.isCacheStale,
|
|
262
|
+
isDeepEqual: state.isDeepEqual,
|
|
263
|
+
staleTier: state.staleTier,
|
|
264
|
+
skipNeptune: state.skipNeptune,
|
|
265
|
+
writeReason: state.writeReason,
|
|
266
|
+
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
267
|
+
cachedClick: cachedIdentityResponse.response?.traits?.click ?? null,
|
|
268
|
+
mergedClick: state.mergedIdentity?.traits?.click ?? null,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
static createPrimaryCacheLookupResult(state) {
|
|
273
|
+
const cacheResult = {
|
|
274
|
+
resolvedIdentity: state.mergedIdentity,
|
|
275
|
+
isCacheStale: state.isCacheStale,
|
|
276
|
+
cachedIdentity: state.cachedIdentity,
|
|
277
|
+
staleTracker: state.isCacheStale ? state.identityStaleCacheTracker : undefined,
|
|
278
|
+
writeReason: state.writeReason,
|
|
279
|
+
staleTier: state.staleTier,
|
|
280
|
+
skipNeptune: state.isCacheStale ? state.skipNeptune : undefined,
|
|
281
|
+
};
|
|
282
|
+
return createIdentityCacheLookupResultFromState(state, cacheResult, {
|
|
283
|
+
outcome: state.isCacheStale ? IDENTITY_CACHE_LOOKUP_OUTCOME.PRIMARY_CACHE_STALE : IDENTITY_CACHE_LOOKUP_OUTCOME.PRIMARY_CACHE_HIT,
|
|
284
|
+
skipNeptune: state.isCacheStale ? state.skipNeptune : undefined,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
static resolveCacheByEmailPointerV2 = async (state) => {
|
|
288
|
+
const incomingIdentity = state.incomingIdentity;
|
|
289
|
+
state.didLookupByEmail = !!incomingIdentity.traits?.emails?.[0];
|
|
290
|
+
state.discoveredIdentityId = await this.getIdentityIdFromEmailLookup(state.pixelId, incomingIdentity);
|
|
291
|
+
if (state.discoveredIdentityId) {
|
|
292
|
+
Logger.debug('IdentityCache - identityId from email pointer', {
|
|
293
|
+
pixelId: state.pixelId,
|
|
294
|
+
discoveredIdentityId: state.discoveredIdentityId,
|
|
295
|
+
incomingIdentity,
|
|
296
|
+
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
297
|
+
});
|
|
298
|
+
const identityWithDiscoveredId = {
|
|
299
|
+
...incomingIdentity,
|
|
300
|
+
identityId: state.discoveredIdentityId,
|
|
301
|
+
};
|
|
302
|
+
state.resolvedIdentity = identityWithDiscoveredId;
|
|
303
|
+
state.isCacheStale = true;
|
|
304
|
+
state.writeReason = CACHE_WRITE_REASON.EMAIL_POINTER_DISCOVERY;
|
|
305
|
+
return createIdentityCacheLookupResultFromState(state, { resolvedIdentity: identityWithDiscoveredId, isCacheStale: true, writeReason: CACHE_WRITE_REASON.EMAIL_POINTER_DISCOVERY }, { outcome: IDENTITY_CACHE_LOOKUP_OUTCOME.EMAIL_POINTER_DISCOVERY });
|
|
306
|
+
}
|
|
307
|
+
state.isCacheStale = true;
|
|
308
|
+
state.writeReason = CACHE_WRITE_REASON.CACHE_MISS;
|
|
309
|
+
return createCacheMissLookupResult(state, IDENTITY_CACHE_LOOKUP_OUTCOME.EMAIL_POINTER_MISS);
|
|
310
|
+
};
|
|
284
311
|
static getIdentityMap = async (pixelId, identityId) => {
|
|
285
312
|
try {
|
|
286
313
|
if (!pixelId || !identityId) {
|
|
287
314
|
return undefined;
|
|
288
315
|
}
|
|
289
316
|
const pk = buildIdentityMapPk(pixelId, identityId);
|
|
290
|
-
const result = (await DynamoDbClient.safeGet(
|
|
317
|
+
const result = (await DynamoDbClient.safeGet(IDENTITY_CACHE_TABLE_NAME, 'pk', pk));
|
|
291
318
|
return result ?? undefined;
|
|
292
319
|
}
|
|
293
320
|
catch (error) {
|
|
@@ -306,7 +333,7 @@ export class IdentityCacheDynamoDbService {
|
|
|
306
333
|
return false;
|
|
307
334
|
}
|
|
308
335
|
const pk = buildForcePurgePk(pixelId, identityId);
|
|
309
|
-
const result = await DynamoDbClient.safeGet(
|
|
336
|
+
const result = await DynamoDbClient.safeGet(IDENTITY_CACHE_TABLE_NAME, 'pk', pk);
|
|
310
337
|
return result !== null;
|
|
311
338
|
}
|
|
312
339
|
catch (error) {
|
|
@@ -347,7 +374,7 @@ export class IdentityCacheDynamoDbService {
|
|
|
347
374
|
items.push(pointerRecord);
|
|
348
375
|
}
|
|
349
376
|
}
|
|
350
|
-
await DynamoDbClient.safeBatchWrite(
|
|
377
|
+
await DynamoDbClient.safeBatchWrite(IDENTITY_CACHE_TABLE_NAME, items);
|
|
351
378
|
Logger.debug('IdentityCache - cache written', { pixelId, identityId: response.identityId, itemCount: items.length });
|
|
352
379
|
}
|
|
353
380
|
catch (error) {
|
|
@@ -370,7 +397,7 @@ export class IdentityCacheDynamoDbService {
|
|
|
370
397
|
linkedIdentities,
|
|
371
398
|
updatedAt: new Date().toISOString(),
|
|
372
399
|
};
|
|
373
|
-
await DynamoDbClient.safePut(
|
|
400
|
+
await DynamoDbClient.safePut(IDENTITY_CACHE_TABLE_NAME, item);
|
|
374
401
|
Logger.debug('IdentityCache - identity map written', { pixelId, identityId, linkedIdentities });
|
|
375
402
|
}
|
|
376
403
|
catch (error) {
|
|
@@ -396,7 +423,7 @@ export class IdentityCacheDynamoDbService {
|
|
|
396
423
|
createdAt: now,
|
|
397
424
|
ttl: Math.floor(ttl),
|
|
398
425
|
};
|
|
399
|
-
await DynamoDbClient.safePut(
|
|
426
|
+
await DynamoDbClient.safePut(IDENTITY_CACHE_TABLE_NAME, item);
|
|
400
427
|
Logger.debug('IdentityCache - force purge flag set', { pixelId, identityId, ttlSeconds });
|
|
401
428
|
}
|
|
402
429
|
catch (error) {
|
|
@@ -459,7 +486,7 @@ export class IdentityCacheDynamoDbService {
|
|
|
459
486
|
return;
|
|
460
487
|
}
|
|
461
488
|
const pk = buildIdentityMapPk(pixelId, identityId);
|
|
462
|
-
await DynamoDbClient.safeDelete(
|
|
489
|
+
await DynamoDbClient.safeDelete(IDENTITY_CACHE_TABLE_NAME, 'pk', pk);
|
|
463
490
|
Logger.debug('IdentityCache - identity map deleted', { pixelId, identityId });
|
|
464
491
|
}
|
|
465
492
|
catch (error) {
|
|
@@ -477,7 +504,7 @@ export class IdentityCacheDynamoDbService {
|
|
|
477
504
|
return;
|
|
478
505
|
}
|
|
479
506
|
const pk = buildForcePurgePk(pixelId, identityId);
|
|
480
|
-
await DynamoDbClient.safeDelete(
|
|
507
|
+
await DynamoDbClient.safeDelete(IDENTITY_CACHE_TABLE_NAME, 'pk', pk);
|
|
481
508
|
Logger.debug('IdentityCache - force purge flag deleted', { pixelId, identityId });
|
|
482
509
|
}
|
|
483
510
|
catch (error) {
|
|
@@ -489,50 +516,6 @@ export class IdentityCacheDynamoDbService {
|
|
|
489
516
|
});
|
|
490
517
|
}
|
|
491
518
|
};
|
|
492
|
-
static readFromCache = async (pixelId, incomingIdentity) => {
|
|
493
|
-
return await this.getIdentityFromCache(pixelId, incomingIdentity);
|
|
494
|
-
};
|
|
495
|
-
static resolveFromNeptune = async (pixelId, incomingIdentity, identifyPrivateLambdaArn) => {
|
|
496
|
-
try {
|
|
497
|
-
const client = this.getLambdaInvokeClient();
|
|
498
|
-
const response = await client.invokeFunction(identifyPrivateLambdaArn, {
|
|
499
|
-
pixelId,
|
|
500
|
-
context: { identity: incomingIdentity },
|
|
501
|
-
});
|
|
502
|
-
if (response?.statusCode === 200 && response?.body) {
|
|
503
|
-
const identifyResponse = JSON.parse(response.body);
|
|
504
|
-
return identifyResponse?.identity;
|
|
505
|
-
}
|
|
506
|
-
return incomingIdentity;
|
|
507
|
-
}
|
|
508
|
-
catch (error) {
|
|
509
|
-
Logger.error('IdentityCache - Neptune resolution failed', {
|
|
510
|
-
error,
|
|
511
|
-
errorMessage: error instanceof Error ? error.message : String(error),
|
|
512
|
-
pixelId,
|
|
513
|
-
incomingIdentity,
|
|
514
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
515
|
-
});
|
|
516
|
-
return undefined;
|
|
517
|
-
}
|
|
518
|
-
};
|
|
519
|
-
static writeBackToCache = async (pixelId, resolvedIdentity) => {
|
|
520
|
-
await this.updateIdentityCache(pixelId, resolvedIdentity);
|
|
521
|
-
};
|
|
522
|
-
static safeWriteBackToCache = async (pixelId, resolvedIdentity, context) => {
|
|
523
|
-
try {
|
|
524
|
-
await this.writeBackToCache(pixelId, resolvedIdentity);
|
|
525
|
-
}
|
|
526
|
-
catch (writeError) {
|
|
527
|
-
Logger.error(`IdentityCache - write back failed (${context})`, {
|
|
528
|
-
error: writeError,
|
|
529
|
-
errorMessage: writeError instanceof Error ? writeError.message : String(writeError),
|
|
530
|
-
pixelId,
|
|
531
|
-
identityId: resolvedIdentity?.identityId,
|
|
532
|
-
resolvedClick: resolvedIdentity?.traits?.click ?? null,
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
};
|
|
536
519
|
static getIdentityIdFromEmailLookup = async (pixelId, incomingIdentity) => {
|
|
537
520
|
try {
|
|
538
521
|
if (!pixelId || !incomingIdentity) {
|
|
@@ -544,7 +527,7 @@ export class IdentityCacheDynamoDbService {
|
|
|
544
527
|
}
|
|
545
528
|
const pk = buildEmailPk(pixelId, firstEmail);
|
|
546
529
|
Logger.debug('IdentityCache - email secondary lookup', { pixelId, pk, email: firstEmail });
|
|
547
|
-
const result = (await DynamoDbClient.safeGet(
|
|
530
|
+
const result = (await DynamoDbClient.safeGet(IDENTITY_CACHE_TABLE_NAME, 'pk', pk));
|
|
548
531
|
if (!result) {
|
|
549
532
|
return undefined;
|
|
550
533
|
}
|
|
@@ -563,7 +546,7 @@ export class IdentityCacheDynamoDbService {
|
|
|
563
546
|
};
|
|
564
547
|
static getItemByPk = async (pk) => {
|
|
565
548
|
try {
|
|
566
|
-
const result = (await DynamoDbClient.safeGet(
|
|
549
|
+
const result = (await DynamoDbClient.safeGet(IDENTITY_CACHE_TABLE_NAME, 'pk', pk));
|
|
567
550
|
return result ?? undefined;
|
|
568
551
|
}
|
|
569
552
|
catch (error) {
|
|
@@ -577,7 +560,7 @@ export class IdentityCacheDynamoDbService {
|
|
|
577
560
|
};
|
|
578
561
|
static queryByGsi1 = async (identityId) => {
|
|
579
562
|
try {
|
|
580
|
-
const results = await DynamoDbClient.safeQueryByGSI(
|
|
563
|
+
const results = await DynamoDbClient.safeQueryByGSI(IDENTITY_CACHE_TABLE_NAME, IDENTITY_CACHE_GSI1_NAME, 'gsi1pk', identityId);
|
|
581
564
|
return (results ?? []);
|
|
582
565
|
}
|
|
583
566
|
catch (error) {
|
|
@@ -600,7 +583,7 @@ export class IdentityCacheDynamoDbService {
|
|
|
600
583
|
DeleteRequest: { Key: { pk: key.pk } },
|
|
601
584
|
}));
|
|
602
585
|
await DynamoDbClient.batchWrite({
|
|
603
|
-
RequestItems: { [
|
|
586
|
+
RequestItems: { [IDENTITY_CACHE_TABLE_NAME]: deleteRequests },
|
|
604
587
|
});
|
|
605
588
|
}
|
|
606
589
|
catch (error) {
|
|
@@ -619,110 +602,5 @@ export class IdentityCacheDynamoDbService {
|
|
|
619
602
|
}
|
|
620
603
|
return chunks;
|
|
621
604
|
}
|
|
622
|
-
static stripAddressTimestamps(identity) {
|
|
623
|
-
if (!identity?.traits?.addresses?.length) {
|
|
624
|
-
return identity;
|
|
625
|
-
}
|
|
626
|
-
const strippedAddresses = identity.traits.addresses.map((addr) => {
|
|
627
|
-
if (!addr)
|
|
628
|
-
return addr;
|
|
629
|
-
const { cra, upa, ...rest } = addr;
|
|
630
|
-
return rest;
|
|
631
|
-
});
|
|
632
|
-
return {
|
|
633
|
-
...identity,
|
|
634
|
-
traits: {
|
|
635
|
-
...identity.traits,
|
|
636
|
-
addresses: strippedAddresses,
|
|
637
|
-
},
|
|
638
|
-
};
|
|
639
|
-
}
|
|
640
|
-
static extractStaleTraitNames(tracker) {
|
|
641
|
-
const staleTraits = [];
|
|
642
|
-
if (tracker.isIdentityIdStale)
|
|
643
|
-
staleTraits.push('identityId');
|
|
644
|
-
if (tracker.isUserIdsStale)
|
|
645
|
-
staleTraits.push('userIds');
|
|
646
|
-
if (tracker.isIdsStale)
|
|
647
|
-
staleTraits.push('ids');
|
|
648
|
-
if (tracker.isEmailsStale)
|
|
649
|
-
staleTraits.push('emails');
|
|
650
|
-
if (tracker.isPhonesStale)
|
|
651
|
-
staleTraits.push('phones');
|
|
652
|
-
if (tracker.isShopifyYIdsStale)
|
|
653
|
-
staleTraits.push('shopifyYIds');
|
|
654
|
-
if (tracker.isGendersStale)
|
|
655
|
-
staleTraits.push('genders');
|
|
656
|
-
if (tracker.isDobsStale)
|
|
657
|
-
staleTraits.push('dobs');
|
|
658
|
-
if (tracker.isAddressesStale)
|
|
659
|
-
staleTraits.push('addresses');
|
|
660
|
-
if (tracker.isClickInfosStale)
|
|
661
|
-
staleTraits.push('clickInfos');
|
|
662
|
-
if (tracker.isIpAddressStale)
|
|
663
|
-
staleTraits.push('ipAddress');
|
|
664
|
-
if (tracker.isUserAgentStale)
|
|
665
|
-
staleTraits.push('userAgent');
|
|
666
|
-
if (tracker.isThirdPartyContactsStale)
|
|
667
|
-
staleTraits.push('thirdPartyContacts');
|
|
668
|
-
return staleTraits;
|
|
669
|
-
}
|
|
670
|
-
static computeTraitChanges(cachedIdentity, resolvedIdentity) {
|
|
671
|
-
const changes = {};
|
|
672
|
-
const cachedTraits = cachedIdentity.traits ?? {};
|
|
673
|
-
const resolvedTraits = resolvedIdentity.traits ?? {};
|
|
674
|
-
const arrayTraits = [
|
|
675
|
-
'emails',
|
|
676
|
-
'phones',
|
|
677
|
-
'userIds',
|
|
678
|
-
'shopifyYIds',
|
|
679
|
-
'shopifyCustomerIds',
|
|
680
|
-
'klaviyoIds',
|
|
681
|
-
'genders',
|
|
682
|
-
'dobs',
|
|
683
|
-
'ids',
|
|
684
|
-
];
|
|
685
|
-
for (const trait of arrayTraits) {
|
|
686
|
-
const cachedValue = cachedTraits[trait];
|
|
687
|
-
const resolvedValue = resolvedTraits[trait];
|
|
688
|
-
if (!fastDeepEqual(cachedValue, resolvedValue)) {
|
|
689
|
-
changes[trait] = {
|
|
690
|
-
cached: cachedValue ?? [],
|
|
691
|
-
resolved: resolvedValue ?? [],
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
if (!fastDeepEqual(cachedTraits.addresses, resolvedTraits.addresses)) {
|
|
696
|
-
changes.addresses = {
|
|
697
|
-
cached: cachedTraits.addresses ?? [],
|
|
698
|
-
resolved: resolvedTraits.addresses ?? [],
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
if (!fastDeepEqual(cachedTraits.click, resolvedTraits.click)) {
|
|
702
|
-
changes.click = {
|
|
703
|
-
cached: cachedTraits.click ?? {},
|
|
704
|
-
resolved: resolvedTraits.click ?? {},
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
if (cachedTraits.ipAddress !== resolvedTraits.ipAddress) {
|
|
708
|
-
changes.ipAddress = {
|
|
709
|
-
cached: cachedTraits.ipAddress,
|
|
710
|
-
resolved: resolvedTraits.ipAddress,
|
|
711
|
-
};
|
|
712
|
-
}
|
|
713
|
-
if (cachedTraits.userAgent !== resolvedTraits.userAgent) {
|
|
714
|
-
changes.userAgent = {
|
|
715
|
-
cached: cachedTraits.userAgent,
|
|
716
|
-
resolved: resolvedTraits.userAgent,
|
|
717
|
-
};
|
|
718
|
-
}
|
|
719
|
-
if (cachedIdentity.identityId !== resolvedIdentity.identityId) {
|
|
720
|
-
changes.identityId = {
|
|
721
|
-
cached: cachedIdentity.identityId,
|
|
722
|
-
resolved: resolvedIdentity.identityId,
|
|
723
|
-
};
|
|
724
|
-
}
|
|
725
|
-
return changes;
|
|
726
|
-
}
|
|
727
605
|
}
|
|
728
|
-
//# sourceMappingURL=identity-cache-dynamodb-service.js.map
|
|
606
|
+
//# sourceMappingURL=identity-cache-dynamodb-db-service.js.map
|