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.
- package/dist/aggregate/index.d.ts +1 -1
- package/dist/auth/client/index.js +1 -1
- package/dist/auth/index.js +19 -21
- package/dist/auth/nextjs/index.d.ts +1 -1
- package/dist/auth/nextjs/index.js +4 -4
- package/dist/{auth-store-ssZDPa37.js → auth-store-BnGZxmnY.js} +4 -1
- package/dist/{backend-core-DqPydYyx.mjs → backend-core-BsKP1LVg.mjs} +204 -164
- package/dist/{builder-DBgto1yn.js → builder-f4F_NRvK.js} +245 -153
- package/dist/{caller-factory-NEfgD5E0.js → caller-factory-DHywSoGZ.js} +7 -5
- package/dist/cli.mjs +14 -7
- package/dist/crpc/index.js +1 -127
- package/dist/{middleware-Bg-PdtrI.js → middleware-Cgrv2jIu.js} +1 -1
- package/dist/orm/index.d.ts +1 -1
- package/dist/orm/index.js +486 -121
- package/dist/plugins/index.js +1 -1
- package/dist/{procedure-caller-9m6NBxQu.js → procedure-caller-Rj6z3ai7.js} +1 -1
- package/dist/{procedure-name-Cy1AxayA.d.ts → procedure-name-Bo5KMcqc.d.ts} +15 -3
- package/dist/{query-context-ydn9kb6P.js → query-context-C90vNlc9.js} +131 -30
- package/dist/query-options-C_eBSIXG.js +247 -0
- package/dist/ratelimit/index.d.ts +26 -6
- package/dist/ratelimit/index.js +427 -100
- package/dist/ratelimit/react/index.d.ts +14 -0
- package/dist/ratelimit/react/index.js +149 -16
- package/dist/react/index.d.ts +3 -1
- package/dist/react/index.js +48 -15
- package/dist/rsc/index.js +22 -33
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +3 -3
- package/dist/solid/index.js +19 -5
- package/dist/watcher.mjs +2 -2
- package/dist/{where-clause-compiler-WF9UcrAB.d.ts → where-clause-compiler-BRhLW1dp.d.ts} +51 -0
- package/package.json +1 -1
- package/skills/kitcn/SKILL.md +1 -0
- package/skills/kitcn/references/features/create-plugins.md +1 -1
- package/skills/kitcn/references/features/orm.md +11 -1
- package/skills/kitcn/references/features/ratelimit.md +105 -0
- package/skills/kitcn/references/setup/server.md +1 -1
- package/dist/query-options-C96zLANM.js +0 -121
|
@@ -2,11 +2,25 @@
|
|
|
2
2
|
import { FunctionReference } from "convex/server";
|
|
3
3
|
|
|
4
4
|
//#region src/ratelimit/types.d.ts
|
|
5
|
+
type RatelimitStoredState = {
|
|
6
|
+
value: number;
|
|
7
|
+
ts: number;
|
|
8
|
+
auxValue?: number;
|
|
9
|
+
auxTs?: number;
|
|
10
|
+
};
|
|
11
|
+
type RatelimitShardState = {
|
|
12
|
+
shard: number;
|
|
13
|
+
state: RatelimitStoredState;
|
|
14
|
+
};
|
|
15
|
+
type RatelimitState = RatelimitStoredState & {
|
|
16
|
+
shards?: RatelimitShardState[];
|
|
17
|
+
};
|
|
5
18
|
type RatelimitSnapshot = {
|
|
6
19
|
value: number;
|
|
7
20
|
ts: number;
|
|
8
21
|
shard: number;
|
|
9
22
|
config: ResolvedAlgorithm;
|
|
23
|
+
state: RatelimitState;
|
|
10
24
|
};
|
|
11
25
|
type FixedWindowAlgorithm = {
|
|
12
26
|
kind: 'fixedWindow';
|
|
@@ -3,12 +3,134 @@ import { useConvex, useQuery } from "convex/react";
|
|
|
3
3
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
4
4
|
import { makeFunctionReference } from "convex/server";
|
|
5
5
|
|
|
6
|
+
//#region src/ratelimit/core/algorithms.ts
|
|
7
|
+
/**
|
|
8
|
+
* Narrow the configured budget down to the slice one shard owns.
|
|
9
|
+
*
|
|
10
|
+
* Every shard stores its own row and spends only what it owns, so without this
|
|
11
|
+
* the effective limit would be multiplied by the shard count. Shares are dealt
|
|
12
|
+
* so they add back up to the configured budget exactly — see {@link shardShare}.
|
|
13
|
+
*/
|
|
14
|
+
function shardAlgorithm(algorithm, shard) {
|
|
15
|
+
const { shards } = algorithm;
|
|
16
|
+
if (shards <= 1) return algorithm;
|
|
17
|
+
const share = (value) => shardShare(value, shards, shard);
|
|
18
|
+
const maxReserved = algorithm.maxReserved === void 0 ? void 0 : share(algorithm.maxReserved);
|
|
19
|
+
if (algorithm.kind === "tokenBucket") {
|
|
20
|
+
const maxTokens = share(algorithm.maxTokens);
|
|
21
|
+
return {
|
|
22
|
+
...algorithm,
|
|
23
|
+
refillRate: algorithm.refillRate * (maxTokens / algorithm.maxTokens),
|
|
24
|
+
maxTokens,
|
|
25
|
+
maxReserved,
|
|
26
|
+
shards: 1
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (algorithm.kind === "fixedWindow") return {
|
|
30
|
+
...algorithm,
|
|
31
|
+
limit: share(algorithm.limit),
|
|
32
|
+
capacity: share(algorithm.capacity),
|
|
33
|
+
maxReserved,
|
|
34
|
+
shards: 1
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
...algorithm,
|
|
38
|
+
limit: share(algorithm.limit),
|
|
39
|
+
maxReserved,
|
|
40
|
+
shards: 1
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** Tokens a shard-level config may spend, ignoring the per-window refill. */
|
|
44
|
+
function algorithmBudget(algorithm) {
|
|
45
|
+
return algorithm.kind === "tokenBucket" ? algorithm.maxTokens : algorithm.limit;
|
|
46
|
+
}
|
|
47
|
+
/** Tokens the algorithm can hold, including fixed-window burst capacity. */
|
|
48
|
+
function algorithmCapacity(algorithm) {
|
|
49
|
+
if (algorithm.kind === "fixedWindow") return algorithm.capacity;
|
|
50
|
+
return algorithmBudget(algorithm);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Deal a whole-token budget across `shards` so the shares sum back to `total`.
|
|
54
|
+
*
|
|
55
|
+
* A plain `total / shards` strands the fractional part of every shard: a shard
|
|
56
|
+
* holding `2.5` tokens only ever grants two whole requests and refills to `2.5`
|
|
57
|
+
* again, so `limit: 5` over two shards would enforce `4` forever. Whole budgets
|
|
58
|
+
* are dealt as `floor` plus one extra token to the first `total % shards` shards
|
|
59
|
+
* instead. Fractional budgets have no whole-token floor to hit, so they keep the
|
|
60
|
+
* even split.
|
|
61
|
+
*/
|
|
62
|
+
function shardShare(total, shards, shard) {
|
|
63
|
+
const whole = Math.floor(total);
|
|
64
|
+
const fractional = total - whole;
|
|
65
|
+
return Math.floor(whole / shards) + (shard < whole % shards ? 1 : 0) + (shard === 0 ? fractional : 0);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
//#endregion
|
|
6
69
|
//#region src/ratelimit/core/calculate-rate-limit.ts
|
|
7
70
|
function calculateRatelimit(state, algorithm, now, count) {
|
|
71
|
+
const shardStates = state?.shards;
|
|
72
|
+
if (algorithm.shards > 1 && count > maximumShardCapacity(algorithm)) return {
|
|
73
|
+
...calculateSingleRatelimit(state, algorithm, now, count),
|
|
74
|
+
retryAfter: Number.POSITIVE_INFINITY,
|
|
75
|
+
reset: Number.POSITIVE_INFINITY
|
|
76
|
+
};
|
|
77
|
+
if (algorithm.shards > 1 && shardStates?.length === algorithm.shards) return calculateShardedRatelimit(shardStates, algorithm, now, count);
|
|
78
|
+
return calculateSingleRatelimit(state, algorithm, now, count);
|
|
79
|
+
}
|
|
80
|
+
function calculateSingleRatelimit(state, algorithm, now, count) {
|
|
8
81
|
if (algorithm.kind === "fixedWindow") return calculateFixedWindow(state, algorithm, now, count);
|
|
9
82
|
if (algorithm.kind === "tokenBucket") return calculateTokenBucket(state, algorithm, now, count);
|
|
10
83
|
return calculateSlidingWindow(state, algorithm, now, count);
|
|
11
84
|
}
|
|
85
|
+
function maximumShardCapacity(algorithm) {
|
|
86
|
+
let maximum = 0;
|
|
87
|
+
for (let shard = 0; shard < algorithm.shards; shard += 1) maximum = Math.max(maximum, algorithmCapacity(shardAlgorithm(algorithm, shard)));
|
|
88
|
+
return maximum;
|
|
89
|
+
}
|
|
90
|
+
function calculateShardedRatelimit(shardStates, algorithm, now, count) {
|
|
91
|
+
const candidates = shardStates.map(({ shard, state: shardState }) => {
|
|
92
|
+
const perShard = shardAlgorithm(algorithm, shard);
|
|
93
|
+
return {
|
|
94
|
+
baseline: calculateRatelimit(shardState, perShard, now, 0),
|
|
95
|
+
requested: calculateRatelimit(shardState, perShard, now, count),
|
|
96
|
+
shard
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
const selected = [...count === 0 ? candidates : candidates.filter((candidate) => candidate.requested.retryAfter === void 0)].sort((a, b) => b.requested.remainingRaw - a.requested.remainingRaw)[0];
|
|
100
|
+
const projected = candidates.map((candidate) => ({
|
|
101
|
+
evaluated: count !== 0 && candidate.shard === selected?.shard ? candidate.requested : candidate.baseline,
|
|
102
|
+
shard: candidate.shard
|
|
103
|
+
}));
|
|
104
|
+
const retryValues = candidates.flatMap((candidate) => candidate.requested.retryAfter === void 0 ? [] : [candidate.requested.retryAfter]);
|
|
105
|
+
const retryAfter = selected ? void 0 : Math.min(...retryValues);
|
|
106
|
+
const remaining = selected ? projected.reduce((total, candidate) => total + candidate.evaluated.remaining, 0) : 0;
|
|
107
|
+
const remainingRaw = selected ? projected.reduce((total, candidate) => total + Math.max(0, candidate.evaluated.remainingRaw), 0) : Math.max(...candidates.map((candidate) => candidate.requested.remainingRaw));
|
|
108
|
+
const auxTimestamps = projected.flatMap((candidate) => candidate.evaluated.state.auxTs === void 0 ? [] : [candidate.evaluated.state.auxTs]);
|
|
109
|
+
return {
|
|
110
|
+
state: {
|
|
111
|
+
value: selected || count === 0 ? projected.reduce((total, candidate) => total + candidate.evaluated.state.value, 0) : remainingRaw,
|
|
112
|
+
ts: Math.max(...projected.map((candidate) => candidate.evaluated.state.ts)),
|
|
113
|
+
...auxTimestamps.length > 0 ? {
|
|
114
|
+
auxValue: projected.reduce((total, candidate) => total + (candidate.evaluated.state.auxValue ?? 0), 0),
|
|
115
|
+
auxTs: Math.max(...auxTimestamps)
|
|
116
|
+
} : {},
|
|
117
|
+
shards: projected.map(({ evaluated, shard }) => ({
|
|
118
|
+
shard,
|
|
119
|
+
state: {
|
|
120
|
+
value: evaluated.state.value,
|
|
121
|
+
ts: evaluated.state.ts,
|
|
122
|
+
auxValue: evaluated.state.auxValue,
|
|
123
|
+
auxTs: evaluated.state.auxTs
|
|
124
|
+
}
|
|
125
|
+
}))
|
|
126
|
+
},
|
|
127
|
+
retryAfter,
|
|
128
|
+
remaining,
|
|
129
|
+
remainingRaw,
|
|
130
|
+
reset: Math.min(...candidates.map((candidate) => candidate.requested.reset)),
|
|
131
|
+
limit: algorithmBudget(algorithm)
|
|
132
|
+
};
|
|
133
|
+
}
|
|
12
134
|
function calculateTokenBucket(state, config, now, count) {
|
|
13
135
|
const ratePerMs = config.refillRate / config.interval;
|
|
14
136
|
const initial = state ?? {
|
|
@@ -17,7 +139,8 @@ function calculateTokenBucket(state, config, now, count) {
|
|
|
17
139
|
};
|
|
18
140
|
const elapsed = Math.max(0, now - initial.ts);
|
|
19
141
|
const nextValue = Math.min(initial.value + elapsed * ratePerMs, config.maxTokens) - count;
|
|
20
|
-
|
|
142
|
+
let retryAfter;
|
|
143
|
+
if (nextValue < 0) retryAfter = count > config.maxTokens ? Number.POSITIVE_INFINITY : Math.ceil(-nextValue / ratePerMs);
|
|
21
144
|
return {
|
|
22
145
|
state: {
|
|
23
146
|
value: nextValue,
|
|
@@ -25,6 +148,7 @@ function calculateTokenBucket(state, config, now, count) {
|
|
|
25
148
|
},
|
|
26
149
|
retryAfter,
|
|
27
150
|
remaining: Math.max(0, Math.floor(nextValue)),
|
|
151
|
+
remainingRaw: nextValue,
|
|
28
152
|
reset: retryAfter ? now + retryAfter : now,
|
|
29
153
|
limit: config.maxTokens
|
|
30
154
|
};
|
|
@@ -39,7 +163,8 @@ function calculateFixedWindow(state, config, now, count) {
|
|
|
39
163
|
const replenished = Math.min(initial.value + config.limit * elapsedWindows, config.capacity);
|
|
40
164
|
const ts = initial.ts + elapsedWindows * config.window;
|
|
41
165
|
const nextValue = replenished - count;
|
|
42
|
-
|
|
166
|
+
let retryAfter;
|
|
167
|
+
if (nextValue < 0) retryAfter = count > config.capacity ? Number.POSITIVE_INFINITY : ts + config.window * Math.ceil(-nextValue / config.limit) - now;
|
|
43
168
|
return {
|
|
44
169
|
state: {
|
|
45
170
|
value: nextValue,
|
|
@@ -47,7 +172,8 @@ function calculateFixedWindow(state, config, now, count) {
|
|
|
47
172
|
},
|
|
48
173
|
retryAfter,
|
|
49
174
|
remaining: Math.max(0, Math.floor(nextValue)),
|
|
50
|
-
|
|
175
|
+
remainingRaw: nextValue,
|
|
176
|
+
reset: retryAfter === Number.POSITIVE_INFINITY ? Number.POSITIVE_INFINITY : ts + config.window,
|
|
51
177
|
limit: config.limit
|
|
52
178
|
};
|
|
53
179
|
}
|
|
@@ -67,7 +193,8 @@ function calculateSlidingWindow(state, config, now, count) {
|
|
|
67
193
|
const projectedCurrent = currentCount + count;
|
|
68
194
|
const projectedUsed = projectedCurrent + previousCount * previousWeight;
|
|
69
195
|
const remaining = config.limit - projectedUsed;
|
|
70
|
-
|
|
196
|
+
let retryAfter;
|
|
197
|
+
if (remaining < 0) retryAfter = count > config.limit ? Number.POSITIVE_INFINITY : Math.max(1, config.window - elapsedInWindow);
|
|
71
198
|
return {
|
|
72
199
|
state: {
|
|
73
200
|
value: projectedCurrent,
|
|
@@ -77,10 +204,22 @@ function calculateSlidingWindow(state, config, now, count) {
|
|
|
77
204
|
},
|
|
78
205
|
retryAfter,
|
|
79
206
|
remaining: Math.max(0, Math.floor(remaining)),
|
|
80
|
-
|
|
207
|
+
remainingRaw: remaining,
|
|
208
|
+
reset: retryAfter === Number.POSITIVE_INFINITY ? Number.POSITIVE_INFINITY : windowStart + config.window,
|
|
81
209
|
limit: config.limit
|
|
82
210
|
};
|
|
83
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Convert a {@link RatelimitSnapshot} back into the `RatelimitState` shape that
|
|
214
|
+
* {@link calculateRatelimit} consumes.
|
|
215
|
+
*
|
|
216
|
+
* Snapshot `value` is always "tokens left". Fixed window and token bucket store
|
|
217
|
+
* that directly, but sliding window state stores the used count, so it has to be
|
|
218
|
+
* inverted before it can be replayed.
|
|
219
|
+
*/
|
|
220
|
+
function snapshotToState(snapshot) {
|
|
221
|
+
return { ...snapshot.state };
|
|
222
|
+
}
|
|
84
223
|
function alignWindowStart(now, window, start = 0) {
|
|
85
224
|
const offsetNow = now - start;
|
|
86
225
|
return start + Math.floor(offsetNow / window) * window;
|
|
@@ -116,8 +255,8 @@ function useRatelimit(getRatelimitValueQuery, options) {
|
|
|
116
255
|
ts: evaluation.ts - timeOffset,
|
|
117
256
|
config: ratelimitData.config,
|
|
118
257
|
shard: ratelimitData.shard,
|
|
119
|
-
ok: evaluation.
|
|
120
|
-
retryAt: evaluation.retryAfter ? serverTs + evaluation.retryAfter - timeOffset
|
|
258
|
+
ok: evaluation.retryAfter === void 0,
|
|
259
|
+
retryAt: evaluation.retryAfter === void 0 ? void 0 : serverTs + evaluation.retryAfter - timeOffset
|
|
121
260
|
};
|
|
122
261
|
}, [
|
|
123
262
|
count,
|
|
@@ -130,7 +269,7 @@ function useRatelimit(getRatelimitValueQuery, options) {
|
|
|
130
269
|
status: void 0,
|
|
131
270
|
check
|
|
132
271
|
};
|
|
133
|
-
if (current.
|
|
272
|
+
if (!current.ok) return {
|
|
134
273
|
status: {
|
|
135
274
|
ok: false,
|
|
136
275
|
retryAt: current.retryAt
|
|
@@ -146,7 +285,7 @@ function useRatelimit(getRatelimitValueQuery, options) {
|
|
|
146
285
|
};
|
|
147
286
|
}, [check, current]);
|
|
148
287
|
useEffect(() => {
|
|
149
|
-
if (response.status?.ok !== false || !response.status.retryAt) return;
|
|
288
|
+
if (response.status?.ok !== false || !response.status.retryAt || !Number.isFinite(response.status.retryAt)) return;
|
|
150
289
|
const timeout = setTimeout(() => setNow(Date.now()), Math.max(0, response.status.retryAt - now));
|
|
151
290
|
return () => clearTimeout(timeout);
|
|
152
291
|
}, [
|
|
@@ -165,13 +304,7 @@ function resolveGetServerTimeMutation(ref) {
|
|
|
165
304
|
return ref;
|
|
166
305
|
}
|
|
167
306
|
function evaluateSnapshot(snapshot, now, count) {
|
|
168
|
-
const evaluated = calculateRatelimit(snapshot.config
|
|
169
|
-
value: Math.max(0, snapshot.config.limit - snapshot.value),
|
|
170
|
-
ts: snapshot.ts
|
|
171
|
-
} : {
|
|
172
|
-
value: snapshot.value,
|
|
173
|
-
ts: snapshot.ts
|
|
174
|
-
}, snapshot.config, now, count);
|
|
307
|
+
const evaluated = calculateRatelimit(snapshotToState(snapshot), snapshot.config, now, count);
|
|
175
308
|
return {
|
|
176
309
|
value: snapshot.config.kind === "slidingWindow" ? evaluated.retryAfter !== void 0 ? -1 : evaluated.remaining : evaluated.state.value,
|
|
177
310
|
ts: evaluated.state.ts,
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1060,7 +1060,9 @@ declare function useConvexInfiniteQueryOptions<T extends FunctionReference<'quer
|
|
|
1060
1060
|
*/
|
|
1061
1061
|
declare function useConvexActionQueryOptions<Action extends FunctionReference<'action'>>(action: Action, args: FunctionArgs<Action> | SkipToken, options?: {
|
|
1062
1062
|
skipUnauth?: boolean;
|
|
1063
|
-
} & DistributiveOmit<UseQueryOptions<FunctionReturnType<Action>, DefaultError>, ReservedQueryOptions>): ConvexActionOptions<Action
|
|
1063
|
+
} & DistributiveOmit<UseQueryOptions<FunctionReturnType<Action>, DefaultError>, ReservedQueryOptions>): ConvexActionOptions<Action> & {
|
|
1064
|
+
meta: ConvexQueryMeta;
|
|
1065
|
+
};
|
|
1064
1066
|
/**
|
|
1065
1067
|
* Hook that returns mutation options for use with useMutation.
|
|
1066
1068
|
* Wraps the Convex mutation with auth guard logic.
|
package/dist/react/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { A as defaultIsUnauthorized, C as useSafeConvexAuth, D as writeAuthSessionFallbackData, O as writeAuthSessionFallbackToken, S as useMaybeAuth, _ as useAuthValue, a as ConvexAuthRecoveryError, b as useFetchAccessToken, c as MaybeAuthenticated, d as decodeJwtExp, f as isSessionSyncGraceActive, g as useAuthStore, h as useAuthState, i as ConvexAuthBridge, j as isCRPCClientError, k as CRPCClientError, l as MaybeUnauthenticated, m as useAuthGuard, n as AuthProvider, o as ConvexProviderWithAuth, p as useAuth, r as Authenticated, s as FetchAccessTokenContext, t as AUTH_SESSION_SYNC_GRACE_MS, u as Unauthenticated, v as useConvexAuthBridge, w as clearAuthSessionFallback, x as useIsAuth, y as useConvexAuthRecovery } from "../auth-store-
|
|
2
|
+
import { A as defaultIsUnauthorized, C as useSafeConvexAuth, D as writeAuthSessionFallbackData, O as writeAuthSessionFallbackToken, S as useMaybeAuth, _ as useAuthValue, a as ConvexAuthRecoveryError, b as useFetchAccessToken, c as MaybeAuthenticated, d as decodeJwtExp, f as isSessionSyncGraceActive, g as useAuthStore, h as useAuthState, i as ConvexAuthBridge, j as isCRPCClientError, k as CRPCClientError, l as MaybeUnauthenticated, m as useAuthGuard, n as AuthProvider, o as ConvexProviderWithAuth, p as useAuth, r as Authenticated, s as FetchAccessTokenContext, t as AUTH_SESSION_SYNC_GRACE_MS, u as Unauthenticated, v as useConvexAuthBridge, w as clearAuthSessionFallback, x as useIsAuth, y as useConvexAuthRecovery } from "../auth-store-BnGZxmnY.js";
|
|
3
3
|
import { ConvexProvider, ConvexReactClient, ConvexReactClient as ConvexReactClient$1, useAction, useConvex, useMutation } from "convex/react";
|
|
4
4
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -418,6 +418,10 @@ const getTransformer = (transformer) => {
|
|
|
418
418
|
transformerCache.set(cacheKey, resolved);
|
|
419
419
|
return resolved;
|
|
420
420
|
};
|
|
421
|
+
/**
|
|
422
|
+
* Encode request payloads (input direction).
|
|
423
|
+
*/
|
|
424
|
+
const encodeWire = (value, transformer) => getTransformer(transformer).input.serialize(value);
|
|
421
425
|
|
|
422
426
|
//#endregion
|
|
423
427
|
//#region src/react/http-proxy.ts
|
|
@@ -673,7 +677,7 @@ function convexInfiniteQueryOptions(funcRef, args, opts = {}, meta) {
|
|
|
673
677
|
cursor: null,
|
|
674
678
|
limit
|
|
675
679
|
};
|
|
676
|
-
const finalEnabled =
|
|
680
|
+
const finalEnabled = isSkip ? false : enabled;
|
|
677
681
|
return {
|
|
678
682
|
queryKey: [
|
|
679
683
|
"convexQuery",
|
|
@@ -686,7 +690,7 @@ function convexInfiniteQueryOptions(funcRef, args, opts = {}, meta) {
|
|
|
686
690
|
refetchOnReconnect: false,
|
|
687
691
|
refetchOnWindowFocus: false,
|
|
688
692
|
...queryOptions,
|
|
689
|
-
...finalEnabled ===
|
|
693
|
+
...finalEnabled === void 0 ? {} : { enabled: finalEnabled },
|
|
690
694
|
meta: {
|
|
691
695
|
authType,
|
|
692
696
|
skipUnauth,
|
|
@@ -723,6 +727,19 @@ function useAuthSkip(funcRef, opts) {
|
|
|
723
727
|
};
|
|
724
728
|
}
|
|
725
729
|
|
|
730
|
+
//#endregion
|
|
731
|
+
//#region src/internal/enabled.ts
|
|
732
|
+
/**
|
|
733
|
+
* Combine a computed gate with the caller's `enabled` option.
|
|
734
|
+
* A predicate is preserved (never collapsed to a boolean) so TanStack Query
|
|
735
|
+
* keeps evaluating it; `allowed: false` always wins.
|
|
736
|
+
*/
|
|
737
|
+
function resolveEnabled(allowed, enabled) {
|
|
738
|
+
if (!allowed) return false;
|
|
739
|
+
if (typeof enabled === "function") return (query) => enabled(query) !== false;
|
|
740
|
+
return enabled ?? true;
|
|
741
|
+
}
|
|
742
|
+
|
|
726
743
|
//#endregion
|
|
727
744
|
//#region src/internal/query-key.ts
|
|
728
745
|
/**
|
|
@@ -745,12 +762,19 @@ function isConvexAction$1(queryKey) {
|
|
|
745
762
|
return queryKey.length >= 2 && queryKey[0] === "convexAction";
|
|
746
763
|
}
|
|
747
764
|
/**
|
|
765
|
+
* Serialize args the same way they go over the wire, so non-native Convex
|
|
766
|
+
* types the transformer supports (e.g. `Date`) can be hashed.
|
|
767
|
+
*/
|
|
768
|
+
function hashArgs(args) {
|
|
769
|
+
return JSON.stringify(convexToJson(encodeWire(args)));
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
748
772
|
* Create stable hash for Convex query keys.
|
|
749
773
|
* Uses Convex's JSON serialization for consistent argument hashing.
|
|
750
774
|
*/
|
|
751
775
|
function hashConvexQuery(queryKey) {
|
|
752
776
|
const [, funcName, args] = queryKey;
|
|
753
|
-
return `convexQuery|${funcName}|${
|
|
777
|
+
return `convexQuery|${funcName}|${hashArgs(args)}`;
|
|
754
778
|
}
|
|
755
779
|
/**
|
|
756
780
|
* Create stable hash for Convex action keys.
|
|
@@ -758,7 +782,7 @@ function hashConvexQuery(queryKey) {
|
|
|
758
782
|
*/
|
|
759
783
|
function hashConvexAction(queryKey) {
|
|
760
784
|
const [, funcName, args] = queryKey;
|
|
761
|
-
return `convexAction|${funcName}|${
|
|
785
|
+
return `convexAction|${funcName}|${hashArgs(args)}`;
|
|
762
786
|
}
|
|
763
787
|
|
|
764
788
|
//#endregion
|
|
@@ -792,12 +816,13 @@ function getStableArgsByHash(hash, args) {
|
|
|
792
816
|
stableArgsByHash.set(hash, stableArgs);
|
|
793
817
|
return stableArgs;
|
|
794
818
|
}
|
|
795
|
-
|
|
819
|
+
const stored = structuredClone(args);
|
|
820
|
+
stableArgsByHash.set(hash, stored);
|
|
796
821
|
if (stableArgsByHash.size > MAX_STABLE_ARGS) {
|
|
797
822
|
const oldestHash = stableArgsByHash.keys().next().value;
|
|
798
823
|
if (oldestHash !== void 0) stableArgsByHash.delete(oldestHash);
|
|
799
824
|
}
|
|
800
|
-
return
|
|
825
|
+
return stored;
|
|
801
826
|
}
|
|
802
827
|
function useStableQueryArgs(prefix, funcRef, args) {
|
|
803
828
|
const resolvedArgs = args === skipToken || args == null ? EMPTY_ARGS : args;
|
|
@@ -846,14 +871,15 @@ function useConvexQueryOptions(funcRef, args, options) {
|
|
|
846
871
|
const stableArgs = useStableQueryArgs("convexQuery", funcRef, isSkipped ? EMPTY_ARGS : args);
|
|
847
872
|
const baseOptions = useMemo(() => convexQuery(funcRef, stableArgs.value), [funcRef, stableArgs]);
|
|
848
873
|
return useMemo(() => {
|
|
849
|
-
const {
|
|
874
|
+
const { enabled: userEnabled, skipUnauth, subscribe, ...queryOptions } = options ?? {};
|
|
850
875
|
return {
|
|
851
876
|
...baseOptions,
|
|
852
877
|
...queryOptions,
|
|
853
|
-
enabled: isSkipped
|
|
878
|
+
enabled: resolveEnabled(!(isSkipped || shouldSkip), userEnabled),
|
|
854
879
|
meta: {
|
|
855
880
|
...baseOptions.meta,
|
|
856
881
|
authType,
|
|
882
|
+
skipUnauth,
|
|
857
883
|
subscribe: subscribe !== false
|
|
858
884
|
}
|
|
859
885
|
};
|
|
@@ -898,7 +924,7 @@ function useConvexInfiniteQueryOptions(funcRef, args, opts) {
|
|
|
898
924
|
enabled: isSkipped ? false : enabledOpt,
|
|
899
925
|
skipUnauth: opts.skipUnauth
|
|
900
926
|
});
|
|
901
|
-
const enabled = isSkipped || shouldSkip
|
|
927
|
+
const enabled = resolveEnabled(!(isSkipped || shouldSkip), opts.enabled);
|
|
902
928
|
const baseOptions = convexInfiniteQueryOptions(funcRef, isSkipped ? {} : args, {
|
|
903
929
|
...opts,
|
|
904
930
|
enabled
|
|
@@ -933,20 +959,26 @@ function useConvexInfiniteQueryOptions(funcRef, args, opts) {
|
|
|
933
959
|
function useConvexActionQueryOptions(action, args, options) {
|
|
934
960
|
const isSkipped = args === skipToken;
|
|
935
961
|
const enabled = typeof options?.enabled === "function" ? void 0 : options?.enabled;
|
|
936
|
-
const { shouldSkip } = useAuthSkip(action, {
|
|
962
|
+
const { authType, shouldSkip } = useAuthSkip(action, {
|
|
937
963
|
enabled: isSkipped ? false : enabled,
|
|
938
964
|
skipUnauth: options?.skipUnauth
|
|
939
965
|
});
|
|
940
966
|
const stableArgs = useStableQueryArgs("convexAction", action, isSkipped ? EMPTY_ARGS : args);
|
|
941
967
|
const baseOptions = useMemo(() => convexAction(action, stableArgs.value), [action, stableArgs]);
|
|
942
968
|
return useMemo(() => {
|
|
943
|
-
const {
|
|
969
|
+
const { enabled: userEnabled, skipUnauth, ...queryOptions } = options ?? {};
|
|
944
970
|
return {
|
|
945
971
|
...baseOptions,
|
|
946
972
|
...queryOptions,
|
|
947
|
-
enabled: isSkipped
|
|
973
|
+
enabled: resolveEnabled(!(isSkipped || shouldSkip), userEnabled),
|
|
974
|
+
meta: {
|
|
975
|
+
...baseOptions.meta,
|
|
976
|
+
authType,
|
|
977
|
+
skipUnauth
|
|
978
|
+
}
|
|
948
979
|
};
|
|
949
980
|
}, [
|
|
981
|
+
authType,
|
|
950
982
|
baseOptions,
|
|
951
983
|
isSkipped,
|
|
952
984
|
options,
|
|
@@ -2380,7 +2412,7 @@ const useInfiniteQueryInternal = (query, args, options) => {
|
|
|
2380
2412
|
const pageArgs = state.queries[key]?.args;
|
|
2381
2413
|
return {
|
|
2382
2414
|
...convexQuery(query, pageArgs ? (({ __paginationId, ...rest }) => rest)(pageArgs) : "skip", meta),
|
|
2383
|
-
enabled: !skip && !!state.queries[key],
|
|
2415
|
+
enabled: resolveEnabled(!skip && !!state.queries[key], enabled),
|
|
2384
2416
|
structuralSharing: false,
|
|
2385
2417
|
...queryOptions ?? {},
|
|
2386
2418
|
...index === 0 && prefetchedFirstPage ? { initialData: prefetchedFirstPage } : {},
|
|
@@ -2395,6 +2427,7 @@ const useInfiniteQueryInternal = (query, args, options) => {
|
|
|
2395
2427
|
state.pageKeys,
|
|
2396
2428
|
state.queries,
|
|
2397
2429
|
skip,
|
|
2430
|
+
enabled,
|
|
2398
2431
|
meta,
|
|
2399
2432
|
queryOptions,
|
|
2400
2433
|
prefetchedFirstPage,
|
|
@@ -2578,7 +2611,7 @@ function useInfiniteQuery(infiniteOptions) {
|
|
|
2578
2611
|
const result = useInfiniteQueryInternal(query, args, {
|
|
2579
2612
|
limit,
|
|
2580
2613
|
...queryOptions,
|
|
2581
|
-
enabled: !shouldSkip
|
|
2614
|
+
enabled: resolveEnabled(!shouldSkip, factoryEnabled)
|
|
2582
2615
|
});
|
|
2583
2616
|
const authLoadingApplies = authType === "optional" || authType === "required";
|
|
2584
2617
|
const isClientError = isCRPCClientError(result.error);
|
package/dist/rsc/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as defaultIsUnauthorized } from "../error-Bvo7YEhk.js";
|
|
2
2
|
import { n as getFuncRef, r as getFunctionMeta, t as buildMetaIndex } from "../meta-utils-D9K4fICl.js";
|
|
3
|
-
import {
|
|
4
|
-
import { n as convexInfiniteQueryOptions, r as convexQuery } from "../query-options-
|
|
3
|
+
import { o as encodeWire, s as getTransformer } from "../transformer-C6pGVHqx.js";
|
|
4
|
+
import { n as convexInfiniteQueryOptions, o as executeHttpRequest, r as convexQuery } from "../query-options-C_eBSIXG.js";
|
|
5
5
|
import { convexToJson } from "convex/values";
|
|
6
6
|
import { getFunctionName } from "convex/server";
|
|
7
7
|
import { fetchAction, fetchQuery } from "convex/nextjs";
|
|
@@ -28,37 +28,19 @@ function buildHttpQueryOptions(route, routeKey, args) {
|
|
|
28
28
|
/**
|
|
29
29
|
* Execute an HTTP route fetch.
|
|
30
30
|
* Called by getServerQueryClientOptions queryFn.
|
|
31
|
+
*
|
|
32
|
+
* Shares the browser client's request builder so a prefetched entry hydrates
|
|
33
|
+
* the client cache instead of being refetched from a different URL.
|
|
31
34
|
*/
|
|
32
35
|
async function fetchHttpRoute(convexSiteUrl, routeMeta, args, token, transformer) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
});
|
|
41
|
-
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
|
|
42
|
-
if (response.headers.get("content-length") === "0" || response.status === 204) return null;
|
|
43
|
-
return decodeWire(await response.json(), transformer);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Build URL with path params and query params.
|
|
47
|
-
*/
|
|
48
|
-
function buildUrl(convexSiteUrl, pathTemplate, args) {
|
|
49
|
-
const remaining = { ...args };
|
|
50
|
-
const path = pathTemplate.replace(/:(\w+)/g, (_, key) => {
|
|
51
|
-
const value = remaining[key];
|
|
52
|
-
delete remaining[key];
|
|
53
|
-
return value !== null && value !== void 0 ? encodeURIComponent(String(value)) : "";
|
|
54
|
-
});
|
|
55
|
-
const queryEntries = Object.entries(remaining).filter(([_, v]) => v !== void 0 && v !== null);
|
|
56
|
-
if (queryEntries.length > 0) {
|
|
57
|
-
const params = new URLSearchParams();
|
|
58
|
-
for (const [key, value] of queryEntries) params.set(key, String(value));
|
|
59
|
-
return `${convexSiteUrl}${path}?${params.toString()}`;
|
|
60
|
-
}
|
|
61
|
-
return convexSiteUrl + path;
|
|
36
|
+
return await executeHttpRequest({
|
|
37
|
+
args,
|
|
38
|
+
baseHeaders: token ? { Authorization: `Bearer ${token}` } : void 0,
|
|
39
|
+
convexSiteUrl,
|
|
40
|
+
procedureName: `${routeMeta.method} ${routeMeta.path}`,
|
|
41
|
+
route: routeMeta,
|
|
42
|
+
transformer
|
|
43
|
+
}) ?? null;
|
|
62
44
|
}
|
|
63
45
|
|
|
64
46
|
//#endregion
|
|
@@ -150,12 +132,19 @@ function isConvexAction(queryKey) {
|
|
|
150
132
|
return queryKey.length >= 2 && queryKey[0] === "convexAction";
|
|
151
133
|
}
|
|
152
134
|
/**
|
|
135
|
+
* Serialize args the same way they go over the wire, so non-native Convex
|
|
136
|
+
* types the transformer supports (e.g. `Date`) can be hashed.
|
|
137
|
+
*/
|
|
138
|
+
function hashArgs(args) {
|
|
139
|
+
return JSON.stringify(convexToJson(encodeWire(args)));
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
153
142
|
* Create stable hash for Convex query keys.
|
|
154
143
|
* Uses Convex's JSON serialization for consistent argument hashing.
|
|
155
144
|
*/
|
|
156
145
|
function hashConvexQuery(queryKey) {
|
|
157
146
|
const [, funcName, args] = queryKey;
|
|
158
|
-
return `convexQuery|${funcName}|${
|
|
147
|
+
return `convexQuery|${funcName}|${hashArgs(args)}`;
|
|
159
148
|
}
|
|
160
149
|
/**
|
|
161
150
|
* Create stable hash for Convex action keys.
|
|
@@ -163,7 +152,7 @@ function hashConvexQuery(queryKey) {
|
|
|
163
152
|
*/
|
|
164
153
|
function hashConvexAction(queryKey) {
|
|
165
154
|
const [, funcName, args] = queryKey;
|
|
166
|
-
return `convexAction|${funcName}|${
|
|
155
|
+
return `convexAction|${funcName}|${hashArgs(args)}`;
|
|
167
156
|
}
|
|
168
157
|
|
|
169
158
|
//#endregion
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as ActionProcedureBuilder, A as CRPCError, B as RuntimeEnv, C as createProcedureHandlerFactory, Ct as zCustomQuery, D as WithHttpRouter, Dt as zodToConvex, E as typedProcedureResolver, Et as zodOutputToConvexFields, F as getCRPCErrorFromUnknown, G as createLazyCaller, H as ConvexContext, I as getHTTPStatusCodeFromError, J as ServerCaller, K as CallerMeta, L as isCRPCError, M as CRPCErrorData, N as CRPC_ERROR_CODES_BY_KEY, O as inferApiInputs, Ot as zodToConvexFields, P as CRPC_ERROR_CODE_TO_HTTP, Q as getGeneratedValue, R as toCRPCError, S as createProcedureCallerFactory, St as zCustomMutation, T as getGeneratedFunctionReference, Tt as zodOutputToConvex, U as createCallerFactory, V as createEnv, W as LazyCaller, X as createApiLeaf, Y as createServerCaller, Z as createGeneratedFunctionReference, _ as ProcedureSchedulableCallerFromRegistry, _t as ZodValidatorFromConvex, a as CreateProcedureCallerFactoryOptions, at as initCRPC, b as createGenericCallerFactory, bt as withSystemFields, c as GeneratedRegistryCallerFactory, ct as extractPathParams, d as GeneratedRegistryHandlerForContext, dt as ConvexValidatorFromZod, et as CRPCFunctionTypeHint, f as ProcedureActionCallerFromRegistry, ft as ConvexValidatorFromZodOutput, g as ProcedureFromFunctionReference, gt as ZodFromValidatorBase, h as ProcedureDefinition, ht as Zid, i as registerProcedureNameLookup, it as createMiddlewareFactory, j as CRPCErrorCode, k as inferApiOutputs, l as GeneratedRegistryCallerForContext, lt as handleHttpError, m as ProcedureCallerFromRegistry, mt as ZCustomCtx, n as ProcedureNameLookup, nt as ProcedureBuilder, o as GeneratedProcedureRegistry, ot as HttpProcedureBuilder, p as ProcedureCaller, pt as CustomBuilder, q as CallerOpts, r as inferProcedureNameFromCallsite, rt as QueryProcedureBuilder, s as GeneratedProcedureRegistryEntry, st as createHttpProcedureBuilder, t as ProcedureNameEntry, tt as MutationProcedureBuilder, u as GeneratedRegistryHandlerFactory, ut as matchPathParams, v as ProcedureScheduleCallerFromRegistry, vt as convexToZod, w as defineProcedure, wt as zid, x as createGenericHandlerFactory, xt as zCustomAction, y as createGeneratedRegistryRuntime, yt as convexToZodFields, z as CreateEnvOptions } from "../procedure-name-
|
|
1
|
+
import { $ as ActionProcedureBuilder, A as CRPCError, B as RuntimeEnv, C as createProcedureHandlerFactory, Ct as zCustomQuery, D as WithHttpRouter, Dt as zodToConvex, E as typedProcedureResolver, Et as zodOutputToConvexFields, F as getCRPCErrorFromUnknown, G as createLazyCaller, H as ConvexContext, I as getHTTPStatusCodeFromError, J as ServerCaller, K as CallerMeta, L as isCRPCError, M as CRPCErrorData, N as CRPC_ERROR_CODES_BY_KEY, O as inferApiInputs, Ot as zodToConvexFields, P as CRPC_ERROR_CODE_TO_HTTP, Q as getGeneratedValue, R as toCRPCError, S as createProcedureCallerFactory, St as zCustomMutation, T as getGeneratedFunctionReference, Tt as zodOutputToConvex, U as createCallerFactory, V as createEnv, W as LazyCaller, X as createApiLeaf, Y as createServerCaller, Z as createGeneratedFunctionReference, _ as ProcedureSchedulableCallerFromRegistry, _t as ZodValidatorFromConvex, a as CreateProcedureCallerFactoryOptions, at as initCRPC, b as createGenericCallerFactory, bt as withSystemFields, c as GeneratedRegistryCallerFactory, ct as extractPathParams, d as GeneratedRegistryHandlerForContext, dt as ConvexValidatorFromZod, et as CRPCFunctionTypeHint, f as ProcedureActionCallerFromRegistry, ft as ConvexValidatorFromZodOutput, g as ProcedureFromFunctionReference, gt as ZodFromValidatorBase, h as ProcedureDefinition, ht as Zid, i as registerProcedureNameLookup, it as createMiddlewareFactory, j as CRPCErrorCode, k as inferApiOutputs, l as GeneratedRegistryCallerForContext, lt as handleHttpError, m as ProcedureCallerFromRegistry, mt as ZCustomCtx, n as ProcedureNameLookup, nt as ProcedureBuilder, o as GeneratedProcedureRegistry, ot as HttpProcedureBuilder, p as ProcedureCaller, pt as CustomBuilder, q as CallerOpts, r as inferProcedureNameFromCallsite, rt as QueryProcedureBuilder, s as GeneratedProcedureRegistryEntry, st as createHttpProcedureBuilder, t as ProcedureNameEntry, tt as MutationProcedureBuilder, u as GeneratedRegistryHandlerFactory, ut as matchPathParams, v as ProcedureScheduleCallerFromRegistry, vt as convexToZod, w as defineProcedure, wt as zid, x as createGenericHandlerFactory, xt as zCustomAction, y as createGeneratedRegistryRuntime, yt as convexToZodFields, z as CreateEnvOptions } from "../procedure-name-Bo5KMcqc.js";
|
|
2
2
|
import { C as HttpProcedure, D as ProcedureMeta, E as InferHttpInput, S as HttpMethod, T as HttpRouteDefinition, _ as extractRouteMap, b as HttpActionHandler, d as CRPCHttpRouter, f as HttpRouterDef, g as createHttpRouterFactory, h as createHttpRouter, m as HttpRouterWithHono, p as HttpRouterRecord, v as CRPCHonoHandler, w as HttpProcedureBuilderDef, x as HttpHandlerOpts, y as HttpActionConstructor } from "../http-types-zsMHb_QN.js";
|
|
3
3
|
import { a as MergeZodObjects, c as MiddlewareMarker, d as MiddlewareProcedureType, f as MiddlewareResult, g as UnsetMarker, h as Simplify, i as IntersectIfDefined, l as MiddlewareNext, m as ResolveIfSet, n as AnyMiddlewareBuilder, o as MiddlewareBuilder, p as Overwrite, r as GetRawInputFn, s as MiddlewareFunction, t as AnyMiddleware, u as MiddlewareProcedureInfo } from "../types-CnTpHR1F.js";
|
|
4
4
|
import { a as isMutationCtx, c as isSchedulerCtx, d as requireQueryCtx, f as requireRunMutationCtx, i as isActionCtx, l as requireActionCtx, n as RunMutationCtx, o as isQueryCtx, p as requireSchedulerCtx, r as SchedulerCtx, s as isRunMutationCtx, t as GenericCtx, u as requireMutationCtx } from "../context-utils-BBUtBqjN.js";
|
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as isMutationCtx, c as isSchedulerCtx, d as requireQueryCtx, f as requireRunMutationCtx, i as isActionCtx, l as requireActionCtx, n as createGeneratedFunctionReference, o as isQueryCtx, p as requireSchedulerCtx, r as getGeneratedValue, s as isRunMutationCtx, t as createApiLeaf, u as requireMutationCtx } from "../api-entry-N3nBOlI2.js";
|
|
2
|
-
import { n as createLazyCaller, r as createServerCaller, t as createCallerFactory } from "../caller-factory-
|
|
3
|
-
import { A as zid, C as toCRPCError, D as zCustomAction, E as withSystemFields, M as zodOutputToConvexFields, N as zodToConvex, O as zCustomMutation, P as zodToConvexFields, S as isCRPCError, T as convexToZodFields, _ as CRPCError, a as createMiddlewareFactory, b as getCRPCErrorFromUnknown, c as registerProcedureNameLookup, d as createHttpRouterFactory, f as extractRouteMap, g as matchPathParams, h as handleHttpError, i as QueryProcedureBuilder, j as zodOutputToConvex, k as zCustomQuery, l as HttpRouterWithHono, m as extractPathParams, n as MutationProcedureBuilder, o as initCRPC, p as createHttpProcedureBuilder, r as ProcedureBuilder, s as inferProcedureNameFromCallsite, t as ActionProcedureBuilder, u as createHttpRouter, v as CRPC_ERROR_CODES_BY_KEY, w as convexToZod, x as getHTTPStatusCodeFromError, y as CRPC_ERROR_CODE_TO_HTTP } from "../builder-
|
|
4
|
-
import { a as createProcedureHandlerFactory, c as typedProcedureResolver, i as createProcedureCallerFactory, l as createEnv, n as createGenericCallerFactory, o as defineProcedure, r as createGenericHandlerFactory, s as getGeneratedFunctionReference, t as createGeneratedRegistryRuntime } from "../procedure-caller-
|
|
2
|
+
import { n as createLazyCaller, r as createServerCaller, t as createCallerFactory } from "../caller-factory-DHywSoGZ.js";
|
|
3
|
+
import { A as zid, C as toCRPCError, D as zCustomAction, E as withSystemFields, M as zodOutputToConvexFields, N as zodToConvex, O as zCustomMutation, P as zodToConvexFields, S as isCRPCError, T as convexToZodFields, _ as CRPCError, a as createMiddlewareFactory, b as getCRPCErrorFromUnknown, c as registerProcedureNameLookup, d as createHttpRouterFactory, f as extractRouteMap, g as matchPathParams, h as handleHttpError, i as QueryProcedureBuilder, j as zodOutputToConvex, k as zCustomQuery, l as HttpRouterWithHono, m as extractPathParams, n as MutationProcedureBuilder, o as initCRPC, p as createHttpProcedureBuilder, r as ProcedureBuilder, s as inferProcedureNameFromCallsite, t as ActionProcedureBuilder, u as createHttpRouter, v as CRPC_ERROR_CODES_BY_KEY, w as convexToZod, x as getHTTPStatusCodeFromError, y as CRPC_ERROR_CODE_TO_HTTP } from "../builder-f4F_NRvK.js";
|
|
4
|
+
import { a as createProcedureHandlerFactory, c as typedProcedureResolver, i as createProcedureCallerFactory, l as createEnv, n as createGenericCallerFactory, o as defineProcedure, r as createGenericHandlerFactory, s as getGeneratedFunctionReference, t as createGeneratedRegistryRuntime } from "../procedure-caller-Rj6z3ai7.js";
|
|
5
5
|
|
|
6
6
|
export { ActionProcedureBuilder, CRPCError, CRPC_ERROR_CODES_BY_KEY, CRPC_ERROR_CODE_TO_HTTP, HttpRouterWithHono, MutationProcedureBuilder, ProcedureBuilder, QueryProcedureBuilder, convexToZod, convexToZodFields, createApiLeaf, createCallerFactory, createEnv, createGeneratedFunctionReference, createGeneratedRegistryRuntime, createGenericCallerFactory, createGenericHandlerFactory, createHttpProcedureBuilder, createHttpRouter, createHttpRouterFactory, createLazyCaller, createMiddlewareFactory, createProcedureCallerFactory, createProcedureHandlerFactory, createServerCaller, defineProcedure, extractPathParams, extractRouteMap, getCRPCErrorFromUnknown, getGeneratedFunctionReference, getGeneratedValue, getHTTPStatusCodeFromError, handleHttpError, inferProcedureNameFromCallsite, initCRPC, isActionCtx, isCRPCError, isMutationCtx, isQueryCtx, isRunMutationCtx, isSchedulerCtx, matchPathParams, registerProcedureNameLookup, requireActionCtx, requireMutationCtx, requireQueryCtx, requireRunMutationCtx, requireSchedulerCtx, toCRPCError, typedProcedureResolver, withSystemFields, zCustomAction, zCustomMutation, zCustomQuery, zid, zodOutputToConvex, zodOutputToConvexFields, zodToConvex, zodToConvexFields };
|
package/dist/solid/index.js
CHANGED
|
@@ -57,7 +57,10 @@ const useConvexAuthBridge = () => useContext(ConvexAuthBridgeContext);
|
|
|
57
57
|
/** Decode JWT expiration (ms timestamp) from token */
|
|
58
58
|
function decodeJwtExp(token) {
|
|
59
59
|
try {
|
|
60
|
-
const
|
|
60
|
+
const segment = token.split(".")[1];
|
|
61
|
+
if (!segment) return null;
|
|
62
|
+
const binary = atob(segment.replaceAll("-", "+").replaceAll("_", "/"));
|
|
63
|
+
const payload = JSON.parse(new TextDecoder().decode(Uint8Array.from(binary, (char) => char.charCodeAt(0))));
|
|
61
64
|
return payload.exp ? payload.exp * 1e3 : null;
|
|
62
65
|
} catch {
|
|
63
66
|
return null;
|
|
@@ -699,6 +702,10 @@ const getTransformer = (transformer) => {
|
|
|
699
702
|
transformerCache.set(cacheKey, resolved);
|
|
700
703
|
return resolved;
|
|
701
704
|
};
|
|
705
|
+
/**
|
|
706
|
+
* Encode request payloads (input direction).
|
|
707
|
+
*/
|
|
708
|
+
const encodeWire = (value, transformer) => getTransformer(transformer).input.serialize(value);
|
|
702
709
|
|
|
703
710
|
//#endregion
|
|
704
711
|
//#region src/solid/http-proxy.ts
|
|
@@ -954,7 +961,7 @@ function convexInfiniteQueryOptions(funcRef, args, opts = {}, meta) {
|
|
|
954
961
|
cursor: null,
|
|
955
962
|
limit
|
|
956
963
|
};
|
|
957
|
-
const finalEnabled =
|
|
964
|
+
const finalEnabled = isSkip ? false : enabled;
|
|
958
965
|
return {
|
|
959
966
|
queryKey: [
|
|
960
967
|
"convexQuery",
|
|
@@ -967,7 +974,7 @@ function convexInfiniteQueryOptions(funcRef, args, opts = {}, meta) {
|
|
|
967
974
|
refetchOnReconnect: false,
|
|
968
975
|
refetchOnWindowFocus: false,
|
|
969
976
|
...queryOptions,
|
|
970
|
-
...finalEnabled ===
|
|
977
|
+
...finalEnabled === void 0 ? {} : { enabled: finalEnabled },
|
|
971
978
|
meta: {
|
|
972
979
|
authType,
|
|
973
980
|
skipUnauth,
|
|
@@ -1785,12 +1792,19 @@ function isConvexAction$1(queryKey) {
|
|
|
1785
1792
|
return queryKey.length >= 2 && queryKey[0] === "convexAction";
|
|
1786
1793
|
}
|
|
1787
1794
|
/**
|
|
1795
|
+
* Serialize args the same way they go over the wire, so non-native Convex
|
|
1796
|
+
* types the transformer supports (e.g. `Date`) can be hashed.
|
|
1797
|
+
*/
|
|
1798
|
+
function hashArgs(args) {
|
|
1799
|
+
return JSON.stringify(convexToJson(encodeWire(args)));
|
|
1800
|
+
}
|
|
1801
|
+
/**
|
|
1788
1802
|
* Create stable hash for Convex query keys.
|
|
1789
1803
|
* Uses Convex's JSON serialization for consistent argument hashing.
|
|
1790
1804
|
*/
|
|
1791
1805
|
function hashConvexQuery(queryKey) {
|
|
1792
1806
|
const [, funcName, args] = queryKey;
|
|
1793
|
-
return `convexQuery|${funcName}|${
|
|
1807
|
+
return `convexQuery|${funcName}|${hashArgs(args)}`;
|
|
1794
1808
|
}
|
|
1795
1809
|
/**
|
|
1796
1810
|
* Create stable hash for Convex action keys.
|
|
@@ -1798,7 +1812,7 @@ function hashConvexQuery(queryKey) {
|
|
|
1798
1812
|
*/
|
|
1799
1813
|
function hashConvexAction(queryKey) {
|
|
1800
1814
|
const [, funcName, args] = queryKey;
|
|
1801
|
-
return `convexAction|${funcName}|${
|
|
1815
|
+
return `convexAction|${funcName}|${hashArgs(args)}`;
|
|
1802
1816
|
}
|
|
1803
1817
|
|
|
1804
1818
|
//#endregion
|