Skip to content

feat(rokt): send the current mParticle session id as a selectPlacements attribute - #1324

Open
jamesnrokt wants to merge 5 commits into
mainfrom
feature/rokt-kit-mparticle-session-attribute
Open

feat(rokt): send the current mParticle session id as a selectPlacements attribute#1324
jamesnrokt wants to merge 5 commits into
mainfrom
feature/rokt-kit-mparticle-session-attribute

Conversation

@jamesnrokt

@jamesnrokt jamesnrokt commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Applies the same change as mparticle-integrations/mparticle-javascript-integration-rokt#116 to the in-repo copy of the Rokt kit, so the two do not drift while the monorepo migration is in progress.

The kit read the mParticle session id once, when creating the launcher, and passed it through as the mpSessionId launcher option. That option is no longer used, and reading the value at launcher-creation time meant it went stale for the life of the page: mParticle mints a new session id on inactivity timeout (sessionTimeout, 30 minutes by default), when another tab starts a new session, and after an explicit endSession() / startNewSession(). None of that reached the launcher.

This PR:

  • Sends the session id as the mparticle_session_id attribute on each selectPlacements call. Because it is read per call, a rotated session is reflected on the next call.
  • Removes the mpSessionId launcher option from attachLauncher.
  • Adds readMpSessionId(), which reads SessionManager.getSessionId() if the facade exposes it and otherwise falls back to getSession().

Review follow-ups applied:

  • Reinstated the getSession() fallback. An earlier revision dropped it on the assumption that getSessionId() was available from core v2.23.3; that is true of the internal _SessionManager but not of the public mParticle.sessionManager facade, which exposes only getSession() in every published core through 2.78.0:

    // mparticle-instance-manager.ts
    this.sessionManager = {
        getSession: function() {
            return self.getInstance()._SessionManager.getSessionId();
        },
    };

    Dropping the fallback made the attribute silently absent — isFunction(undefined) is false, so readMpSessionId() always returned undefined. Confirmed in production against the standalone kit 1.33.0 on core 2.78.0, where the attribute was absent from all 79,987 wsdk events in a sampled window. The public getSession() is not deprecated and emits no warning: it calls _SessionManager.getSessionId() directly, bypassing the deprecated internal _SessionManager.getSession(). Only the internal method carries @deprecated and logDeprecatedMethodUsage.

  • Widened the sessionManager interface back to accept both accessors. It had been narrowed to an optional getSessionId?(), so TypeScript could not catch the absence.

  • Added an isFunction helper and used it for all five typeof x === 'function' checks in the kit rather than leaving the new one inconsistent with the rest.

Testing Plan

  • kits/rokt: 237/237 tests pass; vite build clean.

  • New unit tests cover: the session id current at the time of each call (asserted across a rotation between two calls), the attribute being omitted when sessionManager is unavailable, a facade exposing only getSession (the real shape) yielding the attribute, getSessionId being preferred when both are present, the attribute being omitted when neither accessor exists, and createLauncher no longer receiving mpSessionId.

  • 35 existing full-payload toEqual assertions were updated, since the attribute is present on every call. The #selectPlacements beforeEach now pins a known sessionManager; previously these tests depended on an earlier test deleting window.mParticle.sessionManager without restoring it, which made results order-dependent.

  • Test fixtures in test/vitest.setup.ts and tests.spec.ts use getSession, matching the real public facade. An earlier revision moved them to getSessionId, which is why the suite went green against a facade that does not exist.

  • kits/rokt/dist is intentionally not included. Note this copy has no src/utils.ts, so isFunction sits with the existing module-level helpers rather than in a utils module.

  • kits/rokt has 7,771 pre-existing prettier/prettier lint errors on a pristine tree (an indentation-width mismatch across all four files). This PR does not change that count materially and does not attempt to reformat the kit.

  • Additional testing worth doing: confirm on a long-lived page that a session which times out is reflected on the next selectPlacements call, and that the offers request body carries attributes.mparticle_session_id.

  • Note for reviewers running tests locally: kits/rokt uses vitest 4, which needs Node 22. On Node 20 it fails with bad option: --no-experimental-webstorage.

…ts attribute

The kit read the mParticle session id once, when creating the launcher, and
passed it through as the mpSessionId launcher option, which is no longer used.

Send it as the mparticle_session_id attribute on each selectPlacements call
instead. Reading it per call means a session that has rotated — on inactivity
timeout, when another tab starts a new session, or after an explicit
endSession() — is reflected on the next call, rather than being pinned to
whatever was current when the launcher was created.

Prefer SessionManager.getSessionId() over the deprecated getSession(), falling
back only for core SDK versions that predate it. getSession() logs a
deprecation warning and reports MP_DEPRECATED_METHOD_USAGE, so every launcher
creation was emitting one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jamesnrokt
jamesnrokt requested a review from a team as a code owner August 17, 2026 15:41
@jamesnrokt
jamesnrokt changed the base branch from master to main August 17, 2026 15:42
Calls mp() once instead of twice and reads more directly. No behaviour change:
mp() returns window.mParticle, which may be undefined, and the following guard
handles that case either way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@cursor

cursor Bot commented Aug 17, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes the integration contract for Rokt (attribute vs launcher option) and touches the hot selectPlacements path; behavior is well-covered by tests but partners consuming the old launcher field need to migrate.

Overview
Moves the mParticle session id from launcher creation to every selectPlacements call, so rotated sessions (timeout, new tab, endSession / startNewSession) show up on the next placement instead of staying stuck at the value read when the launcher was created.

  • Removes passing mpSessionId into createLauncher / createLocalLauncher in attachLauncher.
  • Adds mparticle_session_id to the merged selectPlacements attributes when a session id is available, via new readMpSessionId() (prefers sessionManager.getSessionId, falls back to getSession).
  • Introduces shared isFunction and uses it for callable checks (launcher readiness, integration attributes, local session attributes, test helper export).

Tests now assert the attribute on placement payloads (not on launcher options), cover rotation between calls and missing session APIs, and pin sessionManager in selectPlacements setup for stable ordering.

Reviewed by Cursor Bugbot for commit 3125de4. Bugbot is set up for automated code reviews on this repo. Configure here.

…Function util

The kit requires @mparticle/web-sdk ^2.62.0 and getSessionId() has shipped
since v2.23.3, so the getSession() fallback was unreachable for every
supported core version. Removing it also removes the last caller of a
deprecated method.

Adds an isFunction helper and uses it for all five typeof-function checks in
the kit, rather than leaving the new one inconsistent with the rest. The
standalone kit repo keeps this in src/utils.ts; this copy has no utils module,
so it sits with the existing module-level helpers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d11c9e1. Configure here.

Comment thread kits/rokt/src/Rokt-Kit.ts
jamesnrokt and others added 2 commits August 17, 2026 14:10
This copy has no utils module or utils spec, so isFunction is exposed through
testHelpers alongside the other module-level helpers and covered in the kit
spec.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…er facade

readMpSessionId called mParticle.sessionManager.getSessionId(), which does not
exist. The public facade exposes only getSession(); getSessionId() lives on the
internal _SessionManager and has never been re-exported. Verified against the
published bundles for core 2.62.0, 2.75.1 and 2.78.0 — all identical.

isFunction(undefined) was therefore always false, readMpSessionId always
returned undefined, and mparticle_session_id was never added to the
selectPlacements attributes. Confirmed in production against the standalone
kit 1.33.0 on core 2.78.0, where the attribute was absent from all 79,987 wsdk
events in a sampled window.

Read getSessionId if the facade exposes it and fall back to getSession, so this
works on every supported core and picks up the non-deprecated name if one is
ever added. An earlier revision of this branch dropped that fallback on the
assumption that getSessionId() was public from v2.23.3; that holds for the
internal _SessionManager but not for the public facade.

The public getSession() is not deprecated and emits no warning: it calls
_SessionManager.getSessionId() directly, bypassing the deprecated internal
_SessionManager.getSession(). Widen the interface back to accept both
accessors — it had been narrowed to an optional getSessionId, so TypeScript
could not catch the absence.

Move the test fixtures back to getSession so the suite exercises the real
facade shape, and add coverage for the getSession-only shape, getSessionId
preference, and the neither-accessor case.

Mirrors mparticle-integrations/mparticle-javascript-integration-rokt#117.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants