@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
package/dist/index.d.ts CHANGED
@@ -8,6 +8,8 @@ export type { GetOptions as BoundedGetOptions } from "@bounded-sh/core";
8
8
  export { subscribe } from "@bounded-sh/core";
9
9
  export * from "@bounded-sh/core";
10
10
  export { useAuth } from "./auth/hooks/useAuth";
11
+ export { useQuery } from "./hooks/useQuery";
12
+ export type { UseQueryOptions, UseQueryResult } from "./hooks/useQuery";
11
13
  export { deserializeTransaction } from "./auth/providers/sol/sol-utils";
12
14
  export { getIdToken } from "./utils";
13
15
  export { setPlatform, getPlatform } from "./platform";
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- export { U as DEFAULT_TEST_ADDRESS, $ as EFFECT_INTENT_ADDRESS, a0 as FunctionInvokeError, a1 as InsufficientBalanceError, a2 as LiveIntentError, T as MockAuthProvider, V as OffchainAuthProvider, S as PhantomWalletProvider, _ as PrivyExpoProvider, Z as PrivyWalletProvider, a3 as ReactNativeSessionManager, a4 as RealtimeStore, a5 as ServerSessionManager, W as SolanaMobileWalletProvider, a6 as WebSessionManager, L as aggregate, a7 as buildSetDocumentsTransaction, a8 as clearCache, a9 as closeAllSubscriptions, r as completeLoginFromRedirect, u as completeLoginInPopup, aa as convertRemainingAccounts, K as count, ab as createSessionWithSignature, ac as defineLiveModule, ad as deriveUserIdentityFromIdToken, O as deserializeTransaction, ae as functions, af as genAuthNonce, ag as genSolanaMessage, w as get, ah as getActiveSessionManager, e as getAuthLoading, j as getAuthProvider, ai as getCachedData, h as getConfig, c as getCurrentUser, A as getFiles, P as getIdToken, aj as getMany, R as getPlatform, ak as getRealtimeStore, al as getWebhookKeysUrl, am as hasActiveConnection, an as increment, i as init, ao as invokeFunction, ap as isEffectResult, X as isMobileWalletAvailable, m as linkEmail, q as linkWithRedirect, aq as live, ar as liveIntent, l as login, t as loginWithPopup, n as loginWithPrivy, p as loginWithRedirect, f as logout, d as onAuthLoadingChanged, o as onAuthStateChanged, C as queryAggregate, as as reconnectWithNewAuth, at as refreshSession, Y as registerMobileWalletAdapter, au as resetRealtimeStore, av as revokeSession, F as runExpression, G as runExpressionMany, D as runQuery, E as runQueryMany, B as search, k as sendEmailOtp, aw as serverTimestamp, x as set, z as setFile, y as setMany, Q as setPlatform, J as signAndSubmitTransaction, s as signInAnonymously, H as signMessage, ax as signSessionCreateMessage, I as signTransaction, M as subscribe, ay as subscribeLiveView, N as useAuth, v as verifyEmailOtp, az as withEffects, aA as wsDelete, aB as wsGet, aC as wsGetMany, aD as wsQuery, aE as wsSet } from './index-D986s6w7.esm.js';
1
+ export { V as DEFAULT_TEST_ADDRESS, a0 as EFFECT_INTENT_ADDRESS, a1 as FunctionInvokeError, a2 as InsufficientBalanceError, a3 as LiveIntentError, U as MockAuthProvider, W as OffchainAuthProvider, T as PhantomWalletProvider, $ as PrivyExpoProvider, _ as PrivyWalletProvider, a4 as ReactNativeSessionManager, a5 as RealtimeStore, a6 as ServerSessionManager, X as SolanaMobileWalletProvider, a7 as WebSessionManager, L as aggregate, a8 as buildSetDocumentsTransaction, a9 as clearCache, aa as closeAllSubscriptions, r as completeLoginFromRedirect, u as completeLoginInPopup, ab as convertRemainingAccounts, K as count, ac as createSessionWithSignature, ad as defineLiveModule, ae as deriveUserIdentityFromIdToken, P as deserializeTransaction, af as functions, ag as genAuthNonce, ah as genSolanaMessage, w as get, ai as getActiveSessionManager, e as getAuthLoading, j as getAuthProvider, aj as getCachedData, h as getConfig, c as getCurrentUser, A as getFiles, Q as getIdToken, ak as getMany, S as getPlatform, al as getRealtimeStore, am as getWebhookKeysUrl, an as hasActiveConnection, ao as increment, i as init, ap as invokeFunction, aq as isEffectResult, Y as isMobileWalletAvailable, m as linkEmail, q as linkWithRedirect, ar as live, as as liveIntent, at as liveStatus, l as login, t as loginWithPopup, n as loginWithPrivy, p as loginWithRedirect, f as logout, au as now, d as onAuthLoadingChanged, o as onAuthStateChanged, C as queryAggregate, av as reconnectWithNewAuth, aw as refreshSession, Z as registerMobileWalletAdapter, ax as resetRealtimeStore, ay as revokeSession, F as runExpression, G as runExpressionMany, D as runQuery, E as runQueryMany, B as search, k as sendEmailOtp, az as serverTimestamp, x as set, z as setFile, y as setMany, R as setPlatform, J as signAndSubmitTransaction, s as signInAnonymously, H as signMessage, aA as signSessionCreateMessage, I as signTransaction, M as subscribe, aB as subscribeLiveView, aC as toMillis, aD as toSeconds, N as useAuth, O as useQuery, v as verifyEmailOtp, aE as withEffects, aF as wsDelete, aG as wsGet, aH as wsGetMany, aI as wsQuery, aJ as wsSet } from './index-n4fG6EZJ.esm.js';
2
2
  import 'axios';
3
3
  import '@solana/web3.js';
4
4
  import '@coral-xyz/anchor';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-BL-0ZKBl.js');
3
+ var index = require('./index-BBLnBZjY.js');
4
4
  require('axios');
5
5
  require('@solana/web3.js');
6
6
  require('@coral-xyz/anchor');
@@ -63,11 +63,13 @@ exports.linkEmail = index.linkEmail;
63
63
  exports.linkWithRedirect = index.linkWithRedirect;
64
64
  exports.live = index.live;
65
65
  exports.liveIntent = index.intent;
66
+ exports.liveStatus = index.status;
66
67
  exports.login = index.login;
67
68
  exports.loginWithPopup = index.loginWithPopup;
68
69
  exports.loginWithPrivy = index.loginWithPrivy;
69
70
  exports.loginWithRedirect = index.loginWithRedirect;
70
71
  exports.logout = index.logout;
72
+ exports.now = index.now;
71
73
  exports.onAuthLoadingChanged = index.onAuthLoadingChanged;
72
74
  exports.onAuthStateChanged = index.onAuthStateChanged;
73
75
  exports.queryAggregate = index.queryAggregate;
@@ -94,7 +96,10 @@ exports.signSessionCreateMessage = index.signSessionCreateMessage;
94
96
  exports.signTransaction = index.signTransaction;
95
97
  exports.subscribe = index.subscribe;
96
98
  exports.subscribeLiveView = index.subscribeView;
99
+ exports.toMillis = index.toMillis;
100
+ exports.toSeconds = index.toSeconds;
97
101
  exports.useAuth = index.useAuth;
102
+ exports.useQuery = index.useQuery;
98
103
  exports.verifyEmailOtp = index.verifyEmailOtp;
99
104
  exports.withEffects = index.withEffects;
100
105
  exports.wsDelete = index.wsDelete;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -11282,6 +11282,13 @@ async function runExpressionMany(many) {
11282
11282
  throw error;
11283
11283
  }
11284
11284
  }
11285
+ /**
11286
+ * Write a document at `path`. Sugar for a one-element {@link setMany}.
11287
+ *
11288
+ * **Delete:** pass `null` as the document to delete it — `set(path, null)` is
11289
+ * the delete (there is no separate `del`/`remove`). It is routed through the
11290
+ * collection's policy `delete` rule and broadcasts a delete to subscribers.
11291
+ */
11285
11292
  async function set(path, document, options) {
11286
11293
  const result = await setMany([{ path, document }], options);
11287
11294
  // Clear cache entries that might be affected by this update
@@ -12960,6 +12967,73 @@ function serverTimestamp() {
12960
12967
  return { operation: 'time', value: 'now' };
12961
12968
  }
12962
12969
 
12970
+ /**
12971
+ * Time units in Bounded — read this once and never get a 1000× timestamp bug.
12972
+ *
12973
+ * **Bounded's policy/proof layer is Unix SECONDS.** `@time.now` in a rule,
12974
+ * `rollingSum` `windowSeconds`, `scheduledAt`, and any timestamp *field your
12975
+ * policy compares against `@time.now`* are all **seconds**. (This is also what
12976
+ * the chain uses — Solana's on-chain clock is `unix_timestamp` in seconds — so a
12977
+ * single seconds unit works for both onchain and offchain rules.)
12978
+ *
12979
+ * **JavaScript is MILLISECONDS.** `Date.now()`, `new Date().getTime()`, and the
12980
+ * auto-stamped system fields `_createdAt` / `_updatedAt` are all **ms**.
12981
+ *
12982
+ * Comparing across the two (e.g. `@time.now - myField` where `myField` was set
12983
+ * from `Date.now()`) is 1000× off, so a freshness / TTL check silently treats
12984
+ * every row as ancient (or far-future) and drops it — which reads as "realtime
12985
+ * isn't delivering" when the data is actually fine.
12986
+ *
12987
+ * **The rules:**
12988
+ * - To **write** a timestamp a policy will read, prefer **`serverTimestamp()`**
12989
+ * (from this package) — the *server* stamps it in seconds, so it matches
12990
+ * `@time.now` AND can't be forged by the client (use it for TTLs, rate windows,
12991
+ * anti-cheat). Use `now()` only when you need the value in client code before
12992
+ * the write.
12993
+ * - To **compare** timestamps in client/render code, use `now()` (seconds), not
12994
+ * `Date.now()` (ms), and `toSeconds()` to convert the ms system fields
12995
+ * (`_createdAt`/`_updatedAt`) or any `Date.now()` value first.
12996
+ */
12997
+ /**
12998
+ * Current time as a **Unix timestamp in seconds** — the unit Bounded policy rules
12999
+ * use (`@time.now`). Use this (not `Date.now()`) when you need a timestamp in
13000
+ * client code (e.g. a freshness check). For a value you *store* and a policy
13001
+ * reads, prefer the server-authoritative {@link serverTimestamp} instead.
13002
+ *
13003
+ * ```ts
13004
+ * // stale if >15s old — seconds vs seconds ✓
13005
+ * if (now() - doc.lastSeenSeconds > 15) renderStale();
13006
+ * ```
13007
+ */
13008
+ function now() {
13009
+ return Math.floor(Date.now() / 1000);
13010
+ }
13011
+ /**
13012
+ * Convert a JavaScript millisecond timestamp to Bounded's **seconds**. Accepts a
13013
+ * `Date`, or an ms number such as `Date.now()` or a doc's `_createdAt` /
13014
+ * `_updatedAt` system field.
13015
+ *
13016
+ * ```ts
13017
+ * // doc is >15s old (compare the ms system field in seconds):
13018
+ * if (now() - toSeconds(doc._updatedAt) > 15) renderStale();
13019
+ * ```
13020
+ */
13021
+ function toSeconds(msOrDate) {
13022
+ const ms = msOrDate instanceof Date ? msOrDate.getTime() : msOrDate;
13023
+ return Math.floor(ms / 1000);
13024
+ }
13025
+ /**
13026
+ * Convert a Bounded **seconds** timestamp back to JavaScript **milliseconds** —
13027
+ * e.g. to build a `Date` or do client-side date math/formatting.
13028
+ *
13029
+ * ```ts
13030
+ * new Date(toMillis(doc.createdAtSeconds)).toLocaleString();
13031
+ * ```
13032
+ */
13033
+ function toMillis(seconds) {
13034
+ return seconds * 1000;
13035
+ }
13036
+
12963
13037
  // ---------------------------------------------------------------------------
12964
13038
  // realtime-store.ts — Client-side state manager for realtime apps.
12965
13039
  //
@@ -13863,6 +13937,7 @@ const functions = { invoke };
13863
13937
  // collection. This file is the consumer surface around that runtime:
13864
13938
  //
13865
13939
  // bounded.live.intent(roomPath, intent) -> POST {realtime}/live/intent
13940
+ // bounded.live.status(roomPath) -> GET {realtime}/live/status
13866
13941
  //
13867
13942
  // It mirrors `functions.invoke` exactly: it attaches the caller's session token
13868
13943
  // AUTOMATICALLY (the same token the SDK uses for data reads/writes), and throws
@@ -13875,18 +13950,14 @@ const functions = { invoke };
13875
13950
  // Addressing: clients address rooms BY PATH (the `path` field in the body). The
13876
13951
  // worker derives the roomId from `body.path` and sets X-Room-Id internally;
13877
13952
  // clients NEVER set X-Room-Id. The caller's address is taken server-side from
13878
- // the Authorization header (auth.userAddress) — it is NOT sent in the body.
13953
+ // the Authorization header (auth.userId/userAddress) — it is NOT sent in the
13954
+ // body.
13879
13955
  //
13880
13956
  // Subscribing to your view: a per-player view doc lives at
13881
- // `<roomPath>/view/<myAddress>` (the policy declares
13882
- // `rooms/$roomId/view/$addr` ephemeral with `read: $addr == @user.address`).
13883
- // That path has an EVEN segment count, so it is an ordinary document path —
13884
- // plain `subscribe('<roomPath>/view/<myAddress>', { onData })` already works.
13885
- // `subscribeView()` below is thin sugar over that (path construction + address
13886
- // defaulting); it adds zero new transport.
13887
- //
13888
- // Status polling (GET /live/status?path=<sessionCollection>/<roomId>) is out of
13889
- // scope for this piece — see follow-up.
13957
+ // `<roomPath>/view/<myUserId>` (the policy declares
13958
+ // `rooms/$roomId/view/$userId` ephemeral with `read: $userId == @user.id`).
13959
+ // Wallet-address keyed view paths remain supported through opts.address for
13960
+ // older policies, but new live rooms should key views by @user.id.
13890
13961
  // ---------------------------------------------------------------------------
13891
13962
  class LiveIntentError extends Error {
13892
13963
  constructor(message, statusCode, details) {
@@ -13967,7 +14038,7 @@ async function intent(roomPath, intent, opts = {}) {
13967
14038
  res = await fetch(`${base}/live/intent`, {
13968
14039
  method: 'POST',
13969
14040
  headers,
13970
- body: JSON.stringify({ path: roomPath, intent }),
14041
+ body: JSON.stringify({ path: normalizedRoomPath, intent }),
13971
14042
  signal: controller.signal,
13972
14043
  });
13973
14044
  }
@@ -13995,43 +14066,95 @@ async function intent(roomPath, intent, opts = {}) {
13995
14066
  }
13996
14067
  return (body !== null && body !== void 0 ? body : { ok: true });
13997
14068
  }
14069
+ /**
14070
+ * Fetch the runtime status for a live room.
14071
+ *
14072
+ * const s = await bounded.live.status('rooms/abc');
14073
+ * console.log(s.running, s.stopReason, s.generation, s.etag);
14074
+ *
14075
+ * This is diagnostic/ops surface. It reports whether the room facet exists,
14076
+ * whether it is currently ticking, why it last stopped, which module etag is
14077
+ * loaded, and the current generation used after terminal restarts.
14078
+ */
14079
+ async function status(roomPath, opts = {}) {
14080
+ var _a, _b, _c, _d, _e;
14081
+ if (!roomPath || typeof roomPath !== 'string') {
14082
+ throw new LiveIntentError('A room path is required');
14083
+ }
14084
+ const normalizedRoomPath = roomPath.replace(/\/$/, '');
14085
+ const config = await getConfig();
14086
+ const base = realtimeHttpBase(config.wsApiUrl);
14087
+ const headers = Object.assign({ 'X-App-Id': config.appId, 'X-Public-App-Id': config.appId }, ((_a = opts.headers) !== null && _a !== void 0 ? _a : {}));
14088
+ const controller = new AbortController();
14089
+ const timeoutMs = (_b = opts.timeoutMs) !== null && _b !== void 0 ? _b : 15000;
14090
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
14091
+ let res;
14092
+ try {
14093
+ res = await fetch(`${base}/live/status?path=${encodeURIComponent(normalizedRoomPath)}`, {
14094
+ method: 'GET',
14095
+ headers,
14096
+ signal: controller.signal,
14097
+ });
14098
+ }
14099
+ catch (err) {
14100
+ clearTimeout(timer);
14101
+ if ((err === null || err === void 0 ? void 0 : err.name) === 'AbortError') {
14102
+ throw new LiveIntentError(`Live status for "${normalizedRoomPath}" timed out after ${timeoutMs}ms`);
14103
+ }
14104
+ 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)}`);
14105
+ }
14106
+ clearTimeout(timer);
14107
+ let body = null;
14108
+ const text = await res.text();
14109
+ if (text) {
14110
+ try {
14111
+ body = JSON.parse(text);
14112
+ }
14113
+ catch (_f) {
14114
+ body = { raw: text };
14115
+ }
14116
+ }
14117
+ if (!res.ok) {
14118
+ 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}`;
14119
+ throw new LiveIntentError(message, res.status, body);
14120
+ }
14121
+ return body;
14122
+ }
13998
14123
  /**
13999
14124
  * Subscribe to YOUR per-player view of a room. Thin sugar over:
14000
14125
  *
14001
- * subscribe('<roomPath>/view/<myAddress>', { onData, onError })
14126
+ * subscribe('<roomPath>/view/<myUserId>', { onData, onError })
14002
14127
  *
14003
- * The address defaults to the logged-in user's address (from the session
14004
- * token's claims); pass `opts.address` to override. Returns the unsubscribe
14128
+ * The view id defaults to the logged-in user's @user.id (from the session token
14129
+ * claims); pass `opts.userId` to override. `opts.address` is kept as a legacy
14130
+ * alias for older wallet-address keyed policies. Returns the unsubscribe
14005
14131
  * function (a Promise<() => Promise<void>>, same as `subscribe`).
14006
14132
  *
14007
14133
  * Note: this is a browser-first helper (the WS subscription manager is
14008
14134
  * browser-oriented). Server consumers should use `live.intent`.
14009
14135
  */
14010
14136
  async function subscribeView(roomPath, opts) {
14011
- var _a;
14137
+ var _a, _b, _c;
14012
14138
  if (!roomPath || typeof roomPath !== 'string') {
14013
14139
  throw new LiveIntentError('A room path is required');
14014
14140
  }
14015
14141
  if (!opts || typeof opts.onData !== 'function') {
14016
14142
  throw new LiveIntentError('subscribeView requires an onData callback');
14017
14143
  }
14018
- let address = opts.address;
14019
- if (!address) {
14144
+ let viewUserId = (_a = opts.userId) !== null && _a !== void 0 ? _a : opts.address;
14145
+ if (!viewUserId) {
14020
14146
  const config = await getConfig();
14021
14147
  const info = await getUserInfo(config.isServer);
14022
- // getUserInfo returns the RAW idToken payload — the wallet address lives in
14023
- // the `custom:walletAddress` claim, NOT a flat `address` field. Reading only
14024
- // `.address` meant auto-resolution NEVER worked, forcing every caller (browser
14025
- // AND server) to pass opts.address — the client having to hand the backend an
14026
- // identity it already authenticated. Resolve it from the actual claim so a
14027
- // logged-in caller never needs to pass its own address.
14028
- 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'];
14148
+ // getUserInfo returns the RAW idToken payload. The universal live view key
14149
+ // is @user.id (`custom:userId`); wallet-address keyed views are still
14150
+ // resolved as a compatibility fallback for older policies.
14151
+ 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;
14029
14152
  }
14030
- if (!address || typeof address !== 'string') {
14031
- throw new LiveIntentError('Could not resolve a player address for subscribeView; pass opts.address or log in first');
14153
+ if (!viewUserId || typeof viewUserId !== 'string') {
14154
+ throw new LiveIntentError('Could not resolve a player view id for subscribeView; pass opts.userId or log in first');
14032
14155
  }
14033
14156
  const normalizedRoomPath = roomPath.replace(/\/$/, '');
14034
- const viewPath = `${normalizedRoomPath}/view/${address}`;
14157
+ const viewPath = `${normalizedRoomPath}/view/${viewUserId}`;
14035
14158
  // This is a LIVE/room subscription by construction (the caller hands us the
14036
14159
  // room path), so we route its connection to the per-room DO where the live
14037
14160
  // view fan-out runs. App code passes NO routing — the room path is the helper's
@@ -14042,7 +14165,7 @@ async function subscribeView(roomPath, opts) {
14042
14165
  return subscribeV2(viewPath, { onData: opts.onData, onError: opts.onError }, normalizedRoomPath);
14043
14166
  }
14044
14167
  /** The `bounded.live` namespace surface. */
14045
- const live = { intent, subscribeView };
14168
+ const live = { intent, status, subscribeView };
14046
14169
 
14047
14170
  // ---------------------------------------------------------------------------
14048
14171
  // live-effects.ts -- AUTHOR-facing types + helpers for writing a Bounded live
@@ -17686,11 +17809,11 @@ var srcExports = requireSrc();
17686
17809
  var basex = /*@__PURE__*/getDefaultExportFromCjs$1(srcExports);
17687
17810
 
17688
17811
  var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
17689
- var base58 = basex(ALPHABET);
17812
+ var bs582 = basex(ALPHABET);
17690
17813
 
17691
17814
  var index = /*#__PURE__*/Object.freeze({
17692
17815
  __proto__: null,
17693
- default: base58
17816
+ default: bs582
17694
17817
  });
17695
17818
 
17696
17819
  // guest-keystore.ts — durable per-device keypair for anonymous ("guest") auth.
@@ -17763,7 +17886,7 @@ async function tryWebCrypto() {
17763
17886
  await idbPut(db, IDB_KEY, pair); // CryptoKey is structured-cloneable; bytes never exposed
17764
17887
  }
17765
17888
  const raw = new Uint8Array(await s.exportKey('raw', pair.publicKey)); // public is exportable
17766
- const address = base58.encode(raw);
17889
+ const address = bs582.encode(raw);
17767
17890
  return {
17768
17891
  address,
17769
17892
  nonExtractable: true,
@@ -17784,12 +17907,12 @@ function fallbackKey() {
17784
17907
  let secret;
17785
17908
  const saved = store.getItem(FALLBACK_STORE_KEY);
17786
17909
  if (saved) {
17787
- secret = base58.decode(saved);
17910
+ secret = bs582.decode(saved);
17788
17911
  }
17789
17912
  else {
17790
17913
  const kp = Keypair.generate();
17791
17914
  secret = kp.secretKey; // 64 bytes
17792
- store.setItem(FALLBACK_STORE_KEY, base58.encode(secret));
17915
+ store.setItem(FALLBACK_STORE_KEY, bs582.encode(secret));
17793
17916
  }
17794
17917
  const kp = Keypair.fromSecretKey(secret);
17795
17918
  const address = kp.publicKey.toBase58();
@@ -18572,17 +18695,17 @@ function clearIncompatibleSession() {
18572
18695
  // Lazy loaders for web-only providers.
18573
18696
  // Using dynamic import() ensures Metro (RN) never resolves these modules.
18574
18697
  async function loadPhantomWalletProvider() {
18575
- const mod = await import('./phantom-wallet-provider-Cy5T9EVd.esm.js');
18698
+ const mod = await import('./phantom-wallet-provider-C8DNu92D.esm.js');
18576
18699
  return { PhantomWalletProvider: mod.PhantomWalletProvider };
18577
18700
  }
18578
18701
  // Web Privy provider (depends on react-dom + @privy-io/react-auth). Lazy so Metro
18579
18702
  // never bundles it into the RN build — RN uses the @privy-io/expo provider instead.
18580
18703
  async function loadPrivyWalletProvider() {
18581
- const mod = await import('./privy-wallet-provider-BDsrUpk4.esm.js');
18704
+ const mod = await import('./privy-wallet-provider-De3mfJYo.esm.js');
18582
18705
  return mod.PrivyWalletProvider;
18583
18706
  }
18584
18707
  async function loadSolanaMobileWalletProvider() {
18585
- const mod = await import('./solana-mobile-wallet-provider-CSk_FIww.esm.js');
18708
+ const mod = await import('./solana-mobile-wallet-provider-CLCvi-08.esm.js');
18586
18709
  return mod.SolanaMobileWalletProvider;
18587
18710
  }
18588
18711
  async function hotSwapToMWAProvider(config) {
@@ -19393,7 +19516,7 @@ class PrivyExpoProvider {
19393
19516
  const wallet = await this.getWalletOrThrow();
19394
19517
  const messageBytes = getPlatform().textEncode(message);
19395
19518
  const result = await wallet.signMessage(messageBytes);
19396
- return base58.encode(result.signature);
19519
+ return bs582.encode(result.signature);
19397
19520
  }
19398
19521
  async signTransaction(transaction) {
19399
19522
  await this.ensureReady();
@@ -19561,5 +19684,5 @@ class PrivyExpoProvider {
19561
19684
  }
19562
19685
  }
19563
19686
 
19564
- export { aggregate as $, signInAnonymously as A, sendEmailOtp as B, verifyEmailOtp as C, linkEmail as D, loginWithPrivy as E, loginWithRedirect as F, linkWithRedirect as G, completeLoginFromRedirect as H, loginWithPopup as I, completeLoginInPopup as J, get as K, set as L, setMany as M, setFile as N, getFiles as O, search as P, queryAggregate as Q, runQuery as R, SOLANA_DEVNET_RPC_URL as S, runQueryMany as T, runExpression as U, runExpressionMany as V, WebSessionManager as W, signMessage as X, signTransaction as Y, signAndSubmitTransaction as Z, count as _, buildSetDocumentsTransaction as a, subscribe as a0, useAuth as a1, deserializeTransaction as a2, getIdToken as a3, setPlatform as a4, MockAuthProvider as a5, DEFAULT_TEST_ADDRESS as a6, OffchainAuthProvider as a7, PrivyExpoProvider as a8, EFFECT_INTENT_ADDRESS as a9, signSessionCreateMessage as aA, subscribeView as aB, withEffects as aC, wsDelete as aD, wsGet as aE, wsGetMany as aF, wsQuery as aG, wsSet as aH, index as aI, FunctionInvokeError as aa, InsufficientBalanceError as ab, LiveIntentError as ac, ReactNativeSessionManager as ad, RealtimeStore as ae, ServerSessionManager as af, clearCache as ag, closeAllSubscriptions as ah, defineLiveModule as ai, deriveUserIdentityFromIdToken as aj, functions as ak, getCachedData as al, getMany as am, getRealtimeStore as an, getWebhookKeysUrl as ao, hasActiveConnection as ap, increment as aq, invoke as ar, isEffectResult as as, live as at, intent as au, reconnectWithNewAuth as av, refreshSession as aw, resetRealtimeStore as ax, revokeSession as ay, serverTimestamp as az, bufferExports as b, convertRemainingAccounts as c, confirmAndCheckTransaction as d, SOLANA_MAINNET_RPC_URL as e, SURFNET_RPC_URL$1 as f, detectMobile as g, detectAndroid as h, getPlatform as i, setAuthLoading as j, genAuthNonce as k, genSolanaMessage as l, createSessionWithSignature as m, getActiveSessionManager as n, base58 as o, getDefaultExportFromCjs$1 as p, init as q, getCurrentUser as r, setCurrentUser as s, onAuthStateChanged as t, onAuthLoadingChanged as u, getAuthLoading as v, login as w, logout as x, getConfig as y, getAuthProvider as z };
19565
- //# sourceMappingURL=index.native-B-cLm_BI.esm.js.map
19687
+ export { aggregate as $, signInAnonymously as A, sendEmailOtp as B, verifyEmailOtp as C, linkEmail as D, loginWithPrivy as E, loginWithRedirect as F, linkWithRedirect as G, completeLoginFromRedirect as H, loginWithPopup as I, completeLoginInPopup as J, get as K, set as L, setMany as M, setFile as N, getFiles as O, search as P, queryAggregate as Q, runQuery as R, SOLANA_DEVNET_RPC_URL as S, runQueryMany as T, runExpression as U, runExpressionMany as V, WebSessionManager as W, signMessage as X, signTransaction as Y, signAndSubmitTransaction as Z, count as _, buildSetDocumentsTransaction as a, subscribe as a0, useAuth as a1, deserializeTransaction as a2, getIdToken as a3, setPlatform as a4, MockAuthProvider as a5, DEFAULT_TEST_ADDRESS as a6, OffchainAuthProvider as a7, PrivyExpoProvider as a8, EFFECT_INTENT_ADDRESS as a9, revokeSession as aA, serverTimestamp as aB, signSessionCreateMessage as aC, subscribeView as aD, toMillis as aE, toSeconds as aF, withEffects as aG, wsDelete as aH, wsGet as aI, wsGetMany as aJ, wsQuery as aK, wsSet as aL, index as aM, FunctionInvokeError as aa, InsufficientBalanceError as ab, LiveIntentError as ac, ReactNativeSessionManager as ad, RealtimeStore as ae, ServerSessionManager as af, clearCache as ag, closeAllSubscriptions as ah, defineLiveModule as ai, deriveUserIdentityFromIdToken as aj, functions as ak, getCachedData as al, getMany as am, getRealtimeStore as an, getWebhookKeysUrl as ao, hasActiveConnection as ap, increment as aq, invoke as ar, isEffectResult as as, live as at, intent as au, status as av, now as aw, reconnectWithNewAuth as ax, refreshSession as ay, resetRealtimeStore as az, bufferExports as b, convertRemainingAccounts as c, confirmAndCheckTransaction as d, SOLANA_MAINNET_RPC_URL as e, SURFNET_RPC_URL$1 as f, detectMobile as g, detectAndroid as h, getPlatform as i, setAuthLoading as j, genAuthNonce as k, genSolanaMessage as l, createSessionWithSignature as m, getActiveSessionManager as n, bs582 as o, getDefaultExportFromCjs$1 as p, init as q, getCurrentUser as r, setCurrentUser as s, onAuthStateChanged as t, onAuthLoadingChanged as u, getAuthLoading as v, login as w, logout as x, getConfig as y, getAuthProvider as z };
19688
+ //# sourceMappingURL=index.native-D5q2RUeV.esm.js.map