holosphere 1.1.6 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/FEDERATION.md CHANGED
@@ -1,143 +1,111 @@
1
1
  # HoloSphere Federation
2
2
 
3
- This document explains how to use the federation functionality in HoloSphere, which allows different spaces to share data with each other.
3
+ HoloSphere's federation system allows different holons (spaces) to share and access data from each other. Federation creates a relationship between spaces that enables data propagation and cross-space access.
4
4
 
5
- ## What is Federation?
5
+ ## Key Concepts
6
6
 
7
- Federation in HoloSphere allows different spaces (data stores) to connect and share data with each other. This enables:
7
+ - **Federation Relationship**: A connection between two spaces that allows data to flow between them.
8
+ - **Soul References**: Lightweight references that point to data in its original location (single source of truth).
9
+ - **Notification Flow**: Data notifications flow from source spaces to target spaces that are in the notify list.
10
+ - **Source-Target Relationship**: Each federation sets up a source space (federation list) and a target space (notify list).
8
11
 
9
- - Creating networks of connected spaces
10
- - Propagating data across these networks
11
- - Subscribing to changes in federated spaces
12
+ ## Federation Data Flow
12
13
 
13
- Federation can be either public (no authentication required) or private (password-protected).
14
+ The HoloSphere federation system works with a clear source-target relationship:
14
15
 
15
- ## Core Federation Functions
16
+ 1. **Federation List**: When space A federates with space B, space A adds B to its federation list.
17
+ 2. **Notify List**: Space B adds space A to its notify list.
18
+ 3. **Data Flow**: When space A changes, space B gets notified (but not vice versa unless bidirectional).
16
19
 
17
- ### Creating a Federation
20
+ ## Creating Federation
18
21
 
19
- To create a federation between two spaces:
22
+ Create federation relationships between spaces:
20
23
 
21
24
  ```javascript
22
- // Public federation (no passwords)
25
+ // Create federation between space1 and space2
23
26
  await holoSphere.federate('space1', 'space2');
24
27
 
25
- // Private federation (with passwords)
26
- await holoSphere.federate('space1', 'space2', 'password1', 'password2');
28
+ // This sets up:
29
+ // - space1.federation includes space2
30
+ // - space2.notify includes space1
27
31
  ```
28
32
 
29
- ### Setting Up Bidirectional Notification (Important!)
33
+ The bidirectional parameter is largely unused in the current implementation since the federation system naturally sets up the correct notification flow. The default relationship allows space2 to be notified of changes in space1.
30
34
 
31
- After creating a federation, you need to set up the notification settings for proper bidirectional data propagation:
35
+ ## Storing and Propagating Data
36
+
37
+ Data must be explicitly propagated to federated spaces:
32
38
 
33
39
  ```javascript
34
- // 1. Get federation settings for first space
35
- const fedSettings1 = await holoSphere.getGlobal('federation', 'space1');
36
- if (fedSettings1) {
37
- // 2. Configure notify settings
38
- fedSettings1.notify = fedSettings1.notify || [];
39
- if (!fedSettings1.notify.includes('space2')) {
40
- fedSettings1.notify.push('space2');
41
- }
42
- // 3. Save updated settings
43
- await holoSphere.putGlobal('federation', fedSettings1);
44
- }
40
+ const data = {
41
+ id: 'item1',
42
+ title: 'Federation Example',
43
+ value: 42
44
+ };
45
45
 
46
- // Repeat for the second space
47
- const fedSettings2 = await holoSphere.getGlobal('federation', 'space2');
48
- if (fedSettings2) {
49
- fedSettings2.notify = fedSettings2.notify || [];
50
- if (!fedSettings2.notify.includes('space1')) {
51
- fedSettings2.notify.push('space1');
52
- }
53
- await holoSphere.putGlobal('federation', fedSettings2);
54
- }
55
- ```
46
+ // Store data in space1
47
+ await holoSphere.put('space1', 'items', data);
56
48
 
57
- ### Getting Federation Information
49
+ // Propagate to federated spaces
50
+ await holoSphere.propagate('space1', 'items', data);
51
+ ```
58
52
 
59
- To retrieve information about a space's federation:
53
+ You can also enable automatic propagation in the `put()` method:
60
54
 
61
55
  ```javascript
62
- // Public space
63
- const fedInfo = await holoSphere.getFederation('space1');
64
-
65
- // Private space
66
- const fedInfo = await holoSphere.getFederation('space1', 'password1');
56
+ // Store data and automatically propagate
57
+ await holoSphere.put('space1', 'items', data, null, {
58
+ autoPropagate: true
59
+ });
67
60
  ```
68
61
 
69
- The returned object contains:
70
- - `id`: The space ID
71
- - `name`: The space name
72
- - `federation`: Array of space IDs that this space is federated with
73
- - `notify`: Array of space IDs that this space will propagate data to
62
+ ## Accessing Federated Data
74
63
 
75
- ### Propagating Data to Federated Spaces
64
+ ### Direct Retrieval
76
65
 
77
- To propagate data to all federated spaces:
66
+ You can access data directly from any space:
78
67
 
79
68
  ```javascript
80
- const data = { id: 'item1', value: 42 };
81
-
82
- // 1. Store data locally first
83
- await holoSphere.put('space1', 'items', data);
84
-
85
- // 2. Explicitly propagate to federated spaces
86
- await holoSphere.propagateToFederation('space1', 'items', data);
87
-
88
- // 3. (Optional) Add a short delay to ensure propagation completes
89
- await new Promise(resolve => setTimeout(resolve, 1000));
69
+ // Retrieve data from space2 (will resolve reference if it's a reference)
70
+ const data = await holoSphere.get('space2', 'items', 'item1', null, {
71
+ resolveReferences: true // Default is true
72
+ });
90
73
  ```
91
74
 
92
- ### Accessing Data Across Federated Spaces
75
+ ### Aggregate Federated Data
93
76
 
94
- There are multiple ways to access data across federated spaces:
95
-
96
- #### Method 1: Using getFederated (Recommended)
97
-
98
- This retrieves data from both the local space and all federated spaces:
77
+ Use `getFederated()` to get data from multiple federated spaces:
99
78
 
100
79
  ```javascript
101
- // Get all items from local and federated spaces
102
- const allItems = await holoSphere.getFederated('space2', 'items');
103
-
104
- // Find a specific item by ID
105
- const item1 = allItems.find(item => item.id === 'item1');
80
+ // Get combined data from the local space and all its federated spaces
81
+ const federatedData = await holoSphere.getFederated('space2', 'items', {
82
+ resolveReferences: true, // Default: true
83
+ idField: 'id' // Field to use as the unique identifier
84
+ });
106
85
  ```
107
86
 
108
- #### Method 2: Direct Access
87
+ ## Soul References
109
88
 
110
- After propagation, data may also be accessible directly:
89
+ HoloSphere uses a simplified reference system based on soul paths:
111
90
 
112
- ```javascript
113
- // Attempt to get item1 from space2 directly
114
- const item1FromSpace2 = await holoSphere.get('space2', 'items', 'item1');
115
- ```
116
-
117
- ### Subscribing to Federation Changes
91
+ 1. A reference contains only an `id` and a `soul` property
92
+ 2. The soul path is in the format: `appname/holon/lens/key`
93
+ 3. When resolving a reference, HoloSphere follows the soul path to retrieve the original data
118
94
 
119
- To subscribe to changes in a federation:
95
+ By default, federation propagation uses references instead of duplicating data. This can be controlled:
120
96
 
121
97
  ```javascript
122
- // Subscribe
123
- const subscription = await holoSphere.subscribeFederation('space1', null, (data, originSpace, lens) => {
124
- console.log(`Received data from ${originSpace}/${lens}:`, data);
98
+ // Propagate with full data copy instead of references
99
+ await holoSphere.propagate('space1', 'items', data, {
100
+ useReferences: false
125
101
  });
126
-
127
- // Later, unsubscribe
128
- subscription.unsubscribe();
129
102
  ```
130
103
 
131
- ### Removing a Federation
132
-
133
- To remove a federation between two spaces:
104
+ ## Removing Federation
134
105
 
135
106
  ```javascript
136
- // Public federation
107
+ // Remove federation relationship
137
108
  await holoSphere.unfederate('space1', 'space2');
138
-
139
- // Private federation
140
- await holoSphere.unfederate('space1', 'space2', 'password1', 'password2');
141
109
  ```
142
110
 
143
111
  ## Complete Example
@@ -154,61 +122,55 @@ async function federationExample() {
154
122
  const space1 = 'public-space1';
155
123
  const space2 = 'public-space2';
156
124
 
157
- // Step 1: Create federation
125
+ // Step 1: Create federation relationship
158
126
  await holoSphere.federate(space1, space2);
159
127
 
160
- // Step 2: Set up bidirectional notify settings (critical!)
161
- const fedSettings1 = await holoSphere.getGlobal('federation', space1);
162
- if (fedSettings1) {
163
- fedSettings1.notify = fedSettings1.notify || [];
164
- if (!fedSettings1.notify.includes(space2)) {
165
- fedSettings1.notify.push(space2);
166
- await holoSphere.putGlobal('federation', fedSettings1);
167
- }
168
- }
128
+ // Step 2: Verify federation is set up properly
129
+ const fedInfo1 = await holoSphere.getFederation(space1);
130
+ const fedInfo2 = await holoSphere.getFederation(space2);
169
131
 
170
- const fedSettings2 = await holoSphere.getGlobal('federation', space2);
171
- if (fedSettings2) {
172
- fedSettings2.notify = fedSettings2.notify || [];
173
- if (!fedSettings2.notify.includes(space1)) {
174
- fedSettings2.notify.push(space1);
175
- await holoSphere.putGlobal('federation', fedSettings2);
176
- }
177
- }
132
+ console.log(`Federation info for ${space1}:`, fedInfo1);
133
+ // Should include: federation: ['space2']
178
134
 
179
- // Step 3: Verify federation is set up properly
180
- const updatedFedInfo = await holoSphere.getFederation(space1);
181
- console.log(`Federation info for ${space1}:`, updatedFedInfo);
135
+ console.log(`Federation info for ${space2}:`, fedInfo2);
136
+ // Should include: notify: ['space1']
182
137
 
183
- // Step 4: Store data in space1
138
+ // Step 3: Store data in space1
184
139
  const item = {
185
140
  id: 'item1',
186
141
  title: 'Federation Test',
187
142
  value: 42
188
143
  };
144
+
189
145
  await holoSphere.put(space1, 'items', item);
190
146
 
191
- // Step 5: Propagate to federation
192
- await holoSphere.propagateToFederation(space1, 'items', item);
147
+ // Step 4: Propagate data to federated spaces
148
+ await holoSphere.propagate(space1, 'items', item);
193
149
 
194
- // Step 6: Allow time for propagation
150
+ // Allow time for propagation
195
151
  await new Promise(resolve => setTimeout(resolve, 1000));
196
152
 
197
- // Step 7: Access data from both spaces
198
- const itemFromSpace1 = await holoSphere.get(space1, 'items', 'item1');
199
- console.log('Item from space1:', itemFromSpace1);
153
+ // Step 5: Access data from space2 (resolves reference)
154
+ const itemFromSpace2 = await holoSphere.get(space2, 'items', 'item1');
155
+ console.log('Item from space2:', itemFromSpace2);
156
+
157
+ // Step 6: Update item in space1
158
+ const updatedItem = {
159
+ ...item,
160
+ value: 100,
161
+ updated: true
162
+ };
163
+
164
+ await holoSphere.put(space1, 'items', updatedItem);
200
165
 
201
- // Step 8: Access federated data
202
- // Method 1: Using getFederated
203
- const federatedData = await holoSphere.getFederated(space2, 'items');
204
- const itemFromFederation = federatedData.find(item => item.id === 'item1');
205
- console.log('Item from federation:', itemFromFederation);
166
+ // Since we're using soul references, the update is immediately visible
167
+ // through the reference without needing to propagate again
206
168
 
207
- // Method 2: Direct access (if propagation worked correctly)
208
- const directAccess = await holoSphere.get(space2, 'items', 'item1');
209
- console.log('Direct access from space2:', directAccess);
169
+ // Verify update is visible through the reference
170
+ const updatedItemFromSpace2 = await holoSphere.get(space2, 'items', 'item1');
171
+ console.log('Updated item from space2:', updatedItemFromSpace2);
210
172
 
211
- // Step 9: Clean up
173
+ // Step 7: Clean up
212
174
  await holoSphere.unfederate(space1, space2);
213
175
  } finally {
214
176
  // Always close the HoloSphere instance
@@ -219,47 +181,33 @@ async function federationExample() {
219
181
  federationExample().catch(console.error);
220
182
  ```
221
183
 
222
- ## Running the Tests
223
-
224
- HoloSphere includes test scripts to verify federation functionality:
225
-
226
- ### Public Federation Tests
227
-
228
- Run the public federation tests with:
229
-
230
- ```bash
231
- node test-federation.js
232
- ```
233
-
234
- This tests:
235
- - Creating public federations
236
- - Storing and retrieving data
237
- - Propagating data to federated spaces
238
- - Subscribing to federation changes
239
- - Removing federations
240
-
241
184
  ## Troubleshooting
242
185
 
243
186
  ### Common Issues
244
187
 
245
- 1. **Missing Notify Settings**: The most common issue is not properly configuring notify settings. Always ensure both spaces have each other in their notify arrays.
188
+ 1. **Federation Relationship**: Make sure to check both the federation list and notify list to understand data flow.
246
189
 
247
- 2. **No Explicit Propagation**: Data doesn't automatically propagate between spaces. You must explicitly call `propagateToFederation()` after storing data.
190
+ 2. **Data Propagation**: If data isn't appearing in federated spaces, check:
191
+ - The federation relationship was created correctly
192
+ - The data was propagated explicitly or `autoPropagate` was set to `true`
193
+ - The notify list includes the target space
248
194
 
249
- 3. **Authentication Errors**: When working with private federations, ensure passwords are correct and consistent.
195
+ 3. **Reference Resolution**: If you're getting reference objects instead of the actual data:
196
+ - Make sure `resolveReferences` is set to `true` (it's the default)
197
+ - Check that the original data still exists at the referenced location
250
198
 
251
199
  4. **Timing Issues**: Data propagation is asynchronous. Add small delays (500-1000ms) between operations to allow propagation to complete.
252
200
 
253
- 5. **Missing Federation Metadata**: After propagation, federated items should have a `federation` property containing the origin space and timestamp.
254
-
255
201
  ### Best Practices
256
202
 
257
- 1. **Verify Federation Setup**: After creating a federation, always check the federation info to ensure it includes both the federation relationship and notify settings.
258
-
259
- 2. **Error Handling**: Wrap federation operations in try/catch blocks and handle errors gracefully.
203
+ 1. **Verify Federation Structure**: After creating a federation, check both spaces to ensure:
204
+ - Source space has the target in its federation list
205
+ - Target space has the source in its notify list
260
206
 
261
- 3. **Bidirectional Setup**: For proper data sharing, both spaces need notify settings pointing to each other.
207
+ 2. **Explicit Propagation**: Unless you're using `autoPropagate`, always call `propagate()` explicitly after storing data that should be shared.
262
208
 
263
- 4. **Propagation Timing**: Allow sufficient time for propagation operations to complete before attempting to access data.
209
+ 3. **Choose the Right Propagation Method**:
210
+ - Use `useReferences: true` (default) to keep a single source of truth
211
+ - Use `useReferences: false` only when you need independent copies
264
212
 
265
- 5. **Cleanup**: Always close the HoloSphere instance when done to prevent resource leaks.
213
+ 4. **Cleanup**: Always close the HoloSphere instance when done to prevent resource leaks.
package/README.md CHANGED
@@ -329,3 +329,143 @@ Data in HoloSphere is organized by:
329
329
 
330
330
  GPL-3.0-or-later
331
331
 
332
+ # HoloSphere Federation
333
+
334
+ HoloSphere provides a federation system that allows spaces to share data and messages across different holons. This document outlines the federation functionality and how to use it.
335
+
336
+ ## Core Federation Features
337
+
338
+ ### Space Federation
339
+ - Create relationships between spaces with clear source-target connections
340
+ - Use soul references to maintain a single source of truth
341
+ - Control data propagation between federated spaces
342
+ - Manage notification settings for each space
343
+
344
+ ### Message Federation
345
+ - Track messages across federated spaces
346
+ - Maintain message relationships between original and federated copies
347
+ - Update messages consistently across all federated spaces
348
+
349
+ ## API Reference
350
+
351
+ ### Space Federation
352
+
353
+ #### `federate(spaceId1, spaceId2, password1, password2, bidirectional)`
354
+ Creates a federation relationship between two spaces.
355
+
356
+ ```javascript
357
+ await holosphere.federate('space1', 'space2', 'pass1', 'pass2');
358
+ ```
359
+
360
+ This sets up:
361
+ - space1.federation includes space2
362
+ - space2.notify includes space1
363
+
364
+ Parameters:
365
+ - `spaceId1`: First space ID (source space)
366
+ - `spaceId2`: Second space ID (target space)
367
+ - `password1`: Optional password for first space
368
+ - `password2`: Optional password for second space
369
+ - `bidirectional`: Whether to set up bidirectional notifications (default: true, but generally not needed)
370
+
371
+ ### Data Propagation
372
+
373
+ #### `propagate(holon, lens, data, options)`
374
+ Propagates data to federated spaces.
375
+
376
+ ```javascript
377
+ await holosphere.propagate('space1', 'items', data, {
378
+ useReferences: true, // Default: uses soul references
379
+ targetSpaces: ['space2'] // Optional: specific targets
380
+ });
381
+ ```
382
+
383
+ Parameters:
384
+ - `holon`: The holon identifier
385
+ - `lens`: The lens identifier
386
+ - `data`: The data to propagate
387
+ - `options`: Propagation options
388
+
389
+ Alternatively, you can use auto-propagation:
390
+
391
+ ```javascript
392
+ await holosphere.put('space1', 'items', data, null, {
393
+ autoPropagate: true // Enable auto-propagation
394
+ });
395
+ ```
396
+
397
+ ### Message Federation
398
+
399
+ #### `federateMessage(originalChatId, messageId, federatedChatId, federatedMessageId, type)`
400
+ Tracks a federated message across different chats.
401
+
402
+ ```javascript
403
+ await holosphere.federateMessage('chat1', 'msg1', 'chat2', 'msg2', 'quest');
404
+ ```
405
+
406
+ #### `getFederatedMessages(originalChatId, messageId)`
407
+ Gets all federated messages for a given original message.
408
+
409
+ ```javascript
410
+ const messages = await holosphere.getFederatedMessages('chat1', 'msg1');
411
+ ```
412
+
413
+ #### `updateFederatedMessages(originalChatId, messageId, updateCallback)`
414
+ Updates a message across all federated chats.
415
+
416
+ ```javascript
417
+ await holosphere.updateFederatedMessages('chat1', 'msg1', async (chatId, messageId) => {
418
+ // Update message in this chat
419
+ });
420
+ ```
421
+
422
+ ## Usage Example
423
+
424
+ ```javascript
425
+ // Create federation between spaces
426
+ await holosphere.federate('space1', 'space2');
427
+
428
+ // Store data in space1
429
+ const data = { id: 'item1', value: 42 };
430
+ await holosphere.put('space1', 'items', data);
431
+
432
+ // Propagate to federated spaces
433
+ await holosphere.propagate('space1', 'items', data);
434
+
435
+ // Retrieve data from space2 (will resolve the reference)
436
+ const item = await holosphere.get('space2', 'items', 'item1');
437
+
438
+ // Track a federated message
439
+ await holosphere.federateMessage('chat1', 'msg1', 'chat2', 'msg2', 'quest');
440
+
441
+ // Update message across all federated chats
442
+ await holosphere.updateFederatedMessages('chat1', 'msg1', async (chatId, messageId) => {
443
+ await updateMessageInChat(chatId, messageId);
444
+ });
445
+ ```
446
+
447
+ ## Soul References
448
+
449
+ When using the default `useReferences: true` with propagation:
450
+
451
+ 1. Only a lightweight reference is stored in the federated space
452
+ 2. The reference contains the original item's ID and soul path
453
+ 3. When accessed, the reference is automatically resolved to the original data
454
+ 4. Changes to the original data are immediately visible through references
455
+
456
+ This maintains a single source of truth while keeping storage efficient.
457
+
458
+ ## Federation Structure
459
+
460
+ The federation system uses two key arrays to manage relationships:
461
+
462
+ ```javascript
463
+ {
464
+ id: string,
465
+ name: string,
466
+ federation: string[], // Source spaces this holon federates with
467
+ notify: string[], // Target spaces to notify of changes
468
+ timestamp: number
469
+ }
470
+ ```
471
+
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Organization Federation Example for HoloSphere
3
+ *
4
+ * This example demonstrates a real-world use case where a tech team creates tasks
5
+ * that are federated to the parent organization for visibility.
6
+ */
7
+
8
+ import HoloSphere from './holosphere.js';
9
+
10
+ async function organizationFederationExample() {
11
+ const holoSphere = new HoloSphere('organization-example');
12
+
13
+ try {
14
+ console.log('Starting Organization Federation Example...');
15
+
16
+ // Define our spaces/holons
17
+ const orgHolon = 'acme-organization';
18
+ const techTeamHolon = 'acme-tech-team';
19
+
20
+ // Step 1: Create federation relationship between tech team and organization
21
+ console.log('\nStep 1: Creating federation relationship...');
22
+
23
+ await holoSphere.federate(techTeamHolon, orgHolon);
24
+ console.log('Federation created between tech team and organization');
25
+
26
+ // Step 2: Set up bidirectional notification settings (critical!)
27
+ console.log('\nStep 2: Setting up bidirectional notification...');
28
+
29
+ // First set up tech team to notify organization
30
+ const techTeamFedSettings = await holoSphere.getGlobal('federation', techTeamHolon);
31
+ if (techTeamFedSettings) {
32
+ techTeamFedSettings.notify = techTeamFedSettings.notify || [];
33
+ if (!techTeamFedSettings.notify.includes(orgHolon)) {
34
+ techTeamFedSettings.notify.push(orgHolon);
35
+ await holoSphere.putGlobal('federation', techTeamFedSettings);
36
+ console.log('Tech team set to notify organization');
37
+ }
38
+ }
39
+
40
+ // Then set up organization to notify tech team (if needed)
41
+ const orgFedSettings = await holoSphere.getGlobal('federation', orgHolon);
42
+ if (orgFedSettings) {
43
+ orgFedSettings.notify = orgFedSettings.notify || [];
44
+ if (!orgFedSettings.notify.includes(techTeamHolon)) {
45
+ orgFedSettings.notify.push(techTeamHolon);
46
+ await holoSphere.putGlobal('federation', orgFedSettings);
47
+ console.log('Organization set to notify tech team');
48
+ }
49
+ }
50
+
51
+ // Step 3: Verify federation is set up properly
52
+ console.log('\nStep 3: Verifying federation setup...');
53
+
54
+ const techTeamFedInfo = await holoSphere.getFederation(techTeamHolon);
55
+ console.log('Tech team federation info:', techTeamFedInfo);
56
+
57
+ // Step 4: Create a task in the tech team holon
58
+ console.log('\nStep 4: Creating a task in the tech team holon...');
59
+
60
+ const task = {
61
+ id: 'task-123',
62
+ title: 'Implement new authentication system',
63
+ description: 'Replace the current auth system with OAuth2',
64
+ assignee: 'dev@example.com',
65
+ status: 'in_progress',
66
+ priority: 'high',
67
+ dueDate: '2023-12-31',
68
+ createdAt: new Date().toISOString(),
69
+ tags: ['security', 'infrastructure']
70
+ };
71
+
72
+ // Store the task in the tech team holon
73
+ await holoSphere.put(techTeamHolon, 'tasks', task);
74
+ console.log('Task created in tech team holon:', task.id);
75
+
76
+ // Step 5: Propagate the task to the organization holon
77
+ console.log('\nStep 5: Propagating task to organization holon...');
78
+
79
+ await holoSphere.propagate(techTeamHolon, 'tasks', task);
80
+ console.log('Task propagated to organization holon');
81
+
82
+ // Step 6: Allow time for propagation
83
+ console.log('\nStep 6: Waiting for propagation to complete...');
84
+ await new Promise(resolve => setTimeout(resolve, 1000));
85
+
86
+ // Step 7: Verify task in both holons
87
+ console.log('\nStep 7: Verifying task is in both holons...');
88
+
89
+ // Check tech team holon directly
90
+ const techTeamTask = await holoSphere.get(techTeamHolon, 'tasks', 'task-123');
91
+ console.log('Task in tech team holon:', techTeamTask ? 'Found' : 'Not found');
92
+ if (techTeamTask) console.log('Tech team task status:', techTeamTask.status);
93
+
94
+ // Check organization holon directly
95
+ const orgTask = await holoSphere.get(orgHolon, 'tasks', 'task-123');
96
+ console.log('Task in organization holon:', orgTask ? 'Found' : 'Not found');
97
+ if (orgTask) {
98
+ console.log('Organization task status:', orgTask.status);
99
+ console.log('Federation metadata:', orgTask.federation);
100
+ }
101
+
102
+ // Step 8: Use getFederated to view all tasks across holons
103
+ console.log('\nStep 8: Using getFederated to view all tasks...');
104
+
105
+ const allOrgTasks = await holoSphere.getFederated(orgHolon, 'tasks');
106
+ console.log(`Organization holon has access to ${allOrgTasks.length} tasks`);
107
+
108
+ const allTechTasks = await holoSphere.getFederated(techTeamHolon, 'tasks');
109
+ console.log(`Tech team holon has access to ${allTechTasks.length} tasks`);
110
+
111
+ // Step 9: Update the task in tech team and propagate the change
112
+ console.log('\nStep 9: Updating task in tech team holon...');
113
+
114
+ const updatedTask = {
115
+ ...task,
116
+ status: 'completed',
117
+ completedAt: new Date().toISOString()
118
+ };
119
+
120
+ await holoSphere.put(techTeamHolon, 'tasks', updatedTask);
121
+ await holoSphere.propagate(techTeamHolon, 'tasks', updatedTask);
122
+ console.log('Task updated and propagated');
123
+
124
+ // Step 10: Allow time for propagation
125
+ console.log('\nStep 10: Waiting for propagation to complete...');
126
+ await new Promise(resolve => setTimeout(resolve, 1000));
127
+
128
+ // Step 11: Verify updates in both holons
129
+ console.log('\nStep 11: Verifying updated task in both holons...');
130
+
131
+ const updatedTechTeamTask = await holoSphere.get(techTeamHolon, 'tasks', 'task-123');
132
+ console.log('Updated task in tech team holon status:', updatedTechTeamTask?.status);
133
+
134
+ const updatedOrgTask = await holoSphere.get(orgHolon, 'tasks', 'task-123');
135
+ console.log('Updated task in organization holon status:', updatedOrgTask?.status);
136
+
137
+ // Step 12: Clean up - remove federation
138
+ console.log('\nStep 12: Cleaning up - removing federation...');
139
+
140
+ await holoSphere.unfederate(techTeamHolon, orgHolon);
141
+ console.log('Federation removed between tech team and organization');
142
+
143
+ console.log('\nOrganization federation example completed successfully!');
144
+ } catch (error) {
145
+ console.error('Error in organization federation example:', error);
146
+ } finally {
147
+ // Always close the HoloSphere instance
148
+ await holoSphere.close();
149
+ console.log('HoloSphere instance closed');
150
+ }
151
+ }
152
+
153
+ // Run the example
154
+ organizationFederationExample().catch(console.error);