holosphere 2.0.0-alpha0 → 2.0.0-alpha2
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/LICENSE +162 -38
- package/dist/cjs/holosphere.cjs +2 -0
- package/dist/cjs/holosphere.cjs.map +1 -0
- package/dist/esm/holosphere.js +56 -0
- package/dist/esm/holosphere.js.map +1 -0
- package/dist/index-CDfIuXew.js +15974 -0
- package/dist/index-CDfIuXew.js.map +1 -0
- package/dist/index-ifOgtDvd.cjs +3 -0
- package/dist/index-ifOgtDvd.cjs.map +1 -0
- package/dist/indexeddb-storage-CMW4qRQS.js +96 -0
- package/dist/indexeddb-storage-CMW4qRQS.js.map +1 -0
- package/dist/indexeddb-storage-DLZOgetM.cjs +2 -0
- package/dist/indexeddb-storage-DLZOgetM.cjs.map +1 -0
- package/dist/memory-storage-DQzcAZlf.js +47 -0
- package/dist/memory-storage-DQzcAZlf.js.map +1 -0
- package/dist/memory-storage-DmePEP2q.cjs +2 -0
- package/dist/memory-storage-DmePEP2q.cjs.map +1 -0
- package/dist/secp256k1-CP0ZkpAx.cjs +13 -0
- package/dist/secp256k1-CP0ZkpAx.cjs.map +1 -0
- package/dist/secp256k1-vOXp40Fx.js +2281 -0
- package/dist/secp256k1-vOXp40Fx.js.map +1 -0
- package/docs/FOSDEM_PROPOSAL.md +388 -0
- package/docs/LOCALFIRST.md +266 -0
- package/docs/contracts/api-interface.md +793 -0
- package/docs/data-model.md +476 -0
- package/docs/gun-async-usage.md +338 -0
- package/docs/plan.md +349 -0
- package/docs/quickstart.md +674 -0
- package/docs/research.md +362 -0
- package/docs/spec.md +244 -0
- package/docs/storage-backends.md +326 -0
- package/docs/tasks.md +947 -0
- package/package.json +1 -1
- package/tests/unit/ai/aggregation.test.js +0 -295
- package/tests/unit/ai/breakdown.test.js +0 -446
- package/tests/unit/ai/classifier.test.js +0 -294
- package/tests/unit/ai/council.test.js +0 -262
- package/tests/unit/ai/embeddings.test.js +0 -384
- package/tests/unit/ai/federation-ai.test.js +0 -344
- package/tests/unit/ai/h3-ai.test.js +0 -458
- package/tests/unit/ai/index.test.js +0 -304
- package/tests/unit/ai/json-ops.test.js +0 -307
- package/tests/unit/ai/llm-service.test.js +0 -390
- package/tests/unit/ai/nl-query.test.js +0 -383
- package/tests/unit/ai/relationships.test.js +0 -311
- package/tests/unit/ai/schema-extractor.test.js +0 -384
- package/tests/unit/ai/spatial.test.js +0 -279
- package/tests/unit/ai/tts.test.js +0 -279
- package/tests/unit/content.test.js +0 -332
- package/tests/unit/contract/core.test.js +0 -88
- package/tests/unit/contract/crypto.test.js +0 -198
- package/tests/unit/contract/data.test.js +0 -223
- package/tests/unit/contract/federation.test.js +0 -181
- package/tests/unit/contract/hierarchical.test.js +0 -113
- package/tests/unit/contract/schema.test.js +0 -114
- package/tests/unit/contract/social.test.js +0 -217
- package/tests/unit/contract/spatial.test.js +0 -110
- package/tests/unit/contract/subscriptions.test.js +0 -128
- package/tests/unit/contract/utils.test.js +0 -159
- package/tests/unit/core.test.js +0 -152
- package/tests/unit/crypto.test.js +0 -328
- package/tests/unit/federation.test.js +0 -234
- package/tests/unit/gun-async.test.js +0 -252
- package/tests/unit/hierarchical.test.js +0 -399
- package/tests/unit/integration/scenario-01-geographic-storage.test.js +0 -74
- package/tests/unit/integration/scenario-02-federation.test.js +0 -76
- package/tests/unit/integration/scenario-03-subscriptions.test.js +0 -102
- package/tests/unit/integration/scenario-04-validation.test.js +0 -129
- package/tests/unit/integration/scenario-05-hierarchy.test.js +0 -125
- package/tests/unit/integration/scenario-06-social.test.js +0 -135
- package/tests/unit/integration/scenario-07-persistence.test.js +0 -130
- package/tests/unit/integration/scenario-08-authorization.test.js +0 -161
- package/tests/unit/integration/scenario-09-cross-dimensional.test.js +0 -139
- package/tests/unit/integration/scenario-10-cross-holosphere-capabilities.test.js +0 -357
- package/tests/unit/integration/scenario-11-cross-holosphere-federation.test.js +0 -410
- package/tests/unit/integration/scenario-12-capability-federated-read.test.js +0 -719
- package/tests/unit/performance/benchmark.test.js +0 -85
- package/tests/unit/schema.test.js +0 -213
- package/tests/unit/spatial.test.js +0 -158
- package/tests/unit/storage.test.js +0 -195
- package/tests/unit/subscriptions.test.js +0 -328
- package/tests/unit/test-data-permanence-debug.js +0 -197
- package/tests/unit/test-data-permanence.js +0 -340
- package/tests/unit/test-key-persistence-fixed.js +0 -148
- package/tests/unit/test-key-persistence.js +0 -172
- package/tests/unit/test-relay-permanence.js +0 -376
- package/tests/unit/test-second-node.js +0 -95
- package/tests/unit/test-simple-write.js +0 -89
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
# HoloSphere Storage Backends
|
|
2
|
+
|
|
3
|
+
HoloSphere supports multiple storage backends, allowing you to choose the best option for your deployment requirements. All backends expose the same API, ensuring your application code works identically regardless of which backend you use.
|
|
4
|
+
|
|
5
|
+
## Available Backends
|
|
6
|
+
|
|
7
|
+
| Backend | Description | Best For |
|
|
8
|
+
|---------|-------------|----------|
|
|
9
|
+
| **Nostr** (default) | Decentralized relay network | Censorship-resistant, public data |
|
|
10
|
+
| **GunDB** | Real-time P2P database | Offline-first, real-time sync |
|
|
11
|
+
| **ActivityPub** | Fediverse federation | Integration with Mastodon, Pleroma |
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Nostr Backend (Default)
|
|
16
|
+
|
|
17
|
+
The Nostr backend uses the Nostr protocol for decentralized data storage across relay servers.
|
|
18
|
+
|
|
19
|
+
### Configuration
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
import HoloSphere from 'holosphere';
|
|
23
|
+
|
|
24
|
+
const hs = new HoloSphere({
|
|
25
|
+
appName: 'myapp',
|
|
26
|
+
backend: 'nostr', // Optional - this is the default
|
|
27
|
+
relays: [
|
|
28
|
+
'wss://relay.damus.io',
|
|
29
|
+
'wss://relay.nostr.band',
|
|
30
|
+
'wss://nos.lol'
|
|
31
|
+
],
|
|
32
|
+
privateKey: 'hex-encoded-private-key', // Optional - auto-generated if not provided
|
|
33
|
+
persistence: true, // Enable local caching (default: true)
|
|
34
|
+
dataDir: './data' // Custom data directory
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Features
|
|
39
|
+
- Decentralized storage across multiple relays
|
|
40
|
+
- Cryptographic identity via secp256k1 keys
|
|
41
|
+
- Built-in event caching for performance
|
|
42
|
+
- Offline support with guaranteed delivery queue
|
|
43
|
+
- NIP-09 compliant deletion
|
|
44
|
+
|
|
45
|
+
### When to Use
|
|
46
|
+
- Public, censorship-resistant applications
|
|
47
|
+
- Applications requiring cryptographic verification
|
|
48
|
+
- Social features compatible with Nostr ecosystem
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## GunDB Backend
|
|
53
|
+
|
|
54
|
+
The GunDB backend provides real-time P2P synchronization with offline-first capabilities.
|
|
55
|
+
|
|
56
|
+
### Installation
|
|
57
|
+
|
|
58
|
+
GunDB is an optional dependency. Install it before using this backend:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm install gun
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Configuration
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
import HoloSphere from 'holosphere';
|
|
68
|
+
|
|
69
|
+
const hs = new HoloSphere({
|
|
70
|
+
appName: 'myapp',
|
|
71
|
+
backend: 'gundb',
|
|
72
|
+
gundb: {
|
|
73
|
+
peers: [
|
|
74
|
+
'https://gun-us.example.com/gun',
|
|
75
|
+
'https://gun-eu.example.com/gun'
|
|
76
|
+
],
|
|
77
|
+
radisk: true, // Persistent storage (default: true)
|
|
78
|
+
localStorage: true // Browser localStorage (default: true)
|
|
79
|
+
},
|
|
80
|
+
dataDir: './gun-data'
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Wait for backend initialization
|
|
84
|
+
await hs.ready();
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Features
|
|
88
|
+
- Real-time P2P synchronization
|
|
89
|
+
- Offline-first with automatic sync
|
|
90
|
+
- Built-in conflict resolution (CRDT)
|
|
91
|
+
- Works without central server
|
|
92
|
+
|
|
93
|
+
### When to Use
|
|
94
|
+
- Real-time collaborative applications
|
|
95
|
+
- Offline-first mobile/desktop apps
|
|
96
|
+
- Applications requiring P2P sync without relays
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## ActivityPub Backend
|
|
101
|
+
|
|
102
|
+
The ActivityPub backend enables federation with the Fediverse (Mastodon, Pleroma, etc.).
|
|
103
|
+
|
|
104
|
+
### Architecture
|
|
105
|
+
|
|
106
|
+
The ActivityPub backend requires a separate server process:
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
┌─────────────────┐ HTTP ┌─────────────────────┐
|
|
110
|
+
│ Your App │◄────────────►│ ActivityPub Server │
|
|
111
|
+
│ (HoloSphere) │ │ (holosphere-ap) │
|
|
112
|
+
└─────────────────┘ └─────────────────────┘
|
|
113
|
+
│
|
|
114
|
+
│ ActivityPub
|
|
115
|
+
▼
|
|
116
|
+
┌─────────────────┐
|
|
117
|
+
│ Mastodon/ │
|
|
118
|
+
│ Pleroma/etc │
|
|
119
|
+
└─────────────────┘
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Starting the Server
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Start with default settings
|
|
126
|
+
holosphere-activitypub
|
|
127
|
+
|
|
128
|
+
# Start with custom configuration
|
|
129
|
+
holosphere-activitypub \
|
|
130
|
+
--port 3000 \
|
|
131
|
+
--domain myholosphere.example.com \
|
|
132
|
+
--data-dir ./ap-data \
|
|
133
|
+
--protocol https
|
|
134
|
+
|
|
135
|
+
# Or use environment variables
|
|
136
|
+
export HOLOSPHERE_AP_PORT=3000
|
|
137
|
+
export HOLOSPHERE_AP_DOMAIN=myholosphere.example.com
|
|
138
|
+
export HOLOSPHERE_AP_DATADIR=./ap-data
|
|
139
|
+
export HOLOSPHERE_AP_PROTOCOL=https
|
|
140
|
+
holosphere-activitypub
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Server Endpoints
|
|
144
|
+
|
|
145
|
+
| Endpoint | Description |
|
|
146
|
+
|----------|-------------|
|
|
147
|
+
| `/.well-known/webfinger` | Actor discovery (required for federation) |
|
|
148
|
+
| `/actor/:name` | Actor profile |
|
|
149
|
+
| `/actor/:name/inbox` | Receive activities from federated servers |
|
|
150
|
+
| `/actor/:name/outbox` | Published activities |
|
|
151
|
+
| `/api/data` | HoloSphere data API |
|
|
152
|
+
| `/subscribe` | Server-Sent Events for real-time updates |
|
|
153
|
+
| `/health` | Health check |
|
|
154
|
+
|
|
155
|
+
### Client Configuration
|
|
156
|
+
|
|
157
|
+
```javascript
|
|
158
|
+
import HoloSphere from 'holosphere';
|
|
159
|
+
|
|
160
|
+
const hs = new HoloSphere({
|
|
161
|
+
appName: 'myapp',
|
|
162
|
+
backend: 'activitypub',
|
|
163
|
+
activitypub: {
|
|
164
|
+
serverUrl: 'http://localhost:3000',
|
|
165
|
+
apiKey: 'optional-api-key' // For authentication
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Wait for connection to server
|
|
170
|
+
await hs.ready();
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Federation with Mastodon
|
|
174
|
+
|
|
175
|
+
1. Deploy your ActivityPub server with a public domain
|
|
176
|
+
2. Configure HTTPS (required for federation)
|
|
177
|
+
3. Set up DNS records
|
|
178
|
+
4. Users can follow your actors from Mastodon: `@myapp@myholosphere.example.com`
|
|
179
|
+
|
|
180
|
+
### When to Use
|
|
181
|
+
- Integration with existing Fediverse communities
|
|
182
|
+
- Building social features compatible with Mastodon
|
|
183
|
+
- Applications requiring W3C ActivityPub compliance
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Data Migration
|
|
188
|
+
|
|
189
|
+
HoloSphere provides tools to migrate data between backends.
|
|
190
|
+
|
|
191
|
+
### Using the Migration Tool
|
|
192
|
+
|
|
193
|
+
```javascript
|
|
194
|
+
import { MigrationTool, quickMigrate } from 'holosphere/storage/migration';
|
|
195
|
+
|
|
196
|
+
// Option 1: Full control
|
|
197
|
+
const migration = new MigrationTool();
|
|
198
|
+
|
|
199
|
+
// Configure source
|
|
200
|
+
await migration.setSource('nostr', {
|
|
201
|
+
appName: 'myapp',
|
|
202
|
+
relays: ['wss://relay.damus.io']
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Configure target
|
|
206
|
+
await migration.setTarget('gundb', {
|
|
207
|
+
appName: 'myapp',
|
|
208
|
+
gundb: { peers: [] }
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Run migration
|
|
212
|
+
const results = await migration.migrate('myapp/');
|
|
213
|
+
console.log(`Migrated ${results.success} records`);
|
|
214
|
+
|
|
215
|
+
// Validate
|
|
216
|
+
const validation = await migration.validate('myapp/');
|
|
217
|
+
if (!validation.valid) {
|
|
218
|
+
console.error('Missing records:', validation.missing);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
migration.close();
|
|
222
|
+
|
|
223
|
+
// Option 2: Quick migrate
|
|
224
|
+
await quickMigrate(
|
|
225
|
+
{ type: 'nostr', appName: 'myapp', relays: ['wss://relay.damus.io'] },
|
|
226
|
+
{ type: 'activitypub', appName: 'myapp', activitypub: { serverUrl: 'http://localhost:3000' } }
|
|
227
|
+
);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Export/Import for Backup
|
|
231
|
+
|
|
232
|
+
```javascript
|
|
233
|
+
const migration = new MigrationTool();
|
|
234
|
+
await migration.setSource('nostr', { appName: 'myapp', relays: [] });
|
|
235
|
+
|
|
236
|
+
// Export to file
|
|
237
|
+
const bundle = await migration.export();
|
|
238
|
+
await migration.exportToFile(bundle, './backup.json');
|
|
239
|
+
|
|
240
|
+
// Later: Import from file
|
|
241
|
+
const loadedBundle = await migration.importFromFile('./backup.json');
|
|
242
|
+
await migration.setTarget('gundb', { appName: 'myapp', gundb: {} });
|
|
243
|
+
await migration.import(loadedBundle);
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Choosing a Backend
|
|
249
|
+
|
|
250
|
+
| Requirement | Recommended Backend |
|
|
251
|
+
|-------------|---------------------|
|
|
252
|
+
| Censorship resistance | Nostr |
|
|
253
|
+
| Real-time collaboration | GunDB |
|
|
254
|
+
| Fediverse integration | ActivityPub |
|
|
255
|
+
| Offline-first | GunDB or Nostr |
|
|
256
|
+
| Cryptographic identity | Nostr |
|
|
257
|
+
| Self-hosted | Any (Nostr relays, Gun peers, or AP server) |
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Custom Backends
|
|
262
|
+
|
|
263
|
+
You can implement custom storage backends by extending the `StorageBackend` interface:
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
import { StorageBackend, BackendFactory } from 'holosphere/storage';
|
|
267
|
+
|
|
268
|
+
class MyCustomBackend extends StorageBackend {
|
|
269
|
+
async init() { /* ... */ }
|
|
270
|
+
buildPath(appName, holonId, lensName, key) { /* ... */ }
|
|
271
|
+
async write(path, data, options) { /* ... */ }
|
|
272
|
+
async read(path, options) { /* ... */ }
|
|
273
|
+
async readAll(path, options) { /* ... */ }
|
|
274
|
+
async update(path, updates) { /* ... */ }
|
|
275
|
+
async delete(path) { /* ... */ }
|
|
276
|
+
async deleteAll(path) { /* ... */ }
|
|
277
|
+
async subscribe(path, callback, options) { /* ... */ }
|
|
278
|
+
async exportData(pathPrefix) { /* ... */ }
|
|
279
|
+
async importData(records, options) { /* ... */ }
|
|
280
|
+
close() { /* ... */ }
|
|
281
|
+
getStatus() { /* ... */ }
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Register custom backend
|
|
285
|
+
BackendFactory.register('custom', MyCustomBackend);
|
|
286
|
+
|
|
287
|
+
// Use it
|
|
288
|
+
const hs = new HoloSphere({
|
|
289
|
+
appName: 'myapp',
|
|
290
|
+
backend: 'custom',
|
|
291
|
+
// ... custom config
|
|
292
|
+
});
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Backend API Reference
|
|
298
|
+
|
|
299
|
+
All backends implement the `StorageBackend` interface:
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
interface StorageBackend {
|
|
303
|
+
// Initialization
|
|
304
|
+
init(): Promise<void>;
|
|
305
|
+
close(): void;
|
|
306
|
+
getStatus(): BackendStatus;
|
|
307
|
+
|
|
308
|
+
// Path building
|
|
309
|
+
buildPath(appName: string, holonId: string, lensName: string, key?: string): string;
|
|
310
|
+
|
|
311
|
+
// CRUD operations
|
|
312
|
+
write(path: string, data: object, options?: WriteOptions): Promise<boolean>;
|
|
313
|
+
read(path: string, options?: ReadOptions): Promise<object | null>;
|
|
314
|
+
readAll(path: string, options?: ReadOptions): Promise<object[]>;
|
|
315
|
+
update(path: string, updates: object): Promise<boolean>;
|
|
316
|
+
delete(path: string): Promise<boolean>;
|
|
317
|
+
deleteAll(path: string): Promise<{ success: boolean; count: number }>;
|
|
318
|
+
|
|
319
|
+
// Subscriptions
|
|
320
|
+
subscribe(path: string, callback: Function, options?: SubOptions): Promise<Subscription>;
|
|
321
|
+
|
|
322
|
+
// Migration
|
|
323
|
+
exportData(pathPrefix?: string): Promise<ExportRecord[]>;
|
|
324
|
+
importData(records: ExportRecord[], options?: ImportOptions): Promise<ImportResults>;
|
|
325
|
+
}
|
|
326
|
+
```
|