nuxt-convex-module 0.0.1 → 0.9.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.
Files changed (73) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +40 -200
  3. package/dist/chunks/index.mjs +1 -1
  4. package/dist/devtools-client/200.html +1 -1
  5. package/dist/devtools-client/404.html +1 -1
  6. package/dist/devtools-client/_nuxt/{CgIEvOQU.js → 71bSMC-_.js} +1 -1
  7. package/dist/devtools-client/_nuxt/{C2KGYsR4.js → BhmjAr2Q.js} +1 -1
  8. package/dist/devtools-client/_nuxt/{D2ksFYuU.js → C6YdTgGl.js} +2 -2
  9. package/dist/devtools-client/_nuxt/{CtxksWnu.js → _Lf3mfPR.js} +1 -1
  10. package/dist/devtools-client/_nuxt/builds/latest.json +1 -1
  11. package/dist/devtools-client/_nuxt/builds/meta/7dfea6da-3eca-4a35-ba06-5e069ac7e8df.json +1 -0
  12. package/dist/devtools-client/_nuxt/error-404.CLlwiMp-.css +1 -0
  13. package/dist/devtools-client/_nuxt/error-500.Bxr6fpDU.css +1 -0
  14. package/dist/devtools-client/_nuxt/queries.DNBUjWk2.css +1 -0
  15. package/dist/devtools-client/auth/index.html +1 -1
  16. package/dist/devtools-client/index.html +1 -1
  17. package/dist/devtools-client/logs/index.html +1 -1
  18. package/dist/devtools-client/queries/index.html +1 -1
  19. package/dist/module.d.mts +29 -105
  20. package/dist/module.json +2 -2
  21. package/dist/module.mjs +329 -221
  22. package/dist/runtime/auth0/vue/index.d.ts +3 -3
  23. package/dist/runtime/better-auth/nuxt/middleware.d.ts +0 -6
  24. package/dist/runtime/better-auth/nuxt/middleware.js +4 -5
  25. package/dist/runtime/better-auth/nuxt/proxy.d.ts +18 -2
  26. package/dist/runtime/better-auth/nuxt/proxy.js +7 -7
  27. package/dist/runtime/better-auth/nuxt/server.d.ts +6 -6
  28. package/dist/runtime/better-auth/vue/auth-boundary.d.ts +1 -0
  29. package/dist/runtime/better-auth/vue/cross-domain.js +7 -2
  30. package/dist/runtime/better-auth/vue/hydration.d.ts +1 -1
  31. package/dist/runtime/better-auth/vue/index.d.ts +1 -1
  32. package/dist/runtime/better-auth/vue/index.js +1 -1
  33. package/dist/runtime/better-auth/vue/plugin.client.d.ts +1 -5
  34. package/dist/runtime/better-auth/vue/plugin.client.js +6 -10
  35. package/dist/runtime/better-auth/vue/plugin.server.d.ts +5 -16
  36. package/dist/runtime/better-auth/vue/plugin.server.js +3 -6
  37. package/dist/runtime/better-auth/vue/redirect.d.ts +2 -14
  38. package/dist/runtime/better-auth/vue/{use-auth.d.ts → use-better-auth.d.ts} +31 -11
  39. package/dist/runtime/better-auth/vue/{use-auth.js → use-better-auth.js} +2 -2
  40. package/dist/runtime/clerk/vue/index.d.ts +4 -4
  41. package/dist/runtime/nuxt/app.d.ts +48 -0
  42. package/dist/runtime/nuxt/app.js +8 -0
  43. package/dist/runtime/nuxt/composables/use-async-paginated-query.d.ts +88 -0
  44. package/dist/runtime/nuxt/composables/use-async-paginated-query.js +90 -0
  45. package/dist/runtime/nuxt/composables/use-async-query.d.ts +7 -16
  46. package/dist/runtime/nuxt/composables/use-async-query.js +14 -9
  47. package/dist/runtime/nuxt/config.d.ts +11 -0
  48. package/dist/runtime/nuxt/config.js +1 -0
  49. package/dist/runtime/nuxt/index.d.ts +2 -5
  50. package/dist/runtime/polar/vue/components.d.ts +8 -1
  51. package/dist/runtime/polar/vue/components.js +2 -2
  52. package/dist/runtime/vue/auth/index.d.ts +4 -4
  53. package/dist/runtime/vue/client.d.ts +5 -57
  54. package/dist/runtime/vue/client.js +2 -0
  55. package/dist/runtime/vue/components/convex-image.d.ts +50 -0
  56. package/dist/runtime/vue/components/convex-image.js +21 -0
  57. package/dist/runtime/vue/composables/use-connection-state.d.ts +1 -0
  58. package/dist/runtime/vue/composables/use-paginated-query.d.ts +5 -1
  59. package/dist/runtime/vue/composables/use-paginated-query.js +2 -2
  60. package/dist/runtime/vue/composables/use-query.d.ts +2 -0
  61. package/dist/runtime/vue/composables/use-subscription.d.ts +1 -15
  62. package/dist/runtime/vue/composables/use-upload-queue.d.ts +2 -3
  63. package/dist/runtime/vue/hydration.d.ts +3 -24
  64. package/dist/runtime/vue/index.d.ts +2 -2
  65. package/dist/runtime/vue/index.js +1 -0
  66. package/dist/runtime/vue/plugin.js +1 -1
  67. package/dist/runtime/vue/provide.d.ts +5 -5
  68. package/dist/types.d.mts +2 -2
  69. package/package.json +52 -16
  70. package/dist/devtools-client/_nuxt/builds/meta/23303226-2230-4d14-87ce-87b0f562de6c.json +0 -1
  71. package/dist/devtools-client/_nuxt/error-404.BpRUKU69.css +0 -1
  72. package/dist/devtools-client/_nuxt/error-500.DuDYJ5TI.css +0 -1
  73. package/dist/devtools-client/_nuxt/queries.BmISPDaV.css +0 -1
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 razum@qruto.to
3
+ Copyright © 2026 qruto
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,221 +1,66 @@
1
1
  <div align="center">
2
2
 
3
3
  <picture>
4
- <source media="(prefers-color-scheme: dark)" srcset="./.github/assets/hero-dark.svg">
5
- <img src="./.github/assets/hero-light.svg" alt="Nuxt × Convex" width="560">
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/qruto/nuxt-convex-module/main/.github/assets/hero-dark.svg">
5
+ <img src="https://raw.githubusercontent.com/qruto/nuxt-convex-module/main/.github/assets/hero-light.svg" alt="Nuxt × Convex" width="560">
6
6
  </picture>
7
7
 
8
- # nuxt-convex-module
8
+ <a href="https://www.npmjs.com/package/nuxt-convex-module"><img src="https://raw.githubusercontent.com/qruto/nuxt-convex-module/main/.github/assets/npm.svg" alt="npm" height="20" align="middle"></a> &nbsp;<a href="https://www.npmjs.com/package/nuxt-convex-module"><sub><b>View on npm</b></sub></a>
9
9
 
10
- **The [Convex](https://convex.dev) module for [Nuxt](https://nuxt.com)**
10
+ # nuxt-convex-module
11
11
 
12
- Reactive live queries, mutations, actions, cursor pagination, file storage, connection state
13
- and SSR preloading — auto-imported and typed against your deployment.
12
+ Connects a [Nuxt](https://nuxt.com) app to a [Convex](https://convex.dev) backend: live queries, mutations, actions, pagination,
13
+ file storage and SSR, auto-imported and typed against your deployment.
14
14
 
15
- <sub>Underneath it is a complete [Vue](https://vuejs.org) client, so the same composables also run in a plain Vue app.</sub>
15
+ <sub>The same [Vue](https://vuejs.org) client runs without Nuxt; Better Auth, Clerk, Auth0 and Polar are opt-in.</sub>
16
16
 
17
17
  [![Nuxt][nuxt-src]][nuxt-href]
18
- |
18
+ [![Convex][convex-src]][convex-href]
19
+ <img src="https://raw.githubusercontent.com/qruto/nuxt-convex-module/main/.github/assets/separator.svg" alt="" height="20">
19
20
  [![npm version][npm-version-src]][npm-version-href]
20
21
  [![npm downloads][npm-downloads-src]][npm-downloads-href]
21
- |
22
+ <img src="https://raw.githubusercontent.com/qruto/nuxt-convex-module/main/.github/assets/separator.svg" alt="" height="20">
22
23
  [![Tests][tests-src]][tests-href]
23
24
  [![Coverage][coverage-src]][coverage-href]
24
- |
25
+ <img src="https://raw.githubusercontent.com/qruto/nuxt-convex-module/main/.github/assets/separator.svg" alt="" height="20">
25
26
  [![License][license-src]][license-href]
26
27
 
27
- <code>npx nuxi@latest module add nuxt-convex-module</code>
28
-
29
- [Quick start](#quick-start) · [Documentation](./website) · [Supported packages](#supported-official-packages) · [Upstream parity](./PARITY.md) · [Security](#security)
30
-
31
- </div>
32
-
33
- Composables follow [VueUse](https://vueuse.org) conventions (`MaybeRefOrGetter` inputs, `ComputedRef`/`ShallowRef` returns) while keeping the public API Convex already documents — same names, same arguments, same return shapes, so Convex's own docs and examples translate line for line. Authentication is **provider-agnostic**: the core ships the generic `provideConvexAuth` plumbing plus Vue adapters for [Clerk](https://clerk.com) and [Auth0](https://auth0.com), while [Better Auth](https://www.better-auth.com) and [Polar](https://polar.sh) are **opt-in** sub-modules — mirroring how `@convex-dev/better-auth` and `@convex-dev/polar` are separate packages upstream.
34
-
35
- Coverage is complete rather than partial: `convex/react` and `convex/nextjs` are ported in full, hook-for-composable, and the port is kept diffable against upstream so new Convex releases can be tracked file-for-file — see [Relationship to upstream](#relationship-to-upstream) and [`PARITY.md`](./PARITY.md).
36
-
37
- > 📖 **Full documentation:** the **[docs site](./website)** (homepage and docs in one Nuxt app, with live Convex demos throughout) covers installation, the guide, every supported component, and the complete API reference.
38
-
39
- ## Supported official packages
40
-
41
- `nuxt-convex-module` is a **Nuxt/Vue port of Convex's own React/Next integration**, not a reimagining of it. Everything below is at **feature parity** with its upstream counterpart and keeps the **same public API** — same names, same arguments, same return shapes — so Convex's own docs and examples translate line for line. What changes is Vue's shape (a `ComputedRef` instead of a plain value, a plugin instead of a provider component); the Convex part never does.
42
-
43
- ### Convex's own client
44
-
45
- The React and Next entry points Convex ships inside the `convex` package, ported in full — hook for composable. The data layer is always on; the two auth providers Convex supports officially wire themselves up as soon as their Vue SDK is installed.
46
-
47
- | What you get | Enable |
48
- |---|---|
49
- | **Reactive data** — every composable (`useQuery`, `useMutation`, `useAction`, `usePaginatedQuery`, …), `ConvexVueClient`, auth state and the `<Authenticated>` family | **always on** |
50
- | **SSR & server** — `fetchQuery` / `fetchMutation` / `fetchAction` and `preloadQuery`, as Nitro server imports | **always on** |
51
- | **[Clerk](https://clerk.com) auth** — `provideConvexAuthFromClerk()` · `<ConvexProviderWithClerk>` | `npm i @clerk/vue` |
52
- | **[Auth0](https://auth0.com) auth** — `provideConvexAuthFromAuth0()` · `<ConvexProviderWithAuth0>` | `npm i @auth0/auth0-vue` |
53
-
54
- At parity with [`convex@1.45.0`](https://npmjs.com/package/convex) — its [`/react`](https://docs.convex.dev/client/react), [`/nextjs`](https://docs.convex.dev/client/react/nextjs/server-rendering), [`/react-clerk`](https://docs.convex.dev/auth/clerk) and [`/react-auth0`](https://docs.convex.dev/auth/auth0) entry points, ported file-for-file.
55
-
56
- ### Convex components that ship a React/Next client
57
-
58
- Convex [components](https://www.convex.dev/components) are backend modules, and some arrive with a React/Next client alongside the backend half. Those clients get the same treatment: a Vue/Nuxt port on the upstream's own API, tracked against the same pinned baseline.
59
-
60
- | What you get | Enable |
61
- |---|---|
62
- | **[Better Auth](https://better-auth.com)** — `useAuth`, the same-origin `/api/auth/**` proxy, SSR prefetch, the `auth` route middleware, `<AuthBoundary>`, and `convexAuth(event)` for server calls | `npm i @convex-dev/better-auth` |
63
- | **[Polar](https://polar.sh) billing** — `<CheckoutLink>` · `<CustomerPortalLink>` | `npm i @convex-dev/polar` |
64
-
65
- At parity with [`@convex-dev/better-auth@0.12.5`](https://github.com/get-convex/better-auth) (its `react` **and** `nextjs` halves) and [`@convex-dev/polar@0.9.2`](https://github.com/get-convex/polar).
66
-
67
- A component with **no** React/Next client has nothing to port. Install it in your Convex deployment and call its functions from Vue with the ordinary `useMutation` / `useAction`.
68
-
69
- Every surface above is auto-imported, and also reachable as a [subpath export](#manual-imports--subpath-exports) for explicit imports. The authoritative file-by-file map and pinned baselines live in [`PARITY.md`](./PARITY.md).
70
-
71
- ## How it plugs into Nuxt
72
-
73
- Listing `nuxt-convex-module` in your `modules` array wires Convex into every layer of the app — through the same `@nuxt/kit` integration points any module uses. Everything below is registered for you; nothing needs importing or manual wiring.
74
-
75
- ### Auto-imported composables · `addImports`
76
-
77
- **Data**
78
- - `useQuery` / `useConvexQuery` — reactive live query (plus `useQuery_experimental`, the 1.39 result/error split)
79
- - `useAsyncQuery` / `useConvexAsyncQuery` — SSR-fetched, payload-hydrated live query with Nuxt's `{ data, error, status, refresh }` shape
80
- - `useQueries` / `useConvexQueries` — several live queries over one subscription
81
- - `useMutation` / `useConvexMutation` — call a Convex mutation
82
- - `useAction` / `useConvexAction` — call a Convex action
83
- - `usePaginatedQuery` — cursor pagination (plus `usePaginatedQuery_experimental`, dual-overload)
84
- - `useConvexConnectionState` — live WebSocket connection status
85
- - `useConvex` — the underlying Convex client
86
-
87
- **Files**
88
- - `useUpload` / `useConvexUpload` / `uploadFile` — upload to Convex storage
89
- - `useUploadQueue` / `useConvexUploadQueue` — multi-file upload queue
90
- - `useStorageUrl` / `useConvexStorageUrl` — resolve a stored file's URL
91
-
92
- **Auth (provider-agnostic)**
93
- - `useConvexAuth` / `provideConvexAuth` — Convex auth state
94
- - `usePreloadedQuery` — hydrate an SSR-preloaded query on the client
95
-
96
- **App API wiring**
97
- - `provideConvexApi` / `useConvexApi` / `useConvexNamespace` — provide and consume the generated `api`
98
-
99
- ### Auto-imported components · `addComponent`
100
-
101
- - `<Authenticated>` / `<Unauthenticated>` / `<AuthLoading>` / `<AuthRefreshing>` — render by auth state
102
-
103
- > Integration-specific composables and components auto-import too **when their package is installed** — `useAuth` + `<AuthBoundary>` (Better Auth), `provideConvexAuthFromClerk` + `<ConvexProviderWithClerk>` (Clerk), `provideConvexAuthFromAuth0` + `<ConvexProviderWithAuth0>` (Auth0), `<CheckoutLink>` + `<CustomerPortalLink>` (Polar). See [Supported official packages](#supported-official-packages).
104
-
105
- ### Server (Nitro) auto-imports · `addServerImports`
106
-
107
- - `fetchQuery` / `fetchMutation` / `fetchAction` — one-shot Convex calls
108
- - `preloadQuery` / `preloadedQueryResult` — SSR preload and the client hydration handoff
109
- - `convexAuth` — request-scoped authenticated server client (Better Auth only)
110
-
111
- ### Plugins, middleware & dev wiring
112
-
113
- - **Base client plugin** · `addPlugin` — provides a `ConvexVueClient` (server + client) so the data layer works on its own; Better Auth supplies its own client plugin instead when installed.
114
- - **Provide-api plugin** · `addPluginTemplate` — wires the generated `api` app-wide; fs-guarded to a no-op until `convex dev` has run, and **re-rendered live** the moment codegen appears (`builder:watch`).
115
- - **Server handler + route rule** · `addServerHandler` / `extendRouteRules` — the same-origin `/api/auth/**` proxy, marked uncacheable (Better Auth only).
116
- - **Route middleware** · `addRouteMiddleware` — the opt-in `auth` page guard (Better Auth only).
117
- - **Nuxt DevTools tab** · `addCustomTab` + devtools RPC — a **Convex panel** (dev only): live connection state, active query subscriptions with results and per-query server logs, auth state, the client log stream, and open-in-editor for Convex functions. Disable with `convex.devtools: false`.
118
-
119
- ### Runtime config & import aliases
120
-
121
- - **Runtime config** (`convex` key, via `updateRuntimeConfig`): public `convex.url` / `convex.siteUrl`
122
- - **Aliases** (Vite + Nitro): `#convex`, `#convex/api`, `#convex/server`, `#convex/dataModel`, `#convex/_generated`
123
-
124
- ### Optional module · `nuxt-security`
125
-
126
- - When [`nuxt-security`](https://nuxt-security.vercel.app) is installed, the module registers it as a module dependency (no `modules` entry needed) and extends its CSP with your deployment's origins at runtime — `connect-src` (production only), `img-src`, and `media-src`. Opt out with `convex.security: false`. Full details, plus everything the module hardens on its own, in the [security guide](./website/content/1.getting-started/4.security.md).
127
-
128
- ### Manual imports · subpath exports
129
-
130
- Everything above is auto-imported in Nuxt, but each surface is also a real **subpath export** — reach for these for explicit/type-only imports. Entries follow **client/server** naming. The self-contained client entries also work in a **plain Vue** (non-Nuxt) app and carry a `/vue` alias for that use; `/better-auth/client` and `/server` rely on Nuxt-provided aliases/runtime config and need Nuxt:
131
-
132
- | Import path | Contents |
133
- |---|---|
134
- | `nuxt-convex-module` | the Nuxt module (for `modules: []`) |
135
- | `nuxt-convex-module/client` (alias `/vue`) | `ConvexVueClient`, `ConvexClientKey`, every composable (`useQuery`, `useMutation`, `useAction`, pagination, upload, …), auth (`provideConvexAuth`, `useConvexAuth`, `<Authenticated>` …), `usePreloadedQuery`, and all public types |
136
- | `nuxt-convex-module/server` | Nitro/server: `fetchQuery`, `fetchMutation`, `fetchAction`, `preloadQuery`, `preloadedQueryResult` |
137
- | `nuxt-convex-module/clerk/client` (alias `/clerk/vue`) | `provideConvexAuthFromClerk`, `<ConvexProviderWithClerk>` |
138
- | `nuxt-convex-module/auth0/client` (alias `/auth0/vue`) | `provideConvexAuthFromAuth0`, `<ConvexProviderWithAuth0>` |
139
- | `nuxt-convex-module/better-auth/client` | `useAuth`, `authClient`, `usePreloadedAuthQuery`, `consumeCrossDomainOneTimeToken`, `resolveAuthRedirect`, `<AuthBoundary>`, and the `convexClient` / `crossDomainClient` client plugins (re-exported from `@convex-dev/better-auth/client/plugins`) |
140
- | `nuxt-convex-module/better-auth/server` | Nitro/server: `convexAuth(event)` (auto-imported in server code; import explicitly for the `ConvexAuthOptions` / `ConvexAuthService` types) |
141
- | `nuxt-convex-module/polar/client` (alias `/polar/vue`) | `<CheckoutLink>`, `<CustomerPortalLink>` |
142
-
143
- ## Integrations (auto-detected)
144
-
145
- You only ever add **one** module. Better Auth, Polar, and nuxt-security light up automatically when their packages are installed — no extra `modules` entries, no config:
146
-
147
28
  ```bash
148
- # add auth → it's wired on next dev
149
- npm i @convex-dev/better-auth better-auth
150
- # add billing components → registered automatically
151
- npm i @convex-dev/polar @polar-sh/checkout
152
- # add security headers → nuxt-security registered, CSP made Convex-aware
153
- npm i nuxt-security
154
- ```
155
-
156
- ```ts
157
- // nuxt.config.ts — still just one module
158
- export default defineNuxtConfig({
159
- modules: ['nuxt-convex-module'],
160
-
161
- // Everything below is optional. Integrations auto-enable when installed;
162
- // override only if you want to force one on/off or change the auth route.
163
- convex: {
164
- // betterAuth: false,
165
- // betterAuth: { authClient: './app/convex-auth-client' }, // bring your own client
166
- // betterAuth: { crossDomainCallbackRoute: '/auth/callback' }, // restrict ?ott= to one route, for crossDomainClient()
167
- // polar: false,
168
- // security: false, // leave nuxt-security's CSP alone
169
- // authRoute: '/api/auth',
170
- },
171
- })
29
+ npx nuxi@latest module add nuxt-convex-module
172
30
  ```
173
31
 
174
- - **Better Auth** (when `@convex-dev/better-auth` is installed) — a Vue/Nuxt port of its `react` + `nextjs` integration: `useAuth` (session, sign-in/out), the same-origin `/api/auth/**` proxy, SSR token prefetch, the opt-in `auth` route middleware, the `<AuthBoundary>` component, and `convexAuth(event)` for request-scoped server calls. Imported directly via `nuxt-convex-module/better-auth/client`. Bring your own auth client (to choose plugins — e.g. `emailOTPClient()`, `passkeyClient()`, or `crossDomainClient()` for cross-domain auth) by pointing `convex.betterAuth.authClient` at a module that exports `authClient`; otherwise a minimal bundled default (`convexClient()` only) is used.
175
- - **Clerk** (when `@clerk/vue` is installed) — a Vue port of `convex/react-clerk`: `provideConvexAuthFromClerk()` and `<ConvexProviderWithClerk>`. Types via `nuxt-convex-module/clerk/client`.
176
- - **Auth0** (when `@auth0/auth0-vue` is installed) — a Vue port of `convex/react-auth0`: `provideConvexAuthFromAuth0()` and `<ConvexProviderWithAuth0>`. Types via `nuxt-convex-module/auth0/client`.
177
- - **Polar** (when `@convex-dev/polar` is installed) — a Vue port of `@convex-dev/polar/react`'s `<CheckoutLink>` and `<CustomerPortalLink>`. Types via `nuxt-convex-module/polar/client`.
178
- - **nuxt-security** (when `nuxt-security` is installed) — registered as a module dependency and its Content Security Policy extended with your Convex origins: `connect-src` (production only — dev keeps it open for HMR), `img-src`, and `media-src`. Applied at runtime from `runtimeConfig`, so the deployment URL may come from the environment and the order of `modules` doesn't matter. Your own directives are kept; the origins are appended.
32
+ [Documentation](https://nuxt-convex-module.dev) · [Installation](https://nuxt-convex-module.dev/getting-started/installation) · [Components](https://nuxt-convex-module.dev/components) · [Upstream parity](./PARITY.md) · [Stability](./STABILITY.md) · [Security](#security)
179
33
 
180
- Pure Convex with no auth? Install none of them — you get just the data layer (the module provides a base client on its own), and nothing drags an auth provider or Polar into your bundle.
181
-
182
- ## Quick start
34
+ </div>
183
35
 
184
- ### 1. Install
36
+ ## What you get
185
37
 
186
- ```bash
187
- npx nuxi@latest module add nuxt-convex-module
188
- ```
38
+ - ⚡ **Live data** — [`useQuery`, `useQueries`](https://nuxt-convex-module.dev/guide/queries), [`useMutation`, `useAction`](https://nuxt-convex-module.dev/guide/mutations-and-actions) and cursor [`usePaginatedQuery`](https://nuxt-convex-module.dev/guide/pagination), over one `ConvexVueClient`.
39
+ - 🖥️ **SSR and preloading** — [`useAsyncQuery`, `useAsyncPaginatedQuery`, `fetchQuery`, `preloadQuery`](https://nuxt-convex-module.dev/guide/server-and-ssr) for hydration-safe server rendering; `fetchMutation` / `fetchAction` on the Nitro side.
40
+ - 📁 **File storage** — [`useUpload`, `useUploadQueue`, `useStorageUrl`](https://nuxt-convex-module.dev/guide/file-storage) and `<ConvexImage>`.
41
+ - 🔐 **Auth state** — provider-agnostic [`useConvexAuth` / `provideConvexAuth`](https://nuxt-convex-module.dev/guide/auth-state) and the `<Authenticated>` / `<Unauthenticated>` / `<AuthLoading>` / `<AuthRefreshing>` components.
42
+ - 🧩 **Opt-in integrations** — install [Better Auth, Clerk, Auth0 or Polar](https://nuxt-convex-module.dev/components) and they wire themselves up.
43
+ - 🛡️ **Security** — install [`nuxt-security`](https://nuxt-convex-module.dev/getting-started/security) and the CSP learns your deployment's origins.
44
+ - 🧰 **DevTools** — a Convex tab in [Nuxt DevTools](https://nuxt-convex-module.dev/guide/devtools): connection, live subscriptions, server logs, auth state.
189
45
 
190
- > Using **strict** pnpm? Add `public-hoist-pattern[]=@convex-dev/*` to `.npmrc` (or set `node-linker=hoisted`) so Convex can resolve component definitions.
46
+ All of it is auto-imported — composables and components in the app, `fetch*` helpers in Nitro — and also reachable through [subpath exports](https://nuxt-convex-module.dev/api-reference#subpath-exports). The same Vue client runs in a [plain Vue app](https://nuxt-convex-module.dev/guide/plain-vue) with no Nuxt involved.
191
47
 
192
- ### 2. Add the module
48
+ **Packages covered:** `convex` (its `/react`, `/nextjs`, `/react-clerk` and `/react-auth0` entry points), `@convex-dev/better-auth` and `@convex-dev/polar` — each with its pinned upstream version under [Components](https://nuxt-convex-module.dev/components).
193
49
 
194
- ```ts
195
- // nuxt.config.ts
196
- export default defineNuxtConfig({
197
- modules: ['nuxt-convex-module'],
198
- })
199
- ```
50
+ ## How it's built
200
51
 
201
- ### 3. Configure environment
52
+ A Nuxt/Vue **port of Convex's own React/Next client**, hook for composable, not a reimagining: the public API keeps the names, arguments and return shapes Convex documents, so its docs and examples translate line for line. The port is kept diffable against upstream so new Convex releases can be tracked file-for-file — see [Relationship to upstream](#relationship-to-upstream) and [`PARITY.md`](./PARITY.md).
202
53
 
203
- ```bash
204
- # .env (the file Nuxt loads automatically)
205
- NUXT_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud
206
- NUXT_PUBLIC_CONVEX_SITE_URL=https://your-deployment.convex.site
207
- ```
54
+ Composables follow [VueUse](https://vueuse.org) conventions (`MaybeRefOrGetter` inputs, `ComputedRef`/`ShallowRef` returns). Authentication is **provider-agnostic**: the core ships the generic `provideConvexAuth` plumbing plus Vue adapters for [Clerk](https://clerk.com) and [Auth0](https://auth0.com), while [Better Auth](https://www.better-auth.com) and [Polar](https://polar.sh) are **opt-in** sub-modules — mirroring how `@convex-dev/better-auth` and `@convex-dev/polar` are separate packages upstream.
208
55
 
209
- `npx convex dev` also writes the URL itself, as the unprefixed `CONVEX_URL` in
210
- `.env.local` — the module reads that too, so `nuxt dev --dotenv .env.local` is
211
- the other way to get there.
56
+ ## Documentation
212
57
 
213
- ### 4. Start the app, then Convex
58
+ **[nuxt-convex-module.dev](https://nuxt-convex-module.dev) is the single source of truth** — installation, configuration, every guide, each supported package and the complete API reference live there and nowhere else, so this README does not repeat them. Its source is [`website/`](./website).
214
59
 
215
- ```bash
216
- npm run dev
217
- npx convex dev
218
- ```
60
+ - [Installation](https://nuxt-convex-module.dev/getting-started/installation) · [Configuration](https://nuxt-convex-module.dev/getting-started/configuration) · [Security](https://nuxt-convex-module.dev/getting-started/security) · [Troubleshooting](https://nuxt-convex-module.dev/getting-started/troubleshooting)
61
+ - [Guide](https://nuxt-convex-module.dev/guide) — queries, mutations and actions, pagination, file storage, server and SSR, auth state, connection state, DevTools, plain Vue
62
+ - [Components](https://nuxt-convex-module.dev/components) — Better Auth, Clerk, Auth0, Polar
63
+ - [API reference](https://nuxt-convex-module.dev/api-reference) and [Recipes](https://nuxt-convex-module.dev/recipes)
219
64
 
220
65
  ## A taste
221
66
 
@@ -251,24 +96,17 @@ This package is intentionally kept **diffable against the upstream React/Next so
251
96
  | `src/runtime/better-auth/**` | `@convex-dev/better-auth/src/{react,nextjs}/**` |
252
97
  | `src/runtime/polar/**` | `@convex-dev/polar/src/react/**` |
253
98
 
254
- [`PARITY.md`](./PARITY.md) is the authoritative ledger: pinned upstream baselines, the file-by-file map, a compatibility matrix per upstream entry point, and every deliberate divergence with its reason and the test that pins it. It also carries the migration contract and the React→Vue translation rules the port is held to. The sync procedure itself is packaged as the [`upstream-parity` skill](./.agents/skills/upstream-parity/SKILL.md).
99
+ [`PARITY.md`](./PARITY.md) is the authoritative ledger: pinned upstream baselines, the file-by-file map, a compatibility matrix per upstream entry point, and every deliberate divergence with its reason and the test that pins it. It also carries the migration contract and the React→Vue translation rules the port is held to. The sync procedure itself is packaged as the [`upstream-parity` skill](./website/skills/upstream-parity/SKILL.md).
255
100
 
256
- ## Contributing
257
-
258
- 1. Clone this repository
259
- 2. Install dependencies using `pnpm install`
260
- 3. Prepare for development using `pnpm dev:prepare`
261
- 4. Start the development server (the docs site) using `pnpm dev` — or `pnpm start`
101
+ [`STABILITY.md`](./STABILITY.md) is the other contract: what a version number promises from 1.0.0 on — the covered surface, the experimental tier, and how an upstream release maps to a release here (an upstream breaking change is a major here, whatever upstream called it).
262
102
 
263
- `pnpm dev` runs the docs site through [portless](https://portless.sh), so it is served at a stable, named HTTPS URL — **https://nuxt-convex-module.localhost** — instead of a shifting `localhost:<port>`. portless generates and trusts a local CA on first run (auto-elevating to bind port 443); pass `--no-tls` for plain HTTP, or run `nuxt dev website` directly to bypass portless entirely.
103
+ ## Contributing
264
104
 
265
- We follow conventional commits. See [CONTRIBUTING.md](./CONTRIBUTING.md) and [RELEASE.md](./RELEASE.md).
105
+ Setup, project structure, the verification gate and the release flow are in [CONTRIBUTING.md](./CONTRIBUTING.md) and [RELEASE.md](./RELEASE.md); how the port tracks upstream is in [PARITY.md](./PARITY.md). Commits follow conventional commits.
266
106
 
267
107
  ## Security
268
108
 
269
- The [security guide](./website/content/1.getting-started/4.security.md) documents every security aspect in one place: the Convex-aware CSP, the hardened Better Auth proxy, auth tokens in SSR payloads, safe post-sign-in redirects, cross-domain one-time tokens, file-storage caveats, and a production checklist.
270
-
271
- In short — install `nuxt-security` for headers and a CSP, use `resolveAuthRedirect()` on your login page, and set `betterAuth.crossDomainCallbackRoute` if you use cross-domain auth.
109
+ The [security guide](https://nuxt-convex-module.dev/getting-started/security) documents every security aspect in one place: the Convex-aware CSP, the hardened Better Auth proxy, auth tokens in SSR payloads, safe post-sign-in redirects, cross-domain one-time tokens, file-storage caveats, and a production checklist.
272
110
 
273
111
  Found a vulnerability? Report it privately via [GitHub Security Advisories](https://github.com/qruto/nuxt-convex-module/security/advisories/new) — not in a public issue. See [SECURITY.md](./SECURITY.md).
274
112
 
@@ -294,3 +132,5 @@ Found a vulnerability? Report it privately via [GitHub Security Advisories](http
294
132
 
295
133
  [nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt&style=plastic
296
134
  [nuxt-href]: https://nuxt.com
135
+ [convex-src]: https://img.shields.io/badge/Convex-020420?logo=convex&style=plastic
136
+ [convex-href]: https://convex.dev
@@ -9,7 +9,7 @@ const DEVTOOLS_UI_LOCAL_PORT = 3630;
9
9
  const EXTENSIONS = ["ts", "tsx", "js", "jsx", "mts", "mjs"];
10
10
  function resolveFunctionSource(rootDir, functionsDir, udfPath) {
11
11
  const modulePath = udfPath.split(":")[0];
12
- if (!modulePath || modulePath.split("/").some((segment) => segment === "" || segment === "." || segment === "..")) {
12
+ if (!modulePath || modulePath.split(/[\\/]/).some((segment) => segment === "" || segment === "." || segment === "..")) {
13
13
  return {};
14
14
  }
15
15
  const base = join(rootDir, functionsDir);
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-convex-module/_nuxt/D2ksFYuU.js"}}</script><link rel="stylesheet" href="/__nuxt-convex-module/_nuxt/entry.HF8C6P11.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/D2ksFYuU.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/DQmVr-EY.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/EZ4-8Xzm.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/vZZlEX5A.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/BmBQNDID.js"><script type="module" src="/__nuxt-convex-module/_nuxt/D2ksFYuU.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__nuxt-convex-module/_nuxt/error-404.BpRUKU69.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/C2KGYsR4.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/D_Rij7MD.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-convex-module/_nuxt/error-500.DuDYJ5TI.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/CtxksWnu.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-convex-module",buildId:"23303226-2230-4d14-87ce-87b0f562de6c",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1789163686862,false]</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-convex-module/_nuxt/C6YdTgGl.js"}}</script><link rel="stylesheet" href="/__nuxt-convex-module/_nuxt/entry.HF8C6P11.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/C6YdTgGl.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/DQmVr-EY.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/EZ4-8Xzm.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/vZZlEX5A.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/BmBQNDID.js"><script type="module" src="/__nuxt-convex-module/_nuxt/C6YdTgGl.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__nuxt-convex-module/_nuxt/error-404.CLlwiMp-.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/BhmjAr2Q.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/D_Rij7MD.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-convex-module/_nuxt/error-500.Bxr6fpDU.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/_Lf3mfPR.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-convex-module",buildId:"7dfea6da-3eca-4a35-ba06-5e069ac7e8df",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1789472049139,false]</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-convex-module/_nuxt/D2ksFYuU.js"}}</script><link rel="stylesheet" href="/__nuxt-convex-module/_nuxt/entry.HF8C6P11.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/D2ksFYuU.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/DQmVr-EY.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/EZ4-8Xzm.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/vZZlEX5A.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/BmBQNDID.js"><script type="module" src="/__nuxt-convex-module/_nuxt/D2ksFYuU.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__nuxt-convex-module/_nuxt/error-404.BpRUKU69.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/C2KGYsR4.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/D_Rij7MD.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-convex-module/_nuxt/error-500.DuDYJ5TI.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/CtxksWnu.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-convex-module",buildId:"23303226-2230-4d14-87ce-87b0f562de6c",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1789163686862,false]</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-convex-module/_nuxt/C6YdTgGl.js"}}</script><link rel="stylesheet" href="/__nuxt-convex-module/_nuxt/entry.HF8C6P11.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/C6YdTgGl.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/DQmVr-EY.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/EZ4-8Xzm.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/vZZlEX5A.js"><link rel="modulepreload" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/BmBQNDID.js"><script type="module" src="/__nuxt-convex-module/_nuxt/C6YdTgGl.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__nuxt-convex-module/_nuxt/error-404.CLlwiMp-.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/BhmjAr2Q.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/D_Rij7MD.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-convex-module/_nuxt/error-500.Bxr6fpDU.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-convex-module/_nuxt/_Lf3mfPR.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-convex-module",buildId:"7dfea6da-3eca-4a35-ba06-5e069ac7e8df",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1789472049139,false]</script></body></html>
@@ -1,2 +1,2 @@
1
1
  import{$ as e,B as t,E as n,F as r,M as i,P as a,V as o,_t as s,c,d as l,f as u,g as d,h as f,ht as p,i as m,l as h,t as g,u as _,v,x as y}from"./EZ4-8Xzm.js";import{a as b,o as x}from"./vZZlEX5A.js";import{n as S,t as C}from"./BmBQNDID.js";import{a as w,i as T,n as E,o as D,r as O,t as k}from"#entry";import{t as A}from"./CKakiU_h.js";var j=v({name:`NButton`,props:{to:String,icon:String,border:{type:Boolean,default:!0},disabled:Boolean,type:{type:String,default:`button`}},setup(e,{attrs:t,slots:n}){return()=>y(e.to?D:`button`,{to:e.to,...t,...!e.to&&{type:e.type},...e.disabled?{disabled:!0}:{tabindex:0},class:[e.border?`n-button-base active:n-button-active focus-visible:n-focus-base hover:n-button-hover`:``,n.default?``:`n-icon-button`,`n-button n-transition n-disabled:n-disabled`].join(` `)},{default:()=>[r(n,`icon`,{},()=>e.icon?[y(S,{icon:e.icon,class:n.default?`n-button-icon`:``})]:[]),r(n,`default`)]})}}),M=O(),N=[`innerHTML`],P=[`textContent`],F={__name:`NCodeBlock`,props:{code:{type:String,required:!0},lang:{type:String,required:!1},lines:{type:Boolean,required:!1,default:!0},inline:{type:Boolean,required:!1},grammarContextCode:{type:String,required:!1},transformRendered:{type:Function,required:!1}},emits:[`loaded`],setup(e,{emit:t}){let r=e,o=t,l=c(()=>{let e=r.lang===`text`?{code:r.code,supported:!1}:M.value?.devtools.renderCodeHighlight(r.code,r.lang,{grammarContextCode:r.grammarContextCode})||{code:r.code,supported:!1};return e.supported&&r.transformRendered&&(e.code=r.transformRendered(e.code)),e.supported&&n(()=>o(`loaded`)),e}),d=c(()=>[`n-code-block shiki`,r.lines&&!r.inline?`n-code-block-lines`:``]);return(t,n)=>e.lang&&l.value.supported?(i(),u(`pre`,{key:0,class:p(d.value)},[h(`code`,{innerHTML:l.value.code},null,8,N)],2)):(i(),u(`pre`,{key:1,class:p(d.value)},[h(`code`,null,[(i(!0),u(m,null,a(e.code.split(`
2
- `),(e,t)=>(i(),u(m,{key:t},[h(`span`,{class:`line`,textContent:s(e)},null,8,P),n[0]||=h(`br`,null,null,-1)],64))),128))])],2))}},I={flex:`~ gap-3`,"items-center":``},L={__name:`NIconTitle`,props:{icon:{type:String,required:!1},text:{type:String,required:!1}},setup(e){return(t,n)=>(i(),u(`div`,I,[e.icon?(i(),u(`div`,{key:0,class:p(e.icon)},null,2)):l(``,!0),r(t.$slots,`default`,{},()=>[h(`div`,null,s(e.text),1)])]))}},R=[`open`],z={"text-base":``},B={key:0,"text-sm":``,op50:``},V=g({__name:`NSectionBlock`,props:{icon:{type:String,required:!1},text:{type:String,required:!1},description:{type:String,required:!1},containerClass:{type:String,required:!1,default:``},headerClass:{type:String,required:!1},collapse:{type:Boolean,required:!1,default:!0},open:{type:Boolean,required:!1,default:!0},padding:{type:[Boolean,String],required:!1,default:!0}},setup(n){let a=A(n,`open`,void 0,{passive:!0});function c(e){a.value=e.target.open}return(g,v)=>{let y=S,x=L;return i(),u(m,null,[h(`details`,{open:e(a),onToggle:c},[h(`summary`,{class:p([`cursor-pointer select-none p4 hover:bg-active`,n.collapse?``:`pointer-events-none`])},[d(x,{icon:n.icon,text:n.text,"text-xl":``,transition:``,class:p([e(a)?`op100`:`op60`,n.headerClass])},{default:t(()=>[h(`div`,null,[h(`div`,z,[r(g.$slots,`text`,{},()=>[f(s(n.text),1)],!0)]),n.description||g.$slots.description?(i(),u(`div`,B,[r(g.$slots,`description`,{},()=>[f(s(n.description),1)],!0)])):l(``,!0)]),v[0]||=h(`div`,{class:`flex-auto`},null,-1),r(g.$slots,`actions`,{},void 0,!0),n.collapse?(i(),_(y,{key:0,icon:`carbon-chevron-down`,class:`chevron`,"cursor-pointer":``,"place-self-start":``,"text-base":``,op75:``,transition:``,"duration-500":``})):l(``,!0)]),_:3},8,[`icon`,`text`,`class`])],2),v._lazyshow1||e(a)?(v._lazyshow1=!0,i(),u(m,null,[o(h(`div`,{class:p([`flex flex-col flex-gap2 pb6 pt2`,typeof n.padding==`string`?n.padding:n.padding?`px4`:``])},[r(g.$slots,`details`,{},void 0,!0),h(`div`,{class:p([n.containerClass,`mt1`])},[r(g.$slots,`default`,{},void 0,!0)],2),r(g.$slots,`footer`,{},void 0,!0)],2),[[b,e(a)]])],64)):l(`v-show-if`,!0)],40,R),v[1]||=h(`div`,{class:`x-divider`},null,-1)],64)}}},[[`__scopeId`,`data-v-c64ba2dc`]]),H={class:`font-mono text-xs op65`},U={class:`op50 text-xs whitespace-nowrap`},W={class:`flex flex-col gap-3 px4 pb4`},G={class:`font-mono text-xs bg-active rounded p2 flex flex-col gap-1`},K=Object.assign(v({__name:`QuerySubscription`,props:{query:{}},setup(n){function r(e){return e?new Date(e).toLocaleTimeString():`never`}function o(e){return JSON.stringify(e,null,2)??`undefined`}return(c,p)=>{let g=C,v=j,y=w,b=F,S=V;return i(),_(S,{text:n.query.udfPath,padding:!1,open:!1,icon:`carbon-data-share`},{description:t(()=>[h(`span`,H,s(JSON.stringify(n.query.args)),1)]),actions:t(()=>[n.query.paginated?(i(),_(g,{key:0,n:`blue`},{default:t(()=>[...p[1]||=[f(` paginated `,-1)]]),_:1})):l(``,!0),n.query.errorMessage?(i(),_(g,{key:1,n:`red`},{default:t(()=>[...p[2]||=[f(` error `,-1)]]),_:1})):l(``,!0),h(`span`,U,s(n.query.listenerCount)+` 👂 · `+s(n.query.updates)+` updates · `+s(r(n.query.lastUpdatedAt)),1),d(v,{n:`xs`,icon:`carbon-launch`,title:`Open source file in editor`,onClick:p[0]||=x(t=>(`openFunctionInEditor`in c?c.openFunctionInEditor:e(k))(n.query.udfPath),[`stop`])},{default:t(()=>[...p[3]||=[f(` source `,-1)]]),_:1})]),default:t(()=>[h(`div`,W,[n.query.errorMessage?(i(),_(y,{key:0,n:`red`,icon:`carbon-warning`},{default:t(()=>[f(s(n.query.errorMessage),1)]),_:1})):(i(),u(m,{key:1},[p[4]||=h(`div`,{class:`op50 text-xs`},` Result `,-1),d(b,{code:n.query.result===void 0?`// loading…`:o(n.query.result),lang:`json`,lines:!1,class:`max-h-80 of-auto`},null,8,[`code`])],64)),n.query.logs?.length?(i(),u(m,{key:2},[p[5]||=h(`div`,{class:`op50 text-xs`},` Server logs `,-1),h(`div`,G,[(i(!0),u(m,null,a(n.query.logs,(e,t)=>(i(),u(`div`,{key:t},s(e),1))),128))])],64)):l(``,!0)])]),_:1},8,[`text`])}}}),{__name:`QuerySubscription`}),q={class:`flex flex-col gap-2`},J=v({__name:`queries`,setup(n){let r=E();return(n,o)=>{let s=T,c=K;return i(),u(`div`,q,[e(r).queries.length?l(``,!0):(i(),_(s,{key:0},{default:t(()=>[...o[0]||=[h(`span`,{class:`op50`},`No active query subscriptions.`,-1)]]),_:1})),(i(!0),u(m,null,a(e(r).queries,e=>(i(),_(c,{key:e.token,query:e},null,8,[`query`]))),128))])}}});export{J as default};
2
+ `),(e,t)=>(i(),u(m,{key:t},[h(`span`,{class:`line`,textContent:s(e)},null,8,P),n[0]||=h(`br`,null,null,-1)],64))),128))])],2))}},I={flex:`~ gap-3`,"items-center":``},L={__name:`NIconTitle`,props:{icon:{type:String,required:!1},text:{type:String,required:!1}},setup(e){return(t,n)=>(i(),u(`div`,I,[e.icon?(i(),u(`div`,{key:0,class:p(e.icon)},null,2)):l(``,!0),r(t.$slots,`default`,{},()=>[h(`div`,null,s(e.text),1)])]))}},R=[`open`],z={"text-base":``},B={key:0,"text-sm":``,op50:``},V=g({__name:`NSectionBlock`,props:{icon:{type:String,required:!1},text:{type:String,required:!1},description:{type:String,required:!1},containerClass:{type:String,required:!1,default:``},headerClass:{type:String,required:!1},collapse:{type:Boolean,required:!1,default:!0},open:{type:Boolean,required:!1,default:!0},padding:{type:[Boolean,String],required:!1,default:!0}},setup(n){let a=A(n,`open`,void 0,{passive:!0});function c(e){a.value=e.target.open}return(g,v)=>{let y=S,x=L;return i(),u(m,null,[h(`details`,{open:e(a),onToggle:c},[h(`summary`,{class:p([`cursor-pointer select-none p4 hover:bg-active`,n.collapse?``:`pointer-events-none`])},[d(x,{icon:n.icon,text:n.text,"text-xl":``,transition:``,class:p([e(a)?`op100`:`op60`,n.headerClass])},{default:t(()=>[h(`div`,null,[h(`div`,z,[r(g.$slots,`text`,{},()=>[f(s(n.text),1)],!0)]),n.description||g.$slots.description?(i(),u(`div`,B,[r(g.$slots,`description`,{},()=>[f(s(n.description),1)],!0)])):l(``,!0)]),v[0]||=h(`div`,{class:`flex-auto`},null,-1),r(g.$slots,`actions`,{},void 0,!0),n.collapse?(i(),_(y,{key:0,icon:`carbon-chevron-down`,class:`chevron`,"cursor-pointer":``,"place-self-start":``,"text-base":``,op75:``,transition:``,"duration-500":``})):l(``,!0)]),_:3},8,[`icon`,`text`,`class`])],2),v._lazyshow1||e(a)?(v._lazyshow1=!0,i(),u(m,null,[o(h(`div`,{class:p([`flex flex-col flex-gap2 pb6 pt2`,typeof n.padding==`string`?n.padding:n.padding?`px4`:``])},[r(g.$slots,`details`,{},void 0,!0),h(`div`,{class:p([n.containerClass,`mt1`])},[r(g.$slots,`default`,{},void 0,!0)],2),r(g.$slots,`footer`,{},void 0,!0)],2),[[b,e(a)]])],64)):l(`v-show-if`,!0)],40,R),v[1]||=h(`div`,{class:`x-divider`},null,-1)],64)}}},[[`__scopeId`,`data-v-36e420e5`]]),H={class:`font-mono text-xs op65`},U={class:`op50 text-xs whitespace-nowrap`},W={class:`flex flex-col gap-3 px4 pb4`},G={class:`font-mono text-xs bg-active rounded p2 flex flex-col gap-1`},K=Object.assign(v({__name:`QuerySubscription`,props:{query:{}},setup(n){function r(e){return e?new Date(e).toLocaleTimeString():`never`}function o(e){return JSON.stringify(e,null,2)??`undefined`}return(c,p)=>{let g=C,v=j,y=w,b=F,S=V;return i(),_(S,{text:n.query.udfPath,padding:!1,open:!1,icon:`carbon-data-share`},{description:t(()=>[h(`span`,H,s(JSON.stringify(n.query.args)),1)]),actions:t(()=>[n.query.paginated?(i(),_(g,{key:0,n:`blue`},{default:t(()=>[...p[1]||=[f(` paginated `,-1)]]),_:1})):l(``,!0),n.query.errorMessage?(i(),_(g,{key:1,n:`red`},{default:t(()=>[...p[2]||=[f(` error `,-1)]]),_:1})):l(``,!0),h(`span`,U,s(n.query.listenerCount)+` 👂 · `+s(n.query.updates)+` updates · `+s(r(n.query.lastUpdatedAt)),1),d(v,{n:`xs`,icon:`carbon-launch`,title:`Open source file in editor`,onClick:p[0]||=x(t=>(`openFunctionInEditor`in c?c.openFunctionInEditor:e(k))(n.query.udfPath),[`stop`])},{default:t(()=>[...p[3]||=[f(` source `,-1)]]),_:1})]),default:t(()=>[h(`div`,W,[n.query.errorMessage?(i(),_(y,{key:0,n:`red`,icon:`carbon-warning`},{default:t(()=>[f(s(n.query.errorMessage),1)]),_:1})):(i(),u(m,{key:1},[p[4]||=h(`div`,{class:`op50 text-xs`},` Result `,-1),d(b,{code:n.query.result===void 0?`// loading…`:o(n.query.result),lang:`json`,lines:!1,class:`max-h-80 of-auto`},null,8,[`code`])],64)),n.query.logs?.length?(i(),u(m,{key:2},[p[5]||=h(`div`,{class:`op50 text-xs`},` Server logs `,-1),h(`div`,G,[(i(!0),u(m,null,a(n.query.logs,(e,t)=>(i(),u(`div`,{key:t},s(e),1))),128))])],64)):l(``,!0)])]),_:1},8,[`text`])}}}),{__name:`QuerySubscription`}),q={class:`flex flex-col gap-2`},J=v({__name:`queries`,setup(n){let r=E();return(n,o)=>{let s=T,c=K;return i(),u(`div`,q,[e(r).queries.length?l(``,!0):(i(),_(s,{key:0},{default:t(()=>[...o[0]||=[h(`span`,{class:`op50`},`No active query subscriptions.`,-1)]]),_:1})),(i(!0),u(m,null,a(e(r).queries,e=>(i(),_(c,{key:e.token,query:e},null,8,[`query`]))),128))])}}});export{J as default};
@@ -1 +1 @@
1
- import{B as e,M as t,_t as n,f as r,g as i,h as a,l as o,t as s}from"./EZ4-8Xzm.js";import{t as c}from"./D_Rij7MD.js";import{o as l}from"#entry";var u={class:`antialiased bg-white dark:bg-[#020420] dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-[#020420] tracking-wide`},d={class:`max-w-520px text-center`},f=[`textContent`],p=[`textContent`],m=[`textContent`],h={class:`flex items-center justify-center w-full`},g=s({__name:`error-404`,props:{appName:{type:String,default:`Nuxt`},status:{type:Number,default:404},statusText:{type:String,default:`Page not found`},description:{type:String,default:`Sorry, the page you are looking for could not be found.`},backHome:{type:String,default:`Go back home`}},setup(s){let g=s;return c({title:`${g.status} - ${g.statusText} | ${g.appName}`,script:[{innerHTML:`!function(){let e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(let e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(let t of e)if("childList"===t.type)for(let e of t.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;let r=function(e){let r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),r.credentials="use-credentials"===e.crossOrigin?"include":"anonymous"===e.crossOrigin?"omit":"same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:`*,:after,:before{box-sizing:border-box;border-style:solid;border-width:0;border-color:var(--un-default-border-color,#e5e7eb)}:after,:before{--un-content:""}html{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}h1,h2{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}h1,h2,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 #0000;--un-ring-shadow:0 0 #0000;--un-shadow-inset: ;--un-shadow:0 0 #0000;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:#93c5fd80;--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }`}]}),(c,g)=>{let _=l;return t(),r(`div`,u,[o(`div`,d,[o(`h1`,{class:`font-semibold leading-none mb-4 sm:text-[110px] tabular-nums text-[80px]`,textContent:n(s.status)},null,8,f),o(`h2`,{class:`font-semibold mb-2 sm:text-3xl text-2xl`,textContent:n(s.statusText)},null,8,p),o(`p`,{class:`mb-4 px-2 text-[#64748B] text-md`,textContent:n(s.description)},null,8,m),o(`div`,h,[i(_,{to:`/`,class:`font-medium hover:text-[#00DC82] text-sm underline underline-offset-3`},{default:e(()=>[a(n(s.backHome),1)]),_:1})])])])}}},[[`__scopeId`,`data-v-bc32d885`]]);export{g as default};
1
+ import{B as e,M as t,_t as n,f as r,g as i,h as a,l as o,t as s}from"./EZ4-8Xzm.js";import{t as c}from"./D_Rij7MD.js";import{o as l}from"#entry";var u={class:`antialiased bg-white dark:bg-[#020420] dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-[#020420] tracking-wide`},d={class:`max-w-520px text-center`},f=[`textContent`],p=[`textContent`],m=[`textContent`],h={class:`flex items-center justify-center w-full`},g=s({__name:`error-404`,props:{appName:{type:String,default:`Nuxt`},status:{type:Number,default:404},statusText:{type:String,default:`Page not found`},description:{type:String,default:`Sorry, the page you are looking for could not be found.`},backHome:{type:String,default:`Go back home`}},setup(s){let g=s;return c({title:`${g.status} - ${g.statusText} | ${g.appName}`,script:[{innerHTML:`!function(){let e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(let e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(let t of e)if("childList"===t.type)for(let e of t.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;let r=function(e){let r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),r.credentials="use-credentials"===e.crossOrigin?"include":"anonymous"===e.crossOrigin?"omit":"same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:`*,:after,:before{box-sizing:border-box;border-style:solid;border-width:0;border-color:var(--un-default-border-color,#e5e7eb)}:after,:before{--un-content:""}html{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}h1,h2{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}h1,h2,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 #0000;--un-ring-shadow:0 0 #0000;--un-shadow-inset: ;--un-shadow:0 0 #0000;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:#93c5fd80;--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }`}]}),(c,g)=>{let _=l;return t(),r(`div`,u,[o(`div`,d,[o(`h1`,{class:`font-semibold leading-none mb-4 sm:text-[110px] tabular-nums text-[80px]`,textContent:n(s.status)},null,8,f),o(`h2`,{class:`font-semibold mb-2 sm:text-3xl text-2xl`,textContent:n(s.statusText)},null,8,p),o(`p`,{class:`mb-4 px-2 text-[#64748B] text-md`,textContent:n(s.description)},null,8,m),o(`div`,h,[i(_,{to:`/`,class:`font-medium hover:text-[#00DC82] text-sm underline underline-offset-3`},{default:e(()=>[a(n(s.backHome),1)]),_:1})])])])}}},[[`__scopeId`,`data-v-3f48964f`]]);export{g as default};