@usions/sdk 2.21.0 → 2.22.0

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.
@@ -21,13 +21,17 @@ export function createWalletModule(Usion) {
21
21
 
22
22
  /**
23
23
  * Get current wallet balance
24
+ * @param {object} [opts]
25
+ * @param {boolean} [opts.fresh] - Bypass the cache and re-query the host.
26
+ * Use after out-of-band balance changes (e.g. a server-side settle).
24
27
  * @returns {Promise<number>} Balance in credits
25
28
  */
26
- getBalance: function() {
29
+ getBalance: function(opts) {
27
30
  const self = this;
31
+ const fresh = !!(opts && opts.fresh);
28
32
 
29
33
  // If we have cached balance, return it
30
- if (self._balance !== null) {
34
+ if (!fresh && self._balance !== null) {
31
35
  return Promise.resolve(self._balance);
32
36
  }
33
37
 
@@ -94,11 +98,14 @@ export function createWalletModule(Usion) {
94
98
  settled = true;
95
99
  cleanup();
96
100
  // Update cached balance from the authoritative new balance, else
97
- // best-effort subtract (no-op if balance is unknown).
101
+ // best-effort subtract now and re-query the host so the cache
102
+ // converges on the real value (an estimate would otherwise stick
103
+ // until reload).
98
104
  if (response && response.newBalance !== undefined) {
99
105
  self._balance = response.newBalance;
100
- } else if (self._balance !== null) {
101
- self._balance -= amount;
106
+ } else {
107
+ if (self._balance !== null) self._balance -= amount;
108
+ self.getBalance({ fresh: true }).catch(function() { /* keep estimate */ });
102
109
  }
103
110
  resolve(response);
104
111
  }
package/types/index.d.ts CHANGED
@@ -97,7 +97,8 @@ export interface FileStorageModule {
97
97
  // ─── Wallet ──────────────────────────────────────────────────────
98
98
 
99
99
  export interface WalletModule {
100
- getBalance(): Promise<number>;
100
+ /** Cached after the first call; pass `{ fresh: true }` to re-query the host. */
101
+ getBalance(opts?: { fresh?: boolean }): Promise<number>;
101
102
  hasCredits(amount: number): Promise<boolean>;
102
103
  requestPayment(amount: number, reason: string, data?: PaymentOptions): Promise<PaymentResponse>;
103
104
  onBalanceChange(callback: (balance: number) => void): UnsubscribeFn;
@@ -185,6 +186,9 @@ export interface PlayerJoinedData {
185
186
  export interface PlayerLeftData {
186
187
  room_id: string;
187
188
  player_id: string;
189
+ /** Authoritative roster (mirrors PlayerJoinedData) — reconcile membership from either event. */
190
+ player_ids: string[];
191
+ reason?: string;
188
192
  }
189
193
 
190
194
  export interface StateUpdateData {
@@ -901,7 +905,15 @@ export interface UsionSDK {
901
905
  config: UsionConfig;
902
906
 
903
907
  // Lifecycle
904
- init(callback: (config: UsionConfig) => void): void;
908
+ /**
909
+ * Initialize the SDK. The callback fires when the host's INIT config
910
+ * arrives; every call also returns a Promise of the same config, so
911
+ * `const config = await Usion.init()` works. `opts.timeout` (ms) rejects
912
+ * the promise with UsionError(INIT_TIMEOUT) when no INIT arrives in time
913
+ * (embedded but host silent). (promise/timeout: SDK ≥ 2.22)
914
+ */
915
+ init(callback?: (config: UsionConfig) => void, opts?: { timeout?: number }): Promise<UsionConfig>;
916
+ init(opts: { timeout?: number }): Promise<UsionConfig>;
905
917
  exit(options?: { backCount?: number }): void;
906
918
 
907
919
  // Theme & Locale
@@ -946,8 +958,8 @@ export interface UsionSDK {
946
958
  // Logging
947
959
  log(msg: string): void;
948
960
 
949
- // Generic event listener
950
- on(type: string, callback: (data: any) => void): void;
961
+ // Generic event listener (returns an unsubscribe function)
962
+ on(type: string, callback: (data: any) => void): UnsubscribeFn;
951
963
 
952
964
  // UI helpers
953
965
  setLoading(btn: HTMLElement | string, loading: boolean): void;
@@ -1064,8 +1076,14 @@ export interface CloudModule extends CloudScope {
1064
1076
  export interface Match { roomId: string; players: string[]; serviceId?: string; }
1065
1077
 
1066
1078
  export interface MatchmakingModule {
1067
- /** Join the quick-match queue; resolves when paired with online strangers. */
1068
- find(serviceId?: string, opts?: { size?: number }): Promise<Match>;
1079
+ /**
1080
+ * Join the quick-match queue; resolves when paired with online strangers.
1081
+ * `opts.timeout` (ms) bounds the wait: on expiry the queue is left and the
1082
+ * promise rejects with UsionError(MATCH_TIMEOUT). A newer find() rejects
1083
+ * the previous one with SUPERSEDED; cancel() rejects it with CANCELLED.
1084
+ * (timeout: SDK ≥ 2.22)
1085
+ */
1086
+ find(serviceId?: string, opts?: { size?: number; timeout?: number }): Promise<Match>;
1069
1087
  /** Leave the queue / stop waiting. */
1070
1088
  cancel(): Promise<any>;
1071
1089
  /** Called whenever a match is found. */
@@ -1120,16 +1138,29 @@ export declare const ERROR_CODES: {
1120
1138
  readonly NO_ROOM: 'NO_ROOM';
1121
1139
  readonly ROOM_NOT_FOUND: 'ROOM_NOT_FOUND';
1122
1140
  readonly NOT_PARTICIPANT: 'NOT_PARTICIPANT';
1141
+ readonly NOT_IN_ROOM: 'NOT_IN_ROOM';
1123
1142
  readonly NOT_AUTHORITY: 'NOT_AUTHORITY';
1124
1143
  readonly NOT_AUTHENTICATED: 'NOT_AUTHENTICATED';
1125
1144
  readonly JOIN_TIMEOUT: 'JOIN_TIMEOUT';
1126
1145
  readonly CONNECT_TIMEOUT: 'CONNECT_TIMEOUT';
1146
+ readonly INIT_TIMEOUT: 'INIT_TIMEOUT';
1147
+ readonly MATCH_TIMEOUT: 'MATCH_TIMEOUT';
1127
1148
  readonly STATE_TOO_LARGE: 'STATE_TOO_LARGE';
1128
1149
  readonly INVALID_STATE: 'INVALID_STATE';
1150
+ readonly STALE_STATE: 'STALE_STATE';
1129
1151
  readonly INVALID_NEXT_TURN: 'INVALID_NEXT_TURN';
1152
+ readonly INVALID_INPUT: 'INVALID_INPUT';
1153
+ readonly NOT_FOUND: 'NOT_FOUND';
1154
+ readonly QUOTA_EXCEEDED: 'QUOTA_EXCEEDED';
1155
+ readonly VALUE_TOO_LARGE: 'VALUE_TOO_LARGE';
1156
+ readonly LOBBY_FULL: 'LOBBY_FULL';
1157
+ readonly LOBBY_CLOSED: 'LOBBY_CLOSED';
1158
+ readonly CONFLICT: 'CONFLICT';
1130
1159
  readonly RATE_LIMITED: 'RATE_LIMITED';
1131
1160
  readonly REQUEST_TIMEOUT: 'REQUEST_TIMEOUT';
1132
1161
  readonly QUEUE_FULL: 'QUEUE_FULL';
1162
+ readonly CANCELLED: 'CANCELLED';
1163
+ readonly SUPERSEDED: 'SUPERSEDED';
1133
1164
  readonly UNSUPPORTED: 'UNSUPPORTED';
1134
1165
  readonly UNKNOWN: 'UNKNOWN';
1135
1166
  };
@@ -1139,6 +1170,8 @@ export type UsionErrorCode = keyof typeof ERROR_CODES;
1139
1170
  export declare class UsionError extends Error {
1140
1171
  readonly name: 'UsionError';
1141
1172
  readonly code: UsionErrorCode;
1173
+ /** Seconds until a RATE_LIMITED call may be retried (when the server sent it). */
1174
+ readonly retryAfter?: number;
1142
1175
  constructor(code: UsionErrorCode | string, message?: string);
1143
1176
  }
1144
1177