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,305 @@
|
|
|
1
|
+
import type { InjectionKey } from 'vue';
|
|
2
|
+
import { BaseConvexClient } from 'convex/browser';
|
|
3
|
+
import type { AuthTokenFetcher, BaseConvexClientOptions, ConnectionState, OptimisticUpdate, PaginationStatus, QueryJournal, QueryOptions } from 'convex/browser';
|
|
4
|
+
import type { Watch as ConvexWatch } from 'convex/react';
|
|
5
|
+
import type { ArgsAndOptions, FunctionArgs, FunctionReference, FunctionReturnType, OptionalRestArgs, UserIdentityAttributes } from 'convex/server';
|
|
6
|
+
import type { Value } from 'convex/values';
|
|
7
|
+
export type { AuthTokenFetcher, ConnectionState, OptimisticUpdate };
|
|
8
|
+
/**
|
|
9
|
+
* A watch on the output of a Convex query function.
|
|
10
|
+
*
|
|
11
|
+
* Derived from upstream's `Watch` (per-member docs live there), extended with
|
|
12
|
+
* the `@internal` `localQueryLogs`, which is stripped from the published
|
|
13
|
+
* `convex/react` types but present at runtime.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export interface Watch<T> extends ConvexWatch<T> {
|
|
18
|
+
/**
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
localQueryLogs(): string[] | undefined;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A watch on the output of a paginated Convex query function.
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export interface PaginatedWatch<T> {
|
|
29
|
+
/**
|
|
30
|
+
* Initiate a watch on the output of a paginated query.
|
|
31
|
+
*
|
|
32
|
+
* This will subscribe to this query and call
|
|
33
|
+
* the callback whenever the query result changes.
|
|
34
|
+
*
|
|
35
|
+
* @param callback - Function that is called whenever the query result changes.
|
|
36
|
+
* @returns - A function that disposes of the subscription.
|
|
37
|
+
*/
|
|
38
|
+
onUpdate(callback: () => void): () => void;
|
|
39
|
+
/**
|
|
40
|
+
* Get the current result of a paginated query.
|
|
41
|
+
*
|
|
42
|
+
* @returns The current results, status, and loadMore function, or `undefined` if not loaded.
|
|
43
|
+
*/
|
|
44
|
+
localQueryResult(): {
|
|
45
|
+
results: T[];
|
|
46
|
+
status: PaginationStatus;
|
|
47
|
+
loadMore: (numItems: number) => boolean;
|
|
48
|
+
} | undefined;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Options for {@link ConvexVueClient.watchQuery}.
|
|
52
|
+
*
|
|
53
|
+
* @public
|
|
54
|
+
*/
|
|
55
|
+
export interface WatchQueryOptions {
|
|
56
|
+
/**
|
|
57
|
+
* An (optional) journal produced from a previous execution of this query
|
|
58
|
+
* function.
|
|
59
|
+
*
|
|
60
|
+
* If there is an existing subscription to a query function with the same
|
|
61
|
+
* name and arguments, this journal will have no effect.
|
|
62
|
+
*/
|
|
63
|
+
journal?: QueryJournal;
|
|
64
|
+
/**
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
componentPath?: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Options for {@link ConvexVueClient.mutation}.
|
|
71
|
+
*
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
export interface MutationOptions<Args extends Record<string, Value>> {
|
|
75
|
+
/**
|
|
76
|
+
* An optimistic update to apply along with this mutation.
|
|
77
|
+
*
|
|
78
|
+
* An optimistic update locally updates queries while a mutation is pending.
|
|
79
|
+
* Once the mutation completes, the update will be rolled back.
|
|
80
|
+
*/
|
|
81
|
+
optimisticUpdate?: OptimisticUpdate<Args> | undefined;
|
|
82
|
+
}
|
|
83
|
+
export type VueMutationOptions<Args extends Record<string, Value>> = MutationOptions<Args>;
|
|
84
|
+
/**
|
|
85
|
+
* Options for {@link ConvexVueClient}.
|
|
86
|
+
*
|
|
87
|
+
* @public
|
|
88
|
+
*/
|
|
89
|
+
export interface ConvexVueClientOptions extends BaseConvexClientOptions {
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The logger type accepted by {@link ConvexVueClientOptions.logger} — the
|
|
93
|
+
* public shape of convex's non-exported `Logger`.
|
|
94
|
+
*
|
|
95
|
+
* @public
|
|
96
|
+
*/
|
|
97
|
+
export type ConvexLogger = Exclude<BaseConvexClientOptions['logger'], boolean | undefined>;
|
|
98
|
+
/**
|
|
99
|
+
* A Convex client for use within Vue.
|
|
100
|
+
*
|
|
101
|
+
* This loads reactive queries and executes mutations over a WebSocket.
|
|
102
|
+
*
|
|
103
|
+
* In a Nuxt app the client is provided automatically by the plugin and
|
|
104
|
+
* available via the {@link useConvex} composable or `useNuxtApp().$convex`.
|
|
105
|
+
*
|
|
106
|
+
* @public
|
|
107
|
+
*/
|
|
108
|
+
export declare class ConvexVueClient {
|
|
109
|
+
private address;
|
|
110
|
+
private cachedSync?;
|
|
111
|
+
private listeners;
|
|
112
|
+
private options;
|
|
113
|
+
private closed;
|
|
114
|
+
private _logger;
|
|
115
|
+
private adminAuth?;
|
|
116
|
+
private fakeUserIdentity?;
|
|
117
|
+
/**
|
|
118
|
+
* @param address - The url of your Convex deployment, often provided
|
|
119
|
+
* by an environment variable. E.g. `https://small-mouse-123.convex.cloud`.
|
|
120
|
+
* @param options - See {@link ConvexVueClientOptions} for a full description.
|
|
121
|
+
*/
|
|
122
|
+
constructor(address: string, options?: ConvexVueClientOptions);
|
|
123
|
+
/**
|
|
124
|
+
* Return the address for this client, useful for creating a new client.
|
|
125
|
+
*
|
|
126
|
+
* Not guaranteed to match the address with which this client was constructed:
|
|
127
|
+
* it may be canonicalized.
|
|
128
|
+
*/
|
|
129
|
+
get url(): string;
|
|
130
|
+
/**
|
|
131
|
+
* Lazily instantiate the `BaseConvexClient` so we don't create the WebSocket
|
|
132
|
+
* when server-side rendering.
|
|
133
|
+
*
|
|
134
|
+
* @internal
|
|
135
|
+
*/
|
|
136
|
+
get sync(): BaseConvexClient;
|
|
137
|
+
/**
|
|
138
|
+
* Set the authentication token to be used for subsequent queries and mutations.
|
|
139
|
+
* `fetchToken` will be called automatically again if a token expires.
|
|
140
|
+
* `fetchToken` should return `null` if the token cannot be retrieved, for example
|
|
141
|
+
* when the user's rights were permanently revoked.
|
|
142
|
+
* @param fetchToken - an async function returning the JWT-encoded OpenID Connect Identity Token
|
|
143
|
+
* @param onChange - a callback that will be called when the authentication status changes
|
|
144
|
+
* @param onRefreshChange - a callback called with `true` when the socket is paused to fetch a replacement token after a server rejection, and `false` when refresh completes
|
|
145
|
+
*/
|
|
146
|
+
setAuth(fetchToken: AuthTokenFetcher, onChange?: (isAuthenticated: boolean) => void, onRefreshChange?: (isRefreshing: boolean) => void): void;
|
|
147
|
+
/**
|
|
148
|
+
* Clear the current authentication token if set.
|
|
149
|
+
*/
|
|
150
|
+
clearAuth(): void;
|
|
151
|
+
/**
|
|
152
|
+
* @internal
|
|
153
|
+
*/
|
|
154
|
+
setAdminAuth(token: string, identity?: UserIdentityAttributes): void;
|
|
155
|
+
/**
|
|
156
|
+
* Construct a new {@link Watch} on a Convex query function.
|
|
157
|
+
*
|
|
158
|
+
* **Most application code should not call this method directly. Instead use
|
|
159
|
+
* the {@link useQuery} composable.**
|
|
160
|
+
*
|
|
161
|
+
* The act of creating a watch does nothing, a Watch is stateless.
|
|
162
|
+
*
|
|
163
|
+
* @param query - A {@link server.FunctionReference} for the public query to run.
|
|
164
|
+
* @param args - An arguments object for the query. If this is omitted,
|
|
165
|
+
* the arguments will be `{}`.
|
|
166
|
+
* @param options - A {@link WatchQueryOptions} options object for this query.
|
|
167
|
+
*
|
|
168
|
+
* @returns The {@link Watch} object.
|
|
169
|
+
*/
|
|
170
|
+
watchQuery<Query extends FunctionReference<'query'>>(query: Query, ...argsAndOptions: ArgsAndOptions<Query, WatchQueryOptions>): Watch<FunctionReturnType<Query>>;
|
|
171
|
+
/**
|
|
172
|
+
* Indicates likely future interest in a query subscription.
|
|
173
|
+
*
|
|
174
|
+
* The implementation currently immediately subscribes to a query. In the future this method
|
|
175
|
+
* may prioritize some queries over others, fetch the query result without subscribing, or
|
|
176
|
+
* do nothing in slow network connections or high load scenarios.
|
|
177
|
+
*
|
|
178
|
+
* To use this in a Vue component, call useQuery() and ignore the return value.
|
|
179
|
+
*
|
|
180
|
+
* @param queryOptions - A query (function reference from an api object) and its args, plus
|
|
181
|
+
* an optional extendSubscriptionFor for how long to subscribe to the query.
|
|
182
|
+
*/
|
|
183
|
+
prewarmQuery<Query extends FunctionReference<'query'>>(queryOptions: QueryOptions<Query> & {
|
|
184
|
+
extendSubscriptionFor?: number;
|
|
185
|
+
}): void;
|
|
186
|
+
/**
|
|
187
|
+
* Construct a new {@link PaginatedWatch} on a Convex paginated query function.
|
|
188
|
+
*
|
|
189
|
+
* **Not supported in the Vue port — use the {@link usePaginatedQuery}
|
|
190
|
+
* composable instead.** Convex's paginated-subscription engine
|
|
191
|
+
* (`PaginatedQueryClient`) is not part of the public `convex` exports, so a
|
|
192
|
+
* third-party package cannot instantiate it; pagination is handled entirely
|
|
193
|
+
* in the composable layer via ordinary {@link watchQuery} subscriptions.
|
|
194
|
+
*
|
|
195
|
+
* The method is retained for structural parity with
|
|
196
|
+
* `ConvexReactClient.watchPaginatedQuery`. It is reachable only if a caller
|
|
197
|
+
* passes `paginationOptions` to {@link useConvexQueries} (the React-shaped
|
|
198
|
+
* escape hatch); doing so throws this error to fail loudly rather than
|
|
199
|
+
* silently mis-subscribe.
|
|
200
|
+
*
|
|
201
|
+
* Upstream wires {@link usePaginatedQuery_experimental} to this method's
|
|
202
|
+
* `PaginatedQueryClient`; the port re-bases that hook on the same manual
|
|
203
|
+
* page-management engine as {@link usePaginatedQuery}, so both hooks work
|
|
204
|
+
* without ever calling this method (only the experimental single-request
|
|
205
|
+
* network path is not reproduced).
|
|
206
|
+
*
|
|
207
|
+
* @internal
|
|
208
|
+
*/
|
|
209
|
+
watchPaginatedQuery<Query extends FunctionReference<'query'>>(_query: Query, _args: Query['_args'], _options: unknown): PaginatedWatch<FunctionReturnType<Query>>;
|
|
210
|
+
/**
|
|
211
|
+
* Execute a mutation function.
|
|
212
|
+
*
|
|
213
|
+
* @param mutation - A {@link server.FunctionReference} for the public mutation
|
|
214
|
+
* to run.
|
|
215
|
+
* @param args - An arguments object for the mutation. If this is omitted,
|
|
216
|
+
* the arguments will be `{}`.
|
|
217
|
+
* @param options - A {@link MutationOptions} options object for the mutation.
|
|
218
|
+
* @returns A promise of the mutation's result.
|
|
219
|
+
*/
|
|
220
|
+
mutation<Mutation extends FunctionReference<'mutation'>>(mutation: Mutation, ...argsAndOptions: ArgsAndOptions<Mutation, MutationOptions<FunctionArgs<Mutation>>>): Promise<FunctionReturnType<Mutation>>;
|
|
221
|
+
/**
|
|
222
|
+
* Execute an action function.
|
|
223
|
+
*
|
|
224
|
+
* @param action - A {@link server.FunctionReference} for the public action
|
|
225
|
+
* to run.
|
|
226
|
+
* @param args - An arguments object for the action. If this is omitted,
|
|
227
|
+
* the arguments will be `{}`.
|
|
228
|
+
* @returns A promise of the action's result.
|
|
229
|
+
*/
|
|
230
|
+
action<Action extends FunctionReference<'action'>>(action: Action, ...args: OptionalRestArgs<Action>): Promise<FunctionReturnType<Action>>;
|
|
231
|
+
/**
|
|
232
|
+
* Fetch a query result once.
|
|
233
|
+
*
|
|
234
|
+
* **Most application code should subscribe to queries instead, using
|
|
235
|
+
* the {@link useQuery} composable.**
|
|
236
|
+
*
|
|
237
|
+
* @param query - A {@link server.FunctionReference} for the public query
|
|
238
|
+
* to run.
|
|
239
|
+
* @param args - An arguments object for the query. If this is omitted,
|
|
240
|
+
* the arguments will be `{}`.
|
|
241
|
+
* @returns A promise of the query's result.
|
|
242
|
+
*/
|
|
243
|
+
query<Query extends FunctionReference<'query'>>(query: Query, ...args: OptionalRestArgs<Query>): Promise<FunctionReturnType<Query>>;
|
|
244
|
+
/**
|
|
245
|
+
* Get the current {@link ConnectionState} between the client and the Convex
|
|
246
|
+
* deployment.
|
|
247
|
+
*
|
|
248
|
+
* @returns The {@link ConnectionState} with the Convex deployment.
|
|
249
|
+
*/
|
|
250
|
+
connectionState(): ConnectionState;
|
|
251
|
+
/**
|
|
252
|
+
* Subscribe to the {@link ConnectionState} between the client and the Convex
|
|
253
|
+
* deployment, calling a callback each time it changes.
|
|
254
|
+
*
|
|
255
|
+
* Subscribed callbacks will be called when any part of ConnectionState changes.
|
|
256
|
+
* ConnectionState may grow in future versions (e.g. to provide a array of
|
|
257
|
+
* inflight requests) in which case callbacks would be called more frequently.
|
|
258
|
+
* ConnectionState may also *lose* properties in future versions as we figure
|
|
259
|
+
* out what information is most useful. As such this API is considered unstable.
|
|
260
|
+
*
|
|
261
|
+
* @returns An unsubscribe function to stop listening.
|
|
262
|
+
*/
|
|
263
|
+
subscribeToConnectionState(cb: (connectionState: ConnectionState) => void): () => void;
|
|
264
|
+
/**
|
|
265
|
+
* Get the logger for this client.
|
|
266
|
+
*
|
|
267
|
+
* @returns The {@link ConvexLogger} for this client.
|
|
268
|
+
*/
|
|
269
|
+
get logger(): ConvexLogger;
|
|
270
|
+
/**
|
|
271
|
+
* Close any network handles associated with this client and stop all subscriptions.
|
|
272
|
+
*
|
|
273
|
+
* Call this method when you're done with a {@link ConvexVueClient} to
|
|
274
|
+
* dispose of its sockets and resources.
|
|
275
|
+
*
|
|
276
|
+
* @returns A `Promise` fulfilled when the connection has been completely closed.
|
|
277
|
+
*/
|
|
278
|
+
close(): Promise<void>;
|
|
279
|
+
private transition;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Vue injection key for the {@link ConvexVueClient}.
|
|
283
|
+
*
|
|
284
|
+
* @public
|
|
285
|
+
*/
|
|
286
|
+
export declare const ConvexClientKey: InjectionKey<ConvexVueClient>;
|
|
287
|
+
/**
|
|
288
|
+
* Get the {@link ConvexVueClient} within a Vue component.
|
|
289
|
+
*
|
|
290
|
+
* This relies on the client having been provided under {@link ConvexClientKey}
|
|
291
|
+
* (the Nuxt plugin does this automatically).
|
|
292
|
+
*
|
|
293
|
+
* @returns The active {@link ConvexVueClient} object, or `undefined`.
|
|
294
|
+
*
|
|
295
|
+
* @public
|
|
296
|
+
*/
|
|
297
|
+
export declare function useConvex(): ConvexVueClient;
|
|
298
|
+
/**
|
|
299
|
+
* Inject the Convex client for a composable, throwing the per-composable
|
|
300
|
+
* missing-client error when absent — mirrors the checks at the top of
|
|
301
|
+
* upstream's `useQuery`/`useMutation`/`useAction`/`useConvexConnectionState`.
|
|
302
|
+
*
|
|
303
|
+
* @internal
|
|
304
|
+
*/
|
|
305
|
+
export declare function useConvexOrThrow(composableName: string): ConvexVueClient;
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import { inject } from "vue";
|
|
2
|
+
import { BaseConvexClient } from "convex/browser";
|
|
3
|
+
import { getFunctionName } from "convex/server";
|
|
4
|
+
const DEFAULT_EXTEND_SUBSCRIPTION_FOR = 5e3;
|
|
5
|
+
function instantiateNoopLogger(_options) {
|
|
6
|
+
return {
|
|
7
|
+
logVerbose() {
|
|
8
|
+
},
|
|
9
|
+
log() {
|
|
10
|
+
},
|
|
11
|
+
warn() {
|
|
12
|
+
},
|
|
13
|
+
error() {
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function instantiateDefaultLogger({ verbose }) {
|
|
18
|
+
return {
|
|
19
|
+
logVerbose: (...args) => {
|
|
20
|
+
if (verbose) console.debug(...args);
|
|
21
|
+
},
|
|
22
|
+
log: (...args) => console.log(...args),
|
|
23
|
+
warn: (...args) => console.warn(...args),
|
|
24
|
+
error: (...args) => console.error(...args)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export class ConvexVueClient {
|
|
28
|
+
address;
|
|
29
|
+
cachedSync;
|
|
30
|
+
// No `cachedPaginatedQueryClient`: convex's `PaginatedQueryClient` is not a
|
|
31
|
+
// public export — pagination lives in the `usePaginatedQuery` composable
|
|
32
|
+
// layer (see {@link watchPaginatedQuery}). `PaginatedQueryToken` is likewise
|
|
33
|
+
// not exported, so listener keys are plain `QueryToken`s.
|
|
34
|
+
listeners;
|
|
35
|
+
options;
|
|
36
|
+
// "closed" means this client is done, not just that the underlying WS connection is closed.
|
|
37
|
+
closed = false;
|
|
38
|
+
_logger;
|
|
39
|
+
adminAuth;
|
|
40
|
+
fakeUserIdentity;
|
|
41
|
+
/**
|
|
42
|
+
* @param address - The url of your Convex deployment, often provided
|
|
43
|
+
* by an environment variable. E.g. `https://small-mouse-123.convex.cloud`.
|
|
44
|
+
* @param options - See {@link ConvexVueClientOptions} for a full description.
|
|
45
|
+
*/
|
|
46
|
+
constructor(address, options) {
|
|
47
|
+
if (address === void 0) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
"No address provided to ConvexVueClient.\nIf trying to deploy to production, make sure to follow all the instructions found at https://docs.convex.dev/production/hosting/\nIf running locally, make sure to run `convex dev` and ensure the .env.local file is populated."
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
if (typeof address !== "string") {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`ConvexVueClient requires a URL like 'https://happy-otter-123.convex.cloud', received something of type ${typeof address} instead.`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
if (!address.includes("://")) {
|
|
58
|
+
throw new Error("Provided address was not an absolute URL.");
|
|
59
|
+
}
|
|
60
|
+
this.address = address;
|
|
61
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
62
|
+
this._logger = options?.logger === false ? instantiateNoopLogger({ verbose: options?.verbose ?? false }) : options?.logger !== true && options?.logger ? options.logger : instantiateDefaultLogger({ verbose: options?.verbose ?? false });
|
|
63
|
+
this.options = { ...options, logger: this._logger };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Return the address for this client, useful for creating a new client.
|
|
67
|
+
*
|
|
68
|
+
* Not guaranteed to match the address with which this client was constructed:
|
|
69
|
+
* it may be canonicalized.
|
|
70
|
+
*/
|
|
71
|
+
get url() {
|
|
72
|
+
return this.address;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Lazily instantiate the `BaseConvexClient` so we don't create the WebSocket
|
|
76
|
+
* when server-side rendering.
|
|
77
|
+
*
|
|
78
|
+
* @internal
|
|
79
|
+
*/
|
|
80
|
+
get sync() {
|
|
81
|
+
if (this.closed) {
|
|
82
|
+
throw new Error("ConvexVueClient has already been closed.");
|
|
83
|
+
}
|
|
84
|
+
if (this.cachedSync) {
|
|
85
|
+
return this.cachedSync;
|
|
86
|
+
}
|
|
87
|
+
this.cachedSync = new BaseConvexClient(
|
|
88
|
+
this.address,
|
|
89
|
+
(updatedQueries) => this.transition(updatedQueries),
|
|
90
|
+
this.options
|
|
91
|
+
);
|
|
92
|
+
if (this.adminAuth) {
|
|
93
|
+
const sync = this.cachedSync;
|
|
94
|
+
sync.setAdminAuth(this.adminAuth, this.fakeUserIdentity);
|
|
95
|
+
}
|
|
96
|
+
return this.cachedSync;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Set the authentication token to be used for subsequent queries and mutations.
|
|
100
|
+
* `fetchToken` will be called automatically again if a token expires.
|
|
101
|
+
* `fetchToken` should return `null` if the token cannot be retrieved, for example
|
|
102
|
+
* when the user's rights were permanently revoked.
|
|
103
|
+
* @param fetchToken - an async function returning the JWT-encoded OpenID Connect Identity Token
|
|
104
|
+
* @param onChange - a callback that will be called when the authentication status changes
|
|
105
|
+
* @param onRefreshChange - a callback called with `true` when the socket is paused to fetch a replacement token after a server rejection, and `false` when refresh completes
|
|
106
|
+
*/
|
|
107
|
+
setAuth(fetchToken, onChange, onRefreshChange) {
|
|
108
|
+
if (typeof fetchToken === "string") {
|
|
109
|
+
throw new Error(
|
|
110
|
+
"Passing a string to ConvexVueClient.setAuth is no longer supported, please upgrade to passing in an async function to handle reauthentication."
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
this.sync.setAuth(
|
|
114
|
+
fetchToken,
|
|
115
|
+
onChange ?? (() => {
|
|
116
|
+
}),
|
|
117
|
+
onRefreshChange
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Clear the current authentication token if set.
|
|
122
|
+
*/
|
|
123
|
+
clearAuth() {
|
|
124
|
+
this.sync.clearAuth();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* @internal
|
|
128
|
+
*/
|
|
129
|
+
setAdminAuth(token, identity) {
|
|
130
|
+
this.adminAuth = token;
|
|
131
|
+
this.fakeUserIdentity = identity;
|
|
132
|
+
if (this.closed) {
|
|
133
|
+
throw new Error("ConvexVueClient has already been closed.");
|
|
134
|
+
}
|
|
135
|
+
if (this.cachedSync) {
|
|
136
|
+
const sync = this.sync;
|
|
137
|
+
sync.setAdminAuth(token, identity);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Construct a new {@link Watch} on a Convex query function.
|
|
142
|
+
*
|
|
143
|
+
* **Most application code should not call this method directly. Instead use
|
|
144
|
+
* the {@link useQuery} composable.**
|
|
145
|
+
*
|
|
146
|
+
* The act of creating a watch does nothing, a Watch is stateless.
|
|
147
|
+
*
|
|
148
|
+
* @param query - A {@link server.FunctionReference} for the public query to run.
|
|
149
|
+
* @param args - An arguments object for the query. If this is omitted,
|
|
150
|
+
* the arguments will be `{}`.
|
|
151
|
+
* @param options - A {@link WatchQueryOptions} options object for this query.
|
|
152
|
+
*
|
|
153
|
+
* @returns The {@link Watch} object.
|
|
154
|
+
*/
|
|
155
|
+
watchQuery(query, ...argsAndOptions) {
|
|
156
|
+
const [args, options] = argsAndOptions;
|
|
157
|
+
const name = getFunctionName(query);
|
|
158
|
+
return {
|
|
159
|
+
onUpdate: (callback) => {
|
|
160
|
+
const { queryToken, unsubscribe } = this.sync.subscribe(
|
|
161
|
+
name,
|
|
162
|
+
args,
|
|
163
|
+
options
|
|
164
|
+
);
|
|
165
|
+
const currentListeners = this.listeners.get(queryToken);
|
|
166
|
+
if (currentListeners !== void 0) {
|
|
167
|
+
currentListeners.add(callback);
|
|
168
|
+
} else {
|
|
169
|
+
this.listeners.set(queryToken, /* @__PURE__ */ new Set([callback]));
|
|
170
|
+
}
|
|
171
|
+
return () => {
|
|
172
|
+
if (this.closed) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const currentListeners2 = this.listeners.get(queryToken);
|
|
176
|
+
currentListeners2.delete(callback);
|
|
177
|
+
if (currentListeners2.size === 0) {
|
|
178
|
+
this.listeners.delete(queryToken);
|
|
179
|
+
}
|
|
180
|
+
unsubscribe();
|
|
181
|
+
};
|
|
182
|
+
},
|
|
183
|
+
localQueryResult: () => {
|
|
184
|
+
if (this.cachedSync) {
|
|
185
|
+
return this.cachedSync.localQueryResult(name, args);
|
|
186
|
+
}
|
|
187
|
+
return void 0;
|
|
188
|
+
},
|
|
189
|
+
localQueryLogs: () => {
|
|
190
|
+
if (this.cachedSync) {
|
|
191
|
+
return this.cachedSync.localQueryLogs(name, args);
|
|
192
|
+
}
|
|
193
|
+
return void 0;
|
|
194
|
+
},
|
|
195
|
+
journal: () => {
|
|
196
|
+
if (this.cachedSync) {
|
|
197
|
+
return this.cachedSync.queryJournal(name, args);
|
|
198
|
+
}
|
|
199
|
+
return void 0;
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
// Let's try out a queryOptions-style API.
|
|
204
|
+
// This method is similar to the React Query API `queryClient.prefetchQuery()`.
|
|
205
|
+
// In the future an ensureQueryData(): Promise<Data> method could exist.
|
|
206
|
+
/**
|
|
207
|
+
* Indicates likely future interest in a query subscription.
|
|
208
|
+
*
|
|
209
|
+
* The implementation currently immediately subscribes to a query. In the future this method
|
|
210
|
+
* may prioritize some queries over others, fetch the query result without subscribing, or
|
|
211
|
+
* do nothing in slow network connections or high load scenarios.
|
|
212
|
+
*
|
|
213
|
+
* To use this in a Vue component, call useQuery() and ignore the return value.
|
|
214
|
+
*
|
|
215
|
+
* @param queryOptions - A query (function reference from an api object) and its args, plus
|
|
216
|
+
* an optional extendSubscriptionFor for how long to subscribe to the query.
|
|
217
|
+
*/
|
|
218
|
+
prewarmQuery(queryOptions) {
|
|
219
|
+
const extendSubscriptionFor = queryOptions.extendSubscriptionFor ?? DEFAULT_EXTEND_SUBSCRIPTION_FOR;
|
|
220
|
+
const watch = this.watchQuery(queryOptions.query, queryOptions.args || {});
|
|
221
|
+
const unsubscribe = watch.onUpdate(() => {
|
|
222
|
+
});
|
|
223
|
+
setTimeout(unsubscribe, extendSubscriptionFor);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Construct a new {@link PaginatedWatch} on a Convex paginated query function.
|
|
227
|
+
*
|
|
228
|
+
* **Not supported in the Vue port — use the {@link usePaginatedQuery}
|
|
229
|
+
* composable instead.** Convex's paginated-subscription engine
|
|
230
|
+
* (`PaginatedQueryClient`) is not part of the public `convex` exports, so a
|
|
231
|
+
* third-party package cannot instantiate it; pagination is handled entirely
|
|
232
|
+
* in the composable layer via ordinary {@link watchQuery} subscriptions.
|
|
233
|
+
*
|
|
234
|
+
* The method is retained for structural parity with
|
|
235
|
+
* `ConvexReactClient.watchPaginatedQuery`. It is reachable only if a caller
|
|
236
|
+
* passes `paginationOptions` to {@link useConvexQueries} (the React-shaped
|
|
237
|
+
* escape hatch); doing so throws this error to fail loudly rather than
|
|
238
|
+
* silently mis-subscribe.
|
|
239
|
+
*
|
|
240
|
+
* Upstream wires {@link usePaginatedQuery_experimental} to this method's
|
|
241
|
+
* `PaginatedQueryClient`; the port re-bases that hook on the same manual
|
|
242
|
+
* page-management engine as {@link usePaginatedQuery}, so both hooks work
|
|
243
|
+
* without ever calling this method (only the experimental single-request
|
|
244
|
+
* network path is not reproduced).
|
|
245
|
+
*
|
|
246
|
+
* @internal
|
|
247
|
+
*/
|
|
248
|
+
watchPaginatedQuery(_query, _args, _options) {
|
|
249
|
+
throw new Error(
|
|
250
|
+
"ConvexVueClient.watchPaginatedQuery is not supported: Convex's internal PaginatedQueryClient is not part of the public API. Use the `usePaginatedQuery` composable for paginated queries."
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Execute a mutation function.
|
|
255
|
+
*
|
|
256
|
+
* @param mutation - A {@link server.FunctionReference} for the public mutation
|
|
257
|
+
* to run.
|
|
258
|
+
* @param args - An arguments object for the mutation. If this is omitted,
|
|
259
|
+
* the arguments will be `{}`.
|
|
260
|
+
* @param options - A {@link MutationOptions} options object for the mutation.
|
|
261
|
+
* @returns A promise of the mutation's result.
|
|
262
|
+
*/
|
|
263
|
+
mutation(mutation, ...argsAndOptions) {
|
|
264
|
+
const [args, options] = argsAndOptions;
|
|
265
|
+
const name = getFunctionName(mutation);
|
|
266
|
+
return this.sync.mutation(name, args, options);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Execute an action function.
|
|
270
|
+
*
|
|
271
|
+
* @param action - A {@link server.FunctionReference} for the public action
|
|
272
|
+
* to run.
|
|
273
|
+
* @param args - An arguments object for the action. If this is omitted,
|
|
274
|
+
* the arguments will be `{}`.
|
|
275
|
+
* @returns A promise of the action's result.
|
|
276
|
+
*/
|
|
277
|
+
action(action, ...args) {
|
|
278
|
+
const name = getFunctionName(action);
|
|
279
|
+
return this.sync.action(name, ...args);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Fetch a query result once.
|
|
283
|
+
*
|
|
284
|
+
* **Most application code should subscribe to queries instead, using
|
|
285
|
+
* the {@link useQuery} composable.**
|
|
286
|
+
*
|
|
287
|
+
* @param query - A {@link server.FunctionReference} for the public query
|
|
288
|
+
* to run.
|
|
289
|
+
* @param args - An arguments object for the query. If this is omitted,
|
|
290
|
+
* the arguments will be `{}`.
|
|
291
|
+
* @returns A promise of the query's result.
|
|
292
|
+
*/
|
|
293
|
+
query(query, ...args) {
|
|
294
|
+
const watch = this.watchQuery(query, ...args);
|
|
295
|
+
const existingResult = watch.localQueryResult();
|
|
296
|
+
if (existingResult !== void 0) {
|
|
297
|
+
return Promise.resolve(existingResult);
|
|
298
|
+
}
|
|
299
|
+
return new Promise((resolve, reject) => {
|
|
300
|
+
const unsubscribe = watch.onUpdate(() => {
|
|
301
|
+
unsubscribe();
|
|
302
|
+
try {
|
|
303
|
+
resolve(watch.localQueryResult());
|
|
304
|
+
} catch (e) {
|
|
305
|
+
reject(e);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Get the current {@link ConnectionState} between the client and the Convex
|
|
312
|
+
* deployment.
|
|
313
|
+
*
|
|
314
|
+
* @returns The {@link ConnectionState} with the Convex deployment.
|
|
315
|
+
*/
|
|
316
|
+
connectionState() {
|
|
317
|
+
return this.sync.connectionState();
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Subscribe to the {@link ConnectionState} between the client and the Convex
|
|
321
|
+
* deployment, calling a callback each time it changes.
|
|
322
|
+
*
|
|
323
|
+
* Subscribed callbacks will be called when any part of ConnectionState changes.
|
|
324
|
+
* ConnectionState may grow in future versions (e.g. to provide a array of
|
|
325
|
+
* inflight requests) in which case callbacks would be called more frequently.
|
|
326
|
+
* ConnectionState may also *lose* properties in future versions as we figure
|
|
327
|
+
* out what information is most useful. As such this API is considered unstable.
|
|
328
|
+
*
|
|
329
|
+
* @returns An unsubscribe function to stop listening.
|
|
330
|
+
*/
|
|
331
|
+
subscribeToConnectionState(cb) {
|
|
332
|
+
return this.sync.subscribeToConnectionState(cb);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Get the logger for this client.
|
|
336
|
+
*
|
|
337
|
+
* @returns The {@link ConvexLogger} for this client.
|
|
338
|
+
*/
|
|
339
|
+
get logger() {
|
|
340
|
+
return this._logger;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Close any network handles associated with this client and stop all subscriptions.
|
|
344
|
+
*
|
|
345
|
+
* Call this method when you're done with a {@link ConvexVueClient} to
|
|
346
|
+
* dispose of its sockets and resources.
|
|
347
|
+
*
|
|
348
|
+
* @returns A `Promise` fulfilled when the connection has been completely closed.
|
|
349
|
+
*/
|
|
350
|
+
async close() {
|
|
351
|
+
this.closed = true;
|
|
352
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
353
|
+
if (this.cachedSync) {
|
|
354
|
+
const sync = this.cachedSync;
|
|
355
|
+
this.cachedSync = void 0;
|
|
356
|
+
await sync.close();
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
transition(updatedQueries) {
|
|
360
|
+
for (const queryToken of updatedQueries) {
|
|
361
|
+
const callbacks = this.listeners.get(queryToken);
|
|
362
|
+
if (callbacks) {
|
|
363
|
+
for (const callback of callbacks) {
|
|
364
|
+
callback();
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
export const ConvexClientKey = Symbol("ConvexVueClient");
|
|
371
|
+
export function useConvex() {
|
|
372
|
+
return inject(ConvexClientKey, void 0);
|
|
373
|
+
}
|
|
374
|
+
export function useConvexOrThrow(composableName) {
|
|
375
|
+
const client = inject(ConvexClientKey, void 0);
|
|
376
|
+
if (client === void 0) {
|
|
377
|
+
throw new Error(
|
|
378
|
+
`Could not find Convex client! \`${composableName}\` must be used in the Vue component tree where the Convex client has been provided \u2014 in Nuxt, install the \`nuxt-convex-module\` module (or \`provide(ConvexClientKey, client)\`). Did you forget it? See https://docs.convex.dev/quick-start`
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
return client;
|
|
382
|
+
}
|