@solarpunkltd/swarm-chat-js 6.0.6 → 6.0.8

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/index.esm.js CHANGED
@@ -55450,16 +55450,10 @@ var srcExports = src.exports, protobufjs = srcExports;
55450
55450
  const protobuf = /* @__PURE__ */ getDefaultExportFromCjs$1(protobufjs), protoSchema = `
55451
55451
  syntax = "proto3";
55452
55452
 
55453
- enum MessageType {
55454
- TEXT = 0;
55455
- THREAD = 1;
55456
- REACTION = 2;
55457
- }
55458
-
55459
55453
  message MessageData {
55460
55454
  string id = 1;
55461
55455
  optional string targetMessageId = 2;
55462
- MessageType type = 3;
55456
+ string type = 3;
55463
55457
  string message = 4;
55464
55458
  string username = 5;
55465
55459
  string address = 6;
@@ -55488,37 +55482,35 @@ async function initializeProtobuf() {
55488
55482
  }
55489
55483
  async function decodeMessagePayload(y) {
55490
55484
  if (await initializeProtobuf(), !messagePayloadType) throw new Error("MessagePayload type not initialized");
55491
- const u = { 0: "text", 1: "thread", 2: "reaction" };
55492
55485
  try {
55493
- const h = messagePayloadType.decode(y), b = messagePayloadType.toObject(h, {
55486
+ const u = messagePayloadType.decode(y), h = messagePayloadType.toObject(u, {
55494
55487
  longs: String,
55495
55488
  enums: String,
55496
55489
  defaults: !0
55497
55490
  });
55498
- if (!b.message)
55491
+ if (!h.message)
55499
55492
  throw new Error("Decoded object has no message field");
55500
- let v = b.message.additionalProps;
55501
- if (v && typeof v == "string")
55493
+ let b = h.message.additionalProps;
55494
+ if (b && typeof b == "string")
55502
55495
  try {
55503
- v = JSON.parse(v);
55496
+ b = JSON.parse(b);
55504
55497
  } catch {
55505
- console.warn("Failed to parse additionalProps as JSON:", v);
55498
+ console.warn("Failed to parse additionalProps as JSON:", b);
55506
55499
  }
55507
- const w = {
55508
- ...b.message,
55509
- type: u[b.message.type] ?? "text",
55510
- timestamp: Number(b.message.timestamp),
55511
- additionalProps: v
55512
- }, _ = (b.messageStateRefs || []).map((E) => ({
55513
- ...E,
55514
- timestamp: Number(E.timestamp)
55500
+ const v = {
55501
+ ...h.message,
55502
+ timestamp: Number(h.message.timestamp),
55503
+ additionalProps: b
55504
+ }, w = (h.messageStateRefs || []).map((_) => ({
55505
+ ..._,
55506
+ timestamp: Number(_.timestamp)
55515
55507
  }));
55516
55508
  return {
55517
- message: w,
55518
- messageStateRefs: _
55509
+ message: v,
55510
+ messageStateRefs: w
55519
55511
  };
55520
- } catch (h) {
55521
- throw errorHandler.handleError(h, "ProtoMessage.decodeMessagePayload"), h;
55512
+ } catch (u) {
55513
+ throw errorHandler.handleError(u, "ProtoMessage.decodeMessagePayload"), u;
55522
55514
  }
55523
55515
  }
55524
55516
  class Waku {
@@ -55547,11 +55539,11 @@ class Waku {
55547
55539
  }
55548
55540
  createWakuDecoder(u) {
55549
55541
  if (!(u != null && u.trim())) throw new Error("Topic name must be a non-empty string");
55550
- const b = createRoutingInfo({
55542
+ const h = {
55551
55543
  clusterId: WAKU_CLUSTER_ID,
55552
55544
  numShardsInCluster: 8
55553
- }, { contentTopic: u });
55554
- return createDecoder(u, b);
55545
+ }, b = `/solarpunk-msrs/1/${u}/proto`, v = createRoutingInfo(h, { contentTopic: b });
55546
+ return createDecoder(b, v);
55555
55547
  }
55556
55548
  async subscribeToTopic() {
55557
55549
  var u;
@@ -55826,14 +55818,13 @@ class SwarmChat {
55826
55818
  async startWakuMessageFetch(u) {
55827
55819
  this.logger.info("Waku is enabled"), u && (this.isExternalWakuNode = !0, this.logger.info("Using external Waku node instance"));
55828
55820
  const h = this.swarmSettings.chatTopic;
55829
- if (this.waku = new Waku(
55821
+ this.waku = new Waku(
55830
55822
  h,
55831
- (v) => {
55832
- this.emitter.emit(EVENTS.MESSAGE_RECEIVED, v);
55823
+ (b) => {
55824
+ this.emitter.emit(EVENTS.MESSAGE_RECEIVED, b);
55833
55825
  },
55834
55826
  u
55835
- ), !await this.waku.isReady())
55836
- throw new Error("Waku node is not reachable");
55827
+ );
55837
55828
  }
55838
55829
  getEmitter() {
55839
55830
  return this.emitter;
package/dist/index.js CHANGED
@@ -85,16 +85,10 @@ function print() { __p += __j.call(arguments, '') }
85
85
  `&&++v,++h===b)throw x("comment");Se=ve,ve=C(h)}while(Se!=="*"||ve!=="/");++h,Ie&&(O(Pe,h-2,Ee),Ee=!0),de=!0}else return"/"}}while(de);var De=h;delimRe.lastIndex=0;var be=delimRe.test(C(De++));if(!be)for(;De<b&&!delimRe.test(C(De));)++De;var B=y.substring(h,h=De);return(B==='"'||B==="'")&&(S=B),B}function X(de){E.push(de)}function ie(){if(!E.length){var de=te();if(de===null)return null;X(de)}return E[0]}function ee(de,Se){var ve=ie(),Pe=ve===de;if(Pe)return te(),!0;if(!Se)throw x("token '"+ve+"', '"+de+"' expected");return!1}function ae(de){var Se=null,ve;return de===void 0?(ve=_[v-1],delete _[v-1],ve&&(u||ve.type==="*"||ve.lineEmpty)&&(Se=ve.leading?ve.text:null)):(w<de&&ie(),ve=_[de],delete _[de],ve&&!ve.lineEmpty&&(u||ve.type==="/")&&(Se=ve.leading?null:ve.text)),Se}return Object.defineProperty({next:te,peek:ie,push:X,skip:ee,cmnt:ae},"line",{get:function(){return v}})}var parse_1=parse;parse.filename=null;parse.defaults={keepCase:!1};var tokenize=tokenize_1,Root=requireRoot(),Type=requireType(),Field=requireField(),MapField=requireMapfield(),OneOf=requireOneof(),Enum=require_enum(),Service=requireService(),Method=requireMethod(),ReflectionObject=requireObject(),types=requireTypes(),util=requireUtil(),base10Re=/^[1-9][0-9]*$/,base10NegRe=/^-?[1-9][0-9]*$/,base16Re=/^0[x][0-9a-fA-F]+$/,base16NegRe=/^-?0[x][0-9a-fA-F]+$/,base8Re=/^0[0-7]+$/,base8NegRe=/^-?0[0-7]+$/,numberRe=/^(?![eE])[0-9]*(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?$/,nameRe=/^[a-zA-Z_][a-zA-Z_0-9]*$/,typeRefRe=/^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/;function parse(y,u,h){u instanceof Root||(h=u,u=new Root),h||(h=parse.defaults);var b=h.preferTrailingComment||!1,v=tokenize(y,h.alternateCommentMode||!1),w=v.next,_=v.push,E=v.peek,S=v.skip,x=v.cmnt,T=!0,C,O,D,U="proto2",te=u,X=[],ie={},ee=h.keepCase?function(ce){return ce}:util.camelCase;function ae(){X.forEach(ce=>{ce._edition=U,Object.keys(ie).forEach(_e=>{ce.getOption(_e)===void 0&&ce.setOption(_e,ie[_e],!0)})})}function de(ce,_e,Re){var Ue=parse.filename;return Re||(parse.filename=null),Error("illegal "+(_e||"token")+" '"+ce+"' ("+(Ue?Ue+", ":"")+"line "+v.line+")")}function Se(){var ce=[],_e;do{if((_e=w())!=='"'&&_e!=="'")throw de(_e);ce.push(w()),S(_e),_e=E()}while(_e==='"'||_e==="'");return ce.join("")}function ve(ce){var _e=w();switch(_e){case"'":case'"':return _(_e),Se();case"true":case"TRUE":return!0;case"false":case"FALSE":return!1}try{return Ie(_e,!0)}catch{if(typeRefRe.test(_e))return _e;throw de(_e,"value")}}function Pe(ce,_e){var Re,Ue;do if(_e&&((Re=E())==='"'||Re==="'")){var qe=Se();if(ce.push(qe),U>=2023)throw de(qe,"id")}else try{ce.push([Ue=Ee(w()),S("to",!0)?Ee(w()):Ue])}catch(tt){if(_e&&typeRefRe.test(Re)&&U>=2023)ce.push(Re);else throw tt}while(S(",",!0));var Ze={options:void 0};Ze.setOption=function(tt,Fe){this.options===void 0&&(this.options={}),this.options[tt]=Fe},N(Ze,function(Fe){if(Fe==="option")he(Ze,Fe),S(";");else throw de(Fe)},function(){le(Ze)})}function Ie(ce,_e){var Re=1;switch(ce.charAt(0)==="-"&&(Re=-1,ce=ce.substring(1)),ce){case"inf":case"INF":case"Inf":return Re*(1/0);case"nan":case"NAN":case"Nan":case"NaN":return NaN;case"0":return 0}if(base10Re.test(ce))return Re*parseInt(ce,10);if(base16Re.test(ce))return Re*parseInt(ce,16);if(base8Re.test(ce))return Re*parseInt(ce,8);if(numberRe.test(ce))return Re*parseFloat(ce);throw de(ce,"number",_e)}function Ee(ce,_e){switch(ce){case"max":case"MAX":case"Max":return 536870911;case"0":return 0}if(!_e&&ce.charAt(0)==="-")throw de(ce,"id");if(base10NegRe.test(ce))return parseInt(ce,10);if(base16NegRe.test(ce))return parseInt(ce,16);if(base8NegRe.test(ce))return parseInt(ce,8);throw de(ce,"id")}function De(){if(C!==void 0)throw de("package");if(C=w(),!typeRefRe.test(C))throw de(C,"name");te=te.define(C),S(";")}function be(){var ce=E(),_e;switch(ce){case"weak":_e=D||(D=[]),w();break;case"public":w();default:_e=O||(O=[]);break}ce=Se(),S(";"),_e.push(ce)}function B(){if(S("="),U=Se(),U<2023)throw de(U,"syntax");S(";")}function F(){if(S("="),U=Se(),!["2023"].includes(U))throw de(U,"edition");S(";")}function M(ce,_e){switch(_e){case"option":return he(ce,_e),S(";"),!0;case"message":return Q(ce,_e),!0;case"enum":return re(ce,_e),!0;case"service":return me(ce,_e),!0;case"extend":return fe(ce,_e),!0}return!1}function N(ce,_e,Re){var Ue=v.line;if(ce&&(typeof ce.comment!="string"&&(ce.comment=x()),ce.filename=parse.filename),S("{",!0)){for(var qe;(qe=w())!=="}";)_e(qe);S(";",!0)}else Re&&Re(),S(";"),ce&&(typeof ce.comment!="string"||b)&&(ce.comment=x(Ue)||ce.comment)}function Q(ce,_e){if(!nameRe.test(_e=w()))throw de(_e,"type name");var Re=new Type(_e);N(Re,function(qe){if(!M(Re,qe))switch(qe){case"map":J(Re);break;case"required":if(U!=="proto2")throw de(qe);case"repeated":j(Re,qe);break;case"optional":if(U==="proto3")j(Re,"proto3_optional");else{if(U!=="proto2")throw de(qe);j(Re,"optional")}break;case"oneof":q(Re,qe);break;case"extensions":Pe(Re.extensions||(Re.extensions=[]));break;case"reserved":Pe(Re.reserved||(Re.reserved=[]),!0);break;default:if(U==="proto2"||!typeRefRe.test(qe))throw de(qe);_(qe),j(Re,"optional");break}}),ce.add(Re),ce===te&&X.push(Re)}function j(ce,_e,Re){var Ue=w();if(Ue==="group"){ne(ce,_e);return}for(;Ue.endsWith(".")||E().startsWith(".");)Ue+=w();if(!typeRefRe.test(Ue))throw de(Ue,"type");var qe=w();if(!nameRe.test(qe))throw de(qe,"name");qe=ee(qe),S("=");var Ze=new Field(qe,Ee(w()),Ue,_e,Re);if(N(Ze,function(nt){if(nt==="option")he(Ze,nt),S(";");else throw de(nt)},function(){le(Ze)}),_e==="proto3_optional"){var tt=new OneOf("_"+qe);Ze.setOption("proto3_optional",!0),tt.add(Ze),ce.add(tt)}else ce.add(Ze);ce===te&&X.push(Ze)}function ne(ce,_e){if(U>=2023)throw de("group");var Re=w();if(!nameRe.test(Re))throw de(Re,"name");var Ue=util.lcFirst(Re);Re===Ue&&(Re=util.ucFirst(Re)),S("=");var qe=Ee(w()),Ze=new Type(Re);Ze.group=!0;var tt=new Field(Ue,qe,Re,_e);tt.filename=parse.filename,N(Ze,function(nt){switch(nt){case"option":he(Ze,nt),S(";");break;case"required":case"repeated":j(Ze,nt);break;case"optional":U==="proto3"?j(Ze,"proto3_optional"):j(Ze,"optional");break;case"message":Q(Ze,nt);break;case"enum":re(Ze,nt);break;case"reserved":Pe(Ze.reserved||(Ze.reserved=[]),!0);break;default:throw de(nt)}}),ce.add(Ze).add(tt)}function J(ce){S("<");var _e=w();if(types.mapKey[_e]===void 0)throw de(_e,"type");S(",");var Re=w();if(!typeRefRe.test(Re))throw de(Re,"type");S(">");var Ue=w();if(!nameRe.test(Ue))throw de(Ue,"name");S("=");var qe=new MapField(ee(Ue),Ee(w()),_e,Re);N(qe,function(tt){if(tt==="option")he(qe,tt),S(";");else throw de(tt)},function(){le(qe)}),ce.add(qe)}function q(ce,_e){if(!nameRe.test(_e=w()))throw de(_e,"name");var Re=new OneOf(ee(_e));N(Re,function(qe){qe==="option"?(he(Re,qe),S(";")):(_(qe),j(Re,"optional"))}),ce.add(Re)}function re(ce,_e){if(!nameRe.test(_e=w()))throw de(_e,"name");var Re=new Enum(_e);N(Re,function(qe){switch(qe){case"option":he(Re,qe),S(";");break;case"reserved":Pe(Re.reserved||(Re.reserved=[]),!0),Re.reserved===void 0&&(Re.reserved=[]);break;default:H(Re,qe)}}),ce.add(Re),ce===te&&X.push(Re)}function H(ce,_e){if(!nameRe.test(_e))throw de(_e,"name");S("=");var Re=Ee(w(),!0),Ue={options:void 0};Ue.getOption=function(qe){return this.options[qe]},Ue.setOption=function(qe,Ze){ReflectionObject.prototype.setOption.call(Ue,qe,Ze)},Ue.setParsedOption=function(){},N(Ue,function(Ze){if(Ze==="option")he(Ue,Ze),S(";");else throw de(Ze)},function(){le(Ue)}),ce.add(_e,Re,Ue.comment,Ue.parsedOptions||Ue.options)}function he(ce,_e){var Re,Ue,qe=!0;for(_e==="option"&&(_e=w());_e!=="=";){if(_e==="("){var Ze=w();S(")"),_e="("+Ze+")"}if(qe){if(qe=!1,_e.includes(".")&&!_e.includes("(")){var tt=_e.split(".");Re=tt[0]+".",_e=tt[1];continue}Re=_e}else Ue=Ue?Ue+=_e:_e;_e=w()}var Fe=Ue?Re.concat(Ue):Re,nt=Oe(ce,Fe);Ue=Ue&&Ue[0]==="."?Ue.slice(1):Ue,Re=Re&&Re[Re.length-1]==="."?Re.slice(0,-1):Re,Ae(ce,Re,nt,Ue)}function Oe(ce,_e){if(S("{",!0)){for(var Re={};!S("}",!0);){if(!nameRe.test(ge=w()))throw de(ge,"name");if(ge===null)throw de(ge,"end of input");var Ue,qe=ge;if(S(":",!0),E()==="{")Ue=Oe(ce,_e+"."+ge);else if(E()==="["){Ue=[];var Ze;if(S("[",!0)){do Ze=ve(),Ue.push(Ze);while(S(",",!0));S("]"),typeof Ze<"u"&&Ne(ce,_e+"."+ge,Ze)}}else Ue=ve(),Ne(ce,_e+"."+ge,Ue);var tt=Re[qe];tt&&(Ue=[].concat(tt).concat(Ue)),Re[qe]=Ue,S(",",!0),S(";",!0)}return Re}var Fe=ve();return Ne(ce,_e,Fe),Fe}function Ne(ce,_e,Re){if(te===ce&&/^features\./.test(_e)){ie[_e]=Re;return}ce.setOption&&ce.setOption(_e,Re)}function Ae(ce,_e,Re,Ue){ce.setParsedOption&&ce.setParsedOption(_e,Re,Ue)}function le(ce){if(S("[",!0)){do he(ce,"option");while(S(",",!0));S("]")}return ce}function me(ce,_e){if(!nameRe.test(_e=w()))throw de(_e,"service name");var Re=new Service(_e);N(Re,function(qe){if(!M(Re,qe))if(qe==="rpc")Me(Re,qe);else throw de(qe)}),ce.add(Re),ce===te&&X.push(Re)}function Me(ce,_e){var Re=x(),Ue=_e;if(!nameRe.test(_e=w()))throw de(_e,"name");var qe=_e,Ze,tt,Fe,nt;if(S("("),S("stream",!0)&&(tt=!0),!typeRefRe.test(_e=w())||(Ze=_e,S(")"),S("returns"),S("("),S("stream",!0)&&(nt=!0),!typeRefRe.test(_e=w())))throw de(_e);Fe=_e,S(")");var it=new Method(qe,Ue,Ze,Fe,tt,nt);it.comment=Re,N(it,function(ct){if(ct==="option")he(it,ct),S(";");else throw de(ct)}),ce.add(it)}function fe(ce,_e){if(!typeRefRe.test(_e=w()))throw de(_e,"reference");var Re=_e;N(null,function(qe){switch(qe){case"required":case"repeated":j(ce,qe,Re);break;case"optional":U==="proto3"?j(ce,"proto3_optional",Re):j(ce,"optional",Re);break;default:if(U==="proto2"||!typeRefRe.test(qe))throw de(qe);_(qe),j(ce,"optional",Re);break}})}for(var ge;(ge=w())!==null;)switch(ge){case"package":if(!T)throw de(ge);De();break;case"import":if(!T)throw de(ge);be();break;case"syntax":if(!T)throw de(ge);B();break;case"edition":if(!T)throw de(ge);F();break;case"option":he(te,ge),S(";",!0);break;default:if(M(te,ge)){T=!1;continue}throw de(ge)}return ae(),parse.filename=null,{package:C,imports:O,weakImports:D,root:u}}var common_1=common,commonRe=/\/|\./;function common(y,u){commonRe.test(y)||(y="google/protobuf/"+y+".proto",u={nested:{google:{nested:{protobuf:{nested:u}}}}}),common[y]=u}common("any",{Any:{fields:{type_url:{type:"string",id:1},value:{type:"bytes",id:2}}}});var timeType;common("duration",{Duration:timeType={fields:{seconds:{type:"int64",id:1},nanos:{type:"int32",id:2}}}});common("timestamp",{Timestamp:timeType});common("empty",{Empty:{fields:{}}});common("struct",{Struct:{fields:{fields:{keyType:"string",type:"Value",id:1}}},Value:{oneofs:{kind:{oneof:["nullValue","numberValue","stringValue","boolValue","structValue","listValue"]}},fields:{nullValue:{type:"NullValue",id:1},numberValue:{type:"double",id:2},stringValue:{type:"string",id:3},boolValue:{type:"bool",id:4},structValue:{type:"Struct",id:5},listValue:{type:"ListValue",id:6}}},NullValue:{values:{NULL_VALUE:0}},ListValue:{fields:{values:{rule:"repeated",type:"Value",id:1}}}});common("wrappers",{DoubleValue:{fields:{value:{type:"double",id:1}}},FloatValue:{fields:{value:{type:"float",id:1}}},Int64Value:{fields:{value:{type:"int64",id:1}}},UInt64Value:{fields:{value:{type:"uint64",id:1}}},Int32Value:{fields:{value:{type:"int32",id:1}}},UInt32Value:{fields:{value:{type:"uint32",id:1}}},BoolValue:{fields:{value:{type:"bool",id:1}}},StringValue:{fields:{value:{type:"string",id:1}}},BytesValue:{fields:{value:{type:"bytes",id:1}}}});common("field_mask",{FieldMask:{fields:{paths:{rule:"repeated",type:"string",id:1}}}});common.get=function y(u){return common[u]||null};var protobuf$1=src.exports=indexLightExports;protobuf$1.build="full";protobuf$1.tokenize=tokenize_1;protobuf$1.parse=parse_1;protobuf$1.common=common_1;protobuf$1.Root._configure(protobuf$1.Type,protobuf$1.parse,protobuf$1.common);var srcExports=src.exports,protobufjs=srcExports;const protobuf=getDefaultExportFromCjs$1(protobufjs),protoSchema=`
86
86
  syntax = "proto3";
87
87
 
88
- enum MessageType {
89
- TEXT = 0;
90
- THREAD = 1;
91
- REACTION = 2;
92
- }
93
-
94
88
  message MessageData {
95
89
  string id = 1;
96
90
  optional string targetMessageId = 2;
97
- MessageType type = 3;
91
+ string type = 3;
98
92
  string message = 4;
99
93
  string username = 5;
100
94
  string address = 6;
@@ -115,4 +109,4 @@ message MessagePayload {
115
109
  MessageData message = 1;
116
110
  repeated MessageStateRef messageStateRefs = 2;
117
111
  }
118
- `;let protoRoot=null,messagePayloadType=null;const errorHandler=ErrorHandler.getInstance();async function initializeProtobuf(){protoRoot||(protoRoot=protobufjs.Root.fromJSON(protobuf.parse(protoSchema).root),messagePayloadType=protoRoot.lookupType("MessagePayload"))}async function decodeMessagePayload(y){if(await initializeProtobuf(),!messagePayloadType)throw new Error("MessagePayload type not initialized");const u={0:"text",1:"thread",2:"reaction"};try{const h=messagePayloadType.decode(y),b=messagePayloadType.toObject(h,{longs:String,enums:String,defaults:!0});if(!b.message)throw new Error("Decoded object has no message field");let v=b.message.additionalProps;if(v&&typeof v=="string")try{v=JSON.parse(v)}catch{console.warn("Failed to parse additionalProps as JSON:",v)}const w={...b.message,type:u[b.message.type]??"text",timestamp:Number(b.message.timestamp),additionalProps:v},_=(b.messageStateRefs||[]).map(E=>({...E,timestamp:Number(E.timestamp)}));return{message:w,messageStateRefs:_}}catch(h){throw errorHandler.handleError(h,"ProtoMessage.decodeMessagePayload"),h}}class Waku{constructor(u,h,b){this.logger=Logger$2.getInstance(),this.errorHandler=ErrorHandler.getInstance(),this.wakuNode=null,this.handleWakuMessage=async({payload:v})=>{try{if(!v)return this.logger.warn("Received Waku message without payload");const{message:w}=await decodeMessagePayload(v);if(!(w!=null&&w.id))return this.logger.warn("Received invalid message structure via Waku");this.onMessage(w)}catch(w){this.errorHandler.handleError(w,"Waku.handleWakuMessage")}},this.chatTopic=u,this.onMessage=h,this.wakuNode=b||null,this.initPromise=this.init()}async init(){if(this.wakuNode=this.wakuNode??await this.createWakuLightNode(),!await this.subscribeToTopic())throw new Error("Failed to subscribe to Waku topic");this.logger.info(`Subscribed to Waku topic: ${this.chatTopic}`)}async createWakuLightNode(){const u=await createLightNode({defaultBootstrap:!0,networkConfig:{clusterId:WAKU_CLUSTER_ID}});return await u.start(),await u.waitForPeers([Protocols.LightPush,Protocols.Filter],3e4),this.logger.info(`Waku node ready: ${u.libp2p.peerId.toString()}`),u}createWakuDecoder(u){if(!(u!=null&&u.trim()))throw new Error("Topic name must be a non-empty string");const b=createRoutingInfo({clusterId:WAKU_CLUSTER_ID,numShardsInCluster:8},{contentTopic:u});return createDecoder(u,b)}async subscribeToTopic(){var u;if(!((u=this.wakuNode)!=null&&u.isStarted()))throw new Error("Waku node is not running");return this.wakuNode.filter.subscribe(this.createWakuDecoder(this.chatTopic),this.handleWakuMessage)}async isReady(){var u;try{return await this.initPromise,((u=this.wakuNode)==null?void 0:u.isStarted())??!1}catch{return!1}}async stop(){try{await this.initPromise,this.wakuNode&&(await this.wakuNode.stop(),this.wakuNode=null,this.logger.info("Waku node stopped successfully"))}catch(u){throw this.errorHandler.handleError(u,"Waku.stop"),u}}}class SwarmHistory{constructor(u,h){this.utils=u,this.emitter=h,this.logger=Logger$2.getInstance(),this.errorHandler=ErrorHandler.getInstance(),this.processedRefs=new Set,this.refRetryCount=new Map,this.bannedRefs=new Set,this.latestStatefulMessage=null,this.MAX_RETRIES=3,this.RETRY_DELAY=1e3}async init(){try{const{data:u,index:h}=await this.utils.fetchLatestChatMessage();this.latestStatefulMessage=u;try{await this.initMessageState(u)}catch(b){this.errorHandler.handleError(b,"SwarmHistory.initMessageState")}return h}catch(u){return this.errorHandler.handleError(u,"SwarmHistory.init"),beeJs.FeedIndex.fromBigInt(0n)}}async initMessageState(u){try{if(!validateGsocMessage(u)){this.logger.warn("Invalid GSOC message during message state initialization");return}if(!u.messageStateRefs||u.messageStateRefs.length===0){this.logger.debug("No message state refs to initialize");return}const h=this.findLatestRef(u.messageStateRefs);if(!h){this.logger.warn("No valid latest reference found");return}this.logger.debug("Initializing message state with latest ref:",h.reference),await this.processMessageRefWithRetry(h.reference)}catch(h){if(this.utils.isNotFoundError(h)){this.logger.debug("No latest GSOC message found for message state initialization");return}this.errorHandler.handleError(h,"SwarmHistory.init")}}async fetchPreviousMessageState(){let u=this.latestStatefulMessage;if(!u){const{data:b}=await this.utils.fetchLatestChatMessage();u=b,this.latestStatefulMessage=b}if(!u.messageStateRefs||u.messageStateRefs.length===0){this.logger.debug("No message state refs to fetch");return}const h=[...u.messageStateRefs].sort((b,v)=>b.timestamp-v.timestamp);for(const b of h)!this.processedRefs.has(b.reference)&&!this.bannedRefs.has(b.reference)&&(this.logger.debug("Fetching previous message ref:",b.reference),await this.processMessageRefWithRetry(b.reference))}findLatestRef(u){return u.length===0?null:u.reduce((h,b)=>b.timestamp>h.timestamp?b:h)}async processMessageRefWithRetry(u){if(!(this.processedRefs.has(u)||this.bannedRefs.has(u)))try{await this.processMessageRef(u)}catch(h){await this.handleRefError(u,h)}}async processMessageRef(u){const h=await this.utils.downloadObjectFromBee(u);if(!validateMessageState(h))throw new Error(`Invalid message state for ref: ${u}`);this.processedRefs.add(u),this.refRetryCount.delete(u);for(const v of h)this.emitter.emit(EVENTS.MESSAGE_RECEIVED,v)}async handleRefError(u,h){const b=this.refRetryCount.get(u)||0,v=b+1;if(this.logger.warn(`Error processing ref ${u} (attempt ${v}/${this.MAX_RETRIES}):`,h),v>=this.MAX_RETRIES)this.bannedRefs.add(u),this.refRetryCount.delete(u),this.logger.error(`Ref ${u} has been banned after ${this.MAX_RETRIES} failed attempts`),this.errorHandler.handleError(h,"SwarmHistory.processMessageRef");else{this.refRetryCount.set(u,v);const w=this.RETRY_DELAY*Math.pow(2,b);this.logger.debug(`Retrying ref ${u} after ${w}ms delay`),await sleep(w),await this.processMessageRefWithRetry(u)}}hasPreviousMessages(){return!!this.latestStatefulMessage&&!!this.latestStatefulMessage.messageStateRefs&&this.latestStatefulMessage.messageStateRefs.length>1}cleanup(){this.processedRefs.clear(),this.refRetryCount.clear(),this.bannedRefs.clear(),this.latestStatefulMessage=null}}class SwarmChatUtils{constructor(u,h){this.userDetails=u,this.swarmSettings=h,this.depth=26,this.errorHandler=ErrorHandler.getInstance(),this.UPLOAD_GSOC_TIMEOUT=2e3}generateUserOwnedFeedId(u,h){return`${u}_EthercastChat_${h}`}isNotFoundError(u){return u.stack.includes("404")||u.message.includes("Not Found")||u.message.includes("404")||u.code===404}async writeOwnFeedDataByIndex(u,h){const{enveloped:b,stamp:v}=this.swarmSettings;if(!b)await this.writeOwnFeedDataByIndexOwned(u,h);else if(v)await this.writeOwnFeedDataByIndexEnvelope(u,h);else throw new Error("Enveloped mode is enabled, but stamp is not provided")}async writeOwnFeedDataByIndexOwned(u,h){const{bee:b,stamp:v,chatTopic:w}=this.swarmSettings,{privateKey:_,ownAddress:E}=this.userDetails,S=this.generateUserOwnedFeedId(w,E),x=beeJs.Topic.fromString(S);await b.makeFeedWriter(x,new beeJs.PrivateKey(_)).uploadPayload(v,JSON.stringify(h),{index:u})}async writeOwnFeedDataByIndexEnvelope(u,h){const{bee:b,stamp:v,chatTopic:w}=this.swarmSettings,{privateKey:_,ownAddress:E}=this.userDetails,S=new beeJs.PrivateKey(_),x=beeJs.Stamper.fromBlank(_,v,this.depth),T=this.generateUserOwnedFeedId(w,E),C=beeJs.Topic.fromString(T),O=makeFeedIdentifier(C,u),D=makeContentAddressedChunk(h),U=makeSingleOwnerChunk(D,O,S),te={hash:()=>U.address.toUint8Array()},X=x.stamp(te),{upload:ie}=b.makeSOCWriter(S),ee=beeJs.Bytes.fromUtf8(h);return(await ie(X,O,ee.toUint8Array())).reference.toHex()}orderMessages(u){return u.sort((h,b)=>h.timestamp-b.timestamp)}async downloadObjectFromBee(u){try{const{bee:h}=this.swarmSettings,b=await h.downloadData(u);return b?b.toJSON():null}catch(h){return this.errorHandler.handleError(h,"Utils.downloadObjectFromBee"),null}}async uploadObjectToBee(u){const{enveloped:h,stamp:b}=this.swarmSettings;if(h){if(b)return this.uploadObjectToBeeEnvelope(u);throw new Error("Enveloped mode is enabled, but stamp is not provided")}else return this.uploadObjectToBeeOwn(u)}async uploadObjectToBeeOwn(u){try{const{bee:h,stamp:b}=this.swarmSettings;return(await h.uploadData(b,JSON.stringify(u),{redundancyLevel:4})).reference.toString()}catch(h){return this.errorHandler.handleError(h,"Utils.uploadObjectToBee"),null}}async uploadObjectToBeeEnvelope(u){try{const{bee:h,stamp:b}=this.swarmSettings,{privateKey:v}=this.userDetails,w=beeJs.Stamper.fromBlank(v,b,this.depth),_=beeJs.Bytes.fromUtf8(JSON.stringify(u)),E=new MerkleTree(async x=>{await h.uploadChunk(w.stamp(x),x.build())});await E.append(_.toUint8Array());const S=await E.finalize();return Binary.uint8ArrayToHex(S.hash())}catch(h){return this.errorHandler.handleError(h,"Utils.uploadObjectToBee"),null}}async getOwnLatestFeedIndex(){try{const{bee:u,chatTopic:h}=this.swarmSettings,{ownAddress:b}=this.userDetails,v=this.generateUserOwnedFeedId(h,b),w=beeJs.Topic.fromString(v),E=await u.makeFeedReader(w,b).downloadPayload(),S=Number(E.feedIndex.toBigInt()),x=S+1;return{latestIndex:S,nextIndex:x}}catch(u){if(this.isNotFoundError(u))return{latestIndex:-1,nextIndex:0};throw u}}async fetchLatestChatMessage(){const{bee:u,chatTopic:h,chatAddress:b}=this.swarmSettings,w=await u.makeFeedReader(beeJs.Topic.fromString(h),remove0x(b)).downloadPayload();return{data:w.payload.toJSON(),index:w.feedIndex}}async fetchChatMessage(u){const{bee:h,chatTopic:b,chatAddress:v}=this.swarmSettings;return(await h.makeFeedReader(beeJs.Topic.fromString(b),remove0x(v)).downloadPayload({index:u})).payload.toJSON()}async sendMessageToGsoc(u){const{enveloped:h,stamp:b}=this.swarmSettings;if(!h)await this.sendMessageToGsocOwn(u);else if(b)await this.sendMessageToGsocEnvelope(u);else throw new Error("Enveloped mode is enabled, but stamp is not provided")}async rawSocDownload(u,h){const{beeUrl:b}=this.swarmSettings,v=await fetch(`${b}/soc/${u}/${h}`,{headers:{"swarm-chunk-retrieval-timeout":"2000ms"}});if(!v.ok){const w=new Error(`Failed to fetch: ${u}/${h} [${v.status}]`);throw w.status=v.status,w}return v.text()}async sendMessageToGsocOwn(u){const{bee:h,stamp:b,gsocTopic:v,gsocResourceId:w}=this.swarmSettings,_=new beeJs.PrivateKey(w),E=beeJs.Identifier.fromString(v),S=beeJs.Bytes.fromUtf8(u),{upload:x}=h.makeSOCWriter(_,{timeout:this.UPLOAD_GSOC_TIMEOUT});await x(b,E,S.toUint8Array())}async sendMessageToGsocEnvelope(u){const{bee:h,stamp:b,gsocTopic:v,gsocResourceId:w}=this.swarmSettings,{privateKey:_}=this.userDetails,E=beeJs.Stamper.fromBlank(_,b,this.depth),S=new beeJs.PrivateKey(w),x=beeJs.Identifier.fromString(v),T=beeJs.Bytes.fromUtf8(u),C=makeContentAddressedChunk(T.toUint8Array()),O=makeSingleOwnerChunk(C,x,S),D={hash:()=>O.address.toUint8Array()},U=E.stamp(D),{upload:te}=h.makeSOCWriter(S,{timeout:this.UPLOAD_GSOC_TIMEOUT});await te(U,x,T.toUint8Array())}}class SwarmChat{constructor(u){this.waku=null,this.isExternalWakuNode=!1,this.logger=Logger$2.getInstance(),this.errorHandler=ErrorHandler.getInstance(),this.gsocIndex=null,this.fetchProcessRunning=!1,this.stopFetch=!1;const h=new beeJs.PrivateKey(remove0x(u.user.privateKey));this.userDetails={privateKey:u.user.privateKey,ownAddress:h.publicKey().address().toString(),nickname:u.user.nickname,ownIndex:-1},this.swarmSettings={bee:new beeJs.Bee(u.infra.beeUrl),beeUrl:u.infra.beeUrl,stamp:u.infra.stamp||"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",enveloped:u.infra.enveloped,gsocTopic:u.infra.gsocTopic,gsocResourceId:u.infra.gsocResourceId,chatTopic:u.infra.chatTopic,chatAddress:u.infra.chatAddress,waku:u.infra.waku},this.emitter=new EventEmitter$3,this.utils=new SwarmChatUtils(this.userDetails,this.swarmSettings),this.history=new SwarmHistory(this.utils,this.emitter)}async start(){await this.init(),await this.startMessageFetchProcess()}async startMessageFetchProcess(){const{waku:u}=this.swarmSettings;u!=null&&u.enabled?await this.startWakuMessageFetch(u.node):await this.startPollingMessageFetch()}stop(){this.emitter.cleanAll(),this.stopPollingMessageFetch(),this.history.cleanup(),this.waku&&!this.isExternalWakuNode&&this.waku.stop(),this.waku=null}async startWakuMessageFetch(u){this.logger.info("Waku is enabled"),u&&(this.isExternalWakuNode=!0,this.logger.info("Using external Waku node instance"));const h=this.swarmSettings.chatTopic;if(this.waku=new Waku(h,v=>{this.emitter.emit(EVENTS.MESSAGE_RECEIVED,v)},u),!await this.waku.isReady())throw new Error("Waku node is not reachable")}getEmitter(){return this.emitter}orderMessages(u){return this.utils.orderMessages(u)}async sendMessage(u,h,b,v,w){const _=this.userDetails.ownIndex===-1?0:this.userDetails.ownIndex+1,E={id:v||v4$1(),username:this.userDetails.nickname,address:this.userDetails.ownAddress,chatTopic:this.swarmSettings.chatTopic,userTopic:this.utils.generateUserOwnedFeedId(this.swarmSettings.chatTopic,this.userDetails.ownAddress),signature:this.getSignature(u),timestamp:Date.now(),index:_,type:h,targetMessageId:b,message:u,additionalProps:w},S=validateMessageWithAdditionalProperties(E);if(!S.isValid){const x=`Invalid message: ${S.errors.join(", ")}`;throw this.logger.error(x),new Error(x)}try{this.emitter.emit(EVENTS.MESSAGE_REQUEST_INITIATED,E),await this.utils.writeOwnFeedDataByIndex(_,JSON.stringify(E)),this.userDetails.ownIndex=_,this.emitter.emit(EVENTS.MESSAGE_REQUEST_UPLOADED,E),await this.broadcastUserMessage(E)}catch(x){this.emitter.emit(EVENTS.MESSAGE_REQUEST_ERROR,E),this.errorHandler.handleError(x,"Chat.sendMessage")}}async fetchPreviousMessages(){try{return this.emitter.emit(EVENTS.LOADING_PREVIOUS_MESSAGES,!0),await this.history.fetchPreviousMessageState()}finally{this.emitter.emit(EVENTS.LOADING_PREVIOUS_MESSAGES,!1)}}hasPreviousMessages(){return this.history.hasPreviousMessages()}async retrySendMessage(u){this.sendMessage(u.message,u.type,u.targetMessageId,u.id,u.additionalProps)}async retryBroadcastUserMessage(u){await this.broadcastUserMessage(u)}async init(){try{this.emitter.emit(EVENTS.LOADING_INIT,!0);const[u,h]=await Promise.allSettled([this.initOwnIndex(),this.history.init()]);if(u.status==="rejected")throw u.reason;h.status==="fulfilled"&&(this.gsocIndex=h.value),this.emitter.emit(EVENTS.LOADING_INIT,!1)}catch(u){this.errorHandler.handleError(u,"Chat.initSelfState"),this.emitter.emit(EVENTS.CRITICAL_ERROR,u)}}async initOwnIndex(){const{latestIndex:b}=await retryAwaitableAsync(()=>this.utils.getOwnLatestFeedIndex(),10,1e3);this.userDetails.ownIndex=b}async fetchLatestMessage(){try{if(!this.gsocIndex)return;const u=beeJs.Topic.fromString(this.swarmSettings.chatTopic),h=makeFeedIdentifier(u,this.gsocIndex),b=await this.utils.rawSocDownload(this.swarmSettings.chatAddress,h.toString()),v=JSON.parse(b);if(!validateGsocMessage(v)){this.logger.warn("Invalid GSOC message during fetching");return}this.emitter.emit(EVENTS.MESSAGE_RECEIVED,v.message),this.gsocIndex=this.gsocIndex.next()}catch(u){if(this.utils.isNotFoundError(u))return;this.errorHandler.handleError(u,"Chat.fetchLatestMessage")}}async broadcastUserMessage(u){try{return retryAwaitableAsync(()=>this.utils.sendMessageToGsoc(JSON.stringify(u)))}catch(h){this.errorHandler.handleError(h,"Chat.broadcastUserMessage")}}getSignature(u){const{ownAddress:h,privateKey:b,nickname:v}=this.userDetails,w=new beeJs.EthAddress(h).toString(),_=new beeJs.PrivateKey(b);if(_.publicKey().address().toString()!==w)throw new Error("The provided address does not match the address derived from the private key");const S=Date.now();return _.sign(JSON.stringify({username:v,address:w,message:u,timestamp:S})).toHex()}async startPollingMessageFetch(){if(this.fetchProcessRunning)return;this.fetchProcessRunning=!0,this.stopFetch=!1;const u=async()=>{if(this.stopFetch){this.fetchProcessRunning=!1;return}await this.fetchLatestMessage(),setTimeout(u,200)};u()}stopPollingMessageFetch(){this.stopFetch=!0}}exports.EVENTS=EVENTS;exports.MessageType=MessageType;exports.SwarmChat=SwarmChat;
112
+ `;let protoRoot=null,messagePayloadType=null;const errorHandler=ErrorHandler.getInstance();async function initializeProtobuf(){protoRoot||(protoRoot=protobufjs.Root.fromJSON(protobuf.parse(protoSchema).root),messagePayloadType=protoRoot.lookupType("MessagePayload"))}async function decodeMessagePayload(y){if(await initializeProtobuf(),!messagePayloadType)throw new Error("MessagePayload type not initialized");try{const u=messagePayloadType.decode(y),h=messagePayloadType.toObject(u,{longs:String,enums:String,defaults:!0});if(!h.message)throw new Error("Decoded object has no message field");let b=h.message.additionalProps;if(b&&typeof b=="string")try{b=JSON.parse(b)}catch{console.warn("Failed to parse additionalProps as JSON:",b)}const v={...h.message,timestamp:Number(h.message.timestamp),additionalProps:b},w=(h.messageStateRefs||[]).map(_=>({..._,timestamp:Number(_.timestamp)}));return{message:v,messageStateRefs:w}}catch(u){throw errorHandler.handleError(u,"ProtoMessage.decodeMessagePayload"),u}}class Waku{constructor(u,h,b){this.logger=Logger$2.getInstance(),this.errorHandler=ErrorHandler.getInstance(),this.wakuNode=null,this.handleWakuMessage=async({payload:v})=>{try{if(!v)return this.logger.warn("Received Waku message without payload");const{message:w}=await decodeMessagePayload(v);if(!(w!=null&&w.id))return this.logger.warn("Received invalid message structure via Waku");this.onMessage(w)}catch(w){this.errorHandler.handleError(w,"Waku.handleWakuMessage")}},this.chatTopic=u,this.onMessage=h,this.wakuNode=b||null,this.initPromise=this.init()}async init(){if(this.wakuNode=this.wakuNode??await this.createWakuLightNode(),!await this.subscribeToTopic())throw new Error("Failed to subscribe to Waku topic");this.logger.info(`Subscribed to Waku topic: ${this.chatTopic}`)}async createWakuLightNode(){const u=await createLightNode({defaultBootstrap:!0,networkConfig:{clusterId:WAKU_CLUSTER_ID}});return await u.start(),await u.waitForPeers([Protocols.LightPush,Protocols.Filter],3e4),this.logger.info(`Waku node ready: ${u.libp2p.peerId.toString()}`),u}createWakuDecoder(u){if(!(u!=null&&u.trim()))throw new Error("Topic name must be a non-empty string");const h={clusterId:WAKU_CLUSTER_ID,numShardsInCluster:8},b=`/solarpunk-msrs/1/${u}/proto`,v=createRoutingInfo(h,{contentTopic:b});return createDecoder(b,v)}async subscribeToTopic(){var u;if(!((u=this.wakuNode)!=null&&u.isStarted()))throw new Error("Waku node is not running");return this.wakuNode.filter.subscribe(this.createWakuDecoder(this.chatTopic),this.handleWakuMessage)}async isReady(){var u;try{return await this.initPromise,((u=this.wakuNode)==null?void 0:u.isStarted())??!1}catch{return!1}}async stop(){try{await this.initPromise,this.wakuNode&&(await this.wakuNode.stop(),this.wakuNode=null,this.logger.info("Waku node stopped successfully"))}catch(u){throw this.errorHandler.handleError(u,"Waku.stop"),u}}}class SwarmHistory{constructor(u,h){this.utils=u,this.emitter=h,this.logger=Logger$2.getInstance(),this.errorHandler=ErrorHandler.getInstance(),this.processedRefs=new Set,this.refRetryCount=new Map,this.bannedRefs=new Set,this.latestStatefulMessage=null,this.MAX_RETRIES=3,this.RETRY_DELAY=1e3}async init(){try{const{data:u,index:h}=await this.utils.fetchLatestChatMessage();this.latestStatefulMessage=u;try{await this.initMessageState(u)}catch(b){this.errorHandler.handleError(b,"SwarmHistory.initMessageState")}return h}catch(u){return this.errorHandler.handleError(u,"SwarmHistory.init"),beeJs.FeedIndex.fromBigInt(0n)}}async initMessageState(u){try{if(!validateGsocMessage(u)){this.logger.warn("Invalid GSOC message during message state initialization");return}if(!u.messageStateRefs||u.messageStateRefs.length===0){this.logger.debug("No message state refs to initialize");return}const h=this.findLatestRef(u.messageStateRefs);if(!h){this.logger.warn("No valid latest reference found");return}this.logger.debug("Initializing message state with latest ref:",h.reference),await this.processMessageRefWithRetry(h.reference)}catch(h){if(this.utils.isNotFoundError(h)){this.logger.debug("No latest GSOC message found for message state initialization");return}this.errorHandler.handleError(h,"SwarmHistory.init")}}async fetchPreviousMessageState(){let u=this.latestStatefulMessage;if(!u){const{data:b}=await this.utils.fetchLatestChatMessage();u=b,this.latestStatefulMessage=b}if(!u.messageStateRefs||u.messageStateRefs.length===0){this.logger.debug("No message state refs to fetch");return}const h=[...u.messageStateRefs].sort((b,v)=>b.timestamp-v.timestamp);for(const b of h)!this.processedRefs.has(b.reference)&&!this.bannedRefs.has(b.reference)&&(this.logger.debug("Fetching previous message ref:",b.reference),await this.processMessageRefWithRetry(b.reference))}findLatestRef(u){return u.length===0?null:u.reduce((h,b)=>b.timestamp>h.timestamp?b:h)}async processMessageRefWithRetry(u){if(!(this.processedRefs.has(u)||this.bannedRefs.has(u)))try{await this.processMessageRef(u)}catch(h){await this.handleRefError(u,h)}}async processMessageRef(u){const h=await this.utils.downloadObjectFromBee(u);if(!validateMessageState(h))throw new Error(`Invalid message state for ref: ${u}`);this.processedRefs.add(u),this.refRetryCount.delete(u);for(const v of h)this.emitter.emit(EVENTS.MESSAGE_RECEIVED,v)}async handleRefError(u,h){const b=this.refRetryCount.get(u)||0,v=b+1;if(this.logger.warn(`Error processing ref ${u} (attempt ${v}/${this.MAX_RETRIES}):`,h),v>=this.MAX_RETRIES)this.bannedRefs.add(u),this.refRetryCount.delete(u),this.logger.error(`Ref ${u} has been banned after ${this.MAX_RETRIES} failed attempts`),this.errorHandler.handleError(h,"SwarmHistory.processMessageRef");else{this.refRetryCount.set(u,v);const w=this.RETRY_DELAY*Math.pow(2,b);this.logger.debug(`Retrying ref ${u} after ${w}ms delay`),await sleep(w),await this.processMessageRefWithRetry(u)}}hasPreviousMessages(){return!!this.latestStatefulMessage&&!!this.latestStatefulMessage.messageStateRefs&&this.latestStatefulMessage.messageStateRefs.length>1}cleanup(){this.processedRefs.clear(),this.refRetryCount.clear(),this.bannedRefs.clear(),this.latestStatefulMessage=null}}class SwarmChatUtils{constructor(u,h){this.userDetails=u,this.swarmSettings=h,this.depth=26,this.errorHandler=ErrorHandler.getInstance(),this.UPLOAD_GSOC_TIMEOUT=2e3}generateUserOwnedFeedId(u,h){return`${u}_EthercastChat_${h}`}isNotFoundError(u){return u.stack.includes("404")||u.message.includes("Not Found")||u.message.includes("404")||u.code===404}async writeOwnFeedDataByIndex(u,h){const{enveloped:b,stamp:v}=this.swarmSettings;if(!b)await this.writeOwnFeedDataByIndexOwned(u,h);else if(v)await this.writeOwnFeedDataByIndexEnvelope(u,h);else throw new Error("Enveloped mode is enabled, but stamp is not provided")}async writeOwnFeedDataByIndexOwned(u,h){const{bee:b,stamp:v,chatTopic:w}=this.swarmSettings,{privateKey:_,ownAddress:E}=this.userDetails,S=this.generateUserOwnedFeedId(w,E),x=beeJs.Topic.fromString(S);await b.makeFeedWriter(x,new beeJs.PrivateKey(_)).uploadPayload(v,JSON.stringify(h),{index:u})}async writeOwnFeedDataByIndexEnvelope(u,h){const{bee:b,stamp:v,chatTopic:w}=this.swarmSettings,{privateKey:_,ownAddress:E}=this.userDetails,S=new beeJs.PrivateKey(_),x=beeJs.Stamper.fromBlank(_,v,this.depth),T=this.generateUserOwnedFeedId(w,E),C=beeJs.Topic.fromString(T),O=makeFeedIdentifier(C,u),D=makeContentAddressedChunk(h),U=makeSingleOwnerChunk(D,O,S),te={hash:()=>U.address.toUint8Array()},X=x.stamp(te),{upload:ie}=b.makeSOCWriter(S),ee=beeJs.Bytes.fromUtf8(h);return(await ie(X,O,ee.toUint8Array())).reference.toHex()}orderMessages(u){return u.sort((h,b)=>h.timestamp-b.timestamp)}async downloadObjectFromBee(u){try{const{bee:h}=this.swarmSettings,b=await h.downloadData(u);return b?b.toJSON():null}catch(h){return this.errorHandler.handleError(h,"Utils.downloadObjectFromBee"),null}}async uploadObjectToBee(u){const{enveloped:h,stamp:b}=this.swarmSettings;if(h){if(b)return this.uploadObjectToBeeEnvelope(u);throw new Error("Enveloped mode is enabled, but stamp is not provided")}else return this.uploadObjectToBeeOwn(u)}async uploadObjectToBeeOwn(u){try{const{bee:h,stamp:b}=this.swarmSettings;return(await h.uploadData(b,JSON.stringify(u),{redundancyLevel:4})).reference.toString()}catch(h){return this.errorHandler.handleError(h,"Utils.uploadObjectToBee"),null}}async uploadObjectToBeeEnvelope(u){try{const{bee:h,stamp:b}=this.swarmSettings,{privateKey:v}=this.userDetails,w=beeJs.Stamper.fromBlank(v,b,this.depth),_=beeJs.Bytes.fromUtf8(JSON.stringify(u)),E=new MerkleTree(async x=>{await h.uploadChunk(w.stamp(x),x.build())});await E.append(_.toUint8Array());const S=await E.finalize();return Binary.uint8ArrayToHex(S.hash())}catch(h){return this.errorHandler.handleError(h,"Utils.uploadObjectToBee"),null}}async getOwnLatestFeedIndex(){try{const{bee:u,chatTopic:h}=this.swarmSettings,{ownAddress:b}=this.userDetails,v=this.generateUserOwnedFeedId(h,b),w=beeJs.Topic.fromString(v),E=await u.makeFeedReader(w,b).downloadPayload(),S=Number(E.feedIndex.toBigInt()),x=S+1;return{latestIndex:S,nextIndex:x}}catch(u){if(this.isNotFoundError(u))return{latestIndex:-1,nextIndex:0};throw u}}async fetchLatestChatMessage(){const{bee:u,chatTopic:h,chatAddress:b}=this.swarmSettings,w=await u.makeFeedReader(beeJs.Topic.fromString(h),remove0x(b)).downloadPayload();return{data:w.payload.toJSON(),index:w.feedIndex}}async fetchChatMessage(u){const{bee:h,chatTopic:b,chatAddress:v}=this.swarmSettings;return(await h.makeFeedReader(beeJs.Topic.fromString(b),remove0x(v)).downloadPayload({index:u})).payload.toJSON()}async sendMessageToGsoc(u){const{enveloped:h,stamp:b}=this.swarmSettings;if(!h)await this.sendMessageToGsocOwn(u);else if(b)await this.sendMessageToGsocEnvelope(u);else throw new Error("Enveloped mode is enabled, but stamp is not provided")}async rawSocDownload(u,h){const{beeUrl:b}=this.swarmSettings,v=await fetch(`${b}/soc/${u}/${h}`,{headers:{"swarm-chunk-retrieval-timeout":"2000ms"}});if(!v.ok){const w=new Error(`Failed to fetch: ${u}/${h} [${v.status}]`);throw w.status=v.status,w}return v.text()}async sendMessageToGsocOwn(u){const{bee:h,stamp:b,gsocTopic:v,gsocResourceId:w}=this.swarmSettings,_=new beeJs.PrivateKey(w),E=beeJs.Identifier.fromString(v),S=beeJs.Bytes.fromUtf8(u),{upload:x}=h.makeSOCWriter(_,{timeout:this.UPLOAD_GSOC_TIMEOUT});await x(b,E,S.toUint8Array())}async sendMessageToGsocEnvelope(u){const{bee:h,stamp:b,gsocTopic:v,gsocResourceId:w}=this.swarmSettings,{privateKey:_}=this.userDetails,E=beeJs.Stamper.fromBlank(_,b,this.depth),S=new beeJs.PrivateKey(w),x=beeJs.Identifier.fromString(v),T=beeJs.Bytes.fromUtf8(u),C=makeContentAddressedChunk(T.toUint8Array()),O=makeSingleOwnerChunk(C,x,S),D={hash:()=>O.address.toUint8Array()},U=E.stamp(D),{upload:te}=h.makeSOCWriter(S,{timeout:this.UPLOAD_GSOC_TIMEOUT});await te(U,x,T.toUint8Array())}}class SwarmChat{constructor(u){this.waku=null,this.isExternalWakuNode=!1,this.logger=Logger$2.getInstance(),this.errorHandler=ErrorHandler.getInstance(),this.gsocIndex=null,this.fetchProcessRunning=!1,this.stopFetch=!1;const h=new beeJs.PrivateKey(remove0x(u.user.privateKey));this.userDetails={privateKey:u.user.privateKey,ownAddress:h.publicKey().address().toString(),nickname:u.user.nickname,ownIndex:-1},this.swarmSettings={bee:new beeJs.Bee(u.infra.beeUrl),beeUrl:u.infra.beeUrl,stamp:u.infra.stamp||"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",enveloped:u.infra.enveloped,gsocTopic:u.infra.gsocTopic,gsocResourceId:u.infra.gsocResourceId,chatTopic:u.infra.chatTopic,chatAddress:u.infra.chatAddress,waku:u.infra.waku},this.emitter=new EventEmitter$3,this.utils=new SwarmChatUtils(this.userDetails,this.swarmSettings),this.history=new SwarmHistory(this.utils,this.emitter)}async start(){await this.init(),await this.startMessageFetchProcess()}async startMessageFetchProcess(){const{waku:u}=this.swarmSettings;u!=null&&u.enabled?await this.startWakuMessageFetch(u.node):await this.startPollingMessageFetch()}stop(){this.emitter.cleanAll(),this.stopPollingMessageFetch(),this.history.cleanup(),this.waku&&!this.isExternalWakuNode&&this.waku.stop(),this.waku=null}async startWakuMessageFetch(u){this.logger.info("Waku is enabled"),u&&(this.isExternalWakuNode=!0,this.logger.info("Using external Waku node instance"));const h=this.swarmSettings.chatTopic;this.waku=new Waku(h,b=>{this.emitter.emit(EVENTS.MESSAGE_RECEIVED,b)},u)}getEmitter(){return this.emitter}orderMessages(u){return this.utils.orderMessages(u)}async sendMessage(u,h,b,v,w){const _=this.userDetails.ownIndex===-1?0:this.userDetails.ownIndex+1,E={id:v||v4$1(),username:this.userDetails.nickname,address:this.userDetails.ownAddress,chatTopic:this.swarmSettings.chatTopic,userTopic:this.utils.generateUserOwnedFeedId(this.swarmSettings.chatTopic,this.userDetails.ownAddress),signature:this.getSignature(u),timestamp:Date.now(),index:_,type:h,targetMessageId:b,message:u,additionalProps:w},S=validateMessageWithAdditionalProperties(E);if(!S.isValid){const x=`Invalid message: ${S.errors.join(", ")}`;throw this.logger.error(x),new Error(x)}try{this.emitter.emit(EVENTS.MESSAGE_REQUEST_INITIATED,E),await this.utils.writeOwnFeedDataByIndex(_,JSON.stringify(E)),this.userDetails.ownIndex=_,this.emitter.emit(EVENTS.MESSAGE_REQUEST_UPLOADED,E),await this.broadcastUserMessage(E)}catch(x){this.emitter.emit(EVENTS.MESSAGE_REQUEST_ERROR,E),this.errorHandler.handleError(x,"Chat.sendMessage")}}async fetchPreviousMessages(){try{return this.emitter.emit(EVENTS.LOADING_PREVIOUS_MESSAGES,!0),await this.history.fetchPreviousMessageState()}finally{this.emitter.emit(EVENTS.LOADING_PREVIOUS_MESSAGES,!1)}}hasPreviousMessages(){return this.history.hasPreviousMessages()}async retrySendMessage(u){this.sendMessage(u.message,u.type,u.targetMessageId,u.id,u.additionalProps)}async retryBroadcastUserMessage(u){await this.broadcastUserMessage(u)}async init(){try{this.emitter.emit(EVENTS.LOADING_INIT,!0);const[u,h]=await Promise.allSettled([this.initOwnIndex(),this.history.init()]);if(u.status==="rejected")throw u.reason;h.status==="fulfilled"&&(this.gsocIndex=h.value),this.emitter.emit(EVENTS.LOADING_INIT,!1)}catch(u){this.errorHandler.handleError(u,"Chat.initSelfState"),this.emitter.emit(EVENTS.CRITICAL_ERROR,u)}}async initOwnIndex(){const{latestIndex:b}=await retryAwaitableAsync(()=>this.utils.getOwnLatestFeedIndex(),10,1e3);this.userDetails.ownIndex=b}async fetchLatestMessage(){try{if(!this.gsocIndex)return;const u=beeJs.Topic.fromString(this.swarmSettings.chatTopic),h=makeFeedIdentifier(u,this.gsocIndex),b=await this.utils.rawSocDownload(this.swarmSettings.chatAddress,h.toString()),v=JSON.parse(b);if(!validateGsocMessage(v)){this.logger.warn("Invalid GSOC message during fetching");return}this.emitter.emit(EVENTS.MESSAGE_RECEIVED,v.message),this.gsocIndex=this.gsocIndex.next()}catch(u){if(this.utils.isNotFoundError(u))return;this.errorHandler.handleError(u,"Chat.fetchLatestMessage")}}async broadcastUserMessage(u){try{return retryAwaitableAsync(()=>this.utils.sendMessageToGsoc(JSON.stringify(u)))}catch(h){this.errorHandler.handleError(h,"Chat.broadcastUserMessage")}}getSignature(u){const{ownAddress:h,privateKey:b,nickname:v}=this.userDetails,w=new beeJs.EthAddress(h).toString(),_=new beeJs.PrivateKey(b);if(_.publicKey().address().toString()!==w)throw new Error("The provided address does not match the address derived from the private key");const S=Date.now();return _.sign(JSON.stringify({username:v,address:w,message:u,timestamp:S})).toHex()}async startPollingMessageFetch(){if(this.fetchProcessRunning)return;this.fetchProcessRunning=!0,this.stopFetch=!1;const u=async()=>{if(this.stopFetch){this.fetchProcessRunning=!1;return}await this.fetchLatestMessage(),setTimeout(u,200)};u()}stopPollingMessageFetch(){this.stopFetch=!0}}exports.EVENTS=EVENTS;exports.MessageType=MessageType;exports.SwarmChat=SwarmChat;
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,2BAA2B,EAC3B,YAAY,EAGZ,WAAW,EACX,WAAW,EAEZ,MAAM,eAAe,CAAC;AAIvB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AASrD,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,kBAAkB,CAAS;IAEnC,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,WAAW,CAAmB;IACtC,OAAO,CAAC,aAAa,CAAoB;IAEzC,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,YAAY,CAA8B;IAElD,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,SAAS,CAAS;gBAEd,QAAQ,EAAE,YAAY;IA2BrB,KAAK;YAKJ,wBAAwB;IAU/B,IAAI;YAYG,qBAAqB;IAwB5B,UAAU;IAIV,aAAa,CAAC,QAAQ,EAAE,GAAG,EAAE;IAIvB,WAAW,CACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,WAAW,EACjB,eAAe,CAAC,EAAE,MAAM,EACxB,EAAE,CAAC,EAAE,MAAM,EACX,eAAe,CAAC,EAAE,2BAA2B,GAC5C,OAAO,CAAC,IAAI,CAAC;IAwCH,qBAAqB;IAW3B,mBAAmB,IAAI,OAAO;IAIxB,gBAAgB,CAAC,OAAO,EAAE,WAAW;IAIrC,yBAAyB,CAAC,OAAO,EAAE,WAAW;YAI7C,IAAI;YAqBJ,YAAY;YAUZ,kBAAkB;YA4BlB,oBAAoB;IAQlC,OAAO,CAAC,YAAY;YAkBN,wBAAwB;IAmBtC,OAAO,CAAC,uBAAuB;CAGhC"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,2BAA2B,EAC3B,YAAY,EAGZ,WAAW,EACX,WAAW,EAEZ,MAAM,eAAe,CAAC;AAIvB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AASrD,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,kBAAkB,CAAS;IAEnC,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,WAAW,CAAmB;IACtC,OAAO,CAAC,aAAa,CAAoB;IAEzC,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,YAAY,CAA8B;IAElD,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,SAAS,CAAS;gBAEd,QAAQ,EAAE,YAAY;IA2BrB,KAAK;YAKJ,wBAAwB;IAU/B,IAAI;YAYG,qBAAqB;IAmB5B,UAAU;IAIV,aAAa,CAAC,QAAQ,EAAE,GAAG,EAAE;IAIvB,WAAW,CACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,WAAW,EACjB,eAAe,CAAC,EAAE,MAAM,EACxB,EAAE,CAAC,EAAE,MAAM,EACX,eAAe,CAAC,EAAE,2BAA2B,GAC5C,OAAO,CAAC,IAAI,CAAC;IAwCH,qBAAqB;IAW3B,mBAAmB,IAAI,OAAO;IAIxB,gBAAgB,CAAC,OAAO,EAAE,WAAW;IAIrC,yBAAyB,CAAC,OAAO,EAAE,WAAW;YAI7C,IAAI;YAqBJ,YAAY;YAUZ,kBAAkB;YA4BlB,oBAAoB;IAQlC,OAAO,CAAC,YAAY;YAkBN,wBAAwB;IAmBtC,OAAO,CAAC,uBAAuB;CAGhC"}
@@ -85,16 +85,10 @@ function print() { __p += __j.call(arguments, '') }
85
85
  `&&++v,++h===b)throw x("comment");Se=ve,ve=C(h)}while(Se!=="*"||ve!=="/");++h,Ie&&(O(Pe,h-2,Ee),Ee=!0),de=!0}else return"/"}}while(de);var De=h;delimRe.lastIndex=0;var be=delimRe.test(C(De++));if(!be)for(;De<b&&!delimRe.test(C(De));)++De;var B=y.substring(h,h=De);return(B==='"'||B==="'")&&(S=B),B}function X(de){E.push(de)}function ie(){if(!E.length){var de=te();if(de===null)return null;X(de)}return E[0]}function ee(de,Se){var ve=ie(),Pe=ve===de;if(Pe)return te(),!0;if(!Se)throw x("token '"+ve+"', '"+de+"' expected");return!1}function ae(de){var Se=null,ve;return de===void 0?(ve=_[v-1],delete _[v-1],ve&&(u||ve.type==="*"||ve.lineEmpty)&&(Se=ve.leading?ve.text:null)):(w<de&&ie(),ve=_[de],delete _[de],ve&&!ve.lineEmpty&&(u||ve.type==="/")&&(Se=ve.leading?null:ve.text)),Se}return Object.defineProperty({next:te,peek:ie,push:X,skip:ee,cmnt:ae},"line",{get:function(){return v}})}var parse_1=parse;parse.filename=null,parse.defaults={keepCase:!1};var tokenize=tokenize_1,Root=requireRoot(),Type=requireType(),Field=requireField(),MapField=requireMapfield(),OneOf=requireOneof(),Enum=require_enum(),Service=requireService(),Method=requireMethod(),ReflectionObject=requireObject(),types=requireTypes(),util=requireUtil(),base10Re=/^[1-9][0-9]*$/,base10NegRe=/^-?[1-9][0-9]*$/,base16Re=/^0[x][0-9a-fA-F]+$/,base16NegRe=/^-?0[x][0-9a-fA-F]+$/,base8Re=/^0[0-7]+$/,base8NegRe=/^-?0[0-7]+$/,numberRe=/^(?![eE])[0-9]*(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?$/,nameRe=/^[a-zA-Z_][a-zA-Z_0-9]*$/,typeRefRe=/^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/;function parse(y,u,h){u instanceof Root||(h=u,u=new Root),h||(h=parse.defaults);var b=h.preferTrailingComment||!1,v=tokenize(y,h.alternateCommentMode||!1),w=v.next,_=v.push,E=v.peek,S=v.skip,x=v.cmnt,T=!0,C,O,D,U="proto2",te=u,X=[],ie={},ee=h.keepCase?function(ce){return ce}:util.camelCase;function ae(){X.forEach(ce=>{ce._edition=U,Object.keys(ie).forEach(_e=>{ce.getOption(_e)===void 0&&ce.setOption(_e,ie[_e],!0)})})}function de(ce,_e,Re){var Ue=parse.filename;return Re||(parse.filename=null),Error("illegal "+(_e||"token")+" '"+ce+"' ("+(Ue?Ue+", ":"")+"line "+v.line+")")}function Se(){var ce=[],_e;do{if((_e=w())!=='"'&&_e!=="'")throw de(_e);ce.push(w()),S(_e),_e=E()}while(_e==='"'||_e==="'");return ce.join("")}function ve(ce){var _e=w();switch(_e){case"'":case'"':return _(_e),Se();case"true":case"TRUE":return!0;case"false":case"FALSE":return!1}try{return Ie(_e,!0)}catch{if(typeRefRe.test(_e))return _e;throw de(_e,"value")}}function Pe(ce,_e){var Re,Ue;do if(_e&&((Re=E())==='"'||Re==="'")){var qe=Se();if(ce.push(qe),U>=2023)throw de(qe,"id")}else try{ce.push([Ue=Ee(w()),S("to",!0)?Ee(w()):Ue])}catch(tt){if(_e&&typeRefRe.test(Re)&&U>=2023)ce.push(Re);else throw tt}while(S(",",!0));var Ze={options:void 0};Ze.setOption=function(tt,Fe){this.options===void 0&&(this.options={}),this.options[tt]=Fe},N(Ze,function(Fe){if(Fe==="option")he(Ze,Fe),S(";");else throw de(Fe)},function(){le(Ze)})}function Ie(ce,_e){var Re=1;switch(ce.charAt(0)==="-"&&(Re=-1,ce=ce.substring(1)),ce){case"inf":case"INF":case"Inf":return Re*(1/0);case"nan":case"NAN":case"Nan":case"NaN":return NaN;case"0":return 0}if(base10Re.test(ce))return Re*parseInt(ce,10);if(base16Re.test(ce))return Re*parseInt(ce,16);if(base8Re.test(ce))return Re*parseInt(ce,8);if(numberRe.test(ce))return Re*parseFloat(ce);throw de(ce,"number",_e)}function Ee(ce,_e){switch(ce){case"max":case"MAX":case"Max":return 536870911;case"0":return 0}if(!_e&&ce.charAt(0)==="-")throw de(ce,"id");if(base10NegRe.test(ce))return parseInt(ce,10);if(base16NegRe.test(ce))return parseInt(ce,16);if(base8NegRe.test(ce))return parseInt(ce,8);throw de(ce,"id")}function De(){if(C!==void 0)throw de("package");if(C=w(),!typeRefRe.test(C))throw de(C,"name");te=te.define(C),S(";")}function be(){var ce=E(),_e;switch(ce){case"weak":_e=D||(D=[]),w();break;case"public":w();default:_e=O||(O=[]);break}ce=Se(),S(";"),_e.push(ce)}function B(){if(S("="),U=Se(),U<2023)throw de(U,"syntax");S(";")}function F(){if(S("="),U=Se(),!["2023"].includes(U))throw de(U,"edition");S(";")}function M(ce,_e){switch(_e){case"option":return he(ce,_e),S(";"),!0;case"message":return Q(ce,_e),!0;case"enum":return re(ce,_e),!0;case"service":return me(ce,_e),!0;case"extend":return fe(ce,_e),!0}return!1}function N(ce,_e,Re){var Ue=v.line;if(ce&&(typeof ce.comment!="string"&&(ce.comment=x()),ce.filename=parse.filename),S("{",!0)){for(var qe;(qe=w())!=="}";)_e(qe);S(";",!0)}else Re&&Re(),S(";"),ce&&(typeof ce.comment!="string"||b)&&(ce.comment=x(Ue)||ce.comment)}function Q(ce,_e){if(!nameRe.test(_e=w()))throw de(_e,"type name");var Re=new Type(_e);N(Re,function(qe){if(!M(Re,qe))switch(qe){case"map":J(Re);break;case"required":if(U!=="proto2")throw de(qe);case"repeated":j(Re,qe);break;case"optional":if(U==="proto3")j(Re,"proto3_optional");else{if(U!=="proto2")throw de(qe);j(Re,"optional")}break;case"oneof":q(Re,qe);break;case"extensions":Pe(Re.extensions||(Re.extensions=[]));break;case"reserved":Pe(Re.reserved||(Re.reserved=[]),!0);break;default:if(U==="proto2"||!typeRefRe.test(qe))throw de(qe);_(qe),j(Re,"optional");break}}),ce.add(Re),ce===te&&X.push(Re)}function j(ce,_e,Re){var Ue=w();if(Ue==="group"){ne(ce,_e);return}for(;Ue.endsWith(".")||E().startsWith(".");)Ue+=w();if(!typeRefRe.test(Ue))throw de(Ue,"type");var qe=w();if(!nameRe.test(qe))throw de(qe,"name");qe=ee(qe),S("=");var Ze=new Field(qe,Ee(w()),Ue,_e,Re);if(N(Ze,function(nt){if(nt==="option")he(Ze,nt),S(";");else throw de(nt)},function(){le(Ze)}),_e==="proto3_optional"){var tt=new OneOf("_"+qe);Ze.setOption("proto3_optional",!0),tt.add(Ze),ce.add(tt)}else ce.add(Ze);ce===te&&X.push(Ze)}function ne(ce,_e){if(U>=2023)throw de("group");var Re=w();if(!nameRe.test(Re))throw de(Re,"name");var Ue=util.lcFirst(Re);Re===Ue&&(Re=util.ucFirst(Re)),S("=");var qe=Ee(w()),Ze=new Type(Re);Ze.group=!0;var tt=new Field(Ue,qe,Re,_e);tt.filename=parse.filename,N(Ze,function(nt){switch(nt){case"option":he(Ze,nt),S(";");break;case"required":case"repeated":j(Ze,nt);break;case"optional":U==="proto3"?j(Ze,"proto3_optional"):j(Ze,"optional");break;case"message":Q(Ze,nt);break;case"enum":re(Ze,nt);break;case"reserved":Pe(Ze.reserved||(Ze.reserved=[]),!0);break;default:throw de(nt)}}),ce.add(Ze).add(tt)}function J(ce){S("<");var _e=w();if(types.mapKey[_e]===void 0)throw de(_e,"type");S(",");var Re=w();if(!typeRefRe.test(Re))throw de(Re,"type");S(">");var Ue=w();if(!nameRe.test(Ue))throw de(Ue,"name");S("=");var qe=new MapField(ee(Ue),Ee(w()),_e,Re);N(qe,function(tt){if(tt==="option")he(qe,tt),S(";");else throw de(tt)},function(){le(qe)}),ce.add(qe)}function q(ce,_e){if(!nameRe.test(_e=w()))throw de(_e,"name");var Re=new OneOf(ee(_e));N(Re,function(qe){qe==="option"?(he(Re,qe),S(";")):(_(qe),j(Re,"optional"))}),ce.add(Re)}function re(ce,_e){if(!nameRe.test(_e=w()))throw de(_e,"name");var Re=new Enum(_e);N(Re,function(qe){switch(qe){case"option":he(Re,qe),S(";");break;case"reserved":Pe(Re.reserved||(Re.reserved=[]),!0),Re.reserved===void 0&&(Re.reserved=[]);break;default:H(Re,qe)}}),ce.add(Re),ce===te&&X.push(Re)}function H(ce,_e){if(!nameRe.test(_e))throw de(_e,"name");S("=");var Re=Ee(w(),!0),Ue={options:void 0};Ue.getOption=function(qe){return this.options[qe]},Ue.setOption=function(qe,Ze){ReflectionObject.prototype.setOption.call(Ue,qe,Ze)},Ue.setParsedOption=function(){},N(Ue,function(Ze){if(Ze==="option")he(Ue,Ze),S(";");else throw de(Ze)},function(){le(Ue)}),ce.add(_e,Re,Ue.comment,Ue.parsedOptions||Ue.options)}function he(ce,_e){var Re,Ue,qe=!0;for(_e==="option"&&(_e=w());_e!=="=";){if(_e==="("){var Ze=w();S(")"),_e="("+Ze+")"}if(qe){if(qe=!1,_e.includes(".")&&!_e.includes("(")){var tt=_e.split(".");Re=tt[0]+".",_e=tt[1];continue}Re=_e}else Ue=Ue?Ue+=_e:_e;_e=w()}var Fe=Ue?Re.concat(Ue):Re,nt=Oe(ce,Fe);Ue=Ue&&Ue[0]==="."?Ue.slice(1):Ue,Re=Re&&Re[Re.length-1]==="."?Re.slice(0,-1):Re,Ae(ce,Re,nt,Ue)}function Oe(ce,_e){if(S("{",!0)){for(var Re={};!S("}",!0);){if(!nameRe.test(ge=w()))throw de(ge,"name");if(ge===null)throw de(ge,"end of input");var Ue,qe=ge;if(S(":",!0),E()==="{")Ue=Oe(ce,_e+"."+ge);else if(E()==="["){Ue=[];var Ze;if(S("[",!0)){do Ze=ve(),Ue.push(Ze);while(S(",",!0));S("]"),typeof Ze<"u"&&Ne(ce,_e+"."+ge,Ze)}}else Ue=ve(),Ne(ce,_e+"."+ge,Ue);var tt=Re[qe];tt&&(Ue=[].concat(tt).concat(Ue)),Re[qe]=Ue,S(",",!0),S(";",!0)}return Re}var Fe=ve();return Ne(ce,_e,Fe),Fe}function Ne(ce,_e,Re){if(te===ce&&/^features\./.test(_e)){ie[_e]=Re;return}ce.setOption&&ce.setOption(_e,Re)}function Ae(ce,_e,Re,Ue){ce.setParsedOption&&ce.setParsedOption(_e,Re,Ue)}function le(ce){if(S("[",!0)){do he(ce,"option");while(S(",",!0));S("]")}return ce}function me(ce,_e){if(!nameRe.test(_e=w()))throw de(_e,"service name");var Re=new Service(_e);N(Re,function(qe){if(!M(Re,qe))if(qe==="rpc")Me(Re,qe);else throw de(qe)}),ce.add(Re),ce===te&&X.push(Re)}function Me(ce,_e){var Re=x(),Ue=_e;if(!nameRe.test(_e=w()))throw de(_e,"name");var qe=_e,Ze,tt,Fe,nt;if(S("("),S("stream",!0)&&(tt=!0),!typeRefRe.test(_e=w())||(Ze=_e,S(")"),S("returns"),S("("),S("stream",!0)&&(nt=!0),!typeRefRe.test(_e=w())))throw de(_e);Fe=_e,S(")");var it=new Method(qe,Ue,Ze,Fe,tt,nt);it.comment=Re,N(it,function(ct){if(ct==="option")he(it,ct),S(";");else throw de(ct)}),ce.add(it)}function fe(ce,_e){if(!typeRefRe.test(_e=w()))throw de(_e,"reference");var Re=_e;N(null,function(qe){switch(qe){case"required":case"repeated":j(ce,qe,Re);break;case"optional":U==="proto3"?j(ce,"proto3_optional",Re):j(ce,"optional",Re);break;default:if(U==="proto2"||!typeRefRe.test(qe))throw de(qe);_(qe),j(ce,"optional",Re);break}})}for(var ge;(ge=w())!==null;)switch(ge){case"package":if(!T)throw de(ge);De();break;case"import":if(!T)throw de(ge);be();break;case"syntax":if(!T)throw de(ge);B();break;case"edition":if(!T)throw de(ge);F();break;case"option":he(te,ge),S(";",!0);break;default:if(M(te,ge)){T=!1;continue}throw de(ge)}return ae(),parse.filename=null,{package:C,imports:O,weakImports:D,root:u}}var common_1=common,commonRe=/\/|\./;function common(y,u){commonRe.test(y)||(y="google/protobuf/"+y+".proto",u={nested:{google:{nested:{protobuf:{nested:u}}}}}),common[y]=u}common("any",{Any:{fields:{type_url:{type:"string",id:1},value:{type:"bytes",id:2}}}});var timeType;common("duration",{Duration:timeType={fields:{seconds:{type:"int64",id:1},nanos:{type:"int32",id:2}}}}),common("timestamp",{Timestamp:timeType}),common("empty",{Empty:{fields:{}}}),common("struct",{Struct:{fields:{fields:{keyType:"string",type:"Value",id:1}}},Value:{oneofs:{kind:{oneof:["nullValue","numberValue","stringValue","boolValue","structValue","listValue"]}},fields:{nullValue:{type:"NullValue",id:1},numberValue:{type:"double",id:2},stringValue:{type:"string",id:3},boolValue:{type:"bool",id:4},structValue:{type:"Struct",id:5},listValue:{type:"ListValue",id:6}}},NullValue:{values:{NULL_VALUE:0}},ListValue:{fields:{values:{rule:"repeated",type:"Value",id:1}}}}),common("wrappers",{DoubleValue:{fields:{value:{type:"double",id:1}}},FloatValue:{fields:{value:{type:"float",id:1}}},Int64Value:{fields:{value:{type:"int64",id:1}}},UInt64Value:{fields:{value:{type:"uint64",id:1}}},Int32Value:{fields:{value:{type:"int32",id:1}}},UInt32Value:{fields:{value:{type:"uint32",id:1}}},BoolValue:{fields:{value:{type:"bool",id:1}}},StringValue:{fields:{value:{type:"string",id:1}}},BytesValue:{fields:{value:{type:"bytes",id:1}}}}),common("field_mask",{FieldMask:{fields:{paths:{rule:"repeated",type:"string",id:1}}}}),common.get=function y(u){return common[u]||null};var protobuf$1=src.exports=indexLightExports;protobuf$1.build="full",protobuf$1.tokenize=tokenize_1,protobuf$1.parse=parse_1,protobuf$1.common=common_1,protobuf$1.Root._configure(protobuf$1.Type,protobuf$1.parse,protobuf$1.common);var srcExports=src.exports,protobufjs=srcExports;const protobuf=getDefaultExportFromCjs$1(protobufjs),protoSchema=`
86
86
  syntax = "proto3";
87
87
 
88
- enum MessageType {
89
- TEXT = 0;
90
- THREAD = 1;
91
- REACTION = 2;
92
- }
93
-
94
88
  message MessageData {
95
89
  string id = 1;
96
90
  optional string targetMessageId = 2;
97
- MessageType type = 3;
91
+ string type = 3;
98
92
  string message = 4;
99
93
  string username = 5;
100
94
  string address = 6;
@@ -115,4 +109,4 @@ message MessagePayload {
115
109
  MessageData message = 1;
116
110
  repeated MessageStateRef messageStateRefs = 2;
117
111
  }
118
- `;let protoRoot=null,messagePayloadType=null;const errorHandler=ErrorHandler.getInstance();async function initializeProtobuf(){protoRoot||(protoRoot=protobufjs.Root.fromJSON(protobuf.parse(protoSchema).root),messagePayloadType=protoRoot.lookupType("MessagePayload"))}async function decodeMessagePayload(y){if(await initializeProtobuf(),!messagePayloadType)throw new Error("MessagePayload type not initialized");const u={0:"text",1:"thread",2:"reaction"};try{const h=messagePayloadType.decode(y),b=messagePayloadType.toObject(h,{longs:String,enums:String,defaults:!0});if(!b.message)throw new Error("Decoded object has no message field");let v=b.message.additionalProps;if(v&&typeof v=="string")try{v=JSON.parse(v)}catch{console.warn("Failed to parse additionalProps as JSON:",v)}const w={...b.message,type:u[b.message.type]??"text",timestamp:Number(b.message.timestamp),additionalProps:v},_=(b.messageStateRefs||[]).map(E=>({...E,timestamp:Number(E.timestamp)}));return{message:w,messageStateRefs:_}}catch(h){throw errorHandler.handleError(h,"ProtoMessage.decodeMessagePayload"),h}}class Waku{constructor(u,h,b){this.logger=Logger$2.getInstance(),this.errorHandler=ErrorHandler.getInstance(),this.wakuNode=null,this.handleWakuMessage=async({payload:v})=>{try{if(!v)return this.logger.warn("Received Waku message without payload");const{message:w}=await decodeMessagePayload(v);if(!(w!=null&&w.id))return this.logger.warn("Received invalid message structure via Waku");this.onMessage(w)}catch(w){this.errorHandler.handleError(w,"Waku.handleWakuMessage")}},this.chatTopic=u,this.onMessage=h,this.wakuNode=b||null,this.initPromise=this.init()}async init(){if(this.wakuNode=this.wakuNode??await this.createWakuLightNode(),!await this.subscribeToTopic())throw new Error("Failed to subscribe to Waku topic");this.logger.info(`Subscribed to Waku topic: ${this.chatTopic}`)}async createWakuLightNode(){const u=await createLightNode({defaultBootstrap:!0,networkConfig:{clusterId:WAKU_CLUSTER_ID}});return await u.start(),await u.waitForPeers([Protocols.LightPush,Protocols.Filter],3e4),this.logger.info(`Waku node ready: ${u.libp2p.peerId.toString()}`),u}createWakuDecoder(u){if(!(u!=null&&u.trim()))throw new Error("Topic name must be a non-empty string");const b=createRoutingInfo({clusterId:WAKU_CLUSTER_ID,numShardsInCluster:8},{contentTopic:u});return createDecoder(u,b)}async subscribeToTopic(){var u;if(!((u=this.wakuNode)!=null&&u.isStarted()))throw new Error("Waku node is not running");return this.wakuNode.filter.subscribe(this.createWakuDecoder(this.chatTopic),this.handleWakuMessage)}async isReady(){var u;try{return await this.initPromise,((u=this.wakuNode)==null?void 0:u.isStarted())??!1}catch{return!1}}async stop(){try{await this.initPromise,this.wakuNode&&(await this.wakuNode.stop(),this.wakuNode=null,this.logger.info("Waku node stopped successfully"))}catch(u){throw this.errorHandler.handleError(u,"Waku.stop"),u}}}class SwarmHistory{constructor(u,h){this.utils=u,this.emitter=h,this.logger=Logger$2.getInstance(),this.errorHandler=ErrorHandler.getInstance(),this.processedRefs=new Set,this.refRetryCount=new Map,this.bannedRefs=new Set,this.latestStatefulMessage=null,this.MAX_RETRIES=3,this.RETRY_DELAY=1e3}async init(){try{const{data:u,index:h}=await this.utils.fetchLatestChatMessage();this.latestStatefulMessage=u;try{await this.initMessageState(u)}catch(b){this.errorHandler.handleError(b,"SwarmHistory.initMessageState")}return h}catch(u){return this.errorHandler.handleError(u,"SwarmHistory.init"),beeJs.FeedIndex.fromBigInt(0n)}}async initMessageState(u){try{if(!validateGsocMessage(u)){this.logger.warn("Invalid GSOC message during message state initialization");return}if(!u.messageStateRefs||u.messageStateRefs.length===0){this.logger.debug("No message state refs to initialize");return}const h=this.findLatestRef(u.messageStateRefs);if(!h){this.logger.warn("No valid latest reference found");return}this.logger.debug("Initializing message state with latest ref:",h.reference),await this.processMessageRefWithRetry(h.reference)}catch(h){if(this.utils.isNotFoundError(h)){this.logger.debug("No latest GSOC message found for message state initialization");return}this.errorHandler.handleError(h,"SwarmHistory.init")}}async fetchPreviousMessageState(){let u=this.latestStatefulMessage;if(!u){const{data:b}=await this.utils.fetchLatestChatMessage();u=b,this.latestStatefulMessage=b}if(!u.messageStateRefs||u.messageStateRefs.length===0){this.logger.debug("No message state refs to fetch");return}const h=[...u.messageStateRefs].sort((b,v)=>b.timestamp-v.timestamp);for(const b of h)!this.processedRefs.has(b.reference)&&!this.bannedRefs.has(b.reference)&&(this.logger.debug("Fetching previous message ref:",b.reference),await this.processMessageRefWithRetry(b.reference))}findLatestRef(u){return u.length===0?null:u.reduce((h,b)=>b.timestamp>h.timestamp?b:h)}async processMessageRefWithRetry(u){if(!(this.processedRefs.has(u)||this.bannedRefs.has(u)))try{await this.processMessageRef(u)}catch(h){await this.handleRefError(u,h)}}async processMessageRef(u){const h=await this.utils.downloadObjectFromBee(u);if(!validateMessageState(h))throw new Error(`Invalid message state for ref: ${u}`);this.processedRefs.add(u),this.refRetryCount.delete(u);for(const v of h)this.emitter.emit(EVENTS.MESSAGE_RECEIVED,v)}async handleRefError(u,h){const b=this.refRetryCount.get(u)||0,v=b+1;if(this.logger.warn(`Error processing ref ${u} (attempt ${v}/${this.MAX_RETRIES}):`,h),v>=this.MAX_RETRIES)this.bannedRefs.add(u),this.refRetryCount.delete(u),this.logger.error(`Ref ${u} has been banned after ${this.MAX_RETRIES} failed attempts`),this.errorHandler.handleError(h,"SwarmHistory.processMessageRef");else{this.refRetryCount.set(u,v);const w=this.RETRY_DELAY*Math.pow(2,b);this.logger.debug(`Retrying ref ${u} after ${w}ms delay`),await sleep(w),await this.processMessageRefWithRetry(u)}}hasPreviousMessages(){return!!this.latestStatefulMessage&&!!this.latestStatefulMessage.messageStateRefs&&this.latestStatefulMessage.messageStateRefs.length>1}cleanup(){this.processedRefs.clear(),this.refRetryCount.clear(),this.bannedRefs.clear(),this.latestStatefulMessage=null}}class SwarmChatUtils{constructor(u,h){this.userDetails=u,this.swarmSettings=h,this.depth=26,this.errorHandler=ErrorHandler.getInstance(),this.UPLOAD_GSOC_TIMEOUT=2e3}generateUserOwnedFeedId(u,h){return`${u}_EthercastChat_${h}`}isNotFoundError(u){return u.stack.includes("404")||u.message.includes("Not Found")||u.message.includes("404")||u.code===404}async writeOwnFeedDataByIndex(u,h){const{enveloped:b,stamp:v}=this.swarmSettings;if(!b)await this.writeOwnFeedDataByIndexOwned(u,h);else if(v)await this.writeOwnFeedDataByIndexEnvelope(u,h);else throw new Error("Enveloped mode is enabled, but stamp is not provided")}async writeOwnFeedDataByIndexOwned(u,h){const{bee:b,stamp:v,chatTopic:w}=this.swarmSettings,{privateKey:_,ownAddress:E}=this.userDetails,S=this.generateUserOwnedFeedId(w,E),x=beeJs.Topic.fromString(S);await b.makeFeedWriter(x,new beeJs.PrivateKey(_)).uploadPayload(v,JSON.stringify(h),{index:u})}async writeOwnFeedDataByIndexEnvelope(u,h){const{bee:b,stamp:v,chatTopic:w}=this.swarmSettings,{privateKey:_,ownAddress:E}=this.userDetails,S=new beeJs.PrivateKey(_),x=beeJs.Stamper.fromBlank(_,v,this.depth),T=this.generateUserOwnedFeedId(w,E),C=beeJs.Topic.fromString(T),O=makeFeedIdentifier(C,u),D=makeContentAddressedChunk(h),U=makeSingleOwnerChunk(D,O,S),te={hash:()=>U.address.toUint8Array()},X=x.stamp(te),{upload:ie}=b.makeSOCWriter(S),ee=beeJs.Bytes.fromUtf8(h);return(await ie(X,O,ee.toUint8Array())).reference.toHex()}orderMessages(u){return u.sort((h,b)=>h.timestamp-b.timestamp)}async downloadObjectFromBee(u){try{const{bee:h}=this.swarmSettings,b=await h.downloadData(u);return b?b.toJSON():null}catch(h){return this.errorHandler.handleError(h,"Utils.downloadObjectFromBee"),null}}async uploadObjectToBee(u){const{enveloped:h,stamp:b}=this.swarmSettings;if(h){if(b)return this.uploadObjectToBeeEnvelope(u);throw new Error("Enveloped mode is enabled, but stamp is not provided")}else return this.uploadObjectToBeeOwn(u)}async uploadObjectToBeeOwn(u){try{const{bee:h,stamp:b}=this.swarmSettings;return(await h.uploadData(b,JSON.stringify(u),{redundancyLevel:4})).reference.toString()}catch(h){return this.errorHandler.handleError(h,"Utils.uploadObjectToBee"),null}}async uploadObjectToBeeEnvelope(u){try{const{bee:h,stamp:b}=this.swarmSettings,{privateKey:v}=this.userDetails,w=beeJs.Stamper.fromBlank(v,b,this.depth),_=beeJs.Bytes.fromUtf8(JSON.stringify(u)),E=new MerkleTree(async x=>{await h.uploadChunk(w.stamp(x),x.build())});await E.append(_.toUint8Array());const S=await E.finalize();return Binary.uint8ArrayToHex(S.hash())}catch(h){return this.errorHandler.handleError(h,"Utils.uploadObjectToBee"),null}}async getOwnLatestFeedIndex(){try{const{bee:u,chatTopic:h}=this.swarmSettings,{ownAddress:b}=this.userDetails,v=this.generateUserOwnedFeedId(h,b),w=beeJs.Topic.fromString(v),E=await u.makeFeedReader(w,b).downloadPayload(),S=Number(E.feedIndex.toBigInt()),x=S+1;return{latestIndex:S,nextIndex:x}}catch(u){if(this.isNotFoundError(u))return{latestIndex:-1,nextIndex:0};throw u}}async fetchLatestChatMessage(){const{bee:u,chatTopic:h,chatAddress:b}=this.swarmSettings,w=await u.makeFeedReader(beeJs.Topic.fromString(h),remove0x(b)).downloadPayload();return{data:w.payload.toJSON(),index:w.feedIndex}}async fetchChatMessage(u){const{bee:h,chatTopic:b,chatAddress:v}=this.swarmSettings;return(await h.makeFeedReader(beeJs.Topic.fromString(b),remove0x(v)).downloadPayload({index:u})).payload.toJSON()}async sendMessageToGsoc(u){const{enveloped:h,stamp:b}=this.swarmSettings;if(!h)await this.sendMessageToGsocOwn(u);else if(b)await this.sendMessageToGsocEnvelope(u);else throw new Error("Enveloped mode is enabled, but stamp is not provided")}async rawSocDownload(u,h){const{beeUrl:b}=this.swarmSettings,v=await fetch(`${b}/soc/${u}/${h}`,{headers:{"swarm-chunk-retrieval-timeout":"2000ms"}});if(!v.ok){const w=new Error(`Failed to fetch: ${u}/${h} [${v.status}]`);throw w.status=v.status,w}return v.text()}async sendMessageToGsocOwn(u){const{bee:h,stamp:b,gsocTopic:v,gsocResourceId:w}=this.swarmSettings,_=new beeJs.PrivateKey(w),E=beeJs.Identifier.fromString(v),S=beeJs.Bytes.fromUtf8(u),{upload:x}=h.makeSOCWriter(_,{timeout:this.UPLOAD_GSOC_TIMEOUT});await x(b,E,S.toUint8Array())}async sendMessageToGsocEnvelope(u){const{bee:h,stamp:b,gsocTopic:v,gsocResourceId:w}=this.swarmSettings,{privateKey:_}=this.userDetails,E=beeJs.Stamper.fromBlank(_,b,this.depth),S=new beeJs.PrivateKey(w),x=beeJs.Identifier.fromString(v),T=beeJs.Bytes.fromUtf8(u),C=makeContentAddressedChunk(T.toUint8Array()),O=makeSingleOwnerChunk(C,x,S),D={hash:()=>O.address.toUint8Array()},U=E.stamp(D),{upload:te}=h.makeSOCWriter(S,{timeout:this.UPLOAD_GSOC_TIMEOUT});await te(U,x,T.toUint8Array())}}class SwarmChat{constructor(u){this.waku=null,this.isExternalWakuNode=!1,this.logger=Logger$2.getInstance(),this.errorHandler=ErrorHandler.getInstance(),this.gsocIndex=null,this.fetchProcessRunning=!1,this.stopFetch=!1;const h=new beeJs.PrivateKey(remove0x(u.user.privateKey));this.userDetails={privateKey:u.user.privateKey,ownAddress:h.publicKey().address().toString(),nickname:u.user.nickname,ownIndex:-1},this.swarmSettings={bee:new beeJs.Bee(u.infra.beeUrl),beeUrl:u.infra.beeUrl,stamp:u.infra.stamp||"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",enveloped:u.infra.enveloped,gsocTopic:u.infra.gsocTopic,gsocResourceId:u.infra.gsocResourceId,chatTopic:u.infra.chatTopic,chatAddress:u.infra.chatAddress,waku:u.infra.waku},this.emitter=new EventEmitter$3,this.utils=new SwarmChatUtils(this.userDetails,this.swarmSettings),this.history=new SwarmHistory(this.utils,this.emitter)}async start(){await this.init(),await this.startMessageFetchProcess()}async startMessageFetchProcess(){const{waku:u}=this.swarmSettings;u!=null&&u.enabled?await this.startWakuMessageFetch(u.node):await this.startPollingMessageFetch()}stop(){this.emitter.cleanAll(),this.stopPollingMessageFetch(),this.history.cleanup(),this.waku&&!this.isExternalWakuNode&&this.waku.stop(),this.waku=null}async startWakuMessageFetch(u){this.logger.info("Waku is enabled"),u&&(this.isExternalWakuNode=!0,this.logger.info("Using external Waku node instance"));const h=this.swarmSettings.chatTopic;if(this.waku=new Waku(h,v=>{this.emitter.emit(EVENTS.MESSAGE_RECEIVED,v)},u),!await this.waku.isReady())throw new Error("Waku node is not reachable")}getEmitter(){return this.emitter}orderMessages(u){return this.utils.orderMessages(u)}async sendMessage(u,h,b,v,w){const _=this.userDetails.ownIndex===-1?0:this.userDetails.ownIndex+1,E={id:v||v4$1(),username:this.userDetails.nickname,address:this.userDetails.ownAddress,chatTopic:this.swarmSettings.chatTopic,userTopic:this.utils.generateUserOwnedFeedId(this.swarmSettings.chatTopic,this.userDetails.ownAddress),signature:this.getSignature(u),timestamp:Date.now(),index:_,type:h,targetMessageId:b,message:u,additionalProps:w},S=validateMessageWithAdditionalProperties(E);if(!S.isValid){const x=`Invalid message: ${S.errors.join(", ")}`;throw this.logger.error(x),new Error(x)}try{this.emitter.emit(EVENTS.MESSAGE_REQUEST_INITIATED,E),await this.utils.writeOwnFeedDataByIndex(_,JSON.stringify(E)),this.userDetails.ownIndex=_,this.emitter.emit(EVENTS.MESSAGE_REQUEST_UPLOADED,E),await this.broadcastUserMessage(E)}catch(x){this.emitter.emit(EVENTS.MESSAGE_REQUEST_ERROR,E),this.errorHandler.handleError(x,"Chat.sendMessage")}}async fetchPreviousMessages(){try{return this.emitter.emit(EVENTS.LOADING_PREVIOUS_MESSAGES,!0),await this.history.fetchPreviousMessageState()}finally{this.emitter.emit(EVENTS.LOADING_PREVIOUS_MESSAGES,!1)}}hasPreviousMessages(){return this.history.hasPreviousMessages()}async retrySendMessage(u){this.sendMessage(u.message,u.type,u.targetMessageId,u.id,u.additionalProps)}async retryBroadcastUserMessage(u){await this.broadcastUserMessage(u)}async init(){try{this.emitter.emit(EVENTS.LOADING_INIT,!0);const[u,h]=await Promise.allSettled([this.initOwnIndex(),this.history.init()]);if(u.status==="rejected")throw u.reason;h.status==="fulfilled"&&(this.gsocIndex=h.value),this.emitter.emit(EVENTS.LOADING_INIT,!1)}catch(u){this.errorHandler.handleError(u,"Chat.initSelfState"),this.emitter.emit(EVENTS.CRITICAL_ERROR,u)}}async initOwnIndex(){const{latestIndex:b}=await retryAwaitableAsync(()=>this.utils.getOwnLatestFeedIndex(),10,1e3);this.userDetails.ownIndex=b}async fetchLatestMessage(){try{if(!this.gsocIndex)return;const u=beeJs.Topic.fromString(this.swarmSettings.chatTopic),h=makeFeedIdentifier(u,this.gsocIndex),b=await this.utils.rawSocDownload(this.swarmSettings.chatAddress,h.toString()),v=JSON.parse(b);if(!validateGsocMessage(v)){this.logger.warn("Invalid GSOC message during fetching");return}this.emitter.emit(EVENTS.MESSAGE_RECEIVED,v.message),this.gsocIndex=this.gsocIndex.next()}catch(u){if(this.utils.isNotFoundError(u))return;this.errorHandler.handleError(u,"Chat.fetchLatestMessage")}}async broadcastUserMessage(u){try{return retryAwaitableAsync(()=>this.utils.sendMessageToGsoc(JSON.stringify(u)))}catch(h){this.errorHandler.handleError(h,"Chat.broadcastUserMessage")}}getSignature(u){const{ownAddress:h,privateKey:b,nickname:v}=this.userDetails,w=new beeJs.EthAddress(h).toString(),_=new beeJs.PrivateKey(b);if(_.publicKey().address().toString()!==w)throw new Error("The provided address does not match the address derived from the private key");const S=Date.now();return _.sign(JSON.stringify({username:v,address:w,message:u,timestamp:S})).toHex()}async startPollingMessageFetch(){if(this.fetchProcessRunning)return;this.fetchProcessRunning=!0,this.stopFetch=!1;const u=async()=>{if(this.stopFetch){this.fetchProcessRunning=!1;return}await this.fetchLatestMessage(),setTimeout(u,200)};u()}stopPollingMessageFetch(){this.stopFetch=!0}}exports.EVENTS=EVENTS,exports.MessageType=MessageType,exports.SwarmChat=SwarmChat,Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"})});
112
+ `;let protoRoot=null,messagePayloadType=null;const errorHandler=ErrorHandler.getInstance();async function initializeProtobuf(){protoRoot||(protoRoot=protobufjs.Root.fromJSON(protobuf.parse(protoSchema).root),messagePayloadType=protoRoot.lookupType("MessagePayload"))}async function decodeMessagePayload(y){if(await initializeProtobuf(),!messagePayloadType)throw new Error("MessagePayload type not initialized");try{const u=messagePayloadType.decode(y),h=messagePayloadType.toObject(u,{longs:String,enums:String,defaults:!0});if(!h.message)throw new Error("Decoded object has no message field");let b=h.message.additionalProps;if(b&&typeof b=="string")try{b=JSON.parse(b)}catch{console.warn("Failed to parse additionalProps as JSON:",b)}const v={...h.message,timestamp:Number(h.message.timestamp),additionalProps:b},w=(h.messageStateRefs||[]).map(_=>({..._,timestamp:Number(_.timestamp)}));return{message:v,messageStateRefs:w}}catch(u){throw errorHandler.handleError(u,"ProtoMessage.decodeMessagePayload"),u}}class Waku{constructor(u,h,b){this.logger=Logger$2.getInstance(),this.errorHandler=ErrorHandler.getInstance(),this.wakuNode=null,this.handleWakuMessage=async({payload:v})=>{try{if(!v)return this.logger.warn("Received Waku message without payload");const{message:w}=await decodeMessagePayload(v);if(!(w!=null&&w.id))return this.logger.warn("Received invalid message structure via Waku");this.onMessage(w)}catch(w){this.errorHandler.handleError(w,"Waku.handleWakuMessage")}},this.chatTopic=u,this.onMessage=h,this.wakuNode=b||null,this.initPromise=this.init()}async init(){if(this.wakuNode=this.wakuNode??await this.createWakuLightNode(),!await this.subscribeToTopic())throw new Error("Failed to subscribe to Waku topic");this.logger.info(`Subscribed to Waku topic: ${this.chatTopic}`)}async createWakuLightNode(){const u=await createLightNode({defaultBootstrap:!0,networkConfig:{clusterId:WAKU_CLUSTER_ID}});return await u.start(),await u.waitForPeers([Protocols.LightPush,Protocols.Filter],3e4),this.logger.info(`Waku node ready: ${u.libp2p.peerId.toString()}`),u}createWakuDecoder(u){if(!(u!=null&&u.trim()))throw new Error("Topic name must be a non-empty string");const h={clusterId:WAKU_CLUSTER_ID,numShardsInCluster:8},b=`/solarpunk-msrs/1/${u}/proto`,v=createRoutingInfo(h,{contentTopic:b});return createDecoder(b,v)}async subscribeToTopic(){var u;if(!((u=this.wakuNode)!=null&&u.isStarted()))throw new Error("Waku node is not running");return this.wakuNode.filter.subscribe(this.createWakuDecoder(this.chatTopic),this.handleWakuMessage)}async isReady(){var u;try{return await this.initPromise,((u=this.wakuNode)==null?void 0:u.isStarted())??!1}catch{return!1}}async stop(){try{await this.initPromise,this.wakuNode&&(await this.wakuNode.stop(),this.wakuNode=null,this.logger.info("Waku node stopped successfully"))}catch(u){throw this.errorHandler.handleError(u,"Waku.stop"),u}}}class SwarmHistory{constructor(u,h){this.utils=u,this.emitter=h,this.logger=Logger$2.getInstance(),this.errorHandler=ErrorHandler.getInstance(),this.processedRefs=new Set,this.refRetryCount=new Map,this.bannedRefs=new Set,this.latestStatefulMessage=null,this.MAX_RETRIES=3,this.RETRY_DELAY=1e3}async init(){try{const{data:u,index:h}=await this.utils.fetchLatestChatMessage();this.latestStatefulMessage=u;try{await this.initMessageState(u)}catch(b){this.errorHandler.handleError(b,"SwarmHistory.initMessageState")}return h}catch(u){return this.errorHandler.handleError(u,"SwarmHistory.init"),beeJs.FeedIndex.fromBigInt(0n)}}async initMessageState(u){try{if(!validateGsocMessage(u)){this.logger.warn("Invalid GSOC message during message state initialization");return}if(!u.messageStateRefs||u.messageStateRefs.length===0){this.logger.debug("No message state refs to initialize");return}const h=this.findLatestRef(u.messageStateRefs);if(!h){this.logger.warn("No valid latest reference found");return}this.logger.debug("Initializing message state with latest ref:",h.reference),await this.processMessageRefWithRetry(h.reference)}catch(h){if(this.utils.isNotFoundError(h)){this.logger.debug("No latest GSOC message found for message state initialization");return}this.errorHandler.handleError(h,"SwarmHistory.init")}}async fetchPreviousMessageState(){let u=this.latestStatefulMessage;if(!u){const{data:b}=await this.utils.fetchLatestChatMessage();u=b,this.latestStatefulMessage=b}if(!u.messageStateRefs||u.messageStateRefs.length===0){this.logger.debug("No message state refs to fetch");return}const h=[...u.messageStateRefs].sort((b,v)=>b.timestamp-v.timestamp);for(const b of h)!this.processedRefs.has(b.reference)&&!this.bannedRefs.has(b.reference)&&(this.logger.debug("Fetching previous message ref:",b.reference),await this.processMessageRefWithRetry(b.reference))}findLatestRef(u){return u.length===0?null:u.reduce((h,b)=>b.timestamp>h.timestamp?b:h)}async processMessageRefWithRetry(u){if(!(this.processedRefs.has(u)||this.bannedRefs.has(u)))try{await this.processMessageRef(u)}catch(h){await this.handleRefError(u,h)}}async processMessageRef(u){const h=await this.utils.downloadObjectFromBee(u);if(!validateMessageState(h))throw new Error(`Invalid message state for ref: ${u}`);this.processedRefs.add(u),this.refRetryCount.delete(u);for(const v of h)this.emitter.emit(EVENTS.MESSAGE_RECEIVED,v)}async handleRefError(u,h){const b=this.refRetryCount.get(u)||0,v=b+1;if(this.logger.warn(`Error processing ref ${u} (attempt ${v}/${this.MAX_RETRIES}):`,h),v>=this.MAX_RETRIES)this.bannedRefs.add(u),this.refRetryCount.delete(u),this.logger.error(`Ref ${u} has been banned after ${this.MAX_RETRIES} failed attempts`),this.errorHandler.handleError(h,"SwarmHistory.processMessageRef");else{this.refRetryCount.set(u,v);const w=this.RETRY_DELAY*Math.pow(2,b);this.logger.debug(`Retrying ref ${u} after ${w}ms delay`),await sleep(w),await this.processMessageRefWithRetry(u)}}hasPreviousMessages(){return!!this.latestStatefulMessage&&!!this.latestStatefulMessage.messageStateRefs&&this.latestStatefulMessage.messageStateRefs.length>1}cleanup(){this.processedRefs.clear(),this.refRetryCount.clear(),this.bannedRefs.clear(),this.latestStatefulMessage=null}}class SwarmChatUtils{constructor(u,h){this.userDetails=u,this.swarmSettings=h,this.depth=26,this.errorHandler=ErrorHandler.getInstance(),this.UPLOAD_GSOC_TIMEOUT=2e3}generateUserOwnedFeedId(u,h){return`${u}_EthercastChat_${h}`}isNotFoundError(u){return u.stack.includes("404")||u.message.includes("Not Found")||u.message.includes("404")||u.code===404}async writeOwnFeedDataByIndex(u,h){const{enveloped:b,stamp:v}=this.swarmSettings;if(!b)await this.writeOwnFeedDataByIndexOwned(u,h);else if(v)await this.writeOwnFeedDataByIndexEnvelope(u,h);else throw new Error("Enveloped mode is enabled, but stamp is not provided")}async writeOwnFeedDataByIndexOwned(u,h){const{bee:b,stamp:v,chatTopic:w}=this.swarmSettings,{privateKey:_,ownAddress:E}=this.userDetails,S=this.generateUserOwnedFeedId(w,E),x=beeJs.Topic.fromString(S);await b.makeFeedWriter(x,new beeJs.PrivateKey(_)).uploadPayload(v,JSON.stringify(h),{index:u})}async writeOwnFeedDataByIndexEnvelope(u,h){const{bee:b,stamp:v,chatTopic:w}=this.swarmSettings,{privateKey:_,ownAddress:E}=this.userDetails,S=new beeJs.PrivateKey(_),x=beeJs.Stamper.fromBlank(_,v,this.depth),T=this.generateUserOwnedFeedId(w,E),C=beeJs.Topic.fromString(T),O=makeFeedIdentifier(C,u),D=makeContentAddressedChunk(h),U=makeSingleOwnerChunk(D,O,S),te={hash:()=>U.address.toUint8Array()},X=x.stamp(te),{upload:ie}=b.makeSOCWriter(S),ee=beeJs.Bytes.fromUtf8(h);return(await ie(X,O,ee.toUint8Array())).reference.toHex()}orderMessages(u){return u.sort((h,b)=>h.timestamp-b.timestamp)}async downloadObjectFromBee(u){try{const{bee:h}=this.swarmSettings,b=await h.downloadData(u);return b?b.toJSON():null}catch(h){return this.errorHandler.handleError(h,"Utils.downloadObjectFromBee"),null}}async uploadObjectToBee(u){const{enveloped:h,stamp:b}=this.swarmSettings;if(h){if(b)return this.uploadObjectToBeeEnvelope(u);throw new Error("Enveloped mode is enabled, but stamp is not provided")}else return this.uploadObjectToBeeOwn(u)}async uploadObjectToBeeOwn(u){try{const{bee:h,stamp:b}=this.swarmSettings;return(await h.uploadData(b,JSON.stringify(u),{redundancyLevel:4})).reference.toString()}catch(h){return this.errorHandler.handleError(h,"Utils.uploadObjectToBee"),null}}async uploadObjectToBeeEnvelope(u){try{const{bee:h,stamp:b}=this.swarmSettings,{privateKey:v}=this.userDetails,w=beeJs.Stamper.fromBlank(v,b,this.depth),_=beeJs.Bytes.fromUtf8(JSON.stringify(u)),E=new MerkleTree(async x=>{await h.uploadChunk(w.stamp(x),x.build())});await E.append(_.toUint8Array());const S=await E.finalize();return Binary.uint8ArrayToHex(S.hash())}catch(h){return this.errorHandler.handleError(h,"Utils.uploadObjectToBee"),null}}async getOwnLatestFeedIndex(){try{const{bee:u,chatTopic:h}=this.swarmSettings,{ownAddress:b}=this.userDetails,v=this.generateUserOwnedFeedId(h,b),w=beeJs.Topic.fromString(v),E=await u.makeFeedReader(w,b).downloadPayload(),S=Number(E.feedIndex.toBigInt()),x=S+1;return{latestIndex:S,nextIndex:x}}catch(u){if(this.isNotFoundError(u))return{latestIndex:-1,nextIndex:0};throw u}}async fetchLatestChatMessage(){const{bee:u,chatTopic:h,chatAddress:b}=this.swarmSettings,w=await u.makeFeedReader(beeJs.Topic.fromString(h),remove0x(b)).downloadPayload();return{data:w.payload.toJSON(),index:w.feedIndex}}async fetchChatMessage(u){const{bee:h,chatTopic:b,chatAddress:v}=this.swarmSettings;return(await h.makeFeedReader(beeJs.Topic.fromString(b),remove0x(v)).downloadPayload({index:u})).payload.toJSON()}async sendMessageToGsoc(u){const{enveloped:h,stamp:b}=this.swarmSettings;if(!h)await this.sendMessageToGsocOwn(u);else if(b)await this.sendMessageToGsocEnvelope(u);else throw new Error("Enveloped mode is enabled, but stamp is not provided")}async rawSocDownload(u,h){const{beeUrl:b}=this.swarmSettings,v=await fetch(`${b}/soc/${u}/${h}`,{headers:{"swarm-chunk-retrieval-timeout":"2000ms"}});if(!v.ok){const w=new Error(`Failed to fetch: ${u}/${h} [${v.status}]`);throw w.status=v.status,w}return v.text()}async sendMessageToGsocOwn(u){const{bee:h,stamp:b,gsocTopic:v,gsocResourceId:w}=this.swarmSettings,_=new beeJs.PrivateKey(w),E=beeJs.Identifier.fromString(v),S=beeJs.Bytes.fromUtf8(u),{upload:x}=h.makeSOCWriter(_,{timeout:this.UPLOAD_GSOC_TIMEOUT});await x(b,E,S.toUint8Array())}async sendMessageToGsocEnvelope(u){const{bee:h,stamp:b,gsocTopic:v,gsocResourceId:w}=this.swarmSettings,{privateKey:_}=this.userDetails,E=beeJs.Stamper.fromBlank(_,b,this.depth),S=new beeJs.PrivateKey(w),x=beeJs.Identifier.fromString(v),T=beeJs.Bytes.fromUtf8(u),C=makeContentAddressedChunk(T.toUint8Array()),O=makeSingleOwnerChunk(C,x,S),D={hash:()=>O.address.toUint8Array()},U=E.stamp(D),{upload:te}=h.makeSOCWriter(S,{timeout:this.UPLOAD_GSOC_TIMEOUT});await te(U,x,T.toUint8Array())}}class SwarmChat{constructor(u){this.waku=null,this.isExternalWakuNode=!1,this.logger=Logger$2.getInstance(),this.errorHandler=ErrorHandler.getInstance(),this.gsocIndex=null,this.fetchProcessRunning=!1,this.stopFetch=!1;const h=new beeJs.PrivateKey(remove0x(u.user.privateKey));this.userDetails={privateKey:u.user.privateKey,ownAddress:h.publicKey().address().toString(),nickname:u.user.nickname,ownIndex:-1},this.swarmSettings={bee:new beeJs.Bee(u.infra.beeUrl),beeUrl:u.infra.beeUrl,stamp:u.infra.stamp||"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",enveloped:u.infra.enveloped,gsocTopic:u.infra.gsocTopic,gsocResourceId:u.infra.gsocResourceId,chatTopic:u.infra.chatTopic,chatAddress:u.infra.chatAddress,waku:u.infra.waku},this.emitter=new EventEmitter$3,this.utils=new SwarmChatUtils(this.userDetails,this.swarmSettings),this.history=new SwarmHistory(this.utils,this.emitter)}async start(){await this.init(),await this.startMessageFetchProcess()}async startMessageFetchProcess(){const{waku:u}=this.swarmSettings;u!=null&&u.enabled?await this.startWakuMessageFetch(u.node):await this.startPollingMessageFetch()}stop(){this.emitter.cleanAll(),this.stopPollingMessageFetch(),this.history.cleanup(),this.waku&&!this.isExternalWakuNode&&this.waku.stop(),this.waku=null}async startWakuMessageFetch(u){this.logger.info("Waku is enabled"),u&&(this.isExternalWakuNode=!0,this.logger.info("Using external Waku node instance"));const h=this.swarmSettings.chatTopic;this.waku=new Waku(h,b=>{this.emitter.emit(EVENTS.MESSAGE_RECEIVED,b)},u)}getEmitter(){return this.emitter}orderMessages(u){return this.utils.orderMessages(u)}async sendMessage(u,h,b,v,w){const _=this.userDetails.ownIndex===-1?0:this.userDetails.ownIndex+1,E={id:v||v4$1(),username:this.userDetails.nickname,address:this.userDetails.ownAddress,chatTopic:this.swarmSettings.chatTopic,userTopic:this.utils.generateUserOwnedFeedId(this.swarmSettings.chatTopic,this.userDetails.ownAddress),signature:this.getSignature(u),timestamp:Date.now(),index:_,type:h,targetMessageId:b,message:u,additionalProps:w},S=validateMessageWithAdditionalProperties(E);if(!S.isValid){const x=`Invalid message: ${S.errors.join(", ")}`;throw this.logger.error(x),new Error(x)}try{this.emitter.emit(EVENTS.MESSAGE_REQUEST_INITIATED,E),await this.utils.writeOwnFeedDataByIndex(_,JSON.stringify(E)),this.userDetails.ownIndex=_,this.emitter.emit(EVENTS.MESSAGE_REQUEST_UPLOADED,E),await this.broadcastUserMessage(E)}catch(x){this.emitter.emit(EVENTS.MESSAGE_REQUEST_ERROR,E),this.errorHandler.handleError(x,"Chat.sendMessage")}}async fetchPreviousMessages(){try{return this.emitter.emit(EVENTS.LOADING_PREVIOUS_MESSAGES,!0),await this.history.fetchPreviousMessageState()}finally{this.emitter.emit(EVENTS.LOADING_PREVIOUS_MESSAGES,!1)}}hasPreviousMessages(){return this.history.hasPreviousMessages()}async retrySendMessage(u){this.sendMessage(u.message,u.type,u.targetMessageId,u.id,u.additionalProps)}async retryBroadcastUserMessage(u){await this.broadcastUserMessage(u)}async init(){try{this.emitter.emit(EVENTS.LOADING_INIT,!0);const[u,h]=await Promise.allSettled([this.initOwnIndex(),this.history.init()]);if(u.status==="rejected")throw u.reason;h.status==="fulfilled"&&(this.gsocIndex=h.value),this.emitter.emit(EVENTS.LOADING_INIT,!1)}catch(u){this.errorHandler.handleError(u,"Chat.initSelfState"),this.emitter.emit(EVENTS.CRITICAL_ERROR,u)}}async initOwnIndex(){const{latestIndex:b}=await retryAwaitableAsync(()=>this.utils.getOwnLatestFeedIndex(),10,1e3);this.userDetails.ownIndex=b}async fetchLatestMessage(){try{if(!this.gsocIndex)return;const u=beeJs.Topic.fromString(this.swarmSettings.chatTopic),h=makeFeedIdentifier(u,this.gsocIndex),b=await this.utils.rawSocDownload(this.swarmSettings.chatAddress,h.toString()),v=JSON.parse(b);if(!validateGsocMessage(v)){this.logger.warn("Invalid GSOC message during fetching");return}this.emitter.emit(EVENTS.MESSAGE_RECEIVED,v.message),this.gsocIndex=this.gsocIndex.next()}catch(u){if(this.utils.isNotFoundError(u))return;this.errorHandler.handleError(u,"Chat.fetchLatestMessage")}}async broadcastUserMessage(u){try{return retryAwaitableAsync(()=>this.utils.sendMessageToGsoc(JSON.stringify(u)))}catch(h){this.errorHandler.handleError(h,"Chat.broadcastUserMessage")}}getSignature(u){const{ownAddress:h,privateKey:b,nickname:v}=this.userDetails,w=new beeJs.EthAddress(h).toString(),_=new beeJs.PrivateKey(b);if(_.publicKey().address().toString()!==w)throw new Error("The provided address does not match the address derived from the private key");const S=Date.now();return _.sign(JSON.stringify({username:v,address:w,message:u,timestamp:S})).toHex()}async startPollingMessageFetch(){if(this.fetchProcessRunning)return;this.fetchProcessRunning=!0,this.stopFetch=!1;const u=async()=>{if(this.stopFetch){this.fetchProcessRunning=!1;return}await this.fetchLatestMessage(),setTimeout(u,200)};u()}stopPollingMessageFetch(){this.stopFetch=!0}}exports.EVENTS=EVENTS,exports.MessageType=MessageType,exports.SwarmChat=SwarmChat,Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"})});
@@ -1 +1 @@
1
- {"version":3,"file":"ProtoMessage.d.ts","sourceRoot":"","sources":["../../src/waku/ProtoMessage.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAiBrE,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,gBAAgB,EAAE,eAAe,EAAE,CAAA;CAAE,CAAC,CA+CxE"}
1
+ {"version":3,"file":"ProtoMessage.d.ts","sourceRoot":"","sources":["../../src/waku/ProtoMessage.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAiBrE,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,gBAAgB,EAAE,eAAe,EAAE,CAAA;CAAE,CAAC,CA4CxE"}
@@ -1 +1 @@
1
- {"version":3,"file":"Waku.d.ts","sourceRoot":"","sources":["../../src/waku/Waku.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,SAAS,EAAa,MAAM,WAAW,CAAC;AAGhH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAMvD,qBAAa,IAAI;IACf,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA8B;IAC3D,OAAO,CAAC,QAAQ,CAA0B;IAE1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IACvD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,WAAW,CAAgB;gBAEvB,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS;YAOxE,IAAI;YAMJ,mBAAmB;IAajC,OAAO,CAAC,iBAAiB;YAaX,gBAAgB;IAK9B,OAAO,CAAC,iBAAiB,CAWvB;IAEW,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAS3B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAanC"}
1
+ {"version":3,"file":"Waku.d.ts","sourceRoot":"","sources":["../../src/waku/Waku.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,SAAS,EAAa,MAAM,WAAW,CAAC;AAGhH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAMvD,qBAAa,IAAI;IACf,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA8B;IAC3D,OAAO,CAAC,QAAQ,CAA0B;IAE1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IACvD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,WAAW,CAAgB;gBAEvB,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS;YAOxE,IAAI;YAMJ,mBAAmB;IAajC,OAAO,CAAC,iBAAiB;YAcX,gBAAgB;IAK9B,OAAO,CAAC,iBAAiB,CAWvB;IAEW,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAS3B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAanC"}
@@ -1,2 +1,2 @@
1
- export declare const protoSchema = "\nsyntax = \"proto3\";\n\nenum MessageType {\n TEXT = 0;\n THREAD = 1;\n REACTION = 2;\n}\n\nmessage MessageData {\n string id = 1;\n optional string targetMessageId = 2;\n MessageType type = 3;\n string message = 4;\n string username = 5;\n string address = 6;\n uint64 timestamp = 7;\n string signature = 8;\n uint32 index = 9;\n string chatTopic = 10;\n string userTopic = 11;\n optional string additionalProps = 12;\n}\n\nmessage MessageStateRef {\n string reference = 1;\n uint64 timestamp = 2;\n}\n\nmessage MessagePayload {\n MessageData message = 1;\n repeated MessageStateRef messageStateRefs = 2;\n}\n";
1
+ export declare const protoSchema = "\nsyntax = \"proto3\";\n\nmessage MessageData {\n string id = 1;\n optional string targetMessageId = 2;\n string type = 3;\n string message = 4;\n string username = 5;\n string address = 6;\n uint64 timestamp = 7;\n string signature = 8;\n uint32 index = 9;\n string chatTopic = 10;\n string userTopic = 11;\n optional string additionalProps = 12;\n}\n\nmessage MessageStateRef {\n string reference = 1;\n uint64 timestamp = 2;\n}\n\nmessage MessagePayload {\n MessageData message = 1;\n repeated MessageStateRef messageStateRefs = 2;\n}\n";
2
2
  //# sourceMappingURL=message.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/waku/message.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,WAAW,2nBAiCvB,CAAC"}
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/waku/message.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,WAAW,gjBA2BvB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solarpunkltd/swarm-chat-js",
3
- "version": "6.0.6",
3
+ "version": "6.0.8",
4
4
  "description": "JS library for chatting on Swarm",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",