@wlindabla/file_uploader 1.0.0 → 2.0.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 (109) hide show
  1. package/README.md +51 -20
  2. package/dist/cjs/cache/index.d.ts +198 -0
  3. package/dist/cjs/cache/index.js +318 -0
  4. package/dist/cjs/cache/index.js.map +1 -0
  5. package/dist/cjs/core/index.d.ts +267 -0
  6. package/dist/cjs/core/index.js +753 -0
  7. package/dist/cjs/core/index.js.map +1 -0
  8. package/dist/cjs/events/chunk/index.d.ts +27 -0
  9. package/dist/cjs/events/chunk/index.js +70 -0
  10. package/dist/cjs/events/chunk/index.js.map +1 -0
  11. package/dist/cjs/events/complete/index.d.ts +63 -0
  12. package/dist/cjs/events/complete/index.js +152 -0
  13. package/dist/cjs/events/complete/index.js.map +1 -0
  14. package/dist/cjs/events/index.d.ts +94 -0
  15. package/dist/cjs/events/index.js +85 -0
  16. package/dist/cjs/events/index.js.map +1 -0
  17. package/dist/cjs/events/initialize/index.d.ts +45 -0
  18. package/dist/cjs/events/initialize/index.js +105 -0
  19. package/dist/cjs/events/initialize/index.js.map +1 -0
  20. package/dist/cjs/events/state/index.d.ts +67 -0
  21. package/dist/cjs/events/state/index.js +145 -0
  22. package/dist/cjs/events/state/index.js.map +1 -0
  23. package/dist/cjs/exceptions/index.d.ts +84 -0
  24. package/dist/{exceptions → cjs/exceptions}/index.js +38 -18
  25. package/dist/cjs/exceptions/index.js.map +1 -0
  26. package/dist/cjs/index.d.ts +13 -0
  27. package/dist/cjs/index.js +33 -0
  28. package/dist/cjs/index.js.map +1 -0
  29. package/dist/cjs/subscribers/index.d.ts +33 -0
  30. package/dist/cjs/subscribers/index.js +187 -0
  31. package/dist/cjs/subscribers/index.js.map +1 -0
  32. package/dist/cjs/types/index.d.ts +110 -0
  33. package/dist/cjs/types/index.js +53 -0
  34. package/dist/cjs/types/index.js.map +1 -0
  35. package/dist/cjs/utils/index.d.ts +72 -0
  36. package/dist/cjs/utils/index.js +208 -0
  37. package/dist/cjs/utils/index.js.map +1 -0
  38. package/dist/esm/cache/index.d.mts +198 -0
  39. package/dist/esm/cache/index.js +4 -0
  40. package/dist/{index.js.map → esm/cache/index.js.map} +1 -1
  41. package/dist/{subscribers/index.js → esm/chunk-332NNKOW.js} +36 -34
  42. package/dist/esm/chunk-332NNKOW.js.map +1 -0
  43. package/dist/{events/state/index.js → esm/chunk-6225YMFE.js} +38 -20
  44. package/dist/esm/chunk-6225YMFE.js.map +1 -0
  45. package/dist/{core/index.js → esm/chunk-6DIKDA6J.js} +226 -227
  46. package/dist/esm/chunk-6DIKDA6J.js.map +1 -0
  47. package/dist/esm/chunk-7QVYU63E.js +6 -0
  48. package/dist/esm/chunk-7QVYU63E.js.map +1 -0
  49. package/dist/{events/initialize/index.js → esm/chunk-DN5B6PRW.js} +25 -19
  50. package/dist/esm/chunk-DN5B6PRW.js.map +1 -0
  51. package/dist/{events/index.js → esm/chunk-JDL3U4OX.js} +7 -37
  52. package/dist/esm/chunk-JDL3U4OX.js.map +1 -0
  53. package/dist/{events/chunk/index.js → esm/chunk-LD2DWZRJ.js} +14 -11
  54. package/dist/esm/chunk-LD2DWZRJ.js.map +1 -0
  55. package/dist/{events/complete/index.js → esm/chunk-LTYMA4U4.js} +25 -19
  56. package/dist/{events/complete/index.js.map → esm/chunk-LTYMA4U4.js.map} +1 -1
  57. package/dist/{utils/index.js → esm/chunk-MFYC4PBP.js} +15 -22
  58. package/dist/esm/chunk-MFYC4PBP.js.map +1 -0
  59. package/dist/esm/chunk-NXYS73I4.js +125 -0
  60. package/dist/esm/chunk-NXYS73I4.js.map +1 -0
  61. package/dist/{cache/index.js → esm/chunk-PFALORWQ.js} +10 -11
  62. package/dist/esm/chunk-PFALORWQ.js.map +1 -0
  63. package/dist/{types/index.js → esm/chunk-X757PBC5.js} +5 -7
  64. package/dist/esm/chunk-X757PBC5.js.map +1 -0
  65. package/dist/esm/core/index.d.mts +267 -0
  66. package/dist/esm/core/index.js +12 -0
  67. package/dist/esm/core/index.js.map +1 -0
  68. package/dist/esm/events/chunk/index.d.mts +27 -0
  69. package/dist/esm/events/chunk/index.js +4 -0
  70. package/dist/esm/events/chunk/index.js.map +1 -0
  71. package/dist/esm/events/complete/index.d.mts +63 -0
  72. package/dist/esm/events/complete/index.js +4 -0
  73. package/dist/esm/events/complete/index.js.map +1 -0
  74. package/dist/esm/events/index.d.mts +94 -0
  75. package/dist/esm/events/index.js +8 -0
  76. package/dist/esm/events/index.js.map +1 -0
  77. package/dist/esm/events/initialize/index.d.mts +45 -0
  78. package/dist/esm/events/initialize/index.js +4 -0
  79. package/dist/esm/events/initialize/index.js.map +1 -0
  80. package/dist/esm/events/state/index.d.mts +67 -0
  81. package/dist/esm/events/state/index.js +4 -0
  82. package/dist/esm/events/state/index.js.map +1 -0
  83. package/dist/esm/exceptions/index.d.mts +84 -0
  84. package/dist/esm/exceptions/index.js +4 -0
  85. package/dist/esm/exceptions/index.js.map +1 -0
  86. package/dist/esm/index.d.mts +13 -0
  87. package/dist/esm/index.js +14 -0
  88. package/dist/esm/index.js.map +1 -0
  89. package/dist/esm/subscribers/index.d.mts +33 -0
  90. package/dist/esm/subscribers/index.js +10 -0
  91. package/dist/esm/subscribers/index.js.map +1 -0
  92. package/dist/esm/types/index.d.mts +110 -0
  93. package/dist/esm/types/index.js +4 -0
  94. package/dist/esm/types/index.js.map +1 -0
  95. package/dist/esm/utils/index.d.mts +72 -0
  96. package/dist/esm/utils/index.js +5 -0
  97. package/dist/esm/utils/index.js.map +1 -0
  98. package/package.json +165 -14
  99. package/dist/cache/index.js.map +0 -1
  100. package/dist/core/index.js.map +0 -1
  101. package/dist/events/chunk/index.js.map +0 -1
  102. package/dist/events/index.js.map +0 -1
  103. package/dist/events/initialize/index.js.map +0 -1
  104. package/dist/events/state/index.js.map +0 -1
  105. package/dist/exceptions/index.js.map +0 -1
  106. package/dist/index.js +0 -49
  107. package/dist/subscribers/index.js.map +0 -1
  108. package/dist/types/index.js.map +0 -1
  109. package/dist/utils/index.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/index.ts"],"sourcesContent":["/*\n * This file is part of the project by AGBOKOUDJO Franck.\n *\n * (c) AGBOKOUDJO Franck <internationaleswebservices@gmail.com>\n * Phone: +229 0167 25 18 86\n * LinkedIn: https://www.linkedin.com/in/internationales-web-apps-services-120520193/\n * Company: INTERNATIONALES WEB APPS & SERVICES\n *\n * For more information, please feel free to contact the author.\n */\nimport {\n ChunkSizeConfig,\n DEFAULT_CONFIG\n} from \"../types\";\n\nexport class FileUtils {\n static readonly MB = 1024 * 1024;\n static readonly GB = 1024 * 1024 * 1024;\n\n static bytesToMB(bytes: number): number {\n return parseFloat((bytes / this.MB).toFixed(2));\n }\n\n static bytesToGB(bytes: number): number {\n return parseFloat((bytes / this.GB).toFixed(2));\n }\n\n static formatBytes(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n }\n\n static formatDuration(seconds: number): string {\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = Math.floor(seconds % 60);\n\n if (hours > 0) return `${hours}h ${minutes}m ${secs}s`;\n if (minutes > 0) return `${minutes}m ${secs}s`;\n return `${secs}s`;\n }\n\n static calculateChunkSize(\n fileSize: number,\n speedMbps?: number,\n config: ChunkSizeConfig = DEFAULT_CONFIG\n ): number {\n const fileSizeMB = fileSize / this.MB;\n\n // Handle slow connections\n if (speedMbps && speedMbps < config.slowSpeedThresholdMbps) {\n return Math.min(\n config.defaultChunkSizeMB * this.MB,\n config.slowSpeedChunkSizeMB * this.MB\n );\n }\n\n // Adjust based on file size\n for (const threshold of config.fileSizeThresholds) {\n if (fileSizeMB <= threshold.maxSizeMB) {\n return threshold.chunkSizeMB * this.MB;\n }\n }\n\n return config.defaultChunkSizeMB * this.MB;\n }\n\n static generateFileHash(file: File|Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = async (e) => {\n try {\n const buffer = e.target?.result as ArrayBuffer;\n const hashBuffer = await crypto.subtle.digest('SHA-256', buffer.slice(0, 1024 * 1024));\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n resolve(hashHex);\n } catch (error) {\n reject(error);\n }\n };\n reader.onerror = reject;\n reader.readAsArrayBuffer(file.slice(0, 1024 * 1024)); // Hash first 1MB\n });\n }\n}\n\nexport function updateProgressBarHTMLNotified(\n progress: number,\n media_id: number,\n filename: string,\n providerName = \"LocalVideo\"\n): string {\n const progressBarId = `progress-bar-item_${providerName}_${media_id}`;\n // On cherche la barre de progression interne (celle qui a la classe .progress-bar)\n const progressBarContainer = document.querySelector(`#${progressBarId}`);\n const progressBarInner = progressBarContainer?.querySelector('.progress-bar') as HTMLElement;\n\n if (progressBarInner) {\n // Mise à jour du DOM existant\n const roundedProgress = Math.round(progress);\n progressBarInner.style.width = `${progress}%`;\n progressBarInner.setAttribute('aria-valuenow', progress.toString());\n progressBarInner.innerText = `${roundedProgress}%`;\n\n return progressBarContainer!.innerHTML;\n } else {\n // Génération du template initial\n return `\n <div id=\"${progressBarId}\" class=\"mb-2\" style=\"width:100%;\">\n <small class=\"control-label text-dark fw-bolder filename-label w-100 d-block text-truncate\" title=\"${filename}\">\n ${filename}\n </small>\n <div class=\"progress\">\n <div class=\"progress-bar bg-success progress-bar-striped progress-bar-animated\"\n role=\"progressbar\"\n style=\"width: ${progress}%;\"\n aria-valuenow=\"${progress}\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\">${Math.round(progress)}%</div>\n </div>\n </div>`;\n }\n}\n\n/**\n * Options for creating chunk FormData\n */\nexport interface ChunkFormDataOptions {\n chunkIndex: number;\n totalChunks: number;\n mediaId: string;\n fileName: string;\n fileSize: number;\n fileHash: string;\n metadata?: Record<string, string | Blob>;\n}\n\n/**\n * Creates FormData for uploading a single file chunk.\n * \n * @param chunk - The chunk blob to upload\n * @param options - Chunk upload options\n * @returns FormData ready to be sent to the server\n * \n * @example\n * ```typescript\n * const formData = createChunkFormData(blob, {\n * chunkIndex: 5,\n * totalChunks: 10,\n * mediaId: 'abc123',\n * fileName: 'video.mp4',\n * fileSize: 104857600,\n * fileHash: 'sha256...'\n * });\n * ```\n */\nexport function createChunkFormData(\n chunk: Blob,\n options: ChunkFormDataOptions\n): FormData {\n const formData = new FormData();\n\n // Chunk data\n formData.append('chunk', chunk);\n formData.append('chunkIndex', options.chunkIndex.toString());\n formData.append('chunkSize', chunk.size.toString());\n formData.append('totalChunks', options.totalChunks.toString());\n\n // File metadata\n formData.append('fileName', options.fileName);\n formData.append('fileSize', options.fileSize.toString());\n formData.append('fileHash', options.fileHash);\n\n // Media ID (returned by server after metadata registration)\n formData.append('mediaId', options.mediaId);\n\n // Optional additional data\n if (options.metadata) {\n for (const [key, value] of Object.entries(options.metadata)) {\n if (typeof value === 'string' || value instanceof Blob) {\n formData.append(key, value);\n }\n }\n }\n\n return formData;\n}\n\n/**\n * Builder pattern for creating chunk FormData with fluent API.\n */\nexport class ChunkFormDataBuilder {\n private formData: FormData ;\n\n constructor(chunk: Blob) {\n this.formData = new FormData();\n\n this.formData.append('chunk', chunk);\n this.formData.append('chunkSize', chunk.size.toString());\n }\n\n withChunkInfo(chunkIndex: number, totalChunks: number): this {\n this.formData.append('chunkIndex', chunkIndex.toString());\n this.formData.append('totalChunks', totalChunks.toString());\n return this;\n }\n\n withFileInfo(fileName: string, fileSize: number, fileHash: string): this {\n this.formData.append('fileName', fileName);\n this.formData.append('fileSize', fileSize.toString());\n this.formData.append('fileHash', fileHash);\n return this;\n }\n\n withSessionId(sessionId: string): this {\n this.formData.append('sessionId', sessionId);\n return this;\n }\n\n withMetadata(metadata: Record<string, string | Blob>): this {\n for (const [key, value] of Object.entries(metadata)) {\n if (typeof value === 'string' || value instanceof Blob) {\n this.formData.append(key, value);\n }\n }\n return this;\n }\n\n build(): FormData {\n return this.formData;\n }\n}\n\n// Stratégie de retry configurable\ninterface RetryStrategyInterface {\n shouldRetry(attempt: number, maxRetries: number, error: Error): boolean;\n getDelay(attempt: number): number;\n}\n\nexport class ExponentialBackoffStrategy implements RetryStrategyInterface {\n shouldRetry(attempt: number, maxRetries: number): boolean {\n return attempt < maxRetries;\n }\n\n getDelay(attempt: number): number {\n return Math.pow(2, attempt) * 1000;\n }\n}\n\nexport class LinearBackoffStrategy implements RetryStrategyInterface {\n shouldRetry(attempt: number, maxRetries: number): boolean {\n return attempt < maxRetries;\n }\n\n getDelay(attempt: number): number {\n return (attempt + 1) * 1000; // 1s, 2s, 3s...\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,198 @@
1
+ import { ResumeData } from '../types/index.mjs';
2
+ import '@wlindabla/http_client';
3
+
4
+ /**
5
+ * Interface for caching upload resume data.
6
+ *
7
+ * This interface extends the base cache functionality to specifically
8
+ * handle resume data for file uploads, allowing uploads to be paused
9
+ * and resumed across browser sessions.
10
+ *
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const cache: UploadResumeCacheInterface = new LocalStorageUploadResumeCache();
15
+ *
16
+ * // Save progress
17
+ * await cache.setItem('video.mp4', {
18
+ * uploadedChunks: 45,
19
+ * totalChunks: 100,
20
+ * lastBytePosition: 47185920
21
+ * });
22
+ *
23
+ * // Resume later
24
+ * const data = await cache.getItem('video.mp4');
25
+ * console.log(`Resume from chunk ${data.uploadedChunks}`);
26
+ * ```
27
+ */
28
+ interface UploadResumeCacheInterface {
29
+ /**
30
+ * Retrieves cached resume data for a specific upload.
31
+ *
32
+ * @param key - Unique identifier for the upload (typically filename or file hash)
33
+ * @returns Promise resolving to the cached resume data
34
+ * @throws {Error} If the key doesn't exist or data is corrupted
35
+ */
36
+ getItem(key: string): Promise<ResumeData>;
37
+ /**
38
+ * Stores resume data for an upload session.
39
+ *
40
+ * @param key - Unique identifier for the upload
41
+ * @param data - Resume data containing upload progress information
42
+ * @returns Promise that resolves when data is successfully cached
43
+ * @throws {Error} If storage quota is exceeded or data is invalid
44
+ */
45
+ setItem(key: string, data: ResumeData): Promise<void>;
46
+ }
47
+ /**
48
+ * Default adapter for caching resume data during file uploads.
49
+ *
50
+ * Implements an in-memory storage strategy with secure serialization,
51
+ * strict data validation, and comprehensive error handling.
52
+ *
53
+ * This implementation serves as a foundation for specialized adapters
54
+ * (localStorage, IndexedDB, sessionStorage, etc.).
55
+ *
56
+ * @implements {UploadResumeCacheInterface}
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const adapter = new DefaultUploadResumeCacheAdapter();
61
+ *
62
+ * // Save resume data
63
+ * await adapter.setItem('upload-123', {
64
+ * fileId: 'file-abc',
65
+ * fileName: 'document.pdf',
66
+ * fileSize: 5242880,
67
+ * uploadedChunks: 12,
68
+ * lastChunkIndex: 11,
69
+ * lastBytePosition: 1258291,
70
+ * chunkSize: 1048576
71
+ * });
72
+ *
73
+ * // Retrieve and resume
74
+ * const resumeData = await adapter.getItem('upload-123');
75
+ * console.log(`Resume from chunk ${resumeData.uploadedChunks}`);
76
+ *
77
+ * // Remove specific item
78
+ * await adapter.removeItem('upload-123');
79
+ *
80
+ * // Clear all cache
81
+ * await adapter.clear();
82
+ * ```
83
+ */
84
+ declare class DefaultUploadResumeCacheAdapter implements UploadResumeCacheInterface {
85
+ private cache;
86
+ private readonly maxCacheSize;
87
+ constructor();
88
+ /**
89
+ * Validates that the runtime environment is appropriate.
90
+ *
91
+ * @private
92
+ * @throws {UploadCacheError} If the environment is incompatible
93
+ */
94
+ private validateEnvironment;
95
+ /**
96
+ * Validates resume data according to strict criteria.
97
+ *
98
+ * @private
99
+ * @param data - The data to validate
100
+ * @throws {UploadCacheError} If the data is invalid
101
+ */
102
+ private validateResumeData;
103
+ /**
104
+ * Retrieves resume data for a specific upload.
105
+ *
106
+ * @param key - Unique identifier for the upload
107
+ * @returns Promise resolved with the resume data
108
+ * @throws {UploadCacheError} If the key does not exist or data is corrupted
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * try {
113
+ * const data = await adapter.getItem('upload-123');
114
+ * console.log(`${data.uploadedChunks}/${Math.ceil(data.fileSize / data.chunkSize)} chunks`);
115
+ * } catch (error) {
116
+ * console.error('Failed to retrieve data:', error.message);
117
+ * }
118
+ * ```
119
+ */
120
+ getItem(key: string): Promise<ResumeData>;
121
+ /**
122
+ * Stores resume data for an upload session.
123
+ *
124
+ * @param key - Unique identifier for the upload
125
+ * @param data - Resume data containing upload progress information
126
+ * @returns Promise resolved when data is successfully cached
127
+ * @throws {UploadCacheError} If quota is exceeded or data is invalid
128
+ *
129
+ * @example
130
+ * ```typescript
131
+ * try {
132
+ * await adapter.setItem('upload-123', {
133
+ * fileId: 'file-abc',
134
+ * fileName: 'video.mp4',
135
+ * fileSize: 10737418240,
136
+ * uploadedChunks: 45,
137
+ * lastChunkIndex: 44,
138
+ * lastBytePosition: 47185920,
139
+ * chunkSize: 1048576
140
+ * });
141
+ * console.log('Data successfully saved');
142
+ * } catch (error) {
143
+ * console.error('Storage error:', error.message);
144
+ * }
145
+ * ```
146
+ */
147
+ setItem(key: string, data: ResumeData): Promise<void>;
148
+ /**
149
+ * Removes resume data for a specific upload.
150
+ *
151
+ * @param key - Unique identifier for the upload
152
+ * @returns Promise resolved after removal
153
+ *
154
+ * @example
155
+ * ```typescript
156
+ * await adapter.removeItem('upload-123');
157
+ * ```
158
+ */
159
+ removeItem(key: string): Promise<void>;
160
+ /**
161
+ * Clears all cached resume data.
162
+ *
163
+ * @returns Promise resolved after complete cleanup
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * await adapter.clear();
168
+ * console.log('Cache cleared');
169
+ * ```
170
+ */
171
+ clear(): Promise<void>;
172
+ /**
173
+ * Returns the number of entries currently in cache.
174
+ *
175
+ * @returns Number of cache entries
176
+ */
177
+ get size(): number;
178
+ /**
179
+ * Returns cache usage as a percentage.
180
+ *
181
+ * @returns Usage percentage (0-100)
182
+ */
183
+ get usage(): number;
184
+ }
185
+ /**
186
+ * Custom error for upload cache operations.
187
+ *
188
+ * @example
189
+ * ```typescript
190
+ * throw new UploadCacheError('Resume data not found', 'NOT_FOUND');
191
+ * ```
192
+ */
193
+ declare class UploadCacheError extends Error {
194
+ readonly code: string;
195
+ constructor(message: string, code: string);
196
+ }
197
+
198
+ export { DefaultUploadResumeCacheAdapter, UploadCacheError, type UploadResumeCacheInterface };
@@ -0,0 +1,4 @@
1
+ export { DefaultUploadResumeCacheAdapter, UploadCacheError } from '../chunk-PFALORWQ.js';
2
+ import '../chunk-7QVYU63E.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -1,21 +1,21 @@
1
- 'use strict';
1
+ import { InitializeUploadFailureException } from './chunk-NXYS73I4.js';
2
+ import { HttpFileUploaderEvents } from './chunk-JDL3U4OX.js';
3
+ import { FinalizeUploadFailureEvent } from './chunk-LTYMA4U4.js';
4
+ import { InitializeUploadStartedEvent, InitializeUploadFailureEvent, InitializeUploadSuccessEvent } from './chunk-DN5B6PRW.js';
5
+ import { __name } from './chunk-7QVYU63E.js';
6
+ import { safeFetch, HttpFetchError } from '@wlindabla/http_client/core';
2
7
 
3
- var events = require('../events');
4
- var http_client = require('@wlindabla/http_client');
5
- var exceptions = require('../exceptions');
6
-
7
- var __defProp = Object.defineProperty;
8
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
- class InitializeUploadSubscriber {
8
+ var InitializeUploadSubscriber = class {
10
9
  constructor(eventDispatcher) {
11
10
  this.eventDispatcher = eventDispatcher;
12
11
  }
12
+ eventDispatcher;
13
13
  static {
14
14
  __name(this, "InitializeUploadSubscriber");
15
15
  }
16
16
  getSubscribedEvents() {
17
17
  return {
18
- [events.HttpFileUploaderEvents.INITIALIZE_UPLOAD]: { listener: "onInitializeUpload", priority: 100 }
18
+ [HttpFileUploaderEvents.INITIALIZE_UPLOAD]: { listener: "onInitializeUpload", priority: 100 }
19
19
  };
20
20
  }
21
21
  /**
@@ -29,15 +29,15 @@ class InitializeUploadSubscriber {
29
29
  event.stopPropagation();
30
30
  const initialzeUploadRequestOptions = event.initUploadOptions;
31
31
  this.eventDispatcher.dispatch(
32
- new events.InitializeUploadStartedEvent(
32
+ new InitializeUploadStartedEvent(
33
33
  initialzeUploadRequestOptions.fileName,
34
34
  initialzeUploadRequestOptions.fileSize,
35
35
  initialzeUploadRequestOptions.fileHash
36
36
  ),
37
- events.HttpFileUploaderEvents.INITIALIZE_UPLOAD_STARTED
37
+ HttpFileUploaderEvents.INITIALIZE_UPLOAD_STARTED
38
38
  );
39
39
  try {
40
- const response = await http_client.safeFetch({
40
+ const response = await safeFetch({
41
41
  url: initialzeUploadRequestOptions.endpointInit,
42
42
  methodSend: "POST",
43
43
  headers: {
@@ -59,17 +59,17 @@ class InitializeUploadSubscriber {
59
59
  const status = response.status;
60
60
  if (response.failed) {
61
61
  console.error(`Initialize upload failed (HTTP ${status}):`, response);
62
- const errorUploadFailure = new exceptions.InitializeUploadFailureException(
62
+ const errorUploadFailure = new InitializeUploadFailureException(
63
63
  response,
64
64
  `Server returned error: HTTP ${response.status}`
65
65
  );
66
66
  this.eventDispatcher.dispatch(
67
- new events.InitializeUploadFailureEvent(
67
+ new InitializeUploadFailureEvent(
68
68
  errorUploadFailure,
69
69
  status,
70
70
  response.data
71
71
  ),
72
- events.HttpFileUploaderEvents.INITIALIZE_UPLOAD_FAILURE
72
+ HttpFileUploaderEvents.INITIALIZE_UPLOAD_FAILURE
73
73
  );
74
74
  throw errorUploadFailure;
75
75
  }
@@ -77,39 +77,41 @@ class InitializeUploadSubscriber {
77
77
  if (!responseData || typeof responseData !== "object") {
78
78
  const validationError = "Invalid server response: expected object, got " + typeof responseData;
79
79
  console.error("Invalid response structure:", responseData);
80
- throw new exceptions.InitializeUploadFailureException(
80
+ const err = new InitializeUploadFailureException(
81
81
  responseData,
82
82
  validationError
83
83
  );
84
+ throw err;
84
85
  }
85
86
  let sessionId = responseData.mediaId || responseData.mediaIdFromServer || responseData.sessionId || responseData.uploadId;
86
87
  if (!sessionId) {
87
88
  const missingKeyError = 'Server response missing required field: "mediaId","mediaIdFromServer", "sessionId", or "uploadId"';
88
89
  console.error("Missing session ID in response:", responseData);
89
- throw new exceptions.InitializeUploadFailureException(
90
+ const err = new InitializeUploadFailureException(
90
91
  responseData,
91
92
  missingKeyError
92
93
  );
94
+ throw err;
93
95
  }
94
96
  if (typeof sessionId === "number") {
95
97
  sessionId = sessionId.toString();
96
98
  }
97
99
  event.setMediaId(sessionId);
98
100
  this.eventDispatcher.dispatch(
99
- new events.InitializeUploadSuccessEvent(
101
+ new InitializeUploadSuccessEvent(
100
102
  status,
101
103
  sessionId,
102
104
  responseData
103
105
  ),
104
- events.HttpFileUploaderEvents.INITIALIZE_UPLOAD_SUCCESS
106
+ HttpFileUploaderEvents.INITIALIZE_UPLOAD_SUCCESS
105
107
  );
106
108
  } catch (error) {
107
- if (error instanceof http_client.HttpFetchError) {
109
+ if (error instanceof HttpFetchError) {
108
110
  this.eventDispatcher.dispatch(
109
- new events.InitializeUploadFailureEvent(
111
+ new InitializeUploadFailureEvent(
110
112
  error instanceof Error ? error : new Error(String(error))
111
113
  ),
112
- events.HttpFileUploaderEvents.INITIALIZE_UPLOAD_FAILURE
114
+ HttpFileUploaderEvents.INITIALIZE_UPLOAD_FAILURE
113
115
  );
114
116
  return;
115
117
  }
@@ -117,23 +119,24 @@ class InitializeUploadSubscriber {
117
119
  throw error;
118
120
  }
119
121
  }
120
- }
121
- class FinalizeUploadSubscriber {
122
+ };
123
+ var FinalizeUploadSubscriber = class {
122
124
  constructor(eventDispatcher) {
123
125
  this.eventDispatcher = eventDispatcher;
124
126
  }
127
+ eventDispatcher;
125
128
  static {
126
129
  __name(this, "FinalizeUploadSubscriber");
127
130
  }
128
131
  getSubscribedEvents() {
129
132
  return {
130
- [events.HttpFileUploaderEvents.FINALIZE_UPLOAD]: { listener: "onFinalizeUpload", priority: 100 }
133
+ [HttpFileUploaderEvents.FINALIZE_UPLOAD]: { listener: "onFinalizeUpload", priority: 100 }
131
134
  };
132
135
  }
133
136
  async onFinalizeUpload(event) {
134
137
  event.stopPropagation();
135
138
  try {
136
- const responseFinalizeUpload = await http_client.safeFetch({
139
+ const responseFinalizeUpload = await safeFetch({
137
140
  url: event.endPoint,
138
141
  methodSend: "POST",
139
142
  headers: {
@@ -144,19 +147,18 @@ class FinalizeUploadSubscriber {
144
147
  });
145
148
  event.setResponse(responseFinalizeUpload);
146
149
  } catch (error) {
147
- if (error instanceof http_client.HttpFetchError) {
150
+ if (error instanceof HttpFetchError) {
148
151
  this.eventDispatcher.dispatch(
149
- new events.FinalizeUploadFailureEvent(error),
150
- events.HttpFileUploaderEvents.FINALIZE_UPLOAD_FAILURE
152
+ new FinalizeUploadFailureEvent(error),
153
+ HttpFileUploaderEvents.FINALIZE_UPLOAD_FAILURE
151
154
  );
152
155
  return;
153
156
  }
154
157
  throw error;
155
158
  }
156
159
  }
157
- }
160
+ };
158
161
 
159
- exports.FinalizeUploadSubscriber = FinalizeUploadSubscriber;
160
- exports.InitializeUploadSubscriber = InitializeUploadSubscriber;
161
- //# sourceMappingURL=index.js.map
162
- //# sourceMappingURL=index.js.map
162
+ export { FinalizeUploadSubscriber, InitializeUploadSubscriber };
163
+ //# sourceMappingURL=chunk-332NNKOW.js.map
164
+ //# sourceMappingURL=chunk-332NNKOW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/subscribers/index.ts"],"names":[],"mappings":"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","file":"chunk-332NNKOW.js","sourcesContent":["/*\n * This file is part of the project by AGBOKOUDJO Franck.\n *\n * (c) AGBOKOUDJO Franck <internationaleswebservices@gmail.com>\n * Phone: +229 0167 25 18 86\n * LinkedIn: https://www.linkedin.com/in/internationales-web-apps-services-120520193/\n * Company: INTERNATIONALES WEB APPS & SERVICES\n *\n * For more information, please feel free to contact the author.\n */\n\nimport {\n EventSubscriberInterface,\n EventDispatcherInterface\n} from \"@wlindabla/event_dispatcher\";\n\nimport {\n HttpFileUploaderEvents,\n InitializingUploadEvent,\n InitializeUploadStartedEvent,\n InitializeUploadSuccessEvent,\n InitializeUploadFailureEvent,\n FinalizeUploadEvent,\n FinalizeUploadFailureEvent\n} from \"../events\";\n\nimport {\n HttpFetchError,\n safeFetch\n} from \"@wlindabla/http_client/core\";\n\nimport { InitializeUploadResponse } from \"../types\";\n\nimport { InitializeUploadFailureException } from \"../exceptions\";\n\n\n//src/subsciber/index.ts\n\nexport class InitializeUploadSubscriber implements EventSubscriberInterface {\n constructor(private readonly eventDispatcher: EventDispatcherInterface) {\n \n }\n\n public getSubscribedEvents(): Record<string, string | { listener: string; priority?: number | undefined; }> {\n return {\n [HttpFileUploaderEvents.INITIALIZE_UPLOAD]: { listener: \"onInitializeUpload\", priority: 100}\n }\n }\n\n /**\n * Initializes upload session with the server.\n * \n * @param fileHash - SHA-256 hash of the file (first 1MB)\n * @returns Session ID from server, or null if initialization failed\n * @throws {FileUploadInitializationError} If server returns error or network fails\n */\n public async onInitializeUpload(event:InitializingUploadEvent):Promise<void>{\n event.stopPropagation();\n const initialzeUploadRequestOptions = event.initUploadOptions;\n\n this.eventDispatcher.dispatch(\n new InitializeUploadStartedEvent(\n initialzeUploadRequestOptions.fileName,\n initialzeUploadRequestOptions.fileSize,\n initialzeUploadRequestOptions.fileHash\n ),\n HttpFileUploaderEvents.INITIALIZE_UPLOAD_STARTED\n );\n \n try {\n const response = await safeFetch({\n url:initialzeUploadRequestOptions.endpointInit,\n methodSend: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...initialzeUploadRequestOptions.headers\n },\n data: {\n fileName:initialzeUploadRequestOptions.fileName,\n fileSize:initialzeUploadRequestOptions.fileSize,\n fileHash:initialzeUploadRequestOptions.fileHash,\n fileType: initialzeUploadRequestOptions.fileType,\n metadata: initialzeUploadRequestOptions.metadata,\n },\n responseType: \"json\",\n retryCount: 3,\n retryOnStatusCode: true,\n timeout: 45000\n });\n\n const status = response.status;\n \n // Handle error responses (4xx, 5xx)\n if (response.failed) {\n console.error(`Initialize upload failed (HTTP ${status}):`, response);\n\n const errorUploadFailure =new InitializeUploadFailureException(\n response,\n `Server returned error: HTTP ${response.status}`\n );\n\n this.eventDispatcher.dispatch(\n new InitializeUploadFailureEvent(\n errorUploadFailure,\n status,\n response.data),\n HttpFileUploaderEvents.INITIALIZE_UPLOAD_FAILURE\n\n );\n \n throw errorUploadFailure;\n }\n\n const responseData = response.data as InitializeUploadResponse;\n\n // Validate server response struct\n if (!responseData || typeof responseData !== 'object') {\n const validationError = 'Invalid server response: expected object, got ' + typeof responseData\n console.error('Invalid response structure:', responseData);\n\n const err=new InitializeUploadFailureException(\n responseData,\n validationError\n );\n throw err;\n }\n // Extract session ID\n let sessionId =\n responseData.mediaId ||\n responseData.mediaIdFromServer ||\n responseData.sessionId ||\n responseData.uploadId;\n\n if (!sessionId) {\n const missingKeyError = 'Server response missing required field: \"mediaId\",\"mediaIdFromServer\", \"sessionId\", or \"uploadId\"';\n\n console.error('Missing session ID in response:', responseData);\n const err=new InitializeUploadFailureException(\n responseData,\n missingKeyError\n );\n throw err;\n }\n\n if (typeof sessionId === \"number\") { sessionId = sessionId.toString(); }\n\n event.setMediaId(sessionId);\n\n this.eventDispatcher.dispatch(\n new InitializeUploadSuccessEvent(\n status,\n sessionId,\n responseData\n ),\n HttpFileUploaderEvents.INITIALIZE_UPLOAD_SUCCESS\n );\n\n } catch (error) {\n if (error instanceof HttpFetchError) {\n this.eventDispatcher.dispatch(\n new InitializeUploadFailureEvent(\n error instanceof Error ? error : new Error(String(error)),\n ),\n HttpFileUploaderEvents.INITIALIZE_UPLOAD_FAILURE\n );\n return;\n }\n console.error('Initialize upload exception:', error);\n\n throw error;\n }\n }\n}\n\nexport class FinalizeUploadSubscriber implements EventSubscriberInterface{\n\n constructor(private readonly eventDispatcher: EventDispatcherInterface) {\n\n }\n\n public getSubscribedEvents(): Record<string, string | { listener: string; priority?: number | undefined; }> {\n return {\n [HttpFileUploaderEvents.FINALIZE_UPLOAD]: { listener: \"onFinalizeUpload\", priority: 100 }\n }\n }\n\n public async onFinalizeUpload(event: FinalizeUploadEvent): Promise<void>{\n event.stopPropagation();\n try {\n const responseFinalizeUpload = await safeFetch({\n url: event.endPoint,\n methodSend: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...event.headers\n },\n data: { mediaId: event.mediaId, mediaHash: event.mediaHash }\n });\n\n event.setResponse(responseFinalizeUpload)\n } catch (error) {\n if (error instanceof HttpFetchError) {\n this.eventDispatcher.dispatch(\n new FinalizeUploadFailureEvent(error),\n HttpFileUploaderEvents.FINALIZE_UPLOAD_FAILURE\n );\n return;\n }\n\n throw error;\n }\n }\n}"]}
@@ -1,18 +1,20 @@
1
- 'use strict';
1
+ import { __name } from './chunk-7QVYU63E.js';
2
2
 
3
- var __defProp = Object.defineProperty;
4
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
- class UploadStateChangedEvent {
3
+ // src/events/state/index.ts
4
+ var UploadStateChangedEvent = class {
6
5
  constructor(oldState, newState, changedAt = Date.now()) {
7
6
  this.oldState = oldState;
8
7
  this.newState = newState;
9
8
  this.changedAt = changedAt;
10
9
  }
10
+ oldState;
11
+ newState;
12
+ changedAt;
11
13
  static {
12
14
  __name(this, "UploadStateChangedEvent");
13
15
  }
14
- }
15
- class UploadCancelledEvent {
16
+ };
17
+ var UploadCancelledEvent = class {
16
18
  constructor(mediaName, totalChunks, uploadedBytes, percentage, currentChunkIndex, message = "Upload cancelled by user", cancelledAt = Date.now()) {
17
19
  this.mediaName = mediaName;
18
20
  this.totalChunks = totalChunks;
@@ -22,11 +24,18 @@ class UploadCancelledEvent {
22
24
  this.message = message;
23
25
  this.cancelledAt = cancelledAt;
24
26
  }
27
+ mediaName;
28
+ totalChunks;
29
+ uploadedBytes;
30
+ percentage;
31
+ currentChunkIndex;
32
+ message;
33
+ cancelledAt;
25
34
  static {
26
35
  __name(this, "UploadCancelledEvent");
27
36
  }
28
- }
29
- class UploadResumedEvent {
37
+ };
38
+ var UploadResumedEvent = class {
30
39
  constructor(mediaName, totalChunks, uploadedBytes, percentage, resumedAt = Date.now()) {
31
40
  this.mediaName = mediaName;
32
41
  this.totalChunks = totalChunks;
@@ -34,11 +43,16 @@ class UploadResumedEvent {
34
43
  this.percentage = percentage;
35
44
  this.resumedAt = resumedAt;
36
45
  }
46
+ mediaName;
47
+ totalChunks;
48
+ uploadedBytes;
49
+ percentage;
50
+ resumedAt;
37
51
  static {
38
52
  __name(this, "UploadResumedEvent");
39
53
  }
40
- }
41
- class UploadPausedEvent {
54
+ };
55
+ var UploadPausedEvent = class {
42
56
  constructor(mediaName, totalChunks, uploadedBytes, percentage, pausedAt = Date.now()) {
43
57
  this.mediaName = mediaName;
44
58
  this.totalChunks = totalChunks;
@@ -46,16 +60,24 @@ class UploadPausedEvent {
46
60
  this.percentage = percentage;
47
61
  this.pausedAt = pausedAt;
48
62
  }
63
+ mediaName;
64
+ totalChunks;
65
+ uploadedBytes;
66
+ percentage;
67
+ pausedAt;
49
68
  static {
50
69
  __name(this, "UploadPausedEvent");
51
70
  }
52
- }
53
- class UploadProgressEvent {
71
+ };
72
+ var UploadProgressEvent = class {
54
73
  constructor(uploadProgress, responseData, httpStatus) {
55
74
  this.uploadProgress = uploadProgress;
56
75
  this.responseData = responseData;
57
76
  this.httpStatus = httpStatus;
58
77
  }
78
+ uploadProgress;
79
+ responseData;
80
+ httpStatus;
59
81
  static {
60
82
  __name(this, "UploadProgressEvent");
61
83
  }
@@ -86,12 +108,8 @@ class UploadProgressEvent {
86
108
  get elapsed() {
87
109
  return this.uploadProgress.elapsed;
88
110
  }
89
- }
111
+ };
90
112
 
91
- exports.UploadCancelledEvent = UploadCancelledEvent;
92
- exports.UploadPausedEvent = UploadPausedEvent;
93
- exports.UploadProgressEvent = UploadProgressEvent;
94
- exports.UploadResumedEvent = UploadResumedEvent;
95
- exports.UploadStateChangedEvent = UploadStateChangedEvent;
96
- //# sourceMappingURL=index.js.map
97
- //# sourceMappingURL=index.js.map
113
+ export { UploadCancelledEvent, UploadPausedEvent, UploadProgressEvent, UploadResumedEvent, UploadStateChangedEvent };
114
+ //# sourceMappingURL=chunk-6225YMFE.js.map
115
+ //# sourceMappingURL=chunk-6225YMFE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/events/state/index.ts"],"names":[],"mappings":";;;AAmBO,IAAM,0BAAN,MAA8B;AAAA,EACjC,YACoB,QAAA,EACA,QAAA,EACA,SAAA,GAAoB,IAAA,CAAK,KAAI,EAC/C;AAHkB,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAAA,EAChB;AAAA,EAHgB,QAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EAvBxB;AAmBqC,IAAA,MAAA,CAAA,IAAA,EAAA,yBAAA,CAAA;AAAA;AAMrC;AAMO,IAAM,uBAAN,MAA2B;AAAA,EAC9B,WAAA,CACoB,SAAA,EACA,WAAA,EACA,aAAA,EACA,UAAA,EACA,iBAAA,EACA,OAAA,GAAiB,0BAAA,EACjB,WAAA,GAAsB,IAAA,CAAK,GAAA,EAAI,EACjD;AAPkB,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AACA,IAAA,IAAA,CAAA,aAAA,GAAA,aAAA;AACA,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,iBAAA,GAAA,iBAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAA,EAChB;AAAA,EAPgB,SAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA,iBAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EAvCxB;AA+BkC,IAAA,MAAA,CAAA,IAAA,EAAA,sBAAA,CAAA;AAAA;AAUlC;AAMO,IAAM,qBAAN,MAAyB;AAAA,EAC5B,WAAA,CACoB,WACA,WAAA,EACA,aAAA,EACA,YACA,SAAA,GAAoB,IAAA,CAAK,KAAI,EAC/C;AALkB,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AACA,IAAA,IAAA,CAAA,aAAA,GAAA,aAAA;AACA,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAAA,EAChB;AAAA,EALgB,SAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EArDxB;AA+CgC,IAAA,MAAA,CAAA,IAAA,EAAA,oBAAA,CAAA;AAAA;AAQhC;AAKO,IAAM,oBAAN,MAAwB;AAAA,EAC3B,WAAA,CACoB,WACA,WAAA,EACA,aAAA,EACA,YACA,QAAA,GAAmB,IAAA,CAAK,KAAI,EAC9C;AALkB,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AACA,IAAA,IAAA,CAAA,aAAA,GAAA,aAAA;AACA,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAAA,EAChB;AAAA,EALgB,SAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EAlExB;AA4D+B,IAAA,MAAA,CAAA,IAAA,EAAA,mBAAA,CAAA;AAAA;AAQ/B;AAKO,IAAM,sBAAN,MAA0B;AAAA,EAC7B,WAAA,CACqB,cAAA,EACD,YAAA,EACA,UAAA,EAClB;AAHmB,IAAA,IAAA,CAAA,cAAA,GAAA,cAAA;AACD,IAAA,IAAA,CAAA,YAAA,GAAA,YAAA;AACA,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAAA,EAChB;AAAA,EAHiB,cAAA;AAAA,EACD,YAAA;AAAA,EACA,UAAA;AAAA,EA7ExB;AAyEiC,IAAA,MAAA,CAAA,IAAA,EAAA,qBAAA,CAAA;AAAA;AAAA,EAO7B,IAAW,cAAA,GAAyB;AAAE,IAAA,OAAO,KAAK,cAAA,CAAe,cAAA;AAAA,EAAgB;AAAA,EAEjF,IAAW,WAAA,GAAsB;AAAE,IAAA,OAAO,KAAK,cAAA,CAAe,WAAA;AAAA,EAAa;AAAA,EAE3E,IAAW,UAAA,GAAqB;AAAE,IAAA,OAAO,KAAK,cAAA,CAAe,UAAA;AAAA,EAAY;AAAA,EAEzE,IAAW,aAAA,GAAwB;AAAE,IAAA,OAAO,KAAK,cAAA,CAAe,aAAA;AAAA,EAAe;AAAA,EAE/E,IAAW,UAAA,GAAqB;AAAE,IAAA,OAAO,KAAK,cAAA,CAAe,UAAA;AAAA,EAAY;AAAA,EAEzE,IAAW,YAAA,GAAuB;AAAE,IAAA,OAAO,KAAK,cAAA,CAAe,YAAA;AAAA,EAAc;AAAA,EAE7E,IAAW,KAAA,GAA4B;AAAE,IAAA,OAAO,KAAK,cAAA,CAAe,KAAA;AAAA,EAAO;AAAA,EAE3E,IAAW,sBAAA,GAAoD;AAAE,IAAA,OAAO,KAAK,cAAA,CAAe,sBAAA;AAAA,EAAwB;AAAA,EAEpH,IAAW,OAAA,GAAkB;AAAE,IAAA,OAAO,KAAK,cAAA,CAAe,OAAA;AAAA,EAAS;AACvE","file":"chunk-6225YMFE.js","sourcesContent":["/*\n * This file is part of the project by AGBOKOUDJO Franck.\n *\n * (c) AGBOKOUDJO Franck <internationaleswebservices@gmail.com>\n * Phone: +229 0167 25 18 86\n * LinkedIn: https://www.linkedin.com/in/internationales-web-apps-services-120520193/\n * Company: INTERNATIONALES WEB APPS & SERVICES\n *\n * For more information, please feel free to contact the author.\n */\n\nimport {\n UploadState,\n UploadProgress\n} from \"../../types\";\n\n/**\n * Event data for UPLOAD_STATE_CHANGED\n */\nexport class UploadStateChangedEvent {\n constructor(\n public readonly oldState: UploadState,\n public readonly newState: UploadState,\n public readonly changedAt: number = Date.now()\n ) { }\n}\n\n\n/**\n * Event data for UPLOAD_CANCELLED\n */\nexport class UploadCancelledEvent {\n constructor(\n public readonly mediaName: string,\n public readonly totalChunks: number,\n public readonly uploadedBytes: number,\n public readonly percentage: number,\n public readonly currentChunkIndex:number,\n public readonly message: string =\"Upload cancelled by user\",\n public readonly cancelledAt: number = Date.now()\n ) { }\n}\n\n\n/**\n * Event data for UPLOAD_RESUMED\n */\nexport class UploadResumedEvent {\n constructor(\n public readonly mediaName: string,\n public readonly totalChunks: number,\n public readonly uploadedBytes: number,\n public readonly percentage: number,\n public readonly resumedAt: number = Date.now()\n ) { }\n}\n\n/**\n * Event data for UPLOAD_PAUSED\n */\nexport class UploadPausedEvent {\n constructor(\n public readonly mediaName: string,\n public readonly totalChunks: number,\n public readonly uploadedBytes: number,\n public readonly percentage: number,\n public readonly pausedAt: number = Date.now()\n ) { }\n}\n\n/**\n * Event data for MEDIA_CHUNK_UPLOAD_SUCCESS\n */\nexport class UploadProgressEvent {\n constructor(\n private readonly uploadProgress: UploadProgress,\n public readonly responseData: string | Record<string, string | any> | unknown,\n public readonly httpStatus: number\n ) { }\n\n public get uploadedChunks(): number { return this.uploadProgress.uploadedChunks; }\n\n public get totalChunks(): number { return this.uploadProgress.totalChunks; }\n\n public get percentage(): number { return this.uploadProgress.percentage; }\n\n public get uploadedBytes(): number { return this.uploadProgress.uploadedBytes; }\n\n public get totalBytes(): number { return this.uploadProgress.totalBytes; }\n\n public get currentChunk(): number { return this.uploadProgress.currentChunk; }\n\n public get speed(): number | undefined { return this.uploadProgress.speed; }\n\n public get estimatedTimeRemaining(): number | undefined | null { return this.uploadProgress.estimatedTimeRemaining; }\n\n public get elapsed(): number { return this.uploadProgress.elapsed; }\n}\n\n"]}