kitcn 0.12.8 → 0.12.10
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/auth/client/index.js +32 -8
- package/dist/cli.mjs +140 -28
- package/dist/react/index.d.ts +5 -1
- package/dist/react/index.js +67 -47
- package/package.json +1 -1
|
@@ -52,6 +52,13 @@ function ConvexAuthProviderInner({ children, client, authClient }) {
|
|
|
52
52
|
const pendingTokenRef = useRef(null);
|
|
53
53
|
sessionRef.current = session;
|
|
54
54
|
isPendingRef.current = isPending;
|
|
55
|
+
const getCachedJwt = useCallback((minTimeRemainingMs = 0) => {
|
|
56
|
+
const cachedToken = authStore.get("token");
|
|
57
|
+
if (!cachedToken) return null;
|
|
58
|
+
const expiresAt = decodeJwtExp(cachedToken);
|
|
59
|
+
if (expiresAt === null || expiresAt <= Date.now() + minTimeRemainingMs) return null;
|
|
60
|
+
return cachedToken;
|
|
61
|
+
}, [authStore]);
|
|
55
62
|
useEffect(() => {
|
|
56
63
|
if (hasActiveSessionData(session)) {
|
|
57
64
|
authStore.set("sessionSyncGraceUntil", null);
|
|
@@ -86,11 +93,23 @@ function ConvexAuthProviderInner({ children, client, authClient }) {
|
|
|
86
93
|
authStore.set("sessionSyncGraceUntil", null);
|
|
87
94
|
return jwt;
|
|
88
95
|
}
|
|
96
|
+
const cachedJwt = getCachedJwt();
|
|
97
|
+
if (cachedJwt) {
|
|
98
|
+
authStore.set("expiresAt", decodeJwtExp(cachedJwt));
|
|
99
|
+
authStore.set("sessionSyncGraceUntil", null);
|
|
100
|
+
return cachedJwt;
|
|
101
|
+
}
|
|
89
102
|
authStore.set("token", null);
|
|
90
103
|
authStore.set("expiresAt", null);
|
|
91
104
|
authStore.set("sessionSyncGraceUntil", null);
|
|
92
105
|
return null;
|
|
93
106
|
}).catch((error) => {
|
|
107
|
+
const cachedJwt = getCachedJwt();
|
|
108
|
+
if (cachedJwt) {
|
|
109
|
+
authStore.set("expiresAt", decodeJwtExp(cachedJwt));
|
|
110
|
+
authStore.set("sessionSyncGraceUntil", null);
|
|
111
|
+
return cachedJwt;
|
|
112
|
+
}
|
|
94
113
|
authStore.set("token", null);
|
|
95
114
|
authStore.set("expiresAt", null);
|
|
96
115
|
authStore.set("sessionSyncGraceUntil", null);
|
|
@@ -102,9 +121,10 @@ function ConvexAuthProviderInner({ children, client, authClient }) {
|
|
|
102
121
|
return pendingTokenRef.current;
|
|
103
122
|
};
|
|
104
123
|
const fetchFreshTokenForced = async () => {
|
|
124
|
+
const cachedJwt = getCachedJwt();
|
|
105
125
|
if (pendingTokenRef.current) {
|
|
106
126
|
const token = await pendingTokenRef.current;
|
|
107
|
-
if (token) return token;
|
|
127
|
+
if (token && (!cachedJwt || token !== cachedJwt)) return token;
|
|
108
128
|
}
|
|
109
129
|
return fetchFreshToken();
|
|
110
130
|
};
|
|
@@ -114,16 +134,16 @@ function ConvexAuthProviderInner({ children, client, authClient }) {
|
|
|
114
134
|
const hasSessionSyncGrace = isSessionSyncGraceActive(authStore.get("sessionSyncGraceUntil"));
|
|
115
135
|
if (!hasSession) {
|
|
116
136
|
if (currentIsPending || hasSessionSyncGrace) {
|
|
117
|
-
const
|
|
137
|
+
const cachedJwt = getCachedJwt();
|
|
118
138
|
if (!forceRefreshToken) {
|
|
119
|
-
if (
|
|
139
|
+
if (cachedJwt) return cachedJwt;
|
|
120
140
|
return fetchFreshToken();
|
|
121
141
|
}
|
|
122
142
|
const freshToken = await fetchFreshTokenForced();
|
|
123
|
-
if (!freshToken &&
|
|
124
|
-
authStore.set("token",
|
|
125
|
-
authStore.set("expiresAt", decodeJwtExp(
|
|
126
|
-
return
|
|
143
|
+
if (!freshToken && cachedJwt) {
|
|
144
|
+
authStore.set("token", cachedJwt);
|
|
145
|
+
authStore.set("expiresAt", decodeJwtExp(cachedJwt));
|
|
146
|
+
return cachedJwt;
|
|
127
147
|
}
|
|
128
148
|
return freshToken;
|
|
129
149
|
}
|
|
@@ -139,7 +159,11 @@ function ConvexAuthProviderInner({ children, client, authClient }) {
|
|
|
139
159
|
if (!forceRefreshToken && pendingTokenRef.current) return pendingTokenRef.current;
|
|
140
160
|
if (forceRefreshToken) return fetchFreshTokenForced();
|
|
141
161
|
return fetchFreshToken();
|
|
142
|
-
}, [
|
|
162
|
+
}, [
|
|
163
|
+
authStore,
|
|
164
|
+
authClient,
|
|
165
|
+
getCachedJwt
|
|
166
|
+
]);
|
|
143
167
|
const useAuth = useCallback(function useConvexAuthHook() {
|
|
144
168
|
const token = authStore.get("token");
|
|
145
169
|
const hasSession = hasActiveSessionData(sessionRef.current);
|
package/dist/cli.mjs
CHANGED
|
@@ -1950,7 +1950,10 @@ const CONVEX_MANAGED_ENV_KEYS = new Set([
|
|
|
1950
1950
|
"NEXT_PUBLIC_CONVEX_URL",
|
|
1951
1951
|
"VITE_CONVEX_URL"
|
|
1952
1952
|
]);
|
|
1953
|
-
const defaultRunCommand = async (args, cwd) => runLocalConvexCommand(args, {
|
|
1953
|
+
const defaultRunCommand = async (args, cwd, env) => runLocalConvexCommand(args, {
|
|
1954
|
+
cwd,
|
|
1955
|
+
env
|
|
1956
|
+
});
|
|
1954
1957
|
const generateAuthSecret = () => randomBytes(32).toString("base64url");
|
|
1955
1958
|
const defaultSecretGenerator = () => generateAuthSecret();
|
|
1956
1959
|
const normalizeRelativePath = (cwd, filePath) => path.relative(cwd, filePath).replaceAll("\\", "/") || ".";
|
|
@@ -2015,8 +2018,8 @@ const ensureAuthSecret = (params) => {
|
|
|
2015
2018
|
if (!params.silent) logger.info("Generated BETTER_AUTH_SECRET in convex/.env");
|
|
2016
2019
|
return secret;
|
|
2017
2020
|
};
|
|
2018
|
-
const runConvexCommand = async (runCommand, cwd, args) => {
|
|
2019
|
-
const result = await runCommand(args, cwd);
|
|
2021
|
+
const runConvexCommand = async (runCommand, cwd, args, env) => {
|
|
2022
|
+
const result = await runCommand(args, cwd, env);
|
|
2020
2023
|
if (result.exitCode !== 0) throw new Error(formatConvexCommandFailure(args, result));
|
|
2021
2024
|
return result;
|
|
2022
2025
|
};
|
|
@@ -2069,6 +2072,7 @@ async function pushEnv(options = {}, deps = {}) {
|
|
|
2069
2072
|
const rotate = options.rotate ?? false;
|
|
2070
2073
|
const silent = options.silent ?? false;
|
|
2071
2074
|
const targetArgs = options.targetArgs ?? [];
|
|
2075
|
+
const commandEnv = options.commandEnv;
|
|
2072
2076
|
const runCommand = deps.runCommand ?? defaultRunCommand;
|
|
2073
2077
|
const secretGenerator = deps.secretGenerator ?? defaultSecretGenerator;
|
|
2074
2078
|
const envPath = path.join(cwd, "convex", ".env");
|
|
@@ -2096,7 +2100,7 @@ async function pushEnv(options = {}, deps = {}) {
|
|
|
2096
2100
|
envFilePath: tempEnvPath,
|
|
2097
2101
|
force,
|
|
2098
2102
|
targetArgs
|
|
2099
|
-
}));
|
|
2103
|
+
}), commandEnv);
|
|
2100
2104
|
return true;
|
|
2101
2105
|
} finally {
|
|
2102
2106
|
fs.rmSync(tempDir, {
|
|
@@ -2144,14 +2148,14 @@ async function pushEnv(options = {}, deps = {}) {
|
|
|
2144
2148
|
"run",
|
|
2145
2149
|
AUTH_ROTATE_KEYS_FUNCTION,
|
|
2146
2150
|
...targetArgs
|
|
2147
|
-
]);
|
|
2151
|
+
], commandEnv);
|
|
2148
2152
|
if (!silent) logger.info("Rotated auth keys.");
|
|
2149
2153
|
}
|
|
2150
2154
|
nextVars.JWKS = parseConvexRunValue((await runConvexCommand(runCommand, cwd, [
|
|
2151
2155
|
"run",
|
|
2152
2156
|
AUTH_JWKS_FUNCTION,
|
|
2153
2157
|
...targetArgs
|
|
2154
|
-
])).stdout);
|
|
2158
|
+
], commandEnv)).stdout);
|
|
2155
2159
|
await finalizePush();
|
|
2156
2160
|
return;
|
|
2157
2161
|
}
|
|
@@ -2169,23 +2173,26 @@ async function pushEnv(options = {}, deps = {}) {
|
|
|
2169
2173
|
"run",
|
|
2170
2174
|
AUTH_ROTATE_KEYS_FUNCTION,
|
|
2171
2175
|
...targetArgs
|
|
2172
|
-
]);
|
|
2176
|
+
], commandEnv);
|
|
2173
2177
|
if (!silent) logger.info("Rotated auth keys.");
|
|
2174
2178
|
}
|
|
2175
2179
|
nextVars.JWKS = parseConvexRunValue((await runConvexCommand(runCommand, cwd, [
|
|
2176
2180
|
"run",
|
|
2177
2181
|
AUTH_JWKS_FUNCTION,
|
|
2178
2182
|
...targetArgs
|
|
2179
|
-
])).stdout);
|
|
2183
|
+
], commandEnv)).stdout);
|
|
2180
2184
|
await finalizePush();
|
|
2181
2185
|
}
|
|
2182
2186
|
async function pullEnv(options = {}, deps = {}) {
|
|
2183
2187
|
const cwd = process.cwd();
|
|
2184
|
-
const
|
|
2188
|
+
const runCommand = deps.runCommand ?? defaultRunCommand;
|
|
2189
|
+
const targetArgs = options.targetArgs ?? [];
|
|
2190
|
+
const commandEnv = options.commandEnv;
|
|
2191
|
+
const result = await runConvexCommand(runCommand, cwd, [
|
|
2185
2192
|
"env",
|
|
2186
2193
|
"list",
|
|
2187
|
-
...
|
|
2188
|
-
]);
|
|
2194
|
+
...targetArgs
|
|
2195
|
+
], commandEnv);
|
|
2189
2196
|
if (options.outFilePath) {
|
|
2190
2197
|
const outputPath = path.resolve(cwd, options.outFilePath);
|
|
2191
2198
|
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
@@ -9206,6 +9213,7 @@ const CONVEX_DEPLOYMENT_ENV_KEYS = [
|
|
|
9206
9213
|
"CONVEX_SELF_HOSTED_URL",
|
|
9207
9214
|
"CONVEX_SELF_HOSTED_ADMIN_KEY"
|
|
9208
9215
|
];
|
|
9216
|
+
const LOCAL_CONVEX_DEPLOYMENT_PREFIXES = ["local:", "anonymous:"];
|
|
9209
9217
|
function createBackendCommandEnv(overrides) {
|
|
9210
9218
|
const clearedDeploymentEnv = Object.fromEntries(CONVEX_DEPLOYMENT_ENV_KEYS.map((key) => [key, void 0]));
|
|
9211
9219
|
return {
|
|
@@ -9214,6 +9222,26 @@ function createBackendCommandEnv(overrides) {
|
|
|
9214
9222
|
...overrides
|
|
9215
9223
|
};
|
|
9216
9224
|
}
|
|
9225
|
+
function hasRemoteConvexDeploymentEnv(env) {
|
|
9226
|
+
const deployment = env.CONVEX_DEPLOYMENT?.trim();
|
|
9227
|
+
if (deployment && !LOCAL_CONVEX_DEPLOYMENT_PREFIXES.some((prefix) => deployment.startsWith(prefix))) return true;
|
|
9228
|
+
return Boolean(env.CONVEX_DEPLOY_KEY?.trim() || env.CONVEX_SELF_HOSTED_URL?.trim() || env.CONVEX_SELF_HOSTED_ADMIN_KEY?.trim());
|
|
9229
|
+
}
|
|
9230
|
+
function readConvexTargetEnvFile(args, cwd = process.cwd()) {
|
|
9231
|
+
const envFile = readOptionalCliFlagValue(args, "--env-file");
|
|
9232
|
+
if (!envFile) return null;
|
|
9233
|
+
const envFilePath = resolve(cwd, envFile);
|
|
9234
|
+
if (!fs.existsSync(envFilePath)) return null;
|
|
9235
|
+
return parse(fs.readFileSync(envFilePath, "utf8"));
|
|
9236
|
+
}
|
|
9237
|
+
function resolveRemoteConvexDeploymentKey(env) {
|
|
9238
|
+
if (!hasRemoteConvexDeploymentEnv(env)) return null;
|
|
9239
|
+
const deployment = env.CONVEX_DEPLOYMENT?.trim();
|
|
9240
|
+
if (deployment) return `deployment-env:${deployment}`;
|
|
9241
|
+
const selfHostedUrl = env.CONVEX_SELF_HOSTED_URL?.trim();
|
|
9242
|
+
if (selfHostedUrl) return `self-hosted-env:${selfHostedUrl}`;
|
|
9243
|
+
return "remote-env";
|
|
9244
|
+
}
|
|
9217
9245
|
async function withLocalConvexEnv(sharedDir, fn) {
|
|
9218
9246
|
const { functionsDir } = getConvexConfig(sharedDir);
|
|
9219
9247
|
const envPath = join(functionsDir, "..", ".env");
|
|
@@ -10612,12 +10640,19 @@ function writeAggregateFingerprintState(statePath, state) {
|
|
|
10612
10640
|
fs.writeFileSync(tmpPath, JSON.stringify(state, null, 2));
|
|
10613
10641
|
fs.renameSync(tmpPath, statePath);
|
|
10614
10642
|
}
|
|
10615
|
-
function getAggregateBackfillDeploymentKey(args) {
|
|
10643
|
+
function getAggregateBackfillDeploymentKey(args, cwd = process.cwd(), env) {
|
|
10616
10644
|
if (args.includes("--prod")) return "prod";
|
|
10617
10645
|
const deploymentName = readOptionalCliFlagValue(args, "--deployment-name");
|
|
10618
10646
|
if (deploymentName) return `deployment:${deploymentName}`;
|
|
10619
10647
|
const previewName = readOptionalCliFlagValue(args, "--preview-name");
|
|
10620
10648
|
if (previewName) return `preview:${previewName}`;
|
|
10649
|
+
const envKey = env ? resolveRemoteConvexDeploymentKey(env) : null;
|
|
10650
|
+
if (envKey) return envKey;
|
|
10651
|
+
const envFileVars = readConvexTargetEnvFile(args, cwd);
|
|
10652
|
+
if (envFileVars) {
|
|
10653
|
+
const envFileKey = resolveRemoteConvexDeploymentKey(envFileVars);
|
|
10654
|
+
if (envFileKey) return envFileKey;
|
|
10655
|
+
}
|
|
10621
10656
|
return "local";
|
|
10622
10657
|
}
|
|
10623
10658
|
function ensureConvexGitignoreEntry(cwd = process.cwd()) {
|
|
@@ -10825,9 +10860,6 @@ function buildCodegenBootstrapArgs(targetArgs) {
|
|
|
10825
10860
|
function didConvexInitCreateConfiguration(output) {
|
|
10826
10861
|
return CONVEX_INIT_CREATED_CONFIG_RE.test(output);
|
|
10827
10862
|
}
|
|
10828
|
-
function hasRemoteConvexInitTargetArgs(targetArgs) {
|
|
10829
|
-
return targetArgs?.some((arg) => arg === "--prod" || arg === "--preview-name" || arg === "--deployment-name") ?? false;
|
|
10830
|
-
}
|
|
10831
10863
|
async function runConvexInitIfNeeded(params) {
|
|
10832
10864
|
if (params.backendAdapter.publicName !== "convex") return {
|
|
10833
10865
|
created: false,
|
|
@@ -10835,7 +10867,7 @@ async function runConvexInitIfNeeded(params) {
|
|
|
10835
10867
|
stdout: "",
|
|
10836
10868
|
stderr: ""
|
|
10837
10869
|
};
|
|
10838
|
-
const agentModeOverride = params.yes &&
|
|
10870
|
+
const agentModeOverride = params.yes && getAggregateBackfillDeploymentKey(params.targetArgs ?? [], process.cwd(), params.env) === "local" ? "anonymous" : params.env?.CONVEX_AGENT_MODE;
|
|
10839
10871
|
const result = normalizeConvexCommandResult(await params.execaFn(params.backendAdapter.command, [
|
|
10840
10872
|
...params.backendAdapter.argsPrefix,
|
|
10841
10873
|
"init",
|
|
@@ -11449,7 +11481,7 @@ async function runBackendFunction(execaFn, backendAdapter, functionName, args, t
|
|
|
11449
11481
|
JSON.stringify(args)
|
|
11450
11482
|
], {
|
|
11451
11483
|
cwd: process.cwd(),
|
|
11452
|
-
env: createBackendCommandEnv(),
|
|
11484
|
+
env: createBackendCommandEnv(options?.env),
|
|
11453
11485
|
reject: false,
|
|
11454
11486
|
stdio: "pipe"
|
|
11455
11487
|
});
|
|
@@ -11466,13 +11498,16 @@ async function runBackendFunction(execaFn, backendAdapter, functionName, args, t
|
|
|
11466
11498
|
};
|
|
11467
11499
|
}
|
|
11468
11500
|
async function runAggregateBackfillFlow(params) {
|
|
11469
|
-
const { execaFn, backendAdapter, backfillConfig, mode, targetArgs, signal, context } = params;
|
|
11501
|
+
const { execaFn, backendAdapter, backfillConfig, mode, targetArgs, env, signal, context } = params;
|
|
11470
11502
|
if (signal?.aborted) return 0;
|
|
11471
11503
|
if (backfillConfig.enabled === "off") return 0;
|
|
11472
11504
|
const kickoff = await runBackendFunction(execaFn, backendAdapter, "generated/server:aggregateBackfill", {
|
|
11473
11505
|
mode,
|
|
11474
11506
|
batchSize: backfillConfig.batchSize
|
|
11475
|
-
}, targetArgs, {
|
|
11507
|
+
}, targetArgs, {
|
|
11508
|
+
echoOutput: false,
|
|
11509
|
+
env
|
|
11510
|
+
});
|
|
11476
11511
|
if (kickoff.exitCode !== 0) {
|
|
11477
11512
|
const combinedOutput = `${kickoff.stdout}\n${kickoff.stderr}`;
|
|
11478
11513
|
if (backfillConfig.enabled === "auto" && isMissingBackfillFunctionOutput(combinedOutput)) {
|
|
@@ -11499,7 +11534,10 @@ async function runAggregateBackfillFlow(params) {
|
|
|
11499
11534
|
const deadline = Date.now() + backfillConfig.timeoutMs;
|
|
11500
11535
|
let lastProgress = "";
|
|
11501
11536
|
while (!signal?.aborted) {
|
|
11502
|
-
const statusResult = await runBackendFunction(execaFn, backendAdapter, "generated/server:aggregateBackfillStatus", {}, targetArgs, {
|
|
11537
|
+
const statusResult = await runBackendFunction(execaFn, backendAdapter, "generated/server:aggregateBackfillStatus", {}, targetArgs, {
|
|
11538
|
+
echoOutput: false,
|
|
11539
|
+
env
|
|
11540
|
+
});
|
|
11503
11541
|
if (statusResult.exitCode !== 0) return statusResult.exitCode;
|
|
11504
11542
|
const statuses = parseBackendRunJson(statusResult.stdout);
|
|
11505
11543
|
const failed = statuses.find((entry) => Boolean(entry.lastError));
|
|
@@ -11634,7 +11672,7 @@ export const migration = defineMigration({
|
|
|
11634
11672
|
logger.info(`manifest: ${manifestFile}`);
|
|
11635
11673
|
}
|
|
11636
11674
|
async function runMigrationFlow(params) {
|
|
11637
|
-
const { execaFn, backendAdapter, migrationConfig, targetArgs, signal, context, direction, steps, to } = params;
|
|
11675
|
+
const { execaFn, backendAdapter, migrationConfig, targetArgs, env, signal, context, direction, steps, to } = params;
|
|
11638
11676
|
if (signal?.aborted || migrationConfig.enabled === "off") return 0;
|
|
11639
11677
|
const kickoff = await runBackendFunction(execaFn, backendAdapter, "generated/server:migrationRun", {
|
|
11640
11678
|
direction,
|
|
@@ -11642,7 +11680,10 @@ async function runMigrationFlow(params) {
|
|
|
11642
11680
|
allowDrift: migrationConfig.allowDrift,
|
|
11643
11681
|
...steps !== void 0 ? { steps } : {},
|
|
11644
11682
|
...to !== void 0 ? { to } : {}
|
|
11645
|
-
}, targetArgs, {
|
|
11683
|
+
}, targetArgs, {
|
|
11684
|
+
echoOutput: false,
|
|
11685
|
+
env
|
|
11686
|
+
});
|
|
11646
11687
|
if (kickoff.exitCode !== 0) {
|
|
11647
11688
|
const combinedOutput = `${kickoff.stdout}\n${kickoff.stderr}`;
|
|
11648
11689
|
if (migrationConfig.enabled === "auto" && isMissingBackfillFunctionOutput(combinedOutput)) {
|
|
@@ -11677,7 +11718,10 @@ async function runMigrationFlow(params) {
|
|
|
11677
11718
|
const deadline = Date.now() + migrationConfig.timeoutMs;
|
|
11678
11719
|
let lastStatusLine = "";
|
|
11679
11720
|
while (!signal?.aborted) {
|
|
11680
|
-
const statusResult = await runBackendFunction(execaFn, backendAdapter, "generated/server:migrationStatus", { runId }, targetArgs, {
|
|
11721
|
+
const statusResult = await runBackendFunction(execaFn, backendAdapter, "generated/server:migrationStatus", { runId }, targetArgs, {
|
|
11722
|
+
echoOutput: false,
|
|
11723
|
+
env
|
|
11724
|
+
});
|
|
11681
11725
|
if (statusResult.exitCode !== 0) return statusResult.exitCode;
|
|
11682
11726
|
const statusPayload = parseBackendRunJson(statusResult.stdout);
|
|
11683
11727
|
const runStatus = typeof statusPayload === "object" && statusPayload !== null && !Array.isArray(statusPayload) ? statusPayload.activeRun?.status ?? statusPayload.runs?.[0]?.status ?? "unknown" : "unknown";
|
|
@@ -11712,10 +11756,10 @@ async function runMigrationFlow(params) {
|
|
|
11712
11756
|
return 0;
|
|
11713
11757
|
}
|
|
11714
11758
|
async function runDevSchemaBackfillIfNeeded(params) {
|
|
11715
|
-
const { execaFn, backendAdapter, backfillConfig, functionsDir, targetArgs, signal } = params;
|
|
11759
|
+
const { execaFn, backendAdapter, backfillConfig, functionsDir, targetArgs, env, signal } = params;
|
|
11716
11760
|
const fingerprint = await computeAggregateIndexFingerprint(functionsDir);
|
|
11717
11761
|
if (!fingerprint) return 0;
|
|
11718
|
-
const deploymentKey = getAggregateBackfillDeploymentKey(targetArgs);
|
|
11762
|
+
const deploymentKey = getAggregateBackfillDeploymentKey(targetArgs, process.cwd(), env);
|
|
11719
11763
|
const statePath = getDevAggregateBackfillStatePath();
|
|
11720
11764
|
const state = readAggregateFingerprintState(statePath);
|
|
11721
11765
|
if (state.entries[deploymentKey]?.fingerprint === fingerprint) return 0;
|
|
@@ -11729,6 +11773,7 @@ async function runDevSchemaBackfillIfNeeded(params) {
|
|
|
11729
11773
|
},
|
|
11730
11774
|
mode: "resume",
|
|
11731
11775
|
targetArgs,
|
|
11776
|
+
env,
|
|
11732
11777
|
signal,
|
|
11733
11778
|
context: "dev"
|
|
11734
11779
|
});
|
|
@@ -12087,6 +12132,59 @@ function resolveConcaveLocalSiteUrl(cwd = process.cwd()) {
|
|
|
12087
12132
|
const parsed = parseEnv(fs.readFileSync(envLocalPath, "utf8"));
|
|
12088
12133
|
return parsed.NEXT_PUBLIC_SITE_URL ?? parsed.VITE_SITE_URL ?? "http://localhost:3000";
|
|
12089
12134
|
}
|
|
12135
|
+
function resolveImplicitConvexRemoteDeploymentEnv(cwd = process.cwd()) {
|
|
12136
|
+
const envLocalPath = join(cwd, ".env.local");
|
|
12137
|
+
if (!fs.existsSync(envLocalPath)) return null;
|
|
12138
|
+
const parsed = parseEnv(fs.readFileSync(envLocalPath, "utf8"));
|
|
12139
|
+
if (!hasRemoteConvexDeploymentEnv(parsed)) return null;
|
|
12140
|
+
return {
|
|
12141
|
+
CONVEX_DEPLOYMENT: parsed.CONVEX_DEPLOYMENT,
|
|
12142
|
+
CONVEX_DEPLOY_KEY: parsed.CONVEX_DEPLOY_KEY,
|
|
12143
|
+
CONVEX_SELF_HOSTED_URL: parsed.CONVEX_SELF_HOSTED_URL,
|
|
12144
|
+
CONVEX_SELF_HOSTED_ADMIN_KEY: parsed.CONVEX_SELF_HOSTED_ADMIN_KEY
|
|
12145
|
+
};
|
|
12146
|
+
}
|
|
12147
|
+
function resolveConvexEnvFileCommandEnv(args, cwd = process.cwd()) {
|
|
12148
|
+
let envFilePath = null;
|
|
12149
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
12150
|
+
const arg = args[i];
|
|
12151
|
+
if (arg === "--env-file") {
|
|
12152
|
+
envFilePath = args[i + 1] ?? null;
|
|
12153
|
+
break;
|
|
12154
|
+
}
|
|
12155
|
+
if (arg.startsWith("--env-file=")) {
|
|
12156
|
+
envFilePath = arg.slice(11) || null;
|
|
12157
|
+
break;
|
|
12158
|
+
}
|
|
12159
|
+
}
|
|
12160
|
+
if (!envFilePath) return null;
|
|
12161
|
+
const resolvedPath = resolve(cwd, envFilePath);
|
|
12162
|
+
if (!fs.existsSync(resolvedPath)) return null;
|
|
12163
|
+
const parsed = parseEnv(fs.readFileSync(resolvedPath, "utf8"));
|
|
12164
|
+
return {
|
|
12165
|
+
CONVEX_DEPLOYMENT: parsed.CONVEX_DEPLOYMENT,
|
|
12166
|
+
CONVEX_DEPLOY_KEY: parsed.CONVEX_DEPLOY_KEY,
|
|
12167
|
+
CONVEX_SELF_HOSTED_URL: parsed.CONVEX_SELF_HOSTED_URL,
|
|
12168
|
+
CONVEX_SELF_HOSTED_ADMIN_KEY: parsed.CONVEX_SELF_HOSTED_ADMIN_KEY
|
|
12169
|
+
};
|
|
12170
|
+
}
|
|
12171
|
+
function stripConvexEnvFileTargetArgs(args) {
|
|
12172
|
+
const nextArgs = [];
|
|
12173
|
+
let skipNext = false;
|
|
12174
|
+
for (const arg of args) {
|
|
12175
|
+
if (skipNext) {
|
|
12176
|
+
skipNext = false;
|
|
12177
|
+
continue;
|
|
12178
|
+
}
|
|
12179
|
+
if (arg === "--env-file") {
|
|
12180
|
+
skipNext = true;
|
|
12181
|
+
continue;
|
|
12182
|
+
}
|
|
12183
|
+
if (arg.startsWith("--env-file=")) continue;
|
|
12184
|
+
nextArgs.push(arg);
|
|
12185
|
+
}
|
|
12186
|
+
return nextArgs;
|
|
12187
|
+
}
|
|
12090
12188
|
const resolveWatcherCommand = (currentFilename = __filename$1, currentDir = __dirname) => {
|
|
12091
12189
|
const isTs = currentFilename.endsWith(".ts");
|
|
12092
12190
|
return {
|
|
@@ -12265,6 +12363,10 @@ const handleDevCommand = async (argv, deps) => {
|
|
|
12265
12363
|
const debug = parsed.debug || config.dev.debug;
|
|
12266
12364
|
assertNoRemovedDevPreRunFlag(config.dev.args);
|
|
12267
12365
|
const { bootstrap, remainingArgs: convexDevArgs } = extractDevBootstrapCliFlag([...config.dev.args, ...devCommandArgs]);
|
|
12366
|
+
const explicitConvexTargetArgs = extractBackendRunTargetArgs("convex", convexDevArgs);
|
|
12367
|
+
const explicitConvexCommandEnv = resolveConvexEnvFileCommandEnv(convexDevArgs);
|
|
12368
|
+
const implicitConvexCommandEnv = backend === "convex" && explicitConvexTargetArgs.length === 0 && explicitConvexCommandEnv === null ? resolveImplicitConvexRemoteDeploymentEnv() : null;
|
|
12369
|
+
const effectiveConvexCommandEnv = explicitConvexCommandEnv ?? implicitConvexCommandEnv;
|
|
12268
12370
|
const preRunFunction = config.dev.preRun;
|
|
12269
12371
|
if (bootstrap && backend !== "convex") throw new Error("`kitcn dev --bootstrap` is only supported for backend convex.");
|
|
12270
12372
|
if (preRunFunction && backend === "concave") throw new Error("`dev.preRun` is only supported for backend convex. Concave dev has no equivalent `--run` flow.");
|
|
@@ -12281,10 +12383,10 @@ const handleDevCommand = async (argv, deps) => {
|
|
|
12281
12383
|
const concaveLocalDevContract = backend === "concave" ? resolveConcaveLocalDevContract(convexDevArgs, (deps?.resolveConcaveLocalSiteUrl ?? resolveConcaveLocalSiteUrl)(process.cwd())) : null;
|
|
12282
12384
|
const backendDevArgs = concaveLocalDevContract?.backendArgs ?? applyConvexDevPreRunArgs(convexDevArgs, preRunFunction);
|
|
12283
12385
|
const backendOutputMode = debug || backend === "convex" && !hasDevArg(backendDevArgs, "--once") ? "raw" : "filtered";
|
|
12284
|
-
const targetArgs = concaveLocalDevContract?.targetArgs ?? extractBackendRunTargetArgs(backend, convexDevArgs);
|
|
12386
|
+
const targetArgs = concaveLocalDevContract?.targetArgs ?? stripConvexEnvFileTargetArgs(extractBackendRunTargetArgs(backend, convexDevArgs));
|
|
12285
12387
|
const trimSegments = resolveCodegenTrimSegments(config);
|
|
12286
12388
|
const localNodeEnvOverrides = backend === "convex" ? await resolveSupportedLocalNodeEnvOverridesFn({ execaFn }) : {};
|
|
12287
|
-
if (!bootstrap && backend === "convex" && !debug) logger.info("Bootstrapping local Convex...");
|
|
12389
|
+
if (!bootstrap && backend === "convex" && !debug && getAggregateBackfillDeploymentKey(targetArgs, process.cwd(), effectiveConvexCommandEnv ?? void 0) === "local") logger.info("Bootstrapping local Convex...");
|
|
12288
12390
|
if (bootstrap) return runLocalConvexBootstrap({
|
|
12289
12391
|
authSyncMode: "complete",
|
|
12290
12392
|
config,
|
|
@@ -12307,7 +12409,10 @@ const handleDevCommand = async (argv, deps) => {
|
|
|
12307
12409
|
execaFn,
|
|
12308
12410
|
backendAdapter,
|
|
12309
12411
|
echoOutput: false,
|
|
12310
|
-
env:
|
|
12412
|
+
env: {
|
|
12413
|
+
...localNodeEnvOverrides,
|
|
12414
|
+
...effectiveConvexCommandEnv
|
|
12415
|
+
},
|
|
12311
12416
|
targetArgs
|
|
12312
12417
|
});
|
|
12313
12418
|
if (convexInitResult.exitCode !== 0) return convexInitResult.exitCode;
|
|
@@ -12318,6 +12423,7 @@ const handleDevCommand = async (argv, deps) => {
|
|
|
12318
12423
|
});
|
|
12319
12424
|
if (backend === "convex" && (fs.existsSync(localConvexEnvPath) || authEnvState.installed)) await syncEnvFn({
|
|
12320
12425
|
authSyncMode: authEnvState.installed ? "prepare" : "skip",
|
|
12426
|
+
commandEnv: effectiveConvexCommandEnv ?? void 0,
|
|
12321
12427
|
force: true,
|
|
12322
12428
|
sharedDir,
|
|
12323
12429
|
silent: true,
|
|
@@ -12353,6 +12459,7 @@ const handleDevCommand = async (argv, deps) => {
|
|
|
12353
12459
|
cwd: process.cwd(),
|
|
12354
12460
|
env: createBackendCommandEnv({
|
|
12355
12461
|
...localNodeEnvOverrides,
|
|
12462
|
+
...effectiveConvexCommandEnv,
|
|
12356
12463
|
...concaveLocalDevContract?.backendEnv
|
|
12357
12464
|
}),
|
|
12358
12465
|
reject: false
|
|
@@ -12366,6 +12473,7 @@ const handleDevCommand = async (argv, deps) => {
|
|
|
12366
12473
|
signal: backfillAbortController.signal,
|
|
12367
12474
|
runTask: () => syncEnvFn({
|
|
12368
12475
|
authSyncMode: "complete",
|
|
12476
|
+
commandEnv: effectiveConvexCommandEnv ?? void 0,
|
|
12369
12477
|
force: true,
|
|
12370
12478
|
sharedDir,
|
|
12371
12479
|
silent: true,
|
|
@@ -12388,6 +12496,7 @@ const handleDevCommand = async (argv, deps) => {
|
|
|
12388
12496
|
backendAdapter,
|
|
12389
12497
|
backfillConfig: devBackfillConfig,
|
|
12390
12498
|
functionsDir,
|
|
12499
|
+
env: effectiveConvexCommandEnv ?? void 0,
|
|
12391
12500
|
targetArgs,
|
|
12392
12501
|
signal: backfillAbortController.signal
|
|
12393
12502
|
}) !== 0 && !backfillAbortController.signal.aborted) logger.warn("⚠️ aggregateBackfill on schema update failed in dev (continuing without blocking).");
|
|
@@ -12415,6 +12524,7 @@ const handleDevCommand = async (argv, deps) => {
|
|
|
12415
12524
|
await authEnvSyncPromise;
|
|
12416
12525
|
await syncEnvFn({
|
|
12417
12526
|
authSyncMode: "auto",
|
|
12527
|
+
commandEnv: effectiveConvexCommandEnv ?? void 0,
|
|
12418
12528
|
force: true,
|
|
12419
12529
|
sharedDir,
|
|
12420
12530
|
silent: true,
|
|
@@ -12442,6 +12552,7 @@ const handleDevCommand = async (argv, deps) => {
|
|
|
12442
12552
|
runTask: () => runMigrationFlow({
|
|
12443
12553
|
execaFn,
|
|
12444
12554
|
backendAdapter,
|
|
12555
|
+
env: effectiveConvexCommandEnv ?? void 0,
|
|
12445
12556
|
migrationConfig: devMigrationConfig,
|
|
12446
12557
|
targetArgs,
|
|
12447
12558
|
signal: backfillAbortController.signal,
|
|
@@ -12464,6 +12575,7 @@ const handleDevCommand = async (argv, deps) => {
|
|
|
12464
12575
|
execaFn,
|
|
12465
12576
|
backendAdapter,
|
|
12466
12577
|
backfillConfig: devBackfillConfig,
|
|
12578
|
+
env: effectiveConvexCommandEnv ?? void 0,
|
|
12467
12579
|
mode: "resume",
|
|
12468
12580
|
targetArgs,
|
|
12469
12581
|
signal: backfillAbortController.signal,
|
package/dist/react/index.d.ts
CHANGED
|
@@ -350,7 +350,7 @@ declare class ConvexQueryClient {
|
|
|
350
350
|
subscriptions: Record<string, {
|
|
351
351
|
watch: Watch<unknown>;
|
|
352
352
|
unsubscribe: () => void;
|
|
353
|
-
queryKey:
|
|
353
|
+
queryKey: QueryKey;
|
|
354
354
|
}>;
|
|
355
355
|
/** Cleanup function for QueryCache subscription */
|
|
356
356
|
unsubscribe: (() => void) | undefined;
|
|
@@ -377,6 +377,9 @@ declare class ConvexQueryClient {
|
|
|
377
377
|
private cancelPendingUnsubscribe;
|
|
378
378
|
/** Unsubscribe a live Convex watch (if present) and remove it from the subscription map. */
|
|
379
379
|
private unsubscribeQueryByHash;
|
|
380
|
+
private isAuthBoundQuery;
|
|
381
|
+
private isQueryDisabled;
|
|
382
|
+
private subscribeQuery;
|
|
380
383
|
/** Update auth store (for HMR where jotai store may reset) */
|
|
381
384
|
updateAuthStore(authStore?: AuthStore): void;
|
|
382
385
|
/** Get current auth state from store */
|
|
@@ -411,6 +414,7 @@ declare class ConvexQueryClient {
|
|
|
411
414
|
* Call before logout to prevent UNAUTHORIZED errors during session invalidation.
|
|
412
415
|
*/
|
|
413
416
|
unsubscribeAuthQueries(): void;
|
|
417
|
+
resetAuthQueries(): Promise<void>;
|
|
414
418
|
/**
|
|
415
419
|
* Batch update all subscriptions.
|
|
416
420
|
* Called internally when Convex client reconnects.
|
package/dist/react/index.js
CHANGED
|
@@ -1185,7 +1185,24 @@ function createCRPCContext(options) {
|
|
|
1185
1185
|
/** Inner provider */
|
|
1186
1186
|
function CRPCProviderInner({ children, convexClient, convexQueryClient }) {
|
|
1187
1187
|
const authStore = useAuthStore();
|
|
1188
|
+
const token = useAuthValue("token");
|
|
1189
|
+
const isAuthenticated = useAuthValue("isAuthenticated");
|
|
1190
|
+
const previousAuthRef = useRef(null);
|
|
1188
1191
|
const fetchAccessToken = useFetchAccessToken();
|
|
1192
|
+
useEffect(() => {
|
|
1193
|
+
const previous = previousAuthRef.current;
|
|
1194
|
+
const tokenReady = token === null || decodeJwtExp(token) !== null;
|
|
1195
|
+
previousAuthRef.current = {
|
|
1196
|
+
isAuthenticated,
|
|
1197
|
+
token
|
|
1198
|
+
};
|
|
1199
|
+
if (!previous) return;
|
|
1200
|
+
if (tokenReady && (previous.token !== token || previous.isAuthenticated !== isAuthenticated)) convexQueryClient.resetAuthQueries();
|
|
1201
|
+
}, [
|
|
1202
|
+
convexQueryClient,
|
|
1203
|
+
isAuthenticated,
|
|
1204
|
+
token
|
|
1205
|
+
]);
|
|
1189
1206
|
const httpProxy = useMemo(() => {
|
|
1190
1207
|
if (!httpOptions.convexSiteUrl || !meta._http) return;
|
|
1191
1208
|
return createHttpProxy({
|
|
@@ -1438,12 +1455,14 @@ function createAuthMutations(authClient) {
|
|
|
1438
1455
|
authStoreApi.set("token", null);
|
|
1439
1456
|
authStoreApi.set("expiresAt", null);
|
|
1440
1457
|
authStoreApi.set("sessionSyncGraceUntil", null);
|
|
1458
|
+
await convexQueryClient?.resetAuthQueries();
|
|
1441
1459
|
return res;
|
|
1442
1460
|
}
|
|
1443
1461
|
};
|
|
1444
1462
|
});
|
|
1445
1463
|
const useSignInSocialMutationOptions = ((options) => {
|
|
1446
1464
|
const authStoreApi = useAuthStore();
|
|
1465
|
+
const convexQueryClient = useConvexQueryClient();
|
|
1447
1466
|
return {
|
|
1448
1467
|
...options,
|
|
1449
1468
|
mutationFn: async (args) => {
|
|
@@ -1452,12 +1471,15 @@ function createAuthMutations(authClient) {
|
|
|
1452
1471
|
seedReturnedToken(authStoreApi, res);
|
|
1453
1472
|
await hydrateReturnedSession(authClient, res);
|
|
1454
1473
|
await ensureAuth(authStoreApi);
|
|
1474
|
+
authStoreApi.set("isAuthenticated", true);
|
|
1475
|
+
await convexQueryClient?.resetAuthQueries();
|
|
1455
1476
|
return res;
|
|
1456
1477
|
}
|
|
1457
1478
|
};
|
|
1458
1479
|
});
|
|
1459
1480
|
const useSignInMutationOptions = ((options) => {
|
|
1460
1481
|
const authStoreApi = useAuthStore();
|
|
1482
|
+
const convexQueryClient = useConvexQueryClient();
|
|
1461
1483
|
return {
|
|
1462
1484
|
...options,
|
|
1463
1485
|
mutationFn: async (args) => {
|
|
@@ -1466,12 +1488,15 @@ function createAuthMutations(authClient) {
|
|
|
1466
1488
|
seedReturnedToken(authStoreApi, res);
|
|
1467
1489
|
await hydrateReturnedSession(authClient, res);
|
|
1468
1490
|
await ensureAuth(authStoreApi);
|
|
1491
|
+
authStoreApi.set("isAuthenticated", true);
|
|
1492
|
+
await convexQueryClient?.resetAuthQueries();
|
|
1469
1493
|
return res;
|
|
1470
1494
|
}
|
|
1471
1495
|
};
|
|
1472
1496
|
});
|
|
1473
1497
|
const useSignUpMutationOptions = ((options) => {
|
|
1474
1498
|
const authStoreApi = useAuthStore();
|
|
1499
|
+
const convexQueryClient = useConvexQueryClient();
|
|
1475
1500
|
return {
|
|
1476
1501
|
...options,
|
|
1477
1502
|
mutationFn: async (args) => {
|
|
@@ -1480,6 +1505,8 @@ function createAuthMutations(authClient) {
|
|
|
1480
1505
|
seedReturnedToken(authStoreApi, res);
|
|
1481
1506
|
await hydrateReturnedSession(authClient, res);
|
|
1482
1507
|
await ensureAuth(authStoreApi);
|
|
1508
|
+
authStoreApi.set("isAuthenticated", true);
|
|
1509
|
+
await convexQueryClient?.resetAuthQueries();
|
|
1483
1510
|
return res;
|
|
1484
1511
|
}
|
|
1485
1512
|
};
|
|
@@ -1701,6 +1728,31 @@ var ConvexQueryClient = class {
|
|
|
1701
1728
|
sub.unsubscribe();
|
|
1702
1729
|
delete this.subscriptions[queryHash];
|
|
1703
1730
|
}
|
|
1731
|
+
isAuthBoundQuery(query) {
|
|
1732
|
+
const meta = query.meta;
|
|
1733
|
+
return meta?.authType === "required" || meta?.authType === "optional";
|
|
1734
|
+
}
|
|
1735
|
+
isQueryDisabled(query) {
|
|
1736
|
+
return query.isDisabled();
|
|
1737
|
+
}
|
|
1738
|
+
subscribeQuery(query) {
|
|
1739
|
+
if (this.subscriptions[query.queryHash]) return;
|
|
1740
|
+
const meta = query.meta;
|
|
1741
|
+
if (meta?.subscribe === false) return;
|
|
1742
|
+
if (query.getObserversCount() === 0) return;
|
|
1743
|
+
if (this.isQueryDisabled(query)) return;
|
|
1744
|
+
if (this.shouldSkipSubscription(meta?.authType)) return;
|
|
1745
|
+
const [, funcName, args] = query.queryKey;
|
|
1746
|
+
const watch = this.convexClient.watchQuery(funcName, this.transformer.input.serialize(args));
|
|
1747
|
+
const unsubscribe = watch.onUpdate(() => {
|
|
1748
|
+
this.onUpdateQueryKeyHash(query.queryHash);
|
|
1749
|
+
});
|
|
1750
|
+
this.subscriptions[query.queryHash] = {
|
|
1751
|
+
queryKey: query.queryKey,
|
|
1752
|
+
watch,
|
|
1753
|
+
unsubscribe
|
|
1754
|
+
};
|
|
1755
|
+
}
|
|
1704
1756
|
/** Update auth store (for HMR where jotai store may reset) */
|
|
1705
1757
|
updateAuthStore(authStore) {
|
|
1706
1758
|
this.authStore = authStore;
|
|
@@ -1783,6 +1835,15 @@ var ConvexQueryClient = class {
|
|
|
1783
1835
|
this.unsubscribeQueryByHash(queryHash);
|
|
1784
1836
|
}
|
|
1785
1837
|
}
|
|
1838
|
+
async resetAuthQueries() {
|
|
1839
|
+
const authQueries = this.queryClient.getQueryCache().getAll().filter((query) => this.isAuthBoundQuery(query));
|
|
1840
|
+
for (const query of authQueries) {
|
|
1841
|
+
this.cancelPendingUnsubscribe(query.queryHash);
|
|
1842
|
+
this.unsubscribeQueryByHash(query.queryHash);
|
|
1843
|
+
}
|
|
1844
|
+
await this.queryClient.resetQueries({ predicate: (query) => this.isAuthBoundQuery(query) });
|
|
1845
|
+
for (const query of this.queryClient.getQueryCache().getAll()) if (this.isAuthBoundQuery(query)) this.subscribeQuery(query);
|
|
1846
|
+
}
|
|
1786
1847
|
/**
|
|
1787
1848
|
* Batch update all subscriptions.
|
|
1788
1849
|
* Called internally when Convex client reconnects.
|
|
@@ -1860,42 +1921,13 @@ var ConvexQueryClient = class {
|
|
|
1860
1921
|
this.cancelPendingUnsubscribe(event.query.queryHash);
|
|
1861
1922
|
this.unsubscribeQueryByHash(event.query.queryHash);
|
|
1862
1923
|
break;
|
|
1863
|
-
case "added":
|
|
1864
|
-
|
|
1865
|
-
if (meta?.subscribe === false) break;
|
|
1866
|
-
const [, funcName, args] = event.query.queryKey;
|
|
1867
|
-
if (event.query.getObserversCount() === 0) break;
|
|
1868
|
-
if (this.shouldSkipSubscription(meta?.authType)) break;
|
|
1869
|
-
const watch = this.convexClient.watchQuery(funcName, this.transformer.input.serialize(args));
|
|
1870
|
-
const unsubscribe = watch.onUpdate(() => {
|
|
1871
|
-
this.onUpdateQueryKeyHash(event.query.queryHash);
|
|
1872
|
-
});
|
|
1873
|
-
this.subscriptions[event.query.queryHash] = {
|
|
1874
|
-
queryKey: event.query.queryKey,
|
|
1875
|
-
watch,
|
|
1876
|
-
unsubscribe
|
|
1877
|
-
};
|
|
1924
|
+
case "added":
|
|
1925
|
+
this.subscribeQuery(event.query);
|
|
1878
1926
|
break;
|
|
1879
|
-
|
|
1880
|
-
case "observerAdded": {
|
|
1927
|
+
case "observerAdded":
|
|
1881
1928
|
this.cancelPendingUnsubscribe(event.query.queryHash);
|
|
1882
|
-
|
|
1883
|
-
if (event.query.options.enabled === false) break;
|
|
1884
|
-
const meta = event.query.meta;
|
|
1885
|
-
if (meta?.subscribe === false) break;
|
|
1886
|
-
const [, funcName, args] = event.query.queryKey;
|
|
1887
|
-
if (this.shouldSkipSubscription(meta?.authType)) break;
|
|
1888
|
-
const watch = this.convexClient.watchQuery(funcName, this.transformer.input.serialize(args));
|
|
1889
|
-
const unsubscribe = watch.onUpdate(() => {
|
|
1890
|
-
this.onUpdateQueryKeyHash(event.query.queryHash);
|
|
1891
|
-
});
|
|
1892
|
-
this.subscriptions[event.query.queryHash] = {
|
|
1893
|
-
queryKey: event.query.queryKey,
|
|
1894
|
-
watch,
|
|
1895
|
-
unsubscribe
|
|
1896
|
-
};
|
|
1929
|
+
this.subscribeQuery(event.query);
|
|
1897
1930
|
break;
|
|
1898
|
-
}
|
|
1899
1931
|
case "observerRemoved":
|
|
1900
1932
|
if (event.query.getObserversCount() === 0 && this.subscriptions[event.query.queryHash]) {
|
|
1901
1933
|
const queryHash = event.query.queryHash;
|
|
@@ -1911,7 +1943,7 @@ var ConvexQueryClient = class {
|
|
|
1911
1943
|
if (event.action.type === "setState" && event.action.setStateOptions?.meta === "set by ConvexQueryClient") break;
|
|
1912
1944
|
break;
|
|
1913
1945
|
case "observerOptionsUpdated": {
|
|
1914
|
-
const isDisabled = event.query
|
|
1946
|
+
const isDisabled = this.isQueryDisabled(event.query);
|
|
1915
1947
|
const isSubscribed = !!this.subscriptions[event.query.queryHash];
|
|
1916
1948
|
if (isDisabled && isSubscribed) {
|
|
1917
1949
|
this.cancelPendingUnsubscribe(event.query.queryHash);
|
|
@@ -1919,19 +1951,7 @@ var ConvexQueryClient = class {
|
|
|
1919
1951
|
break;
|
|
1920
1952
|
}
|
|
1921
1953
|
if (isSubscribed || isDisabled) break;
|
|
1922
|
-
|
|
1923
|
-
if (meta?.subscribe === false) break;
|
|
1924
|
-
const [, funcName, args] = event.query.queryKey;
|
|
1925
|
-
if (this.shouldSkipSubscription(meta?.authType)) break;
|
|
1926
|
-
const watch = this.convexClient.watchQuery(funcName, this.transformer.input.serialize(args));
|
|
1927
|
-
const unsubscribe = watch.onUpdate(() => {
|
|
1928
|
-
this.onUpdateQueryKeyHash(event.query.queryHash);
|
|
1929
|
-
});
|
|
1930
|
-
this.subscriptions[event.query.queryHash] = {
|
|
1931
|
-
queryKey: event.query.queryKey,
|
|
1932
|
-
watch,
|
|
1933
|
-
unsubscribe
|
|
1934
|
-
};
|
|
1954
|
+
this.subscribeQuery(event.query);
|
|
1935
1955
|
break;
|
|
1936
1956
|
}
|
|
1937
1957
|
}
|