@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.
@@ -12188,8 +12188,20 @@ var GroupChatModule = class {
12188
12188
  }
12189
12189
  }
12190
12190
  }
12191
- destroy() {
12191
+ async destroy() {
12192
12192
  this.destroyConnection();
12193
+ if (this.persistTimer) {
12194
+ clearTimeout(this.persistTimer);
12195
+ this.persistTimer = null;
12196
+ }
12197
+ if (this.deps) {
12198
+ try {
12199
+ if (this.persistPromise) await this.persistPromise;
12200
+ await this.doPersistAll();
12201
+ } catch (err) {
12202
+ logger.debug("GroupChat", "Persist on destroy failed", err);
12203
+ }
12204
+ }
12193
12205
  this.groups.clear();
12194
12206
  this.messages.clear();
12195
12207
  this.members.clear();
@@ -12198,10 +12210,7 @@ var GroupChatModule = class {
12198
12210
  this.messageHandlers.clear();
12199
12211
  this.relayAdminPubkeys = null;
12200
12212
  this.relayAdminFetchPromise = null;
12201
- if (this.persistTimer) {
12202
- clearTimeout(this.persistTimer);
12203
- this.persistTimer = null;
12204
- }
12213
+ this.persistPromise = null;
12205
12214
  this.deps = null;
12206
12215
  }
12207
12216
  destroyConnection() {
@@ -12326,12 +12335,12 @@ var GroupChatModule = class {
12326
12335
  if (!this.client) return;
12327
12336
  const groupIds = Array.from(this.groups.keys());
12328
12337
  if (groupIds.length === 0) return;
12329
- const latestTimestamp = this.getLatestMessageTimestamp(groupIds);
12338
+ const sinceTimestamp = this.getLatestKnownTimestamp(groupIds);
12330
12339
  this.trackSubscription(
12331
12340
  createNip29Filter({
12332
12341
  kinds: [NIP29_KINDS.CHAT_MESSAGE, NIP29_KINDS.THREAD_ROOT, NIP29_KINDS.THREAD_REPLY],
12333
12342
  "#h": groupIds,
12334
- ...latestTimestamp ? { since: latestTimestamp } : {}
12343
+ ...sinceTimestamp ? { since: sinceTimestamp } : {}
12335
12344
  }),
12336
12345
  { onEvent: (event) => this.handleGroupEvent(event) }
12337
12346
  );
@@ -12352,12 +12361,12 @@ var GroupChatModule = class {
12352
12361
  }
12353
12362
  subscribeToGroup(groupId) {
12354
12363
  if (!this.client) return;
12355
- const latestTimestamp = this.getLatestMessageTimestamp([groupId]);
12364
+ const sinceTimestamp = this.getLatestKnownTimestamp([groupId]);
12356
12365
  this.trackSubscription(
12357
12366
  createNip29Filter({
12358
12367
  kinds: [NIP29_KINDS.CHAT_MESSAGE, NIP29_KINDS.THREAD_ROOT, NIP29_KINDS.THREAD_REPLY],
12359
12368
  "#h": [groupId],
12360
- ...latestTimestamp ? { since: latestTimestamp } : {}
12369
+ ...sinceTimestamp ? { since: sinceTimestamp } : {}
12361
12370
  }),
12362
12371
  { onEvent: (event) => this.handleGroupEvent(event) }
12363
12372
  );
@@ -12431,7 +12440,7 @@ var GroupChatModule = class {
12431
12440
  }
12432
12441
  group.updatedAt = event.created_at * 1e3;
12433
12442
  this.groups.set(groupId, group);
12434
- this.persistGroups();
12443
+ this.schedulePersist();
12435
12444
  } else if (event.kind === NIP29_KINDS.GROUP_MEMBERS) {
12436
12445
  this.updateMembersFromEvent(groupId, event);
12437
12446
  } else if (event.kind === NIP29_KINDS.GROUP_ADMINS) {
@@ -12452,7 +12461,7 @@ var GroupChatModule = class {
12452
12461
  }
12453
12462
  }
12454
12463
  this.deps.emitEvent("groupchat:updated", {});
12455
- this.persistMessages();
12464
+ this.schedulePersist();
12456
12465
  } else if (event.kind === NIP29_KINDS.REMOVE_USER) {
12457
12466
  if (this.processedEventIds.has(event.id)) return;
12458
12467
  const eventTimestampMs = event.created_at * 1e3;
@@ -12513,7 +12522,7 @@ var GroupChatModule = class {
12513
12522
  };
12514
12523
  this.saveMemberToMemory(member);
12515
12524
  }
12516
- this.persistMembers();
12525
+ this.schedulePersist();
12517
12526
  }
12518
12527
  updateAdminsFromEvent(groupId, event) {
12519
12528
  const pTags = event.tags.filter((t) => t[0] === "p");
@@ -12533,7 +12542,7 @@ var GroupChatModule = class {
12533
12542
  });
12534
12543
  }
12535
12544
  }
12536
- this.persistMembers();
12545
+ this.schedulePersist();
12537
12546
  }
12538
12547
  // ===========================================================================
12539
12548
  // Group Membership Restoration
@@ -12544,13 +12553,11 @@ var GroupChatModule = class {
12544
12553
  if (!myPubkey) return [];
12545
12554
  const groupIdsWithMembership = /* @__PURE__ */ new Set();
12546
12555
  await this.oneshotSubscription(
12547
- new import_nostr_js_sdk4.Filter({ kinds: [NIP29_KINDS.GROUP_MEMBERS] }),
12556
+ createNip29Filter({ kinds: [NIP29_KINDS.GROUP_MEMBERS], "#p": [myPubkey] }),
12548
12557
  {
12549
12558
  onEvent: (event) => {
12550
12559
  const groupId = this.getGroupIdFromMetadataEvent(event);
12551
- if (!groupId) return;
12552
- const pTags = event.tags.filter((t) => t[0] === "p");
12553
- if (pTags.some((tag) => tag[1] === myPubkey)) {
12560
+ if (groupId) {
12554
12561
  groupIdsWithMembership.add(groupId);
12555
12562
  }
12556
12563
  },
@@ -12562,22 +12569,24 @@ var GroupChatModule = class {
12562
12569
  );
12563
12570
  if (groupIdsWithMembership.size === 0) return [];
12564
12571
  const restoredGroups = [];
12565
- for (const groupId of groupIdsWithMembership) {
12566
- if (this.groups.has(groupId)) continue;
12567
- try {
12568
- const group = await this.fetchGroupMetadataInternal(groupId);
12569
- if (group) {
12570
- this.groups.set(groupId, group);
12571
- restoredGroups.push(group);
12572
- await Promise.all([
12573
- this.fetchAndSaveMembers(groupId),
12574
- this.fetchMessages(groupId)
12575
- ]);
12572
+ await Promise.all(
12573
+ Array.from(groupIdsWithMembership).map(async (groupId) => {
12574
+ if (this.groups.has(groupId)) return;
12575
+ try {
12576
+ const group = await this.fetchGroupMetadataInternal(groupId);
12577
+ if (group) {
12578
+ this.groups.set(groupId, group);
12579
+ restoredGroups.push(group);
12580
+ await Promise.all([
12581
+ this.fetchAndSaveMembers(groupId),
12582
+ this.fetchMessages(groupId)
12583
+ ]);
12584
+ }
12585
+ } catch (error) {
12586
+ logger.warn("GroupChat", "Failed to restore group", groupId, error);
12576
12587
  }
12577
- } catch (error) {
12578
- logger.warn("GroupChat", "Failed to restore group", groupId, error);
12579
- }
12580
- }
12588
+ })
12589
+ );
12581
12590
  if (restoredGroups.length > 0) {
12582
12591
  await this.subscribeToJoinedGroups();
12583
12592
  this.deps.emitEvent("groupchat:updated", {});
@@ -12963,7 +12972,7 @@ var GroupChatModule = class {
12963
12972
  if (group && (group.unreadCount || 0) > 0) {
12964
12973
  group.unreadCount = 0;
12965
12974
  this.groups.set(groupId, group);
12966
- this.persistGroups();
12975
+ this.schedulePersist();
12967
12976
  }
12968
12977
  }
12969
12978
  // ===========================================================================
@@ -12985,7 +12994,7 @@ var GroupChatModule = class {
12985
12994
  if (eventId) {
12986
12995
  this.removeMemberFromMemory(groupId, userPubkey);
12987
12996
  this.deps.emitEvent("groupchat:updated", {});
12988
- this.persistMembers();
12997
+ this.schedulePersist();
12989
12998
  return true;
12990
12999
  }
12991
13000
  return false;
@@ -13008,7 +13017,7 @@ var GroupChatModule = class {
13008
13017
  if (eventId) {
13009
13018
  this.deleteMessageFromMemory(groupId, messageId);
13010
13019
  this.deps.emitEvent("groupchat:updated", {});
13011
- this.persistMessages();
13020
+ this.schedulePersist();
13012
13021
  return true;
13013
13022
  }
13014
13023
  return false;
@@ -13088,13 +13097,19 @@ var GroupChatModule = class {
13088
13097
  * or 0 if no messages exist. Used to set `since` on subscriptions so the relay
13089
13098
  * only sends events we don't already have.
13090
13099
  */
13091
- getLatestMessageTimestamp(groupIds) {
13100
+ getLatestKnownTimestamp(groupIds) {
13092
13101
  let latest = 0;
13093
13102
  for (const gid of groupIds) {
13094
13103
  const msgs = this.messages.get(gid);
13095
- if (!msgs) continue;
13096
- for (const m of msgs) {
13097
- const ts = Math.floor(m.timestamp / 1e3);
13104
+ if (msgs) {
13105
+ for (const m of msgs) {
13106
+ const ts = Math.floor(m.timestamp / 1e3);
13107
+ if (ts > latest) latest = ts;
13108
+ }
13109
+ }
13110
+ const group = this.groups.get(gid);
13111
+ if (group) {
13112
+ const ts = Math.floor((group.updatedAt || group.createdAt) / 1e3);
13098
13113
  if (ts > latest) latest = ts;
13099
13114
  }
13100
13115
  }
@@ -13169,7 +13184,7 @@ var GroupChatModule = class {
13169
13184
  });
13170
13185
  }
13171
13186
  }
13172
- this.persistMembers();
13187
+ this.schedulePersist();
13173
13188
  }
13174
13189
  async fetchGroupMembersInternal(groupId) {
13175
13190
  if (!this.client) return [];
@@ -13296,8 +13311,11 @@ var GroupChatModule = class {
13296
13311
  addProcessedEventId(eventId) {
13297
13312
  this.processedEventIds.add(eventId);
13298
13313
  if (this.processedEventIds.size > 1e4) {
13299
- const arr = Array.from(this.processedEventIds);
13300
- this.processedEventIds = new Set(arr.slice(arr.length - 1e4));
13314
+ let toDelete = 5e3;
13315
+ for (const id of this.processedEventIds) {
13316
+ if (toDelete-- <= 0) break;
13317
+ this.processedEventIds.delete(id);
13318
+ }
13301
13319
  }
13302
13320
  }
13303
13321
  // ===========================================================================