@sparkvault/sdk 1.10.0 → 1.10.2

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.
@@ -7053,12 +7053,20 @@ class UploadModalContainer {
7053
7053
  this.elements.modal.classList.add('svu-with-sidebar');
7054
7054
  this.elements.modal.appendChild(sidebar);
7055
7055
  this.elements.sidebar = sidebar;
7056
+ // Hide header when sidebar is shown (sidebar has its own logo)
7057
+ if (this.headerElement) {
7058
+ this.headerElement.style.display = 'none';
7059
+ }
7056
7060
  }
7057
7061
  else if (!show && this.elements.sidebar) {
7058
7062
  // Remove sidebar
7059
7063
  this.elements.modal.classList.remove('svu-with-sidebar');
7060
7064
  this.elements.sidebar.remove();
7061
7065
  this.elements.sidebar = null;
7066
+ // Show header again when sidebar is hidden
7067
+ if (this.headerElement) {
7068
+ this.headerElement.style.display = '';
7069
+ }
7062
7070
  }
7063
7071
  }
7064
7072
  createSecuritySidebar() {
@@ -8184,48 +8192,66 @@ class UploadRenderer {
8184
8192
  }
8185
8193
  // Build full upload URL
8186
8194
  const uploadUrl = location.startsWith('http') ? location : `${url.origin}${location}`;
8187
- // Step 2: Upload file in chunks
8195
+ // Step 2: Upload file in chunks with progress tracking
8188
8196
  let offset = 0;
8189
8197
  const totalSize = file.size;
8190
8198
  while (offset < totalSize) {
8191
- const end = Math.min(offset + chunkSize, totalSize);
8192
- const chunk = file.slice(offset, end);
8193
- // Upload chunk
8194
- const patchResponse = await fetch(uploadUrl, {
8195
- method: 'PATCH',
8196
- headers: {
8197
- 'Tus-Resumable': TUS_VERSION,
8198
- 'Upload-Offset': String(offset),
8199
- 'Content-Type': 'application/offset+octet-stream',
8200
- },
8201
- body: chunk,
8202
- });
8203
- if (!patchResponse.ok) {
8204
- const errorText = await patchResponse.text();
8205
- throw new Error(`Chunk upload failed: ${patchResponse.status} ${errorText}`);
8206
- }
8207
- // Update offset from server response
8208
- const newOffsetHeader = patchResponse.headers.get('Upload-Offset');
8209
- const newOffset = newOffsetHeader ? parseInt(newOffsetHeader, 10) : end;
8199
+ const chunkStart = offset;
8200
+ const chunkEnd = Math.min(offset + chunkSize, totalSize);
8201
+ const chunk = file.slice(chunkStart, chunkEnd);
8202
+ // Upload chunk with XHR for progress events
8203
+ const newOffset = await this.uploadChunkWithProgress(uploadUrl, chunk, chunkStart, totalSize, TUS_VERSION, file, ingotId, requestId);
8210
8204
  offset = newOffset;
8211
- // Update progress
8212
- const progress = Math.round((offset / totalSize) * 100);
8213
- this.setState({
8214
- view: 'uploading',
8215
- file,
8216
- ingotId,
8217
- requestId,
8218
- progress,
8219
- bytesUploaded: offset,
8220
- });
8221
- this.callbacks.onProgress?.({
8222
- bytesUploaded: offset,
8223
- bytesTotal: totalSize,
8224
- percentage: progress,
8225
- phase: 'uploading',
8226
- });
8227
8205
  }
8228
8206
  }
8207
+ /**
8208
+ * Upload a single chunk using XMLHttpRequest for progress tracking
8209
+ */
8210
+ uploadChunkWithProgress(uploadUrl, chunk, chunkStart, totalSize, tusVersion, file, ingotId, requestId) {
8211
+ return new Promise((resolve, reject) => {
8212
+ const xhr = new XMLHttpRequest();
8213
+ // Track progress within this chunk
8214
+ xhr.upload.onprogress = (e) => {
8215
+ if (e.lengthComputable) {
8216
+ // Calculate total progress: completed chunks + progress within current chunk
8217
+ const totalUploaded = chunkStart + e.loaded;
8218
+ const progress = Math.round((totalUploaded / totalSize) * 100);
8219
+ this.setState({
8220
+ view: 'uploading',
8221
+ file,
8222
+ ingotId,
8223
+ requestId,
8224
+ progress,
8225
+ bytesUploaded: totalUploaded,
8226
+ });
8227
+ this.callbacks.onProgress?.({
8228
+ bytesUploaded: totalUploaded,
8229
+ bytesTotal: totalSize,
8230
+ percentage: progress,
8231
+ phase: 'uploading',
8232
+ });
8233
+ }
8234
+ };
8235
+ xhr.onload = () => {
8236
+ if (xhr.status >= 200 && xhr.status < 300) {
8237
+ // Get new offset from server response
8238
+ const newOffsetHeader = xhr.getResponseHeader('Upload-Offset');
8239
+ const newOffset = newOffsetHeader ? parseInt(newOffsetHeader, 10) : chunkStart + chunk.size;
8240
+ resolve(newOffset);
8241
+ }
8242
+ else {
8243
+ reject(new Error(`Chunk upload failed with status ${xhr.status}`));
8244
+ }
8245
+ };
8246
+ xhr.onerror = () => reject(new Error('Chunk upload failed'));
8247
+ xhr.ontimeout = () => reject(new Error('Chunk upload timed out'));
8248
+ xhr.open('PATCH', uploadUrl);
8249
+ xhr.setRequestHeader('Tus-Resumable', tusVersion);
8250
+ xhr.setRequestHeader('Upload-Offset', String(chunkStart));
8251
+ xhr.setRequestHeader('Content-Type', 'application/offset+octet-stream');
8252
+ xhr.send(chunk);
8253
+ });
8254
+ }
8229
8255
  async runCeremony(file, ingotId, requestId) {
8230
8256
  for (let i = 0; i < CEREMONY_STEPS.length; i++) {
8231
8257
  this.setState({