kitcn 0.33.5 → 0.33.6
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/CHANGELOG.md +11 -0
- package/dist/aggregate/index.d.ts +1 -1
- package/dist/auth/client/index.d.ts +50 -1
- package/dist/auth/client/index.js +125 -11
- package/dist/orm/index.d.ts +1 -1
- package/dist/orm/migrations/index.d.ts +1 -1
- package/dist/react/index.d.ts +12 -3
- package/dist/react/index.js +18 -10
- package/dist/rsc/index.d.ts +11 -1
- package/dist/{where-clause-compiler-qH6-NCM9.d.ts → where-clause-compiler-BzAJnWt4.d.ts} +115 -115
- package/package.json +1 -1
- package/skills/kitcn/references/features/auth.md +15 -0
- package/skills/kitcn/references/features/react.md +16 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# kitcn
|
|
2
2
|
|
|
3
|
+
## 0.33.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#473](https://github.com/udecode/kitcn/pull/473) [`16e0bb4`](https://github.com/udecode/kitcn/commit/16e0bb46d66a4d7166d577793fcb47f8161efa5d) Thanks [@EfficiencyCorp](https://github.com/EfficiencyCorp)! - - Add opt-in optimistic auth and document identity admission to
|
|
8
|
+
`ConvexAuthProvider`, with the same guarded token source for Convex and cRPC
|
|
9
|
+
HTTP requests.
|
|
10
|
+
- Add Convex-native `optimisticUpdate` support to cRPC `mutationOptions`.
|
|
11
|
+
- Reuse the Convex client's logger for server HTTP clients so construction is
|
|
12
|
+
deterministic during prerendering.
|
|
13
|
+
|
|
3
14
|
## 0.33.5
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Vn as ConvexTextBuilderInitial, Zt as ConvexTableWithColumns } from "../capabilities-Bxzoofl4.js";
|
|
2
|
-
import { C as ConvexNumberBuilderInitial, E as ConvexIdBuilderInitial, N as ConvexCustomBuilderInitial } from "../where-clause-compiler-
|
|
2
|
+
import { C as ConvexNumberBuilderInitial, E as ConvexIdBuilderInitial, N as ConvexCustomBuilderInitial } from "../where-clause-compiler-BzAJnWt4.js";
|
|
3
3
|
import * as convex_values0 from "convex/values";
|
|
4
4
|
import { GenericId, Infer, Value } from "convex/values";
|
|
5
5
|
import { DocumentByName, GenericDataModel, GenericDatabaseReader, GenericDatabaseWriter, TableNamesInDataModel } from "convex/server";
|
|
@@ -398,6 +398,51 @@ type ConvexAuthProviderProps = {
|
|
|
398
398
|
queryName: string;
|
|
399
399
|
}) => void; /** Custom function to detect UNAUTHORIZED errors. Default checks code property. */
|
|
400
400
|
isUnauthorized?: (error: unknown) => boolean;
|
|
401
|
+
/**
|
|
402
|
+
* Run auth-bound queries as soon as an unexpired JWT is held instead of
|
|
403
|
+
* after Convex confirms it. Convex sends them after Authenticate on the same
|
|
404
|
+
* socket and evaluates none of them if the token is refused; a refused token
|
|
405
|
+
* sets `isAuthenticated` back to false, which resets auth-bound queries, and
|
|
406
|
+
* never opens the gate again. Default `false`.
|
|
407
|
+
*/
|
|
408
|
+
optimisticAuth?: boolean;
|
|
409
|
+
/**
|
|
410
|
+
* Fix the identity (JWT `sub` and `sessionId`) the document speaks for: the
|
|
411
|
+
* one it holds when it mounts (`initialToken`), or, with none, the first
|
|
412
|
+
* token it obtains. A token for another user or session is refused before
|
|
413
|
+
* it is cached, so neither Convex, the optimistic gate nor HTTP headers ever
|
|
414
|
+
* see it: the Convex client is closed (dropping queued requests and
|
|
415
|
+
* optimistic updates), every later token request answers null, and this is
|
|
416
|
+
* called, typically to reload the page. Same-session refreshes pass
|
|
417
|
+
* through. Off when not set.
|
|
418
|
+
*/
|
|
419
|
+
onTokenIdentityChange?: () => void;
|
|
420
|
+
/**
|
|
421
|
+
* The identity (`sub|sessionId`, as the guard decodes it from a JWT) the
|
|
422
|
+
* document already speaks for when this provider mounts, for an app that
|
|
423
|
+
* mounts the provider more than once in one document (for example one per
|
|
424
|
+
* route group, over a shared Convex client). The guard starts from it
|
|
425
|
+
* instead of from `initialToken` or the first token obtained, so a remount
|
|
426
|
+
* without a token still refuses another user's or session's token.
|
|
427
|
+
*
|
|
428
|
+
* A fixed value is read on the first render only. A getter is read at
|
|
429
|
+
* every admission, cached tokens included, and a token must match both the
|
|
430
|
+
* identity it returns and the one this guard already admitted; any
|
|
431
|
+
* mismatch trips the guard. So a provider kept mounted but hidden (React
|
|
432
|
+
* `<Activity>`) cannot resume under an identity the document has since
|
|
433
|
+
* moved away from. A getter returning null does not constrain. Needs
|
|
434
|
+
* `onTokenIdentityChange`.
|
|
435
|
+
*/
|
|
436
|
+
tokenIdentityBaseline?: string | null | (() => string | null);
|
|
437
|
+
/**
|
|
438
|
+
* Called synchronously with every token the identity guard admits as it is
|
|
439
|
+
* handed to Convex or HTTP headers, cached tokens included, so the document
|
|
440
|
+
* can claim the identity at that moment (for example the first token a
|
|
441
|
+
* document without one obtains). Never called for a refused token. Read
|
|
442
|
+
* from a ref, so passing a new function does not re-run effects. Needs
|
|
443
|
+
* `onTokenIdentityChange`.
|
|
444
|
+
*/
|
|
445
|
+
onTokenIdentityAdmitted?: (token: string) => void;
|
|
401
446
|
};
|
|
402
447
|
/**
|
|
403
448
|
* Unified auth provider for Convex + Better Auth.
|
|
@@ -414,7 +459,11 @@ declare function ConvexAuthProvider({
|
|
|
414
459
|
initialToken,
|
|
415
460
|
onMutationUnauthorized,
|
|
416
461
|
onQueryUnauthorized,
|
|
417
|
-
isUnauthorized
|
|
462
|
+
isUnauthorized,
|
|
463
|
+
optimisticAuth,
|
|
464
|
+
onTokenIdentityChange,
|
|
465
|
+
onTokenIdentityAdmitted,
|
|
466
|
+
tokenIdentityBaseline
|
|
418
467
|
}: ConvexAuthProviderProps): react_jsx_runtime0.JSX.Element;
|
|
419
468
|
//#endregion
|
|
420
469
|
export { type AuthClient, type AuthClientWithPlugins, ConvexAuthProvider, type ConvexAuthProviderClient, ConvexAuthProviderProps, ConvexAuthProviderQueryClient, type PluginsWithCrossDomain, type PluginsWithoutCrossDomain, convexClient };
|
|
@@ -134,7 +134,7 @@ const clearSessionAtom = (authClient) => {
|
|
|
134
134
|
* Structure: AuthProvider wraps ConvexAuthProviderInner so that
|
|
135
135
|
* useAuthStore() is available when creating fetchAccessToken.
|
|
136
136
|
*/
|
|
137
|
-
function ConvexAuthProvider({ children, client, authClient, convexQueryClient, initialToken, onMutationUnauthorized, onQueryUnauthorized, isUnauthorized }) {
|
|
137
|
+
function ConvexAuthProvider({ children, client, authClient, convexQueryClient, initialToken, onMutationUnauthorized, onQueryUnauthorized, isUnauthorized, optimisticAuth = false, onTokenIdentityChange, onTokenIdentityAdmitted, tokenIdentityBaseline }) {
|
|
138
138
|
useOTTHandler(authClient);
|
|
139
139
|
return /* @__PURE__ */ jsx(AuthProvider, {
|
|
140
140
|
initialValues: useMemo(() => ({
|
|
@@ -148,6 +148,10 @@ function ConvexAuthProvider({ children, client, authClient, convexQueryClient, i
|
|
|
148
148
|
authClient,
|
|
149
149
|
client,
|
|
150
150
|
convexQueryClient,
|
|
151
|
+
onTokenIdentityAdmitted,
|
|
152
|
+
onTokenIdentityChange,
|
|
153
|
+
optimisticAuth,
|
|
154
|
+
tokenIdentityBaseline,
|
|
151
155
|
children
|
|
152
156
|
})
|
|
153
157
|
});
|
|
@@ -156,7 +160,7 @@ function ConvexAuthProvider({ children, client, authClient, convexQueryClient, i
|
|
|
156
160
|
* Inner provider that has access to AuthStore via useAuthStore().
|
|
157
161
|
* Creates fetchAccessToken and passes it through context (no race condition).
|
|
158
162
|
*/
|
|
159
|
-
function ConvexAuthProviderInner({ children, client, authClient, convexQueryClient }) {
|
|
163
|
+
function ConvexAuthProviderInner({ children, client, authClient, convexQueryClient, optimisticAuth, onTokenIdentityChange, onTokenIdentityAdmitted, tokenIdentityBaseline }) {
|
|
160
164
|
const authStore = useAuthStore();
|
|
161
165
|
convexQueryClient?.updateAuthStore(authStore);
|
|
162
166
|
const { data: session, isPending } = authClient.useSession();
|
|
@@ -239,6 +243,25 @@ function ConvexAuthProviderInner({ children, client, authClient, convexQueryClie
|
|
|
239
243
|
authStore,
|
|
240
244
|
authClient
|
|
241
245
|
]);
|
|
246
|
+
const onTokenIdentityChangeRef = useRef(onTokenIdentityChange);
|
|
247
|
+
onTokenIdentityChangeRef.current = onTokenIdentityChange;
|
|
248
|
+
const onTokenIdentityAdmittedRef = useRef(onTokenIdentityAdmitted);
|
|
249
|
+
onTokenIdentityAdmittedRef.current = onTokenIdentityAdmitted;
|
|
250
|
+
const tokenIdentityBaselineRef = useRef(tokenIdentityBaseline);
|
|
251
|
+
tokenIdentityBaselineRef.current = tokenIdentityBaseline;
|
|
252
|
+
const identityGuardRef = useRef(null);
|
|
253
|
+
identityGuardRef.current ??= {
|
|
254
|
+
identity: (typeof tokenIdentityBaseline === "function" ? null : resolveTokenIdentityBaseline(tokenIdentityBaseline)) ?? decodeTokenSubjectSessionIdentity(authStore.get("token")),
|
|
255
|
+
currentDocumentIdentity: typeof tokenIdentityBaseline === "function" ? () => resolveTokenIdentityBaseline(tokenIdentityBaselineRef.current) : null,
|
|
256
|
+
tripped: false
|
|
257
|
+
};
|
|
258
|
+
const admitToken = useCallback((token, onAdmitted) => guardTokenIdentity({
|
|
259
|
+
client,
|
|
260
|
+
guard: identityGuardRef.current,
|
|
261
|
+
onAdmitted,
|
|
262
|
+
onIdentityChange: onTokenIdentityChangeRef.current,
|
|
263
|
+
token
|
|
264
|
+
}), [client]);
|
|
242
265
|
const fetchAccessToken = useCallback(async ({ forceRefreshToken = false } = {}) => {
|
|
243
266
|
const fetchFreshToken = () => {
|
|
244
267
|
if (pendingTokenRef.current) return pendingTokenRef.current;
|
|
@@ -250,6 +273,7 @@ function ConvexAuthProviderInner({ children, client, authClient, convexQueryClie
|
|
|
250
273
|
}
|
|
251
274
|
pendingTokenRef.current = authClient.convex.token({ fetchOptions }).then((result) => {
|
|
252
275
|
const jwt = result.data?.token || null;
|
|
276
|
+
if (jwt && !admitToken(jwt)) return null;
|
|
253
277
|
if (jwt) {
|
|
254
278
|
const exp = decodeJwtExp(jwt);
|
|
255
279
|
authStore.set("token", jwt);
|
|
@@ -326,8 +350,15 @@ function ConvexAuthProviderInner({ children, client, authClient, convexQueryClie
|
|
|
326
350
|
}, [
|
|
327
351
|
authStore,
|
|
328
352
|
authClient,
|
|
329
|
-
getCachedJwt
|
|
353
|
+
getCachedJwt,
|
|
354
|
+
admitToken
|
|
330
355
|
]);
|
|
356
|
+
const guardedFetchAccessToken = useCallback(async (args = {}) => {
|
|
357
|
+
if (identityGuardRef.current?.tripped) return null;
|
|
358
|
+
const token = await fetchAccessToken(args);
|
|
359
|
+
if (!token || !admitToken(token, onTokenIdentityAdmittedRef.current)) return null;
|
|
360
|
+
return token;
|
|
361
|
+
}, [fetchAccessToken, admitToken]);
|
|
331
362
|
const useAuth = useCallback(function useConvexAuthHook() {
|
|
332
363
|
const token = authStore.get("token");
|
|
333
364
|
const hasSession = hasActiveSessionData(sessionRef.current);
|
|
@@ -335,15 +366,18 @@ function ConvexAuthProviderInner({ children, client, authClient, convexQueryClie
|
|
|
335
366
|
return {
|
|
336
367
|
isLoading: isPendingRef.current && !token,
|
|
337
368
|
isAuthenticated: sessionMissing ? false : hasSession || token !== null,
|
|
338
|
-
fetchAccessToken
|
|
369
|
+
fetchAccessToken: guardedFetchAccessToken
|
|
339
370
|
};
|
|
340
|
-
}, [
|
|
371
|
+
}, [guardedFetchAccessToken, authStore]);
|
|
341
372
|
return /* @__PURE__ */ jsx(FetchAccessTokenContext.Provider, {
|
|
342
|
-
value:
|
|
373
|
+
value: guardedFetchAccessToken,
|
|
343
374
|
children: /* @__PURE__ */ jsx(ConvexProviderWithAuth$1, {
|
|
344
375
|
client,
|
|
345
376
|
useAuth,
|
|
346
|
-
children: /* @__PURE__ */ jsx(AuthStateSync, {
|
|
377
|
+
children: /* @__PURE__ */ jsx(AuthStateSync, {
|
|
378
|
+
optimisticAuth,
|
|
379
|
+
children
|
|
380
|
+
})
|
|
347
381
|
})
|
|
348
382
|
});
|
|
349
383
|
}
|
|
@@ -359,22 +393,102 @@ function ConvexAuthProviderInner({ children, client, authClient, convexQueryClie
|
|
|
359
393
|
* 5. Without defensive check, we'd sync { isLoading: false, isAuthenticated: false }
|
|
360
394
|
* 6. Queries would throw UNAUTHORIZED before token is validated
|
|
361
395
|
*/
|
|
362
|
-
function AuthStateSync({ children }) {
|
|
396
|
+
function AuthStateSync({ children, optimisticAuth = false }) {
|
|
363
397
|
const { isLoading: convexIsLoading, isAuthenticated } = useConvexAuth();
|
|
364
398
|
const authStore = useAuthStore();
|
|
365
399
|
const token = useAuthValue("token");
|
|
400
|
+
const rejectedTokenRef = useRef(null);
|
|
366
401
|
useEffect(() => {
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
402
|
+
const gate = resolveAuthGate({
|
|
403
|
+
convexIsLoading,
|
|
404
|
+
isAuthenticated,
|
|
405
|
+
optimisticAuth,
|
|
406
|
+
rejectedToken: rejectedTokenRef.current,
|
|
407
|
+
token
|
|
408
|
+
});
|
|
409
|
+
if (optimisticAuth && isTokenRejectedByConvex({
|
|
410
|
+
convexIsLoading,
|
|
411
|
+
isAuthenticated,
|
|
412
|
+
token
|
|
413
|
+
})) rejectedTokenRef.current = token;
|
|
414
|
+
authStore.set("isLoading", gate.isLoading);
|
|
415
|
+
authStore.set("isAuthenticated", gate.isAuthenticated);
|
|
370
416
|
}, [
|
|
371
417
|
convexIsLoading,
|
|
372
418
|
isAuthenticated,
|
|
419
|
+
optimisticAuth,
|
|
373
420
|
token,
|
|
374
421
|
authStore
|
|
375
422
|
]);
|
|
376
423
|
return children;
|
|
377
424
|
}
|
|
425
|
+
function decodeTokenSubjectSessionIdentity(token) {
|
|
426
|
+
if (!token) return null;
|
|
427
|
+
try {
|
|
428
|
+
const segment = token.split(".")[1];
|
|
429
|
+
if (!segment) return null;
|
|
430
|
+
const payload = JSON.parse(atob(segment.replaceAll("-", "+").replaceAll("_", "/")));
|
|
431
|
+
if (typeof payload !== "object" || payload === null) return null;
|
|
432
|
+
const sub = "sub" in payload ? payload.sub : null;
|
|
433
|
+
const sessionId = "sessionId" in payload ? payload.sessionId : null;
|
|
434
|
+
if (typeof sub !== "string") return null;
|
|
435
|
+
return `${sub}|${typeof sessionId === "string" ? sessionId : ""}`;
|
|
436
|
+
} catch {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
function resolveTokenIdentityBaseline(baseline) {
|
|
441
|
+
return typeof baseline === "function" ? baseline() : baseline ?? null;
|
|
442
|
+
}
|
|
443
|
+
function guardTokenIdentity({ client, guard, onAdmitted, onIdentityChange, token }) {
|
|
444
|
+
if (!onIdentityChange) return true;
|
|
445
|
+
if (guard.tripped) return false;
|
|
446
|
+
const identity = decodeTokenSubjectSessionIdentity(token);
|
|
447
|
+
if (identity === null) return true;
|
|
448
|
+
const current = guard.currentDocumentIdentity?.() ?? null;
|
|
449
|
+
if ((guard.identity === null || guard.identity === identity) && (current === null || current === identity)) {
|
|
450
|
+
guard.identity = identity;
|
|
451
|
+
onAdmitted?.(token);
|
|
452
|
+
return true;
|
|
453
|
+
}
|
|
454
|
+
guard.tripped = true;
|
|
455
|
+
client.close();
|
|
456
|
+
onIdentityChange();
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Convex has settled on "not authenticated" while a token is still held: the
|
|
461
|
+
* server refused it (or refused its refresh).
|
|
462
|
+
*/
|
|
463
|
+
function isTokenRejectedByConvex({ convexIsLoading, isAuthenticated, token }) {
|
|
464
|
+
return !!token && !convexIsLoading && !isAuthenticated;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* The auth state published to the store, which is what every query gate reads.
|
|
468
|
+
*
|
|
469
|
+
* Without `optimisticAuth` this is the confirmed state: queries wait until
|
|
470
|
+
* Convex has confirmed the token. With it, a held, unexpired JWT that Convex
|
|
471
|
+
* has not refused yet counts as authenticated while Convex confirms it, so
|
|
472
|
+
* auth-bound queries subscribe at once; Convex sends them after Authenticate on
|
|
473
|
+
* the same socket, and a refused token closes the socket before any of them is
|
|
474
|
+
* evaluated. When Convex refuses the token, `isAuthenticated` falls back to
|
|
475
|
+
* false, which resets auth-bound queries (see `CRPCProviderInner`).
|
|
476
|
+
*/
|
|
477
|
+
function resolveAuthGate({ convexIsLoading, isAuthenticated, optimisticAuth, rejectedToken, token }) {
|
|
478
|
+
if (optimisticAuth && convexIsLoading && isOptimisticToken(token, rejectedToken)) return {
|
|
479
|
+
isAuthenticated: true,
|
|
480
|
+
isLoading: false
|
|
481
|
+
};
|
|
482
|
+
return {
|
|
483
|
+
isAuthenticated,
|
|
484
|
+
isLoading: convexIsLoading || !!token && !isAuthenticated
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
function isOptimisticToken(token, rejectedToken) {
|
|
488
|
+
if (!token || token === rejectedToken) return false;
|
|
489
|
+
const expiresAt = decodeJwtExp(token);
|
|
490
|
+
return expiresAt !== null && expiresAt > Date.now();
|
|
491
|
+
}
|
|
378
492
|
/**
|
|
379
493
|
* Handles cross-domain one-time token (OTT) verification.
|
|
380
494
|
*/
|
package/dist/orm/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { $n as TableName, $t as OrmLifecycleChange, An as ConvexCheckBuilder, At as UpdateSet, Bn as ConvexTextBuilder, Br as IsPrimaryKey, Bt as RelationsBuilderColumnBase, C as MigrationStep, Cn as ConvexVectorIndexConfig, Cr as not, Ct as OrderByClause, D as defineMigration, Dn as searchIndex, Dr as startsWith, Dt as ReturningAll, E as buildMigrationPlan, En as rankIndex, Er as or, Et as PredicateWhereIndexConfig, Fn as ConvexUniqueConstraintBuilderOn, Fr as ColumnBuilderTypeConfig, Ft as ExtractTablesFromSchema, Gn as Columns, Gt as TablesRelationalConfig, H as RlsMode, Hn as text, Hr as NotNull, In as ConvexUniqueConstraintConfig, Ir as ColumnBuilderWithTableName, It as ExtractTablesWithRelations, Jn as OrmSchemaExtensionTables, Jt as ConvexDeletionBuilder, Kt as defineRelations, Ln as check, Lr as ColumnDataType, Lt as ManyConfig, M as DatabaseWithQuery, Mn as ConvexForeignKeyBuilder, Mr as ColumnBuilder, Mt as VectorSearchProvider, N as OrmReader$1, Nn as ConvexForeignKeyConfig, Nr as ColumnBuilderBaseConfig, Nt as unsetToken, O as defineMigrationSet, On as uniqueIndex, Ot as ReturningResult, P as OrmWriter$1, Pn as ConvexUniqueConstraintBuilder, Pr as ColumnBuilderRuntimeConfig, Qn as OrmSchemaTriggers, Qt as DiscriminatorBuilderConfig, Rn as foreignKey, Rr as DrizzleEntity, Rt as OneConfig, S as MigrationStateMap, Sn as ConvexVectorIndexBuilderOn, Sr as ne, St as MutationRunMode, T as MigrationWriteMode, Tn as index, Tr as notInArray, Tt as PaginatedResult, U as EdgeMetadata, V as RlsContext, Vn as ConvexTextBuilderInitial, Vr as IsUnique, Vt as RelationsBuilderColumnConfig, W as extractRelationsConfig, Wn as Brand, Wt as TableRelationalConfig, Xn as OrmSchemaExtensions, Xt as ConvexTable, Yt as ConvexDeletionConfig, Zn as OrmSchemaRelations, Zt as ConvexTableWithColumns, _ as MigrationManifestEntry, _n as ConvexRankIndexBuilderOn, _r as isNotNull, _t as MutationExecutionMode, an as RlsPolicy, ar as UnaryExpression, at as BuildRelationResult, b as MigrationRunStatus, bn as ConvexSearchIndexConfig, br as lt, bt as MutationResult, cn as rlsPolicy, cr as contains, ct as DBQueryConfig, d as MigrationAppliedState, dn as rlsRole, dr as fieldRef, dt as InferInsertModel, en as OrmLifecycleOperation, er as BinaryExpression, f as MigrationDefinition, fn as ConvexAggregateIndexBuilder, fr as gt, ft as InferModelFromColumns, g as MigrationDriftIssue, gn as ConvexRankIndexBuilder, gr as isFieldReference, gt as MutationExecuteResult, h as MigrationDocContext, hn as ConvexIndexBuilderOn, hr as inArray, ht as MutationExecuteConfig, i as OrmMigrationCapability, in as discriminator, ir as LogicalExpression, it as BuildQueryResult, j as DatabaseWithMutations, jn as ConvexCheckConfig, jr as AnyColumn, jt as VectorQueryConfig, k as detectMigrationDrift, kn as vectorIndex, kr as SystemFields, kt as ReturningSelection, ln as RlsRole, lr as endsWith, lt as FilterOperators, m as MigrationDoc, mn as ConvexIndexBuilder, mr as ilike, mt as InsertValue, n as OrmCapabilities, nn as convexTable, nr as FieldReference, nt as AggregateFieldValue, on as RlsPolicyConfig, or as and, ot as CountConfig, p as MigrationDirection, pn as ConvexAggregateIndexBuilderOn, pr as gte, pt as InferSelectModel, qt as defineRelationsPart, r as OrmCapability, rn as deletion, rr as FilterExpression, rt as AggregateResult, sn as RlsPolicyToOption, sr as between, st as CountResult, t as OrmAggregateCapability, tn as TableConfig, tr as ExpressionVisitor, tt as AggregateConfig, un as RlsRoleConfig, ur as eq, ut as GetColumnData, v as MigrationMigrateOne, vn as ConvexSearchIndexBuilder, vr as isNull, vt as MutationPaginateConfig, w as MigrationTableName, wn as aggregateIndex, wr as notBetween, wt as OrderDirection, x as MigrationSet, xn as ConvexVectorIndexBuilder, xr as lte, xt as MutationReturning, y as MigrationPlan, yn as ConvexSearchIndexBuilderOn, yr as like, yt as MutationPaginatedResult, zn as unique, zr as HasDefault, zt as RelationsBuilder } from "../capabilities-Bxzoofl4.js";
|
|
2
|
-
import { $ as OrmClientWithApi$1, A as ConvexDateMode, B as ConvexBytesBuilderInitial, C as ConvexNumberBuilderInitial, D as id, E as ConvexIdBuilderInitial, F as custom, G as ConvexBigIntBuilder, H as ConvexBooleanBuilder, I as json, J as CreateOrmOptions, K as ConvexBigIntBuilderInitial, L as objectOf, M as ConvexCustomBuilder, N as ConvexCustomBuilderInitial, O as ConvexDateBuilder, P as arrayOf, Q as OrmClientBase$1, R as unionOf, S as ConvexNumberBuilder, St as defineTriggers, T as ConvexIdBuilder, U as ConvexBooleanBuilderInitial, V as bytes, W as boolean, X as GenericOrmCtx$1, Y as GenericOrm$1, Z as OrmApiResult, _ as ConvexTimestampMode, _t as OrmBeforeResult, a as requireSchemaRelations, at as ScheduledMutationBatchArgs, b as ConvexTextEnumBuilderInitial, bt as OrmTriggerContext, c as TableConfigResult, ct as scheduledDeleteFactory, d as OrmNotFoundError, et as OrmFunctions, f as ConvexVectorBuilder, g as ConvexTimestampBuilderInitial, gt as defineSchemaExtension, h as ConvexTimestampBuilder, ht as SchemaExtension, i as getSchemaTriggers, it as createOrm, j as date, k as ConvexDateBuilderInitial, l as getTableColumns, m as vector, n as defineSchema, nt as OrmWriterCtx, o as asc, ot as scheduledMutationBatchFactory, p as ConvexVectorBuilderInitial, q as bigint, r as getSchemaRelations, rt as ResolveOrmSchema, s as desc, st as ScheduledDeleteArgs, t as WhereClauseResult, tt as OrmReaderCtx, u as getTableConfig, v as timestamp, vt as OrmTableTriggers, w as integer, x as textEnum, xt as OrmTriggers, y as ConvexTextEnumBuilder, yt as OrmTriggerChange, z as ConvexBytesBuilder } from "../where-clause-compiler-
|
|
2
|
+
import { $ as OrmClientWithApi$1, A as ConvexDateMode, B as ConvexBytesBuilderInitial, C as ConvexNumberBuilderInitial, D as id, E as ConvexIdBuilderInitial, F as custom, G as ConvexBigIntBuilder, H as ConvexBooleanBuilder, I as json, J as CreateOrmOptions, K as ConvexBigIntBuilderInitial, L as objectOf, M as ConvexCustomBuilder, N as ConvexCustomBuilderInitial, O as ConvexDateBuilder, P as arrayOf, Q as OrmClientBase$1, R as unionOf, S as ConvexNumberBuilder, St as defineTriggers, T as ConvexIdBuilder, U as ConvexBooleanBuilderInitial, V as bytes, W as boolean, X as GenericOrmCtx$1, Y as GenericOrm$1, Z as OrmApiResult, _ as ConvexTimestampMode, _t as OrmBeforeResult, a as requireSchemaRelations, at as ScheduledMutationBatchArgs, b as ConvexTextEnumBuilderInitial, bt as OrmTriggerContext, c as TableConfigResult, ct as scheduledDeleteFactory, d as OrmNotFoundError, et as OrmFunctions, f as ConvexVectorBuilder, g as ConvexTimestampBuilderInitial, gt as defineSchemaExtension, h as ConvexTimestampBuilder, ht as SchemaExtension, i as getSchemaTriggers, it as createOrm, j as date, k as ConvexDateBuilderInitial, l as getTableColumns, m as vector, n as defineSchema, nt as OrmWriterCtx, o as asc, ot as scheduledMutationBatchFactory, p as ConvexVectorBuilderInitial, q as bigint, r as getSchemaRelations, rt as ResolveOrmSchema, s as desc, st as ScheduledDeleteArgs, t as WhereClauseResult, tt as OrmReaderCtx, u as getTableConfig, v as timestamp, vt as OrmTableTriggers, w as integer, x as textEnum, xt as OrmTriggers, y as ConvexTextEnumBuilder, yt as OrmTriggerChange, z as ConvexBytesBuilder } from "../where-clause-compiler-BzAJnWt4.js";
|
|
3
3
|
import { i as pretendRequired, n as deprecated, r as pretend } from "../validators-0I-Ik1EN.js";
|
|
4
4
|
import { a as QueryCtxWithPreferredOrmQueryTable, i as QueryCtxWithOrmQueryTable, n as LookupByIdResultByCtx, o as getByIdWithOrmQueryFallback, r as QueryCtxWithOptionalOrmQueryTable, t as DocByCtx } from "../query-context-BkNjkDCk.js";
|
|
5
5
|
import { DefineSchemaOptions, GenericDatabaseReader, GenericDatabaseWriter, GenericSchema, SchemaDefinition } from "convex/server";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { C as MigrationStep, D as defineMigration, E as buildMigrationPlan, O as defineMigrationSet, S as MigrationStateMap, T as MigrationWriteMode, _ as MigrationManifestEntry, a as MAX_STATUS_RUN_LIMIT, b as MigrationRunStatus, c as MigrationRunChunkArgs, d as MigrationAppliedState, f as MigrationDefinition, g as MigrationDriftIssue, h as MigrationDocContext, k as detectMigrationDrift, l as MigrationStatusArgs, m as MigrationDoc, o as MigrationCancelArgs, p as MigrationDirection, s as MigrationRunArgs, u as createMigrationHandlers, v as MigrationMigrateOne, w as MigrationTableName, x as MigrationSet, y as MigrationPlan } from "../../capabilities-Bxzoofl4.js";
|
|
2
|
-
import { Ct as migrationCapability, dt as MIGRATION_STORAGE_TABLE_NAMES, ft as injectMigrationStorageTables, lt as MIGRATION_RUN_TABLE, mt as migrationStorageTables, pt as migrationExtension, ut as MIGRATION_STATE_TABLE } from "../../where-clause-compiler-
|
|
2
|
+
import { Ct as migrationCapability, dt as MIGRATION_STORAGE_TABLE_NAMES, ft as injectMigrationStorageTables, lt as MIGRATION_RUN_TABLE, mt as migrationStorageTables, pt as migrationExtension, ut as MIGRATION_STATE_TABLE } from "../../where-clause-compiler-BzAJnWt4.js";
|
|
3
3
|
export { MAX_STATUS_RUN_LIMIT, MIGRATION_RUN_TABLE, MIGRATION_STATE_TABLE, MIGRATION_STORAGE_TABLE_NAMES, type MigrationAppliedState, type MigrationCancelArgs, type MigrationDefinition, type MigrationDirection, type MigrationDoc, type MigrationDocContext, type MigrationDriftIssue, type MigrationManifestEntry, type MigrationMigrateOne, type MigrationPlan, type MigrationRunArgs, type MigrationRunChunkArgs, type MigrationRunStatus, type MigrationSet, type MigrationStateMap, type MigrationStatusArgs, type MigrationStep, type MigrationTableName, type MigrationWriteMode, buildMigrationPlan, createMigrationHandlers, defineMigration, defineMigrationSet, detectMigrationDrift, injectMigrationStorageTables, migrationCapability, migrationExtension, migrationStorageTables };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -5,7 +5,8 @@ import { ReactNode } from "react";
|
|
|
5
5
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
6
6
|
import { FunctionArgs, FunctionReference, FunctionReturnType } from "convex/server";
|
|
7
7
|
import { DefaultError, QueryCache, QueryClient, QueryFilters, QueryFunction, QueryFunctionContext, QueryKey, SkipToken, UseMutationOptions, UseQueryOptions, UseQueryResult } from "@tanstack/react-query";
|
|
8
|
-
import {
|
|
8
|
+
import { Value } from "convex/values";
|
|
9
|
+
import { ConvexHttpClient, OptimisticUpdate } from "convex/browser";
|
|
9
10
|
import { z } from "zod";
|
|
10
11
|
|
|
11
12
|
//#region src/crpc/auth-error.d.ts
|
|
@@ -582,11 +583,19 @@ type DecorateInfiniteQuery<T extends FunctionReference<'query'>> = {
|
|
|
582
583
|
infiniteQueryKey: (args?: DeepPartial<InfiniteQueryInput<FunctionArgs<T>>>) => ConvexQueryKey<T>; /** Function metadata from server (auth, limit, rateLimit, role, type) */
|
|
583
584
|
meta: PaginatedFnMeta;
|
|
584
585
|
};
|
|
586
|
+
/**
|
|
587
|
+
* Convex-native optimistic update for a cRPC mutation. It edits Convex's local
|
|
588
|
+
* query store, which the query client reads, so Convex rolls it back when the
|
|
589
|
+
* mutation fails. Args and query values are in their wire shape.
|
|
590
|
+
*/
|
|
591
|
+
type ConvexOptimisticUpdateOption<Args extends Record<string, Value>> = {
|
|
592
|
+
optimisticUpdate?: OptimisticUpdate<Args>;
|
|
593
|
+
};
|
|
585
594
|
/**
|
|
586
595
|
* Decorated mutation procedure with mutationOptions and mutationKey methods.
|
|
587
596
|
*/
|
|
588
597
|
type DecorateMutation<T extends FunctionReference<'mutation'>> = {
|
|
589
|
-
mutationOptions: (opts?: DistributiveOmit<UseMutationOptions<FunctionReturnType<T>, DefaultError, MutationVariables<T>>, ReservedMutationOptions$2>) => UseMutationOptions<FunctionReturnType<T>, DefaultError, MutationVariables<T>>; /** Get mutation key for QueryClient methods */
|
|
598
|
+
mutationOptions: (opts?: DistributiveOmit<UseMutationOptions<FunctionReturnType<T>, DefaultError, MutationVariables<T>>, ReservedMutationOptions$2> & ConvexOptimisticUpdateOption<FunctionArgs<T>>) => UseMutationOptions<FunctionReturnType<T>, DefaultError, MutationVariables<T>>; /** Get mutation key for QueryClient methods */
|
|
590
599
|
mutationKey: () => ConvexMutationKey;
|
|
591
600
|
};
|
|
592
601
|
/**
|
|
@@ -1087,7 +1096,7 @@ declare function useConvexActionQueryOptions<Action extends FunctionReference<'a
|
|
|
1087
1096
|
* }));
|
|
1088
1097
|
* ```
|
|
1089
1098
|
*/
|
|
1090
|
-
declare function useConvexMutationOptions<Mutation extends FunctionReference<'mutation'>>(mutation: Mutation, options?: DistributiveOmit<UseMutationOptions<FunctionReturnType<Mutation>, DefaultError, FunctionArgs<Mutation>>, ReservedMutationOptions
|
|
1099
|
+
declare function useConvexMutationOptions<Mutation extends FunctionReference<'mutation'>>(mutation: Mutation, options?: DistributiveOmit<UseMutationOptions<FunctionReturnType<Mutation>, DefaultError, FunctionArgs<Mutation>>, ReservedMutationOptions> & ConvexOptimisticUpdateOption<FunctionArgs<Mutation>>, transformer?: DataTransformerOptions): UseMutationOptions<FunctionReturnType<Mutation>, DefaultError, FunctionArgs<Mutation>>;
|
|
1091
1100
|
/**
|
|
1092
1101
|
* Hook that returns action options for use with useMutation.
|
|
1093
1102
|
* Wraps the Convex action with auth guard logic.
|
package/dist/react/index.js
CHANGED
|
@@ -1155,10 +1155,12 @@ function useConvexMutationOptions(mutation, options, transformer) {
|
|
|
1155
1155
|
const name = getFunctionName(mutation);
|
|
1156
1156
|
const [namespace, fnName] = name.split(":");
|
|
1157
1157
|
const authType = getMeta(namespace, fnName)?.auth;
|
|
1158
|
-
const
|
|
1158
|
+
const { optimisticUpdate, ...mutationOptions } = options ?? {};
|
|
1159
|
+
const reactMutation = useMutation(mutation);
|
|
1160
|
+
const convexMutation = optimisticUpdate ? reactMutation.withOptimisticUpdate(optimisticUpdate) : reactMutation;
|
|
1159
1161
|
const resolvedTransformer = getTransformer(transformer);
|
|
1160
1162
|
return {
|
|
1161
|
-
...
|
|
1163
|
+
...mutationOptions,
|
|
1162
1164
|
mutationFn: async (args) => {
|
|
1163
1165
|
if (authType === "required" && guard()) throw new CRPCClientError({
|
|
1164
1166
|
code: "UNAUTHORIZED",
|
|
@@ -1496,6 +1498,16 @@ function createCRPCContext(options) {
|
|
|
1496
1498
|
convexSiteUrl: httpOptions.convexSiteUrl,
|
|
1497
1499
|
routes: meta._http,
|
|
1498
1500
|
headers: async () => {
|
|
1501
|
+
if (fetchAccessToken) {
|
|
1502
|
+
const expiresAt = authStore.get("expiresAt");
|
|
1503
|
+
const timeRemaining = expiresAt ? expiresAt - Date.now() : 0;
|
|
1504
|
+
const guardedToken = await fetchAccessToken({ forceRefreshToken: !!expiresAt && timeRemaining < 6e4 });
|
|
1505
|
+
const userHeaders = typeof httpOptions.headers === "function" ? await httpOptions.headers() : httpOptions.headers;
|
|
1506
|
+
return guardedToken ? {
|
|
1507
|
+
...userHeaders,
|
|
1508
|
+
Authorization: `Bearer ${guardedToken}`
|
|
1509
|
+
} : { ...userHeaders };
|
|
1510
|
+
}
|
|
1499
1511
|
const token = authStore.get("token");
|
|
1500
1512
|
const expiresAt = authStore.get("expiresAt");
|
|
1501
1513
|
const timeRemaining = expiresAt ? expiresAt - Date.now() : 0;
|
|
@@ -1503,13 +1515,6 @@ function createCRPCContext(options) {
|
|
|
1503
1515
|
...typeof httpOptions.headers === "function" ? await httpOptions.headers() : httpOptions.headers,
|
|
1504
1516
|
Authorization: `Bearer ${token}`
|
|
1505
1517
|
};
|
|
1506
|
-
if (fetchAccessToken) {
|
|
1507
|
-
const newToken = await fetchAccessToken({ forceRefreshToken: !!expiresAt });
|
|
1508
|
-
if (newToken) return {
|
|
1509
|
-
...typeof httpOptions.headers === "function" ? await httpOptions.headers() : httpOptions.headers,
|
|
1510
|
-
Authorization: `Bearer ${newToken}`
|
|
1511
|
-
};
|
|
1512
|
-
}
|
|
1513
1518
|
return { ...typeof httpOptions.headers === "function" ? await httpOptions.headers() : httpOptions.headers };
|
|
1514
1519
|
},
|
|
1515
1520
|
fetch: httpOptions.fetch,
|
|
@@ -2105,7 +2110,10 @@ var ConvexQueryClient = class {
|
|
|
2105
2110
|
this._queryClient = options.queryClient;
|
|
2106
2111
|
this.unsubscribe = this.subscribeInner(options.queryClient.getQueryCache());
|
|
2107
2112
|
}
|
|
2108
|
-
if (isServer) this.serverHttpClient = new ConvexHttpClient(this.convexClient.url, {
|
|
2113
|
+
if (isServer) this.serverHttpClient = new ConvexHttpClient(this.convexClient.url, {
|
|
2114
|
+
fetch: options.serverFetch,
|
|
2115
|
+
logger: this.convexClient.logger
|
|
2116
|
+
});
|
|
2109
2117
|
}
|
|
2110
2118
|
/**
|
|
2111
2119
|
* Connect to TanStack QueryClient.
|
package/dist/rsc/index.d.ts
CHANGED
|
@@ -2,7 +2,9 @@ import { n as DeepPartial, o as Simplify, r as DistributiveOmit } from "../types
|
|
|
2
2
|
import { L as DataTransformerOptions, _ as CRPCHttpRouter, c as HttpQueryKey, k as HttpProcedure, o as HttpMutationKey, y as HttpRouterRecord } from "../http-types-BhhPZtwa.js";
|
|
3
3
|
import { g as UnsetMarker } from "../types-Bkeicpo6.js";
|
|
4
4
|
import { A as HttpInputArgs, C as ReservedMutationOptions$1, S as ReservedInfiniteQueryOptions, T as StaticQueryOptsParam, _ as IsPaginated, b as PaginatedFnMeta, c as ConvexMutationKey, d as ConvexQueryMeta, f as EmptyObject, g as InfiniteQueryInput, l as ConvexQueryHookOptions, m as FUNC_REF_SYMBOL, o as ConvexActionKey, p as ExtractPaginatedItem, s as ConvexInfiniteQueryMeta, u as ConvexQueryKey, w as ReservedQueryOptions$1, y as MutationVariables } from "../types-C7JkpfeY.js";
|
|
5
|
+
import { Value } from "convex/values";
|
|
5
6
|
import { FunctionArgs, FunctionReference, FunctionReturnType } from "convex/server";
|
|
7
|
+
import { OptimisticUpdate } from "convex/browser";
|
|
6
8
|
import { z } from "zod";
|
|
7
9
|
import { DefaultError, QueryFilters, SkipToken, UseMutationOptions, UseQueryOptions } from "@tanstack/react-query";
|
|
8
10
|
|
|
@@ -70,11 +72,19 @@ type DecorateInfiniteQuery<T extends FunctionReference<'query'>> = {
|
|
|
70
72
|
infiniteQueryKey: (args?: DeepPartial<InfiniteQueryInput<FunctionArgs<T>>>) => ConvexQueryKey<T>; /** Function metadata from server (auth, limit, rateLimit, role, type) */
|
|
71
73
|
meta: PaginatedFnMeta;
|
|
72
74
|
};
|
|
75
|
+
/**
|
|
76
|
+
* Convex-native optimistic update for a cRPC mutation. It edits Convex's local
|
|
77
|
+
* query store, which the query client reads, so Convex rolls it back when the
|
|
78
|
+
* mutation fails. Args and query values are in their wire shape.
|
|
79
|
+
*/
|
|
80
|
+
type ConvexOptimisticUpdateOption<Args extends Record<string, Value>> = {
|
|
81
|
+
optimisticUpdate?: OptimisticUpdate<Args>;
|
|
82
|
+
};
|
|
73
83
|
/**
|
|
74
84
|
* Decorated mutation procedure with mutationOptions and mutationKey methods.
|
|
75
85
|
*/
|
|
76
86
|
type DecorateMutation<T extends FunctionReference<'mutation'>> = {
|
|
77
|
-
mutationOptions: (opts?: DistributiveOmit<UseMutationOptions<FunctionReturnType<T>, DefaultError, MutationVariables<T>>, ReservedMutationOptions$1>) => UseMutationOptions<FunctionReturnType<T>, DefaultError, MutationVariables<T>>; /** Get mutation key for QueryClient methods */
|
|
87
|
+
mutationOptions: (opts?: DistributiveOmit<UseMutationOptions<FunctionReturnType<T>, DefaultError, MutationVariables<T>>, ReservedMutationOptions$1> & ConvexOptimisticUpdateOption<FunctionArgs<T>>) => UseMutationOptions<FunctionReturnType<T>, DefaultError, MutationVariables<T>>; /** Get mutation key for QueryClient methods */
|
|
78
88
|
mutationKey: () => ConvexMutationKey;
|
|
79
89
|
};
|
|
80
90
|
/**
|
|
@@ -120,7 +120,7 @@ declare const migrationStorageTables: {
|
|
|
120
120
|
fieldName: "cursor";
|
|
121
121
|
};
|
|
122
122
|
};
|
|
123
|
-
|
|
123
|
+
migrationId: ConvexTextBuilderInitial<""> & {
|
|
124
124
|
_: {
|
|
125
125
|
notNull: true;
|
|
126
126
|
};
|
|
@@ -130,19 +130,23 @@ declare const migrationStorageTables: {
|
|
|
130
130
|
};
|
|
131
131
|
} & {
|
|
132
132
|
_: {
|
|
133
|
-
fieldName: "
|
|
133
|
+
fieldName: "migrationId";
|
|
134
134
|
};
|
|
135
135
|
};
|
|
136
|
-
|
|
136
|
+
checksum: ConvexTextBuilderInitial<""> & {
|
|
137
|
+
_: {
|
|
138
|
+
notNull: true;
|
|
139
|
+
};
|
|
140
|
+
} & {
|
|
137
141
|
_: {
|
|
138
142
|
tableName: "migration_state";
|
|
139
143
|
};
|
|
140
144
|
} & {
|
|
141
145
|
_: {
|
|
142
|
-
fieldName: "
|
|
146
|
+
fieldName: "checksum";
|
|
143
147
|
};
|
|
144
148
|
};
|
|
145
|
-
|
|
149
|
+
applied: ConvexBooleanBuilderInitial<""> & {
|
|
146
150
|
_: {
|
|
147
151
|
notNull: true;
|
|
148
152
|
};
|
|
@@ -152,41 +156,41 @@ declare const migrationStorageTables: {
|
|
|
152
156
|
};
|
|
153
157
|
} & {
|
|
154
158
|
_: {
|
|
155
|
-
fieldName: "
|
|
159
|
+
fieldName: "applied";
|
|
156
160
|
};
|
|
157
161
|
};
|
|
158
|
-
|
|
162
|
+
runId: ConvexTextBuilderInitial<""> & {
|
|
159
163
|
_: {
|
|
160
164
|
tableName: "migration_state";
|
|
161
165
|
};
|
|
162
166
|
} & {
|
|
163
167
|
_: {
|
|
164
|
-
fieldName: "
|
|
168
|
+
fieldName: "runId";
|
|
165
169
|
};
|
|
166
170
|
};
|
|
167
|
-
|
|
171
|
+
processed: ConvexNumberBuilderInitial<""> & {
|
|
168
172
|
_: {
|
|
169
|
-
|
|
173
|
+
notNull: true;
|
|
170
174
|
};
|
|
171
175
|
} & {
|
|
172
176
|
_: {
|
|
173
|
-
|
|
177
|
+
tableName: "migration_state";
|
|
174
178
|
};
|
|
175
|
-
}
|
|
176
|
-
migrationId: ConvexTextBuilderInitial<""> & {
|
|
179
|
+
} & {
|
|
177
180
|
_: {
|
|
178
|
-
|
|
181
|
+
fieldName: "processed";
|
|
179
182
|
};
|
|
180
|
-
}
|
|
183
|
+
};
|
|
184
|
+
startedAt: ConvexNumberBuilderInitial<""> & {
|
|
181
185
|
_: {
|
|
182
186
|
tableName: "migration_state";
|
|
183
187
|
};
|
|
184
188
|
} & {
|
|
185
189
|
_: {
|
|
186
|
-
fieldName: "
|
|
190
|
+
fieldName: "startedAt";
|
|
187
191
|
};
|
|
188
192
|
};
|
|
189
|
-
|
|
193
|
+
updatedAt: ConvexNumberBuilderInitial<""> & {
|
|
190
194
|
_: {
|
|
191
195
|
notNull: true;
|
|
192
196
|
};
|
|
@@ -196,29 +200,25 @@ declare const migrationStorageTables: {
|
|
|
196
200
|
};
|
|
197
201
|
} & {
|
|
198
202
|
_: {
|
|
199
|
-
fieldName: "
|
|
203
|
+
fieldName: "updatedAt";
|
|
200
204
|
};
|
|
201
205
|
};
|
|
202
|
-
|
|
203
|
-
_: {
|
|
204
|
-
notNull: true;
|
|
205
|
-
};
|
|
206
|
-
} & {
|
|
206
|
+
completedAt: ConvexNumberBuilderInitial<""> & {
|
|
207
207
|
_: {
|
|
208
208
|
tableName: "migration_state";
|
|
209
209
|
};
|
|
210
210
|
} & {
|
|
211
211
|
_: {
|
|
212
|
-
fieldName: "
|
|
212
|
+
fieldName: "completedAt";
|
|
213
213
|
};
|
|
214
214
|
};
|
|
215
|
-
|
|
215
|
+
lastError: ConvexTextBuilderInitial<""> & {
|
|
216
216
|
_: {
|
|
217
217
|
tableName: "migration_state";
|
|
218
218
|
};
|
|
219
219
|
} & {
|
|
220
220
|
_: {
|
|
221
|
-
fieldName: "
|
|
221
|
+
fieldName: "lastError";
|
|
222
222
|
};
|
|
223
223
|
};
|
|
224
224
|
writeMode: ConvexTextBuilderInitial<""> & {
|
|
@@ -269,6 +269,19 @@ declare const migrationStorageTables: {
|
|
|
269
269
|
fieldName: "direction";
|
|
270
270
|
};
|
|
271
271
|
};
|
|
272
|
+
runId: ConvexTextBuilderInitial<""> & {
|
|
273
|
+
_: {
|
|
274
|
+
notNull: true;
|
|
275
|
+
};
|
|
276
|
+
} & {
|
|
277
|
+
_: {
|
|
278
|
+
tableName: "migration_run";
|
|
279
|
+
};
|
|
280
|
+
} & {
|
|
281
|
+
_: {
|
|
282
|
+
fieldName: "runId";
|
|
283
|
+
};
|
|
284
|
+
};
|
|
272
285
|
startedAt: ConvexNumberBuilderInitial<""> & {
|
|
273
286
|
_: {
|
|
274
287
|
notNull: true;
|
|
@@ -313,19 +326,6 @@ declare const migrationStorageTables: {
|
|
|
313
326
|
fieldName: "lastError";
|
|
314
327
|
};
|
|
315
328
|
};
|
|
316
|
-
runId: ConvexTextBuilderInitial<""> & {
|
|
317
|
-
_: {
|
|
318
|
-
notNull: true;
|
|
319
|
-
};
|
|
320
|
-
} & {
|
|
321
|
-
_: {
|
|
322
|
-
tableName: "migration_run";
|
|
323
|
-
};
|
|
324
|
-
} & {
|
|
325
|
-
_: {
|
|
326
|
-
fieldName: "runId";
|
|
327
|
-
};
|
|
328
|
-
};
|
|
329
329
|
dryRun: ConvexBooleanBuilderInitial<""> & {
|
|
330
330
|
_: {
|
|
331
331
|
notNull: true;
|
|
@@ -1011,7 +1011,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1011
1011
|
readonly aggregate_bucket: ConvexTableWithColumns<{
|
|
1012
1012
|
name: "aggregate_bucket";
|
|
1013
1013
|
columns: {
|
|
1014
|
-
|
|
1014
|
+
count: ConvexNumberBuilderInitial<""> & {
|
|
1015
1015
|
_: {
|
|
1016
1016
|
notNull: true;
|
|
1017
1017
|
};
|
|
@@ -1021,7 +1021,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1021
1021
|
};
|
|
1022
1022
|
} & {
|
|
1023
1023
|
_: {
|
|
1024
|
-
fieldName: "
|
|
1024
|
+
fieldName: "count";
|
|
1025
1025
|
};
|
|
1026
1026
|
};
|
|
1027
1027
|
updatedAt: ConvexNumberBuilderInitial<""> & {
|
|
@@ -1037,7 +1037,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1037
1037
|
fieldName: "updatedAt";
|
|
1038
1038
|
};
|
|
1039
1039
|
};
|
|
1040
|
-
|
|
1040
|
+
indexName: ConvexTextBuilderInitial<""> & {
|
|
1041
1041
|
_: {
|
|
1042
1042
|
notNull: true;
|
|
1043
1043
|
};
|
|
@@ -1047,10 +1047,10 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1047
1047
|
};
|
|
1048
1048
|
} & {
|
|
1049
1049
|
_: {
|
|
1050
|
-
fieldName: "
|
|
1050
|
+
fieldName: "indexName";
|
|
1051
1051
|
};
|
|
1052
1052
|
};
|
|
1053
|
-
|
|
1053
|
+
tableKey: ConvexTextBuilderInitial<""> & {
|
|
1054
1054
|
_: {
|
|
1055
1055
|
notNull: true;
|
|
1056
1056
|
};
|
|
@@ -1060,7 +1060,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1060
1060
|
};
|
|
1061
1061
|
} & {
|
|
1062
1062
|
_: {
|
|
1063
|
-
fieldName: "
|
|
1063
|
+
fieldName: "tableKey";
|
|
1064
1064
|
};
|
|
1065
1065
|
};
|
|
1066
1066
|
keyHash: ConvexTextBuilderInitial<""> & {
|
|
@@ -1149,7 +1149,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1149
1149
|
fieldName: "kind";
|
|
1150
1150
|
};
|
|
1151
1151
|
};
|
|
1152
|
-
|
|
1152
|
+
updatedAt: ConvexNumberBuilderInitial<""> & {
|
|
1153
1153
|
_: {
|
|
1154
1154
|
notNull: true;
|
|
1155
1155
|
};
|
|
@@ -1159,10 +1159,10 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1159
1159
|
};
|
|
1160
1160
|
} & {
|
|
1161
1161
|
_: {
|
|
1162
|
-
fieldName: "
|
|
1162
|
+
fieldName: "updatedAt";
|
|
1163
1163
|
};
|
|
1164
1164
|
};
|
|
1165
|
-
|
|
1165
|
+
indexName: ConvexTextBuilderInitial<""> & {
|
|
1166
1166
|
_: {
|
|
1167
1167
|
notNull: true;
|
|
1168
1168
|
};
|
|
@@ -1172,7 +1172,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1172
1172
|
};
|
|
1173
1173
|
} & {
|
|
1174
1174
|
_: {
|
|
1175
|
-
fieldName: "
|
|
1175
|
+
fieldName: "indexName";
|
|
1176
1176
|
};
|
|
1177
1177
|
};
|
|
1178
1178
|
tableKey: ConvexTextBuilderInitial<""> & {
|
|
@@ -1343,7 +1343,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1343
1343
|
fieldName: "value";
|
|
1344
1344
|
};
|
|
1345
1345
|
};
|
|
1346
|
-
|
|
1346
|
+
count: ConvexNumberBuilderInitial<""> & {
|
|
1347
1347
|
_: {
|
|
1348
1348
|
notNull: true;
|
|
1349
1349
|
};
|
|
@@ -1353,7 +1353,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1353
1353
|
};
|
|
1354
1354
|
} & {
|
|
1355
1355
|
_: {
|
|
1356
|
-
fieldName: "
|
|
1356
|
+
fieldName: "count";
|
|
1357
1357
|
};
|
|
1358
1358
|
};
|
|
1359
1359
|
updatedAt: ConvexNumberBuilderInitial<""> & {
|
|
@@ -1369,7 +1369,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1369
1369
|
fieldName: "updatedAt";
|
|
1370
1370
|
};
|
|
1371
1371
|
};
|
|
1372
|
-
|
|
1372
|
+
indexName: ConvexTextBuilderInitial<""> & {
|
|
1373
1373
|
_: {
|
|
1374
1374
|
notNull: true;
|
|
1375
1375
|
};
|
|
@@ -1379,10 +1379,10 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1379
1379
|
};
|
|
1380
1380
|
} & {
|
|
1381
1381
|
_: {
|
|
1382
|
-
fieldName: "
|
|
1382
|
+
fieldName: "indexName";
|
|
1383
1383
|
};
|
|
1384
1384
|
};
|
|
1385
|
-
|
|
1385
|
+
tableKey: ConvexTextBuilderInitial<""> & {
|
|
1386
1386
|
_: {
|
|
1387
1387
|
notNull: true;
|
|
1388
1388
|
};
|
|
@@ -1392,7 +1392,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1392
1392
|
};
|
|
1393
1393
|
} & {
|
|
1394
1394
|
_: {
|
|
1395
|
-
fieldName: "
|
|
1395
|
+
fieldName: "tableKey";
|
|
1396
1396
|
};
|
|
1397
1397
|
};
|
|
1398
1398
|
keyHash: ConvexTextBuilderInitial<""> & {
|
|
@@ -1618,7 +1618,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1618
1618
|
fieldName: "cursor";
|
|
1619
1619
|
};
|
|
1620
1620
|
};
|
|
1621
|
-
|
|
1621
|
+
processed: ConvexNumberBuilderInitial<""> & {
|
|
1622
1622
|
_: {
|
|
1623
1623
|
notNull: true;
|
|
1624
1624
|
};
|
|
@@ -1628,10 +1628,10 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1628
1628
|
};
|
|
1629
1629
|
} & {
|
|
1630
1630
|
_: {
|
|
1631
|
-
fieldName: "
|
|
1631
|
+
fieldName: "processed";
|
|
1632
1632
|
};
|
|
1633
1633
|
};
|
|
1634
|
-
|
|
1634
|
+
startedAt: ConvexNumberBuilderInitial<""> & {
|
|
1635
1635
|
_: {
|
|
1636
1636
|
notNull: true;
|
|
1637
1637
|
};
|
|
@@ -1641,10 +1641,10 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1641
1641
|
};
|
|
1642
1642
|
} & {
|
|
1643
1643
|
_: {
|
|
1644
|
-
fieldName: "
|
|
1644
|
+
fieldName: "startedAt";
|
|
1645
1645
|
};
|
|
1646
1646
|
};
|
|
1647
|
-
|
|
1647
|
+
updatedAt: ConvexNumberBuilderInitial<""> & {
|
|
1648
1648
|
_: {
|
|
1649
1649
|
notNull: true;
|
|
1650
1650
|
};
|
|
@@ -1654,23 +1654,28 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1654
1654
|
};
|
|
1655
1655
|
} & {
|
|
1656
1656
|
_: {
|
|
1657
|
-
fieldName: "
|
|
1657
|
+
fieldName: "updatedAt";
|
|
1658
1658
|
};
|
|
1659
1659
|
};
|
|
1660
|
-
|
|
1660
|
+
completedAt: ConvexNumberBuilderInitial<""> & {
|
|
1661
1661
|
_: {
|
|
1662
|
-
|
|
1662
|
+
tableName: "aggregate_state";
|
|
1663
1663
|
};
|
|
1664
1664
|
} & {
|
|
1665
|
+
_: {
|
|
1666
|
+
fieldName: "completedAt";
|
|
1667
|
+
};
|
|
1668
|
+
};
|
|
1669
|
+
lastError: ConvexTextBuilderInitial<""> & {
|
|
1665
1670
|
_: {
|
|
1666
1671
|
tableName: "aggregate_state";
|
|
1667
1672
|
};
|
|
1668
1673
|
} & {
|
|
1669
1674
|
_: {
|
|
1670
|
-
fieldName: "
|
|
1675
|
+
fieldName: "lastError";
|
|
1671
1676
|
};
|
|
1672
1677
|
};
|
|
1673
|
-
|
|
1678
|
+
indexName: ConvexTextBuilderInitial<""> & {
|
|
1674
1679
|
_: {
|
|
1675
1680
|
notNull: true;
|
|
1676
1681
|
};
|
|
@@ -1680,10 +1685,10 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1680
1685
|
};
|
|
1681
1686
|
} & {
|
|
1682
1687
|
_: {
|
|
1683
|
-
fieldName: "
|
|
1688
|
+
fieldName: "indexName";
|
|
1684
1689
|
};
|
|
1685
1690
|
};
|
|
1686
|
-
|
|
1691
|
+
keyDefinitionHash: ConvexTextBuilderInitial<""> & {
|
|
1687
1692
|
_: {
|
|
1688
1693
|
notNull: true;
|
|
1689
1694
|
};
|
|
@@ -1693,25 +1698,20 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1693
1698
|
};
|
|
1694
1699
|
} & {
|
|
1695
1700
|
_: {
|
|
1696
|
-
fieldName: "
|
|
1701
|
+
fieldName: "keyDefinitionHash";
|
|
1697
1702
|
};
|
|
1698
1703
|
};
|
|
1699
|
-
|
|
1704
|
+
metricDefinitionHash: ConvexTextBuilderInitial<""> & {
|
|
1700
1705
|
_: {
|
|
1701
|
-
|
|
1706
|
+
notNull: true;
|
|
1702
1707
|
};
|
|
1703
1708
|
} & {
|
|
1704
|
-
_: {
|
|
1705
|
-
fieldName: "completedAt";
|
|
1706
|
-
};
|
|
1707
|
-
};
|
|
1708
|
-
lastError: ConvexTextBuilderInitial<""> & {
|
|
1709
1709
|
_: {
|
|
1710
1710
|
tableName: "aggregate_state";
|
|
1711
1711
|
};
|
|
1712
1712
|
} & {
|
|
1713
1713
|
_: {
|
|
1714
|
-
fieldName: "
|
|
1714
|
+
fieldName: "metricDefinitionHash";
|
|
1715
1715
|
};
|
|
1716
1716
|
};
|
|
1717
1717
|
tableKey: ConvexTextBuilderInitial<""> & {
|
|
@@ -1769,7 +1769,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1769
1769
|
fieldName: "cursor";
|
|
1770
1770
|
};
|
|
1771
1771
|
};
|
|
1772
|
-
|
|
1772
|
+
migrationId: ConvexTextBuilderInitial<""> & {
|
|
1773
1773
|
_: {
|
|
1774
1774
|
notNull: true;
|
|
1775
1775
|
};
|
|
@@ -1779,19 +1779,23 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1779
1779
|
};
|
|
1780
1780
|
} & {
|
|
1781
1781
|
_: {
|
|
1782
|
-
fieldName: "
|
|
1782
|
+
fieldName: "migrationId";
|
|
1783
1783
|
};
|
|
1784
1784
|
};
|
|
1785
|
-
|
|
1785
|
+
checksum: ConvexTextBuilderInitial<""> & {
|
|
1786
|
+
_: {
|
|
1787
|
+
notNull: true;
|
|
1788
|
+
};
|
|
1789
|
+
} & {
|
|
1786
1790
|
_: {
|
|
1787
1791
|
tableName: "migration_state";
|
|
1788
1792
|
};
|
|
1789
1793
|
} & {
|
|
1790
1794
|
_: {
|
|
1791
|
-
fieldName: "
|
|
1795
|
+
fieldName: "checksum";
|
|
1792
1796
|
};
|
|
1793
1797
|
};
|
|
1794
|
-
|
|
1798
|
+
applied: ConvexBooleanBuilderInitial<""> & {
|
|
1795
1799
|
_: {
|
|
1796
1800
|
notNull: true;
|
|
1797
1801
|
};
|
|
@@ -1801,41 +1805,41 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1801
1805
|
};
|
|
1802
1806
|
} & {
|
|
1803
1807
|
_: {
|
|
1804
|
-
fieldName: "
|
|
1808
|
+
fieldName: "applied";
|
|
1805
1809
|
};
|
|
1806
1810
|
};
|
|
1807
|
-
|
|
1811
|
+
runId: ConvexTextBuilderInitial<""> & {
|
|
1808
1812
|
_: {
|
|
1809
1813
|
tableName: "migration_state";
|
|
1810
1814
|
};
|
|
1811
1815
|
} & {
|
|
1812
1816
|
_: {
|
|
1813
|
-
fieldName: "
|
|
1817
|
+
fieldName: "runId";
|
|
1814
1818
|
};
|
|
1815
1819
|
};
|
|
1816
|
-
|
|
1820
|
+
processed: ConvexNumberBuilderInitial<""> & {
|
|
1817
1821
|
_: {
|
|
1818
|
-
|
|
1822
|
+
notNull: true;
|
|
1819
1823
|
};
|
|
1820
1824
|
} & {
|
|
1821
1825
|
_: {
|
|
1822
|
-
|
|
1826
|
+
tableName: "migration_state";
|
|
1823
1827
|
};
|
|
1824
|
-
}
|
|
1825
|
-
migrationId: ConvexTextBuilderInitial<""> & {
|
|
1828
|
+
} & {
|
|
1826
1829
|
_: {
|
|
1827
|
-
|
|
1830
|
+
fieldName: "processed";
|
|
1828
1831
|
};
|
|
1829
|
-
}
|
|
1832
|
+
};
|
|
1833
|
+
startedAt: ConvexNumberBuilderInitial<""> & {
|
|
1830
1834
|
_: {
|
|
1831
1835
|
tableName: "migration_state";
|
|
1832
1836
|
};
|
|
1833
1837
|
} & {
|
|
1834
1838
|
_: {
|
|
1835
|
-
fieldName: "
|
|
1839
|
+
fieldName: "startedAt";
|
|
1836
1840
|
};
|
|
1837
1841
|
};
|
|
1838
|
-
|
|
1842
|
+
updatedAt: ConvexNumberBuilderInitial<""> & {
|
|
1839
1843
|
_: {
|
|
1840
1844
|
notNull: true;
|
|
1841
1845
|
};
|
|
@@ -1845,29 +1849,25 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1845
1849
|
};
|
|
1846
1850
|
} & {
|
|
1847
1851
|
_: {
|
|
1848
|
-
fieldName: "
|
|
1852
|
+
fieldName: "updatedAt";
|
|
1849
1853
|
};
|
|
1850
1854
|
};
|
|
1851
|
-
|
|
1852
|
-
_: {
|
|
1853
|
-
notNull: true;
|
|
1854
|
-
};
|
|
1855
|
-
} & {
|
|
1855
|
+
completedAt: ConvexNumberBuilderInitial<""> & {
|
|
1856
1856
|
_: {
|
|
1857
1857
|
tableName: "migration_state";
|
|
1858
1858
|
};
|
|
1859
1859
|
} & {
|
|
1860
1860
|
_: {
|
|
1861
|
-
fieldName: "
|
|
1861
|
+
fieldName: "completedAt";
|
|
1862
1862
|
};
|
|
1863
1863
|
};
|
|
1864
|
-
|
|
1864
|
+
lastError: ConvexTextBuilderInitial<""> & {
|
|
1865
1865
|
_: {
|
|
1866
1866
|
tableName: "migration_state";
|
|
1867
1867
|
};
|
|
1868
1868
|
} & {
|
|
1869
1869
|
_: {
|
|
1870
|
-
fieldName: "
|
|
1870
|
+
fieldName: "lastError";
|
|
1871
1871
|
};
|
|
1872
1872
|
};
|
|
1873
1873
|
writeMode: ConvexTextBuilderInitial<""> & {
|
|
@@ -1918,6 +1918,19 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1918
1918
|
fieldName: "direction";
|
|
1919
1919
|
};
|
|
1920
1920
|
};
|
|
1921
|
+
runId: ConvexTextBuilderInitial<""> & {
|
|
1922
|
+
_: {
|
|
1923
|
+
notNull: true;
|
|
1924
|
+
};
|
|
1925
|
+
} & {
|
|
1926
|
+
_: {
|
|
1927
|
+
tableName: "migration_run";
|
|
1928
|
+
};
|
|
1929
|
+
} & {
|
|
1930
|
+
_: {
|
|
1931
|
+
fieldName: "runId";
|
|
1932
|
+
};
|
|
1933
|
+
};
|
|
1921
1934
|
startedAt: ConvexNumberBuilderInitial<""> & {
|
|
1922
1935
|
_: {
|
|
1923
1936
|
notNull: true;
|
|
@@ -1962,19 +1975,6 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1962
1975
|
fieldName: "lastError";
|
|
1963
1976
|
};
|
|
1964
1977
|
};
|
|
1965
|
-
runId: ConvexTextBuilderInitial<""> & {
|
|
1966
|
-
_: {
|
|
1967
|
-
notNull: true;
|
|
1968
|
-
};
|
|
1969
|
-
} & {
|
|
1970
|
-
_: {
|
|
1971
|
-
tableName: "migration_run";
|
|
1972
|
-
};
|
|
1973
|
-
} & {
|
|
1974
|
-
_: {
|
|
1975
|
-
fieldName: "runId";
|
|
1976
|
-
};
|
|
1977
|
-
};
|
|
1978
1978
|
dryRun: ConvexBooleanBuilderInitial<""> & {
|
|
1979
1979
|
_: {
|
|
1980
1980
|
notNull: true;
|
package/package.json
CHANGED
|
@@ -406,11 +406,26 @@ All from `kitcn/react`:
|
|
|
406
406
|
authClient={authClient}
|
|
407
407
|
convexQueryClient={convexQueryClient} // when using TanStack Query
|
|
408
408
|
initialToken={token} // from SSR (caller.getToken())
|
|
409
|
+
optimisticAuth // opt in: open gates while Convex confirms a held JWT
|
|
410
|
+
onTokenIdentityChange={() => window.location.reload()}
|
|
409
411
|
onMutationUnauthorized={() => router.push('/login')}
|
|
410
412
|
onQueryUnauthorized={({ queryName }) => console.log(`Unauth: ${queryName}`)}
|
|
411
413
|
>
|
|
412
414
|
```
|
|
413
415
|
|
|
416
|
+
`optimisticAuth` only opens auth-bound query gates for a held, unexpired JWT;
|
|
417
|
+
expired, opaque, and refused tokens stay closed. Enable
|
|
418
|
+
`onTokenIdentityChange` to refuse a JWT whose `sub` or `sessionId` differs from
|
|
419
|
+
the document identity before Convex or HTTP sees it. The client closes before
|
|
420
|
+
the callback runs, so reload the document there.
|
|
421
|
+
|
|
422
|
+
For multiple provider mounts, pass `tokenIdentityBaseline` as
|
|
423
|
+
`sub|sessionId`, or a getter returning the document's current identity. The
|
|
424
|
+
getter is checked for every admission, cached tokens included.
|
|
425
|
+
`onTokenIdentityAdmitted(token)` observes admitted JWTs so the app can update
|
|
426
|
+
that shared baseline. All three identity options require
|
|
427
|
+
`onTokenIdentityChange`.
|
|
428
|
+
|
|
414
429
|
For `@convex-dev/auth` (React Native):
|
|
415
430
|
```tsx
|
|
416
431
|
import { ConvexProviderWithAuth } from 'kitcn/react';
|
|
@@ -298,6 +298,22 @@ const mutation = useMutation(crpc.user.update.mutationOptions({
|
|
|
298
298
|
|
|
299
299
|
Signature: `crpc.path.mutationOptions(options?)` — standard TanStack mutation options except `mutationFn`.
|
|
300
300
|
|
|
301
|
+
Pass `optimisticUpdate(localStore, args)` to use Convex's optimistic local
|
|
302
|
+
query store. This option is removed before the TanStack options are returned;
|
|
303
|
+
Convex replays it as query data changes and owns rollback when the mutation
|
|
304
|
+
completes.
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
const mutation = useMutation(crpc.todos.rename.mutationOptions({
|
|
308
|
+
optimisticUpdate: (store, args) => {
|
|
309
|
+
const todos = store.getQuery(api.todos.list, {});
|
|
310
|
+
if (todos) store.setQuery(api.todos.list, {}, todos.map((todo) =>
|
|
311
|
+
todo._id === args.id ? { ...todo, title: args.title } : todo
|
|
312
|
+
));
|
|
313
|
+
},
|
|
314
|
+
}));
|
|
315
|
+
```
|
|
316
|
+
|
|
301
317
|
### Mutation Keys
|
|
302
318
|
|
|
303
319
|
```ts
|