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,373 +0,0 @@
1
- /**
2
- * @fileoverview GunDB Authentication Handler.
3
- *
4
- * Handles user authentication and private data storage using Gun's user system.
5
- * Private data is stored under: user.get('private').get(lens).get(key)
6
- * Usernames are namespaced: ${appname}:${holonId}
7
- *
8
- * @module storage/gun-auth
9
- */
10
-
11
- import { gunPromise, gunPut } from './gun-async.js';
12
-
13
- /**
14
- * Authentication handler for GunDB backend.
15
- *
16
- * Manages user creation, authentication, and private data access.
17
- *
18
- * @class GunAuth
19
- * @example
20
- * const auth = new GunAuth(gun, 'myapp');
21
- * await auth.createUser('holon123', 'password');
22
- * await auth.authenticate('holon123', 'password');
23
- */
24
- export class GunAuth {
25
- /**
26
- * Create a new authentication handler.
27
- *
28
- * @param {Object} gun - Gun instance
29
- * @param {string} appname - Application namespace
30
- */
31
- constructor(gun, appname) {
32
- this.gun = gun;
33
- this.appname = appname;
34
- this.user = null;
35
- this.authenticated = false;
36
- this.currentHolonId = null;
37
- }
38
-
39
- /**
40
- * Generate a namespaced username for a holon
41
- * @param {string} holonId - Holon ID
42
- * @returns {string} Namespaced username
43
- */
44
- userName(holonId) {
45
- return `${this.appname}:${holonId}`;
46
- }
47
-
48
- /**
49
- * Authenticate a user for a specific holon
50
- * @param {string} holonId - Holon ID
51
- * @param {string} password - Password
52
- * @returns {Promise<Object>} Authenticated user object
53
- */
54
- async authenticate(holonId, password) {
55
- if (!holonId || !password) {
56
- throw new Error('authenticate: holonId and password are required');
57
- }
58
-
59
- const username = this.userName(holonId);
60
- this.user = this.gun.user();
61
-
62
- return new Promise((resolve, reject) => {
63
- this.user.auth(username, password, (ack) => {
64
- if (ack.err) {
65
- this.authenticated = false;
66
- this.currentHolonId = null;
67
- reject(new Error(ack.err));
68
- } else {
69
- this.authenticated = true;
70
- this.currentHolonId = holonId;
71
- resolve(this.user);
72
- }
73
- });
74
- });
75
- }
76
-
77
- /**
78
- * Create a new user for a holon
79
- * @param {string} holonId - Holon ID
80
- * @param {string} password - Password
81
- * @returns {Promise<Object>} Created user object
82
- */
83
- async createUser(holonId, password) {
84
- if (!holonId || !password) {
85
- throw new Error('createUser: holonId and password are required');
86
- }
87
-
88
- const username = this.userName(holonId);
89
- this.user = this.gun.user();
90
-
91
- return new Promise((resolve, reject) => {
92
- this.user.create(username, password, (ack) => {
93
- if (ack.err) {
94
- reject(new Error(ack.err));
95
- } else {
96
- // Auto-login after creation
97
- this.user.auth(username, password, (authAck) => {
98
- if (authAck.err) {
99
- reject(new Error(authAck.err));
100
- } else {
101
- this.authenticated = true;
102
- this.currentHolonId = holonId;
103
- resolve(this.user);
104
- }
105
- });
106
- }
107
- });
108
- });
109
- }
110
-
111
- /**
112
- * Logout current user
113
- */
114
- logout() {
115
- if (this.user) {
116
- this.user.leave();
117
- }
118
- this.authenticated = false;
119
- this.currentHolonId = null;
120
- this.user = null;
121
- }
122
-
123
- /**
124
- * Check if currently authenticated
125
- * @returns {boolean} True if authenticated
126
- */
127
- isAuthenticated() {
128
- return this.authenticated && this.user !== null;
129
- }
130
-
131
- /**
132
- * Get the private data path for a lens and key
133
- * @param {string} lens - Lens name
134
- * @param {string} key - Data key (optional)
135
- * @returns {Object} Gun chain reference
136
- */
137
- getPrivatePath(lens, key = null) {
138
- if (!this.isAuthenticated()) {
139
- throw new Error('Not authenticated');
140
- }
141
-
142
- const basePath = this.user.get('private').get(lens);
143
- return key ? basePath.get(key) : basePath;
144
- }
145
-
146
- /**
147
- * Write data to private storage
148
- * @param {string} lens - Lens name
149
- * @param {string} key - Data key
150
- * @param {Object} data - Data to write
151
- * @returns {Promise<boolean>} Success indicator
152
- */
153
- async writePrivate(lens, key, data) {
154
- if (!this.isAuthenticated()) {
155
- throw new Error('Not authenticated');
156
- }
157
-
158
- if (!data || !key) {
159
- throw new Error('writePrivate: key and data are required');
160
- }
161
-
162
- try {
163
- const serialized = JSON.stringify(data);
164
- await gunPut(this.getPrivatePath(lens, key), serialized, 2000);
165
- return true;
166
- } catch (error) {
167
- throw error;
168
- }
169
- }
170
-
171
- /**
172
- * Read data from private storage
173
- * @param {string} lens - Lens name
174
- * @param {string} key - Data key
175
- * @returns {Promise<Object|null>} Data or null if not found
176
- */
177
- async readPrivate(lens, key) {
178
- if (!this.isAuthenticated()) {
179
- throw new Error('Not authenticated');
180
- }
181
-
182
- try {
183
- const rawData = await gunPromise(this.getPrivatePath(lens, key), 2000);
184
-
185
- if (!rawData) {
186
- return null;
187
- }
188
-
189
- // Deserialize - primary format is JSON string (like old holosphere)
190
- if (typeof rawData === 'string') {
191
- try {
192
- return JSON.parse(rawData);
193
- } catch (e) {
194
- return rawData; // Return as-is if not valid JSON
195
- }
196
- }
197
-
198
- // Legacy _json wrapper format
199
- if (rawData._json && typeof rawData._json === 'string') {
200
- try {
201
- return JSON.parse(rawData._json);
202
- } catch (e) {
203
- return null;
204
- }
205
- }
206
-
207
- // Plain object format
208
- if (typeof rawData === 'object') {
209
- const cleaned = { ...rawData };
210
- delete cleaned['_'];
211
- return cleaned;
212
- }
213
-
214
- return null;
215
- } catch (error) {
216
- throw error;
217
- }
218
- }
219
-
220
- /**
221
- * Read all data from a private lens
222
- * First gets count of items, then collects until count is reached
223
- * @param {string} lens - Lens name
224
- * @param {number} timeout - Timeout in ms (fallback)
225
- * @returns {Promise<Object[]>} Array of data objects
226
- */
227
- async readAllPrivate(lens, timeout = 5000) {
228
- if (!this.isAuthenticated()) {
229
- throw new Error('Not authenticated');
230
- }
231
-
232
- return new Promise((resolve) => {
233
- const results = [];
234
- const seen = new Set();
235
- const ref = this.getPrivatePath(lens);
236
- let settled = false;
237
- let expectedCount = 0;
238
- let receivedCount = 0;
239
-
240
- const tryResolve = () => {
241
- if (settled) return;
242
- if (expectedCount > 0 && receivedCount >= expectedCount) {
243
- settled = true;
244
- resolve(results);
245
- }
246
- };
247
-
248
- const parseItem = (data) => {
249
- if (!data) return null;
250
- let parsed = null;
251
- // Primary: JSON string format (like old holosphere)
252
- if (typeof data === 'string') {
253
- try {
254
- parsed = JSON.parse(data);
255
- } catch (e) {
256
- parsed = data;
257
- }
258
- // Legacy: _json wrapper format
259
- } else if (data._json && typeof data._json === 'string') {
260
- try {
261
- parsed = JSON.parse(data._json);
262
- } catch (e) {}
263
- // Plain object
264
- } else if (typeof data === 'object') {
265
- parsed = { ...data };
266
- delete parsed['_'];
267
- }
268
- return parsed;
269
- };
270
-
271
- // Step 1: Get parent to count expected items
272
- ref.once((parentData) => {
273
- if (settled) return;
274
-
275
- if (!parentData) {
276
- settled = true;
277
- resolve([]);
278
- return;
279
- }
280
-
281
- const keys = Object.keys(parentData).filter(k => k !== '_');
282
- if (keys.length === 0) {
283
- settled = true;
284
- resolve([]);
285
- return;
286
- }
287
-
288
- // Pre-parse inline items (not Gun references)
289
- for (const key of keys) {
290
- const rawItem = parentData[key];
291
- if (!rawItem) continue;
292
-
293
- // Skip Gun references - will be fetched via map().once()
294
- if (typeof rawItem === 'object' && rawItem['#']) continue;
295
-
296
- const parsed = parseItem(rawItem);
297
- if (parsed && !parsed._deleted && !seen.has(key)) {
298
- seen.add(key);
299
- results.push(parsed);
300
- }
301
- }
302
-
303
- // Expected count is ALL keys (map().once() fires for all)
304
- expectedCount = keys.length;
305
-
306
- // Step 2: Collect items via map().once(), counting as we go
307
- ref.map().once((data, key) => {
308
- if (settled || !data || key.startsWith('_')) return;
309
-
310
- // Count every item, but only add if not already seen
311
- if (!seen.has(key)) {
312
- seen.add(key);
313
- const parsed = parseItem(data);
314
- if (parsed && !parsed._deleted) {
315
- results.push(parsed);
316
- }
317
- }
318
- receivedCount++;
319
- tryResolve();
320
- });
321
- });
322
-
323
- // Fallback timeout
324
- setTimeout(() => {
325
- if (!settled) {
326
- settled = true;
327
- resolve(results);
328
- }
329
- }, timeout);
330
- });
331
- }
332
-
333
- /**
334
- * Delete data from private storage
335
- * @param {string} lens - Lens name
336
- * @param {string} key - Data key
337
- * @returns {Promise<boolean>} Success indicator
338
- */
339
- async deletePrivate(lens, key) {
340
- if (!this.isAuthenticated()) {
341
- throw new Error('Not authenticated');
342
- }
343
-
344
- try {
345
- // Get existing data to preserve ID
346
- const existing = await this.readPrivate(lens, key);
347
-
348
- // Create tombstone
349
- const tombstone = {
350
- id: existing?.id || key,
351
- _deleted: true,
352
- _deletedAt: Date.now()
353
- };
354
-
355
- await gunPut(this.getPrivatePath(lens, key), JSON.stringify(tombstone));
356
- return true;
357
- } catch (error) {
358
- throw error;
359
- }
360
- }
361
- }
362
-
363
- /**
364
- * Create an authentication handler instance
365
- * @param {Object} gun - Gun instance
366
- * @param {string} appname - Application namespace
367
- * @returns {GunAuth} Auth handler instance
368
- */
369
- export function createAuthHandler(gun, appname) {
370
- return new GunAuth(gun, appname);
371
- }
372
-
373
- export default GunAuth;