kitcn 0.32.2 → 0.33.1

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.
Files changed (47) hide show
  1. package/CHANGELOG.md +109 -0
  2. package/dist/aggregate/index.d.ts +2 -2
  3. package/dist/auth/generated/index.d.ts +1 -1
  4. package/dist/auth/index.d.ts +16 -16
  5. package/dist/auth/index.js +1 -1
  6. package/dist/auth/nextjs/index.d.ts +2 -2
  7. package/dist/auth/start/server/index.d.ts +2 -2
  8. package/dist/{builder-Cyd5nCxZ.js → builder-DDYTlmTB.js} +12 -3
  9. package/dist/caller-factory-C3pcbzo0.d.ts +140 -0
  10. package/dist/{capabilities-BJm_VSDT.d.ts → capabilities-Bxzoofl4.d.ts} +149 -9
  11. package/dist/crpc/index.d.ts +3 -2
  12. package/dist/{generated-contract-disabled-BRm1dNQE.d.ts → generated-contract-disabled-B_EaHGCP.d.ts} +33 -33
  13. package/dist/{http-types-BhhPZtwa.d.ts → http-types-8FBr10yl.d.ts} +3 -79
  14. package/dist/{middleware-BBS7oLtT.d.ts → middleware-D2hKJuSZ.d.ts} +1 -1
  15. package/dist/{middleware-D61Nm-iB.js → middleware-LvZov-hA.js} +1 -1
  16. package/dist/orm/aggregate-index/index.d.ts +1 -1
  17. package/dist/orm/aggregate-index/index.js +226 -96
  18. package/dist/orm/index.d.ts +2 -2
  19. package/dist/orm/index.js +364 -108
  20. package/dist/orm/migrations/index.d.ts +2 -2
  21. package/dist/plugins/index.d.ts +1 -1
  22. package/dist/plugins/index.js +1 -1
  23. package/dist/{procedure-caller-DgMiD0-a.js → procedure-caller-DgGF_hA8.js} +1 -1
  24. package/dist/{procedure-name-DPYyLiVS.d.ts → procedure-name-kn-awLk1.d.ts} +12 -142
  25. package/dist/{query-context-D4z1CnDH.js → query-context-DQLv58LH.js} +34 -1
  26. package/dist/ratelimit/index.d.ts +2 -2
  27. package/dist/ratelimit/index.js +2 -2
  28. package/dist/react/index.d.ts +5 -6
  29. package/dist/react/index.js +24 -69
  30. package/dist/rsc/index.d.ts +4 -3
  31. package/dist/{schema-Bh7AmJwY.js → schema-BF4P0ZjS.js} +322 -1
  32. package/dist/server/index.d.ts +5 -4
  33. package/dist/server/index.js +2 -2
  34. package/dist/solid/index.d.ts +5 -6
  35. package/dist/solid/index.js +20 -66
  36. package/dist/transformer-BEkxlnss.d.ts +78 -0
  37. package/dist/{types-BXpu7xIU.d.ts → types-Cl0utsTL.d.ts} +4 -3
  38. package/dist/{where-clause-compiler-Dgf4lrO-.d.ts → where-clause-compiler-CoPVAVDO.d.ts} +136 -136
  39. package/package.json +1 -1
  40. package/skills/kitcn/SKILL.md +2 -1
  41. package/skills/kitcn/references/features/aggregates.md +13 -0
  42. package/skills/kitcn/references/features/auth-admin.md +1 -0
  43. package/skills/kitcn/references/features/orm.md +24 -4
  44. package/skills/kitcn/references/features/react.md +4 -5
  45. /package/dist/{context-utils-Cbv4r0AA.d.ts → context-utils-ax351iFc.d.ts} +0 -0
  46. /package/dist/{token-tlbNKQS0.d.ts → token-CZpDQUHd.d.ts} +0 -0
  47. /package/dist/{types-Bkeicpo6.d.ts → types-CzGsrLrY.d.ts} +0 -0
@@ -1,3 +1,3 @@
1
- import { C as MigrationStep, D as defineMigration, E as buildMigrationPlan, O as defineMigrationSet, S as MigrationStateMap, T as MigrationWriteMode, _ as MigrationManifestEntry, a as MAX_STATUS_RUN_LIMIT, b as MigrationRunStatus, c as MigrationRunChunkArgs, d as MigrationAppliedState, f as MigrationDefinition, g as MigrationDriftIssue, h as MigrationDocContext, k as detectMigrationDrift, l as MigrationStatusArgs, m as MigrationDoc, o as MigrationCancelArgs, p as MigrationDirection, s as MigrationRunArgs, u as createMigrationHandlers, v as MigrationMigrateOne, w as MigrationTableName, x as MigrationSet, y as MigrationPlan } from "../../capabilities-BJm_VSDT.js";
2
- import { Ct as migrationCapability, dt as MIGRATION_STORAGE_TABLE_NAMES, ft as injectMigrationStorageTables, lt as MIGRATION_RUN_TABLE, mt as migrationStorageTables, pt as migrationExtension, ut as MIGRATION_STATE_TABLE } from "../../where-clause-compiler-Dgf4lrO-.js";
1
+ import { C as MigrationStep, D as defineMigration, E as buildMigrationPlan, O as defineMigrationSet, S as MigrationStateMap, T as MigrationWriteMode, _ as MigrationManifestEntry, a as MAX_STATUS_RUN_LIMIT, b as MigrationRunStatus, c as MigrationRunChunkArgs, d as MigrationAppliedState, f as MigrationDefinition, g as MigrationDriftIssue, h as MigrationDocContext, k as detectMigrationDrift, l as MigrationStatusArgs, m as MigrationDoc, o as MigrationCancelArgs, p as MigrationDirection, s as MigrationRunArgs, u as createMigrationHandlers, v as MigrationMigrateOne, w as MigrationTableName, x as MigrationSet, y as MigrationPlan } from "../../capabilities-Bxzoofl4.js";
2
+ import { Ct as migrationCapability, dt as MIGRATION_STORAGE_TABLE_NAMES, ft as injectMigrationStorageTables, lt as MIGRATION_RUN_TABLE, mt as migrationStorageTables, pt as migrationExtension, ut as MIGRATION_STATE_TABLE } from "../../where-clause-compiler-CoPVAVDO.js";
3
3
  export { MAX_STATUS_RUN_LIMIT, MIGRATION_RUN_TABLE, MIGRATION_STATE_TABLE, MIGRATION_STORAGE_TABLE_NAMES, type MigrationAppliedState, type MigrationCancelArgs, type MigrationDefinition, type MigrationDirection, type MigrationDoc, type MigrationDocContext, type MigrationDriftIssue, type MigrationManifestEntry, type MigrationMigrateOne, type MigrationPlan, type MigrationRunArgs, type MigrationRunChunkArgs, type MigrationRunStatus, type MigrationSet, type MigrationStateMap, type MigrationStatusArgs, type MigrationStep, type MigrationTableName, type MigrationWriteMode, buildMigrationPlan, createMigrationHandlers, defineMigration, defineMigrationSet, detectMigrationDrift, injectMigrationStorageTables, migrationCapability, migrationExtension, migrationStorageTables };
@@ -1,2 +1,2 @@
1
- import { a as PluginConfigureResolver, i as PluginConfigureInput, n as PluginApiScope, o as definePlugin, r as PluginConfigureContext, s as resolvePluginOptions, t as Plugin } from "../middleware-BBS7oLtT.js";
1
+ import { a as PluginConfigureResolver, i as PluginConfigureInput, n as PluginApiScope, o as definePlugin, r as PluginConfigureContext, s as resolvePluginOptions, t as Plugin } from "../middleware-D2hKJuSZ.js";
2
2
  export { type Plugin, type PluginApiScope, type PluginConfigureContext, type PluginConfigureInput, type PluginConfigureResolver, definePlugin, resolvePluginOptions };
@@ -1,3 +1,3 @@
1
- import { n as resolvePluginOptions, t as definePlugin } from "../middleware-D61Nm-iB.js";
1
+ import { n as resolvePluginOptions, t as definePlugin } from "../middleware-LvZov-hA.js";
2
2
 
3
3
  export { definePlugin, resolvePluginOptions };
@@ -1,5 +1,5 @@
1
1
  import { i as decodeWire, o as encodeWire } from "./transformer-C8lVwHNT.js";
2
- import { _ as CRPCError } from "./builder-Cyd5nCxZ.js";
2
+ import { _ as CRPCError } from "./builder-DDYTlmTB.js";
3
3
  import * as z$1 from "zod";
4
4
 
5
5
  //#region src/server/env.ts
@@ -1,22 +1,14 @@
1
1
  import { t as VRequired } from "./validators-0I-Ik1EN.js";
2
- import { A as HttpProcedureBuilderDef, D as HttpHandlerOpts, L as DataTransformerOptions, N as ProcedureMeta, O as HttpMethod, W as getTransformer, _ as CRPCHttpRouter, f as InferHttpInput, k as HttpProcedure, p as InferHttpOutput, y as HttpRouterRecord } from "./http-types-BhhPZtwa.js";
3
- import { g as UnsetMarker, i as IntersectIfDefined, o as MiddlewareBuilder, p as Overwrite$1, s as MiddlewareFunction, t as AnyMiddleware } from "./types-Bkeicpo6.js";
2
+ import { l as EmptyObject, u as Expand } from "./caller-factory-C3pcbzo0.js";
3
+ import { d as getTransformer, i as DataTransformerOptions } from "./transformer-BEkxlnss.js";
4
+ import { g as UnsetMarker, i as IntersectIfDefined, o as MiddlewareBuilder, p as Overwrite$1, s as MiddlewareFunction, t as AnyMiddleware } from "./types-CzGsrLrY.js";
5
+ import { A as HttpProcedureBuilderDef, D as HttpHandlerOpts, N as ProcedureMeta, O as HttpMethod, _ as CRPCHttpRouter, f as InferHttpInput, k as HttpProcedure, p as InferHttpOutput, y as HttpRouterRecord } from "./http-types-8FBr10yl.js";
4
6
  import { ConvexError, GenericId, GenericValidator, ObjectType, OptionalProperty, PropertyValidators, VAny, VArray, VBoolean, VBytes, VFloat64, VId, VInt64, VLiteral, VNull, VObject, VOptional, VRecord, VString, VUnion, Validator, Value as Value$1 } from "convex/values";
5
7
  import { ActionBuilder, ArgsArrayToObject, DefaultFunctionArgs, FunctionReference, FunctionReturnType, FunctionVisibility, GenericActionCtx, GenericDataModel, GenericMutationCtx, GenericQueryCtx, MutationBuilder, QueryBuilder, RegisteredAction, RegisteredMutation, RegisteredQuery, TableNamesInDataModel } from "convex/server";
6
8
  import * as z$1 from "zod";
7
9
  import * as z$2 from "zod/v4";
8
10
  import * as zCore from "zod/v4/core";
9
11
 
10
- //#region src/internal/upstream/index.d.ts
11
- type EmptyObject = Record<string, never>;
12
- /**
13
- * Hack! This type causes TypeScript to simplify how it renders object types.
14
- *
15
- * It is functionally the identity for object types, but in practice it can
16
- * simplify expressions like `A & B`.
17
- */
18
- type Expand<ObjectType extends Record<any, any>> = ObjectType extends Record<any, any> ? { [Key in keyof ObjectType]: ObjectType[Key] } : never;
19
- //#endregion
20
12
  //#region src/internal/upstream/server/customFunctions.d.ts
21
13
  /**
22
14
  * A customization of a query, mutation, or action.
@@ -653,13 +645,15 @@ declare function createHttpProcedureBuilder<TCtx, TMeta extends ProcedureMeta>(c
653
645
  */
654
646
  declare const paginatedSchemaForTypes: z$1.ZodObject<{
655
647
  cursor: z$1.ZodUnion<readonly [z$1.ZodString, z$1.ZodNull]>;
648
+ endCursor: z$1.ZodOptional<z$1.ZodUnion<readonly [z$1.ZodString, z$1.ZodNull]>>;
656
649
  limit: z$1.ZodNumber;
657
650
  }, z$1.core.$strip>;
658
651
  /** Paginated schema type - both cursor and limit are required after .paginated() */
659
652
  type PaginatedInputSchema = typeof paginatedSchemaForTypes;
660
- /** Paginated schema type for external callers - both fields are optional due defaults. */
653
+ /** Paginated schema type for external callers before defaults are applied. */
661
654
  declare const paginatedSchemaForClientTypes: z$1.ZodObject<{
662
655
  cursor: z$1.ZodOptional<z$1.ZodUnion<readonly [z$1.ZodString, z$1.ZodNull]>>;
656
+ endCursor: z$1.ZodOptional<z$1.ZodUnion<readonly [z$1.ZodString, z$1.ZodNull]>>;
663
657
  limit: z$1.ZodOptional<z$1.ZodNumber>;
664
658
  }, z$1.core.$strip>;
665
659
  type PaginatedClientInputSchema = typeof paginatedSchemaForClientTypes;
@@ -811,8 +805,8 @@ declare class QueryProcedureBuilder<TBaseCtx, TContext, TContextOverrides extend
811
805
  /**
812
806
  * Add pagination input (chainable before .query())
813
807
  *
814
- * Creates flat { cursor, limit } input like tRPC and auto-wraps output.
815
- * User accesses args.cursor and args.limit directly.
808
+ * Creates flat { cursor, endCursor, limit } input like tRPC and auto-wraps
809
+ * output. User accesses the pagination fields directly from args.
816
810
  *
817
811
  * @param opts.limit - Default/max items per page
818
812
  * @param opts.item - Zod schema for each item in the page array
@@ -824,6 +818,8 @@ declare class QueryProcedureBuilder<TBaseCtx, TContext, TContextOverrides extend
824
818
  continueCursor: z$1.ZodUnion<[z$1.ZodString, z$1.ZodNull]>;
825
819
  isDone: z$1.ZodBoolean;
826
820
  page: z$1.ZodArray<TItem>;
821
+ pageStatus: z$1.ZodOptional<z$1.ZodUnion<[z$1.ZodLiteral<'SplitRecommended'>, z$1.ZodLiteral<'SplitRequired'>, z$1.ZodNull]>>;
822
+ splitCursor: z$1.ZodOptional<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNull]>>;
827
823
  }>, TMeta>;
828
824
  /** Define output schema */
829
825
  output<TNewOutput extends z$1.ZodTypeAny>(schema: TNewOutput): QueryProcedureBuilder<TBaseCtx, TContext, TContextOverrides, TInput, TClientInput, TNewOutput, TMeta>;
@@ -1005,132 +1001,6 @@ declare function createApiLeaf<TType extends ApiFunctionType, TExport, TMeta ext
1005
1001
  };
1006
1002
  declare function createGeneratedFunctionReference<TType extends ApiFunctionType, TVisibility extends GeneratedFunctionVisibility, TExport>(name: string): GeneratedFunctionRefFromExport<TType, TVisibility, TExport>;
1007
1003
  //#endregion
1008
- //#region src/server/caller.d.ts
1009
- /** Metadata for a single function */
1010
- type FnMeta = {
1011
- type?: 'query' | 'mutation' | 'action';
1012
- [key: string]: unknown;
1013
- };
1014
- /** Metadata for all functions in a module */
1015
- type ModuleMeta = Record<string, FnMeta>;
1016
- /** Metadata for all modules - from generated `@convex/api` */
1017
- type CallerMeta = Record<string, ModuleMeta>;
1018
- /** Options for individual caller function calls */
1019
- type CallerOpts = {
1020
- /** Skip query silently when unauthenticated (returns null instead of throwing) */skipUnauth?: boolean;
1021
- };
1022
- type CallerReturn<T, Opts extends CallerOpts | undefined> = Opts extends {
1023
- skipUnauth: true;
1024
- } ? T | null : T;
1025
- type FetchFn<T extends 'query' | 'mutation' | 'action'> = <Fn extends FunctionReference<T>>(fn: Fn, args: Fn['_args'], opts?: CallerOpts) => Promise<FunctionReturnType<Fn> | null>;
1026
- type CreateCallerOptions = {
1027
- fetchQuery: FetchFn<'query'>;
1028
- fetchMutation: FetchFn<'mutation'>;
1029
- fetchAction: FetchFn<'action'>;
1030
- meta: CallerMeta;
1031
- transformer?: DataTransformerOptions;
1032
- };
1033
- type ServerCallerFn<TApi, K extends keyof TApi> = TApi[K] extends FunctionReference<infer T, 'public'> ? T extends 'query' | 'mutation' | 'action' ? keyof TApi[K]['_args'] extends never ? <Opts extends CallerOpts | undefined = undefined>(args?: EmptyObject, opts?: Opts) => Promise<CallerReturn<FunctionReturnType<TApi[K]>, Opts>> : EmptyObject extends TApi[K]['_args'] ? <Opts extends CallerOpts | undefined = undefined>(args?: TApi[K]['_args'], opts?: Opts) => Promise<CallerReturn<FunctionReturnType<TApi[K]>, Opts>> : <Opts extends CallerOpts | undefined = undefined>(args: TApi[K]['_args'], opts?: Opts) => Promise<CallerReturn<FunctionReturnType<TApi[K]>, Opts>> : never : ServerCaller<TApi[K]>;
1034
- type ServerCaller<TApi> = { [K in keyof TApi as K extends string ? K extends `_${string}` ? never : K extends 'http' ? never : K : K]: ServerCallerFn<TApi, K> };
1035
- /**
1036
- * Create a server caller for direct data fetching without React Query.
1037
- *
1038
- * This is detached from React Query cache - data is NOT available in client components.
1039
- * Use for server-only data that doesn't need to be shared with the client.
1040
- *
1041
- * @example
1042
- * ```tsx
1043
- * // src/lib/convex/rsc.tsx
1044
- * export const caller = createServerCaller(api, {
1045
- * fetchQuery: fetchAuthQuery,
1046
- * fetchMutation: fetchAuthMutation,
1047
- * });
1048
- *
1049
- * // app/page.tsx (RSC)
1050
- * const posts = await caller.posts.list();
1051
- * return <div>{posts?.length} posts</div>;
1052
- * ```
1053
- */
1054
- declare function createServerCaller<TApi extends Record<string, unknown>>(api: TApi, opts: CreateCallerOptions): ServerCaller<TApi>;
1055
- //#endregion
1056
- //#region src/server/lazy-caller.d.ts
1057
- type CallerContext<TApi> = {
1058
- caller: ServerCaller<TApi>;
1059
- token: string | undefined;
1060
- isAuthenticated: boolean;
1061
- };
1062
- /**
1063
- * Lazy caller with auth helper methods.
1064
- * Context is created on first procedure invocation, not at definition time.
1065
- */
1066
- type LazyCaller<TApi> = ServerCaller<TApi> & {
1067
- /** Check if user is authenticated */isAuth: () => Promise<boolean>; /** Check if user is unauthenticated */
1068
- isUnauth: () => Promise<boolean>; /** Get the auth token (for RSC prefetching) */
1069
- getToken: () => Promise<string | undefined>;
1070
- };
1071
- /**
1072
- * Create a lazy caller that creates context on each procedure invocation.
1073
- * Matches tRPC's `appRouter.createCaller(createTRPCContext)` pattern.
1074
- *
1075
- * @example
1076
- * ```ts
1077
- * // server.ts
1078
- * const { createContext, createCaller } = createCallerFactory({...});
1079
- *
1080
- * // rsc.tsx
1081
- * const createRSCContext = cache(async () => {
1082
- * const heads = await headers();
1083
- * return createContext({ headers: heads });
1084
- * });
1085
- * export const caller = createCaller(createRSCContext);
1086
- *
1087
- * // app/page.tsx - single call! Context created lazily
1088
- * const posts = await caller.posts.list();
1089
- * ```
1090
- */
1091
- declare function createLazyCaller<TApi extends Record<string, unknown>>(api: TApi, createContext: () => Promise<CallerContext<TApi>>): LazyCaller<TApi>;
1092
- //#endregion
1093
- //#region src/server/caller-factory.d.ts
1094
- type TokenResult = {
1095
- token?: string;
1096
- isFresh?: boolean;
1097
- };
1098
- type GetTokenFn = (siteUrl: string, headers: Headers, opts?: unknown) => Promise<TokenResult>;
1099
- /** Auth options for server-side calls. */
1100
- type AuthOptions = {
1101
- /** Function to extract auth token from request headers. */getToken: GetTokenFn;
1102
- /**
1103
- * Custom function to detect UNAUTHORIZED errors.
1104
- * Set this to resolve those errors to `null` instead of throwing.
1105
- *
1106
- * Refreshing an expired cached token and retrying does not require this:
1107
- * that always falls back to `defaultIsUnauthorized`.
1108
- */
1109
- isUnauthorized?: (error: unknown) => boolean;
1110
- };
1111
- type CreateCallerFactoryOptions<TApi> = {
1112
- /** Your Convex API object. */api: TApi; /** Convex site URL (must end in `.convex.site`). */
1113
- convexSiteUrl: string;
1114
- /**
1115
- * Convex deployment URL (must end in `.convex.cloud`).
1116
- * Defaults to `convexSiteUrl` with the domain swapped.
1117
- */
1118
- convexUrl?: string; /** Auth options. Pass to enable authenticated calls with JWT caching. */
1119
- auth?: AuthOptions; /** Optional wire transformer for request/response payloads (always composed with Date). */
1120
- transformer?: DataTransformerOptions;
1121
- };
1122
- type ConvexContext<TApi> = {
1123
- token: string | undefined;
1124
- isAuthenticated: boolean;
1125
- caller: ServerCaller<TApi>;
1126
- };
1127
- declare function createCallerFactory<TApi extends Record<string, unknown>>(opts: CreateCallerFactoryOptions<TApi>): {
1128
- createCaller: (ctxFn: () => Promise<ConvexContext<TApi>>) => LazyCaller<TApi>;
1129
- createContext: (reqOpts: {
1130
- headers: Headers;
1131
- }) => Promise<ConvexContext<TApi>>;
1132
- };
1133
- //#endregion
1134
1004
  //#region src/server/env.d.ts
1135
1005
  type RuntimeEnv = Record<string, string | undefined>;
1136
1006
  type CreateEnvOptions<TSchema extends z$1.ZodObject<z$1.ZodRawShape>> = {
@@ -1409,4 +1279,4 @@ type ProcedureNameLookup = Record<string, ProcedureNameEntry[]>;
1409
1279
  declare function registerProcedureNameLookup(lookup: ProcedureNameLookup, functionsDirHint: string): void;
1410
1280
  declare function inferProcedureNameFromCallsite(): string | undefined;
1411
1281
  //#endregion
1412
- export { ActionProcedureBuilder as $, CRPCError as A, RuntimeEnv as B, createProcedureHandlerFactory as C, zCustomQuery as Ct, WithHttpRouter as D, zodToConvex as Dt, typedProcedureResolver as E, zodOutputToConvexFields as Et, getCRPCErrorFromUnknown as F, createLazyCaller as G, ConvexContext as H, getHTTPStatusCodeFromError as I, ServerCaller as J, CallerMeta as K, isCRPCError as L, CRPCErrorData as M, CRPC_ERROR_CODES_BY_KEY as N, inferApiInputs as O, zodToConvexFields as Ot, CRPC_ERROR_CODE_TO_HTTP as P, getGeneratedValue as Q, toCRPCError as R, createProcedureCallerFactory as S, zCustomMutation as St, getGeneratedFunctionReference as T, zodOutputToConvex as Tt, createCallerFactory as U, createEnv as V, LazyCaller as W, createApiLeaf as X, createServerCaller as Y, createGeneratedFunctionReference as Z, ProcedureSchedulableCallerFromRegistry as _, ZodValidatorFromConvex as _t, CreateProcedureCallerFactoryOptions as a, initCRPC as at, createGenericCallerFactory as b, withSystemFields as bt, GeneratedRegistryCallerFactory as c, extractPathParams as ct, GeneratedRegistryHandlerForContext as d, ConvexValidatorFromZod as dt, CRPCFunctionTypeHint as et, ProcedureActionCallerFromRegistry as f, ConvexValidatorFromZodOutput as ft, ProcedureFromFunctionReference as g, ZodFromValidatorBase as gt, ProcedureDefinition as h, Zid as ht, registerProcedureNameLookup as i, createMiddlewareFactory as it, CRPCErrorCode as j, inferApiOutputs as k, GeneratedRegistryCallerForContext as l, handleHttpError as lt, ProcedureCallerFromRegistry as m, ZCustomCtx as mt, ProcedureNameLookup as n, ProcedureBuilder as nt, GeneratedProcedureRegistry as o, HttpProcedureBuilder as ot, ProcedureCaller as p, CustomBuilder as pt, CallerOpts as q, inferProcedureNameFromCallsite as r, QueryProcedureBuilder as rt, GeneratedProcedureRegistryEntry as s, createHttpProcedureBuilder as st, ProcedureNameEntry as t, MutationProcedureBuilder as tt, GeneratedRegistryHandlerFactory as u, matchPathParams as ut, ProcedureScheduleCallerFromRegistry as v, convexToZod as vt, defineProcedure as w, zid as wt, createGenericHandlerFactory as x, zCustomAction as xt, createGeneratedRegistryRuntime as y, convexToZodFields as yt, CreateEnvOptions as z };
1282
+ export { createHttpProcedureBuilder as $, CRPCError as A, RuntimeEnv as B, createProcedureHandlerFactory as C, WithHttpRouter as D, typedProcedureResolver as E, getCRPCErrorFromUnknown as F, ActionProcedureBuilder as G, createApiLeaf as H, getHTTPStatusCodeFromError as I, ProcedureBuilder as J, CRPCFunctionTypeHint as K, isCRPCError as L, CRPCErrorData as M, CRPC_ERROR_CODES_BY_KEY as N, inferApiInputs as O, CRPC_ERROR_CODE_TO_HTTP as P, HttpProcedureBuilder as Q, toCRPCError as R, createProcedureCallerFactory as S, getGeneratedFunctionReference as T, createGeneratedFunctionReference as U, createEnv as V, getGeneratedValue as W, createMiddlewareFactory as X, QueryProcedureBuilder as Y, initCRPC as Z, ProcedureSchedulableCallerFromRegistry as _, zodOutputToConvex as _t, CreateProcedureCallerFactoryOptions as a, CustomBuilder as at, createGenericCallerFactory as b, zodToConvexFields as bt, GeneratedRegistryCallerFactory as c, ZodFromValidatorBase as ct, GeneratedRegistryHandlerForContext as d, convexToZodFields as dt, extractPathParams as et, ProcedureActionCallerFromRegistry as f, withSystemFields as ft, ProcedureFromFunctionReference as g, zid as gt, ProcedureDefinition as h, zCustomQuery as ht, registerProcedureNameLookup as i, ConvexValidatorFromZodOutput as it, CRPCErrorCode as j, inferApiOutputs as k, GeneratedRegistryCallerForContext as l, ZodValidatorFromConvex as lt, ProcedureCallerFromRegistry as m, zCustomMutation as mt, ProcedureNameLookup as n, matchPathParams as nt, GeneratedProcedureRegistry as o, ZCustomCtx as ot, ProcedureCaller as p, zCustomAction as pt, MutationProcedureBuilder as q, inferProcedureNameFromCallsite as r, ConvexValidatorFromZod as rt, GeneratedProcedureRegistryEntry as s, Zid as st, ProcedureNameEntry as t, handleHttpError as tt, GeneratedRegistryHandlerFactory as u, convexToZod as ut, ProcedureScheduleCallerFromRegistry as v, zodOutputToConvexFields as vt, defineProcedure as w, createGenericHandlerFactory as x, createGeneratedRegistryRuntime as y, zodToConvex as yt, CreateEnvOptions as z };
@@ -671,6 +671,21 @@ function mergedStream(streams, orderByIndexFields) {
671
671
  return new MergedStream(streams, orderByIndexFields);
672
672
  }
673
673
  /**
674
+ * Read streams over disjoint index ranges one after another, as one stream.
675
+ *
676
+ * Produces the same sequence a `mergedStream` over the whole index key would,
677
+ * for sources that cannot interleave — but a source is only opened once the one
678
+ * before it runs dry, so the fan-out a merge pays up front, one live query per
679
+ * source, never happens. That is what makes a very wide union affordable.
680
+ *
681
+ * The caller owes disjointness and index order. Both are checked as rows come
682
+ * out: a key that goes backwards throws rather than silently returning an
683
+ * unordered stream.
684
+ */
685
+ function concatStreams(streams) {
686
+ return new ConcatStreams(...streams);
687
+ }
688
+ /**
674
689
  * Marks sources that are already `OrderByStream`s, so `narrow` reuses them
675
690
  * instead of adding a redundant delegation layer per call.
676
691
  *
@@ -1134,6 +1149,24 @@ function* getOrderingIndexFields(stream) {
1134
1149
  const streamIndexFields = stream.getIndexFields();
1135
1150
  for (let i = 0; i <= streamEqualityIndexLength; i++) yield streamIndexFields.slice(i);
1136
1151
  }
1152
+ /**
1153
+ * Whether `mergedStream(..., orderByIndexFields)` would accept this stream.
1154
+ *
1155
+ * `MergedStream` wraps every source in an `OrderByStream`, which throws unless
1156
+ * the ordering fields are a suffix of the source's index fields past its
1157
+ * equality-pinned prefix. A caller that is *choosing* which index a source
1158
+ * walks has to know that before it commits to one, so it can fall back instead
1159
+ * of turning a working merge into a runtime error.
1160
+ *
1161
+ * Asks the stream itself rather than re-deriving the rule from an index name,
1162
+ * so the answer cannot drift from what `OrderByStream` actually enforces.
1163
+ */
1164
+ function streamCanOrderBy(stream, orderByIndexFields) {
1165
+ const normalized = orderByIndexFields.slice();
1166
+ normalizeIndexFields(normalized);
1167
+ for (const orderingIndexFields of getOrderingIndexFields(stream)) if (equalIndexFields(orderingIndexFields, normalized)) return true;
1168
+ return false;
1169
+ }
1137
1170
  var OrderByStream = class OrderByStream extends QueryStream {
1138
1171
  #staticFilter;
1139
1172
  #stream;
@@ -1351,4 +1384,4 @@ async function getByIdWithOrmQueryFallback(ctx, tableName, id) {
1351
1384
  }
1352
1385
 
1353
1386
  //#endregion
1354
- export { indexKeyWithinBounds as a, streamIndexRange as c, getIndexFields as i, isUnsetToken as l, EmptyStream as n, mergedStream as o, QueryStream as r, stream as s, getByIdWithOrmQueryFallback as t, unsetToken as u };
1387
+ export { getIndexFields as a, stream as c, isUnsetToken as d, unsetToken as f, concatStreams as i, streamCanOrderBy as l, EmptyStream as n, indexKeyWithinBounds as o, QueryStream as r, mergedStream as s, getByIdWithOrmQueryFallback as t, streamIndexRange as u };
@@ -1,5 +1,5 @@
1
- import { o as MiddlewareBuilder } from "../types-Bkeicpo6.js";
2
- import { t as Plugin } from "../middleware-BBS7oLtT.js";
1
+ import { o as MiddlewareBuilder } from "../types-CzGsrLrY.js";
2
+ import { t as Plugin } from "../middleware-D2hKJuSZ.js";
3
3
  import * as convex_server0 from "convex/server";
4
4
 
5
5
  //#region src/ratelimit/duration.d.ts
@@ -1,6 +1,6 @@
1
1
  import { u as requireMutationCtx } from "../api-entry-Buvjl9hn.js";
2
- import { _ as CRPCError } from "../builder-Cyd5nCxZ.js";
3
- import { t as definePlugin } from "../middleware-D61Nm-iB.js";
2
+ import { _ as CRPCError } from "../builder-DDYTlmTB.js";
3
+ import { t as definePlugin } from "../middleware-LvZov-hA.js";
4
4
  import { v } from "convex/values";
5
5
  import { mutationGeneric, queryGeneric } from "convex/server";
6
6
 
@@ -487,8 +487,8 @@ type ConvexQueryHookOptions = {
487
487
  /** Skip query silently when unauthenticated (default: false, calls onQueryUnauthorized) */skipUnauth?: boolean; /** Set to false to fetch once without subscribing (default: true) */
488
488
  subscribe?: boolean;
489
489
  };
490
- /** Extract input args without cursor/limit (user's filter args only) */
491
- type InfiniteQueryInput<TInput> = Omit<TInput, 'cursor' | 'limit'>;
490
+ /** Extract user args without hook-owned pagination transport fields */
491
+ type InfiniteQueryInput<TInput> = Omit<TInput, 'cursor' | 'endCursor' | 'limit'>;
492
492
  /** Extract item type from PaginationResult<T> */
493
493
  type ExtractPaginatedItem<TOutput> = TOutput extends {
494
494
  page: (infer T)[];
@@ -946,7 +946,7 @@ declare const getConvexQueryClientSingleton: ({
946
946
  * Pagination state persisted in queryClient.
947
947
  * Enables scroll restoration when navigating back to a paginated list.
948
948
  *
949
- * Uses flat { cursor, limit } structure like tRPC.
949
+ * Uses flat { cursor, endCursor, limit } structure like tRPC.
950
950
  */
951
951
  type PaginationState = {
952
952
  id: number;
@@ -955,13 +955,12 @@ type PaginationState = {
955
955
  queries: Record<number, {
956
956
  /** Flat pagination args - tRPC style */args: Record<string, unknown> & {
957
957
  cursor: string | null;
958
+ endCursor?: string | null;
958
959
  limit?: number; /** Internal pagination ID for subscription management */
959
960
  __paginationId?: number;
960
961
  };
961
- endCursor?: string | null;
962
962
  }>;
963
- version: number; /** Recovery key to prevent infinite recovery loops */
964
- autoRecoveryAttempted?: string;
963
+ version: number;
965
964
  };
966
965
  type PaginationStatus = 'CanLoadMore' | 'Exhausted' | 'LoadingFirstPage' | 'LoadingMore';
967
966
  /** Fields we override or omit from TanStack Query's UseQueryResult */
@@ -1479,11 +1479,12 @@ function createCRPCContext(options) {
1479
1479
  const tokenReady = token === null || decodeJwtExp(token) !== null;
1480
1480
  const identity = resolveAuthIdentity(token);
1481
1481
  previousAuthRef.current = {
1482
- isAuthenticated,
1483
- identity
1482
+ identity,
1483
+ isAuthenticated
1484
1484
  };
1485
1485
  if (!previous) return;
1486
- if (tokenReady && (previous.identity !== identity || previous.isAuthenticated !== isAuthenticated)) convexQueryClient.resetAuthQueries();
1486
+ const tokenRejected = previous.isAuthenticated && !isAuthenticated;
1487
+ if (tokenReady && previous.identity !== identity || tokenRejected) convexQueryClient.resetAuthQueries();
1487
1488
  }, [
1488
1489
  convexQueryClient,
1489
1490
  isAuthenticated,
@@ -2431,6 +2432,12 @@ const getConvexQueryClientSingleton = ({ authStore, convex, queryClient, symbolK
2431
2432
  //#endregion
2432
2433
  //#region src/internal/pagination.ts
2433
2434
  const shouldSplitPaginationPage = (page, initialNumItems) => Boolean(page.splitCursor) && (page.pageStatus === "SplitRecommended" || page.pageStatus === "SplitRequired" || initialNumItems !== void 0 && page.page.length > initialNumItems * 2);
2435
+ const isInvalidPaginationCursor = (error) => {
2436
+ if (error instanceof Error && error.message.includes("InvalidCursor")) return true;
2437
+ if (!error || typeof error !== "object" || !("data" in error)) return false;
2438
+ const data = error.data;
2439
+ return Boolean(data && typeof data === "object" && "isConvexSystemError" in data && data.isConvexSystemError === true && "paginationError" in data && data.paginationError === "InvalidCursor");
2440
+ };
2434
2441
 
2435
2442
  //#endregion
2436
2443
  //#region src/react/use-infinite-query.ts
@@ -2438,76 +2445,22 @@ const shouldSplitPaginationPage = (page, initialNumItems) => Boolean(page.splitC
2438
2445
  const PAGINATION_KEY_PREFIX = "__pagination__";
2439
2446
  let paginationIdCounter = 0;
2440
2447
  const createPaginationId = () => ++paginationIdCounter;
2441
- /** Build a unique key for recovery attempt detection */
2442
- const buildRecoveryKey = (pageKeys, page0Cursor, page0UpdatedAt) => JSON.stringify({
2443
- pageKeys,
2444
- page0Cursor,
2445
- page0UpdatedAt
2446
- });
2447
2448
  /**
2448
2449
  * Hook for auto-recovering from stale cursors after WebSocket reconnection.
2449
2450
  *
2450
2451
  * When Convex WebSocket reconnects, page 0 (cursor: null) resubscribes and
2451
2452
  * gets fresh data. However, pages 1+ may have stale cursors that fail.
2452
2453
  *
2453
- * This hook detects this pattern and creates a recovery page that fetches
2454
- * enough items to cover the lost pages, preserving the user's scroll position.
2454
+ * This hook discards the invalid cursor chain and restarts from page one.
2455
2455
  */
2456
- const useStaleCursorRecovery = ({ argsObject, combined, limit, setState, state }) => {
2456
+ const useStaleCursorRecovery = ({ combined, resetPagination }) => {
2457
2457
  useEffect(() => {
2458
2458
  if (!combined.isFetchNextPageError) return;
2459
- const page0Result = combined._rawResults[0];
2460
- const page0Data = page0Result?.data;
2461
- const page0UpdatedAt = page0Result?.dataUpdatedAt ?? 0;
2462
- const hasPage0Data = page0Data !== void 0 && !page0Result?.isError;
2463
- const hasSubsequentErrors = combined._rawResults.slice(1).some((q) => q?.isError && !q?.isFetching);
2464
- if (!hasPage0Data || !hasSubsequentErrors || !page0Data?.continueCursor) return;
2465
- const recoveryKey = buildRecoveryKey(state.pageKeys, page0Data.continueCursor, page0UpdatedAt);
2466
- if (state.autoRecoveryAttempted === recoveryKey) return;
2467
- const erroredPageKeys = state.pageKeys.filter((_, i) => i > 0 && combined._rawResults[i]?.isError);
2468
- const itemsToRecover = erroredPageKeys.reduce((sum, key) => {
2469
- return sum + (state.queries[key]?.args?.limit ?? limit ?? 20);
2470
- }, 0);
2471
- console.warn("[Pagination] Auto-recovering from stale cursors", {
2472
- erroredPages: erroredPageKeys.length,
2473
- itemsToRecover
2474
- });
2475
- setState((prev) => ({
2476
- ...prev,
2477
- id: prev.id,
2478
- nextPageKey: 2,
2479
- pageKeys: [prev.pageKeys[0], 1],
2480
- queries: {
2481
- [prev.pageKeys[0]]: prev.queries[prev.pageKeys[0]],
2482
- 1: { args: {
2483
- ...argsObject,
2484
- cursor: page0Data.continueCursor,
2485
- limit: Math.min(itemsToRecover + (limit ?? 20), 500),
2486
- __paginationId: prev.id
2487
- } }
2488
- },
2489
- version: prev.version + 1,
2490
- autoRecoveryAttempted: recoveryKey
2491
- }));
2459
+ if (combined._rawResults.slice(1).some((result) => result?.isError && !result.isFetching && isInvalidPaginationCursor(result.error))) resetPagination();
2492
2460
  }, [
2493
2461
  combined.isFetchNextPageError,
2494
2462
  combined._rawResults,
2495
- state.pageKeys,
2496
- state.queries,
2497
- state.autoRecoveryAttempted,
2498
- argsObject,
2499
- limit,
2500
- setState
2501
- ]);
2502
- useEffect(() => {
2503
- if ((combined.status === "CanLoadMore" || combined.status === "Exhausted") && state.autoRecoveryAttempted) setState((prev) => ({
2504
- ...prev,
2505
- autoRecoveryAttempted: void 0
2506
- }));
2507
- }, [
2508
- combined.status,
2509
- state.autoRecoveryAttempted,
2510
- setState
2463
+ resetPagination
2511
2464
  ]);
2512
2465
  };
2513
2466
  /**
@@ -2705,7 +2658,7 @@ const useInfiniteQueryInternal = (query, args, options) => {
2705
2658
  error: results.find((r) => r.isError)?.error ?? null,
2706
2659
  isError: results.some((r) => r.isError),
2707
2660
  isFetching,
2708
- isFetchNextPageError: results.length > 1 && (results.at(-1)?.isError ?? false),
2661
+ isFetchNextPageError: results.slice(1).some((result) => result.isError),
2709
2662
  isPlaceholderData,
2710
2663
  isRefetching: isFetching && allItems.length > 0 && !isPlaceholderData,
2711
2664
  _rawResults: results
@@ -2713,11 +2666,8 @@ const useInfiniteQueryInternal = (query, args, options) => {
2713
2666
  }, [placeholderData])
2714
2667
  });
2715
2668
  useStaleCursorRecovery({
2716
- argsObject,
2717
2669
  combined,
2718
- limit,
2719
- setState,
2720
- state
2670
+ resetPagination: useCallback(() => setState(createInitialState()), [createInitialState, setState])
2721
2671
  });
2722
2672
  useEffect(() => {
2723
2673
  for (let i = 0; i < combined._rawResults.length; i++) {
@@ -2726,15 +2676,17 @@ const useInfiniteQueryInternal = (query, args, options) => {
2726
2676
  const page = pageQuery.data;
2727
2677
  const pageKey = state.pageKeys[i];
2728
2678
  const pageState = state.queries[pageKey];
2729
- if (shouldSplitPaginationPage(page, limit) && pageState && !pageState.endCursor) {
2679
+ if (shouldSplitPaginationPage(page, limit) && pageState && pageState.args.endCursor !== page.splitCursor) {
2730
2680
  setState((prev) => {
2731
2681
  const currentPageState = prev.queries[pageKey];
2732
- if (!currentPageState || currentPageState.endCursor) return prev;
2682
+ if (!currentPageState || currentPageState.args.endCursor === page.splitCursor) return prev;
2733
2683
  const newKey = prev.nextPageKey;
2734
2684
  const splitCursor = page.splitCursor;
2685
+ const endCursor = currentPageState.args.endCursor ?? page.continueCursor;
2735
2686
  const splitPageArgs = {
2736
2687
  ...argsObject,
2737
2688
  cursor: splitCursor,
2689
+ endCursor,
2738
2690
  limit: currentPageState.args.limit,
2739
2691
  __paginationId: prev.id
2740
2692
  };
@@ -2749,7 +2701,10 @@ const useInfiniteQueryInternal = (query, args, options) => {
2749
2701
  ...prev.queries,
2750
2702
  [pageKey]: {
2751
2703
  ...currentPageState,
2752
- endCursor: splitCursor
2704
+ args: {
2705
+ ...currentPageState.args,
2706
+ endCursor: splitCursor
2707
+ }
2753
2708
  },
2754
2709
  [newKey]: { args: splitPageArgs }
2755
2710
  }
@@ -1,7 +1,8 @@
1
1
  import { n as DeepPartial, o as Simplify, r as DistributiveOmit } from "../types-Bqi_ivSd.js";
2
- import { L as DataTransformerOptions, _ as CRPCHttpRouter, c as HttpQueryKey, k as HttpProcedure, o as HttpMutationKey, y as HttpRouterRecord } from "../http-types-BhhPZtwa.js";
3
- import { g as UnsetMarker } from "../types-Bkeicpo6.js";
4
- import { A as HttpInputArgs, C as ReservedMutationOptions$1, S as ReservedInfiniteQueryOptions, T as StaticQueryOptsParam, _ as IsPaginated, b as PaginatedFnMeta, c as ConvexMutationKey, d as ConvexQueryMeta, f as EmptyObject, g as InfiniteQueryInput, l as ConvexQueryHookOptions, m as FUNC_REF_SYMBOL, o as ConvexActionKey, p as ExtractPaginatedItem, s as ConvexInfiniteQueryMeta, u as ConvexQueryKey, w as ReservedQueryOptions$1, y as MutationVariables } from "../types-BXpu7xIU.js";
2
+ import { i as DataTransformerOptions } from "../transformer-BEkxlnss.js";
3
+ import { g as UnsetMarker } from "../types-CzGsrLrY.js";
4
+ import { _ as CRPCHttpRouter, c as HttpQueryKey, k as HttpProcedure, o as HttpMutationKey, y as HttpRouterRecord } from "../http-types-8FBr10yl.js";
5
+ import { A as HttpInputArgs, C as ReservedMutationOptions$1, S as ReservedInfiniteQueryOptions, T as StaticQueryOptsParam, _ as IsPaginated, b as PaginatedFnMeta, c as ConvexMutationKey, d as ConvexQueryMeta, f as EmptyObject, g as InfiniteQueryInput, l as ConvexQueryHookOptions, m as FUNC_REF_SYMBOL, o as ConvexActionKey, p as ExtractPaginatedItem, s as ConvexInfiniteQueryMeta, u as ConvexQueryKey, w as ReservedQueryOptions$1, y as MutationVariables } from "../types-Cl0utsTL.js";
5
6
  import { FunctionArgs, FunctionReference, FunctionReturnType } from "convex/server";
6
7
  import { z } from "zod";
7
8
  import { DefaultError, QueryFilters, SkipToken, UseMutationOptions, UseQueryOptions } from "@tanstack/react-query";