holosphere 2.0.0-alpha1 → 2.0.0-alpha4
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/dist/2019-D2OG2idw.js +6680 -0
- package/dist/2019-D2OG2idw.js.map +1 -0
- package/dist/2019-EION3wKo.cjs +8 -0
- package/dist/2019-EION3wKo.cjs.map +1 -0
- package/dist/_commonjsHelpers-C37NGDzP.cjs +2 -0
- package/dist/_commonjsHelpers-C37NGDzP.cjs.map +1 -0
- package/dist/_commonjsHelpers-CUmg6egw.js +7 -0
- package/dist/_commonjsHelpers-CUmg6egw.js.map +1 -0
- package/dist/browser-BSniCNqO.js +3058 -0
- package/dist/browser-BSniCNqO.js.map +1 -0
- package/dist/browser-Cq59Ij19.cjs +2 -0
- package/dist/browser-Cq59Ij19.cjs.map +1 -0
- package/dist/cjs/holosphere.cjs +2 -0
- package/dist/cjs/holosphere.cjs.map +1 -0
- package/dist/esm/holosphere.js +53 -0
- package/dist/esm/holosphere.js.map +1 -0
- package/dist/index-BB_vVJgv.cjs +5 -0
- package/dist/index-BB_vVJgv.cjs.map +1 -0
- package/dist/index-CBitK71M.cjs +12 -0
- package/dist/index-CBitK71M.cjs.map +1 -0
- package/dist/index-CV0eOogK.js +37423 -0
- package/dist/index-CV0eOogK.js.map +1 -0
- package/dist/index-Cz-PLCUR.js +15104 -0
- package/dist/index-Cz-PLCUR.js.map +1 -0
- package/dist/indexeddb-storage-CRsZyB2f.cjs +2 -0
- package/dist/indexeddb-storage-CRsZyB2f.cjs.map +1 -0
- package/dist/indexeddb-storage-DZaGlY_a.js +132 -0
- package/dist/indexeddb-storage-DZaGlY_a.js.map +1 -0
- package/dist/memory-storage-BkUi6sZG.js +51 -0
- package/dist/memory-storage-BkUi6sZG.js.map +1 -0
- package/dist/memory-storage-C0DuUsdY.cjs +2 -0
- package/dist/memory-storage-C0DuUsdY.cjs.map +1 -0
- package/dist/secp256k1-0kPdAVkK.cjs +12 -0
- package/dist/secp256k1-0kPdAVkK.cjs.map +1 -0
- package/dist/secp256k1-DN4FVXcv.js +1890 -0
- package/dist/secp256k1-DN4FVXcv.js.map +1 -0
- package/docs/CONTRACTS.md +797 -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/examples/demo.html +47 -0
- package/package.json +10 -5
- package/src/contracts/abis/Appreciative.json +1280 -0
- package/src/contracts/abis/AppreciativeFactory.json +101 -0
- package/src/contracts/abis/Bundle.json +1435 -0
- package/src/contracts/abis/BundleFactory.json +106 -0
- package/src/contracts/abis/Holon.json +881 -0
- package/src/contracts/abis/Holons.json +330 -0
- package/src/contracts/abis/Managed.json +1262 -0
- package/src/contracts/abis/ManagedFactory.json +149 -0
- package/src/contracts/abis/Membrane.json +261 -0
- package/src/contracts/abis/Splitter.json +1624 -0
- package/src/contracts/abis/SplitterFactory.json +220 -0
- package/src/contracts/abis/TestToken.json +321 -0
- package/src/contracts/abis/Zoned.json +1461 -0
- package/src/contracts/abis/ZonedFactory.json +154 -0
- package/src/contracts/chain-manager.js +375 -0
- package/src/contracts/deployer.js +443 -0
- package/src/contracts/event-listener.js +507 -0
- package/src/contracts/holon-contracts.js +344 -0
- package/src/contracts/index.js +83 -0
- package/src/contracts/networks.js +224 -0
- package/src/contracts/operations.js +670 -0
- package/src/contracts/queries.js +589 -0
- package/src/core/holosphere.js +453 -1
- package/src/crypto/nostr-utils.js +263 -0
- package/src/federation/handshake.js +455 -0
- package/src/federation/hologram.js +1 -1
- package/src/hierarchical/upcast.js +6 -5
- package/src/index.js +463 -1939
- package/src/lib/ai-methods.js +308 -0
- package/src/lib/contract-methods.js +293 -0
- package/src/lib/errors.js +23 -0
- package/src/lib/federation-methods.js +238 -0
- package/src/lib/index.js +26 -0
- package/src/spatial/h3-operations.js +2 -2
- package/src/storage/backends/gundb-backend.js +377 -46
- package/src/storage/global-tables.js +28 -1
- package/src/storage/gun-auth.js +303 -0
- package/src/storage/gun-federation.js +776 -0
- package/src/storage/gun-references.js +198 -0
- package/src/storage/gun-schema.js +291 -0
- package/src/storage/gun-wrapper.js +347 -31
- package/src/storage/indexeddb-storage.js +49 -11
- package/src/storage/memory-storage.js +5 -0
- package/src/storage/nostr-async.js +45 -23
- package/src/storage/nostr-client.js +11 -5
- package/src/storage/persistent-storage.js +6 -1
- package/src/storage/unified-storage.js +119 -0
- package/src/subscriptions/manager.js +1 -1
- package/types/index.d.ts +133 -0
- 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,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GunDB Authentication Handler
|
|
3
|
+
* Handles user authentication and private data storage using Gun's user system
|
|
4
|
+
*
|
|
5
|
+
* Private data is stored under: user.get('private').get(lens).get(key)
|
|
6
|
+
* Usernames are namespaced: ${appname}:${holonId}
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { gunPromise, gunPut } from './gun-async.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Authentication handler for GunDB backend
|
|
13
|
+
*/
|
|
14
|
+
export class GunAuth {
|
|
15
|
+
/**
|
|
16
|
+
* Create a new authentication handler
|
|
17
|
+
* @param {Object} gun - Gun instance
|
|
18
|
+
* @param {string} appname - Application namespace
|
|
19
|
+
*/
|
|
20
|
+
constructor(gun, appname) {
|
|
21
|
+
this.gun = gun;
|
|
22
|
+
this.appname = appname;
|
|
23
|
+
this.user = null;
|
|
24
|
+
this.authenticated = false;
|
|
25
|
+
this.currentHolonId = null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Generate a namespaced username for a holon
|
|
30
|
+
* @param {string} holonId - Holon ID
|
|
31
|
+
* @returns {string} Namespaced username
|
|
32
|
+
*/
|
|
33
|
+
userName(holonId) {
|
|
34
|
+
return `${this.appname}:${holonId}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Authenticate a user for a specific holon
|
|
39
|
+
* @param {string} holonId - Holon ID
|
|
40
|
+
* @param {string} password - Password
|
|
41
|
+
* @returns {Promise<Object>} Authenticated user object
|
|
42
|
+
*/
|
|
43
|
+
async authenticate(holonId, password) {
|
|
44
|
+
if (!holonId || !password) {
|
|
45
|
+
throw new Error('authenticate: holonId and password are required');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const username = this.userName(holonId);
|
|
49
|
+
this.user = this.gun.user();
|
|
50
|
+
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
this.user.auth(username, password, (ack) => {
|
|
53
|
+
if (ack.err) {
|
|
54
|
+
this.authenticated = false;
|
|
55
|
+
this.currentHolonId = null;
|
|
56
|
+
reject(new Error(ack.err));
|
|
57
|
+
} else {
|
|
58
|
+
this.authenticated = true;
|
|
59
|
+
this.currentHolonId = holonId;
|
|
60
|
+
resolve(this.user);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Create a new user for a holon
|
|
68
|
+
* @param {string} holonId - Holon ID
|
|
69
|
+
* @param {string} password - Password
|
|
70
|
+
* @returns {Promise<Object>} Created user object
|
|
71
|
+
*/
|
|
72
|
+
async createUser(holonId, password) {
|
|
73
|
+
if (!holonId || !password) {
|
|
74
|
+
throw new Error('createUser: holonId and password are required');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const username = this.userName(holonId);
|
|
78
|
+
this.user = this.gun.user();
|
|
79
|
+
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
81
|
+
this.user.create(username, password, (ack) => {
|
|
82
|
+
if (ack.err) {
|
|
83
|
+
reject(new Error(ack.err));
|
|
84
|
+
} else {
|
|
85
|
+
// Auto-login after creation
|
|
86
|
+
this.user.auth(username, password, (authAck) => {
|
|
87
|
+
if (authAck.err) {
|
|
88
|
+
reject(new Error(authAck.err));
|
|
89
|
+
} else {
|
|
90
|
+
this.authenticated = true;
|
|
91
|
+
this.currentHolonId = holonId;
|
|
92
|
+
resolve(this.user);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Logout current user
|
|
102
|
+
*/
|
|
103
|
+
logout() {
|
|
104
|
+
if (this.user) {
|
|
105
|
+
this.user.leave();
|
|
106
|
+
}
|
|
107
|
+
this.authenticated = false;
|
|
108
|
+
this.currentHolonId = null;
|
|
109
|
+
this.user = null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Check if currently authenticated
|
|
114
|
+
* @returns {boolean} True if authenticated
|
|
115
|
+
*/
|
|
116
|
+
isAuthenticated() {
|
|
117
|
+
return this.authenticated && this.user !== null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Get the private data path for a lens and key
|
|
122
|
+
* @param {string} lens - Lens name
|
|
123
|
+
* @param {string} key - Data key (optional)
|
|
124
|
+
* @returns {Object} Gun chain reference
|
|
125
|
+
*/
|
|
126
|
+
getPrivatePath(lens, key = null) {
|
|
127
|
+
if (!this.isAuthenticated()) {
|
|
128
|
+
throw new Error('Not authenticated');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const basePath = this.user.get('private').get(lens);
|
|
132
|
+
return key ? basePath.get(key) : basePath;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Write data to private storage
|
|
137
|
+
* @param {string} lens - Lens name
|
|
138
|
+
* @param {string} key - Data key
|
|
139
|
+
* @param {Object} data - Data to write
|
|
140
|
+
* @returns {Promise<boolean>} Success indicator
|
|
141
|
+
*/
|
|
142
|
+
async writePrivate(lens, key, data) {
|
|
143
|
+
if (!this.isAuthenticated()) {
|
|
144
|
+
throw new Error('Not authenticated');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (!data || !key) {
|
|
148
|
+
throw new Error('writePrivate: key and data are required');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
const serialized = JSON.stringify(data);
|
|
153
|
+
await gunPut(this.getPrivatePath(lens, key), serialized, 2000);
|
|
154
|
+
return true;
|
|
155
|
+
} catch (error) {
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Read data from private storage
|
|
162
|
+
* @param {string} lens - Lens name
|
|
163
|
+
* @param {string} key - Data key
|
|
164
|
+
* @returns {Promise<Object|null>} Data or null if not found
|
|
165
|
+
*/
|
|
166
|
+
async readPrivate(lens, key) {
|
|
167
|
+
if (!this.isAuthenticated()) {
|
|
168
|
+
throw new Error('Not authenticated');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
const rawData = await gunPromise(this.getPrivatePath(lens, key), 2000);
|
|
173
|
+
|
|
174
|
+
if (!rawData) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Deserialize - primary format is JSON string (like old holosphere)
|
|
179
|
+
if (typeof rawData === 'string') {
|
|
180
|
+
try {
|
|
181
|
+
return JSON.parse(rawData);
|
|
182
|
+
} catch (e) {
|
|
183
|
+
return rawData; // Return as-is if not valid JSON
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Legacy _json wrapper format
|
|
188
|
+
if (rawData._json && typeof rawData._json === 'string') {
|
|
189
|
+
try {
|
|
190
|
+
return JSON.parse(rawData._json);
|
|
191
|
+
} catch (e) {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Plain object format
|
|
197
|
+
if (typeof rawData === 'object') {
|
|
198
|
+
const cleaned = { ...rawData };
|
|
199
|
+
delete cleaned['_'];
|
|
200
|
+
return cleaned;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return null;
|
|
204
|
+
} catch (error) {
|
|
205
|
+
throw error;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Read all data from a private lens
|
|
211
|
+
* @param {string} lens - Lens name
|
|
212
|
+
* @param {number} timeout - Timeout in ms
|
|
213
|
+
* @returns {Promise<Object[]>} Array of data objects
|
|
214
|
+
*/
|
|
215
|
+
async readAllPrivate(lens, timeout = 2000) {
|
|
216
|
+
if (!this.isAuthenticated()) {
|
|
217
|
+
throw new Error('Not authenticated');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return new Promise((resolve) => {
|
|
221
|
+
const results = [];
|
|
222
|
+
const seen = new Set();
|
|
223
|
+
const ref = this.getPrivatePath(lens);
|
|
224
|
+
|
|
225
|
+
const timer = setTimeout(() => {
|
|
226
|
+
try {
|
|
227
|
+
ref.off();
|
|
228
|
+
} catch (e) {}
|
|
229
|
+
resolve(results);
|
|
230
|
+
}, timeout);
|
|
231
|
+
|
|
232
|
+
ref.map().once((data, key) => {
|
|
233
|
+
if (data && !key.startsWith('_') && !seen.has(key)) {
|
|
234
|
+
seen.add(key);
|
|
235
|
+
|
|
236
|
+
let parsed = null;
|
|
237
|
+
// Primary: JSON string format (like old holosphere)
|
|
238
|
+
if (typeof data === 'string') {
|
|
239
|
+
try {
|
|
240
|
+
parsed = JSON.parse(data);
|
|
241
|
+
} catch (e) {
|
|
242
|
+
parsed = data;
|
|
243
|
+
}
|
|
244
|
+
// Legacy: _json wrapper format
|
|
245
|
+
} else if (data._json && typeof data._json === 'string') {
|
|
246
|
+
try {
|
|
247
|
+
parsed = JSON.parse(data._json);
|
|
248
|
+
} catch (e) {}
|
|
249
|
+
// Plain object
|
|
250
|
+
} else if (typeof data === 'object') {
|
|
251
|
+
parsed = { ...data };
|
|
252
|
+
delete parsed['_'];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (parsed && !parsed._deleted) {
|
|
256
|
+
results.push(parsed);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Delete data from private storage
|
|
265
|
+
* @param {string} lens - Lens name
|
|
266
|
+
* @param {string} key - Data key
|
|
267
|
+
* @returns {Promise<boolean>} Success indicator
|
|
268
|
+
*/
|
|
269
|
+
async deletePrivate(lens, key) {
|
|
270
|
+
if (!this.isAuthenticated()) {
|
|
271
|
+
throw new Error('Not authenticated');
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
try {
|
|
275
|
+
// Get existing data to preserve ID
|
|
276
|
+
const existing = await this.readPrivate(lens, key);
|
|
277
|
+
|
|
278
|
+
// Create tombstone
|
|
279
|
+
const tombstone = {
|
|
280
|
+
id: existing?.id || key,
|
|
281
|
+
_deleted: true,
|
|
282
|
+
_deletedAt: Date.now()
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
await gunPut(this.getPrivatePath(lens, key), JSON.stringify(tombstone));
|
|
286
|
+
return true;
|
|
287
|
+
} catch (error) {
|
|
288
|
+
throw error;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Create an authentication handler instance
|
|
295
|
+
* @param {Object} gun - Gun instance
|
|
296
|
+
* @param {string} appname - Application namespace
|
|
297
|
+
* @returns {GunAuth} Auth handler instance
|
|
298
|
+
*/
|
|
299
|
+
export function createAuthHandler(gun, appname) {
|
|
300
|
+
return new GunAuth(gun, appname);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export default GunAuth;
|