@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
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Reactive realtime query hook — the ergonomic counterpart to the imperative
3
+ * `subscribe(path, { onData })`.
4
+ *
5
+ * `useQuery` subscribes for you and returns an **auto-updating value**, so you
6
+ * never write an `onData` callback (and never trip the classic trap of treating
7
+ * the *first* callback as the final state). `data` always holds the **full,
8
+ * current, read-rule-filtered** result the server last delivered — an array for
9
+ * a collection path, the document (or `null`) for a single-document path — and
10
+ * re-renders whenever ANY writer changes the matching set.
11
+ *
12
+ * ```tsx
13
+ * const { data: rows, loading, error } = useQuery<Presence[]>(
14
+ * `rooms/${roomId}/presence`,
15
+ * { filter: { online: true } },
16
+ * );
17
+ * if (loading) return <Spinner/>;
18
+ * return <>{rows!.map(p => <Peer key={p._id} p={p}/>)}</>; // shows EVERYONE, always
19
+ * ```
20
+ *
21
+ * Mirrors Convex's `useQuery`: there is no callback to get wrong, so a doc
22
+ * another client writes a moment later simply appears in `data` on the next
23
+ * render — there is no "missed cross-writer update".
24
+ *
25
+ * Pass `path = null`/`undefined` to skip subscribing (e.g. until an id is ready);
26
+ * `data` stays `undefined` and `loading` flips to `false`.
27
+ */
28
+ export interface UseQueryOptions {
29
+ /** MongoDB-style filter, same shape as `get()`/`subscribe()`. */
30
+ filter?: Record<string, any>;
31
+ /** Server-side sort, e.g. `{ createdAt: -1 }`. */
32
+ sort?: Record<string, number>;
33
+ /** Natural-language filter (AI), evaluated server-side. */
34
+ prompt?: string;
35
+ /** Also walk nested sub-collections at the path. */
36
+ includeSubPaths?: boolean;
37
+ /** Expand relationship links on each delivered doc. */
38
+ shape?: Record<string, any>;
39
+ /** Cap how many docs the live feed tracks. */
40
+ limit?: number;
41
+ /** Pagination cursor. */
42
+ cursor?: string;
43
+ /** Explicit app id override (else the configured one). */
44
+ appId?: string;
45
+ }
46
+ export interface UseQueryResult<T> {
47
+ /**
48
+ * The full current value the server delivered: an array of documents for a
49
+ * collection path, the document (or `null`) for a single-document path, and
50
+ * `undefined` before the first delivery (or when `path` is nullish).
51
+ */
52
+ data: T | undefined;
53
+ /** `true` until the first delivery arrives. */
54
+ loading: boolean;
55
+ /** The last subscription error, or `null`. */
56
+ error: Error | null;
57
+ }
58
+ export declare function useQuery<T = any>(path: string | null | undefined, options?: UseQueryOptions): UseQueryResult<T>;
@@ -11306,6 +11306,13 @@ async function runExpressionMany(many) {
11306
11306
  throw error;
11307
11307
  }
11308
11308
  }
11309
+ /**
11310
+ * Write a document at `path`. Sugar for a one-element {@link setMany}.
11311
+ *
11312
+ * **Delete:** pass `null` as the document to delete it — `set(path, null)` is
11313
+ * the delete (there is no separate `del`/`remove`). It is routed through the
11314
+ * collection's policy `delete` rule and broadcasts a delete to subscribers.
11315
+ */
11309
11316
  async function set(path, document, options) {
11310
11317
  const result = await setMany([{ path, document }], options);
11311
11318
  // Clear cache entries that might be affected by this update
@@ -12984,6 +12991,73 @@ function serverTimestamp() {
12984
12991
  return { operation: 'time', value: 'now' };
12985
12992
  }
12986
12993
 
12994
+ /**
12995
+ * Time units in Bounded — read this once and never get a 1000× timestamp bug.
12996
+ *
12997
+ * **Bounded's policy/proof layer is Unix SECONDS.** `@time.now` in a rule,
12998
+ * `rollingSum` `windowSeconds`, `scheduledAt`, and any timestamp *field your
12999
+ * policy compares against `@time.now`* are all **seconds**. (This is also what
13000
+ * the chain uses — Solana's on-chain clock is `unix_timestamp` in seconds — so a
13001
+ * single seconds unit works for both onchain and offchain rules.)
13002
+ *
13003
+ * **JavaScript is MILLISECONDS.** `Date.now()`, `new Date().getTime()`, and the
13004
+ * auto-stamped system fields `_createdAt` / `_updatedAt` are all **ms**.
13005
+ *
13006
+ * Comparing across the two (e.g. `@time.now - myField` where `myField` was set
13007
+ * from `Date.now()`) is 1000× off, so a freshness / TTL check silently treats
13008
+ * every row as ancient (or far-future) and drops it — which reads as "realtime
13009
+ * isn't delivering" when the data is actually fine.
13010
+ *
13011
+ * **The rules:**
13012
+ * - To **write** a timestamp a policy will read, prefer **`serverTimestamp()`**
13013
+ * (from this package) — the *server* stamps it in seconds, so it matches
13014
+ * `@time.now` AND can't be forged by the client (use it for TTLs, rate windows,
13015
+ * anti-cheat). Use `now()` only when you need the value in client code before
13016
+ * the write.
13017
+ * - To **compare** timestamps in client/render code, use `now()` (seconds), not
13018
+ * `Date.now()` (ms), and `toSeconds()` to convert the ms system fields
13019
+ * (`_createdAt`/`_updatedAt`) or any `Date.now()` value first.
13020
+ */
13021
+ /**
13022
+ * Current time as a **Unix timestamp in seconds** — the unit Bounded policy rules
13023
+ * use (`@time.now`). Use this (not `Date.now()`) when you need a timestamp in
13024
+ * client code (e.g. a freshness check). For a value you *store* and a policy
13025
+ * reads, prefer the server-authoritative {@link serverTimestamp} instead.
13026
+ *
13027
+ * ```ts
13028
+ * // stale if >15s old — seconds vs seconds ✓
13029
+ * if (now() - doc.lastSeenSeconds > 15) renderStale();
13030
+ * ```
13031
+ */
13032
+ function now() {
13033
+ return Math.floor(Date.now() / 1000);
13034
+ }
13035
+ /**
13036
+ * Convert a JavaScript millisecond timestamp to Bounded's **seconds**. Accepts a
13037
+ * `Date`, or an ms number such as `Date.now()` or a doc's `_createdAt` /
13038
+ * `_updatedAt` system field.
13039
+ *
13040
+ * ```ts
13041
+ * // doc is >15s old (compare the ms system field in seconds):
13042
+ * if (now() - toSeconds(doc._updatedAt) > 15) renderStale();
13043
+ * ```
13044
+ */
13045
+ function toSeconds(msOrDate) {
13046
+ const ms = msOrDate instanceof Date ? msOrDate.getTime() : msOrDate;
13047
+ return Math.floor(ms / 1000);
13048
+ }
13049
+ /**
13050
+ * Convert a Bounded **seconds** timestamp back to JavaScript **milliseconds** —
13051
+ * e.g. to build a `Date` or do client-side date math/formatting.
13052
+ *
13053
+ * ```ts
13054
+ * new Date(toMillis(doc.createdAtSeconds)).toLocaleString();
13055
+ * ```
13056
+ */
13057
+ function toMillis(seconds) {
13058
+ return seconds * 1000;
13059
+ }
13060
+
12987
13061
  // ---------------------------------------------------------------------------
12988
13062
  // realtime-store.ts — Client-side state manager for realtime apps.
12989
13063
  //
@@ -13887,6 +13961,7 @@ const functions = { invoke };
13887
13961
  // collection. This file is the consumer surface around that runtime:
13888
13962
  //
13889
13963
  // bounded.live.intent(roomPath, intent) -> POST {realtime}/live/intent
13964
+ // bounded.live.status(roomPath) -> GET {realtime}/live/status
13890
13965
  //
13891
13966
  // It mirrors `functions.invoke` exactly: it attaches the caller's session token
13892
13967
  // AUTOMATICALLY (the same token the SDK uses for data reads/writes), and throws
@@ -13899,18 +13974,14 @@ const functions = { invoke };
13899
13974
  // Addressing: clients address rooms BY PATH (the `path` field in the body). The
13900
13975
  // worker derives the roomId from `body.path` and sets X-Room-Id internally;
13901
13976
  // clients NEVER set X-Room-Id. The caller's address is taken server-side from
13902
- // the Authorization header (auth.userAddress) — it is NOT sent in the body.
13977
+ // the Authorization header (auth.userId/userAddress) — it is NOT sent in the
13978
+ // body.
13903
13979
  //
13904
13980
  // Subscribing to your view: a per-player view doc lives at
13905
- // `<roomPath>/view/<myAddress>` (the policy declares
13906
- // `rooms/$roomId/view/$addr` ephemeral with `read: $addr == @user.address`).
13907
- // That path has an EVEN segment count, so it is an ordinary document path —
13908
- // plain `subscribe('<roomPath>/view/<myAddress>', { onData })` already works.
13909
- // `subscribeView()` below is thin sugar over that (path construction + address
13910
- // defaulting); it adds zero new transport.
13911
- //
13912
- // Status polling (GET /live/status?path=<sessionCollection>/<roomId>) is out of
13913
- // scope for this piece — see follow-up.
13981
+ // `<roomPath>/view/<myUserId>` (the policy declares
13982
+ // `rooms/$roomId/view/$userId` ephemeral with `read: $userId == @user.id`).
13983
+ // Wallet-address keyed view paths remain supported through opts.address for
13984
+ // older policies, but new live rooms should key views by @user.id.
13914
13985
  // ---------------------------------------------------------------------------
13915
13986
  class LiveIntentError extends Error {
13916
13987
  constructor(message, statusCode, details) {
@@ -13991,7 +14062,7 @@ async function intent(roomPath, intent, opts = {}) {
13991
14062
  res = await fetch(`${base}/live/intent`, {
13992
14063
  method: 'POST',
13993
14064
  headers,
13994
- body: JSON.stringify({ path: roomPath, intent }),
14065
+ body: JSON.stringify({ path: normalizedRoomPath, intent }),
13995
14066
  signal: controller.signal,
13996
14067
  });
13997
14068
  }
@@ -14019,43 +14090,95 @@ async function intent(roomPath, intent, opts = {}) {
14019
14090
  }
14020
14091
  return (body !== null && body !== void 0 ? body : { ok: true });
14021
14092
  }
14093
+ /**
14094
+ * Fetch the runtime status for a live room.
14095
+ *
14096
+ * const s = await bounded.live.status('rooms/abc');
14097
+ * console.log(s.running, s.stopReason, s.generation, s.etag);
14098
+ *
14099
+ * This is diagnostic/ops surface. It reports whether the room facet exists,
14100
+ * whether it is currently ticking, why it last stopped, which module etag is
14101
+ * loaded, and the current generation used after terminal restarts.
14102
+ */
14103
+ async function status(roomPath, opts = {}) {
14104
+ var _a, _b, _c, _d, _e;
14105
+ if (!roomPath || typeof roomPath !== 'string') {
14106
+ throw new LiveIntentError('A room path is required');
14107
+ }
14108
+ const normalizedRoomPath = roomPath.replace(/\/$/, '');
14109
+ const config = await getConfig();
14110
+ const base = realtimeHttpBase(config.wsApiUrl);
14111
+ const headers = Object.assign({ 'X-App-Id': config.appId, 'X-Public-App-Id': config.appId }, ((_a = opts.headers) !== null && _a !== void 0 ? _a : {}));
14112
+ const controller = new AbortController();
14113
+ const timeoutMs = (_b = opts.timeoutMs) !== null && _b !== void 0 ? _b : 15000;
14114
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
14115
+ let res;
14116
+ try {
14117
+ res = await fetch(`${base}/live/status?path=${encodeURIComponent(normalizedRoomPath)}`, {
14118
+ method: 'GET',
14119
+ headers,
14120
+ signal: controller.signal,
14121
+ });
14122
+ }
14123
+ catch (err) {
14124
+ clearTimeout(timer);
14125
+ if ((err === null || err === void 0 ? void 0 : err.name) === 'AbortError') {
14126
+ throw new LiveIntentError(`Live status for "${normalizedRoomPath}" timed out after ${timeoutMs}ms`);
14127
+ }
14128
+ 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)}`);
14129
+ }
14130
+ clearTimeout(timer);
14131
+ let body = null;
14132
+ const text = await res.text();
14133
+ if (text) {
14134
+ try {
14135
+ body = JSON.parse(text);
14136
+ }
14137
+ catch (_f) {
14138
+ body = { raw: text };
14139
+ }
14140
+ }
14141
+ if (!res.ok) {
14142
+ 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}`;
14143
+ throw new LiveIntentError(message, res.status, body);
14144
+ }
14145
+ return body;
14146
+ }
14022
14147
  /**
14023
14148
  * Subscribe to YOUR per-player view of a room. Thin sugar over:
14024
14149
  *
14025
- * subscribe('<roomPath>/view/<myAddress>', { onData, onError })
14150
+ * subscribe('<roomPath>/view/<myUserId>', { onData, onError })
14026
14151
  *
14027
- * The address defaults to the logged-in user's address (from the session
14028
- * token's claims); pass `opts.address` to override. Returns the unsubscribe
14152
+ * The view id defaults to the logged-in user's @user.id (from the session token
14153
+ * claims); pass `opts.userId` to override. `opts.address` is kept as a legacy
14154
+ * alias for older wallet-address keyed policies. Returns the unsubscribe
14029
14155
  * function (a Promise<() => Promise<void>>, same as `subscribe`).
14030
14156
  *
14031
14157
  * Note: this is a browser-first helper (the WS subscription manager is
14032
14158
  * browser-oriented). Server consumers should use `live.intent`.
14033
14159
  */
14034
14160
  async function subscribeView(roomPath, opts) {
14035
- var _a;
14161
+ var _a, _b, _c;
14036
14162
  if (!roomPath || typeof roomPath !== 'string') {
14037
14163
  throw new LiveIntentError('A room path is required');
14038
14164
  }
14039
14165
  if (!opts || typeof opts.onData !== 'function') {
14040
14166
  throw new LiveIntentError('subscribeView requires an onData callback');
14041
14167
  }
14042
- let address = opts.address;
14043
- if (!address) {
14168
+ let viewUserId = (_a = opts.userId) !== null && _a !== void 0 ? _a : opts.address;
14169
+ if (!viewUserId) {
14044
14170
  const config = await getConfig();
14045
14171
  const info = await getUserInfo(config.isServer);
14046
- // getUserInfo returns the RAW idToken payload — the wallet address lives in
14047
- // the `custom:walletAddress` claim, NOT a flat `address` field. Reading only
14048
- // `.address` meant auto-resolution NEVER worked, forcing every caller (browser
14049
- // AND server) to pass opts.address — the client having to hand the backend an
14050
- // identity it already authenticated. Resolve it from the actual claim so a
14051
- // logged-in caller never needs to pass its own address.
14052
- 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'];
14172
+ // getUserInfo returns the RAW idToken payload. The universal live view key
14173
+ // is @user.id (`custom:userId`); wallet-address keyed views are still
14174
+ // resolved as a compatibility fallback for older policies.
14175
+ 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;
14053
14176
  }
14054
- if (!address || typeof address !== 'string') {
14055
- throw new LiveIntentError('Could not resolve a player address for subscribeView; pass opts.address or log in first');
14177
+ if (!viewUserId || typeof viewUserId !== 'string') {
14178
+ throw new LiveIntentError('Could not resolve a player view id for subscribeView; pass opts.userId or log in first');
14056
14179
  }
14057
14180
  const normalizedRoomPath = roomPath.replace(/\/$/, '');
14058
- const viewPath = `${normalizedRoomPath}/view/${address}`;
14181
+ const viewPath = `${normalizedRoomPath}/view/${viewUserId}`;
14059
14182
  // This is a LIVE/room subscription by construction (the caller hands us the
14060
14183
  // room path), so we route its connection to the per-room DO where the live
14061
14184
  // view fan-out runs. App code passes NO routing — the room path is the helper's
@@ -14066,7 +14189,7 @@ async function subscribeView(roomPath, opts) {
14066
14189
  return subscribeV2(viewPath, { onData: opts.onData, onError: opts.onError }, normalizedRoomPath);
14067
14190
  }
14068
14191
  /** The `bounded.live` namespace surface. */
14069
- const live = { intent, subscribeView };
14192
+ const live = { intent, status, subscribeView };
14070
14193
 
14071
14194
  // ---------------------------------------------------------------------------
14072
14195
  // live-effects.ts -- AUTHOR-facing types + helpers for writing a Bounded live
@@ -17710,11 +17833,11 @@ var srcExports = requireSrc();
17710
17833
  var basex = /*@__PURE__*/getDefaultExportFromCjs$1(srcExports);
17711
17834
 
17712
17835
  var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
17713
- var base58 = basex(ALPHABET);
17836
+ var bs582 = basex(ALPHABET);
17714
17837
 
17715
17838
  var index = /*#__PURE__*/Object.freeze({
17716
17839
  __proto__: null,
17717
- default: base58
17840
+ default: bs582
17718
17841
  });
17719
17842
 
17720
17843
  // guest-keystore.ts — durable per-device keypair for anonymous ("guest") auth.
@@ -17787,7 +17910,7 @@ async function tryWebCrypto() {
17787
17910
  await idbPut(db, IDB_KEY, pair); // CryptoKey is structured-cloneable; bytes never exposed
17788
17911
  }
17789
17912
  const raw = new Uint8Array(await s.exportKey('raw', pair.publicKey)); // public is exportable
17790
- const address = base58.encode(raw);
17913
+ const address = bs582.encode(raw);
17791
17914
  return {
17792
17915
  address,
17793
17916
  nonExtractable: true,
@@ -17808,12 +17931,12 @@ function fallbackKey() {
17808
17931
  let secret;
17809
17932
  const saved = store.getItem(FALLBACK_STORE_KEY);
17810
17933
  if (saved) {
17811
- secret = base58.decode(saved);
17934
+ secret = bs582.decode(saved);
17812
17935
  }
17813
17936
  else {
17814
17937
  const kp = web3_js.Keypair.generate();
17815
17938
  secret = kp.secretKey; // 64 bytes
17816
- store.setItem(FALLBACK_STORE_KEY, base58.encode(secret));
17939
+ store.setItem(FALLBACK_STORE_KEY, bs582.encode(secret));
17817
17940
  }
17818
17941
  const kp = web3_js.Keypair.fromSecretKey(secret);
17819
17942
  const address = kp.publicKey.toBase58();
@@ -19098,17 +19221,17 @@ function setAuthProviderInstance(provider) {
19098
19221
  authProviderInstance = provider;
19099
19222
  }
19100
19223
 
19101
- var _a;
19224
+ var _a$1;
19102
19225
  // Whether we're in a server-side rendering context (no hooks allowed).
19103
19226
  // React Native has no `window` but DOES support hooks.
19104
19227
  // We detect Node SSR specifically via process.versions.node to avoid
19105
19228
  // false positives from Node 21+ which defines `navigator` globally.
19106
- const isSSR = typeof window === 'undefined'
19229
+ const isSSR$1 = typeof window === 'undefined'
19107
19230
  && typeof process !== 'undefined'
19108
- && !!((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node);
19231
+ && !!((_a$1 = process.versions) === null || _a$1 === void 0 ? void 0 : _a$1.node);
19109
19232
  function useAuth() {
19110
19233
  // Provide a fallback so server render doesn't break
19111
- if (isSSR) {
19234
+ if (isSSR$1) {
19112
19235
  return {
19113
19236
  login: async () => undefined,
19114
19237
  logout: async () => undefined,
@@ -19168,6 +19291,66 @@ function useAuth() {
19168
19291
  };
19169
19292
  }
19170
19293
 
19294
+ var _a;
19295
+ // SSR guard (mirrors useAuth): no hooks/subscriptions during Node server render.
19296
+ // React Native has no `window` but DOES support hooks, so detect Node SSR
19297
+ // specifically via process.versions.node.
19298
+ const isSSR = typeof window === 'undefined'
19299
+ && typeof process !== 'undefined'
19300
+ && !!((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node);
19301
+ function useQuery(path, options) {
19302
+ if (isSSR) {
19303
+ return { data: undefined, loading: true, error: null };
19304
+ }
19305
+ const [data, setData] = React__namespace.useState(undefined);
19306
+ const [loading, setLoading] = React__namespace.useState(true);
19307
+ const [error, setError] = React__namespace.useState(null);
19308
+ // Re-subscribe only when the query actually changes (not on every render).
19309
+ const optionsKey = options ? JSON.stringify(options) : '';
19310
+ React__namespace.useEffect(() => {
19311
+ if (!path) {
19312
+ setData(undefined);
19313
+ setLoading(false);
19314
+ setError(null);
19315
+ return;
19316
+ }
19317
+ let active = true;
19318
+ let unsubscribe;
19319
+ setLoading(true);
19320
+ setError(null);
19321
+ subscribe(path, Object.assign(Object.assign({}, options), { onData: (d) => {
19322
+ if (!active)
19323
+ return;
19324
+ setData(d);
19325
+ setLoading(false);
19326
+ }, onError: (e) => {
19327
+ if (!active)
19328
+ return;
19329
+ setError(e instanceof Error ? e : new Error(String(e)));
19330
+ setLoading(false);
19331
+ } }))
19332
+ .then((unsub) => {
19333
+ if (active)
19334
+ unsubscribe = unsub;
19335
+ else
19336
+ void unsub(); // unmounted before subscribe resolved
19337
+ })
19338
+ .catch((e) => {
19339
+ if (!active)
19340
+ return;
19341
+ setError(e instanceof Error ? e : new Error(String(e)));
19342
+ setLoading(false);
19343
+ });
19344
+ return () => {
19345
+ active = false;
19346
+ void (unsubscribe === null || unsubscribe === void 0 ? void 0 : unsubscribe());
19347
+ };
19348
+ // optionsKey captures the option object's contents; path is the other input.
19349
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19350
+ }, [path, optionsKey]);
19351
+ return { data, loading, error };
19352
+ }
19353
+
19171
19354
  async function deserializeTransaction(tx) {
19172
19355
  const buf = Buffer.isBuffer(tx) ? tx : Buffer.from(tx, 'base64');
19173
19356
  if ((buf[0] & 0x80) !== 0) {
@@ -19301,7 +19484,7 @@ async function loadDependencies() {
19301
19484
  const [reactModule, reactDomModule, phantomModule] = await Promise.all([
19302
19485
  import('react'),
19303
19486
  import('react-dom/client'),
19304
- Promise.resolve().then(function () { return require('./index-BgAygrhE.js'); })
19487
+ Promise.resolve().then(function () { return require('./index-FYyc3l_y.js'); })
19305
19488
  ]);
19306
19489
  // Extract default export from ESM module namespace
19307
19490
  // Dynamic import() returns { default: Module, ...exports }, not the module directly
@@ -21202,7 +21385,7 @@ async function registerMobileWalletAdapter(config) {
21202
21385
  if (typeof window === 'undefined')
21203
21386
  return;
21204
21387
  try {
21205
- const walletStandardMobile = await Promise.resolve().then(function () { return require('./index.browser-D8u31irV.js'); });
21388
+ const walletStandardMobile = await Promise.resolve().then(function () { return require('./index.browser-D5evrolK.js'); });
21206
21389
  const registerMwa = walletStandardMobile.registerMwa || ((_a = walletStandardMobile.default) === null || _a === void 0 ? void 0 : _a.registerMwa);
21207
21390
  if (!registerMwa) {
21208
21391
  console.warn('[SolanaMobileWallet] registerMwa not found in @solana-mobile/wallet-standard-mobile');
@@ -21341,7 +21524,7 @@ class SolanaMobileWalletProvider {
21341
21524
  async ensureWallet() {
21342
21525
  if (this.wallet)
21343
21526
  return this.wallet;
21344
- const mod = await Promise.resolve().then(function () { return require('./index.browser-D8u31irV.js'); });
21527
+ const mod = await Promise.resolve().then(function () { return require('./index.browser-D5evrolK.js'); });
21345
21528
  const chain = mapChainToWalletStandard(this.cluster);
21346
21529
  this.wallet = new mod.LocalSolanaMobileWalletAdapterWallet({
21347
21530
  appIdentity: this.appIdentity,
@@ -21959,7 +22142,7 @@ class SolanaMobileWalletProvider {
21959
22142
  options: { commitment: 'confirmed' },
21960
22143
  }));
21961
22144
  const { signature: sigBytes } = sendResult;
21962
- const signature = base58.encode(sigBytes);
22145
+ const signature = bs582.encode(sigBytes);
21963
22146
  await confirmAndCheckTransaction(connection, signature);
21964
22147
  return signature;
21965
22148
  }
@@ -22107,7 +22290,7 @@ class SolanaMobileWalletProvider {
22107
22290
  throw new Error('MWA returned no signature');
22108
22291
  }
22109
22292
  const { signature: sigBytes } = sendResult;
22110
- const signature = base58.encode(sigBytes);
22293
+ const signature = bs582.encode(sigBytes);
22111
22294
  const txInfo = await confirmAndCheckTransaction(connection, signature);
22112
22295
  return {
22113
22296
  transactionSignature: signature,
@@ -22944,7 +23127,7 @@ class PrivyWalletProvider {
22944
23127
  // Handle case where signature might be bytes instead of string
22945
23128
  const rawSig = result.signature;
22946
23129
  if (rawSig instanceof Uint8Array || Array.isArray(rawSig)) {
22947
- signature = base58.encode(rawSig instanceof Uint8Array ? rawSig : new Uint8Array(rawSig));
23130
+ signature = bs582.encode(rawSig instanceof Uint8Array ? rawSig : new Uint8Array(rawSig));
22948
23131
  }
22949
23132
  else {
22950
23133
  signature = rawSig;
@@ -23306,7 +23489,7 @@ class PrivyExpoProvider {
23306
23489
  const wallet = await this.getWalletOrThrow();
23307
23490
  const messageBytes = getPlatform().textEncode(message);
23308
23491
  const result = await wallet.signMessage(messageBytes);
23309
- return base58.encode(result.signature);
23492
+ return bs582.encode(result.signature);
23310
23493
  }
23311
23494
  async signTransaction(transaction) {
23312
23495
  await this.ensureReady();
@@ -23490,7 +23673,7 @@ exports.ServerSessionManager = ServerSessionManager;
23490
23673
  exports.SolanaMobileWalletProvider = SolanaMobileWalletProvider;
23491
23674
  exports.WebSessionManager = WebSessionManager;
23492
23675
  exports.aggregate = aggregate;
23493
- exports.base58 = base58;
23676
+ exports.bs582 = bs582;
23494
23677
  exports.bufferExports = bufferExports;
23495
23678
  exports.buildSetDocumentsTransaction = buildSetDocumentsTransaction;
23496
23679
  exports.clearCache = clearCache;
@@ -23535,6 +23718,7 @@ exports.loginWithPopup = loginWithPopup;
23535
23718
  exports.loginWithPrivy = loginWithPrivy;
23536
23719
  exports.loginWithRedirect = loginWithRedirect;
23537
23720
  exports.logout = logout;
23721
+ exports.now = now;
23538
23722
  exports.onAuthLoadingChanged = onAuthLoadingChanged;
23539
23723
  exports.onAuthStateChanged = onAuthStateChanged;
23540
23724
  exports.queryAggregate = queryAggregate;
@@ -23559,9 +23743,13 @@ exports.signInAnonymously = signInAnonymously;
23559
23743
  exports.signMessage = signMessage;
23560
23744
  exports.signSessionCreateMessage = signSessionCreateMessage;
23561
23745
  exports.signTransaction = signTransaction;
23746
+ exports.status = status;
23562
23747
  exports.subscribe = subscribe;
23563
23748
  exports.subscribeView = subscribeView;
23749
+ exports.toMillis = toMillis;
23750
+ exports.toSeconds = toSeconds;
23564
23751
  exports.useAuth = useAuth;
23752
+ exports.useQuery = useQuery;
23565
23753
  exports.verifyEmailOtp = verifyEmailOtp;
23566
23754
  exports.withEffects = withEffects;
23567
23755
  exports.wsDelete = wsDelete;
@@ -23569,4 +23757,4 @@ exports.wsGet = wsGet;
23569
23757
  exports.wsGetMany = wsGetMany;
23570
23758
  exports.wsQuery = wsQuery;
23571
23759
  exports.wsSet = wsSet;
23572
- //# sourceMappingURL=index-BL-0ZKBl.js.map
23760
+ //# sourceMappingURL=index-BBLnBZjY.js.map