feat(audience): add pixel core class, consent state machine, and session cookie#2830
Merged
Conversation
…r, and snippet Add the pixel package scaffold and three self-contained modules that have no dependency on PR #2824. The package builds to a single IIFE bundle (dist/imtbl.js) targeting <10KB gzipped (currently 823 bytes). Modules: - attribution: UTM params, ad click IDs, referrer, landing page (session-cached) - loader: command-queue pattern (window.__imtbl) with pre-load replay - snippet: embeddable <script> tag generator for studio integration Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
View your CI Pipeline Execution ↗ for commit 46a42d8
☁️ Nx Cloud last updated this comment at |
… reference Add dclid (Google DV360) and li_fat_id (LinkedIn) to match the Tracking Pixel Event Reference doc. Also add referral_code parsing and touchpoint_type derivation (set to 'click' when UTMs or click IDs are present). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ion cookie Wire the pixel to audience-core now that PR #2824 has merged: - Consent state machine: three-level (none/anonymous/full), DNT/GPC detection, queue purge on downgrade to none, userId strip on downgrade to anonymous, fire-and-forget PUT to /v1/audience/tracking-consent - Session cookie: _imtbl_sid with 30-min rolling expiry - Pixel class: init creates MessageQueue with storagePrefix isolation, auto-fires PageMessage with attribution context, supports identify at full consent, setConsent, and destroy - Build config: resolves audience-core from source via tsup alias for tree-shaken self-contained IIFE bundle (8.04 KB raw / 3.2 KB gzipped) - Metrics stub: no-op stubs so the pixel bundle doesn't ship internal telemetry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
e1bc2e5 to
8f6bce0
Compare
Add session lifecycle tracking to the Pixel class: - Fire session_start track event on new session creation - Fire session_end track event on pagehide/visibilitychange with duration - Refactor session module to return SessionResult with isNew flag - Fix test listener leaking by cleaning up pixel instances in afterEach Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move session management, attribution tracking, and consent state machine from @imtbl/pixel into @imtbl/audience-core so the web SDK can share them. - session.ts: use SESSION_COOKIE from core config instead of duplicating - attribution.ts: UTM params, click IDs, referrer, sessionStorage caching - consent.ts: three-level state machine with DNT/GPC, queue purge/transform - Remove pixel re-exports of core modules (no backwards compat needed yet) - Add SESSION_MAX_AGE constant to core config - Pixel now imports everything from @imtbl/audience-core Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Read version from package.json in tsup.config.ts and inject it via esbuild define as PIXEL_VERSION_INJECTED. This stamps every event payload with the correct libraryVersion automatically — no manual bumping needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nattb8
reviewed
Apr 7, 2026
nattb8
reviewed
Apr 7, 2026
nattb8
reviewed
Apr 7, 2026
nattb8
reviewed
Apr 7, 2026
…sent Resolve conflicts: keep HEAD versions for pixel package config, re-delete attribution files that were reintroduced from main (#2829), add packages/audience/sdk from main to pnpm-workspace.yaml. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…load fix Review feedback from Natalie on PR #2830: 1. Extract buildBase() helper in Pixel class to deduplicate messageId, eventTimestamp, anonymousId, surface, and context fields across page(), identify(), fireSessionStart(), and fireSessionEnd(). 2. Fix consent PUT payload: rename `consentLevel` to `status` and add `source` field to match backend OAS. Accept source as a parameter to createConsentManager() so pixel passes 'pixel' and web SDK can pass 'sdk'. 3. Add comment on direct fetch usage in consent (different method/payload than httpSend's BatchPayload POST). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nattb8
previously approved these changes
Apr 7, 2026
Add method option to TransportOptions so consent module can use httpSend instead of raw fetch. Type the consent payload as ConsentUpdatePayload and widen httpSend to accept both BatchPayload and ConsentUpdatePayload. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nattb8
approved these changes
Apr 8, 2026
JCSanPedro
approved these changes
Apr 8, 2026
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Wires the pixel package to
@imtbl/audience-coreand lifts shared modules into core:session.ts):_imtbl_sidcookie with 30-min rolling expiry,getOrCreateSession()returnsSessionResultwithisNewflag for session lifecycle eventsattribution.ts): UTM params, click IDs, referrer, landing page, sessionStorage cachingconsent.ts): Three-level consent (none/anonymous/full) with DNT/GPC detection, queue purge on downgrade tonone,userIdstripping on downgrade toanonymous, PUT to/v1/audience/tracking-consentviahttpSendhttpSend→TransportOptionsnow supportsmethod(default POST) and typedConsentUpdatePayload, so consent uses the shared transport instead of rawfetchpixel.ts):init()createsMessageQueuewithstoragePrefixisolation, auto-firesPageMessagewith attribution context, firessession_starton new sessions andsession_endon page unload (with duration), supportsidentify(full consent only),setConsent, anddestroy. Common message fields extracted intobuildBase()helper.definePixel now imports session, attribution, and consent from
@imtbl/audience-core— no duplication. The pixel'sindex.tsonly exports pixel-specific code (Pixel class, loader, snippet).IIFE bundle: 9.05 KB raw (well under 10 KB budget).
Knowingly deferred to follow-up PRs
window.__imtblcommand queue → Pixel instance — PR feat(audience): bootstrap wiring, GA/Meta IDs, unload fix #2831)form_submitted/link_clickedauto-capture (explicitly out of scope per Linear issue)Test plan
pnpm --filter @imtbl/audience-core test— 87/87 passing (11 suites)pnpm --filter @imtbl/pixel test— 26/26 passing (3 suites)pnpm --filter @imtbl/pixel build— IIFE bundle produced (9.05 KB)pnpm --filter @imtbl/pixel lint— cleanpnpm --filter @imtbl/pixel typecheck— clean🤖 Generated with Claude Code