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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "holosphere",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "description": "Holonic Geospatial Communication Infrastructure",
5
5
  "main": "holosphere.js",
6
6
  "types": "holosphere.d.ts",
@@ -14,14 +14,11 @@
14
14
  "license": "GPL-3.0-or-later",
15
15
  "dependencies": {
16
16
  "ajv": "^8.12.0",
17
- "axios": "^1.6.7",
18
- "dotenv": "^16.4.7",
19
17
  "gun": "^0.2020.1240",
20
18
  "h3-js": "^4.1.0",
21
19
  "openai": "^4.85.1"
22
20
  },
23
21
  "devDependencies": {
24
- "@babel/preset-env": "^7.24.0",
25
22
  "jest": "^29.7.0",
26
23
  "jest-environment-node": "^29.7.0"
27
24
  },
@@ -0,0 +1,225 @@
1
+ import HoloSphere from '../holosphere.js';
2
+ import { jest } from '@jest/globals';
3
+
4
+ // Configure Jest
5
+ jest.setTimeout(30000); // 30 second timeout
6
+
7
+ describe('HoloSphere Deletion Tests', () => {
8
+ const testAppName = 'test-app-deletion';
9
+ const testHolon = 'testHolonDeletion';
10
+ const testLens = 'testLensDeletion';
11
+ const testGlobalTable = 'testGlobalTable';
12
+ const testPassword = 'testPassword1234';
13
+ let holoSphere;
14
+
15
+ beforeAll(async () => {
16
+ holoSphere = new HoloSphere(testAppName, false, null);
17
+ });
18
+
19
+ afterAll(async () => {
20
+ // Clean up all test data
21
+ await holoSphere.deleteAll(testHolon, testLens);
22
+ await holoSphere.deleteAllGlobal(testGlobalTable);
23
+
24
+ // Close Gun connections
25
+ if (holoSphere) {
26
+ await holoSphere.close();
27
+ }
28
+
29
+ // Wait for connections to close
30
+ await new Promise(resolve => setTimeout(resolve, 1000));
31
+ });
32
+
33
+ describe('Basic Deletion', () => {
34
+ test('should delete a single item properly', async () => {
35
+ // Create test data
36
+ const testData = { id: 'delete-test-1', value: 'delete me' };
37
+
38
+ // Store data
39
+ await holoSphere.put(testHolon, testLens, testData);
40
+
41
+ // Verify data exists
42
+ const storedData = await holoSphere.get(testHolon, testLens, testData.id);
43
+ expect(storedData).toBeDefined();
44
+ expect(storedData.value).toBe(testData.value);
45
+
46
+ // Delete data
47
+ const deleteResult = await holoSphere.delete(testHolon, testLens, testData.id);
48
+ expect(deleteResult).toBe(true);
49
+
50
+ // Verify data is deleted
51
+ const deletedData = await holoSphere.get(testHolon, testLens, testData.id);
52
+ expect(deletedData).toBeNull();
53
+ });
54
+
55
+ test('should delete a node properly', async () => {
56
+ // Create test node data
57
+ const nodeData = { value: 'node-to-delete' };
58
+ const nodeKey = 'test-node-key';
59
+
60
+ // Store node
61
+ await holoSphere.putNode(testHolon, testLens, { id: nodeKey, value: nodeData });
62
+
63
+ // Verify node exists
64
+ const storedNode = await holoSphere.getNode(testHolon, testLens, 'value');
65
+ expect(storedNode).toBeDefined();
66
+
67
+ // Delete node
68
+ const deleteResult = await holoSphere.deleteNode(testHolon, testLens, 'value');
69
+ expect(deleteResult).toBe(true);
70
+
71
+ // Verify node is deleted
72
+ const deletedNode = await holoSphere.getNode(testHolon, testLens, 'value');
73
+ expect(deletedNode).toBeNull();
74
+ });
75
+ });
76
+
77
+ describe('Bulk Deletion', () => {
78
+ test('should delete all items in a lens', async () => {
79
+ // Create multiple test items
80
+ const items = [
81
+ { id: 'bulk-delete-1', value: 'bulk 1' },
82
+ { id: 'bulk-delete-2', value: 'bulk 2' },
83
+ { id: 'bulk-delete-3', value: 'bulk 3' }
84
+ ];
85
+
86
+ // Store all items
87
+ for (const item of items) {
88
+ await holoSphere.put(testHolon, testLens, item);
89
+ }
90
+
91
+ // Verify items exist
92
+ const allItems = await holoSphere.getAll(testHolon, testLens);
93
+ expect(allItems.length).toBeGreaterThanOrEqual(items.length);
94
+
95
+ // Delete all items
96
+ const deleteAllResult = await holoSphere.deleteAll(testHolon, testLens);
97
+ expect(deleteAllResult).toBe(true);
98
+
99
+ // Verify all items are deleted
100
+ const remainingItems = await holoSphere.getAll(testHolon, testLens);
101
+ expect(remainingItems.length).toBe(0);
102
+ });
103
+ });
104
+
105
+ describe('Global Table Deletion', () => {
106
+ test('should delete global items properly', async () => {
107
+ // Create global test data
108
+ const globalData = { id: 'global-delete-test', value: 'global delete me' };
109
+
110
+ // Store global data
111
+ await holoSphere.putGlobal(testGlobalTable, globalData);
112
+
113
+ // Verify global data exists
114
+ const storedGlobalData = await holoSphere.getGlobal(testGlobalTable, globalData.id);
115
+ expect(storedGlobalData).toBeDefined();
116
+ expect(storedGlobalData.value).toBe(globalData.value);
117
+
118
+ // Delete global data
119
+ const deleteResult = await holoSphere.deleteGlobal(testGlobalTable, globalData.id);
120
+ expect(deleteResult).toBe(true);
121
+
122
+ // Verify global data is deleted
123
+ const deletedGlobalData = await holoSphere.getGlobal(testGlobalTable, globalData.id);
124
+ expect(deletedGlobalData).toBeNull();
125
+ });
126
+
127
+ test('should delete all global items in a table', async () => {
128
+ // Create multiple global test items
129
+ const items = [
130
+ { id: 'global-bulk-1', value: 'global bulk 1' },
131
+ { id: 'global-bulk-2', value: 'global bulk 2' },
132
+ { id: 'global-bulk-3', value: 'global bulk 3' }
133
+ ];
134
+
135
+ // Store all global items
136
+ for (const item of items) {
137
+ await holoSphere.putGlobal(testGlobalTable, item);
138
+ }
139
+
140
+ // Verify global items exist
141
+ const allGlobalItems = await holoSphere.getAllGlobal(testGlobalTable);
142
+ expect(allGlobalItems.length).toBeGreaterThanOrEqual(items.length);
143
+
144
+ // Delete all global items
145
+ const deleteAllResult = await holoSphere.deleteAllGlobal(testGlobalTable);
146
+ expect(deleteAllResult).toBe(true);
147
+
148
+ // Verify all global items are deleted
149
+ const remainingGlobalItems = await holoSphere.getAllGlobal(testGlobalTable);
150
+ expect(remainingGlobalItems.length).toBe(0);
151
+ });
152
+ });
153
+
154
+ describe('Private Data Deletion', () => {
155
+ test('should delete private data properly', async () => {
156
+ // Create private test data
157
+ const privateData = { id: 'private-delete-test', value: 'private delete me' };
158
+
159
+ // Store private data
160
+ await holoSphere.put(testHolon, testLens, privateData, testPassword);
161
+
162
+ // Verify private data exists
163
+ const storedPrivateData = await holoSphere.get(testHolon, testLens, privateData.id, testPassword);
164
+ expect(storedPrivateData).toBeDefined();
165
+ expect(storedPrivateData.value).toBe(privateData.value);
166
+
167
+ // Delete private data
168
+ const deleteResult = await holoSphere.delete(testHolon, testLens, privateData.id, testPassword);
169
+ expect(deleteResult).toBe(true);
170
+
171
+ // Verify private data is deleted
172
+ const deletedPrivateData = await holoSphere.get(testHolon, testLens, privateData.id, testPassword);
173
+ expect(deletedPrivateData).toBeNull();
174
+ });
175
+
176
+ test('should delete all private items in a lens', async () => {
177
+ // Create multiple private test items
178
+ const items = [
179
+ { id: 'private-bulk-1', value: 'private bulk 1' },
180
+ { id: 'private-bulk-2', value: 'private bulk 2' },
181
+ { id: 'private-bulk-3', value: 'private bulk 3' }
182
+ ];
183
+
184
+ // Store all private items
185
+ for (const item of items) {
186
+ await holoSphere.put(testHolon, testLens, item, testPassword);
187
+ }
188
+
189
+ // Verify private items exist
190
+ const allPrivateItems = await holoSphere.getAll(testHolon, testLens, testPassword);
191
+ expect(allPrivateItems.length).toBeGreaterThanOrEqual(items.length);
192
+
193
+ // Delete all private items
194
+ const deleteAllResult = await holoSphere.deleteAll(testHolon, testLens, testPassword);
195
+ expect(deleteAllResult).toBe(true);
196
+
197
+ // Verify all private items are deleted
198
+ const remainingPrivateItems = await holoSphere.getAll(testHolon, testLens, testPassword);
199
+ expect(remainingPrivateItems.length).toBe(0);
200
+ });
201
+ });
202
+
203
+ describe('Edge Cases', () => {
204
+ test('should handle deletion of non-existent items gracefully', async () => {
205
+ // Try to delete non-existent item
206
+ const deleteResult = await holoSphere.delete(testHolon, testLens, 'non-existent-id');
207
+ expect(deleteResult).toBe(true); // Gun returns success even for non-existent items
208
+
209
+ // Try to delete non-existent global item
210
+ const deleteGlobalResult = await holoSphere.deleteGlobal(testGlobalTable, 'non-existent-global-id');
211
+ expect(deleteGlobalResult).toBe(true);
212
+ });
213
+
214
+ test('should handle invalid parameters gracefully', async () => {
215
+ // Test with missing parameters
216
+ await expect(holoSphere.delete(null, testLens, 'test-id')).rejects.toThrow();
217
+ await expect(holoSphere.delete(testHolon, null, 'test-id')).rejects.toThrow();
218
+ await expect(holoSphere.delete(testHolon, testLens, null)).rejects.toThrow();
219
+
220
+ // Test with missing global parameters
221
+ await expect(holoSphere.deleteGlobal(null, 'test-id')).rejects.toThrow();
222
+ await expect(holoSphere.deleteGlobal(testGlobalTable, null)).rejects.toThrow();
223
+ });
224
+ });
225
+ });
@@ -1,6 +1,9 @@
1
1
  import HoloSphere from '../holosphere.js';
2
2
  import { jest } from '@jest/globals';
3
3
 
4
+ // Increase the default test timeout for all tests
5
+ jest.setTimeout(30000);
6
+
4
7
  describe('Federation Tests', () => {
5
8
  let holosphere;
6
9
  const testPrefix = `test_${Date.now()}_`;
@@ -36,6 +39,50 @@ describe('Federation Tests', () => {
36
39
  }
37
40
  });
38
41
 
42
+ test('should set up the correct notification structure', async () => {
43
+ const space1 = `${testPrefix}notify_space1`;
44
+ const space2 = `${testPrefix}notify_space2`;
45
+
46
+ // Create federation
47
+ await holosphere.federate(space1, space2, null, null);
48
+
49
+ // Allow time for federation to be created
50
+ await new Promise(resolve => setTimeout(resolve, 1000));
51
+
52
+ // In the current implementation:
53
+ // space1's federation list should contain space2
54
+ // space2's notify list should contain space1
55
+ const fedInfo1 = await holosphere.getGlobal('federation', space1);
56
+ expect(fedInfo1).toBeTruthy();
57
+ expect(fedInfo1.federation).toContain(space2);
58
+
59
+ const fedInfo2 = await holosphere.getGlobal('federation', space2);
60
+ expect(fedInfo2).toBeTruthy();
61
+ expect(fedInfo2.notify).toContain(space1);
62
+ });
63
+
64
+ test('should respect unidirectional settings', async () => {
65
+ const space1 = `${testPrefix}one_way_space1`;
66
+ const space2 = `${testPrefix}one_way_space2`;
67
+
68
+ // Create federation with bidirectional=false
69
+ await holosphere.federate(space1, space2, null, null, false);
70
+
71
+ // Allow time for federation to be created
72
+ await new Promise(resolve => setTimeout(resolve, 1000));
73
+
74
+ // Verify federation structure:
75
+ // space1 has space2 in federation list
76
+ // space2 has space1 in notify list (this is different from the original test)
77
+ const fedInfo1 = await holosphere.getGlobal('federation', space1);
78
+ expect(fedInfo1).toBeTruthy();
79
+ expect(fedInfo1.federation).toContain(space2);
80
+
81
+ const fedInfo2 = await holosphere.getGlobal('federation', space2);
82
+ expect(fedInfo2).toBeTruthy();
83
+ expect(fedInfo2.notify).toContain(space1);
84
+ });
85
+
39
86
  test('should throw error when trying to federate a space with itself', async () => {
40
87
  const space = `${testPrefix}self_fed_space`;
41
88
  await expect(holosphere.federate(space, space, null))
@@ -107,16 +154,17 @@ describe('Federation Tests', () => {
107
154
  });
108
155
  });
109
156
 
110
- describe('propagateToFederation', () => {
157
+ describe('propagate', () => {
111
158
  test('should handle propagation to non-federated space gracefully', async () => {
112
159
  const space = `${testPrefix}no_fed_space`;
113
160
  const data = { id: 'test-item', value: 42 };
114
161
 
115
162
  // Try to propagate to a space with no federation
116
- const result = await holosphere.propagateToFederation(space, 'items', data);
163
+ const result = await holosphere.propagate(space, 'items', data);
117
164
 
118
165
  // Should have a message property but not fail
119
166
  expect(result).toBeDefined();
167
+ expect(result.message).toBeDefined();
120
168
  });
121
169
  });
122
170
  });
package/config/default.js DELETED
@@ -1 +0,0 @@
1
-
@@ -1,253 +0,0 @@
1
- import axios from 'axios';
2
- import dotenv from 'dotenv';
3
-
4
- dotenv.config();
5
-
6
- const logError = (service, error) => {
7
- const status = error.response?.status;
8
- const message = error.response?.data?.message || error.message;
9
- console.error(`${service} API Error:`, { status, message });
10
- };
11
-
12
- /**
13
- * Fetch Carbon Sequestration Data (Using NASA POWER API)
14
- */
15
- export async function getCarbonSequestration(lat = 41.9, lon = 12.5) {
16
- try {
17
- const response = await axios.default.get(
18
- `https://power.larc.nasa.gov/api/temporal/daily/point?parameters=T2M,PRECTOT,PS,WS2M&community=RE&longitude=${lon}&latitude=${lat}&start=20230101&end=20231231&format=JSON`
19
- );
20
- return response.data;
21
- } catch (error) {
22
- logError('Carbon Sequestration', error);
23
- return null;
24
- }
25
- }
26
-
27
- /**
28
- * Fetch Soil Carbon Data (Using ISRIC World Soil Information)
29
- */
30
- export async function getSoilCarbon(lat = 41.9, lon = 12.5) {
31
- try {
32
- const response = await axios.default.get(
33
- `https://rest.isric.org/soilgrids/v2.0/properties/query?lat=${lat}&lon=${lon}&property=soc&depth=0-30cm&value=mean`
34
- );
35
- return response.data;
36
- } catch (error) {
37
- logError('Soil Carbon', error);
38
- return null;
39
- }
40
- }
41
-
42
- /**
43
- * Fetch Biodiversity Data (GBIF API)
44
- */
45
- export async function getBiodiversityData(countryCode = "ITA") {
46
- try {
47
- const response = await axios.default.get(`https://api.gbif.org/v1/occurrence/search?country=${countryCode}&limit=100`);
48
- return response.data;
49
- } catch (error) {
50
- logError('Biodiversity', error);
51
- return null;
52
- }
53
- }
54
-
55
- /**
56
- * Fetch Vegetation Cover Data (Using NASA MODIS Vegetation Index)
57
- */
58
- export async function getVegetationCover(lat = 41.9, lon = 12.5) {
59
- try {
60
- const response = await axios.default.get(
61
- `https://modis.ornl.gov/rst/api/v1/MOD13Q1/subset?latitude=${lat}&longitude=${lon}&band=NDVI&startDate=2023-01-01&endDate=2023-12-31`,
62
- {
63
- headers: {
64
- 'Accept': 'application/json'
65
- }
66
- }
67
- );
68
- return response.data;
69
- } catch (error) {
70
- logError('Vegetation Cover', error);
71
- return null;
72
- }
73
- }
74
-
75
- /**
76
- * Fetch Air Quality Data (OpenWeather API)
77
- */
78
- export async function getAirQuality(lat = 41.9, lon = 12.5) {
79
- try {
80
- const response = await axios.default.get(
81
- `https://api.openweathermap.org/data/2.5/air_pollution?lat=${lat}&lon=${lon}&appid=${process.env.OPENWEATHER_API_KEY}`
82
- );
83
- return response.data;
84
- } catch (error) {
85
- logError('Air Quality', error);
86
- return null;
87
- }
88
- }
89
-
90
- /**
91
- * Fetch Water Retention Data (Using USGS Water Services)
92
- */
93
- export async function getWaterRetention(lat = 41.9, lon = 12.5) {
94
- try {
95
- const response = await axios.default.get(
96
- `https://waterservices.usgs.gov/nwis/iv/?format=json&sites=11447650&siteStatus=active`,
97
- {
98
- headers: {
99
- 'Accept': 'application/json'
100
- }
101
- }
102
- );
103
- return response.data;
104
- } catch (error) {
105
- logError('Water Retention', error);
106
- return null;
107
- }
108
- }
109
-
110
- /**
111
- * Fetch Deforestation Data (Using World Bank Forest Data)
112
- */
113
- export async function getDeforestationData(countryCode = "ITA") {
114
- try {
115
- const response = await axios.default.get(
116
- `https://api.worldbank.org/v2/country/${countryCode}/indicator/AG.LND.FRST.ZS?format=json`
117
- );
118
- return response.data;
119
- } catch (error) {
120
- logError('Deforestation', error);
121
- return null;
122
- }
123
- }
124
-
125
- /**
126
- * Fetch Flood Risk Data (Using USGS Water Services)
127
- */
128
- export async function getFloodRisk(lat = 41.9, lon = 12.5) {
129
- try {
130
- const response = await axios.default.get(
131
- `https://waterservices.usgs.gov/nwis/iv/?format=json&stateCd=CA&parameterCd=00065&siteStatus=active`,
132
- {
133
- headers: {
134
- 'Accept': 'application/json'
135
- }
136
- }
137
- );
138
- return response.data;
139
- } catch (error) {
140
- logError('Flood Risk', error);
141
- return null;
142
- }
143
- }
144
-
145
- /**
146
- * Fetch Food Security Data (World Bank API)
147
- */
148
- export async function getFoodSecurity(countryCode = "ITA") {
149
- try {
150
- const response = await axios.default.get(
151
- `https://api.worldbank.org/v2/country/${countryCode}/indicator/SN.ITK.DEFC.ZS?format=json`
152
- );
153
- return response.data;
154
- } catch (error) {
155
- logError('Food Security', error);
156
- return null;
157
- }
158
- }
159
-
160
- /**
161
- * Fetch Local Employment Rate (World Bank API)
162
- */
163
- export async function getEmploymentRate(countryCode = "ITA") {
164
- try {
165
- const response = await axios.default.get(
166
- `https://api.worldbank.org/v2/country/${countryCode}/indicator/SL.EMP.TOTL.SP.ZS?format=json`
167
- );
168
- return response.data;
169
- } catch (error) {
170
- logError('Employment Rate', error);
171
- return null;
172
- }
173
- }
174
-
175
- /**
176
- * Fetch Governance Score (World Bank API)
177
- */
178
- export async function getTransparencyScore(countryCode = "ITA") {
179
- try {
180
- const response = await axios.default.get(
181
- `https://api.worldbank.org/v2/country/${countryCode}/indicator/GE.EST?format=json`
182
- );
183
- return response.data;
184
- } catch (error) {
185
- logError('Transparency Score', error);
186
- return null;
187
- }
188
- }
189
-
190
- /**
191
- * Fetch Blockchain Transactions (Etherscan API)
192
- */
193
- export async function getBlockchainTransactions(address = "0x0000000000000000000000000000000000000000") {
194
- try {
195
- const response = await axios.default.get(
196
- `https://api.etherscan.io/api?module=account&action=txlist&address=${address}&startblock=0&endblock=99999999&sort=desc&apikey=${process.env.ETHERSCAN_API_KEY}`
197
- );
198
- return response.data;
199
- } catch (error) {
200
- logError('Blockchain Transactions', error);
201
- return null;
202
- }
203
- }
204
-
205
- /**
206
- * Fetch Circular Economy Data (Using World Bank Development Indicators)
207
- */
208
- export async function getCircularEconomyData(countryCode = "ITA") {
209
- try {
210
- const response = await axios.default.get(
211
- `https://api.worldbank.org/v2/country/${countryCode}/indicator/EN.ATM.GHGT.KT.CE?format=json`
212
- );
213
- return response.data;
214
- } catch (error) {
215
- logError('Circular Economy', error);
216
- return null;
217
- }
218
- }
219
-
220
- /**
221
- * Fetch Renewable Energy Data (World Bank API)
222
- */
223
- export async function getRenewableEnergyData(countryCode = "ITA") {
224
- try {
225
- const response = await axios.default.get(
226
- `https://api.worldbank.org/v2/country/${countryCode}/indicator/EG.FEC.RNEW.ZS?format=json`
227
- );
228
- return response.data;
229
- } catch (error) {
230
- logError('Renewable Energy', error);
231
- return null;
232
- }
233
- }
234
-
235
- /**
236
- * Fetch Climate Change Data (NOAA Climate API)
237
- */
238
- export async function getClimateChangeData(lat = 41.9, lon = 12.5) {
239
- try {
240
- const response = await axios.default.get(
241
- `https://www.ncdc.noaa.gov/cdo-web/api/v2/data?datasetid=GHCND&latitude=${lat}&longitude=${lon}&startdate=2023-01-01&enddate=2023-12-31&limit=1000`,
242
- {
243
- headers: {
244
- 'token': process.env.NOAA_API_KEY
245
- }
246
- }
247
- );
248
- return response.data;
249
- } catch (error) {
250
- logError('Climate Change', error);
251
- return null;
252
- }
253
- }