kitcn 0.16.0 → 0.17.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.
Files changed (38) hide show
  1. package/dist/aggregate/index.d.ts +1 -1
  2. package/dist/auth/client/index.js +1 -1
  3. package/dist/auth/index.js +19 -21
  4. package/dist/auth/nextjs/index.d.ts +1 -1
  5. package/dist/auth/nextjs/index.js +4 -4
  6. package/dist/{auth-store-ssZDPa37.js → auth-store-BnGZxmnY.js} +4 -1
  7. package/dist/{backend-core-DqPydYyx.mjs → backend-core-BsKP1LVg.mjs} +204 -164
  8. package/dist/{builder-DBgto1yn.js → builder-f4F_NRvK.js} +245 -153
  9. package/dist/{caller-factory-NEfgD5E0.js → caller-factory-DHywSoGZ.js} +7 -5
  10. package/dist/cli.mjs +14 -7
  11. package/dist/crpc/index.js +1 -127
  12. package/dist/{middleware-Bg-PdtrI.js → middleware-Cgrv2jIu.js} +1 -1
  13. package/dist/orm/index.d.ts +1 -1
  14. package/dist/orm/index.js +486 -121
  15. package/dist/plugins/index.js +1 -1
  16. package/dist/{procedure-caller-9m6NBxQu.js → procedure-caller-Rj6z3ai7.js} +1 -1
  17. package/dist/{procedure-name-Cy1AxayA.d.ts → procedure-name-Bo5KMcqc.d.ts} +15 -3
  18. package/dist/{query-context-ydn9kb6P.js → query-context-C90vNlc9.js} +131 -30
  19. package/dist/query-options-C_eBSIXG.js +247 -0
  20. package/dist/ratelimit/index.d.ts +26 -6
  21. package/dist/ratelimit/index.js +427 -100
  22. package/dist/ratelimit/react/index.d.ts +14 -0
  23. package/dist/ratelimit/react/index.js +149 -16
  24. package/dist/react/index.d.ts +3 -1
  25. package/dist/react/index.js +48 -15
  26. package/dist/rsc/index.js +22 -33
  27. package/dist/server/index.d.ts +1 -1
  28. package/dist/server/index.js +3 -3
  29. package/dist/solid/index.js +19 -5
  30. package/dist/watcher.mjs +2 -2
  31. package/dist/{where-clause-compiler-WF9UcrAB.d.ts → where-clause-compiler-BRhLW1dp.d.ts} +51 -0
  32. package/package.json +1 -1
  33. package/skills/kitcn/SKILL.md +1 -0
  34. package/skills/kitcn/references/features/create-plugins.md +1 -1
  35. package/skills/kitcn/references/features/orm.md +11 -1
  36. package/skills/kitcn/references/features/ratelimit.md +105 -0
  37. package/skills/kitcn/references/setup/server.md +1 -1
  38. package/dist/query-options-C96zLANM.js +0 -121
package/dist/watcher.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { Dt as generateMeta, F as resolveRunDeps, Ot as getConvexConfig, j as resolveConfiguredBackend, kt as logger, q as withLocalCodegenEnv } from "./backend-core-DqPydYyx.mjs";
2
+ import { At as PARSE_SNAPSHOT_SUFFIX, Dt as generateMeta, F as resolveRunDeps, Ot as getConvexConfig, j as resolveConfiguredBackend, kt as logger, q as withLocalCodegenEnv } from "./backend-core-BsKP1LVg.mjs";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
 
@@ -44,7 +44,7 @@ function shouldIgnoreWatchPath(watchedPath, functionsDir, outputFile) {
44
44
  if (normalizedPath === generatedFile) return true;
45
45
  if (normalizedPath === convexGeneratedDir || normalizedPath.startsWith(`${convexGeneratedDir}${path.sep}`)) return true;
46
46
  if (normalizedPath === generatedDir || normalizedPath.startsWith(`${generatedDir}${path.sep}`)) return true;
47
- return normalizedPath.endsWith(".runtime.ts") || normalizedPath.endsWith(".kitcn-parse.ts");
47
+ return normalizedPath.endsWith(".runtime.ts") || normalizedPath.endsWith(PARSE_SNAPSHOT_SUFFIX);
48
48
  }
49
49
  async function runWatcherCodegen(params, deps = {}) {
50
50
  const resolveRunDepsFn = deps.resolveRunDeps ?? resolveRunDeps;
@@ -2436,6 +2436,19 @@ declare class GelRelationalQuery<TSchema extends TablesRelationalConfig, TTableC
2436
2436
  private _compareByOrderSpecs;
2437
2437
  private _getTableConfigByDbName;
2438
2438
  private _matchLike;
2439
+ /**
2440
+ * True when the expression can be fully enforced by Convex's own `.filter()`.
2441
+ *
2442
+ * `_toConvexExpression` compiles the string/array operators to `() => true`
2443
+ * because Convex filters cannot run JavaScript string methods; those are
2444
+ * evaluated later by `_evaluatePostFetchFilter`. Pushing such an expression
2445
+ * into `.filter()` is not merely useless, it is wrong in two ways: a `take()`
2446
+ * downstream spends its budget on rows that have not been filtered yet, and a
2447
+ * surrounding `NOT` turns the `true` placeholder into `q.not(true)`, which
2448
+ * matches nothing. So the caller must know whether Convex can carry the whole
2449
+ * expression before relying on it.
2450
+ */
2451
+ private _isConvexEnforceableFilter;
2439
2452
  /**
2440
2453
  * Evaluate a filter expression against a fetched row
2441
2454
  * Used for post-fetch filtering (string operators, etc.)
@@ -2461,6 +2474,15 @@ declare class GelRelationalQuery<TSchema extends TablesRelationalConfig, TTableC
2461
2474
  private _resolveWithVariantsState;
2462
2475
  private _assertPolymorphicAliasCollisions;
2463
2476
  private _synthesizePolymorphicRows;
2477
+ /**
2478
+ * Validate role-scoped policies for every table this read plan touches before
2479
+ * relations are loaded. Relation loaders skip work when a parent page is
2480
+ * empty, so per-row evaluation alone would make a misconfigured table fail
2481
+ * only once it holds rows. Mirrors the `_loadRelations` depth budget so the
2482
+ * plan walked here matches the plan that would be executed.
2483
+ */
2484
+ private _assertRlsSelectPlan;
2485
+ private _assertRelationCountRlsPlan;
2464
2486
  private _finalizeRows;
2465
2487
  private _getSchemaDefinitionOrThrow;
2466
2488
  private _applyEqBounds;
@@ -2470,7 +2492,36 @@ declare class GelRelationalQuery<TSchema extends TablesRelationalConfig, TTableC
2470
2492
  private _isPredicateWhereClause;
2471
2493
  private _createFilterOperators;
2472
2494
  private _resolveWhereCallbackExpression;
2495
+ /**
2496
+ * Read an id-only `where` through the primary key instead of scanning for it.
2497
+ *
2498
+ * The where-clause compiler is built from declared indexes only, and `_id` is
2499
+ * never one of them, so an `id` filter can never be index-selected: it lands
2500
+ * in the post-filters and the stream walks the creation-time index until it
2501
+ * happens on the row. `db.get()` reads exactly the rows asked for, so the ids
2502
+ * are fetched directly and replayed as a creation-time-ordered stream — the
2503
+ * order the scan would have produced, so stage order and cursors are the same.
2504
+ *
2505
+ * Returns null when something else already owns the read: a pinned index, an
2506
+ * index the compiler did select, a `where(predicate)`, or an `orderBy` that
2507
+ * walks a different index.
2508
+ */
2509
+ private _buildIdLookupStream;
2473
2510
  private _buildBasePipelineStream;
2511
+ /**
2512
+ * Stream equivalent of the `db.query(...)` chain, used when a post-fetch
2513
+ * filter has to run in JavaScript before `limit` or a page boundary can be
2514
+ * applied. `filterWith` evaluates the predicate as rows are pulled, so
2515
+ * `take`/`paginate` size by matches instead of by scanned rows.
2516
+ *
2517
+ * It deliberately mirrors the index and order decisions the caller already
2518
+ * made for the plain query rather than re-deriving them, so switching to the
2519
+ * stream cannot change which index is scanned or in what direction.
2520
+ *
2521
+ * Returns null when the schema definition needed by `stream()` is missing;
2522
+ * the caller then falls back to its plain-query path.
2523
+ */
2524
+ private _buildResidualFilterStream;
2474
2525
  private _buildUnionSourceStream;
2475
2526
  private _applyFlatMapStage;
2476
2527
  private _applyPipelineStages;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kitcn",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "kitcn - React Query integration and CLI tools for Convex",
5
5
  "keywords": [
6
6
  "convex",
@@ -484,6 +484,7 @@ Before calling a feature done:
484
484
  - `references/features/aggregates.md`: aggregate component patterns
485
485
  - `references/features/migrations.md`: built-in online data migrations (defineMigration, CLI, deploy, drift). Load when: task involves data backfills, optional→required field hardening, field renames/removals, type narrowing, or `kitcn migrate` CLI commands. Skip for backward-compatible changes (new optional fields, new tables, code-level defaults).
486
486
  - `references/features/create-plugins.md`: canonical plugin authoring patterns (split package entries, token config, scaffold/lockfile/CLI manifest rules). Load when: creating or refactoring plugins.
487
+ - `references/features/ratelimit.md`: ratelimit runtime accounting (shard budget dealing, `check()` vs `limit()`, snapshot conversion, read accuracy, failure modes). Load when: tuning `shards`, reading remaining quota, or debugging unexpected denials. Skip for plain `ratelimit.middleware()` wiring, which `setup/server.md` owns.
487
488
  - `references/features/auth.md`: full Better Auth core flow
488
489
  - `references/features/auth-admin.md`: admin plugin details
489
490
  - `references/features/auth-organizations.md`: org/multi-tenant plugin details
@@ -107,7 +107,7 @@ Trigger composition rules:
107
107
  3. Non-function helpers live under `convex/<paths.lib>/plugins/<plugin>/...`.
108
108
  4. `kitcn codegen` must not generate plugin runtime modules.
109
109
  5. Scaffold templates need stable template IDs.
110
- 6. `add` can merge/upsert scaffold mappings; never clobber custom files unless overwrite is explicit.
110
+ 6. `add` can merge/upsert scaffold mappings; never clobber custom files unless overwrite is explicit. Plan files of kind `scaffold`, `config`, and `env` need explicit consent to replace an existing file, so a builder that renders a whole template is safe by default. Only a builder that reads the existing source and patches it may set `requiresExplicitOverwrite: false`. List every shape another kitcn plugin can leave behind in `managedBaselineContent` so a file kitcn itself wrote is still recognized as managed. A refused file makes `add` exit non-zero and report `refused` in `--json`.
111
111
  7. `add --dry-run`, `add --diff [path]`, and `add --view [path]` preview one shared install plan: scaffold files, env bootstrap, `kitcn.json`, schema registration, lockfile write, dependency install status, codegen/hooks, env reminders.
112
112
  8. Preview comparisons for `.ts`, `.tsx`, `.js`, `.jsx`, and `.json` should be semantic enough to ignore formatter-only churn.
113
113
  9. `view` is read-only plan inspection. Default template source is lockfile mappings, fallback is the resolved preset, `--preset` forces preset selection.
@@ -922,12 +922,22 @@ rlsPolicy("admin_only", {
922
922
  using: (ctx, t) => eq(t.ownerId, ctx.viewerId),
923
923
  });
924
924
 
925
- // Provide roleResolver
925
+ // roleResolver is required by any policy scoped to a named role
926
926
  const ormDb = orm.db(ctx, {
927
927
  rls: { ctx, roleResolver: (ctx) => ctx.roles ?? [] },
928
928
  });
929
929
  ```
930
930
 
931
+ **Important:** a policy scoped to a named role throws `RLS_ROLE_RESOLVER_REQUIRED` when no `roleResolver` is configured, instead of granting the policy to every caller. Queries and mutations validate this per table before reading rows, so an empty table throws too. The SQL pseudo-roles `public`, `current_user`, `current_role`, and `session_user` apply to everyone and need no resolver.
932
+
933
+ ### Null handling
934
+
935
+ Policy expressions use SQL null semantics: a comparison against a missing document field or a missing context value is unknown, and unknown denies. An unauthenticated caller (`ctx.viewerId` is `undefined`) never matches rows whose column is unset. Use `isNull` to match absent columns on purpose.
936
+
937
+ ### Relations
938
+
939
+ `with` enforces the related table's policies, and for many-to-many relations the junction table's policies as well, so a caller only traverses links it may read.
940
+
931
941
  **Important:** `ctx.db` bypasses RLS. Only `ctx.orm` enforces policies. FK cascade fan-out also bypasses child-table RLS.
932
942
 
933
943
  ## Triggers
@@ -0,0 +1,105 @@
1
+ # Ratelimit Reference
2
+
3
+ Runtime accounting for the ratelimit plugin. Prerequisites: `setup/server.md` (scaffold, buckets, `ratelimit.middleware()`).
4
+
5
+ The API mirrors Upstash Ratelimit (`limit`, `check`, `getRemaining`, `resetUsedTokens`, `blockUntilReady`). This file covers only where kitcn's behavior is load-bearing or differs.
6
+
7
+ ## Algorithms
8
+
9
+ ```ts
10
+ import { MINUTE, Ratelimit } from 'kitcn/ratelimit';
11
+
12
+ Ratelimit.fixedWindow(limit, window, options?); // limit tokens per window
13
+ Ratelimit.slidingWindow(limit, window, options?); // weighted across window boundary
14
+ Ratelimit.tokenBucket(refillRate, interval, maxTokens, options?);
15
+ ```
16
+
17
+ `options`: `shards`, `maxReserved`, `capacity` (fixedWindow only), `start` (fixedWindow only). `maxReserved` must be finite and non-negative when present. Reserved fixed-window and token-bucket requests have uncapped headroom when it is omitted.
18
+
19
+ `capacity` is the stored ceiling, `limit` is the per-window refill. Set `capacity > limit` for burst headroom.
20
+
21
+ ## Sharding — delta from parity
22
+
23
+ `shards > 1` distributes writes to cut contention. The configured budget is **dealt** across shards, never duplicated.
24
+
25
+ - Shares are whole tokens that sum to the configured budget, with the remainder going to the low-numbered shards. `fixedWindow(5, '1 m', { shards: 2 })` deals `3` and `2`, and enforces exactly 5/min.
26
+ - Fractional totals deal their whole portion first and retain the fraction on one shard, so whole requests are not stranded.
27
+ - Whole-token `maxReserved` headroom is dealt the same way, so configured reservations remain usable under sharding.
28
+ - `tokenBucket` deals `maxTokens` and allocates `refillRate` in proportion to each shard's capacity share, so uneven capacities refill without clipping the configured total.
29
+ - One call spends from one shard, so `count` can never exceed that shard's share. Aim for a share of ten or more times your largest `count`.
30
+ - Builders **throw** when `limit / shards`, `capacity / shards`, or `maxTokens / shards` drops below `1`. `setDynamicLimit()` rejects non-positive, non-finite, or unservable overrides before writing them.
31
+ - The ephemeral block cache is keyed per shard, requested count, and reservation mode, so an exhausted shard never blocks peers and a failed large or ordinary request never blocks a smaller or reserved one. Cache writes prune expired variants, skip infinite resets, and retain at most 32 variants per identifier.
32
+ - Preferred shards are tried first; if none can serve the request, the limiter reads each remaining candidate concurrently before denying it.
33
+ - Failure `reset` is the earliest retry across both cached and freshly evaluated shards.
34
+
35
+ Default to `shards: 1`. Raise it only after observing write contention on hot identifiers.
36
+
37
+ ## Reads
38
+
39
+ | Call | Shards read | Accuracy |
40
+ | --- | --- | --- |
41
+ | `getRemaining(id)` | all | exact at one common read timestamp |
42
+ | `getValue(id, { sampleShards })` | `sampleShards` (default 1) | estimate, scaled up by the sampled share |
43
+ | `limit()` / `check()` → `remaining` | the serving shard | estimate under `shards > 1` |
44
+
45
+ Use `getRemaining()` for quota headers and banners. Use `getValue()` for the React hook and custom projections where a cheap read matters more than exactness.
46
+
47
+ Fixed-window projections scale by stored `capacity`; the response `limit` remains the configured per-window refill.
48
+ `getRemaining()` evaluates every raw shard at one common timestamp and sums each shard's independently usable whole tokens. It never lets a full shard absorb another shard's refill, nets reserved debt against an open peer, or combines unusable fractions across isolated shards.
49
+
50
+ ## `check()` vs `limit()`
51
+
52
+ `check()` runs the same evaluation as `limit()` for the requested `count` / `rate` and never writes. A `check()` that returns `success: true` is what `limit()` would decide at that moment.
53
+
54
+ ```ts
55
+ const gate = await limiter.check(userId, { count: 5 });
56
+ if (!gate.success) return { retryAt: gate.reset };
57
+ ```
58
+
59
+ ## Snapshots
60
+
61
+ `getValue()` returns tokens **left**; `calculateRatelimit()` takes stored **state**. Sliding windows store the used count, so the two differ. Always convert:
62
+
63
+ ```ts
64
+ import { calculateRatelimit, snapshotToState } from 'kitcn/ratelimit';
65
+
66
+ const snapshot = await limiter.getValue('user_123');
67
+ const result = calculateRatelimit(
68
+ snapshotToState(snapshot),
69
+ snapshot.config,
70
+ Date.now(),
71
+ 1
72
+ );
73
+ ```
74
+
75
+ `result.remaining` is floored to `0`. `result.remainingRaw` is exact and goes negative when the request overdraws — use it to rank shards or size a backoff.
76
+
77
+ `RatelimitSnapshot.shard` is the sampled shard holding the most tokens, not "the" shard.
78
+ `RatelimitSnapshot.state` retains the projected aggregate plus every sampled shard state. Sliding windows preserve `value`, `auxValue`, `ts`, and `auxTs`. When every shard is sampled, `snapshotToState()` preserves independent saturation and decay across later projections; partial samples remain estimates.
79
+
80
+ For denied reserved fixed-window and token-bucket requests, `reset` is when the request fits within `maxReserved`, not when all debt reaches zero.
81
+
82
+ A request larger than every shard's capacity plus finite reservation headroom can never succeed. It returns `reason: 'requestTooLarge'` and `reset: 0` without reading shard state. When only smaller shards cannot serve a request, they are excluded from retry calculations. Fresh, full, and partial snapshot projections preserve permanent denial as `retryAfter: Infinity`, and the React hook reports `ok: false` without scheduling a retry timer. Reduce `count`, reduce `shards`, or raise the configured capacity.
83
+
84
+ ## Convex constraints
85
+
86
+ - `blockUntilReady()` needs `setTimeout`, so it only runs in actions or non-Convex runtimes. It throws with that guidance inside queries and mutations. `limit()` and `check()` never touch timers.
87
+ - `limit()`, `resetUsedTokens()`, and `setDynamicLimit()` write state, so they need a mutation `ctx.db`. `check()`, `getValue()`, `getRemaining()`, and `getDynamicLimit()` are read-only and work from a query reader.
88
+ - Missing tables throw actionable setup guidance — run `bunx kitcn add ratelimit` and register `ratelimitExtension()`.
89
+
90
+ ## Failure modes
91
+
92
+ | Option | Effect |
93
+ | --- | --- |
94
+ | `failureMode: 'closed'` (default) | a timeout denies the request, `reason: 'timeout'` |
95
+ | `failureMode: 'open'` | a timeout allows the request, `success: true` with `reason: 'timeout'` |
96
+
97
+ `reason` is `'timeout' \| 'cacheBlock' \| 'denyList' \| 'requestTooLarge'`. `success: true` with `reason: 'timeout'` is reachable only under `failureMode: 'open'` — do not treat `reason` as proof of denial.
98
+
99
+ ## Dynamic limits
100
+
101
+ Requires `dynamicLimits: true` in the constructor, otherwise `setDynamicLimit()` / `getDynamicLimit()` throw. The override replaces `limit` (or `refillRate`) at read time and must be a positive finite budget that every configured shard can serve. Setting or clearing it advances the limiter's cache generation, invalidates snapshots and ephemeral block decisions, and prevents older in-flight operations from restoring them.
102
+
103
+ ```ts
104
+ await limiter.setDynamicLimit({ limit: 20 }); // false clears the override
105
+ ```
@@ -365,7 +365,7 @@ import { ratelimitExtension } from "../lib/plugins/ratelimit/schema";
365
365
  export default defineSchema(tables).extend(ratelimitExtension());
366
366
  ```
367
367
 
368
- Create `convex/lib/plugins/ratelimit/plugin.ts` and call `ratelimit.middleware()` from mutation builders. Use the default bucket for normal writes and reserve `.meta({ ratelimit: ... })` for named overrides.
368
+ Create `convex/lib/plugins/ratelimit/plugin.ts` and call `ratelimit.middleware()` from mutation builders. Use the default bucket for normal writes and reserve `.meta({ ratelimit: ... })` for named overrides. Runtime accounting (`shards`, `check()`, snapshots, read accuracy) lives in `features/ratelimit.md`.
369
369
 
370
370
  Use `RatelimitPlugin` from `kitcn/ratelimit`:
371
371
 
@@ -1,121 +0,0 @@
1
- import { getFunctionName } from "convex/server";
2
-
3
- //#region src/crpc/query-options.ts
4
- /**
5
- * Query options factory for Convex query function subscriptions.
6
- * Requires `convexQueryClient.queryFn()` set as the default `queryFn` globally.
7
- */
8
- function convexQuery(funcRef, args, meta, opts) {
9
- const finalArgs = args ?? {};
10
- const isSkip = finalArgs === "skip";
11
- const funcName = getFunctionName(funcRef);
12
- const [namespace, fnName] = funcName.split(":");
13
- const authType = meta?.[namespace]?.[fnName]?.auth;
14
- const skipUnauth = opts?.skipUnauth;
15
- return {
16
- queryKey: [
17
- "convexQuery",
18
- funcName,
19
- isSkip ? "skip" : finalArgs
20
- ],
21
- staleTime: Number.POSITIVE_INFINITY,
22
- refetchInterval: false,
23
- refetchOnMount: false,
24
- refetchOnReconnect: false,
25
- refetchOnWindowFocus: false,
26
- ...isSkip ? { enabled: false } : {},
27
- meta: {
28
- authType,
29
- skipUnauth,
30
- subscribe: true
31
- }
32
- };
33
- }
34
- /**
35
- * Query options factory for Convex action functions.
36
- * Actions are NOT reactive - they follow normal TanStack Query semantics.
37
- *
38
- * @example
39
- * ```ts
40
- * useQuery(convexAction(api.ai.generate, { prompt }))
41
- * ```
42
- *
43
- * @example With additional options (use spread):
44
- * ```ts
45
- * useQuery({
46
- * ...convexAction(api.files.process, { fileId }),
47
- * staleTime: 60_000
48
- * });
49
- * ```
50
- */
51
- function convexAction(funcRef, args, meta, opts) {
52
- const finalArgs = args ?? {};
53
- const isSkip = finalArgs === "skip";
54
- const funcName = getFunctionName(funcRef);
55
- const [namespace, fnName] = funcName.split(":");
56
- const authType = meta?.[namespace]?.[fnName]?.auth;
57
- const skipUnauth = opts?.skipUnauth;
58
- return {
59
- queryKey: [
60
- "convexAction",
61
- funcName,
62
- isSkip ? {} : finalArgs
63
- ],
64
- staleTime: Number.POSITIVE_INFINITY,
65
- refetchInterval: false,
66
- refetchOnMount: false,
67
- refetchOnReconnect: false,
68
- refetchOnWindowFocus: false,
69
- ...isSkip ? { enabled: false } : {},
70
- meta: {
71
- authType,
72
- skipUnauth,
73
- subscribe: false
74
- }
75
- };
76
- }
77
- /**
78
- * Infinite query options factory for paginated Convex queries.
79
- * Server-safe (non-hook) - can be used in RSC.
80
- *
81
- * Uses flat { cursor, limit } input like tRPC.
82
- */
83
- function convexInfiniteQueryOptions(funcRef, args, opts = {}, meta) {
84
- const { limit, skipUnauth, enabled, ...queryOptions } = opts;
85
- const finalArgs = args === "skip" ? {} : args;
86
- const isSkip = args === "skip";
87
- const funcName = getFunctionName(funcRef);
88
- const [namespace, fnName] = funcName.split(":");
89
- const authType = (meta?.[namespace]?.[fnName])?.auth;
90
- const firstPageArgs = {
91
- ...finalArgs,
92
- cursor: null,
93
- limit
94
- };
95
- const finalEnabled = enabled === false || isSkip ? false : void 0;
96
- return {
97
- queryKey: [
98
- "convexQuery",
99
- funcName,
100
- firstPageArgs
101
- ],
102
- staleTime: Number.POSITIVE_INFINITY,
103
- refetchInterval: false,
104
- refetchOnMount: false,
105
- refetchOnReconnect: false,
106
- refetchOnWindowFocus: false,
107
- ...queryOptions,
108
- ...finalEnabled === false ? { enabled: false } : {},
109
- meta: {
110
- authType,
111
- skipUnauth,
112
- subscribe: true,
113
- queryName: funcName,
114
- args: finalArgs,
115
- limit
116
- }
117
- };
118
- }
119
-
120
- //#endregion
121
- export { convexInfiniteQueryOptions as n, convexQuery as r, convexAction as t };