this.me 2.9.43 → 3.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/LICENSE +0 -0
- package/README.md +187 -55
- package/dist/this-me.cjs.js +55 -0
- package/dist/this-me.es.js +324 -0
- package/dist/this-me.umd.js +55 -0
- package/package.json +27 -18
- package/index.js +0 -10
- package/jsdoc.json +0 -41
- package/notes/Index.md +0 -134
- package/notes/Inmutabilidad_de_la_Identidad_basica.md +0 -44
- package/notes/Questions.md +0 -62
- package/notes/hot_encoding.md +0 -44
- package/src/.me.cli.js +0 -20
- package/src/example.js +0 -25
- package/src/me.js +0 -54
package/LICENSE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
@@ -1,77 +1,209 @@
|
|
|
1
1
|
<img src="https://docs.neurons.me/media/all-this/webP/this.me.webp" alt="SVG Image" width="250" height="250">
|
|
2
2
|
|
|
3
3
|
# THIS.ME
|
|
4
|
-
> **This.Me** is a data-structured identity designed to generate and manage identities, attributes, properties and more.
|
|
4
|
+
> **This.Me** is a data-structured identity designed to generate and manage identities, attributes, properties and more. It combines privacy, user control, and secure interoperability.
|
|
5
|
+
|
|
6
|
+
<strong>.me</strong> is your identity that lives on your machine, under your control. It holds attributes, relationships, and keys that define who you are—and crucially, <strong>how you relate to others</strong>.
|
|
5
7
|
|
|
6
8
|
# Getting Started:
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
10
|
+
You can use **this.me** both in the browser and in Node environments. The library automatically detects the environment and provides a single global instance of `me` once initialized.
|
|
11
|
+
|
|
12
|
+
### **1. Installation**
|
|
13
|
+
|
|
14
|
+
If you are using npm:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install this.me
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or load it directly in the browser (after building):
|
|
21
|
+
|
|
22
|
+
```html
|
|
23
|
+
<script src="this.me.umd.js"></script>
|
|
24
|
+
<script>
|
|
25
|
+
// Global instance automatically attached to `window.me`
|
|
26
|
+
console.log(me); // Ready to use after initialization
|
|
27
|
+
</script>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
### **2. Initialization**
|
|
33
|
+
|
|
34
|
+
You need to initialize the `.me` instance before using it:
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
import me from "this.me";
|
|
38
|
+
|
|
39
|
+
await me.init({
|
|
40
|
+
monadEndpoint: "http://localhost:7777" // optional, defaults to 7777
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Once initialized, the `me` instance will maintain its state (status, loaded identities, etc.) globally.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### **3. Checking Daemon Status**
|
|
49
|
+
|
|
50
|
+
You can verify if the local daemon is running:
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
const status = await me.status();
|
|
54
|
+
console.log("Daemon active:", status.active);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The floating components or any GUI indicators (green/red) can rely directly on `me.status()`.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
### **4. Listing Identities**
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
const list = await me.listUs();
|
|
65
|
+
console.log(list);
|
|
66
|
+
/*
|
|
67
|
+
[
|
|
68
|
+
{ alias: "suign", path: "/Users/abellae/.this/me/suign" }
|
|
69
|
+
]
|
|
70
|
+
*/
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
### **5. Loading an Identity**
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
await me.load("abellae", "mySecretHash");
|
|
79
|
+
console.log(me.active); // true if identity is successfully loaded
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
After loading, you can use all available methods (`be`, `have`, `do`, etc.).
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### **6. Example in the Browser Console**
|
|
87
|
+
|
|
88
|
+
If you include the UMD bundle:
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<script src="this.me.umd.js"></script>
|
|
92
|
+
<script>
|
|
93
|
+
(async () => {
|
|
94
|
+
await me.init();
|
|
95
|
+
console.log(await me.status());
|
|
96
|
+
console.log(await me.listUs());
|
|
97
|
+
})();
|
|
98
|
+
</script>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
- `me` is a **singleton instance** that lives in memory once initialized.
|
|
102
|
+
- Works in both browser and Node.
|
|
103
|
+
- Provides methods for status, identity management, and attribute handling.
|
|
104
|
+
|
|
105
|
+
------
|
|
106
|
+
|
|
107
|
+
# How this.me **Works (Simplified)**
|
|
108
|
+
|
|
109
|
+
The Me class creates and manages a **local, encrypted identity file** based on a username and a secret hash.
|
|
110
|
+
|
|
111
|
+
#### **Creating a new identity**
|
|
112
|
+
|
|
113
|
+
When you run:
|
|
34
114
|
|
|
35
115
|
```js
|
|
36
|
-
|
|
37
|
-
me.be({ name: "Alice", phone: "33550000" });
|
|
116
|
+
Me.create('abellae', 'mySecretHash');
|
|
38
117
|
```
|
|
39
118
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
119
|
+
It does the following:
|
|
120
|
+
|
|
121
|
+
- Builds a .me file path: ~/.this/me/abellae.me.
|
|
122
|
+
- Creates some **identity data** (username, keys, attributes, etc.).
|
|
123
|
+
- Uses the hash to **encrypt** that data with AES-256-CBC:
|
|
124
|
+
- It generates a random iv (initialization vector).
|
|
125
|
+
- Derives a key from the hash (sha256(hash)).
|
|
126
|
+
- Stores the encrypted result as iv + encryptedData.
|
|
127
|
+
|
|
128
|
+
> 🔒 The hash is **never saved** — it’s just used as a secret key.
|
|
129
|
+
|
|
130
|
+
------
|
|
131
|
+
|
|
132
|
+
#### Loading an existing identity
|
|
43
133
|
|
|
44
|
-
|
|
45
|
-
1. **Setup**: A developer installs this.me and configures it to connect to neurons.me.
|
|
46
|
-
2. **User Registration**: Users register their Me identity through the service, and the library connects to the neurons.me registry for verification.
|
|
47
|
-
3. **Service Interaction**: When a user interacts with a service that uses this.me, the service can trust the identity by querying the selected registry.
|
|
134
|
+
When you run:
|
|
48
135
|
|
|
49
|
-
**Implementation:**
|
|
50
136
|
```js
|
|
51
|
-
|
|
52
|
-
const config = {
|
|
53
|
-
registryURL: 'https://registry.neurons.me', // Registry authority URL
|
|
54
|
-
};
|
|
55
|
-
let me = new Me('alice', config);
|
|
56
|
-
me.register({ password: 'securePass123', email: 'alice@example.com' });
|
|
57
|
-
// Verify and interact with services using the connected registry
|
|
137
|
+
Me.load('abellae', 'mySecretHash');
|
|
58
138
|
```
|
|
59
139
|
|
|
60
|
-
|
|
140
|
+
It:
|
|
141
|
+
|
|
142
|
+
- Reads the encrypted .me file.
|
|
143
|
+
- Extracts the first 16 bytes as iv.
|
|
144
|
+
- Recomputes the key from the given hash.
|
|
145
|
+
- Tries to decrypt the file.
|
|
146
|
+
- If it works, it unlocks the identity and loads the data into memory.
|
|
147
|
+
|
|
148
|
+
------
|
|
149
|
+
|
|
150
|
+
#### **Using the unlocked identity**
|
|
151
|
+
|
|
152
|
+
Once unlocked, you can:
|
|
153
|
+
|
|
154
|
+
- Set attributes: me.be('developer', true)
|
|
155
|
+
- Add endorsements: me.addEndorsement(...)
|
|
156
|
+
- View attributes: me.getAttributes()
|
|
157
|
+
- Save updates with: me.save('mySecretHash')
|
|
158
|
+
|
|
159
|
+
------
|
|
160
|
+
|
|
161
|
+
### **Summary**
|
|
162
|
+
|
|
163
|
+
- Your identity is encrypted on your own machine.
|
|
164
|
+
- Only the correct hash can unlock it.
|
|
165
|
+
- No third parties are involved.
|
|
166
|
+
- The .me file is secure, portable, and self-owned.
|
|
167
|
+
|
|
168
|
+
Let me know if you’d like a diagram or visual flow to go with this explanation!
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
### 🔍 Core Principles
|
|
173
|
+
|
|
174
|
+
1. **Freedom to Declare**
|
|
175
|
+
Anyone can generate a `.me` identity locally without external approval.
|
|
176
|
+
2. **Trusted Endorsements**
|
|
177
|
+
Authorities (e.g., Cleaker) can endorse `.me` identities without controlling them.
|
|
178
|
+
3. **Local Ownership**
|
|
179
|
+
All sensitive data (including private keys) stays on the user's machine.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
### 🛡️ Security Model
|
|
183
|
+
* No private key ever leaves the local `.me` file.
|
|
184
|
+
* Endorsements are public and verifiable using the public key.
|
|
185
|
+
* If compromised, user can rotate keys and notify authorities.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
## 🌐 Multi-Device Support
|
|
189
|
+
* `.me` can be restored using a seed phrase or backup.
|
|
190
|
+
* New devices can be authorized using signatures from old devices.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
## 🌍 Use Cases
|
|
194
|
+
* Digital signature of documents
|
|
195
|
+
* Smart contract interaction
|
|
196
|
+
* Federated profiles with trust anchors
|
|
197
|
+
* Group identity and shared contexts (`me && you && them in context/friends`)
|
|
198
|
+
|
|
199
|
+
---
|
|
61
200
|
<img src="https://suign.github.io/assets/imgs/monads.png" alt="Cleak Me Please" width="244">Hello, I am **.me**
|
|
201
|
+
|
|
62
202
|
### ❯ add.me
|
|
63
203
|
----
|
|
64
204
|
|
|
65
|
-
###### Using the CLI and this.me globally to manage user sessions.
|
|
66
|
-
```bash
|
|
67
|
-
npm i -g this.me
|
|
68
|
-
```
|
|
69
|
-
----------
|
|
70
|
-
|
|
71
205
|
# What is All.This?
|
|
72
|
-
|
|
73
206
|
###### Modular Data Structures:
|
|
74
|
-
|
|
75
207
|
**Each module** in **[all.this](https://neurons.me/all-this)** represents a specific **datastructure**. These **classes** encapsulate the functionalities and **data specific to their domain.**
|
|
76
208
|
|
|
77
209
|
**[this.me](https://docs.neurons.me/this.me/index.html) - [this.audio](https://docs.neurons.me/this.audio/index.html) - [this.text](https://docs.neurons.me/this.text/index.html) - [this.wallet](https://docs.neurons.me/this.wallet/index.html) - [this.img](https://docs.neurons.me/this.img/index.html) - [this.pixel](https://docs.neurons.me/this.pixel/index.html) - [be.this](https://docs.neurons.me/be.this/index.html) - [this.DOM](https://docs.neurons.me/this.DOM/index.html) - [this.env](https://docs.neurons.me/this.env/index.html) - [this.GUI](https://docs.neurons.me/this.GUI/index.html) - [this.be](https://docs.neurons.me/this.be/index.html) - [this.video](https://docs.neurons.me/this.video/index.html) - [this.dictionaries](https://docs.neurons.me/this.dictionaries/index.html)**
|
|
@@ -81,7 +213,7 @@ If you are interested in collaborating or wish to share your insights, please fe
|
|
|
81
213
|
|
|
82
214
|
#### License & Policies
|
|
83
215
|
- **License**: MIT License.
|
|
84
|
-
- **Learn more** at **https://
|
|
85
|
-
[Terms](https://
|
|
216
|
+
- **Learn more** at **https://neurons.me**
|
|
217
|
+
[Terms](https://neurons.me/terms-and-conditions) | [Privacy](https://neurons.me/privacy-policy)
|
|
86
218
|
|
|
87
219
|
<img src="https://docs.neurons.me/neurons.me.webp" alt="neurons.me logo" width="123" height="123">
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"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=`
|
|
2
|
+
query {
|
|
3
|
+
status {
|
|
4
|
+
active
|
|
5
|
+
version
|
|
6
|
+
uptime
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
`;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=`
|
|
10
|
+
query {
|
|
11
|
+
listUs {
|
|
12
|
+
alias
|
|
13
|
+
path
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
`;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=`
|
|
17
|
+
mutation($alias: String!, $hash: String!) {
|
|
18
|
+
loadMe(alias: $alias, hash: $hash)
|
|
19
|
+
}
|
|
20
|
+
`;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=`
|
|
21
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
22
|
+
be(alias: $alias, key: $key, value: $value)
|
|
23
|
+
}
|
|
24
|
+
`;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).be}catch{return!1}}async have(t,s,a){const e=`
|
|
25
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
26
|
+
have(alias: $alias, key: $key, value: $value)
|
|
27
|
+
}
|
|
28
|
+
`;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).have}catch{return!1}}async do_(t,s,a){const e=`
|
|
29
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
30
|
+
do(alias: $alias, key: $key, value: $value)
|
|
31
|
+
}
|
|
32
|
+
`;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).do}catch{return!1}}async at(t,s,a){const e=`
|
|
33
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
34
|
+
at(alias: $alias, key: $key, value: $value)
|
|
35
|
+
}
|
|
36
|
+
`;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).at}catch{return!1}}async relate(t,s,a){const e=`
|
|
37
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
38
|
+
relate(alias: $alias, key: $key, value: $value)
|
|
39
|
+
}
|
|
40
|
+
`;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).relate}catch{return!1}}async react(t,s,a){const e=`
|
|
41
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
42
|
+
react(alias: $alias, key: $key, value: $value)
|
|
43
|
+
}
|
|
44
|
+
`;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).react}catch{return!1}}async communication(t,s,a){const e=`
|
|
45
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
46
|
+
communication(alias: $alias, key: $key, value: $value)
|
|
47
|
+
}
|
|
48
|
+
`;try{return!!(await this.#t(e,{alias:t,key:s,value:a})).communication}catch{return!1}}async me(t){const s=`
|
|
49
|
+
query($alias: String!) {
|
|
50
|
+
me(alias: $alias) {
|
|
51
|
+
alias
|
|
52
|
+
publicKey
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
`;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;
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
class o {
|
|
2
|
+
constructor(t, s) {
|
|
3
|
+
this.me = t, this.url = s, this.ws = null, this.reconnectInterval = 1e4, this.isConnected = !1, this.connect();
|
|
4
|
+
}
|
|
5
|
+
connect() {
|
|
6
|
+
this.ws = new WebSocket(this.url), this.ws.onopen = () => {
|
|
7
|
+
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();
|
|
8
|
+
}, this.ws.onmessage = (t) => {
|
|
9
|
+
try {
|
|
10
|
+
const s = JSON.parse(t.data);
|
|
11
|
+
this.#s(s);
|
|
12
|
+
} catch {
|
|
13
|
+
console.warn("[this.me][WS] Invalid message:", t.data);
|
|
14
|
+
}
|
|
15
|
+
}, this.ws.onclose = () => {
|
|
16
|
+
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);
|
|
17
|
+
}, this.ws.onerror = (t) => {
|
|
18
|
+
console.error("[this.me][WS] Error:", t), this.ws.close();
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
#s(t) {
|
|
22
|
+
switch (t.type) {
|
|
23
|
+
case "status":
|
|
24
|
+
this.me.state.status = {
|
|
25
|
+
active: t.data.active,
|
|
26
|
+
error: !1,
|
|
27
|
+
data: t.data
|
|
28
|
+
};
|
|
29
|
+
break;
|
|
30
|
+
case "listUs":
|
|
31
|
+
this.me.state.listUs = t.data;
|
|
32
|
+
break;
|
|
33
|
+
case "update":
|
|
34
|
+
console.log("[this.me][WS] Update event:", t.data);
|
|
35
|
+
break;
|
|
36
|
+
default:
|
|
37
|
+
console.warn("[this.me][WS] Unknown message type:", t.type);
|
|
38
|
+
}
|
|
39
|
+
this.#t();
|
|
40
|
+
}
|
|
41
|
+
send(t, s) {
|
|
42
|
+
this.isConnected && this.ws.readyState === WebSocket.OPEN && this.ws.send(JSON.stringify({ type: t, data: s }));
|
|
43
|
+
}
|
|
44
|
+
#t() {
|
|
45
|
+
this.me.subscribers?.size && this.me.subscribers.forEach((t) => t(this.me.state));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
class c {
|
|
49
|
+
constructor(t = "http://localhost:7777/graphql") {
|
|
50
|
+
this.endpoint = t, this.state = {
|
|
51
|
+
status: { active: !1, error: !1, loading: !0, data: null },
|
|
52
|
+
listUs: [],
|
|
53
|
+
activeMe: null
|
|
54
|
+
}, this.subscribers = /* @__PURE__ */ new Set(), this.status(), this.socket = null;
|
|
55
|
+
}
|
|
56
|
+
/** 🔹 Init
|
|
57
|
+
* Manually initializes the daemon state (status + listUs).
|
|
58
|
+
* Useful if you need to re-check after user actions.
|
|
59
|
+
*/
|
|
60
|
+
async init() {
|
|
61
|
+
return this.#s({
|
|
62
|
+
status: { ...this.state.status, loading: !0 }
|
|
63
|
+
}), (await this.status()).active && (await this.startSocket(), await new Promise((s) => {
|
|
64
|
+
let a = !1;
|
|
65
|
+
const e = this.subscribe((i) => {
|
|
66
|
+
!a && i.status.active !== void 0 && (a = !0, e(), s());
|
|
67
|
+
});
|
|
68
|
+
setTimeout(() => {
|
|
69
|
+
a || (a = !0, e(), s());
|
|
70
|
+
}, 2e3);
|
|
71
|
+
})), this.#s({
|
|
72
|
+
status: { ...this.state.status, loading: !1 }
|
|
73
|
+
}), this.state.status;
|
|
74
|
+
}
|
|
75
|
+
async startSocket() {
|
|
76
|
+
if (this.state.status.active) {
|
|
77
|
+
if (this.socket) {
|
|
78
|
+
console.warn("[this.me] WebSocket already running");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
this.socket = new o(this.endpoint.replace("/graphql", "")), this.socket.on("status", (t) => {
|
|
82
|
+
this._updateFromSocket({
|
|
83
|
+
status: { active: !0, error: !1, data: t }
|
|
84
|
+
});
|
|
85
|
+
}), this.socket.on("listUs", (t) => {
|
|
86
|
+
this._updateFromSocket({ listUs: t });
|
|
87
|
+
}), this.socket.on("update", (t) => {
|
|
88
|
+
console.log("[this.me] update event", t);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
_updateFromSocket(t) {
|
|
93
|
+
this.#s(t);
|
|
94
|
+
}
|
|
95
|
+
setEndpoint(t) {
|
|
96
|
+
typeof t == "string" && t.trim() !== "" && (this.endpoint = t);
|
|
97
|
+
}
|
|
98
|
+
getState() {
|
|
99
|
+
return this.state;
|
|
100
|
+
}
|
|
101
|
+
#s(t) {
|
|
102
|
+
this.state = { ...this.state, ...t }, this.subscribers.forEach((s) => s(this.state));
|
|
103
|
+
}
|
|
104
|
+
subscribe(t) {
|
|
105
|
+
return this.subscribers.add(t), () => this.subscribers.delete(t);
|
|
106
|
+
}
|
|
107
|
+
async #t(t, s = {}) {
|
|
108
|
+
const a = await fetch(this.endpoint, {
|
|
109
|
+
method: "POST",
|
|
110
|
+
headers: { "Content-Type": "application/json" },
|
|
111
|
+
body: JSON.stringify({ query: t, variables: s })
|
|
112
|
+
});
|
|
113
|
+
if (!a.ok) throw new Error(`GraphQL error: ${a.status}`);
|
|
114
|
+
const { data: e, errors: i } = await a.json();
|
|
115
|
+
if (i) throw new Error(i.map((r) => r.message).join(", "));
|
|
116
|
+
return e;
|
|
117
|
+
}
|
|
118
|
+
// 🔹 Daemon-level helpers
|
|
119
|
+
/** 🔹 Daemon status
|
|
120
|
+
* Retrieves the current status of the daemon.
|
|
121
|
+
* Use to check if the service is active and get version/uptime info.
|
|
122
|
+
*/
|
|
123
|
+
async status() {
|
|
124
|
+
const t = `
|
|
125
|
+
query {
|
|
126
|
+
status {
|
|
127
|
+
active
|
|
128
|
+
version
|
|
129
|
+
uptime
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
`;
|
|
133
|
+
try {
|
|
134
|
+
const s = await this.#t(t), a = s.status ? {
|
|
135
|
+
active: s.status.active,
|
|
136
|
+
version: s.status.version,
|
|
137
|
+
uptime: s.status.uptime
|
|
138
|
+
} : { active: !1, version: null, uptime: null };
|
|
139
|
+
return this.#s({ status: { active: a.active, error: !1, data: a } }), a;
|
|
140
|
+
} catch {
|
|
141
|
+
const s = { active: !1, version: null, uptime: null };
|
|
142
|
+
return this.#s({ status: { active: !1, error: !0, data: null } }), s;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/** 🔹 List all identities
|
|
146
|
+
* Fetches all available identities (users).
|
|
147
|
+
* Use to display or manage the list of identities.
|
|
148
|
+
*/
|
|
149
|
+
async listUs() {
|
|
150
|
+
const t = `
|
|
151
|
+
query {
|
|
152
|
+
listUs {
|
|
153
|
+
alias
|
|
154
|
+
path
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
`;
|
|
158
|
+
try {
|
|
159
|
+
const s = await this.#t(t), a = Array.isArray(s.listUs) ? s.listUs.map(({ alias: e, path: i }) => ({ alias: e, path: i })) : [];
|
|
160
|
+
return this.#s({ listUs: a }), a;
|
|
161
|
+
} catch {
|
|
162
|
+
return this.#s({ listUs: [] }), [];
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/** 🔹 Load an identity
|
|
166
|
+
* Loads a specific identity by alias and hash.
|
|
167
|
+
* Use to activate or switch to a particular identity.
|
|
168
|
+
*/
|
|
169
|
+
async loadMe(t, s) {
|
|
170
|
+
const a = `
|
|
171
|
+
mutation($alias: String!, $hash: String!) {
|
|
172
|
+
loadMe(alias: $alias, hash: $hash)
|
|
173
|
+
}
|
|
174
|
+
`;
|
|
175
|
+
try {
|
|
176
|
+
const i = !!(await this.#t(a, { alias: t, hash: s })).loadMe;
|
|
177
|
+
return i && this.#s({ activeMe: t }), i;
|
|
178
|
+
} catch {
|
|
179
|
+
return !1;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// 🔹 Me-level operations
|
|
183
|
+
/** 🔹 Be operation
|
|
184
|
+
* Performs a 'be' mutation for given alias, key, and value.
|
|
185
|
+
* Use to set or update identity attributes.
|
|
186
|
+
*/
|
|
187
|
+
async be(t, s, a) {
|
|
188
|
+
const e = `
|
|
189
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
190
|
+
be(alias: $alias, key: $key, value: $value)
|
|
191
|
+
}
|
|
192
|
+
`;
|
|
193
|
+
try {
|
|
194
|
+
return !!(await this.#t(e, { alias: t, key: s, value: a })).be;
|
|
195
|
+
} catch {
|
|
196
|
+
return !1;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/** 🔹 Have operation
|
|
200
|
+
* Performs a 'have' mutation for given alias, key, and value.
|
|
201
|
+
* Use to declare possession or ownership related to identity.
|
|
202
|
+
*/
|
|
203
|
+
async have(t, s, a) {
|
|
204
|
+
const e = `
|
|
205
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
206
|
+
have(alias: $alias, key: $key, value: $value)
|
|
207
|
+
}
|
|
208
|
+
`;
|
|
209
|
+
try {
|
|
210
|
+
return !!(await this.#t(e, { alias: t, key: s, value: a })).have;
|
|
211
|
+
} catch {
|
|
212
|
+
return !1;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/** 🔹 Do operation
|
|
216
|
+
* Performs a 'do' mutation for given alias, key, and value.
|
|
217
|
+
* Use to record actions or activities for the identity.
|
|
218
|
+
*/
|
|
219
|
+
async do_(t, s, a) {
|
|
220
|
+
const e = `
|
|
221
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
222
|
+
do(alias: $alias, key: $key, value: $value)
|
|
223
|
+
}
|
|
224
|
+
`;
|
|
225
|
+
try {
|
|
226
|
+
return !!(await this.#t(e, { alias: t, key: s, value: a })).do;
|
|
227
|
+
} catch {
|
|
228
|
+
return !1;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/** 🔹 At operation
|
|
232
|
+
* Performs an 'at' mutation for given alias, key, and value.
|
|
233
|
+
* Use to set location or context related data for the identity.
|
|
234
|
+
*/
|
|
235
|
+
async at(t, s, a) {
|
|
236
|
+
const e = `
|
|
237
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
238
|
+
at(alias: $alias, key: $key, value: $value)
|
|
239
|
+
}
|
|
240
|
+
`;
|
|
241
|
+
try {
|
|
242
|
+
return !!(await this.#t(e, { alias: t, key: s, value: a })).at;
|
|
243
|
+
} catch {
|
|
244
|
+
return !1;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/** 🔹 Relate operation
|
|
248
|
+
* Performs a 'relate' mutation for given alias, key, and value.
|
|
249
|
+
* Use to define relationships or connections for the identity.
|
|
250
|
+
*/
|
|
251
|
+
async relate(t, s, a) {
|
|
252
|
+
const e = `
|
|
253
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
254
|
+
relate(alias: $alias, key: $key, value: $value)
|
|
255
|
+
}
|
|
256
|
+
`;
|
|
257
|
+
try {
|
|
258
|
+
return !!(await this.#t(e, { alias: t, key: s, value: a })).relate;
|
|
259
|
+
} catch {
|
|
260
|
+
return !1;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/** 🔹 React operation
|
|
264
|
+
* Performs a 'react' mutation for given alias, key, and value.
|
|
265
|
+
* Use to record reactions or responses by the identity.
|
|
266
|
+
*/
|
|
267
|
+
async react(t, s, a) {
|
|
268
|
+
const e = `
|
|
269
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
270
|
+
react(alias: $alias, key: $key, value: $value)
|
|
271
|
+
}
|
|
272
|
+
`;
|
|
273
|
+
try {
|
|
274
|
+
return !!(await this.#t(e, { alias: t, key: s, value: a })).react;
|
|
275
|
+
} catch {
|
|
276
|
+
return !1;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/** 🔹 Communication operation
|
|
280
|
+
* Performs a 'communication' mutation for given alias, key, and value.
|
|
281
|
+
* Use to log communications or messages for the identity.
|
|
282
|
+
*/
|
|
283
|
+
async communication(t, s, a) {
|
|
284
|
+
const e = `
|
|
285
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
286
|
+
communication(alias: $alias, key: $key, value: $value)
|
|
287
|
+
}
|
|
288
|
+
`;
|
|
289
|
+
try {
|
|
290
|
+
return !!(await this.#t(e, { alias: t, key: s, value: a })).communication;
|
|
291
|
+
} catch {
|
|
292
|
+
return !1;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/** 🔹 Get identity info
|
|
296
|
+
* Queries detailed information about a specific identity by alias.
|
|
297
|
+
* Use to retrieve public data like alias and publicKey.
|
|
298
|
+
*/
|
|
299
|
+
async me(t) {
|
|
300
|
+
const s = `
|
|
301
|
+
query($alias: String!) {
|
|
302
|
+
me(alias: $alias) {
|
|
303
|
+
alias
|
|
304
|
+
publicKey
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
`;
|
|
308
|
+
try {
|
|
309
|
+
const a = await this.#t(s, { alias: t });
|
|
310
|
+
if (a.me && typeof a.me == "object") {
|
|
311
|
+
const { alias: e, publicKey: i } = a.me;
|
|
312
|
+
return e && i ? { alias: e, publicKey: i } : null;
|
|
313
|
+
}
|
|
314
|
+
return null;
|
|
315
|
+
} catch {
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
const u = new c();
|
|
321
|
+
typeof window < "u" && (window.me = u, console.log("[this.me] Global instance available as window.me"));
|
|
322
|
+
export {
|
|
323
|
+
u as default
|
|
324
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
(function(n,r){typeof exports=="object"&&typeof module<"u"?module.exports=r():typeof define=="function"&&define.amd?define(r):(n=typeof globalThis<"u"?globalThis:n||self,n.Me=r())})(this,function(){"use strict";class n{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 r{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 e=!1;const a=this.subscribe(i=>{!e&&i.status.active!==void 0&&(e=!0,a(),s())});setTimeout(()=>{e||(e=!0,a(),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 n(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 e=await fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:t,variables:s})});if(!e.ok)throw new Error(`GraphQL error: ${e.status}`);const{data:a,errors:i}=await e.json();if(i)throw new Error(i.map(u=>u.message).join(", "));return a}async status(){const t=`
|
|
2
|
+
query {
|
|
3
|
+
status {
|
|
4
|
+
active
|
|
5
|
+
version
|
|
6
|
+
uptime
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
`;try{const s=await this.#t(t),e=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:e.active,error:!1,data:e}}),e}catch{const s={active:!1,version:null,uptime:null};return this.#s({status:{active:!1,error:!0,data:null}}),s}}async listUs(){const t=`
|
|
10
|
+
query {
|
|
11
|
+
listUs {
|
|
12
|
+
alias
|
|
13
|
+
path
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
`;try{const s=await this.#t(t),e=Array.isArray(s.listUs)?s.listUs.map(({alias:a,path:i})=>({alias:a,path:i})):[];return this.#s({listUs:e}),e}catch{return this.#s({listUs:[]}),[]}}async loadMe(t,s){const e=`
|
|
17
|
+
mutation($alias: String!, $hash: String!) {
|
|
18
|
+
loadMe(alias: $alias, hash: $hash)
|
|
19
|
+
}
|
|
20
|
+
`;try{const i=!!(await this.#t(e,{alias:t,hash:s})).loadMe;return i&&this.#s({activeMe:t}),i}catch{return!1}}async be(t,s,e){const a=`
|
|
21
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
22
|
+
be(alias: $alias, key: $key, value: $value)
|
|
23
|
+
}
|
|
24
|
+
`;try{return!!(await this.#t(a,{alias:t,key:s,value:e})).be}catch{return!1}}async have(t,s,e){const a=`
|
|
25
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
26
|
+
have(alias: $alias, key: $key, value: $value)
|
|
27
|
+
}
|
|
28
|
+
`;try{return!!(await this.#t(a,{alias:t,key:s,value:e})).have}catch{return!1}}async do_(t,s,e){const a=`
|
|
29
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
30
|
+
do(alias: $alias, key: $key, value: $value)
|
|
31
|
+
}
|
|
32
|
+
`;try{return!!(await this.#t(a,{alias:t,key:s,value:e})).do}catch{return!1}}async at(t,s,e){const a=`
|
|
33
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
34
|
+
at(alias: $alias, key: $key, value: $value)
|
|
35
|
+
}
|
|
36
|
+
`;try{return!!(await this.#t(a,{alias:t,key:s,value:e})).at}catch{return!1}}async relate(t,s,e){const a=`
|
|
37
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
38
|
+
relate(alias: $alias, key: $key, value: $value)
|
|
39
|
+
}
|
|
40
|
+
`;try{return!!(await this.#t(a,{alias:t,key:s,value:e})).relate}catch{return!1}}async react(t,s,e){const a=`
|
|
41
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
42
|
+
react(alias: $alias, key: $key, value: $value)
|
|
43
|
+
}
|
|
44
|
+
`;try{return!!(await this.#t(a,{alias:t,key:s,value:e})).react}catch{return!1}}async communication(t,s,e){const a=`
|
|
45
|
+
mutation($alias: String!, $key: String!, $value: String!) {
|
|
46
|
+
communication(alias: $alias, key: $key, value: $value)
|
|
47
|
+
}
|
|
48
|
+
`;try{return!!(await this.#t(a,{alias:t,key:s,value:e})).communication}catch{return!1}}async me(t){const s=`
|
|
49
|
+
query($alias: String!) {
|
|
50
|
+
me(alias: $alias) {
|
|
51
|
+
alias
|
|
52
|
+
publicKey
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
`;try{const e=await this.#t(s,{alias:t});if(e.me&&typeof e.me=="object"){const{alias:a,publicKey:i}=e.me;return a&&i?{alias:a,publicKey:i}:null}return null}catch{return null}}}const o=new r;return typeof window<"u"&&(window.me=o,console.log("[this.me] Global instance available as window.me")),o});
|
package/package.json
CHANGED
|
@@ -1,33 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "this.me",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"main": "
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": ".me is your identity. It enables decentralized trust through cryptographic signatures.",
|
|
5
|
+
"main": "dist/this-me.cjs.js",
|
|
6
|
+
"module": "dist/this-me.es.js",
|
|
7
|
+
"browser": "dist/this-me.umd.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/this-me.es.js",
|
|
11
|
+
"require": "./dist/this-me.cjs.js"
|
|
12
|
+
}
|
|
12
13
|
},
|
|
14
|
+
"type": "module",
|
|
13
15
|
"keywords": [
|
|
14
16
|
"this.me",
|
|
15
|
-
"
|
|
17
|
+
"identity",
|
|
18
|
+
"decentralized",
|
|
19
|
+
"cryptographic",
|
|
20
|
+
"trust",
|
|
21
|
+
"signature",
|
|
22
|
+
"local",
|
|
23
|
+
"self-sovereign",
|
|
24
|
+
"monad"
|
|
16
25
|
],
|
|
17
26
|
"repository": {
|
|
18
27
|
"type": "git",
|
|
19
28
|
"url": "git+https://github.com/neurons-me/this.me.git"
|
|
20
29
|
},
|
|
21
30
|
"homepage": "https://www.npmjs.com/package/this.me",
|
|
22
|
-
"docs": "https://suiGn.github.io/this.me",
|
|
23
|
-
"type": "module",
|
|
24
31
|
"author": "suiGn",
|
|
25
32
|
"license": "MIT",
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
"files": [
|
|
34
|
+
"dist"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "vite build"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"vite": "^7.0.6"
|
|
32
41
|
}
|
|
33
42
|
}
|
package/index.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
//index.js
|
|
2
|
-
/**
|
|
3
|
-
* @module This.Me
|
|
4
|
-
* @description
|
|
5
|
-
* This.Me is a data-structured identity...
|
|
6
|
-
* */
|
|
7
|
-
|
|
8
|
-
import Me from './src/me.js';
|
|
9
|
-
//when a user declares "I am %.me," their digital existence is affirmed and recorded in the system.
|
|
10
|
-
export default Me;
|
package/jsdoc.json
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"source": {
|
|
3
|
-
"include": ["./src", "./index.js", "./README.md"]
|
|
4
|
-
},
|
|
5
|
-
"opts": {
|
|
6
|
-
"destination": "/mnt/neuroverse/https-neurons/subDomains/docs/public/this.me",
|
|
7
|
-
"template": "../../../suign.github.io/Sandbox/better-docs/",
|
|
8
|
-
"readme": "./README.md"
|
|
9
|
-
},
|
|
10
|
-
"templates": {
|
|
11
|
-
"cleverLinks": false,
|
|
12
|
-
"monospaceLinks": false,
|
|
13
|
-
"search": true,
|
|
14
|
-
"default": {
|
|
15
|
-
"staticFiles": {
|
|
16
|
-
"include": ["./README.md"]
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"better-docs": {
|
|
20
|
-
"name": "this.me",
|
|
21
|
-
"title": "this.me Docs",
|
|
22
|
-
"css": "style.css",
|
|
23
|
-
"trackingCode": "...",
|
|
24
|
-
"hideGenerator": false,
|
|
25
|
-
"navLinks": [
|
|
26
|
-
{
|
|
27
|
-
"label": "All.This",
|
|
28
|
-
"href": "https://docs.neurons.me/all.this/"
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"label": "Neurons.me",
|
|
32
|
-
"href": "https://neurons.me"
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"label": "Github",
|
|
36
|
-
"href": "https://github.com/neurons-me/this.me"
|
|
37
|
-
}
|
|
38
|
-
]
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
package/notes/Index.md
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
### **Index of `this.me` Structure**
|
|
2
|
-
Here’s a comprehensive list of the components and their purposes within the `this.me` class:
|
|
3
|
-
|
|
4
|
-
#### **1. Identity**
|
|
5
|
-
- **Description:** Immutable attributes defining the core identity of the user.
|
|
6
|
-
#### **2. Attributes**
|
|
7
|
-
- **Description:** Flexible traits and descriptive properties of the user.
|
|
8
|
-
#### **3. Relationships**
|
|
9
|
-
- **Description:** Connections and associations with others.
|
|
10
|
-
#### **4. Reactions**
|
|
11
|
-
- **Description:** User’s interactions and engagements with the world.
|
|
12
|
-
#### **5. Properties**
|
|
13
|
-
- **Description:** Items owned or managed by the user.
|
|
14
|
-
|
|
15
|
-
------
|
|
16
|
-
|
|
17
|
-
### **1. The Me Structure Overview**
|
|
18
|
-
#### **Core Components**
|
|
19
|
-
- **Identity:** The foundation of the `this.me` object.
|
|
20
|
-
- Immutable attributes: `username`, `DID`.
|
|
21
|
-
- Core methods for validation and setup.
|
|
22
|
-
|
|
23
|
-
------
|
|
24
|
-
|
|
25
|
-
- **Attributes:** Fundamental identity traits.
|
|
26
|
-
Store and manage user traits dynamically:
|
|
27
|
-
- Examples: Name, age, location, pronouns, bio.
|
|
28
|
-
**Use `.be()` to add or update attributes.**
|
|
29
|
-
|
|
30
|
-
Example:
|
|
31
|
-
```json
|
|
32
|
-
{ name: 'John Doe', age: 30, location: 'Earth' }
|
|
33
|
-
```
|
|
34
|
-
Implement `be()` as a flexible key-value store.
|
|
35
|
-
Add validation for specific attributes (if required).
|
|
36
|
-
|
|
37
|
-
------
|
|
38
|
-
|
|
39
|
-
- **Relationships:** Connections with others.
|
|
40
|
-
- Examples: Friends, groups, networks, organizations.
|
|
41
|
-
**Contacts:** Individual connections.
|
|
42
|
-
**Groups:** Collections of users with shared context.
|
|
43
|
-
|
|
44
|
-
```js
|
|
45
|
-
.relationships.addContact({ username: 'alice', status: 'friend' });
|
|
46
|
-
.relationships.createGroup({ name: 'Family', members: ['alice', 'bob'] });
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Define `addContact` and `createGroup` methods.
|
|
50
|
-
Enable nested relationship structures (e.g., groups of groups).
|
|
51
|
-
|
|
52
|
-
------
|
|
53
|
-
|
|
54
|
-
- **Reactions:** How a user interacts with the world.
|
|
55
|
-
Streamline all user engagements under `.react()`
|
|
56
|
-
- Examples: Likes, comments, shares, emotions.
|
|
57
|
-
- Categorization Rationale:
|
|
58
|
-
- Keeps all engagements unified.
|
|
59
|
-
- Expands easily (adding emojis, advanced reactions).
|
|
60
|
-
|
|
61
|
-
```js
|
|
62
|
-
.react.add({ type: 'like', target: 'PostID' });
|
|
63
|
-
.react.add({ type: 'comment', target: 'PhotoID', content: 'Great pic!' });
|
|
64
|
-
```
|
|
65
|
-
Design a structure to store and retrieve reactions efficiently.
|
|
66
|
-
Define a `log` system for reaction history.
|
|
67
|
-
|
|
68
|
-
------
|
|
69
|
-
|
|
70
|
-
- **Properties:** Things the user owns or manages.
|
|
71
|
-
Attach external, modular objects as user-owned assets:
|
|
72
|
-
- Use `this.me.properties` as a unified interface for ownership.
|
|
73
|
-
- Modular objects like `Wallet`, `Device`, `File`.
|
|
74
|
-
- Examples: Wallets, devices, digital files, accounts.
|
|
75
|
-
- **Sub-Methods:** Add, Share, Transfer Ownership, Revoke Access.
|
|
76
|
-
|
|
77
|
-
```js
|
|
78
|
-
const jabellae = new Me('jabellae'); // Create a new Me instance
|
|
79
|
-
const wallet = new Wallet({ type: 'ETH', address: '0x123...' }); // Create a wallet object
|
|
80
|
-
jabellae.addProperty(wallet); // Add wallet as a property to Me
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Implement `add`, `share`, `transferOwnership`, and `revokeAccess` methods for properties. Define modular objects (`Wallet`, `Device`) independently.
|
|
84
|
-
|
|
85
|
-
1. **Creating a Wallet**
|
|
86
|
-
The wallet is created independently and then added to the `Me` instance's properties.
|
|
87
|
-
```javascript
|
|
88
|
-
const jabellae = new Me('jabellae'); // Create a new Me instance
|
|
89
|
-
const wallet = new Wallet({ type: 'ETH', address: '0x123...' }); // Create a wallet object
|
|
90
|
-
jabellae.addProperty(wallet); // Add wallet as a property to Me
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
2. **Sharing the Wallet**
|
|
94
|
-
Sharing logic is handled by the `Me` instance, not the property itself.
|
|
95
|
-
```javascript
|
|
96
|
-
jabellae.shareProperty(wallet, 'otherMe', { permissions: 'view' });
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
3. **Transferring Ownership**
|
|
100
|
-
Ownership transfer is also managed by the `Me` instance.
|
|
101
|
-
```javascript
|
|
102
|
-
jabellae.transferOwnership(wallet, 'otherMe');
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
------
|
|
106
|
-
------
|
|
107
|
-
------
|
|
108
|
-
|
|
109
|
-
### **2. Why Independent Objects?**
|
|
110
|
-
#### **Modularity**
|
|
111
|
-
- Keeps the `this.me` instance *agnostic* of specifics.
|
|
112
|
-
- Allows new property types to integrate seamlessly.
|
|
113
|
-
|
|
114
|
-
#### **Reusability**
|
|
115
|
-
- Each property (e.g., `this.wallet`, `this.device`) operates independently.
|
|
116
|
-
- Can be ported across `this.me` instances without coupling.
|
|
117
|
-
|
|
118
|
-
#### **Transferability**
|
|
119
|
-
- Ownership is a property-level concern.
|
|
120
|
-
- Example:
|
|
121
|
-
|
|
122
|
-
```javascript
|
|
123
|
-
const wallet = new Wallet(owner = "me");
|
|
124
|
-
wallet.transferOwnership("otherMeInstance");
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
#### **Separation of Concerns**
|
|
128
|
-
- Identity (`this.me`) manages relationships, attributes, and higher-level user interactions.
|
|
129
|
-
- Objects like `Wallet` or `Device` manage their specific functionality.
|
|
130
|
-
|
|
131
|
-
#### **Scalability**
|
|
132
|
-
- Adding a new property type is as simple as:
|
|
133
|
-
1. Defining the object (e.g., `Vehicle`).
|
|
134
|
-
2. Registering it with `this.me`.
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
El mayor acto de rebelión en un mundo que busca controlarte es ser libre de verdad.
|
|
2
|
-
|
|
3
|
-
**this.me** y el proceso de autenticación con **Cleaker** como una red de identificación descentralizada (**DID**) tiene sentido dentro de un marco de criptografía y autenticación distribuida. A continuación, desgloso los puntos importantes para asegurarnos de que el concepto sea claro y funcional:
|
|
4
|
-
|
|
5
|
-
### **Inmutabilidad de la Identidad Básica**
|
|
6
|
-
**this.me** se basa en la creación de una identidad. Los componentes inmutables que mencionas (nombre de usuario, email y la red de autenticación) son fundamentales para que el sistema garantice que la identidad siempre se pueda verificar a partir de un hash único.
|
|
7
|
-
|
|
8
|
-
1. **Nombre de Usuario (username)**: El nombre de usuario es clave en la identidad. No puede cambiar una vez creado porque el hash que lo representa depende de esta cadena de caracteres.
|
|
9
|
-
2. **Correo Electrónico (email)**: Esto actúa como otra pieza inmutable, probablemente porque es un dato importante para autenticar usuarios a través de redes o servicios.
|
|
10
|
-
3. **Red de Autenticación (Cleaker)**: Como mencionas, **Cleaker** actuaría como el **DID**, o sea, la autoridad central que autentica tu identidad. Es clave para asegurar que no cualquiera pueda crear una identidad falsa.
|
|
11
|
-
|
|
12
|
-
### **Proceso de Creación del Hash**
|
|
13
|
-
Lo que estás describiendo es un esquema de hashing similar al que se usa en la criptografía para asegurar que los datos no sean manipulados. Cuando generas una identidad con `this.me`, combinas información inmutable (username, email, red) para generar un **hash único**, que se convierte en tu **clave pública**.
|
|
14
|
-
|
|
15
|
-
1. **Hash como Clave Pública**: Cuando hasheas tu información (e.g., nombre + email + red), se genera una clave pública (hash). Esta clave es única para cada combinación de información.
|
|
16
|
-
- Si cambias incluso una letra de tu nombre o red, el hash resultante será completamente diferente.
|
|
17
|
-
- Este hash será tu "firma digital" o clave pública para verificarte ante otros sistemas.
|
|
18
|
-
|
|
19
|
-
2. **Encriptación y Desencriptación de Datos**: Utilizando tu **clave pública** (hash generado), puedes firmar o desencriptar información que hayas dejado en el sistema. Esencialmente, es una forma de probar que eres el propietario legítimo de esa clave.
|
|
20
|
-
- Si alguien intenta usar un hash distinto (porque cambió alguna información), no podrá desencriptar la información asociada a tu clave pública original.
|
|
21
|
-
|
|
22
|
-
### **Uso de Cleaker como DID**
|
|
23
|
-
**Cleaker** sería la red de confianza que actúa como verificador. En este caso:
|
|
24
|
-
- **Cleaker** puede autenticar tu identidad, asegurando que el hash generado sea correcto, en el sentido de que el nombre de usuario, email, y red de autenticación son válidos.
|
|
25
|
-
- **Cleaker** también sirve como autoridad para evitar que cualquiera pueda generar una identidad falsa o duplicada. Si intentas acceder a la red con información diferente, el sistema rechaza la autenticación porque el hash no coincide con los registros en la red.
|
|
26
|
-
|
|
27
|
-
### **Flujo Ejemplificado de Autenticación**
|
|
28
|
-
1. Creas tu identidad en **this.me** con tu nombre de usuario, email y red de autenticación (**Cleaker**).
|
|
29
|
-
2. **this.me** genera un **hash único** para esa combinación de datos, lo que te da una **clave pública**.
|
|
30
|
-
3. Puedes usar esa clave pública para autenticarte en cualquier servicio compatible, y solo tú puedes desencriptar los datos usando tu hash, ya que corresponde exactamente con la información que usaste para crearlo.
|
|
31
|
-
4. Si cambias cualquier parte de tu información (nombre, email o red), obtendrás un hash completamente diferente, lo que efectivamente cambia tu identidad digital.
|
|
32
|
-
|
|
33
|
-
### **Encriptación y Desencriptación**
|
|
34
|
-
Al tener tu clave pública, puedes usarla para desencriptar datos que hayas almacenado en sistemas que utilizan **this.me**. La clave pública se usa para verificar tu identidad y acceder a la información que has dejado. Como mencionabas:
|
|
35
|
-
|
|
36
|
-
- Si hasheas "jose" y "abella", obtendrás un hash específico.
|
|
37
|
-
- Si cambias "abella" por "abellae", el hash cambia y no podrás desencriptar la información almacenada bajo el hash anterior.
|
|
38
|
-
|
|
39
|
-
Este proceso asegura que tu identidad es única y está protegida criptográficamente.
|
|
40
|
-
|
|
41
|
-
### **Conclusión**
|
|
42
|
-
Este sistema de identidad descentralizada que estás describiendo se asemeja a los **DIDs** utilizados en blockchain y criptografía, donde las identidades no dependen de un servidor centralizado, sino de la prueba criptográfica de su validez. **Cleaker** actuaría como una red que verifica la validez del hash, y **this.me** genera y gestiona las identidades de una forma flexible pero segura. El uso de hashes y criptografía garantiza que las identidades sean inmutables y verificables sin depender de terceros centralizados.
|
|
43
|
-
|
|
44
|
-
Este sistema tiene aplicaciones en una amplia gama de servicios donde la autenticación segura es fundamental y donde se quiere evitar la creación de múltiples credenciales en diferentes plataformas.
|
package/notes/Questions.md
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
Key Questions to Address
|
|
2
|
-
Identity Core: What defines the essence of .me?
|
|
3
|
-
Relationships: How does .me relate to others, groups, or larger entities?
|
|
4
|
-
Belongings: What does .me own or have as personal items?
|
|
5
|
-
Modularity: How do we allow external objects to seamlessly integrate with .me?
|
|
6
|
-
Hierarchy of Interactions: How do we classify interactions into tiers (self, relationships, society, etc.)?
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
### **1. Identity Core: What defines the essence of `.me`?**
|
|
10
|
-
- **Essence Defined:**
|
|
11
|
-
- **Immutable Core Attributes:** `username` and `DID` (Decentralized Identifier).
|
|
12
|
-
- Clearly distinguishes the user's unique existence in the digital realm.
|
|
13
|
-
- **Practical Implementation:**
|
|
14
|
-
- Identity core is foundational and unchangeable, ensuring trust and consistency across systems.
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
### **2. Relationships: How does `.me` relate to others, groups, or larger entities?**
|
|
19
|
-
- **Connections Defined:**
|
|
20
|
-
- **Contacts:** Direct relationships (e.g., friends, acquaintances).
|
|
21
|
-
- **Groups:** Collections with shared contexts (e.g., family, organizations, societies).
|
|
22
|
-
- **Methods:**
|
|
23
|
-
- `.relationships.addContact()` to add individual connections.
|
|
24
|
-
- `.relationships.createGroup()` to organize groups dynamically.
|
|
25
|
-
- **Hierarchy:**
|
|
26
|
-
- Nested structures enable relationships at various tiers (e.g., groups of groups, organizations within societies).
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
### **3. Belongings: What does `.me` own or have as personal items?**
|
|
31
|
-
- **Properties Defined:**
|
|
32
|
-
- Everything the user owns or manages (e.g., wallets, devices, digital files).
|
|
33
|
-
- **Methods for Ownership:**
|
|
34
|
-
- `.properties.add()`, `.properties.share()`, `.properties.transferOwnership()`, `.properties.revokeAccess()`.
|
|
35
|
-
- **Modular Approach:**
|
|
36
|
-
- Allows external objects like `Wallet`, `Device`, or `Vehicle` to integrate without hardcoding.
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
### **4. Modularity: How do we allow external objects to seamlessly integrate with `.me`?**
|
|
41
|
-
- **Independent Objects:**
|
|
42
|
-
- Objects like `Wallet`, `Device`, etc., are designed and managed outside the `this.me` instance.
|
|
43
|
-
- **Integration:**
|
|
44
|
-
- These objects are registered to `this.me` via methods like `.addProperty()`.
|
|
45
|
-
- They maintain their internal logic while adhering to the ownership and interaction protocols defined by `.me`.
|
|
46
|
-
- **Advantages:**
|
|
47
|
-
- Scalability: Easy to introduce new objects without modifying the `this.me` core.
|
|
48
|
-
- Transferability: Ownership can move across `.me` instances seamlessly.
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
### **5. Hierarchy of Interactions: How do we classify interactions into tiers (self, relationships, society, etc.)?**
|
|
53
|
-
- **Tiers of Interactions:**
|
|
54
|
-
- **Reactions:** Personal engagements (`like`, `comment`, `share`).
|
|
55
|
-
- **Relationships:** Broader social connections (individuals, groups, organizations).
|
|
56
|
-
- **Attributes:** How `.me` defines itself (e.g., status, bio, pronouns).
|
|
57
|
-
- **Properties:** Interaction with owned or managed items.
|
|
58
|
-
- **Unified Structure:**
|
|
59
|
-
- Centralized under `.reactions` and `.relationships`.
|
|
60
|
-
- Interaction types remain modular and expandable, allowing for a hierarchy to emerge naturally through usage (e.g., personal to societal interactions).
|
|
61
|
-
|
|
62
|
-
---
|
package/notes/hot_encoding.md
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
### Neural Networks - **One-Hot Encoding**
|
|
2
|
-
--------
|
|
3
|
-
To represent the combinations of **“me, you, him, her, it, us, them”** in a neural network, we need to convert the elements into a suitable format for neural network processing, such as one-hot encoding, and design a neural network architecture that can process these inputs.
|
|
4
|
-
|
|
5
|
-
Here’s a step-by-step approach to achieve this:
|
|
6
|
-
1. **One-Hot Encoding:** Convert each element (“me”, “you”, “him”, “her”, “it”, “us”, “them”) into a one-hot encoded vector.
|
|
7
|
-
2. **Combination Representation:** Create input vectors for each combination by combining the one-hot encoded vectors.
|
|
8
|
-
3. **Neural Network Design:** Design a simple neural network to process these input vectors.
|
|
9
|
-
|
|
10
|
-
#### Step 1: One-Hot Encoding
|
|
11
|
-
One-hot encoding represents each element as a binary vector with a single high (1) value and the rest low (0). For the elements “me”, “you”, “him”, “her”, “it”, “us”, “them”, we can assign the following one-hot encoded vectors:
|
|
12
|
-
|
|
13
|
-
```js
|
|
14
|
-
// Create Me instances
|
|
15
|
-
const meInstance = new Me('me');
|
|
16
|
-
const youInstance = new Me('you');
|
|
17
|
-
const himInstance = new Me('him');
|
|
18
|
-
const herInstance = new Me('her');
|
|
19
|
-
const itInstance = new Me('it');
|
|
20
|
-
const usInstance = new Me('us');
|
|
21
|
-
const themInstance = new Me('them');
|
|
22
|
-
|
|
23
|
-
// One-hot encoding representation
|
|
24
|
-
const subjects = {
|
|
25
|
-
'me': [1, 0, 0, 0, 0, 0, 0],
|
|
26
|
-
'you': [0, 1, 0, 0, 0, 0, 0],
|
|
27
|
-
'him': [0, 0, 1, 0, 0, 0, 0],
|
|
28
|
-
'her': [0, 0, 0, 1, 0, 0, 0],
|
|
29
|
-
'it': [0, 0, 0, 0, 1, 0, 0],
|
|
30
|
-
'us': [0, 0, 0, 0, 0, 1, 0],
|
|
31
|
-
'them': [0, 0, 0, 0, 0, 0, 1]
|
|
32
|
-
};
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
#### Step 2: Combination Representation
|
|
36
|
-
For each combination, we can create an input vector by combining the one-hot encoded vectors of its elements. For example:
|
|
37
|
-
Combination “me, you” would be represented as the sum of the one-hot vectors for “me” and “you”:
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
[1, 0, 0, 0, 0, 0, 0] + [0, 1, 0, 0, 0, 0, 0] = [1, 1, 0, 0, 0, 0, 0]
|
|
41
|
-
```
|
|
42
|
-
---
|
|
43
|
-
### Me Deviation Formula
|
|
44
|
-
**How Spread Out the data Points are around the .me?**
|
package/src/.me.cli.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
//.me.cli.js
|
|
3
|
-
import { program } from 'commander';
|
|
4
|
-
import { meMainChoices } from './CLI/me_MainChoices.js';
|
|
5
|
-
import AddMe from './CLI/AddMe.js';
|
|
6
|
-
import LogMe from './CLI/LogMe.js';
|
|
7
|
-
program
|
|
8
|
-
.description('.Me Command Line Interface')
|
|
9
|
-
.version('1.0.0')
|
|
10
|
-
.action(meMainChoices);
|
|
11
|
-
|
|
12
|
-
program.command('add-me')
|
|
13
|
-
.description('+ Add .me')
|
|
14
|
-
.action(AddMe);
|
|
15
|
-
|
|
16
|
-
program.command('log-me')
|
|
17
|
-
.description('Log .me')
|
|
18
|
-
.action(LogMe);
|
|
19
|
-
|
|
20
|
-
program.parse(process.argv);
|
package/src/example.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
//this.me/src/example.js
|
|
2
|
-
import Me from './me.js';
|
|
3
|
-
import chalk from 'chalk';
|
|
4
|
-
// Create a new Me instance
|
|
5
|
-
let me = new Me('suign');
|
|
6
|
-
// Add attributes to the identity
|
|
7
|
-
me.be({ fullName: "Jose", lastName: "Abella" });
|
|
8
|
-
me.be({ xy: "z" });
|
|
9
|
-
console.log(me);
|
|
10
|
-
// Examplconsole.log(me.identity());e with another instance
|
|
11
|
-
let anotherMe = new Me('anotherUser');
|
|
12
|
-
anotherMe.be({ nickname: "hero", favoriteColor: "blue" });
|
|
13
|
-
console.log(anotherMe);
|
|
14
|
-
// Create a new Me instance with dynamic property name
|
|
15
|
-
let user = 'suign';
|
|
16
|
-
let users = {};
|
|
17
|
-
users[user] = new Me(user);
|
|
18
|
-
// Add attributes to the identity
|
|
19
|
-
users[user].be({ fullName: "ZZZ", lastName: "WWW" });
|
|
20
|
-
users[user].be({ xy: "axax" });
|
|
21
|
-
console.log(users[user]);
|
|
22
|
-
|
|
23
|
-
console.log(users);
|
|
24
|
-
|
|
25
|
-
|
package/src/me.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
//this.me/src/me.js
|
|
2
|
-
import Registry from './registry';
|
|
3
|
-
class Me {
|
|
4
|
-
static registry = Registry.load();
|
|
5
|
-
constructor(username = 'default') {
|
|
6
|
-
if (Me.registry[username]) {
|
|
7
|
-
throw new Error(`Username ${username} already exists.`);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
this.username = username;
|
|
11
|
-
this.identity = {
|
|
12
|
-
username,
|
|
13
|
-
devices: [],
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
this.addDevice(); // Automatically adds the current device
|
|
17
|
-
Me.registry[username] = this.identity;
|
|
18
|
-
Registry.save(Me.registry);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
static load(username) {
|
|
22
|
-
if (!Me.registry[username]) {
|
|
23
|
-
throw new Error(`Username ${username} does not exist.`);
|
|
24
|
-
}
|
|
25
|
-
return new Me(username, Me.registry[username]);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
addDevice(deviceInfo = null) {
|
|
29
|
-
const device = deviceInfo || {
|
|
30
|
-
deviceId: crypto.randomUUID(),
|
|
31
|
-
hostname: os.hostname(),
|
|
32
|
-
platform: os.platform(),
|
|
33
|
-
isPrimary: this.identity.devices.length === 0,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
this.identity.devices.push(device);
|
|
37
|
-
Registry.save(Me.registry);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
removeDevice(deviceId) {
|
|
41
|
-
this.identity.devices = this.identity.devices.filter((d) => d.deviceId !== deviceId);
|
|
42
|
-
Registry.save(Me.registry);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
listDevices() {
|
|
46
|
-
return this.identity.devices;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
static getAllUsers() {
|
|
50
|
-
return Object.keys(Me.registry);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export default Me;
|