@rtc-agent/component 0.2.9-rc.0 → 0.3.0-rc.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/.generated/locales/en-US.d.ts +15 -0
- package/dist/.generated/locales/en-US.d.ts.map +1 -1
- package/dist/assets/index.browser-eyaxJE57.js +201 -0
- package/dist/assets/shared-worker-Czk9mL9X.js +77480 -0
- package/dist/components/chat-layout/rtc-chat-layout.d.ts +12 -0
- package/dist/components/chat-layout/rtc-chat-layout.d.ts.map +1 -1
- package/dist/components/chat-layout/rtc-chat-layout.styles.d.ts.map +1 -1
- package/dist/components/content-area/rtc-error-message.d.ts +1 -2
- package/dist/components/content-area/rtc-error-message.d.ts.map +1 -1
- package/dist/components/content-area/rtc-user-message.d.ts +17 -1
- package/dist/components/content-area/rtc-user-message.d.ts.map +1 -1
- package/dist/components/content-area/rtc-user-message.styles.d.ts +3 -1
- package/dist/components/content-area/rtc-user-message.styles.d.ts.map +1 -1
- package/dist/components/file-preview/rtc-file-preview-area.d.ts +48 -0
- package/dist/components/file-preview/rtc-file-preview-area.d.ts.map +1 -0
- package/dist/components/file-preview/rtc-file-preview-area.styles.d.ts +2 -0
- package/dist/components/file-preview/rtc-file-preview-area.styles.d.ts.map +1 -0
- package/dist/components/file-preview/rtc-file-preview-modal.d.ts +108 -0
- package/dist/components/file-preview/rtc-file-preview-modal.d.ts.map +1 -0
- package/dist/components/file-preview/rtc-file-preview-modal.styles.d.ts +2 -0
- package/dist/components/file-preview/rtc-file-preview-modal.styles.d.ts.map +1 -0
- package/dist/components/file-preview/rtc-file-thumbnail.d.ts +81 -0
- package/dist/components/file-preview/rtc-file-thumbnail.d.ts.map +1 -0
- package/dist/components/file-preview/rtc-file-thumbnail.styles.d.ts +2 -0
- package/dist/components/file-preview/rtc-file-thumbnail.styles.d.ts.map +1 -0
- package/dist/components/input-area/rtc-input-area.d.ts +55 -2
- package/dist/components/input-area/rtc-input-area.d.ts.map +1 -1
- package/dist/components/input-area/rtc-input-area.styles.d.ts.map +1 -1
- package/dist/components/rtc-agent/rtc-agent.d.ts +11 -0
- package/dist/components/rtc-agent/rtc-agent.d.ts.map +1 -1
- package/dist/contexts/file-storage.d.ts +17 -0
- package/dist/contexts/file-storage.d.ts.map +1 -0
- package/dist/controllers/persistence.controller.d.ts +11 -0
- package/dist/controllers/persistence.controller.d.ts.map +1 -1
- package/dist/{en-US-CpXp6drY.js → en-US-CrMLbirj.js} +17 -2
- package/dist/{highlight-languages-DwYGpLW6.js → highlight-languages-BvNFb0HY.js} +1 -1
- package/dist/icons/icons.d.ts +2 -0
- package/dist/icons/icons.d.ts.map +1 -1
- package/dist/icons/index.d.ts +1 -1
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/{index-DJBmvsa_.js → index-BTJMzthg.js} +34938 -30784
- package/dist/index.js +1 -1
- package/dist/index.umd.js +1801 -1008
- package/dist/stats.html +1 -1
- package/dist/utils/file-id.d.ts +23 -0
- package/dist/utils/file-id.d.ts.map +1 -0
- package/dist/utils/file-md5.d.ts +51 -0
- package/dist/utils/file-md5.d.ts.map +1 -0
- package/dist/utils/file-storage.d.ts +527 -0
- package/dist/utils/file-storage.d.ts.map +1 -0
- package/dist/worker-bridge.d.ts +186 -2
- package/dist/worker-bridge.d.ts.map +1 -1
- package/package.json +7 -5
- package/dist/assets/shared-worker-vIZKoWv_.js +0 -2667
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File ID utility functions
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities for parsing and manipulating file identifiers.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Parse a fileid into md5 and extension.
|
|
8
|
+
*
|
|
9
|
+
* @param fileid - File identifier in format "md5.ext"
|
|
10
|
+
* @returns Object with md5 and ext properties
|
|
11
|
+
* @throws Error if fileid format is invalid
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const { md5, ext } = parseFileId('abc123def456.png');
|
|
16
|
+
* // { md5: 'abc123def456', ext: 'png' }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseFileId(fileid: string): {
|
|
20
|
+
md5: string;
|
|
21
|
+
ext: string;
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=file-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-id.d.ts","sourceRoot":"","sources":["../../src/utils/file-id.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,CAStE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File MD5 Calculation Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides MD5 hash calculation for files using spark-md5 library.
|
|
5
|
+
* Supports both small files (single calculation) and large files (chunked calculation).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Calculate MD5 hash of a file.
|
|
9
|
+
*
|
|
10
|
+
* Uses chunked reading for large files to avoid memory issues.
|
|
11
|
+
* Default chunk size is 2MB.
|
|
12
|
+
*
|
|
13
|
+
* @param file - File or Blob to calculate MD5 for
|
|
14
|
+
* @param chunkSize - Size of each chunk in bytes (default: 2MB)
|
|
15
|
+
* @returns Promise resolving to 32-character hex MD5 hash
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const file = input.files[0];
|
|
20
|
+
* const md5 = await calculateFileMD5(file);
|
|
21
|
+
* console.log(md5); // "d41d8cd98f00b204e9800998ecf8427e"
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function calculateFileMD5(file: File | Blob, chunkSize?: number): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Calculate MD5 hash of an ArrayBuffer.
|
|
27
|
+
*
|
|
28
|
+
* @param buffer - ArrayBuffer to calculate MD5 for
|
|
29
|
+
* @returns 32-character hex MD5 hash
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const buffer = new ArrayBuffer(10);
|
|
34
|
+
* const md5 = calculateBufferMD5(buffer);
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function calculateBufferMD5(buffer: ArrayBuffer): string;
|
|
38
|
+
/**
|
|
39
|
+
* Calculate MD5 hash of a string.
|
|
40
|
+
*
|
|
41
|
+
* @param str - String to calculate MD5 for
|
|
42
|
+
* @returns 32-character hex MD5 hash
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const md5 = calculateStringMD5("hello world");
|
|
47
|
+
* console.log(md5); // "5eb63bbbe01eeed093cb22bb8f5acdc3"
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function calculateStringMD5(str: string): string;
|
|
51
|
+
//# sourceMappingURL=file-md5.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-md5.d.ts","sourceRoot":"","sources":["../../src/utils/file-md5.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,SAAS,GAAE,MAAwB,GAClC,OAAO,CAAC,MAAM,CAAC,CAiCjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAE9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD"}
|
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Storage Utility
|
|
3
|
+
*
|
|
4
|
+
* High-level API for file operations with automatic MD5 calculation,
|
|
5
|
+
* caching, and progress tracking. Wraps the WorkerBridge file operations.
|
|
6
|
+
*
|
|
7
|
+
* Progress callback semantics:
|
|
8
|
+
* - Online upload: onProgress reflects S3 upload progress (0% -> 100%)
|
|
9
|
+
* - Offline upload: onProgress jumps to 100% after writing to local cache
|
|
10
|
+
* (background sync progress is not reported via onProgress; tracked via syncStatus)
|
|
11
|
+
* - Online download: onProgress reflects S3 download progress
|
|
12
|
+
* - Offline download (cache hit): returns immediately, onProgress not triggered
|
|
13
|
+
*/
|
|
14
|
+
import type { WorkerBridge } from '../worker-bridge.js';
|
|
15
|
+
/**
|
|
16
|
+
* File information returned by upload operations.
|
|
17
|
+
*/
|
|
18
|
+
export interface FileInfo {
|
|
19
|
+
/** MD5 hash (32-character hex) */
|
|
20
|
+
md5: string;
|
|
21
|
+
/** File extension (without dot) */
|
|
22
|
+
ext: string;
|
|
23
|
+
/** File size in bytes */
|
|
24
|
+
size: number;
|
|
25
|
+
/** MIME type */
|
|
26
|
+
contentType: string;
|
|
27
|
+
/** Original filename (if available) */
|
|
28
|
+
filename?: string;
|
|
29
|
+
/** Sync status: pending, syncing, synced, or failed */
|
|
30
|
+
syncStatus?: 'pending' | 'syncing' | 'synced' | 'failed';
|
|
31
|
+
/** Local creation time (Unix timestamp in ms) */
|
|
32
|
+
createdAt?: number;
|
|
33
|
+
/** Last sync time (Unix timestamp in ms) */
|
|
34
|
+
syncedAt?: number;
|
|
35
|
+
/** Error message if sync failed */
|
|
36
|
+
errorMessage?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Options for file upload.
|
|
40
|
+
*/
|
|
41
|
+
export interface UploadOptions {
|
|
42
|
+
/** File to upload */
|
|
43
|
+
file: File | Blob;
|
|
44
|
+
/** Original filename (used to extract extension) */
|
|
45
|
+
filename?: string;
|
|
46
|
+
/** MIME type (overrides file.type) */
|
|
47
|
+
contentType?: string;
|
|
48
|
+
/** Progress callback: (loaded bytes, total bytes) */
|
|
49
|
+
onProgress?: (loaded: number, total: number) => void;
|
|
50
|
+
/** AbortSignal for cancellation */
|
|
51
|
+
signal?: AbortSignal;
|
|
52
|
+
/** Cache TTL in milliseconds (default: 7 days). Controls how long the file is cached locally. */
|
|
53
|
+
cacheTtlMs?: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Options for file download.
|
|
57
|
+
*/
|
|
58
|
+
export interface DownloadOptions {
|
|
59
|
+
/** Force download from S3, bypassing cache */
|
|
60
|
+
forceRefresh?: boolean;
|
|
61
|
+
/** Progress callback: (loaded bytes, total bytes) */
|
|
62
|
+
onProgress?: (loaded: number, total: number) => void;
|
|
63
|
+
/** AbortSignal for cancellation */
|
|
64
|
+
signal?: AbortSignal;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Options for batch operations.
|
|
68
|
+
*/
|
|
69
|
+
export interface BatchOptions {
|
|
70
|
+
/** Progress callback: (completed count, total count) */
|
|
71
|
+
onProgress?: (current: number, total: number) => void;
|
|
72
|
+
/**
|
|
73
|
+
* Maximum concurrent operations (default: 3).
|
|
74
|
+
*
|
|
75
|
+
* Controls how many operations run in parallel.
|
|
76
|
+
* - Upload: concurrent S3 uploads via WorkerBridge
|
|
77
|
+
* - Download: concurrent S3 downloads via WorkerBridge
|
|
78
|
+
* - Delete: concurrent delete operations
|
|
79
|
+
*
|
|
80
|
+
* Higher values improve throughput but increase memory/bandwidth usage.
|
|
81
|
+
* Recommended: 1-2 for large files (>10MB), 3-5 for mixed, 5-10 for small files.
|
|
82
|
+
*/
|
|
83
|
+
concurrency?: number;
|
|
84
|
+
/**
|
|
85
|
+
* Error handling strategy (default: 'continue').
|
|
86
|
+
*
|
|
87
|
+
* - 'continue': Continue remaining operations on failure (best-effort).
|
|
88
|
+
* Returns only successful results.
|
|
89
|
+
* - 'cancel': Cancel remaining operations on first failure.
|
|
90
|
+
* Already-completed operations are preserved.
|
|
91
|
+
*/
|
|
92
|
+
onError?: 'continue' | 'cancel';
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Options for batch upload operations.
|
|
96
|
+
*
|
|
97
|
+
* Extends BatchOptions with per-file progress, cancellation, and cache TTL
|
|
98
|
+
* that are forwarded to each individual upload() call within the batch.
|
|
99
|
+
*/
|
|
100
|
+
export interface BatchUploadOptions extends BatchOptions {
|
|
101
|
+
/** Per-file progress callback: (loaded bytes, total bytes) forwarded to each upload */
|
|
102
|
+
onFileProgress?: (loaded: number, total: number) => void;
|
|
103
|
+
/** AbortSignal forwarded to each upload for cancellation */
|
|
104
|
+
signal?: AbortSignal;
|
|
105
|
+
/** Cache TTL in milliseconds forwarded to each upload */
|
|
106
|
+
cacheTtlMs?: number;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Options for batch download operations.
|
|
110
|
+
*
|
|
111
|
+
* Extends BatchOptions with per-file progress, cancellation, and force refresh
|
|
112
|
+
* that are forwarded to each individual download() call within the batch.
|
|
113
|
+
*/
|
|
114
|
+
export interface BatchDownloadOptions extends BatchOptions {
|
|
115
|
+
/** Per-file progress callback: (loaded bytes, total bytes) forwarded to each download */
|
|
116
|
+
onFileProgress?: (loaded: number, total: number) => void;
|
|
117
|
+
/** AbortSignal forwarded to each download for cancellation */
|
|
118
|
+
signal?: AbortSignal;
|
|
119
|
+
/** Force download from S3, bypassing cache — forwarded to each download */
|
|
120
|
+
forceRefresh?: boolean;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Filter options for listing files.
|
|
124
|
+
*/
|
|
125
|
+
export interface ListFilter {
|
|
126
|
+
/** Filter by sync status */
|
|
127
|
+
syncStatus?: 'pending' | 'syncing' | 'synced' | 'failed';
|
|
128
|
+
/** Maximum number of entries to return (default: 100) */
|
|
129
|
+
limit?: number;
|
|
130
|
+
/** Number of entries to skip (default: 0) */
|
|
131
|
+
offset?: number;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Options for updating file metadata.
|
|
135
|
+
*/
|
|
136
|
+
export interface UpdateMetadataOptions {
|
|
137
|
+
/** Original filename */
|
|
138
|
+
filename?: string;
|
|
139
|
+
/** MIME type */
|
|
140
|
+
contentType?: string;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Result of a paginated file listing.
|
|
144
|
+
*/
|
|
145
|
+
export interface ListResult {
|
|
146
|
+
/** Array of file info entries */
|
|
147
|
+
files: FileInfo[];
|
|
148
|
+
/** Total number of files matching the filter */
|
|
149
|
+
total: number;
|
|
150
|
+
/** Whether more files are available beyond the current page */
|
|
151
|
+
hasMore: boolean;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Extract file extension from filename.
|
|
155
|
+
*
|
|
156
|
+
* @param filename - Filename to extract extension from
|
|
157
|
+
* @returns Extension without dot, or 'bin' if no extension found
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* getFileExtension('document.pdf') // 'pdf'
|
|
162
|
+
* getFileExtension('image.JPG') // 'jpg'
|
|
163
|
+
* getFileExtension('noextension') // 'bin'
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
export declare function getFileExtension(filename: string): string;
|
|
167
|
+
/**
|
|
168
|
+
* Generate a filename from MD5 and extension.
|
|
169
|
+
*
|
|
170
|
+
* @param md5 - MD5 hash
|
|
171
|
+
* @param ext - File extension
|
|
172
|
+
* @returns Generated filename in format: {md5}.{ext}
|
|
173
|
+
*/
|
|
174
|
+
export declare function generateFilename(md5: string, ext: string): string;
|
|
175
|
+
/**
|
|
176
|
+
* File Storage Utility Class
|
|
177
|
+
*
|
|
178
|
+
* Provides intelligent file upload/download with automatic MD5 calculation,
|
|
179
|
+
* caching, and progress tracking.
|
|
180
|
+
*
|
|
181
|
+
* Progress callback semantics:
|
|
182
|
+
*
|
|
183
|
+
* - Online upload: onProgress reflects S3 upload progress (0% -> 100%)
|
|
184
|
+
* - Offline upload: onProgress jumps to 100% after writing to local cache
|
|
185
|
+
* (background sync progress is not reported via onProgress; tracked via syncStatus)
|
|
186
|
+
* - Online download: onProgress reflects S3 download progress
|
|
187
|
+
* - Offline download (cache hit): returns immediately, onProgress not triggered
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```typescript
|
|
191
|
+
* const fileStorage = new FileStorage(workerBridge, userId);
|
|
192
|
+
*
|
|
193
|
+
* // Upload a file
|
|
194
|
+
* const fileInfo = await fileStorage.upload({
|
|
195
|
+
* file: input.files[0],
|
|
196
|
+
* onProgress: (loaded, total) => console.log(`${loaded}/${total}`)
|
|
197
|
+
* });
|
|
198
|
+
*
|
|
199
|
+
* // Download a file
|
|
200
|
+
* const blob = await fileStorage.download(fileInfo.md5, fileInfo.ext);
|
|
201
|
+
*
|
|
202
|
+
* // Upload with cancellation
|
|
203
|
+
* const controller = new AbortController();
|
|
204
|
+
* const fileInfo = await fileStorage.upload({
|
|
205
|
+
* file: input.files[0],
|
|
206
|
+
* signal: controller.signal,
|
|
207
|
+
* });
|
|
208
|
+
* controller.abort(); // cancels the upload
|
|
209
|
+
*
|
|
210
|
+
* // List files with pagination
|
|
211
|
+
* const result = await fileStorage.list({ limit: 10, offset: 0 });
|
|
212
|
+
* console.log(result.files, result.total, result.hasMore);
|
|
213
|
+
*
|
|
214
|
+
* // Generate presigned URL
|
|
215
|
+
* const url = await fileStorage.getPresignedUrl({ md5: fileInfo.md5, ext: fileInfo.ext });
|
|
216
|
+
*
|
|
217
|
+
* // Check if file exists
|
|
218
|
+
* const exists = await fileStorage.exists({ md5: fileInfo.md5, ext: fileInfo.ext });
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
export declare class FileStorage {
|
|
222
|
+
private readonly bridge;
|
|
223
|
+
private readonly userId;
|
|
224
|
+
constructor(bridge: WorkerBridge, userId: string);
|
|
225
|
+
/**
|
|
226
|
+
* Upload a file with automatic MD5 calculation.
|
|
227
|
+
*
|
|
228
|
+
* Flow:
|
|
229
|
+
* 1. Check abort signal (fail fast if already aborted)
|
|
230
|
+
* 2. Calculate MD5 hash of the file (in Worker thread)
|
|
231
|
+
* 3. Extract extension from filename
|
|
232
|
+
* 4. Upload to S3 via WorkerBridge (with progress and abort support)
|
|
233
|
+
* 5. Return file metadata
|
|
234
|
+
*
|
|
235
|
+
* @param options - Upload options
|
|
236
|
+
* @returns File metadata (md5, ext, size, contentType)
|
|
237
|
+
* @throws DOMException with name 'AbortError' if signal is aborted
|
|
238
|
+
*/
|
|
239
|
+
upload(options: UploadOptions): Promise<FileInfo>;
|
|
240
|
+
/**
|
|
241
|
+
* Download a file with automatic caching.
|
|
242
|
+
*
|
|
243
|
+
* Flow:
|
|
244
|
+
* 1. Check abort signal (fail fast if already aborted)
|
|
245
|
+
* 2. Check local cache (unless forceRefresh is true)
|
|
246
|
+
* 3. If cache hit, return cached blob
|
|
247
|
+
* 4. If cache miss, download from S3 via WorkerBridge
|
|
248
|
+
* 5. Cache the downloaded file
|
|
249
|
+
* 6. Return the blob
|
|
250
|
+
*
|
|
251
|
+
* P2-NEW-4 fix: forceRefresh is now properly passed to the bridge/worker/persistence layer
|
|
252
|
+
*
|
|
253
|
+
* @param md5 - File MD5 hash
|
|
254
|
+
* @param ext - File extension
|
|
255
|
+
* @param options - Download options
|
|
256
|
+
* @returns File content as Blob
|
|
257
|
+
* @throws DOMException with name 'AbortError' if signal is aborted
|
|
258
|
+
*/
|
|
259
|
+
download(md5: string, ext: string, options?: DownloadOptions): Promise<Blob>;
|
|
260
|
+
/**
|
|
261
|
+
* List files with pagination and optional status filtering.
|
|
262
|
+
*
|
|
263
|
+
* @param filter - Optional filter for pagination and sync status
|
|
264
|
+
* @returns Paginated result with files, total count, and hasMore flag
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* ```typescript
|
|
268
|
+
* // First page
|
|
269
|
+
* const page1 = await fileStorage.list({ limit: 10, offset: 0 });
|
|
270
|
+
* // page1.files: FileInfo[], page1.total: number, page1.hasMore: boolean
|
|
271
|
+
*
|
|
272
|
+
* // Filter by status
|
|
273
|
+
* const pending = await fileStorage.list({ syncStatus: 'pending' });
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
list(filter?: ListFilter): Promise<ListResult>;
|
|
277
|
+
/**
|
|
278
|
+
* Check if a file is cached locally.
|
|
279
|
+
*
|
|
280
|
+
* @param md5 - File MD5 hash
|
|
281
|
+
* @param ext - File extension
|
|
282
|
+
* @returns True if file is cached
|
|
283
|
+
*/
|
|
284
|
+
isCached(md5: string, ext: string): Promise<boolean>;
|
|
285
|
+
/**
|
|
286
|
+
* Get file metadata without downloading the file.
|
|
287
|
+
*
|
|
288
|
+
* Checks local cache first, then falls back to S3 HEAD request.
|
|
289
|
+
*
|
|
290
|
+
* @param identifier - File identifier (md5 + ext or FileInfo)
|
|
291
|
+
* @returns File metadata or null if not found
|
|
292
|
+
*/
|
|
293
|
+
getMetadata(identifier: FileIdentifier): Promise<FileInfo | null>;
|
|
294
|
+
/**
|
|
295
|
+
* Check if a file exists (in cache or S3).
|
|
296
|
+
*
|
|
297
|
+
* @param identifier - File identifier (md5 + ext or FileInfo)
|
|
298
|
+
* @returns True if file exists
|
|
299
|
+
*/
|
|
300
|
+
exists(identifier: FileIdentifier): Promise<boolean>;
|
|
301
|
+
/**
|
|
302
|
+
* Get a presigned URL for direct file access.
|
|
303
|
+
*
|
|
304
|
+
* @param identifier - File identifier (md5 + ext or FileInfo)
|
|
305
|
+
* @param expiresIn - URL expiration time in seconds (default: 3600 = 1 hour)
|
|
306
|
+
* @returns Presigned URL string
|
|
307
|
+
*/
|
|
308
|
+
getPresignedUrl(identifier: FileIdentifier, expiresIn?: number): Promise<string>;
|
|
309
|
+
/** Shared blob URL cache (md5.ext → {url, refCount}) */
|
|
310
|
+
private _blobUrlCache;
|
|
311
|
+
/** Inflight dedup (md5.ext → Promise) */
|
|
312
|
+
private _inflightThumbnail;
|
|
313
|
+
/**
|
|
314
|
+
* Get thumbnail URL with shared blob URL cache and inflight dedup.
|
|
315
|
+
*
|
|
316
|
+
* Strategy:
|
|
317
|
+
* 1. Already have blob URL → return directly (refCount++)
|
|
318
|
+
* 2. Request in-flight → reuse Promise (dedup)
|
|
319
|
+
* 3. Local cache hit → download() + createObjectURL()
|
|
320
|
+
* 4. Cache miss → download() (auto-caches) + createObjectURL()
|
|
321
|
+
* 5. Download fails → getPresignedUrl() (final fallback, browser loads directly)
|
|
322
|
+
*
|
|
323
|
+
* @param identifier - File identifier (md5 + ext or FileInfo)
|
|
324
|
+
* @returns URL string (blob: or https:) for use in <img src>
|
|
325
|
+
*/
|
|
326
|
+
getThumbnailUrl(identifier: FileIdentifier): Promise<string>;
|
|
327
|
+
private _resolveThumbnailUrl;
|
|
328
|
+
private _createBlobUrl;
|
|
329
|
+
/**
|
|
330
|
+
* Release thumbnail URL reference.
|
|
331
|
+
*
|
|
332
|
+
* Decrements refCount. When refCount reaches 0, revokes the blob URL.
|
|
333
|
+
* Call this in component disconnectedCallback.
|
|
334
|
+
*
|
|
335
|
+
* @param identifier - File identifier (md5 + ext or FileInfo)
|
|
336
|
+
*/
|
|
337
|
+
releaseThumbnailUrl(identifier: FileIdentifier): void;
|
|
338
|
+
/**
|
|
339
|
+
* Cache file locally for upload (edit mode).
|
|
340
|
+
*
|
|
341
|
+
* Writes file to local cache with syncStatus='pending', without uploading to S3.
|
|
342
|
+
* Returns FileInfo with real fileid (md5.ext) so components can use getThumbnailUrl()
|
|
343
|
+
* immediately. The actual S3 upload happens later via upload().
|
|
344
|
+
*
|
|
345
|
+
* @param file - File object to cache
|
|
346
|
+
* @returns FileInfo with real md5, ext, and syncStatus='pending'
|
|
347
|
+
*/
|
|
348
|
+
cacheFileForUpload(file: File): Promise<FileInfo>;
|
|
349
|
+
/**
|
|
350
|
+
* Execute batch operations with concurrency control and error handling.
|
|
351
|
+
*
|
|
352
|
+
* Common implementation for uploadBatch, downloadBatch, and deleteBatch.
|
|
353
|
+
* Encapsulates: concurrency clamping, abort-on-error cancellation, progress tracking.
|
|
354
|
+
*
|
|
355
|
+
* @param items - Array of items to process
|
|
356
|
+
* @param buildTask - Factory function that creates a task for each item
|
|
357
|
+
* @param options - Batch options (concurrency, onError, onProgress)
|
|
358
|
+
* @returns Array of successful results
|
|
359
|
+
*/
|
|
360
|
+
private _batchExecute;
|
|
361
|
+
/**
|
|
362
|
+
* Batch upload multiple files with concurrency control.
|
|
363
|
+
*
|
|
364
|
+
* @param files - Array of files to upload
|
|
365
|
+
* @param options - Batch options (concurrency, onError, onProgress)
|
|
366
|
+
* @returns Array of successfully uploaded file metadata
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```typescript
|
|
370
|
+
* // Upload with concurrency control
|
|
371
|
+
* const results = await fileStorage.uploadBatch(
|
|
372
|
+
* files,
|
|
373
|
+
* { concurrency: 5, onProgress: (done, total) => console.log(`${done}/${total}`) }
|
|
374
|
+
* );
|
|
375
|
+
*
|
|
376
|
+
* // Cancel on first error
|
|
377
|
+
* const results = await fileStorage.uploadBatch(
|
|
378
|
+
* files,
|
|
379
|
+
* { onError: 'cancel' }
|
|
380
|
+
* );
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
uploadBatch(files: Array<{
|
|
384
|
+
file: File | Blob;
|
|
385
|
+
filename?: string;
|
|
386
|
+
}>, options?: BatchUploadOptions): Promise<FileInfo[]>;
|
|
387
|
+
/**
|
|
388
|
+
* Batch download multiple files with concurrency control.
|
|
389
|
+
*
|
|
390
|
+
* @param keys - Array of {md5, ext} to download
|
|
391
|
+
* @param options - Batch options (concurrency, onError, onProgress)
|
|
392
|
+
* @returns Array of successfully downloaded Blobs
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* ```typescript
|
|
396
|
+
* // Download with concurrency control
|
|
397
|
+
* const blobs = await fileStorage.downloadBatch(
|
|
398
|
+
* keys,
|
|
399
|
+
* { concurrency: 5, onProgress: (done, total) => console.log(`${done}/${total}`) }
|
|
400
|
+
* );
|
|
401
|
+
* ```
|
|
402
|
+
*/
|
|
403
|
+
downloadBatch(keys: Array<{
|
|
404
|
+
md5: string;
|
|
405
|
+
ext: string;
|
|
406
|
+
}>, options?: BatchDownloadOptions): Promise<Blob[]>;
|
|
407
|
+
/**
|
|
408
|
+
* Delete a file (local cache + S3).
|
|
409
|
+
*
|
|
410
|
+
* @param identifier - File identifier (md5 + ext or FileInfo)
|
|
411
|
+
*/
|
|
412
|
+
delete(identifier: FileIdentifier): Promise<void>;
|
|
413
|
+
/**
|
|
414
|
+
* Delete multiple files with concurrency control.
|
|
415
|
+
*
|
|
416
|
+
* @param identifiers - Array of file identifiers
|
|
417
|
+
* @param options - Batch options (concurrency, onError, onProgress)
|
|
418
|
+
*
|
|
419
|
+
* @example
|
|
420
|
+
* ```typescript
|
|
421
|
+
* // Delete with concurrency control
|
|
422
|
+
* await fileStorage.deleteBatch(
|
|
423
|
+
* identifiers,
|
|
424
|
+
* { concurrency: 5, onProgress: (done, total) => console.log(`${done}/${total}`) }
|
|
425
|
+
* );
|
|
426
|
+
* ```
|
|
427
|
+
*/
|
|
428
|
+
deleteBatch(identifiers: FileIdentifier[], options?: BatchOptions): Promise<void>;
|
|
429
|
+
/**
|
|
430
|
+
* Resume interrupted multipart uploads.
|
|
431
|
+
*
|
|
432
|
+
* Typically called automatically during initialization and network recovery.
|
|
433
|
+
* Can be called manually to trigger resume.
|
|
434
|
+
*
|
|
435
|
+
* P2-NEW-6 fix: Returns syncedFiles/failedFiles for per-file event broadcasting.
|
|
436
|
+
*
|
|
437
|
+
* @returns Statistics: number of uploads resumed, failed, expired, plus detailed file lists
|
|
438
|
+
*/
|
|
439
|
+
resumeInterruptedUploads(): Promise<{
|
|
440
|
+
resumed: number;
|
|
441
|
+
failed: number;
|
|
442
|
+
expired: number;
|
|
443
|
+
syncedFiles: Array<{
|
|
444
|
+
md5: string;
|
|
445
|
+
ext: string;
|
|
446
|
+
}>;
|
|
447
|
+
failedFiles: Array<{
|
|
448
|
+
md5: string;
|
|
449
|
+
ext: string;
|
|
450
|
+
errorMessage?: string;
|
|
451
|
+
}>;
|
|
452
|
+
}>;
|
|
453
|
+
/**
|
|
454
|
+
* Get cache statistics: total files, total size, and breakdown by sync status.
|
|
455
|
+
*
|
|
456
|
+
* @returns CacheStats with totalFiles, totalSize (bytes), and byStatus breakdown
|
|
457
|
+
*/
|
|
458
|
+
getCacheStats(): Promise<{
|
|
459
|
+
totalFiles: number;
|
|
460
|
+
totalSize: number;
|
|
461
|
+
byStatus: {
|
|
462
|
+
pending: {
|
|
463
|
+
count: number;
|
|
464
|
+
size: number;
|
|
465
|
+
};
|
|
466
|
+
syncing: {
|
|
467
|
+
count: number;
|
|
468
|
+
size: number;
|
|
469
|
+
};
|
|
470
|
+
synced: {
|
|
471
|
+
count: number;
|
|
472
|
+
size: number;
|
|
473
|
+
};
|
|
474
|
+
failed: {
|
|
475
|
+
count: number;
|
|
476
|
+
size: number;
|
|
477
|
+
};
|
|
478
|
+
};
|
|
479
|
+
}>;
|
|
480
|
+
/**
|
|
481
|
+
* Evict synced cache entries using LRU strategy.
|
|
482
|
+
*
|
|
483
|
+
* Only evicts files with syncStatus='synced'. Pending/failed/syncing files
|
|
484
|
+
* are preserved to prevent data loss.
|
|
485
|
+
*
|
|
486
|
+
* @param targetBytes Number of bytes to free (default: 100MB)
|
|
487
|
+
* @returns Actual evicted count and bytes freed
|
|
488
|
+
*
|
|
489
|
+
* @example
|
|
490
|
+
* ```typescript
|
|
491
|
+
* // Free up 50MB of cache space
|
|
492
|
+
* const result = await fileStorage.evictCache(50 * 1024 * 1024);
|
|
493
|
+
* console.log(`Evicted ${result.evictedCount} files, freed ${result.evictedBytes} bytes`);
|
|
494
|
+
* ```
|
|
495
|
+
*/
|
|
496
|
+
evictCache(targetBytes?: number): Promise<{
|
|
497
|
+
evictedCount: number;
|
|
498
|
+
evictedBytes: number;
|
|
499
|
+
}>;
|
|
500
|
+
/**
|
|
501
|
+
* Update file metadata (filename, contentType) in the local cache.
|
|
502
|
+
*
|
|
503
|
+
* Updates the metadata fields of an existing cached file entry.
|
|
504
|
+
* Throws if the file entry is not found in the local cache.
|
|
505
|
+
*
|
|
506
|
+
* @param identifier - File identifier (md5 + ext or FileInfo)
|
|
507
|
+
* @param options - Metadata fields to update
|
|
508
|
+
*
|
|
509
|
+
* @example
|
|
510
|
+
* ```typescript
|
|
511
|
+
* await fileStorage.updateMetadata(
|
|
512
|
+
* { md5: fileInfo.md5, ext: fileInfo.ext },
|
|
513
|
+
* { filename: 'report.pdf', contentType: 'application/pdf' }
|
|
514
|
+
* );
|
|
515
|
+
* ```
|
|
516
|
+
*/
|
|
517
|
+
updateMetadata(identifier: FileIdentifier, options: UpdateMetadataOptions): Promise<void>;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* File identifier: either {md5, ext} or FileInfo.
|
|
521
|
+
*/
|
|
522
|
+
type FileIdentifier = {
|
|
523
|
+
md5: string;
|
|
524
|
+
ext: string;
|
|
525
|
+
} | FileInfo;
|
|
526
|
+
export {};
|
|
527
|
+
//# sourceMappingURL=file-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-storage.d.ts","sourceRoot":"","sources":["../../src/utils/file-storage.ts"],"names":[],"mappings":"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"}
|