@hashgraph/sdk
Version:
3 lines (2 loc) • 4.45 kB
JavaScript
import t from"../transaction/TransactionId.js";import e from"./SubscriptionHandle.js";import r from"./TopicMessage.js";import*as i from"@hashgraph/proto";import s from"./TopicId.js";import n from"long";import o from"../Timestamp.js";import{RST_STREAM as l}from"../Executable.js";class a{constructor(t={}){this._topicId=null,null!=t.topicId&&this.setTopicId(t.topicId),this._startTime=null,null!=t.startTime&&this.setStartTime(t.startTime),this._endTime=null,null!=t.endTime&&this.setEndTime(t.endTime),this._limit=null,null!=t.limit&&this.setLimit(t.limit),this._errorHandler=(t,e)=>{console.error(`Error attempting to subscribe to topic: ${null!=this._topicId?this._topicId.toString():""}`)},null!=t.errorHandler&&(this._errorHandler=t.errorHandler),this._listener=null,this._completionHandler=()=>{console.log(`Subscription to topic ${null!=this._topicId?this._topicId.toString():""} complete`)},null!=t.completionHandler&&(this._completionHandler=t.completionHandler),this._maxAttempts=20,this._maxBackoff=8e3,this._retryHandler=t=>{if(null!=t){if(t instanceof Error)return!0;switch(t.code){case 13:return l.test(t.details.toString());case 5:case 8:case 14:case 17:return!0;default:return!1}}return!1},null!=t.retryHandler&&(this._retryHandler=t.retryHandler),this._attempt=0,this._handle=null,this.setMaxBackoff(8e3)}get topicId(){return this._topicId}setTopicId(t){return this.requireNotSubscribed(),this._topicId="string"==typeof t?s.fromString(t):t.clone(),this}get startTime(){return this._startTime}setStartTime(t){return this.requireNotSubscribed(),this._startTime=t instanceof o?t:t instanceof Date?o.fromDate(t):new o(t,0),this}get endTime(){return this._endTime}setEndTime(t){return this.requireNotSubscribed(),this._endTime=t instanceof o?t:t instanceof Date?o.fromDate(t):new o(t,0),this}get limit(){return this._limit}setLimit(t){return this.requireNotSubscribed(),this._limit=t instanceof n?t:n.fromValue(t),this}setErrorHandler(t){return this._errorHandler=t,this}setCompletionHandler(t){return this.requireNotSubscribed(),this._completionHandler=t,this}setMaxAttempts(t){return this.requireNotSubscribed(),this._maxAttempts=t,this}setMaxBackoff(t){return this.requireNotSubscribed(),this._maxBackoff=t,this}subscribe(t,r,i){return this._handle=new e,this._listener=i,null!=r&&(this._errorHandler=r),this._makeServerStreamRequest(t),this._handle}_makeServerStreamRequest(t){const e=this._buildConsensusRequest(),r=new Map,i=t._mirrorNetwork.getNextMirrorNode().getChannel().makeServerStreamRequest("ConsensusService","subscribeTopic",e,t=>this._handleMessage(t,r),e=>this._handleError(e,t),this._completionHandler);null!=this._handle&&this._handle._setCall(()=>i())}requireNotSubscribed(){if(null!=this._handle)throw new Error("Cannot change fields on an already subscribed query")}_passTopicMessage(t){try{if(null==this._listener)throw new Error("(BUG) listener is unexpectedly not set");this._listener(t)}catch(e){this._errorHandler(t,e)}}_buildConsensusRequest(){return i.com.hedera.mirror.api.proto.ConsensusTopicQuery.encode({topicID:this._topicId?._toProtobuf()??null,consensusStartTime:this._startTime?._toProtobuf()??null,consensusEndTime:this._endTime?._toProtobuf()??null,limit:this._limit}).finish()}_handleMessage(t,e){const s=i.com.hedera.mirror.api.proto.ConsensusTopicResponse.decode(t);this._limit?.gt(0)&&(this._limit=this._limit.sub(1)),this._startTime=o._fromProtobuf(s.consensusTimestamp).plusNanos(1),null==s.chunkInfo||null!=s.chunkInfo&&1===s.chunkInfo.total?this._passTopicMessage(r._ofSingle(s)):this._handleChunkedMessage(s,e)}_handleChunkedMessage(e,i){const s=e.chunkInfo,n=s.initialTransactionID,o=s.total,l=t._fromProtobuf(n).toString();let a=[];const h=i.get(l);if(null==h?i.set(l,a):a=h,a.push(e),a.length===o){const t=r._ofMany(a);i.delete(l),this._passTopicMessage(t)}}_handleError(t,e){const r=t instanceof Error?t.message:t.details;this._handle?._unsubscribed||(this.shouldRetry(t)?this._scheduleRetry(e,r):this._errorHandler(null,new Error(r)))}shouldRetry(t){return this._attempt<this._maxAttempts&&this._retryHandler(t)}_scheduleRetry(t,e){const r=Math.min(250*2**this._attempt,this._maxBackoff);console.warn(`Error subscribing to topic ${this._topicId?.toString()??"UNKNOWN"} during attempt ${this._attempt}. Waiting ${r} ms before next attempt: ${e}`),this._attempt+=1,setTimeout(()=>this._makeServerStreamRequest(t),r)}}export{a as default};
//# sourceMappingURL=TopicMessageQuery.js.map