@alphea/react
v0.1.5
Published
React hooks and Provider bindings for ALPHEA browser app runtimes
Readme
@alphea/react
React hooks and Provider bindings for ALPHEA browser app runtimes.
npm install @alphea/react react react-dom
npm install -D @types/react @types/react-domimport {
alpheaError,
createAlpheaAppGatewayResolver,
createAlpheaReactHooks,
getAlpheaBrowserClient,
isAlpheaErrorCode,
} from "@alphea/react";
import type { AlpheaFns } from "./alphea-fns.generated";
const alphea = createAlpheaReactHooks<AlpheaFns>();
export function NewNote() {
const createNote = alphea.useFn("createNote");
return (
<button
disabled={createNote.loading}
onClick={() => void createNote.call({ title: "Hello" })}
>
Save
</button>
);
}The hooks resolve the served runtime's ambient window.alphea binding by
default. Use AlpheaProvider only when you want to inject an explicit client,
for example in tests or a custom bootstrap.
@alphea/react is the normal browser-safe dependency for React UI apps. In
addition to the hooks, it re-exports the browser Client Framework factories,
ambient client helpers, shared JSON/error/function/worker types, and ALPN app
resolver helpers so React app code does not need a direct @alphea/framework or
@alphea/client dependency for those browser-safe surfaces.
Keep credential-bearing Foundation RPC clients, bearer/session transports, and
auth login helpers in trusted tooling or server code that depends on
@alphea/foundation; they are not exported by @alphea/react.
Connect hooks: @alphea/react/connect
The Connect bindings live behind a separate import, and that separation is the point rather than packaging trivia.
The root entry above is the browser-capability surface: an ambient session
the served ALPHEA runtime holds on the app's behalf. @alphea/react/connect is
the end-user Connect surface: a credential that belongs to a person who
signed in. An ambient browser-capability session neither is, nor can create, a
Connect session — so reaching the second is an explicit import, not something
an app inherits from the first.
import {
createAlpheaConnectAuthClient,
createAlpheaConnectDataClient,
createAlpheaConnectFetchTransport,
createAlpheaConnectMemorySessionStore,
createAlpheaConnectAccessTokenProvider,
} from "@alphea/connect";
import {
AlpheaConnectProvider,
useConnectPointBalance,
useConnectSession,
} from "@alphea/react/connect";
const sessionStore = createAlpheaConnectMemorySessionStore();
const transport = createAlpheaConnectFetchTransport({
baseUrl: import.meta.env.VITE_CONNECT_BASE_URL,
getAccessToken: createAlpheaConnectAccessTokenProvider(sessionStore),
});
<AlpheaConnectProvider
auth={createAlpheaConnectAuthClient({ transport, sessionStore })}
data={createAlpheaConnectDataClient({ transport })}
>
<App />
</AlpheaConnectProvider>;You construct the clients and pass them in. There is no ambient fallback, because there is nothing ambient to find.
Hook state
Every hook reports one of idle, loading, success, error,
unauthorized, or unavailable. The last two are separate from error
because an app does something different for each:
const balance = useConnectPointBalance();
if (balance.unauthorized) return <SignInPrompt />; // no valid session
if (balance.unavailable) return null; // not served here
if (balance.error) return <Retry onRetry={balance.reload} />;unavailable means the operation was not attempted: either it is not live
in the pinned Connect contract, or the app listed it in
unavailableOperations on the provider. A hook never reports an unavailable
operation as a successful call.
Available hooks:
- Session and sign-in —
useConnectSession,useConnectSessionSnapshot,useConnectGoogleLogin,useConnectEmailLogin,useConnectLogout - Points —
useConnectPointBalance,useConnectPointSummary,useConnectPointHistory - Referral reads —
useConnectReferralCode,useConnectFriends,useConnectReferralRewards,useConnectInviterBonus - Referral actions —
useConnectReferralActions, givingclaimInviterBonus,claimReward,claimCompletionBonus, andredeemInvitation - Rounds and redeem —
useConnectRoundStatus,useConnectRedeemStatus - Wallet —
useConnectWallets,useConnectWalletBinding
Each referral action takes a client-minted idempotency key, so a retried tap cannot double-award:
const referral = useConnectReferralActions();
await referral.claimReward.run({ level: 3, idempotencyKey });Despite the shared word, these are not the reward-claim surface: they are point-ledger mutations the server settles, with nothing signed and no chain involved.
Reward-claim hooks are not in this release. They wait for a dedicated claim surface and its own contract review. Nothing in this entry reads a claim proof, builds calldata, or sends a transaction.
