@bounded-sh/client 0.0.2 → 0.0.4

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 (57) hide show
  1. package/dist/hooks/useQuery.d.ts +58 -0
  2. package/dist/{index-BL-0ZKBl.js → index-BBLnBZjY.js} +234 -46
  3. package/dist/index-BBLnBZjY.js.map +1 -0
  4. package/dist/{index-CqoP9udN.js → index-BMrN-6oK.js} +1202 -450
  5. package/dist/index-BMrN-6oK.js.map +1 -0
  6. package/dist/{index-B2ytfYTB.esm.js → index-D5Ut2JU7.esm.js} +1202 -450
  7. package/dist/index-D5Ut2JU7.esm.js.map +1 -0
  8. package/dist/{index-BFOmV3Pb.esm.js → index-DkWfblRJ.esm.js} +1202 -450
  9. package/dist/index-DkWfblRJ.esm.js.map +1 -0
  10. package/dist/{index-BgAygrhE.js → index-FYyc3l_y.js} +1202 -450
  11. package/dist/index-FYyc3l_y.js.map +1 -0
  12. package/dist/{index-D986s6w7.esm.js → index-n4fG6EZJ.esm.js} +229 -46
  13. package/dist/index-n4fG6EZJ.esm.js.map +1 -0
  14. package/dist/{index.browser-D2xm-q6N.esm.js → index.browser-CCWEiCH-.esm.js} +766 -773
  15. package/dist/index.browser-CCWEiCH-.esm.js.map +1 -0
  16. package/dist/{index.browser-Bd0GwRur.esm.js → index.browser-C_TToxuO.esm.js} +230 -242
  17. package/dist/index.browser-C_TToxuO.esm.js.map +1 -0
  18. package/dist/{index.browser-D8u31irV.js → index.browser-D5evrolK.js} +766 -773
  19. package/dist/index.browser-D5evrolK.js.map +1 -0
  20. package/dist/{index.browser-BeM1bzpe.js → index.browser-DcHalmEf.js} +230 -242
  21. package/dist/index.browser-DcHalmEf.js.map +1 -0
  22. package/dist/index.d.ts +2 -0
  23. package/dist/index.esm.js +1 -1
  24. package/dist/index.js +6 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/{index.native-B-cLm_BI.esm.js → index.native-D5q2RUeV.esm.js} +162 -39
  27. package/dist/index.native-D5q2RUeV.esm.js.map +1 -0
  28. package/dist/{index.native-NgHStPq0.js → index.native-D82ofFXB.js} +166 -39
  29. package/dist/index.native-D82ofFXB.js.map +1 -0
  30. package/dist/index.native.esm.js +1 -1
  31. package/dist/index.native.js +5 -1
  32. package/dist/index.native.js.map +1 -1
  33. package/dist/{phantom-wallet-provider-Cy5T9EVd.esm.js → phantom-wallet-provider-C8DNu92D.esm.js} +3 -3
  34. package/dist/{phantom-wallet-provider-Cy5T9EVd.esm.js.map → phantom-wallet-provider-C8DNu92D.esm.js.map} +1 -1
  35. package/dist/{phantom-wallet-provider-Dy48LSdU.js → phantom-wallet-provider-CoL7g8Sr.js} +3 -3
  36. package/dist/{phantom-wallet-provider-Dy48LSdU.js.map → phantom-wallet-provider-CoL7g8Sr.js.map} +1 -1
  37. package/dist/{privy-wallet-provider-CiKtBJ5M.js → privy-wallet-provider-CV1mU4KR.js} +4 -4
  38. package/dist/{privy-wallet-provider-CiKtBJ5M.js.map → privy-wallet-provider-CV1mU4KR.js.map} +1 -1
  39. package/dist/{privy-wallet-provider-BDsrUpk4.esm.js → privy-wallet-provider-De3mfJYo.esm.js} +4 -4
  40. package/dist/{privy-wallet-provider-BDsrUpk4.esm.js.map → privy-wallet-provider-De3mfJYo.esm.js.map} +1 -1
  41. package/dist/{solana-mobile-wallet-provider-CSk_FIww.esm.js → solana-mobile-wallet-provider-CLCvi-08.esm.js} +5 -5
  42. package/dist/{solana-mobile-wallet-provider-CSk_FIww.esm.js.map → solana-mobile-wallet-provider-CLCvi-08.esm.js.map} +1 -1
  43. package/dist/{solana-mobile-wallet-provider-k_YdrTJZ.js → solana-mobile-wallet-provider-D9dPbk__.js} +5 -5
  44. package/dist/{solana-mobile-wallet-provider-k_YdrTJZ.js.map → solana-mobile-wallet-provider-D9dPbk__.js.map} +1 -1
  45. package/package.json +2 -2
  46. package/dist/index-B2ytfYTB.esm.js.map +0 -1
  47. package/dist/index-BFOmV3Pb.esm.js.map +0 -1
  48. package/dist/index-BL-0ZKBl.js.map +0 -1
  49. package/dist/index-BgAygrhE.js.map +0 -1
  50. package/dist/index-CqoP9udN.js.map +0 -1
  51. package/dist/index-D986s6w7.esm.js.map +0 -1
  52. package/dist/index.browser-Bd0GwRur.esm.js.map +0 -1
  53. package/dist/index.browser-BeM1bzpe.js.map +0 -1
  54. package/dist/index.browser-D2xm-q6N.esm.js.map +0 -1
  55. package/dist/index.browser-D8u31irV.js.map +0 -1
  56. package/dist/index.native-B-cLm_BI.esm.js.map +0 -1
  57. package/dist/index.native-NgHStPq0.js.map +0 -1
@@ -11284,6 +11284,13 @@ async function runExpressionMany(many) {
11284
11284
  throw error;
11285
11285
  }
11286
11286
  }
11287
+ /**
11288
+ * Write a document at `path`. Sugar for a one-element {@link setMany}.
11289
+ *
11290
+ * **Delete:** pass `null` as the document to delete it — `set(path, null)` is
11291
+ * the delete (there is no separate `del`/`remove`). It is routed through the
11292
+ * collection's policy `delete` rule and broadcasts a delete to subscribers.
11293
+ */
11287
11294
  async function set(path, document, options) {
11288
11295
  const result = await setMany([{ path, document }], options);
11289
11296
  // Clear cache entries that might be affected by this update
@@ -12962,6 +12969,73 @@ function serverTimestamp() {
12962
12969
  return { operation: 'time', value: 'now' };
12963
12970
  }
12964
12971
 
12972
+ /**
12973
+ * Time units in Bounded — read this once and never get a 1000× timestamp bug.
12974
+ *
12975
+ * **Bounded's policy/proof layer is Unix SECONDS.** `@time.now` in a rule,
12976
+ * `rollingSum` `windowSeconds`, `scheduledAt`, and any timestamp *field your
12977
+ * policy compares against `@time.now`* are all **seconds**. (This is also what
12978
+ * the chain uses — Solana's on-chain clock is `unix_timestamp` in seconds — so a
12979
+ * single seconds unit works for both onchain and offchain rules.)
12980
+ *
12981
+ * **JavaScript is MILLISECONDS.** `Date.now()`, `new Date().getTime()`, and the
12982
+ * auto-stamped system fields `_createdAt` / `_updatedAt` are all **ms**.
12983
+ *
12984
+ * Comparing across the two (e.g. `@time.now - myField` where `myField` was set
12985
+ * from `Date.now()`) is 1000× off, so a freshness / TTL check silently treats
12986
+ * every row as ancient (or far-future) and drops it — which reads as "realtime
12987
+ * isn't delivering" when the data is actually fine.
12988
+ *
12989
+ * **The rules:**
12990
+ * - To **write** a timestamp a policy will read, prefer **`serverTimestamp()`**
12991
+ * (from this package) — the *server* stamps it in seconds, so it matches
12992
+ * `@time.now` AND can't be forged by the client (use it for TTLs, rate windows,
12993
+ * anti-cheat). Use `now()` only when you need the value in client code before
12994
+ * the write.
12995
+ * - To **compare** timestamps in client/render code, use `now()` (seconds), not
12996
+ * `Date.now()` (ms), and `toSeconds()` to convert the ms system fields
12997
+ * (`_createdAt`/`_updatedAt`) or any `Date.now()` value first.
12998
+ */
12999
+ /**
13000
+ * Current time as a **Unix timestamp in seconds** — the unit Bounded policy rules
13001
+ * use (`@time.now`). Use this (not `Date.now()`) when you need a timestamp in
13002
+ * client code (e.g. a freshness check). For a value you *store* and a policy
13003
+ * reads, prefer the server-authoritative {@link serverTimestamp} instead.
13004
+ *
13005
+ * ```ts
13006
+ * // stale if >15s old — seconds vs seconds ✓
13007
+ * if (now() - doc.lastSeenSeconds > 15) renderStale();
13008
+ * ```
13009
+ */
13010
+ function now() {
13011
+ return Math.floor(Date.now() / 1000);
13012
+ }
13013
+ /**
13014
+ * Convert a JavaScript millisecond timestamp to Bounded's **seconds**. Accepts a
13015
+ * `Date`, or an ms number such as `Date.now()` or a doc's `_createdAt` /
13016
+ * `_updatedAt` system field.
13017
+ *
13018
+ * ```ts
13019
+ * // doc is >15s old (compare the ms system field in seconds):
13020
+ * if (now() - toSeconds(doc._updatedAt) > 15) renderStale();
13021
+ * ```
13022
+ */
13023
+ function toSeconds(msOrDate) {
13024
+ const ms = msOrDate instanceof Date ? msOrDate.getTime() : msOrDate;
13025
+ return Math.floor(ms / 1000);
13026
+ }
13027
+ /**
13028
+ * Convert a Bounded **seconds** timestamp back to JavaScript **milliseconds** —
13029
+ * e.g. to build a `Date` or do client-side date math/formatting.
13030
+ *
13031
+ * ```ts
13032
+ * new Date(toMillis(doc.createdAtSeconds)).toLocaleString();
13033
+ * ```
13034
+ */
13035
+ function toMillis(seconds) {
13036
+ return seconds * 1000;
13037
+ }
13038
+
12965
13039
  // ---------------------------------------------------------------------------
12966
13040
  // realtime-store.ts — Client-side state manager for realtime apps.
12967
13041
  //
@@ -13865,6 +13939,7 @@ const functions = { invoke };
13865
13939
  // collection. This file is the consumer surface around that runtime:
13866
13940
  //
13867
13941
  // bounded.live.intent(roomPath, intent) -> POST {realtime}/live/intent
13942
+ // bounded.live.status(roomPath) -> GET {realtime}/live/status
13868
13943
  //
13869
13944
  // It mirrors `functions.invoke` exactly: it attaches the caller's session token
13870
13945
  // AUTOMATICALLY (the same token the SDK uses for data reads/writes), and throws
@@ -13877,18 +13952,14 @@ const functions = { invoke };
13877
13952
  // Addressing: clients address rooms BY PATH (the `path` field in the body). The
13878
13953
  // worker derives the roomId from `body.path` and sets X-Room-Id internally;
13879
13954
  // clients NEVER set X-Room-Id. The caller's address is taken server-side from
13880
- // the Authorization header (auth.userAddress) — it is NOT sent in the body.
13955
+ // the Authorization header (auth.userId/userAddress) — it is NOT sent in the
13956
+ // body.
13881
13957
  //
13882
13958
  // Subscribing to your view: a per-player view doc lives at
13883
- // `<roomPath>/view/<myAddress>` (the policy declares
13884
- // `rooms/$roomId/view/$addr` ephemeral with `read: $addr == @user.address`).
13885
- // That path has an EVEN segment count, so it is an ordinary document path —
13886
- // plain `subscribe('<roomPath>/view/<myAddress>', { onData })` already works.
13887
- // `subscribeView()` below is thin sugar over that (path construction + address
13888
- // defaulting); it adds zero new transport.
13889
- //
13890
- // Status polling (GET /live/status?path=<sessionCollection>/<roomId>) is out of
13891
- // scope for this piece — see follow-up.
13959
+ // `<roomPath>/view/<myUserId>` (the policy declares
13960
+ // `rooms/$roomId/view/$userId` ephemeral with `read: $userId == @user.id`).
13961
+ // Wallet-address keyed view paths remain supported through opts.address for
13962
+ // older policies, but new live rooms should key views by @user.id.
13892
13963
  // ---------------------------------------------------------------------------
13893
13964
  class LiveIntentError extends Error {
13894
13965
  constructor(message, statusCode, details) {
@@ -13969,7 +14040,7 @@ async function intent(roomPath, intent, opts = {}) {
13969
14040
  res = await fetch(`${base}/live/intent`, {
13970
14041
  method: 'POST',
13971
14042
  headers,
13972
- body: JSON.stringify({ path: roomPath, intent }),
14043
+ body: JSON.stringify({ path: normalizedRoomPath, intent }),
13973
14044
  signal: controller.signal,
13974
14045
  });
13975
14046
  }
@@ -13997,43 +14068,95 @@ async function intent(roomPath, intent, opts = {}) {
13997
14068
  }
13998
14069
  return (body !== null && body !== void 0 ? body : { ok: true });
13999
14070
  }
14071
+ /**
14072
+ * Fetch the runtime status for a live room.
14073
+ *
14074
+ * const s = await bounded.live.status('rooms/abc');
14075
+ * console.log(s.running, s.stopReason, s.generation, s.etag);
14076
+ *
14077
+ * This is diagnostic/ops surface. It reports whether the room facet exists,
14078
+ * whether it is currently ticking, why it last stopped, which module etag is
14079
+ * loaded, and the current generation used after terminal restarts.
14080
+ */
14081
+ async function status(roomPath, opts = {}) {
14082
+ var _a, _b, _c, _d, _e;
14083
+ if (!roomPath || typeof roomPath !== 'string') {
14084
+ throw new LiveIntentError('A room path is required');
14085
+ }
14086
+ const normalizedRoomPath = roomPath.replace(/\/$/, '');
14087
+ const config = await getConfig();
14088
+ const base = realtimeHttpBase(config.wsApiUrl);
14089
+ const headers = Object.assign({ 'X-App-Id': config.appId, 'X-Public-App-Id': config.appId }, ((_a = opts.headers) !== null && _a !== void 0 ? _a : {}));
14090
+ const controller = new AbortController();
14091
+ const timeoutMs = (_b = opts.timeoutMs) !== null && _b !== void 0 ? _b : 15000;
14092
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
14093
+ let res;
14094
+ try {
14095
+ res = await fetch(`${base}/live/status?path=${encodeURIComponent(normalizedRoomPath)}`, {
14096
+ method: 'GET',
14097
+ headers,
14098
+ signal: controller.signal,
14099
+ });
14100
+ }
14101
+ catch (err) {
14102
+ clearTimeout(timer);
14103
+ if ((err === null || err === void 0 ? void 0 : err.name) === 'AbortError') {
14104
+ throw new LiveIntentError(`Live status for "${normalizedRoomPath}" timed out after ${timeoutMs}ms`);
14105
+ }
14106
+ throw new LiveIntentError(`Failed to reach the realtime worker: ${(_c = err === null || err === void 0 ? void 0 : err.message) !== null && _c !== void 0 ? _c : String(err)}`);
14107
+ }
14108
+ clearTimeout(timer);
14109
+ let body = null;
14110
+ const text = await res.text();
14111
+ if (text) {
14112
+ try {
14113
+ body = JSON.parse(text);
14114
+ }
14115
+ catch (_f) {
14116
+ body = { raw: text };
14117
+ }
14118
+ }
14119
+ if (!res.ok) {
14120
+ const message = (_e = (_d = body === null || body === void 0 ? void 0 : body.error) !== null && _d !== void 0 ? _d : body === null || body === void 0 ? void 0 : body.message) !== null && _e !== void 0 ? _e : `Live status failed with HTTP ${res.status}`;
14121
+ throw new LiveIntentError(message, res.status, body);
14122
+ }
14123
+ return body;
14124
+ }
14000
14125
  /**
14001
14126
  * Subscribe to YOUR per-player view of a room. Thin sugar over:
14002
14127
  *
14003
- * subscribe('<roomPath>/view/<myAddress>', { onData, onError })
14128
+ * subscribe('<roomPath>/view/<myUserId>', { onData, onError })
14004
14129
  *
14005
- * The address defaults to the logged-in user's address (from the session
14006
- * token's claims); pass `opts.address` to override. Returns the unsubscribe
14130
+ * The view id defaults to the logged-in user's @user.id (from the session token
14131
+ * claims); pass `opts.userId` to override. `opts.address` is kept as a legacy
14132
+ * alias for older wallet-address keyed policies. Returns the unsubscribe
14007
14133
  * function (a Promise<() => Promise<void>>, same as `subscribe`).
14008
14134
  *
14009
14135
  * Note: this is a browser-first helper (the WS subscription manager is
14010
14136
  * browser-oriented). Server consumers should use `live.intent`.
14011
14137
  */
14012
14138
  async function subscribeView(roomPath, opts) {
14013
- var _a;
14139
+ var _a, _b, _c;
14014
14140
  if (!roomPath || typeof roomPath !== 'string') {
14015
14141
  throw new LiveIntentError('A room path is required');
14016
14142
  }
14017
14143
  if (!opts || typeof opts.onData !== 'function') {
14018
14144
  throw new LiveIntentError('subscribeView requires an onData callback');
14019
14145
  }
14020
- let address = opts.address;
14021
- if (!address) {
14146
+ let viewUserId = (_a = opts.userId) !== null && _a !== void 0 ? _a : opts.address;
14147
+ if (!viewUserId) {
14022
14148
  const config = await getConfig();
14023
14149
  const info = await getUserInfo(config.isServer);
14024
- // getUserInfo returns the RAW idToken payload — the wallet address lives in
14025
- // the `custom:walletAddress` claim, NOT a flat `address` field. Reading only
14026
- // `.address` meant auto-resolution NEVER worked, forcing every caller (browser
14027
- // AND server) to pass opts.address — the client having to hand the backend an
14028
- // identity it already authenticated. Resolve it from the actual claim so a
14029
- // logged-in caller never needs to pass its own address.
14030
- address = (_a = info === null || info === void 0 ? void 0 : info.address) !== null && _a !== void 0 ? _a : info === null || info === void 0 ? void 0 : info['custom:walletAddress'];
14150
+ // getUserInfo returns the RAW idToken payload. The universal live view key
14151
+ // is @user.id (`custom:userId`); wallet-address keyed views are still
14152
+ // resolved as a compatibility fallback for older policies.
14153
+ viewUserId = (_c = (_b = info === null || info === void 0 ? void 0 : info['custom:userId']) !== null && _b !== void 0 ? _b : info === null || info === void 0 ? void 0 : info['custom:walletAddress']) !== null && _c !== void 0 ? _c : info === null || info === void 0 ? void 0 : info.address;
14031
14154
  }
14032
- if (!address || typeof address !== 'string') {
14033
- throw new LiveIntentError('Could not resolve a player address for subscribeView; pass opts.address or log in first');
14155
+ if (!viewUserId || typeof viewUserId !== 'string') {
14156
+ throw new LiveIntentError('Could not resolve a player view id for subscribeView; pass opts.userId or log in first');
14034
14157
  }
14035
14158
  const normalizedRoomPath = roomPath.replace(/\/$/, '');
14036
- const viewPath = `${normalizedRoomPath}/view/${address}`;
14159
+ const viewPath = `${normalizedRoomPath}/view/${viewUserId}`;
14037
14160
  // This is a LIVE/room subscription by construction (the caller hands us the
14038
14161
  // room path), so we route its connection to the per-room DO where the live
14039
14162
  // view fan-out runs. App code passes NO routing — the room path is the helper's
@@ -14044,7 +14167,7 @@ async function subscribeView(roomPath, opts) {
14044
14167
  return subscribeV2(viewPath, { onData: opts.onData, onError: opts.onError }, normalizedRoomPath);
14045
14168
  }
14046
14169
  /** The `bounded.live` namespace surface. */
14047
- const live = { intent, subscribeView };
14170
+ const live = { intent, status, subscribeView };
14048
14171
 
14049
14172
  // ---------------------------------------------------------------------------
14050
14173
  // live-effects.ts -- AUTHOR-facing types + helpers for writing a Bounded live
@@ -17688,11 +17811,11 @@ var srcExports = requireSrc();
17688
17811
  var basex = /*@__PURE__*/getDefaultExportFromCjs$1(srcExports);
17689
17812
 
17690
17813
  var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
17691
- var base58 = basex(ALPHABET);
17814
+ var bs582 = basex(ALPHABET);
17692
17815
 
17693
17816
  var index = /*#__PURE__*/Object.freeze({
17694
17817
  __proto__: null,
17695
- default: base58
17818
+ default: bs582
17696
17819
  });
17697
17820
 
17698
17821
  // guest-keystore.ts — durable per-device keypair for anonymous ("guest") auth.
@@ -17765,7 +17888,7 @@ async function tryWebCrypto() {
17765
17888
  await idbPut(db, IDB_KEY, pair); // CryptoKey is structured-cloneable; bytes never exposed
17766
17889
  }
17767
17890
  const raw = new Uint8Array(await s.exportKey('raw', pair.publicKey)); // public is exportable
17768
- const address = base58.encode(raw);
17891
+ const address = bs582.encode(raw);
17769
17892
  return {
17770
17893
  address,
17771
17894
  nonExtractable: true,
@@ -17786,12 +17909,12 @@ function fallbackKey() {
17786
17909
  let secret;
17787
17910
  const saved = store.getItem(FALLBACK_STORE_KEY);
17788
17911
  if (saved) {
17789
- secret = base58.decode(saved);
17912
+ secret = bs582.decode(saved);
17790
17913
  }
17791
17914
  else {
17792
17915
  const kp = Keypair.generate();
17793
17916
  secret = kp.secretKey; // 64 bytes
17794
- store.setItem(FALLBACK_STORE_KEY, base58.encode(secret));
17917
+ store.setItem(FALLBACK_STORE_KEY, bs582.encode(secret));
17795
17918
  }
17796
17919
  const kp = Keypair.fromSecretKey(secret);
17797
17920
  const address = kp.publicKey.toBase58();
@@ -19076,17 +19199,17 @@ function setAuthProviderInstance(provider) {
19076
19199
  authProviderInstance = provider;
19077
19200
  }
19078
19201
 
19079
- var _a;
19202
+ var _a$1;
19080
19203
  // Whether we're in a server-side rendering context (no hooks allowed).
19081
19204
  // React Native has no `window` but DOES support hooks.
19082
19205
  // We detect Node SSR specifically via process.versions.node to avoid
19083
19206
  // false positives from Node 21+ which defines `navigator` globally.
19084
- const isSSR = typeof window === 'undefined'
19207
+ const isSSR$1 = typeof window === 'undefined'
19085
19208
  && typeof process !== 'undefined'
19086
- && !!((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node);
19209
+ && !!((_a$1 = process.versions) === null || _a$1 === void 0 ? void 0 : _a$1.node);
19087
19210
  function useAuth() {
19088
19211
  // Provide a fallback so server render doesn't break
19089
- if (isSSR) {
19212
+ if (isSSR$1) {
19090
19213
  return {
19091
19214
  login: async () => undefined,
19092
19215
  logout: async () => undefined,
@@ -19146,6 +19269,66 @@ function useAuth() {
19146
19269
  };
19147
19270
  }
19148
19271
 
19272
+ var _a;
19273
+ // SSR guard (mirrors useAuth): no hooks/subscriptions during Node server render.
19274
+ // React Native has no `window` but DOES support hooks, so detect Node SSR
19275
+ // specifically via process.versions.node.
19276
+ const isSSR = typeof window === 'undefined'
19277
+ && typeof process !== 'undefined'
19278
+ && !!((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node);
19279
+ function useQuery(path, options) {
19280
+ if (isSSR) {
19281
+ return { data: undefined, loading: true, error: null };
19282
+ }
19283
+ const [data, setData] = React$1.useState(undefined);
19284
+ const [loading, setLoading] = React$1.useState(true);
19285
+ const [error, setError] = React$1.useState(null);
19286
+ // Re-subscribe only when the query actually changes (not on every render).
19287
+ const optionsKey = options ? JSON.stringify(options) : '';
19288
+ React$1.useEffect(() => {
19289
+ if (!path) {
19290
+ setData(undefined);
19291
+ setLoading(false);
19292
+ setError(null);
19293
+ return;
19294
+ }
19295
+ let active = true;
19296
+ let unsubscribe;
19297
+ setLoading(true);
19298
+ setError(null);
19299
+ subscribe(path, Object.assign(Object.assign({}, options), { onData: (d) => {
19300
+ if (!active)
19301
+ return;
19302
+ setData(d);
19303
+ setLoading(false);
19304
+ }, onError: (e) => {
19305
+ if (!active)
19306
+ return;
19307
+ setError(e instanceof Error ? e : new Error(String(e)));
19308
+ setLoading(false);
19309
+ } }))
19310
+ .then((unsub) => {
19311
+ if (active)
19312
+ unsubscribe = unsub;
19313
+ else
19314
+ void unsub(); // unmounted before subscribe resolved
19315
+ })
19316
+ .catch((e) => {
19317
+ if (!active)
19318
+ return;
19319
+ setError(e instanceof Error ? e : new Error(String(e)));
19320
+ setLoading(false);
19321
+ });
19322
+ return () => {
19323
+ active = false;
19324
+ void (unsubscribe === null || unsubscribe === void 0 ? void 0 : unsubscribe());
19325
+ };
19326
+ // optionsKey captures the option object's contents; path is the other input.
19327
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19328
+ }, [path, optionsKey]);
19329
+ return { data, loading, error };
19330
+ }
19331
+
19149
19332
  async function deserializeTransaction(tx) {
19150
19333
  const buf = Buffer.isBuffer(tx) ? tx : Buffer.from(tx, 'base64');
19151
19334
  if ((buf[0] & 0x80) !== 0) {
@@ -19279,7 +19462,7 @@ async function loadDependencies() {
19279
19462
  const [reactModule, reactDomModule, phantomModule] = await Promise.all([
19280
19463
  import('react'),
19281
19464
  import('react-dom/client'),
19282
- import('./index-B2ytfYTB.esm.js')
19465
+ import('./index-D5Ut2JU7.esm.js')
19283
19466
  ]);
19284
19467
  // Extract default export from ESM module namespace
19285
19468
  // Dynamic import() returns { default: Module, ...exports }, not the module directly
@@ -21180,7 +21363,7 @@ async function registerMobileWalletAdapter(config) {
21180
21363
  if (typeof window === 'undefined')
21181
21364
  return;
21182
21365
  try {
21183
- const walletStandardMobile = await import('./index.browser-D2xm-q6N.esm.js');
21366
+ const walletStandardMobile = await import('./index.browser-CCWEiCH-.esm.js');
21184
21367
  const registerMwa = walletStandardMobile.registerMwa || ((_a = walletStandardMobile.default) === null || _a === void 0 ? void 0 : _a.registerMwa);
21185
21368
  if (!registerMwa) {
21186
21369
  console.warn('[SolanaMobileWallet] registerMwa not found in @solana-mobile/wallet-standard-mobile');
@@ -21319,7 +21502,7 @@ class SolanaMobileWalletProvider {
21319
21502
  async ensureWallet() {
21320
21503
  if (this.wallet)
21321
21504
  return this.wallet;
21322
- const mod = await import('./index.browser-D2xm-q6N.esm.js');
21505
+ const mod = await import('./index.browser-CCWEiCH-.esm.js');
21323
21506
  const chain = mapChainToWalletStandard(this.cluster);
21324
21507
  this.wallet = new mod.LocalSolanaMobileWalletAdapterWallet({
21325
21508
  appIdentity: this.appIdentity,
@@ -21937,7 +22120,7 @@ class SolanaMobileWalletProvider {
21937
22120
  options: { commitment: 'confirmed' },
21938
22121
  }));
21939
22122
  const { signature: sigBytes } = sendResult;
21940
- const signature = base58.encode(sigBytes);
22123
+ const signature = bs582.encode(sigBytes);
21941
22124
  await confirmAndCheckTransaction(connection, signature);
21942
22125
  return signature;
21943
22126
  }
@@ -22085,7 +22268,7 @@ class SolanaMobileWalletProvider {
22085
22268
  throw new Error('MWA returned no signature');
22086
22269
  }
22087
22270
  const { signature: sigBytes } = sendResult;
22088
- const signature = base58.encode(sigBytes);
22271
+ const signature = bs582.encode(sigBytes);
22089
22272
  const txInfo = await confirmAndCheckTransaction(connection, signature);
22090
22273
  return {
22091
22274
  transactionSignature: signature,
@@ -22922,7 +23105,7 @@ class PrivyWalletProvider {
22922
23105
  // Handle case where signature might be bytes instead of string
22923
23106
  const rawSig = result.signature;
22924
23107
  if (rawSig instanceof Uint8Array || Array.isArray(rawSig)) {
22925
- signature = base58.encode(rawSig instanceof Uint8Array ? rawSig : new Uint8Array(rawSig));
23108
+ signature = bs582.encode(rawSig instanceof Uint8Array ? rawSig : new Uint8Array(rawSig));
22926
23109
  }
22927
23110
  else {
22928
23111
  signature = rawSig;
@@ -23284,7 +23467,7 @@ class PrivyExpoProvider {
23284
23467
  const wallet = await this.getWalletOrThrow();
23285
23468
  const messageBytes = getPlatform().textEncode(message);
23286
23469
  const result = await wallet.signMessage(messageBytes);
23287
- return base58.encode(result.signature);
23470
+ return bs582.encode(result.signature);
23288
23471
  }
23289
23472
  async signTransaction(transaction) {
23290
23473
  await this.ensureReady();
@@ -23452,5 +23635,5 @@ class PrivyExpoProvider {
23452
23635
  }
23453
23636
  }
23454
23637
 
23455
- export { EFFECT_INTENT_ADDRESS as $, getFiles as A, search as B, queryAggregate as C, runQuery as D, runQueryMany as E, runExpression as F, runExpressionMany as G, signMessage as H, signTransaction as I, signAndSubmitTransaction as J, count as K, aggregate as L, subscribe as M, useAuth as N, deserializeTransaction as O, getIdToken as P, setPlatform as Q, getPlatform as R, PhantomWalletProvider as S, MockAuthProvider as T, DEFAULT_TEST_ADDRESS as U, OffchainAuthProvider as V, SolanaMobileWalletProvider as W, isMobileWalletAvailable as X, registerMobileWalletAdapter as Y, PrivyWalletProvider as Z, PrivyExpoProvider as _, base58 as a, FunctionInvokeError as a0, InsufficientBalanceError as a1, LiveIntentError as a2, ReactNativeSessionManager as a3, RealtimeStore as a4, ServerSessionManager as a5, WebSessionManager as a6, buildSetDocumentsTransaction as a7, clearCache as a8, closeAllSubscriptions as a9, wsDelete as aA, wsGet as aB, wsGetMany as aC, wsQuery as aD, wsSet as aE, convertRemainingAccounts as aa, createSessionWithSignature as ab, defineLiveModule as ac, deriveUserIdentityFromIdToken as ad, functions as ae, genAuthNonce as af, genSolanaMessage as ag, getActiveSessionManager as ah, getCachedData as ai, getMany as aj, getRealtimeStore as ak, getWebhookKeysUrl as al, hasActiveConnection as am, increment as an, invoke as ao, isEffectResult as ap, live as aq, intent as ar, reconnectWithNewAuth as as, refreshSession as at, resetRealtimeStore as au, revokeSession as av, serverTimestamp as aw, signSessionCreateMessage as ax, subscribeView as ay, withEffects as az, bufferExports as b, getCurrentUser as c, onAuthLoadingChanged as d, getAuthLoading as e, logout as f, getDefaultExportFromCjs$1 as g, getConfig as h, init as i, getAuthProvider as j, sendEmailOtp as k, login as l, linkEmail as m, loginWithPrivy as n, onAuthStateChanged as o, loginWithRedirect as p, linkWithRedirect as q, completeLoginFromRedirect as r, signInAnonymously as s, loginWithPopup as t, completeLoginInPopup as u, verifyEmailOtp as v, get as w, set as x, setMany as y, setFile as z };
23456
- //# sourceMappingURL=index-D986s6w7.esm.js.map
23638
+ export { PrivyExpoProvider as $, getFiles as A, search as B, queryAggregate as C, runQuery as D, runQueryMany as E, runExpression as F, runExpressionMany as G, signMessage as H, signTransaction as I, signAndSubmitTransaction as J, count as K, aggregate as L, subscribe as M, useAuth as N, useQuery as O, deserializeTransaction as P, getIdToken as Q, setPlatform as R, getPlatform as S, PhantomWalletProvider as T, MockAuthProvider as U, DEFAULT_TEST_ADDRESS as V, OffchainAuthProvider as W, SolanaMobileWalletProvider as X, isMobileWalletAvailable as Y, registerMobileWalletAdapter as Z, PrivyWalletProvider as _, bs582 as a, EFFECT_INTENT_ADDRESS as a0, FunctionInvokeError as a1, InsufficientBalanceError as a2, LiveIntentError as a3, ReactNativeSessionManager as a4, RealtimeStore as a5, ServerSessionManager as a6, WebSessionManager as a7, buildSetDocumentsTransaction as a8, clearCache as a9, signSessionCreateMessage as aA, subscribeView as aB, toMillis as aC, toSeconds as aD, withEffects as aE, wsDelete as aF, wsGet as aG, wsGetMany as aH, wsQuery as aI, wsSet as aJ, closeAllSubscriptions as aa, convertRemainingAccounts as ab, createSessionWithSignature as ac, defineLiveModule as ad, deriveUserIdentityFromIdToken as ae, functions as af, genAuthNonce as ag, genSolanaMessage as ah, getActiveSessionManager as ai, getCachedData as aj, getMany as ak, getRealtimeStore as al, getWebhookKeysUrl as am, hasActiveConnection as an, increment as ao, invoke as ap, isEffectResult as aq, live as ar, intent as as, status as at, now as au, reconnectWithNewAuth as av, refreshSession as aw, resetRealtimeStore as ax, revokeSession as ay, serverTimestamp as az, bufferExports as b, getCurrentUser as c, onAuthLoadingChanged as d, getAuthLoading as e, logout as f, getDefaultExportFromCjs$1 as g, getConfig as h, init as i, getAuthProvider as j, sendEmailOtp as k, login as l, linkEmail as m, loginWithPrivy as n, onAuthStateChanged as o, loginWithRedirect as p, linkWithRedirect as q, completeLoginFromRedirect as r, signInAnonymously as s, loginWithPopup as t, completeLoginInPopup as u, verifyEmailOtp as v, get as w, set as x, setMany as y, setFile as z };
23639
+ //# sourceMappingURL=index-n4fG6EZJ.esm.js.map