@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 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
- const delay = this.retryDelay * Math.pow(2, this.retries - 1);
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
- `${this.config.apiBaseUrl}/s3/presign-upload`,
161
- {
162
- method: "POST",
163
- headers: { "Content-Type": "application/json" },
164
- body: JSON.stringify({
165
- fileName: options.fileName || options.file.name,
166
- folder: options.folder,
167
- contentType: options.file.type
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
- const percent = event.loaded / event.total * 100;
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
- const percent = event.loaded / event.total * 100;
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
- const delay = this.retryDelay * Math.pow(2, this.retries - 1);
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
- `${this.config.apiBaseUrl}/s3/presign-upload`,
132
- {
133
- method: "POST",
134
- headers: { "Content-Type": "application/json" },
135
- body: JSON.stringify({
136
- fileName: options.fileName || options.file.name,
137
- folder: options.folder,
138
- contentType: options.file.type
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
- const percent = event.loaded / event.total * 100;
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
- const percent = event.loaded / event.total * 100;
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
  }
@@ -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.1",
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": {