holosphere 1.0.2 → 1.0.4

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 (3) hide show
  1. package/hexlib.js +332 -0
  2. package/index.js +192 -26
  3. package/package.json +2 -2
package/hexlib.js ADDED
@@ -0,0 +1,332 @@
1
+ // Generated code -- CC0 -- No Rights Reserved -- http://www.redblobgames.com/grids/hexagons/
2
+ export class Point {
3
+ constructor(x, y) {
4
+ this.x = x;
5
+ this.y = y;
6
+ }
7
+ }
8
+ export class Hex {
9
+ constructor(q, r, s) {
10
+ this.q = q;
11
+ this.r = r;
12
+ this.s = s;
13
+ if (Math.round(q + r + s) !== 0)
14
+ throw "q + r + s must be 0";
15
+ }
16
+ add(b) {
17
+ return new Hex(this.q + b.q, this.r + b.r, this.s + b.s);
18
+ }
19
+ subtract(b) {
20
+ return new Hex(this.q - b.q, this.r - b.r, this.s - b.s);
21
+ }
22
+ scale(k) {
23
+ return new Hex(this.q * k, this.r * k, this.s * k);
24
+ }
25
+ rotateLeft() {
26
+ return new Hex(-this.s, -this.q, -this.r);
27
+ }
28
+ rotateRight() {
29
+ return new Hex(-this.r, -this.s, -this.q);
30
+ }
31
+ static direction(direction) {
32
+ return Hex.directions[direction];
33
+ }
34
+ neighbor(direction) {
35
+ return this.add(Hex.direction(direction));
36
+ }
37
+ diagonalNeighbor(direction) {
38
+ return this.add(Hex.diagonals[direction]);
39
+ }
40
+ len() {
41
+ return (Math.abs(this.q) + Math.abs(this.r) + Math.abs(this.s)) / 2;
42
+ }
43
+ distance(b) {
44
+ return this.subtract(b).len();
45
+ }
46
+ round() {
47
+ var qi = Math.round(this.q);
48
+ var ri = Math.round(this.r);
49
+ var si = Math.round(this.s);
50
+ var q_diff = Math.abs(qi - this.q);
51
+ var r_diff = Math.abs(ri - this.r);
52
+ var s_diff = Math.abs(si - this.s);
53
+ if (q_diff > r_diff && q_diff > s_diff) {
54
+ qi = -ri - si;
55
+ }
56
+ else if (r_diff > s_diff) {
57
+ ri = -qi - si;
58
+ }
59
+ else {
60
+ si = -qi - ri;
61
+ }
62
+ return new Hex(qi, ri, si);
63
+ }
64
+ lerp(b, t) {
65
+ return new Hex(this.q * (1.0 - t) + b.q * t, this.r * (1.0 - t) + b.r * t, this.s * (1.0 - t) + b.s * t);
66
+ }
67
+ linedraw(b) {
68
+ var N = this.distance(b);
69
+ var a_nudge = new Hex(this.q + 1e-06, this.r + 1e-06, this.s - 2e-06);
70
+ var b_nudge = new Hex(b.q + 1e-06, b.r + 1e-06, b.s - 2e-06);
71
+ var results = [];
72
+ var step = 1.0 / Math.max(N, 1);
73
+ for (var i = 0; i <= N; i++) {
74
+ results.push(a_nudge.lerp(b_nudge, step * i).round());
75
+ }
76
+ return results;
77
+ }
78
+ }
79
+ Hex.directions = [new Hex(1, 0, -1), new Hex(1, -1, 0), new Hex(0, -1, 1), new Hex(-1, 0, 1), new Hex(-1, 1, 0), new Hex(0, 1, -1)];
80
+ Hex.diagonals = [new Hex(2, -1, -1), new Hex(1, -2, 1), new Hex(-1, -1, 2), new Hex(-2, 1, 1), new Hex(-1, 2, -1), new Hex(1, 1, -2)];
81
+ export class OffsetCoord {
82
+ constructor(col, row) {
83
+ this.col = col;
84
+ this.row = row;
85
+ }
86
+ static qoffsetFromCube(offset, h) {
87
+ var col = h.q;
88
+ var row = h.r + (h.q + offset * (h.q & 1)) / 2;
89
+ if (offset !== OffsetCoord.EVEN && offset !== OffsetCoord.ODD) {
90
+ throw "offset must be EVEN (+1) or ODD (-1)";
91
+ }
92
+ return new OffsetCoord(col, row);
93
+ }
94
+ static qoffsetToCube(offset, h) {
95
+ var q = h.col;
96
+ var r = h.row - (h.col + offset * (h.col & 1)) / 2;
97
+ var s = -q - r;
98
+ if (offset !== OffsetCoord.EVEN && offset !== OffsetCoord.ODD) {
99
+ throw "offset must be EVEN (+1) or ODD (-1)";
100
+ }
101
+ return new Hex(q, r, s);
102
+ }
103
+ static roffsetFromCube(offset, h) {
104
+ var col = h.q + (h.r + offset * (h.r & 1)) / 2;
105
+ var row = h.r;
106
+ if (offset !== OffsetCoord.EVEN && offset !== OffsetCoord.ODD) {
107
+ throw "offset must be EVEN (+1) or ODD (-1)";
108
+ }
109
+ return new OffsetCoord(col, row);
110
+ }
111
+ static roffsetToCube(offset, h) {
112
+ var q = h.col - (h.row + offset * (h.row & 1)) / 2;
113
+ var r = h.row;
114
+ var s = -q - r;
115
+ if (offset !== OffsetCoord.EVEN && offset !== OffsetCoord.ODD) {
116
+ throw "offset must be EVEN (+1) or ODD (-1)";
117
+ }
118
+ return new Hex(q, r, s);
119
+ }
120
+ }
121
+ OffsetCoord.EVEN = 1;
122
+ OffsetCoord.ODD = -1;
123
+ export class DoubledCoord {
124
+ constructor(col, row) {
125
+ this.col = col;
126
+ this.row = row;
127
+ }
128
+ static qdoubledFromCube(h) {
129
+ var col = h.q;
130
+ var row = 2 * h.r + h.q;
131
+ return new DoubledCoord(col, row);
132
+ }
133
+ qdoubledToCube() {
134
+ var q = this.col;
135
+ var r = (this.row - this.col) / 2;
136
+ var s = -q - r;
137
+ return new Hex(q, r, s);
138
+ }
139
+ static rdoubledFromCube(h) {
140
+ var col = 2 * h.q + h.r;
141
+ var row = h.r;
142
+ return new DoubledCoord(col, row);
143
+ }
144
+ rdoubledToCube() {
145
+ var q = (this.col - this.row) / 2;
146
+ var r = this.row;
147
+ var s = -q - r;
148
+ return new Hex(q, r, s);
149
+ }
150
+ }
151
+ export class Orientation {
152
+ constructor(f0, f1, f2, f3, b0, b1, b2, b3, start_angle) {
153
+ this.f0 = f0;
154
+ this.f1 = f1;
155
+ this.f2 = f2;
156
+ this.f3 = f3;
157
+ this.b0 = b0;
158
+ this.b1 = b1;
159
+ this.b2 = b2;
160
+ this.b3 = b3;
161
+ this.start_angle = start_angle;
162
+ }
163
+ }
164
+ export class Layout {
165
+ constructor(orientation, size, origin) {
166
+ this.orientation = orientation;
167
+ this.size = size;
168
+ this.origin = origin;
169
+ }
170
+ hexToPixel(h) {
171
+ var M = this.orientation;
172
+ var size = this.size;
173
+ var origin = this.origin;
174
+ var x = (M.f0 * h.q + M.f1 * h.r) * size.x;
175
+ var y = (M.f2 * h.q + M.f3 * h.r) * size.y;
176
+ return new Point(x + origin.x, y + origin.y);
177
+ }
178
+ pixelToHex(p) {
179
+ var M = this.orientation;
180
+ var size = this.size;
181
+ var origin = this.origin;
182
+ var pt = new Point((p.x - origin.x) / size.x, (p.y - origin.y) / size.y);
183
+ var q = M.b0 * pt.x + M.b1 * pt.y;
184
+ var r = M.b2 * pt.x + M.b3 * pt.y;
185
+ return new Hex(q, r, -q - r);
186
+ }
187
+ hexCornerOffset(corner) {
188
+ var M = this.orientation;
189
+ var size = this.size;
190
+ var angle = 2.0 * Math.PI * (M.start_angle - corner) / 6.0;
191
+ return new Point(size.x * Math.cos(angle), size.y * Math.sin(angle));
192
+ }
193
+ polygonCorners(h) {
194
+ var corners = [];
195
+ var center = this.hexToPixel(h);
196
+ for (var i = 0; i < 6; i++) {
197
+ var offset = this.hexCornerOffset(i);
198
+ corners.push(new Point(center.x + offset.x, center.y + offset.y));
199
+ }
200
+ return corners;
201
+ }
202
+ }
203
+ Layout.pointy = new Orientation(Math.sqrt(3.0), Math.sqrt(3.0) / 2.0, 0.0, 3.0 / 2.0, Math.sqrt(3.0) / 3.0, -1.0 / 3.0, 0.0, 2.0 / 3.0, 0.5);
204
+ Layout.flat = new Orientation(3.0 / 2.0, 0.0, Math.sqrt(3.0) / 2.0, Math.sqrt(3.0), 2.0 / 3.0, 0.0, -1.0 / 3.0, Math.sqrt(3.0) / 3.0, 0.0);
205
+ class Tests {
206
+ constructor() { }
207
+ static equalHex(name, a, b) {
208
+ if (!(a.q === b.q && a.s === b.s && a.r === b.r)) {
209
+ complain(name);
210
+ }
211
+ }
212
+ static equalOffsetcoord(name, a, b) {
213
+ if (!(a.col === b.col && a.row === b.row)) {
214
+ complain(name);
215
+ }
216
+ }
217
+ static equalDoubledcoord(name, a, b) {
218
+ if (!(a.col === b.col && a.row === b.row)) {
219
+ complain(name);
220
+ }
221
+ }
222
+ static equalInt(name, a, b) {
223
+ if (!(a === b)) {
224
+ complain(name);
225
+ }
226
+ }
227
+ static equalHexArray(name, a, b) {
228
+ Tests.equalInt(name, a.length, b.length);
229
+ for (var i = 0; i < a.length; i++) {
230
+ Tests.equalHex(name, a[i], b[i]);
231
+ }
232
+ }
233
+ static testHexArithmetic() {
234
+ Tests.equalHex("hex_add", new Hex(4, -10, 6), new Hex(1, -3, 2).add(new Hex(3, -7, 4)));
235
+ Tests.equalHex("hex_subtract", new Hex(-2, 4, -2), new Hex(1, -3, 2).subtract(new Hex(3, -7, 4)));
236
+ }
237
+ static testHexDirection() {
238
+ Tests.equalHex("hex_direction", new Hex(0, -1, 1), Hex.direction(2));
239
+ }
240
+ static testHexNeighbor() {
241
+ Tests.equalHex("hex_neighbor", new Hex(1, -3, 2), new Hex(1, -2, 1).neighbor(2));
242
+ }
243
+ static testHexDiagonal() {
244
+ Tests.equalHex("hex_diagonal", new Hex(-1, -1, 2), new Hex(1, -2, 1).diagonalNeighbor(3));
245
+ }
246
+ static testHexDistance() {
247
+ Tests.equalInt("hex_distance", 7, new Hex(3, -7, 4).distance(new Hex(0, 0, 0)));
248
+ }
249
+ static testHexRotateRight() {
250
+ Tests.equalHex("hex_rotate_right", new Hex(1, -3, 2).rotateRight(), new Hex(3, -2, -1));
251
+ }
252
+ static testHexRotateLeft() {
253
+ Tests.equalHex("hex_rotate_left", new Hex(1, -3, 2).rotateLeft(), new Hex(-2, -1, 3));
254
+ }
255
+ static testHexRound() {
256
+ var a = new Hex(0.0, 0.0, 0.0);
257
+ var b = new Hex(1.0, -1.0, 0.0);
258
+ var c = new Hex(0.0, -1.0, 1.0);
259
+ Tests.equalHex("hex_round 1", new Hex(5, -10, 5), new Hex(0.0, 0.0, 0.0).lerp(new Hex(10.0, -20.0, 10.0), 0.5).round());
260
+ Tests.equalHex("hex_round 2", a.round(), a.lerp(b, 0.499).round());
261
+ Tests.equalHex("hex_round 3", b.round(), a.lerp(b, 0.501).round());
262
+ Tests.equalHex("hex_round 4", a.round(), new Hex(a.q * 0.4 + b.q * 0.3 + c.q * 0.3, a.r * 0.4 + b.r * 0.3 + c.r * 0.3, a.s * 0.4 + b.s * 0.3 + c.s * 0.3).round());
263
+ Tests.equalHex("hex_round 5", c.round(), new Hex(a.q * 0.3 + b.q * 0.3 + c.q * 0.4, a.r * 0.3 + b.r * 0.3 + c.r * 0.4, a.s * 0.3 + b.s * 0.3 + c.s * 0.4).round());
264
+ }
265
+ static testHexLinedraw() {
266
+ Tests.equalHexArray("hex_linedraw", [new Hex(0, 0, 0), new Hex(0, -1, 1), new Hex(0, -2, 2), new Hex(1, -3, 2), new Hex(1, -4, 3), new Hex(1, -5, 4)], new Hex(0, 0, 0).linedraw(new Hex(1, -5, 4)));
267
+ }
268
+ static testLayout() {
269
+ var h = new Hex(3, 4, -7);
270
+ var flat = new Layout(Layout.flat, new Point(10.0, 15.0), new Point(35.0, 71.0));
271
+ Tests.equalHex("layout", h, flat.pixelToHex(flat.hexToPixel(h)).round());
272
+ var pointy = new Layout(Layout.pointy, new Point(10.0, 15.0), new Point(35.0, 71.0));
273
+ Tests.equalHex("layout", h, pointy.pixelToHex(pointy.hexToPixel(h)).round());
274
+ }
275
+ static testOffsetRoundtrip() {
276
+ var a = new Hex(3, 4, -7);
277
+ var b = new OffsetCoord(1, -3);
278
+ Tests.equalHex("conversion_roundtrip even-q", a, OffsetCoord.qoffsetToCube(OffsetCoord.EVEN, OffsetCoord.qoffsetFromCube(OffsetCoord.EVEN, a)));
279
+ Tests.equalOffsetcoord("conversion_roundtrip even-q", b, OffsetCoord.qoffsetFromCube(OffsetCoord.EVEN, OffsetCoord.qoffsetToCube(OffsetCoord.EVEN, b)));
280
+ Tests.equalHex("conversion_roundtrip odd-q", a, OffsetCoord.qoffsetToCube(OffsetCoord.ODD, OffsetCoord.qoffsetFromCube(OffsetCoord.ODD, a)));
281
+ Tests.equalOffsetcoord("conversion_roundtrip odd-q", b, OffsetCoord.qoffsetFromCube(OffsetCoord.ODD, OffsetCoord.qoffsetToCube(OffsetCoord.ODD, b)));
282
+ Tests.equalHex("conversion_roundtrip even-r", a, OffsetCoord.roffsetToCube(OffsetCoord.EVEN, OffsetCoord.roffsetFromCube(OffsetCoord.EVEN, a)));
283
+ Tests.equalOffsetcoord("conversion_roundtrip even-r", b, OffsetCoord.roffsetFromCube(OffsetCoord.EVEN, OffsetCoord.roffsetToCube(OffsetCoord.EVEN, b)));
284
+ Tests.equalHex("conversion_roundtrip odd-r", a, OffsetCoord.roffsetToCube(OffsetCoord.ODD, OffsetCoord.roffsetFromCube(OffsetCoord.ODD, a)));
285
+ Tests.equalOffsetcoord("conversion_roundtrip odd-r", b, OffsetCoord.roffsetFromCube(OffsetCoord.ODD, OffsetCoord.roffsetToCube(OffsetCoord.ODD, b)));
286
+ }
287
+ static testOffsetFromCube() {
288
+ Tests.equalOffsetcoord("offset_from_cube even-q", new OffsetCoord(1, 3), OffsetCoord.qoffsetFromCube(OffsetCoord.EVEN, new Hex(1, 2, -3)));
289
+ Tests.equalOffsetcoord("offset_from_cube odd-q", new OffsetCoord(1, 2), OffsetCoord.qoffsetFromCube(OffsetCoord.ODD, new Hex(1, 2, -3)));
290
+ }
291
+ static testOffsetToCube() {
292
+ Tests.equalHex("offset_to_cube even-", new Hex(1, 2, -3), OffsetCoord.qoffsetToCube(OffsetCoord.EVEN, new OffsetCoord(1, 3)));
293
+ Tests.equalHex("offset_to_cube odd-q", new Hex(1, 2, -3), OffsetCoord.qoffsetToCube(OffsetCoord.ODD, new OffsetCoord(1, 2)));
294
+ }
295
+ static testDoubledRoundtrip() {
296
+ var a = new Hex(3, 4, -7);
297
+ var b = new DoubledCoord(1, -3);
298
+ Tests.equalHex("conversion_roundtrip doubled-q", a, DoubledCoord.qdoubledFromCube(a).qdoubledToCube());
299
+ Tests.equalDoubledcoord("conversion_roundtrip doubled-q", b, DoubledCoord.qdoubledFromCube(b.qdoubledToCube()));
300
+ Tests.equalHex("conversion_roundtrip doubled-r", a, DoubledCoord.rdoubledFromCube(a).rdoubledToCube());
301
+ Tests.equalDoubledcoord("conversion_roundtrip doubled-r", b, DoubledCoord.rdoubledFromCube(b.rdoubledToCube()));
302
+ }
303
+ static testDoubledFromCube() {
304
+ Tests.equalDoubledcoord("doubled_from_cube doubled-q", new DoubledCoord(1, 5), DoubledCoord.qdoubledFromCube(new Hex(1, 2, -3)));
305
+ Tests.equalDoubledcoord("doubled_from_cube doubled-r", new DoubledCoord(4, 2), DoubledCoord.rdoubledFromCube(new Hex(1, 2, -3)));
306
+ }
307
+ static testDoubledToCube() {
308
+ Tests.equalHex("doubled_to_cube doubled-q", new Hex(1, 2, -3), new DoubledCoord(1, 5).qdoubledToCube());
309
+ Tests.equalHex("doubled_to_cube doubled-r", new Hex(1, 2, -3), new DoubledCoord(4, 2).rdoubledToCube());
310
+ }
311
+ static testAll() {
312
+ Tests.testHexArithmetic();
313
+ Tests.testHexDirection();
314
+ Tests.testHexNeighbor();
315
+ Tests.testHexDiagonal();
316
+ Tests.testHexDistance();
317
+ Tests.testHexRotateRight();
318
+ Tests.testHexRotateLeft();
319
+ Tests.testHexRound();
320
+ Tests.testHexLinedraw();
321
+ Tests.testLayout();
322
+ Tests.testOffsetRoundtrip();
323
+ Tests.testOffsetFromCube();
324
+ Tests.testOffsetToCube();
325
+ Tests.testDoubledRoundtrip();
326
+ Tests.testDoubledFromCube();
327
+ Tests.testDoubledToCube();
328
+ }
329
+ }
330
+ // Tests
331
+ function complain(name) { console.log("FAIL", name); }
332
+ Tests.testAll();
package/index.js CHANGED
@@ -2,28 +2,135 @@ 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'
5
- import { createHash } from "crypto";
6
5
 
7
6
  class HoloSphere {
8
7
  constructor(appname, openaikey = null) {
9
- this.appname = appname;
10
8
  this.validator = new Ajv2019({ allErrors: false, strict: false });
11
9
  this.gun = Gun({
12
- peers: ['https://59.src.eco/gun'],
13
- axe: false
10
+ peers: ['http://gun.holons.io', 'https://59.src.eco/gun'],
11
+ axe: false,
12
+ // uuid: (content) => { // generate a unique id for each node
13
+ // console.log('uuid', content);
14
+ // return content;}
14
15
  });
15
16
 
17
+ this.gun = this.gun.get(appname)
18
+
16
19
  if (openaikey != null) {
17
20
  this.openai = new OpenAI({
18
21
  apiKey: openaikey,
19
22
  });
20
23
  }
21
24
 
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
+
22
129
  }
23
130
 
24
131
  async setSchema(lense, schema) {
25
132
  return new Promise((resolve, reject) => {
26
- this.gun.get(this.appname).get(lense).get('schema').put(JSON.stringify(schema), ack => {
133
+ this.gun.get(lense).get('schema').put(JSON.stringify(schema), ack => {
27
134
  if (ack.err) {
28
135
  resolve(new Error('Failed to add schema: ' + ack.err));
29
136
  } else {
@@ -36,7 +143,7 @@ class HoloSphere {
36
143
 
37
144
  async getSchema(lense) {
38
145
  return new Promise((resolve) => {
39
- this.gun.get(this.appname).get(lense).get('schema').once(data => {
146
+ this.gun.get(lense).get('schema').once(data => {
40
147
  if (data) {
41
148
  let parsed;
42
149
  try {
@@ -71,12 +178,11 @@ class HoloSphere {
71
178
  }
72
179
 
73
180
  async delete(id, tag) {
74
- await this.gun.get(this.appname).get(id).get(tag).put(null)
181
+ await this.gun.get(id).get(tag).put(null)
75
182
  }
76
183
 
77
184
  async put(hex, lense, content) {
78
185
  // Retrieve the schema for the lense
79
- console.log('HoloSphere: Putting content in lense:', lense, 'at hex:', hex, 'content:', content)
80
186
  let schema = await this.getSchema(lense)
81
187
  if (schema) {
82
188
  // Validate the content against the schema
@@ -93,16 +199,20 @@ class HoloSphere {
93
199
  let noderef;
94
200
 
95
201
  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)
202
+ noderef = this.gun.get(lense).get(content.id).put(payload)
203
+ this.gun.get(hex.toString()).get(lense).get(content.id).put(payload)
98
204
  } else { // create a content-addressable reference like IPFS. Note: no updates possible using put
99
- 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)
205
+ //const hash = createHash("sha256").update(payload).digest("hex");
206
+ const hash = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(payload));
207
+ // const hashHex = Array.from(new Uint8Array(hash))
208
+ // .map(byte => byte.toString(16).padStart(2, "0"))
209
+ // .join("");
210
+ noderef = this.gun.get(lense).get(hash).put(payload)
211
+ this.gun.get(hex.toString()).get(lense).get(hash).put(payload)
102
212
  }
103
213
 
104
214
  // return new Promise((resolve, reject) => {
105
- // this.gun.get(this.appname).get(hex.toString()).get(lense).set(noderef, ack => {
215
+ // this.gun.get(hex.toString()).get(lense).set(noderef, ack => {
106
216
  // if (ack.err) {
107
217
  // reject(new Error('Failed to add content: ' + ack.err));
108
218
  // } else {
@@ -127,16 +237,16 @@ class HoloSphere {
127
237
  return new Promise(async (resolve, reject) => {
128
238
  let output = []
129
239
  let counter = 0
130
- this.gun.get(this.appname).get(hex.toString()).get(lense).once((data, key) => {
240
+ this.gun.get(hex.toString()).get(lense).once((data, key) => {
131
241
  if (data) {
132
242
  const maplenght = Object.keys(data).length - 1
133
243
  console.log('Map length:', maplenght)
134
- this.gun.get(this.appname).get(hex.toString()).get(lense).map().once(async (itemdata, key) => {
244
+ this.gun.get(hex.toString()).get(lense).map().once(async (itemdata, key) => {
135
245
  counter += 1
136
246
  if (itemdata) {
137
247
  // if (itemdata._["#"]) {
138
248
  // // If the data is a reference, fetch the actual content
139
- // itemdata = await this.gun.get(this.appname).get(itemdata._['#']).then();
249
+ // itemdata = await this.gun.get(itemdata._['#']).then();
140
250
  // console.log("Data :",itemdata)
141
251
  // }
142
252
  var parsed = {}
@@ -151,7 +261,7 @@ class HoloSphere {
151
261
  let valid = this.validator.validate(schema, parsed);
152
262
  if (!valid || parsed == null || parsed == undefined) {
153
263
  console.log('Removing Invalid content:', this.validator.errors);
154
- this.gun.get(this.appname).get(hex).get(lense).get(key).put(null);
264
+ this.gun.get(hex).get(lense).get(key).put(null);
155
265
 
156
266
  } else {
157
267
  output.push(parsed);
@@ -208,7 +318,7 @@ class HoloSphere {
208
318
  console.log('Content:', content);
209
319
  let computed = await this.summarize(content.join('\n'))
210
320
  console.log('Computed:', computed)
211
- let node = await this.gun.get(this.appname).get(parent + '_summary').put({ id: parent + '_summary', content: computed })
321
+ let node = await this.gun.get(parent + '_summary').put({ id: parent + '_summary', content: computed })
212
322
 
213
323
  this.put(parent, lense, node);
214
324
  this.compute(parent, lense, operation)
@@ -218,10 +328,10 @@ class HoloSphere {
218
328
  let entities = {};
219
329
 
220
330
  // Get list out of Gun
221
- this.gun.get(this.appname).get(hex).get(lense).map().once((data, key) => {
331
+ this.gun.get(hex).get(lense).map().once((data, key) => {
222
332
  //entities = data;
223
333
  //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 })
334
+ this.gun.get(hex).get(lense).put({ [key]: null })
225
335
  })
226
336
  }
227
337
 
@@ -260,15 +370,15 @@ class HoloSphere {
260
370
 
261
371
  async upcast(hex, lense, content) {
262
372
  let res = h3.getResolution(hex)
263
-
264
- if (res == 0)
265
- return content
373
+
266
374
 
267
375
  console.log('Upcasting ', hex, lense, content)
268
376
  let parent = h3.cellToParent(hex, res - 1)
269
377
  await this.put(parent, lense, content)
270
-
271
- return this.upcast(parent, lense, content)
378
+ if (res == 0)
379
+ return content
380
+ else
381
+ return this.upcast(parent, lense, content)
272
382
  }
273
383
 
274
384
 
@@ -312,6 +422,62 @@ class HoloSphere {
312
422
  }
313
423
  return list
314
424
  }
425
+
426
+ subscribe(hex, lense, callback) {
427
+ this.gun.get(hex).get(lense).map().on((data, key) => {
428
+ callback(data, key)
429
+ })
430
+ }
431
+
432
+ // VOTING SYSTEM
433
+
434
+ getFinalVote(userId, topic, votes, visited = new Set()) {
435
+ if (visited.has(userId)) {
436
+ return null; // Avoid circular delegations
437
+ }
438
+ visited.add(userId);
439
+
440
+ const delegation = users[userId].delegations[topic];
441
+ if (delegation && votes[delegation] === undefined) {
442
+ return getFinalVote(delegation, topic, votes, visited); // Follow delegation
443
+ }
444
+
445
+ return votes[userId] !== undefined ? votes[userId] : null; // Return direct vote or null
446
+ }
447
+
448
+ aggregateVotes(hexId, topic) {
449
+ const votes = hexagonVotes[hexId][topic];
450
+ const aggregatedVotes = {};
451
+
452
+ Object.keys(votes).forEach(userId => {
453
+ const finalVote = getFinalVote(userId, topic, votes);
454
+ if (finalVote !== null) {
455
+ aggregatedVotes[finalVote] = (aggregatedVotes[finalVote] || 0) + 1;
456
+ }
457
+ });
458
+
459
+ return aggregatedVotes;
460
+ }
461
+
462
+ async delegateVote(userId, topic, delegateTo) {
463
+ const response = await fetch('/delegate', {
464
+ method: 'POST',
465
+ headers: { 'Content-Type': 'application/json' },
466
+ body: JSON.stringify({ userId, topic, delegateTo })
467
+ });
468
+ alert(await response.text());
469
+ }
470
+
471
+ async vote(userId, hexId, topic, vote) {
472
+ const response = await fetch('/vote', {
473
+ method: 'POST',
474
+ headers: { 'Content-Type': 'application/json' },
475
+ body: JSON.stringify({ userId, hexId, topic, vote })
476
+ });
477
+ alert(await response.text());
478
+ }
479
+
480
+
315
481
  }
316
482
 
317
483
  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.4",
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,7 @@
11
11
  "license": "GPL-3.0-or-later",
12
12
  "dependencies": {
13
13
  "ajv": "^8.12.0",
14
- "gun": "^0.2020.1239",
14
+ "gun": "^0.2020.1240",
15
15
  "h3-js": "^4.1.0",
16
16
  "openai": "^4.29.2"
17
17
  }