@unicitylabs/sphere-sdk 0.6.10-dev.4 → 0.6.10-dev.5
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/core/index.cjs +82 -41
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +82 -41
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +2 -2
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +2 -2
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +2 -2
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.js +2 -2
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +82 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +82 -41
- package/dist/index.js.map +1 -1
- package/dist/l1/index.cjs +32 -0
- package/dist/l1/index.cjs.map +1 -1
- package/dist/l1/index.js +32 -0
- package/dist/l1/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -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
|
|
3743
|
+
private getLatestKnownTimestamp;
|
|
3744
3744
|
private fetchRelayAdmins;
|
|
3745
3745
|
private doFetchRelayAdmins;
|
|
3746
3746
|
private fetchGroupMetadataInternal;
|
package/dist/index.d.ts
CHANGED
|
@@ -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
|
|
3743
|
+
private getLatestKnownTimestamp;
|
|
3744
3744
|
private fetchRelayAdmins;
|
|
3745
3745
|
private doFetchRelayAdmins;
|
|
3746
3746
|
private fetchGroupMetadataInternal;
|
package/dist/index.js
CHANGED
|
@@ -542,6 +542,33 @@ function waitForConnection() {
|
|
|
542
542
|
connectionCallbacks.push(callback);
|
|
543
543
|
});
|
|
544
544
|
}
|
|
545
|
+
function startPingTimer() {
|
|
546
|
+
stopPingTimer();
|
|
547
|
+
pingTimer = setInterval(() => {
|
|
548
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
|
549
|
+
try {
|
|
550
|
+
const id = ++requestId;
|
|
551
|
+
ws.send(JSON.stringify({ jsonrpc: "2.0", id, method: "server.ping", params: [] }));
|
|
552
|
+
pending[id] = {
|
|
553
|
+
resolve: () => {
|
|
554
|
+
},
|
|
555
|
+
reject: () => {
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
const timeoutId = setTimeout(() => {
|
|
559
|
+
delete pending[id];
|
|
560
|
+
}, 1e4);
|
|
561
|
+
pending[id].timeoutId = timeoutId;
|
|
562
|
+
} catch {
|
|
563
|
+
}
|
|
564
|
+
}, PING_INTERVAL);
|
|
565
|
+
}
|
|
566
|
+
function stopPingTimer() {
|
|
567
|
+
if (pingTimer) {
|
|
568
|
+
clearInterval(pingTimer);
|
|
569
|
+
pingTimer = null;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
545
572
|
function connect(endpoint = DEFAULT_ENDPOINT) {
|
|
546
573
|
if (isConnected) {
|
|
547
574
|
return Promise.resolve();
|
|
@@ -564,6 +591,7 @@ function connect(endpoint = DEFAULT_ENDPOINT) {
|
|
|
564
591
|
isConnected = true;
|
|
565
592
|
isConnecting = false;
|
|
566
593
|
reconnectAttempts = 0;
|
|
594
|
+
startPingTimer();
|
|
567
595
|
hasResolved = true;
|
|
568
596
|
resolve();
|
|
569
597
|
connectionCallbacks.forEach((cb) => {
|
|
@@ -575,6 +603,7 @@ function connect(endpoint = DEFAULT_ENDPOINT) {
|
|
|
575
603
|
ws.onclose = () => {
|
|
576
604
|
isConnected = false;
|
|
577
605
|
isBlockSubscribed = false;
|
|
606
|
+
stopPingTimer();
|
|
578
607
|
Object.values(pending).forEach((req) => {
|
|
579
608
|
if (req.timeoutId) clearTimeout(req.timeoutId);
|
|
580
609
|
req.reject(new Error("WebSocket connection closed"));
|
|
@@ -757,6 +786,7 @@ async function getCurrentBlockHeight() {
|
|
|
757
786
|
}
|
|
758
787
|
}
|
|
759
788
|
function disconnect() {
|
|
789
|
+
stopPingTimer();
|
|
760
790
|
if (ws) {
|
|
761
791
|
intentionalClose = true;
|
|
762
792
|
ws.close();
|
|
@@ -777,7 +807,7 @@ function disconnect() {
|
|
|
777
807
|
blockSubscribers.length = 0;
|
|
778
808
|
lastBlockHeader = null;
|
|
779
809
|
}
|
|
780
|
-
var DEFAULT_ENDPOINT, ws, isConnected, isConnecting, requestId, intentionalClose, reconnectAttempts, isBlockSubscribed, lastBlockHeader, pending, blockSubscribers, connectionCallbacks, MAX_RECONNECT_ATTEMPTS, BASE_DELAY, MAX_DELAY, RPC_TIMEOUT, CONNECTION_TIMEOUT;
|
|
810
|
+
var DEFAULT_ENDPOINT, ws, isConnected, isConnecting, requestId, intentionalClose, reconnectAttempts, isBlockSubscribed, lastBlockHeader, pingTimer, pending, blockSubscribers, connectionCallbacks, MAX_RECONNECT_ATTEMPTS, BASE_DELAY, MAX_DELAY, RPC_TIMEOUT, CONNECTION_TIMEOUT, PING_INTERVAL;
|
|
781
811
|
var init_network = __esm({
|
|
782
812
|
"l1/network.ts"() {
|
|
783
813
|
"use strict";
|
|
@@ -793,6 +823,7 @@ var init_network = __esm({
|
|
|
793
823
|
reconnectAttempts = 0;
|
|
794
824
|
isBlockSubscribed = false;
|
|
795
825
|
lastBlockHeader = null;
|
|
826
|
+
pingTimer = null;
|
|
796
827
|
pending = {};
|
|
797
828
|
blockSubscribers = [];
|
|
798
829
|
connectionCallbacks = [];
|
|
@@ -801,6 +832,7 @@ var init_network = __esm({
|
|
|
801
832
|
MAX_DELAY = 6e4;
|
|
802
833
|
RPC_TIMEOUT = 3e4;
|
|
803
834
|
CONNECTION_TIMEOUT = 3e4;
|
|
835
|
+
PING_INTERVAL = 3e4;
|
|
804
836
|
}
|
|
805
837
|
});
|
|
806
838
|
|
|
@@ -2461,9 +2493,9 @@ var NostrTransportProvider = class _NostrTransportProvider {
|
|
|
2461
2493
|
if (subId) {
|
|
2462
2494
|
this.nostrClient?.unsubscribe(subId);
|
|
2463
2495
|
}
|
|
2464
|
-
logger.warn("Nostr", `queryEvents timed out after
|
|
2496
|
+
logger.warn("Nostr", `queryEvents timed out after 15s, returning ${events.length} event(s)`, { kinds: filterObj.kinds, limit: filterObj.limit });
|
|
2465
2497
|
resolve(events);
|
|
2466
|
-
},
|
|
2498
|
+
}, 15e3);
|
|
2467
2499
|
const subId = this.nostrClient.subscribe(filter, {
|
|
2468
2500
|
onEvent: (event) => {
|
|
2469
2501
|
events.push({
|
|
@@ -12383,6 +12415,15 @@ var GroupChatModule = class {
|
|
|
12383
12415
|
}
|
|
12384
12416
|
destroy() {
|
|
12385
12417
|
this.destroyConnection();
|
|
12418
|
+
if (this.persistTimer) {
|
|
12419
|
+
clearTimeout(this.persistTimer);
|
|
12420
|
+
this.persistTimer = null;
|
|
12421
|
+
if (this.deps) {
|
|
12422
|
+
this.doPersistAll().catch(
|
|
12423
|
+
(err) => logger.debug("GroupChat", "Persist on destroy failed", err)
|
|
12424
|
+
);
|
|
12425
|
+
}
|
|
12426
|
+
}
|
|
12386
12427
|
this.groups.clear();
|
|
12387
12428
|
this.messages.clear();
|
|
12388
12429
|
this.members.clear();
|
|
@@ -12391,10 +12432,7 @@ var GroupChatModule = class {
|
|
|
12391
12432
|
this.messageHandlers.clear();
|
|
12392
12433
|
this.relayAdminPubkeys = null;
|
|
12393
12434
|
this.relayAdminFetchPromise = null;
|
|
12394
|
-
|
|
12395
|
-
clearTimeout(this.persistTimer);
|
|
12396
|
-
this.persistTimer = null;
|
|
12397
|
-
}
|
|
12435
|
+
this.persistPromise = null;
|
|
12398
12436
|
this.deps = null;
|
|
12399
12437
|
}
|
|
12400
12438
|
destroyConnection() {
|
|
@@ -12519,12 +12557,12 @@ var GroupChatModule = class {
|
|
|
12519
12557
|
if (!this.client) return;
|
|
12520
12558
|
const groupIds = Array.from(this.groups.keys());
|
|
12521
12559
|
if (groupIds.length === 0) return;
|
|
12522
|
-
const
|
|
12560
|
+
const sinceTimestamp = this.getLatestKnownTimestamp(groupIds);
|
|
12523
12561
|
this.trackSubscription(
|
|
12524
12562
|
createNip29Filter({
|
|
12525
12563
|
kinds: [NIP29_KINDS.CHAT_MESSAGE, NIP29_KINDS.THREAD_ROOT, NIP29_KINDS.THREAD_REPLY],
|
|
12526
12564
|
"#h": groupIds,
|
|
12527
|
-
...
|
|
12565
|
+
...sinceTimestamp ? { since: sinceTimestamp } : {}
|
|
12528
12566
|
}),
|
|
12529
12567
|
{ onEvent: (event) => this.handleGroupEvent(event) }
|
|
12530
12568
|
);
|
|
@@ -12545,12 +12583,12 @@ var GroupChatModule = class {
|
|
|
12545
12583
|
}
|
|
12546
12584
|
subscribeToGroup(groupId) {
|
|
12547
12585
|
if (!this.client) return;
|
|
12548
|
-
const
|
|
12586
|
+
const sinceTimestamp = this.getLatestKnownTimestamp([groupId]);
|
|
12549
12587
|
this.trackSubscription(
|
|
12550
12588
|
createNip29Filter({
|
|
12551
12589
|
kinds: [NIP29_KINDS.CHAT_MESSAGE, NIP29_KINDS.THREAD_ROOT, NIP29_KINDS.THREAD_REPLY],
|
|
12552
12590
|
"#h": [groupId],
|
|
12553
|
-
...
|
|
12591
|
+
...sinceTimestamp ? { since: sinceTimestamp } : {}
|
|
12554
12592
|
}),
|
|
12555
12593
|
{ onEvent: (event) => this.handleGroupEvent(event) }
|
|
12556
12594
|
);
|
|
@@ -12624,7 +12662,7 @@ var GroupChatModule = class {
|
|
|
12624
12662
|
}
|
|
12625
12663
|
group.updatedAt = event.created_at * 1e3;
|
|
12626
12664
|
this.groups.set(groupId, group);
|
|
12627
|
-
this.
|
|
12665
|
+
this.schedulePersist();
|
|
12628
12666
|
} else if (event.kind === NIP29_KINDS.GROUP_MEMBERS) {
|
|
12629
12667
|
this.updateMembersFromEvent(groupId, event);
|
|
12630
12668
|
} else if (event.kind === NIP29_KINDS.GROUP_ADMINS) {
|
|
@@ -12645,7 +12683,7 @@ var GroupChatModule = class {
|
|
|
12645
12683
|
}
|
|
12646
12684
|
}
|
|
12647
12685
|
this.deps.emitEvent("groupchat:updated", {});
|
|
12648
|
-
this.
|
|
12686
|
+
this.schedulePersist();
|
|
12649
12687
|
} else if (event.kind === NIP29_KINDS.REMOVE_USER) {
|
|
12650
12688
|
if (this.processedEventIds.has(event.id)) return;
|
|
12651
12689
|
const eventTimestampMs = event.created_at * 1e3;
|
|
@@ -12706,7 +12744,7 @@ var GroupChatModule = class {
|
|
|
12706
12744
|
};
|
|
12707
12745
|
this.saveMemberToMemory(member);
|
|
12708
12746
|
}
|
|
12709
|
-
this.
|
|
12747
|
+
this.schedulePersist();
|
|
12710
12748
|
}
|
|
12711
12749
|
updateAdminsFromEvent(groupId, event) {
|
|
12712
12750
|
const pTags = event.tags.filter((t) => t[0] === "p");
|
|
@@ -12726,7 +12764,7 @@ var GroupChatModule = class {
|
|
|
12726
12764
|
});
|
|
12727
12765
|
}
|
|
12728
12766
|
}
|
|
12729
|
-
this.
|
|
12767
|
+
this.schedulePersist();
|
|
12730
12768
|
}
|
|
12731
12769
|
// ===========================================================================
|
|
12732
12770
|
// Group Membership Restoration
|
|
@@ -12737,13 +12775,11 @@ var GroupChatModule = class {
|
|
|
12737
12775
|
if (!myPubkey) return [];
|
|
12738
12776
|
const groupIdsWithMembership = /* @__PURE__ */ new Set();
|
|
12739
12777
|
await this.oneshotSubscription(
|
|
12740
|
-
|
|
12778
|
+
createNip29Filter({ kinds: [NIP29_KINDS.GROUP_MEMBERS], "#p": [myPubkey] }),
|
|
12741
12779
|
{
|
|
12742
12780
|
onEvent: (event) => {
|
|
12743
12781
|
const groupId = this.getGroupIdFromMetadataEvent(event);
|
|
12744
|
-
if (
|
|
12745
|
-
const pTags = event.tags.filter((t) => t[0] === "p");
|
|
12746
|
-
if (pTags.some((tag) => tag[1] === myPubkey)) {
|
|
12782
|
+
if (groupId) {
|
|
12747
12783
|
groupIdsWithMembership.add(groupId);
|
|
12748
12784
|
}
|
|
12749
12785
|
},
|
|
@@ -12755,22 +12791,24 @@ var GroupChatModule = class {
|
|
|
12755
12791
|
);
|
|
12756
12792
|
if (groupIdsWithMembership.size === 0) return [];
|
|
12757
12793
|
const restoredGroups = [];
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
|
|
12766
|
-
|
|
12767
|
-
|
|
12768
|
-
|
|
12794
|
+
await Promise.all(
|
|
12795
|
+
Array.from(groupIdsWithMembership).map(async (groupId) => {
|
|
12796
|
+
if (this.groups.has(groupId)) return;
|
|
12797
|
+
try {
|
|
12798
|
+
const group = await this.fetchGroupMetadataInternal(groupId);
|
|
12799
|
+
if (group) {
|
|
12800
|
+
this.groups.set(groupId, group);
|
|
12801
|
+
restoredGroups.push(group);
|
|
12802
|
+
await Promise.all([
|
|
12803
|
+
this.fetchAndSaveMembers(groupId),
|
|
12804
|
+
this.fetchMessages(groupId)
|
|
12805
|
+
]);
|
|
12806
|
+
}
|
|
12807
|
+
} catch (error) {
|
|
12808
|
+
logger.warn("GroupChat", "Failed to restore group", groupId, error);
|
|
12769
12809
|
}
|
|
12770
|
-
}
|
|
12771
|
-
|
|
12772
|
-
}
|
|
12773
|
-
}
|
|
12810
|
+
})
|
|
12811
|
+
);
|
|
12774
12812
|
if (restoredGroups.length > 0) {
|
|
12775
12813
|
await this.subscribeToJoinedGroups();
|
|
12776
12814
|
this.deps.emitEvent("groupchat:updated", {});
|
|
@@ -13156,7 +13194,7 @@ var GroupChatModule = class {
|
|
|
13156
13194
|
if (group && (group.unreadCount || 0) > 0) {
|
|
13157
13195
|
group.unreadCount = 0;
|
|
13158
13196
|
this.groups.set(groupId, group);
|
|
13159
|
-
this.
|
|
13197
|
+
this.schedulePersist();
|
|
13160
13198
|
}
|
|
13161
13199
|
}
|
|
13162
13200
|
// ===========================================================================
|
|
@@ -13178,7 +13216,7 @@ var GroupChatModule = class {
|
|
|
13178
13216
|
if (eventId) {
|
|
13179
13217
|
this.removeMemberFromMemory(groupId, userPubkey);
|
|
13180
13218
|
this.deps.emitEvent("groupchat:updated", {});
|
|
13181
|
-
this.
|
|
13219
|
+
this.schedulePersist();
|
|
13182
13220
|
return true;
|
|
13183
13221
|
}
|
|
13184
13222
|
return false;
|
|
@@ -13201,7 +13239,7 @@ var GroupChatModule = class {
|
|
|
13201
13239
|
if (eventId) {
|
|
13202
13240
|
this.deleteMessageFromMemory(groupId, messageId);
|
|
13203
13241
|
this.deps.emitEvent("groupchat:updated", {});
|
|
13204
|
-
this.
|
|
13242
|
+
this.schedulePersist();
|
|
13205
13243
|
return true;
|
|
13206
13244
|
}
|
|
13207
13245
|
return false;
|
|
@@ -13281,7 +13319,7 @@ var GroupChatModule = class {
|
|
|
13281
13319
|
* or 0 if no messages exist. Used to set `since` on subscriptions so the relay
|
|
13282
13320
|
* only sends events we don't already have.
|
|
13283
13321
|
*/
|
|
13284
|
-
|
|
13322
|
+
getLatestKnownTimestamp(groupIds) {
|
|
13285
13323
|
let latest = 0;
|
|
13286
13324
|
for (const gid of groupIds) {
|
|
13287
13325
|
const msgs = this.messages.get(gid);
|
|
@@ -13362,7 +13400,7 @@ var GroupChatModule = class {
|
|
|
13362
13400
|
});
|
|
13363
13401
|
}
|
|
13364
13402
|
}
|
|
13365
|
-
this.
|
|
13403
|
+
this.schedulePersist();
|
|
13366
13404
|
}
|
|
13367
13405
|
async fetchGroupMembersInternal(groupId) {
|
|
13368
13406
|
if (!this.client) return [];
|
|
@@ -13489,8 +13527,11 @@ var GroupChatModule = class {
|
|
|
13489
13527
|
addProcessedEventId(eventId) {
|
|
13490
13528
|
this.processedEventIds.add(eventId);
|
|
13491
13529
|
if (this.processedEventIds.size > 1e4) {
|
|
13492
|
-
|
|
13493
|
-
|
|
13530
|
+
let toDelete = 5e3;
|
|
13531
|
+
for (const id of this.processedEventIds) {
|
|
13532
|
+
if (toDelete-- <= 0) break;
|
|
13533
|
+
this.processedEventIds.delete(id);
|
|
13534
|
+
}
|
|
13494
13535
|
}
|
|
13495
13536
|
}
|
|
13496
13537
|
// ===========================================================================
|