Skip to content

feat(rokt): expose terminate on the window.mParticle.Rokt interface - #1328

Open
jamesnrokt wants to merge 1 commit into
developmentfrom
feat/rokt-manager-terminate
Open

feat(rokt): expose terminate on the window.mParticle.Rokt interface#1328
jamesnrokt wants to merge 1 commit into
developmentfrom
feat/rokt-manager-terminate

Conversation

@jamesnrokt

@jamesnrokt jamesnrokt commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds RoktManager.terminate(), exposing window.mParticle.Rokt.terminate() as a supported teardown path for partners who cannot simply destroy the container element — SPA route changes and confirmation pages in particular.

Today partners reach for the undocumented window.Rokt.currentLauncher?.terminate(). This routes the same call through the documented interface.

Pairs with mparticle-integrations/mparticle-javascript-integration-rokt#122, which adds the terminate() the manager delegates to. That PR should merge and release first — until a kit carrying it is on the page, this method logs that the attached kit version does not support terminate.

Changes

  • RoktManager.terminate(): Promise<void> — delegates to this.kit.terminate(), which forwards to the Rokt launcher.
  • IRoktKit.terminate added as optional, guarded at the call site with isFunction. The Rokt Kit releases on its own cadence, so a kit published before this change genuinely will not implement it — version skew is real rather than theoretical.

IRoktLauncher is untouched: the manager only ever calls through the kit, and the kit owns the launcher-facing type.

Behaviour

State Result
Kit + launcher attached awaits kit.terminate()
Nothing attached Resolves as a no-op, logs verbose
Kit attached, no launcher Resolves as a no-op
Kit predates terminate Resolves, logs error
kit.terminate() rejects Resolves, logs error

terminate() never rejects — teardown should not be something callers have to defend against.

A pre-ready call is not queued

Every other proxied method uses deferredCall when the kit isn't ready. terminate deliberately does not. Replaying a teardown against a launcher created later would silently tear down placements the caller never asked to remove; with no launcher there is nothing to terminate, so the call resolves as a no-op instead. This asymmetry is called out in the method's doc comment and pinned by tests.

Also fixes a latent snippet bug

terminate is already in the snippet's roktMethods stub list (snippet.js), so a snippet-loaded page could queue Rokt.terminate() before init. At flush time processPreloadedItem hit an undefined method, threw, and processReadyQueue logged Unable to compute proper mParticle function. That path now dispatches correctly.

⚠️ getVersion has the same latent gap — it is in the snippet stub list but has no RoktManager implementation. Left out of scope here; happy to add it in a follow-up if wanted.

Not included

kits/rokt/ in this repo is a stale vendored snapshot of the Rokt kit (missing storage.ts, utils.ts, pageViewStorage.ts) and is not loaded by any build or test target, so it was intentionally left untouched. The live kit change is in the companion PR.

Testing

  • npm run lint — pass
  • npm run test:jest — 632/632 across 26 suites
  • Karma (ChromeHeadless) — 1087/1087

7 new #terminate cases in test/jest/roktManager.spec.ts cover each row of the behaviour table above, plus a case asserting the manager stays ready so repeat calls keep reaching the kit. The suite fails to compile against development without the source change.

Note for reviewers running locally: Karma's default config includes FirefoxHeadless and aborts the whole run if Firefox isn't installed. Use npx karma start test/karma.config.js --browsers ChromeHeadless.

🤖 Generated with Claude Code

@jamesnrokt
jamesnrokt requested a review from a team as a code owner August 18, 2026 17:11
@cursor

cursor Bot commented Aug 18, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Additive public API with defensive error handling; behavior is isolated to Rokt teardown and covered by new unit tests.

Overview
Adds window.mParticle.Rokt.terminate() as the documented way to tear down the Rokt launcher and placements (e.g. SPA navigations), delegating to optional kit.terminate() when the attached Rokt kit supports it.

RoktManager.terminate() always resolves (never rejects): it no-ops with verbose logging when the manager is not ready or there is no launcher, logs an error for older kits without terminate, and swallows kit teardown failures after logging. Unlike other proxied Rokt APIs, pre-ready calls are not queued so a late replay cannot tear down placements the host did not intend to remove.

IRoktKit.terminate is optional to tolerate kit/SDK version skew. Seven Jest cases cover delegation, timing, no-op paths, unsupported kit, rejection handling, and repeat calls while staying ready.

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

Comment thread kits/adobe-target/dist/AdobeTarget-Kit.iife.js Outdated
@jamesnrokt
jamesnrokt changed the base branch from development to master August 18, 2026 17:19
Partners tearing down placements had no supported teardown path and were
falling back to the undocumented `window.Rokt.currentLauncher?.terminate()`.
`terminate` is already stubbed in the Rokt snippet, so a snippet-loaded page
could queue the call and then fail to dispatch it.

RoktManager.terminate() delegates to the kit, which forwards to the Rokt
launcher. The kit method is optional on IRoktKit and guarded with isFunction
because the Rokt Kit releases independently — a kit published before this
change will not implement it.

Unlike the other proxied methods a pre-ready call is not queued. Replaying a
teardown against a launcher created later would tear down placements the
caller never asked to remove; with no launcher there is nothing to terminate,
so the call resolves as a no-op.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jamesnrokt
jamesnrokt force-pushed the feat/rokt-manager-terminate branch from 522f21e to b41570f Compare August 18, 2026 17:22
@jamesnrokt
jamesnrokt changed the base branch from master to development August 18, 2026 17:22
@sonarqubecloud

Copy link
Copy Markdown

@rmi22186 rmi22186 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This LGTM. @mattbodle's comment over at mparticle-integrations/mparticle-javascript-integration-rokt#122 shouldn't affect the implementation here, though I'm not 100% clear on the use case of creating a new launcher right after terminating. That seems unlkely?

Edit: Oh I see, for SPAs, so a customer may go back and make another purchase, right?

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.

3 participants