diff --git a/lib/event_processor/batch_event_processor.ts b/lib/event_processor/batch_event_processor.ts index b573ca6aa..6ad19eaf8 100644 --- a/lib/event_processor/batch_event_processor.ts +++ b/lib/event_processor/batch_event_processor.ts @@ -266,6 +266,10 @@ export class BatchEventProcessor extends BaseService implements EventProcessor { } private async readEventCountInStore(store: Store): Promise { + if (this.eventCountInStore !== undefined) { + return; + } + try { const keys = await store.getKeys(); this.eventCountInStore = keys.length; diff --git a/lib/event_processor/event_builder/log_event.spec.ts b/lib/event_processor/event_builder/log_event.spec.ts index 54a9c2acf..3dfa07f08 100644 --- a/lib/event_processor/event_builder/log_event.spec.ts +++ b/lib/event_processor/event_builder/log_event.spec.ts @@ -16,15 +16,13 @@ import { describe, it, expect } from 'vitest'; import { - buildConversionEventV1, - buildImpressionEventV1, makeEventBatch, } from './log_event'; import { ImpressionEvent, ConversionEvent } from './user_event'; -describe('buildImpressionEventV1', () => { - it('should build an ImpressionEventV1 when experiment and variation are defined', () => { +describe('makeEventBatch', () => { + it('should build a batch with single impression event when experiment and variation are defined', () => { const impressionEvent: ImpressionEvent = { type: 'impression', timestamp: 69, @@ -65,7 +63,7 @@ describe('buildImpressionEventV1', () => { enabled: true, } - const result = buildImpressionEventV1(impressionEvent) + const result = makeEventBatch([impressionEvent]) expect(result).toEqual({ client_name: 'node-sdk', client_version: '3.0.0', @@ -123,7 +121,7 @@ describe('buildImpressionEventV1', () => { }) }) - it('should build an ImpressionEventV1 when experiment and variation are not defined', () => { + it('should build a batch with simlge impression event when experiment and variation are not defined', () => { const impressionEvent: ImpressionEvent = { type: 'impression', timestamp: 69, @@ -164,7 +162,7 @@ describe('buildImpressionEventV1', () => { enabled: true, } - const result = buildImpressionEventV1(impressionEvent) + const result = makeEventBatch([impressionEvent]) expect(result).toEqual({ client_name: 'node-sdk', client_version: '3.0.0', @@ -220,11 +218,9 @@ describe('buildImpressionEventV1', () => { }, ], }) - }) -}) + }); -describe('buildConversionEventV1', () => { - it('should build a ConversionEventV1 when tags object is defined', () => { + it('should build a batch with single conversion event when tags object is defined', () => { const conversionEvent: ConversionEvent = { type: 'conversion', timestamp: 69, @@ -260,7 +256,7 @@ describe('buildConversionEventV1', () => { value: 123, } - const result = buildConversionEventV1(conversionEvent) + const result = makeEventBatch([conversionEvent]) expect(result).toEqual({ client_name: 'node-sdk', client_version: '3.0.0', @@ -311,7 +307,7 @@ describe('buildConversionEventV1', () => { }) }) - it('should build a ConversionEventV1 when tags object is undefined', () => { + it('should build a batch with single conversion event when when tags object is undefined', () => { const conversionEvent: ConversionEvent = { type: 'conversion', timestamp: 69, @@ -343,7 +339,7 @@ describe('buildConversionEventV1', () => { value: 123, } - const result = buildConversionEventV1(conversionEvent) + const result = makeEventBatch([conversionEvent]) expect(result).toEqual({ client_name: 'node-sdk', client_version: '3.0.0', @@ -390,7 +386,7 @@ describe('buildConversionEventV1', () => { }) }) - it('should build a ConversionEventV1 when event id is null', () => { + it('should build a batch with single conversion event when event id is null', () => { const conversionEvent: ConversionEvent = { type: 'conversion', timestamp: 69, @@ -422,7 +418,7 @@ describe('buildConversionEventV1', () => { value: 123, } - const result = buildConversionEventV1(conversionEvent) + const result = makeEventBatch([conversionEvent]) expect(result).toEqual({ client_name: 'node-sdk', client_version: '3.0.0', @@ -469,7 +465,7 @@ describe('buildConversionEventV1', () => { }) }) - it('should include revenue and value if they are 0', () => { + it('should include revenue and value for conversion events if they are 0', () => { const conversionEvent: ConversionEvent = { type: 'conversion', timestamp: 69, @@ -505,7 +501,7 @@ describe('buildConversionEventV1', () => { value: 0, } - const result = buildConversionEventV1(conversionEvent) + const result = makeEventBatch([conversionEvent]) expect(result).toEqual({ client_name: 'node-sdk', client_version: '3.0.0', @@ -591,7 +587,7 @@ describe('buildConversionEventV1', () => { value: 123, } - const result = buildConversionEventV1(conversionEvent) + const result = makeEventBatch([conversionEvent]) expect(result).toEqual({ client_name: 'node-sdk', client_version: '3.0.0', @@ -635,9 +631,7 @@ describe('buildConversionEventV1', () => { ], }) }) -}) -describe('makeEventBatch', () => { it('should batch Conversion and Impression events together', () => { const conversionEvent: ConversionEvent = { type: 'conversion', diff --git a/lib/event_processor/event_builder/log_event.ts b/lib/event_processor/event_builder/log_event.ts index 8e65d6ba1..0afdccaeb 100644 --- a/lib/event_processor/event_builder/log_event.ts +++ b/lib/event_processor/event_builder/log_event.ts @@ -214,48 +214,6 @@ function makeVisitor(data: ImpressionEvent | ConversionEvent): Visitor { return visitor } -/** - * Event for usage with v1 logtier - * - * @export - * @interface EventBuilderV1 - */ -export function buildImpressionEventV1(data: ImpressionEvent): EventBatch { - const visitor = makeVisitor(data) - visitor.snapshots.push(makeDecisionSnapshot(data)) - - return { - client_name: data.context.clientName, - client_version: data.context.clientVersion, - - account_id: data.context.accountId, - project_id: data.context.projectId, - revision: data.context.revision, - anonymize_ip: data.context.anonymizeIP, - enrich_decisions: true, - - visitors: [visitor], - } -} - -export function buildConversionEventV1(data: ConversionEvent): EventBatch { - const visitor = makeVisitor(data) - visitor.snapshots.push(makeConversionSnapshot(data)) - - return { - client_name: data.context.clientName, - client_version: data.context.clientVersion, - - account_id: data.context.accountId, - project_id: data.context.projectId, - revision: data.context.revision, - anonymize_ip: data.context.anonymizeIP, - enrich_decisions: true, - - visitors: [visitor], - } -} - export function buildLogEvent(events: UserEvent[]): LogEvent { return { url: 'https://logx.optimizely.com/v1/events', diff --git a/lib/event_processor/event_builder/user_event.ts b/lib/event_processor/event_builder/user_event.ts index c6c6c5446..eaa1734d6 100644 --- a/lib/event_processor/event_builder/user_event.ts +++ b/lib/event_processor/event_builder/user_event.ts @@ -44,8 +44,11 @@ type EventContext = { botFiltering?: boolean; } -export type BaseUserEvent = { - type: 'impression' | 'conversion'; +type EventType = 'impression' | 'conversion'; + + +export type BaseUserEvent = { + type: T; timestamp: number; uuid: string; context: EventContext; @@ -55,9 +58,7 @@ export type BaseUserEvent = { }; }; -export type ImpressionEvent = BaseUserEvent & { - type: 'impression'; - +export type ImpressionEvent = BaseUserEvent<'impression'> & { layer: { id: string | null; } | null; @@ -79,9 +80,7 @@ export type ImpressionEvent = BaseUserEvent & { cmabUuid?: string; }; -export type ConversionEvent = BaseUserEvent & { - type: 'conversion'; - +export type ConversionEvent = BaseUserEvent<'conversion'> & { event: { id: string | null; key: string; @@ -108,6 +107,42 @@ export const areEventContextsEqual = (eventA: UserEvent, eventB: UserEvent): boo ) } +const buildBaseEvent = ({ + configObj, + userId, + userAttributes, + clientEngine, + clientVersion, + type, +}: { + configObj: ProjectConfig; + userId: string; + userAttributes?: UserAttributes; + clientEngine: string; + clientVersion: string; + type: T; +}): BaseUserEvent => { + return { + type, + timestamp: fns.currentTimestamp(), + uuid: fns.uuid(), + context: { + accountId: configObj.accountId, + projectId: configObj.projectId, + revision: configObj.revision, + clientName: clientEngine, + clientVersion: clientVersion, + anonymizeIP: configObj.anonymizeIP || false, + botFiltering: configObj.botFiltering, + }, + user: { + id: userId, + attributes: buildVisitorAttributes(configObj, userAttributes), + }, + }; + +} + export type ImpressionConfig = { decisionObj: DecisionObj; userId: string; @@ -119,7 +154,6 @@ export type ImpressionConfig = { configObj: ProjectConfig; } - /** * Creates an ImpressionEvent object from decision data * @param {ImpressionConfig} config @@ -146,24 +180,14 @@ export const buildImpressionEvent = function({ const layerId = experimentId !== null ? getLayerId(configObj, experimentId) : null; return { - type: 'impression', - timestamp: fns.currentTimestamp(), - uuid: fns.uuid(), - - user: { - id: userId, - attributes: buildVisitorAttributes(configObj, userAttributes), - }, - - context: { - accountId: configObj.accountId, - projectId: configObj.projectId, - revision: configObj.revision, - clientName: clientEngine, - clientVersion: clientVersion, - anonymizeIP: configObj.anonymizeIP || false, - botFiltering: configObj.botFiltering, - }, + ...buildBaseEvent({ + configObj, + userId, + userAttributes, + clientEngine, + clientVersion, + type: 'impression', + }), layer: { id: layerId, @@ -218,24 +242,14 @@ export const buildConversionEvent = function({ const eventValue = eventTags ? eventTagUtils.getEventValue(eventTags, logger) : null; return { - type: 'conversion', - timestamp: fns.currentTimestamp(), - uuid: fns.uuid(), - - user: { - id: userId, - attributes: buildVisitorAttributes(configObj, userAttributes), - }, - - context: { - accountId: configObj.accountId, - projectId: configObj.projectId, - revision: configObj.revision, - clientName: clientEngine, - clientVersion: clientVersion, - anonymizeIP: configObj.anonymizeIP || false, - botFiltering: configObj.botFiltering, - }, + ...buildBaseEvent({ + configObj, + userId, + userAttributes, + clientEngine, + clientVersion, + type: 'conversion', + }), event: { id: eventId,