/**
* React helpers for adding session data to Convex functions.
*
* !Important!: To use these functions, you must wrap your code with
* ```tsx
*
*
*
*
*
* ```
*
* With the `SessionProvider` inside the `ConvexProvider` but outside your app.
*
* See the associated [Stack post](https://stack.convex.dev/track-sessions-without-cookies)
* for more information.
*/
import React from "react";
import type { FunctionArgs, FunctionReference, FunctionReturnType, PaginationOptions, PaginationResult } from "convex/server";
import { ConvexReactClient, type ConvexReactClientOptions, type MutationOptions, type PaginatedQueryArgs, type UsePaginatedQueryReturnType } from "convex/react";
import type { SessionId } from "../server/sessions.js";
import type { EmptyObject, BetterOmit } from "../index.js";
import type { OptimisticUpdate } from "convex/browser";
export declare const DEFAULT_STORAGE_KEY = "convex-session-id";
export type UseStorage = (key: string, initialValue: T) => readonly [T, (value: T) => void] | readonly [T, (value: T) => void, () => void];
export type RefreshSessionFn = (beforeUpdate?: (newSessionId: SessionId) => any | Promise) => Promise;
type SessionFunction = FunctionReference;
type ArgsWithoutSession> = BetterOmit, "sessionId">;
export type SessionQueryArgsArray> = keyof FunctionArgs extends "sessionId" ? [args?: EmptyObject | "skip"] : Partial> extends ArgsWithoutSession ? [args?: ArgsWithoutSession | "skip"] : [args: ArgsWithoutSession | "skip"];
export type SessionArgsArray> = keyof FunctionArgs extends "sessionId" ? [args?: EmptyObject] : Partial> extends ArgsWithoutSession ? [args?: ArgsWithoutSession] : [args: ArgsWithoutSession];
export type SessionArgsAndOptions, Options> = keyof FunctionArgs extends "sessionId" ? [args?: EmptyObject, options?: Options] : Partial> extends ArgsWithoutSession ? [args?: ArgsWithoutSession, options?: Options] : [args: ArgsWithoutSession, options?: Options];
type SessionPaginatedQueryFunction = FunctionReference<"query", "public", {
sessionId: SessionId;
} & Args, PaginationResult>;
export type SessionPaginatedQueryArgs = BetterOmit, "sessionId"> | "skip";
/**
* Context for a Convex session, creating a server session and providing the id.
*
* @param useStorage - Where you want your session ID to be persisted. Roughly:
* - sessionStorage is saved per-tab (default).
* - localStorage is shared between tabs, but not browser profiles.
* @param storageKey - Key under which to store the session ID in the store
* @param idGenerator - Function to return a new, unique session ID string.
* Defaults to crypto.randomUUID (which isn't always available for server SSR)
* @param ssrFriendly - Set this if you're using SSR. Defaults to false.
* The sessionId won't be available on the server, so the server render and
* first client render will have undefined sessionId. During this render:
* 1. {@link useSessionQuery} will wait for a valid ID via "skip".
* 2. {@link useSessionMutation} and {@link useSessionAction} will wait for
* a valid ID via a promise if called from the first pass.
* 3. {@link useSessionId} will return undefined for the sessionId along with
* the promise to await for the valid ID.
* @returns A provider to wrap your React nodes which provides the session ID.
* To be used with useSessionQuery and useSessionMutation.
*/
export declare const SessionProvider: React.FC<{
useStorage?: UseStorage;
storageKey?: string;
idGenerator?: () => string;
ssrFriendly?: boolean;
children?: React.ReactNode;
}>;
/**
* Use this in place of {@link useQuery} to run a query, passing a sessionId.
*
* It automatically injects the sessionid parameter.
* @param query Query that takes in a sessionId parameter. Like `api.foo.bar`.
* @param args Args for that query, without the sessionId.
* @returns A query result. For SSR, it will skip the query until the
* second render.
*/
export declare function useSessionQuery>(query: Query, ...args: SessionQueryArgsArray): FunctionReturnType | undefined;
/**
* Use this in place of {@link usePaginatedQuery} to run a query, passing a sessionId.
*
* @param query Query that takes in a sessionId parameter. Like `api.foo.bar`.
* @param args Args for that query, without the sessionId.
* @param options - An object specifying the `initialNumItems` to be loaded in
* the first page.
* @returns A {@link UsePaginatedQueryRes} that includes the currently loaded
* items, the status of the pagination, and a `loadMore` function.
* For SSR, it will skip the query until the second render.
*/
export declare function useSessionPaginatedQuery(query: Query, args: SessionPaginatedQueryArgs, options: {
initialNumItems: number;
}): UsePaginatedQueryReturnType | undefined;
type SessionMutation> = (...args: SessionArgsArray) => Promise>;
interface ReactSessionMutation> extends SessionMutation {
withOptimisticUpdate(optimisticUpdate: OptimisticUpdate>): SessionMutation;
}
/**
* Use this in place of {@link useMutation} to run a mutation with a sessionId.
*
* It automatically injects the sessionId parameter.
* @param mutation Mutation that takes in a sessionId parameter. Like `api.foo.bar`.
* @param args Args for that mutation, without the sessionId.
* @returns A mutation result. For SSR, it will wait until the client has a
* valid sessionId.
*/
export declare function useSessionMutation>(name: Mutation): ReactSessionMutation;
/**
* Use this in place of {@link useAction} to run an action with a sessionId.
*
* It automatically injects the sessionId parameter.
* @param action Action that takes in a sessionId parameter. Like `api.foo.bar`.
* @param args Args for that action, without the sessionId.
* @returns An action result. For SSR, it will wait until the client has a
* valid sessionId.
*/
export declare function useSessionAction>(name: Action): (...args: SessionArgsArray) => Promise>;
/**
* Get the session context when nested under a SessionProvider.
*
* @returns [sessionId, refresh, sessionIdPromise] where:
* The `sessionId` will only be `undefined` when using SSR with `ssrFriendly`.
* during which time `sessionId` will be `undefined` for the first render.
* To use it in an async context at that time, you can await `sessionIdPromise`.
* `refresh` will generate a new sessionId. Pass a function to it to run before
* generating the new ID.
*/
export declare function useSessionId(): readonly [
SessionId | undefined,
RefreshSessionFn,
Promise
];
/**
* Use this in place of args to a Convex query that also take a sessionId.
* e.g.
* ```ts
* const myQuery = useQuery(api.foo.bar, useSessionIdArg({ arg: "baz" }));
* ```
* @param args Usually args to a Convex query that also take a sessionId.
* @returns "skip" during server & first client render, if ssrFriendly is set.
*/
export declare function useSessionIdArg(args: T | "skip"): "skip" | (T & {
sessionId: SessionId;
});
/**
* Compare with {@link useState}, but also persists the value in sessionStorage.
* @param key Key to use for sessionStorage.
* @param initialValue If there is no value in storage, use this.
* @returns The value and a function to update it.
*/
export declare function useSessionStorage(key: string, initialValue: SessionId | undefined): readonly [SessionId | undefined, (value: SessionId) => void];
/**
* Simple storage interface that matches localStorage/sessionStorage.
*/
interface SessionStorage {
getItem(key: string): string | null;
setItem(key: string, value: string): void;
}
/**
* A client wrapper that adds session data to Convex functions.
*
* Wraps a ConvexClient and provides methods to automatically inject
* the sessionId parameter into queries, mutations, and actions.
*
* Example:
* ```ts
* const sessionClient = new ConvexReactSessionClient(address);
*
* // Use sessionClient instead of client
* const result = await sessionClient.sessionQuery(
* api.myModule.myQuery,
* { arg1: 123 },
* );
* ```
*/
export declare class ConvexReactSessionClient extends ConvexReactClient {
private sessionId;
private storageKey;
private storage;
/**
* Create a new ConvexSessionClient.
*
* @param client The ConvexClient to wrap
* @param options Optional configuration
* @param options.sessionId Initial session ID (will generate one if not provided)
* @param options.storage Storage interface to use (defaults to localStorage if available)
* @param options.storageKey Key to use for storage (defaults to "convex-session-id")
*/
constructor(address: string, options?: ConvexReactClientOptions & {
sessionId?: SessionId;
storage?: SessionStorage;
storageKey?: string;
});
/**
* Set a new session ID to use for future function calls.
*
* NOTE: Setting it here will not propagate to any SessionProvider.
* So if you plan to change the sessionId and you are using a SessionProvider,
* you should update it there instead.
*
* @param sessionId The new session ID
*/
setSessionId(sessionId: SessionId): void;
/**
* Get the current session ID.
*
* @returns The current session ID
*/
getSessionId(): SessionId;
/**
* Run a Convex query with the session ID injected.
*
* @param query Query that takes a sessionId parameter
* @param args Arguments for the query, without the sessionId
* @returns A promise of the query result
*/
sessionQuery>(query: Query, ...args: SessionArgsArray): Promise>;
/**
* Run a Convex mutation with the session ID injected.
*
* @param mutation Mutation that takes a sessionId parameter
* @param args Arguments for the mutation, without the sessionId
* @returns A promise of the mutation result
*/
sessionMutation>(mutation: Mutation, ...args: SessionArgsAndOptions>>): Promise>;
/**
* Run a Convex action with the session ID injected.
*
* @param action Action that takes a sessionId parameter
* @param args Arguments for the action, without the sessionId
* @returns A promise of the action result
*/
sessionAction>(action: Action, ...args: SessionArgsArray): Promise>;
}
export {};
//# sourceMappingURL=sessions.d.ts.map