holosphere 1.1.3 → 1.1.5
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/holosphere.js +236 -257
- package/package.json +9 -3
- package/services/environmentalApi.js +253 -0
- package/services/environmentalApi.test.js +164 -0
- package/test/ai.test.js +233 -0
- package/test/federation.test.js +2 -57
- package/test/holosphere.test.js +68 -107
- package/test/jest.setup.js +5 -0
- package/test/spacesauth.test.js +0 -2
package/test/federation.test.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import HoloSphere from '../holosphere.js';
|
|
2
|
-
import * as h3 from 'h3-js';
|
|
3
2
|
import { jest } from '@jest/globals';
|
|
4
3
|
|
|
5
4
|
// Set global timeout for all tests
|
|
6
|
-
jest.setTimeout(
|
|
5
|
+
jest.setTimeout(3000);
|
|
7
6
|
|
|
8
7
|
describe('Federation Operations', () => {
|
|
9
8
|
const testAppName = 'test-app';
|
|
@@ -28,8 +27,6 @@ describe('Federation Operations', () => {
|
|
|
28
27
|
await holoSphere.deleteAllGlobal('federation');
|
|
29
28
|
await holoSphere.deleteGlobal('spaces', space1.spacename);
|
|
30
29
|
await holoSphere.deleteGlobal('spaces', space2.spacename);
|
|
31
|
-
// Wait for cleanup
|
|
32
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
33
30
|
} catch (error) {
|
|
34
31
|
// Ignore errors during cleanup
|
|
35
32
|
console.log('Cleanup error (expected):', error.message);
|
|
@@ -44,12 +41,9 @@ describe('Federation Operations', () => {
|
|
|
44
41
|
} catch (error) {
|
|
45
42
|
console.log('Space creation attempt', i + 1, 'failed:', error.message);
|
|
46
43
|
if (i === 2) throw error;
|
|
47
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
48
44
|
}
|
|
49
45
|
}
|
|
50
46
|
|
|
51
|
-
// Wait for space creation to complete
|
|
52
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
53
47
|
|
|
54
48
|
// Verify spaces were created
|
|
55
49
|
const space1Created = await holoSphere.getGlobal('spaces', space1.spacename);
|
|
@@ -58,9 +52,6 @@ describe('Federation Operations', () => {
|
|
|
58
52
|
if (!space1Created || !space2Created) {
|
|
59
53
|
throw new Error('Failed to create test spaces');
|
|
60
54
|
}
|
|
61
|
-
|
|
62
|
-
// Wait for everything to settle
|
|
63
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
64
55
|
}, 30000);
|
|
65
56
|
|
|
66
57
|
beforeEach(async () => {
|
|
@@ -91,9 +82,7 @@ describe('Federation Operations', () => {
|
|
|
91
82
|
await holoSphere.setSchema(testLens, baseSchema);
|
|
92
83
|
await strictHoloSphere.setSchema(testLens, baseSchema);
|
|
93
84
|
|
|
94
|
-
|
|
95
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
96
|
-
|
|
85
|
+
|
|
97
86
|
// Verify spaces exist before proceeding
|
|
98
87
|
const space1Exists = await holoSphere.getGlobal('spaces', space1.spacename);
|
|
99
88
|
const space2Exists = await holoSphere.getGlobal('spaces', space2.spacename);
|
|
@@ -102,7 +91,6 @@ describe('Federation Operations', () => {
|
|
|
102
91
|
if (!space1Exists) {
|
|
103
92
|
try {
|
|
104
93
|
await holoSphere.createSpace(space1.spacename, space1.password);
|
|
105
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
106
94
|
} catch (error) {
|
|
107
95
|
if (error.message !== 'Space already exists') {
|
|
108
96
|
throw error;
|
|
@@ -112,7 +100,6 @@ describe('Federation Operations', () => {
|
|
|
112
100
|
if (!space2Exists) {
|
|
113
101
|
try {
|
|
114
102
|
await holoSphere.createSpace(space2.spacename, space2.password);
|
|
115
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
116
103
|
} catch (error) {
|
|
117
104
|
if (error.message !== 'Space already exists') {
|
|
118
105
|
throw error;
|
|
@@ -120,9 +107,6 @@ describe('Federation Operations', () => {
|
|
|
120
107
|
}
|
|
121
108
|
}
|
|
122
109
|
|
|
123
|
-
// Wait for space creation to complete
|
|
124
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
125
|
-
|
|
126
110
|
// Verify spaces again
|
|
127
111
|
const space1Verified = await holoSphere.getGlobal('spaces', space1.spacename);
|
|
128
112
|
const space2Verified = await holoSphere.getGlobal('spaces', space2.spacename);
|
|
@@ -142,17 +126,12 @@ describe('Federation Operations', () => {
|
|
|
142
126
|
// Login as first space to holoSphere
|
|
143
127
|
await holoSphere.login(space1.spacename, space1.password);
|
|
144
128
|
|
|
145
|
-
// Wait for login to complete
|
|
146
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
147
129
|
}, 20000);
|
|
148
130
|
|
|
149
131
|
test('should create federation relationship between spaces', async () => {
|
|
150
132
|
// Create federation relationship
|
|
151
133
|
await holoSphere.federate(space1.spacename, space2.spacename);
|
|
152
134
|
|
|
153
|
-
// Wait for federation to be established
|
|
154
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
155
|
-
|
|
156
135
|
// Verify federation was created
|
|
157
136
|
const fedInfo = await holoSphere.getFederation(space1.spacename);
|
|
158
137
|
expect(fedInfo).toBeDefined();
|
|
@@ -163,9 +142,6 @@ describe('Federation Operations', () => {
|
|
|
163
142
|
// Create bidirectional federation
|
|
164
143
|
await holoSphere.federate(space1.spacename, space2.spacename);
|
|
165
144
|
|
|
166
|
-
// Wait for federation to be established
|
|
167
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
168
|
-
|
|
169
145
|
// Login to space1 to verify federation
|
|
170
146
|
await holoSphere.login(space1.spacename, space1.password);
|
|
171
147
|
|
|
@@ -186,9 +162,6 @@ describe('Federation Operations', () => {
|
|
|
186
162
|
// Create initial federation
|
|
187
163
|
await holoSphere.federate(space1.spacename, space2.spacename);
|
|
188
164
|
|
|
189
|
-
// Wait for federation to be established
|
|
190
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
191
|
-
|
|
192
165
|
// Verify federation exists
|
|
193
166
|
const fedInfo = await holoSphere.getFederation(space1.spacename);
|
|
194
167
|
expect(fedInfo).toBeDefined();
|
|
@@ -213,18 +186,12 @@ describe('Federation Operations', () => {
|
|
|
213
186
|
// Set up federation
|
|
214
187
|
await holoSphere.federate(space1.spacename, space2.spacename);
|
|
215
188
|
|
|
216
|
-
// Wait for federation to be established
|
|
217
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
218
|
-
|
|
219
189
|
// Login to space2 with strict instance
|
|
220
190
|
await strictHoloSphere.login(space2.spacename, space2.password);
|
|
221
191
|
|
|
222
192
|
// Put data in first space
|
|
223
193
|
await holoSphere.put(testHolon, testLens, testData);
|
|
224
194
|
|
|
225
|
-
// Wait for propagation
|
|
226
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
227
|
-
|
|
228
195
|
// Verify data was propagated to federated space
|
|
229
196
|
const federatedData = await strictHoloSphere.get(testHolon, testLens, testData.id);
|
|
230
197
|
expect(federatedData).toBeDefined();
|
|
@@ -239,9 +206,6 @@ describe('Federation Operations', () => {
|
|
|
239
206
|
// Clean up any existing test data first
|
|
240
207
|
await holoSphere.deleteAll(testHolon, testLens);
|
|
241
208
|
await strictHoloSphere.deleteAll(testHolon, testLens);
|
|
242
|
-
|
|
243
|
-
// Wait for cleanup to complete
|
|
244
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
245
209
|
|
|
246
210
|
// Set up federation using non-strict instance (already logged in as space1)
|
|
247
211
|
await holoSphere.federate(space1.spacename, space2.spacename);
|
|
@@ -249,9 +213,6 @@ describe('Federation Operations', () => {
|
|
|
249
213
|
// Login to space2 with strict instance
|
|
250
214
|
await strictHoloSphere.login(space2.spacename, space2.password);
|
|
251
215
|
|
|
252
|
-
// Wait for federation to be established
|
|
253
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
254
|
-
|
|
255
216
|
// Test data with overlapping IDs and different fields
|
|
256
217
|
const testData1 = {
|
|
257
218
|
id: 'user1',
|
|
@@ -281,18 +242,13 @@ describe('Federation Operations', () => {
|
|
|
281
242
|
// Put data using both instances and wait between puts
|
|
282
243
|
console.log('Putting test data 1:', JSON.stringify(testData1, null, 2));
|
|
283
244
|
await holoSphere.put(testHolon, testLens, testData1);
|
|
284
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
285
245
|
|
|
286
246
|
console.log('Putting test data 2:', JSON.stringify(testData2, null, 2));
|
|
287
247
|
await strictHoloSphere.put(testHolon, testLens, testData2);
|
|
288
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
289
248
|
|
|
290
249
|
console.log('Putting test data 3:', JSON.stringify(testData3, null, 2));
|
|
291
250
|
await holoSphere.put(testHolon, testLens, testData3);
|
|
292
251
|
|
|
293
|
-
// Wait longer for data propagation
|
|
294
|
-
await new Promise(resolve => setTimeout(resolve, 10000));
|
|
295
|
-
|
|
296
252
|
// Test 1: Simple concatenation without deduplication
|
|
297
253
|
const concatenatedResults = await holoSphere.getFederated(testHolon, testLens, {
|
|
298
254
|
aggregate: false,
|
|
@@ -352,9 +308,6 @@ describe('Federation Operations', () => {
|
|
|
352
308
|
// Set up federation
|
|
353
309
|
await holoSphere.federate(space1.spacename, space2.spacename);
|
|
354
310
|
|
|
355
|
-
// Wait for federation to be established
|
|
356
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
357
|
-
|
|
358
311
|
// Verify federation exists
|
|
359
312
|
let fedInfo1 = await holoSphere.getFederation(space1.spacename);
|
|
360
313
|
expect(fedInfo1).toBeDefined();
|
|
@@ -364,9 +317,6 @@ describe('Federation Operations', () => {
|
|
|
364
317
|
// Remove federation
|
|
365
318
|
await holoSphere.unfederate(space1.spacename, space2.spacename);
|
|
366
319
|
|
|
367
|
-
// Wait for unfederation to complete
|
|
368
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
369
|
-
|
|
370
320
|
// Verify federation is removed
|
|
371
321
|
fedInfo1 = await holoSphere.getFederation(space1.spacename);
|
|
372
322
|
const fedInfo2 = await holoSphere.getFederation(space2.spacename);
|
|
@@ -391,9 +341,6 @@ describe('Federation Operations', () => {
|
|
|
391
341
|
if (strictHoloSphere.currentSpace) {
|
|
392
342
|
await strictHoloSphere.logout();
|
|
393
343
|
}
|
|
394
|
-
|
|
395
|
-
// Wait for cleanup
|
|
396
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
397
344
|
});
|
|
398
345
|
|
|
399
346
|
afterAll(async () => {
|
|
@@ -401,8 +348,6 @@ describe('Federation Operations', () => {
|
|
|
401
348
|
try {
|
|
402
349
|
await holoSphere.deleteGlobal('spaces', space1.spacename);
|
|
403
350
|
await holoSphere.deleteGlobal('spaces', space2.spacename);
|
|
404
|
-
// Wait for cleanup
|
|
405
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
406
351
|
} catch (error) {
|
|
407
352
|
console.error('Error during final cleanup:', error.message);
|
|
408
353
|
}
|
package/test/holosphere.test.js
CHANGED
|
@@ -7,10 +7,13 @@ describe('HoloSphere', () => {
|
|
|
7
7
|
spacename: 'testuser',
|
|
8
8
|
password: 'testpass'
|
|
9
9
|
};
|
|
10
|
-
let holoSphere
|
|
10
|
+
let holoSphere;
|
|
11
|
+
let strictHoloSphere;
|
|
12
|
+
|
|
11
13
|
beforeAll(async () => {
|
|
12
|
-
// Initialize HoloSphere once for all tests
|
|
13
|
-
|
|
14
|
+
// Initialize HoloSphere instances once for all tests
|
|
15
|
+
holoSphere = new HoloSphere(testAppName, false);
|
|
16
|
+
strictHoloSphere = new HoloSphere(testAppName, true);
|
|
14
17
|
|
|
15
18
|
// Set up test space and authenticate
|
|
16
19
|
try {
|
|
@@ -26,15 +29,9 @@ describe('HoloSphere', () => {
|
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
31
|
|
|
29
|
-
// Ensure
|
|
32
|
+
// Ensure both instances are logged in
|
|
30
33
|
await holoSphere.login(testCredentials.spacename, testCredentials.password);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
beforeEach(async () => {
|
|
34
|
-
// Ensure we're logged in before each test
|
|
35
|
-
if (!holoSphere.currentSpace || holoSphere.currentSpace.exp < Date.now()) {
|
|
36
|
-
await holoSphere.login(testCredentials.spacename, testCredentials.password);
|
|
37
|
-
}
|
|
34
|
+
await strictHoloSphere.login(testCredentials.spacename, testCredentials.password);
|
|
38
35
|
});
|
|
39
36
|
|
|
40
37
|
describe('Constructor', () => {
|
|
@@ -45,11 +42,8 @@ describe('HoloSphere', () => {
|
|
|
45
42
|
expect(holoSphere.openai).toBeUndefined();
|
|
46
43
|
});
|
|
47
44
|
|
|
48
|
-
test('should initialize with OpenAI
|
|
49
|
-
|
|
50
|
-
expect(hsWithAI.openai).toBeDefined();
|
|
51
|
-
// Clean up additional instance
|
|
52
|
-
if (hsWithAI.gun) hsWithAI.gun.off();
|
|
45
|
+
test('should initialize with OpenAI', () => {
|
|
46
|
+
expect(new HoloSphere(testAppName, false, 'fake-key').openai).toBeDefined();
|
|
53
47
|
});
|
|
54
48
|
});
|
|
55
49
|
|
|
@@ -65,10 +59,8 @@ describe('HoloSphere', () => {
|
|
|
65
59
|
};
|
|
66
60
|
|
|
67
61
|
beforeEach(async () => {
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
await holoSphere.login(testCredentials.spacename, testCredentials.password);
|
|
71
|
-
}
|
|
62
|
+
// Clean up any existing schemas
|
|
63
|
+
await holoSphere.deleteAllGlobal('schemas');
|
|
72
64
|
});
|
|
73
65
|
|
|
74
66
|
test('should set and get schema', async () => {
|
|
@@ -84,11 +76,6 @@ describe('HoloSphere', () => {
|
|
|
84
76
|
});
|
|
85
77
|
|
|
86
78
|
test('should enforce strict mode schema validation', async () => {
|
|
87
|
-
const strictHoloSphere = new HoloSphere(testAppName, true);
|
|
88
|
-
|
|
89
|
-
// Login to the strict instance
|
|
90
|
-
await strictHoloSphere.login(testCredentials.spacename, testCredentials.password);
|
|
91
|
-
|
|
92
79
|
const invalidSchema = {
|
|
93
80
|
type: 'object',
|
|
94
81
|
properties: {
|
|
@@ -98,9 +85,6 @@ describe('HoloSphere', () => {
|
|
|
98
85
|
|
|
99
86
|
await expect(strictHoloSphere.setSchema(testLens, invalidSchema))
|
|
100
87
|
.rejects.toThrow();
|
|
101
|
-
|
|
102
|
-
// Clean up
|
|
103
|
-
await strictHoloSphere.logout();
|
|
104
88
|
});
|
|
105
89
|
|
|
106
90
|
test('should handle schema retrieval for non-existent lens', async () => {
|
|
@@ -110,10 +94,6 @@ describe('HoloSphere', () => {
|
|
|
110
94
|
|
|
111
95
|
test('should maintain schema integrity across storage and retrieval', async () => {
|
|
112
96
|
const testLens = 'schemaTestLens';
|
|
113
|
-
const strictHoloSphere = new HoloSphere(testAppName, true);
|
|
114
|
-
|
|
115
|
-
// Login to the strict instance
|
|
116
|
-
await strictHoloSphere.login(testCredentials.spacename, testCredentials.password);
|
|
117
97
|
|
|
118
98
|
// Create test schemas of increasing complexity
|
|
119
99
|
const testSchemas = [
|
|
@@ -151,9 +131,6 @@ describe('HoloSphere', () => {
|
|
|
151
131
|
|
|
152
132
|
// Store schema
|
|
153
133
|
await strictHoloSphere.setSchema(testLensWithIndex, schema);
|
|
154
|
-
|
|
155
|
-
// Add delay to ensure schema is stored
|
|
156
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
157
134
|
|
|
158
135
|
// Retrieve schema
|
|
159
136
|
const retrievedSchema = await strictHoloSphere.getSchema(testLensWithIndex);
|
|
@@ -189,18 +166,8 @@ describe('HoloSphere', () => {
|
|
|
189
166
|
|
|
190
167
|
// Clean up after each schema test
|
|
191
168
|
await strictHoloSphere.deleteAll('testHolon', testLensWithIndex);
|
|
192
|
-
await strictHoloSphere.gun.get(strictHoloSphere.appname)
|
|
193
|
-
.get(testLensWithIndex)
|
|
194
|
-
.get('schema')
|
|
195
|
-
.put(null);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Clean up the strict instance
|
|
199
|
-
if (strictHoloSphere.gun) {
|
|
200
|
-
await strictHoloSphere.logout();
|
|
201
|
-
await new Promise(resolve => setTimeout(resolve, 100)); // Allow time for cleanup
|
|
202
169
|
}
|
|
203
|
-
}, 10000);
|
|
170
|
+
}, 10000);
|
|
204
171
|
|
|
205
172
|
test('should handle concurrent schema operations', async () => {
|
|
206
173
|
const baseLens = 'concurrentSchemaTest';
|
|
@@ -220,16 +187,12 @@ describe('HoloSphere', () => {
|
|
|
220
187
|
required: ['id', 'value']
|
|
221
188
|
};
|
|
222
189
|
expectedSchemas.push({ lens, schema });
|
|
223
|
-
// Add small delay between operations to prevent race conditions
|
|
224
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
225
190
|
promises.push(holoSphere.setSchema(lens, schema));
|
|
226
191
|
}
|
|
227
192
|
|
|
228
193
|
// Wait for all operations to complete
|
|
229
194
|
await Promise.all(promises);
|
|
230
195
|
|
|
231
|
-
// Add delay before verification to ensure data is settled
|
|
232
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
233
196
|
|
|
234
197
|
// Verify each schema was stored correctly
|
|
235
198
|
for (const { lens, schema } of expectedSchemas) {
|
|
@@ -279,10 +242,7 @@ describe('HoloSphere', () => {
|
|
|
279
242
|
|
|
280
243
|
afterEach(async () => {
|
|
281
244
|
// Clean up schemas after each test
|
|
282
|
-
await holoSphere.
|
|
283
|
-
.get(testLens)
|
|
284
|
-
.get('schema')
|
|
285
|
-
.put(null);
|
|
245
|
+
await holoSphere.deleteAllGlobal('schemas');
|
|
286
246
|
});
|
|
287
247
|
});
|
|
288
248
|
|
|
@@ -362,11 +322,6 @@ describe('HoloSphere', () => {
|
|
|
362
322
|
});
|
|
363
323
|
|
|
364
324
|
test('should enforce strict mode data validation', async () => {
|
|
365
|
-
const strictHoloSphere = new HoloSphere(testAppName, true);
|
|
366
|
-
|
|
367
|
-
// Login to the strict instance
|
|
368
|
-
await strictHoloSphere.login(testCredentials.spacename, testCredentials.password);
|
|
369
|
-
|
|
370
325
|
// Define schema for strict mode tests
|
|
371
326
|
const strictSchema = {
|
|
372
327
|
type: 'object',
|
|
@@ -383,9 +338,6 @@ describe('HoloSphere', () => {
|
|
|
383
338
|
// Try to put data without schema in strict mode
|
|
384
339
|
await expect(strictHoloSphere.put(testHolon, 'no-schema-lens', validData))
|
|
385
340
|
.rejects.toThrow('Schema required in strict mode');
|
|
386
|
-
|
|
387
|
-
// Clean up
|
|
388
|
-
await strictHoloSphere.logout();
|
|
389
341
|
});
|
|
390
342
|
|
|
391
343
|
test('should maintain content integrity in holon storage', async () => {
|
|
@@ -480,9 +432,6 @@ describe('HoloSphere', () => {
|
|
|
480
432
|
await holoSphere.put(testHolon, testLens, storeData);
|
|
481
433
|
}
|
|
482
434
|
|
|
483
|
-
// Wait a bit to ensure data is settled
|
|
484
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
485
|
-
|
|
486
435
|
// Get data multiple times
|
|
487
436
|
const results = await Promise.all(
|
|
488
437
|
Array.from({ length: 5 }, () => holoSphere.getAll(testHolon, testLens))
|
|
@@ -671,27 +620,33 @@ describe('HoloSphere', () => {
|
|
|
671
620
|
test('should stop receiving data after unsubscribe', async () => {
|
|
672
621
|
const testData1 = { id: 'test1', data: 'first' };
|
|
673
622
|
const testData2 = { id: 'test2', data: 'second' };
|
|
674
|
-
let
|
|
623
|
+
let receivedData = [];
|
|
675
624
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
received
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
625
|
+
return new Promise(async (resolve, reject) => {
|
|
626
|
+
const timeout = setTimeout(() => {
|
|
627
|
+
// If we only received the first piece of data, test passes
|
|
628
|
+
if (receivedData.length === 1 && receivedData[0].id === testData1.id) {
|
|
629
|
+
resolve();
|
|
630
|
+
} else {
|
|
631
|
+
reject(new Error('Test timeout or received unexpected data'));
|
|
632
|
+
}
|
|
633
|
+
}, 5000);
|
|
634
|
+
|
|
635
|
+
const subscription = await holoSphere.subscribe(testHolon, testLens, async (data) => {
|
|
636
|
+
receivedData.push(data);
|
|
683
637
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
638
|
+
if (data.id === testData1.id) {
|
|
639
|
+
subscription.unsubscribe();
|
|
640
|
+
resolve();
|
|
641
|
+
} else if (data.id === testData2.id) {
|
|
642
|
+
clearTimeout(timeout);
|
|
643
|
+
reject(new Error('Received data after unsubscribe'));
|
|
644
|
+
}
|
|
645
|
+
});
|
|
692
646
|
|
|
693
|
-
|
|
694
|
-
|
|
647
|
+
// Put first piece of data
|
|
648
|
+
await holoSphere.put(testHolon, testLens, testData1);
|
|
649
|
+
});
|
|
695
650
|
}, 10000);
|
|
696
651
|
|
|
697
652
|
test('should handle multiple subscriptions', async () => {
|
|
@@ -846,16 +801,13 @@ describe('HoloSphere', () => {
|
|
|
846
801
|
for (let i = 0; i < numOperations; i++) {
|
|
847
802
|
const data = { id: `concurrent${i}`, value: `value${i}` };
|
|
848
803
|
expectedData.push(data);
|
|
849
|
-
// Add small delay between operations
|
|
850
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
851
804
|
promises.push(holoSphere.putGlobal(testTable, data));
|
|
852
805
|
}
|
|
853
806
|
|
|
854
807
|
// Wait for all operations to complete
|
|
855
808
|
await Promise.all(promises);
|
|
856
809
|
|
|
857
|
-
|
|
858
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
810
|
+
|
|
859
811
|
|
|
860
812
|
// Retrieve and verify data
|
|
861
813
|
const retrievedData = await holoSphere.getAllGlobal(testTable);
|
|
@@ -908,24 +860,31 @@ describe('HoloSphere', () => {
|
|
|
908
860
|
|
|
909
861
|
test('should validate holon resolution', async () => {
|
|
910
862
|
const invalidHolon = h3.latLngToCell(40.7128, -74.0060, 0); // Resolution 0
|
|
911
|
-
await expect(holoSphere.compute(invalidHolon, testLens, 'summarize'))
|
|
863
|
+
await expect(holoSphere.compute(invalidHolon, testLens, { operation: 'summarize' }))
|
|
912
864
|
.rejects.toThrow('compute: Invalid holon resolution (must be between 1 and 15)');
|
|
913
865
|
});
|
|
914
866
|
|
|
915
867
|
test('should validate depth parameters', async () => {
|
|
916
|
-
await expect(holoSphere.compute(testHolon, testLens,
|
|
917
|
-
|
|
868
|
+
await expect(holoSphere.compute(testHolon, testLens, {
|
|
869
|
+
operation: 'summarize',
|
|
870
|
+
depth: -1
|
|
871
|
+
})).rejects.toThrow('compute: Invalid depth parameter');
|
|
918
872
|
|
|
919
|
-
await expect(holoSphere.compute(testHolon, testLens,
|
|
920
|
-
|
|
873
|
+
await expect(holoSphere.compute(testHolon, testLens, {
|
|
874
|
+
operation: 'summarize',
|
|
875
|
+
maxDepth: 0
|
|
876
|
+
})).rejects.toThrow('compute: Invalid maxDepth parameter (must be between 1 and 15)');
|
|
921
877
|
|
|
922
|
-
await expect(holoSphere.compute(testHolon, testLens,
|
|
923
|
-
|
|
878
|
+
await expect(holoSphere.compute(testHolon, testLens, {
|
|
879
|
+
operation: 'summarize',
|
|
880
|
+
maxDepth: 16
|
|
881
|
+
})).rejects.toThrow('compute: Invalid maxDepth parameter (must be between 1 and 15)');
|
|
924
882
|
});
|
|
925
883
|
|
|
926
884
|
test('should validate operation type', async () => {
|
|
927
|
-
await expect(holoSphere.compute(testHolon, testLens,
|
|
928
|
-
|
|
885
|
+
await expect(holoSphere.compute(testHolon, testLens, {
|
|
886
|
+
operation: 'invalid-operation'
|
|
887
|
+
})).rejects.toThrow('compute: Invalid operation (must be one of summarize, aggregate, concatenate)');
|
|
929
888
|
});
|
|
930
889
|
|
|
931
890
|
afterEach(async () => {
|
|
@@ -967,8 +926,6 @@ describe('HoloSphere', () => {
|
|
|
967
926
|
for (let i = 0; i < numOperations; i++) {
|
|
968
927
|
const id = `concurrent${i}`;
|
|
969
928
|
expectedIds.add(id);
|
|
970
|
-
// Add small delay between operations to prevent race conditions
|
|
971
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
972
929
|
promises.push(holoSphere.put(testHolon, testLens, {
|
|
973
930
|
id: id,
|
|
974
931
|
data: 'test'
|
|
@@ -978,9 +935,6 @@ describe('HoloSphere', () => {
|
|
|
978
935
|
// Wait for all operations to complete
|
|
979
936
|
await Promise.all(promises);
|
|
980
937
|
|
|
981
|
-
// Add delay before verification to ensure data is settled
|
|
982
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
983
|
-
|
|
984
938
|
// Get and verify results
|
|
985
939
|
const results = await holoSphere.getAll(testHolon, testLens);
|
|
986
940
|
const resultIds = new Set(results.map(r => r.id));
|
|
@@ -1020,14 +974,13 @@ describe('HoloSphere', () => {
|
|
|
1020
974
|
|
|
1021
975
|
describe('OpenAI Integration', () => {
|
|
1022
976
|
test('should handle missing OpenAI key', async () => {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
expect(result).toBe('OpenAI not initialized, please specify the API key in the constructor.');
|
|
977
|
+
expect(await holoSphere.summarize('test content'))
|
|
978
|
+
.toBe('OpenAI not initialized, please specify the API key in the constructor.');
|
|
1026
979
|
});
|
|
1027
980
|
|
|
1028
981
|
test.skip('should summarize content with valid OpenAI key', async () => {
|
|
1029
|
-
const
|
|
1030
|
-
|
|
982
|
+
const summary = await new HoloSphere('test', false, process.env.OPENAI_API_KEY)
|
|
983
|
+
.summarize('Test content to summarize');
|
|
1031
984
|
expect(typeof summary).toBe('string');
|
|
1032
985
|
expect(summary.length).toBeGreaterThan(0);
|
|
1033
986
|
});
|
|
@@ -1043,13 +996,21 @@ describe('HoloSphere', () => {
|
|
|
1043
996
|
await holoSphere.deleteAllGlobal('testTable');
|
|
1044
997
|
await holoSphere.deleteAllGlobal('testGlobalTable');
|
|
1045
998
|
await holoSphere.deleteAllGlobal('concurrentGlobalTest');
|
|
999
|
+
await holoSphere.deleteAllGlobal('schemas');
|
|
1046
1000
|
|
|
1047
1001
|
// Clean up test space
|
|
1048
1002
|
await holoSphere.deleteGlobal('spaces', testCredentials.spacename);
|
|
1049
1003
|
|
|
1050
|
-
// Logout
|
|
1004
|
+
// Logout both instances
|
|
1051
1005
|
if (holoSphere.currentSpace) {
|
|
1052
1006
|
await holoSphere.logout();
|
|
1053
1007
|
}
|
|
1008
|
+
if (strictHoloSphere.currentSpace) {
|
|
1009
|
+
await strictHoloSphere.logout();
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
// Clean up Gun instances
|
|
1013
|
+
if (holoSphere.gun) holoSphere.gun.off();
|
|
1014
|
+
if (strictHoloSphere.gun) strictHoloSphere.gun.off();
|
|
1054
1015
|
});
|
|
1055
1016
|
});
|