holosphere 1.1.20 → 2.0.0-alpha1
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/.env.example +36 -0
- package/.eslintrc.json +16 -0
- package/.prettierrc.json +7 -0
- package/LICENSE +162 -38
- package/README.md +483 -367
- package/bin/holosphere-activitypub.js +158 -0
- package/cleanup-test-data.js +204 -0
- package/examples/demo.html +1333 -0
- package/examples/example-bot.js +197 -0
- package/package.json +47 -87
- package/scripts/check-bundle-size.js +54 -0
- package/scripts/check-quest-ids.js +77 -0
- package/scripts/import-holons.js +578 -0
- package/scripts/publish-to-relay.js +101 -0
- package/scripts/read-example.js +186 -0
- package/scripts/relay-diagnostic.js +59 -0
- package/scripts/relay-example.js +179 -0
- package/scripts/resync-to-relay.js +245 -0
- package/scripts/revert-import.js +196 -0
- package/scripts/test-hybrid-mode.js +108 -0
- package/scripts/test-local-storage.js +63 -0
- package/scripts/test-nostr-direct.js +55 -0
- package/scripts/test-read-data.js +45 -0
- package/scripts/test-write-read.js +63 -0
- package/scripts/verify-import.js +95 -0
- package/scripts/verify-relay-data.js +139 -0
- package/src/ai/aggregation.js +319 -0
- package/src/ai/breakdown.js +511 -0
- package/src/ai/classifier.js +217 -0
- package/src/ai/council.js +228 -0
- package/src/ai/embeddings.js +279 -0
- package/src/ai/federation-ai.js +324 -0
- package/src/ai/h3-ai.js +955 -0
- package/src/ai/index.js +112 -0
- package/src/ai/json-ops.js +225 -0
- package/src/ai/llm-service.js +205 -0
- package/src/ai/nl-query.js +223 -0
- package/src/ai/relationships.js +353 -0
- package/src/ai/schema-extractor.js +218 -0
- package/src/ai/spatial.js +293 -0
- package/src/ai/tts.js +194 -0
- package/src/content/social-protocols.js +168 -0
- package/src/core/holosphere.js +273 -0
- package/src/crypto/secp256k1.js +259 -0
- package/src/federation/discovery.js +334 -0
- package/src/federation/hologram.js +1042 -0
- package/src/federation/registry.js +386 -0
- package/src/hierarchical/upcast.js +110 -0
- package/src/index.js +2669 -0
- package/src/schema/validator.js +91 -0
- package/src/spatial/h3-operations.js +110 -0
- package/src/storage/backend-factory.js +125 -0
- package/src/storage/backend-interface.js +142 -0
- package/src/storage/backends/activitypub/server.js +653 -0
- package/src/storage/backends/activitypub-backend.js +272 -0
- package/src/storage/backends/gundb-backend.js +233 -0
- package/src/storage/backends/nostr-backend.js +136 -0
- package/src/storage/filesystem-storage-browser.js +41 -0
- package/src/storage/filesystem-storage.js +138 -0
- package/src/storage/global-tables.js +81 -0
- package/src/storage/gun-async.js +281 -0
- package/src/storage/gun-wrapper.js +221 -0
- package/src/storage/indexeddb-storage.js +122 -0
- package/src/storage/key-storage-simple.js +76 -0
- package/src/storage/key-storage.js +136 -0
- package/src/storage/memory-storage.js +59 -0
- package/src/storage/migration.js +338 -0
- package/src/storage/nostr-async.js +811 -0
- package/src/storage/nostr-client.js +939 -0
- package/src/storage/nostr-wrapper.js +211 -0
- package/src/storage/outbox-queue.js +208 -0
- package/src/storage/persistent-storage.js +109 -0
- package/src/storage/sync-service.js +164 -0
- package/src/subscriptions/manager.js +142 -0
- package/test-ai-real-api.js +202 -0
- package/tests/unit/ai/aggregation.test.js +295 -0
- package/tests/unit/ai/breakdown.test.js +446 -0
- package/tests/unit/ai/classifier.test.js +294 -0
- package/tests/unit/ai/council.test.js +262 -0
- package/tests/unit/ai/embeddings.test.js +384 -0
- package/tests/unit/ai/federation-ai.test.js +344 -0
- package/tests/unit/ai/h3-ai.test.js +458 -0
- package/tests/unit/ai/index.test.js +304 -0
- package/tests/unit/ai/json-ops.test.js +307 -0
- package/tests/unit/ai/llm-service.test.js +390 -0
- package/tests/unit/ai/nl-query.test.js +383 -0
- package/tests/unit/ai/relationships.test.js +311 -0
- package/tests/unit/ai/schema-extractor.test.js +384 -0
- package/tests/unit/ai/spatial.test.js +279 -0
- package/tests/unit/ai/tts.test.js +279 -0
- package/tests/unit/content.test.js +332 -0
- package/tests/unit/contract/core.test.js +88 -0
- package/tests/unit/contract/crypto.test.js +198 -0
- package/tests/unit/contract/data.test.js +223 -0
- package/tests/unit/contract/federation.test.js +181 -0
- package/tests/unit/contract/hierarchical.test.js +113 -0
- package/tests/unit/contract/schema.test.js +114 -0
- package/tests/unit/contract/social.test.js +217 -0
- package/tests/unit/contract/spatial.test.js +110 -0
- package/tests/unit/contract/subscriptions.test.js +128 -0
- package/tests/unit/contract/utils.test.js +159 -0
- package/tests/unit/core.test.js +152 -0
- package/tests/unit/crypto.test.js +328 -0
- package/tests/unit/federation.test.js +234 -0
- package/tests/unit/gun-async.test.js +252 -0
- package/tests/unit/hierarchical.test.js +399 -0
- package/tests/unit/integration/scenario-01-geographic-storage.test.js +74 -0
- package/tests/unit/integration/scenario-02-federation.test.js +76 -0
- package/tests/unit/integration/scenario-03-subscriptions.test.js +102 -0
- package/tests/unit/integration/scenario-04-validation.test.js +129 -0
- package/tests/unit/integration/scenario-05-hierarchy.test.js +125 -0
- package/tests/unit/integration/scenario-06-social.test.js +135 -0
- package/tests/unit/integration/scenario-07-persistence.test.js +130 -0
- package/tests/unit/integration/scenario-08-authorization.test.js +161 -0
- package/tests/unit/integration/scenario-09-cross-dimensional.test.js +139 -0
- package/tests/unit/integration/scenario-10-cross-holosphere-capabilities.test.js +357 -0
- package/tests/unit/integration/scenario-11-cross-holosphere-federation.test.js +410 -0
- package/tests/unit/integration/scenario-12-capability-federated-read.test.js +719 -0
- package/tests/unit/performance/benchmark.test.js +85 -0
- package/tests/unit/schema.test.js +213 -0
- package/tests/unit/spatial.test.js +158 -0
- package/tests/unit/storage.test.js +195 -0
- package/tests/unit/subscriptions.test.js +328 -0
- package/tests/unit/test-data-permanence-debug.js +197 -0
- package/tests/unit/test-data-permanence.js +340 -0
- package/tests/unit/test-key-persistence-fixed.js +148 -0
- package/tests/unit/test-key-persistence.js +172 -0
- package/tests/unit/test-relay-permanence.js +376 -0
- package/tests/unit/test-second-node.js +95 -0
- package/tests/unit/test-simple-write.js +89 -0
- package/vite.config.js +49 -0
- package/vitest.config.js +20 -0
- package/FEDERATION.md +0 -213
- package/compute.js +0 -298
- package/content.js +0 -980
- package/federation.js +0 -1234
- package/global.js +0 -736
- package/hexlib.js +0 -335
- package/hologram.js +0 -183
- package/holosphere-bundle.esm.js +0 -33256
- package/holosphere-bundle.js +0 -33287
- package/holosphere-bundle.min.js +0 -39
- package/holosphere.d.ts +0 -601
- package/holosphere.js +0 -719
- package/node.js +0 -246
- package/schema.js +0 -139
- 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
|
-
};
|