holosphere 2.0.0-alpha21 → 2.0.0-alpha23

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.
Files changed (69) hide show
  1. package/README.md +1 -2
  2. package/dist/cjs/holosphere.cjs +1 -1
  3. package/dist/esm/holosphere.js +61 -58
  4. package/dist/{index-B6-8KAQm.js → index-BEkCLOwI.js} +2 -2
  5. package/dist/{index-B6-8KAQm.js.map → index-BEkCLOwI.js.map} +1 -1
  6. package/dist/{index-D2WstuZJ.js → index-BEvX6DxG.js} +2 -2
  7. package/dist/{index-D2WstuZJ.js.map → index-BEvX6DxG.js.map} +1 -1
  8. package/dist/{index--QsHG_gD.cjs → index-BGTOiJ2Y.cjs} +2 -2
  9. package/dist/{index--QsHG_gD.cjs.map → index-BGTOiJ2Y.cjs.map} +1 -1
  10. package/dist/{index-COpLk9gL.cjs → index-BH1woZXL.cjs} +2 -2
  11. package/dist/{index-COpLk9gL.cjs.map → index-BH1woZXL.cjs.map} +1 -1
  12. package/dist/{index-BHptWysv.js → index-Cvxov2jv.js} +2970 -7753
  13. package/dist/index-Cvxov2jv.js.map +1 -0
  14. package/dist/index-vTKI_BAX.cjs +29 -0
  15. package/dist/index-vTKI_BAX.cjs.map +1 -0
  16. package/dist/{indexeddb-storage-wKG4mICM.cjs → indexeddb-storage-BmnCNnSg.cjs} +2 -2
  17. package/dist/{indexeddb-storage-wKG4mICM.cjs.map → indexeddb-storage-BmnCNnSg.cjs.map} +1 -1
  18. package/dist/{indexeddb-storage-kQ53UHEE.js → indexeddb-storage-MIFisaPy.js} +2 -2
  19. package/dist/{indexeddb-storage-kQ53UHEE.js.map → indexeddb-storage-MIFisaPy.js.map} +1 -1
  20. package/dist/{memory-storage-CGC8xM2G.cjs → memory-storage-BJjK3F4r.cjs} +2 -2
  21. package/dist/{memory-storage-CGC8xM2G.cjs.map → memory-storage-BJjK3F4r.cjs.map} +1 -1
  22. package/dist/{memory-storage-DnXCSbBl.js → memory-storage-DhHXdKQ-.js} +2 -2
  23. package/dist/{memory-storage-DnXCSbBl.js.map → memory-storage-DhHXdKQ-.js.map} +1 -1
  24. package/examples/demo.html +2 -29
  25. package/package.json +3 -8
  26. package/src/content/social-protocols.js +3 -59
  27. package/src/core/holosphere.js +16 -554
  28. package/src/crypto/nostr-utils.js +98 -1
  29. package/src/crypto/secp256k1.js +4 -393
  30. package/src/federation/discovery.js +7 -75
  31. package/src/federation/handshake.js +69 -202
  32. package/src/federation/hologram.js +222 -298
  33. package/src/federation/index.js +2 -9
  34. package/src/federation/registry.js +67 -1257
  35. package/src/federation/request-card.js +21 -35
  36. package/src/hierarchical/upcast.js +4 -9
  37. package/src/index.js +145 -296
  38. package/src/lib/federation-methods.js +370 -909
  39. package/src/storage/global-tables.js +1 -1
  40. package/src/storage/nostr-wrapper.js +9 -5
  41. package/src/subscriptions/manager.js +1 -1
  42. package/types/index.d.ts +145 -37
  43. package/bin/holosphere-activitypub.js +0 -158
  44. package/dist/2019-BzVkRcax.js +0 -6680
  45. package/dist/2019-BzVkRcax.js.map +0 -1
  46. package/dist/2019-C1hPR_Os.cjs +0 -8
  47. package/dist/2019-C1hPR_Os.cjs.map +0 -1
  48. package/dist/browser-BcmACE3G.js +0 -3058
  49. package/dist/browser-BcmACE3G.js.map +0 -1
  50. package/dist/browser-DaqYUTcG.cjs +0 -2
  51. package/dist/browser-DaqYUTcG.cjs.map +0 -1
  52. package/dist/index-BHptWysv.js.map +0 -1
  53. package/dist/index-CDlhzxT2.cjs +0 -29
  54. package/dist/index-CDlhzxT2.cjs.map +0 -1
  55. package/src/federation/capabilities.js +0 -46
  56. package/src/storage/backend-factory.js +0 -130
  57. package/src/storage/backend-interface.js +0 -161
  58. package/src/storage/backends/activitypub/server.js +0 -675
  59. package/src/storage/backends/activitypub-backend.js +0 -295
  60. package/src/storage/backends/gundb-backend.js +0 -875
  61. package/src/storage/backends/nostr-backend.js +0 -251
  62. package/src/storage/gun-async.js +0 -341
  63. package/src/storage/gun-auth.js +0 -373
  64. package/src/storage/gun-federation.js +0 -785
  65. package/src/storage/gun-references.js +0 -209
  66. package/src/storage/gun-schema.js +0 -306
  67. package/src/storage/gun-wrapper.js +0 -642
  68. package/src/storage/migration.js +0 -351
  69. package/src/storage/unified-storage.js +0 -161
@@ -1,295 +0,0 @@
1
- /**
2
- * @fileoverview ActivityPub storage backend client adapter.
3
- * Provides HTTP-based connectivity to an ActivityPub server for federated data storage
4
- * and real-time subscriptions via Server-Sent Events.
5
- * @module storage/backends/activitypub-backend
6
- */
7
-
8
- import { StorageBackend } from '../backend-interface.js';
9
-
10
- /**
11
- * ActivityPub storage backend implementation.
12
- * Client adapter for connecting to an ActivityPub server via HTTP API
13
- * with SSE-based real-time subscriptions.
14
- *
15
- * @class ActivityPubBackend
16
- * @extends StorageBackend
17
- * @example
18
- * const backend = await BackendFactory.create('activitypub', {
19
- * serverUrl: 'https://ap.example.com',
20
- * appName: 'myapp',
21
- * apiKey: 'secret-key'
22
- * });
23
- */
24
- export class ActivityPubBackend extends StorageBackend {
25
- /**
26
- * Create a new ActivityPub backend instance.
27
- * @param {Object} config - Backend configuration
28
- * @param {string} config.serverUrl - ActivityPub server URL
29
- * @param {string} [config.appName='holosphere'] - Application/actor name
30
- * @param {string} [config.apiKey] - Optional API key for authentication
31
- */
32
- constructor(config) {
33
- super(config);
34
- this.serverUrl = config.serverUrl;
35
- this.actorName = config.appName || 'holosphere';
36
- this.apiKey = config.apiKey;
37
- this.actorId = null;
38
- }
39
-
40
- async init() {
41
- if (!this.serverUrl) {
42
- throw new Error('ActivityPub backend requires serverUrl in config');
43
- }
44
-
45
- // Ensure server URL doesn't have trailing slash
46
- this.serverUrl = this.serverUrl.replace(/\/$/, '');
47
-
48
- // Try to fetch or create actor
49
- try {
50
- const response = await fetch(`${this.serverUrl}/actor/${this.actorName}`, {
51
- headers: { 'Accept': 'application/activity+json' },
52
- });
53
-
54
- if (response.ok) {
55
- const actor = await response.json();
56
- this.actorId = actor.id;
57
- this.publicKey = actor.publicKey?.id || actor.id;
58
- } else {
59
- // Try to create actor
60
- await this._createActor();
61
- }
62
- } catch (error) {
63
- // Server might not be running yet, try to create actor
64
- await this._createActor();
65
- }
66
- }
67
-
68
- async _createActor() {
69
- try {
70
- const response = await this._fetch(`${this.serverUrl}/api/actors`, {
71
- method: 'POST',
72
- headers: { 'Content-Type': 'application/json' },
73
- body: JSON.stringify({
74
- name: this.actorName,
75
- apiKey: this.apiKey,
76
- }),
77
- });
78
-
79
- if (response.ok) {
80
- const result = await response.json();
81
- this.actorId = result.id;
82
- this.publicKey = result.publicKey || result.id;
83
- } else {
84
- throw new Error(`Failed to create actor: ${response.status}`);
85
- }
86
- } catch (error) {
87
- // If server is not available, set placeholder values
88
- this.actorId = `${this.serverUrl}/actor/${this.actorName}`;
89
- this.publicKey = this.actorId;
90
- }
91
- }
92
-
93
- buildPath(appName, holonId, lensName, key = null) {
94
- // Use same path format as other backends
95
- const encodedHolon = encodeURIComponent(holonId);
96
- const encodedLens = encodeURIComponent(lensName);
97
-
98
- if (key) {
99
- const encodedKey = encodeURIComponent(key);
100
- return `${appName}/${encodedHolon}/${encodedLens}/${encodedKey}`;
101
- }
102
- return `${appName}/${encodedHolon}/${encodedLens}`;
103
- }
104
-
105
- async write(path, data, options = {}) {
106
- const response = await this._fetch(`${this.serverUrl}/api/data`, {
107
- method: 'POST',
108
- headers: { 'Content-Type': 'application/json' },
109
- body: JSON.stringify({
110
- path,
111
- data,
112
- actorName: this.actorName,
113
- }),
114
- });
115
-
116
- return response.ok;
117
- }
118
-
119
- async read(path, options = {}) {
120
- const response = await this._fetch(`${this.serverUrl}/api/data/${path}`);
121
-
122
- if (!response.ok) {
123
- if (response.status === 404) return null;
124
- throw new Error(`Read failed: ${response.status}`);
125
- }
126
-
127
- const data = await response.json();
128
- return data._deleted ? null : data;
129
- }
130
-
131
- async readAll(path, options = {}) {
132
- const response = await this._fetch(`${this.serverUrl}/api/data/${path}`);
133
-
134
- if (!response.ok) {
135
- if (response.status === 404) return [];
136
- throw new Error(`ReadAll failed: ${response.status}`);
137
- }
138
-
139
- const data = await response.json();
140
- return Array.isArray(data) ? data.filter(item => !item._deleted) : [data];
141
- }
142
-
143
- async update(path, updates) {
144
- // Read existing, merge, write back
145
- const existing = await this.read(path);
146
- if (!existing) return false;
147
-
148
- const merged = { ...existing, ...updates };
149
- return this.write(path, merged);
150
- }
151
-
152
- async delete(path) {
153
- const response = await this._fetch(
154
- `${this.serverUrl}/api/data/${path}?actor=${this.actorName}`,
155
- { method: 'DELETE' }
156
- );
157
-
158
- return response.ok;
159
- }
160
-
161
- async deleteAll(path) {
162
- const items = await this.readAll(path);
163
- let count = 0;
164
-
165
- for (const item of items) {
166
- if (item && item.id) {
167
- await this.delete(`${path}/${item.id}`);
168
- count++;
169
- }
170
- }
171
-
172
- return { success: true, count };
173
- }
174
-
175
- async subscribe(path, callback, options = {}) {
176
- // Use Server-Sent Events for real-time updates
177
- const url = `${this.serverUrl}/subscribe?path=${encodeURIComponent(path)}`;
178
-
179
- // Use EventSource if available (browser) or polyfill
180
- let eventSource;
181
-
182
- if (typeof EventSource !== 'undefined') {
183
- eventSource = new EventSource(url);
184
- } else {
185
- // In Node.js, we need to use a different approach
186
- // For now, return a polling-based subscription
187
- return this._pollSubscribe(path, callback, options);
188
- }
189
-
190
- eventSource.addEventListener('update', (event) => {
191
- try {
192
- const { path: eventPath, data } = JSON.parse(event.data);
193
- const key = eventPath.split('/').pop();
194
- callback(data, key);
195
- } catch (error) {
196
- console.error('ActivityPub subscription error:', error);
197
- }
198
- });
199
-
200
- eventSource.onerror = (error) => {
201
- console.error('ActivityPub SSE error:', error);
202
- };
203
-
204
- return {
205
- unsubscribe: () => eventSource.close(),
206
- };
207
- }
208
-
209
- async _pollSubscribe(path, callback, options = {}) {
210
- // Fallback polling for Node.js environments
211
- const interval = options.pollInterval || 5000;
212
- let lastTimestamp = Date.now();
213
- let running = true;
214
-
215
- const poll = async () => {
216
- while (running) {
217
- try {
218
- const items = await this.readAll(path);
219
- for (const item of items) {
220
- if (item._meta?.timestamp > lastTimestamp) {
221
- const key = item.id || item._meta?.path?.split('/').pop();
222
- callback(item, key);
223
- lastTimestamp = item._meta.timestamp;
224
- }
225
- }
226
- } catch (error) {
227
- console.error('Polling error:', error);
228
- }
229
-
230
- await new Promise(resolve => setTimeout(resolve, interval));
231
- }
232
- };
233
-
234
- // Start polling
235
- poll();
236
-
237
- return {
238
- unsubscribe: () => { running = false; },
239
- };
240
- }
241
-
242
- async exportData(pathPrefix = '') {
243
- const items = await this.readAll(pathPrefix || this.actorName);
244
-
245
- return items.map(item => ({
246
- path: item._meta?.path || `${pathPrefix}/${item.id}`,
247
- data: item,
248
- timestamp: item._meta?.timestamp || Date.now(),
249
- }));
250
- }
251
-
252
- async importData(records, options = {}) {
253
- const results = { success: 0, failed: 0, errors: [] };
254
-
255
- for (const record of records) {
256
- try {
257
- await this.write(record.path, record.data);
258
- results.success++;
259
- } catch (error) {
260
- results.failed++;
261
- results.errors.push({ path: record.path, error: error.message });
262
- }
263
- }
264
-
265
- return results;
266
- }
267
-
268
- async _fetch(url, options = {}) {
269
- const headers = options.headers || {};
270
-
271
- // Add authorization if we have an API key
272
- if (this.apiKey) {
273
- headers['Authorization'] = `Bearer ${this.apiKey}`;
274
- }
275
-
276
- return fetch(url, { ...options, headers });
277
- }
278
-
279
- close() {
280
- // Nothing to close for HTTP client
281
- }
282
-
283
- getStatus() {
284
- return {
285
- type: 'activitypub',
286
- serverUrl: this.serverUrl,
287
- actorId: this.actorId,
288
- actorName: this.actorName,
289
- publicKey: this.publicKey,
290
- connected: true,
291
- };
292
- }
293
- }
294
-
295
- export default ActivityPubBackend;