feat: add trackEvent for custom pipeline events#384
Conversation
Zaimwa9
left a comment
There was a problem hiding this comment.
Thanks for picking this up. 2 main comments:
- One related to the identifying behavior of the custom events and the risk of loosing them (or relevant non-identified context)
- Some comments to avoid code repetition
Additionally, i'll work now on removing the trimPipelineBuffer as described here as I think it can definitely get improved
flagsmith-core.ts
Outdated
| } | ||
| } | ||
|
|
||
| private buildCustomEvent(eventName: string, identityIdentifier: string | null, metadata?: Record<string, unknown>, timestamp?: number): IPipelineEvent { |
There was a problem hiding this comment.
We should extract the whole logic from here :
and be able to use the buildCustomEvent with both FLAG_EVALUATION and CUSTOM_EVENT
There was a problem hiding this comment.
Including using get sdkMetadata for the above. NIT: As it also includes the page_url we could rename it into something like getEventMetadata and also rename buildCustomEvent into buildAnalyticEvent
Same with currentTraitsSnapshot that could replace my previous inline ternary
There was a problem hiding this comment.
Makes sense, both build the same IPipelineEvent shape. I'll consolidate into a single shared method that takes event_type as a parameter.
Agreed — getEventMetadata and buildAnalyticEvent are more accurate now that they serve both event types. I'll also reuse currentTraitsSnapshot in the flag evaluation path to replace the inline ternary.
Zaimwa9
left a comment
There was a problem hiding this comment.
Thanks for the changes. Ready to approve after rebase + one nit
| * Requires `evaluationAnalyticsConfig` to be set; no-op otherwise. | ||
| * Events are sent with the current identity (or null if anonymous). | ||
| * @experimental Internal use only — API may change without notice. | ||
| * @hidden |
There was a problem hiding this comment.
just missing the internal tag here too
Add trackEvent(eventName, metadata?) to the public type definitions, allowing custom events to be sent through the evaluation analytics pipeline. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add trackEvent method that sends custom_event through the analytics pipeline batch endpoint. Events tracked before identify() are buffered in pendingCustomEvents and drained once identity is set, preserving original timestamps. Pending events are cleared on logout. Includes helper methods (getPageUrl, currentTraitsSnapshot, sdkMetadata, buildCustomEvent) to keep the implementation clean. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cover custom event shape, no-op without config, no-op with empty name, queue-before-identify with drain, immediate flush when flushInterval is 0, no deduplication, timestamp preservation, cleanup on logout, and pending buffer maxBuffer cap. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… trackEvent Use the stricter Record<string, unknown> for user-provided metadata, which forces consumers to narrow values before using them. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace string literals 'flag_evaluation' and 'custom_event' with PipelineEventType.FLAG_EVALUATION and PipelineEventType.CUSTOM_EVENT to avoid magic strings and ensure type safety. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace 'custom_event' string literals with PipelineEventType.CUSTOM_EVENT in test assertions and helpers - Export PipelineEventType from index.ts for consumer access - Add test for identify → logout → track cycle to verify state resets Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mark evaluationAnalyticsUrl, evaluationAnalyticsMaxBuffer, pipelineEvents, pipelineAnalyticsInterval, isPipelineFlushing, pipelineRecordedKeys, and pendingCustomEvents as private to prevent external access. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Custom events are now sent immediately with the current identity (or null if anonymous), instead of being buffered until identify() is called. This prevents events from being silently lost when identify() is never called and supports anonymous tracking use cases (e.g. public pages, pre-login). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract shared buildAnalyticEvent method that handles both FLAG_EVALUATION and CUSTOM_EVENT types, replacing the separate buildCustomEvent and inline event construction in recordPipelineEvent. Rename sdkMetadata to getEventMetadata (includes page_url, not just SDK info) and reuse currentTraitsSnapshot in the flag evaluation path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ffa2f7f to
3879f71
Compare
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@talissoncosta Sorry just missing the latest code from |
Remove trimPipelineBuffer, aligning with parent branch (36066b2). Add buffer overflow flush condition to trackEvent, matching the approach in recordPipelineEvent. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2efe60e to
ca2ed55
Compare
0e819eb
into
feat/send-evaluation-data-to-analytics-pipeline
Summary
trackEvent(eventName, metadata?)public method to send custom events through the evaluation analytics pipeline (v1/analytics/batch)nullif anonymous) — no bufferingevaluationAnalyticsConfig; no-op otherwisePipelineEventTypeenum (FLAG_EVALUATION,CUSTOM_EVENT) to replace magic strings, exported fromindex.tsfor consumer accessbuildAnalyticEventmethod for both flag evaluations and custom eventssdkMetadata→getEventMetadata, reusecurrentTraitsSnapshotacross event typesRecord<string, unknown>instead ofRecord<string, any>for metadata, enforcing type narrowing on consumersTest plan
flushInterval === 0, no deduplication, null identity after logout