holosphere 1.1.19 → 2.0.0-alpha0

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 (146) hide show
  1. package/.env.example +36 -0
  2. package/.eslintrc.json +16 -0
  3. package/.prettierrc.json +7 -0
  4. package/README.md +476 -531
  5. package/bin/holosphere-activitypub.js +158 -0
  6. package/cleanup-test-data.js +204 -0
  7. package/examples/demo.html +1333 -0
  8. package/examples/example-bot.js +197 -0
  9. package/package.json +47 -87
  10. package/scripts/check-bundle-size.js +54 -0
  11. package/scripts/check-quest-ids.js +77 -0
  12. package/scripts/import-holons.js +578 -0
  13. package/scripts/publish-to-relay.js +101 -0
  14. package/scripts/read-example.js +186 -0
  15. package/scripts/relay-diagnostic.js +59 -0
  16. package/scripts/relay-example.js +179 -0
  17. package/scripts/resync-to-relay.js +245 -0
  18. package/scripts/revert-import.js +196 -0
  19. package/scripts/test-hybrid-mode.js +108 -0
  20. package/scripts/test-local-storage.js +63 -0
  21. package/scripts/test-nostr-direct.js +55 -0
  22. package/scripts/test-read-data.js +45 -0
  23. package/scripts/test-write-read.js +63 -0
  24. package/scripts/verify-import.js +95 -0
  25. package/scripts/verify-relay-data.js +139 -0
  26. package/src/ai/aggregation.js +319 -0
  27. package/src/ai/breakdown.js +511 -0
  28. package/src/ai/classifier.js +217 -0
  29. package/src/ai/council.js +228 -0
  30. package/src/ai/embeddings.js +279 -0
  31. package/src/ai/federation-ai.js +324 -0
  32. package/src/ai/h3-ai.js +955 -0
  33. package/src/ai/index.js +112 -0
  34. package/src/ai/json-ops.js +225 -0
  35. package/src/ai/llm-service.js +205 -0
  36. package/src/ai/nl-query.js +223 -0
  37. package/src/ai/relationships.js +353 -0
  38. package/src/ai/schema-extractor.js +218 -0
  39. package/src/ai/spatial.js +293 -0
  40. package/src/ai/tts.js +194 -0
  41. package/src/content/social-protocols.js +168 -0
  42. package/src/core/holosphere.js +273 -0
  43. package/src/crypto/secp256k1.js +259 -0
  44. package/src/federation/discovery.js +334 -0
  45. package/src/federation/hologram.js +1042 -0
  46. package/src/federation/registry.js +386 -0
  47. package/src/hierarchical/upcast.js +110 -0
  48. package/src/index.js +2669 -0
  49. package/src/schema/validator.js +91 -0
  50. package/src/spatial/h3-operations.js +110 -0
  51. package/src/storage/backend-factory.js +125 -0
  52. package/src/storage/backend-interface.js +142 -0
  53. package/src/storage/backends/activitypub/server.js +653 -0
  54. package/src/storage/backends/activitypub-backend.js +272 -0
  55. package/src/storage/backends/gundb-backend.js +233 -0
  56. package/src/storage/backends/nostr-backend.js +136 -0
  57. package/src/storage/filesystem-storage-browser.js +41 -0
  58. package/src/storage/filesystem-storage.js +138 -0
  59. package/src/storage/global-tables.js +81 -0
  60. package/src/storage/gun-async.js +281 -0
  61. package/src/storage/gun-wrapper.js +221 -0
  62. package/src/storage/indexeddb-storage.js +122 -0
  63. package/src/storage/key-storage-simple.js +76 -0
  64. package/src/storage/key-storage.js +136 -0
  65. package/src/storage/memory-storage.js +59 -0
  66. package/src/storage/migration.js +338 -0
  67. package/src/storage/nostr-async.js +811 -0
  68. package/src/storage/nostr-client.js +939 -0
  69. package/src/storage/nostr-wrapper.js +211 -0
  70. package/src/storage/outbox-queue.js +208 -0
  71. package/src/storage/persistent-storage.js +109 -0
  72. package/src/storage/sync-service.js +164 -0
  73. package/src/subscriptions/manager.js +142 -0
  74. package/test-ai-real-api.js +202 -0
  75. package/tests/unit/ai/aggregation.test.js +295 -0
  76. package/tests/unit/ai/breakdown.test.js +446 -0
  77. package/tests/unit/ai/classifier.test.js +294 -0
  78. package/tests/unit/ai/council.test.js +262 -0
  79. package/tests/unit/ai/embeddings.test.js +384 -0
  80. package/tests/unit/ai/federation-ai.test.js +344 -0
  81. package/tests/unit/ai/h3-ai.test.js +458 -0
  82. package/tests/unit/ai/index.test.js +304 -0
  83. package/tests/unit/ai/json-ops.test.js +307 -0
  84. package/tests/unit/ai/llm-service.test.js +390 -0
  85. package/tests/unit/ai/nl-query.test.js +383 -0
  86. package/tests/unit/ai/relationships.test.js +311 -0
  87. package/tests/unit/ai/schema-extractor.test.js +384 -0
  88. package/tests/unit/ai/spatial.test.js +279 -0
  89. package/tests/unit/ai/tts.test.js +279 -0
  90. package/tests/unit/content.test.js +332 -0
  91. package/tests/unit/contract/core.test.js +88 -0
  92. package/tests/unit/contract/crypto.test.js +198 -0
  93. package/tests/unit/contract/data.test.js +223 -0
  94. package/tests/unit/contract/federation.test.js +181 -0
  95. package/tests/unit/contract/hierarchical.test.js +113 -0
  96. package/tests/unit/contract/schema.test.js +114 -0
  97. package/tests/unit/contract/social.test.js +217 -0
  98. package/tests/unit/contract/spatial.test.js +110 -0
  99. package/tests/unit/contract/subscriptions.test.js +128 -0
  100. package/tests/unit/contract/utils.test.js +159 -0
  101. package/tests/unit/core.test.js +152 -0
  102. package/tests/unit/crypto.test.js +328 -0
  103. package/tests/unit/federation.test.js +234 -0
  104. package/tests/unit/gun-async.test.js +252 -0
  105. package/tests/unit/hierarchical.test.js +399 -0
  106. package/tests/unit/integration/scenario-01-geographic-storage.test.js +74 -0
  107. package/tests/unit/integration/scenario-02-federation.test.js +76 -0
  108. package/tests/unit/integration/scenario-03-subscriptions.test.js +102 -0
  109. package/tests/unit/integration/scenario-04-validation.test.js +129 -0
  110. package/tests/unit/integration/scenario-05-hierarchy.test.js +125 -0
  111. package/tests/unit/integration/scenario-06-social.test.js +135 -0
  112. package/tests/unit/integration/scenario-07-persistence.test.js +130 -0
  113. package/tests/unit/integration/scenario-08-authorization.test.js +161 -0
  114. package/tests/unit/integration/scenario-09-cross-dimensional.test.js +139 -0
  115. package/tests/unit/integration/scenario-10-cross-holosphere-capabilities.test.js +357 -0
  116. package/tests/unit/integration/scenario-11-cross-holosphere-federation.test.js +410 -0
  117. package/tests/unit/integration/scenario-12-capability-federated-read.test.js +719 -0
  118. package/tests/unit/performance/benchmark.test.js +85 -0
  119. package/tests/unit/schema.test.js +213 -0
  120. package/tests/unit/spatial.test.js +158 -0
  121. package/tests/unit/storage.test.js +195 -0
  122. package/tests/unit/subscriptions.test.js +328 -0
  123. package/tests/unit/test-data-permanence-debug.js +197 -0
  124. package/tests/unit/test-data-permanence.js +340 -0
  125. package/tests/unit/test-key-persistence-fixed.js +148 -0
  126. package/tests/unit/test-key-persistence.js +172 -0
  127. package/tests/unit/test-relay-permanence.js +376 -0
  128. package/tests/unit/test-second-node.js +95 -0
  129. package/tests/unit/test-simple-write.js +89 -0
  130. package/vite.config.js +49 -0
  131. package/vitest.config.js +20 -0
  132. package/FEDERATION.md +0 -213
  133. package/compute.js +0 -298
  134. package/content.js +0 -1022
  135. package/federation.js +0 -1234
  136. package/global.js +0 -736
  137. package/hexlib.js +0 -335
  138. package/hologram.js +0 -183
  139. package/holosphere-bundle.esm.js +0 -34549
  140. package/holosphere-bundle.js +0 -34580
  141. package/holosphere-bundle.min.js +0 -49
  142. package/holosphere.d.ts +0 -604
  143. package/holosphere.js +0 -739
  144. package/node.js +0 -246
  145. package/schema.js +0 -139
  146. package/utils.js +0 -302
package/hexlib.js DELETED
@@ -1,335 +0,0 @@
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();
333
-
334
- // Export Hex as the default since it's the main class
335
- export default Hex;
package/hologram.js DELETED
@@ -1,183 +0,0 @@
1
- // holo_hologram.js
2
-
3
- /**
4
- * Creates a soul hologram object for a data item
5
- * @param {HoloSphere} holoInstance - The HoloSphere instance.
6
- * @param {string} holon - The holon where the original data is stored
7
- * @param {string} lens - The lens where the original data is stored
8
- * @param {object} data - The data to create a hologram for
9
- * @returns {object} - A hologram object with id and soul
10
- */
11
- export function createHologram(holoInstance, holon, lens, data) {
12
- // Check if the input data is already a hologram
13
- if (isHologram(data)) {
14
- // If it is, just return its existing ID and Soul, ignoring the provided holon/lens
15
- return {
16
- id: data.id,
17
- soul: data.soul
18
- };
19
- }
20
-
21
- // Original logic: Input data is not a hologram, create a new soul path
22
- if (!holon || !lens || !data || !data.id) {
23
- throw new Error('createHologram: Missing required parameters for non-hologram data');
24
- }
25
-
26
- const soul = `${holoInstance.appname}/${holon}/${lens}/${data.id}`;
27
- return {
28
- id: data.id,
29
- soul: soul
30
- };
31
- }
32
-
33
- /**
34
- * Parses a soul path into its components.
35
- * @param {string} soul - The soul path (e.g., "app/holon/lens/key").
36
- * @returns {object|null} - An object with appname, holon, lens, key, or null if invalid.
37
- */
38
- export function parseSoulPath(soul) {
39
- if (typeof soul !== 'string') return null;
40
- const parts = soul.split('/');
41
- if (parts.length < 4) return null; // Must have at least app/holon/lens/key
42
-
43
- // Reconstruct key if it contained slashes (though generally disallowed by getNodeRef validation)
44
- const key = parts.slice(3).join('/');
45
-
46
- return {
47
- appname: parts[0],
48
- holon: parts[1],
49
- lens: parts[2],
50
- key: key
51
- };
52
- }
53
-
54
- /**
55
- * Checks if an object is a hologram.
56
- * This function checks for the presence and type of `id` and `soul` properties,
57
- * suitable for identifying holograms represented as plain JavaScript objects.
58
- * It also performs a basic check that the `soul` contains '/' as expected for a path.
59
- * @param {object | null | undefined} data - The data to check.
60
- * @returns {boolean} - True if the object is considered a hologram.
61
- */
62
- export function isHologram(data) {
63
- if (!data || typeof data !== 'object') {
64
- return false;
65
- }
66
-
67
- // Basic check: Does it have an 'id' and a 'soul' which is a non-empty string?
68
- if (data.id && typeof data.soul === 'string' && data.soul.length > 0) {
69
- // Optional stricter check: Does the soul look like a valid path?
70
- // This prevents objects like { id: 1, soul: "hello" } from being counted.
71
- // We can use a simplified check here or rely on parseSoulPath failing later.
72
- if (data.soul.includes('/')) { // Simple check for path structure
73
- return true;
74
- }
75
- }
76
-
77
- return false;
78
- }
79
-
80
- /**
81
- * Resolves a hologram to its actual data
82
- * @param {HoloSphere} holoInstance - The HoloSphere instance.
83
- * @param {object} hologram - The hologram to resolve
84
- * @param {object} [options] - Optional parameters
85
- * @param {boolean} [options.followHolograms=true] - Whether to follow nested holograms
86
- * @param {Set<string>} [options.visited] - Internal use: Tracks visited souls to prevent loops
87
- * @param {number} [options.maxDepth=10] - Maximum resolution depth to prevent infinite loops
88
- * @param {number} [options.currentDepth=0] - Current resolution depth
89
- * @returns {Promise<object|null>} - The resolved data, null if resolution failed due to target not found, or the original hologram for circular/invalid cases.
90
- */
91
- export async function resolveHologram(holoInstance, hologram, options = {}) {
92
- if (!isHologram(hologram)) {
93
- return hologram; // Not a hologram, return as is
94
- }
95
-
96
- const {
97
- followHolograms = true,
98
- visited = new Set(),
99
- maxDepth = 10,
100
- currentDepth = 0
101
- } = options;
102
-
103
- // Check depth limit first
104
- if (currentDepth >= maxDepth) {
105
- console.warn(`!!! Maximum resolution depth (${maxDepth}) reached for soul: ${hologram.soul}. Stopping resolution.`);
106
- return null;
107
- }
108
-
109
- // Check for circular hologram
110
- if (hologram.soul && visited.has(hologram.soul)) {
111
- console.warn(`!!! CIRCULAR hologram detected for soul: ${hologram.soul}. Breaking loop.`);
112
- return null;
113
- }
114
-
115
- try {
116
- // Handle direct soul hologram
117
- if (hologram.soul) {
118
- const soulInfo = parseSoulPath(hologram.soul);
119
- if (!soulInfo) {
120
- console.warn(`Invalid soul format: ${hologram.soul}`);
121
- return null;
122
- }
123
-
124
- // Add current soul to visited set for THIS resolution path
125
- const nextVisited = new Set(visited);
126
- nextVisited.add(hologram.soul);
127
-
128
- // Only log when actually resolving a hologram for debugging if needed
129
- // console.log(`Resolving hologram: ${hologram.soul}`);
130
-
131
- // Get original data with increased depth
132
- const originalData = await holoInstance.get(
133
- soulInfo.holon,
134
- soulInfo.lens,
135
- soulInfo.key,
136
- null,
137
- {
138
- resolveHolograms: followHolograms,
139
- visited: nextVisited,
140
- maxDepth: maxDepth,
141
- currentDepth: currentDepth + 1
142
- }
143
- );
144
-
145
- if (originalData && !originalData._invalidHologram) {
146
- // Structure for the returned object - isHologram (top-level) is removed
147
- return {
148
- ...originalData,
149
- _meta: {
150
- ...(originalData._meta || {}), // Preserve original _meta
151
- resolvedFromHologram: true, // This is now the primary indicator
152
- hologramSoul: hologram.soul, // Clarified meta field
153
- resolutionDepth: currentDepth
154
- }
155
- };
156
- } else {
157
- console.warn(`!!! Original data NOT FOUND for soul: ${hologram.soul}. Removing broken hologram.`);
158
-
159
- // Return null to indicate the hologram should be removed
160
- return null;
161
- }
162
- } else {
163
- // Should not happen if isHologram() passed
164
- console.warn('!!! resolveHologram called with object missing soul:', hologram);
165
- return null;
166
- }
167
- } catch (error) {
168
- if (error.message?.startsWith('CIRCULAR_REFERENCE')) {
169
- console.warn(`!!! Circular reference detected during hologram resolution: ${error.message}`);
170
- return null;
171
- }
172
- console.error(`!!! Error resolving hologram: ${error.message}`, error);
173
- return null; // Return null on error to prevent loops
174
- }
175
- }
176
-
177
- // Export all hologram operations as default
178
- export default {
179
- createHologram,
180
- parseSoulPath,
181
- isHologram,
182
- resolveHologram
183
- };