@anuma/sdk 1.3.0 → 1.3.1

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.
@@ -16768,8 +16768,18 @@ function getMigrationReloadKey(prefix, walletAddress) {
16768
16768
  }
16769
16769
  var DatabaseManager = class {
16770
16770
  constructor(options) {
16771
- this.database = null;
16772
- this.currentWalletAddress = void 0;
16771
+ /**
16772
+ * WatermelonDB instances cached by their derived `dbName` (not by raw wallet
16773
+ * address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
16774
+ * that is requested again — including after a transient `undefined`/guest
16775
+ * excursion or an address that briefly arrives in a different form during
16776
+ * sign-up — reuses the SAME instance instead of being torn down and rebuilt.
16777
+ * The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
16778
+ * (client#4821). Instances are kept for the lifetime of the manager (typically
16779
+ * guest + one wallet); switching wallets keeps prior ones cached rather than
16780
+ * disposing an instance the app may still hold a reference to.
16781
+ */
16782
+ this.databases = /* @__PURE__ */ new Map();
16773
16783
  this.migrationInProgress = false;
16774
16784
  this.dbNamePrefix = options.dbNamePrefix;
16775
16785
  this.createAdapter = options.createAdapter;
@@ -16786,8 +16796,9 @@ var DatabaseManager = class {
16786
16796
  /**
16787
16797
  * Get or create a WatermelonDB Database instance for the given wallet.
16788
16798
  *
16789
- * If the wallet address has changed since the last call, the previous
16790
- * database instance is discarded and a new one is created.
16799
+ * Instances are cached per derived dbName and reused across calls (including
16800
+ * repeat/guest-interleaved requests for the same wallet); a new one is built
16801
+ * only for a dbName not yet seen. See the `databases` field for why.
16791
16802
  *
16792
16803
  * @param walletAddress - The wallet address to scope the database to.
16793
16804
  * If undefined, uses a "guest" database.
@@ -16795,46 +16806,47 @@ var DatabaseManager = class {
16795
16806
  * @throws If a destructive migration is in progress
16796
16807
  */
16797
16808
  getDatabase(walletAddress) {
16798
- if (this.database && this.currentWalletAddress !== walletAddress) {
16799
- this.logger.debug?.("Wallet changed, switching database", {
16800
- component: "DatabaseManager",
16801
- from: this.currentWalletAddress,
16802
- to: walletAddress
16803
- });
16804
- this.database = null;
16805
- }
16806
- if (this.database) {
16807
- return this.database;
16809
+ const dbName = this.getDbName(walletAddress);
16810
+ const cached = this.databases.get(dbName);
16811
+ if (cached) {
16812
+ return cached;
16808
16813
  }
16809
16814
  const needsMigration = this.handleSchemaMigration(walletAddress);
16810
16815
  if (needsMigration) {
16811
16816
  throw new Error("Database migration in progress - app will restart");
16812
16817
  }
16813
- this.currentWalletAddress = walletAddress;
16814
- const dbName = this.getDbName(walletAddress);
16815
16818
  this.logger.debug?.("Initializing database", {
16816
16819
  component: "DatabaseManager",
16817
16820
  dbName,
16818
16821
  walletAddress
16819
16822
  });
16820
16823
  const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
16821
- this.database = new import_watermelondb20.Database({
16824
+ const database = new import_watermelondb20.Database({
16822
16825
  adapter,
16823
16826
  modelClasses: sdkModelClasses
16824
16827
  });
16825
- return this.database;
16828
+ this.databases.set(dbName, database);
16829
+ return database;
16826
16830
  }
16827
16831
  /**
16828
- * Reset the current database (useful for logout or testing).
16832
+ * Reset ALL cached databases (useful for logout or testing).
16829
16833
  */
16830
16834
  async resetDatabase() {
16831
- const db = this.database;
16832
- if (db) {
16833
- await db.write(async () => {
16834
- await db.unsafeResetDatabase();
16835
- });
16836
- this.database = null;
16837
- this.currentWalletAddress = void 0;
16835
+ const errors = [];
16836
+ for (const [dbName, db] of [...this.databases.entries()]) {
16837
+ try {
16838
+ await db.write(async () => {
16839
+ await db.unsafeResetDatabase();
16840
+ });
16841
+ this.databases.delete(dbName);
16842
+ } catch (error) {
16843
+ errors.push({ dbName, error });
16844
+ }
16845
+ }
16846
+ if (errors.length > 0) {
16847
+ throw new Error(
16848
+ `Failed to reset ${errors.length} database(s): ${errors.map((e) => e.dbName).join(", ")}`
16849
+ );
16838
16850
  }
16839
16851
  }
16840
16852
  /**
@@ -6542,8 +6542,18 @@ interface DatabaseManagerOptions {
6542
6542
  * ```
6543
6543
  */
6544
6544
  declare class DatabaseManager {
6545
- private database;
6546
- private currentWalletAddress;
6545
+ /**
6546
+ * WatermelonDB instances cached by their derived `dbName` (not by raw wallet
6547
+ * address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
6548
+ * that is requested again — including after a transient `undefined`/guest
6549
+ * excursion or an address that briefly arrives in a different form during
6550
+ * sign-up — reuses the SAME instance instead of being torn down and rebuilt.
6551
+ * The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
6552
+ * (client#4821). Instances are kept for the lifetime of the manager (typically
6553
+ * guest + one wallet); switching wallets keeps prior ones cached rather than
6554
+ * disposing an instance the app may still hold a reference to.
6555
+ */
6556
+ private readonly databases;
6547
6557
  private migrationInProgress;
6548
6558
  private readonly dbNamePrefix;
6549
6559
  private readonly createAdapter;
@@ -6558,8 +6568,9 @@ declare class DatabaseManager {
6558
6568
  /**
6559
6569
  * Get or create a WatermelonDB Database instance for the given wallet.
6560
6570
  *
6561
- * If the wallet address has changed since the last call, the previous
6562
- * database instance is discarded and a new one is created.
6571
+ * Instances are cached per derived dbName and reused across calls (including
6572
+ * repeat/guest-interleaved requests for the same wallet); a new one is built
6573
+ * only for a dbName not yet seen. See the `databases` field for why.
6563
6574
  *
6564
6575
  * @param walletAddress - The wallet address to scope the database to.
6565
6576
  * If undefined, uses a "guest" database.
@@ -6568,7 +6579,7 @@ declare class DatabaseManager {
6568
6579
  */
6569
6580
  getDatabase(walletAddress?: string): Database;
6570
6581
  /**
6571
- * Reset the current database (useful for logout or testing).
6582
+ * Reset ALL cached databases (useful for logout or testing).
6572
6583
  */
6573
6584
  resetDatabase(): Promise<void>;
6574
6585
  /**
@@ -6542,8 +6542,18 @@ interface DatabaseManagerOptions {
6542
6542
  * ```
6543
6543
  */
6544
6544
  declare class DatabaseManager {
6545
- private database;
6546
- private currentWalletAddress;
6545
+ /**
6546
+ * WatermelonDB instances cached by their derived `dbName` (not by raw wallet
6547
+ * address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
6548
+ * that is requested again — including after a transient `undefined`/guest
6549
+ * excursion or an address that briefly arrives in a different form during
6550
+ * sign-up — reuses the SAME instance instead of being torn down and rebuilt.
6551
+ * The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
6552
+ * (client#4821). Instances are kept for the lifetime of the manager (typically
6553
+ * guest + one wallet); switching wallets keeps prior ones cached rather than
6554
+ * disposing an instance the app may still hold a reference to.
6555
+ */
6556
+ private readonly databases;
6547
6557
  private migrationInProgress;
6548
6558
  private readonly dbNamePrefix;
6549
6559
  private readonly createAdapter;
@@ -6558,8 +6568,9 @@ declare class DatabaseManager {
6558
6568
  /**
6559
6569
  * Get or create a WatermelonDB Database instance for the given wallet.
6560
6570
  *
6561
- * If the wallet address has changed since the last call, the previous
6562
- * database instance is discarded and a new one is created.
6571
+ * Instances are cached per derived dbName and reused across calls (including
6572
+ * repeat/guest-interleaved requests for the same wallet); a new one is built
6573
+ * only for a dbName not yet seen. See the `databases` field for why.
6563
6574
  *
6564
6575
  * @param walletAddress - The wallet address to scope the database to.
6565
6576
  * If undefined, uses a "guest" database.
@@ -6568,7 +6579,7 @@ declare class DatabaseManager {
6568
6579
  */
6569
6580
  getDatabase(walletAddress?: string): Database;
6570
6581
  /**
6571
- * Reset the current database (useful for logout or testing).
6582
+ * Reset ALL cached databases (useful for logout or testing).
6572
6583
  */
6573
6584
  resetDatabase(): Promise<void>;
6574
6585
  /**
@@ -10020,8 +10020,18 @@ function getMigrationReloadKey(prefix, walletAddress) {
10020
10020
  }
10021
10021
  var DatabaseManager = class {
10022
10022
  constructor(options) {
10023
- this.database = null;
10024
- this.currentWalletAddress = void 0;
10023
+ /**
10024
+ * WatermelonDB instances cached by their derived `dbName` (not by raw wallet
10025
+ * address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
10026
+ * that is requested again — including after a transient `undefined`/guest
10027
+ * excursion or an address that briefly arrives in a different form during
10028
+ * sign-up — reuses the SAME instance instead of being torn down and rebuilt.
10029
+ * The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
10030
+ * (client#4821). Instances are kept for the lifetime of the manager (typically
10031
+ * guest + one wallet); switching wallets keeps prior ones cached rather than
10032
+ * disposing an instance the app may still hold a reference to.
10033
+ */
10034
+ this.databases = /* @__PURE__ */ new Map();
10025
10035
  this.migrationInProgress = false;
10026
10036
  this.dbNamePrefix = options.dbNamePrefix;
10027
10037
  this.createAdapter = options.createAdapter;
@@ -10038,8 +10048,9 @@ var DatabaseManager = class {
10038
10048
  /**
10039
10049
  * Get or create a WatermelonDB Database instance for the given wallet.
10040
10050
  *
10041
- * If the wallet address has changed since the last call, the previous
10042
- * database instance is discarded and a new one is created.
10051
+ * Instances are cached per derived dbName and reused across calls (including
10052
+ * repeat/guest-interleaved requests for the same wallet); a new one is built
10053
+ * only for a dbName not yet seen. See the `databases` field for why.
10043
10054
  *
10044
10055
  * @param walletAddress - The wallet address to scope the database to.
10045
10056
  * If undefined, uses a "guest" database.
@@ -10047,46 +10058,47 @@ var DatabaseManager = class {
10047
10058
  * @throws If a destructive migration is in progress
10048
10059
  */
10049
10060
  getDatabase(walletAddress) {
10050
- if (this.database && this.currentWalletAddress !== walletAddress) {
10051
- this.logger.debug?.("Wallet changed, switching database", {
10052
- component: "DatabaseManager",
10053
- from: this.currentWalletAddress,
10054
- to: walletAddress
10055
- });
10056
- this.database = null;
10057
- }
10058
- if (this.database) {
10059
- return this.database;
10061
+ const dbName = this.getDbName(walletAddress);
10062
+ const cached = this.databases.get(dbName);
10063
+ if (cached) {
10064
+ return cached;
10060
10065
  }
10061
10066
  const needsMigration = this.handleSchemaMigration(walletAddress);
10062
10067
  if (needsMigration) {
10063
10068
  throw new Error("Database migration in progress - app will restart");
10064
10069
  }
10065
- this.currentWalletAddress = walletAddress;
10066
- const dbName = this.getDbName(walletAddress);
10067
10070
  this.logger.debug?.("Initializing database", {
10068
10071
  component: "DatabaseManager",
10069
10072
  dbName,
10070
10073
  walletAddress
10071
10074
  });
10072
10075
  const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
10073
- this.database = new Database({
10076
+ const database = new Database({
10074
10077
  adapter,
10075
10078
  modelClasses: sdkModelClasses
10076
10079
  });
10077
- return this.database;
10080
+ this.databases.set(dbName, database);
10081
+ return database;
10078
10082
  }
10079
10083
  /**
10080
- * Reset the current database (useful for logout or testing).
10084
+ * Reset ALL cached databases (useful for logout or testing).
10081
10085
  */
10082
10086
  async resetDatabase() {
10083
- const db = this.database;
10084
- if (db) {
10085
- await db.write(async () => {
10086
- await db.unsafeResetDatabase();
10087
- });
10088
- this.database = null;
10089
- this.currentWalletAddress = void 0;
10087
+ const errors = [];
10088
+ for (const [dbName, db] of [...this.databases.entries()]) {
10089
+ try {
10090
+ await db.write(async () => {
10091
+ await db.unsafeResetDatabase();
10092
+ });
10093
+ this.databases.delete(dbName);
10094
+ } catch (error) {
10095
+ errors.push({ dbName, error });
10096
+ }
10097
+ }
10098
+ if (errors.length > 0) {
10099
+ throw new Error(
10100
+ `Failed to reset ${errors.length} database(s): ${errors.map((e) => e.dbName).join(", ")}`
10101
+ );
10090
10102
  }
10091
10103
  }
10092
10104
  /**
@@ -19962,8 +19962,18 @@ function getMigrationReloadKey(prefix, walletAddress) {
19962
19962
  }
19963
19963
  var DatabaseManager = class {
19964
19964
  constructor(options) {
19965
- this.database = null;
19966
- this.currentWalletAddress = void 0;
19965
+ /**
19966
+ * WatermelonDB instances cached by their derived `dbName` (not by raw wallet
19967
+ * address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
19968
+ * that is requested again — including after a transient `undefined`/guest
19969
+ * excursion or an address that briefly arrives in a different form during
19970
+ * sign-up — reuses the SAME instance instead of being torn down and rebuilt.
19971
+ * The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
19972
+ * (client#4821). Instances are kept for the lifetime of the manager (typically
19973
+ * guest + one wallet); switching wallets keeps prior ones cached rather than
19974
+ * disposing an instance the app may still hold a reference to.
19975
+ */
19976
+ this.databases = /* @__PURE__ */ new Map();
19967
19977
  this.migrationInProgress = false;
19968
19978
  this.dbNamePrefix = options.dbNamePrefix;
19969
19979
  this.createAdapter = options.createAdapter;
@@ -19980,8 +19990,9 @@ var DatabaseManager = class {
19980
19990
  /**
19981
19991
  * Get or create a WatermelonDB Database instance for the given wallet.
19982
19992
  *
19983
- * If the wallet address has changed since the last call, the previous
19984
- * database instance is discarded and a new one is created.
19993
+ * Instances are cached per derived dbName and reused across calls (including
19994
+ * repeat/guest-interleaved requests for the same wallet); a new one is built
19995
+ * only for a dbName not yet seen. See the `databases` field for why.
19985
19996
  *
19986
19997
  * @param walletAddress - The wallet address to scope the database to.
19987
19998
  * If undefined, uses a "guest" database.
@@ -19989,46 +20000,47 @@ var DatabaseManager = class {
19989
20000
  * @throws If a destructive migration is in progress
19990
20001
  */
19991
20002
  getDatabase(walletAddress) {
19992
- if (this.database && this.currentWalletAddress !== walletAddress) {
19993
- this.logger.debug?.("Wallet changed, switching database", {
19994
- component: "DatabaseManager",
19995
- from: this.currentWalletAddress,
19996
- to: walletAddress
19997
- });
19998
- this.database = null;
19999
- }
20000
- if (this.database) {
20001
- return this.database;
20003
+ const dbName = this.getDbName(walletAddress);
20004
+ const cached = this.databases.get(dbName);
20005
+ if (cached) {
20006
+ return cached;
20002
20007
  }
20003
20008
  const needsMigration = this.handleSchemaMigration(walletAddress);
20004
20009
  if (needsMigration) {
20005
20010
  throw new Error("Database migration in progress - app will restart");
20006
20011
  }
20007
- this.currentWalletAddress = walletAddress;
20008
- const dbName = this.getDbName(walletAddress);
20009
20012
  this.logger.debug?.("Initializing database", {
20010
20013
  component: "DatabaseManager",
20011
20014
  dbName,
20012
20015
  walletAddress
20013
20016
  });
20014
20017
  const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
20015
- this.database = new import_watermelondb21.Database({
20018
+ const database = new import_watermelondb21.Database({
20016
20019
  adapter,
20017
20020
  modelClasses: sdkModelClasses
20018
20021
  });
20019
- return this.database;
20022
+ this.databases.set(dbName, database);
20023
+ return database;
20020
20024
  }
20021
20025
  /**
20022
- * Reset the current database (useful for logout or testing).
20026
+ * Reset ALL cached databases (useful for logout or testing).
20023
20027
  */
20024
20028
  async resetDatabase() {
20025
- const db = this.database;
20026
- if (db) {
20027
- await db.write(async () => {
20028
- await db.unsafeResetDatabase();
20029
- });
20030
- this.database = null;
20031
- this.currentWalletAddress = void 0;
20029
+ const errors = [];
20030
+ for (const [dbName, db] of [...this.databases.entries()]) {
20031
+ try {
20032
+ await db.write(async () => {
20033
+ await db.unsafeResetDatabase();
20034
+ });
20035
+ this.databases.delete(dbName);
20036
+ } catch (error) {
20037
+ errors.push({ dbName, error });
20038
+ }
20039
+ }
20040
+ if (errors.length > 0) {
20041
+ throw new Error(
20042
+ `Failed to reset ${errors.length} database(s): ${errors.map((e) => e.dbName).join(", ")}`
20043
+ );
20032
20044
  }
20033
20045
  }
20034
20046
  /**
@@ -8077,8 +8077,18 @@ declare const webPlatformStorage: PlatformStorage;
8077
8077
  * ```
8078
8078
  */
8079
8079
  declare class DatabaseManager {
8080
- private database;
8081
- private currentWalletAddress;
8080
+ /**
8081
+ * WatermelonDB instances cached by their derived `dbName` (not by raw wallet
8082
+ * address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
8083
+ * that is requested again — including after a transient `undefined`/guest
8084
+ * excursion or an address that briefly arrives in a different form during
8085
+ * sign-up — reuses the SAME instance instead of being torn down and rebuilt.
8086
+ * The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
8087
+ * (client#4821). Instances are kept for the lifetime of the manager (typically
8088
+ * guest + one wallet); switching wallets keeps prior ones cached rather than
8089
+ * disposing an instance the app may still hold a reference to.
8090
+ */
8091
+ private readonly databases;
8082
8092
  private migrationInProgress;
8083
8093
  private readonly dbNamePrefix;
8084
8094
  private readonly createAdapter;
@@ -8093,8 +8103,9 @@ declare class DatabaseManager {
8093
8103
  /**
8094
8104
  * Get or create a WatermelonDB Database instance for the given wallet.
8095
8105
  *
8096
- * If the wallet address has changed since the last call, the previous
8097
- * database instance is discarded and a new one is created.
8106
+ * Instances are cached per derived dbName and reused across calls (including
8107
+ * repeat/guest-interleaved requests for the same wallet); a new one is built
8108
+ * only for a dbName not yet seen. See the `databases` field for why.
8098
8109
  *
8099
8110
  * @param walletAddress - The wallet address to scope the database to.
8100
8111
  * If undefined, uses a "guest" database.
@@ -8103,7 +8114,7 @@ declare class DatabaseManager {
8103
8114
  */
8104
8115
  getDatabase(walletAddress?: string): Database;
8105
8116
  /**
8106
- * Reset the current database (useful for logout or testing).
8117
+ * Reset ALL cached databases (useful for logout or testing).
8107
8118
  */
8108
8119
  resetDatabase(): Promise<void>;
8109
8120
  /**
@@ -8077,8 +8077,18 @@ declare const webPlatformStorage: PlatformStorage;
8077
8077
  * ```
8078
8078
  */
8079
8079
  declare class DatabaseManager {
8080
- private database;
8081
- private currentWalletAddress;
8080
+ /**
8081
+ * WatermelonDB instances cached by their derived `dbName` (not by raw wallet
8082
+ * address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
8083
+ * that is requested again — including after a transient `undefined`/guest
8084
+ * excursion or an address that briefly arrives in a different form during
8085
+ * sign-up — reuses the SAME instance instead of being torn down and rebuilt.
8086
+ * The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
8087
+ * (client#4821). Instances are kept for the lifetime of the manager (typically
8088
+ * guest + one wallet); switching wallets keeps prior ones cached rather than
8089
+ * disposing an instance the app may still hold a reference to.
8090
+ */
8091
+ private readonly databases;
8082
8092
  private migrationInProgress;
8083
8093
  private readonly dbNamePrefix;
8084
8094
  private readonly createAdapter;
@@ -8093,8 +8103,9 @@ declare class DatabaseManager {
8093
8103
  /**
8094
8104
  * Get or create a WatermelonDB Database instance for the given wallet.
8095
8105
  *
8096
- * If the wallet address has changed since the last call, the previous
8097
- * database instance is discarded and a new one is created.
8106
+ * Instances are cached per derived dbName and reused across calls (including
8107
+ * repeat/guest-interleaved requests for the same wallet); a new one is built
8108
+ * only for a dbName not yet seen. See the `databases` field for why.
8098
8109
  *
8099
8110
  * @param walletAddress - The wallet address to scope the database to.
8100
8111
  * If undefined, uses a "guest" database.
@@ -8103,7 +8114,7 @@ declare class DatabaseManager {
8103
8114
  */
8104
8115
  getDatabase(walletAddress?: string): Database;
8105
8116
  /**
8106
- * Reset the current database (useful for logout or testing).
8117
+ * Reset ALL cached databases (useful for logout or testing).
8107
8118
  */
8108
8119
  resetDatabase(): Promise<void>;
8109
8120
  /**
@@ -12680,8 +12680,18 @@ function getMigrationReloadKey(prefix, walletAddress) {
12680
12680
  }
12681
12681
  var DatabaseManager = class {
12682
12682
  constructor(options) {
12683
- this.database = null;
12684
- this.currentWalletAddress = void 0;
12683
+ /**
12684
+ * WatermelonDB instances cached by their derived `dbName` (not by raw wallet
12685
+ * address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
12686
+ * that is requested again — including after a transient `undefined`/guest
12687
+ * excursion or an address that briefly arrives in a different form during
12688
+ * sign-up — reuses the SAME instance instead of being torn down and rebuilt.
12689
+ * The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
12690
+ * (client#4821). Instances are kept for the lifetime of the manager (typically
12691
+ * guest + one wallet); switching wallets keeps prior ones cached rather than
12692
+ * disposing an instance the app may still hold a reference to.
12693
+ */
12694
+ this.databases = /* @__PURE__ */ new Map();
12685
12695
  this.migrationInProgress = false;
12686
12696
  this.dbNamePrefix = options.dbNamePrefix;
12687
12697
  this.createAdapter = options.createAdapter;
@@ -12698,8 +12708,9 @@ var DatabaseManager = class {
12698
12708
  /**
12699
12709
  * Get or create a WatermelonDB Database instance for the given wallet.
12700
12710
  *
12701
- * If the wallet address has changed since the last call, the previous
12702
- * database instance is discarded and a new one is created.
12711
+ * Instances are cached per derived dbName and reused across calls (including
12712
+ * repeat/guest-interleaved requests for the same wallet); a new one is built
12713
+ * only for a dbName not yet seen. See the `databases` field for why.
12703
12714
  *
12704
12715
  * @param walletAddress - The wallet address to scope the database to.
12705
12716
  * If undefined, uses a "guest" database.
@@ -12707,46 +12718,47 @@ var DatabaseManager = class {
12707
12718
  * @throws If a destructive migration is in progress
12708
12719
  */
12709
12720
  getDatabase(walletAddress) {
12710
- if (this.database && this.currentWalletAddress !== walletAddress) {
12711
- this.logger.debug?.("Wallet changed, switching database", {
12712
- component: "DatabaseManager",
12713
- from: this.currentWalletAddress,
12714
- to: walletAddress
12715
- });
12716
- this.database = null;
12717
- }
12718
- if (this.database) {
12719
- return this.database;
12721
+ const dbName = this.getDbName(walletAddress);
12722
+ const cached = this.databases.get(dbName);
12723
+ if (cached) {
12724
+ return cached;
12720
12725
  }
12721
12726
  const needsMigration = this.handleSchemaMigration(walletAddress);
12722
12727
  if (needsMigration) {
12723
12728
  throw new Error("Database migration in progress - app will restart");
12724
12729
  }
12725
- this.currentWalletAddress = walletAddress;
12726
- const dbName = this.getDbName(walletAddress);
12727
12730
  this.logger.debug?.("Initializing database", {
12728
12731
  component: "DatabaseManager",
12729
12732
  dbName,
12730
12733
  walletAddress
12731
12734
  });
12732
12735
  const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
12733
- this.database = new Database({
12736
+ const database = new Database({
12734
12737
  adapter,
12735
12738
  modelClasses: sdkModelClasses
12736
12739
  });
12737
- return this.database;
12740
+ this.databases.set(dbName, database);
12741
+ return database;
12738
12742
  }
12739
12743
  /**
12740
- * Reset the current database (useful for logout or testing).
12744
+ * Reset ALL cached databases (useful for logout or testing).
12741
12745
  */
12742
12746
  async resetDatabase() {
12743
- const db = this.database;
12744
- if (db) {
12745
- await db.write(async () => {
12746
- await db.unsafeResetDatabase();
12747
- });
12748
- this.database = null;
12749
- this.currentWalletAddress = void 0;
12747
+ const errors = [];
12748
+ for (const [dbName, db] of [...this.databases.entries()]) {
12749
+ try {
12750
+ await db.write(async () => {
12751
+ await db.unsafeResetDatabase();
12752
+ });
12753
+ this.databases.delete(dbName);
12754
+ } catch (error) {
12755
+ errors.push({ dbName, error });
12756
+ }
12757
+ }
12758
+ if (errors.length > 0) {
12759
+ throw new Error(
12760
+ `Failed to reset ${errors.length} database(s): ${errors.map((e) => e.dbName).join(", ")}`
12761
+ );
12750
12762
  }
12751
12763
  }
12752
12764
  /**
@@ -22893,8 +22893,18 @@ function getMigrationReloadKey(prefix, walletAddress) {
22893
22893
  }
22894
22894
  var DatabaseManager = class {
22895
22895
  constructor(options) {
22896
- this.database = null;
22897
- this.currentWalletAddress = void 0;
22896
+ /**
22897
+ * WatermelonDB instances cached by their derived `dbName` (not by raw wallet
22898
+ * address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
22899
+ * that is requested again — including after a transient `undefined`/guest
22900
+ * excursion or an address that briefly arrives in a different form during
22901
+ * sign-up — reuses the SAME instance instead of being torn down and rebuilt.
22902
+ * The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
22903
+ * (client#4821). Instances are kept for the lifetime of the manager (typically
22904
+ * guest + one wallet); switching wallets keeps prior ones cached rather than
22905
+ * disposing an instance the app may still hold a reference to.
22906
+ */
22907
+ this.databases = /* @__PURE__ */ new Map();
22898
22908
  this.migrationInProgress = false;
22899
22909
  this.dbNamePrefix = options.dbNamePrefix;
22900
22910
  this.createAdapter = options.createAdapter;
@@ -22911,8 +22921,9 @@ var DatabaseManager = class {
22911
22921
  /**
22912
22922
  * Get or create a WatermelonDB Database instance for the given wallet.
22913
22923
  *
22914
- * If the wallet address has changed since the last call, the previous
22915
- * database instance is discarded and a new one is created.
22924
+ * Instances are cached per derived dbName and reused across calls (including
22925
+ * repeat/guest-interleaved requests for the same wallet); a new one is built
22926
+ * only for a dbName not yet seen. See the `databases` field for why.
22916
22927
  *
22917
22928
  * @param walletAddress - The wallet address to scope the database to.
22918
22929
  * If undefined, uses a "guest" database.
@@ -22920,46 +22931,47 @@ var DatabaseManager = class {
22920
22931
  * @throws If a destructive migration is in progress
22921
22932
  */
22922
22933
  getDatabase(walletAddress) {
22923
- if (this.database && this.currentWalletAddress !== walletAddress) {
22924
- this.logger.debug?.("Wallet changed, switching database", {
22925
- component: "DatabaseManager",
22926
- from: this.currentWalletAddress,
22927
- to: walletAddress
22928
- });
22929
- this.database = null;
22930
- }
22931
- if (this.database) {
22932
- return this.database;
22934
+ const dbName = this.getDbName(walletAddress);
22935
+ const cached = this.databases.get(dbName);
22936
+ if (cached) {
22937
+ return cached;
22933
22938
  }
22934
22939
  const needsMigration = this.handleSchemaMigration(walletAddress);
22935
22940
  if (needsMigration) {
22936
22941
  throw new Error("Database migration in progress - app will restart");
22937
22942
  }
22938
- this.currentWalletAddress = walletAddress;
22939
- const dbName = this.getDbName(walletAddress);
22940
22943
  this.logger.debug?.("Initializing database", {
22941
22944
  component: "DatabaseManager",
22942
22945
  dbName,
22943
22946
  walletAddress
22944
22947
  });
22945
22948
  const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
22946
- this.database = new import_watermelondb13.Database({
22949
+ const database = new import_watermelondb13.Database({
22947
22950
  adapter,
22948
22951
  modelClasses: sdkModelClasses
22949
22952
  });
22950
- return this.database;
22953
+ this.databases.set(dbName, database);
22954
+ return database;
22951
22955
  }
22952
22956
  /**
22953
- * Reset the current database (useful for logout or testing).
22957
+ * Reset ALL cached databases (useful for logout or testing).
22954
22958
  */
22955
22959
  async resetDatabase() {
22956
- const db = this.database;
22957
- if (db) {
22958
- await db.write(async () => {
22959
- await db.unsafeResetDatabase();
22960
- });
22961
- this.database = null;
22962
- this.currentWalletAddress = void 0;
22960
+ const errors = [];
22961
+ for (const [dbName, db] of [...this.databases.entries()]) {
22962
+ try {
22963
+ await db.write(async () => {
22964
+ await db.unsafeResetDatabase();
22965
+ });
22966
+ this.databases.delete(dbName);
22967
+ } catch (error) {
22968
+ errors.push({ dbName, error });
22969
+ }
22970
+ }
22971
+ if (errors.length > 0) {
22972
+ throw new Error(
22973
+ `Failed to reset ${errors.length} database(s): ${errors.map((e) => e.dbName).join(", ")}`
22974
+ );
22963
22975
  }
22964
22976
  }
22965
22977
  /**
@@ -248,8 +248,18 @@ interface DatabaseManagerOptions {
248
248
  * ```
249
249
  */
250
250
  declare class DatabaseManager {
251
- private database;
252
- private currentWalletAddress;
251
+ /**
252
+ * WatermelonDB instances cached by their derived `dbName` (not by raw wallet
253
+ * address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
254
+ * that is requested again — including after a transient `undefined`/guest
255
+ * excursion or an address that briefly arrives in a different form during
256
+ * sign-up — reuses the SAME instance instead of being torn down and rebuilt.
257
+ * The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
258
+ * (client#4821). Instances are kept for the lifetime of the manager (typically
259
+ * guest + one wallet); switching wallets keeps prior ones cached rather than
260
+ * disposing an instance the app may still hold a reference to.
261
+ */
262
+ private readonly databases;
253
263
  private migrationInProgress;
254
264
  private readonly dbNamePrefix;
255
265
  private readonly createAdapter;
@@ -264,8 +274,9 @@ declare class DatabaseManager {
264
274
  /**
265
275
  * Get or create a WatermelonDB Database instance for the given wallet.
266
276
  *
267
- * If the wallet address has changed since the last call, the previous
268
- * database instance is discarded and a new one is created.
277
+ * Instances are cached per derived dbName and reused across calls (including
278
+ * repeat/guest-interleaved requests for the same wallet); a new one is built
279
+ * only for a dbName not yet seen. See the `databases` field for why.
269
280
  *
270
281
  * @param walletAddress - The wallet address to scope the database to.
271
282
  * If undefined, uses a "guest" database.
@@ -274,7 +285,7 @@ declare class DatabaseManager {
274
285
  */
275
286
  getDatabase(walletAddress?: string): Database;
276
287
  /**
277
- * Reset the current database (useful for logout or testing).
288
+ * Reset ALL cached databases (useful for logout or testing).
278
289
  */
279
290
  resetDatabase(): Promise<void>;
280
291
  /**
@@ -248,8 +248,18 @@ interface DatabaseManagerOptions {
248
248
  * ```
249
249
  */
250
250
  declare class DatabaseManager {
251
- private database;
252
- private currentWalletAddress;
251
+ /**
252
+ * WatermelonDB instances cached by their derived `dbName` (not by raw wallet
253
+ * address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
254
+ * that is requested again — including after a transient `undefined`/guest
255
+ * excursion or an address that briefly arrives in a different form during
256
+ * sign-up — reuses the SAME instance instead of being torn down and rebuilt.
257
+ * The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
258
+ * (client#4821). Instances are kept for the lifetime of the manager (typically
259
+ * guest + one wallet); switching wallets keeps prior ones cached rather than
260
+ * disposing an instance the app may still hold a reference to.
261
+ */
262
+ private readonly databases;
253
263
  private migrationInProgress;
254
264
  private readonly dbNamePrefix;
255
265
  private readonly createAdapter;
@@ -264,8 +274,9 @@ declare class DatabaseManager {
264
274
  /**
265
275
  * Get or create a WatermelonDB Database instance for the given wallet.
266
276
  *
267
- * If the wallet address has changed since the last call, the previous
268
- * database instance is discarded and a new one is created.
277
+ * Instances are cached per derived dbName and reused across calls (including
278
+ * repeat/guest-interleaved requests for the same wallet); a new one is built
279
+ * only for a dbName not yet seen. See the `databases` field for why.
269
280
  *
270
281
  * @param walletAddress - The wallet address to scope the database to.
271
282
  * If undefined, uses a "guest" database.
@@ -274,7 +285,7 @@ declare class DatabaseManager {
274
285
  */
275
286
  getDatabase(walletAddress?: string): Database;
276
287
  /**
277
- * Reset the current database (useful for logout or testing).
288
+ * Reset ALL cached databases (useful for logout or testing).
278
289
  */
279
290
  resetDatabase(): Promise<void>;
280
291
  /**
@@ -2000,8 +2000,18 @@ function getMigrationReloadKey(prefix, walletAddress) {
2000
2000
  }
2001
2001
  var DatabaseManager = class {
2002
2002
  constructor(options) {
2003
- this.database = null;
2004
- this.currentWalletAddress = void 0;
2003
+ /**
2004
+ * WatermelonDB instances cached by their derived `dbName` (not by raw wallet
2005
+ * address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
2006
+ * that is requested again — including after a transient `undefined`/guest
2007
+ * excursion or an address that briefly arrives in a different form during
2008
+ * sign-up — reuses the SAME instance instead of being torn down and rebuilt.
2009
+ * The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
2010
+ * (client#4821). Instances are kept for the lifetime of the manager (typically
2011
+ * guest + one wallet); switching wallets keeps prior ones cached rather than
2012
+ * disposing an instance the app may still hold a reference to.
2013
+ */
2014
+ this.databases = /* @__PURE__ */ new Map();
2005
2015
  this.migrationInProgress = false;
2006
2016
  this.dbNamePrefix = options.dbNamePrefix;
2007
2017
  this.createAdapter = options.createAdapter;
@@ -2018,8 +2028,9 @@ var DatabaseManager = class {
2018
2028
  /**
2019
2029
  * Get or create a WatermelonDB Database instance for the given wallet.
2020
2030
  *
2021
- * If the wallet address has changed since the last call, the previous
2022
- * database instance is discarded and a new one is created.
2031
+ * Instances are cached per derived dbName and reused across calls (including
2032
+ * repeat/guest-interleaved requests for the same wallet); a new one is built
2033
+ * only for a dbName not yet seen. See the `databases` field for why.
2023
2034
  *
2024
2035
  * @param walletAddress - The wallet address to scope the database to.
2025
2036
  * If undefined, uses a "guest" database.
@@ -2027,46 +2038,47 @@ var DatabaseManager = class {
2027
2038
  * @throws If a destructive migration is in progress
2028
2039
  */
2029
2040
  getDatabase(walletAddress) {
2030
- if (this.database && this.currentWalletAddress !== walletAddress) {
2031
- this.logger.debug?.("Wallet changed, switching database", {
2032
- component: "DatabaseManager",
2033
- from: this.currentWalletAddress,
2034
- to: walletAddress
2035
- });
2036
- this.database = null;
2037
- }
2038
- if (this.database) {
2039
- return this.database;
2041
+ const dbName = this.getDbName(walletAddress);
2042
+ const cached = this.databases.get(dbName);
2043
+ if (cached) {
2044
+ return cached;
2040
2045
  }
2041
2046
  const needsMigration = this.handleSchemaMigration(walletAddress);
2042
2047
  if (needsMigration) {
2043
2048
  throw new Error("Database migration in progress - app will restart");
2044
2049
  }
2045
- this.currentWalletAddress = walletAddress;
2046
- const dbName = this.getDbName(walletAddress);
2047
2050
  this.logger.debug?.("Initializing database", {
2048
2051
  component: "DatabaseManager",
2049
2052
  dbName,
2050
2053
  walletAddress
2051
2054
  });
2052
2055
  const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
2053
- this.database = new import_watermelondb13.Database({
2056
+ const database = new import_watermelondb13.Database({
2054
2057
  adapter,
2055
2058
  modelClasses: sdkModelClasses
2056
2059
  });
2057
- return this.database;
2060
+ this.databases.set(dbName, database);
2061
+ return database;
2058
2062
  }
2059
2063
  /**
2060
- * Reset the current database (useful for logout or testing).
2064
+ * Reset ALL cached databases (useful for logout or testing).
2061
2065
  */
2062
2066
  async resetDatabase() {
2063
- const db = this.database;
2064
- if (db) {
2065
- await db.write(async () => {
2066
- await db.unsafeResetDatabase();
2067
- });
2068
- this.database = null;
2069
- this.currentWalletAddress = void 0;
2067
+ const errors = [];
2068
+ for (const [dbName, db] of [...this.databases.entries()]) {
2069
+ try {
2070
+ await db.write(async () => {
2071
+ await db.unsafeResetDatabase();
2072
+ });
2073
+ this.databases.delete(dbName);
2074
+ } catch (error) {
2075
+ errors.push({ dbName, error });
2076
+ }
2077
+ }
2078
+ if (errors.length > 0) {
2079
+ throw new Error(
2080
+ `Failed to reset ${errors.length} database(s): ${errors.map((e) => e.dbName).join(", ")}`
2081
+ );
2070
2082
  }
2071
2083
  }
2072
2084
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",