UNPKG

this.me

Version:

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

325 lines (324 loc) 9.74 kB
class o { 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 c { 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 = /* @__PURE__ */ new Set(), this.status(), this.socket = null; } /** 🔹 Init * Manually initializes the daemon state (status + listUs). * Useful if you need to re-check after user actions. */ 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 o(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((r) => r.message).join(", ")); return e; } // 🔹 Daemon-level helpers /** 🔹 Daemon status * Retrieves the current status of the daemon. * Use to check if the service is active and get version/uptime info. */ 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; } } /** 🔹 List all identities * Fetches all available identities (users). * Use to display or manage the list of identities. */ 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: [] }), []; } } /** 🔹 Load an identity * Loads a specific identity by alias and hash. * Use to activate or switch to a particular identity. */ 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; } } // 🔹 Me-level operations /** 🔹 Be operation * Performs a 'be' mutation for given alias, key, and value. * Use to set or update identity attributes. */ 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; } } /** 🔹 Have operation * Performs a 'have' mutation for given alias, key, and value. * Use to declare possession or ownership related to identity. */ 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; } } /** 🔹 Do operation * Performs a 'do' mutation for given alias, key, and value. * Use to record actions or activities for the identity. */ 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; } } /** 🔹 At operation * Performs an 'at' mutation for given alias, key, and value. * Use to set location or context related data for the identity. */ 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; } } /** 🔹 Relate operation * Performs a 'relate' mutation for given alias, key, and value. * Use to define relationships or connections for the identity. */ 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; } } /** 🔹 React operation * Performs a 'react' mutation for given alias, key, and value. * Use to record reactions or responses by the identity. */ 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; } } /** 🔹 Communication operation * Performs a 'communication' mutation for given alias, key, and value. * Use to log communications or messages for the identity. */ 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; } } /** 🔹 Get identity info * Queries detailed information about a specific identity by alias. * Use to retrieve public data like alias and publicKey. */ 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 u = new c(); typeof window < "u" && (window.me = u, console.log("[this.me] Global instance available as window.me")); export { u as default };