nuxt-convex-module 0.12.2 → 0.12.3
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/devtools-client/index.html +1 -1
- package/dist/module.d.mts +1 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -0
- package/dist/runtime/better-auth/nuxt/server.js +5 -3
- package/dist/runtime/better-auth/vue/plugin.server.js +6 -1
- package/dist/runtime/better-auth/vue/token-store.d.ts +1 -0
- package/dist/runtime/better-auth/vue/token-store.js +18 -0
- package/dist/runtime/better-auth/vue/use-better-auth.js +43 -31
- package/dist/runtime/nuxt/config.d.ts +7 -1
- package/dist/runtime/nuxt/config.js +9 -3
- package/dist/runtime/vue/client.js +13 -0
- package/dist/runtime/vue/plugin.d.ts +2 -1
- package/dist/runtime/vue/plugin.js +2 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-convex-module/_nuxt/COXexnyN.js"}}</script><link rel="stylesheet" href="/__nuxt-convex-module/_nuxt/entry.DsZySRVW.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/COXexnyN.js"><script type="module" src="/__nuxt-convex-module/_nuxt/COXexnyN.js" crossorigin></script><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/BPtiIkWa.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-convex-module",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-convex-module/_nuxt/COXexnyN.js"}}</script><link rel="stylesheet" href="/__nuxt-convex-module/_nuxt/entry.DsZySRVW.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/COXexnyN.js"><script type="module" src="/__nuxt-convex-module/_nuxt/COXexnyN.js" crossorigin></script><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/BPtiIkWa.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-convex-module",buildId:"bfa6df52-caf6-46de-a611-bdf9d975bd3f",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1793468157767,false]</script></body></html>
|
package/dist/module.d.mts
CHANGED
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -402,6 +402,7 @@ const module$1 = defineNuxtModule({
|
|
|
402
402
|
for (const message of diagnostics.errors) logger.error(message);
|
|
403
403
|
for (const message of diagnostics.warnings) logger.warn(message);
|
|
404
404
|
nuxt.options.runtimeConfig.public.convex.loginPath = diagnostics.loginPath;
|
|
405
|
+
nuxt.options.runtimeConfig.public.convex.authRoute = diagnostics.authRoute;
|
|
405
406
|
registerAuthClientAlias(resolver, nuxt, options);
|
|
406
407
|
registerConvexAliases(nuxt);
|
|
407
408
|
registerConvexTypeFallback(nuxt);
|
|
@@ -82,10 +82,12 @@ const getArgsAndOptions = (args, token) => {
|
|
|
82
82
|
return [args[0], { token }];
|
|
83
83
|
};
|
|
84
84
|
export function convexAuth(event, opts) {
|
|
85
|
+
const config = getConvexRuntimeConfig(event);
|
|
85
86
|
const siteUrl = parseConvexSiteUrl(
|
|
86
|
-
opts?.convexSiteUrl
|
|
87
|
+
opts?.convexSiteUrl || config.siteUrl || process.env.NUXT_PUBLIC_CONVEX_SITE_URL
|
|
87
88
|
);
|
|
88
|
-
const
|
|
89
|
+
const basePath = opts?.basePath ?? config.authRoute;
|
|
90
|
+
const cacheKey = `__nuxtConvexToken:${siteUrl}|${basePath ?? ""}`;
|
|
89
91
|
const tokenCache = event.context;
|
|
90
92
|
const cachedGetToken = ({ forceRefresh } = {}) => {
|
|
91
93
|
const cached = tokenCache[cacheKey];
|
|
@@ -94,7 +96,7 @@ export function convexAuth(event, opts) {
|
|
|
94
96
|
mutableHeaders.delete("content-length");
|
|
95
97
|
mutableHeaders.delete("transfer-encoding");
|
|
96
98
|
mutableHeaders.set("accept-encoding", "identity");
|
|
97
|
-
const promise = getToken(siteUrl, mutableHeaders, { ...opts, forceRefresh });
|
|
99
|
+
const promise = getToken(siteUrl, mutableHeaders, { ...opts, basePath, forceRefresh });
|
|
98
100
|
tokenCache[cacheKey] = promise;
|
|
99
101
|
return promise;
|
|
100
102
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { computed } from "vue";
|
|
2
2
|
import { defineNuxtPlugin, useRuntimeConfig, useState, useRequestEvent, useResponseHeader } from "#app";
|
|
3
3
|
import { ConvexVueClient, ConvexClientKey } from "../../vue/client.js";
|
|
4
|
-
import { CONVEX_INITIAL_TOKEN_KEY } from "../../nuxt/config.js";
|
|
4
|
+
import { CONVEX_INITIAL_TOKEN_KEY, closeAfterRender } from "../../nuxt/config.js";
|
|
5
5
|
import { convexAuth } from "../nuxt/server.js";
|
|
6
6
|
import { ConvexAuthStateKey } from "../../vue/auth/index.js";
|
|
7
|
+
import { BetterAuthTokenStoreKey, createBetterAuthTokenStore, seedInitialToken } from "./token-store.js";
|
|
7
8
|
export async function prefetchAuthToken(event, initialToken, cacheControl) {
|
|
8
9
|
try {
|
|
9
10
|
const token = await convexAuth(event).getToken();
|
|
@@ -19,10 +20,13 @@ export default defineNuxtPlugin({
|
|
|
19
20
|
name: "nuxt-convex-module:better-auth:server",
|
|
20
21
|
async setup(nuxtApp) {
|
|
21
22
|
const initialToken = useState(CONVEX_INITIAL_TOKEN_KEY, () => null);
|
|
23
|
+
const tokenStore = createBetterAuthTokenStore();
|
|
24
|
+
nuxtApp.vueApp.provide(BetterAuthTokenStoreKey, tokenStore);
|
|
22
25
|
const url = useRuntimeConfig().public.convex.url;
|
|
23
26
|
const ssrClient = url ? new ConvexVueClient(url) : void 0;
|
|
24
27
|
if (ssrClient) {
|
|
25
28
|
nuxtApp.vueApp.provide(ConvexClientKey, ssrClient);
|
|
29
|
+
closeAfterRender(nuxtApp, ssrClient);
|
|
26
30
|
}
|
|
27
31
|
const ssrAuthState = {
|
|
28
32
|
isLoading: computed(() => true),
|
|
@@ -33,6 +37,7 @@ export default defineNuxtPlugin({
|
|
|
33
37
|
const event = useRequestEvent();
|
|
34
38
|
if (event && !import.meta.prerender) {
|
|
35
39
|
await prefetchAuthToken(event, initialToken, useResponseHeader("Cache-Control"));
|
|
40
|
+
seedInitialToken(tokenStore, initialToken.value);
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
43
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
export function createBetterAuthTokenStore() {
|
|
3
|
+
return {
|
|
4
|
+
cachedToken: ref(null),
|
|
5
|
+
cachedTokenVersion: null,
|
|
6
|
+
pendingToken: null,
|
|
7
|
+
pendingTokenVersion: null,
|
|
8
|
+
initialTokenUsed: false
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export const BetterAuthTokenStoreKey = Symbol("BetterAuthTokenStore");
|
|
12
|
+
export const PENDING_AUTH_VERSION = "__pending__";
|
|
13
|
+
export function seedInitialToken(store, initialToken) {
|
|
14
|
+
if (store.initialTokenUsed || !initialToken) return;
|
|
15
|
+
store.cachedToken.value = initialToken;
|
|
16
|
+
store.cachedTokenVersion = PENDING_AUTH_VERSION;
|
|
17
|
+
store.initialTokenUsed = true;
|
|
18
|
+
}
|
|
@@ -1,18 +1,30 @@
|
|
|
1
|
-
import { computed,
|
|
1
|
+
import { computed, effectScope, hasInjectionContext, inject, shallowRef } from "vue";
|
|
2
2
|
import { authClient } from "#convex/auth-client";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
import { BetterAuthTokenStoreKey, createBetterAuthTokenStore, PENDING_AUTH_VERSION, seedInitialToken } from "./token-store.js";
|
|
4
|
+
const browserStore = createBetterAuthTokenStore();
|
|
5
|
+
function useTokenStore() {
|
|
6
|
+
if (!import.meta.server) return browserStore;
|
|
7
|
+
return (hasInjectionContext() ? inject(BetterAuthTokenStoreKey, null) : null) ?? createBetterAuthTokenStore();
|
|
8
|
+
}
|
|
9
|
+
const serverSession = () => shallowRef({
|
|
10
|
+
data: null,
|
|
11
|
+
error: null,
|
|
12
|
+
isPending: true,
|
|
13
|
+
isRefetching: false,
|
|
14
|
+
refetch: async () => {
|
|
15
15
|
}
|
|
16
|
+
});
|
|
17
|
+
let browserSession;
|
|
18
|
+
let browserSessionScope;
|
|
19
|
+
const useClientSession = () => {
|
|
20
|
+
if (import.meta.server) return serverSession();
|
|
21
|
+
browserSessionScope ??= effectScope(true);
|
|
22
|
+
return browserSession ??= browserSessionScope.run(() => authClient.useSession());
|
|
23
|
+
};
|
|
24
|
+
export function useBetterAuth(initialToken) {
|
|
25
|
+
const store = useTokenStore();
|
|
26
|
+
seedInitialToken(store, initialToken);
|
|
27
|
+
const { cachedToken } = store;
|
|
16
28
|
const session = useClientSession();
|
|
17
29
|
const client = authClient;
|
|
18
30
|
const authVersion = computed(() => {
|
|
@@ -26,32 +38,32 @@ export function useBetterAuth(initialToken) {
|
|
|
26
38
|
const version = currentAuthVersion();
|
|
27
39
|
if (version === null) {
|
|
28
40
|
cachedToken.value = null;
|
|
29
|
-
cachedTokenVersion = null;
|
|
30
|
-
pendingToken = null;
|
|
31
|
-
pendingTokenVersion = null;
|
|
41
|
+
store.cachedTokenVersion = null;
|
|
42
|
+
store.pendingToken = null;
|
|
43
|
+
store.pendingTokenVersion = null;
|
|
32
44
|
return null;
|
|
33
45
|
}
|
|
34
|
-
if (cachedToken.value && !forceRefreshToken && cachedTokenVersion === version) {
|
|
46
|
+
if (cachedToken.value && !forceRefreshToken && store.cachedTokenVersion === version) {
|
|
35
47
|
return cachedToken.value;
|
|
36
48
|
}
|
|
37
|
-
if (!forceRefreshToken && pendingToken && pendingTokenVersion === version) {
|
|
38
|
-
return pendingToken;
|
|
49
|
+
if (!forceRefreshToken && store.pendingToken && store.pendingTokenVersion === version) {
|
|
50
|
+
return store.pendingToken;
|
|
39
51
|
}
|
|
40
|
-
pendingTokenVersion = version;
|
|
41
|
-
pendingToken = client.convex.token({ fetchOptions: { throw: false } }).then(({ data }) => {
|
|
52
|
+
store.pendingTokenVersion = version;
|
|
53
|
+
const pending = store.pendingToken = client.convex.token({ fetchOptions: { throw: false } }).then(({ data }) => {
|
|
42
54
|
const token = data?.token || null;
|
|
43
55
|
cachedToken.value = token;
|
|
44
|
-
cachedTokenVersion = version;
|
|
56
|
+
store.cachedTokenVersion = version;
|
|
45
57
|
return token;
|
|
46
58
|
}).catch(() => {
|
|
47
59
|
cachedToken.value = null;
|
|
48
|
-
cachedTokenVersion = version;
|
|
60
|
+
store.cachedTokenVersion = version;
|
|
49
61
|
return null;
|
|
50
62
|
}).finally(() => {
|
|
51
|
-
pendingToken = null;
|
|
52
|
-
pendingTokenVersion = null;
|
|
63
|
+
store.pendingToken = null;
|
|
64
|
+
store.pendingTokenVersion = null;
|
|
53
65
|
});
|
|
54
|
-
return
|
|
66
|
+
return pending;
|
|
55
67
|
};
|
|
56
68
|
return {
|
|
57
69
|
isLoading: computed(() => session.value.isPending && !cachedToken.value),
|
|
@@ -75,9 +87,9 @@ export function useBetterAuth(initialToken) {
|
|
|
75
87
|
};
|
|
76
88
|
}
|
|
77
89
|
export function __resetUseBetterAuthForTests() {
|
|
78
|
-
cachedToken.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
90
|
+
Object.assign(browserStore, createBetterAuthTokenStore(), { cachedToken: browserStore.cachedToken });
|
|
91
|
+
browserStore.cachedToken.value = null;
|
|
92
|
+
browserSessionScope?.stop();
|
|
93
|
+
browserSessionScope = void 0;
|
|
94
|
+
browserSession = void 0;
|
|
83
95
|
}
|
|
@@ -8,11 +8,17 @@ export declare const CONVEX_INITIAL_TOKEN_KEY = "convex:initialToken";
|
|
|
8
8
|
/**
|
|
9
9
|
* The module's runtime config, tolerating a missing Nuxt context (a plain
|
|
10
10
|
* server import outside a request) by returning an empty object.
|
|
11
|
+
*
|
|
12
|
+
* Given a server route's event, it reads that request's config: an
|
|
13
|
+
* environment variable set after the server started (by a Nitro plugin, say)
|
|
14
|
+
* reaches it, where the config read without one was fixed at startup.
|
|
11
15
|
*/
|
|
12
|
-
export declare function getConvexRuntimeConfig(): {
|
|
16
|
+
export declare function getConvexRuntimeConfig(event?: unknown): {
|
|
13
17
|
url: string | undefined;
|
|
14
18
|
siteUrl: string | undefined;
|
|
19
|
+
authRoute: string | undefined;
|
|
15
20
|
} | {
|
|
16
21
|
url?: undefined;
|
|
17
22
|
siteUrl?: undefined;
|
|
23
|
+
authRoute?: undefined;
|
|
18
24
|
};
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { useRuntimeConfig } from "#imports";
|
|
2
2
|
export const CONVEX_INITIAL_TOKEN_KEY = "convex:initialToken";
|
|
3
|
-
export function
|
|
3
|
+
export function closeAfterRender(nuxtApp, client) {
|
|
4
|
+
const close = () => void client.close();
|
|
5
|
+
nuxtApp.hook("app:rendered", close);
|
|
6
|
+
nuxtApp.hook("app:error", close);
|
|
7
|
+
}
|
|
8
|
+
export function getConvexRuntimeConfig(event) {
|
|
4
9
|
try {
|
|
5
|
-
const config = useRuntimeConfig();
|
|
10
|
+
const config = useRuntimeConfig(event);
|
|
6
11
|
return {
|
|
7
12
|
url: config.public?.convex?.url,
|
|
8
|
-
siteUrl: config.public?.convex?.siteUrl
|
|
13
|
+
siteUrl: config.public?.convex?.siteUrl,
|
|
14
|
+
authRoute: config.public?.convex?.authRoute
|
|
9
15
|
};
|
|
10
16
|
} catch {
|
|
11
17
|
return {};
|
|
@@ -24,6 +24,18 @@ function instantiateDefaultLogger({ verbose }) {
|
|
|
24
24
|
error: (...args) => console.error(...args)
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
+
function notConnected() {
|
|
28
|
+
return {
|
|
29
|
+
hasInflightRequests: false,
|
|
30
|
+
isWebSocketConnected: false,
|
|
31
|
+
timeOfOldestInflightRequest: null,
|
|
32
|
+
hasEverConnected: false,
|
|
33
|
+
connectionCount: 0,
|
|
34
|
+
connectionRetries: 0,
|
|
35
|
+
inflightMutations: 0,
|
|
36
|
+
inflightActions: 0
|
|
37
|
+
};
|
|
38
|
+
}
|
|
27
39
|
export class ConvexVueClient {
|
|
28
40
|
address;
|
|
29
41
|
cachedSync;
|
|
@@ -317,6 +329,7 @@ export class ConvexVueClient {
|
|
|
317
329
|
* @experimental May change in a minor release — see STABILITY.md.
|
|
318
330
|
*/
|
|
319
331
|
connectionState() {
|
|
332
|
+
if (import.meta.server && !this.cachedSync) return notConnected();
|
|
320
333
|
return this.sync.connectionState();
|
|
321
334
|
}
|
|
322
335
|
/**
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
* those instead of this one — see `registerIntegrations` in `src/module.ts`.
|
|
13
13
|
*
|
|
14
14
|
* The WebSocket opens lazily on the first subscription; on the server the
|
|
15
|
-
* preloaded-query helpers short-circuit, so no socket is opened during SSR
|
|
15
|
+
* preloaded-query helpers short-circuit, so no socket is opened during SSR,
|
|
16
|
+
* and a server render's client is closed when its request is done.
|
|
16
17
|
*/
|
|
17
18
|
declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
|
|
18
19
|
export default _default;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { defineNuxtPlugin, useRuntimeConfig } from "#app";
|
|
2
2
|
import { ConvexVueClient, ConvexClientKey } from "./client.js";
|
|
3
|
+
import { closeAfterRender } from "../nuxt/config.js";
|
|
3
4
|
export default defineNuxtPlugin({
|
|
4
5
|
name: "nuxt-convex-module:client",
|
|
5
6
|
setup(nuxtApp) {
|
|
@@ -12,5 +13,6 @@ export default defineNuxtPlugin({
|
|
|
12
13
|
}
|
|
13
14
|
const client = new ConvexVueClient(url);
|
|
14
15
|
nuxtApp.vueApp.provide(ConvexClientKey, client);
|
|
16
|
+
if (import.meta.server) closeAfterRender(nuxtApp, client);
|
|
15
17
|
}
|
|
16
18
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "nuxt-convex-module",
|
|
4
|
-
"version": "0.12.
|
|
4
|
+
"version": "0.12.3",
|
|
5
5
|
"description": "Convex backend integration with live queries, mutations, actions, pagination, file storage and SSR, auto-imported and typed against your deployment. The same Vue client runs without Nuxt; Better Auth, Clerk, Auth0 and Polar are opt-in.",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|