@bounded-sh/client 0.0.3 → 0.0.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 (46) hide show
  1. package/dist/hooks/useQuery.d.ts +58 -0
  2. package/dist/{index-DyfiK3_X.esm.js → index-30RA_Bdf.esm.js} +268 -18
  3. package/dist/index-30RA_Bdf.esm.js.map +1 -0
  4. package/dist/{index-DJg-Dduo.esm.js → index-B9DtkVXb.esm.js} +2 -2
  5. package/dist/{index-DJg-Dduo.esm.js.map → index-B9DtkVXb.esm.js.map} +1 -1
  6. package/dist/{index-CYVVTWs4.js → index-CdqFc68L.js} +2 -2
  7. package/dist/{index-CYVVTWs4.js.map → index-CdqFc68L.js.map} +1 -1
  8. package/dist/{index-C2JpxGAC.js → index-CplhW55m.js} +2 -2
  9. package/dist/{index-C2JpxGAC.js.map → index-CplhW55m.js.map} +1 -1
  10. package/dist/{index-C2yvle9S.esm.js → index-DXdFMfDw.esm.js} +2 -2
  11. package/dist/{index-C2yvle9S.esm.js.map → index-DXdFMfDw.esm.js.map} +1 -1
  12. package/dist/{index-2UpSvA7V.js → index-ZYhdEVCA.js} +272 -17
  13. package/dist/index-ZYhdEVCA.js.map +1 -0
  14. package/dist/{index.browser-pymH6o1X.esm.js → index.browser-Cictefil.esm.js} +2 -2
  15. package/dist/{index.browser-pymH6o1X.esm.js.map → index.browser-Cictefil.esm.js.map} +1 -1
  16. package/dist/{index.browser-BTJZmhY1.js → index.browser-sADlt75X.js} +2 -2
  17. package/dist/{index.browser-BTJZmhY1.js.map → index.browser-sADlt75X.js.map} +1 -1
  18. package/dist/index.d.ts +3 -1
  19. package/dist/index.esm.js +1 -1
  20. package/dist/index.js +6 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/{index.native-BTjBgNiE.esm.js → index.native-C8GJTcIy.esm.js} +204 -14
  23. package/dist/index.native-C8GJTcIy.esm.js.map +1 -0
  24. package/dist/{index.native-BvsmNFXn.js → index.native-DpYQ8GUh.js} +207 -13
  25. package/dist/index.native-DpYQ8GUh.js.map +1 -0
  26. package/dist/index.native.d.ts +1 -1
  27. package/dist/index.native.esm.js +1 -1
  28. package/dist/index.native.js +5 -1
  29. package/dist/index.native.js.map +1 -1
  30. package/dist/{phantom-wallet-provider-BXMvoOrI.js → phantom-wallet-provider-B8gezRxB.js} +3 -3
  31. package/dist/{phantom-wallet-provider-BXMvoOrI.js.map → phantom-wallet-provider-B8gezRxB.js.map} +1 -1
  32. package/dist/{phantom-wallet-provider-CTossIFB.esm.js → phantom-wallet-provider-FOSnYV4t.esm.js} +3 -3
  33. package/dist/{phantom-wallet-provider-CTossIFB.esm.js.map → phantom-wallet-provider-FOSnYV4t.esm.js.map} +1 -1
  34. package/dist/{privy-wallet-provider-1qE_f-DF.esm.js → privy-wallet-provider-BPOjNW9O.esm.js} +3 -3
  35. package/dist/{privy-wallet-provider-1qE_f-DF.esm.js.map → privy-wallet-provider-BPOjNW9O.esm.js.map} +1 -1
  36. package/dist/{privy-wallet-provider-D64DJ3u4.js → privy-wallet-provider-DfR-7xpE.js} +3 -3
  37. package/dist/{privy-wallet-provider-D64DJ3u4.js.map → privy-wallet-provider-DfR-7xpE.js.map} +1 -1
  38. package/dist/{solana-mobile-wallet-provider-C1wQ1DRK.js → solana-mobile-wallet-provider-CBAeRxGQ.js} +2 -2
  39. package/dist/{solana-mobile-wallet-provider-C1wQ1DRK.js.map → solana-mobile-wallet-provider-CBAeRxGQ.js.map} +1 -1
  40. package/dist/{solana-mobile-wallet-provider-9M8U6AA7.esm.js → solana-mobile-wallet-provider-CoS-38SL.esm.js} +2 -2
  41. package/dist/{solana-mobile-wallet-provider-9M8U6AA7.esm.js.map → solana-mobile-wallet-provider-CoS-38SL.esm.js.map} +1 -1
  42. package/package.json +2 -2
  43. package/dist/index-2UpSvA7V.js.map +0 -1
  44. package/dist/index-DyfiK3_X.esm.js.map +0 -1
  45. package/dist/index.native-BTjBgNiE.esm.js.map +0 -1
  46. package/dist/index.native-BvsmNFXn.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}/>)}</>; // p.id = leaf doc key; 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>;
@@ -10632,6 +10632,87 @@ const pendingRequests = {};
10632
10632
  const GET_CACHE_TTL = 500; // Adjust this value as needed (in milliseconds)
10633
10633
  // Last time we cleaned up the cache
10634
10634
  let lastCacheCleanup = Date.now();
10635
+ /**
10636
+ * Return the leaf document key (last path segment) for a document path.
10637
+ *
10638
+ * Bounded rows carry `_id` (and `pathId`) set to the FULL document path
10639
+ * (e.g. `"rooms/r1/prompts/8rd49se3sg"`). Apps that build a child path from a
10640
+ * row naturally want the bare doc key, not the whole path — using the full path
10641
+ * doubles it (`rooms/r1/prompts/rooms/r1/prompts/8rd.../votes/...`) → 403/404.
10642
+ * `docId` extracts that leaf key. Tolerates leading slashes and a trailing `*`.
10643
+ *
10644
+ * @example docId("rooms/r1/prompts/8rd49se3sg") // "8rd49se3sg"
10645
+ */
10646
+ function docId(path) {
10647
+ if (typeof path !== 'string')
10648
+ return '';
10649
+ let p = path.startsWith('/') ? path.slice(1) : path;
10650
+ if (p.endsWith('*') && p.length > 1)
10651
+ p = p.slice(0, -1);
10652
+ if (p.endsWith('/'))
10653
+ p = p.slice(0, -1);
10654
+ const segments = p.split('/').filter(Boolean);
10655
+ return segments.length ? segments[segments.length - 1] : '';
10656
+ }
10657
+ /**
10658
+ * Additively attach a convenience bare `id` (the leaf doc key) to a returned row.
10659
+ *
10660
+ * Rows already carry `_id`/`pathId` = the full document path; this leaves those
10661
+ * untouched and adds `id` = the last path segment so `row.id` is the doc key apps
10662
+ * expect. No-ops for non-objects, arrays, and rows that already define `id`
10663
+ * (never clobber a user field named `id`). Source for the leaf is `_id` (falling
10664
+ * back to `pathId`/`relativePath`/`absolutePath`).
10665
+ */
10666
+ function withBareId(row) {
10667
+ var _a, _b, _c;
10668
+ if (!row || typeof row !== 'object' || Array.isArray(row))
10669
+ return row;
10670
+ const r = row;
10671
+ if ('id' in r)
10672
+ return row; // don't clobber an explicit user field
10673
+ const source = (_c = (_b = (_a = r._id) !== null && _a !== void 0 ? _a : r.pathId) !== null && _b !== void 0 ? _b : r.relativePath) !== null && _c !== void 0 ? _c : r.absolutePath;
10674
+ if (typeof source !== 'string' || source.length === 0)
10675
+ return row;
10676
+ const leaf = docId(source);
10677
+ if (!leaf)
10678
+ return row;
10679
+ return Object.assign(Object.assign({}, r), { id: leaf });
10680
+ }
10681
+ /**
10682
+ * Normalize a raw read response from the worker into the SDK's stable shape and
10683
+ * attach the bare `id` to every returned row (Bug 1 + Bug 2).
10684
+ *
10685
+ * - Single-document path: returns EXACTLY ONE shape — the resolved document, or
10686
+ * `null` if missing (Firebase/Mongo convention). Unwraps the ambiguous
10687
+ * `{ data, status }` envelope the worker sometimes emits for a single doc so a
10688
+ * single-doc `get` never sometimes-returns the doc and sometimes the envelope.
10689
+ * - Collection path: preserves the `{ data, nextCursor, ... }` envelope and maps
10690
+ * the bare `id` onto each row in `data`.
10691
+ */
10692
+ function normalizeReadResult(responseData, pathIsDocument) {
10693
+ if (pathIsDocument) {
10694
+ let doc = responseData;
10695
+ // Unwrap the single-doc envelope `{ data, status }` (Bug 2). A real document
10696
+ // never has the exact shape `{ data, status }` with nothing else meaningful,
10697
+ // so detect the envelope by `data` being present alongside a numeric `status`.
10698
+ if (doc && typeof doc === 'object' && !Array.isArray(doc) &&
10699
+ 'data' in doc && 'status' in doc && typeof doc.status === 'number') {
10700
+ doc = doc.data;
10701
+ }
10702
+ if (doc === undefined || doc === null)
10703
+ return null;
10704
+ return withBareId(doc);
10705
+ }
10706
+ // Collection read. The worker body is `{ data: rows[], nextCursor?, status? }`.
10707
+ if (responseData && typeof responseData === 'object' && !Array.isArray(responseData) && Array.isArray(responseData.data)) {
10708
+ return Object.assign(Object.assign({}, responseData), { data: responseData.data.map((row) => withBareId(row)) });
10709
+ }
10710
+ // Some paths return a bare array of rows — map id onto each.
10711
+ if (Array.isArray(responseData)) {
10712
+ return responseData.map((row) => withBareId(row));
10713
+ }
10714
+ return responseData;
10715
+ }
10635
10716
  function hashForKey$1(value) {
10636
10717
  let h = 5381;
10637
10718
  for (let i = 0; i < value.length; i++) {
@@ -11056,7 +11137,7 @@ async function get(path, opts = {}) {
11056
11137
  if (hasActiveConnection()) {
11057
11138
  if (pathIsDocument) {
11058
11139
  const wsResult = await wsGet(normalizedPath);
11059
- const responseData = wsResult;
11140
+ const responseData = normalizeReadResult(wsResult, true);
11060
11141
  if (!opts.bypassCache) {
11061
11142
  getCache[cacheKey] = { data: responseData, expiresAt: now + GET_CACHE_TTL };
11062
11143
  }
@@ -11068,7 +11149,7 @@ async function get(path, opts = {}) {
11068
11149
  sort: undefined,
11069
11150
  includeSubPaths: opts.includeSubPaths,
11070
11151
  });
11071
- const responseData = wsResult;
11152
+ const responseData = normalizeReadResult(wsResult, false);
11072
11153
  if (!opts.bypassCache) {
11073
11154
  getCache[cacheKey] = { data: responseData, expiresAt: now + GET_CACHE_TTL };
11074
11155
  }
@@ -11099,7 +11180,11 @@ async function get(path, opts = {}) {
11099
11180
  const apiPath = `items?path=${path}${promptQueryParam}${filterParam}${sortParam}${includeSubPathsParam}${shapeParam}${limitParam}${cursorParam}`;
11100
11181
  response = await makeApiRequest('GET', apiPath, null, opts._overrides);
11101
11182
  }
11102
- const responseData = response.data;
11183
+ // Normalize the worker's raw body into the SDK's stable shape:
11184
+ // - single-doc path → the resolved document or null (Bug 2), and
11185
+ // - collection path → `{ data, nextCursor }` preserved,
11186
+ // with the bare `id` (leaf doc key) attached to every returned row (Bug 1).
11187
+ const responseData = normalizeReadResult(response.data, pathIsDocument);
11103
11188
  // Cache the response (unless bypassing cache)
11104
11189
  if (!opts.bypassCache) {
11105
11190
  getCache[cacheKey] = {
@@ -11197,11 +11282,16 @@ async function getMany(paths, opts = {}) {
11197
11282
  const normalizedPath = uncachedPaths[i];
11198
11283
  const serverResult = serverResultsMap.get(normalizedPath);
11199
11284
  if (serverResult) {
11200
- results[originalIndex] = serverResult;
11201
- if (!serverResult.error && !opts.bypassCache) {
11285
+ // getMany batches single-doc paths — attach the bare `id` (leaf doc
11286
+ // key) to each returned doc, additive (Bug 1), matching get().
11287
+ const normalizedResult = serverResult.error
11288
+ ? serverResult
11289
+ : Object.assign(Object.assign({}, serverResult), { data: withBareId(serverResult.data) });
11290
+ results[originalIndex] = normalizedResult;
11291
+ if (!normalizedResult.error && !opts.bypassCache) {
11202
11292
  const cacheKey = `${principalKey}|${normalizedPath}:`;
11203
11293
  getCache[cacheKey] = {
11204
- data: serverResult.data,
11294
+ data: normalizedResult.data,
11205
11295
  expiresAt: now + GET_CACHE_TTL
11206
11296
  };
11207
11297
  }
@@ -11746,6 +11836,7 @@ var operations = /*#__PURE__*/Object.freeze({
11746
11836
  aggregate: aggregate,
11747
11837
  clearReadCacheForAuthChange: clearReadCacheForAuthChange,
11748
11838
  count: count,
11839
+ docId: docId,
11749
11840
  get: get,
11750
11841
  getFiles: getFiles,
11751
11842
  getMany: getMany,
@@ -12333,14 +12424,46 @@ function handleServerMessage(connection, message) {
12333
12424
  }
12334
12425
  }
12335
12426
  }
12427
+ /**
12428
+ * Additively attach the bare `id` (leaf doc key) to a subscription row (Bug 1).
12429
+ * Rows carry `_id`/`pathId` = the full document path; this leaves those as-is and
12430
+ * adds `id` = the last path segment so `row.id` is the doc key apps expect. No-ops
12431
+ * for non-objects and rows that already define `id`.
12432
+ */
12433
+ function withSubscriptionId(row) {
12434
+ var _a, _b, _c;
12435
+ if (!row || typeof row !== 'object' || Array.isArray(row))
12436
+ return row;
12437
+ if ('id' in row)
12438
+ return row;
12439
+ const source = (_c = (_b = (_a = row._id) !== null && _a !== void 0 ? _a : row.pathId) !== null && _b !== void 0 ? _b : row.relativePath) !== null && _c !== void 0 ? _c : row.absolutePath;
12440
+ if (typeof source !== 'string' || source.length === 0)
12441
+ return row;
12442
+ const leaf = docId(source);
12443
+ if (!leaf)
12444
+ return row;
12445
+ return Object.assign(Object.assign({}, row), { id: leaf });
12446
+ }
12447
+ /**
12448
+ * The `onData` payload follows the path: a collection delivers a bare array of
12449
+ * rows, a single-doc path delivers the document (or null). Attach the bare `id`
12450
+ * to each returned row in either case, additive (Bug 1).
12451
+ */
12452
+ function addIdsToSubscriptionData(data) {
12453
+ if (Array.isArray(data))
12454
+ return data.map(withSubscriptionId);
12455
+ return withSubscriptionId(data);
12456
+ }
12336
12457
  function notifyCallbacks(subscription, data) {
12337
12458
  var _a;
12459
+ // Attach the bare `id` (leaf doc key) to every delivered row (Bug 1).
12460
+ const decorated = addIdsToSubscriptionData(data);
12338
12461
  // Snapshot the callbacks array so that unsubscriptions during
12339
12462
  // notification don't cause callbacks to be skipped.
12340
12463
  const callbacks = subscription.callbacks.slice();
12341
12464
  for (const callback of callbacks) {
12342
12465
  try {
12343
- (_a = callback.onData) === null || _a === void 0 ? void 0 : _a.call(callback, data);
12466
+ (_a = callback.onData) === null || _a === void 0 ? void 0 : _a.call(callback, decorated);
12344
12467
  }
12345
12468
  catch (error) {
12346
12469
  console.error('[WS v2] Error in subscription callback:', error);
@@ -12431,7 +12554,7 @@ async function subscribeV2(path, subscriptionOptions, roomRoutePath) {
12431
12554
  if (cachedEntry && Date.now() - cachedEntry.timestamp < CACHE_TTL && subscriptionOptions.onData) {
12432
12555
  setTimeout(() => {
12433
12556
  var _a;
12434
- (_a = subscriptionOptions.onData) === null || _a === void 0 ? void 0 : _a.call(subscriptionOptions, cachedEntry.data);
12557
+ (_a = subscriptionOptions.onData) === null || _a === void 0 ? void 0 : _a.call(subscriptionOptions, addIdsToSubscriptionData(cachedEntry.data));
12435
12558
  }, 0);
12436
12559
  }
12437
12560
  // Get or create connection for this routing target (room-scoped when a
@@ -12461,7 +12584,7 @@ async function subscribeV2(path, subscriptionOptions, roomRoutePath) {
12461
12584
  if (existingSubscription.lastData !== undefined && subscriptionOptions.onData) {
12462
12585
  setTimeout(() => {
12463
12586
  var _a;
12464
- (_a = subscriptionOptions.onData) === null || _a === void 0 ? void 0 : _a.call(subscriptionOptions, existingSubscription.lastData);
12587
+ (_a = subscriptionOptions.onData) === null || _a === void 0 ? void 0 : _a.call(subscriptionOptions, addIdsToSubscriptionData(existingSubscription.lastData));
12465
12588
  }, 0);
12466
12589
  }
12467
12590
  return async () => {
@@ -12969,6 +13092,73 @@ function serverTimestamp() {
12969
13092
  return { operation: 'time', value: 'now' };
12970
13093
  }
12971
13094
 
13095
+ /**
13096
+ * Time units in Bounded — read this once and never get a 1000× timestamp bug.
13097
+ *
13098
+ * **Bounded's policy/proof layer is Unix SECONDS.** `@time.now` in a rule,
13099
+ * `rollingSum` `windowSeconds`, `scheduledAt`, and any timestamp *field your
13100
+ * policy compares against `@time.now`* are all **seconds**. (This is also what
13101
+ * the chain uses — Solana's on-chain clock is `unix_timestamp` in seconds — so a
13102
+ * single seconds unit works for both onchain and offchain rules.)
13103
+ *
13104
+ * **JavaScript is MILLISECONDS.** `Date.now()`, `new Date().getTime()`, and the
13105
+ * auto-stamped system fields `_createdAt` / `_updatedAt` are all **ms**.
13106
+ *
13107
+ * Comparing across the two (e.g. `@time.now - myField` where `myField` was set
13108
+ * from `Date.now()`) is 1000× off, so a freshness / TTL check silently treats
13109
+ * every row as ancient (or far-future) and drops it — which reads as "realtime
13110
+ * isn't delivering" when the data is actually fine.
13111
+ *
13112
+ * **The rules:**
13113
+ * - To **write** a timestamp a policy will read, prefer **`serverTimestamp()`**
13114
+ * (from this package) — the *server* stamps it in seconds, so it matches
13115
+ * `@time.now` AND can't be forged by the client (use it for TTLs, rate windows,
13116
+ * anti-cheat). Use `now()` only when you need the value in client code before
13117
+ * the write.
13118
+ * - To **compare** timestamps in client/render code, use `now()` (seconds), not
13119
+ * `Date.now()` (ms), and `toSeconds()` to convert the ms system fields
13120
+ * (`_createdAt`/`_updatedAt`) or any `Date.now()` value first.
13121
+ */
13122
+ /**
13123
+ * Current time as a **Unix timestamp in seconds** — the unit Bounded policy rules
13124
+ * use (`@time.now`). Use this (not `Date.now()`) when you need a timestamp in
13125
+ * client code (e.g. a freshness check). For a value you *store* and a policy
13126
+ * reads, prefer the server-authoritative {@link serverTimestamp} instead.
13127
+ *
13128
+ * ```ts
13129
+ * // stale if >15s old — seconds vs seconds ✓
13130
+ * if (now() - doc.lastSeenSeconds > 15) renderStale();
13131
+ * ```
13132
+ */
13133
+ function now() {
13134
+ return Math.floor(Date.now() / 1000);
13135
+ }
13136
+ /**
13137
+ * Convert a JavaScript millisecond timestamp to Bounded's **seconds**. Accepts a
13138
+ * `Date`, or an ms number such as `Date.now()` or a doc's `_createdAt` /
13139
+ * `_updatedAt` system field.
13140
+ *
13141
+ * ```ts
13142
+ * // doc is >15s old (compare the ms system field in seconds):
13143
+ * if (now() - toSeconds(doc._updatedAt) > 15) renderStale();
13144
+ * ```
13145
+ */
13146
+ function toSeconds(msOrDate) {
13147
+ const ms = msOrDate instanceof Date ? msOrDate.getTime() : msOrDate;
13148
+ return Math.floor(ms / 1000);
13149
+ }
13150
+ /**
13151
+ * Convert a Bounded **seconds** timestamp back to JavaScript **milliseconds** —
13152
+ * e.g. to build a `Date` or do client-side date math/formatting.
13153
+ *
13154
+ * ```ts
13155
+ * new Date(toMillis(doc.createdAtSeconds)).toLocaleString();
13156
+ * ```
13157
+ */
13158
+ function toMillis(seconds) {
13159
+ return seconds * 1000;
13160
+ }
13161
+
12972
13162
  // ---------------------------------------------------------------------------
12973
13163
  // realtime-store.ts — Client-side state manager for realtime apps.
12974
13164
  //
@@ -21537,17 +21727,17 @@ function setAuthProviderInstance(provider) {
21537
21727
  authProviderInstance = provider;
21538
21728
  }
21539
21729
 
21540
- var _a;
21730
+ var _a$1;
21541
21731
  // Whether we're in a server-side rendering context (no hooks allowed).
21542
21732
  // React Native has no `window` but DOES support hooks.
21543
21733
  // We detect Node SSR specifically via process.versions.node to avoid
21544
21734
  // false positives from Node 21+ which defines `navigator` globally.
21545
- const isSSR = typeof window === 'undefined'
21735
+ const isSSR$1 = typeof window === 'undefined'
21546
21736
  && typeof process !== 'undefined'
21547
- && !!((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node);
21737
+ && !!((_a$1 = process.versions) === null || _a$1 === void 0 ? void 0 : _a$1.node);
21548
21738
  function useAuth() {
21549
21739
  // Provide a fallback so server render doesn't break
21550
- if (isSSR) {
21740
+ if (isSSR$1) {
21551
21741
  return {
21552
21742
  login: async () => undefined,
21553
21743
  logout: async () => undefined,
@@ -21607,6 +21797,66 @@ function useAuth() {
21607
21797
  };
21608
21798
  }
21609
21799
 
21800
+ var _a;
21801
+ // SSR guard (mirrors useAuth): no hooks/subscriptions during Node server render.
21802
+ // React Native has no `window` but DOES support hooks, so detect Node SSR
21803
+ // specifically via process.versions.node.
21804
+ const isSSR = typeof window === 'undefined'
21805
+ && typeof process !== 'undefined'
21806
+ && !!((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node);
21807
+ function useQuery(path, options) {
21808
+ if (isSSR) {
21809
+ return { data: undefined, loading: true, error: null };
21810
+ }
21811
+ const [data, setData] = React$1.useState(undefined);
21812
+ const [loading, setLoading] = React$1.useState(true);
21813
+ const [error, setError] = React$1.useState(null);
21814
+ // Re-subscribe only when the query actually changes (not on every render).
21815
+ const optionsKey = options ? JSON.stringify(options) : '';
21816
+ React$1.useEffect(() => {
21817
+ if (!path) {
21818
+ setData(undefined);
21819
+ setLoading(false);
21820
+ setError(null);
21821
+ return;
21822
+ }
21823
+ let active = true;
21824
+ let unsubscribe;
21825
+ setLoading(true);
21826
+ setError(null);
21827
+ subscribe(path, Object.assign(Object.assign({}, options), { onData: (d) => {
21828
+ if (!active)
21829
+ return;
21830
+ setData(d);
21831
+ setLoading(false);
21832
+ }, onError: (e) => {
21833
+ if (!active)
21834
+ return;
21835
+ setError(e instanceof Error ? e : new Error(String(e)));
21836
+ setLoading(false);
21837
+ } }))
21838
+ .then((unsub) => {
21839
+ if (active)
21840
+ unsubscribe = unsub;
21841
+ else
21842
+ void unsub(); // unmounted before subscribe resolved
21843
+ })
21844
+ .catch((e) => {
21845
+ if (!active)
21846
+ return;
21847
+ setError(e instanceof Error ? e : new Error(String(e)));
21848
+ setLoading(false);
21849
+ });
21850
+ return () => {
21851
+ active = false;
21852
+ void (unsubscribe === null || unsubscribe === void 0 ? void 0 : unsubscribe());
21853
+ };
21854
+ // optionsKey captures the option object's contents; path is the other input.
21855
+ // eslint-disable-next-line react-hooks/exhaustive-deps
21856
+ }, [path, optionsKey]);
21857
+ return { data, loading, error };
21858
+ }
21859
+
21610
21860
  async function deserializeTransaction(tx) {
21611
21861
  const buf = Buffer.isBuffer(tx) ? tx : Buffer.from(tx, 'base64');
21612
21862
  if ((buf[0] & 0x80) !== 0) {
@@ -21740,7 +21990,7 @@ async function loadDependencies() {
21740
21990
  const [reactModule, reactDomModule, phantomModule] = await Promise.all([
21741
21991
  import('react'),
21742
21992
  import('react-dom/client'),
21743
- import('./index-DJg-Dduo.esm.js')
21993
+ import('./index-B9DtkVXb.esm.js')
21744
21994
  ]);
21745
21995
  // Extract default export from ESM module namespace
21746
21996
  // Dynamic import() returns { default: Module, ...exports }, not the module directly
@@ -23641,7 +23891,7 @@ async function registerMobileWalletAdapter(config) {
23641
23891
  if (typeof window === 'undefined')
23642
23892
  return;
23643
23893
  try {
23644
- const walletStandardMobile = await import('./index.browser-pymH6o1X.esm.js');
23894
+ const walletStandardMobile = await import('./index.browser-Cictefil.esm.js');
23645
23895
  const registerMwa = walletStandardMobile.registerMwa || ((_a = walletStandardMobile.default) === null || _a === void 0 ? void 0 : _a.registerMwa);
23646
23896
  if (!registerMwa) {
23647
23897
  console.warn('[SolanaMobileWallet] registerMwa not found in @solana-mobile/wallet-standard-mobile');
@@ -23780,7 +24030,7 @@ class SolanaMobileWalletProvider {
23780
24030
  async ensureWallet() {
23781
24031
  if (this.wallet)
23782
24032
  return this.wallet;
23783
- const mod = await import('./index.browser-pymH6o1X.esm.js');
24033
+ const mod = await import('./index.browser-Cictefil.esm.js');
23784
24034
  const chain = mapChainToWalletStandard(this.cluster);
23785
24035
  this.wallet = new mod.LocalSolanaMobileWalletAdapterWallet({
23786
24036
  appIdentity: this.appIdentity,
@@ -25913,5 +26163,5 @@ class PrivyExpoProvider {
25913
26163
  }
25914
26164
  }
25915
26165
 
25916
- 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 _, bs582 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, withEffects as aA, wsDelete as aB, wsGet as aC, wsGetMany as aD, wsQuery as aE, wsSet as aF, 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, status as as, reconnectWithNewAuth as at, refreshSession as au, resetRealtimeStore as av, revokeSession as aw, serverTimestamp as ax, signSessionCreateMessage as ay, subscribeView 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 };
25917
- //# sourceMappingURL=index-DyfiK3_X.esm.js.map
26166
+ export { registerMobileWalletAdapter as $, setMany as A, setFile as B, getFiles as C, search as D, queryAggregate as E, runQuery as F, runQueryMany as G, runExpression as H, runExpressionMany as I, signMessage as J, signTransaction as K, signAndSubmitTransaction as L, count as M, aggregate as N, subscribe as O, useAuth as P, useQuery as Q, deserializeTransaction as R, getIdToken as S, setPlatform as T, getPlatform as U, PhantomWalletProvider as V, MockAuthProvider as W, DEFAULT_TEST_ADDRESS as X, OffchainAuthProvider as Y, SolanaMobileWalletProvider as Z, isMobileWalletAvailable as _, bs582 as a, PrivyWalletProvider as a0, PrivyExpoProvider as a1, EFFECT_INTENT_ADDRESS as a2, FunctionInvokeError as a3, InsufficientBalanceError as a4, LiveIntentError as a5, ReactNativeSessionManager as a6, RealtimeStore as a7, ServerSessionManager as a8, WebSessionManager as a9, serverTimestamp as aA, signSessionCreateMessage as aB, subscribeView as aC, toMillis as aD, toSeconds as aE, withEffects as aF, wsDelete as aG, wsGet as aH, wsGetMany as aI, wsQuery as aJ, wsSet as aK, buildSetDocumentsTransaction as aa, clearCache as ab, closeAllSubscriptions as ac, convertRemainingAccounts as ad, createSessionWithSignature as ae, defineLiveModule as af, deriveUserIdentityFromIdToken as ag, functions as ah, genAuthNonce as ai, genSolanaMessage as aj, getActiveSessionManager as ak, getCachedData as al, getRealtimeStore as am, getWebhookKeysUrl as an, hasActiveConnection as ao, increment as ap, invoke as aq, isEffectResult as ar, live as as, intent as at, status as au, now as av, reconnectWithNewAuth as aw, refreshSession as ax, resetRealtimeStore as ay, revokeSession 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, getMany as x, docId as y, set as z };
26167
+ //# sourceMappingURL=index-30RA_Bdf.esm.js.map