@lunora/react 1.0.0-alpha.39 → 1.0.0-alpha.40
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/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ReactElement } from 'react';
|
|
2
|
-
import { LunoraClient, OptimisticUpdate, User, FunctionReference, ClientQueryRef, ConnectionStatus, ArgsOf, ReturnOf, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, MutatorHandle, Preloaded } from '@lunora/client';
|
|
2
|
+
import { LunoraClient, OptimisticUpdate, User, AuthImpersonation, AuthSession, AuthUser, FunctionReference, ClientQueryRef, ConnectionStatus, ArgsOf, ReturnOf, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, MutatorHandle, Preloaded } from '@lunora/client';
|
|
3
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';
|
|
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";
|
|
@@ -199,6 +199,136 @@ interface UseAuthResult {
|
|
|
199
199
|
token: string | null;
|
|
200
200
|
user: User | null;
|
|
201
201
|
}
|
|
202
|
+
/** The shape every list hook in this file returns. */
|
|
203
|
+
interface AdminAuthListResult<T> {
|
|
204
|
+
/** Rows loaded so far (the full current window, not just the latest page). `undefined` before the first response. */
|
|
205
|
+
readonly data: ReadonlyArray<T> | undefined;
|
|
206
|
+
/** The read error, or `undefined`. */
|
|
207
|
+
readonly error: Error | undefined;
|
|
208
|
+
/**
|
|
209
|
+
* `true` when the server reports more rows exist beyond the current window
|
|
210
|
+
* (`total > data.length`). `false` before the first response resolves.
|
|
211
|
+
*/
|
|
212
|
+
readonly hasMore: boolean;
|
|
213
|
+
/** `true` only before the first response has resolved (matches TanStack's `isLoading`, not `isFetching`). */
|
|
214
|
+
readonly loading: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* Grow the requested window by one page and re-fetch. A no-op while
|
|
217
|
+
* `hasMore` is `false`. This is a growing-window re-fetch (re-request
|
|
218
|
+
* `{ limit }` from the top), not a page-accumulator — `AuthPage` is
|
|
219
|
+
* offset/limit-based, not cursor-based, and there is no live delta stream
|
|
220
|
+
* to keep page boundaries stable against (unlike
|
|
221
|
+
* `@lunora/react`'s `usePaginatedQuery`). See the design doc for the
|
|
222
|
+
* trade-off.
|
|
223
|
+
*/
|
|
224
|
+
readonly loadMore: () => void;
|
|
225
|
+
/** Re-run the read — e.g. after a caller performs a mutation via a plain `client.*` call (mirrors Studio's `onDone={refetchOrgs}` pattern). */
|
|
226
|
+
readonly refetch: () => void;
|
|
227
|
+
/** `AuthPage.total` — the server-reported row count across the whole collection, not just the current window. `undefined` before the first response. */
|
|
228
|
+
readonly total: number | undefined;
|
|
229
|
+
}
|
|
230
|
+
/** Options shared by every `useAuthUsers`-style hook. */
|
|
231
|
+
interface AdminAuthQueryOptions {
|
|
232
|
+
/** Gate the read (rules-of-hooks safe). Defaults to `true`. */
|
|
233
|
+
enabled?: boolean;
|
|
234
|
+
/** Page size for the first read; `loadMore` grows the window by this amount. Defaults to 50. */
|
|
235
|
+
pageSize?: number;
|
|
236
|
+
}
|
|
237
|
+
/** Options for {@link useAuthUsers}. */
|
|
238
|
+
interface UseAuthUsersOptions extends AdminAuthQueryOptions {
|
|
239
|
+
filterField?: string;
|
|
240
|
+
filterValue?: string;
|
|
241
|
+
search?: string;
|
|
242
|
+
searchField?: string;
|
|
243
|
+
sortBy?: string;
|
|
244
|
+
sortDirection?: "asc" | "desc";
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* List authenticated users, paged and optionally searched/filtered/sorted.
|
|
248
|
+
* Hits the admin-gated `GET /_lunora/admin/auth/users` HTTP endpoint via
|
|
249
|
+
* `client.listAuthUsers` (never the WS/live transport) — the worker must be
|
|
250
|
+
* built with an `authAdmin` and `adminToken`.
|
|
251
|
+
*
|
|
252
|
+
* Mirrors `packages/studio/src/features/auth/users-panel.tsx`'s
|
|
253
|
+
* `useClientQuery(["lunora-auth-users", …], () => client.listAuthUsers(…))`
|
|
254
|
+
* read, minus the studio-specific polling (`useAutoRefresh`) — an app using
|
|
255
|
+
* this hook decides its own refresh cadence by calling `refetch()`.
|
|
256
|
+
*/
|
|
257
|
+
declare const useAuthUsers: (options?: UseAuthUsersOptions) => AdminAuthListResult<AuthUser>;
|
|
258
|
+
/** Options for {@link useOrganizations}. */
|
|
259
|
+
type UseOrganizationsOptions = AdminAuthQueryOptions;
|
|
260
|
+
/**
|
|
261
|
+
* List organizations (requires the better-auth `organization` plugin).
|
|
262
|
+
* Hits `client.listAuthOrganizations` — an HTTP-only admin-gated read, same
|
|
263
|
+
* transport note as {@link useAuthUsers}.
|
|
264
|
+
*
|
|
265
|
+
* Mirrors `organizations-panel.tsx`'s
|
|
266
|
+
* `useClientQuery(["lunora-auth-orgs"], () => client.listAuthOrganizations({ limit: 100 }))`.
|
|
267
|
+
* Mutations (`client.createAuthOrganization`, `client.deleteAuthOrganization`,
|
|
268
|
+
* …) stay plain `client.*` calls; call this hook's `refetch()` afterward —
|
|
269
|
+
* see the design doc's "mutation ergonomics" section for why no hidden
|
|
270
|
+
* invalidation-on-mutate is wired in.
|
|
271
|
+
*/
|
|
272
|
+
declare const useOrganizations: (options?: UseOrganizationsOptions) => AdminAuthListResult<Record<string, unknown>>;
|
|
273
|
+
/** Options for {@link useAuthSessions}. */
|
|
274
|
+
interface UseAuthSessionsOptions extends AdminAuthQueryOptions {
|
|
275
|
+
/** Scope the list to one user's sessions; omit for the global cross-user browser. */
|
|
276
|
+
userId?: string;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* List auth sessions, paged and optionally scoped to one user. Hits
|
|
280
|
+
* `client.listAuthSessions` — HTTP-only, same transport note as
|
|
281
|
+
* {@link useAuthUsers}.
|
|
282
|
+
*
|
|
283
|
+
* Mirrors `auth-sessions-panel.tsx`'s
|
|
284
|
+
* `useClientQuery(["lunora-auth-sessions", …], () => client.listAuthSessions({ limit }))`.
|
|
285
|
+
* Revoking a session (`client.revokeAuthSession`/`revokeAuthUserSessions`)
|
|
286
|
+
* stays a plain `client.*` call followed by this hook's `refetch()`.
|
|
287
|
+
*/
|
|
288
|
+
declare const useAuthSessions: (options?: UseAuthSessionsOptions) => AdminAuthListResult<AuthSession>;
|
|
289
|
+
/** Everything {@link useImpersonate} returns. */
|
|
290
|
+
interface UseImpersonateResult {
|
|
291
|
+
/** The latest successful impersonation's token + user + expiry, or `undefined`. */
|
|
292
|
+
readonly data: AuthImpersonation | undefined;
|
|
293
|
+
/** The latest attempt's error, or `undefined`. */
|
|
294
|
+
readonly error: Error | undefined;
|
|
295
|
+
/**
|
|
296
|
+
* Mint an impersonation session for `userId`, resolving its bearer
|
|
297
|
+
* `AuthImpersonation`. Deliberately does **not** call
|
|
298
|
+
* `client.setAuthToken(...)` on the current client — see the security
|
|
299
|
+
* note below.
|
|
300
|
+
*/
|
|
301
|
+
readonly impersonate: (userId: string) => Promise<AuthImpersonation>;
|
|
302
|
+
/** `true` while an impersonation request is in flight. */
|
|
303
|
+
readonly pending: boolean;
|
|
304
|
+
/** Clear `data`/`error` back to idle. */
|
|
305
|
+
readonly reset: () => void;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Mint an impersonation session via `client.impersonateAuthUser` — the one
|
|
309
|
+
* genuinely mutation-shaped hook of the four prototyped here (TanStack
|
|
310
|
+
* `useMutation` underneath, matching `@lunora/react`'s own `useMutation`
|
|
311
|
+
* ergonomics: `data`/`error`/`pending`/`reset`).
|
|
312
|
+
*
|
|
313
|
+
* **Security note (open question — see the design doc):** Studio's
|
|
314
|
+
* `user-detail-drawer.tsx` (`onImpersonate`) mints the token and displays it
|
|
315
|
+
* in a read-only text field; it never calls `client.setAuthToken(token)` on
|
|
316
|
+
* the admin's own client instance. This hook preserves that discipline
|
|
317
|
+
* deliberately — silently swapping the *current* session would sign the
|
|
318
|
+
* admin out of their own admin session with no visible transition and no
|
|
319
|
+
* "return to admin" path. The caller decides what to do with the resolved
|
|
320
|
+
* `AuthImpersonation` (open a second tab/incognito window authenticated as
|
|
321
|
+
* the target user, surface it for manual copy, etc.). What the ideal UX is
|
|
322
|
+
* (a dedicated "Acting as X — Return to admin" banner + explicit swap-back)
|
|
323
|
+
* is an open product question this spike does not resolve.
|
|
324
|
+
*
|
|
325
|
+
* Unlike the three list hooks, impersonating a user has no single paired
|
|
326
|
+
* list to invalidate (it may affect a sessions list, but not the user/org
|
|
327
|
+
* list currently being viewed) — mirroring Studio's own `refresh: false` on
|
|
328
|
+
* this action, this hook does not auto-invalidate anything. A caller that
|
|
329
|
+
* also renders `useAuthSessions` can call its `refetch()` explicitly.
|
|
330
|
+
*/
|
|
331
|
+
declare const useImpersonate: () => UseImpersonateResult;
|
|
202
332
|
/**
|
|
203
333
|
* The lifecycle status stored on an agent thread. Client-safe mirror of
|
|
204
334
|
* `@lunora/agent`'s `AgentThreadStatus` — re-declared here (rather than imported)
|
|
@@ -1135,4 +1265,4 @@ interface UseVoiceAgentResult {
|
|
|
1135
1265
|
* `createSocket`) so the hook is drivable outside a browser.
|
|
1136
1266
|
*/
|
|
1137
1267
|
declare const useVoiceAgent: (options: UseVoiceAgentOptions) => UseVoiceAgentResult;
|
|
1138
|
-
export { 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 UseCheckoutResult, type UseHttpStreamOptions, type UseHttpStreamResult, type UseInfiniteQueryOptions, type UseInfiniteQueryResult, type UseMutationCallOptions, 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, useAgent, useAgentChat, useAgentState, useAgentToolEvents, useAuth, useAuthState, useCheckout, useClientQuery, useConnectionStatus, useFlag, useFlags, useHttpStream, useInfiniteQuery, useLunora, useMutation, useMutator, usePaginatedQuery, usePreloadedQuery, usePresence, useQuery, useRateLimit, useStream, useSubscription, useVoiceAgent };
|
|
1268
|
+
export { 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, 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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ReactElement } from 'react';
|
|
2
|
-
import { LunoraClient, OptimisticUpdate, User, FunctionReference, ClientQueryRef, ConnectionStatus, ArgsOf, ReturnOf, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, MutatorHandle, Preloaded } from '@lunora/client';
|
|
2
|
+
import { LunoraClient, OptimisticUpdate, User, AuthImpersonation, AuthSession, AuthUser, FunctionReference, ClientQueryRef, ConnectionStatus, ArgsOf, ReturnOf, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, MutatorHandle, Preloaded } from '@lunora/client';
|
|
3
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';
|
|
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";
|
|
@@ -199,6 +199,136 @@ interface UseAuthResult {
|
|
|
199
199
|
token: string | null;
|
|
200
200
|
user: User | null;
|
|
201
201
|
}
|
|
202
|
+
/** The shape every list hook in this file returns. */
|
|
203
|
+
interface AdminAuthListResult<T> {
|
|
204
|
+
/** Rows loaded so far (the full current window, not just the latest page). `undefined` before the first response. */
|
|
205
|
+
readonly data: ReadonlyArray<T> | undefined;
|
|
206
|
+
/** The read error, or `undefined`. */
|
|
207
|
+
readonly error: Error | undefined;
|
|
208
|
+
/**
|
|
209
|
+
* `true` when the server reports more rows exist beyond the current window
|
|
210
|
+
* (`total > data.length`). `false` before the first response resolves.
|
|
211
|
+
*/
|
|
212
|
+
readonly hasMore: boolean;
|
|
213
|
+
/** `true` only before the first response has resolved (matches TanStack's `isLoading`, not `isFetching`). */
|
|
214
|
+
readonly loading: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* Grow the requested window by one page and re-fetch. A no-op while
|
|
217
|
+
* `hasMore` is `false`. This is a growing-window re-fetch (re-request
|
|
218
|
+
* `{ limit }` from the top), not a page-accumulator — `AuthPage` is
|
|
219
|
+
* offset/limit-based, not cursor-based, and there is no live delta stream
|
|
220
|
+
* to keep page boundaries stable against (unlike
|
|
221
|
+
* `@lunora/react`'s `usePaginatedQuery`). See the design doc for the
|
|
222
|
+
* trade-off.
|
|
223
|
+
*/
|
|
224
|
+
readonly loadMore: () => void;
|
|
225
|
+
/** Re-run the read — e.g. after a caller performs a mutation via a plain `client.*` call (mirrors Studio's `onDone={refetchOrgs}` pattern). */
|
|
226
|
+
readonly refetch: () => void;
|
|
227
|
+
/** `AuthPage.total` — the server-reported row count across the whole collection, not just the current window. `undefined` before the first response. */
|
|
228
|
+
readonly total: number | undefined;
|
|
229
|
+
}
|
|
230
|
+
/** Options shared by every `useAuthUsers`-style hook. */
|
|
231
|
+
interface AdminAuthQueryOptions {
|
|
232
|
+
/** Gate the read (rules-of-hooks safe). Defaults to `true`. */
|
|
233
|
+
enabled?: boolean;
|
|
234
|
+
/** Page size for the first read; `loadMore` grows the window by this amount. Defaults to 50. */
|
|
235
|
+
pageSize?: number;
|
|
236
|
+
}
|
|
237
|
+
/** Options for {@link useAuthUsers}. */
|
|
238
|
+
interface UseAuthUsersOptions extends AdminAuthQueryOptions {
|
|
239
|
+
filterField?: string;
|
|
240
|
+
filterValue?: string;
|
|
241
|
+
search?: string;
|
|
242
|
+
searchField?: string;
|
|
243
|
+
sortBy?: string;
|
|
244
|
+
sortDirection?: "asc" | "desc";
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* List authenticated users, paged and optionally searched/filtered/sorted.
|
|
248
|
+
* Hits the admin-gated `GET /_lunora/admin/auth/users` HTTP endpoint via
|
|
249
|
+
* `client.listAuthUsers` (never the WS/live transport) — the worker must be
|
|
250
|
+
* built with an `authAdmin` and `adminToken`.
|
|
251
|
+
*
|
|
252
|
+
* Mirrors `packages/studio/src/features/auth/users-panel.tsx`'s
|
|
253
|
+
* `useClientQuery(["lunora-auth-users", …], () => client.listAuthUsers(…))`
|
|
254
|
+
* read, minus the studio-specific polling (`useAutoRefresh`) — an app using
|
|
255
|
+
* this hook decides its own refresh cadence by calling `refetch()`.
|
|
256
|
+
*/
|
|
257
|
+
declare const useAuthUsers: (options?: UseAuthUsersOptions) => AdminAuthListResult<AuthUser>;
|
|
258
|
+
/** Options for {@link useOrganizations}. */
|
|
259
|
+
type UseOrganizationsOptions = AdminAuthQueryOptions;
|
|
260
|
+
/**
|
|
261
|
+
* List organizations (requires the better-auth `organization` plugin).
|
|
262
|
+
* Hits `client.listAuthOrganizations` — an HTTP-only admin-gated read, same
|
|
263
|
+
* transport note as {@link useAuthUsers}.
|
|
264
|
+
*
|
|
265
|
+
* Mirrors `organizations-panel.tsx`'s
|
|
266
|
+
* `useClientQuery(["lunora-auth-orgs"], () => client.listAuthOrganizations({ limit: 100 }))`.
|
|
267
|
+
* Mutations (`client.createAuthOrganization`, `client.deleteAuthOrganization`,
|
|
268
|
+
* …) stay plain `client.*` calls; call this hook's `refetch()` afterward —
|
|
269
|
+
* see the design doc's "mutation ergonomics" section for why no hidden
|
|
270
|
+
* invalidation-on-mutate is wired in.
|
|
271
|
+
*/
|
|
272
|
+
declare const useOrganizations: (options?: UseOrganizationsOptions) => AdminAuthListResult<Record<string, unknown>>;
|
|
273
|
+
/** Options for {@link useAuthSessions}. */
|
|
274
|
+
interface UseAuthSessionsOptions extends AdminAuthQueryOptions {
|
|
275
|
+
/** Scope the list to one user's sessions; omit for the global cross-user browser. */
|
|
276
|
+
userId?: string;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* List auth sessions, paged and optionally scoped to one user. Hits
|
|
280
|
+
* `client.listAuthSessions` — HTTP-only, same transport note as
|
|
281
|
+
* {@link useAuthUsers}.
|
|
282
|
+
*
|
|
283
|
+
* Mirrors `auth-sessions-panel.tsx`'s
|
|
284
|
+
* `useClientQuery(["lunora-auth-sessions", …], () => client.listAuthSessions({ limit }))`.
|
|
285
|
+
* Revoking a session (`client.revokeAuthSession`/`revokeAuthUserSessions`)
|
|
286
|
+
* stays a plain `client.*` call followed by this hook's `refetch()`.
|
|
287
|
+
*/
|
|
288
|
+
declare const useAuthSessions: (options?: UseAuthSessionsOptions) => AdminAuthListResult<AuthSession>;
|
|
289
|
+
/** Everything {@link useImpersonate} returns. */
|
|
290
|
+
interface UseImpersonateResult {
|
|
291
|
+
/** The latest successful impersonation's token + user + expiry, or `undefined`. */
|
|
292
|
+
readonly data: AuthImpersonation | undefined;
|
|
293
|
+
/** The latest attempt's error, or `undefined`. */
|
|
294
|
+
readonly error: Error | undefined;
|
|
295
|
+
/**
|
|
296
|
+
* Mint an impersonation session for `userId`, resolving its bearer
|
|
297
|
+
* `AuthImpersonation`. Deliberately does **not** call
|
|
298
|
+
* `client.setAuthToken(...)` on the current client — see the security
|
|
299
|
+
* note below.
|
|
300
|
+
*/
|
|
301
|
+
readonly impersonate: (userId: string) => Promise<AuthImpersonation>;
|
|
302
|
+
/** `true` while an impersonation request is in flight. */
|
|
303
|
+
readonly pending: boolean;
|
|
304
|
+
/** Clear `data`/`error` back to idle. */
|
|
305
|
+
readonly reset: () => void;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Mint an impersonation session via `client.impersonateAuthUser` — the one
|
|
309
|
+
* genuinely mutation-shaped hook of the four prototyped here (TanStack
|
|
310
|
+
* `useMutation` underneath, matching `@lunora/react`'s own `useMutation`
|
|
311
|
+
* ergonomics: `data`/`error`/`pending`/`reset`).
|
|
312
|
+
*
|
|
313
|
+
* **Security note (open question — see the design doc):** Studio's
|
|
314
|
+
* `user-detail-drawer.tsx` (`onImpersonate`) mints the token and displays it
|
|
315
|
+
* in a read-only text field; it never calls `client.setAuthToken(token)` on
|
|
316
|
+
* the admin's own client instance. This hook preserves that discipline
|
|
317
|
+
* deliberately — silently swapping the *current* session would sign the
|
|
318
|
+
* admin out of their own admin session with no visible transition and no
|
|
319
|
+
* "return to admin" path. The caller decides what to do with the resolved
|
|
320
|
+
* `AuthImpersonation` (open a second tab/incognito window authenticated as
|
|
321
|
+
* the target user, surface it for manual copy, etc.). What the ideal UX is
|
|
322
|
+
* (a dedicated "Acting as X — Return to admin" banner + explicit swap-back)
|
|
323
|
+
* is an open product question this spike does not resolve.
|
|
324
|
+
*
|
|
325
|
+
* Unlike the three list hooks, impersonating a user has no single paired
|
|
326
|
+
* list to invalidate (it may affect a sessions list, but not the user/org
|
|
327
|
+
* list currently being viewed) — mirroring Studio's own `refresh: false` on
|
|
328
|
+
* this action, this hook does not auto-invalidate anything. A caller that
|
|
329
|
+
* also renders `useAuthSessions` can call its `refetch()` explicitly.
|
|
330
|
+
*/
|
|
331
|
+
declare const useImpersonate: () => UseImpersonateResult;
|
|
202
332
|
/**
|
|
203
333
|
* The lifecycle status stored on an agent thread. Client-safe mirror of
|
|
204
334
|
* `@lunora/agent`'s `AgentThreadStatus` — re-declared here (rather than imported)
|
|
@@ -1135,4 +1265,4 @@ interface UseVoiceAgentResult {
|
|
|
1135
1265
|
* `createSocket`) so the hook is drivable outside a browser.
|
|
1136
1266
|
*/
|
|
1137
1267
|
declare const useVoiceAgent: (options: UseVoiceAgentOptions) => UseVoiceAgentResult;
|
|
1138
|
-
export { 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 UseCheckoutResult, type UseHttpStreamOptions, type UseHttpStreamResult, type UseInfiniteQueryOptions, type UseInfiniteQueryResult, type UseMutationCallOptions, 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, useAgent, useAgentChat, useAgentState, useAgentToolEvents, useAuth, useAuthState, useCheckout, useClientQuery, useConnectionStatus, useFlag, useFlags, useHttpStream, useInfiniteQuery, useLunora, useMutation, useMutator, usePaginatedQuery, usePreloadedQuery, usePresence, useQuery, useRateLimit, useStream, useSubscription, useVoiceAgent };
|
|
1268
|
+
export { 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, 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 };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import{AuthLoading as t,Authenticated as o,Unauthenticated as u}from"./packem_shared/AuthLoading-eLWn4Z7G.mjs";import{useAuthState as a}from"./packem_shared/useAuthState-jnCMkIwt.mjs";import{LunoraProvider as f,useLunora as n}from"./packem_shared/LunoraProvider-InsjxtOB.mjs";import{CheckoutButton as
|
|
2
|
+
import{AuthLoading as t,Authenticated as o,Unauthenticated as u}from"./packem_shared/AuthLoading-eLWn4Z7G.mjs";import{useAuthState as a}from"./packem_shared/useAuthState-jnCMkIwt.mjs";import{LunoraProvider as f,useLunora as n}from"./packem_shared/LunoraProvider-InsjxtOB.mjs";import{CheckoutButton as i,CustomerPortalButton as d,useCheckout as x}from"./packem_shared/CheckoutButton-DS_DKgNf.mjs";import{lunoraQueryOptions as h}from"./packem_shared/lunoraQueryOptions-BhiUY9ZF.mjs";import{useAuthSessions as A,useAuthUsers as c,useImpersonate as C,useOrganizations as U}from"./packem_shared/useAuthSessions-Dw4Zhtxa.mjs";import{useAgent as E}from"./packem_shared/useAgent-DNKxqQ9F.mjs";import{useAgentChat as Q}from"./packem_shared/useAgentChat-BdDuGIHz.mjs";import{useAgentState as L}from"./packem_shared/useAgentState-DO0yz6OU.mjs";import{useAgentToolEvents as F}from"./packem_shared/useAgentToolEvents-DTWZCIfd.mjs";import{default as k}from"./packem_shared/useAuth-CWkJn7i9.mjs";import{default as b}from"./packem_shared/useClientQuery-EPo__hzu.mjs";import{default as z}from"./packem_shared/useConnectionStatus-PL5D-S7t.mjs";import{useFlag as O,useFlags as T}from"./packem_shared/useFlag-Dh7bXXPx.mjs";import{useHttpStream as V}from"./packem_shared/useHttpStream-DFswZrRk.mjs";import{default as q}from"./packem_shared/useInfiniteQuery-DyExohf2.mjs";import{useMutation as D}from"./packem_shared/useMutation-B4uL3Rde.mjs";import{useMutator as J}from"./packem_shared/useMutator-D3CGrk5-.mjs";import{usePaginatedQuery as N}from"./packem_shared/usePaginatedQuery-Roo_jyC9.mjs";import{hydratePreloaded as X,default as Y}from"./packem_shared/hydratePreloaded-DltXxPnp.mjs";import{usePresence as _}from"./packem_shared/usePresence-xAbekAr_.mjs";import{default as ee}from"./packem_shared/useQuery-m-trnMUV.mjs";import{useRateLimit as te}from"./packem_shared/useRateLimit-DqikMrX9.mjs";import{useStream as ue}from"./packem_shared/useStream-CGcSWvPI.mjs";import{default as ae}from"./packem_shared/useSubscription-CiQk8tFR.mjs";import{useVoiceAgent as fe}from"./packem_shared/useVoiceAgent-4gj2W2jc.mjs";import{createClientQuery as me,getErrorCode as ie,getRetryAfterMs as de,isConflictError as xe,isForbiddenError as le,isRateLimitedError as he,isUnauthorizedError as ge}from"@lunora/client";import{RestrictionError as ce,UploadControl as Ce,UploadError as Ue}from"@visulima/storage-client";import{useChunkedRestUpload as Ee,useFileInput as Pe,useMultipartUpload as Qe,usePasteUpload as Se,useTusUpload as Le,useUpload as Re}from"@visulima/storage-client/react";export{t as AuthLoading,o as Authenticated,i as CheckoutButton,d as CustomerPortalButton,f as LunoraProvider,ce as RestrictionError,u as Unauthenticated,Ce as UploadControl,Ue as UploadError,me as createClientQuery,ie as getErrorCode,de as getRetryAfterMs,X as hydratePreloaded,xe as isConflictError,le as isForbiddenError,he as isRateLimitedError,ge as isUnauthorizedError,h as lunoraQueryOptions,E as useAgent,Q as useAgentChat,L as useAgentState,F as useAgentToolEvents,k as useAuth,A as useAuthSessions,a as useAuthState,c as useAuthUsers,x as useCheckout,Ee as useChunkedRestUpload,b as useClientQuery,z as useConnectionStatus,Pe as useFileInput,O as useFlag,T as useFlags,V as useHttpStream,C as useImpersonate,q as useInfiniteQuery,n as useLunora,Qe as useMultipartUpload,D as useMutation,J as useMutator,U as useOrganizations,N as usePaginatedQuery,Se as usePasteUpload,Y as usePreloadedQuery,_ as usePresence,ee as useQuery,te as useRateLimit,ue as useStream,ae as useSubscription,Le as useTusUpload,Re as useUpload,fe as useVoiceAgent};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import{c as y}from"react/compiler-runtime";import{useMutation as b,useQuery as F,keepPreviousData as v}from"@tanstack/react-query";import{useState as A,useSyncExternalStore as I}from"react";import{useLunora as S}from"./LunoraProvider-InsjxtOB.mjs";const D="lunora-react-admin-auth",P=50;function z(t,e,n,d={}){const{enabled:o=!0,pageSize:u=P}=d,[i,r]=A(u),l=I(f=>t.onAuthTokenChange(f),()=>t.currentIdentity(),()=>t.currentIdentity()),s=[D,l??"anon",...e,i],a=F({enabled:o,placeholderData:v,queryFn:()=>n(i),queryKey:s,staleTime:0}),c=a.data?.rows,h=a.data?.total,m=h!==void 0&&c!==void 0&&c.length<h,p=()=>{m&&r(f=>f+u)},g=()=>{a.refetch().catch(()=>{})};return{data:c,error:a.error??void 0,hasMore:m,loadMore:p,loading:a.isLoading,refetch:g,total:h}}const V=t=>{const e=y(20);let n;e[0]!==t?(n=t===void 0?{}:t,e[0]=t,e[1]=n):n=e[1];const d=n,o=S(),{enabled:u,filterField:i,filterValue:r,pageSize:l,search:s,searchField:a,sortBy:c,sortDirection:h}=d;let m;e[2]!==i||e[3]!==r||e[4]!==s||e[5]!==a||e[6]!==c||e[7]!==h?(m=["users",{filterField:i,filterValue:r,search:s,searchField:a,sortBy:c,sortDirection:h}],e[2]=i,e[3]=r,e[4]=s,e[5]=a,e[6]=c,e[7]=h,e[8]=m):m=e[8];let p;e[9]!==o||e[10]!==i||e[11]!==r||e[12]!==s||e[13]!==a||e[14]!==c||e[15]!==h?(p=f=>o.listAuthUsers({filterField:i,filterValue:r,limit:f,search:s,searchField:a,sortBy:c,sortDirection:h}),e[9]=o,e[10]=i,e[11]=r,e[12]=s,e[13]=a,e[14]=c,e[15]=h,e[16]=p):p=e[16];let g;return e[17]!==u||e[18]!==l?(g={enabled:u,pageSize:l},e[17]=u,e[18]=l,e[19]=g):g=e[19],z(o,m,p,g)},k=t=>{const e=y(8);let n;e[0]!==t?(n=t===void 0?{}:t,e[0]=t,e[1]=n):n=e[1];const d=n,o=S(),{enabled:u,pageSize:i}=d;let r;e[2]===Symbol.for("react.memo_cache_sentinel")?(r=["organizations"],e[2]=r):r=e[2];let l;e[3]!==o?(l=a=>o.listAuthOrganizations({limit:a}),e[3]=o,e[4]=l):l=e[4];let s;return e[5]!==u||e[6]!==i?(s={enabled:u,pageSize:i},e[5]=u,e[6]=i,e[7]=s):s=e[7],z(o,r,l,s)},q=t=>{const e=y(10);let n;e[0]!==t?(n=t===void 0?{}:t,e[0]=t,e[1]=n):n=e[1];const d=n,o=S(),{enabled:u,pageSize:i,userId:r}=d;let l;e[2]!==r?(l=["sessions",{userId:r}],e[2]=r,e[3]=l):l=e[3];let s;e[4]!==o||e[5]!==r?(s=c=>o.listAuthSessions({limit:c,userId:r}),e[4]=o,e[5]=r,e[6]=s):s=e[6];let a;return e[7]!==u||e[8]!==i?(a={enabled:u,pageSize:i},e[7]=u,e[8]=i,e[9]=a):a=e[9],z(o,l,s,a)},x=()=>{const t=y(10),e=S();let n;t[0]!==e?(n={mutationFn:a=>e.impersonateAuthUser({userId:a})},t[0]=e,t[1]=n):n=t[1];const d=b(n),{mutateAsync:o,reset:u}=d;let i;t[2]!==o?(i=a=>o(a),t[2]=o,t[3]=i):i=t[3];const r=i,l=d.error??void 0;let s;return t[4]!==r||t[5]!==d.data||t[6]!==d.isPending||t[7]!==u||t[8]!==l?(s={data:d.data,error:l,impersonate:r,pending:d.isPending,reset:u},t[4]=r,t[5]=d.data,t[6]=d.isPending,t[7]=u,t[8]=l,t[9]=s):s=t[9],s};export{q as useAuthSessions,V as useAuthUsers,x as useImpersonate,k as useOrganizations};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import{useMemo as S,useState as U,useRef as I,useEffect as c,useCallback as p}from"react";import{useLunora as $}from"./LunoraProvider-InsjxtOB.mjs";const D=(e="sess")=>{if(typeof crypto<"u"){if(typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto.getRandomValues=="function"){const s=crypto.getRandomValues(new Uint8Array(16));return`${e}-${Array.from(s,t=>t.toString(16).padStart(2,"0")).join("")}`}}return`${e}-${Date.now().toString(36)}`},L=1e4,P=(e,s)=>{const t=$(),{heartbeat:m,intervalMs:y=L,listPresent:f,shardKey:o}=s,i=S(()=>s.sessionId??D(),[s.sessionId]),[h,v]=U(void 0),u=I(s.data),l=I({client:t,heartbeat:m,roomId:e,sessionId:i,shardKey:o});c(()=>{l.current={client:t,heartbeat:m,roomId:e,sessionId:i,shardKey:o}});const n=p(()=>{const{client:r,heartbeat:a,roomId:d,sessionId:K,shardKey:g}=l.current,R={roomId:d,sessionId:K,...u.current===void 0?{}:{data:u.current}};r.mutation(a,R,{shardKey:g}).catch(()=>{})},[]),b=p(r=>{u.current=r,n()},[n]);return c(()=>{n();const r=setInterval(n,y),a=()=>{typeof document<"u"&&document.visibilityState==="visible"&&n()};return typeof document<"u"&&document.addEventListener("visibilitychange",a),()=>{clearInterval(r),typeof document<"u"&&document.removeEventListener("visibilitychange",a)}},[n,y]),c(()=>t.acquireConnectionContext({roomId:e,sessionId:i},{shardKey:o}),[t,e,i,o]),c(()=>{let r=!1;const a=t.subscribe(f,{roomId:e},d=>{r||v(d)},{shardKey:o});return()=>{r=!0,a()}},[t,f.__lunoraRef,e,o]),{present:h,sessionId:i,setData:b}};export{P as usePresence};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/react",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.40",
|
|
4
4
|
"description": "React hooks for Lunora: useQuery, useMutation, useSubscription, and useAuth",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"access": "public"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@lunora/client": "1.0.0-alpha.
|
|
57
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
58
|
-
"@lunora/ratelimit": "1.0.0-alpha.
|
|
56
|
+
"@lunora/client": "1.0.0-alpha.36",
|
|
57
|
+
"@lunora/errors": "1.0.0-alpha.12",
|
|
58
|
+
"@lunora/ratelimit": "1.0.0-alpha.15",
|
|
59
59
|
"@visulima/storage-client": "1.0.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import{useMemo as S,useState as U,useRef as f,useEffect as c,useCallback as h}from"react";import{useLunora as $}from"./LunoraProvider-InsjxtOB.mjs";const D=(e="sess")=>{if(typeof crypto<"u"){if(typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto.getRandomValues=="function"){const s=crypto.getRandomValues(new Uint8Array(16));return`${e}-${Array.from(s,t=>t.toString(16).padStart(2,"0")).join("")}`}}return`${e}-${Date.now().toString(36)}`},C=1e4,P=(e,s)=>{const t=$(),{heartbeat:m,intervalMs:l=C,listPresent:y,shardKey:n}=s,i=S(()=>s.sessionId??D(),[s.sessionId]),[p,v]=U(void 0),d=f(s.data),I=f({client:t,heartbeat:m,roomId:e,sessionId:i,shardKey:n});c(()=>{I.current={client:t,heartbeat:m,roomId:e,sessionId:i,shardKey:n}});const o=h(()=>{const{client:r,heartbeat:a,roomId:u,sessionId:K,shardKey:g}=I.current,R={roomId:u,sessionId:K,...d.current===void 0?{}:{data:d.current}};r.mutation(a,R,{shardKey:g}).catch(()=>{})},[]),b=h(r=>{d.current=r,o()},[o]);return c(()=>{o();const r=setInterval(o,l),a=()=>{document.visibilityState==="visible"&&o()};return document.addEventListener("visibilitychange",a),()=>{clearInterval(r),document.removeEventListener("visibilitychange",a)}},[o,l]),c(()=>t.acquireConnectionContext({roomId:e,sessionId:i},{shardKey:n}),[t,e,i,n]),c(()=>{let r=!1;const a=t.subscribe(y,{roomId:e},u=>{r||v(u)},{shardKey:n});return()=>{r=!0,a()}},[t,y.__lunoraRef,e,n]),{present:p,sessionId:i,setData:b}};export{P as usePresence};
|