holosphere 1.0.8 → 1.1.0
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/README.md +268 -113
- package/holosphere.d.ts +23 -24
- package/holosphere.js +483 -317
- package/package.json +1 -1
- package/test/holosphere.test.js +224 -109
package/package.json
CHANGED
package/test/holosphere.test.js
CHANGED
|
@@ -12,14 +12,14 @@ describe('HoloSphere', () => {
|
|
|
12
12
|
describe('Constructor', () => {
|
|
13
13
|
test('should create instance with app name', () => {
|
|
14
14
|
expect(holoSphere).toBeInstanceOf(HoloSphere);
|
|
15
|
-
expect(holoSphere.
|
|
15
|
+
expect(holoSphere.gun).toBeDefined();
|
|
16
16
|
expect(holoSphere.validator).toBeDefined();
|
|
17
|
-
expect(holoSphere.
|
|
17
|
+
expect(holoSphere.openai).toBeUndefined();
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
test('should initialize with OpenAI when key provided', () => {
|
|
21
|
-
const hsWithAI = new HoloSphere(testAppName, 'fake-key');
|
|
22
|
-
expect(hsWithAI.
|
|
21
|
+
const hsWithAI = new HoloSphere(testAppName, false, 'fake-key');
|
|
22
|
+
expect(hsWithAI.openai).toBeDefined();
|
|
23
23
|
});
|
|
24
24
|
});
|
|
25
25
|
|
|
@@ -34,132 +34,247 @@ describe('HoloSphere', () => {
|
|
|
34
34
|
required: ['id', 'data']
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
test('should set and get
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
expect(
|
|
37
|
+
test('should set and get schema', async () => {
|
|
38
|
+
// Set the schema
|
|
39
|
+
const setResult = await holoSphere.setSchema(testLens, validSchema);
|
|
40
|
+
expect(setResult).toBe(true);
|
|
41
|
+
|
|
42
|
+
// Wait for GunDB to process
|
|
43
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
44
|
+
|
|
45
|
+
// Get and verify the schema
|
|
46
|
+
const retrievedSchema = await holoSphere.getSchema(testLens);
|
|
47
|
+
expect(retrievedSchema).toBeDefined();
|
|
48
|
+
expect(retrievedSchema).toEqual(validSchema);
|
|
49
|
+
}, 5000);
|
|
50
|
+
|
|
51
|
+
test('should handle invalid schema parameters', async () => {
|
|
52
|
+
const nullResult = await holoSphere.setSchema(null, null);
|
|
53
|
+
expect(nullResult).toBe(false);
|
|
54
|
+
|
|
55
|
+
const missingLensResult = await holoSphere.setSchema(undefined, validSchema);
|
|
56
|
+
expect(missingLensResult).toBe(false);
|
|
57
|
+
|
|
58
|
+
const missingSchemaResult = await holoSphere.setSchema(testLens, null);
|
|
59
|
+
expect(missingSchemaResult).toBe(false);
|
|
41
60
|
});
|
|
42
61
|
|
|
43
|
-
test('should
|
|
44
|
-
const
|
|
45
|
-
|
|
62
|
+
test('should enforce strict mode schema validation', async () => {
|
|
63
|
+
const strictHoloSphere = new HoloSphere(testAppName, true);
|
|
64
|
+
|
|
65
|
+
// Test cases for invalid schemas
|
|
66
|
+
const invalidSchemas = [
|
|
67
|
+
{
|
|
68
|
+
// Missing type field
|
|
69
|
+
properties: {
|
|
70
|
+
id: { type: 'string' }
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
// Missing properties
|
|
75
|
+
type: 'object'
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
// Missing required fields
|
|
79
|
+
type: 'object',
|
|
80
|
+
properties: {
|
|
81
|
+
id: { type: 'string' }
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
// Invalid property type
|
|
86
|
+
type: 'object',
|
|
87
|
+
properties: {
|
|
88
|
+
id: { type: 123 } // Should be string
|
|
89
|
+
},
|
|
90
|
+
required: ['id']
|
|
91
|
+
}
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
// Test each invalid schema
|
|
95
|
+
for (const invalidSchema of invalidSchemas) {
|
|
96
|
+
const setResult = await strictHoloSphere.setSchema(testLens, invalidSchema);
|
|
97
|
+
expect(setResult).toBe(false);
|
|
98
|
+
}
|
|
46
99
|
|
|
47
|
-
|
|
100
|
+
// Valid schema should work in strict mode
|
|
101
|
+
const validSchema = {
|
|
102
|
+
type: 'object',
|
|
103
|
+
properties: {
|
|
104
|
+
id: { type: 'string' },
|
|
105
|
+
data: { type: 'string' }
|
|
106
|
+
},
|
|
107
|
+
required: ['id', 'data']
|
|
108
|
+
};
|
|
48
109
|
|
|
49
|
-
const validResult =
|
|
110
|
+
const validResult = await strictHoloSphere.setSchema(testLens, validSchema);
|
|
50
111
|
expect(validResult).toBe(true);
|
|
51
112
|
|
|
52
|
-
|
|
53
|
-
|
|
113
|
+
// Verify schema was stored correctly
|
|
114
|
+
const retrievedSchema = await strictHoloSphere.getSchema(testLens);
|
|
115
|
+
expect(retrievedSchema).toEqual(validSchema);
|
|
116
|
+
}, 5000);
|
|
117
|
+
|
|
118
|
+
test('should handle schema retrieval for non-existent lens', async () => {
|
|
119
|
+
const result = await holoSphere.getSchema('nonexistent-lens');
|
|
120
|
+
expect(result).toBeNull();
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
afterEach(async () => {
|
|
124
|
+
// Clean up schemas after each test
|
|
125
|
+
await holoSphere.gun.get(holoSphere.appname)
|
|
126
|
+
.get(testLens)
|
|
127
|
+
.get('schema')
|
|
128
|
+
.put(null);
|
|
129
|
+
|
|
130
|
+
// Wait for GunDB to process
|
|
131
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
54
132
|
});
|
|
55
133
|
});
|
|
56
134
|
|
|
57
135
|
describe('Data Operations', () => {
|
|
58
|
-
const
|
|
136
|
+
const testHolon = h3.latLngToCell(40.7128, -74.0060, 7);
|
|
59
137
|
const testLens = 'testLens';
|
|
60
|
-
const
|
|
138
|
+
const validData = { id: 'test123', data: 'test data' };
|
|
139
|
+
const invalidData = { id: 'test456', wrongField: 'wrong data' };
|
|
61
140
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
141
|
+
beforeEach(async () => {
|
|
142
|
+
// Set up schema for validation tests
|
|
143
|
+
const schema = {
|
|
144
|
+
type: 'object',
|
|
145
|
+
properties: {
|
|
146
|
+
id: { type: 'string' },
|
|
147
|
+
data: { type: 'string' }
|
|
148
|
+
},
|
|
149
|
+
required: ['id', 'data']
|
|
150
|
+
};
|
|
151
|
+
await holoSphere.setSchema(testLens, schema);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test('should put and get data with schema validation', async () => {
|
|
155
|
+
// Test valid data
|
|
156
|
+
const putResult = await holoSphere.put(testHolon, testLens, validData);
|
|
157
|
+
expect(putResult).toBe(true);
|
|
158
|
+
|
|
159
|
+
const getResult = await holoSphere.get(testHolon, testLens, validData.id);
|
|
160
|
+
expect(getResult).toEqual(validData);
|
|
161
|
+
|
|
162
|
+
// Test invalid data
|
|
163
|
+
const invalidPutResult = await holoSphere.put(testHolon, testLens, invalidData);
|
|
164
|
+
expect(invalidPutResult).toBe(false);
|
|
67
165
|
}, 10000);
|
|
68
166
|
|
|
69
|
-
test('should get
|
|
70
|
-
await holoSphere.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
167
|
+
test('should get all data with schema validation', async () => {
|
|
168
|
+
await holoSphere.put(testHolon, testLens, validData);
|
|
169
|
+
await holoSphere.put(testHolon, testLens, { id: 'test789', data: 'more test data' });
|
|
170
|
+
|
|
171
|
+
const results = await holoSphere.getAll(testHolon, testLens);
|
|
172
|
+
expect(Array.isArray(results)).toBeTruthy();
|
|
173
|
+
expect(results.length).toBeGreaterThan(0);
|
|
174
|
+
expect(results.some(item => item.id === validData.id)).toBeTruthy();
|
|
74
175
|
}, 10000);
|
|
75
176
|
|
|
76
|
-
test('should delete
|
|
77
|
-
await holoSphere.
|
|
78
|
-
await holoSphere.
|
|
79
|
-
|
|
177
|
+
test('should delete data', async () => {
|
|
178
|
+
await holoSphere.put(testHolon, testLens, validData);
|
|
179
|
+
await holoSphere.delete(testHolon, testLens, validData.id);
|
|
180
|
+
|
|
181
|
+
const result = await holoSphere.get(testHolon, testLens, validData.id);
|
|
80
182
|
expect(result).toBeNull();
|
|
81
183
|
}, 10000);
|
|
82
|
-
});
|
|
83
184
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
185
|
+
test('should delete all data', async () => {
|
|
186
|
+
await holoSphere.put(testHolon, testLens, validData);
|
|
187
|
+
await holoSphere.put(testHolon, testLens, { id: 'test789', data: 'more test data' });
|
|
188
|
+
|
|
189
|
+
const deleteResult = await holoSphere.deleteAll(testHolon, testLens);
|
|
190
|
+
expect(deleteResult).toBe(true);
|
|
191
|
+
|
|
192
|
+
const results = await holoSphere.getAll(testHolon, testLens);
|
|
193
|
+
expect(results).toEqual([]);
|
|
194
|
+
}, 10000);
|
|
87
195
|
|
|
88
|
-
test('should
|
|
89
|
-
|
|
90
|
-
// Add delay to allow Gun to process
|
|
91
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
196
|
+
test('should enforce strict mode data validation', async () => {
|
|
197
|
+
const strictHoloSphere = new HoloSphere(testAppName, true);
|
|
92
198
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
199
|
+
// Define schema for strict mode tests
|
|
200
|
+
const strictSchema = {
|
|
201
|
+
type: 'object',
|
|
202
|
+
properties: {
|
|
203
|
+
id: { type: 'string' },
|
|
204
|
+
data: { type: 'string' }
|
|
205
|
+
},
|
|
206
|
+
required: ['id', 'data']
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// Set up schema
|
|
210
|
+
await strictHoloSphere.setSchema(testLens, strictSchema);
|
|
211
|
+
|
|
212
|
+
// Try to put data without schema in strict mode
|
|
213
|
+
const noSchemaResult = await strictHoloSphere.put(testHolon, 'no-schema-lens', validData);
|
|
214
|
+
expect(noSchemaResult).toBe(false);
|
|
215
|
+
|
|
216
|
+
// Try to get data without schema in strict mode
|
|
217
|
+
const noSchemaData = await strictHoloSphere.getAll(testHolon, 'no-schema-lens');
|
|
218
|
+
expect(noSchemaData).toEqual([]);
|
|
219
|
+
|
|
220
|
+
// Invalid data should be removed in strict mode
|
|
221
|
+
await strictHoloSphere.put(testHolon, testLens, invalidData);
|
|
222
|
+
const results = await strictHoloSphere.getAll(testHolon, testLens);
|
|
223
|
+
expect(results.some(item => item.id === invalidData.id)).toBe(false);
|
|
224
|
+
}, 10000);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
describe('Node Operations', () => {
|
|
228
|
+
const testHolon = h3.latLngToCell(40.7128, -74.0060, 7);
|
|
229
|
+
const testLens = 'testLens';
|
|
230
|
+
const testNode = { value: 'test node data' };
|
|
99
231
|
|
|
100
|
-
test('should
|
|
101
|
-
await holoSphere.
|
|
102
|
-
|
|
103
|
-
|
|
232
|
+
test('should put and get node', async () => {
|
|
233
|
+
await holoSphere.putNode(testHolon, testLens, testNode);
|
|
234
|
+
|
|
235
|
+
// Wait for GunDB to process
|
|
236
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
104
237
|
|
|
105
|
-
const result = await holoSphere.
|
|
238
|
+
const result = await holoSphere.getNode(testHolon, testLens, 'value');
|
|
106
239
|
expect(result).toBeDefined();
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
}, 15000);
|
|
240
|
+
expect(result).toBe('test node data');
|
|
241
|
+
}, 10000);
|
|
111
242
|
|
|
112
|
-
test('should delete
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
await new Promise(resolve => setTimeout(resolve,
|
|
243
|
+
test('should delete node', async () => {
|
|
244
|
+
// First put the node
|
|
245
|
+
await holoSphere.putNode(testHolon, testLens, testNode);
|
|
246
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
116
247
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
248
|
+
// Verify node exists
|
|
249
|
+
const beforeDelete = await holoSphere.getNode(testHolon, testLens, 'value');
|
|
250
|
+
expect(beforeDelete).toBe('test node data');
|
|
120
251
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
252
|
+
// Delete the node
|
|
253
|
+
const deleteResult = await holoSphere.deleteNode(testHolon, testLens, 'value');
|
|
254
|
+
expect(deleteResult).toBe(true);
|
|
255
|
+
|
|
256
|
+
// Wait for deletion to process
|
|
257
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
258
|
+
|
|
259
|
+
// Verify node is deleted
|
|
260
|
+
const afterDelete = await holoSphere.getNode(testHolon, testLens, 'value');
|
|
261
|
+
expect(afterDelete).toBeNull();
|
|
262
|
+
}, 10000);
|
|
131
263
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
264
|
+
test('should handle invalid node operations', async () => {
|
|
265
|
+
// Test missing parameters
|
|
266
|
+
const nullResult = await holoSphere.deleteNode(null, null, null);
|
|
267
|
+
expect(nullResult).toBe(false);
|
|
135
268
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
expect(encrypted).toBeDefined();
|
|
139
|
-
|
|
140
|
-
const decrypted = await holoSphere.decrypt(encrypted, testSecret);
|
|
141
|
-
expect(decrypted).toEqual(testData);
|
|
269
|
+
const nullGet = await holoSphere.getNode(null, null, null);
|
|
270
|
+
expect(nullGet).toBeNull();
|
|
142
271
|
});
|
|
143
272
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
// Create and login test user
|
|
150
|
-
try {
|
|
151
|
-
await holoSphere.createUser('testuser', 'testpass');
|
|
152
|
-
await holoSphere.login('testuser', 'testpass');
|
|
153
|
-
} catch (error) {
|
|
154
|
-
console.log('User already exists or login failed');
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
await holoSphere.putHexData(testHex, testLens, testContent, true, testSecret);
|
|
158
|
-
const result = await holoSphere.getHexData(testHex, testLens, testSecret);
|
|
159
|
-
|
|
160
|
-
expect(Array.isArray(result)).toBeTruthy();
|
|
161
|
-
await holoSphere.logout();
|
|
162
|
-
}, 15000);
|
|
273
|
+
afterEach(async () => {
|
|
274
|
+
// Clean up after each test
|
|
275
|
+
await holoSphere.deleteNode(testHolon, testLens, 'value');
|
|
276
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
277
|
+
});
|
|
163
278
|
});
|
|
164
279
|
|
|
165
280
|
describe('Geospatial Operations', () => {
|
|
@@ -167,21 +282,21 @@ describe('HoloSphere', () => {
|
|
|
167
282
|
const lng = -74.0060;
|
|
168
283
|
const resolution = 7;
|
|
169
284
|
|
|
170
|
-
test('should get
|
|
171
|
-
const
|
|
172
|
-
expect(
|
|
173
|
-
expect(typeof
|
|
285
|
+
test('should get holon from coordinates', async () => {
|
|
286
|
+
const holon = await holoSphere.getHolon(lat, lng, resolution);
|
|
287
|
+
expect(holon).toBeDefined();
|
|
288
|
+
expect(typeof holon).toBe('string');
|
|
174
289
|
});
|
|
175
290
|
|
|
176
291
|
test('should get scalespace from coordinates', () => {
|
|
177
292
|
const scales = holoSphere.getScalespace(lat, lng);
|
|
178
293
|
expect(Array.isArray(scales)).toBeTruthy();
|
|
179
|
-
expect(scales.length).toBe(15);
|
|
294
|
+
expect(scales.length).toBe(15); // 0-14 resolution levels
|
|
180
295
|
});
|
|
181
296
|
|
|
182
|
-
test('should get
|
|
183
|
-
const
|
|
184
|
-
const scales = holoSphere.
|
|
297
|
+
test('should get holon scalespace', () => {
|
|
298
|
+
const holon = h3.latLngToCell(lat, lng, resolution);
|
|
299
|
+
const scales = holoSphere.getHolonScalespace(holon);
|
|
185
300
|
expect(Array.isArray(scales)).toBeTruthy();
|
|
186
301
|
expect(scales.length).toBe(resolution + 1);
|
|
187
302
|
});
|
|
@@ -190,8 +305,8 @@ describe('HoloSphere', () => {
|
|
|
190
305
|
afterAll(async () => {
|
|
191
306
|
// Clean up test data
|
|
192
307
|
const testLens = 'testLens';
|
|
193
|
-
const
|
|
194
|
-
await holoSphere.
|
|
308
|
+
const testHolon = h3.latLngToCell(40.7128, -74.0060, 7);
|
|
309
|
+
await holoSphere.deleteAll(testHolon, testLens);
|
|
195
310
|
|
|
196
311
|
// Allow time for Gun to process
|
|
197
312
|
await new Promise(resolve => setTimeout(resolve, 1000));
|