import { isNothing, isSome } from "@jet/environment"; import * as validation from "@jet/environment/json/validation"; import { makeMetatype } from "@jet/environment/util/metatype"; /** * @public * Type to define which type of metrics identifier key to use to fetch identifiers, fields, etc. */ export var MetricsIdentifierType; (function (MetricsIdentifierType) { MetricsIdentifierType["client"] = "clientId"; MetricsIdentifierType["user"] = "userId"; MetricsIdentifierType["canonical"] = "canonicalAccountIdentifierOverride"; })(MetricsIdentifierType || (MetricsIdentifierType = {})); /** * @public * The default namespaces to provide to the native `MetricsIdStore` for fetching and caching */ export var MetricsIdentifiersDefaultBagNamespaces; (function (MetricsIdentifiersDefaultBagNamespaces) { MetricsIdentifiersDefaultBagNamespaces["client"] = "APPSTORE_ENGAGEMENT_CLIENT"; MetricsIdentifiersDefaultBagNamespaces["user"] = "APPSTORE_ENGAGEMENT"; })(MetricsIdentifiersDefaultBagNamespaces || (MetricsIdentifiersDefaultBagNamespaces = {})); export var MetricsIdentifiersPaymentBagNamespaces; (function (MetricsIdentifiersPaymentBagNamespaces) { MetricsIdentifiersPaymentBagNamespaces["client"] = "APPSTORE_PAYMENTS_ENGAGEMENT_CLIENT"; MetricsIdentifiersPaymentBagNamespaces["user"] = "APPSTORE_PAYMENTS_ENGAGEMENT"; })(MetricsIdentifiersPaymentBagNamespaces || (MetricsIdentifiersPaymentBagNamespaces = {})); export var MetricsIdentifiersPersonalizationBagNamespaces; (function (MetricsIdentifiersPersonalizationBagNamespaces) { MetricsIdentifiersPersonalizationBagNamespaces["user"] = "APPSTORE_PERSONALIZATION"; })(MetricsIdentifiersPersonalizationBagNamespaces || (MetricsIdentifiersPersonalizationBagNamespaces = {})); /** * The payment context mappings for a metrics identifier key. */ export const paymentIdentifierContextMapping = { [MetricsIdentifierType.client]: { keyType: MetricsIdentifierType.client, bagNamespace: MetricsIdentifiersPaymentBagNamespaces.client, crossSyncDevice: false, }, [MetricsIdentifierType.user]: { keyType: MetricsIdentifierType.user, bagNamespace: MetricsIdentifiersPaymentBagNamespaces.user, crossSyncDevice: true, }, }; /** * The default context mappings for a metrics identifier key. */ const defaultIdentifierContextMapping = { [MetricsIdentifierType.client]: { keyType: MetricsIdentifierType.client, bagNamespace: MetricsIdentifiersDefaultBagNamespaces.client, crossSyncDevice: false, }, [MetricsIdentifierType.user]: { keyType: MetricsIdentifierType.user, bagNamespace: MetricsIdentifiersDefaultBagNamespaces.user, crossSyncDevice: true, }, }; /** * The personalization context mappings for a metrics identifier key. */ export const personalizationIdentifierContextMapping = { [MetricsIdentifierType.user]: { keyType: MetricsIdentifierType.user, bagNamespace: MetricsIdentifiersPersonalizationBagNamespaces.user, crossSyncDevice: true, }, }; /** * Represents a cache for metrics identifiers and fields. */ export class MetricsIdentifiersCache { /** * Constructs a new instance of the MetricsIdentifiersCache class. * @param identifierContextMapping - The mapping of identifier types to key contexts. */ constructor(identifierContextMapping = defaultIdentifierContextMapping) { this.cachedMetricsIds = {}; this.cachedMetricsFields = {}; /** * A flag indicating whether a DSID fallback field should be added to the event fields. */ this.shouldAddDsIdFallbackField = false; /** * The DSID of the currently logged in user on this JS request. */ this.userDsId = null; this.identifierContextMapping = identifierContextMapping; } /** * Loads the values for the specified identifier types. * @param objectGraph - The object graph. * @param idTypes - The identifier types. * @returns A promise that resolves to an array of loaded values. */ async loadValues(objectGraph, idTypes) { if (objectGraph.bag.isMetricsUserIdFallbackEnabled && !objectGraph.user.isUnderThirteen) { this.shouldAddDsIdFallbackField = true; this.userDsId = objectGraph.user.dsid; } else { this.shouldAddDsIdFallbackField = false; this.userDsId = null; } const loadedValues = []; for (const idType of idTypes) { const idTypeLoadedValues = await this.loadValuesForIdType(objectGraph, idType); loadedValues.push(idTypeLoadedValues); } for (const { idType, id, fields } of loadedValues) { if (id) { this.cachedMetricsIds[idType] = id; } if (fields) { this.cachedMetricsFields[idType] = fields; } } } /** * @param objectGraph The app store object graph for all our native dependencies * @param idType The type of id we're loading values for * @returns The MetricsIdStore values for this id type */ async loadValuesForIdType(objectGraph, idType) { const returnValues = { idType, }; const context = this.identifierContextMapping[idType]; if (context) { try { const fields = await validation.context("MetricsIdentifiersCache:loadValues:metricsFields", async () => { return await objectGraph.metricsIdentifiers.getMetricsFieldsForContexts([context]); }); if (isSome(fields)) { returnValues["fields"] = fields; const extractedIdValue = fields[idType]; if (isSome(extractedIdValue) && typeof extractedIdValue === "string" && extractedIdValue.length > 0) { returnValues["id"] = extractedIdValue; } } } catch (error) { objectGraph.console.error(`Unable to fetch metrics fields for idType ${idType}`, error); } if (isNothing(returnValues["id"])) { try { const id = await validation.context("MetricsIdentifiersCache:loadValues:metricsIdentifier", async () => { return await objectGraph.metricsIdentifiers.getIdentifierForContext(context); }); if (isSome(id)) { returnValues["id"] = id; } } catch (error) { objectGraph.console.error(`Unable to fetch metrics identifier for idType ${idType}`, error); } } } return returnValues; } /** * Gets the metrics identifier for the specified identifier type. * @param idType - The identifier type. * @returns The metrics identifier, or undefined if not found. */ getMetricsIdForType(idType) { return this.cachedMetricsIds[idType]; } /** * Gets the metrics fields for the specified identifier types. * @param idTypes - The identifier types. * @returns The metrics fields, or undefined if not found. */ getMetricsFieldsForTypes(idTypes) { const fieldsForTypes = idTypes.map((idType) => { var _a; return (_a = this.cachedMetricsFields[idType]) !== null && _a !== void 0 ? _a : {}; }); const eventFields = Object.assign({}, ...fieldsForTypes); if (this.shouldAddDsIdFallbackField && idTypes.indexOf(MetricsIdentifierType.user) !== -1) { this.addDsIdFallbackFieldIfNecessary(eventFields); } return eventFields; } /** * Adds a DSID fallback field to the event fields if necessary. * @param eventFields - The event fields. */ addDsIdFallbackFieldIfNecessary(eventFields) { const existingUserId = eventFields[MetricsIdentifierType.user]; const isExistingUserIdInvalid = isNothing(existingUserId) || typeof existingUserId !== "string" || existingUserId.length === 0 || existingUserId.length === MetricsIdentifiersCache.clientGeneratedUserIdLength; if (isExistingUserIdInvalid && isSome(this.userDsId) && this.userDsId.length > 0) { eventFields["dsId"] = this.userDsId; } } /** * Allows the setting of an app-level canonical account override for downstream metrics computations * @param canonicalAccountIdentifier - The identifier to use when operated with canonical account overides */ setCanonicalAccountIdentifierOverride(canonicalAccountIdentifier) { if (canonicalAccountIdentifier.length >= 0) { this.cachedMetricsFields[MetricsIdentifierType.canonical] = { [MetricsIdentifierType.canonical]: canonicalAccountIdentifier, }; } } } /** * The metatype of the MetricsIdentifiersCache class. */ MetricsIdentifiersCache.defaultMetatype = makeMetatype("app-store:metricsIdentifiersCache"); MetricsIdentifiersCache.paymentMetatype = makeMetatype("app-store:paymentMetricsIdentifiersCache"); MetricsIdentifiersCache.personalizationMetatype = makeMetatype("app-store:personalizationMetricsIdentifiersCache"); /** * The length of a client generated user ID. */ MetricsIdentifiersCache.clientGeneratedUserIdLength = 24; export class MockMetricsIdentifiersCache extends MetricsIdentifiersCache { constructor() { super(); this.cachedMetricsIds = { [MetricsIdentifierType.client]: "1a2b3c4d5e", [MetricsIdentifierType.user]: "1a2b3c4d5e", }; this.cachedMetricsFields = { [MetricsIdentifierType.client]: { clientId: "1a2b3c4d5e", }, [MetricsIdentifierType.user]: { userNs: "mockuserNs", userId: "1a2b3c4d5e", metricsId: 2, }, [MetricsIdentifierType.canonical]: { canonicalAccountIdentifierOverride: "mockCanonicalAccountIdentifier", }, }; } } //# sourceMappingURL=metrics-identifiers-cache.js.map