@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.d.cts CHANGED
@@ -3679,7 +3679,7 @@ declare class GroupChatModule {
3679
3679
  constructor(config?: GroupChatModuleConfig);
3680
3680
  initialize(deps: GroupChatModuleDependencies): void;
3681
3681
  load(): Promise<void>;
3682
- destroy(): void;
3682
+ destroy(): Promise<void>;
3683
3683
  private destroyConnection;
3684
3684
  connect(): Promise<void>;
3685
3685
  getConnectionStatus(): boolean;
@@ -3740,7 +3740,7 @@ declare class GroupChatModule {
3740
3740
  * or 0 if no messages exist. Used to set `since` on subscriptions so the relay
3741
3741
  * only sends events we don't already have.
3742
3742
  */
3743
- private getLatestMessageTimestamp;
3743
+ private getLatestKnownTimestamp;
3744
3744
  private fetchRelayAdmins;
3745
3745
  private doFetchRelayAdmins;
3746
3746
  private fetchGroupMetadataInternal;
package/dist/index.d.ts CHANGED
@@ -3679,7 +3679,7 @@ declare class GroupChatModule {
3679
3679
  constructor(config?: GroupChatModuleConfig);
3680
3680
  initialize(deps: GroupChatModuleDependencies): void;
3681
3681
  load(): Promise<void>;
3682
- destroy(): void;
3682
+ destroy(): Promise<void>;
3683
3683
  private destroyConnection;
3684
3684
  connect(): Promise<void>;
3685
3685
  getConnectionStatus(): boolean;
@@ -3740,7 +3740,7 @@ declare class GroupChatModule {
3740
3740
  * or 0 if no messages exist. Used to set `since` on subscriptions so the relay
3741
3741
  * only sends events we don't already have.
3742
3742
  */
3743
- private getLatestMessageTimestamp;
3743
+ private getLatestKnownTimestamp;
3744
3744
  private fetchRelayAdmins;
3745
3745
  private doFetchRelayAdmins;
3746
3746
  private fetchGroupMetadataInternal;
package/dist/index.js CHANGED
@@ -12381,8 +12381,20 @@ var GroupChatModule = class {
12381
12381
  }
12382
12382
  }
12383
12383
  }
12384
- destroy() {
12384
+ async destroy() {
12385
12385
  this.destroyConnection();
12386
+ if (this.persistTimer) {
12387
+ clearTimeout(this.persistTimer);
12388
+ this.persistTimer = null;
12389
+ }
12390
+ if (this.deps) {
12391
+ try {
12392
+ if (this.persistPromise) await this.persistPromise;
12393
+ await this.doPersistAll();
12394
+ } catch (err) {
12395
+ logger.debug("GroupChat", "Persist on destroy failed", err);
12396
+ }
12397
+ }
12386
12398
  this.groups.clear();
12387
12399
  this.messages.clear();
12388
12400
  this.members.clear();
@@ -12391,10 +12403,7 @@ var GroupChatModule = class {
12391
12403
  this.messageHandlers.clear();
12392
12404
  this.relayAdminPubkeys = null;
12393
12405
  this.relayAdminFetchPromise = null;
12394
- if (this.persistTimer) {
12395
- clearTimeout(this.persistTimer);
12396
- this.persistTimer = null;
12397
- }
12406
+ this.persistPromise = null;
12398
12407
  this.deps = null;
12399
12408
  }
12400
12409
  destroyConnection() {
@@ -12519,12 +12528,12 @@ var GroupChatModule = class {
12519
12528
  if (!this.client) return;
12520
12529
  const groupIds = Array.from(this.groups.keys());
12521
12530
  if (groupIds.length === 0) return;
12522
- const latestTimestamp = this.getLatestMessageTimestamp(groupIds);
12531
+ const sinceTimestamp = this.getLatestKnownTimestamp(groupIds);
12523
12532
  this.trackSubscription(
12524
12533
  createNip29Filter({
12525
12534
  kinds: [NIP29_KINDS.CHAT_MESSAGE, NIP29_KINDS.THREAD_ROOT, NIP29_KINDS.THREAD_REPLY],
12526
12535
  "#h": groupIds,
12527
- ...latestTimestamp ? { since: latestTimestamp } : {}
12536
+ ...sinceTimestamp ? { since: sinceTimestamp } : {}
12528
12537
  }),
12529
12538
  { onEvent: (event) => this.handleGroupEvent(event) }
12530
12539
  );
@@ -12545,12 +12554,12 @@ var GroupChatModule = class {
12545
12554
  }
12546
12555
  subscribeToGroup(groupId) {
12547
12556
  if (!this.client) return;
12548
- const latestTimestamp = this.getLatestMessageTimestamp([groupId]);
12557
+ const sinceTimestamp = this.getLatestKnownTimestamp([groupId]);
12549
12558
  this.trackSubscription(
12550
12559
  createNip29Filter({
12551
12560
  kinds: [NIP29_KINDS.CHAT_MESSAGE, NIP29_KINDS.THREAD_ROOT, NIP29_KINDS.THREAD_REPLY],
12552
12561
  "#h": [groupId],
12553
- ...latestTimestamp ? { since: latestTimestamp } : {}
12562
+ ...sinceTimestamp ? { since: sinceTimestamp } : {}
12554
12563
  }),
12555
12564
  { onEvent: (event) => this.handleGroupEvent(event) }
12556
12565
  );
@@ -12624,7 +12633,7 @@ var GroupChatModule = class {
12624
12633
  }
12625
12634
  group.updatedAt = event.created_at * 1e3;
12626
12635
  this.groups.set(groupId, group);
12627
- this.persistGroups();
12636
+ this.schedulePersist();
12628
12637
  } else if (event.kind === NIP29_KINDS.GROUP_MEMBERS) {
12629
12638
  this.updateMembersFromEvent(groupId, event);
12630
12639
  } else if (event.kind === NIP29_KINDS.GROUP_ADMINS) {
@@ -12645,7 +12654,7 @@ var GroupChatModule = class {
12645
12654
  }
12646
12655
  }
12647
12656
  this.deps.emitEvent("groupchat:updated", {});
12648
- this.persistMessages();
12657
+ this.schedulePersist();
12649
12658
  } else if (event.kind === NIP29_KINDS.REMOVE_USER) {
12650
12659
  if (this.processedEventIds.has(event.id)) return;
12651
12660
  const eventTimestampMs = event.created_at * 1e3;
@@ -12706,7 +12715,7 @@ var GroupChatModule = class {
12706
12715
  };
12707
12716
  this.saveMemberToMemory(member);
12708
12717
  }
12709
- this.persistMembers();
12718
+ this.schedulePersist();
12710
12719
  }
12711
12720
  updateAdminsFromEvent(groupId, event) {
12712
12721
  const pTags = event.tags.filter((t) => t[0] === "p");
@@ -12726,7 +12735,7 @@ var GroupChatModule = class {
12726
12735
  });
12727
12736
  }
12728
12737
  }
12729
- this.persistMembers();
12738
+ this.schedulePersist();
12730
12739
  }
12731
12740
  // ===========================================================================
12732
12741
  // Group Membership Restoration
@@ -12737,13 +12746,11 @@ var GroupChatModule = class {
12737
12746
  if (!myPubkey) return [];
12738
12747
  const groupIdsWithMembership = /* @__PURE__ */ new Set();
12739
12748
  await this.oneshotSubscription(
12740
- new Filter3({ kinds: [NIP29_KINDS.GROUP_MEMBERS] }),
12749
+ createNip29Filter({ kinds: [NIP29_KINDS.GROUP_MEMBERS], "#p": [myPubkey] }),
12741
12750
  {
12742
12751
  onEvent: (event) => {
12743
12752
  const groupId = this.getGroupIdFromMetadataEvent(event);
12744
- if (!groupId) return;
12745
- const pTags = event.tags.filter((t) => t[0] === "p");
12746
- if (pTags.some((tag) => tag[1] === myPubkey)) {
12753
+ if (groupId) {
12747
12754
  groupIdsWithMembership.add(groupId);
12748
12755
  }
12749
12756
  },
@@ -12755,22 +12762,24 @@ var GroupChatModule = class {
12755
12762
  );
12756
12763
  if (groupIdsWithMembership.size === 0) return [];
12757
12764
  const restoredGroups = [];
12758
- for (const groupId of groupIdsWithMembership) {
12759
- if (this.groups.has(groupId)) continue;
12760
- try {
12761
- const group = await this.fetchGroupMetadataInternal(groupId);
12762
- if (group) {
12763
- this.groups.set(groupId, group);
12764
- restoredGroups.push(group);
12765
- await Promise.all([
12766
- this.fetchAndSaveMembers(groupId),
12767
- this.fetchMessages(groupId)
12768
- ]);
12765
+ await Promise.all(
12766
+ Array.from(groupIdsWithMembership).map(async (groupId) => {
12767
+ if (this.groups.has(groupId)) return;
12768
+ try {
12769
+ const group = await this.fetchGroupMetadataInternal(groupId);
12770
+ if (group) {
12771
+ this.groups.set(groupId, group);
12772
+ restoredGroups.push(group);
12773
+ await Promise.all([
12774
+ this.fetchAndSaveMembers(groupId),
12775
+ this.fetchMessages(groupId)
12776
+ ]);
12777
+ }
12778
+ } catch (error) {
12779
+ logger.warn("GroupChat", "Failed to restore group", groupId, error);
12769
12780
  }
12770
- } catch (error) {
12771
- logger.warn("GroupChat", "Failed to restore group", groupId, error);
12772
- }
12773
- }
12781
+ })
12782
+ );
12774
12783
  if (restoredGroups.length > 0) {
12775
12784
  await this.subscribeToJoinedGroups();
12776
12785
  this.deps.emitEvent("groupchat:updated", {});
@@ -13156,7 +13165,7 @@ var GroupChatModule = class {
13156
13165
  if (group && (group.unreadCount || 0) > 0) {
13157
13166
  group.unreadCount = 0;
13158
13167
  this.groups.set(groupId, group);
13159
- this.persistGroups();
13168
+ this.schedulePersist();
13160
13169
  }
13161
13170
  }
13162
13171
  // ===========================================================================
@@ -13178,7 +13187,7 @@ var GroupChatModule = class {
13178
13187
  if (eventId) {
13179
13188
  this.removeMemberFromMemory(groupId, userPubkey);
13180
13189
  this.deps.emitEvent("groupchat:updated", {});
13181
- this.persistMembers();
13190
+ this.schedulePersist();
13182
13191
  return true;
13183
13192
  }
13184
13193
  return false;
@@ -13201,7 +13210,7 @@ var GroupChatModule = class {
13201
13210
  if (eventId) {
13202
13211
  this.deleteMessageFromMemory(groupId, messageId);
13203
13212
  this.deps.emitEvent("groupchat:updated", {});
13204
- this.persistMessages();
13213
+ this.schedulePersist();
13205
13214
  return true;
13206
13215
  }
13207
13216
  return false;
@@ -13281,13 +13290,19 @@ var GroupChatModule = class {
13281
13290
  * or 0 if no messages exist. Used to set `since` on subscriptions so the relay
13282
13291
  * only sends events we don't already have.
13283
13292
  */
13284
- getLatestMessageTimestamp(groupIds) {
13293
+ getLatestKnownTimestamp(groupIds) {
13285
13294
  let latest = 0;
13286
13295
  for (const gid of groupIds) {
13287
13296
  const msgs = this.messages.get(gid);
13288
- if (!msgs) continue;
13289
- for (const m of msgs) {
13290
- const ts = Math.floor(m.timestamp / 1e3);
13297
+ if (msgs) {
13298
+ for (const m of msgs) {
13299
+ const ts = Math.floor(m.timestamp / 1e3);
13300
+ if (ts > latest) latest = ts;
13301
+ }
13302
+ }
13303
+ const group = this.groups.get(gid);
13304
+ if (group) {
13305
+ const ts = Math.floor((group.updatedAt || group.createdAt) / 1e3);
13291
13306
  if (ts > latest) latest = ts;
13292
13307
  }
13293
13308
  }
@@ -13362,7 +13377,7 @@ var GroupChatModule = class {
13362
13377
  });
13363
13378
  }
13364
13379
  }
13365
- this.persistMembers();
13380
+ this.schedulePersist();
13366
13381
  }
13367
13382
  async fetchGroupMembersInternal(groupId) {
13368
13383
  if (!this.client) return [];
@@ -13489,8 +13504,11 @@ var GroupChatModule = class {
13489
13504
  addProcessedEventId(eventId) {
13490
13505
  this.processedEventIds.add(eventId);
13491
13506
  if (this.processedEventIds.size > 1e4) {
13492
- const arr = Array.from(this.processedEventIds);
13493
- this.processedEventIds = new Set(arr.slice(arr.length - 1e4));
13507
+ let toDelete = 5e3;
13508
+ for (const id of this.processedEventIds) {
13509
+ if (toDelete-- <= 0) break;
13510
+ this.processedEventIds.delete(id);
13511
+ }
13494
13512
  }
13495
13513
  }
13496
13514
  // ===========================================================================