holosphere 1.0.1 → 1.0.2

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 +63 -164
  2. package/package.json +1 -2
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import h3 from 'h3-js';
1
+ import * as h3 from 'h3-js';
2
2
  import OpenAI from 'openai';
3
3
  import Gun from 'gun'
4
4
  import Ajv2019 from 'ajv/dist/2019.js'
@@ -6,141 +6,53 @@ import { createHash } from "crypto";
6
6
 
7
7
  class HoloSphere {
8
8
  constructor(appname, openaikey = null) {
9
+ this.appname = appname;
9
10
  this.validator = new Ajv2019({ allErrors: false, strict: false });
10
11
  this.gun = Gun({
11
12
  peers: ['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;}
13
+ axe: false
16
14
  });
17
15
 
18
- this.gun = gun.get(appname)
19
16
  if (openaikey != null) {
20
17
  this.openai = new OpenAI({
21
18
  apiKey: openaikey,
22
19
  });
23
20
  }
24
21
 
25
- //this.bot.command('sethex', async (ctx) => { this.setHex(ctx) }) TODO: MOVE HERE FROM SETTINGS
26
-
27
- this.bot.command('resethex', async (ctx) => {
28
- let chatID = ctx.message.chat.id;
29
- let hex = (await this.db.get('settings', chatID)).hex
30
- this.delete(hex, ctx.message.text.split(' ')[1])
31
- })
32
-
33
- this.bot.command('get', async (ctx) => {
34
- const chatID = ctx.message.chat.id;
35
- const lense = ctx.message.text.split(' ')[1];
36
- if (!lense) {
37
- return ctx.reply('Please specify a tag.');
38
- }
39
- let hex = (await this.db.get('settings', chatID)).hex
40
- //let hex = settings.hex
41
- console.log('hex', hex)
42
-
43
- let data = await this.get(ctx, hex, lense)
44
-
45
- })
46
-
47
- this.bot.command('gethex', async (ctx) => {
48
- let settings = await this.db.get('settings', chatID)
49
- let id = settings.hex ? settings.hex : 'Hex not set, use /sethex'
50
- ctx.reply(id)
51
- })
52
-
53
- this.bot.command('compute', async (ctx) => {
54
- const chatID = ctx.message.chat.id;
55
- let operation = ctx.message.text.split(' ')[1];
56
- if (operation != 'sum') {
57
- ctx.reply('Operation not implemented')
58
- return
59
- }
60
- let lense = ctx.message.text.split(' ')[2]
61
- if (!lense) {
62
- ctx.reply('Please specify a lense where to perform the operation ')
63
- return
64
- }
65
- let hex = (await this.db.get('settings', chatID)).hex
66
- await this.compute(hex, lense, operation)
67
-
68
- // let parentInfo = await this.getCellInfo(parent)
69
- // parentInfo.wisdom[id] = report
70
- // //update summary
71
- // let summary = await this.summarize(Object.values(parentInfo.wisdom).join('\n'))
72
- // parentInfo.summary = summary
73
-
74
- // await this.db.put('cell', parentInfo)
75
- // return parentInfo
76
-
77
- // let content = await this.db.getAll(hex+'/tags')
78
- })
79
-
80
-
81
-
82
-
83
- this.bot.command('cast', async (ctx) => {
84
- if (!ctx.message.reply_to_message) {
85
- return ctx.reply('Please reply to a message you want to tag.');
86
- }
87
- const tags = ctx.message.text.split(' ').slice(1);
88
- if (tags.length === 0) {
89
- return ctx.reply('Please provide at least one tag.');
90
- }
91
-
92
- const messageID = ctx.message.reply_to_message.message_id;
93
- const chatID = ctx.message.chat.id;
94
- const messageContent = ctx.message.reply_to_message.text;
95
- let settings = await this.db.get('settings', chatID)
96
- let id = settings.hex ? settings.hex : 'Hex not set, use /sethex'
97
- //create root node for the item
98
- let node = await this.gun.get(chatID + '/' + messageID).put({ id: chatID + '/' + messageID, content: messageContent })
99
- for (let tag of tags) {
100
- await this.gun.get(id).get(tag).set(node)
101
- this.upcast(id, tag, node)
102
- }
103
- })
104
-
105
- this.bot.command('publish', async (ctx) => {
106
- console.log(ctx.message)
107
- if (!ctx.message.reply_to_message) {
108
- return ctx.reply('Please reply to a message you want to tag.');
109
- }
110
- const tags = ctx.message.text.split(' ').slice(1);
111
- if (tags.length === 0) {
112
- return ctx.reply('Please provide at least one tag.');
113
- }
114
-
115
- const messageID = ctx.message.reply_to_message.message_id;
116
- const chatID = ctx.message.chat.id;
117
- const messageContent = ctx.message.reply_to_message.text;
118
- let settings = await this.db.get('settings', chatID)
119
- let hex = settings.hex
120
-
121
- for (let tag of tags) {
122
- let node = await this.gun.get(chatID + '/' + messageID).put({ id: chatID + '/' + messageID, content: messageContent })
123
- await this.put(hex, tag, node)
124
- }
125
-
126
- ctx.reply('Tag published.');
127
- });
128
-
129
22
  }
130
23
 
131
24
  async setSchema(lense, schema) {
132
25
  return new Promise((resolve, reject) => {
133
- this.db.gun.get(lense).get('schema').put(JSON.stringify(schema), ack => {
26
+ this.gun.get(this.appname).get(lense).get('schema').put(JSON.stringify(schema), ack => {
134
27
  if (ack.err) {
135
28
  resolve(new Error('Failed to add schema: ' + ack.err));
136
29
  } else {
137
- console.log('Schema added successfully under tag:', lense);
30
+ console.log('Schema added successfully under lense:', lense);
138
31
  resolve(ack);
139
32
  }
140
33
  })
141
34
  })
142
35
  }
143
36
 
37
+ async getSchema(lense) {
38
+ return new Promise((resolve) => {
39
+ this.gun.get(this.appname).get(lense).get('schema').once(data => {
40
+ if (data) {
41
+ let parsed;
42
+ try {
43
+ parsed = JSON.parse(data);
44
+ }
45
+ catch (e) {
46
+ resolve(null)
47
+ }
48
+ resolve(parsed);
49
+ } else {
50
+ resolve(null);
51
+ }
52
+ })
53
+ })
54
+ }
55
+
144
56
  async setHex(ctx) {
145
57
  const chatID = ctx.message.chat.id;
146
58
  const hex = ctx.message.text.split(' ')[1];
@@ -159,32 +71,20 @@ class HoloSphere {
159
71
  }
160
72
 
161
73
  async delete(id, tag) {
162
- await this.gun.get(id).get(tag).put(null)
74
+ await this.gun.get(this.appname).get(id).get(tag).put(null)
163
75
  }
164
76
 
165
77
  async put(hex, lense, content) {
166
78
  // Retrieve the schema for the lense
167
- let schemaData;
168
- try {
169
- schemaData = await new Promise((resolve, reject) => {
170
- this.gun.get(lense).get('schema').once(data => {
171
- if (data) {
172
- resolve(JSON.parse(data));
173
- } else {
174
- reject(new Error('No schema data found'));
175
- }
176
- });
177
- });
178
- } catch (error) {
179
- console.error(`Error fetching schema for "${lense}": ${error}`);
180
- return null;
181
- }
182
-
183
- // Validate the content against the schema
184
- const valid = this.validator.validate(schemaData, content);
185
- if (!valid) {
186
- console.error('Invalid content:', this.validator.errors);
187
- return null;
79
+ console.log('HoloSphere: Putting content in lense:', lense, 'at hex:', hex, 'content:', content)
80
+ let schema = await this.getSchema(lense)
81
+ if (schema) {
82
+ // Validate the content against the schema
83
+ const valid = this.validator.validate(schema, content);
84
+ if (!valid) {
85
+ console.error('Not committing invalid content:', this.validator.errors);
86
+ return null;
87
+ }
188
88
  }
189
89
 
190
90
  // Create a node for the content
@@ -193,16 +93,16 @@ class HoloSphere {
193
93
  let noderef;
194
94
 
195
95
  if (content.id) { //use the user-defined id. Important to be able to send updates using put
196
- noderef = this.gun.get(lense).get(content.id).put(payload)
197
- this.gun.get(hex.toString()).get(lense).get(content.id).put(payload)
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)
198
98
  } else { // create a content-addressable reference like IPFS. Note: no updates possible using put
199
99
  const hash = createHash("sha256").update(payload).digest("hex");
200
- noderef = this.gun.get(lense).get(hash).put(payload)
201
- this.gun.get(hex.toString()).get(lense).get(hash).put(payload)
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)
202
102
  }
203
103
 
204
104
  // return new Promise((resolve, reject) => {
205
- // this.gun.get(hex.toString()).get(lense).set(noderef, ack => {
105
+ // this.gun.get(this.appname).get(hex.toString()).get(lense).set(noderef, ack => {
206
106
  // if (ack.err) {
207
107
  // reject(new Error('Failed to add content: ' + ack.err));
208
108
  // } else {
@@ -217,36 +117,26 @@ class HoloSphere {
217
117
  async get(hex, lense) {
218
118
  // Wrap the GunDB operation in a promise
219
119
  //retrieve lense schema
220
- const schemaData = JSON.parse(await new Promise((resolve, reject) => {
221
- this.gun.get(lense).get('schema').once(data => {
222
- if (data) {
223
- resolve(data);
224
- } else {
225
- resolve(null);
226
- }
227
- });
228
- })
229
- )
120
+ const schema = await this.getSchema(lense);
230
121
 
231
- if (!schemaData) {
122
+ if (!schema) {
232
123
  console.log('The schema for "' + lense + '" is not defined');
233
- return null;
124
+ // return null; // No schema found, return null if strict about it
234
125
  }
235
126
 
236
127
  return new Promise(async (resolve, reject) => {
237
128
  let output = []
238
129
  let counter = 0
239
- this.gun.get(hex.toString()).get(lense).once((data, key) => {
130
+ this.gun.get(this.appname).get(hex.toString()).get(lense).once((data, key) => {
240
131
  if (data) {
241
132
  const maplenght = Object.keys(data).length - 1
242
- this.gun.get(hex.toString()).get(lense).map().once(async (itemdata, key) => {
133
+ console.log('Map length:', maplenght)
134
+ this.gun.get(this.appname).get(hex.toString()).get(lense).map().once(async (itemdata, key) => {
243
135
  counter += 1
244
136
  if (itemdata) {
245
-
246
-
247
137
  // if (itemdata._["#"]) {
248
138
  // // If the data is a reference, fetch the actual content
249
- // itemdata = await this.gun.get(itemdata._['#']).then();
139
+ // itemdata = await this.gun.get(this.appname).get(itemdata._['#']).then();
250
140
  // console.log("Data :",itemdata)
251
141
  // }
252
142
  var parsed = {}
@@ -254,14 +144,20 @@ class HoloSphere {
254
144
  parsed = JSON.parse(itemdata);
255
145
  } catch (e) {
256
146
  console.log('Invalid JSON:', itemdata);
147
+ parsed = itemdata //return the raw data
257
148
  }
258
149
 
259
- let valid = this.validator.validate(schemaData, parsed);
260
- if (!valid || parsed == null || parsed == undefined) {
261
- console.log('Removing Invalid content:', this.validator.errors);
262
- this.gun.get(hex).get(lense).get(key).put(null);
150
+ if (schema) {
151
+ let valid = this.validator.validate(schema, parsed);
152
+ if (!valid || parsed == null || parsed == undefined) {
153
+ console.log('Removing Invalid content:', this.validator.errors);
154
+ this.gun.get(this.appname).get(hex).get(lense).get(key).put(null);
263
155
 
264
- } else {
156
+ } else {
157
+ output.push(parsed);
158
+ }
159
+ }
160
+ else {
265
161
  output.push(parsed);
266
162
  }
267
163
  }
@@ -312,7 +208,7 @@ class HoloSphere {
312
208
  console.log('Content:', content);
313
209
  let computed = await this.summarize(content.join('\n'))
314
210
  console.log('Computed:', computed)
315
- let node = await this.gun.get(parent + '_summary').put({ id: parent + '_summary', content: computed })
211
+ let node = await this.gun.get(this.appname).get(parent + '_summary').put({ id: parent + '_summary', content: computed })
316
212
 
317
213
  this.put(parent, lense, node);
318
214
  this.compute(parent, lense, operation)
@@ -322,10 +218,10 @@ class HoloSphere {
322
218
  let entities = {};
323
219
 
324
220
  // Get list out of Gun
325
- this.gun.get(hex).get(lense).map().once((data, key) => {
221
+ this.gun.get(this.appname).get(hex).get(lense).map().once((data, key) => {
326
222
  //entities = data;
327
223
  //const id = Object.keys(entities)[0] // since this would be in object form, you can manipulate it as you would like.
328
- this.gun.get(hex).get(lense).put({ [key]: null })
224
+ this.gun.get(this.appname).get(hex).get(lense).put({ [key]: null })
329
225
  })
330
226
  }
331
227
 
@@ -364,15 +260,18 @@ class HoloSphere {
364
260
 
365
261
  async upcast(hex, lense, content) {
366
262
  let res = h3.getResolution(hex)
263
+
367
264
  if (res == 0)
368
265
  return content
369
266
 
370
267
  console.log('Upcasting ', hex, lense, content)
371
268
  let parent = h3.cellToParent(hex, res - 1)
372
269
  await this.put(parent, lense, content)
270
+
373
271
  return this.upcast(parent, lense, content)
374
272
  }
375
273
 
274
+
376
275
  // send information upwards, triggers the parent to update its summary
377
276
  async updateParent(id, report) {
378
277
  let cellinfo = await this.getCellInfo(id)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "holosphere",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Holonic Geospatial Communication Infrastructure based on h3.js and gun.js",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -11,7 +11,6 @@
11
11
  "license": "GPL-3.0-or-later",
12
12
  "dependencies": {
13
13
  "ajv": "^8.12.0",
14
- "dotenv": "^16.4.5",
15
14
  "gun": "^0.2020.1239",
16
15
  "h3-js": "^4.1.0",
17
16
  "openai": "^4.29.2"