@sendoracloud/sdk-react-native 1.31.0 → 1.33.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.
package/dist/index.cjs CHANGED
@@ -202,7 +202,7 @@ var Storage = class {
202
202
  // package.json
203
203
  var package_default = {
204
204
  name: "@sendoracloud/sdk-react-native",
205
- version: "1.31.0",
205
+ version: "1.33.0",
206
206
  description: "Sendora Cloud React Native + Expo SDK \u2014 analytics, identity, push-token registration, auth (incl. Game Center / Play Games), deep links (Branch / Firebase Dynamic Links parity). Auth + analytics + deep links work in Expo Go; push-token registration and the no-arg Game Center / Play Games sign-in require a Dev Client (EAS Build or `npx expo prebuild`).",
207
207
  type: "module",
208
208
  main: "./dist/index.cjs",
@@ -614,6 +614,7 @@ var Auth = class {
614
614
  this.deletionCancelledListeners = /* @__PURE__ */ new Set();
615
615
  this.authStateListeners = /* @__PURE__ */ new Set();
616
616
  this.lastDeletionCancelled = null;
617
+ this.lastAnonRetirement = null;
617
618
  this.lastTakeover = null;
618
619
  /**
619
620
  * Anon refresh token captured at `signIn()` time, stashed keyed to the
@@ -807,6 +808,19 @@ var Auth = class {
807
808
  getLastDeletionCancelled() {
808
809
  return this.lastDeletionCancelled;
809
810
  }
811
+ /**
812
+ * What the last sign-in did with this device's guest account, or null if no
813
+ * sign-in has happened this session (s58.278).
814
+ *
815
+ * The one worth acting on is `"preserved"`: a guest account was presented,
816
+ * was NOT retired, and is therefore still alive server-side — so "recover
817
+ * your other account" is a real offer rather than a guess. `"retired"` means
818
+ * migrate from `onDeviceTakeover`'s id; `"none"` means there was nothing to
819
+ * reconcile. Cleared on signOut.
820
+ */
821
+ getLastAnonRetirement() {
822
+ return this.lastAnonRetirement;
823
+ }
810
824
  /** Internal — fan out deletion-cancelled to subscribers + cache the latest. */
811
825
  fireDeletionCancelled(userId) {
812
826
  const evt = { userId, at: /* @__PURE__ */ new Date() };
@@ -1889,6 +1903,7 @@ var Auth = class {
1889
1903
  retiredAnonUserId: data.retiredAnonUserId
1890
1904
  });
1891
1905
  }
1906
+ if (data.anonRetirement) this.lastAnonRetirement = data.anonRetirement;
1892
1907
  if (data.reactivatedFromDeletion) {
1893
1908
  this.fireDeletionCancelled(data.user.id);
1894
1909
  this.emitAuthState({ event: "deletion_cancelled", user: data.user });
@@ -1925,6 +1940,7 @@ var Auth = class {
1925
1940
  this.accessExpiresAt = 0;
1926
1941
  this.lastTakeover = null;
1927
1942
  this.lastDeletionCancelled = null;
1943
+ this.lastAnonRetirement = null;
1928
1944
  this.pendingAnonTakeover = null;
1929
1945
  this.hooks.storage.remove(USER_KEY);
1930
1946
  this.hooks.storage.remove(TOKEN_KEY);
package/dist/index.d.cts CHANGED
@@ -298,6 +298,8 @@ interface GameCenterPayload {
298
298
  teamPlayerId: string;
299
299
  bundleId: string;
300
300
  }
301
+ /** @see AuthApiResponse.anonRetirement */
302
+ type AnonRetirementOutcome = "retired" | "preserved" | "none";
301
303
  declare class EmailAlreadyTakenError extends Error {
302
304
  constructor(message?: string);
303
305
  }
@@ -348,20 +350,27 @@ declare class CredentialInUseError extends Error {
348
350
  }
349
351
  /**
350
352
  * What a sign-in should do when the credential you present already belongs to
351
- * an account (1.30.0).
353
+ * an account.
352
354
  *
353
- * - `"adopt"` (default — and what every earlier release did unconditionally):
354
- * sign in to that account. This is the reinstall-recovery path: a Game Center
355
- * / Play Games player identity survives a reinstall server-side, so the
356
- * "collision" is usually the SAME person's earlier account. If this device is
357
- * anonymous, that anonymous account is retired — **its row is deleted** — and
358
- * `onDeviceTakeover` fires with its id.
359
- * - `"reject"`: throw `CredentialInUseError` and change nothing at all. Use it
360
- * when the local anonymous session holds progress you are not willing to
361
- * trade. Mirrors Firebase `linkWithCredential`
362
- * (`auth/credential-already-in-use`) and Supabase `linkIdentity`.
355
+ * **You usually want the default — omit this.** Since 1.32.0 the default is
356
+ * safe by construction: adopt the other account silently when nothing would be
357
+ * destroyed, and refuse when something would be.
363
358
  *
364
- * `"reject"` blocks the switch; it does not merge the two accounts. To offer
359
+ * - **Fresh install / no guest session** → nothing to lose, so it adopts. This
360
+ * is the reinstall-recovery path: a Game Center / Play Games identity
361
+ * survives a reinstall server-side, so the "collision" is usually the SAME
362
+ * person's earlier account, and they get it back. Never refused.
363
+ * - **Live guest session** → adopting would retire it (**its row is deleted**
364
+ * and `onDeviceTakeover` fires). Refused with `CredentialInUseError` so you
365
+ * can ask the player instead of the SDK guessing on their behalf.
366
+ *
367
+ * Override in either direction:
368
+ *
369
+ * - `"adopt"` — always adopt, even when it deletes the guest account. This is
370
+ * what every release before 1.30.0 did unconditionally.
371
+ * - `"reject"` — always throw on a collision, even a harmless one.
372
+ *
373
+ * ⚠ A refusal blocks the switch; it does not merge the two accounts. To offer
365
374
  * "use my other account", catch the error and re-call with `"adopt"`, then
366
375
  * migrate your own data from `onDeviceTakeover`'s `retiredAnonUserId`.
367
376
  */
@@ -377,7 +386,8 @@ type GameSignInOptions = {
377
386
  link?: boolean;
378
387
  /**
379
388
  * What to do when the player identity already belongs to an account.
380
- * Default `"adopt"`. See {@link CredentialCollisionPolicy}.
389
+ * **Omit it** — the default refuses only when a live guest session would be
390
+ * deleted. See {@link CredentialCollisionPolicy}.
381
391
  */
382
392
  onCredentialInUse?: CredentialCollisionPolicy;
383
393
  };
@@ -526,6 +536,7 @@ declare class Auth {
526
536
  private deletionCancelledListeners;
527
537
  private authStateListeners;
528
538
  private lastDeletionCancelled;
539
+ private lastAnonRetirement;
529
540
  private lastTakeover;
530
541
  /**
531
542
  * Anon refresh token captured at `signIn()` time, stashed keyed to the
@@ -648,6 +659,17 @@ declare class Auth {
648
659
  onDeletionCancelled(listener: (evt: DeletionCancelledEvent) => void): () => void;
649
660
  /** The most recent deletion-cancelled event this session, or null. Cleared on signOut. */
650
661
  getLastDeletionCancelled(): DeletionCancelledEvent | null;
662
+ /**
663
+ * What the last sign-in did with this device's guest account, or null if no
664
+ * sign-in has happened this session (s58.278).
665
+ *
666
+ * The one worth acting on is `"preserved"`: a guest account was presented,
667
+ * was NOT retired, and is therefore still alive server-side — so "recover
668
+ * your other account" is a real offer rather than a guess. `"retired"` means
669
+ * migrate from `onDeviceTakeover`'s id; `"none"` means there was nothing to
670
+ * reconcile. Cleared on signOut.
671
+ */
672
+ getLastAnonRetirement(): AnonRetirementOutcome | null;
651
673
  /** Internal — fan out deletion-cancelled to subscribers + cache the latest. */
652
674
  private fireDeletionCancelled;
653
675
  /**
@@ -766,9 +788,9 @@ declare class Auth {
766
788
  link?: boolean;
767
789
  /**
768
790
  * What to do if this social identity (or its verified email) already
769
- * belongs to an account. Default `"adopt"` = sign in to it, retiring this
770
- * device's anonymous account. `"reject"` throws `CredentialInUseError` and
771
- * leaves everything untouched. See {@link CredentialCollisionPolicy}.
791
+ * belongs to an account. **Omit it** — the default adopts when nothing
792
+ * would be destroyed and refuses when a live guest session would be
793
+ * deleted. See {@link CredentialCollisionPolicy}.
772
794
  */
773
795
  onCredentialInUse?: CredentialCollisionPolicy;
774
796
  }): Promise<AuthUser>;
@@ -1896,4 +1918,4 @@ declare class SendoraSDK {
1896
1918
  }
1897
1919
  declare const SendoraCloud: SendoraSDK;
1898
1920
 
1899
- export { AlreadyIdentifiedError, type AttachLinkingApiOptions, Auth, AuthError, type AuthErrorKind, type AuthSignedOutReason, type AuthStateChange, type AuthTokens, type AuthUser, type CredentialCollisionPolicy, CredentialInUseError, type DeletionCancelledEvent, type DeviceTakeoverEvent, EmailAlreadyTakenError, type GameSignInOptions, type IdentifyTraits, type LinkCreateInput, type LinkCreateResult, type LinkData, LinkError, type LinkErrorCode, type LinkMatchInput, type LinkOpenedEvent, type LinkOpenedHandler, type LinkStats, type LinkedIdentitiesResponse, type LinkedIdentity, Links, type PushTokenReceipt, type PushTokenRegistration, SendoraCloud, type SendoraConfig, type TrackProperties, computeDeviceFingerprint, SendoraCloud as default, extractShortcodeFromUrl, getPlayInstallReferrer };
1921
+ export { AlreadyIdentifiedError, type AnonRetirementOutcome, type AttachLinkingApiOptions, Auth, AuthError, type AuthErrorKind, type AuthSignedOutReason, type AuthStateChange, type AuthTokens, type AuthUser, type CredentialCollisionPolicy, CredentialInUseError, type DeletionCancelledEvent, type DeviceTakeoverEvent, EmailAlreadyTakenError, type GameSignInOptions, type IdentifyTraits, type LinkCreateInput, type LinkCreateResult, type LinkData, LinkError, type LinkErrorCode, type LinkMatchInput, type LinkOpenedEvent, type LinkOpenedHandler, type LinkStats, type LinkedIdentitiesResponse, type LinkedIdentity, Links, type PushTokenReceipt, type PushTokenRegistration, SendoraCloud, type SendoraConfig, type TrackProperties, computeDeviceFingerprint, SendoraCloud as default, extractShortcodeFromUrl, getPlayInstallReferrer };
package/dist/index.d.ts CHANGED
@@ -298,6 +298,8 @@ interface GameCenterPayload {
298
298
  teamPlayerId: string;
299
299
  bundleId: string;
300
300
  }
301
+ /** @see AuthApiResponse.anonRetirement */
302
+ type AnonRetirementOutcome = "retired" | "preserved" | "none";
301
303
  declare class EmailAlreadyTakenError extends Error {
302
304
  constructor(message?: string);
303
305
  }
@@ -348,20 +350,27 @@ declare class CredentialInUseError extends Error {
348
350
  }
349
351
  /**
350
352
  * What a sign-in should do when the credential you present already belongs to
351
- * an account (1.30.0).
353
+ * an account.
352
354
  *
353
- * - `"adopt"` (default — and what every earlier release did unconditionally):
354
- * sign in to that account. This is the reinstall-recovery path: a Game Center
355
- * / Play Games player identity survives a reinstall server-side, so the
356
- * "collision" is usually the SAME person's earlier account. If this device is
357
- * anonymous, that anonymous account is retired — **its row is deleted** — and
358
- * `onDeviceTakeover` fires with its id.
359
- * - `"reject"`: throw `CredentialInUseError` and change nothing at all. Use it
360
- * when the local anonymous session holds progress you are not willing to
361
- * trade. Mirrors Firebase `linkWithCredential`
362
- * (`auth/credential-already-in-use`) and Supabase `linkIdentity`.
355
+ * **You usually want the default — omit this.** Since 1.32.0 the default is
356
+ * safe by construction: adopt the other account silently when nothing would be
357
+ * destroyed, and refuse when something would be.
363
358
  *
364
- * `"reject"` blocks the switch; it does not merge the two accounts. To offer
359
+ * - **Fresh install / no guest session** → nothing to lose, so it adopts. This
360
+ * is the reinstall-recovery path: a Game Center / Play Games identity
361
+ * survives a reinstall server-side, so the "collision" is usually the SAME
362
+ * person's earlier account, and they get it back. Never refused.
363
+ * - **Live guest session** → adopting would retire it (**its row is deleted**
364
+ * and `onDeviceTakeover` fires). Refused with `CredentialInUseError` so you
365
+ * can ask the player instead of the SDK guessing on their behalf.
366
+ *
367
+ * Override in either direction:
368
+ *
369
+ * - `"adopt"` — always adopt, even when it deletes the guest account. This is
370
+ * what every release before 1.30.0 did unconditionally.
371
+ * - `"reject"` — always throw on a collision, even a harmless one.
372
+ *
373
+ * ⚠ A refusal blocks the switch; it does not merge the two accounts. To offer
365
374
  * "use my other account", catch the error and re-call with `"adopt"`, then
366
375
  * migrate your own data from `onDeviceTakeover`'s `retiredAnonUserId`.
367
376
  */
@@ -377,7 +386,8 @@ type GameSignInOptions = {
377
386
  link?: boolean;
378
387
  /**
379
388
  * What to do when the player identity already belongs to an account.
380
- * Default `"adopt"`. See {@link CredentialCollisionPolicy}.
389
+ * **Omit it** — the default refuses only when a live guest session would be
390
+ * deleted. See {@link CredentialCollisionPolicy}.
381
391
  */
382
392
  onCredentialInUse?: CredentialCollisionPolicy;
383
393
  };
@@ -526,6 +536,7 @@ declare class Auth {
526
536
  private deletionCancelledListeners;
527
537
  private authStateListeners;
528
538
  private lastDeletionCancelled;
539
+ private lastAnonRetirement;
529
540
  private lastTakeover;
530
541
  /**
531
542
  * Anon refresh token captured at `signIn()` time, stashed keyed to the
@@ -648,6 +659,17 @@ declare class Auth {
648
659
  onDeletionCancelled(listener: (evt: DeletionCancelledEvent) => void): () => void;
649
660
  /** The most recent deletion-cancelled event this session, or null. Cleared on signOut. */
650
661
  getLastDeletionCancelled(): DeletionCancelledEvent | null;
662
+ /**
663
+ * What the last sign-in did with this device's guest account, or null if no
664
+ * sign-in has happened this session (s58.278).
665
+ *
666
+ * The one worth acting on is `"preserved"`: a guest account was presented,
667
+ * was NOT retired, and is therefore still alive server-side — so "recover
668
+ * your other account" is a real offer rather than a guess. `"retired"` means
669
+ * migrate from `onDeviceTakeover`'s id; `"none"` means there was nothing to
670
+ * reconcile. Cleared on signOut.
671
+ */
672
+ getLastAnonRetirement(): AnonRetirementOutcome | null;
651
673
  /** Internal — fan out deletion-cancelled to subscribers + cache the latest. */
652
674
  private fireDeletionCancelled;
653
675
  /**
@@ -766,9 +788,9 @@ declare class Auth {
766
788
  link?: boolean;
767
789
  /**
768
790
  * What to do if this social identity (or its verified email) already
769
- * belongs to an account. Default `"adopt"` = sign in to it, retiring this
770
- * device's anonymous account. `"reject"` throws `CredentialInUseError` and
771
- * leaves everything untouched. See {@link CredentialCollisionPolicy}.
791
+ * belongs to an account. **Omit it** — the default adopts when nothing
792
+ * would be destroyed and refuses when a live guest session would be
793
+ * deleted. See {@link CredentialCollisionPolicy}.
772
794
  */
773
795
  onCredentialInUse?: CredentialCollisionPolicy;
774
796
  }): Promise<AuthUser>;
@@ -1896,4 +1918,4 @@ declare class SendoraSDK {
1896
1918
  }
1897
1919
  declare const SendoraCloud: SendoraSDK;
1898
1920
 
1899
- export { AlreadyIdentifiedError, type AttachLinkingApiOptions, Auth, AuthError, type AuthErrorKind, type AuthSignedOutReason, type AuthStateChange, type AuthTokens, type AuthUser, type CredentialCollisionPolicy, CredentialInUseError, type DeletionCancelledEvent, type DeviceTakeoverEvent, EmailAlreadyTakenError, type GameSignInOptions, type IdentifyTraits, type LinkCreateInput, type LinkCreateResult, type LinkData, LinkError, type LinkErrorCode, type LinkMatchInput, type LinkOpenedEvent, type LinkOpenedHandler, type LinkStats, type LinkedIdentitiesResponse, type LinkedIdentity, Links, type PushTokenReceipt, type PushTokenRegistration, SendoraCloud, type SendoraConfig, type TrackProperties, computeDeviceFingerprint, SendoraCloud as default, extractShortcodeFromUrl, getPlayInstallReferrer };
1921
+ export { AlreadyIdentifiedError, type AnonRetirementOutcome, type AttachLinkingApiOptions, Auth, AuthError, type AuthErrorKind, type AuthSignedOutReason, type AuthStateChange, type AuthTokens, type AuthUser, type CredentialCollisionPolicy, CredentialInUseError, type DeletionCancelledEvent, type DeviceTakeoverEvent, EmailAlreadyTakenError, type GameSignInOptions, type IdentifyTraits, type LinkCreateInput, type LinkCreateResult, type LinkData, LinkError, type LinkErrorCode, type LinkMatchInput, type LinkOpenedEvent, type LinkOpenedHandler, type LinkStats, type LinkedIdentitiesResponse, type LinkedIdentity, Links, type PushTokenReceipt, type PushTokenRegistration, SendoraCloud, type SendoraConfig, type TrackProperties, computeDeviceFingerprint, SendoraCloud as default, extractShortcodeFromUrl, getPlayInstallReferrer };
package/dist/index.js CHANGED
@@ -157,7 +157,7 @@ var Storage = class {
157
157
  // package.json
158
158
  var package_default = {
159
159
  name: "@sendoracloud/sdk-react-native",
160
- version: "1.31.0",
160
+ version: "1.33.0",
161
161
  description: "Sendora Cloud React Native + Expo SDK \u2014 analytics, identity, push-token registration, auth (incl. Game Center / Play Games), deep links (Branch / Firebase Dynamic Links parity). Auth + analytics + deep links work in Expo Go; push-token registration and the no-arg Game Center / Play Games sign-in require a Dev Client (EAS Build or `npx expo prebuild`).",
162
162
  type: "module",
163
163
  main: "./dist/index.cjs",
@@ -569,6 +569,7 @@ var Auth = class {
569
569
  this.deletionCancelledListeners = /* @__PURE__ */ new Set();
570
570
  this.authStateListeners = /* @__PURE__ */ new Set();
571
571
  this.lastDeletionCancelled = null;
572
+ this.lastAnonRetirement = null;
572
573
  this.lastTakeover = null;
573
574
  /**
574
575
  * Anon refresh token captured at `signIn()` time, stashed keyed to the
@@ -762,6 +763,19 @@ var Auth = class {
762
763
  getLastDeletionCancelled() {
763
764
  return this.lastDeletionCancelled;
764
765
  }
766
+ /**
767
+ * What the last sign-in did with this device's guest account, or null if no
768
+ * sign-in has happened this session (s58.278).
769
+ *
770
+ * The one worth acting on is `"preserved"`: a guest account was presented,
771
+ * was NOT retired, and is therefore still alive server-side — so "recover
772
+ * your other account" is a real offer rather than a guess. `"retired"` means
773
+ * migrate from `onDeviceTakeover`'s id; `"none"` means there was nothing to
774
+ * reconcile. Cleared on signOut.
775
+ */
776
+ getLastAnonRetirement() {
777
+ return this.lastAnonRetirement;
778
+ }
765
779
  /** Internal — fan out deletion-cancelled to subscribers + cache the latest. */
766
780
  fireDeletionCancelled(userId) {
767
781
  const evt = { userId, at: /* @__PURE__ */ new Date() };
@@ -1844,6 +1858,7 @@ var Auth = class {
1844
1858
  retiredAnonUserId: data.retiredAnonUserId
1845
1859
  });
1846
1860
  }
1861
+ if (data.anonRetirement) this.lastAnonRetirement = data.anonRetirement;
1847
1862
  if (data.reactivatedFromDeletion) {
1848
1863
  this.fireDeletionCancelled(data.user.id);
1849
1864
  this.emitAuthState({ event: "deletion_cancelled", user: data.user });
@@ -1880,6 +1895,7 @@ var Auth = class {
1880
1895
  this.accessExpiresAt = 0;
1881
1896
  this.lastTakeover = null;
1882
1897
  this.lastDeletionCancelled = null;
1898
+ this.lastAnonRetirement = null;
1883
1899
  this.pendingAnonTakeover = null;
1884
1900
  this.hooks.storage.remove(USER_KEY);
1885
1901
  this.hooks.storage.remove(TOKEN_KEY);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendoracloud/sdk-react-native",
3
- "version": "1.31.0",
3
+ "version": "1.33.0",
4
4
  "description": "Sendora Cloud React Native + Expo SDK — analytics, identity, push-token registration, auth (incl. Game Center / Play Games), deep links (Branch / Firebase Dynamic Links parity). Auth + analytics + deep links work in Expo Go; push-token registration and the no-arg Game Center / Play Games sign-in require a Dev Client (EAS Build or `npx expo prebuild`).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",