better-convex-nuxt 0.2.11 → 0.2.12
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/module.json +1 -1
- package/dist/runtime/composables/useConvexAuth.d.ts +27 -51
- package/dist/runtime/composables/useConvexAuth.js +1 -1
- package/dist/runtime/composables/useConvexQuery.js +79 -17
- package/dist/runtime/devtools/ui/dist/200.html +1 -1
- package/dist/runtime/devtools/ui/dist/404.html +1 -1
- package/dist/runtime/devtools/ui/dist/_nuxt/builds/latest.json +1 -1
- package/dist/runtime/devtools/ui/dist/_nuxt/builds/meta/a5e03a13-122d-4d8e-b569-24b5d8908506.json +1 -0
- package/dist/runtime/devtools/ui/dist/index.html +1 -1
- package/dist/runtime/utils/convex-cache.d.ts +20 -0
- package/dist/runtime/utils/convex-cache.js +16 -0
- package/dist/runtime/utils/convex-shared.js +9 -1
- package/package.json +1 -1
- package/dist/runtime/devtools/ui/dist/_nuxt/builds/meta/4441cf51-019c-4d8d-b387-2c168e8d08e3.json +0 -1
package/dist/module.json
CHANGED
|
@@ -1,4 +1,30 @@
|
|
|
1
|
+
import type { ConvexUser } from '../utils/types.js';
|
|
2
|
+
import type { createAuthClient } from 'better-auth/vue';
|
|
3
|
+
import type { ComputedRef, Ref } from 'vue';
|
|
1
4
|
export type { ConvexUser } from '../utils/types.js';
|
|
5
|
+
type AuthClient = ReturnType<typeof createAuthClient>;
|
|
6
|
+
export interface UseConvexAuthReturn {
|
|
7
|
+
/** The JWT token for Convex authentication (readonly) */
|
|
8
|
+
token: Readonly<Ref<string | null>>;
|
|
9
|
+
/** The authenticated user data (readonly) */
|
|
10
|
+
user: Readonly<Ref<ConvexUser | null>>;
|
|
11
|
+
/** Whether the user is authenticated */
|
|
12
|
+
isAuthenticated: ComputedRef<boolean>;
|
|
13
|
+
/** Whether an auth operation is pending */
|
|
14
|
+
isPending: Readonly<Ref<boolean>>;
|
|
15
|
+
/** Auth error message if authentication failed (e.g., 401/403) */
|
|
16
|
+
authError: Readonly<Ref<string | null>>;
|
|
17
|
+
/**
|
|
18
|
+
* Signs out the user from both Better Auth and Convex.
|
|
19
|
+
* Clears local state immediately and calls Better Auth's signOut().
|
|
20
|
+
*/
|
|
21
|
+
signOut: () => Promise<ReturnType<AuthClient['signOut']> extends Promise<infer T> ? T | null : null>;
|
|
22
|
+
/**
|
|
23
|
+
* Force refresh Convex auth state after login.
|
|
24
|
+
* Triggers fresh token fetch and updates reactive state.
|
|
25
|
+
*/
|
|
26
|
+
refreshAuth: () => Promise<void>;
|
|
27
|
+
}
|
|
2
28
|
/**
|
|
3
29
|
* Composable for accessing Convex authentication state.
|
|
4
30
|
*
|
|
@@ -30,54 +56,4 @@ export type { ConvexUser } from '../utils/types.js';
|
|
|
30
56
|
* </template>
|
|
31
57
|
* ```
|
|
32
58
|
*/
|
|
33
|
-
export declare function useConvexAuth():
|
|
34
|
-
/** The JWT token for Convex authentication (readonly) */
|
|
35
|
-
token: Readonly<import("vue").Ref<string | null, string | null>>;
|
|
36
|
-
/** The authenticated user data (readonly) */
|
|
37
|
-
user: Readonly<import("vue").Ref<{
|
|
38
|
-
readonly id: string;
|
|
39
|
-
readonly name: string;
|
|
40
|
-
readonly email: string;
|
|
41
|
-
readonly emailVerified?: boolean | undefined;
|
|
42
|
-
readonly image?: string | undefined;
|
|
43
|
-
readonly createdAt?: string | undefined;
|
|
44
|
-
readonly updatedAt?: string | undefined;
|
|
45
|
-
} | null, {
|
|
46
|
-
readonly id: string;
|
|
47
|
-
readonly name: string;
|
|
48
|
-
readonly email: string;
|
|
49
|
-
readonly emailVerified?: boolean | undefined;
|
|
50
|
-
readonly image?: string | undefined;
|
|
51
|
-
readonly createdAt?: string | undefined;
|
|
52
|
-
readonly updatedAt?: string | undefined;
|
|
53
|
-
} | null>>;
|
|
54
|
-
/** Whether the user is authenticated */
|
|
55
|
-
isAuthenticated: import("vue").ComputedRef<boolean>;
|
|
56
|
-
/** Whether an auth operation is pending */
|
|
57
|
-
isPending: Readonly<import("vue").Ref<boolean, boolean>>;
|
|
58
|
-
/** Auth error message if authentication failed (e.g., 401/403) */
|
|
59
|
-
authError: Readonly<import("vue").Ref<string | null, string | null>>;
|
|
60
|
-
/**
|
|
61
|
-
* Signs out the user from both Better Auth and Convex.
|
|
62
|
-
* Clears local state immediately and calls Better Auth's signOut().
|
|
63
|
-
*/
|
|
64
|
-
signOut: () => Promise<{
|
|
65
|
-
data: {
|
|
66
|
-
success: boolean;
|
|
67
|
-
};
|
|
68
|
-
error: null;
|
|
69
|
-
} | {
|
|
70
|
-
data: null;
|
|
71
|
-
error: {
|
|
72
|
-
code?: string | undefined | undefined;
|
|
73
|
-
message?: string | undefined | undefined;
|
|
74
|
-
status: number;
|
|
75
|
-
statusText: string;
|
|
76
|
-
};
|
|
77
|
-
} | null>;
|
|
78
|
-
/**
|
|
79
|
-
* Force refresh Convex auth state after login.
|
|
80
|
-
* Triggers fresh token fetch and updates reactive state.
|
|
81
|
-
*/
|
|
82
|
-
refreshAuth: () => Promise<void>;
|
|
83
|
-
};
|
|
59
|
+
export declare function useConvexAuth(): UseConvexAuthReturn;
|
|
@@ -3,7 +3,7 @@ export function useConvexAuth() {
|
|
|
3
3
|
const nuxtApp = useNuxtApp();
|
|
4
4
|
const token = useState("convex:token", () => null);
|
|
5
5
|
const user = useState("convex:user", () => null);
|
|
6
|
-
const pending = useState("convex:pending", () =>
|
|
6
|
+
const pending = useState("convex:pending", () => import.meta.client);
|
|
7
7
|
const authError = useState("convex:authError", () => null);
|
|
8
8
|
const isAuthenticated = computed(() => !!token.value && !!user.value);
|
|
9
9
|
const signOut = async () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useNuxtApp, useRuntimeConfig, useRequestEvent, useAsyncData, useState } from "#imports";
|
|
2
|
-
import { computed, watch, triggerRef,
|
|
2
|
+
import { computed, watch, triggerRef, onScopeDispose, getCurrentScope, toValue, isRef, isReactive } from "vue";
|
|
3
3
|
import {
|
|
4
4
|
getFunctionName,
|
|
5
5
|
hashArgs,
|
|
@@ -7,9 +7,11 @@ import {
|
|
|
7
7
|
parseConvexResponse,
|
|
8
8
|
computeQueryStatus,
|
|
9
9
|
fetchAuthToken,
|
|
10
|
+
createQueryBridge,
|
|
10
11
|
registerSubscription,
|
|
11
12
|
getSubscription,
|
|
12
|
-
releaseSubscription
|
|
13
|
+
releaseSubscription,
|
|
14
|
+
ensureQueryBridge
|
|
13
15
|
} from "../utils/convex-cache.js";
|
|
14
16
|
import { createLogger, getLogLevel } from "../utils/logger.js";
|
|
15
17
|
let devToolsRegistry = null;
|
|
@@ -137,7 +139,57 @@ export function useConvexQuery(query, args, options) {
|
|
|
137
139
|
);
|
|
138
140
|
});
|
|
139
141
|
let registeredCacheKey = null;
|
|
140
|
-
|
|
142
|
+
const cleanupScope = import.meta.client && subscribe ? getCurrentScope() : void 0;
|
|
143
|
+
let stopSharedDataWatch = null;
|
|
144
|
+
let stopSharedErrorWatch = null;
|
|
145
|
+
const cleanupSharedBridgeWatchers = () => {
|
|
146
|
+
if (stopSharedDataWatch) {
|
|
147
|
+
stopSharedDataWatch();
|
|
148
|
+
stopSharedDataWatch = null;
|
|
149
|
+
}
|
|
150
|
+
if (stopSharedErrorWatch) {
|
|
151
|
+
stopSharedErrorWatch();
|
|
152
|
+
stopSharedErrorWatch = null;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
const attachSharedBridge = (entry) => {
|
|
156
|
+
cleanupSharedBridgeWatchers();
|
|
157
|
+
const bridge = ensureQueryBridge(entry);
|
|
158
|
+
const syncDataFromBridge = () => {
|
|
159
|
+
if (!bridge.hasRawData) return;
|
|
160
|
+
const transformedResult = applyTransform(bridge.rawData);
|
|
161
|
+
asyncData.data.value = transformedResult;
|
|
162
|
+
if (asyncData.error.value !== null) {
|
|
163
|
+
;
|
|
164
|
+
asyncData.error.value = null;
|
|
165
|
+
}
|
|
166
|
+
triggerRef(asyncData.data);
|
|
167
|
+
};
|
|
168
|
+
const syncErrorFromBridge = () => {
|
|
169
|
+
const err = bridge.error;
|
|
170
|
+
if (!err) return;
|
|
171
|
+
const hasData = asyncData.data.value !== null && asyncData.data.value !== void 0;
|
|
172
|
+
if (!hasData) {
|
|
173
|
+
;
|
|
174
|
+
asyncData.error.value = err;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
stopSharedDataWatch = watch(
|
|
178
|
+
() => bridge.dataVersion.value,
|
|
179
|
+
() => {
|
|
180
|
+
syncDataFromBridge();
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
stopSharedErrorWatch = watch(
|
|
184
|
+
() => bridge.errorVersion.value,
|
|
185
|
+
() => {
|
|
186
|
+
syncErrorFromBridge();
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
syncDataFromBridge();
|
|
190
|
+
syncErrorFromBridge();
|
|
191
|
+
};
|
|
192
|
+
if (import.meta.client && subscribe && cleanupScope) {
|
|
141
193
|
const setupSubscription = () => {
|
|
142
194
|
const currentArgs = getArgs();
|
|
143
195
|
if (currentArgs === "skip") {
|
|
@@ -152,21 +204,20 @@ export function useConvexQuery(query, args, options) {
|
|
|
152
204
|
if (existingEntry) {
|
|
153
205
|
existingEntry.refCount++;
|
|
154
206
|
registeredCacheKey = currentCacheKey;
|
|
207
|
+
attachSharedBridge(existingEntry);
|
|
155
208
|
logger.query({ name: fnName, event: "share", refCount: existingEntry.refCount, args: currentArgs });
|
|
156
209
|
return;
|
|
157
210
|
}
|
|
158
211
|
try {
|
|
212
|
+
const localBridge = createQueryBridge();
|
|
159
213
|
const unsubscribeFn = convex.onUpdate(
|
|
160
214
|
query,
|
|
161
215
|
currentArgs,
|
|
162
216
|
(result) => {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
asyncData.error.value = null;
|
|
168
|
-
}
|
|
169
|
-
triggerRef(asyncData.data);
|
|
217
|
+
localBridge.rawData = result;
|
|
218
|
+
localBridge.hasRawData = true;
|
|
219
|
+
localBridge.error = null;
|
|
220
|
+
localBridge.dataVersion.value += 1;
|
|
170
221
|
logger.query({
|
|
171
222
|
name: fnName,
|
|
172
223
|
event: "update",
|
|
@@ -177,18 +228,15 @@ export function useConvexQuery(query, args, options) {
|
|
|
177
228
|
if (import.meta.dev && devToolsRegistry) {
|
|
178
229
|
devToolsRegistry.updateQueryStatus(currentCacheKey, {
|
|
179
230
|
status: "success",
|
|
180
|
-
data:
|
|
231
|
+
data: result,
|
|
181
232
|
dataSource: "websocket"
|
|
182
233
|
});
|
|
183
234
|
}
|
|
184
235
|
},
|
|
185
236
|
(err) => {
|
|
237
|
+
localBridge.error = err;
|
|
238
|
+
localBridge.errorVersion.value += 1;
|
|
186
239
|
logger.query({ name: fnName, event: "error", error: err });
|
|
187
|
-
const hasData = asyncData.data.value !== null && asyncData.data.value !== void 0;
|
|
188
|
-
if (!hasData) {
|
|
189
|
-
;
|
|
190
|
-
asyncData.error.value = err;
|
|
191
|
-
}
|
|
192
240
|
if (import.meta.dev && devToolsRegistry) {
|
|
193
241
|
devToolsRegistry.updateQueryStatus(currentCacheKey, {
|
|
194
242
|
status: "error",
|
|
@@ -198,7 +246,13 @@ export function useConvexQuery(query, args, options) {
|
|
|
198
246
|
}
|
|
199
247
|
);
|
|
200
248
|
registerSubscription(nuxtApp, currentCacheKey, unsubscribeFn);
|
|
249
|
+
const registeredEntry = getSubscription(nuxtApp, currentCacheKey);
|
|
250
|
+
if (!registeredEntry) {
|
|
251
|
+
throw new Error("[useConvexQuery] Failed to register subscription entry");
|
|
252
|
+
}
|
|
253
|
+
registeredEntry.queryBridge = localBridge;
|
|
201
254
|
registeredCacheKey = currentCacheKey;
|
|
255
|
+
attachSharedBridge(registeredEntry);
|
|
202
256
|
logger.query({ name: fnName, event: "subscribe", args: currentArgs });
|
|
203
257
|
if (import.meta.dev && devToolsRegistry) {
|
|
204
258
|
devToolsRegistry.registerQuery({
|
|
@@ -229,6 +283,7 @@ export function useConvexQuery(query, args, options) {
|
|
|
229
283
|
(newArgs, oldArgs) => {
|
|
230
284
|
if (hashArgs(newArgs) !== hashArgs(oldArgs)) {
|
|
231
285
|
if (oldArgs !== "skip" && registeredCacheKey) {
|
|
286
|
+
cleanupSharedBridgeWatchers();
|
|
232
287
|
const wasUnsubscribed = releaseSubscription(nuxtApp, registeredCacheKey);
|
|
233
288
|
if (wasUnsubscribed) {
|
|
234
289
|
logger.query({ name: fnName, event: "unsubscribe" });
|
|
@@ -246,8 +301,9 @@ export function useConvexQuery(query, args, options) {
|
|
|
246
301
|
{ deep: true }
|
|
247
302
|
);
|
|
248
303
|
}
|
|
249
|
-
|
|
304
|
+
onScopeDispose(() => {
|
|
250
305
|
if (registeredCacheKey) {
|
|
306
|
+
cleanupSharedBridgeWatchers();
|
|
251
307
|
const wasUnsubscribed = releaseSubscription(nuxtApp, registeredCacheKey);
|
|
252
308
|
if (wasUnsubscribed) {
|
|
253
309
|
logger.query({ name: fnName, event: "unsubscribe" });
|
|
@@ -256,8 +312,14 @@ export function useConvexQuery(query, args, options) {
|
|
|
256
312
|
}
|
|
257
313
|
}
|
|
258
314
|
registeredCacheKey = null;
|
|
315
|
+
} else {
|
|
316
|
+
cleanupSharedBridgeWatchers();
|
|
259
317
|
}
|
|
260
318
|
});
|
|
319
|
+
} else if (import.meta.client && subscribe && import.meta.dev) {
|
|
320
|
+
console.warn(
|
|
321
|
+
`[useConvexQuery] Real-time subscriptions require a Vue component/effect scope for cleanup. Detected usage outside a component (e.g. route middleware/plugin). Falling back to one-shot query only. Pass { subscribe: false } to silence this warning.`
|
|
322
|
+
);
|
|
261
323
|
}
|
|
262
324
|
let resolvePromise;
|
|
263
325
|
if (isSkipped.value) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Convex DevTools</title><link rel="stylesheet" href="/__convex_devtools__/_nuxt/entry.BiOLMZBG.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__convex_devtools__/_nuxt/BhO0ov6K.js"><script type="module" src="/__convex_devtools__/_nuxt/BhO0ov6K.js" crossorigin></script><script id="unhead:payload" type="application/json">{"title":"Convex DevTools"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__convex_devtools__",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Convex DevTools</title><link rel="stylesheet" href="/__convex_devtools__/_nuxt/entry.BiOLMZBG.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__convex_devtools__/_nuxt/BhO0ov6K.js"><script type="module" src="/__convex_devtools__/_nuxt/BhO0ov6K.js" crossorigin></script><script id="unhead:payload" type="application/json">{"title":"Convex DevTools"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__convex_devtools__",buildId:"a5e03a13-122d-4d8e-b569-24b5d8908506",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1772128215997,false]</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Convex DevTools</title><link rel="stylesheet" href="/__convex_devtools__/_nuxt/entry.BiOLMZBG.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__convex_devtools__/_nuxt/BhO0ov6K.js"><script type="module" src="/__convex_devtools__/_nuxt/BhO0ov6K.js" crossorigin></script><script id="unhead:payload" type="application/json">{"title":"Convex DevTools"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__convex_devtools__",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Convex DevTools</title><link rel="stylesheet" href="/__convex_devtools__/_nuxt/entry.BiOLMZBG.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__convex_devtools__/_nuxt/BhO0ov6K.js"><script type="module" src="/__convex_devtools__/_nuxt/BhO0ov6K.js" crossorigin></script><script id="unhead:payload" type="application/json">{"title":"Convex DevTools"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__convex_devtools__",buildId:"a5e03a13-122d-4d8e-b569-24b5d8908506",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1772128215997,false]</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"id":"
|
|
1
|
+
{"id":"a5e03a13-122d-4d8e-b569-24b5d8908506","timestamp":1772128213809}
|
package/dist/runtime/devtools/ui/dist/_nuxt/builds/meta/a5e03a13-122d-4d8e-b569-24b5d8908506.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"id":"a5e03a13-122d-4d8e-b569-24b5d8908506","timestamp":1772128213809,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Convex DevTools</title><link rel="stylesheet" href="/__convex_devtools__/_nuxt/entry.BiOLMZBG.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__convex_devtools__/_nuxt/BhO0ov6K.js"><script type="module" src="/__convex_devtools__/_nuxt/BhO0ov6K.js" crossorigin></script><script id="unhead:payload" type="application/json">{"title":"Convex DevTools"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__convex_devtools__",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Convex DevTools</title><link rel="stylesheet" href="/__convex_devtools__/_nuxt/entry.BiOLMZBG.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__convex_devtools__/_nuxt/BhO0ov6K.js"><script type="module" src="/__convex_devtools__/_nuxt/BhO0ov6K.js" crossorigin></script><script id="unhead:payload" type="application/json">{"title":"Convex DevTools"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__convex_devtools__",buildId:"a5e03a13-122d-4d8e-b569-24b5d8908506",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1772128215997,false]</script></body></html>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { useNuxtApp } from '#app';
|
|
2
|
+
import { type ShallowRef } from 'vue';
|
|
2
3
|
export { type QueryStatus, parseConvexResponse, computeQueryStatus, getFunctionName, hashArgs, getQueryKey, } from './convex-shared.js';
|
|
3
4
|
type NuxtApp = ReturnType<typeof useNuxtApp>;
|
|
4
5
|
/**
|
|
@@ -8,11 +9,30 @@ type NuxtApp = ReturnType<typeof useNuxtApp>;
|
|
|
8
9
|
export interface SubscriptionEntry {
|
|
9
10
|
unsubscribe: () => void;
|
|
10
11
|
refCount: number;
|
|
12
|
+
queryBridge?: QuerySubscriptionBridge;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Shared query state for deduplicated useConvexQuery subscribers.
|
|
16
|
+
* Stores raw subscription data and reactive version counters so each subscriber
|
|
17
|
+
* can sync into its own local asyncData refs with its own transform().
|
|
18
|
+
*/
|
|
19
|
+
export interface QuerySubscriptionBridge {
|
|
20
|
+
rawData: unknown;
|
|
21
|
+
hasRawData: boolean;
|
|
22
|
+
dataVersion: ShallowRef<number>;
|
|
23
|
+
error: Error | null;
|
|
24
|
+
errorVersion: ShallowRef<number>;
|
|
11
25
|
}
|
|
12
26
|
/**
|
|
13
27
|
* Subscription cache stored on NuxtApp
|
|
14
28
|
*/
|
|
15
29
|
export type SubscriptionCache = Record<string, SubscriptionEntry | undefined>;
|
|
30
|
+
export declare function createQueryBridge(): QuerySubscriptionBridge;
|
|
31
|
+
/**
|
|
32
|
+
* Ensure a deduplicated query subscription has a shared bridge payload.
|
|
33
|
+
* Used by useConvexQuery to fan out subscription updates to all subscribers.
|
|
34
|
+
*/
|
|
35
|
+
export declare function ensureQueryBridge(entry: SubscriptionEntry): QuerySubscriptionBridge;
|
|
16
36
|
export interface FetchAuthTokenOptions {
|
|
17
37
|
/** Whether this is a public query (skip auth) */
|
|
18
38
|
isPublic: boolean;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { shallowRef } from "vue";
|
|
1
2
|
export {
|
|
2
3
|
parseConvexResponse,
|
|
3
4
|
computeQueryStatus,
|
|
@@ -6,6 +7,21 @@ export {
|
|
|
6
7
|
getQueryKey
|
|
7
8
|
} from "./convex-shared.js";
|
|
8
9
|
const subscriptionRegistry = /* @__PURE__ */ new WeakMap();
|
|
10
|
+
export function createQueryBridge() {
|
|
11
|
+
return {
|
|
12
|
+
rawData: void 0,
|
|
13
|
+
hasRawData: false,
|
|
14
|
+
dataVersion: shallowRef(0),
|
|
15
|
+
error: null,
|
|
16
|
+
errorVersion: shallowRef(0)
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function ensureQueryBridge(entry) {
|
|
20
|
+
if (!entry.queryBridge) {
|
|
21
|
+
entry.queryBridge = createQueryBridge();
|
|
22
|
+
}
|
|
23
|
+
return entry.queryBridge;
|
|
24
|
+
}
|
|
9
25
|
export async function fetchAuthToken(options) {
|
|
10
26
|
const { isPublic, cookieHeader, siteUrl, cachedToken } = options;
|
|
11
27
|
if (isPublic) {
|
|
@@ -34,13 +34,21 @@ export function decodeUserFromJwt(token) {
|
|
|
34
34
|
if (!payload.sub && !payload.userId && !payload.email) {
|
|
35
35
|
return null;
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
const user = {
|
|
38
38
|
id: String(payload.sub || payload.userId || ""),
|
|
39
39
|
name: String(payload.name || ""),
|
|
40
40
|
email: String(payload.email || ""),
|
|
41
41
|
emailVerified: typeof payload.emailVerified === "boolean" ? payload.emailVerified : void 0,
|
|
42
42
|
image: typeof payload.image === "string" ? payload.image : void 0
|
|
43
43
|
};
|
|
44
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
45
|
+
if (key === "sub" || key === "userId" || key === "name" || key === "email" || key === "emailVerified" || key === "image" || key === "iss" || key === "aud" || key === "exp" || key === "nbf" || key === "iat" || key === "jti") {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
;
|
|
49
|
+
user[key] = value;
|
|
50
|
+
}
|
|
51
|
+
return user;
|
|
44
52
|
}
|
|
45
53
|
export function parseConvexResponse(response) {
|
|
46
54
|
if (response && typeof response === "object") {
|
package/package.json
CHANGED
package/dist/runtime/devtools/ui/dist/_nuxt/builds/meta/4441cf51-019c-4d8d-b387-2c168e8d08e3.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"id":"4441cf51-019c-4d8d-b387-2c168e8d08e3","timestamp":1772107966161,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|