holosphere 1.1.11 → 1.1.12
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/content.js +175 -26
- package/examples/hologram-updates-example.js +106 -0
- package/federation.js +236 -118
- package/global.js +174 -9
- package/holosphere.d.ts +15 -0
- package/holosphere.js +2 -2
- package/node.js +92 -7
- package/package.json +1 -1
- package/test/hologram-deletion.test.js +197 -0
- package/test/hologram-updates-return.test.js +166 -0
- package/test/hologram-updates.test.js +143 -0
- package/test/hologram.test.js +3 -3
- package/test/meta-strip.test.js +159 -0
- package/test/parent-propagation.test.js +138 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// hologram-updates.test.js
|
|
2
|
+
|
|
3
|
+
import HoloSphere from '../holosphere.js';
|
|
4
|
+
|
|
5
|
+
describe('Hologram Update Tests', () => {
|
|
6
|
+
let holoSphere;
|
|
7
|
+
const testHolon = 'updateTestHolon';
|
|
8
|
+
const testLens = 'testLens';
|
|
9
|
+
const otherLens = 'otherLens';
|
|
10
|
+
const appName = 'test-hologram-update-app';
|
|
11
|
+
|
|
12
|
+
const waitForGun = (ms = 300) => new Promise(resolve => setTimeout(resolve, ms));
|
|
13
|
+
|
|
14
|
+
beforeEach(async () => {
|
|
15
|
+
holoSphere = new HoloSphere(appName, false);
|
|
16
|
+
// Clean up before each test
|
|
17
|
+
try {
|
|
18
|
+
await holoSphere.deleteAll(testHolon, testLens);
|
|
19
|
+
await holoSphere.deleteAll(testHolon, otherLens);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
// Ignore cleanup errors
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
await waitForGun(100);
|
|
25
|
+
}, 30000);
|
|
26
|
+
|
|
27
|
+
afterEach(async () => {
|
|
28
|
+
if (holoSphere) {
|
|
29
|
+
await holoSphere.close();
|
|
30
|
+
}
|
|
31
|
+
}, 30000);
|
|
32
|
+
|
|
33
|
+
test('should update active holograms when original data is modified', async () => {
|
|
34
|
+
// 1. Store original data
|
|
35
|
+
const originalData = { id: 'update-test-item', value: 'Original Value', count: 1 };
|
|
36
|
+
await holoSphere.put(testHolon, testLens, originalData);
|
|
37
|
+
await waitForGun();
|
|
38
|
+
|
|
39
|
+
// 2. Create and store a hologram pointing to the original data
|
|
40
|
+
const hologram = holoSphere.createHologram(testHolon, testLens, originalData);
|
|
41
|
+
await holoSphere.put(testHolon, otherLens, hologram); // Store hologram in different lens
|
|
42
|
+
await waitForGun(500);
|
|
43
|
+
|
|
44
|
+
// 3. Get the hologram before update (should not have 'updated' field)
|
|
45
|
+
const hologramBeforeUpdate = await holoSphere.get(testHolon, otherLens, originalData.id, null, { resolveHolograms: false });
|
|
46
|
+
expect(hologramBeforeUpdate).toBeDefined();
|
|
47
|
+
expect(hologramBeforeUpdate.soul).toBe(hologram.soul);
|
|
48
|
+
expect(hologramBeforeUpdate.updated).toBeUndefined();
|
|
49
|
+
|
|
50
|
+
// 4. Update the original data
|
|
51
|
+
const updatedData = { id: 'update-test-item', value: 'Updated Value', count: 2 };
|
|
52
|
+
await holoSphere.put(testHolon, testLens, updatedData);
|
|
53
|
+
await waitForGun(1000); // Give time for hologram updates to propagate
|
|
54
|
+
|
|
55
|
+
// 5. Check that the hologram now has an 'updated' timestamp
|
|
56
|
+
const hologramAfterUpdate = await holoSphere.get(testHolon, otherLens, originalData.id, null, { resolveHolograms: false });
|
|
57
|
+
expect(hologramAfterUpdate).toBeDefined();
|
|
58
|
+
expect(hologramAfterUpdate.soul).toBe(hologram.soul);
|
|
59
|
+
expect(hologramAfterUpdate.updated).toBeDefined();
|
|
60
|
+
expect(typeof hologramAfterUpdate.updated).toBe('number');
|
|
61
|
+
expect(hologramAfterUpdate.updated).toBeGreaterThan(Date.now() - 5000); // Should be recent
|
|
62
|
+
|
|
63
|
+
// 6. Verify that resolving the hologram gives the updated data
|
|
64
|
+
const resolvedData = await holoSphere.get(testHolon, otherLens, originalData.id);
|
|
65
|
+
expect(resolvedData).toBeDefined();
|
|
66
|
+
expect(resolvedData.value).toBe('Updated Value');
|
|
67
|
+
expect(resolvedData.count).toBe(2);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('should update multiple holograms pointing to the same data', async () => {
|
|
71
|
+
// 1. Store original data
|
|
72
|
+
const originalData = { id: 'multi-hologram-test', value: 'Original Value' };
|
|
73
|
+
await holoSphere.put(testHolon, testLens, originalData);
|
|
74
|
+
await waitForGun();
|
|
75
|
+
|
|
76
|
+
// 2. Create and store multiple holograms pointing to the same data
|
|
77
|
+
const hologram1 = holoSphere.createHologram(testHolon, testLens, originalData);
|
|
78
|
+
const hologram2 = holoSphere.createHologram(testHolon, testLens, originalData);
|
|
79
|
+
|
|
80
|
+
await holoSphere.put(testHolon, otherLens, { ...hologram1, id: 'hologram-1' });
|
|
81
|
+
await holoSphere.put(testHolon, otherLens, { ...hologram2, id: 'hologram-2' });
|
|
82
|
+
await waitForGun(500);
|
|
83
|
+
|
|
84
|
+
// 3. Update the original data
|
|
85
|
+
const updatedData = { id: 'multi-hologram-test', value: 'Updated Value' };
|
|
86
|
+
await holoSphere.put(testHolon, testLens, updatedData);
|
|
87
|
+
await waitForGun(1000);
|
|
88
|
+
|
|
89
|
+
// 4. Check that both holograms have been updated
|
|
90
|
+
const updatedHologram1 = await holoSphere.get(testHolon, otherLens, 'hologram-1', null, { resolveHolograms: false });
|
|
91
|
+
const updatedHologram2 = await holoSphere.get(testHolon, otherLens, 'hologram-2', null, { resolveHolograms: false });
|
|
92
|
+
|
|
93
|
+
expect(updatedHologram1.updated).toBeDefined();
|
|
94
|
+
expect(updatedHologram2.updated).toBeDefined();
|
|
95
|
+
expect(typeof updatedHologram1.updated).toBe('number');
|
|
96
|
+
expect(typeof updatedHologram2.updated).toBe('number');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test('should not update deleted holograms', async () => {
|
|
100
|
+
// 1. Store original data
|
|
101
|
+
const originalData = { id: 'delete-test-item', value: 'Original Value' };
|
|
102
|
+
await holoSphere.put(testHolon, testLens, originalData);
|
|
103
|
+
await waitForGun();
|
|
104
|
+
|
|
105
|
+
// 2. Create and store a hologram
|
|
106
|
+
const hologram = holoSphere.createHologram(testHolon, testLens, originalData);
|
|
107
|
+
await holoSphere.put(testHolon, otherLens, hologram);
|
|
108
|
+
await waitForGun(500);
|
|
109
|
+
|
|
110
|
+
// 3. Delete the hologram
|
|
111
|
+
await holoSphere.delete(testHolon, otherLens, originalData.id);
|
|
112
|
+
await waitForGun(500);
|
|
113
|
+
|
|
114
|
+
// 4. Update the original data
|
|
115
|
+
const updatedData = { id: 'delete-test-item', value: 'Updated Value' };
|
|
116
|
+
await holoSphere.put(testHolon, testLens, updatedData);
|
|
117
|
+
await waitForGun(1000);
|
|
118
|
+
|
|
119
|
+
// 5. Verify the original data was updated
|
|
120
|
+
const retrievedData = await holoSphere.get(testHolon, testLens, originalData.id);
|
|
121
|
+
expect(retrievedData.value).toBe('Updated Value');
|
|
122
|
+
|
|
123
|
+
// 6. Verify the hologram was not updated (since it's deleted)
|
|
124
|
+
const deletedHologram = await holoSphere.get(testHolon, otherLens, originalData.id);
|
|
125
|
+
expect(deletedHologram).toBeNull(); // Should be null since it was deleted
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('should work with data that has no holograms', async () => {
|
|
129
|
+
// 1. Store data that has no holograms pointing to it
|
|
130
|
+
const originalData = { id: 'no-holograms-test', value: 'Original Value' };
|
|
131
|
+
await holoSphere.put(testHolon, testLens, originalData);
|
|
132
|
+
await waitForGun();
|
|
133
|
+
|
|
134
|
+
// 2. Update the data (should not cause errors even with no holograms)
|
|
135
|
+
const updatedData = { id: 'no-holograms-test', value: 'Updated Value' };
|
|
136
|
+
await holoSphere.put(testHolon, testLens, updatedData);
|
|
137
|
+
await waitForGun(1000);
|
|
138
|
+
|
|
139
|
+
// 3. Verify the data was updated successfully
|
|
140
|
+
const retrievedData = await holoSphere.get(testHolon, testLens, originalData.id);
|
|
141
|
+
expect(retrievedData.value).toBe('Updated Value');
|
|
142
|
+
});
|
|
143
|
+
});
|
package/test/hologram.test.js
CHANGED
|
@@ -297,7 +297,7 @@ describe('HoloSphere Reference System', () => {
|
|
|
297
297
|
const targetNodeRef = holoSphere.getNodeRef(targetSoul);
|
|
298
298
|
let hologramsSet = await new Promise(resolve => targetNodeRef.get('_holograms').once(resolve));
|
|
299
299
|
expect(hologramsSet).toBeDefined();
|
|
300
|
-
expect(hologramsSet[storedHologramSoul]).
|
|
300
|
+
expect(hologramsSet[storedHologramSoul]).toBeDefined(); // Hologram should be tracked initially
|
|
301
301
|
|
|
302
302
|
// 4. Delete the hologram
|
|
303
303
|
await holoSphere.delete(testHolon, 'otherLens', 'hologram-tracker-2');
|
|
@@ -307,9 +307,9 @@ describe('HoloSphere Reference System', () => {
|
|
|
307
307
|
// 5. Fetch the _holograms set again directly
|
|
308
308
|
hologramsSet = await new Promise(resolve => targetNodeRef.get('_holograms').once(resolve));
|
|
309
309
|
|
|
310
|
-
// 6. Verify the hologram's soul is
|
|
310
|
+
// 6. Verify the hologram's soul is completely removed (or set to null by Gun)
|
|
311
311
|
expect(hologramsSet).toBeDefined();
|
|
312
|
-
expect(hologramsSet[storedHologramSoul]).
|
|
312
|
+
expect(hologramsSet[storedHologramSoul]).toBeNull(); // Gun stores null when we put(null)
|
|
313
313
|
});
|
|
314
314
|
// --- End tests for _holograms tracking ---
|
|
315
315
|
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// meta-strip.test.js
|
|
2
|
+
|
|
3
|
+
import HoloSphere from '../holosphere.js';
|
|
4
|
+
|
|
5
|
+
describe('Meta Field Stripping Tests', () => {
|
|
6
|
+
let holoSphere;
|
|
7
|
+
const testHolon = 'testHolon';
|
|
8
|
+
const testLens = 'testLens';
|
|
9
|
+
const testGlobalTable = 'testGlobalTable';
|
|
10
|
+
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
holoSphere = new HoloSphere('test_app', false);
|
|
13
|
+
// Clean up before each test
|
|
14
|
+
try {
|
|
15
|
+
await holoSphere.deleteAll(testHolon, testLens);
|
|
16
|
+
await holoSphere.deleteAllGlobal(testGlobalTable);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
// Ignore cleanup errors
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Small wait for Gun to settle
|
|
22
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
23
|
+
}, 30000);
|
|
24
|
+
|
|
25
|
+
afterEach(async () => {
|
|
26
|
+
if (holoSphere) {
|
|
27
|
+
await holoSphere.close();
|
|
28
|
+
}
|
|
29
|
+
}, 30000);
|
|
30
|
+
|
|
31
|
+
describe('put() should strip _meta field', () => {
|
|
32
|
+
test('should not store _meta field when putting data', async () => {
|
|
33
|
+
const testData = {
|
|
34
|
+
id: 'test1',
|
|
35
|
+
name: 'Test Item',
|
|
36
|
+
value: 42,
|
|
37
|
+
_meta: {
|
|
38
|
+
resolvedFromHologram: true,
|
|
39
|
+
hologramSoul: 'app/holon/lens/key',
|
|
40
|
+
someOtherMeta: 'should not be stored'
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// Store the data (should strip _meta)
|
|
45
|
+
await holoSphere.put(testHolon, testLens, testData);
|
|
46
|
+
|
|
47
|
+
// Wait for Gun to settle
|
|
48
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
49
|
+
|
|
50
|
+
// Retrieve the data
|
|
51
|
+
const retrieved = await holoSphere.get(testHolon, testLens, testData.id);
|
|
52
|
+
|
|
53
|
+
// Verify data exists and _meta is not stored
|
|
54
|
+
expect(retrieved).not.toBeNull();
|
|
55
|
+
expect(retrieved.id).toBe(testData.id);
|
|
56
|
+
expect(retrieved.name).toBe(testData.name);
|
|
57
|
+
expect(retrieved.value).toBe(testData.value);
|
|
58
|
+
expect(retrieved._meta).toBeUndefined(); // _meta should not be stored
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('should handle data without _meta field normally', async () => {
|
|
62
|
+
const testData = {
|
|
63
|
+
id: 'test2',
|
|
64
|
+
name: 'Test Item Without Meta',
|
|
65
|
+
value: 99
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Store the data
|
|
69
|
+
await holoSphere.put(testHolon, testLens, testData);
|
|
70
|
+
|
|
71
|
+
// Wait for Gun to settle
|
|
72
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
73
|
+
|
|
74
|
+
// Retrieve the data
|
|
75
|
+
const retrieved = await holoSphere.get(testHolon, testLens, testData.id);
|
|
76
|
+
|
|
77
|
+
// Verify data exists and matches exactly
|
|
78
|
+
expect(retrieved).toEqual(testData);
|
|
79
|
+
expect(retrieved._meta).toBeUndefined();
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('putGlobal() should strip _meta field', () => {
|
|
84
|
+
test('should not store _meta field when putting global data', async () => {
|
|
85
|
+
const testData = {
|
|
86
|
+
id: 'globaltest1',
|
|
87
|
+
name: 'Global Test Item',
|
|
88
|
+
value: 123,
|
|
89
|
+
_meta: {
|
|
90
|
+
resolvedFromHologram: true,
|
|
91
|
+
hologramSoul: 'app/holon/lens/key',
|
|
92
|
+
federation: { origin: 'someholon' }
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// Store the global data (should strip _meta)
|
|
97
|
+
await holoSphere.putGlobal(testGlobalTable, testData);
|
|
98
|
+
|
|
99
|
+
// Wait for Gun to settle
|
|
100
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
101
|
+
|
|
102
|
+
// Retrieve the data
|
|
103
|
+
const retrieved = await holoSphere.getGlobal(testGlobalTable, testData.id);
|
|
104
|
+
|
|
105
|
+
// Verify data exists and _meta is not stored
|
|
106
|
+
expect(retrieved).not.toBeNull();
|
|
107
|
+
expect(retrieved.id).toBe(testData.id);
|
|
108
|
+
expect(retrieved.name).toBe(testData.name);
|
|
109
|
+
expect(retrieved.value).toBe(testData.value);
|
|
110
|
+
expect(retrieved._meta).toBeUndefined(); // _meta should not be stored
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test('should handle global data without _meta field normally', async () => {
|
|
114
|
+
const testData = {
|
|
115
|
+
id: 'globaltest2',
|
|
116
|
+
name: 'Global Test Item Without Meta',
|
|
117
|
+
value: 456
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// Store the global data
|
|
121
|
+
await holoSphere.putGlobal(testGlobalTable, testData);
|
|
122
|
+
|
|
123
|
+
// Wait for Gun to settle
|
|
124
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
125
|
+
|
|
126
|
+
// Retrieve the data
|
|
127
|
+
const retrieved = await holoSphere.getGlobal(testGlobalTable, testData.id);
|
|
128
|
+
|
|
129
|
+
// Verify data exists and matches exactly
|
|
130
|
+
expect(retrieved).toEqual(testData);
|
|
131
|
+
expect(retrieved._meta).toBeUndefined();
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test('should preserve _meta in original data object (not mutate input)', async () => {
|
|
136
|
+
const testData = {
|
|
137
|
+
id: 'test3',
|
|
138
|
+
name: 'Test Mutation',
|
|
139
|
+
_meta: {
|
|
140
|
+
resolvedFromHologram: true,
|
|
141
|
+
hologramSoul: 'app/holon/lens/key'
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// Store a copy to verify original isn't mutated
|
|
146
|
+
const originalMeta = { ...testData._meta };
|
|
147
|
+
|
|
148
|
+
// Store the data
|
|
149
|
+
await holoSphere.put(testHolon, testLens, testData);
|
|
150
|
+
|
|
151
|
+
// Verify the original object still has _meta (we shouldn't mutate the input)
|
|
152
|
+
expect(testData._meta).toBeDefined();
|
|
153
|
+
expect(testData._meta).toEqual(originalMeta);
|
|
154
|
+
|
|
155
|
+
// But the stored data should not have _meta
|
|
156
|
+
const retrieved = await holoSphere.get(testHolon, testLens, testData.id);
|
|
157
|
+
expect(retrieved._meta).toBeUndefined();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import HoloSphere from '../holosphere.js';
|
|
2
|
+
|
|
3
|
+
describe('Parent Propagation Tests', () => {
|
|
4
|
+
let holosphere;
|
|
5
|
+
const testPrefix = 'parent_prop_test_';
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
holosphere = new HoloSphere('parent-propagation-test');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
afterEach(async () => {
|
|
12
|
+
if (holosphere) {
|
|
13
|
+
await holosphere.close();
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe('propagate with parent propagation', () => {
|
|
18
|
+
test('should propagate to parent hexagons when holon is valid H3 hexagon', async () => {
|
|
19
|
+
// Create a valid H3 hexagon (resolution 7)
|
|
20
|
+
const childHexagon = '87283472bffffff'; // Example H3 hexagon at resolution 7
|
|
21
|
+
const parentHexagon = '86283472fffffff'; // Parent at resolution 6
|
|
22
|
+
|
|
23
|
+
// Test data
|
|
24
|
+
const testData = {
|
|
25
|
+
id: 'test-item-1',
|
|
26
|
+
title: 'Test Item',
|
|
27
|
+
value: 42
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// Propagate with parent propagation enabled
|
|
31
|
+
const result = await holosphere.propagate(childHexagon, 'items', testData, {
|
|
32
|
+
propagateToParents: true,
|
|
33
|
+
maxParentLevels: 5
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Check that parent propagation was attempted
|
|
37
|
+
expect(result.parentPropagation).toBeDefined();
|
|
38
|
+
expect(result.parentPropagation.success).toBeGreaterThan(0);
|
|
39
|
+
expect(result.parentPropagation.messages).toEqual(
|
|
40
|
+
expect.arrayContaining([expect.stringContaining('parent hexagons to propagate to')])
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// Allow time for propagation
|
|
44
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
45
|
+
|
|
46
|
+
// Verify data was propagated to parent hexagon (check for hologram, not resolved data)
|
|
47
|
+
const parentHologram = await holosphere.get(parentHexagon, 'items', testData.id, null, { resolveHolograms: false });
|
|
48
|
+
expect(parentHologram).toBeDefined();
|
|
49
|
+
expect(parentHologram._federation.propagationType).toBe('parent');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('should skip parent propagation for non-H3 hexagons', async () => {
|
|
53
|
+
// Use a non-H3 hexagon identifier
|
|
54
|
+
const nonHexagonHolon = 'not-a-hexagon';
|
|
55
|
+
|
|
56
|
+
const testData = {
|
|
57
|
+
id: 'test-item-2',
|
|
58
|
+
title: 'Test Item',
|
|
59
|
+
value: 42
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const result = await holosphere.propagate(nonHexagonHolon, 'items', testData, {
|
|
63
|
+
propagateToParents: true
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
expect(result.parentPropagation).toBeDefined();
|
|
67
|
+
expect(result.parentPropagation.skipped).toBe(1);
|
|
68
|
+
expect(result.parentPropagation.messages).toEqual(
|
|
69
|
+
expect.arrayContaining([expect.stringContaining('No parent hexagons found')])
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('should respect maxParentLevels option', async () => {
|
|
74
|
+
const childHexagon = '87283472bffffff'; // Resolution 7
|
|
75
|
+
|
|
76
|
+
const testData = {
|
|
77
|
+
id: 'test-item-3',
|
|
78
|
+
title: 'Test Item',
|
|
79
|
+
value: 42
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const result = await holosphere.propagate(childHexagon, 'items', testData, {
|
|
83
|
+
propagateToParents: true,
|
|
84
|
+
maxParentLevels: 2 // Only propagate to 2 parent levels
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
expect(result.parentPropagation).toBeDefined();
|
|
88
|
+
expect(result.parentPropagation.success).toBe(2); // Should propagate to 2 parent levels
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('should disable parent propagation when propagateToParents is false', async () => {
|
|
92
|
+
const childHexagon = '87283472bffffff';
|
|
93
|
+
|
|
94
|
+
const testData = {
|
|
95
|
+
id: 'test-item-4',
|
|
96
|
+
title: 'Test Item',
|
|
97
|
+
value: 42
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const result = await holosphere.propagate(childHexagon, 'items', testData, {
|
|
101
|
+
propagateToParents: false
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
expect(result.parentPropagation).toBeDefined();
|
|
105
|
+
expect(result.parentPropagation.success).toBe(0);
|
|
106
|
+
expect(result.parentPropagation.skipped).toBe(0);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('should include parent level information in federation metadata', async () => {
|
|
110
|
+
const childHexagon = '87283472bffffff'; // Resolution 7
|
|
111
|
+
const parentHexagon = '86283472fffffff'; // Resolution 6
|
|
112
|
+
|
|
113
|
+
const testData = {
|
|
114
|
+
id: 'test-item-5',
|
|
115
|
+
title: 'Test Item',
|
|
116
|
+
value: 42
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// First, store the original data in the child hexagon
|
|
120
|
+
await holosphere.put(childHexagon, 'items', testData);
|
|
121
|
+
|
|
122
|
+
// Then propagate to parent
|
|
123
|
+
await holosphere.propagate(childHexagon, 'items', testData, {
|
|
124
|
+
propagateToParents: true,
|
|
125
|
+
maxParentLevels: 1
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Allow time for propagation
|
|
129
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
130
|
+
|
|
131
|
+
// Check parent data has correct metadata (check for hologram, not resolved data)
|
|
132
|
+
const parentHologram = await holosphere.get(parentHexagon, 'items', testData.id, null, { resolveHolograms: false });
|
|
133
|
+
expect(parentHologram).toBeDefined();
|
|
134
|
+
expect(parentHologram._federation.propagationType).toBe('parent');
|
|
135
|
+
expect(parentHologram._federation.parentLevel).toBe(1); // 1 level up from resolution 7 to 6
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
});
|