@tthr/vue 0.0.82 → 0.0.83
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/index.d.ts +39 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -4
- package/dist/index.js.map +1 -1
- package/nuxt/module.js +8 -0
- package/nuxt/runtime/composables.js +46 -2
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,12 @@ export interface QueryState<T> {
|
|
|
25
25
|
isLoading: Ref<boolean>;
|
|
26
26
|
refetch: () => Promise<void>;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Thenable query state — can be awaited or destructured directly.
|
|
30
|
+
* When awaited, resolves after the initial fetch completes (data is populated).
|
|
31
|
+
* When destructured without await, data starts as undefined and populates reactively.
|
|
32
|
+
*/
|
|
33
|
+
export type AsyncQueryState<T> = QueryState<T> & PromiseLike<QueryState<T>>;
|
|
28
34
|
/**
|
|
29
35
|
* Query function reference
|
|
30
36
|
*/
|
|
@@ -36,17 +42,23 @@ export interface QueryFunction<TArgs = void, TResult = unknown> {
|
|
|
36
42
|
/**
|
|
37
43
|
* Reactive query composable
|
|
38
44
|
*
|
|
45
|
+
* Can be used with or without await:
|
|
46
|
+
*
|
|
39
47
|
* @example
|
|
40
48
|
* ```vue
|
|
41
49
|
* <script setup>
|
|
42
50
|
* import { useQuery } from '@tthr/vue';
|
|
43
51
|
* import { api } from '../_generated/api';
|
|
44
52
|
*
|
|
53
|
+
* // Reactive — data fills in asynchronously, updates in realtime
|
|
45
54
|
* const posts = useQuery(api.posts.list);
|
|
55
|
+
*
|
|
56
|
+
* // Awaited — data is populated when the promise resolves, still updates in realtime
|
|
57
|
+
* const { data: posts } = await useQuery(api.posts.list);
|
|
46
58
|
* </script>
|
|
47
59
|
* ```
|
|
48
60
|
*/
|
|
49
|
-
export declare function useQuery<TArgs, TResult>(query: QueryFunction<TArgs, TResult>, args?: TArgs):
|
|
61
|
+
export declare function useQuery<TArgs, TResult>(query: QueryFunction<TArgs, TResult>, args?: TArgs): AsyncQueryState<TResult>;
|
|
50
62
|
/**
|
|
51
63
|
* Mutation state returned by useMutation
|
|
52
64
|
*/
|
|
@@ -101,6 +113,32 @@ export interface UseMutationOptions {
|
|
|
101
113
|
* ```
|
|
102
114
|
*/
|
|
103
115
|
export declare function useMutation<TArgs, TResult>(mutation: MutationFunction<TArgs, TResult>, options?: UseMutationOptions): MutationState<TArgs, TResult>;
|
|
116
|
+
/**
|
|
117
|
+
* Execute a query and return raw data directly.
|
|
118
|
+
*
|
|
119
|
+
* Unlike useQuery, this does NOT set up reactive state or subscriptions.
|
|
120
|
+
* Use this in event handlers, utilities, or anywhere you need a one-shot data fetch.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* import { $query } from '@tthr/vue';
|
|
125
|
+
* const messages = await $query(api.messages.listByChannel, { channelId });
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export declare function $query<TArgs, TResult>(query: QueryFunction<TArgs, TResult>, args?: TArgs): Promise<TResult>;
|
|
129
|
+
/**
|
|
130
|
+
* Execute a mutation and return the result directly.
|
|
131
|
+
*
|
|
132
|
+
* Unlike useMutation, this does NOT set up reactive state.
|
|
133
|
+
* Use this in event handlers, utilities, or anywhere you need a one-shot mutation.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* import { $mutation } from '@tthr/vue';
|
|
138
|
+
* const post = await $mutation(api.posts.create, { title: 'Hello' });
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export declare function $mutation<TArgs, TResult>(mutation: MutationFunction<TArgs, TResult>, args?: TArgs, options?: UseMutationOptions): Promise<TResult>;
|
|
104
142
|
export type { TetherClientOptions, MutationOptions } from '@tthr/client';
|
|
105
143
|
/**
|
|
106
144
|
* Tether Nuxt/Vue project configuration
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAA+B,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAKtE;;GAEG;AACH,eAAO,MAAM,YAAY;iBACV,GAAG,WAAW,mBAAmB;uBAK3B,mBAAmB;CAGvC,CAAC;AAEF;;GAEG;AACH,wBAAgB,SAAS,IAAI,YAAY,CAKxC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,IAAI,EAAE,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IACzB,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACzB,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,GAAG,OAAO;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -31,13 +31,19 @@ export function useTether() {
|
|
|
31
31
|
/**
|
|
32
32
|
* Reactive query composable
|
|
33
33
|
*
|
|
34
|
+
* Can be used with or without await:
|
|
35
|
+
*
|
|
34
36
|
* @example
|
|
35
37
|
* ```vue
|
|
36
38
|
* <script setup>
|
|
37
39
|
* import { useQuery } from '@tthr/vue';
|
|
38
40
|
* import { api } from '../_generated/api';
|
|
39
41
|
*
|
|
42
|
+
* // Reactive — data fills in asynchronously, updates in realtime
|
|
40
43
|
* const posts = useQuery(api.posts.list);
|
|
44
|
+
*
|
|
45
|
+
* // Awaited — data is populated when the promise resolves, still updates in realtime
|
|
46
|
+
* const { data: posts } = await useQuery(api.posts.list);
|
|
41
47
|
* </script>
|
|
42
48
|
* ```
|
|
43
49
|
*/
|
|
@@ -61,9 +67,11 @@ export function useQuery(query, args) {
|
|
|
61
67
|
isLoading.value = false;
|
|
62
68
|
}
|
|
63
69
|
};
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
70
|
+
// Start the initial fetch immediately (not deferred to onMounted)
|
|
71
|
+
// so the composable can be awaited
|
|
72
|
+
const initialFetchPromise = fetchData();
|
|
73
|
+
onMounted(() => {
|
|
74
|
+
// Subscribe to realtime updates (fetch already started above)
|
|
67
75
|
const client = useTether();
|
|
68
76
|
unsubscribe = client.subscribe(query._name, args, (newData) => {
|
|
69
77
|
data.value = newData;
|
|
@@ -74,12 +82,14 @@ export function useQuery(query, args) {
|
|
|
74
82
|
unsubscribe();
|
|
75
83
|
}
|
|
76
84
|
});
|
|
77
|
-
|
|
85
|
+
const state = {
|
|
78
86
|
data: data,
|
|
79
87
|
error,
|
|
80
88
|
isLoading,
|
|
81
89
|
refetch: fetchData,
|
|
82
90
|
};
|
|
91
|
+
// Make it thenable — resolves when the initial fetch completes
|
|
92
|
+
return Object.assign(initialFetchPromise.then(() => state), state);
|
|
83
93
|
}
|
|
84
94
|
/**
|
|
85
95
|
* Mutation composable
|
|
@@ -136,6 +146,43 @@ export function useMutation(mutation, options) {
|
|
|
136
146
|
reset,
|
|
137
147
|
};
|
|
138
148
|
}
|
|
149
|
+
// ============================================================================
|
|
150
|
+
// Standalone Async Functions
|
|
151
|
+
// ============================================================================
|
|
152
|
+
/**
|
|
153
|
+
* Execute a query and return raw data directly.
|
|
154
|
+
*
|
|
155
|
+
* Unlike useQuery, this does NOT set up reactive state or subscriptions.
|
|
156
|
+
* Use this in event handlers, utilities, or anywhere you need a one-shot data fetch.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* import { $query } from '@tthr/vue';
|
|
161
|
+
* const messages = await $query(api.messages.listByChannel, { channelId });
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export async function $query(query, args) {
|
|
165
|
+
const client = useTether();
|
|
166
|
+
return client.query(query._name, args);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Execute a mutation and return the result directly.
|
|
170
|
+
*
|
|
171
|
+
* Unlike useMutation, this does NOT set up reactive state.
|
|
172
|
+
* Use this in event handlers, utilities, or anywhere you need a one-shot mutation.
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```ts
|
|
176
|
+
* import { $mutation } from '@tthr/vue';
|
|
177
|
+
* const post = await $mutation(api.posts.create, { title: 'Hello' });
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
export async function $mutation(mutation, args, options) {
|
|
181
|
+
const client = useTether();
|
|
182
|
+
return client.mutation(mutation._name, args, {
|
|
183
|
+
invalidates: options?.invalidates,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
139
186
|
/**
|
|
140
187
|
* Define Tether project configuration
|
|
141
188
|
* Used in tether.config.ts at the project root
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,EAAsB,MAAM,KAAK,CAAC;AACtE,OAAO,EAAE,YAAY,EAA4B,MAAM,cAAc,CAAC;AAEtE,yBAAyB;AACzB,IAAI,YAAY,GAAwB,IAAI,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,OAAO,CAAC,GAAQ,EAAE,OAA4B;QAC5C,YAAY,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;QACzC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACtC,CAAC;IAED,SAAS,CAAC,OAA4B;QACpC,YAAY,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/nuxt/module.js
CHANGED
|
@@ -91,6 +91,14 @@ export default defineNuxtModule({
|
|
|
91
91
|
name: 'useTetherSubscription',
|
|
92
92
|
from: resolver.resolve('./runtime/composables'),
|
|
93
93
|
},
|
|
94
|
+
{
|
|
95
|
+
name: '$query',
|
|
96
|
+
from: resolver.resolve('./runtime/composables'),
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: '$mutation',
|
|
100
|
+
from: resolver.resolve('./runtime/composables'),
|
|
101
|
+
},
|
|
94
102
|
]);
|
|
95
103
|
// Auto-import components
|
|
96
104
|
addComponent({
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Queries and mutations are executed server-side to keep API keys secure.
|
|
6
6
|
* WebSocket subscriptions run client-side for realtime updates - automatically!
|
|
7
7
|
*/
|
|
8
|
-
import { ref, onMounted, onUnmounted, computed } from 'vue';
|
|
8
|
+
import { ref, onMounted, onUnmounted, computed, watch } from 'vue';
|
|
9
9
|
import { useAsyncData } from '#imports';
|
|
10
10
|
// Singleton connection manager (client-side only)
|
|
11
11
|
let connectionManager = null;
|
|
@@ -256,13 +256,43 @@ export function useQuery(query, args) {
|
|
|
256
256
|
unsubscribe?.();
|
|
257
257
|
});
|
|
258
258
|
}
|
|
259
|
-
return
|
|
259
|
+
// Build the synchronous return object
|
|
260
|
+
const state = {
|
|
260
261
|
data: data,
|
|
261
262
|
error: error,
|
|
262
263
|
isLoading,
|
|
263
264
|
isConnected,
|
|
264
265
|
refetch,
|
|
265
266
|
};
|
|
267
|
+
// Create a promise that resolves when the initial fetch completes.
|
|
268
|
+
const initialFetchPromise = new Promise((resolve) => {
|
|
269
|
+
if (status.value !== 'pending') {
|
|
270
|
+
resolve(state);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const unwatch = watch(status, (newStatus) => {
|
|
274
|
+
if (newStatus !== 'pending') {
|
|
275
|
+
unwatch();
|
|
276
|
+
resolve(state);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
// Merge the promise onto the state object so it's both destructurable and thenable
|
|
281
|
+
return Object.assign(initialFetchPromise, state);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Execute a query and return raw data directly.
|
|
285
|
+
*/
|
|
286
|
+
export async function $query(query, args) {
|
|
287
|
+
const queryName = typeof query === 'string' ? query : query._name;
|
|
288
|
+
const response = await $fetch('/api/_tether/query', {
|
|
289
|
+
method: 'POST',
|
|
290
|
+
body: {
|
|
291
|
+
function: queryName,
|
|
292
|
+
args,
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
return response.data;
|
|
266
296
|
}
|
|
267
297
|
/**
|
|
268
298
|
* Mutation composable
|
|
@@ -319,6 +349,20 @@ export function useMutation(mutation) {
|
|
|
319
349
|
reset,
|
|
320
350
|
};
|
|
321
351
|
}
|
|
352
|
+
/**
|
|
353
|
+
* Execute a mutation and return the result directly.
|
|
354
|
+
*/
|
|
355
|
+
export async function $mutation(mutation, args) {
|
|
356
|
+
const mutationName = typeof mutation === 'string' ? mutation : mutation._name;
|
|
357
|
+
const response = await $fetch('/api/_tether/mutation', {
|
|
358
|
+
method: 'POST',
|
|
359
|
+
body: {
|
|
360
|
+
function: mutationName,
|
|
361
|
+
args,
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
return response.data;
|
|
365
|
+
}
|
|
322
366
|
/**
|
|
323
367
|
* Manual WebSocket subscription composable
|
|
324
368
|
*
|