nuxt-convex-module 0.0.0
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/LICENSE +21 -0
- package/README.md +242 -0
- package/dist/chunks/index.mjs +64 -0
- package/dist/devtools-client/200.html +1 -0
- package/dist/devtools-client/404.html +1 -0
- package/dist/devtools-client/_nuxt/B29GGJ5n.js +1 -0
- package/dist/devtools-client/_nuxt/BSDEpQet.js +1 -0
- package/dist/devtools-client/_nuxt/BY23OQOo.js +1 -0
- package/dist/devtools-client/_nuxt/BZYRaL-G.js +1 -0
- package/dist/devtools-client/_nuxt/Byw6FxnC.js +1 -0
- package/dist/devtools-client/_nuxt/CJJ_hcZN.js +1 -0
- package/dist/devtools-client/_nuxt/CS6WMFOx.js +2 -0
- package/dist/devtools-client/_nuxt/CZbAGcNC.js +1 -0
- package/dist/devtools-client/_nuxt/Cr6_aklh.js +2 -0
- package/dist/devtools-client/_nuxt/DNfpyBVU.js +3 -0
- package/dist/devtools-client/_nuxt/DPWXUmcI.js +1 -0
- package/dist/devtools-client/_nuxt/builds/latest.json +1 -0
- package/dist/devtools-client/_nuxt/builds/meta/a7708498-bd09-4de2-b5ab-19b380293c77.json +1 -0
- package/dist/devtools-client/_nuxt/dy_xXcv9.js +1 -0
- package/dist/devtools-client/_nuxt/entry.DbTJhkHT.css +1 -0
- package/dist/devtools-client/_nuxt/error-404.CwGGO2Kz.css +1 -0
- package/dist/devtools-client/_nuxt/error-500.8ZJqCQm8.css +1 -0
- package/dist/devtools-client/_nuxt/ncgEdbEt.js +1 -0
- package/dist/devtools-client/_nuxt/queries.CE_dtt9-.css +1 -0
- package/dist/devtools-client/auth/index.html +1 -0
- package/dist/devtools-client/icon.svg +6 -0
- package/dist/devtools-client/index.html +1 -0
- package/dist/devtools-client/logs/index.html +1 -0
- package/dist/devtools-client/queries/index.html +1 -0
- package/dist/module.d.ts +189 -0
- package/dist/module.js +489 -0
- package/dist/module.json +13 -0
- package/dist/runtime/auth0/vue/index.d.ts +58 -0
- package/dist/runtime/auth0/vue/index.js +33 -0
- package/dist/runtime/better-auth/nuxt/middleware.d.ts +14 -0
- package/dist/runtime/better-auth/nuxt/middleware.js +39 -0
- package/dist/runtime/better-auth/nuxt/proxy.d.ts +6 -0
- package/dist/runtime/better-auth/nuxt/proxy.js +11 -0
- package/dist/runtime/better-auth/nuxt/server.d.ts +106 -0
- package/dist/runtime/better-auth/nuxt/server.js +123 -0
- package/dist/runtime/better-auth/vue/auth-boundary.d.ts +131 -0
- package/dist/runtime/better-auth/vue/auth-boundary.js +78 -0
- package/dist/runtime/better-auth/vue/client.d.ts +358 -0
- package/dist/runtime/better-auth/vue/client.js +5 -0
- package/dist/runtime/better-auth/vue/cross-domain.d.ts +39 -0
- package/dist/runtime/better-auth/vue/cross-domain.js +45 -0
- package/dist/runtime/better-auth/vue/hydration.d.ts +20 -0
- package/dist/runtime/better-auth/vue/hydration.js +52 -0
- package/dist/runtime/better-auth/vue/index.d.ts +12 -0
- package/dist/runtime/better-auth/vue/index.js +6 -0
- package/dist/runtime/better-auth/vue/plugin.client.d.ts +6 -0
- package/dist/runtime/better-auth/vue/plugin.client.js +32 -0
- package/dist/runtime/better-auth/vue/plugin.server.d.ts +24 -0
- package/dist/runtime/better-auth/vue/plugin.server.js +42 -0
- package/dist/runtime/better-auth/vue/use-auth.d.ts +92 -0
- package/dist/runtime/better-auth/vue/use-auth.js +82 -0
- package/dist/runtime/clerk/vue/index.d.ts +81 -0
- package/dist/runtime/clerk/vue/index.js +49 -0
- package/dist/runtime/devtools/bridge.d.ts +12 -0
- package/dist/runtime/devtools/bridge.js +191 -0
- package/dist/runtime/devtools/plugin.client.d.ts +8 -0
- package/dist/runtime/devtools/plugin.client.js +34 -0
- package/dist/runtime/devtools/types.d.ts +78 -0
- package/dist/runtime/devtools/types.js +0 -0
- package/dist/runtime/nuxt/composables/use-async-query.d.ts +144 -0
- package/dist/runtime/nuxt/composables/use-async-query.js +104 -0
- package/dist/runtime/nuxt/config.d.ts +7 -0
- package/dist/runtime/nuxt/config.js +12 -0
- package/dist/runtime/nuxt/index.d.ts +136 -0
- package/dist/runtime/nuxt/index.js +91 -0
- package/dist/runtime/polar/vue/components.d.ts +184 -0
- package/dist/runtime/polar/vue/components.js +115 -0
- package/dist/runtime/vue/auth/helpers.d.ts +67 -0
- package/dist/runtime/vue/auth/helpers.js +50 -0
- package/dist/runtime/vue/auth/index.d.ts +125 -0
- package/dist/runtime/vue/auth/index.js +97 -0
- package/dist/runtime/vue/client.d.ts +305 -0
- package/dist/runtime/vue/client.js +382 -0
- package/dist/runtime/vue/composables/use-action.d.ts +62 -0
- package/dist/runtime/vue/composables/use-action.js +13 -0
- package/dist/runtime/vue/composables/use-connection-state.d.ts +30 -0
- package/dist/runtime/vue/composables/use-connection-state.js +14 -0
- package/dist/runtime/vue/composables/use-mutation.d.ts +76 -0
- package/dist/runtime/vue/composables/use-mutation.js +34 -0
- package/dist/runtime/vue/composables/use-paginated-query.d.ts +132 -0
- package/dist/runtime/vue/composables/use-paginated-query.js +513 -0
- package/dist/runtime/vue/composables/use-queries.d.ts +62 -0
- package/dist/runtime/vue/composables/use-queries.js +37 -0
- package/dist/runtime/vue/composables/use-query.d.ts +87 -0
- package/dist/runtime/vue/composables/use-query.js +53 -0
- package/dist/runtime/vue/composables/use-storage-url.d.ts +46 -0
- package/dist/runtime/vue/composables/use-storage-url.js +9 -0
- package/dist/runtime/vue/composables/use-subscription.d.ts +15 -0
- package/dist/runtime/vue/composables/use-subscription.js +33 -0
- package/dist/runtime/vue/composables/use-upload-queue.d.ts +117 -0
- package/dist/runtime/vue/composables/use-upload-queue.js +115 -0
- package/dist/runtime/vue/composables/use-upload.d.ts +134 -0
- package/dist/runtime/vue/composables/use-upload.js +114 -0
- package/dist/runtime/vue/hydration.d.ts +66 -0
- package/dist/runtime/vue/hydration.js +46 -0
- package/dist/runtime/vue/index.d.ts +94 -0
- package/dist/runtime/vue/index.js +42 -0
- package/dist/runtime/vue/plugin.d.ts +18 -0
- package/dist/runtime/vue/plugin.js +16 -0
- package/dist/runtime/vue/provide.d.ts +39 -0
- package/dist/runtime/vue/provide.js +15 -0
- package/dist/runtime/vue/queries-observer.d.ts +41 -0
- package/dist/runtime/vue/queries-observer.js +126 -0
- package/dist/types.d.ts +3 -0
- package/package.json +233 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { FunctionReference } from 'convex/server';
|
|
2
|
+
import { type ComputedRef, type MaybeRefOrGetter } from 'vue';
|
|
3
|
+
/**
|
|
4
|
+
* The preloaded query payload, which should be passed to a client component
|
|
5
|
+
* and passed to {@link usePreloadedQuery}.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export type Preloaded<Query extends FunctionReference<'query'>> = {
|
|
10
|
+
__type: Query;
|
|
11
|
+
_name: string;
|
|
12
|
+
_argsJSON: string;
|
|
13
|
+
_valueJSON: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Load a reactive query within a Vue component using a `Preloaded` payload
|
|
17
|
+
* from the server returned by {@link preloadQuery}.
|
|
18
|
+
*
|
|
19
|
+
* This Vue composable contains internal state that will cause a rerender
|
|
20
|
+
* whenever the query result changes.
|
|
21
|
+
*
|
|
22
|
+
* Throws an error if no Convex client has been provided (see {@link useConvex}).
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```vue
|
|
26
|
+
* <script setup lang="ts">
|
|
27
|
+
* import { usePreloadedQuery } from '#imports'
|
|
28
|
+
*
|
|
29
|
+
* const props = defineProps<{
|
|
30
|
+
* preloaded: Preloaded<typeof api.tasks.list>
|
|
31
|
+
* }>()
|
|
32
|
+
*
|
|
33
|
+
* const tasks = usePreloadedQuery(props.preloaded)
|
|
34
|
+
* </script>
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @param preloadedQuery - The `Preloaded` query payload from the server.
|
|
38
|
+
* Accepts a ref, computed, or getter; a fresh payload re-subscribes with the
|
|
39
|
+
* new query and args.
|
|
40
|
+
* @returns a computed ref with the result of the query. Initially returns the
|
|
41
|
+
* result fetched by the server. Subsequently returns the result fetched by the client.
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export declare function usePreloadedQuery<Query extends FunctionReference<'query'>>(preloadedQuery: MaybeRefOrGetter<Preloaded<Query>>): ComputedRef<Query['_returnType']>;
|
|
46
|
+
/**
|
|
47
|
+
* Derive the query reference and reactive args/fallback from a (possibly
|
|
48
|
+
* reactive) `Preloaded` payload. All three are reactive: swapping in a payload
|
|
49
|
+
* for a different query re-derives the reference, matching upstream's
|
|
50
|
+
* `usePreloadedQuery`, which recomputes `makeFunctionReference(_name)` on
|
|
51
|
+
* every render.
|
|
52
|
+
*
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
export declare function usePreloadedPayload<Query extends FunctionReference<'query'>>(preloadedQuery: MaybeRefOrGetter<Preloaded<Query>>): {
|
|
56
|
+
query: ComputedRef<Query>;
|
|
57
|
+
args: ComputedRef<Query['_args']>;
|
|
58
|
+
preloadedResult: ComputedRef<Query['_returnType']>;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* A `useQuery` variant whose query *reference* is reactive alongside its args.
|
|
62
|
+
* Pass `'skip'` args to pause the subscription.
|
|
63
|
+
*
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
export declare function useReactiveQuery<Query extends FunctionReference<'query'>>(query: ComputedRef<Query>, args: ComputedRef<Query['_args'] | 'skip'>): ComputedRef<Query['_returnType'] | undefined>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { makeFunctionReference } from "convex/server";
|
|
2
|
+
import { jsonToConvex } from "convex/values";
|
|
3
|
+
import { computed, toValue } from "vue";
|
|
4
|
+
import { useConvexQueries } from "./composables/use-queries.js";
|
|
5
|
+
export function usePreloadedQuery(preloadedQuery) {
|
|
6
|
+
const { query, args, preloadedResult } = usePreloadedPayload(preloadedQuery);
|
|
7
|
+
if (import.meta.server) {
|
|
8
|
+
return preloadedResult;
|
|
9
|
+
}
|
|
10
|
+
const result = useReactiveQuery(query, args);
|
|
11
|
+
return computed(
|
|
12
|
+
() => result.value === void 0 ? preloadedResult.value : result.value
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
export function usePreloadedPayload(preloadedQuery) {
|
|
16
|
+
const args = computed(
|
|
17
|
+
() => jsonToConvex(toValue(preloadedQuery)._argsJSON)
|
|
18
|
+
);
|
|
19
|
+
const preloadedResult = computed(
|
|
20
|
+
() => jsonToConvex(toValue(preloadedQuery)._valueJSON)
|
|
21
|
+
);
|
|
22
|
+
const query = computed(
|
|
23
|
+
() => makeFunctionReference(toValue(preloadedQuery)._name)
|
|
24
|
+
);
|
|
25
|
+
return { query, args, preloadedResult };
|
|
26
|
+
}
|
|
27
|
+
export function useReactiveQuery(query, args) {
|
|
28
|
+
const queriesInput = computed(() => {
|
|
29
|
+
const currentArgs = args.value;
|
|
30
|
+
if (currentArgs === "skip") {
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
query: {
|
|
35
|
+
query: query.value,
|
|
36
|
+
args: currentArgs
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
const allResults = useConvexQueries(queriesInput);
|
|
41
|
+
return computed(() => {
|
|
42
|
+
const r = allResults.value.query;
|
|
43
|
+
if (r instanceof Error) throw r;
|
|
44
|
+
return r;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tools to integrate Convex into Vue applications.
|
|
3
|
+
*
|
|
4
|
+
* This module contains:
|
|
5
|
+
* 1. {@link ConvexVueClient}, a client for using Convex in Vue.
|
|
6
|
+
* 2. {@link ConvexClientKey}, an injection key that stores this client in Vue context.
|
|
7
|
+
* 3. {@link Authenticated}, {@link Unauthenticated}, {@link AuthLoading} and {@link AuthRefreshing} helper auth components.
|
|
8
|
+
* 4. Composables {@link useQuery}, {@link useMutation}, {@link useAction} and more for accessing this
|
|
9
|
+
* client from your Vue components.
|
|
10
|
+
*
|
|
11
|
+
* ## Usage
|
|
12
|
+
*
|
|
13
|
+
* ### Creating the client
|
|
14
|
+
*
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { ConvexVueClient } from "nuxt-convex-module/client";
|
|
17
|
+
*
|
|
18
|
+
* // typically loaded from an environment variable
|
|
19
|
+
* const address = "https://small-mouse-123.convex.cloud"
|
|
20
|
+
* const convex = new ConvexVueClient(address);
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* ### Storing the client in Vue context
|
|
24
|
+
*
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import { ConvexClientKey } from "nuxt-convex-module/client";
|
|
27
|
+
*
|
|
28
|
+
* // (the Nuxt module registers a plugin that does this automatically)
|
|
29
|
+
* app.provide(ConvexClientKey, convex);
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* ### Using the auth helpers
|
|
33
|
+
*
|
|
34
|
+
* ```typescript
|
|
35
|
+
* import { Authenticated, Unauthenticated, AuthLoading, AuthRefreshing } from "nuxt-convex-module/client";
|
|
36
|
+
*
|
|
37
|
+
* <Authenticated>
|
|
38
|
+
* Logged in
|
|
39
|
+
* </Authenticated>
|
|
40
|
+
* <Unauthenticated>
|
|
41
|
+
* Logged out
|
|
42
|
+
* </Unauthenticated>
|
|
43
|
+
* <AuthLoading>
|
|
44
|
+
* Still loading
|
|
45
|
+
* </AuthLoading>
|
|
46
|
+
* <AuthRefreshing>
|
|
47
|
+
* Refreshing token...
|
|
48
|
+
* </AuthRefreshing>
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* ### Using Vue composables
|
|
52
|
+
*
|
|
53
|
+
* ```typescript
|
|
54
|
+
* import { useQuery, useMutation } from "nuxt-convex-module/client";
|
|
55
|
+
* import { api } from "../convex/_generated/api";
|
|
56
|
+
*
|
|
57
|
+
* // In your component's <script setup>:
|
|
58
|
+
* const counter = useQuery(api.getCounter.default);
|
|
59
|
+
* const increment = useMutation(api.incrementCounter.default);
|
|
60
|
+
* // Your component here!
|
|
61
|
+
* ```
|
|
62
|
+
* @module client
|
|
63
|
+
*/
|
|
64
|
+
export * from './composables/use-paginated-query.js';
|
|
65
|
+
export { usePaginatedQuery_experimental, type UsePaginatedQueryOptions, type UsePaginatedQueryObjectReturnType, } from './composables/use-paginated-query.js';
|
|
66
|
+
export { usePaginatedQuery } from './composables/use-paginated-query.js';
|
|
67
|
+
export { useQueries, type RequestForQueries } from './composables/use-queries.js';
|
|
68
|
+
export type { AuthTokenFetcher } from 'convex/browser';
|
|
69
|
+
export * from './auth/helpers.js';
|
|
70
|
+
export * from './auth/index.js';
|
|
71
|
+
export { usePreloadedQuery, type Preloaded } from './hydration.js';
|
|
72
|
+
export { useSubscription } from './composables/use-subscription.js';
|
|
73
|
+
export { type VueMutation } from './composables/use-mutation.js';
|
|
74
|
+
export { type VueAction } from './composables/use-action.js';
|
|
75
|
+
export { type Watch, type WatchQueryOptions, type MutationOptions, type ConvexVueClientOptions, } from './client.js';
|
|
76
|
+
export { type OptionalRestArgsOrSkip, type UseQueryResult, } from './composables/use-query.js';
|
|
77
|
+
export { ConvexVueClient, useConvex, ConvexClientKey, } from './client.js';
|
|
78
|
+
export { useQuery, useQuery_experimental } from './composables/use-query.js';
|
|
79
|
+
export { useMutation } from './composables/use-mutation.js';
|
|
80
|
+
export { useAction } from './composables/use-action.js';
|
|
81
|
+
export { useConvexConnectionState } from './composables/use-connection-state.js';
|
|
82
|
+
export type { QueryOptions } from 'convex/browser';
|
|
83
|
+
export { useConvexQueries } from './composables/use-queries.js';
|
|
84
|
+
export { useConvexQuery } from './composables/use-query.js';
|
|
85
|
+
export { useConvexMutation } from './composables/use-mutation.js';
|
|
86
|
+
export { useConvexAction } from './composables/use-action.js';
|
|
87
|
+
export { type PaginatedWatch, type VueMutationOptions, type ConvexLogger, } from './client.js';
|
|
88
|
+
export type { ConnectionState, OptimisticUpdate, QueryJournal, } from 'convex/browser';
|
|
89
|
+
export type { FunctionReference, FunctionArgs, FunctionReturnType, OptionalRestArgs, ArgsAndOptions, } from 'convex/server';
|
|
90
|
+
export type { Value } from 'convex/values';
|
|
91
|
+
export { useUpload, useConvexUpload, uploadFile, type VueUpload, type UseUploadOptions, type UploadFileOptions, type GenerateUploadUrl, type StorageId, } from './composables/use-upload.js';
|
|
92
|
+
export { useUploadQueue, useConvexUploadQueue, type VueUploadQueue, type UseUploadQueueOptions, type UploadQueueItem, type UploadItemStatus, } from './composables/use-upload-queue.js';
|
|
93
|
+
export { useStorageUrl, useConvexStorageUrl, type GetStorageUrl, } from './composables/use-storage-url.js';
|
|
94
|
+
export { provideConvexApi, useConvexApi, useConvexNamespace, ConvexApiKey, type ConvexApi, } from './provide.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export * from "./composables/use-paginated-query.js";
|
|
2
|
+
export {
|
|
3
|
+
usePaginatedQuery_experimental
|
|
4
|
+
} from "./composables/use-paginated-query.js";
|
|
5
|
+
export { usePaginatedQuery } from "./composables/use-paginated-query.js";
|
|
6
|
+
export { useQueries } from "./composables/use-queries.js";
|
|
7
|
+
export * from "./auth/helpers.js";
|
|
8
|
+
export * from "./auth/index.js";
|
|
9
|
+
export { usePreloadedQuery } from "./hydration.js";
|
|
10
|
+
export { useSubscription } from "./composables/use-subscription.js";
|
|
11
|
+
export {
|
|
12
|
+
ConvexVueClient,
|
|
13
|
+
useConvex,
|
|
14
|
+
ConvexClientKey
|
|
15
|
+
} from "./client.js";
|
|
16
|
+
export { useQuery, useQuery_experimental } from "./composables/use-query.js";
|
|
17
|
+
export { useMutation } from "./composables/use-mutation.js";
|
|
18
|
+
export { useAction } from "./composables/use-action.js";
|
|
19
|
+
export { useConvexConnectionState } from "./composables/use-connection-state.js";
|
|
20
|
+
export { useConvexQueries } from "./composables/use-queries.js";
|
|
21
|
+
export { useConvexQuery } from "./composables/use-query.js";
|
|
22
|
+
export { useConvexMutation } from "./composables/use-mutation.js";
|
|
23
|
+
export { useConvexAction } from "./composables/use-action.js";
|
|
24
|
+
export {
|
|
25
|
+
useUpload,
|
|
26
|
+
useConvexUpload,
|
|
27
|
+
uploadFile
|
|
28
|
+
} from "./composables/use-upload.js";
|
|
29
|
+
export {
|
|
30
|
+
useUploadQueue,
|
|
31
|
+
useConvexUploadQueue
|
|
32
|
+
} from "./composables/use-upload-queue.js";
|
|
33
|
+
export {
|
|
34
|
+
useStorageUrl,
|
|
35
|
+
useConvexStorageUrl
|
|
36
|
+
} from "./composables/use-storage-url.js";
|
|
37
|
+
export {
|
|
38
|
+
provideConvexApi,
|
|
39
|
+
useConvexApi,
|
|
40
|
+
useConvexNamespace,
|
|
41
|
+
ConvexApiKey
|
|
42
|
+
} from "./provide.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Convex client bootstrap.
|
|
3
|
+
*
|
|
4
|
+
* Creates a {@link ConvexVueClient} from the configured deployment URL and
|
|
5
|
+
* provides it app-wide (server and client) so the data composables
|
|
6
|
+
* (`useQuery`, `useMutation`, `useAction`, ...) — and the Clerk / Auth0 auth
|
|
7
|
+
* adapters — can resolve a client via `useConvex()`.
|
|
8
|
+
*
|
|
9
|
+
* This runs only when no auth integration is managing the client. When Better
|
|
10
|
+
* Auth is installed, its own `plugin.client` / `plugin.server` create and
|
|
11
|
+
* provide the client (alongside session hydration), so the module registers
|
|
12
|
+
* those instead of this one — see `registerIntegrations` in `src/module.ts`.
|
|
13
|
+
*
|
|
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.
|
|
16
|
+
*/
|
|
17
|
+
declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
|
|
18
|
+
export default _default;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineNuxtPlugin, useRuntimeConfig } from "#app";
|
|
2
|
+
import { ConvexVueClient, ConvexClientKey } from "./client.js";
|
|
3
|
+
export default defineNuxtPlugin({
|
|
4
|
+
name: "nuxt-convex-module:client",
|
|
5
|
+
setup(nuxtApp) {
|
|
6
|
+
const url = useRuntimeConfig().public.convex.url;
|
|
7
|
+
if (!url) {
|
|
8
|
+
if (import.meta.client) {
|
|
9
|
+
console.warn("[nuxt-convex-module] No Convex URL configured; client not created.");
|
|
10
|
+
}
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const client = new ConvexVueClient(url);
|
|
14
|
+
nuxtApp.vueApp.provide(ConvexClientKey, client);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type App, type InjectionKey } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* The consumer's generated Convex `api` object (`#convex/api`). Its exact shape
|
|
4
|
+
* is app-specific, so it's kept loose here — composables and components cast the
|
|
5
|
+
* namespaces they consume (`api.billing`, `api.email`, …) to the precise
|
|
6
|
+
* `FunctionReference` types they expect.
|
|
7
|
+
*/
|
|
8
|
+
export type ConvexApi = Record<string, Record<string, unknown>>;
|
|
9
|
+
export declare const ConvexApiKey: InjectionKey<ConvexApi>;
|
|
10
|
+
/**
|
|
11
|
+
* Make the generated Convex `api` available to every `nuxt-convex-module` composable
|
|
12
|
+
* and component, so `useBilling()`, `<CheckoutLink>`, `useEmailStatus()`, … work
|
|
13
|
+
* with zero arguments.
|
|
14
|
+
*
|
|
15
|
+
* The packaged Nuxt plugin calls this automatically with `#convex/api`. Call it
|
|
16
|
+
* yourself (e.g. with a custom `api`) only to override that default — pass the
|
|
17
|
+
* Nuxt `vueApp` so the binding is available during SSR too:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* export default defineNuxtPlugin((nuxtApp) => {
|
|
21
|
+
* provideConvexApi(api, nuxtApp.vueApp)
|
|
22
|
+
* })
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function provideConvexApi(api: ConvexApi, app?: App): void;
|
|
26
|
+
/**
|
|
27
|
+
* The injected generated `api`, or `undefined` when it hasn't been provided
|
|
28
|
+
* (e.g. outside a setup context, or before Convex codegen has run). Prefer
|
|
29
|
+
* {@link useConvexNamespace} for feature access.
|
|
30
|
+
*/
|
|
31
|
+
export declare function useConvexApi(): ConvexApi | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* The named function group from the generated `api` (e.g. `'billing'`,
|
|
34
|
+
* `'email'`), or `undefined` when billing/email isn't scaffolded — letting the
|
|
35
|
+
* feature degrade to a graceful no-op rather than throwing.
|
|
36
|
+
*
|
|
37
|
+
* @typeParam T - The expected shape of the namespace's function references.
|
|
38
|
+
*/
|
|
39
|
+
export declare function useConvexNamespace<T = Record<string, unknown>>(name: string): T | undefined;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { hasInjectionContext, inject, provide } from "vue";
|
|
2
|
+
export const ConvexApiKey = Symbol("nuxt-convex-module:api");
|
|
3
|
+
export function provideConvexApi(api, app) {
|
|
4
|
+
if (app) app.provide(ConvexApiKey, api);
|
|
5
|
+
else provide(ConvexApiKey, api);
|
|
6
|
+
}
|
|
7
|
+
export function useConvexApi() {
|
|
8
|
+
if (!hasInjectionContext()) return void 0;
|
|
9
|
+
return inject(ConvexApiKey, void 0);
|
|
10
|
+
}
|
|
11
|
+
export function useConvexNamespace(name) {
|
|
12
|
+
const api = useConvexApi();
|
|
13
|
+
const namespace = api?.[name];
|
|
14
|
+
return namespace;
|
|
15
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type Value } from 'convex/values';
|
|
2
|
+
import type { PaginatedWatch, Watch } from './client.js';
|
|
3
|
+
import type { QueryJournal } from 'convex/browser';
|
|
4
|
+
import { type FunctionReference } from 'convex/server';
|
|
5
|
+
import type { RequestForQueries } from './composables/use-queries.js';
|
|
6
|
+
type PaginatedQueryResult<T> = NonNullable<ReturnType<PaginatedWatch<T>['localQueryResult']>>;
|
|
7
|
+
export interface SubscribeToPaginatedQueryOptions {
|
|
8
|
+
initialNumItems: number;
|
|
9
|
+
id: number;
|
|
10
|
+
}
|
|
11
|
+
type Identifier = string;
|
|
12
|
+
export interface CreateWatch {
|
|
13
|
+
(query: FunctionReference<'query'>, args: Record<string, Value>, options: {
|
|
14
|
+
journal?: QueryJournal;
|
|
15
|
+
paginationOptions?: SubscribeToPaginatedQueryOptions;
|
|
16
|
+
}): Watch<Value> | PaginatedWatch<Value>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A class for observing the results of multiple queries at the same time.
|
|
20
|
+
*
|
|
21
|
+
* Any time the result of a query changes, the listeners are notified.
|
|
22
|
+
*/
|
|
23
|
+
export declare class QueriesObserver {
|
|
24
|
+
createWatch: CreateWatch;
|
|
25
|
+
private queries;
|
|
26
|
+
private listeners;
|
|
27
|
+
constructor(createWatch: CreateWatch);
|
|
28
|
+
setQueries(newQueries: Record<Identifier, {
|
|
29
|
+
query: FunctionReference<'query'>;
|
|
30
|
+
args: Record<string, Value>;
|
|
31
|
+
paginationOptions?: SubscribeToPaginatedQueryOptions;
|
|
32
|
+
}>): void;
|
|
33
|
+
subscribe(listener: () => void): () => void;
|
|
34
|
+
getLocalResults(queries: RequestForQueries): Record<Identifier, Value | undefined | Error | PaginatedQueryResult<Value>>;
|
|
35
|
+
setCreateWatch(createWatch: CreateWatch): void;
|
|
36
|
+
destroy(): void;
|
|
37
|
+
private addQuery;
|
|
38
|
+
private removeQuery;
|
|
39
|
+
private notifyListeners;
|
|
40
|
+
}
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { convexToJson } from "convex/values";
|
|
2
|
+
import { getFunctionName } from "convex/server";
|
|
3
|
+
export class QueriesObserver {
|
|
4
|
+
createWatch;
|
|
5
|
+
queries;
|
|
6
|
+
listeners;
|
|
7
|
+
constructor(createWatch) {
|
|
8
|
+
this.createWatch = createWatch;
|
|
9
|
+
this.queries = {};
|
|
10
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
11
|
+
}
|
|
12
|
+
setQueries(newQueries) {
|
|
13
|
+
for (const identifier of Object.keys(newQueries)) {
|
|
14
|
+
const { query, args, paginationOptions } = newQueries[identifier];
|
|
15
|
+
getFunctionName(query);
|
|
16
|
+
if (this.queries[identifier] === void 0) {
|
|
17
|
+
this.addQuery(
|
|
18
|
+
identifier,
|
|
19
|
+
query,
|
|
20
|
+
args,
|
|
21
|
+
paginationOptions ? { paginationOptions } : {}
|
|
22
|
+
);
|
|
23
|
+
} else {
|
|
24
|
+
const existingInfo = this.queries[identifier];
|
|
25
|
+
if (getFunctionName(query) !== getFunctionName(existingInfo.query) || JSON.stringify(convexToJson(args)) !== JSON.stringify(convexToJson(existingInfo.args)) || JSON.stringify(paginationOptions) !== JSON.stringify(existingInfo.paginationOptions)) {
|
|
26
|
+
this.removeQuery(identifier);
|
|
27
|
+
this.addQuery(
|
|
28
|
+
identifier,
|
|
29
|
+
query,
|
|
30
|
+
args,
|
|
31
|
+
paginationOptions ? { paginationOptions } : {}
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
for (const identifier of Object.keys(this.queries)) {
|
|
37
|
+
if (newQueries[identifier] === void 0) {
|
|
38
|
+
this.removeQuery(identifier);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
subscribe(listener) {
|
|
43
|
+
this.listeners.add(listener);
|
|
44
|
+
return () => {
|
|
45
|
+
this.listeners.delete(listener);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
getLocalResults(queries) {
|
|
49
|
+
const result = {};
|
|
50
|
+
for (const identifier of Object.keys(queries)) {
|
|
51
|
+
const { query, args } = queries[identifier];
|
|
52
|
+
const paginationOptions = queries[identifier].paginationOptions;
|
|
53
|
+
getFunctionName(query);
|
|
54
|
+
const watch = this.createWatch(
|
|
55
|
+
query,
|
|
56
|
+
args,
|
|
57
|
+
paginationOptions ? { paginationOptions } : {}
|
|
58
|
+
);
|
|
59
|
+
let value;
|
|
60
|
+
try {
|
|
61
|
+
value = watch.localQueryResult();
|
|
62
|
+
} catch (e) {
|
|
63
|
+
if (e instanceof Error) {
|
|
64
|
+
value = e;
|
|
65
|
+
} else {
|
|
66
|
+
throw e;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
result[identifier] = value;
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
setCreateWatch(createWatch) {
|
|
74
|
+
this.createWatch = createWatch;
|
|
75
|
+
for (const identifier of Object.keys(this.queries)) {
|
|
76
|
+
const { query, args, watch, paginationOptions } = this.queries[identifier];
|
|
77
|
+
const journal = "journal" in watch ? watch.journal() : void 0;
|
|
78
|
+
this.removeQuery(identifier);
|
|
79
|
+
this.addQuery(identifier, query, args, {
|
|
80
|
+
...journal ? { journal } : [],
|
|
81
|
+
...paginationOptions ? { paginationOptions } : {}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
destroy() {
|
|
86
|
+
for (const identifier of Object.keys(this.queries)) {
|
|
87
|
+
this.removeQuery(identifier);
|
|
88
|
+
}
|
|
89
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
90
|
+
}
|
|
91
|
+
addQuery(identifier, query, args, {
|
|
92
|
+
paginationOptions,
|
|
93
|
+
journal
|
|
94
|
+
}) {
|
|
95
|
+
if (this.queries[identifier] !== void 0) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`Tried to add a new query with identifier ${identifier} when it already exists.`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
const watch = this.createWatch(query, args, {
|
|
101
|
+
...journal ? { journal } : [],
|
|
102
|
+
...paginationOptions ? { paginationOptions } : {}
|
|
103
|
+
});
|
|
104
|
+
const unsubscribe = watch.onUpdate(() => this.notifyListeners());
|
|
105
|
+
this.queries[identifier] = {
|
|
106
|
+
query,
|
|
107
|
+
args,
|
|
108
|
+
watch,
|
|
109
|
+
unsubscribe,
|
|
110
|
+
...paginationOptions ? { paginationOptions } : {}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
removeQuery(identifier) {
|
|
114
|
+
const info = this.queries[identifier];
|
|
115
|
+
if (info === void 0) {
|
|
116
|
+
throw new Error(`No query found with identifier ${identifier}.`);
|
|
117
|
+
}
|
|
118
|
+
info.unsubscribe();
|
|
119
|
+
delete this.queries[identifier];
|
|
120
|
+
}
|
|
121
|
+
notifyListeners() {
|
|
122
|
+
for (const listener of this.listeners) {
|
|
123
|
+
listener();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { type applyConvexSecurityDefaults, type convexConnectSrc, type convexResourceSrc, type convexTypeFallbackContents, default, type formatStartupSummary, type getConvexAliases, type resolveIntegrationState, type validateModuleOptions } from './module.js'
|
|
2
|
+
|
|
3
|
+
export { type BetterAuthModuleOptions, type IntegrationFlags, type ModuleOptionDiagnostics, type ModuleOptions } from './module.js'
|