@smartico/public-api 0.0.385 → 0.0.386

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2009,20 +2009,50 @@ const tournamentInfoItemTransform = t => {
2009
2009
  return response;
2010
2010
  };
2011
2011
 
2012
+ /**
2013
+ * Error codes returned in `err_code` by the `registerInTournament` method.
2014
+ *
2015
+ * These are terse value definitions for lookup. The full per-code narrative —
2016
+ * when each fires and how the consumer's UI should react — lives in the
2017
+ * `registerInTournament` method TSDoc, which owns the error table.
2018
+ *
2019
+ * Note the numbering break: the gems / diamonds codes are 6-digit
2020
+ * (`300010` / `300011`) while the rest of the tournament block is 5-digit;
2021
+ * they were appended after the original `30001`–`30009` range was occupied.
2022
+ * Branch on the exact numeric value, not on digit count.
2023
+ */
2012
2024
  var TournamentRegistrationError;
2013
2025
  (function (TournamentRegistrationError) {
2026
+ /** Success — registration persisted; buy-in (if any) deducted. */
2014
2027
  TournamentRegistrationError[TournamentRegistrationError["NO_ERROR"] = 0] = "NO_ERROR";
2028
+ /** Clan-based tournament and the user does not belong to a clan yet. */
2015
2029
  TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_USER_CANNOT_JOIN_WITHOUT_CLAN"] = 1010] = "TOURNAMENT_USER_CANNOT_JOIN_WITHOUT_CLAN";
2030
+ /** Instance id is invalid or the tournament was deleted. */
2016
2031
  TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_INSTANCE_NOT_FOUND"] = 30001] = "TOURNAMENT_INSTANCE_NOT_FOUND";
2032
+ /** Insufficient points balance for a points-priced buy-in. */
2017
2033
  TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_REGISTRATION_NOT_ENOUGH_POINTS"] = 30002] = "TOURNAMENT_REGISTRATION_NOT_ENOUGH_POINTS";
2034
+ /** Tournament is no longer in a registerable state (finished, cancelled, finalizing, or not yet open). */
2018
2035
  TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_INSTANCE_NOT_IN_STATE"] = 30003] = "TOURNAMENT_INSTANCE_NOT_IN_STATE";
2036
+ /** User is already registered; treat as an idempotent success. */
2019
2037
  TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_ALREADY_REGISTERED"] = 30004] = "TOURNAMENT_ALREADY_REGISTERED";
2038
+ /** User does not satisfy the tournament's segment / entry conditions. */
2020
2039
  TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_USER_DONT_MATCH_CONDITIONS"] = 30005] = "TOURNAMENT_USER_DONT_MATCH_CONDITIONS";
2040
+ /** User is not registered; anomalous on a register call (usually a server-side race). */
2021
2041
  TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_USER_NOT_REGISTERED"] = 30006] = "TOURNAMENT_USER_NOT_REGISTERED";
2042
+ /** Registration status transition is not allowed (e.g. re-registering a finished tournament). */
2022
2043
  TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_CANT_CHANGE_REGISTRATION_STATUS"] = 30007] = "TOURNAMENT_CANT_CHANGE_REGISTRATION_STATUS";
2044
+ /** Tournament filled up — maximum registrations reached. */
2023
2045
  TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_MAX_REGISTRATIONS_REACHED"] = 30008] = "TOURNAMENT_MAX_REGISTRATIONS_REACHED";
2024
- TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_REGISTRATION_NOT_ENOUGH_GEMS"] = 30010] = "TOURNAMENT_REGISTRATION_NOT_ENOUGH_GEMS";
2025
- TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_REGISTRATION_NOT_ENOUGH_DIAMONDS"] = 30011] = "TOURNAMENT_REGISTRATION_NOT_ENOUGH_DIAMONDS";
2046
+ /**
2047
+ * The user's wallet currency could not be resolved. Emitted server-side
2048
+ * during tournament score processing, NOT during registration — it is
2049
+ * never returned by `registerInTournament`. Included for completeness.
2050
+ */
2051
+ TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_INVALID_USER_CURRENCY"] = 30009] = "TOURNAMENT_INVALID_USER_CURRENCY";
2052
+ /** Insufficient gems balance for a gems-priced buy-in. */
2053
+ TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_REGISTRATION_NOT_ENOUGH_GEMS"] = 300010] = "TOURNAMENT_REGISTRATION_NOT_ENOUGH_GEMS";
2054
+ /** Insufficient diamonds balance for a diamonds-priced buy-in. */
2055
+ TournamentRegistrationError[TournamentRegistrationError["TOURNAMENT_REGISTRATION_NOT_ENOUGH_DIAMONDS"] = 300011] = "TOURNAMENT_REGISTRATION_NOT_ENOUGH_DIAMONDS";
2026
2056
  })(TournamentRegistrationError || (TournamentRegistrationError = {}));
2027
2057
 
2028
2058
  var TournamentType;
@@ -2744,12 +2774,25 @@ class WSAPIUser extends WSAPIBase {
2744
2774
  * `ach_points_ever` and {@link getLevels} would also work, but
2745
2775
  * `progress` saves the math.
2746
2776
  *
2747
- * **Cache TTL**: the SDK caches the response for 30 seconds. There is
2748
- * no push event that refreshes this cache; a server-side level change
2749
- * (visible immediately on {@link getUserProfile}'s `ach_level_current_id`
2750
- * via the user-properties update channel) becomes visible on this
2751
- * method only after the cache TTL expires, or after
2752
- * `_smartico.api.clearCaches()` is called.
2777
+ * **Cache TTL & freshness**
2778
+ * The response is cached for 30 seconds, but the SDK automatically
2779
+ * drops that cache whenever a user-properties update arrives — the
2780
+ * same live channel that backs {@link getUserProfile}. The practical
2781
+ * effect depends on the label's leveling logic:
2782
+ * - **Points-based or operator-manual leveling**: a points or level
2783
+ * change flows through the user-properties channel, so the cache is
2784
+ * busted at that moment and the next `getCurrentLevel()` call
2785
+ * returns up-to-date data without waiting out the TTL.
2786
+ * - **Counter-based leveling** (level driven by sliding-window
2787
+ * counters such as deposit or wagering totals over a recent window —
2788
+ * see {@link getUserLevelExtraCounters}): ordinary progress changes
2789
+ * are recomputed by a periodic server job and do NOT emit a
2790
+ * user-properties update, so they become visible on this method only
2791
+ * after the 30 s TTL expires (or after `_smartico.api.clearCaches()`).
2792
+ *
2793
+ * Avoid calling `clearCaches()` on the points/manual path — it's
2794
+ * unnecessary there (the cache is already refreshed on the property
2795
+ * update) and forces a slower extra round-trip.
2753
2796
  *
2754
2797
  * **Leveling logic**
2755
2798
  * The semantics of how a user advances depends on the label's
@@ -2777,10 +2820,10 @@ class WSAPIUser extends WSAPIBase {
2777
2820
  * console.log('[smartico] render level badge — name:', level.name,
2778
2821
  * 'progress:', Math.round(level.progress), '%');
2779
2822
  *
2780
- * // Detect level-up via getUserProfile's push channel.
2823
+ * // Detect level-up via getUserProfile's push channel. No clearCaches()
2824
+ * // needed — the SDK already drops the level cache on this update.
2781
2825
  * window._smartico.on('props_change', async (changed) => {
2782
2826
  * if ('ach_level_current_id' in changed) {
2783
- * await window._smartico.api.clearCaches(); // bust the 30 s cache
2784
2827
  * const fresh = await window._smartico.api.getCurrentLevel();
2785
2828
  * console.log('[smartico] user levelled up — animate badge to new level:', fresh.name);
2786
2829
  * }
@@ -2815,14 +2858,12 @@ class WSAPIUser extends WSAPIBase {
2815
2858
  * `levelsCounter2Name`.
2816
2859
  *
2817
2860
  * **Refresh cadence**
2818
- * Sliding-window counters are recomputed by a server-side job that
2819
- * runs roughly every 60 seconds against the operator's BigQuery
2820
- * dataset; level transitions driven by counter changes have a
2821
- * latency of up to several minutes after the underlying activity
2822
- * (e.g. a deposit). The SDK caches the response for 30 seconds; no
2823
- * push event refreshes this cache. After a level change visible on
2824
- * {@link getUserProfile}'s `ach_level_current_id`, call
2825
- * `_smartico.api.clearCaches()` to force a fresh fetch.
2861
+ * Sliding-window counters are recomputed by a periodic server-side
2862
+ * job. Its rebuild cadence is operator-configured per brand —
2863
+ * commonly daily, though it can be set more frequent — so level
2864
+ * transitions driven by counter changes surface with a latency tied
2865
+ * to that rebuild schedule after the underlying activity (e.g. a
2866
+ * deposit), not in real time.
2826
2867
  *
2827
2868
  * **Idempotency**: safe. Read-only. Repeated calls within the cache
2828
2869
  * window return a deep-cloned cached value without a network
@@ -3313,8 +3354,14 @@ class WSAPIMissions extends WSAPIGeneral {
3313
3354
  * **Idempotency / Side effects**: fetch-only; safe to call repeatedly.
3314
3355
  * The cache layer deduplicates concurrent calls within the TTL window.
3315
3356
  *
3357
+ * **Visitor mode**: not supported. Badges are an authenticated-only
3358
+ * feature; calling this on the visitor-mode handle (`_smartico.vapi`)
3359
+ * throws synchronously rather than silently returning an empty list.
3360
+ *
3316
3361
  * **UI guidance**: see [UI Guide — `getBadges`](../../docs/ui/missions/UIGuide_getBadges.md).
3317
3362
  *
3363
+ * @throws `Error("getBadges is not available in visitor mode")` when
3364
+ * called from a visitor-mode session.
3318
3365
  * @returns Promise resolving to `TMissionOrBadge[]`. Every item has
3319
3366
  * `type === 'badge'`. Cached for 30 s under the `Badges` key.
3320
3367
  *
@@ -3356,6 +3403,12 @@ class WSAPIMissions extends WSAPIGeneral {
3356
3403
  * ```
3357
3404
  */
3358
3405
  async getBadges() {
3406
+ // Badges are an authenticated-only feature. The visitor-mode WSAPI
3407
+ // instance (`_smartico.vapi`) is constructed without a tracker, so the
3408
+ // server would silently return nothing; throw a clear error instead.
3409
+ if (!this.api.tracker) {
3410
+ throw new Error('getBadges is not available in visitor mode');
3411
+ }
3359
3412
  return OCache.use(onUpdateContextKey.Badges, ECacheContext.WSAPI, () => this.api.badgetsGetItemsT(this.userExtId), CACHE_DATA_SEC);
3360
3413
  }
3361
3414
  /**
@@ -5434,12 +5487,10 @@ class WSAPIClans extends WSAPITournaments {
5434
5487
  * tournament requires the user to be in a clan first.
5435
5488
  * - `1006` (`JOIN_CLAN_COOLDOWN_ACTIVE`) — user is inside the
5436
5489
  * switch-cooldown window from a previous clan join (default
5437
- * 7 days, configurable per label). Surface the
5490
+ * 7 days, configurable per label). Only reachable when the user is
5491
+ * already in a *different* clan (this call is then a clan switch);
5492
+ * a first-time join never returns `1006`. Surface the
5438
5493
  * `TClans.cooldown_until` expiry in the disabled CTA.
5439
- * - `1007` (`JOIN_CLAN_ARCHIVED`) — defined on the public enum but
5440
- * the server does NOT emit this code in practice (archived clans
5441
- * are reported as `1001`). Handle it as a synonym for `1001`
5442
- * defensively, but do not rely on it.
5443
5494
  * - `1011` (`JOIN_CLAN_JOINED_AFTER_TOURNAMENT_START`) — this
5444
5495
  * method does NOT return `1011` directly. The code fires on
5445
5496
  * {@link registerInTournament} responses when the user joined
@@ -8180,15 +8231,8 @@ class WSAPILeaderBoard extends WSAPIGamePick {
8180
8231
  * the array is the prize for place 1, the second for place 2, and
8181
8232
  * so on. The array length is the number of paid places.
8182
8233
  *
8183
- * **Cache TTL — single shared key (known limitation)**
8184
- * The SDK caches the response for 30 seconds under a SINGLE shared
8185
- * key — calling `getLeaderBoard(DAILY)` followed by
8186
- * `getLeaderBoard(WEEKLY)` within the same 30 s window returns the
8187
- * cached DAILY result for the WEEKLY call. Same applies to
8188
- * switching `getPreviousPeriod`. To force a fresh fetch when
8189
- * switching periods or current/previous, call
8190
- * `_smartico.api.clearCaches()` before the second call, or simply
8191
- * wait out the TTL.
8234
+ * **Cache TTL**
8235
+ * The SDK caches each response for 30 seconds.
8192
8236
  *
8193
8237
  * **Period boundaries**
8194
8238
  * The server finalizes each period on a server-configurable
@@ -8258,8 +8302,7 @@ class WSAPILeaderBoard extends WSAPIGamePick {
8258
8302
  * }
8259
8303
  * }
8260
8304
  *
8261
- * // Switch to previous period view — but bust the cache first to avoid the shared-key collision.
8262
- * await window._smartico.api.clearCaches();
8305
+ * // Switch to previous period view — cached separately from the current period.
8263
8306
  * const prev = await window._smartico.api.getLeaderBoard(LeaderBoardPeriodType.WEEKLY, true);
8264
8307
  * console.log('[smartico] previous-week standings — render with greyed-out "ended" treatment:', prev?.users.length, 'finalists');
8265
8308
  *
@@ -8268,7 +8311,10 @@ class WSAPILeaderBoard extends WSAPIGamePick {
8268
8311
  * ```
8269
8312
  */
8270
8313
  async getLeaderBoard(periodType, getPreviousPeriod) {
8271
- return OCache.use(onUpdateContextKey.LeaderBoards, ECacheContext.WSAPI, () => this.api.leaderboardsGetT(this.userExtId, periodType, getPreviousPeriod), CACHE_DATA_SEC);
8314
+ // Cache per (periodType, current/previous) so switching tabs or
8315
+ // current↔previous within the TTL doesn't return a colliding board.
8316
+ const cacheKey = `${onUpdateContextKey.LeaderBoards}:${periodType}:${getPreviousPeriod ? 1 : 0}`;
8317
+ return OCache.use(cacheKey, ECacheContext.WSAPI, () => this.api.leaderboardsGetT(this.userExtId, periodType, getPreviousPeriod), CACHE_DATA_SEC);
8272
8318
  }
8273
8319
  }
8274
8320
 
@@ -8993,6 +9039,7 @@ class WSAPI extends WSAPIInbox {
8993
9039
  if ((data == null || (_data$props3 = data.props) == null ? void 0 : _data$props3.ach_points_balance) !== undefined || (data == null || (_data$props4 = data.props) == null ? void 0 : _data$props4.ach_gems_balance) !== undefined || (data == null || (_data$props5 = data.props) == null ? void 0 : _data$props5.ach_diamonds_balance) !== undefined) {
8994
9040
  this.notifyActivityLogUpdate();
8995
9041
  }
9042
+ OCache.clear(ECacheContext.WSAPI, onUpdateContextKey.CurrentLevel);
8996
9043
  });
8997
9044
  on(ClassId.RAF_OPTIN_RESPONSE, () => this.updateRaffles());
8998
9045
  }
@@ -10888,31 +10935,37 @@ const AvatarCustomizeErrorMessage = {
10888
10935
  [AvatarCustomizeErrorCode.AVATAR_LABEL_LIMIT]: 'The custom avatars are not available, please try again later'
10889
10936
  };
10890
10937
 
10891
- /*
10892
- * Possible error codes returned in JOIN_CLAN_RESPONSE.errCode (cid: 575).
10893
- * Clan-protocol-specific numeric codes defined in the handler spec.
10938
+ /**
10939
+ * Error codes returned in `errCode` by the `joinClan` method (also carried
10940
+ * on `TClanJoinResult`). These are terse value definitions for lookup; the
10941
+ * full per-code narrative and UI handling lives in the `joinClan` method
10942
+ * TSDoc, which owns the error table.
10894
10943
  */
10895
10944
  var JoinClanErrorCode;
10896
10945
  (function (JoinClanErrorCode) {
10897
- /** No error, join completed */
10946
+ /** Success — join completed; entry fee (if any) deducted. */
10898
10947
  JoinClanErrorCode[JoinClanErrorCode["JOIN_CLAN_OK"] = 0] = "JOIN_CLAN_OK";
10899
- /** Invalid parameters */
10948
+ /** Request was malformed (missing or invalid parameters). */
10900
10949
  JoinClanErrorCode[JoinClanErrorCode["JOIN_CLAN_INVALID_PARAMETERS"] = 1000] = "JOIN_CLAN_INVALID_PARAMETERS";
10901
- /** clan_id doesn't exist for this label */
10950
+ /** Clan doesn't exist for this label. Archived clans are also reported as `1001`. */
10902
10951
  JoinClanErrorCode[JoinClanErrorCode["JOIN_CLAN_NOT_FOUND"] = 1001] = "JOIN_CLAN_NOT_FOUND";
10903
- /** members_count >= capacity_limit */
10952
+ /** Clan is full — member capacity reached. */
10904
10953
  JoinClanErrorCode[JoinClanErrorCode["JOIN_CLAN_FULL"] = 1002] = "JOIN_CLAN_FULL";
10905
- /** Not enough Points / Gems / Diamonds for entry fee */
10954
+ /** Insufficient balance for the entry fee (points / gems / diamonds). */
10906
10955
  JoinClanErrorCode[JoinClanErrorCode["JOIN_CLAN_INSUFFICIENT_FUNDS"] = 1003] = "JOIN_CLAN_INSUFFICIENT_FUNDS";
10907
- /** User doesn't satisfy entry_conditions / entry_segment_id */
10956
+ /** User doesn't meet the clan's entry segment or conditions. */
10908
10957
  JoinClanErrorCode[JoinClanErrorCode["JOIN_CLAN_SEGMENT_MISMATCH"] = 1004] = "JOIN_CLAN_SEGMENT_MISMATCH";
10909
- /** User is not in a clan */
10958
+ /**
10959
+ * User is not in a clan. Note: a `registerInTournament` response code
10960
+ * that shares this enum — never returned by `joinClan`.
10961
+ */
10910
10962
  JoinClanErrorCode[JoinClanErrorCode["JOIN_CLAN_USER_IS_NOT_IN_CLAN"] = 1005] = "JOIN_CLAN_USER_IS_NOT_IN_CLAN";
10911
- /** User is within the CLAN_COOLDOWN_DAYS window */
10963
+ /** User is within the clan-switch cooldown window (switch only). */
10912
10964
  JoinClanErrorCode[JoinClanErrorCode["JOIN_CLAN_COOLDOWN_ACTIVE"] = 1006] = "JOIN_CLAN_COOLDOWN_ACTIVE";
10913
- /** clan_status_id != 1 (clan is archived) */
10914
- JoinClanErrorCode[JoinClanErrorCode["JOIN_CLAN_ARCHIVED"] = 1007] = "JOIN_CLAN_ARCHIVED";
10915
- /** Clan joined after tournament start */
10965
+ /**
10966
+ * Clan joined after tournament start. Note: a `registerInTournament`
10967
+ * response code that shares this enum — never returned by `joinClan`.
10968
+ */
10916
10969
  JoinClanErrorCode[JoinClanErrorCode["JOIN_CLAN_JOINED_AFTER_TOURNAMENT_START"] = 1011] = "JOIN_CLAN_JOINED_AFTER_TOURNAMENT_START";
10917
10970
  })(JoinClanErrorCode || (JoinClanErrorCode = {}));
10918
10971