@livetemplate/client 0.1.0 → 0.3.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/LICENSE +21 -0
- package/README.md +171 -115
- package/dist/livetemplate-client.browser.js +5 -5
- package/dist/livetemplate-client.browser.js.map +4 -4
- package/dist/livetemplate-client.d.ts +5 -0
- package/dist/livetemplate-client.d.ts.map +1 -1
- package/dist/livetemplate-client.js +66 -0
- package/dist/livetemplate-client.js.map +1 -1
- package/dist/tests/test-reconstruction.test.js +1 -1
- package/dist/tests/test-reconstruction.test.js.map +1 -1
- package/dist/upload/s3-uploader.d.ts +11 -0
- package/dist/upload/s3-uploader.d.ts.map +1 -0
- package/dist/upload/s3-uploader.js +71 -0
- package/dist/upload/s3-uploader.js.map +1 -0
- package/dist/upload/types.d.ts +96 -0
- package/dist/upload/types.d.ts.map +1 -0
- package/dist/upload/types.js +6 -0
- package/dist/upload/types.js.map +1 -0
- package/dist/upload/upload-handler.d.ts +71 -0
- package/dist/upload/upload-handler.d.ts.map +1 -0
- package/dist/upload/upload-handler.js +315 -0
- package/dist/upload/upload-handler.js.map +1 -0
- package/package.json +5 -6
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* UploadHandler - Manages file uploads for LiveTemplate
|
|
4
|
+
*
|
|
5
|
+
* Handles:
|
|
6
|
+
* - File input detection and change events
|
|
7
|
+
* - Chunked uploads to server via WebSocket
|
|
8
|
+
* - External uploads (S3) via presigned URLs
|
|
9
|
+
* - Progress tracking and callbacks
|
|
10
|
+
* - Upload cancellation
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.UploadHandler = void 0;
|
|
14
|
+
const s3_uploader_1 = require("./s3-uploader");
|
|
15
|
+
class UploadHandler {
|
|
16
|
+
constructor(sendMessage, options = {}) {
|
|
17
|
+
this.sendMessage = sendMessage;
|
|
18
|
+
this.entries = new Map();
|
|
19
|
+
this.pendingFiles = new Map(); // uploadName -> files
|
|
20
|
+
this.uploaders = new Map();
|
|
21
|
+
this.inputHandlers = new WeakMap();
|
|
22
|
+
this.chunkSize = options.chunkSize || 256 * 1024; // 256KB default
|
|
23
|
+
this.onProgress = options.onProgress;
|
|
24
|
+
this.onComplete = options.onComplete;
|
|
25
|
+
this.onError = options.onError;
|
|
26
|
+
// Register default uploaders
|
|
27
|
+
this.uploaders.set("s3", new s3_uploader_1.S3Uploader());
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Initialize upload detection on file inputs with lvt-upload attribute
|
|
31
|
+
*/
|
|
32
|
+
initializeFileInputs(container) {
|
|
33
|
+
const inputs = container.querySelectorAll('input[type="file"][lvt-upload]');
|
|
34
|
+
inputs.forEach((input) => {
|
|
35
|
+
const uploadName = input.getAttribute("lvt-upload");
|
|
36
|
+
if (!uploadName)
|
|
37
|
+
return;
|
|
38
|
+
// Remove existing listener if any
|
|
39
|
+
const existingHandler = this.inputHandlers.get(input);
|
|
40
|
+
if (existingHandler) {
|
|
41
|
+
input.removeEventListener("change", existingHandler);
|
|
42
|
+
}
|
|
43
|
+
// Create new handler
|
|
44
|
+
const handler = (e) => {
|
|
45
|
+
const files = e.target.files;
|
|
46
|
+
if (!files || files.length === 0)
|
|
47
|
+
return;
|
|
48
|
+
this.startUpload(uploadName, Array.from(files));
|
|
49
|
+
};
|
|
50
|
+
input.addEventListener("change", handler);
|
|
51
|
+
// Store handler in WeakMap to prevent memory leaks
|
|
52
|
+
this.inputHandlers.set(input, handler);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Start upload process for selected files
|
|
57
|
+
*/
|
|
58
|
+
async startUpload(uploadName, files) {
|
|
59
|
+
// Store files temporarily for when server response arrives
|
|
60
|
+
this.pendingFiles.set(uploadName, files);
|
|
61
|
+
// Create file metadata
|
|
62
|
+
const fileMetadata = files.map((file) => ({
|
|
63
|
+
name: file.name,
|
|
64
|
+
type: file.type || "application/octet-stream",
|
|
65
|
+
size: file.size,
|
|
66
|
+
}));
|
|
67
|
+
// Send upload_start message to server
|
|
68
|
+
const startMessage = {
|
|
69
|
+
action: "upload_start",
|
|
70
|
+
upload_name: uploadName,
|
|
71
|
+
files: fileMetadata,
|
|
72
|
+
};
|
|
73
|
+
this.sendMessage(startMessage);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Handle upload_start response from server
|
|
77
|
+
*/
|
|
78
|
+
async handleUploadStartResponse(response) {
|
|
79
|
+
const { upload_name, entries: entryInfos } = response;
|
|
80
|
+
// Get pending files for this upload
|
|
81
|
+
const files = this.pendingFiles.get(upload_name);
|
|
82
|
+
if (!files) {
|
|
83
|
+
console.error(`No pending files found for upload: ${upload_name}`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// Clear pending files
|
|
87
|
+
this.pendingFiles.delete(upload_name);
|
|
88
|
+
// Build a map from file name to file object for lookup
|
|
89
|
+
const fileMap = new Map();
|
|
90
|
+
for (const file of files) {
|
|
91
|
+
fileMap.set(file.name, file);
|
|
92
|
+
}
|
|
93
|
+
// Create upload entries
|
|
94
|
+
const entries = [];
|
|
95
|
+
for (const info of entryInfos) {
|
|
96
|
+
const file = fileMap.get(info.client_name);
|
|
97
|
+
if (!file) {
|
|
98
|
+
console.warn(`No file found for entry ${info.entry_id} (client_name: ${info.client_name})`);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const entry = {
|
|
102
|
+
id: info.entry_id,
|
|
103
|
+
file,
|
|
104
|
+
uploadName: upload_name,
|
|
105
|
+
progress: 0,
|
|
106
|
+
bytesUploaded: 0,
|
|
107
|
+
valid: info.valid,
|
|
108
|
+
done: false,
|
|
109
|
+
error: info.error,
|
|
110
|
+
external: info.external,
|
|
111
|
+
};
|
|
112
|
+
this.entries.set(entry.id, entry);
|
|
113
|
+
entries.push(entry);
|
|
114
|
+
// Handle invalid entries
|
|
115
|
+
if (!info.valid) {
|
|
116
|
+
if (this.onError && info.error) {
|
|
117
|
+
this.onError(entry, info.error);
|
|
118
|
+
}
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
// Start upload (external or chunked)
|
|
122
|
+
if (info.external) {
|
|
123
|
+
this.uploadExternal(entry, info.external);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.uploadChunked(entry);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Upload file using external uploader (S3, etc.)
|
|
132
|
+
*/
|
|
133
|
+
async uploadExternal(entry, meta) {
|
|
134
|
+
try {
|
|
135
|
+
const uploader = this.uploaders.get(meta.uploader);
|
|
136
|
+
if (!uploader) {
|
|
137
|
+
throw new Error(`Unknown uploader: ${meta.uploader}`);
|
|
138
|
+
}
|
|
139
|
+
// Start external upload with progress callback
|
|
140
|
+
await uploader.upload(entry, meta, this.onProgress);
|
|
141
|
+
// Notify server of completion
|
|
142
|
+
const completeMessage = {
|
|
143
|
+
action: "upload_complete",
|
|
144
|
+
upload_name: entry.uploadName,
|
|
145
|
+
entry_ids: [entry.id],
|
|
146
|
+
};
|
|
147
|
+
this.sendMessage(completeMessage);
|
|
148
|
+
if (this.onComplete) {
|
|
149
|
+
this.onComplete(entry.uploadName, [entry]);
|
|
150
|
+
}
|
|
151
|
+
// Schedule cleanup after completion
|
|
152
|
+
this.cleanupEntries(entry.uploadName);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
156
|
+
entry.error = errorMsg;
|
|
157
|
+
if (this.onError) {
|
|
158
|
+
this.onError(entry, errorMsg);
|
|
159
|
+
}
|
|
160
|
+
// Schedule cleanup after error
|
|
161
|
+
this.cleanupEntries(entry.uploadName);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Upload file in chunks via WebSocket
|
|
166
|
+
*/
|
|
167
|
+
async uploadChunked(entry) {
|
|
168
|
+
const { file, id } = entry;
|
|
169
|
+
let offset = 0;
|
|
170
|
+
// Create abort controller for cancellation
|
|
171
|
+
entry.abortController = new AbortController();
|
|
172
|
+
try {
|
|
173
|
+
while (offset < file.size) {
|
|
174
|
+
// Check if upload was cancelled
|
|
175
|
+
if (entry.abortController.signal.aborted) {
|
|
176
|
+
throw new Error("Upload cancelled");
|
|
177
|
+
}
|
|
178
|
+
// Read chunk
|
|
179
|
+
const end = Math.min(offset + this.chunkSize, file.size);
|
|
180
|
+
const chunk = file.slice(offset, end);
|
|
181
|
+
// Convert to base64
|
|
182
|
+
const base64 = await this.fileToBase64(chunk);
|
|
183
|
+
// Send chunk
|
|
184
|
+
const chunkMessage = {
|
|
185
|
+
action: "upload_chunk",
|
|
186
|
+
entry_id: id,
|
|
187
|
+
chunk_base64: base64,
|
|
188
|
+
offset,
|
|
189
|
+
total: file.size,
|
|
190
|
+
};
|
|
191
|
+
this.sendMessage(chunkMessage);
|
|
192
|
+
// Update progress
|
|
193
|
+
offset = end;
|
|
194
|
+
entry.bytesUploaded = offset;
|
|
195
|
+
entry.progress = Math.round((offset / file.size) * 100);
|
|
196
|
+
if (this.onProgress) {
|
|
197
|
+
this.onProgress(entry);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Send complete message
|
|
201
|
+
entry.done = true;
|
|
202
|
+
const completeMessage = {
|
|
203
|
+
action: "upload_complete",
|
|
204
|
+
upload_name: entry.uploadName,
|
|
205
|
+
entry_ids: [id],
|
|
206
|
+
};
|
|
207
|
+
this.sendMessage(completeMessage);
|
|
208
|
+
if (this.onComplete) {
|
|
209
|
+
this.onComplete(entry.uploadName, [entry]);
|
|
210
|
+
}
|
|
211
|
+
// Schedule cleanup after completion
|
|
212
|
+
this.cleanupEntries(entry.uploadName);
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
216
|
+
entry.error = errorMsg;
|
|
217
|
+
if (this.onError) {
|
|
218
|
+
this.onError(entry, errorMsg);
|
|
219
|
+
}
|
|
220
|
+
// Schedule cleanup after error
|
|
221
|
+
this.cleanupEntries(entry.uploadName);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Handle progress message from server (for chunked uploads)
|
|
226
|
+
*/
|
|
227
|
+
handleProgressMessage(message) {
|
|
228
|
+
const entry = this.entries.get(message.entry_id);
|
|
229
|
+
if (!entry)
|
|
230
|
+
return;
|
|
231
|
+
entry.progress = message.progress;
|
|
232
|
+
entry.bytesUploaded = message.bytes_recv;
|
|
233
|
+
if (this.onProgress) {
|
|
234
|
+
this.onProgress(entry);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Cancel upload
|
|
239
|
+
*/
|
|
240
|
+
cancelUpload(entryId) {
|
|
241
|
+
const entry = this.entries.get(entryId);
|
|
242
|
+
if (!entry)
|
|
243
|
+
return;
|
|
244
|
+
// Abort external upload if in progress
|
|
245
|
+
if (entry.abortController) {
|
|
246
|
+
entry.abortController.abort();
|
|
247
|
+
}
|
|
248
|
+
// Send cancel message to server
|
|
249
|
+
this.sendMessage({
|
|
250
|
+
action: "cancel_upload",
|
|
251
|
+
entry_id: entryId,
|
|
252
|
+
});
|
|
253
|
+
// Remove entry
|
|
254
|
+
this.entries.delete(entryId);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Get all entries for an upload name
|
|
258
|
+
*/
|
|
259
|
+
getEntries(uploadName) {
|
|
260
|
+
const entries = [];
|
|
261
|
+
for (const entry of this.entries.values()) {
|
|
262
|
+
if (entry.uploadName === uploadName) {
|
|
263
|
+
entries.push(entry);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return entries;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Register custom uploader
|
|
270
|
+
*/
|
|
271
|
+
registerUploader(name, uploader) {
|
|
272
|
+
this.uploaders.set(name, uploader);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Clean up completed or errored upload entries to prevent memory leaks
|
|
276
|
+
* Automatically called after completion/error, but can be called manually
|
|
277
|
+
* @param uploadName - Optional upload name to clean specific uploads
|
|
278
|
+
* @param delay - Optional delay in ms before cleanup (default: 5000ms)
|
|
279
|
+
*/
|
|
280
|
+
cleanupEntries(uploadName, delay = 5000) {
|
|
281
|
+
setTimeout(() => {
|
|
282
|
+
const entriesToRemove = [];
|
|
283
|
+
for (const [id, entry] of this.entries) {
|
|
284
|
+
// Skip if uploadName is specified and doesn't match
|
|
285
|
+
if (uploadName && entry.uploadName !== uploadName)
|
|
286
|
+
continue;
|
|
287
|
+
// Remove completed or errored entries
|
|
288
|
+
if (entry.done || entry.error) {
|
|
289
|
+
entriesToRemove.push(id);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
for (const id of entriesToRemove) {
|
|
293
|
+
this.entries.delete(id);
|
|
294
|
+
}
|
|
295
|
+
}, delay);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Convert File/Blob to base64 string
|
|
299
|
+
*/
|
|
300
|
+
fileToBase64(blob) {
|
|
301
|
+
return new Promise((resolve, reject) => {
|
|
302
|
+
const reader = new FileReader();
|
|
303
|
+
reader.onload = () => {
|
|
304
|
+
const result = reader.result;
|
|
305
|
+
// Remove data URL prefix
|
|
306
|
+
const base64 = result.split(",")[1];
|
|
307
|
+
resolve(base64);
|
|
308
|
+
};
|
|
309
|
+
reader.onerror = reject;
|
|
310
|
+
reader.readAsDataURL(blob);
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
exports.UploadHandler = UploadHandler;
|
|
315
|
+
//# sourceMappingURL=upload-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-handler.js","sourceRoot":"","sources":["../../upload/upload-handler.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livetemplate/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "TypeScript client for LiveTemplate tree-based updates",
|
|
5
5
|
"main": "dist/livetemplate-client.js",
|
|
6
6
|
"browser": "dist/livetemplate-client.browser.js",
|
|
@@ -26,12 +26,11 @@
|
|
|
26
26
|
"license": "MIT",
|
|
27
27
|
"repository": {
|
|
28
28
|
"type": "git",
|
|
29
|
-
"url": "https://github.com/livetemplate/
|
|
30
|
-
"directory": "client"
|
|
29
|
+
"url": "https://github.com/livetemplate/client.git"
|
|
31
30
|
},
|
|
32
|
-
"homepage": "https://github.com/livetemplate/
|
|
31
|
+
"homepage": "https://github.com/livetemplate/client#readme",
|
|
33
32
|
"bugs": {
|
|
34
|
-
"url": "https://github.com/livetemplate/
|
|
33
|
+
"url": "https://github.com/livetemplate/client/issues"
|
|
35
34
|
},
|
|
36
35
|
"publishConfig": {
|
|
37
36
|
"access": "public"
|
|
@@ -43,7 +42,7 @@
|
|
|
43
42
|
"jest": "^30.1.3",
|
|
44
43
|
"jest-environment-jsdom": "^30.2.0",
|
|
45
44
|
"ts-jest": "^29.4.4",
|
|
46
|
-
"typescript": "^5.
|
|
45
|
+
"typescript": "^5.9.3"
|
|
47
46
|
},
|
|
48
47
|
"files": [
|
|
49
48
|
"dist/**/*",
|