@@ -4,12 +4,12 @@ import {
44 IDecoder ,
55 IFilter ,
66 IStore ,
7- NetworkConfig
7+ NetworkConfig ,
8+ SubscribeListener
89} from "@waku/interfaces" ;
910import { createRoutingInfo } from "@waku/utils" ;
1011
1112import { MessageStore } from "./message_store.js" ;
12- import { IAckManager } from "./utils.js" ;
1313
1414type AckManagerConstructorParams = {
1515 messageStore : MessageStore ;
@@ -18,6 +18,14 @@ type AckManagerConstructorParams = {
1818 networkConfig : NetworkConfig ;
1919} ;
2020
21+ export interface IAckManager {
22+ start ( ) : void ;
23+ stop ( ) : void ;
24+ observe ( contentTopic : string ) : Promise < boolean > ;
25+ subscribe ( contentTopic : string , cb : SubscribeListener ) : Promise < boolean > ;
26+ unsubscribe ( contentTopic : string ) : Promise < void > ;
27+ }
28+
2129export class AckManager implements IAckManager {
2230 private readonly messageStore : MessageStore ;
2331 private readonly filterAckManager : FilterAckManager ;
@@ -49,7 +57,7 @@ export class AckManager implements IAckManager {
4957 this . subscribedContentTopics . clear ( ) ;
5058 }
5159
52- public async subscribe ( contentTopic : string ) : Promise < boolean > {
60+ public async observe ( contentTopic : string ) : Promise < boolean > {
5361 if ( this . subscribedContentTopics . has ( contentTopic ) ) {
5462 return true ;
5563 }
@@ -69,6 +77,24 @@ export class AckManager implements IAckManager {
6977 ] )
7078 ) . some ( ( success ) => success ) ;
7179 }
80+
81+ public async subscribe (
82+ contentTopic : string ,
83+ cb : SubscribeListener
84+ ) : Promise < boolean > {
85+ const decoder = createDecoder (
86+ contentTopic ,
87+ createRoutingInfo ( this . networkConfig , {
88+ contentTopic
89+ } )
90+ ) ;
91+
92+ return this . filterAckManager . subscribe ( decoder , cb ) ;
93+ }
94+
95+ public async unsubscribe ( contentTopic : string ) : Promise < void > {
96+ return this . filterAckManager . unsubscribe ( contentTopic ) ;
97+ }
7298}
7399
74100class FilterAckManager {
@@ -77,7 +103,9 @@ class FilterAckManager {
77103 public constructor (
78104 private messageStore : MessageStore ,
79105 private filter : IFilter
80- ) { }
106+ ) {
107+ this . onMessage = this . onMessage . bind ( this ) ;
108+ }
81109
82110 public start ( ) : void {
83111 return ;
@@ -91,18 +119,48 @@ class FilterAckManager {
91119 this . decoders . clear ( ) ;
92120 }
93121
94- public async subscribe ( decoder : IDecoder < IDecodedMessage > ) : Promise < boolean > {
95- const success = await this . filter . subscribe (
96- decoder ,
97- this . onMessage . bind ( this )
98- ) ;
122+ public async subscribe (
123+ decoder : IDecoder < IDecodedMessage > ,
124+ cb ?: SubscribeListener
125+ ) : Promise < boolean > {
126+ const success = await this . filter . subscribe ( decoder , ( message ) => {
127+ try {
128+ cb ?.( message ) ;
129+ } catch ( error ) {
130+ // ignore
131+ }
132+
133+ try {
134+ this . onMessage ( message ) ;
135+ } catch ( error ) {
136+ // ignore
137+ }
138+ } ) ;
139+
99140 if ( success ) {
100141 this . decoders . add ( decoder ) ;
101142 }
143+
102144 return success ;
103145 }
104146
105- private async onMessage ( message : IDecodedMessage ) : Promise < void > {
147+ public async unsubscribe ( contentTopic : string ) : Promise < void > {
148+ const decoders = Array . from ( this . decoders ) . filter (
149+ ( decoder ) => decoder . contentTopic === contentTopic
150+ ) ;
151+
152+ const promises = decoders . map ( ( decoder ) =>
153+ this . filter . unsubscribe ( decoder )
154+ ) ;
155+
156+ await Promise . all ( promises ) ;
157+
158+ for ( const decoder of decoders ) {
159+ this . decoders . delete ( decoder ) ;
160+ }
161+ }
162+
163+ private onMessage ( message : IDecodedMessage ) : void {
106164 if ( ! this . messageStore . has ( message . hashStr ) ) {
107165 this . messageStore . add ( message , { filterAck : true } ) ;
108166 }
0 commit comments