holosphere 1.1.11 → 1.1.13

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.
@@ -1,354 +0,0 @@
1
- import HoloSphere from '../holosphere.js';
2
- import * as h3 from 'h3-js';
3
- import { jest } from '@jest/globals';
4
-
5
- // Configure Jest
6
- jest.setTimeout(30000); // 30 second timeout
7
-
8
- describe('HoloSphere', () => {
9
- const testAppName = 'test-app3';
10
- const testHolon = 'testHolon3';
11
- const testLens = 'testLens3';
12
- const testPassword = 'testPassword1234';
13
- let holoSphere;
14
- let strictHoloSphere;
15
- beforeAll(async () => {
16
- holoSphere = new HoloSphere('test-app', false, null);
17
- strictHoloSphere = new HoloSphere('test-app-strict', true, null);
18
- });
19
-
20
- afterEach(async () => {
21
- // Clean up test data
22
- try {
23
- if (holoSphere) {
24
- await holoSphere.deleteAll(testHolon, testLens);
25
- }
26
- if (strictHoloSphere) {
27
- await strictHoloSphere.deleteAll(testHolon, testLens);
28
- }
29
- } catch (error) {
30
- console.error('Error in afterEach cleanup:', error);
31
- }
32
- });
33
-
34
- afterAll(async () => {
35
- // Clean up all test data
36
- await holoSphere.deleteAll(testHolon, testLens);
37
- await holoSphere.deleteAllGlobal('testTable');
38
-
39
- // Close HoloSphere instances
40
- if (holoSphere) {
41
- await holoSphere.close();
42
- }
43
- if (strictHoloSphere) {
44
- await strictHoloSphere.close();
45
- }
46
-
47
- // Wait for connections to close
48
- await new Promise(resolve => setTimeout(resolve, 1000));
49
- });
50
-
51
-
52
- describe('Constructor', () => {
53
- test('should have initialized with correct properties', () => {
54
- expect(holoSphere).toBeInstanceOf(HoloSphere);
55
- expect(holoSphere.gun).toBeDefined();
56
- expect(holoSphere.validator).toBeDefined();
57
- expect(holoSphere.openai).toBeUndefined();
58
- expect(holoSphere.subscriptions).toBeDefined();
59
- expect(holoSphere.subscriptions).toEqual({});
60
- });
61
-
62
- test('should initialize with OpenAI', () => {
63
- expect(new HoloSphere(testAppName, false, 'fake-key').openai).toBeDefined();
64
- });
65
- });
66
-
67
- describe('Space Management', () => {
68
- test('should handle private space authentication', async () => {
69
- const testData = { id: 'test1', value: 'data' + Date.now() };
70
-
71
- await holoSphere.put(testHolon, testLens, testData, testPassword);
72
- const result = await holoSphere.get(testHolon, testLens, testData.id, testPassword);
73
- expect(result).toBeDefined();
74
- expect(result.value).toBe(testData.value);
75
- });
76
-
77
- test('should handle public space access', async () => {
78
- const testData = { id: 'public1', value: 'public data' + Date.now() };
79
-
80
- await holoSphere.put(testHolon, testLens, testData);
81
- const result = await holoSphere.get(testHolon, testLens, testData.id);
82
- expect(result).toBeDefined();
83
- expect(result.value).toBe(testData.value);
84
- });
85
-
86
- test('should handle missing parameters gracefully', async () => {
87
- const result1 = await holoSphere.get(null, testLens, 'key');
88
- expect(result1).toBeNull();
89
-
90
- const result2 = await holoSphere.get(testHolon, null, 'key');
91
- expect(result2).toBeNull();
92
-
93
- const result3 = await holoSphere.get(testHolon, testLens, null);
94
- expect(result3).toBeNull();
95
- });
96
-
97
- test('should handle authentication errors gracefully', async () => {
98
- const testData = { id: 'test2', value: 'private data' };
99
-
100
- await holoSphere.put(testHolon, testLens, testData, testPassword);
101
- const result = await holoSphere.get(testHolon, testLens, testData.id, 'wrong_password');
102
- expect(result).toBeNull();
103
- });
104
- });
105
-
106
- describe('Data Operations', () => {
107
- const validSchema = {
108
- type: 'object',
109
- properties: {
110
- id: { type: 'string' },
111
- value: { type: 'string' }
112
- },
113
- required: ['id', 'value']
114
- };
115
-
116
- beforeEach(async () => {
117
- await holoSphere.setSchema(testLens, validSchema);
118
- });
119
-
120
- test('should handle data operations gracefully', async () => {
121
- const testData = { id: 'test3', value: 'test data' };
122
-
123
- // Test non-existent data
124
- const nonExistent = await holoSphere.get(testHolon, testLens, 'non-existent');
125
- expect(nonExistent).toBeNull();
126
-
127
- // Test storing and retrieving data
128
- await holoSphere.put(testHolon, testLens, testData);
129
- const result = await holoSphere.get(testHolon, testLens, testData.id);
130
- expect(result).toEqual(testData);
131
-
132
- // Test deleting data
133
- await holoSphere.delete(testHolon, testLens, testData.id);
134
- const deletedResult = await holoSphere.get(testHolon, testLens, testData.id);
135
- expect(deletedResult).toBeNull();
136
- });
137
-
138
- test('should handle invalid data gracefully', async () => {
139
- const invalidData = { wrongField: 'no id field' };
140
-
141
- // Should not throw when storing invalid data in non-strict mode
142
- await expect(holoSphere.put(testHolon, testLens, invalidData))
143
- .resolves.toBeTruthy();
144
-
145
- // Should return null when retrieving invalid data
146
- const result = await holoSphere.get(testHolon, testLens, 'undefined');
147
- expect(result).toBeNull();
148
- });
149
- });
150
-
151
- describe('Global Operations', () => {
152
- test('should handle global operations gracefully', async () => {
153
- const globalData = { id: 'global1', value: 'global test data' };
154
-
155
- // Test non-existent data
156
- const nonExistent = await holoSphere.getGlobal(testHolon, testLens, 'non-existent');
157
- expect(nonExistent).toBeNull();
158
-
159
- // Test storing and retrieving data
160
- await holoSphere.putGlobal(testLens, globalData);
161
- const result = await holoSphere.getGlobal(testLens, globalData.id);
162
- expect(result).toEqual(globalData);
163
-
164
- // Test deleting data
165
- await holoSphere.deleteGlobal( testLens, globalData.id);
166
- const deletedResult = await holoSphere.getGlobal( testLens, globalData.id);
167
- expect(deletedResult).toBeNull();
168
- });
169
- });
170
-
171
- describe('Schema Functions', () => {
172
- test('should set and get a schema', async () => {
173
- const schema = {
174
- type: 'object',
175
- properties: {
176
- id: { type: 'string' },
177
- value: { type: 'string' }
178
- },
179
- required: ['id', 'value']
180
- };
181
-
182
- await holoSphere.setSchema('testLens', schema);
183
- const retrieved = await holoSphere.getSchema('testLens');
184
-
185
- expect(retrieved).toEqual(schema);
186
- });
187
-
188
- test('should cache schemas when fetched', async () => {
189
- const schema = {
190
- type: 'object',
191
- properties: {
192
- id: { type: 'string' },
193
- test: { type: 'string' }
194
- },
195
- required: ['id', 'test']
196
- };
197
-
198
- // Clear any existing cache and set up fresh schema
199
- holoSphere.clearSchemaCache();
200
- await holoSphere.setSchema('cacheTestLens', schema);
201
-
202
- // Cache should be populated by setSchema
203
- expect(holoSphere.schemaCache.has('cacheTestLens')).toBe(true);
204
-
205
- // Save the getGlobal method to create a spy
206
- const originalGetGlobal = holoSphere.getGlobal;
207
- let globalCalled = false;
208
-
209
- // Replace with a spy
210
- holoSphere.getGlobal = async (...args) => {
211
- globalCalled = true;
212
- return originalGetGlobal.apply(holoSphere, args);
213
- };
214
-
215
- // This call should use the cache and not call getGlobal
216
- const cachedFetch = await holoSphere.getSchema('cacheTestLens');
217
- expect(cachedFetch).toEqual(schema);
218
-
219
- // Verify getGlobal was not called because we used the cache
220
- expect(globalCalled).toBe(false);
221
-
222
- // Now force a non-cached fetch
223
- globalCalled = false;
224
- const forcedFetch = await holoSphere.getSchema('cacheTestLens', { useCache: false });
225
- expect(forcedFetch).toEqual(schema);
226
-
227
- // Verify getGlobal was called this time
228
- expect(globalCalled).toBe(true);
229
-
230
- // Restore original method
231
- holoSphere.getGlobal = originalGetGlobal;
232
- });
233
-
234
- test('should respect cache max age', async () => {
235
- const schema = {
236
- type: 'object',
237
- properties: {
238
- id: { type: 'string' },
239
- age: { type: 'number' }
240
- },
241
- required: ['id', 'age']
242
- };
243
-
244
- // Clear any existing cache
245
- holoSphere.clearSchemaCache();
246
- await holoSphere.setSchema('ageTestLens', schema);
247
-
248
- // First fetch to populate cache
249
- await holoSphere.getSchema('ageTestLens');
250
-
251
- // Verify cache has the entry now
252
- expect(holoSphere.schemaCache.has('ageTestLens')).toBe(true);
253
-
254
- // Manually set an old timestamp on the cache entry
255
- const oldTimestamp = Date.now() - 3700000; // Older than the default maxCacheAge
256
- holoSphere.schemaCache.set('ageTestLens', {
257
- schema,
258
- timestamp: oldTimestamp
259
- });
260
-
261
- // Save the getGlobal method to create a spy
262
- const originalGetGlobal = holoSphere.getGlobal;
263
- let globalCalled = false;
264
-
265
- // Replace with a spy
266
- holoSphere.getGlobal = async (...args) => {
267
- globalCalled = true;
268
- return originalGetGlobal.apply(holoSphere, args);
269
- };
270
-
271
- // Call should bypass the cache due to age
272
- const secondFetch = await holoSphere.getSchema('ageTestLens');
273
- expect(secondFetch).toEqual(schema);
274
-
275
- // getGlobal should have been called again
276
- expect(globalCalled).toBe(true);
277
-
278
- // Restore original method
279
- holoSphere.getGlobal = originalGetGlobal;
280
- });
281
-
282
- test('should clear cache properly', async () => {
283
- const schema1 = {
284
- type: 'object',
285
- properties: { id: { type: 'string' } },
286
- required: ['id']
287
- };
288
-
289
- const schema2 = {
290
- type: 'object',
291
- properties: { name: { type: 'string' } },
292
- required: ['name']
293
- };
294
-
295
- // Set two schemas
296
- await holoSphere.setSchema('clearTest1', schema1);
297
- await holoSphere.setSchema('clearTest2', schema2);
298
-
299
- // Verify they're cached
300
- expect(holoSphere.schemaCache.has('clearTest1')).toBe(true);
301
- expect(holoSphere.schemaCache.has('clearTest2')).toBe(true);
302
-
303
- // Clear one schema
304
- holoSphere.clearSchemaCache('clearTest1');
305
- expect(holoSphere.schemaCache.has('clearTest1')).toBe(false);
306
- expect(holoSphere.schemaCache.has('clearTest2')).toBe(true);
307
-
308
- // Clear all schemas
309
- holoSphere.clearSchemaCache();
310
- expect(holoSphere.schemaCache.has('clearTest1')).toBe(false);
311
- expect(holoSphere.schemaCache.has('clearTest2')).toBe(false);
312
- });
313
-
314
- test('should provide significant performance improvement with caching', async () => {
315
- const schema = {
316
- type: 'object',
317
- properties: {
318
- id: { type: 'string' },
319
- value: { type: 'number' },
320
- name: { type: 'string' }
321
- },
322
- required: ['id', 'value']
323
- };
324
-
325
- // Set up the schema
326
- await holoSphere.setSchema('perfTestLens', schema);
327
-
328
- // Measure time without caching (force bypass)
329
- const start1 = Date.now();
330
- for (let i = 0; i < 100; i++) {
331
- await holoSphere.getSchema('perfTestLens', { useCache: false });
332
- }
333
- const end1 = Date.now();
334
- const timeWithoutCache = end1 - start1;
335
-
336
- // Measure time with caching
337
- const start2 = Date.now();
338
- for (let i = 0; i < 100; i++) {
339
- await holoSphere.getSchema('perfTestLens');
340
- }
341
- const end2 = Date.now();
342
- const timeWithCache = end2 - start2;
343
-
344
- console.log(`Performance comparison:
345
- Without cache: ${timeWithoutCache}ms
346
- With cache: ${timeWithCache}ms
347
- Improvement factor: ${timeWithoutCache / timeWithCache}x
348
- `);
349
-
350
- // The cached version should be at least 2x faster
351
- expect(timeWithCache).toBeLessThan(timeWithoutCache / 2);
352
- });
353
- });
354
- });