@signskart/uploader 1.0.1 → 1.0.4
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.mts +0 -12
- package/dist/index.d.ts +0 -12
- package/dist/index.js +18 -54
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +18 -54
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -3
package/dist/index.d.mts
CHANGED
|
@@ -39,21 +39,9 @@ declare class UploadTask {
|
|
|
39
39
|
private abortController;
|
|
40
40
|
private retries;
|
|
41
41
|
constructor(uploader: BaseUploader, options: UploadOptions, maxRetries?: number, retryDelay?: number);
|
|
42
|
-
/**
|
|
43
|
-
* Starts the upload process
|
|
44
|
-
*/
|
|
45
42
|
start(): Promise<void>;
|
|
46
|
-
/**
|
|
47
|
-
* Cancels the upload
|
|
48
|
-
*/
|
|
49
43
|
cancel(): void;
|
|
50
|
-
/**
|
|
51
|
-
* Internal state updater
|
|
52
|
-
*/
|
|
53
44
|
private update;
|
|
54
|
-
/**
|
|
55
|
-
* Utility sleep helper
|
|
56
|
-
*/
|
|
57
45
|
private sleep;
|
|
58
46
|
}
|
|
59
47
|
|
package/dist/index.d.ts
CHANGED
|
@@ -39,21 +39,9 @@ declare class UploadTask {
|
|
|
39
39
|
private abortController;
|
|
40
40
|
private retries;
|
|
41
41
|
constructor(uploader: BaseUploader, options: UploadOptions, maxRetries?: number, retryDelay?: number);
|
|
42
|
-
/**
|
|
43
|
-
* Starts the upload process
|
|
44
|
-
*/
|
|
45
42
|
start(): Promise<void>;
|
|
46
|
-
/**
|
|
47
|
-
* Cancels the upload
|
|
48
|
-
*/
|
|
49
43
|
cancel(): void;
|
|
50
|
-
/**
|
|
51
|
-
* Internal state updater
|
|
52
|
-
*/
|
|
53
44
|
private update;
|
|
54
|
-
/**
|
|
55
|
-
* Utility sleep helper
|
|
56
|
-
*/
|
|
57
45
|
private sleep;
|
|
58
46
|
}
|
|
59
47
|
|
package/dist/index.js
CHANGED
|
@@ -59,25 +59,16 @@ var UploadTask = class {
|
|
|
59
59
|
status: "queued"
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Starts the upload process
|
|
64
|
-
*/
|
|
65
62
|
async start() {
|
|
66
63
|
this.update({ status: "uploading" });
|
|
67
64
|
while (this.retries <= this.maxRetries) {
|
|
68
65
|
try {
|
|
69
66
|
const response = await this.uploader.upload(
|
|
70
67
|
this.options,
|
|
71
|
-
(progress) => {
|
|
72
|
-
this.update({ progress });
|
|
73
|
-
},
|
|
68
|
+
(progress) => this.update({ progress }),
|
|
74
69
|
this.abortController.signal
|
|
75
70
|
);
|
|
76
|
-
this.update({
|
|
77
|
-
status: "success",
|
|
78
|
-
progress: 100,
|
|
79
|
-
response
|
|
80
|
-
});
|
|
71
|
+
this.update({ status: "success", progress: 100, response });
|
|
81
72
|
return;
|
|
82
73
|
} catch (error) {
|
|
83
74
|
if (this.abortController.signal.aborted) {
|
|
@@ -86,35 +77,22 @@ var UploadTask = class {
|
|
|
86
77
|
}
|
|
87
78
|
const message = error instanceof Error ? error.message : "Unknown upload error";
|
|
88
79
|
if (this.retries >= this.maxRetries) {
|
|
89
|
-
this.update({
|
|
90
|
-
status: "error",
|
|
91
|
-
error: message
|
|
92
|
-
});
|
|
80
|
+
this.update({ status: "error", error: message });
|
|
93
81
|
return;
|
|
94
82
|
}
|
|
95
83
|
this.retries++;
|
|
96
|
-
|
|
97
|
-
await this.sleep(delay);
|
|
84
|
+
await this.sleep(this.retryDelay * Math.pow(2, this.retries - 1));
|
|
98
85
|
}
|
|
99
86
|
}
|
|
100
87
|
}
|
|
101
|
-
/**
|
|
102
|
-
* Cancels the upload
|
|
103
|
-
*/
|
|
104
88
|
cancel() {
|
|
105
89
|
this.abortController.abort();
|
|
106
90
|
this.update({ status: "cancelled" });
|
|
107
91
|
}
|
|
108
|
-
/**
|
|
109
|
-
* Internal state updater
|
|
110
|
-
*/
|
|
111
92
|
update(update) {
|
|
112
93
|
this.state = { ...this.state, ...update };
|
|
113
94
|
this.events.emit(this.state);
|
|
114
95
|
}
|
|
115
|
-
/**
|
|
116
|
-
* Utility sleep helper
|
|
117
|
-
*/
|
|
118
96
|
sleep(ms) {
|
|
119
97
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
120
98
|
}
|
|
@@ -156,33 +134,26 @@ var S3Uploader = class extends BaseUploader {
|
|
|
156
134
|
this.config = config;
|
|
157
135
|
}
|
|
158
136
|
async upload(options, onProgress, signal) {
|
|
159
|
-
const presignRes = await fetch(
|
|
160
|
-
|
|
161
|
-
{
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
})
|
|
169
|
-
}
|
|
170
|
-
);
|
|
137
|
+
const presignRes = await fetch(`${this.config.apiBaseUrl}/s3/presign-upload`, {
|
|
138
|
+
method: "POST",
|
|
139
|
+
headers: { "Content-Type": "application/json" },
|
|
140
|
+
body: JSON.stringify({
|
|
141
|
+
fileName: options.fileName || options.file.name,
|
|
142
|
+
folder: options.folder,
|
|
143
|
+
contentType: options.file.type
|
|
144
|
+
})
|
|
145
|
+
});
|
|
171
146
|
const { uploadUrl, key } = await presignRes.json();
|
|
172
147
|
return new Promise((resolve, reject) => {
|
|
173
148
|
const xhr = new XMLHttpRequest();
|
|
174
149
|
xhr.upload.onprogress = (event) => {
|
|
175
150
|
if (event.lengthComputable) {
|
|
176
|
-
|
|
177
|
-
onProgress(Math.round(percent));
|
|
151
|
+
onProgress(Math.round(event.loaded / event.total * 100));
|
|
178
152
|
}
|
|
179
153
|
};
|
|
180
154
|
xhr.onload = () => {
|
|
181
155
|
if (xhr.status === 200) {
|
|
182
|
-
resolve({
|
|
183
|
-
url: `${this.config.publicUrl}/${key}`,
|
|
184
|
-
provider: "s3"
|
|
185
|
-
});
|
|
156
|
+
resolve({ url: `${this.config.publicUrl}/${key}`, provider: "s3" });
|
|
186
157
|
} else {
|
|
187
158
|
reject(new Error("S3 upload failed"));
|
|
188
159
|
}
|
|
@@ -214,26 +185,19 @@ var CloudinaryUploader = class extends BaseUploader {
|
|
|
214
185
|
const xhr = new XMLHttpRequest();
|
|
215
186
|
xhr.upload.onprogress = (event) => {
|
|
216
187
|
if (event.lengthComputable) {
|
|
217
|
-
|
|
218
|
-
onProgress(Math.round(percent));
|
|
188
|
+
onProgress(Math.round(event.loaded / event.total * 100));
|
|
219
189
|
}
|
|
220
190
|
};
|
|
221
191
|
xhr.onload = () => {
|
|
222
192
|
const data = JSON.parse(xhr.responseText);
|
|
223
193
|
if (xhr.status === 200 && data.secure_url) {
|
|
224
|
-
resolve({
|
|
225
|
-
url: data.secure_url,
|
|
226
|
-
provider: "cloudinary"
|
|
227
|
-
});
|
|
194
|
+
resolve({ url: data.secure_url, provider: "cloudinary" });
|
|
228
195
|
} else {
|
|
229
196
|
reject(new Error("Cloudinary upload failed"));
|
|
230
197
|
}
|
|
231
198
|
};
|
|
232
199
|
xhr.onerror = () => reject(new Error("Cloudinary upload failed"));
|
|
233
|
-
xhr.open(
|
|
234
|
-
"POST",
|
|
235
|
-
`https://api.cloudinary.com/v1_1/${this.config.cloudName}/upload`
|
|
236
|
-
);
|
|
200
|
+
xhr.open("POST", `https://api.cloudinary.com/v1_1/${this.config.cloudName}/upload`);
|
|
237
201
|
xhr.send(formData);
|
|
238
202
|
});
|
|
239
203
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/core/EventEmitter.ts","../src/core/UploadTask.ts","../src/core/UploadManager.ts","../src/core/BaseUploader.ts","../src/providers/S3Uploader.ts","../src/providers/CloudinaryUploader.ts"],"sourcesContent":["export * from './core/types';\nexport * from './core/UploadManager';\nexport * from './core/UploadTask';\nexport * from './providers/S3Uploader';\nexport * from './providers/CloudinaryUploader';","type Listener<T> = (payload: T) => void;\n\nexport class EventEmitter<T> {\n private listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>) {\n this.listeners.push(listener);\n return () => {\n this.listeners = this.listeners.filter(l => l !== listener);\n };\n }\n\n emit(payload: T) {\n this.listeners.forEach(listener => listener(payload));\n }\n}","import { BaseUploader } from './BaseUploader';\nimport { UploadOptions, UploadTaskState } from './types';\nimport { EventEmitter } from './EventEmitter';\n\nexport class UploadTask {\n public state: UploadTaskState;\n public events = new EventEmitter<UploadTaskState>();\n\n private abortController = new AbortController();\n private retries = 0;\n\n constructor(\n private uploader: BaseUploader,\n private options: UploadOptions,\n private maxRetries = 2,\n private retryDelay = 500 // base delay in ms\n ) {\n this.state = {\n id: crypto.randomUUID(),\n progress: 0,\n status: 'queued',\n };\n }\n\n /**\n * Starts the upload process\n */\n async start(): Promise<void> {\n this.update({ status: 'uploading' });\n\n while (this.retries <= this.maxRetries) {\n try {\n const response = await this.uploader.upload(\n this.options,\n (progress: number) => {\n this.update({ progress });\n },\n this.abortController.signal\n );\n\n this.update({\n status: 'success',\n progress: 100,\n response,\n });\n\n return;\n } catch (error: unknown) {\n if (this.abortController.signal.aborted) {\n this.update({ status: 'cancelled' });\n return;\n }\n\n const message =\n error instanceof Error\n ? error.message\n : 'Unknown upload error';\n\n if (this.retries >= this.maxRetries) {\n this.update({\n status: 'error',\n error: message,\n });\n return;\n }\n\n this.retries++;\n\n // Exponential backoff delay\n const delay = this.retryDelay * Math.pow(2, this.retries - 1);\n await this.sleep(delay);\n }\n }\n }\n\n /**\n * Cancels the upload\n */\n cancel(): void {\n this.abortController.abort();\n this.update({ status: 'cancelled' });\n }\n\n /**\n * Internal state updater\n */\n private update(update: Partial<UploadTaskState>): void {\n this.state = { ...this.state, ...update };\n this.events.emit(this.state);\n }\n\n /**\n * Utility sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}","import { BaseUploader } from './BaseUploader';\nimport { UploadOptions } from './types';\nimport { UploadTask } from './UploadTask';\n\nexport class UploadManager {\n private queue: UploadTask[] = [];\n private active = 0;\n\n constructor(\n private uploader: BaseUploader,\n private concurrency = 3\n ) { }\n\n add(options: UploadOptions) {\n const task = new UploadTask(this.uploader, options);\n this.queue.push(task);\n this.process();\n return task;\n }\n\n private async process() {\n if (this.active >= this.concurrency) return;\n\n const next = this.queue.find(t => t.state.status === 'queued');\n if (!next) return;\n\n this.active++;\n await next.start();\n this.active--;\n\n this.process();\n }\n}","import { UploadOptions, UploadResponse } from './types';\n\nexport abstract class BaseUploader {\n abstract upload(options: UploadOptions, onProgress: (percent: number) => void, signal?: AbortSignal): Promise<UploadResponse>;\n}","import { BaseUploader } from '../core/BaseUploader';\nimport { UploadOptions, UploadResponse } from '../core/types';\n\ninterface S3Config {\n apiBaseUrl: string;\n publicUrl: string;\n}\n\nexport class S3Uploader extends BaseUploader {\n constructor(private config: S3Config) {\n super();\n }\n\n async upload(\n options: UploadOptions,\n onProgress: (percent: number) => void,\n signal?: AbortSignal\n ): Promise<UploadResponse> {\n const presignRes = await fetch(\n `${this.config.apiBaseUrl}/s3/presign-upload`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n fileName: options.fileName || options.file.name,\n folder: options.folder,\n contentType: options.file.type,\n }),\n }\n );\n\n const { uploadUrl, key } = await presignRes.json();\n\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n xhr.upload.onprogress = (event) => {\n if (event.lengthComputable) {\n const percent = (event.loaded / event.total) * 100;\n onProgress(Math.round(percent));\n }\n };\n\n xhr.onload = () => {\n if (xhr.status === 200) {\n resolve({\n url: `${this.config.publicUrl}/${key}`,\n provider: 's3',\n });\n } else {\n reject(new Error('S3 upload failed'));\n }\n };\n\n xhr.onerror = () => reject(new Error('S3 upload failed'));\n\n signal?.addEventListener('abort', () => {\n xhr.abort();\n reject(new Error('Upload cancelled'));\n });\n\n xhr.open('PUT', uploadUrl);\n xhr.setRequestHeader('Content-Type', options.file.type);\n xhr.send(options.file);\n });\n }\n}","import { BaseUploader } from '../core/BaseUploader';\nimport { UploadOptions, UploadResponse } from '../core/types';\n\ninterface CloudinaryConfig {\n cloudName: string;\n uploadPreset: string;\n}\n\nexport class CloudinaryUploader extends BaseUploader {\n constructor(private config: CloudinaryConfig) {\n super();\n }\n\n async upload(\n options: UploadOptions,\n onProgress: (percent: number) => void\n ): Promise<UploadResponse> {\n const formData = new FormData();\n formData.append('file', options.file);\n formData.append('upload_preset', this.config.uploadPreset);\n formData.append('folder', options.folder);\n\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n xhr.upload.onprogress = (event) => {\n if (event.lengthComputable) {\n const percent = (event.loaded / event.total) * 100;\n onProgress(Math.round(percent));\n }\n };\n\n xhr.onload = () => {\n const data = JSON.parse(xhr.responseText);\n if (xhr.status === 200 && data.secure_url) {\n resolve({\n url: data.secure_url,\n provider: 'cloudinary',\n });\n } else {\n reject(new Error('Cloudinary upload failed'));\n }\n };\n\n xhr.onerror = () => reject(new Error('Cloudinary upload failed'));\n\n xhr.open(\n 'POST',\n `https://api.cloudinary.com/v1_1/${this.config.cloudName}/upload`\n );\n\n xhr.send(formData);\n });\n }\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/core/EventEmitter.ts","../src/core/UploadTask.ts","../src/core/UploadManager.ts","../src/core/BaseUploader.ts","../src/providers/S3Uploader.ts","../src/providers/CloudinaryUploader.ts"],"sourcesContent":["export * from './core/types';\nexport * from './core/UploadManager';\nexport * from './core/UploadTask';\nexport * from './providers/S3Uploader';\nexport * from './providers/CloudinaryUploader';","type Listener<T> = (payload: T) => void;\n\nexport class EventEmitter<T> {\n private listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>) {\n this.listeners.push(listener);\n return () => {\n this.listeners = this.listeners.filter(l => l !== listener);\n };\n }\n\n emit(payload: T) {\n this.listeners.forEach(listener => listener(payload));\n }\n}","import { BaseUploader } from './BaseUploader';\nimport { UploadOptions, UploadTaskState } from './types';\nimport { EventEmitter } from './EventEmitter';\n\nexport class UploadTask {\n public state: UploadTaskState;\n public events = new EventEmitter<UploadTaskState>();\n private abortController = new AbortController();\n private retries = 0;\n\n constructor(\n private uploader: BaseUploader,\n private options: UploadOptions,\n private maxRetries = 2,\n private retryDelay = 500\n ) {\n this.state = {\n id: crypto.randomUUID(),\n progress: 0,\n status: 'queued'\n };\n }\n\n async start(): Promise<void> {\n this.update({ status: 'uploading' });\n\n while (this.retries <= this.maxRetries) {\n try {\n const response = await this.uploader.upload(\n this.options,\n progress => this.update({ progress }),\n this.abortController.signal\n );\n\n this.update({ status: 'success', progress: 100, response });\n return;\n } catch (error: unknown) {\n if (this.abortController.signal.aborted) {\n this.update({ status: 'cancelled' });\n return;\n }\n\n const message = error instanceof Error ? error.message : 'Unknown upload error';\n\n if (this.retries >= this.maxRetries) {\n this.update({ status: 'error', error: message });\n return;\n }\n\n this.retries++;\n await this.sleep(this.retryDelay * Math.pow(2, this.retries - 1));\n }\n }\n }\n\n cancel() {\n this.abortController.abort();\n this.update({ status: 'cancelled' });\n }\n\n private update(update: Partial<UploadTaskState>) {\n this.state = { ...this.state, ...update };\n this.events.emit(this.state);\n }\n\n private sleep(ms: number) {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}","import { BaseUploader } from './BaseUploader';\nimport { UploadOptions } from './types';\nimport { UploadTask } from './UploadTask';\n\nexport class UploadManager {\n private queue: UploadTask[] = [];\n private active = 0;\n\n constructor(private uploader: BaseUploader, private concurrency = 3) { }\n\n add(options: UploadOptions) {\n const task = new UploadTask(this.uploader, options);\n this.queue.push(task);\n this.process();\n return task;\n }\n\n private async process() {\n if (this.active >= this.concurrency) return;\n\n const next = this.queue.find(t => t.state.status === 'queued');\n if (!next) return;\n\n this.active++;\n await next.start();\n this.active--;\n this.process();\n }\n}","import { UploadOptions, UploadResponse } from './types';\n\nexport abstract class BaseUploader {\n abstract upload(options: UploadOptions, onProgress: (percent: number) => void, signal?: AbortSignal): Promise<UploadResponse>;\n}","import { BaseUploader } from '../core/BaseUploader';\nimport { UploadOptions, UploadResponse } from '../core/types';\n\ninterface S3Config {\n apiBaseUrl: string;\n publicUrl: string;\n}\n\nexport class S3Uploader extends BaseUploader {\n constructor(private config: S3Config) {\n super();\n }\n\n async upload(\n options: UploadOptions,\n onProgress: (percent: number) => void,\n signal?: AbortSignal\n ): Promise<UploadResponse> {\n const presignRes = await fetch(`${this.config.apiBaseUrl}/s3/presign-upload`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n fileName: options.fileName || options.file.name,\n folder: options.folder,\n contentType: options.file.type\n })\n });\n\n const { uploadUrl, key } = await presignRes.json();\n\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n xhr.upload.onprogress = event => {\n if (event.lengthComputable) {\n onProgress(Math.round((event.loaded / event.total) * 100));\n }\n };\n\n xhr.onload = () => {\n if (xhr.status === 200) {\n resolve({ url: `${this.config.publicUrl}/${key}`, provider: 's3' });\n } else {\n reject(new Error('S3 upload failed'));\n }\n };\n\n xhr.onerror = () => reject(new Error('S3 upload failed'));\n\n signal?.addEventListener('abort', () => {\n xhr.abort();\n reject(new Error('Upload cancelled'));\n });\n\n xhr.open('PUT', uploadUrl);\n xhr.setRequestHeader('Content-Type', options.file.type);\n xhr.send(options.file);\n });\n }\n}","import { BaseUploader } from '../core/BaseUploader';\nimport { UploadOptions, UploadResponse } from '../core/types';\n\ninterface CloudinaryConfig {\n cloudName: string;\n uploadPreset: string;\n}\n\nexport class CloudinaryUploader extends BaseUploader {\n constructor(private config: CloudinaryConfig) {\n super();\n }\n\n async upload(\n options: UploadOptions,\n onProgress: (percent: number) => void\n ): Promise<UploadResponse> {\n const formData = new FormData();\n formData.append('file', options.file);\n formData.append('upload_preset', this.config.uploadPreset);\n formData.append('folder', options.folder);\n\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n xhr.upload.onprogress = event => {\n if (event.lengthComputable) {\n onProgress(Math.round((event.loaded / event.total) * 100));\n }\n };\n\n xhr.onload = () => {\n const data = JSON.parse(xhr.responseText);\n if (xhr.status === 200 && data.secure_url) {\n resolve({ url: data.secure_url, provider: 'cloudinary' });\n } else {\n reject(new Error('Cloudinary upload failed'));\n }\n };\n\n xhr.onerror = () => reject(new Error('Cloudinary upload failed'));\n\n xhr.open('POST', `https://api.cloudinary.com/v1_1/${this.config.cloudName}/upload`);\n xhr.send(formData);\n });\n }\n}"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -30,25 +30,16 @@ var UploadTask = class {
|
|
|
30
30
|
status: "queued"
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Starts the upload process
|
|
35
|
-
*/
|
|
36
33
|
async start() {
|
|
37
34
|
this.update({ status: "uploading" });
|
|
38
35
|
while (this.retries <= this.maxRetries) {
|
|
39
36
|
try {
|
|
40
37
|
const response = await this.uploader.upload(
|
|
41
38
|
this.options,
|
|
42
|
-
(progress) => {
|
|
43
|
-
this.update({ progress });
|
|
44
|
-
},
|
|
39
|
+
(progress) => this.update({ progress }),
|
|
45
40
|
this.abortController.signal
|
|
46
41
|
);
|
|
47
|
-
this.update({
|
|
48
|
-
status: "success",
|
|
49
|
-
progress: 100,
|
|
50
|
-
response
|
|
51
|
-
});
|
|
42
|
+
this.update({ status: "success", progress: 100, response });
|
|
52
43
|
return;
|
|
53
44
|
} catch (error) {
|
|
54
45
|
if (this.abortController.signal.aborted) {
|
|
@@ -57,35 +48,22 @@ var UploadTask = class {
|
|
|
57
48
|
}
|
|
58
49
|
const message = error instanceof Error ? error.message : "Unknown upload error";
|
|
59
50
|
if (this.retries >= this.maxRetries) {
|
|
60
|
-
this.update({
|
|
61
|
-
status: "error",
|
|
62
|
-
error: message
|
|
63
|
-
});
|
|
51
|
+
this.update({ status: "error", error: message });
|
|
64
52
|
return;
|
|
65
53
|
}
|
|
66
54
|
this.retries++;
|
|
67
|
-
|
|
68
|
-
await this.sleep(delay);
|
|
55
|
+
await this.sleep(this.retryDelay * Math.pow(2, this.retries - 1));
|
|
69
56
|
}
|
|
70
57
|
}
|
|
71
58
|
}
|
|
72
|
-
/**
|
|
73
|
-
* Cancels the upload
|
|
74
|
-
*/
|
|
75
59
|
cancel() {
|
|
76
60
|
this.abortController.abort();
|
|
77
61
|
this.update({ status: "cancelled" });
|
|
78
62
|
}
|
|
79
|
-
/**
|
|
80
|
-
* Internal state updater
|
|
81
|
-
*/
|
|
82
63
|
update(update) {
|
|
83
64
|
this.state = { ...this.state, ...update };
|
|
84
65
|
this.events.emit(this.state);
|
|
85
66
|
}
|
|
86
|
-
/**
|
|
87
|
-
* Utility sleep helper
|
|
88
|
-
*/
|
|
89
67
|
sleep(ms) {
|
|
90
68
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
91
69
|
}
|
|
@@ -127,33 +105,26 @@ var S3Uploader = class extends BaseUploader {
|
|
|
127
105
|
this.config = config;
|
|
128
106
|
}
|
|
129
107
|
async upload(options, onProgress, signal) {
|
|
130
|
-
const presignRes = await fetch(
|
|
131
|
-
|
|
132
|
-
{
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
})
|
|
140
|
-
}
|
|
141
|
-
);
|
|
108
|
+
const presignRes = await fetch(`${this.config.apiBaseUrl}/s3/presign-upload`, {
|
|
109
|
+
method: "POST",
|
|
110
|
+
headers: { "Content-Type": "application/json" },
|
|
111
|
+
body: JSON.stringify({
|
|
112
|
+
fileName: options.fileName || options.file.name,
|
|
113
|
+
folder: options.folder,
|
|
114
|
+
contentType: options.file.type
|
|
115
|
+
})
|
|
116
|
+
});
|
|
142
117
|
const { uploadUrl, key } = await presignRes.json();
|
|
143
118
|
return new Promise((resolve, reject) => {
|
|
144
119
|
const xhr = new XMLHttpRequest();
|
|
145
120
|
xhr.upload.onprogress = (event) => {
|
|
146
121
|
if (event.lengthComputable) {
|
|
147
|
-
|
|
148
|
-
onProgress(Math.round(percent));
|
|
122
|
+
onProgress(Math.round(event.loaded / event.total * 100));
|
|
149
123
|
}
|
|
150
124
|
};
|
|
151
125
|
xhr.onload = () => {
|
|
152
126
|
if (xhr.status === 200) {
|
|
153
|
-
resolve({
|
|
154
|
-
url: `${this.config.publicUrl}/${key}`,
|
|
155
|
-
provider: "s3"
|
|
156
|
-
});
|
|
127
|
+
resolve({ url: `${this.config.publicUrl}/${key}`, provider: "s3" });
|
|
157
128
|
} else {
|
|
158
129
|
reject(new Error("S3 upload failed"));
|
|
159
130
|
}
|
|
@@ -185,26 +156,19 @@ var CloudinaryUploader = class extends BaseUploader {
|
|
|
185
156
|
const xhr = new XMLHttpRequest();
|
|
186
157
|
xhr.upload.onprogress = (event) => {
|
|
187
158
|
if (event.lengthComputable) {
|
|
188
|
-
|
|
189
|
-
onProgress(Math.round(percent));
|
|
159
|
+
onProgress(Math.round(event.loaded / event.total * 100));
|
|
190
160
|
}
|
|
191
161
|
};
|
|
192
162
|
xhr.onload = () => {
|
|
193
163
|
const data = JSON.parse(xhr.responseText);
|
|
194
164
|
if (xhr.status === 200 && data.secure_url) {
|
|
195
|
-
resolve({
|
|
196
|
-
url: data.secure_url,
|
|
197
|
-
provider: "cloudinary"
|
|
198
|
-
});
|
|
165
|
+
resolve({ url: data.secure_url, provider: "cloudinary" });
|
|
199
166
|
} else {
|
|
200
167
|
reject(new Error("Cloudinary upload failed"));
|
|
201
168
|
}
|
|
202
169
|
};
|
|
203
170
|
xhr.onerror = () => reject(new Error("Cloudinary upload failed"));
|
|
204
|
-
xhr.open(
|
|
205
|
-
"POST",
|
|
206
|
-
`https://api.cloudinary.com/v1_1/${this.config.cloudName}/upload`
|
|
207
|
-
);
|
|
171
|
+
xhr.open("POST", `https://api.cloudinary.com/v1_1/${this.config.cloudName}/upload`);
|
|
208
172
|
xhr.send(formData);
|
|
209
173
|
});
|
|
210
174
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/EventEmitter.ts","../src/core/UploadTask.ts","../src/core/UploadManager.ts","../src/core/BaseUploader.ts","../src/providers/S3Uploader.ts","../src/providers/CloudinaryUploader.ts"],"sourcesContent":["type Listener<T> = (payload: T) => void;\n\nexport class EventEmitter<T> {\n private listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>) {\n this.listeners.push(listener);\n return () => {\n this.listeners = this.listeners.filter(l => l !== listener);\n };\n }\n\n emit(payload: T) {\n this.listeners.forEach(listener => listener(payload));\n }\n}","import { BaseUploader } from './BaseUploader';\nimport { UploadOptions, UploadTaskState } from './types';\nimport { EventEmitter } from './EventEmitter';\n\nexport class UploadTask {\n public state: UploadTaskState;\n public events = new EventEmitter<UploadTaskState>();\n\n private abortController = new AbortController();\n private retries = 0;\n\n constructor(\n private uploader: BaseUploader,\n private options: UploadOptions,\n private maxRetries = 2,\n private retryDelay = 500 // base delay in ms\n ) {\n this.state = {\n id: crypto.randomUUID(),\n progress: 0,\n status: 'queued',\n };\n }\n\n /**\n * Starts the upload process\n */\n async start(): Promise<void> {\n this.update({ status: 'uploading' });\n\n while (this.retries <= this.maxRetries) {\n try {\n const response = await this.uploader.upload(\n this.options,\n (progress: number) => {\n this.update({ progress });\n },\n this.abortController.signal\n );\n\n this.update({\n status: 'success',\n progress: 100,\n response,\n });\n\n return;\n } catch (error: unknown) {\n if (this.abortController.signal.aborted) {\n this.update({ status: 'cancelled' });\n return;\n }\n\n const message =\n error instanceof Error\n ? error.message\n : 'Unknown upload error';\n\n if (this.retries >= this.maxRetries) {\n this.update({\n status: 'error',\n error: message,\n });\n return;\n }\n\n this.retries++;\n\n // Exponential backoff delay\n const delay = this.retryDelay * Math.pow(2, this.retries - 1);\n await this.sleep(delay);\n }\n }\n }\n\n /**\n * Cancels the upload\n */\n cancel(): void {\n this.abortController.abort();\n this.update({ status: 'cancelled' });\n }\n\n /**\n * Internal state updater\n */\n private update(update: Partial<UploadTaskState>): void {\n this.state = { ...this.state, ...update };\n this.events.emit(this.state);\n }\n\n /**\n * Utility sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}","import { BaseUploader } from './BaseUploader';\nimport { UploadOptions } from './types';\nimport { UploadTask } from './UploadTask';\n\nexport class UploadManager {\n private queue: UploadTask[] = [];\n private active = 0;\n\n constructor(\n private uploader: BaseUploader,\n private concurrency = 3\n ) { }\n\n add(options: UploadOptions) {\n const task = new UploadTask(this.uploader, options);\n this.queue.push(task);\n this.process();\n return task;\n }\n\n private async process() {\n if (this.active >= this.concurrency) return;\n\n const next = this.queue.find(t => t.state.status === 'queued');\n if (!next) return;\n\n this.active++;\n await next.start();\n this.active--;\n\n this.process();\n }\n}","import { UploadOptions, UploadResponse } from './types';\n\nexport abstract class BaseUploader {\n abstract upload(options: UploadOptions, onProgress: (percent: number) => void, signal?: AbortSignal): Promise<UploadResponse>;\n}","import { BaseUploader } from '../core/BaseUploader';\nimport { UploadOptions, UploadResponse } from '../core/types';\n\ninterface S3Config {\n apiBaseUrl: string;\n publicUrl: string;\n}\n\nexport class S3Uploader extends BaseUploader {\n constructor(private config: S3Config) {\n super();\n }\n\n async upload(\n options: UploadOptions,\n onProgress: (percent: number) => void,\n signal?: AbortSignal\n ): Promise<UploadResponse> {\n const presignRes = await fetch(\n `${this.config.apiBaseUrl}/s3/presign-upload`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n fileName: options.fileName || options.file.name,\n folder: options.folder,\n contentType: options.file.type,\n }),\n }\n );\n\n const { uploadUrl, key } = await presignRes.json();\n\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n xhr.upload.onprogress = (event) => {\n if (event.lengthComputable) {\n const percent = (event.loaded / event.total) * 100;\n onProgress(Math.round(percent));\n }\n };\n\n xhr.onload = () => {\n if (xhr.status === 200) {\n resolve({\n url: `${this.config.publicUrl}/${key}`,\n provider: 's3',\n });\n } else {\n reject(new Error('S3 upload failed'));\n }\n };\n\n xhr.onerror = () => reject(new Error('S3 upload failed'));\n\n signal?.addEventListener('abort', () => {\n xhr.abort();\n reject(new Error('Upload cancelled'));\n });\n\n xhr.open('PUT', uploadUrl);\n xhr.setRequestHeader('Content-Type', options.file.type);\n xhr.send(options.file);\n });\n }\n}","import { BaseUploader } from '../core/BaseUploader';\nimport { UploadOptions, UploadResponse } from '../core/types';\n\ninterface CloudinaryConfig {\n cloudName: string;\n uploadPreset: string;\n}\n\nexport class CloudinaryUploader extends BaseUploader {\n constructor(private config: CloudinaryConfig) {\n super();\n }\n\n async upload(\n options: UploadOptions,\n onProgress: (percent: number) => void\n ): Promise<UploadResponse> {\n const formData = new FormData();\n formData.append('file', options.file);\n formData.append('upload_preset', this.config.uploadPreset);\n formData.append('folder', options.folder);\n\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n xhr.upload.onprogress = (event) => {\n if (event.lengthComputable) {\n const percent = (event.loaded / event.total) * 100;\n onProgress(Math.round(percent));\n }\n };\n\n xhr.onload = () => {\n const data = JSON.parse(xhr.responseText);\n if (xhr.status === 200 && data.secure_url) {\n resolve({\n url: data.secure_url,\n provider: 'cloudinary',\n });\n } else {\n reject(new Error('Cloudinary upload failed'));\n }\n };\n\n xhr.onerror = () => reject(new Error('Cloudinary upload failed'));\n\n xhr.open(\n 'POST',\n `https://api.cloudinary.com/v1_1/${this.config.cloudName}/upload`\n );\n\n xhr.send(formData);\n });\n }\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/core/EventEmitter.ts","../src/core/UploadTask.ts","../src/core/UploadManager.ts","../src/core/BaseUploader.ts","../src/providers/S3Uploader.ts","../src/providers/CloudinaryUploader.ts"],"sourcesContent":["type Listener<T> = (payload: T) => void;\n\nexport class EventEmitter<T> {\n private listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>) {\n this.listeners.push(listener);\n return () => {\n this.listeners = this.listeners.filter(l => l !== listener);\n };\n }\n\n emit(payload: T) {\n this.listeners.forEach(listener => listener(payload));\n }\n}","import { BaseUploader } from './BaseUploader';\nimport { UploadOptions, UploadTaskState } from './types';\nimport { EventEmitter } from './EventEmitter';\n\nexport class UploadTask {\n public state: UploadTaskState;\n public events = new EventEmitter<UploadTaskState>();\n private abortController = new AbortController();\n private retries = 0;\n\n constructor(\n private uploader: BaseUploader,\n private options: UploadOptions,\n private maxRetries = 2,\n private retryDelay = 500\n ) {\n this.state = {\n id: crypto.randomUUID(),\n progress: 0,\n status: 'queued'\n };\n }\n\n async start(): Promise<void> {\n this.update({ status: 'uploading' });\n\n while (this.retries <= this.maxRetries) {\n try {\n const response = await this.uploader.upload(\n this.options,\n progress => this.update({ progress }),\n this.abortController.signal\n );\n\n this.update({ status: 'success', progress: 100, response });\n return;\n } catch (error: unknown) {\n if (this.abortController.signal.aborted) {\n this.update({ status: 'cancelled' });\n return;\n }\n\n const message = error instanceof Error ? error.message : 'Unknown upload error';\n\n if (this.retries >= this.maxRetries) {\n this.update({ status: 'error', error: message });\n return;\n }\n\n this.retries++;\n await this.sleep(this.retryDelay * Math.pow(2, this.retries - 1));\n }\n }\n }\n\n cancel() {\n this.abortController.abort();\n this.update({ status: 'cancelled' });\n }\n\n private update(update: Partial<UploadTaskState>) {\n this.state = { ...this.state, ...update };\n this.events.emit(this.state);\n }\n\n private sleep(ms: number) {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}","import { BaseUploader } from './BaseUploader';\nimport { UploadOptions } from './types';\nimport { UploadTask } from './UploadTask';\n\nexport class UploadManager {\n private queue: UploadTask[] = [];\n private active = 0;\n\n constructor(private uploader: BaseUploader, private concurrency = 3) { }\n\n add(options: UploadOptions) {\n const task = new UploadTask(this.uploader, options);\n this.queue.push(task);\n this.process();\n return task;\n }\n\n private async process() {\n if (this.active >= this.concurrency) return;\n\n const next = this.queue.find(t => t.state.status === 'queued');\n if (!next) return;\n\n this.active++;\n await next.start();\n this.active--;\n this.process();\n }\n}","import { UploadOptions, UploadResponse } from './types';\n\nexport abstract class BaseUploader {\n abstract upload(options: UploadOptions, onProgress: (percent: number) => void, signal?: AbortSignal): Promise<UploadResponse>;\n}","import { BaseUploader } from '../core/BaseUploader';\nimport { UploadOptions, UploadResponse } from '../core/types';\n\ninterface S3Config {\n apiBaseUrl: string;\n publicUrl: string;\n}\n\nexport class S3Uploader extends BaseUploader {\n constructor(private config: S3Config) {\n super();\n }\n\n async upload(\n options: UploadOptions,\n onProgress: (percent: number) => void,\n signal?: AbortSignal\n ): Promise<UploadResponse> {\n const presignRes = await fetch(`${this.config.apiBaseUrl}/s3/presign-upload`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n fileName: options.fileName || options.file.name,\n folder: options.folder,\n contentType: options.file.type\n })\n });\n\n const { uploadUrl, key } = await presignRes.json();\n\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n xhr.upload.onprogress = event => {\n if (event.lengthComputable) {\n onProgress(Math.round((event.loaded / event.total) * 100));\n }\n };\n\n xhr.onload = () => {\n if (xhr.status === 200) {\n resolve({ url: `${this.config.publicUrl}/${key}`, provider: 's3' });\n } else {\n reject(new Error('S3 upload failed'));\n }\n };\n\n xhr.onerror = () => reject(new Error('S3 upload failed'));\n\n signal?.addEventListener('abort', () => {\n xhr.abort();\n reject(new Error('Upload cancelled'));\n });\n\n xhr.open('PUT', uploadUrl);\n xhr.setRequestHeader('Content-Type', options.file.type);\n xhr.send(options.file);\n });\n }\n}","import { BaseUploader } from '../core/BaseUploader';\nimport { UploadOptions, UploadResponse } from '../core/types';\n\ninterface CloudinaryConfig {\n cloudName: string;\n uploadPreset: string;\n}\n\nexport class CloudinaryUploader extends BaseUploader {\n constructor(private config: CloudinaryConfig) {\n super();\n }\n\n async upload(\n options: UploadOptions,\n onProgress: (percent: number) => void\n ): Promise<UploadResponse> {\n const formData = new FormData();\n formData.append('file', options.file);\n formData.append('upload_preset', this.config.uploadPreset);\n formData.append('folder', options.folder);\n\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n xhr.upload.onprogress = event => {\n if (event.lengthComputable) {\n onProgress(Math.round((event.loaded / event.total) * 100));\n }\n };\n\n xhr.onload = () => {\n const data = JSON.parse(xhr.responseText);\n if (xhr.status === 200 && data.secure_url) {\n resolve({ url: data.secure_url, provider: 'cloudinary' });\n } else {\n reject(new Error('Cloudinary upload failed'));\n }\n };\n\n xhr.onerror = () => reject(new Error('Cloudinary upload failed'));\n\n xhr.open('POST', `https://api.cloudinary.com/v1_1/${this.config.cloudName}/upload`);\n xhr.send(formData);\n });\n }\n}"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signskart/uploader",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Production-grade upload manager SDK with queue, progress tracking, retry logic, and multi-provider support (S3, Cloudinary).",
|
|
5
5
|
"author": "Signskart",
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
15
15
|
"import": "./dist/index.js",
|
|
16
|
-
"require": "./dist/index.cjs"
|
|
17
|
-
"types": "./dist/index.d.ts"
|
|
16
|
+
"require": "./dist/index.cjs"
|
|
18
17
|
}
|
|
19
18
|
},
|
|
20
19
|
"scripts": {
|