@solarpunkltd/swarm-chat-js 9.0.0 → 10.0.0

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.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./message-DBi9VeRs.cjs");let t=require("@ethersphere/bee-js");var n={LOADING_INIT:`loadingInit`,LOADING_PREVIOUS_MESSAGES:`loadingPreviousMessages`,MESSAGE_RECEIVED:`messageReceived`,MESSAGE_REQUEST_INITIATED:`messageRequestInitiated`,MESSAGE_REQUEST_UPLOADED:`messageRequestUploaded`,MESSAGE_REQUEST_ERROR:`messageRequestError`,CRITICAL_ERROR:`criticalError`,STATUS:`status`,MESSAGE_SKIPPED:`messageSkipped`,ERROR:`error`};function r(e){return a(e,-1,e.ts)}function i(e){return a(e.msg,e.seq,e.at)}function a(e,t,n){return{id:e.id,type:e.type,message:e.text,username:e.name,address:e.addr,timestamp:n,...e.target?{targetMessageId:e.target}:{},index:t,signedMessage:e}}var o=class{constructor(){this.listeners=new Map,this.on=(e,t)=>{this.listeners.set(e,[...this.listeners.get(e)??[],t])},this.off=(e,t)=>{this.listeners.set(e,(this.listeners.get(e)??[]).filter(e=>e!==t))},this.cleanAll=()=>{this.listeners.clear()}}emit(e,t){for(let n of this.listeners.get(e)??[])try{n(t)}catch(t){console.error(`a listener for ${e} threw`,t)}}},s=2e4,c=class{constructor(e,t){this.spacingMs=e,this.now=t,this.missedAt=new Map}readableAt(e,t=this.now()){let n=this.missedAt.get(e);return n===void 0||this.expired(n,t)?-1/0:n+this.spacingMs}mayRead(e,t=this.now()){return t>=this.readableAt(e,t)}missed(e,t=this.now()){for(let[e,n]of this.missedAt)this.expired(n,t)&&this.missedAt.delete(e);this.missedAt.set(e,t)}found(e){this.missedAt.delete(e)}clear(){this.missedAt.clear()}expired(e,t){return e>t||t-e>=this.spacingMs}},l=class extends Error{constructor(e){super(`the feed head lookup did not answer in time`,e),this.name=`HeadLookupTimeoutError`}},u=class extends Error{constructor(e,t){super(`feed slot ${e} was served but could not be read`,t),this.index=e,this.name=`UnreadableSlotError`}};function d(e){return e instanceof t.BeeResponseError&&(e.status===404||e.status===500)}async function f(e,n){try{return await n()}catch(n){if(d(n))return null;throw n instanceof t.BeeResponseError?n:new u(e,{cause:n})}}function p(n,r,i,a,o=e.n){let s=t.Topic.fromString(i),c=e=>n.feed.makeReader(s,r,m(e));return{readNote:t=>f(t,async()=>(await n.soc.makeReader(r,m(a.slotReadMs)).download(e.s(i,o,t))).payload.toUint8Array()),readSlot:e=>f(e,async()=>(await c(a.slotReadMs).downloadPayload({index:e})).payload.toUint8Array()),async readHead(){let e=m(a.feedReadMs);try{let{payload:t,feedIndex:i}=await n.feed.makeReader(s,r,e).downloadPayload();return{index:Number(i.toBigInt()),payload:t.toUint8Array()}}catch(t){if(d(t))return null;throw e.signal?.aborted?new l({cause:t}):t}},async readFile(e){return(await n.data.download(e,void 0,m(a.feedReadMs))).toUint8Array()}}}function m(e){return{signal:AbortSignal.timeout(e)}}var h=`0123456789abcdef`.repeat(4);function g(e,n,r,i,a){let o=new t.PrivateKey(r),s=t.Identifier.fromString(i);return async t=>{await e.messaging.gsocSend(n,o,s,t,{deferred:!1},m(a.writeMs))}}var _={LIVE:`live`,RECONNECTING:`reconnecting`,STALLED:`stalled`},v={pollIntervalMs:1e3,missingReadSpacingMs:s,maxSlotsPerPoll:16,unservedPollsBeforeProbe:3,unreadablePollsBeforeFailure:3,probeIntervalCapMs:6e4,probeDistances:[1,2,4,8],missedLimit:32,missedReadsPerPoll:4,missedExpiryMs:3e5,backoffCapMs:8e3,stallAfterMs:8e3,random:Math.random,now:Date.now},y=class extends Error{constructor(e){super(`the gateway keeps answering feed slot ${e} with something that is not a chunk`),this.index=e,this.name=`UnreadableGatewayError`}},b=class{constructor(e,t,n,r={},i=null){this.source=e,this.topic=t,this.events=n,this.notes=i,this.next=0,this.ceiling=null,this.nextNoteSlot=0,this.lastNoteFoundAt=0,this.unservedPolls=0,this.nextProbeAt=0,this.unreadablePolls=0,this.gatewayFailures=0,this.missed=new Map,this.timer=null,this.generation=0,this.running=!1,this.status=null,this.settings={...v,...r},this.pacer=new c(this.settings.missingReadSpacingMs,this.settings.now)}get nextIndex(){return this.next}get missedIndices(){return[...this.missed.keys()]}get ledByNotes(){return this.ceiling!==null}start(e,t=null){this.stop(),this.next=e,this.ceiling=t?.newest??null,this.nextNoteSlot=t?.nextNoteSlot??(this.notes?this.notes.lastReadableSlot()+1:0),this.lastNoteFoundAt=this.settings.now(),this.resetRefusals(),this.unreadablePolls=0,this.gatewayFailures=0,this.missed.clear(),this.pacer.clear(),this.status=null,this.running=!0,this.schedule(0)}stop(){this.running=!1,this.generation++,this.timer&&=(clearTimeout(this.timer),null)}schedule(e){let t=this.generation;this.timer=setTimeout(()=>{this.timer=null,this.poll(t)},e)}async poll(e){let t=0,n=!1;try{this.notes!==null&&await this.readDueNotes(this.notes,e),t=await this.walk(e),await this.readMissed(e)}catch(t){n=!0,e===this.generation&&this.gatewayFailed(t)}if(e===this.generation&&this.running){if(n){this.schedule(this.backoffMs());return}this.gatewayAnswered(),this.schedule(t>=this.settings.maxSlotsPerPoll?0:this.untilNextRead())}}untilNextRead(){let e=this.settings.now(),t=t=>{let n=this.pacer.readableAt(t);return n>e?n:e+this.settings.pollIntervalMs},n=[...this.missed.keys()].map(t);return this.notes!==null&&n.push(this.notes.readableAt(this.nextNoteSlot)),this.ceiling===null&&n.push(t(this.next)),Math.max(0,Math.min(...n)-e)}async readDueNotes(e,t){let n=this.settings.now(),r=e.lastReadableSlot(n);if(r<this.nextNoteSlot)return;let i=Math.max(this.nextNoteSlot,r-e.lookBackSlots+1),a=await e.scan(r,i);if(t===this.generation){if(this.nextNoteSlot=r+1,a){this.lastNoteFoundAt=n,this.ceiling=Math.max(this.ceiling??-1,a.note.newest,this.next-1);return}n-this.lastNoteFoundAt>=e.silenceMs&&(this.lastNoteFoundAt=n,e.clock.distrust(),this.nextNoteSlot=Math.min(this.nextNoteSlot,e.lastReadableSlot(n)+1))}}async read(e){let t;try{t=await this.source.readSlot(e)}catch(e){if(e instanceof u)return`unreadable`;throw e}return t===null?this.pacer.missed(e):this.pacer.found(e),t}async readUnnamed(e){return this.pacer.mayRead(e)?this.read(e):`held`}async walk(e){for(let t=0;t<this.settings.maxSlotsPerPoll;t++){let n=this.next;if(this.ceiling!==null&&n>this.ceiling)return t;let r=this.ceiling===null?await this.readUnnamed(n):await this.read(n);if(e!==this.generation||r===`held`)return t;if(this.ceiling!==null&&(r===null||r===`unreadable`)){this.remember(n),this.next=n+1;continue}if(r===null||r===`unreadable`){if(t===0){if(this.unservedPolls++,this.unreadablePolls=r===`unreadable`?this.unreadablePolls+1:0,this.shouldProbe()&&await this.probePast(n,e)){this.unreadablePolls=0;continue}if(this.unreadablePolls>=this.settings.unreadablePollsBeforeFailure)throw new y(n)}return t}this.resetRefusals(),this.unreadablePolls=0,this.next=n+1,this.accept(n,r)}return this.settings.maxSlotsPerPoll}shouldProbe(){if(this.unservedPolls!==this.nextProbeAt)return!1;let{probeIntervalCapMs:e,pollIntervalMs:t,missingReadSpacingMs:n}=this.settings,r=Math.max(1,Math.ceil(e/Math.max(t,n)));return this.nextProbeAt+=Math.min(this.nextProbeAt,r),!0}resetRefusals(){this.unservedPolls=0,this.nextProbeAt=this.settings.unservedPollsBeforeProbe}async probePast(e,t){let n=new Set([e]);for(let r of this.settings.probeDistances){let i=e+r,a=await this.readUnnamed(i);if(t!==this.generation)return!1;if(a===null||a===`unreadable`||a===`held`){n.add(i);continue}this.resetRefusals(),this.remember(e);for(let r=e+1;r<i;r++){let e=n.has(r)?null:await this.readUnnamed(r);if(t!==this.generation)return!1;e===null||e===`unreadable`||e===`held`?this.remember(r):this.accept(r,e)}return this.next=i+1,this.accept(i,a),!0}return!1}remember(e){if(!this.missed.has(e)){if(this.missed.size>=this.settings.missedLimit){this.events.skipped(e,`unreachable`,`stepped past with the retry list full`);return}this.missed.set(e,this.settings.now())}}async readMissed(e){let t=this.settings.now();for(let[e,n]of this.missed)t-n>=this.settings.missedExpiryMs&&(this.missed.delete(e),this.events.skipped(e,`unreachable`,`not served within the time a stepped-past slot is kept`));let n=[...this.missed.keys()].filter(e=>this.pacer.mayRead(e,t)).slice(0,this.settings.missedReadsPerPoll);for(let t of n){let n=await this.read(t);if(e!==this.generation)return;let r=this.missed.get(t);this.missed.delete(t),n!==null&&n!==`unreadable`?this.accept(t,n):r!==void 0&&this.missed.set(t,r)}}accept(t,n){let r=e.v(n,t,this.topic);r.ok?(this.notes?.clock.observe(r.value.at,this.settings.now()),this.events.entry(r.value)):this.events.skipped(t,r.reason,r.detail)}gatewayFailed(e){this.gatewayFailures++,this.setStatus(_.RECONNECTING),this.events.error(e)}gatewayAnswered(){this.gatewayFailures=0;let e=this.settings.now(),t=[...this.missed.values()].some(t=>e-t>=this.settings.stallAfterMs);this.setStatus(t?_.STALLED:_.LIVE)}backoffMs(){let{pollIntervalMs:e,backoffCapMs:t,random:n}=this.settings,r=Math.min(t,e*2**this.gatewayFailures);return r/2+n()*r/2}setStatus(e){e!==this.status&&(this.status=e,this.events.status(e))}},x=16,S=class{constructor(e,t,n,r=null){this.source=e,this.topic=t,this.events=n,this.notes=r,this.older=null,this.loading=null}async open(){this.older=null;let e=await this.newestNote();if(e!==null)return this.openAt(e.newest,e);let t=await this.readHead();return t===null?{startAt:0,rows:[],notes:null}:this.openAt(t.index,null,t.payload)}async newestNote(){if(this.notes===null)return null;let e=this.notes.lastReadableSlot(),t=await this.notes.scan(e,e-this.notes.lookBackSlots+1);return t===null?null:{newest:t.note.newest,nextNoteSlot:e+1}}async openAt(e,t,n){let r=e<0?null:await this.newestLink(e,n);if(r===null)return{startAt:0,rows:[],notes:t};let i=await this.readFile(r);return i===`refused`?{startAt:0,rows:[],notes:t}:{startAt:r.toSeq+1,rows:i??[],notes:t}}async readHead(){try{return await this.source.readHead()}catch(e){if(e instanceof l)return this.events.error(e),null;throw e}}hasOlder(){return this.older!==null}loadOlder(){return this.loading??=this.loadOlderOnce().finally(()=>{this.loading=null}),this.loading}async loadOlderOnce(){let t=this.older;if(t===null)return[];let n=await this.source.readFile(t.ref),r=e.y(n,this.topic,t);if(!r.ok)throw this.older=null,Error(`history file ${t.ref} refused (${r.reason}): ${r.detail}`);return this.report(r.value.skipped),this.older=r.value.prev,r.value.rows}async newestLink(t,n){let r=n===void 0?t:t-1;if(n!==void 0){let r=e.v(n,t,this.topic);if(r.ok)return r.value.history}for(let n=r;n>=Math.max(0,t-x);n--){let t=await this.source.readSlot(n).catch(e=>{if(e instanceof u)return null;throw e});if(t===null)continue;let r=e.v(t,n,this.topic);if(r.ok)return r.value.history}return null}async readFile(t){try{let n=e.y(await this.source.readFile(t.ref),this.topic,t);return n.ok?(this.report(n.value.skipped),this.older=n.value.prev,n.value.rows):(this.events.error(Error(`history file ${t.ref} refused (${n.reason}): ${n.detail}`)),`refused`)}catch(e){return this.events.error(e),this.older=t,null}}report(e){e>0&&this.events.skipped(e)}},C={slotMs:e.n,heartbeatMs:e.t,marginMs:1e3,scanBatch:4,clockLimitMs:3e5,missingReadSpacingMs:s};function w(e){return typeof e.readNote==`function`}var T=class{constructor(e){this.limitMs=e,this.aheadAtMost=1/0,this.trusted=!0}observe(e,t){this.aheadAtMost=Math.min(this.aheadAtMost,t-e)}distrust(){this.trusted=!1}get isTrusted(){return this.trusted}get ms(){let e=Number.isFinite(this.aheadAtMost),t=this.trusted||!e?Math.min(0,this.aheadAtMost):this.aheadAtMost;return Math.max(-this.limitMs,Math.min(this.limitMs,t))}},E=class{constructor(e,t,n){this.source=e,this.now=n,this.counts={found:0,empty:0},this.settings={...C,...t},this.clock=new T(this.settings.clockLimitMs),this.pacer=new c(this.settings.missingReadSpacingMs,n)}lastReadableSlot(t=this.now()){return e.u(t-this.settings.marginMs-this.clock.ms,this.settings.slotMs)-1}readableAt(t){return e.l(t,this.settings.slotMs)+this.settings.marginMs+this.clock.ms}get lookBackSlots(){return Math.ceil(this.settings.heartbeatMs/this.settings.slotMs)+2}get silenceMs(){return this.settings.heartbeatMs+2*this.settings.slotMs+this.settings.marginMs}async read(t){if(!this.pacer.mayRead(t))return null;let n;try{n=await this.source.readNote(t),n===null&&this.pacer.missed(t)}catch(e){if(!(e instanceof u))throw e;n=null}let r=n===null?null:e.d(n);return r===null?(this.counts.empty++,null):(this.counts.found++,this.clock.observe(r.writtenAt,this.now()),r)}async scan(e,t){for(let n=e;n>=t;n-=this.settings.scanBatch){let e=[];for(let r=n;r>n-this.settings.scanBatch&&r>=t;r--)e.push(r);let r=await Promise.all(e.map(e=>this.read(e))),i=r.findIndex(e=>e!==null);if(i>=0)return{slot:e[i],note:r[i]}}return null}},D={resendAfterMs:1e4,maxResends:5,reactionWindowMs:1e3,isLive:()=>!0},O=class{constructor(e,t,n,r,i=D){this.key=e,this.profile=t,this.write=n,this.events=r,this.settings=i,this.outgoing=new Map,this.reactions=new Map,this.stopped=!1}get address(){return this.key.publicKey().address().toHex()}send(t){let{message:n,bytes:r}=e.M(this.key,{...t,...this.profile}),i={message:n,bytes:r,writes:0,written:!1,inFlight:!1,timer:null,lastError:null};return this.outgoing.set(n.id,i),this.events.pending(n),this.attempt(i),n}react(t,n,r){let i=JSON.stringify([t,n,r]),a=this.reactions.get(i);if(a){a.taps++;return}let o=setTimeout(()=>{let a=this.reactions.get(i);this.reactions.delete(i),a&&a.taps%2==1&&!this.stopped&&this.send({topic:t,type:e.O.REACTION,target:n,text:r})},this.settings.reactionWindowMs);this.reactions.set(i,{taps:1,timer:o})}confirm(e){if(e.addr!==this.address)return;let t=this.outgoing.get(e.id);t&&(this.clearTimer(t),this.outgoing.delete(e.id),this.events.confirmed(t.message))}retry(e){let t=this.outgoing.get(e);return!t||this.stopped?!1:(this.clearTimer(t),t.writes=0,t.inFlight||this.attempt(t),!0)}isPending(e){return this.outgoing.has(e)}stop(){this.stopped=!0;for(let e of this.outgoing.values())this.clearTimer(e);for(let{timer:e}of this.reactions.values())clearTimeout(e);this.reactions.clear()}attempt(e){!this.stopped&&this.outgoing.has(e.message.id)&&(e.writes++,e.inFlight=!0,this.write(e.bytes).then(()=>{e.inFlight=!1,!e.written&&this.outgoing.has(e.message.id)&&(e.written=!0,this.events.written(e.message)),this.scheduleNext(e)},t=>{e.inFlight=!1,e.lastError=t,this.scheduleNext(e)}))}scheduleNext(e){!this.stopped&&this.outgoing.has(e.message.id)&&(e.timer=setTimeout(()=>{if(e.timer=null,!this.settings.isLive()){this.scheduleNext(e);return}if(e.writes>this.settings.maxResends){this.events.failed(e.message,e.lastError??Error(`never seen on the chat feed`));return}this.attempt(e)},this.settings.resendAfterMs))}clearTimer(e){e.timer&&=(clearTimeout(e.timer),null)}},k=[1e3,2e3,4e3,8e3],A=3;function j(e){return(e.startsWith(`0x`)?e.slice(2):e).toLowerCase()}var M=class{constructor(e,r={}){this.emitter=new o,this.seen=new Set,this.status=null,this.generation=0,this.running=!1,this.starting=null,this.openTimer=null,this.wakeOpen=null;let{user:i,infra:a}=e;this.key=new t.PrivateKey(j(i.privateKey)),this.topic=a.chatTopic,this.profile={name:i.nickname,via:a.via,...i.binding?{idb:i.binding}:{},...i.walletLink?{wl:i.walletLink}:{}},this.openRetryMs=r.openRetryMs??k,this.senderSettings={...D,isLive:()=>this.status===_.LIVE,...r.sender};let s={slotReadMs:a.socReadTimeout??5e3,feedReadMs:a.feedReadTimeout??15e3,writeMs:a.gsocWriteTimeout??1e4},c={...a.noteSlotMs===void 0?{}:{slotMs:a.noteSlotMs},...a.noteHeartbeatMs===void 0?{}:{heartbeatMs:a.noteHeartbeatMs},...r.notes};this.source=r.source??p(new t.Bee(a.beeUrl),j(a.chatAddress),a.chatTopic,s,c.slotMs),this.write=r.write??g(new t.Bee(a.writeUrl??a.beeUrl),a.stamp?j(a.stamp):h,j(a.gsocResourceId),a.gsocTopic,s);let l=r.follower?.now??(()=>Date.now()),u={pollIntervalMs:a.pollingInterval??1e3,...r.follower,now:l},d=this.source;this.notes=w(d)?new E(d,c,l):null,this.follower=new b(this.source,this.topic,{entry:e=>this.show(e),skipped:(e,t,r)=>this.emitter.emit(n.MESSAGE_SKIPPED,{index:e,reason:t,detail:r}),status:e=>this.setStatus(e),error:e=>this.emitter.emit(n.ERROR,e)},u,this.notes),this.history=new S(this.source,this.topic,{skipped:e=>this.emitter.emit(n.MESSAGE_SKIPPED,{index:-1,reason:`history-row`,detail:`${e} rows of a history file`}),error:e=>this.emitter.emit(n.ERROR,e)},this.notes),this.sender=this.makeSender()}getEmitter(){return this.emitter}getStatus(){return this.status}getAddress(){return this.key.publicKey().address().toHex()}start(){if(this.running)return this.starting??Promise.resolve();this.running=!0,this.generation++,this.seen.clear(),this.sender=this.makeSender();let e=this.open(this.generation).finally(()=>{this.starting===e&&(this.starting=null)});return this.starting=e,e}async stop(){this.running=!1,this.generation++,this.openTimer&&=(clearTimeout(this.openTimer),null),this.wakeOpen?.(),this.follower.stop(),this.sender.stop()}async sendMessage(t,n,i){if(n===e.O.REACTION){if(!i)throw Error(`a reaction names the message it reacts to`);return this.sender.react(this.topic,i,t),null}return r(this.sender.send({topic:this.topic,type:n,target:i??``,text:t}))}retrySendMessage(e){return this.sender.retry(typeof e==`string`?e:e.id)}async fetchPreviousMessages(){this.emitter.emit(n.LOADING_PREVIOUS_MESSAGES,!0);try{let e=this.generation,t=await this.history.loadOlder();return e===this.generation?this.showRows(t):[]}finally{this.emitter.emit(n.LOADING_PREVIOUS_MESSAGES,!1)}}hasPreviousMessages(){return this.history.hasOlder()}orderMessages(e){return[...e].sort((e,t)=>e.index>=0&&t.index>=0?e.index-t.index:e.index>=0||t.index>=0?e.index>=0?-1:1:e.timestamp-t.timestamp)}async open(e){this.emitter.emit(n.LOADING_INIT,!0);let t=0;for(;e===this.generation;)try{let t=await this.history.open();if(e!==this.generation)return;this.showRows(t.rows),this.follower.start(t.startAt,t.notes),this.emitter.emit(n.LOADING_INIT,!1);return}catch(r){if(e!==this.generation)return;t++,this.emitter.emit(n.ERROR,r),this.setStatus(_.RECONNECTING),t===A&&this.emitter.emit(n.CRITICAL_ERROR,r),await this.waitToOpen(this.openRetryMs[Math.min(t,this.openRetryMs.length)-1]??8e3)}}waitToOpen(e){return new Promise(t=>{this.wakeOpen=()=>{this.wakeOpen=null,t()},this.openTimer=setTimeout(()=>{this.openTimer=null,this.wakeOpen?.()},e)})}makeSender(){return new O(this.key,this.profile,this.write,{pending:e=>this.emitter.emit(n.MESSAGE_REQUEST_INITIATED,r(e)),written:e=>this.emitter.emit(n.MESSAGE_REQUEST_UPLOADED,r(e)),failed:(e,t)=>{this.emitter.emit(n.ERROR,t),this.emitter.emit(n.MESSAGE_REQUEST_ERROR,r(e))},confirmed:()=>{}},this.senderSettings)}show(e){this.seen.has(e.seq)||(this.seen.add(e.seq),this.sender.confirm(e.msg),this.emitter.emit(n.MESSAGE_RECEIVED,i(e)))}showRows(e){let t=[];for(let r of e){if(this.seen.has(r.seq))continue;this.seen.add(r.seq),this.sender.confirm(r.msg);let e=i(r);t.push(e),this.emitter.emit(n.MESSAGE_RECEIVED,e)}return t}setStatus(e){e!==this.status&&(this.status=e,this.emitter.emit(n.STATUS,e))}};exports.CHAT_BINDING_TITLE=e.G,exports.ChatEmitter=o,exports.ChatMessageError=e.S,exports.DEFAULT_NOTE_HEARTBEAT_MS=e.t,exports.DEFAULT_NOTE_SLOT_MS=e.n,exports.EVENTS=n,exports.FeedStatus=_,exports.HeadLookupTimeoutError=l,exports.MAX_BINDING_CHARACTERS=e.K,exports.MAX_ENTRY_BYTES=e.p,exports.MAX_MESSAGE_BYTES=e.C,exports.MAX_NAME_CHARACTERS=e.w,exports.MAX_NOTE_BYTES=e.r,exports.MAX_TEXT_CHARACTERS=e.T,exports.MAX_TOPIC_CHARACTERS=e.E,exports.MAX_WALLET_LINK_CHARACTERS=e.B,exports.MESSAGE_VERSION=e.D,exports.MessageType=e.O,exports.MessageVia=e.k,exports.NOTE_VERSION=e.i,exports.OWN_FEED_TOPIC_PREFIX=e.b,exports.SwarmChat=M,exports.UnreadableGatewayError=y,exports.UnreadableSlotError=u,exports.WALLET_LINK_STATEMENT=e.V,exports.WALLET_LINK_TITLE=e.H,exports.chatBindingSchema=e.q,exports.chatMessageSchema=e.A,exports.checkChatBinding=e.J,exports.checkWalletLink=e.U,exports.countCharacters=e.j,exports.createChatMessage=e.M,exports.displayNameProblem=e.N,exports.encodeChatMessage=e.P,exports.encodeSlotNote=e.a,exports.feedEntrySchema=e.m,exports.hasValidSignature=e.F,exports.historyFileSchema=e.h,exports.historyLinkSchema=e.g,exports.historyRowSchema=e._,exports.newMessageId=e.I,exports.noteAddress=e.o,exports.noteIdentifier=e.s,exports.noteIdentifierText=e.c,exports.noteSlotEnd=e.l,exports.noteSlotOf=e.u,exports.ownFeedTopic=e.x,exports.parseChatMessage=e.L,exports.parseFeedEntry=e.v,exports.parseHistoryFile=e.y,exports.parseSlotNote=e.d,exports.signedBytes=e.R,exports.slotNoteSchema=e.f,exports.verifyChatMessage=e.z,exports.walletLinkSchema=e.W;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./message-BjeTRy2F.cjs");let t=require("@ethersphere/bee-js");var n={LOADING_INIT:`loadingInit`,LOADING_PREVIOUS_MESSAGES:`loadingPreviousMessages`,MESSAGE_RECEIVED:`messageReceived`,MESSAGE_REQUEST_INITIATED:`messageRequestInitiated`,MESSAGE_REQUEST_UPLOADED:`messageRequestUploaded`,MESSAGE_REQUEST_ERROR:`messageRequestError`,CRITICAL_ERROR:`criticalError`,STATUS:`status`,MESSAGE_SKIPPED:`messageSkipped`,ERROR:`error`};function r(e){return a(e,-1,e.ts)}function i(e){return a(e.msg,e.seq,e.at)}function a(e,t,n){return{id:e.id,type:e.type,message:e.text,username:e.name,address:e.addr,timestamp:n,...e.target?{targetMessageId:e.target}:{},index:t,signedMessage:e}}var o=class{constructor(){this.listeners=new Map,this.on=(e,t)=>{this.listeners.set(e,[...this.listeners.get(e)??[],t])},this.off=(e,t)=>{this.listeners.set(e,(this.listeners.get(e)??[]).filter(e=>e!==t))},this.cleanAll=()=>{this.listeners.clear()}}emit(e,t){for(let n of this.listeners.get(e)??[])try{n(t)}catch(t){console.error(`a listener for ${e} threw`,t)}}},s=2e4,c=class{constructor(e,t){this.spacingMs=e,this.now=t,this.missedAt=new Map}readableAt(e,t=this.now()){let n=this.missedAt.get(e);return n===void 0||this.expired(n,t)?-1/0:n+this.spacingMs}mayRead(e,t=this.now()){return t>=this.readableAt(e,t)}missed(e,t=this.now()){for(let[e,n]of this.missedAt)this.expired(n,t)&&this.missedAt.delete(e);this.missedAt.set(e,t)}found(e){this.missedAt.delete(e)}clear(){this.missedAt.clear()}expired(e,t){return e>t||t-e>=this.spacingMs}},l=class extends Error{constructor(e){super(`the feed head lookup did not answer in time`,e),this.name=`HeadLookupTimeoutError`}},u=class extends Error{constructor(e,t){super(`feed slot ${e} was served but could not be read`,t),this.index=e,this.name=`UnreadableSlotError`}};function d(e){return e instanceof t.BeeResponseError&&(e.status===404||e.status===500)}async function f(e,n){try{return await n()}catch(n){if(d(n))return null;throw n instanceof t.BeeResponseError?n:new u(e,{cause:n})}}function p(n,r,i,a,o=e.n){let s=t.Topic.fromString(i),c=e=>n.feed.makeReader(s,r,m(e));return{readNote:t=>f(t,async()=>(await n.soc.makeReader(r,m(a.slotReadMs)).download(e.s(i,o,t))).payload.toUint8Array()),readSlot:e=>f(e,async()=>(await c(a.slotReadMs).downloadPayload({index:e})).payload.toUint8Array()),async readHead(){let e=m(a.feedReadMs);try{let{payload:t,feedIndex:i}=await n.feed.makeReader(s,r,e).downloadPayload();return{index:Number(i.toBigInt()),payload:t.toUint8Array()}}catch(t){if(d(t))return null;throw e.signal?.aborted?new l({cause:t}):t}},async readFile(e){return(await n.data.download(e,void 0,m(a.feedReadMs))).toUint8Array()}}}function m(e){return{signal:AbortSignal.timeout(e)}}var h=`0123456789abcdef`.repeat(4);function g(e,n,r,i,a){let o=new t.PrivateKey(r),s=t.Identifier.fromString(i);return async t=>{await e.messaging.gsocSend(n,o,s,t,{deferred:!1},m(a.writeMs))}}var _={LIVE:`live`,RECONNECTING:`reconnecting`,STALLED:`stalled`},v={pollIntervalMs:1e3,missingReadSpacingMs:s,maxSlotsPerPoll:16,unservedPollsBeforeProbe:3,unreadablePollsBeforeFailure:3,probeIntervalCapMs:6e4,probeDistances:[1,2,4,8],missedLimit:32,missedReadsPerPoll:4,missedExpiryMs:3e5,backoffCapMs:8e3,stallAfterMs:8e3,random:Math.random,now:Date.now},y=class extends Error{constructor(e){super(`the gateway keeps answering feed slot ${e} with something that is not a chunk`),this.index=e,this.name=`UnreadableGatewayError`}},b=class{constructor(e,t,n,r={},i=null){this.source=e,this.topic=t,this.events=n,this.notes=i,this.next=0,this.ceiling=null,this.nextNoteSlot=0,this.lastNoteFoundAt=0,this.unservedPolls=0,this.nextProbeAt=0,this.unreadablePolls=0,this.gatewayFailures=0,this.missed=new Map,this.timer=null,this.generation=0,this.running=!1,this.status=null,this.settings={...v,...r},this.pacer=new c(this.settings.missingReadSpacingMs,this.settings.now)}get nextIndex(){return this.next}get missedIndices(){return[...this.missed.keys()]}get ledByNotes(){return this.ceiling!==null}start(e,t=null){this.stop(),this.next=e,this.ceiling=t?.newest??null,this.nextNoteSlot=t?.nextNoteSlot??(this.notes?this.notes.lastReadableSlot()+1:0),this.lastNoteFoundAt=this.settings.now(),this.resetRefusals(),this.unreadablePolls=0,this.gatewayFailures=0,this.missed.clear(),this.pacer.clear(),this.status=null,this.running=!0,this.schedule(0)}stop(){this.running=!1,this.generation++,this.timer&&=(clearTimeout(this.timer),null)}schedule(e){let t=this.generation;this.timer=setTimeout(()=>{this.timer=null,this.poll(t)},e)}async poll(e){let t=0,n=!1;try{this.notes!==null&&await this.readDueNotes(this.notes,e),t=await this.walk(e),await this.readMissed(e)}catch(t){n=!0,e===this.generation&&this.gatewayFailed(t)}e===this.generation&&this.running&&(n?this.schedule(this.backoffMs()):(this.gatewayAnswered(),this.schedule(t>=this.settings.maxSlotsPerPoll?0:this.untilNextRead())))}untilNextRead(){let e=this.settings.now(),t=t=>{let n=this.pacer.readableAt(t);return n>e?n:e+this.settings.pollIntervalMs},n=[...this.missed.keys()].map(t);return this.notes!==null&&n.push(this.notes.readableAt(this.nextNoteSlot)),this.ceiling===null&&n.push(t(this.next)),Math.max(0,Math.min(...n)-e)}async readDueNotes(e,t){let n=this.settings.now(),r=e.lastReadableSlot(n);if(r<this.nextNoteSlot)return;let i=Math.max(this.nextNoteSlot,r-e.lookBackSlots+1),a=await e.scan(r,i);t===this.generation&&(this.nextNoteSlot=r+1,a?(this.lastNoteFoundAt=n,this.ceiling=Math.max(this.ceiling??-1,a.note.newest,this.next-1)):n-this.lastNoteFoundAt>=e.silenceMs&&(this.lastNoteFoundAt=n,e.clock.distrust(),this.nextNoteSlot=Math.min(this.nextNoteSlot,e.lastReadableSlot(n)+1)))}async read(e){let t;try{t=await this.source.readSlot(e)}catch(e){if(e instanceof u)return`unreadable`;throw e}return t===null?this.pacer.missed(e):this.pacer.found(e),t}async readUnnamed(e){return this.pacer.mayRead(e)?this.read(e):`held`}async walk(e){for(let t=0;t<this.settings.maxSlotsPerPoll;t++){let n=this.next;if(this.ceiling!==null&&n>this.ceiling)return t;let r=this.ceiling===null?await this.readUnnamed(n):await this.read(n);if(e!==this.generation||r===`held`)return t;if(this.ceiling!==null&&(r===null||r===`unreadable`))this.remember(n),this.next=n+1;else{if(r===null||r===`unreadable`){if(t===0){if(this.unservedPolls++,this.unreadablePolls=r===`unreadable`?this.unreadablePolls+1:0,this.shouldProbe()&&await this.probePast(n,e)){this.unreadablePolls=0;continue}if(this.unreadablePolls>=this.settings.unreadablePollsBeforeFailure)throw new y(n)}return t}this.resetRefusals(),this.unreadablePolls=0,this.next=n+1,this.accept(n,r)}}return this.settings.maxSlotsPerPoll}shouldProbe(){if(this.unservedPolls!==this.nextProbeAt)return!1;let{probeIntervalCapMs:e,pollIntervalMs:t,missingReadSpacingMs:n}=this.settings,r=Math.max(1,Math.ceil(e/Math.max(t,n)));return this.nextProbeAt+=Math.min(this.nextProbeAt,r),!0}resetRefusals(){this.unservedPolls=0,this.nextProbeAt=this.settings.unservedPollsBeforeProbe}async probePast(e,t){let n=new Set([e]);for(let r of this.settings.probeDistances){let i=e+r,a=await this.readUnnamed(i);if(t!==this.generation)return!1;if(a===null||a===`unreadable`||a===`held`)n.add(i);else{this.resetRefusals(),this.remember(e);for(let r=e+1;r<i;r++){let e=n.has(r)?null:await this.readUnnamed(r);if(t!==this.generation)return!1;e===null||e===`unreadable`||e===`held`?this.remember(r):this.accept(r,e)}return this.next=i+1,this.accept(i,a),!0}}return!1}remember(e){this.missed.has(e)||(this.missed.size>=this.settings.missedLimit?this.events.skipped(e,`unreachable`,`stepped past with the retry list full`):this.missed.set(e,this.settings.now()))}async readMissed(e){let t=this.settings.now();for(let[e,n]of this.missed)t-n>=this.settings.missedExpiryMs&&(this.missed.delete(e),this.events.skipped(e,`unreachable`,`not served within the time a stepped-past slot is kept`));let n=[...this.missed.keys()].filter(e=>this.pacer.mayRead(e,t)).slice(0,this.settings.missedReadsPerPoll);for(let t of n){let n=await this.read(t);if(e!==this.generation)return;let r=this.missed.get(t);this.missed.delete(t),n!==null&&n!==`unreadable`?this.accept(t,n):r!==void 0&&this.missed.set(t,r)}}accept(t,n){let r=e.v(n,t,this.topic);r.ok?(this.notes?.clock.observe(r.value.at,this.settings.now()),this.events.entry(r.value)):this.events.skipped(t,r.reason,r.detail)}gatewayFailed(e){this.gatewayFailures++,this.setStatus(_.RECONNECTING),this.events.error(e)}gatewayAnswered(){this.gatewayFailures=0;let e=this.settings.now(),t=[...this.missed.values()].some(t=>e-t>=this.settings.stallAfterMs);this.setStatus(t?_.STALLED:_.LIVE)}backoffMs(){let{pollIntervalMs:e,backoffCapMs:t,random:n}=this.settings,r=Math.min(t,e*2**this.gatewayFailures);return r/2+n()*r/2}setStatus(e){e!==this.status&&(this.status=e,this.events.status(e))}},x=16,S=class{constructor(e,t,n,r=null){this.source=e,this.topic=t,this.events=n,this.notes=r,this.older=null,this.loading=null}async open(){this.older=null;let e=await this.newestNote();if(e!==null)return this.openAt(e.newest,e);let t=await this.readHead();return t===null?{startAt:0,rows:[],notes:null}:this.openAt(t.index,null,t.payload)}async newestNote(){if(this.notes===null)return null;let e=this.notes.lastReadableSlot(),t=await this.notes.scan(e,e-this.notes.lookBackSlots+1);return t===null?null:{newest:t.note.newest,nextNoteSlot:e+1}}async openAt(e,t,n){let r=e<0?null:await this.newestLink(e,n);if(r===null)return{startAt:0,rows:[],notes:t};let i=await this.readFile(r);return i===`refused`?{startAt:0,rows:[],notes:t}:{startAt:r.toSeq+1,rows:i??[],notes:t}}async readHead(){try{return await this.source.readHead()}catch(e){if(e instanceof l)return this.events.error(e),null;throw e}}hasOlder(){return this.older!==null}loadOlder(){return this.loading??=this.loadOlderOnce().finally(()=>{this.loading=null}),this.loading}async loadOlderOnce(){let t=this.older;if(t===null)return[];let n=await this.source.readFile(t.ref),r=e.y(n,this.topic,t);if(!r.ok)throw this.older=null,Error(`history file ${t.ref} refused (${r.reason}): ${r.detail}`);return this.report(r.value.skipped),this.older=r.value.prev,r.value.rows}async newestLink(t,n){let r=n===void 0?t:t-1;if(n!==void 0){let r=e.v(n,t,this.topic);if(r.ok)return r.value.history}for(let n=r;n>=Math.max(0,t-x);n--){let t=await this.source.readSlot(n).catch(e=>{if(e instanceof u)return null;throw e});if(t===null)continue;let r=e.v(t,n,this.topic);if(r.ok)return r.value.history}return null}async readFile(t){try{let n=e.y(await this.source.readFile(t.ref),this.topic,t);return n.ok?(this.report(n.value.skipped),this.older=n.value.prev,n.value.rows):(this.events.error(Error(`history file ${t.ref} refused (${n.reason}): ${n.detail}`)),`refused`)}catch(e){return this.events.error(e),this.older=t,null}}report(e){e>0&&this.events.skipped(e)}},C={slotMs:e.n,heartbeatMs:e.t,marginMs:1e3,scanBatch:4,clockLimitMs:3e5,missingReadSpacingMs:s};function w(e){return typeof e.readNote==`function`}var T=class{constructor(e){this.limitMs=e,this.aheadAtMost=1/0,this.trusted=!0}observe(e,t){this.aheadAtMost=Math.min(this.aheadAtMost,t-e)}distrust(){this.trusted=!1}get isTrusted(){return this.trusted}get ms(){let e=Number.isFinite(this.aheadAtMost),t=this.trusted||!e?Math.min(0,this.aheadAtMost):this.aheadAtMost;return Math.max(-this.limitMs,Math.min(this.limitMs,t))}},E=class{constructor(e,t,n){this.source=e,this.now=n,this.counts={found:0,empty:0},this.settings={...C,...t},this.clock=new T(this.settings.clockLimitMs),this.pacer=new c(this.settings.missingReadSpacingMs,n)}lastReadableSlot(t=this.now()){return e.u(t-this.settings.marginMs-this.clock.ms,this.settings.slotMs)-1}readableAt(t){return e.l(t,this.settings.slotMs)+this.settings.marginMs+this.clock.ms}get lookBackSlots(){return Math.ceil(this.settings.heartbeatMs/this.settings.slotMs)+2}get silenceMs(){return this.settings.heartbeatMs+2*this.settings.slotMs+this.settings.marginMs}async read(t){if(!this.pacer.mayRead(t))return null;let n;try{n=await this.source.readNote(t),n===null&&this.pacer.missed(t)}catch(e){if(!(e instanceof u))throw e;n=null}let r=n===null?null:e.d(n);return r===null?(this.counts.empty++,null):(this.counts.found++,this.clock.observe(r.writtenAt,this.now()),r)}async scan(e,t){for(let n=e;n>=t;n-=this.settings.scanBatch){let e=[];for(let r=n;r>n-this.settings.scanBatch&&r>=t;r--)e.push(r);let r=await Promise.all(e.map(e=>this.read(e))),i=r.findIndex(e=>e!==null);if(i>=0)return{slot:e[i],note:r[i]}}return null}},D={resendAfterMs:1e4,maxResends:5,reactionWindowMs:1e3,isLive:()=>!0},O=class{constructor(e,t,n,r,i=D){this.key=e,this.profile=t,this.write=n,this.events=r,this.settings=i,this.outgoing=new Map,this.reactions=new Map,this.stopped=!1}get address(){return this.key.publicKey().address().toHex()}send(t){let{message:n,bytes:r}=e.M(this.key,{...t,...this.profile}),i={message:n,bytes:r,writes:0,written:!1,inFlight:!1,timer:null,lastError:null};return this.outgoing.set(n.id,i),this.events.pending(n),this.attempt(i),n}react(t,n,r){let i=JSON.stringify([t,n,r]),a=this.reactions.get(i);if(a){a.taps++;return}let o=setTimeout(()=>{let a=this.reactions.get(i);this.reactions.delete(i),a&&a.taps%2==1&&!this.stopped&&this.send({topic:t,type:e.O.REACTION,target:n,text:r})},this.settings.reactionWindowMs);this.reactions.set(i,{taps:1,timer:o})}confirm(e){if(e.addr!==this.address)return;let t=this.outgoing.get(e.id);t&&(this.clearTimer(t),this.outgoing.delete(e.id),this.events.confirmed(t.message))}retry(e){let t=this.outgoing.get(e);return!t||this.stopped?!1:(this.clearTimer(t),t.writes=0,t.inFlight||this.attempt(t),!0)}isPending(e){return this.outgoing.has(e)}stop(){this.stopped=!0;for(let e of this.outgoing.values())this.clearTimer(e);for(let{timer:e}of this.reactions.values())clearTimeout(e);this.reactions.clear()}attempt(e){!this.stopped&&this.outgoing.has(e.message.id)&&(e.writes++,e.inFlight=!0,this.write(e.bytes).then(()=>{e.inFlight=!1,!e.written&&this.outgoing.has(e.message.id)&&(e.written=!0,this.events.written(e.message)),this.scheduleNext(e)},t=>{e.inFlight=!1,e.lastError=t,this.scheduleNext(e)}))}scheduleNext(e){!this.stopped&&this.outgoing.has(e.message.id)&&(e.timer=setTimeout(()=>{e.timer=null,this.settings.isLive()?e.writes>this.settings.maxResends?this.events.failed(e.message,e.lastError??Error(`never seen on the chat feed`)):this.attempt(e):this.scheduleNext(e)},this.settings.resendAfterMs))}clearTimer(e){e.timer&&=(clearTimeout(e.timer),null)}},k=[1e3,2e3,4e3,8e3],A=3;function j(e){return(e.startsWith(`0x`)?e.slice(2):e).toLowerCase()}var M=class{constructor(e,r={}){this.emitter=new o,this.seen=new Set,this.status=null,this.generation=0,this.running=!1,this.starting=null,this.openTimer=null,this.wakeOpen=null;let{user:i,infra:a}=e;this.key=new t.PrivateKey(j(i.privateKey)),this.topic=a.chatTopic,this.profile={name:i.nickname,via:a.via,...i.binding?{idb:i.binding}:{},...i.walletLink?{wl:i.walletLink}:{}},this.openRetryMs=r.openRetryMs??k,this.senderSettings={...D,isLive:()=>this.status===_.LIVE,...r.sender};let s={slotReadMs:a.socReadTimeout??5e3,feedReadMs:a.feedReadTimeout??15e3,writeMs:a.gsocWriteTimeout??1e4},c={...a.noteSlotMs===void 0?{}:{slotMs:a.noteSlotMs},...a.noteHeartbeatMs===void 0?{}:{heartbeatMs:a.noteHeartbeatMs},...r.notes};this.source=r.source??p(new t.Bee(a.beeUrl),j(a.chatAddress),a.chatTopic,s,c.slotMs),this.write=r.write??g(new t.Bee(a.writeUrl??a.beeUrl),a.stamp?j(a.stamp):h,j(a.gsocResourceId),a.gsocTopic,s);let l=r.follower?.now??(()=>Date.now()),u={pollIntervalMs:a.pollingInterval??1e3,...r.follower,now:l},d=this.source;this.notes=w(d)?new E(d,c,l):null,this.follower=new b(this.source,this.topic,{entry:e=>this.show(e),skipped:(e,t,r)=>this.emitter.emit(n.MESSAGE_SKIPPED,{index:e,reason:t,detail:r}),status:e=>this.setStatus(e),error:e=>this.emitter.emit(n.ERROR,e)},u,this.notes),this.history=new S(this.source,this.topic,{skipped:e=>this.emitter.emit(n.MESSAGE_SKIPPED,{index:-1,reason:`history-row`,detail:`${e} rows of a history file`}),error:e=>this.emitter.emit(n.ERROR,e)},this.notes),this.sender=this.makeSender()}getEmitter(){return this.emitter}getStatus(){return this.status}getAddress(){return this.key.publicKey().address().toHex()}start(){if(this.running)return this.starting??Promise.resolve();this.running=!0,this.generation++,this.seen.clear(),this.sender=this.makeSender();let e=this.open(this.generation).finally(()=>{this.starting===e&&(this.starting=null)});return this.starting=e,e}async stop(){this.running=!1,this.generation++,this.openTimer&&=(clearTimeout(this.openTimer),null),this.wakeOpen?.(),this.follower.stop(),this.sender.stop()}async sendMessage(t,n,i){if(n===e.O.REACTION){if(!i)throw Error(`a reaction names the message it reacts to`);return this.sender.react(this.topic,i,t),null}return r(this.sender.send({topic:this.topic,type:n,target:i??``,text:t}))}retrySendMessage(e){return this.sender.retry(typeof e==`string`?e:e.id)}async fetchPreviousMessages(){this.emitter.emit(n.LOADING_PREVIOUS_MESSAGES,!0);try{let e=this.generation,t=await this.history.loadOlder();return e===this.generation?this.showRows(t):[]}finally{this.emitter.emit(n.LOADING_PREVIOUS_MESSAGES,!1)}}hasPreviousMessages(){return this.history.hasOlder()}orderMessages(e){return[...e].sort((e,t)=>e.index>=0&&t.index>=0?e.index-t.index:e.index>=0||t.index>=0?e.index>=0?-1:1:e.timestamp-t.timestamp)}async open(e){this.emitter.emit(n.LOADING_INIT,!0);let t=0;for(;e===this.generation;)try{let t=await this.history.open();if(e!==this.generation)return;this.showRows(t.rows),this.follower.start(t.startAt,t.notes),this.emitter.emit(n.LOADING_INIT,!1);return}catch(r){if(e!==this.generation)return;t++,this.emitter.emit(n.ERROR,r),this.setStatus(_.RECONNECTING),t===A&&this.emitter.emit(n.CRITICAL_ERROR,r),await this.waitToOpen(this.openRetryMs[Math.min(t,this.openRetryMs.length)-1]??8e3)}}waitToOpen(e){return new Promise(t=>{this.wakeOpen=()=>{this.wakeOpen=null,t()},this.openTimer=setTimeout(()=>{this.openTimer=null,this.wakeOpen?.()},e)})}makeSender(){return new O(this.key,this.profile,this.write,{pending:e=>this.emitter.emit(n.MESSAGE_REQUEST_INITIATED,r(e)),written:e=>this.emitter.emit(n.MESSAGE_REQUEST_UPLOADED,r(e)),failed:(e,t)=>{this.emitter.emit(n.ERROR,t),this.emitter.emit(n.MESSAGE_REQUEST_ERROR,r(e))},confirmed:()=>{}},this.senderSettings)}show(e){this.seen.has(e.seq)||(this.seen.add(e.seq),this.sender.confirm(e.msg),this.emitter.emit(n.MESSAGE_RECEIVED,i(e)))}showRows(e){let t=[];for(let r of e){if(this.seen.has(r.seq))continue;this.seen.add(r.seq),this.sender.confirm(r.msg);let e=i(r);t.push(e),this.emitter.emit(n.MESSAGE_RECEIVED,e)}return t}setStatus(e){e!==this.status&&(this.status=e,this.emitter.emit(n.STATUS,e))}};exports.CHAT_BINDING_TITLE=e.G,exports.ChatEmitter=o,exports.ChatMessageError=e.S,exports.DEFAULT_NOTE_HEARTBEAT_MS=e.t,exports.DEFAULT_NOTE_SLOT_MS=e.n,exports.EVENTS=n,exports.FeedStatus=_,exports.HeadLookupTimeoutError=l,exports.MAX_BINDING_CHARACTERS=e.K,exports.MAX_ENTRY_BYTES=e.p,exports.MAX_MESSAGE_BYTES=e.C,exports.MAX_NAME_CHARACTERS=e.w,exports.MAX_NOTE_BYTES=e.r,exports.MAX_TEXT_CHARACTERS=e.T,exports.MAX_TOPIC_CHARACTERS=e.E,exports.MAX_WALLET_LINK_CHARACTERS=e.B,exports.MESSAGE_VERSION=e.D,exports.MessageType=e.O,exports.MessageVia=e.k,exports.NOTE_VERSION=e.i,exports.OWN_FEED_TOPIC_PREFIX=e.b,exports.SwarmChat=M,exports.UnreadableGatewayError=y,exports.UnreadableSlotError=u,exports.WALLET_LINK_STATEMENT=e.V,exports.WALLET_LINK_TITLE=e.H,exports.chatBindingSchema=e.q,exports.chatMessageSchema=e.A,exports.checkChatBinding=e.J,exports.checkWalletLink=e.U,exports.countCharacters=e.j,exports.createChatMessage=e.M,exports.displayNameProblem=e.N,exports.encodeChatMessage=e.P,exports.encodeSlotNote=e.a,exports.feedEntrySchema=e.m,exports.hasValidSignature=e.F,exports.historyFileSchema=e.h,exports.historyLinkSchema=e.g,exports.historyRowSchema=e._,exports.newMessageId=e.I,exports.noteAddress=e.o,exports.noteIdentifier=e.s,exports.noteIdentifierText=e.c,exports.noteSlotEnd=e.l,exports.noteSlotOf=e.u,exports.ownFeedTopic=e.x,exports.parseChatMessage=e.L,exports.parseFeedEntry=e.v,exports.parseHistoryFile=e.y,exports.parseSlotNote=e.d,exports.signedBytes=e.R,exports.slotNoteSchema=e.f,exports.verifyChatMessage=e.z,exports.walletLinkSchema=e.W;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { A as e, B as t, C as n, D as r, E as i, F as a, G as o, H as s, I as c, J as ee, K as l, L as te, M as u, N as ne, O as d, P as f, R as p, S as m, T as h, U as g, V as _, W as v, _ as y, a as b, b as re, c as ie, d as x, f as ae, g as oe, h as se, i as ce, j as le, k as ue, l as S, m as de, n as C, o as fe, p as pe, q as me, r as he, s as w, t as T, u as E, v as D, w as O, x as k, y as A, z as j } from "./message-DQda4_Ge.js";
1
+ import { A as e, B as t, C as n, D as r, E as i, F as a, G as o, H as s, I as c, J as ee, K as l, L as te, M as u, N as ne, O as d, P as f, R as p, S as m, T as h, U as g, V as _, W as v, _ as y, a as b, b as re, c as ie, d as x, f as ae, g as oe, h as se, i as ce, j as le, k as ue, l as S, m as de, n as C, o as fe, p as pe, q as me, r as he, s as w, t as T, u as E, v as D, w as O, x as k, y as A, z as j } from "./message-BUFAxjtN.js";
2
2
  import { Bee as M, BeeResponseError as N, Identifier as P, PrivateKey as F, Topic as I } from "@ethersphere/bee-js";
3
- //#region src/events.ts
3
+ // src/events.ts
4
4
  var L = {
5
5
  LOADING_INIT: "loadingInit",
6
6
  LOADING_PREVIOUS_MESSAGES: "loadingPreviousMessages",
@@ -126,8 +126,7 @@ function ve(e, t, n, r, i) {
126
126
  await e.messaging.gsocSend(t, a, o, n, { deferred: !1 }, J(i.writeMs));
127
127
  };
128
128
  }
129
- //#endregion
130
- //#region src/follower.ts
129
+ // src/follower.ts
131
130
  var Y = {
132
131
  LIVE: "live",
133
132
  RECONNECTING: "reconnecting",
@@ -191,13 +190,7 @@ var Y = {
191
190
  } catch (t) {
192
191
  n = !0, e === this.generation && this.gatewayFailed(t);
193
192
  }
194
- if (e === this.generation && this.running) {
195
- if (n) {
196
- this.schedule(this.backoffMs());
197
- return;
198
- }
199
- this.gatewayAnswered(), this.schedule(t >= this.settings.maxSlotsPerPoll ? 0 : this.untilNextRead());
200
- }
193
+ e === this.generation && this.running && (n ? this.schedule(this.backoffMs()) : (this.gatewayAnswered(), this.schedule(t >= this.settings.maxSlotsPerPoll ? 0 : this.untilNextRead())));
201
194
  }
202
195
  untilNextRead() {
203
196
  let e = this.settings.now(), t = (t) => {
@@ -210,13 +203,7 @@ var Y = {
210
203
  let n = this.settings.now(), r = e.lastReadableSlot(n);
211
204
  if (r < this.nextNoteSlot) return;
212
205
  let i = Math.max(this.nextNoteSlot, r - e.lookBackSlots + 1), a = await e.scan(r, i);
213
- if (t === this.generation) {
214
- if (this.nextNoteSlot = r + 1, a) {
215
- this.lastNoteFoundAt = n, this.ceiling = Math.max(this.ceiling ?? -1, a.note.newest, this.next - 1);
216
- return;
217
- }
218
- n - this.lastNoteFoundAt >= e.silenceMs && (this.lastNoteFoundAt = n, e.clock.distrust(), this.nextNoteSlot = Math.min(this.nextNoteSlot, e.lastReadableSlot(n) + 1));
219
- }
206
+ t === this.generation && (this.nextNoteSlot = r + 1, a ? (this.lastNoteFoundAt = n, this.ceiling = Math.max(this.ceiling ?? -1, a.note.newest, this.next - 1)) : n - this.lastNoteFoundAt >= e.silenceMs && (this.lastNoteFoundAt = n, e.clock.distrust(), this.nextNoteSlot = Math.min(this.nextNoteSlot, e.lastReadableSlot(n) + 1)));
220
207
  }
221
208
  async read(e) {
222
209
  let t;
@@ -237,21 +224,20 @@ var Y = {
237
224
  if (this.ceiling !== null && n > this.ceiling) return t;
238
225
  let r = this.ceiling === null ? await this.readUnnamed(n) : await this.read(n);
239
226
  if (e !== this.generation || r === "held") return t;
240
- if (this.ceiling !== null && (r === null || r === "unreadable")) {
241
- this.remember(n), this.next = n + 1;
242
- continue;
243
- }
244
- if (r === null || r === "unreadable") {
245
- if (t === 0) {
246
- if (this.unservedPolls++, this.unreadablePolls = r === "unreadable" ? this.unreadablePolls + 1 : 0, this.shouldProbe() && await this.probePast(n, e)) {
247
- this.unreadablePolls = 0;
248
- continue;
227
+ if (this.ceiling !== null && (r === null || r === "unreadable")) this.remember(n), this.next = n + 1;
228
+ else {
229
+ if (r === null || r === "unreadable") {
230
+ if (t === 0) {
231
+ if (this.unservedPolls++, this.unreadablePolls = r === "unreadable" ? this.unreadablePolls + 1 : 0, this.shouldProbe() && await this.probePast(n, e)) {
232
+ this.unreadablePolls = 0;
233
+ continue;
234
+ }
235
+ if (this.unreadablePolls >= this.settings.unreadablePollsBeforeFailure) throw new X(n);
249
236
  }
250
- if (this.unreadablePolls >= this.settings.unreadablePollsBeforeFailure) throw new X(n);
237
+ return t;
251
238
  }
252
- return t;
239
+ this.resetRefusals(), this.unreadablePolls = 0, this.next = n + 1, this.accept(n, r);
253
240
  }
254
- this.resetRefusals(), this.unreadablePolls = 0, this.next = n + 1, this.accept(n, r);
255
241
  }
256
242
  return this.settings.maxSlotsPerPoll;
257
243
  }
@@ -268,28 +254,21 @@ var Y = {
268
254
  for (let r of this.settings.probeDistances) {
269
255
  let i = e + r, a = await this.readUnnamed(i);
270
256
  if (t !== this.generation) return !1;
271
- if (a === null || a === "unreadable" || a === "held") {
272
- n.add(i);
273
- continue;
274
- }
275
- this.resetRefusals(), this.remember(e);
276
- for (let r = e + 1; r < i; r++) {
277
- let e = n.has(r) ? null : await this.readUnnamed(r);
278
- if (t !== this.generation) return !1;
279
- e === null || e === "unreadable" || e === "held" ? this.remember(r) : this.accept(r, e);
257
+ if (a === null || a === "unreadable" || a === "held") n.add(i);
258
+ else {
259
+ this.resetRefusals(), this.remember(e);
260
+ for (let r = e + 1; r < i; r++) {
261
+ let e = n.has(r) ? null : await this.readUnnamed(r);
262
+ if (t !== this.generation) return !1;
263
+ e === null || e === "unreadable" || e === "held" ? this.remember(r) : this.accept(r, e);
264
+ }
265
+ return this.next = i + 1, this.accept(i, a), !0;
280
266
  }
281
- return this.next = i + 1, this.accept(i, a), !0;
282
267
  }
283
268
  return !1;
284
269
  }
285
270
  remember(e) {
286
- if (!this.missed.has(e)) {
287
- if (this.missed.size >= this.settings.missedLimit) {
288
- this.events.skipped(e, "unreachable", "stepped past with the retry list full");
289
- return;
290
- }
291
- this.missed.set(e, this.settings.now());
292
- }
271
+ this.missed.has(e) || (this.missed.size >= this.settings.missedLimit ? this.events.skipped(e, "unreachable", "stepped past with the retry list full") : this.missed.set(e, this.settings.now()));
293
272
  }
294
273
  async readMissed(e) {
295
274
  let t = this.settings.now();
@@ -565,15 +544,7 @@ var Te = class {
565
544
  }
566
545
  scheduleNext(e) {
567
546
  !this.stopped && this.outgoing.has(e.message.id) && (e.timer = setTimeout(() => {
568
- if (e.timer = null, !this.settings.isLive()) {
569
- this.scheduleNext(e);
570
- return;
571
- }
572
- if (e.writes > this.settings.maxResends) {
573
- this.events.failed(e.message, e.lastError ?? /* @__PURE__ */ Error("never seen on the chat feed"));
574
- return;
575
- }
576
- this.attempt(e);
547
+ e.timer = null, this.settings.isLive() ? e.writes > this.settings.maxResends ? this.events.failed(e.message, e.lastError ?? /* @__PURE__ */ Error("never seen on the chat feed")) : this.attempt(e) : this.scheduleNext(e);
577
548
  }, this.settings.resendAfterMs));
578
549
  }
579
550
  clearTimer(e) {
@@ -734,5 +705,4 @@ var ke = class {
734
705
  e !== this.status && (this.status = e, this.emitter.emit(L.STATUS, e));
735
706
  }
736
707
  };
737
- //#endregion
738
708
  export { o as CHAT_BINDING_TITLE, V as ChatEmitter, m as ChatMessageError, T as DEFAULT_NOTE_HEARTBEAT_MS, C as DEFAULT_NOTE_SLOT_MS, L as EVENTS, Y as FeedStatus, W as HeadLookupTimeoutError, l as MAX_BINDING_CHARACTERS, pe as MAX_ENTRY_BYTES, n as MAX_MESSAGE_BYTES, O as MAX_NAME_CHARACTERS, he as MAX_NOTE_BYTES, h as MAX_TEXT_CHARACTERS, i as MAX_TOPIC_CHARACTERS, t as MAX_WALLET_LINK_CHARACTERS, r as MESSAGE_VERSION, d as MessageType, ue as MessageVia, ce as NOTE_VERSION, re as OWN_FEED_TOPIC_PREFIX, ke as SwarmChat, X as UnreadableGatewayError, G as UnreadableSlotError, _ as WALLET_LINK_STATEMENT, s as WALLET_LINK_TITLE, me as chatBindingSchema, e as chatMessageSchema, ee as checkChatBinding, g as checkWalletLink, le as countCharacters, u as createChatMessage, ne as displayNameProblem, f as encodeChatMessage, b as encodeSlotNote, de as feedEntrySchema, a as hasValidSignature, se as historyFileSchema, oe as historyLinkSchema, y as historyRowSchema, c as newMessageId, fe as noteAddress, w as noteIdentifier, ie as noteIdentifierText, S as noteSlotEnd, E as noteSlotOf, k as ownFeedTopic, te as parseChatMessage, D as parseFeedEntry, A as parseHistoryFile, x as parseSlotNote, p as signedBytes, ae as slotNoteSchema, j as verifyChatMessage, v as walletLinkSchema };
@@ -2,15 +2,15 @@ import { z } from 'zod';
2
2
  /**
3
3
  * The Swarm ID chat binding: the account's statement, signed with its own key, that a chat address on one site is its
4
4
  * own. The Swarm ID fork (solarpunk-id, `lib/src/utils/chat-binding.ts`) makes it, and this module reads it exactly as
5
- * the fork's `verifyChatBinding` does, without importing the fork: the same four lines, the same clean site origin,
5
+ * Swarm ID's `verifyChatBinding` does, without importing Swarm ID: the same four lines, the same clean site origin,
6
6
  * the same EIP-191 personal_sign recovery with v 27 or 28 and a low s.
7
7
  */
8
8
  /** The first line, which also versions the binding format. */
9
9
  export declare const CHAT_BINDING_TITLE = "Swarm ID chat binding v1";
10
- /** The fork's own bound on a binding's text. */
10
+ /** Swarm ID's own bound on a binding's text. */
11
11
  export declare const MAX_BINDING_CHARACTERS = 512;
12
12
  /**
13
- * A binding as a message carries it. `sig` is spelled as the fork writes it, `0x` and 130 lowercase hex characters
13
+ * A binding as a message carries it. `sig` is spelled as Swarm ID writes it, `0x` and 130 lowercase hex characters
14
14
  * of r, s and v, so one binding has one spelling inside the signed bytes.
15
15
  */
16
16
  export declare const chatBindingSchema: z.ZodObject<{
@@ -29,13 +29,13 @@ export interface ChatIdentity {
29
29
  /**
30
30
  * The wallet the message's Swarm ID wallet link names, `0x` and 40 lowercase hex characters, present only when the
31
31
  * message carries a link both the wallet and this account signed. A reader looks its ENS name up itself, and the
32
- * fork's `resolveVerifiedEnsName` does that with both the reverse and the forward record.
32
+ * Swarm ID's `resolveVerifiedEnsName` does that with both the reverse and the forward record.
33
33
  */
34
34
  wallet?: string;
35
35
  }
36
36
  export interface BindingOptions {
37
- /** The origin the reader runs on. When given, a binding for any other site is refused. */
38
- origin?: string;
37
+ /** The origins the reader runs on, each bare. When given, a binding for a site not among them is refused. */
38
+ origins?: readonly string[];
39
39
  /** Accept a binding for `http://localhost`, `http://127.0.0.1` or `http://[::1]`, as only a development build signs. */
40
40
  allowLocalHttp?: boolean;
41
41
  }
@@ -48,7 +48,7 @@ export type BindingCheck = {
48
48
  };
49
49
  /**
50
50
  * Reads a binding for the chat address `addr` (40 lowercase hex characters, no `0x`). Refuses every text but the four
51
- * lines the fork writes, a binding for another chat address, one for another site than `origin` when that is given,
51
+ * lines Swarm ID writes, a binding for another chat address, one for a site not in `origins` when that is given,
52
52
  * and a signature nothing recovers an account from. Never throws.
53
53
  */
54
54
  export declare function checkChatBinding(binding: ChatBinding, addr: string, options?: BindingOptions): BindingCheck;
@@ -88,11 +88,12 @@ export type ChatMessageCheck = {
88
88
  detail: string;
89
89
  };
90
90
  /**
91
- * `origin` is the site the chat runs on, a bare origin such as `https://example.com`, and is required: a binding for
92
- * any other site is refused, so a binding signed for one site never passes in another site's chat.
91
+ * `origins` are the sites the chat runs on, each a bare origin such as `https://example.com`, and are required: a
92
+ * binding for any other site is refused, so a binding signed for one site never passes in a chat that site is not
93
+ * part of. A chat served from several pages, such as one domain and a copy on Swarm under an ENS name, lists each.
93
94
  */
94
95
  export interface VerifyOptions {
95
- origin: string;
96
+ origins: readonly string[];
96
97
  /** Accept a binding for `http://localhost`, `http://127.0.0.1` or `http://[::1]`, as only a development build signs. */
97
98
  allowLocalHttp?: boolean;
98
99
  }
@@ -139,10 +140,10 @@ export declare function createChatMessage(privateKey: PrivateKey | Uint8Array |
139
140
  export declare function hasValidSignature(message: ChatMessage): boolean;
140
141
  /**
141
142
  * Verifies a message that arrived as an object: its shape, its signature, and, when it carries a binding, that the
142
- * binding is the fork's four lines for this `addr` and for `options.origin`, and recovers an account. When it also
143
- * carries a wallet link, the link must be the fork's five lines for that account, signed by its wallet and by the
143
+ * binding is Swarm ID's four lines for this `addr` and for one of `options.origins`, and recovers an account. When it also
144
+ * carries a wallet link, the link must be Swarm ID's five lines for that account, signed by its wallet and by the
144
145
  * account, and the identity then names the wallet. A message whose binding or link fails is refused as `binding`,
145
- * never passed as a guest, and so is a bound message checked with no origin.
146
+ * never passed as a guest, and so is a bound message checked with no origins.
146
147
  * Never throws, and touches no DOM and no Node API, so a page runs it in a Web Worker as the server runs it.
147
148
  */
148
149
  export declare function verifyChatMessage(value: unknown, options: VerifyOptions): ChatMessageCheck;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The address that made `sig` over `text`, `0x` and 40 lowercase hex characters, or null for a signature the fork
2
+ * The address that made `sig` over `text`, `0x` and 40 lowercase hex characters, or null for a signature Swarm ID
3
3
  * would refuse or nothing recovers from. `sig` is `0x` and 130 hex characters of r, s and v, already shape-checked.
4
4
  */
5
5
  export declare function recoverPersonalSigner(text: string, sig: string): string | null;
@@ -4,18 +4,18 @@ import { z } from 'zod';
4
4
  * that the two belong to the same person, which lets a reader show the wallet's ENS name. The Swarm ID fork makes it
5
5
  * while the person has "Show my ENS name on sites" on, and its canonical description is `docs/Wallet-Link.md` in the
6
6
  * fork (solarpunk-id), with `verifyWalletLink` in its `lib/src/utils/wallet-link.ts`. This module reads it exactly as
7
- * that function does, without importing the fork: the same five lines, the second of them read exactly, and both
7
+ * that function does, without importing Swarm ID: the same five lines, the second of them read exactly, and both
8
8
  * EIP-191 personal_sign signatures with v 27 or 28 and a low s. It looks nothing up: a reader takes the checked wallet to its own ENS lookup.
9
9
  */
10
10
  /** The first line, which also versions the wallet link format. */
11
11
  export declare const WALLET_LINK_TITLE = "Swarm ID wallet link v1";
12
12
  /** The second line, what the wallet's owner agrees to, which a wallet shows them before they sign. */
13
13
  export declare const WALLET_LINK_STATEMENT = "I link this wallet to the Swarm ID account below, so sites may show my ENS name beside its messages.";
14
- /** The fork's own bound on a wallet link's text, which is 258 characters in the format it writes. */
14
+ /** Swarm ID's own bound on a wallet link's text, which is 258 characters in the format it writes. */
15
15
  export declare const MAX_WALLET_LINK_CHARACTERS = 320;
16
16
  /**
17
- * A wallet link as a message carries it: the fork's `{ message, walletSignature, accountSignature }` as `msg`, `wsig`
18
- * and `asig`. Each signature is spelled as the fork writes it, `0x` and 130 lowercase hex characters of r, s and v, so
17
+ * A wallet link as a message carries it: Swarm ID's `{ message, walletSignature, accountSignature }` as `msg`, `wsig`
18
+ * and `asig`. Each signature is spelled as Swarm ID writes it, `0x` and 130 lowercase hex characters of r, s and v, so
19
19
  * one link has one spelling inside the signed bytes.
20
20
  */
21
21
  export declare const walletLinkSchema: z.ZodObject<{
@@ -38,7 +38,7 @@ export type WalletLinkCheck = {
38
38
  };
39
39
  /**
40
40
  * Reads a wallet link for `account` (`0x` and 40 lowercase hex characters), the account a verified chat binding
41
- * named. Refuses every text but the five lines the fork writes, its statement included, a wallet signature that does not recover the wallet
41
+ * named. Refuses every text but the five lines Swarm ID writes, its statement included, a wallet signature that does not recover the wallet
42
42
  * the link names, an account signature that does not recover the account it names, and a link naming any other
43
43
  * account. Never throws.
44
44
  */
@@ -1,14 +1,13 @@
1
1
  import { Bytes as e, EthAddress as t, Identifier as n, PrivateKey as r, Reference as i, Signature as a } from "@ethersphere/bee-js";
2
2
  import { z as o } from "zod";
3
3
  import { publicKeyToAddress as s, recoverPublicKey as c } from "@ethersphere/core-sdk/crypto";
4
- //#region src/message/canonicalSignature.ts
4
+ // src/message/canonicalSignature.ts
5
5
  var l = 115792089237316195423570985008687907852837564279074904382605163141518161494337n, ee = l / 2n;
6
6
  function te(e, t) {
7
7
  let n = BigInt(`0x${e}`), r = BigInt(`0x${t}`);
8
8
  return n > 0n && n < l && r > 0n && r <= ee;
9
9
  }
10
- //#endregion
11
- //#region src/message/personalSign.ts
10
+ // src/message/personalSign.ts
12
11
  var ne = "Ethereum Signed Message:\n", re = /* @__PURE__ */ new Set([27, 28]), ie = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/, u = new TextEncoder();
13
12
  function ae(e) {
14
13
  let t = u.encode(e), n = u.encode(`${ne}${t.length}`), r = new Uint8Array(n.length + t.length);
@@ -32,8 +31,7 @@ function f(e) {
32
31
  let t = Date.parse(e);
33
32
  return !Number.isNaN(t) && new Date(t).toISOString() === e;
34
33
  }
35
- //#endregion
36
- //#region src/message/binding.ts
34
+ // src/message/binding.ts
37
35
  var p = "Swarm ID chat binding v1", se = 512, ce = "Site: ", le = "Chat address: ", ue = "Date: ", de = "\n", fe = 4, pe = /^0x[0-9a-f]{40}$/, me = /^[a-z0-9-]+(\.[a-z0-9-]+)*$/, he = /* @__PURE__ */ new Set([
38
36
  "localhost",
39
37
  "127.0.0.1",
@@ -82,9 +80,13 @@ function g(e, t, n = {}) {
82
80
  ok: !1,
83
81
  detail: "the binding is for another chat address than addr"
84
82
  };
85
- if (n.origin !== void 0 && i !== n.origin) return {
83
+ if (n.origins !== void 0 && !Array.isArray(n.origins)) return {
86
84
  ok: !1,
87
- detail: `the binding is for ${i}, not ${n.origin}`
85
+ detail: "origins is not a list of sites"
86
+ };
87
+ if (n.origins !== void 0 && !n.origins.includes(i)) return {
88
+ ok: !1,
89
+ detail: `the binding is for ${i}, not for ${n.origins.join(" or ") || "any site"}`
88
90
  };
89
91
  let s = d(e.msg, e.sig);
90
92
  return s === null ? {
@@ -99,8 +101,7 @@ function g(e, t, n = {}) {
99
101
  }
100
102
  };
101
103
  }
102
- //#endregion
103
- //#region src/message/walletLink.ts
104
+ // src/message/walletLink.ts
104
105
  var _ = "Swarm ID wallet link v1", _e = "I link this wallet to the Swarm ID account below, so sites may show my ENS name beside its messages.", ve = 320, ye = "Account: ", be = "Wallet: ", xe = "Date: ", Se = "\n", v = 5, y = /^0x[0-9a-f]{40}$/, b = o.string().regex(/^0x[0-9a-f]{130}$/, "expected 0x and 130 lowercase hex characters"), x = o.strictObject({
105
106
  msg: o.string().max(320),
106
107
  wsig: b,
@@ -149,8 +150,7 @@ function C(e, t) {
149
150
  detail: `the wallet link is for ${r}, not the binding's account ${t}`
150
151
  };
151
152
  }
152
- //#endregion
153
- //#region src/message/message.ts
153
+ // src/message/message.ts
154
154
  var Ce = 9, w = 3072, we = 128, Te = 500, Ee = 20, T = {
155
155
  TEXT: "text",
156
156
  THREAD: "thread",
@@ -338,10 +338,10 @@ function U(e, t) {
338
338
  message: r,
339
339
  identity: null
340
340
  };
341
- if (typeof t?.origin != "string") return {
341
+ if (!Array.isArray(t?.origins)) return {
342
342
  ok: !1,
343
343
  reason: "binding",
344
- detail: "no origin was given to check the binding against"
344
+ detail: "no origins were given to check the binding against"
345
345
  };
346
346
  let i = g(r.idb, r.addr, t);
347
347
  if (!i.ok) return {
@@ -396,14 +396,12 @@ function Re(e, t) {
396
396
  }
397
397
  return U(r, t);
398
398
  }
399
- //#endregion
400
- //#region src/message/ownFeed.ts
399
+ // src/message/ownFeed.ts
401
400
  var W = "swarm-chat-own-feed-v1:";
402
401
  function ze(e) {
403
402
  return `${W}${e}`;
404
403
  }
405
- //#endregion
406
- //#region src/message/entry.ts
404
+ // src/message/entry.ts
407
405
  var Be = 4096, Ve = o.string().regex(/^[0-9a-f]{64}([0-9a-f]{64})?$/, "expected a 64 or 128 hex character reference"), G = o.number().int().nonnegative().max(2 ** 53 - 1), K = o.strictObject({
408
406
  ref: Ve,
409
407
  toSeq: G
@@ -507,8 +505,7 @@ function We(e, t, n) {
507
505
  }
508
506
  };
509
507
  }
510
- //#endregion
511
- //#region src/message/note.ts
508
+ // src/message/note.ts
512
509
  var Ge = 1, Ke = 2e3, qe = 3e4, Je = 256, Ye = o.strictObject({
513
510
  v: o.literal(1),
514
511
  newest: o.number().int().min(-1).max(2 ** 53 - 1),
@@ -551,5 +548,4 @@ function rt(e) {
551
548
  return null;
552
549
  }
553
550
  }
554
- //#endregion
555
551
  export { F as A, ve as B, w as C, Ce as D, we as E, H as F, p as G, _ as H, B as I, g as J, se as K, Re as L, Le as M, Ne as N, T as O, z as P, R, I as S, Te as T, C as U, _e as V, x as W, J as _, nt as a, W as b, Qe as c, rt as d, Ye as f, K as g, Y as h, Ge as i, D as j, E as k, Ze as l, q as m, Ke as n, $e as o, Be as p, m as q, Je as r, $ as s, qe as t, Xe as u, Ue as v, Ee as w, ze as x, We as y, U as z };
@@ -0,0 +1,4 @@
1
+ let e=require("@ethersphere/bee-js"),t=require("zod"),n=require("@ethersphere/core-sdk/crypto");var r=115792089237316195423570985008687907852837564279074904382605163141518161494337n,i=r/2n;function a(e,t){let n=BigInt(`0x${e}`),a=BigInt(`0x${t}`);return n>0n&&n<r&&a>0n&&a<=i}var o=`Ethereum Signed Message:
2
+ `,s=new Set([27,28]),c=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/,l=new TextEncoder;function ee(e){let t=l.encode(e),n=l.encode(`${o}${t.length}`),r=new Uint8Array(n.length+t.length);return r.set(n),r.set(t,n.length),r}function te(e){return Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function u(e,t){let r=t.slice(2,66),i=t.slice(66,130),o=parseInt(t.slice(130),16);if(!s.has(o)||!a(r,i))return null;try{let t=(0,n.recoverPublicKey)(ee(e),BigInt(`0x${r}`),BigInt(`0x${i}`),BigInt(o));return`0x${te((0,n.publicKeyToAddress)(t))}`}catch{return null}}function d(e){if(!c.test(e))return!1;let t=Date.parse(e);return!Number.isNaN(t)&&new Date(t).toISOString()===e}var f=`Swarm ID chat binding v1`,ne=512,re=`Site: `,ie=`Chat address: `,ae=`Date: `,oe=`
3
+ `,p=4,se=/^0x[0-9a-f]{40}$/,ce=/^[a-z0-9-]+(\.[a-z0-9-]+)*$/,le=new Set([`localhost`,`127.0.0.1`,`[::1]`]),m=t.z.strictObject({msg:t.z.string().max(512),sig:t.z.string().regex(/^0x[0-9a-f]{130}$/,`expected 0x and 130 lowercase hex characters`)});function ue(e,t){let n;try{n=new URL(e)}catch{return!1}let r=n.protocol===`https:`,i=t&&n.protocol===`http:`&&le.has(n.hostname);return!r&&!i||!i&&!ce.test(n.hostname)?!1:n.host!==``&&n.username===``&&n.password===``&&n.origin===e}function h(e,t){return e.startsWith(t)?e.slice(t.length):null}function g(e,t,n={}){if(!m.safeParse(e).success)return{ok:!1,detail:`not a binding of a text and a 65 byte signature`};let r=e.msg.split(oe);if(r.length!==p||r[0]!==`Swarm ID chat binding v1`)return{ok:!1,detail:`not the ${p} lines of a ${f}`};let i=h(r[1],re),a=h(r[2],ie),o=h(r[3],ae);if(i===null||!ue(i,n.allowLocalHttp===!0))return{ok:!1,detail:`the binding does not name a clean site origin`};if(a===null||!se.test(a))return{ok:!1,detail:`the binding does not name a chat address as 0x and 40 lowercase hex characters`};if(o===null||!d(o))return{ok:!1,detail:`the binding date is not ISO 8601 UTC with milliseconds`};if(a!==`0x${t}`)return{ok:!1,detail:`the binding is for another chat address than addr`};if(n.origins!==void 0&&!Array.isArray(n.origins))return{ok:!1,detail:`origins is not a list of sites`};if(n.origins!==void 0&&!n.origins.includes(i))return{ok:!1,detail:`the binding is for ${i}, not for ${n.origins.join(` or `)||`any site`}`};let s=u(e.msg,e.sig);return s===null?{ok:!1,detail:`the binding signature recovers no account`}:{ok:!0,identity:{account:s,site:i,date:o}}}var _=`Swarm ID wallet link v1`,de=`I link this wallet to the Swarm ID account below, so sites may show my ENS name beside its messages.`,fe=320,pe=`Account: `,me=`Wallet: `,he=`Date: `,ge=`
4
+ `,v=5,y=/^0x[0-9a-f]{40}$/,b=t.z.string().regex(/^0x[0-9a-f]{130}$/,`expected 0x and 130 lowercase hex characters`),x=t.z.strictObject({msg:t.z.string().max(320),wsig:b,asig:b});function S(e,t){return e.startsWith(t)?e.slice(t.length):null}function C(e,t){if(!x.safeParse(e).success)return{ok:!1,detail:`not a wallet link of a text and two 65 byte signatures`};let n=e.msg.split(ge);if(n.length!==v||n[0]!==`Swarm ID wallet link v1`)return{ok:!1,detail:`not the ${v} lines of a ${_}`};if(n[1]!==`I link this wallet to the Swarm ID account below, so sites may show my ENS name beside its messages.`)return{ok:!1,detail:`the wallet link's second line is not the ${_} statement`};let r=S(n[2],pe),i=S(n[3],me),a=S(n[4],he);return r===null||!y.test(r)?{ok:!1,detail:`the wallet link does not name an account as 0x and 40 lowercase hex characters`}:i===null||!y.test(i)?{ok:!1,detail:`the wallet link does not name a wallet as 0x and 40 lowercase hex characters`}:a===null||!d(a)?{ok:!1,detail:`the wallet link date is not ISO 8601 UTC with milliseconds`}:r===t?u(e.msg,e.wsig)===i?u(e.msg,e.asig)===r?{ok:!0,wallet:i,account:r,date:a}:{ok:!1,detail:`the account signature does not recover the account the link names`}:{ok:!1,detail:`the wallet signature does not recover the wallet the link names`}:{ok:!1,detail:`the wallet link is for ${r}, not the binding's account ${t}`}}var _e=9,w=3072,ve=128,ye=500,be=20,T={TEXT:`text`,THREAD:`thread`,REACTION:`reaction`},E={GATEWAY:`gateway`,OWN_STAMP:`own-stamp`};function D(e){let t=0;for(let n of e)t++;return t}function O(e){return t.z.string().regex(RegExp(`^[0-9a-f]{${e}}$`),`expected ${e} lowercase hex characters`)}function k(e,n){return t.z.string().refine(t=>{let r=D(t);return r>=e&&r<=n},`expected ${e} to ${n} characters`)}var A=/(?![\u200c\u200d])[\p{Cf}\p{Cc}\u2800\u115f\u1160\u3164\uffa0]|\u034f|\u17b4|\u17b5/u,xe=/[\p{Default_Ignorable_Code_Point}\p{Mn}\p{Me}\u2800]/gu,j=Object.fromEntries([...[...`℮ꬲеҽ⋿ΕЕⴹᎬꗋꓰ𑢦𑢮𐊆𝾁`].map(e=>[e,`e`]),...[...`⊤⟙🝨𝍳ΤⲦТтߠᎢꔋㄒꓔ𖼊𑢼𐊗𐊱𐌕丅`].map(e=>[e,`t`]),...[...`һҺႹհᏂΗⲎНнᎻᕼꓧ𐋏`].map(e=>[e,`h`])]),Se=RegExp(`[${Object.keys(j).join(``)}]`,`gu`),Ce=/[\u3002\u0660\u06f0\u0701\u0702\ua4f8\ua60e\uabec\u{10a50}\u{1d16d}\u{1ecae}]/gu,we=/[\p{Z}.]+$/u,M=`.eth`;function Te(e){return e.normalize(`NFKD`).replace(Ce,`.`).replace(xe,``).replace(Se,e=>j[e]??e).toLowerCase().trim().replace(we,``)}function N(e){return Te(e).endsWith(M)}function Ee(e,t){return k(e,t).refine(e=>!A.test(e),`expected no format or control characters`).refine(e=>!N(e),`expected a name not ending in ${M}, which ENS names keep`)}function De(e){let t=D(e);return t<1||t>20?`length`:A.test(e)?`invisible`:N(e)?`ens-like`:null}var P=O(32),F=t.z.strictObject({v:t.z.literal(9),topic:k(1,128),id:P,type:t.z.enum([T.TEXT,T.THREAD,T.REACTION]),target:t.z.union([t.z.literal(``),P]),text:k(1,500),name:Ee(1,20),addr:O(40),ts:t.z.number().int().nonnegative().max(2**53-1),via:t.z.enum([E.GATEWAY,E.OWN_STAMP]),idb:m.optional(),wl:x.optional(),sig:O(130)}).refine(e=>e.type===T.TEXT==(e.target===``),{message:`a text message has no target, a thread reply or a reaction names one`,path:[`target`]}).refine(e=>e.wl===void 0||e.idb!==void 0,{message:`a wallet link is carried only beside a chat binding, whose account it names`,path:[`wl`]}),I=class extends Error{constructor(e,t){super(`chat message refused (${e}): ${t}`),this.reason=e,this.name=`ChatMessageError`}},L=new TextEncoder,Oe=`1b`,ke=`1c`,Ae=new TextDecoder(`utf-8`,{fatal:!0});function R(e){return L.encode(JSON.stringify([e.v,e.topic,e.id,e.type,e.target,e.text,e.name,e.addr,e.ts,e.via,e.idb?.msg??``,e.idb?.sig??``,...e.wl?[e.wl.msg,e.wl.wsig,e.wl.asig]:[]]))}function z(e){let t={v:e.v,topic:e.topic,id:e.id,type:e.type,target:e.target,text:e.text,name:e.name,addr:e.addr,ts:e.ts,via:e.via,...e.idb?{idb:{msg:e.idb.msg,sig:e.idb.sig}}:{},...e.wl?{wl:{msg:e.wl.msg,wsig:e.wl.wsig,asig:e.wl.asig}}:{},sig:e.sig};return L.encode(JSON.stringify(t))}function B(){let e=crypto.getRandomValues(new Uint8Array(16));return Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function V(e){return e.issues.map(e=>`${e.path.join(`.`)||`message`}: ${e.message}`).join(`, `)}function je(t,n){let r=t instanceof e.PrivateKey?t:new e.PrivateKey(t),i={v:9,topic:n.topic,id:n.id??B(),type:n.type,target:n.target??``,text:n.text,name:n.name,addr:r.publicKey().address().toHex(),ts:n.ts??Date.now(),via:n.via,...n.idb?{idb:n.idb}:{},...n.wl?{wl:n.wl}:{}},a={...i,sig:`0`.repeat(130)},o=F.safeParse(a);if(!o.success)throw new I(`shape`,V(o.error));let s=z(a).byteLength;if(s>3072)throw new I(`too-large`,`${s} bytes, the cap is ${w}`);if(i.idb){let e=g(i.idb,i.addr,{allowLocalHttp:!0});if(!e.ok)throw new I(`binding`,e.detail);if(i.wl){let t=C(i.wl,e.identity.account);if(!t.ok)throw new I(`binding`,`wallet link: ${t.detail}`)}}let c={...i,sig:r.sign(R(i)).toHex()};return{message:c,bytes:z(c)}}function H(t){let n=t.sig.slice(128);if(n!==Oe&&n!==ke||!a(t.sig.slice(0,64),t.sig.slice(64,128)))return!1;try{return new e.Signature(t.sig).recoverPublicKey(R(t)).address().toHex()===t.addr}catch{return!1}}function U(e,t){let n=F.safeParse(e);if(!n.success)return{ok:!1,reason:`shape`,detail:V(n.error)};let r=n.data;if(!H(r))return{ok:!1,reason:`signature`,detail:`the signature was not made by addr over these fields`};if(!r.idb)return{ok:!0,message:r,identity:null};if(!Array.isArray(t?.origins))return{ok:!1,reason:`binding`,detail:`no origins were given to check the binding against`};let i=g(r.idb,r.addr,t);if(!i.ok)return{ok:!1,reason:`binding`,detail:i.detail};if(!r.wl)return{ok:!0,message:r,identity:i.identity};let a=C(r.wl,i.identity.account);return a.ok?{ok:!0,message:r,identity:{...i.identity,wallet:a.wallet}}:{ok:!1,reason:`binding`,detail:`wallet link: ${a.detail}`}}function Me(e,t){if(e.byteLength>3072)return{ok:!1,reason:`too-large`,detail:`${e.byteLength} bytes, the cap is ${w}`};let n;try{n=Ae.decode(e)}catch{return{ok:!1,reason:`not-utf8`,detail:`the payload is not valid UTF-8`}}let r;try{r=JSON.parse(n)}catch{return{ok:!1,reason:`not-json`,detail:`the payload is not JSON`}}return U(r,t)}var W=`swarm-chat-own-feed-v1:`;function Ne(e){return`${W}${e}`}var Pe=4096,Fe=t.z.string().regex(/^[0-9a-f]{64}([0-9a-f]{64})?$/,`expected a 64 or 128 hex character reference`),G=t.z.number().int().nonnegative().max(2**53-1),K=t.z.strictObject({ref:Fe,toSeq:G}),q=t.z.strictObject({v:t.z.literal(9),seq:G,at:G,msg:F,history:K.nullable()}),J=t.z.strictObject({seq:G,at:G,msg:F}),Y=t.z.strictObject({v:t.z.literal(9),topic:t.z.string().min(1),fromSeq:G,toSeq:G,messages:t.z.array(t.z.unknown()),prev:K.nullable()}).refine(e=>e.fromSeq<=e.toSeq,{message:`fromSeq is after toSeq`,path:[`fromSeq`]}),Ie=new TextDecoder(`utf-8`,{fatal:!0});function X(e){let t;try{t=Ie.decode(e)}catch{return{ok:!1,reason:`not-utf8`,detail:`the payload is not valid UTF-8`}}try{return{ok:!0,value:JSON.parse(t)}}catch{return{ok:!1,reason:`not-json`,detail:`the payload is not JSON`}}}function Z(e){return e.issues.map(e=>`${e.path.join(`.`)||`value`}: ${e.message}`).join(`, `)}function Le(e,t,n){let r=X(e);if(!r.ok)return r;let i=q.safeParse(r.value);return i.success?i.data.seq===t?i.data.msg.topic===n?{ok:!0,value:i.data}:{ok:!1,reason:`mismatch`,detail:`the message belongs to another chat`}:{ok:!1,reason:`mismatch`,detail:`seq ${i.data.seq} at index ${t}`}:{ok:!1,reason:`shape`,detail:Z(i.error)}}function Re(e,t,n){let r=X(e);if(!r.ok)return r;let i=Y.safeParse(r.value);if(!i.success)return{ok:!1,reason:`shape`,detail:Z(i.error)};if(i.data.topic!==t||i.data.toSeq!==n.toSeq)return{ok:!1,reason:`mismatch`,detail:`the file is not the one its link names`};let{fromSeq:a,toSeq:o,prev:s}=i.data,c=[],l=0;for(let e of i.data.messages){let n=J.safeParse(e);n.success&&n.data.seq>=a&&n.data.seq<=o&&n.data.msg.topic===t?c.push(n.data):l++}return{ok:!0,value:{topic:t,fromSeq:a,toSeq:o,rows:c,prev:s,skipped:l}}}var ze=1,Be=2e3,Ve=3e4,He=256,Q=t.z.strictObject({v:t.z.literal(1),newest:t.z.number().int().min(-1).max(2**53-1),writtenAt:t.z.number().int().nonnegative().max(2**53-1)});function $(e){if(!Number.isInteger(e)||e<=0)throw RangeError(`a note slot is a positive whole number of milliseconds, not ${e}`)}function Ue(e,t){return $(t),Math.floor(e/t)}function We(e,t){return $(t),(e+1)*t}function Ge(e,t,n){return`${e}/note/${t}/${n}`}function Ke(t,n,r){return e.Identifier.fromString(Ge(t,n,r))}function qe(t,n,r,i){let a=Ke(t,n,r);return new e.Reference(e.Bytes.keccak256(e.Bytes.concat(a.toUint8Array(),new e.EthAddress(i).toUint8Array())))}var Je=new TextEncoder,Ye=new TextDecoder(`utf-8`,{fatal:!0});function Xe(e){let t={v:1,newest:e.newest,writtenAt:e.writtenAt};return Je.encode(JSON.stringify(t))}function Ze(e){if(e.length>256)return null;try{let t=Q.safeParse(JSON.parse(Ye.decode(e)));return t.success?t.data:null}catch{return null}}Object.defineProperty(exports,"A",{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,"B",{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,"C",{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,"D",{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,"E",{enumerable:!0,get:function(){return ve}}),Object.defineProperty(exports,"F",{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,"G",{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,"H",{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,"I",{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,"J",{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,"K",{enumerable:!0,get:function(){return ne}}),Object.defineProperty(exports,"L",{enumerable:!0,get:function(){return Me}}),Object.defineProperty(exports,"M",{enumerable:!0,get:function(){return je}}),Object.defineProperty(exports,"N",{enumerable:!0,get:function(){return De}}),Object.defineProperty(exports,"O",{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,"P",{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,"R",{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,"S",{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,"T",{enumerable:!0,get:function(){return ye}}),Object.defineProperty(exports,"U",{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,"V",{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,"W",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"_",{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return Xe}}),Object.defineProperty(exports,"b",{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return Ge}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return Ze}}),Object.defineProperty(exports,"f",{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,"g",{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,"h",{enumerable:!0,get:function(){return Y}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return ze}}),Object.defineProperty(exports,"j",{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,"k",{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return We}}),Object.defineProperty(exports,"m",{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return Be}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return qe}}),Object.defineProperty(exports,"p",{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(exports,"q",{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return He}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return Ke}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return Ve}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return Ue}}),Object.defineProperty(exports,"v",{enumerable:!0,get:function(){return Le}}),Object.defineProperty(exports,"w",{enumerable:!0,get:function(){return be}}),Object.defineProperty(exports,"x",{enumerable:!0,get:function(){return Ne}}),Object.defineProperty(exports,"y",{enumerable:!0,get:function(){return Re}}),Object.defineProperty(exports,"z",{enumerable:!0,get:function(){return U}});
package/dist/message.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./message-DBi9VeRs.cjs");exports.CHAT_BINDING_TITLE=e.G,exports.ChatMessageError=e.S,exports.DEFAULT_NOTE_HEARTBEAT_MS=e.t,exports.DEFAULT_NOTE_SLOT_MS=e.n,exports.MAX_BINDING_CHARACTERS=e.K,exports.MAX_ENTRY_BYTES=e.p,exports.MAX_MESSAGE_BYTES=e.C,exports.MAX_NAME_CHARACTERS=e.w,exports.MAX_NOTE_BYTES=e.r,exports.MAX_TEXT_CHARACTERS=e.T,exports.MAX_TOPIC_CHARACTERS=e.E,exports.MAX_WALLET_LINK_CHARACTERS=e.B,exports.MESSAGE_VERSION=e.D,exports.MessageType=e.O,exports.MessageVia=e.k,exports.NOTE_VERSION=e.i,exports.OWN_FEED_TOPIC_PREFIX=e.b,exports.WALLET_LINK_STATEMENT=e.V,exports.WALLET_LINK_TITLE=e.H,exports.chatBindingSchema=e.q,exports.chatMessageSchema=e.A,exports.checkChatBinding=e.J,exports.checkWalletLink=e.U,exports.countCharacters=e.j,exports.createChatMessage=e.M,exports.displayNameProblem=e.N,exports.encodeChatMessage=e.P,exports.encodeSlotNote=e.a,exports.feedEntrySchema=e.m,exports.hasValidSignature=e.F,exports.historyFileSchema=e.h,exports.historyLinkSchema=e.g,exports.historyRowSchema=e._,exports.newMessageId=e.I,exports.noteAddress=e.o,exports.noteIdentifier=e.s,exports.noteIdentifierText=e.c,exports.noteSlotEnd=e.l,exports.noteSlotOf=e.u,exports.ownFeedTopic=e.x,exports.parseChatMessage=e.L,exports.parseFeedEntry=e.v,exports.parseHistoryFile=e.y,exports.parseSlotNote=e.d,exports.signedBytes=e.R,exports.slotNoteSchema=e.f,exports.verifyChatMessage=e.z,exports.walletLinkSchema=e.W;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./message-BjeTRy2F.cjs");exports.CHAT_BINDING_TITLE=e.G,exports.ChatMessageError=e.S,exports.DEFAULT_NOTE_HEARTBEAT_MS=e.t,exports.DEFAULT_NOTE_SLOT_MS=e.n,exports.MAX_BINDING_CHARACTERS=e.K,exports.MAX_ENTRY_BYTES=e.p,exports.MAX_MESSAGE_BYTES=e.C,exports.MAX_NAME_CHARACTERS=e.w,exports.MAX_NOTE_BYTES=e.r,exports.MAX_TEXT_CHARACTERS=e.T,exports.MAX_TOPIC_CHARACTERS=e.E,exports.MAX_WALLET_LINK_CHARACTERS=e.B,exports.MESSAGE_VERSION=e.D,exports.MessageType=e.O,exports.MessageVia=e.k,exports.NOTE_VERSION=e.i,exports.OWN_FEED_TOPIC_PREFIX=e.b,exports.WALLET_LINK_STATEMENT=e.V,exports.WALLET_LINK_TITLE=e.H,exports.chatBindingSchema=e.q,exports.chatMessageSchema=e.A,exports.checkChatBinding=e.J,exports.checkWalletLink=e.U,exports.countCharacters=e.j,exports.createChatMessage=e.M,exports.displayNameProblem=e.N,exports.encodeChatMessage=e.P,exports.encodeSlotNote=e.a,exports.feedEntrySchema=e.m,exports.hasValidSignature=e.F,exports.historyFileSchema=e.h,exports.historyLinkSchema=e.g,exports.historyRowSchema=e._,exports.newMessageId=e.I,exports.noteAddress=e.o,exports.noteIdentifier=e.s,exports.noteIdentifierText=e.c,exports.noteSlotEnd=e.l,exports.noteSlotOf=e.u,exports.ownFeedTopic=e.x,exports.parseChatMessage=e.L,exports.parseFeedEntry=e.v,exports.parseHistoryFile=e.y,exports.parseSlotNote=e.d,exports.signedBytes=e.R,exports.slotNoteSchema=e.f,exports.verifyChatMessage=e.z,exports.walletLinkSchema=e.W;
package/dist/message.js CHANGED
@@ -1,2 +1 @@
1
- import { A as e, B as t, C as n, D as r, E as i, F as a, G as o, H as s, I as c, J as l, K as u, L as d, M as f, N as p, O as m, P as h, R as g, S as _, T as v, U as y, V as b, W as x, _ as S, a as C, b as w, c as T, d as E, f as D, g as O, h as k, i as A, j, k as M, l as N, m as P, n as F, o as I, p as L, q as R, r as z, s as B, t as V, u as H, v as U, w as W, x as G, y as K, z as q } from "./message-DQda4_Ge.js";
2
- export { o as CHAT_BINDING_TITLE, _ as ChatMessageError, V as DEFAULT_NOTE_HEARTBEAT_MS, F as DEFAULT_NOTE_SLOT_MS, u as MAX_BINDING_CHARACTERS, L as MAX_ENTRY_BYTES, n as MAX_MESSAGE_BYTES, W as MAX_NAME_CHARACTERS, z as MAX_NOTE_BYTES, v as MAX_TEXT_CHARACTERS, i as MAX_TOPIC_CHARACTERS, t as MAX_WALLET_LINK_CHARACTERS, r as MESSAGE_VERSION, m as MessageType, M as MessageVia, A as NOTE_VERSION, w as OWN_FEED_TOPIC_PREFIX, b as WALLET_LINK_STATEMENT, s as WALLET_LINK_TITLE, R as chatBindingSchema, e as chatMessageSchema, l as checkChatBinding, y as checkWalletLink, j as countCharacters, f as createChatMessage, p as displayNameProblem, h as encodeChatMessage, C as encodeSlotNote, P as feedEntrySchema, a as hasValidSignature, k as historyFileSchema, O as historyLinkSchema, S as historyRowSchema, c as newMessageId, I as noteAddress, B as noteIdentifier, T as noteIdentifierText, N as noteSlotEnd, H as noteSlotOf, G as ownFeedTopic, d as parseChatMessage, U as parseFeedEntry, K as parseHistoryFile, E as parseSlotNote, g as signedBytes, D as slotNoteSchema, q as verifyChatMessage, x as walletLinkSchema };
1
+ export { G as CHAT_BINDING_TITLE, S as ChatMessageError, t as DEFAULT_NOTE_HEARTBEAT_MS, n as DEFAULT_NOTE_SLOT_MS, K as MAX_BINDING_CHARACTERS, p as MAX_ENTRY_BYTES, C as MAX_MESSAGE_BYTES, w as MAX_NAME_CHARACTERS, r as MAX_NOTE_BYTES, T as MAX_TEXT_CHARACTERS, E as MAX_TOPIC_CHARACTERS, B as MAX_WALLET_LINK_CHARACTERS, D as MESSAGE_VERSION, O as MessageType, k as MessageVia, i as NOTE_VERSION, b as OWN_FEED_TOPIC_PREFIX, V as WALLET_LINK_STATEMENT, H as WALLET_LINK_TITLE, q as chatBindingSchema, A as chatMessageSchema, J as checkChatBinding, U as checkWalletLink, j as countCharacters, M as createChatMessage, N as displayNameProblem, P as encodeChatMessage, a as encodeSlotNote, m as feedEntrySchema, F as hasValidSignature, h as historyFileSchema, g as historyLinkSchema, _ as historyRowSchema, I as newMessageId, o as noteAddress, s as noteIdentifier, c as noteIdentifierText, l as noteSlotEnd, u as noteSlotOf, x as ownFeedTopic, L as parseChatMessage, v as parseFeedEntry, y as parseHistoryFile, d as parseSlotNote, R as signedBytes, f as slotNoteSchema, z as verifyChatMessage, W as walletLinkSchema } from "./message-BUFAxjtN.js";
package/dist/pacer.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * chunk for a minute (`ethersphere/bee`, `pkg/retrieval/retrieval.go`, `errSkip` and `skiplistDur = time.Minute`).
6
6
  * Once no peer is left it answers 500 at once, because "no peer left" is not `storage.ErrNotFound`
7
7
  * (`pkg/api/chunk.go`). A chunk written while its address is on that list stays unreadable on that node for up to a
8
- * minute. Measured on swarm-dev on 2026-10-12: an address read every second for 20 s and then written was readable
8
+ * minute. Measured on a test node on 2026-10-12: an address read every second for 20 s and then written was readable
9
9
  * after 33 to 36 s, one nobody had asked for at once. About four reads of a missing address exhaust the list, so one
10
10
  * read every twenty seconds stays under it.
11
11
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solarpunkltd/swarm-chat-js",
3
- "version": "9.0.0",
3
+ "version": "10.0.0",
4
4
  "description": "JS library for chatting on Swarm",
5
5
  "keywords": [
6
6
  "chat",
@@ -11,7 +11,7 @@
11
11
  "url": "https://github.com/Solar-Punk-Ltd/swarm-chat-js/issues"
12
12
  },
13
13
  "license": "Apache-2.0",
14
- "author": "levente.kiss@solarpunk.buzz",
14
+ "author": "Solar Punk Ltd",
15
15
  "repository": {
16
16
  "type": "git",
17
17
  "url": "git+https://github.com/Solar-Punk-Ltd/swarm-chat-js"
@@ -56,7 +56,7 @@
56
56
  "oxlint": "1.83.0",
57
57
  "oxlint-tsgolint": "7.0.2001",
58
58
  "typescript": "7.0.2",
59
- "vite": "8.3.0",
59
+ "vite": "8.3.3",
60
60
  "vitest": "5.0.1"
61
61
  },
62
62
  "peerDependencies": {
@@ -1,4 +0,0 @@
1
- let e=require("@ethersphere/bee-js"),t=require("zod"),n=require("@ethersphere/core-sdk/crypto");var r=115792089237316195423570985008687907852837564279074904382605163141518161494337n,i=r/2n;function a(e,t){let n=BigInt(`0x${e}`),a=BigInt(`0x${t}`);return n>0n&&n<r&&a>0n&&a<=i}var o=`Ethereum Signed Message:
2
- `,s=new Set([27,28]),c=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/,l=new TextEncoder;function ee(e){let t=l.encode(e),n=l.encode(`${o}${t.length}`),r=new Uint8Array(n.length+t.length);return r.set(n),r.set(t,n.length),r}function te(e){return Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function u(e,t){let r=t.slice(2,66),i=t.slice(66,130),o=parseInt(t.slice(130),16);if(!s.has(o)||!a(r,i))return null;try{let t=(0,n.recoverPublicKey)(ee(e),BigInt(`0x${r}`),BigInt(`0x${i}`),BigInt(o));return`0x${te((0,n.publicKeyToAddress)(t))}`}catch{return null}}function d(e){if(!c.test(e))return!1;let t=Date.parse(e);return!Number.isNaN(t)&&new Date(t).toISOString()===e}var f=`Swarm ID chat binding v1`,ne=512,re=`Site: `,ie=`Chat address: `,ae=`Date: `,oe=`
3
- `,p=4,se=/^0x[0-9a-f]{40}$/,ce=/^[a-z0-9-]+(\.[a-z0-9-]+)*$/,le=new Set([`localhost`,`127.0.0.1`,`[::1]`]),m=t.z.strictObject({msg:t.z.string().max(512),sig:t.z.string().regex(/^0x[0-9a-f]{130}$/,`expected 0x and 130 lowercase hex characters`)});function ue(e,t){let n;try{n=new URL(e)}catch{return!1}let r=n.protocol===`https:`,i=t&&n.protocol===`http:`&&le.has(n.hostname);return!r&&!i||!i&&!ce.test(n.hostname)?!1:n.host!==``&&n.username===``&&n.password===``&&n.origin===e}function h(e,t){return e.startsWith(t)?e.slice(t.length):null}function g(e,t,n={}){if(!m.safeParse(e).success)return{ok:!1,detail:`not a binding of a text and a 65 byte signature`};let r=e.msg.split(oe);if(r.length!==p||r[0]!==`Swarm ID chat binding v1`)return{ok:!1,detail:`not the ${p} lines of a ${f}`};let i=h(r[1],re),a=h(r[2],ie),o=h(r[3],ae);if(i===null||!ue(i,n.allowLocalHttp===!0))return{ok:!1,detail:`the binding does not name a clean site origin`};if(a===null||!se.test(a))return{ok:!1,detail:`the binding does not name a chat address as 0x and 40 lowercase hex characters`};if(o===null||!d(o))return{ok:!1,detail:`the binding date is not ISO 8601 UTC with milliseconds`};if(a!==`0x${t}`)return{ok:!1,detail:`the binding is for another chat address than addr`};if(n.origin!==void 0&&i!==n.origin)return{ok:!1,detail:`the binding is for ${i}, not ${n.origin}`};let s=u(e.msg,e.sig);return s===null?{ok:!1,detail:`the binding signature recovers no account`}:{ok:!0,identity:{account:s,site:i,date:o}}}var _=`Swarm ID wallet link v1`,de=`I link this wallet to the Swarm ID account below, so sites may show my ENS name beside its messages.`,fe=320,pe=`Account: `,me=`Wallet: `,he=`Date: `,ge=`
4
- `,v=5,y=/^0x[0-9a-f]{40}$/,b=t.z.string().regex(/^0x[0-9a-f]{130}$/,`expected 0x and 130 lowercase hex characters`),x=t.z.strictObject({msg:t.z.string().max(320),wsig:b,asig:b});function S(e,t){return e.startsWith(t)?e.slice(t.length):null}function C(e,t){if(!x.safeParse(e).success)return{ok:!1,detail:`not a wallet link of a text and two 65 byte signatures`};let n=e.msg.split(ge);if(n.length!==v||n[0]!==`Swarm ID wallet link v1`)return{ok:!1,detail:`not the ${v} lines of a ${_}`};if(n[1]!==`I link this wallet to the Swarm ID account below, so sites may show my ENS name beside its messages.`)return{ok:!1,detail:`the wallet link's second line is not the ${_} statement`};let r=S(n[2],pe),i=S(n[3],me),a=S(n[4],he);return r===null||!y.test(r)?{ok:!1,detail:`the wallet link does not name an account as 0x and 40 lowercase hex characters`}:i===null||!y.test(i)?{ok:!1,detail:`the wallet link does not name a wallet as 0x and 40 lowercase hex characters`}:a===null||!d(a)?{ok:!1,detail:`the wallet link date is not ISO 8601 UTC with milliseconds`}:r===t?u(e.msg,e.wsig)===i?u(e.msg,e.asig)===r?{ok:!0,wallet:i,account:r,date:a}:{ok:!1,detail:`the account signature does not recover the account the link names`}:{ok:!1,detail:`the wallet signature does not recover the wallet the link names`}:{ok:!1,detail:`the wallet link is for ${r}, not the binding's account ${t}`}}var _e=9,w=3072,ve=128,ye=500,be=20,T={TEXT:`text`,THREAD:`thread`,REACTION:`reaction`},E={GATEWAY:`gateway`,OWN_STAMP:`own-stamp`};function D(e){let t=0;for(let n of e)t++;return t}function O(e){return t.z.string().regex(RegExp(`^[0-9a-f]{${e}}$`),`expected ${e} lowercase hex characters`)}function k(e,n){return t.z.string().refine(t=>{let r=D(t);return r>=e&&r<=n},`expected ${e} to ${n} characters`)}var A=/(?![\u200c\u200d])[\p{Cf}\p{Cc}\u2800\u115f\u1160\u3164\uffa0]|\u034f|\u17b4|\u17b5/u,xe=/[\p{Default_Ignorable_Code_Point}\p{Mn}\p{Me}\u2800]/gu,j=Object.fromEntries([...[...`℮ꬲеҽ⋿ΕЕⴹᎬꗋꓰ𑢦𑢮𐊆𝾁`].map(e=>[e,`e`]),...[...`⊤⟙🝨𝍳ΤⲦТтߠᎢꔋㄒꓔ𖼊𑢼𐊗𐊱𐌕丅`].map(e=>[e,`t`]),...[...`һҺႹհᏂΗⲎНнᎻᕼꓧ𐋏`].map(e=>[e,`h`])]),Se=RegExp(`[${Object.keys(j).join(``)}]`,`gu`),Ce=/[\u3002\u0660\u06f0\u0701\u0702\ua4f8\ua60e\uabec\u{10a50}\u{1d16d}\u{1ecae}]/gu,we=/[\p{Z}.]+$/u,M=`.eth`;function Te(e){return e.normalize(`NFKD`).replace(Ce,`.`).replace(xe,``).replace(Se,e=>j[e]??e).toLowerCase().trim().replace(we,``)}function N(e){return Te(e).endsWith(M)}function Ee(e,t){return k(e,t).refine(e=>!A.test(e),`expected no format or control characters`).refine(e=>!N(e),`expected a name not ending in ${M}, which ENS names keep`)}function De(e){let t=D(e);return t<1||t>20?`length`:A.test(e)?`invisible`:N(e)?`ens-like`:null}var P=O(32),F=t.z.strictObject({v:t.z.literal(9),topic:k(1,128),id:P,type:t.z.enum([T.TEXT,T.THREAD,T.REACTION]),target:t.z.union([t.z.literal(``),P]),text:k(1,500),name:Ee(1,20),addr:O(40),ts:t.z.number().int().nonnegative().max(2**53-1),via:t.z.enum([E.GATEWAY,E.OWN_STAMP]),idb:m.optional(),wl:x.optional(),sig:O(130)}).refine(e=>e.type===T.TEXT==(e.target===``),{message:`a text message has no target, a thread reply or a reaction names one`,path:[`target`]}).refine(e=>e.wl===void 0||e.idb!==void 0,{message:`a wallet link is carried only beside a chat binding, whose account it names`,path:[`wl`]}),I=class extends Error{constructor(e,t){super(`chat message refused (${e}): ${t}`),this.reason=e,this.name=`ChatMessageError`}},L=new TextEncoder,Oe=`1b`,ke=`1c`,Ae=new TextDecoder(`utf-8`,{fatal:!0});function R(e){return L.encode(JSON.stringify([e.v,e.topic,e.id,e.type,e.target,e.text,e.name,e.addr,e.ts,e.via,e.idb?.msg??``,e.idb?.sig??``,...e.wl?[e.wl.msg,e.wl.wsig,e.wl.asig]:[]]))}function z(e){let t={v:e.v,topic:e.topic,id:e.id,type:e.type,target:e.target,text:e.text,name:e.name,addr:e.addr,ts:e.ts,via:e.via,...e.idb?{idb:{msg:e.idb.msg,sig:e.idb.sig}}:{},...e.wl?{wl:{msg:e.wl.msg,wsig:e.wl.wsig,asig:e.wl.asig}}:{},sig:e.sig};return L.encode(JSON.stringify(t))}function B(){let e=crypto.getRandomValues(new Uint8Array(16));return Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function V(e){return e.issues.map(e=>`${e.path.join(`.`)||`message`}: ${e.message}`).join(`, `)}function je(t,n){let r=t instanceof e.PrivateKey?t:new e.PrivateKey(t),i={v:9,topic:n.topic,id:n.id??B(),type:n.type,target:n.target??``,text:n.text,name:n.name,addr:r.publicKey().address().toHex(),ts:n.ts??Date.now(),via:n.via,...n.idb?{idb:n.idb}:{},...n.wl?{wl:n.wl}:{}},a={...i,sig:`0`.repeat(130)},o=F.safeParse(a);if(!o.success)throw new I(`shape`,V(o.error));let s=z(a).byteLength;if(s>3072)throw new I(`too-large`,`${s} bytes, the cap is ${w}`);if(i.idb){let e=g(i.idb,i.addr,{allowLocalHttp:!0});if(!e.ok)throw new I(`binding`,e.detail);if(i.wl){let t=C(i.wl,e.identity.account);if(!t.ok)throw new I(`binding`,`wallet link: ${t.detail}`)}}let c={...i,sig:r.sign(R(i)).toHex()};return{message:c,bytes:z(c)}}function H(t){let n=t.sig.slice(128);if(n!==Oe&&n!==ke||!a(t.sig.slice(0,64),t.sig.slice(64,128)))return!1;try{return new e.Signature(t.sig).recoverPublicKey(R(t)).address().toHex()===t.addr}catch{return!1}}function U(e,t){let n=F.safeParse(e);if(!n.success)return{ok:!1,reason:`shape`,detail:V(n.error)};let r=n.data;if(!H(r))return{ok:!1,reason:`signature`,detail:`the signature was not made by addr over these fields`};if(!r.idb)return{ok:!0,message:r,identity:null};if(typeof t?.origin!=`string`)return{ok:!1,reason:`binding`,detail:`no origin was given to check the binding against`};let i=g(r.idb,r.addr,t);if(!i.ok)return{ok:!1,reason:`binding`,detail:i.detail};if(!r.wl)return{ok:!0,message:r,identity:i.identity};let a=C(r.wl,i.identity.account);return a.ok?{ok:!0,message:r,identity:{...i.identity,wallet:a.wallet}}:{ok:!1,reason:`binding`,detail:`wallet link: ${a.detail}`}}function Me(e,t){if(e.byteLength>3072)return{ok:!1,reason:`too-large`,detail:`${e.byteLength} bytes, the cap is ${w}`};let n;try{n=Ae.decode(e)}catch{return{ok:!1,reason:`not-utf8`,detail:`the payload is not valid UTF-8`}}let r;try{r=JSON.parse(n)}catch{return{ok:!1,reason:`not-json`,detail:`the payload is not JSON`}}return U(r,t)}var W=`swarm-chat-own-feed-v1:`;function Ne(e){return`${W}${e}`}var Pe=4096,Fe=t.z.string().regex(/^[0-9a-f]{64}([0-9a-f]{64})?$/,`expected a 64 or 128 hex character reference`),G=t.z.number().int().nonnegative().max(2**53-1),K=t.z.strictObject({ref:Fe,toSeq:G}),q=t.z.strictObject({v:t.z.literal(9),seq:G,at:G,msg:F,history:K.nullable()}),J=t.z.strictObject({seq:G,at:G,msg:F}),Y=t.z.strictObject({v:t.z.literal(9),topic:t.z.string().min(1),fromSeq:G,toSeq:G,messages:t.z.array(t.z.unknown()),prev:K.nullable()}).refine(e=>e.fromSeq<=e.toSeq,{message:`fromSeq is after toSeq`,path:[`fromSeq`]}),Ie=new TextDecoder(`utf-8`,{fatal:!0});function X(e){let t;try{t=Ie.decode(e)}catch{return{ok:!1,reason:`not-utf8`,detail:`the payload is not valid UTF-8`}}try{return{ok:!0,value:JSON.parse(t)}}catch{return{ok:!1,reason:`not-json`,detail:`the payload is not JSON`}}}function Z(e){return e.issues.map(e=>`${e.path.join(`.`)||`value`}: ${e.message}`).join(`, `)}function Le(e,t,n){let r=X(e);if(!r.ok)return r;let i=q.safeParse(r.value);return i.success?i.data.seq===t?i.data.msg.topic===n?{ok:!0,value:i.data}:{ok:!1,reason:`mismatch`,detail:`the message belongs to another chat`}:{ok:!1,reason:`mismatch`,detail:`seq ${i.data.seq} at index ${t}`}:{ok:!1,reason:`shape`,detail:Z(i.error)}}function Re(e,t,n){let r=X(e);if(!r.ok)return r;let i=Y.safeParse(r.value);if(!i.success)return{ok:!1,reason:`shape`,detail:Z(i.error)};if(i.data.topic!==t||i.data.toSeq!==n.toSeq)return{ok:!1,reason:`mismatch`,detail:`the file is not the one its link names`};let{fromSeq:a,toSeq:o,prev:s}=i.data,c=[],l=0;for(let e of i.data.messages){let n=J.safeParse(e);n.success&&n.data.seq>=a&&n.data.seq<=o&&n.data.msg.topic===t?c.push(n.data):l++}return{ok:!0,value:{topic:t,fromSeq:a,toSeq:o,rows:c,prev:s,skipped:l}}}var ze=1,Be=2e3,Ve=3e4,He=256,Q=t.z.strictObject({v:t.z.literal(1),newest:t.z.number().int().min(-1).max(2**53-1),writtenAt:t.z.number().int().nonnegative().max(2**53-1)});function $(e){if(!Number.isInteger(e)||e<=0)throw RangeError(`a note slot is a positive whole number of milliseconds, not ${e}`)}function Ue(e,t){return $(t),Math.floor(e/t)}function We(e,t){return $(t),(e+1)*t}function Ge(e,t,n){return`${e}/note/${t}/${n}`}function Ke(t,n,r){return e.Identifier.fromString(Ge(t,n,r))}function qe(t,n,r,i){let a=Ke(t,n,r);return new e.Reference(e.Bytes.keccak256(e.Bytes.concat(a.toUint8Array(),new e.EthAddress(i).toUint8Array())))}var Je=new TextEncoder,Ye=new TextDecoder(`utf-8`,{fatal:!0});function Xe(e){let t={v:1,newest:e.newest,writtenAt:e.writtenAt};return Je.encode(JSON.stringify(t))}function Ze(e){if(e.length>256)return null;try{let t=Q.safeParse(JSON.parse(Ye.decode(e)));return t.success?t.data:null}catch{return null}}Object.defineProperty(exports,"A",{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,"B",{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,"C",{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,"D",{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,"E",{enumerable:!0,get:function(){return ve}}),Object.defineProperty(exports,"F",{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,"G",{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,"H",{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,"I",{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,"J",{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,"K",{enumerable:!0,get:function(){return ne}}),Object.defineProperty(exports,"L",{enumerable:!0,get:function(){return Me}}),Object.defineProperty(exports,"M",{enumerable:!0,get:function(){return je}}),Object.defineProperty(exports,"N",{enumerable:!0,get:function(){return De}}),Object.defineProperty(exports,"O",{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,"P",{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,"R",{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,"S",{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,"T",{enumerable:!0,get:function(){return ye}}),Object.defineProperty(exports,"U",{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,"V",{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,"W",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"_",{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return Xe}}),Object.defineProperty(exports,"b",{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return Ge}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return Ze}}),Object.defineProperty(exports,"f",{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,"g",{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,"h",{enumerable:!0,get:function(){return Y}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return ze}}),Object.defineProperty(exports,"j",{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,"k",{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return We}}),Object.defineProperty(exports,"m",{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return Be}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return qe}}),Object.defineProperty(exports,"p",{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(exports,"q",{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return He}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return Ke}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return Ve}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return Ue}}),Object.defineProperty(exports,"v",{enumerable:!0,get:function(){return Le}}),Object.defineProperty(exports,"w",{enumerable:!0,get:function(){return be}}),Object.defineProperty(exports,"x",{enumerable:!0,get:function(){return Ne}}),Object.defineProperty(exports,"y",{enumerable:!0,get:function(){return Re}}),Object.defineProperty(exports,"z",{enumerable:!0,get:function(){return U}});