@unicitylabs/sphere-sdk 0.6.10-dev.1 → 0.6.10-dev.3

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
@@ -12528,8 +12528,20 @@ var GroupChatModule = class {
12528
12528
  }
12529
12529
  }
12530
12530
  }
12531
- destroy() {
12531
+ async destroy() {
12532
12532
  this.destroyConnection();
12533
+ if (this.persistTimer) {
12534
+ clearTimeout(this.persistTimer);
12535
+ this.persistTimer = null;
12536
+ }
12537
+ if (this.deps) {
12538
+ try {
12539
+ if (this.persistPromise) await this.persistPromise;
12540
+ await this.doPersistAll();
12541
+ } catch (err) {
12542
+ logger.debug("GroupChat", "Persist on destroy failed", err);
12543
+ }
12544
+ }
12533
12545
  this.groups.clear();
12534
12546
  this.messages.clear();
12535
12547
  this.members.clear();
@@ -12538,10 +12550,7 @@ var GroupChatModule = class {
12538
12550
  this.messageHandlers.clear();
12539
12551
  this.relayAdminPubkeys = null;
12540
12552
  this.relayAdminFetchPromise = null;
12541
- if (this.persistTimer) {
12542
- clearTimeout(this.persistTimer);
12543
- this.persistTimer = null;
12544
- }
12553
+ this.persistPromise = null;
12545
12554
  this.deps = null;
12546
12555
  }
12547
12556
  destroyConnection() {
@@ -12666,12 +12675,12 @@ var GroupChatModule = class {
12666
12675
  if (!this.client) return;
12667
12676
  const groupIds = Array.from(this.groups.keys());
12668
12677
  if (groupIds.length === 0) return;
12669
- const latestTimestamp = this.getLatestMessageTimestamp(groupIds);
12678
+ const sinceTimestamp = this.getLatestKnownTimestamp(groupIds);
12670
12679
  this.trackSubscription(
12671
12680
  createNip29Filter({
12672
12681
  kinds: [NIP29_KINDS.CHAT_MESSAGE, NIP29_KINDS.THREAD_ROOT, NIP29_KINDS.THREAD_REPLY],
12673
12682
  "#h": groupIds,
12674
- ...latestTimestamp ? { since: latestTimestamp } : {}
12683
+ ...sinceTimestamp ? { since: sinceTimestamp } : {}
12675
12684
  }),
12676
12685
  { onEvent: (event) => this.handleGroupEvent(event) }
12677
12686
  );
@@ -12692,12 +12701,12 @@ var GroupChatModule = class {
12692
12701
  }
12693
12702
  subscribeToGroup(groupId) {
12694
12703
  if (!this.client) return;
12695
- const latestTimestamp = this.getLatestMessageTimestamp([groupId]);
12704
+ const sinceTimestamp = this.getLatestKnownTimestamp([groupId]);
12696
12705
  this.trackSubscription(
12697
12706
  createNip29Filter({
12698
12707
  kinds: [NIP29_KINDS.CHAT_MESSAGE, NIP29_KINDS.THREAD_ROOT, NIP29_KINDS.THREAD_REPLY],
12699
12708
  "#h": [groupId],
12700
- ...latestTimestamp ? { since: latestTimestamp } : {}
12709
+ ...sinceTimestamp ? { since: sinceTimestamp } : {}
12701
12710
  }),
12702
12711
  { onEvent: (event) => this.handleGroupEvent(event) }
12703
12712
  );
@@ -12771,7 +12780,7 @@ var GroupChatModule = class {
12771
12780
  }
12772
12781
  group.updatedAt = event.created_at * 1e3;
12773
12782
  this.groups.set(groupId, group);
12774
- this.persistGroups();
12783
+ this.schedulePersist();
12775
12784
  } else if (event.kind === NIP29_KINDS.GROUP_MEMBERS) {
12776
12785
  this.updateMembersFromEvent(groupId, event);
12777
12786
  } else if (event.kind === NIP29_KINDS.GROUP_ADMINS) {
@@ -12792,7 +12801,7 @@ var GroupChatModule = class {
12792
12801
  }
12793
12802
  }
12794
12803
  this.deps.emitEvent("groupchat:updated", {});
12795
- this.persistMessages();
12804
+ this.schedulePersist();
12796
12805
  } else if (event.kind === NIP29_KINDS.REMOVE_USER) {
12797
12806
  if (this.processedEventIds.has(event.id)) return;
12798
12807
  const eventTimestampMs = event.created_at * 1e3;
@@ -12853,7 +12862,7 @@ var GroupChatModule = class {
12853
12862
  };
12854
12863
  this.saveMemberToMemory(member);
12855
12864
  }
12856
- this.persistMembers();
12865
+ this.schedulePersist();
12857
12866
  }
12858
12867
  updateAdminsFromEvent(groupId, event) {
12859
12868
  const pTags = event.tags.filter((t) => t[0] === "p");
@@ -12873,7 +12882,7 @@ var GroupChatModule = class {
12873
12882
  });
12874
12883
  }
12875
12884
  }
12876
- this.persistMembers();
12885
+ this.schedulePersist();
12877
12886
  }
12878
12887
  // ===========================================================================
12879
12888
  // Group Membership Restoration
@@ -12884,13 +12893,11 @@ var GroupChatModule = class {
12884
12893
  if (!myPubkey) return [];
12885
12894
  const groupIdsWithMembership = /* @__PURE__ */ new Set();
12886
12895
  await this.oneshotSubscription(
12887
- new import_nostr_js_sdk4.Filter({ kinds: [NIP29_KINDS.GROUP_MEMBERS] }),
12896
+ createNip29Filter({ kinds: [NIP29_KINDS.GROUP_MEMBERS], "#p": [myPubkey] }),
12888
12897
  {
12889
12898
  onEvent: (event) => {
12890
12899
  const groupId = this.getGroupIdFromMetadataEvent(event);
12891
- if (!groupId) return;
12892
- const pTags = event.tags.filter((t) => t[0] === "p");
12893
- if (pTags.some((tag) => tag[1] === myPubkey)) {
12900
+ if (groupId) {
12894
12901
  groupIdsWithMembership.add(groupId);
12895
12902
  }
12896
12903
  },
@@ -12902,22 +12909,24 @@ var GroupChatModule = class {
12902
12909
  );
12903
12910
  if (groupIdsWithMembership.size === 0) return [];
12904
12911
  const restoredGroups = [];
12905
- for (const groupId of groupIdsWithMembership) {
12906
- if (this.groups.has(groupId)) continue;
12907
- try {
12908
- const group = await this.fetchGroupMetadataInternal(groupId);
12909
- if (group) {
12910
- this.groups.set(groupId, group);
12911
- restoredGroups.push(group);
12912
- await Promise.all([
12913
- this.fetchAndSaveMembers(groupId),
12914
- this.fetchMessages(groupId)
12915
- ]);
12912
+ await Promise.all(
12913
+ Array.from(groupIdsWithMembership).map(async (groupId) => {
12914
+ if (this.groups.has(groupId)) return;
12915
+ try {
12916
+ const group = await this.fetchGroupMetadataInternal(groupId);
12917
+ if (group) {
12918
+ this.groups.set(groupId, group);
12919
+ restoredGroups.push(group);
12920
+ await Promise.all([
12921
+ this.fetchAndSaveMembers(groupId),
12922
+ this.fetchMessages(groupId)
12923
+ ]);
12924
+ }
12925
+ } catch (error) {
12926
+ logger.warn("GroupChat", "Failed to restore group", groupId, error);
12916
12927
  }
12917
- } catch (error) {
12918
- logger.warn("GroupChat", "Failed to restore group", groupId, error);
12919
- }
12920
- }
12928
+ })
12929
+ );
12921
12930
  if (restoredGroups.length > 0) {
12922
12931
  await this.subscribeToJoinedGroups();
12923
12932
  this.deps.emitEvent("groupchat:updated", {});
@@ -13303,7 +13312,7 @@ var GroupChatModule = class {
13303
13312
  if (group && (group.unreadCount || 0) > 0) {
13304
13313
  group.unreadCount = 0;
13305
13314
  this.groups.set(groupId, group);
13306
- this.persistGroups();
13315
+ this.schedulePersist();
13307
13316
  }
13308
13317
  }
13309
13318
  // ===========================================================================
@@ -13325,7 +13334,7 @@ var GroupChatModule = class {
13325
13334
  if (eventId) {
13326
13335
  this.removeMemberFromMemory(groupId, userPubkey);
13327
13336
  this.deps.emitEvent("groupchat:updated", {});
13328
- this.persistMembers();
13337
+ this.schedulePersist();
13329
13338
  return true;
13330
13339
  }
13331
13340
  return false;
@@ -13348,7 +13357,7 @@ var GroupChatModule = class {
13348
13357
  if (eventId) {
13349
13358
  this.deleteMessageFromMemory(groupId, messageId);
13350
13359
  this.deps.emitEvent("groupchat:updated", {});
13351
- this.persistMessages();
13360
+ this.schedulePersist();
13352
13361
  return true;
13353
13362
  }
13354
13363
  return false;
@@ -13428,13 +13437,19 @@ var GroupChatModule = class {
13428
13437
  * or 0 if no messages exist. Used to set `since` on subscriptions so the relay
13429
13438
  * only sends events we don't already have.
13430
13439
  */
13431
- getLatestMessageTimestamp(groupIds) {
13440
+ getLatestKnownTimestamp(groupIds) {
13432
13441
  let latest = 0;
13433
13442
  for (const gid of groupIds) {
13434
13443
  const msgs = this.messages.get(gid);
13435
- if (!msgs) continue;
13436
- for (const m of msgs) {
13437
- const ts = Math.floor(m.timestamp / 1e3);
13444
+ if (msgs) {
13445
+ for (const m of msgs) {
13446
+ const ts = Math.floor(m.timestamp / 1e3);
13447
+ if (ts > latest) latest = ts;
13448
+ }
13449
+ }
13450
+ const group = this.groups.get(gid);
13451
+ if (group) {
13452
+ const ts = Math.floor((group.updatedAt || group.createdAt) / 1e3);
13438
13453
  if (ts > latest) latest = ts;
13439
13454
  }
13440
13455
  }
@@ -13509,7 +13524,7 @@ var GroupChatModule = class {
13509
13524
  });
13510
13525
  }
13511
13526
  }
13512
- this.persistMembers();
13527
+ this.schedulePersist();
13513
13528
  }
13514
13529
  async fetchGroupMembersInternal(groupId) {
13515
13530
  if (!this.client) return [];
@@ -13636,8 +13651,11 @@ var GroupChatModule = class {
13636
13651
  addProcessedEventId(eventId) {
13637
13652
  this.processedEventIds.add(eventId);
13638
13653
  if (this.processedEventIds.size > 1e4) {
13639
- const arr = Array.from(this.processedEventIds);
13640
- this.processedEventIds = new Set(arr.slice(arr.length - 1e4));
13654
+ let toDelete = 5e3;
13655
+ for (const id of this.processedEventIds) {
13656
+ if (toDelete-- <= 0) break;
13657
+ this.processedEventIds.delete(id);
13658
+ }
13641
13659
  }
13642
13660
  }
13643
13661
  // ===========================================================================