4 Commits

Author SHA1 Message Date
edmand46 04e3565412 0.6.0: LeaderboardSession.claim, rank_not_eligible is recoverable
CI / publish (push) Successful in 27s
CI / check (push) Successful in 59s
onClaim replaces onRewardClaimed. rewardClaimed() is a deprecated alias removed in the next version.
2026-08-29 11:33:01 +03:00
edmand46 19a296ab9a ci: publish with NPM_TOKEN PAT (job GITEA_TOKEN cannot write org packages)
CI / publish (push) Successful in 29s
CI / check (push) Successful in 58s
2026-08-28 18:42:59 +03:00
edmand46 a72989402e 0.5.1: custom quest metrics no-op, doc fix
CI / publish (push) Failing after 31s
CI / check (push) Successful in 1m5s
2026-08-28 17:38:02 +03:00
edmand46 3556c0b035 ci: grant packages:write to publish job (GITEA_TOKEN 401 on npm publish) 2026-08-28 17:38:02 +03:00
7 changed files with 45 additions and 8 deletions
+4 -1
View File
@@ -35,6 +35,9 @@ jobs:
if: startsWith(github.ref, 'refs/tags/v') if: startsWith(github.ref, 'refs/tags/v')
needs: check needs: check
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -55,4 +58,4 @@ jobs:
- name: Publish - name: Publish
run: npm publish run: npm publish
env: env:
NODE_AUTH_TOKEN: ${{ secrets.GITEA_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+17
View File
@@ -1,5 +1,22 @@
# Changelog # Changelog
## 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 ## 0.5.0
- `client.auth.loginWithCustom({ customData, region?, language?, nickname? })` - `client.auth.loginWithCustom({ customData, region?, language?, nickname? })`
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@rudder/js-sdk", "name": "@rudder/js-sdk",
"version": "0.5.0", "version": "0.6.0",
"publishConfig": { "publishConfig": {
"registry": "https://hub.rudder.build/api/packages/rudder/npm/" "registry": "https://hub.rudder.build/api/packages/rudder/npm/"
}, },
+4 -1
View File
@@ -35,6 +35,8 @@ export interface StoreOfferEffect {
export interface LeaderboardEffect { export interface LeaderboardEffect {
end(): Promise<void>; end(): Promise<void>;
claim(): Promise<void>;
/** @deprecated Use {@link LeaderboardEffect.claim}. Removed in the next SDK version. */
rewardClaimed(): Promise<void>; rewardClaimed(): Promise<void>;
} }
@@ -191,7 +193,8 @@ export class EffectsCenter implements Effects {
emitLeaderboard(session: LeaderboardSession): void { emitLeaderboard(session: LeaderboardSession): void {
this.emit(this.leaderboardHandlers, { this.emit(this.leaderboardHandlers, {
end: () => session.end(), end: () => session.end(),
rewardClaimed: () => session.rewardClaimed(), claim: () => session.claim(),
rewardClaimed: () => session.claim(),
}); });
} }
+3 -2
View File
@@ -3,8 +3,9 @@
* *
* Purchase metrics are reported automatically server-side by the shop * Purchase metrics are reported automatically server-side by the shop
* purchase fan-out, so these helpers exist mainly to name the format * purchase fan-out, so these helpers exist mainly to name the format
* instead of hardcoding it. Any other metric is a custom string reported via * instead of hardcoding it. Catalog counter slugs are reported via
* {@link QuestsService.reportProgress}. * {@link QuestsService.reportProgress}. Custom free-text metrics no longer
* progress quests — they no-op at runtime.
*/ */
/** Metric for purchasing a store offer; auto-reported on purchase. */ /** Metric for purchasing a store offer; auto-reported on purchase. */
+8
View File
@@ -61,6 +61,10 @@ function isTransientHttpError(err: unknown): boolean {
return false; return false;
} }
function isRankNotEligible(err: unknown): boolean {
return err instanceof RudderHttpError && err.code === 'rank_not_eligible';
}
export class ScenarioService<TConfig extends RemoteConfigShape = RemoteConfigShape> { export class ScenarioService<TConfig extends RemoteConfigShape = RemoteConfigShape> {
private readonly runs = new Map<string, RuntimeRun>(); private readonly runs = new Map<string, RuntimeRun>();
@@ -434,6 +438,10 @@ export class ScenarioService<TConfig extends RemoteConfigShape = RemoteConfigSha
await this.persist(); await this.persist();
} catch (err) { } catch (err) {
run.pendingTransitions--; run.pendingTransitions--;
if (isRankNotEligible(err)) {
await this.persist();
throw err;
}
this.failRun( this.failRun(
run, run,
nodeId, nodeId,
+8 -3
View File
@@ -180,14 +180,19 @@ export class LeaderboardSession {
async end(): Promise<void> { async end(): Promise<void> {
if (this.resolved) return; if (this.resolved) return;
this.resolved = true;
await this.context.complete('onEnd'); await this.context.complete('onEnd');
this.resolved = true;
} }
async rewardClaimed(): Promise<void> { async claim(): Promise<void> {
if (this.resolved) return; if (this.resolved) return;
await this.context.complete('onClaim');
this.resolved = true; this.resolved = true;
await this.context.complete('onRewardClaimed'); }
/** @deprecated Use {@link LeaderboardSession.claim}. Removed in the next SDK version. */
async rewardClaimed(): Promise<void> {
return this.claim();
} }
} }