Files
rudder-js-sdk/CHANGELOG.md
T
edmand46 7271874cac
CI / check (push) Successful in 16s
CI / publish (push) Has been skipped
2.0.0: changelog and skill docs for slugs and environments
Claude-Session: https://claude.ai/code/session_01SMCvdwDmuxoaqGgvGBLk1V
2026-09-06 22:39:03 +03:00

7.1 KiB

Changelog

2.0.0

Breaking change — major bump, required by the backend environments release. Every project now has exactly two environments, staging and prod, and the SDK key passed as projectKey decides which one the player belongs to. The environment never appears in the client API: it is resolved at login and carried inside the access and refresh tokens. Tokens issued before this release have no environment claim and are rejected with 401, so the first call after the backend upgrade refreshes, fails, clears the token store and emits 'signed-out' to every onAuthStateChange listener. Log the player in again with client.auth.loginWithDevice() / loginWithCustom().

Quests, scenarios and offers are addressed by their slug instead of their id, because ids differ between staging and prod while slugs are stable. Renamed accordingly: Quest.id is now Quest.slug, client.quests.claim() takes a quest slug, reportProgress() resolves to the slugs of the completed quests (ReportQuestProgressResponse.completedQuestSlugs), client.stores.purchase(storeSlug, offerSlug, options?) takes an offer slug and OfferHandle carries a slug alongside its id, QuestMetrics.purchaseOffer(offerSlug) builds its metric from the offer slug, and every scenario-scoped type exposes scenarioSlug instead of scenarioIdPendingEffect, ScenarioCompletedEffect, ScenarioFailedEffect, the battle pass requests and client.battlePass.getProgress(scenarioSlug, nodeId). offer.buy() is unchanged; it now binds the slug for you. Leaderboards, items and stores already used slugs and are untouched.

Also shipped here, previously committed but never published: the effects client reconciles against every GET /sdk/v1/scenarios/pending response, so a run that disappears server-side (finished elsewhere, expired after a promote) now emits onScenarioCompleted instead of lingering; and run_not_active joins unknown_run and run_expired as a terminal rejection that drops the run and emits onScenarioFailed.

1.0.0

  • Scenario execution moved server-side. The SDK no longer walks a local DAG or persists plan state to IndexedDB.
  • Removed RudderClientOptions.runtime.planStateStore and the PlanStateStore type.
  • GET /sdk/v1/scenarios/pending is polled on login, on a ~30s heartbeat, and at each effect waitDeadline. Completions POST /sdk/v1/scenarios/callback; the response may carry the next PendingEffect.
  • Scenario remote_config_override nodes no longer emit onConfigChanged (the server applies the override). The ConfigChangedEffect type and onConfigChanged subscription remain.

0.6.0

  • LeaderboardSession.claim() / effect claim() completes the leaderboard node with handle onClaim. The server matches live rank to an authored place and continues from that place (Grant Reward and/or In-App Message).
  • rewardClaimed() is a deprecated alias for claim() and will be removed in the next SDK version.
  • rank_not_eligible on Claim leaves the session open (retry Claim or End); it no longer fails the run.

0.5.1

  • QuestMetrics / reportProgress: custom free-text metrics no longer progress quests. Report a released catalog counter slug instead. purchaseOffer / purchaseItem helpers are unchanged (server-side shop fan-out).

0.5.0

  • client.auth.loginWithCustom({ customData, region?, language?, nickname? }) — custom webhook auth, same token + runtime start as loginWithDevice.
  • QuestMetrics.purchaseOffer / purchaseItem helpers for the shop purchase metric format.
  • Typecheck against regenerated models: listQuests no longer takes a body, battle-pass track is 'free' | 'premium', scenario run status has no unknown_run.

0.4.0

  • Fixed BattlePassLevelSession.level reading node data key level — the admin editor writes levelNumber, so tiers always reported 0. The session now reads levelNumber, matching the editor and server validation.
  • UGC support removed from the generated wire types (src/generated/ugc.ts deleted by apigen); no UGC surface was ever exposed by this SDK.
  • Generated API types regenerated from the gateway openapi spec, adding the new platform operations.

0.3.0

Breaking changes — the package was aligned with the Rudder SDK glossary and the regenerated wire types (src/generated, apigen). No compatibility shims are provided.

Auth

  • client.auth.loginViaDevice(region, language, nickname?) replaced by client.auth.loginWithDevice(options?: { region?, language?, nickname? }). Default region is now 'global' (was 'en'); default language stays 'en'.
  • New client.auth.onAuthStateChange(cb) — fires immediately with the current state, then on every 'signed-in' | 'signed-out' transition (login, logout, and unrecoverable session expiry in the transport).
  • New client.auth.isAuthenticated.

Client configuration

  • tokenStore in RudderClientOptions is now optional. Default: localStorage-backed store with a silent in-memory fallback where localStorage is unavailable (SSR, private mode). New createDefaultTokenStore() export.
  • Invalid client options (baseUrl / projectKey missing) now throw RudderError with code: 'sdk/invalid-options' instead of a plain Error.
  • New onEffectError option — called when an effect handler throws (default: console.error); previously such errors were swallowed silently.

Renames

  • client.configclient.remoteConfig (canonical glossary name).
  • client.battlepassclient.battlePass; BattlepassServiceBattlePassService.
  • Effects: onBattlepass / BattlepassEffectonBattlePass / BattlePassEffect; onBattlepassLevel / BattlepassLevelEffectonBattlePassLevel / BattlePassLevelEffect.
  • Generated types: SdkQuestQuest; *Battlepass* request/response types → *BattlePass*.
  • Internal transport sendAsyncrequest (not part of the public surface).

Leaderboards

  • Removed LeaderboardsService.getRanking(slug, limit) and LeaderboardsService.submitScore(slug, score). Single path: client.leaderboards.findBySlug(slug)handle.list(limit?) / handle.submit(score).

Errors

  • RudderNetworkError.inner → standard Error.cause.
  • RudderHttpError.code is typed as RudderErrorCode | (string & {}) (generated union of server error codes, plus room for unknown strings).
  • New exports: RudderErrorCode (type), RudderErrorCodes (constants), SDK_ERROR_INVALID_OPTIONS, RudderErrorCodeLike (type).

Public surface

  • The barrel no longer exports getOrCreateDeviceId, domain classes (PlayerDomain, …) or service constructors (AuthService, …) as values — they remain available as types. Instances live on the client.
  • SubmittedBy is no longer re-exported (UGC is unsupported on web).

Bundle

  • The scenario engine and the IndexedDB plan store are loaded lazily (dynamic import) on first login / first runtime access — a thin client never pulls the scenario machinery into the initial chunk.
  • The package now ships both ESM (dist/index.js) and CJS (dist/index.cjs) builds with matching exports entries.