@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.
- package/dist/hooks/useQuery.d.ts +58 -0
- package/dist/{index-BL-0ZKBl.js → index-BBLnBZjY.js} +234 -46
- package/dist/index-BBLnBZjY.js.map +1 -0
- package/dist/{index-CqoP9udN.js → index-BMrN-6oK.js} +1202 -450
- package/dist/index-BMrN-6oK.js.map +1 -0
- package/dist/{index-B2ytfYTB.esm.js → index-D5Ut2JU7.esm.js} +1202 -450
- package/dist/index-D5Ut2JU7.esm.js.map +1 -0
- package/dist/{index-BFOmV3Pb.esm.js → index-DkWfblRJ.esm.js} +1202 -450
- package/dist/index-DkWfblRJ.esm.js.map +1 -0
- package/dist/{index-BgAygrhE.js → index-FYyc3l_y.js} +1202 -450
- package/dist/index-FYyc3l_y.js.map +1 -0
- package/dist/{index-D986s6w7.esm.js → index-n4fG6EZJ.esm.js} +229 -46
- package/dist/index-n4fG6EZJ.esm.js.map +1 -0
- package/dist/{index.browser-D2xm-q6N.esm.js → index.browser-CCWEiCH-.esm.js} +766 -773
- package/dist/index.browser-CCWEiCH-.esm.js.map +1 -0
- package/dist/{index.browser-Bd0GwRur.esm.js → index.browser-C_TToxuO.esm.js} +230 -242
- package/dist/index.browser-C_TToxuO.esm.js.map +1 -0
- package/dist/{index.browser-D8u31irV.js → index.browser-D5evrolK.js} +766 -773
- package/dist/index.browser-D5evrolK.js.map +1 -0
- package/dist/{index.browser-BeM1bzpe.js → index.browser-DcHalmEf.js} +230 -242
- package/dist/index.browser-DcHalmEf.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/{index.native-B-cLm_BI.esm.js → index.native-D5q2RUeV.esm.js} +162 -39
- package/dist/index.native-D5q2RUeV.esm.js.map +1 -0
- package/dist/{index.native-NgHStPq0.js → index.native-D82ofFXB.js} +166 -39
- package/dist/index.native-D82ofFXB.js.map +1 -0
- package/dist/index.native.esm.js +1 -1
- package/dist/index.native.js +5 -1
- package/dist/index.native.js.map +1 -1
- package/dist/{phantom-wallet-provider-Cy5T9EVd.esm.js → phantom-wallet-provider-C8DNu92D.esm.js} +3 -3
- package/dist/{phantom-wallet-provider-Cy5T9EVd.esm.js.map → phantom-wallet-provider-C8DNu92D.esm.js.map} +1 -1
- package/dist/{phantom-wallet-provider-Dy48LSdU.js → phantom-wallet-provider-CoL7g8Sr.js} +3 -3
- package/dist/{phantom-wallet-provider-Dy48LSdU.js.map → phantom-wallet-provider-CoL7g8Sr.js.map} +1 -1
- package/dist/{privy-wallet-provider-CiKtBJ5M.js → privy-wallet-provider-CV1mU4KR.js} +4 -4
- package/dist/{privy-wallet-provider-CiKtBJ5M.js.map → privy-wallet-provider-CV1mU4KR.js.map} +1 -1
- package/dist/{privy-wallet-provider-BDsrUpk4.esm.js → privy-wallet-provider-De3mfJYo.esm.js} +4 -4
- package/dist/{privy-wallet-provider-BDsrUpk4.esm.js.map → privy-wallet-provider-De3mfJYo.esm.js.map} +1 -1
- package/dist/{solana-mobile-wallet-provider-CSk_FIww.esm.js → solana-mobile-wallet-provider-CLCvi-08.esm.js} +5 -5
- package/dist/{solana-mobile-wallet-provider-CSk_FIww.esm.js.map → solana-mobile-wallet-provider-CLCvi-08.esm.js.map} +1 -1
- package/dist/{solana-mobile-wallet-provider-k_YdrTJZ.js → solana-mobile-wallet-provider-D9dPbk__.js} +5 -5
- package/dist/{solana-mobile-wallet-provider-k_YdrTJZ.js.map → solana-mobile-wallet-provider-D9dPbk__.js.map} +1 -1
- package/package.json +2 -2
- package/dist/index-B2ytfYTB.esm.js.map +0 -1
- package/dist/index-BFOmV3Pb.esm.js.map +0 -1
- package/dist/index-BL-0ZKBl.js.map +0 -1
- package/dist/index-BgAygrhE.js.map +0 -1
- package/dist/index-CqoP9udN.js.map +0 -1
- package/dist/index-D986s6w7.esm.js.map +0 -1
- package/dist/index.browser-Bd0GwRur.esm.js.map +0 -1
- package/dist/index.browser-BeM1bzpe.js.map +0 -1
- package/dist/index.browser-D2xm-q6N.esm.js.map +0 -1
- package/dist/index.browser-D8u31irV.js.map +0 -1
- package/dist/index.native-B-cLm_BI.esm.js.map +0 -1
- 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
|
|
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/<
|
|
13906
|
-
// `rooms/$roomId/view/$
|
|
13907
|
-
//
|
|
13908
|
-
//
|
|
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:
|
|
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/<
|
|
14150
|
+
* subscribe('<roomPath>/view/<myUserId>', { onData, onError })
|
|
14026
14151
|
*
|
|
14027
|
-
* The
|
|
14028
|
-
*
|
|
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
|
|
14043
|
-
if (!
|
|
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
|
|
14047
|
-
//
|
|
14048
|
-
//
|
|
14049
|
-
|
|
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 (!
|
|
14055
|
-
throw new LiveIntentError('Could not resolve a player
|
|
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/${
|
|
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
|
|
17836
|
+
var bs582 = basex(ALPHABET);
|
|
17714
17837
|
|
|
17715
17838
|
var index = /*#__PURE__*/Object.freeze({
|
|
17716
17839
|
__proto__: null,
|
|
17717
|
-
default:
|
|
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 =
|
|
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 =
|
|
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,
|
|
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-
|
|
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-
|
|
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-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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.
|
|
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-
|
|
23760
|
+
//# sourceMappingURL=index-BBLnBZjY.js.map
|