@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.
@@ -3269,7 +3269,7 @@ declare class GroupChatModule {
3269
3269
  constructor(config?: GroupChatModuleConfig);
3270
3270
  initialize(deps: GroupChatModuleDependencies): void;
3271
3271
  load(): Promise<void>;
3272
- destroy(): void;
3272
+ destroy(): Promise<void>;
3273
3273
  private destroyConnection;
3274
3274
  connect(): Promise<void>;
3275
3275
  getConnectionStatus(): boolean;
@@ -3330,7 +3330,7 @@ declare class GroupChatModule {
3330
3330
  * or 0 if no messages exist. Used to set `since` on subscriptions so the relay
3331
3331
  * only sends events we don't already have.
3332
3332
  */
3333
- private getLatestMessageTimestamp;
3333
+ private getLatestKnownTimestamp;
3334
3334
  private fetchRelayAdmins;
3335
3335
  private doFetchRelayAdmins;
3336
3336
  private fetchGroupMetadataInternal;
@@ -3269,7 +3269,7 @@ declare class GroupChatModule {
3269
3269
  constructor(config?: GroupChatModuleConfig);
3270
3270
  initialize(deps: GroupChatModuleDependencies): void;
3271
3271
  load(): Promise<void>;
3272
- destroy(): void;
3272
+ destroy(): Promise<void>;
3273
3273
  private destroyConnection;
3274
3274
  connect(): Promise<void>;
3275
3275
  getConnectionStatus(): boolean;
@@ -3330,7 +3330,7 @@ declare class GroupChatModule {
3330
3330
  * or 0 if no messages exist. Used to set `since` on subscriptions so the relay
3331
3331
  * only sends events we don't already have.
3332
3332
  */
3333
- private getLatestMessageTimestamp;
3333
+ private getLatestKnownTimestamp;
3334
3334
  private fetchRelayAdmins;
3335
3335
  private doFetchRelayAdmins;
3336
3336
  private fetchGroupMetadataInternal;
@@ -12112,8 +12112,20 @@ var GroupChatModule = class {
12112
12112
  }
12113
12113
  }
12114
12114
  }
12115
- destroy() {
12115
+ async destroy() {
12116
12116
  this.destroyConnection();
12117
+ if (this.persistTimer) {
12118
+ clearTimeout(this.persistTimer);
12119
+ this.persistTimer = null;
12120
+ }
12121
+ if (this.deps) {
12122
+ try {
12123
+ if (this.persistPromise) await this.persistPromise;
12124
+ await this.doPersistAll();
12125
+ } catch (err) {
12126
+ logger.debug("GroupChat", "Persist on destroy failed", err);
12127
+ }
12128
+ }
12117
12129
  this.groups.clear();
12118
12130
  this.messages.clear();
12119
12131
  this.members.clear();
@@ -12122,10 +12134,7 @@ var GroupChatModule = class {
12122
12134
  this.messageHandlers.clear();
12123
12135
  this.relayAdminPubkeys = null;
12124
12136
  this.relayAdminFetchPromise = null;
12125
- if (this.persistTimer) {
12126
- clearTimeout(this.persistTimer);
12127
- this.persistTimer = null;
12128
- }
12137
+ this.persistPromise = null;
12129
12138
  this.deps = null;
12130
12139
  }
12131
12140
  destroyConnection() {
@@ -12250,12 +12259,12 @@ var GroupChatModule = class {
12250
12259
  if (!this.client) return;
12251
12260
  const groupIds = Array.from(this.groups.keys());
12252
12261
  if (groupIds.length === 0) return;
12253
- const latestTimestamp = this.getLatestMessageTimestamp(groupIds);
12262
+ const sinceTimestamp = this.getLatestKnownTimestamp(groupIds);
12254
12263
  this.trackSubscription(
12255
12264
  createNip29Filter({
12256
12265
  kinds: [NIP29_KINDS.CHAT_MESSAGE, NIP29_KINDS.THREAD_ROOT, NIP29_KINDS.THREAD_REPLY],
12257
12266
  "#h": groupIds,
12258
- ...latestTimestamp ? { since: latestTimestamp } : {}
12267
+ ...sinceTimestamp ? { since: sinceTimestamp } : {}
12259
12268
  }),
12260
12269
  { onEvent: (event) => this.handleGroupEvent(event) }
12261
12270
  );
@@ -12276,12 +12285,12 @@ var GroupChatModule = class {
12276
12285
  }
12277
12286
  subscribeToGroup(groupId) {
12278
12287
  if (!this.client) return;
12279
- const latestTimestamp = this.getLatestMessageTimestamp([groupId]);
12288
+ const sinceTimestamp = this.getLatestKnownTimestamp([groupId]);
12280
12289
  this.trackSubscription(
12281
12290
  createNip29Filter({
12282
12291
  kinds: [NIP29_KINDS.CHAT_MESSAGE, NIP29_KINDS.THREAD_ROOT, NIP29_KINDS.THREAD_REPLY],
12283
12292
  "#h": [groupId],
12284
- ...latestTimestamp ? { since: latestTimestamp } : {}
12293
+ ...sinceTimestamp ? { since: sinceTimestamp } : {}
12285
12294
  }),
12286
12295
  { onEvent: (event) => this.handleGroupEvent(event) }
12287
12296
  );
@@ -12355,7 +12364,7 @@ var GroupChatModule = class {
12355
12364
  }
12356
12365
  group.updatedAt = event.created_at * 1e3;
12357
12366
  this.groups.set(groupId, group);
12358
- this.persistGroups();
12367
+ this.schedulePersist();
12359
12368
  } else if (event.kind === NIP29_KINDS.GROUP_MEMBERS) {
12360
12369
  this.updateMembersFromEvent(groupId, event);
12361
12370
  } else if (event.kind === NIP29_KINDS.GROUP_ADMINS) {
@@ -12376,7 +12385,7 @@ var GroupChatModule = class {
12376
12385
  }
12377
12386
  }
12378
12387
  this.deps.emitEvent("groupchat:updated", {});
12379
- this.persistMessages();
12388
+ this.schedulePersist();
12380
12389
  } else if (event.kind === NIP29_KINDS.REMOVE_USER) {
12381
12390
  if (this.processedEventIds.has(event.id)) return;
12382
12391
  const eventTimestampMs = event.created_at * 1e3;
@@ -12437,7 +12446,7 @@ var GroupChatModule = class {
12437
12446
  };
12438
12447
  this.saveMemberToMemory(member);
12439
12448
  }
12440
- this.persistMembers();
12449
+ this.schedulePersist();
12441
12450
  }
12442
12451
  updateAdminsFromEvent(groupId, event) {
12443
12452
  const pTags = event.tags.filter((t) => t[0] === "p");
@@ -12457,7 +12466,7 @@ var GroupChatModule = class {
12457
12466
  });
12458
12467
  }
12459
12468
  }
12460
- this.persistMembers();
12469
+ this.schedulePersist();
12461
12470
  }
12462
12471
  // ===========================================================================
12463
12472
  // Group Membership Restoration
@@ -12468,13 +12477,11 @@ var GroupChatModule = class {
12468
12477
  if (!myPubkey) return [];
12469
12478
  const groupIdsWithMembership = /* @__PURE__ */ new Set();
12470
12479
  await this.oneshotSubscription(
12471
- new Filter3({ kinds: [NIP29_KINDS.GROUP_MEMBERS] }),
12480
+ createNip29Filter({ kinds: [NIP29_KINDS.GROUP_MEMBERS], "#p": [myPubkey] }),
12472
12481
  {
12473
12482
  onEvent: (event) => {
12474
12483
  const groupId = this.getGroupIdFromMetadataEvent(event);
12475
- if (!groupId) return;
12476
- const pTags = event.tags.filter((t) => t[0] === "p");
12477
- if (pTags.some((tag) => tag[1] === myPubkey)) {
12484
+ if (groupId) {
12478
12485
  groupIdsWithMembership.add(groupId);
12479
12486
  }
12480
12487
  },
@@ -12486,22 +12493,24 @@ var GroupChatModule = class {
12486
12493
  );
12487
12494
  if (groupIdsWithMembership.size === 0) return [];
12488
12495
  const restoredGroups = [];
12489
- for (const groupId of groupIdsWithMembership) {
12490
- if (this.groups.has(groupId)) continue;
12491
- try {
12492
- const group = await this.fetchGroupMetadataInternal(groupId);
12493
- if (group) {
12494
- this.groups.set(groupId, group);
12495
- restoredGroups.push(group);
12496
- await Promise.all([
12497
- this.fetchAndSaveMembers(groupId),
12498
- this.fetchMessages(groupId)
12499
- ]);
12496
+ await Promise.all(
12497
+ Array.from(groupIdsWithMembership).map(async (groupId) => {
12498
+ if (this.groups.has(groupId)) return;
12499
+ try {
12500
+ const group = await this.fetchGroupMetadataInternal(groupId);
12501
+ if (group) {
12502
+ this.groups.set(groupId, group);
12503
+ restoredGroups.push(group);
12504
+ await Promise.all([
12505
+ this.fetchAndSaveMembers(groupId),
12506
+ this.fetchMessages(groupId)
12507
+ ]);
12508
+ }
12509
+ } catch (error) {
12510
+ logger.warn("GroupChat", "Failed to restore group", groupId, error);
12500
12511
  }
12501
- } catch (error) {
12502
- logger.warn("GroupChat", "Failed to restore group", groupId, error);
12503
- }
12504
- }
12512
+ })
12513
+ );
12505
12514
  if (restoredGroups.length > 0) {
12506
12515
  await this.subscribeToJoinedGroups();
12507
12516
  this.deps.emitEvent("groupchat:updated", {});
@@ -12887,7 +12896,7 @@ var GroupChatModule = class {
12887
12896
  if (group && (group.unreadCount || 0) > 0) {
12888
12897
  group.unreadCount = 0;
12889
12898
  this.groups.set(groupId, group);
12890
- this.persistGroups();
12899
+ this.schedulePersist();
12891
12900
  }
12892
12901
  }
12893
12902
  // ===========================================================================
@@ -12909,7 +12918,7 @@ var GroupChatModule = class {
12909
12918
  if (eventId) {
12910
12919
  this.removeMemberFromMemory(groupId, userPubkey);
12911
12920
  this.deps.emitEvent("groupchat:updated", {});
12912
- this.persistMembers();
12921
+ this.schedulePersist();
12913
12922
  return true;
12914
12923
  }
12915
12924
  return false;
@@ -12932,7 +12941,7 @@ var GroupChatModule = class {
12932
12941
  if (eventId) {
12933
12942
  this.deleteMessageFromMemory(groupId, messageId);
12934
12943
  this.deps.emitEvent("groupchat:updated", {});
12935
- this.persistMessages();
12944
+ this.schedulePersist();
12936
12945
  return true;
12937
12946
  }
12938
12947
  return false;
@@ -13012,13 +13021,19 @@ var GroupChatModule = class {
13012
13021
  * or 0 if no messages exist. Used to set `since` on subscriptions so the relay
13013
13022
  * only sends events we don't already have.
13014
13023
  */
13015
- getLatestMessageTimestamp(groupIds) {
13024
+ getLatestKnownTimestamp(groupIds) {
13016
13025
  let latest = 0;
13017
13026
  for (const gid of groupIds) {
13018
13027
  const msgs = this.messages.get(gid);
13019
- if (!msgs) continue;
13020
- for (const m of msgs) {
13021
- const ts = Math.floor(m.timestamp / 1e3);
13028
+ if (msgs) {
13029
+ for (const m of msgs) {
13030
+ const ts = Math.floor(m.timestamp / 1e3);
13031
+ if (ts > latest) latest = ts;
13032
+ }
13033
+ }
13034
+ const group = this.groups.get(gid);
13035
+ if (group) {
13036
+ const ts = Math.floor((group.updatedAt || group.createdAt) / 1e3);
13022
13037
  if (ts > latest) latest = ts;
13023
13038
  }
13024
13039
  }
@@ -13093,7 +13108,7 @@ var GroupChatModule = class {
13093
13108
  });
13094
13109
  }
13095
13110
  }
13096
- this.persistMembers();
13111
+ this.schedulePersist();
13097
13112
  }
13098
13113
  async fetchGroupMembersInternal(groupId) {
13099
13114
  if (!this.client) return [];
@@ -13220,8 +13235,11 @@ var GroupChatModule = class {
13220
13235
  addProcessedEventId(eventId) {
13221
13236
  this.processedEventIds.add(eventId);
13222
13237
  if (this.processedEventIds.size > 1e4) {
13223
- const arr = Array.from(this.processedEventIds);
13224
- this.processedEventIds = new Set(arr.slice(arr.length - 1e4));
13238
+ let toDelete = 5e3;
13239
+ for (const id of this.processedEventIds) {
13240
+ if (toDelete-- <= 0) break;
13241
+ this.processedEventIds.delete(id);
13242
+ }
13225
13243
  }
13226
13244
  }
13227
13245
  // ===========================================================================