@lunora/react 1.0.0-alpha.70 → 1.0.0-alpha.72

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/README.md CHANGED
@@ -94,24 +94,31 @@ function MessageList({ room }: { room: string }) {
94
94
 
95
95
  ## Hooks
96
96
 
97
- | Hook | Returns | Notes |
98
- | ---------------------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------ |
99
- | `useQuery(fn, args, options?)` | `T \| undefined` | Live query; shares one WS subscription across consumers of the same key. |
100
- | `useMutation(fn)` | `{ mutate, pending, data, error, reset, withOptimisticUpdate }` | Per-call `optimistic` / `optimisticUpdate` options pass through to the client. |
101
- | `useSubscription(fn, args, options?)` | `{ data, error }` | No initial fetch — only server-pushed values. |
102
- | `usePaginatedQuery(fn, args, { initialNumItems })` | `{ results, status, isLoading, loadMore }` | Cursor-paginated feed that stays consistent under live edits. |
103
- | `useInfiniteQuery(fn, args, { initialNumItems })` | `{ pages, status, hasNextPage, fetchNextPage, … }` | Page-array variant of the same paginator. |
104
- | `usePreloadedQuery(preloaded)` | `T` | Reads a server `Preloaded` token, then goes live. |
105
- | `usePresence({ heartbeat, listPresent, roomId, … })` | present members | Drives the `definePresence` heartbeat + list functions. |
106
- | `useFlag(key, default, context?)` | flag value (live) | Live OpenFeature flag over the WS; reads `default` until the server answers. |
107
- | `useFlags(defaults, context?)` | `{ [key]: value }` | Batch variant — one live value per key in the `defaults` map. |
108
- | `useStream(fn, args, options?)` | `{ chunks, status, error, cancel }` | Consumes a streamed action response chunk by chunk. |
109
- | `useRateLimit(config, options?)` | `{ ok, disabled, retryAfter, check, consume, reset }` | Client-side mirror of a `@lunora/ratelimit` budget for instant UX. |
110
- | `useConnectionStatus()` | `ConnectionStatus` | `idle` / `connecting` / `connected` / `offline`. |
111
- | `useAuth()` | `{ user, token, setToken }` | Call `setToken(jwt)` after sign-in; RPC then carries the token. |
112
- | `useAuthState()` | `{ isAuthenticated, isLoading }` | Hydration-safe three-state gate. |
113
-
114
- `Authenticated`, `Unauthenticated`, and `AuthLoading` are gate components built on `useAuthState`. `CheckoutButton`, `CustomerPortalButton`, and `useCheckout` wrap `@lunora/payment` flows.
97
+ | Hook | Returns | Notes |
98
+ | -------------------------------------------------------------------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------- |
99
+ | `useQuery(fn, args, options?)` | `T \| undefined` | Live query; shares one WS subscription across consumers of the same key. |
100
+ | `useMutation(fn)` | `{ mutate, pending, data, error, reset, withOptimisticUpdate }` | Per-call `optimistic` / `optimisticUpdate` options pass through to the client. |
101
+ | `useSubscription(fn, args, options?)` | `{ data, error }` | No initial fetch — only server-pushed values. |
102
+ | `usePaginatedQuery(fn, args, { initialNumItems })` | `{ results, status, isLoading, loadMore }` | Cursor-paginated feed that stays consistent under live edits. |
103
+ | `useInfiniteQuery(fn, args, { initialNumItems })` | `{ pages, status, hasNextPage, fetchNextPage, … }` | Page-array variant of the same paginator. |
104
+ | `usePreloadedQuery(preloaded)` | `T` | Reads a server `Preloaded` token, then goes live. |
105
+ | `usePresence({ heartbeat, listPresent, roomId, … })` | present members | Drives the `definePresence` heartbeat + list functions. |
106
+ | `useFlag(key, default, context?)` | flag value (live) | Live OpenFeature flag over the WS; reads `default` until the server answers. |
107
+ | `useFlags(defaults, context?)` | `{ [key]: value }` | Batch variant — one live value per key in the `defaults` map. |
108
+ | `useStream(fn, args, options?)` | `{ chunks, status, error, cancel }` | Consumes a streamed action response chunk by chunk. |
109
+ | `useRateLimit(config, options?)` | `{ ok, disabled, retryAfter, check, consume, reset }` | Client-side mirror of a `@lunora/ratelimit` budget for instant UX. |
110
+ | `useConnectionStatus()` | `ConnectionStatus` | `idle` / `connecting` / `connected` / `offline`. |
111
+ | `useAuth()` | `{ user, token, setToken }` | Call `setToken(jwt)` after sign-in; RPC then carries the token. |
112
+ | `useAuthState()` | `{ isAuthenticated, isLoading }` | Hydration-safe three-state gate. |
113
+ | `useAgentToolEvents({ api, threadKey, … })` | `{ events }` | One agent thread's tool lifecycle: call / result / awaiting-approval / progress. |
114
+ | `useVoiceAgent({ voice, threadKey, … })` | `{ status, transcript, startCall, endCall, … }` | Full-duplex voice call: mic capture, playback, live transcripts, barge-in. |
115
+ | `useAuthUsers` / `useAuthSessions` / `useOrganizations` / `useImpersonate` | `{ data, error, loading, refresh }` (+ `impersonate`/`stop`) | Admin-plane auth reads for a console UI; each needs an admin-capable token. |
116
+
117
+ `Authenticated`, `Unauthenticated`, and `AuthLoading` are gate components built on `useAuthState`.
118
+
119
+ The payment kit — `CheckoutButton`, `CustomerPortalButton`, and `useCheckout`, which wrap `@lunora/payment` flows — ships from the `@lunora/react/payment` subpath, not the package root: it renders a DOM `<button>` and navigates via `globalThis.location`, so it is the one part of this package that is browser-only (the root barrel stays renderer-agnostic, which is what lets `@lunora/react-native` re-export it wholesale).
120
+
121
+ `useVoiceAgent` opens nothing until you call `startCall()` — that is what requests the microphone, so it has to run from a user gesture; `endCall()` releases the socket, the mic tracks and the Web Audio graph, and also runs on unmount. See the [voice-agent docs](https://lunora.sh/docs/packages/react#voice-agents--usevoiceagentoptions) for the silence/barge-in thresholds.
115
122
 
116
123
  ## Server Components
117
124
 
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ReactNode, ReactElement } from 'react';
2
- import { LunoraClient, OptimisticUpdate, User, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, AuthImpersonation, AuthSession, AuthUser, ClientQueryRef, ConnectionStatus, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, MutatorHandle, Preloaded } from '@lunora/client';
3
- export { type ArgsOf, type ClientQueryRef, type FunctionReference, type HttpStreamArgsOf, type HttpStreamChunkOf, type HttpStreamRef, type LunoraClient, type LunoraErrorCode, type MutatorHandle, type MutatorTransaction, type OptimisticLocalStore, type OptimisticUpdate, type Preloaded, type ReturnOf, type User, createClientQuery, getErrorCode, getRetryAfterMs, isConflictError, isForbiddenError, isRateLimitedError, isUnauthorizedError } from '@lunora/client';
2
+ import { LunoraClient, OptimisticUpdate, User, SubscriptionErrorCallback, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, AuthImpersonation, AuthSession, AuthUser, ClientQueryRef, ConnectionStatus, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, MutatorHandle, Preloaded } from '@lunora/client';
3
+ export { type ArgsOf, type AuthImpersonation, type AuthPage, type AuthSession, type AuthUser, type ClientQueryRef, type FunctionReference, type HttpStreamArgsOf, type HttpStreamChunkOf, type HttpStreamRef, type LunoraClient, type LunoraErrorCode, type MutatorHandle, type MutatorTransaction, type OptimisticLocalStore, type OptimisticUpdate, type Preloaded, type ReturnOf, type SubscriptionError, type SubscriptionErrorCallback, type User, createClientQuery, getErrorCode, getRetryAfterMs, isConflictError, isForbiddenError, isRateLimitedError, isUnauthorizedError } from '@lunora/client';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  export { type L as LunoraQueryOptions, l as lunoraQueryOptions } from "./packem_shared/query-options.d-CdgGQ9s4.mjs";
6
6
  import { PaginationStatus } from '@lunora/client/pagination';
@@ -63,89 +63,13 @@ declare const LunoraProvider: ({ children, client, queryClient }: LunoraProvider
63
63
  * colocated with the provider for back-compat.
64
64
  */
65
65
  declare const useLunora: () => LunoraClient;
66
- /**
67
- * Client-safe mirror of `@lunora/payment`'s `Subscription`. Re-declared here
68
- * (rather than imported) so this React entry never pulls in the server-only
69
- * `@lunora/payment` module graph — the kit stays React + DOM only. Keep this in
70
- * sync with `packages/payment/src/types.ts`.
71
- */
72
- interface Subscription {
73
- readonly cancelAtPeriodEnd: boolean;
74
- readonly createdAt: number;
75
- readonly currentPeriodEnd?: number;
76
- readonly id: string;
77
- readonly priceId: string;
78
- readonly provider: "polar" | "stripe";
79
- readonly quantity: number;
80
- readonly referenceId: string;
81
- readonly state: "active" | "canceled" | "past_due" | "paused" | "trialing";
82
- readonly updatedAt: number;
83
- }
84
- /** The `{ url }` shape every checkout/portal trigger resolves to. */
85
- interface RedirectTarget {
86
- readonly url: string;
87
- }
88
- /** A thunk the app supplies that calls its own Lunora action and resolves a redirect URL. */
89
- type RedirectTrigger = () => Promise<RedirectTarget>;
90
- interface UseCheckoutResult {
91
- /** Run the trigger and redirect the browser to the resolved URL. Resolves once the redirect is issued; rejects on failure. */
92
- checkout: () => Promise<void>;
93
- /** The most recent failure, or `undefined`. */
94
- error: Error | undefined;
95
- /** `true` while the trigger is in flight (before the redirect is issued). */
96
- pending: boolean;
97
- }
98
- /**
99
- * Decoupled redirect-on-resolve primitive shared by `CheckoutButton` and
100
- * `CustomerPortalButton`. The app passes a `trigger` thunk that calls its own
101
- * Lunora action (the one wrapping `LunoraPayment.createCheckout` /
102
- * `createPortalSession`) and resolves `{ url }`; this hook awaits it, flips
103
- * `pending`, surfaces any `error`, and on success navigates via
104
- * `location.assign(url)`.
105
- *
106
- * Mirrors Convex's `CheckoutLink` / `CustomerPortalLink` flow (trigger an action
107
- * that returns a URL, then redirect) while staying agnostic of the app's
108
- * function names.
109
- */
110
- declare const useCheckout: (trigger: RedirectTrigger) => UseCheckoutResult;
111
- /**
112
- * Presentational props shared by the redirect buttons. Kept to a curated set
113
- * (rather than spreading arbitrary button attributes) so the component stays
114
- * within the repo's `react/jsx-props-no-spreading` rule while covering the
115
- * common styling / accessibility hooks.
116
- */
117
- interface RedirectButtonOwnProps {
118
- /** Accessible label when the visible `children` are icon-only. */
119
- "aria-label"?: string;
120
- children?: ReactNode;
121
- className?: string;
122
- /** Force-disable the control regardless of pending state. */
123
- disabled?: boolean;
124
- /** Called with the failure when the trigger rejects. The error is also surfaced via `useCheckout`. */
125
- onError?: (error: Error) => void;
126
- title?: string;
127
- }
128
- interface CheckoutButtonProps extends RedirectButtonOwnProps {
129
- /** Calls the app's checkout action and resolves the hosted-checkout `{ url }`. */
130
- onCheckout: RedirectTrigger;
131
- }
132
- interface CustomerPortalButtonProps extends RedirectButtonOwnProps {
133
- /** Calls the app's portal action and resolves the customer-portal `{ url }`. */
134
- onPortal: RedirectTrigger;
135
- }
136
- /**
137
- * Button that starts a hosted checkout. On click it awaits `onCheckout` (a thunk
138
- * that calls the app's checkout action) and redirects to the returned URL,
139
- * disabling itself while the request is in flight.
140
- */
141
- declare const CheckoutButton: ({ onCheckout, ...rest }: CheckoutButtonProps) => ReactNode;
142
- /**
143
- * Button that opens the provider's customer portal. On click it awaits
144
- * `onPortal` (a thunk that calls the app's portal action) and redirects to the
145
- * returned URL, disabling itself while the request is in flight.
146
- */
147
- declare const CustomerPortalButton: ({ onPortal, ...rest }: CustomerPortalButtonProps) => ReactNode;
148
66
  interface UseQueryOptions {
67
+ /**
68
+ * Called when the server pushes a subscription-scoped error (an RLS denial, a
69
+ * query that starts failing server-side). Without a handler such an error has
70
+ * nowhere to go and the hook's value simply freezes at its last good result.
71
+ */
72
+ onError?: SubscriptionErrorCallback;
149
73
  shardKey?: string;
150
74
  }
151
75
  interface UseMutationCallOptions<TCurrent = unknown, TValue = unknown, TArgs = unknown> {
@@ -1121,6 +1045,10 @@ declare const usePresence: <H extends HeartbeatReference, L extends ListPresentR
1121
1045
  * so an args object built in a different key order still dedupes). The
1122
1046
  * subscription registry shares a single WS subscription across every consumer
1123
1047
  * of the same queryKey; pushes call `queryClient.setQueryData(...)`.
1048
+ *
1049
+ * Pass `onError` to surface a subscription-scoped error the server pushes (an RLS
1050
+ * denial, a query that starts failing server-side). Without it such an error is
1051
+ * dropped and the returned value just freezes at its last good result.
1124
1052
  */
1125
1053
  declare const useQuery: <F extends FunctionReference>(function_: F, args: ArgsOf<F> | "skip", options?: UseQueryOptions) => ReturnOf<F> | undefined;
1126
1054
  interface UseRateLimitOptions {
@@ -1334,4 +1262,4 @@ interface UseVoiceAgentResult {
1334
1262
  * `createSocket`) so the hook is drivable outside a browser.
1335
1263
  */
1336
1264
  declare const useVoiceAgent: (options: UseVoiceAgentOptions) => UseVoiceAgentResult;
1337
- export { type ActionHook, type AdminAuthListResult, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, type AuthState, Authenticated, CheckoutButton, type CheckoutButtonProps, CustomerPortalButton, type CustomerPortalButtonProps, type FlagContext, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraProvider, type LunoraProviderProps, type MutationHook, type MutatorHook, type PageItemOf, type PaginatedArgs, type RedirectTarget, type RedirectTrigger, type Subscription, Unauthenticated, type UseAgentApi, type UseAgentChatApi, type UseAgentChatOptions, type UseAgentChatResult, type UseAgentOptions, type UseAgentResult, type UseAgentStateApi, type UseAgentStateOptions, type UseAgentStateResult, type UseAgentToolEventsApi, type UseAgentToolEventsOptions, type UseAgentToolEventsResult, type UseAuthResult, type UseAuthSessionsOptions, type UseAuthUsersOptions, type UseCheckoutResult, type UseHttpStreamOptions, type UseHttpStreamResult, type UseImpersonateResult, type UseInfiniteQueryOptions, type UseInfiniteQueryResult, type UseMutationCallOptions, type UseOrganizationsOptions, type UsePaginatedQueryOptions, type UsePaginatedQueryResult, type UsePresenceOptions, type UsePresenceResult, type UseQueryOptions, type UseRateLimitOptions, type UseRateLimitResult, type UseStreamOptions, type UseStreamResult, type UseStreamStatus, type UseSubscriptionResult, type UseVoiceAgentOptions, type UseVoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, hydratePreloaded, useAction, useAgent, useAgentChat, useAgentState, useAgentToolEvents, useAuth, useAuthSessions, useAuthState, useAuthUsers, useCheckout, useClientQuery, useConnectionStatus, useFlag, useFlags, useHttpStream, useImpersonate, useInfiniteQuery, useLunora, useMutation, useMutator, useOrganizations, usePaginatedQuery, usePreloadedQuery, usePresence, useQuery, useRateLimit, useStream, useSubscription, useVoiceAgent };
1265
+ export { type ActionHook, type AdminAuthListResult, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, type AuthState, Authenticated, type FlagContext, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraProvider, type LunoraProviderProps, type MutationHook, type MutatorHook, type PageItemOf, type PaginatedArgs, Unauthenticated, type UseAgentApi, type UseAgentChatApi, type UseAgentChatOptions, type UseAgentChatResult, type UseAgentOptions, type UseAgentResult, type UseAgentStateApi, type UseAgentStateOptions, type UseAgentStateResult, type UseAgentToolEventsApi, type UseAgentToolEventsOptions, type UseAgentToolEventsResult, type UseAuthResult, type UseAuthSessionsOptions, type UseAuthUsersOptions, type UseHttpStreamOptions, type UseHttpStreamResult, type UseImpersonateResult, type UseInfiniteQueryOptions, type UseInfiniteQueryResult, type UseMutationCallOptions, type UseOrganizationsOptions, type UsePaginatedQueryOptions, type UsePaginatedQueryResult, type UsePresenceOptions, type UsePresenceResult, type UseQueryOptions, type UseRateLimitOptions, type UseRateLimitResult, type UseStreamOptions, type UseStreamResult, type UseStreamStatus, type UseSubscriptionResult, type UseVoiceAgentOptions, type UseVoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, hydratePreloaded, useAction, useAgent, useAgentChat, useAgentState, useAgentToolEvents, useAuth, useAuthSessions, useAuthState, useAuthUsers, useClientQuery, useConnectionStatus, useFlag, useFlags, useHttpStream, useImpersonate, useInfiniteQuery, useLunora, useMutation, useMutator, useOrganizations, usePaginatedQuery, usePreloadedQuery, usePresence, useQuery, useRateLimit, useStream, useSubscription, useVoiceAgent };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ReactNode, ReactElement } from 'react';
2
- import { LunoraClient, OptimisticUpdate, User, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, AuthImpersonation, AuthSession, AuthUser, ClientQueryRef, ConnectionStatus, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, MutatorHandle, Preloaded } from '@lunora/client';
3
- export { type ArgsOf, type ClientQueryRef, type FunctionReference, type HttpStreamArgsOf, type HttpStreamChunkOf, type HttpStreamRef, type LunoraClient, type LunoraErrorCode, type MutatorHandle, type MutatorTransaction, type OptimisticLocalStore, type OptimisticUpdate, type Preloaded, type ReturnOf, type User, createClientQuery, getErrorCode, getRetryAfterMs, isConflictError, isForbiddenError, isRateLimitedError, isUnauthorizedError } from '@lunora/client';
2
+ import { LunoraClient, OptimisticUpdate, User, SubscriptionErrorCallback, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, AuthImpersonation, AuthSession, AuthUser, ClientQueryRef, ConnectionStatus, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, MutatorHandle, Preloaded } from '@lunora/client';
3
+ export { type ArgsOf, type AuthImpersonation, type AuthPage, type AuthSession, type AuthUser, type ClientQueryRef, type FunctionReference, type HttpStreamArgsOf, type HttpStreamChunkOf, type HttpStreamRef, type LunoraClient, type LunoraErrorCode, type MutatorHandle, type MutatorTransaction, type OptimisticLocalStore, type OptimisticUpdate, type Preloaded, type ReturnOf, type SubscriptionError, type SubscriptionErrorCallback, type User, createClientQuery, getErrorCode, getRetryAfterMs, isConflictError, isForbiddenError, isRateLimitedError, isUnauthorizedError } from '@lunora/client';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  export { type L as LunoraQueryOptions, l as lunoraQueryOptions } from "./packem_shared/query-options.d-CdgGQ9s4.js";
6
6
  import { PaginationStatus } from '@lunora/client/pagination';
@@ -63,89 +63,13 @@ declare const LunoraProvider: ({ children, client, queryClient }: LunoraProvider
63
63
  * colocated with the provider for back-compat.
64
64
  */
65
65
  declare const useLunora: () => LunoraClient;
66
- /**
67
- * Client-safe mirror of `@lunora/payment`'s `Subscription`. Re-declared here
68
- * (rather than imported) so this React entry never pulls in the server-only
69
- * `@lunora/payment` module graph — the kit stays React + DOM only. Keep this in
70
- * sync with `packages/payment/src/types.ts`.
71
- */
72
- interface Subscription {
73
- readonly cancelAtPeriodEnd: boolean;
74
- readonly createdAt: number;
75
- readonly currentPeriodEnd?: number;
76
- readonly id: string;
77
- readonly priceId: string;
78
- readonly provider: "polar" | "stripe";
79
- readonly quantity: number;
80
- readonly referenceId: string;
81
- readonly state: "active" | "canceled" | "past_due" | "paused" | "trialing";
82
- readonly updatedAt: number;
83
- }
84
- /** The `{ url }` shape every checkout/portal trigger resolves to. */
85
- interface RedirectTarget {
86
- readonly url: string;
87
- }
88
- /** A thunk the app supplies that calls its own Lunora action and resolves a redirect URL. */
89
- type RedirectTrigger = () => Promise<RedirectTarget>;
90
- interface UseCheckoutResult {
91
- /** Run the trigger and redirect the browser to the resolved URL. Resolves once the redirect is issued; rejects on failure. */
92
- checkout: () => Promise<void>;
93
- /** The most recent failure, or `undefined`. */
94
- error: Error | undefined;
95
- /** `true` while the trigger is in flight (before the redirect is issued). */
96
- pending: boolean;
97
- }
98
- /**
99
- * Decoupled redirect-on-resolve primitive shared by `CheckoutButton` and
100
- * `CustomerPortalButton`. The app passes a `trigger` thunk that calls its own
101
- * Lunora action (the one wrapping `LunoraPayment.createCheckout` /
102
- * `createPortalSession`) and resolves `{ url }`; this hook awaits it, flips
103
- * `pending`, surfaces any `error`, and on success navigates via
104
- * `location.assign(url)`.
105
- *
106
- * Mirrors Convex's `CheckoutLink` / `CustomerPortalLink` flow (trigger an action
107
- * that returns a URL, then redirect) while staying agnostic of the app's
108
- * function names.
109
- */
110
- declare const useCheckout: (trigger: RedirectTrigger) => UseCheckoutResult;
111
- /**
112
- * Presentational props shared by the redirect buttons. Kept to a curated set
113
- * (rather than spreading arbitrary button attributes) so the component stays
114
- * within the repo's `react/jsx-props-no-spreading` rule while covering the
115
- * common styling / accessibility hooks.
116
- */
117
- interface RedirectButtonOwnProps {
118
- /** Accessible label when the visible `children` are icon-only. */
119
- "aria-label"?: string;
120
- children?: ReactNode;
121
- className?: string;
122
- /** Force-disable the control regardless of pending state. */
123
- disabled?: boolean;
124
- /** Called with the failure when the trigger rejects. The error is also surfaced via `useCheckout`. */
125
- onError?: (error: Error) => void;
126
- title?: string;
127
- }
128
- interface CheckoutButtonProps extends RedirectButtonOwnProps {
129
- /** Calls the app's checkout action and resolves the hosted-checkout `{ url }`. */
130
- onCheckout: RedirectTrigger;
131
- }
132
- interface CustomerPortalButtonProps extends RedirectButtonOwnProps {
133
- /** Calls the app's portal action and resolves the customer-portal `{ url }`. */
134
- onPortal: RedirectTrigger;
135
- }
136
- /**
137
- * Button that starts a hosted checkout. On click it awaits `onCheckout` (a thunk
138
- * that calls the app's checkout action) and redirects to the returned URL,
139
- * disabling itself while the request is in flight.
140
- */
141
- declare const CheckoutButton: ({ onCheckout, ...rest }: CheckoutButtonProps) => ReactNode;
142
- /**
143
- * Button that opens the provider's customer portal. On click it awaits
144
- * `onPortal` (a thunk that calls the app's portal action) and redirects to the
145
- * returned URL, disabling itself while the request is in flight.
146
- */
147
- declare const CustomerPortalButton: ({ onPortal, ...rest }: CustomerPortalButtonProps) => ReactNode;
148
66
  interface UseQueryOptions {
67
+ /**
68
+ * Called when the server pushes a subscription-scoped error (an RLS denial, a
69
+ * query that starts failing server-side). Without a handler such an error has
70
+ * nowhere to go and the hook's value simply freezes at its last good result.
71
+ */
72
+ onError?: SubscriptionErrorCallback;
149
73
  shardKey?: string;
150
74
  }
151
75
  interface UseMutationCallOptions<TCurrent = unknown, TValue = unknown, TArgs = unknown> {
@@ -1121,6 +1045,10 @@ declare const usePresence: <H extends HeartbeatReference, L extends ListPresentR
1121
1045
  * so an args object built in a different key order still dedupes). The
1122
1046
  * subscription registry shares a single WS subscription across every consumer
1123
1047
  * of the same queryKey; pushes call `queryClient.setQueryData(...)`.
1048
+ *
1049
+ * Pass `onError` to surface a subscription-scoped error the server pushes (an RLS
1050
+ * denial, a query that starts failing server-side). Without it such an error is
1051
+ * dropped and the returned value just freezes at its last good result.
1124
1052
  */
1125
1053
  declare const useQuery: <F extends FunctionReference>(function_: F, args: ArgsOf<F> | "skip", options?: UseQueryOptions) => ReturnOf<F> | undefined;
1126
1054
  interface UseRateLimitOptions {
@@ -1334,4 +1262,4 @@ interface UseVoiceAgentResult {
1334
1262
  * `createSocket`) so the hook is drivable outside a browser.
1335
1263
  */
1336
1264
  declare const useVoiceAgent: (options: UseVoiceAgentOptions) => UseVoiceAgentResult;
1337
- export { type ActionHook, type AdminAuthListResult, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, type AuthState, Authenticated, CheckoutButton, type CheckoutButtonProps, CustomerPortalButton, type CustomerPortalButtonProps, type FlagContext, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraProvider, type LunoraProviderProps, type MutationHook, type MutatorHook, type PageItemOf, type PaginatedArgs, type RedirectTarget, type RedirectTrigger, type Subscription, Unauthenticated, type UseAgentApi, type UseAgentChatApi, type UseAgentChatOptions, type UseAgentChatResult, type UseAgentOptions, type UseAgentResult, type UseAgentStateApi, type UseAgentStateOptions, type UseAgentStateResult, type UseAgentToolEventsApi, type UseAgentToolEventsOptions, type UseAgentToolEventsResult, type UseAuthResult, type UseAuthSessionsOptions, type UseAuthUsersOptions, type UseCheckoutResult, type UseHttpStreamOptions, type UseHttpStreamResult, type UseImpersonateResult, type UseInfiniteQueryOptions, type UseInfiniteQueryResult, type UseMutationCallOptions, type UseOrganizationsOptions, type UsePaginatedQueryOptions, type UsePaginatedQueryResult, type UsePresenceOptions, type UsePresenceResult, type UseQueryOptions, type UseRateLimitOptions, type UseRateLimitResult, type UseStreamOptions, type UseStreamResult, type UseStreamStatus, type UseSubscriptionResult, type UseVoiceAgentOptions, type UseVoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, hydratePreloaded, useAction, useAgent, useAgentChat, useAgentState, useAgentToolEvents, useAuth, useAuthSessions, useAuthState, useAuthUsers, useCheckout, useClientQuery, useConnectionStatus, useFlag, useFlags, useHttpStream, useImpersonate, useInfiniteQuery, useLunora, useMutation, useMutator, useOrganizations, usePaginatedQuery, usePreloadedQuery, usePresence, useQuery, useRateLimit, useStream, useSubscription, useVoiceAgent };
1265
+ export { type ActionHook, type AdminAuthListResult, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, type AuthState, Authenticated, type FlagContext, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraProvider, type LunoraProviderProps, type MutationHook, type MutatorHook, type PageItemOf, type PaginatedArgs, Unauthenticated, type UseAgentApi, type UseAgentChatApi, type UseAgentChatOptions, type UseAgentChatResult, type UseAgentOptions, type UseAgentResult, type UseAgentStateApi, type UseAgentStateOptions, type UseAgentStateResult, type UseAgentToolEventsApi, type UseAgentToolEventsOptions, type UseAgentToolEventsResult, type UseAuthResult, type UseAuthSessionsOptions, type UseAuthUsersOptions, type UseHttpStreamOptions, type UseHttpStreamResult, type UseImpersonateResult, type UseInfiniteQueryOptions, type UseInfiniteQueryResult, type UseMutationCallOptions, type UseOrganizationsOptions, type UsePaginatedQueryOptions, type UsePaginatedQueryResult, type UsePresenceOptions, type UsePresenceResult, type UseQueryOptions, type UseRateLimitOptions, type UseRateLimitResult, type UseStreamOptions, type UseStreamResult, type UseStreamStatus, type UseSubscriptionResult, type UseVoiceAgentOptions, type UseVoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, hydratePreloaded, useAction, useAgent, useAgentChat, useAgentState, useAgentToolEvents, useAuth, useAuthSessions, useAuthState, useAuthUsers, useClientQuery, useConnectionStatus, useFlag, useFlags, useHttpStream, useImpersonate, useInfiniteQuery, useLunora, useMutation, useMutator, useOrganizations, usePaginatedQuery, usePreloadedQuery, usePresence, useQuery, useRateLimit, useStream, useSubscription, useVoiceAgent };
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  'use client';
2
- import{AuthLoading as o,Authenticated as t,Unauthenticated as u}from"./packem_shared/AuthLoading-dC08yqew.mjs";import{useAuthState as a}from"./packem_shared/useAuthState-CoOG9XdT.mjs";import{LunoraProvider as f,useLunora as n}from"./packem_shared/LunoraProvider-DC06S-p1.mjs";import{CheckoutButton as i,CustomerPortalButton as d,useCheckout as x}from"./packem_shared/CheckoutButton-D8MutXhg.mjs";import{lunoraQueryOptions as h}from"./packem_shared/lunoraQueryOptions-B5PEocLy.mjs";import{useAction as c}from"./packem_shared/useAction-CUSJu4yq.mjs";import{useAuthSessions as C,useAuthUsers as U,useImpersonate as y,useOrganizations as E}from"./packem_shared/useAuthSessions-Bq4-f3g-.mjs";import{useAgent as Q}from"./packem_shared/useAgent-BtmvbOfx.mjs";import{useAgentChat as L}from"./packem_shared/useAgentChat-CYdAxCn5.mjs";import{useAgentState as F}from"./packem_shared/useAgentState-CxeO0Nzo.mjs";import{useAgentToolEvents as k}from"./packem_shared/useAgentToolEvents-MfR_4MA_.mjs";import{default as b}from"./packem_shared/useAuth-x4boOoAR.mjs";import{default as z}from"./packem_shared/useClientQuery-DFs7trEf.mjs";import{default as O}from"./packem_shared/useConnectionStatus-XYsYGiT6.mjs";import{useFlag as H,useFlags as V}from"./packem_shared/useFlag-HLt4Xzmd.mjs";import{useHttpStream as q}from"./packem_shared/useHttpStream-D9vum8Qx.mjs";import{default as D}from"./packem_shared/useInfiniteQuery-DDYp2Df1.mjs";import{useMutation as J}from"./packem_shared/useMutation-BnKec7bE.mjs";import{useMutator as N}from"./packem_shared/useMutator-BtUd-xEA.mjs";import{usePaginatedQuery as X}from"./packem_shared/usePaginatedQuery-B3Q7mppN.mjs";import{hydratePreloaded as Z,default as _}from"./packem_shared/hydratePreloaded-D6ZG10Q7.mjs";import{usePresence as ee}from"./packem_shared/usePresence-DsYEO_XX.mjs";import{default as oe}from"./packem_shared/useQuery-BIkNc_t1.mjs";import{useRateLimit as ue}from"./packem_shared/useRateLimit-Cckxi8m9.mjs";import{useStream as ae}from"./packem_shared/useStream-CmGOT0qj.mjs";import{default as fe}from"./packem_shared/useSubscription-BXhI6J-f.mjs";import{useVoiceAgent as me}from"./packem_shared/useVoiceAgent-BziH3D-1.mjs";import{createClientQuery as de,getErrorCode as xe,getRetryAfterMs as le,isConflictError as he,isForbiddenError as Ae,isRateLimitedError as ce,isUnauthorizedError as ge}from"@lunora/client";import{RestrictionError as Ue,UploadControl as ye,UploadError as Ee}from"@visulima/storage-client";import{useChunkedRestUpload as Qe,useFileInput as Se,useMultipartUpload as Le,usePasteUpload as Re,useTusUpload as Fe,useUpload as Me}from"@visulima/storage-client/react";export{o as AuthLoading,t as Authenticated,i as CheckoutButton,d as CustomerPortalButton,f as LunoraProvider,Ue as RestrictionError,u as Unauthenticated,ye as UploadControl,Ee as UploadError,de as createClientQuery,xe as getErrorCode,le as getRetryAfterMs,Z as hydratePreloaded,he as isConflictError,Ae as isForbiddenError,ce as isRateLimitedError,ge as isUnauthorizedError,h as lunoraQueryOptions,c as useAction,Q as useAgent,L as useAgentChat,F as useAgentState,k as useAgentToolEvents,b as useAuth,C as useAuthSessions,a as useAuthState,U as useAuthUsers,x as useCheckout,Qe as useChunkedRestUpload,z as useClientQuery,O as useConnectionStatus,Se as useFileInput,H as useFlag,V as useFlags,q as useHttpStream,y as useImpersonate,D as useInfiniteQuery,n as useLunora,Le as useMultipartUpload,J as useMutation,N as useMutator,E as useOrganizations,X as usePaginatedQuery,Re as usePasteUpload,_ as usePreloadedQuery,ee as usePresence,oe as useQuery,ue as useRateLimit,ae as useStream,fe as useSubscription,Fe as useTusUpload,Me as useUpload,me as useVoiceAgent};
2
+ import{AuthLoading as o,Authenticated as t,Unauthenticated as u}from"./packem_shared/AuthLoading-dC08yqew.mjs";import{useAuthState as a}from"./packem_shared/useAuthState-CoOG9XdT.mjs";import{LunoraProvider as f,useLunora as n}from"./packem_shared/LunoraProvider-DC06S-p1.mjs";import{lunoraQueryOptions as m}from"./packem_shared/lunoraQueryOptions-B5PEocLy.mjs";import{useAction as x}from"./packem_shared/useAction-CUSJu4yq.mjs";import{useAuthSessions as A,useAuthUsers as g,useImpersonate as h,useOrganizations as c}from"./packem_shared/useAuthSessions-Bq4-f3g-.mjs";import{useAgent as y}from"./packem_shared/useAgent-BtmvbOfx.mjs";import{useAgentChat as E}from"./packem_shared/useAgentChat-PSWHsc8L.mjs";import{useAgentState as S}from"./packem_shared/useAgentState-CxeO0Nzo.mjs";import{useAgentToolEvents as L}from"./packem_shared/useAgentToolEvents-MfR_4MA_.mjs";import{default as F}from"./packem_shared/useAuth-x4boOoAR.mjs";import{default as I}from"./packem_shared/useClientQuery-DFs7trEf.mjs";import{default as v}from"./packem_shared/useConnectionStatus-XYsYGiT6.mjs";import{useFlag as O,useFlags as T}from"./packem_shared/useFlag-BFNfCLq3.mjs";import{useHttpStream as H}from"./packem_shared/useHttpStream-D9vum8Qx.mjs";import{default as j}from"./packem_shared/useInfiniteQuery-JrM8Gv4A.mjs";import{useMutation as w}from"./packem_shared/useMutation-BnKec7bE.mjs";import{useMutator as D}from"./packem_shared/useMutator-BtUd-xEA.mjs";import{usePaginatedQuery as J}from"./packem_shared/usePaginatedQuery-f-GjDA-g.mjs";import{hydratePreloaded as N,default as W}from"./packem_shared/hydratePreloaded-D_NlgGV_.mjs";import{usePresence as Y}from"./packem_shared/usePresence-DsYEO_XX.mjs";import{default as _}from"./packem_shared/useQuery-HeFPuRVz.mjs";import{useRateLimit as ee}from"./packem_shared/useRateLimit-Cckxi8m9.mjs";import{useStream as oe}from"./packem_shared/useStream-CmGOT0qj.mjs";import{default as ue}from"./packem_shared/useSubscription-BXhI6J-f.mjs";import{useVoiceAgent as ae}from"./packem_shared/useVoiceAgent-BziH3D-1.mjs";import{createClientQuery as fe,getErrorCode as ne,getRetryAfterMs as ie,isConflictError as me,isForbiddenError as de,isRateLimitedError as xe,isUnauthorizedError as le}from"@lunora/client";import{RestrictionError as ge,UploadControl as he,UploadError as ce}from"@visulima/storage-client";import{useChunkedRestUpload as ye,useFileInput as Ce,useMultipartUpload as Ee,usePasteUpload as Qe,useTusUpload as Se,useUpload as Pe}from"@visulima/storage-client/react";export{o as AuthLoading,t as Authenticated,f as LunoraProvider,ge as RestrictionError,u as Unauthenticated,he as UploadControl,ce as UploadError,fe as createClientQuery,ne as getErrorCode,ie as getRetryAfterMs,N as hydratePreloaded,me as isConflictError,de as isForbiddenError,xe as isRateLimitedError,le as isUnauthorizedError,m as lunoraQueryOptions,x as useAction,y as useAgent,E as useAgentChat,S as useAgentState,L as useAgentToolEvents,F as useAuth,A as useAuthSessions,a as useAuthState,g as useAuthUsers,ye as useChunkedRestUpload,I as useClientQuery,v as useConnectionStatus,Ce as useFileInput,O as useFlag,T as useFlags,H as useHttpStream,h as useImpersonate,j as useInfiniteQuery,n as useLunora,Ee as useMultipartUpload,w as useMutation,D as useMutator,c as useOrganizations,J as usePaginatedQuery,Qe as usePasteUpload,W as usePreloadedQuery,Y as usePresence,_ as useQuery,ee as useRateLimit,oe as useStream,ue as useSubscription,Se as useTusUpload,Pe as useUpload,ae as useVoiceAgent};
@@ -0,0 +1 @@
1
+ import{k as u}from"./query-key-C6iUhRuD.mjs";class k{constructor(e){this.client=e}client;entries=new Map;keyOf(e){return u(e)}attach(e,o,b,h,p,l={}){const i=u(o);let t=this.entries.get(i);if(!t){t={errorCallbacks:new Set,pollTimer:void 0,refCount:0,unsubscribe:void 0},this.entries.set(i,t);const r=t;try{t.unsubscribe=this.client.subscribe(b,h,a=>{e.setQueryData(o,a)},{onError:a=>{for(const d of r.errorCallbacks)d(a)},shardKey:p})}catch{t.pollTimer=setInterval(()=>{e.invalidateQueries({queryKey:o}).catch(()=>{})},l.pollIntervalMs??5e3)}}t.refCount+=1;const{onError:n}=l;n&&t.errorCallbacks.add(n);let c=!1;return()=>{if(c)return;c=!0;const r=this.entries.get(i);r&&(r.refCount-=1,n&&r.errorCallbacks.delete(n),r.refCount<=0&&(r.unsubscribe?.(),r.pollTimer&&clearInterval(r.pollTimer),this.entries.delete(i)))}}}const f=new WeakMap,C=s=>{let e=f.get(s);return e||(e=new k(s),f.set(s,e)),e};export{C as g};
@@ -1,2 +1,2 @@
1
1
  'use client';
2
- import{c as m}from"react/compiler-runtime";import{useQueryClient as d,useQuery as p}from"@tanstack/react-query";import{useEffect as g}from"react";import{g as I}from"./cache-I4w1R5RF.mjs";import{useLunora as Q}from"./LunoraProvider-DC06S-p1.mjs";import{l as h,s as q}from"./query-key-C6iUhRuD.mjs";const K=function(n){const e=m(4),t=Q(),r=d(),{args:s,functionPath:l,shardKey:u,value:y}=n,i={__lunoraRef:l},a=h(i,s,u),{data:f}=p({initialData:y,queryFn:()=>t.query(i,s,{shardKey:u}),queryKey:a,staleTime:Number.POSITIVE_INFINITY}),c=q(a);let o;return e[0]!==t||e[1]!==r||e[2]!==c?(o=[t,r,c],e[0]=t,e[1]=r,e[2]=c,e[3]=o):o=e[3],g(()=>I(t).attach(r,a,i,s,u),o),f===void 0?y:f},C=function(n){return K(n)};export{K as default,C as hydratePreloaded};
2
+ import{c as m}from"react/compiler-runtime";import{useQueryClient as d,useQuery as p}from"@tanstack/react-query";import{useEffect as g}from"react";import{g as I}from"./cache-BuILe2dy.mjs";import{useLunora as Q}from"./LunoraProvider-DC06S-p1.mjs";import{l as h,s as q}from"./query-key-C6iUhRuD.mjs";const K=function(n){const e=m(4),t=Q(),r=d(),{args:s,functionPath:l,shardKey:u,value:y}=n,i={__lunoraRef:l},a=h(i,s,u),{data:f}=p({initialData:y,queryFn:()=>t.query(i,s,{shardKey:u}),queryKey:a,staleTime:Number.POSITIVE_INFINITY}),c=q(a);let o;return e[0]!==t||e[1]!==r||e[2]!==c?(o=[t,r,c],e[0]=t,e[1]=r,e[2]=c,e[3]=o):o=e[3],g(()=>I(t).attach(r,a,i,s,u),o),f===void 0?y:f},C=function(n){return K(n)};export{K as default,C as hydratePreloaded};
@@ -1,2 +1,2 @@
1
1
  'use client';
2
- import{initialPages as M,rebalance as D,derivePaginationStatus as A,applyLoadMore as E}from"@lunora/client/pagination";import{useQueryClient as O}from"@tanstack/react-query";import{useRef as m,useReducer as _,useState as $,useEffect as d,useCallback as j}from"react";import{g as H}from"./cache-I4w1R5RF.mjs";import{useLunora as N}from"./LunoraProvider-DC06S-p1.mjs";import{s as i,l as q}from"./query-key-C6iUhRuD.mjs";const T=function(o){const f=m(void 0);return f.current??=o(),f},Y=function(o,f,L){const a=N(),n=O(),{initialNumItems:g,shardKey:l}=L,c=f==="skip",p=c?{}:f,[,P]=_(e=>e+1,0),[v,K]=$(()=>M(g)),b=`${i(q(o,p,l))}::${String(g)}`,S=m(b);S.current!==b&&(S.current=b,K(M(g)));const h=v.map(e=>{const s={...p,paginationOpts:{cursor:e.lower,endCursor:e.upper,numItems:e.numItems}},r=q(o,s,l);return{args:s,key:r}}),w=h.map(({key:e})=>i(e)).join("|"),k=m({baseArgs:p,entries:[],fn:o,shardKey:l});d(()=>{k.current={baseArgs:p,entries:h,fn:o,shardKey:l}});const C=T(()=>new Map),I=m(a);d(()=>{const e=C.current;if(I.current!==a){for(const t of e.values())t();e.clear(),I.current=a}if(c){for(const t of e.values())t();e.clear();return}const s=k.current,r=H(a),y=new Set(s.entries.map(({key:t})=>i(t)));for(const[t,u]of e)y.has(t)||(u(),e.delete(t));for(const t of s.entries){const u=i(t.key);if(e.has(u))continue;n.fetchQuery({queryFn:()=>a.query(s.fn,t.args,{shardKey:s.shardKey}),queryKey:t.key,staleTime:0}).catch(()=>{}),e.set(u,r.attach(n,t.key,s.fn,t.args,s.shardKey))}},[a,n,w,c]),d(()=>()=>{for(const e of C.current.values())e();C.current.clear()},[]),d(()=>n.getQueryCache().subscribe(r=>{if(r.type!=="updated")return;const y=i(r.query.queryKey);h.some(({key:t})=>i(t)===y)&&P()}),[n,w]);const R=c?[]:h.map(({key:e})=>n.getQueryData(e));d(()=>{if(c)return;const e=D(v,R);e&&K(e)});const{status:x}=A(c,R);return{loadMore:j(e=>{K(s=>{const r=k.current,y=s.map(Q=>{const z={...r.baseArgs,paginationOpts:{cursor:Q.lower,endCursor:Q.upper,numItems:Q.numItems}};return n.getQueryData(q(r.fn,z,r.shardKey))}),{nextCursor:t,status:u}=A(!1,y);return E(s,u==="CanLoadMore"?t:void 0,e)??s})},[n]),pageResults:R,status:x}};export{Y as u};
2
+ import{initialPages as M,rebalance as D,derivePaginationStatus as A,applyLoadMore as E}from"@lunora/client/pagination";import{useQueryClient as O}from"@tanstack/react-query";import{useRef as m,useReducer as _,useState as $,useEffect as d,useCallback as j}from"react";import{g as H}from"./cache-BuILe2dy.mjs";import{useLunora as N}from"./LunoraProvider-DC06S-p1.mjs";import{s as i,l as q}from"./query-key-C6iUhRuD.mjs";const T=function(o){const f=m(void 0);return f.current??=o(),f},Y=function(o,f,L){const a=N(),n=O(),{initialNumItems:g,shardKey:l}=L,c=f==="skip",p=c?{}:f,[,P]=_(e=>e+1,0),[v,K]=$(()=>M(g)),b=`${i(q(o,p,l))}::${String(g)}`,S=m(b);S.current!==b&&(S.current=b,K(M(g)));const h=v.map(e=>{const s={...p,paginationOpts:{cursor:e.lower,endCursor:e.upper,numItems:e.numItems}},r=q(o,s,l);return{args:s,key:r}}),w=h.map(({key:e})=>i(e)).join("|"),k=m({baseArgs:p,entries:[],fn:o,shardKey:l});d(()=>{k.current={baseArgs:p,entries:h,fn:o,shardKey:l}});const C=T(()=>new Map),I=m(a);d(()=>{const e=C.current;if(I.current!==a){for(const t of e.values())t();e.clear(),I.current=a}if(c){for(const t of e.values())t();e.clear();return}const s=k.current,r=H(a),y=new Set(s.entries.map(({key:t})=>i(t)));for(const[t,u]of e)y.has(t)||(u(),e.delete(t));for(const t of s.entries){const u=i(t.key);if(e.has(u))continue;n.fetchQuery({queryFn:()=>a.query(s.fn,t.args,{shardKey:s.shardKey}),queryKey:t.key,staleTime:0}).catch(()=>{}),e.set(u,r.attach(n,t.key,s.fn,t.args,s.shardKey))}},[a,n,w,c]),d(()=>()=>{for(const e of C.current.values())e();C.current.clear()},[]),d(()=>n.getQueryCache().subscribe(r=>{if(r.type!=="updated")return;const y=i(r.query.queryKey);h.some(({key:t})=>i(t)===y)&&P()}),[n,w]);const R=c?[]:h.map(({key:e})=>n.getQueryData(e));d(()=>{if(c)return;const e=D(v,R);e&&K(e)});const{status:x}=A(c,R);return{loadMore:j(e=>{K(s=>{const r=k.current,y=s.map(Q=>{const z={...r.baseArgs,paginationOpts:{cursor:Q.lower,endCursor:Q.upper,numItems:Q.numItems}};return n.getQueryData(q(r.fn,z,r.shardKey))}),{nextCursor:t,status:u}=A(!1,y);return E(s,u==="CanLoadMore"?t:void 0,e)??s})},[n]),pageResults:R,status:x}};export{Y as u};
@@ -0,0 +1,2 @@
1
+ 'use client';
2
+ import{reconcileOptimistic as y,maxSeq as M}from"@lunora/client";import{useState as H,useRef as R}from"react";import{useMutation as u}from"./useMutation-BnKec7bE.mjs";import{useStream as J}from"./useStream-CmGOT0qj.mjs";import S from"./useSubscription-BXhI6J-f.mjs";const L={__lunoraRef:""},Q={__lunoraRef:""},V=[],ot=A=>{const{api:r,cancel:m,limit:d,send:_,sendArgs:k,stream:l,threadKey:e}=A,x=d===void 0?{key:e}:{key:e,limit:d},{data:E}=S(r.agents.agentMessages,x),{data:w}=S(r.agents.agentThread,{key:e}),O=l===void 0?"skip":{key:e},{chunks:T}=J(l??Q,O),b=u(_),I=u(m??L),j=u(r.agents.agentResolveApproval),[q,c]=H([]),p=R(0),f=R(e);f.current!==e&&(f.current=e,c([]));const g=w,C=g?.status,o=g?.instanceId,s=E??V,h=y(q,s),D=M(s),K=h.length===0?s:[...s,...h.map((t,n)=>({content:t.content,optimistic:!0,role:"user",seq:D+1+n}))],N=s.filter(t=>t.role==="assistant").length,F=T.filter(t=>t.kind!=="progress"&&t.threadKey===e&&t.turn>=N).map(t=>t.text).join(""),{mutate:G}=b,{mutate:P}=I,{mutate:U}=j,Y=async(t,n)=>{const a=p.current;p.current+=1;const $=M(s);c(i=>[...y(i,s),{content:t,id:a,maxDurableSeqAtSend:$}]);try{await G({input:t,threadKey:e,...k,...n})}catch(i){throw c(z=>z.filter(B=>B.id!==a)),i}},v=async(t,n,a)=>{if(o===void 0)throw new Error(`useAgentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await U({decision:t,instanceId:o,threadKey:e,toolCallId:n,...a===void 0?{}:{note:a}})};return{approve:(t,n)=>v("approve",t,n),cancel:async()=>{m===void 0||o===void 0||await P({instanceId:o,threadKey:e})},messages:K,reject:(t,n)=>v("reject",t,n),send:Y,status:C,streamingText:F}};export{ot as useAgentChat};
@@ -0,0 +1,2 @@
1
+ 'use client';
2
+ import{useState as x,useRef as p,useEffect as _}from"react";import{useLunora as F}from"./LunoraProvider-DC06S-p1.mjs";import{s as v}from"./stable-key-B_BlboiY.mjs";const A="__lunora_flags__:eval",K=t=>{const e=typeof t;return e==="boolean"||e==="number"||e==="string"?e:"object"},E={__lunoraRef:A},R=(t,e,r)=>{try{return t.subscribe(E,{context:e.context,default:e.default,key:e.key,type:K(e.default)},n=>{r(n)},{onError:()=>{r(e.default)}})}catch{return()=>{}}},h=(t,e,r)=>{const n=F(),[l,s]=x(e),f=K(e),c=r===void 0?"":v(r),o=`${t}::${f}::${c}`,i=p(o);i.current!==o&&(i.current=o,s(e));const a=p({context:r,defaultValue:e});return _(()=>{a.current={context:r,defaultValue:e}}),_(()=>{let d=!1;const{context:y,defaultValue:b}=a.current;s(b);const u=R(n,{context:y,default:b,key:t},m=>{d||s(m)});return()=>{d=!0,u()}},[n,t,f,c]),l},j=(t,e)=>{const r=F(),[n,l]=x(t),s=v(t),f=e===void 0?"":v(e),c=`${s}::${f}`,o=p(c);o.current!==c&&(o.current=c,l(t));const i=p({context:e,flags:t});return _(()=>{i.current={context:e,flags:t}}),_(()=>{let a=!1;const{context:d,flags:y}=i.current;l(y);const b=[];for(const[u,m]of Object.entries(y))b.push(R(r,{context:d,default:m,key:u},$=>{a||l(C=>({...C,[u]:$}))}));return()=>{a=!0;for(const u of b)u()}},[r,s,f]),n};export{h as useFlag,j as useFlags};
@@ -1,2 +1,2 @@
1
1
  'use client';
2
- import{c as L}from"react/compiler-runtime";import{useRef as M,useEffect as R}from"react";import{u as y}from"./use-paginated-core-D7U-wwgW.mjs";const b=(h,c,g)=>{const e=L(15),{initialNumItems:s}=g,{loadMore:o,pageResults:u,status:a}=y(h,c==="skip"?"skip":c,g),N=c==="skip";let t;if(e[0]!==u){t=[];for(const f of u)f&&t.push(f.page);e[0]=u,e[1]=t}else t=e[1];let i;e[2]!==s||e[3]!==o?(i={defaultNumItems:s,loadMore:o},e[2]=s,e[3]=o,e[4]=i):i=e[4];const P=M(i);let n;e[5]!==s||e[6]!==o?(n=()=>{P.current={defaultNumItems:s,loadMore:o}},e[5]=s,e[6]=o,e[7]=n):n=e[7],R(n);let l;e[8]===Symbol.for("react.memo_cache_sentinel")?(l=f=>{const{defaultNumItems:I,loadMore:k}=P.current;k(f??I)},e[8]=l):l=e[8];const x=l,m=a==="CanLoadMore",d=!N&&a==="LoadingMore",p=!N&&a==="LoadingFirstPage";let r;return e[9]!==t||e[10]!==a||e[11]!==m||e[12]!==d||e[13]!==p?(r={fetchNextPage:x,hasNextPage:m,isFetchingNextPage:d,isLoading:p,pages:t,status:a},e[9]=t,e[10]=a,e[11]=m,e[12]=d,e[13]=p,e[14]=r):r=e[14],r};export{b as default};
2
+ import{c as L}from"react/compiler-runtime";import{useRef as M,useEffect as R}from"react";import{u as y}from"./use-paginated-core-Lu50LpUb.mjs";const b=(h,c,g)=>{const e=L(15),{initialNumItems:s}=g,{loadMore:o,pageResults:u,status:a}=y(h,c==="skip"?"skip":c,g),N=c==="skip";let t;if(e[0]!==u){t=[];for(const f of u)f&&t.push(f.page);e[0]=u,e[1]=t}else t=e[1];let i;e[2]!==s||e[3]!==o?(i={defaultNumItems:s,loadMore:o},e[2]=s,e[3]=o,e[4]=i):i=e[4];const P=M(i);let n;e[5]!==s||e[6]!==o?(n=()=>{P.current={defaultNumItems:s,loadMore:o}},e[5]=s,e[6]=o,e[7]=n):n=e[7],R(n);let l;e[8]===Symbol.for("react.memo_cache_sentinel")?(l=f=>{const{defaultNumItems:I,loadMore:k}=P.current;k(f??I)},e[8]=l):l=e[8];const x=l,m=a==="CanLoadMore",d=!N&&a==="LoadingMore",p=!N&&a==="LoadingFirstPage";let r;return e[9]!==t||e[10]!==a||e[11]!==m||e[12]!==d||e[13]!==p?(r={fetchNextPage:x,hasNextPage:m,isFetchingNextPage:d,isLoading:p,pages:t,status:a},e[9]=t,e[10]=a,e[11]=m,e[12]=d,e[13]=p,e[14]=r):r=e[14],r};export{b as default};
@@ -1,2 +1,2 @@
1
1
  'use client';
2
- import{c as l}from"react/compiler-runtime";import{u as c}from"./use-paginated-core-D7U-wwgW.mjs";const m=(u,i,d)=>{const e=l(7),{loadMore:p,pageResults:r,status:t}=c(u,i==="skip"?"skip":i,d);let s;if(e[0]!==r){s=[];for(const a of r)a&&s.push(...a.page);e[0]=r,e[1]=s}else s=e[1];const n=!(i==="skip")&&(t==="LoadingFirstPage"||t==="LoadingMore");let o;return e[2]!==p||e[3]!==s||e[4]!==t||e[5]!==n?(o={isLoading:n,loadMore:p,results:s,status:t},e[2]=p,e[3]=s,e[4]=t,e[5]=n,e[6]=o):o=e[6],o};export{m as usePaginatedQuery};
2
+ import{c as l}from"react/compiler-runtime";import{u as c}from"./use-paginated-core-Lu50LpUb.mjs";const m=(u,i,d)=>{const e=l(7),{loadMore:p,pageResults:r,status:t}=c(u,i==="skip"?"skip":i,d);let s;if(e[0]!==r){s=[];for(const a of r)a&&s.push(...a.page);e[0]=r,e[1]=s}else s=e[1];const n=!(i==="skip")&&(t==="LoadingFirstPage"||t==="LoadingMore");let o;return e[2]!==p||e[3]!==s||e[4]!==t||e[5]!==n?(o={isLoading:n,loadMore:p,results:s,status:t},e[2]=p,e[3]=s,e[4]=t,e[5]=n,e[6]=o):o=e[6],o};export{m as usePaginatedQuery};
@@ -0,0 +1,2 @@
1
+ 'use client';
2
+ import{useQueryClient as h,useQuery as E}from"@tanstack/react-query";import{useRef as b,useEffect as n,useCallback as g,useState as I}from"react";import{g as k}from"./cache-BuILe2dy.mjs";import{useLunora as q}from"./LunoraProvider-DC06S-p1.mjs";import{l as K,s as C}from"./query-key-C6iUhRuD.mjs";const F=(t,i,p={})=>{const e=q(),y=h(),{onError:c,shardKey:s}=p,d=b(c);n(()=>{d.current=c});const l=g(m=>{d.current?.(m)},[]),r=i==="skip",o=r?{}:i,a=K(t,o,s),[u,f]=I(e.isReady);n(()=>{u||e.whenReady().then(()=>{f(!0)})},[e,u]);const Q=r?void 0:e.peekHydratedQuery(t.__lunoraRef,o,s),{data:R}=E({enabled:!r&&u,initialData:Q,queryFn:()=>e.query(t,o,{shardKey:s}),queryKey:a,staleTime:Number.POSITIVE_INFINITY});return n(()=>r?()=>{}:k(e).attach(y,a,t,o,s,{onError:l}),[e,y,C(a),r,l]),r?void 0:R};export{F as default};
@@ -0,0 +1,84 @@
1
+ import { ReactNode } from 'react';
2
+ /**
3
+ * Client-safe mirror of `@lunora/payment`'s `Subscription`. Re-declared here
4
+ * (rather than imported) so this React entry never pulls in the server-only
5
+ * `@lunora/payment` module graph — the kit stays React + DOM only. Keep this in
6
+ * sync with `packages/payment/src/types.ts`.
7
+ */
8
+ interface Subscription {
9
+ readonly cancelAtPeriodEnd: boolean;
10
+ readonly createdAt: number;
11
+ readonly currentPeriodEnd?: number;
12
+ readonly id: string;
13
+ readonly priceId: string;
14
+ readonly provider: "polar" | "stripe";
15
+ readonly quantity: number;
16
+ readonly referenceId: string;
17
+ readonly state: "active" | "canceled" | "past_due" | "paused" | "trialing";
18
+ readonly updatedAt: number;
19
+ }
20
+ /** The `{ url }` shape every checkout/portal trigger resolves to. */
21
+ interface RedirectTarget {
22
+ readonly url: string;
23
+ }
24
+ /** A thunk the app supplies that calls its own Lunora action and resolves a redirect URL. */
25
+ type RedirectTrigger = () => Promise<RedirectTarget>;
26
+ interface UseCheckoutResult {
27
+ /** Run the trigger and redirect the browser to the resolved URL. Resolves once the redirect is issued; rejects on failure. */
28
+ checkout: () => Promise<void>;
29
+ /** The most recent failure, or `undefined`. */
30
+ error: Error | undefined;
31
+ /** `true` while the trigger is in flight (before the redirect is issued). */
32
+ pending: boolean;
33
+ }
34
+ /**
35
+ * Decoupled redirect-on-resolve primitive shared by `CheckoutButton` and
36
+ * `CustomerPortalButton`. The app passes a `trigger` thunk that calls its own
37
+ * Lunora action (the one wrapping `LunoraPayment.createCheckout` /
38
+ * `createPortalSession`) and resolves `{ url }`; this hook awaits it, flips
39
+ * `pending`, surfaces any `error`, and on success navigates via
40
+ * `location.assign(url)`.
41
+ *
42
+ * Mirrors Convex's `CheckoutLink` / `CustomerPortalLink` flow (trigger an action
43
+ * that returns a URL, then redirect) while staying agnostic of the app's
44
+ * function names.
45
+ */
46
+ declare const useCheckout: (trigger: RedirectTrigger) => UseCheckoutResult;
47
+ /**
48
+ * Presentational props shared by the redirect buttons. Kept to a curated set
49
+ * (rather than spreading arbitrary button attributes) so the component stays
50
+ * within the repo's `react/jsx-props-no-spreading` rule while covering the
51
+ * common styling / accessibility hooks.
52
+ */
53
+ interface RedirectButtonOwnProps {
54
+ /** Accessible label when the visible `children` are icon-only. */
55
+ "aria-label"?: string;
56
+ children?: ReactNode;
57
+ className?: string;
58
+ /** Force-disable the control regardless of pending state. */
59
+ disabled?: boolean;
60
+ /** Called with the failure when the trigger rejects. The error is also surfaced via `useCheckout`. */
61
+ onError?: (error: Error) => void;
62
+ title?: string;
63
+ }
64
+ interface CheckoutButtonProps extends RedirectButtonOwnProps {
65
+ /** Calls the app's checkout action and resolves the hosted-checkout `{ url }`. */
66
+ onCheckout: RedirectTrigger;
67
+ }
68
+ interface CustomerPortalButtonProps extends RedirectButtonOwnProps {
69
+ /** Calls the app's portal action and resolves the customer-portal `{ url }`. */
70
+ onPortal: RedirectTrigger;
71
+ }
72
+ /**
73
+ * Button that starts a hosted checkout. On click it awaits `onCheckout` (a thunk
74
+ * that calls the app's checkout action) and redirects to the returned URL,
75
+ * disabling itself while the request is in flight.
76
+ */
77
+ declare const CheckoutButton: ({ onCheckout, ...rest }: CheckoutButtonProps) => ReactNode;
78
+ /**
79
+ * Button that opens the provider's customer portal. On click it awaits
80
+ * `onPortal` (a thunk that calls the app's portal action) and redirects to the
81
+ * returned URL, disabling itself while the request is in flight.
82
+ */
83
+ declare const CustomerPortalButton: ({ onPortal, ...rest }: CustomerPortalButtonProps) => ReactNode;
84
+ export { CheckoutButton, type CheckoutButtonProps, CustomerPortalButton, type CustomerPortalButtonProps, type RedirectTarget, type RedirectTrigger, type Subscription, type UseCheckoutResult, useCheckout };
@@ -0,0 +1,84 @@
1
+ import { ReactNode } from 'react';
2
+ /**
3
+ * Client-safe mirror of `@lunora/payment`'s `Subscription`. Re-declared here
4
+ * (rather than imported) so this React entry never pulls in the server-only
5
+ * `@lunora/payment` module graph — the kit stays React + DOM only. Keep this in
6
+ * sync with `packages/payment/src/types.ts`.
7
+ */
8
+ interface Subscription {
9
+ readonly cancelAtPeriodEnd: boolean;
10
+ readonly createdAt: number;
11
+ readonly currentPeriodEnd?: number;
12
+ readonly id: string;
13
+ readonly priceId: string;
14
+ readonly provider: "polar" | "stripe";
15
+ readonly quantity: number;
16
+ readonly referenceId: string;
17
+ readonly state: "active" | "canceled" | "past_due" | "paused" | "trialing";
18
+ readonly updatedAt: number;
19
+ }
20
+ /** The `{ url }` shape every checkout/portal trigger resolves to. */
21
+ interface RedirectTarget {
22
+ readonly url: string;
23
+ }
24
+ /** A thunk the app supplies that calls its own Lunora action and resolves a redirect URL. */
25
+ type RedirectTrigger = () => Promise<RedirectTarget>;
26
+ interface UseCheckoutResult {
27
+ /** Run the trigger and redirect the browser to the resolved URL. Resolves once the redirect is issued; rejects on failure. */
28
+ checkout: () => Promise<void>;
29
+ /** The most recent failure, or `undefined`. */
30
+ error: Error | undefined;
31
+ /** `true` while the trigger is in flight (before the redirect is issued). */
32
+ pending: boolean;
33
+ }
34
+ /**
35
+ * Decoupled redirect-on-resolve primitive shared by `CheckoutButton` and
36
+ * `CustomerPortalButton`. The app passes a `trigger` thunk that calls its own
37
+ * Lunora action (the one wrapping `LunoraPayment.createCheckout` /
38
+ * `createPortalSession`) and resolves `{ url }`; this hook awaits it, flips
39
+ * `pending`, surfaces any `error`, and on success navigates via
40
+ * `location.assign(url)`.
41
+ *
42
+ * Mirrors Convex's `CheckoutLink` / `CustomerPortalLink` flow (trigger an action
43
+ * that returns a URL, then redirect) while staying agnostic of the app's
44
+ * function names.
45
+ */
46
+ declare const useCheckout: (trigger: RedirectTrigger) => UseCheckoutResult;
47
+ /**
48
+ * Presentational props shared by the redirect buttons. Kept to a curated set
49
+ * (rather than spreading arbitrary button attributes) so the component stays
50
+ * within the repo's `react/jsx-props-no-spreading` rule while covering the
51
+ * common styling / accessibility hooks.
52
+ */
53
+ interface RedirectButtonOwnProps {
54
+ /** Accessible label when the visible `children` are icon-only. */
55
+ "aria-label"?: string;
56
+ children?: ReactNode;
57
+ className?: string;
58
+ /** Force-disable the control regardless of pending state. */
59
+ disabled?: boolean;
60
+ /** Called with the failure when the trigger rejects. The error is also surfaced via `useCheckout`. */
61
+ onError?: (error: Error) => void;
62
+ title?: string;
63
+ }
64
+ interface CheckoutButtonProps extends RedirectButtonOwnProps {
65
+ /** Calls the app's checkout action and resolves the hosted-checkout `{ url }`. */
66
+ onCheckout: RedirectTrigger;
67
+ }
68
+ interface CustomerPortalButtonProps extends RedirectButtonOwnProps {
69
+ /** Calls the app's portal action and resolves the customer-portal `{ url }`. */
70
+ onPortal: RedirectTrigger;
71
+ }
72
+ /**
73
+ * Button that starts a hosted checkout. On click it awaits `onCheckout` (a thunk
74
+ * that calls the app's checkout action) and redirects to the returned URL,
75
+ * disabling itself while the request is in flight.
76
+ */
77
+ declare const CheckoutButton: ({ onCheckout, ...rest }: CheckoutButtonProps) => ReactNode;
78
+ /**
79
+ * Button that opens the provider's customer portal. On click it awaits
80
+ * `onPortal` (a thunk that calls the app's portal action) and redirects to the
81
+ * returned URL, disabling itself while the request is in flight.
82
+ */
83
+ declare const CustomerPortalButton: ({ onPortal, ...rest }: CustomerPortalButtonProps) => ReactNode;
84
+ export { CheckoutButton, type CheckoutButtonProps, CustomerPortalButton, type CustomerPortalButtonProps, type RedirectTarget, type RedirectTrigger, type Subscription, type UseCheckoutResult, useCheckout };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/react",
3
- "version": "1.0.0-alpha.70",
3
+ "version": "1.0.0-alpha.72",
4
4
  "description": "React hooks for Lunora: useQuery, useMutation, useSubscription, and useAuth",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -39,6 +39,10 @@
39
39
  "types": "./dist/index.d.ts",
40
40
  "import": "./dist/index.mjs"
41
41
  },
42
+ "./payment": {
43
+ "types": "./dist/payment.d.ts",
44
+ "import": "./dist/payment.mjs"
45
+ },
42
46
  "./server": {
43
47
  "types": "./dist/server.d.ts",
44
48
  "import": "./dist/server.mjs"
@@ -53,9 +57,9 @@
53
57
  "access": "public"
54
58
  },
55
59
  "dependencies": {
56
- "@lunora/client": "1.0.0-alpha.65",
60
+ "@lunora/client": "1.0.0-alpha.67",
57
61
  "@lunora/errors": "1.0.0-alpha.26",
58
- "@lunora/ratelimit": "1.0.0-alpha.30",
62
+ "@lunora/ratelimit": "1.0.0-alpha.31",
59
63
  "@visulima/storage-client": "1.0.2"
60
64
  },
61
65
  "peerDependencies": {
@@ -1 +0,0 @@
1
- import{k as a}from"./query-key-C6iUhRuD.mjs";class p{constructor(e){this.client=e}client;entries=new Map;keyOf(e){return a(e)}attach(e,n,l,u,f,h={}){const i=a(n);let r=this.entries.get(i);if(!r){r={pollTimer:void 0,refCount:0,unsubscribe:void 0},this.entries.set(i,r);try{r.unsubscribe=this.client.subscribe(l,u,t=>{e.setQueryData(n,t)},{shardKey:f})}catch{r.pollTimer=setInterval(()=>{e.invalidateQueries({queryKey:n}).catch(()=>{})},h.pollIntervalMs??5e3)}}r.refCount+=1;let o=!1;return()=>{if(o)return;o=!0;const t=this.entries.get(i);t&&(t.refCount-=1,t.refCount<=0&&(t.unsubscribe?.(),t.pollTimer&&clearInterval(t.pollTimer),this.entries.delete(i)))}}}const c=new WeakMap,g=s=>{let e=c.get(s);return e||(e=new p(s),c.set(s,e)),e};export{g};
@@ -1,2 +0,0 @@
1
- 'use client';
2
- import{c as rt}from"react/compiler-runtime";import{reconcileOptimistic as H,maxSeq as J}from"@lunora/client";import{useState as ct,useRef as it}from"react";import{useMutation as Y}from"./useMutation-BnKec7bE.mjs";import{useStream as lt}from"./useStream-CmGOT0qj.mjs";import L from"./useSubscription-BXhI6J-f.mjs";const ut={__lunoraRef:""},mt={__lunoraRef:""},ft=[],St=i=>{const t=rt(47),{api:E,cancel:u,limit:m,send:Q,sendArgs:b,stream:f,threadKey:e}=i;let d;t[0]!==m||t[1]!==e?(d=m===void 0?{key:e}:{key:e,limit:m},t[0]=m,t[1]=e,t[2]=d):d=t[2];const V=d,{data:W}=L(E.agents.agentMessages,V);let p;t[3]!==e?(p={key:e},t[3]=e,t[4]=p):p=t[4];const{data:X}=L(E.agents.agentThread,p);let g;t[5]!==f||t[6]!==e?(g=f===void 0?"skip":{key:e},t[5]=f,t[6]=e,t[7]=g):g=t[7];const Z=g,{chunks:w}=lt(f??mt,Z),tt=Y(Q),et=Y(u??ut),st=Y(E.agents.agentResolveApproval);let h;t[8]===Symbol.for("react.memo_cache_sentinel")?(h=[],t[8]=h):h=t[8];const[O,z]=ct(h),T=it(0),B=X,I=B?.status,a=B?.instanceId,n=W??ft;let _;if(t[9]!==n||t[10]!==O){const s=H(O,n),o=J(n);_=s.length===0?n:[...n,...s.map((r,P)=>({content:r.content,optimistic:!0,role:"user",seq:o+1+P}))],t[9]=n,t[10]=O,t[11]=_}else _=t[11];const q=_;let v;t[12]!==n?(v=n.filter(dt),t[12]=n,t[13]=v):v=t[13];const l=v.length;let y;if(t[14]!==l||t[15]!==w||t[16]!==e){let s;t[18]!==l||t[19]!==e?(s=o=>o.kind!=="progress"&&o.threadKey===e&&o.turn>=l,t[18]=l,t[19]=e,t[20]=s):s=t[20],y=w.filter(s).map(pt).join(""),t[14]=l,t[15]=w,t[16]=e,t[17]=y}else y=t[17];const j=y,{mutate:C}=tt,{mutate:D}=et,{mutate:N}=st;let M;t[21]!==n||t[22]!==b||t[23]!==C||t[24]!==e?(M=async(s,o)=>{const r=T.current;T.current=T.current+1;const P=J(n);z(U=>[...H(U,n),{content:s,id:r,maxDurableSeqAtSend:P}]);try{await C({input:s,threadKey:e,...b,...o})}catch(U){const nt=U;throw z(ot=>ot.filter(at=>at.id!==r)),nt}},t[21]=n,t[22]=b,t[23]=C,t[24]=e,t[25]=M):M=t[25];const F=M;let S;t[26]!==a||t[27]!==N||t[28]!==e?(S=async(s,o,r)=>{if(a===void 0)throw new Error(`useAgentChat: cannot ${s} — no in-flight run (thread has no instanceId)`);await N({decision:s,instanceId:a,threadKey:e,toolCallId:o,...r===void 0?{}:{note:r}})},t[26]=a,t[27]=N,t[28]=e,t[29]=S):S=t[29];const c=S;let R;t[30]!==c?(R=(s,o)=>c("approve",s,o),t[30]=c,t[31]=R):R=t[31];const K=R;let A;t[32]!==c?(A=(s,o)=>c("reject",s,o),t[32]=c,t[33]=A):A=t[33];const $=A;let k;t[34]!==D||t[35]!==u||t[36]!==a||t[37]!==e?(k=async()=>{u===void 0||a===void 0||await D({instanceId:a,threadKey:e})},t[34]=D,t[35]=u,t[36]=a,t[37]=e,t[38]=k):k=t[38];const G=k;let x;return t[39]!==K||t[40]!==G||t[41]!==q||t[42]!==$||t[43]!==F||t[44]!==I||t[45]!==j?(x={approve:K,cancel:G,messages:q,reject:$,send:F,status:I,streamingText:j},t[39]=K,t[40]=G,t[41]=q,t[42]=$,t[43]=F,t[44]=I,t[45]=j,t[46]=x):x=t[46],x};function dt(i){return i.role==="assistant"}function pt(i){return i.text}export{St as useAgentChat};
@@ -1,2 +0,0 @@
1
- 'use client';
2
- import{useState as v,useRef as d,useEffect as m}from"react";import{useLunora as K}from"./LunoraProvider-DC06S-p1.mjs";import{s as g}from"./stable-key-B_BlboiY.mjs";const h="__lunora_flags__:eval",R=t=>{const e=typeof t;return e==="boolean"||e==="number"||e==="string"?e:"object"},$={__lunoraRef:h},S=(t,e,r)=>{const p=K(),[i,s]=v(e),c=R(e),o=r===void 0?"":g(r),u=`${t}::${c}::${o}`,l=d(u);l.current!==u&&(l.current=u,s(e));const a=d({context:r,defaultValue:e});return m(()=>{a.current={context:r,defaultValue:e}}),m(()=>{let f=!1;const{context:y,defaultValue:b}=a.current;s(b);let n;try{n=p.subscribe($,{context:y,default:b,key:t,type:c},_=>{f||s(_)})}catch{return()=>{f=!0}}return()=>{f=!0,n()}},[p,t,c,o]),i},j=(t,e)=>{const r=K(),[p,i]=v(t),s=g(t),c=e===void 0?"":g(e),o=`${s}::${c}`,u=d(o);u.current!==o&&(u.current=o,i(t));const l=d({context:e,flags:t});return m(()=>{l.current={context:e,flags:t}}),m(()=>{let a=!1;const{context:f,flags:y}=l.current;i(y);const b=[];for(const[n,_]of Object.entries(y))try{b.push(r.subscribe($,{context:f,default:_,key:n,type:R(_)},C=>{a||i(F=>({...F,[n]:C}))}))}catch{}return()=>{a=!0;for(const n of b)n()}},[r,s,c]),p};export{S as useFlag,j as useFlags};
@@ -1,2 +0,0 @@
1
- 'use client';
2
- import{c as R}from"react/compiler-runtime";import{useQueryClient as q,useQuery as K}from"@tanstack/react-query";import{useState as b,useEffect as f}from"react";import{g as k}from"./cache-I4w1R5RF.mjs";import{useLunora as v}from"./LunoraProvider-DC06S-p1.mjs";import{l as N,s as S}from"./query-key-C6iUhRuD.mjs";const x=(o,m,p)=>{const e=R(9),Q=p===void 0?{}:p,t=v(),a=q(),{shardKey:i}=Q,r=m==="skip",n=r?{}:m,d=N(o,n,i),[s,h]=b(t.isReady);let u,y;e[0]!==t||e[1]!==s?(u=()=>{s||t.whenReady().then(()=>{h(!0)})},y=[t,s],e[0]=t,e[1]=s,e[2]=u,e[3]=y):(u=e[2],y=e[3]),f(u,y);const g=r?void 0:t.peekHydratedQuery(o.__lunoraRef,n,i),{data:I}=K({enabled:!r&&s,initialData:g,queryFn:()=>t.query(o,n,{shardKey:i}),queryKey:d,staleTime:Number.POSITIVE_INFINITY}),l=S(d);let c;return e[4]!==t||e[5]!==a||e[6]!==r||e[7]!==l?(c=[t,a,l,r],e[4]=t,e[5]=a,e[6]=r,e[7]=l,e[8]=c):c=e[8],f(()=>r?T:k(t).attach(a,d,o,n,i),c),r?void 0:I};function T(){}export{x as default};