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
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * HoloSphere ActivityPub Server CLI
5
+ *
6
+ * Starts a self-hosted ActivityPub server for HoloSphere federation.
7
+ *
8
+ * Usage:
9
+ * holosphere-activitypub [options]
10
+ *
11
+ * Options:
12
+ * -p, --port <port> Port to listen on (default: 3000)
13
+ * -d, --domain <domain> Domain name for federation (default: localhost)
14
+ * --data-dir <dir> Data directory for storage
15
+ * --protocol <protocol> Protocol: http or https (default: http)
16
+ * -h, --help Show this help message
17
+ *
18
+ * Environment Variables:
19
+ * HOLOSPHERE_AP_PORT Port to listen on
20
+ * HOLOSPHERE_AP_DOMAIN Domain name
21
+ * HOLOSPHERE_AP_DATADIR Data directory
22
+ * HOLOSPHERE_AP_PROTOCOL Protocol (http/https)
23
+ */
24
+
25
+ import { ActivityPubServer } from '../src/storage/backends/activitypub/server.js';
26
+
27
+ function parseArgs(args) {
28
+ const config = {
29
+ port: parseInt(process.env.HOLOSPHERE_AP_PORT) || 3000,
30
+ domain: process.env.HOLOSPHERE_AP_DOMAIN || 'localhost',
31
+ dataDir: process.env.HOLOSPHERE_AP_DATADIR,
32
+ protocol: process.env.HOLOSPHERE_AP_PROTOCOL || 'http',
33
+ };
34
+
35
+ for (let i = 0; i < args.length; i++) {
36
+ const arg = args[i];
37
+ const next = args[i + 1];
38
+
39
+ switch (arg) {
40
+ case '-p':
41
+ case '--port':
42
+ config.port = parseInt(next);
43
+ i++;
44
+ break;
45
+ case '-d':
46
+ case '--domain':
47
+ config.domain = next;
48
+ i++;
49
+ break;
50
+ case '--data-dir':
51
+ config.dataDir = next;
52
+ i++;
53
+ break;
54
+ case '--protocol':
55
+ config.protocol = next;
56
+ i++;
57
+ break;
58
+ case '-h':
59
+ case '--help':
60
+ showHelp();
61
+ process.exit(0);
62
+ default:
63
+ if (arg.startsWith('-')) {
64
+ console.error(`Unknown option: ${arg}`);
65
+ showHelp();
66
+ process.exit(1);
67
+ }
68
+ }
69
+ }
70
+
71
+ return config;
72
+ }
73
+
74
+ function showHelp() {
75
+ console.log(`
76
+ HoloSphere ActivityPub Server
77
+
78
+ Starts a self-hosted ActivityPub server for HoloSphere federation.
79
+ This server can federate with Mastodon, Pleroma, and other ActivityPub servers.
80
+
81
+ Usage:
82
+ holosphere-activitypub [options]
83
+
84
+ Options:
85
+ -p, --port <port> Port to listen on (default: 3000)
86
+ -d, --domain <domain> Domain name for federation (default: localhost)
87
+ --data-dir <dir> Data directory for persistent storage
88
+ --protocol <protocol> Protocol: http or https (default: http)
89
+ -h, --help Show this help message
90
+
91
+ Environment Variables:
92
+ HOLOSPHERE_AP_PORT Port to listen on
93
+ HOLOSPHERE_AP_DOMAIN Domain name
94
+ HOLOSPHERE_AP_DATADIR Data directory
95
+ HOLOSPHERE_AP_PROTOCOL Protocol (http/https)
96
+
97
+ Examples:
98
+ # Start server on default port
99
+ holosphere-activitypub
100
+
101
+ # Start server on port 8080 with custom domain
102
+ holosphere-activitypub -p 8080 -d myholosphere.example.com
103
+
104
+ # Start with persistent data directory
105
+ holosphere-activitypub --data-dir ./data --domain myserver.local
106
+
107
+ Federation Notes:
108
+ For federation with other ActivityPub servers (Mastodon, etc.):
109
+ 1. Your server must be accessible via the domain you specify
110
+ 2. HTTPS is recommended for production federation
111
+ 3. Set up proper DNS records pointing to your server
112
+ 4. WebFinger discovery is available at /.well-known/webfinger
113
+ `);
114
+ }
115
+
116
+ async function main() {
117
+ const args = process.argv.slice(2);
118
+ const config = parseArgs(args);
119
+
120
+ console.log('\n========================================');
121
+ console.log(' HoloSphere ActivityPub Server');
122
+ console.log('========================================');
123
+ console.log(` Port: ${config.port}`);
124
+ console.log(` Domain: ${config.domain}`);
125
+ console.log(` Protocol: ${config.protocol}`);
126
+ console.log(` Data Dir: ${config.dataDir || '(default)'}`);
127
+ console.log('========================================\n');
128
+
129
+ const server = new ActivityPubServer(config);
130
+
131
+ // Handle shutdown gracefully
132
+ process.on('SIGINT', () => {
133
+ console.log('\nShutting down...');
134
+ server.stop();
135
+ process.exit(0);
136
+ });
137
+
138
+ process.on('SIGTERM', () => {
139
+ console.log('\nShutting down...');
140
+ server.stop();
141
+ process.exit(0);
142
+ });
143
+
144
+ try {
145
+ await server.start();
146
+ console.log('\nServer endpoints:');
147
+ console.log(` WebFinger: ${config.protocol}://${config.domain}:${config.port}/.well-known/webfinger`);
148
+ console.log(` Actors: ${config.protocol}://${config.domain}:${config.port}/actor/{name}`);
149
+ console.log(` API: ${config.protocol}://${config.domain}:${config.port}/api/data`);
150
+ console.log(` Health: ${config.protocol}://${config.domain}:${config.port}/health`);
151
+ console.log('\nPress Ctrl+C to stop the server\n');
152
+ } catch (error) {
153
+ console.error('Failed to start server:', error);
154
+ process.exit(1);
155
+ }
156
+ }
157
+
158
+ main();
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Cleanup Test Data from Relays
3
+ *
4
+ * This script finds and deletes test data published to relays
5
+ * It uses tombstone deletion (Nostr standard) to mark events as deleted
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
+ const c = {
17
+ reset: '\x1b[0m',
18
+ green: '\x1b[32m',
19
+ red: '\x1b[31m',
20
+ yellow: '\x1b[33m',
21
+ blue: '\x1b[34m',
22
+ cyan: '\x1b[36m'
23
+ };
24
+
25
+ function log(msg, color = 'reset') {
26
+ console.log(`${c[color]}${msg}${c.reset}`);
27
+ }
28
+
29
+ console.log('\n╔═══════════════════════════════════════════════════════════════════╗');
30
+ log('║ HOLOSPHERE TEST DATA CLEANUP UTILITY ║', 'cyan');
31
+ console.log('╚═══════════════════════════════════════════════════════════════════╝\n');
32
+
33
+ // Test app names to clean up
34
+ const TEST_APPS = [
35
+ 'permanence-test',
36
+ 'debug-test',
37
+ 'simple-test',
38
+ 'relay-permanence-test',
39
+ 'HolonsDebug'
40
+ ];
41
+
42
+ log('This script will delete test data from the following apps:', 'yellow');
43
+ TEST_APPS.forEach(app => log(` • ${app}`, 'blue'));
44
+
45
+ log('\n⚠️ Note: Deletion in Nostr is done by publishing tombstone events.', 'yellow');
46
+ log(' Old events may still exist on relays but will be marked as deleted.\n', 'yellow');
47
+
48
+ // Function to clean up a specific app
49
+ async function cleanupApp(appName) {
50
+ log(`\n${'─'.repeat(70)}`, 'cyan');
51
+ log(`Cleaning up: ${appName}`, 'cyan');
52
+ log('─'.repeat(70), 'cyan');
53
+
54
+ try {
55
+ const hs = new HoloSphere({
56
+ appName: appName,
57
+ relays: RELAYS,
58
+ logLevel: 'WARN'
59
+ });
60
+
61
+ log(`Public Key: ${hs.client.publicKey}`, 'blue');
62
+
63
+ // Wait for connections
64
+ await new Promise(resolve => setTimeout(resolve, 2000));
65
+
66
+ // Query all events for this app
67
+ log('\nQuerying events...', 'yellow');
68
+
69
+ const filter = {
70
+ kinds: [30000],
71
+ authors: [hs.client.publicKey],
72
+ limit: 1000
73
+ };
74
+
75
+ const events = await hs.client.query(filter, { timeout: 5000 });
76
+
77
+ // Filter to only this app's events
78
+ const appEvents = events.filter(event => {
79
+ const dTag = event.tags.find(t => t[0] === 'd');
80
+ return dTag && dTag[1] && dTag[1].startsWith(appName + '/');
81
+ });
82
+
83
+ log(`Found ${appEvents.length} events for ${appName}`, 'blue');
84
+
85
+ if (appEvents.length === 0) {
86
+ log('No events to clean up', 'green');
87
+ return { deleted: 0, failed: 0 };
88
+ }
89
+
90
+ // Show sample of events
91
+ log('\nSample events:', 'yellow');
92
+ appEvents.slice(0, 5).forEach((event, i) => {
93
+ const dTag = event.tags.find(t => t[0] === 'd');
94
+ log(` ${i + 1}. ${dTag[1]}`, 'blue');
95
+ });
96
+ if (appEvents.length > 5) {
97
+ log(` ... and ${appEvents.length - 5} more`, 'blue');
98
+ }
99
+
100
+ log('\nDeleting events...', 'yellow');
101
+
102
+ let deleted = 0;
103
+ let failed = 0;
104
+
105
+ // Import storage utilities
106
+ const { nostrPut } = await import('./src/storage/nostr-async.js');
107
+
108
+ for (const event of appEvents) {
109
+ const dTag = event.tags.find(t => t[0] === 'd');
110
+ if (!dTag) continue;
111
+
112
+ const path = dTag[1];
113
+
114
+ try {
115
+ // Create tombstone
116
+ const tombstone = {
117
+ _deleted: true,
118
+ _deletedAt: Date.now(),
119
+ _cleanedUp: true
120
+ };
121
+
122
+ const result = await nostrPut(hs.client, path, tombstone);
123
+ const success = result.results.some(r => r.status === 'fulfilled');
124
+
125
+ if (success) {
126
+ deleted++;
127
+ log(` ✓ Deleted: ${path}`, 'green');
128
+ } else {
129
+ failed++;
130
+ log(` ✗ Failed: ${path}`, 'red');
131
+ }
132
+ } catch (error) {
133
+ failed++;
134
+ log(` ✗ Error deleting ${path}: ${error.message}`, 'red');
135
+ }
136
+
137
+ // Rate limit to avoid overwhelming relays
138
+ await new Promise(resolve => setTimeout(resolve, 100));
139
+ }
140
+
141
+ log(`\n✓ Cleanup complete for ${appName}`, 'green');
142
+ log(` Deleted: ${deleted}`, 'green');
143
+ log(` Failed: ${failed}`, failed > 0 ? 'red' : 'green');
144
+
145
+ return { deleted, failed };
146
+
147
+ } catch (error) {
148
+ log(`\n✗ Error cleaning up ${appName}: ${error.message}`, 'red');
149
+ return { deleted: 0, failed: 1 };
150
+ }
151
+ }
152
+
153
+ // Main cleanup function
154
+ async function cleanup() {
155
+ const results = {
156
+ totalDeleted: 0,
157
+ totalFailed: 0,
158
+ apps: []
159
+ };
160
+
161
+ for (const app of TEST_APPS) {
162
+ const result = await cleanupApp(app);
163
+ results.totalDeleted += result.deleted;
164
+ results.totalFailed += result.failed;
165
+ results.apps.push({ app, ...result });
166
+ }
167
+
168
+ // Summary
169
+ log('\n' + '═'.repeat(70), 'cyan');
170
+ log(' CLEANUP SUMMARY', 'cyan');
171
+ log('═'.repeat(70), 'cyan');
172
+
173
+ results.apps.forEach(({ app, deleted, failed }) => {
174
+ if (deleted > 0 || failed > 0) {
175
+ log(`\n${app}:`, 'blue');
176
+ log(` Deleted: ${deleted}`, 'green');
177
+ if (failed > 0) log(` Failed: ${failed}`, 'red');
178
+ }
179
+ });
180
+
181
+ log(`\nTotal Deleted: ${results.totalDeleted}`, 'green');
182
+ if (results.totalFailed > 0) {
183
+ log(`Total Failed: ${results.totalFailed}`, 'red');
184
+ }
185
+
186
+ if (results.totalDeleted === 0) {
187
+ log('\n✓ No test data found to clean up', 'green');
188
+ } else {
189
+ log('\n✓ Test data cleanup complete!', 'green');
190
+ }
191
+
192
+ log('\n');
193
+ }
194
+
195
+ // Run cleanup
196
+ cleanup()
197
+ .then(() => {
198
+ setTimeout(() => process.exit(0), 1000);
199
+ })
200
+ .catch(error => {
201
+ log(`\n✗ Fatal error: ${error.message}`, 'red');
202
+ console.error(error);
203
+ process.exit(1);
204
+ });