@uploadista/vue 0.0.20-beta.9 → 0.1.0-beta.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.
Files changed (77) hide show
  1. package/dist/components/index.d.mts +3 -3
  2. package/dist/components/index.mjs +1 -1
  3. package/dist/{components-CskPs6sR.css → components-B_L33hsM.css} +33 -33
  4. package/dist/{components-CskPs6sR.css.map → components-B_L33hsM.css.map} +1 -1
  5. package/dist/components-MZ9ETx9c.mjs +2 -0
  6. package/dist/components-MZ9ETx9c.mjs.map +1 -0
  7. package/dist/composables/index.d.mts +1 -1
  8. package/dist/composables/index.mjs +1 -1
  9. package/dist/composables-Dny_9Zrg.mjs +2 -0
  10. package/dist/composables-Dny_9Zrg.mjs.map +1 -0
  11. package/dist/index-6Scxoy1b.d.mts +1289 -0
  12. package/dist/index-6Scxoy1b.d.mts.map +1 -0
  13. package/dist/{index-B2fUTjNP.d.mts → index-BpCRFLJ5.d.mts} +4 -4
  14. package/dist/index-BpCRFLJ5.d.mts.map +1 -0
  15. package/dist/{index-DiRR_Ua6.d.mts → index-RY4FPqAk.d.mts} +431 -432
  16. package/dist/index-RY4FPqAk.d.mts.map +1 -0
  17. package/dist/index.d.mts +5 -5
  18. package/dist/index.mjs +1 -1
  19. package/dist/providers/index.d.mts +1 -1
  20. package/dist/providers/index.mjs +1 -1
  21. package/dist/{providers-fqmOwF71.mjs → providers-CjhEBaQV.mjs} +2 -2
  22. package/dist/providers-CjhEBaQV.mjs.map +1 -0
  23. package/dist/useUploadistaClient-WVuo8jYH.mjs.map +1 -1
  24. package/dist/utils/index.d.mts +62 -2
  25. package/dist/utils/index.d.mts.map +1 -0
  26. package/package.json +11 -9
  27. package/src/__tests__/setup.ts +154 -0
  28. package/src/components/FlowUploadList.vue +25 -24
  29. package/src/components/UploadList.vue +3 -6
  30. package/src/components/UploadZone.vue +2 -5
  31. package/src/components/flow/Flow.vue +16 -4
  32. package/src/components/flow/FlowDropZone.vue +4 -2
  33. package/src/components/flow/FlowInput.vue +14 -8
  34. package/src/components/flow/FlowInputDropZone.vue +4 -2
  35. package/src/components/flow/FlowInputPreview.vue +3 -1
  36. package/src/components/flow/FlowProgress.vue +1 -1
  37. package/src/components/flow/FlowStatus.vue +1 -1
  38. package/src/components/flow/useFlowContext.ts +7 -5
  39. package/src/components/index.ts +4 -2
  40. package/src/components/upload/Upload.vue +146 -0
  41. package/src/components/upload/UploadCancel.vue +22 -0
  42. package/src/components/upload/UploadClearCompleted.vue +24 -0
  43. package/src/components/upload/UploadDropZone.vue +96 -0
  44. package/src/components/upload/UploadError.vue +42 -0
  45. package/src/components/upload/UploadItem.vue +54 -0
  46. package/src/components/upload/UploadItems.vue +33 -0
  47. package/src/components/upload/UploadProgress.vue +35 -0
  48. package/src/components/upload/UploadReset.vue +20 -0
  49. package/src/components/upload/UploadRetry.vue +22 -0
  50. package/src/components/upload/UploadStartAll.vue +30 -0
  51. package/src/components/upload/UploadStatus.vue +65 -0
  52. package/src/components/upload/index.ts +98 -0
  53. package/src/components/upload/useUploadContext.ts +67 -0
  54. package/src/composables/eventUtils.test.ts +267 -0
  55. package/src/composables/eventUtils.ts +5 -4
  56. package/src/composables/index.ts +1 -1
  57. package/src/composables/useDragDrop.test.ts +304 -0
  58. package/src/composables/useFlow.ts +6 -2
  59. package/src/composables/useFlowManagerContext.ts +5 -1
  60. package/src/composables/useUploadEvents.ts +1 -4
  61. package/src/composables/useUploadistaClient.test.ts +152 -0
  62. package/src/index.ts +65 -4
  63. package/src/providers/FlowManagerProvider.vue +5 -2
  64. package/src/utils/index.test.ts +396 -0
  65. package/src/utils/is-browser-file.test.ts +45 -0
  66. package/vitest.config.ts +25 -0
  67. package/dist/components-BxBz_7tS.mjs +0 -2
  68. package/dist/components-BxBz_7tS.mjs.map +0 -1
  69. package/dist/composables-BZ2c_WgI.mjs +0 -2
  70. package/dist/composables-BZ2c_WgI.mjs.map +0 -1
  71. package/dist/index-B2fUTjNP.d.mts.map +0 -1
  72. package/dist/index-BLNNvTVx.d.mts +0 -62
  73. package/dist/index-BLNNvTVx.d.mts.map +0 -1
  74. package/dist/index-D3PNaPGh.d.mts +0 -787
  75. package/dist/index-D3PNaPGh.d.mts.map +0 -1
  76. package/dist/index-DiRR_Ua6.d.mts.map +0 -1
  77. package/dist/providers-fqmOwF71.mjs.map +0 -1
@@ -0,0 +1,30 @@
1
+ <script setup lang="ts">
2
+ import { computed, inject } from "vue";
3
+ import type { UploadContextValue } from "./Upload.vue";
4
+ import { UPLOAD_CONTEXT_KEY } from "./useUploadContext";
5
+
6
+ const uploadContext = inject<{ value: UploadContextValue }>(UPLOAD_CONTEXT_KEY);
7
+ if (!uploadContext) {
8
+ throw new Error("UploadStartAll must be used within an <Upload> component.");
9
+ }
10
+
11
+ const idleCount = computed(
12
+ () =>
13
+ uploadContext.value.items.filter((item) => item.state.status === "idle")
14
+ .length,
15
+ );
16
+
17
+ const isDisabled = computed(
18
+ () => uploadContext.value.state.isUploading || idleCount.value === 0,
19
+ );
20
+
21
+ const handleClick = () => {
22
+ uploadContext.value.startAll();
23
+ };
24
+ </script>
25
+
26
+ <template>
27
+ <button type="button" :disabled="isDisabled" @click="handleClick">
28
+ <slot />
29
+ </button>
30
+ </template>
@@ -0,0 +1,65 @@
1
+ <script setup lang="ts">
2
+ import { computed, inject } from "vue";
3
+ import type { UploadContextValue } from "./Upload.vue";
4
+ import { UPLOAD_CONTEXT_KEY } from "./useUploadContext";
5
+
6
+ /**
7
+ * Slot props for UploadStatus component.
8
+ */
9
+ export interface UploadStatusSlotProps {
10
+ /** Overall status */
11
+ status: "idle" | "uploading" | "success" | "error";
12
+ /** Whether idle (no uploads active or completed) */
13
+ isIdle: boolean;
14
+ /** Whether uploading */
15
+ isUploading: boolean;
16
+ /** Whether all uploads succeeded */
17
+ isSuccess: boolean;
18
+ /** Whether any upload failed */
19
+ isError: boolean;
20
+ /** Whether all uploads completed (success or failure) */
21
+ isComplete: boolean;
22
+ /** Number of total items */
23
+ total: number;
24
+ /** Number of successful uploads */
25
+ successful: number;
26
+ /** Number of failed uploads */
27
+ failed: number;
28
+ /** Number of currently uploading */
29
+ uploading: number;
30
+ }
31
+
32
+ const uploadContext = inject<{ value: UploadContextValue }>(UPLOAD_CONTEXT_KEY);
33
+ if (!uploadContext) {
34
+ throw new Error("UploadStatus must be used within an <Upload> component.");
35
+ }
36
+
37
+ const slotProps = computed<UploadStatusSlotProps>(() => {
38
+ const state = uploadContext.value.state;
39
+
40
+ // Derive overall status
41
+ let status: "idle" | "uploading" | "success" | "error" = "idle";
42
+ if (state.isUploading) {
43
+ status = "uploading";
44
+ } else if (state.isComplete) {
45
+ status = state.failed > 0 ? "error" : "success";
46
+ }
47
+
48
+ return {
49
+ status,
50
+ isIdle: status === "idle",
51
+ isUploading: state.isUploading,
52
+ isSuccess: state.isComplete && state.failed === 0,
53
+ isError: state.failed > 0,
54
+ isComplete: state.isComplete,
55
+ total: state.total,
56
+ successful: state.successful,
57
+ failed: state.failed,
58
+ uploading: state.uploading,
59
+ };
60
+ });
61
+ </script>
62
+
63
+ <template>
64
+ <slot v-bind="slotProps" />
65
+ </template>
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Vue 3 Upload Compound Components for Uploadista
3
+ *
4
+ * These components provide a composable, headless API for building upload interfaces.
5
+ * They use Vue's provide/inject for context and scoped slots for complete UI control.
6
+ *
7
+ * @example Simple Drop Zone (Single File)
8
+ * ```vue
9
+ * <template>
10
+ * <Upload @success="handleSuccess">
11
+ * <UploadDropZone accept="image/*" v-slot="{ isDragging, dragHandlers, inputProps, onInputChange, openFilePicker }">
12
+ * <div v-bind="dragHandlers" @click="openFilePicker">
13
+ * <input type="file" v-bind="inputProps" @change="onInputChange" style="display: none" />
14
+ * {{ isDragging ? 'Drop here' : 'Drag or click' }}
15
+ * </div>
16
+ * </UploadDropZone>
17
+ * <UploadProgress v-slot="{ progress, isUploading }">
18
+ * <progress v-if="isUploading" :value="progress" max="100" />
19
+ * </UploadProgress>
20
+ * </Upload>
21
+ * </template>
22
+ *
23
+ * <script setup>
24
+ * import { Upload, UploadDropZone, UploadProgress } from '@uploadista/vue'
25
+ *
26
+ * const handleSuccess = (result) => {
27
+ * console.log('Upload complete:', result)
28
+ * }
29
+ * </script>
30
+ * ```
31
+ *
32
+ * @example Multi-File Upload
33
+ * ```vue
34
+ * <template>
35
+ * <Upload multiple :max-concurrent="3" @complete="handleComplete">
36
+ * <UploadDropZone v-slot="{ dragHandlers, inputProps, onInputChange, openFilePicker }">
37
+ * <div v-bind="dragHandlers" @click="openFilePicker">
38
+ * <input type="file" v-bind="inputProps" @change="onInputChange" style="display: none" />
39
+ * Drop files here
40
+ * </div>
41
+ * </UploadDropZone>
42
+ * <UploadItems v-slot="{ items, isEmpty }">
43
+ * <p v-if="isEmpty">No files</p>
44
+ * <div v-else v-for="item in items" :key="item.id">
45
+ * <UploadItem :id="item.id" v-slot="{ file, state, abort, remove }">
46
+ * {{ file.name }}: {{ state.progress }}%
47
+ * <button @click="abort">Cancel</button>
48
+ * <button @click="remove">Remove</button>
49
+ * </UploadItem>
50
+ * </div>
51
+ * </UploadItems>
52
+ * <UploadStartAll>Upload All</UploadStartAll>
53
+ * <UploadCancel>Cancel All</UploadCancel>
54
+ * <UploadClearCompleted>Clear Completed</UploadClearCompleted>
55
+ * </Upload>
56
+ * </template>
57
+ * ```
58
+ */
59
+
60
+ export type { UploadContextValue, UploadProps } from "./Upload.vue";
61
+ // Root component
62
+ export { default as Upload } from "./Upload.vue";
63
+ // Action components
64
+ export { default as UploadCancel } from "./UploadCancel.vue";
65
+ export { default as UploadClearCompleted } from "./UploadClearCompleted.vue";
66
+ export type {
67
+ UploadDropZoneProps,
68
+ UploadDropZoneSlotProps,
69
+ } from "./UploadDropZone.vue";
70
+ // Drop zone
71
+ export { default as UploadDropZone } from "./UploadDropZone.vue";
72
+ export type { UploadErrorSlotProps } from "./UploadError.vue";
73
+ // Error
74
+ export { default as UploadError } from "./UploadError.vue";
75
+ export type { UploadItemProps, UploadItemSlotProps } from "./UploadItem.vue";
76
+ // Item
77
+ export { default as UploadItem } from "./UploadItem.vue";
78
+ export type { UploadItemsSlotProps } from "./UploadItems.vue";
79
+ // Items
80
+ export { default as UploadItems } from "./UploadItems.vue";
81
+ export type { UploadProgressSlotProps } from "./UploadProgress.vue";
82
+ // Progress
83
+ export { default as UploadProgress } from "./UploadProgress.vue";
84
+ export { default as UploadReset } from "./UploadReset.vue";
85
+ export { default as UploadRetry } from "./UploadRetry.vue";
86
+ export { default as UploadStartAll } from "./UploadStartAll.vue";
87
+ export type { UploadStatusSlotProps } from "./UploadStatus.vue";
88
+ // Status
89
+ export { default as UploadStatus } from "./UploadStatus.vue";
90
+
91
+ // Context hooks
92
+ export {
93
+ UPLOAD_CONTEXT_KEY,
94
+ UPLOAD_ITEM_CONTEXT_KEY,
95
+ type UploadItemContextValue,
96
+ useUploadContext,
97
+ useUploadItemContext,
98
+ } from "./useUploadContext";
@@ -0,0 +1,67 @@
1
+ import { inject } from "vue";
2
+ import type { UploadContextValue } from "./Upload.vue";
3
+
4
+ /**
5
+ * Injection key for the Upload context
6
+ */
7
+ export const UPLOAD_CONTEXT_KEY = "uploadContext";
8
+
9
+ /**
10
+ * Injection key for the UploadItem context
11
+ */
12
+ export const UPLOAD_ITEM_CONTEXT_KEY = "uploadItemContext";
13
+
14
+ /**
15
+ * Context value for a specific upload item within an Upload.
16
+ */
17
+ export interface UploadItemContextValue {
18
+ /** Item ID */
19
+ id: string;
20
+ /** The file being uploaded */
21
+ file: File | Blob;
22
+ /** Current upload state */
23
+ state: {
24
+ status: string;
25
+ progress: number;
26
+ bytesUploaded: number;
27
+ totalBytes: number | null;
28
+ error: Error | null;
29
+ result: unknown;
30
+ };
31
+ /** Abort this upload */
32
+ abort: () => void;
33
+ /** Retry this upload */
34
+ retry: () => void;
35
+ /** Remove this item from the queue */
36
+ remove: () => void;
37
+ }
38
+
39
+ /**
40
+ * Composable to access upload context from within an Upload component.
41
+ * @throws Error if used outside of an Upload component
42
+ */
43
+ export function useUploadContext(): UploadContextValue {
44
+ const context = inject<UploadContextValue>(UPLOAD_CONTEXT_KEY);
45
+ if (!context) {
46
+ throw new Error(
47
+ "useUploadContext must be used within an <Upload> component. " +
48
+ "Wrap your component tree with <Upload>",
49
+ );
50
+ }
51
+ return context;
52
+ }
53
+
54
+ /**
55
+ * Composable to access upload item context from within an UploadItem component.
56
+ * @throws Error if used outside of an UploadItem component
57
+ */
58
+ export function useUploadItemContext(): UploadItemContextValue {
59
+ const context = inject<UploadItemContextValue>(UPLOAD_ITEM_CONTEXT_KEY);
60
+ if (!context) {
61
+ throw new Error(
62
+ "useUploadItemContext must be used within an <UploadItem> component. " +
63
+ 'Wrap your component with <UploadItem id="...">',
64
+ );
65
+ }
66
+ return context;
67
+ }
@@ -0,0 +1,267 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { isFlowEvent, isUploadEvent } from "./eventUtils";
3
+
4
+ describe("eventUtils", () => {
5
+ describe("isFlowEvent", () => {
6
+ it("should return true for JobStart event", () => {
7
+ const event = { eventType: "job-start", jobId: "job-1" };
8
+ expect(isFlowEvent(event)).toBe(true);
9
+ });
10
+
11
+ it("should return true for JobEnd event", () => {
12
+ const event = { eventType: "job-end", jobId: "job-1" };
13
+ expect(isFlowEvent(event)).toBe(true);
14
+ });
15
+
16
+ it("should return true for FlowStart event", () => {
17
+ const event = {
18
+ eventType: "flow-start",
19
+ jobId: "job-1",
20
+ flowId: "flow-1",
21
+ };
22
+ expect(isFlowEvent(event)).toBe(true);
23
+ });
24
+
25
+ it("should return true for FlowEnd event", () => {
26
+ const event = {
27
+ eventType: "flow-end",
28
+ jobId: "job-1",
29
+ flowId: "flow-1",
30
+ };
31
+ expect(isFlowEvent(event)).toBe(true);
32
+ });
33
+
34
+ it("should return true for FlowError event", () => {
35
+ const event = {
36
+ eventType: "flow-error",
37
+ jobId: "job-1",
38
+ flowId: "flow-1",
39
+ error: "Something went wrong",
40
+ };
41
+ expect(isFlowEvent(event)).toBe(true);
42
+ });
43
+
44
+ it("should return true for FlowPause event", () => {
45
+ const event = {
46
+ eventType: "flow-pause",
47
+ jobId: "job-1",
48
+ flowId: "flow-1",
49
+ };
50
+ expect(isFlowEvent(event)).toBe(true);
51
+ });
52
+
53
+ it("should return true for FlowCancel event", () => {
54
+ const event = {
55
+ eventType: "flow-cancel",
56
+ jobId: "job-1",
57
+ flowId: "flow-1",
58
+ };
59
+ expect(isFlowEvent(event)).toBe(true);
60
+ });
61
+
62
+ it("should return true for NodeStart event", () => {
63
+ const event = {
64
+ eventType: "node-start",
65
+ jobId: "job-1",
66
+ flowId: "flow-1",
67
+ nodeId: "node-1",
68
+ nodeName: "input-node",
69
+ nodeType: "input",
70
+ };
71
+ expect(isFlowEvent(event)).toBe(true);
72
+ });
73
+
74
+ it("should return true for NodeEnd event", () => {
75
+ const event = {
76
+ eventType: "node-end",
77
+ jobId: "job-1",
78
+ flowId: "flow-1",
79
+ nodeId: "node-1",
80
+ nodeName: "input-node",
81
+ };
82
+ expect(isFlowEvent(event)).toBe(true);
83
+ });
84
+
85
+ it("should return true for NodePause event", () => {
86
+ const event = {
87
+ eventType: "node-pause",
88
+ jobId: "job-1",
89
+ flowId: "flow-1",
90
+ nodeId: "node-1",
91
+ nodeName: "input-node",
92
+ };
93
+ expect(isFlowEvent(event)).toBe(true);
94
+ });
95
+
96
+ it("should return true for NodeResume event", () => {
97
+ const event = {
98
+ eventType: "node-resume",
99
+ jobId: "job-1",
100
+ flowId: "flow-1",
101
+ nodeId: "node-1",
102
+ nodeName: "input-node",
103
+ nodeType: "input",
104
+ };
105
+ expect(isFlowEvent(event)).toBe(true);
106
+ });
107
+
108
+ it("should return true for NodeError event", () => {
109
+ const event = {
110
+ eventType: "node-error",
111
+ jobId: "job-1",
112
+ flowId: "flow-1",
113
+ nodeId: "node-1",
114
+ nodeName: "input-node",
115
+ error: "Node failed",
116
+ };
117
+ expect(isFlowEvent(event)).toBe(true);
118
+ });
119
+
120
+ it("should return true for NodeStream event", () => {
121
+ const event = {
122
+ eventType: "node-stream",
123
+ jobId: "job-1",
124
+ flowId: "flow-1",
125
+ nodeId: "node-1",
126
+ };
127
+ expect(isFlowEvent(event)).toBe(true);
128
+ });
129
+
130
+ it("should return true for NodeResponse event", () => {
131
+ const event = {
132
+ eventType: "node-response",
133
+ jobId: "job-1",
134
+ flowId: "flow-1",
135
+ nodeId: "node-1",
136
+ nodeName: "input-node",
137
+ data: {},
138
+ };
139
+ expect(isFlowEvent(event)).toBe(true);
140
+ });
141
+
142
+ it("should return false for upload events", () => {
143
+ const event = {
144
+ type: "upload-started",
145
+ data: { id: "upload-1" },
146
+ };
147
+ expect(isFlowEvent(event)).toBe(false);
148
+ });
149
+
150
+ it("should return false for events without eventType", () => {
151
+ const event = { type: "unknown" };
152
+ expect(isFlowEvent(event)).toBe(false);
153
+ });
154
+
155
+ it("should return false for unknown eventType values", () => {
156
+ const event = { eventType: "unknown-event" };
157
+ expect(isFlowEvent(event)).toBe(false);
158
+ });
159
+ });
160
+
161
+ describe("isUploadEvent", () => {
162
+ it("should return true for UPLOAD_STARTED event", () => {
163
+ const event = {
164
+ type: "upload-started",
165
+ data: { id: "upload-1", name: "test.txt", size: 100 },
166
+ };
167
+ expect(isUploadEvent(event)).toBe(true);
168
+ });
169
+
170
+ it("should return true for UPLOAD_PROGRESS event", () => {
171
+ const event = {
172
+ type: "upload-progress",
173
+ data: { id: "upload-1", progress: 50, total: 100 },
174
+ };
175
+ expect(isUploadEvent(event)).toBe(true);
176
+ });
177
+
178
+ it("should return true for UPLOAD_COMPLETE event", () => {
179
+ const event = {
180
+ type: "upload-complete",
181
+ data: { id: "upload-1", name: "test.txt", size: 100 },
182
+ };
183
+ expect(isUploadEvent(event)).toBe(true);
184
+ });
185
+
186
+ it("should return true for UPLOAD_FAILED event", () => {
187
+ const event = {
188
+ type: "upload-failed",
189
+ data: { id: "upload-1", error: "Upload failed" },
190
+ };
191
+ expect(isUploadEvent(event)).toBe(true);
192
+ });
193
+
194
+ it("should return true for UPLOAD_VALIDATION_SUCCESS event", () => {
195
+ const event = {
196
+ type: "upload-validation-success",
197
+ data: { id: "upload-1", validationType: "checksum" },
198
+ };
199
+ expect(isUploadEvent(event)).toBe(true);
200
+ });
201
+
202
+ it("should return true for UPLOAD_VALIDATION_FAILED event", () => {
203
+ const event = {
204
+ type: "upload-validation-failed",
205
+ data: {
206
+ id: "upload-1",
207
+ reason: "Checksum mismatch",
208
+ expected: "abc",
209
+ actual: "def",
210
+ },
211
+ };
212
+ expect(isUploadEvent(event)).toBe(true);
213
+ });
214
+
215
+ it("should return true for UPLOAD_VALIDATION_WARNING event", () => {
216
+ const event = {
217
+ type: "upload-validation-warning",
218
+ data: { id: "upload-1", message: "Warning message" },
219
+ };
220
+ expect(isUploadEvent(event)).toBe(true);
221
+ });
222
+
223
+ it("should return false for flow events", () => {
224
+ const event = {
225
+ eventType: "flow-start",
226
+ jobId: "job-1",
227
+ flowId: "flow-1",
228
+ };
229
+ expect(isUploadEvent(event)).toBe(false);
230
+ });
231
+
232
+ it("should return false for events without type", () => {
233
+ const event = { eventType: "flow-start" };
234
+ expect(isUploadEvent(event)).toBe(false);
235
+ });
236
+
237
+ it("should return false for unknown type values", () => {
238
+ const event = { type: "unknown-type" };
239
+ expect(isUploadEvent(event)).toBe(false);
240
+ });
241
+ });
242
+
243
+ describe("combined behavior", () => {
244
+ it("should not classify the same event as both flow and upload", () => {
245
+ const flowEvent = {
246
+ eventType: "flow-start",
247
+ jobId: "job-1",
248
+ flowId: "flow-1",
249
+ };
250
+ const uploadEvent = {
251
+ type: "upload-started",
252
+ data: { id: "upload-1" },
253
+ };
254
+
255
+ expect(isFlowEvent(flowEvent)).toBe(true);
256
+ expect(isUploadEvent(flowEvent)).toBe(false);
257
+
258
+ expect(isUploadEvent(uploadEvent)).toBe(true);
259
+ expect(isFlowEvent(uploadEvent)).toBe(false);
260
+ });
261
+
262
+ it("should return false for empty objects", () => {
263
+ expect(isFlowEvent({})).toBe(false);
264
+ expect(isUploadEvent({})).toBe(false);
265
+ });
266
+ });
267
+ });
@@ -1,11 +1,11 @@
1
- import type { UploadistaEvent } from "@uploadista/client-browser";
2
1
  import { EventType, type FlowEvent } from "@uploadista/core/flow";
3
- import { UploadEventType, type UploadEvent } from "@uploadista/core/types";
2
+ import { type UploadEvent, UploadEventType } from "@uploadista/core/types";
4
3
 
5
4
  /**
6
5
  * Type guard to check if an event is a flow event
7
6
  */
8
- export function isFlowEvent(event: UploadistaEvent): event is FlowEvent {
7
+ export function isFlowEvent(event: unknown): event is FlowEvent {
8
+ if (typeof event !== "object" || event === null) return false;
9
9
  if (!("eventType" in event)) return false;
10
10
  const e = event as { eventType: unknown };
11
11
  return (
@@ -29,7 +29,8 @@ export function isFlowEvent(event: UploadistaEvent): event is FlowEvent {
29
29
  /**
30
30
  * Type guard to check if an event is an upload event
31
31
  */
32
- export function isUploadEvent(event: UploadistaEvent): event is UploadEvent {
32
+ export function isUploadEvent(event: unknown): event is UploadEvent {
33
+ if (typeof event !== "object" || event === null) return false;
33
34
  if (!("type" in event)) return false;
34
35
  const e = event as { type: unknown };
35
36
  return (
@@ -1,6 +1,5 @@
1
1
  // Event composables
2
2
  export { isFlowEvent, isUploadEvent } from "./eventUtils";
3
- export { useUploadistaEvents } from "./useUploadistaEvents";
4
3
  export type { UseFlowEventsOptions } from "./useFlowEvents";
5
4
  export { useFlowEvents } from "./useFlowEvents";
6
5
  export type {
@@ -13,6 +12,7 @@ export type {
13
12
  UseUploadEventsOptions,
14
13
  } from "./useUploadEvents";
15
14
  export { useUploadEvents } from "./useUploadEvents";
15
+ export { useUploadistaEvents } from "./useUploadistaEvents";
16
16
 
17
17
  // Plugin
18
18