@unicitylabs/sphere-sdk 0.6.5 → 0.6.6

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.
@@ -6340,7 +6340,7 @@ function normalizeToHex(value) {
6340
6340
  return String(value);
6341
6341
  }
6342
6342
  function normalizeSdkTokenToStorage(sdkTokenJson) {
6343
- const txf = JSON.parse(JSON.stringify(sdkTokenJson));
6343
+ const txf = structuredClone(sdkTokenJson);
6344
6344
  if (txf.genesis?.data) {
6345
6345
  const data = txf.genesis.data;
6346
6346
  if (data.tokenId !== void 0) {
@@ -7570,35 +7570,45 @@ async function parseTokenInfo(tokenData) {
7570
7570
  }
7571
7571
  return defaultInfo;
7572
7572
  }
7573
- function extractTokenIdFromSdkData(sdkData) {
7574
- if (!sdkData) return null;
7575
- try {
7576
- const txf = JSON.parse(sdkData);
7577
- return txf.genesis?.data?.tokenId || null;
7578
- } catch {
7579
- return null;
7580
- }
7581
- }
7582
- function extractStateHashFromSdkData(sdkData) {
7583
- if (!sdkData) return "";
7573
+ var sdkDataCache = /* @__PURE__ */ new Map();
7574
+ var SDK_DATA_CACHE_MAX = 2e3;
7575
+ function parseSdkDataCached(sdkData) {
7576
+ const cached = sdkDataCache.get(sdkData);
7577
+ if (cached) return cached;
7578
+ let tokenId = null;
7579
+ let stateHash = "";
7584
7580
  try {
7585
7581
  const txf = JSON.parse(sdkData);
7586
- const stateHash = getCurrentStateHash(txf);
7582
+ tokenId = txf.genesis?.data?.tokenId || null;
7583
+ stateHash = getCurrentStateHash(txf) || "";
7587
7584
  if (!stateHash) {
7588
7585
  if (txf.state?.hash) {
7589
- return txf.state.hash;
7590
- }
7591
- if (txf.stateHash) {
7592
- return txf.stateHash;
7593
- }
7594
- if (txf.currentStateHash) {
7595
- return txf.currentStateHash;
7586
+ stateHash = txf.state.hash;
7587
+ } else if (txf.stateHash) {
7588
+ stateHash = txf.stateHash;
7589
+ } else if (txf.currentStateHash) {
7590
+ stateHash = txf.currentStateHash;
7596
7591
  }
7597
7592
  }
7598
- return stateHash || "";
7599
7593
  } catch {
7600
- return "";
7601
7594
  }
7595
+ const entry = { tokenId, stateHash };
7596
+ if (sdkDataCache.size >= SDK_DATA_CACHE_MAX) {
7597
+ sdkDataCache.clear();
7598
+ }
7599
+ sdkDataCache.set(sdkData, entry);
7600
+ return entry;
7601
+ }
7602
+ function clearSdkDataCache() {
7603
+ sdkDataCache.clear();
7604
+ }
7605
+ function extractTokenIdFromSdkData(sdkData) {
7606
+ if (!sdkData) return null;
7607
+ return parseSdkDataCached(sdkData).tokenId;
7608
+ }
7609
+ function extractStateHashFromSdkData(sdkData) {
7610
+ if (!sdkData) return "";
7611
+ return parseSdkDataCached(sdkData).stateHash;
7602
7612
  }
7603
7613
  function createTokenStateKey(tokenId, stateHash) {
7604
7614
  return `${tokenId}_${stateHash}`;
@@ -7708,6 +7718,8 @@ var PaymentsModule = class _PaymentsModule {
7708
7718
  pendingBackgroundTasks = [];
7709
7719
  // Repository State (tombstones, archives, forked, history)
7710
7720
  tombstones = [];
7721
+ // O(1) lookup set derived from tombstones array. Rebuilt via rebuildTombstoneKeySet().
7722
+ tombstoneKeySet = /* @__PURE__ */ new Set();
7711
7723
  archivedTokens = /* @__PURE__ */ new Map();
7712
7724
  forkedTokens = /* @__PURE__ */ new Map();
7713
7725
  _historyCache = [];
@@ -7792,8 +7804,10 @@ var PaymentsModule = class _PaymentsModule {
7792
7804
  }
7793
7805
  this.pendingResponseResolvers.clear();
7794
7806
  this.tokens.clear();
7807
+ clearSdkDataCache();
7795
7808
  this.pendingTransfers.clear();
7796
7809
  this.tombstones = [];
7810
+ this.tombstoneKeySet.clear();
7797
7811
  this.archivedTokens.clear();
7798
7812
  this.forkedTokens.clear();
7799
7813
  this._historyCache = [];
@@ -9914,11 +9928,10 @@ var PaymentsModule = class _PaymentsModule {
9914
9928
  await this.archiveToken(token);
9915
9929
  const tombstone = createTombstoneFromToken(token);
9916
9930
  if (tombstone) {
9917
- const alreadyTombstoned = this.tombstones.some(
9918
- (t) => t.tokenId === tombstone.tokenId && t.stateHash === tombstone.stateHash
9919
- );
9920
- if (!alreadyTombstoned) {
9931
+ const key = `${tombstone.tokenId}:${tombstone.stateHash}`;
9932
+ if (!this.tombstoneKeySet.has(key)) {
9921
9933
  this.tombstones.push(tombstone);
9934
+ this.tombstoneKeySet.add(key);
9922
9935
  logger.debug("Payments", `Created tombstone for ${tombstone.tokenId.slice(0, 8)}..._${tombstone.stateHash.slice(0, 8)}...`);
9923
9936
  }
9924
9937
  } else {
@@ -9943,15 +9956,20 @@ var PaymentsModule = class _PaymentsModule {
9943
9956
  }
9944
9957
  /**
9945
9958
  * Check whether a specific `(tokenId, stateHash)` combination is tombstoned.
9959
+ * Uses O(1) Set lookup instead of O(n) linear scan.
9946
9960
  *
9947
9961
  * @param tokenId - The genesis token ID.
9948
9962
  * @param stateHash - The state hash of the token version to check.
9949
9963
  * @returns `true` if the exact combination has been tombstoned.
9950
9964
  */
9951
9965
  isStateTombstoned(tokenId, stateHash) {
9952
- return this.tombstones.some(
9953
- (t) => t.tokenId === tokenId && t.stateHash === stateHash
9954
- );
9966
+ return this.tombstoneKeySet.has(`${tokenId}:${stateHash}`);
9967
+ }
9968
+ rebuildTombstoneKeySet() {
9969
+ this.tombstoneKeySet.clear();
9970
+ for (const t of this.tombstones) {
9971
+ this.tombstoneKeySet.add(`${t.tokenId}:${t.stateHash}`);
9972
+ }
9955
9973
  }
9956
9974
  /**
9957
9975
  * Merge tombstones received from a remote sync source.
@@ -9983,11 +10001,10 @@ var PaymentsModule = class _PaymentsModule {
9983
10001
  removedCount++;
9984
10002
  }
9985
10003
  for (const remoteTombstone of remoteTombstones) {
9986
- const alreadyExists = this.tombstones.some(
9987
- (t) => t.tokenId === remoteTombstone.tokenId && t.stateHash === remoteTombstone.stateHash
9988
- );
9989
- if (!alreadyExists) {
10004
+ const key = `${remoteTombstone.tokenId}:${remoteTombstone.stateHash}`;
10005
+ if (!this.tombstoneKeySet.has(key)) {
9990
10006
  this.tombstones.push(remoteTombstone);
10007
+ this.tombstoneKeySet.add(key);
9991
10008
  }
9992
10009
  }
9993
10010
  if (removedCount > 0) {
@@ -10003,6 +10020,7 @@ var PaymentsModule = class _PaymentsModule {
10003
10020
  async pruneTombstones(maxAge) {
10004
10021
  const originalCount = this.tombstones.length;
10005
10022
  this.tombstones = pruneTombstonesByAge(this.tombstones, maxAge);
10023
+ this.rebuildTombstoneKeySet();
10006
10024
  if (this.tombstones.length < originalCount) {
10007
10025
  await this.save();
10008
10026
  logger.debug("Payments", `Pruned tombstones from ${originalCount} to ${this.tombstones.length}`);
@@ -10489,6 +10507,11 @@ var PaymentsModule = class _PaymentsModule {
10489
10507
  }
10490
10508
  const savedTokens = new Map(this.tokens);
10491
10509
  this.loadFromStorageData(result.merged);
10510
+ const existingGenesisIds = /* @__PURE__ */ new Set();
10511
+ for (const existing of this.tokens.values()) {
10512
+ const gid = extractTokenIdFromSdkData(existing.sdkData);
10513
+ if (gid) existingGenesisIds.add(gid);
10514
+ }
10492
10515
  let restoredCount = 0;
10493
10516
  for (const [tokenId, token] of savedTokens) {
10494
10517
  if (this.tokens.has(tokenId)) continue;
@@ -10497,17 +10520,11 @@ var PaymentsModule = class _PaymentsModule {
10497
10520
  if (sdkTokenId && stateHash && this.isStateTombstoned(sdkTokenId, stateHash)) {
10498
10521
  continue;
10499
10522
  }
10500
- if (sdkTokenId) {
10501
- let hasEquivalent = false;
10502
- for (const existing of this.tokens.values()) {
10503
- if (extractTokenIdFromSdkData(existing.sdkData) === sdkTokenId) {
10504
- hasEquivalent = true;
10505
- break;
10506
- }
10507
- }
10508
- if (hasEquivalent) continue;
10523
+ if (sdkTokenId && existingGenesisIds.has(sdkTokenId)) {
10524
+ continue;
10509
10525
  }
10510
10526
  this.tokens.set(tokenId, token);
10527
+ if (sdkTokenId) existingGenesisIds.add(sdkTokenId);
10511
10528
  restoredCount++;
10512
10529
  }
10513
10530
  if (restoredCount > 0) {
@@ -11254,6 +11271,7 @@ var PaymentsModule = class _PaymentsModule {
11254
11271
  const parsed = parseTxfStorageData(data);
11255
11272
  logger.debug("Payments", `loadFromStorageData: parsed ${parsed.tokens.length} tokens, ${parsed.tombstones.length} tombstones, errors=[${parsed.validationErrors.join("; ")}]`);
11256
11273
  this.tombstones = parsed.tombstones;
11274
+ this.rebuildTombstoneKeySet();
11257
11275
  this.tokens.clear();
11258
11276
  for (const token of parsed.tokens) {
11259
11277
  const sdkTokenId = extractTokenIdFromSdkData(token.sdkData);
@@ -17894,9 +17912,16 @@ var Sphere = class _Sphere {
17894
17912
  emitEvent
17895
17913
  });
17896
17914
  await payments.load();
17897
- await communications.load();
17898
- await groupChat?.load();
17899
- await market?.load();
17915
+ const results = await Promise.allSettled([
17916
+ communications.load(),
17917
+ groupChat?.load(),
17918
+ market?.load()
17919
+ ]);
17920
+ for (const r of results) {
17921
+ if (r.status === "rejected") {
17922
+ logger.warn("Sphere", "Module load failed:", r.reason);
17923
+ }
17924
+ }
17900
17925
  const moduleSet = {
17901
17926
  index,
17902
17927
  identity,
@@ -19111,9 +19136,9 @@ var Sphere = class _Sphere {
19111
19136
  await this._transport.connect();
19112
19137
  }
19113
19138
  await this._oracle.initialize();
19114
- for (const provider of this._tokenStorageProviders.values()) {
19115
- await provider.initialize();
19116
- }
19139
+ await Promise.all(
19140
+ [...this._tokenStorageProviders.values()].map((p) => p.initialize())
19141
+ );
19117
19142
  this.subscribeToProviderEvents();
19118
19143
  }
19119
19144
  /**
@@ -19219,10 +19244,17 @@ var Sphere = class _Sphere {
19219
19244
  identity: this._identity,
19220
19245
  emitEvent
19221
19246
  });
19222
- await this._payments.load();
19223
- await this._communications.load();
19224
- await this._groupChat?.load();
19225
- await this._market?.load();
19247
+ const results = await Promise.allSettled([
19248
+ this._payments.load(),
19249
+ this._communications.load(),
19250
+ this._groupChat?.load(),
19251
+ this._market?.load()
19252
+ ]);
19253
+ for (const r of results) {
19254
+ if (r.status === "rejected") {
19255
+ logger.warn("Sphere", "Module load failed:", r.reason);
19256
+ }
19257
+ }
19226
19258
  this._addressModules.set(this._currentAddressIndex, {
19227
19259
  index: this._currentAddressIndex,
19228
19260
  identity: this._identity,