holosphere 1.1.9 → 1.1.11
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/.cursor/rules/futura.mdc +55 -0
- package/FEDERATION.md +17 -17
- package/compute.js +289 -0
- package/content.js +797 -0
- package/examples/federation.js +98 -90
- package/examples/{references.js → holograms.js} +49 -51
- package/federation.js +307 -197
- package/global.js +560 -0
- package/hologram.js +156 -0
- package/holosphere.d.ts +94 -7
- package/holosphere.js +211 -1464
- package/node.js +155 -0
- package/package.json +2 -5
- package/schema.js +132 -0
- package/test/auth.test.js +85 -51
- package/test/delete.test.js +15 -11
- package/test/federation.test.js +179 -0
- package/test/hologram.test.js +316 -0
- package/test/holosphere.test.js +189 -5
- package/test/subscription.test.js +364 -0
- package/utils.js +290 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
description:
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
## 1. Collaboration with PRD Development
|
|
7
|
+
- Do not start coding until the PRD is provided.
|
|
8
|
+
- Once I send the completed PRD, use it as the definitive guide for all tasks, referring to it before starting any work.
|
|
9
|
+
- Treat the PRD as a living document that may evolve; check for updates before each task and adjust plans accordingly.
|
|
10
|
+
- Reference the PRD’s user stories, acceptance criteria, and priority levels (Must-have, Should-have, Could-have, Won’t-have) to guide coding and testing decisions.
|
|
11
|
+
- Never use React, libraries are outdated and gives too many problems of compatibility and stability, go for Python in doubt
|
|
12
|
+
- Do not build frontend and backend in separate folders and instaces as it seems that you will have a lot of trouble in managing the connections between the 2 sides
|
|
13
|
+
|
|
14
|
+
## 2. Project Setup and Tracking
|
|
15
|
+
- After receiving the PRD, create a README.md file with:
|
|
16
|
+
- A section listing all patterns and technologies used in the project (e.g., frameworks, libraries, tools).
|
|
17
|
+
- A brief project overview based on the PRD.
|
|
18
|
+
- Create a checklist.md file with:
|
|
19
|
+
- A task list derived from the PRD, broken into actionable steps (e.g., "Implement login endpoint", "Write tests for user authentication").
|
|
20
|
+
- A status column (e.g., "Not Started", "In Progress", "Completed") to track progress.
|
|
21
|
+
- Update checklist.md after completing each task by marking it as "Completed" and noting the git commit hash.
|
|
22
|
+
- Incorporate the PRD’s feature breakdown table into checklist.md, including Priority and Dependencies columns to sequence tasks logically.
|
|
23
|
+
- If the PRD includes a release plan (e.g., MVP, v1.1), group tasks by release milestones in checklist.md.
|
|
24
|
+
|
|
25
|
+
## 3. Task Execution Workflow
|
|
26
|
+
### Step 1: Identify the Next Task
|
|
27
|
+
- Grep the codebase, review the PRD, and check checklist.md to determine the next task in sequence.
|
|
28
|
+
- Focus only on the code areas relevant to the current task.
|
|
29
|
+
- Use the PRD’s priority levels and technical dependencies to select the next task, starting with Must-haves and respecting dependency order.
|
|
30
|
+
|
|
31
|
+
### Step 2: Write the Code
|
|
32
|
+
- Iterate on existing code if possible, avoiding new solutions unless necessary.
|
|
33
|
+
- Follow naming conventions and keep files under 500-700 lines, refactoring if needed.
|
|
34
|
+
- Add comments for complex logic.
|
|
35
|
+
- Avoid duplication by checking for similar functionality elsewhere in the codebase.
|
|
36
|
+
- Ensure code meets the PRD’s acceptance criteria for the task’s feature or user story.
|
|
37
|
+
- Adhere to non-functional requirements (e.g., performance, scalability) from the PRD when applicable.
|
|
38
|
+
|
|
39
|
+
### Step 3: Write Tests
|
|
40
|
+
- Write unit tests for individual functions and integration tests for workflows.
|
|
41
|
+
- Name tests clearly (e.g., testLoginSuccess, testUserCreationWorkflow).
|
|
42
|
+
- Ensure tests cover major functionality and edge cases outlined in the PRD.
|
|
43
|
+
- Make tests specific, measurable, and traceable to the PRD’s acceptance criteria (e.g., "User can log in with email/password" passes if the API returns a 200 status).
|
|
44
|
+
- Include tests for edge cases and error states documented in the PRD’s User Flows or AI-generated insights.
|
|
45
|
+
|
|
46
|
+
### Step 4: Run the Server and Tests
|
|
47
|
+
- Run all tests and verify they pass.
|
|
48
|
+
|
|
49
|
+
### Step 5: Handle Test Failures
|
|
50
|
+
- If tests fail, first review the test for accuracy (e.g., correct assertions, realistic mocks). Edit the test if it’s incorrect.
|
|
51
|
+
- If the test is valid and still fails, debug the code:
|
|
52
|
+
- Add logs/console messages to trace the issue.
|
|
53
|
+
- Fix the underlying problem rather than masking it.
|
|
54
|
+
- Re-run the server and tests after each change.
|
|
55
|
+
- Repeat until all tests pass. For persistent issues, check the fixes folder for prior solutions or use firecrawl to research fixes.
|
package/FEDERATION.md
CHANGED
|
@@ -66,9 +66,9 @@ await holoSphere.put('space1', 'items', data, null, {
|
|
|
66
66
|
You can access data directly from any space:
|
|
67
67
|
|
|
68
68
|
```javascript
|
|
69
|
-
// Retrieve data from space2 (will resolve
|
|
69
|
+
// Retrieve data from space2 (will resolve hologram if it's a hologram)
|
|
70
70
|
const data = await holoSphere.get('space2', 'items', 'item1', null, {
|
|
71
|
-
|
|
71
|
+
resolveHolograms: true // Default is true
|
|
72
72
|
});
|
|
73
73
|
```
|
|
74
74
|
|
|
@@ -79,25 +79,25 @@ Use `getFederated()` to get data from multiple federated spaces:
|
|
|
79
79
|
```javascript
|
|
80
80
|
// Get combined data from the local space and all its federated spaces
|
|
81
81
|
const federatedData = await holoSphere.getFederated('space2', 'items', {
|
|
82
|
-
|
|
82
|
+
resolveHolograms: true, // Default: true
|
|
83
83
|
idField: 'id' // Field to use as the unique identifier
|
|
84
84
|
});
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
## Soul
|
|
87
|
+
## Soul Holograms
|
|
88
88
|
|
|
89
|
-
HoloSphere uses a simplified
|
|
89
|
+
HoloSphere uses a simplified hologram system based on soul paths:
|
|
90
90
|
|
|
91
|
-
1. A
|
|
91
|
+
1. A hologram contains only an `id` and a `soul` property
|
|
92
92
|
2. The soul path is in the format: `appname/holon/lens/key`
|
|
93
|
-
3. When resolving a
|
|
93
|
+
3. When resolving a hologram, HoloSphere follows the soul path to retrieve the original data
|
|
94
94
|
|
|
95
|
-
By default, federation propagation uses
|
|
95
|
+
By default, federation propagation uses holograms instead of duplicating data. This can be controlled:
|
|
96
96
|
|
|
97
97
|
```javascript
|
|
98
|
-
// Propagate with full data copy instead of
|
|
98
|
+
// Propagate with full data copy instead of holograms
|
|
99
99
|
await holoSphere.propagate('space1', 'items', data, {
|
|
100
|
-
|
|
100
|
+
useHolograms: false
|
|
101
101
|
});
|
|
102
102
|
```
|
|
103
103
|
|
|
@@ -150,7 +150,7 @@ async function federationExample() {
|
|
|
150
150
|
// Allow time for propagation
|
|
151
151
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
152
152
|
|
|
153
|
-
// Step 5: Access data from space2 (resolves
|
|
153
|
+
// Step 5: Access data from space2 (resolves hologram)
|
|
154
154
|
const itemFromSpace2 = await holoSphere.get(space2, 'items', 'item1');
|
|
155
155
|
console.log('Item from space2:', itemFromSpace2);
|
|
156
156
|
|
|
@@ -163,10 +163,10 @@ async function federationExample() {
|
|
|
163
163
|
|
|
164
164
|
await holoSphere.put(space1, 'items', updatedItem);
|
|
165
165
|
|
|
166
|
-
// Since we're using soul
|
|
167
|
-
// through the
|
|
166
|
+
// Since we're using soul holograms, the update is immediately visible
|
|
167
|
+
// through the hologram without needing to propagate again
|
|
168
168
|
|
|
169
|
-
// Verify update is visible through the
|
|
169
|
+
// Verify update is visible through the hologram
|
|
170
170
|
const updatedItemFromSpace2 = await holoSphere.get(space2, 'items', 'item1');
|
|
171
171
|
console.log('Updated item from space2:', updatedItemFromSpace2);
|
|
172
172
|
|
|
@@ -193,7 +193,7 @@ federationExample().catch(console.error);
|
|
|
193
193
|
- The notify list includes the target space
|
|
194
194
|
|
|
195
195
|
3. **Reference Resolution**: If you're getting reference objects instead of the actual data:
|
|
196
|
-
- Make sure `
|
|
196
|
+
- Make sure `resolveHolograms` is set to `true` (it's the default)
|
|
197
197
|
- Check that the original data still exists at the referenced location
|
|
198
198
|
|
|
199
199
|
4. **Timing Issues**: Data propagation is asynchronous. Add small delays (500-1000ms) between operations to allow propagation to complete.
|
|
@@ -207,7 +207,7 @@ federationExample().catch(console.error);
|
|
|
207
207
|
2. **Explicit Propagation**: Unless you're using `autoPropagate`, always call `propagate()` explicitly after storing data that should be shared.
|
|
208
208
|
|
|
209
209
|
3. **Choose the Right Propagation Method**:
|
|
210
|
-
- Use `
|
|
211
|
-
- Use `
|
|
210
|
+
- Use `useHolograms: true` (default) to keep a single source of truth
|
|
211
|
+
- Use `useHolograms: false` only when you need independent copies
|
|
212
212
|
|
|
213
213
|
4. **Cleanup**: Always close the HoloSphere instance when done to prevent resource leaks.
|
package/compute.js
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
// holo_compute.js
|
|
2
|
+
import * as h3 from 'h3-js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Computes operations across multiple layers up the hierarchy
|
|
6
|
+
* @param {HoloSphere} holoInstance - The HoloSphere instance.
|
|
7
|
+
* @param {string} holon - Starting holon identifier
|
|
8
|
+
* @param {string} lens - The lens to compute
|
|
9
|
+
* @param {object} options - Computation options
|
|
10
|
+
* @param {number} [maxLevels=15] - Maximum levels to compute up
|
|
11
|
+
* @param {string} [password] - Optional password for private holons
|
|
12
|
+
*/
|
|
13
|
+
export async function computeHierarchy(holoInstance, holon, lens, options, maxLevels = 15, password = null) {
|
|
14
|
+
let currentHolon = holon;
|
|
15
|
+
let currentRes = h3.getResolution(currentHolon);
|
|
16
|
+
const results = [];
|
|
17
|
+
|
|
18
|
+
while (currentRes > 0 && maxLevels > 0) {
|
|
19
|
+
try {
|
|
20
|
+
// Use the instance's compute method
|
|
21
|
+
const result = await holoInstance.compute(currentHolon, lens, options, password);
|
|
22
|
+
if (result) {
|
|
23
|
+
results.push(result);
|
|
24
|
+
}
|
|
25
|
+
currentHolon = h3.cellToParent(currentHolon, currentRes - 1);
|
|
26
|
+
currentRes--;
|
|
27
|
+
maxLevels--;
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.error('Error in compute hierarchy:', error);
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return results;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Computes operations on content within a holon and lens for one layer up.
|
|
39
|
+
* @param {HoloSphere} holoInstance - The HoloSphere instance.
|
|
40
|
+
* @param {string} holon - The holon identifier.
|
|
41
|
+
* @param {string} lens - The lens to compute.
|
|
42
|
+
* @param {object} options - Computation options
|
|
43
|
+
* @param {string} options.operation - The operation to perform ('summarize', 'aggregate', 'concatenate')
|
|
44
|
+
* @param {string[]} [options.fields] - Fields to perform operation on
|
|
45
|
+
* @param {string} [options.targetField] - Field to store the result in
|
|
46
|
+
* @param {string} [password] - Optional password for private holons
|
|
47
|
+
* @throws {Error} If parameters are invalid or missing
|
|
48
|
+
*/
|
|
49
|
+
export async function compute(holoInstance, holon, lens, options, password = null) {
|
|
50
|
+
// Validate required parameters
|
|
51
|
+
if (!holon || !lens) {
|
|
52
|
+
throw new Error('compute: Missing required parameters');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Convert string operation to options object
|
|
56
|
+
if (typeof options === 'string') {
|
|
57
|
+
options = { operation: options };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!options?.operation) {
|
|
61
|
+
throw new Error('compute: Missing required parameters');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Validate holon format and resolution first
|
|
65
|
+
let res;
|
|
66
|
+
try {
|
|
67
|
+
res = h3.getResolution(holon);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
throw new Error('compute: Invalid holon format');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (res < 1 || res > 15) {
|
|
73
|
+
throw new Error('compute: Invalid holon resolution (must be between 1 and 15)');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const {
|
|
77
|
+
operation,
|
|
78
|
+
fields = [],
|
|
79
|
+
targetField,
|
|
80
|
+
depth,
|
|
81
|
+
maxDepth
|
|
82
|
+
} = options;
|
|
83
|
+
|
|
84
|
+
// Validate depth parameters if provided
|
|
85
|
+
if (depth !== undefined && depth < 0) {
|
|
86
|
+
throw new Error('compute: Invalid depth parameter');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (maxDepth !== undefined && (maxDepth < 1 || maxDepth > 15)) {
|
|
90
|
+
throw new Error('compute: Invalid maxDepth parameter (must be between 1 and 15)');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Validate operation
|
|
94
|
+
const validOperations = ['summarize', 'aggregate', 'concatenate'];
|
|
95
|
+
if (!validOperations.includes(operation)) {
|
|
96
|
+
throw new Error(`compute: Invalid operation (must be one of ${validOperations.join(', ')})`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const parent = h3.cellToParent(holon, res - 1);
|
|
100
|
+
const siblings = h3.cellToChildren(parent, res);
|
|
101
|
+
|
|
102
|
+
// Collect all content from siblings using instance's getAll
|
|
103
|
+
const contents = await Promise.all(
|
|
104
|
+
siblings.map(sibling => holoInstance.getAll(sibling, lens, password))
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const flatContents = contents.flat().filter(Boolean);
|
|
108
|
+
|
|
109
|
+
if (flatContents.length > 0) {
|
|
110
|
+
try {
|
|
111
|
+
let computed;
|
|
112
|
+
switch (operation) {
|
|
113
|
+
case 'summarize':
|
|
114
|
+
// For summarize, concatenate specified fields or use entire content
|
|
115
|
+
const textToSummarize = fields.length > 0
|
|
116
|
+
? flatContents.map(item => fields.map(field => item[field]).filter(Boolean).join('\n')).join('\n')
|
|
117
|
+
: JSON.stringify(flatContents);
|
|
118
|
+
computed = await holoInstance.summarize(textToSummarize); // Use instance's summarize
|
|
119
|
+
break;
|
|
120
|
+
|
|
121
|
+
case 'aggregate':
|
|
122
|
+
// For aggregate, sum numeric fields
|
|
123
|
+
computed = fields.reduce((acc, field) => {
|
|
124
|
+
acc[field] = flatContents.reduce((sum, item) => {
|
|
125
|
+
return sum + (Number(item[field]) || 0);
|
|
126
|
+
}, 0);
|
|
127
|
+
return acc;
|
|
128
|
+
}, {});
|
|
129
|
+
break;
|
|
130
|
+
|
|
131
|
+
case 'concatenate':
|
|
132
|
+
// For concatenate, combine arrays or strings
|
|
133
|
+
computed = fields.reduce((acc, field) => {
|
|
134
|
+
acc[field] = flatContents.reduce((combined, item) => {
|
|
135
|
+
const value = item[field];
|
|
136
|
+
if (Array.isArray(value)) {
|
|
137
|
+
return [...combined, ...value];
|
|
138
|
+
} else if (value) {
|
|
139
|
+
return [...combined, value];
|
|
140
|
+
}
|
|
141
|
+
return combined;
|
|
142
|
+
}, []);
|
|
143
|
+
// Remove duplicates if array
|
|
144
|
+
acc[field] = Array.from(new Set(acc[field]));
|
|
145
|
+
return acc;
|
|
146
|
+
}, {});
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (computed) {
|
|
151
|
+
const resultId = `${parent}_${operation}`;
|
|
152
|
+
const result = {
|
|
153
|
+
id: resultId,
|
|
154
|
+
timestamp: Date.now()
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// Store result in targetField if specified, otherwise at root level
|
|
158
|
+
if (targetField) {
|
|
159
|
+
result[targetField] = computed;
|
|
160
|
+
} else if (typeof computed === 'object') {
|
|
161
|
+
Object.assign(result, computed);
|
|
162
|
+
} else {
|
|
163
|
+
result.value = computed;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
await holoInstance.put(parent, lens, result, password); // Use instance's put
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.warn('Error in compute operation:', error);
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Summarizes provided history text using OpenAI.
|
|
180
|
+
* @param {HoloSphere} holoInstance - The HoloSphere instance.
|
|
181
|
+
* @param {string} history - The history text to summarize.
|
|
182
|
+
* @returns {Promise<string>} - The summarized text.
|
|
183
|
+
*/
|
|
184
|
+
export async function summarize(holoInstance, history) {
|
|
185
|
+
if (!holoInstance.openai) {
|
|
186
|
+
return 'OpenAI not initialized, please specify the API key in the constructor.'
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
const response = await holoInstance.openai.chat.completions.create({
|
|
191
|
+
model: "gpt-4",
|
|
192
|
+
messages: [
|
|
193
|
+
{
|
|
194
|
+
role: "system",
|
|
195
|
+
content: "You are a helpful assistant that summarizes text concisely while preserving key information. Keep summaries clear and focused."
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
role: "user",
|
|
199
|
+
content: history
|
|
200
|
+
}
|
|
201
|
+
],
|
|
202
|
+
temperature: 0.7,
|
|
203
|
+
max_tokens: 500
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
return response.choices[0].message.content.trim();
|
|
207
|
+
} catch (error) {
|
|
208
|
+
console.error('Error in summarize:', error);
|
|
209
|
+
throw new Error('Failed to generate summary');
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Upcasts content to parent holonagons recursively using holograms.
|
|
215
|
+
* @param {HoloSphere} holoInstance - The HoloSphere instance.
|
|
216
|
+
* @param {string} holon - The current holon identifier.
|
|
217
|
+
* @param {string} lens - The lens under which to upcast.
|
|
218
|
+
* @param {object} content - The content to upcast.
|
|
219
|
+
* @param {number} [maxLevels=15] - Maximum levels to upcast.
|
|
220
|
+
* @returns {Promise<object>} - The original content.
|
|
221
|
+
*/
|
|
222
|
+
export async function upcast(holoInstance, holon, lens, content, maxLevels = 15) {
|
|
223
|
+
// Store the actual content at the original resolution using instance's put
|
|
224
|
+
await holoInstance.put(holon, lens, content);
|
|
225
|
+
|
|
226
|
+
let res = h3.getResolution(holon);
|
|
227
|
+
|
|
228
|
+
// If already at the highest level (res 0) or reached max levels, we're done
|
|
229
|
+
if (res === 0 || maxLevels <= 0) {
|
|
230
|
+
return content;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Get the parent cell
|
|
234
|
+
let parent = h3.cellToParent(holon, res - 1);
|
|
235
|
+
|
|
236
|
+
// Create a hologram to store in the parent using instance's createHologram
|
|
237
|
+
const hologram = holoInstance.createHologram(holon, lens, content);
|
|
238
|
+
|
|
239
|
+
// Store the hologram in the parent cell using instance's put
|
|
240
|
+
await holoInstance.put(parent, lens, hologram, null, {
|
|
241
|
+
autoPropagate: false
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// Continue upcasting with the parent using instance's upcast
|
|
245
|
+
if (res > 1 && maxLevels > 1) {
|
|
246
|
+
// Recursively call the instance's upcast method
|
|
247
|
+
// Pass the *hologram* to the next level, not the original content
|
|
248
|
+
return holoInstance.upcast(parent, lens, hologram, maxLevels - 1);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return content;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Updates the parent holon with a new report.
|
|
256
|
+
* Note: This function assumes the existence of `getCellInfo` and `db.put` on the holoInstance,
|
|
257
|
+
* which were not defined in the original class. Adjust as needed.
|
|
258
|
+
* @param {HoloSphere} holoInstance - The HoloSphere instance.
|
|
259
|
+
* @param {string} id - The child holon identifier.
|
|
260
|
+
* @param {string} report - The report to update.
|
|
261
|
+
* @returns {Promise<object>} - The updated parent information.
|
|
262
|
+
*/
|
|
263
|
+
export async function updateParent(holoInstance, id, report) {
|
|
264
|
+
// Check if required methods exist on the instance
|
|
265
|
+
if (typeof holoInstance.getCellInfo !== 'function' || !holoInstance.db || typeof holoInstance.db.put !== 'function') {
|
|
266
|
+
console.warn('updateParent requires getCellInfo and db.put methods on the HoloSphere instance.');
|
|
267
|
+
// Decide how to handle this: throw error, return null, etc.
|
|
268
|
+
// For now, let's proceed assuming they might exist but log a warning.
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
try {
|
|
272
|
+
let cellinfo = await holoInstance.getCellInfo(id)
|
|
273
|
+
let res = h3.getResolution(id)
|
|
274
|
+
let parent = h3.cellToParent(id, res - 1)
|
|
275
|
+
let parentInfo = await holoInstance.getCellInfo(parent)
|
|
276
|
+
parentInfo.wisdom[id] = report
|
|
277
|
+
//update summary using instance's summarize
|
|
278
|
+
let summary = await holoInstance.summarize(Object.values(parentInfo.wisdom).join('\n'))
|
|
279
|
+
parentInfo.summary = summary
|
|
280
|
+
|
|
281
|
+
// Assuming db is accessible like this
|
|
282
|
+
await holoInstance.db.put('cell', parentInfo)
|
|
283
|
+
return parentInfo
|
|
284
|
+
} catch (error) {
|
|
285
|
+
console.error("Error during updateParent:", error);
|
|
286
|
+
// Re-throw or handle error appropriately
|
|
287
|
+
throw error;
|
|
288
|
+
}
|
|
289
|
+
}
|