holosphere 1.0.2 → 1.0.3

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.
Files changed (2) hide show
  1. package/index.js +187 -24
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -6,24 +6,132 @@ import { createHash } from "crypto";
6
6
 
7
7
  class HoloSphere {
8
8
  constructor(appname, openaikey = null) {
9
- this.appname = appname;
10
9
  this.validator = new Ajv2019({ allErrors: false, strict: false });
11
10
  this.gun = Gun({
12
- peers: ['https://59.src.eco/gun'],
13
- axe: false
11
+ peers: [ 'http://localhost:8765','http://gun.holons.io', 'https://gun-eu.herokuapp.com/gun','https://59.src.eco/gun'],
12
+ axe: false,
13
+ // uuid: (content) => { // generate a unique id for each node
14
+ // console.log('uuid', content);
15
+ // return content;}
14
16
  });
15
17
 
18
+ this.gun = this.gun.get(appname)
19
+
16
20
  if (openaikey != null) {
17
21
  this.openai = new OpenAI({
18
22
  apiKey: openaikey,
19
23
  });
20
24
  }
21
25
 
26
+ //this.bot.command('sethex', async (ctx) => { this.setHex(ctx) }) TODO: MOVE HERE FROM SETTINGS
27
+
28
+ // this.bot.command('resethex', async (ctx) => {
29
+ // let chatID = ctx.message.chat.id;
30
+ // let hex = (await this.db.get('settings', chatID)).hex
31
+ // this.delete(hex, ctx.message.text.split(' ')[1])
32
+ // })
33
+
34
+ // this.bot.command('get', async (ctx) => {
35
+ // const chatID = ctx.message.chat.id;
36
+ // const lense = ctx.message.text.split(' ')[1];
37
+ // if (!lense) {
38
+ // return ctx.reply('Please specify a tag.');
39
+ // }
40
+ // let hex = (await this.db.get('settings', chatID)).hex
41
+ // //let hex = settings.hex
42
+ // console.log('hex', hex)
43
+
44
+ // let data = await this.get(ctx, hex, lense)
45
+
46
+ // })
47
+
48
+ // this.bot.command('gethex', async (ctx) => {
49
+ // let settings = await this.db.get('settings', chatID)
50
+ // let id = settings.hex ? settings.hex : 'Hex not set, use /sethex'
51
+ // ctx.reply(id)
52
+ // })
53
+
54
+ // this.bot.command('compute', async (ctx) => {
55
+ // const chatID = ctx.message.chat.id;
56
+ // let operation = ctx.message.text.split(' ')[1];
57
+ // if (operation != 'sum') {
58
+ // ctx.reply('Operation not implemented')
59
+ // return
60
+ // }
61
+ // let lense = ctx.message.text.split(' ')[2]
62
+ // if (!lense) {
63
+ // ctx.reply('Please specify a lense where to perform the operation ')
64
+ // return
65
+ // }
66
+ // let hex = (await this.db.get('settings', chatID)).hex
67
+ // await this.compute(hex, lense, operation)
68
+
69
+ // // let parentInfo = await this.getCellInfo(parent)
70
+ // // parentInfo.wisdom[id] = report
71
+ // // //update summary
72
+ // // let summary = await this.summarize(Object.values(parentInfo.wisdom).join('\n'))
73
+ // // parentInfo.summary = summary
74
+
75
+ // // await this.db.put('cell', parentInfo)
76
+ // // return parentInfo
77
+
78
+ // // let content = await this.db.getAll(hex+'/tags')
79
+ // })
80
+
81
+
82
+
83
+
84
+ // this.bot.command('cast', async (ctx) => {
85
+ // if (!ctx.message.reply_to_message) {
86
+ // return ctx.reply('Please reply to a message you want to tag.');
87
+ // }
88
+ // const tags = ctx.message.text.split(' ').slice(1);
89
+ // if (tags.length === 0) {
90
+ // return ctx.reply('Please provide at least one tag.');
91
+ // }
92
+
93
+ // const messageID = ctx.message.reply_to_message.message_id;
94
+ // const chatID = ctx.message.chat.id;
95
+ // const messageContent = ctx.message.reply_to_message.text;
96
+ // let settings = await this.db.get('settings', chatID)
97
+ // let id = settings.hex ? settings.hex : 'Hex not set, use /sethex'
98
+ // //create root node for the item
99
+ // let node = await this.gun.get(chatID + '/' + messageID).put({ id: chatID + '/' + messageID, content: messageContent })
100
+ // for (let tag of tags) {
101
+ // await this.gun.get(id).get(tag).set(node)
102
+ // this.upcast(id, tag, node)
103
+ // }
104
+ // })
105
+
106
+ // this.bot.command('publish', async (ctx) => {
107
+ // console.log(ctx.message)
108
+ // if (!ctx.message.reply_to_message) {
109
+ // return ctx.reply('Please reply to a message you want to tag.');
110
+ // }
111
+ // const tags = ctx.message.text.split(' ').slice(1);
112
+ // if (tags.length === 0) {
113
+ // return ctx.reply('Please provide at least one tag.');
114
+ // }
115
+
116
+ // const messageID = ctx.message.reply_to_message.message_id;
117
+ // const chatID = ctx.message.chat.id;
118
+ // const messageContent = ctx.message.reply_to_message.text;
119
+ // let settings = await this.db.get('settings', chatID)
120
+ // let hex = settings.hex
121
+
122
+ // for (let tag of tags) {
123
+ // let node = await this.gun.get(chatID + '/' + messageID).put({ id: chatID + '/' + messageID, content: messageContent })
124
+ // await this.put(hex, tag, node)
125
+ // }
126
+
127
+ // ctx.reply('Tag published.');
128
+ // });
129
+
22
130
  }
23
131
 
24
132
  async setSchema(lense, schema) {
25
133
  return new Promise((resolve, reject) => {
26
- this.gun.get(this.appname).get(lense).get('schema').put(JSON.stringify(schema), ack => {
134
+ this.gun.get(lense).get('schema').put(JSON.stringify(schema), ack => {
27
135
  if (ack.err) {
28
136
  resolve(new Error('Failed to add schema: ' + ack.err));
29
137
  } else {
@@ -36,7 +144,7 @@ class HoloSphere {
36
144
 
37
145
  async getSchema(lense) {
38
146
  return new Promise((resolve) => {
39
- this.gun.get(this.appname).get(lense).get('schema').once(data => {
147
+ this.gun.get(lense).get('schema').once(data => {
40
148
  if (data) {
41
149
  let parsed;
42
150
  try {
@@ -71,12 +179,11 @@ class HoloSphere {
71
179
  }
72
180
 
73
181
  async delete(id, tag) {
74
- await this.gun.get(this.appname).get(id).get(tag).put(null)
182
+ await this.gun.get(id).get(tag).put(null)
75
183
  }
76
184
 
77
185
  async put(hex, lense, content) {
78
186
  // Retrieve the schema for the lense
79
- console.log('HoloSphere: Putting content in lense:', lense, 'at hex:', hex, 'content:', content)
80
187
  let schema = await this.getSchema(lense)
81
188
  if (schema) {
82
189
  // Validate the content against the schema
@@ -93,16 +200,16 @@ class HoloSphere {
93
200
  let noderef;
94
201
 
95
202
  if (content.id) { //use the user-defined id. Important to be able to send updates using put
96
- noderef = this.gun.get(this.appname).get(lense).get(content.id).put(payload)
97
- this.gun.get(this.appname).get(hex.toString()).get(lense).get(content.id).put(payload)
203
+ noderef = this.gun.get(lense).get(content.id).put(payload)
204
+ this.gun.get(hex.toString()).get(lense).get(content.id).put(payload)
98
205
  } else { // create a content-addressable reference like IPFS. Note: no updates possible using put
99
206
  const hash = createHash("sha256").update(payload).digest("hex");
100
- noderef = this.gun.get(this.appname).get(lense).get(hash).put(payload)
101
- this.gun.get(this.appname).get(hex.toString()).get(lense).get(hash).put(payload)
207
+ noderef = this.gun.get(lense).get(hash).put(payload)
208
+ this.gun.get(hex.toString()).get(lense).get(hash).put(payload)
102
209
  }
103
210
 
104
211
  // return new Promise((resolve, reject) => {
105
- // this.gun.get(this.appname).get(hex.toString()).get(lense).set(noderef, ack => {
212
+ // this.gun.get(hex.toString()).get(lense).set(noderef, ack => {
106
213
  // if (ack.err) {
107
214
  // reject(new Error('Failed to add content: ' + ack.err));
108
215
  // } else {
@@ -127,16 +234,16 @@ class HoloSphere {
127
234
  return new Promise(async (resolve, reject) => {
128
235
  let output = []
129
236
  let counter = 0
130
- this.gun.get(this.appname).get(hex.toString()).get(lense).once((data, key) => {
237
+ this.gun.get(hex.toString()).get(lense).once((data, key) => {
131
238
  if (data) {
132
239
  const maplenght = Object.keys(data).length - 1
133
240
  console.log('Map length:', maplenght)
134
- this.gun.get(this.appname).get(hex.toString()).get(lense).map().once(async (itemdata, key) => {
241
+ this.gun.get(hex.toString()).get(lense).map().once(async (itemdata, key) => {
135
242
  counter += 1
136
243
  if (itemdata) {
137
244
  // if (itemdata._["#"]) {
138
245
  // // If the data is a reference, fetch the actual content
139
- // itemdata = await this.gun.get(this.appname).get(itemdata._['#']).then();
246
+ // itemdata = await this.gun.get(itemdata._['#']).then();
140
247
  // console.log("Data :",itemdata)
141
248
  // }
142
249
  var parsed = {}
@@ -151,7 +258,7 @@ class HoloSphere {
151
258
  let valid = this.validator.validate(schema, parsed);
152
259
  if (!valid || parsed == null || parsed == undefined) {
153
260
  console.log('Removing Invalid content:', this.validator.errors);
154
- this.gun.get(this.appname).get(hex).get(lense).get(key).put(null);
261
+ this.gun.get(hex).get(lense).get(key).put(null);
155
262
 
156
263
  } else {
157
264
  output.push(parsed);
@@ -208,7 +315,7 @@ class HoloSphere {
208
315
  console.log('Content:', content);
209
316
  let computed = await this.summarize(content.join('\n'))
210
317
  console.log('Computed:', computed)
211
- let node = await this.gun.get(this.appname).get(parent + '_summary').put({ id: parent + '_summary', content: computed })
318
+ let node = await this.gun.get(parent + '_summary').put({ id: parent + '_summary', content: computed })
212
319
 
213
320
  this.put(parent, lense, node);
214
321
  this.compute(parent, lense, operation)
@@ -218,10 +325,10 @@ class HoloSphere {
218
325
  let entities = {};
219
326
 
220
327
  // Get list out of Gun
221
- this.gun.get(this.appname).get(hex).get(lense).map().once((data, key) => {
328
+ this.gun.get(hex).get(lense).map().once((data, key) => {
222
329
  //entities = data;
223
330
  //const id = Object.keys(entities)[0] // since this would be in object form, you can manipulate it as you would like.
224
- this.gun.get(this.appname).get(hex).get(lense).put({ [key]: null })
331
+ this.gun.get(hex).get(lense).put({ [key]: null })
225
332
  })
226
333
  }
227
334
 
@@ -260,15 +367,15 @@ class HoloSphere {
260
367
 
261
368
  async upcast(hex, lense, content) {
262
369
  let res = h3.getResolution(hex)
263
-
264
- if (res == 0)
265
- return content
370
+
266
371
 
267
372
  console.log('Upcasting ', hex, lense, content)
268
373
  let parent = h3.cellToParent(hex, res - 1)
269
374
  await this.put(parent, lense, content)
270
-
271
- return this.upcast(parent, lense, content)
375
+ if (res == 0)
376
+ return content
377
+ else
378
+ return this.upcast(parent, lense, content)
272
379
  }
273
380
 
274
381
 
@@ -312,6 +419,62 @@ class HoloSphere {
312
419
  }
313
420
  return list
314
421
  }
422
+
423
+ subscribe(hex, lense, callback) {
424
+ this.gun.get(hex).get(lense).map().on((data, key) => {
425
+ callback(data, key)
426
+ })
427
+ }
428
+
429
+ // VOTING SYSTEM
430
+
431
+ getFinalVote(userId, topic, votes, visited = new Set()) {
432
+ if (visited.has(userId)) {
433
+ return null; // Avoid circular delegations
434
+ }
435
+ visited.add(userId);
436
+
437
+ const delegation = users[userId].delegations[topic];
438
+ if (delegation && votes[delegation] === undefined) {
439
+ return getFinalVote(delegation, topic, votes, visited); // Follow delegation
440
+ }
441
+
442
+ return votes[userId] !== undefined ? votes[userId] : null; // Return direct vote or null
443
+ }
444
+
445
+ aggregateVotes(hexId, topic) {
446
+ const votes = hexagonVotes[hexId][topic];
447
+ const aggregatedVotes = {};
448
+
449
+ Object.keys(votes).forEach(userId => {
450
+ const finalVote = getFinalVote(userId, topic, votes);
451
+ if (finalVote !== null) {
452
+ aggregatedVotes[finalVote] = (aggregatedVotes[finalVote] || 0) + 1;
453
+ }
454
+ });
455
+
456
+ return aggregatedVotes;
457
+ }
458
+
459
+ async delegateVote(userId, topic, delegateTo) {
460
+ const response = await fetch('/delegate', {
461
+ method: 'POST',
462
+ headers: { 'Content-Type': 'application/json' },
463
+ body: JSON.stringify({ userId, topic, delegateTo })
464
+ });
465
+ alert(await response.text());
466
+ }
467
+
468
+ async vote(userId, hexId, topic, vote) {
469
+ const response = await fetch('/vote', {
470
+ method: 'POST',
471
+ headers: { 'Content-Type': 'application/json' },
472
+ body: JSON.stringify({ userId, hexId, topic, vote })
473
+ });
474
+ alert(await response.text());
475
+ }
476
+
477
+
315
478
  }
316
479
 
317
480
  export default HoloSphere;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "holosphere",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Holonic Geospatial Communication Infrastructure based on h3.js and gun.js",
5
5
  "main": "index.js",
6
6
  "type": "module",