better-convex-nuxt 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/runtime/composables/useConvexQuery.js +34 -30
- package/dist/runtime/devtools/ui/dist/200.html +1 -1
- package/dist/runtime/devtools/ui/dist/404.html +1 -1
- package/dist/runtime/devtools/ui/dist/_nuxt/builds/latest.json +1 -1
- package/dist/runtime/devtools/ui/dist/_nuxt/builds/meta/e830e57d-37c5-4c85-b066-5cda3df527f3.json +1 -0
- package/dist/runtime/devtools/ui/dist/index.html +1 -1
- package/dist/runtime/types.d.ts +34 -0
- package/dist/runtime/utils/convex-cache.d.ts +32 -10
- package/dist/runtime/utils/convex-cache.js +28 -4
- package/package.json +1 -1
- package/dist/runtime/devtools/ui/dist/_nuxt/builds/meta/3bfccd49-ba9e-4cb1-a2c9-c8dd3a9b8463.json +0 -1
package/dist/module.json
CHANGED
|
@@ -8,9 +8,8 @@ import {
|
|
|
8
8
|
computeQueryStatus,
|
|
9
9
|
fetchAuthToken,
|
|
10
10
|
registerSubscription,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
cleanupSubscription
|
|
11
|
+
getSubscription,
|
|
12
|
+
releaseSubscription
|
|
14
13
|
} from "../utils/convex-cache.js";
|
|
15
14
|
import { createModuleLogger, getLoggingOptions } from "../utils/logger.js";
|
|
16
15
|
let devToolsRegistryPromise = null;
|
|
@@ -137,7 +136,7 @@ export function useConvexQuery(query, args, options) {
|
|
|
137
136
|
// Simplified: != null covers both null and undefined
|
|
138
137
|
);
|
|
139
138
|
});
|
|
140
|
-
let
|
|
139
|
+
let registeredCacheKey = null;
|
|
141
140
|
if (import.meta.client && subscribe) {
|
|
142
141
|
const setupSubscription = () => {
|
|
143
142
|
const currentArgs = getArgs();
|
|
@@ -149,12 +148,15 @@ export function useConvexQuery(query, args, options) {
|
|
|
149
148
|
return;
|
|
150
149
|
}
|
|
151
150
|
const currentCacheKey = getCacheKey();
|
|
152
|
-
|
|
151
|
+
const existingEntry = getSubscription(nuxtApp, currentCacheKey);
|
|
152
|
+
if (existingEntry) {
|
|
153
|
+
existingEntry.refCount++;
|
|
154
|
+
registeredCacheKey = currentCacheKey;
|
|
153
155
|
return;
|
|
154
156
|
}
|
|
155
157
|
try {
|
|
156
158
|
updateCount = 0;
|
|
157
|
-
unsubscribeFn = convex.onUpdate(
|
|
159
|
+
const unsubscribeFn = convex.onUpdate(
|
|
158
160
|
query,
|
|
159
161
|
currentArgs,
|
|
160
162
|
(result) => {
|
|
@@ -196,6 +198,7 @@ export function useConvexQuery(query, args, options) {
|
|
|
196
198
|
}
|
|
197
199
|
);
|
|
198
200
|
registerSubscription(nuxtApp, currentCacheKey, unsubscribeFn);
|
|
201
|
+
registeredCacheKey = currentCacheKey;
|
|
199
202
|
logger.event({
|
|
200
203
|
event: "subscription:change",
|
|
201
204
|
env: "client",
|
|
@@ -240,17 +243,18 @@ export function useConvexQuery(query, args, options) {
|
|
|
240
243
|
() => toValue(args),
|
|
241
244
|
(newArgs, oldArgs) => {
|
|
242
245
|
if (hashArgs(newArgs) !== hashArgs(oldArgs)) {
|
|
243
|
-
if (oldArgs !== "skip" &&
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
event
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
246
|
+
if (oldArgs !== "skip" && registeredCacheKey) {
|
|
247
|
+
const wasUnsubscribed = releaseSubscription(nuxtApp, registeredCacheKey);
|
|
248
|
+
if (wasUnsubscribed) {
|
|
249
|
+
logger.event({
|
|
250
|
+
event: "subscription:change",
|
|
251
|
+
env: "client",
|
|
252
|
+
name: fnName,
|
|
253
|
+
state: "unsubscribed",
|
|
254
|
+
updates_received: updateCount
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
registeredCacheKey = null;
|
|
254
258
|
}
|
|
255
259
|
if (newArgs !== "skip") {
|
|
256
260
|
setupSubscription();
|
|
@@ -261,19 +265,19 @@ export function useConvexQuery(query, args, options) {
|
|
|
261
265
|
);
|
|
262
266
|
}
|
|
263
267
|
onUnmounted(() => {
|
|
264
|
-
if (
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
event
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
268
|
+
if (registeredCacheKey) {
|
|
269
|
+
const wasUnsubscribed = releaseSubscription(nuxtApp, registeredCacheKey);
|
|
270
|
+
if (wasUnsubscribed) {
|
|
271
|
+
logger.event({
|
|
272
|
+
event: "subscription:change",
|
|
273
|
+
env: "client",
|
|
274
|
+
name: fnName,
|
|
275
|
+
state: "unsubscribed",
|
|
276
|
+
updates_received: updateCount
|
|
277
|
+
});
|
|
278
|
+
devToolsRegistry?.unregisterQuery(registeredCacheKey);
|
|
279
|
+
}
|
|
280
|
+
registeredCacheKey = null;
|
|
277
281
|
}
|
|
278
282
|
});
|
|
279
283
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Convex DevTools</title><link rel="stylesheet" href="/__convex_devtools__/_nuxt/entry.CXPHzcHp.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__convex_devtools__/_nuxt/DRR5kXdS.js"><script type="module" src="/__convex_devtools__/_nuxt/DRR5kXdS.js" crossorigin></script><script id="unhead:payload" type="application/json">{"title":"Convex DevTools"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__convex_devtools__",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Convex DevTools</title><link rel="stylesheet" href="/__convex_devtools__/_nuxt/entry.CXPHzcHp.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__convex_devtools__/_nuxt/DRR5kXdS.js"><script type="module" src="/__convex_devtools__/_nuxt/DRR5kXdS.js" crossorigin></script><script id="unhead:payload" type="application/json">{"title":"Convex DevTools"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__convex_devtools__",buildId:"e830e57d-37c5-4c85-b066-5cda3df527f3",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1768510467224,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.0"><title>Convex DevTools</title><link rel="stylesheet" href="/__convex_devtools__/_nuxt/entry.CXPHzcHp.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__convex_devtools__/_nuxt/DRR5kXdS.js"><script type="module" src="/__convex_devtools__/_nuxt/DRR5kXdS.js" crossorigin></script><script id="unhead:payload" type="application/json">{"title":"Convex DevTools"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__convex_devtools__",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Convex DevTools</title><link rel="stylesheet" href="/__convex_devtools__/_nuxt/entry.CXPHzcHp.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__convex_devtools__/_nuxt/DRR5kXdS.js"><script type="module" src="/__convex_devtools__/_nuxt/DRR5kXdS.js" crossorigin></script><script id="unhead:payload" type="application/json">{"title":"Convex DevTools"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__convex_devtools__",buildId:"e830e57d-37c5-4c85-b066-5cda3df527f3",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1768510467224,false]</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"id":"
|
|
1
|
+
{"id":"e830e57d-37c5-4c85-b066-5cda3df527f3","timestamp":1768510464889}
|
package/dist/runtime/devtools/ui/dist/_nuxt/builds/meta/e830e57d-37c5-4c85-b066-5cda3df527f3.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"id":"e830e57d-37c5-4c85-b066-5cda3df527f3","timestamp":1768510464889,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Convex DevTools</title><link rel="stylesheet" href="/__convex_devtools__/_nuxt/entry.CXPHzcHp.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__convex_devtools__/_nuxt/DRR5kXdS.js"><script type="module" src="/__convex_devtools__/_nuxt/DRR5kXdS.js" crossorigin></script><script id="unhead:payload" type="application/json">{"title":"Convex DevTools"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__convex_devtools__",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Convex DevTools</title><link rel="stylesheet" href="/__convex_devtools__/_nuxt/entry.CXPHzcHp.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__convex_devtools__/_nuxt/DRR5kXdS.js"><script type="module" src="/__convex_devtools__/_nuxt/DRR5kXdS.js" crossorigin></script><script id="unhead:payload" type="application/json">{"title":"Convex DevTools"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__convex_devtools__",buildId:"e830e57d-37c5-4c85-b066-5cda3df527f3",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1768510467224,false]</script></body></html>
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -3,6 +3,25 @@ import type { ConvexClient } from 'convex/browser'
|
|
|
3
3
|
|
|
4
4
|
type AuthClient = ReturnType<typeof createAuthClient>
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Convex module public runtime config
|
|
8
|
+
*/
|
|
9
|
+
export interface ConvexPublicRuntimeConfig {
|
|
10
|
+
/** Convex deployment URL (WebSocket) */
|
|
11
|
+
url?: string
|
|
12
|
+
/** Convex site URL (HTTP/Auth) */
|
|
13
|
+
siteUrl?: string
|
|
14
|
+
/** Routes that should skip auth checks */
|
|
15
|
+
skipAuthRoutes?: string[]
|
|
16
|
+
/** Logging options */
|
|
17
|
+
logging?: {
|
|
18
|
+
enabled?: boolean | 'debug'
|
|
19
|
+
format?: 'pretty' | 'json'
|
|
20
|
+
}
|
|
21
|
+
/** Index signature for compatibility with Record<string, unknown> */
|
|
22
|
+
[key: string]: unknown
|
|
23
|
+
}
|
|
24
|
+
|
|
6
25
|
declare module '#app' {
|
|
7
26
|
interface NuxtApp {
|
|
8
27
|
$convex: ConvexClient
|
|
@@ -19,4 +38,19 @@ declare module 'vue' {
|
|
|
19
38
|
}
|
|
20
39
|
}
|
|
21
40
|
|
|
41
|
+
declare module 'nuxt/schema' {
|
|
42
|
+
interface PublicRuntimeConfig {
|
|
43
|
+
convex?: ConvexPublicRuntimeConfig
|
|
44
|
+
}
|
|
45
|
+
interface RuntimeConfig {
|
|
46
|
+
convexDevtoolsPath?: string
|
|
47
|
+
}
|
|
48
|
+
interface NuxtConfig {
|
|
49
|
+
convex?: ConvexPublicRuntimeConfig
|
|
50
|
+
}
|
|
51
|
+
interface NuxtOptions {
|
|
52
|
+
convex?: ConvexPublicRuntimeConfig
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
22
56
|
export {}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { type useNuxtApp } from '#app';
|
|
2
2
|
export { type QueryStatus, parseConvexResponse, computeQueryStatus, getFunctionName, hashArgs, getQueryKey, } from './convex-shared.js';
|
|
3
3
|
type NuxtApp = ReturnType<typeof useNuxtApp>;
|
|
4
|
+
/**
|
|
5
|
+
* Subscription entry with reference counting.
|
|
6
|
+
* Multiple components can share the same subscription.
|
|
7
|
+
*/
|
|
8
|
+
export interface SubscriptionEntry {
|
|
9
|
+
unsubscribe: () => void;
|
|
10
|
+
refCount: number;
|
|
11
|
+
}
|
|
4
12
|
/**
|
|
5
13
|
* Subscription cache stored on NuxtApp
|
|
6
14
|
*/
|
|
7
|
-
export type SubscriptionCache = Record<string,
|
|
15
|
+
export type SubscriptionCache = Record<string, SubscriptionEntry | undefined>;
|
|
8
16
|
export interface FetchAuthTokenOptions {
|
|
9
17
|
/** Whether this is a public query (skip auth) */
|
|
10
18
|
isPublic: boolean;
|
|
@@ -58,13 +66,15 @@ export declare function getCachedAuthToken(): string | undefined;
|
|
|
58
66
|
*/
|
|
59
67
|
export declare function getSubscriptionCache(nuxtApp: NuxtApp): SubscriptionCache;
|
|
60
68
|
/**
|
|
61
|
-
* Register a subscription in the cache.
|
|
69
|
+
* Register a subscription in the cache with reference counting.
|
|
70
|
+
* If a subscription already exists, increments the ref count instead of replacing.
|
|
62
71
|
*
|
|
63
72
|
* @param nuxtApp - The NuxtApp instance
|
|
64
73
|
* @param cacheKey - Unique key for this subscription
|
|
65
74
|
* @param unsubscribe - The unsubscribe function
|
|
75
|
+
* @returns true if this component should manage the subscription (first registrant), false if joining existing
|
|
66
76
|
*/
|
|
67
|
-
export declare function registerSubscription(nuxtApp: NuxtApp, cacheKey: string, unsubscribe: () => void):
|
|
77
|
+
export declare function registerSubscription(nuxtApp: NuxtApp, cacheKey: string, unsubscribe: () => void): boolean;
|
|
68
78
|
/**
|
|
69
79
|
* Check if a subscription already exists in the cache.
|
|
70
80
|
*
|
|
@@ -73,23 +83,35 @@ export declare function registerSubscription(nuxtApp: NuxtApp, cacheKey: string,
|
|
|
73
83
|
* @returns True if subscription exists
|
|
74
84
|
*/
|
|
75
85
|
export declare function hasSubscription(nuxtApp: NuxtApp, cacheKey: string): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Get the current subscription entry from the cache.
|
|
88
|
+
*
|
|
89
|
+
* @param nuxtApp - The NuxtApp instance
|
|
90
|
+
* @param cacheKey - Unique key for this subscription
|
|
91
|
+
* @returns The subscription entry if it exists, undefined otherwise
|
|
92
|
+
*/
|
|
93
|
+
export declare function getSubscription(nuxtApp: NuxtApp, cacheKey: string): SubscriptionEntry | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Decrement reference count and cleanup subscription if no more references.
|
|
96
|
+
* Returns true if the subscription was actually unsubscribed.
|
|
97
|
+
*
|
|
98
|
+
* @param nuxtApp - The NuxtApp instance
|
|
99
|
+
* @param cacheKey - Unique key for this subscription
|
|
100
|
+
* @returns true if subscription was unsubscribed, false if still has references
|
|
101
|
+
*/
|
|
102
|
+
export declare function releaseSubscription(nuxtApp: NuxtApp, cacheKey: string): boolean;
|
|
76
103
|
/**
|
|
77
104
|
* Clean up a subscription from the cache.
|
|
78
105
|
* Calls the unsubscribe function and removes from cache.
|
|
106
|
+
* DEPRECATED: Use releaseSubscription for ref-counted cleanup.
|
|
79
107
|
*
|
|
80
108
|
* @param nuxtApp - The NuxtApp instance
|
|
81
109
|
* @param cacheKey - Unique key for this subscription
|
|
82
|
-
*
|
|
83
|
-
* @example
|
|
84
|
-
* ```ts
|
|
85
|
-
* // In cleanup/unmount
|
|
86
|
-
* cleanupSubscription(nuxtApp, cacheKey)
|
|
87
|
-
* ```
|
|
88
110
|
*/
|
|
89
111
|
export declare function cleanupSubscription(nuxtApp: NuxtApp, cacheKey: string): void;
|
|
90
112
|
/**
|
|
91
113
|
* Remove a subscription from the cache without calling unsubscribe.
|
|
92
|
-
* Use
|
|
114
|
+
* DEPRECATED: Use releaseSubscription for ref-counted cleanup.
|
|
93
115
|
*
|
|
94
116
|
* @param nuxtApp - The NuxtApp instance
|
|
95
117
|
* @param cacheKey - Unique key for this subscription
|
|
@@ -46,17 +46,41 @@ export function getSubscriptionCache(nuxtApp) {
|
|
|
46
46
|
}
|
|
47
47
|
export function registerSubscription(nuxtApp, cacheKey, unsubscribe) {
|
|
48
48
|
const cache = getSubscriptionCache(nuxtApp);
|
|
49
|
-
cache[cacheKey]
|
|
49
|
+
const existing = cache[cacheKey];
|
|
50
|
+
if (existing) {
|
|
51
|
+
existing.refCount++;
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
cache[cacheKey] = { unsubscribe, refCount: 1 };
|
|
55
|
+
return true;
|
|
50
56
|
}
|
|
51
57
|
export function hasSubscription(nuxtApp, cacheKey) {
|
|
52
58
|
const cache = getSubscriptionCache(nuxtApp);
|
|
53
59
|
return !!cache[cacheKey];
|
|
54
60
|
}
|
|
61
|
+
export function getSubscription(nuxtApp, cacheKey) {
|
|
62
|
+
const cache = getSubscriptionCache(nuxtApp);
|
|
63
|
+
return cache[cacheKey];
|
|
64
|
+
}
|
|
65
|
+
export function releaseSubscription(nuxtApp, cacheKey) {
|
|
66
|
+
const cache = getSubscriptionCache(nuxtApp);
|
|
67
|
+
const entry = cache[cacheKey];
|
|
68
|
+
if (!entry) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
entry.refCount--;
|
|
72
|
+
if (entry.refCount <= 0) {
|
|
73
|
+
entry.unsubscribe();
|
|
74
|
+
cache[cacheKey] = void 0;
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
55
79
|
export function cleanupSubscription(nuxtApp, cacheKey) {
|
|
56
80
|
const cache = getSubscriptionCache(nuxtApp);
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
59
|
-
unsubscribe();
|
|
81
|
+
const entry = cache[cacheKey];
|
|
82
|
+
if (entry) {
|
|
83
|
+
entry.unsubscribe();
|
|
60
84
|
cache[cacheKey] = void 0;
|
|
61
85
|
}
|
|
62
86
|
}
|
package/package.json
CHANGED
package/dist/runtime/devtools/ui/dist/_nuxt/builds/meta/3bfccd49-ba9e-4cb1-a2c9-c8dd3a9b8463.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"id":"3bfccd49-ba9e-4cb1-a2c9-c8dd3a9b8463","timestamp":1768401017389,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|