UNPKG

this.me

Version:

.me is your identity. It enables decentralized trust through cryptographic signatures.

56 lines (55 loc) 5.98 kB
"use strict";class c{constructor(t,s){this.me=t,this.url=s,this.ws=null,this.reconnectInterval=1e4,this.isConnected=!1,this.connect()}connect(){this.ws=new WebSocket(this.url),this.ws.onopen=()=>{console.log("[this.me][WS] Connected to daemon"),this.isConnected=!0,this.me.state?.status&&(this.me.state.status.active=!0,this.me.state.status.error=!1),this.#t()},this.ws.onmessage=t=>{try{const s=JSON.parse(t.data);this.#s(s)}catch{console.warn("[this.me][WS] Invalid message:",t.data)}},this.ws.onclose=()=>{console.warn("[this.me][WS] Disconnected, retrying in 10s"),this.isConnected=!1,this.me.state?.status&&(this.me.state.status.active=!1,this.me.state.status.error=!0),this.#t(),setTimeout(()=>this.connect(),this.reconnectInterval)},this.ws.onerror=t=>{console.error("[this.me][WS] Error:",t),this.ws.close()}}#s(t){switch(t.type){case"status":this.me.state.status={active:t.data.active,error:!1,data:t.data};break;case"listUs":this.me.state.listUs=t.data;break;case"update":console.log("[this.me][WS] Update event:",t.data);break;default:console.warn("[this.me][WS] Unknown message type:",t.type)}this.#t()}send(t,s){this.isConnected&&this.ws.readyState===WebSocket.OPEN&&this.ws.send(JSON.stringify({type:t,data:s}))}#t(){this.me.subscribers?.size&&this.me.subscribers.forEach(t=>t(this.me.state))}}class u{constructor(t="http://localhost:7777/graphql"){this.endpoint=t,this.state={status:{active:!1,error:!1,loading:!0,data:null},listUs:[],activeMe:null},this.subscribers=new Set,this.status(),this.socket=null}async init(){return this.#s({status:{...this.state.status,loading:!0}}),(await this.status()).active&&(await this.startSocket(),await new Promise(s=>{let a=!1;const e=this.subscribe(i=>{!a&&i.status.active!==void 0&&(a=!0,e(),s())});setTimeout(()=>{a||(a=!0,e(),s())},2e3)})),this.#s({status:{...this.state.status,loading:!1}}),this.state.status}async startSocket(){if(this.state.status.active){if(this.socket){console.warn("[this.me] WebSocket already running");return}this.socket=new c(this.endpoint.replace("/graphql","")),this.socket.on("status",t=>{this._updateFromSocket({status:{active:!0,error:!1,data:t}})}),this.socket.on("listUs",t=>{this._updateFromSocket({listUs:t})}),this.socket.on("update",t=>{console.log("[this.me] update event",t)})}}_updateFromSocket(t){this.#s(t)}setEndpoint(t){typeof t=="string"&&t.trim()!==""&&(this.endpoint=t)}getState(){return this.state}#s(t){this.state={...this.state,...t},this.subscribers.forEach(s=>s(this.state))}subscribe(t){return this.subscribers.add(t),()=>this.subscribers.delete(t)}async#t(t,s={}){const a=await fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:t,variables:s})});if(!a.ok)throw new Error(`GraphQL error: ${a.status}`);const{data:e,errors:i}=await a.json();if(i)throw new Error(i.map(o=>o.message).join(", "));return e}async status(){const t=` query { status { active version uptime } } `;try{const s=await this.#t(t),a=s.status?{active:s.status.active,version:s.status.version,uptime:s.status.uptime}:{active:!1,version:null,uptime:null};return this.#s({status:{active:a.active,error:!1,data:a}}),a}catch{const s={active:!1,version:null,uptime:null};return this.#s({status:{active:!1,error:!0,data:null}}),s}}async listUs(){const t=` query { listUs { alias path } } `;try{const s=await this.#t(t),a=Array.isArray(s.listUs)?s.listUs.map(({alias:e,path:i})=>({alias:e,path:i})):[];return this.#s({listUs:a}),a}catch{return this.#s({listUs:[]}),[]}}async loadMe(t,s){const a=` mutation($alias: String!, $hash: String!) { loadMe(alias: $alias, hash: $hash) } `;try{const i=!!(await this.#t(a,{alias:t,hash:s})).loadMe;return i&&this.#s({activeMe:t}),i}catch{return!1}}async be(t,s,a){const e=` mutation($alias: String!, $key: String!, $value: String!) { be(alias: $alias, key: $key, value: $value) } `;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).be}catch{return!1}}async have(t,s,a){const e=` mutation($alias: String!, $key: String!, $value: String!) { have(alias: $alias, key: $key, value: $value) } `;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).have}catch{return!1}}async do_(t,s,a){const e=` mutation($alias: String!, $key: String!, $value: String!) { do(alias: $alias, key: $key, value: $value) } `;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).do}catch{return!1}}async at(t,s,a){const e=` mutation($alias: String!, $key: String!, $value: String!) { at(alias: $alias, key: $key, value: $value) } `;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).at}catch{return!1}}async relate(t,s,a){const e=` mutation($alias: String!, $key: String!, $value: String!) { relate(alias: $alias, key: $key, value: $value) } `;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).relate}catch{return!1}}async react(t,s,a){const e=` mutation($alias: String!, $key: String!, $value: String!) { react(alias: $alias, key: $key, value: $value) } `;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).react}catch{return!1}}async communication(t,s,a){const e=` mutation($alias: String!, $key: String!, $value: String!) { communication(alias: $alias, key: $key, value: $value) } `;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).communication}catch{return!1}}async me(t){const s=` query($alias: String!) { me(alias: $alias) { alias publicKey } } `;try{const a=await this.#t(s,{alias:t});if(a.me&&typeof a.me=="object"){const{alias:e,publicKey:i}=a.me;return e&&i?{alias:e,publicKey:i}:null}return null}catch{return null}}}const n=new u;typeof window<"u"&&(window.me=n,console.log("[this.me] Global instance available as window.me"));module.exports=n;