@unicitylabs/sphere-sdk 0.5.3 → 0.5.5

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 (50) hide show
  1. package/README.md +2 -0
  2. package/dist/connect/index.cjs +145 -23
  3. package/dist/connect/index.cjs.map +1 -1
  4. package/dist/connect/index.d.cts +15 -2
  5. package/dist/connect/index.d.ts +15 -2
  6. package/dist/connect/index.js +145 -23
  7. package/dist/connect/index.js.map +1 -1
  8. package/dist/core/index.cjs +670 -473
  9. package/dist/core/index.cjs.map +1 -1
  10. package/dist/core/index.d.cts +123 -2
  11. package/dist/core/index.d.ts +123 -2
  12. package/dist/core/index.js +667 -473
  13. package/dist/core/index.js.map +1 -1
  14. package/dist/impl/browser/connect/index.cjs +119 -1
  15. package/dist/impl/browser/connect/index.cjs.map +1 -1
  16. package/dist/impl/browser/connect/index.d.cts +53 -1
  17. package/dist/impl/browser/connect/index.d.ts +53 -1
  18. package/dist/impl/browser/connect/index.js +119 -1
  19. package/dist/impl/browser/connect/index.js.map +1 -1
  20. package/dist/impl/browser/index.cjs +306 -193
  21. package/dist/impl/browser/index.cjs.map +1 -1
  22. package/dist/impl/browser/index.js +306 -193
  23. package/dist/impl/browser/index.js.map +1 -1
  24. package/dist/impl/browser/ipfs.cjs +134 -19
  25. package/dist/impl/browser/ipfs.cjs.map +1 -1
  26. package/dist/impl/browser/ipfs.js +134 -19
  27. package/dist/impl/browser/ipfs.js.map +1 -1
  28. package/dist/impl/nodejs/connect/index.cjs +101 -6
  29. package/dist/impl/nodejs/connect/index.cjs.map +1 -1
  30. package/dist/impl/nodejs/connect/index.d.cts +2 -0
  31. package/dist/impl/nodejs/connect/index.d.ts +2 -0
  32. package/dist/impl/nodejs/connect/index.js +101 -6
  33. package/dist/impl/nodejs/connect/index.js.map +1 -1
  34. package/dist/impl/nodejs/index.cjs +267 -152
  35. package/dist/impl/nodejs/index.cjs.map +1 -1
  36. package/dist/impl/nodejs/index.d.cts +2 -1
  37. package/dist/impl/nodejs/index.d.ts +2 -1
  38. package/dist/impl/nodejs/index.js +267 -152
  39. package/dist/impl/nodejs/index.js.map +1 -1
  40. package/dist/index.cjs +682 -493
  41. package/dist/index.cjs.map +1 -1
  42. package/dist/index.d.cts +124 -8
  43. package/dist/index.d.ts +124 -8
  44. package/dist/index.js +680 -493
  45. package/dist/index.js.map +1 -1
  46. package/dist/l1/index.cjs +139 -32
  47. package/dist/l1/index.cjs.map +1 -1
  48. package/dist/l1/index.js +139 -32
  49. package/dist/l1/index.js.map +1 -1
  50. package/package.json +1 -16
@@ -538,6 +538,20 @@ var sha256 = /* @__PURE__ */ createHasher(
538
538
  var bip39 = __toESM(require("bip39"), 1);
539
539
  var import_crypto_js = __toESM(require("crypto-js"), 1);
540
540
  var import_elliptic = __toESM(require("elliptic"), 1);
541
+
542
+ // core/errors.ts
543
+ var SphereError = class extends Error {
544
+ code;
545
+ cause;
546
+ constructor(message, code, cause) {
547
+ super(message);
548
+ this.name = "SphereError";
549
+ this.code = code;
550
+ this.cause = cause;
551
+ }
552
+ };
553
+
554
+ // core/crypto.ts
541
555
  var ec = new import_elliptic.default.ec("secp256k1");
542
556
  var CURVE_ORDER = BigInt(
543
557
  "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"
@@ -771,6 +785,98 @@ var IpfsCache = class {
771
785
  }
772
786
  };
773
787
 
788
+ // core/logger.ts
789
+ var LOGGER_KEY = "__sphere_sdk_logger__";
790
+ function getState() {
791
+ const g = globalThis;
792
+ if (!g[LOGGER_KEY]) {
793
+ g[LOGGER_KEY] = { debug: false, tags: {}, handler: null };
794
+ }
795
+ return g[LOGGER_KEY];
796
+ }
797
+ function isEnabled(tag) {
798
+ const state = getState();
799
+ if (tag in state.tags) return state.tags[tag];
800
+ return state.debug;
801
+ }
802
+ var logger = {
803
+ /**
804
+ * Configure the logger. Can be called multiple times (last write wins).
805
+ * Typically called by createBrowserProviders(), createNodeProviders(), or Sphere.init().
806
+ */
807
+ configure(config) {
808
+ const state = getState();
809
+ if (config.debug !== void 0) state.debug = config.debug;
810
+ if (config.handler !== void 0) state.handler = config.handler;
811
+ },
812
+ /**
813
+ * Enable/disable debug logging for a specific tag.
814
+ * Per-tag setting overrides the global debug flag.
815
+ *
816
+ * @example
817
+ * ```ts
818
+ * logger.setTagDebug('Nostr', true); // enable only Nostr logs
819
+ * logger.setTagDebug('Nostr', false); // disable Nostr logs even if global debug=true
820
+ * ```
821
+ */
822
+ setTagDebug(tag, enabled) {
823
+ getState().tags[tag] = enabled;
824
+ },
825
+ /**
826
+ * Clear per-tag override, falling back to global debug flag.
827
+ */
828
+ clearTagDebug(tag) {
829
+ delete getState().tags[tag];
830
+ },
831
+ /** Returns true if debug mode is enabled for the given tag (or globally). */
832
+ isDebugEnabled(tag) {
833
+ if (tag) return isEnabled(tag);
834
+ return getState().debug;
835
+ },
836
+ /**
837
+ * Debug-level log. Only shown when debug is enabled (globally or for this tag).
838
+ * Use for detailed operational information.
839
+ */
840
+ debug(tag, message, ...args) {
841
+ if (!isEnabled(tag)) return;
842
+ const state = getState();
843
+ if (state.handler) {
844
+ state.handler("debug", tag, message, ...args);
845
+ } else {
846
+ console.log(`[${tag}]`, message, ...args);
847
+ }
848
+ },
849
+ /**
850
+ * Warning-level log. ALWAYS shown regardless of debug flag.
851
+ * Use for important but non-critical issues (timeouts, retries, degraded state).
852
+ */
853
+ warn(tag, message, ...args) {
854
+ const state = getState();
855
+ if (state.handler) {
856
+ state.handler("warn", tag, message, ...args);
857
+ } else {
858
+ console.warn(`[${tag}]`, message, ...args);
859
+ }
860
+ },
861
+ /**
862
+ * Error-level log. ALWAYS shown regardless of debug flag.
863
+ * Use for critical failures that should never be silenced.
864
+ */
865
+ error(tag, message, ...args) {
866
+ const state = getState();
867
+ if (state.handler) {
868
+ state.handler("error", tag, message, ...args);
869
+ } else {
870
+ console.error(`[${tag}]`, message, ...args);
871
+ }
872
+ },
873
+ /** Reset all logger state (debug flag, tags, handler). Primarily for tests. */
874
+ reset() {
875
+ const g = globalThis;
876
+ delete g[LOGGER_KEY];
877
+ }
878
+ };
879
+
774
880
  // impl/shared/ipfs/ipfs-http-client.ts
775
881
  var DEFAULT_CONNECTIVITY_TIMEOUT_MS = 5e3;
776
882
  var DEFAULT_FETCH_TIMEOUT_MS = 15e3;
@@ -927,7 +1033,10 @@ var IpfsHttpClient = class {
927
1033
  { headers: { Accept: "application/octet-stream" } }
928
1034
  );
929
1035
  if (!response.ok) {
930
- const body = await response.text().catch(() => "");
1036
+ const body = await response.text().catch((err) => {
1037
+ logger.debug("IPFS-HTTP", "Failed to read error response body", err);
1038
+ return "";
1039
+ });
931
1040
  throw new IpfsError(
932
1041
  `Fetch failed: HTTP ${response.status}`,
933
1042
  classifyHttpStatus(response.status, body),
@@ -973,7 +1082,10 @@ var IpfsHttpClient = class {
973
1082
  { method: "POST" }
974
1083
  );
975
1084
  if (!response.ok) {
976
- const body = await response.text().catch(() => "");
1085
+ const body = await response.text().catch((err) => {
1086
+ logger.debug("IPFS-HTTP", "Failed to read error response body", err);
1087
+ return "";
1088
+ });
977
1089
  const category = classifyHttpStatus(response.status, body);
978
1090
  if (category === "NOT_FOUND") return null;
979
1091
  throw new IpfsError(`Routing API: HTTP ${response.status}`, category, gateway);
@@ -1019,7 +1131,8 @@ var IpfsHttpClient = class {
1019
1131
  }
1020
1132
  }
1021
1133
  return { cid: "", content };
1022
- } catch {
1134
+ } catch (err) {
1135
+ logger.debug("IPFS-HTTP", "IPNS gateway resolution failed", err);
1023
1136
  return null;
1024
1137
  }
1025
1138
  }
@@ -1084,7 +1197,10 @@ var IpfsHttpClient = class {
1084
1197
  { method: "POST", body: formData }
1085
1198
  );
1086
1199
  if (!response.ok) {
1087
- const errorText = await response.text().catch(() => "");
1200
+ const errorText = await response.text().catch((err) => {
1201
+ logger.debug("IPFS-HTTP", "Failed to read error response body", err);
1202
+ return "";
1203
+ });
1088
1204
  throw new IpfsError(
1089
1205
  `IPNS publish: HTTP ${response.status}: ${errorText.slice(0, 100)}`,
1090
1206
  classifyHttpStatus(response.status, errorText),
@@ -1161,9 +1277,7 @@ var IpfsHttpClient = class {
1161
1277
  }
1162
1278
  }
1163
1279
  log(message) {
1164
- if (this.debug) {
1165
- console.log(`[IPFS-HTTP] ${message}`);
1166
- }
1280
+ logger.debug("IPFS-HTTP", message);
1167
1281
  }
1168
1282
  };
1169
1283
 
@@ -1615,10 +1729,12 @@ var IpnsSubscriptionClient = class {
1615
1729
  startFallbackPolling() {
1616
1730
  if (this.fallbackPollInterval || !this.fallbackPollFn || this.destroyed) return;
1617
1731
  this.log(`Starting fallback polling (${this.fallbackPollIntervalMs / 1e3}s interval)`);
1618
- this.fallbackPollFn().catch(() => {
1732
+ this.fallbackPollFn().catch((err) => {
1733
+ logger.warn("IPNS-WS", "Fallback poll error:", err);
1619
1734
  });
1620
1735
  this.fallbackPollInterval = setInterval(() => {
1621
- this.fallbackPollFn?.().catch(() => {
1736
+ this.fallbackPollFn?.().catch((err) => {
1737
+ logger.warn("IPNS-WS", "Fallback poll error:", err);
1622
1738
  });
1623
1739
  }, this.fallbackPollIntervalMs);
1624
1740
  }
@@ -1632,9 +1748,7 @@ var IpnsSubscriptionClient = class {
1632
1748
  // Internal: Logging
1633
1749
  // ---------------------------------------------------------------------------
1634
1750
  log(message) {
1635
- if (this.debugEnabled) {
1636
- console.log(`[IPNS-WS] ${message}`);
1637
- }
1751
+ logger.debug("IPNS-WS", message);
1638
1752
  }
1639
1753
  };
1640
1754
 
@@ -1906,7 +2020,8 @@ var IpfsStorageProvider = class {
1906
2020
  } else {
1907
2021
  this.log("Warning: no healthy gateways found");
1908
2022
  }
1909
- }).catch(() => {
2023
+ }).catch((err) => {
2024
+ logger.warn("IPFS-Storage", "Gateway health check failed (non-fatal):", err);
1910
2025
  });
1911
2026
  this.isShuttingDown = false;
1912
2027
  this.status = "connected";
@@ -2070,7 +2185,7 @@ var IpfsStorageProvider = class {
2070
2185
  };
2071
2186
  const result = await this._doSave(baseData);
2072
2187
  if (!result.success) {
2073
- throw new Error(result.error ?? "Save failed");
2188
+ throw new SphereError(result.error ?? "Save failed", "STORAGE_ERROR");
2074
2189
  }
2075
2190
  this.log(`Flushed successfully: CID=${result.cid}`);
2076
2191
  } catch (error) {
@@ -2310,10 +2425,12 @@ var IpfsStorageProvider = class {
2310
2425
  if (this.flushTimer) {
2311
2426
  clearTimeout(this.flushTimer);
2312
2427
  this.flushTimer = null;
2313
- await this.flushQueue.enqueue(() => this.executeFlush()).catch(() => {
2428
+ await this.flushQueue.enqueue(() => this.executeFlush()).catch((err) => {
2429
+ logger.warn("IPFS-Storage", "Flush on shutdown failed:", err);
2314
2430
  });
2315
2431
  } else if (!this.pendingBuffer.isEmpty) {
2316
- await this.flushQueue.enqueue(() => this.executeFlush()).catch(() => {
2432
+ await this.flushQueue.enqueue(() => this.executeFlush()).catch((err) => {
2433
+ logger.warn("IPFS-Storage", "Flush on shutdown failed:", err);
2317
2434
  });
2318
2435
  } else {
2319
2436
  await this.flushQueue.enqueue(async () => {
@@ -2367,9 +2484,7 @@ var IpfsStorageProvider = class {
2367
2484
  }
2368
2485
  }
2369
2486
  log(message) {
2370
- if (this.debug) {
2371
- console.log(`[IPFS-Storage] ${message}`);
2372
- }
2487
+ logger.debug("IPFS-Storage", message);
2373
2488
  }
2374
2489
  };
2375
2490