@peerbit/pubsub 5.1.0 → 5.1.1
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/src/fanout-channel.d.ts +1 -0
- package/dist/src/fanout-channel.d.ts.map +1 -1
- package/dist/src/fanout-channel.js +3 -0
- package/dist/src/fanout-channel.js.map +1 -1
- package/dist/src/fanout-tree.d.ts +1 -0
- package/dist/src/fanout-tree.d.ts.map +1 -1
- package/dist/src/fanout-tree.js +12 -2
- package/dist/src/fanout-tree.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +76 -15
- package/dist/src/index.js.map +1 -1
- package/package.json +2 -2
- package/src/fanout-channel.ts +4 -0
- package/src/fanout-tree.ts +16 -2
- package/src/index.ts +96 -16
package/src/index.ts
CHANGED
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
type DirectStreamComponents,
|
|
29
29
|
type DirectStreamOptions,
|
|
30
30
|
type PeerStreams,
|
|
31
|
-
dontThrowIfDeliveryError,
|
|
32
31
|
} from "@peerbit/stream";
|
|
33
32
|
import {
|
|
34
33
|
AcknowledgeAnyWhere,
|
|
@@ -687,9 +686,7 @@ export class TopicControlPlane
|
|
|
687
686
|
priority: 1,
|
|
688
687
|
skipRecipientValidation: true,
|
|
689
688
|
} as any);
|
|
690
|
-
await this.
|
|
691
|
-
dontThrowIfDeliveryError,
|
|
692
|
-
);
|
|
689
|
+
await this.publishMessageMaybe(this.publicKey, embedded, streams);
|
|
693
690
|
}
|
|
694
691
|
|
|
695
692
|
private mergeAutoTopicRootCandidatesFromPeer(candidates: string[]): boolean {
|
|
@@ -1559,7 +1556,7 @@ export class TopicControlPlane
|
|
|
1559
1556
|
await this.ensureFanoutChannel(shardTopic, { ephemeral: true });
|
|
1560
1557
|
const st = this.fanoutChannels.get(shardTopic);
|
|
1561
1558
|
if (st) {
|
|
1562
|
-
void st.channel.
|
|
1559
|
+
void st.channel.publishMaybe(toUint8Array(embedded.bytes()));
|
|
1563
1560
|
this.touchFanoutChannel(shardTopic);
|
|
1564
1561
|
}
|
|
1565
1562
|
} catch {
|
|
@@ -1589,7 +1586,7 @@ export class TopicControlPlane
|
|
|
1589
1586
|
await this.ensureFanoutChannel(shardTopic, { ephemeral: true });
|
|
1590
1587
|
const st = this.fanoutChannels.get(shardTopic);
|
|
1591
1588
|
if (st) {
|
|
1592
|
-
void st.channel.
|
|
1589
|
+
void st.channel.publishMaybe(toUint8Array(embedded.bytes()));
|
|
1593
1590
|
this.touchFanoutChannel(shardTopic);
|
|
1594
1591
|
}
|
|
1595
1592
|
} catch {
|
|
@@ -1672,10 +1669,16 @@ export class TopicControlPlane
|
|
|
1672
1669
|
|
|
1673
1670
|
await Promise.all(
|
|
1674
1671
|
[...byShard.entries()].map(async ([shardTopic, userTopics]) => {
|
|
1672
|
+
const msg = new GetSubscribers({ topics: userTopics });
|
|
1673
|
+
const directPeer = to ? this.peers.get(to.hashcode()) : undefined;
|
|
1674
|
+
if (directPeer) {
|
|
1675
|
+
await this.sendDirectControlMessage(directPeer, msg);
|
|
1676
|
+
return;
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1675
1679
|
const persistent = (this.shardRefCounts.get(shardTopic) ?? 0) > 0;
|
|
1676
1680
|
await this.ensureFanoutChannel(shardTopic, { ephemeral: !persistent });
|
|
1677
1681
|
|
|
1678
|
-
const msg = new GetSubscribers({ topics: userTopics });
|
|
1679
1682
|
const embedded = await this.createMessage(toUint8Array(msg.bytes()), {
|
|
1680
1683
|
mode: new AnyWhere(),
|
|
1681
1684
|
priority: 1,
|
|
@@ -1693,7 +1696,7 @@ export class TopicControlPlane
|
|
|
1693
1696
|
timeoutMs: 5_000,
|
|
1694
1697
|
});
|
|
1695
1698
|
} catch {
|
|
1696
|
-
await st.channel.
|
|
1699
|
+
await st.channel.publishMaybe(payload);
|
|
1697
1700
|
}
|
|
1698
1701
|
} else {
|
|
1699
1702
|
await st.channel.publish(payload);
|
|
@@ -2048,19 +2051,16 @@ export class TopicControlPlane
|
|
|
2048
2051
|
} catch {
|
|
2049
2052
|
// ignore and fall back
|
|
2050
2053
|
}
|
|
2051
|
-
|
|
2052
|
-
await st.channel.publish(payload);
|
|
2053
|
-
} catch {
|
|
2054
|
-
// ignore
|
|
2055
|
-
}
|
|
2054
|
+
await st.channel.publishMaybe(payload);
|
|
2056
2055
|
}
|
|
2057
2056
|
|
|
2058
2057
|
private async processDirectPubSubMessage(input: {
|
|
2059
2058
|
pubsubMessage: PubSubMessage;
|
|
2060
2059
|
message: DataMessage;
|
|
2060
|
+
from: PublicSignKey;
|
|
2061
2061
|
stream: PeerStreams;
|
|
2062
2062
|
}): Promise<void> {
|
|
2063
|
-
const { pubsubMessage, message, stream } = input;
|
|
2063
|
+
const { pubsubMessage, message, from, stream } = input;
|
|
2064
2064
|
|
|
2065
2065
|
if (pubsubMessage instanceof TopicRootCandidates) {
|
|
2066
2066
|
// Used only to converge deterministic shard-root candidates in auto mode.
|
|
@@ -2088,6 +2088,83 @@ export class TopicControlPlane
|
|
|
2088
2088
|
return;
|
|
2089
2089
|
}
|
|
2090
2090
|
|
|
2091
|
+
if (pubsubMessage instanceof Subscribe) {
|
|
2092
|
+
const sender = from;
|
|
2093
|
+
const senderKey = sender.hashcode();
|
|
2094
|
+
const relevantTopics = pubsubMessage.topics.filter((t) =>
|
|
2095
|
+
this.isTrackedTopic(t),
|
|
2096
|
+
);
|
|
2097
|
+
|
|
2098
|
+
if (
|
|
2099
|
+
relevantTopics.length > 0 &&
|
|
2100
|
+
this.subscriptionMessageIsLatest(message, pubsubMessage, relevantTopics)
|
|
2101
|
+
) {
|
|
2102
|
+
const changed: string[] = [];
|
|
2103
|
+
for (const topic of relevantTopics) {
|
|
2104
|
+
const peers = this.topics.get(topic);
|
|
2105
|
+
if (!peers) continue;
|
|
2106
|
+
this.initializePeer(sender);
|
|
2107
|
+
|
|
2108
|
+
const existing = peers.get(senderKey);
|
|
2109
|
+
if (!existing || existing.session < message.header.session) {
|
|
2110
|
+
peers.delete(senderKey);
|
|
2111
|
+
peers.set(
|
|
2112
|
+
senderKey,
|
|
2113
|
+
new SubscriptionData({
|
|
2114
|
+
session: message.header.session,
|
|
2115
|
+
timestamp: message.header.timestamp,
|
|
2116
|
+
publicKey: sender,
|
|
2117
|
+
}),
|
|
2118
|
+
);
|
|
2119
|
+
changed.push(topic);
|
|
2120
|
+
} else {
|
|
2121
|
+
peers.delete(senderKey);
|
|
2122
|
+
peers.set(senderKey, existing);
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
if (!existing) {
|
|
2126
|
+
this.peerToTopic.get(senderKey)!.add(topic);
|
|
2127
|
+
}
|
|
2128
|
+
this.pruneTopicSubscribers(topic);
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
if (changed.length > 0) {
|
|
2132
|
+
this.dispatchEvent(
|
|
2133
|
+
new CustomEvent<SubscriptionEvent>("subscribe", {
|
|
2134
|
+
detail: new SubscriptionEvent(sender, changed),
|
|
2135
|
+
}),
|
|
2136
|
+
);
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
if (pubsubMessage.requestSubscribers) {
|
|
2141
|
+
const overlap = this.getSubscriptionOverlap(pubsubMessage.topics);
|
|
2142
|
+
if (overlap.length > 0) {
|
|
2143
|
+
await this.sendDirectControlMessage(
|
|
2144
|
+
stream,
|
|
2145
|
+
new Subscribe({
|
|
2146
|
+
topics: overlap,
|
|
2147
|
+
requestSubscribers: false,
|
|
2148
|
+
}),
|
|
2149
|
+
);
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
return;
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
if (pubsubMessage instanceof GetSubscribers) {
|
|
2156
|
+
const overlap = this.getSubscriptionOverlap(pubsubMessage.topics);
|
|
2157
|
+
if (overlap.length === 0) return;
|
|
2158
|
+
await this.sendDirectControlMessage(
|
|
2159
|
+
stream,
|
|
2160
|
+
new Subscribe({
|
|
2161
|
+
topics: overlap,
|
|
2162
|
+
requestSubscribers: false,
|
|
2163
|
+
}),
|
|
2164
|
+
);
|
|
2165
|
+
return;
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2091
2168
|
if (pubsubMessage instanceof PubSubData) {
|
|
2092
2169
|
this.dispatchEvent(
|
|
2093
2170
|
new CustomEvent("data", {
|
|
@@ -2340,12 +2417,14 @@ export class TopicControlPlane
|
|
|
2340
2417
|
return super.onDataMessage(from, stream, message, seenBefore);
|
|
2341
2418
|
}
|
|
2342
2419
|
|
|
2343
|
-
// DirectStream
|
|
2344
|
-
//
|
|
2420
|
+
// DirectStream supports targeted pubsub data plus targeted subscriber snapshot
|
|
2421
|
+
// traffic used by Program.waitFor() when a peer is already connected directly.
|
|
2345
2422
|
if (
|
|
2346
2423
|
!(pubsubMessage instanceof PubSubData) &&
|
|
2347
2424
|
!(pubsubMessage instanceof TopicRootCandidates) &&
|
|
2348
2425
|
!(pubsubMessage instanceof TopicRootQuery) &&
|
|
2426
|
+
!(pubsubMessage instanceof GetSubscribers) &&
|
|
2427
|
+
!(pubsubMessage instanceof Subscribe) &&
|
|
2349
2428
|
!(pubsubMessage instanceof TopicRootQueryResponse)
|
|
2350
2429
|
) {
|
|
2351
2430
|
return true;
|
|
@@ -2376,6 +2455,7 @@ export class TopicControlPlane
|
|
|
2376
2455
|
await this.processDirectPubSubMessage({
|
|
2377
2456
|
pubsubMessage,
|
|
2378
2457
|
message,
|
|
2458
|
+
from,
|
|
2379
2459
|
stream,
|
|
2380
2460
|
});
|
|
2381
2461
|
}
|