holosphere 2.0.0-alpha1 → 2.0.0-alpha4

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 (154) hide show
  1. package/dist/2019-D2OG2idw.js +6680 -0
  2. package/dist/2019-D2OG2idw.js.map +1 -0
  3. package/dist/2019-EION3wKo.cjs +8 -0
  4. package/dist/2019-EION3wKo.cjs.map +1 -0
  5. package/dist/_commonjsHelpers-C37NGDzP.cjs +2 -0
  6. package/dist/_commonjsHelpers-C37NGDzP.cjs.map +1 -0
  7. package/dist/_commonjsHelpers-CUmg6egw.js +7 -0
  8. package/dist/_commonjsHelpers-CUmg6egw.js.map +1 -0
  9. package/dist/browser-BSniCNqO.js +3058 -0
  10. package/dist/browser-BSniCNqO.js.map +1 -0
  11. package/dist/browser-Cq59Ij19.cjs +2 -0
  12. package/dist/browser-Cq59Ij19.cjs.map +1 -0
  13. package/dist/cjs/holosphere.cjs +2 -0
  14. package/dist/cjs/holosphere.cjs.map +1 -0
  15. package/dist/esm/holosphere.js +53 -0
  16. package/dist/esm/holosphere.js.map +1 -0
  17. package/dist/index-BB_vVJgv.cjs +5 -0
  18. package/dist/index-BB_vVJgv.cjs.map +1 -0
  19. package/dist/index-CBitK71M.cjs +12 -0
  20. package/dist/index-CBitK71M.cjs.map +1 -0
  21. package/dist/index-CV0eOogK.js +37423 -0
  22. package/dist/index-CV0eOogK.js.map +1 -0
  23. package/dist/index-Cz-PLCUR.js +15104 -0
  24. package/dist/index-Cz-PLCUR.js.map +1 -0
  25. package/dist/indexeddb-storage-CRsZyB2f.cjs +2 -0
  26. package/dist/indexeddb-storage-CRsZyB2f.cjs.map +1 -0
  27. package/dist/indexeddb-storage-DZaGlY_a.js +132 -0
  28. package/dist/indexeddb-storage-DZaGlY_a.js.map +1 -0
  29. package/dist/memory-storage-BkUi6sZG.js +51 -0
  30. package/dist/memory-storage-BkUi6sZG.js.map +1 -0
  31. package/dist/memory-storage-C0DuUsdY.cjs +2 -0
  32. package/dist/memory-storage-C0DuUsdY.cjs.map +1 -0
  33. package/dist/secp256k1-0kPdAVkK.cjs +12 -0
  34. package/dist/secp256k1-0kPdAVkK.cjs.map +1 -0
  35. package/dist/secp256k1-DN4FVXcv.js +1890 -0
  36. package/dist/secp256k1-DN4FVXcv.js.map +1 -0
  37. package/docs/CONTRACTS.md +797 -0
  38. package/docs/FOSDEM_PROPOSAL.md +388 -0
  39. package/docs/LOCALFIRST.md +266 -0
  40. package/docs/contracts/api-interface.md +793 -0
  41. package/docs/data-model.md +476 -0
  42. package/docs/gun-async-usage.md +338 -0
  43. package/docs/plan.md +349 -0
  44. package/docs/quickstart.md +674 -0
  45. package/docs/research.md +362 -0
  46. package/docs/spec.md +244 -0
  47. package/docs/storage-backends.md +326 -0
  48. package/docs/tasks.md +947 -0
  49. package/examples/demo.html +47 -0
  50. package/package.json +10 -5
  51. package/src/contracts/abis/Appreciative.json +1280 -0
  52. package/src/contracts/abis/AppreciativeFactory.json +101 -0
  53. package/src/contracts/abis/Bundle.json +1435 -0
  54. package/src/contracts/abis/BundleFactory.json +106 -0
  55. package/src/contracts/abis/Holon.json +881 -0
  56. package/src/contracts/abis/Holons.json +330 -0
  57. package/src/contracts/abis/Managed.json +1262 -0
  58. package/src/contracts/abis/ManagedFactory.json +149 -0
  59. package/src/contracts/abis/Membrane.json +261 -0
  60. package/src/contracts/abis/Splitter.json +1624 -0
  61. package/src/contracts/abis/SplitterFactory.json +220 -0
  62. package/src/contracts/abis/TestToken.json +321 -0
  63. package/src/contracts/abis/Zoned.json +1461 -0
  64. package/src/contracts/abis/ZonedFactory.json +154 -0
  65. package/src/contracts/chain-manager.js +375 -0
  66. package/src/contracts/deployer.js +443 -0
  67. package/src/contracts/event-listener.js +507 -0
  68. package/src/contracts/holon-contracts.js +344 -0
  69. package/src/contracts/index.js +83 -0
  70. package/src/contracts/networks.js +224 -0
  71. package/src/contracts/operations.js +670 -0
  72. package/src/contracts/queries.js +589 -0
  73. package/src/core/holosphere.js +453 -1
  74. package/src/crypto/nostr-utils.js +263 -0
  75. package/src/federation/handshake.js +455 -0
  76. package/src/federation/hologram.js +1 -1
  77. package/src/hierarchical/upcast.js +6 -5
  78. package/src/index.js +463 -1939
  79. package/src/lib/ai-methods.js +308 -0
  80. package/src/lib/contract-methods.js +293 -0
  81. package/src/lib/errors.js +23 -0
  82. package/src/lib/federation-methods.js +238 -0
  83. package/src/lib/index.js +26 -0
  84. package/src/spatial/h3-operations.js +2 -2
  85. package/src/storage/backends/gundb-backend.js +377 -46
  86. package/src/storage/global-tables.js +28 -1
  87. package/src/storage/gun-auth.js +303 -0
  88. package/src/storage/gun-federation.js +776 -0
  89. package/src/storage/gun-references.js +198 -0
  90. package/src/storage/gun-schema.js +291 -0
  91. package/src/storage/gun-wrapper.js +347 -31
  92. package/src/storage/indexeddb-storage.js +49 -11
  93. package/src/storage/memory-storage.js +5 -0
  94. package/src/storage/nostr-async.js +45 -23
  95. package/src/storage/nostr-client.js +11 -5
  96. package/src/storage/persistent-storage.js +6 -1
  97. package/src/storage/unified-storage.js +119 -0
  98. package/src/subscriptions/manager.js +1 -1
  99. package/types/index.d.ts +133 -0
  100. package/tests/unit/ai/aggregation.test.js +0 -295
  101. package/tests/unit/ai/breakdown.test.js +0 -446
  102. package/tests/unit/ai/classifier.test.js +0 -294
  103. package/tests/unit/ai/council.test.js +0 -262
  104. package/tests/unit/ai/embeddings.test.js +0 -384
  105. package/tests/unit/ai/federation-ai.test.js +0 -344
  106. package/tests/unit/ai/h3-ai.test.js +0 -458
  107. package/tests/unit/ai/index.test.js +0 -304
  108. package/tests/unit/ai/json-ops.test.js +0 -307
  109. package/tests/unit/ai/llm-service.test.js +0 -390
  110. package/tests/unit/ai/nl-query.test.js +0 -383
  111. package/tests/unit/ai/relationships.test.js +0 -311
  112. package/tests/unit/ai/schema-extractor.test.js +0 -384
  113. package/tests/unit/ai/spatial.test.js +0 -279
  114. package/tests/unit/ai/tts.test.js +0 -279
  115. package/tests/unit/content.test.js +0 -332
  116. package/tests/unit/contract/core.test.js +0 -88
  117. package/tests/unit/contract/crypto.test.js +0 -198
  118. package/tests/unit/contract/data.test.js +0 -223
  119. package/tests/unit/contract/federation.test.js +0 -181
  120. package/tests/unit/contract/hierarchical.test.js +0 -113
  121. package/tests/unit/contract/schema.test.js +0 -114
  122. package/tests/unit/contract/social.test.js +0 -217
  123. package/tests/unit/contract/spatial.test.js +0 -110
  124. package/tests/unit/contract/subscriptions.test.js +0 -128
  125. package/tests/unit/contract/utils.test.js +0 -159
  126. package/tests/unit/core.test.js +0 -152
  127. package/tests/unit/crypto.test.js +0 -328
  128. package/tests/unit/federation.test.js +0 -234
  129. package/tests/unit/gun-async.test.js +0 -252
  130. package/tests/unit/hierarchical.test.js +0 -399
  131. package/tests/unit/integration/scenario-01-geographic-storage.test.js +0 -74
  132. package/tests/unit/integration/scenario-02-federation.test.js +0 -76
  133. package/tests/unit/integration/scenario-03-subscriptions.test.js +0 -102
  134. package/tests/unit/integration/scenario-04-validation.test.js +0 -129
  135. package/tests/unit/integration/scenario-05-hierarchy.test.js +0 -125
  136. package/tests/unit/integration/scenario-06-social.test.js +0 -135
  137. package/tests/unit/integration/scenario-07-persistence.test.js +0 -130
  138. package/tests/unit/integration/scenario-08-authorization.test.js +0 -161
  139. package/tests/unit/integration/scenario-09-cross-dimensional.test.js +0 -139
  140. package/tests/unit/integration/scenario-10-cross-holosphere-capabilities.test.js +0 -357
  141. package/tests/unit/integration/scenario-11-cross-holosphere-federation.test.js +0 -410
  142. package/tests/unit/integration/scenario-12-capability-federated-read.test.js +0 -719
  143. package/tests/unit/performance/benchmark.test.js +0 -85
  144. package/tests/unit/schema.test.js +0 -213
  145. package/tests/unit/spatial.test.js +0 -158
  146. package/tests/unit/storage.test.js +0 -195
  147. package/tests/unit/subscriptions.test.js +0 -328
  148. package/tests/unit/test-data-permanence-debug.js +0 -197
  149. package/tests/unit/test-data-permanence.js +0 -340
  150. package/tests/unit/test-key-persistence-fixed.js +0 -148
  151. package/tests/unit/test-key-persistence.js +0 -172
  152. package/tests/unit/test-relay-permanence.js +0 -376
  153. package/tests/unit/test-second-node.js +0 -95
  154. package/tests/unit/test-simple-write.js +0 -89
@@ -1,376 +0,0 @@
1
- /**
2
- * Comprehensive Data Permanence Test Through Relays
3
- *
4
- * This test validates complete data persistence through the Nostr relay network:
5
- * 1. Write data from Node 1
6
- * 2. Verify immediate readback on Node 1
7
- * 3. Wait for relay propagation
8
- * 4. Create Node 2 and verify it can read Node 1's data
9
- * 5. Restart Node 1 (new instance) and verify data recovery
10
- * 6. Update data and verify updates propagate
11
- * 7. Verify batch writes persist
12
- */
13
-
14
- import { HoloSphere } from './dist/esm/holosphere.js';
15
-
16
- // Relay configuration - use env vars or these defaults
17
- const RELAYS = process.env.HOLOSPHERE_RELAYS?.split(',') || [
18
- 'wss://relay.holons.io',
19
- 'wss://relay.nostr.band',
20
- ];
21
-
22
- // Test configuration
23
- const TEST_CONFIG = {
24
- appName: 'relay-permanence-test',
25
- relays: RELAYS,
26
- logLevel: 'INFO'
27
- };
28
-
29
- const TEST_HOLON = 'global://permanence';
30
- const WAIT_FOR_SYNC = 4000; // 4 seconds for relay sync
31
-
32
- // Colors for console
33
- const c = {
34
- reset: '\x1b[0m',
35
- green: '\x1b[32m',
36
- red: '\x1b[31m',
37
- yellow: '\x1b[33m',
38
- blue: '\x1b[34m',
39
- cyan: '\x1b[36m',
40
- bold: '\x1b[1m'
41
- };
42
-
43
- function log(msg, color = 'reset') {
44
- console.log(`${c[color]}${msg}${c.reset}`);
45
- }
46
-
47
- function section(title) {
48
- console.log('\n' + '═'.repeat(70));
49
- log(` ${title}`, 'cyan');
50
- console.log('═'.repeat(70) + '\n');
51
- }
52
-
53
- function test(name, passed, details = '') {
54
- const icon = passed ? 'āœ…' : 'āŒ';
55
- const color = passed ? 'green' : 'red';
56
- log(`${icon} ${name}`, color);
57
- if (details) console.log(` ${details}`);
58
- }
59
-
60
- async function wait(ms, message) {
61
- if (message) log(`ā³ ${message}`, 'yellow');
62
- await new Promise(resolve => setTimeout(resolve, ms));
63
- }
64
-
65
- // Track test results
66
- const results = {
67
- passed: 0,
68
- failed: 0,
69
- tests: []
70
- };
71
-
72
- function addResult(name, passed, details = '') {
73
- test(name, passed, details);
74
- results.tests.push({ name, passed, details });
75
- if (passed) results.passed++;
76
- else results.failed++;
77
- }
78
-
79
- /**
80
- * Test 1: Write data from Node 1 and verify immediate readback
81
- */
82
- async function test1_WriteAndRead(hs) {
83
- section('TEST 1: Write Data and Immediate Readback');
84
-
85
- const testData = {
86
- id: `perm-test-${Date.now()}`,
87
- message: 'Data permanence test',
88
- timestamp: Date.now(),
89
- metadata: {
90
- test: 'write-read',
91
- node: 1
92
- }
93
- };
94
-
95
- log('Writing test data from Node 1...', 'yellow');
96
- const writeResult = await hs.write(TEST_HOLON, 'data', testData);
97
- addResult('Write operation successful', writeResult, `ID: ${testData.id}`);
98
-
99
- if (!writeResult) {
100
- log('āš ļø Write failed - skipping read test', 'red');
101
- return { success: false, testData };
102
- }
103
-
104
- await wait(500, 'Waiting for local cache...');
105
-
106
- log('Reading data back on Node 1...', 'yellow');
107
- const readData = await hs.read(TEST_HOLON, 'data');
108
-
109
- const found = readData && readData.some(d => d.id === testData.id);
110
- addResult('Data readable immediately after write', found,
111
- found ? `Found ${readData.length} record(s)` : 'Data not found');
112
-
113
- if (found) {
114
- const record = readData.find(d => d.id === testData.id);
115
- const matches = record.message === testData.message;
116
- addResult('Data content matches original', matches);
117
- }
118
-
119
- return { success: writeResult && found, testData };
120
- }
121
-
122
- /**
123
- * Test 2: Verify data persists after relay sync period
124
- */
125
- async function test2_RelayPersistence(hs, testData) {
126
- section('TEST 2: Data Persistence After Relay Sync');
127
-
128
- await wait(WAIT_FOR_SYNC, `Waiting ${WAIT_FOR_SYNC/1000}s for relay synchronization...`);
129
-
130
- log('Re-reading data after sync period...', 'yellow');
131
- const readData = await hs.read(TEST_HOLON, 'data');
132
-
133
- const found = readData && readData.some(d => d.id === testData.id);
134
- addResult('Data persists after relay sync', found,
135
- found ? `Found ${readData.length} record(s)` : 'Data disappeared');
136
-
137
- return { success: found };
138
- }
139
-
140
- /**
141
- * Test 3: Create second node and verify cross-node data visibility
142
- */
143
- async function test3_CrossNodeSync(testData, privateKey) {
144
- section('TEST 3: Cross-Node Data Synchronization');
145
-
146
- log('Creating Node 2 with same private key...', 'yellow');
147
- const hs2 = new HoloSphere({
148
- ...TEST_CONFIG,
149
- privateKey // Same key to see same events
150
- });
151
-
152
- log(`Node 2 Public Key: ${hs2.client.publicKey}`, 'blue');
153
-
154
- await wait(WAIT_FOR_SYNC, `Waiting ${WAIT_FOR_SYNC/1000}s for Node 2 relay connection...`);
155
-
156
- log('Node 2 reading data from relays...', 'yellow');
157
- const readData = await hs2.read(TEST_HOLON, 'data');
158
-
159
- const found = readData && readData.some(d => d.id === testData.id);
160
- addResult('Node 2 can read Node 1 data', found,
161
- found ? `Found ${readData.length} record(s)` : 'Data not visible on Node 2');
162
-
163
- if (found) {
164
- const record = readData.find(d => d.id === testData.id);
165
- const matches = record.message === testData.message;
166
- addResult('Data content matches on Node 2', matches);
167
- }
168
-
169
- return { success: found, hs2 };
170
- }
171
-
172
- /**
173
- * Test 4: Restart Node 1 and verify data recovery from relays
174
- */
175
- async function test4_NodeRestart(testData, privateKey) {
176
- section('TEST 4: Data Recovery After Node Restart');
177
-
178
- log('Simulating Node 1 restart (new instance with same key)...', 'yellow');
179
- const hsRestart = new HoloSphere({
180
- ...TEST_CONFIG,
181
- privateKey // Same key
182
- });
183
-
184
- log(`Restarted Node Public Key: ${hsRestart.client.publicKey}`, 'blue');
185
-
186
- await wait(WAIT_FOR_SYNC, `Waiting ${WAIT_FOR_SYNC/1000}s for relay connection...`);
187
-
188
- log('Restarted node reading from relays...', 'yellow');
189
- const readData = await hsRestart.read(TEST_HOLON, 'data');
190
-
191
- const found = readData && readData.some(d => d.id === testData.id);
192
- addResult('Data recovered after restart', found,
193
- found ? `Found ${readData.length} record(s)` : 'Data not recovered');
194
-
195
- return { success: found, hsRestart };
196
- }
197
-
198
- /**
199
- * Test 5: Update data and verify update persistence
200
- */
201
- async function test5_UpdatePersistence(hs, testData) {
202
- section('TEST 5: Data Update and Update Persistence');
203
-
204
- const updatedData = {
205
- ...testData,
206
- message: 'Updated message - testing permanence',
207
- metadata: {
208
- ...testData.metadata,
209
- updated: true,
210
- updateTimestamp: Date.now()
211
- }
212
- };
213
-
214
- log('Updating data...', 'yellow');
215
- const writeResult = await hs.write(TEST_HOLON, 'data', updatedData);
216
- addResult('Update write successful', writeResult);
217
-
218
- await wait(WAIT_FOR_SYNC, `Waiting ${WAIT_FOR_SYNC/1000}s for update propagation...`);
219
-
220
- log('Reading updated data...', 'yellow');
221
- const readData = await hs.read(TEST_HOLON, 'data');
222
-
223
- const found = readData && readData.find(d => d.id === testData.id);
224
- const updatePersisted = found && found.metadata && found.metadata.updated === true;
225
-
226
- addResult('Update persisted correctly', updatePersisted,
227
- updatePersisted ? `Message: "${found.message}"` : 'Update not found');
228
-
229
- return { success: writeResult && updatePersisted };
230
- }
231
-
232
- /**
233
- * Test 6: Verify update visible on second node
234
- */
235
- async function test6_UpdateCrossNode(hs2, testData) {
236
- section('TEST 6: Update Visibility Across Nodes');
237
-
238
- await wait(WAIT_FOR_SYNC, `Waiting ${WAIT_FOR_SYNC/1000}s for update to sync to Node 2...`);
239
-
240
- log('Node 2 reading updated data...', 'yellow');
241
- const readData = await hs2.read(TEST_HOLON, 'data');
242
-
243
- const found = readData && readData.find(d => d.id === testData.id);
244
- const updateVisible = found && found.metadata && found.metadata.updated === true;
245
-
246
- addResult('Update visible on Node 2', updateVisible,
247
- updateVisible ? `Message: "${found.message}"` : 'Update not visible');
248
-
249
- return { success: updateVisible };
250
- }
251
-
252
- /**
253
- * Test 7: Multiple writes and verify all persist
254
- */
255
- async function test7_BatchPersistence(hs) {
256
- section('TEST 7: Batch Write Persistence');
257
-
258
- const count = 5;
259
- const records = [];
260
-
261
- log(`Writing ${count} records...`, 'yellow');
262
- for (let i = 0; i < count; i++) {
263
- const record = {
264
- id: `batch-${Date.now()}-${i}`,
265
- index: i,
266
- timestamp: Date.now(),
267
- message: `Batch record ${i + 1}/${count}`
268
- };
269
- records.push(record);
270
- const result = await hs.write(TEST_HOLON, 'data', record);
271
- if (result) {
272
- log(` āœ“ Written: ${record.id}`, 'blue');
273
- } else {
274
- log(` āœ— Failed: ${record.id}`, 'red');
275
- }
276
- }
277
-
278
- await wait(WAIT_FOR_SYNC, `Waiting ${WAIT_FOR_SYNC/1000}s for batch sync...`);
279
-
280
- log('Reading all records...', 'yellow');
281
- const readData = await hs.read(TEST_HOLON, 'data');
282
-
283
- const foundCount = records.filter(r =>
284
- readData && readData.some(d => d.id === r.id)
285
- ).length;
286
-
287
- const allFound = foundCount === count;
288
- addResult('All batch records persisted', allFound,
289
- `Found ${foundCount}/${count} records`);
290
-
291
- return { success: allFound, records };
292
- }
293
-
294
- /**
295
- * Main test runner
296
- */
297
- async function runTests() {
298
- log('\n╔═══════════════════════════════════════════════════════════════════╗', 'cyan');
299
- log('ā•‘ HOLOSPHERE DATA PERMANENCE TEST - NOSTR RELAY NETWORK ā•‘', 'cyan');
300
- log('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•', 'cyan');
301
-
302
- log(`\nTest Configuration:`, 'yellow');
303
- log(` App Name: ${TEST_CONFIG.appName}`, 'blue');
304
- log(` Test Holon: ${TEST_HOLON}`, 'blue');
305
- log(` Relays:`, 'blue');
306
- TEST_CONFIG.relays.forEach(relay => log(` • ${relay}`, 'blue'));
307
- log(` Sync Wait Time: ${WAIT_FOR_SYNC / 1000}s`, 'blue');
308
-
309
- try {
310
- // Initialize Node 1
311
- log('\nšŸ“” Initializing Node 1...', 'yellow');
312
- const hs1 = new HoloSphere(TEST_CONFIG);
313
- const privateKey = hs1.client.privateKey;
314
- log(`Node 1 Public Key: ${hs1.client.publicKey}`, 'blue');
315
-
316
- await wait(2000, 'Waiting for initial relay connections...');
317
-
318
- // Run all tests
319
- const { success: t1, testData } = await test1_WriteAndRead(hs1);
320
- if (!t1) {
321
- log('\nāš ļø Initial write failed - cannot continue tests', 'red');
322
- throw new Error('Initial write failed');
323
- }
324
-
325
- const { success: t2 } = await test2_RelayPersistence(hs1, testData);
326
- const { success: t3, hs2 } = await test3_CrossNodeSync(testData, privateKey);
327
- const { success: t4 } = await test4_NodeRestart(testData, privateKey);
328
- const { success: t5 } = await test5_UpdatePersistence(hs1, testData);
329
- const { success: t6 } = await test6_UpdateCrossNode(hs2, testData);
330
- const { success: t7 } = await test7_BatchPersistence(hs1);
331
-
332
- } catch (error) {
333
- log('\nāŒ TEST SUITE FAILED WITH ERROR:', 'red');
334
- console.error(error);
335
- results.failed++;
336
- }
337
-
338
- // Print summary
339
- section('TEST SUMMARY');
340
-
341
- results.tests.forEach(t => {
342
- test(t.name, t.passed, t.details);
343
- });
344
-
345
- console.log('\n' + '─'.repeat(70));
346
- log(`Total Tests: ${results.tests.length}`, 'blue');
347
- log(`Passed: ${results.passed}`, 'green');
348
- log(`Failed: ${results.failed}`, 'red');
349
- const successRate = ((results.passed / results.tests.length) * 100).toFixed(1);
350
- log(`Success Rate: ${successRate}%`, results.failed === 0 ? 'green' : 'yellow');
351
- console.log('─'.repeat(70) + '\n');
352
-
353
- if (results.failed === 0) {
354
- log('šŸŽ‰ ALL TESTS PASSED!', 'green');
355
- log('āœ“ Data writes to relays successfully', 'green');
356
- log('āœ“ Data persists across time', 'green');
357
- log('āœ“ Data syncs across multiple nodes', 'green');
358
- log('āœ“ Data survives node restarts', 'green');
359
- log('āœ“ Updates propagate correctly', 'green');
360
- log('āœ“ Batch operations work reliably', 'green');
361
- log('\n🌐 Your data is PERMANENT on the Nostr relay network!', 'bold');
362
- } else {
363
- log('āš ļø SOME TESTS FAILED', 'yellow');
364
- log('Please review the results above.', 'yellow');
365
- }
366
-
367
- log('\nTest complete.\n');
368
-
369
- setTimeout(() => process.exit(results.failed === 0 ? 0 : 1), 1000);
370
- }
371
-
372
- // Run the test suite
373
- runTests().catch(error => {
374
- console.error('āŒ Fatal error:', error);
375
- process.exit(1);
376
- });
@@ -1,95 +0,0 @@
1
- /**
2
- * Test Second Node - Verify quest synchronization
3
- *
4
- * This script simulates a second node connecting to the same relays
5
- * and verifying it can see quests created by the first node.
6
- */
7
-
8
- import { HoloSphere } from './dist/esm/holosphere.js';
9
-
10
- // Relay configuration - use env vars or these defaults
11
- const RELAYS = process.env.HOLOSPHERE_RELAYS?.split(',') || [
12
- 'wss://relay.holons.io',
13
- 'wss://relay.nostr.band',
14
- ];
15
-
16
- console.log('\n=== Second Node Test ===\n');
17
- console.log('This node will connect to the same relays and fetch quests...\n');
18
-
19
- // Initialize with the SAME configuration as the first node
20
- const hs = new HoloSphere({
21
- appName: 'quest-game', // MUST match the first node's appName
22
- relays: RELAYS,
23
- logLevel: 'INFO'
24
- });
25
-
26
- console.log('Second Node initialized with relays:', hs.config.relays);
27
- console.log('Second Node Public Key:', hs.client.publicKey);
28
- console.log('(Note: Different public key is OK - we can still read public quests)\n');
29
-
30
- // Use the same holon ID as the first node
31
- const QUEST_HOLON = 'global://quests';
32
-
33
- async function testSync() {
34
- // Wait for relay connections to establish
35
- console.log('ā³ Waiting 3 seconds for relay connections...');
36
- await new Promise(resolve => setTimeout(resolve, 3000));
37
-
38
- console.log('\nšŸ“‹ Fetching quests from relays...');
39
-
40
- const quests = await hs.read(QUEST_HOLON, 'quests');
41
-
42
- if (quests && quests.length > 0) {
43
- console.log(`\nāœ… SUCCESS! Found ${quests.length} quest(s) from the first node:\n`);
44
- quests.forEach((quest, index) => {
45
- console.log(`${index + 1}. ${quest.title}`);
46
- console.log(` ID: ${quest.id}`);
47
- console.log(` Status: ${quest.status || 'active'}`);
48
- console.log(` Description: ${quest.description || 'No description'}`);
49
- console.log(` Reward: ${quest.reward || 0} gold`);
50
- console.log('');
51
- });
52
-
53
- console.log('āœ… QUEST SYNCHRONIZATION IS WORKING!');
54
- console.log(' Quests created on Node 1 are visible on Node 2.\n');
55
- } else {
56
- console.log('\nāŒ No quests found.');
57
- console.log(' Possible reasons:');
58
- console.log(' 1. First node hasn\'t created quests yet');
59
- console.log(' 2. Quests haven\'t synced to relays yet (try again in a few seconds)');
60
- console.log(' 3. Different appName between nodes');
61
- console.log(' 4. Relay connectivity issues\n');
62
- }
63
-
64
- // Test creating a quest from this node
65
- console.log('šŸ“ Creating a quest from the second node...\n');
66
-
67
- const newQuest = {
68
- id: `quest-${Date.now()}-from-node2`,
69
- title: 'Explore the Mysterious Cave',
70
- description: 'Discover what lies deep within the cave',
71
- reward: 750,
72
- difficulty: 'medium'
73
- };
74
-
75
- const result = await hs.write(QUEST_HOLON, 'quests', newQuest);
76
-
77
- if (result) {
78
- console.log('āœ… Quest created from Node 2!');
79
- console.log(' The first node should now see 3 quests total.\n');
80
- } else {
81
- console.log('āŒ Failed to create quest from Node 2\n');
82
- }
83
-
84
- // Fetch again to see all quests
85
- await new Promise(resolve => setTimeout(resolve, 2000));
86
- const allQuests = await hs.read(QUEST_HOLON, 'quests');
87
- console.log(`šŸ“‹ Total quests after Node 2 creation: ${allQuests ? allQuests.length : 0}\n`);
88
-
89
- console.log('Test complete! Press Ctrl+C to exit.');
90
- }
91
-
92
- testSync().catch(error => {
93
- console.error('āŒ Test failed:', error);
94
- process.exit(1);
95
- });
@@ -1,89 +0,0 @@
1
- /**
2
- * Simple write test to debug relay issues
3
- */
4
-
5
- import { HoloSphere } from './dist/esm/holosphere.js';
6
-
7
- // Relay configuration - use env vars or these defaults
8
- const RELAYS = process.env.HOLOSPHERE_RELAYS?.split(',') || [
9
- 'wss://relay.holons.io',
10
- 'wss://relay.nostr.band',
11
- ];
12
-
13
- console.log('\n=== SIMPLE WRITE TEST ===\n');
14
-
15
- const hs = new HoloSphere({
16
- appName: 'simple-test',
17
- relays: RELAYS,
18
- logLevel: 'DEBUG'
19
- });
20
-
21
- console.log(`Public Key: ${hs.client.publicKey}`);
22
- console.log(`Relays:`, hs.config.relays);
23
-
24
- // Wait for connections
25
- await new Promise(resolve => setTimeout(resolve, 3000));
26
-
27
- console.log('\n--- Writing data ---\n');
28
-
29
- const testData = {
30
- id: 'test-123',
31
- message: 'Hello, relay!',
32
- timestamp: Date.now()
33
- };
34
-
35
- try {
36
- // Get more details from the write
37
- const storage = await import('./src/storage/nostr-wrapper.js');
38
- const nostrAsync = await import('./src/storage/nostr-async.js');
39
-
40
- const path = storage.buildPath('simple-test', 'global://test', 'data', testData.id);
41
- console.log(`Path: ${path}`);
42
-
43
- // Call nostrPut directly to see the result
44
- const result = await nostrAsync.nostrPut(hs.client, path, testData);
45
-
46
- console.log('\n--- Publish Result ---');
47
- console.log(`Event ID: ${result.event.id}`);
48
- console.log(`Event created_at: ${result.event.created_at}`);
49
- console.log(`Event pubkey: ${result.event.pubkey}`);
50
- console.log(`Event tags:`, JSON.stringify(result.event.tags, null, 2));
51
- console.log(`\nRelay Results:`);
52
-
53
- result.results.forEach((r, i) => {
54
- console.log(`\n Relay ${i + 1}: ${hs.config.relays[i]}`);
55
- console.log(` Status: ${r.status}`);
56
- if (r.status === 'fulfilled') {
57
- console.log(` Value: ${r.value}`);
58
- } else if (r.status === 'rejected') {
59
- console.log(` Reason: ${r.reason}`);
60
- }
61
- });
62
-
63
- const success = result.results.some(r => r.status === 'fulfilled');
64
- console.log(`\n--- Summary ---`);
65
- console.log(`Success: ${success}`);
66
- console.log(`Fulfilled: ${result.results.filter(r => r.status === 'fulfilled').length}/${result.results.length}`);
67
-
68
- // Now try reading it back
69
- console.log('\n--- Reading data back ---\n');
70
- await new Promise(resolve => setTimeout(resolve, 2000));
71
-
72
- const readData = await hs.read('global://test', 'data');
73
- console.log(`Found ${readData ? readData.length : 0} records`);
74
-
75
- if (readData && readData.length > 0) {
76
- readData.forEach((d, i) => {
77
- console.log(`\nRecord ${i + 1}:`);
78
- console.log(JSON.stringify(d, null, 2));
79
- });
80
- }
81
-
82
- } catch (error) {
83
- console.error('\nāŒ Error:', error);
84
- console.error(error.stack);
85
- }
86
-
87
- console.log('\n=== TEST COMPLETE ===\n');
88
-
89
- setTimeout(() => process.exit(0), 1000);