nuxt-convex-module 0.13.0 → 0.14.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 (30) hide show
  1. package/dist/devtools-client/index.html +1 -1
  2. package/dist/module.d.mts +18 -0
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +120 -36
  5. package/dist/runtime/better-auth/nuxt/middleware.js +8 -2
  6. package/dist/runtime/better-auth/nuxt/no-session-vary.d.ts +38 -0
  7. package/dist/runtime/better-auth/nuxt/no-session-vary.js +21 -0
  8. package/dist/runtime/better-auth/nuxt/server.js +2 -1
  9. package/dist/runtime/better-auth/nuxt/shared-render.d.ts +9 -0
  10. package/dist/runtime/better-auth/nuxt/shared-render.js +17 -0
  11. package/dist/runtime/better-auth/vue/auth-client-loader.d.ts +17 -0
  12. package/dist/runtime/better-auth/vue/auth-client-loader.js +186 -0
  13. package/dist/runtime/better-auth/vue/cross-domain.d.ts +2 -2
  14. package/dist/runtime/better-auth/vue/cross-domain.js +52 -35
  15. package/dist/runtime/better-auth/vue/index.d.ts +1 -0
  16. package/dist/runtime/better-auth/vue/index.js +1 -0
  17. package/dist/runtime/better-auth/vue/plugin.client.js +21 -2
  18. package/dist/runtime/better-auth/vue/plugin.server.js +23 -3
  19. package/dist/runtime/better-auth/vue/token-store.js +4 -0
  20. package/dist/runtime/better-auth/vue/use-better-auth.d.ts +7 -1
  21. package/dist/runtime/better-auth/vue/use-better-auth.js +78 -6
  22. package/dist/runtime/nuxt/function-name.d.ts +9 -0
  23. package/dist/runtime/nuxt/function-name.js +38 -0
  24. package/dist/runtime/nuxt/index.js +4 -3
  25. package/dist/runtime/nuxt/testing.d.ts +21 -0
  26. package/dist/runtime/nuxt/testing.js +1 -0
  27. package/dist/runtime/vue/composables/use-upload-queue.d.ts +70 -3
  28. package/dist/runtime/vue/composables/use-upload-queue.js +74 -19
  29. package/dist/runtime/vue/index.d.ts +1 -1
  30. package/package.json +8 -1
@@ -1,4 +1,5 @@
1
- import { computed, ref } from "vue";
1
+ import { ConvexError } from "convex/values";
2
+ import { computed, ref, toRaw } from "vue";
2
3
  import { useConvexOrThrow } from "../client.js";
3
4
  import { uploadFile } from "./use-upload.js";
4
5
  function normalizeFiles(input) {
@@ -16,6 +17,8 @@ export function useUploadQueue(generateUploadUrl, options = {}) {
16
17
  const concurrency = Math.max(1, Math.floor(options.concurrency ?? 3));
17
18
  const items = ref([]);
18
19
  const controllers = /* @__PURE__ */ new Map();
20
+ const afterDone = /* @__PURE__ */ new Set();
21
+ const resend = /* @__PURE__ */ new Set();
19
22
  const activeCount = computed(
20
23
  () => items.value.filter((item) => item.status === "uploading").length
21
24
  );
@@ -38,31 +41,64 @@ export function useUploadQueue(generateUploadUrl, options = {}) {
38
41
  void run(item);
39
42
  }
40
43
  }
44
+ const isRefusal = options.isRefusal ?? ((error) => error instanceof ConvexError);
45
+ async function transfer(item, signal) {
46
+ if (options.prepare && item.prepared === null) {
47
+ item.stage = "prepare";
48
+ const prepared = await options.prepare(toRaw(item.file), item, signal);
49
+ signal.throwIfAborted();
50
+ item.prepared = prepared;
51
+ }
52
+ item.stage = "upload";
53
+ const url = await convex.mutation(generateUploadUrl, {});
54
+ const storageId = await uploadFile({
55
+ url,
56
+ // The blob itself, not a reactive proxy of it, wherever Vue would wrap one.
57
+ file: toRaw(item.prepared ?? item.file),
58
+ signal,
59
+ onProgress: (value) => {
60
+ item.progress = value;
61
+ }
62
+ });
63
+ item.progress = 1;
64
+ return storageId;
65
+ }
66
+ function refusal(failure, item) {
67
+ try {
68
+ return isRefusal(failure, item);
69
+ } catch {
70
+ return false;
71
+ }
72
+ }
73
+ function fail(item, caught, signal) {
74
+ const failure = caught instanceof Error ? caught : new Error(String(caught));
75
+ item.refused = !signal.aborted && refusal(failure, item);
76
+ if (item.refused && item.stage === "after") resend.add(item.id);
77
+ item.stage = null;
78
+ item.error = failure;
79
+ item.status = "error";
80
+ options.onItemError?.(failure, item);
81
+ }
41
82
  async function run(item) {
42
83
  item.status = "uploading";
43
84
  const controller = new AbortController();
44
85
  controllers.set(item.id, controller);
86
+ const { signal } = controller;
45
87
  try {
46
- const url = await convex.mutation(generateUploadUrl, {});
47
- const storageId = await uploadFile({
48
- url,
49
- file: item.file,
50
- signal: controller.signal,
51
- onProgress: (value) => {
52
- item.progress = value;
53
- }
54
- });
55
- item.storageId = storageId;
56
- item.progress = 1;
88
+ const storageId = item.storageId ??= await transfer(item, signal);
89
+ if (options.after && !afterDone.has(item.id)) {
90
+ item.stage = "after";
91
+ await options.after(storageId, item, signal);
92
+ signal.throwIfAborted();
93
+ afterDone.add(item.id);
94
+ }
95
+ item.stage = null;
57
96
  item.status = "success";
58
97
  await options.onItemSuccess?.(storageId, item);
59
98
  } catch (caught) {
60
- const failure = caught instanceof Error ? caught : new Error(String(caught));
61
- item.error = failure;
62
- item.status = "error";
63
- options.onItemError?.(failure, item);
99
+ fail(item, caught, signal);
64
100
  } finally {
65
- controllers.delete(item.id);
101
+ if (controllers.get(item.id) === controller) controllers.delete(item.id);
66
102
  if (pendingCount.value === 0 && activeCount.value === 0) {
67
103
  options.onComplete?.(items.value);
68
104
  } else {
@@ -80,7 +116,10 @@ export function useUploadQueue(generateUploadUrl, options = {}) {
80
116
  status: "pending",
81
117
  progress: 0,
82
118
  storageId: null,
83
- error: null
119
+ error: null,
120
+ refused: false,
121
+ stage: null,
122
+ prepared: null
84
123
  }))
85
124
  );
86
125
  pump();
@@ -93,11 +132,26 @@ export function useUploadQueue(generateUploadUrl, options = {}) {
93
132
  function remove(id) {
94
133
  controllers.get(id)?.abort();
95
134
  controllers.delete(id);
135
+ afterDone.delete(id);
136
+ resend.delete(id);
96
137
  items.value = items.value.filter((item) => item.id !== id);
97
138
  }
139
+ function retry(id) {
140
+ for (const item of items.value) {
141
+ if (item.status !== "error" || id !== void 0 && item.id !== id) continue;
142
+ item.status = "pending";
143
+ item.error = null;
144
+ item.refused = false;
145
+ if (resend.delete(item.id)) item.storageId = null;
146
+ if (item.storageId === null) item.progress = 0;
147
+ }
148
+ pump();
149
+ }
98
150
  function clear() {
99
151
  cancel();
100
152
  controllers.clear();
153
+ afterDone.clear();
154
+ resend.clear();
101
155
  items.value = [];
102
156
  }
103
157
  return {
@@ -109,7 +163,8 @@ export function useUploadQueue(generateUploadUrl, options = {}) {
109
163
  activeCount,
110
164
  cancel,
111
165
  remove,
112
- clear
166
+ clear,
167
+ retry
113
168
  };
114
169
  }
115
170
  export const useConvexUploadQueue = useUploadQueue;
@@ -88,6 +88,6 @@ export type { ConnectionState, OptimisticUpdate, QueryJournal, } from 'convex/br
88
88
  export type { FunctionReference, FunctionReference_future, FunctionArgs, FunctionReturnType, OptionalRestArgs, ArgsAndOptions, } from 'convex/server';
89
89
  export type { Value } from 'convex/values';
90
90
  export { useUpload, useConvexUpload, uploadFile, type VueUpload, type UseUploadOptions, type UploadFileOptions, type GenerateUploadUrl, type StorageId, } from './composables/use-upload.js';
91
- export { useUploadQueue, useConvexUploadQueue, type VueUploadQueue, type UseUploadQueueOptions, type UploadQueueItem, type UploadItemStatus, type EnqueueInput, } from './composables/use-upload-queue.js';
91
+ export { useUploadQueue, useConvexUploadQueue, type VueUploadQueue, type UseUploadQueueOptions, type UploadQueueItem, type UploadItemStage, type UploadItemStatus, type EnqueueInput, } from './composables/use-upload-queue.js';
92
92
  export { useStorageUrl, useConvexStorageUrl, type GetStorageUrl, } from './composables/use-storage-url.js';
93
93
  export { ConvexImage } from './components/convex-image.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "nuxt-convex-module",
4
- "version": "0.13.0",
4
+ "version": "0.14.0",
5
5
  "description": "Convex backend integration with live queries, mutations, actions, pagination, file storage and SSR, auto-imported and typed against your deployment. The same Vue client runs without Nuxt; Better Auth, Clerk, Auth0 and Polar are opt-in.",
6
6
  "repository": {
7
7
  "type": "git",
@@ -60,6 +60,10 @@
60
60
  "types": "./dist/runtime/nuxt/app.d.ts",
61
61
  "import": "./dist/runtime/nuxt/app.js"
62
62
  },
63
+ "./testing": {
64
+ "types": "./dist/runtime/nuxt/testing.d.ts",
65
+ "import": "./dist/runtime/nuxt/testing.js"
66
+ },
63
67
  "./better-auth/client": {
64
68
  "types": "./dist/runtime/better-auth/vue/index.d.ts",
65
69
  "import": "./dist/runtime/better-auth/vue/index.js"
@@ -115,6 +119,9 @@
115
119
  "app": [
116
120
  "./dist/runtime/nuxt/app.d.ts"
117
121
  ],
122
+ "testing": [
123
+ "./dist/runtime/nuxt/testing.d.ts"
124
+ ],
118
125
  "better-auth/client": [
119
126
  "./dist/runtime/better-auth/vue/index.d.ts"
120
127
  ],