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.
Files changed (147) hide show
  1. package/.env.example +36 -0
  2. package/.eslintrc.json +16 -0
  3. package/.prettierrc.json +7 -0
  4. package/LICENSE +162 -38
  5. package/README.md +483 -367
  6. package/bin/holosphere-activitypub.js +158 -0
  7. package/cleanup-test-data.js +204 -0
  8. package/examples/demo.html +1333 -0
  9. package/examples/example-bot.js +197 -0
  10. package/package.json +47 -87
  11. package/scripts/check-bundle-size.js +54 -0
  12. package/scripts/check-quest-ids.js +77 -0
  13. package/scripts/import-holons.js +578 -0
  14. package/scripts/publish-to-relay.js +101 -0
  15. package/scripts/read-example.js +186 -0
  16. package/scripts/relay-diagnostic.js +59 -0
  17. package/scripts/relay-example.js +179 -0
  18. package/scripts/resync-to-relay.js +245 -0
  19. package/scripts/revert-import.js +196 -0
  20. package/scripts/test-hybrid-mode.js +108 -0
  21. package/scripts/test-local-storage.js +63 -0
  22. package/scripts/test-nostr-direct.js +55 -0
  23. package/scripts/test-read-data.js +45 -0
  24. package/scripts/test-write-read.js +63 -0
  25. package/scripts/verify-import.js +95 -0
  26. package/scripts/verify-relay-data.js +139 -0
  27. package/src/ai/aggregation.js +319 -0
  28. package/src/ai/breakdown.js +511 -0
  29. package/src/ai/classifier.js +217 -0
  30. package/src/ai/council.js +228 -0
  31. package/src/ai/embeddings.js +279 -0
  32. package/src/ai/federation-ai.js +324 -0
  33. package/src/ai/h3-ai.js +955 -0
  34. package/src/ai/index.js +112 -0
  35. package/src/ai/json-ops.js +225 -0
  36. package/src/ai/llm-service.js +205 -0
  37. package/src/ai/nl-query.js +223 -0
  38. package/src/ai/relationships.js +353 -0
  39. package/src/ai/schema-extractor.js +218 -0
  40. package/src/ai/spatial.js +293 -0
  41. package/src/ai/tts.js +194 -0
  42. package/src/content/social-protocols.js +168 -0
  43. package/src/core/holosphere.js +273 -0
  44. package/src/crypto/secp256k1.js +259 -0
  45. package/src/federation/discovery.js +334 -0
  46. package/src/federation/hologram.js +1042 -0
  47. package/src/federation/registry.js +386 -0
  48. package/src/hierarchical/upcast.js +110 -0
  49. package/src/index.js +2669 -0
  50. package/src/schema/validator.js +91 -0
  51. package/src/spatial/h3-operations.js +110 -0
  52. package/src/storage/backend-factory.js +125 -0
  53. package/src/storage/backend-interface.js +142 -0
  54. package/src/storage/backends/activitypub/server.js +653 -0
  55. package/src/storage/backends/activitypub-backend.js +272 -0
  56. package/src/storage/backends/gundb-backend.js +233 -0
  57. package/src/storage/backends/nostr-backend.js +136 -0
  58. package/src/storage/filesystem-storage-browser.js +41 -0
  59. package/src/storage/filesystem-storage.js +138 -0
  60. package/src/storage/global-tables.js +81 -0
  61. package/src/storage/gun-async.js +281 -0
  62. package/src/storage/gun-wrapper.js +221 -0
  63. package/src/storage/indexeddb-storage.js +122 -0
  64. package/src/storage/key-storage-simple.js +76 -0
  65. package/src/storage/key-storage.js +136 -0
  66. package/src/storage/memory-storage.js +59 -0
  67. package/src/storage/migration.js +338 -0
  68. package/src/storage/nostr-async.js +811 -0
  69. package/src/storage/nostr-client.js +939 -0
  70. package/src/storage/nostr-wrapper.js +211 -0
  71. package/src/storage/outbox-queue.js +208 -0
  72. package/src/storage/persistent-storage.js +109 -0
  73. package/src/storage/sync-service.js +164 -0
  74. package/src/subscriptions/manager.js +142 -0
  75. package/test-ai-real-api.js +202 -0
  76. package/tests/unit/ai/aggregation.test.js +295 -0
  77. package/tests/unit/ai/breakdown.test.js +446 -0
  78. package/tests/unit/ai/classifier.test.js +294 -0
  79. package/tests/unit/ai/council.test.js +262 -0
  80. package/tests/unit/ai/embeddings.test.js +384 -0
  81. package/tests/unit/ai/federation-ai.test.js +344 -0
  82. package/tests/unit/ai/h3-ai.test.js +458 -0
  83. package/tests/unit/ai/index.test.js +304 -0
  84. package/tests/unit/ai/json-ops.test.js +307 -0
  85. package/tests/unit/ai/llm-service.test.js +390 -0
  86. package/tests/unit/ai/nl-query.test.js +383 -0
  87. package/tests/unit/ai/relationships.test.js +311 -0
  88. package/tests/unit/ai/schema-extractor.test.js +384 -0
  89. package/tests/unit/ai/spatial.test.js +279 -0
  90. package/tests/unit/ai/tts.test.js +279 -0
  91. package/tests/unit/content.test.js +332 -0
  92. package/tests/unit/contract/core.test.js +88 -0
  93. package/tests/unit/contract/crypto.test.js +198 -0
  94. package/tests/unit/contract/data.test.js +223 -0
  95. package/tests/unit/contract/federation.test.js +181 -0
  96. package/tests/unit/contract/hierarchical.test.js +113 -0
  97. package/tests/unit/contract/schema.test.js +114 -0
  98. package/tests/unit/contract/social.test.js +217 -0
  99. package/tests/unit/contract/spatial.test.js +110 -0
  100. package/tests/unit/contract/subscriptions.test.js +128 -0
  101. package/tests/unit/contract/utils.test.js +159 -0
  102. package/tests/unit/core.test.js +152 -0
  103. package/tests/unit/crypto.test.js +328 -0
  104. package/tests/unit/federation.test.js +234 -0
  105. package/tests/unit/gun-async.test.js +252 -0
  106. package/tests/unit/hierarchical.test.js +399 -0
  107. package/tests/unit/integration/scenario-01-geographic-storage.test.js +74 -0
  108. package/tests/unit/integration/scenario-02-federation.test.js +76 -0
  109. package/tests/unit/integration/scenario-03-subscriptions.test.js +102 -0
  110. package/tests/unit/integration/scenario-04-validation.test.js +129 -0
  111. package/tests/unit/integration/scenario-05-hierarchy.test.js +125 -0
  112. package/tests/unit/integration/scenario-06-social.test.js +135 -0
  113. package/tests/unit/integration/scenario-07-persistence.test.js +130 -0
  114. package/tests/unit/integration/scenario-08-authorization.test.js +161 -0
  115. package/tests/unit/integration/scenario-09-cross-dimensional.test.js +139 -0
  116. package/tests/unit/integration/scenario-10-cross-holosphere-capabilities.test.js +357 -0
  117. package/tests/unit/integration/scenario-11-cross-holosphere-federation.test.js +410 -0
  118. package/tests/unit/integration/scenario-12-capability-federated-read.test.js +719 -0
  119. package/tests/unit/performance/benchmark.test.js +85 -0
  120. package/tests/unit/schema.test.js +213 -0
  121. package/tests/unit/spatial.test.js +158 -0
  122. package/tests/unit/storage.test.js +195 -0
  123. package/tests/unit/subscriptions.test.js +328 -0
  124. package/tests/unit/test-data-permanence-debug.js +197 -0
  125. package/tests/unit/test-data-permanence.js +340 -0
  126. package/tests/unit/test-key-persistence-fixed.js +148 -0
  127. package/tests/unit/test-key-persistence.js +172 -0
  128. package/tests/unit/test-relay-permanence.js +376 -0
  129. package/tests/unit/test-second-node.js +95 -0
  130. package/tests/unit/test-simple-write.js +89 -0
  131. package/vite.config.js +49 -0
  132. package/vitest.config.js +20 -0
  133. package/FEDERATION.md +0 -213
  134. package/compute.js +0 -298
  135. package/content.js +0 -980
  136. package/federation.js +0 -1234
  137. package/global.js +0 -736
  138. package/hexlib.js +0 -335
  139. package/hologram.js +0 -183
  140. package/holosphere-bundle.esm.js +0 -33256
  141. package/holosphere-bundle.js +0 -33287
  142. package/holosphere-bundle.min.js +0 -39
  143. package/holosphere.d.ts +0 -601
  144. package/holosphere.js +0 -719
  145. package/node.js +0 -246
  146. package/schema.js +0 -139
  147. package/utils.js +0 -302
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Revert script to delete incorrectly imported data
5
+ *
6
+ * This script deletes data that was imported with quest IDs as lens names
7
+ * instead of using the subfolder as the holon ID.
8
+ *
9
+ * Usage:
10
+ * node scripts/revert-import.js [options]
11
+ *
12
+ * Options:
13
+ * --dry-run Show what would be deleted without actually deleting
14
+ * --verbose Show detailed progress
15
+ */
16
+
17
+ import { HoloSphere } from '../src/index.js';
18
+ import dotenv from 'dotenv';
19
+
20
+ // Load environment variables
21
+ dotenv.config();
22
+
23
+ // Parse command line arguments
24
+ const args = process.argv.slice(2);
25
+ const options = {
26
+ dryRun: false,
27
+ verbose: true,
28
+ relays: ['wss://relay.holons.io'],
29
+ persistence: true
30
+ };
31
+
32
+ for (let i = 0; i < args.length; i++) {
33
+ switch (args[i]) {
34
+ case '--dry-run':
35
+ options.dryRun = true;
36
+ break;
37
+ case '--verbose':
38
+ options.verbose = true;
39
+ break;
40
+ case '--help':
41
+ console.log(`
42
+ Revert incorrectly imported data from holosphere
43
+
44
+ Usage: node scripts/revert-import.js [options]
45
+
46
+ Options:
47
+ --dry-run Show what would be deleted without actually deleting
48
+ --verbose Show detailed progress
49
+ --help Show this help message
50
+ `);
51
+ process.exit(0);
52
+ }
53
+ }
54
+
55
+ // These are the incorrect apps that were created (should have been lenses)
56
+ const incorrectApps = [
57
+ '3891', 'announcements', 'checklists', 'expenses', 'linked_quests',
58
+ 'profile', 'roles', 'settings', 'users'
59
+ ];
60
+
61
+ // These are the incorrect lenses that were created (should have been IDs)
62
+ const incorrectQuestLenses = [
63
+ '1002', '10026', '1005', '1011', '1017', '10177', '10213', '10231',
64
+ '1024', '1026', '10269', '10273', '1028', '10281', '1029', '10291',
65
+ '10310', '10313', '10316', '1033', '1035', '10362', '10385', '10393',
66
+ '10399', '10412', '10639', '10759', '10838', '11239', '11347', '11354',
67
+ '11361', '11367', '11431', '11435', '11452', '11455', '11468', '11484',
68
+ '11491', '11500', '11516', '11580', '11587', '11596', '11601', '11725',
69
+ '11971', '11974', '11977', '11981', '11984', '11987', '11994', '12283',
70
+ '12291', '12296', '12310', '12315', '12384', '13036', '15637', '15656',
71
+ '15789', '15908', '15913', '15916', '15921', '15981', '16282', '16296',
72
+ '16349', '16352', '16364', '16469', '16540', '16545', '16619', '16650',
73
+ '16653', '16656', '16659', '16662', '16665', '16671', '16690', '167',
74
+ '16712', '16717', '16753', '16758', '16769', '16782', '16793', '16818',
75
+ '16896', '16910', '173442588812194d9kcgiz', '1739201779001ug89uo3fh',
76
+ '1739201790600krobxpk5u', '17392021107016nn2xo6fr', '17392022587064gb5lwy1u',
77
+ '1739202266947zmjy6lmcr', '1739202303652q3csgus2f', '1739203',
78
+ '1739203388980mjeej5d9c', '17392034164678wpynqaxj', '1739203427753zeoqpuqmr',
79
+ '1739203441458vc6p1a5pg', '1747629817053', '1749241269564', '17621',
80
+ '17649', '17653', '17657', '18', '183', '19', '221', '224', '242', '252',
81
+ '274', '327', '358', '364', '367', '369', '380', '382', '383', '415',
82
+ '430', '44', '45', '46', '462', '463', '468', '475', '476', '48', '495',
83
+ '498', '501', '504', '518', '550', '551', '562', '631', '645', '646',
84
+ '661', '680', '685', '706', '749', '752', '786', '789', '795', '801',
85
+ '817', '82', '829', '843', '852'
86
+ ];
87
+
88
+ // Additional lenses under Holons app that need to be cleaned
89
+ const holonsLenses = [
90
+ '1073', '1082', '1110', '1113', '14677', '14680', '1487', '14912',
91
+ '14958', '18610', '19454', '1948', '1750784563464', '1753288184361',
92
+ '1753288962009', '1753346754181', '1753347504071', '1753903926664'
93
+ ];
94
+
95
+ const stats = {
96
+ deleted: 0,
97
+ errors: 0
98
+ };
99
+
100
+ async function main() {
101
+ console.log('Holosphere Revert Tool');
102
+ console.log('======================\n');
103
+ console.log(`Dry run: ${options.dryRun ? 'Yes' : 'No'}`);
104
+ console.log('');
105
+
106
+ // Initialize holosphere
107
+ console.log('Initializing holosphere...');
108
+ const hs = new HoloSphere({
109
+ appName: 'Holons',
110
+ relays: options.relays,
111
+ persistence: options.persistence,
112
+ logLevel: options.verbose ? 'DEBUG' : 'INFO',
113
+ privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
114
+ });
115
+ console.log('Holosphere initialized.\n');
116
+
117
+ console.log('Starting revert...\n');
118
+
119
+ // Delete incorrect app entries
120
+ for (const appName of incorrectApps) {
121
+ try {
122
+ if (options.verbose) {
123
+ console.log(`Deleting app: ${appName} (holon=global)`);
124
+ }
125
+
126
+ if (!options.dryRun) {
127
+ // Note: HoloSphere doesn't have a direct delete API yet
128
+ // We'll need to null out the data instead
129
+ await hs.writeGlobal(appName, null);
130
+ }
131
+ stats.deleted++;
132
+ } catch (error) {
133
+ console.error(`Error deleting app ${appName}:`, error.message);
134
+ stats.errors++;
135
+ }
136
+ }
137
+
138
+ // Delete incorrect quest lenses under 'quests' app
139
+ for (const lensName of incorrectQuestLenses) {
140
+ try {
141
+ if (options.verbose) {
142
+ console.log(`Deleting: app=quests, holon=global, lens=${lensName}`);
143
+ }
144
+
145
+ if (!options.dryRun) {
146
+ // Switch to quests app context
147
+ const questsHs = new HoloSphere({
148
+ appName: 'quests',
149
+ relays: options.relays,
150
+ persistence: options.persistence,
151
+ logLevel: 'ERROR',
152
+ privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
153
+ });
154
+ await questsHs.writeGlobal(lensName, null);
155
+ }
156
+ stats.deleted++;
157
+ } catch (error) {
158
+ console.error(`Error deleting lens ${lensName}:`, error.message);
159
+ stats.errors++;
160
+ }
161
+ }
162
+
163
+ // Delete incorrect quest lenses under 'Holons' app
164
+ for (const lensName of holonsLenses) {
165
+ try {
166
+ if (options.verbose) {
167
+ console.log(`Deleting: app=Holons, holon=global, lens=quests, id=${lensName}`);
168
+ }
169
+
170
+ if (!options.dryRun) {
171
+ await hs.writeGlobal(`quests.${lensName}`, null);
172
+ }
173
+ stats.deleted++;
174
+ } catch (error) {
175
+ console.error(`Error deleting quest ${lensName}:`, error.message);
176
+ stats.errors++;
177
+ }
178
+ }
179
+
180
+ console.log('\n======================');
181
+ console.log('Revert Complete');
182
+ console.log('======================');
183
+ console.log(`Items deleted: ${stats.deleted}`);
184
+ console.log(`Errors: ${stats.errors}`);
185
+
186
+ if (options.dryRun) {
187
+ console.log('\nThis was a dry run. No data was actually deleted.');
188
+ console.log('Run without --dry-run to perform the actual deletion.');
189
+ }
190
+ }
191
+
192
+ // Run main function
193
+ main().catch(error => {
194
+ console.error('Fatal error:', error);
195
+ process.exit(1);
196
+ });
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test hybrid mode (local + relay)
5
+ * Demonstrates that hybrid mode returns data from both sources
6
+ */
7
+
8
+ import { HoloSphere } from '../src/index.js';
9
+ import dotenv from 'dotenv';
10
+
11
+ dotenv.config();
12
+
13
+ async function main() {
14
+ console.log('Testing Hybrid Mode');
15
+ console.log('===================\n');
16
+
17
+ const holonId = process.argv[2] || '235114395';
18
+ const relayUrl = process.env.HOLOSPHERE_RELAY || 'wss://relay.holons.io';
19
+
20
+ // Test 1: Relay-only mode (old behavior)
21
+ console.log('Test 1: Relay-only mode (hybridMode: false)');
22
+ console.log('-'.repeat(60));
23
+
24
+ const hsRelayOnly = new HoloSphere({
25
+ appName: 'Holons',
26
+ relays: [relayUrl],
27
+ persistence: true,
28
+ logLevel: 'ERROR',
29
+ privateKey: process.env.HOLOSPHERE_PRIVATE_KEY,
30
+ hybridMode: false // Disable hybrid mode
31
+ });
32
+
33
+ await new Promise(resolve => setTimeout(resolve, 2000));
34
+
35
+ const relayOnlyQuests = await hsRelayOnly.read(holonId, 'quests');
36
+ const relayOnlyCount = relayOnlyQuests ? relayOnlyQuests.length : 0;
37
+
38
+ console.log(`Quests retrieved: ${relayOnlyCount}`);
39
+ console.log(`Source: Relay only\n`);
40
+
41
+ // Test 2: Hybrid mode (new behavior - default)
42
+ console.log('Test 2: Hybrid mode (hybridMode: true - default)');
43
+ console.log('-'.repeat(60));
44
+
45
+ const hsHybrid = new HoloSphere({
46
+ appName: 'Holons',
47
+ relays: [relayUrl],
48
+ persistence: true,
49
+ logLevel: 'ERROR',
50
+ privateKey: process.env.HOLOSPHERE_PRIVATE_KEY,
51
+ hybridMode: true // Enable hybrid mode (default)
52
+ });
53
+
54
+ await new Promise(resolve => setTimeout(resolve, 2000));
55
+
56
+ const hybridQuests = await hsHybrid.read(holonId, 'quests');
57
+ const hybridCount = hybridQuests ? hybridQuests.length : 0;
58
+
59
+ console.log(`Quests retrieved: ${hybridCount}`);
60
+ console.log(`Source: Local + Relay merged\n`);
61
+
62
+ // Test 3: Local-only mode
63
+ console.log('Test 3: Local-only mode (no relays)');
64
+ console.log('-'.repeat(60));
65
+
66
+ const hsLocal = new HoloSphere({
67
+ appName: 'Holons',
68
+ relays: [],
69
+ persistence: true,
70
+ logLevel: 'ERROR',
71
+ privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
72
+ });
73
+
74
+ await new Promise(resolve => setTimeout(resolve, 2000));
75
+
76
+ const localQuests = await hsLocal.read(holonId, 'quests');
77
+ const localCount = localQuests ? localQuests.length : 0;
78
+
79
+ console.log(`Quests retrieved: ${localCount}`);
80
+ console.log(`Source: Local only\n`);
81
+
82
+ // Summary
83
+ console.log('='.repeat(60));
84
+ console.log('Summary');
85
+ console.log('='.repeat(60));
86
+ console.log(`Relay-only: ${relayOnlyCount} quests`);
87
+ console.log(`Hybrid mode: ${hybridCount} quests ← BEST (merges local + relay)`);
88
+ console.log(`Local-only: ${localCount} quests`);
89
+ console.log('');
90
+
91
+ if (hybridCount >= localCount && hybridCount >= relayOnlyCount) {
92
+ console.log('✓ Hybrid mode returns the most data!');
93
+ console.log(' It merges local storage with relay data\n');
94
+ }
95
+
96
+ console.log('Benefits of Hybrid Mode:');
97
+ console.log(' - Returns data even if relay is down');
98
+ console.log(' - Includes locally-stored data not yet synced to relay');
99
+ console.log(' - Merges both sources for complete data set');
100
+ console.log(' - Prefers newer events when duplicates exist\n');
101
+
102
+ process.exit(0);
103
+ }
104
+
105
+ main().catch(error => {
106
+ console.error('Error:', error);
107
+ process.exit(1);
108
+ });
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test reading from local storage only (no relays)
5
+ */
6
+
7
+ import { HoloSphere } from '../src/index.js';
8
+ import dotenv from 'dotenv';
9
+
10
+ dotenv.config();
11
+
12
+ async function main() {
13
+ console.log('Testing Local Storage (No Relays)');
14
+ console.log('==================================\n');
15
+
16
+ // Initialize WITHOUT relays to force local-only reads
17
+ const hs = new HoloSphere({
18
+ appName: 'Holons',
19
+ relays: [], // Empty - will read from local cache only
20
+ persistence: true,
21
+ logLevel: 'INFO',
22
+ privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
23
+ });
24
+
25
+ const holonId = '235114395';
26
+
27
+ console.log('Waiting for storage to load...\n');
28
+ await new Promise(resolve => setTimeout(resolve, 3000));
29
+
30
+ // Read quests
31
+ console.log('Reading quests from local storage...\n');
32
+ const quests = await hs.read(holonId, 'quests');
33
+
34
+ const questCount = quests ? Object.keys(quests).length : 0;
35
+ console.log(`Found ${questCount} quests in local storage\n`);
36
+
37
+ if (questCount > 0) {
38
+ console.log('Sample quests:');
39
+ const questIds = Object.keys(quests).slice(0, 10);
40
+ for (const id of questIds) {
41
+ const quest = quests[id];
42
+ console.log(` - ${id}: ${quest.title || 'N/A'} (${quest.status || 'N/A'})`);
43
+ }
44
+ }
45
+
46
+ // Test other lenses
47
+ console.log('\nTesting all lenses:\n');
48
+ const lenses = ['3891', 'announcements', 'checklists', 'expenses', 'linked_quests',
49
+ 'profile', 'quests', 'roles', 'settings', 'users'];
50
+
51
+ for (const lens of lenses) {
52
+ const data = await hs.read(holonId, lens);
53
+ const count = data ? Object.keys(data).length : 0;
54
+ console.log(` ${lens.padEnd(20)} ${count} items`);
55
+ }
56
+
57
+ process.exit(0);
58
+ }
59
+
60
+ main().catch(error => {
61
+ console.error('Error:', error);
62
+ process.exit(1);
63
+ });
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test nostr-tools directly
5
+ */
6
+
7
+ import WebSocket from 'ws';
8
+ // Polyfill WebSocket for Node.js
9
+ global.WebSocket = WebSocket;
10
+
11
+ import { SimplePool, finalizeEvent, generateSecretKey, getPublicKey } from 'nostr-tools';
12
+
13
+ async function main() {
14
+ console.log('Testing nostr-tools directly\n');
15
+
16
+ const sk = generateSecretKey();
17
+ const pk = getPublicKey(sk);
18
+
19
+ console.log('Public key:', pk);
20
+
21
+ const pool = new SimplePool();
22
+ const relays = ['wss://relay.holons.io'];
23
+
24
+ const event = {
25
+ kind: 1,
26
+ created_at: Math.floor(Date.now() / 1000),
27
+ tags: [],
28
+ content: 'Hello from HoloSphere test!'
29
+ };
30
+
31
+ const signedEvent = finalizeEvent(event, sk);
32
+ console.log('\nPublishing event...');
33
+ console.log('Event ID:', signedEvent.id);
34
+
35
+ try {
36
+ const results = await Promise.allSettled(pool.publish(relays, signedEvent));
37
+ console.log('\nResults:');
38
+ results.forEach((r, i) => {
39
+ console.log(`Relay ${i}:`, r.status, r.value || r.reason);
40
+ });
41
+ } catch (error) {
42
+ console.error('Error:', error);
43
+ }
44
+
45
+ console.log('\nWaiting 2 seconds...');
46
+ await new Promise(resolve => setTimeout(resolve, 2000));
47
+
48
+ console.log('\nQuerying event...');
49
+ const events = await pool.querySync(relays, { ids: [signedEvent.id] }, { timeout: 3000 });
50
+ console.log('Found events:', events.length);
51
+
52
+ pool.close(relays);
53
+ }
54
+
55
+ main().catch(console.error);
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test script to verify data structure after import
5
+ */
6
+
7
+ import { HoloSphere } from '../src/index.js';
8
+ import dotenv from 'dotenv';
9
+
10
+ // Load environment variables
11
+ dotenv.config();
12
+
13
+ async function main() {
14
+ console.log('Testing data structure...\n');
15
+
16
+ // Initialize holosphere
17
+ const hs = new HoloSphere({
18
+ appName: 'Holons',
19
+ relays: ['wss://relay.holons.io'],
20
+ persistence: true,
21
+ logLevel: 'INFO',
22
+ privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
23
+ });
24
+
25
+ console.log('Reading quests from holon 235114395...\n');
26
+
27
+ // Try to read some quests
28
+ const quests = await hs.read('235114395', 'quests');
29
+
30
+ if (quests && quests.length > 0) {
31
+ console.log(`✓ Found ${quests.length} quests`);
32
+ console.log(`✓ Sample quest IDs: ${quests.slice(0, 5).map(q => q.id).join(', ')}`);
33
+ console.log('\n✓ Data structure is correct!');
34
+ console.log(` - app: Holons`);
35
+ console.log(` - holon: 235114395`);
36
+ console.log(` - lens: quests`);
37
+ } else {
38
+ console.log('✗ No quests found');
39
+ }
40
+ }
41
+
42
+ main().catch(error => {
43
+ console.error('Error:', error);
44
+ process.exit(1);
45
+ });
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Simple test to verify write/read cycle works
5
+ */
6
+
7
+ import { HoloSphere } from '../src/index.js';
8
+ import dotenv from 'dotenv';
9
+
10
+ // Load environment variables
11
+ dotenv.config();
12
+
13
+ async function main() {
14
+ console.log('Testing Write/Read Cycle');
15
+ console.log('========================\n');
16
+
17
+ const hs = new HoloSphere({
18
+ appName: 'test-app',
19
+ relays: ['wss://relay.holons.io', 'wss://relay.nostr.band'],
20
+ persistence: true,
21
+ logLevel: 'DEBUG',
22
+ privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
23
+ });
24
+
25
+ console.log('Writing test data...');
26
+
27
+ // Write a test item
28
+ const testData = {
29
+ id: 'test-123',
30
+ title: 'Test Item',
31
+ value: 42,
32
+ timestamp: Date.now()
33
+ };
34
+
35
+ testData.id = 'test-123';
36
+ await hs.writeGlobal('test-lens', testData);
37
+ console.log('✓ Data written');
38
+
39
+ // Wait a moment for relay propagation
40
+ console.log('\nWaiting 2 seconds for relay propagation...');
41
+ await new Promise(resolve => setTimeout(resolve, 2000));
42
+
43
+ // Try to read it back
44
+ console.log('\nReading data back...');
45
+ const result = await hs.readGlobal('test-lens', 'test-123');
46
+
47
+ if (result) {
48
+ console.log('✓ Data retrieved successfully:');
49
+ console.log(JSON.stringify(result, null, 2));
50
+ } else {
51
+ console.log('✗ No data found');
52
+ }
53
+
54
+ // Try reading all from the lens
55
+ console.log('\nReading all from test-lens...');
56
+ const allData = await hs.readGlobal('test-lens');
57
+ console.log('Result:', allData);
58
+
59
+ // Show metrics
60
+ console.log('\nMetrics:', hs.metrics());
61
+ }
62
+
63
+ main().catch(console.error);
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Verify imported data can be retrieved
5
+ */
6
+
7
+ import { HoloSphere } from '../src/index.js';
8
+ import dotenv from 'dotenv';
9
+
10
+ dotenv.config();
11
+
12
+ async function main() {
13
+ console.log('Verifying Import Data');
14
+ console.log('=====================\n');
15
+
16
+ const hs = new HoloSphere({
17
+ appName: 'Holons',
18
+ relays: ['wss://relay.holons.io'],
19
+ persistence: true,
20
+ logLevel: 'INFO',
21
+ privateKey: process.env.HOLOSPHERE_PRIVATE_KEY
22
+ });
23
+
24
+ const holonId = '235114395';
25
+ const lenses = ['3891', 'announcements', 'checklists', 'expenses', 'linked_quests',
26
+ 'profile', 'quests', 'roles', 'settings', 'users'];
27
+
28
+ console.log('Waiting for storage to initialize...\n');
29
+ await new Promise(resolve => setTimeout(resolve, 2000));
30
+
31
+ // Test each lens
32
+ console.log('Testing data retrieval by lens:\n');
33
+ const results = {};
34
+
35
+ for (const lens of lenses) {
36
+ try {
37
+ const data = await hs.read(holonId, lens);
38
+ const count = data ? Object.keys(data).length : 0;
39
+ results[lens] = count;
40
+ console.log(`✓ ${lens.padEnd(20)} ${count} items`);
41
+ } catch (error) {
42
+ console.log(`✗ ${lens.padEnd(20)} Error: ${error.message}`);
43
+ results[lens] = 0;
44
+ }
45
+ }
46
+
47
+ console.log('\n' + '='.repeat(50));
48
+ const totalItems = Object.values(results).reduce((sum, count) => sum + count, 0);
49
+ console.log(`Total items retrieved: ${totalItems}`);
50
+ console.log('='.repeat(50) + '\n');
51
+
52
+ // Test specific quest retrieval
53
+ console.log('Testing specific quest retrieval:\n');
54
+
55
+ const testQuests = ['1002', '10026', '1073', 'nonexistent-quest'];
56
+
57
+ for (const questId of testQuests) {
58
+ try {
59
+ const allQuests = await hs.read(holonId, 'quests');
60
+ const quest = allQuests ? allQuests[questId] : null;
61
+
62
+ if (quest) {
63
+ console.log(`✓ Quest ${questId}: Found`);
64
+ console.log(` Title: ${quest.title || 'N/A'}`);
65
+ console.log(` Status: ${quest.status || 'N/A'}`);
66
+ } else {
67
+ console.log(`✗ Quest ${questId}: Not found`);
68
+ console.log(` Returns: ${quest === null ? 'null' : typeof quest}`);
69
+ }
70
+ } catch (error) {
71
+ console.log(`✗ Quest ${questId}: Error - ${error.message}`);
72
+ }
73
+ console.log('');
74
+ }
75
+
76
+ // Test what happens when reading non-existent lens
77
+ console.log('Testing non-existent lens:\n');
78
+ try {
79
+ const data = await hs.read(holonId, 'nonexistent-lens');
80
+ console.log(`Result: ${data === null ? 'null' : typeof data}`);
81
+ console.log(`Value: ${JSON.stringify(data)}`);
82
+ } catch (error) {
83
+ console.log(`Error: ${error.message}`);
84
+ }
85
+
86
+ console.log('\n✓ Verification complete\n');
87
+
88
+ // Force exit since Nostr connections stay open
89
+ process.exit(0);
90
+ }
91
+
92
+ main().catch(error => {
93
+ console.error('Error:', error);
94
+ process.exit(1);
95
+ });