@universal-uploader/core 1.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.
- package/dist/const.d.ts +19 -0
- package/dist/createUpload-Bv4Z2y9b.js +155 -0
- package/dist/createUpload-Bv4Z2y9b.js.map +1 -0
- package/dist/createUpload-CePIp5sg.js +123 -0
- package/dist/createUpload-CePIp5sg.js.map +1 -0
- package/dist/createUpload-DfsX80rY.js +121 -0
- package/dist/createUpload-DfsX80rY.js.map +1 -0
- package/dist/createUpload-wm9hFbGi.js +153 -0
- package/dist/createUpload-wm9hFbGi.js.map +1 -0
- package/dist/createUpload.d.ts +10 -0
- package/dist/helper.d.ts +74 -0
- package/dist/index-BS99wlKk.js +214 -0
- package/dist/index-BS99wlKk.js.map +1 -0
- package/dist/index-CZdguoWB.js +216 -0
- package/dist/index-CZdguoWB.js.map +1 -0
- package/dist/index.cjs +954 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +144 -0
- package/dist/index.js +952 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator.d.ts +6 -0
- package/dist/stream/helper.d.ts +28 -0
- package/dist/stream/index.d.ts +7 -0
- package/dist/stream/index.js +79 -0
- package/dist/stream-chunked/helper.d.ts +9 -0
- package/dist/stream-chunked/index.d.ts +5 -0
- package/dist/stream.cjs +249 -0
- package/dist/stream.cjs.map +1 -0
- package/dist/stream.d.ts +10 -0
- package/dist/stream.js +247 -0
- package/dist/stream.js.map +1 -0
- package/dist/types-CLZnJDsz.d.ts +111 -0
- package/dist/types.d.ts +127 -0
- package/dist/utils-B4LG-_oN.js +12 -0
- package/dist/utils-B4LG-_oN.js.map +1 -0
- package/dist/utils-MtT6SgZa.js +10 -0
- package/dist/utils-MtT6SgZa.js.map +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/xhr-chuncked/helper.d.ts +27 -0
- package/dist/xhr-chuncked/index.d.ts +7 -0
- package/dist/xhr-chuncked/index.js +181 -0
- package/dist/xhr.cjs +142 -0
- package/dist/xhr.cjs.map +1 -0
- package/dist/xhr.d.ts +10 -0
- package/dist/xhr.js +140 -0
- package/dist/xhr.js.map +1 -0
- package/package.json +34 -0
package/dist/stream.js
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { w as wait } from './utils-MtT6SgZa.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default chunk size (1 MiB) for stream uploads.
|
|
5
|
+
* Used as both API default and fallback for invalid chunk sizes.
|
|
6
|
+
*
|
|
7
|
+
* 스트림 업로드를 위한 기본 청크 크기(1 MiB)입니다.
|
|
8
|
+
* API 기본값 및 유효하지 않은 청크 크기에 대한 폴백으로 사용됩니다.
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_STREAM_CHUNK_SIZE = 1024 * 1024;
|
|
11
|
+
/**
|
|
12
|
+
* Creates a Uint8Array buffer from a specific slice of the file.
|
|
13
|
+
* 파일의 특정 부분을 잘라 Uint8Array 버퍼를 생성합니다.
|
|
14
|
+
*/
|
|
15
|
+
const createBuffer = async ({ file, offset, chunkSize, }) => {
|
|
16
|
+
const chunk = file.slice(offset, offset + chunkSize);
|
|
17
|
+
const buffer = await chunk.arrayBuffer();
|
|
18
|
+
return new Uint8Array(buffer);
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Returns a ReadableStream that yields chunks of the file.
|
|
22
|
+
* 파일의 청크를 순차적으로 내보내는 ReadableStream을 반환합니다.
|
|
23
|
+
*/
|
|
24
|
+
const getStreamUploader = ({ file, chunkSize }) => {
|
|
25
|
+
let offset = 0;
|
|
26
|
+
return new ReadableStream({
|
|
27
|
+
async pull(controller) {
|
|
28
|
+
if (offset >= file.size) {
|
|
29
|
+
controller.close();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const chunkBuffer = await createBuffer({ file, offset, chunkSize });
|
|
33
|
+
controller.enqueue(chunkBuffer);
|
|
34
|
+
offset += chunkSize;
|
|
35
|
+
if (offset >= file.size) {
|
|
36
|
+
controller.close();
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Creates a TransformStream that tracks the progress of the data flowing through it.
|
|
43
|
+
* 데이터 흐름을 추적하여 진행률을 계산하는 TransformStream을 생성합니다.
|
|
44
|
+
*/
|
|
45
|
+
const createProgressStream = ({ totalFileSize, onProgress, }) => {
|
|
46
|
+
let bytesRead = 0;
|
|
47
|
+
return new TransformStream({
|
|
48
|
+
// Calculate progress by obtaining chunks from the readable stream piped through. No separate data processing is performed.
|
|
49
|
+
// 각 리더블 스트림에 파이프를 걸어 청크를 얻어 진행율을 계산합니다. 별도의 chunk 데이터 가공은 하지 않습니다.
|
|
50
|
+
transform: (chunk, controller) => {
|
|
51
|
+
bytesRead += chunk.byteLength;
|
|
52
|
+
onProgress({
|
|
53
|
+
loaded: bytesRead,
|
|
54
|
+
percentage: (bytesRead / totalFileSize) * 100,
|
|
55
|
+
total: totalFileSize,
|
|
56
|
+
});
|
|
57
|
+
controller.enqueue(chunk);
|
|
58
|
+
},
|
|
59
|
+
// Trigger the final progress event once the transform streaming is complete.
|
|
60
|
+
// 변환 스트리밍이 완료되면 마지막 프로그레스 이벤트를 발생시킵니다.
|
|
61
|
+
flush: () => {
|
|
62
|
+
onProgress({
|
|
63
|
+
loaded: totalFileSize,
|
|
64
|
+
percentage: 100,
|
|
65
|
+
total: totalFileSize,
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Uploads a file using the Fetch streaming request body.
|
|
72
|
+
* Fetch 스트리밍 요청 바디를 사용하여 파일을 업로드합니다.
|
|
73
|
+
*/
|
|
74
|
+
const uploadWithStream = async ({ url, file, refresh, options: { chunkSize = DEFAULT_STREAM_CHUNK_SIZE, customHeaders = {}, onProgress, }, }) => {
|
|
75
|
+
const safeChunkSize = Number.isFinite(chunkSize) && chunkSize > 0
|
|
76
|
+
? chunkSize
|
|
77
|
+
: DEFAULT_STREAM_CHUNK_SIZE;
|
|
78
|
+
const stream = getStreamUploader({ file, chunkSize: safeChunkSize });
|
|
79
|
+
const body = onProgress
|
|
80
|
+
? stream.pipeThrough(createProgressStream({ totalFileSize: file.size, onProgress }))
|
|
81
|
+
: stream;
|
|
82
|
+
const abortController = new AbortController();
|
|
83
|
+
const init = {
|
|
84
|
+
method: "POST",
|
|
85
|
+
body,
|
|
86
|
+
duplex: "half",
|
|
87
|
+
signal: abortController.signal,
|
|
88
|
+
headers: {
|
|
89
|
+
"Content-Type": "application/octet-stream",
|
|
90
|
+
...(customHeaders || {}),
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
const response = fetch(url, init);
|
|
94
|
+
return {
|
|
95
|
+
result: response.then((res) => ({
|
|
96
|
+
ok: res.ok,
|
|
97
|
+
total: file.size,
|
|
98
|
+
message: res.ok ? undefined : `Upload failed with status ${res.status}`,
|
|
99
|
+
status: res.ok ? "success" : "error",
|
|
100
|
+
})),
|
|
101
|
+
actions: {
|
|
102
|
+
abort: () => abortController.abort(), // Never put an argument when aborting.
|
|
103
|
+
refresh: () => {
|
|
104
|
+
abortController.abort(); // Never put an argument when aborting.
|
|
105
|
+
refresh();
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Orchestrates file upload by selecting the optimal method and managing retries and errors.
|
|
113
|
+
* 최적의 업로드 방식을 선택하고 재시도 및 에러 처리를 관리하여 파일 업로드를 수행합니다.
|
|
114
|
+
*/
|
|
115
|
+
const upload = async ({ url, file, options: { method = "stream", ...options } }, retryAttempt = 0) => {
|
|
116
|
+
const { onComplete, onProgress, onAbort, onRetry, onError, retryCount: retryCountArg = 3, retryDelay = 1000, throwOnError = false, ...restOptions } = options;
|
|
117
|
+
const retryCount = retryCountArg;
|
|
118
|
+
/**
|
|
119
|
+
* Determines whether to throw an error based on configuration.
|
|
120
|
+
* 구성 설정에 따라 에러를 throw할지 결정합니다.
|
|
121
|
+
*/
|
|
122
|
+
const shouldThrowError = (e) => {
|
|
123
|
+
if (typeof throwOnError === "function") {
|
|
124
|
+
return throwOnError(e);
|
|
125
|
+
}
|
|
126
|
+
return Boolean(throwOnError);
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Handles user-triggered aborts.
|
|
130
|
+
* 사용자에 의해 중단된 경우를 처리합니다.
|
|
131
|
+
*/
|
|
132
|
+
const handleAbort = (e) => {
|
|
133
|
+
onAbort?.(e);
|
|
134
|
+
if (shouldThrowError(e)) {
|
|
135
|
+
throw e;
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
total: 0,
|
|
140
|
+
message: "Aborted by user action",
|
|
141
|
+
status: "aborted",
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Handles generic errors during upload.
|
|
146
|
+
* 업로드 중 발생하는 일반적인 에러를 처리합니다.
|
|
147
|
+
*/
|
|
148
|
+
const handleError = (e) => {
|
|
149
|
+
onError?.(e);
|
|
150
|
+
if (shouldThrowError(e)) {
|
|
151
|
+
throw e;
|
|
152
|
+
}
|
|
153
|
+
return { ok: false, total: 0, message: e.message, status: "error" };
|
|
154
|
+
};
|
|
155
|
+
const finalOptions = {
|
|
156
|
+
...restOptions,
|
|
157
|
+
onProgress: ({ loaded, total, percentage }) => {
|
|
158
|
+
onProgress?.({ loaded, total, percentage });
|
|
159
|
+
if (percentage === 100) {
|
|
160
|
+
onComplete?.();
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
const refresh = () => upload({ url, file, options });
|
|
165
|
+
/**
|
|
166
|
+
* Attempts to retry an upload operation.
|
|
167
|
+
* 업로드 작업을 재시도합니다.
|
|
168
|
+
*/
|
|
169
|
+
const retryUpload = async (uploadArgs) => {
|
|
170
|
+
const nextRetryAttempt = retryAttempt + 1;
|
|
171
|
+
const nextRetryDelay = typeof retryDelay === "function"
|
|
172
|
+
? retryDelay(nextRetryAttempt)
|
|
173
|
+
: retryDelay;
|
|
174
|
+
await wait(nextRetryDelay);
|
|
175
|
+
const uploadResponse = await upload(uploadArgs, nextRetryAttempt);
|
|
176
|
+
onRetry?.();
|
|
177
|
+
return uploadResponse;
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* Wraps the upload operation with error and retry handling.
|
|
181
|
+
* 에러 처리 및 재시도 로직으로 업로드 작업을 래핑합니다.
|
|
182
|
+
*/
|
|
183
|
+
const wrapPromiseErrorHandler = async (uploadResponse) => {
|
|
184
|
+
const { result: originalResult, actions: originalActions } = uploadResponse;
|
|
185
|
+
const retriedResult = originalResult
|
|
186
|
+
.then((uploadResult) => {
|
|
187
|
+
/**
|
|
188
|
+
* fetch resolves for HTTP 4xx/5xx, so stream mode can return { ok: false, status: 'error' }
|
|
189
|
+
* without rejecting. We rethrow here to route it through retry/onError handling.
|
|
190
|
+
*
|
|
191
|
+
* fetch는 HTTP 4xx/5xx에서도 reject하지 않아 stream 모드가 실패 결과를 resolve로 반환할 수 있습니다.
|
|
192
|
+
* 그래서 여기서 다시 throw해서 retry/onError 흐름으로 태웁니다.
|
|
193
|
+
*/
|
|
194
|
+
if (!uploadResult.ok && uploadResult.status === "error") {
|
|
195
|
+
throw new Error(uploadResult.message || "Upload failed");
|
|
196
|
+
}
|
|
197
|
+
return uploadResult;
|
|
198
|
+
})
|
|
199
|
+
.catch(async (e) => {
|
|
200
|
+
if (e instanceof DOMException && e.name === "AbortError") {
|
|
201
|
+
return handleAbort(e);
|
|
202
|
+
}
|
|
203
|
+
if (retryCount > 0) {
|
|
204
|
+
const { result: retryResult, actions: retryActions } = await retryUpload({
|
|
205
|
+
url,
|
|
206
|
+
file,
|
|
207
|
+
options: {
|
|
208
|
+
...options,
|
|
209
|
+
method,
|
|
210
|
+
retryCount: retryCount - 1,
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
Object.assign(originalActions, retryActions);
|
|
214
|
+
return retryResult;
|
|
215
|
+
}
|
|
216
|
+
return handleError(e);
|
|
217
|
+
});
|
|
218
|
+
return { result: Promise.resolve(retriedResult), actions: originalActions };
|
|
219
|
+
};
|
|
220
|
+
try {
|
|
221
|
+
const uploadResult = await wrapPromiseErrorHandler(await uploadWithStream({
|
|
222
|
+
url,
|
|
223
|
+
file,
|
|
224
|
+
refresh,
|
|
225
|
+
options: finalOptions,
|
|
226
|
+
}));
|
|
227
|
+
return uploadResult;
|
|
228
|
+
}
|
|
229
|
+
catch (e) {
|
|
230
|
+
onError?.(e);
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
result: Promise.resolve({
|
|
234
|
+
ok: false,
|
|
235
|
+
total: 0,
|
|
236
|
+
message: "Unsupported upload method",
|
|
237
|
+
status: "error",
|
|
238
|
+
}),
|
|
239
|
+
actions: {
|
|
240
|
+
abort: () => null,
|
|
241
|
+
refresh,
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
export { upload as default };
|
|
247
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sources":["../src/stream/index.ts","../src/stream.ts"],"sourcesContent":["import { UploadParams, UploadResponse, OnProgressParams } from \"../index\";\n\n/**\n * Parameters for stream uploader configuration.\n * 스트림 업로더 구성을 위한 매개변수입니다.\n */\ninterface StreamUploaderParams {\n /** The file to be uploaded. / 업로드할 파일. */\n file: File;\n /** Chunk size in bytes. / 바이트 단위의 청크 크기. */\n chunkSize: number;\n}\n\n/**\n * Default chunk size (1 MiB) for stream uploads.\n * Used as both API default and fallback for invalid chunk sizes.\n *\n * 스트림 업로드를 위한 기본 청크 크기(1 MiB)입니다.\n * API 기본값 및 유효하지 않은 청크 크기에 대한 폴백으로 사용됩니다.\n */\nconst DEFAULT_STREAM_CHUNK_SIZE = 1024 * 1024;\n\n/**\n * Creates a Uint8Array buffer from a specific slice of the file.\n * 파일의 특정 부분을 잘라 Uint8Array 버퍼를 생성합니다.\n */\nconst createBuffer = async ({\n file,\n offset,\n chunkSize,\n}: StreamUploaderParams & { offset: number }) => {\n const chunk = file.slice(offset, offset + chunkSize);\n\n const buffer = await chunk.arrayBuffer();\n\n return new Uint8Array(buffer);\n};\n\n/**\n * Returns a ReadableStream that yields chunks of the file.\n * 파일의 청크를 순차적으로 내보내는 ReadableStream을 반환합니다.\n */\nconst getStreamUploader = ({ file, chunkSize }: StreamUploaderParams) => {\n let offset = 0;\n\n return new ReadableStream<Uint8Array>({\n async pull(controller) {\n if (offset >= file.size) {\n controller.close();\n return;\n }\n\n const chunkBuffer = await createBuffer({ file, offset, chunkSize });\n controller.enqueue(chunkBuffer);\n offset += chunkSize;\n\n if (offset >= file.size) {\n controller.close();\n }\n },\n });\n};\n\n/**\n * Creates a TransformStream that tracks the progress of the data flowing through it.\n * 데이터 흐름을 추적하여 진행률을 계산하는 TransformStream을 생성합니다.\n */\nconst createProgressStream = ({\n totalFileSize,\n onProgress,\n}: {\n totalFileSize: number;\n onProgress: (args: OnProgressParams) => void;\n}) => {\n let bytesRead = 0;\n\n return new TransformStream<Uint8Array, Uint8Array>({\n // Calculate progress by obtaining chunks from the readable stream piped through. No separate data processing is performed.\n // 각 리더블 스트림에 파이프를 걸어 청크를 얻어 진행율을 계산합니다. 별도의 chunk 데이터 가공은 하지 않습니다.\n transform: (chunk, controller) => {\n bytesRead += chunk.byteLength;\n onProgress({\n loaded: bytesRead,\n percentage: (bytesRead / totalFileSize) * 100,\n total: totalFileSize,\n });\n\n controller.enqueue(chunk);\n },\n\n // Trigger the final progress event once the transform streaming is complete.\n // 변환 스트리밍이 완료되면 마지막 프로그레스 이벤트를 발생시킵니다.\n flush: () => {\n onProgress({\n loaded: totalFileSize,\n percentage: 100,\n total: totalFileSize,\n });\n },\n });\n};\n\n/**\n * Uploads a file using the Fetch streaming request body.\n * Fetch 스트리밍 요청 바디를 사용하여 파일을 업로드합니다.\n */\nconst uploadWithStream = async ({\n url,\n file,\n refresh,\n options: {\n chunkSize = DEFAULT_STREAM_CHUNK_SIZE,\n customHeaders = {},\n onProgress,\n },\n}: UploadParams & { refresh: () => void }): Promise<UploadResponse> => {\n const safeChunkSize =\n Number.isFinite(chunkSize) && chunkSize > 0\n ? chunkSize\n : DEFAULT_STREAM_CHUNK_SIZE;\n\n const stream = getStreamUploader({ file, chunkSize: safeChunkSize });\n\n const body = onProgress\n ? stream.pipeThrough(\n createProgressStream({ totalFileSize: file.size, onProgress }),\n )\n : stream;\n\n const abortController = new AbortController();\n\n const init: Readonly<RequestInit> = {\n method: \"POST\",\n body,\n duplex: \"half\",\n signal: abortController.signal,\n headers: {\n \"Content-Type\": \"application/octet-stream\",\n ...(customHeaders || {}),\n },\n };\n\n const response = fetch(url, init);\n\n return {\n result: response.then((res) => ({\n ok: res.ok,\n total: file.size,\n message: res.ok ? undefined : `Upload failed with status ${res.status}`,\n status: res.ok ? \"success\" : \"error\",\n })),\n actions: {\n abort: () => abortController.abort(), // Never put an argument when aborting.\n refresh: () => {\n abortController.abort(); // Never put an argument when aborting.\n refresh();\n },\n },\n };\n};\n\nexport default uploadWithStream;\n","export * from \"./types\";\nimport {\n Upload,\n UploadResponse,\n UploadResult,\n OnProgressParams,\n} from \"./types\";\nimport { wait } from \"./utils\";\nimport uploadWithStream from \"./stream/index\";\n\n/**\n * Orchestrates file upload by selecting the optimal method and managing retries and errors.\n * 최적의 업로드 방식을 선택하고 재시도 및 에러 처리를 관리하여 파일 업로드를 수행합니다.\n */\nconst upload = async (\n { url, file, options: { method = \"stream\", ...options } }: Upload,\n retryAttempt = 0,\n): Promise<UploadResponse> => {\n const {\n onComplete,\n onProgress,\n onAbort,\n onRetry,\n onError,\n retryCount: retryCountArg = 3,\n retryDelay = 1000,\n throwOnError = false,\n ...restOptions\n } = options;\n\n const retryCount = retryCountArg;\n\n /**\n * Determines whether to throw an error based on configuration.\n * 구성 설정에 따라 에러를 throw할지 결정합니다.\n */\n const shouldThrowError = (e: unknown): boolean => {\n if (typeof throwOnError === \"function\") {\n return throwOnError(e);\n }\n\n return Boolean(throwOnError);\n };\n\n /**\n * Handles user-triggered aborts.\n * 사용자에 의해 중단된 경우를 처리합니다.\n */\n const handleAbort = (e: DOMException): UploadResult => {\n onAbort?.(e);\n\n if (shouldThrowError(e)) {\n throw e;\n }\n\n return {\n ok: false,\n total: 0,\n message: \"Aborted by user action\",\n status: \"aborted\",\n };\n };\n\n /**\n * Handles generic errors during upload.\n * 업로드 중 발생하는 일반적인 에러를 처리합니다.\n */\n const handleError = (e: Error): UploadResult => {\n onError?.(e);\n\n if (shouldThrowError(e)) {\n throw e;\n }\n\n return { ok: false, total: 0, message: e.message, status: \"error\" };\n };\n\n const finalOptions = {\n ...restOptions,\n onProgress: ({ loaded, total, percentage }: OnProgressParams) => {\n onProgress?.({ loaded, total, percentage });\n\n if (percentage === 100) {\n onComplete?.();\n }\n },\n };\n\n const refresh = () => upload({ url, file, options });\n\n /**\n * Attempts to retry an upload operation.\n * 업로드 작업을 재시도합니다.\n */\n const retryUpload = async (uploadArgs: Upload): Promise<UploadResponse> => {\n const nextRetryAttempt = retryAttempt + 1;\n\n const nextRetryDelay =\n typeof retryDelay === \"function\"\n ? retryDelay(nextRetryAttempt)\n : retryDelay;\n\n await wait(nextRetryDelay);\n\n const uploadResponse = await upload(uploadArgs, nextRetryAttempt);\n\n onRetry?.();\n\n return uploadResponse;\n };\n\n /**\n * Wraps the upload operation with error and retry handling.\n * 에러 처리 및 재시도 로직으로 업로드 작업을 래핑합니다.\n */\n const wrapPromiseErrorHandler = async (\n uploadResponse: UploadResponse,\n ): Promise<UploadResponse> => {\n const { result: originalResult, actions: originalActions } = uploadResponse;\n\n const retriedResult: Promise<UploadResult> = originalResult\n .then((uploadResult) => {\n /**\n * fetch resolves for HTTP 4xx/5xx, so stream mode can return { ok: false, status: 'error' }\n * without rejecting. We rethrow here to route it through retry/onError handling.\n *\n * fetch는 HTTP 4xx/5xx에서도 reject하지 않아 stream 모드가 실패 결과를 resolve로 반환할 수 있습니다.\n * 그래서 여기서 다시 throw해서 retry/onError 흐름으로 태웁니다.\n */\n if (!uploadResult.ok && uploadResult.status === \"error\") {\n throw new Error(uploadResult.message || \"Upload failed\");\n }\n\n return uploadResult;\n })\n .catch(async (e) => {\n if (e instanceof DOMException && e.name === \"AbortError\") {\n return handleAbort(e);\n }\n\n if (retryCount > 0) {\n const { result: retryResult, actions: retryActions } =\n await retryUpload({\n url,\n file,\n options: {\n ...options,\n method,\n retryCount: retryCount - 1,\n },\n });\n\n Object.assign(originalActions, retryActions);\n return retryResult;\n }\n\n return handleError(e as Error);\n });\n\n return { result: Promise.resolve(retriedResult), actions: originalActions };\n };\n\n try {\n const uploadResult = await wrapPromiseErrorHandler(\n await uploadWithStream({\n url,\n file,\n refresh,\n options: finalOptions,\n }),\n );\n\n return uploadResult;\n } catch (e) {\n onError?.(e as Error);\n }\n\n return {\n result: Promise.resolve({\n ok: false,\n total: 0,\n message: \"Unsupported upload method\",\n status: \"error\",\n }),\n actions: {\n abort: () => null,\n refresh,\n },\n };\n};\n\nexport default upload;\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents progress information for an upload.
|
|
3
|
+
* 업로드 진행 정보를 나타냅니다.
|
|
4
|
+
*/
|
|
5
|
+
interface OnProgressParams {
|
|
6
|
+
/** Bytes loaded so far. / 지금까지 로드된 바이트 수. */
|
|
7
|
+
loaded: number;
|
|
8
|
+
/** Total bytes of the file. / 파일의 전체 바이트 수. */
|
|
9
|
+
total: number;
|
|
10
|
+
/** Percentage completed. / 완료된 비율(%). */
|
|
11
|
+
percentage: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Configuration options for the upload process.
|
|
15
|
+
* 업로드 프로세스를 위한 구성 옵션입니다.
|
|
16
|
+
*/
|
|
17
|
+
interface UploadOptions {
|
|
18
|
+
/** Upload method. 'auto' defaults to stream if supported. / 업로드 방식. 'auto'는 지원 시 스트림을 사용합니다. */
|
|
19
|
+
method?: 'auto' | 'stream' | 'xhr chunked';
|
|
20
|
+
/** Size of each chunk in bytes. / 각 청크의 바이트 크기. */
|
|
21
|
+
chunkSize?: number;
|
|
22
|
+
/** Custom HTTP headers to be sent with the request. / 요청과 함께 전송될 커스텀 HTTP 헤더. */
|
|
23
|
+
customHeaders?: Record<string, string>;
|
|
24
|
+
/** Maximum number of retries. / 최대 재시도 횟수. */
|
|
25
|
+
retryCount?: number;
|
|
26
|
+
/** Delay before retrying (in ms or as a function). / 재시도 전 지연 시간(ms 또는 함수). */
|
|
27
|
+
retryDelay?: number | ((retryCount: number) => number);
|
|
28
|
+
/** Whether to throw an error on failure. / 실패 시 에러를 던질지 여부. */
|
|
29
|
+
throwOnError?: boolean | ((error: unknown) => boolean);
|
|
30
|
+
/** Callback on successful completion. / 성공적으로 완료될 때 호출되는 콜백. */
|
|
31
|
+
onComplete?: () => void;
|
|
32
|
+
/** Callback for progress updates. / 진행률 업데이트를 위한 콜백. */
|
|
33
|
+
onProgress?: (args: OnProgressParams) => void;
|
|
34
|
+
/** Callback on upload abort. / 업로드 중단 시 호출되는 콜백. */
|
|
35
|
+
onAbort?: (error: DOMException) => void;
|
|
36
|
+
/** Callback on retry attempt. / 재시도 시 호출되는 콜백. */
|
|
37
|
+
onRetry?: () => void;
|
|
38
|
+
/** Callback on fatal error. / 치명적 에러 발생 시 호출되는 콜백. */
|
|
39
|
+
onError?: (error: Error) => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Request details for initiating an upload.
|
|
43
|
+
* 업로드를 시작하기 위한 요청 정보입니다.
|
|
44
|
+
*/
|
|
45
|
+
interface Upload {
|
|
46
|
+
/** The destination URL. / 대상 URL. */
|
|
47
|
+
url: string;
|
|
48
|
+
/** The file to upload. / 업로드할 파일. */
|
|
49
|
+
file: File;
|
|
50
|
+
/** Upload options. / 업로드 옵션. */
|
|
51
|
+
options: UploadOptions;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Parameters for starting an upload operation.
|
|
55
|
+
* 업로드 작업을 시작하기 위한 매개변수입니다.
|
|
56
|
+
*/
|
|
57
|
+
interface UploadParams {
|
|
58
|
+
/** The destination URL. / 대상 URL. */
|
|
59
|
+
url: string;
|
|
60
|
+
/** The file to upload. / 업로드할 파일. */
|
|
61
|
+
file: File;
|
|
62
|
+
/** Upload options. / 업로드 옵션. */
|
|
63
|
+
options: UploadOptions;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Possible status states of an upload.
|
|
67
|
+
* 업로드의 가능한 상태 값들입니다.
|
|
68
|
+
*/
|
|
69
|
+
type UploadStatus = 'idle' | 'uploading' | 'success' | 'error' | 'aborted';
|
|
70
|
+
/**
|
|
71
|
+
* The final result of an upload operation.
|
|
72
|
+
* 업로드 작업의 최종 결과입니다.
|
|
73
|
+
*/
|
|
74
|
+
interface UploadResult {
|
|
75
|
+
/** Whether the upload was successful. / 업로드 성공 여부. */
|
|
76
|
+
ok: boolean;
|
|
77
|
+
/** Total bytes of the file. / 파일의 전체 바이트 수. */
|
|
78
|
+
total: number;
|
|
79
|
+
/** Error message if failed. / 실패 시 에러 메시지. */
|
|
80
|
+
message?: string;
|
|
81
|
+
/** Current upload status. / 현재 업로드 상태. */
|
|
82
|
+
status: UploadStatus;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Actions available to control the upload process.
|
|
86
|
+
* 업로드 프로세스를 제어하기 위한 액션들입니다.
|
|
87
|
+
*/
|
|
88
|
+
interface UploadActions {
|
|
89
|
+
/** Abort the current upload. / 현재 업로드를 중단합니다. */
|
|
90
|
+
abort: () => void;
|
|
91
|
+
/** Restart or refresh the upload. / 업로드를 재시작하거나 갱신합니다. */
|
|
92
|
+
refresh: () => void;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The response object returned by the upload initiator.
|
|
96
|
+
* 업로드 시작 시 반환되는 응답 객체입니다.
|
|
97
|
+
*/
|
|
98
|
+
interface UploadResponse {
|
|
99
|
+
/** Promise that resolves with the final upload result. / 최종 업로드 결과를 반환하는 Promise. */
|
|
100
|
+
result: Promise<UploadResult>;
|
|
101
|
+
/** Available control actions. / 사용 가능한 제어 액션들. */
|
|
102
|
+
actions: UploadActions;
|
|
103
|
+
}
|
|
104
|
+
declare global {
|
|
105
|
+
interface RequestInit {
|
|
106
|
+
/** Duplex mode for streaming fetch requests. / 스트리밍 fetch 요청을 위한 듀플렉스 모드. */
|
|
107
|
+
duplex?: 'half';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export type { OnProgressParams as O, Upload as U, UploadActions as a, UploadOptions as b, UploadParams as c, UploadResponse as d, UploadResult as e, UploadStatus as f };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents progress information for an upload.
|
|
3
|
+
* 업로드 진행 정보를 나타냅니다.
|
|
4
|
+
*/
|
|
5
|
+
export interface OnProgressParams {
|
|
6
|
+
/** Bytes loaded so far. / 지금까지 로드된 바이트 수. */
|
|
7
|
+
loaded: number;
|
|
8
|
+
/** Total bytes of the file. / 파일의 전체 바이트 수. */
|
|
9
|
+
total: number;
|
|
10
|
+
/** Percentage completed. / 완료된 비율(%). */
|
|
11
|
+
percentage: number;
|
|
12
|
+
}
|
|
13
|
+
export type UploadMethod = "auto" | "stream" | "stream chunked" | "xhr chunked";
|
|
14
|
+
/**
|
|
15
|
+
* Configuration options for the upload process.
|
|
16
|
+
* 업로드 프로세스를 위한 구성 옵션입니다.
|
|
17
|
+
*/
|
|
18
|
+
export interface UploadOptions {
|
|
19
|
+
/** Upload method. 'auto' defaults to stream if supported. / 업로드 방식. 'auto'는 지원 시 스트림을 사용합니다. */
|
|
20
|
+
method?: UploadMethod;
|
|
21
|
+
/** Size of each chunk in bytes. / 각 청크의 바이트 크기. */
|
|
22
|
+
chunkSize?: number;
|
|
23
|
+
/** Internal retry state for resumed chunked uploads. / 청크 재시도 내부 상태용 오프셋입니다(외부 입력용 아님). */
|
|
24
|
+
offset?: number;
|
|
25
|
+
/** Custom HTTP headers to be sent with the request. / 요청과 함께 전송될 커스텀 HTTP 헤더. */
|
|
26
|
+
customHeaders?: Record<string, string>;
|
|
27
|
+
/** Whether to include credentials (cookies, etc.) in the request. / 요청에 자격 증명(쿠키 등)을 포함할지 여부. */
|
|
28
|
+
withCredentials?: boolean;
|
|
29
|
+
/** Maximum number of retries. / 최대 재시도 횟수. */
|
|
30
|
+
retryCount?: number;
|
|
31
|
+
/** Delay before retrying (in ms or as a function). / 재시도 전 지연 시간(ms 또는 함수). */
|
|
32
|
+
retryDelay?: number | ((retryCount: number) => number);
|
|
33
|
+
/** Whether to throw an error on failure. / 실패 시 에러를 던질지 여부. */
|
|
34
|
+
throwOnError?: boolean | ((error: unknown) => boolean);
|
|
35
|
+
/** Callback on successful completion. / 성공적으로 완료될 때 호출되는 콜백. */
|
|
36
|
+
onComplete?: () => void;
|
|
37
|
+
/** Callback for progress updates. / 진행률 업데이트를 위한 콜백. */
|
|
38
|
+
onProgress?: (args: OnProgressParams) => void;
|
|
39
|
+
/** Callback on upload abort. / 업로드 중단 시 호출되는 콜백. */
|
|
40
|
+
onAbort?: (error: DOMException) => void;
|
|
41
|
+
/** Callback on retry attempt. / 재시도 시 호출되는 콜백. */
|
|
42
|
+
onRetry?: () => void;
|
|
43
|
+
/** Callback when upload is paused. / 업로드 일시정지 시 호출되는 콜백. */
|
|
44
|
+
onPause?: () => void;
|
|
45
|
+
/** Callback when upload is resumed. / 업로드 재개 시 호출되는 콜백. */
|
|
46
|
+
onResume?: () => void;
|
|
47
|
+
/** Callback on fatal error. / 치명적 에러 발생 시 호출되는 콜백. */
|
|
48
|
+
onError?: (error: Error) => void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Parameters for starting an upload operation.
|
|
52
|
+
|
|
53
|
+
* 업로드 작업을 시작하기 위한 매개변수입니다.
|
|
54
|
+
*/
|
|
55
|
+
export interface UploadParams {
|
|
56
|
+
/** The destination URL. / 대상 URL. */
|
|
57
|
+
url: string;
|
|
58
|
+
/** The file to upload. / 업로드할 파일. */
|
|
59
|
+
file: File;
|
|
60
|
+
/** Upload options. / 업로드 옵션. */
|
|
61
|
+
options: UploadOptions;
|
|
62
|
+
}
|
|
63
|
+
export interface UploadParamsInternal extends UploadParams {
|
|
64
|
+
/** Restart upload from the initial options snapshot. / 초기 옵션 스냅샷으로 업로드를 재시작합니다. */
|
|
65
|
+
refresh: () => void;
|
|
66
|
+
/** Resume upload with current retry context and persisted offset. / 현재 재시도 컨텍스트와 저장된 오프셋으로 업로드를 재개합니다. */
|
|
67
|
+
resume: () => void;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Possible status states of an upload.
|
|
71
|
+
* 업로드의 가능한 상태 값들입니다.
|
|
72
|
+
*/
|
|
73
|
+
export type UploadStatus = "idle" | "uploading" | "success" | "error" | "aborted" | "paused";
|
|
74
|
+
/**
|
|
75
|
+
* The final result of an upload operation.
|
|
76
|
+
* 업로드 작업의 최종 결과입니다.
|
|
77
|
+
*/
|
|
78
|
+
export interface UploadResult {
|
|
79
|
+
/** Whether the upload was successful. / 업로드 성공 여부. */
|
|
80
|
+
ok: boolean;
|
|
81
|
+
/** Total bytes of the file. / 파일의 전체 바이트 수. */
|
|
82
|
+
total: number;
|
|
83
|
+
/** Error message if failed. / 실패 시 에러 메시지. */
|
|
84
|
+
message?: string;
|
|
85
|
+
/** Current upload status. / 현재 업로드 상태. */
|
|
86
|
+
status: UploadStatus;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Actions available to control the upload process.
|
|
90
|
+
* 업로드 프로세스를 제어하기 위한 액션들입니다.
|
|
91
|
+
*/
|
|
92
|
+
export interface UploadActions {
|
|
93
|
+
/** Abort the current upload. / 현재 업로드를 중단합니다. */
|
|
94
|
+
abort: () => void;
|
|
95
|
+
/** Restart upload from the initial options snapshot (retry/offset reset). / 초기 옵션 스냅샷으로 업로드를 재시작합니다(재시도/오프셋 초기화). */
|
|
96
|
+
refresh: () => void;
|
|
97
|
+
/** Pause the current upload. / 현재 업로드를 일시 중지합니다. */
|
|
98
|
+
pause: () => void;
|
|
99
|
+
/** Resume upload from persisted progress without resetting retry context. / 저장된 진행 상태로 재개하며 재시도 컨텍스트를 초기화하지 않습니다. */
|
|
100
|
+
resume: () => void;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The response object returned by the upload initiator.
|
|
104
|
+
* 업로드 시작 시 반환되는 응답 객체입니다.
|
|
105
|
+
*/
|
|
106
|
+
export interface UploadResponse {
|
|
107
|
+
/** Promise that resolves with the final upload result. / 최종 업로드 결과를 반환하는 Promise. */
|
|
108
|
+
result: Promise<UploadResult>;
|
|
109
|
+
/** Available control actions. / 사용 가능한 제어 액션들. */
|
|
110
|
+
actions: UploadActions;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Parameters for stream uploader configuration.
|
|
114
|
+
* 스트림 업로더 구성을 위한 매개변수입니다.
|
|
115
|
+
*/
|
|
116
|
+
export interface StreamUploaderParams {
|
|
117
|
+
/** The file to be uploaded. / 업로드할 파일. */
|
|
118
|
+
file: File;
|
|
119
|
+
/** Chunk size in bytes. / 바이트 단위의 청크 크기. */
|
|
120
|
+
chunkSize: number;
|
|
121
|
+
}
|
|
122
|
+
declare global {
|
|
123
|
+
interface RequestInit {
|
|
124
|
+
/** Duplex mode for streaming fetch requests. / 스트리밍 fetch 요청을 위한 듀플렉스 모드. */
|
|
125
|
+
duplex?: "half";
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Utility function to wait for a specific duration.
|
|
5
|
+
* 지정된 시간만큼 대기하기 위한 유틸리티 함수입니다.
|
|
6
|
+
*/
|
|
7
|
+
const wait = (ms) => new Promise((resolve) => {
|
|
8
|
+
setTimeout(resolve, ms);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
exports.wait = wait;
|
|
12
|
+
//# sourceMappingURL=utils-B4LG-_oN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-B4LG-_oN.js","sources":["../src/utils.ts"],"sourcesContent":["/**\n * Utility function to wait for a specific duration.\n * 지정된 시간만큼 대기하기 위한 유틸리티 함수입니다.\n */\nexport const wait = (ms: number) =>\n new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n"],"names":[],"mappings":";;AAAA;;;AAGG;AACI,MAAM,IAAI,GAAG,CAAC,EAAU,KAC7B,IAAI,OAAO,CAAO,CAAC,OAAO,KAAI;AAC5B,IAAA,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;AACzB,CAAC;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-MtT6SgZa.js","sources":["../src/utils.ts"],"sourcesContent":["/**\n * Utility function to wait for a specific duration.\n * 지정된 시간만큼 대기하기 위한 유틸리티 함수입니다.\n */\nexport const wait = (ms: number) =>\n new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n"],"names":[],"mappings":"AAAA;;;AAGG;AACI,MAAM,IAAI,GAAG,CAAC,EAAU,KAC7B,IAAI,OAAO,CAAO,CAAC,OAAO,KAAI;AAC5B,IAAA,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;AACzB,CAAC;;;;"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if the given HTTP status code indicates success (2xx).
|
|
3
|
+
* 주어진 HTTP 상태 코드가 성공(2xx)을 나타내는지 확인합니다.
|
|
4
|
+
*/
|
|
5
|
+
export declare const isSuccessfulHttpStatus: (status: number) => boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Calculates the end byte position for a specific chunk.
|
|
8
|
+
* 특정 청크의 종료 바이트 위치를 계산합니다.
|
|
9
|
+
*/
|
|
10
|
+
export declare const calculateChunkEnd: ({ chunkIndex, chunkSize, totalFileSize, }: {
|
|
11
|
+
chunkIndex: number;
|
|
12
|
+
chunkSize: number;
|
|
13
|
+
totalFileSize: number;
|
|
14
|
+
}) => number;
|
|
15
|
+
/**
|
|
16
|
+
* Applies chunking-related headers and custom headers to the XMLHttpRequest object.
|
|
17
|
+
* XMLHttpRequest 객체에 청크 관련 헤더 및 커스텀 헤더를 적용합니다.
|
|
18
|
+
*/
|
|
19
|
+
export declare const applyChunkHeaders: ({ xhr, customHeaders, chunkIndex, totalChunks, safeChunkSize, totalFileSize, fileName, }: {
|
|
20
|
+
xhr: XMLHttpRequest;
|
|
21
|
+
customHeaders?: Record<string, string>;
|
|
22
|
+
chunkIndex?: number;
|
|
23
|
+
totalChunks?: number;
|
|
24
|
+
safeChunkSize?: number;
|
|
25
|
+
totalFileSize?: number;
|
|
26
|
+
fileName: string;
|
|
27
|
+
}) => void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { UploadParamsInternal, UploadResponse } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Uploads a file by splitting it into sequential chunks using XMLHttpRequest.
|
|
4
|
+
* XMLHttpRequest를 사용하여 파일을 여러 개의 청크로 나누어 순차적으로 업로드합니다.
|
|
5
|
+
*/
|
|
6
|
+
declare const uploadWithXhrChuncked: (args: UploadParamsInternal) => Promise<UploadResponse>;
|
|
7
|
+
export default uploadWithXhrChuncked;
|