use-convex 0.0.2

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.
Files changed (87) hide show
  1. package/LICENSE +2 -0
  2. package/README.md +321 -0
  3. package/dist/module.d.mts +97 -0
  4. package/dist/module.json +12 -0
  5. package/dist/module.mjs +232 -0
  6. package/dist/runtime/components/AuthLoading.d.vue.ts +13 -0
  7. package/dist/runtime/components/AuthLoading.vue +8 -0
  8. package/dist/runtime/components/AuthLoading.vue.d.ts +13 -0
  9. package/dist/runtime/components/AuthRefreshing.d.vue.ts +13 -0
  10. package/dist/runtime/components/AuthRefreshing.vue +8 -0
  11. package/dist/runtime/components/AuthRefreshing.vue.d.ts +13 -0
  12. package/dist/runtime/components/Authenticated.d.vue.ts +13 -0
  13. package/dist/runtime/components/Authenticated.vue +8 -0
  14. package/dist/runtime/components/Authenticated.vue.d.ts +13 -0
  15. package/dist/runtime/components/Unauthenticated.d.vue.ts +13 -0
  16. package/dist/runtime/components/Unauthenticated.vue +8 -0
  17. package/dist/runtime/components/Unauthenticated.vue.d.ts +13 -0
  18. package/dist/runtime/composables/prewarmQuery.d.ts +9 -0
  19. package/dist/runtime/composables/prewarmQuery.js +14 -0
  20. package/dist/runtime/composables/useAuth.d.ts +60 -0
  21. package/dist/runtime/composables/useAuth.js +426 -0
  22. package/dist/runtime/composables/useAuthToken.d.ts +24 -0
  23. package/dist/runtime/composables/useAuthToken.js +71 -0
  24. package/dist/runtime/composables/useConvex.d.ts +5 -0
  25. package/dist/runtime/composables/useConvex.js +10 -0
  26. package/dist/runtime/composables/useConvexAction.d.ts +13 -0
  27. package/dist/runtime/composables/useConvexAction.js +30 -0
  28. package/dist/runtime/composables/useConvexAuth.d.ts +51 -0
  29. package/dist/runtime/composables/useConvexAuth.js +96 -0
  30. package/dist/runtime/composables/useConvexConnectionState.d.ts +8 -0
  31. package/dist/runtime/composables/useConvexConnectionState.js +21 -0
  32. package/dist/runtime/composables/useConvexGate.d.ts +20 -0
  33. package/dist/runtime/composables/useConvexGate.js +21 -0
  34. package/dist/runtime/composables/useConvexMutation.d.ts +25 -0
  35. package/dist/runtime/composables/useConvexMutation.js +35 -0
  36. package/dist/runtime/composables/useConvexPaginatedQuery.d.ts +43 -0
  37. package/dist/runtime/composables/useConvexPaginatedQuery.js +188 -0
  38. package/dist/runtime/composables/useConvexQueries.d.ts +27 -0
  39. package/dist/runtime/composables/useConvexQueries.js +84 -0
  40. package/dist/runtime/composables/useConvexQuery.d.ts +56 -0
  41. package/dist/runtime/composables/useConvexQuery.js +147 -0
  42. package/dist/runtime/plugin.auth.client.d.ts +8 -0
  43. package/dist/runtime/plugin.auth.client.js +41 -0
  44. package/dist/runtime/plugin.client.d.ts +7 -0
  45. package/dist/runtime/plugin.client.js +40 -0
  46. package/dist/runtime/plugin.devtools.client.d.ts +6 -0
  47. package/dist/runtime/plugin.devtools.client.js +16 -0
  48. package/dist/runtime/plugin.server.d.ts +7 -0
  49. package/dist/runtime/plugin.server.js +44 -0
  50. package/dist/runtime/server/api/convex/auth/session.d.ts +36 -0
  51. package/dist/runtime/server/api/convex/auth/session.js +95 -0
  52. package/dist/runtime/server/auth.d.ts +19 -0
  53. package/dist/runtime/server/auth.js +32 -0
  54. package/dist/runtime/server/authCookies.d.ts +9 -0
  55. package/dist/runtime/server/authCookies.js +86 -0
  56. package/dist/runtime/server/fetch.d.ts +43 -0
  57. package/dist/runtime/server/fetch.js +63 -0
  58. package/dist/runtime/server/routes/__convex_devtools.get.d.ts +6 -0
  59. package/dist/runtime/server/routes/__convex_devtools.get.js +32 -0
  60. package/dist/runtime/server/sameOrigin.d.ts +14 -0
  61. package/dist/runtime/server/sameOrigin.js +33 -0
  62. package/dist/runtime/utils/authCookie.d.ts +21 -0
  63. package/dist/runtime/utils/authCookie.js +47 -0
  64. package/dist/runtime/utils/authGate.d.ts +11 -0
  65. package/dist/runtime/utils/authGate.js +9 -0
  66. package/dist/runtime/utils/authMutex.d.ts +15 -0
  67. package/dist/runtime/utils/authMutex.js +47 -0
  68. package/dist/runtime/utils/authState.d.ts +31 -0
  69. package/dist/runtime/utils/authState.js +35 -0
  70. package/dist/runtime/utils/authStorage.d.ts +55 -0
  71. package/dist/runtime/utils/authStorage.js +85 -0
  72. package/dist/runtime/utils/context.d.ts +53 -0
  73. package/dist/runtime/utils/context.js +41 -0
  74. package/dist/runtime/utils/fetchToken.d.ts +9 -0
  75. package/dist/runtime/utils/fetchToken.js +6 -0
  76. package/dist/runtime/utils/http.d.ts +10 -0
  77. package/dist/runtime/utils/http.js +13 -0
  78. package/dist/runtime/utils/oauthRedirect.d.ts +5 -0
  79. package/dist/runtime/utils/oauthRedirect.js +12 -0
  80. package/dist/runtime/utils/overlay.d.ts +18 -0
  81. package/dist/runtime/utils/overlay.js +48 -0
  82. package/dist/runtime/utils/paginatedOptimistic.d.ts +37 -0
  83. package/dist/runtime/utils/paginatedOptimistic.js +178 -0
  84. package/dist/runtime/utils/queryKey.d.ts +8 -0
  85. package/dist/runtime/utils/queryKey.js +11 -0
  86. package/dist/types.d.mts +29 -0
  87. package/package.json +66 -0
@@ -0,0 +1,53 @@
1
+ import type { AuthTokenFetcher, ConvexClient, ConvexHttpClient } from 'convex/browser';
2
+ import type { ComputedRef, InjectionKey, Ref } from 'vue';
3
+ export interface ConvexAuthContext {
4
+ /**
5
+ * Whether useConvexAuth({ fetchToken }) has been called.
6
+ */
7
+ configured: boolean;
8
+ fetchToken: AuthTokenFetcher | null;
9
+ providerLoading: Ref<boolean>;
10
+ providerAuthenticated: Ref<boolean>;
11
+ /**
12
+ * Backend confirmation. `null` = waiting for Convex onChange.
13
+ */
14
+ isConvexAuthenticated: Ref<boolean | null>;
15
+ isRefreshingRaw: Ref<boolean>;
16
+ /** Derived UI flags (written by useConvexAuth). */
17
+ isLoading: Ref<boolean>;
18
+ isAuthenticated: Ref<boolean>;
19
+ isRefreshing: Ref<boolean>;
20
+ }
21
+ export interface ConvexNuxtContext {
22
+ url: string;
23
+ /**
24
+ * Live WebSocket client. Only available in the browser plugin.
25
+ */
26
+ client: ConvexClient | null;
27
+ /**
28
+ * JWT from the optional auth cookie. Reactive so sign-in/out updates
29
+ * HttpClient refreshes and `hasSsrSession`.
30
+ */
31
+ ssrToken: ComputedRef<string | undefined>;
32
+ /**
33
+ * Shared auth state for useConvexAuth.
34
+ */
35
+ auth: ConvexAuthContext;
36
+ /**
37
+ * Create a fresh HttpClient for one-shot fetches (SSR / Nitro / refresh).
38
+ * Prefer a new client per call — HttpClient is stateful.
39
+ */
40
+ createHttpClient: (options?: {
41
+ token?: string;
42
+ }) => ConvexHttpClient;
43
+ }
44
+ export declare const convexNuxtKey: InjectionKey<ConvexNuxtContext>;
45
+ export declare function createAuthContext(): ConvexAuthContext;
46
+ /**
47
+ * Resolve Convex context from Nuxt `$convex` provide and/or Vue inject.
48
+ *
49
+ * Prefer `$convex` so async plugins can still read context after `await`
50
+ * (Vue `inject()` only works synchronously inside setup).
51
+ */
52
+ export declare function tryUseConvexContext(): ConvexNuxtContext | null;
53
+ export declare function useConvexContext(): ConvexNuxtContext;
@@ -0,0 +1,41 @@
1
+ import { inject, ref } from "vue";
2
+ import { useNuxtApp } from "nuxt/app";
3
+ export const convexNuxtKey = Symbol("convex-nuxt");
4
+ export function createAuthContext() {
5
+ return {
6
+ configured: false,
7
+ fetchToken: null,
8
+ providerLoading: ref(false),
9
+ providerAuthenticated: ref(false),
10
+ isConvexAuthenticated: ref(null),
11
+ isRefreshingRaw: ref(false),
12
+ // Default: no auth wired → not loading, not authenticated.
13
+ isLoading: ref(false),
14
+ isAuthenticated: ref(false),
15
+ isRefreshing: ref(false)
16
+ };
17
+ }
18
+ export function tryUseConvexContext() {
19
+ try {
20
+ const app = useNuxtApp();
21
+ const fromNuxt = app.$convex;
22
+ if (fromNuxt) {
23
+ return fromNuxt;
24
+ }
25
+ } catch {
26
+ }
27
+ try {
28
+ return inject(convexNuxtKey, null);
29
+ } catch {
30
+ return null;
31
+ }
32
+ }
33
+ export function useConvexContext() {
34
+ const ctx = tryUseConvexContext();
35
+ if (!ctx) {
36
+ throw new Error(
37
+ "[convex-nuxt] Convex plugin did not start \u2014 set convex.url or NUXT_PUBLIC_CONVEX_URL (the module no-ops when the URL is empty)."
38
+ );
39
+ }
40
+ return ctx;
41
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Resolve the JWT for a Nitro `fetch*` call.
3
+ * Explicit `token` wins; otherwise use the cookie value from the event.
4
+ */
5
+ export declare function resolveFetchToken(options: {
6
+ token?: string;
7
+ cookieName?: string;
8
+ cookieValue?: string | null;
9
+ }): string | undefined;
@@ -0,0 +1,6 @@
1
+ export function resolveFetchToken(options) {
2
+ if (options.token !== void 0) {
3
+ return options.token || void 0;
4
+ }
5
+ return options.cookieValue || void 0;
6
+ }
@@ -0,0 +1,10 @@
1
+ import { ConvexHttpClient } from 'convex/browser';
2
+ export interface CreateHttpClientOptions {
3
+ token?: string;
4
+ skipConvexDeploymentUrlCheck?: boolean;
5
+ }
6
+ /**
7
+ * Construct a fresh ConvexHttpClient for a single request.
8
+ * Matches the convex/nextjs pattern: new client, optional auth, no-store fetch.
9
+ */
10
+ export declare function createHttpClient(url: string, options?: CreateHttpClientOptions): ConvexHttpClient;
@@ -0,0 +1,13 @@
1
+ import { ConvexHttpClient } from "convex/browser";
2
+ export function createHttpClient(url, options = {}) {
3
+ const client = new ConvexHttpClient(url, {
4
+ skipConvexDeploymentUrlCheck: options.skipConvexDeploymentUrlCheck,
5
+ ...options.token ? { auth: options.token } : {}
6
+ });
7
+ if (options.token) {
8
+ client.setAuth(options.token);
9
+ }
10
+ ;
11
+ client.setFetchOptions({ cache: "no-store" });
12
+ return client;
13
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Validate an OAuth redirect from Convex `auth:signIn`.
3
+ * Only http(s) absolute URLs are allowed (blocks javascript:/data: etc.).
4
+ */
5
+ export declare function parseOAuthRedirect(redirect: string): URL;
@@ -0,0 +1,12 @@
1
+ export function parseOAuthRedirect(redirect) {
2
+ let url;
3
+ try {
4
+ url = new URL(redirect);
5
+ } catch {
6
+ throw new Error("Invalid OAuth redirect URL");
7
+ }
8
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
9
+ throw new Error("OAuth redirect must be http(s)");
10
+ }
11
+ return url;
12
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Resolve SSR payload vs live subscription — Nuxt equivalent of
3
+ * Next.js `usePreloadedQuery`: `live === undefined ? payload : live`.
4
+ */
5
+ export declare function resolveQueryOverlay<T>(input: {
6
+ skipped: boolean;
7
+ liveReady: boolean;
8
+ liveData: T | undefined;
9
+ liveError: Error | null;
10
+ payload: T | null | undefined;
11
+ payloadError: Error | null | undefined;
12
+ payloadPending: boolean;
13
+ }): {
14
+ data: T | null | undefined;
15
+ error: Error | null;
16
+ pending: boolean;
17
+ status: 'pending' | 'success' | 'error';
18
+ };
@@ -0,0 +1,48 @@
1
+ export function resolveQueryOverlay(input) {
2
+ if (input.skipped) {
3
+ return {
4
+ data: input.payload,
5
+ error: null,
6
+ pending: false,
7
+ status: "success"
8
+ };
9
+ }
10
+ if (input.liveReady) {
11
+ if (input.liveError) {
12
+ return {
13
+ data: input.liveData,
14
+ error: input.liveError,
15
+ pending: false,
16
+ status: "error"
17
+ };
18
+ }
19
+ return {
20
+ data: input.liveData,
21
+ error: null,
22
+ pending: false,
23
+ status: "success"
24
+ };
25
+ }
26
+ if (input.payloadError) {
27
+ return {
28
+ data: input.payload,
29
+ error: input.payloadError,
30
+ pending: false,
31
+ status: "error"
32
+ };
33
+ }
34
+ if (input.payloadPending) {
35
+ return {
36
+ data: input.payload,
37
+ error: null,
38
+ pending: true,
39
+ status: "pending"
40
+ };
41
+ }
42
+ return {
43
+ data: input.payload,
44
+ error: null,
45
+ pending: false,
46
+ status: "success"
47
+ };
48
+ }
@@ -0,0 +1,37 @@
1
+ import type { OptimisticLocalStore } from 'convex/browser';
2
+ import type { Value } from 'convex/values';
3
+ import type { PaginatedQueryArgs, PaginatedQueryItem, PaginatedQueryReference } from '../composables/useConvexPaginatedQuery.js';
4
+ /**
5
+ * Apply an optimistic update to every loaded page of a paginated query
6
+ * (React `optimisticallyUpdateValueInPaginatedQuery` parity).
7
+ */
8
+ export declare function optimisticallyUpdateValueInPaginatedQuery<Query extends PaginatedQueryReference>(localStore: OptimisticLocalStore, query: Query, args: PaginatedQueryArgs<Query>, updateValue: (currentValue: PaginatedQueryItem<Query>) => PaginatedQueryItem<Query>): void;
9
+ /**
10
+ * Insert an item at the top of a paginated list's first loaded page.
11
+ */
12
+ export declare function insertAtTop<Query extends PaginatedQueryReference>(options: {
13
+ paginatedQuery: Query;
14
+ argsToMatch?: Partial<PaginatedQueryArgs<Query>>;
15
+ localQueryStore: OptimisticLocalStore;
16
+ item: PaginatedQueryItem<Query>;
17
+ }): void;
18
+ /**
19
+ * Insert an item at the bottom of a paginated list only if the last page is loaded.
20
+ */
21
+ export declare function insertAtBottomIfLoaded<Query extends PaginatedQueryReference>(options: {
22
+ paginatedQuery: Query;
23
+ argsToMatch?: Partial<PaginatedQueryArgs<Query>>;
24
+ localQueryStore: OptimisticLocalStore;
25
+ item: PaginatedQueryItem<Query>;
26
+ }): void;
27
+ /**
28
+ * Insert an item at a sort-key position within loaded paginated pages.
29
+ */
30
+ export declare function insertAtPosition<Query extends PaginatedQueryReference>(options: {
31
+ paginatedQuery: Query;
32
+ argsToMatch?: Partial<PaginatedQueryArgs<Query>>;
33
+ sortOrder: 'asc' | 'desc';
34
+ sortKeyFromItem: (element: PaginatedQueryItem<Query>) => Value | Value[];
35
+ localQueryStore: OptimisticLocalStore;
36
+ item: PaginatedQueryItem<Query>;
37
+ }): void;
@@ -0,0 +1,178 @@
1
+ import { compareValues, convexToJson } from "convex/values";
2
+ export function optimisticallyUpdateValueInPaginatedQuery(localStore, query, args, updateValue) {
3
+ const expectedArgs = JSON.stringify(convexToJson(args));
4
+ for (const queryResult of localStore.getAllQueries(query)) {
5
+ if (queryResult.value === void 0) {
6
+ continue;
7
+ }
8
+ const { paginationOpts: _, ...innerArgs } = queryResult.args;
9
+ if (JSON.stringify(convexToJson(innerArgs)) !== expectedArgs) {
10
+ continue;
11
+ }
12
+ const value = queryResult.value;
13
+ if (typeof value === "object" && value !== null && Array.isArray(value.page)) {
14
+ localStore.setQuery(query, queryResult.args, {
15
+ ...value,
16
+ page: value.page.map(
17
+ updateValue
18
+ )
19
+ });
20
+ }
21
+ }
22
+ }
23
+ export function insertAtTop(options) {
24
+ const { paginatedQuery, argsToMatch, localQueryStore, item } = options;
25
+ const queries = localQueryStore.getAllQueries(paginatedQuery);
26
+ const matching = queries.filter((q) => {
27
+ if (argsToMatch === void 0) {
28
+ return true;
29
+ }
30
+ return Object.keys(argsToMatch).every(
31
+ // @ts-expect-error both are plain objects
32
+ (key) => compareValues(argsToMatch[key], q.args[key]) === 0
33
+ );
34
+ });
35
+ const firstPage = matching.find(
36
+ (q) => q.args.paginationOpts.cursor === null
37
+ );
38
+ if (firstPage === void 0 || firstPage.value === void 0) {
39
+ return;
40
+ }
41
+ localQueryStore.setQuery(paginatedQuery, firstPage.args, {
42
+ ...firstPage.value,
43
+ page: [item, ...firstPage.value.page]
44
+ });
45
+ }
46
+ export function insertAtBottomIfLoaded(options) {
47
+ const { paginatedQuery, localQueryStore, item, argsToMatch } = options;
48
+ const queries = localQueryStore.getAllQueries(paginatedQuery);
49
+ const matching = queries.filter((q) => {
50
+ if (argsToMatch === void 0) {
51
+ return true;
52
+ }
53
+ return Object.keys(argsToMatch).every(
54
+ // @ts-expect-error both are plain objects
55
+ (key) => compareValues(argsToMatch[key], q.args[key]) === 0
56
+ );
57
+ });
58
+ const lastPage = matching.find(
59
+ (q) => q.value !== void 0 && q.value.isDone
60
+ );
61
+ if (lastPage === void 0 || lastPage.value === void 0) {
62
+ return;
63
+ }
64
+ localQueryStore.setQuery(paginatedQuery, lastPage.args, {
65
+ ...lastPage.value,
66
+ page: [...lastPage.value.page, item]
67
+ });
68
+ }
69
+ export function insertAtPosition(options) {
70
+ const {
71
+ paginatedQuery,
72
+ sortOrder,
73
+ sortKeyFromItem,
74
+ localQueryStore,
75
+ item,
76
+ argsToMatch
77
+ } = options;
78
+ const queries = localQueryStore.getAllQueries(paginatedQuery);
79
+ const queryGroups = {};
80
+ for (const query of queries) {
81
+ if (argsToMatch !== void 0 && !Object.keys(argsToMatch).every(
82
+ // @ts-expect-error both are plain objects
83
+ (key2) => argsToMatch[key2] === query.args[key2]
84
+ )) {
85
+ continue;
86
+ }
87
+ const key = JSON.stringify(
88
+ Object.fromEntries(
89
+ Object.entries(query.args).map(([k, v]) => [
90
+ k,
91
+ k === "paginationOpts" ? v.id : v
92
+ ])
93
+ )
94
+ );
95
+ queryGroups[key] ??= [];
96
+ queryGroups[key].push(query);
97
+ }
98
+ for (const pageQueries of Object.values(queryGroups)) {
99
+ insertAtPositionInPages({
100
+ pageQueries,
101
+ paginatedQuery,
102
+ sortOrder,
103
+ sortKeyFromItem,
104
+ localQueryStore,
105
+ item
106
+ });
107
+ }
108
+ }
109
+ function insertAtPositionInPages(options) {
110
+ const {
111
+ pageQueries,
112
+ sortOrder,
113
+ sortKeyFromItem,
114
+ localQueryStore,
115
+ item,
116
+ paginatedQuery
117
+ } = options;
118
+ const insertedKey = sortKeyFromItem(item);
119
+ const loadedPages = pageQueries.filter(
120
+ (q) => q.value !== void 0 && q.value.page.length > 0
121
+ );
122
+ const sortedPages = loadedPages.sort((a, b) => {
123
+ const aKey = sortKeyFromItem(a.value.page[0]);
124
+ const bKey = sortKeyFromItem(b.value.page[0]);
125
+ return sortOrder === "asc" ? compareValues(aKey, bKey) : compareValues(bKey, aKey);
126
+ });
127
+ const firstLoadedPage = sortedPages[0];
128
+ if (firstLoadedPage === void 0) {
129
+ return;
130
+ }
131
+ const firstPageKey = sortKeyFromItem(firstLoadedPage.value.page[0]);
132
+ const isBeforeFirstPage = sortOrder === "asc" ? compareValues(insertedKey, firstPageKey) <= 0 : compareValues(insertedKey, firstPageKey) >= 0;
133
+ if (isBeforeFirstPage) {
134
+ if (firstLoadedPage.args.paginationOpts.cursor === null) {
135
+ localQueryStore.setQuery(paginatedQuery, firstLoadedPage.args, {
136
+ ...firstLoadedPage.value,
137
+ page: [item, ...firstLoadedPage.value.page]
138
+ });
139
+ }
140
+ return;
141
+ }
142
+ const lastLoadedPage = sortedPages[sortedPages.length - 1];
143
+ if (lastLoadedPage === void 0) {
144
+ return;
145
+ }
146
+ const lastPageKey = sortKeyFromItem(
147
+ lastLoadedPage.value.page[lastLoadedPage.value.page.length - 1]
148
+ );
149
+ const isAfterLastPage = sortOrder === "asc" ? compareValues(insertedKey, lastPageKey) >= 0 : compareValues(insertedKey, lastPageKey) <= 0;
150
+ if (isAfterLastPage) {
151
+ if (lastLoadedPage.value.isDone) {
152
+ localQueryStore.setQuery(paginatedQuery, lastLoadedPage.args, {
153
+ ...lastLoadedPage.value,
154
+ page: [...lastLoadedPage.value.page, item]
155
+ });
156
+ }
157
+ return;
158
+ }
159
+ const successorPageIndex = sortedPages.findIndex(
160
+ (p) => sortOrder === "asc" ? compareValues(sortKeyFromItem(p.value.page[0]), insertedKey) > 0 : compareValues(sortKeyFromItem(p.value.page[0]), insertedKey) < 0
161
+ );
162
+ const pageToUpdate = successorPageIndex === -1 ? sortedPages[sortedPages.length - 1] : sortedPages[successorPageIndex - 1];
163
+ if (pageToUpdate === void 0) {
164
+ return;
165
+ }
166
+ const indexWithinPage = pageToUpdate.value.page.findIndex(
167
+ (element) => sortOrder === "asc" ? compareValues(sortKeyFromItem(element), insertedKey) >= 0 : compareValues(sortKeyFromItem(element), insertedKey) <= 0
168
+ );
169
+ const newPage = indexWithinPage === -1 ? [...pageToUpdate.value.page, item] : [
170
+ ...pageToUpdate.value.page.slice(0, indexWithinPage),
171
+ item,
172
+ ...pageToUpdate.value.page.slice(indexWithinPage)
173
+ ];
174
+ localQueryStore.setQuery(paginatedQuery, pageToUpdate.args, {
175
+ ...pageToUpdate.value,
176
+ page: newPage
177
+ });
178
+ }
@@ -0,0 +1,8 @@
1
+ import type { FunctionReference } from 'convex/server';
2
+ /**
3
+ * Stable Nuxt payload / useAsyncData key for a Convex query.
4
+ *
5
+ * `'skip'` means "don't fetch" — it must not change the key, otherwise
6
+ * auth-gated queries lose the SSR payload on the client.
7
+ */
8
+ export declare function convexQueryKey(query: FunctionReference<'query'>, args: unknown, explicitKey?: string): string;
@@ -0,0 +1,11 @@
1
+ import { getFunctionName } from "convex/server";
2
+ import { convexToJson } from "convex/values";
3
+ export function convexQueryKey(query, args, explicitKey) {
4
+ if (explicitKey) {
5
+ return explicitKey;
6
+ }
7
+ const name = getFunctionName(query);
8
+ const keyArgs = args === "skip" ? {} : args ?? {};
9
+ const argsJson = convexToJson(keyArgs);
10
+ return `convex:${name}:${JSON.stringify(argsJson)}`;
11
+ }
@@ -0,0 +1,29 @@
1
+ import type { ModulePublicRuntimeConfig } from './module.mjs'
2
+
3
+ declare module '@nuxt/schema' {
4
+ interface PublicRuntimeConfig extends ModulePublicRuntimeConfig {}
5
+ }
6
+
7
+ export { type AuthTokens, type SignInResult, type UseAuthReturn } from '../dist/runtime/composables/useAuth.js'
8
+
9
+ export { type ConvexQueryArgs, type UseConvexQueryOptions, type UseConvexQueryReturn } from '../dist/runtime/composables/useConvexQuery.js'
10
+
11
+ export { type AuthTokenFetcher, type UseConvexAuthReturn, type UseConvexAuthSetupOptions } from '../dist/runtime/composables/useConvexAuth.js'
12
+
13
+ export { type UseConvexMutationOptions } from '../dist/runtime/composables/useConvexMutation.js'
14
+
15
+ export { type PaginatedQueryReference, type PaginationStatus, type UseConvexPaginatedQueryOptions, type UseConvexPaginatedQueryReturn } from '../dist/runtime/composables/useConvexPaginatedQuery.js'
16
+
17
+ export { type ConvexQueriesRequest, type ConvexQueriesResult } from '../dist/runtime/composables/useConvexQueries.js'
18
+
19
+ export { type ConvexFetchOptions } from '../dist/runtime/server/fetch.js'
20
+
21
+ export { type ConvexAuthContext, type ConvexNuxtContext } from '../dist/runtime/utils/context.js'
22
+
23
+ export { type ConnectionState } from '../dist/runtime/composables/useConvexConnectionState.js'
24
+
25
+ export { type ConvexGate } from '../dist/runtime/composables/useConvexGate.js'
26
+
27
+ export { default } from './module.mjs'
28
+
29
+ export { type ModuleAuthOptions, type ModuleOptions, type ModulePublicRuntimeConfig } from './module.mjs'
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "use-convex",
3
+ "version": "0.0.2",
4
+ "description": "First-class Convex integration for Nuxt",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/jrmybtlr/convex-nuxt.git"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/module.d.mts",
17
+ "import": "./dist/module.mjs"
18
+ },
19
+ "./runtime/*": "./dist/runtime/*"
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "scripts": {
25
+ "build": "nuxt-module-build build",
26
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
27
+ "dev": "nuxi dev playground --dotenv .env.local",
28
+ "dev:backend": "cd playground && convex dev",
29
+ "build:playground": "nuxi build playground",
30
+ "typecheck": "vue-tsc --noEmit",
31
+ "test": "vitest run",
32
+ "test:watch": "vitest",
33
+ "test:e2e": "E2E_CONVEX=1 vitest run playground/e2e test/e2e",
34
+ "release": "semantic-release"
35
+ },
36
+ "peerDependencies": {
37
+ "convex": "^1.21.0",
38
+ "nuxt": "^4.0.0",
39
+ "vue": "^3.5.0"
40
+ },
41
+ "dependencies": {
42
+ "@nuxt/kit": "^4.0.0",
43
+ "defu": "^6.1.4",
44
+ "h3": "^1.15.0"
45
+ },
46
+ "devDependencies": {
47
+ "@auth/core": "0.41.1",
48
+ "@convex-dev/auth": "^0.0.95",
49
+ "@nuxt/module-builder": "^1.0.0",
50
+ "@nuxt/schema": "^4.0.0",
51
+ "@nuxt/test-utils": "^3.23.0",
52
+ "@types/node": "^26.5.0",
53
+ "convex": "^1.45.0",
54
+ "convex-helpers": "^0.1.124",
55
+ "convex-test": "^0.0.56",
56
+ "happy-dom": "^20.14.0",
57
+ "nitropack": "^2.13.0",
58
+ "nuxt": "^4.5.2",
59
+ "semantic-release": "^25.0.9",
60
+ "typescript": "^5.9.0",
61
+ "vitest": "^3.2.0",
62
+ "vue": "^3.5.0",
63
+ "vue-tsc": "^3.0.0"
64
+ },
65
+ "packageManager": "pnpm@10.0.0"
66
+ }