@uploadbox/react 0.1.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 (52) hide show
  1. package/dist/generate-components.d.ts +5 -0
  2. package/dist/generate-components.d.ts.map +1 -0
  3. package/dist/generate-components.js +9 -0
  4. package/dist/generate-components.js.map +1 -0
  5. package/dist/index.d.ts +11 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +9 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/multipart.d.ts +25 -0
  10. package/dist/multipart.d.ts.map +1 -0
  11. package/dist/multipart.js +130 -0
  12. package/dist/multipart.js.map +1 -0
  13. package/dist/progress-tracker.d.ts +13 -0
  14. package/dist/progress-tracker.d.ts.map +1 -0
  15. package/dist/progress-tracker.js +93 -0
  16. package/dist/progress-tracker.js.map +1 -0
  17. package/dist/provider.d.ts +14 -0
  18. package/dist/provider.d.ts.map +1 -0
  19. package/dist/provider.js +12 -0
  20. package/dist/provider.js.map +1 -0
  21. package/dist/retry.d.ts +5 -0
  22. package/dist/retry.d.ts.map +1 -0
  23. package/dist/retry.js +47 -0
  24. package/dist/retry.js.map +1 -0
  25. package/dist/types.d.ts +86 -0
  26. package/dist/types.d.ts.map +1 -0
  27. package/dist/types.js +2 -0
  28. package/dist/types.js.map +1 -0
  29. package/dist/upload-button.d.ts +4 -0
  30. package/dist/upload-button.d.ts.map +1 -0
  31. package/dist/upload-button.js +25 -0
  32. package/dist/upload-button.js.map +1 -0
  33. package/dist/upload-dropzone.d.ts +4 -0
  34. package/dist/upload-dropzone.d.ts.map +1 -0
  35. package/dist/upload-dropzone.js +47 -0
  36. package/dist/upload-dropzone.js.map +1 -0
  37. package/dist/use-uploadbox.d.ts +4 -0
  38. package/dist/use-uploadbox.d.ts.map +1 -0
  39. package/dist/use-uploadbox.js +246 -0
  40. package/dist/use-uploadbox.js.map +1 -0
  41. package/package.json +56 -0
  42. package/src/generate-components.ts +20 -0
  43. package/src/index.ts +22 -0
  44. package/src/multipart.ts +189 -0
  45. package/src/progress-tracker.ts +107 -0
  46. package/src/provider.tsx +34 -0
  47. package/src/retry.ts +62 -0
  48. package/src/styles.css +126 -0
  49. package/src/types.ts +96 -0
  50. package/src/upload-button.tsx +76 -0
  51. package/src/upload-dropzone.tsx +138 -0
  52. package/src/use-uploadbox.ts +333 -0
@@ -0,0 +1,5 @@
1
+ import type { FileRouter } from "@uploadbox/core";
2
+ import type { UploadButtonProps, UploadDropzoneProps } from "./types.js";
3
+ export declare function generateUploadButton<TRouter extends FileRouter>(): <TEndpoint extends keyof TRouter & string>(props: UploadButtonProps<TRouter, TEndpoint>) => React.JSX.Element;
4
+ export declare function generateUploadDropzone<TRouter extends FileRouter>(): <TEndpoint extends keyof TRouter & string>(props: UploadDropzoneProps<TRouter, TEndpoint>) => React.JSX.Element;
5
+ //# sourceMappingURL=generate-components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-components.d.ts","sourceRoot":"","sources":["../src/generate-components.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAIzE,wBAAgB,oBAAoB,CAClC,OAAO,SAAS,UAAU,KAEH,CAAC,SAAS,SAAS,MAAM,OAAO,GAAG,MAAM,EAC9D,KAAK,EAAE,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,KACzC,KAAK,CAAC,GAAG,CAAC,OAAO,CACvB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,SAAS,UAAU,KAED,CAAC,SAAS,SAAS,MAAM,OAAO,GAAG,MAAM,EAChE,KAAK,EAAE,mBAAmB,CAAC,OAAO,EAAE,SAAS,CAAC,KAC3C,KAAK,CAAC,GAAG,CAAC,OAAO,CACvB"}
@@ -0,0 +1,9 @@
1
+ import { UploadButton } from "./upload-button.js";
2
+ import { UploadDropzone } from "./upload-dropzone.js";
3
+ export function generateUploadButton() {
4
+ return UploadButton;
5
+ }
6
+ export function generateUploadDropzone() {
7
+ return UploadDropzone;
8
+ }
9
+ //# sourceMappingURL=generate-components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-components.js","sourceRoot":"","sources":["../src/generate-components.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,UAAU,oBAAoB;IAGlC,OAAO,YAEe,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,sBAAsB;IAGpC,OAAO,cAEe,CAAC;AACzB,CAAC"}
@@ -0,0 +1,11 @@
1
+ export { UploadButton } from "./upload-button.js";
2
+ export { UploadDropzone } from "./upload-dropzone.js";
3
+ export { useUploadbox } from "./use-uploadbox.js";
4
+ export { generateUploadButton, generateUploadDropzone } from "./generate-components.js";
5
+ export { UploadboxProvider, useUploadboxConfig } from "./provider.js";
6
+ export type { UploadboxContextValue } from "./provider.js";
7
+ export { withRetry, DEFAULT_RETRY_CONFIG, isRetryableError } from "./retry.js";
8
+ export { ProgressTracker } from "./progress-tracker.js";
9
+ export { shouldUseMultipart, uploadFileMultipart } from "./multipart.js";
10
+ export type { UploadButtonProps, UploadDropzoneProps, UseUploadboxOpts, UseUploadboxReturn, UploadedFile, UploadProgressEvent, EndpointHelper, FileUploadStatus, FileProgress, EnhancedUploadProgressEvent, RetryConfig, } from "./types.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACtE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACzE,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,2BAA2B,EAC3B,WAAW,GACZ,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ export { UploadButton } from "./upload-button.js";
2
+ export { UploadDropzone } from "./upload-dropzone.js";
3
+ export { useUploadbox } from "./use-uploadbox.js";
4
+ export { generateUploadButton, generateUploadDropzone } from "./generate-components.js";
5
+ export { UploadboxProvider, useUploadboxConfig } from "./provider.js";
6
+ export { withRetry, DEFAULT_RETRY_CONFIG, isRetryableError } from "./retry.js";
7
+ export { ProgressTracker } from "./progress-tracker.js";
8
+ export { shouldUseMultipart, uploadFileMultipart } from "./multipart.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { RetryConfig } from "./types.js";
2
+ export declare function shouldUseMultipart(fileSize: number): boolean;
3
+ interface MultipartUploadOptions {
4
+ file: File;
5
+ routeKey: string;
6
+ fileInfo: {
7
+ name: string;
8
+ size: number;
9
+ type: string;
10
+ customMetadata?: Record<string, string>;
11
+ ttlSeconds?: number;
12
+ };
13
+ apiUrl?: string;
14
+ headers?: Record<string, string>;
15
+ retryConfig?: RetryConfig;
16
+ signal?: AbortSignal;
17
+ onProgress?: (loaded: number) => void;
18
+ onRetry?: () => void;
19
+ }
20
+ export declare function uploadFileMultipart(options: MultipartUploadOptions): Promise<{
21
+ key: string;
22
+ uploadId: string;
23
+ }>;
24
+ export {};
25
+ //# sourceMappingURL=multipart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart.d.ts","sourceRoot":"","sources":["../src/multipart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAQ9C,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,UAAU,sBAAsB;IAC9B,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAkDD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAkH5C"}
@@ -0,0 +1,130 @@
1
+ import { withRetry, DEFAULT_RETRY_CONFIG } from "./retry.js";
2
+ const DEFAULT_API_URL = "/api/uploadbox";
3
+ const MULTIPART_THRESHOLD = 10 * 1024 * 1024; // 10MB
4
+ const DEFAULT_PART_SIZE = 10 * 1024 * 1024; // 10MB
5
+ const MAX_CONCURRENT_PARTS = 4;
6
+ export function shouldUseMultipart(fileSize) {
7
+ return fileSize >= MULTIPART_THRESHOLD;
8
+ }
9
+ function uploadPartWithXhr(url, blob, onProgress, signal) {
10
+ return new Promise((resolve, reject) => {
11
+ const xhr = new XMLHttpRequest();
12
+ xhr.open("PUT", url);
13
+ if (signal) {
14
+ signal.addEventListener("abort", () => xhr.abort(), { once: true });
15
+ }
16
+ xhr.upload.addEventListener("progress", (event) => {
17
+ if (event.lengthComputable) {
18
+ onProgress?.(event.loaded);
19
+ }
20
+ });
21
+ xhr.addEventListener("load", () => {
22
+ if (xhr.status >= 200 && xhr.status < 300) {
23
+ const etag = xhr.getResponseHeader("ETag");
24
+ if (!etag) {
25
+ reject(new Error("Missing ETag in upload response — check S3 CORS exposeHeaders"));
26
+ return;
27
+ }
28
+ resolve(etag);
29
+ }
30
+ else {
31
+ reject(new Error(`Part upload failed with status ${xhr.status}`));
32
+ }
33
+ });
34
+ xhr.addEventListener("error", () => reject(new Error("Part upload failed")));
35
+ xhr.addEventListener("abort", () => reject(new Error("Upload aborted")));
36
+ xhr.send(blob);
37
+ });
38
+ }
39
+ export async function uploadFileMultipart(options) {
40
+ const { file, routeKey, fileInfo, apiUrl = DEFAULT_API_URL, headers, retryConfig, signal, onProgress, onRetry } = options;
41
+ // 1. Create multipart upload on server
42
+ const initRes = await fetch(apiUrl, {
43
+ method: "POST",
44
+ headers: { "Content-Type": "application/json", ...headers },
45
+ body: JSON.stringify({
46
+ action: "create-multipart",
47
+ routeKey,
48
+ file: fileInfo,
49
+ }),
50
+ signal,
51
+ });
52
+ if (!initRes.ok) {
53
+ const err = await initRes.json();
54
+ throw new Error(err.message || "Failed to create multipart upload");
55
+ }
56
+ const initData = await initRes.json();
57
+ const { fileKey, uploadId, parts, partSize } = initData;
58
+ // 2. Upload parts with concurrency
59
+ const completedParts = [];
60
+ const partLoaded = new Map();
61
+ let aborted = false;
62
+ const uploadPart = async (part) => {
63
+ if (signal?.aborted)
64
+ throw new Error("Upload aborted");
65
+ const start = (part.partNumber - 1) * partSize;
66
+ const end = Math.min(start + partSize, file.size);
67
+ const blob = file.slice(start, end);
68
+ const retry = retryConfig ?? DEFAULT_RETRY_CONFIG;
69
+ const etag = await withRetry(async () => {
70
+ return uploadPartWithXhr(part.url, blob, (loaded) => {
71
+ partLoaded.set(part.partNumber, loaded);
72
+ const totalLoaded = Array.from(partLoaded.values()).reduce((a, b) => a + b, 0);
73
+ onProgress?.(totalLoaded);
74
+ }, signal);
75
+ }, retry, () => {
76
+ partLoaded.set(part.partNumber, 0);
77
+ onRetry?.();
78
+ }, signal);
79
+ completedParts.push({ partNumber: part.partNumber, etag });
80
+ };
81
+ // Process parts with concurrency limit
82
+ const queue = [...parts];
83
+ const workers = [];
84
+ for (let i = 0; i < Math.min(MAX_CONCURRENT_PARTS, queue.length); i++) {
85
+ workers.push((async () => {
86
+ while (queue.length > 0 && !aborted) {
87
+ const part = queue.shift();
88
+ if (!part)
89
+ break;
90
+ await uploadPart(part);
91
+ }
92
+ })());
93
+ }
94
+ try {
95
+ await Promise.all(workers);
96
+ }
97
+ catch (err) {
98
+ aborted = true;
99
+ // Abort the multipart upload on failure
100
+ await fetch(apiUrl, {
101
+ method: "POST",
102
+ headers: { "Content-Type": "application/json", ...headers },
103
+ body: JSON.stringify({
104
+ action: "abort-multipart",
105
+ fileKey,
106
+ uploadId,
107
+ }),
108
+ }).catch(() => { });
109
+ throw err;
110
+ }
111
+ // 3. Complete multipart upload on server
112
+ const completeRes = await fetch(apiUrl, {
113
+ method: "POST",
114
+ headers: { "Content-Type": "application/json", ...headers },
115
+ body: JSON.stringify({
116
+ action: "complete-multipart",
117
+ routeKey,
118
+ fileKey,
119
+ uploadId,
120
+ parts: completedParts,
121
+ }),
122
+ signal,
123
+ });
124
+ if (!completeRes.ok) {
125
+ const err = await completeRes.json();
126
+ throw new Error(err.message || "Failed to complete multipart upload");
127
+ }
128
+ return { key: fileKey, uploadId };
129
+ }
130
+ //# sourceMappingURL=multipart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart.js","sourceRoot":"","sources":["../src/multipart.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { FileUploadStatus, EnhancedUploadProgressEvent } from "./types.js";
2
+ export declare class ProgressTracker {
3
+ private files;
4
+ private speedSamples;
5
+ init(fileId: string, name: string, size: number, type: string): void;
6
+ updateProgress(fileId: string, loaded: number): void;
7
+ setStatus(fileId: string, status: FileUploadStatus, error?: string): void;
8
+ setKey(fileId: string, key: string): void;
9
+ incrementRetry(fileId: string): void;
10
+ getSnapshot(): EnhancedUploadProgressEvent;
11
+ reset(): void;
12
+ }
13
+ //# sourceMappingURL=progress-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-tracker.d.ts","sourceRoot":"","sources":["../src/progress-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAS9F,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,YAAY,CAAoC;IAExD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAgBpE,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IA+BpD,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAYzE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAKzC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAYpC,WAAW,IAAI,2BAA2B;IAa1C,KAAK,IAAI,IAAI;CAId"}
@@ -0,0 +1,93 @@
1
+ const SPEED_WINDOW_MS = 3000;
2
+ export class ProgressTracker {
3
+ files = new Map();
4
+ speedSamples = new Map();
5
+ init(fileId, name, size, type) {
6
+ this.files.set(fileId, {
7
+ fileId,
8
+ name,
9
+ size,
10
+ type,
11
+ status: "pending",
12
+ loaded: 0,
13
+ percent: 0,
14
+ speed: 0,
15
+ eta: 0,
16
+ retryCount: 0,
17
+ });
18
+ this.speedSamples.set(fileId, []);
19
+ }
20
+ updateProgress(fileId, loaded) {
21
+ const file = this.files.get(fileId);
22
+ if (!file)
23
+ return;
24
+ file.loaded = loaded;
25
+ file.percent = file.size > 0 ? Math.round((loaded / file.size) * 100) : 0;
26
+ file.status = "uploading";
27
+ // Update speed samples
28
+ const samples = this.speedSamples.get(fileId) ?? [];
29
+ const now = Date.now();
30
+ samples.push({ timestamp: now, loaded });
31
+ // Prune old samples
32
+ const cutoff = now - SPEED_WINDOW_MS;
33
+ const validSamples = samples.filter((s) => s.timestamp >= cutoff);
34
+ this.speedSamples.set(fileId, validSamples);
35
+ // Calculate speed from sliding window
36
+ if (validSamples.length >= 2) {
37
+ const oldest = validSamples[0];
38
+ const newest = validSamples[validSamples.length - 1];
39
+ const timeDiff = (newest.timestamp - oldest.timestamp) / 1000;
40
+ if (timeDiff > 0) {
41
+ file.speed = (newest.loaded - oldest.loaded) / timeDiff;
42
+ const remaining = file.size - loaded;
43
+ file.eta = file.speed > 0 ? remaining / file.speed : 0;
44
+ }
45
+ }
46
+ }
47
+ setStatus(fileId, status, error) {
48
+ const file = this.files.get(fileId);
49
+ if (!file)
50
+ return;
51
+ file.status = status;
52
+ if (error)
53
+ file.error = error;
54
+ if (status === "complete") {
55
+ file.loaded = file.size;
56
+ file.percent = 100;
57
+ file.eta = 0;
58
+ }
59
+ }
60
+ setKey(fileId, key) {
61
+ const file = this.files.get(fileId);
62
+ if (file)
63
+ file.key = key;
64
+ }
65
+ incrementRetry(fileId) {
66
+ const file = this.files.get(fileId);
67
+ if (!file)
68
+ return;
69
+ file.retryCount++;
70
+ file.status = "retrying";
71
+ file.loaded = 0;
72
+ file.percent = 0;
73
+ file.speed = 0;
74
+ file.eta = 0;
75
+ this.speedSamples.set(fileId, []);
76
+ }
77
+ getSnapshot() {
78
+ const allFiles = Array.from(this.files.values());
79
+ const totalSize = allFiles.reduce((sum, f) => sum + f.size, 0);
80
+ const totalLoaded = allFiles.reduce((sum, f) => sum + f.loaded, 0);
81
+ return {
82
+ loaded: totalLoaded,
83
+ total: totalSize,
84
+ percent: totalSize > 0 ? Math.round((totalLoaded / totalSize) * 100) : 0,
85
+ fileProgress: allFiles.map((f) => ({ ...f })),
86
+ };
87
+ }
88
+ reset() {
89
+ this.files.clear();
90
+ this.speedSamples.clear();
91
+ }
92
+ }
93
+ //# sourceMappingURL=progress-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-tracker.js","sourceRoot":"","sources":["../src/progress-tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ export interface UploadboxContextValue {
3
+ /** Base URL for the upload API. Defaults to "/api/uploadbox". */
4
+ apiUrl?: string;
5
+ /** API key for hosted mode — sent as Authorization: Bearer. */
6
+ apiKey?: string;
7
+ /** Extra headers to include with every request. */
8
+ headers?: Record<string, string>;
9
+ }
10
+ export declare function UploadboxProvider({ children, ...config }: UploadboxContextValue & {
11
+ children: React.ReactNode;
12
+ }): import("react/jsx-runtime").JSX.Element;
13
+ export declare function useUploadboxConfig(): UploadboxContextValue;
14
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAElE,MAAM,WAAW,qBAAqB;IACpC,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAID,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,GAAG,MAAM,EACV,EAAE,qBAAqB,GAAG;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CAWvD;AAED,wBAAgB,kBAAkB,IAAI,qBAAqB,CAE1D"}
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext, useMemo } from "react";
4
+ const UploadboxContext = createContext({});
5
+ export function UploadboxProvider({ children, ...config }) {
6
+ const value = useMemo(() => ({ apiUrl: config.apiUrl, apiKey: config.apiKey, headers: config.headers }), [config.apiUrl, config.apiKey, config.headers]);
7
+ return (_jsx(UploadboxContext.Provider, { value: value, children: children }));
8
+ }
9
+ export function useUploadboxConfig() {
10
+ return useContext(UploadboxContext);
11
+ }
12
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAc,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAWlE,MAAM,gBAAgB,GAAG,aAAa,CAAwB,EAAE,CAAC,CAAC;AAElE,MAAM,UAAU,iBAAiB,CAAC,EAChC,QAAQ,EACR,GAAG,MAAM,EAC6C;IACtD,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,EACjF,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAC/C,CAAC;IAEF,OAAO,CACL,KAAC,gBAAgB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACpC,QAAQ,GACiB,CAC7B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,UAAU,CAAC,gBAAgB,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { RetryConfig } from "./types.js";
2
+ export declare const DEFAULT_RETRY_CONFIG: RetryConfig;
3
+ export declare function isRetryableError(status: number): boolean;
4
+ export declare function withRetry<T>(fn: (attempt: number) => Promise<T>, config: RetryConfig, onRetry?: (attempt: number, error: Error) => void, signal?: AbortSignal): Promise<T>;
5
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,eAAO,MAAM,oBAAoB,EAAE,WAKlC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EACnC,MAAM,EAAE,WAAW,EACnB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,EACjD,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,CAAC,CAAC,CA0CZ"}
package/dist/retry.js ADDED
@@ -0,0 +1,47 @@
1
+ export const DEFAULT_RETRY_CONFIG = {
2
+ maxRetries: 3,
3
+ initialDelayMs: 1000,
4
+ backoffMultiplier: 2,
5
+ maxDelayMs: 30000,
6
+ };
7
+ export function isRetryableError(status) {
8
+ if (status === 0 || status === 408 || status === 429)
9
+ return true;
10
+ return status >= 500 && status < 600;
11
+ }
12
+ export async function withRetry(fn, config, onRetry, signal) {
13
+ let lastError;
14
+ for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
15
+ if (signal?.aborted) {
16
+ throw new Error("Upload aborted");
17
+ }
18
+ try {
19
+ return await fn(attempt);
20
+ }
21
+ catch (err) {
22
+ lastError = err instanceof Error ? err : new Error(String(err));
23
+ if (attempt >= config.maxRetries)
24
+ break;
25
+ // Check if the error contains a retryable status
26
+ const statusMatch = lastError.message.match(/status (\d+)/);
27
+ if (statusMatch) {
28
+ const status = parseInt(statusMatch[1], 10);
29
+ if (!isRetryableError(status))
30
+ break;
31
+ }
32
+ const delay = Math.min(config.initialDelayMs * Math.pow(config.backoffMultiplier, attempt), config.maxDelayMs);
33
+ // Add jitter: 0.5x to 1.5x of delay
34
+ const jitteredDelay = delay * (0.5 + Math.random());
35
+ onRetry?.(attempt + 1, lastError);
36
+ await new Promise((resolve, reject) => {
37
+ const timeout = setTimeout(resolve, jitteredDelay);
38
+ signal?.addEventListener("abort", () => {
39
+ clearTimeout(timeout);
40
+ reject(new Error("Upload aborted"));
41
+ }, { once: true });
42
+ });
43
+ }
44
+ }
45
+ throw lastError ?? new Error("Retry failed");
46
+ }
47
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,oBAAoB,GAAgB;IAC/C,UAAU,EAAE,CAAC;IACb,cAAc,EAAE,IAAI;IACpB,iBAAiB,EAAE,CAAC;IACpB,UAAU,EAAE,KAAK;CAClB,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,IAAI,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAClE,OAAO,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAAmC,EACnC,MAAmB,EACnB,OAAiD,EACjD,MAAoB;IAEpB,IAAI,SAA4B,CAAC;IAEjC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QAC9D,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAEhE,IAAI,OAAO,IAAI,MAAM,CAAC,UAAU;gBAAE,MAAM;YAExC,iDAAiD;YACjD,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAC5D,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC;gBAC7C,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;oBAAE,MAAM;YACvC,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE,OAAO,CAAC,EACnE,MAAM,CAAC,UAAU,CAClB,CAAC;YACF,oCAAoC;YACpC,MAAM,aAAa,GAAG,KAAK,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAEpD,OAAO,EAAE,CAAC,OAAO,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;YAElC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;gBACnD,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;oBACrC,YAAY,CAAC,OAAO,CAAC,CAAC;oBACtB,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBACtC,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACrB,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,86 @@
1
+ import type { FileRouter, RouterConfig } from "@uploadbox/core";
2
+ export type EndpointHelper<TRouter extends FileRouter> = keyof TRouter & string;
3
+ export interface UploadProgressEvent {
4
+ loaded: number;
5
+ total: number;
6
+ percent: number;
7
+ }
8
+ export interface UploadedFile {
9
+ key: string;
10
+ name: string;
11
+ size: number;
12
+ type: string;
13
+ url: string;
14
+ customMetadata?: Record<string, string>;
15
+ }
16
+ export type FileUploadStatus = "pending" | "uploading" | "retrying" | "complete" | "error";
17
+ export interface FileProgress {
18
+ fileId: string;
19
+ name: string;
20
+ size: number;
21
+ type: string;
22
+ status: FileUploadStatus;
23
+ loaded: number;
24
+ percent: number;
25
+ speed: number;
26
+ eta: number;
27
+ error?: string;
28
+ retryCount: number;
29
+ key?: string;
30
+ }
31
+ export interface EnhancedUploadProgressEvent extends UploadProgressEvent {
32
+ fileProgress: FileProgress[];
33
+ }
34
+ export interface RetryConfig {
35
+ maxRetries: number;
36
+ initialDelayMs: number;
37
+ backoffMultiplier: number;
38
+ maxDelayMs: number;
39
+ }
40
+ export interface UseUploadboxOpts<TRouter extends FileRouter, TEndpoint extends keyof TRouter & string> {
41
+ endpoint: TEndpoint;
42
+ onClientUploadComplete?: (files: UploadedFile[]) => void;
43
+ onUploadError?: (error: Error) => void;
44
+ onUploadProgress?: (progress: EnhancedUploadProgressEvent) => void;
45
+ onBeforeUploadBegin?: (files: File[]) => File[];
46
+ headers?: Record<string, string>;
47
+ getFileMetadata?: (file: File) => Record<string, string>;
48
+ ttlSeconds?: number;
49
+ retry?: RetryConfig | false;
50
+ }
51
+ export interface UseUploadboxReturn {
52
+ startUpload: (files: File[]) => Promise<UploadedFile[] | undefined>;
53
+ isUploading: boolean;
54
+ progress: number;
55
+ routeConfig: RouterConfig[string] | undefined;
56
+ fileProgress: FileProgress[];
57
+ abort: () => void;
58
+ }
59
+ export interface UploadButtonProps<TRouter extends FileRouter, TEndpoint extends keyof TRouter & string> {
60
+ endpoint: TEndpoint;
61
+ onClientUploadComplete?: (files: UploadedFile[]) => void;
62
+ onUploadError?: (error: Error) => void;
63
+ onUploadProgress?: (progress: UploadProgressEvent) => void;
64
+ onBeforeUploadBegin?: (files: File[]) => File[];
65
+ className?: string;
66
+ disabled?: boolean;
67
+ content?: {
68
+ button?: string;
69
+ allowedContent?: string;
70
+ };
71
+ }
72
+ export interface UploadDropzoneProps<TRouter extends FileRouter, TEndpoint extends keyof TRouter & string> {
73
+ endpoint: TEndpoint;
74
+ onClientUploadComplete?: (files: UploadedFile[]) => void;
75
+ onUploadError?: (error: Error) => void;
76
+ onUploadProgress?: (progress: UploadProgressEvent) => void;
77
+ onBeforeUploadBegin?: (files: File[]) => File[];
78
+ className?: string;
79
+ disabled?: boolean;
80
+ content?: {
81
+ label?: string;
82
+ allowedContent?: string;
83
+ button?: string;
84
+ };
85
+ }
86
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { FileRouter } from "@uploadbox/core";
2
+ import type { UploadButtonProps } from "./types.js";
3
+ export declare function UploadButton<TRouter extends FileRouter, TEndpoint extends keyof TRouter & string>(props: UploadButtonProps<TRouter, TEndpoint>): import("react/jsx-runtime").JSX.Element;
4
+ //# sourceMappingURL=upload-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-button.d.ts","sourceRoot":"","sources":["../src/upload-button.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGpD,wBAAgB,YAAY,CAC1B,OAAO,SAAS,UAAU,EAC1B,SAAS,SAAS,MAAM,OAAO,GAAG,MAAM,EACxC,KAAK,EAAE,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,2CAiE7C"}
@@ -0,0 +1,25 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useRef, useCallback } from "react";
4
+ import { useUploadbox } from "./use-uploadbox.js";
5
+ export function UploadButton(props) {
6
+ const { endpoint, onClientUploadComplete, onUploadError, onUploadProgress, onBeforeUploadBegin, className, disabled, content, } = props;
7
+ const inputRef = useRef(null);
8
+ const { startUpload, isUploading, progress } = useUploadbox(endpoint, { onClientUploadComplete, onUploadError, onUploadProgress, onBeforeUploadBegin });
9
+ const handleClick = useCallback(() => {
10
+ inputRef.current?.click();
11
+ }, []);
12
+ const handleChange = useCallback(async (e) => {
13
+ const files = Array.from(e.target.files ?? []);
14
+ if (files.length > 0) {
15
+ await startUpload(files);
16
+ }
17
+ // Reset input so the same file can be selected again
18
+ if (inputRef.current)
19
+ inputRef.current.value = "";
20
+ }, [startUpload]);
21
+ return (_jsxs("div", { className: `uploadbox-button-wrapper ${className ?? ""}`, children: [_jsx("input", { ref: inputRef, type: "file", multiple: true, onChange: handleChange, style: { display: "none" }, disabled: disabled || isUploading }), _jsx("button", { type: "button", className: "uploadbox-button", onClick: handleClick, disabled: disabled || isUploading, children: isUploading
22
+ ? `Uploading... ${progress}%`
23
+ : content?.button ?? "Upload Files" }), isUploading && (_jsx("div", { className: "uploadbox-progress-bar", children: _jsx("div", { className: "uploadbox-progress-bar-fill", style: { width: `${progress}%` } }) }))] }));
24
+ }
25
+ //# sourceMappingURL=upload-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-button.js","sourceRoot":"","sources":["../src/upload-button.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAGnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,UAAU,YAAY,CAG1B,KAA4C;IAC5C,MAAM,EACJ,QAAQ,EACR,sBAAsB,EACtB,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,QAAQ,EACR,OAAO,GACR,GAAG,KAAK,CAAC;IAEV,MAAM,QAAQ,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAEhD,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,YAAY,CACzD,QAAQ,EACR,EAAE,sBAAsB,EAAE,aAAa,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,CACjF,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,YAAY,GAAG,WAAW,CAC9B,KAAK,EAAE,CAAsC,EAAE,EAAE;QAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC/C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QACD,qDAAqD;QACrD,IAAI,QAAQ,CAAC,OAAO;YAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,GAAG,EAAE,CAAC;IACpD,CAAC,EACD,CAAC,WAAW,CAAC,CACd,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAE,4BAA4B,SAAS,IAAI,EAAE,EAAE,aAC3D,gBACE,GAAG,EAAE,QAAQ,EACb,IAAI,EAAC,MAAM,EACX,QAAQ,QACR,QAAQ,EAAE,YAAY,EACtB,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAC1B,QAAQ,EAAE,QAAQ,IAAI,WAAW,GACjC,EACF,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,kBAAkB,EAC5B,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,QAAQ,IAAI,WAAW,YAEhC,WAAW;oBACV,CAAC,CAAC,gBAAgB,QAAQ,GAAG;oBAC7B,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,cAAc,GAC9B,EACR,WAAW,IAAI,CACd,cAAK,SAAS,EAAC,wBAAwB,YACrC,cACE,SAAS,EAAC,6BAA6B,EACvC,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,QAAQ,GAAG,EAAE,GAChC,GACE,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { FileRouter } from "@uploadbox/core";
2
+ import type { UploadDropzoneProps } from "./types.js";
3
+ export declare function UploadDropzone<TRouter extends FileRouter, TEndpoint extends keyof TRouter & string>(props: UploadDropzoneProps<TRouter, TEndpoint>): import("react/jsx-runtime").JSX.Element;
4
+ //# sourceMappingURL=upload-dropzone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-dropzone.d.ts","sourceRoot":"","sources":["../src/upload-dropzone.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAKtD,wBAAgB,cAAc,CAC5B,OAAO,SAAS,UAAU,EAC1B,SAAS,SAAS,MAAM,OAAO,GAAG,MAAM,EACxC,KAAK,EAAE,mBAAmB,CAAC,OAAO,EAAE,SAAS,CAAC,2CA4H/C"}