kitcn 0.23.0 → 0.24.0

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.
@@ -1,4 +1,4 @@
1
- import { C as ConvexNumberBuilderInitial, E as ConvexIdBuilderInitial, N as ConvexCustomBuilderInitial, dn as ConvexTableWithColumns, tr as ConvexTextBuilderInitial } from "../where-clause-compiler-B_H3oio5.js";
1
+ import { C as ConvexNumberBuilderInitial, E as ConvexIdBuilderInitial, N as ConvexCustomBuilderInitial, dn as ConvexTableWithColumns, tr as ConvexTextBuilderInitial } from "../where-clause-compiler-DW6jy2er.js";
2
2
  import * as convex_values0 from "convex/values";
3
3
  import { GenericId, Infer, Value } from "convex/values";
4
4
  import { DocumentByName, GenericDataModel, GenericDatabaseReader, GenericDatabaseWriter, TableNamesInDataModel } from "convex/server";
@@ -1,4 +1,4 @@
1
- import { H as ConvexContext, W as LazyCaller } from "../../procedure-name-C55TynK3.js";
1
+ import { H as ConvexContext, W as LazyCaller } from "../../procedure-name-C20pFZnk.js";
2
2
  import { t as GetTokenOptions } from "../../token-B9Bjcqug.js";
3
3
 
4
4
  //#region src/auth-nextjs/index.d.ts
package/dist/cli.mjs CHANGED
@@ -2506,7 +2506,7 @@ function QueryProvider({ children }: { children: ReactNode }) {
2506
2506
  const FUNCTIONS_DIR_IMPORT_PLACEHOLDER$5 = "__KITCN_FUNCTIONS_DIR__";
2507
2507
  const PLUGIN_CONFIG_IMPORT_PLACEHOLDER$1 = "__KITCN_PLUGIN_CONFIG_IMPORT__";
2508
2508
  const PLUGIN_SCHEMA_IMPORT_PLACEHOLDER$1 = "__KITCN_PLUGIN_SCHEMA_IMPORT__";
2509
- const PROJECT_CRPC_IMPORT_PLACEHOLDER$3 = "__KITCN_PROJECT_CRPC_IMPORT__";
2509
+ const PROJECT_CRPC_IMPORT_PLACEHOLDER$4 = "__KITCN_PROJECT_CRPC_IMPORT__";
2510
2510
  const PROJECT_SHARED_API_IMPORT_PLACEHOLDER = "__KITCN_PROJECT_SHARED_API_IMPORT__";
2511
2511
  const PROJECT_GET_ENV_IMPORT_PLACEHOLDER$2 = "__KITCN_PROJECT_GET_ENV_IMPORT__";
2512
2512
 
@@ -2536,7 +2536,7 @@ const INIT_HTTP_IMPORT_MARKER = "// __KITCN_HTTP_IMPORTS__";
2536
2536
  const INIT_HTTP_ROUTE_MARKER = " // __KITCN_HTTP_ROUTES__";
2537
2537
  const INIT_HTTP_TEMPLATE = `import { createHttpRouter } from 'kitcn/server';
2538
2538
  import { Hono } from 'hono';
2539
- import { router } from '${PROJECT_CRPC_IMPORT_PLACEHOLDER$3}';
2539
+ import { router } from '${PROJECT_CRPC_IMPORT_PLACEHOLDER$4}';
2540
2540
  ${INIT_HTTP_IMPORT_MARKER}
2541
2541
 
2542
2542
  const app = new Hono();
@@ -2849,7 +2849,7 @@ function resolveRelativeImportPath(filePath, targetFilePath) {
2849
2849
  return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2850
2850
  }
2851
2851
  function renderInitTemplateContent(params) {
2852
- return params.template.replaceAll(FUNCTIONS_DIR_IMPORT_PLACEHOLDER$5, resolveRelativeImportPath(params.filePath, params.functionsDir)).replaceAll(PROJECT_CRPC_IMPORT_PLACEHOLDER$3, resolveRelativeImportPath(params.filePath, params.crpcFilePath));
2852
+ return params.template.replaceAll(FUNCTIONS_DIR_IMPORT_PLACEHOLDER$5, resolveRelativeImportPath(params.filePath, params.functionsDir)).replaceAll(PROJECT_CRPC_IMPORT_PLACEHOLDER$4, resolveRelativeImportPath(params.filePath, params.crpcFilePath));
2853
2853
  }
2854
2854
 
2855
2855
  //#endregion
@@ -3424,7 +3424,7 @@ const resolvePluginScaffoldFiles = (templates, roots, functionsDir, existingTemp
3424
3424
  const lockfilePath = normalizeLockfileScaffoldPath(mappedLockfilePath) ?? normalizePath$2(relative(process.cwd(), join(rootDir, template.path)));
3425
3425
  const filePath = resolve(process.cwd(), lockfilePath);
3426
3426
  const getEnvImportPath = resolveProjectGetEnvImportPrefix(filePath, roots.envFilePath);
3427
- const content = template.content.replaceAll(FUNCTIONS_DIR_IMPORT_PLACEHOLDER$5, resolveFunctionsDirImportPrefix(filePath, functionsDir)).replaceAll(PROJECT_CRPC_IMPORT_PLACEHOLDER$3, resolveProjectCrpcImportPrefix(filePath, roots.crpcFilePath)).replaceAll(PROJECT_SHARED_API_IMPORT_PLACEHOLDER, resolveProjectSharedApiImportPrefix(filePath, roots.sharedApiFilePath)).replaceAll(PROJECT_GET_ENV_IMPORT_PLACEHOLDER$2, `import { getEnv } from '${getEnvImportPath}';`).replaceAll(PLUGIN_CONFIG_IMPORT_PLACEHOLDER$1, resolvePluginConfigImportPrefix(filePath, roots.libRootDir)).replaceAll(PLUGIN_SCHEMA_IMPORT_PLACEHOLDER$1, resolvePluginSchemaImportPrefix(filePath, roots.libRootDir));
3427
+ const content = template.content.replaceAll(FUNCTIONS_DIR_IMPORT_PLACEHOLDER$5, resolveFunctionsDirImportPrefix(filePath, functionsDir)).replaceAll(PROJECT_CRPC_IMPORT_PLACEHOLDER$4, resolveProjectCrpcImportPrefix(filePath, roots.crpcFilePath)).replaceAll(PROJECT_SHARED_API_IMPORT_PLACEHOLDER, resolveProjectSharedApiImportPrefix(filePath, roots.sharedApiFilePath)).replaceAll(PROJECT_GET_ENV_IMPORT_PLACEHOLDER$2, `import { getEnv } from '${getEnvImportPath}';`).replaceAll(PLUGIN_CONFIG_IMPORT_PLACEHOLDER$1, resolvePluginConfigImportPrefix(filePath, roots.libRootDir)).replaceAll(PLUGIN_SCHEMA_IMPORT_PLACEHOLDER$1, resolvePluginSchemaImportPrefix(filePath, roots.libRootDir));
3428
3428
  if (!(descriptor.key === "auth" && preset === "convex") && (template.target === "functions" || template.target === "lib") && content.includes("process.env")) throw new Error(`Scaffold template "${descriptor.key}/${template.id}" contains process.env. Use getEnv() instead.`);
3429
3429
  return {
3430
3430
  templateId: template.id,
@@ -6776,10 +6776,46 @@ const authRegistryItem = defineInternalRegistryItem({
6776
6776
  }
6777
6777
  });
6778
6778
 
6779
+ //#endregion
6780
+ //#region src/cli/registry/items/ratelimit/ratelimit-functions.template.ts
6781
+ const PROJECT_CRPC_IMPORT_PLACEHOLDER$3 = "__KITCN_PROJECT_CRPC_IMPORT__";
6782
+ const RATELIMIT_FUNCTIONS_TEMPLATE = `import { cleanupRatelimitState } from "kitcn/ratelimit";
6783
+ import { z } from "zod";
6784
+ import { privateMutation } from "${PROJECT_CRPC_IMPORT_PLACEHOLDER$3}";
6785
+
6786
+ const DEFAULT_BATCH_SIZE = 500;
6787
+
6788
+ export const cleanup = privateMutation
6789
+ .input(
6790
+ z.object({
6791
+ olderThanMs: z.number().positive(),
6792
+ limit: z.number().int().min(1).max(1000).optional(),
6793
+ })
6794
+ )
6795
+ .output(
6796
+ z.object({
6797
+ deleted: z.number(),
6798
+ hasMore: z.boolean(),
6799
+ })
6800
+ )
6801
+ .mutation(async ({ ctx, input }) =>
6802
+ cleanupRatelimitState(ctx.db, {
6803
+ before: Date.now() - input.olderThanMs,
6804
+ limit: input.limit ?? DEFAULT_BATCH_SIZE,
6805
+ })
6806
+ );
6807
+ `;
6808
+
6779
6809
  //#endregion
6780
6810
  //#region src/cli/registry/items/ratelimit/ratelimit-plugin.template.ts
6781
6811
  const FUNCTIONS_DIR_IMPORT_PLACEHOLDER$4 = "__KITCN_FUNCTIONS_DIR__";
6782
- const RATELIMIT_PLUGIN_TEMPLATE = `import { MINUTE, Ratelimit, RatelimitPlugin } from "kitcn/ratelimit";
6812
+ const RATELIMIT_PLUGIN_TEMPLATE = `import {
6813
+ type LimitRequest,
6814
+ MINUTE,
6815
+ Ratelimit,
6816
+ RatelimitPlugin,
6817
+ SECOND,
6818
+ } from "kitcn/ratelimit";
6783
6819
  import type { MutationCtx } from "${FUNCTIONS_DIR_IMPORT_PLACEHOLDER$4}/generated/server";
6784
6820
 
6785
6821
  const fixed = (rate: number) => Ratelimit.fixedWindow(rate, MINUTE);
@@ -6790,6 +6826,11 @@ export const ratelimitBuckets = {
6790
6826
  free: fixed(60),
6791
6827
  premium: fixed(200),
6792
6828
  },
6829
+ interactive: {
6830
+ public: Ratelimit.fixedWindow(3, 30 * SECOND),
6831
+ free: Ratelimit.fixedWindow(3, 30 * SECOND),
6832
+ premium: Ratelimit.fixedWindow(3, 30 * SECOND),
6833
+ },
6793
6834
  } as const;
6794
6835
 
6795
6836
  type RatelimitTier = keyof (typeof ratelimitBuckets)["default"];
@@ -6829,14 +6870,38 @@ async function getRequestSignals(ctx: RatelimitCtx) {
6829
6870
  };
6830
6871
  }
6831
6872
 
6873
+ /**
6874
+ * The identifier is the rate-limit partition key: everything that resolves to
6875
+ * the same string shares one budget and one \`ratelimitState\` document.
6876
+ *
6877
+ * Unauthenticated traffic is keyed by request IP so one visitor cannot spend
6878
+ * every other visitor's budget. Calls without request metadata all fall back
6879
+ * to one key.
6880
+ */
6881
+ function getRequestIdentifier(
6882
+ user: RatelimitUser | null,
6883
+ signals: LimitRequest | undefined
6884
+ ) {
6885
+ if (user) {
6886
+ return user.id;
6887
+ }
6888
+
6889
+ return signals?.ip ? \`ip:\${signals.ip}\` : "ip:unknown";
6890
+ }
6891
+
6832
6892
  export const ratelimit = RatelimitPlugin.configure({
6833
6893
  buckets: ratelimitBuckets,
6834
6894
  getBucket: ({ meta }: { meta: RatelimitMeta }) => meta.ratelimit ?? "default",
6835
6895
  getUser: ({ ctx }: { ctx: RatelimitCtx }) => ctx.user ?? null,
6836
- getIdentifier: ({ user }: { user: RatelimitUser | null }) =>
6837
- user?.id ?? "anonymous",
6838
6896
  getTier: getUserTier,
6839
6897
  getSignals: ({ ctx }: { ctx: RatelimitCtx }) => getRequestSignals(ctx),
6898
+ getIdentifier: ({
6899
+ user,
6900
+ signals,
6901
+ }: {
6902
+ user: RatelimitUser | null;
6903
+ signals: LimitRequest | undefined;
6904
+ }) => getRequestIdentifier(user, signals),
6840
6905
  prefix: ({ bucket, tier }) => \`ratelimit:\${bucket}:\${tier}\`,
6841
6906
  failureMode: "closed",
6842
6907
  enableProtection: true,
@@ -6869,6 +6934,7 @@ export const ratelimitStateTable = convexTable(
6869
6934
  (t) => [
6870
6935
  index("by_name_key_shard").on(t.name, t.key, t.shard),
6871
6936
  index("by_name_key").on(t.name, t.key),
6937
+ index("by_ts").on(t.ts),
6872
6938
  ],
6873
6939
  );
6874
6940
 
@@ -6909,18 +6975,28 @@ export function ratelimitExtension() {
6909
6975
 
6910
6976
  //#endregion
6911
6977
  //#region src/cli/registry/items/ratelimit/ratelimit-item.ts
6912
- const RATELIMIT_FILES = [createRegistryFile({
6913
- id: "ratelimit-schema",
6914
- path: "schema.ts",
6915
- target: "lib",
6916
- content: RATELIMIT_SCHEMA_TEMPLATE
6917
- }), createRegistryFile({
6918
- id: "ratelimit-plugin",
6919
- path: "plugin.ts",
6920
- target: "lib",
6921
- content: RATELIMIT_PLUGIN_TEMPLATE,
6922
- requires: ["ratelimit-schema"]
6923
- })];
6978
+ const RATELIMIT_FILES = [
6979
+ createRegistryFile({
6980
+ id: "ratelimit-schema",
6981
+ path: "schema.ts",
6982
+ target: "lib",
6983
+ content: RATELIMIT_SCHEMA_TEMPLATE
6984
+ }),
6985
+ createRegistryFile({
6986
+ id: "ratelimit-functions",
6987
+ path: "ratelimit.ts",
6988
+ target: "functions",
6989
+ content: RATELIMIT_FUNCTIONS_TEMPLATE,
6990
+ requires: ["ratelimit-schema"]
6991
+ }),
6992
+ createRegistryFile({
6993
+ id: "ratelimit-plugin",
6994
+ path: "plugin.ts",
6995
+ target: "lib",
6996
+ content: RATELIMIT_PLUGIN_TEMPLATE,
6997
+ requires: ["ratelimit-schema"]
6998
+ })
6999
+ ];
6924
7000
  function buildRatelimitCrpcRegistrationPlanFile(params) {
6925
7001
  const crpcPath = getCrpcFilePath(params.config);
6926
7002
  const baselineCrpcSource = renderInitTemplateContent({
@@ -6966,7 +7042,7 @@ const ratelimitRegistryItem = defineInternalRegistryItem({
6966
7042
  presets: [{
6967
7043
  name: "server-first",
6968
7044
  description: "Scaffold a reusable ratelimit plugin and auto-register schema extension.",
6969
- registryDependencies: ["ratelimit-schema", "ratelimit-plugin"]
7045
+ registryDependencies: RATELIMIT_FILES.map((file) => file.meta.id)
6970
7046
  }, {
6971
7047
  name: "schema-only",
6972
7048
  description: "Only register ratelimit extension in schema.",
@@ -1,5 +1,5 @@
1
- import { A as DataTransformer, F as decodeWire, I as defaultCRPCTransformer, L as encodeWire, M as WireCodec, N as createTaggedTransformer, O as CombinedDataTransformer, P as dateWireCodec, R as getTransformer, a as HttpProcedureCall, c as InferHttpInput, i as HttpErrorCode, j as DataTransformerOptions, k as DATE_CODEC_TAG, l as InferHttpOutput, n as HttpClientError, o as HttpRouteInfo, r as HttpClientFromRouter, s as HttpRouteMap, t as HttpClient, u as isHttpClientError, z as identityTransformer } from "../http-types-BoSDAh4Y.js";
2
- import { A as HttpInputArgs, C as ReservedMutationOptions, D as VanillaMutation, E as VanillaAction, F as replaceUrlParam, M as RESERVED_KEYS, N as buildSearchParams, O as HttpClientOptions, P as executeHttpRequest, S as ReservedInfiniteQueryOptions, T as StaticQueryOptsParam, _ as IsPaginated, a as BaseInfiniteQueryOptsParam, b as PaginatedFnMeta, c as ConvexMutationKey, d as ConvexQueryMeta, f as EmptyObject, g as InfiniteQueryInput, h as FnMeta, i as BaseConvexQueryOptions, j as HttpProxyBaseOptions, k as HttpFormValue, l as ConvexQueryHookOptions, m as FUNC_REF_SYMBOL, n as BaseConvexActionOptions, o as ConvexActionKey, p as ExtractPaginatedItem, r as BaseConvexInfiniteQueryOptions, s as ConvexInfiniteQueryMeta, t as AuthType, u as ConvexQueryKey, v as Meta, w as ReservedQueryOptions, x as PaginationOpts, y as MutationVariables } from "../types-C0Xl7P8K.js";
1
+ import { B as dateWireCodec, F as DATE_CODEC_TAG, G as identityTransformer, H as defaultCRPCTransformer, I as DataTransformer, L as DataTransformerOptions, P as CombinedDataTransformer, R as WireCodec, U as encodeWire, V as decodeWire, W as getTransformer, a as HttpErrorCode, c as HttpQueryKey, d as HttpRouteMap, f as InferHttpInput, g as isHttpClientError, h as buildHttpQueryPrefixKey, i as HttpClientFromRouter, l as HttpQueryPrefixKey, m as buildHttpQueryKey, n as HttpClient, o as HttpMutationKey, p as InferHttpOutput, r as HttpClientError, s as HttpProcedureCall, t as HTTP_DEFAULT_STALE_TIME, u as HttpRouteInfo, z as createTaggedTransformer } from "../http-types-DXOgaerG.js";
2
+ import { A as HttpInputArgs, C as ReservedMutationOptions, D as VanillaMutation, E as VanillaAction, F as replaceUrlParam, M as RESERVED_KEYS, N as buildSearchParams, O as HttpClientOptions, P as executeHttpRequest, S as ReservedInfiniteQueryOptions, T as StaticQueryOptsParam, _ as IsPaginated, a as BaseInfiniteQueryOptsParam, b as PaginatedFnMeta, c as ConvexMutationKey, d as ConvexQueryMeta, f as EmptyObject, g as InfiniteQueryInput, h as FnMeta, i as BaseConvexQueryOptions, j as HttpProxyBaseOptions, k as HttpFormValue, l as ConvexQueryHookOptions, m as FUNC_REF_SYMBOL, n as BaseConvexActionOptions, o as ConvexActionKey, p as ExtractPaginatedItem, r as BaseConvexInfiniteQueryOptions, s as ConvexInfiniteQueryMeta, t as AuthType, u as ConvexQueryKey, v as Meta, w as ReservedQueryOptions, x as PaginationOpts, y as MutationVariables } from "../types-BHR7ZKKD.js";
3
3
  import { FunctionArgs, FunctionReference } from "convex/server";
4
4
 
5
5
  //#region src/crpc/auth-error.d.ts
@@ -102,4 +102,4 @@ declare function convexAction<T extends FunctionReference<'action'>>(funcRef: T,
102
102
  */
103
103
  declare function convexInfiniteQueryOptions<T extends FunctionReference<'query'>>(funcRef: T, args: Record<string, unknown> | 'skip', opts?: BaseInfiniteQueryOptsParam<T> & Record<string, unknown>, meta?: Meta): BaseConvexInfiniteQueryOptions<T> & Record<string, unknown>;
104
104
  //#endregion
105
- export { AuthMutationError, AuthType, BaseConvexActionOptions, BaseConvexInfiniteQueryOptions, BaseConvexQueryOptions, BaseInfiniteQueryOptsParam, CRPCClientError, CombinedDataTransformer, ConvexActionKey, ConvexInfiniteQueryMeta, ConvexMutationKey, ConvexQueryHookOptions, ConvexQueryKey, ConvexQueryMeta, DATE_CODEC_TAG, DataTransformer, DataTransformerOptions, EmptyObject, ExtractPaginatedItem, FUNC_REF_SYMBOL, FnMeta, HttpClient, HttpClientError, HttpClientFromRouter, HttpClientOptions, HttpErrorCode, HttpFormValue, HttpInputArgs, HttpProcedureCall, HttpProxyBaseOptions, HttpRouteInfo, HttpRouteMap, InferHttpInput, InferHttpOutput, InfiniteQueryInput, IsPaginated, Meta, MutationVariables, PaginatedFnMeta, PaginationOpts, RESERVED_KEYS, ReservedInfiniteQueryOptions, ReservedMutationOptions, ReservedQueryOptions, StaticQueryOptsParam, VanillaAction, VanillaMutation, WireCodec, buildSearchParams, convexAction, convexInfiniteQueryOptions, convexQuery, createTaggedTransformer, dateWireCodec, decodeWire, defaultCRPCTransformer, defaultIsUnauthorized, encodeWire, executeHttpRequest, getTransformer, identityTransformer, isAuthMutationError, isCRPCClientError, isCRPCError, isCRPCErrorCode, isHttpClientError, replaceUrlParam };
105
+ export { AuthMutationError, AuthType, BaseConvexActionOptions, BaseConvexInfiniteQueryOptions, BaseConvexQueryOptions, BaseInfiniteQueryOptsParam, CRPCClientError, CombinedDataTransformer, ConvexActionKey, ConvexInfiniteQueryMeta, ConvexMutationKey, ConvexQueryHookOptions, ConvexQueryKey, ConvexQueryMeta, DATE_CODEC_TAG, DataTransformer, DataTransformerOptions, EmptyObject, ExtractPaginatedItem, FUNC_REF_SYMBOL, FnMeta, HTTP_DEFAULT_STALE_TIME, HttpClient, HttpClientError, HttpClientFromRouter, HttpClientOptions, HttpErrorCode, HttpFormValue, HttpInputArgs, HttpMutationKey, HttpProcedureCall, HttpProxyBaseOptions, HttpQueryKey, HttpQueryPrefixKey, HttpRouteInfo, HttpRouteMap, InferHttpInput, InferHttpOutput, InfiniteQueryInput, IsPaginated, Meta, MutationVariables, PaginatedFnMeta, PaginationOpts, RESERVED_KEYS, ReservedInfiniteQueryOptions, ReservedMutationOptions, ReservedQueryOptions, StaticQueryOptsParam, VanillaAction, VanillaMutation, WireCodec, buildHttpQueryKey, buildHttpQueryPrefixKey, buildSearchParams, convexAction, convexInfiniteQueryOptions, convexQuery, createTaggedTransformer, dateWireCodec, decodeWire, defaultCRPCTransformer, defaultIsUnauthorized, encodeWire, executeHttpRequest, getTransformer, identityTransformer, isAuthMutationError, isCRPCClientError, isCRPCError, isCRPCErrorCode, isHttpClientError, replaceUrlParam };
@@ -1,6 +1,6 @@
1
1
  import { a as isCRPCErrorCode, i as isCRPCError, n as defaultIsUnauthorized, r as isCRPCClientError, t as CRPCClientError } from "../error-Bvo7YEhk.js";
2
2
  import { a as defaultCRPCTransformer, c as identityTransformer, i as decodeWire, n as createTaggedTransformer, o as encodeWire, r as dateWireCodec, s as getTransformer, t as DATE_CODEC_TAG } from "../transformer-yZuBWo8v.js";
3
- import { a as buildSearchParams, c as HttpClientError, i as RESERVED_KEYS, l as isHttpClientError, n as convexInfiniteQueryOptions, o as executeHttpRequest, r as convexQuery, s as replaceUrlParam, t as convexAction } from "../query-options-C_eBSIXG.js";
3
+ import { a as buildSearchParams, c as HTTP_DEFAULT_STALE_TIME, d as buildHttpQueryPrefixKey, f as isHttpClientError, i as RESERVED_KEYS, l as HttpClientError, n as convexInfiniteQueryOptions, o as executeHttpRequest, r as convexQuery, s as replaceUrlParam, t as convexAction, u as buildHttpQueryKey } from "../query-options-CzRV4G4N.js";
4
4
 
5
5
  //#region src/crpc/auth-error.ts
6
6
  /**
@@ -40,4 +40,4 @@ function isAuthMutationError(error) {
40
40
  const FUNC_REF_SYMBOL = Symbol.for("convex.funcRef");
41
41
 
42
42
  //#endregion
43
- export { AuthMutationError, CRPCClientError, DATE_CODEC_TAG, FUNC_REF_SYMBOL, HttpClientError, RESERVED_KEYS, buildSearchParams, convexAction, convexInfiniteQueryOptions, convexQuery, createTaggedTransformer, dateWireCodec, decodeWire, defaultCRPCTransformer, defaultIsUnauthorized, encodeWire, executeHttpRequest, getTransformer, identityTransformer, isAuthMutationError, isCRPCClientError, isCRPCError, isCRPCErrorCode, isHttpClientError, replaceUrlParam };
43
+ export { AuthMutationError, CRPCClientError, DATE_CODEC_TAG, FUNC_REF_SYMBOL, HTTP_DEFAULT_STALE_TIME, HttpClientError, RESERVED_KEYS, buildHttpQueryKey, buildHttpQueryPrefixKey, buildSearchParams, convexAction, convexInfiniteQueryOptions, convexQuery, createTaggedTransformer, dateWireCodec, decodeWire, defaultCRPCTransformer, defaultIsUnauthorized, encodeWire, executeHttpRequest, getTransformer, identityTransformer, isAuthMutationError, isCRPCClientError, isCRPCError, isCRPCErrorCode, isHttpClientError, replaceUrlParam };
@@ -261,6 +261,36 @@ type HttpRouteInfo = {
261
261
  };
262
262
  /** Route map type - from codegen */
263
263
  type HttpRouteMap = Record<string, HttpRouteInfo>;
264
+ /** Exact cache key for one route + args, as stored in the QueryClient */
265
+ type HttpQueryKey = readonly ['httpQuery', string, unknown];
266
+ /** Route-wide prefix key that matches every args variant of one route */
267
+ type HttpQueryPrefixKey = readonly ['httpQuery', string];
268
+ /** Mutation key for HTTP endpoints */
269
+ type HttpMutationKey = readonly ['httpMutation', string];
270
+ /**
271
+ * Build the exact cache key for an HTTP route.
272
+ *
273
+ * Missing args normalize to `{}` so the RSC prefetch, the browser observer, and
274
+ * a hand-written `getQueryData` call all hash to the same key. Every producer
275
+ * of an `httpQuery` cache key goes through here.
276
+ */
277
+ declare function buildHttpQueryKey(routeKey: string, args?: unknown): HttpQueryKey;
278
+ /**
279
+ * Build the route-wide prefix key.
280
+ *
281
+ * Filters match on prefix, so this matches every args variant of the route.
282
+ * Not a cache key: nothing is ever stored under it.
283
+ */
284
+ declare function buildHttpQueryPrefixKey(routeKey: string): HttpQueryPrefixKey;
285
+ /**
286
+ * Freshness window for `crpc.http.*` routes, in milliseconds.
287
+ *
288
+ * HTTP routes are a pull model with no push channel, so hydrated data needs a
289
+ * real freshness window or the browser refetches it on mount. The RSC
290
+ * QueryClient reads the same constant, so the server dedupe window and the
291
+ * client freshness window cannot drift apart.
292
+ */
293
+ declare const HTTP_DEFAULT_STALE_TIME = 30000;
264
294
  /** Infer schema type or return empty object if UnsetMarker */
265
295
  type InferSchemaOrEmpty<T> = T extends UnsetMarker ? object : T extends z.ZodTypeAny ? z.infer<T> : object;
266
296
  /**
@@ -305,4 +335,4 @@ declare class HttpClientError extends Error {
305
335
  /** Type guard for HttpClientError */
306
336
  declare const isHttpClientError: (error: unknown) => error is HttpClientError;
307
337
  //#endregion
308
- export { DataTransformer as A, HttpProcedure as C, ProcedureMeta as D, InferHttpInput$1 as E, decodeWire as F, defaultCRPCTransformer as I, encodeWire as L, WireCodec as M, createTaggedTransformer as N, CombinedDataTransformer as O, dateWireCodec as P, getTransformer as R, HttpMethod as S, HttpRouteDefinition as T, extractRouteMap as _, HttpProcedureCall as a, HttpActionHandler as b, InferHttpInput as c, CRPCHttpRouter as d, HttpRouterDef as f, createHttpRouterFactory as g, createHttpRouter as h, HttpErrorCode as i, DataTransformerOptions as j, DATE_CODEC_TAG as k, InferHttpOutput as l, HttpRouterWithHono as m, HttpClientError as n, HttpRouteInfo as o, HttpRouterRecord as p, HttpClientFromRouter as r, HttpRouteMap as s, HttpClient as t, isHttpClientError as u, CRPCHonoHandler as v, HttpProcedureBuilderDef as w, HttpHandlerOpts as x, HttpActionConstructor as y, identityTransformer as z };
338
+ export { HttpProcedureBuilderDef as A, dateWireCodec as B, extractRouteMap as C, HttpHandlerOpts as D, HttpActionHandler as E, DATE_CODEC_TAG as F, identityTransformer as G, defaultCRPCTransformer as H, DataTransformer as I, DataTransformerOptions as L, InferHttpInput$1 as M, ProcedureMeta as N, HttpMethod as O, CombinedDataTransformer as P, WireCodec as R, createHttpRouterFactory as S, HttpActionConstructor as T, encodeWire as U, decodeWire as V, getTransformer as W, CRPCHttpRouter as _, HttpErrorCode as a, HttpRouterWithHono as b, HttpQueryKey as c, HttpRouteMap as d, InferHttpInput as f, isHttpClientError as g, buildHttpQueryPrefixKey as h, HttpClientFromRouter as i, HttpRouteDefinition as j, HttpProcedure as k, HttpQueryPrefixKey as l, buildHttpQueryKey as m, HttpClient as n, HttpMutationKey as o, InferHttpOutput as p, HttpClientError as r, HttpProcedureCall as s, HTTP_DEFAULT_STALE_TIME as t, HttpRouteInfo as u, HttpRouterDef as v, CRPCHonoHandler as w, createHttpRouter as x, HttpRouterRecord as y, createTaggedTransformer as z };
@@ -1,4 +1,4 @@
1
- import { $ as GenericOrmCtx$1, $n as unique, $r as endsWith, $t as ManyConfig, A as ConvexDateMode, An as ConvexRankIndexBuilder, Ar as ReturningResult, At as MigrationManifestEntry, B as ConvexBytesBuilderInitial, Bn as rankIndex, Br as OrmSchemaRelations, Bt as defineMigration, C as ConvexNumberBuilderInitial, Ci as ColumnBuilderWithTableName, Cn as RlsRole, Cr as MutationReturning, Ct as MigrationStatusArgs, D as id, Di as IsPrimaryKey, Dn as ConvexAggregateIndexBuilderOn, Dr as PaginatedResult, Dt as MigrationDoc, E as ConvexIdBuilderInitial, Ei as HasDefault, En as ConvexAggregateIndexBuilder, Er as OrderDirection, Et as MigrationDirection, F as custom, Fn as ConvexVectorIndexBuilder, Fr as unsetToken, Ft as MigrationStateMap, G as ConvexBigIntBuilder, Gn as ConvexCheckConfig, Gr as ExpressionVisitor, Gt as OrmReader$1, H as ConvexBooleanBuilder, Hn as uniqueIndex, Hr as TableName, Ht as detectMigrationDrift, I as json, In as ConvexVectorIndexBuilderOn, Ir as Brand, It as MigrationStep, J as CountBackfillChunkArgs, Jn as ConvexUniqueConstraintBuilder, Jr as LogicalExpression, Jt as RlsMode, K as ConvexBigIntBuilderInitial, Kn as ConvexForeignKeyBuilder, Kr as FieldReference, Kt as OrmWriter$1, L as objectOf, Ln as ConvexVectorIndexConfig, Lr as Columns, Lt as MigrationTableName, M as ConvexCustomBuilder, Mn as ConvexSearchIndexBuilder, Mr as UpdateSet, Mt as MigrationPlan, N as ConvexCustomBuilderInitial, Nn as ConvexSearchIndexBuilderOn, Nr as VectorQueryConfig, Nt as MigrationRunStatus, O as ConvexDateBuilder, Oi as IsUnique, On as ConvexIndexBuilder, Or as PredicateWhereIndexConfig, Ot as MigrationDocContext, P as arrayOf, Pn as ConvexSearchIndexConfig, Pr as VectorSearchProvider, Pt as MigrationSet, Q as GenericOrm$1, Qn as foreignKey, Qr as contains, Qt as ExtractTablesWithRelations, R as unionOf, Rn as aggregateIndex, Rr as OrmSchemaExtensionTables, Rt as MigrationWriteMode, S as ConvexNumberBuilder, Si as ColumnBuilderTypeConfig, Sn as rlsPolicy, Sr as MutationResult, St as MigrationRunChunkArgs, T as ConvexIdBuilder, Ti as DrizzleEntity, Tn as rlsRole, Tr as OrderByClause, Tt as MigrationDefinition, U as ConvexBooleanBuilderInitial, Un as vectorIndex, Ur as SystemFields, Ut as DatabaseWithMutations, V as bytes, Vn as searchIndex, Vr as OrmSchemaTriggers, Vt as defineMigrationSet, W as boolean, Wn as ConvexCheckBuilder, Wr as BinaryExpression, Wt as DatabaseWithQuery, X as CountBackfillStatusArgs, Xn as ConvexUniqueConstraintConfig, Xr as and, Xt as extractRelationsConfig, Y as CountBackfillKickoffArgs, Yn as ConvexUniqueConstraintBuilderOn, Yr as UnaryExpression, Yt as EdgeMetadata, Z as CreateOrmOptions, Zn as check, Zr as between, Zt as ExtractTablesFromSchema, _ as ConvexTimestampMode, _i as startsWith, _n as deletion, _r as MutationExecuteConfig, _t as OrmTriggerContext, a as requireSchemaRelations, ai as inArray, an as TablesRelationalConfig, ar as AggregateResult, at as OrmWriterCtx, b as ConvexTextEnumBuilderInitial, bi as ColumnBuilderBaseConfig, bn as RlsPolicyConfig, br as MutationPaginateConfig, bt as MigrationCancelArgs, c as TableConfigResult, ci as isNull, cn as ConvexDeletionBuilder, cr as CountConfig, ct as ScheduledMutationBatchArgs, d as OrmNotFoundError, di as lte, dn as ConvexTableWithColumns, dr as FilterOperators, dt as scheduledDeleteFactory, ei as eq, en as OneConfig, er as ConvexTextBuilder, et as OrmApiResult, f as ConvexVectorBuilder, fi as ne, fn as DiscriminatorBuilderConfig, fr as GetColumnData, ft as SchemaExtension, g as ConvexTimestampBuilderInitial, gi as or, gn as convexTable, gr as InsertValue, gt as OrmTriggerChange, h as ConvexTimestampBuilder, hi as notInArray, hn as TableConfig, hr as InferSelectModel, ht as OrmTableTriggers, i as getSchemaTriggers, ii as ilike, in as TableRelationalConfig, ir as AggregateFieldValue, it as OrmReaderCtx, j as date, jn as ConvexRankIndexBuilderOn, jr as ReturningSelection, jt as MigrationMigrateOne, k as ConvexDateBuilderInitial, ki as NotNull, kn as ConvexIndexBuilderOn, kr as ReturningAll, kt as MigrationDriftIssue, l as getTableColumns, li as like, ln as ConvexDeletionConfig, lr as CountResult, lt as scheduledMutationBatchFactory, m as vector, mi as notBetween, mn as OrmLifecycleOperation, mr as InferModelFromColumns, mt as OrmBeforeResult, n as defineSchema, ni as gt, nn as RelationsBuilderColumnBase, nr as text, nt as OrmClientWithApi$1, o as asc, oi as isFieldReference, on as defineRelations, or as BuildQueryResult, ot as ResolveOrmSchema, p as ConvexVectorBuilderInitial, pi as not, pn as OrmLifecycleChange, pr as InferInsertModel, pt as defineSchemaExtension, q as bigint, qn as ConvexForeignKeyConfig, qr as FilterExpression, qt as RlsContext, r as getSchemaRelations, ri as gte, rn as RelationsBuilderColumnConfig, rr as AggregateConfig, rt as OrmFunctions, s as desc, si as isNotNull, sn as defineRelationsPart, sr as BuildRelationResult, st as createOrm, t as WhereClauseResult, ti as fieldRef, tn as RelationsBuilder, tr as ConvexTextBuilderInitial, tt as OrmClientBase$1, u as getTableConfig, ui as lt, un as ConvexTable, ur as DBQueryConfig, ut as ScheduledDeleteArgs, v as timestamp, vi as AnyColumn, vn as discriminator, vr as MutationExecuteResult, vt as OrmTriggers, w as integer, wi as ColumnDataType, wn as RlsRoleConfig, wr as MutationRunMode, wt as MigrationAppliedState, x as textEnum, xi as ColumnBuilderRuntimeConfig, xn as RlsPolicyToOption, xr as MutationPaginatedResult, xt as MigrationRunArgs, y as ConvexTextEnumBuilder, yi as ColumnBuilder, yn as RlsPolicy, yr as MutationExecutionMode, yt as defineTriggers, z as ConvexBytesBuilder, zn as index, zr as OrmSchemaExtensions, zt as buildMigrationPlan } from "../where-clause-compiler-B_H3oio5.js";
1
+ import { $ as GenericOrmCtx$1, $n as unique, $r as endsWith, $t as ManyConfig, A as ConvexDateMode, An as ConvexRankIndexBuilder, Ar as ReturningResult, At as MigrationManifestEntry, B as ConvexBytesBuilderInitial, Bn as rankIndex, Br as OrmSchemaRelations, Bt as defineMigration, C as ConvexNumberBuilderInitial, Ci as ColumnBuilderWithTableName, Cn as RlsRole, Cr as MutationReturning, Ct as MigrationStatusArgs, D as id, Di as IsPrimaryKey, Dn as ConvexAggregateIndexBuilderOn, Dr as PaginatedResult, Dt as MigrationDoc, E as ConvexIdBuilderInitial, Ei as HasDefault, En as ConvexAggregateIndexBuilder, Er as OrderDirection, Et as MigrationDirection, F as custom, Fn as ConvexVectorIndexBuilder, Fr as unsetToken, Ft as MigrationStateMap, G as ConvexBigIntBuilder, Gn as ConvexCheckConfig, Gr as ExpressionVisitor, Gt as OrmReader$1, H as ConvexBooleanBuilder, Hn as uniqueIndex, Hr as TableName, Ht as detectMigrationDrift, I as json, In as ConvexVectorIndexBuilderOn, Ir as Brand, It as MigrationStep, J as CountBackfillChunkArgs, Jn as ConvexUniqueConstraintBuilder, Jr as LogicalExpression, Jt as RlsMode, K as ConvexBigIntBuilderInitial, Kn as ConvexForeignKeyBuilder, Kr as FieldReference, Kt as OrmWriter$1, L as objectOf, Ln as ConvexVectorIndexConfig, Lr as Columns, Lt as MigrationTableName, M as ConvexCustomBuilder, Mn as ConvexSearchIndexBuilder, Mr as UpdateSet, Mt as MigrationPlan, N as ConvexCustomBuilderInitial, Nn as ConvexSearchIndexBuilderOn, Nr as VectorQueryConfig, Nt as MigrationRunStatus, O as ConvexDateBuilder, Oi as IsUnique, On as ConvexIndexBuilder, Or as PredicateWhereIndexConfig, Ot as MigrationDocContext, P as arrayOf, Pn as ConvexSearchIndexConfig, Pr as VectorSearchProvider, Pt as MigrationSet, Q as GenericOrm$1, Qn as foreignKey, Qr as contains, Qt as ExtractTablesWithRelations, R as unionOf, Rn as aggregateIndex, Rr as OrmSchemaExtensionTables, Rt as MigrationWriteMode, S as ConvexNumberBuilder, Si as ColumnBuilderTypeConfig, Sn as rlsPolicy, Sr as MutationResult, St as MigrationRunChunkArgs, T as ConvexIdBuilder, Ti as DrizzleEntity, Tn as rlsRole, Tr as OrderByClause, Tt as MigrationDefinition, U as ConvexBooleanBuilderInitial, Un as vectorIndex, Ur as SystemFields, Ut as DatabaseWithMutations, V as bytes, Vn as searchIndex, Vr as OrmSchemaTriggers, Vt as defineMigrationSet, W as boolean, Wn as ConvexCheckBuilder, Wr as BinaryExpression, Wt as DatabaseWithQuery, X as CountBackfillStatusArgs, Xn as ConvexUniqueConstraintConfig, Xr as and, Xt as extractRelationsConfig, Y as CountBackfillKickoffArgs, Yn as ConvexUniqueConstraintBuilderOn, Yr as UnaryExpression, Yt as EdgeMetadata, Z as CreateOrmOptions, Zn as check, Zr as between, Zt as ExtractTablesFromSchema, _ as ConvexTimestampMode, _i as startsWith, _n as deletion, _r as MutationExecuteConfig, _t as OrmTriggerContext, a as requireSchemaRelations, ai as inArray, an as TablesRelationalConfig, ar as AggregateResult, at as OrmWriterCtx, b as ConvexTextEnumBuilderInitial, bi as ColumnBuilderBaseConfig, bn as RlsPolicyConfig, br as MutationPaginateConfig, bt as MigrationCancelArgs, c as TableConfigResult, ci as isNull, cn as ConvexDeletionBuilder, cr as CountConfig, ct as ScheduledMutationBatchArgs, d as OrmNotFoundError, di as lte, dn as ConvexTableWithColumns, dr as FilterOperators, dt as scheduledDeleteFactory, ei as eq, en as OneConfig, er as ConvexTextBuilder, et as OrmApiResult, f as ConvexVectorBuilder, fi as ne, fn as DiscriminatorBuilderConfig, fr as GetColumnData, ft as SchemaExtension, g as ConvexTimestampBuilderInitial, gi as or, gn as convexTable, gr as InsertValue, gt as OrmTriggerChange, h as ConvexTimestampBuilder, hi as notInArray, hn as TableConfig, hr as InferSelectModel, ht as OrmTableTriggers, i as getSchemaTriggers, ii as ilike, in as TableRelationalConfig, ir as AggregateFieldValue, it as OrmReaderCtx, j as date, jn as ConvexRankIndexBuilderOn, jr as ReturningSelection, jt as MigrationMigrateOne, k as ConvexDateBuilderInitial, ki as NotNull, kn as ConvexIndexBuilderOn, kr as ReturningAll, kt as MigrationDriftIssue, l as getTableColumns, li as like, ln as ConvexDeletionConfig, lr as CountResult, lt as scheduledMutationBatchFactory, m as vector, mi as notBetween, mn as OrmLifecycleOperation, mr as InferModelFromColumns, mt as OrmBeforeResult, n as defineSchema, ni as gt, nn as RelationsBuilderColumnBase, nr as text, nt as OrmClientWithApi$1, o as asc, oi as isFieldReference, on as defineRelations, or as BuildQueryResult, ot as ResolveOrmSchema, p as ConvexVectorBuilderInitial, pi as not, pn as OrmLifecycleChange, pr as InferInsertModel, pt as defineSchemaExtension, q as bigint, qn as ConvexForeignKeyConfig, qr as FilterExpression, qt as RlsContext, r as getSchemaRelations, ri as gte, rn as RelationsBuilderColumnConfig, rr as AggregateConfig, rt as OrmFunctions, s as desc, si as isNotNull, sn as defineRelationsPart, sr as BuildRelationResult, st as createOrm, t as WhereClauseResult, ti as fieldRef, tn as RelationsBuilder, tr as ConvexTextBuilderInitial, tt as OrmClientBase$1, u as getTableConfig, ui as lt, un as ConvexTable, ur as DBQueryConfig, ut as ScheduledDeleteArgs, v as timestamp, vi as AnyColumn, vn as discriminator, vr as MutationExecuteResult, vt as OrmTriggers, w as integer, wi as ColumnDataType, wn as RlsRoleConfig, wr as MutationRunMode, wt as MigrationAppliedState, x as textEnum, xi as ColumnBuilderRuntimeConfig, xn as RlsPolicyToOption, xr as MutationPaginatedResult, xt as MigrationRunArgs, y as ConvexTextEnumBuilder, yi as ColumnBuilder, yn as RlsPolicy, yr as MutationExecutionMode, yt as defineTriggers, z as ConvexBytesBuilder, zn as index, zr as OrmSchemaExtensions, zt as buildMigrationPlan } from "../where-clause-compiler-DW6jy2er.js";
2
2
  import { i as pretendRequired, n as deprecated, r as pretend } from "../validators-BhsByJeg.js";
3
3
  import { a as QueryCtxWithPreferredOrmQueryTable, i as QueryCtxWithOrmQueryTable, n as LookupByIdResultByCtx, o as getByIdWithOrmQueryFallback, r as QueryCtxWithOptionalOrmQueryTable, t as DocByCtx } from "../query-context-CNo9ffvI.js";
4
4
  import { DefineSchemaOptions, GenericDatabaseReader, GenericDatabaseWriter, GenericSchema, SchemaDefinition } from "convex/server";
@@ -1,5 +1,5 @@
1
1
  import { t as VRequired } from "./validators-BhsByJeg.js";
2
- import { C as HttpProcedure, D as ProcedureMeta, R as getTransformer, S as HttpMethod, c as InferHttpInput, d as CRPCHttpRouter, j as DataTransformerOptions, l as InferHttpOutput, p as HttpRouterRecord, w as HttpProcedureBuilderDef, x as HttpHandlerOpts } from "./http-types-BoSDAh4Y.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-DXOgaerG.js";
3
3
  import { g as UnsetMarker, i as IntersectIfDefined, o as MiddlewareBuilder, p as Overwrite$1, s as MiddlewareFunction, t as AnyMiddleware } from "./types-CnTpHR1F.js";
4
4
  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
5
  import { ActionBuilder, ArgsArrayToObject, DefaultFunctionArgs, FunctionReference, FunctionReturnType, FunctionVisibility, GenericActionCtx, GenericDataModel, GenericMutationCtx, GenericQueryCtx, MutationBuilder, QueryBuilder, RegisteredAction, RegisteredMutation, RegisteredQuery, TableNamesInDataModel } from "convex/server";
@@ -1,6 +1,38 @@
1
1
  import { getFunctionName } from "convex/server";
2
2
 
3
3
  //#region src/crpc/http-types.ts
4
+ /**
5
+ * Build the exact cache key for an HTTP route.
6
+ *
7
+ * Missing args normalize to `{}` so the RSC prefetch, the browser observer, and
8
+ * a hand-written `getQueryData` call all hash to the same key. Every producer
9
+ * of an `httpQuery` cache key goes through here.
10
+ */
11
+ function buildHttpQueryKey(routeKey, args) {
12
+ return [
13
+ "httpQuery",
14
+ routeKey,
15
+ args ?? {}
16
+ ];
17
+ }
18
+ /**
19
+ * Build the route-wide prefix key.
20
+ *
21
+ * Filters match on prefix, so this matches every args variant of the route.
22
+ * Not a cache key: nothing is ever stored under it.
23
+ */
24
+ function buildHttpQueryPrefixKey(routeKey) {
25
+ return ["httpQuery", routeKey];
26
+ }
27
+ /**
28
+ * Freshness window for `crpc.http.*` routes, in milliseconds.
29
+ *
30
+ * HTTP routes are a pull model with no push channel, so hydrated data needs a
31
+ * real freshness window or the browser refetches it on mount. The RSC
32
+ * QueryClient reads the same constant, so the server dedupe window and the
33
+ * client freshness window cannot drift apart.
34
+ */
35
+ const HTTP_DEFAULT_STALE_TIME = 3e4;
4
36
  /** HTTP client error */
5
37
  var HttpClientError = class extends Error {
6
38
  name = "HttpClientError";
@@ -244,4 +276,4 @@ function convexInfiniteQueryOptions(funcRef, args, opts = {}, meta) {
244
276
  }
245
277
 
246
278
  //#endregion
247
- export { buildSearchParams as a, HttpClientError as c, RESERVED_KEYS as i, isHttpClientError as l, convexInfiniteQueryOptions as n, executeHttpRequest as o, convexQuery as r, replaceUrlParam as s, convexAction as t };
279
+ export { buildSearchParams as a, HTTP_DEFAULT_STALE_TIME as c, buildHttpQueryPrefixKey as d, isHttpClientError as f, RESERVED_KEYS as i, HttpClientError as l, convexInfiniteQueryOptions as n, executeHttpRequest as o, convexQuery as r, replaceUrlParam as s, convexAction as t, buildHttpQueryKey as u };
@@ -127,6 +127,7 @@ type ConvexQueryBuilder = {
127
127
  withIndex: (name: any, cb: any) => {
128
128
  unique: () => Promise<any>;
129
129
  collect: () => Promise<any[]>;
130
+ take: (limit: number) => Promise<any[]>;
130
131
  };
131
132
  };
132
133
  type ConvexRatelimitDbReader = {
@@ -176,17 +177,36 @@ declare function calculateRatelimit(state: RatelimitState | null, algorithm: Res
176
177
  */
177
178
  declare function snapshotToState(snapshot: RatelimitSnapshot): RatelimitState;
178
179
  //#endregion
180
+ //#region src/ratelimit/maintenance.d.ts
181
+ type CleanupRatelimitStateOptions = {
182
+ before: number;
183
+ limit?: number;
184
+ };
185
+ type CleanupRatelimitStateResult = {
186
+ deleted: number;
187
+ hasMore: boolean;
188
+ };
189
+ /** Deletes one on-demand batch of state older than the caller-owned cutoff. */
190
+ declare function cleanupRatelimitState(db: ConvexRatelimitDbWriter, options: CleanupRatelimitStateOptions): Promise<CleanupRatelimitStateResult>;
191
+ //#endregion
179
192
  //#region src/ratelimit/plugin.d.ts
180
193
  type MaybePromise<T> = T | Promise<T>;
181
194
  type RatelimitBuckets = Record<string, Record<string, ResolvedAlgorithm>>;
182
195
  type BucketName<TBuckets extends RatelimitBuckets> = Extract<keyof TBuckets, string>;
183
196
  type TierName<TBuckets extends RatelimitBuckets> = Extract<keyof TBuckets[BucketName<TBuckets>], string>;
184
- type RatelimitResolvedArgs<TCtx, TMeta extends object, TUser, TBuckets extends RatelimitBuckets> = {
197
+ /** What is known before request signals are resolved. */
198
+ type RatelimitRequestArgs<TCtx, TMeta extends object, TUser, TBuckets extends RatelimitBuckets> = {
185
199
  ctx: TCtx;
186
200
  meta: TMeta;
187
201
  user: TUser;
188
202
  bucket: BucketName<TBuckets>;
189
203
  tier: TierName<TBuckets>;
204
+ };
205
+ /** Signals are resolved once per request and reused as the identifier input. */
206
+ type RatelimitIdentifierArgs<TCtx, TMeta extends object, TUser, TBuckets extends RatelimitBuckets> = RatelimitRequestArgs<TCtx, TMeta, TUser, TBuckets> & {
207
+ signals: LimitRequest | undefined;
208
+ };
209
+ type RatelimitResolvedArgs<TCtx, TMeta extends object, TUser, TBuckets extends RatelimitBuckets> = RatelimitIdentifierArgs<TCtx, TMeta, TUser, TBuckets> & {
190
210
  identifier: string;
191
211
  };
192
212
  type RatelimitPluginOptions<TCtx = unknown, TMeta extends object = object, TUser = unknown, TBuckets extends RatelimitBuckets = RatelimitBuckets> = {
@@ -199,18 +219,34 @@ type RatelimitPluginOptions<TCtx = unknown, TMeta extends object = object, TUser
199
219
  ctx: TCtx;
200
220
  meta: TMeta;
201
221
  }) => MaybePromise<TUser>;
202
- getIdentifier: (args: {
203
- ctx: TCtx;
204
- meta: TMeta;
205
- user: TUser;
206
- bucket: BucketName<TBuckets>;
207
- }) => MaybePromise<string>;
208
222
  getTier: (user: TUser) => MaybePromise<TierName<TBuckets>>;
209
- getSignals: (args: RatelimitResolvedArgs<TCtx, TMeta, TUser, TBuckets>) => MaybePromise<LimitRequest | undefined>;
223
+ /**
224
+ * Resolved once per request, before `getIdentifier`, and reused for the limit
225
+ * call. Read request metadata here rather than in `getIdentifier`, so a
226
+ * guarded mutation pays at most one `ctx.meta.getRequestMetadata()` syscall.
227
+ */
228
+ getSignals: (args: RatelimitRequestArgs<TCtx, TMeta, TUser, TBuckets>) => MaybePromise<LimitRequest | undefined>;
229
+ /**
230
+ * The rate-limit partition key. Everything sharing a value shares one budget
231
+ * and one `ratelimitState` document, so key unauthenticated traffic by
232
+ * `signals.ip` rather than a constant.
233
+ */
234
+ getIdentifier: (args: RatelimitIdentifierArgs<TCtx, TMeta, TUser, TBuckets>) => MaybePromise<string>;
210
235
  prefix?: string | ((args: RatelimitResolvedArgs<TCtx, TMeta, TUser, TBuckets>) => MaybePromise<string>);
211
236
  failureMode?: 'closed' | 'open';
212
237
  enableProtection?: boolean;
213
238
  denyListThreshold?: number;
239
+ denyList?: RatelimitConfig['denyList'];
240
+ dynamicLimits?: boolean;
241
+ timeout?: number;
242
+ /**
243
+ * Block cache backing store. The plugin builds one `Ratelimit` per guarded
244
+ * mutation, so the default per-instance cache never outlives a request. Pass
245
+ * a longer-lived `Map` only if you accept that a stale block can deny a
246
+ * request a refilled shard could have served, and that a mutation replayed
247
+ * after an OCC conflict can observe entries its first attempt wrote.
248
+ */
249
+ ephemeralCache?: RatelimitConfig['ephemeralCache'];
214
250
  message?: string | ((args: RatelimitResolvedArgs<TCtx, TMeta, TUser, TBuckets>) => MaybePromise<string>);
215
251
  };
216
252
  type AnyRatelimitPluginOptions = RatelimitPluginOptions<any, any, any, any>;
@@ -285,4 +321,4 @@ declare const HOUR: number;
285
321
  declare const DAY: number;
286
322
  declare const WEEK: number;
287
323
  //#endregion
288
- export { type CheckRequest, type ConvexQueryBuilder, type ConvexRatelimitDbReader, type ConvexRatelimitDbWriter, DAY, type Duration, type DurationString, type DurationUnit, type DynamicLimitResponse, type EvaluationResult, type FixedWindowAlgorithm, HOUR, type HookAPIOptions, type HookCheckValue, type LimitRequest, MINUTE, RATE_LIMIT_DYNAMIC_TABLE, RATE_LIMIT_HIT_TABLE, RATE_LIMIT_STATE_TABLE, Ratelimit, type RatelimitConfig, RatelimitPlugin, type RatelimitPluginOptions, type RatelimitReason, type RatelimitResponse, type RatelimitRow, type RatelimitShardState, type RatelimitSnapshot, type RatelimitState, type RatelimitStoredState, type RemainingResponse, type ResolvedAlgorithm, SECOND, type SlidingWindowAlgorithm, type TokenBucketAlgorithm, WEEK, applyDynamicLimit, calculateRatelimit, fixedWindow, slidingWindow, snapshotToState, toMs, tokenBucket };
324
+ export { type CheckRequest, type CleanupRatelimitStateOptions, type CleanupRatelimitStateResult, type ConvexQueryBuilder, type ConvexRatelimitDbReader, type ConvexRatelimitDbWriter, DAY, type Duration, type DurationString, type DurationUnit, type DynamicLimitResponse, type EvaluationResult, type FixedWindowAlgorithm, HOUR, type HookAPIOptions, type HookCheckValue, type LimitRequest, MINUTE, RATE_LIMIT_DYNAMIC_TABLE, RATE_LIMIT_HIT_TABLE, RATE_LIMIT_STATE_TABLE, Ratelimit, type RatelimitConfig, RatelimitPlugin, type RatelimitPluginOptions, type RatelimitReason, type RatelimitResponse, type RatelimitRow, type RatelimitShardState, type RatelimitSnapshot, type RatelimitState, type RatelimitStoredState, type RemainingResponse, type ResolvedAlgorithm, SECOND, type SlidingWindowAlgorithm, type TokenBucketAlgorithm, WEEK, applyDynamicLimit, calculateRatelimit, cleanupRatelimitState, fixedWindow, slidingWindow, snapshotToState, toMs, tokenBucket };