holosphere 1.1.19 → 1.1.20
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 +2 -173
- package/content.js +3 -45
- package/holosphere-bundle.esm.js +12 -1305
- package/holosphere-bundle.js +12 -1305
- package/holosphere-bundle.min.js +20 -30
- package/holosphere.d.ts +16 -19
- package/holosphere.js +16 -36
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -136,135 +136,21 @@ npm install holosphere
|
|
|
136
136
|
|
|
137
137
|
## Quick Start
|
|
138
138
|
|
|
139
|
-
### Node.js Usage
|
|
140
|
-
|
|
141
139
|
```javascript
|
|
142
140
|
import HoloSphere from 'holosphere';
|
|
143
141
|
|
|
144
|
-
// Initialize HoloSphere
|
|
142
|
+
// Initialize HoloSphere
|
|
145
143
|
const sphere = new HoloSphere('my-app');
|
|
146
144
|
|
|
147
|
-
//
|
|
148
|
-
sphere.configureRadisk({
|
|
149
|
-
file: './my-data', // Custom storage directory
|
|
150
|
-
radisk: true, // Enable disk persistence
|
|
151
|
-
retry: 3, // Retry failed operations
|
|
152
|
-
timeout: 5000 // Operation timeout
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
// Store data at a location (persisted to disk)
|
|
145
|
+
// Store data at a location
|
|
156
146
|
const holon = await sphere.getHolon(40.7128, -74.0060, 7); // NYC at resolution 7
|
|
157
147
|
await sphere.put(holon, 'observations', {
|
|
158
148
|
id: 'obs-001',
|
|
159
149
|
temperature: 22.5,
|
|
160
150
|
timestamp: Date.now()
|
|
161
151
|
});
|
|
162
|
-
|
|
163
|
-
// Retrieve data (from memory or disk)
|
|
164
|
-
const data = await sphere.get(holon, 'observations', 'obs-001');
|
|
165
|
-
console.log(data);
|
|
166
|
-
|
|
167
|
-
// Get radisk statistics
|
|
168
|
-
const stats = sphere.getRadiskStats();
|
|
169
|
-
console.log('Storage stats:', stats);
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### Browser Usage
|
|
173
|
-
|
|
174
|
-
HoloSphere works seamlessly in browsers with radisk persistence. The bundle automatically includes radisk support:
|
|
175
|
-
|
|
176
|
-
```html
|
|
177
|
-
<!DOCTYPE html>
|
|
178
|
-
<html>
|
|
179
|
-
<head>
|
|
180
|
-
<title>HoloSphere Browser Example</title>
|
|
181
|
-
</head>
|
|
182
|
-
<body>
|
|
183
|
-
<!-- Load HoloSphere Bundle -->
|
|
184
|
-
<script src="https://unpkg.com/holosphere@1.1.18/holosphere-bundle.js"></script>
|
|
185
|
-
|
|
186
|
-
<script>
|
|
187
|
-
// Radisk is enabled by default in browser
|
|
188
|
-
const sphere = new HoloSphere('browser-app');
|
|
189
|
-
|
|
190
|
-
// Store data (persisted via IndexedDB)
|
|
191
|
-
async function storeData() {
|
|
192
|
-
const holon = await sphere.getHolon(40.7128, -74.0060, 7);
|
|
193
|
-
await sphere.put(holon, 'observations', {
|
|
194
|
-
id: 'browser-obs-001',
|
|
195
|
-
temperature: 22.5,
|
|
196
|
-
timestamp: Date.now()
|
|
197
|
-
});
|
|
198
|
-
console.log('Data stored and persisted!');
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Retrieve data (from IndexedDB)
|
|
202
|
-
async function retrieveData() {
|
|
203
|
-
const holon = await sphere.getHolon(40.7128, -74.0060, 7);
|
|
204
|
-
const data = await sphere.get(holon, 'observations', 'browser-obs-001');
|
|
205
|
-
console.log('Retrieved data:', data);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Check radisk status
|
|
209
|
-
const stats = sphere.getRadiskStats();
|
|
210
|
-
console.log('Radisk stats:', stats);
|
|
211
|
-
</script>
|
|
212
|
-
</body>
|
|
213
|
-
</html>
|
|
214
152
|
```
|
|
215
153
|
|
|
216
|
-
**Key Browser Features:**
|
|
217
|
-
- ✅ Radisk automatically included in bundle
|
|
218
|
-
- ✅ Data persists across page reloads via IndexedDB
|
|
219
|
-
- ✅ Works offline with local storage
|
|
220
|
-
- ✅ No additional configuration needed
|
|
221
|
-
- ✅ Compatible with all modern browsers
|
|
222
|
-
|
|
223
|
-
See `examples/radisk-browser-example.html` for a complete working example.
|
|
224
|
-
|
|
225
|
-
### Svelte/SvelteKit Usage
|
|
226
|
-
|
|
227
|
-
HoloSphere works seamlessly with Svelte and SvelteKit applications:
|
|
228
|
-
|
|
229
|
-
```svelte
|
|
230
|
-
<script>
|
|
231
|
-
import { onMount } from 'svelte';
|
|
232
|
-
import { browser } from '$app/environment'; // SvelteKit only
|
|
233
|
-
import HoloSphere from 'holosphere';
|
|
234
|
-
|
|
235
|
-
let hs = null;
|
|
236
|
-
|
|
237
|
-
async function initHoloSphere() {
|
|
238
|
-
// Client-side only for SvelteKit
|
|
239
|
-
if (typeof browser !== 'undefined' && !browser) return;
|
|
240
|
-
|
|
241
|
-
hs = new HoloSphere('my-app', false, null, {
|
|
242
|
-
radisk: true,
|
|
243
|
-
file: './app-radata'
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
onMount(() => {
|
|
248
|
-
initHoloSphere();
|
|
249
|
-
});
|
|
250
|
-
</script>
|
|
251
|
-
|
|
252
|
-
<main>
|
|
253
|
-
<button on:click={() => storeData()} disabled={!hs}>
|
|
254
|
-
Store Data
|
|
255
|
-
</button>
|
|
256
|
-
</main>
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
**Key Svelte Features:**
|
|
260
|
-
- ✅ Full Svelte and SvelteKit compatibility
|
|
261
|
-
- ✅ SSR-safe initialization
|
|
262
|
-
- ✅ Reactive data binding
|
|
263
|
-
- ✅ Component lifecycle management
|
|
264
|
-
- ✅ Persistent storage across navigation
|
|
265
|
-
|
|
266
|
-
See `examples/svelte-holosphere-example.svelte` and `examples/sveltekit-holosphere-example/+page.svelte` for complete examples.
|
|
267
|
-
|
|
268
154
|
## Real-World Examples
|
|
269
155
|
|
|
270
156
|
### Environmental Monitoring System
|
|
@@ -558,63 +444,6 @@ await holosphere.updateFederatedMessages('chat1', 'msg1', async (chatId, message
|
|
|
558
444
|
});
|
|
559
445
|
```
|
|
560
446
|
|
|
561
|
-
## Radisk Storage Configuration
|
|
562
|
-
|
|
563
|
-
HoloSphere uses GunDB's radisk module for persistent storage. Data is automatically saved to disk and can survive application restarts.
|
|
564
|
-
|
|
565
|
-
### Basic Configuration
|
|
566
|
-
|
|
567
|
-
```javascript
|
|
568
|
-
// Configure radisk with custom options
|
|
569
|
-
sphere.configureRadisk({
|
|
570
|
-
file: './my-data', // Storage directory
|
|
571
|
-
radisk: true, // Enable disk persistence
|
|
572
|
-
retry: 3, // Retry failed operations
|
|
573
|
-
timeout: 5000 // Operation timeout in ms
|
|
574
|
-
});
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
### Get Storage Statistics
|
|
578
|
-
|
|
579
|
-
```javascript
|
|
580
|
-
const stats = sphere.getRadiskStats();
|
|
581
|
-
console.log(stats);
|
|
582
|
-
// Output:
|
|
583
|
-
// {
|
|
584
|
-
// enabled: true,
|
|
585
|
-
// filePath: './my-data',
|
|
586
|
-
// retry: 3,
|
|
587
|
-
// timeout: 5000,
|
|
588
|
-
// until: null,
|
|
589
|
-
// peers: ['https://gun.holons.io/gun'],
|
|
590
|
-
// localStorage: false
|
|
591
|
-
// }
|
|
592
|
-
```
|
|
593
|
-
|
|
594
|
-
### Radisk Options
|
|
595
|
-
|
|
596
|
-
- `file`: Directory for storing data files (default: `'./radata'`)
|
|
597
|
-
- `radisk`: Enable/disable disk persistence (default: `true`)
|
|
598
|
-
- `retry`: Number of retries for failed operations (default: `3`)
|
|
599
|
-
- `timeout`: Operation timeout in milliseconds (default: `5000`)
|
|
600
|
-
- `until`: Timestamp until which to keep data (optional)
|
|
601
|
-
|
|
602
|
-
### Data Persistence
|
|
603
|
-
|
|
604
|
-
All data stored via HoloSphere is automatically persisted to disk:
|
|
605
|
-
|
|
606
|
-
```javascript
|
|
607
|
-
// This data will be saved to disk
|
|
608
|
-
await sphere.put(holon, 'environment', {
|
|
609
|
-
id: 'reading-001',
|
|
610
|
-
temperature: 22.5,
|
|
611
|
-
timestamp: Date.now()
|
|
612
|
-
});
|
|
613
|
-
|
|
614
|
-
// Data persists across application restarts
|
|
615
|
-
const data = await sphere.get(holon, 'environment', 'reading-001');
|
|
616
|
-
```
|
|
617
|
-
|
|
618
447
|
## Soul References
|
|
619
448
|
|
|
620
449
|
When using the default `useReferences: true` with propagation:
|
package/content.js
CHANGED
|
@@ -151,10 +151,7 @@ export async function put(holoInstance, holon, lens, data, password = null, opti
|
|
|
151
151
|
|
|
152
152
|
const putCallback = async (ack) => {
|
|
153
153
|
if (ack.err) {
|
|
154
|
-
|
|
155
|
-
// If it's an object, convert it to JSON string for better error reporting
|
|
156
|
-
const errorMessage = typeof ack.err === 'object' ? JSON.stringify(ack.err) : ack.err;
|
|
157
|
-
reject(new Error(errorMessage));
|
|
154
|
+
reject(new Error(ack.err));
|
|
158
155
|
} else {
|
|
159
156
|
// --- Start: Hologram Tracking Logic (for data *being put*, if it's a hologram) ---
|
|
160
157
|
if (isHologram) {
|
|
@@ -642,57 +639,18 @@ export async function parse(holoInstance, rawData) {
|
|
|
642
639
|
} else if (rawData._) {
|
|
643
640
|
// Handle potential GunDB metadata remnants (attempt cleanup)
|
|
644
641
|
console.warn('Parsing raw Gun object with metadata (_) - attempting cleanup:', rawData);
|
|
645
|
-
|
|
646
|
-
// Enhanced cleanup for complex GunDB structures
|
|
647
642
|
const potentialData = Object.keys(rawData).reduce((acc, k) => {
|
|
648
643
|
if (k !== '_') {
|
|
649
|
-
|
|
650
|
-
if (rawData[k] && typeof rawData[k] === 'object' && rawData[k]._) {
|
|
651
|
-
// Recursively parse nested raw nodes
|
|
652
|
-
const parsedNested = parse(holoInstance, rawData[k]);
|
|
653
|
-
if (parsedNested !== null) {
|
|
654
|
-
acc[k] = parsedNested;
|
|
655
|
-
}
|
|
656
|
-
} else if (rawData[k] !== null) {
|
|
657
|
-
// Only include non-null values
|
|
658
|
-
acc[k] = rawData[k];
|
|
659
|
-
}
|
|
644
|
+
acc[k] = rawData[k];
|
|
660
645
|
}
|
|
661
646
|
return acc;
|
|
662
647
|
}, {});
|
|
663
|
-
|
|
664
648
|
if (Object.keys(potentialData).length === 0) {
|
|
665
|
-
console.warn('Raw Gun object had only metadata (_)
|
|
666
|
-
return null;
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
// Additional validation: check if the cleaned object has meaningful data
|
|
670
|
-
const hasValidData = Object.values(potentialData).some(value =>
|
|
671
|
-
value !== null && value !== undefined &&
|
|
672
|
-
(typeof value !== 'object' || Object.keys(value).length > 0)
|
|
673
|
-
);
|
|
674
|
-
|
|
675
|
-
if (!hasValidData) {
|
|
676
|
-
console.warn('Cleaned Gun object has no valid data, returning null.');
|
|
649
|
+
console.warn('Raw Gun object had only metadata (_), returning null.');
|
|
677
650
|
return null;
|
|
678
651
|
}
|
|
679
|
-
|
|
680
652
|
return potentialData; // Return cleaned-up object
|
|
681
653
|
} else {
|
|
682
|
-
// Check for objects that might be arrays of raw GunDB nodes
|
|
683
|
-
if (Array.isArray(rawData)) {
|
|
684
|
-
const cleanedArray = rawData
|
|
685
|
-
.map(item => parse(holoInstance, item))
|
|
686
|
-
.filter(item => item !== null);
|
|
687
|
-
|
|
688
|
-
if (cleanedArray.length === 0) {
|
|
689
|
-
console.warn('Array contained only invalid/raw GunDB nodes, returning null.');
|
|
690
|
-
return null;
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
return cleanedArray;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
654
|
// Assume it's a regular plain object
|
|
697
655
|
return rawData;
|
|
698
656
|
}
|