holosphere 2.0.0-alpha7 → 2.0.0-alpha8
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/cjs/holosphere.cjs +1 -1
- package/dist/esm/holosphere.js +1 -1
- package/dist/{index-d6f4RJBM.js → index-4XHHKe6S.js} +356 -58
- package/dist/index-4XHHKe6S.js.map +1 -0
- package/dist/{index-jmTHEbR2.js → index-BjP1TXGz.js} +2 -2
- package/dist/{index-jmTHEbR2.js.map → index-BjP1TXGz.js.map} +1 -1
- package/dist/{index-C-IlLYlk.cjs → index-CKffQDmQ.cjs} +2 -2
- package/dist/{index-C-IlLYlk.cjs.map → index-CKffQDmQ.cjs.map} +1 -1
- package/dist/index-Dz5kOZMI.cjs +5 -0
- package/dist/index-Dz5kOZMI.cjs.map +1 -0
- package/dist/{indexeddb-storage-a8GipaDr.cjs → indexeddb-storage-DD7EFBVc.cjs} +2 -2
- package/dist/{indexeddb-storage-a8GipaDr.cjs.map → indexeddb-storage-DD7EFBVc.cjs.map} +1 -1
- package/dist/{indexeddb-storage-D8kOl0oK.js → indexeddb-storage-lExjjFlV.js} +2 -2
- package/dist/{indexeddb-storage-D8kOl0oK.js.map → indexeddb-storage-lExjjFlV.js.map} +1 -1
- package/dist/{memory-storage-DBQK622V.js → memory-storage-C68adso2.js} +2 -2
- package/dist/{memory-storage-DBQK622V.js.map → memory-storage-C68adso2.js.map} +1 -1
- package/dist/{memory-storage-gfRovk2O.cjs → memory-storage-DD_6yyXT.cjs} +2 -2
- package/dist/{memory-storage-gfRovk2O.cjs.map → memory-storage-DD_6yyXT.cjs.map} +1 -1
- package/dist/{secp256k1-BCAPF45D.cjs → secp256k1-DYELiqgx.cjs} +2 -2
- package/dist/{secp256k1-BCAPF45D.cjs.map → secp256k1-DYELiqgx.cjs.map} +1 -1
- package/dist/{secp256k1-DYm_CMqW.js → secp256k1-OM8siPyy.js} +2 -2
- package/dist/{secp256k1-DYm_CMqW.js.map → secp256k1-OM8siPyy.js.map} +1 -1
- package/examples/holosphere-widget.js +1242 -0
- package/examples/widget-demo.html +274 -0
- package/examples/widget.html +703 -0
- package/package.json +3 -1
- package/src/cdn-entry.js +22 -0
- package/src/contracts/queries.js +16 -1
- package/src/core/holosphere.js +2 -2
- package/src/crypto/nostr-utils.js +36 -2
- package/src/federation/handshake.js +16 -4
- package/src/index.js +16 -2
- package/src/storage/backends/gundb-backend.js +293 -9
- package/src/storage/gun-wrapper.js +64 -16
- package/src/storage/nostr-async.js +40 -25
- package/src/storage/unified-storage.js +31 -1
- package/vite.config.cdn.js +60 -0
- package/dist/index-Bvwyvd0T.cjs +0 -5
- package/dist/index-Bvwyvd0T.cjs.map +0 -1
- package/dist/index-d6f4RJBM.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getPublicKey as getPublicKey$2, finalizeEvent, SimplePool, nip19, nip04, verifyEvent as verifyEvent$1 } from "nostr-tools";
|
|
1
|
+
import { getPublicKey as getPublicKey$2, finalizeEvent, SimplePool, nip19, nip04, nip44, verifyEvent as verifyEvent$1 } from "nostr-tools";
|
|
2
2
|
import * as h3 from "h3-js";
|
|
3
3
|
import { latLngToCell, getResolution, cellToParent, cellToChildren, isValidCell } from "h3-js";
|
|
4
4
|
import Ajv from "ajv";
|
|
@@ -361,12 +361,12 @@ async function createPersistentStorage(namespace, options = {}) {
|
|
|
361
361
|
const isBrowser = typeof window !== "undefined" && typeof window.indexedDB !== "undefined";
|
|
362
362
|
typeof process !== "undefined" && process.versions && void 0;
|
|
363
363
|
if (isBrowser) {
|
|
364
|
-
const { IndexedDBStorage } = await import("./indexeddb-storage-
|
|
364
|
+
const { IndexedDBStorage } = await import("./indexeddb-storage-lExjjFlV.js");
|
|
365
365
|
const storage = new IndexedDBStorage();
|
|
366
366
|
await storage.init(namespace);
|
|
367
367
|
return storage;
|
|
368
368
|
} else {
|
|
369
|
-
const { MemoryStorage } = await import("./memory-storage-
|
|
369
|
+
const { MemoryStorage } = await import("./memory-storage-C68adso2.js");
|
|
370
370
|
const storage = new MemoryStorage();
|
|
371
371
|
await storage.init(namespace);
|
|
372
372
|
return storage;
|
|
@@ -1628,8 +1628,16 @@ function buildGlobalPath(appname, tableName, key = null) {
|
|
|
1628
1628
|
function encodePathComponent$1(component) {
|
|
1629
1629
|
return encodeURIComponent(component).replace(/%2F/g, "/");
|
|
1630
1630
|
}
|
|
1631
|
+
function getGunPath(gun, path) {
|
|
1632
|
+
const parts = path.split("/").filter((p) => p.length > 0);
|
|
1633
|
+
let ref = gun;
|
|
1634
|
+
for (const part of parts) {
|
|
1635
|
+
ref = ref.get(part);
|
|
1636
|
+
}
|
|
1637
|
+
return ref;
|
|
1638
|
+
}
|
|
1631
1639
|
function serializeForGun(data) {
|
|
1632
|
-
return
|
|
1640
|
+
return JSON.stringify(data);
|
|
1633
1641
|
}
|
|
1634
1642
|
function deserializeFromGun(data) {
|
|
1635
1643
|
if (!data) {
|
|
@@ -1681,15 +1689,29 @@ function deserializeFromGun(data) {
|
|
|
1681
1689
|
async function write$2(gun, path, data) {
|
|
1682
1690
|
try {
|
|
1683
1691
|
const serialized = serializeForGun(data);
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1692
|
+
const parts = path.split("/").filter((p) => p.length > 0);
|
|
1693
|
+
console.log("[gun-wrapper] write:", { path, parts, dataId: data?.id });
|
|
1694
|
+
const ref = getGunPath(gun, path);
|
|
1695
|
+
console.log("[gun-wrapper] write ref soul:", ref?._.get);
|
|
1696
|
+
const ack = await gunPut(ref, serialized, 5e3);
|
|
1697
|
+
console.log("[gun-wrapper] write ack:", { ok: ack.ok, timeout: ack.timeout });
|
|
1698
|
+
if (ack.timeout) {
|
|
1699
|
+
console.warn("[gun-wrapper] write timed out (data may not be persisted):", path);
|
|
1700
|
+
}
|
|
1701
|
+
console.log("[gun-wrapper] write complete:", path);
|
|
1702
|
+
return { ok: true, timeout: ack.timeout || false };
|
|
1687
1703
|
} catch (error) {
|
|
1704
|
+
console.error("[gun-wrapper] write error:", error);
|
|
1688
1705
|
throw error;
|
|
1689
1706
|
}
|
|
1690
1707
|
}
|
|
1691
1708
|
async function read$2(gun, path) {
|
|
1692
|
-
const
|
|
1709
|
+
const parts = path.split("/").filter((p) => p.length > 0);
|
|
1710
|
+
console.log("[gun-wrapper] read:", { path, parts });
|
|
1711
|
+
const ref = getGunPath(gun, path);
|
|
1712
|
+
console.log("[gun-wrapper] read ref soul:", ref?._.get);
|
|
1713
|
+
const rawData = await gunPromise(ref, 2e3);
|
|
1714
|
+
console.log("[gun-wrapper] read rawData:", rawData ? typeof rawData === "string" ? rawData.substring(0, 100) : "object" : "null");
|
|
1693
1715
|
if (!rawData) {
|
|
1694
1716
|
return null;
|
|
1695
1717
|
}
|
|
@@ -1700,16 +1722,20 @@ async function read$2(gun, path) {
|
|
|
1700
1722
|
return data;
|
|
1701
1723
|
}
|
|
1702
1724
|
async function readAll$2(gun, path, timeout = 5e3) {
|
|
1725
|
+
const parts = path.split("/").filter((p) => p.length > 0);
|
|
1726
|
+
console.log("[gun-wrapper] readAll:", { path, parts });
|
|
1703
1727
|
return new Promise((resolve) => {
|
|
1704
1728
|
const output2 = /* @__PURE__ */ new Map();
|
|
1705
1729
|
let settled = false;
|
|
1706
1730
|
let expectedCount = 0;
|
|
1707
1731
|
let receivedCount = 0;
|
|
1708
|
-
const ref = gun
|
|
1732
|
+
const ref = getGunPath(gun, path);
|
|
1733
|
+
console.log("[gun-wrapper] readAll ref soul:", ref?._.get);
|
|
1709
1734
|
const tryResolve = () => {
|
|
1710
1735
|
if (settled) return;
|
|
1711
1736
|
if (expectedCount > 0 && receivedCount >= expectedCount) {
|
|
1712
1737
|
settled = true;
|
|
1738
|
+
console.log("[gun-wrapper] readAll resolved with", output2.size, "items");
|
|
1713
1739
|
resolve(Array.from(output2.values()));
|
|
1714
1740
|
}
|
|
1715
1741
|
};
|
|
@@ -1718,14 +1744,20 @@ async function readAll$2(gun, path, timeout = 5e3) {
|
|
|
1718
1744
|
};
|
|
1719
1745
|
ref.once((parentData) => {
|
|
1720
1746
|
if (settled) return;
|
|
1747
|
+
console.log("[gun-wrapper] readAll parentData:", parentData);
|
|
1748
|
+
console.log("[gun-wrapper] readAll parentData keys:", parentData ? Object.keys(parentData).filter((k) => k !== "_") : "null");
|
|
1749
|
+
console.log("[gun-wrapper] readAll parentData type:", typeof parentData);
|
|
1721
1750
|
if (!parentData) {
|
|
1722
1751
|
settled = true;
|
|
1752
|
+
console.log("[gun-wrapper] readAll: no parent data, returning empty");
|
|
1723
1753
|
resolve([]);
|
|
1724
1754
|
return;
|
|
1725
1755
|
}
|
|
1726
1756
|
const keys = Object.keys(parentData).filter((k) => k !== "_");
|
|
1757
|
+
console.log("[gun-wrapper] readAll keys:", keys);
|
|
1727
1758
|
if (keys.length === 0) {
|
|
1728
1759
|
settled = true;
|
|
1760
|
+
console.log("[gun-wrapper] readAll: no keys, returning empty");
|
|
1729
1761
|
resolve([]);
|
|
1730
1762
|
return;
|
|
1731
1763
|
}
|
|
@@ -1767,7 +1799,7 @@ async function readAll$2(gun, path, timeout = 5e3) {
|
|
|
1767
1799
|
});
|
|
1768
1800
|
}
|
|
1769
1801
|
async function update$2(gun, path, updates) {
|
|
1770
|
-
const rawData = await gunPromise(gun
|
|
1802
|
+
const rawData = await gunPromise(getGunPath(gun, path));
|
|
1771
1803
|
if (!rawData) {
|
|
1772
1804
|
return false;
|
|
1773
1805
|
}
|
|
@@ -1778,7 +1810,8 @@ async function update$2(gun, path, updates) {
|
|
|
1778
1810
|
const merged = { ...existing, ...updates };
|
|
1779
1811
|
try {
|
|
1780
1812
|
const serialized = serializeForGun(merged);
|
|
1781
|
-
await gunPut(gun
|
|
1813
|
+
await gunPut(getGunPath(gun, path), serialized, 2e3);
|
|
1814
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
1782
1815
|
return true;
|
|
1783
1816
|
} catch (error) {
|
|
1784
1817
|
throw error;
|
|
@@ -1786,7 +1819,7 @@ async function update$2(gun, path, updates) {
|
|
|
1786
1819
|
}
|
|
1787
1820
|
async function deleteData$2(gun, path) {
|
|
1788
1821
|
try {
|
|
1789
|
-
const rawData = await gunPromise(gun
|
|
1822
|
+
const rawData = await gunPromise(getGunPath(gun, path));
|
|
1790
1823
|
if (!rawData) {
|
|
1791
1824
|
return true;
|
|
1792
1825
|
}
|
|
@@ -1796,7 +1829,8 @@ async function deleteData$2(gun, path) {
|
|
|
1796
1829
|
_deleted: true,
|
|
1797
1830
|
_deletedAt: Date.now()
|
|
1798
1831
|
};
|
|
1799
|
-
await gunPut(gun
|
|
1832
|
+
await gunPut(getGunPath(gun, path), serializeForGun(tombstone), 2e3);
|
|
1833
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
1800
1834
|
return true;
|
|
1801
1835
|
} catch (error) {
|
|
1802
1836
|
throw error;
|
|
@@ -1818,7 +1852,7 @@ function subscribe$2(gun, path, callback, options = {}) {
|
|
|
1818
1852
|
const pathParts = path.split("/");
|
|
1819
1853
|
const isPrefix = options.prefix !== void 0 ? options.prefix : pathParts.length <= 3;
|
|
1820
1854
|
if (isPrefix) {
|
|
1821
|
-
const ref = gun
|
|
1855
|
+
const ref = getGunPath(gun, path);
|
|
1822
1856
|
ref.map().on((data, key) => {
|
|
1823
1857
|
if (data && !key.startsWith("_")) {
|
|
1824
1858
|
const deserialized = deserializeFromGun(data);
|
|
@@ -1836,7 +1870,7 @@ function subscribe$2(gun, path, callback, options = {}) {
|
|
|
1836
1870
|
}
|
|
1837
1871
|
};
|
|
1838
1872
|
} else {
|
|
1839
|
-
const listener = gun
|
|
1873
|
+
const listener = getGunPath(gun, path).on((data, key) => {
|
|
1840
1874
|
if (data) {
|
|
1841
1875
|
const deserialized = deserializeFromGun(data);
|
|
1842
1876
|
if (deserialized && !deserialized._deleted) {
|
|
@@ -3193,24 +3227,44 @@ class GunDBBackend extends StorageBackend {
|
|
|
3193
3227
|
this.schemaValidator = null;
|
|
3194
3228
|
this.subscriptions = /* @__PURE__ */ new Map();
|
|
3195
3229
|
this.subscriptionCounter = 0;
|
|
3230
|
+
this.writeCache = /* @__PURE__ */ new Map();
|
|
3231
|
+
this.writeCacheTTL = 3e5;
|
|
3232
|
+
this.pendingWrites = /* @__PURE__ */ new Map();
|
|
3233
|
+
this.maxWriteRetries = 5;
|
|
3234
|
+
this.writeRetryInterval = 1e4;
|
|
3196
3235
|
}
|
|
3197
3236
|
async init() {
|
|
3198
3237
|
let Gun;
|
|
3199
3238
|
try {
|
|
3239
|
+
console.log("[gundb-backend] Importing Gun...");
|
|
3200
3240
|
const gunModule = await import("./browser-BSniCNqO.js").then((n2) => n2.b);
|
|
3201
3241
|
Gun = gunModule.default || gunModule;
|
|
3242
|
+
console.log("[gundb-backend] Gun imported:", typeof Gun);
|
|
3202
3243
|
} catch (error) {
|
|
3203
3244
|
throw new Error(
|
|
3204
3245
|
'GunDB backend requires the "gun" package. Install it with: npm install gun'
|
|
3205
3246
|
);
|
|
3206
3247
|
}
|
|
3248
|
+
const dataDir = this.config.dataDir || "radata";
|
|
3207
3249
|
const gunConfig = {
|
|
3208
3250
|
peers: this.config.peers || [],
|
|
3209
3251
|
radisk: this.config.radisk !== false,
|
|
3210
3252
|
localStorage: this.config.localStorage !== false,
|
|
3211
|
-
file:
|
|
3253
|
+
file: dataDir
|
|
3212
3254
|
};
|
|
3255
|
+
console.log("[gundb-backend] Gun config:", JSON.stringify(gunConfig));
|
|
3213
3256
|
this.gun = Gun(gunConfig);
|
|
3257
|
+
console.log("[gundb-backend] Gun instance created:", !!this.gun);
|
|
3258
|
+
try {
|
|
3259
|
+
const testKey = `_test_${Date.now()}`;
|
|
3260
|
+
this.gun.get(testKey).put({ test: true }, (ack) => {
|
|
3261
|
+
console.log("[gundb-backend] Gun test write ack:", ack);
|
|
3262
|
+
});
|
|
3263
|
+
console.log("[gundb-backend] Gun test write initiated");
|
|
3264
|
+
} catch (e) {
|
|
3265
|
+
console.error("[gundb-backend] Gun test write failed:", e.message);
|
|
3266
|
+
}
|
|
3267
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
3214
3268
|
try {
|
|
3215
3269
|
const SEA = Gun.SEA;
|
|
3216
3270
|
if (SEA) {
|
|
@@ -3236,6 +3290,88 @@ class GunDBBackend extends StorageBackend {
|
|
|
3236
3290
|
await this.schemaValidator.init();
|
|
3237
3291
|
}
|
|
3238
3292
|
// ============================================================================
|
|
3293
|
+
// WRITE CACHE (for immediate consistency)
|
|
3294
|
+
// ============================================================================
|
|
3295
|
+
/**
|
|
3296
|
+
* Add item to the local write cache for immediate consistency
|
|
3297
|
+
* @private
|
|
3298
|
+
*/
|
|
3299
|
+
_addToWriteCache(path, data) {
|
|
3300
|
+
if (!data || !data.id) return;
|
|
3301
|
+
const parentPath = path.substring(0, path.lastIndexOf("/"));
|
|
3302
|
+
if (!parentPath) return;
|
|
3303
|
+
if (!this.writeCache.has(parentPath)) {
|
|
3304
|
+
this.writeCache.set(parentPath, /* @__PURE__ */ new Map());
|
|
3305
|
+
}
|
|
3306
|
+
const pathCache = this.writeCache.get(parentPath);
|
|
3307
|
+
pathCache.set(data.id.toString(), {
|
|
3308
|
+
data,
|
|
3309
|
+
timestamp: Date.now()
|
|
3310
|
+
});
|
|
3311
|
+
}
|
|
3312
|
+
/**
|
|
3313
|
+
* Remove item from write cache (e.g., on delete)
|
|
3314
|
+
* @private
|
|
3315
|
+
*/
|
|
3316
|
+
_removeFromWriteCache(path, id2) {
|
|
3317
|
+
const parentPath = path.substring(0, path.lastIndexOf("/"));
|
|
3318
|
+
const pathCache = this.writeCache.get(parentPath);
|
|
3319
|
+
if (pathCache) {
|
|
3320
|
+
pathCache.delete(id2.toString());
|
|
3321
|
+
}
|
|
3322
|
+
}
|
|
3323
|
+
/**
|
|
3324
|
+
* Get cached writes for a path, filtering out expired entries
|
|
3325
|
+
* @private
|
|
3326
|
+
*/
|
|
3327
|
+
_getWriteCacheEntries(path) {
|
|
3328
|
+
const pathCache = this.writeCache.get(path);
|
|
3329
|
+
if (!pathCache) return [];
|
|
3330
|
+
const now = Date.now();
|
|
3331
|
+
const validEntries = [];
|
|
3332
|
+
for (const [id2, entry] of pathCache) {
|
|
3333
|
+
if (now - entry.timestamp < this.writeCacheTTL) {
|
|
3334
|
+
validEntries.push(entry.data);
|
|
3335
|
+
} else {
|
|
3336
|
+
pathCache.delete(id2);
|
|
3337
|
+
}
|
|
3338
|
+
}
|
|
3339
|
+
return validEntries;
|
|
3340
|
+
}
|
|
3341
|
+
/**
|
|
3342
|
+
* Merge cached writes with results from Gun
|
|
3343
|
+
* @private
|
|
3344
|
+
*/
|
|
3345
|
+
_mergeWithWriteCache(path, gunResults) {
|
|
3346
|
+
const cachedWrites = this._getWriteCacheEntries(path);
|
|
3347
|
+
if (cachedWrites.length === 0) return gunResults;
|
|
3348
|
+
const resultMap = /* @__PURE__ */ new Map();
|
|
3349
|
+
for (const item of gunResults) {
|
|
3350
|
+
if (item && item.id) {
|
|
3351
|
+
resultMap.set(item.id.toString(), item);
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
for (const item of cachedWrites) {
|
|
3355
|
+
if (item && item.id && !item._deleted) {
|
|
3356
|
+
resultMap.set(item.id.toString(), item);
|
|
3357
|
+
} else if (item && item.id && item._deleted) {
|
|
3358
|
+
resultMap.delete(item.id.toString());
|
|
3359
|
+
}
|
|
3360
|
+
}
|
|
3361
|
+
return Array.from(resultMap.values());
|
|
3362
|
+
}
|
|
3363
|
+
/**
|
|
3364
|
+
* Clear write cache for a specific path or all paths
|
|
3365
|
+
* @param {string} [path] - Optional path to clear, clears all if not provided
|
|
3366
|
+
*/
|
|
3367
|
+
clearWriteCache(path = null) {
|
|
3368
|
+
if (path) {
|
|
3369
|
+
this.writeCache.delete(path);
|
|
3370
|
+
} else {
|
|
3371
|
+
this.writeCache.clear();
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
// ============================================================================
|
|
3239
3375
|
// PATH BUILDING
|
|
3240
3376
|
// ============================================================================
|
|
3241
3377
|
buildPath(appName, holonId, lensName, key = null) {
|
|
@@ -3253,19 +3389,56 @@ class GunDBBackend extends StorageBackend {
|
|
|
3253
3389
|
if (pathParts.length >= 3) {
|
|
3254
3390
|
const lens = pathParts[2];
|
|
3255
3391
|
if (!this.isReference(data)) {
|
|
3256
|
-
const
|
|
3392
|
+
const result2 = await this.schemaValidator.validateData(
|
|
3257
3393
|
this.gun,
|
|
3258
3394
|
this.appName,
|
|
3259
3395
|
lens,
|
|
3260
3396
|
data
|
|
3261
3397
|
);
|
|
3262
|
-
if (!
|
|
3263
|
-
throw new Error(`Schema validation failed: ${JSON.stringify(
|
|
3398
|
+
if (!result2.valid) {
|
|
3399
|
+
throw new Error(`Schema validation failed: ${JSON.stringify(result2.errors)}`);
|
|
3264
3400
|
}
|
|
3265
3401
|
}
|
|
3266
3402
|
}
|
|
3267
3403
|
}
|
|
3268
|
-
|
|
3404
|
+
this._addToWriteCache(path, data);
|
|
3405
|
+
const result = await this._writeWithRetry(path, data);
|
|
3406
|
+
return result;
|
|
3407
|
+
}
|
|
3408
|
+
/**
|
|
3409
|
+
* Write to Gun with automatic retry on timeout
|
|
3410
|
+
* @private
|
|
3411
|
+
*/
|
|
3412
|
+
async _writeWithRetry(path, data, attempt = 0) {
|
|
3413
|
+
const result = await write$2(this.gun, path, data);
|
|
3414
|
+
if (result.timeout && attempt < this.maxWriteRetries) {
|
|
3415
|
+
this.pendingWrites.set(path, {
|
|
3416
|
+
data,
|
|
3417
|
+
retries: attempt + 1,
|
|
3418
|
+
lastAttempt: Date.now()
|
|
3419
|
+
});
|
|
3420
|
+
this._scheduleRetry(path);
|
|
3421
|
+
} else if (!result.timeout) {
|
|
3422
|
+
this.pendingWrites.delete(path);
|
|
3423
|
+
}
|
|
3424
|
+
return result;
|
|
3425
|
+
}
|
|
3426
|
+
/**
|
|
3427
|
+
* Schedule a background retry for a pending write
|
|
3428
|
+
* @private
|
|
3429
|
+
*/
|
|
3430
|
+
_scheduleRetry(path) {
|
|
3431
|
+
setTimeout(async () => {
|
|
3432
|
+
const pending = this.pendingWrites.get(path);
|
|
3433
|
+
if (!pending) return;
|
|
3434
|
+
if (pending.retries >= this.maxWriteRetries) {
|
|
3435
|
+
console.warn(`[gundb-backend] Max retries reached for: ${path}`);
|
|
3436
|
+
this.pendingWrites.delete(path);
|
|
3437
|
+
return;
|
|
3438
|
+
}
|
|
3439
|
+
console.log(`[gundb-backend] Retrying write (attempt ${pending.retries + 1}): ${path}`);
|
|
3440
|
+
await this._writeWithRetry(path, pending.data, pending.retries);
|
|
3441
|
+
}, this.writeRetryInterval);
|
|
3269
3442
|
}
|
|
3270
3443
|
async read(path, options = {}) {
|
|
3271
3444
|
const data = await read$2(this.gun, path);
|
|
@@ -3275,7 +3448,8 @@ class GunDBBackend extends StorageBackend {
|
|
|
3275
3448
|
return data;
|
|
3276
3449
|
}
|
|
3277
3450
|
async readAll(path, options = {}) {
|
|
3278
|
-
const
|
|
3451
|
+
const gunItems = await readAll$2(this.gun, path);
|
|
3452
|
+
const items = this._mergeWithWriteCache(path, gunItems);
|
|
3279
3453
|
if (options.resolveReferences) {
|
|
3280
3454
|
const resolved = [];
|
|
3281
3455
|
for (const item of items) {
|
|
@@ -3296,7 +3470,20 @@ class GunDBBackend extends StorageBackend {
|
|
|
3296
3470
|
return update$2(this.gun, path, updates);
|
|
3297
3471
|
}
|
|
3298
3472
|
async delete(path) {
|
|
3299
|
-
|
|
3473
|
+
const result = await deleteData$2(this.gun, path);
|
|
3474
|
+
const pathParts = path.split("/");
|
|
3475
|
+
const id2 = pathParts[pathParts.length - 1];
|
|
3476
|
+
if (id2) {
|
|
3477
|
+
const parentPath = path.substring(0, path.lastIndexOf("/"));
|
|
3478
|
+
if (!this.writeCache.has(parentPath)) {
|
|
3479
|
+
this.writeCache.set(parentPath, /* @__PURE__ */ new Map());
|
|
3480
|
+
}
|
|
3481
|
+
this.writeCache.get(parentPath).set(id2.toString(), {
|
|
3482
|
+
data: { id: id2, _deleted: true },
|
|
3483
|
+
timestamp: Date.now()
|
|
3484
|
+
});
|
|
3485
|
+
}
|
|
3486
|
+
return result;
|
|
3300
3487
|
}
|
|
3301
3488
|
async deleteAll(path) {
|
|
3302
3489
|
const items = await this.readAll(path);
|
|
@@ -3314,16 +3501,67 @@ class GunDBBackend extends StorageBackend {
|
|
|
3314
3501
|
// GLOBAL TABLE OPERATIONS
|
|
3315
3502
|
// ============================================================================
|
|
3316
3503
|
async writeGlobal(tableName, data) {
|
|
3317
|
-
|
|
3504
|
+
const path = this.buildGlobalPath(tableName, data.id);
|
|
3505
|
+
this._addToWriteCache(path, data);
|
|
3506
|
+
const result = await this._writeGlobalWithRetry(tableName, data);
|
|
3507
|
+
return result;
|
|
3508
|
+
}
|
|
3509
|
+
/**
|
|
3510
|
+
* Write to global table with automatic retry on timeout
|
|
3511
|
+
* @private
|
|
3512
|
+
*/
|
|
3513
|
+
async _writeGlobalWithRetry(tableName, data, attempt = 0) {
|
|
3514
|
+
const path = this.buildGlobalPath(tableName, data.id);
|
|
3515
|
+
const result = await writeGlobal$1(this.gun, this.appName, tableName, data);
|
|
3516
|
+
if (result.timeout && attempt < this.maxWriteRetries) {
|
|
3517
|
+
this.pendingWrites.set(path, {
|
|
3518
|
+
data: { tableName, data },
|
|
3519
|
+
isGlobal: true,
|
|
3520
|
+
retries: attempt + 1,
|
|
3521
|
+
lastAttempt: Date.now()
|
|
3522
|
+
});
|
|
3523
|
+
this._scheduleGlobalRetry(path, tableName);
|
|
3524
|
+
} else if (!result.timeout) {
|
|
3525
|
+
this.pendingWrites.delete(path);
|
|
3526
|
+
}
|
|
3527
|
+
return result;
|
|
3528
|
+
}
|
|
3529
|
+
/**
|
|
3530
|
+
* Schedule a background retry for a pending global write
|
|
3531
|
+
* @private
|
|
3532
|
+
*/
|
|
3533
|
+
_scheduleGlobalRetry(path, tableName) {
|
|
3534
|
+
setTimeout(async () => {
|
|
3535
|
+
const pending = this.pendingWrites.get(path);
|
|
3536
|
+
if (!pending || !pending.isGlobal) return;
|
|
3537
|
+
if (pending.retries >= this.maxWriteRetries) {
|
|
3538
|
+
console.warn(`[gundb-backend] Max retries reached for global: ${path}`);
|
|
3539
|
+
this.pendingWrites.delete(path);
|
|
3540
|
+
return;
|
|
3541
|
+
}
|
|
3542
|
+
console.log(`[gundb-backend] Retrying global write (attempt ${pending.retries + 1}): ${path}`);
|
|
3543
|
+
await this._writeGlobalWithRetry(tableName, pending.data.data, pending.retries);
|
|
3544
|
+
}, this.writeRetryInterval);
|
|
3318
3545
|
}
|
|
3319
3546
|
async readGlobal(tableName, key) {
|
|
3320
3547
|
return readGlobal$1(this.gun, this.appName, tableName, key);
|
|
3321
3548
|
}
|
|
3322
3549
|
async readAllGlobal(tableName, timeout = 5e3) {
|
|
3323
|
-
|
|
3550
|
+
const gunItems = await readAllGlobal(this.gun, this.appName, tableName, timeout);
|
|
3551
|
+
const path = this.buildGlobalPath(tableName);
|
|
3552
|
+
return this._mergeWithWriteCache(path, gunItems);
|
|
3324
3553
|
}
|
|
3325
3554
|
async deleteGlobal(tableName, key) {
|
|
3326
|
-
|
|
3555
|
+
const result = await deleteGlobal$1(this.gun, this.appName, tableName, key);
|
|
3556
|
+
const path = this.buildGlobalPath(tableName);
|
|
3557
|
+
if (!this.writeCache.has(path)) {
|
|
3558
|
+
this.writeCache.set(path, /* @__PURE__ */ new Map());
|
|
3559
|
+
}
|
|
3560
|
+
this.writeCache.get(path).set(key.toString(), {
|
|
3561
|
+
data: { id: key, _deleted: true },
|
|
3562
|
+
timestamp: Date.now()
|
|
3563
|
+
});
|
|
3564
|
+
return result;
|
|
3327
3565
|
}
|
|
3328
3566
|
async deleteAllGlobal(tableName) {
|
|
3329
3567
|
return deleteAllGlobal$1(this.gun, this.appName, tableName);
|
|
@@ -3594,6 +3832,7 @@ class GunDBBackend extends StorageBackend {
|
|
|
3594
3832
|
if (this.schemaValidator) {
|
|
3595
3833
|
this.schemaValidator.clearCache();
|
|
3596
3834
|
}
|
|
3835
|
+
this.writeCache.clear();
|
|
3597
3836
|
if (this.auth) {
|
|
3598
3837
|
this.auth.logout();
|
|
3599
3838
|
}
|
|
@@ -3629,7 +3868,7 @@ class GunDBBackend extends StorageBackend {
|
|
|
3629
3868
|
}
|
|
3630
3869
|
}
|
|
3631
3870
|
const name = "holosphere";
|
|
3632
|
-
const version$1 = "2.0.0-
|
|
3871
|
+
const version$1 = "2.0.0-alpha8";
|
|
3633
3872
|
const description = "Holonic geospatial communication infrastructure combining H3 hexagonal indexing with distributed P2P storage";
|
|
3634
3873
|
const type = "module";
|
|
3635
3874
|
const bin = {
|
|
@@ -3648,6 +3887,8 @@ const exports = {
|
|
|
3648
3887
|
const scripts = {
|
|
3649
3888
|
dev: "vite",
|
|
3650
3889
|
build: "vite build",
|
|
3890
|
+
"build:cdn": "vite build --config vite.config.cdn.js",
|
|
3891
|
+
"build:all": "npm run build && npm run build:cdn",
|
|
3651
3892
|
test: "vitest run",
|
|
3652
3893
|
"test:watch": "vitest",
|
|
3653
3894
|
"test:coverage": "vitest run --coverage",
|
|
@@ -3735,7 +3976,7 @@ let HoloSphere$1 = class HoloSphere {
|
|
|
3735
3976
|
* @param {string} config.backend - Storage backend: 'nostr' | 'gundb' | 'activitypub' (default: 'nostr')
|
|
3736
3977
|
* @param {string[]} config.relays - Nostr relay URLs (default from HOLOSPHERE_RELAYS env or ['wss://relay.holons.io', 'wss://relay.nostr.band'])
|
|
3737
3978
|
* @param {string} config.privateKey - Private key for signing (hex format, optional)
|
|
3738
|
-
* @param {string} config.logLevel - Log verbosity: ERROR|WARN|INFO|DEBUG (default: '
|
|
3979
|
+
* @param {string} config.logLevel - Log verbosity: ERROR|WARN|INFO|DEBUG (default: 'INFO')
|
|
3739
3980
|
* @param {boolean} config.hybridMode - Enable hybrid mode (local + relay queries) (default: true)
|
|
3740
3981
|
* @param {Object} config.gundb - GunDB-specific configuration
|
|
3741
3982
|
* @param {Object} config.activitypub - ActivityPub-specific configuration
|
|
@@ -3764,7 +4005,7 @@ let HoloSphere$1 = class HoloSphere {
|
|
|
3764
4005
|
backend: config.backend || "nostr",
|
|
3765
4006
|
relays: config.relays || getDefaultRelays(),
|
|
3766
4007
|
privateKey: config.privateKey || getEnv("HOLOSPHERE_PRIVATE_KEY"),
|
|
3767
|
-
logLevel: config.logLevel || getEnv("HOLOSPHERE_LOG_LEVEL") || "
|
|
4008
|
+
logLevel: config.logLevel || getEnv("HOLOSPHERE_LOG_LEVEL") || "INFO",
|
|
3768
4009
|
hybridMode: config.hybridMode !== false
|
|
3769
4010
|
// Enable by default
|
|
3770
4011
|
};
|
|
@@ -4396,20 +4637,23 @@ async function nostrGet(client, path, kind2 = 3e4, options = {}) {
|
|
|
4396
4637
|
if (!options.skipPersistent && client.persistentGet) {
|
|
4397
4638
|
const persistedEvent = await client.persistentGet(path);
|
|
4398
4639
|
if (persistedEvent && persistedEvent.content) {
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4640
|
+
if (!authors.includes(persistedEvent.pubkey)) ;
|
|
4641
|
+
else {
|
|
4642
|
+
try {
|
|
4643
|
+
const data = JSON.parse(persistedEvent.content);
|
|
4644
|
+
if (data._deleted) {
|
|
4645
|
+
return null;
|
|
4646
|
+
}
|
|
4647
|
+
if (options.includeAuthor) {
|
|
4648
|
+
data._author = persistedEvent.pubkey;
|
|
4649
|
+
}
|
|
4650
|
+
if (client.refreshPathInBackground) {
|
|
4651
|
+
client.refreshPathInBackground(path, kind2, { authors, timeout });
|
|
4652
|
+
}
|
|
4653
|
+
return data;
|
|
4654
|
+
} catch (error) {
|
|
4655
|
+
console.warn("[nostrGet] Failed to parse persisted event:", error);
|
|
4409
4656
|
}
|
|
4410
|
-
return data;
|
|
4411
|
-
} catch (error) {
|
|
4412
|
-
console.warn("[nostrGet] Failed to parse persisted event:", error);
|
|
4413
4657
|
}
|
|
4414
4658
|
}
|
|
4415
4659
|
}
|
|
@@ -4443,10 +4687,11 @@ async function _executeNostrGet(client, path, kind2, authors, timeout, options)
|
|
|
4443
4687
|
// Increase limit to get events from all authors
|
|
4444
4688
|
};
|
|
4445
4689
|
const events = await client.query(filter, { timeout });
|
|
4446
|
-
|
|
4690
|
+
const authoredEvents = events.filter((event2) => authors.includes(event2.pubkey));
|
|
4691
|
+
if (authoredEvents.length === 0) {
|
|
4447
4692
|
return null;
|
|
4448
4693
|
}
|
|
4449
|
-
const event =
|
|
4694
|
+
const event = authoredEvents.sort((a, b2) => b2.created_at - a.created_at)[0];
|
|
4450
4695
|
try {
|
|
4451
4696
|
const data = JSON.parse(event.content);
|
|
4452
4697
|
if (data._deleted) {
|
|
@@ -4470,6 +4715,7 @@ async function nostrGetAll(client, pathPrefix, kind2 = 3e4, options = {}) {
|
|
|
4470
4715
|
const byPath = /* @__PURE__ */ new Map();
|
|
4471
4716
|
for (const event of persistedEvents) {
|
|
4472
4717
|
if (!event || !event.tags) continue;
|
|
4718
|
+
if (!authors.includes(event.pubkey)) continue;
|
|
4473
4719
|
const dTag = event.tags.find((t) => t[0] === "d");
|
|
4474
4720
|
if (!dTag || !dTag[1] || !dTag[1].startsWith(pathPrefix)) continue;
|
|
4475
4721
|
const path = dTag[1];
|
|
@@ -4524,7 +4770,9 @@ async function _executeNostrGetAll(client, pathPrefix, kind2, authors, timeout,
|
|
|
4524
4770
|
const events = await client.query(filter, { timeout });
|
|
4525
4771
|
const matching = events.filter((event) => {
|
|
4526
4772
|
const dTag = event.tags.find((t) => t[0] === "d");
|
|
4527
|
-
|
|
4773
|
+
const pathMatches = dTag && dTag[1] && dTag[1].startsWith(pathPrefix);
|
|
4774
|
+
const authorAllowed = authors.includes(event.pubkey);
|
|
4775
|
+
return pathMatches && authorAllowed;
|
|
4528
4776
|
});
|
|
4529
4777
|
const byPath = /* @__PURE__ */ new Map();
|
|
4530
4778
|
for (const event of matching) {
|
|
@@ -4560,7 +4808,9 @@ async function nostrGetAllHybrid(client, pathPrefix, kind2 = 3e4, options = {})
|
|
|
4560
4808
|
const events = await queryMethod.call(client, filter, { timeout });
|
|
4561
4809
|
const matching = events.filter((event) => {
|
|
4562
4810
|
const dTag = event.tags.find((t) => t[0] === "d");
|
|
4563
|
-
|
|
4811
|
+
const pathMatches = dTag && dTag[1] && dTag[1].startsWith(pathPrefix);
|
|
4812
|
+
const authorAllowed = authors.includes(event.pubkey);
|
|
4813
|
+
return pathMatches && authorAllowed;
|
|
4564
4814
|
});
|
|
4565
4815
|
const byPath = /* @__PURE__ */ new Map();
|
|
4566
4816
|
for (const event of matching) {
|
|
@@ -4986,30 +5236,45 @@ function buildPath(appName, holonId, lensName, key = null) {
|
|
|
4986
5236
|
return buildPath$1(appName, holonId, lensName, key);
|
|
4987
5237
|
}
|
|
4988
5238
|
async function write(client, path, data) {
|
|
5239
|
+
if (client.write && client.gun) {
|
|
5240
|
+
return client.write(path, data);
|
|
5241
|
+
}
|
|
4989
5242
|
if (client.gun) {
|
|
4990
5243
|
return write$2(client.gun, path, data);
|
|
4991
5244
|
}
|
|
4992
5245
|
return write$1(client, path, data);
|
|
4993
5246
|
}
|
|
4994
5247
|
async function read(client, path, options = {}) {
|
|
5248
|
+
if (client.read && client.gun) {
|
|
5249
|
+
return client.read(path, options);
|
|
5250
|
+
}
|
|
4995
5251
|
if (client.gun) {
|
|
4996
5252
|
return read$2(client.gun, path);
|
|
4997
5253
|
}
|
|
4998
5254
|
return read$1(client, path, options);
|
|
4999
5255
|
}
|
|
5000
5256
|
async function readAll(client, path, options = {}) {
|
|
5257
|
+
if (client.readAll && client.gun) {
|
|
5258
|
+
return client.readAll(path, options);
|
|
5259
|
+
}
|
|
5001
5260
|
if (client.gun) {
|
|
5002
5261
|
return readAll$2(client.gun, path);
|
|
5003
5262
|
}
|
|
5004
5263
|
return readAll$1(client, path, options);
|
|
5005
5264
|
}
|
|
5006
5265
|
async function update(client, path, updates) {
|
|
5266
|
+
if (client.update && client.gun) {
|
|
5267
|
+
return client.update(path, updates);
|
|
5268
|
+
}
|
|
5007
5269
|
if (client.gun) {
|
|
5008
5270
|
return update$2(client.gun, path, updates);
|
|
5009
5271
|
}
|
|
5010
5272
|
return update$1(client, path, updates);
|
|
5011
5273
|
}
|
|
5012
5274
|
async function deleteData(client, path) {
|
|
5275
|
+
if (client.delete && client.gun) {
|
|
5276
|
+
return client.delete(path);
|
|
5277
|
+
}
|
|
5013
5278
|
if (client.gun) {
|
|
5014
5279
|
return deleteData$2(client.gun, path);
|
|
5015
5280
|
}
|
|
@@ -5022,6 +5287,9 @@ async function deleteAll(client, path) {
|
|
|
5022
5287
|
return deleteAll$1(client, path);
|
|
5023
5288
|
}
|
|
5024
5289
|
function subscribe(client, path, callback, options = {}) {
|
|
5290
|
+
if (client.subscribe && client.gun) {
|
|
5291
|
+
return client.subscribe(path, callback, options);
|
|
5292
|
+
}
|
|
5025
5293
|
if (client.gun) {
|
|
5026
5294
|
return subscribe$2(client.gun, path, callback, options);
|
|
5027
5295
|
}
|
|
@@ -5526,7 +5794,7 @@ const sha256 = sha256$1;
|
|
|
5526
5794
|
let secp256k1 = null;
|
|
5527
5795
|
async function loadCrypto() {
|
|
5528
5796
|
if (!secp256k1) {
|
|
5529
|
-
const module2 = await import("./secp256k1-
|
|
5797
|
+
const module2 = await import("./secp256k1-OM8siPyy.js");
|
|
5530
5798
|
secp256k1 = module2.secp256k1;
|
|
5531
5799
|
}
|
|
5532
5800
|
return secp256k1;
|
|
@@ -6530,6 +6798,16 @@ async function encryptNIP04(privateKey, recipientPubKey, content) {
|
|
|
6530
6798
|
async function decryptNIP04(privateKey, senderPubKey, encryptedContent) {
|
|
6531
6799
|
return await nip04.decrypt(privateKey, senderPubKey, encryptedContent);
|
|
6532
6800
|
}
|
|
6801
|
+
function encryptNIP44(privateKey, recipientPubKey, content) {
|
|
6802
|
+
const privKeyBytes = hexToBytes(privateKey);
|
|
6803
|
+
const conversationKey = nip44.v2.utils.getConversationKey(privKeyBytes, recipientPubKey);
|
|
6804
|
+
return nip44.v2.encrypt(content, conversationKey);
|
|
6805
|
+
}
|
|
6806
|
+
function decryptNIP44(privateKey, senderPubKey, encryptedContent) {
|
|
6807
|
+
const privKeyBytes = hexToBytes(privateKey);
|
|
6808
|
+
const conversationKey = nip44.v2.utils.getConversationKey(privKeyBytes, senderPubKey);
|
|
6809
|
+
return nip44.v2.decrypt(encryptedContent, conversationKey);
|
|
6810
|
+
}
|
|
6533
6811
|
function createSignedEvent(kind2, content, tags, privateKey) {
|
|
6534
6812
|
const event = {
|
|
6535
6813
|
kind: kind2,
|
|
@@ -6583,7 +6861,9 @@ const nostrUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
6583
6861
|
createDMEvent,
|
|
6584
6862
|
createSignedEvent,
|
|
6585
6863
|
decryptNIP04,
|
|
6864
|
+
decryptNIP44,
|
|
6586
6865
|
encryptNIP04,
|
|
6866
|
+
encryptNIP44,
|
|
6587
6867
|
generateNonce,
|
|
6588
6868
|
getPublicKey,
|
|
6589
6869
|
hexToBytes,
|
|
@@ -6645,7 +6925,7 @@ function createFederationResponse({
|
|
|
6645
6925
|
async function sendFederationRequest$1(client, privateKey, recipientPubKey, request) {
|
|
6646
6926
|
try {
|
|
6647
6927
|
const content = JSON.stringify(request);
|
|
6648
|
-
const encrypted =
|
|
6928
|
+
const encrypted = encryptNIP44(privateKey, recipientPubKey, content);
|
|
6649
6929
|
const event = createDMEvent(recipientPubKey, encrypted, privateKey);
|
|
6650
6930
|
if (client?.publish) {
|
|
6651
6931
|
await client.publish(event);
|
|
@@ -6663,7 +6943,7 @@ async function sendFederationRequest$1(client, privateKey, recipientPubKey, requ
|
|
|
6663
6943
|
async function sendFederationResponse(client, privateKey, recipientPubKey, response) {
|
|
6664
6944
|
try {
|
|
6665
6945
|
const content = JSON.stringify(response);
|
|
6666
|
-
const encrypted =
|
|
6946
|
+
const encrypted = encryptNIP44(privateKey, recipientPubKey, content);
|
|
6667
6947
|
const event = createDMEvent(recipientPubKey, encrypted, privateKey);
|
|
6668
6948
|
if (client?.publish) {
|
|
6669
6949
|
await client.publish(event);
|
|
@@ -6690,7 +6970,12 @@ function subscribeToFederationDMs(client, privateKey, publicKey, handlers) {
|
|
|
6690
6970
|
const pTag = event.tags?.find((t) => t[0] === "p");
|
|
6691
6971
|
if (!pTag || pTag[1] !== publicKey) return;
|
|
6692
6972
|
try {
|
|
6693
|
-
|
|
6973
|
+
let decrypted;
|
|
6974
|
+
try {
|
|
6975
|
+
decrypted = decryptNIP44(privateKey, event.pubkey, event.content);
|
|
6976
|
+
} catch (nip44Error) {
|
|
6977
|
+
decrypted = await decryptNIP04(privateKey, event.pubkey, event.content);
|
|
6978
|
+
}
|
|
6694
6979
|
const payload = JSON.parse(decrypted);
|
|
6695
6980
|
if (payload.type === "federation_request" && payload.version === "1.0") {
|
|
6696
6981
|
console.log("[Handshake] Received federation request from:", event.pubkey.substring(0, 8) + "...");
|
|
@@ -7010,7 +7295,7 @@ async function createSubscription(client, path, callback, options = {}) {
|
|
|
7010
7295
|
lastInvoke = now;
|
|
7011
7296
|
callback(resolvedData, key);
|
|
7012
7297
|
};
|
|
7013
|
-
const subscription = await subscribe(client, path, wrappedCallback, {});
|
|
7298
|
+
const subscription = await subscribe(client, path, wrappedCallback, { realtimeOnly });
|
|
7014
7299
|
return {
|
|
7015
7300
|
path,
|
|
7016
7301
|
unsubscribe: () => {
|
|
@@ -17160,7 +17445,7 @@ class ChainManager {
|
|
|
17160
17445
|
*/
|
|
17161
17446
|
async _loadEthers() {
|
|
17162
17447
|
if (!this.ethers) {
|
|
17163
|
-
const ethersModule = await import("./index-
|
|
17448
|
+
const ethersModule = await import("./index-BjP1TXGz.js");
|
|
17164
17449
|
this.ethers = ethersModule;
|
|
17165
17450
|
}
|
|
17166
17451
|
return this.ethers;
|
|
@@ -25929,7 +26214,7 @@ class ContractDeployer {
|
|
|
25929
26214
|
*/
|
|
25930
26215
|
async _loadEthers() {
|
|
25931
26216
|
if (!this.ethers) {
|
|
25932
|
-
this.ethers = await import("./index-
|
|
26217
|
+
this.ethers = await import("./index-BjP1TXGz.js");
|
|
25933
26218
|
}
|
|
25934
26219
|
return this.ethers;
|
|
25935
26220
|
}
|
|
@@ -26291,7 +26576,7 @@ class ContractOperations {
|
|
|
26291
26576
|
*/
|
|
26292
26577
|
async _loadEthers() {
|
|
26293
26578
|
if (!this.ethers) {
|
|
26294
|
-
this.ethers = await import("./index-
|
|
26579
|
+
this.ethers = await import("./index-BjP1TXGz.js");
|
|
26295
26580
|
}
|
|
26296
26581
|
return this.ethers;
|
|
26297
26582
|
}
|
|
@@ -35542,8 +35827,7 @@ const ContractABIs = {
|
|
|
35542
35827
|
Zoned: ZonedABI,
|
|
35543
35828
|
Appreciative: AppreciativeABI,
|
|
35544
35829
|
Bundle: BundleABI,
|
|
35545
|
-
Holons: HolonsABI
|
|
35546
|
-
TestToken: TestTokenABI
|
|
35830
|
+
Holons: HolonsABI
|
|
35547
35831
|
};
|
|
35548
35832
|
function formatEthNumber(wei) {
|
|
35549
35833
|
return Number(formatEther(wei));
|
|
@@ -37040,6 +37324,7 @@ class HoloSphereBase extends HoloSphere$1 {
|
|
|
37040
37324
|
data.id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
37041
37325
|
}
|
|
37042
37326
|
const path = buildPath(this.config.appName, holonId, lensName, data.id);
|
|
37327
|
+
this._log("DEBUG", "write", { holonId, lensName, dataId: data.id, path });
|
|
37043
37328
|
const existingData = await read(this.client, path);
|
|
37044
37329
|
if (existingData && existingData.hologram === true && existingData.target) {
|
|
37045
37330
|
const hologramStructureFields = ["hologram", "soul", "target", "id", "_meta"];
|
|
@@ -37135,8 +37420,15 @@ class HoloSphereBase extends HoloSphere$1 {
|
|
|
37135
37420
|
data.target.lensName,
|
|
37136
37421
|
data.target.dataId
|
|
37137
37422
|
);
|
|
37423
|
+
this._log("DEBUG", "resolving hologram", {
|
|
37424
|
+
hologramId: data.id,
|
|
37425
|
+
sourcePath,
|
|
37426
|
+
targetHolon: data.target.holonId,
|
|
37427
|
+
targetLens: data.target.lensName,
|
|
37428
|
+
targetDataId: data.target.dataId
|
|
37429
|
+
});
|
|
37138
37430
|
if (visited.has(sourcePath)) {
|
|
37139
|
-
|
|
37431
|
+
this._log("WARN", "Circular hologram reference detected", { sourcePath });
|
|
37140
37432
|
return null;
|
|
37141
37433
|
}
|
|
37142
37434
|
visited.add(sourcePath);
|
|
@@ -37146,6 +37438,7 @@ class HoloSphereBase extends HoloSphere$1 {
|
|
|
37146
37438
|
resolveOptions.includeAuthor = true;
|
|
37147
37439
|
}
|
|
37148
37440
|
const sourceData = await read(this.client, sourcePath, resolveOptions);
|
|
37441
|
+
this._log("DEBUG", "hologram source fetched", { found: !!sourceData, sourcePath });
|
|
37149
37442
|
if (sourceData) {
|
|
37150
37443
|
let resolvedSource = sourceData;
|
|
37151
37444
|
if (sourceData.hologram === true && sourceData.target) {
|
|
@@ -37203,13 +37496,18 @@ class HoloSphereBase extends HoloSphere$1 {
|
|
|
37203
37496
|
let result;
|
|
37204
37497
|
if (dataId) {
|
|
37205
37498
|
const path = buildPath(this.config.appName, holonId, lensName, dataId);
|
|
37499
|
+
this._log("DEBUG", "read", { holonId, lensName, dataId, path });
|
|
37206
37500
|
result = await read(this.client, path);
|
|
37501
|
+
this._log("DEBUG", "read result", { found: !!result, isHologram: result?.hologram === true });
|
|
37207
37502
|
} else {
|
|
37208
37503
|
const path = buildPath(this.config.appName, holonId, lensName);
|
|
37504
|
+
this._log("DEBUG", "readAll", { holonId, lensName, path });
|
|
37209
37505
|
result = await readAll(this.client, path);
|
|
37506
|
+
this._log("DEBUG", "readAll result", { count: Array.isArray(result) ? result.length : 0 });
|
|
37210
37507
|
}
|
|
37211
37508
|
const { resolveHolograms = true } = options;
|
|
37212
|
-
if (resolveHolograms) {
|
|
37509
|
+
if (resolveHolograms && result) {
|
|
37510
|
+
this._log("DEBUG", "resolving holograms", { itemCount: Array.isArray(result) ? result.length : 1 });
|
|
37213
37511
|
result = await this._resolveHolograms(result);
|
|
37214
37512
|
}
|
|
37215
37513
|
const endTime = Date.now();
|
|
@@ -37972,4 +38270,4 @@ export {
|
|
|
37972
38270
|
exists as y,
|
|
37973
38271
|
bytes as z
|
|
37974
38272
|
};
|
|
37975
|
-
//# sourceMappingURL=index-
|
|
38273
|
+
//# sourceMappingURL=index-4XHHKe6S.js.map
|