holosphere 2.0.0-alpha21 → 2.0.0-alpha23

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 (69) hide show
  1. package/README.md +1 -2
  2. package/dist/cjs/holosphere.cjs +1 -1
  3. package/dist/esm/holosphere.js +61 -58
  4. package/dist/{index-B6-8KAQm.js → index-BEkCLOwI.js} +2 -2
  5. package/dist/{index-B6-8KAQm.js.map → index-BEkCLOwI.js.map} +1 -1
  6. package/dist/{index-D2WstuZJ.js → index-BEvX6DxG.js} +2 -2
  7. package/dist/{index-D2WstuZJ.js.map → index-BEvX6DxG.js.map} +1 -1
  8. package/dist/{index--QsHG_gD.cjs → index-BGTOiJ2Y.cjs} +2 -2
  9. package/dist/{index--QsHG_gD.cjs.map → index-BGTOiJ2Y.cjs.map} +1 -1
  10. package/dist/{index-COpLk9gL.cjs → index-BH1woZXL.cjs} +2 -2
  11. package/dist/{index-COpLk9gL.cjs.map → index-BH1woZXL.cjs.map} +1 -1
  12. package/dist/{index-BHptWysv.js → index-Cvxov2jv.js} +2970 -7753
  13. package/dist/index-Cvxov2jv.js.map +1 -0
  14. package/dist/index-vTKI_BAX.cjs +29 -0
  15. package/dist/index-vTKI_BAX.cjs.map +1 -0
  16. package/dist/{indexeddb-storage-wKG4mICM.cjs → indexeddb-storage-BmnCNnSg.cjs} +2 -2
  17. package/dist/{indexeddb-storage-wKG4mICM.cjs.map → indexeddb-storage-BmnCNnSg.cjs.map} +1 -1
  18. package/dist/{indexeddb-storage-kQ53UHEE.js → indexeddb-storage-MIFisaPy.js} +2 -2
  19. package/dist/{indexeddb-storage-kQ53UHEE.js.map → indexeddb-storage-MIFisaPy.js.map} +1 -1
  20. package/dist/{memory-storage-CGC8xM2G.cjs → memory-storage-BJjK3F4r.cjs} +2 -2
  21. package/dist/{memory-storage-CGC8xM2G.cjs.map → memory-storage-BJjK3F4r.cjs.map} +1 -1
  22. package/dist/{memory-storage-DnXCSbBl.js → memory-storage-DhHXdKQ-.js} +2 -2
  23. package/dist/{memory-storage-DnXCSbBl.js.map → memory-storage-DhHXdKQ-.js.map} +1 -1
  24. package/examples/demo.html +2 -29
  25. package/package.json +3 -8
  26. package/src/content/social-protocols.js +3 -59
  27. package/src/core/holosphere.js +16 -554
  28. package/src/crypto/nostr-utils.js +98 -1
  29. package/src/crypto/secp256k1.js +4 -393
  30. package/src/federation/discovery.js +7 -75
  31. package/src/federation/handshake.js +69 -202
  32. package/src/federation/hologram.js +222 -298
  33. package/src/federation/index.js +2 -9
  34. package/src/federation/registry.js +67 -1257
  35. package/src/federation/request-card.js +21 -35
  36. package/src/hierarchical/upcast.js +4 -9
  37. package/src/index.js +145 -296
  38. package/src/lib/federation-methods.js +370 -909
  39. package/src/storage/global-tables.js +1 -1
  40. package/src/storage/nostr-wrapper.js +9 -5
  41. package/src/subscriptions/manager.js +1 -1
  42. package/types/index.d.ts +145 -37
  43. package/bin/holosphere-activitypub.js +0 -158
  44. package/dist/2019-BzVkRcax.js +0 -6680
  45. package/dist/2019-BzVkRcax.js.map +0 -1
  46. package/dist/2019-C1hPR_Os.cjs +0 -8
  47. package/dist/2019-C1hPR_Os.cjs.map +0 -1
  48. package/dist/browser-BcmACE3G.js +0 -3058
  49. package/dist/browser-BcmACE3G.js.map +0 -1
  50. package/dist/browser-DaqYUTcG.cjs +0 -2
  51. package/dist/browser-DaqYUTcG.cjs.map +0 -1
  52. package/dist/index-BHptWysv.js.map +0 -1
  53. package/dist/index-CDlhzxT2.cjs +0 -29
  54. package/dist/index-CDlhzxT2.cjs.map +0 -1
  55. package/src/federation/capabilities.js +0 -46
  56. package/src/storage/backend-factory.js +0 -130
  57. package/src/storage/backend-interface.js +0 -161
  58. package/src/storage/backends/activitypub/server.js +0 -675
  59. package/src/storage/backends/activitypub-backend.js +0 -295
  60. package/src/storage/backends/gundb-backend.js +0 -875
  61. package/src/storage/backends/nostr-backend.js +0 -251
  62. package/src/storage/gun-async.js +0 -341
  63. package/src/storage/gun-auth.js +0 -373
  64. package/src/storage/gun-federation.js +0 -785
  65. package/src/storage/gun-references.js +0 -209
  66. package/src/storage/gun-schema.js +0 -306
  67. package/src/storage/gun-wrapper.js +0 -642
  68. package/src/storage/migration.js +0 -351
  69. package/src/storage/unified-storage.js +0 -161
@@ -2,44 +2,15 @@
2
2
  * @fileoverview Core HoloSphere class providing the foundational infrastructure
3
3
  * for holonic geospatial communication.
4
4
  *
5
- * This module implements the core HoloSphere class that supports multiple storage
6
- * backends (Nostr, GunDB, ActivityPub) and provides essential operations for
7
- * distributed P2P communication and data management.
5
+ * This module implements the core HoloSphere class using the Nostr protocol
6
+ * for distributed P2P communication and data management.
8
7
  *
9
8
  * @module core/holosphere
10
9
  */
11
10
 
12
11
  import { createClient } from '../storage/nostr-client.js';
13
- import { BackendFactory } from '../storage/backend-factory.js';
14
- import * as gunWrapper from '../storage/gun-wrapper.js';
15
- import * as gunFederation from '../storage/gun-federation.js';
16
- import { GunDBBackend } from '../storage/backends/gundb-backend.js';
17
12
  import pkg from '../../package.json' with { type: 'json' };
18
13
 
19
- /** @type {Function|null} Gun constructor, loaded dynamically */
20
- let Gun = null;
21
- /** @type {Promise<Function>|null} Promise for Gun loading */
22
- let gunLoadPromise = null;
23
-
24
- /**
25
- * Dynamically loads the Gun module.
26
- * Uses lazy loading to reduce initial bundle size and improve startup time.
27
- *
28
- * @private
29
- * @returns {Promise<Function>} Gun constructor
30
- */
31
- async function loadGun() {
32
- if (Gun) return Gun;
33
- if (gunLoadPromise) return gunLoadPromise;
34
-
35
- gunLoadPromise = import('gun').then(module => {
36
- Gun = module.default || module;
37
- return Gun;
38
- });
39
-
40
- return gunLoadPromise;
41
- }
42
-
43
14
  /**
44
15
  * Get environment variable (works in Node.js, returns undefined in browser)
45
16
  * @param {string} name - Environment variable name
@@ -67,30 +38,20 @@ function getDefaultRelays() {
67
38
  /**
68
39
  * HoloSphere - Holonic Geospatial Communication Infrastructure.
69
40
  *
70
- * The core class that combines H3 hexagonal indexing with distributed P2P storage.
71
- * Supports multiple storage backends including Nostr, GunDB, and ActivityPub.
41
+ * The core class that combines H3 hexagonal indexing with Nostr distributed P2P storage.
72
42
  *
73
43
  * @class HoloSphere
74
44
  * @example
75
- * // Create with Nostr backend (default)
76
45
  * const hs = new HoloSphere({ appName: 'myapp', relays: ['wss://relay.example.com'] });
77
- *
78
- * @example
79
- * // Create with GunDB backend
80
- * const hs = new HoloSphere({ appName: 'myapp', backend: 'gundb' });
81
- * await hs.ready(); // Wait for async initialization
82
46
  */
83
47
  export class HoloSphere {
84
48
  /**
85
49
  * @param {Object} config - Configuration options
86
50
  * @param {string} config.appName - Application namespace (default: 'holosphere')
87
- * @param {string} config.backend - Storage backend: 'nostr' | 'gundb' | 'activitypub' (default: 'nostr')
88
- * @param {string[]} config.relays - Nostr relay URLs (default from HOLOSPHERE_RELAYS env or ['wss://relay.holons.io', 'wss://relay.nostr.band'])
51
+ * @param {string[]} config.relays - Nostr relay URLs (default from HOLOSPHERE_RELAYS env or ['wss://relay.holons.io'])
89
52
  * @param {string} config.privateKey - Private key for signing (hex format, optional)
90
53
  * @param {string} config.logLevel - Log verbosity: ERROR|WARN|INFO|DEBUG (default: 'INFO')
91
54
  * @param {boolean} config.hybridMode - Enable hybrid mode (local + relay queries) (default: true)
92
- * @param {Object} config.gundb - GunDB-specific configuration
93
- * @param {Object} config.activitypub - ActivityPub-specific configuration
94
55
  */
95
56
  constructor(config = {}) {
96
57
  // Allow string as shorthand for appName (backward compatibility)
@@ -113,14 +74,10 @@ export class HoloSphere {
113
74
  if (config.logLevel !== undefined && !['ERROR', 'WARN', 'INFO', 'DEBUG'].includes(config.logLevel)) {
114
75
  throw new TypeError('config.logLevel must be one of: ERROR, WARN, INFO, DEBUG');
115
76
  }
116
- if (config.backend !== undefined && !BackendFactory.isAvailable(config.backend)) {
117
- throw new TypeError(`config.backend must be one of: ${BackendFactory.getAvailableBackends().join(', ')}`);
118
- }
119
77
 
120
78
  // Set defaults (with environment variable fallbacks)
121
79
  this.config = {
122
80
  appName: config.appName || getEnv('HOLOSPHERE_APP_NAME') || 'holosphere',
123
- backend: config.backend || 'nostr',
124
81
  relays: config.relays || getDefaultRelays(),
125
82
  privateKey: config.privateKey || getEnv('HOLOSPHERE_PRIVATE_KEY'),
126
83
  logLevel: config.logLevel || getEnv('HOLOSPHERE_LOG_LEVEL') || 'INFO',
@@ -134,20 +91,8 @@ export class HoloSphere {
134
91
  this.logLevels = { ERROR: 0, WARN: 1, INFO: 2, DEBUG: 3 };
135
92
  this.currentLogLevel = this.logLevels[this.config.logLevel] || 1;
136
93
 
137
- // Backend instance (set during initialization)
138
- this._backend = null;
139
-
140
- // For backward compatibility with Nostr, initialize synchronously
141
- // GunDB and other backends use async initialization via _backendReady
142
- if (this.config.backend === 'nostr') {
143
- this._initNostrSync(config);
144
- } else if (this.config.backend === 'gundb') {
145
- // GunDB uses async init due to dynamic import
146
- this._backendReady = this._initGunDBAsync(config);
147
- } else {
148
- // Async initialization for other backends
149
- this._backendReady = this._initBackendAsync(config);
150
- }
94
+ // Initialize Nostr client
95
+ this._initNostrSync(config);
151
96
 
152
97
  // Metrics tracking
153
98
  this._metrics = {
@@ -158,7 +103,7 @@ export class HoloSphere {
158
103
  }
159
104
 
160
105
  /**
161
- * Initialize Nostr backend synchronously (for backward compatibility)
106
+ * Initialize Nostr backend synchronously
162
107
  * @private
163
108
  */
164
109
  _initNostrSync(config) {
@@ -178,7 +123,6 @@ export class HoloSphere {
178
123
  this._logStartup({
179
124
  version: pkg.version,
180
125
  appName: this.config.appName,
181
- backend: 'nostr',
182
126
  relays: this.config.relays,
183
127
  publicKey: this.client.publicKey,
184
128
  logLevel: this.config.logLevel,
@@ -195,107 +139,6 @@ export class HoloSphere {
195
139
  }
196
140
  }
197
141
 
198
- /**
199
- * Initialize GunDB backend asynchronously (for browser compatibility with dynamic import)
200
- * @private
201
- */
202
- async _initGunDBAsync(config) {
203
- try {
204
- const gundbConfig = config.gundb || {};
205
-
206
- // Create the full-featured GunDB backend
207
- this._backend = new GunDBBackend({
208
- appName: this.config.appName,
209
- peers: gundbConfig.peers || [],
210
- radisk: gundbConfig.radisk !== false,
211
- localStorage: gundbConfig.localStorage !== false,
212
- dataDir: config.dataDir,
213
- privateKey: this.config.privateKey,
214
- strict: gundbConfig.strict || false,
215
- schemaCacheMaxAge: gundbConfig.schemaCacheMaxAge || 3600000,
216
- });
217
-
218
- // Initialize the backend
219
- await this._backend.init();
220
-
221
- // Set public key from backend
222
- this.publicKey = this._backend.publicKey;
223
-
224
- // Store Gun instance for direct access
225
- this._gun = this._backend.gun;
226
-
227
- // Create a client-like interface for compatibility
228
- this.client = {
229
- publicKey: this.publicKey,
230
- gun: this._gun,
231
- write: (path, data) => this._backend.write(path, data),
232
- read: (path, options) => this._backend.read(path, options),
233
- readAll: (path, options) => this._backend.readAll(path, options),
234
- update: (path, updates) => this._backend.update(path, updates),
235
- delete: (path) => this._backend.delete(path),
236
- subscribe: (path, callback, options) => this._backend.subscribe(path, callback, options),
237
- buildPath: gunWrapper.buildPath,
238
- };
239
-
240
- // Store Gun wrapper functions for direct access
241
- this._gunWrapper = gunWrapper;
242
-
243
- // Log startup information
244
- this._logStartup({
245
- version: pkg.version,
246
- appName: this.config.appName,
247
- backend: 'gundb',
248
- peers: gundbConfig.peers || [],
249
- publicKey: this.publicKey,
250
- logLevel: this.config.logLevel,
251
- persistence: gundbConfig.radisk !== false,
252
- dataDir: config.dataDir,
253
- });
254
- } catch (error) {
255
- this._log('ERROR', 'GunDB client initialization failed', { error: error.message });
256
- throw new Error(`GunDB client initialization failed: ${error.message}`);
257
- }
258
- }
259
-
260
- /**
261
- * Initialize non-Nostr backends asynchronously
262
- * @private
263
- */
264
- async _initBackendAsync(config) {
265
- const backendType = this.config.backend;
266
- const backendSpecificConfig = config[backendType] || {};
267
-
268
- try {
269
- // Merge common config with backend-specific config
270
- const backendConfig = {
271
- appName: this.config.appName,
272
- privateKey: this.config.privateKey,
273
- persistence: config.persistence !== false,
274
- dataDir: config.dataDir,
275
- ...backendSpecificConfig,
276
- };
277
-
278
- this._backend = await BackendFactory.create(backendType, backendConfig);
279
-
280
- // For compatibility, also set client if backend has one
281
- this.client = this._backend.client || this._backend;
282
-
283
- // Log startup information
284
- this._logStartup({
285
- version: pkg.version,
286
- appName: this.config.appName,
287
- backend: backendType,
288
- publicKey: this._backend.publicKey,
289
- logLevel: this.config.logLevel,
290
- persistence: config.persistence !== false,
291
- ...this._backend.getStatus(),
292
- });
293
- } catch (error) {
294
- this._log('ERROR', `${backendType} backend initialization failed`, { error: error.message });
295
- throw new Error(`${backendType} backend initialization failed: ${error.message}`);
296
- }
297
- }
298
-
299
142
  /**
300
143
  * Ensure backend is ready before operations
301
144
  * @returns {Promise<void>}
@@ -306,14 +149,6 @@ export class HoloSphere {
306
149
  }
307
150
  }
308
151
 
309
- /**
310
- * Get the storage backend instance
311
- * @returns {StorageBackend|null}
312
- */
313
- get backend() {
314
- return this._backend;
315
- }
316
-
317
152
  /**
318
153
  * Internal structured logging
319
154
  * @private
@@ -343,36 +178,18 @@ export class HoloSphere {
343
178
  console.log('='.repeat(60));
344
179
  console.log(` Version: ${info.version}`);
345
180
  console.log(` App Name: ${info.appName}`);
346
- console.log(` Backend: ${info.backend || 'nostr'}`);
347
181
  console.log(` Public Key: ${info.publicKey ? info.publicKey.substring(0, 16) + '...' : 'N/A'}`);
348
182
  console.log(` Log Level: ${info.logLevel}`);
349
183
  console.log(` Persistence: ${info.persistence ? 'Enabled' : 'Disabled'}${info.dataDir ? ` (${info.dataDir})` : ''}`);
350
-
351
- // Backend-specific info
352
- if (info.backend === 'nostr' || !info.backend) {
353
- console.log(` Auto-reconnect: ${info.reconnect ? 'Enabled' : 'Disabled'}`);
354
- console.log('\n Connected Relays:');
355
- if (!info.relays || info.relays.length === 0) {
356
- console.log(' (none - running in local mode)');
357
- } else {
358
- info.relays.forEach((relay, idx) => {
359
- console.log(` ${idx + 1}. ${relay}`);
360
- });
361
- }
362
- } else if (info.backend === 'gundb') {
363
- console.log('\n Gun Peers:');
364
- if (!info.peers || info.peers.length === 0) {
365
- console.log(' (none - running in local mode)');
366
- } else {
367
- info.peers.forEach((peer, idx) => {
368
- console.log(` ${idx + 1}. ${peer}`);
369
- });
370
- }
371
- } else if (info.backend === 'activitypub') {
372
- console.log(` Server URL: ${info.serverUrl || 'N/A'}`);
373
- console.log(` Actor ID: ${info.actorId || 'N/A'}`);
184
+ console.log(` Auto-reconnect: ${info.reconnect ? 'Enabled' : 'Disabled'}`);
185
+ console.log('\n Connected Relays:');
186
+ if (!info.relays || info.relays.length === 0) {
187
+ console.log(' (none - running in local mode)');
188
+ } else {
189
+ info.relays.forEach((relay, idx) => {
190
+ console.log(` ${idx + 1}. ${relay}`);
191
+ });
374
192
  }
375
-
376
193
  console.log('='.repeat(60) + '\n');
377
194
  }
378
195
  }
@@ -385,368 +202,13 @@ export class HoloSphere {
385
202
  return { ...this._metrics };
386
203
  }
387
204
 
388
- // ============================================================================
389
- // GUNDB-SPECIFIC METHODS
390
- // These methods are only available when using the 'gundb' backend
391
- // ============================================================================
392
-
393
- /**
394
- * Check if using GunDB backend
395
- * @private
396
- */
397
- _requireGunDB() {
398
- if (this.config.backend !== 'gundb') {
399
- throw new Error('This method requires the GunDB backend');
400
- }
401
- if (!this._backend) {
402
- throw new Error('Backend not initialized. Call ready() first.');
403
- }
404
- }
405
-
406
- // ============================================================================
407
- // GLOBAL TABLE OPERATIONS
408
- // ============================================================================
409
-
410
- /**
411
- * Write data to a global table
412
- * @param {string} tableName - Global table name (e.g., 'federation', 'schemas')
413
- * @param {Object} data - Data to write (must have 'id' field)
414
- * @returns {Promise<boolean>} Success indicator
415
- */
416
- async putGlobal(tableName, data) {
417
- await this.ready();
418
- this._requireGunDB();
419
- return this._backend.writeGlobal(tableName, data);
420
- }
421
-
422
- /**
423
- * Read data from a global table
424
- * @param {string} tableName - Global table name
425
- * @param {string} key - Data key
426
- * @returns {Promise<Object|null>} Data or null if not found
427
- */
428
- async getGlobal(tableName, key) {
429
- await this.ready();
430
- this._requireGunDB();
431
- return this._backend.readGlobal(tableName, key);
432
- }
433
-
434
- /**
435
- * Read all data from a global table
436
- * @param {string} tableName - Global table name
437
- * @returns {Promise<Object[]>} Array of data objects
438
- */
439
- async getAllGlobal(tableName) {
440
- await this.ready();
441
- this._requireGunDB();
442
- return this._backend.readAllGlobal(tableName);
443
- }
444
-
445
- /**
446
- * Delete data from a global table
447
- * @param {string} tableName - Global table name
448
- * @param {string} key - Data key
449
- * @returns {Promise<boolean>} Success indicator
450
- */
451
- async deleteGlobal(tableName, key) {
452
- await this.ready();
453
- this._requireGunDB();
454
- return this._backend.deleteGlobal(tableName, key);
455
- }
456
-
457
- // ============================================================================
458
- // REFERENCE OPERATIONS
459
- // ============================================================================
460
-
461
205
  /**
462
- * Create a reference to data
463
- * @param {string} holon - Holon ID
464
- * @param {string} lens - Lens name
465
- * @param {Object} data - Data object (must have 'id' field)
466
- * @returns {Object} Reference object with id and soul
467
- */
468
- createReference(holon, lens, data) {
469
- this._requireGunDB();
470
- return this._backend.createReference(holon, lens, data);
471
- }
472
-
473
- /**
474
- * Check if data is a reference
475
- * @param {Object} data - Data to check
476
- * @returns {boolean} True if data is a reference
477
- */
478
- isReference(data) {
479
- this._requireGunDB();
480
- return this._backend.isReference(data);
481
- }
482
-
483
- /**
484
- * Resolve a reference to get actual data
485
- * @param {Object} reference - Reference object
486
- * @param {Object} options - Resolution options
487
- * @returns {Promise<Object|null>} Resolved data or null
488
- */
489
- async resolveReference(reference, options = {}) {
490
- await this.ready();
491
- this._requireGunDB();
492
- return this._backend.resolveReference(reference, options);
493
- }
494
-
495
- // ============================================================================
496
- // AUTHENTICATION OPERATIONS
497
- // ============================================================================
498
-
499
- /**
500
- * Authenticate for a holon
501
- * @param {string} holonId - Holon ID
502
- * @param {string} password - Password
503
- * @returns {Promise<Object>} Authenticated user object
504
- */
505
- async authenticate(holonId, password) {
506
- await this.ready();
507
- this._requireGunDB();
508
- return this._backend.authenticate(holonId, password);
509
- }
510
-
511
- /**
512
- * Create a new user for a holon
513
- * @param {string} holonId - Holon ID
514
- * @param {string} password - Password
515
- * @returns {Promise<Object>} Created user object
516
- */
517
- async createUser(holonId, password) {
518
- await this.ready();
519
- this._requireGunDB();
520
- return this._backend.createUser(holonId, password);
521
- }
522
-
523
- /**
524
- * Logout current user
525
- */
526
- logout() {
527
- this._requireGunDB();
528
- this._backend.logout();
529
- }
530
-
531
- /**
532
- * Check if authenticated
533
- * @returns {boolean} True if authenticated
534
- */
535
- isAuthenticated() {
536
- this._requireGunDB();
537
- return this._backend.isAuthenticated();
538
- }
539
-
540
- /**
541
- * Write to private storage (requires authentication)
542
- * @param {string} lens - Lens name
543
- * @param {string} key - Data key
544
- * @param {Object} data - Data to write
545
- * @returns {Promise<boolean>} Success indicator
546
- */
547
- async writePrivate(lens, key, data) {
548
- await this.ready();
549
- this._requireGunDB();
550
- return this._backend.writePrivate(lens, key, data);
551
- }
552
-
553
- /**
554
- * Read from private storage (requires authentication)
555
- * @param {string} lens - Lens name
556
- * @param {string} key - Data key
557
- * @returns {Promise<Object|null>} Data or null
558
- */
559
- async readPrivate(lens, key) {
560
- await this.ready();
561
- this._requireGunDB();
562
- return this._backend.readPrivate(lens, key);
563
- }
564
-
565
- // ============================================================================
566
- // SCHEMA OPERATIONS
567
- // ============================================================================
568
-
569
- /**
570
- * Set a schema for a lens
571
- * @param {string} lens - Lens name
572
- * @param {Object} schema - JSON Schema definition
573
- * @returns {Promise<boolean>} Success indicator
574
- */
575
- async setSchema(lens, schema) {
576
- await this.ready();
577
- this._requireGunDB();
578
- return this._backend.setSchema(lens, schema);
579
- }
580
-
581
- /**
582
- * Get a schema for a lens
583
- * @param {string} lens - Lens name
584
- * @returns {Promise<Object|null>} Schema or null
585
- */
586
- async getSchema(lens) {
587
- await this.ready();
588
- this._requireGunDB();
589
- return this._backend.getSchema(lens);
590
- }
591
-
592
- /**
593
- * Validate data against a lens schema
594
- * @param {string} lens - Lens name
595
- * @param {Object} data - Data to validate
596
- * @returns {Promise<Object>} Validation result { valid: boolean, errors: Array }
597
- */
598
- async validateData(lens, data) {
599
- await this.ready();
600
- this._requireGunDB();
601
- return this._backend.validateData(lens, data);
602
- }
603
-
604
- // ============================================================================
605
- // FEDERATION OPERATIONS
606
- // ============================================================================
607
-
608
- /**
609
- * Create a federation relationship between two spaces
610
- * @param {string} spaceId1 - First space ID
611
- * @param {string} spaceId2 - Second space ID
612
- * @param {boolean} bidirectional - Whether to set up bidirectional notifications (default: true)
613
- * @returns {Promise<boolean>} True if federation was created
614
- */
615
- async federate(spaceId1, spaceId2, bidirectional = true) {
616
- await this.ready();
617
- this._requireGunDB();
618
- return gunFederation.federate(this._backend, spaceId1, spaceId2, bidirectional);
619
- }
620
-
621
- /**
622
- * Remove a federation relationship
623
- * @param {string} spaceId1 - First space ID
624
- * @param {string} spaceId2 - Second space ID
625
- * @returns {Promise<boolean>} True if federation was removed
626
- */
627
- async unfederate(spaceId1, spaceId2) {
628
- await this.ready();
629
- this._requireGunDB();
630
- return gunFederation.unfederate(this._backend, spaceId1, spaceId2);
631
- }
632
-
633
- /**
634
- * Get federation info for a space
635
- * @param {string} spaceId - Space ID
636
- * @returns {Promise<Object|null>} Federation info or null
637
- */
638
- async getFederation(spaceId) {
639
- await this.ready();
640
- this._requireGunDB();
641
- return gunFederation.getFederation(this._backend, spaceId);
642
- }
643
-
644
- /**
645
- * Reset all federation relationships for a space
646
- * @param {string} spaceId - Space ID
647
- * @param {Object} options - Reset options
648
- * @returns {Promise<Object>} Result object
649
- */
650
- async resetFederation(spaceId, options = {}) {
651
- await this.ready();
652
- this._requireGunDB();
653
- return gunFederation.resetFederation(this._backend, spaceId, options);
654
- }
655
-
656
- /**
657
- * Propagate data to federated spaces
658
- * @param {string} holon - Holon identifier
659
- * @param {string} lens - Lens identifier
660
- * @param {Object} data - Data to propagate
661
- * @param {Object} options - Propagation options
662
- * @returns {Promise<Object>} Result with success count and errors
663
- */
664
- async propagate(holon, lens, data, options = {}) {
665
- await this.ready();
666
- this._requireGunDB();
667
- return gunFederation.propagate(this._backend, holon, lens, data, options);
668
- }
669
-
670
- /**
671
- * Get combined data from local and federated sources
672
- * @param {string} holon - Local holon name
673
- * @param {string} lens - Lens to query
674
- * @param {Object} options - Options for data retrieval and aggregation
675
- * @returns {Promise<Array>} Combined array of local and federated data
676
- */
677
- async getFederated(holon, lens, options = {}) {
678
- await this.ready();
679
- this._requireGunDB();
680
- return gunFederation.getFederated(this._backend, holon, lens, options);
681
- }
682
-
683
- /**
684
- * Subscribe to federation notifications for a space
685
- * @param {string} spaceId - Space ID to subscribe to
686
- * @param {Function} callback - Callback to execute on notifications
687
- * @param {Object} options - Subscription options
688
- * @returns {Promise<Object>} Subscription object with unsubscribe() method
689
- */
690
- async subscribeFederation(spaceId, callback, options = {}) {
691
- await this.ready();
692
- this._requireGunDB();
693
- return gunFederation.subscribeFederation(this._backend, spaceId, callback, options);
694
- }
695
-
696
- /**
697
- * Track a federated message across different chats
698
- * @param {string} originalChatId - Original chat ID
699
- * @param {string} messageId - Original message ID
700
- * @param {string} federatedChatId - Federated chat ID
701
- * @param {string} federatedMessageId - Federated message ID
702
- * @param {string} type - Message type
703
- * @returns {Promise<void>}
704
- */
705
- async federateMessage(originalChatId, messageId, federatedChatId, federatedMessageId, type = 'generic') {
706
- await this.ready();
707
- this._requireGunDB();
708
- return gunFederation.federateMessage(this._backend, originalChatId, messageId, federatedChatId, federatedMessageId, type);
709
- }
710
-
711
- /**
712
- * Get all federated messages for a given original message
713
- * @param {string} originalChatId - Original chat ID
714
- * @param {string} messageId - Original message ID
715
- * @returns {Promise<Object|null>} Tracking information for the message
716
- */
717
- async getFederatedMessages(originalChatId, messageId) {
718
- await this.ready();
719
- this._requireGunDB();
720
- return gunFederation.getFederatedMessages(this._backend, originalChatId, messageId);
721
- }
722
-
723
- /**
724
- * Update a federated message across all federated chats
725
- * @param {string} originalChatId - Original chat ID
726
- * @param {string} messageId - Original message ID
727
- * @param {Function} updateCallback - Function to update the message in each chat
728
- * @returns {Promise<void>}
729
- */
730
- async updateFederatedMessages(originalChatId, messageId, updateCallback) {
731
- await this.ready();
732
- this._requireGunDB();
733
- return gunFederation.updateFederatedMessages(this._backend, originalChatId, messageId, updateCallback);
734
- }
735
-
736
- // ============================================================================
737
- // LIFECYCLE
738
- // ============================================================================
739
-
740
- /**
741
- * Closes the backend and cleans up resources.
206
+ * Closes the client and cleans up resources.
742
207
  * Should be called when done using the HoloSphere instance.
743
208
  *
744
209
  * @returns {void}
745
210
  */
746
211
  close() {
747
- if (this._backend) {
748
- this._backend.close();
749
- }
750
212
  if (this.client && typeof this.client.close === 'function') {
751
213
  this.client.close();
752
214
  }